@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.
Files changed (68) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +147 -0
  3. package/dist/app-server-policy-bg5QPSVP.js +25 -0
  4. package/dist/attempt-client-cleanup-URjUlCHg.js +735 -0
  5. package/dist/binding-connection-DAvZwp96.js +45 -0
  6. package/dist/{bounded-turn-D2ZAgZVz.js → bounded-turn-4BjrZEwW.js} +63 -56
  7. package/dist/{capabilities-BFDTVYr4.js → capabilities-CH3K57v4.js} +8 -2
  8. package/dist/cli-metadata.js +1 -1
  9. package/dist/{command-formatters-C336eRVS.js → command-formatters-D0nZ3qtd.js} +18 -18
  10. package/dist/{command-handlers-DAHUSry9.js → command-handlers-DC86lgT4.js} +507 -101
  11. package/dist/command-rpc-xUIIonsO.js +90 -0
  12. package/dist/{compact-D_uvHurS.js → compact-COqgBRny.js} +234 -214
  13. package/dist/{session-binding-BXpo9ymA.js → config-CpNeo5AE.js} +284 -1163
  14. package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
  15. package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
  16. package/dist/doctor-contract-api.js +48 -50
  17. package/dist/{dynamic-tools-D2gYkSBO.js → dynamic-tools-fJZhl4CE.js} +3442 -1433
  18. package/dist/{effective-mcp-catalog-Bbd98Inw.js → effective-mcp-catalog-4YKn51aG.js} +20 -15
  19. package/dist/elicitation-input-DMkeki8d.js +71 -0
  20. package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
  21. package/dist/{attempt-notifications-AP-a-Q5k.js → event-projector-usage-CLwNEJqW.js} +113 -29
  22. package/dist/harness-DoKQcF8n.js +258 -0
  23. package/dist/harness.js +2 -160
  24. package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
  25. package/dist/index.js +730 -256
  26. package/dist/isolated-completion-DPMtlH9r.js +75 -0
  27. package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
  28. package/dist/managed-binary-By4FZC6i.js +212 -0
  29. package/dist/media-understanding-provider.js +5 -5
  30. package/dist/model-catalog-CmGoqVKB.js +48 -0
  31. package/dist/{models-BBMKU4jA.js → models-CZw1wClT.js} +12 -17
  32. package/dist/native-subagent-monitor-GGq3RnOo.js +3225 -0
  33. package/dist/node-exec-server.runtime-Bsu1LdFZ.js +192 -0
  34. package/dist/{plugin-app-cache-key-DztPafOA.js → plugin-app-cache-key-DMNQ8Zi8.js} +18 -6
  35. package/dist/plugin-approval-roundtrip-C75Yiiwc.js +95 -0
  36. package/dist/plugin-marketplace-discovery-CSWDkMrP.js +399 -0
  37. package/dist/{computer-use-CYEc8U3w.js → plugin-metadata-cache-BXH5NF-4.js} +109 -6
  38. package/dist/protocol-validators-VAVyEnDp.js +2399 -0
  39. package/dist/{rate-limits-CU-gVCCS.js → rate-limits-BI1dMHDG.js} +17 -35
  40. package/dist/{request-qKh331yu.js → request-DSK0W6YI.js} +3 -3
  41. package/dist/{run-attempt-CY9WlDLc.js → run-attempt-BV3HzuCf.js} +3416 -7194
  42. package/dist/{runtime-artifact-CmtG_t1L.js → runtime-artifact-BvyT1uyd.js} +11 -29
  43. package/dist/{sandbox-guard-NuhpXmPB.js → sandbox-guard-C1qEeZ5C.js} +29 -30
  44. package/dist/session-binding-BTrLf9Qm.js +874 -0
  45. package/dist/{session-catalog-DyOgR4WH.js → session-catalog-ezP_UcRM.js} +1584 -1289
  46. package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
  47. package/dist/{session-cli-2PZaFLRh.js → session-cli-B1hKvfkI.js} +20 -7
  48. package/dist/session-retirement-CE4iMiLh.js +36 -0
  49. package/dist/{session-upstream-marker-B6U7tLw5.js → session-upstream-marker-D_2npHlA.js} +1 -1
  50. package/dist/{settled-turn-finalizer-CXY2Z9dT.js → settled-turn-finalizer-Dx1onIqg.js} +40 -28
  51. package/dist/{shared-client-DTbvH-XV.js → shared-client-Dw-rzii0.js} +1315 -469
  52. package/dist/{side-question-_ulBk1AL.js → side-question-DbXkJZzg.js} +140 -69
  53. package/dist/{thread-lifecycle-DF53ogiA.js → thread-lifecycle-DKdrnTMX.js} +927 -768
  54. package/dist/thread-ownership-i2NBwDUL.js +92 -0
  55. package/dist/thread-resume-CdJk2Ehf.js +30 -0
  56. package/dist/transcript-mirror-BU0_LKAL.js +588 -0
  57. package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DhoGy33Z.js} +13 -2
  58. package/dist/upstream-prompt-provenance-CFmsKwr9.js +39 -0
  59. package/dist/{upstream-session-fork-Dy4Xvuoj.js → upstream-session-fork-BDVJCLAD.js} +14 -8
  60. package/dist/{usage-CQ6GhD5-.js → usage-9dKJCgcy.js} +3 -3
  61. package/dist/{web-search-provider.runtime-CCFhg2z5.js → web-search-provider.runtime-DCdx4DGu.js} +8 -9
  62. package/openclaw.plugin.json +49 -4
  63. package/package.json +6 -5
  64. package/dist/app-server-policy-BSaO2JIT.js +0 -49
  65. package/dist/conversation-control-xsIeXbo4.js +0 -287
  66. package/dist/event-projector-usage-Xp4AlR2k.js +0 -86
  67. package/dist/notification-correlation-CU6_AnOb.js +0 -67
  68. package/dist/transcript-mirror-DzsdNCf5.js +0 -6924
@@ -0,0 +1,75 @@
1
+ import { h as readCodexPluginConfig, r as resolveCodexAppServerHomeScope } from "./config-CpNeo5AE.js";
2
+ import { at as resolveCodexAppServerPreparedAuthHandoff, ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
3
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-4BjrZEwW.js";
4
+ import { i as createAttributedCodexAssistantMessage } from "./event-projector-assistant-message-BwxV4d6N.js";
5
+ //#region extensions/codex/src/app-server/isolated-completion.ts
6
+ const ISOLATED_PASSIVE_ITEM_TYPES = /* @__PURE__ */ new Set(["agentMessage", "reasoning"]);
7
+ function assertIsolatedCompletionItems(items, prompt) {
8
+ let promptEchoSeen = false;
9
+ for (const item of items) {
10
+ if (ISOLATED_PASSIVE_ITEM_TYPES.has(item.type)) continue;
11
+ if (item.type === "userMessage" && !promptEchoSeen) {
12
+ const content = Array.isArray(item.content) ? item.content : [];
13
+ const input = content[0];
14
+ if (content.length === 1 && isJsonObject(input) && input.type === "text" && input.text === prompt) {
15
+ promptEchoSeen = true;
16
+ continue;
17
+ }
18
+ }
19
+ throw new Error(`Codex isolated completion returned unexpected native item: ${item.type}`);
20
+ }
21
+ }
22
+ /** Runs prompt-only Codex inference on an ephemeral, ring-zero native thread. */
23
+ async function runCodexIsolatedCompletion(params, options) {
24
+ const authorization = params.authorization;
25
+ if (authorization.owner !== "harness") throw new Error("Codex native isolated completion requires harness-owned authorization.");
26
+ const pluginConfig = readCodexPluginConfig(options.pluginConfig);
27
+ const authRequirement = authorization.plan.modelRoute?.authRequirement;
28
+ const authHandoff = await resolveCodexAppServerPreparedAuthHandoff({
29
+ authRequirement,
30
+ authProfileId: authorization.plan.forwardedAuthProfileId,
31
+ authProfileStore: authorization.authProfileStore,
32
+ agentDir: params.agentDir,
33
+ homeScope: resolveCodexAppServerHomeScope({ appServer: pluginConfig.appServer }),
34
+ config: params.config,
35
+ subscriptionProfileRequiredError: "Prepared Codex subscription route requires a scoped native OAuth or token profile.",
36
+ subscriptionProfileUnusableError: `Prepared Codex auth profile "${authorization.plan.forwardedAuthProfileId}" is unusable.`
37
+ });
38
+ const authSelection = authHandoff.preparedAuth ? { preparedAuth: authHandoff.preparedAuth } : { profile: authHandoff.authProfileId };
39
+ const result = await runBoundedCodexAppServerTurn({
40
+ config: params.config,
41
+ model: {
42
+ mode: "required",
43
+ id: params.modelId
44
+ },
45
+ ...authSelection,
46
+ authRequirement,
47
+ timeoutMs: params.timeoutMs,
48
+ signal: params.abortSignal,
49
+ agentDir: params.agentDir,
50
+ authProfileStore: authorization.authProfileStore,
51
+ options,
52
+ taskLabel: "isolated completion",
53
+ developerInstructions: params.systemPrompt,
54
+ input: [{
55
+ type: "text",
56
+ text: params.prompt,
57
+ text_elements: []
58
+ }],
59
+ requiredModalities: ["text"],
60
+ isolation: "configured-transport",
61
+ requireNoExternalCapabilities: true
62
+ });
63
+ assertIsolatedCompletionItems(result.items, params.prompt);
64
+ return { assistant: createAttributedCodexAssistantMessage({
65
+ api: "openai-chatgpt-responses",
66
+ provider: params.provider,
67
+ modelId: result.model
68
+ }, result.text, {
69
+ tokenUsage: result.usage,
70
+ aborted: false,
71
+ promptError: null
72
+ }) };
73
+ }
74
+ //#endregion
75
+ export { runCodexIsolatedCompletion };
@@ -0,0 +1,19 @@
1
+ import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/string-coerce-runtime";
2
+ //#region extensions/codex/src/app-server/local-runtime-attribution.ts
3
+ const OPENAI_PROVIDER_ID = "openai";
4
+ const OPENAI_RESPONSES_API = "openai-responses";
5
+ const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses";
6
+ /** Maps local Codex runtime plans onto the provider/api pair exposed to event projection. */
7
+ function resolveCodexLocalRuntimeAttribution(params) {
8
+ const authProfileProvider = normalizeLowercaseStringOrEmpty(params.runtimePlan?.auth?.authProfileProviderForAuth);
9
+ if (normalizeLowercaseStringOrEmpty(params.runtimePlan?.observability.harnessId) === "codex" && authProfileProvider !== OPENAI_PROVIDER_ID && normalizeLowercaseStringOrEmpty(params.model.provider) === OPENAI_PROVIDER_ID && normalizeLowercaseStringOrEmpty(params.model.api) === OPENAI_RESPONSES_API) return {
10
+ provider: OPENAI_PROVIDER_ID,
11
+ api: OPENAI_CODEX_RESPONSES_API
12
+ };
13
+ return {
14
+ provider: params.provider,
15
+ api: params.model.api
16
+ };
17
+ }
18
+ //#endregion
19
+ export { resolveCodexLocalRuntimeAttribution as t };
@@ -0,0 +1,212 @@
1
+ import { createRequire } from "node:module";
2
+ import { access } from "node:fs/promises";
3
+ import path from "node:path";
4
+ import { constants, existsSync, readFileSync, realpathSync } from "node:fs";
5
+ import { fileURLToPath } from "node:url";
6
+ import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
7
+ //#region extensions/codex/src/app-server/version.ts
8
+ /**
9
+ * Version and package pins for the managed Codex app-server runtime.
10
+ */
11
+ /** Exact Codex app-server version shipped by the OpenClaw Codex bridge. */
12
+ const CODEX_APP_SERVER_VERSION = "0.149.1";
13
+ /** Inclusive runtime compatibility floor for external app-server binaries. */
14
+ const MIN_SUPPORTED_CODEX_APP_SERVER_VERSION = "0.147.0";
15
+ /** npm package name for the managed Codex app-server binary. */
16
+ const MANAGED_CODEX_APP_SERVER_PACKAGE = "@openai/codex";
17
+ //#endregion
18
+ //#region extensions/codex/src/app-server/managed-binary.ts
19
+ /**
20
+ * Resolves the managed Codex app-server binary shipped with or installed beside
21
+ * the Codex plugin before stdio startup.
22
+ */
23
+ const CODEX_PLUGIN_ROOT = resolveDefaultCodexPluginRoot(path.dirname(fileURLToPath(import.meta.url)));
24
+ let registeredCodexPluginRoot;
25
+ const MACOS_DESKTOP_CODEX_APP_SERVER_COMMANDS = ["/Applications/ChatGPT.app/Contents/Resources/codex", "/Applications/Codex.app/Contents/Resources/codex"];
26
+ /** Records the process-stable plugin root prepared by OpenClaw's plugin loader. */
27
+ function setManagedCodexPluginRoot(pluginRoot) {
28
+ registeredCodexPluginRoot = pluginRoot;
29
+ }
30
+ /** Rewrites managed stdio start options to point at an executable Codex binary path. */
31
+ async function resolveManagedCodexAppServerStartOptions(startOptions, options = {}) {
32
+ if (startOptions.transport !== "stdio" || startOptions.commandSource !== "managed") return startOptions;
33
+ const platform = options.platform ?? process.platform;
34
+ const commandPaths = await findManagedCodexAppServerCommandPaths({
35
+ candidateCommandPaths: resolveManagedCodexAppServerCommandCandidates(options.pluginRoot ?? registeredCodexPluginRoot ?? CODEX_PLUGIN_ROOT, platform, startOptions.managedCommandOrder ?? "package-first"),
36
+ pathExists: options.pathExists ?? commandPathExists,
37
+ platform
38
+ });
39
+ const commandPath = expectDefined(commandPaths[0], "resolved managed Codex command path");
40
+ const managedFallbackCommandPaths = commandPaths.slice(1);
41
+ return {
42
+ ...startOptions,
43
+ command: commandPath,
44
+ commandSource: "resolved-managed",
45
+ ...managedFallbackCommandPaths.length > 0 ? { managedFallbackCommandPaths } : {}
46
+ };
47
+ }
48
+ /** Resolves the native artifact behind a successful managed launcher selection. */
49
+ function resolveManagedCodexNativeCommand(command, options = {}) {
50
+ const platform = options.platform ?? process.platform;
51
+ if (isManagedCodexDesktopCommand(command, platform)) return command;
52
+ const target = resolveCodexNativeTarget(platform, options.arch ?? process.arch);
53
+ if (!target) return;
54
+ const packageRoot = resolveManagedCodexPackageRootForCommand(command, platform);
55
+ if (!packageRoot) return;
56
+ const resolvePackageJson = options.resolvePackageJson ?? resolvePackageJsonFromRoot;
57
+ const pathExists = options.pathExists ?? existsSync;
58
+ for (const packageName of [target.packageName, MANAGED_CODEX_APP_SERVER_PACKAGE]) {
59
+ const packageJsonPath = resolvePackageJson(packageName, packageRoot);
60
+ if (!packageJsonPath) continue;
61
+ const candidate = path.join(path.dirname(packageJsonPath), "vendor", target.triple, "bin", platform === "win32" ? "codex.exe" : "codex");
62
+ if (pathExists(candidate)) return candidate;
63
+ }
64
+ }
65
+ /** Returns whether a resolved managed command is owned by the macOS desktop app. */
66
+ function isManagedCodexDesktopCommand(command, platform = process.platform) {
67
+ return platform === "darwin" && MACOS_DESKTOP_CODEX_APP_SERVER_COMMANDS.some((candidate) => candidate === command);
68
+ }
69
+ function resolveManagedCodexPackageRootForCommand(command, platform) {
70
+ const pathApi = pathForPlatform(platform);
71
+ const commandPaths = [command];
72
+ try {
73
+ commandPaths.unshift(realpathSync(command));
74
+ } catch {}
75
+ for (const commandPath of commandPaths) {
76
+ let current = pathApi.dirname(commandPath);
77
+ while (true) {
78
+ if (pathApi.basename(current) === "codex" && pathApi.basename(pathApi.dirname(current)) === "@openai") return current;
79
+ if (pathApi.basename(current) === ".bin") return pathApi.join(pathApi.dirname(current), "@openai", "codex");
80
+ const parent = pathApi.dirname(current);
81
+ if (parent === current) break;
82
+ current = parent;
83
+ }
84
+ }
85
+ }
86
+ function resolveCodexNativeTarget(platform, arch) {
87
+ if ((platform === "linux" || platform === "android") && arch === "x64") return {
88
+ packageName: "@openai/codex-linux-x64",
89
+ triple: "x86_64-unknown-linux-musl"
90
+ };
91
+ if ((platform === "linux" || platform === "android") && arch === "arm64") return {
92
+ packageName: "@openai/codex-linux-arm64",
93
+ triple: "aarch64-unknown-linux-musl"
94
+ };
95
+ if (platform === "darwin" && arch === "x64") return {
96
+ packageName: "@openai/codex-darwin-x64",
97
+ triple: "x86_64-apple-darwin"
98
+ };
99
+ if (platform === "darwin" && arch === "arm64") return {
100
+ packageName: "@openai/codex-darwin-arm64",
101
+ triple: "aarch64-apple-darwin"
102
+ };
103
+ if (platform === "win32" && arch === "x64") return {
104
+ packageName: "@openai/codex-win32-x64",
105
+ triple: "x86_64-pc-windows-msvc"
106
+ };
107
+ if (platform === "win32" && arch === "arm64") return {
108
+ packageName: "@openai/codex-win32-arm64",
109
+ triple: "aarch64-pc-windows-msvc"
110
+ };
111
+ }
112
+ function resolvePackageJsonFromRoot(packageName, root) {
113
+ try {
114
+ return createRequire(path.join(root, "package.json")).resolve(`${packageName}/package.json`);
115
+ } catch {
116
+ return;
117
+ }
118
+ }
119
+ function resolveManagedCodexAppServerCommandCandidates(pluginRoot, platform, managedCommandOrder) {
120
+ const pathApi = pathForPlatform(platform);
121
+ const commandName = platform === "win32" ? "codex.cmd" : "codex";
122
+ const roots = resolveManagedCodexAppServerCandidateRoots(pluginRoot, platform);
123
+ const packageCommandPaths = [...roots.map((root) => pathApi.join(root, "node_modules", ".bin", commandName)), ...resolveManagedCodexPackageBinCandidates(roots, platform)];
124
+ const desktopCommandPaths = resolveDesktopCodexAppServerCommandCandidates(platform);
125
+ const orderedCommandPaths = managedCommandOrder === "desktop-first" ? [...desktopCommandPaths, ...packageCommandPaths] : [...packageCommandPaths, ...desktopCommandPaths];
126
+ return [...new Set(orderedCommandPaths)];
127
+ }
128
+ function resolveDesktopCodexAppServerCommandCandidates(platform) {
129
+ return platform === "darwin" ? [...MACOS_DESKTOP_CODEX_APP_SERVER_COMMANDS] : [];
130
+ }
131
+ function resolveDefaultCodexPluginRoot(moduleDir) {
132
+ const moduleBaseName = path.basename(moduleDir);
133
+ if (moduleBaseName === "dist" || moduleBaseName === "dist-runtime") return path.dirname(moduleDir);
134
+ return path.resolve(moduleDir, "..", "..");
135
+ }
136
+ function resolveManagedCodexAppServerCandidateRoots(pluginRoot, platform) {
137
+ const pathApi = pathForPlatform(platform);
138
+ const directRoots = [
139
+ pluginRoot,
140
+ pathApi.dirname(pluginRoot),
141
+ pathApi.dirname(pathApi.dirname(pluginRoot)),
142
+ isDistExtensionRoot(pluginRoot, platform) ? pathApi.dirname(pathApi.dirname(pathApi.dirname(pluginRoot))) : null
143
+ ].filter((root) => Boolean(root));
144
+ return [.../* @__PURE__ */ new Set([...directRoots, ...resolveNearestNodeModulesProjectRoots(directRoots, platform)])];
145
+ }
146
+ function resolveNearestNodeModulesProjectRoots(roots, platform) {
147
+ const pathApi = pathForPlatform(platform);
148
+ const projectRoots = [];
149
+ for (const root of roots) {
150
+ let current = pathApi.resolve(root);
151
+ while (true) {
152
+ if (pathApi.basename(current) === "node_modules") {
153
+ projectRoots.push(pathApi.dirname(current));
154
+ break;
155
+ }
156
+ const parent = pathApi.dirname(current);
157
+ if (parent === current) break;
158
+ current = parent;
159
+ }
160
+ }
161
+ return projectRoots;
162
+ }
163
+ function resolveManagedCodexPackageBinCandidates(roots, platform) {
164
+ if (platform === "win32") return [];
165
+ const candidates = [];
166
+ for (const root of roots) {
167
+ const candidate = resolveManagedCodexPackageBinCandidate(root);
168
+ if (candidate) candidates.push(candidate);
169
+ }
170
+ return candidates;
171
+ }
172
+ function resolveManagedCodexPackageBinCandidate(root) {
173
+ try {
174
+ const packageJsonPath = createRequire(path.join(root, "package.json")).resolve(`${MANAGED_CODEX_APP_SERVER_PACKAGE}/package.json`);
175
+ const packageRoot = path.dirname(packageJsonPath);
176
+ const packageJson = JSON.parse(readFileSync(packageJsonPath, "utf8"));
177
+ const packageBin = packageJson.bin && typeof packageJson.bin === "object" ? packageJson.bin : void 0;
178
+ const binPath = typeof packageJson.bin === "string" ? packageJson.bin : typeof packageBin?.codex === "string" ? packageBin.codex : null;
179
+ return binPath ? path.resolve(packageRoot, binPath) : null;
180
+ } catch {
181
+ return null;
182
+ }
183
+ }
184
+ function isDistExtensionRoot(pluginRoot, platform) {
185
+ const pathApi = pathForPlatform(platform);
186
+ const extensionsDir = pathApi.dirname(pluginRoot);
187
+ const distDir = pathApi.dirname(extensionsDir);
188
+ return pathApi.basename(extensionsDir) === "extensions" && (pathApi.basename(distDir) === "dist" || pathApi.basename(distDir) === "dist-runtime");
189
+ }
190
+ function pathForPlatform(platform) {
191
+ return platform === "win32" ? path.win32 : path.posix;
192
+ }
193
+ async function findManagedCodexAppServerCommandPaths(params) {
194
+ const commandPaths = [];
195
+ for (const commandPath of params.candidateCommandPaths) if (await params.pathExists(commandPath, params.platform)) commandPaths.push(commandPath);
196
+ if (commandPaths.length > 0) return commandPaths;
197
+ throw new Error([
198
+ `Managed Codex app-server binary was not found for ${MANAGED_CODEX_APP_SERVER_PACKAGE}.`,
199
+ "Reinstall or update OpenClaw, or run pnpm install in a source checkout.",
200
+ "Set plugins.entries.codex.config.appServer.command or OPENCLAW_CODEX_APP_SERVER_BIN to use a custom Codex binary."
201
+ ].join(" "));
202
+ }
203
+ async function commandPathExists(filePath, platform) {
204
+ try {
205
+ await access(filePath, platform === "win32" ? constants.F_OK : constants.X_OK);
206
+ return true;
207
+ } catch {
208
+ return false;
209
+ }
210
+ }
211
+ //#endregion
212
+ export { CODEX_APP_SERVER_VERSION as a, setManagedCodexPluginRoot as i, resolveManagedCodexAppServerStartOptions as n, MIN_SUPPORTED_CODEX_APP_SERVER_VERSION as o, resolveManagedCodexNativeCommand as r, isManagedCodexDesktopCommand as t };
@@ -1,4 +1,5 @@
1
- import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-D2ZAgZVz.js";
1
+ import { t as runBoundedCodexAppServerTurn } from "./bounded-turn-4BjrZEwW.js";
2
+ import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
2
3
  import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
3
4
  //#region extensions/codex/media-understanding-provider.ts
4
5
  /**
@@ -49,6 +50,7 @@ async function describeCodexImages(req, options) {
49
50
  mode: "required",
50
51
  id: model
51
52
  },
53
+ modelProvider: "openai",
52
54
  profile: req.profile,
53
55
  timeoutMs: req.timeoutMs,
54
56
  signal: req.signal,
@@ -86,6 +88,7 @@ async function extractCodexStructured(req, options) {
86
88
  mode: "required",
87
89
  id: model
88
90
  },
91
+ modelProvider: "openai",
89
92
  profile: req.profile,
90
93
  timeoutMs: req.timeoutMs,
91
94
  signal: req.signal,
@@ -138,9 +141,6 @@ function buildStructuredExtractionPrompt(req) {
138
141
  req.jsonMode === false ? "Return the extraction as concise text." : "Return valid JSON only. Do not wrap the JSON in Markdown fences."
139
142
  ].filter((part) => Boolean(part)).join("\n\n");
140
143
  }
141
- function isJsonSchemaObject(value) {
142
- return typeof value === "object" && value !== null && !Array.isArray(value);
143
- }
144
144
  function normalizeStructuredExtractionResult(params) {
145
145
  const result = {
146
146
  text: params.text,
@@ -154,7 +154,7 @@ function normalizeStructuredExtractionResult(params) {
154
154
  } catch {
155
155
  throw new Error("Codex structured extraction returned invalid JSON.");
156
156
  }
157
- if (isJsonSchemaObject(params.req.jsonSchema)) {
157
+ if (isRecord(params.req.jsonSchema)) {
158
158
  const validation = validateJsonSchemaValue({
159
159
  schema: params.req.jsonSchema,
160
160
  cacheKey: "codex.media-understanding.extractStructured",
@@ -0,0 +1,48 @@
1
+ import { r as buildCodexRuntimeModelParams } from "./harness-DoKQcF8n.js";
2
+ import { h as readCodexPluginConfig } from "./config-CpNeo5AE.js";
3
+ import { t as listAllCodexAppServerModels } from "./models-CZw1wClT.js";
4
+ import { r as requestOptions } from "./command-rpc-xUIIonsO.js";
5
+ //#region extensions/codex/src/app-server/model-catalog.ts
6
+ const OPENAI_CODEX_BASE_URL = "https://chatgpt.com/backend-api/codex";
7
+ const DEFAULT_MODEL_DISCOVERY_TIMEOUT_MS = 2500;
8
+ const INPUT_TYPES = /* @__PURE__ */ new Set([
9
+ "text",
10
+ "image",
11
+ "audio",
12
+ "video",
13
+ "document"
14
+ ]);
15
+ function isModelInputType(value) {
16
+ return INPUT_TYPES.has(value);
17
+ }
18
+ function codexAppServerModelsToCatalogEntries(models) {
19
+ return models.map((model, providerOrder) => {
20
+ const input = model.inputModalities.filter(isModelInputType);
21
+ const runtimeParams = buildCodexRuntimeModelParams(model.id, model.model);
22
+ return {
23
+ provider: "openai",
24
+ id: model.id,
25
+ name: model.displayName ?? model.id,
26
+ providerOrder,
27
+ api: "openai-chatgpt-responses",
28
+ baseUrl: OPENAI_CODEX_BASE_URL,
29
+ reasoning: model.supportedReasoningEfforts.length > 0,
30
+ ...input.length > 0 ? { input } : {},
31
+ ...runtimeParams ? { params: runtimeParams } : {},
32
+ compat: {
33
+ supportsReasoningEffort: model.supportedReasoningEfforts.length > 0,
34
+ supportedReasoningEfforts: model.supportedReasoningEfforts
35
+ }
36
+ };
37
+ });
38
+ }
39
+ async function loadCodexAppServerModelCatalog(params, pluginConfig) {
40
+ const discovery = readCodexPluginConfig(pluginConfig).discovery;
41
+ if (discovery?.enabled === false) return [];
42
+ return codexAppServerModelsToCatalogEntries((await listAllCodexAppServerModels({
43
+ ...requestOptions(pluginConfig, 100, params.config, params.agentDir),
44
+ timeoutMs: discovery?.timeoutMs ?? DEFAULT_MODEL_DISCOVERY_TIMEOUT_MS
45
+ })).models);
46
+ }
47
+ //#endregion
48
+ export { loadCodexAppServerModelCatalog };
@@ -1,5 +1,5 @@
1
- import { x as readCodexModelListResponse } from "./transcript-mirror-DzsdNCf5.js";
2
- import { uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
1
+ import { t as assertCodexModelListResponse } from "./protocol-validators-VAVyEnDp.js";
2
+ import { normalizeOptionalString, uniqueStrings } from "openclaw/plugin-sdk/string-coerce-runtime";
3
3
  //#region extensions/codex/src/app-server/models.ts
4
4
  /**
5
5
  * Lists and normalizes models exposed by the Codex app-server `model/list`
@@ -40,7 +40,7 @@ async function listAllCodexAppServerModels(options = {}) {
40
40
  async function withCodexAppServerModelClient(options, run) {
41
41
  const timeoutMs = options.timeoutMs ?? 2500;
42
42
  const useSharedClient = options.sharedClient !== false;
43
- const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-DTbvH-XV.js").then((n) => n.m);
43
+ const { createIsolatedCodexAppServerClient, getLeasedSharedCodexAppServerClient, releaseLeasedSharedCodexAppServerClient } = await import("./shared-client-Dw-rzii0.js").then((n) => n.m);
44
44
  const client = useSharedClient ? await getLeasedSharedCodexAppServerClient({
45
45
  startOptions: options.startOptions,
46
46
  timeoutMs,
@@ -75,9 +75,8 @@ async function requestModelListPage(client, options) {
75
75
  }
76
76
  /** Parses a raw Codex app-server model/list response into OpenClaw's normalized shape. */
77
77
  function readModelListResult(value) {
78
- const response = readCodexModelListResponse(value);
79
- if (!response) return { models: [] };
80
- const models = response.data.map((entry) => readCodexModel(entry)).filter((entry) => entry !== void 0);
78
+ const response = assertCodexModelListResponse(value);
79
+ const models = response.data.map((entry) => readCodexModel(entry));
81
80
  const nextCursor = response.nextCursor ?? void 0;
82
81
  return {
83
82
  models,
@@ -85,27 +84,23 @@ function readModelListResult(value) {
85
84
  };
86
85
  }
87
86
  function readCodexModel(value) {
88
- const id = readNonEmptyString(value.id);
89
- const model = readNonEmptyString(value.model) ?? id;
90
- if (!id || !model) return;
87
+ const id = normalizeOptionalString(value.id);
88
+ const model = normalizeOptionalString(value.model);
89
+ if (!id || !model) throw new Error("Invalid Codex app-server model/list response: model id and name must be non-empty strings");
91
90
  return {
92
91
  id,
93
92
  model,
94
- ...readNonEmptyString(value.displayName) ? { displayName: readNonEmptyString(value.displayName) } : {},
95
- ...readNonEmptyString(value.description) ? { description: readNonEmptyString(value.description) } : {},
93
+ ...normalizeOptionalString(value.displayName) ? { displayName: normalizeOptionalString(value.displayName) } : {},
94
+ ...normalizeOptionalString(value.description) ? { description: normalizeOptionalString(value.description) } : {},
96
95
  hidden: value.hidden,
97
96
  isDefault: value.isDefault,
98
97
  inputModalities: value.inputModalities,
99
98
  supportedReasoningEfforts: readReasoningEfforts(value.supportedReasoningEfforts),
100
- ...readNonEmptyString(value.defaultReasoningEffort) ? { defaultReasoningEffort: readNonEmptyString(value.defaultReasoningEffort) } : {}
99
+ ...normalizeOptionalString(value.defaultReasoningEffort) ? { defaultReasoningEffort: normalizeOptionalString(value.defaultReasoningEffort) } : {}
101
100
  };
102
101
  }
103
102
  function readReasoningEfforts(value) {
104
- return uniqueStrings(value.map((entry) => readNonEmptyString(entry.reasoningEffort)).filter((entry) => entry !== void 0));
105
- }
106
- function readNonEmptyString(value) {
107
- if (typeof value !== "string") return;
108
- return value.trim() || void 0;
103
+ return uniqueStrings(value.map((entry) => normalizeOptionalString(entry.reasoningEffort)).filter((entry) => entry !== void 0));
109
104
  }
110
105
  function normalizeMaxPages(value) {
111
106
  return typeof value === "number" && Number.isFinite(value) && value > 0 ? Math.floor(value) : 20;