@openclaw/codex 2026.7.2-beta.7 → 2026.8.1-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -0
- package/dist/{app-server-policy-BSaO2JIT.js → app-server-policy-zcBDc1JU.js} +1 -1
- package/dist/attempt-client-cleanup-DMLXUfa8.js +735 -0
- package/dist/{notification-correlation-CU6_AnOb.js → binding-connection-I5Bo-AsX.js} +3 -37
- package/dist/{bounded-turn-D2ZAgZVz.js → bounded-turn-qgZmzy_4.js} +50 -49
- package/dist/{capabilities-BFDTVYr4.js → capabilities-CybGI1oz.js} +8 -2
- package/dist/cli-metadata.js +1 -1
- package/dist/{command-formatters-C336eRVS.js → command-formatters-B1AEz8ZA.js} +18 -18
- package/dist/{command-handlers-DAHUSry9.js → command-handlers-Db8pu_ds.js} +484 -95
- package/dist/{compact-D_uvHurS.js → compact-LspQaGfl.js} +213 -199
- package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
- package/dist/doctor-contract-api.js +40 -43
- package/dist/{dynamic-tools-D2gYkSBO.js → dynamic-tools-BVdyWkUD.js} +2597 -1221
- package/dist/{effective-mcp-catalog-Bbd98Inw.js → effective-mcp-catalog-DIIhAtOZ.js} +20 -15
- 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-e5huIQWu.js} +113 -29
- package/dist/harness.js +80 -14
- package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
- package/dist/index.js +591 -240
- package/dist/isolated-completion-C58NbL40.js +75 -0
- package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
- package/dist/media-understanding-provider.js +5 -5
- package/dist/{models-BBMKU4jA.js → models-BFlpn1Ex.js} +12 -17
- package/dist/native-subagent-monitor-DyTGmTUx.js +3111 -0
- package/dist/{plugin-app-cache-key-DztPafOA.js → plugin-app-cache-key-C3H2CVp6.js} +5 -5
- package/dist/plugin-marketplace-discovery-CzrGJdCR.js +385 -0
- package/dist/{computer-use-CYEc8U3w.js → plugin-metadata-cache-CNJPj4_b.js} +105 -5
- package/dist/protocol-validators-B4F7L8Rf.js +2346 -0
- package/dist/{rate-limits-CU-gVCCS.js → rate-limits-DZXmOL8-.js} +17 -35
- package/dist/{request-qKh331yu.js → request-BRl5_UfX.js} +3 -3
- package/dist/{run-attempt-CY9WlDLc.js → run-attempt-P8BdxC1I.js} +4837 -9047
- package/dist/{runtime-artifact-CmtG_t1L.js → runtime-artifact-BVSPdd6g.js} +8 -23
- package/dist/{sandbox-guard-NuhpXmPB.js → sandbox-guard-Cmwc9eIk.js} +6 -13
- package/dist/{session-binding-BXpo9ymA.js → session-binding-DPxIvMgE.js} +246 -265
- package/dist/{session-catalog-DyOgR4WH.js → session-catalog-xwNi_SDM.js} +159 -109
- package/dist/{session-cli-2PZaFLRh.js → session-cli-7hgXZDV7.js} +1 -1
- package/dist/session-retirement-DoMMJFKm.js +36 -0
- package/dist/{session-upstream-marker-B6U7tLw5.js → session-upstream-marker-CrIFX06J.js} +1 -1
- package/dist/{settled-turn-finalizer-CXY2Z9dT.js → settled-turn-finalizer-BRWBO4MO.js} +21 -13
- package/dist/{shared-client-DTbvH-XV.js → shared-client-kIBbGjk4.js} +587 -223
- package/dist/{side-question-_ulBk1AL.js → side-question-9HAL26l9.js} +101 -52
- package/dist/{thread-lifecycle-DF53ogiA.js → thread-lifecycle-Bu1BTDXr.js} +694 -753
- package/dist/thread-ownership-6kOQHlyC.js +92 -0
- package/dist/thread-resume-CPrJNQVM.js +30 -0
- package/dist/transcript-mirror-B9gGgnJS.js +570 -0
- package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DIImwDVS.js} +11 -0
- package/dist/upstream-prompt-provenance-ClRBije0.js +41 -0
- package/dist/{upstream-session-fork-Dy4Xvuoj.js → upstream-session-fork-CE-_LdnP.js} +5 -5
- package/dist/{usage-CQ6GhD5-.js → usage-CHlV0e-o.js} +3 -3
- package/dist/{web-search-provider.runtime-CCFhg2z5.js → web-search-provider.runtime-DRw2Vl42.js} +8 -9
- package/openclaw.plugin.json +18 -3
- package/package.json +5 -5
- package/dist/conversation-control-xsIeXbo4.js +0 -287
- package/dist/event-projector-usage-Xp4AlR2k.js +0 -86
- package/dist/transcript-mirror-DzsdNCf5.js +0 -6924
|
@@ -1,30 +1,31 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import { n as listCodexAppServerModels } from "./models-
|
|
5
|
-
import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import { n as
|
|
10
|
-
import { i as
|
|
1
|
+
import { c as reclaimCurrentCodexSessionGeneration, d as sessionBindingIdentity, g as resolveCodexAppServerRuntimeOptions, y as resolveCodexSupervisionAppServerRuntimeOptions } from "./session-binding-DPxIvMgE.js";
|
|
2
|
+
import { R as resolveCodexAppServerClientInstanceId, _ as withTimeout, a as getLeasedSharedCodexAppServerClient, at as CODEX_INTERACTIVE_THREAD_SOURCE_KINDS, ct as isJsonObject, dt as resolveCodexAppServerLocalHomeDir, it as CODEX_INTERACTIVE_CUSTOM_THREAD_SOURCES, l as releaseLeasedSharedCodexAppServerClient, z as CodexAppServerRpcError } from "./shared-client-kIBbGjk4.js";
|
|
3
|
+
import { n as assertCodexThreadForkParams } from "./protocol-validators-B4F7L8Rf.js";
|
|
4
|
+
import { n as listCodexAppServerModels } from "./models-BFlpn1Ex.js";
|
|
5
|
+
import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-C3H2CVp6.js";
|
|
6
|
+
import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-B9gGgnJS.js";
|
|
7
|
+
import { n as describeControlFailure, t as CODEX_CONTROL_METHODS } from "./capabilities-CybGI1oz.js";
|
|
8
|
+
import { r as formatCodexDisplayText } from "./command-formatters-B1AEz8ZA.js";
|
|
9
|
+
import { n as createCodexCliNodeConversationBindingData } from "./conversation-binding-data-CW2GuupV.js";
|
|
10
|
+
import { i as withCodexAppServerJsonClient, n as requestCodexAppServerClientJson, r as requestCodexAppServerJson } from "./request-BRl5_UfX.js";
|
|
11
|
+
import { i as createImportedCodexSession, n as codexUpstreamBaseline, r as codexUpstreamContinueResult, t as codexLastTerminalTurnId } from "./session-upstream-marker-CrIFX06J.js";
|
|
12
|
+
import { asFiniteNumber, isRecord, normalizeBoundedOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
11
13
|
import fs from "node:fs/promises";
|
|
12
14
|
import path from "node:path";
|
|
13
15
|
import { timestampMsToIsoString } from "openclaw/plugin-sdk/number-runtime";
|
|
14
16
|
import { resolvePreferredOpenClawTmpDir } from "openclaw/plugin-sdk/temp-path";
|
|
15
17
|
import { createHash } from "node:crypto";
|
|
16
|
-
import { listAgentIds, resolveAllowedModelRef, resolveDefaultAgentDir, resolveDefaultAgentId, resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
17
18
|
import os from "node:os";
|
|
19
|
+
import { listAgentIds, resolveAllowedModelRef, resolveDefaultAgentDir, resolveDefaultAgentId, resolveDefaultModelForAgent } from "openclaw/plugin-sdk/agent-runtime";
|
|
18
20
|
import { parseAgentSessionKey } from "openclaw/plugin-sdk/routing";
|
|
19
|
-
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
20
21
|
import { materializeWindowsSpawnProgram, resolveWindowsSpawnProgram } from "openclaw/plugin-sdk/windows-spawn";
|
|
21
22
|
import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
22
23
|
import { spawn } from "node:child_process";
|
|
23
24
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
24
25
|
import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
|
|
26
|
+
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
25
27
|
import process$1 from "node:process";
|
|
26
28
|
import { listSessionCatalogEntries } from "openclaw/plugin-sdk/session-catalog";
|
|
27
|
-
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
28
29
|
import { decodeNodePtyResumeParams, resolveNodeHostExecutable, runNodePtyCommand } from "openclaw/plugin-sdk/node-host";
|
|
29
30
|
//#region extensions/codex/src/jsonl-lines.ts
|
|
30
31
|
const JSONL_STREAM_THRESHOLD_BYTES = 4 * 1024 * 1024;
|
|
@@ -578,61 +579,6 @@ function formatNodeLabel(node) {
|
|
|
578
579
|
].filter(Boolean).join(" / ") || "node";
|
|
579
580
|
}
|
|
580
581
|
//#endregion
|
|
581
|
-
//#region extensions/codex/src/app-server/thread-archive-guard.ts
|
|
582
|
-
const DESCENDANT_PAGE_LIMIT = 100;
|
|
583
|
-
const MAX_DESCENDANT_PAGES = 100;
|
|
584
|
-
const MAX_THREAD_ID_LENGTH = 256;
|
|
585
|
-
const MAX_CURSOR_LENGTH$1 = 4096;
|
|
586
|
-
function readBoundedId(value) {
|
|
587
|
-
if (typeof value !== "string") return;
|
|
588
|
-
const normalized = value.trim();
|
|
589
|
-
return normalized && normalized.length <= MAX_THREAD_ID_LENGTH ? normalized : void 0;
|
|
590
|
-
}
|
|
591
|
-
function readNextCursor(value) {
|
|
592
|
-
if (value === void 0 || value === null) return;
|
|
593
|
-
if (typeof value !== "string" || !value.trim() || value.length > MAX_CURSOR_LENGTH$1) throw new Error("Codex app-server returned an invalid descendant-list cursor");
|
|
594
|
-
return value;
|
|
595
|
-
}
|
|
596
|
-
/**
|
|
597
|
-
* Native archive includes the spawned subtree. Enumerate that same subtree first so an
|
|
598
|
-
* OpenClaw-owned descendant cannot be stopped as an undocumented side effect.
|
|
599
|
-
*/
|
|
600
|
-
async function assertCodexArchiveDescendantsUnowned(params) {
|
|
601
|
-
const ancestorThreadId = readBoundedId(params.threadId);
|
|
602
|
-
if (!ancestorThreadId) throw new Error("cannot verify Codex archive descendants for an invalid thread id");
|
|
603
|
-
const seenCursors = /* @__PURE__ */ new Set();
|
|
604
|
-
const seenThreadIds = /* @__PURE__ */ new Set([ancestorThreadId]);
|
|
605
|
-
let cursor;
|
|
606
|
-
for (let pageIndex = 0; pageIndex < MAX_DESCENDANT_PAGES; pageIndex += 1) {
|
|
607
|
-
const response = await params.listPage({
|
|
608
|
-
ancestorThreadId,
|
|
609
|
-
archived: false,
|
|
610
|
-
limit: DESCENDANT_PAGE_LIMIT,
|
|
611
|
-
sortKey: "created_at",
|
|
612
|
-
sortDirection: "desc",
|
|
613
|
-
useStateDbOnly: true,
|
|
614
|
-
...cursor ? { cursor } : {}
|
|
615
|
-
});
|
|
616
|
-
if (!isJsonObject(response) || !Array.isArray(response.data)) throw new Error("Codex app-server returned an invalid descendant-list response");
|
|
617
|
-
if (response.data.length > DESCENDANT_PAGE_LIMIT) throw new Error("Codex app-server exceeded the descendant-list page limit");
|
|
618
|
-
for (const value of response.data) {
|
|
619
|
-
if (!isJsonObject(value)) throw new Error("Codex app-server returned an invalid descendant thread");
|
|
620
|
-
const descendantThreadId = readBoundedId(value.id);
|
|
621
|
-
if (!descendantThreadId) throw new Error("Codex app-server returned a descendant without a valid thread id");
|
|
622
|
-
if (seenThreadIds.has(descendantThreadId)) throw new Error("Codex app-server returned a cyclic descendant thread list");
|
|
623
|
-
seenThreadIds.add(descendantThreadId);
|
|
624
|
-
await params.assertDescendantIdle(descendantThreadId);
|
|
625
|
-
if (await params.bindingStore.hasOtherThreadOwner(descendantThreadId)) throw new Error("cannot archive a Codex thread while a spawned descendant is owned by an OpenClaw session");
|
|
626
|
-
}
|
|
627
|
-
const nextCursor = readNextCursor(response.nextCursor);
|
|
628
|
-
if (!nextCursor) return;
|
|
629
|
-
if (seenCursors.has(nextCursor)) throw new Error("Codex app-server returned a repeated descendant-list cursor");
|
|
630
|
-
seenCursors.add(nextCursor);
|
|
631
|
-
cursor = nextCursor;
|
|
632
|
-
}
|
|
633
|
-
throw new Error("Codex descendant enumeration exceeded its safety limit");
|
|
634
|
-
}
|
|
635
|
-
//#endregion
|
|
636
582
|
//#region extensions/codex/src/command-rpc.ts
|
|
637
583
|
function requestOptions(pluginConfig, limit, config, agentDir) {
|
|
638
584
|
const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig });
|
|
@@ -645,10 +591,8 @@ function requestOptions(pluginConfig, limit, config, agentDir) {
|
|
|
645
591
|
};
|
|
646
592
|
}
|
|
647
593
|
async function codexControlRequest(pluginConfig, method, requestParams, options = {}) {
|
|
648
|
-
const runtime = resolveCodexAppServerRuntimeOptions({ pluginConfig });
|
|
649
|
-
|
|
650
|
-
method,
|
|
651
|
-
requestParams,
|
|
594
|
+
const runtime = options.startOptions ? resolveCodexSupervisionAppServerRuntimeOptions({ pluginConfig }) : resolveCodexAppServerRuntimeOptions({ pluginConfig });
|
|
595
|
+
const controlRequestOptions = {
|
|
652
596
|
timeoutMs: options.timeoutMs ?? runtime.requestTimeoutMs,
|
|
653
597
|
startOptions: options.startOptions ?? runtime.start,
|
|
654
598
|
config: options.config,
|
|
@@ -657,6 +601,19 @@ async function codexControlRequest(pluginConfig, method, requestParams, options
|
|
|
657
601
|
authProfileId: options.authProfileId,
|
|
658
602
|
agentDir: options.agentDir,
|
|
659
603
|
isolated: options.isolated
|
|
604
|
+
};
|
|
605
|
+
if (options.onResponse) return await withCodexAppServerJsonClient(controlRequestOptions, async (request, client) => {
|
|
606
|
+
const response = await request({
|
|
607
|
+
method,
|
|
608
|
+
requestParams
|
|
609
|
+
});
|
|
610
|
+
await options.onResponse(response, client);
|
|
611
|
+
return response;
|
|
612
|
+
});
|
|
613
|
+
return await requestCodexAppServerJson({
|
|
614
|
+
method,
|
|
615
|
+
requestParams,
|
|
616
|
+
...controlRequestOptions
|
|
660
617
|
});
|
|
661
618
|
}
|
|
662
619
|
async function safeCodexControlRequest(pluginConfig, method, requestParams, options = {}) {
|
|
@@ -707,6 +664,56 @@ async function safeValue(read) {
|
|
|
707
664
|
}
|
|
708
665
|
}
|
|
709
666
|
//#endregion
|
|
667
|
+
//#region extensions/codex/src/app-server/thread-archive-guard.ts
|
|
668
|
+
const DESCENDANT_PAGE_LIMIT = 100;
|
|
669
|
+
const MAX_DESCENDANT_PAGES = 100;
|
|
670
|
+
const MAX_THREAD_ID_LENGTH = 256;
|
|
671
|
+
const MAX_CURSOR_LENGTH$1 = 4096;
|
|
672
|
+
function readNextCursor(value) {
|
|
673
|
+
if (value === void 0 || value === null) return;
|
|
674
|
+
if (typeof value !== "string" || !value.trim() || value.length > MAX_CURSOR_LENGTH$1) throw new Error("Codex app-server returned an invalid descendant-list cursor");
|
|
675
|
+
return value;
|
|
676
|
+
}
|
|
677
|
+
/**
|
|
678
|
+
* Native archive includes the spawned subtree. Enumerate that same subtree first so an
|
|
679
|
+
* OpenClaw-owned descendant cannot be stopped as an undocumented side effect.
|
|
680
|
+
*/
|
|
681
|
+
async function assertCodexArchiveDescendantsUnowned(params) {
|
|
682
|
+
const ancestorThreadId = normalizeBoundedOptionalString(params.threadId, MAX_THREAD_ID_LENGTH);
|
|
683
|
+
if (!ancestorThreadId) throw new Error("cannot verify Codex archive descendants for an invalid thread id");
|
|
684
|
+
const seenCursors = /* @__PURE__ */ new Set();
|
|
685
|
+
const seenThreadIds = /* @__PURE__ */ new Set([ancestorThreadId]);
|
|
686
|
+
let cursor;
|
|
687
|
+
for (let pageIndex = 0; pageIndex < MAX_DESCENDANT_PAGES; pageIndex += 1) {
|
|
688
|
+
const response = await params.listPage({
|
|
689
|
+
ancestorThreadId,
|
|
690
|
+
archived: false,
|
|
691
|
+
limit: DESCENDANT_PAGE_LIMIT,
|
|
692
|
+
sortKey: "created_at",
|
|
693
|
+
sortDirection: "desc",
|
|
694
|
+
useStateDbOnly: true,
|
|
695
|
+
...cursor ? { cursor } : {}
|
|
696
|
+
});
|
|
697
|
+
if (!isJsonObject(response) || !Array.isArray(response.data)) throw new Error("Codex app-server returned an invalid descendant-list response");
|
|
698
|
+
if (response.data.length > DESCENDANT_PAGE_LIMIT) throw new Error("Codex app-server exceeded the descendant-list page limit");
|
|
699
|
+
for (const value of response.data) {
|
|
700
|
+
if (!isJsonObject(value)) throw new Error("Codex app-server returned an invalid descendant thread");
|
|
701
|
+
const descendantThreadId = normalizeBoundedOptionalString(value.id, MAX_THREAD_ID_LENGTH);
|
|
702
|
+
if (!descendantThreadId) throw new Error("Codex app-server returned a descendant without a valid thread id");
|
|
703
|
+
if (seenThreadIds.has(descendantThreadId)) throw new Error("Codex app-server returned a cyclic descendant thread list");
|
|
704
|
+
seenThreadIds.add(descendantThreadId);
|
|
705
|
+
await params.assertDescendantIdle(descendantThreadId);
|
|
706
|
+
if (await params.bindingStore.hasOtherThreadOwner(descendantThreadId)) throw new Error("cannot archive a Codex thread while a spawned descendant is owned by an OpenClaw session");
|
|
707
|
+
}
|
|
708
|
+
const nextCursor = readNextCursor(response.nextCursor);
|
|
709
|
+
if (!nextCursor) return;
|
|
710
|
+
if (seenCursors.has(nextCursor)) throw new Error("Codex app-server returned a repeated descendant-list cursor");
|
|
711
|
+
seenCursors.add(nextCursor);
|
|
712
|
+
cursor = nextCursor;
|
|
713
|
+
}
|
|
714
|
+
throw new Error("Codex descendant enumeration exceeded its safety limit");
|
|
715
|
+
}
|
|
716
|
+
//#endregion
|
|
710
717
|
//#region extensions/codex/src/session-catalog-create.ts
|
|
711
718
|
const CODEX_AGENT_RUNTIME_ID = "codex";
|
|
712
719
|
const CODEX_CATALOG_DEFAULT_MODEL_REF = "openai/gpt-5.6-sol";
|
|
@@ -813,7 +820,7 @@ function normalizeLimit(value, key) {
|
|
|
813
820
|
if (!Number.isInteger(value) || value < 1 || value > 100) throw new CatalogParamsError(`${key} must be an integer from 1 to 100`);
|
|
814
821
|
return value;
|
|
815
822
|
}
|
|
816
|
-
function
|
|
823
|
+
function readBoundedOptionalString(params, key, maxLength) {
|
|
817
824
|
const value = params[key];
|
|
818
825
|
if (value === void 0) return;
|
|
819
826
|
if (typeof value !== "string") throw new CatalogParamsError(`${key} must be a string`);
|
|
@@ -835,9 +842,9 @@ function readPageParams(value) {
|
|
|
835
842
|
"searchTerm",
|
|
836
843
|
"cwd"
|
|
837
844
|
]));
|
|
838
|
-
const cursor =
|
|
839
|
-
const searchTerm =
|
|
840
|
-
const cwd =
|
|
845
|
+
const cursor = readBoundedOptionalString(params, "cursor", MAX_CURSOR_LENGTH);
|
|
846
|
+
const searchTerm = readBoundedOptionalString(params, "searchTerm", MAX_SEARCH_LENGTH);
|
|
847
|
+
const cwd = readBoundedOptionalString(params, "cwd", MAX_CWD_LENGTH);
|
|
841
848
|
return {
|
|
842
849
|
limit: normalizeLimit(params.limit, "limit"),
|
|
843
850
|
...cursor ? { cursor } : {},
|
|
@@ -854,7 +861,7 @@ function readGatewayParams(value) {
|
|
|
854
861
|
"hostIds",
|
|
855
862
|
"cursors"
|
|
856
863
|
]));
|
|
857
|
-
const search =
|
|
864
|
+
const search = readBoundedOptionalString(params, "search", MAX_SEARCH_LENGTH);
|
|
858
865
|
let hostIds;
|
|
859
866
|
if (params.hostIds !== void 0) {
|
|
860
867
|
if (!Array.isArray(params.hostIds) || params.hostIds.length > 100) throw new CatalogParamsError(`hostIds must contain at most 100 host ids`);
|
|
@@ -894,9 +901,6 @@ function parseJsonParams(paramsJSON) {
|
|
|
894
901
|
throw new Error("Codex session catalog parameters must be valid JSON", { cause: error });
|
|
895
902
|
}
|
|
896
903
|
}
|
|
897
|
-
function readFiniteNumber(value) {
|
|
898
|
-
return typeof value === "number" && Number.isFinite(value) ? value : void 0;
|
|
899
|
-
}
|
|
900
904
|
function parseOptionalCatalogString(value, field, maxLength) {
|
|
901
905
|
if (value === void 0) return;
|
|
902
906
|
if (typeof value !== "string" || value.length > maxLength) throw new Error(`Codex session catalog returned an invalid ${field}`);
|
|
@@ -922,9 +926,9 @@ function parseCatalogSession(value, options = {}) {
|
|
|
922
926
|
const cliVersion = parseOptionalCatalogString(value.cliVersion, "CLI version", MAX_METADATA_LENGTH);
|
|
923
927
|
const gitBranch = parseOptionalCatalogString(value.gitBranch, "Git branch", MAX_METADATA_LENGTH);
|
|
924
928
|
const sessionKey = options.allowSessionKey ? parseOptionalCatalogString(value.sessionKey, "OpenClaw session key", MAX_SESSION_KEY_LENGTH) : void 0;
|
|
925
|
-
const createdAt =
|
|
926
|
-
const updatedAt =
|
|
927
|
-
const recencyAt = value.recencyAt === null ? null :
|
|
929
|
+
const createdAt = asFiniteNumber(value.createdAt);
|
|
930
|
+
const updatedAt = asFiniteNumber(value.updatedAt);
|
|
931
|
+
const recencyAt = value.recencyAt === null ? null : asFiniteNumber(value.recencyAt);
|
|
928
932
|
return {
|
|
929
933
|
threadId: value.threadId,
|
|
930
934
|
status,
|
|
@@ -1415,6 +1419,12 @@ async function continueNodeCodexSession(params) {
|
|
|
1415
1419
|
//#endregion
|
|
1416
1420
|
//#region extensions/codex/src/session-catalog-terminal.ts
|
|
1417
1421
|
const CODEX_TERMINAL_RESUME_COMMAND = "codex.terminal.resume.v1";
|
|
1422
|
+
function resolveCodexCatalogTerminalHome(sources) {
|
|
1423
|
+
const runtimeConfig = sources.getRuntimeConfig();
|
|
1424
|
+
if (!runtimeConfig) throw new Error("OpenClaw runtime config is unavailable");
|
|
1425
|
+
const startOptions = resolveCodexSupervisionAppServerRuntimeOptions({ pluginConfig: sources.getPluginConfig() }).start;
|
|
1426
|
+
return resolveCodexAppServerLocalHomeDir(startOptions, resolveDefaultAgentDir(runtimeConfig));
|
|
1427
|
+
}
|
|
1418
1428
|
function resolveLocalCodexTerminalExecutable(env = process.env) {
|
|
1419
1429
|
return resolveLocalCodexTerminalResolution(env)?.executable;
|
|
1420
1430
|
}
|
|
@@ -1458,7 +1468,7 @@ async function findCatalogEligibleThread(control, threadId, forceRefresh) {
|
|
|
1458
1468
|
}
|
|
1459
1469
|
throw new CatalogParamsError("Codex session eligibility could not be verified");
|
|
1460
1470
|
}
|
|
1461
|
-
function createCodexTerminalNodeHostCommand(control) {
|
|
1471
|
+
function createCodexTerminalNodeHostCommand(control, configSources) {
|
|
1462
1472
|
return {
|
|
1463
1473
|
command: CODEX_TERMINAL_RESUME_COMMAND,
|
|
1464
1474
|
cap: CODEX_APP_SERVER_THREADS_CAPABILITY,
|
|
@@ -1486,6 +1496,7 @@ function createCodexTerminalNodeHostCommand(control) {
|
|
|
1486
1496
|
file: resolution.executable,
|
|
1487
1497
|
args: ["resume", resume.threadId],
|
|
1488
1498
|
cwd: record.cwd,
|
|
1499
|
+
env: { CODEX_HOME: resolveCodexCatalogTerminalHome(configSources) },
|
|
1489
1500
|
cols: resume.cols,
|
|
1490
1501
|
rows: resume.rows
|
|
1491
1502
|
}, io));
|
|
@@ -1533,6 +1544,7 @@ async function openCodexCatalogTerminal(params) {
|
|
|
1533
1544
|
params.threadId
|
|
1534
1545
|
],
|
|
1535
1546
|
...record.cwd ? { cwd: record.cwd } : {},
|
|
1547
|
+
env: { CODEX_HOME: resolveCodexCatalogTerminalHome(params) },
|
|
1536
1548
|
...resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {},
|
|
1537
1549
|
title
|
|
1538
1550
|
};
|
|
@@ -1558,6 +1570,19 @@ async function openCodexCatalogTerminal(params) {
|
|
|
1558
1570
|
title
|
|
1559
1571
|
};
|
|
1560
1572
|
}
|
|
1573
|
+
async function startCodexCatalogTerminal(params) {
|
|
1574
|
+
if (params.nodeId) throw new CatalogParamsError("Paired-node Codex terminal start is unavailable; omit hostId to start on the gateway host");
|
|
1575
|
+
const resolution = resolveLocalCodexTerminalResolution();
|
|
1576
|
+
if (!resolution) throw new CatalogParamsError("Codex CLI is unavailable; install Codex or add codex to PATH, then try again");
|
|
1577
|
+
return {
|
|
1578
|
+
kind: "local",
|
|
1579
|
+
argv: [resolution.executable, ...params.initialMessage !== void 0 ? ["--", params.initialMessage] : []],
|
|
1580
|
+
cwd: params.cwd,
|
|
1581
|
+
env: { CODEX_HOME: resolveCodexCatalogTerminalHome(params) },
|
|
1582
|
+
...resolution.pathEnv ? { pathEnv: resolution.pathEnv } : {},
|
|
1583
|
+
title: "codex"
|
|
1584
|
+
};
|
|
1585
|
+
}
|
|
1561
1586
|
//#endregion
|
|
1562
1587
|
//#region extensions/codex/src/session-catalog-transcript-item.ts
|
|
1563
1588
|
const CODEX_MESSAGE_TYPES = /* @__PURE__ */ new Map([
|
|
@@ -2044,7 +2069,7 @@ async function listGatewayHost(params) {
|
|
|
2044
2069
|
async function listCodexSessionCatalog(params) {
|
|
2045
2070
|
const query = readGatewayParams(params.query);
|
|
2046
2071
|
const requestedHostIds = query.hostIds ? new Set(query.hostIds) : void 0;
|
|
2047
|
-
const localHosts = !requestedHostIds || requestedHostIds.has("gateway:local") ? [listGatewayHost({
|
|
2072
|
+
const localHosts = params.includeLocal !== false && (!requestedHostIds || requestedHostIds.has("gateway:local")) ? [listGatewayHost({
|
|
2048
2073
|
bindingStore: params.bindingStore,
|
|
2049
2074
|
config: params.config,
|
|
2050
2075
|
control: params.control,
|
|
@@ -2087,7 +2112,7 @@ async function listCodexSessionCatalog(params) {
|
|
|
2087
2112
|
return { hosts: await Promise.all([...localHosts, ...nodeHosts]) };
|
|
2088
2113
|
}
|
|
2089
2114
|
/** Builds the node-local read-only Codex app-server catalog command. */
|
|
2090
|
-
function createCodexSessionCatalogNodeHostCommands(control) {
|
|
2115
|
+
function createCodexSessionCatalogNodeHostCommands(control, configSources) {
|
|
2091
2116
|
return [
|
|
2092
2117
|
{
|
|
2093
2118
|
command: CODEX_APP_SERVER_THREADS_LIST_COMMAND,
|
|
@@ -2125,7 +2150,7 @@ function createCodexSessionCatalogNodeHostCommands(control) {
|
|
|
2125
2150
|
}
|
|
2126
2151
|
}
|
|
2127
2152
|
},
|
|
2128
|
-
createCodexTerminalNodeHostCommand(control)
|
|
2153
|
+
createCodexTerminalNodeHostCommand(control, configSources)
|
|
2129
2154
|
];
|
|
2130
2155
|
}
|
|
2131
2156
|
function readNodeTranscriptParams(value) {
|
|
@@ -2135,9 +2160,9 @@ function readNodeTranscriptParams(value) {
|
|
|
2135
2160
|
"cursor",
|
|
2136
2161
|
"limit"
|
|
2137
2162
|
]));
|
|
2138
|
-
const threadId =
|
|
2163
|
+
const threadId = readBoundedOptionalString(value, "threadId", 256);
|
|
2139
2164
|
if (!threadId) throw new CatalogParamsError("threadId is required");
|
|
2140
|
-
const cursor =
|
|
2165
|
+
const cursor = readBoundedOptionalString(value, "cursor", MAX_CURSOR_LENGTH);
|
|
2141
2166
|
return {
|
|
2142
2167
|
threadId,
|
|
2143
2168
|
limit: readBoundedLimit(value.limit, "limit", 20, 50),
|
|
@@ -2239,7 +2264,6 @@ async function listAdoptedSessionEntries(params) {
|
|
|
2239
2264
|
async function findAdoptedSessionEntry(params) {
|
|
2240
2265
|
return (await listAdoptedSessionEntries(params)).get(params.threadId);
|
|
2241
2266
|
}
|
|
2242
|
-
var CodexAdoptionBindingCleanupError = class extends AggregateError {};
|
|
2243
2267
|
async function clearCreatedAdoptionBinding(params) {
|
|
2244
2268
|
let cleared = false;
|
|
2245
2269
|
let clearError;
|
|
@@ -2257,14 +2281,14 @@ async function clearCreatedAdoptionBinding(params) {
|
|
|
2257
2281
|
try {
|
|
2258
2282
|
current = await params.bindingStore.read(params.identity);
|
|
2259
2283
|
} catch (readError) {
|
|
2260
|
-
throw new
|
|
2284
|
+
throw new AggregateError([
|
|
2261
2285
|
params.cause,
|
|
2262
2286
|
...clearError ? [clearError] : [],
|
|
2263
2287
|
readError
|
|
2264
|
-
], `OpenClaw session creation failed and the Codex binding could not be verified for ${params.sourceThreadId}
|
|
2288
|
+
], `OpenClaw session creation failed and the Codex binding could not be verified for ${params.sourceThreadId}`, { cause: readError });
|
|
2265
2289
|
}
|
|
2266
2290
|
if (!matchesPendingSupervisionOwner(current, params.expectedPending)) return;
|
|
2267
|
-
throw new
|
|
2291
|
+
throw new AggregateError([params.cause, ...clearError ? [clearError] : []], `OpenClaw session creation failed and the Codex binding could not be cleared for ${params.sourceThreadId}`, { cause: params.cause });
|
|
2268
2292
|
}
|
|
2269
2293
|
function matchesPendingAdoptionBinding(binding, expected) {
|
|
2270
2294
|
const historyCoveredThrough = binding?.historyCoveredThrough;
|
|
@@ -2576,13 +2600,22 @@ function toGenericCatalogHost(host, localTerminalAvailable) {
|
|
|
2576
2600
|
};
|
|
2577
2601
|
}
|
|
2578
2602
|
function registerCodexSessionCatalog(params) {
|
|
2579
|
-
const
|
|
2603
|
+
const usesProcessHomeFallback = () => {
|
|
2604
|
+
const start = resolveCodexSupervisionAppServerRuntimeOptions({ pluginConfig: params.getPluginConfig() }).start;
|
|
2605
|
+
return start.transport === "stdio" && start.homeScope === "user" && !process.env.CODEX_HOME?.trim();
|
|
2606
|
+
};
|
|
2607
|
+
const assertLocalAccess = (hostId, allowProcessHomeFallback) => {
|
|
2608
|
+
if (hostId === "gateway:local" && allowProcessHomeFallback === false && usesProcessHomeFallback()) throw new CatalogParamsError("local Codex sessions are unavailable in isolated state");
|
|
2609
|
+
};
|
|
2610
|
+
const checkUpstreamActivity = createChecker(params);
|
|
2611
|
+
params.api.registerSessionCatalog({
|
|
2580
2612
|
id: "codex",
|
|
2581
2613
|
label: "Codex",
|
|
2614
|
+
supportsProcessHomeIsolation: true,
|
|
2582
2615
|
resolveCreateSession: ({ agentId }) => resolveCodexCatalogCreateSession(params.getRuntimeConfig() ?? params.api.config, agentId),
|
|
2583
2616
|
list: async (query) => {
|
|
2584
2617
|
const localTerminalAvailable = resolveLocalCodexTerminalExecutable() !== void 0;
|
|
2585
|
-
const { listNodes, onHost, sessionEntries, ...gatewayQuery } = query;
|
|
2618
|
+
const { allowProcessHomeFallback, listNodes, onHost, sessionEntries, ...gatewayQuery } = query;
|
|
2586
2619
|
const mapHost = (host) => toGenericCatalogHost(host, localTerminalAvailable);
|
|
2587
2620
|
return (await listCodexSessionCatalog({
|
|
2588
2621
|
bindingStore: params.bindingStore,
|
|
@@ -2592,17 +2625,20 @@ function registerCodexSessionCatalog(params) {
|
|
|
2592
2625
|
query: gatewayQuery,
|
|
2593
2626
|
listNodes,
|
|
2594
2627
|
sessionEntries,
|
|
2628
|
+
includeLocal: allowProcessHomeFallback !== false || !usesProcessHomeFallback(),
|
|
2595
2629
|
...onHost ? { onHost: (host) => onHost(mapHost(host)) } : {}
|
|
2596
2630
|
})).hosts.map(mapHost);
|
|
2597
2631
|
},
|
|
2598
2632
|
read: async (request) => {
|
|
2633
|
+
const { allowProcessHomeFallback, ...catalogRequest } = request;
|
|
2634
|
+
assertLocalAccess(catalogRequest.hostId, allowProcessHomeFallback);
|
|
2599
2635
|
const page = await readCodexSessionTranscript({
|
|
2600
2636
|
runtime: params.api.runtime,
|
|
2601
2637
|
control: params.control,
|
|
2602
|
-
hostId:
|
|
2603
|
-
threadId:
|
|
2604
|
-
cursor:
|
|
2605
|
-
limit:
|
|
2638
|
+
hostId: catalogRequest.hostId,
|
|
2639
|
+
threadId: catalogRequest.threadId,
|
|
2640
|
+
cursor: catalogRequest.cursor,
|
|
2641
|
+
limit: catalogRequest.limit ?? 20
|
|
2606
2642
|
});
|
|
2607
2643
|
return {
|
|
2608
2644
|
...page,
|
|
@@ -2610,6 +2646,7 @@ function registerCodexSessionCatalog(params) {
|
|
|
2610
2646
|
};
|
|
2611
2647
|
},
|
|
2612
2648
|
continueSession: async (request) => {
|
|
2649
|
+
assertLocalAccess(request.hostId, request.allowProcessHomeFallback);
|
|
2613
2650
|
const config = params.getRuntimeConfig();
|
|
2614
2651
|
if (!config) throw new Error("OpenClaw runtime config is unavailable");
|
|
2615
2652
|
if (request.hostId.startsWith("node:")) return await continueNodeCodexSession({
|
|
@@ -2632,8 +2669,9 @@ function registerCodexSessionCatalog(params) {
|
|
|
2632
2669
|
}
|
|
2633
2670
|
})).sessionKey, request.threadId, upstreamBaseline);
|
|
2634
2671
|
},
|
|
2635
|
-
checkUpstreamActivity:
|
|
2672
|
+
checkUpstreamActivity: (probes, policy) => checkUpstreamActivity(probes.filter((probe) => probe.hostId !== "gateway:local" || policy?.allowProcessHomeFallback !== false || !usesProcessHomeFallback())),
|
|
2636
2673
|
archive: async (request) => {
|
|
2674
|
+
assertLocalAccess(request.hostId, request.allowProcessHomeFallback);
|
|
2637
2675
|
if (request.confirmNoOtherRunner !== true) throw new CatalogParamsError("archive requires confirmation that no other runner is active");
|
|
2638
2676
|
if (request.hostId !== "gateway:local") throw new CatalogParamsError("paired-node Codex sessions are view-only");
|
|
2639
2677
|
const config = params.getRuntimeConfig();
|
|
@@ -2647,14 +2685,26 @@ function registerCodexSessionCatalog(params) {
|
|
|
2647
2685
|
});
|
|
2648
2686
|
return { ok: true };
|
|
2649
2687
|
},
|
|
2650
|
-
openTerminal: (request) =>
|
|
2651
|
-
|
|
2652
|
-
|
|
2653
|
-
|
|
2654
|
-
|
|
2655
|
-
|
|
2656
|
-
|
|
2657
|
-
|
|
2688
|
+
openTerminal: async (request) => {
|
|
2689
|
+
assertLocalAccess(request.hostId, request.allowProcessHomeFallback);
|
|
2690
|
+
return await openCodexCatalogTerminal({
|
|
2691
|
+
api: params.api,
|
|
2692
|
+
control: params.control,
|
|
2693
|
+
getPluginConfig: params.getPluginConfig,
|
|
2694
|
+
getRuntimeConfig: params.getRuntimeConfig,
|
|
2695
|
+
parseCatalogPage,
|
|
2696
|
+
...request
|
|
2697
|
+
});
|
|
2698
|
+
},
|
|
2699
|
+
startTerminalSession: async (request) => {
|
|
2700
|
+
assertLocalAccess(request.nodeId ? `node:${request.nodeId}` : CODEX_LOCAL_SESSION_HOST_ID, request.allowProcessHomeFallback);
|
|
2701
|
+
return await startCodexCatalogTerminal({
|
|
2702
|
+
getPluginConfig: params.getPluginConfig,
|
|
2703
|
+
getRuntimeConfig: params.getRuntimeConfig,
|
|
2704
|
+
...request
|
|
2705
|
+
});
|
|
2706
|
+
}
|
|
2707
|
+
});
|
|
2658
2708
|
}
|
|
2659
2709
|
const codexSessionCatalogRuntime = {
|
|
2660
2710
|
register: registerCodexSessionCatalog,
|
|
@@ -2665,4 +2715,4 @@ const codexSessionCatalogRuntime = {
|
|
|
2665
2715
|
archiveLocal: archiveLocalCodexSession
|
|
2666
2716
|
};
|
|
2667
2717
|
//#endregion
|
|
2668
|
-
export { CODEX_LOCAL_SESSION_HOST_ID as a,
|
|
2718
|
+
export { CODEX_LOCAL_SESSION_HOST_ID as a, readCodexStatusProbes as c, createCodexCliSessionNodeHostCommands as d, createCodexCliSessionNodeInvokePolicies as f, resumeCodexCliSessionOnNode as g, resolveCodexCliSessionForBindingOnNode as h, createCodexSessionCatalogNodeInvokePolicies as i, requestOptions as l, listCodexCliSessionsOnNode as m, createCodexSessionCatalogControl as n, assertCodexArchiveDescendantsUnowned as o, formatCodexCliSessions as p, createCodexSessionCatalogNodeHostCommands as r, codexControlRequest as s, codexSessionCatalogRuntime as t, safeCodexControlRequest as u };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as CODEX_LOCAL_SESSION_HOST_ID } from "./session-catalog-
|
|
1
|
+
import { a as CODEX_LOCAL_SESSION_HOST_ID } from "./session-catalog-xwNi_SDM.js";
|
|
2
2
|
import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
3
3
|
import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
|
|
4
4
|
import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { K as releaseCodexAppServerLiveThread, d as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-kIBbGjk4.js";
|
|
2
|
+
import { a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-DMLXUfa8.js";
|
|
3
|
+
import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
|
|
4
|
+
import { t as codexNativeSubagentMonitorRuntime } from "./native-subagent-monitor-DyTGmTUx.js";
|
|
5
|
+
//#region extensions/codex/src/app-server/session-retirement.ts
|
|
6
|
+
/** Retire binding and native subscription under the same generation/physical-client ownership fence. */
|
|
7
|
+
async function retireCodexAppServerSessionGeneration(params) {
|
|
8
|
+
const retireGeneration = () => params.mode === "reset" ? params.bindingStore.resetSessionGeneration(params.identity) : params.bindingStore.retireSessionGeneration(params.identity);
|
|
9
|
+
const expectedBinding = await params.bindingStore.read(params.identity);
|
|
10
|
+
if (!expectedBinding) return await retireGeneration();
|
|
11
|
+
return await params.bindingStore.withLease(params.identity, async () => {
|
|
12
|
+
const binding = await params.bindingStore.read(params.identity);
|
|
13
|
+
if (binding?.threadId !== expectedBinding.threadId) return "conflict";
|
|
14
|
+
const result = await retireGeneration();
|
|
15
|
+
if (result !== "applied" || !binding?.clientId) return result;
|
|
16
|
+
const clientLease = retainSharedCodexAppServerClientByInstanceId(binding.clientId);
|
|
17
|
+
if (!clientLease) return result;
|
|
18
|
+
try {
|
|
19
|
+
codexNativeSubagentMonitorRuntime.retireParent(clientLease.client, binding.threadId);
|
|
20
|
+
if (!await releaseCodexAppServerLiveThread(clientLease.client, binding.threadId) && isIncognitoSessionKey(params.identity.sessionKey)) {
|
|
21
|
+
if (!await unsubscribeCodexThreadBestEffort(clientLease.client, {
|
|
22
|
+
threadId: binding.threadId,
|
|
23
|
+
timeoutMs: 5e3
|
|
24
|
+
})) {
|
|
25
|
+
await closeCodexStartupClientBestEffort(clientLease.client);
|
|
26
|
+
throw new CodexAppServerUnsafeSubscriptionError(`Codex retired session subscription could not be released: ${binding.threadId}`);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
} finally {
|
|
30
|
+
clientLease.release();
|
|
31
|
+
}
|
|
32
|
+
return result;
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
export { retireCodexAppServerSessionGeneration };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-
|
|
1
|
+
import { r as importCodexThreadHistoryToTranscript } from "./transcript-mirror-B9gGgnJS.js";
|
|
2
2
|
import { resolveStorePath } from "openclaw/plugin-sdk/session-store-runtime";
|
|
3
3
|
//#region extensions/codex/src/app-server/session-history-import.ts
|
|
4
4
|
/** Creates a session whose transcript is derived from one verified Codex thread snapshot. */
|
|
@@ -1,8 +1,9 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { t as
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
1
|
+
import { ct as isJsonObject } from "./shared-client-kIBbGjk4.js";
|
|
2
|
+
import { i as readUpstreamUserText, r as readMirrorIdentity, t as attachCodexMirrorIdentity } from "./upstream-prompt-provenance-ClRBije0.js";
|
|
3
|
+
import { c as readCodexMirrorSourceFingerprint, s as fingerprintCodexMirrorSourceMessage, t as codexTranscriptMirrorRuntime } from "./transcript-mirror-B9gGgnJS.js";
|
|
4
|
+
import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-qgZmzy_4.js";
|
|
5
|
+
import { n as createAssistantMessage } from "./event-projector-assistant-message-BwxV4d6N.js";
|
|
6
|
+
import { isRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
|
|
6
7
|
import { Buffer } from "node:buffer";
|
|
7
8
|
import { isSilentReplyText } from "openclaw/plugin-sdk/reply-runtime";
|
|
8
9
|
//#region extensions/codex/src/app-server/settled-turn-projection.ts
|
|
@@ -11,9 +12,6 @@ const MAX_PROJECTION_BYTES = 512 * 1024;
|
|
|
11
12
|
const MAX_TEXT_BYTES = 64 * 1024;
|
|
12
13
|
const TOOL_NAME_PATTERN = /^[a-zA-Z0-9_-]{1,128}$/u;
|
|
13
14
|
const TOOL_ERROR_STATUS_PREFIX = "[Tool result status: error]\n";
|
|
14
|
-
function readNonEmptyString(value) {
|
|
15
|
-
return typeof value === "string" ? value.trim() || void 0 : void 0;
|
|
16
|
-
}
|
|
17
15
|
function readBoundedText(value, label, maxBytes = MAX_TEXT_BYTES) {
|
|
18
16
|
if (typeof value !== "string" || !value.trim()) return;
|
|
19
17
|
if (Buffer.byteLength(value, "utf8") > maxBytes) throw new Error(`Codex settled-turn projection found oversized ${label}`);
|
|
@@ -28,12 +26,12 @@ function responseItemBytes(item) {
|
|
|
28
26
|
return Buffer.byteLength(JSON.stringify(item), "utf8");
|
|
29
27
|
}
|
|
30
28
|
function requireCallId(value) {
|
|
31
|
-
const callId =
|
|
29
|
+
const callId = normalizeOptionalString(value);
|
|
32
30
|
if (!callId || callId.length > 256) throw new Error("Codex settled-turn projection found an invalid tool call id");
|
|
33
31
|
return callId;
|
|
34
32
|
}
|
|
35
33
|
function requireToolName(value) {
|
|
36
|
-
const name =
|
|
34
|
+
const name = normalizeOptionalString(value);
|
|
37
35
|
if (!name || !TOOL_NAME_PATTERN.test(name)) throw new Error("Codex settled-turn projection found an invalid tool name");
|
|
38
36
|
return name;
|
|
39
37
|
}
|
|
@@ -152,7 +150,7 @@ function projectToolResult(message) {
|
|
|
152
150
|
for (const value of message.content) {
|
|
153
151
|
if (!isRecord(value)) throw new Error("Codex settled-turn projection found malformed tool result content");
|
|
154
152
|
if (value.type === "image") {
|
|
155
|
-
const mimeType =
|
|
153
|
+
const mimeType = normalizeOptionalString(value.mimeType) ?? "unknown type";
|
|
156
154
|
parts.push(`[Image tool result: ${mimeType}]`);
|
|
157
155
|
continue;
|
|
158
156
|
}
|
|
@@ -246,6 +244,7 @@ async function runCodexSettledTurnFinalization(operation, options) {
|
|
|
246
244
|
mode: "required",
|
|
247
245
|
id: attempt.modelId
|
|
248
246
|
},
|
|
247
|
+
modelProvider: "openai",
|
|
249
248
|
profile: attempt.authProfileId,
|
|
250
249
|
timeoutMs: attempt.runTimeoutOverrideMs ?? attempt.timeoutMs,
|
|
251
250
|
signal: attempt.abortSignal,
|
|
@@ -262,7 +261,8 @@ async function runCodexSettledTurnFinalization(operation, options) {
|
|
|
262
261
|
requiredModalities: ["text"],
|
|
263
262
|
isolation: "private-stdio",
|
|
264
263
|
historyItems,
|
|
265
|
-
requireNoExternalCapabilities: true
|
|
264
|
+
requireNoExternalCapabilities: true,
|
|
265
|
+
allowEmptyText: true
|
|
266
266
|
});
|
|
267
267
|
let promptEchoSeen = false;
|
|
268
268
|
let unexpectedItem;
|
|
@@ -281,7 +281,15 @@ async function runCodexSettledTurnFinalization(operation, options) {
|
|
|
281
281
|
}
|
|
282
282
|
if (unexpectedItem) throw new Error(`Codex settled-turn finalization returned unexpected native item: ${unexpectedItem.type}`);
|
|
283
283
|
const text = bounded.text.trim();
|
|
284
|
-
if (!text
|
|
284
|
+
if (!text) return {
|
|
285
|
+
assistant: createAssistantMessage(attempt, "", {
|
|
286
|
+
tokenUsage: bounded.usage,
|
|
287
|
+
aborted: false,
|
|
288
|
+
promptError: null
|
|
289
|
+
}),
|
|
290
|
+
...bounded.usage ? { usage: bounded.usage } : {}
|
|
291
|
+
};
|
|
292
|
+
if (isSilentReplyText(text)) throw new Error("Codex settled-turn finalization completed without a visible answer");
|
|
285
293
|
const mirrorIdentity = `settled-finalizer:${attempt.runId}`;
|
|
286
294
|
const assistant = attachCodexMirrorIdentity(createAssistantMessage(attempt, text, {
|
|
287
295
|
tokenUsage: bounded.usage,
|