@openclaw/codex 2026.7.2-beta.7 → 2026.8.1-beta.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (68) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +147 -0
  3. package/dist/app-server-policy-bg5QPSVP.js +25 -0
  4. package/dist/attempt-client-cleanup-URjUlCHg.js +735 -0
  5. package/dist/binding-connection-DAvZwp96.js +45 -0
  6. package/dist/{bounded-turn-D2ZAgZVz.js → bounded-turn-4BjrZEwW.js} +63 -56
  7. package/dist/{capabilities-BFDTVYr4.js → capabilities-CH3K57v4.js} +8 -2
  8. package/dist/cli-metadata.js +1 -1
  9. package/dist/{command-formatters-C336eRVS.js → command-formatters-D0nZ3qtd.js} +18 -18
  10. package/dist/{command-handlers-DAHUSry9.js → command-handlers-DC86lgT4.js} +507 -101
  11. package/dist/command-rpc-xUIIonsO.js +90 -0
  12. package/dist/{compact-D_uvHurS.js → compact-COqgBRny.js} +234 -214
  13. package/dist/{session-binding-BXpo9ymA.js → config-CpNeo5AE.js} +284 -1163
  14. package/dist/context-compaction-activity-BOeJf7yo.js +58 -0
  15. package/dist/{conversation-binding-data-BHRpYbX3.js → conversation-binding-data-CW2GuupV.js} +6 -10
  16. package/dist/doctor-contract-api.js +48 -50
  17. package/dist/{dynamic-tools-D2gYkSBO.js → dynamic-tools-fJZhl4CE.js} +3442 -1433
  18. package/dist/{effective-mcp-catalog-Bbd98Inw.js → effective-mcp-catalog-4YKn51aG.js} +20 -15
  19. package/dist/elicitation-input-DMkeki8d.js +71 -0
  20. package/dist/{event-projector-assistant-message-DTgnPPVF.js → event-projector-assistant-message-BwxV4d6N.js} +11 -23
  21. package/dist/{attempt-notifications-AP-a-Q5k.js → event-projector-usage-CLwNEJqW.js} +113 -29
  22. package/dist/harness-DoKQcF8n.js +258 -0
  23. package/dist/harness.js +2 -160
  24. package/dist/image-payload-sanitizer-CnfoUPCE.js +65 -0
  25. package/dist/index.js +730 -256
  26. package/dist/isolated-completion-DPMtlH9r.js +75 -0
  27. package/dist/local-runtime-attribution-B_2mnqhb.js +19 -0
  28. package/dist/managed-binary-By4FZC6i.js +212 -0
  29. package/dist/media-understanding-provider.js +5 -5
  30. package/dist/model-catalog-CmGoqVKB.js +48 -0
  31. package/dist/{models-BBMKU4jA.js → models-CZw1wClT.js} +12 -17
  32. package/dist/native-subagent-monitor-GGq3RnOo.js +3225 -0
  33. package/dist/node-exec-server.runtime-Bsu1LdFZ.js +192 -0
  34. package/dist/{plugin-app-cache-key-DztPafOA.js → plugin-app-cache-key-DMNQ8Zi8.js} +18 -6
  35. package/dist/plugin-approval-roundtrip-C75Yiiwc.js +95 -0
  36. package/dist/plugin-marketplace-discovery-CSWDkMrP.js +399 -0
  37. package/dist/{computer-use-CYEc8U3w.js → plugin-metadata-cache-BXH5NF-4.js} +109 -6
  38. package/dist/protocol-validators-VAVyEnDp.js +2399 -0
  39. package/dist/{rate-limits-CU-gVCCS.js → rate-limits-BI1dMHDG.js} +17 -35
  40. package/dist/{request-qKh331yu.js → request-DSK0W6YI.js} +3 -3
  41. package/dist/{run-attempt-CY9WlDLc.js → run-attempt-BV3HzuCf.js} +3416 -7194
  42. package/dist/{runtime-artifact-CmtG_t1L.js → runtime-artifact-BvyT1uyd.js} +11 -29
  43. package/dist/{sandbox-guard-NuhpXmPB.js → sandbox-guard-C1qEeZ5C.js} +29 -30
  44. package/dist/session-binding-BTrLf9Qm.js +874 -0
  45. package/dist/{session-catalog-DyOgR4WH.js → session-catalog-ezP_UcRM.js} +1584 -1289
  46. package/dist/session-catalog-home-id-BNwAJ9D7.js +18 -0
  47. package/dist/{session-cli-2PZaFLRh.js → session-cli-B1hKvfkI.js} +20 -7
  48. package/dist/session-retirement-CE4iMiLh.js +36 -0
  49. package/dist/{session-upstream-marker-B6U7tLw5.js → session-upstream-marker-D_2npHlA.js} +1 -1
  50. package/dist/{settled-turn-finalizer-CXY2Z9dT.js → settled-turn-finalizer-Dx1onIqg.js} +40 -28
  51. package/dist/{shared-client-DTbvH-XV.js → shared-client-Dw-rzii0.js} +1315 -469
  52. package/dist/{side-question-_ulBk1AL.js → side-question-DbXkJZzg.js} +140 -69
  53. package/dist/{thread-lifecycle-DF53ogiA.js → thread-lifecycle-DKdrnTMX.js} +927 -768
  54. package/dist/thread-ownership-i2NBwDUL.js +92 -0
  55. package/dist/thread-resume-CdJk2Ehf.js +30 -0
  56. package/dist/transcript-mirror-BU0_LKAL.js +588 -0
  57. package/dist/{transport-stdio-DXgGZ7Ib.js → transport-stdio-DhoGy33Z.js} +13 -2
  58. package/dist/upstream-prompt-provenance-CFmsKwr9.js +39 -0
  59. package/dist/{upstream-session-fork-Dy4Xvuoj.js → upstream-session-fork-BDVJCLAD.js} +14 -8
  60. package/dist/{usage-CQ6GhD5-.js → usage-9dKJCgcy.js} +3 -3
  61. package/dist/{web-search-provider.runtime-CCFhg2z5.js → web-search-provider.runtime-DCdx4DGu.js} +8 -9
  62. package/openclaw.plugin.json +49 -4
  63. package/package.json +6 -5
  64. package/dist/app-server-policy-BSaO2JIT.js +0 -49
  65. package/dist/conversation-control-xsIeXbo4.js +0 -287
  66. package/dist/event-projector-usage-Xp4AlR2k.js +0 -86
  67. package/dist/notification-correlation-CU6_AnOb.js +0 -67
  68. package/dist/transcript-mirror-DzsdNCf5.js +0 -6924
