@ai-sdk/harness-acp 1.0.0 → 1.0.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/CHANGELOG.md +22 -0
- package/README.md +5 -6
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/bridge/index.mjs +145 -39
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +137 -19
- package/dist/index.js +187 -110
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/src/acp-harness.ts +26 -60
- package/src/acp-tool-call.ts +124 -0
- package/src/index.ts +21 -3
- package/src/v1/acp-v1-bridge-protocol.ts +17 -1
- package/src/v1/acp-v1-harness.ts +111 -21
- package/src/v1/acp-v1-settings.ts +27 -20
- package/src/v1/acp-v1-turn-start-config.ts +3 -0
- package/src/v1/bridge/acp-diagnostics.ts +27 -1
- package/src/v1/bridge/agent-stderr-monitor.ts +52 -0
- package/src/v1/bridge/create-emit-stream-event.ts +8 -1
- package/src/v1/bridge/index.ts +66 -34
- package/src/v1/bridge/stream-translator.ts +62 -5
- package/src/v1/implementation.ts +73 -47
- package/src/v1/index.ts +3 -3
package/dist/index.js
CHANGED
|
@@ -1,6 +1,33 @@
|
|
|
1
1
|
// src/acp-harness.ts
|
|
2
2
|
import { z as z4 } from "zod/v4";
|
|
3
3
|
|
|
4
|
+
// src/v1/acp-v1-harness.ts
|
|
5
|
+
import { createHash as createHash5, randomBytes } from "crypto";
|
|
6
|
+
import { readFile } from "fs/promises";
|
|
7
|
+
import { posix } from "path";
|
|
8
|
+
import { fileURLToPath } from "url";
|
|
9
|
+
import {
|
|
10
|
+
HarnessCapabilityUnsupportedError as HarnessCapabilityUnsupportedError2,
|
|
11
|
+
harnessV1DiagnosticFromBridgeFrame
|
|
12
|
+
} from "@ai-sdk/harness";
|
|
13
|
+
import { HarnessBridgeCapabilityUnsupportedError } from "@ai-sdk/harness/bridge";
|
|
14
|
+
import {
|
|
15
|
+
createBridgeErrorHandler,
|
|
16
|
+
createBridgeStartupError,
|
|
17
|
+
classifyDiskLog,
|
|
18
|
+
drainBridgeProcessStream,
|
|
19
|
+
forwardBridgeProcessStream,
|
|
20
|
+
markBridgeStarting,
|
|
21
|
+
resolveSandboxHomeDir,
|
|
22
|
+
SandboxChannel,
|
|
23
|
+
shellQuote,
|
|
24
|
+
waitForBridgeReady
|
|
25
|
+
} from "@ai-sdk/harness/utils";
|
|
26
|
+
import {
|
|
27
|
+
asSchema
|
|
28
|
+
} from "@ai-sdk/provider-utils";
|
|
29
|
+
import { WebSocket } from "ws";
|
|
30
|
+
|
|
4
31
|
// src/acp-auth.ts
|
|
5
32
|
import { createHash } from "crypto";
|
|
6
33
|
import { getAiGatewayAuthFromEnv } from "@ai-sdk/harness/utils";
|
|
@@ -145,53 +172,34 @@ function sortIdentityValue({ value }) {
|
|
|
145
172
|
return value;
|
|
146
173
|
}
|
|
147
174
|
|
|
148
|
-
// src/v1/acp-v1-harness.ts
|
|
149
|
-
import { createHash as createHash5, randomBytes } from "crypto";
|
|
150
|
-
import { readFile } from "fs/promises";
|
|
151
|
-
import { posix } from "path";
|
|
152
|
-
import { fileURLToPath } from "url";
|
|
153
|
-
import {
|
|
154
|
-
HarnessCapabilityUnsupportedError as HarnessCapabilityUnsupportedError2,
|
|
155
|
-
harnessV1DiagnosticFromBridgeFrame
|
|
156
|
-
} from "@ai-sdk/harness";
|
|
157
|
-
import { HarnessBridgeCapabilityUnsupportedError } from "@ai-sdk/harness/bridge";
|
|
158
|
-
import {
|
|
159
|
-
createBridgeErrorHandler,
|
|
160
|
-
createBridgeStartupError,
|
|
161
|
-
classifyDiskLog,
|
|
162
|
-
drainBridgeProcessStream,
|
|
163
|
-
forwardBridgeProcessStream,
|
|
164
|
-
markBridgeStarting,
|
|
165
|
-
resolveSandboxHomeDir,
|
|
166
|
-
SandboxChannel,
|
|
167
|
-
shellQuote,
|
|
168
|
-
waitForBridgeReady
|
|
169
|
-
} from "@ai-sdk/harness/utils";
|
|
170
|
-
import {
|
|
171
|
-
asSchema
|
|
172
|
-
} from "@ai-sdk/provider-utils";
|
|
173
|
-
import { WebSocket } from "ws";
|
|
174
|
-
|
|
175
175
|
// src/v1/implementation.ts
|
|
176
176
|
import { createHash as createHash2 } from "crypto";
|
|
177
|
+
function createACPV1Implementation({
|
|
178
|
+
settings
|
|
179
|
+
}) {
|
|
180
|
+
return {
|
|
181
|
+
source: settings.source,
|
|
182
|
+
executable: settings.executable,
|
|
183
|
+
args: settings.args,
|
|
184
|
+
forwardEnv: settings.forwardEnv,
|
|
185
|
+
env: settings.env
|
|
186
|
+
};
|
|
187
|
+
}
|
|
177
188
|
var EXACT_SEMVER_REGEXP = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
178
189
|
var PACKAGE_NAME_REGEXP = /^(?:@[a-z0-9][a-z0-9._-]*\/)?[a-z0-9][a-z0-9._-]*$/;
|
|
179
190
|
var EXECUTABLE_NAME_REGEXP = /^[A-Za-z0-9][A-Za-z0-9._-]*$/;
|
|
180
191
|
var ENVIRONMENT_VARIABLE_NAME_REGEXP = /^[A-Za-z_][A-Za-z0-9_]*$/;
|
|
181
192
|
function validateACPV1Implementation(implementation) {
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
);
|
|
193
|
+
const { source } = implementation;
|
|
194
|
+
if (source.type === "npm-locked") {
|
|
195
|
+
if (source.packageJson.length === 0) {
|
|
196
|
+
throw new Error("ACP source.packageJson must not be empty.");
|
|
187
197
|
}
|
|
188
|
-
if (
|
|
189
|
-
throw new Error(
|
|
190
|
-
"ACP locked npm implementation pnpmLockYaml must not be empty."
|
|
191
|
-
);
|
|
198
|
+
if (source.pnpmLockYaml.length === 0) {
|
|
199
|
+
throw new Error("ACP source.pnpmLockYaml must not be empty.");
|
|
192
200
|
}
|
|
193
201
|
} else {
|
|
194
|
-
|
|
202
|
+
validateNpmSimpleSource({ source });
|
|
195
203
|
}
|
|
196
204
|
if (!EXECUTABLE_NAME_REGEXP.test(implementation.executable)) {
|
|
197
205
|
throw new Error(
|
|
@@ -212,8 +220,9 @@ function validateACPV1Implementation(implementation) {
|
|
|
212
220
|
function createImplementationManifest({
|
|
213
221
|
implementation
|
|
214
222
|
}) {
|
|
215
|
-
|
|
216
|
-
|
|
223
|
+
const { source } = implementation;
|
|
224
|
+
if (source.type === "npm-locked") {
|
|
225
|
+
return source.packageJson;
|
|
217
226
|
}
|
|
218
227
|
return JSON.stringify(
|
|
219
228
|
{
|
|
@@ -222,7 +231,7 @@ function createImplementationManifest({
|
|
|
222
231
|
private: true,
|
|
223
232
|
type: "module",
|
|
224
233
|
dependencies: {
|
|
225
|
-
[
|
|
234
|
+
[source.packageName]: source.packageVersion ?? "latest"
|
|
226
235
|
}
|
|
227
236
|
},
|
|
228
237
|
null,
|
|
@@ -232,18 +241,17 @@ function createImplementationManifest({
|
|
|
232
241
|
function getImplementationLockfile({
|
|
233
242
|
implementation
|
|
234
243
|
}) {
|
|
235
|
-
|
|
244
|
+
const { source } = implementation;
|
|
245
|
+
return source.type === "npm-locked" ? source.pnpmLockYaml : void 0;
|
|
236
246
|
}
|
|
237
247
|
function createImplementationDescriptor({
|
|
238
|
-
implementation
|
|
239
|
-
implementationIdentity
|
|
248
|
+
implementation
|
|
240
249
|
}) {
|
|
241
250
|
return JSON.stringify(
|
|
242
251
|
{
|
|
243
252
|
executable: implementation.executable,
|
|
244
253
|
args: implementation.args ?? [],
|
|
245
|
-
envKeys: getImplementationEnvironmentKeys({ implementation })
|
|
246
|
-
implementationIdentity
|
|
254
|
+
envKeys: getImplementationEnvironmentKeys({ implementation })
|
|
247
255
|
},
|
|
248
256
|
null,
|
|
249
257
|
2
|
|
@@ -257,14 +265,15 @@ function createImplementationIdentity({
|
|
|
257
265
|
providerAuthentication,
|
|
258
266
|
permissionModeMapping
|
|
259
267
|
}) {
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
268
|
+
const { source } = implementation;
|
|
269
|
+
const sourceIdentity = source.type === "npm-locked" ? {
|
|
270
|
+
type: source.type,
|
|
271
|
+
packageJson: source.packageJson,
|
|
272
|
+
pnpmLockYaml: source.pnpmLockYaml
|
|
264
273
|
} : {
|
|
265
|
-
|
|
266
|
-
packageName:
|
|
267
|
-
|
|
274
|
+
type: source.type,
|
|
275
|
+
packageName: source.packageName,
|
|
276
|
+
...source.packageVersion == null ? {} : { packageVersion: source.packageVersion }
|
|
268
277
|
};
|
|
269
278
|
const forwardedEnvironment = [
|
|
270
279
|
...new Set(implementation.forwardEnv ?? [])
|
|
@@ -275,7 +284,7 @@ function createImplementationIdentity({
|
|
|
275
284
|
const payload = {
|
|
276
285
|
harnessId,
|
|
277
286
|
acpVersion,
|
|
278
|
-
|
|
287
|
+
source: sourceIdentity,
|
|
279
288
|
executable: implementation.executable,
|
|
280
289
|
args: implementation.args ?? [],
|
|
281
290
|
clientApp,
|
|
@@ -293,7 +302,7 @@ function createImplementationInstallCommand({
|
|
|
293
302
|
storeDir,
|
|
294
303
|
implementation
|
|
295
304
|
}) {
|
|
296
|
-
return `pnpm --dir ${implementationDir} install` + (
|
|
305
|
+
return `pnpm --dir ${implementationDir} install` + (implementation.source.type === "npm-locked" ? " --frozen-lockfile" : "") + ` --prod --store-dir ${storeDir}`;
|
|
297
306
|
}
|
|
298
307
|
function resolveImplementationEnvironment({
|
|
299
308
|
implementation,
|
|
@@ -311,17 +320,17 @@ function resolveImplementationEnvironment({
|
|
|
311
320
|
...implementation.env
|
|
312
321
|
};
|
|
313
322
|
}
|
|
314
|
-
function
|
|
315
|
-
|
|
323
|
+
function validateNpmSimpleSource({
|
|
324
|
+
source
|
|
316
325
|
}) {
|
|
317
|
-
if (!PACKAGE_NAME_REGEXP.test(
|
|
326
|
+
if (!PACKAGE_NAME_REGEXP.test(source.packageName)) {
|
|
318
327
|
throw new Error(
|
|
319
|
-
`ACP npm package name is invalid: ${JSON.stringify(
|
|
328
|
+
`ACP npm package name is invalid: ${JSON.stringify(source.packageName)}.`
|
|
320
329
|
);
|
|
321
330
|
}
|
|
322
|
-
if (!EXACT_SEMVER_REGEXP.test(
|
|
331
|
+
if (source.packageVersion != null && !EXACT_SEMVER_REGEXP.test(source.packageVersion)) {
|
|
323
332
|
throw new Error(
|
|
324
|
-
`ACP npm
|
|
333
|
+
`ACP npm package version must be an exact semantic version; received ${JSON.stringify(source.packageVersion)}.`
|
|
325
334
|
);
|
|
326
335
|
}
|
|
327
336
|
}
|
|
@@ -360,9 +369,6 @@ function getImplementationEnvironmentKeys({
|
|
|
360
369
|
])
|
|
361
370
|
].sort();
|
|
362
371
|
}
|
|
363
|
-
function isLockedImplementation(implementation) {
|
|
364
|
-
return implementation.mode === "locked";
|
|
365
|
-
}
|
|
366
372
|
function stableStringify2({ value }) {
|
|
367
373
|
return JSON.stringify(sortValue({ value }));
|
|
368
374
|
}
|
|
@@ -534,9 +540,19 @@ var coldRestoreSchema = z2.object({
|
|
|
534
540
|
type: z2.literal("cold-restore"),
|
|
535
541
|
acpSessionId: z2.string()
|
|
536
542
|
});
|
|
537
|
-
var
|
|
543
|
+
var acpToolCallCandidateSchema = z2.object({
|
|
544
|
+
type: z2.literal("acp-tool-call-candidate"),
|
|
545
|
+
toolCall: z2.custom(
|
|
546
|
+
(value) => value != null && typeof value === "object" && typeof value.toolCallId === "string" && typeof value.title === "string"
|
|
547
|
+
)
|
|
548
|
+
});
|
|
549
|
+
var outboundMessageSchema = z2.union([
|
|
550
|
+
harnessV1BridgeOutboundMessageSchema,
|
|
551
|
+
acpToolCallCandidateSchema
|
|
552
|
+
]);
|
|
538
553
|
var startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
|
|
539
554
|
prompt: z2.array(acpTextContentBlockSchema),
|
|
555
|
+
mcpServers: z2.record(z2.string(), z2.unknown()).optional(),
|
|
540
556
|
tools: z2.array(acpSerializableToolSpecSchema).optional(),
|
|
541
557
|
builtinTools: z2.array(builtinToolSchema).readonly().default([]),
|
|
542
558
|
permissionModeMapping: permissionModeMappingSchema.optional(),
|
|
@@ -616,6 +632,7 @@ function createACPTurnStartConfig({
|
|
|
616
632
|
builtinTools,
|
|
617
633
|
permissionMode,
|
|
618
634
|
permissionModeMapping,
|
|
635
|
+
mcpServers,
|
|
619
636
|
debug,
|
|
620
637
|
authenticationProfile,
|
|
621
638
|
sessionMeta
|
|
@@ -627,7 +644,8 @@ function createACPTurnStartConfig({
|
|
|
627
644
|
authenticationProfile,
|
|
628
645
|
sessionMeta: sessionMeta ?? null,
|
|
629
646
|
builtinTools,
|
|
630
|
-
permissionModeMapping: permissionModeMapping ?? null
|
|
647
|
+
permissionModeMapping: permissionModeMapping ?? null,
|
|
648
|
+
mcpServers: mcpServers ?? null
|
|
631
649
|
})
|
|
632
650
|
).digest("hex"),
|
|
633
651
|
prompt: [...prompt],
|
|
@@ -889,17 +907,23 @@ function createACPV1({
|
|
|
889
907
|
port: portOverride,
|
|
890
908
|
startupTimeoutMs,
|
|
891
909
|
clientApp,
|
|
892
|
-
implementationIdentity,
|
|
893
|
-
authenticationProfile,
|
|
894
|
-
providerAuthenticationCompatibility,
|
|
895
910
|
lifecycleStateSchema
|
|
896
911
|
}) {
|
|
912
|
+
if (settings.mcpServers != null && Object.prototype.hasOwnProperty.call(
|
|
913
|
+
settings.mcpServers,
|
|
914
|
+
"ai-sdk-harness-tools"
|
|
915
|
+
)) {
|
|
916
|
+
throw new Error(
|
|
917
|
+
'ACP MCP server name "ai-sdk-harness-tools" is reserved for HarnessAgent tools.'
|
|
918
|
+
);
|
|
919
|
+
}
|
|
897
920
|
if (!HARNESS_ID_REGEXP.test(settings.harnessId)) {
|
|
898
921
|
throw new Error(
|
|
899
922
|
`ACP harnessId must be a stable kebab-case identifier; received ${JSON.stringify(settings.harnessId)}.`
|
|
900
923
|
);
|
|
901
924
|
}
|
|
902
|
-
|
|
925
|
+
const implementation = createACPV1Implementation({ settings });
|
|
926
|
+
validateACPV1Implementation(implementation);
|
|
903
927
|
const BOOTSTRAP_DIR = `.harness-bootstrap/${settings.harnessId}`;
|
|
904
928
|
let cachedBootstrap;
|
|
905
929
|
const permissionModeMapping = isCompletePermissionModeMapping({
|
|
@@ -921,7 +945,7 @@ function createACPV1({
|
|
|
921
945
|
readBridgeAsset({ name: "host-tool-mcp.mjs" })
|
|
922
946
|
]);
|
|
923
947
|
const implementationLock = getImplementationLockfile({
|
|
924
|
-
implementation
|
|
948
|
+
implementation
|
|
925
949
|
});
|
|
926
950
|
cachedBootstrap = {
|
|
927
951
|
harnessId: settings.harnessId,
|
|
@@ -943,14 +967,13 @@ function createACPV1({
|
|
|
943
967
|
{
|
|
944
968
|
path: `${BOOTSTRAP_DIR}/implementation/package.json`,
|
|
945
969
|
content: createImplementationManifest({
|
|
946
|
-
implementation
|
|
970
|
+
implementation
|
|
947
971
|
})
|
|
948
972
|
},
|
|
949
973
|
{
|
|
950
974
|
path: `${BOOTSTRAP_DIR}/implementation/implementation.json`,
|
|
951
975
|
content: createImplementationDescriptor({
|
|
952
|
-
implementation
|
|
953
|
-
implementationIdentity
|
|
976
|
+
implementation
|
|
954
977
|
})
|
|
955
978
|
},
|
|
956
979
|
...implementationLock == null ? [] : [
|
|
@@ -968,7 +991,7 @@ function createACPV1({
|
|
|
968
991
|
command: createImplementationInstallCommand({
|
|
969
992
|
implementationDir: "implementation",
|
|
970
993
|
storeDir: "../.pnpm-store",
|
|
971
|
-
implementation
|
|
994
|
+
implementation
|
|
972
995
|
})
|
|
973
996
|
}
|
|
974
997
|
]
|
|
@@ -983,13 +1006,31 @@ function createACPV1({
|
|
|
983
1006
|
});
|
|
984
1007
|
}
|
|
985
1008
|
const permissionMode = startOptions.permissionMode ?? "allow-all";
|
|
1009
|
+
const env = { ...process.env };
|
|
1010
|
+
const providerAuthenticationCompatibility = resolveACPProviderAuthenticationCompatibility({
|
|
1011
|
+
auth: settings.auth,
|
|
1012
|
+
providerAuthentication: settings.providerAuthentication,
|
|
1013
|
+
env
|
|
1014
|
+
});
|
|
1015
|
+
const implementationIdentity = createImplementationIdentity({
|
|
1016
|
+
harnessId: settings.harnessId,
|
|
1017
|
+
acpVersion: "v1",
|
|
1018
|
+
implementation,
|
|
1019
|
+
clientApp,
|
|
1020
|
+
providerAuthentication: providerAuthenticationCompatibility,
|
|
1021
|
+
permissionModeMapping: settings.permissionModeMapping
|
|
1022
|
+
});
|
|
1023
|
+
const authenticationProfile = createACPAuthenticationProfileIdentity({
|
|
1024
|
+
authentication: settings.authentication,
|
|
1025
|
+
providerAuthenticationCompatibility
|
|
1026
|
+
});
|
|
986
1027
|
const resolvedProviderAuthentication = resolveACPProviderAuthentication({
|
|
987
1028
|
auth: {
|
|
988
1029
|
mode: settings.auth,
|
|
989
1030
|
providerAuthentication: settings.providerAuthentication,
|
|
990
1031
|
clientApp
|
|
991
1032
|
},
|
|
992
|
-
env
|
|
1033
|
+
env,
|
|
993
1034
|
compatibility: providerAuthenticationCompatibility
|
|
994
1035
|
});
|
|
995
1036
|
const sandboxSession = startOptions.sandboxSession;
|
|
@@ -1097,6 +1138,8 @@ function createACPV1({
|
|
|
1097
1138
|
builtinTools: builtinToolCatalog,
|
|
1098
1139
|
permissionMode,
|
|
1099
1140
|
permissionModeMapping,
|
|
1141
|
+
mcpServers: settings.mcpServers,
|
|
1142
|
+
isMcpToolCall: settings.isMcpToolCall,
|
|
1100
1143
|
initialGuidanceApplied: resolveACPInitialGuidanceApplied({
|
|
1101
1144
|
isResume: true,
|
|
1102
1145
|
lifecycleState: lifecycleData
|
|
@@ -1146,7 +1189,8 @@ function createACPV1({
|
|
|
1146
1189
|
authenticationProfile,
|
|
1147
1190
|
sessionMeta: settings.session?.meta,
|
|
1148
1191
|
builtinTools: builtinToolCatalog,
|
|
1149
|
-
permissionModeMapping
|
|
1192
|
+
permissionModeMapping,
|
|
1193
|
+
mcpServers: settings.mcpServers
|
|
1150
1194
|
});
|
|
1151
1195
|
respawnStrategy = {
|
|
1152
1196
|
mode: "lossy-rerun",
|
|
@@ -1175,6 +1219,7 @@ function createACPV1({
|
|
|
1175
1219
|
sessionMeta: settings.session?.meta,
|
|
1176
1220
|
builtinTools: builtinToolCatalog,
|
|
1177
1221
|
permissionModeMapping,
|
|
1222
|
+
mcpServers: settings.mcpServers,
|
|
1178
1223
|
debug: startOptions.observability?.debug
|
|
1179
1224
|
});
|
|
1180
1225
|
respawnStrategy = {
|
|
@@ -1189,7 +1234,7 @@ function createACPV1({
|
|
|
1189
1234
|
override: portOverride,
|
|
1190
1235
|
harnessId: settings.harnessId
|
|
1191
1236
|
});
|
|
1192
|
-
const token = randomBytes(32).toString("hex");
|
|
1237
|
+
const token = settings.mintBridgeToken == null ? randomBytes(32).toString("hex") : settings.mintBridgeToken(sandboxSession.id);
|
|
1193
1238
|
await sandbox.run({
|
|
1194
1239
|
command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)}`,
|
|
1195
1240
|
abortSignal: startOptions.abortSignal
|
|
@@ -1204,8 +1249,8 @@ function createACPV1({
|
|
|
1204
1249
|
command: `node ${shellQuote(`${resolvedBridgeDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --implementation-dir ${shellQuote(resolvedImplementationDir)} --bridge-type ${shellQuote(settings.harnessId)}`,
|
|
1205
1250
|
env: {
|
|
1206
1251
|
...resolveImplementationEnvironment({
|
|
1207
|
-
implementation
|
|
1208
|
-
env
|
|
1252
|
+
implementation,
|
|
1253
|
+
env
|
|
1209
1254
|
}),
|
|
1210
1255
|
...createACPBridgeEnvironment({
|
|
1211
1256
|
authentication: settings.authentication,
|
|
@@ -1279,6 +1324,7 @@ function createACPV1({
|
|
|
1279
1324
|
builtinTools: builtinToolCatalog,
|
|
1280
1325
|
permissionMode,
|
|
1281
1326
|
permissionModeMapping,
|
|
1327
|
+
...settings.mcpServers == null ? {} : { mcpServers: settings.mcpServers },
|
|
1282
1328
|
tools: respawnStrategy.turnStartConfig.tools,
|
|
1283
1329
|
turnStartConfig: respawnStrategy.turnStartConfig,
|
|
1284
1330
|
recoveryMode: {
|
|
@@ -1316,6 +1362,8 @@ function createACPV1({
|
|
|
1316
1362
|
builtinTools: builtinToolCatalog,
|
|
1317
1363
|
permissionMode,
|
|
1318
1364
|
permissionModeMapping,
|
|
1365
|
+
mcpServers: settings.mcpServers,
|
|
1366
|
+
isMcpToolCall: settings.isMcpToolCall,
|
|
1319
1367
|
initialGuidanceApplied: resolveACPInitialGuidanceApplied({
|
|
1320
1368
|
isResume,
|
|
1321
1369
|
lifecycleState: lifecycleData
|
|
@@ -1475,6 +1523,8 @@ function createSession({
|
|
|
1475
1523
|
builtinTools,
|
|
1476
1524
|
permissionMode,
|
|
1477
1525
|
permissionModeMapping,
|
|
1526
|
+
mcpServers,
|
|
1527
|
+
isMcpToolCall,
|
|
1478
1528
|
initialGuidanceApplied: initialGuidanceAppliedAtStart,
|
|
1479
1529
|
skillCatalog,
|
|
1480
1530
|
skillsFingerprint,
|
|
@@ -1521,6 +1571,8 @@ function createSession({
|
|
|
1521
1571
|
let abortError;
|
|
1522
1572
|
let abortListenerAttached = false;
|
|
1523
1573
|
let openBlock;
|
|
1574
|
+
const dynamicToolCalls = /* @__PURE__ */ new Map();
|
|
1575
|
+
const toolCallClassificationErrors = /* @__PURE__ */ new Map();
|
|
1524
1576
|
const subscriptions = [];
|
|
1525
1577
|
const forward = (event) => {
|
|
1526
1578
|
if (event.type === "text-start" || event.type === "reasoning-start") {
|
|
@@ -1553,9 +1605,7 @@ function createSession({
|
|
|
1553
1605
|
"reasoning-start",
|
|
1554
1606
|
"reasoning-delta",
|
|
1555
1607
|
"reasoning-end",
|
|
1556
|
-
"tool-call",
|
|
1557
1608
|
"tool-approval-request",
|
|
1558
|
-
"tool-result",
|
|
1559
1609
|
"file-change",
|
|
1560
1610
|
"finish-step",
|
|
1561
1611
|
"raw"
|
|
@@ -1583,6 +1633,44 @@ function createSession({
|
|
|
1583
1633
|
settle({ error: abortError });
|
|
1584
1634
|
}
|
|
1585
1635
|
};
|
|
1636
|
+
subscriptions.push(
|
|
1637
|
+
channel.on("acp-tool-call-candidate", (event) => {
|
|
1638
|
+
try {
|
|
1639
|
+
dynamicToolCalls.set(
|
|
1640
|
+
event.toolCall.toolCallId,
|
|
1641
|
+
isMcpToolCall?.(event.toolCall) === true
|
|
1642
|
+
);
|
|
1643
|
+
} catch (error) {
|
|
1644
|
+
toolCallClassificationErrors.set(event.toolCall.toolCallId, error);
|
|
1645
|
+
}
|
|
1646
|
+
})
|
|
1647
|
+
);
|
|
1648
|
+
subscriptions.push(
|
|
1649
|
+
channel.on("tool-call", (event) => {
|
|
1650
|
+
if (toolCallClassificationErrors.has(event.toolCallId)) {
|
|
1651
|
+
const error = toolCallClassificationErrors.get(event.toolCallId);
|
|
1652
|
+
closeForwardedBlock();
|
|
1653
|
+
forward({ type: "error", error });
|
|
1654
|
+
try {
|
|
1655
|
+
channel.send({ type: "abort" });
|
|
1656
|
+
} catch {
|
|
1657
|
+
}
|
|
1658
|
+
settle({ error });
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
forward(
|
|
1662
|
+
dynamicToolCalls.get(event.toolCallId) === true ? { ...event, dynamic: true } : event
|
|
1663
|
+
);
|
|
1664
|
+
})
|
|
1665
|
+
);
|
|
1666
|
+
subscriptions.push(
|
|
1667
|
+
channel.on("tool-result", (event) => {
|
|
1668
|
+
const dynamic = dynamicToolCalls.get(event.toolCallId) === true;
|
|
1669
|
+
dynamicToolCalls.delete(event.toolCallId);
|
|
1670
|
+
toolCallClassificationErrors.delete(event.toolCallId);
|
|
1671
|
+
forward(dynamic ? { ...event, dynamic: true } : event);
|
|
1672
|
+
})
|
|
1673
|
+
);
|
|
1586
1674
|
for (const type of eventTypes) {
|
|
1587
1675
|
subscriptions.push(channel.on(type, (event) => forward(event)));
|
|
1588
1676
|
}
|
|
@@ -1723,6 +1811,7 @@ function createSession({
|
|
|
1723
1811
|
builtinTools,
|
|
1724
1812
|
permissionMode,
|
|
1725
1813
|
permissionModeMapping,
|
|
1814
|
+
mcpServers,
|
|
1726
1815
|
debug,
|
|
1727
1816
|
authenticationProfile,
|
|
1728
1817
|
sessionMeta
|
|
@@ -1748,6 +1837,7 @@ function createSession({
|
|
|
1748
1837
|
builtinTools,
|
|
1749
1838
|
permissionMode,
|
|
1750
1839
|
permissionModeMapping,
|
|
1840
|
+
...mcpServers == null ? {} : { mcpServers },
|
|
1751
1841
|
tools: options.tools == null ? void 0 : turnStartConfig.tools,
|
|
1752
1842
|
turnStartConfig
|
|
1753
1843
|
});
|
|
@@ -1785,6 +1875,7 @@ function createSession({
|
|
|
1785
1875
|
builtinTools: turnStartConfig.builtinTools,
|
|
1786
1876
|
permissionMode: turnStartConfig.permissionMode,
|
|
1787
1877
|
permissionModeMapping: turnStartConfig.permissionModeMapping,
|
|
1878
|
+
...mcpServers == null ? {} : { mcpServers },
|
|
1788
1879
|
tools: turnStartConfig.tools,
|
|
1789
1880
|
turnStartConfig,
|
|
1790
1881
|
recoveryMode: {
|
|
@@ -1917,7 +2008,8 @@ function validateACPTurnStartConfig({
|
|
|
1917
2008
|
authenticationProfile,
|
|
1918
2009
|
sessionMeta,
|
|
1919
2010
|
builtinTools,
|
|
1920
|
-
permissionModeMapping
|
|
2011
|
+
permissionModeMapping,
|
|
2012
|
+
mcpServers
|
|
1921
2013
|
}) {
|
|
1922
2014
|
const current = createACPTurnStartConfig({
|
|
1923
2015
|
prompt: turnStartConfig.prompt,
|
|
@@ -1925,6 +2017,7 @@ function validateACPTurnStartConfig({
|
|
|
1925
2017
|
builtinTools,
|
|
1926
2018
|
permissionMode: turnStartConfig.permissionMode,
|
|
1927
2019
|
permissionModeMapping,
|
|
2020
|
+
mcpServers,
|
|
1928
2021
|
debug: turnStartConfig.debug,
|
|
1929
2022
|
authenticationProfile,
|
|
1930
2023
|
sessionMeta
|
|
@@ -1943,6 +2036,7 @@ function validateACPColdSessionConfiguration({
|
|
|
1943
2036
|
sessionMeta,
|
|
1944
2037
|
builtinTools,
|
|
1945
2038
|
permissionModeMapping,
|
|
2039
|
+
mcpServers,
|
|
1946
2040
|
debug
|
|
1947
2041
|
}) {
|
|
1948
2042
|
const current = createACPTurnStartConfig({
|
|
@@ -1951,6 +2045,7 @@ function validateACPColdSessionConfiguration({
|
|
|
1951
2045
|
builtinTools,
|
|
1952
2046
|
permissionMode,
|
|
1953
2047
|
permissionModeMapping,
|
|
2048
|
+
mcpServers,
|
|
1954
2049
|
debug,
|
|
1955
2050
|
authenticationProfile,
|
|
1956
2051
|
sessionMeta
|
|
@@ -2000,7 +2095,7 @@ function deserializeBridgeError({
|
|
|
2000
2095
|
}
|
|
2001
2096
|
|
|
2002
2097
|
// src/version.ts
|
|
2003
|
-
var VERSION = true ? "1.0.
|
|
2098
|
+
var VERSION = true ? "1.0.2" : "0.0.0-test";
|
|
2004
2099
|
|
|
2005
2100
|
// src/acp-harness.ts
|
|
2006
2101
|
var ACP_CLIENT_APP = {
|
|
@@ -2042,43 +2137,25 @@ var acpResumeStateSchema = z4.object({
|
|
|
2042
2137
|
skillsFingerprint: z4.string().optional()
|
|
2043
2138
|
});
|
|
2044
2139
|
function createACP(settings) {
|
|
2140
|
+
if (settings.mcpServers != null && Object.prototype.hasOwnProperty.call(
|
|
2141
|
+
settings.mcpServers,
|
|
2142
|
+
"ai-sdk-harness-tools"
|
|
2143
|
+
)) {
|
|
2144
|
+
throw new Error(
|
|
2145
|
+
'ACP MCP server name "ai-sdk-harness-tools" is reserved for HarnessAgent tools.'
|
|
2146
|
+
);
|
|
2147
|
+
}
|
|
2045
2148
|
const version = settings.version ?? "v1";
|
|
2046
2149
|
switch (version) {
|
|
2047
2150
|
case "v1": {
|
|
2048
2151
|
const clientApp = settings.clientApp ?? ACP_CLIENT_APP;
|
|
2049
|
-
const providerAuthenticationCompatibility = resolveACPProviderAuthenticationCompatibility({
|
|
2050
|
-
auth: settings.auth,
|
|
2051
|
-
providerAuthentication: settings.providerAuthentication,
|
|
2052
|
-
env: process.env
|
|
2053
|
-
});
|
|
2054
|
-
const implementationIdentity = createImplementationIdentity({
|
|
2055
|
-
harnessId: settings.harnessId,
|
|
2056
|
-
acpVersion: version,
|
|
2057
|
-
implementation: settings.implementation,
|
|
2058
|
-
clientApp,
|
|
2059
|
-
providerAuthentication: providerAuthenticationCompatibility,
|
|
2060
|
-
permissionModeMapping: settings.permissionModeMapping
|
|
2061
|
-
});
|
|
2062
|
-
const authenticationProfile = createACPAuthenticationProfileIdentity({
|
|
2063
|
-
authentication: settings.authentication,
|
|
2064
|
-
providerAuthenticationCompatibility
|
|
2065
|
-
});
|
|
2066
|
-
const lifecycleStateSchema = acpResumeStateSchema.extend({
|
|
2067
|
-
implementationIdentity: z4.literal(implementationIdentity),
|
|
2068
|
-
authenticationProfile: acpResumeStateSchema.shape.authenticationProfile.unwrap().extend({
|
|
2069
|
-
digest: z4.literal(authenticationProfile.digest)
|
|
2070
|
-
}).optional()
|
|
2071
|
-
});
|
|
2072
2152
|
return createACPV1({
|
|
2073
2153
|
settings,
|
|
2074
2154
|
builtinTools: settings.builtinTools ?? ACP_BUILTIN_TOOLS,
|
|
2075
2155
|
port: settings.port,
|
|
2076
2156
|
startupTimeoutMs: settings.startupTimeoutMs,
|
|
2077
2157
|
clientApp,
|
|
2078
|
-
|
|
2079
|
-
authenticationProfile,
|
|
2080
|
-
providerAuthenticationCompatibility,
|
|
2081
|
-
lifecycleStateSchema
|
|
2158
|
+
lifecycleStateSchema: acpResumeStateSchema
|
|
2082
2159
|
});
|
|
2083
2160
|
}
|
|
2084
2161
|
default:
|