Skip to content

feat(memory): 引入 User/Peer 记忆隔离模型#2236

Draft
qin-ctx wants to merge 1 commit into
mainfrom
feat/user-peer-memory-auth
Draft

feat(memory): 引入 User/Peer 记忆隔离模型#2236
qin-ctx wants to merge 1 commit into
mainfrom
feat/user-peer-memory-auth

Conversation

@qin-ctx
Copy link
Copy Markdown
Collaborator

@qin-ctx qin-ctx commented May 26, 2026

Description

本 PR 实现 OpenViking 数据面认证和记忆隔离的新方案:以 API Key 对应的 user_id 作为唯一数据归属主体,废弃 OpenViking 内部的 agent 数据主体语义,并引入 peer_id 表达当前 User 在交互中需要长期区分的外部对象。

核心目标是让数据归属、目录落点和检索范围形成闭环:

  • 常规数据访问只由当前 API Key 决定 user_id,不会因为消息里的说话人、历史 agent_id 或模型抽取结果改变写入 owner。
  • Session 消息可以携带 peer_id,用于客服、陪聊、群聊等场景下区分稳定交互对象。
  • agent_id 作为兼容字段仍可出现在请求里,但会在数据面入口统一转换为 peer_id,内部不再继续传播 agent 身份和 agent 目录。
  • Session commit 支持 memory_policy,用于决定本次提交是否抽取 self memory、是否抽取 peer memory,以及可抽取哪些 memory types。
  • 检索在不指定 peer_id 时返回当前 User 可访问的全部 User/Peer 记忆;指定 peer_id 时只补充该 peer 的记忆空间。

Related Issue

暂无关联 issue。本 PR 来自数据面认证、User/Peer 记忆归属和目录结构方案讨论。

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • Documentation update
  • Refactoring (no functional changes)
  • Performance improvement
  • Test update

Changes Made

  • 数据主体收敛到 User:

    • 移除 OpenViking 服务端、SDK、CLI 中以 agent_id 作为内部数据主体的路径传播。
    • 保留请求层 agent_id 兼容入口,并通过 normalize_peer_id(peer_id, agent_id) 统一转换为 peer_id
    • 清理 viking://agent/...、agent directory、agent identity 等内部目录和身份语义,相关模板里的 agent_space 仅作为兼容变量映射到当前 User 空间。
  • 引入 Peer 记忆模型:

    • Session message 新增 peer_id 字段,支持单条和 batch add messages。
    • peer_id 不参与授权,也不会改变当前请求的 user_id;它只决定是否在当前 User 下创建和访问 peers/{peer_id} 记忆空间。
    • MemoryIsolationHandler 只以当前 authenticated User 作为写入 owner,LLM 抽取出的 user_idagent_idagent_ids 不能改写归属。
    • peer memory 仅允许 profile、preferences、entities、events 这类描述交互对象的记忆类型。
  • 增加 Session memory policy:

    • 新增 openviking/session/memory_policy.py,统一解析 self/peer 抽取策略。
    • create_sessioncommit_session 支持设置或覆盖 memory_policy
    • self.enabled 控制当前 User 自身记忆抽取。
    • peer.enabled 控制是否按消息中的 peer_id 抽取 peer memory。
    • types 为空时表示使用默认可抽取类型;未知类型或 peer 不支持的类型会被拒绝。
  • 调整目录与资源能力:

    • User 私有 skills 迁移到当前 User 空间,add_skill 写入 viking://user/{user_id}/skills/...
    • 资源、技能、记忆相关的目录解析不再依赖 agent 目录。
    • usage audit、namespace、directory 初始化、MCP endpoint、admin/system/watch 等路径处理同步去掉 agent 维度。
  • 调整检索行为:

    • find/search 支持 peer_id 参数。
    • 不传 peer_id 时,默认检索当前 User 的自身记忆以及该 User 下全部 peer 记忆。
    • 传入 peer_id 时,检索当前 User 自身记忆和对应 peer 记忆。
    • legacy agent_id 请求会被转换为 peer_id,保证旧调用可以平滑进入新模型。
  • SDK/CLI 适配:

    • Python async/sync/local client 支持 session peer_id、batch add messages、commit memory_policy、search/find peer_id
    • Rust CLI 增加 ov find/search --peer-id,并保持 profile output、TUI、配置项和主分支最新改动兼容。
    • HTTP client、sync_http client、BaseClient 抽象接口补齐对应方法。
  • 测试覆盖:

    • 新增 tests/server/test_peer_id_compat.py 覆盖 agent_id -> peer_id 兼容、冲突校验、检索默认 peer 范围等行为。
    • 新增 tests/session/test_memory_policy.py 覆盖 memory policy 默认值、类型过滤、commit 覆盖和非法配置。
    • 更新 session message、session commit、memory isolation、skill management、auth/identity、namespace URI、CLI user identifier 等测试,使其匹配 User/Peer 模型。

Testing

  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • I have tested this on the following platforms:
    • Linux
    • macOS
    • Windows

本地验证命令:

cargo fmt -p ov_cli
.venv/bin/python -m compileall -q openviking openviking_cli
git diff --check
.venv/bin/python -m pytest tests/server/test_peer_id_compat.py tests/session/test_session_messages.py tests/client/test_http_client_config.py tests/cli/test_user_identifier.py tests/session/memory/test_memory_isolation_handler.py tests/session/test_memory_policy.py -q
cargo test -p ov_cli

结果:

  • Python 目标测试:58 passed,存在 Pydantic deprecation warnings。
  • Rust CLI 测试:67 passed,存在已有 dead_code/lifetime warnings。
  • pre-commit:ruff 和 ruff-format 均通过。

Checklist

  • My code follows the project's coding style
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • Any dependent changes have been merged and published

Screenshots (if applicable)

不涉及 UI 截图。

Additional Notes

本 PR 当前以 Draft 形式创建,原因是改动覆盖数据面认证、目录结构、Session commit、检索、SDK/CLI 和大量测试,建议先按设计方案和核心调用链做 review,再决定是否 Ready for review。

需要重点 review 的点:

  • agent_id 兼容策略是否只保留在请求入口,内部是否已经统一为 peer_id
  • 不传 peer_id 时检索全部当前 User peer memory 的行为是否符合产品预期。
  • memory_policy 的默认值和类型约束是否足够简单,是否避免引入不必要的授权模型复杂度。
  • add_skill 写入 User 私有 skill 空间是否符合当前阶段对 skills 私有化的判断。
  • 旧 agent 目录和 agent identity 清理后,插件层或外部集成是否还有需要后续单独适配的路径。

Unify agent-scoped memory behavior into user-owned memory spaces, add peer_id compatibility for session and retrieval paths, and wire memory_policy through session commit flows.
@github-actions
Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
🏅 Score: 85
🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 Multiple PR themes

Sub-PR theme: Deprecate agent_id and switch to user-only identity

Relevant files:

  • openviking/server/auth.py
  • openviking/core/namespace.py
  • openviking/resource/watch_manager.py

Sub-PR theme: Add memory_policy for commit-time extraction control

Relevant files:

  • openviking/session/memory_policy.py
  • tests/session/test_memory_policy.py

Sub-PR theme: Add peer_id support with agent_id backward compatibility

Relevant files:

  • openviking/core/peer_id.py
  • tests/server/test_peer_id_compat.py
  • openviking/client/local.py

⚡ Recommended focus areas for review

Potential regression in error handling for parallel extractions

In _run_memory_extraction, when multiple extractions (self + peers) run in parallel, only the first error is raised. This could mask other failures and make debugging harder. Consider aggregating all errors or logging all of them before raising.

    if target_skills:
        extracted_skill_results.extend(target_skills)

if extraction_errors:
    raise extraction_errors[0]
Backward compatibility fallback uses user_space for agent_space

In _render_memory_schema_locks, agent_space is set to user_space for backward compatibility. Ensure this doesn't accidentally write to the wrong path for existing agent-scoped memory templates.

user_space = to_user_space(policy, user_id)
template_vars = {
    "user_space": user_space,
    "agent_space": user_space,

@github-actions
Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Backlog

Development

Successfully merging this pull request may close these issues.

1 participant