@ai-sdk/harness-acp 1.0.24 → 1.0.25
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 +11 -0
- package/dist/bridge/host-tool-mcp.mjs +1 -1
- package/dist/bridge/index.mjs +93 -11
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +15 -1
- package/dist/index.js +119 -23
- package/dist/index.js.map +1 -1
- package/package.json +6 -6
- package/src/acp-harness.ts +6 -0
- package/src/v1/acp-bootstrap.ts +12 -0
- package/src/v1/acp-v1-bridge-protocol.ts +14 -0
- package/src/v1/acp-v1-harness.ts +148 -31
- package/src/v1/acp-v1-settings.ts +9 -0
- package/src/v1/bridge/index.ts +44 -18
- package/src/v1/bridge/refresh-host-tool-catalog.ts +28 -0
- package/src/v1/bridge/stream-translator.ts +65 -0
- package/src/v1/implementation.ts +13 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,16 @@
|
|
|
1
1
|
# @ai-sdk/harness-acp
|
|
2
2
|
|
|
3
|
+
## 1.0.25
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- 79186d1: Allow pinned OpenCode and Grok Build install scripts during pnpm 11 sandbox bootstrap.
|
|
8
|
+
- b6396ff: feat(harness-acp): support `title` and `toolUseKind` for ACP tools
|
|
9
|
+
- 8a15038: feat(harness): add `credentialForwarding` setting to bridge backed harness adapters for granular control
|
|
10
|
+
- Updated dependencies [8a15038]
|
|
11
|
+
- @ai-sdk/harness@1.0.87
|
|
12
|
+
- @ai-sdk/provider-utils@5.0.30
|
|
13
|
+
|
|
3
14
|
## 1.0.24
|
|
4
15
|
|
|
5
16
|
### Patch Changes
|
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
ListToolsRequestSchema,
|
|
13
13
|
McpError
|
|
14
14
|
} from "@modelcontextprotocol/sdk/types.js";
|
|
15
|
-
var VERSION = true ? "1.0.
|
|
15
|
+
var VERSION = true ? "1.0.25" : "0.0.0-test";
|
|
16
16
|
function createHostToolMCPServer({
|
|
17
17
|
tools: tools2,
|
|
18
18
|
revision = 1,
|
package/dist/bridge/index.mjs
CHANGED
|
@@ -1116,6 +1116,11 @@ function createACPStreamTranslator({
|
|
|
1116
1116
|
const builtin = resolveBuiltinTool({
|
|
1117
1117
|
programmaticName,
|
|
1118
1118
|
metadata: state.values._meta,
|
|
1119
|
+
title: getStringProperty2({
|
|
1120
|
+
value: state.values,
|
|
1121
|
+
property: "title"
|
|
1122
|
+
}),
|
|
1123
|
+
kind: isACPToolKind(state.values.kind) ? state.values.kind : void 0,
|
|
1119
1124
|
rawInput: state.values.rawInput,
|
|
1120
1125
|
builtinTools,
|
|
1121
1126
|
builtinToolsByName
|
|
@@ -1323,6 +1328,8 @@ function addBuiltinToolMatch({
|
|
|
1323
1328
|
function resolveBuiltinTool({
|
|
1324
1329
|
programmaticName,
|
|
1325
1330
|
metadata,
|
|
1331
|
+
title,
|
|
1332
|
+
kind,
|
|
1326
1333
|
rawInput,
|
|
1327
1334
|
builtinTools,
|
|
1328
1335
|
builtinToolsByName
|
|
@@ -1337,11 +1344,49 @@ function resolveBuiltinTool({
|
|
|
1337
1344
|
if (metadataMatch.hasProgrammaticName) {
|
|
1338
1345
|
return metadataMatch.matches.length === 1 ? metadataMatch.matches[0] : void 0;
|
|
1339
1346
|
}
|
|
1347
|
+
const titleMatch = findBuiltinToolByTitle({
|
|
1348
|
+
title,
|
|
1349
|
+
kind,
|
|
1350
|
+
builtinTools
|
|
1351
|
+
});
|
|
1352
|
+
if (titleMatch != null) return titleMatch;
|
|
1340
1353
|
const schemaMatches = builtinTools.filter(
|
|
1341
1354
|
(tool) => matchesBuiltinToolInput({ rawInput, inputSchema: tool.inputSchema })
|
|
1342
1355
|
);
|
|
1343
1356
|
return schemaMatches.length === 1 ? schemaMatches[0] : void 0;
|
|
1344
1357
|
}
|
|
1358
|
+
function findBuiltinToolByTitle({
|
|
1359
|
+
title,
|
|
1360
|
+
kind,
|
|
1361
|
+
builtinTools
|
|
1362
|
+
}) {
|
|
1363
|
+
if (title == null) return void 0;
|
|
1364
|
+
const matches = builtinTools.filter(
|
|
1365
|
+
(tool) => tool.title != null && title.startsWith(tool.title) && isCompatibleToolKind({ toolUseKind: tool.toolUseKind, kind })
|
|
1366
|
+
);
|
|
1367
|
+
if (matches.length === 0) return void 0;
|
|
1368
|
+
const longestPrefixLength = Math.max(
|
|
1369
|
+
...matches.map((tool) => tool.title.length)
|
|
1370
|
+
);
|
|
1371
|
+
const longestMatches = matches.filter(
|
|
1372
|
+
(tool) => tool.title.length === longestPrefixLength
|
|
1373
|
+
);
|
|
1374
|
+
return longestMatches.length === 1 ? longestMatches[0] : void 0;
|
|
1375
|
+
}
|
|
1376
|
+
function isCompatibleToolKind({
|
|
1377
|
+
toolUseKind,
|
|
1378
|
+
kind
|
|
1379
|
+
}) {
|
|
1380
|
+
if (toolUseKind == null || kind == null) return true;
|
|
1381
|
+
switch (toolUseKind) {
|
|
1382
|
+
case "readonly":
|
|
1383
|
+
return kind === "read" || kind === "search" || kind === "fetch" || kind === "think";
|
|
1384
|
+
case "edit":
|
|
1385
|
+
return kind === "edit" || kind === "delete" || kind === "move";
|
|
1386
|
+
case "bash":
|
|
1387
|
+
return kind === "execute";
|
|
1388
|
+
}
|
|
1389
|
+
}
|
|
1345
1390
|
function findBuiltinToolsInMetadata({
|
|
1346
1391
|
metadata,
|
|
1347
1392
|
builtinToolsByName
|
|
@@ -2589,6 +2634,21 @@ var RelayRequestError = class extends Error {
|
|
|
2589
2634
|
};
|
|
2590
2635
|
|
|
2591
2636
|
// src/v1/bridge/refresh-host-tool-catalog.ts
|
|
2637
|
+
async function promptAndRefreshInitialHostToolCatalog({
|
|
2638
|
+
startPrompt,
|
|
2639
|
+
relay,
|
|
2640
|
+
tools,
|
|
2641
|
+
harnessId,
|
|
2642
|
+
timeoutMs
|
|
2643
|
+
}) {
|
|
2644
|
+
void startPrompt();
|
|
2645
|
+
await refreshHostToolCatalog({
|
|
2646
|
+
relay,
|
|
2647
|
+
tools,
|
|
2648
|
+
harnessId,
|
|
2649
|
+
timeoutMs
|
|
2650
|
+
});
|
|
2651
|
+
}
|
|
2592
2652
|
async function refreshHostToolCatalog({
|
|
2593
2653
|
relay,
|
|
2594
2654
|
tools,
|
|
@@ -3063,8 +3123,12 @@ await runBridge({
|
|
|
3063
3123
|
}
|
|
3064
3124
|
});
|
|
3065
3125
|
async function runTurn(start, turn) {
|
|
3126
|
+
let initialHostToolCatalogRefreshRequired;
|
|
3066
3127
|
try {
|
|
3067
|
-
await ensureSession({
|
|
3128
|
+
({ initialHostToolCatalogRefreshRequired } = await ensureSession({
|
|
3129
|
+
start,
|
|
3130
|
+
turn
|
|
3131
|
+
}));
|
|
3068
3132
|
} catch (error) {
|
|
3069
3133
|
if (HarnessBridgeCapabilityUnsupportedError.isInstance(error)) throw error;
|
|
3070
3134
|
throw createACPBridgeError({
|
|
@@ -3082,6 +3146,10 @@ async function runTurn(start, turn) {
|
|
|
3082
3146
|
"ACP session initialization did not start stderr monitoring."
|
|
3083
3147
|
);
|
|
3084
3148
|
}
|
|
3149
|
+
const activeHostToolRelay = hostToolRelay;
|
|
3150
|
+
if (activeHostToolRelay == null) {
|
|
3151
|
+
throw new Error("The host tool MCP relay is unavailable.");
|
|
3152
|
+
}
|
|
3085
3153
|
if (start.recoveryMode?.type === "lossy-rerun") {
|
|
3086
3154
|
const marker = {
|
|
3087
3155
|
type: "acp-recovery",
|
|
@@ -3189,15 +3257,34 @@ async function runTurn(start, turn) {
|
|
|
3189
3257
|
registerCorrelationInvocation: emitStreamEvent.registerHostToolCorrelationInvocation,
|
|
3190
3258
|
removeCorrelationInvocation: emitStreamEvent.removeHostToolCorrelationInvocation
|
|
3191
3259
|
};
|
|
3192
|
-
|
|
3260
|
+
activeHostToolRelay.bindTurn({ turn: relayTurn });
|
|
3193
3261
|
try {
|
|
3194
3262
|
const promptMeta = createOutputSchemaPromptMeta({ start });
|
|
3195
|
-
|
|
3263
|
+
const startPrompt = () => promptActiveSession({
|
|
3196
3264
|
session: activeSession,
|
|
3197
3265
|
agent: connection.agent,
|
|
3198
3266
|
prompt: start.prompt,
|
|
3199
3267
|
meta: promptMeta
|
|
3200
3268
|
});
|
|
3269
|
+
if (initialHostToolCatalogRefreshRequired) {
|
|
3270
|
+
try {
|
|
3271
|
+
await promptAndRefreshInitialHostToolCatalog({
|
|
3272
|
+
startPrompt,
|
|
3273
|
+
relay: activeHostToolRelay,
|
|
3274
|
+
tools: start.tools ?? [],
|
|
3275
|
+
harnessId: bridgeType,
|
|
3276
|
+
timeoutMs: CATALOG_REFRESH_TIMEOUT_MS
|
|
3277
|
+
});
|
|
3278
|
+
} catch (error) {
|
|
3279
|
+
if (HarnessBridgeCapabilityUnsupportedError.isInstance(error)) {
|
|
3280
|
+
catalogRefreshError = error;
|
|
3281
|
+
}
|
|
3282
|
+
sessionConfigurationFailure = { error };
|
|
3283
|
+
throw error;
|
|
3284
|
+
}
|
|
3285
|
+
} else {
|
|
3286
|
+
void startPrompt();
|
|
3287
|
+
}
|
|
3201
3288
|
if (turn.abortSignal.aborted) {
|
|
3202
3289
|
await cancel();
|
|
3203
3290
|
} else {
|
|
@@ -3245,7 +3332,7 @@ async function runTurn(start, turn) {
|
|
|
3245
3332
|
} finally {
|
|
3246
3333
|
permissionController.cancelAll();
|
|
3247
3334
|
activePermissionController = void 0;
|
|
3248
|
-
|
|
3335
|
+
activeHostToolRelay.unbindTurn({ turn: relayTurn });
|
|
3249
3336
|
}
|
|
3250
3337
|
}
|
|
3251
3338
|
async function ensureSession({
|
|
@@ -3289,7 +3376,7 @@ async function ensureSession({
|
|
|
3289
3376
|
}
|
|
3290
3377
|
throw error;
|
|
3291
3378
|
}
|
|
3292
|
-
return;
|
|
3379
|
+
return { initialHostToolCatalogRefreshRequired: false };
|
|
3293
3380
|
}
|
|
3294
3381
|
const clientApp = resolveClientApp();
|
|
3295
3382
|
const authentication = bridgeConfiguration.authentication;
|
|
@@ -3452,12 +3539,6 @@ async function ensureSession({
|
|
|
3452
3539
|
}).start();
|
|
3453
3540
|
}
|
|
3454
3541
|
try {
|
|
3455
|
-
await refreshHostToolCatalog({
|
|
3456
|
-
relay: hostToolRelay,
|
|
3457
|
-
tools,
|
|
3458
|
-
harnessId: bridgeType,
|
|
3459
|
-
timeoutMs: CATALOG_REFRESH_TIMEOUT_MS
|
|
3460
|
-
});
|
|
3461
3542
|
if (start.permissionModeMapping != null) {
|
|
3462
3543
|
await configureACPPermissionMode({
|
|
3463
3544
|
agent: connection.agent,
|
|
@@ -3482,6 +3563,7 @@ async function ensureSession({
|
|
|
3482
3563
|
sessionId: createdSession.sessionId
|
|
3483
3564
|
});
|
|
3484
3565
|
sessionConfigurationFingerprint = fingerprint;
|
|
3566
|
+
return { initialHostToolCatalogRefreshRequired: tools.length > 0 };
|
|
3485
3567
|
}
|
|
3486
3568
|
function createExternalMcpServers({
|
|
3487
3569
|
mcpServers,
|