@openclaw/codex 2026.5.28 → 2026.5.31-beta.1

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 (28) hide show
  1. package/dist/{client-DMXvboVu.js → client-BnOmn0y-.js} +20 -6
  2. package/dist/client-factory-B8dh39UW.js +20 -0
  3. package/dist/{command-handlers-C2t6-ChO.js → command-handlers-BsK6kZJi.js} +265 -16
  4. package/dist/{compact-Dlnt5G3v.js → compact-BXLjhUHX.js} +4 -4
  5. package/dist/{computer-use-Ba4vW9fO.js → computer-use-D-0EFJBJ.js} +3 -4
  6. package/dist/{config--tW89bHH.js → config-AlzuNKCY.js} +14 -5
  7. package/dist/{conversation-binding-CC9XMAwn.js → conversation-binding-KUDxop-C.js} +69 -92
  8. package/dist/doctor-contract-api.js +1 -1
  9. package/dist/harness.js +6 -10
  10. package/dist/index.js +23 -60
  11. package/dist/media-understanding-provider.js +8 -9
  12. package/dist/{models-QT-XOhE7.js → models-mbjSisZL.js} +2 -2
  13. package/dist/{native-hook-relay-B8qM8ZwR.js → native-hook-relay-DCxPRaBN.js} +77 -9
  14. package/dist/{notification-correlation-BDakP_d3.js → notification-correlation-BykOI_jh.js} +3 -3
  15. package/dist/{protocol-validators-DtjYmUw_.js → protocol-validators-DIt7cXIp.js} +2 -2
  16. package/dist/provider-catalog.js +2 -2
  17. package/dist/provider.js +2 -2
  18. package/dist/{request-CF4f5hWY.js → request-DuFgTwRU.js} +4 -4
  19. package/dist/{run-attempt-CuhGEh0u.js → run-attempt-CgaY9r5u.js} +579 -288
  20. package/dist/{sandbox-guard-mXE4_vE_.js → sandbox-guard-DMCJlzmz.js} +4 -1
  21. package/dist/{session-binding-ueMCn4om.js → session-binding-BXJAV_xy.js} +27 -10
  22. package/dist/{shared-client-Duh1bHaP.js → shared-client-DBlR-rV2.js} +33 -4
  23. package/dist/{side-question-B-Cjb9wm.js → side-question-SjBLGANT.js} +10 -10
  24. package/dist/{thread-lifecycle-Dv9Npl7a.js → thread-lifecycle-Bnlv_Q8u.js} +78 -120
  25. package/npm-shrinkwrap.json +34 -34
  26. package/openclaw.plugin.json +5 -4
  27. package/package.json +6 -6
  28. package/dist/client-factory-qZvhyyXr.js +0 -15
@@ -92,7 +92,10 @@ function resolveEffectiveExecHost(params) {
92
92
  }
