@agentclientprotocol/claude-agent-acp 0.81.2 → 0.81.3-preview.2
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.
- package/README.md +8 -5
- package/dist/acp-agent.d.ts +32 -40
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +557 -577
- package/dist/acp-subagents.d.ts +6 -0
- package/dist/acp-subagents.d.ts.map +1 -1
- package/dist/air-extension.d.ts +31 -1
- package/dist/air-extension.d.ts.map +1 -1
- package/dist/air-extension.js +35 -1
- package/dist/async-tasks.d.ts +39 -2
- package/dist/async-tasks.d.ts.map +1 -1
- package/dist/async-tasks.js +147 -44
- package/dist/context-compaction-meta.d.ts +6 -5
- package/dist/context-compaction-meta.d.ts.map +1 -1
- package/dist/context-compaction-meta.js +10 -10
- package/dist/context-compaction.d.ts +3 -0
- package/dist/context-compaction.d.ts.map +1 -1
- package/dist/context-compaction.js +23 -57
- package/dist/diff.d.ts +73 -5
- package/dist/diff.d.ts.map +1 -1
- package/dist/diff.js +435 -64
- package/dist/elicitation.d.ts +1 -1
- package/dist/elicitation.d.ts.map +1 -1
- package/dist/elicitation.js +12 -14
- package/dist/hide-claude-auth.d.ts +2 -6
- package/dist/hide-claude-auth.d.ts.map +1 -1
- package/dist/hide-claude-auth.js +3 -21
- package/dist/native-subagents.d.ts +58 -0
- package/dist/native-subagents.d.ts.map +1 -1
- package/dist/native-subagents.js +186 -34
- package/dist/paths.d.ts +3 -0
- package/dist/paths.d.ts.map +1 -0
- package/dist/paths.js +6 -0
- package/dist/permissions/presentation.d.ts +13 -2
- package/dist/permissions/presentation.d.ts.map +1 -1
- package/dist/permissions/presentation.js +49 -44
- package/dist/resumed-session.d.ts +11 -0
- package/dist/resumed-session.d.ts.map +1 -1
- package/dist/resumed-session.js +106 -4
- package/dist/session-failure-extension.js +1 -1
- package/dist/session-mode.d.ts +2 -0
- package/dist/session-mode.d.ts.map +1 -1
- package/dist/session-mode.js +12 -5
- package/dist/settings.js +2 -2
- package/dist/subagent-history.d.ts +20 -0
- package/dist/subagent-history.d.ts.map +1 -0
- package/dist/subagent-history.js +46 -0
- package/dist/tool-calls/background.d.ts +20 -0
- package/dist/tool-calls/background.d.ts.map +1 -0
- package/dist/tool-calls/background.js +41 -0
- package/dist/tool-calls/changed-meta-filter.d.ts +27 -0
- package/dist/tool-calls/changed-meta-filter.d.ts.map +1 -0
- package/dist/tool-calls/changed-meta-filter.js +102 -0
- package/dist/tool-calls/client-capabilities.d.ts +51 -0
- package/dist/tool-calls/client-capabilities.d.ts.map +1 -0
- package/dist/tool-calls/client-capabilities.js +43 -0
- package/dist/tool-calls/content.d.ts +59 -0
- package/dist/tool-calls/content.d.ts.map +1 -0
- package/dist/tool-calls/content.js +194 -0
- package/dist/tool-calls/facts.d.ts +116 -0
- package/dist/tool-calls/facts.d.ts.map +1 -0
- package/dist/tool-calls/facts.js +1 -0
- package/dist/tool-calls/field-tracker.d.ts +58 -0
- package/dist/tool-calls/field-tracker.d.ts.map +1 -0
- package/dist/tool-calls/field-tracker.js +167 -0
- package/dist/tool-calls/renderer.d.ts +216 -0
- package/dist/tool-calls/renderer.d.ts.map +1 -0
- package/dist/tool-calls/renderer.js +487 -0
- package/dist/tool-calls/reporters/agent.d.ts +7 -0
- package/dist/tool-calls/reporters/agent.d.ts.map +1 -0
- package/dist/tool-calls/reporters/agent.js +190 -0
- package/dist/tool-calls/reporters/bash.d.ts +9 -0
- package/dist/tool-calls/reporters/bash.d.ts.map +1 -0
- package/dist/tool-calls/reporters/bash.js +83 -0
- package/dist/tool-calls/reporters/compaction.d.ts +24 -0
- package/dist/tool-calls/reporters/compaction.d.ts.map +1 -0
- package/dist/tool-calls/reporters/compaction.js +66 -0
- package/dist/tool-calls/reporters/file-edit.d.ts +46 -0
- package/dist/tool-calls/reporters/file-edit.d.ts.map +1 -0
- package/dist/tool-calls/reporters/file-edit.js +180 -0
- package/dist/tool-calls/reporters/index.d.ts +4 -0
- package/dist/tool-calls/reporters/index.d.ts.map +1 -0
- package/dist/tool-calls/reporters/index.js +40 -0
- package/dist/tool-calls/reporters/interaction.d.ts +71 -0
- package/dist/tool-calls/reporters/interaction.d.ts.map +1 -0
- package/dist/tool-calls/reporters/interaction.js +222 -0
- package/dist/tool-calls/reporters/read.d.ts +7 -0
- package/dist/tool-calls/reporters/read.d.ts.map +1 -0
- package/dist/tool-calls/reporters/read.js +64 -0
- package/dist/tool-calls/reporters/search.d.ts +10 -0
- package/dist/tool-calls/reporters/search.d.ts.map +1 -0
- package/dist/tool-calls/reporters/search.js +50 -0
- package/dist/tool-calls/reporters/web.d.ts +11 -0
- package/dist/tool-calls/reporters/web.d.ts.map +1 -0
- package/dist/tool-calls/reporters/web.js +42 -0
- package/dist/tools.d.ts +32 -37
- package/dist/tools.d.ts.map +1 -1
- package/dist/tools.js +48 -970
- package/package.json +4 -1
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
/** The `_meta` namespaces whose keys a client merges one by one. */
|
|
2
|
+
const MERGED_NAMESPACES = ["claudeCode"];
|
|
3
|
+
/** The top-level `_meta` flags that stay the same for a tool call. */
|
|
4
|
+
const FLAGS = ["is_mcp_tool_call", "terminal_info"];
|
|
5
|
+
/** The number of tool calls whose `_meta` the filter remembers. */
|
|
6
|
+
const TOOL_CALL_LIMIT = 2048;
|
|
7
|
+
/**
|
|
8
|
+
* Removes the `_meta` keys of a `tool_call_update` that an earlier report of
|
|
9
|
+
* the same tool call already sent with the same value.
|
|
10
|
+
*
|
|
11
|
+
* Only an AIR client gets the filtered updates, because AIR merges these
|
|
12
|
+
* `_meta` keys. ACP does not define a merge for `_meta` keys, so another
|
|
13
|
+
* client gets every key on every update.
|
|
14
|
+
*
|
|
15
|
+
* It runs on the final notification, after the native subagent routing,
|
|
16
|
+
* because the routing reads `claudeCode.toolName` and
|
|
17
|
+
* `claudeCode.parentToolUseId` on every update. It compares the keys of
|
|
18
|
+
* `claudeCode`, of `jetbrains.air`, and the flags `is_mcp_tool_call` and
|
|
19
|
+
* `terminal_info`. It never compares `terminal_output`,
|
|
20
|
+
* `terminal_output_delta`, `terminal_exit`, or `mcp_output_delta`: a client
|
|
21
|
+
* appends their data. An update with nothing left is dropped.
|
|
22
|
+
*/
|
|
23
|
+
export class ChangedMetaFilter {
|
|
24
|
+
sent = new Map();
|
|
25
|
+
/** Returns the update without the unchanged keys, or null when nothing is left. */
|
|
26
|
+
apply(update) {
|
|
27
|
+
if (update.sessionUpdate !== "tool_call" && update.sessionUpdate !== "tool_call_update") {
|
|
28
|
+
return update;
|
|
29
|
+
}
|
|
30
|
+
let held = this.sent.get(update.toolCallId);
|
|
31
|
+
if (update.sessionUpdate === "tool_call" || !held) {
|
|
32
|
+
held = new Map();
|
|
33
|
+
this.remember(update.toolCallId, held);
|
|
34
|
+
recordAndStrip(held, update._meta, false);
|
|
35
|
+
return update;
|
|
36
|
+
}
|
|
37
|
+
this.remember(update.toolCallId, held);
|
|
38
|
+
if (!update._meta)
|
|
39
|
+
return update;
|
|
40
|
+
const meta = structuredClone(update._meta);
|
|
41
|
+
recordAndStrip(held, meta, true);
|
|
42
|
+
const filtered = { ...update, _meta: meta };
|
|
43
|
+
if (Object.keys(meta).length === 0)
|
|
44
|
+
delete filtered._meta;
|
|
45
|
+
const carriesSomething = Object.keys(filtered).some((key) => key !== "sessionUpdate" && key !== "toolCallId");
|
|
46
|
+
return carriesSomething ? filtered : null;
|
|
47
|
+
}
|
|
48
|
+
/** Stores the entry as the most recent one, and forgets the oldest one past the limit. */
|
|
49
|
+
remember(toolCallId, held) {
|
|
50
|
+
this.sent.delete(toolCallId);
|
|
51
|
+
this.sent.set(toolCallId, held);
|
|
52
|
+
if (this.sent.size > TOOL_CALL_LIMIT) {
|
|
53
|
+
const oldest = this.sent.keys().next().value;
|
|
54
|
+
if (oldest !== undefined)
|
|
55
|
+
this.sent.delete(oldest);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
/** Records the compared keys of `meta`. With `strip`, deletes the unchanged ones. */
|
|
60
|
+
function recordAndStrip(held, meta, strip) {
|
|
61
|
+
if (!meta)
|
|
62
|
+
return;
|
|
63
|
+
const keep = (key, value) => {
|
|
64
|
+
const json = JSON.stringify(value);
|
|
65
|
+
if (strip && held.get(key) === json)
|
|
66
|
+
return false;
|
|
67
|
+
held.set(key, json);
|
|
68
|
+
return true;
|
|
69
|
+
};
|
|
70
|
+
const mergeKeys = (prefix, values) => {
|
|
71
|
+
for (const [key, value] of Object.entries(values)) {
|
|
72
|
+
if (!keep(prefix + key, value))
|
|
73
|
+
delete values[key];
|
|
74
|
+
}
|
|
75
|
+
};
|
|
76
|
+
for (const namespace of MERGED_NAMESPACES) {
|
|
77
|
+
const values = asRecord(meta[namespace]);
|
|
78
|
+
if (!values)
|
|
79
|
+
continue;
|
|
80
|
+
mergeKeys(`${namespace}.`, values);
|
|
81
|
+
if (Object.keys(values).length === 0)
|
|
82
|
+
delete meta[namespace];
|
|
83
|
+
}
|
|
84
|
+
const jetbrains = asRecord(meta.jetbrains);
|
|
85
|
+
const air = asRecord(jetbrains?.air);
|
|
86
|
+
if (jetbrains && air) {
|
|
87
|
+
mergeKeys("jetbrains.air.", air);
|
|
88
|
+
if (Object.keys(air).length === 0)
|
|
89
|
+
delete jetbrains.air;
|
|
90
|
+
if (Object.keys(jetbrains).length === 0)
|
|
91
|
+
delete meta.jetbrains;
|
|
92
|
+
}
|
|
93
|
+
for (const flag of FLAGS) {
|
|
94
|
+
if (meta[flag] !== undefined && !keep(flag, meta[flag]))
|
|
95
|
+
delete meta[flag];
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
function asRecord(value) {
|
|
99
|
+
return value && typeof value === "object" && !Array.isArray(value)
|
|
100
|
+
? value
|
|
101
|
+
: undefined;
|
|
102
|
+
}
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { ClientCapabilities as AcpClientCapabilities } from "@agentclientprotocol/sdk";
|
|
2
|
+
/**
|
|
3
|
+
* The client choices that decide the shape of a tool call report.
|
|
4
|
+
*
|
|
5
|
+
* The agent reads them once from `initialize.clientCapabilities`. The public
|
|
6
|
+
* `toAcpNotifications` functions take the ACP capabilities and read them on
|
|
7
|
+
* each call. The {@link AcpToolCallRenderer} reads nothing else, so one object
|
|
8
|
+
* holds every capability choice of a tool call report.
|
|
9
|
+
*/
|
|
10
|
+
export declare class ClientCapabilities {
|
|
11
|
+
/** The client renders a terminal from `_meta.terminal_info`, `terminal_output`, and `terminal_exit`. */
|
|
12
|
+
readonly terminalOutput: boolean;
|
|
13
|
+
/** The client appends `_meta.terminal_output_delta` instead of `terminal_output` chunks. */
|
|
14
|
+
readonly terminalOutputDelta: boolean;
|
|
15
|
+
/** The client accepts an exact git patch in a diff (`jetbrains.air` `diffPatch`). */
|
|
16
|
+
readonly diffPatch: boolean;
|
|
17
|
+
/** The capabilities that only JetBrains AIR declares. */
|
|
18
|
+
readonly air: AirCapabilities;
|
|
19
|
+
constructor(
|
|
20
|
+
/** The client renders a terminal from `_meta.terminal_info`, `terminal_output`, and `terminal_exit`. */
|
|
21
|
+
terminalOutput?: boolean,
|
|
22
|
+
/** The client appends `_meta.terminal_output_delta` instead of `terminal_output` chunks. */
|
|
23
|
+
terminalOutputDelta?: boolean,
|
|
24
|
+
/** The client accepts an exact git patch in a diff (`jetbrains.air` `diffPatch`). */
|
|
25
|
+
diffPatch?: boolean,
|
|
26
|
+
/** The capabilities that only JetBrains AIR declares. */
|
|
27
|
+
air?: AirCapabilities);
|
|
28
|
+
static from(capabilities: AcpClientCapabilities | null | undefined): ClientCapabilities;
|
|
29
|
+
}
|
|
30
|
+
/** The capabilities of JetBrains AIR, read from `_meta.jetbrains.air`. */
|
|
31
|
+
export interface AirCapabilities {
|
|
32
|
+
/**
|
|
33
|
+
* The client declared `_meta.jetbrains.air`. Only then does a report follow
|
|
34
|
+
* the tool call contract of `docs/air-extensions.md`. Every other client
|
|
35
|
+
* gets the fields of the upstream adapter, and only the unchanged fields of
|
|
36
|
+
* an update are left out.
|
|
37
|
+
*/
|
|
38
|
+
readonly client: boolean;
|
|
39
|
+
/**
|
|
40
|
+
* AIR renders `rawInput` itself. A tool call report for AIR then carries no
|
|
41
|
+
* display copy of the input in `content`.
|
|
42
|
+
*/
|
|
43
|
+
readonly rawInputRendering: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* AIR reads the plan of an ExitPlanMode from the file that
|
|
46
|
+
* `rawInput.planFilePath` names. A report then carries the path and not the
|
|
47
|
+
* plan text, when the plan file exists.
|
|
48
|
+
*/
|
|
49
|
+
readonly planFile: boolean;
|
|
50
|
+
}
|
|
51
|
+
//# sourceMappingURL=client-capabilities.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-capabilities.d.ts","sourceRoot":"","sources":["../../src/tool-calls/client-capabilities.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,kBAAkB,IAAI,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAS5F;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAE3B,wGAAwG;IACxG,QAAQ,CAAC,cAAc,EAAE,OAAO;IAChC,4FAA4F;IAC5F,QAAQ,CAAC,mBAAmB,EAAE,OAAO;IACrC,qFAAqF;IACrF,QAAQ,CAAC,SAAS,EAAE,OAAO;IAC3B,yDAAyD;IACzD,QAAQ,CAAC,GAAG,EAAE,eAAe;;IAP7B,wGAAwG;IAC/F,cAAc,GAAE,OAAe;IACxC,4FAA4F;IACnF,mBAAmB,GAAE,OAAe;IAC7C,qFAAqF;IAC5E,SAAS,GAAE,OAAe;IACnC,yDAAyD;IAChD,GAAG,GAAE,eAAwB;IAGxC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,qBAAqB,GAAG,IAAI,GAAG,SAAS,GAAG,kBAAkB;CAiBxF;AAED,0EAA0E;AAC1E,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;IACzB;;;OAGG;IACH,QAAQ,CAAC,iBAAiB,EAAE,OAAO,CAAC;IACpC;;;;OAIG;IACH,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC;CAC5B"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { AIR_DIFF_PATCH_CAPABILITY, AIR_PLAN_FILE_CAPABILITY, AIR_RAW_INPUT_RENDERING_CAPABILITY, clientSupportsAirCapability, isAirClient, } from "../air-extension.js";
|
|
2
|
+
/**
|
|
3
|
+
* The client choices that decide the shape of a tool call report.
|
|
4
|
+
*
|
|
5
|
+
* The agent reads them once from `initialize.clientCapabilities`. The public
|
|
6
|
+
* `toAcpNotifications` functions take the ACP capabilities and read them on
|
|
7
|
+
* each call. The {@link AcpToolCallRenderer} reads nothing else, so one object
|
|
8
|
+
* holds every capability choice of a tool call report.
|
|
9
|
+
*/
|
|
10
|
+
export class ClientCapabilities {
|
|
11
|
+
terminalOutput;
|
|
12
|
+
terminalOutputDelta;
|
|
13
|
+
diffPatch;
|
|
14
|
+
air;
|
|
15
|
+
constructor(
|
|
16
|
+
/** The client renders a terminal from `_meta.terminal_info`, `terminal_output`, and `terminal_exit`. */
|
|
17
|
+
terminalOutput = false,
|
|
18
|
+
/** The client appends `_meta.terminal_output_delta` instead of `terminal_output` chunks. */
|
|
19
|
+
terminalOutputDelta = false,
|
|
20
|
+
/** The client accepts an exact git patch in a diff (`jetbrains.air` `diffPatch`). */
|
|
21
|
+
diffPatch = false,
|
|
22
|
+
/** The capabilities that only JetBrains AIR declares. */
|
|
23
|
+
air = NO_AIR) {
|
|
24
|
+
this.terminalOutput = terminalOutput;
|
|
25
|
+
this.terminalOutputDelta = terminalOutputDelta;
|
|
26
|
+
this.diffPatch = diffPatch;
|
|
27
|
+
this.air = air;
|
|
28
|
+
}
|
|
29
|
+
static from(capabilities) {
|
|
30
|
+
const meta = capabilities?._meta;
|
|
31
|
+
const terminalOutputDelta = meta?.["terminal_output_delta"] === true;
|
|
32
|
+
return new ClientCapabilities(terminalOutputDelta || meta?.["terminal_output"] === true, terminalOutputDelta, clientSupportsAirCapability(capabilities, AIR_DIFF_PATCH_CAPABILITY), {
|
|
33
|
+
client: isAirClient(capabilities),
|
|
34
|
+
rawInputRendering: clientSupportsAirCapability(capabilities, AIR_RAW_INPUT_RENDERING_CAPABILITY),
|
|
35
|
+
planFile: clientSupportsAirCapability(capabilities, AIR_PLAN_FILE_CAPABILITY),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
const NO_AIR = {
|
|
40
|
+
client: false,
|
|
41
|
+
rawInputRendering: false,
|
|
42
|
+
planFile: false,
|
|
43
|
+
};
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import type { ContentBlock, ToolCallContent } from "@agentclientprotocol/sdk";
|
|
2
|
+
import { DocumentBlockParam, ImageBlockParam, TextBlockParam, ToolResultBlockParam, WebSearchResultBlock, WebSearchToolResultBlockParam, WebSearchToolResultError } from "@anthropic-ai/sdk/resources";
|
|
3
|
+
import { BetaBashCodeExecutionResultBlock, BetaBashCodeExecutionToolResultBlockParam, BetaBashCodeExecutionToolResultError, BetaCodeExecutionResultBlock, BetaCodeExecutionToolResultBlockParam, BetaCodeExecutionToolResultError, BetaImageBlockParam, BetaRequestMCPToolResultBlockParam, BetaTextEditorCodeExecutionCreateResultBlock, BetaTextEditorCodeExecutionStrReplaceResultBlock, BetaTextEditorCodeExecutionToolResultBlockParam, BetaTextEditorCodeExecutionToolResultError, BetaTextEditorCodeExecutionViewResultBlock, BetaToolReferenceBlock, BetaToolResultBlockParam, BetaToolSearchToolResultBlockParam, BetaToolSearchToolResultError, BetaToolSearchToolSearchResultBlock, BetaWebFetchBlock, BetaWebFetchToolResultBlockParam, BetaWebFetchToolResultErrorBlock, BetaWebSearchToolResultBlockParam } from "@anthropic-ai/sdk/resources/beta.mjs";
|
|
4
|
+
/**
|
|
5
|
+
* Union of all possible content types that can appear in tool results from the Anthropic SDK.
|
|
6
|
+
* These are transformed to valid ACP ContentBlock types by toValidAcpContent().
|
|
7
|
+
*/
|
|
8
|
+
export type ToolResultContent = TextBlockParam | DocumentBlockParam | ImageBlockParam | BetaImageBlockParam | BetaToolReferenceBlock | BetaToolSearchToolSearchResultBlock | BetaToolSearchToolResultError | WebSearchResultBlock | WebSearchToolResultError | BetaWebFetchBlock | BetaWebFetchToolResultErrorBlock | BetaCodeExecutionResultBlock | BetaCodeExecutionToolResultError | BetaBashCodeExecutionResultBlock | BetaBashCodeExecutionToolResultError | BetaTextEditorCodeExecutionViewResultBlock | BetaTextEditorCodeExecutionCreateResultBlock | BetaTextEditorCodeExecutionStrReplaceResultBlock | BetaTextEditorCodeExecutionToolResultError;
|
|
9
|
+
/**
|
|
10
|
+
* Convert an absolute file path to a project-relative path for display.
|
|
11
|
+
* Returns the original path if it's outside the project directory or if no cwd is provided.
|
|
12
|
+
*/
|
|
13
|
+
export declare function toDisplayPath(filePath: string, cwd?: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Narrow the untyped message-level `tool_use_result` toward a per-tool Output
|
|
16
|
+
* shape: rejects everything but a plain non-null object (arrays pass a bare
|
|
17
|
+
* `typeof === "object"` check, so they're excluded here). The returned value
|
|
18
|
+
* is only *nominally* typed — it arrives over the wire from arbitrary CLI
|
|
19
|
+
* versions, so each caller must still guard the specific fields it reads
|
|
20
|
+
* before trusting them.
|
|
21
|
+
*/
|
|
22
|
+
export declare function structuredResult<T extends object>(toolUseResult: unknown): T | undefined;
|
|
23
|
+
/** One display format for a web-search hit, shared by the structured
|
|
24
|
+
* WebSearchOutput render and the server-side `web_search_result` block so
|
|
25
|
+
* the two paths can't drift. */
|
|
26
|
+
export declare function formatWebSearchHit(hit: {
|
|
27
|
+
title: string;
|
|
28
|
+
url: string;
|
|
29
|
+
}): string;
|
|
30
|
+
export declare function toAcpContentUpdate(content: any, isError?: boolean): {
|
|
31
|
+
content?: ToolCallContent[];
|
|
32
|
+
};
|
|
33
|
+
export declare function toAcpContentBlock(content: ToolResultContent, isError: boolean): ContentBlock;
|
|
34
|
+
export declare function markdownEscape(text: string): string;
|
|
35
|
+
/** Every SDK block that reports the result of a tool use. */
|
|
36
|
+
export type ToolResultBlock = ToolResultBlockParam | BetaToolResultBlockParam | BetaWebSearchToolResultBlockParam | BetaWebFetchToolResultBlockParam | WebSearchToolResultBlockParam | BetaCodeExecutionToolResultBlockParam | BetaBashCodeExecutionToolResultBlockParam | BetaTextEditorCodeExecutionToolResultBlockParam | BetaRequestMCPToolResultBlockParam | BetaToolSearchToolResultBlockParam;
|
|
37
|
+
/** One text content block. */
|
|
38
|
+
export declare function textContent(text: string): ToolCallContent;
|
|
39
|
+
/** The result text that the model saw, as the result to show. */
|
|
40
|
+
export declare function resultText(result: {
|
|
41
|
+
content?: unknown;
|
|
42
|
+
is_error?: boolean | null;
|
|
43
|
+
}): {
|
|
44
|
+
content?: ToolCallContent[];
|
|
45
|
+
};
|
|
46
|
+
/**
|
|
47
|
+
* The marker fields of a PostToolUse `tool_response` that clients read.
|
|
48
|
+
*
|
|
49
|
+
* The full `tool_response` repeats the tool output. A Read holds the whole
|
|
50
|
+
* file, a Bash holds stdout and stderr, and a Write holds the content. The
|
|
51
|
+
* tool-call content already carries that output. JetBrains AIR reads
|
|
52
|
+
* `status` and `isAsync` to detect an async subagent launch, so only those
|
|
53
|
+
* fields stay. Returns undefined when neither field is present.
|
|
54
|
+
*/
|
|
55
|
+
export declare function toolResponseMarkers(toolResponse: unknown): {
|
|
56
|
+
status?: string;
|
|
57
|
+
isAsync?: boolean;
|
|
58
|
+
} | undefined;
|
|
59
|
+
//# sourceMappingURL=content.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"content.d.ts","sourceRoot":"","sources":["../../src/tool-calls/content.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC9E,OAAO,EACL,kBAAkB,EAClB,eAAe,EACf,cAAc,EACd,oBAAoB,EACpB,oBAAoB,EACpB,6BAA6B,EAC7B,wBAAwB,EACzB,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,gCAAgC,EAChC,yCAAyC,EACzC,oCAAoC,EACpC,4BAA4B,EAC5B,qCAAqC,EACrC,gCAAgC,EAChC,mBAAmB,EACnB,kCAAkC,EAClC,4CAA4C,EAC5C,gDAAgD,EAChD,+CAA+C,EAC/C,0CAA0C,EAC1C,0CAA0C,EAC1C,sBAAsB,EACtB,wBAAwB,EACxB,kCAAkC,EAClC,6BAA6B,EAC7B,mCAAmC,EACnC,iBAAiB,EACjB,gCAAgC,EAChC,gCAAgC,EAChC,iCAAiC,EAClC,MAAM,sCAAsC,CAAC;AAG9C;;;GAGG;AACH,MAAM,MAAM,iBAAiB,GACzB,cAAc,GACd,kBAAkB,GAClB,eAAe,GACf,mBAAmB,GACnB,sBAAsB,GACtB,mCAAmC,GACnC,6BAA6B,GAC7B,oBAAoB,GACpB,wBAAwB,GACxB,iBAAiB,GACjB,gCAAgC,GAChC,4BAA4B,GAC5B,gCAAgC,GAChC,gCAAgC,GAChC,oCAAoC,GACpC,0CAA0C,GAC1C,4CAA4C,GAC5C,gDAAgD,GAChD,0CAA0C,CAAC;AAE/C;;;GAGG;AACH,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,CAAC,EAAE,MAAM,GAAG,MAAM,CAQpE;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,aAAa,EAAE,OAAO,GAAG,CAAC,GAAG,SAAS,CAMxF;AAED;;iCAEiC;AACjC,wBAAgB,kBAAkB,CAAC,GAAG,EAAE;IAAE,KAAK,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAE9E;AAUD,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,GAAG,EACZ,OAAO,GAAE,OAAe,GACvB;IAAE,OAAO,CAAC,EAAE,eAAe,EAAE,CAAA;CAAE,CA+BjC;AAED,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,iBAAiB,EAAE,OAAO,EAAE,OAAO,GAAG,YAAY,CA6F5F;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAQnD;AAED,6DAA6D;AAC7D,MAAM,MAAM,eAAe,GACvB,oBAAoB,GACpB,wBAAwB,GACxB,iCAAiC,GACjC,gCAAgC,GAChC,6BAA6B,GAC7B,qCAAqC,GACrC,yCAAyC,GACzC,+CAA+C,GAC/C,kCAAkC,GAClC,kCAAkC,CAAC;AAEvC,8BAA8B;AAC9B,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,eAAe,CAEzD;AAED,iEAAiE;AACjE,wBAAgB,UAAU,CAAC,MAAM,EAAE;IAAE,OAAO,CAAC,EAAE,OAAO,CAAC;IAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAA;CAAE,GAAG;IACpF,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;CAC7B,CAEA;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,OAAO,GACpB;IAAE,MAAM,CAAC,EAAE,MAAM,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAUpD"}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
import path from "node:path";
|
|
2
|
+
/**
|
|
3
|
+
* Convert an absolute file path to a project-relative path for display.
|
|
4
|
+
* Returns the original path if it's outside the project directory or if no cwd is provided.
|
|
5
|
+
*/
|
|
6
|
+
export function toDisplayPath(filePath, cwd) {
|
|
7
|
+
if (!cwd)
|
|
8
|
+
return filePath;
|
|
9
|
+
const resolvedCwd = path.resolve(cwd);
|
|
10
|
+
const resolvedFile = path.resolve(filePath);
|
|
11
|
+
if (resolvedFile.startsWith(resolvedCwd + path.sep) || resolvedFile === resolvedCwd) {
|
|
12
|
+
return path.relative(resolvedCwd, resolvedFile);
|
|
13
|
+
}
|
|
14
|
+
return filePath;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Narrow the untyped message-level `tool_use_result` toward a per-tool Output
|
|
18
|
+
* shape: rejects everything but a plain non-null object (arrays pass a bare
|
|
19
|
+
* `typeof === "object"` check, so they're excluded here). The returned value
|
|
20
|
+
* is only *nominally* typed — it arrives over the wire from arbitrary CLI
|
|
21
|
+
* versions, so each caller must still guard the specific fields it reads
|
|
22
|
+
* before trusting them.
|
|
23
|
+
*/
|
|
24
|
+
export function structuredResult(toolUseResult) {
|
|
25
|
+
return toolUseResult !== null &&
|
|
26
|
+
typeof toolUseResult === "object" &&
|
|
27
|
+
!Array.isArray(toolUseResult)
|
|
28
|
+
? toolUseResult
|
|
29
|
+
: undefined;
|
|
30
|
+
}
|
|
31
|
+
/** One display format for a web-search hit, shared by the structured
|
|
32
|
+
* WebSearchOutput render and the server-side `web_search_result` block so
|
|
33
|
+
* the two paths can't drift. */
|
|
34
|
+
export function formatWebSearchHit(hit) {
|
|
35
|
+
return `${hit.title} (${hit.url})`;
|
|
36
|
+
}
|
|
37
|
+
/** Human-readable size for the document placeholder ("312 B", "2.4 KB",
|
|
38
|
+
* "1.3 MB"). */
|
|
39
|
+
function formatByteSize(bytes) {
|
|
40
|
+
if (bytes < 1024)
|
|
41
|
+
return `${bytes} B`;
|
|
42
|
+
if (bytes < 1024 * 1024)
|
|
43
|
+
return `${(bytes / 1024).toFixed(1)} KB`;
|
|
44
|
+
return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
|
|
45
|
+
}
|
|
46
|
+
export function toAcpContentUpdate(content, isError = false) {
|
|
47
|
+
if (Array.isArray(content) && content.length > 0) {
|
|
48
|
+
return {
|
|
49
|
+
content: content.map((c) => ({
|
|
50
|
+
type: "content",
|
|
51
|
+
content: toAcpContentBlock(c, isError),
|
|
52
|
+
})),
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
else if (typeof content === "object" && content !== null && "type" in content) {
|
|
56
|
+
return {
|
|
57
|
+
content: [
|
|
58
|
+
{
|
|
59
|
+
type: "content",
|
|
60
|
+
content: toAcpContentBlock(content, isError),
|
|
61
|
+
},
|
|
62
|
+
],
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
else if (typeof content === "string" && content.length > 0) {
|
|
66
|
+
return {
|
|
67
|
+
content: [
|
|
68
|
+
{
|
|
69
|
+
type: "content",
|
|
70
|
+
content: {
|
|
71
|
+
type: "text",
|
|
72
|
+
text: isError ? `\`\`\`\n${content}\n\`\`\`` : content,
|
|
73
|
+
},
|
|
74
|
+
},
|
|
75
|
+
],
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
return {};
|
|
79
|
+
}
|
|
80
|
+
export function toAcpContentBlock(content, isError) {
|
|
81
|
+
const wrapText = (text) => ({
|
|
82
|
+
type: "text",
|
|
83
|
+
text: isError ? `\`\`\`\n${text}\n\`\`\`` : text,
|
|
84
|
+
});
|
|
85
|
+
switch (content.type) {
|
|
86
|
+
case "text":
|
|
87
|
+
return {
|
|
88
|
+
type: "text",
|
|
89
|
+
text: isError ? `\`\`\`\n${content.text}\n\`\`\`` : content.text,
|
|
90
|
+
};
|
|
91
|
+
case "image":
|
|
92
|
+
if (content.source.type === "base64") {
|
|
93
|
+
return {
|
|
94
|
+
type: "image",
|
|
95
|
+
data: content.source.data,
|
|
96
|
+
mimeType: content.source.media_type,
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
// URL and file-based images can't be converted to ACP format (requires data)
|
|
100
|
+
return wrapText(content.source.type === "url"
|
|
101
|
+
? `[image: ${content.source.url}]`
|
|
102
|
+
: "[image: file reference]");
|
|
103
|
+
case "document": {
|
|
104
|
+
// A PDF Read delivers its raw `document` block inside the tool_result
|
|
105
|
+
// content (SDK 0.3.243 moved it here from a separate follow-up user
|
|
106
|
+
// message; the MultiRead documents lane always lived here). ACP has no
|
|
107
|
+
// document block and the base64 payload can be megabytes — render a
|
|
108
|
+
// compact placeholder, never the data, matching the CLI's own compact
|
|
109
|
+
// "Read PDF (size)" rendering.
|
|
110
|
+
const title = typeof content.title === "string" && content.title.length > 0 ? ` "${content.title}"` : "";
|
|
111
|
+
const source = content.source;
|
|
112
|
+
switch (source.type) {
|
|
113
|
+
case "url":
|
|
114
|
+
return wrapText(`[document${title}: ${source.url}]`);
|
|
115
|
+
case "base64":
|
|
116
|
+
case "text":
|
|
117
|
+
// base64 inflates the byte count by 4/3; plain text is 1:1.
|
|
118
|
+
return wrapText(`[document${title}: ${source.media_type}, ${formatByteSize(source.type === "base64"
|
|
119
|
+
? Math.floor((source.data.length * 3) / 4)
|
|
120
|
+
: source.data.length)}]`);
|
|
121
|
+
default:
|
|
122
|
+
return wrapText(`[document${title}]`);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
case "tool_reference":
|
|
126
|
+
return wrapText(`Tool: ${content.tool_name}`);
|
|
127
|
+
case "tool_search_tool_search_result":
|
|
128
|
+
return wrapText(`Tools found: ${content.tool_references.map((r) => r.tool_name).join(", ") || "none"}`);
|
|
129
|
+
case "tool_search_tool_result_error":
|
|
130
|
+
return wrapText(`Error: ${content.error_code}${content.error_message ? ` - ${content.error_message}` : ""}`);
|
|
131
|
+
case "web_search_result":
|
|
132
|
+
return wrapText(formatWebSearchHit(content));
|
|
133
|
+
case "web_search_tool_result_error":
|
|
134
|
+
return wrapText(`Error: ${content.error_code}`);
|
|
135
|
+
case "web_fetch_result":
|
|
136
|
+
return wrapText(`Fetched: ${content.url}`);
|
|
137
|
+
case "web_fetch_tool_result_error":
|
|
138
|
+
return wrapText(`Error: ${content.error_code}`);
|
|
139
|
+
case "code_execution_result":
|
|
140
|
+
return wrapText(`Output: ${content.stdout || content.stderr || ""}`);
|
|
141
|
+
case "bash_code_execution_result":
|
|
142
|
+
return wrapText(`Output: ${content.stdout || content.stderr || ""}`);
|
|
143
|
+
case "code_execution_tool_result_error":
|
|
144
|
+
case "bash_code_execution_tool_result_error":
|
|
145
|
+
return wrapText(`Error: ${content.error_code}`);
|
|
146
|
+
case "text_editor_code_execution_view_result":
|
|
147
|
+
return wrapText(content.content);
|
|
148
|
+
case "text_editor_code_execution_create_result":
|
|
149
|
+
return wrapText(content.is_file_update ? "File updated" : "File created");
|
|
150
|
+
case "text_editor_code_execution_str_replace_result":
|
|
151
|
+
return wrapText(content.lines?.join("\n") || "");
|
|
152
|
+
case "text_editor_code_execution_tool_result_error":
|
|
153
|
+
return wrapText(`Error: ${content.error_code}${content.error_message ? ` - ${content.error_message}` : ""}`);
|
|
154
|
+
default:
|
|
155
|
+
return wrapText(JSON.stringify(content));
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
export function markdownEscape(text) {
|
|
159
|
+
let escape = "```";
|
|
160
|
+
for (const [m] of text.matchAll(/^```+/gm)) {
|
|
161
|
+
while (m.length >= escape.length) {
|
|
162
|
+
escape += "`";
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
return escape + "\n" + text + (text.endsWith("\n") ? "" : "\n") + escape;
|
|
166
|
+
}
|
|
167
|
+
/** One text content block. */
|
|
168
|
+
export function textContent(text) {
|
|
169
|
+
return { type: "content", content: { type: "text", text } };
|
|
170
|
+
}
|
|
171
|
+
/** The result text that the model saw, as the result to show. */
|
|
172
|
+
export function resultText(result) {
|
|
173
|
+
return toAcpContentUpdate(result.content, result.is_error === true);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* The marker fields of a PostToolUse `tool_response` that clients read.
|
|
177
|
+
*
|
|
178
|
+
* The full `tool_response` repeats the tool output. A Read holds the whole
|
|
179
|
+
* file, a Bash holds stdout and stderr, and a Write holds the content. The
|
|
180
|
+
* tool-call content already carries that output. JetBrains AIR reads
|
|
181
|
+
* `status` and `isAsync` to detect an async subagent launch, so only those
|
|
182
|
+
* fields stay. Returns undefined when neither field is present.
|
|
183
|
+
*/
|
|
184
|
+
export function toolResponseMarkers(toolResponse) {
|
|
185
|
+
if (!toolResponse || typeof toolResponse !== "object" || Array.isArray(toolResponse)) {
|
|
186
|
+
return undefined;
|
|
187
|
+
}
|
|
188
|
+
const { status, isAsync } = toolResponse;
|
|
189
|
+
const markers = {
|
|
190
|
+
...(typeof status === "string" ? { status } : {}),
|
|
191
|
+
...(typeof isAsync === "boolean" ? { isAsync } : {}),
|
|
192
|
+
};
|
|
193
|
+
return Object.keys(markers).length > 0 ? markers : undefined;
|
|
194
|
+
}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
import type { ToolCallContent, ToolCallLocation, ToolKind } from "@agentclientprotocol/sdk";
|
|
2
|
+
import type { ClientCapabilities } from "./client-capabilities.js";
|
|
3
|
+
/** A tool use as the SDK reports it. */
|
|
4
|
+
export interface ToolUse {
|
|
5
|
+
id: string;
|
|
6
|
+
name: string;
|
|
7
|
+
input: unknown;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* The facts of a tool use, read once from its input. The
|
|
11
|
+
* {@link AcpToolCallRenderer} decides which ACP field carries each fact.
|
|
12
|
+
*/
|
|
13
|
+
export interface ToolUseFacts {
|
|
14
|
+
/** A short label. Not the input and not the output. */
|
|
15
|
+
title: string;
|
|
16
|
+
kind: ToolKind;
|
|
17
|
+
locations?: ToolCallLocation[];
|
|
18
|
+
/** The file change that the input makes, as diff content. */
|
|
19
|
+
change?: ToolCallContent[];
|
|
20
|
+
/**
|
|
21
|
+
* The input keys whose text a diff holds: {@link change}, or for a Write of a
|
|
22
|
+
* client with diffPatch, the approval preview or the hook patch. `rawInput`
|
|
23
|
+
* leaves them out.
|
|
24
|
+
*/
|
|
25
|
+
fileTextKeys?: readonly string[];
|
|
26
|
+
/**
|
|
27
|
+
* A display copy of the input that the user reads: a plan, a subagent
|
|
28
|
+
* prompt, a question, a command description. A client that renders
|
|
29
|
+
* `rawInput` itself gets no display copy.
|
|
30
|
+
*/
|
|
31
|
+
display?: ToolCallContent[];
|
|
32
|
+
/** The tool runs a command. Its output goes to the terminal channel. */
|
|
33
|
+
command?: boolean;
|
|
34
|
+
/**
|
|
35
|
+
* The absolute path of the plan file that holds the plan text of the input.
|
|
36
|
+
* Set only for a `planFile` client and an existing file. `rawInput` then
|
|
37
|
+
* carries this path and not the plan text.
|
|
38
|
+
*/
|
|
39
|
+
planFilePath?: string;
|
|
40
|
+
}
|
|
41
|
+
/** The output of a command, for the terminal channel. */
|
|
42
|
+
export interface CommandOutput {
|
|
43
|
+
output: string;
|
|
44
|
+
exitCode: number;
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* The facts of a tool result, read once from the SDK tool_result.
|
|
48
|
+
*
|
|
49
|
+
* `rawOutput` is present when the reporter decided what the raw output is.
|
|
50
|
+
* Otherwise the renderer sends the raw tool_result as `rawOutput` only when
|
|
51
|
+
* nothing else carries the result.
|
|
52
|
+
*/
|
|
53
|
+
export interface ToolResultFacts {
|
|
54
|
+
title?: string;
|
|
55
|
+
/** The result to show. */
|
|
56
|
+
content?: ToolCallContent[];
|
|
57
|
+
/** The final locations of an edit. */
|
|
58
|
+
locations?: ToolCallLocation[];
|
|
59
|
+
/** The output of a command. */
|
|
60
|
+
command?: CommandOutput;
|
|
61
|
+
/** A result that has no display form. */
|
|
62
|
+
rawOutput?: unknown;
|
|
63
|
+
/** The plan file of the tool use, as {@link ToolUseFacts.planFilePath} defines it. */
|
|
64
|
+
planFilePath?: string;
|
|
65
|
+
/**
|
|
66
|
+
* The plan is done with its file: the user approved it and the session left
|
|
67
|
+
* Plan mode. AIR then gets the clear signal of the plan file.
|
|
68
|
+
*/
|
|
69
|
+
planFileReleased?: boolean;
|
|
70
|
+
}
|
|
71
|
+
/** What a reporter reads besides the input of the tool use. */
|
|
72
|
+
export interface ToolUseContext {
|
|
73
|
+
cwd?: string;
|
|
74
|
+
capabilities: ClientCapabilities;
|
|
75
|
+
/**
|
|
76
|
+
* True when the tool use comes from the history of a loaded session. The
|
|
77
|
+
* files on disk then show a later state, so a reporter must not read them.
|
|
78
|
+
*/
|
|
79
|
+
replay?: boolean;
|
|
80
|
+
}
|
|
81
|
+
/** What a reporter reads to report a tool result. */
|
|
82
|
+
export interface ToolResultContext {
|
|
83
|
+
toolUse: ToolUse;
|
|
84
|
+
/** The SDK tool_result block. */
|
|
85
|
+
result: {
|
|
86
|
+
content?: unknown;
|
|
87
|
+
is_error?: boolean | null;
|
|
88
|
+
tool_use_id?: string;
|
|
89
|
+
};
|
|
90
|
+
/** The structured `tool_use_result` of the SDK message, when it is known. */
|
|
91
|
+
structured?: unknown;
|
|
92
|
+
capabilities: ClientCapabilities;
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Turns the SDK data of one tool kind into tool facts. A reporter holds no
|
|
96
|
+
* state and knows nothing about the ACP fields.
|
|
97
|
+
*/
|
|
98
|
+
export interface ToolReporter {
|
|
99
|
+
toolUse(input: unknown, context: ToolUseContext): ToolUseFacts;
|
|
100
|
+
/**
|
|
101
|
+
* The facts of a successful result. Without this method, the result text
|
|
102
|
+
* that the model saw is the result to show.
|
|
103
|
+
*/
|
|
104
|
+
toolResult?(context: ToolResultContext): ToolResultFacts;
|
|
105
|
+
/**
|
|
106
|
+
* The facts of an error result. Without this method, the error text is the
|
|
107
|
+
* result to show.
|
|
108
|
+
*/
|
|
109
|
+
errorResult?(context: ToolResultContext): ToolResultFacts | undefined;
|
|
110
|
+
/**
|
|
111
|
+
* The facts of the PostToolUse hook `tool_response`: the final file change
|
|
112
|
+
* of an edit tool.
|
|
113
|
+
*/
|
|
114
|
+
hookResult?(toolResponse: unknown, context: ToolUseContext): Promise<ToolResultFacts>;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=facts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"facts.d.ts","sourceRoot":"","sources":["../../src/tool-calls/facts.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,eAAe,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAC5F,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAEnE,wCAAwC;AACxC,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,CAAC;CAChB;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,uDAAuD;IACvD,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,6DAA6D;IAC7D,MAAM,CAAC,EAAE,eAAe,EAAE,CAAC;IAC3B;;;;OAIG;IACH,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC;;;;OAIG;IACH,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,wEAAwE;IACxE,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,yDAAyD;AACzD,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,0BAA0B;IAC1B,OAAO,CAAC,EAAE,eAAe,EAAE,CAAC;IAC5B,sCAAsC;IACtC,SAAS,CAAC,EAAE,gBAAgB,EAAE,CAAC;IAC/B,+BAA+B;IAC/B,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,yCAAyC;IACzC,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,sFAAsF;IACtF,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB;;;OAGG;IACH,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAED,+DAA+D;AAC/D,MAAM,WAAW,cAAc;IAC7B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,YAAY,EAAE,kBAAkB,CAAC;IACjC;;;OAGG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,qDAAqD;AACrD,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,iCAAiC;IACjC,MAAM,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,QAAQ,CAAC,EAAE,OAAO,GAAG,IAAI,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAC/E,6EAA6E;IAC7E,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,YAAY,EAAE,kBAAkB,CAAC;CAClC;AAED;;;GAGG;AACH,MAAM,WAAW,YAAY;IAC3B,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,YAAY,CAAC;IAC/D;;;OAGG;IACH,UAAU,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,CAAC;IACzD;;;OAGG;IACH,WAAW,CAAC,CAAC,OAAO,EAAE,iBAAiB,GAAG,eAAe,GAAG,SAAS,CAAC;IACtE;;;OAGG;IACH,UAAU,CAAC,CAAC,YAAY,EAAE,OAAO,EAAE,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,eAAe,CAAC,CAAC;CACvF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { SessionNotification, ToolCallContent } from "@agentclientprotocol/sdk";
|
|
2
|
+
type SessionUpdate = SessionNotification["update"];
|
|
3
|
+
/**
|
|
4
|
+
* Remembers what the client holds for each open tool call, so that a
|
|
5
|
+
* `tool_call_update` carries only the fields that changed.
|
|
6
|
+
*
|
|
7
|
+
* A client overwrites a field that an update carries and merges `_meta` by
|
|
8
|
+
* key. An update that repeats a field value therefore only costs bandwidth,
|
|
9
|
+
* and for a Write it repeats the whole file. The tracker drops such fields.
|
|
10
|
+
* It never drops `_meta`, because a client appends `terminal_output_delta`
|
|
11
|
+
* data.
|
|
12
|
+
*
|
|
13
|
+
* An entry starts at the `tool_call` and ends after both the tool_result and
|
|
14
|
+
* the PostToolUse hook callback, or when the session is torn down.
|
|
15
|
+
*/
|
|
16
|
+
export declare class ToolCallFieldTracker {
|
|
17
|
+
private readonly calls;
|
|
18
|
+
/**
|
|
19
|
+
* Records a `tool_call`, or removes the unchanged fields of a
|
|
20
|
+
* `tool_call_update` and records the rest.
|
|
21
|
+
*
|
|
22
|
+
* Returns false when the update carries nothing new: no replaced field
|
|
23
|
+
* remains, `_meta` has no key besides `claudeCode` and `jetbrains`, and
|
|
24
|
+
* every `claudeCode` and `jetbrains.air` key repeats its value. The caller
|
|
25
|
+
* then skips the update. An update for a tool call that the tracker does
|
|
26
|
+
* not know passes through unchanged.
|
|
27
|
+
*
|
|
28
|
+
* `replacePinnedContent` lets the final result of the tool replace an exact
|
|
29
|
+
* approval patch (see {@link pinContent}).
|
|
30
|
+
*/
|
|
31
|
+
apply(update: SessionUpdate, options?: {
|
|
32
|
+
replacePinnedContent?: boolean;
|
|
33
|
+
}): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Records the exact approval patch that the client shows for a tool call.
|
|
36
|
+
*
|
|
37
|
+
* The streamed tool input later refines the call with a standard diff of
|
|
38
|
+
* the Edit snippet. That diff must not replace the exact patch, so the
|
|
39
|
+
* content stays until an update passes `replacePinnedContent`.
|
|
40
|
+
*/
|
|
41
|
+
pinContent(toolCallId: string, content: ToolCallContent[]): void;
|
|
42
|
+
/**
|
|
43
|
+
* Marks the tool_result of a tool call. The entry ends now, or after the
|
|
44
|
+
* PostToolUse hook callback when `hookPending` is true.
|
|
45
|
+
*/
|
|
46
|
+
finishResult(toolCallId: string, hookPending: boolean): void;
|
|
47
|
+
/**
|
|
48
|
+
* Marks the end of the PostToolUse hook callback of a tool call. The entry
|
|
49
|
+
* ends when the tool_result was seen. Otherwise the tool_result ends it.
|
|
50
|
+
*/
|
|
51
|
+
finishHook(toolCallId: string): void;
|
|
52
|
+
/** Forgets one tool call. */
|
|
53
|
+
delete(toolCallId: string): void;
|
|
54
|
+
/** Forgets every tool call, when the session is torn down. */
|
|
55
|
+
clear(): void;
|
|
56
|
+
}
|
|
57
|
+
export {};
|
|
58
|
+
//# sourceMappingURL=field-tracker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"field-tracker.d.ts","sourceRoot":"","sources":["../../src/tool-calls/field-tracker.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAErF,KAAK,aAAa,GAAG,mBAAmB,CAAC,QAAQ,CAAC,CAAC;AA+BnD;;;;;;;;;;;;GAYG;AACH,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAmC;IAEzD;;;;;;;;;;;;OAYG;IACH,KAAK,CAAC,MAAM,EAAE,aAAa,EAAE,OAAO,CAAC,EAAE;QAAE,oBAAoB,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,OAAO;IA8CnF;;;;;;OAMG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,EAAE,GAAG,IAAI;IAOhE;;;OAGG;IACH,YAAY,CAAC,UAAU,EAAE,MAAM,EAAE,WAAW,EAAE,OAAO,GAAG,IAAI;IAO5D;;;OAGG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIpC,6BAA6B;IAC7B,MAAM,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI;IAIhC,8DAA8D;IAC9D,KAAK,IAAI,IAAI;CAGd"}
|