@openclaw/codex 2026.5.18 → 2026.5.19-alpha.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 (24) hide show
  1. package/dist/{client-6FkrXfaz.js → client-BCJaLwdZ.js} +1 -1
  2. package/dist/{client-factory-9L6Ie1dC.js → client-factory-By1f68U_.js} +1 -1
  3. package/dist/{command-formatters-BRW7_Nu7.js → command-formatters-BpPOTePl.js} +2 -1
  4. package/dist/{command-handlers-DcoFMn4e.js → command-handlers-CFFYwpt4.js} +78 -7
  5. package/dist/{compact-UKyG6Pw2.js → compact-BPnB6ZWJ.js} +6 -6
  6. package/dist/{computer-use-UJ3dxrXF.js → computer-use-BD8UmXB-.js} +2 -2
  7. package/dist/{config-B5pq6hEz.js → config-B5rU0vP3.js} +2 -0
  8. package/dist/harness.js +8 -8
  9. package/dist/index.js +54 -10
  10. package/dist/media-understanding-provider.js +3 -3
  11. package/dist/{models-C1zn2RN0.js → models-6ViLQ-HQ.js} +1 -1
  12. package/dist/{node-cli-sessions-C9rlYMPw.js → node-cli-sessions-douLgfcf.js} +5 -5
  13. package/dist/{plugin-activation-B49xb7pI.js → plugin-activation-Dtcfb3sk.js} +65 -6
  14. package/dist/provider.js +2 -2
  15. package/dist/{request-XPjLayGw.js → request-BLCZjckr.js} +3 -3
  16. package/dist/{run-attempt-DyLQRA61.js → run-attempt-nWX3d1pe.js} +357 -98
  17. package/dist/{session-binding-DqApZIgD.js → session-binding-D9ejASYj.js} +1 -1
  18. package/dist/{shared-client-DlvmoLBJ.js → shared-client-DWgKldR5.js} +2 -2
  19. package/dist/{side-question-CfRPUq5X.js → side-question-CpJYlXni.js} +48 -16
  20. package/dist/test-api.js +3 -3
  21. package/dist/{thread-lifecycle-5SBrtWFl.js → thread-lifecycle-D8uxjJA4.js} +126 -51
  22. package/dist/{vision-tools-BX9YuTEK.js → vision-tools-CDoJ4rDN.js} +61 -7
  23. package/openclaw.plugin.json +9 -0
  24. package/package.json +4 -4
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-DUslC3ob.js";
2
- import { o as normalizeCodexServiceTier } from "./config-B5pq6hEz.js";
2
+ import { o as normalizeCodexServiceTier } from "./config-B5rU0vP3.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";
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-DUslC3ob.js";
2
- import { c as resolveCodexAppServerRuntimeOptions, n as codexAppServerStartOptionsKey } from "./config-B5pq6hEz.js";
3
- import { a as MANAGED_CODEX_APP_SERVER_PACKAGE, o as resolveCodexAppServerSpawnEnv, t as CodexAppServerClient } from "./client-6FkrXfaz.js";
2
+ import { c as resolveCodexAppServerRuntimeOptions, n as codexAppServerStartOptionsKey } from "./config-B5rU0vP3.js";
3
+ import { a as MANAGED_CODEX_APP_SERVER_PACKAGE, o as resolveCodexAppServerSpawnEnv, t as CodexAppServerClient } from "./client-BCJaLwdZ.js";
4
4
  import { createRequire } from "node:module";
5
5
  import { createHash } from "node:crypto";
6
6
  import { constants, readFileSync } from "node:fs";
@@ -1,12 +1,12 @@
1
- import { c as resolveCodexAppServerRuntimeOptions, s as readCodexPluginConfig } from "./config-B5pq6hEz.js";
1
+ import { c as resolveCodexAppServerRuntimeOptions, s as readCodexPluginConfig } from "./config-B5rU0vP3.js";
2
2
  import { a as readCodexDynamicToolCallParams, i as assertCodexTurnStartResponse, l as readCodexTurnCompletedNotification, t as assertCodexThreadForkResponse } from "./protocol-validators-BGBspNmF.js";
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
- import { r as isCodexAppServerApprovalRequest } from "./client-6FkrXfaz.js";
5
- import { u as formatCodexUsageLimitErrorMessage } from "./command-formatters-BRW7_Nu7.js";
6
- import { i as getSharedCodexAppServerClient, s as refreshCodexAppServerAuthTokens } from "./shared-client-DlvmoLBJ.js";
7
- import { i as readCodexAppServerBinding } from "./session-binding-DqApZIgD.js";
8
- import { S as filterCodexDynamicTools, T as resolveCodexDynamicToolsLoading, b as createCodexDynamicToolBridge, d as resolveReasoningEffort, h as mergeCodexThreadConfigs, n as buildCodexRuntimeThreadConfig, u as resolveCodexAppServerModelProvider } from "./thread-lifecycle-5SBrtWFl.js";
9
- import { a as handleCodexAppServerElicitationRequest, i as buildCodexNativeHookRelayDisabledConfig, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as handleCodexAppServerApprovalRequest, r as buildCodexNativeHookRelayConfig, t as filterToolsForVisionInputs } from "./vision-tools-BX9YuTEK.js";
4
+ import { r as isCodexAppServerApprovalRequest } from "./client-BCJaLwdZ.js";
5
+ import { u as formatCodexUsageLimitErrorMessage } from "./command-formatters-BpPOTePl.js";
6
+ import { i as getSharedCodexAppServerClient, s as refreshCodexAppServerAuthTokens } from "./shared-client-DWgKldR5.js";
7
+ import { i as readCodexAppServerBinding } from "./session-binding-D9ejASYj.js";
8
+ import { S as filterCodexDynamicTools, T as resolveCodexDynamicToolsLoading, b as createCodexDynamicToolBridge, d as resolveReasoningEffort, h as mergeCodexThreadConfigs, n as buildCodexRuntimeThreadConfig, u as resolveCodexAppServerModelProvider } from "./thread-lifecycle-D8uxjJA4.js";
9
+ import { a as handleCodexAppServerElicitationRequest, c as emitDynamicToolTerminalDiagnostic, i as buildCodexNativeHookRelayDisabledConfig, l as handleCodexAppServerApprovalRequest, n as CODEX_NATIVE_HOOK_RELAY_EVENTS, o as emitDynamicToolErrorDiagnostic, r as buildCodexNativeHookRelayConfig, s as emitDynamicToolStartedDiagnostic, t as filterToolsForVisionInputs } from "./vision-tools-CDoJ4rDN.js";
10
10
  import { n as rememberCodexRateLimits, t as readRecentCodexRateLimits } from "./rate-limit-cache-dvhq-4pi.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
