Skip to content

fix(tools): wire manage_rag into tool dispatch (#5557)#5595

Open
RavinduPabasara wants to merge 1 commit into
odysseus-dev:devfrom
RavinduPabasara:fix/manage-rag-dispatch-5557
Open

fix(tools): wire manage_rag into tool dispatch (#5557)#5595
RavinduPabasara wants to merge 1 commit into
odysseus-dev:devfrom
RavinduPabasara:fix/manage-rag-dispatch-5557

Conversation

@RavinduPabasara

@RavinduPabasara RavinduPabasara commented Jul 18, 2026

Copy link
Copy Markdown

Summary

manage_rag was advertised to users (UI TOOL_GROUPS) and to nobody's benefit: it was absent from TOOL_TAGS and from every dispatch site, so agent tool blocks naming it were rejected as unknown before reaching a handler — models loop hunting for workarounds, as documented in #5557. The handler itself was alive and maintained (it received the #1660 data-loss fix), so the unwiring looks like accidental registry-era fallout (cf. #4277) rather than a deliberate removal — this PR takes the issue's "re-register" direction: recognize the fence tag, route it through dispatch_ai_tool next to manage_memory, and add manage_rag to NON_ADMIN_BLOCKED_TOOLS so re-wiring doesn't open a new non-admin capability (add_directory indexes arbitrary server paths — same sensitivity class as manage_memory/read_file, both gated).

Target branch

  • This PR targets dev, not main.

Linked Issue

Fixes #5557

Type of Change

  • Bug fix (non-breaking — fixes a confirmed issue)

Checklist

How to Test

  1. python -m pytest tests/test_manage_rag_dispatch.py — 4 new regression tests: fence tag recognized, dispatch reaches do_manage_rag with session scope, public-user gating, user-disable handling. Hermetic (no chromadb), same style as test_rag_remove_directory_scope.py.
  2. python -m pytest — 4,613 passed. The 4 failures in TestHostDockerAccess/test_cookbook_docker_access.py occur identically on clean dev on this machine (Docker-socket environment tests, macOS) — not introduced here.
  3. Ran the app (uvicorn app:app, fresh sqlite env) — boots cleanly with the change, and exercising the real dispatch chain in the running install now reaches the handler:
    from src.tool_execution import execute_tool_block
    from src.agent_tools import ToolBlock
    await execute_tool_block(ToolBlock("manage_rag", "list"), session_id="s")
    # -> ("manage_rag: list", {"results": "Personal docs manager not available. RAG may not be configured."})
    On dev without this PR, the same block never reaches a handler ("unknown tool"). What I did not drive: a full chat turn with a live model emitting the fence block (no model endpoint in my test env) — the blockdispatchhandler path above is the changed surface.
  4. On a configured deployment: ask the agent to "list what's in the RAG index" — it should call manage_rag and get a listing instead of looping.

Note: the destructive remove_directory action stays available to admin/single-user as-is, since #1660's collection-wipe bug is already fixed inside the handler. Happy to restrict dispatch to list/add_directory if you'd prefer the conservative surface.

No UI changes — nothing that renders was touched.

manage_rag was advertised in the UI's TOOL_GROUPS and had a maintained
handler (do_manage_rag, last touched by the odysseus-dev#1660 data-loss fix), but
was absent from TOOL_TAGS and from every dispatch site, so agents had
no working path to it: fence blocks naming it were rejected as unknown
before reaching a handler, and models looped hunting for workarounds.

The unwiring appears accidental (registry-era fallout, cf odysseus-dev#4277): the
handler kept receiving fixes after odysseus-dev#1660, the UI kept advertising the
tool, and its tests kept passing against the orphaned function.

Wiring, following the manage_memory pattern exactly:
- TOOL_TAGS: recognize the manage_rag fence tag
- tool_execution: route manage_rag through dispatch_ai_tool
- ai_interaction.dispatch_ai_tool: add the manage_rag branch

Also add manage_rag to NON_ADMIN_BLOCKED_TOOLS: add_directory indexes
arbitrary server paths into the shared RAG index, the same sensitivity
class as manage_memory/read_file, which are both gated. Without this,
re-wiring the tool would open a new non-admin capability.

Tests: tag recognition, dispatch reaches the handler with session
scope, public-user gating, and user-disable handling.
@github-actions github-actions Bot added needs work PR description incomplete — please update before review ready for review Description complete — ready for maintainer review and removed needs work PR description incomplete — please update before review labels Jul 18, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ready for review Description complete — ready for maintainer review

Projects

None yet

1 participant