@openclaw/codex 2026.9.2 → 2026.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +14 -19
  3. package/dist/apply-B6el6hdO.js +357 -0
  4. package/dist/{attempt-client-cleanup-Bp1ZOnk2.js → attempt-client-cleanup-D6cR54TV.js} +39 -19
  5. package/dist/{attempt-context-CSazkWns.js → attempt-context-AO4DSjE0.js} +8 -6
  6. package/dist/{event-projector-usage-ZqEVbAEY.js → attempt-notifications--H8zXR5-.js} +3 -106
  7. package/dist/auth-cache-key-Kq6oerr6.js +498 -0
  8. package/dist/auth-profile-CwzO4_RG.js +43 -0
  9. package/dist/auth-profile-selection-DFu9e167.js +45 -0
  10. package/dist/binding-connection-QqgcPCgk.js +60 -0
  11. package/dist/{bounded-turn-DxGJRYbY.js → bounded-turn-lRpmZHFv.js} +25 -122
  12. package/dist/build-state-6RL6qohz.js +19 -0
  13. package/dist/{capabilities-B1mgvpP8.js → capabilities-BeqLPbtM.js} +1 -1
  14. package/dist/cli-metadata.js +1 -1
  15. package/dist/client-BEKu4yDx.js +3983 -0
  16. package/dist/command-dispatch-CisT9Jqq.js +21 -0
  17. package/dist/{command-formatters-DSbGMXA0.js → command-formatters-DeTfrapr.js} +2 -2
  18. package/dist/{command-handlers-DOJvGv6-.js → command-handlers-BfIsJEuA.js} +31 -21
  19. package/dist/command-rpc-BMqRQOFX.js +226 -0
  20. package/dist/{compact-Y_xBqrHN.js → compact-CGJZ2rlb.js} +19 -14
  21. package/dist/config-JDfTI4VI.js +106 -0
  22. package/dist/{config-CyapYSji.js → config-options-jnIFvwxD.js} +204 -592
  23. package/dist/config-runtime-BWf6JLWG.js +11 -0
  24. package/dist/conversation-binding-CxOlHiix.js +889 -0
  25. package/dist/{plugin-marketplace-discovery-B7gHXJ3d.js → conversation-control-CUCrSIQI.js} +10 -142
  26. package/dist/doctor-contract-api.js +5 -5
  27. package/dist/{dynamic-tools-BwpvTxaX.js → dynamic-tools-D-JBoaLt.js} +66 -70
  28. package/dist/{effective-mcp-catalog-CY9Jn4bA.js → effective-mcp-catalog-J_5Ep5Um.js} +3 -3
  29. package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
  30. package/dist/ephemeral-turn-DSwzP8YY.js +101 -0
  31. package/dist/{event-projector-assistant-message-B9kp6iGC.js → event-projector-assistant-message-BmBM4qBV.js} +12 -25
  32. package/dist/event-projector-usage-CIyrYYid.js +102 -0
  33. package/dist/{harness-Czh2Sdoc.js → harness-FR6eQgyO.js} +31 -24
  34. package/dist/harness.js +1 -1
  35. package/dist/history-rejection-B4nOXNXF.js +13 -0
  36. package/dist/incognito-session-uhrBF6wJ.js +15 -0
  37. package/dist/index.js +411 -2875
  38. package/dist/{isolated-completion-CRh-51AK.js → isolated-completion-DHBefrzg.js} +7 -4
  39. package/dist/launch-args-RXQwn8zV.js +90 -0
  40. package/dist/{managed-binary-DcpnJF9x.js → managed-binary-DrjjRRUD.js} +4 -103
  41. package/dist/managed-thread-store-D1t5jh3G.js +66 -0
  42. package/dist/media-understanding-provider.js +4 -1
  43. package/dist/{model-catalog-DT5vo6qo.js → model-catalog-B_6M04Wo.js} +6 -5
  44. package/dist/{models-CcrgSMQR.js → models-P9k2qAof.js} +3 -3
  45. package/dist/native-execution-policy-umd0tgh4.js +128 -0
  46. package/dist/{native-subagent-monitor-B3bvQGcg.js → native-subagent-monitor-BbCUKRwC.js} +69 -42
  47. package/dist/node-cli-sessions-rj0ysJwM.js +527 -0
  48. package/dist/{node-exec-server.runtime-nfbUOtUB.js → node-exec-server.runtime-BY_ctYnT.js} +53 -22
  49. package/dist/plan-BMJdMOEF.js +711 -0
  50. package/dist/plugin-activation-BQK-f5sV.js +133 -0
  51. package/dist/{thread-resume-BLgqkUc1.js → plugin-app-cache-key-CdSQzWyX.js} +4 -52
  52. package/dist/{plugin-approval-roundtrip-aQVdyL5g.js → plugin-approval-roundtrip-DeW95wB5.js} +1 -1
  53. package/dist/plugin-inventory-CoRCzWW4.js +325 -0
  54. package/dist/plugin-marketplace-discovery-3akBizzF.js +134 -0
  55. package/dist/{plugin-metadata-cache-BwCLTY_U.js → plugin-metadata-cache-DgNfRAGA.js} +13 -9
  56. package/dist/protocol-CAAcVIKF.js +275 -0
  57. package/dist/{provider-capabilities-BpG9Ltc5.js → provider-capabilities-W4tfK5Y5.js} +2 -2
  58. package/dist/{rate-limits-Fx_l4eNa.js → rate-limits-Bqnx1N4z.js} +1 -1
  59. package/dist/request-CGvGOpeR.js +198 -0
  60. package/dist/{run-attempt-BzthFQSM.js → run-attempt-DwKds3DN.js} +589 -373
  61. package/dist/{runtime-artifact-Bh_gf6-t.js → runtime-artifact-T-NwqeSH.js} +27 -27
  62. package/dist/sandbox-guard-BcT66fWy.js +165 -0
  63. package/dist/{session-binding-4Ki04sW-.js → session-binding-CKSepwIC.js} +29 -47
  64. package/dist/{session-binding-record-CyaXZvTe.js → session-binding-record-CaZjYwNS.js} +11 -25
  65. package/dist/session-catalog-HaDcp7Sv.js +1533 -0
  66. package/dist/session-catalog-adoption-BKLtSrwi.js +251 -0
  67. package/dist/session-catalog-archive-D0i2pGj2.js +56 -0
  68. package/dist/session-catalog-home-id-D7-aLiNt.js +190 -0
  69. package/dist/session-catalog-node-adoption-BUuDYY8R.js +182 -0
  70. package/dist/session-catalog-node-continue-CBtc4wkI.js +238 -0
  71. package/dist/session-catalog-parsing-CdD3JhdM.js +280 -0
  72. package/dist/session-catalog-provenance-DkJHo735.js +124 -0
  73. package/dist/{session-cli-BjLhpmS1.js → session-cli-CbgaHh0f.js} +3 -2
  74. package/dist/{session-history-DWmMqiqW.js → session-history-Cz-tOOYj.js} +6 -3
  75. package/dist/{session-upstream-marker-DReTpGz6.js → session-history-import-DFN7sWRU.js} +5 -50
  76. package/dist/{session-history-read-LHldwvyh.js → session-history-read-cxPUxyVV.js} +21 -7
  77. package/dist/session-history-worker-runtime.js +18 -6
  78. package/dist/{session-history.worker-zZVcx0ME.js → session-history.worker-CNEvGaU5.js} +58 -51
  79. package/dist/session-history.worker.js +1 -1
  80. package/dist/{session-initialization-BCFVnLL4.js → session-initialization-Jo86C60I.js} +2 -2
  81. package/dist/{session-permission-policy-BaueHmSj.js → session-permission-policy-B22InTp_.js} +4 -7
  82. package/dist/{session-retirement-DNdmYdFc.js → session-retirement-BSNG_mhf.js} +6 -5
  83. package/dist/session-upstream-marker-D15C9NHp.js +46 -0
  84. package/dist/{settled-turn-context-BOM3Y1pl.js → settled-turn-context-Du6gdUDd.js} +9 -9
  85. package/dist/{settled-turn-finalizer-BI-b1sry.js → settled-turn-finalizer-BuLUrZl2.js} +7 -6
  86. package/dist/shared-client-CVhez2Uo.js +2911 -0
  87. package/dist/{side-question-B6DWAw1A.js → side-question-DLbr2vUU.js} +64 -169
  88. package/dist/source-Da-h6f7e.js +518 -0
  89. package/dist/thread-archive-guard-D1bP04Tf.js +53 -0
  90. package/dist/{thread-lifecycle-DPK30jad.js → thread-lifecycle-D1pzRwHB.js} +112 -616
  91. package/dist/{thread-ownership-CbucAmmp.js → thread-ownership-D6oASVRu.js} +13 -15
  92. package/dist/thread-policy-D8kI7yAO.js +54 -0
  93. package/dist/thread-resume-T5cveyxA.js +52 -0
  94. package/dist/timeout-BVw8aaM1.js +33 -0
  95. package/dist/{transcript-mirror-attestation-Byl34PC-.js → transcript-mirror-attestation-DibE0krH.js} +17 -4
  96. package/dist/{transcript-mirror-_njEB84z.js → transcript-mirror-t5TOccct.js} +50 -260
  97. package/dist/{transport-stdio-CzTngV0j.js → transport-stdio-BGjHoYLr.js} +73 -43
  98. package/dist/{upstream-session-fork-1fwbNKzQ.js → upstream-session-fork-De-sLJ2r.js} +26 -18
  99. package/dist/{usage-i9fv5-4m.js → usage-CPPTmBvZ.js} +4 -3
  100. package/dist/version-omm6IPI3.js +12 -0
  101. package/dist/{web-search-provider.runtime-DKQn67A7.js → web-search-provider.runtime-CSVgQL0w.js} +3 -3
  102. package/openclaw.plugin.json +22 -1
  103. package/package.json +4 -4
  104. package/dist/request-C8H22rPi.js +0 -475
  105. package/dist/session-catalog-B47uwekb.js +0 -3272
  106. package/dist/shared-client-CKhX2kFt.js +0 -7505
  107. package/dist/thread-policy-CTalhWFy.js +0 -105
  108. package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-Co2Vfcf_.js} +1 -1
