Skip to content

Open the ACP tool-call enums at the wire boundary (M4) - #2198

Closed
SawyerHood wants to merge 1 commit into
mainfrom
ws2b-acp-1-open-wire-enums
Closed

Open the ACP tool-call enums at the wire boundary (M4)#2198
SawyerHood wants to merge 1 commit into
mainfrom
ws2b-acp-1-open-wire-enums

Conversation

@SawyerHood

@SawyerHood SawyerHood commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

What was wrong

plugins/provider-acp/src/wire.ts parsed the ACP tool-call kind and status with closed zod enums. ACP's ToolKind is an open enum upstream (#[serde(other)]; the v2 draft adds Unknown(String), an open status, and cancelled), and the v1 schema already has switch_mode, which the enum did not list. One unseen value failed the whole tool_call parse, so the call never opened and its later completed update merged into nothing: the row was lost. The same schema drove the permission request's toolCall, and a foreign content entry dropped the call the same way. This is the M4 finding of the ACP tool-reporting spike (a live data-loss bug).

What changed

  • A z.preprocess boundary on the tool-call schemas (acpToolCallUpdateEventSchema, the permission toolCall) normalizes the enums before validation: an unknown kind parses as other and the agent's own word survives on rawKind; an unknown status parses as pending; null reads as absent.
  • switch_mode is a known kind (presentation: "Switching mode" / SlidersHorizontal). The v2 cancelled status is terminal and settles the item as interrupted.
  • content entries parse one at a time: an entry of an unknown type is skipped, the call keeps the rest.
  • The generic tool item names itself by rawKind ?? kind so a deploy call reads tool: "deploy", and the merge cache carries rawKind through updates.

No grammar change, no wire change to the daemon.

How I verified

  • New tests in wire.test.ts (unknown kind/status, switch_mode + cancelled, null enums, foreign content entry, the permission request path) and delta-translation.test.ts ("keeps a call whose kind the schema does not know": the call now opens under its own kind word and the completed update closes the same item; a cancelled close is interrupted). All fail on main.
  • pnpm exec turbo run typecheck test --filter=bb-plugin-provider-acp: 15 files, 203 tests pass, including the recorded acp-cursor conformance cells.

Part of the WS2b ACP stack (kit + plugin-owned agents + ACP tier deletion). This is the bottom layer.

AGENT GENERATED: by Claude Opus 5

ACP's ToolKind is an open enum upstream; a closed zod enum dropped the whole
tool_call for one unseen kind, so the call never opened and its completed
update merged into nothing. Unknown kind → other (raw value kept on rawKind
for the tool slot), unknown status → pending, switch_mode accepted, v2
cancelled → interrupted, null kind/status read as absent, and an unknown
content entry is skipped per entry instead of per call.

Co-Authored-By: Claude <noreply@anthropic.com>
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