@ai-sdk/harness-acp 1.0.25 → 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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-sdk/harness-acp",
3
- "version": "1.0.25",
3
+ "version": "1.0.28",
4
4
  "type": "module",
5
5
  "license": "Apache-2.0",
6
6
  "sideEffects": false,
@@ -26,8 +26,8 @@
26
26
  }
27
27
  },
28
28
  "dependencies": {
29
- "@ai-sdk/harness": "1.0.87",
30
- "@ai-sdk/provider-utils": "5.0.30",
29
+ "@ai-sdk/harness": "1.0.90",
30
+ "@ai-sdk/provider-utils": "5.0.32",
31
31
  "ws": "^8.21.0"
32
32
  },
33
33
  "peerDependencies": {
@@ -85,6 +85,7 @@ const acpResumeStateSchema = z.object({
85
85
  .optional(),
86
86
  })
87
87
  .optional(),
88
+ sandboxCredentialEnvironment: z.record(z.string(), z.string()).optional(),
88
89
  acpSessionId: z.string().optional(),
89
90
  bridge: acpBridgeCoordsSchema.optional(),
90
91
  coldSession: acpColdSessionStateSchema.optional(),
@@ -17,12 +17,12 @@ import {
17
17
  applyCredentialForwarding,
18
18
  createBridgeErrorHandler,
19
19
  createBridgeStartupError,
20
+ createSandboxCredentialEnvironment,
20
21
  classifyDiskLog,
21
22
  drainBridgeProcessStream,
22
23
  forwardBridgeProcessStream,
23
24
  getRestrictedSandboxSession,
24
25
  markBridgeStarting,
25
- maskSandboxCredentials,
26
26
  resolveSandboxDefaultWorkingDirectory,
27
27
  resolveSandboxHomeDir,
28
28
  SandboxChannel,
@@ -237,6 +237,25 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
237
237
  sandboxSession,
238
238
  abortSignal: startOptions.abortSignal,
239
239
  });
240
+ const continueFrom =
241
+ startOptions.continueFrom ?? startOptions.resumeFrom?.continueFrom;
242
+ const lifecycleState = continueFrom ?? startOptions.resumeFrom;
243
+ const isContinue = continueFrom != null;
244
+ const isResume = lifecycleState != null;
245
+ const lifecycleData =
246
+ lifecycleState != null
247
+ ? (lifecycleState.data as unknown as ACPLifecycleData)
248
+ : undefined;
249
+ if (lifecycleData != null && lifecycleState != null) {
250
+ validateACPLifecycleCompatibility({
251
+ harnessId: settings.harnessId,
252
+ lifecycleHarnessId: lifecycleState.harnessId,
253
+ implementationIdentity,
254
+ authenticationProfile,
255
+ lifecycleData,
256
+ sandboxId,
257
+ });
258
+ }
240
259
  const implementationEnvironment = resolveImplementationEnvironment({
241
260
  implementation,
242
261
  env,
@@ -261,6 +280,9 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
261
280
  }),
262
281
  ]),
263
282
  ];
283
+ let sandboxCredentialEnvironment:
284
+ | Readonly<Record<string, string>>
285
+ | undefined;
264
286
 
265
287
  if (
266
288
  settings.credentialBrokering != null &&
@@ -271,31 +293,36 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
271
293
  resolvedProviderAuthentication,
272
294
  clientApp,
273
295
  });
296
+ const brokeringEnvironment = {
297
+ ...implementationEnvironment,
298
+ ...providerEnvironment,
299
+ };
300
+ sandboxCredentialEnvironment =
301
+ lifecycleData?.sandboxCredentialEnvironment ??
302
+ (await createSandboxCredentialEnvironment({
303
+ environment: brokeringEnvironment,
304
+ credentialEnvironmentVariables:
305
+ credentialForwardingEnvironmentVariables,
306
+ credentialForwarding: settings.credentialForwarding,
307
+ }));
308
+ sandboxImplementationEnvironment = {
309
+ ...brokeringEnvironment,
310
+ ...sandboxCredentialEnvironment,
311
+ };
274
312
  const requestTransformations = settings.credentialBrokering({
275
- env: {
276
- ...implementationEnvironment,
277
- ...providerEnvironment,
278
- },
313
+ env: brokeringEnvironment,
314
+ sandboxEnv: sandboxImplementationEnvironment,
279
315
  });
