@openclaw/codex 2026.8.1 → 2026.8.2
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/api.js +2 -2
- package/dist/{attempt-client-cleanup-CVPvp9dL.js → attempt-client-cleanup-CpVfwctT.js} +1 -1
- package/dist/{binding-connection-CCQFs8lf.js → binding-connection-CF7BmrDk.js} +2 -2
- package/dist/{bounded-turn-rq5tiSXk.js → bounded-turn-DRC3hcjm.js} +10 -9
- package/dist/{capabilities-CGm_94eL.js → capabilities-D6m_TdVy.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-C54Yg3eA.js → command-formatters--UToCokS.js} +4 -3
- package/dist/{command-handlers-BvOAHTrA.js → command-handlers-CLFx2Ypa.js} +41 -33
- package/dist/{compact-Hd7SAc0N.js → compact-5xqW1oCh.js} +13 -11
- package/dist/{config-Cxw3Cl3k.js → config-CcYL77O6.js} +6 -4
- package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
- package/dist/doctor-contract-api.js +8 -4
- package/dist/{dynamic-tools-BFoUcRdx.js → dynamic-tools-BmeXjwNZ.js} +103 -106
- package/dist/{effective-mcp-catalog-BTJHnDSx.js → effective-mcp-catalog-XXQKgK1U.js} +2 -2
- package/dist/{event-projector-usage-D3PHFFXh.js → event-projector-usage-B2r5vhWH.js} +7 -12
- package/dist/{harness-DVfUQBlQ.js → harness-BgeB7LnD.js} +13 -13
- package/dist/harness.js +1 -1
- package/dist/index.js +56 -37
- package/dist/{isolated-completion-Cbbx_5Ed.js → isolated-completion-CxTus3vZ.js} +3 -3
- package/dist/media-understanding-provider.js +1 -1
- package/dist/{model-catalog-o6Cgjoss.js → model-catalog-DULBcniB.js} +5 -5
- package/dist/{models-DgFWSuxA.js → models-DaWfETQk.js} +4 -3
- package/dist/{native-subagent-monitor-CwFyoylz.js → native-subagent-monitor-vXYUZH37.js} +24 -104
- package/dist/{node-exec-server.runtime-DXrqpw1c.js → node-exec-server.runtime-DirKVZ5h.js} +2 -2
- package/dist/{plugin-approval-roundtrip-D80UZiJ_.js → plugin-approval-roundtrip-CCWQGlAI.js} +2 -1
- package/dist/{plugin-marketplace-discovery-mdmScYOj.js → plugin-marketplace-discovery-BXjIFEiw.js} +14 -13
- package/dist/{plugin-metadata-cache-CulOABwu.js → plugin-metadata-cache-DQQm4gWT.js} +5 -5
- package/dist/{rate-limits-hFtzt2Up.js → rate-limits-BqHEHXQJ.js} +3 -2
- package/dist/{request-CCm4LaED.js → request-BWxweEdK.js} +2 -2
- package/dist/{run-attempt-BwNQDH2u.js → run-attempt-BVLE4Gbi.js} +133 -182
- package/dist/{runtime-artifact-DeBvleJw.js → runtime-artifact-D9pYp4zL.js} +3 -3
- package/dist/{session-binding-q2WSTVmC.js → session-binding-D0zinCP1.js} +1 -1
- package/dist/{session-catalog-C2Tae4rI.js → session-catalog-eMhVm0Ql.js} +232 -204
- package/dist/{session-catalog-home-id-DAKUrm3C.js → session-catalog-home-id-Dt2GiG5o.js} +3 -3
- package/dist/{session-cli-BuDjm5Ou.js → session-cli-B2lyjJA0.js} +1 -1
- package/dist/session-history-C5J1AKzG.js +87 -0
- package/dist/{session-permission-policy-gLm40Vtq.js → session-permission-policy-ScnAyG90.js} +1 -1
- package/dist/{session-retirement-CdkI0bvb.js → session-retirement-CtUtUTr9.js} +4 -4
- package/dist/{session-upstream-marker-Bcy33kam.js → session-upstream-marker-gqrYIRHk.js} +1 -1
- package/dist/settled-turn-context-Bk3IUwod.js +290 -0
- package/dist/settled-turn-finalizer-BXLN9PfJ.js +104 -0
- package/dist/{shared-client-kNkljY-R.js → shared-client-B1tT5U6r.js} +33 -35
- package/dist/{side-question-GwD73tX6.js → side-question-CZ-mCw-t.js} +18 -15
- package/dist/{thread-lifecycle-Ss-uwnC4.js → thread-lifecycle-CGGKP720.js} +206 -163
- package/dist/{thread-ownership-CeYBqg_4.js → thread-ownership-RkaoZCmQ.js} +2 -2
- package/dist/{thread-resume-DF54hagX.js → thread-resume-BFt1-ZDa.js} +7 -6
- package/dist/{transcript-mirror-CkEQIna-.js → transcript-mirror-1ep4XjzF.js} +14 -7
- package/dist/{transport-stdio-C7-s9TLG.js → transport-stdio-NT_Dpd9V.js} +40 -24
- package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
- package/dist/{upstream-session-fork-BACGlOFa.js → upstream-session-fork-Dc8BFExw.js} +13 -19
- package/dist/{usage-C2l8Mils.js → usage-DUhd58gI.js} +3 -3
- package/dist/{web-search-provider.runtime-B2XgRdFv.js → web-search-provider.runtime-BEmlE7ov.js} +3 -3
- package/package.json +5 -5
- package/dist/settled-turn-finalizer-B8JJcxCi.js +0 -329
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as resolveCodexAppServerSpawnEnv } from "./transport-stdio-
|
|
1
|
+
import { n as resolveCodexAppServerSpawnEnv } from "./transport-stdio-NT_Dpd9V.js";
|
|
2
2
|
import fs from "node:fs/promises";
|
|
3
3
|
import path from "node:path";
|
|
4
4
|
import { createHash } from "node:crypto";
|
|
@@ -9,14 +9,14 @@ import { isPathInside } from "openclaw/plugin-sdk/file-access-runtime";
|
|
|
9
9
|
/** Exact local runtime artifact identity for verified Codex setup turns. */
|
|
10
10
|
const ARTIFACT_ID_PREFIX = "codex-app-server:v1:";
|
|
11
11
|
const ARTIFACT_HASH_DOMAIN = "openclaw-codex-app-server-runtime-artifact-v1\0";
|
|
12
|
-
const MAX_ARTIFACT_ID_BYTES =
|
|
12
|
+
const MAX_ARTIFACT_ID_BYTES = 32768;
|
|
13
13
|
const MAX_ARTIFACT_PATH_BYTES = 4096;
|
|
14
14
|
const MAX_ARTIFACT_INVOCATION_PATHS = 8;
|
|
15
15
|
const MAX_ARTIFACT_DEPTH = 64;
|
|
16
16
|
const MAX_ARTIFACT_ENTRIES = 32768;
|
|
17
17
|
const MAX_ARTIFACT_FILES = 8192;
|
|
18
18
|
const MAX_ARTIFACT_TOTAL_BYTES = 1024n * 1024n * 1024n;
|
|
19
|
-
const READ_CHUNK_BYTES =
|
|
19
|
+
const READ_CHUNK_BYTES = 65536;
|
|
20
20
|
const CODE_MODE_HOST_PATH_ENV = "CODEX_CODE_MODE_HOST_PATH";
|
|
21
21
|
const SAFE_NODE_OPTIONS_BOOLEAN_FLAGS = /* @__PURE__ */ new Set([
|
|
22
22
|
"--enable-network-family-autoselection",
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
-
import { A as normalizeCodexServiceTier, N as CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN } from "./config-
|
|
2
|
+
import { A as normalizeCodexServiceTier, N as CODEX_PLUGIN_MARKETPLACE_NAME_PATTERN } from "./config-CcYL77O6.js";
|
|
3
3
|
import { n as CODEX_APP_SERVER_BINDING_NAMESPACE, t as CODEX_APP_SERVER_BINDING_MAX_ENTRIES } from "./session-binding-meta-B7aEMU7g.js";
|
|
4
4
|
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
5
|
import { AgentHarnessSessionSupersededError, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import { F as resolveCodexAppServerLocalHomeDir, I as resolveCodexAppServerUserHomeDir, P as resolveCodexAppServerHomeDir, T as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-
|
|
2
|
-
import { $ as CodexAppServerRpcError, Et as withTimeout, Ht as isJsonObject, Lt as resolveCodexAppServerPreparedAuthHandoff, Mt as resolveCodexAppServerAuthProfileId, Pt as resolveCodexAppServerAuthProfileStore, Q as resolveCodexAppServerClientInstanceId, Rt as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, zt as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS } from "./shared-client-
|
|
3
|
-
import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity } from "./session-binding-
|
|
1
|
+
import { F as resolveCodexAppServerLocalHomeDir, I as resolveCodexAppServerUserHomeDir, P as resolveCodexAppServerHomeDir, T as readCodexPluginConfig, i as resolveCodexAppServerRuntimeOptions, s as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-CcYL77O6.js";
|
|
2
|
+
import { $ as CodexAppServerRpcError, Et as withTimeout, Ht as isJsonObject, Lt as resolveCodexAppServerPreparedAuthHandoff, Mt as resolveCodexAppServerAuthProfileId, Pt as resolveCodexAppServerAuthProfileStore, Q as resolveCodexAppServerClientInstanceId, Rt as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, zt as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS } from "./shared-client-B1tT5U6r.js";
|
|
3
|
+
import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity } from "./session-binding-D0zinCP1.js";
|
|
4
4
|
import { i as assertCodexThreadForkParams } from "./protocol-validators-Bg5rpNxk.js";
|
|
5
|
-
import { a as closeCodexStartupClientBestEffort } from "./attempt-client-cleanup-
|
|
6
|
-
import { n as listCodexAppServerModels } from "./models-
|
|
7
|
-
import { a as replaceCodexCatalogConnectionHomes, n as buildCodexAppServerConnectionFingerprint, t as resumeCodexAppServerThread } from "./thread-resume-
|
|
8
|
-
import { n as codexCatalogHomeId, r as isOpenClawManagedCodexThread, t as canonicalCodexCatalogHome } from "./session-catalog-home-id-
|
|
9
|
-
import { i as requestCodexAppServerJson, o as withCodexAppServerJsonClient, r as requestCodexAppServerClientJson } from "./request-
|
|
10
|
-
import {
|
|
11
|
-
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-
|
|
12
|
-
import { r as formatCodexDisplayText } from "./command-formatters
|
|
13
|
-
import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-
|
|
5
|
+
import { a as closeCodexStartupClientBestEffort } from "./attempt-client-cleanup-CpVfwctT.js";
|
|
6
|
+
import { n as listCodexAppServerModels } from "./models-DaWfETQk.js";
|
|
7
|
+
import { a as replaceCodexCatalogConnectionHomes, n as buildCodexAppServerConnectionFingerprint, t as resumeCodexAppServerThread } from "./thread-resume-BFt1-ZDa.js";
|
|
8
|
+
import { i as readCodexSessionMeta, n as codexCatalogHomeId, r as isOpenClawManagedCodexThread, t as canonicalCodexCatalogHome } from "./session-catalog-home-id-Dt2GiG5o.js";
|
|
9
|
+
import { i as requestCodexAppServerJson, o as withCodexAppServerJsonClient, r as requestCodexAppServerClientJson } from "./request-BWxweEdK.js";
|
|
10
|
+
import { m as projectCodexUserItemText, r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-1ep4XjzF.js";
|
|
11
|
+
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-D6m_TdVy.js";
|
|
12
|
+
import { r as formatCodexDisplayText } from "./command-formatters--UToCokS.js";
|
|
13
|
+
import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-BiodpIzq.js";
|
|
14
14
|
import { n as prepareCodexAppServerAuthBinding } from "./auth-binding-Ds_QVm-X.js";
|
|
15
|
-
import { i as createImportedCodexSession, n as codexUpstreamBaseline, r as codexUpstreamContinueResult, t as codexLastTerminalTurnId } from "./session-upstream-marker-
|
|
15
|
+
import { i as createImportedCodexSession, n as codexUpstreamBaseline, r as codexUpstreamContinueResult, t as codexLastTerminalTurnId } from "./session-upstream-marker-gqrYIRHk.js";
|
|
16
16
|
import { asFiniteNumber, isRecord, normalizeBoundedOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
17
17
|
import fs from "node:fs/promises";
|
|
18
18
|
import path from "node:path";
|
|
@@ -37,8 +37,8 @@ import { createSessionCatalogAdoptionCoordinator, listSessionCatalogEntries, ses
|
|
|
37
37
|
import { decodeNodePtyResumeParams, resolveNodeHostExecutable, runNodePtyCommand } from "openclaw/plugin-sdk/node-host";
|
|
38
38
|
import { pruneMapToMaxSize } from "openclaw/plugin-sdk/collection-runtime";
|
|
39
39
|
//#region extensions/codex/src/jsonl-lines.ts
|
|
40
|
-
const JSONL_STREAM_THRESHOLD_BYTES =
|
|
41
|
-
const JSONL_READ_CHUNK_BYTES =
|
|
40
|
+
const JSONL_STREAM_THRESHOLD_BYTES = 4194304;
|
|
41
|
+
const JSONL_READ_CHUNK_BYTES = 1048576;
|
|
42
42
|
async function visitJsonlLines(file, visitor, chunkBytes = JSONL_READ_CHUNK_BYTES) {
|
|
43
43
|
let size;
|
|
44
44
|
try {
|
|
@@ -138,7 +138,7 @@ const CODEX_CLI_SESSIONS_LIST_COMMAND = "codex.cli.sessions.list";
|
|
|
138
138
|
const CODEX_CLI_SESSION_RESUME_COMMAND = "codex.cli.session.resume";
|
|
139
139
|
const DEFAULT_SESSION_LIMIT = 10;
|
|
140
140
|
const MAX_SESSION_LIMIT = 50;
|
|
141
|
-
const DEFAULT_RESUME_TIMEOUT_MS =
|
|
141
|
+
const DEFAULT_RESUME_TIMEOUT_MS = 12e5;
|
|
142
142
|
const SESSION_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
|
|
143
143
|
const activeResumeSessions = /* @__PURE__ */ new Set();
|
|
144
144
|
function createCodexCliSessionNodeHostCommands() {
|
|
@@ -529,7 +529,7 @@ function normalizeLimit$1(value) {
|
|
|
529
529
|
return typeof value === "number" && Number.isFinite(value) ? Math.min(MAX_SESSION_LIMIT, Math.max(1, Math.floor(value))) : DEFAULT_SESSION_LIMIT;
|
|
530
530
|
}
|
|
531
531
|
function normalizeTimeoutMs(value) {
|
|
532
|
-
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.min(
|
|
532
|
+
return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.min(36e5, Math.floor(value)) : DEFAULT_RESUME_TIMEOUT_MS;
|
|
533
533
|
}
|
|
534
534
|
function truncateText(value, max) {
|
|
535
535
|
if (value.length <= max) return value;
|
|
@@ -808,7 +808,7 @@ const MAX_SESSION_PREVIEW_LENGTH = 500;
|
|
|
808
808
|
const MAX_SESSION_KEY_LENGTH = 1024;
|
|
809
809
|
const MAX_METADATA_LENGTH = 500;
|
|
810
810
|
const MAX_ACTIVE_FLAGS = 16;
|
|
811
|
-
const MAX_TRANSCRIPT_PAGE_BYTES =
|
|
811
|
+
const MAX_TRANSCRIPT_PAGE_BYTES = 20971520;
|
|
812
812
|
var CatalogParamsError = class extends Error {};
|
|
813
813
|
function readControlCursor(value, label) {
|
|
814
814
|
if (value === void 0 || value === null) return;
|
|
@@ -1235,182 +1235,6 @@ async function createOrReuseNodeAdoptedSession(params) {
|
|
|
1235
1235
|
}
|
|
1236
1236
|
}
|
|
1237
1237
|
//#endregion
|
|
1238
|
-
//#region extensions/codex/src/session-catalog-terminal.ts
|
|
1239
|
-
const CODEX_TERMINAL_RESUME_COMMAND = "codex.terminal.resume.v1";
|
|
1240
|
-
function resolveCodexCatalogTerminalHome(sources) {
|
|
1241
|
-
const runtimeConfig = sources.getRuntimeConfig();
|
|
1242
|
-
if (!runtimeConfig) throw new Error("OpenClaw runtime config is unavailable");
|
|
1243
|
-
const agentDir = sources.source?.agentDir ?? (sources.agentId ? resolveAgentDir$1(runtimeConfig, sources.agentId) : resolveDefaultAgentDir(runtimeConfig));
|
|
1244
|
-
return resolveCodexAppServerLocalHomeDir(sources.source?.appServer.start ?? resolveCodexSupervisionAppServerRuntimeOptions({ pluginConfig: sources.getPluginConfig() }).start, agentDir);
|
|
1245
|
-
}
|
|
1246
|
-
function resolveLocalCodexTerminalExecutable(env = process.env) {
|
|
1247
|
-
return resolveLocalCodexTerminalResolution(env)?.executable;
|
|
1248
|
-
}
|
|
1249
|
-
function resolveLocalCodexTerminalResolution(env = process.env) {
|
|
1250
|
-
return resolveNodeHostExecutable("codex", {
|
|
1251
|
-
env,
|
|
1252
|
-
pathEnv: env.PATH ?? env.Path ?? "",
|
|
1253
|
-
strategy: "fallback"
|
|
1254
|
-
});
|
|
1255
|
-
}
|
|
1256
|
-
function codexNodeTerminalCapability(node) {
|
|
1257
|
-
const commands = node.invocableCommands ?? node.commands;
|
|
1258
|
-
return node.connected === true && commands?.includes("codex.terminal.resume.v1") === true ? { canOpenTerminalCodex: true } : {};
|
|
1259
|
-
}
|
|
1260
|
-
async function requireCatalogEligibleThread(control, threadId) {
|
|
1261
|
-
const cached = await findCatalogEligibleThread(control, threadId, false);
|
|
1262
|
-
if (cached) return cached;
|
|
1263
|
-
const refreshed = await findCatalogEligibleThread(control, threadId, true);
|
|
1264
|
-
if (refreshed) return refreshed;
|
|
1265
|
-
throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
|
|
1266
|
-
}
|
|
1267
|
-
async function findCatalogEligibleThread(control, threadId, forceRefresh) {
|
|
1268
|
-
let cursor;
|
|
1269
|
-
const seenCursors = /* @__PURE__ */ new Set();
|
|
1270
|
-
for (let pageIndex = 0; pageIndex < 100; pageIndex += 1) {
|
|
1271
|
-
const page = await control.listPage({
|
|
1272
|
-
limit: 100,
|
|
1273
|
-
...cursor ? { cursor } : {},
|
|
1274
|
-
...forceRefresh ? { forceRefresh: true } : {}
|
|
1275
|
-
});
|
|
1276
|
-
const candidate = page.sessions.find((session) => session.threadId === threadId);
|
|
1277
|
-
if (candidate) {
|
|
1278
|
-
if (isInteractiveThreadSource(candidate.source)) return candidate;
|
|
1279
|
-
throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
|
|
1280
|
-
}
|
|
1281
|
-
const nextCursor = page.nextCursor?.trim();
|
|
1282
|
-
if (!nextCursor) return;
|
|
1283
|
-
if (seenCursors.has(nextCursor)) throw new CatalogParamsError("Codex session eligibility could not be verified");
|
|
1284
|
-
seenCursors.add(nextCursor);
|
|
1285
|
-
cursor = nextCursor;
|
|
1286
|
-
}
|
|
1287
|
-
throw new CatalogParamsError("Codex session eligibility could not be verified");
|
|
1288
|
-
}
|
|
1289
|
-
function createCodexTerminalNodeHostCommand(bindRequest, configSources) {
|
|
1290
|
-
return {
|
|
1291
|
-
command: CODEX_TERMINAL_RESUME_COMMAND,
|
|
1292
|
-
cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
|
|
1293
|
-
dangerous: false,
|
|
1294
|
-
duplex: true,
|
|
1295
|
-
isAvailable: ({ env }) => Boolean(resolveNodeHostExecutable("codex", {
|
|
1296
|
-
env,
|
|
1297
|
-
pathEnv: env.PATH ?? env.Path ?? "",
|
|
1298
|
-
strategy: "direct"
|
|
1299
|
-
})),
|
|
1300
|
-
handle: async (paramsJSON, io) => {
|
|
1301
|
-
if (!io) throw new Error("Codex terminal command requires duplex transport");
|
|
1302
|
-
const request = bindRequest(paramsJSON);
|
|
1303
|
-
const resume = decodeNodePtyResumeParams(request.paramsJSON, (value) => {
|
|
1304
|
-
if (typeof value !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(value)) throw new CatalogParamsError("threadId must be a UUID");
|
|
1305
|
-
return value;
|
|
1306
|
-
});
|
|
1307
|
-
const record = await requireCatalogEligibleThread(request.control, resume.threadId);
|
|
1308
|
-
const resolution = resolveNodeHostExecutable("codex", {
|
|
1309
|
-
env: process.env,
|
|
1310
|
-
pathEnv: process.env.PATH ?? process.env.Path ?? "",
|
|
1311
|
-
strategy: "direct"
|
|
1312
|
-
});
|
|
1313
|
-
if (!resolution) throw new Error("Codex CLI is unavailable");
|
|
1314
|
-
return JSON.stringify(await runNodePtyCommand({
|
|
1315
|
-
file: resolution.executable,
|
|
1316
|
-
args: ["resume", resume.threadId],
|
|
1317
|
-
cwd: record.cwd,
|
|
1318
|
-
env: { CODEX_HOME: resolveCodexCatalogTerminalHome({
|
|
1319
|
-
...configSources,
|
|
1320
|
-
agentId: request.agentId
|
|
1321
|
-
}) },
|
|
1322
|
-
cols: resume.cols,
|
|
1323
|
-
rows: resume.rows
|
|
1324
|
-
}, io));
|
|
1325
|
-
}
|
|
1326
|
-
};
|
|
1327
|
-
}
|
|
1328
|
-
async function resolveNodeCatalogEligibleThread(params) {
|
|
1329
|
-
let cursor;
|
|
1330
|
-
const seenCursors = /* @__PURE__ */ new Set();
|
|
1331
|
-
for (let pageIndex = 0; pageIndex < 100; pageIndex += 1) {
|
|
1332
|
-
const raw = await params.runtime.nodes.invoke({
|
|
1333
|
-
nodeId: params.nodeId,
|
|
1334
|
-
command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
|
|
1335
|
-
params: {
|
|
1336
|
-
agentId: params.agentId,
|
|
1337
|
-
limit: 100,
|
|
1338
|
-
...cursor ? { cursor } : {}
|
|
1339
|
-
},
|
|
1340
|
-
timeoutMs: NODE_INVOKE_TIMEOUT_MS,
|
|
1341
|
-
scopes: ["operator.write"]
|
|
1342
|
-
});
|
|
1343
|
-
const page = params.parseCatalogPage(unwrapNodeInvokePayload(raw));
|
|
1344
|
-
const record = page.sessions.find((candidate) => candidate.threadId === params.threadId);
|
|
1345
|
-
if (record) {
|
|
1346
|
-
if (isInteractiveThreadSource(record.source)) return record;
|
|
1347
|
-
break;
|
|
1348
|
-
}
|
|
1349
|
-
const nextCursor = page.nextCursor?.trim();
|
|
1350
|
-
if (!nextCursor || seenCursors.has(nextCursor)) break;
|
|
1351
|
-
seenCursors.add(nextCursor);
|
|
1352
|
-
cursor = nextCursor;
|
|
1353
|
-
}
|
|
1354
|
-
throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
|
|
1355
|
-
}
|
|
1356
|
-
async function openCodexCatalogTerminal(params) {
|
|
1357
|
-
const title = `codex resume ${params.threadId.slice(0, 8)}…`;
|
|
1358
|
-
if (params.hostId === "gateway:local" || params.hostId.startsWith(`gateway:local:`)) {
|
|
1359
|
-
const record = await requireCatalogEligibleThread(params.control, params.threadId);
|
|
1360
|
-
const resolution = resolveLocalCodexTerminalResolution();
|
|
1361
|
-
if (!resolution) throw new CatalogParamsError("Codex CLI is unavailable");
|
|
1362
|
-
return {
|
|
1363
|
-
kind: "local",
|
|
1364
|
-
argv: [
|
|
1365
|
-
resolution.executable,
|
|
1366
|
-
"resume",
|
|
1367
|
-
params.threadId
|
|
1368
|
-
],
|
|
1369
|
-
...record.cwd ? { cwd: record.cwd } : {},
|
|
1370
|
-
env: { CODEX_HOME: resolveCodexCatalogTerminalHome(params) },
|
|
1371
|
-
...resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {},
|
|
1372
|
-
title
|
|
1373
|
-
};
|
|
1374
|
-
}
|
|
1375
|
-
if (!params.hostId.startsWith("node:")) throw new CatalogParamsError("hostId is invalid");
|
|
1376
|
-
const nodeId = params.hostId.slice(5);
|
|
1377
|
-
if (!(await params.api.runtime.nodes.list()).nodes.find((candidate) => {
|
|
1378
|
-
const commands = candidate.invocableCommands ?? candidate.commands;
|
|
1379
|
-
return candidate.nodeId === nodeId && candidate.connected === true && commands?.includes("codex.appServer.threads.list.v1") === true && commands.includes("codex.terminal.resume.v1");
|
|
1380
|
-
})) throw new CatalogParamsError("paired-node Codex terminal is unavailable");
|
|
1381
|
-
const record = await resolveNodeCatalogEligibleThread({
|
|
1382
|
-
agentId: params.agentId,
|
|
1383
|
-
runtime: params.api.runtime,
|
|
1384
|
-
nodeId,
|
|
1385
|
-
threadId: params.threadId,
|
|
1386
|
-
parseCatalogPage: params.parseCatalogPage
|
|
1387
|
-
});
|
|
1388
|
-
return {
|
|
1389
|
-
kind: "node",
|
|
1390
|
-
nodeId,
|
|
1391
|
-
command: CODEX_TERMINAL_RESUME_COMMAND,
|
|
1392
|
-
paramsJSON: JSON.stringify({
|
|
1393
|
-
agentId: params.agentId,
|
|
1394
|
-
threadId: params.threadId
|
|
1395
|
-
}),
|
|
1396
|
-
...record.cwd ? { cwd: record.cwd } : {},
|
|
1397
|
-
title
|
|
1398
|
-
};
|
|
1399
|
-
}
|
|
1400
|
-
async function startCodexCatalogTerminal(params) {
|
|
1401
|
-
if (params.nodeId) throw new CatalogParamsError("Paired-node Codex terminal start is unavailable; omit hostId to start on the gateway host");
|
|
1402
|
-
const resolution = resolveLocalCodexTerminalResolution();
|
|
1403
|
-
if (!resolution) throw new CatalogParamsError("Codex CLI is unavailable; install Codex or add codex to PATH, then try again");
|
|
1404
|
-
return {
|
|
1405
|
-
kind: "local",
|
|
1406
|
-
argv: [resolution.executable, ...params.initialMessage !== void 0 ? ["--", params.initialMessage] : []],
|
|
1407
|
-
cwd: params.cwd,
|
|
1408
|
-
env: { CODEX_HOME: resolveCodexCatalogTerminalHome(params) },
|
|
1409
|
-
...resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {},
|
|
1410
|
-
title: "codex"
|
|
1411
|
-
};
|
|
1412
|
-
}
|
|
1413
|
-
//#endregion
|
|
1414
1238
|
//#region extensions/codex/src/session-catalog-adoption.ts
|
|
1415
1239
|
const CODEX_SUPERVISION_SESSION_KEY_PREFIX = "harness:codex:supervision:";
|
|
1416
1240
|
const boundCatalogSessionId = (value) => boundedCatalogString(value, 256);
|
|
@@ -1635,7 +1459,7 @@ async function createOrReuseAdoptedSession(params) {
|
|
|
1635
1459
|
}
|
|
1636
1460
|
}
|
|
1637
1461
|
async function continueLocalCodexSessionInner(params) {
|
|
1638
|
-
await
|
|
1462
|
+
await params.control.requireEligibleThread(params.threadId);
|
|
1639
1463
|
const existing = await findAdoptedSessionEntry({
|
|
1640
1464
|
...params,
|
|
1641
1465
|
runtime: params.api.runtime
|
|
@@ -1728,8 +1552,8 @@ async function archiveLocalCodexSession(params) {
|
|
|
1728
1552
|
return await runSessionActionExclusive(sessionCatalogAdoptedSourceKey(params.hostId ?? "gateway:local", params.threadId), async () => {
|
|
1729
1553
|
return await params.bindingStore.withThreadArchiveFence(async () => {
|
|
1730
1554
|
const run = async (control) => {
|
|
1731
|
-
await requireCatalogEligibleThread(control, params.threadId);
|
|
1732
1555
|
await assertNoPendingSupervisionBranch(params);
|
|
1556
|
+
await control.requireEligibleThread(params.threadId);
|
|
1733
1557
|
const thread = await control.readThread(params.threadId, false);
|
|
1734
1558
|
if (thread.id !== params.threadId) throw new Error("Codex app-server returned a different thread than requested");
|
|
1735
1559
|
requireIdleThread(thread, "archive");
|
|
@@ -2013,6 +1837,154 @@ async function continueNodeCodexSession(params) {
|
|
|
2013
1837
|
});
|
|
2014
1838
|
}
|
|
2015
1839
|
//#endregion
|
|
1840
|
+
//#region extensions/codex/src/session-catalog-terminal.ts
|
|
1841
|
+
const CODEX_TERMINAL_RESUME_COMMAND = "codex.terminal.resume.v1";
|
|
1842
|
+
function resolveCodexCatalogTerminalHome(sources) {
|
|
1843
|
+
const runtimeConfig = sources.getRuntimeConfig();
|
|
1844
|
+
if (!runtimeConfig) throw new Error("OpenClaw runtime config is unavailable");
|
|
1845
|
+
const agentDir = sources.source?.agentDir ?? (sources.agentId ? resolveAgentDir$1(runtimeConfig, sources.agentId) : resolveDefaultAgentDir(runtimeConfig));
|
|
1846
|
+
const startOptions = sources.source?.appServer.start ?? resolveCodexSupervisionAppServerRuntimeOptions({ pluginConfig: sources.getPluginConfig() }).start;
|
|
1847
|
+
return resolveCodexAppServerLocalHomeDir(startOptions, agentDir);
|
|
1848
|
+
}
|
|
1849
|
+
function resolveLocalCodexTerminalExecutable(env = process.env) {
|
|
1850
|
+
return resolveLocalCodexTerminalResolution(env)?.executable;
|
|
1851
|
+
}
|
|
1852
|
+
function resolveLocalCodexTerminalResolution(env = process.env) {
|
|
1853
|
+
return resolveNodeHostExecutable("codex", {
|
|
1854
|
+
env,
|
|
1855
|
+
pathEnv: env.PATH ?? env.Path ?? "",
|
|
1856
|
+
strategy: "fallback"
|
|
1857
|
+
});
|
|
1858
|
+
}
|
|
1859
|
+
function codexNodeTerminalCapability(node) {
|
|
1860
|
+
const commands = node.invocableCommands ?? node.commands;
|
|
1861
|
+
return node.connected === true && commands?.includes("codex.terminal.resume.v1") === true ? { canOpenTerminalCodex: true } : {};
|
|
1862
|
+
}
|
|
1863
|
+
function createCodexTerminalNodeHostCommand(bindRequest, configSources) {
|
|
1864
|
+
return {
|
|
1865
|
+
command: CODEX_TERMINAL_RESUME_COMMAND,
|
|
1866
|
+
cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
|
|
1867
|
+
dangerous: false,
|
|
1868
|
+
duplex: true,
|
|
1869
|
+
isAvailable: ({ env }) => Boolean(resolveNodeHostExecutable("codex", {
|
|
1870
|
+
env,
|
|
1871
|
+
pathEnv: env.PATH ?? env.Path ?? "",
|
|
1872
|
+
strategy: "direct"
|
|
1873
|
+
})),
|
|
1874
|
+
handle: async (paramsJSON, io) => {
|
|
1875
|
+
if (!io) throw new Error("Codex terminal command requires duplex transport");
|
|
1876
|
+
const request = bindRequest(paramsJSON);
|
|
1877
|
+
const resume = decodeNodePtyResumeParams(request.paramsJSON, (value) => {
|
|
1878
|
+
if (typeof value !== "string" || !/^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu.test(value)) throw new CatalogParamsError("threadId must be a UUID");
|
|
1879
|
+
return value;
|
|
1880
|
+
});
|
|
1881
|
+
const record = await request.control.requireEligibleThread(resume.threadId);
|
|
1882
|
+
const resolution = resolveNodeHostExecutable("codex", {
|
|
1883
|
+
env: process.env,
|
|
1884
|
+
pathEnv: process.env.PATH ?? process.env.Path ?? "",
|
|
1885
|
+
strategy: "direct"
|
|
1886
|
+
});
|
|
1887
|
+
if (!resolution) throw new Error("Codex CLI is unavailable");
|
|
1888
|
+
return JSON.stringify(await runNodePtyCommand({
|
|
1889
|
+
file: resolution.executable,
|
|
1890
|
+
args: ["resume", resume.threadId],
|
|
1891
|
+
...record.cwd ? { cwd: record.cwd } : {},
|
|
1892
|
+
env: { CODEX_HOME: resolveCodexCatalogTerminalHome({
|
|
1893
|
+
...configSources,
|
|
1894
|
+
agentId: request.agentId
|
|
1895
|
+
}) },
|
|
1896
|
+
cols: resume.cols,
|
|
1897
|
+
rows: resume.rows
|
|
1898
|
+
}, io));
|
|
1899
|
+
}
|
|
1900
|
+
};
|
|
1901
|
+
}
|
|
1902
|
+
async function resolveNodeCatalogEligibleThread(params) {
|
|
1903
|
+
let cursor;
|
|
1904
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
1905
|
+
for (let pageIndex = 0; pageIndex < 100; pageIndex += 1) {
|
|
1906
|
+
const raw = await params.runtime.nodes.invoke({
|
|
1907
|
+
nodeId: params.nodeId,
|
|
1908
|
+
command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
|
|
1909
|
+
params: {
|
|
1910
|
+
agentId: params.agentId,
|
|
1911
|
+
limit: 100,
|
|
1912
|
+
...cursor ? { cursor } : {}
|
|
1913
|
+
},
|
|
1914
|
+
timeoutMs: NODE_INVOKE_TIMEOUT_MS,
|
|
1915
|
+
scopes: ["operator.write"]
|
|
1916
|
+
});
|
|
1917
|
+
const page = params.parseCatalogPage(unwrapNodeInvokePayload(raw));
|
|
1918
|
+
const record = page.sessions.find((candidate) => candidate.threadId === params.threadId);
|
|
1919
|
+
if (record) {
|
|
1920
|
+
if (isInteractiveThreadSource(record.source)) return record;
|
|
1921
|
+
break;
|
|
1922
|
+
}
|
|
1923
|
+
const nextCursor = page.nextCursor?.trim();
|
|
1924
|
+
if (!nextCursor || seenCursors.has(nextCursor)) break;
|
|
1925
|
+
seenCursors.add(nextCursor);
|
|
1926
|
+
cursor = nextCursor;
|
|
1927
|
+
}
|
|
1928
|
+
throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
|
|
1929
|
+
}
|
|
1930
|
+
async function openCodexCatalogTerminal(params) {
|
|
1931
|
+
const title = `codex resume ${params.threadId.slice(0, 8)}…`;
|
|
1932
|
+
if (params.hostId === "gateway:local" || params.hostId.startsWith(`gateway:local:`)) {
|
|
1933
|
+
const record = await params.control.requireEligibleThread(params.threadId);
|
|
1934
|
+
const resolution = resolveLocalCodexTerminalResolution();
|
|
1935
|
+
if (!resolution) throw new CatalogParamsError("Codex CLI is unavailable");
|
|
1936
|
+
return {
|
|
1937
|
+
kind: "local",
|
|
1938
|
+
argv: [
|
|
1939
|
+
resolution.executable,
|
|
1940
|
+
"resume",
|
|
1941
|
+
params.threadId
|
|
1942
|
+
],
|
|
1943
|
+
...record.cwd ? { cwd: record.cwd } : {},
|
|
1944
|
+
env: { CODEX_HOME: resolveCodexCatalogTerminalHome(params) },
|
|
1945
|
+
...resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {},
|
|
1946
|
+
title
|
|
1947
|
+
};
|
|
1948
|
+
}
|
|
1949
|
+
if (!params.hostId.startsWith("node:")) throw new CatalogParamsError("hostId is invalid");
|
|
1950
|
+
const nodeId = params.hostId.slice(5);
|
|
1951
|
+
if (!(await params.api.runtime.nodes.list()).nodes.find((candidate) => {
|
|
1952
|
+
const commands = candidate.invocableCommands ?? candidate.commands;
|
|
1953
|
+
return candidate.nodeId === nodeId && candidate.connected === true && commands?.includes("codex.appServer.threads.list.v1") === true && commands.includes("codex.terminal.resume.v1");
|
|
1954
|
+
})) throw new CatalogParamsError("paired-node Codex terminal is unavailable");
|
|
1955
|
+
const record = await resolveNodeCatalogEligibleThread({
|
|
1956
|
+
agentId: params.agentId,
|
|
1957
|
+
runtime: params.api.runtime,
|
|
1958
|
+
nodeId,
|
|
1959
|
+
threadId: params.threadId,
|
|
1960
|
+
parseCatalogPage: params.parseCatalogPage
|
|
1961
|
+
});
|
|
1962
|
+
return {
|
|
1963
|
+
kind: "node",
|
|
1964
|
+
nodeId,
|
|
1965
|
+
command: CODEX_TERMINAL_RESUME_COMMAND,
|
|
1966
|
+
paramsJSON: JSON.stringify({
|
|
1967
|
+
agentId: params.agentId,
|
|
1968
|
+
threadId: params.threadId
|
|
1969
|
+
}),
|
|
1970
|
+
...record.cwd ? { cwd: record.cwd } : {},
|
|
1971
|
+
title
|
|
1972
|
+
};
|
|
1973
|
+
}
|
|
1974
|
+
async function startCodexCatalogTerminal(params) {
|
|
1975
|
+
if (params.nodeId) throw new CatalogParamsError("Paired-node Codex terminal start is unavailable; omit hostId to start on the gateway host");
|
|
1976
|
+
const resolution = resolveLocalCodexTerminalResolution();
|
|
1977
|
+
if (!resolution) throw new CatalogParamsError("Codex CLI is unavailable; install Codex or add codex to PATH, then try again");
|
|
1978
|
+
return {
|
|
1979
|
+
kind: "local",
|
|
1980
|
+
argv: [resolution.executable, ...params.initialMessage !== void 0 ? ["--", params.initialMessage] : []],
|
|
1981
|
+
cwd: params.cwd,
|
|
1982
|
+
env: { CODEX_HOME: resolveCodexCatalogTerminalHome(params) },
|
|
1983
|
+
...resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {},
|
|
1984
|
+
title: "codex"
|
|
1985
|
+
};
|
|
1986
|
+
}
|
|
1987
|
+
//#endregion
|
|
2016
1988
|
//#region extensions/codex/src/session-catalog-listing.ts
|
|
2017
1989
|
async function listVisiblePage(params) {
|
|
2018
1990
|
const excluded = params.excludedThreadIds;
|
|
@@ -2231,7 +2203,7 @@ function createCodexSessionCatalogNodeHostCommands(controlFactory, configSources
|
|
|
2231
2203
|
const request = bindRequest(paramsJSON);
|
|
2232
2204
|
const action = readNodeTranscriptParams(request.params);
|
|
2233
2205
|
try {
|
|
2234
|
-
await
|
|
2206
|
+
await request.control.requireEligibleThread(action.threadId);
|
|
2235
2207
|
const page = parseTranscriptPage(await request.control.listTurnPage({
|
|
2236
2208
|
threadId: action.threadId,
|
|
2237
2209
|
limit: action.limit,
|
|
@@ -2276,7 +2248,7 @@ function flattenTranscriptPageDesc(page) {
|
|
|
2276
2248
|
/** Reads the persisted transcript for a Gateway-local or paired-node Codex session. */
|
|
2277
2249
|
async function readCodexSessionTranscript(params) {
|
|
2278
2250
|
if (params.source || params.hostId === "gateway:local") {
|
|
2279
|
-
await
|
|
2251
|
+
await params.control.requireEligibleThread(params.threadId);
|
|
2280
2252
|
const listParams = {
|
|
2281
2253
|
threadId: params.threadId,
|
|
2282
2254
|
limit: params.limit,
|
|
@@ -2615,10 +2587,10 @@ function createCodexCatalogRequestSnapshot(requestTimeoutMs, request) {
|
|
|
2615
2587
|
listThreads: (params, timeoutMs) => request(CODEX_CONTROL_METHODS.listThreads, params, timeoutMs),
|
|
2616
2588
|
listThreadTurns: (params) => request(CODEX_CONTROL_METHODS.listThreadTurns, params),
|
|
2617
2589
|
forkThread: (params) => request(CODEX_CONTROL_METHODS.forkThread, assertCodexThreadForkParams(params)),
|
|
2618
|
-
readThread: async (threadId, includeTurns) => (await request(CODEX_CONTROL_METHODS.readThread, {
|
|
2590
|
+
readThread: async (threadId, includeTurns, timeoutMs) => (await request(CODEX_CONTROL_METHODS.readThread, {
|
|
2619
2591
|
threadId,
|
|
2620
2592
|
includeTurns
|
|
2621
|
-
})).thread,
|
|
2593
|
+
}, timeoutMs)).thread,
|
|
2622
2594
|
archiveThread: async (threadId) => {
|
|
2623
2595
|
await request(CODEX_CONTROL_METHODS.archiveThread, { threadId });
|
|
2624
2596
|
}
|
|
@@ -2629,6 +2601,58 @@ function createCodexSessionCatalogControlFromRequests(params) {
|
|
|
2629
2601
|
...params.clientId ? { clientId: params.clientId } : {},
|
|
2630
2602
|
...params.connectionFingerprint ? { connectionFingerprint: params.connectionFingerprint } : {},
|
|
2631
2603
|
withPinnedConnection: params.withPinnedConnection,
|
|
2604
|
+
async requireEligibleThread(threadId) {
|
|
2605
|
+
const requests = params.createRequestSnapshot();
|
|
2606
|
+
const deadline = params.now() + requests.requestTimeoutMs;
|
|
2607
|
+
const unverified = () => new CatalogParamsError("Codex session eligibility could not be verified. Refresh the catalog and verify the session in its native Codex home before retrying.");
|
|
2608
|
+
const remaining = () => {
|
|
2609
|
+
const timeoutMs = Math.ceil(deadline - params.now());
|
|
2610
|
+
if (timeoutMs <= 0) throw unverified();
|
|
2611
|
+
return timeoutMs;
|
|
2612
|
+
};
|
|
2613
|
+
const verify = async () => {
|
|
2614
|
+
if (params.sourceHomeId && await params.managedThreads?.has(params.sourceHomeId, threadId)) throw unverified();
|
|
2615
|
+
const root = params.localSessionsRoot;
|
|
2616
|
+
const thread = root ? await requests.readThread(threadId, false, remaining()) : void 0;
|
|
2617
|
+
if (root && (!thread || thread.id !== threadId || !isInteractiveThreadSource(thread.source))) throw unverified();
|
|
2618
|
+
let cursor;
|
|
2619
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
2620
|
+
for (let pageIndex = 0; pageIndex < 100; pageIndex += 1) {
|
|
2621
|
+
const page = await requests.listThreads({
|
|
2622
|
+
archived: false,
|
|
2623
|
+
limit: 100,
|
|
2624
|
+
modelProviders: [],
|
|
2625
|
+
sortKey: root ? "recency_at" : "updated_at",
|
|
2626
|
+
sortDirection: "desc",
|
|
2627
|
+
...root ? {
|
|
2628
|
+
useStateDbOnly: true,
|
|
2629
|
+
...thread?.cwd ? { cwd: thread.cwd } : {}
|
|
2630
|
+
} : {},
|
|
2631
|
+
...cursor ? { cursor } : {}
|
|
2632
|
+
}, remaining());
|
|
2633
|
+
remaining();
|
|
2634
|
+
const candidate = page.data.find((value) => value.id === threadId);
|
|
2635
|
+
if (candidate) {
|
|
2636
|
+
if (!isInteractiveThreadSource(candidate.source)) throw unverified();
|
|
2637
|
+
if (root && thread) {
|
|
2638
|
+
const rolloutPath = thread.path;
|
|
2639
|
+
if (!rolloutPath || !candidate.path || rolloutPath.replace(/\.zst$/u, "") !== candidate.path.replace(/\.zst$/u, "")) throw unverified();
|
|
2640
|
+
const metadata = await readCodexSessionMeta(root, rolloutPath, threadId);
|
|
2641
|
+
remaining();
|
|
2642
|
+
if (!metadata || !isInteractiveThreadSource(metadata.source) || metadata.originator === "openclaw") throw unverified();
|
|
2643
|
+
return thread;
|
|
2644
|
+
}
|
|
2645
|
+
return candidate;
|
|
2646
|
+
}
|
|
2647
|
+
const nextCursor = readControlCursor(page.nextCursor, "next response");
|
|
2648
|
+
if (!nextCursor || seenCursors.has(nextCursor)) throw unverified();
|
|
2649
|
+
seenCursors.add(nextCursor);
|
|
2650
|
+
cursor = nextCursor;
|
|
2651
|
+
}
|
|
2652
|
+
throw unverified();
|
|
2653
|
+
};
|
|
2654
|
+
return await withTimeout(verify(), requests.requestTimeoutMs, "Codex session eligibility could not be verified", unverified);
|
|
2655
|
+
},
|
|
2632
2656
|
async listPage(pageParams) {
|
|
2633
2657
|
const limit = normalizeLimit(pageParams.limit, "limit");
|
|
2634
2658
|
const search = pageParams.searchTerm?.trim().toLocaleLowerCase() || void 0;
|
|
@@ -2768,6 +2792,8 @@ function createCodexSessionCatalogControl(params) {
|
|
|
2768
2792
|
connectionFingerprint: buildCodexAppServerConnectionFingerprint(runtime, agentDir),
|
|
2769
2793
|
createRequestSnapshot: () => requests,
|
|
2770
2794
|
...source?.localSessionsRoot ? { localSessionsRoot: source.localSessionsRoot } : {},
|
|
2795
|
+
sourceHomeId: source?.sourceHomeId,
|
|
2796
|
+
managedThreads: params.managedThreads,
|
|
2771
2797
|
now,
|
|
2772
2798
|
withPinnedConnection: async (nestedRun) => await nestedRun(pinnedControl)
|
|
2773
2799
|
});
|
|
@@ -2784,6 +2810,7 @@ function createCodexSessionCatalogControl(params) {
|
|
|
2784
2810
|
});
|
|
2785
2811
|
return {
|
|
2786
2812
|
...control,
|
|
2813
|
+
requireEligibleThread: (threadId) => withPinnedConnection((pinned) => pinned.requireEligibleThread(threadId)),
|
|
2787
2814
|
async listPage(pageParams) {
|
|
2788
2815
|
const runtimeConfig = params.getRuntimeConfig();
|
|
2789
2816
|
if (!runtimeConfig) return await control.listPage(pageParams);
|
|
@@ -2794,7 +2821,7 @@ function createCodexSessionCatalogControl(params) {
|
|
|
2794
2821
|
}
|
|
2795
2822
|
const key = codexCatalogPageCacheKey(pageParams, agentId, source);
|
|
2796
2823
|
const cached = cache.get(key);
|
|
2797
|
-
if (
|
|
2824
|
+
if (cached) {
|
|
2798
2825
|
cache.delete(key);
|
|
2799
2826
|
cache.set(key, cached);
|
|
2800
2827
|
if (cached.expiresAt > now()) return cached.value ?? await cached.page;
|
|
@@ -2825,7 +2852,7 @@ function createCodexSessionCatalogControl(params) {
|
|
|
2825
2852
|
});
|
|
2826
2853
|
else cache.delete(key);
|
|
2827
2854
|
};
|
|
2828
|
-
if (
|
|
2855
|
+
if (staleValue) {
|
|
2829
2856
|
page.then(settle, restore);
|
|
2830
2857
|
return staleValue;
|
|
2831
2858
|
}
|
|
@@ -3000,7 +3027,7 @@ function registerCodexSessionCatalog(params) {
|
|
|
3000
3027
|
if (!isLocalCodexCatalogHost(request.hostId)) throw new CatalogParamsError("Codex session catalog hostId is invalid");
|
|
3001
3028
|
const { agentId, source, control } = bindLocalRequest(request);
|
|
3002
3029
|
let upstreamBaseline;
|
|
3003
|
-
|
|
3030
|
+
const continued = await continueLocalCodexSession({
|
|
3004
3031
|
agentId,
|
|
3005
3032
|
api: params.api,
|
|
3006
3033
|
bindingStore: params.bindingStore,
|
|
@@ -3013,7 +3040,8 @@ function registerCodexSessionCatalog(params) {
|
|
|
3013
3040
|
onContinued: (baseline) => {
|
|
3014
3041
|
upstreamBaseline = baseline;
|
|
3015
3042
|
}
|
|
3016
|
-
})
|
|
3043
|
+
});
|
|
3044
|
+
return codexUpstreamContinueResult(continued.sessionKey, request.threadId, upstreamBaseline);
|
|
3017
3045
|
},
|
|
3018
3046
|
checkUpstreamActivity: (probes, policy) => checkUpstreamActivity(probes.filter((probe) => !isLocalCodexCatalogHost(probe.hostId) || policy?.allowProcessHomeFallback !== false || catalogHomes(probe.agentId, false).some((home) => home.hostId === probe.hostId))),
|
|
3019
3047
|
archive: async (request) => {
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
import { Ht as isJsonObject } from "./shared-client-
|
|
1
|
+
import { Ht as isJsonObject } from "./shared-client-B1tT5U6r.js";
|
|
2
2
|
import path from "node:path";
|
|
3
3
|
import { createHash } from "node:crypto";
|
|
4
4
|
import fsSync from "node:fs";
|
|
5
5
|
import { root } from "openclaw/plugin-sdk/file-access-runtime";
|
|
6
6
|
import { createZstdDecompress } from "node:zlib";
|
|
7
7
|
//#region extensions/codex/src/session-catalog-provenance.ts
|
|
8
|
-
const MAX_SESSION_META_BYTES =
|
|
9
|
-
const SESSION_META_READ_CHUNK_BYTES =
|
|
8
|
+
const MAX_SESSION_META_BYTES = 1048576;
|
|
9
|
+
const SESSION_META_READ_CHUNK_BYTES = 65536;
|
|
10
10
|
const MAX_PROVENANCE_CACHE_ENTRIES = 2e4;
|
|
11
11
|
const provenanceByPath = /* @__PURE__ */ new Map();
|
|
12
12
|
function cacheProvenance(key, value) {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import "./session-catalog-
|
|
1
|
+
import "./session-catalog-eMhVm0Ql.js";
|
|
2
2
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
3
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
4
4
|
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|