@openclaw/codex 2026.5.24-beta.2 → 2026.5.26-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{client-1sSy4p3z.js → client-BVK_jmHW.js} +10 -3
- package/dist/{client-factory-Bk6i4FnW.js → client-factory-CaOpX89B.js} +1 -1
- package/dist/{command-handlers-CcTABuem.js → command-handlers-D4C2y46B.js} +10 -23
- package/dist/compact-CRI0BEc_.js +155 -0
- package/dist/{computer-use-Hdq1WgTA.js → computer-use-CDDlIBhY.js} +2 -2
- package/dist/{config-DDMrwfJl.js → config-0-UN67Qg.js} +8 -4
- package/dist/{node-cli-sessions-9CAqnIaA.js → conversation-binding-BnnjOmgs.js} +426 -434
- package/dist/{dynamic-tools-Bq717oJR.js → dynamic-tools-BG9ICyU4.js} +20 -11
- package/dist/harness.js +5 -5
- package/dist/index.js +452 -18
- package/dist/media-understanding-provider.js +8 -6
- package/dist/{models-DtGLkqMP.js → models-ASKu9eOY.js} +4 -4
- package/dist/{notification-correlation-qKY_sgga.js → notification-correlation-YINts3PA.js} +26 -11
- package/dist/{protocol-validators-_gKDcd0x.js → protocol-validators-CSuFMLvY.js} +138 -29
- package/dist/provider.js +3 -3
- package/dist/{request-D93E78SA.js → request-DmBkYLPy.js} +3 -3
- package/dist/{run-attempt-CT1N__qp.js → run-attempt-CFBsGx1T.js} +488 -280
- package/dist/{session-binding-Bw_mfIW2.js → session-binding-UFjjws4k.js} +1 -1
- package/dist/{shared-client-CFCUGEVs.js → shared-client-Fou5nAyt.js} +66 -11
- package/dist/{side-question-CYFMTA1O.js → side-question-fq_T2d_x.js} +17 -12
- package/dist/test-api.js +3 -3
- package/dist/{thread-lifecycle-DGoaguJh.js → thread-lifecycle-BapIT9Qs.js} +113 -28
- package/dist/{vision-tools-DOnxzH2y.js → vision-tools-B30YCKRK.js} +16 -4
- package/npm-shrinkwrap.json +222 -305
- package/package.json +8 -8
- package/dist/compact-DnTgL6UT.js +0 -475
- package/dist/protocol-oeJQu4rs.js +0 -9
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openclaw/codex",
|
|
3
|
-
"version": "2026.5.
|
|
3
|
+
"version": "2026.5.26-beta.1",
|
|
4
4
|
"description": "OpenClaw Codex harness and model provider plugin",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -8,10 +8,10 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"dependencies": {
|
|
11
|
-
"@earendil-works/pi-coding-agent": "0.75.
|
|
12
|
-
"@openai/codex": "0.
|
|
13
|
-
"
|
|
14
|
-
"ws": "8.
|
|
11
|
+
"@earendil-works/pi-coding-agent": "0.75.5",
|
|
12
|
+
"@openai/codex": "0.133.0",
|
|
13
|
+
"typebox": "1.1.38",
|
|
14
|
+
"ws": "8.21.0",
|
|
15
15
|
"zod": "4.4.3"
|
|
16
16
|
},
|
|
17
17
|
"devDependencies": {
|
|
@@ -27,10 +27,10 @@
|
|
|
27
27
|
"minHostVersion": ">=2026.5.1-beta.1"
|
|
28
28
|
},
|
|
29
29
|
"compat": {
|
|
30
|
-
"pluginApi": ">=2026.5.
|
|
30
|
+
"pluginApi": ">=2026.5.26-beta.1"
|
|
31
31
|
},
|
|
32
32
|
"build": {
|
|
33
|
-
"openclawVersion": "2026.5.
|
|
33
|
+
"openclawVersion": "2026.5.26-beta.1"
|
|
34
34
|
},
|
|
35
35
|
"release": {
|
|
36
36
|
"publishToClawHub": true,
|
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
"npm-shrinkwrap.json"
|
|
48
48
|
],
|
|
49
49
|
"peerDependencies": {
|
|
50
|
-
"openclaw": ">=2026.5.
|
|
50
|
+
"openclaw": ">=2026.5.26-beta.1"
|
|
51
51
|
},
|
|
52
52
|
"peerDependenciesMeta": {
|
|
53
53
|
"openclaw": {
|
package/dist/compact-DnTgL6UT.js
DELETED
|
@@ -1,475 +0,0 @@
|
|
|
1
|
-
import { l as resolveCodexAppServerRuntimeOptions } from "./config-DDMrwfJl.js";
|
|
2
|
-
import { t as isJsonObject } from "./protocol-oeJQu4rs.js";
|
|
3
|
-
import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-Bw_mfIW2.js";
|
|
4
|
-
import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-CTnEWuor.js";
|
|
5
|
-
import { t as defaultCodexAppServerClientFactory } from "./client-factory-Bk6i4FnW.js";
|
|
6
|
-
import { compactContextEngineWithSafetyTimeout, embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine, resolveCompactionTimeoutMs, resolveContextEngineOwnerPluginId, runHarnessContextEngineMaintenance } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
7
|
-
//#region extensions/codex/src/app-server/compact.ts
|
|
8
|
-
const DEFAULT_CODEX_COMPACTION_WAIT_TIMEOUT_MS = 300 * 1e3;
|
|
9
|
-
const CODEX_COMPACTION_TOKEN_USAGE_GRACE_MS = 250;
|
|
10
|
-
const MAX_CODEX_NATIVE_COMPACTION_ATTEMPTS = 2;
|
|
11
|
-
const warnedIgnoredCompactionOverrides = /* @__PURE__ */ new Set();
|
|
12
|
-
var CodexNativeCompactionTimeoutError = class extends Error {
|
|
13
|
-
constructor(threadId) {
|
|
14
|
-
super(`timed out waiting for codex app-server compaction for ${threadId}`);
|
|
15
|
-
this.threadId = threadId;
|
|
16
|
-
}
|
|
17
|
-
};
|
|
18
|
-
async function maybeCompactCodexAppServerSession(params, options = {}) {
|
|
19
|
-
const activeContextEngine = isActiveHarnessContextEngine(params.contextEngine) ? params.contextEngine : void 0;
|
|
20
|
-
if (activeContextEngine?.info.ownsCompaction) return await compactOwningContextEngine(params, activeContextEngine);
|
|
21
|
-
warnIfIgnoringOpenClawCompactionOverrides(params);
|
|
22
|
-
const nativeResult = await compactCodexNativeThread(params, options);
|
|
23
|
-
if (activeContextEngine && nativeResult?.ok && nativeResult.compacted) try {
|
|
24
|
-
await runHarnessContextEngineMaintenance({
|
|
25
|
-
contextEngine: activeContextEngine,
|
|
26
|
-
sessionId: params.sessionId,
|
|
27
|
-
sessionKey: params.sessionKey,
|
|
28
|
-
sessionFile: params.sessionFile,
|
|
29
|
-
reason: "compaction",
|
|
30
|
-
runtimeContext: params.contextEngineRuntimeContext,
|
|
31
|
-
config: params.config
|
|
32
|
-
});
|
|
33
|
-
} catch (error) {
|
|
34
|
-
embeddedAgentLog.warn("context engine compaction maintenance failed after Codex compaction", {
|
|
35
|
-
sessionId: params.sessionId,
|
|
36
|
-
engineId: activeContextEngine.info.id,
|
|
37
|
-
error: formatErrorMessage(error)
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
return nativeResult;
|
|
41
|
-
}
|
|
42
|
-
async function compactOwningContextEngine(params, contextEngine) {
|
|
43
|
-
const compactionTarget = params.trigger === "manual" ? "threshold" : "budget";
|
|
44
|
-
const force = params.force === true || params.trigger === "manual";
|
|
45
|
-
embeddedAgentLog.info("starting context-engine-owned Codex app-server compaction", {
|
|
46
|
-
sessionId: params.sessionId,
|
|
47
|
-
sessionKey: params.sessionKey,
|
|
48
|
-
engineId: contextEngine.info.id,
|
|
49
|
-
tokenBudget: params.contextTokenBudget,
|
|
50
|
-
currentTokenCount: params.currentTokenCount,
|
|
51
|
-
trigger: params.trigger,
|
|
52
|
-
compactionTarget,
|
|
53
|
-
force
|
|
54
|
-
});
|
|
55
|
-
let result;
|
|
56
|
-
try {
|
|
57
|
-
result = await compactContextEngineWithSafetyTimeout(contextEngine, {
|
|
58
|
-
sessionId: params.sessionId,
|
|
59
|
-
sessionKey: params.sessionKey,
|
|
60
|
-
sessionFile: params.sessionFile,
|
|
61
|
-
tokenBudget: params.contextTokenBudget,
|
|
62
|
-
currentTokenCount: params.currentTokenCount,
|
|
63
|
-
compactionTarget,
|
|
64
|
-
customInstructions: params.customInstructions,
|
|
65
|
-
force,
|
|
66
|
-
runtimeContext: params.contextEngineRuntimeContext
|
|
67
|
-
}, resolveCompactionTimeoutMs(params.config), params.abortSignal);
|
|
68
|
-
} catch (error) {
|
|
69
|
-
embeddedAgentLog.warn("context-engine-owned Codex app-server compaction failed", {
|
|
70
|
-
sessionId: params.sessionId,
|
|
71
|
-
sessionKey: params.sessionKey,
|
|
72
|
-
engineId: contextEngine.info.id,
|
|
73
|
-
error: formatErrorMessage(error)
|
|
74
|
-
});
|
|
75
|
-
return {
|
|
76
|
-
ok: false,
|
|
77
|
-
compacted: false,
|
|
78
|
-
reason: `context engine compaction failed: ${formatErrorMessage(error)}`
|
|
79
|
-
};
|
|
80
|
-
}
|
|
81
|
-
if (result.ok && result.compacted) {
|
|
82
|
-
const compactedSessionId = result.result?.sessionId ?? params.sessionId;
|
|
83
|
-
const compactedSessionFile = result.result?.sessionFile ?? params.sessionFile;
|
|
84
|
-
try {
|
|
85
|
-
await runHarnessContextEngineMaintenance({
|
|
86
|
-
contextEngine,
|
|
87
|
-
sessionId: compactedSessionId,
|
|
88
|
-
sessionKey: params.sessionKey,
|
|
89
|
-
sessionFile: compactedSessionFile,
|
|
90
|
-
reason: "compaction",
|
|
91
|
-
runtimeContext: params.contextEngineRuntimeContext,
|
|
92
|
-
config: params.config
|
|
93
|
-
});
|
|
94
|
-
} catch (error) {
|
|
95
|
-
embeddedAgentLog.warn("context engine compaction maintenance failed", {
|
|
96
|
-
sessionId: compactedSessionId,
|
|
97
|
-
engineId: contextEngine.info.id,
|
|
98
|
-
error: formatErrorMessage(error)
|
|
99
|
-
});
|
|
100
|
-
}
|
|
101
|
-
await clearCodexAppServerBinding(params.sessionFile, { config: params.config });
|
|
102
|
-
if (compactedSessionFile !== params.sessionFile) await clearCodexAppServerBinding(compactedSessionFile, { config: params.config });
|
|
103
|
-
}
|
|
104
|
-
embeddedAgentLog.info("completed context-engine-owned Codex app-server compaction", {
|
|
105
|
-
sessionId: params.sessionId,
|
|
106
|
-
sessionKey: params.sessionKey,
|
|
107
|
-
engineId: contextEngine.info.id,
|
|
108
|
-
ok: result.ok,
|
|
109
|
-
compacted: result.compacted,
|
|
110
|
-
reason: result.reason,
|
|
111
|
-
codexThreadBindingInvalidated: result.ok && result.compacted
|
|
112
|
-
});
|
|
113
|
-
return {
|
|
114
|
-
ok: result.ok,
|
|
115
|
-
compacted: result.compacted,
|
|
116
|
-
reason: result.reason,
|
|
117
|
-
result: result.result ? {
|
|
118
|
-
...result.result,
|
|
119
|
-
summary: result.result.summary ?? "",
|
|
120
|
-
firstKeptEntryId: result.result.firstKeptEntryId ?? "",
|
|
121
|
-
details: mergeContextEngineCompactionDetails(result.result.details, { codexThreadBindingInvalidated: result.ok && result.compacted })
|
|
122
|
-
} : result.ok && result.compacted ? {
|
|
123
|
-
summary: "",
|
|
124
|
-
firstKeptEntryId: "",
|
|
125
|
-
tokensBefore: params.currentTokenCount ?? 0,
|
|
126
|
-
details: { codexThreadBindingInvalidated: true }
|
|
127
|
-
} : void 0
|
|
128
|
-
};
|
|
129
|
-
}
|
|
130
|
-
function mergeContextEngineCompactionDetails(details, extra) {
|
|
131
|
-
if (details && typeof details === "object" && !Array.isArray(details)) return {
|
|
132
|
-
...details,
|
|
133
|
-
...extra
|
|
134
|
-
};
|
|
135
|
-
return extra;
|
|
136
|
-
}
|
|
137
|
-
function warnIfIgnoringOpenClawCompactionOverrides(params) {
|
|
138
|
-
const ignoredConfig = readIgnoredCompactionOverridePaths(params, isActiveHarnessContextEngine(params.contextEngine) ? params.contextEngine : void 0);
|
|
139
|
-
if (ignoredConfig.length === 0) return;
|
|
140
|
-
const warningKey = ignoredConfig.join("\0");
|
|
141
|
-
if (warnedIgnoredCompactionOverrides.has(warningKey)) return;
|
|
142
|
-
warnedIgnoredCompactionOverrides.add(warningKey);
|
|
143
|
-
embeddedAgentLog.warn("ignoring OpenClaw compaction overrides for Codex app-server compaction; Codex uses native server-side compaction", {
|
|
144
|
-
sessionId: params.sessionId,
|
|
145
|
-
sessionKey: params.sessionKey,
|
|
146
|
-
ignoredConfig
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
function readIgnoredCompactionOverridePaths(params, activeContextEngine) {
|
|
150
|
-
const ignored = /* @__PURE__ */ new Set();
|
|
151
|
-
const configuredContextEngine = readStringPath(params.config, [
|
|
152
|
-
"plugins",
|
|
153
|
-
"slots",
|
|
154
|
-
"contextEngine"
|
|
155
|
-
]);
|
|
156
|
-
const runtimeContextEnginePlugin = typeof params.contextEngineRuntimeContext?.contextEnginePluginId === "string" ? params.contextEngineRuntimeContext.contextEnginePluginId.trim() : "";
|
|
157
|
-
const activeContextEnginePlugin = resolveContextEngineOwnerPluginId(activeContextEngine);
|
|
158
|
-
for (const entry of readCompactionOverrideEntries(params)) {
|
|
159
|
-
const localProvider = typeof entry.record.provider === "string" ? entry.record.provider.trim() : "";
|
|
160
|
-
const inheritedProvider = !localProvider && typeof entry.inheritedRecord?.provider === "string" ? entry.inheritedRecord.provider.trim() : "";
|
|
161
|
-
const provider = localProvider || inheritedProvider;
|
|
162
|
-
const providerPath = localProvider ? `${entry.path}.compaction.provider` : inheritedProvider && entry.inheritedPath ? `${entry.inheritedPath}.compaction.provider` : void 0;
|
|
163
|
-
if (provider.toLowerCase() === "lossless-claw" && (activeContextEnginePlugin === "lossless-claw" || runtimeContextEnginePlugin.toLowerCase() === "lossless-claw" || configuredContextEngine?.toLowerCase() === "lossless-claw")) continue;
|
|
164
|
-
if (typeof entry.record.model === "string" && entry.record.model.trim()) ignored.add(`${entry.path}.compaction.model`);
|
|
165
|
-
if (providerPath) ignored.add(providerPath);
|
|
166
|
-
}
|
|
167
|
-
return [...ignored];
|
|
168
|
-
}
|
|
169
|
-
function readCompactionOverrideEntries(params) {
|
|
170
|
-
const entries = [];
|
|
171
|
-
const defaultCompaction = readRecord(readRecord(params.config?.agents)?.defaults)?.compaction;
|
|
172
|
-
const defaultRecord = readRecord(defaultCompaction);
|
|
173
|
-
if (defaultRecord) entries.push({
|
|
174
|
-
path: "agents.defaults",
|
|
175
|
-
record: defaultRecord
|
|
176
|
-
});
|
|
177
|
-
const agentId = readAgentIdFromSessionKey(params.sessionKey ?? params.sandboxSessionKey);
|
|
178
|
-
if (!agentId) return entries;
|
|
179
|
-
const agentCompaction = readRecord((Array.isArray(params.config?.agents?.list) ? params.config.agents.list : []).find((agent) => {
|
|
180
|
-
return (typeof agent?.id === "string" ? agent.id.trim().toLowerCase() : "") === agentId;
|
|
181
|
-
}))?.compaction;
|
|
182
|
-
const agentRecord = readRecord(agentCompaction);
|
|
183
|
-
if (agentRecord) entries.push({
|
|
184
|
-
path: `agents.list.${agentId}`,
|
|
185
|
-
record: agentRecord,
|
|
186
|
-
inheritedRecord: defaultRecord,
|
|
187
|
-
inheritedPath: "agents.defaults"
|
|
188
|
-
});
|
|
189
|
-
return entries;
|
|
190
|
-
}
|
|
191
|
-
function readAgentIdFromSessionKey(sessionKey) {
|
|
192
|
-
const parts = sessionKey?.trim().toLowerCase().split(":").filter(Boolean) ?? [];
|
|
193
|
-
if (parts.length < 3 || parts[0] !== "agent") return;
|
|
194
|
-
return parts[1]?.trim() || void 0;
|
|
195
|
-
}
|
|
196
|
-
function readRecord(value) {
|
|
197
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
198
|
-
}
|
|
199
|
-
function readStringPath(value, path) {
|
|
200
|
-
let current = value;
|
|
201
|
-
for (const segment of path) current = readRecord(current)?.[segment];
|
|
202
|
-
return typeof current === "string" && current.trim() ? current.trim() : void 0;
|
|
203
|
-
}
|
|
204
|
-
async function compactCodexNativeThread(params, options = {}) {
|
|
205
|
-
const nativeExecutionBlock = resolveCodexNativeExecutionBlock({
|
|
206
|
-
config: params.config,
|
|
207
|
-
sessionKey: params.sandboxSessionKey ?? params.sessionKey,
|
|
208
|
-
sessionId: params.sessionId,
|
|
209
|
-
surface: "native compaction"
|
|
210
|
-
});
|
|
211
|
-
if (nativeExecutionBlock) return {
|
|
212
|
-
ok: false,
|
|
213
|
-
compacted: false,
|
|
214
|
-
reason: nativeExecutionBlock
|
|
215
|
-
};
|
|
216
|
-
const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
|
|
217
|
-
const binding = await readCodexAppServerBinding(params.sessionFile, { config: params.config });
|
|
218
|
-
if (!binding?.threadId) return failedCodexThreadBindingCompactionResult(params, {
|
|
219
|
-
reason: "no codex app-server thread binding",
|
|
220
|
-
recovery: "missing_thread_binding"
|
|
221
|
-
});
|
|
222
|
-
const requestedAuthProfileId = params.authProfileId?.trim() || void 0;
|
|
223
|
-
if (requestedAuthProfileId && binding.authProfileId && binding.authProfileId !== requestedAuthProfileId) return {
|
|
224
|
-
ok: false,
|
|
225
|
-
compacted: false,
|
|
226
|
-
reason: "auth profile mismatch for session binding"
|
|
227
|
-
};
|
|
228
|
-
const clientFactory = options.clientFactory ?? defaultCodexAppServerClientFactory;
|
|
229
|
-
let completion;
|
|
230
|
-
let attempt = 0;
|
|
231
|
-
for (attempt = 1; attempt <= MAX_CODEX_NATIVE_COMPACTION_ATTEMPTS; attempt += 1) {
|
|
232
|
-
const client = await clientFactory(appServer.start, requestedAuthProfileId ?? binding.authProfileId, params.agentDir, params.config);
|
|
233
|
-
const waiter = createCodexNativeCompactionWaiter(client, binding.threadId);
|
|
234
|
-
try {
|
|
235
|
-
await client.request("thread/compact/start", { threadId: binding.threadId });
|
|
236
|
-
embeddedAgentLog.info("started codex app-server compaction", {
|
|
237
|
-
sessionId: params.sessionId,
|
|
238
|
-
threadId: binding.threadId,
|
|
239
|
-
attempt
|
|
240
|
-
});
|
|
241
|
-
waiter.startTimeout();
|
|
242
|
-
completion = await waiter.promise;
|
|
243
|
-
break;
|
|
244
|
-
} catch (error) {
|
|
245
|
-
waiter.cancel();
|
|
246
|
-
if (isCodexThreadNotFoundError(error)) {
|
|
247
|
-
await clearCodexAppServerBinding(params.sessionFile, { config: params.config });
|
|
248
|
-
return failedCodexThreadBindingCompactionResult(params, {
|
|
249
|
-
threadId: binding.threadId,
|
|
250
|
-
reason: formatCompactionError(error),
|
|
251
|
-
recovery: "stale_thread_binding"
|
|
252
|
-
});
|
|
253
|
-
}
|
|
254
|
-
if (isCodexNativeCompactionTimeoutError(error, binding.threadId) && attempt < MAX_CODEX_NATIVE_COMPACTION_ATTEMPTS) {
|
|
255
|
-
restartCodexAppServerAfterNativeCompactionTimeout(client, params, binding.threadId, attempt);
|
|
256
|
-
continue;
|
|
257
|
-
}
|
|
258
|
-
if (isCodexNativeCompactionTimeoutError(error, binding.threadId)) restartCodexAppServerAfterNativeCompactionTimeout(client, params, binding.threadId, attempt);
|
|
259
|
-
return {
|
|
260
|
-
ok: false,
|
|
261
|
-
compacted: false,
|
|
262
|
-
reason: formatCompactionError(error)
|
|
263
|
-
};
|
|
264
|
-
}
|
|
265
|
-
}
|
|
266
|
-
if (!completion) return {
|
|
267
|
-
ok: false,
|
|
268
|
-
compacted: false,
|
|
269
|
-
reason: `codex app-server compaction did not complete for ${binding.threadId}`
|
|
270
|
-
};
|
|
271
|
-
embeddedAgentLog.info("completed codex app-server compaction", {
|
|
272
|
-
sessionId: params.sessionId,
|
|
273
|
-
threadId: binding.threadId,
|
|
274
|
-
signal: completion.signal,
|
|
275
|
-
turnId: completion.turnId,
|
|
276
|
-
itemId: completion.itemId,
|
|
277
|
-
tokensAfter: completion.tokensAfter
|
|
278
|
-
});
|
|
279
|
-
const resultDetails = {
|
|
280
|
-
backend: "codex-app-server",
|
|
281
|
-
threadId: binding.threadId,
|
|
282
|
-
signal: completion.signal
|
|
283
|
-
};
|
|
284
|
-
if (completion.turnId) resultDetails.turnId = completion.turnId;
|
|
285
|
-
if (completion.itemId) resultDetails.itemId = completion.itemId;
|
|
286
|
-
if (completion.tokensAfter !== void 0) resultDetails.tokenUsageSource = "thread/tokenUsage/updated";
|
|
287
|
-
if (attempt > 1) {
|
|
288
|
-
resultDetails.compactionAttempts = attempt;
|
|
289
|
-
resultDetails.recoveredAfterAppServerRestart = true;
|
|
290
|
-
}
|
|
291
|
-
return {
|
|
292
|
-
ok: true,
|
|
293
|
-
compacted: true,
|
|
294
|
-
result: {
|
|
295
|
-
summary: "",
|
|
296
|
-
firstKeptEntryId: "",
|
|
297
|
-
tokensBefore: params.currentTokenCount ?? 0,
|
|
298
|
-
...completion.tokensAfter !== void 0 ? { tokensAfter: completion.tokensAfter } : {},
|
|
299
|
-
details: resultDetails
|
|
300
|
-
}
|
|
301
|
-
};
|
|
302
|
-
}
|
|
303
|
-
function failedCodexThreadBindingCompactionResult(params, recovery) {
|
|
304
|
-
embeddedAgentLog.warn("codex app-server compaction could not use thread binding", {
|
|
305
|
-
sessionId: params.sessionId,
|
|
306
|
-
sessionKey: params.sessionKey,
|
|
307
|
-
threadId: recovery.threadId,
|
|
308
|
-
reason: recovery.reason,
|
|
309
|
-
recovery: recovery.recovery
|
|
310
|
-
});
|
|
311
|
-
return {
|
|
312
|
-
ok: false,
|
|
313
|
-
compacted: false,
|
|
314
|
-
reason: recovery.reason,
|
|
315
|
-
failure: {
|
|
316
|
-
reason: recovery.recovery,
|
|
317
|
-
rawError: recovery.reason
|
|
318
|
-
}
|
|
319
|
-
};
|
|
320
|
-
}
|
|
321
|
-
function isCodexThreadNotFoundError(error) {
|
|
322
|
-
return formatCompactionError(error).toLowerCase().includes("thread not found");
|
|
323
|
-
}
|
|
324
|
-
function isCodexNativeCompactionTimeoutError(error, threadId) {
|
|
325
|
-
return error instanceof CodexNativeCompactionTimeoutError && error.threadId === threadId;
|
|
326
|
-
}
|
|
327
|
-
function restartCodexAppServerAfterNativeCompactionTimeout(client, params, threadId, attempt) {
|
|
328
|
-
embeddedAgentLog.warn("codex app-server compaction timed out; restarting app-server", {
|
|
329
|
-
sessionId: params.sessionId,
|
|
330
|
-
sessionKey: params.sessionKey,
|
|
331
|
-
threadId,
|
|
332
|
-
attempt,
|
|
333
|
-
maxAttempts: MAX_CODEX_NATIVE_COMPACTION_ATTEMPTS
|
|
334
|
-
});
|
|
335
|
-
client.close();
|
|
336
|
-
}
|
|
337
|
-
function createCodexNativeCompactionWaiter(client, threadId) {
|
|
338
|
-
let settled = false;
|
|
339
|
-
let removeHandler = () => {};
|
|
340
|
-
let timeout;
|
|
341
|
-
let tokenUsageGraceTimeout;
|
|
342
|
-
let failWaiter = () => {};
|
|
343
|
-
return {
|
|
344
|
-
promise: new Promise((resolve, reject) => {
|
|
345
|
-
const cleanup = () => {
|
|
346
|
-
removeHandler();
|
|
347
|
-
if (timeout) clearTimeout(timeout);
|
|
348
|
-
if (tokenUsageGraceTimeout) clearTimeout(tokenUsageGraceTimeout);
|
|
349
|
-
};
|
|
350
|
-
const complete = (completion) => {
|
|
351
|
-
if (settled) return;
|
|
352
|
-
settled = true;
|
|
353
|
-
cleanup();
|
|
354
|
-
resolve(completion);
|
|
355
|
-
};
|
|
356
|
-
const fail = (error) => {
|
|
357
|
-
if (settled) return;
|
|
358
|
-
settled = true;
|
|
359
|
-
cleanup();
|
|
360
|
-
reject(error);
|
|
361
|
-
};
|
|
362
|
-
let latestTokensAfter;
|
|
363
|
-
const completionWithLatestTokenUsage = (completion) => latestTokensAfter === void 0 ? completion : {
|
|
364
|
-
...completion,
|
|
365
|
-
tokensAfter: latestTokensAfter
|
|
366
|
-
};
|
|
367
|
-
const completeAfterTokenUsageGrace = (completion) => {
|
|
368
|
-
if (settled || tokenUsageGraceTimeout) return;
|
|
369
|
-
if (timeout) {
|
|
370
|
-
clearTimeout(timeout);
|
|
371
|
-
timeout = void 0;
|
|
372
|
-
}
|
|
373
|
-
tokenUsageGraceTimeout = setTimeout(() => complete(completionWithLatestTokenUsage(observedCompletion ?? completion)), CODEX_COMPACTION_TOKEN_USAGE_GRACE_MS);
|
|
374
|
-
tokenUsageGraceTimeout.unref?.();
|
|
375
|
-
};
|
|
376
|
-
failWaiter = fail;
|
|
377
|
-
let observedCompletion;
|
|
378
|
-
const handler = (notification) => {
|
|
379
|
-
const tokensAfter = readNativeCompactionTokenUsage(notification, threadId);
|
|
380
|
-
if (tokensAfter !== void 0) {
|
|
381
|
-
latestTokensAfter = tokensAfter;
|
|
382
|
-
if (observedCompletion) {
|
|
383
|
-
complete(completionWithLatestTokenUsage(observedCompletion));
|
|
384
|
-
return;
|
|
385
|
-
}
|
|
386
|
-
}
|
|
387
|
-
const completion = readNativeCompactionCompletion(notification, threadId);
|
|
388
|
-
if (completion) {
|
|
389
|
-
observedCompletion = completionWithLatestTokenUsage({
|
|
390
|
-
...observedCompletion,
|
|
391
|
-
...completion
|
|
392
|
-
});
|
|
393
|
-
if (latestTokensAfter !== void 0) {
|
|
394
|
-
complete(observedCompletion);
|
|
395
|
-
return;
|
|
396
|
-
}
|
|
397
|
-
completeAfterTokenUsageGrace(observedCompletion);
|
|
398
|
-
}
|
|
399
|
-
};
|
|
400
|
-
removeHandler = client.addNotificationHandler(handler);
|
|
401
|
-
}),
|
|
402
|
-
startTimeout() {
|
|
403
|
-
if (settled || timeout) return;
|
|
404
|
-
timeout = setTimeout(() => {
|
|
405
|
-
failWaiter(new CodexNativeCompactionTimeoutError(threadId));
|
|
406
|
-
}, resolveCompactionWaitTimeoutMs());
|
|
407
|
-
timeout.unref?.();
|
|
408
|
-
},
|
|
409
|
-
cancel() {
|
|
410
|
-
if (settled) return;
|
|
411
|
-
settled = true;
|
|
412
|
-
removeHandler();
|
|
413
|
-
if (timeout) clearTimeout(timeout);
|
|
414
|
-
}
|
|
415
|
-
};
|
|
416
|
-
}
|
|
417
|
-
function readNativeCompactionTokenUsage(notification, threadId) {
|
|
418
|
-
const params = notification.params;
|
|
419
|
-
if (!isJsonObject(params) || readString(params, "threadId", "thread_id") !== threadId) return;
|
|
420
|
-
if (notification.method !== "thread/tokenUsage/updated") return;
|
|
421
|
-
return readCodexTotalTokens(readCodexCurrentTokenUsage(isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0) ?? readCodexCurrentTokenUsage(params));
|
|
422
|
-
}
|
|
423
|
-
function readCodexCurrentTokenUsage(value) {
|
|
424
|
-
if (!value) return;
|
|
425
|
-
for (const key of [
|
|
426
|
-
"last",
|
|
427
|
-
"current",
|
|
428
|
-
"lastCall",
|
|
429
|
-
"lastCallUsage",
|
|
430
|
-
"lastTokenUsage",
|
|
431
|
-
"last_token_usage"
|
|
432
|
-
]) {
|
|
433
|
-
const usage = value[key];
|
|
434
|
-
if (isJsonObject(usage)) return usage;
|
|
435
|
-
}
|
|
436
|
-
}
|
|
437
|
-
function readCodexTotalTokens(value) {
|
|
438
|
-
const totalTokens = value?.total_tokens ?? value?.totalTokens ?? value?.total;
|
|
439
|
-
return typeof totalTokens === "number" && Number.isFinite(totalTokens) && totalTokens > 0 ? Math.floor(totalTokens) : void 0;
|
|
440
|
-
}
|
|
441
|
-
function readNativeCompactionCompletion(notification, threadId) {
|
|
442
|
-
const params = notification.params;
|
|
443
|
-
if (!isJsonObject(params) || readString(params, "threadId", "thread_id") !== threadId) return;
|
|
444
|
-
if (notification.method === "thread/compacted") return {
|
|
445
|
-
signal: "thread/compacted",
|
|
446
|
-
turnId: readString(params, "turnId", "turn_id")
|
|
447
|
-
};
|
|
448
|
-
if (notification.method !== "item/completed") return;
|
|
449
|
-
const item = isJsonObject(params.item) ? params.item : void 0;
|
|
450
|
-
if (readString(item, "type") !== "contextCompaction") return;
|
|
451
|
-
return {
|
|
452
|
-
signal: "item/completed",
|
|
453
|
-
turnId: readString(params, "turnId", "turn_id"),
|
|
454
|
-
itemId: readString(item, "id") ?? readString(params, "itemId", "item_id", "id")
|
|
455
|
-
};
|
|
456
|
-
}
|
|
457
|
-
function resolveCompactionWaitTimeoutMs() {
|
|
458
|
-
const raw = process.env.OPENCLAW_CODEX_COMPACTION_WAIT_TIMEOUT_MS?.trim();
|
|
459
|
-
const parsed = raw ? Number.parseInt(raw, 10) : NaN;
|
|
460
|
-
if (Number.isFinite(parsed) && parsed > 0) return parsed;
|
|
461
|
-
return DEFAULT_CODEX_COMPACTION_WAIT_TIMEOUT_MS;
|
|
462
|
-
}
|
|
463
|
-
function readString(params, ...keys) {
|
|
464
|
-
if (!params) return;
|
|
465
|
-
for (const key of keys) {
|
|
466
|
-
const value = params[key];
|
|
467
|
-
if (typeof value === "string") return value;
|
|
468
|
-
}
|
|
469
|
-
}
|
|
470
|
-
function formatCompactionError(error) {
|
|
471
|
-
if (error instanceof Error) return error.message;
|
|
472
|
-
return String(error);
|
|
473
|
-
}
|
|
474
|
-
//#endregion
|
|
475
|
-
export { maybeCompactCodexAppServerSession };
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
//#region extensions/codex/src/app-server/protocol.ts
|
|
2
|
-
function isJsonObject(value) {
|
|
3
|
-
return Boolean(value && typeof value === "object" && !Array.isArray(value));
|
|
4
|
-
}
|
|
5
|
-
function isRpcResponse(message) {
|
|
6
|
-
return "id" in message && !("method" in message);
|
|
7
|
-
}
|
|
8
|
-
//#endregion
|
|
9
|
-
export { isRpcResponse as n, isJsonObject as t };
|