@openclaw/codex 2026.5.10-beta.2 → 2026.5.10-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.
@@ -1,4 +1,4 @@
1
- import { s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
1
+ import { s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
2
  import { n as isRpcResponse } from "./protocol-C9UWI98H.js";
3
3
  import { createInterface } from "node:readline";
4
4
  import { OPENCLAW_VERSION, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -1,5 +1,5 @@
1
1
  //#region extensions/codex/src/app-server/client-factory.ts
2
- const defaultCodexAppServerClientFactory = (startOptions, authProfileId, agentDir, config) => import("./shared-client-p-TvEiNL.js").then((n) => n.r).then(({ getSharedCodexAppServerClient }) => getSharedCodexAppServerClient({
2
+ const defaultCodexAppServerClientFactory = (startOptions, authProfileId, agentDir, config) => import("./shared-client-BRX9tReb.js").then((n) => n.r).then(({ getSharedCodexAppServerClient }) => getSharedCodexAppServerClient({
3
3
  startOptions,
4
4
  authProfileId,
5
5
  agentDir,
@@ -1,10 +1,10 @@
1
- import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
2
- import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-H-PTi3W0.js";
1
+ import { i as isCodexFastServiceTier, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
+ import { n as listCodexAppServerModels, t as listAllCodexAppServerModels } from "./models-lvthKXfT.js";
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
- import { a as formatCodexStatus, c as formatModels, f as CODEX_CONTROL_METHODS, i as formatCodexDisplayText, l as formatThreads, n as buildHelp, o as formatComputerUseStatus, p as describeControlFailure, r as formatAccount, s as formatList, t as requestCodexAppServerJson, u as readString } from "./request-DC1Dz3iZ.js";
5
- import { i as readCodexAppServerBinding, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-B44KIZM2.js";
6
- import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-FqeYliIk.js";
7
- import { a as readCodexComputerUseStatus, i as installCodexComputerUse, n as rememberCodexRateLimits } from "./rate-limit-cache-DbZvmrAD.js";
4
+ import { a as formatCodexStatus, c as formatModels, i as formatCodexDisplayText, l as formatThreads, m as describeControlFailure, n as buildHelp, o as formatComputerUseStatus, p as CODEX_CONTROL_METHODS, r as formatAccount, s as formatList, t as requestCodexAppServerJson, u as readString } from "./request-Bj4IRDU9.js";
5
+ import { i as readCodexAppServerBinding, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-BAaJ-7s-.js";
6
+ import { a as parseCodexFastModeArg, c as setCodexConversationFastMode, d as steerCodexConversationTurn, f as stopCodexConversationTurn, i as formatPermissionsMode, l as setCodexConversationModel, m as resolveCodexDefaultWorkspaceDir, o as parseCodexPermissionsModeArg, p as readCodexConversationBindingData, r as startCodexConversationThread, s as readCodexConversationActiveTurn, u as setCodexConversationPermissions } from "./conversation-binding-zeuTIuN2.js";
7
+ import { a as readCodexComputerUseStatus, i as installCodexComputerUse, n as rememberCodexRateLimits } from "./rate-limit-cache-BFTJlMhx.js";
8
8
  import crypto from "node:crypto";
9
9
  //#region extensions/codex/src/command-rpc.ts
10
10
  function requestOptions(pluginConfig, limit, config) {
@@ -318,9 +318,9 @@ async function handleCodexDiagnosticsFeedback(deps, ctx, pluginConfig, args, com
318
318
  if (parsed.action === "cancel") return { text: cancelCodexDiagnosticsFeedback(ctx, parsed.token) };
319
319
  if (ctx.diagnosticsUploadApproved === true) return { text: await sendCodexDiagnosticsFeedbackForContext(deps, ctx, pluginConfig, parsed.note) };
320
320
  if (ctx.diagnosticsPreviewOnly === true) return { text: await previewCodexDiagnosticsFeedbackApproval(deps, ctx, parsed.note) };
321
- return await requestCodexDiagnosticsFeedbackApproval(deps, ctx, pluginConfig, parsed.note, commandPrefix);
321
+ return await requestCodexDiagnosticsFeedbackApproval(deps, ctx, parsed.note, commandPrefix);
322
322
  }
323
- async function requestCodexDiagnosticsFeedbackApproval(deps, ctx, pluginConfig, note, commandPrefix) {
323
+ async function requestCodexDiagnosticsFeedbackApproval(deps, ctx, note, commandPrefix) {
324
324
  if (!await hasAnyCodexDiagnosticsSessionFile(ctx)) return { text: "Cannot send Codex diagnostics because this command did not include an OpenClaw session file." };
325
325
  const targets = await resolveCodexDiagnosticsTargets(deps, ctx);
326
326
  if (targets.length === 0) return { text: ["No Codex thread is attached to this OpenClaw session yet.", "Use /codex threads to find a thread, then /codex resume <thread-id> before sending diagnostics."].join("\n") };
@@ -1,7 +1,7 @@
1
- import { s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
1
+ import { s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
- import { i as readCodexAppServerBinding } from "./session-binding-B44KIZM2.js";
4
- import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-BJL_efz4.js";
3
+ import { i as readCodexAppServerBinding } from "./session-binding-BAaJ-7s-.js";
4
+ import { n as defaultCodexAppServerClientFactory, t as createCodexAppServerClientFactoryTestHooks } from "./client-factory-BHbKz0nI.js";
5
5
  import { embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine, runHarnessContextEngineMaintenance } from "openclaw/plugin-sdk/agent-harness-runtime";
6
6
  //#region extensions/codex/src/app-server/compact.ts
7
7
  const DEFAULT_CODEX_COMPACTION_WAIT_TIMEOUT_MS = 300 * 1e3;
@@ -1,7 +1,7 @@
1
1
  import { createHmac, randomBytes } from "node:crypto";
2
2
  import { readFileSync } from "node:fs";
3
3
  import { hostname } from "node:os";
4
- import { z } from "openclaw/plugin-sdk/zod";
4
+ import { z } from "zod";
5
5
  //#region extensions/codex/src/app-server/config.ts
6
6
  const START_OPTIONS_KEY_SECRET = randomBytes(32);
7
7
  const UNIX_CODEX_REQUIREMENTS_PATH = "/etc/codex/requirements.toml";
@@ -1,8 +1,8 @@
1
- import { i as isCodexFastServiceTier, r as codexSandboxPolicyForTurn, s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
1
+ import { i as isCodexFastServiceTier, r as codexSandboxPolicyForTurn, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
2
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
3
- import { f as CODEX_CONTROL_METHODS, i as formatCodexDisplayText } from "./request-DC1Dz3iZ.js";
4
- import { c as resolveCodexAppServerAuthProfileIdForAgent, n as getSharedCodexAppServerClient } from "./shared-client-p-TvEiNL.js";
5
- import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, r as normalizeCodexAppServerBindingModelProvider, t as clearCodexAppServerBinding } from "./session-binding-B44KIZM2.js";
3
+ import { i as formatCodexDisplayText, p as CODEX_CONTROL_METHODS } from "./request-Bj4IRDU9.js";
4
+ import { c as resolveCodexAppServerAuthProfileIdForAgent, n as getSharedCodexAppServerClient } from "./shared-client-BRX9tReb.js";
5
+ import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, r as normalizeCodexAppServerBindingModelProvider, t as clearCodexAppServerBinding } from "./session-binding-BAaJ-7s-.js";
6
6
  import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
7
7
  import path from "node:path";
8
8
  import { fileURLToPath } from "node:url";
package/dist/harness.js CHANGED
@@ -18,21 +18,21 @@ function createCodexAppServerAgentHarness(options) {
18
18
  };
19
19
  },
20
20
  runAttempt: async (params) => {
21
- const { runCodexAppServerAttempt } = await import("./run-attempt-CefRS5_d.js");
21
+ const { runCodexAppServerAttempt } = await import("./run-attempt-COMElKgN.js");
22
22
  return runCodexAppServerAttempt(params, { pluginConfig: options?.pluginConfig });
23
23
  },
24
24
  compact: async (params) => {
25
- const { maybeCompactCodexAppServerSession } = await import("./compact-4FVe6NwI.js");
25
+ const { maybeCompactCodexAppServerSession } = await import("./compact-CMIpm-H_.js");
26
26
  return maybeCompactCodexAppServerSession(params, { pluginConfig: options?.pluginConfig });
27
27
  },
28
28
  reset: async (params) => {
29
29
  if (params.sessionFile) {
30
- const { clearCodexAppServerBinding } = await import("./session-binding-B44KIZM2.js").then((n) => n.a);
30
+ const { clearCodexAppServerBinding } = await import("./session-binding-BAaJ-7s-.js").then((n) => n.a);
31
31
  await clearCodexAppServerBinding(params.sessionFile);
32
32
  }
33
33
  },
34
34
  dispose: async () => {
35
- const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-p-TvEiNL.js").then((n) => n.r);
35
+ const { clearSharedCodexAppServerClientAndWait } = await import("./shared-client-BRX9tReb.js").then((n) => n.r);
36
36
  await clearSharedCodexAppServerClientAndWait();
37
37
  }
38
38
  };
package/dist/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { createCodexAppServerAgentHarness } from "./harness.js";
2
- import { t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-CT01BBDc.js";
2
+ import { t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-C7xdbzrp.js";
3
3
  import { buildCodexMediaUnderstandingProvider } from "./media-understanding-provider.js";
4
4
  import { buildCodexProvider } from "./provider.js";
5
- import { i as formatCodexDisplayText, p as describeControlFailure, t as requestCodexAppServerJson } from "./request-DC1Dz3iZ.js";
6
- import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-FqeYliIk.js";
7
- import { i as defaultCodexAppInventoryCache, t as ensureCodexPluginActivation } from "./plugin-activation-CweAZa7r.js";
5
+ import { i as formatCodexDisplayText, m as describeControlFailure, t as requestCodexAppServerJson } from "./request-Bj4IRDU9.js";
6
+ import { n as handleCodexConversationInboundClaim, t as handleCodexConversationBindingResolved } from "./conversation-binding-zeuTIuN2.js";
7
+ import { i as defaultCodexAppInventoryCache, t as ensureCodexPluginActivation } from "./plugin-activation-Dn14PX1W.js";
8
8
  import { resolveLivePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
9
9
  import { definePluginEntry } from "openclaw/plugin-sdk/plugin-entry";
10
10
  import os from "node:os";
@@ -28,13 +28,17 @@ function createCodexCommand(options) {
28
28
  };
29
29
  }
30
30
  async function handleCodexCommand(ctx, options = {}) {
31
- const { handleCodexSubcommand } = await import("./command-handlers-BLZCm3fD.js");
31
+ const { loadSubcommandHandler, ...subcommandOptions } = options;
32
32
  try {
33
- return await handleCodexSubcommand(ctx, options);
33
+ return await (loadSubcommandHandler ? await loadSubcommandHandler() : await loadDefaultCodexSubcommandHandler())(ctx, subcommandOptions);
34
34
  } catch (error) {
35
35
  return { text: `Codex command failed: ${formatCodexDisplayText(describeControlFailure(error))}` };
36
36
  }
37
37
  }
38
+ async function loadDefaultCodexSubcommandHandler() {
39
+ const { handleCodexSubcommand } = await import("./command-handlers-BPaLMsgL.js");
40
+ return handleCodexSubcommand;
41
+ }
38
42
  //#endregion
39
43
  //#region extensions/codex/src/migration/helpers.ts
40
44
  async function exists(filePath) {
@@ -1,8 +1,9 @@
1
1
  import { CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS } from "./provider-catalog.js";
2
- import { s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
2
+ import { s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
3
3
  import { a as readCodexErrorNotification, c as readCodexTurnCompletedNotification, n as assertCodexThreadStartResponse, r as assertCodexTurnStartResponse } from "./protocol-validators-CeCyJaWj.js";
4
- import { i as readModelListResult } from "./models-H-PTi3W0.js";
4
+ import { i as readModelListResult } from "./models-lvthKXfT.js";
5
5
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
6
+ import { validateJsonSchemaValue } from "openclaw/plugin-sdk/json-schema-runtime";
6
7
  //#region extensions/codex/media-understanding-provider.ts
7
8
  const DEFAULT_CODEX_IMAGE_MODEL = FALLBACK_CODEX_MODELS.find((model) => model.inputModalities.includes("image"))?.id ?? FALLBACK_CODEX_MODELS[0]?.id;
8
9
  const DEFAULT_CODEX_IMAGE_PROMPT = "Describe the image.";
@@ -28,38 +29,63 @@ function buildCodexMediaUnderstandingProvider(options = {}) {
28
29
  agentDir: req.agentDir,
29
30
  cfg: req.cfg
30
31
  }, options),
31
- describeImages: async (req) => describeCodexImages(req, options)
32
+ describeImages: async (req) => describeCodexImages(req, options),
33
+ extractStructured: async (req) => extractCodexStructured(req, options)
32
34
  };
33
35
  }
34
36
  async function describeCodexImages(req, options) {
35
37
  const model = req.model.trim();
36
38
  if (!model) throw new Error("Codex image understanding requires model id.");
37
- const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: options.pluginConfig });
38
- const timeoutMs = Math.max(100, req.timeoutMs);
39
- const ownsClient = !options.clientFactory;
40
- const client = options.clientFactory ? await options.clientFactory(appServer.start, req.profile) : await import("./shared-client-p-TvEiNL.js").then((n) => n.r).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
39
+ return {
40
+ text: await runBoundedCodexVisionTurn({
41
+ model,
42
+ profile: req.profile,
43
+ timeoutMs: req.timeoutMs,
44
+ agentDir: req.agentDir,
45
+ options,
46
+ taskLabel: "image understanding",
47
+ developerInstructions: "You are OpenClaw's bounded image-understanding worker. Describe only the provided image content. Do not call tools, edit files, or ask follow-up questions.",
48
+ input: [{
49
+ type: "text",
50
+ text: buildCodexImagePrompt(req),
51
+ text_elements: []
52
+ }, ...req.images.map((image) => ({
53
+ type: "image",
54
+ url: `data:${image.mime ?? "image/png"};base64,${image.buffer.toString("base64")}`
55
+ }))],
56
+ requiredModalities: ["text", "image"]
57
+ }),
58
+ model
59
+ };
60
+ }
61
+ async function runBoundedCodexVisionTurn(params) {
62
+ const appServer = resolveCodexAppServerRuntimeOptions({ pluginConfig: params.options.pluginConfig });
63
+ const timeoutMs = Math.max(100, params.timeoutMs);
64
+ const ownsClient = !params.options.clientFactory;
65
+ const client = params.options.clientFactory ? await params.options.clientFactory(appServer.start, params.profile) : await import("./shared-client-BRX9tReb.js").then((n) => n.r).then(({ createIsolatedCodexAppServerClient }) => createIsolatedCodexAppServerClient({
41
66
  startOptions: appServer.start,
42
67
  timeoutMs,
43
- authProfileId: req.profile
68
+ authProfileId: params.profile
44
69
  }));
45
70
  const abortController = new AbortController();
46
71
  const timeout = setTimeout(() => abortController.abort("timeout"), timeoutMs);
47
72
  timeout.unref?.();
48
73
  try {
49
- await assertCodexModelSupportsImage({
74
+ await assertCodexModelSupportsInput({
50
75
  client,
51
- model,
76
+ model: params.model,
77
+ requiredModalities: params.requiredModalities,
52
78
  timeoutMs,
53
79
  signal: abortController.signal
54
80
  });
55
81
  const thread = assertCodexThreadStartResponse(await client.request("thread/start", {
56
- model,
82
+ model: params.model,
57
83
  modelProvider: "openai",
58
- cwd: req.agentDir || process.cwd(),
84
+ cwd: params.agentDir || process.cwd(),
59
85
  approvalPolicy: "on-request",
60
86
  sandbox: "read-only",
61
87
  serviceName: "OpenClaw",
62
- developerInstructions: "You are OpenClaw's bounded image-understanding worker. Describe only the provided image content. Do not call tools, edit files, or ask follow-up questions.",
88
+ developerInstructions: params.developerInstructions,
63
89
  dynamicTools: [],
64
90
  experimentalRawEvents: true,
65
91
  persistExtendedHistory: false,
@@ -68,35 +94,25 @@ async function describeCodexImages(req, options) {
68
94
  timeoutMs,
69
95
  signal: abortController.signal
70
96
  }));
71
- const collector = createCodexImageTurnCollector(thread.thread.id);
97
+ const collector = createCodexTurnCollector(thread.thread.id, params.taskLabel);
72
98
  const cleanup = client.addNotificationHandler(collector.handleNotification);
73
99
  const requestCleanup = client.addRequestHandler(denyCodexImageApprovalRequest);
74
100
  try {
75
101
  const turn = assertCodexTurnStartResponse(await client.request("turn/start", {
76
102
  threadId: thread.thread.id,
77
- input: [{
78
- type: "text",
79
- text: buildCodexImagePrompt(req),
80
- text_elements: []
81
- }, ...req.images.map((image) => ({
82
- type: "image",
83
- url: `data:${image.mime ?? "image/png"};base64,${image.buffer.toString("base64")}`
84
- }))],
85
- cwd: req.agentDir || process.cwd(),
103
+ input: params.input,
104
+ cwd: params.agentDir || process.cwd(),
86
105
  approvalPolicy: "on-request",
87
- model,
106
+ model: params.model,
88
107
  effort: "low"
89
108
  }, {
90
109
  timeoutMs,
91
110
  signal: abortController.signal
92
111
  }));
93
- return {
94
- text: await collector.collect(turn.turn, {
95
- timeoutMs,
96
- signal: abortController.signal
97
- }),
98
- model
99
- };
112
+ return await collector.collect(turn.turn, {
113
+ timeoutMs,
114
+ signal: abortController.signal
115
+ });
100
116
  } finally {
101
117
  requestCleanup();
102
118
  cleanup();
@@ -106,6 +122,29 @@ async function describeCodexImages(req, options) {
106
122
  if (ownsClient) client.close();
107
123
  }
108
124
  }
125
+ async function extractCodexStructured(req, options) {
126
+ const model = req.model.trim();
127
+ if (!model) throw new Error("Codex structured extraction requires model id.");
128
+ if (!req.instructions.trim()) throw new Error("Codex structured extraction requires instructions.");
129
+ if (req.input.length === 0) throw new Error("Codex structured extraction requires at least one input.");
130
+ if (!req.input.some((entry) => entry.type === "image")) throw new Error("Codex structured extraction requires at least one image input.");
131
+ return normalizeStructuredExtractionResult({
132
+ text: await runBoundedCodexVisionTurn({
133
+ model,
134
+ profile: req.profile,
135
+ timeoutMs: req.timeoutMs,
136
+ agentDir: req.agentDir,
137
+ options,
138
+ taskLabel: "structured extraction",
139
+ developerInstructions: "You are OpenClaw's bounded structured-extraction worker. Return only the requested extraction. Do not call tools, edit files, ask follow-up questions, or include secrets.",
140
+ input: buildCodexStructuredInput(req),
141
+ requiredModalities: requiredStructuredModalities()
142
+ }),
143
+ model,
144
+ provider: req.provider,
145
+ req
146
+ });
147
+ }
109
148
  function denyCodexImageApprovalRequest(request) {
110
149
  if (request.method === "item/commandExecution/requestApproval" || request.method === "item/fileChange/requestApproval") return {
111
150
  decision: "decline",
@@ -121,7 +160,7 @@ function denyCodexImageApprovalRequest(request) {
121
160
  };
122
161
  if (request.method === "mcpServer/elicitation/request") return { action: "decline" };
123
162
  }
124
- async function assertCodexModelSupportsImage(params) {
163
+ async function assertCodexModelSupportsInput(params) {
125
164
  const match = readModelListResult(await params.client.request("model/list", {
126
165
  limit: 100,
127
166
  cursor: null,
@@ -131,14 +170,75 @@ async function assertCodexModelSupportsImage(params) {
131
170
  signal: params.signal
132
171
  })).models.find((entry) => entry.model === params.model || entry.id === params.model);
133
172
  if (!match) throw new Error(`Codex app-server model not found: ${params.model}`);
134
- if (!match.inputModalities.includes("image")) throw new Error(`Codex app-server model does not support images: ${params.model}`);
173
+ if (params.requiredModalities.includes("image") && !match.inputModalities.includes("image")) throw new Error(`Codex app-server model does not support images: ${params.model}`);
174
+ if (params.requiredModalities.includes("text") && !match.inputModalities.includes("text")) throw new Error(`Codex app-server model does not support text: ${params.model}`);
135
175
  }
136
176
  function buildCodexImagePrompt(req) {
137
177
  const prompt = req.prompt?.trim() || DEFAULT_CODEX_IMAGE_PROMPT;
138
178
  if (req.images.length <= 1) return prompt;
139
179
  return `${prompt}\n\nAnalyze all ${req.images.length} images together.`;
140
180
  }
141
- function createCodexImageTurnCollector(threadId) {
181
+ function requiredStructuredModalities() {
182
+ return ["text", "image"];
183
+ }
184
+ function buildCodexStructuredInput(req) {
185
+ return [{
186
+ type: "text",
187
+ text: buildStructuredExtractionPrompt(req),
188
+ text_elements: []
189
+ }, ...req.input.map((entry) => {
190
+ if (entry.type === "text") return {
191
+ type: "text",
192
+ text: entry.text,
193
+ text_elements: []
194
+ };
195
+ return {
196
+ type: "image",
197
+ url: `data:${entry.mime ?? "image/png"};base64,${entry.buffer.toString("base64")}`
198
+ };
199
+ })];
200
+ }
201
+ function buildStructuredExtractionPrompt(req) {
202
+ return [
203
+ req.instructions.trim(),
204
+ req.schemaName ? `Schema name: ${req.schemaName}` : void 0,
205
+ req.jsonSchema ? `JSON schema:\n${JSON.stringify(req.jsonSchema)}` : void 0,
206
+ req.jsonMode === false ? "Return the extraction as concise text." : "Return valid JSON only. Do not wrap the JSON in Markdown fences."
207
+ ].filter((part) => Boolean(part)).join("\n\n");
208
+ }
209
+ function isJsonSchemaObject(value) {
210
+ return typeof value === "object" && value !== null && !Array.isArray(value);
211
+ }
212
+ function normalizeStructuredExtractionResult(params) {
213
+ const result = {
214
+ text: params.text,
215
+ model: params.model,
216
+ provider: params.provider,
217
+ contentType: params.req.jsonMode === false ? "text" : "json"
218
+ };
219
+ if (params.req.jsonMode !== false) {
220
+ try {
221
+ result.parsed = JSON.parse(params.text);
222
+ } catch {
223
+ throw new Error("Codex structured extraction returned invalid JSON.");
224
+ }
225
+ if (isJsonSchemaObject(params.req.jsonSchema)) {
226
+ const validation = validateJsonSchemaValue({
227
+ schema: params.req.jsonSchema,
228
+ cacheKey: "codex.media-understanding.extractStructured",
229
+ value: result.parsed,
230
+ cache: false
231
+ });
232
+ if (!validation.ok) {
233
+ const message = validation.errors.map((error) => error.text).join("; ") || "invalid";
234
+ throw new Error(`Codex structured extraction JSON did not match schema: ${message}`);
235
+ }
236
+ result.parsed = validation.value;
237
+ }
238
+ }
239
+ return result;
240
+ }
241
+ function createCodexTurnCollector(threadId, taskLabel) {
142
242
  let turnId;
143
243
  let completedTurn;
144
244
  let promptError;
@@ -174,7 +274,7 @@ function createCodexImageTurnCollector(threadId) {
174
274
  return;
175
275
  }
176
276
  if (notification.method === "error") {
177
- promptError = readCodexErrorNotification(notification.params)?.error.message ?? "codex app-server image turn failed";
277
+ promptError = readCodexErrorNotification(notification.params)?.error.message ?? `codex app-server ${taskLabel} turn failed`;
178
278
  resolveCompletion?.();
179
279
  }
180
280
  };
@@ -187,14 +287,15 @@ function createCodexImageTurnCollector(threadId) {
187
287
  if (!completedTurn && !promptError) await waitForTurnCompletion({
188
288
  completion,
189
289
  timeoutMs: options.timeoutMs,
190
- signal: options.signal
290
+ signal: options.signal,
291
+ taskLabel
191
292
  });
192
293
  if (promptError) throw new Error(promptError);
193
- if (completedTurn?.status === "failed") throw new Error(completedTurn.error?.message ?? "codex app-server image turn failed");
294
+ if (completedTurn?.status === "failed") throw new Error(completedTurn.error?.message ?? `codex app-server ${taskLabel} turn failed`);
194
295
  const itemText = collectAssistantTextFromItems(completedTurn?.items);
195
296
  const deltaText = assistantItemOrder.map((itemId) => assistantTextByItem.get(itemId)?.trim()).filter((text) => Boolean(text)).join("\n\n").trim();
196
297
  const text = (itemText || deltaText).trim();
197
- if (!text) throw new Error("Codex app-server image turn returned no text.");
298
+ if (!text) throw new Error(`Codex app-server ${taskLabel} turn returned no text.`);
198
299
  return text;
199
300
  }
200
301
  };
@@ -204,9 +305,9 @@ async function waitForTurnCompletion(params) {
204
305
  let cleanupAbort;
205
306
  try {
206
307
  await Promise.race([params.completion, new Promise((_, reject) => {
207
- timeout = setTimeout(() => reject(/* @__PURE__ */ new Error("codex app-server image turn timed out")), params.timeoutMs);
308
+ timeout = setTimeout(() => reject(/* @__PURE__ */ new Error(`codex app-server ${params.taskLabel} turn timed out`)), params.timeoutMs);
208
309
  timeout.unref?.();
209
- const abortListener = () => reject(/* @__PURE__ */ new Error("codex app-server image turn aborted"));
310
+ const abortListener = () => reject(/* @__PURE__ */ new Error(`codex app-server ${params.taskLabel} turn aborted`));
210
311
  params.signal.addEventListener("abort", abortListener, { once: true });
211
312
  cleanupAbort = () => params.signal.removeEventListener("abort", abortListener);
212
313
  })]);
@@ -39,7 +39,7 @@ async function listAllCodexAppServerModels(options = {}) {
39
39
  async function withCodexAppServerModelClient(options, run) {
40
40
  const timeoutMs = options.timeoutMs ?? 2500;
41
41
  const useSharedClient = options.sharedClient !== false;
42
- const { createIsolatedCodexAppServerClient, getSharedCodexAppServerClient } = await import("./shared-client-p-TvEiNL.js").then((n) => n.r);
42
+ const { createIsolatedCodexAppServerClient, getSharedCodexAppServerClient } = await import("./shared-client-BRX9tReb.js").then((n) => n.r);
43
43
  const client = useSharedClient ? await getSharedCodexAppServerClient({
44
44
  startOptions: options.startOptions,
45
45
  timeoutMs,
@@ -1,4 +1,4 @@
1
- import { l as resolveCodexPluginsPolicy, t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-CT01BBDc.js";
1
+ import { l as resolveCodexPluginsPolicy, t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-C7xdbzrp.js";
2
2
  import "node:fs/promises";
3
3
  import "node:path";
4
4
  var CodexAppInventoryCache = class {
package/dist/provider.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { CODEX_APP_SERVER_AUTH_MARKER, CODEX_BASE_URL, CODEX_PROVIDER_ID, FALLBACK_CODEX_MODELS, buildCodexModelDefinition, buildCodexProviderConfig } from "./provider-catalog.js";
2
- import { o as readCodexPluginConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
2
+ import { o as readCodexPluginConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
3
3
  import { resolveCodexSystemPromptContribution } from "./prompt-overlay.js";
4
4
  import { resolvePluginConfigObject } from "openclaw/plugin-sdk/plugin-config-runtime";
5
5
  import { createSubsystemLogger } from "openclaw/plugin-sdk/core";
@@ -123,7 +123,7 @@ async function listModelsBestEffort(params) {
123
123
  }
124
124
  }
125
125
  async function listCodexAppServerModelsLazy(options) {
126
- const { listCodexAppServerModels } = await import("./models-H-PTi3W0.js").then((n) => n.r);
126
+ const { listCodexAppServerModels } = await import("./models-lvthKXfT.js").then((n) => n.r);
127
127
  return listCodexAppServerModels(options);
128
128
  }
129
129
  function normalizeTimeoutMs(value) {
@@ -1,5 +1,5 @@
1
- import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-CT01BBDc.js";
2
- import { p as describeControlFailure, t as requestCodexAppServerJson } from "./request-DC1Dz3iZ.js";
1
+ import { c as resolveCodexComputerUseConfig, s as resolveCodexAppServerRuntimeOptions } from "./config-C7xdbzrp.js";
2
+ import { m as describeControlFailure, t as requestCodexAppServerJson } from "./request-Bj4IRDU9.js";
3
3
  import { existsSync } from "node:fs";
4
4
  //#region extensions/codex/src/app-server/computer-use.ts
5
5
  var CodexComputerUseSetupError = class extends Error {