@openclaw/codex 2026.7.2-beta.4 → 2026.7.2-beta.7
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/{app-server-policy-BO3jYBkv.js → app-server-policy-BSaO2JIT.js} +1 -1
- package/dist/{attempt-notifications-DdmnBMUp.js → attempt-notifications-AP-a-Q5k.js} +1 -1
- package/dist/{bounded-turn-CaQL96kg.js → bounded-turn-D2ZAgZVz.js} +54 -24
- package/dist/{capabilities-CLICvTxf.js → capabilities-BFDTVYr4.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-DgADqnHa.js → command-formatters-C336eRVS.js} +2 -2
- package/dist/{command-handlers-l_lVPNlB.js → command-handlers-DAHUSry9.js} +1233 -1222
- package/dist/{compact-CC5KhBzX.js → compact-D_uvHurS.js} +8 -8
- package/dist/{computer-use-Ip1-QGa-.js → computer-use-CYEc8U3w.js} +123 -115
- package/dist/{conversation-control-sNPsbTCP.js → conversation-control-xsIeXbo4.js} +6 -6
- package/dist/doctor-contract-api.js +24 -86
- package/dist/{dynamic-tools-CQI3UwqY.js → dynamic-tools-D2gYkSBO.js} +482 -91
- package/dist/effective-mcp-catalog-Bbd98Inw.js +114 -0
- package/dist/{event-projector-usage-D6tE7_qD.js → event-projector-usage-Xp4AlR2k.js} +20 -3
- package/dist/harness.js +19 -14
- package/dist/index.js +292 -328
- package/dist/media-understanding-provider.js +6 -1
- package/dist/{models-BNeMlHgg.js → models-BBMKU4jA.js} +2 -2
- package/dist/{notification-correlation-BGLixv5_.js → notification-correlation-CU6_AnOb.js} +3 -3
- package/dist/{plugin-app-cache-key-CvzvmBRz.js → plugin-app-cache-key-DztPafOA.js} +135 -42
- package/dist/{rate-limits-D0IJT-a6.js → rate-limits-CU-gVCCS.js} +1 -1
- package/dist/{request-BTccUTD3.js → request-qKh331yu.js} +3 -3
- package/dist/{run-attempt--858NXDl.js → run-attempt-CY9WlDLc.js} +1060 -402
- package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-CmtG_t1L.js} +90 -24
- package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-NuhpXmPB.js} +4 -0
- package/dist/{session-binding-ZSMX1omP.js → session-binding-BXpo9ymA.js} +1006 -891
- package/dist/{session-catalog-DsKaezgR.js → session-catalog-DyOgR4WH.js} +289 -56
- package/dist/{session-cli-CYJTfRLG.js → session-cli-2PZaFLRh.js} +2 -2
- package/dist/{session-upstream-marker-D7XlI9us.js → session-upstream-marker-B6U7tLw5.js} +1 -1
- package/dist/{settled-turn-finalizer-DHltNgtF.js → settled-turn-finalizer-CXY2Z9dT.js} +19 -6
- package/dist/{shared-client-wmgNFNYp.js → shared-client-DTbvH-XV.js} +1993 -1720
- package/dist/{side-question-BfFZCsJ-.js → side-question-_ulBk1AL.js} +12 -10
- package/dist/{thread-lifecycle-cqrOlJkq.js → thread-lifecycle-DF53ogiA.js} +980 -346
- package/dist/{transcript-mirror-2p7kl6e4.js → transcript-mirror-DzsdNCf5.js} +80 -41
- package/dist/{upstream-session-fork-vPjwkT1i.js → upstream-session-fork-Dy4Xvuoj.js} +3 -3
- package/dist/{usage-DM_I3mPT.js → usage-CQ6GhD5-.js} +3 -3
- package/dist/{web-search-provider.runtime-Bx6HAc_k.js → web-search-provider.runtime-CCFhg2z5.js} +3 -3
- package/package.json +6 -8
- package/npm-shrinkwrap.json +0 -202
- package/dist/{auth-binding-C1czuHPA.js → auth-binding-B4FfbcCg.js} +1 -1
|
@@ -1,30 +1,128 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { m as assertCodexThreadForkParams, r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-
|
|
4
|
-
import { n as listCodexAppServerModels } from "./models-
|
|
5
|
-
import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-
|
|
6
|
-
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-
|
|
7
|
-
import { r as formatCodexDisplayText } from "./command-formatters-
|
|
1
|
+
import { B as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES, D as resolveCodexAppServerClientInstanceId, V as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, W as isJsonObject, a as getLeasedSharedCodexAppServerClient, g as withTimeout, l as releaseLeasedSharedCodexAppServerClient, v as CodexAppServerRpcError } from "./shared-client-DTbvH-XV.js";
|
|
2
|
+
import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, g as resolveCodexAppServerRuntimeOptions, y as resolveCodexSupervisionAppServerRuntimeOptions } from "./session-binding-BXpo9ymA.js";
|
|
3
|
+
import { m as assertCodexThreadForkParams, r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-DzsdNCf5.js";
|
|
4
|
+
import { n as listCodexAppServerModels } from "./models-BBMKU4jA.js";
|
|
5
|
+
import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-DztPafOA.js";
|
|
6
|
+
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-BFDTVYr4.js";
|
|
7
|
+
import { r as formatCodexDisplayText } from "./command-formatters-C336eRVS.js";
|
|
8
8
|
import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-BHRpYbX3.js";
|
|
9
|
-
import { n as requestCodexAppServerClientJson, r as requestCodexAppServerJson } from "./request-
|
|
10
|
-
import { i as createImportedCodexSession, n as codexUpstreamBaseline, r as codexUpstreamContinueResult, t as codexLastTerminalTurnId } from "./session-upstream-marker-
|
|
9
|
+
import { n as requestCodexAppServerClientJson, r as requestCodexAppServerJson } from "./request-qKh331yu.js";
|
|
10
|
+
import { i as createImportedCodexSession, n as codexUpstreamBaseline, r as codexUpstreamContinueResult, t as codexLastTerminalTurnId } from "./session-upstream-marker-B6U7tLw5.js";
|
|
11
11
|
import fs from "node:fs/promises";
|
|
12
12
|
import path from "node:path";
|
|
13
13
|
import { timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
14
14
|
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
|
15
|
-
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
16
15
|
import { createHash } from "node:crypto";
|
|
17
|
-
import os from "node:os";
|
|
18
16
|
import { listAgentIds, resolveAllowedModelRef, resolveDefaultAgentDir, resolveDefaultAgentId, resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
17
|
+
import os from "node:os";
|
|
19
18
|
import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
20
19
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
21
20
|
import { materializeWindowsSpawnProgram, resolveWindowsSpawnProgram } from "openclaw/plugin-sdk/windows-spawn";
|
|
22
|
-
import { spawn } from "node:child_process";
|
|
23
21
|
import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
22
|
+
import { spawn } from "node:child_process";
|
|
23
|
+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
24
24
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
25
25
|
import process$1 from "node:process";
|
|
26
|
+
import { listSessionCatalogEntries } from "openclaw/plugin-sdk/session-catalog";
|
|
26
27
|
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
27
28
|
import { decodeNodePtyResumeParams, resolveNodeHostExecutable, runNodePtyCommand } from "openclaw/plugin-sdk/node-host";
|
|
29
|
+
//#region extensions/codex/src/jsonl-lines.ts
|
|
30
|
+
const JSONL_STREAM_THRESHOLD_BYTES = 4 * 1024 * 1024;
|
|
31
|
+
const JSONL_READ_CHUNK_BYTES = 1024 * 1024;
|
|
32
|
+
async function visitJsonlLines(file, visitor, chunkBytes = JSONL_READ_CHUNK_BYTES) {
|
|
33
|
+
let size;
|
|
34
|
+
try {
|
|
35
|
+
size = (await fs.stat(file)).size;
|
|
36
|
+
} catch {
|
|
37
|
+
return {
|
|
38
|
+
ok: false,
|
|
39
|
+
lineCount: 0
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
if (size <= JSONL_STREAM_THRESHOLD_BYTES) {
|
|
43
|
+
let content;
|
|
44
|
+
try {
|
|
45
|
+
content = await fs.readFile(file, "utf8");
|
|
46
|
+
} catch {
|
|
47
|
+
return {
|
|
48
|
+
ok: false,
|
|
49
|
+
lineCount: 0
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
if (content.length === 0) return {
|
|
53
|
+
ok: true,
|
|
54
|
+
lineCount: 0
|
|
55
|
+
};
|
|
56
|
+
let lineCount = 0;
|
|
57
|
+
for (const line of content.split(/\r?\n/u)) {
|
|
58
|
+
lineCount += 1;
|
|
59
|
+
if (visitor(line) === false) break;
|
|
60
|
+
}
|
|
61
|
+
return {
|
|
62
|
+
ok: true,
|
|
63
|
+
lineCount
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
let handle;
|
|
67
|
+
try {
|
|
68
|
+
handle = await fs.open(file, "r");
|
|
69
|
+
} catch {
|
|
70
|
+
return {
|
|
71
|
+
ok: false,
|
|
72
|
+
lineCount: 0
|
|
73
|
+
};
|
|
74
|
+
}
|
|
75
|
+
const buffer = Buffer.allocUnsafe(chunkBytes);
|
|
76
|
+
const decoder = new TextDecoder();
|
|
77
|
+
let pendingFragments = [];
|
|
78
|
+
let lineCount = 0;
|
|
79
|
+
try {
|
|
80
|
+
while (true) {
|
|
81
|
+
const { bytesRead } = await handle.read(buffer, 0, buffer.length, null);
|
|
82
|
+
if (bytesRead === 0) break;
|
|
83
|
+
const content = decoder.decode(buffer.subarray(0, bytesRead), { stream: true });
|
|
84
|
+
let lineStart = 0;
|
|
85
|
+
while (true) {
|
|
86
|
+
const newline = content.indexOf("\n", lineStart);
|
|
87
|
+
if (newline === -1) break;
|
|
88
|
+
let rawLine = content.slice(lineStart, newline);
|
|
89
|
+
if (pendingFragments.length > 0) {
|
|
90
|
+
pendingFragments.push(rawLine);
|
|
91
|
+
rawLine = pendingFragments.join("");
|
|
92
|
+
pendingFragments = [];
|
|
93
|
+
}
|
|
94
|
+
const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
|
|
95
|
+
lineCount += 1;
|
|
96
|
+
if (visitor(line) === false) return {
|
|
97
|
+
ok: true,
|
|
98
|
+
lineCount
|
|
99
|
+
};
|
|
100
|
+
lineStart = newline + 1;
|
|
101
|
+
}
|
|
102
|
+
if (lineStart < content.length) pendingFragments.push(content.slice(lineStart));
|
|
103
|
+
}
|
|
104
|
+
const decoderTail = decoder.decode();
|
|
105
|
+
if (decoderTail.length > 0) pendingFragments.push(decoderTail);
|
|
106
|
+
if (pendingFragments.length > 0) {
|
|
107
|
+
const rawLine = pendingFragments.join("");
|
|
108
|
+
const line = rawLine.endsWith("\r") ? rawLine.slice(0, -1) : rawLine;
|
|
109
|
+
lineCount += 1;
|
|
110
|
+
visitor(line);
|
|
111
|
+
}
|
|
112
|
+
return {
|
|
113
|
+
ok: true,
|
|
114
|
+
lineCount
|
|
115
|
+
};
|
|
116
|
+
} catch {
|
|
117
|
+
return {
|
|
118
|
+
ok: false,
|
|
119
|
+
lineCount: 0
|
|
120
|
+
};
|
|
121
|
+
} finally {
|
|
122
|
+
await handle.close().catch(() => void 0);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
//#endregion
|
|
28
126
|
//#region extensions/codex/src/node-cli-sessions.ts
|
|
29
127
|
const CODEX_CLI_SESSIONS_LIST_COMMAND = "codex.cli.sessions.list";
|
|
30
128
|
const CODEX_CLI_SESSION_RESUME_COMMAND = "codex.cli.session.resume";
|
|
@@ -247,20 +345,18 @@ function resolveCodexCliResumeSpawnInvocation(args, runtime = DEFAULT_RESUME_SPA
|
|
|
247
345
|
}
|
|
248
346
|
async function readHistorySessions(codexHome) {
|
|
249
347
|
const summaries = /* @__PURE__ */ new Map();
|
|
250
|
-
|
|
251
|
-
if (!content) return summaries;
|
|
252
|
-
for (const line of content.split(/\r?\n/u)) {
|
|
348
|
+
if (!(await visitJsonlLines(path.join(codexHome, "history.jsonl"), (line) => {
|
|
253
349
|
const trimmed = line.trim();
|
|
254
|
-
if (!trimmed)
|
|
350
|
+
if (!trimmed) return;
|
|
255
351
|
let parsed;
|
|
256
352
|
try {
|
|
257
353
|
parsed = JSON.parse(trimmed);
|
|
258
354
|
} catch {
|
|
259
|
-
|
|
355
|
+
return;
|
|
260
356
|
}
|
|
261
|
-
if (!isRecord(parsed) || typeof parsed.session_id !== "string")
|
|
357
|
+
if (!isRecord(parsed) || typeof parsed.session_id !== "string") return;
|
|
262
358
|
const sessionId = parsed.session_id.trim();
|
|
263
|
-
if (!sessionId)
|
|
359
|
+
if (!sessionId) return;
|
|
264
360
|
const entry = summaries.get(sessionId) ?? {
|
|
265
361
|
sessionId,
|
|
266
362
|
messageCount: 0
|
|
@@ -269,7 +365,7 @@ async function readHistorySessions(codexHome) {
|
|
|
269
365
|
if (typeof parsed.text === "string" && parsed.text.trim()) entry.lastMessage = truncateText(parsed.text.trim(), 140);
|
|
270
366
|
if (typeof parsed.ts === "number") entry.updatedAt = timestampMsToIsoString(parsed.ts * 1e3) ?? entry.updatedAt;
|
|
271
367
|
summaries.set(sessionId, entry);
|
|
272
|
-
}
|
|
368
|
+
})).ok) return /* @__PURE__ */ new Map();
|
|
273
369
|
return summaries;
|
|
274
370
|
}
|
|
275
371
|
async function hydrateSessionFiles(codexHome, summaries) {
|
|
@@ -307,35 +403,35 @@ async function hydrateSessionsFromSessionFiles(codexHome, summaries) {
|
|
|
307
403
|
}
|
|
308
404
|
}
|
|
309
405
|
async function readSessionFileSummary(file) {
|
|
310
|
-
const content = await readFileIfExists(file);
|
|
311
|
-
if (!content) return null;
|
|
312
406
|
let sessionId = "";
|
|
313
407
|
let cwd;
|
|
314
408
|
let updatedAt;
|
|
315
409
|
let lastMessage;
|
|
316
410
|
let messageCount = 0;
|
|
317
|
-
|
|
411
|
+
const result = await visitJsonlLines(file, (line) => {
|
|
318
412
|
const trimmed = line.trim();
|
|
319
|
-
if (!trimmed)
|
|
413
|
+
if (!trimmed) return;
|
|
320
414
|
let parsed;
|
|
321
415
|
try {
|
|
322
416
|
parsed = JSON.parse(trimmed);
|
|
323
417
|
} catch {
|
|
324
|
-
|
|
418
|
+
return;
|
|
325
419
|
}
|
|
326
|
-
if (!isRecord(parsed))
|
|
420
|
+
if (!isRecord(parsed)) return;
|
|
327
421
|
if (typeof parsed.timestamp === "string" && parsed.timestamp.trim()) updatedAt = parsed.timestamp.trim();
|
|
328
422
|
if (parsed.type === "session_meta" && isRecord(parsed.payload)) {
|
|
329
423
|
if (typeof parsed.payload.id === "string" && parsed.payload.id.trim()) sessionId = parsed.payload.id.trim();
|
|
330
424
|
if (typeof parsed.payload.cwd === "string" && parsed.payload.cwd.trim()) cwd = parsed.payload.cwd.trim();
|
|
331
|
-
|
|
425
|
+
return;
|
|
332
426
|
}
|
|
333
427
|
const messageText = readResponseItemMessageText(parsed);
|
|
334
428
|
if (messageText) {
|
|
335
429
|
messageCount += 1;
|
|
336
430
|
lastMessage = truncateText(messageText, 140);
|
|
337
431
|
}
|
|
338
|
-
}
|
|
432
|
+
});
|
|
433
|
+
if (!result.ok) return null;
|
|
434
|
+
if (result.lineCount === 0) return null;
|
|
339
435
|
if (!sessionId) sessionId = readSessionIdFromFilename(file) ?? "";
|
|
340
436
|
if (!sessionId) return null;
|
|
341
437
|
return {
|
|
@@ -443,15 +539,12 @@ function readRecordParam(paramsJSON) {
|
|
|
443
539
|
function resolveCodexHome() {
|
|
444
540
|
return process$1.env.CODEX_HOME?.trim() || path.join(os.homedir(), ".codex");
|
|
445
541
|
}
|
|
446
|
-
async function readFileIfExists(file) {
|
|
447
|
-
try {
|
|
448
|
-
return await fs.readFile(file, "utf8");
|
|
449
|
-
} catch {
|
|
450
|
-
return;
|
|
451
|
-
}
|
|
452
|
-
}
|
|
453
542
|
async function readFirstLine(file) {
|
|
454
|
-
|
|
543
|
+
let firstLine;
|
|
544
|
+
return (await visitJsonlLines(file, (line) => {
|
|
545
|
+
firstLine = line;
|
|
546
|
+
return false;
|
|
547
|
+
}, 65536)).ok ? firstLine : void 0;
|
|
455
548
|
}
|
|
456
549
|
async function readFileMtimeIso(file) {
|
|
457
550
|
try {
|
|
@@ -965,9 +1058,10 @@ function readNodeSessionMarker(entry) {
|
|
|
965
1058
|
}
|
|
966
1059
|
function listNodeAdoptedSessionEntries(params) {
|
|
967
1060
|
const adopted = /* @__PURE__ */ new Map();
|
|
968
|
-
for (const
|
|
969
|
-
|
|
970
|
-
|
|
1061
|
+
for (const { agentId, entry, sessionKey } of listSessionCatalogEntries({
|
|
1062
|
+
config: params.config ?? {},
|
|
1063
|
+
runtime: params.runtime,
|
|
1064
|
+
sessionEntries: params.sessionEntries
|
|
971
1065
|
})) {
|
|
972
1066
|
const marker = readNodeSessionMarker(entry);
|
|
973
1067
|
const sessionId = entry.sessionId?.trim();
|
|
@@ -1336,12 +1430,20 @@ function codexNodeTerminalCapability(node) {
|
|
|
1336
1430
|
return node.connected === true && commands?.includes("codex.terminal.resume.v1") === true ? { canOpenTerminalCodex: true } : {};
|
|
1337
1431
|
}
|
|
1338
1432
|
async function requireCatalogEligibleThread(control, threadId) {
|
|
1433
|
+
const cached = await findCatalogEligibleThread(control, threadId, false);
|
|
1434
|
+
if (cached) return cached;
|
|
1435
|
+
const refreshed = await findCatalogEligibleThread(control, threadId, true);
|
|
1436
|
+
if (refreshed) return refreshed;
|
|
1437
|
+
throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
|
|
1438
|
+
}
|
|
1439
|
+
async function findCatalogEligibleThread(control, threadId, forceRefresh) {
|
|
1339
1440
|
let cursor;
|
|
1340
1441
|
const seenCursors = /* @__PURE__ */ new Set();
|
|
1341
1442
|
for (let pageIndex = 0; pageIndex < 100; pageIndex += 1) {
|
|
1342
1443
|
const page = await control.listPage({
|
|
1343
1444
|
limit: 100,
|
|
1344
|
-
...cursor ? { cursor } : {}
|
|
1445
|
+
...cursor ? { cursor } : {},
|
|
1446
|
+
...forceRefresh ? { forceRefresh: true } : {}
|
|
1345
1447
|
});
|
|
1346
1448
|
const candidate = page.sessions.find((session) => session.threadId === threadId);
|
|
1347
1449
|
if (candidate) {
|
|
@@ -1349,7 +1451,7 @@ async function requireCatalogEligibleThread(control, threadId) {
|
|
|
1349
1451
|
throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
|
|
1350
1452
|
}
|
|
1351
1453
|
const nextCursor = page.nextCursor?.trim();
|
|
1352
|
-
if (!nextCursor)
|
|
1454
|
+
if (!nextCursor) return;
|
|
1353
1455
|
if (seenCursors.has(nextCursor)) throw new CatalogParamsError("Codex session eligibility could not be verified");
|
|
1354
1456
|
seenCursors.add(nextCursor);
|
|
1355
1457
|
cursor = nextCursor;
|
|
@@ -1615,6 +1717,16 @@ function createChecker(params) {
|
|
|
1615
1717
|
//#region extensions/codex/src/session-catalog.ts
|
|
1616
1718
|
const boundCatalogSessionId = (value) => boundedCatalogString(value, 256);
|
|
1617
1719
|
const CODEX_SUPERVISION_SESSION_KEY_PREFIX = "harness:codex:supervision:";
|
|
1720
|
+
const CODEX_SESSION_CATALOG_LIST_TTL_MS = 32e3;
|
|
1721
|
+
const CODEX_SESSION_CATALOG_LIST_CACHE_MAX_ENTRIES = 32;
|
|
1722
|
+
function codexCatalogPageCacheKey(params) {
|
|
1723
|
+
return JSON.stringify([
|
|
1724
|
+
params.cursor ?? null,
|
|
1725
|
+
params.limit ?? null,
|
|
1726
|
+
params.searchTerm?.trim().toLocaleLowerCase() || null,
|
|
1727
|
+
params.cwd?.trim() || null
|
|
1728
|
+
]);
|
|
1729
|
+
}
|
|
1618
1730
|
function createCodexSessionCatalogControlFromRequests(params) {
|
|
1619
1731
|
return {
|
|
1620
1732
|
...params.clientId ? { clientId: params.clientId } : {},
|
|
@@ -1684,13 +1796,27 @@ function createCodexSessionCatalogControlFromRequests(params) {
|
|
|
1684
1796
|
function createCodexSessionCatalogControl(params) {
|
|
1685
1797
|
const now = params.now ?? Date.now;
|
|
1686
1798
|
const getPluginConfig = () => params.getPluginConfig();
|
|
1799
|
+
const requestOptionsByConfig = /* @__PURE__ */ new WeakMap();
|
|
1800
|
+
const catalogPagesByConfig = /* @__PURE__ */ new WeakMap();
|
|
1801
|
+
const resolveRequestOptions = (startOptions) => {
|
|
1802
|
+
const runtimeConfig = params.getRuntimeConfig();
|
|
1803
|
+
if (!runtimeConfig) return {
|
|
1804
|
+
config: void 0,
|
|
1805
|
+
startOptions: structuredClone(startOptions)
|
|
1806
|
+
};
|
|
1807
|
+
const cached = requestOptionsByConfig.get(runtimeConfig);
|
|
1808
|
+
if (cached) return cached;
|
|
1809
|
+
const resolved = {
|
|
1810
|
+
config: structuredClone(runtimeConfig),
|
|
1811
|
+
startOptions: structuredClone(startOptions)
|
|
1812
|
+
};
|
|
1813
|
+
requestOptionsByConfig.set(runtimeConfig, resolved);
|
|
1814
|
+
return resolved;
|
|
1815
|
+
};
|
|
1687
1816
|
const createRequestSnapshot = () => {
|
|
1688
1817
|
const pluginConfig = getPluginConfig();
|
|
1689
1818
|
const runtime = resolveCodexSupervisionAppServerRuntimeOptions({ pluginConfig });
|
|
1690
|
-
const requestOptions =
|
|
1691
|
-
config: structuredClone(params.getRuntimeConfig()),
|
|
1692
|
-
startOptions: structuredClone(runtime.start)
|
|
1693
|
-
};
|
|
1819
|
+
const requestOptions = resolveRequestOptions(runtime.start);
|
|
1694
1820
|
return {
|
|
1695
1821
|
requestTimeoutMs: runtime.requestTimeoutMs,
|
|
1696
1822
|
listThreads: async (listParams, timeoutMs) => await codexControlRequest(pluginConfig, CODEX_CONTROL_METHODS.listThreads, listParams, {
|
|
@@ -1710,10 +1836,10 @@ function createCodexSessionCatalogControl(params) {
|
|
|
1710
1836
|
};
|
|
1711
1837
|
const withPinnedConnection = async (run) => {
|
|
1712
1838
|
const runtime = resolveCodexSupervisionAppServerRuntimeOptions({ pluginConfig: getPluginConfig() });
|
|
1713
|
-
const runtimeConfig =
|
|
1839
|
+
const { config: runtimeConfig, startOptions } = resolveRequestOptions(runtime.start);
|
|
1714
1840
|
const client = await getLeasedSharedCodexAppServerClient({
|
|
1715
1841
|
config: runtimeConfig,
|
|
1716
|
-
startOptions
|
|
1842
|
+
startOptions,
|
|
1717
1843
|
timeoutMs: runtime.requestTimeoutMs
|
|
1718
1844
|
});
|
|
1719
1845
|
try {
|
|
@@ -1772,11 +1898,112 @@ function createCodexSessionCatalogControl(params) {
|
|
|
1772
1898
|
releaseLeasedSharedCodexAppServerClient(client);
|
|
1773
1899
|
}
|
|
1774
1900
|
};
|
|
1775
|
-
|
|
1901
|
+
const control = createCodexSessionCatalogControlFromRequests({
|
|
1776
1902
|
createRequestSnapshot,
|
|
1777
1903
|
now,
|
|
1778
1904
|
withPinnedConnection
|
|
1779
1905
|
});
|
|
1906
|
+
return {
|
|
1907
|
+
...control,
|
|
1908
|
+
async listPage(pageParams) {
|
|
1909
|
+
const runtimeConfig = params.getRuntimeConfig();
|
|
1910
|
+
if (!runtimeConfig) return await control.listPage(pageParams);
|
|
1911
|
+
let cache = catalogPagesByConfig.get(runtimeConfig);
|
|
1912
|
+
if (!cache) {
|
|
1913
|
+
cache = /* @__PURE__ */ new Map();
|
|
1914
|
+
catalogPagesByConfig.set(runtimeConfig, cache);
|
|
1915
|
+
}
|
|
1916
|
+
const key = codexCatalogPageCacheKey(pageParams);
|
|
1917
|
+
const cached = cache.get(key);
|
|
1918
|
+
if (pageParams.forceRefresh !== true && cached) {
|
|
1919
|
+
cache.delete(key);
|
|
1920
|
+
cache.set(key, cached);
|
|
1921
|
+
if (cached.stalePage) return await cached.stalePage;
|
|
1922
|
+
if (cached.expiresAt > now()) return await cached.page;
|
|
1923
|
+
const stalePage = cached.settledPage;
|
|
1924
|
+
if (!stalePage) return await cached.page;
|
|
1925
|
+
const page = control.listPage(pageParams);
|
|
1926
|
+
const entry = {
|
|
1927
|
+
expiresAt: Number.POSITIVE_INFINITY,
|
|
1928
|
+
page,
|
|
1929
|
+
settledPage: stalePage,
|
|
1930
|
+
stalePage
|
|
1931
|
+
};
|
|
1932
|
+
cache.set(key, entry);
|
|
1933
|
+
page.then(() => {
|
|
1934
|
+
if (cache.get(key) === entry) {
|
|
1935
|
+
delete entry.stalePage;
|
|
1936
|
+
entry.settledPage = page;
|
|
1937
|
+
entry.expiresAt = now() + CODEX_SESSION_CATALOG_LIST_TTL_MS;
|
|
1938
|
+
}
|
|
1939
|
+
}, async () => {
|
|
1940
|
+
let stale;
|
|
1941
|
+
try {
|
|
1942
|
+
stale = await stalePage;
|
|
1943
|
+
} catch {}
|
|
1944
|
+
if (cache.get(key) !== entry) return;
|
|
1945
|
+
if (stale) {
|
|
1946
|
+
cache.delete(key);
|
|
1947
|
+
const settledPage = Promise.resolve(stale);
|
|
1948
|
+
cache.set(key, {
|
|
1949
|
+
expiresAt: now(),
|
|
1950
|
+
page: settledPage,
|
|
1951
|
+
settledPage
|
|
1952
|
+
});
|
|
1953
|
+
} else cache.delete(key);
|
|
1954
|
+
});
|
|
1955
|
+
return await stalePage;
|
|
1956
|
+
}
|
|
1957
|
+
if (cached) cache.delete(key);
|
|
1958
|
+
const serveStaleOnError = pageParams.forceRefresh !== true;
|
|
1959
|
+
const page = control.listPage(pageParams);
|
|
1960
|
+
const stalePage = cached?.settledPage;
|
|
1961
|
+
const entry = {
|
|
1962
|
+
expiresAt: Number.POSITIVE_INFINITY,
|
|
1963
|
+
page,
|
|
1964
|
+
...stalePage ? {
|
|
1965
|
+
stalePage,
|
|
1966
|
+
settledPage: stalePage
|
|
1967
|
+
} : {}
|
|
1968
|
+
};
|
|
1969
|
+
cache.set(key, entry);
|
|
1970
|
+
while (cache.size > CODEX_SESSION_CATALOG_LIST_CACHE_MAX_ENTRIES) {
|
|
1971
|
+
const oldest = cache.keys().next();
|
|
1972
|
+
if (oldest.done) break;
|
|
1973
|
+
cache.delete(oldest.value);
|
|
1974
|
+
}
|
|
1975
|
+
try {
|
|
1976
|
+
const result = await page;
|
|
1977
|
+
if (cache.get(key) === entry) {
|
|
1978
|
+
delete entry.stalePage;
|
|
1979
|
+
entry.settledPage = page;
|
|
1980
|
+
entry.expiresAt = now() + CODEX_SESSION_CATALOG_LIST_TTL_MS;
|
|
1981
|
+
}
|
|
1982
|
+
return result;
|
|
1983
|
+
} catch (error) {
|
|
1984
|
+
if (stalePage) {
|
|
1985
|
+
let stale;
|
|
1986
|
+
try {
|
|
1987
|
+
stale = await stalePage;
|
|
1988
|
+
} catch {}
|
|
1989
|
+
if (stale) {
|
|
1990
|
+
if (cache.get(key) === entry) {
|
|
1991
|
+
cache.delete(key);
|
|
1992
|
+
const settledPage = Promise.resolve(stale);
|
|
1993
|
+
cache.set(key, {
|
|
1994
|
+
expiresAt: now(),
|
|
1995
|
+
page: settledPage,
|
|
1996
|
+
settledPage
|
|
1997
|
+
});
|
|
1998
|
+
}
|
|
1999
|
+
if (serveStaleOnError) return stale;
|
|
2000
|
+
}
|
|
2001
|
+
}
|
|
2002
|
+
if (cache.get(key) === entry) cache.delete(key);
|
|
2003
|
+
throw error;
|
|
2004
|
+
}
|
|
2005
|
+
}
|
|
2006
|
+
};
|
|
1780
2007
|
}
|
|
1781
2008
|
async function listGatewayHost(params) {
|
|
1782
2009
|
try {
|
|
@@ -1788,7 +2015,8 @@ async function listGatewayHost(params) {
|
|
|
1788
2015
|
const adoptedSessions = await listAdoptedSessionEntries({
|
|
1789
2016
|
bindingStore: params.bindingStore,
|
|
1790
2017
|
config: params.config,
|
|
1791
|
-
runtime: params.runtime
|
|
2018
|
+
runtime: params.runtime,
|
|
2019
|
+
sessionEntries: params.sessionEntries
|
|
1792
2020
|
});
|
|
1793
2021
|
return {
|
|
1794
2022
|
hostId: CODEX_LOCAL_SESSION_HOST_ID,
|
|
@@ -1821,13 +2049,14 @@ async function listCodexSessionCatalog(params) {
|
|
|
1821
2049
|
config: params.config,
|
|
1822
2050
|
control: params.control,
|
|
1823
2051
|
query,
|
|
1824
|
-
runtime: params.runtime
|
|
2052
|
+
runtime: params.runtime,
|
|
2053
|
+
sessionEntries: params.sessionEntries
|
|
1825
2054
|
})] : [];
|
|
1826
2055
|
for (const host of localHosts) if (params.onHost) host.then(params.onHost).catch(() => void 0);
|
|
1827
2056
|
if (!(!requestedHostIds || query.hostIds?.some((hostId) => hostId.startsWith("node:")))) return { hosts: await Promise.all(localHosts) };
|
|
1828
2057
|
let nodes;
|
|
1829
2058
|
try {
|
|
1830
|
-
nodes = (await params.runtime.nodes.list()).nodes.filter((node) => node.commands?.includes("codex.appServer.threads.list.v1") && (!requestedHostIds || requestedHostIds.has(`node:${node.nodeId}`))).slice(0, 100 - localHosts.length);
|
|
2059
|
+
nodes = (await (params.listNodes?.() ?? params.runtime.nodes.list())).nodes.filter((node) => node.gatewayLocal !== true && node.commands?.includes("codex.appServer.threads.list.v1") && (!requestedHostIds || requestedHostIds.has(`node:${node.nodeId}`))).slice(0, 100 - localHosts.length);
|
|
1831
2060
|
} catch (error) {
|
|
1832
2061
|
const registryHost = {
|
|
1833
2062
|
hostId: "node:registry",
|
|
@@ -1842,7 +2071,8 @@ async function listCodexSessionCatalog(params) {
|
|
|
1842
2071
|
}
|
|
1843
2072
|
const adoptedNodeSessions = listNodeAdoptedSessionEntries({
|
|
1844
2073
|
config: params.config,
|
|
1845
|
-
runtime: params.runtime
|
|
2074
|
+
runtime: params.runtime,
|
|
2075
|
+
sessionEntries: params.sessionEntries
|
|
1846
2076
|
});
|
|
1847
2077
|
const nodeHosts = nodes.toSorted(compareNodeLabels).map(async (node) => {
|
|
1848
2078
|
const host = await listPairedNode({
|
|
@@ -1979,9 +2209,10 @@ function isAdoptionSessionKeyForThread(sessionKey, threadId) {
|
|
|
1979
2209
|
}
|
|
1980
2210
|
async function listAdoptedSessionEntries(params) {
|
|
1981
2211
|
const adopted = /* @__PURE__ */ new Map();
|
|
1982
|
-
for (const
|
|
1983
|
-
|
|
1984
|
-
|
|
2212
|
+
for (const { agentId, entry, sessionKey } of listSessionCatalogEntries({
|
|
2213
|
+
config: params.config ?? {},
|
|
2214
|
+
runtime: params.runtime,
|
|
2215
|
+
sessionEntries: params.sessionEntries
|
|
1985
2216
|
})) {
|
|
1986
2217
|
const sessionKeyRest = adoptionSessionKeyRest(sessionKey);
|
|
1987
2218
|
if (!sessionKeyRest.startsWith(CODEX_SUPERVISION_SESSION_KEY_PREFIX) || entry.initializationPending === true || entry.agentHarnessId !== "codex" || entry.modelSelectionLocked !== true) continue;
|
|
@@ -2351,7 +2582,7 @@ function registerCodexSessionCatalog(params) {
|
|
|
2351
2582
|
resolveCreateSession: ({ agentId }) => resolveCodexCatalogCreateSession(params.getRuntimeConfig() ?? params.api.config, agentId),
|
|
2352
2583
|
list: async (query) => {
|
|
2353
2584
|
const localTerminalAvailable = resolveLocalCodexTerminalExecutable() !== void 0;
|
|
2354
|
-
const { onHost, ...gatewayQuery } = query;
|
|
2585
|
+
const { listNodes, onHost, sessionEntries, ...gatewayQuery } = query;
|
|
2355
2586
|
const mapHost = (host) => toGenericCatalogHost(host, localTerminalAvailable);
|
|
2356
2587
|
return (await listCodexSessionCatalog({
|
|
2357
2588
|
bindingStore: params.bindingStore,
|
|
@@ -2359,6 +2590,8 @@ function registerCodexSessionCatalog(params) {
|
|
|
2359
2590
|
runtime: params.api.runtime,
|
|
2360
2591
|
control: params.control,
|
|
2361
2592
|
query: gatewayQuery,
|
|
2593
|
+
listNodes,
|
|
2594
|
+
sessionEntries,
|
|
2362
2595
|
...onHost ? { onHost: (host) => onHost(mapHost(host)) } : {}
|
|
2363
2596
|
})).hosts.map(mapHost);
|
|
2364
2597
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { a as CODEX_LOCAL_SESSION_HOST_ID } from "./session-catalog-
|
|
2
|
-
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
1
|
+
import { a as CODEX_LOCAL_SESSION_HOST_ID } from "./session-catalog-DyOgR4WH.js";
|
|
3
2
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
|
+
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
4
4
|
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
5
5
|
import { addGatewayClientOptions, callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
|
|
6
6
|
//#region extensions/codex/src/session-cli.ts
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-
|
|
1
|
+
import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-DzsdNCf5.js";
|
|
2
2
|
import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
3
3
|
//#region extensions/codex/src/app-server/session-history-import.ts
|
|
4
4
|
/** Creates a session whose transcript is derived from one verified Codex thread snapshot. */
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { t as
|
|
1
|
+
import { W as isJsonObject } from "./shared-client-DTbvH-XV.js";
|
|
2
|
+
import { c as fingerprintCodexMirrorSourceMessage, d as attachCodexMirrorIdentity, f as readMirrorIdentity, l as readCodexMirrorSourceFingerprint, p as readUpstreamUserText, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-DzsdNCf5.js";
|
|
3
|
+
import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-D2ZAgZVz.js";
|
|
3
4
|
import { n as createAssistantMessage } from "./event-projector-assistant-message-DTgnPPVF.js";
|
|
5
|
+
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
6
|
import { Buffer } from "node:buffer";
|
|
5
7
|
import { isSilentReplyText } from "openclaw/plugin-sdk/reply-runtime";
|
|
6
8
|
//#region extensions/codex/src/app-server/settled-turn-projection.ts
|
|
@@ -9,9 +11,6 @@ const MAX_PROJECTION_BYTES = 512 * 1024;
|
|
|
9
11
|
const MAX_TEXT_BYTES = 64 * 1024;
|
|
10
12
|
const TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,128}$/u;
|
|
11
13
|
const TOOL_ERROR_STATUS_PREFIX = "[Tool result status: error]\n";
|
|
12
|
-
function isRecord(value) {
|
|
13
|
-
return Boolean(value) && typeof value === "object" && !Array.isArray(value);
|
|
14
|
-
}
|
|
15
14
|
function readNonEmptyString(value) {
|
|
16
15
|
return typeof value === "string" ? value.trim() || void 0 : void 0;
|
|
17
16
|
}
|
|
@@ -265,7 +264,21 @@ async function runCodexSettledTurnFinalization(operation, options) {
|
|
|
265
264
|
historyItems,
|
|
266
265
|
requireNoExternalCapabilities: true
|
|
267
266
|
});
|
|
268
|
-
|
|
267
|
+
let promptEchoSeen = false;
|
|
268
|
+
let unexpectedItem;
|
|
269
|
+
for (const item of bounded.items) {
|
|
270
|
+
if (FINALIZER_PASSIVE_ITEM_TYPES.has(item.type)) continue;
|
|
271
|
+
if (item.type === "userMessage" && !promptEchoSeen) {
|
|
272
|
+
const content = Array.isArray(item.content) ? item.content : [];
|
|
273
|
+
const input = content[0];
|
|
274
|
+
if (content.length === 1 && isJsonObject(input) && input.type === "text" && input.text === attempt.prompt) {
|
|
275
|
+
promptEchoSeen = true;
|
|
276
|
+
continue;
|
|
277
|
+
}
|
|
278
|
+
}
|
|
279
|
+
unexpectedItem = item;
|
|
280
|
+
break;
|
|
281
|
+
}
|
|
269
282
|
if (unexpectedItem) throw new Error(`Codex settled-turn finalization returned unexpected native item: ${unexpectedItem.type}`);
|
|
270
283
|
const text = bounded.text.trim();
|
|
271
284
|
if (!text || isSilentReplyText(text)) throw new Error("Codex settled-turn finalization completed without a visible answer");
|