@ai-sdk/harness-codex 1.0.79 → 1.0.80
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 +10 -0
- package/dist/bridge/index.mjs +142 -8
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/index.d.ts +6 -1
- package/dist/index.js +83 -26
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
- package/src/bridge/index.ts +0 -2
- package/src/codex-harness.ts +111 -30
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.
|
|
229
|
+
var VERSION = true ? "1.0.80" : "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
|
-
|
|
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 = `${
|
|
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
|
|
334
|
-
|
|
335
|
-
|
|
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
|
-
|
|
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(
|
|
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:
|
|
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
|
|
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:
|
|
431
|
+
sandbox: toolSafeSandboxSession,
|
|
411
432
|
bridgeStateDir,
|
|
412
433
|
bridgeType: "codex",
|
|
413
434
|
abortSignal: startOpts.abortSignal
|
|
414
435
|
});
|
|
415
|
-
const proc = await
|
|
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:
|
|
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
|
|
451
|
-
|
|
452
|
-
|
|
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(
|
|
513
|
+
function resolveBridgePort({
|
|
514
|
+
sandboxSession,
|
|
515
|
+
override
|
|
516
|
+
}) {
|
|
492
517
|
if (override !== void 0) return override;
|
|
493
|
-
if (sandboxSession.ports.length > 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
|
};
|