@openclaw/codex 2026.7.2-beta.5 → 2026.7.2-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.
Files changed (42) hide show
  1. package/dist/{app-server-policy-BmDgseo_.js → app-server-policy-BSaO2JIT.js} +1 -1
  2. package/dist/{attempt-notifications-CMR2_fmR.js → attempt-notifications-AP-a-Q5k.js} +1 -1
  3. package/dist/{bounded-turn-FEbUXoYT.js → bounded-turn-D2ZAgZVz.js} +29 -22
  4. package/dist/{capabilities-BHRSI6Cn.js → capabilities-BFDTVYr4.js} +1 -1
  5. package/dist/cli-metadata.js +1 -1
  6. package/dist/{command-formatters-ico4ZFnk.js → command-formatters-C336eRVS.js} +2 -2
  7. package/dist/{command-handlers-CRmnwI2N.js → command-handlers-DAHUSry9.js} +12 -12
  8. package/dist/{compact-dEN49UH6.js → compact-D_uvHurS.js} +5 -5
  9. package/dist/{computer-use-BjGylO-E.js → computer-use-CYEc8U3w.js} +111 -113
  10. package/dist/{conversation-control-DE7d9DOj.js → conversation-control-xsIeXbo4.js} +6 -6
  11. package/dist/doctor-contract-api.js +1 -1
  12. package/dist/{dynamic-tools-LIt9ojep.js → dynamic-tools-D2gYkSBO.js} +438 -51
  13. package/dist/effective-mcp-catalog-Bbd98Inw.js +114 -0
  14. package/dist/{event-projector-usage-tvgb1NCX.js → event-projector-usage-Xp4AlR2k.js} +20 -3
  15. package/dist/harness.js +13 -9
  16. package/dist/index.js +131 -108
  17. package/dist/media-understanding-provider.js +1 -1
  18. package/dist/{models-BA01NEez.js → models-BBMKU4jA.js} +2 -2
  19. package/dist/{notification-correlation-Bj_Ak_jI.js → notification-correlation-CU6_AnOb.js} +3 -3
  20. package/dist/{plugin-app-cache-key-DSXX-rXO.js → plugin-app-cache-key-DztPafOA.js} +132 -39
  21. package/dist/{rate-limits-S_PXs0ul.js → rate-limits-CU-gVCCS.js} +1 -1
  22. package/dist/{request-CXpPennK.js → request-qKh331yu.js} +3 -3
  23. package/dist/{run-attempt-C5GTPJOE.js → run-attempt-CY9WlDLc.js} +677 -199
  24. package/dist/{runtime-artifact-C2ITXdhM.js → runtime-artifact-CmtG_t1L.js} +90 -24
  25. package/dist/{sandbox-guard-D1Wky__S.js → sandbox-guard-NuhpXmPB.js} +4 -0
  26. package/dist/{session-binding-DlVQ-Pxs.js → session-binding-BXpo9ymA.js} +60 -7
  27. package/dist/{session-catalog-CP2oCcEb.js → session-catalog-DyOgR4WH.js} +268 -44
  28. package/dist/{session-cli-CqZ0Fp2a.js → session-cli-2PZaFLRh.js} +1 -1
  29. package/dist/{session-upstream-marker-QE-m5QFG.js → session-upstream-marker-B6U7tLw5.js} +1 -1
  30. package/dist/{settled-turn-finalizer-CA_2QXIE.js → settled-turn-finalizer-CXY2Z9dT.js} +19 -6
  31. package/dist/{shared-client-BVKE40c-.js → shared-client-DTbvH-XV.js} +166 -49
  32. package/dist/{side-question-CO12sHxo.js → side-question-_ulBk1AL.js} +10 -10
  33. package/dist/{thread-lifecycle-DRg_FdzC.js → thread-lifecycle-DF53ogiA.js} +968 -214
  34. package/dist/{protocol-validators-Dm4eXZmt.js → transcript-mirror-DzsdNCf5.js} +589 -2
  35. package/dist/{upstream-session-fork-_Vrz4WJr.js → upstream-session-fork-Dy4Xvuoj.js} +3 -3
  36. package/dist/{usage-UpVbdX5G.js → usage-CQ6GhD5-.js} +3 -3
  37. package/dist/{web-search-provider.runtime-CaQMYDbp.js → web-search-provider.runtime-CCFhg2z5.js} +3 -3
  38. package/package.json +6 -7
  39. package/dist/attempt-client-cleanup-Ia52yRWc.js +0 -127
  40. package/dist/realtime-voice-api-BPcA1uN9.js +0 -494
  41. package/dist/realtime-voice-api.js +0 -2
  42. package/dist/transcript-mirror-uKA-A4tB.js +0 -550
