~kris/9p

llm9p

ref: 35c20f3e6e008970ccdc9ea460682c578bd6d35a llm9p/internal/llm/session.go -rw-r--r-- 14.9 KiB
0afa911a — pdfinn 6 months ago
feat(llmfs): native Anthropic tool_use protocol support

Add structured tool_use protocol to llm9p, enabling Veltro to use
Claude's native JSON tool invocation instead of text-based parsing.

New types (backend.go):
- AskResponse: carries Response, StructuredJSON, and Tokens — replaces
  the old (string, int, error) return from AskWithRequest
- ToolDef: tool definition passed to Anthropic tools API
- ToolResult: tool execution result for submission to the LLM
- Backend.AskWithRequest() now returns (AskResponse, error)

client.go:
- Message.StructuredContent: stores JSON content blocks for correct
  history replay of tool_use and tool_result turns
- AskWithRequest(): when ToolDefs non-nil, passes tools to API and
  returns STOP:/TOOL: formatted response for Limbo parsing
  Format: "STOP:tool_use\nTOOL:<id>:<name>:<args>\n<text>" or
          "STOP:end_turn\n<text>" or plain text (no tools)
- AskWithToolResults(): submits tool results as a new user turn
- Helpers: buildMessageParam(), buildToolParams(), extractToolArgs(),
  jsonEscapeString()

session.go:
- Session.tools field + SetTools/Tools methods
- Session.AddStructuredMessage() for storing structured content blocks
- AskRequest extended with ToolDefs and ToolResults fields
- SessionManager.Ask(): includes tools, stores structured JSON in history
- SessionManager.AskWithToolResults(): new method for tool result turns
- Fix Compact() for new AskResponse return type
- Helpers: extractTextContent(), buildToolResultsJSON()

cli_client.go: update AskWithRequest() to return AskResponse (no tools
support; StructuredJSON always empty)

session_tools.go (new): /n/llm/{id}/tools write-only file
- Write JSON array of ToolDef to enable native tool_use protocol
- Empty write clears tools (returns session to text-only mode)

session_ask.go:
- Detect TOOL_RESULTS\n prefix in Write() → parseToolResults() → AskWithToolResults()
- TOOL_RESULTS format: "TOOL_RESULTS\n<id>\n<content>\n---\n..."

session_dir.go: add tools file to Children() and Lookup()

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6da61fd4 — pdfinn 6 months ago
feat(llm9p): per-session compact and usage files for context window management

Add automatic context window compaction support to the per-session 9P API:

- session.go: Add Session.EstimatedContextTokens() (4 chars/token heuristic
  over current messages — more accurate than cumulative totalTokens for
  threshold decisions). Add SessionManager.Compact(ctx, id) which summarises
  the conversation via AskWithRequest then replaces session.messages with a
  compact 2-message exchange. Add SessionManager.EstimatedContextTokens(id)
  and SessionManager.ContextLimit() (200K for all Claude models).

- session_compact.go: New /n/llm/N/compact file. Write any content to
  trigger Compact() for that session. Follows the SessionModelFile pattern.

- session_usage.go: New /n/llm/N/usage file. Read returns
  "estimated_tokens/200000\n". Follows the SessionModelFile pattern.

- session_dir.go: Wire compact and usage into Children() and Lookup().

Also land two pre-existing uncommitted fixes:
- cli_client.go: Accept result messages with empty Result field
- protocol.go: Increase MaxMessageSize 8192→65536 for large system prompts

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
a3dc06aa — pdfinn 7 months ago
feat(llm9p): Implement clone-based session architecture

Replace per-fid session model with Plan 9 clone pattern:
- Reading /n/llm/new creates a session and returns its ID
- Each session gets its own directory: /n/llm/<id>/
- Per-session files: ask, ctl, model, system, thinking, context, metrics
- AskWithRequest method for stateless CSP-style LLM calls
- Session settings (model, temperature, thinking) are per-session
- Remove old ask.go, context.go in favor of session-scoped files

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
ed43a61b — pdfinn 7 months ago
feat(llm9p): Add per-fid session isolation and prefill support

- Add SessionManager for per-fid conversation isolation
- Each 9P fid now gets its own conversation history
- Add FidAwareFile interface for files needing fid context
- Add /n/llm/prefill file for assistant response prefill
- Prefill helps keep model in character (e.g., "[Veltro]")
- Update ask, new, context files to use session manager
- Fix context contamination between parent and subagent

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>