@ai-sdk/harness-acp 1.0.24 → 1.0.28

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { HarnessV1RequestTransformation, HarnessV1PermissionMode, HarnessV1PortEndpoint, HarnessV1 } from '@ai-sdk/harness';
1
+ import { HarnessV1RequestTransformation, HarnessV1CredentialForwarding, HarnessV1PermissionMode, HarnessV1PortEndpoint, HarnessV1 } from '@ai-sdk/harness';
2
2
  import { ToolSet } from '@ai-sdk/provider-utils';
3
3
 
4
4
  type ACPMetadata = Record<string, unknown>;
@@ -126,6 +126,8 @@ type ACPNpmLockedSource = {
126
126
  readonly type: 'npm-locked';
127
127
  readonly packageJson: string;
128
128
  readonly pnpmLockYaml: string;
129
+ /** Optional pnpm workspace configuration required by the locked install. */
130
+ readonly pnpmWorkspaceYaml?: string;
129
131
  };
130
132
  type ACPInstallCommandSource = {
131
133
  readonly type: 'install-command';
@@ -143,8 +145,9 @@ type ACPProviderAuthentication = {
143
145
  readonly env: Readonly<Record<string, ACPProfileValue>>;
144
146
  };
145
147
  };
146
- type ACPCredentialBrokering = ({ env, }: {
148
+ type ACPCredentialBrokering = ({ env, sandboxEnv, }: {
147
149
  env: Readonly<Record<string, string>>;
150
+ sandboxEnv?: Readonly<Record<string, string>>;
148
151
  }) => ReadonlyArray<HarnessV1RequestTransformation>;
149
152
  type ACPPermissionModeTarget = {
150
153
  readonly type: 'session-mode';
@@ -184,6 +187,12 @@ type ACPV1Settings = {
184
187
  readonly forwardEnv?: ReadonlyArray<string>;
185
188
  readonly credentialEnv?: ReadonlyArray<string>;
186
189
  readonly credentialBrokering?: ACPCredentialBrokering;
190
+ /**
191
+ * Customizes each credential value before it is forwarded into a sandbox
192
+ * process. This does not restrict which credentials the harness adapter can
193
+ * discover, read, or otherwise access in the host process.
194
+ */
195
+ readonly credentialForwarding?: HarnessV1CredentialForwarding;
187
196
  /**
188
197
  * Runtime environment values that are safe to persist in bootstrap and
189
198
  * lifecycle compatibility identity.
@@ -244,6 +253,12 @@ type ACPHarnessSettings<TBuiltinTools extends ToolSet = {}> = {
244
253
  readonly forwardEnv?: ACPV1Settings['forwardEnv'];
245
254
  readonly credentialEnv?: ACPV1Settings['credentialEnv'];
246
255
  readonly credentialBrokering?: ACPV1Settings['credentialBrokering'];
256
+ /**
257
+ * Customizes each credential value before it is forwarded into a sandbox
258
+ * process. This does not restrict which credentials the harness adapter can
259
+ * discover, read, or otherwise access in the host process.
260
+ */
261
+ readonly credentialForwarding?: ACPV1Settings['credentialForwarding'];
247
262
  readonly env?: ACPV1Settings['env'];
248
263
  readonly authentication?: ACPV1Settings['authentication'];
249
264
  readonly providerAuthentication?: ACPV1Settings['providerAuthentication'];
package/dist/index.js CHANGED
@@ -10,14 +10,15 @@ import {
10
10
  } from "@ai-sdk/harness";
11
11
  import { HarnessBridgeCapabilityUnsupportedError } from "@ai-sdk/harness/bridge";
12
12
  import {
13
+ applyCredentialForwarding,
13
14
  createBridgeErrorHandler,
14
15
  createBridgeStartupError,
16
+ createSandboxCredentialEnvironment,
15
17
  classifyDiskLog,
16
18
  drainBridgeProcessStream,
17
19
  forwardBridgeProcessStream,
18
20
  getRestrictedSandboxSession,
19
21
  markBridgeStarting,
20
- maskSandboxCredentials,
21
22
  resolveSandboxDefaultWorkingDirectory,
22
23
  resolveSandboxHomeDir,
23
24
  SandboxChannel,
@@ -201,6 +202,9 @@ function validateACPV1Implementation(implementation) {
201
202
  if (source.pnpmLockYaml.length === 0) {
202
203
  throw new Error("ACP source.pnpmLockYaml must not be empty.");
203
204
  }
205
+ if (source.pnpmWorkspaceYaml?.length === 0) {
206
+ throw new Error("ACP source.pnpmWorkspaceYaml must not be empty.");
207
+ }
204
208
  } else if (source.type === "npm-simple") {
205
209
  validateNpmSimpleSource({ source });
206
210
  } else if (source.command.trim().length === 0) {
@@ -264,6 +268,12 @@ function getImplementationLockfile({
264
268
  const { source } = implementation;
265
269
  return source.type === "npm-locked" ? source.pnpmLockYaml : void 0;
266
270
  }
271
+ function getImplementationWorkspaceFile({
272
+ implementation
273
+ }) {
274
+ const { source } = implementation;
275
+ return source.type === "npm-locked" ? source.pnpmWorkspaceYaml : void 0;
276
+ }
267
277
  function createImplementationDescriptor({
268
278
  implementation
269
279
  }) {
@@ -290,7 +300,8 @@ function createImplementationIdentity({
290
300
  const sourceIdentity = source.type === "npm-locked" ? {
291
301
  type: source.type,
292
302
  packageJson: source.packageJson,
293
- pnpmLockYaml: source.pnpmLockYaml
303
+ pnpmLockYaml: source.pnpmLockYaml,
304
+ pnpmWorkspaceYaml: source.pnpmWorkspaceYaml
294
305
  } : source.type === "npm-simple" ? {
295
306
  type: source.type,
296
307
  packageName: source.packageName,
@@ -462,6 +473,9 @@ function createACPBootstrap({
462
473
  const implementationLock = getImplementationLockfile({
463
474
  implementation
464
475
  });
476
+ const implementationWorkspace = getImplementationWorkspaceFile({
477
+ implementation
478
+ });
465
479
  const implementationInstallScript = getImplementationInstallScript({
466
480
  implementation
467
481
  });
@@ -498,6 +512,12 @@ function createACPBootstrap({
498
512
  content: implementationLock
499
513
  }
500
514
  ],
515
+ ...implementationWorkspace == null ? [] : [
516
+ {
517
+ path: `${bootstrapDir}/implementation/pnpm-workspace.yaml`,
518
+ content: implementationWorkspace
519
+ }
520
+ ],
501
521
  ...implementationInstallScript == null ? [] : [
502
522
  {
503
523
  path: `${bootstrapDir}/implementation/install.sh`,
@@ -658,6 +678,8 @@ function unsupportedPromptContent({
658
678
  var builtinToolSchema = z2.object({
659
679
  toolName: z2.string(),
660
680
  nativeName: z2.string().optional(),
681
+ title: z2.string().optional(),
682
+ toolUseKind: z2.enum(["readonly", "edit", "bash"]).optional(),
661
683
  inputSchema: z2.json().optional()
662
684
  });
663
685
  var jsonValueSchema = z2.json();
@@ -1296,6 +1318,21 @@ function createACPV1({
1296
1318
  sandboxSession,
1297
1319
  abortSignal: startOptions.abortSignal
1298
1320
  });
1321
+ const continueFrom = startOptions.continueFrom ?? startOptions.resumeFrom?.continueFrom;
1322
+ const lifecycleState = continueFrom ?? startOptions.resumeFrom;
1323
+ const isContinue = continueFrom != null;
1324
+ const isResume = lifecycleState != null;
1325
+ const lifecycleData = lifecycleState != null ? lifecycleState.data : void 0;
1326
+ if (lifecycleData != null && lifecycleState != null) {
1327
+ validateACPLifecycleCompatibility({
1328
+ harnessId: settings.harnessId,
1329
+ lifecycleHarnessId: lifecycleState.harnessId,
1330
+ implementationIdentity,
1331
+ authenticationProfile,
1332
+ lifecycleData,
1333
+ sandboxId
1334
+ });
1335
+ }
1299
1336
  const implementationEnvironment = resolveImplementationEnvironment({
1300
1337
  implementation,
1301
1338
  env
@@ -1303,48 +1340,69 @@ function createACPV1({
1303
1340
  let sandboxImplementationEnvironment = implementationEnvironment;
1304
1341
  let sandboxProviderAuthenticationEnvironment = resolvedProviderAuthentication.env;
1305
1342
  let sandboxProviderEnvironment;
1343
+ const credentialEnvironmentVariables = [
1344
+ .../* @__PURE__ */ new Set([
1345
+ ...settings.credentialEnv ?? [],
1346
+ "AI_GATEWAY_API_KEY",
1347
+ "VERCEL_OIDC_TOKEN"
1348
+ ])
1349
+ ];
1350
+ const credentialForwardingEnvironmentVariables = [
1351
+ .../* @__PURE__ */ new Set([
1352
+ ...credentialEnvironmentVariables,
1353
+ ...resolveACPProviderCredentialEnvironmentVariables({
1354
+ providerAuthentication: resolvedProviderAuthentication.providerAuthentication
1355
+ })
1356
+ ])
1357
+ ];
1358
+ let sandboxCredentialEnvironment;
1306
1359
  if (settings.credentialBrokering != null && "addRequestTransformations" in sandboxSession && sandboxSession.addRequestTransformations != null) {
1307
1360
  const providerEnvironment = resolveProviderEnvironment({
1308
1361
  resolvedProviderAuthentication,
1309
1362
  clientApp
1310
1363
  });
1311
- const credentialEnvironmentVariables = [
1312
- .../* @__PURE__ */ new Set([
1313
- ...settings.credentialEnv ?? [],
1314
- "AI_GATEWAY_API_KEY",
1315
- "VERCEL_OIDC_TOKEN"
1316
- ])
1317
- ];
1364
+ const brokeringEnvironment = {
1365
+ ...implementationEnvironment,
1366
+ ...providerEnvironment
1367
+ };
1368
+ sandboxCredentialEnvironment = lifecycleData?.sandboxCredentialEnvironment ?? await createSandboxCredentialEnvironment({
1369
+ environment: brokeringEnvironment,
1370
+ credentialEnvironmentVariables: credentialForwardingEnvironmentVariables,
1371
+ credentialForwarding: settings.credentialForwarding
1372
+ });
1373
+ sandboxImplementationEnvironment = {
1374
+ ...brokeringEnvironment,
1375
+ ...sandboxCredentialEnvironment
1376
+ };
1318
1377
  const requestTransformations = settings.credentialBrokering({
1319
- env: {
1320
- ...implementationEnvironment,
1321
- ...providerEnvironment
1322
- }
1378
+ env: brokeringEnvironment,
1379
+ sandboxEnv: sandboxImplementationEnvironment
1323
1380
  });
1324
1381
  if (requestTransformations.length > 0) {
1325
1382
  await sandboxSession.addRequestTransformations(
1326
1383
  requestTransformations
1327
1384
  );
1328
1385
  }
1329
- sandboxImplementationEnvironment = maskSandboxCredentials({
1330
- environment: implementationEnvironment,
1331
- credentialEnvironmentVariables
1332
- });
1333
- sandboxProviderEnvironment = maskSandboxCredentials({
1334
- environment: resolveProviderEnvironment({
1335
- resolvedProviderAuthentication,
1336
- clientApp,
1337
- gatewayApiKey: "AI_GATEWAY_API_KEY"
1338
- }),
1339
- credentialEnvironmentVariables
1386
+ sandboxProviderEnvironment = resolvedProviderAuthentication.providerAuthentication?.type === "ai-gateway" ? {} : void 0;
1387
+ } else if (settings.credentialBrokering != null) {
1388
+ warnCredentialBrokeringUnavailable();
1389
+ }
1390
+ if (settings.credentialForwarding != null && sandboxProviderEnvironment == null && resolvedProviderAuthentication.providerAuthentication?.type === "ai-gateway") {
1391
+ sandboxProviderEnvironment = resolveProviderEnvironment({
1392
+ resolvedProviderAuthentication,
1393
+ clientApp
1340
1394
  });
1395
+ }
1396
+ if (sandboxProviderEnvironment != null) {
1397
+ sandboxImplementationEnvironment = {
1398
+ ...sandboxImplementationEnvironment,
1399
+ ...sandboxProviderEnvironment
1400
+ };
1341
1401
  sandboxProviderAuthenticationEnvironment = Object.fromEntries(
1342
1402
  Object.entries(resolvedProviderAuthentication.env).filter(
1343
1403
  ([key]) => key !== "AI_SDK_ACP_GATEWAY_API_KEY" && key !== "AI_SDK_ACP_GATEWAY_BASE_URL"
1344
1404
  )
1345
1405
  );
1346
- } else if (settings.credentialBrokering != null) {
1347
- warnCredentialBrokeringUnavailable();
1348
1406
  }
1349
1407
  const resolvedBridgeDir = posix.resolve(
1350
1408
  defaultWorkingDirectory,
@@ -1363,21 +1421,6 @@ function createACPV1({
1363
1421
  sessionId: startOptions.sessionId
1364
1422
  });
1365
1423
  const bridgeStateDir = `${privateSessionDir}/bridge`;
1366
- const continueFrom = startOptions.continueFrom ?? startOptions.resumeFrom?.continueFrom;
1367
- const lifecycleState = continueFrom ?? startOptions.resumeFrom;
1368
- const isContinue = continueFrom != null;
1369
- const isResume = lifecycleState != null;
1370
- const lifecycleData = lifecycleState != null ? lifecycleState.data : void 0;
1371
- if (lifecycleData != null && lifecycleState != null) {
1372
- validateACPLifecycleCompatibility({
1373
- harnessId: settings.harnessId,
1374
- lifecycleHarnessId: lifecycleState.harnessId,
1375
- implementationIdentity,
1376
- authenticationProfile,
1377
- lifecycleData,
1378
- sandboxId
1379
- });
1380
- }
1381
1424
  const skills = startOptions.skills ?? [];
1382
1425
  const skillsFingerprint = createACPSkillsFingerprint({ skills });
1383
1426
  const shouldMaterializeSkills = shouldMaterializeACPSkills({
@@ -1475,6 +1518,7 @@ function createACPV1({
1475
1518
  turnStartConfig: lifecycleData.turnStartConfig,
1476
1519
  recoveryStatus: lifecycleData.recovery,
1477
1520
  restoration: lifecycleData.restoration,
1521
+ sandboxCredentialEnvironment,
1478
1522
  replayOnly: false,
1479
1523
  lossyRerun: false
1480
1524
  });
@@ -1552,6 +1596,11 @@ function createACPV1({
1552
1596
  };
1553
1597
  }
1554
1598
  }
1599
+ const forwardedImplementationEnvironment = sandboxCredentialEnvironment == null ? await applyCredentialForwarding({
1600
+ environment: sandboxImplementationEnvironment,
1601
+ credentialEnvironmentVariables: credentialForwardingEnvironmentVariables,
1602
+ credentialForwarding: settings.credentialForwarding
1603
+ }) : sandboxImplementationEnvironment;
1555
1604
  const port = resolveBridgePort({
1556
1605
  sandboxSession,
1557
1606
  override: portOverride,
@@ -1571,11 +1620,11 @@ function createACPV1({
1571
1620
  const proc = await toolSafeSandboxSession.spawn({
1572
1621
  command: `node ${shellQuote(`${resolvedBridgeDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --implementation-dir ${shellQuote(resolvedImplementationDir)} --bridge-type ${shellQuote(settings.harnessId)}`,
1573
1622
  env: {
1574
- ...sandboxImplementationEnvironment,
1623
+ ...forwardedImplementationEnvironment,
1575
1624
  ...createACPBridgeEnvironment({
1576
1625
  authentication: settings.authentication,
1577
1626
  providerAuthentication: resolvedProviderAuthentication.providerAuthentication,
1578
- providerEnvironment: sandboxProviderEnvironment,
1627
+ providerEnvironment: sandboxProviderEnvironment == null ? void 0 : {},
1579
1628
  sessionMeta: settings.session?.meta
1580
1629
  }),
1581
1630
  ...sandboxProviderAuthenticationEnvironment,
@@ -1710,6 +1759,7 @@ function createACPV1({
1710
1759
  reason: respawnStrategy.reason
1711
1760
  } : void 0,
1712
1761
  restoration: coldRestoration == null ? lifecycleData?.restoration : { method: coldRestoration },
1762
+ sandboxCredentialEnvironment,
1713
1763
  replayOnly: respawnStrategy?.mode === "disk-replay",
1714
1764
  lossyRerun: respawnStrategy?.mode === "lossy-rerun"
1715
1765
  });
@@ -1718,8 +1768,7 @@ function createACPV1({
1718
1768
  }
1719
1769
  function resolveProviderEnvironment({
1720
1770
  resolvedProviderAuthentication,
1721
- clientApp,
1722
- gatewayApiKey
1771
+ clientApp
1723
1772
  }) {
1724
1773
  if (resolvedProviderAuthentication.providerAuthentication?.type !== "ai-gateway") {
1725
1774
  return {};
@@ -1727,7 +1776,7 @@ function resolveProviderEnvironment({
1727
1776
  return resolveACPLaunchEnvironment({
1728
1777
  providerAuthentication: resolvedProviderAuthentication.providerAuthentication,
1729
1778
  gateway: {
1730
- apiKey: gatewayApiKey ?? requireResolvedEnvironmentValue({
1779
+ apiKey: requireResolvedEnvironmentValue({
1731
1780
  environment: resolvedProviderAuthentication.env,
1732
1781
  name: "AI_SDK_ACP_GATEWAY_API_KEY"
1733
1782
  }),
@@ -1740,6 +1789,26 @@ function resolveProviderEnvironment({
1740
1789
  }
1741
1790
  });
1742
1791
  }
1792
+ function resolveACPProviderCredentialEnvironmentVariables({
1793
+ providerAuthentication
1794
+ }) {
1795
+ if (providerAuthentication?.type !== "ai-gateway") return [];
1796
+ return Object.entries(providerAuthentication.env).filter(([, value]) => containsACPProviderCredential({ value })).map(([name]) => name);
1797
+ }
1798
+ function containsACPProviderCredential({
1799
+ value
1800
+ }) {
1801
+ if (Array.isArray(value)) {
1802
+ return value.some((item) => containsACPProviderCredential({ value: item }));
1803
+ }
1804
+ if (value == null || typeof value !== "object") return false;
1805
+ if ("$source" in value) {
1806
+ return value.$source === "gateway-api-key" || value.$source === "gateway-authorization";
1807
+ }
1808
+ return Object.values(value).some(
1809
+ (item) => containsACPProviderCredential({ value: item })
1810
+ );
1811
+ }
1743
1812
  function requireResolvedEnvironmentValue({
1744
1813
  environment,
1745
1814
  name
@@ -1926,6 +1995,7 @@ function createSession({
1926
1995
  turnStartConfig: turnStartConfigAtStart,
1927
1996
  recoveryStatus,
1928
1997
  restoration,
1998
+ sandboxCredentialEnvironment,
1929
1999
  replayOnly,
1930
2000
  lossyRerun
1931
2001
  }) {
@@ -2161,6 +2231,7 @@ function createSession({
2161
2231
  }) => ({
2162
2232
  implementationIdentity,
2163
2233
  authenticationProfile,
2234
+ ...sandboxCredentialEnvironment == null ? {} : { sandboxCredentialEnvironment },
2164
2235
  ...latestACPSessionId == null ? {} : { acpSessionId: latestACPSessionId },
2165
2236
  ...bridge == null ? {} : { bridge },
2166
2237
  ...latestTurnStartConfig == null ? {} : {
@@ -2418,6 +2489,8 @@ function serializeBuiltinTools({
2418
2489
  }) {
2419
2490
  return Object.entries(builtinTools).map(([toolName, tool]) => {
2420
2491
  const nativeName = tool != null && typeof tool === "object" && "nativeName" in tool && typeof tool.nativeName === "string" ? tool.nativeName : void 0;
2492
+ const title = tool != null && typeof tool === "object" && "title" in tool && typeof tool.title === "string" ? tool.title : void 0;
2493
+ const toolUseKind = tool != null && typeof tool === "object" && "toolUseKind" in tool && (tool.toolUseKind === "readonly" || tool.toolUseKind === "edit" || tool.toolUseKind === "bash") ? tool.toolUseKind : void 0;
2421
2494
  let inputSchema;
2422
2495
  if (tool != null && typeof tool === "object" && "inputSchema" in tool && tool.inputSchema != null) {
2423
2496
  try {
@@ -2430,6 +2503,8 @@ function serializeBuiltinTools({
2430
2503
  return {
2431
2504
  toolName,
2432
2505
  ...nativeName == null ? {} : { nativeName },
2506
+ ...title == null ? {} : { title },
2507
+ ...toolUseKind == null ? {} : { toolUseKind },
2433
2508
  ...inputSchema == null ? {} : { inputSchema }
2434
2509
  };
2435
2510
  });
@@ -2536,7 +2611,7 @@ function deserializeBridgeError({
2536
2611
  }
2537
2612
 
2538
2613
  // src/version.ts
2539
- var VERSION = true ? "1.0.24" : "0.0.0-test";
2614
+ var VERSION = true ? "1.0.28" : "0.0.0-test";
2540
2615
 
2541
2616
  // src/acp-harness.ts
2542
2617
  var ACP_CLIENT_APP = {
@@ -2562,6 +2637,7 @@ var acpResumeStateSchema = z4.object({
2562
2637
  providerMode: z4.enum(["auto", "direct", "ai-gateway"]).optional(),
2563
2638
  gatewayCredentialSource: z4.enum(["AI_GATEWAY_API_KEY", "VERCEL_OIDC_TOKEN"]).nullable().optional()
2564
2639
  }).optional(),
2640
+ sandboxCredentialEnvironment: z4.record(z4.string(), z4.string()).optional(),
2565
2641
  acpSessionId: z4.string().optional(),
2566
2642
  bridge: acpBridgeCoordsSchema.optional(),
2567
2643
  coldSession: acpColdSessionStateSchema.optional(),