mirror of
https://github.com/agentclientprotocol/claude-agent-acp.git
synced 2026-10-27 04:30:59 +00:00
## Summary
- advertise a provider-neutral goal extension in
`InitializeResponse._meta.goal`
- map Claude SDK `active_goal` messages to
`session_info_update._meta.goal`
- expose the shared `_session/goal` control method with the truthfully
supported `clear` action
- document the extension as a candidate shape for a future first-class
ACP goal API
## Architecture
A goal is persistent **session state**, not the lifecycle of one
`session/prompt` request. `goal.status === "active"` says that the
objective may drive more work; it does not say that a prompt is
executing now.
This keeps two independent axes:
1. **Goal state** is published asynchronously as session metadata and
may survive multiple prompt turns.
2. **Prompt activity** follows the backend's actual running/quiescent
boundaries. While a turn runs, clients use advertised steering or prompt
queueing. Once the backend is quiescent, an ordinary `session/prompt` is
valid even if the goal remains active.
The metadata is deliberately provider-neutral:
```json
{
"_meta": {
"goal": {
"version": 1,
"controlMethod": "_session/goal",
"actions": ["clear"]
}
}
}
```
State is emitted as `session_info_update._meta.goal`; `null` clears it.
The common snapshot vocabulary supports `objective`, common statuses,
timestamps in Unix milliseconds, budgets/usage, iteration count, and a
continuation reason. Each implementation emits only fields it actually
knows. This shape is intentionally close to a future typed ACP
capability/update so promotion out of `_meta` would not require a
provider-specific migration.
Control actions are capability-negotiated. The shared vocabulary
reserves `set`, `pause`, `resume`, and `clear`, but an agent advertises
only the subset it can implement with correct semantics.
## Claude mapping
The Claude runtime already emits internal `active_goal` messages,
although that message is not currently included in the public
`SDKMessage` union. The adapter handles it before the exhaustive switch:
- `condition` → `objective`
- `iterations` → `iterations`
- `set_at` → `createdAt`
- `last_reason` → `lastReason`
- `value: null` → `goal: null`
Provider bookkeeping such as `tokens_at_start` is intentionally not
exposed. Goal updates do not settle, extend, or otherwise mutate ACP
prompt lifecycle. Claude's existing Stop hook remains authoritative for
whether the backend itself continues working.
Only `clear` is advertised for out-of-band control. It submits `/goal
clear` through the existing session prompt queue, preserving the
adapter's established ordering and turn ownership. Setting a goal
remains available through `/goal <condition>` but is not advertised as a
control action because it starts the long-running Stop-hook workflow.
The companion Codex implementation is agentclientprotocol/codex-acp#371.
## Verification
- `npm run test:run` — 692 passed, 20 skipped
- `npm run build`
- `npm run check`
39 lines
2.1 KiB
Markdown
39 lines
2.1 KiB
Markdown
# ACP adapter for the Claude Agent SDK
|
|
|
|
[](https://www.npmjs.com/package/@agentclientprotocol/claude-agent-acp)
|
|
|
|
Use [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview#branding-guidelines) from [ACP-compatible](https://agentclientprotocol.com) clients!
|
|
|
|
This tool implements an ACP agent by using the official [Claude Agent SDK](https://platform.claude.com/docs/en/agent-sdk/overview), supporting:
|
|
|
|
- Context @-mentions
|
|
- Images
|
|
- Tool calls (with permission requests)
|
|
- Following
|
|
- Edit review
|
|
- TODO lists
|
|
- Nested subagent transcripts
|
|
- Interactive (and background) terminals
|
|
- Custom [Slash commands](https://docs.anthropic.com/en/docs/claude-code/slash-commands)
|
|
- Client MCP servers
|
|
- Session-scoped long-running goals through the provider-neutral [goal extension](docs/goal-extension.md)
|
|
|
|
Learn more about the [Agent Client Protocol](https://agentclientprotocol.com/).
|
|
|
|
### Nested subagent transcripts
|
|
|
|
ACP 1.2 has no standard subagent tool kind or nested-message relationship. Clients that can render
|
|
nested transcripts can opt in with `clientCapabilities._meta["subagent-transcript"] = true`.
|
|
The agent then forwards subagent text, thinking, and tool calls, relating nested updates to the
|
|
launching Agent/Task call through `_meta.claudeCode.parentToolUseId`. Agent/Task calls are marked
|
|
with `_meta.claudeCode.subagent = true`.
|
|
|
|
Clients that do not advertise the capability retain the legacy flattened behavior. In both modes,
|
|
the normal Agent/Task tool result is preserved as the protocol-compatible fallback.
|
|
|
|
## 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](https://www.apache.org/licenses/LICENSE-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).
|