@agentclientprotocol/claude-agent-acp 0.98.1-preview.3 → 0.98.1-preview.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/v2/agent.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,mDAAmD,CAAC;AACxE,OAAO,EAAE,cAAc,EAAkB,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAoB9E;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACvC,EAAE,CAAC,QAAQ,CAqFb"}
1
+ {"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../src/v2/agent.ts"],"names":[],"mappings":"AAeA,OAAO,KAAK,EAAE,MAAM,mDAAmD,CAAC;AACxE,OAAO,EAAE,cAAc,EAAkB,KAAK,MAAM,EAAE,MAAM,iBAAiB,CAAC;AAqB9E;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,GAAG,SAAS,EAC1B,OAAO,EAAE,CAAC,KAAK,EAAE,cAAc,KAAK,IAAI,GACvC,EAAE,CAAC,QAAQ,CA8Fb"}
package/dist/v2/agent.js CHANGED
@@ -7,6 +7,7 @@ import { v1ForkSessionRequest, v1NewSessionRequest, v1RestoreSessionRequest, v1S
7
7
  import { v2ChildStateUpdate, v2SessionUpdate } from "./session-update.js";
8
8
  import { V2Terminals } from "./terminal.js";
9
9
  import { V2ToolCallMeta } from "./tool-call-meta.js";
10
+ import { v2RestartedToolCall } from "./tool-call.js";
10
11
  /**
11
12
  * The ACP v2 surface, for one connection.
12
13
  *
@@ -81,7 +82,16 @@ export function v2AgentApp(logger, onAgent) {
81
82
  .onRequest(v2.methods.agent.session.delete, ({ params }) => agent.deleteSession(params))
82
83
  .onRequest(v2.methods.agent.session.setConfigOption, async ({ params }) => {
83
84
  const { configOptions, ...response } = await agent.setSessionConfigOption(v1SetSessionConfigOptionRequest(params));
84
- return { ...response, configOptions: v2ConfigOptions(configOptions) };
85
+ // v2 asks for a `config_option_update` on every config change, also one
86
+ // that a client requested, so other attached clients see it. It goes
87
+ // before the response, as v2 asks of this duplicate. The agent sends v1
88
+ // clients none: they read the change from the response only.
89
+ const options = v2ConfigOptions(configOptions);
90
+ void client.send({
91
+ sessionId: params.sessionId,
92
+ update: { sessionUpdate: "config_option_update", configOptions: options },
93
+ });
94
+ return { ...response, configOptions: options };
85
95
  })
86
96
  .onRequest(v2.methods.agent.session.prompt, ({ params }) => v2Prompt(agent, params, (update) => {
87
97
  void client.send({ sessionId: params.sessionId, update });
@@ -239,8 +249,14 @@ class V2ClientConnection {
239
249
  if (!report)
240
250
  return terminal;
241
251
  const starts = report.sessionUpdate === "tool_call";
242
- const [reported, metaPatch] = this.toolCallMeta.apply(sessionId, report, starts, this.replays.has(sessionId));
243
- const reportUpdate = v2SessionUpdate(reported);
252
+ const replaying = this.replays.has(sessionId);
253
+ // A v1 `tool_call` starts the tool call afresh, but v2 only has updates,
254
+ // which keep each field they leave out. The client may already hold this
255
+ // id: from an earlier report on this connection, or, during a replay, from
256
+ // before it (a client that resumes a session it showed before).
257
+ const restarts = starts && (replaying || this.toolCallMeta.reported(sessionId, report.toolCallId));
258
+ const [reported, metaPatch] = this.toolCallMeta.apply(sessionId, report, starts, replaying);
259
+ const reportUpdate = restarts ? v2RestartedToolCall(reported) : v2SessionUpdate(reported);
244
260
  const metaUpdate = metaPatch
245
261
  ? v2SessionUpdate({ sessionUpdate: "tool_call_update", ...metaPatch })
246
262
  : undefined;
@@ -45,9 +45,11 @@ export declare function v2Prompt(agent: ClaudeAcpAgent, params: v2.PromptRequest
45
45
  */
46
46
  export declare function v2Foreground(send: (update: v2.SessionUpdate) => void): ForegroundEvents;
47
47
  /**
48
- * A v2 prompt may hold content blocks that v1 cannot express: a custom one,
49
- * or one from a newer ACP version. Clients send only the kinds the agent
50
- * advertised, so such a block is rejected rather than silently dropped.
48
+ * A v2 prompt may hold content blocks that the agent does not take: audio,
49
+ * which it does not advertise and Claude cannot read, a custom one, or one
50
+ * from a newer ACP version. Clients send only the kinds the agent advertised,
51
+ * so such a block fails the request with invalid params (-32602) rather than
52
+ * being dropped from the prompt.
51
53
  */
52
54
  export declare function v1PromptRequest({ prompt, ...request }: v2.PromptRequest): PromptRequest;
53
55
  export declare function v1ContentBlock(block: v2.ContentBlock): ContentBlock;
@@ -1 +1 @@
1
- {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/v2/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,aAAa,EAEnB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,mDAAmD,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAuC,MAAM,mBAAmB,CAAC;AAE/F;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,EAAE,CAAC,aAAa,EACxB,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,GACvC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,CAiC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,GAAG,gBAAgB,CAoBvF;AAgCD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,aAAa,GAAG,aAAa,CAEvF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,GAAG,YAAY,CAenE"}
1
+ {"version":3,"file":"prompt.d.ts","sourceRoot":"","sources":["../../src/v2/prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AACH,OAAO,EAGL,KAAK,YAAY,EACjB,KAAK,aAAa,EAEnB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,KAAK,EAAE,MAAM,mDAAmD,CAAC;AACxE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AACtD,OAAO,KAAK,EAAE,gBAAgB,EAAuC,MAAM,mBAAmB,CAAC;AAE/F;;;;;;;;;;;GAWG;AACH,wBAAgB,QAAQ,CACtB,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,EAAE,CAAC,aAAa,EACxB,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,GACvC,OAAO,CAAC,EAAE,CAAC,cAAc,CAAC,CAiC5B;AAED;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,YAAY,CAAC,IAAI,EAAE,CAAC,MAAM,EAAE,EAAE,CAAC,aAAa,KAAK,IAAI,GAAG,gBAAgB,CAoBvF;AAgCD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,EAAE,MAAM,EAAE,GAAG,OAAO,EAAE,EAAE,EAAE,CAAC,aAAa,GAAG,aAAa,CAEvF;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,EAAE,CAAC,YAAY,GAAG,YAAY,CAcnE"}
package/dist/v2/prompt.js CHANGED
@@ -122,9 +122,11 @@ function idle({ stopReason, usage, _meta }) {
122
122
  return { sessionUpdate: "state_update", state: "idle", ...state };
123
123
  }
124
124
  /**
125
- * A v2 prompt may hold content blocks that v1 cannot express: a custom one,
126
- * or one from a newer ACP version. Clients send only the kinds the agent
127
- * advertised, so such a block is rejected rather than silently dropped.
125
+ * A v2 prompt may hold content blocks that the agent does not take: audio,
126
+ * which it does not advertise and Claude cannot read, a custom one, or one
127
+ * from a newer ACP version. Clients send only the kinds the agent advertised,
128
+ * so such a block fails the request with invalid params (-32602) rather than
129
+ * being dropped from the prompt.
128
130
  */
129
131
  export function v1PromptRequest({ prompt, ...request }) {
130
132
  return { ...request, prompt: prompt.map(v1ContentBlock) };
@@ -132,7 +134,6 @@ export function v1PromptRequest({ prompt, ...request }) {
132
134
  export function v1ContentBlock(block) {
133
135
  if (v2.ContentBlock.isText(block) ||
134
136
  v2.ContentBlock.isImage(block) ||
135
- v2.ContentBlock.isAudio(block) ||
136
137
  v2.ContentBlock.isResourceLink(block) ||
137
138
  v2.ContentBlock.isResource(block)) {
138
139
  const { annotations, ...rest } = block;
@@ -123,8 +123,10 @@ function v2ConfigOptionsField(options) {
123
123
  /**
124
124
  * v2 requires a `type` on every transport and makes the empty lists optional.
125
125
  * The agent recognizes a v1 stdio server by its missing `type`, so the v2 tag
126
- * is dropped. A transport that v1 cannot express is rejected rather than
127
- * silently left out of the session.
126
+ * is dropped. Any other transport, such as `acp` or a custom `_` type, fails
127
+ * the request with invalid params (-32602): the agent advertises only stdio
128
+ * and HTTP, and the v1 session setup would otherwise drop the server without
129
+ * telling the client.
128
130
  */
129
131
  function v1McpServer(server) {
130
132
  if (v2.McpServer.isStdio(server)) {
@@ -134,8 +136,5 @@ function v1McpServer(server) {
134
136
  if (v2.McpServer.isHttp(server)) {
135
137
  return { ...server, headers: server.headers ?? [] };
136
138
  }
137
- if (v2.McpServer.isAcp(server)) {
138
- return server;
139
- }
140
139
  throw RequestError.invalidParams({ type: server.type }, `MCP servers of type ${server.type} are not supported`);
141
140
  }
@@ -45,6 +45,8 @@ export declare class V2ToolCallMeta {
45
45
  * a client can show the request from the request alone.
46
46
  */
47
47
  subject<Report extends ToolCall | ToolCallUpdate>(sessionId: string, toolCall: Report): Report;
48
+ /** Whether this connection reported the tool call, so the client holds it. */
49
+ reported(sessionId: string, toolCallId: string): boolean;
48
50
  /** Forgets the tool calls of a session, when it closes. */
49
51
  forget(sessionId: string): void;
50
52
  /** Stores the entry as the most recent one, and forgets the oldest one past the limit. */
@@ -1 +1 @@
1
- {"version":3,"file":"tool-call-meta.d.ts","sourceRoot":"","sources":["../../src/v2/tool-call-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAOlF,qBAAa,cAAc;IACzB,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqD;IAE3E;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,MAAM,SAAS,QAAQ,GAAG,cAAc,EAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,SAAS,UAAQ,GAChB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IA6CtC;;;;OAIG;IACH,OAAO,CAAC,MAAM,SAAS,QAAQ,GAAG,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAO9F,2DAA2D;IAC3D,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAM/B,0FAA0F;IAC1F,OAAO,CAAC,QAAQ;CAQjB"}
1
+ {"version":3,"file":"tool-call-meta.d.ts","sourceRoot":"","sources":["../../src/v2/tool-call-meta.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAE,cAAc,EAAE,MAAM,mCAAmC,CAAC;AAOlF,qBAAa,cAAc;IACzB,oFAAoF;IACpF,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqD;IAE3E;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,MAAM,SAAS,QAAQ,GAAG,cAAc,EAC5C,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,MAAM,EAAE,OAAO,EACf,SAAS,UAAQ,GAChB,CAAC,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,cAAc,CAAC;IA6CtC;;;;OAIG;IACH,OAAO,CAAC,MAAM,SAAS,QAAQ,GAAG,cAAc,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,MAAM;IAO9F,8EAA8E;IAC9E,QAAQ,CAAC,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IAIxD,2DAA2D;IAC3D,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI;IAM/B,0FAA0F;IAC1F,OAAO,CAAC,QAAQ;CAQjB"}
@@ -77,6 +77,10 @@ export class V2ToolCallMeta {
77
77
  result._meta = { ...result._meta, ...stored };
78
78
  return result;
79
79
  }
80
+ /** Whether this connection reported the tool call, so the client holds it. */
81
+ reported(sessionId, toolCallId) {
82
+ return this.calls.has(`${sessionId} ${toolCallId}`);
83
+ }
80
84
  /** Forgets the tool calls of a session, when it closes. */
81
85
  forget(sessionId) {
82
86
  for (const key of this.calls.keys()) {
@@ -29,6 +29,17 @@ type V2ToolCallUpdate = v2.ToolCallUpdate & {
29
29
  * (see `terminal.ts`).
30
30
  */
31
31
  export declare function v2ToolCallUpdate(report: V1ToolCallReport): V2ToolCallUpdate;
32
+ /**
33
+ * The v2 form of a v1 `tool_call`, for a client that may already hold a tool
34
+ * call with the same id. Each field that the `tool_call` leaves out is `null`,
35
+ * so the client resets it to its default instead of keeping the old value. For
36
+ * example, a replayed Bash call that the client holds with the `rawOutput` of
37
+ * the live run gets `rawOutput: null`, which removes it.
38
+ *
39
+ * `V2ToolCallMeta` decides what `_meta` clears. Its `_meta: null` is a v2
40
+ * clear, so it stays, where {@link v2ToolCallUpdate} drops a v1 `null`.
41
+ */
42
+ export declare function v2RestartedToolCall(report: V1ToolCallReport): V2ToolCallUpdate;
32
43
  /**
33
44
  * The v2 form of the fields of a v1 tool call report, which a session update
34
45
  * and the subject of a permission request carry. See {@link v2ToolCallUpdate}.
@@ -1 +1 @@
1
- {"version":3,"file":"tool-call.d.ts","sourceRoot":"","sources":["../../src/v2/tool-call.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAmB,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnG,OAAO,KAAK,KAAK,EAAE,MAAM,mDAAmD,CAAC;AAE7E,KAAK,gBAAgB,GACjB,CAAC,QAAQ,GAAG;IAAE,aAAa,EAAE,WAAW,CAAA;CAAE,CAAC,GAC3C,CAAC,cAAc,GAAG;IAAE,aAAa,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAAC;AAE7D,KAAK,gBAAgB,GAAG,EAAE,CAAC,cAAc,GAAG;IAAE,aAAa,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAElF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAE3E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,GAAG,EAAE,CAAC,cAAc,CAUtF"}
1
+ {"version":3,"file":"tool-call.d.ts","sourceRoot":"","sources":["../../src/v2/tool-call.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,OAAO,KAAK,EAAE,QAAQ,EAAmB,cAAc,EAAE,MAAM,mCAAmC,CAAC;AACnG,OAAO,KAAK,KAAK,EAAE,MAAM,mDAAmD,CAAC;AAE7E,KAAK,gBAAgB,GACjB,CAAC,QAAQ,GAAG;IAAE,aAAa,EAAE,WAAW,CAAA;CAAE,CAAC,GAC3C,CAAC,cAAc,GAAG;IAAE,aAAa,EAAE,kBAAkB,CAAA;CAAE,CAAC,CAAC;AAE7D,KAAK,gBAAgB,GAAG,EAAE,CAAC,cAAc,GAAG;IAAE,aAAa,EAAE,kBAAkB,CAAA;CAAE,CAAC;AAElF;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAE3E;AAcD;;;;;;;;;GASG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,gBAAgB,GAAG,gBAAgB,CAM9E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,QAAQ,EAAE,QAAQ,GAAG,cAAc,GAAG,EAAE,CAAC,cAAc,CAUtF"}
@@ -17,6 +17,32 @@
17
17
  export function v2ToolCallUpdate(report) {
18
18
  return { ...v2ToolCallPatch(report), sessionUpdate: "tool_call_update" };
19
19
  }
20
+ /** The fields of a v2 tool call besides `toolCallId` and `_meta`. */
21
+ const TOOL_CALL_FIELDS = [
22
+ "name",
23
+ "title",
24
+ "kind",
25
+ "status",
26
+ "content",
27
+ "locations",
28
+ "rawInput",
29
+ "rawOutput",
30
+ ];
31
+ /**
32
+ * The v2 form of a v1 `tool_call`, for a client that may already hold a tool
33
+ * call with the same id. Each field that the `tool_call` leaves out is `null`,
34
+ * so the client resets it to its default instead of keeping the old value. For
35
+ * example, a replayed Bash call that the client holds with the `rawOutput` of
36
+ * the live run gets `rawOutput: null`, which removes it.
37
+ *
38
+ * `V2ToolCallMeta` decides what `_meta` clears. Its `_meta: null` is a v2
39
+ * clear, so it stays, where {@link v2ToolCallUpdate} drops a v1 `null`.
40
+ */
41
+ export function v2RestartedToolCall(report) {
42
+ const update = v2ToolCallUpdate(report);
43
+ const reset = Object.fromEntries(TOOL_CALL_FIELDS.filter((field) => !(field in update)).map((field) => [field, null]));
44
+ return { ...reset, ...update, ...(report._meta === null ? { _meta: null } : {}) };
45
+ }
20
46
  /**
21
47
  * The v2 form of the fields of a v1 tool call report, which a session update
22
48
  * and the subject of a permission request carry. See {@link v2ToolCallUpdate}.
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "publishConfig": {
4
4
  "access": "public"
5
5
  },
6
- "version": "0.98.1-preview.3",
6
+ "version": "0.98.1-preview.4",
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",