@openclaw/codex 2026.5.24-beta.1 → 2026.5.25-beta.1
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/{client-1sSy4p3z.js → client-SrtuTTVa.js} +10 -3
- package/dist/{client-factory-Bk6i4FnW.js → client-factory-A7DQkSLq.js} +1 -1
- package/dist/{command-handlers-CcTABuem.js → command-handlers-CLtPT37L.js} +10 -23
- package/dist/compact-acCua7zr.js +155 -0
- package/dist/{computer-use-Hdq1WgTA.js → computer-use-CVfE2Vfb.js} +2 -2
- package/dist/{config-DDMrwfJl.js → config-D6TUuyo2.js} +6 -3
- package/dist/{node-cli-sessions-9CAqnIaA.js → conversation-binding-B-GevkEb.js} +426 -434
- package/dist/{dynamic-tools-Bq717oJR.js → dynamic-tools-BXAE1U1-.js} +20 -11
- package/dist/harness.js +5 -5
- package/dist/index.js +451 -17
- package/dist/media-understanding-provider.js +7 -5
- package/dist/{models-DtGLkqMP.js → models-CC2IusQs.js} +3 -3
- package/dist/{notification-correlation-qKY_sgga.js → notification-correlation-D7tJW3FW.js} +26 -11
- package/dist/provider.js +3 -3
- package/dist/{request-D93E78SA.js → request-BO0z3vA8.js} +3 -3
- package/dist/{run-attempt-CT1N__qp.js → run-attempt-BjoI3hUJ.js} +279 -230
- package/dist/{session-binding-Bw_mfIW2.js → session-binding-CwNOIDP2.js} +1 -1
- package/dist/{shared-client-CFCUGEVs.js → shared-client-CZP1DjaN.js} +3 -4
- package/dist/{side-question-CYFMTA1O.js → side-question-Cb4COOQ9.js} +16 -11
- package/dist/test-api.js +3 -3
- package/dist/{thread-lifecycle-DGoaguJh.js → thread-lifecycle-CXMd9UgJ.js} +10 -12
- package/dist/{vision-tools-DOnxzH2y.js → vision-tools-CETeQgze.js} +16 -4
- package/npm-shrinkwrap.json +225 -238
- package/package.json +7 -7
- package/dist/compact-DnTgL6UT.js +0 -475
- package/dist/protocol-oeJQu4rs.js +0 -9
|
@@ -1,21 +1,21 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { t as defaultCodexAppServerClientFactory } from "./client-factory-A7DQkSLq.js";
|
|
2
|
+
import { c as readCodexPluginConfig, d as resolveCodexPluginsPolicy, f as shouldAutoApproveCodexAppServerApprovals, i as isCodexAppServerApprovalPolicyAllowedByRequirements, l as resolveCodexAppServerRuntimeOptions, o as isCodexSandboxExecServerEnabled, p as withMcpElicitationsApprovalPolicy, u as resolveCodexComputerUseConfig } from "./config-D6TUuyo2.js";
|
|
2
3
|
import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse } from "./protocol-validators-_gKDcd0x.js";
|
|
3
|
-
import {
|
|
4
|
-
import { a as
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import { n as
|
|
8
|
-
import {
|
|
9
|
-
import { c as resolveCodexAppServerAuthAccountCacheKey, d as resolveCodexAppServerEnvApiKeyCacheKey, f as resolveCodexAppServerHomeDir, l as resolveCodexAppServerAuthProfileId, s as refreshCodexAppServerAuthTokens, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-CFCUGEVs.js";
|
|
4
|
+
import { a as isCodexAppServerConnectionClosedError, i as isCodexAppServerApprovalRequest, l as isJsonObject, r as compareCodexAppServerVersions, s as MIN_CODEX_SANDBOX_EXEC_SERVER_APP_SERVER_VERSION } from "./client-SrtuTTVa.js";
|
|
5
|
+
import { D as resolveCodexContextEngineProjectionMaxChars, E as projectContextEngineAssemblyForCodex, O as resolveCodexContextEngineProjectionReserveTokens, S as defaultCodexAppInventoryCache, _ as mergeCodexThreadConfigs, a as buildDeveloperInstructions, c as buildTurnCollaborationMode, d as isContextEngineBindingCompatible, g as buildCodexPluginThreadConfigInputFingerprint, h as buildCodexPluginThreadConfig, i as buildContextEngineBinding, l as buildTurnStartParams, m as startOrResumeThread, n as areCodexDynamicToolFingerprintsCompatible, u as codexDynamicToolsFingerprint, v as shouldBuildCodexPluginThreadConfig, w as sanitizeCodexHistoryImagePayloads } from "./thread-lifecycle-CXMd9UgJ.js";
|
|
6
|
+
import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-CwNOIDP2.js";
|
|
7
|
+
import { n as buildCodexPluginAppCacheKey, r as CODEX_CONTROL_METHODS } from "./request-BO0z3vA8.js";
|
|
8
|
+
import { g as shouldRefreshCodexRateLimitsForUsageLimitMessage, h as resolveCodexUsageLimitResetAtMs, i as readCodexNotificationTurnId, m as formatCodexUsageLimitErrorMessage, n as isCodexNotificationForTurn, r as readCodexNotificationThreadId, s as formatCodexDisplayText, t as describeCodexNotificationCorrelation } from "./notification-correlation-D7tJW3FW.js";
|
|
9
|
+
import { c as resolveCodexAppServerAuthAccountCacheKey, d as resolveCodexAppServerEnvApiKeyCacheKey, f as resolveCodexAppServerHomeDir, l as resolveCodexAppServerAuthProfileId, s as refreshCodexAppServerAuthTokens, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-CZP1DjaN.js";
|
|
10
10
|
import { i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-CTnEWuor.js";
|
|
11
|
-
import { a as resolveCodexDynamicToolsLoading, i as normalizeCodexDynamicToolName, n as filterCodexDynamicTools, r as isForcedPrivateQaCodexRuntime, t as createCodexDynamicToolBridge } from "./dynamic-tools-
|
|
12
|
-
import { t as
|
|
13
|
-
import {
|
|
14
|
-
import { t as ensureCodexComputerUse } from "./computer-use-Hdq1WgTA.js";
|
|
11
|
+
import { a as resolveCodexDynamicToolsLoading, i as normalizeCodexDynamicToolName, n as filterCodexDynamicTools, r as isForcedPrivateQaCodexRuntime, t as createCodexDynamicToolBridge } from "./dynamic-tools-BXAE1U1-.js";
|
|
12
|
+
import { a as handleCodexAppServerElicitationRequest, c as emitDynamicToolTerminalDiagnostic, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerApprovalRequest, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as emitDynamicToolErrorDiagnostic, r as buildCodexNativeHookRelayConfig, s as emitDynamicToolStartedDiagnostic, t as filterToolsForVisionInputs } from "./vision-tools-CETeQgze.js";
|
|
13
|
+
import { t as ensureCodexComputerUse } from "./computer-use-CVfE2Vfb.js";
|
|
15
14
|
import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-N66I-Rd7.js";
|
|
16
15
|
import { createHash, randomUUID } from "node:crypto";
|
|
17
16
|
import nodeFs from "node:fs";
|
|
18
|
-
import {
|
|
17
|
+
import { asBoolean, asFiniteNumber, normalizeOptionalString, normalizeStringEntries } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
18
|
+
import { CODEX_APP_SERVER_CONTEXT_ENGINE_HOST, TOOL_PROGRESS_OUTPUT_MAX_CHARS, acquireSessionWriteLock, appendSessionTranscriptMessage, assembleHarnessContextEngine, assertContextEngineHostSupport, awaitAgentHarnessAgentEndHook, bootstrapHarnessContextEngine, buildAgentHookContextChannelFields, buildEmbeddedAttemptToolRunContext, buildHarnessContextEngineRuntimeContext, buildHarnessContextEngineRuntimeContextFromUsage, classifyAgentHarnessTerminalOutcome, clearActiveEmbeddedRun, embeddedAgentLog, emitAgentEvent, emitSessionTranscriptUpdate, finalizeHarnessContextEngineTurn, formatErrorMessage, formatToolAggregate, formatToolProgressOutput, getBeforeToolCallPolicyDiagnosticState, inferToolMetaFromArgs, isActiveHarnessContextEngine, isSubagentSessionKey, loadCodexBundleMcpThreadConfig, normalizeAgentRuntimeTools, normalizeUsage, registerNativeHookRelay, resolveAgentHarnessBeforePromptBuildResult, resolveAttemptSpawnWorkspaceDir, resolveBootstrapContextForRun, resolveContextEngineOwnerPluginId, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, resolveSessionWriteLockOptions, resolveUserPath, runAgentCleanupStep, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessAgentEndHook, runAgentHarnessBeforeCompactionHook, runAgentHarnessBeforeMessageWriteHook, runAgentHarnessLlmInputHook, runAgentHarnessLlmOutputHook, runHarnessContextEngineMaintenance, setActiveEmbeddedRun, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
19
19
|
import { spawn } from "node:child_process";
|
|
20
20
|
import { once } from "node:events";
|
|
21
21
|
import { WebSocketServer } from "ws";
|
|
@@ -25,7 +25,7 @@ import path, { posix } from "node:path";
|
|
|
25
25
|
import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
|
|
26
26
|
import { isToolAllowed } from "openclaw/plugin-sdk/sandbox";
|
|
27
27
|
import { appendRegularFile, pathExists } from "openclaw/plugin-sdk/security-runtime";
|
|
28
|
-
import { emitTrustedDiagnosticEvent, hasPendingInternalDiagnosticEvent, onInternalDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
28
|
+
import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, hasPendingInternalDiagnosticEvent, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
29
29
|
import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "@earendil-works/pi-coding-agent";
|
|
30
30
|
import { createAgentHarnessTaskRuntime, deliverAgentHarnessTaskCompletion, isDurableAgentHarnessCompletionDelivery } from "openclaw/plugin-sdk/agent-harness-task-runtime";
|
|
31
31
|
import { isIP } from "node:net";
|
|
@@ -102,10 +102,6 @@ function inferCodexDynamicToolMeta(call, detailMode) {
|
|
|
102
102
|
//#endregion
|
|
103
103
|
//#region extensions/codex/src/app-server/transcript-mirror.ts
|
|
104
104
|
const MIRROR_IDENTITY_META_KEY = "mirrorIdentity";
|
|
105
|
-
function normalizeOptionalString$1(value) {
|
|
106
|
-
const normalized = value?.trim();
|
|
107
|
-
return normalized ? normalized : void 0;
|
|
108
|
-
}
|
|
109
105
|
function buildSenderLabel(params) {
|
|
110
106
|
const label = params.senderName ?? params.senderUsername ?? params.senderE164 ?? params.senderId;
|
|
111
107
|
if (!label) return;
|
|
@@ -113,17 +109,17 @@ function buildSenderLabel(params) {
|
|
|
113
109
|
return `${label} (${params.senderId})`;
|
|
114
110
|
}
|
|
115
111
|
function buildCodexUserPromptMessage(params) {
|
|
116
|
-
const senderId = normalizeOptionalString
|
|
117
|
-
const senderName = normalizeOptionalString
|
|
118
|
-
const senderUsername = normalizeOptionalString
|
|
119
|
-
const senderE164 = normalizeOptionalString
|
|
112
|
+
const senderId = normalizeOptionalString(params.senderId);
|
|
113
|
+
const senderName = normalizeOptionalString(params.senderName);
|
|
114
|
+
const senderUsername = normalizeOptionalString(params.senderUsername);
|
|
115
|
+
const senderE164 = normalizeOptionalString(params.senderE164);
|
|
120
116
|
const senderLabel = buildSenderLabel({
|
|
121
117
|
senderId,
|
|
122
118
|
senderName,
|
|
123
119
|
senderUsername,
|
|
124
120
|
senderE164
|
|
125
121
|
});
|
|
126
|
-
const sourceChannel = normalizeOptionalString
|
|
122
|
+
const sourceChannel = normalizeOptionalString(params.inputProvenance?.sourceChannel ?? params.messageChannel ?? params.messageProvider);
|
|
127
123
|
return {
|
|
128
124
|
role: "user",
|
|
129
125
|
content: params.prompt,
|
|
@@ -183,12 +179,14 @@ async function mirrorCodexAppServerTranscript(params) {
|
|
|
183
179
|
sessionFile: params.sessionFile,
|
|
184
180
|
...resolveSessionWriteLockOptions(params.config)
|
|
185
181
|
});
|
|
182
|
+
const appendedUpdates = [];
|
|
186
183
|
try {
|
|
187
|
-
const
|
|
184
|
+
const mirrorState = await readTranscriptMirrorState(params.sessionFile);
|
|
185
|
+
let nextMessageSeq = mirrorState.messageCount;
|
|
188
186
|
for (const message of messages) {
|
|
189
187
|
const dedupeIdentity = buildMirrorDedupeIdentity(message);
|
|
190
188
|
const idempotencyKey = params.idempotencyScope ? `${params.idempotencyScope}:${dedupeIdentity}` : void 0;
|
|
191
|
-
if (idempotencyKey &&
|
|
189
|
+
if (idempotencyKey && mirrorState.idempotencyKeys.has(idempotencyKey)) continue;
|
|
192
190
|
const nextMessage = runAgentHarnessBeforeMessageWriteHook({
|
|
193
191
|
message: {
|
|
194
192
|
...message,
|
|
@@ -202,41 +200,57 @@ async function mirrorCodexAppServerTranscript(params) {
|
|
|
202
200
|
...nextMessage,
|
|
203
201
|
idempotencyKey
|
|
204
202
|
} : nextMessage;
|
|
205
|
-
await appendSessionTranscriptMessage({
|
|
203
|
+
const { messageId, message: appendedMessage } = await appendSessionTranscriptMessage({
|
|
206
204
|
transcriptPath: params.sessionFile,
|
|
207
205
|
message: messageToAppend,
|
|
208
206
|
config: params.config
|
|
209
207
|
});
|
|
210
|
-
|
|
208
|
+
nextMessageSeq += 1;
|
|
209
|
+
appendedUpdates.push({
|
|
210
|
+
messageId,
|
|
211
|
+
message: appendedMessage,
|
|
212
|
+
messageSeq: nextMessageSeq
|
|
213
|
+
});
|
|
214
|
+
if (idempotencyKey) mirrorState.idempotencyKeys.add(idempotencyKey);
|
|
211
215
|
}
|
|
212
216
|
} finally {
|
|
213
217
|
await lock.release();
|
|
214
218
|
}
|
|
215
|
-
|
|
219
|
+
for (const update of appendedUpdates) emitSessionTranscriptUpdate({
|
|
216
220
|
sessionFile: params.sessionFile,
|
|
217
|
-
sessionKey: params.sessionKey
|
|
221
|
+
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
222
|
+
message: update.message,
|
|
223
|
+
messageId: update.messageId,
|
|
224
|
+
messageSeq: update.messageSeq
|
|
218
225
|
});
|
|
219
|
-
else emitSessionTranscriptUpdate(params.sessionFile);
|
|
220
226
|
}
|
|
221
|
-
async function
|
|
222
|
-
const
|
|
227
|
+
async function readTranscriptMirrorState(sessionFile) {
|
|
228
|
+
const idempotencyKeys = /* @__PURE__ */ new Set();
|
|
229
|
+
let messageCount = 0;
|
|
223
230
|
let raw;
|
|
224
231
|
try {
|
|
225
232
|
raw = await fs.readFile(sessionFile, "utf8");
|
|
226
233
|
} catch (error) {
|
|
227
234
|
if (error.code !== "ENOENT") throw error;
|
|
228
|
-
return
|
|
235
|
+
return {
|
|
236
|
+
idempotencyKeys,
|
|
237
|
+
messageCount
|
|
238
|
+
};
|
|
229
239
|
}
|
|
230
240
|
for (const line of raw.split(/\r?\n/)) {
|
|
231
241
|
if (!line.trim()) continue;
|
|
232
242
|
try {
|
|
233
243
|
const parsed = JSON.parse(line);
|
|
234
|
-
if (
|
|
244
|
+
if (parsed.type === "message") messageCount += 1;
|
|
245
|
+
if (typeof parsed.message?.idempotencyKey === "string") idempotencyKeys.add(parsed.message.idempotencyKey);
|
|
235
246
|
} catch {
|
|
236
247
|
continue;
|
|
237
248
|
}
|
|
238
249
|
}
|
|
239
|
-
return
|
|
250
|
+
return {
|
|
251
|
+
idempotencyKeys,
|
|
252
|
+
messageCount
|
|
253
|
+
};
|
|
240
254
|
}
|
|
241
255
|
//#endregion
|
|
242
256
|
//#region extensions/codex/src/app-server/event-projector.ts
|
|
@@ -463,6 +477,12 @@ var CodexAppServerEventProjector = class {
|
|
|
463
477
|
});
|
|
464
478
|
}
|
|
465
479
|
recordDynamicToolResult(params) {
|
|
480
|
+
const existingMeta = this.toolMetas.get(params.callId);
|
|
481
|
+
this.toolMetas.set(params.callId, {
|
|
482
|
+
toolName: params.tool,
|
|
483
|
+
...existingMeta?.meta ? { meta: existingMeta.meta } : {},
|
|
484
|
+
...existingMeta?.asyncStarted === true || params.asyncStarted === true ? { asyncStarted: true } : {}
|
|
485
|
+
});
|
|
466
486
|
this.recordToolTranscriptResult({
|
|
467
487
|
id: params.callId,
|
|
468
488
|
name: params.tool,
|
|
@@ -832,7 +852,7 @@ var CodexAppServerEventProjector = class {
|
|
|
832
852
|
if (savedPath) this.nativeGeneratedMediaUrls.add(savedPath);
|
|
833
853
|
}
|
|
834
854
|
buildToolMediaUrls(toolTelemetry) {
|
|
835
|
-
const mediaUrls = new Set(toolTelemetry.toolMediaUrls
|
|
855
|
+
const mediaUrls = new Set(normalizeStringEntries(toolTelemetry.toolMediaUrls ?? []));
|
|
836
856
|
if ((toolTelemetry.messagingToolSentMediaUrls?.length ?? 0) === 0) for (const mediaUrl of this.nativeGeneratedMediaUrls) mediaUrls.add(mediaUrl);
|
|
837
857
|
return mediaUrls.size > 0 ? [...mediaUrls] : toolTelemetry.toolMediaUrls;
|
|
838
858
|
}
|
|
@@ -1118,9 +1138,11 @@ var CodexAppServerEventProjector = class {
|
|
|
1118
1138
|
const toolName = itemName(item);
|
|
1119
1139
|
if (!toolName) return;
|
|
1120
1140
|
const meta = itemMeta(item, this.toolProgressDetailMode());
|
|
1141
|
+
const existingMeta = this.toolMetas.get(item.id);
|
|
1121
1142
|
this.toolMetas.set(item.id, {
|
|
1122
1143
|
toolName,
|
|
1123
|
-
...meta ? { meta } : {}
|
|
1144
|
+
...meta ? { meta } : {},
|
|
1145
|
+
...existingMeta?.asyncStarted === true ? { asyncStarted: true } : {}
|
|
1124
1146
|
});
|
|
1125
1147
|
if (isSideEffectingNativeToolItem(item)) this.sideEffectingToolItemIds.add(item.id);
|
|
1126
1148
|
else this.sideEffectingToolItemIds.delete(item.id);
|
|
@@ -1364,12 +1386,10 @@ function readNullableString$1(record, key) {
|
|
|
1364
1386
|
return typeof value === "string" ? value : void 0;
|
|
1365
1387
|
}
|
|
1366
1388
|
function readNumber$1(record, key) {
|
|
1367
|
-
|
|
1368
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
1389
|
+
return asFiniteNumber(record[key]);
|
|
1369
1390
|
}
|
|
1370
1391
|
function readBoolean$1(record, key) {
|
|
1371
|
-
|
|
1372
|
-
return typeof value === "boolean" ? value : void 0;
|
|
1392
|
+
return asBoolean(record[key]);
|
|
1373
1393
|
}
|
|
1374
1394
|
function readBooleanAlias(record, keys) {
|
|
1375
1395
|
for (const key of keys) {
|
|
@@ -2616,9 +2636,6 @@ function readString$2(record, key) {
|
|
|
2616
2636
|
const value = record?.[key];
|
|
2617
2637
|
return typeof value === "string" ? value : void 0;
|
|
2618
2638
|
}
|
|
2619
|
-
function normalizeOptionalString(value) {
|
|
2620
|
-
return value?.trim() || void 0;
|
|
2621
|
-
}
|
|
2622
2639
|
function readStringArray(value) {
|
|
2623
2640
|
if (!Array.isArray(value)) return [];
|
|
2624
2641
|
return value.filter((entry) => typeof entry === "string" && entry.trim() !== "");
|
|
@@ -2741,8 +2758,7 @@ function readTranscriptParentThreadId(payload) {
|
|
|
2741
2758
|
return readString$2(isJsonObject(subagent?.thread_spawn) ? subagent.thread_spawn : void 0, "parent_thread_id")?.trim();
|
|
2742
2759
|
}
|
|
2743
2760
|
function readNumber(record, key) {
|
|
2744
|
-
|
|
2745
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
2761
|
+
return asFiniteNumber(record[key]);
|
|
2746
2762
|
}
|
|
2747
2763
|
function secondsToMillis(value) {
|
|
2748
2764
|
return value === void 0 ? void 0 : Math.round(value * 1e3);
|
|
@@ -4669,6 +4685,13 @@ function readCodexAppServerRolloutTokenUsageLine(line) {
|
|
|
4669
4685
|
return;
|
|
4670
4686
|
}
|
|
4671
4687
|
}
|
|
4688
|
+
function utf8JsonByteLength(value) {
|
|
4689
|
+
try {
|
|
4690
|
+
return Buffer.byteLength(JSON.stringify(value), "utf8");
|
|
4691
|
+
} catch {
|
|
4692
|
+
return;
|
|
4693
|
+
}
|
|
4694
|
+
}
|
|
4672
4695
|
function maxFiniteNumber(values) {
|
|
4673
4696
|
const nums = values.filter((value) => typeof value === "number" && Number.isFinite(value));
|
|
4674
4697
|
if (nums.length === 0) return;
|
|
@@ -4724,10 +4747,18 @@ async function runCodexAgentEndHook(params, hookParams) {
|
|
|
4724
4747
|
}
|
|
4725
4748
|
async function runCodexAppServerAttempt(params, options = {}) {
|
|
4726
4749
|
const attemptStartedAt = Date.now();
|
|
4750
|
+
const codexModelCallTrace = freezeDiagnosticTraceContext(createDiagnosticTraceContextFromActiveScope());
|
|
4751
|
+
const codexModelContentCapture = resolveDiagnosticModelContentCapturePolicy(params.config);
|
|
4752
|
+
const codexModelCallId = `${params.runId}:codex-model:1`;
|
|
4753
|
+
let codexModelCallStartedAt = attemptStartedAt;
|
|
4754
|
+
let codexModelCallStarted = false;
|
|
4755
|
+
let codexModelCallTerminalEmitted = false;
|
|
4756
|
+
let codexModelCallRequestPayloadBytes;
|
|
4727
4757
|
const attemptClientFactory = options.clientFactory ?? defaultCodexAppServerClientFactory;
|
|
4728
4758
|
const pluginConfig = readCodexPluginConfig(options.pluginConfig);
|
|
4729
4759
|
const computerUseConfig = resolveCodexComputerUseConfig({ pluginConfig });
|
|
4730
4760
|
const configuredAppServer = resolveCodexAppServerRuntimeOptions({ pluginConfig });
|
|
4761
|
+
const beforeToolCallPolicy = getBeforeToolCallPolicyDiagnosticState();
|
|
4731
4762
|
const resolvedWorkspace = resolveUserPath(params.workspaceDir);
|
|
4732
4763
|
await fs.mkdir(resolvedWorkspace, { recursive: true });
|
|
4733
4764
|
const sandboxSessionKey = params.sandboxSessionKey?.trim() || params.sessionKey?.trim() || params.sessionId;
|
|
@@ -4743,9 +4774,15 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
4743
4774
|
appServer: configuredAppServer,
|
|
4744
4775
|
pluginConfig,
|
|
4745
4776
|
env: process.env,
|
|
4746
|
-
shouldPromote:
|
|
4777
|
+
shouldPromote: beforeToolCallPolicy.hasBeforeToolCallHook || beforeToolCallPolicy.trustedToolPolicies.length > 0,
|
|
4747
4778
|
canUseUntrustedApprovalPolicy: configuredAppServer.start.transport !== "stdio" || isCodexAppServerApprovalPolicyAllowedByRequirements("untrusted")
|
|
4748
4779
|
});
|
|
4780
|
+
if (configuredAppServer.approvalPolicy === "never" && appServer.approvalPolicy === "untrusted") embeddedAgentLog.info("codex app-server approval policy promoted for OpenClaw tool policy", {
|
|
4781
|
+
from: "never",
|
|
4782
|
+
to: "untrusted",
|
|
4783
|
+
beforeToolCallHook: beforeToolCallPolicy.hasBeforeToolCallHook,
|
|
4784
|
+
trustedToolPolicies: beforeToolCallPolicy.trustedToolPolicies
|
|
4785
|
+
});
|
|
4749
4786
|
let pluginAppServer = appServer;
|
|
4750
4787
|
const nativeHookRelayEvents = resolveCodexNativeHookRelayEvents({
|
|
4751
4788
|
configuredEvents: options.nativeHookRelay?.events,
|
|
@@ -4794,10 +4831,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
4794
4831
|
sessionId: activeSessionId,
|
|
4795
4832
|
sessionFile: activeSessionFile
|
|
4796
4833
|
});
|
|
4797
|
-
const adoptContextEngineCompactionTranscript = (compactResult) => {
|
|
4798
|
-
if (compactResult.result?.sessionId) activeSessionId = compactResult.result.sessionId;
|
|
4799
|
-
if (compactResult.result?.sessionFile) activeSessionFile = compactResult.result.sessionFile;
|
|
4800
|
-
};
|
|
4801
4834
|
const startupAuthAccountCacheKey = await resolveCodexAppServerAuthAccountCacheKey({
|
|
4802
4835
|
authProfileId: startupAuthProfileId,
|
|
4803
4836
|
authProfileStore: params.authProfileStore,
|
|
@@ -4832,21 +4865,22 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
4832
4865
|
});
|
|
4833
4866
|
const hookChannelId = resolveCodexAppServerHookChannelId(params, sandboxSessionKey);
|
|
4834
4867
|
let yieldDetected = false;
|
|
4868
|
+
const tools = await buildDynamicTools({
|
|
4869
|
+
params,
|
|
4870
|
+
resolvedWorkspace,
|
|
4871
|
+
effectiveWorkspace,
|
|
4872
|
+
sandboxSessionKey,
|
|
4873
|
+
sandbox,
|
|
4874
|
+
nativeToolSurfaceEnabled,
|
|
4875
|
+
runAbortController,
|
|
4876
|
+
sessionAgentId,
|
|
4877
|
+
pluginConfig,
|
|
4878
|
+
onYieldDetected: () => {
|
|
4879
|
+
yieldDetected = true;
|
|
4880
|
+
}
|
|
4881
|
+
});
|
|
4835
4882
|
const toolBridge = createCodexDynamicToolBridge({
|
|
4836
|
-
tools
|
|
4837
|
-
params,
|
|
4838
|
-
resolvedWorkspace,
|
|
4839
|
-
effectiveWorkspace,
|
|
4840
|
-
sandboxSessionKey,
|
|
4841
|
-
sandbox,
|
|
4842
|
-
nativeToolSurfaceEnabled,
|
|
4843
|
-
runAbortController,
|
|
4844
|
-
sessionAgentId,
|
|
4845
|
-
pluginConfig,
|
|
4846
|
-
onYieldDetected: () => {
|
|
4847
|
-
yieldDetected = true;
|
|
4848
|
-
}
|
|
4849
|
-
}),
|
|
4883
|
+
tools,
|
|
4850
4884
|
registeredTools: await buildDynamicTools({
|
|
4851
4885
|
params,
|
|
4852
4886
|
resolvedWorkspace,
|
|
@@ -4902,65 +4936,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
4902
4936
|
contextEnginePluginId: activeContextEnginePluginId,
|
|
4903
4937
|
tokenBudget: params.contextTokenBudget
|
|
4904
4938
|
});
|
|
4905
|
-
const forceContextEngineCompactionForCodexOverflow = async (error, options = {}) => {
|
|
4906
|
-
if (!activeContextEngine?.info.ownsCompaction) return false;
|
|
4907
|
-
embeddedAgentLog.warn("codex app-server context-engine prompt overflowed; forcing context-engine compaction", {
|
|
4908
|
-
sessionId: activeSessionId,
|
|
4909
|
-
sessionKey: contextSessionKey,
|
|
4910
|
-
...options.threadId ? { threadId: options.threadId } : {},
|
|
4911
|
-
engineId: activeContextEngine.info.id,
|
|
4912
|
-
tokenBudget: params.contextTokenBudget,
|
|
4913
|
-
error: formatErrorMessage(error)
|
|
4914
|
-
});
|
|
4915
|
-
try {
|
|
4916
|
-
const runtimeContext = buildActiveContextEngineRuntimeContext();
|
|
4917
|
-
const overflowTokenCount = params.contextTokenBudget ?? params.contextWindowInfo?.tokens;
|
|
4918
|
-
const compactResult = await compactContextEngineWithSafetyTimeout(activeContextEngine, {
|
|
4919
|
-
sessionId: activeSessionId,
|
|
4920
|
-
sessionKey: contextSessionKey,
|
|
4921
|
-
sessionFile: activeSessionFile,
|
|
4922
|
-
tokenBudget: params.contextTokenBudget,
|
|
4923
|
-
force: true,
|
|
4924
|
-
...overflowTokenCount ? { currentTokenCount: overflowTokenCount } : {},
|
|
4925
|
-
compactionTarget: "threshold",
|
|
4926
|
-
runtimeContext: overflowTokenCount ? {
|
|
4927
|
-
...runtimeContext,
|
|
4928
|
-
currentTokenCount: overflowTokenCount
|
|
4929
|
-
} : runtimeContext
|
|
4930
|
-
}, resolveCompactionTimeoutMs(params.config), runAbortController.signal);
|
|
4931
|
-
embeddedAgentLog.info("codex app-server context-engine forced compaction result", {
|
|
4932
|
-
sessionId: activeSessionId,
|
|
4933
|
-
sessionKey: contextSessionKey,
|
|
4934
|
-
engineId: activeContextEngine.info.id,
|
|
4935
|
-
ok: compactResult.ok,
|
|
4936
|
-
compacted: compactResult.compacted,
|
|
4937
|
-
reason: compactResult.reason,
|
|
4938
|
-
tokensBefore: compactResult.result?.tokensBefore,
|
|
4939
|
-
tokensAfter: compactResult.result?.tokensAfter
|
|
4940
|
-
});
|
|
4941
|
-
if (!compactResult.ok || !compactResult.compacted) return false;
|
|
4942
|
-
adoptContextEngineCompactionTranscript(compactResult);
|
|
4943
|
-
const maintenanceRuntimeContext = buildActiveContextEngineRuntimeContext();
|
|
4944
|
-
await runHarnessContextEngineMaintenance({
|
|
4945
|
-
contextEngine: activeContextEngine,
|
|
4946
|
-
sessionId: activeSessionId,
|
|
4947
|
-
sessionKey: contextSessionKey,
|
|
4948
|
-
sessionFile: activeSessionFile,
|
|
4949
|
-
reason: "compaction",
|
|
4950
|
-
runtimeContext: maintenanceRuntimeContext,
|
|
4951
|
-
config: params.config
|
|
4952
|
-
});
|
|
4953
|
-
return true;
|
|
4954
|
-
} catch (compactErr) {
|
|
4955
|
-
embeddedAgentLog.warn("codex app-server context-engine forced compaction failed", {
|
|
4956
|
-
sessionId: params.sessionId,
|
|
4957
|
-
sessionKey: contextSessionKey,
|
|
4958
|
-
engineId: activeContextEngine.info.id,
|
|
4959
|
-
error: formatErrorMessage(compactErr)
|
|
4960
|
-
});
|
|
4961
|
-
return false;
|
|
4962
|
-
}
|
|
4963
|
-
};
|
|
4964
4939
|
if (activeContextEngine) {
|
|
4965
4940
|
await bootstrapHarnessContextEngine({
|
|
4966
4941
|
hadSessionFile,
|
|
@@ -4992,12 +4967,6 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
4992
4967
|
let developerInstructions = baseDeveloperInstructions;
|
|
4993
4968
|
let prePromptMessageCount = historyMessages.length;
|
|
4994
4969
|
let contextEngineProjection;
|
|
4995
|
-
const resetCodexPromptInputs = () => {
|
|
4996
|
-
promptText = params.prompt;
|
|
4997
|
-
developerInstructions = baseDeveloperInstructions;
|
|
4998
|
-
prePromptMessageCount = historyMessages.length;
|
|
4999
|
-
contextEngineProjection = void 0;
|
|
5000
|
-
};
|
|
5001
4970
|
const applyActiveContextEngineProjection = async (decisionStartupBinding) => {
|
|
5002
4971
|
if (!activeContextEngine) return;
|
|
5003
4972
|
const assembled = await assembleHarnessContextEngine({
|
|
@@ -5082,78 +5051,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5082
5051
|
let promptBuild = await buildPromptFromCurrentInputs();
|
|
5083
5052
|
const decorateCodexTurnPromptText = (prompt) => prependCodexOpenClawPromptContext(prompt, openClawPromptContext);
|
|
5084
5053
|
let codexTurnPromptText = decorateCodexTurnPromptText(promptBuild.prompt);
|
|
5085
|
-
const refreshCodexTurnPromptText = () => {
|
|
5086
|
-
codexTurnPromptText = decorateCodexTurnPromptText(promptBuild.prompt);
|
|
5087
|
-
};
|
|
5088
5054
|
const buildCodexTurnCollaborationDeveloperInstructions = () => buildTurnCollaborationMode(params, {
|
|
5089
5055
|
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
5090
5056
|
heartbeatCollaborationInstructions: workspaceBootstrapContext.heartbeatCollaborationInstructions
|
|
5091
5057
|
}).settings.developer_instructions ?? void 0;
|
|
5092
5058
|
const buildRenderedCodexDeveloperInstructions = () => joinPresentSections(promptBuild.developerInstructions, buildCodexTurnCollaborationDeveloperInstructions());
|
|
5093
|
-
const rebuildPromptAfterContextEngineCompaction = async () => {
|
|
5094
|
-
historyMessages = await readMirroredSessionHistoryMessages(activeSessionFile) ?? historyMessages;
|
|
5095
|
-
resetCodexPromptInputs();
|
|
5096
|
-
try {
|
|
5097
|
-
await applyActiveContextEngineProjection(void 0);
|
|
5098
|
-
} catch (assembleErr) {
|
|
5099
|
-
embeddedAgentLog.warn("context engine assemble failed after forced compaction; using Codex baseline prompt", { error: formatErrorMessage(assembleErr) });
|
|
5100
|
-
}
|
|
5101
|
-
promptBuild = await buildPromptFromCurrentInputs();
|
|
5102
|
-
refreshCodexTurnPromptText();
|
|
5103
|
-
};
|
|
5104
|
-
const buildCodexProviderBoundaryPrecheck = () => {
|
|
5105
|
-
const contextTokenBudget = typeof params.contextTokenBudget === "number" && Number.isFinite(params.contextTokenBudget) ? Math.floor(params.contextTokenBudget) : typeof params.contextWindowInfo?.tokens === "number" && Number.isFinite(params.contextWindowInfo.tokens) ? Math.floor(params.contextWindowInfo.tokens) : void 0;
|
|
5106
|
-
if (!contextTokenBudget || contextTokenBudget <= 0) return;
|
|
5107
|
-
const reserveTokens = resolveCodexContextEngineProjectionReserveTokens({ config: params.config }) ?? 2e4;
|
|
5108
|
-
const renderedDeveloperInstructions = buildRenderedCodexDeveloperInstructions();
|
|
5109
|
-
const renderedChars = codexTurnPromptText.length + renderedDeveloperInstructions.length;
|
|
5110
|
-
return shouldPreemptivelyCompactBeforePrompt({
|
|
5111
|
-
messages: historyMessages,
|
|
5112
|
-
systemPrompt: renderedDeveloperInstructions,
|
|
5113
|
-
prompt: codexTurnPromptText,
|
|
5114
|
-
contextTokenBudget,
|
|
5115
|
-
reserveTokens,
|
|
5116
|
-
llmBoundaryTokenPressure: {
|
|
5117
|
-
estimatedPromptTokens: estimateRenderedLlmBoundaryTokenPressure({
|
|
5118
|
-
systemPrompt: renderedDeveloperInstructions,
|
|
5119
|
-
prompt: codexTurnPromptText
|
|
5120
|
-
}),
|
|
5121
|
-
source: "codex_app_server_rendered_prompt",
|
|
5122
|
-
renderedChars
|
|
5123
|
-
}
|
|
5124
|
-
});
|
|
5125
|
-
};
|
|
5126
|
-
const maybeCompactContextEngineForProviderBoundaryPrecheck = async () => {
|
|
5127
|
-
if (!activeContextEngine?.info.ownsCompaction || !contextEngineProjection) return;
|
|
5128
|
-
const precheck = buildCodexProviderBoundaryPrecheck();
|
|
5129
|
-
if (!precheck) return;
|
|
5130
|
-
embeddedAgentLog.debug(formatPrePromptPrecheckLog({
|
|
5131
|
-
result: precheck,
|
|
5132
|
-
provider: params.provider,
|
|
5133
|
-
modelId: params.modelId,
|
|
5134
|
-
messageCount: historyMessages.length,
|
|
5135
|
-
contextTokenBudget: typeof params.contextTokenBudget === "number" ? params.contextTokenBudget : params.contextWindowInfo?.tokens ?? 0,
|
|
5136
|
-
reserveTokens: resolveCodexContextEngineProjectionReserveTokens({ config: params.config }) ?? 2e4,
|
|
5137
|
-
...contextSessionKey ? { sessionKey: contextSessionKey } : {},
|
|
5138
|
-
...activeSessionId ? { sessionId: activeSessionId } : {},
|
|
5139
|
-
...activeSessionFile ? { sessionFile: activeSessionFile } : {}
|
|
5140
|
-
}));
|
|
5141
|
-
if (precheck.route === "fits") return;
|
|
5142
|
-
if (!await forceContextEngineCompactionForCodexOverflow(PREEMPTIVE_OVERFLOW_ERROR_TEXT)) throw new Error(PREEMPTIVE_OVERFLOW_ERROR_TEXT);
|
|
5143
|
-
await rebuildPromptAfterContextEngineCompaction();
|
|
5144
|
-
const afterCompactionPrecheck = buildCodexProviderBoundaryPrecheck();
|
|
5145
|
-
if (!afterCompactionPrecheck || afterCompactionPrecheck.route === "fits") return;
|
|
5146
|
-
embeddedAgentLog.warn("codex app-server provider-boundary precheck still overflowed after compaction", {
|
|
5147
|
-
sessionId: activeSessionId,
|
|
5148
|
-
sessionKey: contextSessionKey,
|
|
5149
|
-
route: afterCompactionPrecheck.route,
|
|
5150
|
-
estimatedPromptTokens: afterCompactionPrecheck.estimatedPromptTokens,
|
|
5151
|
-
promptBudgetBeforeReserve: afterCompactionPrecheck.promptBudgetBeforeReserve,
|
|
5152
|
-
overflowTokens: afterCompactionPrecheck.overflowTokens
|
|
5153
|
-
});
|
|
5154
|
-
throw new Error(PREEMPTIVE_OVERFLOW_ERROR_TEXT);
|
|
5155
|
-
};
|
|
5156
|
-
await maybeCompactContextEngineForProviderBoundaryPrecheck();
|
|
5157
5059
|
const systemPromptReport = buildCodexSystemPromptReport({
|
|
5158
5060
|
attempt: params,
|
|
5159
5061
|
sessionKey: contextSessionKey,
|
|
@@ -5990,6 +5892,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
5990
5892
|
threadId: thread.threadId,
|
|
5991
5893
|
turnId,
|
|
5992
5894
|
nativeHookRelay,
|
|
5895
|
+
autoApprove: shouldAutoApproveCodexAppServerApprovals(appServer),
|
|
5993
5896
|
signal: runAbortController.signal
|
|
5994
5897
|
});
|
|
5995
5898
|
}
|
|
@@ -6083,22 +5986,26 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6083
5986
|
projector?.recordDynamicToolResult({
|
|
6084
5987
|
callId: call.callId,
|
|
6085
5988
|
tool: call.tool,
|
|
5989
|
+
asyncStarted: response.asyncStarted === true,
|
|
6086
5990
|
success: protocolResponse.success,
|
|
6087
5991
|
terminalType: response.diagnosticTerminalType ?? (protocolResponse.success ? "completed" : "error"),
|
|
6088
5992
|
sideEffectEvidence: response.sideEffectEvidence === true,
|
|
6089
5993
|
contentItems: protocolResponse.contentItems
|
|
6090
5994
|
});
|
|
6091
|
-
if (shouldEmitDynamicToolProgress)
|
|
6092
|
-
|
|
6093
|
-
|
|
6094
|
-
|
|
6095
|
-
|
|
6096
|
-
|
|
6097
|
-
|
|
6098
|
-
|
|
6099
|
-
|
|
6100
|
-
|
|
6101
|
-
|
|
5995
|
+
if (shouldEmitDynamicToolProgress) {
|
|
5996
|
+
const progressResponse = toCodexDynamicToolProgressResponse(response, protocolResponse);
|
|
5997
|
+
emitCodexAppServerEvent(params, {
|
|
5998
|
+
stream: "tool",
|
|
5999
|
+
data: {
|
|
6000
|
+
phase: "result",
|
|
6001
|
+
name: call.tool,
|
|
6002
|
+
toolCallId: call.callId,
|
|
6003
|
+
...toolMeta ? { meta: toolMeta } : {},
|
|
6004
|
+
isError: !protocolResponse.success,
|
|
6005
|
+
result: sanitizeCodexToolResponse(progressResponse)
|
|
6006
|
+
}
|
|
6007
|
+
});
|
|
6008
|
+
}
|
|
6102
6009
|
if (!terminalDiagnosticObserved && !hasPendingDynamicToolTerminalDiagnostic({
|
|
6103
6010
|
call,
|
|
6104
6011
|
runId: params.runId,
|
|
@@ -6161,27 +6068,99 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6161
6068
|
systemPrompt: buildRenderedCodexDeveloperInstructions(),
|
|
6162
6069
|
prompt: codexTurnPromptText,
|
|
6163
6070
|
historyMessages,
|
|
6164
|
-
imagesCount: params.images?.length ?? 0
|
|
6071
|
+
imagesCount: params.images?.length ?? 0,
|
|
6072
|
+
tools
|
|
6165
6073
|
});
|
|
6166
6074
|
const buildTurnStartFailureMessages = () => [...historyMessages, buildCodexUserPromptMessage({
|
|
6167
6075
|
...params,
|
|
6168
6076
|
prompt: codexTurnPromptText
|
|
6169
6077
|
})];
|
|
6078
|
+
const codexModelCallBaseFields = {
|
|
6079
|
+
runId: params.runId,
|
|
6080
|
+
callId: codexModelCallId,
|
|
6081
|
+
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
6082
|
+
sessionId: params.sessionId,
|
|
6083
|
+
provider: params.provider,
|
|
6084
|
+
model: params.modelId,
|
|
6085
|
+
api: params.model.api,
|
|
6086
|
+
transport: appServer.start.transport,
|
|
6087
|
+
...hookContextWindowFields,
|
|
6088
|
+
trace: codexModelCallTrace
|
|
6089
|
+
};
|
|
6090
|
+
const codexDiagnosticToolDefinitions = codexModelContentCapture.toolDefinitions ? buildCodexDiagnosticToolDefinitions(tools) : void 0;
|
|
6091
|
+
const codexModelContentPrivateData = (modelContent) => modelContent && Object.keys(modelContent).length > 0 ? { modelContent } : void 0;
|
|
6092
|
+
const buildCodexModelCallDiagnosticContent = () => {
|
|
6093
|
+
const modelContent = {
|
|
6094
|
+
...codexModelContentCapture.inputMessages ? { inputMessages: buildTurnStartFailureMessages() } : {},
|
|
6095
|
+
...codexModelContentCapture.systemPrompt ? { systemPrompt: buildRenderedCodexDeveloperInstructions() } : {},
|
|
6096
|
+
...codexDiagnosticToolDefinitions ? { toolDefinitions: codexDiagnosticToolDefinitions } : {}
|
|
6097
|
+
};
|
|
6098
|
+
return Object.keys(modelContent).length > 0 ? modelContent : void 0;
|
|
6099
|
+
};
|
|
6100
|
+
const emitCodexModelCallStarted = () => {
|
|
6101
|
+
codexModelCallStartedAt = Date.now();
|
|
6102
|
+
codexModelCallStarted = true;
|
|
6103
|
+
emitTrustedDiagnosticEventWithPrivateData({
|
|
6104
|
+
type: "model.call.started",
|
|
6105
|
+
...codexModelCallBaseFields
|
|
6106
|
+
}, codexModelContentPrivateData(buildCodexModelCallDiagnosticContent()));
|
|
6107
|
+
};
|
|
6108
|
+
const emitCodexModelCallCompleted = (result) => {
|
|
6109
|
+
if (!codexModelCallStarted || codexModelCallTerminalEmitted) return;
|
|
6110
|
+
codexModelCallTerminalEmitted = true;
|
|
6111
|
+
emitTrustedDiagnosticEventWithPrivateData({
|
|
6112
|
+
type: "model.call.completed",
|
|
6113
|
+
...codexModelCallBaseFields,
|
|
6114
|
+
durationMs: Math.max(0, Date.now() - codexModelCallStartedAt),
|
|
6115
|
+
...codexModelCallRequestPayloadBytes !== void 0 ? { requestPayloadBytes: codexModelCallRequestPayloadBytes } : {}
|
|
6116
|
+
}, codexModelContentPrivateData({
|
|
6117
|
+
...buildCodexModelCallDiagnosticContent(),
|
|
6118
|
+
...codexModelContentCapture.outputMessages ? { outputMessages: result.lastAssistant ? [result.lastAssistant] : result.assistantTexts } : {}
|
|
6119
|
+
}));
|
|
6120
|
+
};
|
|
6121
|
+
const emitCodexModelCallError = (error, fields = {}) => {
|
|
6122
|
+
if (!codexModelCallStarted || codexModelCallTerminalEmitted) return;
|
|
6123
|
+
codexModelCallTerminalEmitted = true;
|
|
6124
|
+
emitTrustedDiagnosticEventWithPrivateData({
|
|
6125
|
+
type: "model.call.error",
|
|
6126
|
+
...codexModelCallBaseFields,
|
|
6127
|
+
durationMs: Math.max(0, Date.now() - codexModelCallStartedAt),
|
|
6128
|
+
errorCategory: fields.failureKind ?? "error",
|
|
6129
|
+
...fields.failureKind ? { failureKind: fields.failureKind } : {},
|
|
6130
|
+
...codexModelCallRequestPayloadBytes !== void 0 ? { requestPayloadBytes: codexModelCallRequestPayloadBytes } : {}
|
|
6131
|
+
}, codexModelContentPrivateData({
|
|
6132
|
+
...buildCodexModelCallDiagnosticContent(),
|
|
6133
|
+
...codexModelContentCapture.outputMessages ? { outputMessages: [] } : {}
|
|
6134
|
+
}));
|
|
6135
|
+
embeddedAgentLog.debug("codex app-server model call diagnostic ended with error", { error: formatErrorMessage(error) });
|
|
6136
|
+
};
|
|
6137
|
+
const classifyCodexModelCallFailureKind = (error) => {
|
|
6138
|
+
if (timedOut || turnCompletionIdleTimedOut) return "timeout";
|
|
6139
|
+
const errorMessage = error ? formatErrorMessage(error).toLowerCase() : "";
|
|
6140
|
+
if (errorMessage.includes("timed out") || errorMessage.includes("timeout")) return "timeout";
|
|
6141
|
+
if (runAbortController.signal.aborted && !clientClosedAbort) return String(runAbortController.signal.reason ?? "").toLowerCase().includes("timeout") ? "timeout" : "aborted";
|
|
6142
|
+
return errorMessage.includes("aborted") ? "aborted" : void 0;
|
|
6143
|
+
};
|
|
6170
6144
|
let turn;
|
|
6171
|
-
const startCodexTurn = async () =>
|
|
6172
|
-
|
|
6173
|
-
|
|
6174
|
-
|
|
6175
|
-
|
|
6176
|
-
|
|
6177
|
-
|
|
6178
|
-
|
|
6179
|
-
|
|
6180
|
-
|
|
6181
|
-
|
|
6182
|
-
|
|
6183
|
-
|
|
6145
|
+
const startCodexTurn = async () => {
|
|
6146
|
+
const turnStartParams = buildTurnStartParams(params, {
|
|
6147
|
+
threadId: thread.threadId,
|
|
6148
|
+
cwd: codexExecutionCwd,
|
|
6149
|
+
appServer: pluginAppServer,
|
|
6150
|
+
promptText: codexTurnPromptText,
|
|
6151
|
+
sandboxPolicy: codexSandboxPolicy,
|
|
6152
|
+
environmentSelection: codexEnvironmentSelection,
|
|
6153
|
+
turnScopedDeveloperInstructions: workspaceBootstrapContext.turnScopedDeveloperInstructions,
|
|
6154
|
+
heartbeatCollaborationInstructions: workspaceBootstrapContext.heartbeatCollaborationInstructions
|
|
6155
|
+
});
|
|
6156
|
+
codexModelCallRequestPayloadBytes = utf8JsonByteLength(turnStartParams);
|
|
6157
|
+
return assertCodexTurnStartResponse(await client.request("turn/start", turnStartParams, {
|
|
6158
|
+
timeoutMs: params.timeoutMs,
|
|
6159
|
+
signal: runAbortController.signal
|
|
6160
|
+
}));
|
|
6161
|
+
};
|
|
6184
6162
|
try {
|
|
6163
|
+
emitCodexModelCallStarted();
|
|
6185
6164
|
runAgentHarnessLlmInputHook({
|
|
6186
6165
|
event: buildLlmInputEvent(),
|
|
6187
6166
|
ctx: hookContext
|
|
@@ -6207,10 +6186,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6207
6186
|
});
|
|
6208
6187
|
try {
|
|
6209
6188
|
const preRetrySessionFile = activeSessionFile;
|
|
6210
|
-
const compactedForRetry = await forceContextEngineCompactionForCodexOverflow(turnStartError, { threadId: thread.threadId });
|
|
6211
6189
|
await clearCodexAppServerBinding(preRetrySessionFile);
|
|
6212
6190
|
if (activeSessionFile !== preRetrySessionFile) await clearCodexAppServerBinding(activeSessionFile);
|
|
6213
|
-
if (compactedForRetry) await rebuildPromptAfterContextEngineCompaction();
|
|
6214
6191
|
thread = await restartContextEngineCodexThread();
|
|
6215
6192
|
emitCodexAppServerEvent(params, {
|
|
6216
6193
|
stream: "codex_app_server.lifecycle",
|
|
@@ -6270,6 +6247,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6270
6247
|
},
|
|
6271
6248
|
ctx: hookContext
|
|
6272
6249
|
});
|
|
6250
|
+
const turnStartFailureKind = classifyCodexModelCallFailureKind(turnStartError);
|
|
6251
|
+
emitCodexModelCallError(turnStartErrorMessage, turnStartFailureKind ? { failureKind: turnStartFailureKind } : {});
|
|
6273
6252
|
await runCodexAgentEndHook(params, {
|
|
6274
6253
|
event: {
|
|
6275
6254
|
messages: buildTurnStartFailureMessages(),
|
|
@@ -6303,12 +6282,12 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6303
6282
|
authProfileId: startupAuthProfileId,
|
|
6304
6283
|
rateLimits: usageLimitError.rateLimitsForProfile
|
|
6305
6284
|
});
|
|
6306
|
-
return buildCodexTurnStartFailureResult({
|
|
6285
|
+
return { ...buildCodexTurnStartFailureResult({
|
|
6307
6286
|
params,
|
|
6308
6287
|
message: usageLimitError.message,
|
|
6309
6288
|
messagesSnapshot: buildTurnStartFailureMessages(),
|
|
6310
6289
|
systemPromptReport
|
|
6311
|
-
});
|
|
6290
|
+
}) };
|
|
6312
6291
|
}
|
|
6313
6292
|
throw turnStartError;
|
|
6314
6293
|
}
|
|
@@ -6380,10 +6359,18 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6380
6359
|
queueMessage: async (text, options) => activeSteeringQueue.queue(text, options),
|
|
6381
6360
|
isStreaming: () => !completed,
|
|
6382
6361
|
isCompacting: () => projector?.isCompacting() ?? false,
|
|
6362
|
+
sourceReplyDeliveryMode: params.sourceReplyDeliveryMode,
|
|
6383
6363
|
cancel: () => runAbortController.abort("cancelled"),
|
|
6384
6364
|
abort: () => runAbortController.abort("aborted")
|
|
6385
6365
|
};
|
|
6386
6366
|
setActiveEmbeddedRun(params.sessionId, handle, params.sessionKey);
|
|
6367
|
+
mirrorPromptAtTurnStartBestEffort({
|
|
6368
|
+
params,
|
|
6369
|
+
agentId: sessionAgentId,
|
|
6370
|
+
sessionKey: sandboxSessionKey,
|
|
6371
|
+
threadId: thread.threadId,
|
|
6372
|
+
turnId: activeTurnId
|
|
6373
|
+
});
|
|
6387
6374
|
turnAttemptIdleWatchArmed = true;
|
|
6388
6375
|
turnTerminalIdleWatchArmed = true;
|
|
6389
6376
|
touchTurnCompletionActivity("turn:start", { attemptProgress: true });
|
|
@@ -6432,6 +6419,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6432
6419
|
result,
|
|
6433
6420
|
turnCompletionIdleTimedOut
|
|
6434
6421
|
});
|
|
6422
|
+
const modelCallFailureKind = classifyCodexModelCallFailureKind(finalPromptError) ?? (finalAborted ? "aborted" : void 0);
|
|
6423
|
+
if (modelCallFailureKind) emitCodexModelCallError(finalPromptError ?? "codex app-server attempt interrupted", { failureKind: modelCallFailureKind });
|
|
6424
|
+
else if (finalPromptError) emitCodexModelCallError(finalPromptError);
|
|
6425
|
+
else emitCodexModelCallCompleted(result);
|
|
6435
6426
|
recordCodexTrajectoryCompletion(trajectoryRecorder, {
|
|
6436
6427
|
attempt: params,
|
|
6437
6428
|
result,
|
|
@@ -6542,6 +6533,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
6542
6533
|
systemPromptReport
|
|
6543
6534
|
};
|
|
6544
6535
|
} finally {
|
|
6536
|
+
emitCodexModelCallError("codex app-server run completed without model-call terminal event");
|
|
6545
6537
|
emitLifecycleTerminal({
|
|
6546
6538
|
phase: "error",
|
|
6547
6539
|
error: "codex app-server run completed without lifecycle terminal event"
|
|
@@ -6717,6 +6709,16 @@ function toCodexDynamicToolProtocolResponse(response) {
|
|
|
6717
6709
|
success: response.success
|
|
6718
6710
|
};
|
|
6719
6711
|
}
|
|
6712
|
+
function toCodexDynamicToolProgressResponse(response, protocolResponse) {
|
|
6713
|
+
if (response.asyncStarted !== true) return protocolResponse;
|
|
6714
|
+
return {
|
|
6715
|
+
...protocolResponse,
|
|
6716
|
+
details: {
|
|
6717
|
+
async: true,
|
|
6718
|
+
status: "started"
|
|
6719
|
+
}
|
|
6720
|
+
};
|
|
6721
|
+
}
|
|
6720
6722
|
function shouldReleaseTurnAfterTerminalDynamicTool(state) {
|
|
6721
6723
|
return !state.completed && !state.aborted && state.responseSuccess && !state.currentTurnHadNonTerminalDynamicToolResult && state.activeAppServerTurnRequests === 0 && state.activeTurnItemIdsCount === 0 && state.pendingOpenClawDynamicToolCompletionIdsCount === 0;
|
|
6722
6724
|
}
|
|
@@ -7528,8 +7530,7 @@ function readString(record, key) {
|
|
|
7528
7530
|
return typeof value === "string" ? value : void 0;
|
|
7529
7531
|
}
|
|
7530
7532
|
function readBoolean(record, key) {
|
|
7531
|
-
|
|
7532
|
-
return typeof value === "boolean" ? value : void 0;
|
|
7533
|
+
return asBoolean(record[key]);
|
|
7533
7534
|
}
|
|
7534
7535
|
async function readMirroredSessionHistoryMessages(sessionFile) {
|
|
7535
7536
|
const messages = await readCodexMirroredSessionHistoryMessages(sessionFile);
|
|
@@ -7596,7 +7597,8 @@ function buildCodexSystemPromptReport(params) {
|
|
|
7596
7597
|
systemPrompt: {
|
|
7597
7598
|
chars: params.developerInstructions.length,
|
|
7598
7599
|
projectContextChars: 0,
|
|
7599
|
-
nonProjectContextChars: params.developerInstructions.length
|
|
7600
|
+
nonProjectContextChars: params.developerInstructions.length,
|
|
7601
|
+
hash: sha256Text(params.developerInstructions)
|
|
7600
7602
|
},
|
|
7601
7603
|
injectedWorkspaceFiles: buildCodexBootstrapInjectionStats({
|
|
7602
7604
|
bootstrapFiles: params.workspaceBootstrapContext.bootstrapFiles,
|
|
@@ -7605,6 +7607,7 @@ function buildCodexSystemPromptReport(params) {
|
|
|
7605
7607
|
}),
|
|
7606
7608
|
skills: {
|
|
7607
7609
|
promptChars: skillsPrompt.length,
|
|
7610
|
+
hash: sha256Text(skillsPrompt),
|
|
7608
7611
|
entries: buildCodexSkillReportEntries(skillsPrompt)
|
|
7609
7612
|
},
|
|
7610
7613
|
tools: {
|
|
@@ -7621,17 +7624,30 @@ function buildCodexSkillReportEntries(skillsPrompt) {
|
|
|
7621
7624
|
blockChars: block.length
|
|
7622
7625
|
})).filter((entry) => entry.blockChars > 0);
|
|
7623
7626
|
}
|
|
7627
|
+
function readCodexDiagnosticToolParameters(tool) {
|
|
7628
|
+
return tool.inputSchema ?? tool.parameters;
|
|
7629
|
+
}
|
|
7630
|
+
function buildCodexDiagnosticToolDefinitions(tools) {
|
|
7631
|
+
return tools.map((tool) => ({
|
|
7632
|
+
name: tool.name,
|
|
7633
|
+
description: tool.description,
|
|
7634
|
+
parameters: readCodexDiagnosticToolParameters(tool)
|
|
7635
|
+
}));
|
|
7636
|
+
}
|
|
7624
7637
|
function buildCodexToolReportEntry(tool) {
|
|
7625
7638
|
const summary = tool.description.trim();
|
|
7626
7639
|
if (tool.deferLoading === true) return {
|
|
7627
7640
|
name: tool.name,
|
|
7628
7641
|
summaryChars: summary.length,
|
|
7642
|
+
summaryHash: sha256Text(summary),
|
|
7629
7643
|
schemaChars: 0,
|
|
7644
|
+
schemaHash: stableJsonHash(null),
|
|
7630
7645
|
propertiesCount: null
|
|
7631
7646
|
};
|
|
7632
7647
|
return {
|
|
7633
7648
|
name: tool.name,
|
|
7634
7649
|
summaryChars: summary.length,
|
|
7650
|
+
summaryHash: sha256Text(summary),
|
|
7635
7651
|
...buildCodexToolSchemaStats(tool.inputSchema)
|
|
7636
7652
|
};
|
|
7637
7653
|
}
|
|
@@ -7646,9 +7662,24 @@ function buildCodexToolSchemaStats(schema) {
|
|
|
7646
7662
|
const properties = isJsonObject(schema) && isJsonObject(schema.properties) ? schema.properties : null;
|
|
7647
7663
|
return {
|
|
7648
7664
|
schemaChars,
|
|
7665
|
+
schemaHash: stableJsonHash(schema),
|
|
7649
7666
|
propertiesCount: properties ? Object.keys(properties).length : null
|
|
7650
7667
|
};
|
|
7651
7668
|
}
|
|
7669
|
+
function sha256Text(value) {
|
|
7670
|
+
return createHash("sha256").update(value).digest("hex");
|
|
7671
|
+
}
|
|
7672
|
+
function normalizeForStableHash(value) {
|
|
7673
|
+
if (Array.isArray(value)) return value.map((entry) => normalizeForStableHash(entry));
|
|
7674
|
+
if (value && typeof value === "object") {
|
|
7675
|
+
const record = value;
|
|
7676
|
+
return Object.fromEntries(Object.keys(record).toSorted((left, right) => left.localeCompare(right)).map((key) => [key, normalizeForStableHash(record[key])]));
|
|
7677
|
+
}
|
|
7678
|
+
return value;
|
|
7679
|
+
}
|
|
7680
|
+
function stableJsonHash(value) {
|
|
7681
|
+
return sha256Text(JSON.stringify(normalizeForStableHash(value)) ?? "null");
|
|
7682
|
+
}
|
|
7652
7683
|
function buildCodexBootstrapInjectionStats(params) {
|
|
7653
7684
|
const injectedIndex = indexCodexContextFileContent(params.injectedFiles);
|
|
7654
7685
|
const developerInstructionIndex = indexCodexContextFileContent(params.developerInstructionFiles ?? []);
|
|
@@ -7822,9 +7853,11 @@ function isMissingCodexBootstrapContextFile(file) {
|
|
|
7822
7853
|
function remapCodexContextFilePath(params) {
|
|
7823
7854
|
const relativePath = path.relative(params.sourceWorkspaceDir, params.file.path);
|
|
7824
7855
|
if (!relativePath || relativePath === ".." || relativePath.startsWith(`..${path.sep}`) || path.isAbsolute(relativePath) || params.sourceWorkspaceDir === params.targetWorkspaceDir) return params.file;
|
|
7856
|
+
const targetUsesPosixSeparators = params.targetWorkspaceDir.includes("/") && !params.targetWorkspaceDir.includes("\\");
|
|
7857
|
+
const normalizedRelativePath = targetUsesPosixSeparators ? relativePath.replaceAll("\\", "/") : relativePath.replaceAll("/", "\\");
|
|
7825
7858
|
return {
|
|
7826
7859
|
...params.file,
|
|
7827
|
-
path: path.join(params.targetWorkspaceDir,
|
|
7860
|
+
path: targetUsesPosixSeparators ? path.posix.join(params.targetWorkspaceDir, normalizedRelativePath) : path.win32.join(params.targetWorkspaceDir, normalizedRelativePath)
|
|
7828
7861
|
};
|
|
7829
7862
|
}
|
|
7830
7863
|
function compareCodexContextFiles(left, right) {
|
|
@@ -7861,6 +7894,21 @@ async function mirrorTranscriptBestEffort(params) {
|
|
|
7861
7894
|
embeddedAgentLog.warn("failed to mirror codex app-server transcript", { error });
|
|
7862
7895
|
}
|
|
7863
7896
|
}
|
|
7897
|
+
async function mirrorPromptAtTurnStartBestEffort(params) {
|
|
7898
|
+
if (params.params.suppressNextUserMessagePersistence) return;
|
|
7899
|
+
try {
|
|
7900
|
+
await mirrorCodexAppServerTranscript({
|
|
7901
|
+
sessionFile: params.params.sessionFile,
|
|
7902
|
+
agentId: params.agentId,
|
|
7903
|
+
sessionKey: params.sessionKey,
|
|
7904
|
+
messages: [attachCodexMirrorIdentity(buildCodexUserPromptMessage(params.params), `${params.turnId}:prompt`)],
|
|
7905
|
+
idempotencyScope: `codex-app-server:${params.threadId}`,
|
|
7906
|
+
config: params.params.config
|
|
7907
|
+
});
|
|
7908
|
+
} catch (error) {
|
|
7909
|
+
embeddedAgentLog.warn("failed to mirror codex app-server prompt at turn start", { error });
|
|
7910
|
+
}
|
|
7911
|
+
}
|
|
7864
7912
|
function isNonEmptyString(value) {
|
|
7865
7913
|
return typeof value === "string" && value.length > 0;
|
|
7866
7914
|
}
|
|
@@ -7907,6 +7955,7 @@ function handleApprovalRequest(params) {
|
|
|
7907
7955
|
threadId: params.threadId,
|
|
7908
7956
|
turnId: params.turnId,
|
|
7909
7957
|
nativeHookRelay: params.nativeHookRelay,
|
|
7958
|
+
autoApprove: params.autoApprove,
|
|
7910
7959
|
signal: params.signal
|
|
7911
7960
|
});
|
|
7912
7961
|
}
|