@@ -0,0 +1,238 @@
1
+ import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-BiodpIzq.js";
2
+ import { t as CODEX_CLI_SESSION_RESUME_COMMAND } from "./node-cli-sessions-rj0ysJwM.js";
3
+ import { a as lookupNodeCodexCatalogRecord } from "./session-catalog-HaDcp7Sv.js";
4
+ import { T as unwrapNodeInvokePayload, _ as parseTranscriptPage, d as catalogError, f as filterCatalogPageByTitle, h as parseCatalogPage, l as NODE_INVOKE_TIMEOUT_MS, n as CODEX_APP_SERVER_THREADS_LIST_COMMAND, o as CatalogParamsError, p as isInteractiveThreadSource, r as CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND, u as boundedCatalogString } from "./session-catalog-parsing-CdD3JhdM.js";
5
+ import { t as codexLastTerminalTurnId } from "./session-upstream-marker-D15C9NHp.js";
6
+ import { n as withTimeout } from "./timeout-BVw8aaM1.js";
7
+ import { createOrReuseNodeAdoptedSession, finalizeNodeAdoptedSession, findNodeAdoptedSessionEntry, nodeSessionMarker, runSessionActionExclusive } from "./session-catalog-node-adoption-BUuDYY8R.js";
8
+ import { resolveSessionAgentIdsStrict } from "openclaw/plugin-sdk/agent-scope-runtime";
9
+ import { createSessionCatalogAdoptionCoordinator, publishSessionCatalogHost, sessionCatalogAdoptedSourceKey } from "openclaw/plugin-sdk/session-catalog";
10
+ //#region extensions/codex/src/session-catalog-node-continue.ts
11
+ const CODEX_NODE_CONTINUE_COMMANDS = [
12
+ CODEX_APP_SERVER_THREADS_LIST_COMMAND,
13
+ CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND,
14
+ CODEX_CLI_SESSION_RESUME_COMMAND
15
+ ];
16
+ const NODE_CATALOG_LIST_RESPONSE_TIMEOUT_MS = 8e3;
17
+ const continueNodeAdoption = createSessionCatalogAdoptionCoordinator();
18
+ function nodeLabel(node) {
19
+ return node.displayName?.trim() || node.remoteIp?.trim() || node.nodeId;
20
+ }
21
+ function compareNodeLabels(left, right) {
22
+ const leftLabel = nodeLabel(left);
23
+ const rightLabel = nodeLabel(right);
24
+ if (leftLabel < rightLabel) return -1;
25
+ if (leftLabel > rightLabel) return 1;
26
+ return 0;
27
+ }
28
+ function canContinueCodexOnNode(node) {
29
+ return node.connected === true && CODEX_NODE_CONTINUE_COMMANDS.every((command) => node.commands?.includes(command) === true && node.invocableCommands?.includes(command) === true);
30
+ }
31
+ async function listPairedNode(params) {
32
+ const hostId = `node:${params.node.nodeId}`;
33
+ const common = {
34
+ hostId,
35
+ label: nodeLabel(params.node),
36
+ kind: "node",
37
+ nodeId: params.node.nodeId,
38
+ canContinueCodex: canContinueCodexOnNode(params.node),
39
+ ...params.terminalCapabilities
40
+ };
41
+ if (params.node.connected !== true) {
42
+ const host = {
43
+ ...common,
44
+ connected: false,
45
+ sessions: [],
46
+ error: {
47
+ code: "NODE_OFFLINE",
48
+ message: "Paired node is offline"
49
+ }
50
+ };
51
+ params.onHost?.(host);
52
+ return host;
53
+ }
54
+ if (!params.node.commands?.includes("codex.appServer.threads.list.v1")) {
55
+ const host = {
56
+ ...common,
57
+ connected: true,
58
+ sessions: []
59
+ };
60
+ params.onHost?.(host);
61
+ return host;
62
+ }
63
+ const eventualHost = Promise.resolve().then(async () => {
64
+ const raw = await params.runtime.nodes.invoke({
65
+ nodeId: params.node.nodeId,
66
+ command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
67
+ params: {
68
+ agentId: params.agentId,
69
+ cursor: params.query.cursors?.[hostId],
70
+ limit: params.query.limitPerHost,
71
+ searchTerm: params.query.search
72
+ },
73
+ timeoutMs: NODE_INVOKE_TIMEOUT_MS,
74
+ scopes: ["operator.write"],
75
+ signal: params.signal
76
+ });
77
+ const page = filterCatalogPageByTitle(parseCatalogPage(unwrapNodeInvokePayload(raw)), params.query.search);
78
+ return {
79
+ ...common,
80
+ connected: true,
81
+ ...page,
82
+ sessions: page.sessions.map((session) => {
83
+ const adopted = params.adoptedSessions.get(sessionCatalogAdoptedSourceKey(hostId, session.threadId));
84
+ return adopted ? Object.assign({}, session, { sessionKey: adopted.key }) : session;
85
+ })
86
+ };
87
+ }).catch((error) => ({
88
+ ...common,
89
+ connected: true,
90
+ sessions: [],
91
+ error: catalogError("NODE_INVOKE_FAILED", error)
92
+ }));
93
+ publishSessionCatalogHost(params, eventualHost);
94
+ try {
95
+ return await withTimeout(eventualHost, NODE_CATALOG_LIST_RESPONSE_TIMEOUT_MS, "paired node Codex session catalog timed out");
96
+ } catch (error) {
97
+ return {
98
+ ...common,
99
+ connected: true,
100
+ sessions: [],
101
+ error: catalogError("NODE_INVOKE_FAILED", error)
102
+ };
103
+ }
104
+ }
105
+ async function requireNodeForCodexContinue(params) {
106
+ const nodeId = params.hostId.slice(5).trim();
107
+ if (!nodeId || params.hostId !== `node:${nodeId}`) throw new CatalogParamsError("Codex session catalog hostId is invalid");
108
+ const node = (await params.runtime.nodes.list()).nodes.find((candidate) => candidate.nodeId === nodeId);
109
+ if (!node || !canContinueCodexOnNode(node)) throw new CatalogParamsError("paired node does not permit Codex session continuation");
110
+ return {
111
+ node,
112
+ nodeId
113
+ };
114
+ }
115
+ function requireContinuableNodeRecord(record) {
116
+ if (record.archived) throw new CatalogParamsError("Codex session is archived on the paired node");
117
+ if (!isInteractiveThreadSource(record.source)) throw new CatalogParamsError("Codex session is not a non-archived interactive Codex session");
118
+ if (record.status === "idle" || record.status === "notLoaded") return;
119
+ if (record.status === "active") throw new CatalogParamsError("Codex session is active on the paired node; wait for it to finish before continuing");
120
+ throw new CatalogParamsError("Codex session cannot be continued in its current state");
121
+ }
122
+ async function readNodeCodexHistory(params) {
123
+ const raw = await params.runtime.nodes.invoke({
124
+ nodeId: params.nodeId,
125
+ command: CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND,
126
+ params: {
127
+ agentId: params.agentId,
128
+ threadId: params.record.threadId,
129
+ limit: 50
130
+ },
131
+ timeoutMs: NODE_INVOKE_TIMEOUT_MS,
132
+ scopes: ["operator.write"]
133
+ });
134
+ const page = parseTranscriptPage(unwrapNodeInvokePayload(raw));
135
+ const thread = {
136
+ id: params.record.threadId,
137
+ createdAt: params.record.createdAt ?? 0,
138
+ modelProvider: params.record.modelProvider ?? "openai",
139
+ projectId: null,
140
+ turns: page.data.toReversed()
141
+ };
142
+ return {
143
+ thread,
144
+ throughTurnId: codexLastTerminalTurnId(thread, (value) => boundedCatalogString(value, 256)) ?? null
145
+ };
146
+ }
147
+ async function continueNodeCodexSessionInner(params) {
148
+ const { nodeId } = await requireNodeForCodexContinue({
149
+ runtime: params.api.runtime,
150
+ hostId: params.hostId
151
+ });
152
+ const lookup = await lookupNodeCodexCatalogRecord({
153
+ agentId: params.agentId,
154
+ runtime: params.api.runtime,
155
+ nodeId,
156
+ threadId: params.threadId
157
+ });
158
+ if (lookup.kind !== "found") throw new CatalogParamsError(lookup.kind === "cursor-cycle" ? "Codex session eligibility could not be verified" : "Codex session is unavailable on the paired node");
159
+ const record = lookup.record;
160
+ requireContinuableNodeRecord(record);
161
+ const existing = findNodeAdoptedSessionEntry({
162
+ agentId: params.agentId,
163
+ config: params.config,
164
+ runtime: params.api.runtime,
165
+ hostId: params.hostId,
166
+ threadId: params.threadId,
167
+ includeInitializing: true
168
+ });
169
+ let adopted;
170
+ let disposition;
171
+ if (existing) {
172
+ adopted = existing;
173
+ disposition = "existing";
174
+ } else {
175
+ const history = await readNodeCodexHistory({
176
+ agentId: params.agentId,
177
+ runtime: params.api.runtime,
178
+ nodeId,
179
+ record
180
+ });
181
+ adopted = await createOrReuseNodeAdoptedSession({
182
+ agentId: params.agentId,
183
+ api: params.api,
184
+ config: params.config,
185
+ hostId: params.hostId,
186
+ nodeId,
187
+ record,
188
+ history
189
+ });
190
+ disposition = "forked";
191
+ }
192
+ const marker = nodeSessionMarker({
193
+ hostId: params.hostId,
194
+ threadId: params.threadId,
195
+ nodeId
196
+ });
197
+ return {
198
+ sessionKey: adopted.key,
199
+ disposition,
200
+ conversationBinding: {
201
+ summary: "Continue this Codex session on its paired node.",
202
+ detachHint: "Start a new chat to leave the paired-node Codex session.",
203
+ data: createCodexCliNodeConversationBindingData({
204
+ nodeId,
205
+ sessionId: params.threadId,
206
+ agentId: adopted.agentId,
207
+ cwd: record.cwd
208
+ })
209
+ },
210
+ afterConversationBound: async () => await finalizeNodeAdoptedSession({
211
+ api: params.api,
212
+ adopted,
213
+ marker
214
+ })
215
+ };
216
+ }
217
+ async function continueNodeCodexSession(params) {
218
+ if (params.clientScopes?.includes("operator.admin") !== true) throw new CatalogParamsError("continuing a paired-node Codex session requires operator.admin");
219
+ const nodeId = params.hostId.slice(5).trim();
220
+ if (!nodeId || params.hostId !== `node:${nodeId}`) throw new CatalogParamsError("Codex session catalog hostId is invalid");
221
+ const agentId = resolveSessionAgentIdsStrict({
222
+ config: params.config,
223
+ agentId: params.agentId
224
+ }).sessionAgentId;
225
+ const sourceKey = sessionCatalogAdoptedSourceKey(`node:${nodeId}`, params.threadId);
226
+ const operationKey = sessionCatalogAdoptedSourceKey(agentId, sourceKey);
227
+ return await continueNodeAdoption({
228
+ sourceKey: operationKey,
229
+ findExisting: () => void 0,
230
+ create: () => runSessionActionExclusive(sourceKey, async () => continueNodeCodexSessionInner({
231
+ ...params,
232
+ agentId
233
+ })),
234
+ complete: async (continued) => continued
235
+ });
236
+ }
237
+ //#endregion
238
+ export { compareNodeLabels, continueNodeCodexSession, listPairedNode, nodeLabel };
@@ -0,0 +1,280 @@
1
+ import { n as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, t as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES } from "./protocol-CAAcVIKF.js";
2
+ import { asFiniteNumber, isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
+ //#region extensions/codex/src/session-catalog-parsing.ts
5
+ const DEFAULT_PAGE_LIMIT = 50;
6
+ const CODEX_APP_SERVER_THREADS_CAPABILITY = "codex-app-server-threads";
7
+ const CODEX_APP_SERVER_THREADS_LIST_COMMAND = "codex.appServer.threads.list.v1";
8
+ const CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND = "codex.appServer.thread.turns.list.v1";
9
+ const CODEX_CATALOG_TRANSCRIPT_READ_COMMAND = "codex.sessionCatalog.transcript.read.v1";
10
+ const CODEX_LOCAL_SESSION_HOST_ID = "gateway:local";
11
+ const NODE_INVOKE_TIMEOUT_MS = 65e3;
12
+ const MAX_SEARCH_LENGTH = 500;
13
+ const MAX_CURSOR_LENGTH = 4096;
14
+ const MAX_CURSOR_COUNT = 100;
15
+ const MAX_HOST_ID_LENGTH = 256;
16
+ const MAX_CWD_LENGTH = 4096;
17
+ const MAX_SESSION_NAME_LENGTH = 500;
18
+ const MAX_SESSION_PREVIEW_LENGTH = 500;
19
+ const MAX_SESSION_KEY_LENGTH = 1024;
20
+ const MAX_METADATA_LENGTH = 500;
21
+ const MAX_ACTIVE_FLAGS = 16;
22
+ const MAX_TRANSCRIPT_PAGE_BYTES = 20971520;
23
+ var CatalogParamsError = class extends Error {};
24
+ function readControlCursor(value, label) {
25
+ if (value === void 0 || value === null) return;
26
+ if (typeof value !== "string" || !value.trim() || value.length > 4096) throw new CatalogParamsError(`invalid Codex session catalog ${label} cursor`);
27
+ return value;
28
+ }
29
+ function boundedCatalogString(value, maxLength, overflow = "omit") {
30
+ if (typeof value !== "string") return;
31
+ const normalized = value.trim();
32
+ if (!normalized) return;
33
+ if (normalized.length <= maxLength) return normalized;
34
+ return overflow === "truncate" ? truncateUtf16Safe(normalized, maxLength) : void 0;
35
+ }
36
+ function catalogPreview(value, sanitize) {
37
+ if (typeof value !== "string") return;
38
+ return boundedCatalogString(sanitize(value.replace(/\s+/g, " ")), MAX_SESSION_PREVIEW_LENGTH, "truncate");
39
+ }
40
+ function normalizeInteractiveThreadSource(source) {
41
+ if (CODEX_INTERACTIVE_THREAD_SOURCE_KINDS.some((kind) => kind === source) || CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source)) return source;
42
+ if (isRecord(source) && CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES.some((kind) => kind === source.custom)) return source.custom;
43
+ }
44
+ function isInteractiveThreadSource(source) {
45
+ return normalizeInteractiveThreadSource(source) !== void 0;
46
+ }
47
+ function toCatalogSession(thread, archived, sanitize) {
48
+ const source = normalizeInteractiveThreadSource(thread.source);
49
+ if (!source) return;
50
+ const record = thread;
51
+ const threadId = boundedCatalogString(thread.id, 256);
52
+ if (!threadId) return;
53
+ const activeFlags = thread.status?.type === "active" ? thread.status.activeFlags?.flatMap((flag) => {
54
+ const normalized = boundedCatalogString(flag, 128);
55
+ return normalized ? [normalized] : [];
56
+ }).slice(0, MAX_ACTIVE_FLAGS) : void 0;
57
+ const gitInfo = isRecord(record.gitInfo) ? record.gitInfo : void 0;
58
+ const sessionId = boundedCatalogString(thread.sessionId, 256);
59
+ const name = boundedCatalogString(thread.name, MAX_SESSION_NAME_LENGTH, "truncate");
60
+ const fallbackName = name ? void 0 : catalogPreview(thread.preview, sanitize);
61
+ const cwd = boundedCatalogString(thread.cwd, MAX_CWD_LENGTH);
62
+ const modelProvider = boundedCatalogString(record.modelProvider, MAX_METADATA_LENGTH, "truncate");
63
+ const cliVersion = boundedCatalogString(record.cliVersion, MAX_METADATA_LENGTH, "truncate");
64
+ const gitBranch = boundedCatalogString(gitInfo?.branch, MAX_METADATA_LENGTH, "truncate");
65
+ return {
66
+ threadId,
67
+ status: thread.status?.type ?? "notLoaded",
68
+ archived,
69
+ ...sessionId ? { sessionId } : {},
70
+ ...thread.name === null ? { name: null } : name ? { name } : {},
71
+ ...fallbackName ? { fallbackName } : {},
72
+ ...cwd ? { cwd } : {},
73
+ ...activeFlags?.length ? { activeFlags } : {},
74
+ ...typeof thread.createdAt === "number" && Number.isFinite(thread.createdAt) ? { createdAt: thread.createdAt } : {},
75
+ ...typeof thread.updatedAt === "number" && Number.isFinite(thread.updatedAt) ? { updatedAt: thread.updatedAt } : {},
76
+ ...typeof record.recencyAt === "number" && Number.isFinite(record.recencyAt) ? { recencyAt: record.recencyAt } : record.recencyAt === null ? { recencyAt: null } : {},
77
+ source,
78
+ ...modelProvider ? { modelProvider } : {},
79
+ ...cliVersion ? { cliVersion } : {},
80
+ ...gitBranch ? { gitBranch } : {}
81
+ };
82
+ }
83
+ function normalizeLimit(value, key) {
84
+ if (value === void 0) return DEFAULT_PAGE_LIMIT;
85
+ if (!Number.isInteger(value) || value < 1 || value > 100) throw new CatalogParamsError(`${key} must be an integer from 1 to 100`);
86
+ return value;
87
+ }
88
+ function readBoundedOptionalString(params, key, maxLength) {
89
+ const value = params[key];
90
+ if (value === void 0) return;
91
+ if (typeof value !== "string") throw new CatalogParamsError(`${key} must be a string`);
92
+ const trimmed = value.trim();
93
+ if (!trimmed) return;
94
+ if (trimmed.length > maxLength) throw new CatalogParamsError(`${key} must be at most ${maxLength} characters`);
95
+ return trimmed;
96
+ }
97
+ function requireOnlyKeys(params, allowed) {
98
+ const unknown = Object.keys(params).find((key) => !allowed.has(key));
99
+ if (unknown) throw new CatalogParamsError(`unknown Codex session catalog parameter: ${unknown}`);
100
+ }
101
+ function readPageParams(value) {
102
+ if (!isRecord(value)) throw new CatalogParamsError("Codex session catalog parameters must be an object");
103
+ const params = value;
104
+ requireOnlyKeys(params, /* @__PURE__ */ new Set([
105
+ "cursor",
106
+ "limit",
107
+ "searchTerm",
108
+ "cwd"
109
+ ]));
110
+ const cursor = readBoundedOptionalString(params, "cursor", MAX_CURSOR_LENGTH);
111
+ const searchTerm = readBoundedOptionalString(params, "searchTerm", MAX_SEARCH_LENGTH);
112
+ const cwd = readBoundedOptionalString(params, "cwd", MAX_CWD_LENGTH);
113
+ return {
114
+ limit: normalizeLimit(params.limit, "limit"),
115
+ ...cursor ? { cursor } : {},
116
+ ...searchTerm ? { searchTerm } : {},
117
+ ...cwd ? { cwd } : {}
118
+ };
119
+ }
120
+ function readGatewayParams(value) {
121
+ if (value !== void 0 && !isRecord(value)) throw new CatalogParamsError("Codex session catalog parameters must be an object");
122
+ const params = isRecord(value) ? value : {};
123
+ requireOnlyKeys(params, /* @__PURE__ */ new Set([
124
+ "search",
125
+ "limitPerHost",
126
+ "hostIds",
127
+ "cursors"
128
+ ]));
129
+ const search = readBoundedOptionalString(params, "search", MAX_SEARCH_LENGTH);
130
+ let hostIds;
131
+ if (params.hostIds !== void 0) {
132
+ if (!Array.isArray(params.hostIds) || params.hostIds.length > 100) throw new CatalogParamsError(`hostIds must contain at most 100 host ids`);
133
+ hostIds = [...new Set(params.hostIds.map((hostId) => readHostId(hostId)))];
134
+ }
135
+ let cursors;
136
+ if (params.cursors !== void 0) {
137
+ if (!isRecord(params.cursors)) throw new CatalogParamsError("cursors must be an object");
138
+ const entries = Object.entries(params.cursors);
139
+ if (entries.length > MAX_CURSOR_COUNT) throw new CatalogParamsError(`cursors may contain at most ${MAX_CURSOR_COUNT} hosts`);
140
+ cursors = {};
141
+ for (const [hostId, cursor] of entries) {
142
+ const normalizedHostId = hostId.trim();
143
+ 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}`);
144
+ if (typeof cursor !== "string" || !cursor.trim() || cursor.trim().length > 4096) throw new CatalogParamsError(`invalid cursor for Codex session catalog host: ${hostId}`);
145
+ cursors[normalizedHostId] = cursor.trim();
146
+ }
147
+ }
148
+ return {
149
+ limitPerHost: normalizeLimit(params.limitPerHost, "limitPerHost"),
150
+ ...search ? { search } : {},
151
+ ...hostIds && hostIds.length > 0 ? { hostIds } : {},
152
+ ...cursors && Object.keys(cursors).length > 0 ? { cursors } : {}
153
+ };
154
+ }
155
+ function readHostId(value) {
156
+ if (typeof value !== "string") throw new CatalogParamsError("Codex session catalog host ids must be strings");
157
+ const hostId = value.trim();
158
+ if (hostId.length === 0 || hostId.length > MAX_HOST_ID_LENGTH || !hostId.startsWith("gateway:") && !hostId.startsWith("node:")) throw new CatalogParamsError(`invalid Codex session catalog host id: ${value}`);
159
+ return hostId;
160
+ }
161
+ function parseJsonParams(paramsJSON) {
162
+ if (!paramsJSON?.trim()) return {};
163
+ try {
164
+ return JSON.parse(paramsJSON);
165
+ } catch (error) {
166
+ throw new Error("Codex session catalog parameters must be valid JSON", { cause: error });
167
+ }
168
+ }
169
+ function parseOptionalCatalogString(value, field, maxLength) {
170
+ if (value === void 0) return;
171
+ if (typeof value !== "string" || value.length > maxLength) throw new Error(`Codex session catalog returned an invalid ${field}`);
172
+ return value;
173
+ }
174
+ function parseCatalogSession(value, options = {}) {
175
+ if (!isRecord(value) || typeof value.threadId !== "string" || !value.threadId.trim() || value.threadId.length > 256 || value.archived !== false) throw new Error("Codex session catalog returned an invalid session");
176
+ const status = parseOptionalCatalogString(value.status, "status", 64);
177
+ if (!status?.trim()) throw new Error("Codex session catalog returned an invalid status");
178
+ if (value.activeFlags !== void 0 && !Array.isArray(value.activeFlags)) throw new Error("Codex session catalog returned invalid active flags");
179
+ if (Array.isArray(value.activeFlags) && value.activeFlags.length > MAX_ACTIVE_FLAGS) throw new Error("Codex session catalog returned too many active flags");
180
+ const activeFlags = Array.isArray(value.activeFlags) ? value.activeFlags.map((entry) => {
181
+ const flag = parseOptionalCatalogString(entry, "active flag", 128);
182
+ if (flag === void 0) throw new Error("Codex session catalog returned an invalid active flag");
183
+ return flag;
184
+ }) : void 0;
185
+ const sessionId = parseOptionalCatalogString(value.sessionId, "session id", 256);
186
+ const name = value.name === null ? null : parseOptionalCatalogString(value.name, "session name", MAX_SESSION_NAME_LENGTH);
187
+ const fallbackName = parseOptionalCatalogString(value.fallbackName, "session fallback name", MAX_SESSION_PREVIEW_LENGTH);
188
+ const cwd = parseOptionalCatalogString(value.cwd, "cwd", MAX_CWD_LENGTH);
189
+ const source = parseOptionalCatalogString(value.source, "source", MAX_METADATA_LENGTH);
190
+ const modelProvider = parseOptionalCatalogString(value.modelProvider, "model provider", MAX_METADATA_LENGTH);
191
+ const cliVersion = parseOptionalCatalogString(value.cliVersion, "CLI version", MAX_METADATA_LENGTH);
192
+ const gitBranch = parseOptionalCatalogString(value.gitBranch, "Git branch", MAX_METADATA_LENGTH);
193
+ const sessionKey = options.allowSessionKey ? parseOptionalCatalogString(value.sessionKey, "OpenClaw session key", MAX_SESSION_KEY_LENGTH) : void 0;
194
+ const createdAt = asFiniteNumber(value.createdAt);
195
+ const updatedAt = asFiniteNumber(value.updatedAt);
196
+ const recencyAt = value.recencyAt === null ? null : asFiniteNumber(value.recencyAt);
197
+ return {
198
+ threadId: value.threadId,
199
+ status,
200
+ archived: value.archived,
201
+ ...sessionId !== void 0 ? { sessionId } : {},
202
+ ...name !== void 0 ? { name } : {},
203
+ ...fallbackName !== void 0 ? { fallbackName } : {},
204
+ ...cwd !== void 0 ? { cwd } : {},
205
+ ...activeFlags && activeFlags.length > 0 ? { activeFlags } : {},
206
+ ...createdAt !== void 0 ? { createdAt } : {},
207
+ ...updatedAt !== void 0 ? { updatedAt } : {},
208
+ ...recencyAt !== void 0 ? { recencyAt } : {},
209
+ ...source !== void 0 ? { source } : {},
210
+ ...modelProvider !== void 0 ? { modelProvider } : {},
211
+ ...cliVersion !== void 0 ? { cliVersion } : {},
212
+ ...gitBranch !== void 0 ? { gitBranch } : {},
213
+ ...sessionKey !== void 0 ? { sessionKey } : {}
214
+ };
215
+ }
216
+ function parseCatalogPage(value, options = {}) {
217
+ if (!isRecord(value) || !Array.isArray(value.sessions) || value.sessions.length > 100) throw new Error("Codex session catalog returned an invalid page");
218
+ const nextCursor = parseOptionalCatalogString(value.nextCursor, "next cursor", MAX_CURSOR_LENGTH);
219
+ const backwardsCursor = parseOptionalCatalogString(value.backwardsCursor, "backwards cursor", MAX_CURSOR_LENGTH);
220
+ return {
221
+ sessions: value.sessions.map((session) => parseCatalogSession(session, options)),
222
+ ...nextCursor ? { nextCursor } : {},
223
+ ...backwardsCursor ? { backwardsCursor } : {}
224
+ };
225
+ }
226
+ function filterCatalogPageByTitle(page, searchTerm) {
227
+ if (!searchTerm) return page;
228
+ return {
229
+ ...page,
230
+ sessions: page.sessions.filter((session) => (session.name ?? session.fallbackName)?.toLocaleLowerCase().includes(searchTerm.toLocaleLowerCase()))
231
+ };
232
+ }
233
+ function unwrapNodeInvokePayload(value) {
234
+ if (!isRecord(value)) return value;
235
+ if (typeof value.payloadJSON === "string" && value.payloadJSON.trim()) try {
236
+ return JSON.parse(value.payloadJSON);
237
+ } catch (error) {
238
+ throw new Error("Codex node returned malformed session catalog JSON", { cause: error });
239
+ }
240
+ return "payload" in value ? value.payload : value;
241
+ }
242
+ function catalogErrorDetail(error) {
243
+ if (error instanceof Error) return error.message.trim();
244
+ if (typeof error === "string") return error.trim();
245
+ if (error && typeof error === "object" && "message" in error) {
246
+ const message = error.message;
247
+ return typeof message === "string" ? message.trim() : "";
248
+ }
249
+ return "";
250
+ }
251
+ function catalogError(code, error) {
252
+ const summary = {
253
+ APP_SERVER_UNAVAILABLE: "Codex app-server is unavailable on this host",
254
+ NODE_INVOKE_FAILED: "The paired node could not return its Codex session catalog",
255
+ NODE_LIST_FAILED: "Paired nodes could not be listed"
256
+ }[code] ?? "Codex session catalog request failed";
257
+ const detail = code === "NODE_LIST_FAILED" ? catalogErrorDetail(error) : "";
258
+ return {
259
+ code,
260
+ message: detail && detail !== summary ? `${summary}: ${detail}` : summary
261
+ };
262
+ }
263
+ function parseTranscriptPage(value) {
264
+ if (!isRecord(value) || !Array.isArray(value.data) || value.data.length > 50 || value.data.some((turn) => !isRecord(turn) || !Array.isArray(turn.items) || turn.items.some((item) => !isRecord(item)))) throw new Error("Codex app-server returned an invalid transcript page");
265
+ const nextCursor = readControlCursor(value.nextCursor, "transcript next response");
266
+ const backwardsCursor = readControlCursor(value.backwardsCursor, "transcript backwards response");
267
+ const page = {
268
+ data: value.data,
269
+ ...nextCursor ? { nextCursor } : {},
270
+ ...backwardsCursor ? { backwardsCursor } : {}
271
+ };
272
+ if (Buffer.byteLength(JSON.stringify(page), "utf8") > 20971520) throw new Error("Codex app-server transcript page exceeds the safe response size");
273
+ return page;
274
+ }
275
+ function requireBoundThread(entry) {
276
+ if (!entry.boundThreadId) throw new CatalogParamsError("Codex adoption is missing its bound thread. Retry.");
277
+ return entry.boundThreadId;
278
+ }
279
+ //#endregion
280
+ export { requireOnlyKeys as C, requireBoundThread as S, unwrapNodeInvokePayload as T, parseTranscriptPage as _, CODEX_LOCAL_SESSION_HOST_ID as a, readGatewayParams as b, MAX_TRANSCRIPT_PAGE_BYTES as c, catalogError as d, filterCatalogPageByTitle as f, parseJsonParams as g, parseCatalogPage as h, CODEX_CATALOG_TRANSCRIPT_READ_COMMAND as i, NODE_INVOKE_TIMEOUT_MS as l, normalizeLimit as m, CODEX_APP_SERVER_THREADS_LIST_COMMAND as n, CatalogParamsError as o, isInteractiveThreadSource as p, CODEX_APP_SERVER_THREAD_TURNS_LIST_COMMAND as r, MAX_CURSOR_LENGTH as s, CODEX_APP_SERVER_THREADS_CAPABILITY as t, boundedCatalogString as u, readBoundedOptionalString as v, toCatalogSession as w, readPageParams as x, readControlCursor as y };
@@ -0,0 +1,124 @@
1
+ import { o as isJsonObject } from "./protocol-CAAcVIKF.js";
2
+ import path from "node:path";
3
+ import { createZstdDecompress } from "node:zlib";
4
+ import { root } from "openclaw/plugin-sdk/file-access-runtime";
5
+ //#region extensions/codex/src/app-server/rpc-error.ts
6
+ /** RPC error wrapper that preserves app-server error code and data. */
7
+ var CodexAppServerRpcError = class extends Error {
8
+ constructor(error, method) {
9
+ super(formatCodexAppServerRpcErrorMessage(error, method));
10
+ this.name = "CodexAppServerRpcError";
11
+ this.code = error.code;
12
+ this.data = error.data;
13
+ this.method = method;
14
+ }
15
+ };
16
+ function isCodexThreadReadMissingError(error, threadId) {
17
+ return error instanceof CodexAppServerRpcError && error.method === "thread/read" && error.code === -32600 && error.message === `thread not loaded: ${threadId}`;
18
+ }
19
+ function formatCodexAppServerRpcErrorMessage(error, method) {
20
+ const message = error.message || `${method} failed`;
21
+ const detail = readCodexAppServerRpcReloginDetail(error.data);
22
+ return detail && !message.includes(detail) ? `${message}: ${detail}` : message;
23
+ }
24
+ function readCodexAppServerRpcReloginDetail(data) {
25
+ const record = isJsonObject(data) ? data : void 0;
26
+ const nested = isJsonObject(record?.error) ? record.error : record;
27
+ if (!nested) return;
28
+ const isRelogin = nested.action === "relogin" || nested.reason === "cloudRequirements" && nested.errorCode === "Auth";
29
+ const detail = typeof nested.detail === "string" ? nested.detail.trim() : "";
30
+ return isRelogin && detail ? detail : void 0;
31
+ }
32
+ //#endregion
33
+ //#region extensions/codex/src/session-catalog-provenance.ts
34
+ const MAX_SESSION_META_BYTES = 1048576;
35
+ const SESSION_META_READ_CHUNK_BYTES = 65536;
36
+ const MAX_PROVENANCE_CACHE_ENTRIES = 2e4;
37
+ const provenanceByPath = /* @__PURE__ */ new Map();
38
+ function cacheProvenance(key, value) {
39
+ provenanceByPath.delete(key);
40
+ provenanceByPath.set(key, value);
41
+ while (provenanceByPath.size > MAX_PROVENANCE_CACHE_ENTRIES) {
42
+ const oldest = provenanceByPath.keys().next().value;
43
+ if (oldest === void 0) break;
44
+ provenanceByPath.delete(oldest);
45
+ }
46
+ }
47
+ /** Undefined means the metadata line is not durable enough to cache yet. */
48
+ async function readCodexSessionMeta(sessionsRoot, rolloutPath, threadId) {
49
+ let safeRoot;
50
+ try {
51
+ safeRoot = await root(sessionsRoot, {
52
+ hardlinks: "reject",
53
+ maxBytes: Number.MAX_SAFE_INTEGER,
54
+ symlinks: "reject"
55
+ });
56
+ } catch {
57
+ return;
58
+ }
59
+ const candidates = rolloutPath.endsWith(".zst") ? [rolloutPath, rolloutPath.slice(0, -4)] : [rolloutPath, `${rolloutPath}.zst`];
60
+ for (const candidate of candidates) {
61
+ let opened;
62
+ try {
63
+ opened = await safeRoot.open(path.relative(sessionsRoot, candidate));
64
+ } catch {
65
+ continue;
66
+ }
67
+ const input = opened.handle.createReadStream({
68
+ autoClose: false,
69
+ highWaterMark: SESSION_META_READ_CHUNK_BYTES
70
+ });
71
+ const reader = candidate.endsWith(".zst") ? input.pipe(createZstdDecompress()) : input;
72
+ try {
73
+ const chunks = [];
74
+ let bytesReadTotal = 0;
75
+ let line;
76
+ for await (const value of reader) {
77
+ const chunk = Buffer.isBuffer(value) ? value : Buffer.from(value);
78
+ const remaining = MAX_SESSION_META_BYTES - bytesReadTotal;
79
+ if (remaining <= 0) break;
80
+ const bounded = chunk.subarray(0, remaining);
81
+ bytesReadTotal += bounded.length;
82
+ const newline = bounded.indexOf(10);
83
+ chunks.push(newline >= 0 ? bounded.subarray(0, newline) : bounded);
84
+ if (newline >= 0) {
85
+ line = Buffer.concat(chunks).toString("utf8");
86
+ break;
87
+ }
88
+ }
89
+ if (!line) continue;
90
+ let parsed;
91
+ try {
92
+ parsed = JSON.parse(line);
93
+ } catch {
94
+ continue;
95
+ }
96
+ if (!isJsonObject(parsed) || parsed.type !== "session_meta" || !isJsonObject(parsed.payload)) return null;
97
+ const payload = parsed.payload;
98
+ return payload.id === threadId ? payload : null;
99
+ } catch {
100
+ continue;
101
+ } finally {
102
+ reader.destroy();
103
+ input.destroy();
104
+ await opened.handle.close().catch(() => void 0);
105
+ }
106
+ }
107
+ }
108
+ /**
109
+ * Codex 0.147 reports OpenClaw app-server rollouts as `vscode`, so the rollout's
110
+ * immutable session metadata is the authoritative historical provenance.
111
+ */
112
+ async function isOpenClawManagedCodexThread(thread, localSessionsRoot) {
113
+ const rolloutPath = typeof thread.path === "string" ? thread.path.trim() : "";
114
+ if (!localSessionsRoot || !rolloutPath) return false;
115
+ const cacheKey = `${localSessionsRoot}\0${rolloutPath}`;
116
+ const cached = provenanceByPath.get(cacheKey);
117
+ if (cached !== void 0) return cached;
118
+ const metadata = await readCodexSessionMeta(localSessionsRoot, rolloutPath, thread.id);
119
+ const managed = metadata === void 0 ? void 0 : metadata?.originator === "openclaw";
120
+ if (managed !== void 0) cacheProvenance(cacheKey, managed);
121
+ return managed ?? false;
122
+ }
123
+ //#endregion
124
+ export { isCodexThreadReadMissingError as i, readCodexSessionMeta as n, CodexAppServerRpcError as r, isOpenClawManagedCodexThread as t };
@@ -1,8 +1,9 @@
1
- import "./session-catalog-B47uwekb.js";
1
+ import "./session-catalog-HaDcp7Sv.js";
2
+ import "./session-catalog-parsing-CdD3JhdM.js";
2
3
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
3
4
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
4
- import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
5
5
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
6
+ import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
6
7
  import { addGatewayClientOptions, callGatewayFromCli } from "openclaw/plugin-sdk/gateway-runtime";
7
8
  //#region extensions/codex/src/session-cli.ts
8
9
  const CODEX_SESSION_CATALOG_CLI_TIMEOUT_MS = 75e3;
@@ -1,6 +1,6 @@
1
- import { n as readCodexNativeHistory, t as consumeCodexHistory } from "./session-history-read-LHldwvyh.js";
2
- import { getSessionEntry, parseSqliteSessionFileMarker, resolveTranscriptSessionKeyBySessionId } from "openclaw/plugin-sdk/session-store-runtime";
1
+ import { n as readCodexNativeHistory, t as consumeCodexHistory } from "./session-history-read-cxPUxyVV.js";
3
2
  import { SessionManager } from "openclaw/plugin-sdk/agent-sessions";
3
+ import { getSessionEntry, parseSqliteSessionFileMarker, resolveTranscriptSessionKeyBySessionId } from "openclaw/plugin-sdk/session-store-runtime";
4
4
  //#region extensions/codex/src/app-server/session-history.ts
5
5
  function resolveCodexHistoryTarget(target, admission) {
6
6
  if (target.sessionTarget) {
@@ -64,7 +64,10 @@ async function readCodexMirroredSessionHistoryMessages(target, admission, view =
64
64
  signal
65
65
  });
66
66
  result = consumeCodexHistory(loaded.buildSessionContext().messages, loaded.getHeader(), target.sessionId, read, "codex mirrored model context");
67
- } else result = await readCodexNativeHistory(resolved, target.sessionId, read, admission);
67
+ } else {
68
+ const history = await readCodexNativeHistory(resolved, target.sessionId, read, admission);
69
+ result = history.status === "ok" ? history.value : void 0;
70
+ }
68
71
  }
69
72
  signal?.throwIfAborted();
70
73
  return result;