@ai-sdk/harness-codex 1.0.94 → 1.0.96
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 +26 -0
- package/dist/bridge/index.mjs +32 -6
- package/dist/bridge/index.mjs.map +1 -1
- package/dist/bridge/package.json +1 -1
- package/dist/bridge/pnpm-lock.yaml +34 -34
- package/dist/index.d.ts +3 -1
- package/dist/index.js +95 -42
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
- package/src/bridge/index.ts +3 -1
- package/src/bridge/package.json +1 -1
- package/src/bridge/pnpm-lock.yaml +34 -34
- package/src/codex-bridge-protocol.ts +2 -1
- package/src/codex-harness.ts +141 -51
package/dist/bridge/package.json
CHANGED
|
@@ -9,55 +9,55 @@ importers:
|
|
|
9
9
|
.:
|
|
10
10
|
dependencies:
|
|
11
11
|
'@openai/codex-sdk':
|
|
12
|
-
specifier: 0.
|
|
13
|
-
version: 0.
|
|
12
|
+
specifier: 0.149.1
|
|
13
|
+
version: 0.149.1
|
|
14
14
|
ws:
|
|
15
15
|
specifier: 8.21.0
|
|
16
16
|
version: 8.21.0
|
|
17
17
|
|
|
18
18
|
packages:
|
|
19
19
|
|
|
20
|
-
'@openai/codex-sdk@0.
|
|
21
|
-
resolution: {integrity: sha512-
|
|
20
|
+
'@openai/codex-sdk@0.149.1':
|
|
21
|
+
resolution: {integrity: sha512-R00Rz5327LefZggAxl28r7vFQq1vxa91OxtjZJOsQfAM/MyH8InW5qwwRu6pzUmRGp1E29XrOzm7u1TeV5Yz2A==}
|
|
22
22
|
engines: {node: '>=18'}
|
|
23
23
|
|
|
24
|
-
'@openai/codex@0.
|
|
25
|
-
resolution: {integrity: sha512-
|
|
24
|
+
'@openai/codex@0.149.1':
|
|
25
|
+
resolution: {integrity: sha512-6q5pbcpFbJbqOpkubSDBwXmktQ55aD8eUzGzBF1zASob2DjwhBKDSNGtdZKalfrNJUdTDTPDMmzCXEXs5tMBYA==}
|
|
26
26
|
engines: {node: '>=16'}
|
|
27
27
|
hasBin: true
|
|
28
28
|
|
|
29
|
-
'@openai/codex@0.
|
|
30
|
-
resolution: {integrity: sha512-
|
|
29
|
+
'@openai/codex@0.149.1-darwin-arm64':
|
|
30
|
+
resolution: {integrity: sha512-6X84kTCbnTgPIJ2EdcPsrvwS0Wxsqpa+bCswGmRf4BjhcQ5nPMnBC6yCAaCMj+vrbXQHj+L6sa9FaR4QkmA1qw==}
|
|
31
31
|
engines: {node: '>=16'}
|
|
32
32
|
cpu: [arm64]
|
|
33
33
|
os: [darwin]
|
|
34
34
|
|
|
35
|
-
'@openai/codex@0.
|
|
36
|
-
resolution: {integrity: sha512
|
|
35
|
+
'@openai/codex@0.149.1-darwin-x64':
|
|
36
|
+
resolution: {integrity: sha512-MfLBQLfcElJL9tvj6y45qVHHMGSXCPnQOixuD3/Zq0g1BW/eFizkrGLdn48cFpc+l8cK+gt5nYG5pQYwVs6g4A==}
|
|
37
37
|
engines: {node: '>=16'}
|
|
38
38
|
cpu: [x64]
|
|
39
39
|
os: [darwin]
|
|
40
40
|
|
|
41
|
-
'@openai/codex@0.
|
|
42
|
-
resolution: {integrity: sha512-
|
|
41
|
+
'@openai/codex@0.149.1-linux-arm64':
|
|
42
|
+
resolution: {integrity: sha512-OqxUfZ1TVvHd18zHPKK/8ZRlpk8Vy11mg5CMHaLxNWldTbwVImDKtSLWT+m8m4NM5Sz4PbjtZMrVT/RfpBW/mQ==}
|
|
43
43
|
engines: {node: '>=16'}
|
|
44
44
|
cpu: [arm64]
|
|
45
45
|
os: [linux]
|
|
46
46
|
|
|
47
|
-
'@openai/codex@0.
|
|
48
|
-
resolution: {integrity: sha512-
|
|
47
|
+
'@openai/codex@0.149.1-linux-x64':
|
|
48
|
+
resolution: {integrity: sha512-Of5fGYgr7tAMsyj6vhXb4/RM/UoA3Zq8BLegUBDC09UNy1XTLGYP/2XD+UX8z3qh0NDwxYdCjFIWdDNijKZggQ==}
|
|
49
49
|
engines: {node: '>=16'}
|
|
50
50
|
cpu: [x64]
|
|
51
51
|
os: [linux]
|
|
52
52
|
|
|
53
|
-
'@openai/codex@0.
|
|
54
|
-
resolution: {integrity: sha512-
|
|
53
|
+
'@openai/codex@0.149.1-win32-arm64':
|
|
54
|
+
resolution: {integrity: sha512-5K0DmOKGK9Bos627p8sK8ATHjovPK0sDyT6h9Cb+4v+5CW5SGw1HLgjGxoLfJ8g3cg6mtg/pRCXXo2L/j71UVA==}
|
|
55
55
|
engines: {node: '>=16'}
|
|
56
56
|
cpu: [arm64]
|
|
57
57
|
os: [win32]
|
|
58
58
|
|
|
59
|
-
'@openai/codex@0.
|
|
60
|
-
resolution: {integrity: sha512-
|
|
59
|
+
'@openai/codex@0.149.1-win32-x64':
|
|
60
|
+
resolution: {integrity: sha512-G3QXGAg7nyyhqOeooAMUekBCeHd8a1QByhKcVAFyzNBaI06t6Ft7nsF+1SzFS0spuIdU4YyMi5YD26ukADBQUQ==}
|
|
61
61
|
engines: {node: '>=16'}
|
|
62
62
|
cpu: [x64]
|
|
63
63
|
os: [win32]
|
|
@@ -76,35 +76,35 @@ packages:
|
|
|
76
76
|
|
|
77
77
|
snapshots:
|
|
78
78
|
|
|
79
|
-
'@openai/codex-sdk@0.
|
|
79
|
+
'@openai/codex-sdk@0.149.1':
|
|
80
80
|
dependencies:
|
|
81
|
-
'@openai/codex': 0.
|
|
81
|
+
'@openai/codex': 0.149.1
|
|
82
82
|
|
|
83
|
-
'@openai/codex@0.
|
|
83
|
+
'@openai/codex@0.149.1':
|
|
84
84
|
optionalDependencies:
|
|
85
|
-
'@openai/codex-darwin-arm64': '@openai/codex@0.
|
|
86
|
-
'@openai/codex-darwin-x64': '@openai/codex@0.
|
|
87
|
-
'@openai/codex-linux-arm64': '@openai/codex@0.
|
|
88
|
-
'@openai/codex-linux-x64': '@openai/codex@0.
|
|
89
|
-
'@openai/codex-win32-arm64': '@openai/codex@0.
|
|
90
|
-
'@openai/codex-win32-x64': '@openai/codex@0.
|
|
91
|
-
|
|
92
|
-
'@openai/codex@0.
|
|
85
|
+
'@openai/codex-darwin-arm64': '@openai/codex@0.149.1-darwin-arm64'
|
|
86
|
+
'@openai/codex-darwin-x64': '@openai/codex@0.149.1-darwin-x64'
|
|
87
|
+
'@openai/codex-linux-arm64': '@openai/codex@0.149.1-linux-arm64'
|
|
88
|
+
'@openai/codex-linux-x64': '@openai/codex@0.149.1-linux-x64'
|
|
89
|
+
'@openai/codex-win32-arm64': '@openai/codex@0.149.1-win32-arm64'
|
|
90
|
+
'@openai/codex-win32-x64': '@openai/codex@0.149.1-win32-x64'
|
|
91
|
+
|
|
92
|
+
'@openai/codex@0.149.1-darwin-arm64':
|
|
93
93
|
optional: true
|
|
94
94
|
|
|
95
|
-
'@openai/codex@0.
|
|
95
|
+
'@openai/codex@0.149.1-darwin-x64':
|
|
96
96
|
optional: true
|
|
97
97
|
|
|
98
|
-
'@openai/codex@0.
|
|
98
|
+
'@openai/codex@0.149.1-linux-arm64':
|
|
99
99
|
optional: true
|
|
100
100
|
|
|
101
|
-
'@openai/codex@0.
|
|
101
|
+
'@openai/codex@0.149.1-linux-x64':
|
|
102
102
|
optional: true
|
|
103
103
|
|
|
104
|
-
'@openai/codex@0.
|
|
104
|
+
'@openai/codex@0.149.1-win32-arm64':
|
|
105
105
|
optional: true
|
|
106
106
|
|
|
107
|
-
'@openai/codex@0.
|
|
107
|
+
'@openai/codex@0.149.1-win32-x64':
|
|
108
108
|
optional: true
|
|
109
109
|
|
|
110
110
|
ws@8.21.0: {}
|
package/dist/index.d.ts
CHANGED
|
@@ -25,13 +25,15 @@ type CodexHarnessSettings = {
|
|
|
25
25
|
/**
|
|
26
26
|
* OpenAI model id the underlying `codex` CLI should use. Leaving this unset
|
|
27
27
|
* pins the adapter default (`DEFAULT_CODEX_MODEL`).
|
|
28
|
+
*
|
|
29
|
+
* @deprecated Use `model` on `HarnessAgent` instead.
|
|
28
30
|
*/
|
|
29
31
|
readonly model?: string;
|
|
30
32
|
/**
|
|
31
33
|
* Reasoning effort for reasoning-capable models. Leaving this unset
|
|
32
34
|
* defers to the CLI's default.
|
|
33
35
|
*/
|
|
34
|
-
readonly reasoningEffort?: 'low' | 'medium' | 'high';
|
|
36
|
+
readonly reasoningEffort?: 'low' | 'medium' | 'high' | 'xhigh' | 'max';
|
|
35
37
|
/**
|
|
36
38
|
* When `true`, allow the underlying runtime to use live web search.
|
|
37
39
|
*/
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// src/codex-harness.ts
|
|
2
|
-
import { randomBytes } from "crypto";
|
|
2
|
+
import { createHash, randomBytes } from "crypto";
|
|
3
3
|
import path from "path";
|
|
4
4
|
import {
|
|
5
5
|
commonTool,
|
|
@@ -175,7 +175,7 @@ import { z } from "zod/v4";
|
|
|
175
175
|
var outboundMessageSchema = harnessV1BridgeOutboundMessageSchema;
|
|
176
176
|
var startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
|
|
177
177
|
instructions: z.string().optional(),
|
|
178
|
-
reasoningEffort: z.enum(["low", "medium", "high"]).optional(),
|
|
178
|
+
reasoningEffort: z.enum(["low", "medium", "high", "xhigh", "max"]).optional(),
|
|
179
179
|
webSearch: z.boolean().optional(),
|
|
180
180
|
codexConfig: z.record(z.string(), z.unknown()).optional(),
|
|
181
181
|
mcpServers: z.record(z.string(), z.unknown()).optional(),
|
|
@@ -183,7 +183,8 @@ var startMessageSchema = harnessV1BridgeStartBaseSchema.extend({
|
|
|
183
183
|
// `codex.resumeThread(resumeThreadId, …)` instead of starting a fresh thread.
|
|
184
184
|
// The host sources the id from lifecycle state `data` cached from a prior
|
|
185
185
|
// `agent.detach`.
|
|
186
|
-
resumeThreadId: z.string().optional()
|
|
186
|
+
resumeThreadId: z.string().optional(),
|
|
187
|
+
restartThread: z.boolean().optional()
|
|
187
188
|
});
|
|
188
189
|
var inboundMessageSchema = z.discriminatedUnion("type", [
|
|
189
190
|
startMessageSchema,
|
|
@@ -194,7 +195,7 @@ var inboundMessageSchema = z.discriminatedUnion("type", [
|
|
|
194
195
|
var CLI_SHIM_FILENAME = "harness-tool.mjs";
|
|
195
196
|
|
|
196
197
|
// src/version.ts
|
|
197
|
-
var VERSION = true ? "1.0.
|
|
198
|
+
var VERSION = true ? "1.0.96" : "0.0.0-test";
|
|
198
199
|
|
|
199
200
|
// src/codex-harness.ts
|
|
200
201
|
var DEFAULT_CODEX_MODEL = "gpt-5.5";
|
|
@@ -221,6 +222,7 @@ var codexBridgeCoordsSchema = z2.object({
|
|
|
221
222
|
});
|
|
222
223
|
var codexResumeStateSchema = z2.object({
|
|
223
224
|
threadId: z2.string().optional(),
|
|
225
|
+
turnConfigurationFingerprint: z2.string().optional(),
|
|
224
226
|
bridge: codexBridgeCoordsSchema.optional(),
|
|
225
227
|
sandboxCredentialEnvironment: z2.record(z2.string(), z2.string()).optional()
|
|
226
228
|
});
|
|
@@ -233,6 +235,7 @@ function createCodex(settings = {}) {
|
|
|
233
235
|
lifecycleStateSchema: codexResumeStateSchema,
|
|
234
236
|
getBootstrap: getCodexBootstrap,
|
|
235
237
|
doStart: async (startOpts) => {
|
|
238
|
+
const model = settings.model ?? DEFAULT_CODEX_MODEL;
|
|
236
239
|
if (startOpts.builtinToolFiltering != null) {
|
|
237
240
|
throw new HarnessCapabilityUnsupportedError({
|
|
238
241
|
message: "Harness 'codex' does not support built-in tool filtering controls.",
|
|
@@ -269,6 +272,7 @@ function createCodex(settings = {}) {
|
|
|
269
272
|
const resumeData = isResume && typeof lifecycleState?.data === "object" ? lifecycleState.data : void 0;
|
|
270
273
|
const resumeThreadId = resumeData?.threadId;
|
|
271
274
|
const resumeThreadIdString = typeof resumeThreadId === "string" && resumeThreadId.length > 0 ? resumeThreadId : void 0;
|
|
275
|
+
const turnConfigurationFingerprint = typeof resumeData?.turnConfigurationFingerprint === "string" ? resumeData.turnConfigurationFingerprint : void 0;
|
|
272
276
|
const coords = resumeData?.bridge;
|
|
273
277
|
const authenticationMode = resolveCodexAuthenticationMode(settings.auth);
|
|
274
278
|
const resolvedAuthEnvironment = resolveCodexEnv(settings.auth);
|
|
@@ -307,6 +311,10 @@ function createCodex(settings = {}) {
|
|
|
307
311
|
CODEX_BOOTSTRAP_DIR
|
|
308
312
|
);
|
|
309
313
|
const workDir = startOpts.sessionWorkDir;
|
|
314
|
+
const sandboxHomeDir = await resolveSandboxHomeDir({
|
|
315
|
+
sandbox: toolSafeSandboxSession,
|
|
316
|
+
abortSignal: startOpts.abortSignal
|
|
317
|
+
});
|
|
310
318
|
const sessionDataDir = `${defaultWorkingDirectory}/.agent-runs/${startOpts.sessionId}`;
|
|
311
319
|
const bridgeStateDir = `${sessionDataDir}/bridge`;
|
|
312
320
|
const cliShimDir = `${sessionDataDir}/codex`;
|
|
@@ -348,7 +356,7 @@ function createCodex(settings = {}) {
|
|
|
348
356
|
cliShimPath,
|
|
349
357
|
// The live bridge was spawned by another process; no process handle.
|
|
350
358
|
proc: void 0,
|
|
351
|
-
model
|
|
359
|
+
model,
|
|
352
360
|
reasoningEffort: settings.reasoningEffort,
|
|
353
361
|
webSearch: settings.webSearch,
|
|
354
362
|
codexConfig: settings.codexConfig,
|
|
@@ -362,7 +370,10 @@ function createCodex(settings = {}) {
|
|
|
362
370
|
sandboxId,
|
|
363
371
|
sandboxCredentialEnvironment,
|
|
364
372
|
debug: startOpts.observability?.debug,
|
|
365
|
-
permissionMode: startOpts.permissionMode
|
|
373
|
+
permissionMode: startOpts.permissionMode,
|
|
374
|
+
sandbox: toolSafeSandboxSession,
|
|
375
|
+
sandboxHomeDir,
|
|
376
|
+
turnConfigurationFingerprint
|
|
366
377
|
});
|
|
367
378
|
} catch {
|
|
368
379
|
}
|
|
@@ -389,20 +400,11 @@ function createCodex(settings = {}) {
|
|
|
389
400
|
credentialEnvironmentVariables: CODEX_CREDENTIAL_ENVIRONMENT_VARIABLES,
|
|
390
401
|
credentialForwarding: settings.credentialForwarding
|
|
391
402
|
});
|
|
392
|
-
const codexSkillSetup = startOpts.skills && startOpts.skills.length > 0 ? await writeCodexSkills({
|
|
393
|
-
sandbox: toolSafeSandboxSession,
|
|
394
|
-
skills: startOpts.skills,
|
|
395
|
-
abortSignal: startOpts.abortSignal
|
|
396
|
-
}) : void 0;
|
|
397
403
|
const env = {
|
|
398
404
|
...forwardedAuthEnvironment,
|
|
399
405
|
AI_SDK_HARNESS_CLIENT_APP: CODEX_CLIENT_APP,
|
|
400
406
|
BRIDGE_CHANNEL_TOKEN: token,
|
|
401
407
|
BRIDGE_WS_PORT: String(port),
|
|
402
|
-
...codexSkillSetup ? {
|
|
403
|
-
HOME: codexSkillSetup.homeDir,
|
|
404
|
-
CODEX_HOME: codexSkillSetup.codexHomeDir
|
|
405
|
-
} : {},
|
|
406
408
|
...respawnStrategy === "replay" ? { BRIDGE_REPLAY_FROM_DISK: "1" } : {}
|
|
407
409
|
};
|
|
408
410
|
if (respawnStrategy === void 0) {
|
|
@@ -476,7 +478,7 @@ function createCodex(settings = {}) {
|
|
|
476
478
|
channel,
|
|
477
479
|
cliShimPath,
|
|
478
480
|
proc,
|
|
479
|
-
model
|
|
481
|
+
model,
|
|
480
482
|
reasoningEffort: settings.reasoningEffort,
|
|
481
483
|
webSearch: settings.webSearch,
|
|
482
484
|
codexConfig: settings.codexConfig,
|
|
@@ -490,7 +492,10 @@ function createCodex(settings = {}) {
|
|
|
490
492
|
sandboxId,
|
|
491
493
|
sandboxCredentialEnvironment,
|
|
492
494
|
debug: startOpts.observability?.debug,
|
|
493
|
-
permissionMode: startOpts.permissionMode
|
|
495
|
+
permissionMode: startOpts.permissionMode,
|
|
496
|
+
sandbox: toolSafeSandboxSession,
|
|
497
|
+
sandboxHomeDir,
|
|
498
|
+
turnConfigurationFingerprint
|
|
494
499
|
});
|
|
495
500
|
}
|
|
496
501
|
};
|
|
@@ -543,17 +548,12 @@ async function resolveBridgeEndpoint({
|
|
|
543
548
|
}
|
|
544
549
|
async function writeCodexSkills({
|
|
545
550
|
sandbox,
|
|
551
|
+
sandboxHomeDir,
|
|
546
552
|
skills,
|
|
547
553
|
abortSignal
|
|
548
554
|
}) {
|
|
549
|
-
const
|
|
550
|
-
|
|
551
|
-
await sandbox.run({
|
|
552
|
-
command: `mkdir -p ${shellQuote(codexHomeDir)}`,
|
|
553
|
-
abortSignal
|
|
554
|
-
});
|
|
555
|
-
const rootDir = path.posix.join(homeDir, ".agents", "skills");
|
|
556
|
-
await writeHarnessSkills({
|
|
555
|
+
const rootDir = path.posix.join(sandboxHomeDir, ".agents", "skills");
|
|
556
|
+
return writeHarnessSkills({
|
|
557
557
|
sandbox,
|
|
558
558
|
rootDir,
|
|
559
559
|
skills,
|
|
@@ -561,10 +561,6 @@ async function writeCodexSkills({
|
|
|
561
561
|
invalidSkillNameMessage: ({ name }) => `Invalid Codex skill name: ${name}`,
|
|
562
562
|
invalidSkillFilePathMessage: ({ skillName, filePath }) => `Invalid Codex skill file path for ${skillName}: ${filePath}`
|
|
563
563
|
});
|
|
564
|
-
return {
|
|
565
|
-
homeDir,
|
|
566
|
-
codexHomeDir
|
|
567
|
-
};
|
|
568
564
|
}
|
|
569
565
|
function openWebSocket({
|
|
570
566
|
url,
|
|
@@ -613,16 +609,44 @@ function createSession({
|
|
|
613
609
|
sandboxId,
|
|
614
610
|
sandboxCredentialEnvironment,
|
|
615
611
|
debug,
|
|
616
|
-
permissionMode
|
|
612
|
+
permissionMode,
|
|
613
|
+
sandbox,
|
|
614
|
+
sandboxHomeDir,
|
|
615
|
+
turnConfigurationFingerprint
|
|
617
616
|
}) {
|
|
618
617
|
let stopped = false;
|
|
619
618
|
let stopPromise;
|
|
620
619
|
let pendingResumeThreadId = seedResumeThreadOnFirstPrompt ? resumeThreadId : void 0;
|
|
621
620
|
let initialPromptGuidanceApplied = isResume;
|
|
622
621
|
let latestThreadId = resumeThreadId;
|
|
622
|
+
let latestTurnConfigurationFingerprint = turnConfigurationFingerprint;
|
|
623
623
|
channel.on("bridge-thread", (msg) => {
|
|
624
624
|
latestThreadId = msg.threadId;
|
|
625
625
|
});
|
|
626
|
+
const synchronizeTurnConfiguration = async ({
|
|
627
|
+
skills,
|
|
628
|
+
instructions,
|
|
629
|
+
tools,
|
|
630
|
+
abortSignal
|
|
631
|
+
}) => {
|
|
632
|
+
const skillsResult = await writeCodexSkills({
|
|
633
|
+
sandbox,
|
|
634
|
+
sandboxHomeDir,
|
|
635
|
+
skills,
|
|
636
|
+
abortSignal
|
|
637
|
+
});
|
|
638
|
+
const nextFingerprint = fingerprintCodexTurnConfiguration({
|
|
639
|
+
instructions,
|
|
640
|
+
tools
|
|
641
|
+
});
|
|
642
|
+
const restartThread = latestThreadId != null && (skillsResult.changed || latestTurnConfigurationFingerprint != null && latestTurnConfigurationFingerprint !== nextFingerprint);
|
|
643
|
+
latestTurnConfigurationFingerprint = nextFingerprint;
|
|
644
|
+
if (restartThread) {
|
|
645
|
+
initialPromptGuidanceApplied = false;
|
|
646
|
+
pendingResumeThreadId = void 0;
|
|
647
|
+
}
|
|
648
|
+
return { restartThread };
|
|
649
|
+
};
|
|
626
650
|
const wireTurn = (turnOpts) => {
|
|
627
651
|
let pendingResolve;
|
|
628
652
|
let pendingReject;
|
|
@@ -749,7 +773,6 @@ function createSession({
|
|
|
749
773
|
return {
|
|
750
774
|
sessionId,
|
|
751
775
|
isResume,
|
|
752
|
-
modelId: model,
|
|
753
776
|
doPromptTurn: async (promptOpts) => {
|
|
754
777
|
if (promptOpts.responseFormat?.type === "json" && promptOpts.responseFormat.schema == null) {
|
|
755
778
|
throw new HarnessCapabilityUnsupportedError({
|
|
@@ -757,15 +780,21 @@ function createSession({
|
|
|
757
780
|
harnessId: "codex"
|
|
758
781
|
});
|
|
759
782
|
}
|
|
760
|
-
const turn = wireTurn({
|
|
761
|
-
emit: promptOpts.emit,
|
|
762
|
-
abortSignal: promptOpts.abortSignal
|
|
763
|
-
});
|
|
764
783
|
const tools = (promptOpts.tools ?? []).map((t) => ({
|
|
765
784
|
name: t.name,
|
|
766
785
|
description: t.description,
|
|
767
786
|
inputSchema: t.inputSchema
|
|
768
787
|
}));
|
|
788
|
+
const { restartThread } = await synchronizeTurnConfiguration({
|
|
789
|
+
skills: promptOpts.skills,
|
|
790
|
+
instructions: promptOpts.instructions,
|
|
791
|
+
tools,
|
|
792
|
+
abortSignal: promptOpts.abortSignal
|
|
793
|
+
});
|
|
794
|
+
const turn = wireTurn({
|
|
795
|
+
emit: promptOpts.emit,
|
|
796
|
+
abortSignal: promptOpts.abortSignal
|
|
797
|
+
});
|
|
769
798
|
let promptText = extractUserText(promptOpts.prompt);
|
|
770
799
|
if (!initialPromptGuidanceApplied) {
|
|
771
800
|
promptText = frameInitialPromptGuidance({
|
|
@@ -783,13 +812,14 @@ function createSession({
|
|
|
783
812
|
tools,
|
|
784
813
|
...promptOpts.responseFormat == null ? {} : { responseFormat: promptOpts.responseFormat },
|
|
785
814
|
...promptOpts.instructions ? { instructions: promptOpts.instructions } : {},
|
|
786
|
-
model,
|
|
815
|
+
model: promptOpts.model ?? model,
|
|
787
816
|
reasoningEffort,
|
|
788
817
|
webSearch,
|
|
789
818
|
...codexConfig == null ? {} : { codexConfig },
|
|
790
819
|
...mcpServers == null ? {} : { mcpServers },
|
|
791
820
|
...permissionMode ? { permissionMode } : {},
|
|
792
821
|
...pendingResumeThreadId ? { resumeThreadId: pendingResumeThreadId } : {},
|
|
822
|
+
...restartThread ? { restartThread: true } : {},
|
|
793
823
|
...debug ? { debug } : {}
|
|
794
824
|
};
|
|
795
825
|
pendingResumeThreadId = void 0;
|
|
@@ -803,6 +833,17 @@ function createSession({
|
|
|
803
833
|
harnessId: "codex"
|
|
804
834
|
});
|
|
805
835
|
}
|
|
836
|
+
const tools = (continueOpts.tools ?? []).map((t) => ({
|
|
837
|
+
name: t.name,
|
|
838
|
+
description: t.description,
|
|
839
|
+
inputSchema: t.inputSchema
|
|
840
|
+
}));
|
|
841
|
+
const { restartThread } = await synchronizeTurnConfiguration({
|
|
842
|
+
skills: continueOpts.skills,
|
|
843
|
+
instructions: continueOpts.instructions,
|
|
844
|
+
tools,
|
|
845
|
+
abortSignal: continueOpts.abortSignal
|
|
846
|
+
});
|
|
806
847
|
const turn = wireTurn({
|
|
807
848
|
emit: continueOpts.emit,
|
|
808
849
|
abortSignal: continueOpts.abortSignal
|
|
@@ -821,20 +862,17 @@ function createSession({
|
|
|
821
862
|
* empty text block trips the Anthropic API's `cache_control` rule).
|
|
822
863
|
*/
|
|
823
864
|
prompt: "Continue.",
|
|
824
|
-
tools
|
|
825
|
-
name: t.name,
|
|
826
|
-
description: t.description,
|
|
827
|
-
inputSchema: t.inputSchema
|
|
828
|
-
})),
|
|
865
|
+
tools,
|
|
829
866
|
...continueOpts.responseFormat == null ? {} : { responseFormat: continueOpts.responseFormat },
|
|
830
867
|
...continueOpts.instructions ? { instructions: continueOpts.instructions } : {},
|
|
831
|
-
model,
|
|
868
|
+
model: continueOpts.model ?? model,
|
|
832
869
|
reasoningEffort,
|
|
833
870
|
webSearch,
|
|
834
871
|
...codexConfig == null ? {} : { codexConfig },
|
|
835
872
|
...mcpServers == null ? {} : { mcpServers },
|
|
836
873
|
...permissionMode ? { permissionMode } : {},
|
|
837
874
|
...threadId ? { resumeThreadId: threadId } : {},
|
|
875
|
+
...restartThread ? { restartThread: true } : {},
|
|
838
876
|
...debug ? { debug } : {}
|
|
839
877
|
})
|
|
840
878
|
);
|
|
@@ -861,6 +899,9 @@ function createSession({
|
|
|
861
899
|
specificationVersion: "harness-v1",
|
|
862
900
|
data: {
|
|
863
901
|
...latestThreadId ? { threadId: latestThreadId } : {},
|
|
902
|
+
...latestTurnConfigurationFingerprint ? {
|
|
903
|
+
turnConfigurationFingerprint: latestTurnConfigurationFingerprint
|
|
904
|
+
} : {},
|
|
864
905
|
...sandboxCredentialEnvironment == null ? {} : { sandboxCredentialEnvironment },
|
|
865
906
|
bridge: {
|
|
866
907
|
port: bridgePort,
|
|
@@ -962,6 +1003,9 @@ function createSession({
|
|
|
962
1003
|
specificationVersion: "harness-v1",
|
|
963
1004
|
data: {
|
|
964
1005
|
...lifecycleData,
|
|
1006
|
+
...latestTurnConfigurationFingerprint ? {
|
|
1007
|
+
turnConfigurationFingerprint: latestTurnConfigurationFingerprint
|
|
1008
|
+
} : {},
|
|
965
1009
|
...sandboxCredentialEnvironment == null ? {} : { sandboxCredentialEnvironment }
|
|
966
1010
|
}
|
|
967
1011
|
};
|
|
@@ -981,6 +1025,9 @@ function createSession({
|
|
|
981
1025
|
specificationVersion: "harness-v1",
|
|
982
1026
|
data: {
|
|
983
1027
|
...latestThreadId ? { threadId: latestThreadId } : {},
|
|
1028
|
+
...latestTurnConfigurationFingerprint ? {
|
|
1029
|
+
turnConfigurationFingerprint: latestTurnConfigurationFingerprint
|
|
1030
|
+
} : {},
|
|
984
1031
|
...sandboxCredentialEnvironment == null ? {} : { sandboxCredentialEnvironment },
|
|
985
1032
|
bridge: {
|
|
986
1033
|
port: bridgePort,
|
|
@@ -994,6 +1041,12 @@ function createSession({
|
|
|
994
1041
|
}
|
|
995
1042
|
};
|
|
996
1043
|
}
|
|
1044
|
+
function fingerprintCodexTurnConfiguration({
|
|
1045
|
+
instructions,
|
|
1046
|
+
tools
|
|
1047
|
+
}) {
|
|
1048
|
+
return createHash("sha256").update(JSON.stringify({ instructions: instructions ?? null, tools })).digest("hex");
|
|
1049
|
+
}
|
|
997
1050
|
function frameInitialPromptGuidance({
|
|
998
1051
|
toolUsageBlock,
|
|
999
1052
|
userText
|