@agentclientprotocol/claude-agent-acp 0.42.0 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -227,7 +227,7 @@ export declare class ClaudeAcpAgent implements Agent {
227
227
  /** Tear down all active sessions. Called when the ACP connection closes. */
228
228
  dispose(): Promise<void>;
229
229
  closeSession(params: CloseSessionRequest): Promise<CloseSessionResponse>;
230
- unstable_deleteSession(params: DeleteSessionRequest): Promise<DeleteSessionResponse>;
230
+ deleteSession(params: DeleteSessionRequest): Promise<DeleteSessionResponse>;
231
231
  setSessionMode(params: SetSessionModeRequest): Promise<SetSessionModeResponse>;
232
232
  setSessionConfigOption(params: SetSessionConfigOptionRequest): Promise<SetSessionConfigOptionResponse>;
233
233
  private applySessionMode;
@@ -235,10 +235,29 @@ export declare class ClaudeAcpAgent implements Agent {
235
235
  readTextFile(params: ReadTextFileRequest): Promise<ReadTextFileResponse>;
236
236
  writeTextFile(params: WriteTextFileRequest): Promise<WriteTextFileResponse>;
237
237
  canUseTool(sessionId: string): CanUseTool;
238
+ /**
239
+ * Handle elicitation requests that originate from MCP servers by forwarding
240
+ * them to the client over ACP. Modes the client did not advertise (or
241
+ * requests we can't represent) are declined.
242
+ */
243
+ private handleMcpElicitation;
244
+ /**
245
+ * Present the built-in AskUserQuestion tool's questions as an ACP form
246
+ * elicitation and return the answers as the tool's `updatedInput`. Called from
247
+ * `canUseTool` since that is where the SDK routes the tool's permission check.
248
+ */
249
+ private handleAskUserQuestion;
238
250
  private sendAvailableCommandsUpdate;
239
251
  private updateConfigOption;
240
252
  private applyConfigOptionValue;
241
253
  private getOrCreateSession;
254
+ /**
255
+ * Ensures the requested `cwd` is an absolute path that points at an existing
256
+ * directory before we create a session. Throws an `invalidParams` error with
257
+ * an actionable message so clients (e.g. Zed) can surface it to the user
258
+ * instead of failing later with an opaque SDK error.
259
+ */
260
+ private validateCwd;
242
261
  private createSession;
243
262
  }
244
263
  export declare function promptToClaude(prompt: PromptRequest): SDKUserMessage;
@@ -1 +1 @@
1
- {"version":3,"file":"acp-agent.d.ts","sourceRoot":"","sources":["../src/acp-agent.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"acp-agent.d.ts","sourceRoot":"","sources":["../src/acp-agent.ts"],"names":[],"mappings":"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"}
package/dist/acp-agent.js CHANGED
@@ -1,9 +1,11 @@
1
1
  import { AgentSideConnection, ndJsonStream, RequestError, } from "@agentclientprotocol/sdk";
2
2
  import { deleteSession, getSessionMessages, listSessions, query, } from "@anthropic-ai/claude-agent-sdk";
3
3
  import { randomUUID } from "node:crypto";
4
+ import * as fs from "node:fs/promises";
4
5
  import * as os from "node:os";
5
6
  import * as path from "node:path";
6
7
  import packageJson from "../package.json" with { type: "json" };
8
+ import { applyAskElicitationResponse, askUserQuestionsToCreateRequest, createElicitationResponseToElicitResult, extractAskUserQuestions, mcpElicitationToCreateRequest, } from "./elicitation.js";
7
9
  import { SettingsManager } from "./settings.js";
8
10
  import { applyTaskCreate, applyTaskUpdate, createPostToolUseHook, createTaskHook, parseTaskCreateOutput, planEntries, registerHookCallback, taskStateToPlanEntries, toolInfoFromToolUse, toolUpdateFromDiffToolResponse, toolUpdateFromToolResult, } from "./tools.js";
9
11
  import { nodeToWebReadable, nodeToWebWritable, Pushable, unreachable } from "./utils.js";
@@ -499,6 +501,21 @@ export class ClaudeAcpAgent {
499
501
  // `parent_tool_use_id === null` (subagent work is folded into tool-result
500
502
  // messages, never surfaced as partial streams).
501
503
  let currentStreamMessageId;
504
+ // Per-message-id record of which assistant content actually streamed live via
505
+ // `stream_event` deltas, split by block type. The `assistant` case below
506
+ // normally drops `text`/`thinking` blocks on the assumption they already
507
+ // reached the client as `agent_message_chunk`/`agent_thought_chunk`. That
508
+ // breaks behind Anthropic-protocol gateways that return a turn as a single
509
+ // non-streamed block (common with OpenAI-compatible proxies): no
510
+ // `content_block_delta` fires, so the assembled block is the only copy the
511
+ // client will ever see. We keep the filter per (id, block type) for content
512
+ // that did stream, and fall back to forwarding what did not. Split by type so
513
+ // a gateway that streams text but not thinking (or vice versa) doesn't lose
514
+ // the un-streamed block. Only top-level (`parent_tool_use_id === null`)
515
+ // streams are recorded — subagent text is never streamed and must stay
516
+ // filtered, as it is internal to the tool call.
517
+ const streamedTextIds = new Set();
518
+ const streamedThinkingIds = new Set();
502
519
  const userMessage = promptToClaude(params);
503
520
  const promptUuid = randomUUID();
504
521
  userMessage.uuid = promptUuid;
@@ -755,7 +772,23 @@ export class ClaudeAcpAgent {
755
772
  case "task_notification":
756
773
  case "task_progress":
757
774
  case "task_updated":
758
- case "elicitation_complete":
775
+ break;
776
+ case "elicitation_complete": {
777
+ // A url-mode MCP elicitation finished server-side. Let the client
778
+ // dismiss any UI it opened for it. Only meaningful when the
779
+ // client supports url elicitation; ignore failures otherwise.
780
+ if (this.clientCapabilities?.elicitation?.url) {
781
+ try {
782
+ await this.client.unstable_completeElicitation({
783
+ elicitationId: message.elicitation_id,
784
+ });
785
+ }
786
+ catch (error) {
787
+ this.logger.error(`Failed to complete elicitation: ${error}`);
788
+ }
789
+ }
790
+ break;
791
+ }
759
792
  case "plugin_install":
760
793
  case "notification":
761
794
  case "api_retry":
@@ -894,6 +927,21 @@ export class ClaudeAcpAgent {
894
927
  if (message.event.type === "message_start") {
895
928
  currentStreamMessageId = message.event.message.id || undefined;
896
929
  }
930
+ // Record that this top-level message id actually streamed text/
931
+ // thinking, so the `assistant` case below knows its assembled blocks
932
+ // are duplicates (filter them) rather than the only copy (forward
933
+ // them). Gated on `parent_tool_use_id === null` so a subagent stream
934
+ // can't attribute its content to the top-level message id.
935
+ if (currentStreamMessageId &&
936
+ message.parent_tool_use_id === null &&
937
+ message.event.type === "content_block_delta") {
938
+ if (message.event.delta.type === "text_delta") {
939
+ streamedTextIds.add(currentStreamMessageId);
940
+ }
941
+ else if (message.event.delta.type === "thinking_delta") {
942
+ streamedThinkingIds.add(currentStreamMessageId);
943
+ }
944
+ }
897
945
  if (message.parent_tool_use_id === null &&
898
946
  (message.event.type === "message_start" || message.event.type === "message_delta")) {
899
947
  if (message.event.type === "message_start") {
@@ -1049,10 +1097,46 @@ export class ClaudeAcpAgent {
1049
1097
  message.message.content[0].text.includes("Please run /login")) {
1050
1098
  throw RequestError.authRequired();
1051
1099
  }
1052
- const content = message.type === "assistant"
1053
- ? // Handled by stream events above
1054
- message.message.content.filter((item) => !["text", "thinking"].includes(item.type))
1055
- : message.message.content;
1100
+ let content;
1101
+ if (message.type === "assistant" && message.parent_tool_use_id === null) {
1102
+ // Top-level assistant message: drop text/thinking blocks already
1103
+ // streamed live as chunks, and forward (as a fallback) any that were
1104
+ // not, so non-streaming gateways still deliver the final answer.
1105
+ const id = messageIdForGrouping(message);
1106
+ content = message.message.content.filter((item) => {
1107
+ // Non-text blocks (tool_use, etc.) always pass through; their own
1108
+ // dedupe (`toolUseCache`) collapses the streamed/assembled pair.
1109
+ if (item.type !== "text" && item.type !== "thinking") {
1110
+ return true;
1111
+ }
1112
+ // Already delivered live as a chunk of this exact type — drop the
1113
+ // duplicate. Checked per type so streaming one (e.g. text) doesn't
1114
+ // suppress an un-streamed block of the other (e.g. thinking).
1115
+ const streamedLive = id !== undefined &&
1116
+ (item.type === "text" ? streamedTextIds : streamedThinkingIds).has(id);
1117
+ if (streamedLive) {
1118
+ return false;
1119
+ }
1120
+ // Empty assembled blocks carry nothing (some gateways emit an empty
1121
+ // `thinking` block before the real text) — don't forward stray
1122
+ // empty chunks.
1123
+ const text = item.type === "text" ? item.text : item.thinking;
1124
+ if (text.length === 0) {
1125
+ return false;
1126
+ }
1127
+ return true;
1128
+ });
1129
+ }
1130
+ else if (message.type === "assistant") {
1131
+ // Subagent assistant message (`parent_tool_use_id !== null`). It is
1132
+ // never streamed live and its text/thinking is internal to the tool
1133
+ // call — keep dropping it so subagent prose doesn't leak into the
1134
+ // top-level feed.
1135
+ content = message.message.content.filter((item) => item.type !== "text" && item.type !== "thinking");
1136
+ }
1137
+ else {
1138
+ content = message.message.content;
1139
+ }
1056
1140
  for (const notification of toAcpNotifications(content, message.message.role, params.sessionId, session.toolUseCache, this.client, this.logger, {
1057
1141
  clientCapabilities: this.clientCapabilities,
1058
1142
  parentToolUseId: message.parent_tool_use_id,
@@ -1253,7 +1337,7 @@ export class ClaudeAcpAgent {
1253
1337
  await this.teardownSession(params.sessionId);
1254
1338
  return {};
1255
1339
  }
1256
- async unstable_deleteSession(params) {
1340
+ async deleteSession(params) {
1257
1341
  // Tear down any active in-memory state first so the on-disk file isn't
1258
1342
  // recreated by an outstanding query writing to it.
1259
1343
  if (this.sessions[params.sessionId]) {
@@ -1415,6 +1499,13 @@ export class ClaudeAcpAgent {
1415
1499
  message: "Session not found",
1416
1500
  };
1417
1501
  }
1502
+ // AskUserQuestion is surfaced to us as a normal permission check (the SDK
1503
+ // routes it through canUseTool whenever a callback is registered, rather
1504
+ // than the interactive dialog). Present it as an ACP form elicitation and
1505
+ // feed the answers back as updatedInput for the tool's own call() to read.
1506
+ if (toolName === "AskUserQuestion" && this.clientCapabilities?.elicitation?.form) {
1507
+ return this.handleAskUserQuestion(sessionId, toolInput, toolUseID, signal);
1508
+ }
1418
1509
  if (toolName === "ExitPlanMode") {
1419
1510
  const optionsAll = [
1420
1511
  { kind: "allow_always", name: 'Yes, and use "auto" mode', optionId: "auto" },
@@ -1540,6 +1631,62 @@ export class ClaudeAcpAgent {
1540
1631
  }
1541
1632
  };
1542
1633
  }
1634
+ /**
1635
+ * Handle elicitation requests that originate from MCP servers by forwarding
1636
+ * them to the client over ACP. Modes the client did not advertise (or
1637
+ * requests we can't represent) are declined.
1638
+ */
1639
+ handleMcpElicitation(sessionId, support) {
1640
+ return async (request, { signal }) => {
1641
+ const isUrl = request.mode === "url";
1642
+ if ((isUrl && !support.url) || (!isUrl && !support.form)) {
1643
+ return { action: "decline" };
1644
+ }
1645
+ const createRequest = mcpElicitationToCreateRequest(request, sessionId);
1646
+ if (!createRequest) {
1647
+ return { action: "decline" };
1648
+ }
1649
+ try {
1650
+ const response = await this.client.unstable_createElicitation(createRequest);
1651
+ if (signal.aborted) {
1652
+ return { action: "cancel" };
1653
+ }
1654
+ return createElicitationResponseToElicitResult(response);
1655
+ }
1656
+ catch (error) {
1657
+ this.logger.error(`Failed to forward MCP elicitation: ${error}`);
1658
+ return { action: "decline" };
1659
+ }
1660
+ };
1661
+ }
1662
+ /**
1663
+ * Present the built-in AskUserQuestion tool's questions as an ACP form
1664
+ * elicitation and return the answers as the tool's `updatedInput`. Called from
1665
+ * `canUseTool` since that is where the SDK routes the tool's permission check.
1666
+ */
1667
+ async handleAskUserQuestion(sessionId, toolInput, toolUseID, signal) {
1668
+ const questions = extractAskUserQuestions(toolInput);
1669
+ if (!questions) {
1670
+ return { behavior: "deny", message: "AskUserQuestion called with no valid questions." };
1671
+ }
1672
+ const createRequest = askUserQuestionsToCreateRequest(questions, sessionId, toolUseID);
1673
+ let response;
1674
+ try {
1675
+ response = await this.client.unstable_createElicitation(createRequest);
1676
+ }
1677
+ catch (error) {
1678
+ this.logger.error(`Failed to present AskUserQuestion elicitation: ${error}`);
1679
+ return { behavior: "deny", message: "Could not present the question to the user." };
1680
+ }
1681
+ if (signal.aborted) {
1682
+ throw new Error("Tool use aborted");
1683
+ }
1684
+ const outcome = applyAskElicitationResponse(response, toolInput, questions);
1685
+ if (outcome.action === "cancel") {
1686
+ throw new Error("Tool use aborted");
1687
+ }
1688
+ return { behavior: "allow", updatedInput: outcome.updatedInput };
1689
+ }
1543
1690
  async sendAvailableCommandsUpdate(sessionId) {
1544
1691
  const session = this.sessions[sessionId];
1545
1692
  if (!session)
@@ -1676,7 +1823,34 @@ export class ClaudeAcpAgent {
1676
1823
  configOptions: response.configOptions,
1677
1824
  };
1678
1825
  }
1826
+ /**
1827
+ * Ensures the requested `cwd` is an absolute path that points at an existing
1828
+ * directory before we create a session. Throws an `invalidParams` error with
1829
+ * an actionable message so clients (e.g. Zed) can surface it to the user
1830
+ * instead of failing later with an opaque SDK error.
1831
+ */
1832
+ async validateCwd(cwd) {
1833
+ if (!path.isAbsolute(cwd)) {
1834
+ throw RequestError.invalidParams({ cwd }, `\`cwd\` must be an absolute path, but received: ${cwd}`);
1835
+ }
1836
+ let stats;
1837
+ try {
1838
+ stats = await fs.stat(cwd);
1839
+ }
1840
+ catch {
1841
+ throw RequestError.invalidParams({ cwd }, `\`cwd\` does not exist on the machine running the agent: ${cwd}`);
1842
+ }
1843
+ if (!stats.isDirectory()) {
1844
+ throw RequestError.invalidParams({ cwd }, `\`cwd\` is not a directory: ${cwd}`);
1845
+ }
1846
+ }
1679
1847
  async createSession(params, creationOpts = {}) {
1848
+ // Validate `cwd` up front. The ACP spec requires an absolute path, and the
1849
+ // directory must actually exist on the machine running the agent. Without
1850
+ // this check a session is created against a missing directory and the
1851
+ // failure only surfaces later as a confusing "native binary failed to
1852
+ // launch" error from the SDK (see issue #749).
1853
+ await this.validateCwd(params.cwd);
1680
1854
  // We want to create a new session id unless it is resume,
1681
1855
  // but not resume + forkSession.
1682
1856
  let sessionId;
@@ -1746,8 +1920,17 @@ export class ClaudeAcpAgent {
1746
1920
  const thinking = resolveThinkingConfig(process.env.MAX_THINKING_TOKENS, this.logger);
1747
1921
  // Parse model configuration from environment (e.g. Bedrock model overrides)
1748
1922
  const modelConfig = parseModelConfig(process.env.CLAUDE_MODEL_CONFIG);
1749
- // Disable this for now, not a great way to expose this over ACP at the moment (in progress work so we can revisit)
1750
- const disallowedTools = ["AskUserQuestion"];
1923
+ // Elicitation modes the connected client advertised. We only forward
1924
+ // elicitations (and only re-enable AskUserQuestion) for modes the client
1925
+ // can actually render.
1926
+ const elicitationSupport = {
1927
+ form: !!this.clientCapabilities?.elicitation?.form,
1928
+ url: !!this.clientCapabilities?.elicitation?.url,
1929
+ };
1930
+ // AskUserQuestion surfaces as a `permission_ask_user_question` dialog that
1931
+ // we render as a form elicitation. Without form-elicitation support there
1932
+ // is no way to present it over ACP, so keep it disabled in that case.
1933
+ const disallowedTools = elicitationSupport.form ? [] : ["AskUserQuestion"];
1751
1934
  // Resolve which built-in tools to expose.
1752
1935
  // Explicit tools array from _meta.claudeCode.options takes precedence.
1753
1936
  // disableBuiltInTools is a legacy shorthand for tools: [] — kept for
@@ -1791,6 +1974,13 @@ export class ClaudeAcpAgent {
1791
1974
  allowDangerouslySkipPermissions: ALLOW_BYPASS,
1792
1975
  permissionMode,
1793
1976
  canUseTool: this.canUseTool(sessionId),
1977
+ // Forward MCP elicitation requests onto ACP elicitation. Only attached
1978
+ // when the client advertised support, so non-supporting clients keep the
1979
+ // SDK's default (auto-decline) behavior. (AskUserQuestion is handled in
1980
+ // canUseTool, not here.)
1981
+ ...(elicitationSupport.form || elicitationSupport.url
1982
+ ? { onElicitation: this.handleMcpElicitation(sessionId, elicitationSupport) }
1983
+ : {}),
1794
1984
  pathToClaudeCodeExecutable: process.env.CLAUDE_CODE_EXECUTABLE ?? (await claudeCliPath()),
1795
1985
  extraArgs: {
1796
1986
  ...userProvidedOptions?.extraArgs,
@@ -0,0 +1,80 @@
1
+ import type { CreateElicitationRequest, CreateElicitationResponse } from "@agentclientprotocol/sdk";
2
+ import type { ElicitationRequest, ElicitationResult } from "@anthropic-ai/claude-agent-sdk";
3
+ import type { AskUserQuestionInput } from "@anthropic-ai/claude-agent-sdk/sdk-tools.js";
4
+ /**
5
+ * Bridges between the Claude Agent SDK's elicitation/dialog callbacks and ACP's
6
+ * (unstable) elicitation protocol.
7
+ *
8
+ * Two distinct SDK surfaces flow through here:
9
+ *
10
+ * 1. `onElicitation` — fired when an MCP server requests user input. These map
11
+ * directly onto ACP `session/create_elicitation` (form or url mode).
12
+ * 2. The built-in AskUserQuestion tool — when a `canUseTool` callback is
13
+ * registered the SDK routes its permission check through `canUseTool`
14
+ * (not the interactive `permission_ask_user_question` dialog). We render
15
+ * its questions as an ACP form elicitation and feed the user's selections
16
+ * back as the tool's `updatedInput`, which the tool's own `call()` reads.
17
+ */
18
+ /** Modes the connected client advertised support for. */
19
+ export type ElicitationSupport = {
20
+ form: boolean;
21
+ url: boolean;
22
+ };
23
+ /**
24
+ * Convert an MCP elicitation request (from the SDK's `onElicitation` callback)
25
+ * into an ACP `CreateElicitationRequest`. Returns `null` when the request can't
26
+ * be represented (e.g. a url-mode request with no url).
27
+ */
28
+ export declare function mcpElicitationToCreateRequest(request: ElicitationRequest, sessionId: string): CreateElicitationRequest | null;
29
+ /**
30
+ * Map an ACP elicitation response back to the MCP `ElicitResult` the SDK expects
31
+ * to hand back to the requesting server.
32
+ */
33
+ export declare function createElicitationResponseToElicitResult(response: CreateElicitationResponse): ElicitationResult;
34
+ /**
35
+ * A single question as supplied by the AskUserQuestion tool. Derived from the
36
+ * SDK's input type so the shape stays in sync; the SDK validates the model's
37
+ * tool call against this schema before it reaches us.
38
+ */
39
+ export type AskUserQuestion = AskUserQuestionInput["questions"][number];
40
+ /**
41
+ * Pull the well-formed questions out of an AskUserQuestion tool input. Returns
42
+ * `null` when there are no usable questions — including the case where every
43
+ * entry is malformed and filtering leaves an empty list — so callers can treat
44
+ * "nothing to ask" uniformly.
45
+ */
46
+ export declare function extractAskUserQuestions(input: Record<string, unknown>): AskUserQuestion[] | null;
47
+ /**
48
+ * Render the AskUserQuestion tool's questions as an ACP form elicitation.
49
+ *
50
+ * Fields are keyed by a short stable id (`question_<n>`) rather than the full
51
+ * question text, so the question text appears in exactly one place per field.
52
+ * Single-select questions use a titled `oneOf` enum; multi-select questions use
53
+ * an array with a titled `anyOf` item enum. The enum `const` is always the
54
+ * option label, since that is what the tool records as the answer.
55
+ *
56
+ * A trailing optional free-text field mirrors the CLI's custom-answer box: the
57
+ * user can type their own answer instead of (or as well as) picking an option.
58
+ * Nothing is marked required, so the user can also just skip — matching the
59
+ * built-in tool, which always offers Skip + a free-text box.
60
+ */
61
+ export declare function askUserQuestionsToCreateRequest(questions: AskUserQuestion[], sessionId: string, toolCallId: string | undefined): CreateElicitationRequest;
62
+ /** Outcome of an AskUserQuestion elicitation, decoupled from any transport. */
63
+ export type AskUserQuestionOutcome = {
64
+ action: "answered";
65
+ updatedInput: Record<string, unknown>;
66
+ } | {
67
+ action: "cancel";
68
+ };
69
+ /**
70
+ * Fold an ACP elicitation response into the AskUserQuestion tool's input.
71
+ *
72
+ * Selected labels are read back from the indexed form fields and written into
73
+ * `answers` as a `{ [questionText]: label }` map (comma-joining multi-selects)
74
+ * — the key shape the tool's own `call()` reads. Free text from the custom-
75
+ * answer field becomes the tool's top-level `response`. Decline yields empty
76
+ * answers (the model is told the user skipped rather than the turn aborting);
77
+ * cancel aborts the tool call.
78
+ */
79
+ export declare function applyAskElicitationResponse(response: CreateElicitationResponse, toolInput: Record<string, unknown>, questions: AskUserQuestion[]): AskUserQuestionOutcome;
80
+ //# sourceMappingURL=elicitation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"elicitation.d.ts","sourceRoot":"","sources":["../src/elicitation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,wBAAwB,EACxB,yBAAyB,EAI1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,gCAAgC,CAAC;AAC5F,OAAO,KAAK,EACV,oBAAoB,EAErB,MAAM,6CAA6C,CAAC;AAErD;;;;;;;;;;;;;GAaG;AAEH,yDAAyD;AACzD,MAAM,MAAM,kBAAkB,GAAG;IAC/B,IAAI,EAAE,OAAO,CAAC;IACd,GAAG,EAAE,OAAO,CAAC;CACd,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,6BAA6B,CAC3C,OAAO,EAAE,kBAAkB,EAC3B,SAAS,EAAE,MAAM,GAChB,wBAAwB,GAAG,IAAI,CAyBjC;AAED;;;GAGG;AACH,wBAAgB,uCAAuC,CACrD,QAAQ,EAAE,yBAAyB,GAClC,iBAAiB,CAUnB;AAED;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,oBAAoB,CAAC,WAAW,CAAC,CAAC,MAAM,CAAC,CAAC;AAExE;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,eAAe,EAAE,GAAG,IAAI,CAUhG;AAUD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,+BAA+B,CAC7C,SAAS,EAAE,eAAe,EAAE,EAC5B,SAAS,EAAE,MAAM,EACjB,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,wBAAwB,CAyC1B;AAED,+EAA+E;AAC/E,MAAM,MAAM,sBAAsB,GAC9B;IAAE,MAAM,EAAE,UAAU,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,GAC7D;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,CAAC;AAEzB;;;;;;;;;GASG;AACH,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,yBAAyB,EACnC,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClC,SAAS,EAAE,eAAe,EAAE,GAC3B,sBAAsB,CAiCxB"}
@@ -0,0 +1,166 @@
1
+ import { randomUUID } from "node:crypto";
2
+ /**
3
+ * Convert an MCP elicitation request (from the SDK's `onElicitation` callback)
4
+ * into an ACP `CreateElicitationRequest`. Returns `null` when the request can't
5
+ * be represented (e.g. a url-mode request with no url).
6
+ */
7
+ export function mcpElicitationToCreateRequest(request, sessionId) {
8
+ if (request.mode === "url") {
9
+ if (!request.url) {
10
+ return null;
11
+ }
12
+ return {
13
+ mode: "url",
14
+ sessionId,
15
+ message: request.message,
16
+ url: request.url,
17
+ // URL elicitations need a stable id so the client can correlate the
18
+ // later `session/complete_elicitation` notification. MCP servers usually
19
+ // provide one; fall back to a generated id if not.
20
+ elicitationId: request.elicitationId ?? randomUUID(),
21
+ };
22
+ }
23
+ // Form mode (the default). The MCP `requestedSchema` is already a JSON Schema
24
+ // with primitive-typed properties, which is structurally what ACP expects.
25
+ return {
26
+ mode: "form",
27
+ sessionId,
28
+ message: request.message,
29
+ requestedSchema: normalizeElicitationSchema(request.requestedSchema),
30
+ };
31
+ }
32
+ /**
33
+ * Map an ACP elicitation response back to the MCP `ElicitResult` the SDK expects
34
+ * to hand back to the requesting server.
35
+ */
36
+ export function createElicitationResponseToElicitResult(response) {
37
+ switch (response.action) {
38
+ case "accept":
39
+ return { action: "accept", content: response.content ?? {} };
40
+ case "decline":
41
+ return { action: "decline" };
42
+ case "cancel":
43
+ default:
44
+ return { action: "cancel" };
45
+ }
46
+ }
47
+ /**
48
+ * Pull the well-formed questions out of an AskUserQuestion tool input. Returns
49
+ * `null` when there are no usable questions — including the case where every
50
+ * entry is malformed and filtering leaves an empty list — so callers can treat
51
+ * "nothing to ask" uniformly.
52
+ */
53
+ export function extractAskUserQuestions(input) {
54
+ const questions = input.questions;
55
+ if (!Array.isArray(questions)) {
56
+ return null;
57
+ }
58
+ const valid = questions.filter((q) => !!q && typeof q.question === "string" && Array.isArray(q.options) && q.options.length > 0);
59
+ return valid.length > 0 ? valid : null;
60
+ }
61
+ /** Stable form-field key for the question at the given index. */
62
+ function questionFieldKey(index) {
63
+ return `question_${index}`;
64
+ }
65
+ /** Form-field key for the optional free-text "custom answer" field. */
66
+ const CUSTOM_ANSWER_FIELD = "customAnswer";
67
+ /**
68
+ * Render the AskUserQuestion tool's questions as an ACP form elicitation.
69
+ *
70
+ * Fields are keyed by a short stable id (`question_<n>`) rather than the full
71
+ * question text, so the question text appears in exactly one place per field.
72
+ * Single-select questions use a titled `oneOf` enum; multi-select questions use
73
+ * an array with a titled `anyOf` item enum. The enum `const` is always the
74
+ * option label, since that is what the tool records as the answer.
75
+ *
76
+ * A trailing optional free-text field mirrors the CLI's custom-answer box: the
77
+ * user can type their own answer instead of (or as well as) picking an option.
78
+ * Nothing is marked required, so the user can also just skip — matching the
79
+ * built-in tool, which always offers Skip + a free-text box.
80
+ */
81
+ export function askUserQuestionsToCreateRequest(questions, sessionId, toolCallId) {
82
+ const single = questions.length === 1;
83
+ const properties = {};
84
+ questions.forEach((question, index) => {
85
+ const options = question.options.map((option) => ({
86
+ const: option.label,
87
+ title: option.description ? `${option.label} — ${option.description}` : option.label,
88
+ }));
89
+ // For a single question the prompt is carried by `message`, so we don't
90
+ // repeat it in the field description. With multiple questions each field
91
+ // needs its own question text.
92
+ const description = single ? undefined : question.question;
93
+ const title = question.header || undefined;
94
+ properties[questionFieldKey(index)] = question.multiSelect
95
+ ? { type: "array", title, description, items: { anyOf: options } }
96
+ : { type: "string", title, description, oneOf: options };
97
+ });
98
+ properties[CUSTOM_ANSWER_FIELD] = {
99
+ type: "string",
100
+ title: "Other",
101
+ description: "Type your own answer instead of choosing an option above (optional).",
102
+ };
103
+ const requestedSchema = {
104
+ type: "object",
105
+ properties,
106
+ };
107
+ const message = single ? questions[0].question : "Please answer the following questions.";
108
+ return {
109
+ mode: "form",
110
+ sessionId,
111
+ ...(toolCallId ? { toolCallId } : {}),
112
+ message,
113
+ requestedSchema,
114
+ };
115
+ }
116
+ /**
117
+ * Fold an ACP elicitation response into the AskUserQuestion tool's input.
118
+ *
119
+ * Selected labels are read back from the indexed form fields and written into
120
+ * `answers` as a `{ [questionText]: label }` map (comma-joining multi-selects)
121
+ * — the key shape the tool's own `call()` reads. Free text from the custom-
122
+ * answer field becomes the tool's top-level `response`. Decline yields empty
123
+ * answers (the model is told the user skipped rather than the turn aborting);
124
+ * cancel aborts the tool call.
125
+ */
126
+ export function applyAskElicitationResponse(response, toolInput, questions) {
127
+ if (response.action === "cancel") {
128
+ return { action: "cancel" };
129
+ }
130
+ if (response.action === "decline") {
131
+ return { action: "answered", updatedInput: { ...toolInput, answers: {} } };
132
+ }
133
+ const content = response.content ?? {};
134
+ // Typed against the tool's own output schema so the answer/response shapes
135
+ // stay in sync with what the built-in tool's call() expects to read back.
136
+ const answers = {};
137
+ questions.forEach((question, index) => {
138
+ const value = content[questionFieldKey(index)];
139
+ if (value === undefined || value === null) {
140
+ return;
141
+ }
142
+ const text = Array.isArray(value) ? value.join(", ") : String(value);
143
+ if (text === "") {
144
+ return;
145
+ }
146
+ answers[question.question] = text;
147
+ });
148
+ const updatedInput = { ...toolInput, answers };
149
+ const custom = content[CUSTOM_ANSWER_FIELD];
150
+ if (typeof custom === "string" && custom.trim() !== "") {
151
+ const response = custom;
152
+ updatedInput.response = response;
153
+ }
154
+ return { action: "answered", updatedInput };
155
+ }
156
+ /**
157
+ * Coerce an arbitrary MCP `requestedSchema` into an ACP `ElicitationSchema`.
158
+ * The two are structurally compatible JSON Schemas; we just guarantee the
159
+ * `type: "object"` discriminator is present.
160
+ */
161
+ function normalizeElicitationSchema(schema) {
162
+ if (!schema || typeof schema !== "object") {
163
+ return { type: "object", properties: {} };
164
+ }
165
+ return { ...schema, type: "object" };
166
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../src/tools.ts"],"names":[],"mappings":"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"}
package/dist/tools.js CHANGED
@@ -274,6 +274,22 @@ export function toolInfoFromToolUse(toolUse, supportsTerminalOutput = false, cwd
274
274
  : [],
275
275
  };
276
276
  }
277
+ case "AskUserQuestion": {
278
+ const input = toolUse.input;
279
+ const questions = Array.isArray(input?.questions) ? input.questions : [];
280
+ return {
281
+ title: questions.length === 1 && questions[0]?.question
282
+ ? questions[0].question
283
+ : "Asking for your input",
284
+ kind: "other",
285
+ content: questions
286
+ .filter((q) => typeof q?.question === "string")
287
+ .map((q) => ({
288
+ type: "content",
289
+ content: { type: "text", text: q.question },
290
+ })),
291
+ };
292
+ }
277
293
  case "Other": {
278
294
  const input = toolUse.input;
279
295
  let output;
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.42.0",
6
+ "version": "0.43.0",
7
7
  "description": "An ACP-compatible coding agent powered by the Claude Agent SDK (TypeScript)",
8
8
  "main": "dist/lib.js",
9
9
  "types": "dist/lib.d.ts",
@@ -60,14 +60,14 @@
60
60
  "author": "Zed Industries",
61
61
  "license": "Apache-2.0",
62
62
  "dependencies": {
63
- "@agentclientprotocol/sdk": "0.24.0",
64
- "@anthropic-ai/claude-agent-sdk": "0.3.165",
63
+ "@agentclientprotocol/sdk": "0.25.0",
64
+ "@anthropic-ai/claude-agent-sdk": "0.3.169",
65
65
  "zod": "^3.25.0 || ^4.0.0"
66
66
  },
67
67
  "devDependencies": {
68
- "@anthropic-ai/sdk": "0.100.1",
68
+ "@anthropic-ai/sdk": "0.102.0",
69
69
  "@eslint/js": "10.0.1",
70
- "@types/node": "25.9.1",
70
+ "@types/node": "25.9.2",
71
71
  "@typescript-eslint/eslint-plugin": "8.60.1",
72
72
  "@typescript-eslint/parser": "8.60.1",
73
73
  "eslint": "10.4.1",