@openclaw/codex 2026.5.16-beta.4 → 2026.5.16-beta.6
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/{command-handlers-jZV_1Ks9.js → command-handlers-DcoFMn4e.js} +86 -32
- package/dist/harness.js +6 -3
- package/dist/index.js +2 -2
- package/dist/{node-cli-sessions-BKhlcAB9.js → node-cli-sessions-C9rlYMPw.js} +79 -31
- package/dist/{run-attempt-DMKAwtUV.js → run-attempt-D6sdcUE0.js} +425 -119
- package/dist/{side-question-BYYJZq23.js → side-question-BzVnOoBU.js} +103 -16
- package/dist/test-api.js +1 -1
- package/dist/{thread-lifecycle-wcyYqwrl.js → thread-lifecycle-Cc_ljZLZ.js} +243 -21
- package/dist/{vision-tools-Cm_YicZb.js → vision-tools-BX9YuTEK.js} +203 -7
- package/package.json +5 -5
|
@@ -5,15 +5,19 @@ import { r as isCodexAppServerApprovalRequest } from "./client-6FkrXfaz.js";
|
|
|
5
5
|
import { u as formatCodexUsageLimitErrorMessage } from "./command-formatters-BRW7_Nu7.js";
|
|
6
6
|
import { i as getSharedCodexAppServerClient, s as refreshCodexAppServerAuthTokens } from "./shared-client-DlvmoLBJ.js";
|
|
7
7
|
import { i as readCodexAppServerBinding } from "./session-binding-DqApZIgD.js";
|
|
8
|
-
import { b as createCodexDynamicToolBridge, d as resolveReasoningEffort,
|
|
9
|
-
import {
|
|
8
|
+
import { S as filterCodexDynamicTools, T as resolveCodexDynamicToolsLoading, b as createCodexDynamicToolBridge, d as resolveReasoningEffort, h as mergeCodexThreadConfigs, n as buildCodexRuntimeThreadConfig, u as resolveCodexAppServerModelProvider } from "./thread-lifecycle-Cc_ljZLZ.js";
|
|
9
|
+
import { a as handleCodexAppServerElicitationRequest, i as buildCodexNativeHookRelayDisabledConfig, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as handleCodexAppServerApprovalRequest, r as buildCodexNativeHookRelayConfig, t as filterToolsForVisionInputs } from "./vision-tools-BX9YuTEK.js";
|
|
10
10
|
import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.js";
|
|
11
|
-
import { embeddedAgentLog, formatErrorMessage, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
11
|
+
import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
12
12
|
//#region extensions/codex/src/app-server/side-question.ts
|
|
13
13
|
const CODEX_SIDE_DYNAMIC_TOOL_TIMEOUT_MS = 3e4;
|
|
14
14
|
const CODEX_SIDE_DYNAMIC_TOOL_MAX_TIMEOUT_MS = 6e5;
|
|
15
15
|
const CODEX_SIDE_DYNAMIC_IMAGE_TOOL_TIMEOUT_MS = 6e4;
|
|
16
16
|
const SIDE_QUESTION_COMPLETION_TIMEOUT_MS = 6e5;
|
|
17
|
+
const CODEX_SIDE_NATIVE_HOOK_RELAY_MIN_TTL_MS = 30 * 6e4;
|
|
18
|
+
const CODEX_SIDE_NATIVE_HOOK_RELAY_TTL_GRACE_MS = 5 * 6e4;
|
|
19
|
+
const CODEX_SIDE_NATIVE_HOOK_RELAY_STARTUP_REQUEST_COUNT = 3;
|
|
20
|
+
const CODEX_SIDE_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS = CODEX_NATIVE_HOOK_RELAY_EVENTS.filter((event) => event !== "permission_request");
|
|
17
21
|
const SIDE_BOUNDARY_PROMPT = `Side conversation boundary.
|
|
18
22
|
|
|
19
23
|
Everything before this boundary is inherited history from the parent thread. It is reference context only. It is not your current task.
|
|
@@ -63,6 +67,7 @@ async function runCodexAppServerSideQuestion(params, options = {}) {
|
|
|
63
67
|
let childThreadId;
|
|
64
68
|
let turnId;
|
|
65
69
|
let removeRequestHandler;
|
|
70
|
+
let nativeHookRelay;
|
|
66
71
|
try {
|
|
67
72
|
const cwd = binding.cwd || params.workspaceDir || process.cwd();
|
|
68
73
|
const sideRunParams = buildSideRunAttemptParams(params, {
|
|
@@ -103,6 +108,7 @@ async function runCodexAppServerSideQuestion(params, options = {}) {
|
|
|
103
108
|
paramsForRun: sideRunParams,
|
|
104
109
|
threadId: childThreadId,
|
|
105
110
|
turnId,
|
|
111
|
+
nativeHookRelay,
|
|
106
112
|
signal: runAbortController.signal
|
|
107
113
|
});
|
|
108
114
|
if (request.method !== "item/tool/call") return;
|
|
@@ -122,6 +128,36 @@ async function runCodexAppServerSideQuestion(params, options = {}) {
|
|
|
122
128
|
const approvalPolicy = binding.approvalPolicy ?? appServer.approvalPolicy;
|
|
123
129
|
const sandbox = binding.sandbox ?? appServer.sandbox;
|
|
124
130
|
const serviceTier = binding.serviceTier ?? appServer.serviceTier;
|
|
131
|
+
const nativeHookRelayEvents = resolveCodexSideNativeHookRelayEvents({
|
|
132
|
+
configuredEvents: options.nativeHookRelay?.events,
|
|
133
|
+
approvalPolicy
|
|
134
|
+
});
|
|
135
|
+
nativeHookRelay = options.nativeHookRelay ? registerCodexSideNativeHookRelay({
|
|
136
|
+
options: options.nativeHookRelay,
|
|
137
|
+
events: nativeHookRelayEvents,
|
|
138
|
+
agentId: sessionAgentId,
|
|
139
|
+
sessionId: params.sessionId,
|
|
140
|
+
sessionKey: params.sessionKey,
|
|
141
|
+
config: params.cfg,
|
|
142
|
+
runId: sideRunParams.runId,
|
|
143
|
+
channelId: buildAgentHookContextChannelFields({
|
|
144
|
+
sessionKey: params.sessionKey,
|
|
145
|
+
messageChannel: params.messageChannel,
|
|
146
|
+
messageProvider: params.messageProvider,
|
|
147
|
+
currentChannelId: params.currentChannelId
|
|
148
|
+
}).channelId,
|
|
149
|
+
requestTimeoutMs: appServer.requestTimeoutMs,
|
|
150
|
+
completionTimeoutMs: Math.max(appServer.turnCompletionIdleTimeoutMs, SIDE_QUESTION_COMPLETION_TIMEOUT_MS),
|
|
151
|
+
signal: runAbortController.signal
|
|
152
|
+
}) : void 0;
|
|
153
|
+
const nativeHookRelayConfig = nativeHookRelay ? buildCodexNativeHookRelayConfig({
|
|
154
|
+
relay: nativeHookRelay,
|
|
155
|
+
events: nativeHookRelayEvents,
|
|
156
|
+
hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec,
|
|
157
|
+
clearOmittedEvents: true
|
|
158
|
+
}) : options.nativeHookRelay?.enabled === false ? buildCodexNativeHookRelayDisabledConfig() : void 0;
|
|
159
|
+
const runtimeThreadConfig = buildCodexRuntimeThreadConfig(void 0);
|
|
160
|
+
const threadConfig = mergeCodexThreadConfigs(nativeHookRelayConfig, runtimeThreadConfig) ?? runtimeThreadConfig;
|
|
125
161
|
const modelProvider = resolveCodexAppServerModelProvider({
|
|
126
162
|
provider: params.provider,
|
|
127
163
|
authProfileId,
|
|
@@ -137,7 +173,7 @@ async function runCodexAppServerSideQuestion(params, options = {}) {
|
|
|
137
173
|
approvalsReviewer: appServer.approvalsReviewer,
|
|
138
174
|
sandbox,
|
|
139
175
|
...serviceTier ? { serviceTier } : {},
|
|
140
|
-
config:
|
|
176
|
+
config: threadConfig,
|
|
141
177
|
developerInstructions: SIDE_DEVELOPER_INSTRUCTIONS,
|
|
142
178
|
ephemeral: true,
|
|
143
179
|
threadSource: "user"
|
|
@@ -184,18 +220,51 @@ async function runCodexAppServerSideQuestion(params, options = {}) {
|
|
|
184
220
|
if (!trimmed) throw new Error("Codex /btw completed without an answer.");
|
|
185
221
|
return { text: trimmed };
|
|
186
222
|
} finally {
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
223
|
+
try {
|
|
224
|
+
params.opts?.abortSignal?.removeEventListener("abort", abortFromUpstream);
|
|
225
|
+
if (!runAbortController.signal.aborted) runAbortController.abort("codex_side_question_finished");
|
|
226
|
+
removeNotificationHandler();
|
|
227
|
+
removeRequestHandler?.();
|
|
228
|
+
await cleanupCodexSideThread(client, {
|
|
229
|
+
threadId: childThreadId,
|
|
230
|
+
turnId,
|
|
231
|
+
interrupt: !collector.completed,
|
|
232
|
+
timeoutMs: appServer.requestTimeoutMs
|
|
233
|
+
});
|
|
234
|
+
} finally {
|
|
235
|
+
nativeHookRelay?.unregister();
|
|
236
|
+
}
|
|
197
237
|
}
|
|
198
238
|
}
|
|
239
|
+
function resolveCodexSideNativeHookRelayEvents(params) {
|
|
240
|
+
if (params.configuredEvents?.length) return params.configuredEvents;
|
|
241
|
+
return params.approvalPolicy === "never" ? CODEX_NATIVE_HOOK_RELAY_EVENTS : CODEX_SIDE_NATIVE_HOOK_RELAY_EVENTS_WITH_APP_SERVER_APPROVALS;
|
|
242
|
+
}
|
|
243
|
+
function registerCodexSideNativeHookRelay(params) {
|
|
244
|
+
if (params.options.enabled === false) return;
|
|
245
|
+
return registerNativeHookRelay({
|
|
246
|
+
provider: "codex",
|
|
247
|
+
...params.agentId ? { agentId: params.agentId } : {},
|
|
248
|
+
sessionId: params.sessionId,
|
|
249
|
+
...params.sessionKey ? { sessionKey: params.sessionKey } : {},
|
|
250
|
+
...params.config ? { config: params.config } : {},
|
|
251
|
+
runId: params.runId,
|
|
252
|
+
...params.channelId ? { channelId: params.channelId } : {},
|
|
253
|
+
allowedEvents: params.events,
|
|
254
|
+
ttlMs: resolveCodexSideNativeHookRelayTtlMs({
|
|
255
|
+
explicitTtlMs: params.options.ttlMs,
|
|
256
|
+
requestTimeoutMs: params.requestTimeoutMs,
|
|
257
|
+
completionTimeoutMs: params.completionTimeoutMs
|
|
258
|
+
}),
|
|
259
|
+
signal: params.signal,
|
|
260
|
+
command: { timeoutMs: params.options.gatewayTimeoutMs }
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
function resolveCodexSideNativeHookRelayTtlMs(params) {
|
|
264
|
+
if (params.explicitTtlMs !== void 0) return params.explicitTtlMs;
|
|
265
|
+
const relayBudgetMs = params.requestTimeoutMs * CODEX_SIDE_NATIVE_HOOK_RELAY_STARTUP_REQUEST_COUNT + params.completionTimeoutMs + CODEX_SIDE_NATIVE_HOOK_RELAY_TTL_GRACE_MS;
|
|
266
|
+
return Math.max(CODEX_SIDE_NATIVE_HOOK_RELAY_MIN_TTL_MS, Math.floor(relayBudgetMs));
|
|
267
|
+
}
|
|
199
268
|
function buildSideRunAttemptParams(params, options) {
|
|
200
269
|
return {
|
|
201
270
|
params,
|
|
@@ -211,6 +280,9 @@ function buildSideRunAttemptParams(params, options) {
|
|
|
211
280
|
sessionFile: params.sessionFile,
|
|
212
281
|
sessionKey: params.sessionKey,
|
|
213
282
|
agentId: params.agentId,
|
|
283
|
+
...params.messageChannel ? { messageChannel: params.messageChannel } : {},
|
|
284
|
+
...params.messageProvider ? { messageProvider: params.messageProvider } : {},
|
|
285
|
+
...params.currentChannelId ? { currentChannelId: params.currentChannelId } : {},
|
|
214
286
|
workspaceDir: options.cwd,
|
|
215
287
|
authProfileId: options.authProfileId,
|
|
216
288
|
authProfileIdSource: params.authProfileIdSource,
|
|
@@ -262,6 +334,14 @@ async function createCodexSideToolBridge(input) {
|
|
|
262
334
|
modelApi: runtimeModel.api,
|
|
263
335
|
modelContextWindowTokens: runtimeModel.contextWindow,
|
|
264
336
|
modelAuthMode: resolveModelAuthMode(runtimeModel.provider, input.params.cfg, void 0, { workspaceDir: input.cwd }),
|
|
337
|
+
...input.params.messageProvider || input.params.messageChannel ? { messageProvider: input.params.messageProvider ?? input.params.messageChannel } : {},
|
|
338
|
+
...input.params.currentChannelId ? { currentChannelId: input.params.currentChannelId } : {},
|
|
339
|
+
hookChannelId: buildAgentHookContextChannelFields({
|
|
340
|
+
sessionKey: input.params.sessionKey,
|
|
341
|
+
messageChannel: input.params.messageChannel,
|
|
342
|
+
messageProvider: input.params.messageProvider,
|
|
343
|
+
currentChannelId: input.params.currentChannelId
|
|
344
|
+
}).channelId,
|
|
265
345
|
sandbox,
|
|
266
346
|
modelHasVision: runtimeModel.input?.includes("image") ?? false,
|
|
267
347
|
requireExplicitMessageTarget: true
|
|
@@ -270,16 +350,23 @@ async function createCodexSideToolBridge(input) {
|
|
|
270
350
|
hasInboundImages: false
|
|
271
351
|
});
|
|
272
352
|
}
|
|
353
|
+
const hookChannelFields = buildAgentHookContextChannelFields({
|
|
354
|
+
sessionKey: input.params.sessionKey,
|
|
355
|
+
messageChannel: input.params.messageChannel,
|
|
356
|
+
messageProvider: input.params.messageProvider,
|
|
357
|
+
currentChannelId: input.params.currentChannelId
|
|
358
|
+
});
|
|
273
359
|
return createCodexDynamicToolBridge({
|
|
274
360
|
tools,
|
|
275
361
|
signal: input.signal,
|
|
276
|
-
loading: input.pluginConfig
|
|
362
|
+
loading: resolveCodexDynamicToolsLoading(input.pluginConfig),
|
|
277
363
|
hookContext: {
|
|
278
364
|
agentId: input.sessionAgentId,
|
|
279
365
|
config: input.params.cfg,
|
|
280
366
|
sessionId: input.params.sessionId,
|
|
281
367
|
sessionKey: input.params.sessionKey,
|
|
282
|
-
runId: input.params.opts?.runId ?? `codex-btw:${input.params.sessionId}
|
|
368
|
+
runId: input.params.opts?.runId ?? `codex-btw:${input.params.sessionId}`,
|
|
369
|
+
...hookChannelFields
|
|
283
370
|
}
|
|
284
371
|
});
|
|
285
372
|
}
|
package/dist/test-api.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { c as resolveCodexAppServerRuntimeOptions } from "./config-B5pq6hEz.js";
|
|
2
|
-
import { a as buildThreadResumeParams, b as createCodexDynamicToolBridge, i as buildDeveloperInstructions, o as buildThreadStartParams, s as buildTurnStartParams
|
|
2
|
+
import { S as filterCodexDynamicTools, a as buildThreadResumeParams, b as createCodexDynamicToolBridge, i as buildDeveloperInstructions, o as buildThreadStartParams, s as buildTurnStartParams } from "./thread-lifecycle-Cc_ljZLZ.js";
|
|
3
3
|
//#region extensions/codex/test-api.ts
|
|
4
4
|
function resolveCodexPromptSnapshotAppServerOptions(pluginConfig) {
|
|
5
5
|
return resolveCodexAppServerRuntimeOptions({
|
|
@@ -8,6 +8,7 @@ import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile,
|
|
|
8
8
|
import { a as defaultCodexAppInventoryCache, r as readCodexPluginInventory, t as ensureCodexPluginActivation } from "./plugin-activation-B49xb7pI.js";
|
|
9
9
|
import crypto from "node:crypto";
|
|
10
10
|
import { HEARTBEAT_RESPONSE_TOOL_NAME, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractToolResultMediaArtifact, filterToolResultMediaUrls, isActiveHarnessContextEngine, isMessagingTool, isMessagingToolSendAction, isToolWrappedWithBeforeToolCallHook, normalizeHeartbeatToolResponse, runAgentHarnessAfterToolCallHook, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
11
|
+
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
11
12
|
import { buildCodexUserMcpServersThreadConfigPatch } from "openclaw/plugin-sdk/codex-mcp-projection";
|
|
12
13
|
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
13
14
|
//#region extensions/codex/src/app-server/dynamic-tool-profile.ts
|
|
@@ -32,9 +33,15 @@ function normalizeCodexDynamicToolName(name) {
|
|
|
32
33
|
const normalized = name.trim().toLowerCase();
|
|
33
34
|
return DYNAMIC_TOOL_NAME_ALIASES[normalized] ?? normalized;
|
|
34
35
|
}
|
|
35
|
-
function
|
|
36
|
+
function isForcedPrivateQaCodexRuntime(env = process.env) {
|
|
37
|
+
return env.OPENCLAW_BUILD_PRIVATE_QA === "1" && env.OPENCLAW_QA_FORCE_RUNTIME?.trim().toLowerCase() === "codex";
|
|
38
|
+
}
|
|
39
|
+
function resolveCodexDynamicToolsLoading(config, env = process.env) {
|
|
40
|
+
return isForcedPrivateQaCodexRuntime(env) ? "direct" : config.codexDynamicToolsLoading ?? "searchable";
|
|
41
|
+
}
|
|
42
|
+
function filterCodexDynamicTools(tools, config, env = process.env) {
|
|
36
43
|
const excludes = /* @__PURE__ */ new Set();
|
|
37
|
-
for (const name of CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES) excludes.add(name);
|
|
44
|
+
if (!isForcedPrivateQaCodexRuntime(env)) for (const name of CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES) excludes.add(name);
|
|
38
45
|
for (const name of config.codexDynamicToolsExclude ?? []) {
|
|
39
46
|
const trimmed = normalizeCodexDynamicToolName(name);
|
|
40
47
|
if (trimmed) excludes.add(trimmed);
|
|
@@ -42,11 +49,113 @@ function filterCodexDynamicTools(tools, config) {
|
|
|
42
49
|
return excludes.size === 0 ? tools : tools.filter((tool) => !excludes.has(normalizeCodexDynamicToolName(tool.name)));
|
|
43
50
|
}
|
|
44
51
|
//#endregion
|
|
52
|
+
//#region extensions/codex/src/app-server/image-payload-sanitizer.ts
|
|
53
|
+
const DATA_URL_PREFIX = "data:";
|
|
54
|
+
const IMAGE_OMITTED_TEXT = "omitted image payload: invalid inline image data";
|
|
55
|
+
function startsWithDataUrl(value) {
|
|
56
|
+
return value.slice(0, 5).toLowerCase() === DATA_URL_PREFIX;
|
|
57
|
+
}
|
|
58
|
+
function canonicalizeBase64(base64) {
|
|
59
|
+
let cleaned = "";
|
|
60
|
+
let padding = 0;
|
|
61
|
+
let sawPadding = false;
|
|
62
|
+
for (let i = 0; i < base64.length; i += 1) {
|
|
63
|
+
const code = base64.charCodeAt(i);
|
|
64
|
+
if (code <= 32) continue;
|
|
65
|
+
if (code === 61) {
|
|
66
|
+
padding += 1;
|
|
67
|
+
if (padding > 2) return;
|
|
68
|
+
sawPadding = true;
|
|
69
|
+
cleaned += "=";
|
|
70
|
+
continue;
|
|
71
|
+
}
|
|
72
|
+
if (sawPadding || !(code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 43 || code === 47)) return;
|
|
73
|
+
cleaned += base64[i];
|
|
74
|
+
}
|
|
75
|
+
if (!cleaned || cleaned.length % 4 !== 0) return;
|
|
76
|
+
return cleaned;
|
|
77
|
+
}
|
|
78
|
+
function sniffImageMime(buffer) {
|
|
79
|
+
if (buffer.length >= 8 && buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71 && buffer[4] === 13 && buffer[5] === 10 && buffer[6] === 26 && buffer[7] === 10) return "image/png";
|
|
80
|
+
if (buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255) return "image/jpeg";
|
|
81
|
+
if (buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP") return "image/webp";
|
|
82
|
+
if (buffer.length >= 6 && (buffer.subarray(0, 6).toString("ascii") === "GIF87a" || buffer.subarray(0, 6).toString("ascii") === "GIF89a")) return "image/gif";
|
|
83
|
+
}
|
|
84
|
+
function sanitizeInlineImageDataUrl(imageUrl) {
|
|
85
|
+
if (!startsWithDataUrl(imageUrl)) return imageUrl;
|
|
86
|
+
const commaIndex = imageUrl.indexOf(",");
|
|
87
|
+
if (commaIndex < 0) return;
|
|
88
|
+
const metadata = imageUrl.slice(5, commaIndex);
|
|
89
|
+
const payload = imageUrl.slice(commaIndex + 1);
|
|
90
|
+
const metadataParts = metadata.split(";").map((part) => part.trim());
|
|
91
|
+
if (!(metadataParts[0]?.toLowerCase())?.startsWith("image/")) return;
|
|
92
|
+
if (!metadataParts.slice(1).some((part) => part.toLowerCase() === "base64")) return;
|
|
93
|
+
const canonicalPayload = canonicalizeBase64(payload);
|
|
94
|
+
if (!canonicalPayload) return;
|
|
95
|
+
const sniffedMimeType = sniffImageMime(Buffer.from(canonicalPayload, "base64"));
|
|
96
|
+
if (!sniffedMimeType) return;
|
|
97
|
+
return `data:${sniffedMimeType};base64,${canonicalPayload}`;
|
|
98
|
+
}
|
|
99
|
+
function invalidInlineImageText(label) {
|
|
100
|
+
return `[${label}] ${IMAGE_OMITTED_TEXT}`;
|
|
101
|
+
}
|
|
102
|
+
function isRecord$1(value) {
|
|
103
|
+
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
104
|
+
}
|
|
105
|
+
function sanitizeImageContentRecord(record, label) {
|
|
106
|
+
if (record.type === "image" && typeof record.data === "string") {
|
|
107
|
+
const mimeType = typeof record.mimeType === "string" ? record.mimeType : "image/png";
|
|
108
|
+
const imageUrl = sanitizeInlineImageDataUrl(`data:${mimeType};base64,${record.data}`);
|
|
109
|
+
if (!imageUrl) return {
|
|
110
|
+
type: "text",
|
|
111
|
+
text: invalidInlineImageText(label)
|
|
112
|
+
};
|
|
113
|
+
const commaIndex = imageUrl.indexOf(",");
|
|
114
|
+
const mime = imageUrl.slice(5, commaIndex).split(";")[0] ?? mimeType;
|
|
115
|
+
return {
|
|
116
|
+
...record,
|
|
117
|
+
mimeType: mime,
|
|
118
|
+
data: imageUrl.slice(commaIndex + 1)
|
|
119
|
+
};
|
|
120
|
+
}
|
|
121
|
+
if (record.type === "inputImage" && typeof record.imageUrl === "string") {
|
|
122
|
+
const imageUrl = sanitizeInlineImageDataUrl(record.imageUrl);
|
|
123
|
+
return imageUrl ? {
|
|
124
|
+
...record,
|
|
125
|
+
imageUrl
|
|
126
|
+
} : {
|
|
127
|
+
type: "inputText",
|
|
128
|
+
text: invalidInlineImageText(label)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
if (record.type === "input_image" && typeof record.image_url === "string") {
|
|
132
|
+
const imageUrl = sanitizeInlineImageDataUrl(record.image_url);
|
|
133
|
+
return imageUrl ? {
|
|
134
|
+
...record,
|
|
135
|
+
image_url: imageUrl
|
|
136
|
+
} : {
|
|
137
|
+
type: "input_text",
|
|
138
|
+
text: invalidInlineImageText(label)
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
function sanitizeCodexHistoryImagePayloads(value, label) {
|
|
143
|
+
if (Array.isArray(value)) return value.map((entry) => sanitizeCodexHistoryImagePayloads(entry, label));
|
|
144
|
+
if (!isRecord$1(value)) return value;
|
|
145
|
+
const imageRecord = sanitizeImageContentRecord(value, label);
|
|
146
|
+
if (imageRecord) return imageRecord;
|
|
147
|
+
const next = {};
|
|
148
|
+
for (const [key, child] of Object.entries(value)) next[key] = sanitizeCodexHistoryImagePayloads(child, label);
|
|
149
|
+
return next;
|
|
150
|
+
}
|
|
151
|
+
//#endregion
|
|
45
152
|
//#region extensions/codex/src/app-server/dynamic-tools.ts
|
|
46
153
|
const CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE = "openclaw";
|
|
47
154
|
const ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES = new Set(["sessions_yield"]);
|
|
155
|
+
const DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS = 16e3;
|
|
48
156
|
function createCodexDynamicToolBridge(params) {
|
|
49
157
|
const toolResultHookContext = toToolResultHookContext(params.hookContext);
|
|
158
|
+
const toolResultMaxChars = resolveCodexDynamicToolResultMaxChars(params.hookContext);
|
|
50
159
|
const tools = params.tools.map((tool) => isToolWrappedWithBeforeToolCallHook(tool) ? tool : wrapToolWithBeforeToolCallHook(tool, params.hookContext));
|
|
51
160
|
const toolMap = new Map(tools.map((tool) => [tool.name, tool]));
|
|
52
161
|
const telemetry = {
|
|
@@ -120,12 +229,13 @@ function createCodexDynamicToolBridge(params) {
|
|
|
120
229
|
agentId: toolResultHookContext.agentId,
|
|
121
230
|
sessionId: toolResultHookContext.sessionId,
|
|
122
231
|
sessionKey: toolResultHookContext.sessionKey,
|
|
232
|
+
channelId: toolResultHookContext.channelId,
|
|
123
233
|
startArgs: args,
|
|
124
234
|
result,
|
|
125
235
|
startedAt
|
|
126
236
|
});
|
|
127
237
|
return {
|
|
128
|
-
contentItems: result.content
|
|
238
|
+
contentItems: convertToolContents(result.content, toolResultMaxChars),
|
|
129
239
|
success: !resultIsError
|
|
130
240
|
};
|
|
131
241
|
} catch (error) {
|
|
@@ -143,6 +253,7 @@ function createCodexDynamicToolBridge(params) {
|
|
|
143
253
|
agentId: toolResultHookContext.agentId,
|
|
144
254
|
sessionId: toolResultHookContext.sessionId,
|
|
145
255
|
sessionKey: toolResultHookContext.sessionKey,
|
|
256
|
+
channelId: toolResultHookContext.channelId,
|
|
146
257
|
startArgs: args,
|
|
147
258
|
error: error instanceof Error ? error.message : String(error),
|
|
148
259
|
startedAt
|
|
@@ -172,14 +283,34 @@ function createCodexDynamicToolSpec(params) {
|
|
|
172
283
|
};
|
|
173
284
|
}
|
|
174
285
|
function toToolResultHookContext(ctx) {
|
|
175
|
-
const { agentId, sessionId, sessionKey, runId } = ctx ?? {};
|
|
286
|
+
const { agentId, sessionId, sessionKey, runId, channelId } = ctx ?? {};
|
|
176
287
|
return {
|
|
177
288
|
...agentId && { agentId },
|
|
178
289
|
...sessionId && { sessionId },
|
|
179
290
|
...sessionKey && { sessionKey },
|
|
180
|
-
...runId && { runId }
|
|
291
|
+
...runId && { runId },
|
|
292
|
+
...channelId && { channelId }
|
|
181
293
|
};
|
|
182
294
|
}
|
|
295
|
+
function resolveCodexDynamicToolResultMaxChars(ctx) {
|
|
296
|
+
return resolveAgentContextLimitValue({
|
|
297
|
+
config: ctx?.config,
|
|
298
|
+
agentId: ctx?.agentId,
|
|
299
|
+
key: "toolResultMaxChars"
|
|
300
|
+
}) ?? DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS;
|
|
301
|
+
}
|
|
302
|
+
function resolveAgentContextLimitValue(params) {
|
|
303
|
+
const agents = readRecord(params.config?.agents);
|
|
304
|
+
const defaultValue = readPositiveInteger(readRecord(readRecord(agents?.defaults)?.contextLimits)?.[params.key]);
|
|
305
|
+
if (!params.agentId) return defaultValue;
|
|
306
|
+
const list = agents?.list;
|
|
307
|
+
if (!Array.isArray(list)) return defaultValue;
|
|
308
|
+
const normalizedAgentId = normalizeAgentId(params.agentId);
|
|
309
|
+
return readPositiveInteger(readRecord(readRecord(list.find((entry) => {
|
|
310
|
+
const entryId = readRecord(entry)?.id;
|
|
311
|
+
return typeof entryId === "string" && normalizeAgentId(entryId) === normalizedAgentId;
|
|
312
|
+
}))?.contextLimits)?.[params.key]) ?? defaultValue;
|
|
313
|
+
}
|
|
183
314
|
function composeAbortSignals(...signals) {
|
|
184
315
|
const activeSignals = signals.filter((signal) => Boolean(signal));
|
|
185
316
|
if (activeSignals.length === 0) return new AbortController().signal;
|
|
@@ -261,6 +392,13 @@ function extractInternalSourceReplyPayload(details) {
|
|
|
261
392
|
function isRecord(value) {
|
|
262
393
|
return value !== null && typeof value === "object" && !Array.isArray(value);
|
|
263
394
|
}
|
|
395
|
+
function readRecord(value) {
|
|
396
|
+
return isRecord(value) ? value : void 0;
|
|
397
|
+
}
|
|
398
|
+
function readPositiveInteger(value) {
|
|
399
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value <= 0) return;
|
|
400
|
+
return Math.floor(value);
|
|
401
|
+
}
|
|
264
402
|
function isToolResultError(result) {
|
|
265
403
|
const details = result.details;
|
|
266
404
|
if (!isRecord(details)) return false;
|
|
@@ -270,14 +408,66 @@ function isToolResultError(result) {
|
|
|
270
408
|
const status = details.status.trim().toLowerCase();
|
|
271
409
|
return status !== "" && status !== "0" && status !== "ok" && status !== "success" && status !== "completed" && status !== "recorded" && status !== "running";
|
|
272
410
|
}
|
|
411
|
+
function normalizeToolResultMaxChars(maxChars) {
|
|
412
|
+
return typeof maxChars === "number" && Number.isFinite(maxChars) && maxChars > 0 ? Math.floor(maxChars) : DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS;
|
|
413
|
+
}
|
|
414
|
+
function convertToolContents(content, toolResultMaxChars = DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS) {
|
|
415
|
+
const maxChars = normalizeToolResultMaxChars(toolResultMaxChars);
|
|
416
|
+
const totalTextChars = content.reduce((total, item) => total + (item.type === "text" ? item.text.length : 0), 0);
|
|
417
|
+
if (totalTextChars <= maxChars) return content.flatMap(convertToolContent);
|
|
418
|
+
const noticeText = `...(OpenClaw truncated dynamic tool result: original ${totalTextChars} chars, showing ${maxChars}; rerun with narrower args.)`;
|
|
419
|
+
const notice = `\n${noticeText}`;
|
|
420
|
+
let remainingTextBudget = Math.max(0, maxChars - notice.length);
|
|
421
|
+
let appendedNotice = false;
|
|
422
|
+
const output = [];
|
|
423
|
+
for (const item of content) {
|
|
424
|
+
if (item.type !== "text") {
|
|
425
|
+
output.push(...convertToolContent(item));
|
|
426
|
+
continue;
|
|
427
|
+
}
|
|
428
|
+
if (appendedNotice) continue;
|
|
429
|
+
if (notice.length >= maxChars) {
|
|
430
|
+
output.push({
|
|
431
|
+
type: "inputText",
|
|
432
|
+
text: noticeText.slice(0, maxChars)
|
|
433
|
+
});
|
|
434
|
+
appendedNotice = true;
|
|
435
|
+
continue;
|
|
436
|
+
}
|
|
437
|
+
const sliceLength = Math.min(item.text.length, remainingTextBudget);
|
|
438
|
+
remainingTextBudget -= sliceLength;
|
|
439
|
+
const shouldAppendNotice = remainingTextBudget <= 0;
|
|
440
|
+
const text = item.text.slice(0, sliceLength);
|
|
441
|
+
if (shouldAppendNotice) {
|
|
442
|
+
output.push({
|
|
443
|
+
type: "inputText",
|
|
444
|
+
text: `${text.trimEnd()}${notice}`.slice(0, maxChars)
|
|
445
|
+
});
|
|
446
|
+
appendedNotice = true;
|
|
447
|
+
} else if (text.length > 0) output.push({
|
|
448
|
+
type: "inputText",
|
|
449
|
+
text
|
|
450
|
+
});
|
|
451
|
+
}
|
|
452
|
+
if (!appendedNotice) output.push({
|
|
453
|
+
type: "inputText",
|
|
454
|
+
text: noticeText.slice(0, maxChars)
|
|
455
|
+
});
|
|
456
|
+
return output;
|
|
457
|
+
}
|
|
273
458
|
function convertToolContent(content) {
|
|
274
459
|
if (content.type === "text") return [{
|
|
275
460
|
type: "inputText",
|
|
276
461
|
text: content.text
|
|
277
462
|
}];
|
|
463
|
+
const imageUrl = sanitizeInlineImageDataUrl(`data:${content.mimeType};base64,${content.data}`);
|
|
464
|
+
if (!imageUrl) return [{
|
|
465
|
+
type: "inputText",
|
|
466
|
+
text: invalidInlineImageText("codex dynamic tool")
|
|
467
|
+
}];
|
|
278
468
|
return [{
|
|
279
469
|
type: "inputImage",
|
|
280
|
-
imageUrl
|
|
470
|
+
imageUrl
|
|
281
471
|
}];
|
|
282
472
|
}
|
|
283
473
|
function toJsonValue(value) {
|
|
@@ -379,7 +569,7 @@ function projectContextEngineAssemblyForCodex(params) {
|
|
|
379
569
|
CONTEXT_SAFETY_NOTE,
|
|
380
570
|
"",
|
|
381
571
|
CONTEXT_OPEN,
|
|
382
|
-
|
|
572
|
+
truncateOlderContext(renderedContext, maxRenderedContextChars),
|
|
383
573
|
CONTEXT_CLOSE,
|
|
384
574
|
"",
|
|
385
575
|
REQUEST_HEADER,
|
|
@@ -549,6 +739,17 @@ function resolveTextPartMaxChars(maxRenderedContextChars) {
|
|
|
549
739
|
function truncateText(text, maxChars) {
|
|
550
740
|
return text.length > maxChars ? `${text.slice(0, maxChars)}\n[truncated ${text.length - maxChars} chars]` : text;
|
|
551
741
|
}
|
|
742
|
+
function truncateOlderContext(text, maxChars) {
|
|
743
|
+
if (text.length <= maxChars) return text;
|
|
744
|
+
if (maxChars <= 0) return "";
|
|
745
|
+
const buildMarker = (omittedChars) => `[truncated ${omittedChars} chars from older context]\n`;
|
|
746
|
+
let marker = buildMarker(text.length - maxChars);
|
|
747
|
+
let tailChars = Math.max(0, maxChars - marker.length);
|
|
748
|
+
marker = buildMarker(text.length - tailChars);
|
|
749
|
+
if (marker.length >= maxChars) return marker.slice(0, maxChars);
|
|
750
|
+
tailChars = maxChars - marker.length;
|
|
751
|
+
return `${marker}${text.slice(text.length - tailChars).trimStart()}`;
|
|
752
|
+
}
|
|
552
753
|
//#endregion
|
|
553
754
|
//#region extensions/codex/src/app-server/plugin-thread-config.ts
|
|
554
755
|
const CODEX_PLUGIN_THREAD_CONFIG_INPUT_FINGERPRINT_VERSION = 1;
|
|
@@ -787,11 +988,15 @@ const CODEX_CODE_MODE_THREAD_CONFIG = {
|
|
|
787
988
|
"features.code_mode": true,
|
|
788
989
|
"features.code_mode_only": true
|
|
789
990
|
};
|
|
991
|
+
const CODEX_CODE_MODE_DISABLED_THREAD_CONFIG = {
|
|
992
|
+
"features.code_mode": false,
|
|
993
|
+
"features.code_mode_only": false
|
|
994
|
+
};
|
|
790
995
|
const CODEX_LIGHTWEIGHT_CONTEXT_THREAD_CONFIG = { project_doc_max_bytes: 0 };
|
|
791
996
|
async function startOrResumeThread(params) {
|
|
792
997
|
const dynamicToolsFingerprint = fingerprintDynamicTools(params.dynamicTools);
|
|
793
998
|
const contextEngineBinding = buildContextEngineBinding(params.params, params.contextEngineProjection);
|
|
794
|
-
const userMcpServersConfigPatch = buildCodexUserMcpServersThreadConfigPatch(params.params.config, { agentId: params.agentId ?? params.params.agentId });
|
|
999
|
+
const userMcpServersConfigPatch = params.userMcpServersEnabled === false ? void 0 : buildCodexUserMcpServersThreadConfigPatch(params.params.config, { agentId: params.agentId ?? params.params.agentId });
|
|
795
1000
|
const userMcpServersFingerprint = fingerprintUserMcpServersConfigPatch(userMcpServersConfigPatch);
|
|
796
1001
|
let binding = await readCodexAppServerBinding(params.params.sessionFile, {
|
|
797
1002
|
authProfileStore: params.params.authProfileStore,
|
|
@@ -801,6 +1006,11 @@ async function startOrResumeThread(params) {
|
|
|
801
1006
|
let preserveExistingBinding = false;
|
|
802
1007
|
let rotatedContextEngineBinding = false;
|
|
803
1008
|
let prebuiltPluginThreadConfig;
|
|
1009
|
+
if (binding?.threadId && params.nativeCodeModeEnabled === false) {
|
|
1010
|
+
embeddedAgentLog.debug("codex app-server native tool surface disabled for turn; starting transient thread", { threadId: binding.threadId });
|
|
1011
|
+
preserveExistingBinding = true;
|
|
1012
|
+
binding = void 0;
|
|
1013
|
+
}
|
|
804
1014
|
if (binding?.threadId && (binding.contextEngine || contextEngineBinding)) {
|
|
805
1015
|
if (!contextEngineBinding || !isContextEngineBindingCompatible(binding.contextEngine, contextEngineBinding)) {
|
|
806
1016
|
embeddedAgentLog.debug("codex app-server context-engine binding changed; starting a new thread", {
|
|
@@ -878,7 +1088,8 @@ async function startOrResumeThread(params) {
|
|
|
878
1088
|
authProfileId,
|
|
879
1089
|
appServer: params.appServer,
|
|
880
1090
|
developerInstructions: params.developerInstructions,
|
|
881
|
-
config: resumeConfig
|
|
1091
|
+
config: resumeConfig,
|
|
1092
|
+
nativeCodeModeEnabled: params.nativeCodeModeEnabled
|
|
882
1093
|
})));
|
|
883
1094
|
const boundAuthProfileId = authProfileId;
|
|
884
1095
|
const fallbackModelProvider = resolveCodexAppServerModelProvider({
|
|
@@ -945,7 +1156,8 @@ async function startOrResumeThread(params) {
|
|
|
945
1156
|
dynamicTools: params.dynamicTools,
|
|
946
1157
|
appServer: params.appServer,
|
|
947
1158
|
developerInstructions: params.developerInstructions,
|
|
948
|
-
config
|
|
1159
|
+
config,
|
|
1160
|
+
nativeCodeModeEnabled: params.nativeCodeModeEnabled
|
|
949
1161
|
})));
|
|
950
1162
|
const modelProvider = resolveCodexAppServerModelProvider({
|
|
951
1163
|
provider: params.params.provider,
|
|
@@ -1086,7 +1298,8 @@ function buildThreadStartParams(params, options) {
|
|
|
1086
1298
|
sandbox: options.appServer.sandbox,
|
|
1087
1299
|
...options.appServer.serviceTier ? { serviceTier: options.appServer.serviceTier } : {},
|
|
1088
1300
|
serviceName: "OpenClaw",
|
|
1089
|
-
config: buildCodexRuntimeThreadConfigForRun(params, options.config),
|
|
1301
|
+
config: buildCodexRuntimeThreadConfigForRun(params, options.config, { nativeCodeModeEnabled: options.nativeCodeModeEnabled }),
|
|
1302
|
+
...options.nativeCodeModeEnabled === false ? { environments: [] } : {},
|
|
1090
1303
|
developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params),
|
|
1091
1304
|
dynamicTools: options.dynamicTools,
|
|
1092
1305
|
experimentalRawEvents: true,
|
|
@@ -1109,16 +1322,17 @@ function buildThreadResumeParams(params, options) {
|
|
|
1109
1322
|
approvalsReviewer: options.appServer.approvalsReviewer,
|
|
1110
1323
|
sandbox: options.appServer.sandbox,
|
|
1111
1324
|
...options.appServer.serviceTier ? { serviceTier: options.appServer.serviceTier } : {},
|
|
1112
|
-
config: buildCodexRuntimeThreadConfigForRun(params, options.config),
|
|
1325
|
+
config: buildCodexRuntimeThreadConfigForRun(params, options.config, { nativeCodeModeEnabled: options.nativeCodeModeEnabled }),
|
|
1113
1326
|
developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params),
|
|
1114
1327
|
persistExtendedHistory: true
|
|
1115
1328
|
};
|
|
1116
1329
|
}
|
|
1117
|
-
function buildCodexRuntimeThreadConfig(config) {
|
|
1118
|
-
|
|
1330
|
+
function buildCodexRuntimeThreadConfig(config, options = {}) {
|
|
1331
|
+
const codeModeConfig = options.nativeCodeModeEnabled === false ? CODEX_CODE_MODE_DISABLED_THREAD_CONFIG : CODEX_CODE_MODE_THREAD_CONFIG;
|
|
1332
|
+
return mergeCodexThreadConfigs(config, codeModeConfig) ?? { ...codeModeConfig };
|
|
1119
1333
|
}
|
|
1120
|
-
function buildCodexRuntimeThreadConfigForRun(params, config) {
|
|
1121
|
-
const runtimeConfig = buildCodexRuntimeThreadConfig(config);
|
|
1334
|
+
function buildCodexRuntimeThreadConfigForRun(params, config, options = {}) {
|
|
1335
|
+
const runtimeConfig = buildCodexRuntimeThreadConfig(config, options);
|
|
1122
1336
|
if (params.bootstrapContextMode !== "lightweight") return runtimeConfig;
|
|
1123
1337
|
return mergeCodexThreadConfigs(runtimeConfig, CODEX_LIGHTWEIGHT_CONTEXT_THREAD_CONFIG) ?? {
|
|
1124
1338
|
...runtimeConfig,
|
|
@@ -1238,14 +1452,22 @@ function renderCodexRuntimePromptOverlay(params) {
|
|
|
1238
1452
|
].filter((section) => typeof section === "string" && section.trim().length > 0).join("\n\n");
|
|
1239
1453
|
}
|
|
1240
1454
|
function buildUserInput(params, promptText = params.prompt) {
|
|
1455
|
+
const imageInputs = (params.images ?? []).map((image) => {
|
|
1456
|
+
const imageUrl = sanitizeInlineImageDataUrl(`data:${image.mimeType};base64,${image.data}`);
|
|
1457
|
+
return imageUrl ? {
|
|
1458
|
+
type: "image",
|
|
1459
|
+
url: imageUrl
|
|
1460
|
+
} : {
|
|
1461
|
+
type: "text",
|
|
1462
|
+
text: invalidInlineImageText("codex user input"),
|
|
1463
|
+
text_elements: []
|
|
1464
|
+
};
|
|
1465
|
+
});
|
|
1241
1466
|
return [{
|
|
1242
1467
|
type: "text",
|
|
1243
1468
|
text: promptText,
|
|
1244
1469
|
text_elements: []
|
|
1245
|
-
}, ...
|
|
1246
|
-
type: "image",
|
|
1247
|
-
url: `data:${image.mimeType};base64,${image.data}`
|
|
1248
|
-
}))];
|
|
1470
|
+
}, ...imageInputs];
|
|
1249
1471
|
}
|
|
1250
1472
|
function resolveCodexAppServerModelProvider(params) {
|
|
1251
1473
|
const normalized = params.provider.trim();
|
|
@@ -1260,4 +1482,4 @@ function resolveReasoningEffort(thinkLevel, modelId) {
|
|
|
1260
1482
|
return null;
|
|
1261
1483
|
}
|
|
1262
1484
|
//#endregion
|
|
1263
|
-
export {
|
|
1485
|
+
export { isForcedPrivateQaCodexRuntime as C, filterCodexDynamicTools as S, resolveCodexDynamicToolsLoading as T, projectContextEngineAssemblyForCodex as _, buildThreadResumeParams as a, createCodexDynamicToolBridge as b, codexDynamicToolsFingerprint as c, resolveReasoningEffort as d, startOrResumeThread as f, shouldBuildCodexPluginThreadConfig as g, mergeCodexThreadConfigs as h, buildDeveloperInstructions as i, isContextEngineBindingCompatible as l, buildCodexPluginThreadConfigInputFingerprint as m, buildCodexRuntimeThreadConfig as n, buildThreadStartParams as o, buildCodexPluginThreadConfig as p, buildContextEngineBinding as r, buildTurnStartParams as s, areCodexDynamicToolFingerprintsCompatible as t, resolveCodexAppServerModelProvider as u, resolveCodexContextEngineProjectionMaxChars as v, normalizeCodexDynamicToolName as w, sanitizeCodexHistoryImagePayloads as x, resolveCodexContextEngineProjectionReserveTokens as y };
|