@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 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.24" : "0.0.0-test";
15
+ var VERSION = true ? "1.0.25" : "0.0.0-test";
16
16
  function createHostToolMCPServer({
17
17
  tools: tools2,
18
18
  revision = 1,
@@ -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({ start, turn });
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
- hostToolRelay?.bindTurn({ turn: relayTurn });
3260
+ activeHostToolRelay.bindTurn({ turn: relayTurn });
3193
3261
  try {
3194
3262
  const promptMeta = createOutputSchemaPromptMeta({ start });
3195
- void promptActiveSession({
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
- hostToolRelay?.unbindTurn({ turn: relayTurn });
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,