Ben Brandt 77910dea74 refactor: report a tool call that Claude dropped before it ran as cancelled on the experimental ACP v2 surface (#1300)
v2 has a `cancelled` tool call status ("the tool call was cancelled
before it completed"), which v1 doesn't. #1289 started using it for a
run that Claude Code aborted. This PR uses it for the other tool call
that never ran: one that Claude dropped before running it.

## What changes

When a turn ends with `end_turn` and a streamed `tool_use` never reached
a complete assistant message, Claude dropped that tool call before it
ran, for example when it switched to a steering message. The agent
closes it at the end of the turn with "Claude stopped this tool call
before it ran." The turn itself still succeeds.

| Case | v2 client | v1 and AIR clients |
| --- | --- | --- |
| Dropped before it ran | `cancelled` (was `failed`) | `failed`, as
before |
| Ran, but Claude Code returned no result | `failed`, as before, and the
turn fails with `incomplete_tool_call` | same |

The content text is unchanged in both cases.

## How

- **The renderer builds both closing reports**
(`AcpToolCallRenderer.unfinished`), and picks the status from
`ClientCapabilities.v2`, as `resultStatus` does since #1289. Before, the
agent built the report inline with a hardcoded `failed`.
- **The agent** passes whether the tool ran. Its closing step
(`failToolCall`, now `closeUnfinished`) already removes the call from
all of its tracking itself, so no "is this status final" check needed
changing.

## Checks

- `npm run check`, `npm run build` and all 2728 tests pass. No golden
file changes: no recorded scenario drops a tool call.
- New tests:
  - **renderer:** dropped and ran-without-result, on v2, v1 and AIR;
- **v2 surface:** a v2 client receives `pending` then `cancelled` for a
dropped tool call, and the turn ends `end_turn`.
- The existing v1 tests in `incomplete-tools.test.ts` are unchanged and
still pass.
- I made five mutations and each failed a test: the renderer never
cancels, the renderer cancels a tool that ran, the agent marks a dropped
call as having run, the agent marks a no-result call as dropped, and the
agent's renderer ignores the client's capabilities.
2026-10-12 11:57:21 +02:00
2026-07-21 18:53:56 +02:00
2025-09-02 19:06:32 -03:00
2026-03-26 12:19:06 +01:00

ACP adapter for the Claude Agent SDK

npm

Use Claude Agent SDK from ACP-compatible clients!

This tool implements an ACP agent by using the official Claude Agent SDK, supporting:

  • Context @-mentions
  • Images
  • Tool calls (with permission requests)
  • Compact file changes through the negotiated AIR diff patch extension
  • Following
  • Edit review
  • TODO lists
  • Nested subagent transcripts
  • Interactive (and background) terminals
  • Custom Slash commands
  • Client MCP servers
  • /mcp in the chat: the MCP server status as a list. The adapter runs /mcp reconnect, /mcp enable, and /mcp disable through the SDK control API, because Claude Code refuses them in SDK mode. A reconnect of an ACP server that needs authentication starts MCP OAuth through URL elicitation
  • Session-scoped long-running goals for AIR through the goal extension under _meta.jetbrains.air.goal
  • Structured errors, recovery, and warnings through the opt-in session failure extension
  • Concrete model and effort defaults through the opt-in recommended config value extension
  • Tool permission presentation, editable choices, and durable effects through the permission extension
  • One fact per field in every tool call report, as the ACP tool call contract defines
  • All AIR extensions, capabilities, and _meta keys: AIR extensions

Learn more about the Agent Client Protocol.

To try changes that have landed on main but are not released yet, install from the preview channel — every push to main publishes one. See docs/RELEASES.md.

npm install @agentclientprotocol/claude-agent-acp@preview

Subagent sessions

Subagents are exposed only after bilateral capability negotiation. Until the released ACP SDKs preserve the draft clientCapabilities.subagents field, a supporting client may advertise nativeSubagentSessions in _meta.jetbrains.air.capabilities; the adapter mirrors the capability in its initialize response. The canonical field remains supported and takes precedence once it is available. Without either client signal, Agent/Task lifecycle keeps its legacy ordinary ACP tool-call representation and child interactions stay on the root session. Clients that use the historical _meta["subagent-transcript"] capability or forwardSubagentText session option retain the flattened child transcript behavior. See AIR extensions.

Contribution Policy

This project does not require a Contributor License Agreement (CLA). Instead, contributions are accepted under the following terms:

By contributing to this project, you agree that your contributions will be licensed under the Apache License, Version 2.0. You affirm that you have the legal right to submit your work, that you are not including code you do not have rights to, and that you understand contributions are made without requiring a Contributor License Agreement (CLA).

Description
Pull mirror of agentclientprotocol/claude-agent-acp (Apache-2.0): the ACP bridge that lets Buzz drive Claude Code
Readme 107 MiB
Languages
TypeScript 99.2%
JavaScript 0.6%
Shell 0.2%