diff --git a/app/core/deep_agent.py b/app/core/deep_agent.py index 55a4536..1ecae95 100644 --- a/app/core/deep_agent.py +++ b/app/core/deep_agent.py @@ -396,7 +396,7 @@ _CONTEXTUAL_SYSTEM_PROMPT = """You are adiuvAI's contextual assistant. The user Rules: 1. Base context (current view summary) is provided every turn. Treat it as ground truth for ids and names; never invent them. -2. When the user asks about details not in the base context (e.g. "what tasks are blocking the launch milestone"), call `get_page_details` for the relevant entity before answering. Don't guess. +2. ALL reads go through `get_page_details`. The legacy tools `list_projects`, `get_project`, `list_tasks`, `get_task`, `list_notes`, `get_note` are NOT available in this channel — do not attempt to call them. To find an entity by name, call `get_page_details({entityType: 'projects_all' | 'tasks_all' | 'timeline_all'})` to list, then `get_page_details({entityType: '', entityId})` for the full snapshot. 3. When the user requests an action that creates or updates an entity: - If the current view is a project and no project is specified, use the current project automatically. - If the current view is the global Tasks / Projects / Timeline list and no project is specified, ASK before attaching to any project. Don't silently create orphan entities. @@ -606,25 +606,21 @@ async def get_page_details( def _contextual_tools(user_id: str, trace_id: str | None) -> list[Any]: """Return the tool palette for the contextual sidebar agent. - Includes get_page_details, entity-create/update tools, and memory tools. - Note-edit tools (propose_note_edit) are intentionally excluded — next sprint. + Read ops go through get_page_details only — legacy list_*/get_* tools + return shallow snapshots and cause the agent to under-answer (see + smoke trace 0b46841484ba7d024ed9f8d5ac8b1df0). Writes are limited + to entity creation + task update; note edits are next-sprint. """ - from app.agents.note_agent import create_note, list_notes, get_note # noqa: PLC0415 - from app.agents.task_agent import create_task, update_task, list_tasks # noqa: PLC0415 - from app.agents.timeline_agent import create_timeline, list_timelines # noqa: PLC0415 - from app.agents.project_agent import PROJECT_TOOLS # noqa: PLC0415 + from app.agents.note_agent import create_note # noqa: PLC0415 + from app.agents.task_agent import create_task, update_task # noqa: PLC0415 + from app.agents.timeline_agent import create_timeline # noqa: PLC0415 return [ get_page_details, create_task, update_task, - list_tasks, create_note, - list_notes, - get_note, create_timeline, - list_timelines, - *PROJECT_TOOLS, *_memory_tools(user_id, trace_id), ] diff --git a/tests/test_run_contextual.py b/tests/test_run_contextual.py index d336201..81fade8 100644 --- a/tests/test_run_contextual.py +++ b/tests/test_run_contextual.py @@ -74,3 +74,12 @@ async def test_run_contextual_stream_includes_scope_block(monkeypatch): # Note edit tools must NOT be exposed. assert "propose_note_edit" not in names, "propose_note_edit must be excluded" + + # Legacy read tools must be excluded — they return shallow snapshots and + # cause the agent to under-answer (see trace 0b46841484ba7d024ed9f8d5ac8b1df0). + assert "list_projects" not in names, "list_projects must be excluded (legacy read)" + assert "get_project" not in names, "get_project must be excluded (legacy read)" + assert "list_tasks" not in names, "list_tasks must be excluded (legacy read)" + assert "get_task" not in names, "get_task must be excluded (legacy read)" + assert "list_notes" not in names, "list_notes must be excluded (legacy read)" + assert "get_note" not in names, "get_note must be excluded (legacy read)"