@agentclientprotocol/claude-agent-acp 0.90.1-preview.9 → 0.91.1-preview.1
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 +14 -5
- package/dist/acp-agent.d.ts +94 -11
- package/dist/acp-agent.d.ts.map +1 -1
- package/dist/acp-agent.js +246 -76
- package/dist/air-extension.d.ts +6 -0
- package/dist/air-extension.d.ts.map +1 -1
- package/dist/air-extension.js +6 -0
- package/dist/file-change-audit.d.ts +17 -0
- package/dist/file-change-audit.d.ts.map +1 -1
- package/dist/file-change-audit.js +62 -20
- package/dist/gateway-models.d.ts +62 -0
- package/dist/gateway-models.d.ts.map +1 -0
- package/dist/gateway-models.js +180 -0
- package/dist/native-subagents.d.ts +34 -9
- package/dist/native-subagents.d.ts.map +1 -1
- package/dist/native-subagents.js +55 -11
- package/dist/session-index/connection.d.ts +4 -3
- package/dist/session-index/connection.d.ts.map +1 -1
- package/dist/session-index/connection.js +8 -7
- package/dist/session-index/list-subscriptions.d.ts.map +1 -1
- package/dist/session-index/list-subscriptions.js +4 -1
- package/dist/session-index/service.d.ts +10 -0
- package/dist/session-index/service.d.ts.map +1 -1
- package/dist/session-index/service.js +21 -0
- package/dist/session-index/session-index.d.ts +10 -2
- package/dist/session-index/session-index.d.ts.map +1 -1
- package/dist/session-index/session-index.js +21 -5
- package/dist/session-index/session-info.d.ts.map +1 -1
- package/dist/session-index/session-info.js +1 -0
- package/dist/session-index/transcript-scan.d.ts +25 -1
- package/dist/session-index/transcript-scan.d.ts.map +1 -1
- package/dist/session-index/transcript-scan.js +57 -1
- package/dist/session-index/worktrees.d.ts +6 -0
- package/dist/session-index/worktrees.d.ts.map +1 -1
- package/dist/session-index/worktrees.js +12 -0
- package/dist/session-model.d.ts +21 -1
- package/dist/session-model.d.ts.map +1 -1
- package/dist/session-model.js +89 -11
- package/dist/turn-events.d.ts +5 -1
- package/dist/turn-events.d.ts.map +1 -1
- package/dist/v2/prompt.d.ts +2 -1
- package/dist/v2/prompt.d.ts.map +1 -1
- package/dist/v2/prompt.js +2 -1
- package/package.json +3 -3
|
@@ -9,6 +9,10 @@ export type FileChangeReportTurnState = {
|
|
|
9
9
|
export type NativeFileChangeReportTurn = {
|
|
10
10
|
promptUuid: string;
|
|
11
11
|
fileChangeReport?: FileChangeReportTurnState;
|
|
12
|
+
/** Raw `file_path`/`notebook_path` values of the file-tool edits that
|
|
13
|
+
* subagents of this turn completed. Checkpoints do not track files that
|
|
14
|
+
* only a subagent edited. */
|
|
15
|
+
editedPaths?: Set<string>;
|
|
12
16
|
};
|
|
13
17
|
export type FileChangeReportWorkspace = {
|
|
14
18
|
cwd: string;
|
|
@@ -42,6 +46,19 @@ export type NativeFileChangeReporter = {
|
|
|
42
46
|
export declare function agentFileChangeReportRequestId(meta: unknown): string | undefined;
|
|
43
47
|
export declare function supportsAgentFileChangeReport(capabilities: unknown): boolean;
|
|
44
48
|
export declare function agentFileChangeReportMeta(result: AgentFileChangeReportResult): Record<string, unknown>;
|
|
49
|
+
/**
|
|
50
|
+
* Adds to `turn.editedPaths` the `file_path` (`notebook_path` for NotebookEdit)
|
|
51
|
+
* of each successful file-tool edit among the tool results of a subagent
|
|
52
|
+
* message. Root-agent messages (`parentToolUseId === null`) are skipped: the
|
|
53
|
+
* checkpoint already tracks their files. Must run before `toAcpNotifications`
|
|
54
|
+
* drops the tool use cache entries.
|
|
55
|
+
*/
|
|
56
|
+
export declare function recordSubagentFileEdits(turn: (NativeFileChangeReportTurn & {
|
|
57
|
+
settled: boolean;
|
|
58
|
+
}) | null | undefined, parentToolUseId: string | null, content: unknown, toolUses: Record<string, {
|
|
59
|
+
name: string;
|
|
60
|
+
input: unknown;
|
|
61
|
+
} | undefined>): void;
|
|
45
62
|
export declare function createNativeFileChangeReporter(options: NativeFileChangeReporterOptions): NativeFileChangeReporter;
|
|
46
63
|
export {};
|
|
47
64
|
//# sourceMappingURL=file-change-audit.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-change-audit.d.ts","sourceRoot":"","sources":["../src/file-change-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,gCAAgC,CAAC;AAK/E,eAAO,MAAM,mCAAmC,0BAA0B,CAAC;AAI3E,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAC7D,eAAO,MAAM,mCAAmC,OAAQ,CAAC;AAGzD,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-change-audit.d.ts","sourceRoot":"","sources":["../src/file-change-audit.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAqB,MAAM,gCAAgC,CAAC;AAK/E,eAAO,MAAM,mCAAmC,0BAA0B,CAAC;AAI3E,eAAO,MAAM,kCAAkC,QAAa,CAAC;AAC7D,eAAO,MAAM,mCAAmC,OAAQ,CAAC;AAGzD,MAAM,MAAM,yBAAyB,GAAG;IACtC,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,WAAW,GAAG,YAAY,GAAG,UAAU,CAAC;CAChD,CAAC;AAEF,MAAM,MAAM,0BAA0B,GAAG;IACvC,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,yBAAyB,CAAC;IAC7C;;kCAE8B;IAC9B,WAAW,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;CAC3B,CAAC;AAEF,MAAM,MAAM,yBAAyB,GAAG;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;CACjC,CAAC;AAEF,MAAM,MAAM,2BAA2B,GAAG;IACxC,OAAO,EAAE,CAAC,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;CACnB,GAAG,CACA;IACE,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,gBAAgB,EAAE,OAAO,CAAC;IAC1B,SAAS,EAAE,OAAO,CAAC;CACpB,GACD;IACE,MAAM,EAAE,aAAa,CAAC;IACtB,MAAM,EAAE,iCAAiC,CAAC;CAC3C,CACJ,CAAC;AAEF,MAAM,MAAM,iCAAiC,GAC3C,WAAW,GAAG,SAAS,GAAG,eAAe,GAAG,aAAa,GAAG,eAAe,CAAC;AAE9E,KAAK,+BAA+B,GAAG;IACrC,GAAG,EAAE,MAAM,CAAC;IACZ,qBAAqB,EAAE,MAAM,EAAE,CAAC;IAChC,OAAO,EAAE,CAAC,MAAM,EAAE,2BAA2B,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,QAAQ,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CAAC;IAC9D,MAAM,CACJ,IAAI,EAAE,0BAA0B,GAAG,IAAI,GAAG,SAAS,EACnD,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,aAAa,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAAC;IACjB,MAAM,CACJ,KAAK,EAAE,yBAAyB,GAAG,SAAS,EAC5C,MAAM,EAAE,iCAAiC,GACxC,IAAI,CAAC;CACT,CAAC;AAEF,wBAAgB,8BAA8B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAiBhF;AAED,wBAAgB,6BAA6B,CAAC,YAAY,EAAE,OAAO,GAAG,OAAO,CAE5E;AAED,wBAAgB,yBAAyB,CACvC,MAAM,EAAE,2BAA2B,GAClC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAEzB;AAID;;;;;;GAMG;AACH,wBAAgB,uBAAuB,CACrC,IAAI,EAAE,CAAC,0BAA0B,GAAG;IAAE,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,GAAG,IAAI,GAAG,SAAS,EAC5E,eAAe,EAAE,MAAM,GAAG,IAAI,EAC9B,OAAO,EAAE,OAAO,EAChB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,OAAO,CAAA;CAAE,GAAG,SAAS,CAAC,GACrE,IAAI,CAmBN;AAED,wBAAgB,8BAA8B,CAC5C,OAAO,EAAE,+BAA+B,GACvC,wBAAwB,CA8G1B"}
|
|
@@ -30,11 +30,40 @@ export function supportsAgentFileChangeReport(capabilities) {
|
|
|
30
30
|
export function agentFileChangeReportMeta(result) {
|
|
31
31
|
return withAirMeta(undefined, AGENT_FILE_CHANGE_REPORT_CAPABILITY, result);
|
|
32
32
|
}
|
|
33
|
+
const FILE_EDIT_TOOLS = new Set(["Edit", "Write", "MultiEdit", "NotebookEdit"]);
|
|
34
|
+
/**
|
|
35
|
+
* Adds to `turn.editedPaths` the `file_path` (`notebook_path` for NotebookEdit)
|
|
36
|
+
* of each successful file-tool edit among the tool results of a subagent
|
|
37
|
+
* message. Root-agent messages (`parentToolUseId === null`) are skipped: the
|
|
38
|
+
* checkpoint already tracks their files. Must run before `toAcpNotifications`
|
|
39
|
+
* drops the tool use cache entries.
|
|
40
|
+
*/
|
|
41
|
+
export function recordSubagentFileEdits(turn, parentToolUseId, content, toolUses) {
|
|
42
|
+
if (parentToolUseId === null || !turn || turn.settled || !turn.fileChangeReport)
|
|
43
|
+
return;
|
|
44
|
+
if (!Array.isArray(content))
|
|
45
|
+
return;
|
|
46
|
+
for (const block of content) {
|
|
47
|
+
if (block?.type !== "tool_result" ||
|
|
48
|
+
block.is_error === true ||
|
|
49
|
+
typeof block.tool_use_id !== "string") {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const toolUse = toolUses[block.tool_use_id];
|
|
53
|
+
if (!toolUse || !FILE_EDIT_TOOLS.has(toolUse.name))
|
|
54
|
+
continue;
|
|
55
|
+
const input = toolUse.input;
|
|
56
|
+
const editedPath = toolUse.name === "NotebookEdit" ? input?.notebook_path : input?.file_path;
|
|
57
|
+
if (typeof editedPath === "string" && editedPath.length > 0) {
|
|
58
|
+
(turn.editedPaths ??= new Set()).add(editedPath);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
}
|
|
33
62
|
export function createNativeFileChangeReporter(options) {
|
|
34
63
|
const workspace = normalizeWorkspace(options.cwd, options.additionalDirectories);
|
|
35
64
|
const timeoutMs = options.timeoutMs ?? AGENT_FILE_CHANGE_REPORT_TIMEOUT_MS;
|
|
36
65
|
const requestIds = new Set();
|
|
37
|
-
|
|
66
|
+
async function publish(state, result) {
|
|
38
67
|
if (state.phase === "finished")
|
|
39
68
|
return;
|
|
40
69
|
state.phase = "finished";
|
|
@@ -44,16 +73,39 @@ export function createNativeFileChangeReporter(options) {
|
|
|
44
73
|
catch (error) {
|
|
45
74
|
options.logError(`Failed to publish file-change report ${state.requestId}: ${error}`);
|
|
46
75
|
}
|
|
47
|
-
}
|
|
48
|
-
|
|
76
|
+
}
|
|
77
|
+
async function finishUnavailable(state, reason) {
|
|
49
78
|
await publish(state, {
|
|
50
79
|
version: 1,
|
|
51
80
|
requestId: state.requestId,
|
|
52
81
|
status: "unavailable",
|
|
53
82
|
reason,
|
|
54
83
|
});
|
|
55
|
-
}
|
|
56
|
-
|
|
84
|
+
}
|
|
85
|
+
async function publishReported(state, reportedPaths) {
|
|
86
|
+
const normalized = normalizeReportedPaths(reportedPaths, workspace);
|
|
87
|
+
await publish(state, fitReportedAgentFileChangeReport({
|
|
88
|
+
version: 1,
|
|
89
|
+
requestId: state.requestId,
|
|
90
|
+
status: "reported",
|
|
91
|
+
paths: normalized.paths,
|
|
92
|
+
// Checkpoints miss Bash mutations. Subagent file-tool edits are added
|
|
93
|
+
// from the message stream, but the list is still not exhaustive.
|
|
94
|
+
declaredComplete: false,
|
|
95
|
+
truncated: normalized.truncated,
|
|
96
|
+
}));
|
|
97
|
+
}
|
|
98
|
+
// Used when the checkpoint preview fails: the subagent edits seen in the
|
|
99
|
+
// stream are still worth reporting.
|
|
100
|
+
async function finishWithoutPreview(state, editedPaths, reason) {
|
|
101
|
+
if (editedPaths && editedPaths.size > 0) {
|
|
102
|
+
await publishReported(state, [...editedPaths]);
|
|
103
|
+
}
|
|
104
|
+
else {
|
|
105
|
+
await finishUnavailable(state, reason);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
async function report(turn, query) {
|
|
57
109
|
const state = turn?.fileChangeReport;
|
|
58
110
|
if (!state || state.phase !== "requested")
|
|
59
111
|
return;
|
|
@@ -72,34 +124,24 @@ export function createNativeFileChangeReporter(options) {
|
|
|
72
124
|
}),
|
|
73
125
|
]);
|
|
74
126
|
if (preview === null) {
|
|
75
|
-
await
|
|
127
|
+
await finishWithoutPreview(state, turn.editedPaths, "timeout");
|
|
76
128
|
return;
|
|
77
129
|
}
|
|
78
130
|
if (!preview.canRewind || !Array.isArray(preview.filesChanged)) {
|
|
79
|
-
await
|
|
131
|
+
await finishWithoutPreview(state, turn.editedPaths, "invalidOutput");
|
|
80
132
|
return;
|
|
81
133
|
}
|
|
82
|
-
|
|
83
|
-
await publish(state, fitReportedAgentFileChangeReport({
|
|
84
|
-
version: 1,
|
|
85
|
-
requestId: state.requestId,
|
|
86
|
-
status: "reported",
|
|
87
|
-
paths: normalized.paths,
|
|
88
|
-
// Checkpoints cover Claude file tools, but not every mutation source
|
|
89
|
-
// (notably Bash and most subagents), so this list is never exhaustive.
|
|
90
|
-
declaredComplete: false,
|
|
91
|
-
truncated: normalized.truncated,
|
|
92
|
-
}));
|
|
134
|
+
await publishReported(state, [...preview.filesChanged, ...(turn.editedPaths ?? [])]);
|
|
93
135
|
}
|
|
94
136
|
catch (error) {
|
|
95
137
|
options.logError(`Failed to inspect Claude file checkpoint ${turn.promptUuid}: ${error}`);
|
|
96
|
-
await
|
|
138
|
+
await finishWithoutPreview(state, turn.editedPaths, "providerError");
|
|
97
139
|
}
|
|
98
140
|
finally {
|
|
99
141
|
if (timer)
|
|
100
142
|
clearTimeout(timer);
|
|
101
143
|
}
|
|
102
|
-
}
|
|
144
|
+
}
|
|
103
145
|
return {
|
|
104
146
|
request(meta) {
|
|
105
147
|
const requestId = agentFileChangeReportRequestId(meta);
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model discovery for a gateway set via `providers/set`.
|
|
3
|
+
*
|
|
4
|
+
* An organization can restrict which models its gateway serves, and the
|
|
5
|
+
* gateway's listing returns only those: `GET /v1/models` for an `anthropic`
|
|
6
|
+
* gateway, `GET /foundation-models` (Bedrock `ListFoundationModels`) for a
|
|
7
|
+
* `bedrock` one. The adapter lists them once when the provider is set, and the
|
|
8
|
+
* model picker then offers only the SDK models the gateway listed (see
|
|
9
|
+
* `narrowToGatewayModels` in `session-model.ts`). A listing that fails fails
|
|
10
|
+
* `providers/set` with a {@link GatewayListingError}.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* The bearer token `createEnvForProvider` sets as `ANTHROPIC_AUTH_TOKEN` and
|
|
14
|
+
* `AWS_BEARER_TOKEN_BEDROCK`, so the CLI sends `Authorization: Bearer acp-proxy`
|
|
15
|
+
* unless the provider headers replace it. The listing sends the same, so the
|
|
16
|
+
* gateway sees the same auth as on chat requests.
|
|
17
|
+
*/
|
|
18
|
+
export declare const PROVIDER_AUTH_TOKEN_PLACEHOLDER = "acp-proxy";
|
|
19
|
+
type ListingLogger = {
|
|
20
|
+
log: (...args: any[]) => void;
|
|
21
|
+
error: (...args: any[]) => void;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* A gateway listing that failed: a network error, a status other than 2xx or
|
|
25
|
+
* 4xx, a body that is not the expected listing, or the 10 s timeout. The
|
|
26
|
+
* message names the request path and the reason, never a header value.
|
|
27
|
+
*/
|
|
28
|
+
export declare class GatewayListingError extends Error {
|
|
29
|
+
name: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Lists the model ids an `anthropic` gateway at `baseUrl` serves, following
|
|
33
|
+
* `has_more` / `last_id` pagination. Returns `undefined` when the gateway
|
|
34
|
+
* answers 4xx: it has no listing, and nothing is narrowed. Throws a
|
|
35
|
+
* {@link GatewayListingError} when the listing fails. Header values are never
|
|
36
|
+
* logged.
|
|
37
|
+
*/
|
|
38
|
+
export declare function listGatewayModels(baseUrl: string, providerHeaders: Record<string, string>, logger: ListingLogger): Promise<string[] | undefined>;
|
|
39
|
+
/**
|
|
40
|
+
* Lists the Anthropic models a `bedrock` gateway at `baseUrl` serves
|
|
41
|
+
* (`GET /foundation-models`, Bedrock `ListFoundationModels`, one page), the
|
|
42
|
+
* listing AI Router answers on its Bedrock route. Returns the listed ids, such
|
|
43
|
+
* as `global.anthropic.claude-sonnet-5-5`; `undefined` and the errors are
|
|
44
|
+
* those of {@link listGatewayModels}.
|
|
45
|
+
*/
|
|
46
|
+
export declare function listBedrockModels(baseUrl: string, providerHeaders: Record<string, string>, logger: ListingLogger): Promise<string[] | undefined>;
|
|
47
|
+
/** The cross-region prefix of a Bedrock model id or ARN, if it has one. */
|
|
48
|
+
export declare function bedrockRegionPrefix(modelId: string): string | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Picks the region of the listed Bedrock models: `global` when the gateway
|
|
51
|
+
* lists it, else the prefix of the first id that has one. A gateway that lists
|
|
52
|
+
* `eu.*` and `us.*` ids gets the prefix that comes first, and the ids of the
|
|
53
|
+
* other prefixes are dropped, so the picker offers only models the CLI can
|
|
54
|
+
* call under that prefix. Ids without a prefix (`anthropic.claude-…`) are
|
|
55
|
+
* dropped too once a prefix is picked; without any prefix every id is kept.
|
|
56
|
+
*/
|
|
57
|
+
export declare function selectBedrockRegion(modelIds: readonly string[]): {
|
|
58
|
+
regionPrefix?: string;
|
|
59
|
+
modelIds: string[];
|
|
60
|
+
};
|
|
61
|
+
export {};
|
|
62
|
+
//# sourceMappingURL=gateway-models.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gateway-models.d.ts","sourceRoot":"","sources":["../src/gateway-models.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAQH;;;;;GAKG;AACH,eAAO,MAAM,+BAA+B,cAAc,CAAC;AAW3D,KAAK,aAAa,GAAG;IAAE,GAAG,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAC;IAAC,KAAK,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,IAAI,CAAA;CAAE,CAAC;AAIxF;;;;GAIG;AACH,qBAAa,mBAAoB,SAAQ,KAAK;IACnC,IAAI,SAAyB;CACvC;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAkB/B;AAED;;;;;;GAMG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,MAAM,EACf,eAAe,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACvC,MAAM,EAAE,aAAa,GACpB,OAAO,CAAC,MAAM,EAAE,GAAG,SAAS,CAAC,CAa/B;AAED,2EAA2E;AAC3E,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAGvE;AAED;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,GAAG;IAChE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB,CAUA"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model discovery for a gateway set via `providers/set`.
|
|
3
|
+
*
|
|
4
|
+
* An organization can restrict which models its gateway serves, and the
|
|
5
|
+
* gateway's listing returns only those: `GET /v1/models` for an `anthropic`
|
|
6
|
+
* gateway, `GET /foundation-models` (Bedrock `ListFoundationModels`) for a
|
|
7
|
+
* `bedrock` one. The adapter lists them once when the provider is set, and the
|
|
8
|
+
* model picker then offers only the SDK models the gateway listed (see
|
|
9
|
+
* `narrowToGatewayModels` in `session-model.ts`). A listing that fails fails
|
|
10
|
+
* `providers/set` with a {@link GatewayListingError}.
|
|
11
|
+
*/
|
|
12
|
+
const LISTING_TIMEOUT_MS = 10_000;
|
|
13
|
+
const ANTHROPIC_PAGE_LIMIT = "1000";
|
|
14
|
+
const MAX_LISTING_PAGES = 20;
|
|
15
|
+
const MAX_LOGGED_BODY_CHARS = 500;
|
|
16
|
+
const ANTHROPIC_VERSION = "2023-06-01";
|
|
17
|
+
/**
|
|
18
|
+
* The bearer token `createEnvForProvider` sets as `ANTHROPIC_AUTH_TOKEN` and
|
|
19
|
+
* `AWS_BEARER_TOKEN_BEDROCK`, so the CLI sends `Authorization: Bearer acp-proxy`
|
|
20
|
+
* unless the provider headers replace it. The listing sends the same, so the
|
|
21
|
+
* gateway sees the same auth as on chat requests.
|
|
22
|
+
*/
|
|
23
|
+
export const PROVIDER_AUTH_TOKEN_PLACEHOLDER = "acp-proxy";
|
|
24
|
+
/**
|
|
25
|
+
* The cross-region inference profile prefixes the CLI knows:
|
|
26
|
+
* `eu.anthropic.claude-sonnet-5`. `ANTHROPIC_BEDROCK_REGION_PREFIX` accepts all
|
|
27
|
+
* of them but `us-gov`, which the CLI takes only from a `us-gov-*` AWS region;
|
|
28
|
+
* a gateway listing only `us-gov.*` ids would then get an empty picker. That
|
|
29
|
+
* case is theoretical, so it is left as is.
|
|
30
|
+
*/
|
|
31
|
+
const BEDROCK_REGION_PREFIXES = ["us", "eu", "apac", "jp", "au", "us-gov", "global"];
|
|
32
|
+
/**
|
|
33
|
+
* A gateway listing that failed: a network error, a status other than 2xx or
|
|
34
|
+
* 4xx, a body that is not the expected listing, or the 10 s timeout. The
|
|
35
|
+
* message names the request path and the reason, never a header value.
|
|
36
|
+
*/
|
|
37
|
+
export class GatewayListingError extends Error {
|
|
38
|
+
name = "GatewayListingError";
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Lists the model ids an `anthropic` gateway at `baseUrl` serves, following
|
|
42
|
+
* `has_more` / `last_id` pagination. Returns `undefined` when the gateway
|
|
43
|
+
* answers 4xx: it has no listing, and nothing is narrowed. Throws a
|
|
44
|
+
* {@link GatewayListingError} when the listing fails. Header values are never
|
|
45
|
+
* logged.
|
|
46
|
+
*/
|
|
47
|
+
export async function listGatewayModels(baseUrl, providerHeaders, logger) {
|
|
48
|
+
return listPages(`${baseUrl.replace(/\/+$/, "")}/v1/models`, { limit: ANTHROPIC_PAGE_LIMIT }, listingHeaders(providerHeaders, { "anthropic-version": ANTHROPIC_VERSION }), logger, (body) => {
|
|
49
|
+
const page = body;
|
|
50
|
+
if (!Array.isArray(page.data))
|
|
51
|
+
return undefined;
|
|
52
|
+
return {
|
|
53
|
+
ids: stringField(page.data, "id"),
|
|
54
|
+
nextQuery: page.has_more === true && typeof page.last_id === "string"
|
|
55
|
+
? { limit: ANTHROPIC_PAGE_LIMIT, after_id: page.last_id }
|
|
56
|
+
: undefined,
|
|
57
|
+
};
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Lists the Anthropic models a `bedrock` gateway at `baseUrl` serves
|
|
62
|
+
* (`GET /foundation-models`, Bedrock `ListFoundationModels`, one page), the
|
|
63
|
+
* listing AI Router answers on its Bedrock route. Returns the listed ids, such
|
|
64
|
+
* as `global.anthropic.claude-sonnet-5-5`; `undefined` and the errors are
|
|
65
|
+
* those of {@link listGatewayModels}.
|
|
66
|
+
*/
|
|
67
|
+
export async function listBedrockModels(baseUrl, providerHeaders, logger) {
|
|
68
|
+
const ids = await listPages(`${baseUrl.replace(/\/+$/, "")}/foundation-models`, {}, listingHeaders(providerHeaders, {}), logger, (body) => {
|
|
69
|
+
const page = body;
|
|
70
|
+
if (!Array.isArray(page.modelSummaries))
|
|
71
|
+
return undefined;
|
|
72
|
+
return { ids: stringField(page.modelSummaries, "modelId") };
|
|
73
|
+
});
|
|
74
|
+
return ids?.filter((id) => id.includes("anthropic."));
|
|
75
|
+
}
|
|
76
|
+
/** The cross-region prefix of a Bedrock model id or ARN, if it has one. */
|
|
77
|
+
export function bedrockRegionPrefix(modelId) {
|
|
78
|
+
const id = modelId.slice(modelId.lastIndexOf("/") + 1).toLowerCase();
|
|
79
|
+
return BEDROCK_REGION_PREFIXES.find((prefix) => id.startsWith(`${prefix}.anthropic.`));
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Picks the region of the listed Bedrock models: `global` when the gateway
|
|
83
|
+
* lists it, else the prefix of the first id that has one. A gateway that lists
|
|
84
|
+
* `eu.*` and `us.*` ids gets the prefix that comes first, and the ids of the
|
|
85
|
+
* other prefixes are dropped, so the picker offers only models the CLI can
|
|
86
|
+
* call under that prefix. Ids without a prefix (`anthropic.claude-…`) are
|
|
87
|
+
* dropped too once a prefix is picked; without any prefix every id is kept.
|
|
88
|
+
*/
|
|
89
|
+
export function selectBedrockRegion(modelIds) {
|
|
90
|
+
const prefixes = modelIds.map(bedrockRegionPrefix);
|
|
91
|
+
const regionPrefix = prefixes.includes("global")
|
|
92
|
+
? "global"
|
|
93
|
+
: prefixes.find((prefix) => prefix !== undefined);
|
|
94
|
+
if (!regionPrefix)
|
|
95
|
+
return { modelIds: [...modelIds] };
|
|
96
|
+
return {
|
|
97
|
+
regionPrefix,
|
|
98
|
+
modelIds: modelIds.filter((id) => bedrockRegionPrefix(id) === regionPrefix),
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
// Provider headers win over the defaults, matched case-insensitively, the way
|
|
102
|
+
// `ANTHROPIC_CUSTOM_HEADERS` overrides the CLI's own headers.
|
|
103
|
+
function listingHeaders(providerHeaders, protocolHeaders) {
|
|
104
|
+
const headers = new Headers({
|
|
105
|
+
authorization: `Bearer ${PROVIDER_AUTH_TOKEN_PLACEHOLDER}`,
|
|
106
|
+
accept: "application/json",
|
|
107
|
+
...protocolHeaders,
|
|
108
|
+
});
|
|
109
|
+
for (const [name, value] of Object.entries(providerHeaders)) {
|
|
110
|
+
// `Headers.set` puts an invalid value into its error message, so name only the header.
|
|
111
|
+
try {
|
|
112
|
+
headers.set(name, value);
|
|
113
|
+
}
|
|
114
|
+
catch {
|
|
115
|
+
throw new GatewayListingError(`Model listing cannot send the invalid header "${name}"`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
return headers;
|
|
119
|
+
}
|
|
120
|
+
function stringField(entries, field) {
|
|
121
|
+
return entries.flatMap((entry) => {
|
|
122
|
+
const value = entry?.[field];
|
|
123
|
+
return typeof value === "string" && value.trim() !== "" ? [value] : [];
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Reads `endpoint` page by page; `parse` returns `undefined` for a body it does
|
|
128
|
+
* not understand. A 4xx answer on any page means the gateway has no listing:
|
|
129
|
+
* the result is `undefined`, and nothing is narrowed.
|
|
130
|
+
*/
|
|
131
|
+
async function listPages(endpoint, firstQuery, headers, logger, parse) {
|
|
132
|
+
const { pathname: path, username, password } = new URL(endpoint);
|
|
133
|
+
const failure = (reason) => {
|
|
134
|
+
const error = new GatewayListingError(`Model listing GET ${path} ${reason}`);
|
|
135
|
+
logger.error(`[providers/set] ${error.message}`);
|
|
136
|
+
return error;
|
|
137
|
+
};
|
|
138
|
+
// fetch refuses such a URL and repeats it, credentials included, in its error.
|
|
139
|
+
if (username || password)
|
|
140
|
+
throw failure("cannot be sent: the base URL carries credentials");
|
|
141
|
+
const signal = AbortSignal.timeout(LISTING_TIMEOUT_MS);
|
|
142
|
+
const ids = [];
|
|
143
|
+
let query = firstQuery;
|
|
144
|
+
for (let page = 0; page < MAX_LISTING_PAGES && query; page++) {
|
|
145
|
+
const url = new URL(endpoint);
|
|
146
|
+
for (const [name, value] of Object.entries(query))
|
|
147
|
+
url.searchParams.set(name, value);
|
|
148
|
+
let response;
|
|
149
|
+
let body;
|
|
150
|
+
try {
|
|
151
|
+
response = await fetch(url, { headers, signal });
|
|
152
|
+
body = await response.text();
|
|
153
|
+
}
|
|
154
|
+
catch (error) {
|
|
155
|
+
throw failure(`failed: ${error instanceof Error ? error.message : String(error)}`);
|
|
156
|
+
}
|
|
157
|
+
if (response.status >= 400 && response.status < 500) {
|
|
158
|
+
logger.log(`[providers/set] Model listing GET ${path} returned ${response.status}: the gateway has no listing, models are not narrowed`);
|
|
159
|
+
return undefined;
|
|
160
|
+
}
|
|
161
|
+
if (!response.ok) {
|
|
162
|
+
throw failure(`returned ${response.status}: ${body.slice(0, MAX_LOGGED_BODY_CHARS)}`);
|
|
163
|
+
}
|
|
164
|
+
let parsed;
|
|
165
|
+
try {
|
|
166
|
+
parsed = parse(JSON.parse(body));
|
|
167
|
+
}
|
|
168
|
+
catch {
|
|
169
|
+
parsed = undefined;
|
|
170
|
+
}
|
|
171
|
+
if (!parsed)
|
|
172
|
+
throw failure("returned an unexpected body");
|
|
173
|
+
ids.push(...parsed.ids);
|
|
174
|
+
query = parsed.nextQuery;
|
|
175
|
+
}
|
|
176
|
+
if (query) {
|
|
177
|
+
logger.error(`[providers/set] Model listing GET ${path} still had more pages after ${MAX_LISTING_PAGES}; using what was read`);
|
|
178
|
+
}
|
|
179
|
+
return ids;
|
|
180
|
+
}
|
|
@@ -34,6 +34,9 @@ export type NativeSubagent = {
|
|
|
34
34
|
missingError?: boolean;
|
|
35
35
|
/** The RFD form: the open permission and question requests of the child. */
|
|
36
36
|
openRequests?: number;
|
|
37
|
+
/** The RFD form: how many times the client cancelled the child (see
|
|
38
|
+
* `NativeSubagentRuntime.cancelChild`). */
|
|
39
|
+
cancels?: number;
|
|
37
40
|
/** The RFD form: the ids of the prompt messages in the child's transcript. */
|
|
38
41
|
promptIds?: Set<string>;
|
|
39
42
|
/** The RFD form: the calls that delegated to the child, whose runs ended. */
|
|
@@ -185,19 +188,32 @@ export declare class NativeSubagentRuntime {
|
|
|
185
188
|
* the cancel, for {@link awaitingUser}.
|
|
186
189
|
*/
|
|
187
190
|
parentCancelled(deliver: Publish): Promise<void>;
|
|
191
|
+
/**
|
|
192
|
+
* The RFD form: the client sent `session/cancel` for the child session
|
|
193
|
+
* `sessionId`, which the child's `cancel` capability permits (see
|
|
194
|
+
* `announceNativeSubagent`). `stop` stops the child's task, as
|
|
195
|
+
* `Query.stopTask` does: Claude Code stops the child's current work and the
|
|
196
|
+
* foreground subagents that it waits on, and the parent's work goes on. The
|
|
197
|
+
* SDK's task events report each stopped child `idle` with `cancelled` (see
|
|
198
|
+
* {@link finishTask}). Accepting the stop is no evidence that the child
|
|
199
|
+
* stopped, so nothing is reported here, and a child whose work already ended
|
|
200
|
+
* keeps its outcome. Returns false when `sessionId` is not a child session
|
|
201
|
+
* of this runtime. AIR's draft grants no `cancel`.
|
|
202
|
+
*/
|
|
203
|
+
cancelChild(sessionId: string, stop: (taskId: string) => Promise<void>): Promise<boolean>;
|
|
188
204
|
/**
|
|
189
205
|
* Runs `request`, a permission or question request of the session
|
|
190
206
|
* `sessionId`. In the RFD form, a child waiting on it is `requires_action`
|
|
191
207
|
* until its last open request ends, and then `running` again.
|
|
192
208
|
*
|
|
193
209
|
* `signal` aborts when Claude Code withdraws the request, which is not an
|
|
194
|
-
* answer. If the
|
|
195
|
-
*
|
|
196
|
-
*
|
|
197
|
-
* `running`, which would show a child
|
|
198
|
-
* Without a cancel, something else
|
|
199
|
-
*
|
|
200
|
-
* reports `running`.
|
|
210
|
+
* answer. If the root session, the child, or an ancestor of the child was
|
|
211
|
+
* cancelled while the request was open, Claude Code withdrew it as it
|
|
212
|
+
* stopped the child, and the SDK's events report the child `idle` next. The
|
|
213
|
+
* end of the request then reports no `running`, which would show a child
|
|
214
|
+
* that is being stopped as working. Without a cancel, something else
|
|
215
|
+
* answered the request in the user's place, such as a `PermissionRequest`
|
|
216
|
+
* hook, and the child runs on, so the end reports `running`.
|
|
201
217
|
*/
|
|
202
218
|
awaitingUser<T>(sessionId: string, request: () => Promise<T>, signal?: AbortSignal): Promise<T>;
|
|
203
219
|
discardPending(parentToolUseId: string): void;
|
|
@@ -269,6 +285,13 @@ export declare class NativeSubagentRuntime {
|
|
|
269
285
|
*/
|
|
270
286
|
private rememberSendMessage;
|
|
271
287
|
private rememberToolCallOwner;
|
|
288
|
+
/**
|
|
289
|
+
* The RFD form: how many cancels the client sent for `child`, its
|
|
290
|
+
* ancestors, and the root session. Each cancel stops the foreground work
|
|
291
|
+
* under it, and the counts only grow, so a changed sum shows that a cancel
|
|
292
|
+
* that reaches the child came.
|
|
293
|
+
*/
|
|
294
|
+
private cancelsAbove;
|
|
272
295
|
/** The child generation with the ACP session `sessionId`, if one exists. */
|
|
273
296
|
private childOfSession;
|
|
274
297
|
clear(): void;
|
|
@@ -299,8 +322,10 @@ export declare class NativeSubagentRuntime {
|
|
|
299
322
|
/**
|
|
300
323
|
* Announces the child on its parent, once, before any update of the child.
|
|
301
324
|
* The RFD form announces it as running and then sends the prompt as the
|
|
302
|
-
* first message of the child.
|
|
303
|
-
*
|
|
325
|
+
* first message of the child. It grants the child `cancel`: the client may
|
|
326
|
+
* stop the child's current work with `session/cancel` (see
|
|
327
|
+
* `NativeSubagentRuntime.cancelChild`), and nothing else. AIR's draft grants
|
|
328
|
+
* no capabilities.
|
|
304
329
|
*/
|
|
305
330
|
export declare function announceNativeSubagent(child: NativeSubagent, publish: Publish, form: SubagentForm): Promise<void>;
|
|
306
331
|
export declare function finishNativeSubagent(session: NativeSubagentSession, taskId: string, state: SubagentState, publish: Publish): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"native-subagents.d.ts","sourceRoot":"","sources":["../src/native-subagents.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"native-subagents.d.ts","sourceRoot":"","sources":["../src/native-subagents.ts"],"names":[],"mappings":"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"}
|
package/dist/native-subagents.js
CHANGED
|
@@ -372,25 +372,49 @@ export class NativeSubagentRuntime {
|
|
|
372
372
|
else
|
|
373
373
|
this.parentCancels++;
|
|
374
374
|
}
|
|
375
|
+
/**
|
|
376
|
+
* The RFD form: the client sent `session/cancel` for the child session
|
|
377
|
+
* `sessionId`, which the child's `cancel` capability permits (see
|
|
378
|
+
* `announceNativeSubagent`). `stop` stops the child's task, as
|
|
379
|
+
* `Query.stopTask` does: Claude Code stops the child's current work and the
|
|
380
|
+
* foreground subagents that it waits on, and the parent's work goes on. The
|
|
381
|
+
* SDK's task events report each stopped child `idle` with `cancelled` (see
|
|
382
|
+
* {@link finishTask}). Accepting the stop is no evidence that the child
|
|
383
|
+
* stopped, so nothing is reported here, and a child whose work already ended
|
|
384
|
+
* keeps its outcome. Returns false when `sessionId` is not a child session
|
|
385
|
+
* of this runtime. AIR's draft grants no `cancel`.
|
|
386
|
+
*/
|
|
387
|
+
async cancelChild(sessionId, stop) {
|
|
388
|
+
if (this.form !== "rfd")
|
|
389
|
+
return false;
|
|
390
|
+
for (const [taskId, child] of this.children) {
|
|
391
|
+
if (child.sessionId !== sessionId || !child.announced)
|
|
392
|
+
continue;
|
|
393
|
+
child.cancels = (child.cancels ?? 0) + 1;
|
|
394
|
+
await stop(taskId);
|
|
395
|
+
return true;
|
|
396
|
+
}
|
|
397
|
+
return false;
|
|
398
|
+
}
|
|
375
399
|
/**
|
|
376
400
|
* Runs `request`, a permission or question request of the session
|
|
377
401
|
* `sessionId`. In the RFD form, a child waiting on it is `requires_action`
|
|
378
402
|
* until its last open request ends, and then `running` again.
|
|
379
403
|
*
|
|
380
404
|
* `signal` aborts when Claude Code withdraws the request, which is not an
|
|
381
|
-
* answer. If the
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
* `running`, which would show a child
|
|
385
|
-
* Without a cancel, something else
|
|
386
|
-
*
|
|
387
|
-
* reports `running`.
|
|
405
|
+
* answer. If the root session, the child, or an ancestor of the child was
|
|
406
|
+
* cancelled while the request was open, Claude Code withdrew it as it
|
|
407
|
+
* stopped the child, and the SDK's events report the child `idle` next. The
|
|
408
|
+
* end of the request then reports no `running`, which would show a child
|
|
409
|
+
* that is being stopped as working. Without a cancel, something else
|
|
410
|
+
* answered the request in the user's place, such as a `PermissionRequest`
|
|
411
|
+
* hook, and the child runs on, so the end reports `running`.
|
|
388
412
|
*/
|
|
389
413
|
async awaitingUser(sessionId, request, signal) {
|
|
390
414
|
const child = this.form === "rfd" ? this.childOfSession(sessionId) : undefined;
|
|
391
415
|
if (!child?.announced)
|
|
392
416
|
return request();
|
|
393
|
-
const cancelsAtOpen = this.
|
|
417
|
+
const cancelsAtOpen = this.cancelsAbove(child);
|
|
394
418
|
child.openRequests = (child.openRequests ?? 0) + 1;
|
|
395
419
|
if (child.openRequests === 1 && child.workState === "running") {
|
|
396
420
|
await this.reportState(child, { state: "requires_action" }).catch((error) => this.logger.log(`Failed to report that subagent ${child.sessionId} waits: ${error}`));
|
|
@@ -401,7 +425,7 @@ export class NativeSubagentRuntime {
|
|
|
401
425
|
finally {
|
|
402
426
|
child.openRequests = (child.openRequests ?? 1) - 1;
|
|
403
427
|
// Withdrawn after a cancel that came while the request was open.
|
|
404
|
-
const stopped = signal?.aborted === true && this.
|
|
428
|
+
const stopped = signal?.aborted === true && this.cancelsAbove(child) !== cancelsAtOpen;
|
|
405
429
|
if (child.openRequests === 0 && child.workState === "requires_action" && !stopped) {
|
|
406
430
|
await this.reportState(child, { state: "running" }).catch((error) => this.logger.log(`Failed to report that subagent ${child.sessionId} runs: ${error}`));
|
|
407
431
|
}
|
|
@@ -604,6 +628,23 @@ export class NativeSubagentRuntime {
|
|
|
604
628
|
this.childByToolCall.delete(oldest);
|
|
605
629
|
}
|
|
606
630
|
}
|
|
631
|
+
/**
|
|
632
|
+
* The RFD form: how many cancels the client sent for `child`, its
|
|
633
|
+
* ancestors, and the root session. Each cancel stops the foreground work
|
|
634
|
+
* under it, and the counts only grow, so a changed sum shows that a cancel
|
|
635
|
+
* that reaches the child came.
|
|
636
|
+
*/
|
|
637
|
+
cancelsAbove(child) {
|
|
638
|
+
let cancels = this.parentCancels;
|
|
639
|
+
const seen = new Set();
|
|
640
|
+
let next = child;
|
|
641
|
+
while (next && !seen.has(next)) {
|
|
642
|
+
seen.add(next);
|
|
643
|
+
cancels += next.cancels ?? 0;
|
|
644
|
+
next = this.childOfSession(next.parentSessionId);
|
|
645
|
+
}
|
|
646
|
+
return cancels;
|
|
647
|
+
}
|
|
607
648
|
/** The child generation with the ACP session `sessionId`, if one exists. */
|
|
608
649
|
childOfSession(sessionId) {
|
|
609
650
|
if (sessionId === this.rootSessionId)
|
|
@@ -716,8 +757,10 @@ export class NativeSubagentRuntime {
|
|
|
716
757
|
/**
|
|
717
758
|
* Announces the child on its parent, once, before any update of the child.
|
|
718
759
|
* The RFD form announces it as running and then sends the prompt as the
|
|
719
|
-
* first message of the child.
|
|
720
|
-
*
|
|
760
|
+
* first message of the child. It grants the child `cancel`: the client may
|
|
761
|
+
* stop the child's current work with `session/cancel` (see
|
|
762
|
+
* `NativeSubagentRuntime.cancelChild`), and nothing else. AIR's draft grants
|
|
763
|
+
* no capabilities.
|
|
721
764
|
*/
|
|
722
765
|
export async function announceNativeSubagent(child, publish, form) {
|
|
723
766
|
if (child.announced)
|
|
@@ -734,6 +777,7 @@ export async function announceNativeSubagent(child, publish, form) {
|
|
|
734
777
|
sessionId: child.sessionId,
|
|
735
778
|
...(child.title ? { title: child.title } : {}),
|
|
736
779
|
...(child.description ? { description: child.description } : {}),
|
|
780
|
+
capabilities: { cancel: {} },
|
|
737
781
|
state: { state: "running" },
|
|
738
782
|
},
|
|
739
783
|
});
|