@openclaw/codex 2026.9.6 → 2026.9.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/README.md +2 -0
- package/assets/icon.png +0 -0
- package/dist/.setup/{account-usage-runtime-Eem_WGqY.mjs → account-usage-runtime-DFhbh1zz.mjs} +5 -5
- package/dist/.setup/{apply-DDOi8uNx.mjs → apply-D3GcSoSa.mjs} +22 -36
- package/dist/.setup/{attempt-client-cleanup-CEv1cKwF.mjs → attempt-client-cleanup-DOP-cW5j.mjs} +128 -37
- package/dist/.setup/attempt-workspace-context-C5HigshI.mjs +164 -0
- package/dist/.setup/{auth-binding-DhLWa_7K.mjs → auth-binding-BLWz7stm.mjs} +14 -1
- package/dist/.setup/{auth-cache-key-B2mpaI9D.mjs → auth-cache-key-Dbvq-QgB.mjs} +36 -34
- package/dist/.setup/{auth-profile-WqZtZfXN.mjs → auth-profile-B0okYl2D.mjs} +1 -2
- package/dist/.setup/auth-start-options-BPIPeEX8.mjs +44 -0
- package/dist/.setup/{binding-connection-ThoatDcb.mjs → binding-connection-DTtN1KrX.mjs} +2 -2
- package/dist/.setup/{binding-connection.runtime-yoHrABt-.mjs → binding-connection.runtime-6TpgD1M6.mjs} +4 -4
- package/dist/.setup/{bounded-turn-B2HScEgT.mjs → bounded-turn-CbjoN2OW.mjs} +15 -18
- package/dist/.setup/bounded-turn-isolation-B8K_ylqk.mjs +14 -0
- package/dist/.setup/{build-state-C7EnDVgr.mjs → build-state-Da1_z0kd.mjs} +1 -1
- package/dist/.setup/{capabilities-CDXOOFdZ.mjs → capabilities-B3WEZl4e.mjs} +2 -10
- package/dist/.setup/{client-Cs08OXVQ.mjs → client-N0JpgSzF.mjs} +138 -399
- package/dist/.setup/{client-catalog-response-BMgt_4q4.mjs → client-catalog-response-5HHLdcde.mjs} +1 -1
- package/dist/.setup/{command-dispatch-B4JuOsOk.mjs → command-dispatch-BeAoaovI.mjs} +5 -8
- package/dist/.setup/{command-formatters-Bmqvr9tO.mjs → command-formatters-R3ckE3Co.mjs} +29 -61
- package/dist/.setup/{command-handlers-DW7Lx9oH.mjs → command-handlers-ylTMS00z.mjs} +222 -343
- package/dist/.setup/{command-rpc-DixIj3HW.mjs → command-rpc-CGJGUQ6Y.mjs} +15 -18
- package/dist/.setup/compact-C2WamavS.mjs +776 -0
- package/dist/.setup/{config-BoTP_mrL.mjs → config-DKhXquav.mjs} +26 -28
- package/dist/.setup/{config-options-BvaRs51b.mjs → config-options-CzyWLTJt.mjs} +24 -37
- package/dist/.setup/{config-parsing-CcB9iPoq.mjs → config-parsing-b088LyhT.mjs} +57 -60
- package/dist/.setup/{config-runtime-C8Rw1m1m.mjs → config-runtime-C0NbLms1.mjs} +2 -2
- package/dist/.setup/{config-security-BEReZ6go.mjs → config-security-CE-FcGw9.mjs} +32 -111
- package/dist/.setup/{config-utils-DujwEnhg.mjs → config-utils-D0CXecki.mjs} +3 -13
- package/dist/.setup/context-engine-projection-PezSESth.mjs +387 -0
- package/dist/.setup/{conversation-binding-DP-gMrBP.mjs → conversation-binding-3Min8qvP.mjs} +67 -90
- package/dist/.setup/{conversation-binding-data-CrcyZk6O.mjs → conversation-binding-data-C746z5Pn.mjs} +8 -12
- package/dist/.setup/{conversation-control-uK9Jomlc.mjs → conversation-control-CEP8X5JC.mjs} +8 -8
- package/dist/.setup/{cyber-failover-DYwbmf1o.mjs → cyber-failover-XV0nNRZu.mjs} +1 -1
- package/dist/.setup/{cyber-failover-notice-e9G3J9-e.mjs → cyber-failover-notice-RNpGpTyP.mjs} +1 -1
- package/dist/.setup/{dynamic-tools-BDXl-8Cw.mjs → dynamic-tools-DzlsLUuS.mjs} +2305 -2606
- package/dist/.setup/{effective-mcp-catalog-CvnvnGIe.mjs → effective-mcp-catalog-CxUtC-xG.mjs} +8 -17
- package/dist/.setup/{ephemeral-turn-poidXgek.mjs → ephemeral-turn-CDsPJOa2.mjs} +3 -3
- package/dist/.setup/event-projector-assistant-message-CigreO4K.mjs +69 -0
- package/dist/.setup/{event-projector-usage-CnBS8Wa3.mjs → event-projector-usage-03R0I2dM.mjs} +3 -25
- package/dist/.setup/event-projector-values-DJSz8BTk.mjs +106 -0
- package/dist/.setup/incognito-session-DWYapfwf.mjs +2 -0
- package/dist/.setup/{inference-context-D96l9-ew.mjs → inference-context-D-9gWlTR.mjs} +16 -18
- package/dist/.setup/inference-dispatch-CMZtjQyz.mjs +359 -0
- package/dist/.setup/inference-metadata-CgIf7sOx.mjs +81 -0
- package/dist/.setup/{inference-proxy-b-aJMSxm.mjs → inference-proxy-DhcXOgUE.mjs} +174 -214
- package/dist/.setup/{isolated-completion-BIZFhTNG.mjs → isolated-completion-Dm3PzxJk.mjs} +9 -12
- package/dist/.setup/{managed-binary-BnshlFag.mjs → managed-binary-kiWRhNRE.mjs} +8 -12
- package/dist/.setup/{model-catalog-CfXJf9Ay.mjs → model-catalog-PAuZgJC6.mjs} +11 -10
- package/dist/.setup/model-runtime-BdqzOMkU.mjs +11 -0
- package/dist/.setup/{models-KnqBv0hE.mjs → models-DHXZtVVk.mjs} +9 -18
- package/dist/.setup/{native-auth-rWbGbMn3.mjs → native-auth-CuG53tu4.mjs} +4 -4
- package/dist/.setup/{native-execution-policy-umd0tgh4.mjs → native-execution-policy-BxZJy5mP.mjs} +5 -30
- package/dist/.setup/{native-subagent-monitor-D3filLY2.mjs → native-subagent-monitor-Dpsmf2wz.mjs} +4395 -3609
- package/dist/.setup/native-subagent-pending-assignments-DwkCzLvD.mjs +203 -0
- package/dist/.setup/native-task-assignments-DMQ0g3hu.mjs +194 -0
- package/dist/.setup/{node-cli-sessions-r3avj02l.mjs → node-cli-sessions-HC4W6FLI.mjs} +19 -49
- package/dist/.setup/{node-exec-server.runtime-BDwWXVpK.mjs → node-exec-server.runtime-BgBfWQqo.mjs} +3 -6
- package/dist/.setup/{plan-CN3VwfNU.mjs → plan-Y-QIvrKB.mjs} +49 -92
- package/dist/.setup/{plugin-activation-DT3MNtqj.mjs → plugin-activation-cNHRfaxU.mjs} +8 -36
- package/dist/.setup/{plugin-app-cache-key-B2CsSdnV.mjs → plugin-app-cache-key-BL9B5H0L.mjs} +6 -23
- package/dist/.setup/{plugin-inventory-BoRei8Z4.mjs → plugin-inventory-Cky2XJUw.mjs} +21 -21
- package/dist/.setup/{plugin-marketplace-discovery-CDOi8IFs.mjs → plugin-marketplace-discovery-D_dV9FXa.mjs} +18 -24
- package/dist/.setup/{plugin-metadata-cache-Ctmo83k_.mjs → plugin-metadata-cache-DsjsL1dr.mjs} +115 -175
- package/dist/.setup/{provider-BOsxQHOM.mjs → provider-DH8NSzGt.mjs} +11 -14
- package/dist/.setup/{provider-capabilities-BfE88FZ5.mjs → provider-capabilities-CAxoF-X1.mjs} +13 -18
- package/dist/.setup/{rate-limits-CMU3DUD0.mjs → rate-limits-B7-X2TgG.mjs} +9 -31
- package/dist/.setup/{request-D2L0zMrq.mjs → request-BHZ1nz8d.mjs} +7 -6
- package/dist/.setup/responses-oauth-twnuTaAa.mjs +93 -0
- package/dist/.setup/rpc-error-BlD2vuzn.mjs +31 -0
- package/dist/.setup/{run-attempt-BHu11r7h.mjs → run-attempt-D8RZUOzY.mjs} +1035 -1023
- package/dist/.setup/{run-attempt-lifecycle-B7JbY4-F.mjs → run-attempt-lifecycle-C-6O3Exn.mjs} +10 -24
- package/dist/.setup/{runtime-artifact-CLZ8udh-.mjs → runtime-artifact-DDQ-HGXf.mjs} +16 -4
- package/dist/.setup/runtime-artifact-connection-D68qQn1m.mjs +78 -0
- package/dist/.setup/sandbox-guard-DjCz2eOw.mjs +126 -0
- package/dist/.setup/scope-DOC1Xjc8.mjs +6 -0
- package/dist/.setup/session-binding-DGCYAfvD.mjs +443 -0
- package/dist/.setup/{session-binding-record-BGoz8wOK.mjs → session-binding-record-Oe9L-CNY.mjs} +52 -130
- package/dist/.setup/{session-binding-sidecars-BlB5EvIS.mjs → session-binding-sidecars-jo6H8dFr.mjs} +196 -17
- package/dist/.setup/{session-catalog-Pno1xGcl.mjs → session-catalog-4sCdv5qx.mjs} +170 -324
- package/dist/.setup/{session-catalog-adoption-BI6UTDZT.mjs → session-catalog-adoption-BU_pHWG7.mjs} +7 -6
- package/dist/.setup/{session-catalog-archive-lHBqzhaO.mjs → session-catalog-archive-spHfihri.mjs} +6 -6
- package/dist/.setup/session-catalog-events-DePDzzjc.mjs +139 -0
- package/dist/.setup/session-catalog-home-id-vlih0B_g.mjs +22 -0
- package/dist/.setup/{session-catalog-index-B9_VQIUz.mjs → session-catalog-index-CZvDzC6z.mjs} +126 -122
- package/dist/.setup/{session-catalog-index-order-hcdz07yN.mjs → session-catalog-index-order-BcQpHks3.mjs} +1 -1
- package/dist/.setup/{session-catalog-index-state-Dgh8ORJm.mjs → session-catalog-index-state-TeO7EyO-.mjs} +3 -2
- package/dist/.setup/session-catalog-limits-DDxOsQeC.mjs +14 -0
- package/dist/.setup/session-catalog-list-request-CvtxrYSe.mjs +170 -0
- package/dist/.setup/session-catalog-native-projection-DjhwGL6x.mjs +178 -0
- package/dist/.setup/{session-catalog-node-adoption-ITddWx_X.mjs → session-catalog-node-adoption-DgXvSGu0.mjs} +10 -27
- package/dist/.setup/{session-catalog-node-continue-6g6qi4A9.mjs → session-catalog-node-continue-DjKXHBbi.mjs} +8 -10
- package/dist/.setup/session-catalog-node-lookup-CtAXI5W5.mjs +56 -0
- package/dist/.setup/{session-catalog-native-projection-DowriLid.mjs → session-catalog-parsing-CPGaPYr-.mjs} +11 -194
- package/dist/.setup/{session-catalog-projection-zK_PUsiE.mjs → session-catalog-projection-Cr5qP5Dj.mjs} +6 -4
- package/dist/.setup/session-catalog-provenance-DoAvktcj.mjs +95 -0
- package/dist/.setup/{session-cli-irrD-uo7.mjs → session-cli-Cn_nCqfq.mjs} +9 -22
- package/dist/.setup/{session-history-BrqhSCf9.mjs → session-history-D83lJWHG.mjs} +4 -6
- package/dist/.setup/{session-history-import-D-3wAgOP.mjs → session-history-import-WhX-X33a.mjs} +7 -10
- package/dist/.setup/session-history-read-Ov3StuL4.mjs +133 -0
- package/dist/.setup/{session-history.worker-CaCh0xF_.mjs → session-history.worker-MnPKncqP.mjs} +9 -5
- package/dist/.setup/session-initialization-6aveB9qb.mjs +22 -0
- package/dist/.setup/{session-permission-policy-BI1QK_98.mjs → session-permission-policy-Ci_fVX6y.mjs} +4 -8
- package/dist/.setup/{session-retirement-BH-S6qkJ.mjs → session-retirement-qMTxkNx2.mjs} +17 -17
- package/dist/.setup/{settled-turn-context-fmwouT5I.mjs → settled-turn-context-D4yj4rxf.mjs} +1 -1
- package/dist/.setup/{settled-turn-finalizer-DiAi6Kx6.mjs → settled-turn-finalizer-BsvEabkw.mjs} +14 -10
- package/dist/.setup/{shared-client-DA4VR4Eb.mjs → shared-client-DqyTMYug.mjs} +783 -412
- package/dist/.setup/shared-client-lifecycle-DJIgqgMw.mjs +153 -0
- package/dist/.setup/{side-question-BJ1wSDcB.mjs → side-question-C4kCmQy1.mjs} +79 -143
- package/dist/.setup/{source-CUzJq5WN.mjs → source-CS_7GFJZ.mjs} +80 -137
- package/dist/.setup/{thread-lifecycle-B3mfz1TG.mjs → thread-lifecycle-DPflntEJ.mjs} +294 -737
- package/dist/.setup/{incognito-session-uhrBF6wJ.mjs → thread-ownership-queue-Dp24d7-F.mjs} +1 -2
- package/dist/.setup/{thread-ownership-DcTtAcXj.mjs → thread-ownership-roNP0l1c.mjs} +45 -10
- package/dist/.setup/{thread-policy-DGuQsuFC.mjs → thread-policy-DTd-DtkX.mjs} +46 -7
- package/dist/.setup/{thread-requests-BLvGkP2R.mjs → thread-requests-B_bRnMGN.mjs} +199 -302
- package/dist/.setup/{thread-resume-DIBXwOpE.mjs → thread-resume-CdDaoc7T.mjs} +6 -6
- package/dist/.setup/{timeout-C910MdAB.mjs → timeout-CXOfNoaX.mjs} +1 -35
- package/dist/.setup/{transcript-history-projection-ZZpkFkJ_.mjs → transcript-history-projection-DRSifI-1.mjs} +17 -89
- package/dist/.setup/{transcript-mirror-attestation-CzM-94NC.mjs → transcript-mirror-attestation-YSegaktH.mjs} +3 -4
- package/dist/.setup/{transcript-mirror-BtHDBp1G.mjs → transcript-mirror-kxmCYsuF.mjs} +7 -9
- package/dist/.setup/{transport-stdio-h2VHOskC.mjs → transport-stdio-Bdegpn2V.mjs} +5 -22
- package/dist/.setup/transport-websocket-BTBE-LD9.mjs +211 -0
- package/dist/.setup/{upstream-prompt-provenance-LphB8slG.mjs → upstream-prompt-provenance-fXkKbPVC.mjs} +3 -9
- package/dist/.setup/{upstream-session-fork-BUr4OUbC.mjs → upstream-session-fork-CBeVjBpT.mjs} +23 -23
- package/dist/.setup/{usage-BML0r-ua.mjs → usage-BMzNxeR_.mjs} +4 -4
- package/dist/.setup/{usage-limit-error-DUMbefVY.mjs → usage-limit-error-QXerDo3i.mjs} +4 -19
- package/dist/.setup/{web-search-provider.runtime-CDKlN-Rv.mjs → web-search-provider.runtime-P77OUeoo.mjs} +8 -19
- package/dist/api.js +9 -11
- package/dist/catalog-page.worker.js +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/doctor-contract-api.js +50 -8
- package/dist/harness.js +344 -1
- package/dist/index.js +193 -245
- package/dist/media-understanding-provider.js +9 -22
- package/dist/migration-provider-api.js +1 -1
- package/dist/provider-discovery.js +1 -1
- package/dist/session-history-worker-runtime.js +3 -3
- package/dist/session-history.worker.js +1 -1
- package/openclaw.plugin.json +14 -2
- package/package.json +7 -6
- package/dist/.setup/attempt-workspace-context-DUVEn_CS.mjs +0 -331
- package/dist/.setup/compact-Du5UvtxA.mjs +0 -680
- package/dist/.setup/event-projector-assistant-message-BsruvNrH.mjs +0 -103
- package/dist/.setup/event-projector-items-C6L_5ZiT.mjs +0 -234
- package/dist/.setup/harness-a_MsE4-_.mjs +0 -355
- package/dist/.setup/history-rejection-B4nOXNXF.mjs +0 -13
- package/dist/.setup/image-payload-sanitizer-tupAr-2o.mjs +0 -79
- package/dist/.setup/local-runtime-attribution-B_2mnqhb.mjs +0 -19
- package/dist/.setup/native-subagent-history-0nYYgo0k.mjs +0 -148
- package/dist/.setup/native-subagent-task-ids-wb8CKZGN.mjs +0 -441
- package/dist/.setup/plugin-approval-roundtrip-C0MZzCuP.mjs +0 -122
- package/dist/.setup/rolldown-runtime-8H4AJuhK.mjs +0 -14
- package/dist/.setup/sandbox-guard-C2sRMOEY.mjs +0 -166
- package/dist/.setup/session-binding-Cm0apEbd.mjs +0 -692
- package/dist/.setup/session-catalog-events-Bj6j94E_.mjs +0 -347
- package/dist/.setup/session-history-read-B3ZfSUbF.mjs +0 -50
- package/dist/.setup/session-initialization-rcgbZiid.mjs +0 -75
- package/dist/.setup/thread-history-page-DoVpnHim.mjs +0 -83
|
@@ -1,24 +1,11 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { n as
|
|
3
|
-
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
1
|
+
import "./protocol-CANUwXJ3.mjs";
|
|
2
|
+
import { n as detachCodexCatalogString } from "./session-catalog-limits-DDxOsQeC.mjs";
|
|
4
3
|
import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
4
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
6
5
|
//#region extensions/codex/src/app-server/protocol-session-source.ts
|
|
7
6
|
const CODEX_INTERACTIVE_THREAD_SOURCE_KINDS = ["cli", "vscode"];
|
|
8
7
|
const CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES = ["atlas", "chatgpt"];
|
|
9
8
|
//#endregion
|
|
10
|
-
//#region extensions/codex/src/session-catalog-limits.ts
|
|
11
|
-
var session_catalog_limits_exports = /* @__PURE__ */ __exportAll({
|
|
12
|
-
CODEX_CATALOG_MAX_ROWS: () => CODEX_CATALOG_MAX_ROWS,
|
|
13
|
-
CODEX_CATALOG_MAX_STATE_KEY_BYTES: () => 512,
|
|
14
|
-
detachCodexCatalogString: () => detachCodexCatalogString
|
|
15
|
-
});
|
|
16
|
-
const CODEX_CATALOG_MAX_ROWS = 2e4;
|
|
17
|
-
/** Preserve UTF-16 code units without retaining an oversized source string. */
|
|
18
|
-
function detachCodexCatalogString(value) {
|
|
19
|
-
return Buffer.from(value, "utf16le").toString("utf16le");
|
|
20
|
-
}
|
|
21
|
-
//#endregion
|
|
22
9
|
//#region extensions/codex/src/session-catalog-parsing.ts
|
|
23
10
|
const DEFAULT_PAGE_LIMIT = 50;
|
|
24
11
|
const CODEX_APP_SERVER_THREADS_CAPABILITY = "codex-app-server-threads";
|
|
@@ -67,8 +54,7 @@ function truncateCodexCatalogPreview(value, sanitize) {
|
|
|
67
54
|
return Buffer.from(catalogPreview(value, sanitize) ?? "", "utf8").toString("utf8");
|
|
68
55
|
}
|
|
69
56
|
function normalizeInteractiveThreadSource(source) {
|
|
70
|
-
|
|
71
|
-
if (isRecord(source) && CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source.custom)) return source.custom;
|
|
57
|
+
return CODEX_INTERACTIVE_THREAD_SOURCE_KINDS.find((kind) => kind === source) ?? CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.find((kind) => kind === source) ?? (isRecord(source) ? CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.find((kind) => kind === source.custom) : void 0);
|
|
72
58
|
}
|
|
73
59
|
function isInteractiveThreadSource(source) {
|
|
74
60
|
return normalizeInteractiveThreadSource(source) !== void 0;
|
|
@@ -118,9 +104,9 @@ function toCatalogSession(thread, archived, sanitize, preparedPreview) {
|
|
|
118
104
|
...gitBranch ? { gitBranch } : {}
|
|
119
105
|
};
|
|
120
106
|
}
|
|
121
|
-
function normalizeLimit(value, key) {
|
|
122
|
-
if (value === void 0) return
|
|
123
|
-
if (!Number.isInteger(value) || value < 1 || value >
|
|
107
|
+
function normalizeLimit(value, key, fallback = DEFAULT_PAGE_LIMIT, max = 100) {
|
|
108
|
+
if (value === void 0) return fallback;
|
|
109
|
+
if (typeof value !== "number" || !Number.isInteger(value) || value < 1 || value > max) throw new CatalogParamsError(`${key} must be an integer from 1 to ${max}`);
|
|
124
110
|
return value;
|
|
125
111
|
}
|
|
126
112
|
function readBoundedOptionalString(params, key, maxLength) {
|
|
@@ -157,7 +143,7 @@ function readPageParams(value) {
|
|
|
157
143
|
}
|
|
158
144
|
function readGatewayParams(value) {
|
|
159
145
|
if (value !== void 0 && !isRecord(value)) throw new CatalogParamsError("Codex session catalog parameters must be an object");
|
|
160
|
-
const params =
|
|
146
|
+
const params = value ?? {};
|
|
161
147
|
requireOnlyKeys(params, /* @__PURE__ */ new Set([
|
|
162
148
|
"search",
|
|
163
149
|
"limitPerHost",
|
|
@@ -177,8 +163,7 @@ function readGatewayParams(value) {
|
|
|
177
163
|
if (entries.length > MAX_CURSOR_COUNT) throw new CatalogParamsError(`cursors may contain at most ${MAX_CURSOR_COUNT} hosts`);
|
|
178
164
|
cursors = {};
|
|
179
165
|
for (const [hostId, cursor] of entries) {
|
|
180
|
-
const normalizedHostId = hostId
|
|
181
|
-
if (normalizedHostId.length === 0 || normalizedHostId.length > MAX_HOST_ID_LENGTH || !normalizedHostId.startsWith("gateway:") && !normalizedHostId.startsWith("node:")) throw new CatalogParamsError(`invalid Codex session catalog host id: ${hostId}`);
|
|
166
|
+
const normalizedHostId = readHostId(hostId);
|
|
182
167
|
if (typeof cursor !== "string" || !cursor.trim() || cursor.trim().length > 4096) throw new CatalogParamsError(`invalid cursor for Codex session catalog host: ${hostId}`);
|
|
183
168
|
cursors[normalizedHostId] = cursor.trim();
|
|
184
169
|
}
|
|
@@ -271,12 +256,12 @@ function filterCatalogPageByTitle(page, searchTerm) {
|
|
|
271
256
|
sessions: page.sessions.filter((session) => (session.name ?? session.fallbackName)?.toLocaleLowerCase().includes(searchTerm.toLocaleLowerCase()))
|
|
272
257
|
};
|
|
273
258
|
}
|
|
274
|
-
function unwrapNodeInvokePayload(value) {
|
|
259
|
+
function unwrapNodeInvokePayload(value, malformedMessage = "Codex node returned malformed session catalog JSON") {
|
|
275
260
|
if (!isRecord(value)) return value;
|
|
276
261
|
if (typeof value.payloadJSON === "string" && value.payloadJSON.trim()) try {
|
|
277
262
|
return JSON.parse(value.payloadJSON);
|
|
278
263
|
} catch (error) {
|
|
279
|
-
throw new Error(
|
|
264
|
+
throw new Error(malformedMessage, { cause: error });
|
|
280
265
|
}
|
|
281
266
|
return "payload" in value ? value.payload : value;
|
|
282
267
|
}
|
|
@@ -318,172 +303,4 @@ function requireBoundThread(entry) {
|
|
|
318
303
|
return entry.boundThreadId;
|
|
319
304
|
}
|
|
320
305
|
//#endregion
|
|
321
|
-
|
|
322
|
-
const getSources = defineCodexBuildState("openclaw.codexCatalogSources", () => ({
|
|
323
|
-
clients: /* @__PURE__ */ new WeakMap(),
|
|
324
|
-
values: /* @__PURE__ */ new WeakMap()
|
|
325
|
-
}));
|
|
326
|
-
const getEphemeralObservers = defineCodexBuildState("openclaw.codexCatalogEphemeralObservers", () => /* @__PURE__ */ new WeakMap());
|
|
327
|
-
/** A passive lifetime fact; the token never retains its client or a lease. */
|
|
328
|
-
function codexCatalogSourceForClient(client) {
|
|
329
|
-
const { clients } = getSources();
|
|
330
|
-
let source = clients.get(client);
|
|
331
|
-
if (!source) {
|
|
332
|
-
source = { closed: false };
|
|
333
|
-
clients.set(client, source);
|
|
334
|
-
}
|
|
335
|
-
return source;
|
|
336
|
-
}
|
|
337
|
-
function closeCodexCatalogClientSource(client) {
|
|
338
|
-
const { clients } = getSources();
|
|
339
|
-
const source = clients.get(client);
|
|
340
|
-
if (source) {
|
|
341
|
-
source.closed = true;
|
|
342
|
-
getEphemeralObservers().delete(source);
|
|
343
|
-
} else clients.set(client, { closed: true });
|
|
344
|
-
}
|
|
345
|
-
/** The catalog observer is bound once per physical source and released on closure. */
|
|
346
|
-
function observeCodexCatalogEphemeralThreads(source, observer) {
|
|
347
|
-
getEphemeralObservers().set(source, observer);
|
|
348
|
-
}
|
|
349
|
-
function getCodexCatalogSource(value) {
|
|
350
|
-
return value !== null && typeof value === "object" ? getSources().values.get(value) : void 0;
|
|
351
|
-
}
|
|
352
|
-
function setCodexCatalogSource(value, source) {
|
|
353
|
-
if (source) getSources().values.set(value, source);
|
|
354
|
-
return value;
|
|
355
|
-
}
|
|
356
|
-
/** Source attribution survives projection without becoming serialized row data. */
|
|
357
|
-
function copyCodexCatalogSource(from, to) {
|
|
358
|
-
return setCodexCatalogSource(to, getCodexCatalogSource(from));
|
|
359
|
-
}
|
|
360
|
-
/** Stamp the final decoded objects, including any bounded catalog DTO replacement. */
|
|
361
|
-
function recordCodexCatalogResponseSource(method, result, source) {
|
|
362
|
-
if (result === null || typeof result !== "object") return;
|
|
363
|
-
if (method === "thread/list" && "data" in result && Array.isArray(result.data)) {
|
|
364
|
-
setCodexCatalogSource(result, source);
|
|
365
|
-
for (const thread of result.data) if (thread !== null && typeof thread === "object") setCodexCatalogSource(thread, source);
|
|
366
|
-
} else if ((method === "thread/read" || method === "thread/start" || method === "thread/fork" || method === "thread/resume") && "thread" in result && result.thread !== null && typeof result.thread === "object") {
|
|
367
|
-
setCodexCatalogSource(result, source);
|
|
368
|
-
setCodexCatalogSource(result.thread, source);
|
|
369
|
-
if ("ephemeral" in result.thread && result.thread.ephemeral === true && "id" in result.thread && typeof result.thread.id === "string") getEphemeralObservers().get(source)?.(result.thread.id);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
//#endregion
|
|
373
|
-
//#region extensions/codex/src/session-catalog-native-projection.ts
|
|
374
|
-
var session_catalog_native_projection_exports = /* @__PURE__ */ __exportAll({
|
|
375
|
-
CODEX_CATALOG_NATIVE_PAGE_LIMIT: () => 64,
|
|
376
|
-
projectCodexCatalogNativeResponse: () => projectCodexCatalogNativeResponse,
|
|
377
|
-
projectCodexCatalogNativeThread: () => projectCodexCatalogNativeThread,
|
|
378
|
-
reuseCodexCatalogPreview: () => reuseCodexCatalogPreview
|
|
379
|
-
});
|
|
380
|
-
const CODEX_CATALOG_NATIVE_PAGE_LIMIT = 64;
|
|
381
|
-
const STRING_FIELDS = [
|
|
382
|
-
[
|
|
383
|
-
"name",
|
|
384
|
-
500,
|
|
385
|
-
"truncate"
|
|
386
|
-
],
|
|
387
|
-
[
|
|
388
|
-
"cwd",
|
|
389
|
-
MAX_CWD_LENGTH,
|
|
390
|
-
"omit"
|
|
391
|
-
],
|
|
392
|
-
[
|
|
393
|
-
"modelProvider",
|
|
394
|
-
500,
|
|
395
|
-
"truncate"
|
|
396
|
-
],
|
|
397
|
-
[
|
|
398
|
-
"cliVersion",
|
|
399
|
-
500,
|
|
400
|
-
"truncate"
|
|
401
|
-
]
|
|
402
|
-
];
|
|
403
|
-
/** Drop unused native fields before catalog-owned asynchronous work can retain them. */
|
|
404
|
-
function projectCodexCatalogNativeThread(thread, sanitize, cachedPreview) {
|
|
405
|
-
if (!isJsonObject(thread)) throw new Error("Codex catalog response contains an invalid thread");
|
|
406
|
-
const id = boundedCatalogString(thread.id, 256);
|
|
407
|
-
if (!id) throw new Error("Codex catalog response contains an invalid thread id");
|
|
408
|
-
const row = {
|
|
409
|
-
id,
|
|
410
|
-
projectId: boundedCatalogString(thread.projectId, 256, "omit") ?? null
|
|
411
|
-
};
|
|
412
|
-
const sessionId = boundedCatalogString(thread.sessionId, 256, "omit");
|
|
413
|
-
if (sessionId) row.sessionId = sessionId;
|
|
414
|
-
if (thread.ephemeral === true) return copyCodexCatalogSource(thread, {
|
|
415
|
-
...row,
|
|
416
|
-
ephemeral: true
|
|
417
|
-
});
|
|
418
|
-
for (const [field, limit, overflow] of STRING_FIELDS) {
|
|
419
|
-
const value = thread[field];
|
|
420
|
-
const bounded = boundedCatalogString(value, limit, overflow);
|
|
421
|
-
if (value === null || bounded !== void 0) row[field] = bounded ?? null;
|
|
422
|
-
}
|
|
423
|
-
if (typeof thread.path === "string") {
|
|
424
|
-
if (thread.path.length > 4096) throw new Error("Codex catalog rollout path exceeds its length limit");
|
|
425
|
-
row.path = detachCodexCatalogString(thread.path);
|
|
426
|
-
} else if (thread.path === null) row.path = null;
|
|
427
|
-
if (typeof thread.originator === "string") row.originator = detachCodexCatalogString(thread.originator.slice(0, 500));
|
|
428
|
-
for (const field of [
|
|
429
|
-
"createdAt",
|
|
430
|
-
"updatedAt",
|
|
431
|
-
"recencyAt"
|
|
432
|
-
]) {
|
|
433
|
-
const value = thread[field];
|
|
434
|
-
if (value === null || typeof value === "number" && Number.isFinite(value)) row[field] = value;
|
|
435
|
-
}
|
|
436
|
-
const rawPreview = thread.preview;
|
|
437
|
-
const preview = reuseCodexCatalogPreview(row, typeof rawPreview === "string" ? Boolean(rawPreview) : void 0, cachedPreview);
|
|
438
|
-
if (preview !== void 0) row.preview = preview;
|
|
439
|
-
else if (typeof rawPreview === "string") row.preview = rawPreview ? truncateCodexCatalogPreview(selectCodexCatalogPreviewInput(rawPreview), sanitize) : "";
|
|
440
|
-
else if (rawPreview === null) row.preview = null;
|
|
441
|
-
const source = typeof thread.source === "string" ? detachCodexCatalogString(thread.source.slice(0, 500)) : void 0;
|
|
442
|
-
if (source === "cli" || source === "vscode" || source === "exec" || source === "appServer" || source === "unknown") row.source = source;
|
|
443
|
-
else if (isJsonObject(thread.source) && typeof thread.source.custom === "string" && thread.source.custom.length <= 500) row.source = { custom: detachCodexCatalogString(thread.source.custom) };
|
|
444
|
-
if (isJsonObject(thread.gitInfo)) {
|
|
445
|
-
const branch = boundedCatalogString(thread.gitInfo.branch, 500, "truncate");
|
|
446
|
-
if (branch !== void 0) row.gitInfo = { branch };
|
|
447
|
-
}
|
|
448
|
-
if (isJsonObject(thread.status)) {
|
|
449
|
-
const type = boundedCatalogString(thread.status.type, 64);
|
|
450
|
-
if (type === "active" || type === "idle" || type === "notLoaded" || type === "systemError") {
|
|
451
|
-
const activeFlags = type === "active" && Array.isArray(thread.status.activeFlags) ? thread.status.activeFlags.slice(0, 16).flatMap((flag) => {
|
|
452
|
-
const bounded = boundedCatalogString(flag, 128, "omit");
|
|
453
|
-
return bounded ? [bounded] : [];
|
|
454
|
-
}) : void 0;
|
|
455
|
-
row.status = type === "active" ? {
|
|
456
|
-
type,
|
|
457
|
-
...activeFlags ? { activeFlags } : {}
|
|
458
|
-
} : { type };
|
|
459
|
-
}
|
|
460
|
-
}
|
|
461
|
-
return copyCodexCatalogSource(thread, row);
|
|
462
|
-
}
|
|
463
|
-
/** Keep only the admitted prefix before an RPC promise retains its response. */
|
|
464
|
-
function projectCodexCatalogNativeResponse(response, sanitize, cachedPreview, remainingRows = 64) {
|
|
465
|
-
if (!Array.isArray(response.data) || response.data.length > 64) throw new Error("Codex catalog response exceeds its native page limit");
|
|
466
|
-
const limit = Number.isFinite(remainingRows) ? Math.max(0, Math.min(64, Math.floor(remainingRows))) : 0;
|
|
467
|
-
const page = { data: response.data.slice(0, limit).map((thread) => projectCodexCatalogNativeThread(thread, sanitize, cachedPreview)) };
|
|
468
|
-
for (const field of ["nextCursor", "backwardsCursor"]) {
|
|
469
|
-
const value = response[field];
|
|
470
|
-
if (value === null) page[field] = null;
|
|
471
|
-
else if (value !== void 0) {
|
|
472
|
-
if (typeof value !== "string" || value.length > 4096) throw new Error("Codex catalog response contains an invalid cursor");
|
|
473
|
-
page[field] = detachCodexCatalogString(value);
|
|
474
|
-
}
|
|
475
|
-
}
|
|
476
|
-
return page;
|
|
477
|
-
}
|
|
478
|
-
/** Reuse resident text without transferring a cache or an unbounded native preview. */
|
|
479
|
-
function reuseCodexCatalogPreview(thread, rawPreviewNonempty, cachedPreview) {
|
|
480
|
-
const preview = cachedPreview?.({
|
|
481
|
-
id: thread.id,
|
|
482
|
-
path: typeof thread.path === "string" ? thread.path : null,
|
|
483
|
-
updatedAt: typeof thread.updatedAt === "number" ? thread.updatedAt : null,
|
|
484
|
-
recencyAt: typeof thread.recencyAt === "number" ? thread.recencyAt : null
|
|
485
|
-
});
|
|
486
|
-
return preview !== void 0 && preview.length <= 500 && (rawPreviewNonempty === void 0 || rawPreviewNonempty === Boolean(preview)) ? preview : void 0;
|
|
487
|
-
}
|
|
488
|
-
//#endregion
|
|
489
|
-
export { parseCatalogPage as A, toCatalogSession as B, boundedCatalogString as C, filterCatalogPageByTitle as D, codexCatalogThreadStatus as E, readGatewayParams as F, session_catalog_limits_exports as G, unwrapNodeInvokePayload as H, readPageParams as I, CODEX_INTERACTIVE_THREAD_SOURCE_KINDS as K, requireBoundThread as L, parseTranscriptPage as M, readBoundedOptionalString as N, isInteractiveThreadSource as O, readControlCursor as P, requireOnlyKeys as R, NODE_INVOKE_TIMEOUT_MS as S, codexCatalogThreadName as T, CODEX_CATALOG_MAX_ROWS as U, truncateCodexCatalogPreview as V, detachCodexCatalogString as W, CODEX_LOCAL_SESSION_HOST_ID as _, session_catalog_native_projection_exports as a, MAX_CWD_LENGTH as b, copyCodexCatalogSource as c, recordCodexCatalogResponseSource as d, setCodexCatalogSource as f, CODEX_CATALOG_TRANSCRIPT_READ_COMMAND as g, CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND as h, reuseCodexCatalogPreview as i, parseJsonParams as j, normalizeLimit as k, getCodexCatalogSource as l, CODEX_APP_SERVER_THREADS_LIST_COMMAND as m, projectCodexCatalogNativeResponse as n, closeCodexCatalogClientSource as o, CODEX_APP_SERVER_THREADS_CAPABILITY as p, projectCodexCatalogNativeThread as r, codexCatalogSourceForClient as s, CODEX_CATALOG_NATIVE_PAGE_LIMIT as t, observeCodexCatalogEphemeralThreads as u, CatalogParamsError as v, catalogError as w, MAX_TRANSCRIPT_PAGE_BYTES as x, MAX_CURSOR_LENGTH as y, selectCodexCatalogPreviewInput as z };
|
|
306
|
+
export { unwrapNodeInvokePayload as A, readGatewayParams as C, selectCodexCatalogPreviewInput as D, requireOnlyKeys as E, toCatalogSession as O, readControlCursor as S, requireBoundThread as T, normalizeLimit as _, CODEX_LOCAL_SESSION_HOST_ID as a, parseTranscriptPage as b, MAX_CWD_LENGTH as c, boundedCatalogString as d, catalogError as f, isInteractiveThreadSource as g, filterCatalogPageByTitle as h, CODEX_CATALOG_TRANSCRIPT_READ_COMMAND as i, CODEX_INTERACTIVE_THREAD_SOURCE_KINDS as j, truncateCodexCatalogPreview as k, MAX_TRANSCRIPT_PAGE_BYTES as l, codexCatalogThreadStatus as m, CODEX_APP_SERVER_THREADS_LIST_COMMAND as n, CatalogParamsError as o, codexCatalogThreadName as p, CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND as r, MAX_CURSOR_LENGTH as s, CODEX_APP_SERVER_THREADS_CAPABILITY as t, NODE_INVOKE_TIMEOUT_MS as u, parseCatalogPage as v, readPageParams as w, readBoundedOptionalString as x, parseJsonParams as y };
|
|
@@ -1,11 +1,13 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { n as codexCatalogRowRecency } from "./session-catalog-index-order-
|
|
1
|
+
import { D as selectCodexCatalogPreviewInput, O as toCatalogSession, S as readControlCursor, d as boundedCatalogString, k as truncateCodexCatalogPreview } from "./session-catalog-parsing-CPGaPYr-.mjs";
|
|
2
|
+
import { n as detachCodexCatalogString } from "./session-catalog-limits-DDxOsQeC.mjs";
|
|
3
|
+
import { n as codexCatalogRowRecency } from "./session-catalog-index-order-BcQpHks3.mjs";
|
|
4
|
+
import { t as isOpenClawManagedCodexThread } from "./session-catalog-provenance-DoAvktcj.mjs";
|
|
5
|
+
import { c as copyCodexCatalogSource, l as getCodexCatalogSource, p as setCodexCatalogSource, r as projectCodexCatalogNativeThread } from "./session-catalog-native-projection-DjhwGL6x.mjs";
|
|
4
6
|
import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
5
7
|
import path from "node:path";
|
|
6
8
|
import fs from "node:fs/promises";
|
|
7
|
-
import { root } from "openclaw/plugin-sdk/file-access-runtime";
|
|
8
9
|
import { extractErrorCode, toErrorObject } from "openclaw/plugin-sdk/error-runtime";
|
|
10
|
+
import { root } from "openclaw/plugin-sdk/file-access-runtime";
|
|
9
11
|
import { constants, createZstdDecompress } from "node:zlib";
|
|
10
12
|
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
11
13
|
//#region extensions/codex/src/session-catalog-rollouts.ts
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { i as isJsonObject } from "./protocol-CANUwXJ3.mjs";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { root } from "openclaw/plugin-sdk/file-access-runtime";
|
|
4
|
+
import { createZstdDecompress } from "node:zlib";
|
|
5
|
+
//#region extensions/codex/src/session-catalog-provenance.ts
|
|
6
|
+
const MAX_SESSION_META_BYTES = 1048576;
|
|
7
|
+
const SESSION_META_READ_CHUNK_BYTES = 65536;
|
|
8
|
+
const MAX_PROVENANCE_CACHE_ENTRIES = 2e4;
|
|
9
|
+
const provenanceByPath = /* @__PURE__ */ new Map();
|
|
10
|
+
function cacheProvenance(key, value) {
|
|
11
|
+
provenanceByPath.delete(key);
|
|
12
|
+
provenanceByPath.set(key, value);
|
|
13
|
+
if (provenanceByPath.size > MAX_PROVENANCE_CACHE_ENTRIES) provenanceByPath.delete(provenanceByPath.keys().next().value);
|
|
14
|
+
}
|
|
15
|
+
/** Undefined means the metadata line is not durable enough to cache yet. */
|
|
16
|
+
async function readCodexSessionMeta(sessionsRoot, rolloutPath, threadId) {
|
|
17
|
+
let safeRoot;
|
|
18
|
+
try {
|
|
19
|
+
safeRoot = await root(sessionsRoot, {
|
|
20
|
+
hardlinks: "reject",
|
|
21
|
+
maxBytes: Number.MAX_SAFE_INTEGER,
|
|
22
|
+
symlinks: "reject"
|
|
23
|
+
});
|
|
24
|
+
} catch {
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
const candidates = rolloutPath.endsWith(".zst") ? [rolloutPath, rolloutPath.slice(0, -4)] : [rolloutPath, `${rolloutPath}.zst`];
|
|
28
|
+
for (const candidate of candidates) {
|
|
29
|
+
let opened;
|
|
30
|
+
try {
|
|
31
|
+
opened = await safeRoot.open(path.relative(sessionsRoot, candidate));
|
|
32
|
+
} catch {
|
|
33
|
+
continue;
|
|
34
|
+
}
|
|
35
|
+
const input = opened.handle.createReadStream({
|
|
36
|
+
autoClose: false,
|
|
37
|
+
highWaterMark: SESSION_META_READ_CHUNK_BYTES
|
|
38
|
+
});
|
|
39
|
+
const reader = candidate.endsWith(".zst") ? input.pipe(createZstdDecompress()) : input;
|
|
40
|
+
try {
|
|
41
|
+
const chunks = [];
|
|
42
|
+
let bytesReadTotal = 0;
|
|
43
|
+
let line;
|
|
44
|
+
for await (const value of reader) {
|
|
45
|
+
const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
|
|
46
|
+
const remaining = MAX_SESSION_META_BYTES - bytesReadTotal;
|
|
47
|
+
if (remaining <= 0) break;
|
|
48
|
+
const bounded = chunk.subarray(0, remaining);
|
|
49
|
+
bytesReadTotal += bounded.length;
|
|
50
|
+
const newline = bounded.indexOf(10);
|
|
51
|
+
chunks.push(newline >= 0 ? bounded.subarray(0, newline) : bounded);
|
|
52
|
+
if (newline >= 0) {
|
|
53
|
+
line = Buffer.concat(chunks).toString("utf8");
|
|
54
|
+
break;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
if (!line) continue;
|
|
58
|
+
const parsed = JSON.parse(line);
|
|
59
|
+
if (!isJsonObject(parsed) || parsed.type !== "session_meta" || !isJsonObject(parsed.payload)) return null;
|
|
60
|
+
const payload = parsed.payload;
|
|
61
|
+
return payload.id === threadId ? payload : null;
|
|
62
|
+
} catch {
|
|
63
|
+
continue;
|
|
64
|
+
} finally {
|
|
65
|
+
reader.destroy();
|
|
66
|
+
input.destroy();
|
|
67
|
+
await opened.handle.close().catch(() => void 0);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Passive local listing uses native creation provenance, with rollout fallback for older records. */
|
|
72
|
+
async function isOpenClawManagedCodexThread(thread, localSessionsRoot, diagnostics) {
|
|
73
|
+
const started = diagnostics ? performance.now() : 0;
|
|
74
|
+
if (diagnostics) diagnostics.fields.provenanceChecks++;
|
|
75
|
+
try {
|
|
76
|
+
const rolloutPath = typeof thread.path === "string" ? thread.path.trim() : "";
|
|
77
|
+
if (!localSessionsRoot || !rolloutPath) return false;
|
|
78
|
+
if (typeof thread.originator === "string" && thread.originator.length > 0) return thread.originator === "openclaw";
|
|
79
|
+
const cacheKey = `${localSessionsRoot}\0${rolloutPath}`;
|
|
80
|
+
const cached = provenanceByPath.get(cacheKey);
|
|
81
|
+
if (cached !== void 0) {
|
|
82
|
+
if (diagnostics) diagnostics.fields.provenanceCacheHits++;
|
|
83
|
+
return cached;
|
|
84
|
+
}
|
|
85
|
+
if (diagnostics) diagnostics.fields.provenanceReadCalls++;
|
|
86
|
+
const metadata = await readCodexSessionMeta(localSessionsRoot, rolloutPath, thread.id);
|
|
87
|
+
const managed = metadata === void 0 ? void 0 : metadata?.originator === "openclaw";
|
|
88
|
+
if (managed !== void 0) cacheProvenance(cacheKey, managed);
|
|
89
|
+
return managed ?? false;
|
|
90
|
+
} finally {
|
|
91
|
+
if (diagnostics) diagnostics.fields.provenanceMs = (diagnostics.fields.provenanceMs ?? 0) + performance.now() - started;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
//#endregion
|
|
95
|
+
export { readCodexSessionMeta as n, isOpenClawManagedCodexThread as t };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import "./session-catalog-
|
|
2
|
-
import "./session-catalog-
|
|
1
|
+
import "./session-catalog-parsing-CPGaPYr-.mjs";
|
|
2
|
+
import "./session-catalog-4sCdv5qx.mjs";
|
|
3
3
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
4
4
|
import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
|
|
5
5
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
@@ -79,12 +79,6 @@ function writeHost(host) {
|
|
|
79
79
|
}
|
|
80
80
|
if (host.nextCursor) writeLine(` More sessions: repeat the same filters with --host ${quoteShellArgument(host.hostId)} --cursor ${quoteShellArgument(host.nextCursor)}`);
|
|
81
81
|
}
|
|
82
|
-
function filterHosts(result, selector) {
|
|
83
|
-
return selector ? {
|
|
84
|
-
...result,
|
|
85
|
-
hosts: result.hosts.filter((host) => host.hostId === selector)
|
|
86
|
-
} : result;
|
|
87
|
-
}
|
|
88
82
|
async function listCodexSessions(options) {
|
|
89
83
|
const agentId = requestedAgentId(options);
|
|
90
84
|
const host = options.host?.trim() || void 0;
|
|
@@ -93,23 +87,22 @@ async function listCodexSessions(options) {
|
|
|
93
87
|
const search = options.search?.trim() || void 0;
|
|
94
88
|
const limitPerHost = parsePageLimit(options.limit);
|
|
95
89
|
const params = {
|
|
90
|
+
catalogId: "codex",
|
|
96
91
|
...agentId ? { agentId } : {},
|
|
97
92
|
...search ? { search } : {},
|
|
98
93
|
...limitPerHost !== void 0 ? { limitPerHost } : {},
|
|
99
94
|
...host ? { hostIds: [host] } : {},
|
|
100
95
|
...cursor && host ? { cursors: { [host]: cursor } } : {}
|
|
101
96
|
};
|
|
102
|
-
const raw = await callGatewayFromCli("sessions.catalog.list", gatewayOptions(options), {
|
|
103
|
-
catalogId: "codex",
|
|
104
|
-
...params
|
|
105
|
-
}, {
|
|
97
|
+
const raw = await callGatewayFromCli("sessions.catalog.list", gatewayOptions(options), params, {
|
|
106
98
|
mode: "cli",
|
|
107
99
|
scopes: ["operator.write"]
|
|
108
100
|
});
|
|
109
101
|
if (!isRecord(raw) || !Array.isArray(raw.catalogs)) throw new Error("Codex session catalog returned an invalid result");
|
|
110
102
|
const catalog = raw.catalogs.find((candidate) => isRecord(candidate) && candidate.id === "codex" && Array.isArray(candidate.hosts));
|
|
111
103
|
if (!isRecord(catalog)) throw new Error("Codex session catalog is unavailable on this Gateway");
|
|
112
|
-
const
|
|
104
|
+
const hosts = catalog.hosts;
|
|
105
|
+
const result = { hosts: host ? hosts.filter((entry) => entry.hostId === host) : hosts };
|
|
113
106
|
if (options.json) {
|
|
114
107
|
writeJson(result);
|
|
115
108
|
return;
|
|
@@ -175,15 +168,9 @@ async function archiveCodexSession(threadIdValue, options) {
|
|
|
175
168
|
/** Registers the plugin-owned Codex session supervision CLI. */
|
|
176
169
|
function registerCodexSessionCli(program) {
|
|
177
170
|
const codex = program.command("codex").description("Inspect and branch from Codex sessions through the Gateway");
|
|
178
|
-
addGatewayClientOptions(codex.command("sessions").description("List non-archived Codex app-server sessions across connected hosts").option("--agent <id>", "Agent id that owns the Codex sessions").option("--search <text>", "Search session titles (case-insensitive)").option("--host <id>", "Filter by stable host id").option("--limit <count>", "Maximum sessions returned per host").option("--cursor <cursor>", "Continue one host page (requires --host)").option("--json", "Print the structured catalog response", false), { timeoutMs: CODEX_SESSION_CATALOG_CLI_TIMEOUT_MS }).action(
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
addGatewayClientOptions(codex.command("continue <thread-id>").description("Continue a Gateway-local Codex thread as an OpenClaw branch").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--json", "Print the structured response", false)).action(async (threadId, options) => {
|
|
182
|
-
await continueCodexSession(threadId, options);
|
|
183
|
-
});
|
|
184
|
-
addGatewayClientOptions(codex.command("archive <thread-id>").description("Archive a stored or idle Gateway-local Codex thread").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--confirm-no-other-runner", "Confirm no other Codex client or OpenClaw runner is using this thread", false).option("--json", "Print the structured response", false)).action(async (threadId, options) => {
|
|
185
|
-
await archiveCodexSession(threadId, options);
|
|
186
|
-
});
|
|
171
|
+
addGatewayClientOptions(codex.command("sessions").description("List non-archived Codex app-server sessions across connected hosts").option("--agent <id>", "Agent id that owns the Codex sessions").option("--search <text>", "Search session titles (case-insensitive)").option("--host <id>", "Filter by stable host id").option("--limit <count>", "Maximum sessions returned per host").option("--cursor <cursor>", "Continue one host page (requires --host)").option("--json", "Print the structured catalog response", false), { timeoutMs: CODEX_SESSION_CATALOG_CLI_TIMEOUT_MS }).action(listCodexSessions);
|
|
172
|
+
addGatewayClientOptions(codex.command("continue <thread-id>").description("Continue a Gateway-local Codex thread as an OpenClaw branch").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--json", "Print the structured response", false)).action(continueCodexSession);
|
|
173
|
+
addGatewayClientOptions(codex.command("archive <thread-id>").description("Archive a stored or idle Gateway-local Codex thread").option("--agent <id>", "Agent id that owns the Codex session").option("--host <id>", "Stable local host id from codex sessions").option("--confirm-no-other-runner", "Confirm no other Codex client or OpenClaw runner is using this thread", false).option("--json", "Print the structured response", false)).action(archiveCodexSession);
|
|
187
174
|
}
|
|
188
175
|
//#endregion
|
|
189
176
|
export { registerCodexSessionCli };
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { n as readCodexNativeHistory, t as consumeCodexHistory } from "./session-history-read-
|
|
1
|
+
import { n as readCodexNativeHistory, t as consumeCodexHistory } from "./session-history-read-Ov3StuL4.mjs";
|
|
2
|
+
import { resolveAgentHarnessHistoryLimits } from "openclaw/plugin-sdk/agent-harness-attempt-runtime";
|
|
2
3
|
import { SessionManager } from "openclaw/plugin-sdk/agent-sessions";
|
|
3
4
|
import { getSessionEntry, parseSqliteSessionFileMarker, resolveTranscriptSessionKeyBySessionId } from "openclaw/plugin-sdk/session-store-runtime";
|
|
4
5
|
//#region extensions/codex/src/app-server/session-history.ts
|
|
6
|
+
/** Reads bounded model context from the Codex transcript mirror. */
|
|
5
7
|
function resolveCodexHistoryTarget(target, admission) {
|
|
6
8
|
if (target.sessionTarget) {
|
|
7
9
|
const { agentId, sessionId, sessionKey, storePath } = target.sessionTarget;
|
|
@@ -58,11 +60,7 @@ async function readCodexMirroredSessionHistoryMessages(target, admission, signal
|
|
|
58
60
|
const loaded = await SessionManager.openModelContextAsync(resolved.target, {
|
|
59
61
|
admission,
|
|
60
62
|
signal,
|
|
61
|
-
limits:
|
|
62
|
-
maxBytes: Math.min(67108864, Math.max(1024, Math.floor((contextTokenBudget ?? 128e3) * 8))),
|
|
63
|
-
maxEvents: 1e4,
|
|
64
|
-
toolResultOverflow: "omit"
|
|
65
|
-
}
|
|
63
|
+
limits: resolveAgentHarnessHistoryLimits(contextTokenBudget)
|
|
66
64
|
});
|
|
67
65
|
result = consumeCodexHistory(loaded.buildSessionContext().messages, loaded.getHeader(), target.sessionId, read, "codex mirrored model context");
|
|
68
66
|
} else {
|
package/dist/.setup/{session-history-import-D-3wAgOP.mjs → session-history-import-WhX-X33a.mjs}
RENAMED
|
@@ -1,19 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import "./session-binding-
|
|
3
|
-
import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-
|
|
4
|
-
import { n as prepareCodexSessionInitialization } from "./session-initialization-
|
|
1
|
+
import { v as sessionBindingIdentity } from "./session-binding-record-Oe9L-CNY.mjs";
|
|
2
|
+
import "./session-binding-DGCYAfvD.mjs";
|
|
3
|
+
import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-kxmCYsuF.mjs";
|
|
4
|
+
import { n as prepareCodexSessionInitialization } from "./session-initialization-6aveB9qb.mjs";
|
|
5
5
|
import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
6
6
|
//#region extensions/codex/src/app-server/session-history-import.ts
|
|
7
7
|
/** Creates a session whose transcript is derived from one verified Codex thread snapshot. */
|
|
8
8
|
async function createImportedCodexSession(params) {
|
|
9
9
|
const spawnedCwd = params.thread.cwd?.trim() || void 0;
|
|
10
|
-
|
|
10
|
+
return await params.runtime.agent.session.createSessionEntry({
|
|
11
11
|
cfg: params.config,
|
|
12
12
|
key: params.key,
|
|
13
13
|
agentId: params.agentId,
|
|
14
14
|
...params.displayName !== void 0 ? { displayName: params.displayName } : {},
|
|
15
15
|
...spawnedCwd ? { spawnedCwd } : {},
|
|
16
16
|
initialEntry: params.initialEntry,
|
|
17
|
+
...params.recoverMatchingInitialEntry ? { recoverMatchingInitialEntry: true } : {},
|
|
17
18
|
afterCreate: async (entry) => {
|
|
18
19
|
if (!entry.initialization) throw new Error("Codex history initialization requires host creation authority");
|
|
19
20
|
const initialization = prepareCodexSessionInitialization({
|
|
@@ -43,11 +44,7 @@ async function createImportedCodexSession(params) {
|
|
|
43
44
|
entry.initialization.assertCurrent();
|
|
44
45
|
return await params.afterImport(entry, initialization);
|
|
45
46
|
}
|
|
46
|
-
};
|
|
47
|
-
return params.recoverMatchingInitialEntry ? await params.runtime.agent.session.createSessionEntry({
|
|
48
|
-
...createParams,
|
|
49
|
-
recoverMatchingInitialEntry: true
|
|
50
|
-
}) : await params.runtime.agent.session.createSessionEntry(createParams);
|
|
47
|
+
});
|
|
51
48
|
}
|
|
52
49
|
//#endregion
|
|
53
50
|
export { createImportedCodexSession };
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
2
|
+
import fs from "node:fs/promises";
|
|
3
|
+
import { SessionTranscriptReadFenceError, readCodexSessionContext } from "openclaw/plugin-sdk/codex-session-transcript-runtime";
|
|
4
|
+
import { INLINE_IMAGE_DATA_URL_PREFIX, sanitizeInlineImageDataUrl } from "openclaw/plugin-sdk/inline-image-data-url-runtime";
|
|
5
|
+
//#region extensions/codex/src/app-server/history-rejection.ts
|
|
6
|
+
/** Only an owning rejection site can supply a diagnostic; exception text is never evidence. */
|
|
7
|
+
var CodexHistoryRejection = class extends Error {
|
|
8
|
+
constructor(reason) {
|
|
9
|
+
super(`Codex history rejected: ${reason}`);
|
|
10
|
+
this.reason = reason;
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
function codexHistoryRejectionReason(error) {
|
|
14
|
+
return error instanceof CodexHistoryRejection ? error.reason : "history_read_failed";
|
|
15
|
+
}
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region extensions/codex/src/app-server/image-payload-sanitizer.ts
|
|
18
|
+
/**
|
|
19
|
+
* Sanitizes inline image payloads mirrored through Codex history so invalid
|
|
20
|
+
* base64 data becomes readable text instead of poisoning replayed transcripts.
|
|
21
|
+
*/
|
|
22
|
+
const IMAGE_OMITTED_TEXT = "omitted image payload: invalid inline image data";
|
|
23
|
+
/** Builds the replacement text inserted when an inline image payload is invalid. */
|
|
24
|
+
function invalidInlineImageText(label) {
|
|
25
|
+
return `[${label}] ${IMAGE_OMITTED_TEXT}`;
|
|
26
|
+
}
|
|
27
|
+
function sanitizeImageContentRecord(record, label) {
|
|
28
|
+
if (record.type === "image" && typeof record.data === "string") {
|
|
29
|
+
const mimeType = typeof record.mimeType === "string" ? record.mimeType : "image/png";
|
|
30
|
+
const imageUrl = sanitizeInlineImageDataUrl(`data:${mimeType};base64,${record.data}`);
|
|
31
|
+
if (!imageUrl) return {
|
|
32
|
+
type: "text",
|
|
33
|
+
text: invalidInlineImageText(label)
|
|
34
|
+
};
|
|
35
|
+
const commaIndex = imageUrl.indexOf(",");
|
|
36
|
+
const mime = imageUrl.slice(INLINE_IMAGE_DATA_URL_PREFIX.length, commaIndex).split(";")[0] ?? mimeType;
|
|
37
|
+
const data = imageUrl.slice(commaIndex + 1);
|
|
38
|
+
return mime === record.mimeType && data === record.data ? record : {
|
|
39
|
+
...record,
|
|
40
|
+
mimeType: mime,
|
|
41
|
+
data
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
if (record.type === "inputImage" && typeof record.imageUrl === "string") {
|
|
45
|
+
const imageUrl = sanitizeInlineImageDataUrl(record.imageUrl);
|
|
46
|
+
if (!imageUrl) return {
|
|
47
|
+
type: "inputText",
|
|
48
|
+
text: invalidInlineImageText(label)
|
|
49
|
+
};
|
|
50
|
+
return imageUrl === record.imageUrl ? record : {
|
|
51
|
+
...record,
|
|
52
|
+
imageUrl
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
if (record.type === "input_image" && typeof record.image_url === "string") {
|
|
56
|
+
const imageUrl = sanitizeInlineImageDataUrl(record.image_url);
|
|
57
|
+
if (!imageUrl) return {
|
|
58
|
+
type: "input_text",
|
|
59
|
+
text: invalidInlineImageText(label)
|
|
60
|
+
};
|
|
61
|
+
return imageUrl === record.image_url ? record : {
|
|
62
|
+
...record,
|
|
63
|
+
image_url: imageUrl
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/** Sanitizes images without copying unchanged history or mutating its owned snapshot. */
|
|
68
|
+
function sanitizeCodexHistoryImagePayloads(value, label) {
|
|
69
|
+
if (Array.isArray(value)) {
|
|
70
|
+
let next;
|
|
71
|
+
for (let index = 0; index < value.length; index++) {
|
|
72
|
+
const child = sanitizeCodexHistoryImagePayloads(value[index], label);
|
|
73
|
+
if (child !== value[index]) (next ??= value.slice())[index] = child;
|
|
74
|
+
}
|
|
75
|
+
return next ?? value;
|
|
76
|
+
}
|
|
77
|
+
if (!isRecord(value)) return value;
|
|
78
|
+
const imageRecord = sanitizeImageContentRecord(value, label);
|
|
79
|
+
if (imageRecord) return imageRecord;
|
|
80
|
+
let next;
|
|
81
|
+
for (const key in value) {
|
|
82
|
+
if (!Object.hasOwn(value, key)) continue;
|
|
83
|
+
const child = sanitizeCodexHistoryImagePayloads(value[key], label);
|
|
84
|
+
if (child !== value[key]) (next ??= { ...value })[key] = child;
|
|
85
|
+
}
|
|
86
|
+
return next ?? value;
|
|
87
|
+
}
|
|
88
|
+
//#endregion
|
|
89
|
+
//#region extensions/codex/src/app-server/session-history-read.ts
|
|
90
|
+
function consumeCodexHistory(messages, header, sessionId, read, imageLabel = "codex mirrored history") {
|
|
91
|
+
if (!isRecord(header) || header.type !== "session") return read([]);
|
|
92
|
+
if (typeof header.id !== "string") throw new CodexHistoryRejection("malformed_header");
|
|
93
|
+
if (header.id !== sessionId) return read([]);
|
|
94
|
+
return read((function* () {
|
|
95
|
+
for (const message of messages) yield sanitizeCodexHistoryImagePayloads(message, imageLabel);
|
|
96
|
+
})());
|
|
97
|
+
}
|
|
98
|
+
/** Keeps native evidence and its synchronous consumer inside the same readonly snapshot. */
|
|
99
|
+
async function readCodexNativeHistory(target, sessionId, read, admission, onSnapshot) {
|
|
100
|
+
const consume = (messages, header, version) => {
|
|
101
|
+
try {
|
|
102
|
+
onSnapshot?.(version);
|
|
103
|
+
return {
|
|
104
|
+
status: "ok",
|
|
105
|
+
value: consumeCodexHistory(messages, header, sessionId, read)
|
|
106
|
+
};
|
|
107
|
+
} catch (error) {
|
|
108
|
+
return {
|
|
109
|
+
status: "rejected",
|
|
110
|
+
reason: codexHistoryRejectionReason(error)
|
|
111
|
+
};
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
try {
|
|
115
|
+
if (target.kind === "empty") return consume([], void 0);
|
|
116
|
+
if (target.kind === "sqlite") return readCodexSessionContext(target.target, consume, admission);
|
|
117
|
+
const { buildSessionContext, migrateSessionEntries, parseSessionEntries } = await import("openclaw/plugin-sdk/agent-sessions");
|
|
118
|
+
const entries = parseSessionEntries(await fs.readFile(target.sessionFile, "utf-8"));
|
|
119
|
+
return consume((function* () {
|
|
120
|
+
migrateSessionEntries(entries);
|
|
121
|
+
const sessionEntries = entries.filter((entry) => isRecord(entry) && entry.type !== "session");
|
|
122
|
+
yield* buildSessionContext(sessionEntries).messages;
|
|
123
|
+
})(), entries[0]);
|
|
124
|
+
} catch (error) {
|
|
125
|
+
if (isRecord(error) && error.code === "ENOENT") return consume([], void 0);
|
|
126
|
+
return {
|
|
127
|
+
status: "rejected",
|
|
128
|
+
reason: error instanceof SessionTranscriptReadFenceError || isRecord(error) && (error.code === "EACCES" || error.code === "EPERM") ? "access_rejected" : codexHistoryRejectionReason(error)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
//#endregion
|
|
133
|
+
export { CodexHistoryRejection as a, sanitizeInlineImageDataUrl as i, readCodexNativeHistory as n, codexHistoryRejectionReason as o, invalidInlineImageText as r, consumeCodexHistory as t };
|