@openclaw/codex 2026.7.2-beta.7 → 2026.8.1-beta.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.
- package/README.md +2 -0
- package/dist/api.js +147 -0
- package/dist/app-server-policy-bg5QPSVP.js +25 -0
- package/dist/attempt-client-cleanup-URjUlCHg.js +735 -0
- package/dist/binding-connection-DAvZwp96.js +45 -0
- package/dist/{bounded-turn-D2ZAgZVz.js → bounded-turn-4BjrZEwW.js} +63 -56
- package/dist/{capabilities-BFDTVYr4.js → capabilities-CH3K57v4.js} +8 -2
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-C336eRVS.js → command-formatters-D0nZ3qtd.js} +18 -18
- package/dist/{command-handlers-DAHUSry9.js → command-handlers-DC86lgT4.js} +507 -101
- package/dist/command-rpc-xUIIonsO.js +90 -0
- package/dist/{compact-D_uvHurS.js → compact-COqgBRny.js} +234 -214
- package/dist/{session-binding-BXpo9ymA.js → config-CpNeo5AE.js} +284 -1163
- package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
- package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
- package/dist/doctor-contract-api.js +48 -50
- package/dist/{dynamic-tools-D2gYkSBO.js → dynamic-tools-fJZhl4CE.js} +3442 -1433
- package/dist/{effective-mcp-catalog-Bbd98Inw.js → effective-mcp-catalog-4YKn51aG.js} +20 -15
- package/dist/elicitation-input-DMkeki8d.js +71 -0
- package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
- package/dist/{attempt-notifications-AP-a-Q5k.js → event-projector-usage-CLwNEJqW.js} +113 -29
- package/dist/harness-DoKQcF8n.js +258 -0
- package/dist/harness.js +2 -160
- package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
- package/dist/index.js +730 -256
- package/dist/isolated-completion-DPMtlH9r.js +75 -0
- package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
- package/dist/managed-binary-By4FZC6i.js +212 -0
- package/dist/media-understanding-provider.js +5 -5
- package/dist/model-catalog-CmGoqVKB.js +48 -0
- package/dist/{models-BBMKU4jA.js → models-CZw1wClT.js} +12 -17
- package/dist/native-subagent-monitor-GGq3RnOo.js +3225 -0
- package/dist/node-exec-server.runtime-Bsu1LdFZ.js +192 -0
- package/dist/{plugin-app-cache-key-DztPafOA.js → plugin-app-cache-key-DMNQ8Zi8.js} +18 -6
- package/dist/plugin-approval-roundtrip-C75Yiiwc.js +95 -0
- package/dist/plugin-marketplace-discovery-CSWDkMrP.js +399 -0
- package/dist/{computer-use-CYEc8U3w.js → plugin-metadata-cache-BXH5NF-4.js} +109 -6
- package/dist/protocol-validators-VAVyEnDp.js +2399 -0
- package/dist/{rate-limits-CU-gVCCS.js → rate-limits-BI1dMHDG.js} +17 -35
- package/dist/{request-qKh331yu.js → request-DSK0W6YI.js} +3 -3
- package/dist/{run-attempt-CY9WlDLc.js → run-attempt-BV3HzuCf.js} +3416 -7194
- package/dist/{runtime-artifact-CmtG_t1L.js → runtime-artifact-BvyT1uyd.js} +11 -29
- package/dist/{sandbox-guard-NuhpXmPB.js → sandbox-guard-C1qEeZ5C.js} +29 -30
- package/dist/session-binding-BTrLf9Qm.js +874 -0
- package/dist/{session-catalog-DyOgR4WH.js → session-catalog-ezP_UcRM.js} +1584 -1289
- package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
- package/dist/{session-cli-2PZaFLRh.js → session-cli-B1hKvfkI.js} +20 -7
- package/dist/session-retirement-CE4iMiLh.js +36 -0
- package/dist/{session-upstream-marker-B6U7tLw5.js → session-upstream-marker-D_2npHlA.js} +1 -1
- package/dist/{settled-turn-finalizer-CXY2Z9dT.js → settled-turn-finalizer-Dx1onIqg.js} +40 -28
- package/dist/{shared-client-DTbvH-XV.js → shared-client-Dw-rzii0.js} +1315 -469
- package/dist/{side-question-_ulBk1AL.js → side-question-DbXkJZzg.js} +140 -69
- package/dist/{thread-lifecycle-DF53ogiA.js → thread-lifecycle-DKdrnTMX.js} +927 -768
- package/dist/thread-ownership-i2NBwDUL.js +92 -0
- package/dist/thread-resume-CdJk2Ehf.js +30 -0
- package/dist/transcript-mirror-BU0_LKAL.js +588 -0
- package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DhoGy33Z.js} +13 -2
- package/dist/upstream-prompt-provenance-CFmsKwr9.js +39 -0
- package/dist/{upstream-session-fork-Dy4Xvuoj.js → upstream-session-fork-BDVJCLAD.js} +14 -8
- package/dist/{usage-CQ6GhD5-.js → usage-9dKJCgcy.js} +3 -3
- package/dist/{web-search-provider.runtime-CCFhg2z5.js → web-search-provider.runtime-DCdx4DGu.js} +8 -9
- package/openclaw.plugin.json +49 -4
- package/package.json +6 -5
- package/dist/app-server-policy-BSaO2JIT.js +0 -49
- package/dist/conversation-control-xsIeXbo4.js +0 -287
- package/dist/event-projector-usage-Xp4AlR2k.js +0 -86
- package/dist/notification-correlation-CU6_AnOb.js +0 -67
- package/dist/transcript-mirror-DzsdNCf5.js +0 -6924
|
@@ -1,23 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { d as sessionBindingIdentity, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-
|
|
3
|
-
import { _ as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { B as CodexAppServerRpcError, U as consumeCodexAppServerLiveThread, Y as retainCodexAppServerLiveThread, a as getLeasedSharedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient, ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
|
|
2
|
+
import { d as sessionBindingIdentity, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-BTrLf9Qm.js";
|
|
3
|
+
import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, g as readCodexNotificationThreadId, r as CodexAppServerUnsafeSubscriptionError, s as isCodexAlreadyTerminalInterruptError } from "./attempt-client-cleanup-URjUlCHg.js";
|
|
4
|
+
import { i as readCodexThreadContextSnapshot, x as readCodexNotificationItem } from "./event-projector-usage-CLwNEJqW.js";
|
|
5
|
+
import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
|
|
6
|
+
import { t as resumeCodexAppServerThread } from "./thread-resume-CdJk2Ehf.js";
|
|
7
|
+
import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-C1qEeZ5C.js";
|
|
8
|
+
import { t as isSameCodexAppServerThreadOwner } from "./thread-ownership-i2NBwDUL.js";
|
|
9
|
+
import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-DAvZwp96.js";
|
|
10
|
+
import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-BOeJf7yo.js";
|
|
11
|
+
import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
12
|
+
import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
|
|
6
13
|
import { embeddedAgentLog, resolveCompactionTimeoutMs } from "openclaw/plugin-sdk/agent-harness-runtime";
|
|
7
|
-
import { resolveAgentDir as resolveAgentDir$1
|
|
14
|
+
import { resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
|
|
15
|
+
import { resolveDefaultAgentId as resolveDefaultAgentId$1 } from "openclaw/plugin-sdk/agent-scope-runtime";
|
|
16
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
17
|
+
import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
|
|
18
|
+
import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
|
|
19
|
+
import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
|
|
8
20
|
//#region extensions/codex/src/app-server/compact.ts
|
|
9
21
|
/**
|
|
10
22
|
* Native Codex app-server compaction bridge for bound OpenClaw sessions.
|
|
11
23
|
*/
|
|
12
|
-
const warnedIgnoredCompactionOverrides =
|
|
13
|
-
|
|
24
|
+
const warnedIgnoredCompactionOverrides = createDedupeCache({
|
|
25
|
+
ttlMs: 0,
|
|
26
|
+
maxSize: 4096
|
|
27
|
+
});
|
|
28
|
+
const codexNativeCompactionQueue = new KeyedAsyncQueue();
|
|
14
29
|
const CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS = 3e4;
|
|
15
|
-
const CODEX_NO_ACTIVE_TURN_ERROR_CODE = -32600;
|
|
16
|
-
const CODEX_NO_ACTIVE_TURN_ERROR_MESSAGE = "no active turn to interrupt";
|
|
17
|
-
function isAlreadyTerminalInterruptError(error) {
|
|
18
|
-
return error instanceof CodexAppServerRpcError && error.code === CODEX_NO_ACTIVE_TURN_ERROR_CODE && error.message === CODEX_NO_ACTIVE_TURN_ERROR_MESSAGE;
|
|
19
|
-
}
|
|
20
30
|
function watchCodexNativeCompactionCompletion(params) {
|
|
31
|
+
const runOutsideBindingLease = AsyncLocalStorage.snapshot();
|
|
21
32
|
let settled = false;
|
|
22
33
|
let requestStarted = false;
|
|
23
34
|
let abortRequested = false;
|
|
@@ -26,10 +37,8 @@ function watchCodexNativeCompactionCompletion(params) {
|
|
|
26
37
|
let compactionTurnId;
|
|
27
38
|
let compactionItemId;
|
|
28
39
|
let compactionItemCompleted = false;
|
|
29
|
-
let
|
|
30
|
-
const completion =
|
|
31
|
-
resolveCompletion = resolve;
|
|
32
|
-
});
|
|
40
|
+
let tokensAfter;
|
|
41
|
+
const { promise: completion, resolve: resolveCompletion } = createDeferred();
|
|
33
42
|
let removeNotificationHandler = () => {};
|
|
34
43
|
let removeCloseHandler = () => {};
|
|
35
44
|
let removeAbortHandler = () => {};
|
|
@@ -45,17 +54,24 @@ function watchCodexNativeCompactionCompletion(params) {
|
|
|
45
54
|
clearTimeout(interruptGraceTimeout);
|
|
46
55
|
resolveCompletion(result);
|
|
47
56
|
};
|
|
57
|
+
const complete = () => finish({
|
|
58
|
+
completed: true,
|
|
59
|
+
...compactionTurnId ? { turnId: compactionTurnId } : {},
|
|
60
|
+
...compactionItemId ? { itemId: compactionItemId } : {},
|
|
61
|
+
...tokensAfter !== void 0 ? { tokensAfter } : {}
|
|
62
|
+
});
|
|
63
|
+
const fail = (reason) => finish({
|
|
64
|
+
completed: false,
|
|
65
|
+
reason
|
|
66
|
+
});
|
|
48
67
|
const retireUnconfirmed = (reason) => {
|
|
49
68
|
if (settled || retirementStarted) return;
|
|
50
69
|
retirementStarted = true;
|
|
51
|
-
params.retireUnconfirmed().then(() =>
|
|
52
|
-
completed: false,
|
|
53
|
-
reason
|
|
54
|
-
})).catch((error) => {
|
|
70
|
+
runOutsideBindingLease(() => params.retireUnconfirmed()).then(() => fail(reason)).catch((error) => {
|
|
55
71
|
embeddedAgentLog.error("failed to retire unconfirmed codex app-server compaction", {
|
|
56
72
|
threadId: params.threadId,
|
|
57
73
|
turnId: compactionTurnId,
|
|
58
|
-
reason:
|
|
74
|
+
reason: coerceErrorMessage(error)
|
|
59
75
|
});
|
|
60
76
|
});
|
|
61
77
|
};
|
|
@@ -65,23 +81,19 @@ function watchCodexNativeCompactionCompletion(params) {
|
|
|
65
81
|
params.client.request("turn/interrupt", {
|
|
66
82
|
threadId: params.threadId,
|
|
67
83
|
turnId: compactionTurnId
|
|
68
|
-
}, { timeoutMs: Math.max(1, params.interruptGraceMs) }).
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
finish(compactionItemCompleted ? { completed: true } : {
|
|
76
|
-
completed: false,
|
|
77
|
-
reason: "codex app-server compaction reached terminal state without a completed compaction item"
|
|
78
|
-
});
|
|
84
|
+
}, { timeoutMs: Math.max(1, params.interruptGraceMs) }).catch((error) => {
|
|
85
|
+
if (isCodexAlreadyTerminalInterruptError(error)) {
|
|
86
|
+
if (compactionItemCompleted) {
|
|
87
|
+
complete();
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
fail("codex app-server compaction reached terminal state without a completed compaction item");
|
|
79
91
|
return;
|
|
80
92
|
}
|
|
81
93
|
embeddedAgentLog.warn("codex app-server compaction interrupt request failed", {
|
|
82
94
|
threadId: params.threadId,
|
|
83
95
|
turnId: compactionTurnId,
|
|
84
|
-
reason:
|
|
96
|
+
reason: coerceErrorMessage(error)
|
|
85
97
|
});
|
|
86
98
|
});
|
|
87
99
|
};
|
|
@@ -121,6 +133,10 @@ function watchCodexNativeCompactionCompletion(params) {
|
|
|
121
133
|
return;
|
|
122
134
|
}
|
|
123
135
|
if (compactionTurnId && notificationTurnId !== compactionTurnId) return;
|
|
136
|
+
if (notification.method === "thread/tokenUsage/updated") {
|
|
137
|
+
tokensAfter = readCodexThreadContextSnapshot(notification.params).activeContextTokens ?? tokensAfter;
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
124
140
|
const item = readCodexNotificationItem(notification.params);
|
|
125
141
|
if (item?.type === "contextCompaction") {
|
|
126
142
|
if (notification.method === "item/started") {
|
|
@@ -138,27 +154,15 @@ function watchCodexNativeCompactionCompletion(params) {
|
|
|
138
154
|
const turn = isJsonObject(notification.params.turn) ? notification.params.turn : void 0;
|
|
139
155
|
const status = typeof turn?.status === "string" ? turn.status : void 0;
|
|
140
156
|
if (status !== "completed") {
|
|
141
|
-
|
|
142
|
-
completed: false,
|
|
143
|
-
reason: `codex app-server compaction turn ended with status ${status ?? "unknown"}`
|
|
144
|
-
});
|
|
157
|
+
fail(`codex app-server compaction turn ended with status ${status ?? "unknown"}`);
|
|
145
158
|
return;
|
|
146
159
|
}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
reason: "codex app-server compaction turn completed without a compaction item"
|
|
151
|
-
});
|
|
160
|
+
const incompleteReason = !compactionItemId ? "codex app-server compaction turn completed without a compaction item" : !compactionItemCompleted ? "codex app-server compaction turn completed before its compaction item" : void 0;
|
|
161
|
+
if (incompleteReason) {
|
|
162
|
+
fail(incompleteReason);
|
|
152
163
|
return;
|
|
153
164
|
}
|
|
154
|
-
|
|
155
|
-
finish({
|
|
156
|
-
completed: false,
|
|
157
|
-
reason: "codex app-server compaction turn completed before its compaction item"
|
|
158
|
-
});
|
|
159
|
-
return;
|
|
160
|
-
}
|
|
161
|
-
finish({ completed: true });
|
|
165
|
+
complete();
|
|
162
166
|
});
|
|
163
167
|
removeCloseHandler = params.client.addCloseHandler(() => {
|
|
164
168
|
retireUnconfirmed("codex app-server closed before native compaction completed");
|
|
@@ -179,57 +183,35 @@ function watchCodexNativeCompactionCompletion(params) {
|
|
|
179
183
|
beginCompletionTimeout();
|
|
180
184
|
if (abortRequested) beginInterruptGrace();
|
|
181
185
|
},
|
|
182
|
-
confirmRequestRejected: () =>
|
|
183
|
-
completed: false,
|
|
184
|
-
reason: "codex app-server rejected the compaction request"
|
|
185
|
-
}),
|
|
186
|
+
confirmRequestRejected: () => fail("codex app-server rejected the compaction request"),
|
|
186
187
|
retireUnconfirmedRequest: async (reason) => {
|
|
187
188
|
retireUnconfirmed(reason);
|
|
188
189
|
return await completion;
|
|
189
190
|
},
|
|
190
191
|
cancel: () => {
|
|
191
|
-
if (!requestStarted)
|
|
192
|
-
completed: false,
|
|
193
|
-
reason: "compaction request did not start"
|
|
194
|
-
});
|
|
192
|
+
if (!requestStarted) fail("compaction request did not start");
|
|
195
193
|
}
|
|
196
194
|
};
|
|
197
195
|
}
|
|
198
196
|
async function runExclusiveCodexNativeCompaction(threadId, signal, run) {
|
|
199
|
-
|
|
200
|
-
let
|
|
201
|
-
const
|
|
202
|
-
|
|
203
|
-
});
|
|
204
|
-
const queued = previous.then(() => current, () => current);
|
|
205
|
-
codexNativeCompactionQueues.set(threadId, queued);
|
|
206
|
-
try {
|
|
207
|
-
await waitForCodexNativeCompactionQueue(previous, signal);
|
|
197
|
+
signal?.throwIfAborted();
|
|
198
|
+
let started = false;
|
|
199
|
+
const queued = codexNativeCompactionQueue.enqueue(threadId, async () => {
|
|
200
|
+
started = true;
|
|
208
201
|
signal?.throwIfAborted();
|
|
209
|
-
return
|
|
210
|
-
}
|
|
211
|
-
|
|
212
|
-
queued.then(() => {
|
|
213
|
-
if (codexNativeCompactionQueues.get(threadId) === queued) codexNativeCompactionQueues.delete(threadId);
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
}
|
|
217
|
-
async function waitForCodexNativeCompactionQueue(previous, signal) {
|
|
218
|
-
if (!signal) {
|
|
219
|
-
await previous.catch(() => void 0);
|
|
220
|
-
return;
|
|
221
|
-
}
|
|
222
|
-
signal.throwIfAborted();
|
|
202
|
+
return run();
|
|
203
|
+
});
|
|
204
|
+
if (!signal) return queued;
|
|
223
205
|
let removeAbortListener = () => {};
|
|
224
206
|
const aborted = new Promise((_, reject) => {
|
|
225
207
|
const onAbort = () => {
|
|
226
|
-
reject(signal.reason instanceof Error ? signal.reason : /* @__PURE__ */ new Error("compaction aborted"));
|
|
208
|
+
if (!started) reject(signal.reason instanceof Error ? signal.reason : /* @__PURE__ */ new Error("compaction aborted"));
|
|
227
209
|
};
|
|
228
210
|
removeAbortListener = () => signal.removeEventListener("abort", onAbort);
|
|
229
211
|
signal.addEventListener("abort", onAbort, { once: true });
|
|
230
212
|
});
|
|
231
213
|
try {
|
|
232
|
-
await Promise.race([
|
|
214
|
+
return await Promise.race([queued, aborted]);
|
|
233
215
|
} finally {
|
|
234
216
|
removeAbortListener();
|
|
235
217
|
}
|
|
@@ -246,8 +228,7 @@ function warnIfIgnoringOpenClawCompactionOverrides(params) {
|
|
|
246
228
|
const ignoredConfig = readIgnoredCompactionOverridePaths(params);
|
|
247
229
|
if (ignoredConfig.length === 0) return;
|
|
248
230
|
const warningKey = ignoredConfig.join("\0");
|
|
249
|
-
if (warnedIgnoredCompactionOverrides.
|
|
250
|
-
warnedIgnoredCompactionOverrides.add(warningKey);
|
|
231
|
+
if (warnedIgnoredCompactionOverrides.check(warningKey)) return;
|
|
251
232
|
embeddedAgentLog.warn("ignoring OpenClaw compaction overrides for Codex app-server compaction; Codex uses native server-side compaction", {
|
|
252
233
|
sessionId: params.sessionId,
|
|
253
234
|
sessionKey: params.sessionKey,
|
|
@@ -258,34 +239,19 @@ function readIgnoredCompactionOverridePaths(params) {
|
|
|
258
239
|
const ignored = /* @__PURE__ */ new Set();
|
|
259
240
|
for (const entry of readCompactionOverrideEntries(params)) {
|
|
260
241
|
const localProvider = typeof entry.record.provider === "string" ? entry.record.provider.trim() : "";
|
|
261
|
-
const inheritedProvider = !localProvider && typeof entry.inheritedRecord?.provider === "string" ? entry.inheritedRecord.provider.trim() : "";
|
|
262
|
-
const providerPath = localProvider ? `${entry.path}.compaction.provider` : inheritedProvider && entry.inheritedPath ? `${entry.inheritedPath}.compaction.provider` : void 0;
|
|
263
242
|
if (typeof entry.record.model === "string" && entry.record.model.trim()) ignored.add(`${entry.path}.compaction.model`);
|
|
264
243
|
if (typeof entry.record.thinkingLevel === "string" && entry.record.thinkingLevel.trim()) ignored.add(`${entry.path}.compaction.thinkingLevel`);
|
|
265
|
-
if (
|
|
244
|
+
if (localProvider) ignored.add(`${entry.path}.compaction.provider`);
|
|
266
245
|
}
|
|
267
246
|
return [...ignored];
|
|
268
247
|
}
|
|
269
248
|
function readCompactionOverrideEntries(params) {
|
|
270
249
|
const entries = [];
|
|
271
|
-
const
|
|
272
|
-
const defaultRecord = readRecord(defaultCompaction);
|
|
250
|
+
const defaultRecord = asOptionalRecord(params.config?.agents?.defaults?.compaction);
|
|
273
251
|
if (defaultRecord) entries.push({
|
|
274
252
|
path: "agents.defaults",
|
|
275
253
|
record: defaultRecord
|
|
276
254
|
});
|
|
277
|
-
const agentId = readAgentIdFromSessionKey(params.sessionKey ?? params.sandboxSessionKey);
|
|
278
|
-
if (!agentId) return entries;
|
|
279
|
-
const agentCompaction = readRecord((Array.isArray(params.config?.agents?.list) ? params.config.agents.list : []).find((agent) => {
|
|
280
|
-
return (typeof agent?.id === "string" ? agent.id.trim().toLowerCase() : "") === agentId;
|
|
281
|
-
}))?.compaction;
|
|
282
|
-
const agentRecord = readRecord(agentCompaction);
|
|
283
|
-
if (agentRecord) entries.push({
|
|
284
|
-
path: `agents.list.${agentId}`,
|
|
285
|
-
record: agentRecord,
|
|
286
|
-
inheritedRecord: defaultRecord,
|
|
287
|
-
inheritedPath: "agents.defaults"
|
|
288
|
-
});
|
|
289
255
|
return entries;
|
|
290
256
|
}
|
|
291
257
|
function readAgentIdFromSessionKey(sessionKey) {
|
|
@@ -293,9 +259,6 @@ function readAgentIdFromSessionKey(sessionKey) {
|
|
|
293
259
|
if (parts.length < 3 || parts[0] !== "agent") return;
|
|
294
260
|
return parts[1]?.trim() || void 0;
|
|
295
261
|
}
|
|
296
|
-
function readRecord(value) {
|
|
297
|
-
return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
|
|
298
|
-
}
|
|
299
262
|
async function compactCodexNativeThread(params, options) {
|
|
300
263
|
if (params.trigger !== "manual" && !options.allowNonManualNativeRequest) {
|
|
301
264
|
embeddedAgentLog.info("skipping codex app-server compaction for non-manual trigger", {
|
|
@@ -303,27 +266,24 @@ async function compactCodexNativeThread(params, options) {
|
|
|
303
266
|
sessionKey: params.sessionKey,
|
|
304
267
|
trigger: params.trigger
|
|
305
268
|
});
|
|
306
|
-
return {
|
|
307
|
-
ok: true,
|
|
269
|
+
return codexNativeCompactionResult(params, {
|
|
308
270
|
compacted: false,
|
|
309
271
|
reason: "codex app-server owns automatic compaction",
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
backend: "codex-app-server",
|
|
316
|
-
skipped: true,
|
|
317
|
-
reason: "non_manual_trigger",
|
|
318
|
-
trigger: params.trigger ?? "unknown"
|
|
319
|
-
}
|
|
272
|
+
details: {
|
|
273
|
+
backend: "codex-app-server",
|
|
274
|
+
skipped: true,
|
|
275
|
+
reason: "non_manual_trigger",
|
|
276
|
+
trigger: params.trigger ?? "unknown"
|
|
320
277
|
}
|
|
321
|
-
};
|
|
278
|
+
});
|
|
322
279
|
}
|
|
280
|
+
const sandbox = params.sandbox;
|
|
323
281
|
const nativeExecutionBlock = resolveCodexNativeExecutionBlock({
|
|
324
282
|
config: params.config,
|
|
325
283
|
sessionKey: params.sandboxSessionKey ?? params.sessionKey,
|
|
326
284
|
sessionId: params.sessionId,
|
|
285
|
+
agentId: params.agentId,
|
|
286
|
+
sandbox,
|
|
327
287
|
surface: "native compaction"
|
|
328
288
|
});
|
|
329
289
|
if (nativeExecutionBlock) return {
|
|
@@ -342,12 +302,22 @@ async function compactCodexNativeThread(params, options) {
|
|
|
342
302
|
reason: "no codex app-server thread binding",
|
|
343
303
|
recovery: "missing_thread_binding"
|
|
344
304
|
});
|
|
305
|
+
if (params.nativeToolSurface === "host-isolated" || initialBinding.nativeToolPolicyRestricted === true || initialBinding.ringZeroConfigFingerprint !== void 0) return codexNativeCompactionResult(params, {
|
|
306
|
+
compacted: false,
|
|
307
|
+
reason: "native compaction is unavailable for a host-isolated Codex session",
|
|
308
|
+
details: {
|
|
309
|
+
backend: "codex-app-server",
|
|
310
|
+
skipped: true,
|
|
311
|
+
reason: "native_tool_policy_restricted",
|
|
312
|
+
expectedThreadId: initialBinding.threadId
|
|
313
|
+
}
|
|
314
|
+
});
|
|
345
315
|
let binding = initialBinding;
|
|
346
316
|
const requestedAuthProfileId = params.authProfileId?.trim() || void 0;
|
|
347
317
|
let connection;
|
|
348
318
|
try {
|
|
349
319
|
const config = params.config ?? {};
|
|
350
|
-
const agentId = params.agentId ?? readAgentIdFromSessionKey(params.sessionKey) ?? resolveDefaultAgentId(config);
|
|
320
|
+
const agentId = params.agentId ?? readAgentIdFromSessionKey(params.sessionKey) ?? resolveDefaultAgentId$1(config);
|
|
351
321
|
connection = resolveCodexBindingAppServerConnection({
|
|
352
322
|
binding,
|
|
353
323
|
authProfileId: requestedAuthProfileId ?? binding.authProfileId,
|
|
@@ -359,7 +329,7 @@ async function compactCodexNativeThread(params, options) {
|
|
|
359
329
|
return {
|
|
360
330
|
ok: false,
|
|
361
331
|
compacted: false,
|
|
362
|
-
reason:
|
|
332
|
+
reason: coerceErrorMessage(error)
|
|
363
333
|
};
|
|
364
334
|
}
|
|
365
335
|
const { appServer, usesSupervisionConnection } = connection;
|
|
@@ -389,6 +359,19 @@ async function compactCodexNativeThread(params, options) {
|
|
|
389
359
|
agentDir: params.agentDir,
|
|
390
360
|
config: params.config
|
|
391
361
|
});
|
|
362
|
+
let releaseThreadSubscription;
|
|
363
|
+
let retainedThreadOwnership;
|
|
364
|
+
let compactionSucceeded = false;
|
|
365
|
+
let compactionRequestDefinitelyRejected = false;
|
|
366
|
+
let tokensAfter;
|
|
367
|
+
const releaseCompactionThread = async (threadId) => {
|
|
368
|
+
if (await unsubscribeCodexThreadBestEffort(client, {
|
|
369
|
+
threadId,
|
|
370
|
+
timeoutMs: 5e3
|
|
371
|
+
})) return;
|
|
372
|
+
await closeCodexStartupClientBestEffort(client);
|
|
373
|
+
throw new CodexAppServerUnsafeSubscriptionError(`Codex compaction thread subscription could not be released: ${threadId}`);
|
|
374
|
+
};
|
|
392
375
|
const completionWatch = watchCodexNativeCompactionCompletion({
|
|
393
376
|
client,
|
|
394
377
|
threadId: binding.threadId,
|
|
@@ -396,6 +379,7 @@ async function compactCodexNativeThread(params, options) {
|
|
|
396
379
|
timeoutMs: options.nativeCompletionTimeoutMs ?? resolveCompactionTimeoutMs(params.config),
|
|
397
380
|
interruptGraceMs: options.nativeInterruptGraceMs ?? CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS,
|
|
398
381
|
retireUnconfirmed: async () => {
|
|
382
|
+
releaseThreadSubscription = void 0;
|
|
399
383
|
const transportStopped = await client.closeAndWait({
|
|
400
384
|
exitTimeoutMs: 5e3,
|
|
401
385
|
forceKillDelayMs: 250
|
|
@@ -413,84 +397,98 @@ async function compactCodexNativeThread(params, options) {
|
|
|
413
397
|
throw new Error("failed to detach unconfirmed codex app-server thread binding");
|
|
414
398
|
}
|
|
415
399
|
});
|
|
416
|
-
const
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
400
|
+
const acquireThreadSubscription = async (timeoutMs) => {
|
|
401
|
+
if (!isIncognitoSessionKey(params.sessionKey)) {
|
|
402
|
+
retainedThreadOwnership = await consumeCodexAppServerLiveThread(client, binding.threadId);
|
|
403
|
+
if (!retainedThreadOwnership) await resumeCodexAppServerThread({
|
|
404
|
+
client,
|
|
405
|
+
abandonClient: async () => closeCodexStartupClientBestEffort(client),
|
|
406
|
+
request: {
|
|
407
|
+
threadId: binding.threadId,
|
|
408
|
+
excludeTurns: true
|
|
409
|
+
},
|
|
410
|
+
timeoutMs: timeoutMs ?? appServer.requestTimeoutMs,
|
|
411
|
+
...params.abortSignal ? { signal: params.abortSignal } : {}
|
|
412
|
+
});
|
|
413
|
+
releaseThreadSubscription = async () => releaseCompactionThread(binding.threadId);
|
|
414
|
+
}
|
|
425
415
|
};
|
|
426
416
|
try {
|
|
427
|
-
|
|
428
|
-
const
|
|
429
|
-
|
|
430
|
-
if (params.abortSignal
|
|
417
|
+
const guardedResult = await options.bindingStore.withLease(bindingIdentity, async () => {
|
|
418
|
+
const currentBinding = await options.bindingStore.read(bindingIdentity);
|
|
419
|
+
if (params.abortSignal?.aborted) {
|
|
420
|
+
if (!options.allowNonManualNativeRequest) params.abortSignal.throwIfAborted();
|
|
421
|
+
return {
|
|
431
422
|
started: false,
|
|
432
423
|
result: skippedCodexNativeCompactionResult(params, {
|
|
433
424
|
reason: "codex app-server compaction aborted before native compaction",
|
|
434
425
|
code: "aborted_before_native_compaction",
|
|
426
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
435
427
|
expectedThreadId: binding.threadId,
|
|
436
428
|
currentThreadId: currentBinding?.threadId
|
|
437
429
|
})
|
|
438
430
|
};
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
sessionKey: params.sessionKey,
|
|
443
|
-
expectedThreadId: binding.threadId,
|
|
444
|
-
currentThreadId: currentBinding?.threadId
|
|
445
|
-
});
|
|
446
|
-
return {
|
|
447
|
-
started: false,
|
|
448
|
-
result: skippedCodexNativeCompactionResult(params, {
|
|
449
|
-
reason: "codex app-server binding changed before native compaction",
|
|
450
|
-
code: "binding_changed_before_native_compaction",
|
|
451
|
-
expectedThreadId: binding.threadId,
|
|
452
|
-
currentThreadId: currentBinding?.threadId
|
|
453
|
-
})
|
|
454
|
-
};
|
|
455
|
-
}
|
|
456
|
-
binding = currentBinding;
|
|
457
|
-
await clearContextEngineProjectionBeforeNativeCompaction({
|
|
431
|
+
}
|
|
432
|
+
if (!currentBinding || !isSameNativeCompactionBinding(currentBinding, binding)) {
|
|
433
|
+
embeddedAgentLog.warn("codex app-server compaction could not use the thread binding because it changed", {
|
|
458
434
|
sessionId: params.sessionId,
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
435
|
+
sessionKey: params.sessionKey,
|
|
436
|
+
expectedThreadId: binding.threadId,
|
|
437
|
+
currentThreadId: currentBinding?.threadId
|
|
462
438
|
});
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
439
|
+
const isRequiredPreflight = options.nativeCompactionRequest === "required_preflight";
|
|
440
|
+
return {
|
|
441
|
+
started: false,
|
|
442
|
+
result: options.allowNonManualNativeRequest && !isRequiredPreflight ? skippedCodexNativeCompactionResult(params, {
|
|
443
|
+
reason: "codex app-server binding changed before native compaction",
|
|
444
|
+
code: "binding_changed_before_native_compaction",
|
|
445
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
446
|
+
expectedThreadId: binding.threadId,
|
|
447
|
+
currentThreadId: currentBinding?.threadId
|
|
448
|
+
}) : failedCodexThreadBindingCompactionResult(params, {
|
|
449
|
+
threadId: currentBinding?.threadId ?? binding.threadId,
|
|
450
|
+
reason: "codex app-server binding changed before native compaction",
|
|
451
|
+
recovery: "stale_thread_binding"
|
|
452
|
+
})
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
binding = currentBinding;
|
|
456
|
+
const guardedRequestTimeoutMs = options.allowNonManualNativeRequest ? Math.min(appServer.requestTimeoutMs, CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS) : void 0;
|
|
457
|
+
await acquireThreadSubscription(guardedRequestTimeoutMs);
|
|
458
|
+
await clearContextEngineProjectionBeforeNativeCompaction({
|
|
459
|
+
sessionId: params.sessionId,
|
|
460
|
+
bindingStore: options.bindingStore,
|
|
461
|
+
identity: bindingIdentity,
|
|
462
|
+
binding
|
|
463
|
+
});
|
|
464
|
+
try {
|
|
465
|
+
completionWatch.beginRequest();
|
|
466
|
+
if (guardedRequestTimeoutMs === void 0) await client.request("thread/compact/start", { threadId: binding.threadId });
|
|
467
|
+
else await client.request("thread/compact/start", { threadId: binding.threadId }, { timeoutMs: guardedRequestTimeoutMs });
|
|
468
|
+
return {
|
|
469
|
+
started: true,
|
|
470
|
+
accepted: true
|
|
471
|
+
};
|
|
472
|
+
} catch (error) {
|
|
473
|
+
if (error instanceof CodexAppServerRpcError) {
|
|
470
474
|
await options.bindingStore.mutate(bindingIdentity, {
|
|
471
475
|
kind: "set",
|
|
472
476
|
binding
|
|
473
477
|
});
|
|
474
|
-
|
|
475
|
-
started: true,
|
|
476
|
-
accepted: false,
|
|
477
|
-
error
|
|
478
|
-
};
|
|
478
|
+
compactionRequestDefinitelyRejected = !isCodexThreadNotFoundError(error);
|
|
479
479
|
}
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
}
|
|
486
|
-
} else {
|
|
487
|
-
params.abortSignal?.throwIfAborted();
|
|
488
|
-
try {
|
|
489
|
-
await beginNativeCompactionRequest();
|
|
490
|
-
} catch (error) {
|
|
491
|
-
await settleNativeCompactionRequestError(error);
|
|
492
|
-
throw error;
|
|
480
|
+
return {
|
|
481
|
+
started: true,
|
|
482
|
+
accepted: false,
|
|
483
|
+
error
|
|
484
|
+
};
|
|
493
485
|
}
|
|
486
|
+
});
|
|
487
|
+
if (!guardedResult.started) return guardedResult.result;
|
|
488
|
+
if (!guardedResult.accepted) {
|
|
489
|
+
if (guardedResult.error instanceof CodexAppServerRpcError) completionWatch.confirmRequestRejected();
|
|
490
|
+
else await completionWatch.retireUnconfirmedRequest(`codex app-server compaction start was unconfirmed: ${coerceErrorMessage(guardedResult.error)}`);
|
|
491
|
+
throw guardedResult.error;
|
|
494
492
|
}
|
|
495
493
|
embeddedAgentLog.info("started codex app-server compaction", {
|
|
496
494
|
sessionId: params.sessionId,
|
|
@@ -498,58 +496,76 @@ async function compactCodexNativeThread(params, options) {
|
|
|
498
496
|
});
|
|
499
497
|
const completion = await completionWatch.completion;
|
|
500
498
|
if (!completion.completed) throw new Error(completion.reason);
|
|
499
|
+
tokensAfter = completion.tokensAfter;
|
|
500
|
+
if (completion.turnId && completion.itemId) await persistCodexContextCompactionActivity({
|
|
501
|
+
sessionTarget: params.sessionTarget,
|
|
502
|
+
config: params.config,
|
|
503
|
+
cwd: params.workspaceDir,
|
|
504
|
+
runId: params.runId,
|
|
505
|
+
threadId: binding.threadId,
|
|
506
|
+
turnId: completion.turnId,
|
|
507
|
+
itemId: completion.itemId,
|
|
508
|
+
timestamp: Date.now()
|
|
509
|
+
});
|
|
501
510
|
embeddedAgentLog.info("completed codex app-server compaction", {
|
|
502
511
|
sessionId: params.sessionId,
|
|
503
512
|
threadId: binding.threadId
|
|
504
513
|
});
|
|
514
|
+
compactionSucceeded = true;
|
|
505
515
|
} catch (error) {
|
|
506
516
|
if (isCodexThreadNotFoundError(error)) return failedCodexThreadBindingCompactionResult(params, {
|
|
507
517
|
threadId: binding.threadId,
|
|
508
|
-
reason:
|
|
518
|
+
reason: coerceErrorMessage(error),
|
|
509
519
|
recovery: "stale_thread_binding"
|
|
510
520
|
});
|
|
511
521
|
embeddedAgentLog.warn("codex app-server compaction failed", {
|
|
512
522
|
sessionId: params.sessionId,
|
|
513
523
|
sessionKey: params.sessionKey,
|
|
514
524
|
threadId: binding.threadId,
|
|
515
|
-
reason:
|
|
525
|
+
reason: coerceErrorMessage(error)
|
|
516
526
|
});
|
|
517
527
|
return {
|
|
518
528
|
ok: false,
|
|
519
529
|
compacted: false,
|
|
520
|
-
reason:
|
|
530
|
+
reason: coerceErrorMessage(error)
|
|
521
531
|
};
|
|
522
532
|
} finally {
|
|
523
533
|
completionWatch.cancel();
|
|
524
|
-
|
|
534
|
+
try {
|
|
535
|
+
if ((compactionSucceeded || compactionRequestDefinitelyRejected) && retainedThreadOwnership) {
|
|
536
|
+
const ownership = retainedThreadOwnership;
|
|
537
|
+
if (!(isSameCodexAppServerThreadOwner(await options.bindingStore.read(bindingIdentity), binding) && await options.bindingStore.withLease(bindingIdentity, async () => {
|
|
538
|
+
if (!isSameCodexAppServerThreadOwner(await options.bindingStore.read(bindingIdentity), binding)) return false;
|
|
539
|
+
return await retainCodexAppServerLiveThread(client, binding.threadId, ownership.release, ownership.configFingerprint, ownership.serviceTier);
|
|
540
|
+
}))) await releaseThreadSubscription?.();
|
|
541
|
+
} else await releaseThreadSubscription?.();
|
|
542
|
+
} finally {
|
|
543
|
+
if (shouldReleaseDefaultLease) releaseLeasedSharedCodexAppServerClient(client);
|
|
544
|
+
}
|
|
525
545
|
}
|
|
526
|
-
const
|
|
546
|
+
const details = {
|
|
527
547
|
backend: "codex-app-server",
|
|
528
548
|
threadId: binding.threadId,
|
|
529
549
|
signal: "thread/compact/start",
|
|
530
550
|
pending: false,
|
|
531
551
|
completed: true,
|
|
532
552
|
...options.allowNonManualNativeRequest ? {
|
|
533
|
-
request: "after_context_engine",
|
|
553
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
534
554
|
trigger: params.trigger ?? "unknown"
|
|
535
555
|
} : {}
|
|
536
556
|
};
|
|
537
|
-
return {
|
|
538
|
-
ok: true,
|
|
557
|
+
return codexNativeCompactionResult(params, {
|
|
539
558
|
compacted: true,
|
|
540
|
-
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
tokensBefore: params.currentTokenCount ?? 0,
|
|
544
|
-
details: resultDetails
|
|
545
|
-
}
|
|
546
|
-
};
|
|
559
|
+
tokensAfter,
|
|
560
|
+
details
|
|
561
|
+
});
|
|
547
562
|
});
|
|
548
563
|
} catch (error) {
|
|
549
564
|
if (params.abortSignal?.aborted) {
|
|
550
565
|
if (options.allowNonManualNativeRequest) return skippedCodexNativeCompactionResult(params, {
|
|
551
566
|
reason: "codex app-server compaction aborted before native compaction",
|
|
552
567
|
code: "aborted_before_native_compaction",
|
|
568
|
+
request: options.nativeCompactionRequest ?? "after_context_engine",
|
|
553
569
|
expectedThreadId: initialBinding.threadId,
|
|
554
570
|
currentThreadId: binding.threadId
|
|
555
571
|
});
|
|
@@ -562,27 +578,35 @@ async function compactCodexNativeThread(params, options) {
|
|
|
562
578
|
throw error;
|
|
563
579
|
}
|
|
564
580
|
}
|
|
565
|
-
function
|
|
581
|
+
function codexNativeCompactionResult(params, outcome) {
|
|
566
582
|
return {
|
|
567
583
|
ok: true,
|
|
568
|
-
compacted:
|
|
569
|
-
reason:
|
|
584
|
+
compacted: outcome.compacted,
|
|
585
|
+
...outcome.reason ? { reason: outcome.reason } : {},
|
|
570
586
|
result: {
|
|
571
587
|
summary: "",
|
|
572
588
|
firstKeptEntryId: "",
|
|
573
589
|
tokensBefore: params.currentTokenCount ?? 0,
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
skipped: true,
|
|
577
|
-
reason: skipped.code,
|
|
578
|
-
request: "after_context_engine",
|
|
579
|
-
trigger: params.trigger ?? "unknown",
|
|
580
|
-
...skipped.expectedThreadId ? { expectedThreadId: skipped.expectedThreadId } : {},
|
|
581
|
-
...skipped.currentThreadId ? { currentThreadId: skipped.currentThreadId } : {}
|
|
582
|
-
}
|
|
590
|
+
...outcome.tokensAfter !== void 0 ? { tokensAfter: outcome.tokensAfter } : {},
|
|
591
|
+
details: outcome.details
|
|
583
592
|
}
|
|
584
593
|
};
|
|
585
594
|
}
|
|
595
|
+
function skippedCodexNativeCompactionResult(params, skipped) {
|
|
596
|
+
return codexNativeCompactionResult(params, {
|
|
597
|
+
compacted: false,
|
|
598
|
+
reason: skipped.reason,
|
|
599
|
+
details: {
|
|
600
|
+
backend: "codex-app-server",
|
|
601
|
+
skipped: true,
|
|
602
|
+
reason: skipped.code,
|
|
603
|
+
request: skipped.request ?? "after_context_engine",
|
|
604
|
+
trigger: params.trigger ?? "unknown",
|
|
605
|
+
...skipped.expectedThreadId ? { expectedThreadId: skipped.expectedThreadId } : {},
|
|
606
|
+
...skipped.currentThreadId ? { currentThreadId: skipped.currentThreadId } : {}
|
|
607
|
+
}
|
|
608
|
+
});
|
|
609
|
+
}
|
|
586
610
|
function failedCodexThreadBindingCompactionResult(params, recovery) {
|
|
587
611
|
embeddedAgentLog.warn("codex app-server compaction could not use thread binding", {
|
|
588
612
|
sessionId: params.sessionId,
|
|
@@ -620,14 +644,10 @@ async function clearContextEngineProjectionBeforeNativeCompaction(params) {
|
|
|
620
644
|
});
|
|
621
645
|
}
|
|
622
646
|
function isSameNativeCompactionBinding(current, expected) {
|
|
623
|
-
return current
|
|
647
|
+
return isSameCodexAppServerThreadOwner(current, expected) && current.authProfileId === expected.authProfileId && current.contextEngine?.engineId === expected.contextEngine?.engineId && current.contextEngine?.policyFingerprint === expected.contextEngine?.policyFingerprint && current.contextEngine?.projection?.mode === expected.contextEngine?.projection?.mode && current.contextEngine?.projection?.epoch === expected.contextEngine?.projection?.epoch && current.contextEngine?.projection?.fingerprint === expected.contextEngine?.projection?.fingerprint;
|
|
624
648
|
}
|
|
625
649
|
function isCodexThreadNotFoundError(error) {
|
|
626
|
-
return
|
|
627
|
-
}
|
|
628
|
-
function formatCompactionError(error) {
|
|
629
|
-
if (error instanceof Error) return error.message;
|
|
630
|
-
return String(error);
|
|
650
|
+
return coerceErrorMessage(error).toLowerCase().includes("thread not found");
|
|
631
651
|
}
|
|
632
652
|
//#endregion
|
|
633
653
|
export { maybeCompactCodexAppServerSession };
|