Skip to content

M5: the assistant plans by tool calls through Gecko Suite (beta, per-person switch) - #218

Merged
davior merged 2 commits into
mainfrom
claude/beautiful-wright-og4xur
Nov 4, 2026
Merged

davior merged 2 commits into
mainfrom
claude/beautiful-wright-og4xur

Conversation

@davior

@davior davior commented Nov 4, 2026

Copy link
Copy Markdown
Owner

Summary

M5 (the suite's SN-3), Notes side. With AI_BACKEND=suite and Settings → Assistant → Tool calling (beta) switched on, phase one of an assistant turn is planned by tool calls instead of a JSON plan written as text. Everything after planning is unchanged.

How it works

  • The loop: run_agent from gecko-suite-client (shared with GAM and GVC) over SuiteChat, using the model picked in Notes' own panel, named to the suite by vendor + model (needs gecko-suite#10).
  • Read tools run now: find_notes, read_note and web_search reuse the retrieval code the text plan's search rounds used (_run_find_notes, _render_note, search_web_for_user). A note they surface is added to valid_note_ids, so the executor accepts it.
  • Write tools only record. There are 20, one per action type the executor knows. Each checks its arguments with the existing validate_action and appends to a proposal; nothing touches a note.
  • Same plan out: the result is the same {"actions": [...]} plan (the model's reply as a respond action, then the changes), handed to the same _decide. So approval, plan mode, deferred spec bodies and the executor neither know nor care which planner ran.
  • The prompt is built on the server (tools.py): the text plan's rules minus everything that existed only because the plan was JSON in text. The browser sends the neutral parts (tool_ctx: reference block, live note, history, request, image attachments) beside the usual body.

When it is used

  • Only in suite mode, with the switch on, and with no PDF attached (the suite's chat carries images, not PDFs).
  • Anything else keeps today's text plan, so nothing changes for anyone who doesn't switch it on.
  • The switch is a per-person app setting (assistant_tool_mode), off by default, and shown only in suite mode.

Files: new backend/app/assistant/tools.py, tool_planner.py; a hook at the top of planner.run_planning; suite.chat_client; the client pin in requirements.txt; frontend utils/toolContext.ts, the settings store, AIConversationPanel and AssistantSettings.

Test plan

  • pytest -q in backend/: 1397 passed, 1 skipped, run against the client installed from the pinned URL (Python 3.13 locally; CI is 3.11).
  • 14 new tests in tests/test_assistant_tools.py, through real create_run and run_planning against a fake suite:
    • a question answered with no tools;
    • a change proposed and parked, not applied;
    • a note found by search then changed, with its id widened;
    • unusable arguments sent back to the model and nothing recorded;
    • another person's note refused;
    • the suite's error shown in words;
    • every write tool is an executor action;
    • when the tool planner is and isn't used.
  • Frontend: npm test 224 passed (new toolContext tests) and npm run build passes.
  • Not verified: no turn has run against a real model. Plan quality and the condensed prompt need trying, and expect tuning; that's why it's a switch, off by default.

Deployment

  • Before pulling: gecko-suite#10 must be merged and deployed. This PR pins its client to that branch's commit e4d0d2a. If Add admin flag, user management, and profile features #10 merges as that commit, the pin stays valid; I'll re-pin to main's commit if it changes.
  • Services rebuilt: backend and frontend (docker compose up --build -d), then hard-refresh. The backend image installs gecko-suite-client from the pinned archive URL.
  • Configuration, migrations, Caddy: none.
  • Verify: in suite mode, Settings → Assistant shows "Tool calling (beta)". Turn it on, ask the assistant a question (an answer appears), then ask it to change a note (a proposal waits for approval). The suite's Usage view shows the calls under app notes.
  • Roll back: switch it off (per person, instantly), or redeploy the previous commit. Nothing is stored that the text path can't read.

Generated by Claude Code

…er-person switch (M5)

With AI_BACKEND=suite and Settings -> Assistant -> Tool calling on, phase one of a turn
runs run_agent over SuiteChat with Notes' own tools instead of asking for a JSON plan in
text. Read tools (find_notes, read_note, web_search) run through the retrieval code the
text plan uses; write tools record a validate_action-checked action and change nothing.
The result is the same plan, handed to the same _decide, so approval, deferred bodies and
the executor are unchanged. The model is the one picked in Notes' panel, named by vendor
and model. Local mode, the switch off, or a PDF attached keeps the text plan.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1geD2ELWgL2sDpxYbx3Aw
…del (M5)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01V1geD2ELWgL2sDpxYbx3Aw
@davior
davior marked this pull request as ready for review November 4, 2026 12:22
@davior
davior merged commit 758e357 into main Nov 4, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants