@openclaw/codex 2026.9.2 → 2026.9.4
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 +29 -26
- package/dist/apply-CvT8tW5i.js +356 -0
- package/dist/{attempt-client-cleanup-Bp1ZOnk2.js → attempt-client-cleanup-DKHzbwt5.js} +38 -214
- package/dist/{attempt-context-CSazkWns.js → attempt-context-D44yeDII.js} +9 -7
- package/dist/{event-projector-usage-ZqEVbAEY.js → attempt-notifications-C9XufG6l.js} +3 -106
- package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-CWlKVccJ.js} +2 -2
- package/dist/auth-cache-key-7orQae_j.js +498 -0
- package/dist/auth-profile-CwzO4_RG.js +43 -0
- package/dist/auth-profile-selection-DFu9e167.js +45 -0
- package/dist/binding-connection-D3udKbIE.js +60 -0
- package/dist/{bounded-turn-DxGJRYbY.js → bounded-turn-C_Hneydj.js} +28 -125
- package/dist/build-state-BCmg9-5p.js +19 -0
- package/dist/{capabilities-B1mgvpP8.js → capabilities-8vx68WLH.js} +1 -1
- package/dist/cli-metadata.js +1 -1
- package/dist/client-B57KWPQx.js +4005 -0
- package/dist/command-dispatch-BpduNGVf.js +21 -0
- package/dist/{command-formatters-DSbGMXA0.js → command-formatters-lxlkNZgU.js} +4 -3
- package/dist/{command-handlers-DOJvGv6-.js → command-handlers-tiL9iWj7.js} +788 -135
- package/dist/command-rpc-CR5EOEZX.js +233 -0
- package/dist/{compact-Y_xBqrHN.js → compact-B_H3AOd7.js} +19 -14
- package/dist/config-oIORaQ5T.js +106 -0
- package/dist/{config-CyapYSji.js → config-options-CXMq1T-C.js} +205 -593
- package/dist/config-runtime-D0zGNIHu.js +11 -0
- package/dist/{config-utils-C57JiJrU.js → config-utils-DujwEnhg.js} +2 -4
- package/dist/conversation-binding-DsB4-O7U.js +900 -0
- package/dist/{plugin-marketplace-discovery-B7gHXJ3d.js → conversation-control-CtUu1b3m.js} +11 -143
- package/dist/doctor-contract-api.js +5 -5
- package/dist/{dynamic-tools-BwpvTxaX.js → dynamic-tools-CmN5RAip.js} +133 -76
- package/dist/{effective-mcp-catalog-CY9Jn4bA.js → effective-mcp-catalog-Bd73bqA8.js} +3 -3
- package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
- package/dist/ephemeral-turn-D78_VmzO.js +101 -0
- package/dist/{event-projector-assistant-message-B9kp6iGC.js → event-projector-assistant-message-BmBM4qBV.js} +12 -25
- package/dist/event-projector-items-5VhsECCO.js +200 -0
- package/dist/event-projector-usage-BfXmpOec.js +102 -0
- package/dist/{harness-Czh2Sdoc.js → harness-C7rRa7bm.js} +48 -24
- package/dist/harness.js +1 -1
- package/dist/history-rejection-B4nOXNXF.js +13 -0
- package/dist/incognito-session-uhrBF6wJ.js +15 -0
- package/dist/index.js +406 -2915
- package/dist/inference-context-Dr_mzvk4.js +94 -0
- package/dist/inference-proxy-HGXKUIre.js +311 -0
- package/dist/{isolated-completion-CRh-51AK.js → isolated-completion-DWVb5U2J.js} +7 -4
- package/dist/launch-args-RXQwn8zV.js +90 -0
- package/dist/{managed-binary-DcpnJF9x.js → managed-binary-D22rNEcR.js} +13 -103
- package/dist/managed-thread-store-D1t5jh3G.js +66 -0
- package/dist/media-understanding-provider.js +4 -1
- package/dist/migration-provider-api.js +2 -0
- package/dist/{model-catalog-DT5vo6qo.js → model-catalog-Dq2n8f_p.js} +6 -5
- package/dist/{models-CcrgSMQR.js → models-PCKOim-h.js} +3 -3
- package/dist/native-execution-policy-umd0tgh4.js +128 -0
- package/dist/native-subagent-history-DjtPloaU.js +140 -0
- package/dist/native-subagent-history-owner-Pcp7JuVF.js +34 -0
- package/dist/{native-subagent-monitor-B3bvQGcg.js → native-subagent-monitor-fQ7eIXEf.js} +115 -460
- package/dist/native-subagent-task-ids-BzTdT0Uw.js +387 -0
- package/dist/node-cli-sessions-DKaOmVUh.js +527 -0
- package/dist/{node-exec-server.runtime-nfbUOtUB.js → node-exec-server.runtime-Cl2vapEi.js} +55 -24
- package/dist/plan-7uG-Fp36.js +947 -0
- package/dist/plugin-activation-BYQculil.js +138 -0
- package/dist/{thread-resume-BLgqkUc1.js → plugin-app-cache-key-d0eKxy7b.js} +4 -52
- package/dist/{plugin-approval-roundtrip-aQVdyL5g.js → plugin-approval-roundtrip-Bz3FT8W5.js} +1 -1
- package/dist/plugin-inventory-oL4Na1ZG.js +328 -0
- package/dist/plugin-marketplace-discovery-P-Vndfqq.js +137 -0
- package/dist/{plugin-metadata-cache-BwCLTY_U.js → plugin-metadata-cache-ClPJpRio.js} +17 -9
- package/dist/protocol-5bh1G-H7.js +275 -0
- package/dist/provider-MQ8PVkuE.js +50 -0
- package/dist/{provider-capabilities-BpG9Ltc5.js → provider-capabilities-BvCUL69A.js} +2 -2
- package/dist/{rate-limits-Fx_l4eNa.js → rate-limits-CBMmWBr9.js} +1 -1
- package/dist/request-B7hEkBGq.js +212 -0
- package/dist/rpc-error-ttN_QjEm.js +30 -0
- package/dist/{run-attempt-BzthFQSM.js → run-attempt-CvsAAGa0.js} +664 -377
- package/dist/{runtime-artifact-Bh_gf6-t.js → runtime-artifact-BJ0rXBZ_.js} +27 -27
- package/dist/sandbox-guard-BxgyoM8M.js +166 -0
- package/dist/{session-binding-4Ki04sW-.js → session-binding-CI8UuilT.js} +30 -48
- package/dist/{session-binding-record-CyaXZvTe.js → session-binding-record-Bcvslnhf.js} +12 -26
- package/dist/session-catalog-adoption-tcZi1IfX.js +251 -0
- package/dist/session-catalog-archive-CwKg8Xz2.js +56 -0
- package/dist/session-catalog-ct-AH01I.js +1477 -0
- package/dist/session-catalog-home-id-CwhLdC03.js +18 -0
- package/dist/session-catalog-node-adoption-B1tgDW-m.js +182 -0
- package/dist/session-catalog-node-continue-Ci-DXyJP.js +238 -0
- package/dist/session-catalog-provenance-D-dIfRAH.js +96 -0
- package/dist/{session-cli-BjLhpmS1.js → session-cli-DNN_jhGc.js} +3 -2
- package/dist/{session-history-DWmMqiqW.js → session-history-Cz-tOOYj.js} +6 -3
- package/dist/{session-upstream-marker-DReTpGz6.js → session-history-import-DwyijFI6.js} +5 -50
- package/dist/{session-history-read-LHldwvyh.js → session-history-read-cxPUxyVV.js} +21 -7
- package/dist/session-history-worker-runtime.js +18 -6
- package/dist/session-history.worker-BeK1YOyT.js +378 -0
- package/dist/session-history.worker.js +1 -1
- package/dist/{session-initialization-BCFVnLL4.js → session-initialization-Ct0_Hzmg.js} +2 -2
- package/dist/{session-permission-policy-BaueHmSj.js → session-permission-policy-BBmXA8Eg.js} +4 -7
- package/dist/{session-retirement-DNdmYdFc.js → session-retirement-B2YfbAAT.js} +6 -5
- package/dist/session-upstream-marker-D15C9NHp.js +46 -0
- package/dist/{settled-turn-context-BOM3Y1pl.js → settled-turn-context-Du6gdUDd.js} +9 -9
- package/dist/{settled-turn-finalizer-BI-b1sry.js → settled-turn-finalizer-Dn91stmc.js} +8 -7
- package/dist/shared-client-CscigXXL.js +3109 -0
- package/dist/{side-question-B6DWAw1A.js → side-question-BGMJQf4U.js} +65 -170
- package/dist/source-CElXU0Oy.js +518 -0
- package/dist/thread-archive-guard-DfpBr-Sz.js +53 -0
- package/dist/thread-history-page-D0JIp48V.js +361 -0
- package/dist/{thread-lifecycle-DPK30jad.js → thread-lifecycle-DXl1-I6b.js} +187 -639
- package/dist/{thread-ownership-CbucAmmp.js → thread-ownership-BsDRTsyp.js} +13 -15
- package/dist/thread-policy-BuEQfE0g.js +54 -0
- package/dist/thread-resume-DsDOZpFg.js +52 -0
- package/dist/timeout-BVw8aaM1.js +33 -0
- package/dist/transcript-history-projection-v17wXgdK.js +238 -0
- package/dist/{transcript-mirror-_njEB84z.js → transcript-mirror-C5CKgNy6.js} +50 -260
- package/dist/{transcript-mirror-attestation-Byl34PC-.js → transcript-mirror-attestation-DibE0krH.js} +17 -4
- package/dist/{transport-stdio-CzTngV0j.js → transport-stdio-BGjHoYLr.js} +73 -43
- package/dist/{upstream-session-fork-1fwbNKzQ.js → upstream-session-fork-BZerMte_.js} +27 -19
- package/dist/{usage-i9fv5-4m.js → usage-tCk-mg_x.js} +4 -3
- package/dist/version-omm6IPI3.js +12 -0
- package/dist/{web-search-provider.runtime-DKQn67A7.js → web-search-provider.runtime-B7bGbGWq.js} +3 -3
- package/openclaw.plugin.json +23 -1
- package/package.json +4 -4
- package/dist/request-C8H22rPi.js +0 -475
- package/dist/session-catalog-B47uwekb.js +0 -3272
- package/dist/session-history.worker-zZVcx0ME.js +0 -267
- package/dist/shared-client-CKhX2kFt.js +0 -7505
- package/dist/thread-policy-CTalhWFy.js +0 -105
|
@@ -0,0 +1,498 @@
|
|
|
1
|
+
import { n as defineCodexBuildState } from "./build-state-BCmg9-5p.js";
|
|
2
|
+
import { c as resolveMacOSDesktopCodexAppPathCandidates } from "./managed-binary-D22rNEcR.js";
|
|
3
|
+
import { n as resolveCodexAppServerSpawnEnv } from "./transport-stdio-BGjHoYLr.js";
|
|
4
|
+
import { createHash } from "node:crypto";
|
|
5
|
+
import fs, { constants, existsSync, watch } from "node:fs";
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import os from "node:os";
|
|
8
|
+
import fs$1 from "node:fs/promises";
|
|
9
|
+
import { readSecretFile } from "openclaw/plugin-sdk/secret-file";
|
|
10
|
+
//#region extensions/codex/src/app-server/desktop-generation-fingerprint.ts
|
|
11
|
+
const MAX_COMPUTER_USE_PLUGIN_TREE_ENTRIES = 4096;
|
|
12
|
+
/** Fingerprints every desktop candidate that can own a managed fallback artifact. */
|
|
13
|
+
async function readMacOSDesktopGenerationFingerprint(candidates = resolveMacOSDesktopCodexAppPathCandidates("darwin")) {
|
|
14
|
+
const entries = [];
|
|
15
|
+
for (const candidate of candidates) {
|
|
16
|
+
const command = await statFingerprint(candidate.appServerCommandPath);
|
|
17
|
+
entries.push(`candidate:${candidate.appName}:${candidate.appServerCommandPath}:${command}`);
|
|
18
|
+
for (const artifactPath of resolveMacOSDesktopGenerationPaths(candidate)) entries.push(`${artifactPath}\0${await statFingerprint(artifactPath)}`);
|
|
19
|
+
const pluginRoot = resolveComputerUsePluginRoot(candidate);
|
|
20
|
+
entries.push(`${pluginRoot}\0${await directoryTreeFingerprint(pluginRoot)}`);
|
|
21
|
+
}
|
|
22
|
+
return createHash("sha256").update(entries.join("\0")).digest("hex");
|
|
23
|
+
}
|
|
24
|
+
function resolveMacOSDesktopGenerationPaths(candidate) {
|
|
25
|
+
return [
|
|
26
|
+
candidate.appBundlePath,
|
|
27
|
+
path.join(candidate.bundledMarketplacePath, ".agents", "plugins", "marketplace.json"),
|
|
28
|
+
...candidate.computerUseServiceAppPaths.flatMap((servicePath) => [
|
|
29
|
+
servicePath,
|
|
30
|
+
path.join(servicePath, "Contents", "Info.plist"),
|
|
31
|
+
path.join(servicePath, "Contents", "SharedSupport", "SkyComputerUseClient.app", "Contents", "MacOS", "SkyComputerUseClient")
|
|
32
|
+
])
|
|
33
|
+
];
|
|
34
|
+
}
|
|
35
|
+
function resolveComputerUsePluginRoot(candidate) {
|
|
36
|
+
return path.join(candidate.bundledMarketplacePath, "plugins", "computer-use");
|
|
37
|
+
}
|
|
38
|
+
/** Stable roots that cover bundle replacement and recursive artifact updates. */
|
|
39
|
+
function resolveMacOSDesktopGenerationWatchPaths(candidates = resolveMacOSDesktopCodexAppPathCandidates("darwin")) {
|
|
40
|
+
const watched = /* @__PURE__ */ new Set(["/Applications"]);
|
|
41
|
+
for (const candidate of candidates) watched.add(candidate.appBundlePath);
|
|
42
|
+
return [...watched];
|
|
43
|
+
}
|
|
44
|
+
async function directoryTreeFingerprint(root) {
|
|
45
|
+
let rootStat;
|
|
46
|
+
try {
|
|
47
|
+
rootStat = await fs$1.lstat(root, { bigint: true });
|
|
48
|
+
} catch (error) {
|
|
49
|
+
if (isNodeError(error, "ENOENT") || isNodeError(error, "ENOTDIR")) return "missing";
|
|
50
|
+
throw error;
|
|
51
|
+
}
|
|
52
|
+
if (!rootStat.isDirectory()) return statFingerprint(root);
|
|
53
|
+
let entryCount = 0;
|
|
54
|
+
const hash = createHash("sha256");
|
|
55
|
+
hash.update("openclaw-codex-computer-use-plugin-tree-v1\0");
|
|
56
|
+
const visit = async (directory, relativeDirectory, before) => {
|
|
57
|
+
hash.update(`directory\0${relativeDirectory}\0${statTuple(before)}\0`);
|
|
58
|
+
const entries = (await fs$1.readdir(directory, { withFileTypes: true })).toSorted((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
59
|
+
for (const entry of entries) {
|
|
60
|
+
entryCount += 1;
|
|
61
|
+
if (entryCount > MAX_COMPUTER_USE_PLUGIN_TREE_ENTRIES) throw new Error("Codex Computer Use plugin exceeds the bounded tree size");
|
|
62
|
+
const entryPath = path.join(directory, entry.name);
|
|
63
|
+
const relativePath = path.join(relativeDirectory, entry.name);
|
|
64
|
+
const entryStat = await fs$1.lstat(entryPath, { bigint: true });
|
|
65
|
+
if (entryStat.isDirectory()) await visit(entryPath, relativePath, entryStat);
|
|
66
|
+
else hash.update(`entry\0${relativePath}\0${await statFingerprint(entryPath)}\0`);
|
|
67
|
+
}
|
|
68
|
+
if (!sameStat(before, await fs$1.lstat(directory, { bigint: true }))) throw new Error(`Codex desktop artifact changed while fingerprinting: ${directory}`);
|
|
69
|
+
};
|
|
70
|
+
await visit(root, ".", rootStat);
|
|
71
|
+
return hash.digest("hex");
|
|
72
|
+
}
|
|
73
|
+
async function statFingerprint(filePath) {
|
|
74
|
+
try {
|
|
75
|
+
const entry = await fs$1.lstat(filePath, { bigint: true });
|
|
76
|
+
const type = entry.isSymbolicLink() ? "link" : entry.isDirectory() ? "directory" : entry.isFile() ? "file" : "other";
|
|
77
|
+
const own = statTuple(entry);
|
|
78
|
+
if (!entry.isSymbolicLink()) return `${type}:${own}:${entry.isFile() ? await readFileFingerprint(filePath, entry, false) : ""}`;
|
|
79
|
+
const [link, realPath, target] = await Promise.all([
|
|
80
|
+
fs$1.readlink(filePath),
|
|
81
|
+
fs$1.realpath(filePath),
|
|
82
|
+
fs$1.stat(filePath, { bigint: true })
|
|
83
|
+
]);
|
|
84
|
+
const content = target.isFile() ? await readFileFingerprint(filePath, target, true) : "";
|
|
85
|
+
return `${type}:${own}:${link}:${realPath}:${statTuple(target)}:${content}`;
|
|
86
|
+
} catch (error) {
|
|
87
|
+
if (isNodeError(error, "ENOENT") || isNodeError(error, "ENOTDIR")) return "missing";
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
async function readFileFingerprint(filePath, expected, followsSymlink) {
|
|
92
|
+
const noFollow = followsSymlink ? 0 : constants.O_NOFOLLOW ?? 0;
|
|
93
|
+
const handle = await fs$1.open(filePath, constants.O_RDONLY | noFollow);
|
|
94
|
+
try {
|
|
95
|
+
const before = await handle.stat({ bigint: true });
|
|
96
|
+
if (!sameStat(before, expected)) throw new Error(`Codex desktop artifact changed while fingerprinting: ${filePath}`);
|
|
97
|
+
const hash = createHash("sha256");
|
|
98
|
+
for await (const chunk of handle.createReadStream({ autoClose: false })) hash.update(chunk);
|
|
99
|
+
if (!sameStat(before, await handle.stat({ bigint: true }))) throw new Error(`Codex desktop artifact changed while fingerprinting: ${filePath}`);
|
|
100
|
+
return hash.digest("hex");
|
|
101
|
+
} finally {
|
|
102
|
+
await handle.close();
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
function sameStat(left, right) {
|
|
106
|
+
return statTuple(left) === statTuple(right);
|
|
107
|
+
}
|
|
108
|
+
function statTuple(stat) {
|
|
109
|
+
return [
|
|
110
|
+
stat.dev,
|
|
111
|
+
stat.ino,
|
|
112
|
+
stat.mode,
|
|
113
|
+
stat.size,
|
|
114
|
+
stat.mtimeNs,
|
|
115
|
+
stat.ctimeNs
|
|
116
|
+
].join(":");
|
|
117
|
+
}
|
|
118
|
+
function isNodeError(error, code) {
|
|
119
|
+
return Boolean(error && typeof error === "object" && "code" in error && error.code === code);
|
|
120
|
+
}
|
|
121
|
+
//#endregion
|
|
122
|
+
//#region extensions/codex/src/app-server/desktop-generation-owner.ts
|
|
123
|
+
const SETTLE_DELAY_MS = 1e3;
|
|
124
|
+
/** Coalesces filesystem invalidations into one stable desktop generation. */
|
|
125
|
+
function createCodexDesktopGenerationOwner(params) {
|
|
126
|
+
let generation = params.initialGeneration;
|
|
127
|
+
let invalidation = 0;
|
|
128
|
+
let dirty = false;
|
|
129
|
+
let refresh;
|
|
130
|
+
let stopped = false;
|
|
131
|
+
const markDirty = () => {
|
|
132
|
+
invalidation += 1;
|
|
133
|
+
dirty = true;
|
|
134
|
+
};
|
|
135
|
+
const reconcile = () => {
|
|
136
|
+
if (refresh) return refresh;
|
|
137
|
+
refresh = (async () => {
|
|
138
|
+
for (;;) {
|
|
139
|
+
if (stopped) throw new Error("Codex desktop generation owner stopped");
|
|
140
|
+
const observedInvalidation = invalidation;
|
|
141
|
+
const first = await params.readFingerprint();
|
|
142
|
+
await delay(SETTLE_DELAY_MS);
|
|
143
|
+
if (stopped) throw new Error("Codex desktop generation owner stopped");
|
|
144
|
+
const second = await params.readFingerprint();
|
|
145
|
+
if (stopped) throw new Error("Codex desktop generation owner stopped");
|
|
146
|
+
if (observedInvalidation !== invalidation || first !== second) continue;
|
|
147
|
+
const previous = generation;
|
|
148
|
+
generation = previous?.fingerprint === second ? previous : {
|
|
149
|
+
epoch: (previous?.epoch ?? 0) + 1,
|
|
150
|
+
fingerprint: second
|
|
151
|
+
};
|
|
152
|
+
dirty = false;
|
|
153
|
+
if (previous && generation !== previous) params.onGenerationChange?.(generation);
|
|
154
|
+
return generation;
|
|
155
|
+
}
|
|
156
|
+
})().finally(() => {
|
|
157
|
+
refresh = void 0;
|
|
158
|
+
});
|
|
159
|
+
return refresh;
|
|
160
|
+
};
|
|
161
|
+
return {
|
|
162
|
+
read: () => generation,
|
|
163
|
+
markDirty,
|
|
164
|
+
wait: () => dirty ? reconcile() : Promise.resolve(generation),
|
|
165
|
+
refresh: () => {
|
|
166
|
+
markDirty();
|
|
167
|
+
return reconcile();
|
|
168
|
+
},
|
|
169
|
+
isCurrent: (candidate) => Boolean(candidate && !dirty && generation && candidate.epoch === generation.epoch && candidate.fingerprint === generation.fingerprint),
|
|
170
|
+
stop: () => {
|
|
171
|
+
stopped = true;
|
|
172
|
+
}
|
|
173
|
+
};
|
|
174
|
+
}
|
|
175
|
+
function delay(ms) {
|
|
176
|
+
return new Promise((resolve) => {
|
|
177
|
+
setTimeout(resolve, ms);
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
//#endregion
|
|
181
|
+
//#region extensions/codex/src/app-server/desktop-generation.ts
|
|
182
|
+
/** Lifecycle-owned generation for managed macOS Codex desktop artifacts. */
|
|
183
|
+
const APPLICATIONS_PATH = "/Applications";
|
|
184
|
+
const REARM_INITIAL_DELAY_MS = 100;
|
|
185
|
+
const REARM_MAX_DELAY_MS = 3e4;
|
|
186
|
+
const state = defineCodexBuildState("openclaw.codexDesktopGenerationState", () => ({}));
|
|
187
|
+
function waitForCodexDesktopGeneration() {
|
|
188
|
+
return state().owner?.wait() ?? Promise.resolve(void 0);
|
|
189
|
+
}
|
|
190
|
+
function isCodexDesktopGenerationCurrent(generation) {
|
|
191
|
+
return state().owner?.isCurrent(generation) ?? false;
|
|
192
|
+
}
|
|
193
|
+
function createCodexDesktopGenerationService(params, runtime = {
|
|
194
|
+
platform: process.platform,
|
|
195
|
+
readFingerprint: readMacOSDesktopGenerationFingerprint,
|
|
196
|
+
resolveWatchPaths: resolveMacOSDesktopGenerationWatchPaths,
|
|
197
|
+
pathExists: existsSync,
|
|
198
|
+
watchPath: (watchedPath, options, listener) => watch(watchedPath, options, listener)
|
|
199
|
+
}) {
|
|
200
|
+
return {
|
|
201
|
+
id: "codex-desktop-generation",
|
|
202
|
+
async start(ctx) {
|
|
203
|
+
if (runtime.platform !== "darwin") return;
|
|
204
|
+
const current = state();
|
|
205
|
+
current.context = ctx;
|
|
206
|
+
current.readFingerprint = runtime.readFingerprint;
|
|
207
|
+
current.resolveWatchPaths = runtime.resolveWatchPaths;
|
|
208
|
+
current.pathExists = runtime.pathExists;
|
|
209
|
+
current.watchPath = runtime.watchPath;
|
|
210
|
+
current.owner = createCodexDesktopGenerationOwner({
|
|
211
|
+
readFingerprint: current.readFingerprint,
|
|
212
|
+
onGenerationChange: params.onGenerationChange,
|
|
213
|
+
initialGeneration: current.lastGeneration
|
|
214
|
+
});
|
|
215
|
+
armWatchers(current);
|
|
216
|
+
refreshGeneration(current, current.owner, current.owner.refresh());
|
|
217
|
+
},
|
|
218
|
+
async stop() {
|
|
219
|
+
const current = state();
|
|
220
|
+
current.lastGeneration = current.owner?.read() ?? current.lastGeneration;
|
|
221
|
+
current.owner?.stop();
|
|
222
|
+
current.owner = void 0;
|
|
223
|
+
current.armEpoch = (current.armEpoch ?? 0) + 1;
|
|
224
|
+
current.context = void 0;
|
|
225
|
+
current.readFingerprint = void 0;
|
|
226
|
+
current.resolveWatchPaths = void 0;
|
|
227
|
+
current.pathExists = void 0;
|
|
228
|
+
current.watchPath = void 0;
|
|
229
|
+
current.watchHealthy = void 0;
|
|
230
|
+
current.rearmDelayMs = void 0;
|
|
231
|
+
if (current.rearmTimer) {
|
|
232
|
+
clearTimeout(current.rearmTimer);
|
|
233
|
+
current.rearmTimer = void 0;
|
|
234
|
+
}
|
|
235
|
+
closeWatchers(current);
|
|
236
|
+
}
|
|
237
|
+
};
|
|
238
|
+
}
|
|
239
|
+
function armWatchers(current) {
|
|
240
|
+
const owner = current.owner;
|
|
241
|
+
if (!owner || current.watchers) return false;
|
|
242
|
+
const armEpoch = (current.armEpoch ?? 0) + 1;
|
|
243
|
+
current.armEpoch = armEpoch;
|
|
244
|
+
const watchers = /* @__PURE__ */ new Set();
|
|
245
|
+
current.watchers = watchers;
|
|
246
|
+
const candidateNames = new Set(resolveMacOSDesktopCodexAppPathCandidates("darwin").map((candidate) => candidate.appName));
|
|
247
|
+
let complete = true;
|
|
248
|
+
for (const watchedPath of current.resolveWatchPaths?.() ?? []) {
|
|
249
|
+
if (!current.pathExists?.(watchedPath)) continue;
|
|
250
|
+
try {
|
|
251
|
+
const watcher = current.watchPath?.(watchedPath, { recursive: watchedPath !== APPLICATIONS_PATH }, (_eventType, filename) => {
|
|
252
|
+
if (!isCurrentArm(current, owner, watchers, armEpoch)) return;
|
|
253
|
+
if (watchedPath === APPLICATIONS_PATH && filename && !candidateNames.has(filename.toString().split(path.sep)[0] ?? "")) return;
|
|
254
|
+
owner.markDirty();
|
|
255
|
+
scheduleRearm(current, owner);
|
|
256
|
+
});
|
|
257
|
+
if (!watcher) {
|
|
258
|
+
complete = false;
|
|
259
|
+
reportWatcherFailure(current, owner, /* @__PURE__ */ new Error(`Could not watch ${watchedPath}`));
|
|
260
|
+
scheduleRearm(current, owner);
|
|
261
|
+
continue;
|
|
262
|
+
}
|
|
263
|
+
watchers.add(watcher);
|
|
264
|
+
watcher.on("error", (error) => {
|
|
265
|
+
if (!isCurrentArm(current, owner, watchers, armEpoch)) return;
|
|
266
|
+
reportWatcherFailure(current, owner, error);
|
|
267
|
+
scheduleRearm(current, owner);
|
|
268
|
+
});
|
|
269
|
+
} catch (error) {
|
|
270
|
+
complete = false;
|
|
271
|
+
reportWatcherFailure(current, owner, error);
|
|
272
|
+
scheduleRearm(current, owner);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
current.watchHealthy = complete;
|
|
276
|
+
if (complete) current.rearmDelayMs = REARM_INITIAL_DELAY_MS;
|
|
277
|
+
return complete;
|
|
278
|
+
}
|
|
279
|
+
function reportWatcherFailure(current, owner, error) {
|
|
280
|
+
if (current.watchHealthy === false) return;
|
|
281
|
+
current.watchHealthy = false;
|
|
282
|
+
owner.markDirty();
|
|
283
|
+
current.context?.serviceHealth?.reportFailure(error);
|
|
284
|
+
current.context?.logger.warn(`codex desktop generation watcher failed: ${String(error)}`);
|
|
285
|
+
}
|
|
286
|
+
function isCurrentArm(current, owner, watchers, armEpoch) {
|
|
287
|
+
return current.owner === owner && current.watchers === watchers && current.armEpoch === armEpoch;
|
|
288
|
+
}
|
|
289
|
+
function scheduleRearm(current, owner) {
|
|
290
|
+
if (current.rearmTimer) {
|
|
291
|
+
if (current.watchHealthy === false) return;
|
|
292
|
+
clearTimeout(current.rearmTimer);
|
|
293
|
+
}
|
|
294
|
+
const delayMs = current.watchHealthy === false ? current.rearmDelayMs ?? REARM_INITIAL_DELAY_MS : REARM_INITIAL_DELAY_MS;
|
|
295
|
+
if (current.watchHealthy === false) current.rearmDelayMs = Math.min(delayMs * 2, REARM_MAX_DELAY_MS);
|
|
296
|
+
current.rearmTimer = setTimeout(() => {
|
|
297
|
+
current.rearmTimer = void 0;
|
|
298
|
+
if (current.owner !== owner) return;
|
|
299
|
+
const wasUnhealthy = current.watchHealthy === false;
|
|
300
|
+
closeWatchers(current);
|
|
301
|
+
if (!armWatchers(current) || wasUnhealthy) owner.markDirty();
|
|
302
|
+
refreshGeneration(current, owner, owner.wait());
|
|
303
|
+
}, delayMs);
|
|
304
|
+
current.rearmTimer.unref();
|
|
305
|
+
}
|
|
306
|
+
function logRefreshFailure(current, owner) {
|
|
307
|
+
return (error) => {
|
|
308
|
+
if (current.owner !== owner) return;
|
|
309
|
+
current.context?.serviceHealth?.reportFailure(error);
|
|
310
|
+
current.context?.logger.warn(`codex desktop generation refresh failed: ${String(error)}`);
|
|
311
|
+
};
|
|
312
|
+
}
|
|
313
|
+
function refreshGeneration(current, owner, refresh) {
|
|
314
|
+
refresh.then(() => {
|
|
315
|
+
if (current.owner === owner && current.watchHealthy) current.context?.serviceHealth?.clearFailure();
|
|
316
|
+
}).catch(logRefreshFailure(current, owner));
|
|
317
|
+
}
|
|
318
|
+
function closeWatchers(current) {
|
|
319
|
+
const watchers = current.watchers;
|
|
320
|
+
current.watchers = void 0;
|
|
321
|
+
for (const watcher of watchers ?? []) watcher.close();
|
|
322
|
+
}
|
|
323
|
+
//#endregion
|
|
324
|
+
//#region extensions/codex/src/app-server/shared-client-lifecycle.ts
|
|
325
|
+
/** Client ownership and synchronous retirement, independent of startup/auth execution. */
|
|
326
|
+
const createCodexAppServerStartupLifetime = () => ({
|
|
327
|
+
controller: new AbortController(),
|
|
328
|
+
pending: /* @__PURE__ */ new Set()
|
|
329
|
+
});
|
|
330
|
+
const getSharedCodexAppServerClientState = defineCodexBuildState("openclaw.codexAppServerClientState", () => ({
|
|
331
|
+
clients: /* @__PURE__ */ new Map(),
|
|
332
|
+
liveClients: /* @__PURE__ */ new Set(),
|
|
333
|
+
isolatedClients: /* @__PURE__ */ new Set(),
|
|
334
|
+
entriesByClient: /* @__PURE__ */ new WeakMap(),
|
|
335
|
+
desktopGenerationDrainChecks: /* @__PURE__ */ new Set(),
|
|
336
|
+
startup: createCodexAppServerStartupLifetime(),
|
|
337
|
+
startMetadata: /* @__PURE__ */ new WeakMap()
|
|
338
|
+
}));
|
|
339
|
+
function getCurrentSharedClientEntry(client) {
|
|
340
|
+
const state = getSharedCodexAppServerClientState();
|
|
341
|
+
const entry = client ? state.entriesByClient.get(client) : void 0;
|
|
342
|
+
return entry && entry.client === client && state.clients.get(entry.key) === entry ? entry : void 0;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Retires a matching shared client. Default is graceful: detach from the map
|
|
346
|
+
* (future acquisitions get a fresh client) and close once leases drain.
|
|
347
|
+
* `failActiveLeases` is for suspect clients only (timed-out turns): it closes
|
|
348
|
+
* the physical connection immediately so co-leased attempts hit the normal
|
|
349
|
+
* client-closed retry path, and pending acquires reject instead of leasing
|
|
350
|
+
* the poisoned process. Routine cleanup must NOT use it — it would abort
|
|
351
|
+
* healthy sibling turns on a working client.
|
|
352
|
+
*/
|
|
353
|
+
function retireSharedCodexAppServerClientIfCurrent(client, opts) {
|
|
354
|
+
if (!client) return;
|
|
355
|
+
const state = getSharedCodexAppServerClientState();
|
|
356
|
+
const currentEntry = getCurrentSharedClientEntry(client);
|
|
357
|
+
const entry = currentEntry ?? state.entriesByClient.get(client);
|
|
358
|
+
if (!entry || entry.client !== client && !entry.closeError) return;
|
|
359
|
+
if (currentEntry) {
|
|
360
|
+
state.clients.delete(entry.key);
|
|
361
|
+
entry.closeWhenIdle = true;
|
|
362
|
+
}
|
|
363
|
+
if (opts?.failActiveLeases && (currentEntry || !entry.closeError)) {
|
|
364
|
+
entry.closeError = /* @__PURE__ */ new Error("codex app-server client is closed");
|
|
365
|
+
return {
|
|
366
|
+
activeLeases: entry.activeLeases,
|
|
367
|
+
closed: closeRetiredSharedClientEntry(entry)
|
|
368
|
+
};
|
|
369
|
+
}
|
|
370
|
+
return {
|
|
371
|
+
activeLeases: entry.activeLeases,
|
|
372
|
+
closed: currentEntry ? closeRetiredSharedClientEntryIfIdle(entry) : false
|
|
373
|
+
};
|
|
374
|
+
}
|
|
375
|
+
/** Gracefully retires exact clients attached to an older desktop generation. */
|
|
376
|
+
function retireSharedCodexAppServerClientsBeforeDesktopGeneration(generation) {
|
|
377
|
+
const state = getSharedCodexAppServerClientState();
|
|
378
|
+
for (const entry of state.clients.values()) {
|
|
379
|
+
const client = entry.client;
|
|
380
|
+
const attached = client ? state.startMetadata.get(client) : void 0;
|
|
381
|
+
if (client && attached?.desktopGeneration && attached.desktopGeneration.epoch < generation.epoch) retireSharedCodexAppServerClientIfCurrent(client);
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
function closeRetiredSharedClientEntryIfIdle(entry) {
|
|
385
|
+
if (!entry.closeWhenIdle || entry.activeLeases > 0 || entry.pendingAcquires > 0 || !entry.client) return false;
|
|
386
|
+
entry.closeWhenIdle = false;
|
|
387
|
+
return closeRetiredSharedClientEntry(entry);
|
|
388
|
+
}
|
|
389
|
+
function closeRetiredSharedClientEntry(entry) {
|
|
390
|
+
const client = entry.client;
|
|
391
|
+
if (!client) return false;
|
|
392
|
+
entry.client = void 0;
|
|
393
|
+
client.close();
|
|
394
|
+
return true;
|
|
395
|
+
}
|
|
396
|
+
//#endregion
|
|
397
|
+
//#region extensions/codex/src/app-server/auth-cache-key.ts
|
|
398
|
+
/** Auth cache identity and native CLI credential reads, without login or refresh. */
|
|
399
|
+
const CODEX_HOME_ENV_VAR = "CODEX_HOME";
|
|
400
|
+
const HOME_ENV_VAR = "HOME";
|
|
401
|
+
const CODEX_HOME_DIRNAME = ".codex";
|
|
402
|
+
const CODEX_AUTH_JSON_FILENAME = "auth.json";
|
|
403
|
+
const CODEX_APP_SERVER_API_KEY_ENV_VARS = ["CODEX_API_KEY", "OPENAI_API_KEY"];
|
|
404
|
+
function resolveCodexAppServerEnvApiKeyCacheKey(params) {
|
|
405
|
+
if (params.startOptions.transport !== "stdio") return;
|
|
406
|
+
const apiKey = readFirstNonEmptyEnvEntry(resolveCodexAppServerSpawnEnv(params.startOptions, params.baseEnv ?? process.env, params.platform ?? process.platform), CODEX_APP_SERVER_API_KEY_ENV_VARS);
|
|
407
|
+
if (!apiKey) return;
|
|
408
|
+
const hash = createHash("sha256");
|
|
409
|
+
hash.update("openclaw:codex:app-server-env-api-key:v1");
|
|
410
|
+
hash.update("\0");
|
|
411
|
+
hash.update(apiKey.key);
|
|
412
|
+
hash.update("\0");
|
|
413
|
+
hash.update(apiKey.value);
|
|
414
|
+
return `${apiKey.key}:sha256:${hash.digest("hex")}`;
|
|
415
|
+
}
|
|
416
|
+
function resolveCodexAppServerFallbackApiKeyCacheKey(params) {
|
|
417
|
+
if (params.startOptions.transport !== "stdio") return;
|
|
418
|
+
return resolveCodexAppServerEnvApiKeyCacheKey(params) ?? resolveCodexCliAuthFileApiKeyCacheKey(params.baseEnv ?? process.env);
|
|
419
|
+
}
|
|
420
|
+
/** Secret-free cache identity for an API key already resolved by the runtime plan. */
|
|
421
|
+
function resolveCodexAppServerPreparedApiKeyCacheKey(apiKey) {
|
|
422
|
+
const resolved = apiKey?.trim();
|
|
423
|
+
return resolved ? fingerprintApiKeyAuthProfileCacheKey(resolved) : void 0;
|
|
424
|
+
}
|
|
425
|
+
function fingerprintApiKeyAuthProfileCacheKey(apiKey) {
|
|
426
|
+
const hash = createHash("sha256");
|
|
427
|
+
hash.update("openclaw:codex:app-server-auth-profile-api-key:v1");
|
|
428
|
+
hash.update("\0");
|
|
429
|
+
hash.update(apiKey);
|
|
430
|
+
return `api_key:sha256:${hash.digest("hex")}`;
|
|
431
|
+
}
|
|
432
|
+
function fingerprintTokenAuthProfileCacheKey(accessToken) {
|
|
433
|
+
const hash = createHash("sha256");
|
|
434
|
+
hash.update("openclaw:codex:app-server-auth-profile-token:v1");
|
|
435
|
+
hash.update("\0");
|
|
436
|
+
hash.update(accessToken);
|
|
437
|
+
return `token:sha256:${hash.digest("hex")}`;
|
|
438
|
+
}
|
|
439
|
+
function fingerprintCodexCliAuthFileApiKeyCacheKey(apiKey) {
|
|
440
|
+
const hash = createHash("sha256");
|
|
441
|
+
hash.update("openclaw:codex:app-server-cli-auth-json-api-key:v1");
|
|
442
|
+
hash.update("\0");
|
|
443
|
+
hash.update(apiKey);
|
|
444
|
+
return `CODEX_AUTH_JSON:sha256:${hash.digest("hex")}`;
|
|
445
|
+
}
|
|
446
|
+
function resolveCodexCliAuthFilePath(env) {
|
|
447
|
+
const configuredCodexHome = env[CODEX_HOME_ENV_VAR]?.trim();
|
|
448
|
+
if (configuredCodexHome) return path.join(resolveHomeRelativePath(configuredCodexHome, env), CODEX_AUTH_JSON_FILENAME);
|
|
449
|
+
const home = env[HOME_ENV_VAR]?.trim() || env.USERPROFILE?.trim() || os.homedir();
|
|
450
|
+
return path.join(home, CODEX_HOME_DIRNAME, CODEX_AUTH_JSON_FILENAME);
|
|
451
|
+
}
|
|
452
|
+
function resolveHomeRelativePath(value, env) {
|
|
453
|
+
if (value === "~" || value.startsWith("~/") || value.startsWith("~\\")) {
|
|
454
|
+
const home = env[HOME_ENV_VAR]?.trim() || env.USERPROFILE?.trim() || os.homedir();
|
|
455
|
+
return path.join(home, value.slice(value === "~" ? 1 : 2));
|
|
456
|
+
}
|
|
457
|
+
return value;
|
|
458
|
+
}
|
|
459
|
+
function parseCodexCliAuthFileApiKey(raw) {
|
|
460
|
+
let parsed;
|
|
461
|
+
try {
|
|
462
|
+
parsed = JSON.parse(raw);
|
|
463
|
+
} catch {
|
|
464
|
+
return;
|
|
465
|
+
}
|
|
466
|
+
if (!parsed || typeof parsed !== "object") return;
|
|
467
|
+
const apiKey = parsed.OPENAI_API_KEY;
|
|
468
|
+
return typeof apiKey === "string" && apiKey.trim() ? apiKey.trim() : void 0;
|
|
469
|
+
}
|
|
470
|
+
async function readCodexCliAuthFileApiKey(env) {
|
|
471
|
+
try {
|
|
472
|
+
return parseCodexCliAuthFileApiKey(await readSecretFile(resolveCodexCliAuthFilePath(env), "Codex CLI auth file"));
|
|
473
|
+
} catch {
|
|
474
|
+
return;
|
|
475
|
+
}
|
|
476
|
+
}
|
|
477
|
+
function resolveCodexCliAuthFileApiKeyCacheKey(env) {
|
|
478
|
+
try {
|
|
479
|
+
const apiKey = parseCodexCliAuthFileApiKey(fs.readFileSync(resolveCodexCliAuthFilePath(env), "utf8"));
|
|
480
|
+
return apiKey ? fingerprintCodexCliAuthFileApiKeyCacheKey(apiKey) : void 0;
|
|
481
|
+
} catch {
|
|
482
|
+
return;
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
function readFirstNonEmptyEnv(env, keys) {
|
|
486
|
+
return readFirstNonEmptyEnvEntry(env, keys)?.value;
|
|
487
|
+
}
|
|
488
|
+
function readFirstNonEmptyEnvEntry(env, keys) {
|
|
489
|
+
for (const key of keys) {
|
|
490
|
+
const value = env[key]?.trim();
|
|
491
|
+
if (value) return {
|
|
492
|
+
key,
|
|
493
|
+
value
|
|
494
|
+
};
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
//#endregion
|
|
498
|
+
export { isCodexDesktopGenerationCurrent as _, readCodexCliAuthFileApiKey as a, resolveCodexAppServerPreparedApiKeyCacheKey as c, createCodexAppServerStartupLifetime as d, getCurrentSharedClientEntry as f, createCodexDesktopGenerationService as g, retireSharedCodexAppServerClientsBeforeDesktopGeneration as h, fingerprintTokenAuthProfileCacheKey as i, closeRetiredSharedClientEntry as l, retireSharedCodexAppServerClientIfCurrent as m, CODEX_AUTH_JSON_FILENAME as n, readFirstNonEmptyEnv as o, getSharedCodexAppServerClientState as p, fingerprintApiKeyAuthProfileCacheKey as r, resolveCodexAppServerFallbackApiKeyCacheKey as s, CODEX_APP_SERVER_API_KEY_ENV_VARS as t, closeRetiredSharedClientEntryIfIdle as u, waitForCodexDesktopGeneration as v };
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { n as createCodexAuthProfileSelection } from "./auth-profile-selection-DFu9e167.js";
|
|
2
|
+
import { embeddedAgentLog, resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-harness-registration";
|
|
3
|
+
import { resolveProviderIdForAuth } from "openclaw/plugin-sdk/provider-auth-aliases";
|
|
4
|
+
import { ensureAuthProfileStore, resolveAuthProfileOrder } from "openclaw/plugin-sdk/provider-auth";
|
|
5
|
+
//#region extensions/codex/src/app-server/auth-profile.ts
|
|
6
|
+
/** Synchronous auth-profile selection and native provider identity. */
|
|
7
|
+
const CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER = "openai";
|
|
8
|
+
const PUBLIC_OPENAI_MODEL_PROVIDER = "openai";
|
|
9
|
+
const { resolveCodexAppServerAuthProfileId, resolveCodexAppServerAuthProfileIdForAgent, resolveCodexAppServerAuthProfileStore } = createCodexAuthProfileSelection({
|
|
10
|
+
ensureAuthProfileStore,
|
|
11
|
+
resolveAuthProfileOrder
|
|
12
|
+
});
|
|
13
|
+
/** Returns true when an auth profile uses native Codex/OpenAI app-server auth. */
|
|
14
|
+
function isCodexAppServerNativeAuthProfile(lookup) {
|
|
15
|
+
const authProfileId = lookup.authProfileId?.trim();
|
|
16
|
+
if (!authProfileId) return false;
|
|
17
|
+
try {
|
|
18
|
+
const credential = (lookup.authProfileStore ?? ensureAuthProfileStore(lookup.agentDir?.trim() || resolveDefaultAgentDir(lookup.config ?? {}), {
|
|
19
|
+
allowKeychainPrompt: false,
|
|
20
|
+
config: lookup.config,
|
|
21
|
+
externalCliProviderIds: [CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER],
|
|
22
|
+
externalCliProfileIds: [authProfileId]
|
|
23
|
+
})).profiles[authProfileId];
|
|
24
|
+
if (!credential || credential.type === "api_key") return false;
|
|
25
|
+
const provider = credential.provider?.trim();
|
|
26
|
+
return Boolean(provider && resolveProviderIdForAuth(provider, { config: lookup.config }) === CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER);
|
|
27
|
+
} catch (error) {
|
|
28
|
+
embeddedAgentLog.debug("failed to resolve codex app-server auth profile provider", {
|
|
29
|
+
authProfileId,
|
|
30
|
+
error
|
|
31
|
+
});
|
|
32
|
+
return false;
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Hides redundant OpenAI provider attribution for native Codex auth bindings. */
|
|
36
|
+
function normalizeCodexAppServerBindingModelProvider(params) {
|
|
37
|
+
const modelProvider = params.modelProvider?.trim();
|
|
38
|
+
if (!modelProvider) return;
|
|
39
|
+
if (isCodexAppServerNativeAuthProfile(params) && modelProvider.toLowerCase() === PUBLIC_OPENAI_MODEL_PROVIDER) return;
|
|
40
|
+
return modelProvider;
|
|
41
|
+
}
|
|
42
|
+
//#endregion
|
|
43
|
+
export { resolveCodexAppServerAuthProfileStore as a, resolveCodexAppServerAuthProfileIdForAgent as i, normalizeCodexAppServerBindingModelProvider as n, resolveCodexAppServerAuthProfileId as r, isCodexAppServerNativeAuthProfile as t };
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import { resolveDefaultAgentDir } from "openclaw/plugin-sdk/agent-harness-registration";
|
|
2
|
+
//#region extensions/codex/src/app-server/auth-profile-selection.ts
|
|
3
|
+
const CODEX_APP_SERVER_AUTH_PROVIDER = "openai";
|
|
4
|
+
const CODEX_APP_SERVER_EXTERNAL_CLI_PROVIDER_IDS = [CODEX_APP_SERVER_AUTH_PROVIDER];
|
|
5
|
+
function createCodexAuthProfileSelection({ ensureAuthProfileStore, resolveAuthProfileOrder }) {
|
|
6
|
+
function resolveCodexAppServerAuthProfileId(params) {
|
|
7
|
+
const requested = params.authProfileId?.trim();
|
|
8
|
+
if (requested) return requested;
|
|
9
|
+
return resolveAuthProfileOrder({
|
|
10
|
+
cfg: params.config,
|
|
11
|
+
store: params.store,
|
|
12
|
+
provider: CODEX_APP_SERVER_AUTH_PROVIDER
|
|
13
|
+
})[0]?.trim();
|
|
14
|
+
}
|
|
15
|
+
function resolveCodexAppServerAuthProfileIdForAgent(params) {
|
|
16
|
+
const store = resolveCodexAppServerAuthProfileStore({
|
|
17
|
+
agentDir: params.agentDir?.trim() || resolveDefaultAgentDir(params.config ?? {}),
|
|
18
|
+
authProfileId: params.authProfileId,
|
|
19
|
+
authProfileStore: params.authProfileStore,
|
|
20
|
+
config: params.config
|
|
21
|
+
});
|
|
22
|
+
return resolveCodexAppServerAuthProfileId({
|
|
23
|
+
authProfileId: params.authProfileId,
|
|
24
|
+
store,
|
|
25
|
+
config: params.config
|
|
26
|
+
});
|
|
27
|
+
}
|
|
28
|
+
function resolveCodexAppServerAuthProfileStore(params) {
|
|
29
|
+
if (params.authProfileStore) return params.authProfileStore;
|
|
30
|
+
return ensureAuthProfileStore(params.agentDir, {
|
|
31
|
+
profileId: params.authProfileId,
|
|
32
|
+
allowKeychainPrompt: false,
|
|
33
|
+
config: params.config,
|
|
34
|
+
externalCliProviderIds: CODEX_APP_SERVER_EXTERNAL_CLI_PROVIDER_IDS,
|
|
35
|
+
...params.authProfileId ? { externalCliProfileIds: [params.authProfileId] } : {}
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return {
|
|
39
|
+
resolveCodexAppServerAuthProfileId,
|
|
40
|
+
resolveCodexAppServerAuthProfileIdForAgent,
|
|
41
|
+
resolveCodexAppServerAuthProfileStore
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
//#endregion
|
|
45
|
+
export { createCodexAuthProfileSelection as n, CODEX_APP_SERVER_AUTH_PROVIDER as t };
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
|
|
2
|
+
import { x as readCodexPluginConfig } from "./protocol-5bh1G-H7.js";
|
|
3
|
+
import { a as resolveCodexCatalogConnectionHome, t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-d0eKxy7b.js";
|
|
4
|
+
import { n as resolveCodexAppServerRuntimeOptions, r as resolveCodexSupervisionAppServerRuntimeOptions } from "./config-runtime-D0zGNIHu.js";
|
|
5
|
+
import { AgentHarnessPreflightError } from "openclaw/plugin-sdk/agent-harness-registration";
|
|
6
|
+
//#region extensions/codex/src/app-server/binding-connection.ts
|
|
7
|
+
var binding_connection_exports = /* @__PURE__ */ __exportAll({
|
|
8
|
+
assertCodexSessionRuntimeOwnership: () => assertCodexSessionRuntimeOwnership,
|
|
9
|
+
requireCodexSupervisionModelSelection: () => requireCodexSupervisionModelSelection,
|
|
10
|
+
resolveCodexBindingAppServerConnection: () => resolveCodexBindingAppServerConnection
|
|
11
|
+
});
|
|
12
|
+
/** Prevents a prepared native session from becoming a fresh thread after its binding changes. */
|
|
13
|
+
function assertCodexSessionRuntimeOwnership(binding, expected) {
|
|
14
|
+
if (!expected) return;
|
|
15
|
+
const auth = binding?.connectionScope === "supervision" ? "native" : "host";
|
|
16
|
+
const hostModelChanged = expected.auth === "host" && (!expected.modelRef || binding?.model !== expected.modelRef.model || binding?.modelProvider !== expected.modelRef.provider);
|
|
17
|
+
if (binding?.preserveNativeModel !== true || auth !== expected.auth || hostModelChanged) throw new AgentHarnessPreflightError("Codex native session ownership is missing or changed. Reattach the original native session or create a new chat with a concrete model; no replacement thread was started.");
|
|
18
|
+
}
|
|
19
|
+
/** Requires the native model pair after a supervised pending branch has materialized. */
|
|
20
|
+
function requireCodexSupervisionModelSelection(binding) {
|
|
21
|
+
const model = binding.model?.trim();
|
|
22
|
+
const modelProvider = binding.modelProvider?.trim();
|
|
23
|
+
if (binding.connectionScope !== "supervision" || !model || !modelProvider) throw new Error("Codex supervised binding is missing its native model and provider; refusing request selection");
|
|
24
|
+
return {
|
|
25
|
+
model,
|
|
26
|
+
modelProvider
|
|
27
|
+
};
|
|
28
|
+
}
|
|
29
|
+
/** Resolves connection and auth ownership exclusively from the private thread binding. */
|
|
30
|
+
function resolveCodexBindingAppServerConnection(params) {
|
|
31
|
+
const { binding, authProfileId, ...runtimeParams } = params;
|
|
32
|
+
const usesSupervisionConnection = binding?.connectionScope === "supervision";
|
|
33
|
+
if (usesSupervisionConnection && readCodexPluginConfig(runtimeParams.pluginConfig).supervision?.enabled !== true) throw new Error("Codex supervision is disabled; refusing to open a native user-home supervised session");
|
|
34
|
+
let appServer = (usesSupervisionConnection ? resolveCodexSupervisionAppServerRuntimeOptions : resolveCodexAppServerRuntimeOptions)(runtimeParams);
|
|
35
|
+
if (usesSupervisionConnection) {
|
|
36
|
+
const persistedFingerprint = binding.pendingSupervisionBranch?.connectionFingerprint ?? binding.appServerRuntimeFingerprint;
|
|
37
|
+
const catalogHome = persistedFingerprint ? resolveCodexCatalogConnectionHome(persistedFingerprint, runtimeParams.agentDir) : void 0;
|
|
38
|
+
if (catalogHome) appServer = {
|
|
39
|
+
...appServer,
|
|
40
|
+
start: {
|
|
41
|
+
...appServer.start,
|
|
42
|
+
homeScope: "user",
|
|
43
|
+
env: {
|
|
44
|
+
...appServer.start.env,
|
|
45
|
+
CODEX_HOME: catalogHome
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
const currentFingerprint = buildCodexAppServerConnectionFingerprint(appServer, runtimeParams.agentDir);
|
|
50
|
+
if (!persistedFingerprint || persistedFingerprint !== currentFingerprint) throw new Error("Codex supervision connection changed; refusing to operate on its bound native thread");
|
|
51
|
+
}
|
|
52
|
+
return {
|
|
53
|
+
appServer,
|
|
54
|
+
usesSupervisionConnection,
|
|
55
|
+
requestAuthProfileId: usesSupervisionConnection ? void 0 : authProfileId,
|
|
56
|
+
clientAuthProfileId: usesSupervisionConnection ? null : authProfileId
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
//#endregion
|
|
60
|
+
export { resolveCodexBindingAppServerConnection as i, binding_connection_exports as n, requireCodexSupervisionModelSelection as r, assertCodexSessionRuntimeOwnership as t };
|