93
93
  function readRuntimeSessionEntryBestEffort(sessionKey) {
94
94
  try {
95
- return getSessionEntry({ sessionKey });
95
+ return getSessionEntry({
96
+ sessionKey,
97
+ hydrateSkillPromptRefs: false
98
+ });
96
99
  } catch {
97
100
  return;
98
101
  }
@@ -1,18 +1,19 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { s as normalizeCodexServiceTier } from "./config--tW89bHH.js";
2
+ import { l as normalizeCodexServiceTier, s as isCodexPluginsMarketplaceName } from "./config-AlzuNKCY.js";
3
3
  import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
4
4
  import fs from "node:fs/promises";
5
5
  import { ensureAuthProfileStore, resolveDefaultAgentDir, resolveProviderIdForAuth } from "openclaw/plugin-sdk/agent-runtime";
6
6
  //#region extensions/codex/src/app-server/session-binding.ts
7
7
  var session_binding_exports = /* @__PURE__ */ __exportAll({
8
8
  clearCodexAppServerBinding: () => clearCodexAppServerBinding,
9
+ clearCodexAppServerBindingForThread: () => clearCodexAppServerBindingForThread,
9
10
  isCodexAppServerNativeAuthProfile: () => isCodexAppServerNativeAuthProfile,
10
11
  normalizeCodexAppServerBindingModelProvider: () => normalizeCodexAppServerBindingModelProvider,
11
12
  readCodexAppServerBinding: () => readCodexAppServerBinding,
12
13
  resolveCodexAppServerBindingPath: () => resolveCodexAppServerBindingPath,
13
14
  writeCodexAppServerBinding: () => writeCodexAppServerBinding
14
15
  });
15
- const CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER = "openai-codex";
16
+ const CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER = "openai";
16
17
  const PUBLIC_OPENAI_MODEL_PROVIDER = "openai";
17
18
  function resolveCodexAppServerBindingPath(sessionFile) {
18
19
  return `${sessionFile}.codex-app-server.json`;
@@ -132,7 +133,7 @@ function readPluginAppPolicyContext(value) {
132
133
  for (const [appId, rawEntry] of Object.entries(apps)) {
133
134
  if (!rawEntry || typeof rawEntry !== "object" || Array.isArray(rawEntry)) return;
134
135
  const entry = rawEntry;
135
- if ("appId" in entry || typeof entry.configKey !== "string" || entry.marketplaceName !== "openai-curated" || typeof entry.pluginName !== "string" || typeof entry.allowDestructiveActions !== "boolean" || !Array.isArray(entry.mcpServerNames) || entry.mcpServerNames.some((serverName) => typeof serverName !== "string")) return;
136
+ if ("appId" in entry || typeof entry.configKey !== "string" || typeof entry.marketplaceName !== "string" || !isCodexPluginsMarketplaceName(entry.marketplaceName) || typeof entry.pluginName !== "string" || typeof entry.allowDestructiveActions !== "boolean" || !Array.isArray(entry.mcpServerNames) || entry.mcpServerNames.some((serverName) => typeof serverName !== "string")) return;
136
137
  parsedApps[appId] = {
137
138
  configKey: entry.configKey,
138
139
  marketplaceName: entry.marketplaceName,
@@ -164,6 +165,20 @@ async function clearCodexAppServerBinding(sessionFile, _lookup = {}) {
164
165
  });
165
166
  }
166
167
  }
168
+ async function clearCodexAppServerBindingForThread(sessionFile, threadId, lookup = {}) {
169
+ const binding = await readCodexAppServerBinding(sessionFile, lookup);
170
+ if (!binding) return false;
171
+ if (binding.threadId !== threadId) {
172
+ embeddedAgentLog.debug("codex app-server binding points at a different thread; preserving", {
173
+ sessionFile,
174
+ threadId,
175
+ boundThreadId: binding.threadId
176
+ });
177
+ return false;
178
+ }
179
+ await clearCodexAppServerBinding(sessionFile);
180
+ return true;
181
+ }
167
182
  function isNotFound(error) {
168
183
  return Boolean(error && typeof error === "object" && "code" in error && error.code === "ENOENT");
169
184
  }
@@ -171,11 +186,13 @@ function isCodexAppServerNativeAuthProfile(lookup) {
171
186
  const authProfileId = lookup.authProfileId?.trim();
172
187
  if (!authProfileId) return false;
173
188
  try {
174
- return isCodexAppServerNativeAuthProvider({
175
- provider: resolveCodexAppServerAuthProfileCredential({
176
- ...lookup,
177
- authProfileId
178
- })?.provider,
189
+ const credential = resolveCodexAppServerAuthProfileCredential({
190
+ ...lookup,
191
+ authProfileId
192
+ });
193
+ if (!credential || credential.type === "api_key") return false;
194
+ return isOpenAiAuthProvider({
195
+ provider: credential.provider,
179
196
  config: lookup.config
180
197
  });
181
198
  } catch (error) {
@@ -209,7 +226,7 @@ function loadCodexAppServerAuthProfileStore(params) {
209
226
  externalCliProfileIds: [params.authProfileId]
210
227
  });
211
228
  }
212
- function isCodexAppServerNativeAuthProvider(params) {
229
+ function isOpenAiAuthProvider(params) {
213
230
  const provider = params.provider?.trim();
214
231
  return Boolean(provider && resolveProviderIdForAuth(provider, { config: params.config }) === CODEX_APP_SERVER_NATIVE_AUTH_PROVIDER);
215
232
  }
@@ -223,4 +240,4 @@ function readServiceTier(value) {
223
240
  return normalizeCodexServiceTier(value);
224
241
  }
225
242
  //#endregion
226
- export { session_binding_exports as a, readCodexAppServerBinding as i, isCodexAppServerNativeAuthProfile as n, writeCodexAppServerBinding as o, normalizeCodexAppServerBindingModelProvider as r, clearCodexAppServerBinding as t };
243
+ export { readCodexAppServerBinding as a, normalizeCodexAppServerBindingModelProvider as i, clearCodexAppServerBindingForThread as n, session_binding_exports as o, isCodexAppServerNativeAuthProfile as r, writeCodexAppServerBinding as s, clearCodexAppServerBinding as t };
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
- import { l as resolveCodexAppServerRuntimeOptions, n as codexAppServerStartOptionsKey } from "./config--tW89bHH.js";
3
- import { c as resolveCodexAppServerSpawnEnv, o as MANAGED_CODEX_APP_SERVER_PACKAGE, t as CodexAppServerClient } from "./client-DMXvboVu.js";
2
+ import { d as resolveCodexAppServerRuntimeOptions, r as codexAppServerStartOptionsKey } from "./config-AlzuNKCY.js";
3
+ import { c as resolveCodexAppServerSpawnEnv, o as MANAGED_CODEX_APP_SERVER_PACKAGE, t as CodexAppServerClient } from "./client-BnOmn0y-.js";
4
4
  import { createRequire } from "node:module";
5
5
  import { createHash } from "node:crypto";
6
6
  import fsSync, { constants, readFileSync } from "node:fs";
@@ -11,9 +11,9 @@ import { ensureAuthProfileStore, ensureAuthProfileStoreWithoutExternalProfiles,
11
11
  import { fileURLToPath } from "node:url";
12
12
  import { withTimeout } from "openclaw/plugin-sdk/security-runtime";
13
13
  //#region extensions/codex/src/app-server/auth-bridge.ts
14
- const CODEX_APP_SERVER_AUTH_PROVIDER = "openai-codex";
14
+ const CODEX_APP_SERVER_AUTH_PROVIDER = "openai";
15
15
  const OPENAI_PROVIDER = "openai";
16
- const OPENAI_CODEX_DEFAULT_PROFILE_ID = "openai-codex:default";
16
+ const OPENAI_CODEX_DEFAULT_PROFILE_ID = "openai:default";
17
17
  const CODEX_HOME_ENV_VAR = "CODEX_HOME";
18
18
  const HOME_ENV_VAR = "HOME";
19
19
  const CODEX_APP_SERVER_HOME_DIRNAME = "codex-home";
@@ -546,13 +546,17 @@ async function withTimeout$1(promise, timeoutMs, timeoutMessage) {
546
546
  //#endregion
547
547
  //#region extensions/codex/src/app-server/shared-client.ts
548
548
  var shared_client_exports = /* @__PURE__ */ __exportAll({
549
+ clearSharedCodexAppServerClient: () => clearSharedCodexAppServerClient,
549
550
  clearSharedCodexAppServerClientAndWait: () => clearSharedCodexAppServerClientAndWait,
550
551
  clearSharedCodexAppServerClientIfCurrent: () => clearSharedCodexAppServerClientIfCurrent,
551
552
  clearSharedCodexAppServerClientIfCurrentAndWait: () => clearSharedCodexAppServerClientIfCurrentAndWait,
552
553
  createIsolatedCodexAppServerClient: () => createIsolatedCodexAppServerClient,
554
+ detachSharedCodexAppServerClientIfCurrent: () => detachSharedCodexAppServerClientIfCurrent,
553
555
  getLeasedSharedCodexAppServerClient: () => getLeasedSharedCodexAppServerClient,
554
556
  getSharedCodexAppServerClient: () => getSharedCodexAppServerClient,
555
557
  releaseLeasedSharedCodexAppServerClient: () => releaseLeasedSharedCodexAppServerClient,
558
+ resetSharedCodexAppServerClientForTests: () => resetSharedCodexAppServerClientForTests,
559
+ retainSharedCodexAppServerClientIfCurrent: () => retainSharedCodexAppServerClientIfCurrent,
556
560
  retireSharedCodexAppServerClientIfCurrent: () => retireSharedCodexAppServerClientIfCurrent
557
561
  });
558
562
  const SHARED_CODEX_APP_SERVER_CLIENT_STATE = Symbol.for("openclaw.codexAppServerClientState");
@@ -654,6 +658,7 @@ async function acquireSharedCodexAppServerClient(options, leaseOptions) {
654
658
  const sharedPromise = entry.promise ?? (entry.promise = (async () => {
655
659
  const client = CodexAppServerClient.start(startOptions);
656
660
  entry.client = client;
661
+ client.setActiveSharedLeaseCountProviderForUnscopedNotifications(() => entry.activeLeases);
657
662
  client.addCloseHandler((closedClient) => clearSharedClientEntryIfCurrent(key, closedClient));
658
663
  try {
659
664
  await client.initialize();
@@ -672,6 +677,7 @@ async function acquireSharedCodexAppServerClient(options, leaseOptions) {
672
677
  })());
673
678
  try {
674
679
  const client = await withTimeout$1(sharedPromise, options?.timeoutMs ?? 0, "codex app-server initialize timed out");
680
+ client.setActiveSharedLeaseCountProviderForUnscopedNotifications(() => entry.activeLeases);
675
681
  const release = leaseOptions?.leased ? retainSharedClientEntry(entry) : void 0;
676
682
  return release ? {
677
683
  client,
@@ -703,6 +709,15 @@ async function createIsolatedCodexAppServerClient(options) {
703
709
  throw error;
704
710
  }
705
711
  }
712
+ function resetSharedCodexAppServerClientForTests() {
713
+ getSharedCodexAppServerClientState().clients.clear();
714
+ }
715
+ function clearSharedCodexAppServerClient() {
716
+ const state = getSharedCodexAppServerClientState();
717
+ const clients = collectSharedClients(state);
718
+ state.clients.clear();
719
+ for (const client of clients) client.close();
720
+ }
706
721
  function clearSharedCodexAppServerClientIfCurrent(client) {
707
722
  if (!client) return false;
708
723
  const state = getSharedCodexAppServerClientState();
@@ -713,6 +728,20 @@ function clearSharedCodexAppServerClientIfCurrent(client) {
713
728
  }
714
729
  return false;
715
730
  }
731
+ function detachSharedCodexAppServerClientIfCurrent(client) {
732
+ if (!client) return false;
733
+ const state = getSharedCodexAppServerClientState();
734
+ for (const [key, entry] of state.clients) if (entry.client === client) {
735
+ state.clients.delete(key);
736
+ return true;
737
+ }
738
+ return false;
739
+ }
740
+ function retainSharedCodexAppServerClientIfCurrent(client) {
741
+ if (!client) return;
742
+ const state = getSharedCodexAppServerClientState();
743
+ for (const entry of state.clients.values()) if (entry.client === client) return retainSharedClientEntry(entry);
744
+ }
716
745
  function retireSharedCodexAppServerClientIfCurrent(client) {
717
746
  if (!client) return;
718
747
  const state = getSharedCodexAppServerClientState();
@@ -1,12 +1,12 @@
1
- import { c as readCodexPluginConfig, l as resolveCodexAppServerRuntimeOptions, p as shouldAutoApproveCodexAppServerApprovals } from "./config--tW89bHH.js";
2
- import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse, t as assertCodexThreadForkResponse } from "./protocol-validators-DtjYmUw_.js";
3
- import { i as isCodexAppServerApprovalRequest, l as isJsonObject } from "./client-DMXvboVu.js";
4
- import { d as resolveReasoningEffort, g as mergeCodexThreadConfigs, r as buildCodexRuntimeThreadConfig, t as CODEX_NATIVE_PERSONALITY_NONE, u as resolveCodexAppServerModelProvider } from "./thread-lifecycle-Dv9Npl7a.js";
5
- import { i as readCodexAppServerBinding } from "./session-binding-ueMCn4om.js";
6
- import { h as formatCodexUsageLimitErrorMessage, i as readCodexNotificationTurnId, r as readCodexNotificationThreadId } from "./notification-correlation-BDakP_d3.js";
7
- import { a as releaseLeasedSharedCodexAppServerClient, i as getLeasedSharedCodexAppServerClient, l as refreshCodexAppServerAuthTokens } from "./shared-client-Duh1bHaP.js";
8
- import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-mXE4_vE_.js";
9
- import { d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, h as filterCodexDynamicTools, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, t as CODEX_NATIVE_HOOK_RELAY_EVENTS, u as createCodexDynamicToolBridge, v as resolveCodexDynamicToolsLoading, y as handleCodexAppServerApprovalRequest } from "./native-hook-relay-B8qM8ZwR.js";
1
+ import { d as resolveCodexAppServerRuntimeOptions, h as shouldAutoApproveCodexAppServerApprovals, u as readCodexPluginConfig } from "./config-AlzuNKCY.js";
2
+ import { a as readCodexDynamicToolCallParams, c as readCodexTurn, i as assertCodexTurnStartResponse, t as assertCodexThreadForkResponse } from "./protocol-validators-DIt7cXIp.js";
3
+ import { i as isCodexAppServerApprovalRequest, l as isJsonObject } from "./client-BnOmn0y-.js";
4
+ import { d as resolveReasoningEffort, g as mergeCodexThreadConfigs, r as buildCodexRuntimeThreadConfig, t as CODEX_NATIVE_PERSONALITY_NONE, u as resolveCodexAppServerModelProvider } from "./thread-lifecycle-Bnlv_Q8u.js";
5
+ import { a as readCodexAppServerBinding } from "./session-binding-BXJAV_xy.js";
6
+ import { h as formatCodexUsageLimitErrorMessage, i as readCodexNotificationTurnId, r as readCodexNotificationThreadId } from "./notification-correlation-BykOI_jh.js";
7
+ import { a as releaseLeasedSharedCodexAppServerClient, i as getLeasedSharedCodexAppServerClient, l as refreshCodexAppServerAuthTokens } from "./shared-client-DBlR-rV2.js";
8
+ import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-DMCJlzmz.js";
9
+ import { d as emitDynamicToolErrorDiagnostic, f as emitDynamicToolStartedDiagnostic, h as filterCodexDynamicTools, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerElicitationRequest, m as filterToolsForVisionInputs, p as emitDynamicToolTerminalDiagnostic, r as buildCodexNativeHookRelayConfig, t as CODEX_NATIVE_HOOK_RELAY_EVENTS, u as createCodexDynamicToolBridge, v as resolveCodexDynamicToolsLoading, y as handleCodexAppServerApprovalRequest } from "./native-hook-relay-DCxPRaBN.js";
10
10
  import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-N66I-Rd7.js";
11
11
  import { buildAgentHookContextChannelFields, embeddedAgentLog, formatErrorMessage, registerNativeHookRelay, resolveAgentDir, resolveAttemptSpawnWorkspaceDir, resolveModelAuthMode, resolveSandboxContext, resolveSessionAgentIds, supportsModelTools } from "openclaw/plugin-sdk/agent-harness-runtime";
12
12
  //#region extensions/codex/src/app-server/side-question.ts
@@ -418,7 +418,7 @@ async function handleSideDynamicToolCallWithTimeout(params) {
418
418
  let resolveAbort;
419
419
  const abortFromRun = () => {
420
420
  const message = "OpenClaw dynamic tool call aborted.";
421
- controller.abort(params.signal.reason ?? new Error(message));
421
+ controller.abort(params.signal.reason ?? /* @__PURE__ */ new Error(message));
422
422
  resolveAbort?.(failedSideDynamicToolResponse(message));
423
423
  };
424
424
  const abortPromise = new Promise((resolve) => {
@@ -1,15 +1,17 @@
1
- import { d as resolveCodexPluginsPolicy, r as codexSandboxPolicyForTurn, t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config--tW89bHH.js";
2
- import { n as assertCodexThreadResumeResponse, r as assertCodexThreadStartResponse } from "./protocol-validators-DtjYmUw_.js";
3
- import { a as isCodexAppServerConnectionClosedError, l as isJsonObject, n as CodexAppServerRpcError } from "./client-DMXvboVu.js";
1
+ import { i as codexSandboxPolicyForTurn, n as CODEX_PLUGINS_MARKETPLACE_NAMES, p as resolveCodexPluginsPolicy, s as isCodexPluginsMarketplaceName, t as CODEX_PLUGINS_MARKETPLACE_NAME } from "./config-AlzuNKCY.js";
2
+ import { n as assertCodexThreadResumeResponse, r as assertCodexThreadStartResponse } from "./protocol-validators-DIt7cXIp.js";
3
+ import { a as isCodexAppServerConnectionClosedError, l as isJsonObject, n as CodexAppServerRpcError } from "./client-BnOmn0y-.js";
4
4
  import { CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY } from "./prompt-overlay.js";
5
5
  import { isModernCodexModel } from "./provider.js";
6
- import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-ueMCn4om.js";
6
+ import { a as readCodexAppServerBinding, r as isCodexAppServerNativeAuthProfile, s as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-BXJAV_xy.js";
7
+ import { isFutureDateTimestampMs, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
7
8
  import crypto from "node:crypto";
8
9
  import { isRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
9
- import { embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine } from "openclaw/plugin-sdk/agent-harness-runtime";
10
+ import { SKILL_WORKSHOP_TOOL_NAME, buildSkillWorkshopPromptSection, embeddedAgentLog, formatErrorMessage, isActiveHarnessContextEngine } from "openclaw/plugin-sdk/agent-harness-runtime";
10
11
  import { buildCodexUserMcpServersThreadConfigPatch } from "openclaw/plugin-sdk/codex-mcp-projection";
11
12
  import { listRegisteredPluginAgentPromptGuidance } from "openclaw/plugin-sdk/plugin-runtime";
12
13
  import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
14
+ import { INLINE_IMAGE_DATA_URL_PREFIX, sanitizeInlineImageDataUrl } from "openclaw/plugin-sdk/inline-image-data-url-runtime";
13
15
  import "node:fs/promises";
14
16
  import "node:path";
15
17
  import { isDiagnosticFlagEnabled } from "openclaw/plugin-sdk/diagnostic-runtime";
@@ -226,78 +228,9 @@ function truncateOlderContext(text, maxChars) {
226
228
  }
227
229
  //#endregion
228
230
  //#region extensions/codex/src/app-server/image-payload-sanitizer.ts
229
- const DATA_URL_PREFIX = "data:";
230
231
  const IMAGE_OMITTED_TEXT = "omitted image payload: invalid inline image data";
231
- const IMAGE_SIGNATURES = [
232
- {
233
- mime: "image/png",
234
- matches: (buffer) => buffer.length >= 8 && buffer[0] === 137 && buffer[1] === 80 && buffer[2] === 78 && buffer[3] === 71 && buffer[4] === 13 && buffer[5] === 10 && buffer[6] === 26 && buffer[7] === 10
235
- },
236
- {
237
- mime: "image/jpeg",
238
- matches: (buffer) => buffer.length >= 3 && buffer[0] === 255 && buffer[1] === 216 && buffer[2] === 255
239
- },
240
- {
241
- mime: "image/webp",
242
- matches: (buffer) => buffer.length >= 12 && buffer.subarray(0, 4).toString("ascii") === "RIFF" && buffer.subarray(8, 12).toString("ascii") === "WEBP"
243
- },
244
- {
245
- mime: "image/gif",
246
- matches: (buffer) => buffer.length >= 6 && (buffer.subarray(0, 6).toString("ascii") === "GIF87a" || buffer.subarray(0, 6).toString("ascii") === "GIF89a")
247
- }
248
- ];
249
- function startsWithDataUrl(value) {
250
- return value.slice(0, 5).toLowerCase() === DATA_URL_PREFIX;
251
- }
252
- function canonicalizeBase64(base64) {
253
- let cleaned = "";
254
- let padding = 0;
255
- let sawPadding = false;
256
- for (let i = 0; i < base64.length; i += 1) {
257
- const code = base64.charCodeAt(i);
258
- if (code <= 32) continue;
259
- if (code === 61) {
260
- padding += 1;
261
- if (padding > 2) return;
262
- sawPadding = true;
263
- cleaned += "=";
264
- continue;
265
- }
266
- if (sawPadding || !(code >= 65 && code <= 90 || code >= 97 && code <= 122 || code >= 48 && code <= 57 || code === 43 || code === 47)) return;
267
- cleaned += base64[i];
268
- }
269
- if (!cleaned || cleaned.length % 4 !== 0) return;
270
- return cleaned;
271
- }
272
- function sniffImageMime(buffer) {
273
- return IMAGE_SIGNATURES.find((signature) => signature.matches(buffer))?.mime;
274
- }
275
- function parseImageDataUrl(value) {
276
- if (!startsWithDataUrl(value)) return {
277
- metadata: [],
278
- payload: value
279
- };
280
- const commaIndex = value.indexOf(",");
281
- if (commaIndex < 0) return;
282
- return {
283
- metadata: value.slice(5, commaIndex).split(";").map((part) => part.trim()),
284
- payload: value.slice(commaIndex + 1)
285
- };
286
- }
287
- function metadataAllowsImageBase64(metadata) {
288
- const [mimeType, ...options] = metadata;
289
- return mimeType !== void 0 && mimeType.toLowerCase().startsWith("image/") && options.some((part) => part.toLowerCase() === "base64");
290
- }
291
- function sanitizeInlineImageDataUrl(imageUrl) {
292
- const parsed = parseImageDataUrl(imageUrl);
293
- if (!parsed) return;
294
- if (parsed.metadata.length === 0) return imageUrl;
295
- if (!metadataAllowsImageBase64(parsed.metadata)) return;
296
- const canonicalPayload = canonicalizeBase64(parsed.payload);
297
- if (!canonicalPayload) return;
298
- const sniffedMimeType = sniffImageMime(Buffer.from(canonicalPayload, "base64"));
299
- if (!sniffedMimeType) return;
300
- return `data:${sniffedMimeType};base64,${canonicalPayload}`;
232
+ function sanitizeInlineImageDataUrl$1(imageUrl) {
233
+ return sanitizeInlineImageDataUrl(imageUrl);
301
234
  }
302
235
  function invalidInlineImageText(label) {
303
236
  return `[${label}] ${IMAGE_OMITTED_TEXT}`;
@@ -305,13 +238,13 @@ function invalidInlineImageText(label) {
305
238
  function sanitizeImageContentRecord(record, label) {
306
239
  if (record.type === "image" && typeof record.data === "string") {
307
240
  const mimeType = typeof record.mimeType === "string" ? record.mimeType : "image/png";
308
- const imageUrl = sanitizeInlineImageDataUrl(`data:${mimeType};base64,${record.data}`);
241
+ const imageUrl = sanitizeInlineImageDataUrl$1(`data:${mimeType};base64,${record.data}`);
309
242
  if (!imageUrl) return {
310
243
  type: "text",
311
244
  text: invalidInlineImageText(label)
312
245
  };
313
246
  const commaIndex = imageUrl.indexOf(",");
314
- const mime = imageUrl.slice(5, commaIndex).split(";")[0] ?? mimeType;
247
+ const mime = imageUrl.slice(INLINE_IMAGE_DATA_URL_PREFIX.length, commaIndex).split(";")[0] ?? mimeType;
315
248
  return {
316
249
  ...record,
317
250
  mimeType: mime,
@@ -319,7 +252,7 @@ function sanitizeImageContentRecord(record, label) {
319
252
  };
320
253
  }
321
254
  if (record.type === "inputImage" && typeof record.imageUrl === "string") {
322
- const imageUrl = sanitizeInlineImageDataUrl(record.imageUrl);
255
+ const imageUrl = sanitizeInlineImageDataUrl$1(record.imageUrl);
323
256
  return imageUrl ? {
324
257
  ...record,
325
258
  imageUrl
@@ -329,7 +262,7 @@ function sanitizeImageContentRecord(record, label) {
329
262
  };
330
263
  }
331
264
  if (record.type === "input_image" && typeof record.image_url === "string") {
332
- const imageUrl = sanitizeInlineImageDataUrl(record.image_url);
265
+ const imageUrl = sanitizeInlineImageDataUrl$1(record.image_url);
333
266
  return imageUrl ? {
334
267
  ...record,
335
268
  image_url: imageUrl
@@ -359,7 +292,7 @@ var CodexAppInventoryCache = class {
359
292
  this.ttlMs = options.ttlMs ?? 36e5;
360
293
  }
361
294
  read(params) {
362
- const nowMs = params.nowMs ?? Date.now();
295
+ const nowMs = resolveDateTimestampMs(params.nowMs);
363
296
  const entry = this.entries.get(params.key);
364
297
  if (!entry) {
365
298
  const refreshScheduled = params.suppressRefresh ? false : this.scheduleRefresh(params);
@@ -371,7 +304,7 @@ var CodexAppInventoryCache = class {
371
304
  ...this.diagnostics.get(params.key) ? { diagnostic: this.diagnostics.get(params.key) } : {}
372
305
  };
373
306
  }
374
- const state = entry.invalidated || entry.expiresAtMs <= nowMs ? "stale" : "fresh";
307
+ const state = entry.invalidated || !isFutureDateTimestampMs(entry.expiresAtMs, { nowMs }) ? "stale" : "fresh";
375
308
  const refreshScheduled = state === "fresh" && !params.forceRefetch ? false : this.scheduleRefresh(params);
376
309
  return {
377
310
  state,
@@ -430,15 +363,16 @@ var CodexAppInventoryCache = class {
430
363
  }
431
364
  }
432
365
  async refreshUncoalesced(params, refreshToken) {
433
- const nowMs = params.nowMs ?? Date.now();
366
+ const nowMs = resolveDateTimestampMs(params.nowMs);
434
367
  try {
435
368
  const apps = await listAllApps(params.request, params.forceRefetch ?? false);
436
369
  this.revision += 1;
370
+ const expiresAtMs = resolveExpiresAtMsFromDurationMs(this.ttlMs, { nowMs }) ?? 0;
437
371
  const snapshot = {
438
372
  key: params.key,
439
373
  apps,
440
374
  fetchedAtMs: nowMs,
441
- expiresAtMs: nowMs + this.ttlMs,
375
+ expiresAtMs,
442
376
  revision: this.revision
443
377
  };
444
378
  if (this.refreshTokens.get(params.key) === refreshToken) {
@@ -548,18 +482,9 @@ async function readCodexPluginInventory(params) {
548
482
  }]
549
483
  };
550
484
  const appInventory = readCachedAppInventory(params);
551
- const marketplaceEntry = (await params.request("plugin/list", { cwds: [] })).marketplaces.find((marketplace) => marketplace.name === CODEX_PLUGINS_MARKETPLACE_NAME);
552
- if (!marketplaceEntry) return {
553
- policy,
554
- records: [],
555
- diagnostics: policy.pluginPolicies.filter((pluginPolicy) => pluginPolicy.enabled).map((pluginPolicy) => ({
556
- code: "marketplace_missing",
557
- plugin: pluginPolicy,
558
- message: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found.`
559
- })),
560
- ...appInventory ? { appInventory } : {}
561
- };
562
- const marketplace = marketplaceRef(marketplaceEntry);
485
+ const listed = await params.request("plugin/list", { cwds: [] });
486
+ const marketplaceByName = /* @__PURE__ */ new Map();
487
+ for (const marketplace of listed.marketplaces) if (isCodexPluginsMarketplaceName(marketplace.name)) marketplaceByName.set(marketplace.name, marketplace);
563
488
  const diagnostics = [];
564
489
  const records = [];
565
490
  if (appInventory?.state === "missing") diagnostics.push({
@@ -572,12 +497,22 @@ async function readCodexPluginInventory(params) {
572
497
  });
573
498
  for (const pluginPolicy of policy.pluginPolicies) {
574
499
  if (!pluginPolicy.enabled) continue;
500
+ const marketplaceEntry = marketplaceByName.get(pluginPolicy.marketplaceName);
501
+ if (!marketplaceEntry) {
502
+ diagnostics.push({
503
+ code: "marketplace_missing",
504
+ plugin: pluginPolicy,
505
+ message: `Codex marketplace ${pluginPolicy.marketplaceName} was not found.`
506
+ });
507
+ continue;
508
+ }
509
+ const marketplace = marketplaceRef(marketplaceEntry);
575
510
  const summary = findPluginSummary(marketplaceEntry, pluginPolicy.pluginName);
576
511
  if (!summary) {
577
512
  diagnostics.push({
578
513
  code: "plugin_missing",
579
514
  plugin: pluginPolicy,
580
- message: `${pluginPolicy.pluginName} was not found in ${CODEX_PLUGINS_MARKETPLACE_NAME}.`
515
+ message: `${pluginPolicy.pluginName} was not found in ${pluginPolicy.marketplaceName}.`
581
516
  });
582
517
  continue;
583
518
  }
@@ -616,20 +551,30 @@ async function readCodexPluginInventory(params) {
616
551
  }
617
552
  return {
618
553
  policy,
619
- marketplace,
620
554
  records,
621
555
  diagnostics,
622
556
  ...appInventory ? { appInventory } : {}
623
557
  };
624
558
  }
625
- function findOpenAiCuratedPluginSummary(listed, pluginName) {
626
- const marketplaceEntry = listed.marketplaces.find((marketplace) => marketplace.name === CODEX_PLUGINS_MARKETPLACE_NAME);
627
- if (!marketplaceEntry) return;
628
- const summary = findPluginSummary(marketplaceEntry, pluginName);
629
- return summary ? {
630
- marketplace: marketplaceRef(marketplaceEntry),
631
- summary
632
- } : void 0;
559
+ function findOpenAiCuratedPluginSummary(listed, pluginName, marketplaceName) {
560
+ if (marketplaceName) {
561
+ const marketplaceEntry = listed.marketplaces.find((marketplace) => marketplace.name === marketplaceName);
562
+ if (!marketplaceEntry) return;
563
+ const summary = findPluginSummary(marketplaceEntry, pluginName);
564
+ return summary ? {
565
+ marketplace: marketplaceRef(marketplaceEntry),
566
+ summary
567
+ } : void 0;
568
+ }
569
+ for (const allowedName of CODEX_PLUGINS_MARKETPLACE_NAMES) {
570
+ const marketplaceEntry = listed.marketplaces.find((marketplace) => marketplace.name === allowedName);
571
+ if (!marketplaceEntry) continue;
572
+ const summary = findPluginSummary(marketplaceEntry, pluginName);
573
+ if (summary) return {
574
+ marketplace: marketplaceRef(marketplaceEntry),
575
+ summary
576
+ };
577
+ }
633
578
  }
634
579
  function pluginReadParams(marketplace, pluginName) {
635
580
  return {
@@ -706,7 +651,7 @@ function pluginNameFromPluginId(pluginId, marketplaceName) {
706
651
  }
707
652
  function marketplaceRef(marketplace) {
708
653
  return {
709
- name: CODEX_PLUGINS_MARKETPLACE_NAME,
654
+ name: isCodexPluginsMarketplaceName(marketplace.name) ? marketplace.name : CODEX_PLUGINS_MARKETPLACE_NAME,
710
655
  ...marketplace.path ? { path: marketplace.path } : {},
711
656
  ...!marketplace.path ? { remoteMarketplaceName: marketplace.name } : {}
712
657
  };
@@ -714,12 +659,12 @@ function marketplaceRef(marketplace) {
714
659
  //#endregion
715
660
  //#region extensions/codex/src/app-server/plugin-activation.ts
716
661
  async function ensureCodexPluginActivation(params) {
717
- if (params.identity.marketplaceName !== "openai-curated") return activationFailure(params.identity, "marketplace_missing", { message: "Only " + CODEX_PLUGINS_MARKETPLACE_NAME + " plugins can be activated." });
662
+ if (!isCodexPluginsMarketplaceName(params.identity.marketplaceName)) return activationFailure(params.identity, "marketplace_missing", { message: "Only " + CODEX_PLUGINS_MARKETPLACE_NAMES.join(" or ") + " plugins can be activated." });
718
663
  const listed = await params.request("plugin/list", { cwds: [] });
719
- const resolved = findOpenAiCuratedPluginSummary(listed, params.identity.pluginName);
664
+ const resolved = findOpenAiCuratedPluginSummary(listed, params.identity.pluginName, params.identity.marketplaceName);
720
665
  if (!resolved) {
721
- if (!listed.marketplaces.some((marketplace) => marketplace.name === "openai-curated")) return activationFailure(params.identity, "marketplace_missing", { message: `Codex marketplace ${CODEX_PLUGINS_MARKETPLACE_NAME} was not found.` });
722
- return activationFailure(params.identity, "plugin_missing", { message: `${params.identity.pluginName} was not found in ${CODEX_PLUGINS_MARKETPLACE_NAME}.` });
666
+ if (!listed.marketplaces.some((marketplace) => marketplace.name === params.identity.marketplaceName)) return activationFailure(params.identity, "marketplace_missing", { message: `Codex marketplace ${params.identity.marketplaceName} was not found.` });
667
+ return activationFailure(params.identity, "plugin_missing", { message: `${params.identity.pluginName} was not found in ${params.identity.marketplaceName}.` });
723
668
  }
724
669
  if (resolved.summary.installed && resolved.summary.enabled && !params.installEvenIfActive) return {
725
670
  identity: params.identity,
@@ -1084,7 +1029,8 @@ var CodexThreadStartRequestError = class extends Error {
1084
1029
  const CODEX_NATIVE_PERSONALITY_NONE = "none";
1085
1030
  const CODEX_CODE_MODE_THREAD_CONFIG = {
1086
1031
  "features.code_mode": true,
1087
- "features.code_mode_only": false
1032
+ "features.code_mode_only": false,
1033
+ "features.apply_patch_streaming_events": true
1088
1034
  };
1089
1035
  const CODEX_CODE_MODE_DISABLED_THREAD_CONFIG = {
1090
1036
  "features.code_mode": false,
@@ -1554,7 +1500,11 @@ function buildCodexRuntimeThreadConfig(config, options = {}) {
1554
1500
  ...CODEX_CODE_MODE_THREAD_CONFIG,
1555
1501
  "features.code_mode_only": options.nativeCodeModeOnlyEnabled === true
1556
1502
  };
1557
- if (options.nativeCodeModeEnabled === false) return mergeCodexThreadConfigs(codeModeConfig, config, CODEX_CODE_MODE_DISABLED_THREAD_CONFIG) ?? { ...CODEX_CODE_MODE_DISABLED_THREAD_CONFIG };
1503
+ if (options.nativeCodeModeEnabled === false) {
1504
+ const disabledConfig = mergeCodexThreadConfigs(config, CODEX_CODE_MODE_DISABLED_THREAD_CONFIG) ?? { ...CODEX_CODE_MODE_DISABLED_THREAD_CONFIG };
1505
+ delete disabledConfig["features.apply_patch_streaming_events"];
1506
+ return disabledConfig;
1507
+ }
1558
1508
  if (options.nativeCodeModeOnlyEnabled === true) return mergeCodexThreadConfigs(codeModeConfig, config, { "features.code_mode_only": true }) ?? {
1559
1509
  ...codeModeConfig,
1560
1510
  "features.code_mode_only": true
@@ -1584,6 +1534,8 @@ function buildTurnStartParams(params, options) {
1584
1534
  ...options.environmentSelection ? { environments: options.environmentSelection } : {},
1585
1535
  collaborationMode: buildTurnCollaborationMode(params, {
1586
1536
  turnScopedDeveloperInstructions: options.turnScopedDeveloperInstructions,
1537
+ skillsCollaborationInstructions: options.skillsCollaborationInstructions,
1538
+ memoryCollaborationInstructions: options.memoryCollaborationInstructions,
1587
1539
  heartbeatCollaborationInstructions: options.heartbeatCollaborationInstructions
1588
1540
  })
1589
1541
  };
@@ -1604,9 +1556,10 @@ function buildTurnCollaborationMode(params, options = {}) {
1604
1556
  };
1605
1557
  }
1606
1558
  function buildTurnScopedCollaborationInstructions(params, options = {}) {
1607
- if (params.trigger === "cron") return joinPresentSections(buildCronCollaborationInstructions(), options.turnScopedDeveloperInstructions);
1608
- if (params.trigger === "heartbeat") return joinPresentSections(buildHeartbeatCollaborationInstructions(), options.turnScopedDeveloperInstructions, options.heartbeatCollaborationInstructions);
1609
- if (options.turnScopedDeveloperInstructions?.trim()) return joinPresentSections(buildDefaultCollaborationInstructions(), options.turnScopedDeveloperInstructions);
1559
+ const contextInstructions = joinPresentSections(options.turnScopedDeveloperInstructions, options.memoryCollaborationInstructions, options.skillsCollaborationInstructions);
1560
+ if (params.trigger === "cron") return joinPresentSections(buildCronCollaborationInstructions(), contextInstructions);
1561
+ if (params.trigger === "heartbeat") return joinPresentSections(buildHeartbeatCollaborationInstructions(), contextInstructions, options.heartbeatCollaborationInstructions);
1562
+ if (contextInstructions?.trim()) return joinPresentSections(buildDefaultCollaborationInstructions(), contextInstructions);
1610
1563
  return null;
1611
1564
  }
1612
1565
  function buildDefaultCollaborationInstructions() {
@@ -1691,6 +1644,7 @@ function buildDeveloperInstructions(params, options = {}) {
1691
1644
  return [
1692
1645
  "You are a personal agent running inside OpenClaw. OpenClaw has dynamic tools for OpenClaw-owned messaging, cron, sessions, media, gateway, and nodes.",
1693
1646
  buildDeferredDynamicToolManifest(options.dynamicTools),
1647
+ buildSkillWorkshopInstruction(options.dynamicTools),
1694
1648
  "Use Codex native `spawn_agent` for Codex subagents. Use OpenClaw `sessions_spawn` only for OpenClaw or ACP delegation.",
1695
1649
  buildVisibleReplyInstruction(params, options.dynamicTools),
1696
1650
  nativeCommandGuidance,
@@ -1702,6 +1656,10 @@ function buildDeferredDynamicToolManifest(dynamicTools) {
1702
1656
  if (deferredToolNames.length === 0) return;
1703
1657
  return `Deferred searchable OpenClaw dynamic tools available: ${deferredToolNames.join(", ")}. Use \`tool_search\` to load exact callable specs before use.`;
1704
1658
  }
1659
+ function buildSkillWorkshopInstruction(dynamicTools) {
1660
+ if (!(dynamicTools ?? []).some((tool) => tool.name.trim() === SKILL_WORKSHOP_TOOL_NAME)) return;
1661
+ return buildSkillWorkshopPromptSection().join("\n");
1662
+ }
1705
1663
  function buildVisibleReplyInstruction(params, dynamicTools) {
1706
1664
  const messageToolAvailable = dynamicTools ? dynamicTools.some((tool) => tool.name.trim() === "message") : params.disableMessageTool !== true;
1707
1665
  if (params.sourceReplyDeliveryMode === "message_tool_only" && messageToolAvailable) return "Visible source replies are not automatically delivered for this run. Use `message(action=send)` for user-visible source-channel output. Do not repeat that visible content in your final answer.";
@@ -1710,7 +1668,7 @@ function buildVisibleReplyInstruction(params, dynamicTools) {
1710
1668
  }
1711
1669
  function buildUserInput(params, promptText = params.prompt) {
1712
1670
  const imageInputs = (params.images ?? []).map((image) => {
1713
- const imageUrl = sanitizeInlineImageDataUrl(`data:${image.mimeType};base64,${image.data}`);
1671
+ const imageUrl = sanitizeInlineImageDataUrl$1(`data:${image.mimeType};base64,${image.data}`);
1714
1672
  return imageUrl ? {
1715
1673
  type: "image",
1716
1674
  url: imageUrl
@@ -1730,8 +1688,8 @@ function resolveCodexAppServerModelProvider(params) {
1730
1688
  const normalized = params.provider.trim();
1731
1689
  const normalizedLower = normalized.toLowerCase();
1732
1690
  if (!normalized || normalizedLower === "codex") return;
1733
- if (isCodexAppServerNativeAuthProfile(params) && (normalizedLower === "openai" || normalizedLower === "openai-codex")) return;
1734
- return normalizedLower === "openai-codex" ? "openai" : normalized;
1691
+ if (isCodexAppServerNativeAuthProfile(params) && normalizedLower === "openai") return;
1692
+ return normalizedLower === "openai" ? "openai" : normalized;
1735
1693
  }
1736
1694
  function resolveReasoningEffort(thinkLevel, modelId) {
1737
1695
  if (thinkLevel === "minimal") return isModernCodexModel(modelId) ? "low" : "minimal";
@@ -1739,4 +1697,4 @@ function resolveReasoningEffort(thinkLevel, modelId) {
1739
1697
  return null;
1740
1698
  }
1741
1699
  //#endregion
1742
- export { sanitizeCodexHistoryImagePayloads as C, resolveCodexContextEngineProjectionReserveTokens as D, resolveCodexContextEngineProjectionMaxChars as E, invalidInlineImageText as S, projectContextEngineAssemblyForCodex as T, shouldBuildCodexPluginThreadConfig as _, buildDeveloperInstructions as a, buildCodexAppInventoryCacheKey as b, codexDynamicToolsFingerprint as c, resolveReasoningEffort as d, startOrResumeThread as f, mergeCodexThreadConfigs as g, buildCodexPluginThreadConfigInputFingerprint as h, buildContextEngineBinding as i, isContextEngineBindingCompatible as l, buildCodexPluginThreadConfig as m, areCodexDynamicToolFingerprintsCompatible as n, buildTurnCollaborationMode as o, isCodexAppServerProfilerEnabled as p, buildCodexRuntimeThreadConfig as r, buildTurnStartParams as s, CODEX_NATIVE_PERSONALITY_NONE as t, resolveCodexAppServerModelProvider as u, ensureCodexPluginActivation as v, sanitizeInlineImageDataUrl as w, defaultCodexAppInventoryCache as x, pluginReadParams as y };
1700
+ export { sanitizeCodexHistoryImagePayloads as C, resolveCodexContextEngineProjectionReserveTokens as D, resolveCodexContextEngineProjectionMaxChars as E, invalidInlineImageText as S, projectContextEngineAssemblyForCodex as T, shouldBuildCodexPluginThreadConfig as _, buildDeveloperInstructions as a, buildCodexAppInventoryCacheKey as b, codexDynamicToolsFingerprint as c, resolveReasoningEffort as d, startOrResumeThread as f, mergeCodexThreadConfigs as g, buildCodexPluginThreadConfigInputFingerprint as h, buildContextEngineBinding as i, isContextEngineBindingCompatible as l, buildCodexPluginThreadConfig as m, areCodexDynamicToolFingerprintsCompatible as n, buildTurnCollaborationMode as o, isCodexAppServerProfilerEnabled as p, buildCodexRuntimeThreadConfig as r, buildTurnStartParams as s, CODEX_NATIVE_PERSONALITY_NONE as t, resolveCodexAppServerModelProvider as u, ensureCodexPluginActivation as v, sanitizeInlineImageDataUrl$1 as w, defaultCodexAppInventoryCache as x, pluginReadParams as y };