280
316
  if (requestTransformations.length > 0) {
281
317
  await sandboxSession.addRequestTransformations(
282
318
  requestTransformations,
283
319
  );
284
320
  }
285
- sandboxImplementationEnvironment = maskSandboxCredentials({
286
- environment: implementationEnvironment,
287
- credentialEnvironmentVariables,
288
- });
289
-
290
- /*
291
- * Each profile environment variable is resolved with its own name as
292
- * the fake Gateway credential. This preserves profile transformations
293
- * without exposing the real credential to the sandbox process.
294
- */
295
- sandboxProviderEnvironment = resolveBrokeredProviderEnvironment({
296
- resolvedProviderAuthentication,
297
- clientApp,
298
- });
321
+ sandboxProviderEnvironment =
322
+ resolvedProviderAuthentication.providerAuthentication?.type ===
323
+ 'ai-gateway'
324
+ ? {}
325
+ : undefined;
299
326
  } else if (settings.credentialBrokering != null) {
300
327
  warnCredentialBrokeringUnavailable();
301
328
  }
@@ -340,25 +367,6 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
340
367
  sessionId: startOptions.sessionId,
341
368
  });
342
369
  const bridgeStateDir = `${privateSessionDir}/bridge`;
343
- const continueFrom =
344
- startOptions.continueFrom ?? startOptions.resumeFrom?.continueFrom;
345
- const lifecycleState = continueFrom ?? startOptions.resumeFrom;
346
- const isContinue = continueFrom != null;
347
- const isResume = lifecycleState != null;
348
- const lifecycleData =
349
- lifecycleState != null
350
- ? (lifecycleState.data as unknown as ACPLifecycleData)
351
- : undefined;
352
- if (lifecycleData != null && lifecycleState != null) {
353
- validateACPLifecycleCompatibility({
354
- harnessId: settings.harnessId,
355
- lifecycleHarnessId: lifecycleState.harnessId,
356
- implementationIdentity,
357
- authenticationProfile,
358
- lifecycleData,
359
- sandboxId,
360
- });
361
- }
362
370
  const skills = startOptions.skills ?? [];
363
371
  const skillsFingerprint = createACPSkillsFingerprint({ skills });
364
372
  const shouldMaterializeSkills = shouldMaterializeACPSkills({
@@ -463,6 +471,7 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
463
471
  turnStartConfig: lifecycleData.turnStartConfig,
464
472
  recoveryStatus: lifecycleData.recovery,
465
473
  restoration: lifecycleData.restoration,
474
+ sandboxCredentialEnvironment,
466
475
  replayOnly: false,
467
476
  lossyRerun: false,
468
477
  });
@@ -544,12 +553,14 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
544
553
  }
545
554
 
546
555
  const forwardedImplementationEnvironment =