@@ -1,6 +1,6 @@
1
- import { V as isJsonObject } from "./shared-client-BVKE40c-.js";
2
- import { T as readCodexPluginConfig, g as resolveCodexSupervisionAppServerRuntimeOptions, p as resolveCodexAppServerRuntimeOptions } from "./session-binding-DlVQ-Pxs.js";
3
- import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-DSXX-rXO.js";
1
+ import { W as isJsonObject } from "./shared-client-DTbvH-XV.js";
2
+ import { O as readCodexPluginConfig, g as resolveCodexAppServerRuntimeOptions, y as resolveCodexSupervisionAppServerRuntimeOptions } from "./session-binding-BXpo9ymA.js";
3
+ import { t as buildCodexAppServerConnectionFingerprint } from "./plugin-app-cache-key-DztPafOA.js";
4
4
  //#region extensions/codex/src/app-server/binding-connection.ts
5
5
  /** Requires the native model pair after a supervised pending branch has materialized. */
6
6
  function requireCodexSupervisionModelSelection(binding) {
@@ -1,5 +1,5 @@
1
- import { U as resolveCodexAppServerHomeDir } from "./shared-client-BVKE40c-.js";
2
- import { x as resolveCodexAppServerUserHomeDir } from "./session-binding-DlVQ-Pxs.js";
1
+ import { K as resolveCodexAppServerHomeDir } from "./shared-client-DTbvH-XV.js";
2
+ import { w as resolveCodexAppServerUserHomeDir } from "./session-binding-BXpo9ymA.js";
3
3
  import { createRequire } from "node:module";
4
4
  import { isFutureDateTimestampMs, resolveDateTimestampMs, resolveExpiresAtMsFromDurationMs } from "openclaw/plugin-sdk/number-runtime";
5
5
  import { OPENCLAW_VERSION, embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
@@ -14,7 +14,7 @@ import { truncateUtf16Safe } from "openclaw/plugin-sdk/text-utility-runtime";
14
14
  */
15
15
  /** Default app inventory cache freshness window. */
16
16
  const CODEX_APP_INVENTORY_CACHE_TTL_MS = 3600 * 1e3;
17
- const CODEX_TARGETED_APP_INVENTORY_LIMIT = 1e3;
17
+ const CODEX_APP_READ_BATCH_LIMIT = 100;
18
18
  const MAX_SERIALIZED_ERROR_MESSAGE_LENGTH = 500;
19
19
  /** In-memory app inventory cache with coalesced refreshes per key. */
20
20
  var CodexAppInventoryCache = class {
@@ -55,15 +55,25 @@ var CodexAppInventoryCache = class {
55
55
  refreshNow(params) {
56
56
  return this.refresh(params);
57
57
  }
58
- /** Marks a key stale and records the reason as a diagnostic. */
59
- invalidate(key, reason, nowMs = Date.now()) {
58
+ /**
59
+ * Marks a key stale and records the reason as a diagnostic. A scope names
60
+ * the app ids the invalidation concerns so a covering targeted refresh can
61
+ * clear it; without one, only a complete refresh revalidates the entry.
62
+ */
63
+ invalidate(key, reason, nowMs = Date.now(), invalidatedAppIds) {
60
64
  this.revision += 1;
65
+ this.refreshTokens.set(key, (this.refreshTokens.get(key) ?? 0) + 1);
66
+ this.inFlight.delete(key);
61
67
  const diagnostic = {
62
68
  message: reason,
63
69
  atMs: nowMs
64
70
  };
65
71
  const entry = this.entries.get(key);
66
72
  if (entry) {
73
+ const scope = invalidatedAppIds?.filter(Boolean) ?? [];
74
+ if (!entry.invalidated) entry.invalidatedAppIds = scope.length ? [...scope].toSorted() : void 0;
75
+ else if (entry.invalidatedAppIds && scope.length) entry.invalidatedAppIds = Array.from(/* @__PURE__ */ new Set([...entry.invalidatedAppIds, ...scope])).toSorted();
76
+ else entry.invalidatedAppIds = void 0;
67
77
  entry.invalidated = true;
68
78
  entry.lastError = diagnostic;
69
79
  entry.revision = this.revision;
@@ -83,42 +93,60 @@ var CodexAppInventoryCache = class {
83
93
  return this.revision;
84
94
  }
85
95
  scheduleRefresh(params) {
86
- if (this.inFlight.has(params.key) && !params.forceRefetch) return true;
87
- const promise = this.refresh(params);
88
- this.inFlight.set(params.key, promise);
89
- promise.catch(() => void 0);
96
+ const existing = this.inFlight.get(params.key);
97
+ if (existing && !params.forceRefetch && doesInFlightRefreshCover(existing, params)) return true;
98
+ this.refresh(params).catch(() => void 0);
90
99
  return true;
91
100
  }
92
101
  async refresh(params) {
93
102
  const existing = this.inFlight.get(params.key);
94
- if (existing && !params.forceRefetch) return existing;
103
+ if (existing && !params.forceRefetch && doesInFlightRefreshCover(existing, params)) return existing.promise;
95
104
  const refreshToken = (this.refreshTokens.get(params.key) ?? 0) + 1;
96
105
  this.refreshTokens.set(params.key, refreshToken);
97
- const promise = this.refreshUncoalesced(params, refreshToken);
98
- this.inFlight.set(params.key, promise);
106
+ const previousRefresh = params.forceRefetch ? void 0 : existing?.promise;
107
+ const promise = this.refreshUncoalesced(params, refreshToken, previousRefresh);
108
+ const currentRefresh = {
109
+ promise,
110
+ targetAppIds: new Set(params.targetAppIds?.filter(Boolean) ?? [])
111
+ };
112
+ this.inFlight.set(params.key, currentRefresh);
99
113
  try {
100
114
  return await promise;
101
115
  } finally {
102
- if (this.inFlight.get(params.key) === promise) this.inFlight.delete(params.key);
116
+ if (this.inFlight.get(params.key) === currentRefresh) this.inFlight.delete(params.key);
103
117
  }
104
118
  }
105
- async refreshUncoalesced(params, refreshToken) {
119
+ async refreshUncoalesced(params, refreshToken, previousRefresh) {
106
120
  const nowMs = resolveDateTimestampMs(params.nowMs);
107
121
  try {
108
- const apps = await listAllApps(params.request, params.forceRefetch ?? false, params.targetAppIds);
122
+ let previousRefreshSucceeded = false;
123
+ if (previousRefresh) try {
124
+ await previousRefresh;
125
+ previousRefreshSucceeded = true;
126
+ } catch {}
127
+ const inventory = await readInstalledApps(params.request, {
128
+ forceRefresh: params.forceRefetch === true || !this.entries.has(params.key) && !previousRefreshSucceeded,
129
+ targetAppIds: params.targetAppIds
130
+ });
109
131
  this.revision += 1;
110
132
  const expiresAtMs = resolveExpiresAtMsFromDurationMs(this.ttlMs, { nowMs }) ?? 0;
111
133
  const snapshot = {
112
134
  key: params.key,
113
- apps,
135
+ apps: inventory.apps,
136
+ installedApps: inventory.installedApps,
137
+ ...params.targetAppIds?.some(Boolean) ? { targetAppIds: Array.from(new Set(params.targetAppIds.filter(Boolean))).toSorted() } : {},
114
138
  fetchedAtMs: nowMs,
115
139
  expiresAtMs,
116
140
  revision: this.revision
117
141
  };
118
142
  if (this.refreshTokens.get(params.key) === refreshToken) {
143
+ const existingEntry = this.entries.get(params.key);
144
+ const published = resolvePublishedInventorySnapshot(existingEntry, snapshot, nowMs);
145
+ const remaining = resolveRemainingInvalidationScope(existingEntry, snapshot);
119
146
  this.entries.set(params.key, {
120
- ...snapshot,
121
- invalidated: false
147
+ ...published,
148
+ ...remaining,
149
+ ...remaining.invalidated && existingEntry?.lastError ? { lastError: existingEntry.lastError } : {}
122
150
  });
123
151
  this.diagnostics.delete(params.key);
124
152
  }
@@ -140,6 +168,59 @@ var CodexAppInventoryCache = class {
140
168
  }
141
169
  }
142
170
  };
171
+ /**
172
+ * Publish policy for refreshed snapshots. A complete refresh replaces the
173
+ * entry, but a targeted refresh only rewrites its own target rows in place —
174
+ * replacing the whole entry with a narrow snapshot makes agents that share
175
+ * the runtime identity see each other's plugin apps vanish and force a hosted
176
+ * connector refresh per turn. The refreshed snapshot stays authoritative for
177
+ * its target set, so target rows it no longer returns are deleted.
178
+ */
179
+ function resolvePublishedInventorySnapshot(existing, snapshot, nowMs) {
180
+ if (!snapshot.targetAppIds?.length || !existing) return snapshot;
181
+ if (!isFutureDateTimestampMs(existing.expiresAtMs, { nowMs })) return snapshot;
182
+ const refreshedTargetIds = new Set(snapshot.targetAppIds);
183
+ const { targetAppIds: snapshotTargetAppIds, ...snapshotBase } = snapshot;
184
+ return {
185
+ ...snapshotBase,
186
+ fetchedAtMs: existing.fetchedAtMs,
187
+ expiresAtMs: existing.expiresAtMs,
188
+ apps: mergeRefreshedRows(existing.apps, snapshot.apps, refreshedTargetIds),
189
+ installedApps: mergeRefreshedRows(existing.installedApps, snapshot.installedApps, refreshedTargetIds),
190
+ ...existing.targetAppIds?.length ? { targetAppIds: Array.from(/* @__PURE__ */ new Set([...existing.targetAppIds, ...snapshotTargetAppIds])).toSorted() } : {}
191
+ };
192
+ }
193
+ /** Replaces refreshed target rows in place, deletes vanished ones, appends new ones. */
194
+ function mergeRefreshedRows(existingRows, refreshedRows, refreshedTargetIds) {
195
+ const refreshedById = new Map(refreshedRows.map((row) => [row.id, row]));
196
+ const existingIds = new Set(existingRows.map((row) => row.id));
197
+ return [...existingRows.flatMap((row) => {
198
+ if (!refreshedTargetIds.has(row.id)) return [row];
199
+ const refreshed = refreshedById.get(row.id);
200
+ return refreshed ? [refreshed] : [];
201
+ }), ...refreshedRows.filter((row) => !existingIds.has(row.id))];
202
+ }
203
+ /**
204
+ * A refresh retires exactly the invalidation scope it re-read: a complete
205
+ * refresh clears everything; a targeted one subtracts its target ids so
206
+ * separate covering refreshes accumulate until no scope remains. Unscoped
207
+ * invalidations require a complete refresh.
208
+ */
209
+ function resolveRemainingInvalidationScope(existing, snapshot) {
210
+ if (!existing?.invalidated || !snapshot.targetAppIds?.length) return { invalidated: false };
211
+ if (!existing.invalidatedAppIds) return { invalidated: true };
212
+ const refreshedTargetIds = new Set(snapshot.targetAppIds);
213
+ const remaining = existing.invalidatedAppIds.filter((appId) => !refreshedTargetIds.has(appId));
214
+ return remaining.length > 0 ? {
215
+ invalidated: true,
216
+ invalidatedAppIds: remaining
217
+ } : { invalidated: false };
218
+ }
219
+ function doesInFlightRefreshCover(existing, params) {
220
+ if (existing.targetAppIds.size === 0) return true;
221
+ const requestedAppIds = new Set(params.targetAppIds?.filter(Boolean) ?? []);
222
+ return requestedAppIds.size > 0 && Array.from(requestedAppIds).every((appId) => existing.targetAppIds.has(appId));
223
+ }
143
224
  /** Serializes a refresh failure without leaking large or sensitive error data. */
144
225
  function serializeCodexAppInventoryError(error) {
145
226
  const record = isRecord(error) ? error : void 0;
@@ -175,29 +256,41 @@ function normalizeRuntimeIdentityForCacheKey(value) {
175
256
  }).toSorted(([left], [right]) => left.localeCompare(right));
176
257
  return entries.length > 0 ? Object.fromEntries(entries) : null;
177
258
  }
178
- async function listAllApps(request, forceRefetch, targetAppIds = []) {
179
- const apps = [];
180
- const targetIds = new Set(targetAppIds.filter(Boolean));
181
- const remainingTargetIds = new Set(targetIds);
182
- const seenCursors = /* @__PURE__ */ new Set();
183
- let cursor;
184
- do {
185
- const response = await request("app/list", {
186
- cursor,
187
- limit: targetIds.size > 0 ? CODEX_TARGETED_APP_INVENTORY_LIMIT : 100,
188
- forceRefetch
189
- });
190
- apps.push(...response.data);
191
- for (const app of response.data) remainingTargetIds.delete(app.id);
192
- if (targetIds.size > 0 && remainingTargetIds.size === 0) break;
193
- cursor = response.nextCursor;
194
- if (cursor && seenCursors.has(cursor)) throw new Error(`app/list returned repeated cursor ${cursor}`);
195
- if (cursor) seenCursors.add(cursor);
196
- } while (cursor);
197
- return apps;
259
+ async function readInstalledApps(request, options) {
260
+ const installed = await request("app/installed", { forceRefresh: options.forceRefresh });
261
+ const targetIds = new Set((options.targetAppIds ?? []).filter(Boolean));
262
+ const apps = targetIds.size === 0 ? installed.apps : installed.apps.filter((app) => targetIds.has(app.id));
263
+ if (apps.length === 0) return {
264
+ apps: [],
265
+ installedApps: []
266
+ };
267
+ const metadataResponses = await Promise.all(Array.from({ length: Math.ceil(apps.length / CODEX_APP_READ_BATCH_LIMIT) }, (_, index) => request("app/read", { appIds: apps.slice(index * CODEX_APP_READ_BATCH_LIMIT, (index + 1) * CODEX_APP_READ_BATCH_LIMIT).map((app) => app.id) })));
268
+ const metadataById = new Map(metadataResponses.flatMap((response) => response.apps).map((metadata) => [metadata.id, metadata]));
269
+ return {
270
+ apps: apps.flatMap((installedApp) => {
271
+ const metadata = metadataById.get(installedApp.id);
272
+ if (!metadata) return [];
273
+ return [{
274
+ id: installedApp.id,
275
+ name: metadata.name,
276
+ description: metadata.description ?? null,
277
+ logoUrl: metadata.iconUrl ?? null,
278
+ logoUrlDark: metadata.iconUrlDark ?? null,
279
+ distributionChannel: metadata.distributionChannel ?? null,
280
+ branding: null,
281
+ appMetadata: null,
282
+ labels: null,
283
+ installUrl: metadata.installUrl ?? null,
284
+ isAccessible: true,
285
+ isEnabled: installedApp.enabled,
286
+ pluginDisplayNames: metadata.pluginDisplayNames
287
+ }];
288
+ }),
289
+ installedApps: apps
290
+ };
198
291
  }
199
292
  function stripEntryState(entry) {
200
- const { invalidated: _invalidated, ...snapshot } = entry;
293
+ const { invalidated: _invalidated, invalidatedAppIds: _invalidatedAppIds, ...snapshot } = entry;
201
294
  return snapshot;
202
295
  }
203
296
  function fingerprintInventoryCacheKey(key) {
@@ -1,4 +1,4 @@
1
- import { V as isJsonObject } from "./shared-client-BVKE40c-.js";
1
+ import { W as isJsonObject } from "./shared-client-DTbvH-XV.js";
2
2
  import { MAX_DATE_TIMESTAMP_MS, resolveExpiresAtMsFromEpochSeconds } from "openclaw/plugin-sdk/number-runtime";
3
3
  import { asFiniteNumber, parseStrictFiniteNumber } from "openclaw/plugin-sdk/string-coerce-runtime";
4
4
  import { expectDefined } from "openclaw/plugin-sdk/expect-runtime";
@@ -1,5 +1,5 @@
1
- import { a as getLeasedSharedCodexAppServerClient, f as retireSharedCodexAppServerClientIfCurrent, h as withTimeout, i as createIsolatedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient, s as isCodexAppServerStartSelectionChangedError } from "./shared-client-BVKE40c-.js";
2
- import { t as resolveCodexAppServerDirectSandboxBypassBlock } from "./sandbox-guard-D1Wky__S.js";
1
+ import { a as getLeasedSharedCodexAppServerClient, g as withTimeout, i as createIsolatedCodexAppServerClient, l as releaseLeasedSharedCodexAppServerClient, p as retireSharedCodexAppServerClientIfCurrent, s as isCodexAppServerStartSelectionChangedError } from "./shared-client-DTbvH-XV.js";
2
+ import { t as resolveCodexAppServerDirectSandboxBypassBlock } from "./sandbox-guard-NuhpXmPB.js";
3
3
  //#region extensions/codex/src/app-server/request.ts
4
4
  /** Sends one guarded request over a client lease owned by the caller. */
5
5
  async function requestCodexAppServerClientJson(params) {
@@ -154,4 +154,4 @@ async function withCodexAppServerJsonClient(params, run) {
154
154
  }
155
155
  }
156
156
  //#endregion
157
- export { requestCodexAppServerClientJson as n, requestCodexAppServerJson as r, readCodexAppServerUsage as t };
157
+ export { withCodexAppServerJsonClient as i, requestCodexAppServerClientJson as n, requestCodexAppServerJson as r, readCodexAppServerUsage as t };