speakeasy-api / speakeasy-api/kit
ACP agent: umbrella for protocol features Kit does not yet support
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 40
- Forks
- 4
- Avg merge
- 4h 18m
- Merged PRs (30d)
- 148
Description
Tracking issue for Agent Client Protocol features that kit serve / kit acp does not implement or advertise, audited against agent-client-protocol-schema 1.7.0 (fork rev 6e7e044, v1 + v2) at Kit v0.1.134 (e75629c). Scope is Kit as ACP agent only. Client-side behavior (Kit driving child harnesses) is out of scope here.
Each item is intended to become its own issue or PR. Check off as they land.
1. Capability and stop-reason fixes
- v1
additionalDirectoriescapability mismatch.capabilities()insrc/protocols/acp.rsadvertisessessionCapabilities.additionalDirectories, but every non-empty value is rejected onsession/new,load, andfork. Drop the capability until item 9 lands. - v2
capabilities.authnever populated.auth/logoutis handled insrc/protocols/acp/v2.rsbut not advertised. v2 also suppresses all auth methods unless logout is supported; those should be independent. - Stop reason parity. v1 maps an error finish to a JSON-RPC internal error instead of a stop reason.
max_turn_requestsis never returned in either version. - v2
usage_update.cost. v1 setscost, v2 sends onlyusedandsize.
2. Project compose inner calls onto ACP tool calls
Kit exposes one model tool, compose. Over ACP that becomes a single tool_call whose title is the literal string compose, kind unset (clients render other), no locations, rawInput = the Runlet program, rawOutput = the result. Inner calls (shell, edit, read_file, subagent, tool_search, tool, docs, ...) are only visible through the stderr runlet progress transport (src/runlet_progress/), which the TUI consumes and no ACP client sees.
- Decide the projection. Two options: (a) one child
tool_callper Runlet call node keyed byowner+ node id, created onNodeAdded, updated onNodeUpdated, with thecomposecard as parent; or (b) keep onecomposecard and stream inner-call state into itscontent, aggregatingkindandlocations. Option (a) matches how editors render tool activity; option (b) is closer to the current transport model. - Per-call
kind.shell→execute,edit→edit,read_file→read,tool_search→search,docs→fetch,subagent/prompt/fork→otherorthink. The outercomposecard staysexecute. -
locations. Populate fromeditandread_filepaths (plus line for hunk edits) so editors can follow the agent. -
titlevsname. Emit a human-readabletitleper call and carry the raw tool name inname(unstable_tool_call_name). Todaytitleis the raw name in both versions (agentkit-acptool_call()/ v2 emitter). - Bound it. Runlet progress already caps nodes and source size; the ACP projection must respect the same bounds and never block execution.
3. Rich tool content
- Diff content for
edit. EmitToolCallContent::Difffrom hunk edit results. v1:path,oldText,newText. v2:changeswithadd/delete/modify/moveplus optionalgit_patch. Never produced today in kit oragentkit-acp. - Terminal content for
shell. v2 only:terminal_updateandterminal_output_chunkstreamed from the local shell runner, plusToolCallContent::Terminalon the call. v1 needs client-owned terminals, skip.
4. Session state broadcasting
-
session_info_update. Never emitted. SendtitleandupdatedAtso session pickers andsession/listshow something useful. -
config_option_update. Never pushed; new options are only returned in theset_config_optionresponse. A model or effort change from one attachment leaves co-attached clients stale. -
plan_update/plan. Never emitted. Map runlet progress or task-manager state to plan entries. -
noticebeyond one case. Today onlyResponse interrupted; replacement followsin v1, nothing in v2. Candidates: provider rate limits, context nearing limit, background compose completion, tool failures. Overlaps with #45.
5. Config surface
- Modes. No
modecategory option andsession/set_modeunhandled in v1. Expose whichever session-level switches make sense asmodeoptions. - Boolean options. None exposed; the v1 client
session.configOptions.booleancapability is never read. Candidates: native voice, auto-compaction. -
model_configcategory. Reasoning effort isthought_leveltoday, which is right, but any provider-specific knobs belong undermodel_config.
6. Multi-root and MCP transports
- Multi-root sessions. Accept
additionalDirectoriesonsession/new,load,resume,fork, and report them inSessionInfo. Depends on the runtime root model; todaycwdmust equal the runtime root. - HTTP MCP servers from clients.
src/tools/mcp.rsand v2 reject anything butstdio(session MCP servers support only stdio transport). Addhttpwithheaders(v1 alsosse) and advertisesession.mcp.httpin v2.
7. Elicitation
- Use
elicitation/create(stable since schema 1.7.0) when the client advertiseselicitation.formorelicitation.url. URL mode can replace the out-of-process terminal auth flow; form mode enables a structured ask-user tool. Kit never issues this request today.
8. Lifecycle completeness
-
session/deletein both versions. -
session/forkin v2 (v1 handles it, v2 has no handler). -
session/resumecursors. v2 only acceptsreplayFrom: start; anything else returnsUnsupported. - In-band auth.
authenticate/auth/loginalways returninvalid_params; onlyterminalauth methods are offered. Consider anagentauth method where a provider allows it.
9. Slash commands
- Real command surface. Only
compactis advertised, it has noinputhint, and it is dispatched by matching the literal prompt prefix/compactinsrc/compaction.rs. Give commands a proper dispatch path and advertise skills as commands with hints.
10. Unstable protocol extras
- Compaction updates. Emit
compaction_updateandcompaction_summary_chunk(unstable_session_compaction) instead of replaying summaries asagent_message_chunk. Gate on the v1 clientsession.compactioncapability. - End-turn token usage. Set
Usageon v1PromptResponse.usageand v2 idlestate_update.usage(unstable_end_turn_token_usage). - Providers.
providers/list|set|disable(unstable_llm_providers) so clients switch between openai, openrouter, and speakeasy. - Trace context in
_meta. Honor the reservedtraceparent,tracestate, andbaggagekeys and attach them to Kit telemetry spans. - HTTP transport hardening. Health endpoint and CORS are disabled on both routers in
src/protocols/http.rs. Track the Active streamable-HTTP RFD for v2 reconnection andLast-Event-IDresumption. - Agent registry manifest. Publish an
agent.jsonso ACP editors list Kit as installable.
Explicitly out of scope
session/request_permission: Kit has no approval path, so there is nothing to forward.- Client
fs/read_text_file/fs/write_text_file: not a feature Kit intends to support. - Client
terminal/*(v1): Kit runs shell locally.
Related: #25 (upstream inject dependencies), #36 (background compose activity view), #45 (provider retry progress to ACP parents).
Contributor guide
No contributing guide indexed for this repository
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
This is a broad ACP tracking issue rather than one implementation task. Start by reading the relevant entry points in src/protocols/acp.rs, src/protocols/acp/v2.rs, src/runlet_progress/, src/tools/mcp.rs, src/compaction.rs, and src/protocols/http.rs, then split one unchecked item into a scoped issue or PR. Done means the selected ACP behavior is implemented, advertised consistently, and its checklist item is checked.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100