@@ -1,25 +1,21 @@
1
- import { d as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-DTbvH-XV.js";
2
- import { d as sessionBindingIdentity } from "./session-binding-BXpo9ymA.js";
1
+ import { d as retainSharedCodexAppServerClientByInstanceId } from "./shared-client-Dw-rzii0.js";
2
+ import { d as sessionBindingIdentity } from "./session-binding-BTrLf9Qm.js";
3
+ import { asOptionalRecord, normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
3
4
  import { assignMcpCatalogSafeServerNames } from "openclaw/plugin-sdk/agent-harness-runtime";
4
5
  //#region extensions/codex/src/app-server/effective-mcp-catalog.ts
5
6
  const MCP_STATUS_PAGE_SIZE = 100;
6
7
  const MCP_STATUS_MAX_PAGES = 100;
7
- function asRecord(value) {
8
- return value && typeof value === "object" && !Array.isArray(value) ? value : void 0;
9
- }
10
- function readString(value) {
11
- return typeof value === "string" && value.trim() ? value.trim() : void 0;
12
- }
13
8
  function catalogTool(params) {
14
- const raw = asRecord(params.raw);
15
- const description = readString(raw?.description);
9
+ const raw = asOptionalRecord(params.raw);
10
+ const description = normalizeOptionalString(raw?.description);
11
+ const title = normalizeOptionalString(raw?.title);
16
12
  return {
17
13
  serverName: params.serverName,
18
14
  safeServerName: params.safeServerName,
19
15
  toolName: params.toolName,
20
- ...readString(raw?.title) ? { title: readString(raw?.title) } : {},
16
+ ...title ? { title } : {},
21
17
  ...description ? { description } : {},
22
- inputSchema: asRecord(raw?.inputSchema) ?? { type: "object" },
18
+ inputSchema: asOptionalRecord(raw?.inputSchema) ?? { type: "object" },
23
19
  fallbackDescription: description ?? params.toolName,
24
20
  ...params.deniedBySession ? { deniedBySession: true } : {}
25
21
  };
@@ -92,7 +88,12 @@ async function listCodexMcpServerStatuses(client, threadId) {
92
88
  }
93
89
  throw new Error("Codex mcpServerStatus/list exceeded the bounded page limit");
94
90
  }
95
- /** Loads MCP inventory only from the already-bound Codex process and thread. */
91
+ /** Loads the requested MCP inventory from the exact client/thread already selected for a run. */
92
+ async function loadCodexEffectiveMcpCatalogFromThread(params) {
93
+ const allowedServerNames = new Set(params.mcpServerNames);
94
+ return buildCodexEffectiveMcpCatalog((await listCodexMcpServerStatuses(params.client, params.threadId)).filter((status) => allowedServerNames.has(status.name)), params.toolOverrides);
95
+ }
96
+ /** Loads MCP inventory from the bound Codex client while retaining its lease through all pages. */
96
97
  async function loadCodexEffectiveMcpCatalog(params, options) {
97
98
  const binding = await options.bindingStore.read(sessionBindingIdentity({
98
99
  agentId: params.agentId,
@@ -104,8 +105,12 @@ async function loadCodexEffectiveMcpCatalog(params, options) {
104
105
  const retained = retainSharedCodexAppServerClientByInstanceId(binding.clientId);
105
106
  if (!retained) return;
106
107
  try {
107
- const allowedServerNames = new Set(params.mcpServerNames);
108
- return buildCodexEffectiveMcpCatalog((await listCodexMcpServerStatuses(retained.client, binding.threadId)).filter((status) => allowedServerNames.has(status.name)), params.toolOverrides);
108
+ return await loadCodexEffectiveMcpCatalogFromThread({
109
+ client: retained.client,
110
+ threadId: binding.threadId,
111
+ mcpServerNames: params.mcpServerNames,
112
+ toolOverrides: params.toolOverrides
113
+ });
109
114
  } finally {
110
115
  retained.release();
111
116
  }
@@ -0,0 +1,71 @@
1
+ import { agentHarnessStructuredInput } from "openclaw/plugin-sdk/agent-harness-runtime";
2
+ //#region extensions/codex/src/app-server/elicitation-input.ts
3
+ /** Snapshots and compiles ordinary Codex input before it enters the per-turn queue. */
4
+ function compileCodexOrdinaryElicitation(params) {
5
+ if (readRawOwnString(params.value, "threadId") !== params.threadId) return { kind: "ignored" };
6
+ const snapshot = agentHarnessStructuredInput.snapshot(params.value);
7
+ if (!agentHarnessStructuredInput.isRecord(snapshot)) return {
8
+ kind: "compiled",
9
+ input: {
10
+ kind: "unsupported",
11
+ message: "OpenClaw declined a malformed or over-limit MCP elicitation request."
12
+ }
13
+ };
14
+ const requestTurnId = readValue(snapshot, "turnId");
15
+ if (typeof requestTurnId === "string" && requestTurnId !== params.turnId) return { kind: "ignored" };
16
+ if (requestTurnId !== null && typeof requestTurnId !== "string") return {
17
+ kind: "compiled",
18
+ input: {
19
+ kind: "unsupported",
20
+ message: "OpenClaw declined an MCP elicitation with invalid turn correlation."
21
+ }
22
+ };
23
+ const mode = readCodexElicitationString(snapshot, "mode");
24
+ if (mode === "url") return {
25
+ kind: "compiled",
26
+ input: agentHarnessStructuredInput.compileUrl({
27
+ url: readValue(snapshot, "url"),
28
+ elicitationId: readValue(snapshot, "elicitationId"),
29
+ message: readValue(snapshot, "message"),
30
+ fallbackMessage: "Codex provided a URL",
31
+ protocolName: "MCP"
32
+ })
33
+ };
34
+ if (mode !== "form" && mode !== "openai/form") return {
35
+ kind: "compiled",
36
+ input: {
37
+ kind: "unsupported",
38
+ message: `OpenClaw does not support MCP elicitation mode ${JSON.stringify(mode ?? "unknown")}.`
39
+ }
40
+ };
41
+ return {
42
+ kind: "compiled",
43
+ input: agentHarnessStructuredInput.compileForm({
44
+ schema: readValue(snapshot, "requestedSchema"),
45
+ message: readCodexElicitationString(snapshot, "message"),
46
+ fallbackMessage: "Codex needs input",
47
+ options: {
48
+ protocolName: mode === "openai/form" ? "OpenAI" : "MCP",
49
+ allowEmptyForm: true,
50
+ minimumChoiceCount: 1,
51
+ allowEnumNames: true,
52
+ allowImagePicker: mode === "openai/form",
53
+ metadata: { secretPath: ["isSecret"] }
54
+ }
55
+ })
56
+ };
57
+ }
58
+ function readValue(record, key) {
59
+ return Object.hasOwn(record, key) ? record[key] : void 0;
60
+ }
61
+ function readCodexElicitationString(record, key) {
62
+ const value = readValue(record, key);
63
+ return typeof value === "string" ? value : void 0;
64
+ }
65
+ function readRawOwnString(value, key) {
66
+ if (!value || typeof value !== "object" || Array.isArray(value)) return;
67
+ const descriptor = Object.getOwnPropertyDescriptor(value, key);
68
+ return descriptor && "value" in descriptor && typeof descriptor.value === "string" ? descriptor.value : void 0;
69
+ }
70
+ //#endregion
71
+ export { compileCodexOrdinaryElicitation };
@@ -1,24 +1,5 @@
1
+ import { t as resolveCodexLocalRuntimeAttribution } from "./local-runtime-attribution-B_2mnqhb.js";
1
2
  import { formatErrorMessage } from "openclaw/plugin-sdk/agent-harness-runtime";
2
- //#region extensions/codex/src/app-server/local-runtime-attribution.ts
3
- const OPENAI_PROVIDER_ID = "openai";
4
- const OPENAI_RESPONSES_API = "openai-responses";
5
- const OPENAI_CODEX_RESPONSES_API = "openai-chatgpt-responses";
6
- function normalizeRuntimeId(value) {
7
- return value?.trim().toLowerCase() ?? "";
8
- }
9
- /** Maps local Codex runtime plans onto the provider/api pair exposed to event projection. */
10
- function resolveCodexLocalRuntimeAttribution(params) {
11
- const authProfileProvider = normalizeRuntimeId(params.runtimePlan?.auth?.authProfileProviderForAuth);
12
- if (normalizeRuntimeId(params.runtimePlan?.observability.harnessId) === "codex" && authProfileProvider !== OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.provider) === OPENAI_PROVIDER_ID && normalizeRuntimeId(params.model.api) === OPENAI_RESPONSES_API) return {
13
- provider: OPENAI_PROVIDER_ID,
14
- api: OPENAI_CODEX_RESPONSES_API
15
- };
16
- return {
17
- provider: params.provider,
18
- api: params.model.api
19
- };
20
- }
21
- //#endregion
22
3
  //#region extensions/codex/src/app-server/event-projector-assistant-message.ts
23
4
  const ZERO_USAGE = {
24
5
  input: 0,
@@ -35,12 +16,19 @@ const ZERO_USAGE = {
35
16
  }
36
17
  };
37
18
  function createAssistantMessage(params, text, options) {
38
- const attribution = resolveCodexLocalRuntimeAttribution(params);
19
+ return createAttributedCodexAssistantMessage({
20
+ ...resolveCodexLocalRuntimeAttribution(params),
21
+ modelId: params.modelId
22
+ }, text, options);
23
+ }
24
+ /** Creates a Codex assistant row when a bounded call already owns attribution. */
25
+ function createAttributedCodexAssistantMessage(attribution, text, options) {
39
26
  const usage = options.tokenUsage ? {
40
27
  input: options.tokenUsage.input ?? 0,
41
28
  output: options.tokenUsage.output ?? 0,
42
29
  cacheRead: options.tokenUsage.cacheRead ?? 0,
43
30
  cacheWrite: options.tokenUsage.cacheWrite ?? 0,
31
+ ...options.tokenUsage.reasoningTokens !== void 0 ? { reasoningTokens: options.tokenUsage.reasoningTokens } : {},
44
32
  ...options.tokenUsage.contextUsage ? { contextUsage: options.tokenUsage.contextUsage } : {},
45
33
  totalTokens: options.tokenUsage.total ?? (options.tokenUsage.input ?? 0) + (options.tokenUsage.output ?? 0) + (options.tokenUsage.cacheRead ?? 0) + (options.tokenUsage.cacheWrite ?? 0),
46
34
  cost: ZERO_USAGE.cost
@@ -53,7 +41,7 @@ function createAssistantMessage(params, text, options) {
53
41
  }],
54
42
  api: attribution.api ?? "openai-chatgpt-responses",
55
43
  provider: attribution.provider,
56
- model: params.modelId,
44
+ model: attribution.modelId,
57
45
  usage,
58
46
  stopReason: options.aborted ? "aborted" : options.promptError ? "error" : "stop",
59
47
  errorMessage: options.promptError ? formatErrorMessage(options.promptError) : void 0,
@@ -98,4 +86,4 @@ function createAssistantMirrorMessage(params, title, text) {
98
86
  };
99
87
  }
100
88
  //#endregion
101
- export { resolveCodexLocalRuntimeAttribution as i, createAssistantMessage as n, createAssistantMirrorMessage as r, createAssistantCommentaryMessage as t };
89
+ export { createAttributedCodexAssistantMessage as i, createAssistantMessage as n, createAssistantMirrorMessage as r, createAssistantCommentaryMessage as t };
@@ -1,4 +1,6 @@
1
- import { W as isJsonObject } from "./shared-client-DTbvH-XV.js";
1
+ import { ut as isJsonObject } from "./shared-client-Dw-rzii0.js";
2
+ import { asSafeIntegerInRange, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
3
+ import { normalizeUsage } from "openclaw/plugin-sdk/agent-harness-runtime";
2
4
  import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
3
5
  //#region extensions/codex/src/app-server/attempt-notifications.ts
4
6
  /**
@@ -14,9 +16,9 @@ function describeNotificationActivity(notification) {
14
16
  if (!item) return { lastNotificationMethod: notification.method };
15
17
  return {
16
18
  lastNotificationMethod: notification.method,
17
- lastNotificationItemId: readString(item, "id"),
18
- lastNotificationItemType: readString(item, "type"),
19
- lastNotificationItemRole: readString(item, "role"),
19
+ lastNotificationItemId: readStringField(item, "id"),
20
+ lastNotificationItemType: readStringField(item, "type"),
21
+ lastNotificationItemRole: readStringField(item, "role"),
20
22
  lastAssistantTextPreview: readRawAssistantTextPreview(item)
21
23
  };
22
24
  }
@@ -59,25 +61,25 @@ function isCompletedAssistantNotification(notification) {
59
61
  if (!isJsonObject(notification.params)) return false;
60
62
  if (notification.method !== "item/completed") return false;
61
63
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
62
- return Boolean(item && readString(item, "type") === "agentMessage" && readString(item, "phase") !== "commentary");
64
+ return Boolean(item && readStringField(item, "type") === "agentMessage" && readStringField(item, "phase") !== "commentary");
63
65
  }
64
66
  /** Returns true for completed app-server reasoning items. */
65
67
  function isReasoningItemCompletionNotification(notification) {
66
68
  if (!isJsonObject(notification.params) || notification.method !== "item/completed") return false;
67
69
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
68
- return item ? readString(item, "type") === "reasoning" : false;
70
+ return item ? readStringField(item, "type") === "reasoning" : false;
69
71
  }
70
72
  /** Returns true for completed assistant commentary items. */
71
73
  function isAssistantCommentaryCompletionNotification(notification) {
72
74
  if (!isJsonObject(notification.params) || notification.method !== "item/completed") return false;
73
75
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
74
- return Boolean(item && readString(item, "type") === "agentMessage" && readString(item, "phase") === "commentary");
76
+ return Boolean(item && readStringField(item, "type") === "agentMessage" && readStringField(item, "phase") === "commentary");
75
77
  }
76
78
  /** Returns true for completed raw response reasoning items. */
77
79
  function isRawReasoningCompletionNotification(notification) {
78
80
  if (!isJsonObject(notification.params) || notification.method !== "rawResponseItem/completed") return false;
79
81
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
80
- return item ? readString(item, "type") === "reasoning" : false;
82
+ return item ? readStringField(item, "type") === "reasoning" : false;
81
83
  }
82
84
  /** Returns true for streamed app-server reasoning progress. */
83
85
  function isReasoningProgressNotification(notification) {
@@ -99,7 +101,7 @@ function shouldDisarmAssistantCompletionIdleWatch(notification) {
99
101
  function readNotificationItemId(notification) {
100
102
  if (!isJsonObject(notification.params)) return;
101
103
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
102
- return (item ? readString(item, "id") : void 0) ?? readString(notification.params, "itemId") ?? readString(notification.params, "id");
104
+ return (item ? readStringField(item, "id") : void 0) ?? readStringField(notification.params, "itemId") ?? readStringField(notification.params, "id");
103
105
  }
104
106
  /** Detects completion for an OpenClaw dynamic tool result still awaited by Codex. */
105
107
  function isPendingOpenClawDynamicToolCompletionNotification(notification, pendingOpenClawDynamicToolCompletionIds) {
@@ -107,14 +109,14 @@ function isPendingOpenClawDynamicToolCompletionNotification(notification, pendin
107
109
  const itemId = readNotificationItemId(notification);
108
110
  if (!itemId || !pendingOpenClawDynamicToolCompletionIds.has(itemId)) return false;
109
111
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
110
- const itemType = item ? readString(item, "type") : void 0;
112
+ const itemType = item ? readStringField(item, "type") : void 0;
111
113
  return itemType === void 0 || itemType === "dynamicToolCall";
112
114
  }
113
115
  /** Returns true for raw response tool-output completion notifications. */
114
116
  function isRawToolOutputCompletionNotification(notification) {
115
117
  if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
116
118
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
117
- switch (item ? readString(item, "type") : void 0) {
119
+ switch (item ? readStringField(item, "type") : void 0) {
118
120
  case "custom_tool_call_output":
119
121
  case "function_call_output": return true;
120
122
  default: return false;
@@ -123,14 +125,14 @@ function isRawToolOutputCompletionNotification(notification) {
123
125
  function isRawFunctionToolOutputCompletionNotification(notification) {
124
126
  if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
125
127
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
126
- return item ? readString(item, "type") === "function_call_output" : false;
128
+ return item ? readStringField(item, "type") === "function_call_output" : false;
127
129
  }
128
130
  /** Returns true for progress on Codex-native tool item types. */
129
131
  function isNativeToolProgressNotification(notification) {
130
132
  if (notification.method !== "item/started" && notification.method !== "item/completed" && notification.method !== "item/updated") return false;
131
133
  if (!isJsonObject(notification.params)) return false;
132
134
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
133
- switch (item ? readString(item, "type") : void 0) {
135
+ switch (item ? readStringField(item, "type") : void 0) {
134
136
  case "commandExecution":
135
137
  case "fileChange":
136
138
  case "mcpToolCall":
@@ -146,19 +148,19 @@ function isFileChangePatchUpdatedNotification(notification) {
146
148
  function isRawAssistantProgressNotification(notification) {
147
149
  if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
148
150
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
149
- return Boolean(item && readString(item, "type") === "message" && readString(item, "role") === "assistant" && readRawAssistantTextPreview(item));
151
+ return Boolean(item && readStringField(item, "type") === "message" && readStringField(item, "role") === "assistant" && readRawAssistantTextPreview(item));
150
152
  }
151
153
  /** Returns true for raw assistant completion outside commentary phase. */
152
154
  function isRawAssistantCompletionNotification(notification) {
153
155
  if (!isRawAssistantProgressNotification(notification) || !isJsonObject(notification.params)) return false;
154
156
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
155
- return Boolean(item && readString(item, "phase") !== "commentary");
157
+ return Boolean(item && readStringField(item, "phase") !== "commentary");
156
158
  }
157
159
  function readRawAssistantTextPreview(item) {
158
- if (readString(item, "role") !== "assistant" || !Array.isArray(item.content)) return;
160
+ if (readStringField(item, "role") !== "assistant" || !Array.isArray(item.content)) return;
159
161
  const text = item.content.flatMap((content) => {
160
162
  if (!isJsonObject(content)) return [];
161
- const contentText = readString(content, "text");
163
+ const contentText = readStringField(content, "text");
162
164
  return contentText ? [contentText] : [];
163
165
  }).join("\n").trim();
164
166
  if (!text) return;
@@ -179,8 +181,8 @@ function isTerminalTurnStatus(status) {
179
181
  function isCodexTurnAbortMarkerNotification(notification, options = {}) {
180
182
  if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return false;
181
183
  const item = notification.params.item;
182
- const role = isJsonObject(item) ? readString(item, "role") : void 0;
183
- if (!isJsonObject(item) || readString(item, "type") !== "message" || role !== "user" && role !== "developer") return false;
184
+ const role = isJsonObject(item) ? readStringField(item, "role") : void 0;
185
+ if (!isJsonObject(item) || readStringField(item, "type") !== "message" || role !== "user" && role !== "developer") return false;
184
186
  const text = extractRawResponseItemText(item).trim();
185
187
  const currentPromptTexts = [options.currentPromptText, ...options.currentPromptTexts ?? []].filter(isNonEmptyString).map((prompt) => prompt.trim());
186
188
  if (role === "user" && currentPromptTexts.includes(text)) return false;
@@ -195,16 +197,12 @@ function extractRawResponseItemText(item) {
195
197
  if (!Array.isArray(content)) return "";
196
198
  return content.flatMap((entry) => {
197
199
  if (!isJsonObject(entry)) return [];
198
- const type = readString(entry, "type");
200
+ const type = readStringField(entry, "type");
199
201
  if (type !== "input_text" && type !== "text") return [];
200
- const text = readString(entry, "text");
202
+ const text = readStringField(entry, "text");
201
203
  return text ? [text] : [];
202
204
  }).join("");
203
205
  }
204
- function readString(record, key) {
205
- const value = record[key];
206
- return typeof value === "string" ? value : void 0;
207
- }
208
206
  /** Reads a typed Codex item from notification params when id/type are present. */
209
207
  function readCodexNotificationItem(params) {
210
208
  if (!isJsonObject(params) || !isJsonObject(params.item)) return;
@@ -216,13 +214,13 @@ function readRawResponseToolCallId(notification) {
216
214
  if (notification.method !== "rawResponseItem/completed" || !isJsonObject(notification.params)) return;
217
215
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
218
216
  if (!item) return;
219
- switch (readString(item, "type")) {
217
+ switch (readStringField(item, "type")) {
220
218
  case "custom_tool_call":
221
219
  case "function_call":
222
220
  case "local_shell_call":
223
- case "tool_search_call": return readString(item, "call_id");
221
+ case "tool_search_call": return readStringField(item, "call_id");
224
222
  case "image_generation_call":
225
- case "web_search_call": return readString(item, "id");
223
+ case "web_search_call": return readStringField(item, "id");
226
224
  default: return;
227
225
  }
228
226
  }
@@ -241,4 +239,90 @@ function isNonEmptyString(value) {
241
239
  return typeof value === "string" && value.length > 0;
242
240
  }
243
241
  //#endregion
244
- export { updateActiveTurnItemIds as S, readCodexNotificationItem as _, isCodexTurnAbortMarkerNotification as a, shouldDisarmAssistantCompletionIdleWatch as b, isPendingOpenClawDynamicToolCompletionNotification as c, isRawReasoningCompletionNotification as d, isRawToolOutputCompletionNotification as f, isTerminalTurnStatus as g, isRetryableErrorNotification as h, isAssistantCompletionReleaseNotification as i, isRawAssistantProgressNotification as l, isReasoningProgressNotification as m, describeNotificationActivity as n, isFileChangePatchUpdatedNotification as o, isReasoningItemCompletionNotification as p, isAssistantCommentaryCompletionNotification as r, isNativeToolProgressNotification as s, codexExecutionToolName as t, isRawFunctionToolOutputCompletionNotification as u, readNotificationItemId as v, updateActiveCompletionBlockerItemIds as x, readRawResponseToolCallId as y };
242
+ //#region extensions/codex/src/app-server/event-projector-usage.ts
243
+ function readTokenCount(record, key) {
244
+ return asSafeIntegerInRange(record[key], { min: 0 });
245
+ }
246
+ function readCodexThreadTokenUsage(params) {
247
+ const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
248
+ const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
249
+ return last ? normalizeCodexThreadTokenUsage(last) : void 0;
250
+ }
251
+ function readCodexThreadContextSnapshot(params) {
252
+ const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
253
+ const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
254
+ const modelContextWindow = tokenUsage ? readTokenCount(tokenUsage, "modelContextWindow") : void 0;
255
+ const activeContextTokens = last ? readTokenCount(last, "totalTokens") : void 0;
256
+ const inputTokens = last ? readTokenCount(last, "inputTokens") : void 0;
257
+ const cachedInputTokens = last ? readTokenCount(last, "cachedInputTokens") : void 0;
258
+ const cacheWriteInputTokens = last ? readTokenCount(last, "cacheWriteInputTokens") : void 0;
259
+ const outputTokens = last ? readTokenCount(last, "outputTokens") : void 0;
260
+ const reasoningOutputTokens = last ? readTokenCount(last, "reasoningOutputTokens") : void 0;
261
+ return {
262
+ ...activeContextTokens !== void 0 ? { activeContextTokens } : {},
263
+ ...cachedInputTokens !== void 0 ? { cachedInputTokens } : {},
264
+ ...cacheWriteInputTokens !== void 0 ? { cacheWriteInputTokens } : {},
265
+ ...inputTokens !== void 0 ? { inputTokens } : {},
266
+ ...modelContextWindow && modelContextWindow > 0 ? { modelContextWindow } : {},
267
+ ...outputTokens !== void 0 ? { outputTokens } : {},
268
+ ...inputTokens !== void 0 ? { promptTokens: inputTokens } : {},
269
+ ...reasoningOutputTokens !== void 0 ? { reasoningOutputTokens } : {}
270
+ };
271
+ }
272
+ function projectCodexThreadUsageUpdate(params, currentUsage, applyUsage, emitContext) {
273
+ applyUsage(readCodexThreadTokenUsage(params) ?? currentUsage);
274
+ const context = readCodexThreadContextSnapshot(params);
275
+ if (Object.keys(context).length > 0) emitContext(context);
276
+ }
277
+ function normalizeCodexThreadTokenUsage(record) {
278
+ return normalizeCodexTokenUsageBreakdown(record);
279
+ }
280
+ function normalizeCodexResponseTokenUsage(record) {
281
+ return normalizeCodexTokenUsageBreakdown(record);
282
+ }
283
+ function normalizeCodexTokenUsageBreakdown(record) {
284
+ const totalTokens = readTokenCount(record, "totalTokens");
285
+ const inputTokens = readTokenCount(record, "inputTokens");
286
+ const cacheRead = readTokenCount(record, "cachedInputTokens");
287
+ const output = readTokenCount(record, "outputTokens");
288
+ const reasoningTokens = readTokenCount(record, "reasoningOutputTokens");
289
+ const cacheWrite = record.cacheWriteInputTokens === void 0 ? 0 : readTokenCount(record, "cacheWriteInputTokens");
290
+ const hasCoherentInput = inputTokens !== void 0 && cacheRead !== void 0 && cacheWrite !== void 0 && cacheRead + cacheWrite <= inputTokens;
291
+ const hasCoherentContext = hasCoherentInput && totalTokens !== void 0 && output !== void 0 && totalTokens === inputTokens + output;
292
+ const usage = normalizeUsage({
293
+ input: hasCoherentInput ? inputTokens - cacheRead - cacheWrite : void 0,
294
+ output,
295
+ cacheRead,
296
+ cacheWrite,
297
+ reasoningTokens,
298
+ total: totalTokens
299
+ });
300
+ if (!usage) return;
301
+ return {
302
+ ...usage,
303
+ contextUsage: hasCoherentContext ? {
304
+ state: "available",
305
+ promptTokens: inputTokens,
306
+ totalTokens
307
+ } : { state: "unavailable" }
308
+ };
309
+ }
310
+ var CodexResponseCompletionProjection = class {
311
+ constructor() {
312
+ this.responseIds = /* @__PURE__ */ new Set();
313
+ }
314
+ get modelIterations() {
315
+ return this.responseIds.size;
316
+ }
317
+ clear() {
318
+ this.usage = void 0;
319
+ }
320
+ record(params) {
321
+ const responseId = readStringField(params, "responseId");
322
+ if (responseId) this.responseIds.add(responseId);
323
+ const usage = isJsonObject(params.usage) ? params.usage : void 0;
324
+ this.usage = usage ? normalizeCodexResponseTokenUsage(usage) : void 0;
325
+ }
326
+ };
327
+ //#endregion
328
+ export { readRawResponseToolCallId as C, updateActiveTurnItemIds as E, readNotificationItemId as S, updateActiveCompletionBlockerItemIds as T, isReasoningItemCompletionNotification as _, codexExecutionToolName as a, isTerminalTurnStatus as b, isAssistantCompletionReleaseNotification as c, isNativeToolProgressNotification as d, isPendingOpenClawDynamicToolCompletionNotification as f, isRawToolOutputCompletionNotification as g, isRawReasoningCompletionNotification as h, readCodexThreadContextSnapshot as i, isCodexTurnAbortMarkerNotification as l, isRawFunctionToolOutputCompletionNotification as m, normalizeCodexResponseTokenUsage as n, describeNotificationActivity as o, isRawAssistantProgressNotification as p, projectCodexThreadUsageUpdate as r, isAssistantCommentaryCompletionNotification as s, CodexResponseCompletionProjection as t, isFileChangePatchUpdatedNotification as u, isReasoningProgressNotification as v, shouldDisarmAssistantCompletionIdleWatch as w, readCodexNotificationItem as x, isRetryableErrorNotification as y };