mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-10-27 04:30:59 +00:00
## Problem A v1 report's `_meta` belongs to that report, and the agent gives each report its own `_meta.claudeCode` keys. A v2 client stores a tool call's `_meta`, and any report that carries `_meta` replaces it (`tool-calls.mdx`; the migration guide since agentclientprotocol/agent-client-protocol#2355). So a v2 client kept only the last report's keys. For example, a result's `{ toolName }` replaced the denial reason that came before it. On top of that, a PostToolUse hook stored the whole `tool_response` in `_meta`, which for a Write is the whole file text. ## Change All of this is v2 only. No v1 or AIR output changes, and no v1 golden changes. - **Stored `_meta` (`src/v2/tool-call-meta.ts`).** The v2 bridge keeps each tool call's `_meta` the way the client stores it. `claudeCode` keys merge one by one, and every other key replaces whole, the same model `ToolCallFieldTracker` uses. - A report that changes the stored `_meta` carries all of it. - A report that changes nothing carries no `_meta`, which leaves the stored value unchanged. - A permission request's subject always carries the stored `_meta`, since a client can show the request on its own. - The tool call's first report starts from nothing. - **`toolName` becomes `name`.** `claudeCode.toolName` repeats the tool's name, which v2 has a field for. It becomes the `name` of a tool call that has none yet, and is left out otherwise. A memory recall gets a `name` this way. Subagent routing still reads `toolName` on the agent's v1 reports, before the bridge. - **The `toolResponse` AIR gets.** A v2 client also keeps `_meta`, so it gets AIR's trimmed `toolResponse`: - a hook carries only the `status` and `isAsync` markers, not output the content already shows; - a denial carries the SDK message only when it differs from the reason. ## Evidence - **v2 goldens:** 28 change. Most only lose `toolName`. Hook reports lose the repeated stdout or file text. Memory recall gains `name`. The denial keeps its reason type and message. Subagent tool calls and their permission subjects keep `parentToolUseId`. - **Live, CLI 2.1.293 on Haiku, v2:** a Write and a Bash command arrived with `name` on their first report and no `_meta` at all. - **Tests:** 7 unit tests for the stored `_meta`. - **Mutation checks:** removing any of these 9 rules fails at least one test: - naming once; - leaving `toolName` out; - merging with earlier `claudeCode` keys, which also fails the `subagent-late-child-update` golden; - keeping other keys; - omitting unchanged `_meta`; - starting fresh; - the subject's stored `_meta`; - the bridge wiring; - the trimmed `toolResponse`. Forgetting a closed session's tool calls is memory cleanup that no test observes, like `V2Terminals.forget`. A limit of 2048 tool calls also bounds the memory. - `npm run check`, build and all 2820 tests pass.
9 lines
3.2 KiB
JSON
Generated
9 lines
3.2 KiB
JSON
Generated
{"kind":"response","method":"initialize","payload":{"authMethods":[],"capabilities":{"_meta":{"authStatus":{},"claudeCode":{"promptQueueing":true}},"providers":{},"session":{"additionalDirectories":{},"delete":{},"fork":{},"mcp":{"http":{},"stdio":{}},"prompt":{"embeddedContext":{},"image":{}}}},"info":{"name":"@agentclientprotocol/claude-agent-acp","title":"Claude Agent","version":"<version>"},"protocolVersion":2}}
|
|
{"kind":"response","method":"session/new","payload":{"availableCommands":[{"description":"Show the MCP servers and their status, or reconnect, enable, or disable a server","input":{"hint":"[reconnect|enable|disable [<server>|all]]","type":"text"},"name":"mcp"}],"configOptions":[{"category":"mode","configId":"mode","currentValue":"default","description":"Session permission mode","name":"Mode","options":[{"description":"Always ask before making changes","name":"Manual","value":"default"},{"description":"Automatically accept all file edits","name":"Accept edits","value":"acceptEdits"},{"description":"Create a plan before making changes","name":"Plan","value":"plan"},{"description":"Claude handles permission decisions","name":"Auto","value":"auto"},{"description":"Accepts all permissions","name":"Bypass permissions","value":"bypassPermissions"}],"type":"select"},{"category":"model","configId":"model","currentValue":"claude-sonnet-4-6","description":"AI model to use","name":"Model","options":[{"description":"Fast","name":"Claude Sonnet 4.6","value":"claude-sonnet-4-6"}],"type":"select"}],"sessionId":"<session>"}}
|
|
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"content":[{"text":"prompt 1","type":"text"}],"messageId":"<id-1>","sessionUpdate":"user_message"}}}
|
|
{"kind":"response","method":"session/prompt","payload":{"messageId":"<id-1>"}}
|
|
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"sessionUpdate":"state_update","state":"running"}}}
|
|
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"claudeCode":{"toolResponse":{"mode":"select"}}},"kind":"read","locations":[{"path":"/memory/a.md"},{"path":"/memory/b.md"}],"name":"memory_recall","sessionUpdate":"tool_call_update","status":"completed","title":"Recalled 2 memories","toolCallId":"00000000-0000-4000-8000-000000000001"}}}
|
|
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"claudeCode":{"toolResponse":{"mode":"synthesize"}}},"content":[{"content":{"text":"The user prefers tabs.","type":"text"},"type":"content"}],"kind":"read","name":"memory_recall","sessionUpdate":"tool_call_update","status":"completed","title":"Recalled synthesized memory","toolCallId":"00000000-0000-4000-8000-000000000002"}}}
|
|
{"kind":"notification","method":"session/update","payload":{"sessionId":"<session>","update":{"_meta":{"quota":{"model_usage":[],"token_count":{"cachedInputTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"reasoningOutputTokens":0,"totalTokens":0}}},"sessionUpdate":"state_update","state":"idle","stopReason":"end_turn","usage":{"cachedReadTokens":0,"cachedWriteTokens":0,"inputTokens":0,"outputTokens":0,"totalTokens":0}}}}
|