@ai-sdk/harness-codex 1.0.79 → 1.0.81

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.js CHANGED
@@ -12,8 +12,10 @@ import {
12
12
  createBridgeStartupError,
13
13
  drainBridgeProcessStream,
14
14
  forwardBridgeProcessStream,
15
+ getRestrictedSandboxSession,
15
16
  markBridgeStarting,
16
17
  maskSandboxCredentials,
18
+ resolveSandboxDefaultWorkingDirectory,
17
19
  resolveSandboxHomeDir,
18
20
  SandboxChannel,
19
21
  shellQuote,
@@ -224,7 +226,7 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
224
226
  var CLI_SHIM_FILENAME = "harness-tool.mjs";
225
227
 
226
228
  // src/version.ts
227
- var VERSION = true ? "1.0.79" : "0.0.0-test";
229
+ var VERSION = true ? "1.0.81" : "0.0.0-test";
228
230
 
229
231
  // src/codex-harness.ts
230
232
  var DEFAULT_CODEX_MODEL = "gpt-5.5";
@@ -275,10 +277,27 @@ function createCodex(settings = {}) {
275
277
  });
276
278
  }
277
279
  const sandboxSession = startOpts.sandboxSession;
280
+ const toolSafeSandboxSession = getRestrictedSandboxSession(sandboxSession);
281
+ const sandboxId = "id" in sandboxSession ? sandboxSession.id : void 0;
282
+ validateBasicSandboxSettings({
283
+ sandboxSession,
284
+ port: settings.port,
285
+ portEndpoint: settings.portEndpoint
286
+ });
287
+ if (settings.mintBridgeToken != null && sandboxId == null) {
288
+ throw new HarnessCapabilityUnsupportedError({
289
+ harnessId: "codex",
290
+ message: "The codex harness cannot use `mintBridgeToken` with a sandbox session that does not expose an id."
291
+ });
292
+ }
293
+ const defaultWorkingDirectory = await resolveSandboxDefaultWorkingDirectory({
294
+ sandboxSession,
295
+ abortSignal: startOpts.abortSignal
296
+ });
278
297
  const authenticationMode = resolveCodexAuthenticationMode(settings.auth);
279
298
  const resolvedAuthEnvironment = resolveCodexEnv(settings.auth);
280
299
  let sandboxAuthEnvironment = resolvedAuthEnvironment;