547
- await applyCredentialForwarding({
548
- environment: sandboxImplementationEnvironment,
549
- credentialEnvironmentVariables:
550
- credentialForwardingEnvironmentVariables,
551
- credentialForwarding: settings.credentialForwarding,
552
- });
556
+ sandboxCredentialEnvironment == null
557
+ ? await applyCredentialForwarding({
558
+ environment: sandboxImplementationEnvironment,
559
+ credentialEnvironmentVariables:
560
+ credentialForwardingEnvironmentVariables,
561
+ credentialForwarding: settings.credentialForwarding,
562
+ })
563
+ : sandboxImplementationEnvironment;
553
564
  const port = resolveBridgePort({
554
565
  sandboxSession,
555
566
  override: portOverride,
@@ -742,6 +753,7 @@ export function createACPV1<TBuiltinTools extends ToolSet = {}>({
742
753
  coldRestoration == null
743
754
  ? lifecycleData?.restoration
744
755
  : { method: coldRestoration },
756
+ sandboxCredentialEnvironment,
745
757
  replayOnly: respawnStrategy?.mode === 'disk-replay',
746
758
  lossyRerun: respawnStrategy?.mode === 'lossy-rerun',
747
759
  });
@@ -781,45 +793,6 @@ function resolveProviderEnvironment({
781
793
  });
782
794
  }
783
795
 
784
- function resolveBrokeredProviderEnvironment({
785
- resolvedProviderAuthentication,
786
- clientApp,
787
- }: {
788
- resolvedProviderAuthentication: ReturnType<
789
- typeof resolveACPProviderAuthentication
790
- >;
791
- clientApp: ACPClientApp;
792
- }): Record<string, string> {
793
- const providerAuthentication =
794
- resolvedProviderAuthentication.providerAuthentication;
795
- if (providerAuthentication?.type !== 'ai-gateway') return {};
796
-
797
- const baseUrl = requireResolvedEnvironmentValue({
798
- environment: resolvedProviderAuthentication.env,
799
- name: 'AI_SDK_ACP_GATEWAY_BASE_URL',
800
- });
801
-
802
- return Object.fromEntries(
803
- Object.entries(providerAuthentication.env).map(
804
- ([environmentVariableName, value]) => {
805
- const environment = resolveACPLaunchEnvironment({
806
- providerAuthentication: {
807
- type: 'ai-gateway',
808
- env: { [environmentVariableName]: value },
809
- },
810
- gateway: {
811
- apiKey: environmentVariableName,
812
- baseUrl,
813
- clientAppName: clientApp.name,
814
- clientAppVersion: clientApp.version,
815
- },
816
- });
817
- return [environmentVariableName, environment[environmentVariableName]!];
818
- },
819
- ),
820
- );
821
- }
822
-
823
796
  function resolveACPProviderCredentialEnvironmentVariables({
824
797
  providerAuthentication,
825
798
  }: {
@@ -1083,6 +1056,7 @@ function createSession({
1083
1056
  turnStartConfig: turnStartConfigAtStart,
1084
1057
  recoveryStatus,
1085
1058
  restoration,
1059
+ sandboxCredentialEnvironment,
1086
1060
  replayOnly,
1087
1061
  lossyRerun,
1088
1062
  }: {
@@ -1115,6 +1089,7 @@ function createSession({
1115
1089
  turnStartConfig: ACPTurnStartConfig | undefined;
1116
1090
  recoveryStatus: ACPLifecycleData['recovery'];
1117
1091
  restoration: ACPLifecycleData['restoration'];
1092
+ sandboxCredentialEnvironment: Readonly<Record<string, string>> | undefined;
1118
1093
  replayOnly: boolean;
1119
1094
  lossyRerun: boolean;
1120
1095
  }): HarnessV1Session {
@@ -1370,6 +1345,9 @@ function createSession({
1370
1345
  }): ACPLifecycleData => ({
1371
1346
  implementationIdentity,
1372
1347
  authenticationProfile,
1348
+ ...(sandboxCredentialEnvironment == null
1349
+ ? {}
1350
+ : { sandboxCredentialEnvironment }),
1373
1351
  ...(latestACPSessionId == null ? {} : { acpSessionId: latestACPSessionId }),
1374
1352
  ...(bridge == null ? {} : { bridge }),
1375
1353
  ...(latestTurnStartConfig == null
@@ -21,6 +21,7 @@ export type ACPBridgeCoordinates = {
21
21
  export type ACPLifecycleData = ACPPromptGuidanceLifecycleState & {
22
22
  readonly implementationIdentity: string;
23
23
  readonly authenticationProfile?: ACPAuthenticationProfileIdentity;
24
+ readonly sandboxCredentialEnvironment?: Readonly<Record<string, string>>;
24
25
  readonly acpSessionId?: string;
25
26
  readonly bridge?: ACPBridgeCoordinates;
26
27
  readonly coldSession?: ACPColdSessionState;
@@ -76,8 +76,10 @@ export type ACPProviderAuthentication = {
76
76
 
77
77
  export type ACPCredentialBrokering = ({
78
78
  env,
79
+ sandboxEnv,
79
80
  }: {
80
81
  env: Readonly<Record<string, string>>;
82
+ sandboxEnv?: Readonly<Record<string, string>>;
81
83
  }) => ReadonlyArray<HarnessV1RequestTransformation>;
82
84
 
83
85
  export type ACPPermissionModeTarget =