@openclaw/codex 2026.5.16-beta.5 → 2026.5.16-beta.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/harness.js CHANGED
@@ -18,14 +18,14 @@ function createCodexAppServerAgentHarness(options) {
18
18
  };
19
19
  },
20
20
  runAttempt: async (params) => {
21
- const { runCodexAppServerAttempt } = await import("./run-attempt-Bssnu2uw.js");
21
+ const { runCodexAppServerAttempt } = await import("./run-attempt-Mn4zlbBO.js");
22
22
  return runCodexAppServerAttempt(params, {
23
23
  pluginConfig: options?.pluginConfig,
24
24
  nativeHookRelay: { enabled: true }
25
25
  });
26
26
  },
27
27
  runSideQuestion: async (params) => {
28
- const { runCodexAppServerSideQuestion } = await import("./side-question-DgVgwmjR.js");
28
+ const { runCodexAppServerSideQuestion } = await import("./side-question-D8VnF9iq.js");
29
29
  return runCodexAppServerSideQuestion(params, {
30
30
  pluginConfig: options?.pluginConfig,
31
31
  nativeHookRelay: { enabled: true }
@@ -7,7 +7,7 @@ import { d as resolveCodexUsageLimitResetAtMs, f as shouldRefreshCodexRateLimits
7
7
  import { c as resolveCodexAppServerAuthAccountCacheKey, d as resolveCodexAppServerEnvApiKeyCacheKey, f as resolveCodexAppServerHomeDir, l as resolveCodexAppServerAuthProfileId, s as refreshCodexAppServerAuthTokens, t as clearSharedCodexAppServerClientIfCurrent, u as resolveCodexAppServerAuthProfileIdForAgent } from "./shared-client-DlvmoLBJ.js";
8
8
  import { i as readCodexAppServerBinding, t as clearCodexAppServerBinding } from "./session-binding-DqApZIgD.js";
9
9
  import { a as defaultCodexAppInventoryCache } from "./plugin-activation-B49xb7pI.js";
10
- import { C as isForcedPrivateQaCodexRuntime, S as filterCodexDynamicTools, T as resolveCodexDynamicToolsLoading, _ as projectContextEngineAssemblyForCodex, b as createCodexDynamicToolBridge, c as codexDynamicToolsFingerprint, f as startOrResumeThread, g as shouldBuildCodexPluginThreadConfig, h as mergeCodexThreadConfigs, i as buildDeveloperInstructions, l as isContextEngineBindingCompatible, m as buildCodexPluginThreadConfigInputFingerprint, p as buildCodexPluginThreadConfig, r as buildContextEngineBinding, s as buildTurnStartParams, t as areCodexDynamicToolFingerprintsCompatible, v as resolveCodexContextEngineProjectionMaxChars, w as normalizeCodexDynamicToolName, x as sanitizeCodexHistoryImagePayloads, y as resolveCodexContextEngineProjectionReserveTokens } from "./thread-lifecycle-BbriKhTq.js";
10
+ import { C as isForcedPrivateQaCodexRuntime, S as filterCodexDynamicTools, T as resolveCodexDynamicToolsLoading, _ as projectContextEngineAssemblyForCodex, b as createCodexDynamicToolBridge, c as codexDynamicToolsFingerprint, f as startOrResumeThread, g as shouldBuildCodexPluginThreadConfig, h as mergeCodexThreadConfigs, i as buildDeveloperInstructions, l as isContextEngineBindingCompatible, m as buildCodexPluginThreadConfigInputFingerprint, p as buildCodexPluginThreadConfig, r as buildContextEngineBinding, s as buildTurnStartParams, t as areCodexDynamicToolFingerprintsCompatible, v as resolveCodexContextEngineProjectionMaxChars, w as normalizeCodexDynamicToolName, x as sanitizeCodexHistoryImagePayloads, y as resolveCodexContextEngineProjectionReserveTokens } from "./thread-lifecycle-Czx7CGwZ.js";
11
11
  import { t as defaultCodexAppServerClientFactory } from "./client-factory-9L6Ie1dC.js";
12
12
  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";
13
13
  import { t as ensureCodexComputerUse } from "./computer-use-UJ3dxrXF.js";
@@ -21,7 +21,7 @@ import { markAuthProfileBlockedUntil, resolveAgentDir as resolveAgentDir$1 } fro
21
21
  import { appendRegularFile, pathExists } from "openclaw/plugin-sdk/security-runtime";
22
22
  import { redactSensitiveFieldValue, redactToolPayloadText } from "openclaw/plugin-sdk/logging-core";
23
23
  import { emitTrustedDiagnosticEvent } from "openclaw/plugin-sdk/diagnostic-runtime";
24
- import { createRunningTaskRun, finalizeTaskRunByRunId, recordTaskRunProgressByRunId } from "openclaw/plugin-sdk/codex-native-task-runtime";
24
+ import { CODEX_NATIVE_SUBAGENT_RUNTIME, CODEX_NATIVE_SUBAGENT_RUN_ID_PREFIX, CODEX_NATIVE_SUBAGENT_TASK_KIND, createRunningTaskRun, finalizeTaskRunByRunId, recordTaskRunProgressByRunId } from "openclaw/plugin-sdk/codex-native-task-runtime";
25
25
  import { buildSessionContext, migrateSessionEntries, parseSessionEntries } from "@earendil-works/pi-coding-agent";
26
26
  //#region extensions/codex/src/app-server/local-runtime-attribution.ts
27
27
  const OPENAI_PROVIDER_ID = "openai";
@@ -44,8 +44,6 @@ function resolveCodexLocalRuntimeAttribution(params) {
44
44
  }
45
45
  //#endregion
46
46
  //#region extensions/codex/src/app-server/native-subagent-task-mirror.ts
47
- const CODEX_NATIVE_SUBAGENT_RUNTIME = "subagent";
48
- const CODEX_NATIVE_SUBAGENT_TASK_KIND = "codex-native";
49
47
  const defaultRuntime = {
50
48
  createRunningTaskRun,
51
49
  recordTaskRunProgressByRunId,
@@ -239,7 +237,7 @@ var CodexNativeSubagentTaskMirror = class {
239
237
  }
240
238
  };
241
239
  function codexNativeSubagentRunId(threadId) {
242
- return `codex-thread:${threadId.trim()}`;
240
+ return `${CODEX_NATIVE_SUBAGENT_RUN_ID_PREFIX}${threadId.trim()}`;
243
241
  }
244
242
  function readSubagentThreadSpawnSource(source, parentThreadId) {
245
243
  if (!source || typeof source !== "object" || !("subAgent" in source)) return;
@@ -535,6 +533,19 @@ const CODEX_PROMPT_TOTAL_INPUT_KEYS = [
535
533
  ];
536
534
  const MAX_TOOL_OUTPUT_DELTA_MESSAGES_PER_ITEM = 20;
537
535
  const TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS = 12e3;
536
+ const TRANSCRIPT_PROGRESS_SUPPRESSED_TOOL_NAMES = new Set([
537
+ "message",
538
+ "messages",
539
+ "reply",
540
+ "send",
541
+ "reaction",
542
+ "react",
543
+ "typing"
544
+ ]);
545
+ function shouldEmitTranscriptToolProgress(toolName, args) {
546
+ const normalized = typeof toolName === "string" ? toolName.trim().toLowerCase() : "";
547
+ return Boolean(normalized && !TRANSCRIPT_PROGRESS_SUPPRESSED_TOOL_NAMES.has(normalized) && !isActivityLogCommandProgress(normalized, args));
548
+ }
538
549
  var CodexAppServerEventProjector = class {
539
550
  constructor(params, threadId, turnId, options = {}) {
540
551
  this.params = params;
@@ -554,11 +565,15 @@ var CodexAppServerEventProjector = class {
554
565
  this.toolResultSummaryItemIds = /* @__PURE__ */ new Set();
555
566
  this.toolResultOutputItemIds = /* @__PURE__ */ new Set();
556
567
  this.toolResultOutputStreamedItemIds = /* @__PURE__ */ new Set();
568
+ this.transcriptToolProgressSuppressedIds = /* @__PURE__ */ new Set();
569
+ this.toolTranscriptArgumentsById = /* @__PURE__ */ new Map();
557
570
  this.toolResultOutputDeltaState = /* @__PURE__ */ new Map();
571
+ this.toolResultOutputTextByItem = /* @__PURE__ */ new Map();
558
572
  this.toolMetas = /* @__PURE__ */ new Map();
559
573
  this.toolTranscriptMessages = [];
560
574
  this.toolTranscriptCallIds = /* @__PURE__ */ new Set();
561
575
  this.toolTranscriptResultIds = /* @__PURE__ */ new Set();
576
+ this.transcriptToolProgressCallIds = /* @__PURE__ */ new Set();
562
577
  this.nativeGeneratedMediaUrls = /* @__PURE__ */ new Set();
563
578
  this.diagnosticToolStartedAtByItem = /* @__PURE__ */ new Map();
564
579
  this.afterToolCallObservedItemIds = /* @__PURE__ */ new Set();
@@ -683,6 +698,7 @@ var CodexAppServerEventProjector = class {
683
698
  assistantTexts,
684
699
  toolMetas: [...this.toolMetas.values()],
685
700
  lastAssistant,
701
+ ...this.lastNativeToolError ? { lastToolError: this.lastNativeToolError } : {},
686
702
  didSendViaMessagingTool: toolTelemetry.didSendViaMessagingTool,
687
703
  messagingToolSentTexts: toolTelemetry.messagingToolSentTexts,
688
704
  messagingToolSentMediaUrls: toolTelemetry.messagingToolSentMediaUrls,
@@ -1030,7 +1046,10 @@ var CodexAppServerEventProjector = class {
1030
1046
  handleOutputDelta(params, toolName) {
1031
1047
  const itemId = readString$2(params, "itemId");
1032
1048
  const delta = readString$2(params, "delta");
1033
- if (!itemId || !delta || !this.shouldEmitToolOutput()) return;
1049
+ if (!itemId || !delta) return;
1050
+ appendToolOutputDeltaText(this.toolResultOutputTextByItem, itemId, delta);
1051
+ if (!this.shouldEmitToolOutput()) return;
1052
+ if (this.transcriptToolProgressSuppressedIds.has(itemId) || !shouldEmitTranscriptToolProgress(toolName, this.toolTranscriptArgumentsById.get(itemId))) return;
1034
1053
  const state = this.toolResultOutputDeltaState.get(itemId) ?? {
1035
1054
  chars: 0,
1036
1055
  messages: 0,
@@ -1153,9 +1172,9 @@ var CodexAppServerEventProjector = class {
1153
1172
  if (!item || !shouldSynthesizeToolProgressForItem(item)) return;
1154
1173
  const name = itemName(item);
1155
1174
  if (!name) return;
1156
- const meta = itemMeta(item, this.toolProgressDetailMode());
1157
- const args = params.phase === "start" ? itemToolArgs(item) : void 0;
1158
1175
  const status = params.phase === "result" ? itemStatus(item) : "running";
1176
+ const args = itemToolArgs(item);
1177
+ const meta = itemMeta(item, this.toolProgressDetailMode());
1159
1178
  this.recordToolTrajectoryEvent({
1160
1179
  phase: params.phase,
1161
1180
  item,
@@ -1169,6 +1188,16 @@ var CodexAppServerEventProjector = class {
1169
1188
  name,
1170
1189
  status
1171
1190
  });
1191
+ if (params.phase === "result") this.recordNativeToolError({
1192
+ item,
1193
+ name,
1194
+ meta,
1195
+ status
1196
+ });
1197
+ if (!shouldEmitTranscriptToolProgress(name, args)) {
1198
+ if (params.phase === "result") this.emitAfterToolCallObservation(item);
1199
+ return;
1200
+ }
1172
1201
  this.emitAgentEvent({
1173
1202
  stream: "tool",
1174
1203
  data: {
@@ -1177,7 +1206,7 @@ var CodexAppServerEventProjector = class {
1177
1206
  itemId: item.id,
1178
1207
  toolCallId: item.id,
1179
1208
  ...meta ? { meta } : {},
1180
- ...args ? { args } : {},
1209
+ ...params.phase === "start" && args ? { args } : {},
1181
1210
  ...params.phase === "result" ? {
1182
1211
  status,
1183
1212
  isError: isNonSuccessItemStatus(status),
@@ -1187,6 +1216,27 @@ var CodexAppServerEventProjector = class {
1187
1216
  });
1188
1217
  if (params.phase === "result") this.emitAfterToolCallObservation(item);
1189
1218
  }
1219
+ recordNativeToolError(params) {
1220
+ if (!isNonSuccessItemStatus(params.status)) {
1221
+ if (!this.lastNativeToolError) return;
1222
+ if (!this.lastNativeToolError.mutatingAction) {
1223
+ this.lastNativeToolError = void 0;
1224
+ return;
1225
+ }
1226
+ const actionFingerprint = nativeToolActionFingerprint(params.item);
1227
+ if (this.lastNativeToolError.actionFingerprint && actionFingerprint && this.lastNativeToolError.actionFingerprint === actionFingerprint) this.lastNativeToolError = void 0;
1228
+ return;
1229
+ }
1230
+ const error = itemToolError(params.item, params.status, this.toolResultOutputTextByItem);
1231
+ const actionFingerprint = nativeToolActionFingerprint(params.item);
1232
+ this.lastNativeToolError = {
1233
+ toolName: params.name,
1234
+ ...params.meta ? { meta: params.meta } : {},
1235
+ ...error ? { error } : {},
1236
+ ...isMutatingNativeToolItem(params.item) ? { mutatingAction: true } : {},
1237
+ ...actionFingerprint ? { actionFingerprint } : {}
1238
+ };
1239
+ }
1190
1240
  recordToolTrajectoryEvent(params) {
1191
1241
  if (params.phase === "start") {
1192
1242
  this.options.trajectoryRecorder?.recordEvent("tool.call", {
@@ -1200,7 +1250,7 @@ var CodexAppServerEventProjector = class {
1200
1250
  return;
1201
1251
  }
1202
1252
  const toolResult = itemToolResult(params.item).result;
1203
- const output = itemOutputText(params.item);
1253
+ const output = itemOutputText(params.item, this.toolResultOutputTextByItem);
1204
1254
  this.options.trajectoryRecorder?.recordEvent("tool.result", {
1205
1255
  threadId: this.threadId,
1206
1256
  turnId: this.turnId,
@@ -1257,7 +1307,7 @@ var CodexAppServerEventProjector = class {
1257
1307
  if (status === "running") return;
1258
1308
  this.afterToolCallObservedItemIds.add(item.id);
1259
1309
  const result = itemToolResult(item).result;
1260
- const error = itemToolError(item, status);
1310
+ const error = itemToolError(item, status, this.toolResultOutputTextByItem);
1261
1311
  const startedAt = typeof item.durationMs === "number" ? Date.now() - Math.max(0, item.durationMs) : void 0;
1262
1312
  const hookParams = {
1263
1313
  toolName: name,
@@ -1286,6 +1336,7 @@ var CodexAppServerEventProjector = class {
1286
1336
  if (this.toolResultSummaryItemIds.has(itemId)) return;
1287
1337
  const toolName = itemName(item);
1288
1338
  if (!toolName) return;
1339
+ if (!shouldEmitTranscriptToolProgress(toolName, itemToolArgs(item))) return;
1289
1340
  this.toolResultSummaryItemIds.add(itemId);
1290
1341
  const meta = itemMeta(item, this.toolProgressDetailMode());
1291
1342
  this.emitToolResultMessage({
@@ -1299,8 +1350,9 @@ var CodexAppServerEventProjector = class {
1299
1350
  if (this.toolResultOutputItemIds.has(itemId)) return;
1300
1351
  if (this.toolResultOutputStreamedItemIds.has(itemId)) return;
1301
1352
  const toolName = itemName(item);
1302
- const output = itemOutputText(item);
1353
+ const output = itemOutputText(item, this.toolResultOutputTextByItem);
1303
1354
  if (!toolName || !output) return;
1355
+ if (!shouldEmitTranscriptToolProgress(toolName, itemToolArgs(item))) return;
1304
1356
  this.emitToolResultMessage({
1305
1357
  itemId,
1306
1358
  text: formatToolOutput(toolName, itemMeta(item, this.toolProgressDetailMode()), output),
@@ -1352,20 +1404,53 @@ var CodexAppServerEventProjector = class {
1352
1404
  this.recordToolTranscriptResult({
1353
1405
  id: item.id,
1354
1406
  name,
1355
- text: itemTranscriptResultText(item),
1407
+ text: itemTranscriptResultText(item, this.toolResultOutputTextByItem),
1356
1408
  isError: isNonSuccessItemStatus(itemStatus(item))
1357
1409
  });
1358
1410
  }
1359
1411
  recordToolTranscriptCall(params) {
1360
1412
  if (!params.id || !params.name || this.toolTranscriptCallIds.has(params.id)) return;
1361
1413
  this.toolTranscriptCallIds.add(params.id);
1414
+ this.toolTranscriptArgumentsById.set(params.id, params.arguments);
1415
+ if (!shouldEmitTranscriptToolProgress(params.name, params.arguments)) this.transcriptToolProgressSuppressedIds.add(params.id);
1416
+ else this.transcriptToolProgressSuppressedIds.delete(params.id);
1417
+ this.emitTranscriptToolCallProgress(params);
1362
1418
  this.toolTranscriptMessages.push(attachCodexMirrorIdentity(this.createToolCallMessage(params), `${this.turnId}:tool:${params.id}:call`));
1363
1419
  }
1364
1420
  recordToolTranscriptResult(params) {
1365
1421
  if (!params.id || !params.name || this.toolTranscriptResultIds.has(params.id)) return;
1366
1422
  this.toolTranscriptResultIds.add(params.id);
1423
+ this.emitTranscriptToolResultProgress(params);
1367
1424
  this.toolTranscriptMessages.push(attachCodexMirrorIdentity(this.createToolResultMessage(params), `${this.turnId}:tool:${params.id}:result`));
1368
1425
  }
1426
+ emitTranscriptToolCallProgress(params) {
1427
+ if (!shouldEmitTranscriptToolProgress(params.name, params.arguments)) return;
1428
+ this.transcriptToolProgressCallIds.add(params.id);
1429
+ const args = normalizeToolTranscriptArguments(params.arguments);
1430
+ const meta = inferToolMetaFromArgs(params.name, args, { detailMode: this.toolProgressDetailMode() });
1431
+ if (!this.params.onToolResult || !this.shouldEmitToolResult() || this.toolResultSummaryItemIds.has(params.id) || this.toolResultOutputStreamedItemIds.has(params.id)) return;
1432
+ this.toolResultSummaryItemIds.add(params.id);
1433
+ this.emitToolResultMessage({
1434
+ itemId: params.id,
1435
+ text: formatToolSummary(params.name, meta)
1436
+ });
1437
+ }
1438
+ emitTranscriptToolResultProgress(params) {
1439
+ if (this.transcriptToolProgressSuppressedIds.has(params.id) || !shouldEmitTranscriptToolProgress(params.name, this.toolTranscriptArgumentsById.get(params.id))) return;
1440
+ if (!this.transcriptToolProgressCallIds.has(params.id)) this.emitTranscriptToolCallProgress({
1441
+ id: params.id,
1442
+ name: params.name,
1443
+ arguments: {}
1444
+ });
1445
+ if (!this.params.onToolResult || !this.shouldEmitToolOutput() || this.toolResultOutputItemIds.has(params.id) || this.toolResultOutputStreamedItemIds.has(params.id)) return;
1446
+ const text = params.text?.trim();
1447
+ if (!text) return;
1448
+ this.emitToolResultMessage({
1449
+ itemId: params.id,
1450
+ text: formatToolOutput(params.name, void 0, text),
1451
+ finalOutput: true
1452
+ });
1453
+ }
1369
1454
  formatCodexErrorMessage(params) {
1370
1455
  const error = isJsonObject(params.error) ? params.error : void 0;
1371
1456
  return formatCodexUsageLimitErrorMessage({
@@ -1669,6 +1754,20 @@ function shouldSynthesizeToolProgressForItem(item) {
1669
1754
  default: return false;
1670
1755
  }
1671
1756
  }
1757
+ function isMutatingNativeToolItem(item) {
1758
+ return item.type === "commandExecution" || item.type === "fileChange";
1759
+ }
1760
+ function nativeToolActionFingerprint(item) {
1761
+ if (item.type === "commandExecution" && typeof item.command === "string") return JSON.stringify({
1762
+ type: item.type,
1763
+ command: item.command,
1764
+ cwd: typeof item.cwd === "string" ? item.cwd : ""
1765
+ });
1766
+ if (item.type === "fileChange") return JSON.stringify({
1767
+ type: item.type,
1768
+ changes: itemFileChanges(item)
1769
+ });
1770
+ }
1672
1771
  function isNativePostToolUseRelayItem(item) {
1673
1772
  switch (item.type) {
1674
1773
  case "commandExecution":
@@ -1715,10 +1814,10 @@ function itemFileChanges(item) {
1715
1814
  kind: change.kind
1716
1815
  })) : [];
1717
1816
  }
1718
- function itemToolError(item, status) {
1817
+ function itemToolError(item, status, outputTextByItem) {
1719
1818
  if (status === "blocked") return "codex native tool blocked";
1720
1819
  if (status !== "failed") return;
1721
- return itemOutputText(item) ?? "codex native tool failed";
1820
+ return itemOutputText(item, outputTextByItem) ?? "codex native tool failed";
1722
1821
  }
1723
1822
  function itemMeta(item, detailMode = "explain") {
1724
1823
  if (item.type === "commandExecution" && typeof item.command === "string") return inferToolMetaFromArgs("exec", {
@@ -1729,24 +1828,50 @@ function itemMeta(item, detailMode = "explain") {
1729
1828
  const toolName = itemName(item);
1730
1829
  if ((item.type === "dynamicToolCall" || item.type === "mcpToolCall") && toolName) return inferToolMetaFromArgs(toolName, item.arguments, { detailMode });
1731
1830
  }
1732
- function itemOutputText(item) {
1733
- if (item.type === "commandExecution") return item.aggregatedOutput?.trim() || void 0;
1831
+ function itemOutputText(item, outputTextByItem) {
1832
+ if (item.type === "commandExecution") return item.aggregatedOutput?.trim() || outputTextByItem?.get(item.id)?.trim() || void 0;
1734
1833
  if (item.type === "dynamicToolCall") return collectDynamicToolContentText(item.contentItems).trim() || void 0;
1735
1834
  if (item.type === "mcpToolCall") {
1736
1835
  if (item.error) return stringifyJsonValue(item.error);
1737
1836
  return item.result ? stringifyJsonValue(item.result) : void 0;
1738
1837
  }
1739
1838
  }
1740
- function itemTranscriptResultText(item) {
1741
- const output = itemOutputText(item);
1839
+ function itemTranscriptResultText(item, outputTextByItem) {
1840
+ const output = itemOutputText(item, outputTextByItem);
1742
1841
  if (output) return output;
1743
1842
  const result = itemToolResult(item).result;
1744
1843
  return result ? stringifyJsonValue(result) : itemStatus(item);
1745
1844
  }
1845
+ function appendToolOutputDeltaText(outputTextByItem, itemId, delta) {
1846
+ const current = outputTextByItem.get(itemId) ?? "";
1847
+ if (current.length >= TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS) return;
1848
+ const remaining = TOOL_TRANSCRIPT_OUTPUT_MAX_CHARS - current.length;
1849
+ const next = current + (delta.length > remaining ? delta.slice(0, remaining) : delta);
1850
+ outputTextByItem.set(itemId, next);
1851
+ }
1746
1852
  function normalizeToolTranscriptArguments(value) {
1747
1853
  if (!value || typeof value !== "object" || Array.isArray(value)) return {};
1748
1854
  return value;
1749
1855
  }
1856
+ function isActivityLogCommandProgress(toolName, args) {
1857
+ if (toolName !== "bash" && toolName !== "exec" && toolName !== "shell") return false;
1858
+ const command = readToolCommandText(args);
1859
+ return Boolean(command && command.includes("log_activity.sh"));
1860
+ }
1861
+ function readToolCommandText(value) {
1862
+ if (typeof value === "string") return value;
1863
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
1864
+ const record = value;
1865
+ for (const key of [
1866
+ "command",
1867
+ "cmd",
1868
+ "shellCommand",
1869
+ "script"
1870
+ ]) {
1871
+ const text = record[key];
1872
+ if (typeof text === "string" && text) return text;
1873
+ }
1874
+ }
1750
1875
  function collectDynamicToolContentText(contentItems) {
1751
1876
  if (!Array.isArray(contentItems)) return "";
1752
1877
  return contentItems.flatMap((entry) => {
@@ -2631,6 +2756,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
2631
2756
  disableTools: params.disableTools,
2632
2757
  toolsAllow: params.toolsAllow
2633
2758
  });
2759
+ const nativeToolSurfaceEnabled = shouldEnableCodexAppServerNativeToolSurface(params);
2634
2760
  for (const diagnostic of bundleMcpThreadConfig.diagnostics) embeddedAgentLog.warn(`bundle-mcp: ${diagnostic.pluginId}: ${diagnostic.message}`);
2635
2761
  const activeContextEngine = isActiveHarnessContextEngine(params.contextEngine) ? params.contextEngine : void 0;
2636
2762
  const hookChannelId = resolveCodexAppServerHookChannelId(params, sandboxSessionKey);
@@ -2852,7 +2978,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
2852
2978
  hookTimeoutSec: options.nativeHookRelay?.hookTimeoutSec
2853
2979
  }) : options.nativeHookRelay?.enabled === false ? buildCodexNativeHookRelayDisabledConfig() : void 0;
2854
2980
  const threadConfig = mergeCodexThreadConfigs(bundleMcpThreadConfig?.configPatch);
2855
- const pluginThreadConfigEnabled = shouldBuildCodexPluginThreadConfig(pluginConfig);
2981
+ const pluginThreadConfigRequired = !nativeToolSurfaceEnabled || shouldBuildCodexPluginThreadConfig(pluginConfig);
2982
+ const pluginThreadConfigPluginConfig = nativeToolSurfaceEnabled ? pluginConfig : disableCodexPluginThreadConfig(pluginConfig);
2856
2983
  const pluginAppCacheKey = buildCodexPluginAppCacheKey({
2857
2984
  appServer,
2858
2985
  agentDir,
@@ -2860,11 +2987,11 @@ async function runCodexAppServerAttempt(params, options = {}) {
2860
2987
  accountId: startupAuthAccountCacheKey,
2861
2988
  envApiKeyFingerprint: startupEnvApiKeyCacheKey
2862
2989
  });
2863
- const pluginThreadConfigInputFingerprint = pluginThreadConfigEnabled ? buildCodexPluginThreadConfigInputFingerprint({
2864
- pluginConfig,
2990
+ const pluginThreadConfigInputFingerprint = pluginThreadConfigRequired ? buildCodexPluginThreadConfigInputFingerprint({
2991
+ pluginConfig: pluginThreadConfigPluginConfig,
2865
2992
  appCacheKey: pluginAppCacheKey
2866
2993
  }) : void 0;
2867
- const resolvedPluginPolicy = pluginThreadConfigEnabled ? resolveCodexPluginsPolicy(pluginConfig) : void 0;
2994
+ const resolvedPluginPolicy = pluginThreadConfigRequired ? resolveCodexPluginsPolicy(pluginThreadConfigPluginConfig) : void 0;
2868
2995
  const enabledPluginConfigKeys = resolvedPluginPolicy ? resolvedPluginPolicy.pluginPolicies.filter((plugin) => plugin.enabled).map((plugin) => plugin.configKey).toSorted() : void 0;
2869
2996
  pluginAppServer = resolvedPluginPolicy?.enabled === true ? {
2870
2997
  ...appServer,
@@ -2895,15 +3022,17 @@ async function runCodexAppServerAttempt(params, options = {}) {
2895
3022
  developerInstructions: promptBuild.developerInstructions,
2896
3023
  config: threadConfig,
2897
3024
  finalConfigPatch: nativeHookRelayConfig,
3025
+ nativeCodeModeEnabled: nativeToolSurfaceEnabled,
3026
+ userMcpServersEnabled: nativeToolSurfaceEnabled,
2898
3027
  mcpServersFingerprint: bundleMcpThreadConfig.fingerprint,
2899
3028
  mcpServersFingerprintEvaluated: bundleMcpThreadConfig.evaluated,
2900
3029
  contextEngineProjection,
2901
- pluginThreadConfig: pluginThreadConfigEnabled ? {
3030
+ pluginThreadConfig: pluginThreadConfigRequired ? {
2902
3031
  enabled: true,
2903
3032
  inputFingerprint: pluginThreadConfigInputFingerprint,
2904
3033
  enabledPluginConfigKeys,
2905
3034
  build: () => buildCodexPluginThreadConfig({
2906
- pluginConfig,
3035
+ pluginConfig: pluginThreadConfigPluginConfig,
2907
3036
  request: (method, requestParams) => startupClient.request(method, requestParams, {
2908
3037
  timeoutMs: appServer.requestTimeoutMs,
2909
3038
  signal: runAbortController.signal
@@ -3482,7 +3611,8 @@ async function runCodexAppServerAttempt(params, options = {}) {
3482
3611
  });
3483
3612
  const toolMeta = inferCodexDynamicToolMeta(call, resolveCodexToolProgressDetailMode(params.toolProgressDetail));
3484
3613
  const toolArgs = sanitizeCodexToolArguments(call.arguments);
3485
- emitCodexAppServerEvent(params, {
3614
+ const shouldEmitDynamicToolProgress = shouldEmitTranscriptToolProgress(call.tool, toolArgs);
3615
+ if (shouldEmitDynamicToolProgress) emitCodexAppServerEvent(params, {
3486
3616
  stream: "tool",
3487
3617
  data: {
3488
3618
  phase: "start",
@@ -3525,7 +3655,7 @@ async function runCodexAppServerAttempt(params, options = {}) {
3525
3655
  success: response.success,
3526
3656
  contentItems: response.contentItems
3527
3657
  });
3528
- emitCodexAppServerEvent(params, {
3658
+ if (shouldEmitDynamicToolProgress) emitCodexAppServerEvent(params, {
3529
3659
  stream: "tool",
3530
3660
  data: {
3531
3661
  phase: "result",
@@ -4332,16 +4462,35 @@ async function buildDynamicTools(input) {
4332
4462
  });
4333
4463
  }
4334
4464
  function includeForcedMessageToolAllow(toolsAllow, params) {
4335
- if (!shouldForceMessageTool(params)) return toolsAllow;
4336
- if (toolsAllow === void 0) return toolsAllow;
4465
+ if (!shouldForceMessageTool(params) || toolsAllow === void 0 || hasWildcardCodexToolsAllow(toolsAllow)) return toolsAllow;
4337
4466
  if (toolsAllow.length === 0) return ["message"];
4338
4467
  return new Set(toolsAllow.map((name) => normalizeCodexDynamicToolName(name))).has("message") ? toolsAllow : [...toolsAllow, "message"];
4339
4468
  }
4469
+ function shouldEnableCodexAppServerNativeToolSurface(params) {
4470
+ const toolsAllow = includeForcedMessageToolAllow(params.toolsAllow, params);
4471
+ if (toolsAllow === void 0) return true;
4472
+ return hasWildcardCodexToolsAllow(toolsAllow);
4473
+ }
4474
+ function disableCodexPluginThreadConfig(pluginConfig) {
4475
+ const config = readCodexPluginConfig(pluginConfig);
4476
+ return {
4477
+ ...config,
4478
+ codexPlugins: {
4479
+ ...config.codexPlugins,
4480
+ enabled: false
4481
+ }
4482
+ };
4483
+ }
4340
4484
  function filterCodexDynamicToolsForAllowlist(tools, toolsAllow) {
4341
- if (!toolsAllow || toolsAllow.length === 0) return tools;
4485
+ if (!toolsAllow) return tools;
4486
+ if (toolsAllow.length === 0) return [];
4487
+ if (hasWildcardCodexToolsAllow(toolsAllow)) return tools;
4342
4488
  const allowSet = new Set(toolsAllow.map((name) => normalizeCodexDynamicToolName(name)).filter(Boolean));
4343
4489
  return tools.filter((tool) => allowSet.has(normalizeCodexDynamicToolName(tool.name)));
4344
4490
  }
4491
+ function hasWildcardCodexToolsAllow(toolsAllow) {
4492
+ return toolsAllow.some((name) => normalizeCodexDynamicToolName(name) === "*");
4493
+ }
4345
4494
  function shouldForceMessageTool(params) {
4346
4495
  return params.sourceReplyDeliveryMode === "message_tool_only";
4347
4496
  }
@@ -5,7 +5,7 @@ import { r as isCodexAppServerApprovalRequest } from "./client-6FkrXfaz.js";
5
5
  import { u as formatCodexUsageLimitErrorMessage } from "./command-formatters-BRW7_Nu7.js";
6
6
  import { i as getSharedCodexAppServerClient, s as refreshCodexAppServerAuthTokens } from "./shared-client-DlvmoLBJ.js";
7
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-BbriKhTq.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-Czx7CGwZ.js";
9
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";
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";
package/dist/test-api.js CHANGED
@@ -1,5 +1,5 @@
1
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-BbriKhTq.js";
2
+ import { S as filterCodexDynamicTools, a as buildThreadResumeParams, b as createCodexDynamicToolBridge, i as buildDeveloperInstructions, o as buildThreadStartParams, s as buildTurnStartParams } from "./thread-lifecycle-Czx7CGwZ.js";
3
3
  //#region extensions/codex/test-api.ts
4
4
  function resolveCodexPromptSnapshotAppServerOptions(pluginConfig) {
5
5
  return resolveCodexAppServerRuntimeOptions({
@@ -569,7 +569,7 @@ function projectContextEngineAssemblyForCodex(params) {
569
569
  CONTEXT_SAFETY_NOTE,
570
570
  "",
571
571
  CONTEXT_OPEN,
572
- truncateText(renderedContext, maxRenderedContextChars),
572
+ truncateOlderContext(renderedContext, maxRenderedContextChars),
573
573
  CONTEXT_CLOSE,
574
574
  "",
575
575
  REQUEST_HEADER,
@@ -739,6 +739,17 @@ function resolveTextPartMaxChars(maxRenderedContextChars) {
739
739
  function truncateText(text, maxChars) {
740
740
  return text.length > maxChars ? `${text.slice(0, maxChars)}\n[truncated ${text.length - maxChars} chars]` : text;
741
741
  }
742
+ function truncateOlderContext(text, maxChars) {
743
+ if (text.length <= maxChars) return text;
744
+ if (maxChars <= 0) return "";
745
+ const buildMarker = (omittedChars) => `[truncated ${omittedChars} chars from older context]\n`;
746
+ let marker = buildMarker(text.length - maxChars);
747
+ let tailChars = Math.max(0, maxChars - marker.length);
748
+ marker = buildMarker(text.length - tailChars);
749
+ if (marker.length >= maxChars) return marker.slice(0, maxChars);
750
+ tailChars = maxChars - marker.length;
751
+ return `${marker}${text.slice(text.length - tailChars).trimStart()}`;
752
+ }
742
753
  //#endregion
743
754
  //#region extensions/codex/src/app-server/plugin-thread-config.ts
744
755
  const CODEX_PLUGIN_THREAD_CONFIG_INPUT_FINGERPRINT_VERSION = 1;
@@ -977,11 +988,15 @@ const CODEX_CODE_MODE_THREAD_CONFIG = {
977
988
  "features.code_mode": true,
978
989
  "features.code_mode_only": true
979
990
  };
991
+ const CODEX_CODE_MODE_DISABLED_THREAD_CONFIG = {
992
+ "features.code_mode": false,
993
+ "features.code_mode_only": false
994
+ };
980
995
  const CODEX_LIGHTWEIGHT_CONTEXT_THREAD_CONFIG = { project_doc_max_bytes: 0 };
981
996
  async function startOrResumeThread(params) {
982
997
  const dynamicToolsFingerprint = fingerprintDynamicTools(params.dynamicTools);
983
998
  const contextEngineBinding = buildContextEngineBinding(params.params, params.contextEngineProjection);
984
- const userMcpServersConfigPatch = buildCodexUserMcpServersThreadConfigPatch(params.params.config, { agentId: params.agentId ?? params.params.agentId });
999
+ const userMcpServersConfigPatch = params.userMcpServersEnabled === false ? void 0 : buildCodexUserMcpServersThreadConfigPatch(params.params.config, { agentId: params.agentId ?? params.params.agentId });
985
1000
  const userMcpServersFingerprint = fingerprintUserMcpServersConfigPatch(userMcpServersConfigPatch);
986
1001
  let binding = await readCodexAppServerBinding(params.params.sessionFile, {
987
1002
  authProfileStore: params.params.authProfileStore,
@@ -991,6 +1006,11 @@ async function startOrResumeThread(params) {
991
1006
  let preserveExistingBinding = false;
992
1007
  let rotatedContextEngineBinding = false;
993
1008
  let prebuiltPluginThreadConfig;
1009
+ if (binding?.threadId && params.nativeCodeModeEnabled === false) {
1010
+ embeddedAgentLog.debug("codex app-server native tool surface disabled for turn; starting transient thread", { threadId: binding.threadId });
1011
+ preserveExistingBinding = true;
1012
+ binding = void 0;
1013
+ }
994
1014
  if (binding?.threadId && (binding.contextEngine || contextEngineBinding)) {
995
1015
  if (!contextEngineBinding || !isContextEngineBindingCompatible(binding.contextEngine, contextEngineBinding)) {
996
1016
  embeddedAgentLog.debug("codex app-server context-engine binding changed; starting a new thread", {
@@ -1068,7 +1088,8 @@ async function startOrResumeThread(params) {
1068
1088
  authProfileId,
1069
1089
  appServer: params.appServer,
1070
1090
  developerInstructions: params.developerInstructions,
1071
- config: resumeConfig
1091
+ config: resumeConfig,
1092
+ nativeCodeModeEnabled: params.nativeCodeModeEnabled
1072
1093
  })));
1073
1094
  const boundAuthProfileId = authProfileId;
1074
1095
  const fallbackModelProvider = resolveCodexAppServerModelProvider({
@@ -1135,7 +1156,8 @@ async function startOrResumeThread(params) {
1135
1156
  dynamicTools: params.dynamicTools,
1136
1157
  appServer: params.appServer,
1137
1158
  developerInstructions: params.developerInstructions,
1138
- config
1159
+ config,
1160
+ nativeCodeModeEnabled: params.nativeCodeModeEnabled
1139
1161
  })));
1140
1162
  const modelProvider = resolveCodexAppServerModelProvider({
1141
1163
  provider: params.params.provider,
@@ -1276,7 +1298,8 @@ function buildThreadStartParams(params, options) {
1276
1298
  sandbox: options.appServer.sandbox,
1277
1299
  ...options.appServer.serviceTier ? { serviceTier: options.appServer.serviceTier } : {},
1278
1300
  serviceName: "OpenClaw",
1279
- config: buildCodexRuntimeThreadConfigForRun(params, options.config),
1301
+ config: buildCodexRuntimeThreadConfigForRun(params, options.config, { nativeCodeModeEnabled: options.nativeCodeModeEnabled }),
1302
+ ...options.nativeCodeModeEnabled === false ? { environments: [] } : {},
1280
1303
  developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params),
1281
1304
  dynamicTools: options.dynamicTools,
1282
1305
  experimentalRawEvents: true,
@@ -1299,16 +1322,17 @@ function buildThreadResumeParams(params, options) {
1299
1322
  approvalsReviewer: options.appServer.approvalsReviewer,
1300
1323
  sandbox: options.appServer.sandbox,
1301
1324
  ...options.appServer.serviceTier ? { serviceTier: options.appServer.serviceTier } : {},
1302
- config: buildCodexRuntimeThreadConfigForRun(params, options.config),
1325
+ config: buildCodexRuntimeThreadConfigForRun(params, options.config, { nativeCodeModeEnabled: options.nativeCodeModeEnabled }),
1303
1326
  developerInstructions: options.developerInstructions ?? buildDeveloperInstructions(params),
1304
1327
  persistExtendedHistory: true
1305
1328
  };
1306
1329
  }
1307
- function buildCodexRuntimeThreadConfig(config) {
1308
- return mergeCodexThreadConfigs(config, CODEX_CODE_MODE_THREAD_CONFIG) ?? { ...CODEX_CODE_MODE_THREAD_CONFIG };
1330
+ function buildCodexRuntimeThreadConfig(config, options = {}) {
1331
+ const codeModeConfig = options.nativeCodeModeEnabled === false ? CODEX_CODE_MODE_DISABLED_THREAD_CONFIG : CODEX_CODE_MODE_THREAD_CONFIG;
1332
+ return mergeCodexThreadConfigs(config, codeModeConfig) ?? { ...codeModeConfig };
1309
1333
  }
1310
- function buildCodexRuntimeThreadConfigForRun(params, config) {
1311
- const runtimeConfig = buildCodexRuntimeThreadConfig(config);
1334
+ function buildCodexRuntimeThreadConfigForRun(params, config, options = {}) {
1335
+ const runtimeConfig = buildCodexRuntimeThreadConfig(config, options);
1312
1336
  if (params.bootstrapContextMode !== "lightweight") return runtimeConfig;
1313
1337
  return mergeCodexThreadConfigs(runtimeConfig, CODEX_LIGHTWEIGHT_CONTEXT_THREAD_CONFIG) ?? {
1314
1338
  ...runtimeConfig,
@@ -1400,6 +1424,7 @@ function compareJsonFingerprint(left, right) {
1400
1424
  function buildDeveloperInstructions(params) {
1401
1425
  return [
1402
1426
  "Running inside OpenClaw. Use dynamic tools for messaging, cron, sessions, media, gateway, and nodes when available.",
1427
+ "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.",
1403
1428
  "Preserve channel/session context. Visible channel replies: use `message`, do not describe would-reply.",
1404
1429
  renderCodexRuntimePromptOverlay(params),
1405
1430
  params.extraSystemPrompt,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openclaw/codex",
3
- "version": "2026.5.16-beta.5",
3
+ "version": "2026.5.16-beta.7",
4
4
  "description": "OpenClaw Codex harness and model provider plugin",
5
5
  "repository": {
6
6
  "type": "git",
@@ -8,7 +8,7 @@
8
8
  },
9
9
  "type": "module",
10
10
  "dependencies": {
11
- "@earendil-works/pi-coding-agent": "0.74.1",
11
+ "@earendil-works/pi-coding-agent": "0.75.1",
12
12
  "@openai/codex": "0.130.0",
13
13
  "ajv": "8.20.0",
14
14
  "ws": "8.20.1",
@@ -27,10 +27,10 @@
27
27
  "minHostVersion": ">=2026.5.1-beta.1"
28
28
  },
29
29
  "compat": {
30
- "pluginApi": ">=2026.5.16-beta.5"
30
+ "pluginApi": ">=2026.5.16-beta.7"
31
31
  },
32
32
  "build": {
33
- "openclawVersion": "2026.5.16-beta.5"
33
+ "openclawVersion": "2026.5.16-beta.7"
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.16-beta.5"
48
+ "openclaw": ">=2026.5.16-beta.7"
49
49
  },
50
50
  "peerDependenciesMeta": {
51
51
  "openclaw": {