@@ -118,12 +118,37 @@ async function runCodexAppServerSideQuestion(params, options = {}) {
118
118
  call,
119
119
  config: params.cfg
120
120
  });
121
- return await handleSideDynamicToolCallWithTimeout({
121
+ const toolStartedAt = Date.now();
122
+ const diagnosticContext = {
122
123
  call,
123
- toolBridge,
124
- signal: runAbortController.signal,
125
- timeoutMs
126
- });
124
+ runId: sideRunParams.runId,
125
+ sessionId: params.sessionId,
126
+ sessionKey: params.sessionKey
127
+ };
128
+ emitDynamicToolStartedDiagnostic(diagnosticContext);
129
+ try {
130
+ const response = await handleSideDynamicToolCallWithTimeout({
131
+ call,
132
+ toolBridge,
133
+ signal: runAbortController.signal,
134
+ timeoutMs
135
+ });
136
+ emitDynamicToolTerminalDiagnostic({
137
+ ...diagnosticContext,
138
+ response,
139
+ durationMs: Math.max(0, Date.now() - toolStartedAt)
140
+ });
141
+ return {
142
+ contentItems: response.contentItems,
143
+ success: response.success
144
+ };
145
+ } catch (error) {
146
+ emitDynamicToolErrorDiagnostic({
147
+ ...diagnosticContext,
148
+ durationMs: Math.max(0, Date.now() - toolStartedAt)
149
+ });
150
+ throw error;
151
+ }
127
152
  });
128
153
  const approvalPolicy = binding.approvalPolicy ?? appServer.approvalPolicy;
129
154
  const sandbox = binding.sandbox ?? appServer.sandbox;
@@ -156,7 +181,7 @@ async function runCodexAppServerSideQuestion(params, options = {}) {
156
181
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec,
157
182
  clearOmittedEvents: true
158
183
  }) : options.nativeHookRelay?.enabled === false ? buildCodexNativeHookRelayDisabledConfig() : void 0;
159
- const runtimeThreadConfig = buildCodexRuntimeThreadConfig(void 0);
184
+ const runtimeThreadConfig = buildCodexRuntimeThreadConfig(void 0, { nativeCodeModeOnlyEnabled: appServer.codeModeOnly });
160
185
  const threadConfig = mergeCodexThreadConfigs(nativeHookRelayConfig, runtimeThreadConfig) ?? runtimeThreadConfig;
161
186
  const modelProvider = resolveCodexAppServerModelProvider({
162
187
  provider: params.provider,
@@ -343,6 +368,7 @@ async function createCodexSideToolBridge(input) {
343
368
  currentChannelId: input.params.currentChannelId
344
369
  }).channelId,
345
370
  sandbox,
371
+ emitBeforeToolCallDiagnostics: false,
346
372
  modelHasVision: runtimeModel.input?.includes("image") ?? false,
347
373
  requireExplicitMessageTarget: true
348
374
  }), input.pluginConfig), {
@@ -409,13 +435,19 @@ async function handleSideDynamicToolCallWithTimeout(params) {
409
435
  }
410
436
  }
411
437
  function failedSideDynamicToolResponse(message) {
412
- return {
413
- success: false,
438
+ const response = {
414
439
  contentItems: [{
415
440
  type: "inputText",
416
441
  text: message
417
- }]
442
+ }],
443
+ success: false
418
444
  };
445
+ Object.defineProperty(response, "diagnosticTerminalType", {
446
+ configurable: true,
447
+ enumerable: false,
448
+ value: "error"
449
+ });
450
+ return response;
419
451
  }
