@openclaw/codex 2026.6.5-beta.1 → 2026.6.5-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/dist/harness.js +2 -2
- package/dist/{native-hook-relay-DZ3Oon0b.js → native-hook-relay-DHwz_ICg.js} +137 -38
- package/dist/{run-attempt-B_6VkFQN.js → run-attempt-DOr_d98I.js} +211 -66
- package/dist/{side-question-BEpALo9c.js → side-question-BnvBQPqW.js} +1 -1
- package/npm-shrinkwrap.json +2 -2
- package/package.json +4 -4
package/dist/harness.js
CHANGED
|
@@ -32,14 +32,14 @@ function createCodexAppServerAgentHarness(options) {
|
|
|
32
32
|
};
|
|
33
33
|
},
|
|
34
34
|
runAttempt: async (params) => {
|
|
35
|
-
const { runCodexAppServerAttempt } = await import("./run-attempt-
|
|
35
|
+
const { runCodexAppServerAttempt } = await import("./run-attempt-DOr_d98I.js");
|
|
36
36
|
return runCodexAppServerAttempt(params, {
|
|
37
37
|
pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
|
|
38
38
|
nativeHookRelay: { enabled: true }
|
|
39
39
|
});
|
|
40
40
|
},
|
|
41
41
|
runSideQuestion: async (params) => {
|
|
42
|
-
const { runCodexAppServerSideQuestion } = await import("./side-question-
|
|
42
|
+
const { runCodexAppServerSideQuestion } = await import("./side-question-BnvBQPqW.js");
|
|
43
43
|
return runCodexAppServerSideQuestion(params, {
|
|
44
44
|
pluginConfig: options?.resolvePluginConfig?.() ?? options?.pluginConfig,
|
|
45
45
|
nativeHookRelay: { enabled: true }
|
|
@@ -992,23 +992,17 @@ function createCodexDynamicToolBridge(params) {
|
|
|
992
992
|
const toolResultMaxChars = resolveCodexDynamicToolResultMaxChars(params.hookContext);
|
|
993
993
|
const availableProjection = projectCodexDynamicTools(params.tools);
|
|
994
994
|
const registeredProjection = params.registeredTools ? projectCodexDynamicTools(params.registeredTools) : availableProjection;
|
|
995
|
-
const
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
};
|
|
1007
|
-
});
|
|
1008
|
-
const toolMap = new Map(availableTools.map(({ tool }) => [tool.name, tool]));
|
|
1009
|
-
const registeredTools = registeredProjection.tools.map(({ tool }) => tool);
|
|
1010
|
-
const registeredToolNames = new Set(registeredTools.map((tool) => tool.name));
|
|
1011
|
-
const quarantinedTools = dedupeQuarantinedDynamicTools([...availableProjection.quarantinedTools, ...registeredProjection.quarantinedTools]);
|
|
995
|
+
const wrappedAvailableProjection = wrapProjectedCodexDynamicTools(availableProjection.tools, params.hookContext);
|
|
996
|
+
const availableTools = wrappedAvailableProjection.tools;
|
|
997
|
+
const quarantinedAvailableToolNames = new Set([...availableProjection.quarantinedTools, ...wrappedAvailableProjection.quarantinedTools].map((tool) => tool.tool));
|
|
998
|
+
const registeredSpecTools = (params.registeredTools ? registeredProjection.tools : availableTools).filter((entry) => !quarantinedAvailableToolNames.has(entry.name));
|
|
999
|
+
const toolMap = new Map(availableTools.map((entry) => [entry.name, entry]));
|
|
1000
|
+
const registeredToolNames = new Set(registeredSpecTools.map((entry) => entry.name));
|
|
1001
|
+
const quarantinedTools = dedupeQuarantinedDynamicTools([
|
|
1002
|
+
...availableProjection.quarantinedTools,
|
|
1003
|
+
...registeredProjection.quarantinedTools,
|
|
1004
|
+
...wrappedAvailableProjection.quarantinedTools
|
|
1005
|
+
]);
|
|
1012
1006
|
warnQuarantinedDynamicTools(quarantinedTools);
|
|
1013
1007
|
emitQuarantinedDynamicToolDiagnostics(quarantinedTools, params.hookContext);
|
|
1014
1008
|
const telemetry = {
|
|
@@ -1028,22 +1022,20 @@ function createCodexDynamicToolBridge(params) {
|
|
|
1028
1022
|
const legacyExtensionRunner = createCodexAppServerToolResultExtensionRunner(toolResultHookContext);
|
|
1029
1023
|
const directToolNames = new Set([...ALWAYS_DIRECT_DYNAMIC_TOOL_NAMES, ...params.directToolNames ?? []]);
|
|
1030
1024
|
return {
|
|
1031
|
-
availableSpecs: availableTools.map((
|
|
1032
|
-
|
|
1033
|
-
inputSchema,
|
|
1025
|
+
availableSpecs: availableTools.map((entry) => createCodexDynamicToolSpec({
|
|
1026
|
+
entry,
|
|
1034
1027
|
loading: params.loading ?? "searchable",
|
|
1035
1028
|
directToolNames
|
|
1036
1029
|
})),
|
|
1037
|
-
specs:
|
|
1038
|
-
|
|
1039
|
-
inputSchema,
|
|
1030
|
+
specs: registeredSpecTools.map((entry) => createCodexDynamicToolSpec({
|
|
1031
|
+
entry,
|
|
1040
1032
|
loading: params.loading ?? "searchable",
|
|
1041
1033
|
directToolNames
|
|
1042
1034
|
})),
|
|
1043
1035
|
telemetry,
|
|
1044
1036
|
handleToolCall: async (call, options) => {
|
|
1045
|
-
const
|
|
1046
|
-
if (!
|
|
1037
|
+
const toolEntry = toolMap.get(call.tool);
|
|
1038
|
+
if (!toolEntry) {
|
|
1047
1039
|
if (registeredToolNames.has(call.tool)) return {
|
|
1048
1040
|
contentItems: [{
|
|
1049
1041
|
type: "inputText",
|
|
@@ -1059,6 +1051,7 @@ function createCodexDynamicToolBridge(params) {
|
|
|
1059
1051
|
success: false
|
|
1060
1052
|
};
|
|
1061
1053
|
}
|
|
1054
|
+
const { tool, name: toolName } = toolEntry;
|
|
1062
1055
|
const args = jsonObjectToRecord(call.arguments);
|
|
1063
1056
|
const startedAt = Date.now();
|
|
1064
1057
|
const signal = composeAbortSignals(params.signal, options?.signal);
|
|
@@ -1072,7 +1065,7 @@ function createCodexDynamicToolBridge(params) {
|
|
|
1072
1065
|
threadId: call.threadId,
|
|
1073
1066
|
turnId: call.turnId,
|
|
1074
1067
|
toolCallId: call.callId,
|
|
1075
|
-
toolName
|
|
1068
|
+
toolName,
|
|
1076
1069
|
args,
|
|
1077
1070
|
isError: rawIsError,
|
|
1078
1071
|
result: rawResult
|
|
@@ -1081,13 +1074,13 @@ function createCodexDynamicToolBridge(params) {
|
|
|
1081
1074
|
threadId: call.threadId,
|
|
1082
1075
|
turnId: call.turnId,
|
|
1083
1076
|
toolCallId: call.callId,
|
|
1084
|
-
toolName
|
|
1077
|
+
toolName,
|
|
1085
1078
|
args,
|
|
1086
1079
|
result: middlewareResult
|
|
1087
1080
|
});
|
|
1088
1081
|
const resultIsError = rawIsError || isToolResultError(result);
|
|
1089
1082
|
collectToolTelemetry({
|
|
1090
|
-
toolName
|
|
1083
|
+
toolName,
|
|
1091
1084
|
args,
|
|
1092
1085
|
result,
|
|
1093
1086
|
mediaTrustResult: rawResult,
|
|
@@ -1095,7 +1088,7 @@ function createCodexDynamicToolBridge(params) {
|
|
|
1095
1088
|
isError: resultIsError
|
|
1096
1089
|
});
|
|
1097
1090
|
runAgentHarnessAfterToolCallHook({
|
|
1098
|
-
toolName
|
|
1091
|
+
toolName,
|
|
1099
1092
|
toolCallId: call.callId,
|
|
1100
1093
|
runId: toolResultHookContext.runId,
|
|
1101
1094
|
agentId: toolResultHookContext.agentId,
|
|
@@ -1116,14 +1109,14 @@ function createCodexDynamicToolBridge(params) {
|
|
|
1116
1109
|
return withSideEffectEvidence(response, terminalType !== "blocked");
|
|
1117
1110
|
} catch (error) {
|
|
1118
1111
|
collectToolTelemetry({
|
|
1119
|
-
toolName
|
|
1112
|
+
toolName,
|
|
1120
1113
|
args,
|
|
1121
1114
|
result: void 0,
|
|
1122
1115
|
telemetry,
|
|
1123
1116
|
isError: true
|
|
1124
1117
|
});
|
|
1125
1118
|
runAgentHarnessAfterToolCallHook({
|
|
1126
|
-
toolName
|
|
1119
|
+
toolName,
|
|
1127
1120
|
toolCallId: call.callId,
|
|
1128
1121
|
runId: toolResultHookContext.runId,
|
|
1129
1122
|
agentId: toolResultHookContext.agentId,
|
|
@@ -1145,13 +1138,37 @@ function createCodexDynamicToolBridge(params) {
|
|
|
1145
1138
|
}
|
|
1146
1139
|
};
|
|
1147
1140
|
}
|
|
1141
|
+
function wrapProjectedCodexDynamicTools(tools, hookContext) {
|
|
1142
|
+
const wrappedTools = [];
|
|
1143
|
+
const quarantinedTools = [];
|
|
1144
|
+
for (const entry of tools) try {
|
|
1145
|
+
if (isToolWrappedWithBeforeToolCallHook(entry.tool)) {
|
|
1146
|
+
setBeforeToolCallDiagnosticsEnabled(entry.tool, false);
|
|
1147
|
+
wrappedTools.push(entry);
|
|
1148
|
+
continue;
|
|
1149
|
+
}
|
|
1150
|
+
wrappedTools.push({
|
|
1151
|
+
...entry,
|
|
1152
|
+
tool: wrapToolWithBeforeToolCallHook(entry.tool, hookContext, { emitDiagnostics: false })
|
|
1153
|
+
});
|
|
1154
|
+
} catch {
|
|
1155
|
+
quarantinedTools.push({
|
|
1156
|
+
tool: entry.name,
|
|
1157
|
+
violations: [`${entry.name} could not be wrapped for before-tool-call hooks`]
|
|
1158
|
+
});
|
|
1159
|
+
}
|
|
1160
|
+
return {
|
|
1161
|
+
tools: wrappedTools,
|
|
1162
|
+
quarantinedTools
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1148
1165
|
function createCodexDynamicToolSpec(params) {
|
|
1149
1166
|
const base = {
|
|
1150
|
-
name: params.
|
|
1151
|
-
description: params.
|
|
1152
|
-
inputSchema: params.inputSchema
|
|
1167
|
+
name: params.entry.name,
|
|
1168
|
+
description: params.entry.description,
|
|
1169
|
+
inputSchema: params.entry.inputSchema
|
|
1153
1170
|
};
|
|
1154
|
-
if (params.loading === "direct" || params.directToolNames.has(params.
|
|
1171
|
+
if (params.loading === "direct" || params.directToolNames.has(params.entry.name)) return base;
|
|
1155
1172
|
return {
|
|
1156
1173
|
...base,
|
|
1157
1174
|
namespace: CODEX_OPENCLAW_DYNAMIC_TOOL_NAMESPACE,
|
|
@@ -1161,17 +1178,46 @@ function createCodexDynamicToolSpec(params) {
|
|
|
1161
1178
|
function projectCodexDynamicTools(tools) {
|
|
1162
1179
|
const projectedTools = [];
|
|
1163
1180
|
const quarantinedTools = [];
|
|
1164
|
-
|
|
1165
|
-
|
|
1181
|
+
let length;
|
|
1182
|
+
try {
|
|
1183
|
+
length = tools.length;
|
|
1184
|
+
} catch {
|
|
1185
|
+
return {
|
|
1186
|
+
tools: [],
|
|
1187
|
+
quarantinedTools: [{
|
|
1188
|
+
tool: "tool[0]",
|
|
1189
|
+
violations: ["tool[0] is unreadable"]
|
|
1190
|
+
}]
|
|
1191
|
+
};
|
|
1192
|
+
}
|
|
1193
|
+
for (let toolIndex = 0; toolIndex < length; toolIndex += 1) {
|
|
1194
|
+
let tool;
|
|
1195
|
+
try {
|
|
1196
|
+
tool = tools[toolIndex];
|
|
1197
|
+
} catch {
|
|
1198
|
+
quarantinedTools.push({
|
|
1199
|
+
tool: `tool[${toolIndex}]`,
|
|
1200
|
+
violations: [`tool[${toolIndex}] is unreadable`]
|
|
1201
|
+
});
|
|
1202
|
+
continue;
|
|
1203
|
+
}
|
|
1204
|
+
const descriptor = readCodexDynamicToolDescriptor(tool, toolIndex);
|
|
1205
|
+
if (!descriptor.ok) {
|
|
1206
|
+
quarantinedTools.push(descriptor.diagnostic);
|
|
1207
|
+
continue;
|
|
1208
|
+
}
|
|
1209
|
+
const projection = projectRuntimeToolInputSchema(descriptor.parameters, `${descriptor.name}.inputSchema`);
|
|
1166
1210
|
if (projection.violations.length > 0) {
|
|
1167
1211
|
quarantinedTools.push({
|
|
1168
|
-
tool:
|
|
1212
|
+
tool: descriptor.name,
|
|
1169
1213
|
violations: projection.violations
|
|
1170
1214
|
});
|
|
1171
1215
|
continue;
|
|
1172
1216
|
}
|
|
1173
1217
|
projectedTools.push({
|
|
1174
1218
|
tool,
|
|
1219
|
+
name: descriptor.name,
|
|
1220
|
+
description: descriptor.description,
|
|
1175
1221
|
inputSchema: projection.schema
|
|
1176
1222
|
});
|
|
1177
1223
|
}
|
|
@@ -1180,6 +1226,59 @@ function projectCodexDynamicTools(tools) {
|
|
|
1180
1226
|
quarantinedTools
|
|
1181
1227
|
};
|
|
1182
1228
|
}
|
|
1229
|
+
function readCodexDynamicToolDescriptor(tool, toolIndex) {
|
|
1230
|
+
const fallbackName = `tool[${toolIndex}]`;
|
|
1231
|
+
let name;
|
|
1232
|
+
try {
|
|
1233
|
+
const rawName = tool.name;
|
|
1234
|
+
if (typeof rawName !== "string" || !rawName) return {
|
|
1235
|
+
ok: false,
|
|
1236
|
+
diagnostic: {
|
|
1237
|
+
tool: fallbackName,
|
|
1238
|
+
violations: [`${fallbackName}.name must be a non-empty string`]
|
|
1239
|
+
}
|
|
1240
|
+
};
|
|
1241
|
+
name = rawName;
|
|
1242
|
+
} catch {
|
|
1243
|
+
return {
|
|
1244
|
+
ok: false,
|
|
1245
|
+
diagnostic: {
|
|
1246
|
+
tool: fallbackName,
|
|
1247
|
+
violations: [`${fallbackName}.name is unreadable`]
|
|
1248
|
+
}
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
let description;
|
|
1252
|
+
try {
|
|
1253
|
+
description = typeof tool.description === "string" ? tool.description : "";
|
|
1254
|
+
} catch {
|
|
1255
|
+
return {
|
|
1256
|
+
ok: false,
|
|
1257
|
+
diagnostic: {
|
|
1258
|
+
tool: name,
|
|
1259
|
+
violations: [`${name}.description is unreadable`]
|
|
1260
|
+
}
|
|
1261
|
+
};
|
|
1262
|
+
}
|
|
1263
|
+
let parameters;
|
|
1264
|
+
try {
|
|
1265
|
+
parameters = tool.parameters;
|
|
1266
|
+
} catch {
|
|
1267
|
+
return {
|
|
1268
|
+
ok: false,
|
|
1269
|
+
diagnostic: {
|
|
1270
|
+
tool: name,
|
|
1271
|
+
violations: [`${name}.inputSchema is unreadable`]
|
|
1272
|
+
}
|
|
1273
|
+
};
|
|
1274
|
+
}
|
|
1275
|
+
return {
|
|
1276
|
+
ok: true,
|
|
1277
|
+
name,
|
|
1278
|
+
description,
|
|
1279
|
+
parameters
|
|
1280
|
+
};
|
|
1281
|
+
}
|
|
1183
1282
|
function warnQuarantinedDynamicTools(tools) {
|
|
1184
1283
|
if (tools.length === 0) return;
|
|
1185
1284
|
const unique = /* @__PURE__ */ new Map();
|
|
@@ -8,7 +8,7 @@ import { _ as shouldRefreshCodexRateLimitsForUsageLimitMessage, g as resolveCode
|
|
|
8
8
|
import { d as resolveCodexAppServerAuthAccountCacheKey, f as resolveCodexAppServerAuthProfileId, h as resolveCodexAppServerHomeDir, m as resolveCodexAppServerFallbackApiKeyCacheKey, n as clearSharedCodexAppServerClientIfCurrentAndUnclaimed, o as releaseLeasedSharedCodexAppServerClient, p as resolveCodexAppServerAuthProfileIdForAgent, s as retireSharedCodexAppServerClientIfCurrent, t as clearSharedCodexAppServerClientIfCurrent, u as refreshCodexAppServerAuthTokens } from "./shared-client-xytpSKD0.js";
|
|
9
9
|
import { i as resolveCodexNativeExecutionPolicy } from "./sandbox-guard-C-Yv9uwY.js";
|
|
10
10
|
import { t as defaultLeasedCodexAppServerClientFactory } from "./client-factory-Bt49r45B.js";
|
|
11
|
-
import { S as withCodexStartupTimeout, _ as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, a as createCodexNativeHookRelay, b as resolveCodexTurnCompletionIdleTimeoutMs, c as scheduleCodexNativeHookRelayUnregister, d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, g as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, h as handleCodexAppServerApprovalRequest, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, n as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, o as resolveCodexNativeHookRelayEvents, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, s as resolveCodexNativeHookRelayTtlMs, u as createCodexDynamicToolBridge, v as resolveCodexStartupTimeoutMs, x as resolveCodexTurnTerminalIdleTimeoutMs, y as resolveCodexTurnAssistantCompletionIdleTimeoutMs } from "./native-hook-relay-
|
|
11
|
+
import { S as withCodexStartupTimeout, _ as resolveCodexPostToolRawAssistantCompletionIdleTimeoutMs, a as createCodexNativeHookRelay, b as resolveCodexTurnCompletionIdleTimeoutMs, c as scheduleCodexNativeHookRelayUnregister, d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, g as CODEX_POST_REASONING_REPLY_IDLE_TIMEOUT_MS, h as handleCodexAppServerApprovalRequest, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, n as CODEX_NATIVE_HOOK_RELAY_TTL_GRACE_MS, o as resolveCodexNativeHookRelayEvents, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, s as resolveCodexNativeHookRelayTtlMs, u as createCodexDynamicToolBridge, v as resolveCodexStartupTimeoutMs, x as resolveCodexTurnTerminalIdleTimeoutMs, y as resolveCodexTurnAssistantCompletionIdleTimeoutMs } from "./native-hook-relay-DHwz_ICg.js";
|
|
12
12
|
import { t as ensureCodexComputerUse } from "./computer-use-ClweWaMz.js";
|
|
13
13
|
import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-C7qmZ0Jh.js";
|
|
14
14
|
import { asDateTimestampMs, parseStrictNonNegativeInteger, resolveTimerTimeoutMs } from "openclaw/plugin-sdk/number-runtime";
|
|
@@ -25,6 +25,7 @@ import fs from "node:fs/promises";
|
|
|
25
25
|
import path, { posix } from "node:path";
|
|
26
26
|
import { createDiagnosticTraceContextFromActiveScope, emitTrustedDiagnosticEvent, emitTrustedDiagnosticEventWithPrivateData, freezeDiagnosticTraceContext, hasPendingInternalDiagnosticEvent, onInternalDiagnosticEvent, resolveDiagnosticModelContentCapturePolicy } from "openclaw/plugin-sdk/diagnostic-runtime";
|
|
27
27
|
import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1, resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
|
|
28
|
+
import { loadSessionStore } from "openclaw/plugin-sdk/session-store-runtime";
|
|
28
29
|
import { isToolAllowed } from "openclaw/plugin-sdk/sandbox";
|
|
29
30
|
import { appendRegularFile, pathExists } from "openclaw/plugin-sdk/security-runtime";
|
|
30
31
|
import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "openclaw/plugin-sdk/agent-sessions";
|
|
@@ -893,6 +894,10 @@ function isRawReasoningCompletionNotification(notification) {
|
|
|
893
894
|
const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
|
|
894
895
|
return item ? readString$6(item, "type") === "reasoning" : false;
|
|
895
896
|
}
|
|
897
|
+
/** Returns true for streamed app-server reasoning progress. */
|
|
898
|
+
function isReasoningProgressNotification(notification) {
|
|
899
|
+
return notification.method === "item/reasoning/textDelta" || notification.method === "item/reasoning/summaryTextDelta" || notification.method === "item/reasoning/summaryPartAdded";
|
|
900
|
+
}
|
|
896
901
|
/** Returns true when assistant completion can release the short idle watch. */
|
|
897
902
|
function isAssistantCompletionReleaseNotification(notification, turnCrossedToolHandoff) {
|
|
898
903
|
if (isCompletedAssistantNotification(notification)) return true;
|
|
@@ -1116,13 +1121,13 @@ function applyCodexTurnNotificationState(params) {
|
|
|
1116
1121
|
const rawToolOutputCompletion = isRawToolOutputCompletionNotification(notification);
|
|
1117
1122
|
if (isCurrentTurnNotification && (rawToolOutputCompletion || isNativeToolProgressNotification(notification))) turnCrossedToolHandoff = true;
|
|
1118
1123
|
const assistantCompletionCanRelease = isAssistantCompletionReleaseNotification(notification, turnCrossedToolHandoff);
|
|
1119
|
-
const
|
|
1124
|
+
const postToolProgressNeedsTerminalGuard = isCurrentTurnNotification && turnCrossedToolHandoff && ((isRawAssistantProgressNotification(notification) || isRawReasoningCompletionNotification(notification)) && params.activeTurnItemIds.size === 0 || isReasoningProgressNotification(notification));
|
|
1120
1125
|
const postToolPatchUpdateNeedsTerminalGuard = isCurrentTurnNotification && turnCrossedToolHandoff && isFileChangePatchUpdatedNotification(notification);
|
|
1121
|
-
const rawResponseItemCompletedWithNoActiveItems = isCurrentTurnNotification && notification.method === "rawResponseItem/completed" && params.activeTurnItemIds.size === 0 && params.activeAppServerTurnRequests === 0 && !assistantCompletionCanRelease && !
|
|
1126
|
+
const rawResponseItemCompletedWithNoActiveItems = isCurrentTurnNotification && notification.method === "rawResponseItem/completed" && params.activeTurnItemIds.size === 0 && params.activeAppServerTurnRequests === 0 && !assistantCompletionCanRelease && !postToolProgressNeedsTerminalGuard && !rawToolOutputCompletion;
|
|
1122
1127
|
const shouldArmNoToolPostProgressReplyWatch = isCurrentTurnNotification && !turnCrossedToolHandoff && params.activeTurnItemIds.size === 0 && (isReasoningItemCompletionNotification(notification) || isAssistantCommentaryCompletionNotification(notification));
|
|
1123
1128
|
const shouldArmNoToolPostRawProgressReplyWatch = !turnCrossedToolHandoff && rawResponseItemCompletedWithNoActiveItems && (isRawReasoningCompletionNotification(notification) || isRawAssistantProgressNotification(notification));
|
|
1124
1129
|
const shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem = isCurrentTurnNotification && notification.method === "item/completed" && params.activeTurnItemIds.size === 0 && !trackedDynamicToolCompletion && !assistantCompletionCanRelease && !shouldArmNoToolPostProgressReplyWatch;
|
|
1125
|
-
const shouldUsePostToolContinuationWatch = turnCrossedToolHandoff && (
|
|
1130
|
+
const shouldUsePostToolContinuationWatch = turnCrossedToolHandoff && (postToolProgressNeedsTerminalGuard || postToolPatchUpdateNeedsTerminalGuard || rawToolOutputCompletion || trackedDynamicToolCompletion || shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem);
|
|
1126
1131
|
const armPostToolContinuationWatch = () => {
|
|
1127
1132
|
turnWatches.armCompletionIdleWatch({ timeoutMs: params.postToolRawAssistantCompletionIdleTimeoutMs });
|
|
1128
1133
|
turnWatches.extendAttemptIdleWatch(params.postToolRawAssistantCompletionIdleTimeoutMs);
|
|
@@ -1137,7 +1142,7 @@ function applyCodexTurnNotificationState(params) {
|
|
|
1137
1142
|
turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1138
1143
|
} else if (isTurnCompletion) turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1139
1144
|
else if (isCurrentTurnNotification && assistantCompletionCanRelease) turnWatches.armAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
1140
|
-
else if (
|
|
1145
|
+
else if (postToolProgressNeedsTerminalGuard || postToolPatchUpdateNeedsTerminalGuard) armPostToolContinuationWatch();
|
|
1141
1146
|
else if (shouldArmNoToolPostProgressReplyWatch || shouldArmNoToolPostRawProgressReplyWatch) armPostProgressReplyWatch();
|
|
1142
1147
|
else if (trackedDynamicToolCompletion) armPostToolContinuationWatch();
|
|
1143
1148
|
else if (unblockedAssistantCompletionRelease) turnWatches.armAssistantCompletionIdleWatch(describeNotificationActivity(notification));
|
|
@@ -1146,7 +1151,7 @@ function applyCodexTurnNotificationState(params) {
|
|
|
1146
1151
|
else if (rawResponseItemCompletedWithNoActiveItems) turnWatches.armCompletionIdleWatch();
|
|
1147
1152
|
else if (isCurrentTurnNotification && rawToolOutputCompletion) armPostToolContinuationWatch();
|
|
1148
1153
|
else if (isCurrentTurnNotification && shouldDisarmAssistantCompletionIdleWatch(notification)) turnWatches.disarmAssistantCompletionIdleWatch();
|
|
1149
|
-
if (turnWatches.isCompletionIdleWatchArmed() && !turnWatches.isCompletionIdleWatchPinnedByTerminalError() && notification.method !== "turn/completed" && isCurrentTurnNotification && !isNativeResponseStreamDelta && !trackedDynamicToolCompletion && !rawToolOutputCompletion && !
|
|
1154
|
+
if (turnWatches.isCompletionIdleWatchArmed() && !turnWatches.isCompletionIdleWatchPinnedByTerminalError() && notification.method !== "turn/completed" && isCurrentTurnNotification && !isNativeResponseStreamDelta && !trackedDynamicToolCompletion && !rawToolOutputCompletion && !postToolProgressNeedsTerminalGuard && !postToolPatchUpdateNeedsTerminalGuard && !rawResponseItemCompletedWithNoActiveItems && !shouldArmNoToolPostProgressReplyWatch && !shouldArmNoToolPostRawProgressReplyWatch && !shouldRearmCompletionIdleWatchAfterLastCurrentTurnItem) turnWatches.disarmCompletionIdleWatch();
|
|
1150
1155
|
if (trackedDynamicToolCompletion) {
|
|
1151
1156
|
const itemId = readNotificationItemId(notification);
|
|
1152
1157
|
if (itemId) {
|
|
@@ -1174,21 +1179,17 @@ const CODEX_APP_SERVER_MISSING_TERMINAL_EVENT_SIDE_EFFECT_USER_MESSAGE = "Codex
|
|
|
1174
1179
|
function collectTerminalAssistantText(result) {
|
|
1175
1180
|
return result.assistantTexts.join("\n\n").trim();
|
|
1176
1181
|
}
|
|
1177
|
-
/** Returns whether attempt metadata saw potential side effects. */
|
|
1178
|
-
function hasCodexAppServerPotentialSideEffectEvidence(result) {
|
|
1179
|
-
return result.replayMetadata.hadPotentialSideEffects;
|
|
1180
|
-
}
|
|
1181
1182
|
/**
|
|
1182
1183
|
* Builds the user-facing timeout outcome when Codex stops without a terminal
|
|
1183
1184
|
* turn event.
|
|
1184
1185
|
*/
|
|
1185
1186
|
function buildCodexAppServerPromptTimeoutOutcome(params) {
|
|
1186
|
-
|
|
1187
|
+
if (!params.turnCompletionIdleTimedOut) return;
|
|
1188
|
+
if (params.turnWatchTimeoutKind !== void 0 && params.turnWatchTimeoutKind !== "completion") return;
|
|
1187
1189
|
const replayBlockedReason = resolveCodexAppServerReplayBlockedReason(params.result);
|
|
1188
|
-
if (!params.turnCompletionIdleTimedOut || params.result.itemLifecycle.completedCount === 0 && !completionIdleTimeoutHadPotentialSideEffects && replayBlockedReason === void 0) return;
|
|
1189
1190
|
return {
|
|
1190
|
-
message:
|
|
1191
|
-
...
|
|
1191
|
+
message: replayBlockedReason === "tool_activity" || replayBlockedReason === "potential_side_effect" || replayBlockedReason === "active_item" ? CODEX_APP_SERVER_MISSING_TERMINAL_EVENT_SIDE_EFFECT_USER_MESSAGE : CODEX_APP_SERVER_MISSING_TERMINAL_EVENT_USER_MESSAGE,
|
|
1192
|
+
...replayBlockedReason ? {
|
|
1192
1193
|
replayInvalid: true,
|
|
1193
1194
|
livenessState: "abandoned"
|
|
1194
1195
|
} : {}
|
|
@@ -3484,12 +3485,21 @@ function createCodexAttemptTurnWatchController(params) {
|
|
|
3484
3485
|
scheduleCompletionIdleWatch();
|
|
3485
3486
|
return;
|
|
3486
3487
|
}
|
|
3488
|
+
const details = {
|
|
3489
|
+
...completionLastActivityDetails,
|
|
3490
|
+
activeAppServerTurnRequests: params.getActiveAppServerTurnRequests(),
|
|
3491
|
+
activeTurnItemCount: params.getActiveTurnItemCount(),
|
|
3492
|
+
terminalTurnNotificationQueued: params.isTerminalTurnNotificationQueued(),
|
|
3493
|
+
completionIdleWatchArmed,
|
|
3494
|
+
assistantCompletionIdleWatchArmed,
|
|
3495
|
+
terminalIdleWatchArmed
|
|
3496
|
+
};
|
|
3487
3497
|
const timeout = {
|
|
3488
3498
|
kind: "completion",
|
|
3489
3499
|
idleMs,
|
|
3490
3500
|
timeoutMs,
|
|
3491
3501
|
lastActivityReason: completionLastActivityReason,
|
|
3492
|
-
details
|
|
3502
|
+
details
|
|
3493
3503
|
};
|
|
3494
3504
|
params.onTimeout(timeout);
|
|
3495
3505
|
params.onMarkTimedOut();
|
|
@@ -4228,6 +4238,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4228
4238
|
this.toolTrajectoryCallIds = /* @__PURE__ */ new Set();
|
|
4229
4239
|
this.toolTrajectoryResultIds = /* @__PURE__ */ new Set();
|
|
4230
4240
|
this.toolTrajectoryNamesById = /* @__PURE__ */ new Map();
|
|
4241
|
+
this.toolTrajectoryItemsById = /* @__PURE__ */ new Map();
|
|
4231
4242
|
this.transcriptToolProgressCallIds = /* @__PURE__ */ new Set();
|
|
4232
4243
|
this.nativeGeneratedMediaUrls = /* @__PURE__ */ new Set();
|
|
4233
4244
|
this.nativeGeneratedMediaItemIds = /* @__PURE__ */ new Set();
|
|
@@ -4246,6 +4257,10 @@ var CodexAppServerEventProjector = class {
|
|
|
4246
4257
|
getCompletedTurnStatus() {
|
|
4247
4258
|
return this.completedTurn?.status;
|
|
4248
4259
|
}
|
|
4260
|
+
hasCompletedTerminalAssistantText() {
|
|
4261
|
+
const finalItem = this.resolveFinalAssistantTextItem();
|
|
4262
|
+
return finalItem !== void 0 && this.completedItemIds.has(finalItem.itemId);
|
|
4263
|
+
}
|
|
4249
4264
|
async handleNotification(notification) {
|
|
4250
4265
|
const params = isJsonObject(notification.params) ? notification.params : void 0;
|
|
4251
4266
|
if (!params) return;
|
|
@@ -4312,7 +4327,13 @@ var CodexAppServerEventProjector = class {
|
|
|
4312
4327
|
const assistantTexts = this.collectAssistantTexts();
|
|
4313
4328
|
const reasoningText = collectReasoningTextValues(this.reasoningTextByGroup, this.reasoningItemOrder).join("\n\n");
|
|
4314
4329
|
const planText = collectTextValues(this.planTextByItem).join("\n\n");
|
|
4315
|
-
|
|
4330
|
+
const hasAssistantItemText = this.hasAssistantItemTextForSynthesis();
|
|
4331
|
+
const legacyFailClosed = !this.completedTurn || this.completedTurn.status !== "completed" || hasAssistantItemText;
|
|
4332
|
+
const hasDeliverableAssistantOnCompletedTurn = this.completedTurn?.status === "completed" && assistantTexts.some((text) => text.trim().length > 0);
|
|
4333
|
+
this.synthesizeMissingToolResults({
|
|
4334
|
+
synthesize: legacyFailClosed,
|
|
4335
|
+
recordPromptError: legacyFailClosed && !hasDeliverableAssistantOnCompletedTurn
|
|
4336
|
+
});
|
|
4316
4337
|
const lastAssistant = assistantTexts.length > 0 ? this.createAssistantMessage(assistantTexts.join("\n\n")) : void 0;
|
|
4317
4338
|
const turnId = this.turnId;
|
|
4318
4339
|
const messagesSnapshot = this.params.suppressNextUserMessagePersistence ? [] : [attachCodexMirrorIdentity(buildCodexUserPromptMessage(this.params), `${turnId}:prompt`)];
|
|
@@ -4974,6 +4995,7 @@ var CodexAppServerEventProjector = class {
|
|
|
4974
4995
|
if (params.phase === "start") {
|
|
4975
4996
|
this.toolTrajectoryCallIds.add(params.item.id);
|
|
4976
4997
|
this.toolTrajectoryNamesById.set(params.item.id, params.name);
|
|
4998
|
+
this.toolTrajectoryItemsById.set(params.item.id, params.item);
|
|
4977
4999
|
this.options.trajectoryRecorder?.recordEvent("tool.call", {
|
|
4978
5000
|
threadId: this.threadId,
|
|
4979
5001
|
turnId: this.turnId,
|
|
@@ -5169,7 +5191,7 @@ var CodexAppServerEventProjector = class {
|
|
|
5169
5191
|
this.toolTranscriptMessages.push(attachCodexMirrorIdentity(this.createToolResultMessage(params), `${this.turnId}:tool:${params.id}:result`));
|
|
5170
5192
|
}
|
|
5171
5193
|
synthesizeMissingToolResults(params) {
|
|
5172
|
-
if (!params.
|
|
5194
|
+
if (!params.synthesize) return;
|
|
5173
5195
|
const missingTranscriptIds = [...this.toolTranscriptCallIds].filter((id) => !this.toolTranscriptResultIds.has(id));
|
|
5174
5196
|
const missingTrajectoryIds = [...this.toolTrajectoryCallIds].filter((id) => !this.toolTrajectoryResultIds.has(id));
|
|
5175
5197
|
if (missingTranscriptIds.length === 0 && missingTrajectoryIds.length === 0) return;
|
|
@@ -5209,6 +5231,34 @@ var CodexAppServerEventProjector = class {
|
|
|
5209
5231
|
output: text
|
|
5210
5232
|
});
|
|
5211
5233
|
}
|
|
5234
|
+
if (!params.recordPromptError) {
|
|
5235
|
+
const firstMissingId = missingTranscriptIds.find((id) => {
|
|
5236
|
+
const name = this.toolTranscriptNamesById.get(id) ?? this.toolTrajectoryNamesById.get(id);
|
|
5237
|
+
return Boolean(name);
|
|
5238
|
+
}) ?? missingTrajectoryIds.find((id) => {
|
|
5239
|
+
const name = this.toolTrajectoryNamesById.get(id) ?? this.toolTranscriptNamesById.get(id);
|
|
5240
|
+
return Boolean(name);
|
|
5241
|
+
});
|
|
5242
|
+
if (firstMissingId) {
|
|
5243
|
+
const name = this.toolTranscriptNamesById.get(firstMissingId) ?? this.toolTrajectoryNamesById.get(firstMissingId);
|
|
5244
|
+
if (name) {
|
|
5245
|
+
const item = this.toolTrajectoryItemsById.get(firstMissingId);
|
|
5246
|
+
const meta = item ? itemMeta(item, this.toolProgressDetailMode()) : this.toolMetas.get(firstMissingId)?.meta;
|
|
5247
|
+
const actionFingerprint = item ? nativeToolActionFingerprint(item) : void 0;
|
|
5248
|
+
this.lastNativeToolError = {
|
|
5249
|
+
toolName: name,
|
|
5250
|
+
...meta ? { meta } : {},
|
|
5251
|
+
error: formatMissingToolResultError({
|
|
5252
|
+
id: firstMissingId,
|
|
5253
|
+
name
|
|
5254
|
+
}),
|
|
5255
|
+
...item && isMutatingNativeToolItem(item) ? { mutatingAction: true } : {},
|
|
5256
|
+
...actionFingerprint ? { actionFingerprint } : {}
|
|
5257
|
+
};
|
|
5258
|
+
}
|
|
5259
|
+
}
|
|
5260
|
+
return;
|
|
5261
|
+
}
|
|
5212
5262
|
const missingCount = new Set([...missingTranscriptIds, ...missingTrajectoryIds]).size;
|
|
5213
5263
|
this.synthesizedMissingToolResultError = missingCount === 1 ? MISSING_TOOL_RESULT_ERROR : `${MISSING_TOOL_RESULT_ERROR} missingToolResultCount=${missingCount}`;
|
|
5214
5264
|
this.promptErrorSource = this.promptErrorSource ?? "prompt";
|
|
@@ -5274,13 +5324,29 @@ var CodexAppServerEventProjector = class {
|
|
|
5274
5324
|
const finalText = this.resolveFinalAssistantText();
|
|
5275
5325
|
return finalText ? [finalText] : [];
|
|
5276
5326
|
}
|
|
5327
|
+
hasAssistantItemTextForSynthesis() {
|
|
5328
|
+
for (let i = this.assistantItemOrder.length - 1; i >= 0; i -= 1) {
|
|
5329
|
+
const itemId = this.assistantItemOrder[i];
|
|
5330
|
+
if (!itemId) continue;
|
|
5331
|
+
if (this.assistantPhaseByItem.get(itemId) === "commentary") continue;
|
|
5332
|
+
const text = this.assistantTextByItem.get(itemId);
|
|
5333
|
+
if (text && text.length > 0) return true;
|
|
5334
|
+
}
|
|
5335
|
+
return false;
|
|
5336
|
+
}
|
|
5277
5337
|
resolveFinalAssistantText() {
|
|
5338
|
+
return this.resolveFinalAssistantTextItem()?.text;
|
|
5339
|
+
}
|
|
5340
|
+
resolveFinalAssistantTextItem() {
|
|
5278
5341
|
for (let i = this.assistantItemOrder.length - 1; i >= 0; i -= 1) {
|
|
5279
5342
|
const itemId = this.assistantItemOrder[i];
|
|
5280
5343
|
if (!itemId) continue;
|
|
5281
5344
|
const text = this.assistantTextByItem.get(itemId)?.trim();
|
|
5282
5345
|
if (this.assistantPhaseByItem.get(itemId) === "commentary") continue;
|
|
5283
|
-
if (text && !this.toolProgressTexts.has(text)) return
|
|
5346
|
+
if (text && !this.toolProgressTexts.has(text)) return {
|
|
5347
|
+
itemId,
|
|
5348
|
+
text
|
|
5349
|
+
};
|
|
5284
5350
|
}
|
|
5285
5351
|
}
|
|
5286
5352
|
rememberAssistantItem(itemId) {
|
|
@@ -5849,10 +5915,11 @@ function readCompletionStatus(status) {
|
|
|
5849
5915
|
for (const [rawKey, value] of Object.entries(status)) {
|
|
5850
5916
|
const mappedStatus = mapCompletionStatus(normalizeStatusKey(rawKey));
|
|
5851
5917
|
if (!mappedStatus) continue;
|
|
5918
|
+
const result = stringifyResult(value, mappedStatus);
|
|
5852
5919
|
return {
|
|
5853
5920
|
status: mappedStatus,
|
|
5854
|
-
label: rawKey,
|
|
5855
|
-
result:
|
|
5921
|
+
label: mappedStatus === "succeeded" && result.kind === "no_final_assistant_message" ? "completed_without_final_message" : rawKey,
|
|
5922
|
+
result: result.text
|
|
5856
5923
|
};
|
|
5857
5924
|
}
|
|
5858
5925
|
}
|
|
@@ -5861,15 +5928,25 @@ function mapCompletionStatus(value) {
|
|
|
5861
5928
|
if (value === "cancelled" || value === "canceled" || value === "interrupted" || value === "shutdown") return "cancelled";
|
|
5862
5929
|
if (value === "failed" || value === "error" || value === "errored" || value === "systemerror" || value === "notfound") return "failed";
|
|
5863
5930
|
}
|
|
5864
|
-
function stringifyResult(value) {
|
|
5865
|
-
if (typeof value === "string")
|
|
5866
|
-
|
|
5931
|
+
function stringifyResult(value, status) {
|
|
5932
|
+
if (typeof value === "string") {
|
|
5933
|
+
const text = value.trim();
|
|
5934
|
+
if (text) return { text };
|
|
5935
|
+
return status === "succeeded" ? completedWithoutFinalAssistantMessage() : { text: "(no output)" };
|
|
5936
|
+
}
|
|
5937
|
+
if (value === null || value === void 0) return status === "succeeded" ? completedWithoutFinalAssistantMessage() : { text: "(no output)" };
|
|
5867
5938
|
try {
|
|
5868
|
-
return JSON.stringify(value);
|
|
5939
|
+
return { text: JSON.stringify(value) };
|
|
5869
5940
|
} catch {
|
|
5870
|
-
return "(unserializable output)";
|
|
5941
|
+
return { text: "(unserializable output)" };
|
|
5871
5942
|
}
|
|
5872
5943
|
}
|
|
5944
|
+
function completedWithoutFinalAssistantMessage() {
|
|
5945
|
+
return {
|
|
5946
|
+
text: "Codex native subagent completed without a final assistant message.",
|
|
5947
|
+
kind: "no_final_assistant_message"
|
|
5948
|
+
};
|
|
5949
|
+
}
|
|
5873
5950
|
function readTrustedInterAgentCommunicationContent(item) {
|
|
5874
5951
|
const communication = readTrustedInterAgentCommunication(item);
|
|
5875
5952
|
return typeof communication?.content === "string" ? communication.content : void 0;
|
|
@@ -6400,6 +6477,14 @@ var CodexNativeSubagentMonitor = class {
|
|
|
6400
6477
|
continue;
|
|
6401
6478
|
}
|
|
6402
6479
|
const completion = toThreadCompletion(nativeCompletion, childState.childThreadId);
|
|
6480
|
+
if (shouldWaitForTranscriptCompletion(completion, this.codexHome)) {
|
|
6481
|
+
const eventAt = Date.now();
|
|
6482
|
+
if (!await this.reconcileChildTranscript(childState.childThreadId)) {
|
|
6483
|
+
this.scheduleTranscriptPoll(childState);
|
|
6484
|
+
this.scheduleNoFinalCompletionFallback(state, childState, completion, eventAt);
|
|
6485
|
+
}
|
|
6486
|
+
continue;
|
|
6487
|
+
}
|
|
6403
6488
|
await this.processCompletion(state, completion);
|
|
6404
6489
|
}
|
|
6405
6490
|
}
|
|
@@ -6433,6 +6518,10 @@ var CodexNativeSubagentMonitor = class {
|
|
|
6433
6518
|
clearTimeout(childState.transcriptPollTimer);
|
|
6434
6519
|
childState.transcriptPollTimer = void 0;
|
|
6435
6520
|
}
|
|
6521
|
+
if (childState.noFinalCompletionFallbackTimer) {
|
|
6522
|
+
clearTimeout(childState.noFinalCompletionFallbackTimer);
|
|
6523
|
+
childState.noFinalCompletionFallbackTimer = void 0;
|
|
6524
|
+
}
|
|
6436
6525
|
}
|
|
6437
6526
|
if (!state.requesterSessionKey) return;
|
|
6438
6527
|
const completionKey = buildCompletionDedupeKey(state.parentThreadId, completion);
|
|
@@ -6586,6 +6675,24 @@ var CodexNativeSubagentMonitor = class {
|
|
|
6586
6675
|
}, delayMs);
|
|
6587
6676
|
unrefTimer(childState.transcriptPollTimer);
|
|
6588
6677
|
}
|
|
6678
|
+
scheduleNoFinalCompletionFallback(state, childState, completion, eventAt) {
|
|
6679
|
+
if (childState.transcriptTerminal || childState.noFinalCompletionFallbackTimer) return;
|
|
6680
|
+
const delayMs = noFinalCompletionFallbackDelayMs(this.transcriptPollDelaysMs);
|
|
6681
|
+
childState.noFinalCompletionFallbackTimer = setTimeout(() => {
|
|
6682
|
+
childState.noFinalCompletionFallbackTimer = void 0;
|
|
6683
|
+
this.deliverNoFinalCompletionFallback(state, childState, completion, eventAt);
|
|
6684
|
+
}, delayMs);
|
|
6685
|
+
unrefTimer(childState.noFinalCompletionFallbackTimer);
|
|
6686
|
+
}
|
|
6687
|
+
async deliverNoFinalCompletionFallback(state, childState, completion, eventAt) {
|
|
6688
|
+
if (!await this.reconcileChildTranscript(childState.childThreadId).catch((error) => {
|
|
6689
|
+
embeddedAgentLog.warn("Failed to reconcile Codex native subagent transcript", {
|
|
6690
|
+
childThreadId: childState.childThreadId,
|
|
6691
|
+
error: formatErrorMessage(error)
|
|
6692
|
+
});
|
|
6693
|
+
return false;
|
|
6694
|
+
}) && !childState.transcriptTerminal) await this.processCompletion(state, completion, eventAt);
|
|
6695
|
+
}
|
|
6589
6696
|
clearTimers() {
|
|
6590
6697
|
if (this.taskRowReconcileTimer) {
|
|
6591
6698
|
clearInterval(this.taskRowReconcileTimer);
|
|
@@ -6600,6 +6707,10 @@ var CodexNativeSubagentMonitor = class {
|
|
|
6600
6707
|
clearTimeout(childState.completionDeliveryTimer);
|
|
6601
6708
|
childState.completionDeliveryTimer = void 0;
|
|
6602
6709
|
}
|
|
6710
|
+
if (childState.noFinalCompletionFallbackTimer) {
|
|
6711
|
+
clearTimeout(childState.noFinalCompletionFallbackTimer);
|
|
6712
|
+
childState.noFinalCompletionFallbackTimer = void 0;
|
|
6713
|
+
}
|
|
6603
6714
|
}
|
|
6604
6715
|
}
|
|
6605
6716
|
startTaskRowReconciler(intervalMs) {
|
|
@@ -6733,6 +6844,14 @@ function toThreadCompletion(completion, childThreadId) {
|
|
|
6733
6844
|
result: completion.result
|
|
6734
6845
|
};
|
|
6735
6846
|
}
|
|
6847
|
+
function shouldWaitForTranscriptCompletion(completion, codexHome) {
|
|
6848
|
+
return Boolean(codexHome && completion.status === "succeeded" && completion.statusLabel === "completed_without_final_message");
|
|
6849
|
+
}
|
|
6850
|
+
function noFinalCompletionFallbackDelayMs(delays) {
|
|
6851
|
+
const first = delays[0] ?? 0;
|
|
6852
|
+
const second = delays[1] ?? 0;
|
|
6853
|
+
return Math.max(1, first + second);
|
|
6854
|
+
}
|
|
6736
6855
|
function readSpawnParentThreadId(thread) {
|
|
6737
6856
|
const source = isJsonObject(thread?.source) ? thread.source : void 0;
|
|
6738
6857
|
const subAgent = isJsonObject(source?.subAgent) ? source.subAgent : void 0;
|
|
@@ -6841,15 +6960,17 @@ async function readTranscriptCompletion(transcriptPath, childThreadId) {
|
|
|
6841
6960
|
}
|
|
6842
6961
|
if (readString$2(entry, "type") !== "event_msg") continue;
|
|
6843
6962
|
const payloadType = readString$2(payload, "type");
|
|
6844
|
-
if (payloadType === "task_complete")
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6963
|
+
if (payloadType === "task_complete") {
|
|
6964
|
+
const result = readString$2(payload, "last_agent_message")?.trim() || readString$2(payload, "message")?.trim();
|
|
6965
|
+
completion = {
|
|
6966
|
+
childThreadId,
|
|
6967
|
+
parentThreadId,
|
|
6968
|
+
status: "succeeded",
|
|
6969
|
+
statusLabel: result ? "task_complete" : "completed_without_final_message",
|
|
6970
|
+
result: result ?? "Codex native subagent completed without a final assistant message.",
|
|
6971
|
+
completedAt: secondsToMillis(readNumber(payload, "completed_at")) ?? readTimestamp(entry)
|
|
6972
|
+
};
|
|
6973
|
+
} else if (payloadType === "task_failed") {
|
|
6853
6974
|
const result = readString$2(payload, "last_agent_message")?.trim() || readString$2(payload, "error")?.trim() || readString$2(payload, "message")?.trim() || "Codex native subagent failed.";
|
|
6854
6975
|
completion = {
|
|
6855
6976
|
childThreadId,
|
|
@@ -6904,7 +7025,6 @@ const CODEX_APP_SERVER_BYTE_UNITS = {
|
|
|
6904
7025
|
tb: 1024 * 1024 * 1024 * 1024,
|
|
6905
7026
|
tib: 1024 * 1024 * 1024 * 1024
|
|
6906
7027
|
};
|
|
6907
|
-
const codexSessionRecordCache = /* @__PURE__ */ new Map();
|
|
6908
7028
|
function parseCodexAppServerByteLimit(value) {
|
|
6909
7029
|
if (typeof value === "number" && Number.isFinite(value) && value > 0) return Math.floor(value);
|
|
6910
7030
|
if (typeof value !== "string") return;
|
|
@@ -6959,45 +7079,22 @@ async function listCodexAppServerRolloutFilesForThread(agentDir, threadId, codex
|
|
|
6959
7079
|
return files;
|
|
6960
7080
|
}
|
|
6961
7081
|
async function readCodexSessionRecordForSessionFile(sessionFile) {
|
|
6962
|
-
const
|
|
7082
|
+
const storePath = path.join(path.dirname(sessionFile), "sessions.json");
|
|
6963
7083
|
const resolvedSessionFile = path.resolve(sessionFile);
|
|
6964
|
-
let stat;
|
|
6965
|
-
try {
|
|
6966
|
-
stat = await fs.stat(sessionsFile);
|
|
6967
|
-
} catch {
|
|
6968
|
-
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6969
|
-
return;
|
|
6970
|
-
}
|
|
6971
|
-
const cached = codexSessionRecordCache.get(resolvedSessionFile);
|
|
6972
|
-
if (cached?.sessionsFile === sessionsFile && cached.mtimeMs === stat.mtimeMs && cached.size === stat.size) return cached.record;
|
|
6973
7084
|
let store;
|
|
6974
7085
|
try {
|
|
6975
|
-
store =
|
|
7086
|
+
store = loadSessionStore(storePath, { skipCache: true });
|
|
6976
7087
|
} catch {
|
|
6977
|
-
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6978
|
-
return;
|
|
6979
|
-
}
|
|
6980
|
-
if (!isJsonObject(store)) {
|
|
6981
|
-
codexSessionRecordCache.delete(resolvedSessionFile);
|
|
6982
7088
|
return;
|
|
6983
7089
|
}
|
|
6984
|
-
let found;
|
|
6985
7090
|
for (const [sessionKey, record] of Object.entries(store)) {
|
|
6986
7091
|
if (!isJsonObject(record) || typeof record.sessionFile !== "string") continue;
|
|
6987
7092
|
if (path.resolve(record.sessionFile) !== resolvedSessionFile) continue;
|
|
6988
|
-
|
|
7093
|
+
return {
|
|
6989
7094
|
sessionKey,
|
|
6990
7095
|
...record
|
|
6991
7096
|
};
|
|
6992
|
-
break;
|
|
6993
7097
|
}
|
|
6994
|
-
codexSessionRecordCache.set(resolvedSessionFile, {
|
|
6995
|
-
sessionsFile,
|
|
6996
|
-
mtimeMs: stat.mtimeMs,
|
|
6997
|
-
size: stat.size,
|
|
6998
|
-
record: found
|
|
6999
|
-
});
|
|
7000
|
-
return found;
|
|
7001
7098
|
}
|
|
7002
7099
|
async function readCodexAppServerRolloutTokenSnapshot(file) {
|
|
7003
7100
|
let handle;
|
|
@@ -8343,6 +8440,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8343
8440
|
let timedOut = false;
|
|
8344
8441
|
let turnCompletionIdleTimedOut = false;
|
|
8345
8442
|
let turnWatchTimeoutKind;
|
|
8443
|
+
let turnWatchTimeoutIdleMs;
|
|
8444
|
+
let turnWatchTimeoutMs;
|
|
8445
|
+
let turnWatchTimeoutLastActivityReason;
|
|
8446
|
+
let turnWatchTimeoutDetails;
|
|
8346
8447
|
let turnCompletionIdleTimeoutMessage;
|
|
8347
8448
|
let clientClosedPromptError;
|
|
8348
8449
|
let clientClosedAbort = false;
|
|
@@ -8403,6 +8504,10 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
8403
8504
|
timedOut = true;
|
|
8404
8505
|
turnCompletionIdleTimedOut = true;
|
|
8405
8506
|
turnWatchTimeoutKind = timeout.kind;
|
|
8507
|
+
turnWatchTimeoutIdleMs = timeout.idleMs;
|
|
8508
|
+
turnWatchTimeoutMs = timeout.timeoutMs;
|
|
8509
|
+
turnWatchTimeoutLastActivityReason = timeout.lastActivityReason;
|
|
8510
|
+
turnWatchTimeoutDetails = timeout.details;
|
|
8406
8511
|
turnCompletionIdleTimeoutMessage = "codex app-server turn idle timed out waiting for turn/completed";
|
|
8407
8512
|
},
|
|
8408
8513
|
onMarkTimedOut: () => projectorRef.current?.markTimedOut(),
|
|
@@ -9197,7 +9302,9 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
9197
9302
|
await notificationQueue;
|
|
9198
9303
|
const result = activeProjector.buildResult(toolBridge.telemetry, { yieldDetected });
|
|
9199
9304
|
const finalAborted = result.aborted || runAbortController.signal.aborted && !clientClosedAbort;
|
|
9200
|
-
|
|
9305
|
+
const canUseCompletedAssistantTextAfterClientClose = activeProjector.hasCompletedTerminalAssistantText() && activeAppServerTurnRequests === 0 && activeTurnItemIds.size === 0 && pendingOpenClawDynamicToolCompletionIds.size === 0;
|
|
9306
|
+
const clientClosedPromptErrorForFinal = clientClosedPromptError && canUseCompletedAssistantTextAfterClientClose ? void 0 : clientClosedPromptError;
|
|
9307
|
+
let finalPromptError = clientClosedPromptErrorForFinal ?? (turnCompletionIdleTimedOut ? turnCompletionIdleTimeoutMessage : timedOut ? "codex app-server attempt timed out" : result.promptError);
|
|
9201
9308
|
const finalPromptErrorMessage = typeof finalPromptError === "string" ? finalPromptError : finalPromptError ? formatErrorMessage(finalPromptError) : void 0;
|
|
9202
9309
|
if (isInvalidCodexImagePayloadError(finalPromptErrorMessage)) await clearCodexBindingAfterInvalidImagePayload(activeSessionFile, {
|
|
9203
9310
|
phase: "turn_completed",
|
|
@@ -9226,13 +9333,20 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
9226
9333
|
signal: runAbortController.signal
|
|
9227
9334
|
});
|
|
9228
9335
|
if (refreshedUsageLimitPromptError) finalPromptError = refreshedUsageLimitPromptError;
|
|
9229
|
-
const finalPromptErrorSource = timedOut ||
|
|
9230
|
-
const codexAppServerFailureKind =
|
|
9336
|
+
const finalPromptErrorSource = timedOut || clientClosedPromptErrorForFinal ? "prompt" : result.promptErrorSource;
|
|
9337
|
+
const codexAppServerFailureKind = clientClosedPromptErrorForFinal ? "client_closed_before_turn_completed" : turnCompletionIdleTimedOut ? "turn_completion_idle_timeout" : void 0;
|
|
9231
9338
|
const codexAppServerReplayBlockedReason = codexAppServerFailureKind ? resolveCodexAppServerReplayBlockedReason(result) : void 0;
|
|
9232
9339
|
const promptTimeoutOutcome = buildCodexAppServerPromptTimeoutOutcome({
|
|
9233
9340
|
result,
|
|
9234
|
-
turnCompletionIdleTimedOut
|
|
9341
|
+
turnCompletionIdleTimedOut,
|
|
9342
|
+
turnWatchTimeoutKind
|
|
9235
9343
|
});
|
|
9344
|
+
const codexAppServerFailureDiagnostics = codexAppServerFailureKind === "turn_completion_idle_timeout" && turnWatchTimeoutKind === "completion" ? buildCodexAppServerTimeoutDiagnostics({
|
|
9345
|
+
idleMs: turnWatchTimeoutIdleMs,
|
|
9346
|
+
timeoutMs: turnWatchTimeoutMs,
|
|
9347
|
+
lastActivityReason: turnWatchTimeoutLastActivityReason,
|
|
9348
|
+
details: turnWatchTimeoutDetails
|
|
9349
|
+
}) : void 0;
|
|
9236
9350
|
const modelCallFailureKind = classifyCodexModelCallFailureKind({
|
|
9237
9351
|
error: finalPromptError,
|
|
9238
9352
|
timedOut,
|
|
@@ -9363,7 +9477,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
|
|
|
9363
9477
|
threadId: thread.threadId,
|
|
9364
9478
|
turnId: activeTurnId,
|
|
9365
9479
|
replaySafe: codexAppServerReplayBlockedReason === void 0,
|
|
9366
|
-
...codexAppServerReplayBlockedReason ? { replayBlockedReason: codexAppServerReplayBlockedReason } : {}
|
|
9480
|
+
...codexAppServerReplayBlockedReason ? { replayBlockedReason: codexAppServerReplayBlockedReason } : {},
|
|
9481
|
+
...codexAppServerFailureDiagnostics ? { diagnostics: codexAppServerFailureDiagnostics } : {}
|
|
9367
9482
|
} } : {},
|
|
9368
9483
|
...promptTimeoutOutcome ? { promptTimeoutOutcome } : {},
|
|
9369
9484
|
systemPromptReport
|
|
@@ -9472,6 +9587,36 @@ function waitForCodexNotificationDispatchTurn() {
|
|
|
9472
9587
|
setImmediate(resolve);
|
|
9473
9588
|
});
|
|
9474
9589
|
}
|
|
9590
|
+
function buildCodexAppServerTimeoutDiagnostics(params) {
|
|
9591
|
+
const readString = (key) => {
|
|
9592
|
+
const value = params.details?.[key];
|
|
9593
|
+
return typeof value === "string" && value.trim() ? value : void 0;
|
|
9594
|
+
};
|
|
9595
|
+
const readNumber = (key) => {
|
|
9596
|
+
const value = params.details?.[key];
|
|
9597
|
+
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
9598
|
+
};
|
|
9599
|
+
const readBoolean = (key) => {
|
|
9600
|
+
const value = params.details?.[key];
|
|
9601
|
+
return typeof value === "boolean" ? value : void 0;
|
|
9602
|
+
};
|
|
9603
|
+
return {
|
|
9604
|
+
...params.idleMs !== void 0 ? { idleMs: params.idleMs } : {},
|
|
9605
|
+
...params.timeoutMs !== void 0 ? { timeoutMs: params.timeoutMs } : {},
|
|
9606
|
+
...params.lastActivityReason ? { lastActivityReason: params.lastActivityReason } : {},
|
|
9607
|
+
...readString("lastNotificationMethod") ? { lastNotificationMethod: readString("lastNotificationMethod") } : {},
|
|
9608
|
+
...readString("lastNotificationItemId") ? { lastNotificationItemId: readString("lastNotificationItemId") } : {},
|
|
9609
|
+
...readString("lastNotificationItemType") ? { lastNotificationItemType: readString("lastNotificationItemType") } : {},
|
|
9610
|
+
...readString("lastNotificationItemRole") ? { lastNotificationItemRole: readString("lastNotificationItemRole") } : {},
|
|
9611
|
+
...readString("lastAssistantTextPreview") ? { lastAssistantTextPreview: readString("lastAssistantTextPreview") } : {},
|
|
9612
|
+
...readNumber("activeAppServerTurnRequests") !== void 0 ? { activeAppServerTurnRequests: readNumber("activeAppServerTurnRequests") } : {},
|
|
9613
|
+
...readNumber("activeTurnItemCount") !== void 0 ? { activeTurnItemCount: readNumber("activeTurnItemCount") } : {},
|
|
9614
|
+
...readBoolean("terminalTurnNotificationQueued") !== void 0 ? { terminalTurnNotificationQueued: readBoolean("terminalTurnNotificationQueued") } : {},
|
|
9615
|
+
...readBoolean("completionIdleWatchArmed") !== void 0 ? { completionIdleWatchArmed: readBoolean("completionIdleWatchArmed") } : {},
|
|
9616
|
+
...readBoolean("assistantCompletionIdleWatchArmed") !== void 0 ? { assistantCompletionIdleWatchArmed: readBoolean("assistantCompletionIdleWatchArmed") } : {},
|
|
9617
|
+
...readBoolean("terminalIdleWatchArmed") !== void 0 ? { terminalIdleWatchArmed: readBoolean("terminalIdleWatchArmed") } : {}
|
|
9618
|
+
};
|
|
9619
|
+
}
|
|
9475
9620
|
function handleApprovalRequest(params) {
|
|
9476
9621
|
return handleCodexAppServerApprovalRequest({
|
|
9477
9622
|
method: params.method,
|
|
@@ -6,7 +6,7 @@ import { a as readCodexAppServerBinding } from "./session-binding-BgTv_YGm.js";
|
|
|
6
6
|
import { h as formatCodexUsageLimitErrorMessage, i as readCodexNotificationTurnId, r as readCodexNotificationThreadId } from "./notification-correlation-o8quHmTK.js";
|
|
7
7
|
import { a as getLeasedSharedCodexAppServerClient, o as releaseLeasedSharedCodexAppServerClient, u as refreshCodexAppServerAuthTokens } from "./shared-client-xytpSKD0.js";
|
|
8
8
|
import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-C-Yv9uwY.js";
|
|
9
|
-
import { d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, h as handleCodexAppServerApprovalRequest, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, t as CODEX_NATIVE_HOOK_RELAY_EVENTS, u as createCodexDynamicToolBridge } from "./native-hook-relay-
|
|
9
|
+
import { d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, h as handleCodexAppServerApprovalRequest, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, t as CODEX_NATIVE_HOOK_RELAY_EVENTS, u as createCodexDynamicToolBridge } from "./native-hook-relay-DHwz_ICg.js";
|
|
10
10
|
import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-C7qmZ0Jh.js";
|
|
11
11
|
import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
12
12
|
//#region extensions/codex/src/app-server/side-question.ts
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/codex",
|
|
3
|
-
"version": "2026.6.5-beta.
|
|
3
|
+
"version": "2026.6.5-beta.3",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "@openclaw/codex",
|
|
9
|
-
"version": "2026.6.5-beta.
|
|
9
|
+
"version": "2026.6.5-beta.3",
|
|
10
10
|
"dependencies": {
|
|
11
11
|
"@openai/codex": "0.135.0",
|
|
12
12
|
"typebox": "1.1.39",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/codex",
|
|
3
|
-
"version": "2026.6.5-beta.
|
|
3
|
+
"version": "2026.6.5-beta.3",
|
|
4
4
|
"description": "OpenClaw Codex app-server harness and model provider plugin with a Codex-managed GPT catalog.",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -26,10 +26,10 @@
|
|
|
26
26
|
"minHostVersion": ">=2026.5.1-beta.1"
|
|
27
27
|
},
|
|
28
28
|
"compat": {
|
|
29
|
-
"pluginApi": ">=2026.6.5-beta.
|
|
29
|
+
"pluginApi": ">=2026.6.5-beta.3"
|
|
30
30
|
},
|
|
31
31
|
"build": {
|
|
32
|
-
"openclawVersion": "2026.6.5-beta.
|
|
32
|
+
"openclawVersion": "2026.6.5-beta.3"
|
|
33
33
|
},
|
|
34
34
|
"release": {
|
|
35
35
|
"publishToClawHub": true,
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"README.md"
|
|
48
48
|
],
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"openclaw": ">=2026.6.5-beta.
|
|
50
|
+
"openclaw": ">=2026.6.5-beta.3"
|
|
51
51
|
},
|
|
52
52
|
"peerDependenciesMeta": {
|
|
53
53
|
"openclaw": {
|