Skip to content

feat(agents): Agent Designer Phase 3 — memory_* tools (write side)#596

Merged
philmerrell merged 1 commit into
developfrom
feature/agent-memory-tools
Jul 8, 2026
Merged

feat(agents): Agent Designer Phase 3 — memory_* tools (write side)#596
philmerrell merged 1 commit into
developfrom
feature/agent-memory-tools

Conversation

@philmerrell

Copy link
Copy Markdown
Contributor

Agent Designer — Phase 3: memory_* tools (completes the D6 read+write payoff)

Builds on the merged read-side (#594). An Agent with a memory_space binding now gets tools to interact with its bound space at invocation — so Oliver can read and write his Memory Space, the D6 dogfood.

What's here

  • agents/builtin_tools/memory_spaces/ — closure-scoped factories (make_memory_list_tool / make_memory_read_tool / make_memory_write_tool) that capture the binding's space id + the invoker's identity, calling MemorySpaceService via asyncio.to_thread. Same pattern as the artifact/spreadsheet tools.
  • routes.py _build_memory_tools() — appended to the extra_tools seam, only when a memory binding resolved. memory_list + memory_read always; memory_write only for access: readwrite.

Safety (per invoker, by construction)

  • The tool closes over the bound space id — it physically can't be re-pointed at another space.
  • MemorySpaceService re-checks the caller's grant on every call (viewer+ read / editor+ write), so a grant revoked mid-session becomes an error tool-result, never a leak.
  • extra_tools agents are never cached, so a tool closed over user A's identity can never be served to user B.
  • Not gated on the user's enabled_tools picker — the governing capability is the Agent's binding (same reasoning as artifact tools). Import-boundary clean (apis.shared only).

Testing

6 tool-factory tests (success + revoked-grant + missing-entry → error tool-result) + 3 seam tests (none=0 / read=2 / readwrite=3 tools) + existing inference/chat tests unchanged + architecture boundary gate. routes.py imports clean.

Phase 3 is now complete (code-side)

Model selection + memory index injection (#594) + these tools = the full harness resolution. The remaining step to verify Oliver live is infra: deploy Memory Spaces to the target env and flip AGENTS_API_ENABLED/MEMORY_SPACES_ENABLED on.

🤖 Generated with Claude Code

…(Phase 3)

Completes the Workstream B write side: an Agent with a memory_space binding now
gets memory_list / memory_read (always) and memory_write (readwrite bindings
only) at invocation — Oliver can read AND write his space.

- agents/builtin_tools/memory_spaces/: closure-scoped factories capturing the
  binding's space id + invoker identity, MemorySpaceService via asyncio.to_thread
  (artifact-tools pattern). Every call re-checks the grant inside the service
  (viewer+ read / editor+ write), so a revoked grant becomes an error tool-result
  mid-session, never a leak
- routes.py _build_memory_tools(): appended to the extra_tools seam only when a
  memory binding resolved; write tool gated on access==readwrite. extra_tools
  agents are never cached → tools closed over user A can't be served to user B
- not gated on enabled_tools: the governing capability is the Agent's binding,
  not the user's tool picker (same reasoning as artifact tools)
- tests: tool success/permission-error/not-found matrix + seam counts
  (none=0, read=2, readwrite=3); 84 inference+tool tests green

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@philmerrell philmerrell merged commit a875cce into develop Jul 8, 2026
4 checks passed
@philmerrell philmerrell deleted the feature/agent-memory-tools branch July 8, 2026 02:57
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.

1 participant