420
452
  function emptySideUserInputResponse() {
421
453
  return { answers: {} };
package/dist/test-api.js CHANGED
@@ -1,5 +1,5 @@
1
- import { c as resolveCodexAppServerRuntimeOptions } from "./config-B5pq6hEz.js";
2
- import { S as filterCodexDynamicTools, a as buildThreadResumeParams, b as createCodexDynamicToolBridge, i as buildDeveloperInstructions, o as buildThreadStartParams, s as buildTurnStartParams } from "./thread-lifecycle-5SBrtWFl.js";
1
+ import { c as resolveCodexAppServerRuntimeOptions } from "./config-B5rU0vP3.js";
2
+ import { S as filterCodexDynamicTools, a as buildThreadResumeParams, b as createCodexDynamicToolBridge, i as buildDeveloperInstructions, o as buildThreadStartParams, s as buildTurnStartParams } from "./thread-lifecycle-D8uxjJA4.js";
3
3
  //#region extensions/codex/test-api.ts
4
4
  function resolveCodexPromptSnapshotAppServerOptions(pluginConfig) {
5
5
  return resolveCodexAppServerRuntimeOptions({
@@ -9,7 +9,7 @@ function resolveCodexPromptSnapshotAppServerOptions(pluginConfig) {
9
9
  });
10
10
  }
11
11
  function buildCodexHarnessPromptSnapshot(params) {
12
- const developerInstructions = buildDeveloperInstructions(params.attempt);
12
+ const developerInstructions = buildDeveloperInstructions(params.attempt, { dynamicTools: params.dynamicTools });
13
13
  return {
14
14
  developerInstructions,
15
15
  threadStartParams: buildThreadStartParams(params.attempt, {
@@ -1,15 +1,16 @@
1
- import { r as codexSandboxPolicyForTurn, u as resolveCodexPluginsPolicy } from "./config-B5pq6hEz.js";
1
+ import { r as codexSandboxPolicyForTurn, u as resolveCodexPluginsPolicy } from "./config-B5rU0vP3.js";
2
2
  import { n as assertCodexThreadResumeResponse, r as assertCodexThreadStartResponse } from "./protocol-validators-BGBspNmF.js";
3
3
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
4
- import { CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY, renderCodexPromptOverlay } from "./prompt-overlay.js";
4
+ import { CODEX_GPT5_HEARTBEAT_PROMPT_OVERLAY } from "./prompt-overlay.js";
5
5
  import { isModernCodexModel } from "./provider.js";
6
- import { i as isCodexAppServerConnectionClosedError } from "./client-6FkrXfaz.js";
7
- import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-DqApZIgD.js";
8
- import { a as defaultCodexAppInventoryCache, r as readCodexPluginInventory, t as ensureCodexPluginActivation } from "./plugin-activation-B49xb7pI.js";
6
+ import { i as isCodexAppServerConnectionClosedError } from "./client-BCJaLwdZ.js";
7
+ import { i as readCodexAppServerBinding, n as isCodexAppServerNativeAuthProfile, o as writeCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-D9ejASYj.js";
8
+ import { a as defaultCodexAppInventoryCache, o as serializeCodexAppInventoryError, r as readCodexPluginInventory, t as ensureCodexPluginActivation } from "./plugin-activation-Dtcfb3sk.js";
9
9
  import crypto from "node:crypto";
10
- import { HEARTBEAT_RESPONSE_TOOL_NAME, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractToolResultMediaArtifact, filterToolResultMediaUrls, isActiveHarnessContextEngine, isMessagingTool, isMessagingToolSendAction, isToolWrappedWithBeforeToolCallHook, normalizeHeartbeatToolResponse, runAgentHarnessAfterToolCallHook, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
10
+ import { HEARTBEAT_RESPONSE_TOOL_NAME, createAgentToolResultMiddlewareRunner, createCodexAppServerToolResultExtensionRunner, embeddedAgentLog, extractToolResultMediaArtifact, filterToolResultMediaUrls, isActiveHarnessContextEngine, isMessagingTool, isMessagingToolSendAction, isToolWrappedWithBeforeToolCallHook, normalizeHeartbeatToolResponse, runAgentHarnessAfterToolCallHook, setBeforeToolCallDiagnosticsEnabled, wrapToolWithBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
11
11
  import { normalizeAgentId } from "openclaw/plugin-sdk/routing";
12
12
  import { buildCodexUserMcpServersThreadConfigPatch } from "openclaw/plugin-sdk/codex-mcp-projection";
13
+ import { listRegisteredPluginAgentPromptGuidance } from "openclaw/plugin-sdk/plugin-runtime";
13
14
  import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
14
15
  //#region extensions/codex/src/app-server/dynamic-tool-profile.ts
15
16
  const CODEX_APP_SERVER_OWNED_DYNAMIC_TOOL_EXCLUDES = [
@@ -156,7 +157,13 @@ const DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS = 16e3;
156
157
  function createCodexDynamicToolBridge(params) {
157
158
  const toolResultHookContext = toToolResultHookContext(params.hookContext);
158
159
  const toolResultMaxChars = resolveCodexDynamicToolResultMaxChars(params.hookContext);
159
- const tools = params.tools.map((tool) => isToolWrappedWithBeforeToolCallHook(tool) ? tool : wrapToolWithBeforeToolCallHook(tool, params.hookContext));
160
+ const tools = params.tools.map((tool) => {
161
+ if (isToolWrappedWithBeforeToolCallHook(tool)) {
162
+ setBeforeToolCallDiagnosticsEnabled(tool, false);
163
+ return tool;
164
+ }
165
+ return wrapToolWithBeforeToolCallHook(tool, params.hookContext, { emitDiagnostics: false });
166
+ });
160
167
  const toolMap = new Map(tools.map((tool) => [tool.name, tool]));
161
168
  const telemetry = {
162
169
  didSendViaMessagingTool: false,
@@ -234,10 +241,10 @@ function createCodexDynamicToolBridge(params) {
234
241
  result,
235
242
  startedAt
236
243
  });
237
- return {
244
+ return withDiagnosticTerminalType({
238
245
  contentItems: convertToolContents(result.content, toolResultMaxChars),
239
246
  success: !resultIsError
240
- };
247
+ }, inferToolResultDiagnosticTerminalType(result, resultIsError));
241
248
  } catch (error) {
242
249
  collectToolTelemetry({
243
250
  toolName: tool.name,
@@ -258,13 +265,13 @@ function createCodexDynamicToolBridge(params) {
258
265
  error: error instanceof Error ? error.message : String(error),
259
266
  startedAt
260
267
  });
261
- return {
268
+ return withDiagnosticTerminalType({
262
269
  contentItems: [{
263
270
  type: "inputText",
264
271
  text: error instanceof Error ? error.message : String(error)
265
272
  }],
266
273
  success: false
267
- };
274
+ }, "error");
268
275
  }
269
276
  }
270
277
  };
@@ -408,6 +415,21 @@ function isToolResultError(result) {
408
415
  const status = details.status.trim().toLowerCase();
409
416
  return status !== "" && status !== "0" && status !== "ok" && status !== "success" && status !== "completed" && status !== "recorded" && status !== "running";
410
417
  }
418
+ function inferToolResultDiagnosticTerminalType(result, isError) {
419
+ const details = result.details;
420
+ if (isRecord(details) && typeof details.status === "string") {
421
+ if (details.status.trim().toLowerCase() === "blocked") return "blocked";
422
+ }
423
+ return isError ? "error" : "completed";
424
+ }
425
+ function withDiagnosticTerminalType(response, terminalType) {
426
+ Object.defineProperty(response, "diagnosticTerminalType", {
427
+ configurable: true,
428
+ enumerable: false,
429
+ value: terminalType
430
+ });
431
+ return response;
432
+ }
411
433
  function normalizeToolResultMaxChars(maxChars) {
412
434
  return typeof maxChars === "number" && Number.isFinite(maxChars) && maxChars > 0 ? Math.floor(maxChars) : DEFAULT_CODEX_DYNAMIC_TOOL_RESULT_MAX_CHARS;
413
435
  }
@@ -782,10 +804,14 @@ async function buildCodexPluginThreadConfig(params) {
782
804
  request: params.request,
783
805
  appCache,
784
806
  appCacheKey: params.appCacheKey,
785
- nowMs: params.nowMs
807
+ nowMs: params.nowMs,
808
+ suppressAppInventoryRefresh: true
786
809
  });
787
810
  if (shouldWaitForInitialAppInventory(params, policy, inventory)) {
788
- await refreshAppInventoryNow(params, appCache);
811
+ await refreshAppInventoryNow(params, appCache, {
812
+ forceRefetch: true,
813
+ reason: "initial_missing"
814
+ });
789
815
  inventory = await readCodexPluginInventory({
790
816
  pluginConfig: params.pluginConfig,
791
817
  policy,
@@ -817,7 +843,28 @@ async function buildCodexPluginThreadConfig(params) {
817
843
  });
818
844
  }
819
845
  if (activationResults.some((activation) => activation.ok && activation.installAttempted)) {
820
- await refreshAppInventoryNow(params, appCache, { forceRefetch: true });
846
+ await refreshAppInventoryNow(params, appCache, {
847
+ forceRefetch: true,
848
+ reason: "post_install"
849
+ });
850
+ inventory = await readCodexPluginInventory({
851
+ pluginConfig: params.pluginConfig,
852
+ policy,
853
+ request: params.request,
854
+ appCache,
855
+ appCacheKey: params.appCacheKey,
856
+ nowMs: params.nowMs
857
+ });
858
+ inputFingerprint = buildCodexPluginThreadConfigInputFingerprint({
859
+ pluginConfig: params.pluginConfig,
860
+ appCacheKey: params.appCacheKey
861
+ });
862
+ }
863
+ if (shouldForceRefreshForNotReadyPluginApps(params, policy, inventory)) {
864
+ await refreshAppInventoryNow(params, appCache, {
865
+ forceRefetch: true,
866
+ reason: "not_ready_plugin_apps"
867
+ });
821
868
  inventory = await readCodexPluginInventory({
822
869
  pluginConfig: params.pluginConfig,
823
870
  policy,
@@ -845,7 +892,10 @@ async function buildCodexPluginThreadConfig(params) {
845
892
  }
846
893
  if (record.appOwnership !== "proven") continue;
847
894
  pluginAppIds[record.policy.configKey] = [...record.ownedAppIds].toSorted();
848
- for (const app of record.apps) {
895
+ for (const app of resolveThreadConfigAppsForRecord({
896
+ record,
897
+ inventory
898
+ })) {
849
899
  if (!app.accessible || !app.enabled) {
850
900
  diagnostics.push({
851
901
  code: "app_not_ready",
@@ -942,13 +992,29 @@ async function refreshAppInventoryNow(params, appCache, options = {}) {
942
992
  if (!appCacheKey) return;
943
993
  const request = async (method, requestParams) => await params.request(method, requestParams);
944
994
  try {
945
- await appCache.refreshNow({
995
+ return await appCache.refreshNow({
946
996
  key: appCacheKey,
947
997
  request,
948
998
  nowMs: params.nowMs,
949
999
  forceRefetch: options.forceRefetch
950
1000
  });
951
- } catch {}
1001
+ } catch (error) {
1002
+ embeddedAgentLog.warn("codex plugin thread config app inventory refresh failed", {
1003
+ reason: options.reason,
1004
+ forceRefetch: options.forceRefetch === true,
1005
+ error: serializeCodexAppInventoryError(error)
1006
+ });
1007
+ return;
1008
+ }
1009
+ }
1010
+ function resolveThreadConfigAppsForRecord(params) {
1011
+ if (params.inventory.appInventory?.state === "missing") return [];
1012
+ return params.record.apps;
1013
+ }
1014
+ function shouldForceRefreshForNotReadyPluginApps(params, policy, inventory) {
1015
+ if (!params.appCacheKey || !policy.pluginPolicies.some((plugin) => plugin.enabled)) return false;
1016
+ if (inventory.appInventory?.state === "missing") return false;
1017
+ return inventory.records.some((record) => record.appOwnership === "proven" && record.ownedAppIds.length > 0 && (record.apps.length === 0 || record.apps.some((app) => !app.accessible || !app.enabled)));
952
1018
  }
953
1019
  function policyFingerprint(policy) {
954
1020
  return {
@@ -1087,9 +1153,11 @@ async function startOrResumeThread(params) {
1087
1153
  threadId: binding.threadId,
1088
1154
  authProfileId,
1089
1155
  appServer: params.appServer,
1156
+ dynamicTools: params.dynamicTools,
1090
1157
  developerInstructions: params.developerInstructions,
1091
1158
  config: resumeConfig,
1092
- nativeCodeModeEnabled: params.nativeCodeModeEnabled
1159
+ nativeCodeModeEnabled: params.nativeCodeModeEnabled,
1160
+ nativeCodeModeOnlyEnabled: params.nativeCodeModeOnlyEnabled
1093
1161
  })));
1094
1162
  const boundAuthProfileId = authProfileId;
1095
1163
  const fallbackModelProvider = resolveCodexAppServerModelProvider({
@@ -1157,7 +1225,8 @@ async function startOrResumeThread(params) {
1157
1225
  appServer: params.appServer,
1158
1226
  developerInstructions: params.developerInstructions,
1159
1227
  config,
1160
- nativeCodeModeEnabled: params.nativeCodeModeEnabled
1228
+ nativeCodeModeEnabled: params.nativeCodeModeEnabled,
1229
+ nativeCodeModeOnlyEnabled: params.nativeCodeModeOnlyEnabled
1161
1230
  })));
1162
1231
  const modelProvider = resolveCodexAppServerModelProvider({
1163
1232
  provider: params.params.provider,
@@ -1298,9 +1367,12 @@ function buildThreadStartParams(params, options) {
1298
1367
  sandbox: options.appServer.sandbox,
1299
1368
  ...options.appServer.serviceTier ? { serviceTier: options.appServer.serviceTier } : {},
1300
1369
  serviceName: "OpenClaw",
1301
- config: buildCodexRuntimeThreadConfigForRun(params, options.config, { nativeCodeModeEnabled: options.nativeCodeModeEnabled }),
1370
+ config: buildCodexRuntimeThreadConfigForRun(params, options.config, {
1371
+ nativeCodeModeEnabled: options.nativeCodeModeEnabled,
1372
+ nativeCodeModeOnlyEnabled: options.nativeCodeModeOnlyEnabled
1373
+ }),
1302
1374
  ...options.nativeCodeModeEnabled === false ? { environments: [] } : {},
1303
- developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params),
1375
+ developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params, { dynamicTools: options.dynamicTools }),
1304
1376
  dynamicTools: options.dynamicTools,
1305
1377
  experimentalRawEvents: true,
1306
1378
  persistExtendedHistory: true
@@ -1322,14 +1394,25 @@ function buildThreadResumeParams(params, options) {
1322
1394
  approvalsReviewer: options.appServer.approvalsReviewer,
1323
1395
  sandbox: options.appServer.sandbox,
1324
1396
  ...options.appServer.serviceTier ? { serviceTier: options.appServer.serviceTier } : {},
1325
- config: buildCodexRuntimeThreadConfigForRun(params, options.config, { nativeCodeModeEnabled: options.nativeCodeModeEnabled }),
1326
- developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params),
1397
+ config: buildCodexRuntimeThreadConfigForRun(params, options.config, {
1398
+ nativeCodeModeEnabled: options.nativeCodeModeEnabled,
1399
+ nativeCodeModeOnlyEnabled: options.nativeCodeModeOnlyEnabled
1400
+ }),
1401
+ developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params, { dynamicTools: options.dynamicTools }),
1327
1402
  persistExtendedHistory: true
1328
1403
  };
1329
1404
  }
1330
1405
  function buildCodexRuntimeThreadConfig(config, options = {}) {
1331
- if (options.nativeCodeModeEnabled === false) return mergeCodexThreadConfigs(CODEX_CODE_MODE_THREAD_CONFIG, config, CODEX_CODE_MODE_DISABLED_THREAD_CONFIG) ?? { ...CODEX_CODE_MODE_DISABLED_THREAD_CONFIG };
1332
- return mergeCodexThreadConfigs(CODEX_CODE_MODE_THREAD_CONFIG, config) ?? { ...CODEX_CODE_MODE_THREAD_CONFIG };
1406
+ const codeModeConfig = {
1407
+ ...CODEX_CODE_MODE_THREAD_CONFIG,
1408
+ "features.code_mode_only": options.nativeCodeModeOnlyEnabled === true
1409
+ };
1410
+ if (options.nativeCodeModeEnabled === false) return mergeCodexThreadConfigs(codeModeConfig, config, CODEX_CODE_MODE_DISABLED_THREAD_CONFIG) ?? { ...CODEX_CODE_MODE_DISABLED_THREAD_CONFIG };
1411
+ if (options.nativeCodeModeOnlyEnabled === true) return mergeCodexThreadConfigs(codeModeConfig, config, { "features.code_mode_only": true }) ?? {
1412
+ ...codeModeConfig,
1413
+ "features.code_mode_only": true
1414
+ };
1415
+ return mergeCodexThreadConfigs(codeModeConfig, config) ?? { ...codeModeConfig };
1333
1416
  }
1334
1417
  function buildCodexRuntimeThreadConfigForRun(params, config, options = {}) {
1335
1418
  const runtimeConfig = buildCodexRuntimeThreadConfig(config, options);
@@ -1421,36 +1504,28 @@ function shouldStartTransientNoToolThread(params) {
1421
1504
  function compareJsonFingerprint(left, right) {
1422
1505
  return JSON.stringify(left).localeCompare(JSON.stringify(right));
1423
1506
  }
1424
- function buildDeveloperInstructions(params) {
1507
+ function buildDeveloperInstructions(params, options = {}) {
1508
+ const nativeCommandGuidance = listRegisteredPluginAgentPromptGuidance({
1509
+ surface: "codex_app_server",
1510
+ includeLegacyGlobalGuidance: false
1511
+ }).join("\n");
1425
1512
  return [
1426
- "Running inside OpenClaw. Use dynamic tools for messaging, cron, sessions, media, gateway, and nodes when available.",
1513
+ "Running inside OpenClaw. Use OpenClaw dynamic tools for OpenClaw-owned messaging, cron, sessions, media, gateway, and nodes capabilities when available.",
1514
+ buildDeferredDynamicToolManifest(options.dynamicTools),
1427
1515
  "Use Codex native `spawn_agent` for Codex subagents. Use OpenClaw `sessions_spawn` only for OpenClaw or ACP delegation; if it is not already loaded, search for `sessions_spawn` in the `openclaw` dynamic tool namespace before calling it.",
1428
- "Preserve channel/session context. Visible channel replies: use `message`, do not describe would-reply.",
1429
- renderCodexRuntimePromptOverlay(params),
1430
- params.extraSystemPrompt,
1431
- params.skillsSnapshot?.prompt
1516
+ buildVisibleReplyInstruction(params),
1517
+ nativeCommandGuidance,
1518
+ params.extraSystemPrompt
1432
1519
  ].filter((section) => typeof section === "string" && section.trim()).join("\n\n");
1433
1520
  }
1434
- function renderCodexRuntimePromptOverlay(params) {
1435
- const contribution = params.runtimePlan?.prompt.resolveSystemPromptContribution({
1436
- config: params.config,
1437
- agentDir: params.agentDir,
1438
- workspaceDir: params.workspaceDir,
1439
- provider: params.provider,
1440
- modelId: params.modelId,
1441
- promptMode: "full",
1442
- agentId: params.agentId
1443
- });
1444
- if (!contribution) return renderCodexPromptOverlay({
1445
- config: params.config,
1446
- providerId: params.provider,
1447
- modelId: params.modelId
1448
- });
1449
- return [
1450
- contribution.stablePrefix,
1451
- ...Object.values(contribution.sectionOverrides ?? {}),
1452
- contribution.dynamicSuffix
1453
- ].filter((section) => typeof section === "string" && section.trim().length > 0).join("\n\n");
1521
+ function buildDeferredDynamicToolManifest(dynamicTools) {
1522
+ const deferredToolNames = [...new Set((dynamicTools ?? []).filter((tool) => tool.deferLoading === true).map((tool) => tool.name.trim()).filter(Boolean))].toSorted((left, right) => left.localeCompare(right));
1523
+ if (deferredToolNames.length === 0) return;
1524
+ return `Deferred searchable OpenClaw dynamic tools available: ${deferredToolNames.join(", ")}. Use \`tool_search\` to load exact callable specs before use.`;
1525
+ }
1526
+ function buildVisibleReplyInstruction(params) {
1527
+ if (params.sourceReplyDeliveryMode === "message_tool_only") return "Preserve channel/session context. Visible channel replies: use `message`, do not describe would-reply.";
1528
+ return "Preserve channel/session context. Visible channel replies should use the active Codex delivery path; do not describe would-reply.";
1454
1529
  }
1455
1530
  function buildUserInput(params, promptText = params.prompt) {
1456
1531
  const imageInputs = (params.images ?? []).map((image) => {
@@ -1,7 +1,8 @@
1
1
  import { t as isJsonObject } from "./protocol-C9UWI98H.js";
2
- import { r as formatCodexDisplayText } from "./command-formatters-BRW7_Nu7.js";
2
+ import { r as formatCodexDisplayText } from "./command-formatters-BpPOTePl.js";
3
3
  import { createHash } from "node:crypto";
4
4
  import { buildAgentHookContextChannelFields, callGatewayTool, embeddedAgentLog, formatApprovalDisplayPath, hasNativeHookRelayInvocation, invokeNativeHookRelay, runBeforeToolCallHook } from "openclaw/plugin-sdk/agent-harness-runtime";
5
+ import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
5
6
  //#region extensions/codex/src/app-server/plugin-approval-roundtrip.ts
6
7
  const DEFAULT_CODEX_APPROVAL_TIMEOUT_MS = 12e4;
7
8
  const MAX_PLUGIN_APPROVAL_TITLE_LENGTH = 80;
@@ -743,6 +744,59 @@ function formatErrorMessage$1(error) {
743
744
  return error instanceof Error ? error.message : String(error);
744
745
  }
745
746
  //#endregion
747
+ //#region extensions/codex/src/app-server/dynamic-tool-diagnostics.ts
748
+ function emitDynamicToolStartedDiagnostic(params) {
749
+ emitTrustedDiagnosticEvent({
750
+ type: "tool.execution.started",
751
+ runId: params.runId,
752
+ sessionId: params.sessionId,
753
+ sessionKey: params.sessionKey,
754
+ toolName: params.call.tool,
755
+ toolCallId: params.call.callId
756
+ });
757
+ }
758
+ function emitDynamicToolErrorDiagnostic(params) {
759
+ emitTrustedDiagnosticEvent({
760
+ type: "tool.execution.error",
761
+ runId: params.runId,
762
+ sessionId: params.sessionId,
763
+ sessionKey: params.sessionKey,
764
+ toolName: params.call.tool,
765
+ toolCallId: params.call.callId,
766
+ durationMs: params.durationMs,
767
+ errorCategory: "codex_dynamic_tool_error"
768
+ });
769
+ }
770
+ function emitDynamicToolTerminalDiagnostic(params) {
771
+ const terminalType = params.response.diagnosticTerminalType ?? (params.response.success ? "completed" : "error");
772
+ if (terminalType === "completed") {
773
+ emitTrustedDiagnosticEvent({
774
+ type: "tool.execution.completed",
775
+ runId: params.runId,
776
+ sessionId: params.sessionId,
777
+ sessionKey: params.sessionKey,
778
+ toolName: params.call.tool,
779
+ toolCallId: params.call.callId,
780
+ durationMs: params.durationMs
781
+ });
782
+ return;
783
+ }
784
+ if (terminalType === "blocked") {
785
+ emitTrustedDiagnosticEvent({
786
+ type: "tool.execution.blocked",
787
+ runId: params.runId,
788
+ sessionId: params.sessionId,
789
+ sessionKey: params.sessionKey,
790
+ toolName: params.call.tool,
791
+ toolCallId: params.call.callId,
792
+ deniedReason: "plugin-before-tool-call",
793
+ reason: "Tool call blocked"
794
+ });
795
+ return;
796
+ }
797
+ emitDynamicToolErrorDiagnostic(params);
798
+ }
799
+ //#endregion
746
800
  //#region extensions/codex/src/app-server/elicitation-bridge.ts
747
801
  const MCP_TOOL_APPROVAL_KIND = "mcp_tool_call";
748
802
  const MCP_TOOL_APPROVAL_KIND_KEY = "codex_approval_kind";
@@ -832,7 +886,7 @@ function hasExactTurnId(requestParams, turnId) {
832
886
  function resolvePluginElicitation(params) {
833
887
  const requestParams = params.requestParams;
834
888
  if (!requestParams) return { kind: "not_plugin" };
835
- const meta = isJsonObject(requestParams._meta) ? requestParams._meta : {};
889
+ const meta = isJsonObject(requestParams["_meta"]) ? requestParams["_meta"] : {};
836
890
  const context = params.pluginAppPolicyContext;
837
891
  const entries = context ? Object.values(context.apps) : [];
838
892
  const appId = readFirstString(meta, PLUGIN_APP_ID_META_KEYS) ?? readFirstString(requestParams, PLUGIN_APP_ID_META_KEYS);
@@ -923,7 +977,7 @@ function buildPluginPolicyElicitationResponse(entry, requestParams) {
923
977
  logPluginElicitationDecline("unsupported_schema", requestParams);
924
978
  return declineElicitationResponse();
925
979
  }
926
- const meta = isJsonObject(requestParams._meta) ? requestParams._meta : {};
980
+ const meta = isJsonObject(requestParams["_meta"]) ? requestParams["_meta"] : {};
927
981
  const response = buildElicitationResponse(requestParams.requestedSchema, meta, "approved-once");
928
982
  if (isJsonObject(response) && response.action === "accept") return response;
929
983
  logPluginElicitationDecline("unmappable_schema", requestParams);
@@ -944,7 +998,7 @@ function logPluginElicitationDecline(reason, requestParams) {
944
998
  });
945
999
  }
946
1000
  function readBridgeableApprovalElicitation(requestParams) {
947
- if (!requestParams || readString(requestParams, "mode") !== "form" || !isJsonObject(requestParams._meta) || requestParams._meta[MCP_TOOL_APPROVAL_KIND_KEY] !== MCP_TOOL_APPROVAL_KIND || !isJsonObject(requestParams.requestedSchema)) return;
1001
+ if (!requestParams || readString(requestParams, "mode") !== "form" || !isJsonObject(requestParams["_meta"]) || requestParams["_meta"][MCP_TOOL_APPROVAL_KIND_KEY] !== MCP_TOOL_APPROVAL_KIND || !isJsonObject(requestParams.requestedSchema)) return;
948
1002
  const requestedSchema = requestParams.requestedSchema;
949
1003
  if (readString(requestedSchema, "type") !== "object" || !isJsonObject(requestedSchema.properties)) return;
950
1004
  const title = sanitizeDisplayText(readString(requestParams, "message") ?? "") || "Codex MCP tool approval";
@@ -952,12 +1006,12 @@ function readBridgeableApprovalElicitation(requestParams) {
952
1006
  title,
953
1007
  description: buildApprovalDescription({
954
1008
  title,
955
- meta: requestParams._meta,
1009
+ meta: requestParams["_meta"],
956
1010
  requestedSchema,
957
1011
  serverName: sanitizeOptionalDisplayText(readString(requestParams, "serverName"))
958
1012
  }),
959
1013
  requestedSchema,
960
- meta: requestParams._meta
1014
+ meta: requestParams["_meta"]
961
1015
  };
962
1016
  }
963
1017
  function buildApprovalDescription(params) {
@@ -1322,4 +1376,4 @@ function filterToolsForVisionInputs(tools, params) {
1322
1376
  return tools.filter((tool) => tool.name !== "image");
1323
1377
  }
1324
1378
  //#endregion
1325
- export { handleCodexAppServerElicitationRequest as a, buildCodexNativeHookRelayDisabledConfig as i, CODEX_NATIVE_HOOK_RELAY_EVENTS as n, handleCodexAppServerApprovalRequest as o, buildCodexNativeHookRelayConfig as r, filterToolsForVisionInputs as t };
1379
+ export { handleCodexAppServerElicitationRequest as a, emitDynamicToolTerminalDiagnostic as c, buildCodexNativeHookRelayDisabledConfig as i, handleCodexAppServerApprovalRequest as l, CODEX_NATIVE_HOOK_RELAY_EVENTS as n, emitDynamicToolErrorDiagnostic as o, buildCodexNativeHookRelayConfig as r, emitDynamicToolStartedDiagnostic as s, filterToolsForVisionInputs as t };
@@ -161,6 +161,10 @@
161
161
  "type": "array",
162
162
  "items": { "type": "string" }
163
163
  },
164
+ "codeModeOnly": {
165
+ "type": "boolean",
166
+ "default": false
167
+ },
164
168
  "requestTimeoutMs": {
165
169
  "type": "number",
166
170
  "minimum": 1,
@@ -326,6 +330,11 @@
326
330
  "help": "Environment variable names removed from the spawned stdio app-server process after overrides are applied.",
327
331
  "advanced": true
328
332
  },
333
+ "appServer.codeModeOnly": {
334
+ "label": "Code Mode Only",
335
+ "help": "Expose Codex's code-mode-only tool surface. OpenClaw dynamic tools remain available through Codex nested tool calls.",
336
+ "advanced": true
337
+ },
329
338
  "appServer.requestTimeoutMs": {
330
339
  "label": "Request Timeout",
331
340
  "help": "Maximum time to wait for Codex app-server control-plane requests.",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.5.18",
3
+ "version": "2026.5.19-alpha.1",
4
4
  "description": "OpenClaw Codex harness and model provider plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -27,10 +27,10 @@
27
27
  "minHostVersion": ">=2026.5.1-beta.1"
28
28
  },
29
29
  "compat": {
30
- "pluginApi": ">=2026.5.18"
30
+ "pluginApi": ">=2026.5.19-alpha.1"
31
31
  },
32
32
  "build": {
33
- "openclawVersion": "2026.5.18"
33
+ "openclawVersion": "2026.5.19-alpha.1"
34
34
  },
35
35
  "release": {
36
36
  "publishToClawHub": true,
@@ -45,7 +45,7 @@
45
45
  "openclaw.plugin.json"
46
46
  ],
47
47
  "peerDependencies": {
48
- "openclaw": ">=2026.5.18"
48
+ "openclaw": ">=2026.5.19-alpha.1"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "openclaw": {