Skip to content

feat(bot):Support user-key OpenViking mode and align memory namespaces#1994

Open
yeshion23333 wants to merge 12 commits into
mainfrom
feature_bot_mode
Open

feat(bot):Support user-key OpenViking mode and align memory namespaces#1994
yeshion23333 wants to merge 12 commits into
mainfrom
feature_bot_mode

Conversation

@yeshion23333
Copy link
Copy Markdown
Collaborator

@yeshion23333 yeshion23333 commented May 12, 2026

Description

  • add ov_server.api_key_type (root/user) and update OpenViking client flow to support user-key mode while keeping root-key fanout behavior
  • align memory namespace resolution with account policy in OpenViking paths, including compact hook and search path handling
  • update LoCoMo/OpenClaw benchmark scripts (ingest record format and eval flow) and add/expand tests for api_key_type + namespace behaviors

Related Issue

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

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

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)

Additional Notes

# Conflicts:
#	benchmark/locomo/vikingbot/import_and_eval_one.sh
#	benchmark/locomo/vikingbot/import_to_ov.py
#	benchmark/locomo/vikingbot/run_eval.py
#	bot/vikingbot/agent/memory.py
#	bot/vikingbot/agent/tools/ov_file.py
#	bot/vikingbot/openviking_mount/ov_server.py
@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: 75
🧪 PR contains tests
🔒 No security concerns identified
✅ No TODO sections
🔀 Multiple PR themes

Sub-PR theme: Add api_key_type support and namespace alignment

Relevant files:

  • bot/vikingbot/config/schema.py
  • bot/vikingbot/openviking_mount/ov_server.py
  • bot/tests/test_openviking_api_key_type.py
  • bot/vikingbot/hooks/builtins/openviking_hooks.py
  • bot/vikingbot/agent/tools/ov_file.py
  • bot/vikingbot/agent/memory.py

Sub-PR theme: Update OpenClaw benchmark to use CSV ingest record and compact via chat

Relevant files:

  • benchmark/locomo/openclaw/eval.py

Sub-PR theme: Update VikingBot benchmark with separate user by sample and parallel options

Relevant files:

  • benchmark/locomo/vikingbot/import_to_ov.py
  • benchmark/locomo/vikingbot/run_eval.py

⚡ Recommended focus areas for review

Missing await for async import tasks

The code creates async tasks for processing samples but never awaits them, leading to incomplete imports as the program will exit before tasks finish.

            sample_id=sample_id,
            display_id=display_id,
            session_key=session_key,
            meta=meta,
            run_time=run_time,
            ingest_record=ingest_record,
            args=args,
        )
        if res.get("status") == "success":
            success_count += 1
            total_embedding_tokens += res.get("embedding_tokens", 0)
            total_vlm_tokens += res.get("vlm_tokens", 0)
        elif res.get("status") == "error":
            error_count += 1

if args.parallel_samples:
    semaphore = asyncio.Semaphore(args.parallel_samples)

    async def process_sample_with_limit(item, sample_index):
        async with semaphore:
            await process_sample(item, sample_index)

    tasks = [
        asyncio.create_task(process_sample_with_limit(item, idx))
        for idx, item in enumerate(samples)
    ]
else:
    tasks = [asyncio.create_task(process_sample(item, idx)) for idx, item in enumerate(samples)]

@github-actions
Copy link
Copy Markdown

PR Code Suggestions ✨

No code suggestions found for the PR.

# Conflicts:
#	bot/vikingbot/agent/memory.py
@@ -260,14 +263,13 @@ async def execute(
if not all_results:
return f"No results found for query: {query}"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Bug] (blocking) This branch drops normal SDK object results. search_client.search() commonly returns an object with .memories, but the memory_user_ids path only handles dict and list; object results fall into this else branch, set memories = [], and the tool returns No results found even when OpenViking returned memory matches.

Please reuse _extract_search_items() here or add the same object handling used elsewhere, for example:

elif hasattr(results, "memories"):
    memories = getattr(results, "memories", []) or []

uri = f"viking://user/{user_id}/memories/profile.md"
uri = "viking://user/memories/profile.md"
if effective_user_id:
uri = f"viking://user/{effective_user_id}/memories/profile.md"
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Bug] (blocking) read_user_profile() bypasses the namespace-policy URI helpers added in this PR. When an account enables isolate_user_scope_by_agent, the profile lives under viking://user/{user}/agent/{agent}/memories/profile.md, but this still reads viking://user/{user}/memories/profile.md. That means profile injection can read the wrong namespace or fail to find the profile under the exact policy this PR is trying to support.

Please build this URI from _memory_target_uri(effective_user_id), e.g. uri = f"{self._memory_target_uri(effective_user_id)}profile.md", so profile reads follow the same namespace policy as memory search.

]

assert (
client._skill_memory_uri("planner", "admin")
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[Suggestion] (non-blocking) This test defines _accounts() with isolate_agent_scope_by_user=True, but never patches it onto client.client.admin_list_accounts and never calls await client._load_namespace_policy(). As written, _skill_memory_uri() is using the default policy, so the test either fails or does not actually prove policy-scoped skill memory behavior.

Please patch admin_list_accounts and load the policy before asserting the URI.

Copy link
Copy Markdown
Collaborator

@qin-ctx qin-ctx left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Review summary:

This PR moves vikingbot toward supporting both root-key and user-key OpenViking modes, and aligns several memory URI paths with account namespace policy. The direction is good, but there are still two blocking behavior issues in the memory read/search paths.

CI is also currently blocked by formatting: ruff format --check reports 6 files that would be reformatted (benchmark/locomo/openclaw/eval.py, benchmark/locomo/vikingbot/import_to_ov.py, benchmark/locomo/vikingbot/run_eval.py, bot/tests/test_openviking_api_key_type.py, bot/vikingbot/agent/tools/ov_file.py, bot/vikingbot/hooks/builtins/openviking_hooks.py). Please run formatting before the next update.

Non-code PR hygiene: the PR has no linked issue, the testing checklist is unchecked, and the commit stack contains repeated eval commits plus merge commits. Please add the testing notes and consider squashing into clearer logical commits before merge.

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.

2 participants