@openclaw/codex 2026.7.2-beta.1 → 2026.7.2-beta.3
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/README.md +1 -1
- package/dist/{app-server-policy-DVcxdse_.js → app-server-policy-DUMF2Xyr.js} +1 -1
- package/dist/{attempt-notifications-DEv9h7iC.js → attempt-notifications-Ecjyzufe.js} +3 -6
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-D6ZlGNmb.js → command-formatters-NCTL7A2q.js} +38 -3
- package/dist/{command-handlers-Cpl9fUWv.js → command-handlers-DtFbZiba.js} +70 -15
- package/dist/{compact-FnJmiPNA.js → compact-Kgy26gIM.js} +4 -5
- package/dist/{computer-use-DVzr8OP1.js → computer-use-C7x4ZaqR.js} +4 -4
- package/dist/{conversation-control-DtQ-E7mr.js → conversation-control-B0s3aIjT.js} +5 -7
- package/dist/doctor-contract-api.js +1 -1
- package/dist/{dynamic-tools-BMLoaTeG.js → dynamic-tools-D_vSVmv9.js} +851 -434
- package/dist/harness.js +11 -6
- package/dist/index.js +52 -31
- package/dist/{media-understanding-provider-D580L0P8.js → media-understanding-provider-IPNNQre6.js} +11 -12
- package/dist/media-understanding-provider.js +1 -1
- package/dist/{models-DuKzZA6G.js → models-DD5zBdX5.js} +5 -9
- package/dist/{notification-correlation-DfaCm0mx.js → notification-correlation-C8DVQ_Bq.js} +3 -3
- package/dist/{plugin-app-cache-key-BKNjHMEs.js → plugin-app-cache-key-DJbhLYSK.js} +2 -2
- package/dist/{rate-limits-Dhp04Rqo.js → rate-limits-CqhWQ2R9.js} +9 -6
- package/dist/{request-DborTWgw.js → request-9yf9pZjf.js} +54 -8
- package/dist/{run-attempt-VPVJoYDP.js → run-attempt-BIoO8ISr.js} +637 -351
- package/dist/{config-c48K5HP9.js → session-binding-Bmt20HfB.js} +788 -3
- package/dist/{session-catalog-7H112Tr_.js → session-catalog-CA7R-hX2.js} +82 -45
- package/dist/{session-cli-B28RhCyp.js → session-cli-Bxk3-Wqz.js} +2 -2
- package/dist/{shared-client-D4mFI9al.js → shared-client-CSXLtCLE.js} +304 -81
- package/dist/{side-question-CgJBz52s.js → side-question-DtzquMOb.js} +15 -13
- package/dist/{thread-lifecycle-BgLXzjvV.js → thread-lifecycle-CQ_9mAa1.js} +1821 -1582
- package/dist/{protocol-validators-dZQ-UTOa.js → transcript-mirror-D9rTxx2P.js} +485 -2
- package/dist/usage-CuPpFgTc.js +25 -0
- package/dist/{web-search-provider.runtime-Bs-eTn5U.js → web-search-provider.runtime-_x5XTeqh.js} +3 -3
- package/npm-shrinkwrap.json +30 -30
- package/openclaw.plugin.json +21 -6
- package/package.json +6 -6
- package/dist/capabilities-42Dfn2TV.js +0 -33
- package/dist/prompt-overlay.js +0 -15
- package/dist/protocol-BMifTfdW.js +0 -15
- package/dist/provider-catalog.js +0 -118
- package/dist/provider-discovery.js +0 -34
- package/dist/provider.js +0 -307
- package/dist/session-binding-BMfX1OX-.js +0 -786
- package/dist/transcript-mirror-DhLwFIL4.js +0 -485
|
@@ -1,30 +1,30 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { c as readCodexTurn } from "./
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { n as formatCodexUsageLimitErrorMessage } from "./rate-limits-
|
|
7
|
-
import { c as attachCodexMirrorIdentity, s as promptSnapshot } from "./transcript-mirror-DhLwFIL4.js";
|
|
8
|
-
import { r as formatCodexDisplayText } from "./command-formatters-D6ZlGNmb.js";
|
|
1
|
+
import { Y as CODEX_OPENCLAW_DIRECT_DYNAMIC_TOOL_NAMESPACE, Z as isJsonObject, _ as readCodexRateLimitsRevision, c as releaseLeasedSharedCodexAppServerClient, j as resolveCodexGatewayTimeoutWithGraceMs, v as readRecentCodexRateLimits, y as rememberCodexRateLimitsRead } from "./shared-client-CSXLtCLE.js";
|
|
2
|
+
import { y as readCodexPluginConfig } from "./session-binding-Bmt20HfB.js";
|
|
3
|
+
import { c as attachCodexMirrorIdentity, g as readCodexTurn, s as promptSnapshot } from "./transcript-mirror-D9rTxx2P.js";
|
|
4
|
+
import { C as isForcedPrivateQaCodexRuntime, S as filterCodexDynamicToolsWithOpenClawShell, T as normalizeCodexDynamicToolName, a as sanitizeCodexHistoryImagePayloads, d as resolveCodexWebSearchPlan, i as invalidInlineImageText, o as sanitizeInlineImageDataUrl, w as isSystemAgentOnlyCodexDynamicToolAllowlist, x as filterCodexDynamicTools } from "./thread-lifecycle-CQ_9mAa1.js";
|
|
5
|
+
import { d as CODEX_CONTROL_METHODS, r as formatCodexDisplayText } from "./command-formatters-NCTL7A2q.js";
|
|
6
|
+
import { a as shouldRefreshCodexRateLimitsForUsageLimitMessage, i as resolveCodexUsageLimitResetAtMs, n as formatCodexUsageLimitErrorMessage } from "./rate-limits-CqhWQ2R9.js";
|
|
9
7
|
import { a as resolveCodexNodeExecToolOverrides, i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-D1Wky__S.js";
|
|
10
|
-
import { n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-
|
|
8
|
+
import { n as readCodexNotificationThreadId, r as readCodexNotificationTurnId } from "./notification-correlation-C8DVQ_Bq.js";
|
|
11
9
|
import fs from "node:fs/promises";
|
|
12
|
-
import { addTimerTimeoutGraceMs, asDateTimestampMs, finiteSecondsToTimerSafeMilliseconds, parseStrictNonNegativeInteger
|
|
10
|
+
import { addTimerTimeoutGraceMs, asDateTimestampMs, finiteSecondsToTimerSafeMilliseconds, parseStrictNonNegativeInteger } from "openclaw/plugin-sdk/number-runtime";
|
|
13
11
|
import { sliceUtf16Safe, truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
14
12
|
import { createHash } from "node:crypto";
|
|
15
|
-
import { resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
13
|
+
import { markAuthProfileBlockedUntil, resolveAgentDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
16
14
|
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
17
15
|
import { asOptionalRecord, isRecord, normalizeTrimmedStringList } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
18
16
|
import { HEARTBEAT_RESPONSE_TOOL_NAME, TOOL_PROGRESS_OUTPUT_MAX_CHARS, buildAgentHookContextChannelFields, buildEmbeddedAttemptToolRunContext, callGatewayTool, classifyAgentHarnessTerminalOutcome, consumeAdjustedParamsForToolCall, consumePreExecutionBlockedToolCall, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, emitAgentEvent, extractMessagingToolSend, extractMessagingToolSendResult, extractToolResultMediaArtifact, filterProviderNormalizableTools, filterToolResultMediaUrls, finalizeToolTerminalPresentation, formatApprovalDisplayPath, formatErrorMessage, formatToolAggregate, formatToolExecutionErrorMessage, formatToolProgressOutput, getBeforeToolCallFailureDisposition, getChannelAgentToolMeta, getPluginToolMeta, hasNativeHookRelayInvocation, inferToolMetaFromArgs, invokeNativeHookRelay, isDeliveredMessageToolOnlySourceReplyResult, isDeliveredMessagingToolResult, isHostScopedAgentToolActive, isMessagingTool, isMessagingToolSendAction, isReplaySafeToolCall, isSubagentSessionKey, isToolResultError, isToolWrappedWithBeforeToolCallHook, normalizeAgentRuntimeTools, normalizeHeartbeatToolResponse, normalizeUsage, projectRuntimeToolInputSchema, registerNativeHookRelay, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveNativeHookRelayDeferredToolApproval, resolveToolExecutionErrorKind, resolveToolResultFailureKind, runAgentHarnessAfterCompactionHook, runAgentHarnessAfterToolCallHook, runAgentHarnessBeforeCompactionHook, runBeforeToolCallHook, sanitizeToolResult, setBeforeToolCallDiagnosticsEnabled, supportsModelTools, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
19
17
|
import { listSessionEntries, parseSqliteSessionFileMarker } from "openclaw/plugin-sdk/session-store-runtime";
|
|
20
18
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
21
|
-
import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
19
|
+
import { redactSensitiveFieldValue, redactSensitiveText, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
|
|
22
20
|
import { emitTrustedDiagnosticEvent, hasPendingInternalDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
23
21
|
import { readSessionTranscriptEvents } from "openclaw/plugin-sdk/session-transcript-runtime";
|
|
24
22
|
import { isToolAllowed } from "openclaw/plugin-sdk/sandbox";
|
|
23
|
+
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
25
24
|
import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "openclaw/plugin-sdk/agent-sessions";
|
|
26
25
|
import { generatedImageAssetFromBase64 } from "openclaw/plugin-sdk/image-generation";
|
|
27
26
|
import { saveMediaBuffer } from "openclaw/plugin-sdk/media-store";
|
|
27
|
+
import { normalizeOpenAIToolSchemas } from "openclaw/plugin-sdk/provider-tools";
|
|
28
28
|
//#region extensions/codex/src/app-server/local-runtime-attribution.ts
|
|
29
29
|
const OPENAI_PROVIDER_ID = "openai";
|
|
30
30
|
const OPENAI_RESPONSES_API = "openai-responses";
|
|
@@ -67,6 +67,7 @@ function createAssistantMessage(params, text, options) {
|
|
|
67
67
|
output: options.tokenUsage.output ?? 0,
|
|
68
68
|
cacheRead: options.tokenUsage.cacheRead ?? 0,
|
|
69
69
|
cacheWrite: options.tokenUsage.cacheWrite ?? 0,
|
|
70
|
+
...options.tokenUsage.contextUsage ? { contextUsage: options.tokenUsage.contextUsage } : {},
|
|
70
71
|
totalTokens: options.tokenUsage.total ?? (options.tokenUsage.input ?? 0) + (options.tokenUsage.output ?? 0) + (options.tokenUsage.cacheRead ?? 0) + (options.tokenUsage.cacheWrite ?? 0),
|
|
71
72
|
cost: ZERO_USAGE$1.cost
|
|
72
73
|
} : ZERO_USAGE$1;
|
|
@@ -103,7 +104,7 @@ function createAssistantMirrorMessage(params, title, text) {
|
|
|
103
104
|
}
|
|
104
105
|
//#endregion
|
|
105
106
|
//#region extensions/codex/src/app-server/event-projector-values.ts
|
|
106
|
-
function readString$
|
|
107
|
+
function readString$3(record, key) {
|
|
107
108
|
const value = record[key];
|
|
108
109
|
return typeof value === "string" ? value : void 0;
|
|
109
110
|
}
|
|
@@ -139,15 +140,15 @@ function readNonNegativeInteger(record, key) {
|
|
|
139
140
|
}
|
|
140
141
|
function readCodexErrorNotificationMessage(record) {
|
|
141
142
|
const error = record.error;
|
|
142
|
-
return isJsonObject(error) ? readString$
|
|
143
|
+
return isJsonObject(error) ? readString$3(error, "message") : void 0;
|
|
143
144
|
}
|
|
144
145
|
function readHookOutputEntries(value) {
|
|
145
146
|
if (!Array.isArray(value)) return [];
|
|
146
147
|
return value.flatMap((entry) => {
|
|
147
148
|
if (!isJsonObject(entry)) return [];
|
|
148
|
-
const text = readString$
|
|
149
|
+
const text = readString$3(entry, "text");
|
|
149
150
|
if (!text) return [];
|
|
150
|
-
const kind = readString$
|
|
151
|
+
const kind = readString$3(entry, "kind");
|
|
151
152
|
return [{
|
|
152
153
|
...kind ? { kind } : {},
|
|
153
154
|
text
|
|
@@ -160,9 +161,9 @@ function splitPlanText(text) {
|
|
|
160
161
|
function extractRawAssistantText(item) {
|
|
161
162
|
return (Array.isArray(item.content) ? item.content : []).flatMap((entry) => {
|
|
162
163
|
if (!isJsonObject(entry)) return [];
|
|
163
|
-
const type = readString$
|
|
164
|
+
const type = readString$3(entry, "type");
|
|
164
165
|
if (type !== "output_text" && type !== "text") return [];
|
|
165
|
-
const value = readString$
|
|
166
|
+
const value = readString$3(entry, "text");
|
|
166
167
|
return value ? [value] : [];
|
|
167
168
|
}).join("").trim() || void 0;
|
|
168
169
|
}
|
|
@@ -178,6 +179,117 @@ function readItem(value) {
|
|
|
178
179
|
return value;
|
|
179
180
|
}
|
|
180
181
|
//#endregion
|
|
182
|
+
//#region extensions/codex/src/app-server/event-projector-items.ts
|
|
183
|
+
function itemKind(item) {
|
|
184
|
+
switch (item.type) {
|
|
185
|
+
case "dynamicToolCall":
|
|
186
|
+
case "mcpToolCall": return "tool";
|
|
187
|
+
case "commandExecution": return "command";
|
|
188
|
+
case "fileChange": return "patch";
|
|
189
|
+
case "webSearch": return "search";
|
|
190
|
+
case "reasoning":
|
|
191
|
+
case "contextCompaction": return "analysis";
|
|
192
|
+
default: return;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
function itemTitle(item) {
|
|
196
|
+
switch (item.type) {
|
|
197
|
+
case "commandExecution": return "Command";
|
|
198
|
+
case "fileChange": return "File change";
|
|
199
|
+
case "mcpToolCall": return "MCP tool";
|
|
200
|
+
case "dynamicToolCall": return "Tool";
|
|
201
|
+
case "webSearch": return "Web search";
|
|
202
|
+
case "contextCompaction": return "Context compaction";
|
|
203
|
+
case "reasoning": return "Reasoning";
|
|
204
|
+
default: return item.type;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function itemStatus(item) {
|
|
208
|
+
const status = readItemString(item, "status");
|
|
209
|
+
if (status === "failed" || status === "error") return "failed";
|
|
210
|
+
if (status === "declined") return "blocked";
|
|
211
|
+
if (status === "inProgress" || status === "in_progress" || status === "running") return "running";
|
|
212
|
+
return "completed";
|
|
213
|
+
}
|
|
214
|
+
function unknownItemStatus(item) {
|
|
215
|
+
const status = readItemString(item, "status");
|
|
216
|
+
switch (status) {
|
|
217
|
+
case void 0:
|
|
218
|
+
case "completed":
|
|
219
|
+
case "failed":
|
|
220
|
+
case "error":
|
|
221
|
+
case "declined":
|
|
222
|
+
case "inProgress":
|
|
223
|
+
case "in_progress":
|
|
224
|
+
case "running": return;
|
|
225
|
+
default: return status;
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
function auditNativeToolTerminalStatus(item) {
|
|
229
|
+
if (item.type === "imageView" || item.type === "sleep") return "completed";
|
|
230
|
+
const status = readItemString(item, "status");
|
|
231
|
+
if (status === "completed") return "completed";
|
|
232
|
+
if (status === "failed" || status === "error") return "failed";
|
|
233
|
+
if (status === "declined") return "blocked";
|
|
234
|
+
return "unknown";
|
|
235
|
+
}
|
|
236
|
+
function auditNativeToolUnfinishedStatus(item) {
|
|
237
|
+
return item.type === "webSearch" || item.type === "imageGeneration" ? "unknown" : "failed";
|
|
238
|
+
}
|
|
239
|
+
function isNonSuccessItemStatus(status) {
|
|
240
|
+
return status === "failed" || status === "blocked";
|
|
241
|
+
}
|
|
242
|
+
function itemName(item) {
|
|
243
|
+
if (item.type === "dynamicToolCall" && typeof item.tool === "string") return item.tool;
|
|
244
|
+
if (item.type === "mcpToolCall" && typeof item.tool === "string") {
|
|
245
|
+
const server = typeof item.server === "string" ? item.server : void 0;
|
|
246
|
+
return server ? `${server}.${item.tool}` : item.tool;
|
|
247
|
+
}
|
|
248
|
+
if (item.type === "commandExecution") return "bash";
|
|
249
|
+
if (item.type === "fileChange") return "apply_patch";
|
|
250
|
+
if (item.type === "webSearch") return "web_search";
|
|
251
|
+
}
|
|
252
|
+
function auditNativeToolName(item) {
|
|
253
|
+
if (item.type === "dynamicToolCall") return;
|
|
254
|
+
const progressName = itemName(item);
|
|
255
|
+
if (progressName) return progressName;
|
|
256
|
+
if (item.type === "collabAgentToolCall") return typeof item.tool === "string" && item.tool.trim() ? `collab.${item.tool.trim()}` : "collab_agent";
|
|
257
|
+
if (item.type === "imageGeneration") return "image_generation";
|
|
258
|
+
if (item.type === "imageView") return "image_view";
|
|
259
|
+
if (item.type === "sleep") return "sleep";
|
|
260
|
+
}
|
|
261
|
+
function isSideEffectingNativeToolItem(item) {
|
|
262
|
+
return itemStatus(item) !== "blocked" && (isMutatingNativeToolItem(item) || item.type === "mcpToolCall");
|
|
263
|
+
}
|
|
264
|
+
function shouldSynthesizeToolProgressForItem(item) {
|
|
265
|
+
switch (item.type) {
|
|
266
|
+
case "commandExecution":
|
|
267
|
+
case "fileChange":
|
|
268
|
+
case "webSearch":
|
|
269
|
+
case "mcpToolCall": return true;
|
|
270
|
+
default: return false;
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
function shouldRecordNativeToolTranscript(item) {
|
|
274
|
+
return shouldSynthesizeToolProgressForItem(item) && item.type !== "webSearch";
|
|
275
|
+
}
|
|
276
|
+
function isMutatingNativeToolItem(item) {
|
|
277
|
+
if (item.type === "commandExecution") return true;
|
|
278
|
+
return item.type === "fileChange" || item.type === "collabAgentToolCall" || item.type === "imageGeneration";
|
|
279
|
+
}
|
|
280
|
+
function shouldClearTerminalPresentationForNativeItem(item) {
|
|
281
|
+
switch (item.type) {
|
|
282
|
+
case "collabAgentToolCall":
|
|
283
|
+
case "commandExecution":
|
|
284
|
+
case "fileChange":
|
|
285
|
+
case "imageGeneration":
|
|
286
|
+
case "imageView":
|
|
287
|
+
case "mcpToolCall":
|
|
288
|
+
case "webSearch": return true;
|
|
289
|
+
default: return false;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
//#endregion
|
|
181
293
|
//#region extensions/codex/src/app-server/event-projector-assistant.ts
|
|
182
294
|
var CodexAssistantProjection = class {
|
|
183
295
|
constructor(params, emitAgentEvent, matchesToolProgressEcho) {
|
|
@@ -191,6 +303,7 @@ var CodexAssistantProjection = class {
|
|
|
191
303
|
this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff = false;
|
|
192
304
|
this.terminalAssistantCandidateEarlierActiveItemIds = /* @__PURE__ */ new Set();
|
|
193
305
|
this.lastCommentaryProgressTextByItem = /* @__PURE__ */ new Map();
|
|
306
|
+
this.lastAnswerCandidateEventByItem = /* @__PURE__ */ new Map();
|
|
194
307
|
this.pendingRawCommentaryEchoes = 0;
|
|
195
308
|
this.rawPromotedAssistantItemIds = /* @__PURE__ */ new Set();
|
|
196
309
|
this.assistantStarted = false;
|
|
@@ -218,8 +331,8 @@ var CodexAssistantProjection = class {
|
|
|
218
331
|
return this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff && this.hasLatestTerminalAssistantCandidateText();
|
|
219
332
|
}
|
|
220
333
|
async handleAssistantDelta(params) {
|
|
221
|
-
const itemId = readString$
|
|
222
|
-
const delta = readString$
|
|
334
|
+
const itemId = readString$3(params, "itemId") ?? "assistant";
|
|
335
|
+
const delta = readString$3(params, "delta") ?? "";
|
|
223
336
|
if (!delta) return;
|
|
224
337
|
if (itemId !== this.pendingRawTerminalAssistantEchoItemId) this.pendingRawTerminalAssistantEchoItemId = void 0;
|
|
225
338
|
const isCommentary = this.isCommentaryAssistantItem(itemId);
|
|
@@ -238,6 +351,7 @@ var CodexAssistantProjection = class {
|
|
|
238
351
|
});
|
|
239
352
|
return;
|
|
240
353
|
}
|
|
354
|
+
if (this.isFinalAnswerAssistantItem(itemId)) this.emitAnswerCandidate(itemId, "candidate");
|
|
241
355
|
const knownFinalAnswer = this.shouldStreamAssistantPartial(itemId);
|
|
242
356
|
const replace = this.streamedPartialAssistantItemId !== void 0 && this.streamedPartialAssistantItemId !== itemId;
|
|
243
357
|
if (replace && (!knownFinalAnswer || this.streamedPartialAssistantItemReplaceable)) this.streamedPartialAssistantItemReplaceable = true;
|
|
@@ -288,7 +402,7 @@ var CodexAssistantProjection = class {
|
|
|
288
402
|
text: item.text
|
|
289
403
|
});
|
|
290
404
|
this.pendingRawCommentaryEchoes += 1;
|
|
291
|
-
}
|
|
405
|
+
} else if (item.text && this.isFinalAnswerAssistantItem(item.id)) this.emitAnswerCandidate(item.id, "candidate");
|
|
292
406
|
}
|
|
293
407
|
}
|
|
294
408
|
recordSnapshotItem(item) {
|
|
@@ -299,9 +413,9 @@ var CodexAssistantProjection = class {
|
|
|
299
413
|
}
|
|
300
414
|
}
|
|
301
415
|
handleRawResponseItemCompleted(item, activeItemIds) {
|
|
302
|
-
const role = readString$
|
|
303
|
-
const phase = readString$
|
|
304
|
-
const rawItemId = readString$
|
|
416
|
+
const role = readString$3(item, "role");
|
|
417
|
+
const phase = readString$3(item, "phase");
|
|
418
|
+
const rawItemId = readString$3(item, "id");
|
|
305
419
|
const candidateWasSupersededBeforeRaw = this.latestTerminalAssistantCandidateSuperseded;
|
|
306
420
|
const pendingTerminalAssistantEchoItemId = this.pendingRawTerminalAssistantEchoItemId;
|
|
307
421
|
const isPendingTerminalAssistantEcho = role === "assistant" && phase !== "commentary" && pendingTerminalAssistantEchoItemId !== void 0 && (rawItemId === void 0 || rawItemId === pendingTerminalAssistantEchoItemId);
|
|
@@ -342,6 +456,26 @@ var CodexAssistantProjection = class {
|
|
|
342
456
|
const finalText = this.resolveFinalAssistantTextItem()?.text;
|
|
343
457
|
return finalText ? [finalText] : [];
|
|
344
458
|
}
|
|
459
|
+
finalizeAnswerCandidate(turn) {
|
|
460
|
+
if (turn.status !== "completed") {
|
|
461
|
+
this.supersedeVisibleAnswerCandidate();
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const turnItems = turn.items ?? [];
|
|
465
|
+
const authoritativeIndex = turnItems.findLastIndex((item) => item.type === "agentMessage" && readItemString(item, "phase") === "final_answer" && typeof item.text === "string" && item.text.trim().length > 0);
|
|
466
|
+
const authoritative = authoritativeIndex >= 0 ? turnItems[authoritativeIndex] : void 0;
|
|
467
|
+
if (turnItems.slice(authoritativeIndex + 1).some(shouldClearTerminalPresentationForNativeItem) || authoritative?.id === this.latestTerminalAssistantCandidateItemId && this.latestTerminalAssistantCandidateSuperseded) {
|
|
468
|
+
this.supersedeVisibleAnswerCandidate();
|
|
469
|
+
return;
|
|
470
|
+
}
|
|
471
|
+
const itemId = authoritative?.id ?? this.visibleAnswerCandidateItemId;
|
|
472
|
+
if (!itemId) return;
|
|
473
|
+
if (itemId !== this.visibleAnswerCandidateItemId) {
|
|
474
|
+
this.supersedeVisibleAnswerCandidate();
|
|
475
|
+
this.visibleAnswerCandidateItemId = itemId;
|
|
476
|
+
}
|
|
477
|
+
this.emitAnswerCandidate(itemId, "selected");
|
|
478
|
+
}
|
|
345
479
|
hasAssistantItemTextForSynthesis() {
|
|
346
480
|
for (let i = this.assistantItemOrder.length - 1; i >= 0; i -= 1) {
|
|
347
481
|
const itemId = this.assistantItemOrder[i];
|
|
@@ -375,6 +509,9 @@ var CodexAssistantProjection = class {
|
|
|
375
509
|
isCommentaryAssistantItem(itemId) {
|
|
376
510
|
return this.assistantPhaseByItem.get(itemId) === "commentary";
|
|
377
511
|
}
|
|
512
|
+
isFinalAnswerAssistantItem(itemId) {
|
|
513
|
+
return this.assistantPhaseByItem.get(itemId) === "final_answer";
|
|
514
|
+
}
|
|
378
515
|
shouldStreamAssistantPartial(itemId) {
|
|
379
516
|
return this.assistantPhaseByItem.get(itemId) === "final_answer";
|
|
380
517
|
}
|
|
@@ -394,6 +531,36 @@ var CodexAssistantProjection = class {
|
|
|
394
531
|
}
|
|
395
532
|
});
|
|
396
533
|
}
|
|
534
|
+
emitAnswerCandidate(itemId, status) {
|
|
535
|
+
const text = this.assistantTextByItem.get(itemId)?.trim();
|
|
536
|
+
if (!text) return;
|
|
537
|
+
if (status === "candidate" && this.visibleAnswerCandidateItemId !== itemId) {
|
|
538
|
+
this.supersedeVisibleAnswerCandidate();
|
|
539
|
+
this.visibleAnswerCandidateItemId = itemId;
|
|
540
|
+
}
|
|
541
|
+
const signature = `${status}\0${text}`;
|
|
542
|
+
if (this.lastAnswerCandidateEventByItem.get(itemId) === signature) return;
|
|
543
|
+
this.lastAnswerCandidateEventByItem.set(itemId, signature);
|
|
544
|
+
this.emitAgentEvent({
|
|
545
|
+
stream: "item",
|
|
546
|
+
data: {
|
|
547
|
+
itemId,
|
|
548
|
+
kind: "answer_candidate",
|
|
549
|
+
title: "Answer candidate",
|
|
550
|
+
phase: "update",
|
|
551
|
+
status,
|
|
552
|
+
progressText: text,
|
|
553
|
+
source: "codex-app-server",
|
|
554
|
+
hideFromChannelProgress: true
|
|
555
|
+
}
|
|
556
|
+
});
|
|
557
|
+
}
|
|
558
|
+
supersedeVisibleAnswerCandidate() {
|
|
559
|
+
const itemId = this.visibleAnswerCandidateItemId;
|
|
560
|
+
if (!itemId) return;
|
|
561
|
+
this.emitAnswerCandidate(itemId, "superseded");
|
|
562
|
+
this.visibleAnswerCandidateItemId = void 0;
|
|
563
|
+
}
|
|
397
564
|
markLatestTerminalAssistantCandidate(itemId, activeItemIds, options) {
|
|
398
565
|
this.latestTerminalAssistantCandidateItemId = itemId;
|
|
399
566
|
this.latestTerminalAssistantCandidateSuperseded = false;
|
|
@@ -409,6 +576,7 @@ var CodexAssistantProjection = class {
|
|
|
409
576
|
this.latestTerminalAssistantCandidateSuperseded = true;
|
|
410
577
|
this.latestTerminalAssistantCandidateCanReleaseAfterToolHandoff = false;
|
|
411
578
|
this.terminalAssistantCandidateEarlierActiveItemIds.clear();
|
|
579
|
+
this.supersedeVisibleAnswerCandidate();
|
|
412
580
|
}
|
|
413
581
|
resolveFinalAssistantTextItem() {
|
|
414
582
|
for (let i = this.assistantItemOrder.length - 1; i >= 0; i -= 1) {
|
|
@@ -431,102 +599,52 @@ var CodexAssistantProjection = class {
|
|
|
431
599
|
}
|
|
432
600
|
};
|
|
433
601
|
//#endregion
|
|
434
|
-
//#region extensions/codex/src/app-server/event-projector-
|
|
435
|
-
function
|
|
436
|
-
|
|
437
|
-
case "dynamicToolCall":
|
|
438
|
-
case "mcpToolCall": return "tool";
|
|
439
|
-
case "commandExecution": return "command";
|
|
440
|
-
case "fileChange": return "patch";
|
|
441
|
-
case "webSearch": return "search";
|
|
442
|
-
case "reasoning":
|
|
443
|
-
case "contextCompaction": return "analysis";
|
|
444
|
-
default: return;
|
|
445
|
-
}
|
|
602
|
+
//#region extensions/codex/src/app-server/event-projector-diagnostics.ts
|
|
603
|
+
function redactCodexEventKind(method) {
|
|
604
|
+
return redactSensitiveText(sanitizeTerminalText(method));
|
|
446
605
|
}
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
case "dynamicToolCall": return "Tool";
|
|
453
|
-
case "webSearch": return "Web search";
|
|
454
|
-
case "contextCompaction": return "Context compaction";
|
|
455
|
-
case "reasoning": return "Reasoning";
|
|
456
|
-
default: return item.type;
|
|
606
|
+
var CodexProjectionDiagnostics = class {
|
|
607
|
+
constructor(threadId, turnId) {
|
|
608
|
+
this.threadId = threadId;
|
|
609
|
+
this.turnId = turnId;
|
|
610
|
+
this.warningKeys = /* @__PURE__ */ new Set();
|
|
457
611
|
}
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
}
|
|
474
|
-
function auditNativeToolUnfinishedStatus(item) {
|
|
475
|
-
return item.type === "webSearch" || item.type === "imageGeneration" ? "unknown" : "failed";
|
|
476
|
-
}
|
|
477
|
-
function isNonSuccessItemStatus(status) {
|
|
478
|
-
return status === "failed" || status === "blocked";
|
|
479
|
-
}
|
|
480
|
-
function itemName(item) {
|
|
481
|
-
if (item.type === "dynamicToolCall" && typeof item.tool === "string") return item.tool;
|
|
482
|
-
if (item.type === "mcpToolCall" && typeof item.tool === "string") {
|
|
483
|
-
const server = typeof item.server === "string" ? item.server : void 0;
|
|
484
|
-
return server ? `${server}.${item.tool}` : item.tool;
|
|
612
|
+
warnUnknownItemStatus(item) {
|
|
613
|
+
if (!item) return;
|
|
614
|
+
const status = unknownItemStatus(item);
|
|
615
|
+
if (!status) return;
|
|
616
|
+
const safeStatus = redactCodexEventKind(status);
|
|
617
|
+
const safeItemType = redactCodexEventKind(item.type);
|
|
618
|
+
this.warnOnce(JSON.stringify([
|
|
619
|
+
"status",
|
|
620
|
+
item.type,
|
|
621
|
+
status
|
|
622
|
+
]), "codex app-server item reported unknown status; continuing projection", {
|
|
623
|
+
itemId: item.id,
|
|
624
|
+
itemType: safeItemType,
|
|
625
|
+
status: safeStatus
|
|
626
|
+
});
|
|
485
627
|
}
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
}
|
|
499
|
-
function isSideEffectingNativeToolItem(item) {
|
|
500
|
-
return itemStatus(item) !== "blocked" && (isMutatingNativeToolItem(item) || item.type === "mcpToolCall");
|
|
501
|
-
}
|
|
502
|
-
function shouldSynthesizeToolProgressForItem(item) {
|
|
503
|
-
switch (item.type) {
|
|
504
|
-
case "commandExecution":
|
|
505
|
-
case "fileChange":
|
|
506
|
-
case "webSearch":
|
|
507
|
-
case "mcpToolCall": return true;
|
|
508
|
-
default: return false;
|
|
628
|
+
warnUnknownEvent(notification, params) {
|
|
629
|
+
const notificationThreadId = readCodexNotificationThreadId(params);
|
|
630
|
+
const notificationTurnId = readCodexNotificationTurnId(params);
|
|
631
|
+
const eventKind = redactCodexEventKind(notification.method);
|
|
632
|
+
this.warnOnce(JSON.stringify(["method", notification.method]), `codex app-server projector received unknown event kind; continuing: ${eventKind}`, {
|
|
633
|
+
eventKind,
|
|
634
|
+
activeThreadId: this.threadId,
|
|
635
|
+
activeTurnId: this.turnId,
|
|
636
|
+
threadId: notificationThreadId,
|
|
637
|
+
turnId: notificationTurnId,
|
|
638
|
+
matchesActiveThread: notificationThreadId === this.threadId,
|
|
639
|
+
matchesActiveTurn: notificationTurnId === this.turnId
|
|
640
|
+
});
|
|
509
641
|
}
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
function isMutatingNativeToolItem(item) {
|
|
515
|
-
if (item.type === "commandExecution") return true;
|
|
516
|
-
return item.type === "fileChange" || item.type === "collabAgentToolCall" || item.type === "imageGeneration";
|
|
517
|
-
}
|
|
518
|
-
function shouldClearTerminalPresentationForNativeItem(item) {
|
|
519
|
-
switch (item.type) {
|
|
520
|
-
case "collabAgentToolCall":
|
|
521
|
-
case "commandExecution":
|
|
522
|
-
case "fileChange":
|
|
523
|
-
case "imageGeneration":
|
|
524
|
-
case "imageView":
|
|
525
|
-
case "mcpToolCall":
|
|
526
|
-
case "webSearch": return true;
|
|
527
|
-
default: return false;
|
|
642
|
+
warnOnce(key, message, context) {
|
|
643
|
+
if (this.warningKeys.has(key)) return;
|
|
644
|
+
this.warningKeys.add(key);
|
|
645
|
+
embeddedAgentLog.warn(message, context);
|
|
528
646
|
}
|
|
529
|
-
}
|
|
647
|
+
};
|
|
530
648
|
//#endregion
|
|
531
649
|
//#region extensions/codex/src/app-server/event-projector-tool-output.ts
|
|
532
650
|
const TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS = 1e4;
|
|
@@ -607,7 +725,7 @@ function collectDynamicToolContentText(contentItems) {
|
|
|
607
725
|
if (!Array.isArray(contentItems)) return "";
|
|
608
726
|
return contentItems.flatMap((entry) => {
|
|
609
727
|
if (!isJsonObject(entry)) return [];
|
|
610
|
-
const text = readString$
|
|
728
|
+
const text = readString$3(entry, "text");
|
|
611
729
|
return text ? [text] : [];
|
|
612
730
|
}).join("\n");
|
|
613
731
|
}
|
|
@@ -956,7 +1074,29 @@ var CodexToolProgressProjection = class {
|
|
|
956
1074
|
return this.sideEffectingNativeIds.size > 0 || this.sideEffectingDynamicIds.size > 0;
|
|
957
1075
|
}
|
|
958
1076
|
setLastToolError(error) {
|
|
959
|
-
|
|
1077
|
+
if (!error) {
|
|
1078
|
+
this.lastNativeToolError = void 0;
|
|
1079
|
+
return;
|
|
1080
|
+
}
|
|
1081
|
+
const terminalResolution = this.params.observeToolTerminal?.({
|
|
1082
|
+
toolName: error.toolName,
|
|
1083
|
+
...error.meta ? { meta: error.meta } : {},
|
|
1084
|
+
outcome: "failure",
|
|
1085
|
+
failure: {
|
|
1086
|
+
...error.errorCode ? { errorCode: error.errorCode } : {},
|
|
1087
|
+
...error.error ? { error: error.error } : {},
|
|
1088
|
+
...error.validationErrorSummary ? { validationErrorSummary: error.validationErrorSummary } : {},
|
|
1089
|
+
...error.timedOut ? { timedOut: true } : {},
|
|
1090
|
+
...error.middlewareError ? { middlewareError: true } : {}
|
|
1091
|
+
},
|
|
1092
|
+
nativeMutation: {
|
|
1093
|
+
mutatingAction: error.mutatingAction === true,
|
|
1094
|
+
replaySafe: error.mutatingAction !== true,
|
|
1095
|
+
...error.actionFingerprint ? { actionFingerprint: error.actionFingerprint } : {},
|
|
1096
|
+
...error.fileTarget ? { fileTarget: error.fileTarget } : {}
|
|
1097
|
+
}
|
|
1098
|
+
});
|
|
1099
|
+
this.lastNativeToolError = terminalResolution?.lastToolError ?? (this.lastNativeToolError?.mutatingAction && error.mutatingAction !== true ? this.lastNativeToolError : error);
|
|
960
1100
|
}
|
|
961
1101
|
recordDynamicToolResult(params) {
|
|
962
1102
|
const resultText = collectDynamicToolContentText(params.contentItems);
|
|
@@ -967,16 +1107,17 @@ var CodexToolProgressProjection = class {
|
|
|
967
1107
|
...params.asyncStarted === true ? { asyncStarted: true } : {},
|
|
968
1108
|
...!params.success ? { isError: true } : {}
|
|
969
1109
|
});
|
|
970
|
-
if (
|
|
1110
|
+
if (params.terminalResolution) this.lastNativeToolError = params.terminalResolution.lastToolError;
|
|
1111
|
+
else if (!params.success) this.lastNativeToolError = {
|
|
971
1112
|
toolName: params.tool,
|
|
972
|
-
error: resultText || "codex dynamic tool blocked"
|
|
1113
|
+
error: resultText || (params.terminalType === "blocked" ? "codex dynamic tool blocked" : "codex dynamic tool failed")
|
|
973
1114
|
};
|
|
974
|
-
else if (
|
|
1115
|
+
else if (this.lastNativeToolError?.mutatingAction !== true) this.lastNativeToolError = void 0;
|
|
975
1116
|
if (params.sideEffectEvidence === true) this.sideEffectingDynamicIds.add(params.callId);
|
|
976
1117
|
}
|
|
977
1118
|
handleOutputDelta(params, toolName) {
|
|
978
|
-
const itemId = readString$
|
|
979
|
-
const delta = readString$
|
|
1119
|
+
const itemId = readString$3(params, "itemId");
|
|
1120
|
+
const delta = readString$3(params, "delta");
|
|
980
1121
|
if (!itemId || !delta) return;
|
|
981
1122
|
const storedOutput = this.output.append(itemId, delta);
|
|
982
1123
|
this.rememberEcho(itemId, {
|
|
@@ -1017,25 +1158,37 @@ var CodexToolProgressProjection = class {
|
|
|
1017
1158
|
});
|
|
1018
1159
|
}
|
|
1019
1160
|
recordNativeToolError(params) {
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
|
|
1023
|
-
|
|
1024
|
-
|
|
1161
|
+
const executionStarted = params.status !== "blocked";
|
|
1162
|
+
const mutatingAction = executionStarted && isMutatingNativeToolItem(params.item);
|
|
1163
|
+
const actionFingerprint = mutatingAction ? nativeToolActionFingerprint(params.item) : void 0;
|
|
1164
|
+
const isFailure = isNonSuccessItemStatus(params.status);
|
|
1165
|
+
const error = isFailure ? itemToolError(params.item, params.status, this.output.textByItem) : void 0;
|
|
1166
|
+
const terminalResolution = this.params.observeToolTerminal?.({
|
|
1167
|
+
toolCallId: params.item.id,
|
|
1168
|
+
toolName: params.name,
|
|
1169
|
+
arguments: itemToolArgs(params.item),
|
|
1170
|
+
...params.meta ? { meta: params.meta } : {},
|
|
1171
|
+
executionStarted,
|
|
1172
|
+
outcome: isFailure ? "failure" : "success",
|
|
1173
|
+
...isFailure ? { failure: error ? { error } : {} } : {},
|
|
1174
|
+
nativeMutation: {
|
|
1175
|
+
mutatingAction,
|
|
1176
|
+
replaySafe: !mutatingAction,
|
|
1177
|
+
...actionFingerprint ? { actionFingerprint } : {}
|
|
1025
1178
|
}
|
|
1026
|
-
|
|
1027
|
-
|
|
1179
|
+
});
|
|
1180
|
+
if (terminalResolution) {
|
|
1181
|
+
this.lastNativeToolError = terminalResolution.lastToolError;
|
|
1028
1182
|
return;
|
|
1029
1183
|
}
|
|
1030
|
-
|
|
1031
|
-
const actionFingerprint = nativeToolActionFingerprint(params.item);
|
|
1032
|
-
this.lastNativeToolError = {
|
|
1184
|
+
if (isFailure) this.lastNativeToolError = {
|
|
1033
1185
|
toolName: params.name,
|
|
1034
1186
|
...params.meta ? { meta: params.meta } : {},
|
|
1035
1187
|
...error ? { error } : {},
|
|
1036
|
-
...
|
|
1188
|
+
...mutatingAction ? { mutatingAction: true } : {},
|
|
1037
1189
|
...actionFingerprint ? { actionFingerprint } : {}
|
|
1038
1190
|
};
|
|
1191
|
+
else if (this.lastNativeToolError?.mutatingAction !== true) this.lastNativeToolError = void 0;
|
|
1039
1192
|
}
|
|
1040
1193
|
emitToolResultSummary(item) {
|
|
1041
1194
|
if (!item || !this.params.onToolResult || !this.shouldEmitToolResult()) return;
|
|
@@ -1202,7 +1355,8 @@ async function readCodexMirroredSessionHistoryMessages(target) {
|
|
|
1202
1355
|
const entries = await readCodexMirroredSessionEntries(target);
|
|
1203
1356
|
if (entries.length === 0) return [];
|
|
1204
1357
|
const firstEntry = entries[0];
|
|
1205
|
-
if (firstEntry?.type !== "session"
|
|
1358
|
+
if (firstEntry?.type !== "session") return [];
|
|
1359
|
+
if (typeof firstEntry.id !== "string") return;
|
|
1206
1360
|
migrateSessionEntries(entries);
|
|
1207
1361
|
return sanitizeCodexHistoryImagePayloads(buildSessionContext(entries.filter((entry) => {
|
|
1208
1362
|
return entry !== null && typeof entry === "object" && !Array.isArray(entry) && entry.type !== "session";
|
|
@@ -1533,14 +1687,14 @@ var CodexEventProjection = class {
|
|
|
1533
1687
|
data: {
|
|
1534
1688
|
method,
|
|
1535
1689
|
phase: method.endsWith("/started") ? "started" : "completed",
|
|
1536
|
-
reviewId: readString$
|
|
1690
|
+
reviewId: readString$3(params, "reviewId"),
|
|
1537
1691
|
targetItemId: readNullableString(params, "targetItemId"),
|
|
1538
|
-
decisionSource: readString$
|
|
1539
|
-
status: review ? readString$
|
|
1540
|
-
riskLevel: review ? readString$
|
|
1541
|
-
userAuthorization: review ? readString$
|
|
1692
|
+
decisionSource: readString$3(params, "decisionSource"),
|
|
1693
|
+
status: review ? readString$3(review, "status") : void 0,
|
|
1694
|
+
riskLevel: review ? readString$3(review, "riskLevel") : void 0,
|
|
1695
|
+
userAuthorization: review ? readString$3(review, "userAuthorization") : void 0,
|
|
1542
1696
|
rationale: review ? readNullableString(review, "rationale") : void 0,
|
|
1543
|
-
actionType: action ? readString$
|
|
1697
|
+
actionType: action ? readString$3(action, "type") : void 0
|
|
1544
1698
|
}
|
|
1545
1699
|
});
|
|
1546
1700
|
}
|
|
@@ -1549,7 +1703,7 @@ var CodexEventProjection = class {
|
|
|
1549
1703
|
stream: "codex_app_server.guardian",
|
|
1550
1704
|
data: {
|
|
1551
1705
|
phase: "warning",
|
|
1552
|
-
message: readString$
|
|
1706
|
+
message: readString$3(params, "message")
|
|
1553
1707
|
}
|
|
1554
1708
|
});
|
|
1555
1709
|
}
|
|
@@ -1565,14 +1719,14 @@ var CodexEventProjection = class {
|
|
|
1565
1719
|
phase: method === "hook/started" ? "started" : "completed",
|
|
1566
1720
|
threadId: this.threadId,
|
|
1567
1721
|
turnId: hookTurnId === void 0 ? this.turnId : hookTurnId,
|
|
1568
|
-
hookRunId: readString$
|
|
1569
|
-
eventName: readString$
|
|
1570
|
-
handlerType: readString$
|
|
1571
|
-
executionMode: readString$
|
|
1572
|
-
scope: readString$
|
|
1573
|
-
source: readString$
|
|
1574
|
-
sourcePath: readString$
|
|
1575
|
-
status: readString$
|
|
1722
|
+
hookRunId: readString$3(run, "id"),
|
|
1723
|
+
eventName: readString$3(run, "eventName"),
|
|
1724
|
+
handlerType: readString$3(run, "handlerType"),
|
|
1725
|
+
executionMode: readString$3(run, "executionMode"),
|
|
1726
|
+
scope: readString$3(run, "scope"),
|
|
1727
|
+
source: readString$3(run, "source"),
|
|
1728
|
+
sourcePath: readString$3(run, "sourcePath"),
|
|
1729
|
+
status: readString$3(run, "status"),
|
|
1576
1730
|
statusMessage: readNullableString(run, "statusMessage"),
|
|
1577
1731
|
...durationMs !== void 0 ? { durationMs } : {},
|
|
1578
1732
|
...entries.length > 0 ? { entries } : {}
|
|
@@ -1673,10 +1827,10 @@ var CodexGeneratedMediaProjection = class {
|
|
|
1673
1827
|
});
|
|
1674
1828
|
}
|
|
1675
1829
|
async recordRaw(item) {
|
|
1676
|
-
if (readString$
|
|
1677
|
-
const result = readString$
|
|
1830
|
+
if (readString$3(item, "type") !== "image_generation_call") return;
|
|
1831
|
+
const result = readString$3(item, "result");
|
|
1678
1832
|
if (!result) return;
|
|
1679
|
-
const itemId = readString$
|
|
1833
|
+
const itemId = readString$3(item, "id") ?? `raw-image-${this.itemIds.size}`;
|
|
1680
1834
|
this.itemIds.add(itemId);
|
|
1681
1835
|
const maxBytes = resolveGeneratedImageMaxBytes(this.config);
|
|
1682
1836
|
const estimatedDecodedBytes = estimateBase64DecodedBytes(result);
|
|
@@ -1691,7 +1845,7 @@ var CodexGeneratedMediaProjection = class {
|
|
|
1691
1845
|
const asset = generatedImageAssetFromBase64({
|
|
1692
1846
|
base64: result,
|
|
1693
1847
|
index: this.itemIds.size,
|
|
1694
|
-
revisedPrompt: readString$
|
|
1848
|
+
revisedPrompt: readString$3(item, "revised_prompt") ?? readString$3(item, "revisedPrompt"),
|
|
1695
1849
|
fileNamePrefix: "codex-image-generation",
|
|
1696
1850
|
sniffMimeType: true
|
|
1697
1851
|
});
|
|
@@ -1749,6 +1903,90 @@ function resolveGeneratedImageMaxBytes(config) {
|
|
|
1749
1903
|
return DEFAULT_GENERATED_IMAGE_MAX_BYTES;
|
|
1750
1904
|
}
|
|
1751
1905
|
//#endregion
|
|
1906
|
+
//#region extensions/codex/src/app-server/dynamic-tool-response-state.ts
|
|
1907
|
+
function withDynamicToolTerminalResolution(response, terminalResolution) {
|
|
1908
|
+
if (terminalResolution) {
|
|
1909
|
+
Object.defineProperties(response, {
|
|
1910
|
+
terminalResolution: {
|
|
1911
|
+
configurable: true,
|
|
1912
|
+
enumerable: false,
|
|
1913
|
+
value: terminalResolution
|
|
1914
|
+
},
|
|
1915
|
+
executionStarted: {
|
|
1916
|
+
configurable: true,
|
|
1917
|
+
enumerable: false,
|
|
1918
|
+
value: terminalResolution.executionStarted
|
|
1919
|
+
},
|
|
1920
|
+
...terminalResolution.executedArguments ? { executedArguments: {
|
|
1921
|
+
configurable: true,
|
|
1922
|
+
enumerable: false,
|
|
1923
|
+
value: terminalResolution.executedArguments
|
|
1924
|
+
} } : {}
|
|
1925
|
+
});
|
|
1926
|
+
withDynamicToolSideEffectEvidence(response, terminalResolution.sideEffectEvidence);
|
|
1927
|
+
}
|
|
1928
|
+
return response;
|
|
1929
|
+
}
|
|
1930
|
+
function withDynamicToolExecutionState(response, state) {
|
|
1931
|
+
Object.defineProperties(response, {
|
|
1932
|
+
executedArguments: {
|
|
1933
|
+
configurable: true,
|
|
1934
|
+
enumerable: false,
|
|
1935
|
+
value: state.executedArguments
|
|
1936
|
+
},
|
|
1937
|
+
executionStarted: {
|
|
1938
|
+
configurable: true,
|
|
1939
|
+
enumerable: false,
|
|
1940
|
+
value: state.executionStarted
|
|
1941
|
+
}
|
|
1942
|
+
});
|
|
1943
|
+
return withDynamicToolSideEffectEvidence(response, state.sideEffectEvidence === true);
|
|
1944
|
+
}
|
|
1945
|
+
function withDynamicToolSideEffectEvidence(response, sideEffectEvidence) {
|
|
1946
|
+
if (!sideEffectEvidence) {
|
|
1947
|
+
delete response.sideEffectEvidence;
|
|
1948
|
+
return response;
|
|
1949
|
+
}
|
|
1950
|
+
Object.defineProperty(response, "sideEffectEvidence", {
|
|
1951
|
+
configurable: true,
|
|
1952
|
+
enumerable: false,
|
|
1953
|
+
value: true
|
|
1954
|
+
});
|
|
1955
|
+
return response;
|
|
1956
|
+
}
|
|
1957
|
+
function createFailedDynamicToolResponse(message, options) {
|
|
1958
|
+
const response = {
|
|
1959
|
+
contentItems: [{
|
|
1960
|
+
type: "inputText",
|
|
1961
|
+
text: message
|
|
1962
|
+
}],
|
|
1963
|
+
success: false
|
|
1964
|
+
};
|
|
1965
|
+
Object.defineProperties(response, {
|
|
1966
|
+
diagnosticTerminalReason: {
|
|
1967
|
+
configurable: true,
|
|
1968
|
+
enumerable: false,
|
|
1969
|
+
value: options?.terminalReason ?? "failed"
|
|
1970
|
+
},
|
|
1971
|
+
diagnosticTerminalType: {
|
|
1972
|
+
configurable: true,
|
|
1973
|
+
enumerable: false,
|
|
1974
|
+
value: "error"
|
|
1975
|
+
}
|
|
1976
|
+
});
|
|
1977
|
+
if (options?.executionStarted !== void 0) Object.defineProperty(response, "executionStarted", {
|
|
1978
|
+
configurable: true,
|
|
1979
|
+
enumerable: false,
|
|
1980
|
+
value: options.executionStarted
|
|
1981
|
+
});
|
|
1982
|
+
if (options?.executedArguments !== void 0) Object.defineProperty(response, "executedArguments", {
|
|
1983
|
+
configurable: true,
|
|
1984
|
+
enumerable: false,
|
|
1985
|
+
value: options.executedArguments
|
|
1986
|
+
});
|
|
1987
|
+
return withDynamicToolSideEffectEvidence(response, options?.sideEffectEvidence === true);
|
|
1988
|
+
}
|
|
1989
|
+
//#endregion
|
|
1752
1990
|
//#region extensions/codex/src/app-server/tool-abort-terminal-reason.ts
|
|
1753
1991
|
/** Leaf helper shared by native and dynamic tool diagnostics. */
|
|
1754
1992
|
const CODEX_TIMEOUT_ABORT_REASONS = /* @__PURE__ */ new Set([
|
|
@@ -1846,6 +2084,30 @@ function formatDynamicToolTimeoutDetails(params) {
|
|
|
1846
2084
|
*/
|
|
1847
2085
|
async function handleDynamicToolCallWithTimeout(params) {
|
|
1848
2086
|
let didNotifyAgentToolResult = false;
|
|
2087
|
+
const conservativeRaceResponses = /* @__PURE__ */ new WeakSet();
|
|
2088
|
+
const finalizeTerminal = (response) => {
|
|
2089
|
+
const executionSnapshot = params.toolBridge.consumeToolExecutionSnapshot?.(params.call.callId);
|
|
2090
|
+
const observedExecutionStarted = executionSnapshot?.executionStarted ?? (conservativeRaceResponses.has(response) ? void 0 : response.executionStarted);
|
|
2091
|
+
const terminalResolution = params.observeToolTerminal?.({
|
|
2092
|
+
toolCallId: params.call.callId,
|
|
2093
|
+
toolName: params.call.tool,
|
|
2094
|
+
arguments: response.executedArguments ?? executionSnapshot?.executedArguments ?? params.call.arguments,
|
|
2095
|
+
...params.toolMeta ? { meta: params.toolMeta } : {},
|
|
2096
|
+
...observedExecutionStarted !== void 0 ? { executionStarted: observedExecutionStarted } : {},
|
|
2097
|
+
outcome: response.success ? "success" : "failure",
|
|
2098
|
+
...!response.success ? { failure: { error: readDynamicToolResponseText(response) } } : {}
|
|
2099
|
+
});
|
|
2100
|
+
return withDynamicToolTerminalResolution(response, terminalResolution);
|
|
2101
|
+
};
|
|
2102
|
+
const createFailedAfterPossibleDispatch = (message, terminalReason) => {
|
|
2103
|
+
const response = createFailedDynamicToolResponse(message, {
|
|
2104
|
+
executionStarted: true,
|
|
2105
|
+
sideEffectEvidence: true,
|
|
2106
|
+
terminalReason
|
|
2107
|
+
});
|
|
2108
|
+
conservativeRaceResponses.add(response);
|
|
2109
|
+
return response;
|
|
2110
|
+
};
|
|
1849
2111
|
const notifyAgentToolResult = (event) => {
|
|
1850
2112
|
if (didNotifyAgentToolResult) return;
|
|
1851
2113
|
didNotifyAgentToolResult = true;
|
|
@@ -1876,7 +2138,10 @@ async function handleDynamicToolCallWithTimeout(params) {
|
|
|
1876
2138
|
const terminalReason = resolveCodexToolAbortTerminalReason(params.signal);
|
|
1877
2139
|
params.onFallbackSelected?.();
|
|
1878
2140
|
notifyFailedToolResult(message, terminalReason);
|
|
1879
|
-
return
|
|
2141
|
+
return finalizeTerminal(createFailedDynamicToolResponse(message, {
|
|
2142
|
+
executionStarted: false,
|
|
2143
|
+
terminalReason
|
|
2144
|
+
}));
|
|
1880
2145
|
}
|
|
1881
2146
|
const controller = new AbortController();
|
|
1882
2147
|
let timeout;
|
|
@@ -1888,10 +2153,7 @@ async function handleDynamicToolCallWithTimeout(params) {
|
|
|
1888
2153
|
params.onFallbackSelected?.();
|
|
1889
2154
|
controller.abort(params.signal.reason ?? /* @__PURE__ */ new Error(message));
|
|
1890
2155
|
notifyFailedToolResult(message, terminalReason);
|
|
1891
|
-
resolveAbort?.(
|
|
1892
|
-
sideEffectEvidence: true,
|
|
1893
|
-
terminalReason
|
|
1894
|
-
}));
|
|
2156
|
+
resolveAbort?.(createFailedAfterPossibleDispatch(message, terminalReason));
|
|
1895
2157
|
};
|
|
1896
2158
|
const abortPromise = new Promise((resolve) => {
|
|
1897
2159
|
resolveAbort = resolve;
|
|
@@ -1912,10 +2174,7 @@ async function handleDynamicToolCallWithTimeout(params) {
|
|
|
1912
2174
|
consoleMessage: timeoutDetails.consoleMessage
|
|
1913
2175
|
});
|
|
1914
2176
|
notifyFailedToolResult(timeoutDetails.responseMessage, "timed_out");
|
|
1915
|
-
resolve(
|
|
1916
|
-
sideEffectEvidence: true,
|
|
1917
|
-
terminalReason: "timed_out"
|
|
1918
|
-
}));
|
|
2177
|
+
resolve(createFailedAfterPossibleDispatch(timeoutDetails.responseMessage, "timed_out"));
|
|
1919
2178
|
}, timeoutMs);
|
|
1920
2179
|
timeout.unref?.();
|
|
1921
2180
|
});
|
|
@@ -1926,21 +2185,19 @@ async function handleDynamicToolCallWithTimeout(params) {
|
|
|
1926
2185
|
params.toolBridge.handleToolCall(params.call, {
|
|
1927
2186
|
signal: controller.signal,
|
|
1928
2187
|
onAgentToolResult: notifyAgentToolResult,
|
|
1929
|
-
toolCallOrdinal: params.toolCallOrdinal
|
|
2188
|
+
toolCallOrdinal: params.toolCallOrdinal,
|
|
2189
|
+
retainExecutionSnapshot: true
|
|
1930
2190
|
}),
|
|
1931
2191
|
abortPromise,
|
|
1932
2192
|
timeoutPromise
|
|
1933
2193
|
]);
|
|
1934
2194
|
if (!response.success && !didNotifyAgentToolResult) notifyFailedToolResult(readDynamicToolResponseText(response), response.diagnosticTerminalReason ?? "failed");
|
|
1935
|
-
return response;
|
|
2195
|
+
return finalizeTerminal(response);
|
|
1936
2196
|
} catch (error) {
|
|
1937
2197
|
const terminalReason = params.signal.aborted ? resolveCodexToolAbortTerminalReason(params.signal) : resolveToolExecutionErrorKind(error);
|
|
1938
2198
|
const message = formatToolExecutionErrorMessage(error, "OpenClaw dynamic tool call failed.");
|
|
1939
2199
|
notifyFailedToolResult(message, terminalReason);
|
|
1940
|
-
return
|
|
1941
|
-
sideEffectEvidence: true,
|
|
1942
|
-
terminalReason
|
|
1943
|
-
});
|
|
2200
|
+
return finalizeTerminal(createFailedAfterPossibleDispatch(message, terminalReason));
|
|
1944
2201
|
} finally {
|
|
1945
2202
|
if (timeout) clearTimeout(timeout);
|
|
1946
2203
|
params.signal.removeEventListener("abort", abortFromRun);
|
|
@@ -1951,31 +2208,6 @@ async function handleDynamicToolCallWithTimeout(params) {
|
|
|
1951
2208
|
function readDynamicToolResponseText(response) {
|
|
1952
2209
|
return response.contentItems.flatMap((item) => item.type === "inputText" && typeof item.text === "string" ? [item.text] : []).join("\n").trim() || "OpenClaw dynamic tool call failed.";
|
|
1953
2210
|
}
|
|
1954
|
-
function failedDynamicToolResponse(message, options) {
|
|
1955
|
-
const response = {
|
|
1956
|
-
contentItems: [{
|
|
1957
|
-
type: "inputText",
|
|
1958
|
-
text: message
|
|
1959
|
-
}],
|
|
1960
|
-
success: false
|
|
1961
|
-
};
|
|
1962
|
-
Object.defineProperty(response, "diagnosticTerminalType", {
|
|
1963
|
-
configurable: true,
|
|
1964
|
-
enumerable: false,
|
|
1965
|
-
value: "error"
|
|
1966
|
-
});
|
|
1967
|
-
Object.defineProperty(response, "diagnosticTerminalReason", {
|
|
1968
|
-
configurable: true,
|
|
1969
|
-
enumerable: false,
|
|
1970
|
-
value: options?.terminalReason ?? "failed"
|
|
1971
|
-
});
|
|
1972
|
-
if (options?.sideEffectEvidence === true) Object.defineProperty(response, "sideEffectEvidence", {
|
|
1973
|
-
configurable: true,
|
|
1974
|
-
enumerable: false,
|
|
1975
|
-
value: true
|
|
1976
|
-
});
|
|
1977
|
-
return response;
|
|
1978
|
-
}
|
|
1979
2211
|
/** Strips OpenClaw-only metadata before sending a dynamic tool response to Codex. */
|
|
1980
2212
|
function toCodexDynamicToolProtocolResponse(response) {
|
|
1981
2213
|
return {
|
|
@@ -2181,6 +2413,7 @@ function createCodexNativeHookRelay(params) {
|
|
|
2181
2413
|
runId: params.runId,
|
|
2182
2414
|
...params.channelId ? { channelId: params.channelId } : {},
|
|
2183
2415
|
allowedEvents: params.events,
|
|
2416
|
+
preToolUseLoopDetection: params.loopDetectionPreToolUseRelay,
|
|
2184
2417
|
ttlMs: resolveCodexNativeHookRelayTtlMs({
|
|
2185
2418
|
explicitTtlMs: params.options?.ttlMs,
|
|
2186
2419
|
attemptTimeoutMs: params.attemptTimeoutMs,
|
|
@@ -2239,7 +2472,8 @@ function buildCodexNativeHookRelayConfig(params) {
|
|
|
2239
2472
|
const codexEvent = CODEX_HOOK_EVENT_BY_NATIVE_EVENT[event];
|
|
2240
2473
|
const selected = selectedEvents.has(event);
|
|
2241
2474
|
const shouldRelay = params.relay.shouldRelayEvent(event);
|
|
2242
|
-
|
|
2475
|
+
const selectedNoopPreToolUse = selected && event === "pre_tool_use" && !shouldRelay && params.loopDetectionPreToolUseRelay;
|
|
2476
|
+
if (!selected || !shouldRelay && !selectedNoopPreToolUse) {
|
|
2243
2477
|
if (selected || params.clearOmittedEvents) config[`hooks.${codexEvent}`] = [];
|
|
2244
2478
|
if (params.clearOmittedEvents) for (const sourcePath of CODEX_SESSION_FLAGS_HOOK_SOURCE_PATHS) hookState[`${sourcePath}:${CODEX_HOOK_KEY_LABEL_BY_NATIVE_EVENT[event]}:0:0`] = { enabled: false };
|
|
2245
2479
|
continue;
|
|
@@ -2382,12 +2616,12 @@ var CodexNativeToolLifecycleProjector = class {
|
|
|
2382
2616
|
this.preToolUseFailureByItem.set(failure.toolCallId, record);
|
|
2383
2617
|
}
|
|
2384
2618
|
recordRawWebSearchResult(item) {
|
|
2385
|
-
if (readString$
|
|
2386
|
-
const toolCallId = readString$
|
|
2619
|
+
if (readString$3(item, "type") !== "web_search_call") return;
|
|
2620
|
+
const toolCallId = readString$3(item, "id");
|
|
2387
2621
|
if (!toolCallId || this.completedItemIds.has(toolCallId)) return;
|
|
2388
2622
|
const toolName = "web_search";
|
|
2389
2623
|
this.recordStarted(toolCallId, toolName, "unknown");
|
|
2390
|
-
const rawStatus = readString$
|
|
2624
|
+
const rawStatus = readString$3(item, "status");
|
|
2391
2625
|
if (rawStatus === "in_progress" || rawStatus === "running") return;
|
|
2392
2626
|
const status = rawStatus === "completed" ? "completed" : rawStatus === "cancelled" ? "cancelled" : rawStatus === "failed" || rawStatus === "error" || rawStatus === "incomplete" ? "failed" : "unknown";
|
|
2393
2627
|
this.recordTerminal(toolCallId, toolName, status, { sourceTimestampMs: this.webSearchCompletionByItem.get(toolCallId)?.sourceTimestampMs });
|
|
@@ -2512,8 +2746,8 @@ var CodexReasoningProjection = class {
|
|
|
2512
2746
|
this.reasoningEnded = false;
|
|
2513
2747
|
}
|
|
2514
2748
|
async handleReasoningDelta(method, params) {
|
|
2515
|
-
const itemId = readString$
|
|
2516
|
-
const delta = readString$
|
|
2749
|
+
const itemId = readString$3(params, "itemId") ?? "reasoning";
|
|
2750
|
+
const delta = readString$3(params, "delta") ?? "";
|
|
2517
2751
|
if (!delta) return;
|
|
2518
2752
|
this.reasoningStarted = true;
|
|
2519
2753
|
if (!this.reasoningItemOrder.has(itemId)) this.reasoningItemOrder.set(itemId, this.reasoningItemOrder.size);
|
|
@@ -2532,27 +2766,35 @@ var CodexReasoningProjection = class {
|
|
|
2532
2766
|
});
|
|
2533
2767
|
}
|
|
2534
2768
|
handlePlanDelta(params) {
|
|
2535
|
-
const itemId = readString$
|
|
2536
|
-
const delta = readString$
|
|
2769
|
+
const itemId = readString$3(params, "itemId") ?? "plan";
|
|
2770
|
+
const delta = readString$3(params, "delta") ?? "";
|
|
2537
2771
|
if (!delta) return;
|
|
2538
2772
|
const text = `${this.planTextByItem.get(itemId) ?? ""}${delta}`;
|
|
2539
2773
|
this.planTextByItem.set(itemId, text);
|
|
2540
2774
|
this.emitPlanUpdate({
|
|
2541
2775
|
explanation: void 0,
|
|
2542
|
-
steps: splitPlanText(text)
|
|
2776
|
+
steps: splitPlanText(text).map((step) => ({
|
|
2777
|
+
step,
|
|
2778
|
+
status: "pending"
|
|
2779
|
+
}))
|
|
2543
2780
|
});
|
|
2544
2781
|
}
|
|
2545
2782
|
handleTurnPlanUpdated(params) {
|
|
2783
|
+
const explanation = readNullableString(params, "explanation");
|
|
2546
2784
|
const plan = Array.isArray(params.plan) ? params.plan.flatMap((entry) => {
|
|
2547
2785
|
if (!entry || typeof entry !== "object" || Array.isArray(entry)) return [];
|
|
2548
2786
|
const record = entry;
|
|
2549
|
-
const step = readString$
|
|
2550
|
-
const status = readString$2(record, "status");
|
|
2787
|
+
const step = readString$3(record, "step");
|
|
2551
2788
|
if (!step) return [];
|
|
2552
|
-
return
|
|
2789
|
+
return [{
|
|
2790
|
+
step,
|
|
2791
|
+
status: normalizePlanStepStatus(readString$3(record, "status"))
|
|
2792
|
+
}];
|
|
2553
2793
|
}) : void 0;
|
|
2794
|
+
const planText = [explanation, ...(plan ?? []).map(({ step, status }) => `- [${status}] ${step}`)].filter((part) => Boolean(part)).join("\n");
|
|
2795
|
+
if (planText) this.turnPlanText = planText;
|
|
2554
2796
|
this.emitPlanUpdate({
|
|
2555
|
-
explanation
|
|
2797
|
+
explanation,
|
|
2556
2798
|
steps: plan
|
|
2557
2799
|
});
|
|
2558
2800
|
}
|
|
@@ -2561,7 +2803,10 @@ var CodexReasoningProjection = class {
|
|
|
2561
2803
|
this.planTextByItem.set(item.id, item.text);
|
|
2562
2804
|
this.emitPlanUpdate({
|
|
2563
2805
|
explanation: void 0,
|
|
2564
|
-
steps: splitPlanText(item.text)
|
|
2806
|
+
steps: splitPlanText(item.text).map((step) => ({
|
|
2807
|
+
step,
|
|
2808
|
+
status: "pending"
|
|
2809
|
+
}))
|
|
2565
2810
|
});
|
|
2566
2811
|
}
|
|
2567
2812
|
}
|
|
@@ -2574,7 +2819,7 @@ var CodexReasoningProjection = class {
|
|
|
2574
2819
|
return collectReasoningTextValues(this.reasoningTextByGroup, this.reasoningItemOrder).join("\n\n");
|
|
2575
2820
|
}
|
|
2576
2821
|
planText() {
|
|
2577
|
-
return [...this.planTextByItem.values()].filter((text) => text.trim().length > 0).join("\n\n");
|
|
2822
|
+
return this.turnPlanText ?? [...this.planTextByItem.values()].filter((text) => text.trim().length > 0).join("\n\n");
|
|
2578
2823
|
}
|
|
2579
2824
|
emitPlanUpdate(params) {
|
|
2580
2825
|
if (!params.explanation && (!params.steps || params.steps.length === 0)) return;
|
|
@@ -2590,6 +2835,10 @@ var CodexReasoningProjection = class {
|
|
|
2590
2835
|
});
|
|
2591
2836
|
}
|
|
2592
2837
|
};
|
|
2838
|
+
function normalizePlanStepStatus(status) {
|
|
2839
|
+
if (status === "inProgress" || status === "in_progress") return "in_progress";
|
|
2840
|
+
return status === "completed" ? "completed" : "pending";
|
|
2841
|
+
}
|
|
2593
2842
|
function collectReasoningTextValues(groups, itemOrder) {
|
|
2594
2843
|
return [...groups.values()].toSorted((left, right) => {
|
|
2595
2844
|
const itemDelta = (itemOrder.get(left.itemId) ?? Number.MAX_SAFE_INTEGER) - (itemOrder.get(right.itemId) ?? Number.MAX_SAFE_INTEGER);
|
|
@@ -2603,15 +2852,193 @@ function reasoningMethodOrder(method) {
|
|
|
2603
2852
|
}
|
|
2604
2853
|
//#endregion
|
|
2605
2854
|
//#region extensions/codex/src/app-server/event-projector-usage.ts
|
|
2606
|
-
function
|
|
2855
|
+
function readTokenCount(record, key) {
|
|
2856
|
+
const value = readNonNegativeInteger(record, key);
|
|
2857
|
+
return value !== void 0 && Number.isSafeInteger(value) ? value : void 0;
|
|
2858
|
+
}
|
|
2859
|
+
function readCodexThreadTokenUsage(params) {
|
|
2860
|
+
const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
|
|
2861
|
+
const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
|
|
2862
|
+
return last ? normalizeCodexThreadTokenUsage(last) : void 0;
|
|
2863
|
+
}
|
|
2864
|
+
function normalizeCodexThreadTokenUsage(record) {
|
|
2607
2865
|
const inputTokens = readNumber(record, "inputTokens");
|
|
2608
2866
|
const cacheRead = readNumber(record, "cachedInputTokens");
|
|
2609
|
-
|
|
2867
|
+
const usage = normalizeUsage({
|
|
2610
2868
|
input: inputTokens !== void 0 && cacheRead !== void 0 ? Math.max(0, inputTokens - cacheRead) : inputTokens,
|
|
2611
2869
|
output: readNumber(record, "outputTokens"),
|
|
2612
2870
|
cacheRead,
|
|
2613
2871
|
total: readNumber(record, "totalTokens")
|
|
2614
2872
|
});
|
|
2873
|
+
return usage ? {
|
|
2874
|
+
...usage,
|
|
2875
|
+
contextUsage: { state: "unavailable" }
|
|
2876
|
+
} : void 0;
|
|
2877
|
+
}
|
|
2878
|
+
function normalizeCodexResponseTokenUsage(record) {
|
|
2879
|
+
const totalTokens = readTokenCount(record, "totalTokens");
|
|
2880
|
+
const inputTokens = readTokenCount(record, "inputTokens");
|
|
2881
|
+
const cacheRead = readTokenCount(record, "cachedInputTokens");
|
|
2882
|
+
const output = readTokenCount(record, "outputTokens");
|
|
2883
|
+
const reasoningOutput = readTokenCount(record, "reasoningOutputTokens");
|
|
2884
|
+
const cacheWrite = record.cacheWriteInputTokens === void 0 ? 0 : readTokenCount(record, "cacheWriteInputTokens");
|
|
2885
|
+
if (totalTokens === void 0 || inputTokens === void 0 || cacheRead === void 0 || cacheWrite === void 0 || output === void 0 || reasoningOutput === void 0 || cacheRead + cacheWrite > inputTokens || totalTokens !== inputTokens + output) return;
|
|
2886
|
+
const usage = normalizeUsage({
|
|
2887
|
+
input: inputTokens - cacheRead - cacheWrite,
|
|
2888
|
+
output,
|
|
2889
|
+
cacheRead,
|
|
2890
|
+
cacheWrite,
|
|
2891
|
+
total: totalTokens
|
|
2892
|
+
});
|
|
2893
|
+
if (!usage) return;
|
|
2894
|
+
return {
|
|
2895
|
+
...usage,
|
|
2896
|
+
contextUsage: {
|
|
2897
|
+
state: "available",
|
|
2898
|
+
promptTokens: inputTokens,
|
|
2899
|
+
totalTokens
|
|
2900
|
+
}
|
|
2901
|
+
};
|
|
2902
|
+
}
|
|
2903
|
+
//#endregion
|
|
2904
|
+
//#region extensions/codex/src/app-server/usage-limit-error.ts
|
|
2905
|
+
/**
|
|
2906
|
+
* Enriches Codex usage-limit failures with current rate-limit information and
|
|
2907
|
+
* marks blocked auth profiles when Codex exposes a reset time.
|
|
2908
|
+
*/
|
|
2909
|
+
const CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS = 5e3;
|
|
2910
|
+
function createCodexUsageLimitPromptError(message) {
|
|
2911
|
+
return Object.assign(new Error(message), { status: 429 });
|
|
2912
|
+
}
|
|
2913
|
+
function isCodexUsageLimitPromptError(error) {
|
|
2914
|
+
return error instanceof Error && "status" in error && error.status === 429;
|
|
2915
|
+
}
|
|
2916
|
+
/** Marks a Codex auth profile blocked until the reset time advertised by rate limits. */
|
|
2917
|
+
async function markCodexAuthProfileBlockedFromRateLimits(params) {
|
|
2918
|
+
const authProfileId = params.authProfileId?.trim();
|
|
2919
|
+
if (!authProfileId || !params.params.authProfileStore) return;
|
|
2920
|
+
const blockedUntil = resolveCodexUsageLimitResetAtMs(params.rateLimits);
|
|
2921
|
+
if (!blockedUntil) return;
|
|
2922
|
+
try {
|
|
2923
|
+
await markAuthProfileBlockedUntil({
|
|
2924
|
+
store: params.params.authProfileStore,
|
|
2925
|
+
profileId: authProfileId,
|
|
2926
|
+
blockedUntil,
|
|
2927
|
+
source: "codex_rate_limits",
|
|
2928
|
+
agentDir: params.params.agentDir,
|
|
2929
|
+
runId: params.params.runId,
|
|
2930
|
+
modelId: params.params.modelId
|
|
2931
|
+
});
|
|
2932
|
+
} catch (error) {
|
|
2933
|
+
embeddedAgentLog.debug("failed to mark Codex auth profile blocked from app-server limits", {
|
|
2934
|
+
authProfileId,
|
|
2935
|
+
error: formatErrorMessage(error)
|
|
2936
|
+
});
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
/** Formats a turn-start usage-limit error, refreshing rate limits when needed. */
|
|
2940
|
+
async function formatCodexTurnStartUsageLimitError(params) {
|
|
2941
|
+
return refreshCodexUsageLimitError({
|
|
2942
|
+
client: params.client,
|
|
2943
|
+
source: readCodexTurnStartUsageLimitErrorSource(params.client, params.error, params.errorNotification, params.rateLimitsRevisionBeforeTurnStart),
|
|
2944
|
+
timeoutMs: params.timeoutMs,
|
|
2945
|
+
signal: params.signal
|
|
2946
|
+
});
|
|
2947
|
+
}
|
|
2948
|
+
/** Refreshes a generic prompt usage-limit message into a reset-aware message. */
|
|
2949
|
+
async function refreshCodexUsageLimitPromptError(params) {
|
|
2950
|
+
if (!shouldRefreshCodexRateLimitsForUsageLimitMessage(params.message)) return;
|
|
2951
|
+
return refreshCodexUsageLimitError({
|
|
2952
|
+
client: params.client,
|
|
2953
|
+
source: {
|
|
2954
|
+
message: params.message,
|
|
2955
|
+
codexErrorInfo: "usageLimitExceeded",
|
|
2956
|
+
rateLimits: readRecentCodexRateLimits(params.client)
|
|
2957
|
+
},
|
|
2958
|
+
timeoutMs: params.timeoutMs,
|
|
2959
|
+
signal: params.signal
|
|
2960
|
+
});
|
|
2961
|
+
}
|
|
2962
|
+
async function refreshCodexUsageLimitError(params) {
|
|
2963
|
+
const initialMessage = formatCodexUsageLimitErrorMessage(params.source);
|
|
2964
|
+
if (!shouldRefreshCodexRateLimitsForUsageLimitMessage(initialMessage)) return initialMessage ? {
|
|
2965
|
+
message: initialMessage,
|
|
2966
|
+
...params.source.rateLimitsTrustedForProfile ? { rateLimitsForProfile: params.source.rateLimits } : {}
|
|
2967
|
+
} : void 0;
|
|
2968
|
+
const rateLimits = await readCodexRateLimitsFromAppServerForUsageLimitError({
|
|
2969
|
+
client: params.client,
|
|
2970
|
+
timeoutMs: params.timeoutMs,
|
|
2971
|
+
signal: params.signal
|
|
2972
|
+
});
|
|
2973
|
+
if (!rateLimits) return initialMessage ? {
|
|
2974
|
+
message: initialMessage,
|
|
2975
|
+
...params.source.rateLimitsTrustedForProfile ? { rateLimitsForProfile: params.source.rateLimits } : {}
|
|
2976
|
+
} : void 0;
|
|
2977
|
+
const message = formatCodexUsageLimitErrorMessage({
|
|
2978
|
+
message: params.source.message,
|
|
2979
|
+
codexErrorInfo: params.source.codexErrorInfo,
|
|
2980
|
+
rateLimits,
|
|
2981
|
+
rateLimitsAuthoritative: true
|
|
2982
|
+
}) ?? initialMessage;
|
|
2983
|
+
return message ? {
|
|
2984
|
+
message,
|
|
2985
|
+
rateLimitsForProfile: rateLimits
|
|
2986
|
+
} : void 0;
|
|
2987
|
+
}
|
|
2988
|
+
async function readCodexRateLimitsFromAppServerForUsageLimitError(params) {
|
|
2989
|
+
if (params.signal?.aborted) return;
|
|
2990
|
+
try {
|
|
2991
|
+
const rateLimits = await params.client.request(CODEX_CONTROL_METHODS.rateLimits, void 0, {
|
|
2992
|
+
timeoutMs: resolveCodexUsageLimitRateLimitRefreshTimeoutMs(params.timeoutMs),
|
|
2993
|
+
signal: params.signal
|
|
2994
|
+
});
|
|
2995
|
+
rememberCodexRateLimitsRead(params.client, rateLimits);
|
|
2996
|
+
return rateLimits;
|
|
2997
|
+
} catch (error) {
|
|
2998
|
+
embeddedAgentLog.debug("codex app-server rate-limit refresh failed after usage-limit error", { error: formatErrorMessage(error) });
|
|
2999
|
+
return;
|
|
3000
|
+
}
|
|
3001
|
+
}
|
|
3002
|
+
function resolveCodexUsageLimitRateLimitRefreshTimeoutMs(timeoutMs) {
|
|
3003
|
+
if (timeoutMs === void 0 || !Number.isFinite(timeoutMs) || timeoutMs <= 0) return CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS;
|
|
3004
|
+
return Math.max(100, Math.min(timeoutMs, CODEX_USAGE_LIMIT_RATE_LIMIT_REFRESH_TIMEOUT_MS));
|
|
3005
|
+
}
|
|
3006
|
+
function readCodexTurnStartUsageLimitErrorSource(client, error, errorNotification, rateLimitsRevisionBeforeTurnStart) {
|
|
3007
|
+
const notificationError = readCodexErrorNotification(errorNotification);
|
|
3008
|
+
const errorPayload = readCodexErrorPayload(error);
|
|
3009
|
+
const rateLimits = errorPayload.rateLimits ?? readRecentCodexRateLimits(client);
|
|
3010
|
+
const cacheUpdatedDuringTurnStart = rateLimitsRevisionBeforeTurnStart !== void 0 && readCodexRateLimitsRevision(client) > rateLimitsRevisionBeforeTurnStart;
|
|
3011
|
+
return {
|
|
3012
|
+
message: notificationError?.message ?? errorPayload.message ?? formatErrorMessage(error),
|
|
3013
|
+
codexErrorInfo: notificationError?.codexErrorInfo ?? errorPayload.codexErrorInfo,
|
|
3014
|
+
rateLimits,
|
|
3015
|
+
rateLimitsTrustedForProfile: errorPayload.rateLimits !== void 0 || cacheUpdatedDuringTurnStart
|
|
3016
|
+
};
|
|
3017
|
+
}
|
|
3018
|
+
function readCodexErrorNotification(notification) {
|
|
3019
|
+
if (notification?.method !== "error" || !isJsonObject(notification.params)) return;
|
|
3020
|
+
const error = notification.params.error;
|
|
3021
|
+
return isJsonObject(error) ? {
|
|
3022
|
+
message: readString$2(error, "message"),
|
|
3023
|
+
codexErrorInfo: error.codexErrorInfo
|
|
3024
|
+
} : void 0;
|
|
3025
|
+
}
|
|
3026
|
+
function readCodexErrorPayload(error) {
|
|
3027
|
+
const message = error instanceof Error ? error.message : void 0;
|
|
3028
|
+
if (!error || typeof error !== "object" || !("data" in error)) return { message };
|
|
3029
|
+
const data = error.data;
|
|
3030
|
+
if (!isJsonObject(data)) return { message };
|
|
3031
|
+
const nestedError = isJsonObject(data.error) ? data.error : data;
|
|
3032
|
+
const rateLimits = nestedError.rateLimits ?? data.rateLimits;
|
|
3033
|
+
return {
|
|
3034
|
+
message: readString$2(nestedError, "message") ?? message,
|
|
3035
|
+
codexErrorInfo: nestedError.codexErrorInfo,
|
|
3036
|
+
rateLimits
|
|
3037
|
+
};
|
|
3038
|
+
}
|
|
3039
|
+
function readString$2(record, key) {
|
|
3040
|
+
const value = record[key];
|
|
3041
|
+
return typeof value === "string" ? value : void 0;
|
|
2615
3042
|
}
|
|
2616
3043
|
//#endregion
|
|
2617
3044
|
//#region extensions/codex/src/app-server/event-projector.ts
|
|
@@ -2630,6 +3057,7 @@ var CodexAppServerEventProjector = class {
|
|
|
2630
3057
|
this.synthesizedMissingToolResultError = null;
|
|
2631
3058
|
this.aborted = false;
|
|
2632
3059
|
this.completedCompactionCount = 0;
|
|
3060
|
+
this.diagnostics = new CodexProjectionDiagnostics(threadId, turnId);
|
|
2633
3061
|
this.nativeToolLifecycleProjector = new CodexNativeToolLifecycleProjector(params, threadId, turnId, { runAbortSignal: options.runAbortSignal });
|
|
2634
3062
|
this.generatedMediaProjection = new CodexGeneratedMediaProjection(params.config);
|
|
2635
3063
|
this.toolProgressProjection = new CodexToolProgressProjection(params);
|
|
@@ -2720,20 +3148,38 @@ var CodexAppServerEventProjector = class {
|
|
|
2720
3148
|
this.eventProjection.handleHook(notification.method, params);
|
|
2721
3149
|
break;
|
|
2722
3150
|
case "thread/tokenUsage/updated":
|
|
2723
|
-
this.
|
|
3151
|
+
this.tokenUsage = readCodexThreadTokenUsage(params) ?? this.tokenUsage;
|
|
2724
3152
|
break;
|
|
2725
3153
|
case "turn/completed":
|
|
2726
3154
|
await this.handleTurnCompleted(params);
|
|
2727
3155
|
break;
|
|
3156
|
+
case "rawResponse/completed":
|
|
3157
|
+
this.handleRawResponseCompleted(params);
|
|
3158
|
+
break;
|
|
2728
3159
|
case "rawResponseItem/completed":
|
|
2729
3160
|
await this.handleRawResponseItemCompleted(params);
|
|
2730
3161
|
break;
|
|
2731
3162
|
case "error":
|
|
3163
|
+
this.responseUsage = void 0;
|
|
2732
3164
|
if (params.willRetry === true) break;
|
|
2733
3165
|
this.promptError = this.formatCodexErrorMessage(params) ?? "codex app-server error";
|
|
2734
3166
|
this.promptErrorSource = "prompt";
|
|
2735
3167
|
break;
|
|
2736
|
-
|
|
3168
|
+
case "thread/compacted":
|
|
3169
|
+
case "turn/started":
|
|
3170
|
+
case "turn/diff/updated":
|
|
3171
|
+
case "item/reasoning/summaryPartAdded":
|
|
3172
|
+
case "item/commandExecution/terminalInteraction":
|
|
3173
|
+
case "item/fileChange/outputDelta":
|
|
3174
|
+
case "item/fileChange/patchUpdated":
|
|
3175
|
+
case "item/mcpToolCall/progress":
|
|
3176
|
+
case "model/rerouted":
|
|
3177
|
+
case "model/verification":
|
|
3178
|
+
case "turn/moderationMetadata":
|
|
3179
|
+
case "model/safetyBuffering/updated": break;
|
|
3180
|
+
default:
|
|
3181
|
+
this.diagnostics.warnUnknownEvent(notification, params);
|
|
3182
|
+
break;
|
|
2737
3183
|
}
|
|
2738
3184
|
}
|
|
2739
3185
|
buildResult(toolTelemetry, options) {
|
|
@@ -2741,6 +3187,7 @@ var CodexAppServerEventProjector = class {
|
|
|
2741
3187
|
const assistantTexts = this.assistantProjection.collectAssistantTexts();
|
|
2742
3188
|
const reasoningText = this.reasoningProjection.reasoningText();
|
|
2743
3189
|
const planText = this.reasoningProjection.planText();
|
|
3190
|
+
const projectedUsage = this.aborted ? this.tokenUsage : this.responseUsage ?? this.tokenUsage;
|
|
2744
3191
|
const hasAssistantItemText = this.assistantProjection.hasAssistantItemTextForSynthesis();
|
|
2745
3192
|
const legacyFailClosed = !this.completedTurn || this.completedTurn.status !== "completed" || hasAssistantItemText;
|
|
2746
3193
|
const hasDeliverableAssistantOnCompletedTurn = this.completedTurn?.status === "completed" && assistantTexts.some((text) => text.trim().length > 0);
|
|
@@ -2753,7 +3200,7 @@ var CodexAppServerEventProjector = class {
|
|
|
2753
3200
|
this.promptErrorSource = this.promptErrorSource ?? "prompt";
|
|
2754
3201
|
}
|
|
2755
3202
|
const assistantMessageOptions = {
|
|
2756
|
-
tokenUsage:
|
|
3203
|
+
tokenUsage: projectedUsage,
|
|
2757
3204
|
aborted: this.aborted,
|
|
2758
3205
|
promptError: this.promptError
|
|
2759
3206
|
};
|
|
@@ -2806,7 +3253,8 @@ var CodexAppServerEventProjector = class {
|
|
|
2806
3253
|
toolAudioAsVoice: toolTelemetry.toolAudioAsVoice,
|
|
2807
3254
|
successfulCronAdds: toolTelemetry.successfulCronAdds,
|
|
2808
3255
|
cloudCodeAssistFormatError: false,
|
|
2809
|
-
attemptUsage:
|
|
3256
|
+
attemptUsage: projectedUsage,
|
|
3257
|
+
...this.completedCompactionCount > 0 ? { compactionCount: this.completedCompactionCount } : {},
|
|
2810
3258
|
replayMetadata: {
|
|
2811
3259
|
hadPotentialSideEffects,
|
|
2812
3260
|
replaySafe: !hadPotentialSideEffects
|
|
@@ -2814,8 +3262,7 @@ var CodexAppServerEventProjector = class {
|
|
|
2814
3262
|
itemLifecycle: {
|
|
2815
3263
|
startedCount: this.activeItemIds.size + this.completedItemIds.size,
|
|
2816
3264
|
completedCount: this.completedItemIds.size,
|
|
2817
|
-
activeCount: this.activeItemIds.size
|
|
2818
|
-
...this.completedCompactionCount > 0 ? { compactionCount: this.completedCompactionCount } : {}
|
|
3265
|
+
activeCount: this.activeItemIds.size
|
|
2819
3266
|
},
|
|
2820
3267
|
yieldDetected: options?.yieldDetected || false,
|
|
2821
3268
|
didSendDeterministicApprovalPrompt: this.eventProjection.guardianReviewCount > 0 ? false : void 0
|
|
@@ -2835,13 +3282,14 @@ var CodexAppServerEventProjector = class {
|
|
|
2835
3282
|
}
|
|
2836
3283
|
markAborted() {
|
|
2837
3284
|
this.aborted = true;
|
|
3285
|
+
this.responseUsage = void 0;
|
|
2838
3286
|
}
|
|
2839
3287
|
isCompacting() {
|
|
2840
3288
|
return this.activeCompactionItemIds.size > 0;
|
|
2841
3289
|
}
|
|
2842
3290
|
async handleItemStarted(params) {
|
|
2843
3291
|
const item = readItem(params.item);
|
|
2844
|
-
const itemId = item?.id ?? readString$
|
|
3292
|
+
const itemId = item?.id ?? readString$3(params, "itemId");
|
|
2845
3293
|
this.assistantProjection.recordItemStarted(item, itemId);
|
|
2846
3294
|
if (itemId) this.activeItemIds.add(itemId);
|
|
2847
3295
|
this.recordNativeToolOutcome(item);
|
|
@@ -2894,9 +3342,10 @@ var CodexAppServerEventProjector = class {
|
|
|
2894
3342
|
}
|
|
2895
3343
|
async handleItemCompleted(params) {
|
|
2896
3344
|
const item = readItem(params.item);
|
|
3345
|
+
this.diagnostics.warnUnknownItemStatus(item);
|
|
2897
3346
|
this.recordNativeToolOutcome(item);
|
|
2898
3347
|
this.clearTerminalPresentationForNativeItem(item);
|
|
2899
|
-
const itemId = item?.id ?? readString$
|
|
3348
|
+
const itemId = item?.id ?? readString$3(params, "itemId");
|
|
2900
3349
|
if (itemId) {
|
|
2901
3350
|
this.activeItemIds.delete(itemId);
|
|
2902
3351
|
this.completedItemIds.add(itemId);
|
|
@@ -2958,23 +3407,22 @@ var CodexAppServerEventProjector = class {
|
|
|
2958
3407
|
}
|
|
2959
3408
|
});
|
|
2960
3409
|
}
|
|
2961
|
-
|
|
2962
|
-
const
|
|
2963
|
-
|
|
2964
|
-
if (!last) return;
|
|
2965
|
-
const usage = normalizeCodexTokenUsage(last);
|
|
2966
|
-
if (usage) this.tokenUsage = usage;
|
|
3410
|
+
handleRawResponseCompleted(params) {
|
|
3411
|
+
const usage = isJsonObject(params.usage) ? params.usage : void 0;
|
|
3412
|
+
this.responseUsage = usage ? normalizeCodexResponseTokenUsage(usage) : void 0;
|
|
2967
3413
|
}
|
|
2968
3414
|
async handleTurnCompleted(params) {
|
|
2969
3415
|
const turn = readCodexTurn(params.turn);
|
|
2970
3416
|
if (!turn || turn.id !== this.turnId) return;
|
|
2971
3417
|
this.completedTurn = turn;
|
|
3418
|
+
if (turn.status !== "completed") this.responseUsage = void 0;
|
|
2972
3419
|
if (turn.status === "failed") {
|
|
2973
|
-
|
|
3420
|
+
const usageLimitMessage = formatCodexUsageLimitErrorMessage({
|
|
2974
3421
|
message: turn.error?.message,
|
|
2975
3422
|
codexErrorInfo: turn.error?.codexErrorInfo,
|
|
2976
3423
|
rateLimits: this.options.readRecentRateLimits?.()
|
|
2977
|
-
})
|
|
3424
|
+
});
|
|
3425
|
+
this.promptError = usageLimitMessage ? createCodexUsageLimitPromptError(usageLimitMessage) : turn.error?.message ?? "codex app-server turn failed";
|
|
2978
3426
|
this.promptErrorSource = "prompt";
|
|
2979
3427
|
}
|
|
2980
3428
|
const turnItems = turn.items ?? [];
|
|
@@ -2988,6 +3436,7 @@ var CodexAppServerEventProjector = class {
|
|
|
2988
3436
|
}
|
|
2989
3437
|
}
|
|
2990
3438
|
for (const item of turnItems) {
|
|
3439
|
+
this.diagnostics.warnUnknownItemStatus(item);
|
|
2991
3440
|
this.assistantProjection.recordSnapshotItem(item);
|
|
2992
3441
|
this.reasoningProjection.recordItem(item);
|
|
2993
3442
|
this.generatedMediaProjection.recordNative(item);
|
|
@@ -3000,6 +3449,7 @@ var CodexAppServerEventProjector = class {
|
|
|
3000
3449
|
this.toolProgressProjection.emitToolResultSummary(item);
|
|
3001
3450
|
this.toolProgressProjection.emitToolResultOutput(item);
|
|
3002
3451
|
}
|
|
3452
|
+
this.assistantProjection.finalizeAnswerCandidate(turn);
|
|
3003
3453
|
this.activeCompactionItemIds.clear();
|
|
3004
3454
|
await this.reasoningProjection.maybeEndReasoning();
|
|
3005
3455
|
}
|
|
@@ -3051,11 +3501,12 @@ var CodexAppServerEventProjector = class {
|
|
|
3051
3501
|
}
|
|
3052
3502
|
formatCodexErrorMessage(params) {
|
|
3053
3503
|
const error = isJsonObject(params.error) ? params.error : void 0;
|
|
3054
|
-
|
|
3055
|
-
message: error ? readString$
|
|
3504
|
+
const usageLimitMessage = formatCodexUsageLimitErrorMessage({
|
|
3505
|
+
message: error ? readString$3(error, "message") : void 0,
|
|
3056
3506
|
codexErrorInfo: error?.codexErrorInfo,
|
|
3057
3507
|
rateLimits: this.options.readRecentRateLimits?.()
|
|
3058
|
-
})
|
|
3508
|
+
});
|
|
3509
|
+
return usageLimitMessage ? createCodexUsageLimitPromptError(usageLimitMessage) : readCodexErrorNotificationMessage(params);
|
|
3059
3510
|
}
|
|
3060
3511
|
emitAgentEvent(event) {
|
|
3061
3512
|
try {
|
|
@@ -3083,7 +3534,7 @@ var CodexAppServerEventProjector = class {
|
|
|
3083
3534
|
return threadId === this.threadId && turnId === this.turnId;
|
|
3084
3535
|
}
|
|
3085
3536
|
isHookNotificationForCurrentThread(params) {
|
|
3086
|
-
const threadId = readString$
|
|
3537
|
+
const threadId = readString$3(params, "threadId");
|
|
3087
3538
|
const turnId = params.turnId;
|
|
3088
3539
|
return threadId === this.threadId && (turnId === this.turnId || turnId === null);
|
|
3089
3540
|
}
|
|
@@ -3121,12 +3572,72 @@ function addCodexMessageToolOnlyFinalParameter(parameters) {
|
|
|
3121
3572
|
...rawProperties,
|
|
3122
3573
|
final: {
|
|
3123
3574
|
type: "boolean",
|
|
3124
|
-
description: "Set
|
|
3575
|
+
description: "Set false for progress or true to complete the current source reply. If omitted, OpenClaw continues and resolves the latest omitted source reply when the turn ends."
|
|
3125
3576
|
}
|
|
3126
3577
|
}
|
|
3127
3578
|
};
|
|
3128
3579
|
}
|
|
3129
3580
|
//#endregion
|
|
3581
|
+
//#region extensions/codex/src/app-server/shell-dynamic-tools.ts
|
|
3582
|
+
const CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME = "node_exec";
|
|
3583
|
+
const CODEX_NODE_PROCESS_DYNAMIC_TOOL_NAME = "node_process";
|
|
3584
|
+
const CODEX_NODE_EXEC_POLICY_PARAMETER_NAMES = /* @__PURE__ */ new Set([
|
|
3585
|
+
"host",
|
|
3586
|
+
"security",
|
|
3587
|
+
"ask"
|
|
3588
|
+
]);
|
|
3589
|
+
/** Returns true when plugin config explicitly removes any named dynamic tool. */
|
|
3590
|
+
function isCodexDynamicToolExcluded(config, names) {
|
|
3591
|
+
const normalizedNames = new Set(names.map((name) => normalizeCodexDynamicToolName(name)));
|
|
3592
|
+
return (config.codexDynamicToolsExclude ?? []).some((name) => normalizedNames.has(normalizeCodexDynamicToolName(name)));
|
|
3593
|
+
}
|
|
3594
|
+
function createNodeExecDynamicTool(execTool, configuredNode) {
|
|
3595
|
+
const pinnedNode = configuredNode?.trim();
|
|
3596
|
+
return {
|
|
3597
|
+
...execTool,
|
|
3598
|
+
name: CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME,
|
|
3599
|
+
description: pinnedNode ? "Run a shell command on the OpenClaw configured remote node for this session. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Use node_process for follow-up on backgrounded node_exec sessions. Use Codex's native shell for local app-server work." : "Run a shell command on an OpenClaw remote node. Select the node by name or id when multiple nodes are available. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Use node_process for follow-up on backgrounded node_exec sessions. Use Codex's native shell for local app-server work.",
|
|
3600
|
+
parameters: hideNodeExecDynamicToolParameters(execTool.parameters, { hideNode: Boolean(pinnedNode) }),
|
|
3601
|
+
execute: async (toolCallId, args, signal, onUpdate) => {
|
|
3602
|
+
const result = await execTool.execute(toolCallId, pinNodeExecDynamicToolArgs(args, pinnedNode), signal, onUpdate);
|
|
3603
|
+
return {
|
|
3604
|
+
...result,
|
|
3605
|
+
content: result.content.map((item) => item.type === "text" ? Object.assign({}, item, { text: item.text.replace("Use process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.", "Use node_process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.") }) : item)
|
|
3606
|
+
};
|
|
3607
|
+
}
|
|
3608
|
+
};
|
|
3609
|
+
}
|
|
3610
|
+
function createNodeProcessDynamicTool(processTool) {
|
|
3611
|
+
return {
|
|
3612
|
+
...processTool,
|
|
3613
|
+
name: CODEX_NODE_PROCESS_DYNAMIC_TOOL_NAME,
|
|
3614
|
+
description: "Manage node_exec sessions that were started on OpenClaw remote nodes: list, poll, log, write, send-keys, submit, paste, kill, clear, or remove. Use only for node_exec follow-up; use Codex's native shell session handling for local app-server work."
|
|
3615
|
+
};
|
|
3616
|
+
}
|
|
3617
|
+
function pinNodeExecDynamicToolArgs(args, configuredNode) {
|
|
3618
|
+
const { host: _host, security: _security, ask: _ask, node: requestedNode, ...rest } = args && typeof args === "object" && !Array.isArray(args) ? args : {};
|
|
3619
|
+
const node = configuredNode ?? (typeof requestedNode === "string" ? requestedNode.trim() : "");
|
|
3620
|
+
return {
|
|
3621
|
+
...rest,
|
|
3622
|
+
host: "node",
|
|
3623
|
+
...node ? { node } : {}
|
|
3624
|
+
};
|
|
3625
|
+
}
|
|
3626
|
+
function hideNodeExecDynamicToolParameters(parameters, options) {
|
|
3627
|
+
if (!parameters || typeof parameters !== "object" || Array.isArray(parameters)) return parameters;
|
|
3628
|
+
const schema = parameters;
|
|
3629
|
+
const rawProperties = schema.properties;
|
|
3630
|
+
if (!rawProperties || typeof rawProperties !== "object" || Array.isArray(rawProperties)) return parameters;
|
|
3631
|
+
const nextProperties = Object.fromEntries(Object.entries(rawProperties).filter(([name]) => !CODEX_NODE_EXEC_POLICY_PARAMETER_NAMES.has(normalizeCodexDynamicToolName(name)) && !(options.hideNode && normalizeCodexDynamicToolName(name) === "node")));
|
|
3632
|
+
const rawRequired = schema.required;
|
|
3633
|
+
const nextRequired = Array.isArray(rawRequired) ? rawRequired.filter((name) => typeof name !== "string" || !CODEX_NODE_EXEC_POLICY_PARAMETER_NAMES.has(normalizeCodexDynamicToolName(name)) && !(options.hideNode && normalizeCodexDynamicToolName(name) === "node")) : rawRequired;
|
|
3634
|
+
return {
|
|
3635
|
+
...schema,
|
|
3636
|
+
properties: nextProperties,
|
|
3637
|
+
...Array.isArray(rawRequired) ? { required: nextRequired } : {}
|
|
3638
|
+
};
|
|
3639
|
+
}
|
|
3640
|
+
//#endregion
|
|
3130
3641
|
//#region extensions/codex/src/app-server/vision-tools.ts
|
|
3131
3642
|
/**
|
|
3132
3643
|
* Filters Codex dynamic tools for turns that already contain image inputs so
|
|
@@ -3153,13 +3664,6 @@ const CODEX_NATIVE_SANDBOX_TOOL_REQUIREMENTS = [
|
|
|
3153
3664
|
"apply_patch"
|
|
3154
3665
|
];
|
|
3155
3666
|
const CODEX_MEMORY_FLUSH_DYNAMIC_TOOL_ALLOW = /* @__PURE__ */ new Set(["read", "write"]);
|
|
3156
|
-
const CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME = "node_exec";
|
|
3157
|
-
const CODEX_NODE_PROCESS_DYNAMIC_TOOL_NAME = "node_process";
|
|
3158
|
-
const CODEX_NODE_EXEC_POLICY_PARAMETER_NAMES = /* @__PURE__ */ new Set([
|
|
3159
|
-
"host",
|
|
3160
|
-
"security",
|
|
3161
|
-
"ask"
|
|
3162
|
-
]);
|
|
3163
3667
|
function preserveRingZeroSystemAgentTool(allTools, filteredTools) {
|
|
3164
3668
|
const openclaw = allTools.find((tool) => tool.name === "openclaw" && tool.catalogMode === "direct-only");
|
|
3165
3669
|
if (!openclaw) return filteredTools;
|
|
@@ -3248,8 +3752,8 @@ async function buildDynamicTools(input) {
|
|
|
3248
3752
|
const toolBuildStages = createCodexDynamicToolBuildStageTracker({ enabled: input.profilerEnabled });
|
|
3249
3753
|
const modelHasVision = params.model.input?.includes("image") ?? false;
|
|
3250
3754
|
const agentDir = params.agentDir ?? resolveAgentDir(params.config ?? {}, input.sessionAgentId);
|
|
3251
|
-
const
|
|
3252
|
-
const createOpenClawCodingTools = dynamicToolBuildState.openClawCodingToolsFactory ??
|
|
3755
|
+
const { createOpenClawCodingTools: defaultCreateOpenClawCodingTools, resolveWebSearchToolPolicy } = await import("openclaw/plugin-sdk/agent-harness");
|
|
3756
|
+
const createOpenClawCodingTools = dynamicToolBuildState.openClawCodingToolsFactory ?? defaultCreateOpenClawCodingTools;
|
|
3253
3757
|
toolBuildStages.mark("load-agent-harness-tools");
|
|
3254
3758
|
const sessionKeys = resolveOpenClawCodingToolsSessionKeys(params, input.sandboxSessionKey);
|
|
3255
3759
|
const nativeExecutionPolicy = resolveCodexNativeExecutionPolicyForDynamicTools(input);
|
|
@@ -3302,6 +3806,7 @@ async function buildDynamicTools(input) {
|
|
|
3302
3806
|
modelCompat: params.model.compat && typeof params.model.compat === "object" ? params.model.compat : void 0,
|
|
3303
3807
|
modelApi: params.model.api,
|
|
3304
3808
|
modelContextWindowTokens: params.model.contextWindow,
|
|
3809
|
+
delegationCapability: params.delegationCapability,
|
|
3305
3810
|
modelAuthMode: resolveModelAuthMode(params.model.provider, params.config, params.toolAuthProfileStore ?? params.authProfileStore, { workspaceDir: input.effectiveWorkspace }),
|
|
3306
3811
|
suppressManagedWebSearch: false,
|
|
3307
3812
|
currentChannelId: params.currentChannelId,
|
|
@@ -3346,7 +3851,7 @@ async function buildDynamicTools(input) {
|
|
|
3346
3851
|
nativeProviderWebSearchSupport: input.nativeProviderWebSearchSupport
|
|
3347
3852
|
});
|
|
3348
3853
|
const readableAllTools = [...readableAllToolProjection.tools];
|
|
3349
|
-
const normallyProfiledTools = filterCodexDynamicTools(readableAllTools, input.pluginConfig);
|
|
3854
|
+
const normallyProfiledTools = shouldKeepOpenClawShellDynamicTools(input, nativeExecutionPolicy) ? filterCodexDynamicToolsWithOpenClawShell(readableAllTools, input.pluginConfig) : filterCodexDynamicTools(readableAllTools, input.pluginConfig);
|
|
3350
3855
|
const profileFilteredTools = (input.isHostScopedToolActive?.("openclaw") ?? isHostScopedAgentToolActive("openclaw")) && isSystemAgentOnlyCodexDynamicToolAllowlist(params.toolsAllow) ? preserveRingZeroSystemAgentTool(readableAllTools, normallyProfiledTools) : normallyProfiledTools;
|
|
3351
3856
|
const codexFilteredTools = addNodeShellDynamicToolsIfNeeded(addSandboxShellDynamicToolsIfAvailable(isCodexMemoryFlushRun(params) ? filterCodexMemoryFlushDynamicTools(readableAllTools) : profileFilteredTools, readableAllTools, input), readableAllTools, input, nativeExecutionPolicy);
|
|
3352
3857
|
toolBuildStages.mark("codex-filtering");
|
|
@@ -3356,7 +3861,7 @@ async function buildDynamicTools(input) {
|
|
|
3356
3861
|
});
|
|
3357
3862
|
toolBuildStages.mark("vision-filtering");
|
|
3358
3863
|
const webSearchPresent = visionFilteredTools.some((tool) => tool.name === "web_search");
|
|
3359
|
-
const webSearchPolicy =
|
|
3864
|
+
const webSearchPolicy = resolveWebSearchToolPolicy({
|
|
3360
3865
|
config: params.config,
|
|
3361
3866
|
modelProvider: params.model.provider,
|
|
3362
3867
|
modelId: params.modelId,
|
|
@@ -3570,13 +4075,6 @@ function shouldExposeSandboxExecDynamicTool(input) {
|
|
|
3570
4075
|
const backendId = input.sandbox?.enabled ? input.sandbox.backendId.trim().toLowerCase() : "";
|
|
3571
4076
|
return Boolean(backendId && input.nativeToolSurfaceEnabled === false);
|
|
3572
4077
|
}
|
|
3573
|
-
function isCodexDynamicToolExcluded(config, names) {
|
|
3574
|
-
const normalizedNames = new Set(names.map((name) => normalizeCodexDynamicToolName(name)));
|
|
3575
|
-
return (config.codexDynamicToolsExclude ?? []).some((name) => {
|
|
3576
|
-
const normalized = normalizeCodexDynamicToolName(name);
|
|
3577
|
-
return normalizedNames.has(normalized);
|
|
3578
|
-
});
|
|
3579
|
-
}
|
|
3580
4078
|
function isSandboxShellDynamicToolExcluded(config) {
|
|
3581
4079
|
return isCodexDynamicToolExcluded(config, [
|
|
3582
4080
|
"exec",
|
|
@@ -3594,55 +4092,12 @@ function addNodeShellDynamicToolsIfNeeded(filteredTools, allTools, input, nodePo
|
|
|
3594
4092
|
const processTool = allTools.find((tool) => normalizeCodexDynamicToolName(tool.name) === "process");
|
|
3595
4093
|
if (!execTool || !processTool) return filteredTools;
|
|
3596
4094
|
const toolsToAppend = [];
|
|
3597
|
-
if (!isCodexDynamicToolExcluded(input.pluginConfig, ["exec",
|
|
3598
|
-
if (!isCodexDynamicToolExcluded(input.pluginConfig, ["process",
|
|
4095
|
+
if (!isCodexDynamicToolExcluded(input.pluginConfig, ["exec", "node_exec"]) && !filteredTools.some((tool) => normalizeCodexDynamicToolName(tool.name) === "node_exec")) toolsToAppend.push(createNodeExecDynamicTool(execTool, nodePolicy.node));
|
|
4096
|
+
if (!isCodexDynamicToolExcluded(input.pluginConfig, ["process", "node_process"]) && !filteredTools.some((tool) => normalizeCodexDynamicToolName(tool.name) === "node_process")) toolsToAppend.push(createNodeProcessDynamicTool(processTool));
|
|
3599
4097
|
return toolsToAppend.length > 0 ? [...filteredTools, ...toolsToAppend] : filteredTools;
|
|
3600
4098
|
}
|
|
3601
|
-
function
|
|
3602
|
-
|
|
3603
|
-
return {
|
|
3604
|
-
...execTool,
|
|
3605
|
-
name: CODEX_NODE_EXEC_DYNAMIC_TOOL_NAME,
|
|
3606
|
-
description: pinnedNode ? "Run a shell command on the OpenClaw configured remote node for this session. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Use node_process for follow-up on backgrounded node_exec sessions. Use Codex's native shell for local app-server work." : "Run a shell command on an OpenClaw remote node. Select the node by name or id when multiple nodes are available. This tool always uses OpenClaw host=node internally and follows the existing node exec approval and allowlist policy. Use node_process for follow-up on backgrounded node_exec sessions. Use Codex's native shell for local app-server work.",
|
|
3607
|
-
parameters: hideNodeExecDynamicToolParameters(execTool.parameters, { hideNode: Boolean(pinnedNode) }),
|
|
3608
|
-
execute: async (toolCallId, args, signal, onUpdate) => {
|
|
3609
|
-
const result = await execTool.execute(toolCallId, pinNodeExecDynamicToolArgs(args, pinnedNode), signal, onUpdate);
|
|
3610
|
-
return {
|
|
3611
|
-
...result,
|
|
3612
|
-
content: result.content.map((item) => item.type === "text" ? Object.assign({}, item, { text: item.text.replace("Use process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.", "Use node_process (list/poll/log/write/send-keys/submit/paste/kill/clear/remove) for follow-up.") }) : item)
|
|
3613
|
-
};
|
|
3614
|
-
}
|
|
3615
|
-
};
|
|
3616
|
-
}
|
|
3617
|
-
function createNodeProcessDynamicTool(processTool) {
|
|
3618
|
-
return {
|
|
3619
|
-
...processTool,
|
|
3620
|
-
name: CODEX_NODE_PROCESS_DYNAMIC_TOOL_NAME,
|
|
3621
|
-
description: "Manage node_exec sessions that were started on OpenClaw remote nodes: list, poll, log, write, send-keys, submit, paste, kill, clear, or remove. Use only for node_exec follow-up; use Codex's native shell session handling for local app-server work."
|
|
3622
|
-
};
|
|
3623
|
-
}
|
|
3624
|
-
function pinNodeExecDynamicToolArgs(args, configuredNode) {
|
|
3625
|
-
const { host: _host, security: _security, ask: _ask, node: requestedNode, ...rest } = args && typeof args === "object" && !Array.isArray(args) ? args : {};
|
|
3626
|
-
const node = configuredNode ?? (typeof requestedNode === "string" ? requestedNode.trim() : "");
|
|
3627
|
-
return {
|
|
3628
|
-
...rest,
|
|
3629
|
-
host: "node",
|
|
3630
|
-
...node ? { node } : {}
|
|
3631
|
-
};
|
|
3632
|
-
}
|
|
3633
|
-
function hideNodeExecDynamicToolParameters(parameters, options) {
|
|
3634
|
-
if (!parameters || typeof parameters !== "object" || Array.isArray(parameters)) return parameters;
|
|
3635
|
-
const schema = parameters;
|
|
3636
|
-
const rawProperties = schema.properties;
|
|
3637
|
-
if (!rawProperties || typeof rawProperties !== "object" || Array.isArray(rawProperties)) return parameters;
|
|
3638
|
-
const nextProperties = Object.fromEntries(Object.entries(rawProperties).filter(([name]) => !CODEX_NODE_EXEC_POLICY_PARAMETER_NAMES.has(normalizeCodexDynamicToolName(name)) && !(options.hideNode && normalizeCodexDynamicToolName(name) === "node")));
|
|
3639
|
-
const rawRequired = schema.required;
|
|
3640
|
-
const nextRequired = Array.isArray(rawRequired) ? rawRequired.filter((name) => typeof name !== "string" || !CODEX_NODE_EXEC_POLICY_PARAMETER_NAMES.has(normalizeCodexDynamicToolName(name)) && !(options.hideNode && normalizeCodexDynamicToolName(name) === "node")) : rawRequired;
|
|
3641
|
-
return {
|
|
3642
|
-
...schema,
|
|
3643
|
-
properties: nextProperties,
|
|
3644
|
-
...Array.isArray(rawRequired) ? { required: nextRequired } : {}
|
|
3645
|
-
};
|
|
4099
|
+
function shouldKeepOpenClawShellDynamicTools(input, nodePolicy) {
|
|
4100
|
+
return !isCodexMemoryFlushRun(input.params) && input.nativeToolSurfaceEnabled === false && input.sandbox?.enabled !== true && nodePolicy.effectiveExecHost !== "node";
|
|
3646
4101
|
}
|
|
3647
4102
|
function resolveCodexNativeExecutionPolicyForDynamicTools(input) {
|
|
3648
4103
|
return resolveCodexNativeExecutionPolicy({
|
|
@@ -3663,7 +4118,7 @@ function filterCodexDynamicToolsForAllowlist(tools, toolsAllow) {
|
|
|
3663
4118
|
const allowSet = new Set(toolsAllow.map((name) => normalizeCodexDynamicToolName(name)).filter(Boolean));
|
|
3664
4119
|
return tools.filter((tool) => {
|
|
3665
4120
|
const normalized = normalizeCodexDynamicToolName(tool.name);
|
|
3666
|
-
return allowSet.has(normalized) || normalized === "sandbox_exec" && allowSet.has("exec") || normalized === "sandbox_process" && (allowSet.has("exec") || allowSet.has("process")) || normalized ===
|
|
4121
|
+
return allowSet.has(normalized) || normalized === "sandbox_exec" && allowSet.has("exec") || normalized === "sandbox_process" && (allowSet.has("exec") || allowSet.has("process")) || normalized === "node_exec" && allowSet.has("exec") || normalized === "node_process" && (allowSet.has("exec") || allowSet.has("process"));
|
|
3667
4122
|
});
|
|
3668
4123
|
}
|
|
3669
4124
|
/** Detects the wildcard allowlist marker after Codex tool-name normalization. */
|
|
@@ -3675,90 +4130,28 @@ function shouldForceMessageTool(params) {
|
|
|
3675
4130
|
return params.disableMessageTool !== true && params.sourceReplyDeliveryMode === "message_tool_only";
|
|
3676
4131
|
}
|
|
3677
4132
|
//#endregion
|
|
3678
|
-
//#region extensions/codex/src/app-server/
|
|
3679
|
-
|
|
3680
|
-
|
|
3681
|
-
|
|
3682
|
-
|
|
3683
|
-
|
|
3684
|
-
|
|
3685
|
-
|
|
3686
|
-
const CODEX_TURN_COMPLETION_IDLE_TIMEOUT_MS = 6e4;
|
|
3687
|
-
/** Short guard after apparent assistant completion. */
|
|
3688
|
-
const CODEX_TURN_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS = 1e4;
|
|
3689
|
-
const CODEX_POST_TOOL_RAW_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS = 5 * 6e4;
|
|
3690
|
-
/** Guard after reasoning/commentary progress when no tool handoff occurred. */
|
|
3691
|
-
const CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS = 5 * 6e4;
|
|
3692
|
-
/** Long terminal idle watch for app-server turns that never send completion. */
|
|
3693
|
-
const CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS = 30 * 6e4;
|
|
3694
|
-
function resolvePositiveIntegerTimeoutMs(value, fallbackMs) {
|
|
3695
|
-
return resolveTimerTimeoutMs(value, resolveTimerTimeoutMs(fallbackMs, 1));
|
|
3696
|
-
}
|
|
3697
|
-
/** Runs startup work with abort and timeout handling plus optional cleanup. */
|
|
3698
|
-
async function withCodexStartupTimeout(params) {
|
|
3699
|
-
if (params.signal.aborted) throw new Error("codex app-server startup aborted");
|
|
3700
|
-
let timeout;
|
|
3701
|
-
let abortCleanup;
|
|
3702
|
-
let timeoutError;
|
|
3703
|
-
let timeoutCleanup;
|
|
3704
|
-
try {
|
|
3705
|
-
return await Promise.race([params.operation(), new Promise((_, reject) => {
|
|
3706
|
-
const rejectOnce = (error) => {
|
|
3707
|
-
if (timeout) {
|
|
3708
|
-
clearTimeout(timeout);
|
|
3709
|
-
timeout = void 0;
|
|
3710
|
-
}
|
|
3711
|
-
reject(error);
|
|
3712
|
-
};
|
|
3713
|
-
timeout = setTimeout(() => {
|
|
3714
|
-
timeoutError = /* @__PURE__ */ new Error("codex app-server startup timed out");
|
|
3715
|
-
timeoutCleanup = Promise.resolve(params.onTimeout?.()).then(() => void 0, () => void 0);
|
|
3716
|
-
timeoutCleanup.finally(() => {
|
|
3717
|
-
rejectOnce(timeoutError);
|
|
3718
|
-
});
|
|
3719
|
-
}, params.timeoutMs);
|
|
3720
|
-
const abortListener = () => rejectOnce(/* @__PURE__ */ new Error("codex app-server startup aborted"));
|
|
3721
|
-
params.signal.addEventListener("abort", abortListener, { once: true });
|
|
3722
|
-
abortCleanup = () => params.signal.removeEventListener("abort", abortListener);
|
|
3723
|
-
})]);
|
|
3724
|
-
} catch (error) {
|
|
3725
|
-
if (timeoutError) {
|
|
3726
|
-
await timeoutCleanup;
|
|
3727
|
-
throw timeoutError;
|
|
3728
|
-
}
|
|
3729
|
-
throw error;
|
|
3730
|
-
} finally {
|
|
3731
|
-
if (timeout) clearTimeout(timeout);
|
|
3732
|
-
abortCleanup?.();
|
|
4133
|
+
//#region extensions/codex/src/app-server/source-reply-finality.ts
|
|
4134
|
+
const sourceReplyDeliveryIntents = /* @__PURE__ */ new WeakMap();
|
|
4135
|
+
/** Retain source-reply intent until the owning Codex turn has an authoritative outcome. */
|
|
4136
|
+
function recordCodexSourceReplyDeliveryIntent(owner, intent) {
|
|
4137
|
+
const intents = sourceReplyDeliveryIntents.get(owner);
|
|
4138
|
+
if (intents) {
|
|
4139
|
+
intents.push(intent);
|
|
4140
|
+
return;
|
|
3733
4141
|
}
|
|
4142
|
+
sourceReplyDeliveryIntents.set(owner, [intent]);
|
|
3734
4143
|
}
|
|
3735
|
-
/**
|
|
3736
|
-
function
|
|
3737
|
-
const
|
|
3738
|
-
|
|
3739
|
-
|
|
3740
|
-
|
|
3741
|
-
|
|
3742
|
-
|
|
3743
|
-
|
|
3744
|
-
|
|
3745
|
-
|
|
3746
|
-
function resolveCodexTurnAssistantCompletionIdleTimeoutMs(value) {
|
|
3747
|
-
return resolvePositiveIntegerTimeoutMs(value, CODEX_TURN_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS);
|
|
3748
|
-
}
|
|
3749
|
-
/** Resolves the conservative post-tool raw assistant guard timeout. */
|
|
3750
|
-
function resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs(value, fallbackMs) {
|
|
3751
|
-
return resolvePositiveIntegerTimeoutMs(value, Math.max(resolvePositiveIntegerTimeoutMs(void 0, fallbackMs), CODEX_POST_TOOL_RAW_ASSISTANT_COMPLETION_IDLE_TIMEOUT_MS));
|
|
3752
|
-
}
|
|
3753
|
-
/** Resolves the long terminal turn idle timeout. */
|
|
3754
|
-
function resolveCodexTurnTerminalIdleTimeoutMs(value, runTimeoutOverrideMs) {
|
|
3755
|
-
const explicitRunBudgetMs = resolvePositiveIntegerTimeoutMs(runTimeoutOverrideMs, CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS);
|
|
3756
|
-
return resolvePositiveIntegerTimeoutMs(value, Math.max(CODEX_TURN_TERMINAL_IDLE_TIMEOUT_MS, explicitRunBudgetMs));
|
|
3757
|
-
}
|
|
3758
|
-
/** Adds gateway grace time to a caller timeout without overflowing invalid values. */
|
|
3759
|
-
function resolveCodexGatewayTimeoutWithGraceMs(timeoutMs, graceMs = 1e4) {
|
|
3760
|
-
const timeout = resolvePositiveIntegerTimeoutMs(timeoutMs, 1);
|
|
3761
|
-
return addTimerTimeoutGraceMs(timeout, resolveTimerTimeoutMs(graceMs, 0, 0)) ?? timeout;
|
|
4144
|
+
/** Resolve omitted finality without changing explicit progress or final markers. */
|
|
4145
|
+
function settleCodexSourceReplyFinality(owner, turnSucceeded) {
|
|
4146
|
+
const intents = sourceReplyDeliveryIntents.get(owner);
|
|
4147
|
+
if (!intents) return false;
|
|
4148
|
+
const lastIntent = intents.at(-1);
|
|
4149
|
+
for (const intent of intents) {
|
|
4150
|
+
if (intent.final !== void 0) continue;
|
|
4151
|
+
intent.record.sourceReplyFinal = turnSucceeded && intent === lastIntent;
|
|
4152
|
+
}
|
|
4153
|
+
sourceReplyDeliveryIntents.delete(owner);
|
|
4154
|
+
return turnSucceeded && intents.some((intent) => intent.record.sourceReplyFinal === true);
|
|
3762
4155
|
}
|
|
3763
4156
|
//#endregion
|
|
3764
4157
|
//#region extensions/codex/src/app-server/provider-capabilities.ts
|
|
@@ -4580,6 +4973,7 @@ async function handleCodexAppServerApprovalRequest(params) {
|
|
|
4580
4973
|
paramsForRun: params.paramsForRun,
|
|
4581
4974
|
context,
|
|
4582
4975
|
nativeHookRelay: params.nativeHookRelay,
|
|
4976
|
+
autoApprove: params.autoApprove,
|
|
4583
4977
|
signal: params.signal
|
|
4584
4978
|
});
|
|
4585
4979
|
if (policyOutcome?.outcome === "denied") {
|
|
@@ -4759,6 +5153,7 @@ async function runOpenClawToolPolicyForApprovalRequest(params) {
|
|
|
4759
5153
|
context: params.context,
|
|
4760
5154
|
policyRequest,
|
|
4761
5155
|
nativeHookRelay: params.nativeHookRelay,
|
|
5156
|
+
autoApprove: params.autoApprove,
|
|
4762
5157
|
cwd,
|
|
4763
5158
|
signal: params.signal
|
|
4764
5159
|
});
|
|
@@ -4867,6 +5262,11 @@ async function runNativeRelayToolPolicyForApprovalRequest(params) {
|
|
|
4867
5262
|
};
|
|
4868
5263
|
return { handled: true };
|
|
4869
5264
|
} catch (error) {
|
|
5265
|
+
if (params.autoApprove === true && !hasNativeHookRelayInvocation({
|
|
5266
|
+
relayId: params.nativeHookRelay.relayId,
|
|
5267
|
+
event: "pre_tool_use",
|
|
5268
|
+
toolUseId: params.context.approvalId
|
|
5269
|
+
})) return;
|
|
4870
5270
|
return {
|
|
4871
5271
|
handled: true,
|
|
4872
5272
|
blocked: true,
|
|
@@ -5539,6 +5939,7 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5539
5939
|
return getChannelAgentToolMeta(tool) === void 0;
|
|
5540
5940
|
};
|
|
5541
5941
|
const legacyExtensionRunner = createCodexAppServerToolResultExtensionRunner(toolResultHookContext);
|
|
5942
|
+
const executionSnapshotStates = /* @__PURE__ */ new Map();
|
|
5542
5943
|
const directToolNames = /* @__PURE__ */ new Set([...ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES, ...params.directToolNames ?? []]);
|
|
5543
5944
|
return {
|
|
5544
5945
|
availableSpecs: createCodexDynamicToolSpecs({
|
|
@@ -5552,9 +5953,16 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5552
5953
|
directToolNames
|
|
5553
5954
|
}),
|
|
5554
5955
|
telemetry,
|
|
5956
|
+
consumeToolExecutionSnapshot: (toolCallId) => {
|
|
5957
|
+
const state = executionSnapshotStates.get(toolCallId);
|
|
5958
|
+
executionSnapshotStates.delete(toolCallId);
|
|
5959
|
+
if (state) state.consumed = true;
|
|
5960
|
+
return state?.snapshot;
|
|
5961
|
+
},
|
|
5555
5962
|
handleToolCall: async (call, options) => {
|
|
5556
5963
|
const toolEntry = toolMap.get(call.tool);
|
|
5557
5964
|
if (!toolEntry) {
|
|
5965
|
+
const executedArguments = jsonObjectToRecord(call.arguments);
|
|
5558
5966
|
const message = registeredToolNames.has(call.tool) ? `OpenClaw tool is not available for this turn: ${call.tool}` : `Unknown OpenClaw tool: ${call.tool}`;
|
|
5559
5967
|
finalizeToolTerminalPresentation({
|
|
5560
5968
|
toolCallId: call.callId,
|
|
@@ -5566,28 +5974,34 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5566
5974
|
toolCallOrdinal: options?.toolCallOrdinal
|
|
5567
5975
|
});
|
|
5568
5976
|
notifyAgentToolResult(options?.onAgentToolResult, call.tool, failedToolResult(message), true);
|
|
5569
|
-
|
|
5570
|
-
|
|
5571
|
-
|
|
5572
|
-
|
|
5573
|
-
}],
|
|
5574
|
-
success: false
|
|
5575
|
-
};
|
|
5576
|
-
return {
|
|
5577
|
-
contentItems: [{
|
|
5578
|
-
type: "inputText",
|
|
5579
|
-
text: message
|
|
5580
|
-
}],
|
|
5581
|
-
success: false
|
|
5582
|
-
};
|
|
5977
|
+
return createFailedDynamicToolResponse(message, {
|
|
5978
|
+
executedArguments,
|
|
5979
|
+
executionStarted: false
|
|
5980
|
+
});
|
|
5583
5981
|
}
|
|
5584
5982
|
const { tool, name: toolName } = toolEntry;
|
|
5585
5983
|
const args = jsonObjectToRecord(call.arguments);
|
|
5586
5984
|
const startedAt = Date.now();
|
|
5587
5985
|
const signal = composeAbortSignals(params.signal, options?.signal);
|
|
5588
5986
|
let didStartExecution = false;
|
|
5987
|
+
let didDispatchExecution = false;
|
|
5589
5988
|
let executionPrevented = false;
|
|
5590
5989
|
let executedArgs = structuredClone(args);
|
|
5990
|
+
const executionSnapshotState = {
|
|
5991
|
+
consumed: false,
|
|
5992
|
+
retainAfterCompletion: options?.retainExecutionSnapshot === true
|
|
5993
|
+
};
|
|
5994
|
+
executionSnapshotStates.set(call.callId, executionSnapshotState);
|
|
5995
|
+
const captureExecutionBoundary = () => {
|
|
5996
|
+
didStartExecution ||= didDispatchExecution;
|
|
5997
|
+
executionPrevented = executionPrevented || consumePreExecutionBlockedToolCall(call.callId, toolResultHookContext.runId);
|
|
5998
|
+
const adjustedExecutedArgs = consumeAdjustedParamsForToolCall(call.callId, toolResultHookContext.runId);
|
|
5999
|
+
if (isRecord(adjustedExecutedArgs)) executedArgs = adjustedExecutedArgs;
|
|
6000
|
+
if (!executionSnapshotState.consumed) executionSnapshotState.snapshot = {
|
|
6001
|
+
executedArguments: structuredClone(executedArgs),
|
|
6002
|
+
executionStarted: didStartExecution && !executionPrevented
|
|
6003
|
+
};
|
|
6004
|
+
};
|
|
5591
6005
|
try {
|
|
5592
6006
|
const preparedArgs = tool.prepareArguments ? tool.prepareArguments(args) : args;
|
|
5593
6007
|
const telemetryArgs = isRecord(preparedArgs) ? preparedArgs : args;
|
|
@@ -5600,13 +6014,11 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5600
6014
|
replyToMode: params.hookContext?.replyToMode,
|
|
5601
6015
|
hasRepliedRef: params.hookContext?.hasRepliedRef ? { value: params.hookContext.hasRepliedRef.value } : void 0
|
|
5602
6016
|
};
|
|
5603
|
-
|
|
6017
|
+
didDispatchExecution = true;
|
|
5604
6018
|
const rawResult = await tool.execute(call.callId, preparedArgs, signal);
|
|
5605
|
-
|
|
5606
|
-
if (isRecord(adjustedExecutedArgs)) executedArgs = structuredClone(adjustedExecutedArgs);
|
|
5607
|
-
executionPrevented = consumePreExecutionBlockedToolCall(call.callId, toolResultHookContext.runId);
|
|
6019
|
+
captureExecutionBoundary();
|
|
5608
6020
|
const telemetryRawResult = sanitizeToolResult(rawResult);
|
|
5609
|
-
const rawIsError =
|
|
6021
|
+
const rawIsError = isToolResultError(rawResult);
|
|
5610
6022
|
const rawResultFailureKind = resolveToolResultFailureKind(rawResult);
|
|
5611
6023
|
const middlewareResult = await middlewareRunner.applyToolResultMiddleware({
|
|
5612
6024
|
threadId: call.threadId,
|
|
@@ -5625,7 +6037,7 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5625
6037
|
args: structuredClone(executedArgs),
|
|
5626
6038
|
result: middlewareResult
|
|
5627
6039
|
});
|
|
5628
|
-
const resultIsError = rawIsError ||
|
|
6040
|
+
const resultIsError = rawIsError || isToolResultError(result);
|
|
5629
6041
|
const finalResultFailureKind = resolveToolResultFailureKind(result);
|
|
5630
6042
|
const resultFailureKind = rawResultFailureKind ?? finalResultFailureKind;
|
|
5631
6043
|
const observerResult = rawResultFailureKind && finalResultFailureKind !== rawResultFailureKind ? {
|
|
@@ -5689,8 +6101,9 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5689
6101
|
}) && (replyReceiptMatchesCurrentMessage(rawResult, params.hookContext) || replyReceiptMatchesCurrentMessage(result, params.hookContext));
|
|
5690
6102
|
const toolConfirmedSourceReply = params.hookContext?.sourceReplyDeliveryMode === "message_tool_only" && toolName === "message" && !resultIsError && (rawResult.terminate === true || result.terminate === true);
|
|
5691
6103
|
const hasExplicitFinalControl = typeof executedArgs.final === "boolean";
|
|
5692
|
-
const
|
|
5693
|
-
|
|
6104
|
+
const confirmedSourceReply = params.hookContext?.sourceReplyDeliveryMode === "message_tool_only" && toolName === "message" && (toolConfirmedSourceReply || deliveredSourceReply || receiptConfirmedSourceReply);
|
|
6105
|
+
const sourceReplyFinal = confirmedSourceReply ? hasExplicitFinalControl ? executedArgs.final === true : void 0 : void 0;
|
|
6106
|
+
const sourceReplyRecord = collectToolTelemetry({
|
|
5694
6107
|
toolName,
|
|
5695
6108
|
args: executedArgs,
|
|
5696
6109
|
result,
|
|
@@ -5700,17 +6113,26 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5700
6113
|
messagingTarget: confirmedMessagingTarget,
|
|
5701
6114
|
sourceReplyFinal
|
|
5702
6115
|
});
|
|
6116
|
+
if (confirmedSourceReply && sourceReplyRecord) recordCodexSourceReplyDeliveryIntent(telemetry, {
|
|
6117
|
+
record: sourceReplyRecord,
|
|
6118
|
+
final: sourceReplyFinal
|
|
6119
|
+
});
|
|
5703
6120
|
if (deliveredSourceReply || receiptConfirmedSourceReply || toolConfirmedSourceReply) telemetry.didDeliverSourceReplyViaMessageTool = true;
|
|
5704
|
-
|
|
6121
|
+
const defersInferredSourceReplyTermination = confirmedSourceReply && executedArgs.final !== true;
|
|
6122
|
+
withDynamicToolTermination(response, (rawResult.terminate === true || result.terminate === true) && !defersInferredSourceReplyTermination || isToolResultYield(rawResult) || isToolResultYield(result) || confirmedSourceReply && executedArgs.final === true);
|
|
5705
6123
|
const asyncStarted = isAsyncStartedToolResult(rawResult) || isAsyncStartedToolResult(result);
|
|
5706
6124
|
withDynamicToolAsyncStarted(response, asyncStarted);
|
|
5707
|
-
|
|
6125
|
+
const replaySafe = executionPrevented || !asyncStarted && isReplaySafeToolInstance(toolEntry.tool) && isReplaySafeToolCall(toolName, executedArgs);
|
|
6126
|
+
return withDynamicToolExecutionState(response, {
|
|
6127
|
+
executedArguments: executedArgs,
|
|
6128
|
+
executionStarted: didStartExecution && !executionPrevented,
|
|
6129
|
+
sideEffectEvidence: !replaySafe
|
|
6130
|
+
});
|
|
5708
6131
|
} catch (error) {
|
|
6132
|
+
captureExecutionBoundary();
|
|
5709
6133
|
if (toolName === "computer" && params.computerContextEpoch?.frameToolCallId === call.callId) invalidateComputerFrame(params.computerContextEpoch);
|
|
5710
6134
|
const executionDisposition = getBeforeToolCallFailureDisposition(error) ?? (signal.aborted ? resolveCodexToolAbortTerminalReason(signal) : resolveToolExecutionErrorKind(error));
|
|
5711
6135
|
const errorMessage = formatToolExecutionErrorMessage(error, "OpenClaw dynamic tool call failed.");
|
|
5712
|
-
const adjustedExecutedArgs = consumeAdjustedParamsForToolCall(call.callId, toolResultHookContext.runId);
|
|
5713
|
-
if (isRecord(adjustedExecutedArgs)) executedArgs = structuredClone(adjustedExecutedArgs);
|
|
5714
6136
|
executionPrevented = executionPrevented || consumePreExecutionBlockedToolCall(call.callId, toolResultHookContext.runId);
|
|
5715
6137
|
const failedResult = failedToolResult(errorMessage, executionDisposition);
|
|
5716
6138
|
finalizeToolTerminalPresentation({
|
|
@@ -5743,13 +6165,20 @@ function createCodexDynamicToolBridge(params) {
|
|
|
5743
6165
|
startedAt
|
|
5744
6166
|
});
|
|
5745
6167
|
const replaySafe = !didStartExecution || executionPrevented || isReplaySafeToolInstance(toolEntry.tool) && isReplaySafeToolCall(toolName, executedArgs);
|
|
5746
|
-
return
|
|
6168
|
+
return withDynamicToolExecutionState(withDiagnosticFailureDisposition({
|
|
5747
6169
|
contentItems: [{
|
|
5748
6170
|
type: "inputText",
|
|
5749
6171
|
text: errorMessage
|
|
5750
6172
|
}],
|
|
5751
6173
|
success: false
|
|
5752
|
-
}, executionDisposition),
|
|
6174
|
+
}, executionDisposition), {
|
|
6175
|
+
executedArguments: executedArgs,
|
|
6176
|
+
executionStarted: didStartExecution && !executionPrevented,
|
|
6177
|
+
sideEffectEvidence: didStartExecution && !replaySafe
|
|
6178
|
+
});
|
|
6179
|
+
} finally {
|
|
6180
|
+
if (executionSnapshotStates.get(call.callId) === executionSnapshotState && (executionSnapshotState.consumed || !executionSnapshotState.retainAfterCompletion)) executionSnapshotStates.delete(call.callId);
|
|
6181
|
+
consumeAdjustedParamsForToolCall(call.callId, toolResultHookContext.runId);
|
|
5753
6182
|
}
|
|
5754
6183
|
}
|
|
5755
6184
|
};
|
|
@@ -5877,7 +6306,12 @@ function projectCodexDynamicTools(tools) {
|
|
|
5877
6306
|
quarantinedTools.push(descriptor.diagnostic);
|
|
5878
6307
|
continue;
|
|
5879
6308
|
}
|
|
5880
|
-
const
|
|
6309
|
+
const normalizedParameters = normalizeOpenAIToolSchemas({
|
|
6310
|
+
provider: "openai",
|
|
6311
|
+
modelApi: "openai-chatgpt-responses",
|
|
6312
|
+
tools: [{ parameters: descriptor.parameters }]
|
|
6313
|
+
})[0]?.parameters;
|
|
6314
|
+
const projection = projectRuntimeToolInputSchema(normalizedParameters ?? descriptor.parameters, `${descriptor.name}.inputSchema`);
|
|
5881
6315
|
if (projection.violations.length > 0) {
|
|
5882
6316
|
quarantinedTools.push({
|
|
5883
6317
|
tool: descriptor.name,
|
|
@@ -6032,11 +6466,12 @@ function collectToolTelemetry(params) {
|
|
|
6032
6466
|
params.telemetry.didSendViaMessagingTool = true;
|
|
6033
6467
|
const sourceReplyPayload = extractInternalSourceReplyPayload(params.result?.details);
|
|
6034
6468
|
if (sourceReplyPayload) {
|
|
6035
|
-
|
|
6469
|
+
const record = {
|
|
6036
6470
|
...sourceReplyPayload,
|
|
6037
6471
|
...params.sourceReplyFinal !== void 0 ? { sourceReplyFinal: params.sourceReplyFinal } : {}
|
|
6038
|
-
}
|
|
6039
|
-
|
|
6472
|
+
};
|
|
6473
|
+
params.telemetry.messagingToolSourceReplyPayloads.push(record);
|
|
6474
|
+
return record;
|
|
6040
6475
|
}
|
|
6041
6476
|
const text = readFirstString(params.args, [
|
|
6042
6477
|
"text",
|
|
@@ -6047,7 +6482,7 @@ function collectToolTelemetry(params) {
|
|
|
6047
6482
|
if (text) params.telemetry.messagingToolSentTexts.push(text);
|
|
6048
6483
|
const mediaUrls = collectMediaUrls(params.args);
|
|
6049
6484
|
params.telemetry.messagingToolSentMediaUrls.push(...mediaUrls);
|
|
6050
|
-
|
|
6485
|
+
const record = {
|
|
6051
6486
|
...params.messagingTarget ?? {
|
|
6052
6487
|
tool: params.toolName,
|
|
6053
6488
|
provider: readFirstString(params.args, ["provider", "channel"]) ?? params.toolName,
|
|
@@ -6066,7 +6501,9 @@ function collectToolTelemetry(params) {
|
|
|
6066
6501
|
...text ? { text } : {},
|
|
6067
6502
|
...mediaUrls.length > 0 ? { mediaUrls } : {},
|
|
6068
6503
|
...params.sourceReplyFinal !== void 0 ? { sourceReplyFinal: params.sourceReplyFinal } : {}
|
|
6069
|
-
}
|
|
6504
|
+
};
|
|
6505
|
+
params.telemetry.messagingToolSentTargets.push(record);
|
|
6506
|
+
return record;
|
|
6070
6507
|
}
|
|
6071
6508
|
function extractInternalSourceReplyPayload(details) {
|
|
6072
6509
|
if (!isRecord(details) || details.sourceReplySink !== "internal-ui") return;
|
|
@@ -6087,17 +6524,6 @@ function extractInternalSourceReplyPayload(details) {
|
|
|
6087
6524
|
};
|
|
6088
6525
|
return text || mediaUrls.length > 0 || payload.presentation || payload.interactive ? payload : void 0;
|
|
6089
6526
|
}
|
|
6090
|
-
function isCodexToolResultError(result) {
|
|
6091
|
-
if (isToolResultError(result)) return true;
|
|
6092
|
-
const details = result.details;
|
|
6093
|
-
if (!isRecord(details)) return false;
|
|
6094
|
-
if (details.ok === true || details.success === true) return false;
|
|
6095
|
-
if (details.timedOut === true) return true;
|
|
6096
|
-
if (typeof details.exitCode === "number" && details.exitCode !== 0) return true;
|
|
6097
|
-
if (typeof details.status !== "string") return false;
|
|
6098
|
-
const status = details.status.trim().toLowerCase();
|
|
6099
|
-
return status !== "" && status !== "0" && status !== "ok" && status !== "success" && status !== "completed" && status !== "recorded" && status !== "created" && status !== "updated" && status !== "accepted" && status !== "found" && status !== "missing" && status !== "pending" && status !== "started" && status !== "running" && status !== "yielded";
|
|
6100
|
-
}
|
|
6101
6527
|
function isToolResultYield(result) {
|
|
6102
6528
|
const details = result.details;
|
|
6103
6529
|
if (!isRecord(details) || typeof details.status !== "string") return false;
|
|
@@ -6125,15 +6551,6 @@ function withDiagnosticFailureDisposition(response, disposition) {
|
|
|
6125
6551
|
});
|
|
6126
6552
|
return response;
|
|
6127
6553
|
}
|
|
6128
|
-
function withSideEffectEvidence(response, sideEffectEvidence) {
|
|
6129
|
-
if (!sideEffectEvidence) return response;
|
|
6130
|
-
Object.defineProperty(response, "sideEffectEvidence", {
|
|
6131
|
-
configurable: true,
|
|
6132
|
-
enumerable: false,
|
|
6133
|
-
value: true
|
|
6134
|
-
});
|
|
6135
|
-
return response;
|
|
6136
|
-
}
|
|
6137
6554
|
function withDynamicToolTermination(response, terminate) {
|
|
6138
6555
|
if (!terminate) return response;
|
|
6139
6556
|
Object.defineProperty(response, "terminate", {
|
|
@@ -6274,4 +6691,4 @@ function isCronAddAction(args) {
|
|
|
6274
6691
|
return typeof action === "string" && action.trim().toLowerCase() === "add";
|
|
6275
6692
|
}
|
|
6276
6693
|
//#endregion
|
|
6277
|
-
export {
|
|
6694
|
+
export { resolveCodexToolProgressDetailMode as $, CODEX_NATIVE_HOOK_RELAY_EVENTS as A, hasPendingDynamicToolTerminalDiagnostic as B, CodexAppServerEventProjector as C, markCodexAuthProfileBlockedFromRateLimits as D, isCodexUsageLimitPromptError as E, emitCodexNativePreToolUseFailureDiagnostic as F, shouldBlockTerminalReleaseForNonTerminalDynamicToolResult as G, isMatchingDynamicToolTerminalDiagnostic as H, resolveCodexNativeHookRelayEvents as I, toCodexDynamicToolProtocolResponse as J, shouldReleaseTurnAfterTerminalDynamicTool as K, resolveCodexNativeHookRelayTtlMs as L, buildCodexNativeHookRelayConfig as M, buildCodexNativeHookRelayDisabledConfig as N, refreshCodexUsageLimitPromptError as O, createCodexNativeHookRelay as P, inferCodexDynamicToolMeta as Q, scheduleCodexNativeHookRelayUnregister as R, filterToolsForVisionInputs as S, formatCodexTurnStartUsageLimitError as T, resolveDynamicToolCallTimeoutMs as U, isDynamicToolTerminalDiagnosticEvent as V, resolveTerminalDynamicToolBatchAction as W, readCodexMirroredSessionHistoryMessages as X, resolveCodexToolAbortTerminalReason as Y, shouldEmitTranscriptToolProgress as Z, resolveCodexMessageToolProvider as _, emitDynamicToolStartedDiagnostic as a, shouldRequireCodexSandboxExecServerEnvironment as b, resolveCodexProviderWebSearchSupportForClient as c, createCodexDynamicToolBuildStageTracker as d, sanitizeCodexToolArguments as et, disableCodexPluginThreadConfig as f, resolveCodexExternalSandboxPolicyForOpenClawSandbox as g, resolveCodexAppServerHookChannelId as h, emitDynamicToolErrorDiagnostic as i, CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS as j, CodexNativeToolLifecycleProjector as k, settleCodexSourceReplyFinality as l, resolveCodexAppServerExecutionCwd as m, handleCodexAppServerApprovalRequest as n, redactCodexEventKind as nt, emitDynamicToolTerminalDiagnostic as o, formatCodexDynamicToolBuildStageSummary as p, toCodexDynamicToolProgressResponse as q, handleCodexAppServerElicitationRequest as r, resolveCodexLocalRuntimeAttribution as rt, resolveCodexProviderWebSearchSupport as s, createCodexDynamicToolBridge as t, sanitizeCodexToolResponse as tt, buildDynamicTools as u, resolveCodexSandboxEnvironmentSelection as v, createCodexUsageLimitPromptError as w, shouldWarnCodexDynamicToolBuildStageSummary as x, shouldEnableCodexAppServerNativeToolSurface as y, handleDynamicToolCallWithTimeout as z };
|