281
- if (sandboxSession.addRequestTransformations != null) {
300
+ if ("addRequestTransformations" in sandboxSession && sandboxSession.addRequestTransformations != null) {
282
301
  const requestTransformations = createCodexRequestTransformations(
283
302
  resolvedAuthEnvironment,
284
303
  authenticationMode
@@ -298,10 +317,8 @@ function createCodex(settings = {}) {
298
317
  } else {
299
318
  warnCredentialBrokeringUnavailable();
300
319
  }
301
- const session = sandboxSession.restricted();
302
- const sandboxId = sandboxSession.id;
303
320
  const bootstrapDir = path.posix.resolve(
304
- sandboxSession.defaultWorkingDirectory,
321
+ defaultWorkingDirectory,
305
322
  CODEX_BOOTSTRAP_DIR
306
323
  );
307
324
  const lifecycleState = startOpts.continueFrom ?? startOpts.resumeFrom;
@@ -312,7 +329,7 @@ function createCodex(settings = {}) {
312
329
  const resumeThreadIdString = typeof resumeThreadId === "string" && resumeThreadId.length > 0 ? resumeThreadId : void 0;
313
330
  const coords = resumeData?.bridge;
314
331
  const workDir = startOpts.sessionWorkDir;
315
- const sessionDataDir = `${sandboxSession.defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;
332
+ const sessionDataDir = `${defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;
316
333
  const bridgeStateDir = `${sessionDataDir}/bridge`;
317
334
  const cliShimDir = `${sessionDataDir}/codex`;
318
335
  const cliShimPath = `${cliShimDir}/${CLI_SHIM_FILENAME}`;
@@ -330,9 +347,10 @@ function createCodex(settings = {}) {
330
347
  });
331
348
  if (coords) {
332
349
  try {
333
- const endpoint2 = await sandboxSession.getPortEndpoint({
334
- port: coords.port,
335
- protocol: "ws"
350
+ const endpoint2 = await resolveBridgeEndpoint({
351
+ sandboxSession,
352
+ override: settings.portEndpoint,
353
+ port: coords.port
336
354
  });
337
355
  const attachEndpoint = withBridgeToken({
338
356
  endpoint: endpoint2,
@@ -373,7 +391,7 @@ function createCodex(settings = {}) {
373
391
  let respawnStrategy = isResume ? "rerun" : void 0;
374
392
  if (coords && isContinue) {
375
393
  const logRaw = await Promise.resolve(
376
- session.readTextFile({
394
+ toolSafeSandboxSession.readTextFile({
377
395
  path: `${bridgeStateDir}/event-log.ndjson`,
378
396
  abortSignal: startOpts.abortSignal
379
397
  })
@@ -382,10 +400,13 @@ function createCodex(settings = {}) {
382
400
  respawnStrategy = "replay";
383
401
  }
384
402
  }
385
- const port = resolveBridgePort(sandboxSession, settings.port);
403
+ const port = resolveBridgePort({
404
+ sandboxSession,
405
+ override: settings.port
406
+ });
386
407
  const token = settings.mintBridgeToken == null ? randomBytes(32).toString("hex") : settings.mintBridgeToken(sandboxId);
387
408
  const codexSkillSetup = startOpts.skills && startOpts.skills.length > 0 ? await writeCodexSkills({
388
- sandbox: session,
409
+ sandbox: toolSafeSandboxSession,
389
410
  skills: startOpts.skills,
390
411
  abortSignal: startOpts.abortSignal
391
412
  }) : void 0;
@@ -401,18 +422,18 @@ function createCodex(settings = {}) {
401
422
  ...respawnStrategy === "replay" ? { BRIDGE_REPLAY_FROM_DISK: "1" } : {}
402
423
  };
403
424
  if (respawnStrategy === void 0) {
404
- await session.run({
425
+ await toolSafeSandboxSession.run({
405
426
  command: `mkdir -p ${shellQuote(workDir)} ${shellQuote(bridgeStateDir)}`,
406
427
  abortSignal: startOpts.abortSignal
407
428
  });
408
429
  }
409
430
  await markBridgeStarting({
410
- sandbox: session,
431
+ sandbox: toolSafeSandboxSession,
411
432
  bridgeStateDir,
412
433
  bridgeType: "codex",
413
434
  abortSignal: startOpts.abortSignal
414
435
  });
415
- const proc = await session.spawn({
436
+ const proc = await toolSafeSandboxSession.spawn({
416
437
  command: `node ${shellQuote(`${bootstrapDir}/bridge.mjs`)} --workdir ${shellQuote(workDir)} --bridge-state-dir ${shellQuote(bridgeStateDir)} --cli-shim-dir ${shellQuote(cliShimDir)}`,
417
438
  env,
418
439
  abortSignal: startOpts.abortSignal
@@ -426,7 +447,7 @@ function createCodex(settings = {}) {
426
447
  });
427
448
  const { port: boundPort } = await waitForBridgeReady({
428
449
  proc,
429
- sandbox: session,
450
+ sandbox: toolSafeSandboxSession,
430
451
  bridgeStateDir,
431
452
  bridgeType: "codex",
432
453
  timeoutMs,
@@ -447,9 +468,10 @@ function createCodex(settings = {}) {
447
468
  })
448
469
  });
449
470
  void drainBridgeProcessStream(proc.stdout);
450
- const endpoint = await sandboxSession.getPortEndpoint({
451
- port: boundPort,
452
- protocol: "ws"
471
+ const endpoint = await resolveBridgeEndpoint({
472
+ sandboxSession,
473
+ override: settings.portEndpoint,
474
+ port: boundPort
453
475
  });
454
476
  const bridgeEndpoint = withBridgeToken({ endpoint, token });
455
477
  const channel = new SandboxChannel({
@@ -488,14 +510,52 @@ function createCodex(settings = {}) {
488
510
  }
489
511
  };
490
512
  }
491
- function resolveBridgePort(sandboxSession, override) {
513
+ function resolveBridgePort({
514
+ sandboxSession,
515
+ override
516
+ }) {
492
517
  if (override !== void 0) return override;
493
- if (sandboxSession.ports.length > 0) return sandboxSession.ports[0];
518
+ if ("ports" in sandboxSession && sandboxSession.ports.length > 0) {
519
+ return sandboxSession.ports[0];
520
+ }
494
521
  throw new HarnessCapabilityUnsupportedError({
495
522
  harnessId: "codex",
496
523
  message: "The codex harness needs a TCP port exposed by the sandbox. Create the sandbox with `ports: [<port>]` or pass `createCodex({ port })`."
497
524
  });
498
525
  }
526
+ function validateBasicSandboxSettings({
527
+ sandboxSession,
528
+ port,
529
+ portEndpoint
530
+ }) {
531
+ if ("getPortEndpoint" in sandboxSession) return;
532
+ if (port == null) {
533
+ throw new HarnessCapabilityUnsupportedError({
534
+ harnessId: "codex",
535
+ message: "The codex harness requires an explicit `port` when using a basic sandbox session."
536
+ });
537
+ }
538
+ if (portEndpoint == null) {
539
+ throw new HarnessCapabilityUnsupportedError({
540
+ harnessId: "codex",
541
+ message: "The codex harness requires an explicit `portEndpoint` when using a basic sandbox session."
542
+ });
543
+ }
544
+ }
545
+ async function resolveBridgeEndpoint({
546
+ sandboxSession,
547
+ override,
548
+ port
549
+ }) {
550
+ if (override != null) return override;
551
+ if ("getPortEndpoint" in sandboxSession) {
552
+ return sandboxSession.getPortEndpoint({ port, protocol: "ws" });
553
+ }
554
+ throw new HarnessCapabilityUnsupportedError({
555
+ harnessId: "codex",
556
+ message: "The codex harness requires an explicit `portEndpoint` when using a basic sandbox session."
557
+ });
558
+ }
499
559
  async function writeCodexSkills({
500
560
  sandbox,
501
561
  skills,
@@ -683,9 +743,6 @@ function createSession({
683
743
  reason: input.reason
684
744
  });
685
745
  },
686
- submitUserMessage: async (text) => {
687
- channel.send({ type: "user-message", text });
688
- },
689
746
  done
690
747
  };
691
748
  return {
@@ -822,7 +879,7 @@ function createSession({
822
879
  port: bridgePort,
823
880
  token: bridgeToken,
824
881
  lastSeenEventId,
825
- sandboxId
882
+ ...sandboxId == null ? {} : { sandboxId }
826
883
  }
827
884
  }
828
885
  };
@@ -937,7 +994,7 @@ function createSession({
937
994
  port: bridgePort,
938
995
  token: bridgeToken,
939
996
  lastSeenEventId,
940
- sandboxId
997
+ ...sandboxId == null ? {} : { sandboxId }
941
998
  }
942
999
  }
943
1000
  };