@openclaw/codex 2026.9.1 → 2026.9.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 (109) hide show
  1. package/README.md +2 -0
  2. package/dist/api.js +18 -23
  3. package/dist/apply-B6el6hdO.js +357 -0
  4. package/dist/{attempt-client-cleanup-DYHcRQAa.js → attempt-client-cleanup-D6cR54TV.js} +113 -49
  5. package/dist/{attempt-context-DmQUNWwT.js → attempt-context-AO4DSjE0.js} +11 -9
  6. package/dist/{event-projector-usage-C5mcrGjp.js → attempt-notifications--H8zXR5-.js} +3 -89
  7. package/dist/auth-cache-key-Kq6oerr6.js +498 -0
  8. package/dist/auth-profile-CwzO4_RG.js +43 -0
  9. package/dist/auth-profile-selection-DFu9e167.js +45 -0
  10. package/dist/{binding-connection-E6uDsPlx.js → binding-connection-QqgcPCgk.js} +18 -3
  11. package/dist/{bounded-turn-wzJrwKKe.js → bounded-turn-lRpmZHFv.js} +54 -150
  12. package/dist/build-state-6RL6qohz.js +19 -0
  13. package/dist/{capabilities-dIjNVCYH.js → capabilities-BeqLPbtM.js} +2 -1
  14. package/dist/cli-metadata.js +1 -1
  15. package/dist/client-BEKu4yDx.js +3983 -0
  16. package/dist/command-dispatch-CisT9Jqq.js +21 -0
  17. package/dist/{command-formatters-CLHhEB1Q.js → command-formatters-DeTfrapr.js} +2 -2
  18. package/dist/{command-handlers-CTGb2csu.js → command-handlers-BfIsJEuA.js} +158 -76
  19. package/dist/command-rpc-BMqRQOFX.js +226 -0
  20. package/dist/{compact-_t0HQrUS.js → compact-CGJZ2rlb.js} +89 -49
  21. package/dist/config-JDfTI4VI.js +106 -0
  22. package/dist/{config-BhmfC1s6.js → config-options-jnIFvwxD.js} +208 -654
  23. package/dist/config-runtime-BWf6JLWG.js +11 -0
  24. package/dist/config-utils-C57JiJrU.js +69 -0
  25. package/dist/conversation-binding-CxOlHiix.js +889 -0
  26. package/dist/{plugin-marketplace-discovery-CfFlKqDl.js → conversation-control-CUCrSIQI.js} +36 -155
  27. package/dist/doctor-contract-api.js +8 -9
  28. package/dist/{dynamic-tools-BU9tmlYm.js → dynamic-tools-D-JBoaLt.js} +734 -698
  29. package/dist/{effective-mcp-catalog-DzYBW4h1.js → effective-mcp-catalog-J_5Ep5Um.js} +4 -3
  30. package/dist/{elicitation-input-DMkeki8d.js → elicitation-input-DPoK8F7w.js} +8 -22
  31. package/dist/ephemeral-turn-DSwzP8YY.js +101 -0
  32. package/dist/{event-projector-assistant-message-DHRFXKbS.js → event-projector-assistant-message-BmBM4qBV.js} +23 -27
  33. package/dist/event-projector-usage-CIyrYYid.js +102 -0
  34. package/dist/{harness-DXVZ5II5.js → harness-FR6eQgyO.js} +47 -17
  35. package/dist/harness.js +1 -1
  36. package/dist/history-rejection-B4nOXNXF.js +13 -0
  37. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  38. package/dist/incognito-session-uhrBF6wJ.js +15 -0
  39. package/dist/index.js +413 -2893
  40. package/dist/{isolated-completion-kg9kv4iH.js → isolated-completion-DHBefrzg.js} +12 -21
  41. package/dist/{managed-binary-4-Vjz5GH.js → managed-binary-DrjjRRUD.js} +17 -84
  42. package/dist/managed-thread-store-D1t5jh3G.js +66 -0
  43. package/dist/media-understanding-provider.js +4 -1
  44. package/dist/{model-catalog-CUM68Hkl.js → model-catalog-B_6M04Wo.js} +6 -5
  45. package/dist/{models-sYnEc0gd.js → models-P9k2qAof.js} +4 -4
  46. package/dist/native-execution-policy-umd0tgh4.js +128 -0
  47. package/dist/{native-subagent-monitor-CnH147jH.js → native-subagent-monitor-BbCUKRwC.js} +76 -48
  48. package/dist/node-cli-sessions-rj0ysJwM.js +527 -0
  49. package/dist/{node-exec-server.runtime-CstNHCmC.js → node-exec-server.runtime-BY_ctYnT.js} +54 -23
  50. package/dist/plan-BMJdMOEF.js +711 -0
  51. package/dist/plugin-activation-BQK-f5sV.js +133 -0
  52. package/dist/{thread-resume-C7pyVKeW.js → plugin-app-cache-key-CdSQzWyX.js} +5 -53
  53. package/dist/{plugin-approval-roundtrip-CNe-Xrjx.js → plugin-approval-roundtrip-DeW95wB5.js} +1 -1
  54. package/dist/plugin-inventory-CoRCzWW4.js +325 -0
  55. package/dist/plugin-marketplace-discovery-3akBizzF.js +134 -0
  56. package/dist/{plugin-metadata-cache-BFrPhb2c.js → plugin-metadata-cache-DgNfRAGA.js} +13 -9
  57. package/dist/protocol-CAAcVIKF.js +275 -0
  58. package/dist/{provider-capabilities-DW5p4k9w.js → provider-capabilities-W4tfK5Y5.js} +2 -2
  59. package/dist/{rate-limits-CawQJfUS.js → rate-limits-Bqnx1N4z.js} +1 -1
  60. package/dist/request-CGvGOpeR.js +198 -0
  61. package/dist/{run-attempt-D1hJO4fX.js → run-attempt-DwKds3DN.js} +1498 -1028
  62. package/dist/{runtime-artifact-C3jVimFn.js → runtime-artifact-T-NwqeSH.js} +28 -28
  63. package/dist/sandbox-guard-BcT66fWy.js +165 -0
  64. package/dist/{session-binding-BHuTCRZQ.js → session-binding-CKSepwIC.js} +118 -324
  65. package/dist/session-binding-record-CaZjYwNS.js +256 -0
  66. package/dist/session-catalog-HaDcp7Sv.js +1533 -0
  67. package/dist/session-catalog-adoption-BKLtSrwi.js +251 -0
  68. package/dist/session-catalog-archive-D0i2pGj2.js +56 -0
  69. package/dist/session-catalog-home-id-D7-aLiNt.js +190 -0
  70. package/dist/session-catalog-node-adoption-BUuDYY8R.js +182 -0
  71. package/dist/session-catalog-node-continue-CBtc4wkI.js +238 -0
  72. package/dist/session-catalog-parsing-CdD3JhdM.js +280 -0
  73. package/dist/session-catalog-provenance-DkJHo735.js +124 -0
  74. package/dist/{session-cli-CmFEXMAM.js → session-cli-CbgaHh0f.js} +3 -2
  75. package/dist/session-history-Cz-tOOYj.js +96 -0
  76. package/dist/{session-upstream-marker-C351-5Qw.js → session-history-import-DFN7sWRU.js} +5 -49
  77. package/dist/session-history-read-cxPUxyVV.js +50 -0
  78. package/dist/session-history-worker-runtime.js +60 -0
  79. package/dist/{settled-turn-context-D3SNWtUn.js → session-history.worker-CNEvGaU5.js} +75 -69
  80. package/dist/session-history.worker.js +2 -0
  81. package/dist/{session-initialization-BeWzjGiR.js → session-initialization-Jo86C60I.js} +2 -1
  82. package/dist/{session-permission-policy-DeWVTCMj.js → session-permission-policy-B22InTp_.js} +4 -7
  83. package/dist/{session-retirement-BujDjXVF.js → session-retirement-BSNG_mhf.js} +8 -7
  84. package/dist/session-upstream-marker-D15C9NHp.js +46 -0
  85. package/dist/settled-turn-context-Du6gdUDd.js +45 -0
  86. package/dist/{settled-turn-finalizer-BVJx4yoc.js → settled-turn-finalizer-BuLUrZl2.js} +54 -42
  87. package/dist/shared-client-CVhez2Uo.js +2911 -0
  88. package/dist/{side-question-BTZAII4l.js → side-question-DLbr2vUU.js} +135 -191
  89. package/dist/source-Da-h6f7e.js +518 -0
  90. package/dist/thread-archive-guard-D1bP04Tf.js +53 -0
  91. package/dist/{thread-lifecycle-DAcEJ_Om.js → thread-lifecycle-D1pzRwHB.js} +467 -977
  92. package/dist/{thread-ownership-zGokd8i1.js → thread-ownership-D6oASVRu.js} +15 -17
  93. package/dist/{thread-policy-g4KbJPzp.js → thread-policy-D8kI7yAO.js} +2 -2
  94. package/dist/thread-resume-T5cveyxA.js +52 -0
  95. package/dist/timeout-BVw8aaM1.js +33 -0
  96. package/dist/transcript-mirror-attestation-DibE0krH.js +89 -0
  97. package/dist/{transcript-mirror-DTUxFWa_.js → transcript-mirror-t5TOccct.js} +111 -379
  98. package/dist/{transport-stdio-CyPldczm.js → transport-stdio-BGjHoYLr.js} +80 -48
  99. package/dist/{upstream-session-fork-CYlBIGVt.js → upstream-session-fork-De-sLJ2r.js} +94 -166
  100. package/dist/{usage-Bj-rrzkR.js → usage-CPPTmBvZ.js} +4 -3
  101. package/dist/version-omm6IPI3.js +12 -0
  102. package/dist/{web-search-provider.runtime-D2FWSK4w.js → web-search-provider.runtime-CSVgQL0w.js} +3 -3
  103. package/openclaw.plugin.json +22 -1
  104. package/package.json +6 -6
  105. package/dist/request-DYAI5FQE.js +0 -475
  106. package/dist/session-catalog-yyvTWFOw.js +0 -3120
  107. package/dist/session-history-C5J1AKzG.js +0 -87
  108. package/dist/shared-client-DxcfF9KX.js +0 -7494
  109. package/dist/{auth-binding-Ds_QVm-X.js → auth-binding-Co2Vfcf_.js} +1 -1
@@ -1,10 +1,32 @@
1
- import { $t as isJsonObject, jt as unsubscribeCodexAppServerLiveThread, q as CodexAppServerRpcError, y as retireSharedCodexAppServerClientIfCurrent } from "./shared-client-DxcfF9KX.js";
1
+ import { o as isJsonObject } from "./protocol-CAAcVIKF.js";
2
+ import "./client-BEKu4yDx.js";
3
+ import { m as retireSharedCodexAppServerClientIfCurrent } from "./auth-cache-key-Kq6oerr6.js";
4
+ import { r as CodexAppServerRpcError } from "./session-catalog-provenance-DkJHo735.js";
5
+ import { G as unsubscribeCodexAppServerLiveThread } from "./shared-client-CVhez2Uo.js";
2
6
  import { asFiniteNumber, normalizeOptionalString, normalizeOptionalString as normalizeOptionalString$1, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
3
7
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
4
8
  import { embeddedAgentLog } from "openclaw/plugin-sdk/agent-harness-runtime";
9
+ import { AsyncResource } from "node:async_hooks";
5
10
  import { redactSensitiveText } from "openclaw/plugin-sdk/logging-core";
6
11
  import { sanitizeTerminalText } from "openclaw/plugin-sdk/text-chunking";
7
12
  //#region extensions/codex/src/app-server/event-projector-values.ts
13
+ const BIO_POLICY_SAFETY_ACCESS_BLOCK_PREFIX = "This content was flagged for possible biological risk.";
14
+ /** Project only Codex's explicit refusal contracts; other policy errors retain their own paths. */
15
+ function readCodexProviderRefusal(message, codexErrorInfo) {
16
+ if (!message) return;
17
+ if (codexErrorInfo === "cyberPolicy") return {
18
+ category: "cyber",
19
+ message
20
+ };
21
+ if (codexErrorInfo === "misalignmentPolicyViolation") return {
22
+ category: "misalignment",
23
+ message
24
+ };
25
+ return message.startsWith(BIO_POLICY_SAFETY_ACCESS_BLOCK_PREFIX) ? {
26
+ category: "bio",
27
+ message
28
+ } : void 0;
29
+ }
8
30
  function readNonEmptyString(record, key) {
9
31
  return normalizeOptionalString$1(record[key]);
10
32
  }
@@ -279,7 +301,6 @@ var ClientTurnRouter = class {
279
301
  this.routes = /* @__PURE__ */ new Map();
280
302
  this.globalWarnings = [];
281
303
  this.nativeTurnCompletionWatchers = /* @__PURE__ */ new Map();
282
- this.disposed = false;
283
304
  client.addNotificationHandler((notification) => this.routeNotification(notification));
284
305
  client.addRequestHandler((request, signal) => this.routeRequest(request, signal));
285
306
  client.addCloseHandler((closedClient) => {
@@ -320,9 +341,12 @@ var ClientTurnRouter = class {
320
341
  get observedNativeTurnId() {
321
342
  return route.observedNativeTurn?.id;
322
343
  },
344
+ get completed() {
345
+ return Boolean(route.turnId && route.completedNativeTurnIds.has(route.turnId));
346
+ },
323
347
  activate: (handlers) => this.activate(route, handlers),
324
348
  armTurn: () => this.armTurn(route),
325
- bindTurn: (turnId) => this.bindTurn(route, turnId),
349
+ bindTurn: (turnId, bindingOptions) => this.bindTurn(route, turnId, bindingOptions),
326
350
  cancelTurn: () => this.cancelTurn(route),
327
351
  drain: () => this.drainNotifications(route),
328
352
  release: () => this.release(route)
@@ -334,28 +358,35 @@ var ClientTurnRouter = class {
334
358
  const turnId = requireId(options.turnId, "turn id");
335
359
  if (options.signal?.aborted) return {
336
360
  completion: Promise.resolve(false),
361
+ state: "unconfirmed",
362
+ settledSignal: AbortSignal.abort(),
337
363
  cancel: () => {}
338
364
  };
339
- if (this.routes.get(threadId)?.completedNativeTurnIds.delete(turnId)) return {
365
+ if (this.routes.get(threadId)?.completedNativeTurnIds.has(turnId)) return {
340
366
  completion: Promise.resolve(true),
367
+ state: "confirmed",
368
+ settledSignal: AbortSignal.abort(),
341
369
  cancel: () => {}
342
370
  };
343
371
  const { promise: completion, resolve: settle } = createDeferred();
372
+ const settlement = new AbortController();
344
373
  const watchers = this.nativeTurnCompletionWatchers.get(threadId) ?? /* @__PURE__ */ new Set();
345
374
  this.nativeTurnCompletionWatchers.set(threadId, watchers);
346
- let settled = false;
375
+ let state = "pending";
347
376
  const finish = (completed) => {
348
- if (settled) return;
349
- settled = true;
377
+ if (state !== "pending") return;
378
+ state = completed ? "confirmed" : "unconfirmed";
350
379
  watchers.delete(watcher);
351
380
  if (watchers.size === 0) this.nativeTurnCompletionWatchers.delete(threadId);
352
381
  clearTimeout(timeout);
353
382
  options.signal?.removeEventListener("abort", abort);
383
+ settlement.abort();
354
384
  settle(completed);
355
385
  };
356
386
  const watcher = {
357
387
  turnId,
358
- finish
388
+ finish,
389
+ onStarted: options.onStarted
359
390
  };
360
391
  watchers.add(watcher);
361
392
  const timeout = setTimeout(() => finish(false), Math.max(1, options.timeoutMs));
@@ -364,13 +395,17 @@ var ClientTurnRouter = class {
364
395
  options.signal?.addEventListener("abort", abort, { once: true });
365
396
  return {
366
397
  completion,
398
+ settledSignal: settlement.signal,
399
+ get state() {
400
+ return state;
401
+ },
367
402
  cancel: () => finish(false)
368
403
  };
369
404
  }
370
405
  dispose(cause) {
371
- if (this.disposed) return;
372
- this.disposed = true;
406
+ if (this.closeError) return;
373
407
  const closeError = cause ? new Error("codex app-server turn router closed", { cause }) : /* @__PURE__ */ new Error("codex app-server turn router closed");
408
+ this.closeError = closeError;
374
409
  for (const route of this.routes.values()) this.release(route, closeError);
375
410
  for (const watchers of this.nativeTurnCompletionWatchers.values()) for (const watcher of watchers) watcher.finish(false);
376
411
  }
@@ -384,7 +419,11 @@ var ClientTurnRouter = class {
384
419
  if (route.handlers) throw new Error(`codex app-server thread route already activated: ${route.threadId}`);
385
420
  this.assertRoute(route);
386
421
  if (!handlers.onNotification && !handlers.onRequest) throw new Error("codex app-server thread route requires a notification or request handler");
387
- route.handlers = handlers;
422
+ route.handlers = {
423
+ onRequest: handlers.onRequest && AsyncResource.bind(handlers.onRequest),
424
+ onNotification: handlers.onNotification && AsyncResource.bind(handlers.onNotification),
425
+ onNotificationReceived: handlers.onNotificationReceived && AsyncResource.bind(handlers.onNotificationReceived, void 0, handlers)
426
+ };
388
427
  if (!handlers.onNotification) route.pending.length = 0;
389
428
  else if (route.gate !== "armed") this.flushNotifications(route);
390
429
  route.activated.resolve();
@@ -407,20 +446,22 @@ var ClientTurnRouter = class {
407
446
  await this.waitForNotifications(route);
408
447
  this.assertRoute(route);
409
448
  }
410
- async bindTurn(route, turnIdInput) {
411
- this.assertRoute(route);
449
+ async bindTurn(route, turnIdInput, options) {
450
+ const turnId = requireId(turnIdInput, "turn id");
451
+ if (options?.completed && route.gate === "armed" && (!route.released || route.released === this.closeError)) route.completedNativeTurnIds.add(turnId);
452
+ this.assertRoute(route, route.gate === "armed" ? turnId : void 0);
412
453
  if (!route.handlers) throw new Error("codex app-server thread route must be activated before binding a turn");
413
454
  if (route.gate !== "armed") throw new Error(`codex app-server thread route cannot bind from ${route.gate}`);
414
- const turnId = requireId(turnIdInput, "turn id");
415
455
  route.gate = "bound";
416
456
  route.turnId = turnId;
417
457
  this.flushNotifications(route);
418
458
  route.binding?.resolve();
419
459
  await this.waitForNotifications(route);
420
- this.assertRoute(route);
460
+ this.assertRoute(route, turnId);
461
+ await route.notificationTail;
421
462
  }
422
463
  routeNotification(notification) {
423
- if (this.disposed) return;
464
+ if (this.closeError) return;
424
465
  const scope = readScope(notification.params);
425
466
  if (!scope.threadId && (notification.method === "configWarning" || notification.method === "warning")) {
426
467
  if (this.globalWarnings.length === DEFAULT_GLOBAL_WARNING_LIMIT) this.globalWarnings.shift();
@@ -436,6 +477,7 @@ var ClientTurnRouter = class {
436
477
  if (!watchers && !route) return;
437
478
  if (scope.turnId && watchers) {
438
479
  for (const watcher of watchers) if (watcher.turnId === scope.turnId && notification.method === "turn/completed") watcher.finish(true);
480
+ else if (watcher.turnId === scope.turnId && notification.method === "turn/started") watcher.onStarted?.();
439
481
  }
440
482
  if (!route) return;
441
483
  const routeScope = {
@@ -443,12 +485,15 @@ var ClientTurnRouter = class {
443
485
  ...scope.turnId ? { turnId: scope.turnId } : {}
444
486
  };
445
487
  const receivedAtMs = Date.now();
446
- if (route.gate !== "bound" && scope.turnId) {
447
- if (notification.method === "turn/started") route.observedNativeTurn = {
448
- id: scope.turnId,
449
- completed: false
450
- };
451
- else if (notification.method === "turn/completed") {
488
+ if (scope.turnId && (route.gate !== "bound" || scope.turnId === route.turnId)) {
489
+ if (notification.method === "turn/started") {
490
+ route.completedNativeTurnIds.delete(scope.turnId);
491
+ route.observedNativeTurn = {
492
+ id: scope.turnId,
493
+ completed: false
494
+ };
495
+ } else if (notification.method === "turn/completed") {
496
+ if (route.gate === "bound") route.completedNativeTurnIds.clear();
452
497
  route.completedNativeTurnIds.add(scope.turnId);
453
498
  if (!route.observedNativeTurn || route.observedNativeTurn.completed || route.observedNativeTurn.id === scope.turnId) route.observedNativeTurn = {
454
499
  id: scope.turnId,
@@ -475,7 +520,7 @@ var ClientTurnRouter = class {
475
520
  return route.notificationTail;
476
521
  }
477
522
  async routeRequest(request, signal = new AbortController().signal) {
478
- if (this.disposed || signal.aborted) return;
523
+ if (this.closeError || signal.aborted) return;
479
524
  const scope = readScope(request.params);
480
525
  if (!scope.threadId) return;
481
526
  const route = this.routes.get(scope.threadId);
@@ -550,7 +595,7 @@ var ClientTurnRouter = class {
550
595
  this.release(route, error);
551
596
  }
552
597
  enqueueNotification(route, handler, notification, scope) {
553
- if (route.released) return;
598
+ if (route.released && !this.canDrainClosedTurn(route, route.turnId)) return;
554
599
  route.notificationTail = route.notificationTail.then(() => handler(notification, scope)).catch((error) => {
555
600
  if (!route.released) embeddedAgentLog.warn("codex app-server keyed notification handler failed", {
556
601
  method: notification.method,
@@ -569,7 +614,7 @@ var ClientTurnRouter = class {
569
614
  release(route, error = /* @__PURE__ */ new Error("codex app-server thread route is released")) {
570
615
  if (route.released) return;
571
616
  route.released = error;
572
- route.pending.length = 0;
617
+ if (error !== this.closeError) route.pending.length = 0;
573
618
  route.ended.resolve();
574
619
  route.activated.resolve();
575
620
  route.binding?.resolve();
@@ -578,10 +623,13 @@ var ClientTurnRouter = class {
578
623
  if (this.routes.get(route.threadId) === route) this.routes.delete(route.threadId);
579
624
  }
580
625
  assertActive() {
581
- if (this.disposed) throw new Error("codex app-server turn router is closed");
626
+ if (this.closeError) throw new Error("codex app-server turn router is closed");
627
+ }
628
+ canDrainClosedTurn(route, turnId) {
629
+ return Boolean(this.closeError && route.released === this.closeError && turnId && route.completedNativeTurnIds.has(turnId));
582
630
  }
583
- assertRoute(route) {
584
- if (route.released) throw route.released;
631
+ assertRoute(route, completedTurnId) {
632
+ if (route.released && !this.canDrainClosedTurn(route, completedTurnId)) throw route.released;
585
633
  }
586
634
  };
587
635
  async function waitForPromiseOrAbort(promise, signal) {
@@ -626,8 +674,8 @@ const CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS = 5e3;
626
674
  const CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS = 5e3;
627
675
  const CODEX_NO_ACTIVE_TURN_ERROR_CODE = -32600;
628
676
  const CODEX_NO_ACTIVE_TURN_ERROR_MESSAGE = "no active turn to interrupt";
629
- /** Identifies Codex's exact proof that an interrupt target already finished. */
630
- function isCodexAlreadyTerminalInterruptError(error) {
677
+ /** Codex also reports this before an accepted turn publishes its start event. */
678
+ function isCodexNoActiveTurnInterruptError(error) {
631
679
  return error instanceof CodexAppServerRpcError && error.code === CODEX_NO_ACTIVE_TURN_ERROR_CODE && error.message === CODEX_NO_ACTIVE_TURN_ERROR_MESSAGE;
632
680
  }
633
681
  /** Raised when a thread subscription may be live on a client OpenClaw no longer controls. */
@@ -644,18 +692,10 @@ function isCodexAppServerUnsafeSubscriptionError(error) {
644
692
  function assertCodexThreadResumeSubscription(requestedThreadId, returnedThreadId) {
645
693
  if (returnedThreadId !== requestedThreadId) throw new CodexAppServerUnsafeSubscriptionError(`Codex thread/resume returned ${returnedThreadId} for ${requestedThreadId}`);
646
694
  }
647
- async function closeClientAndWaitIfAvailable(client) {
648
- const closeable = client;
649
- if (typeof closeable.closeAndWait === "function") {
650
- await closeable.closeAndWait();
651
- return;
652
- }
653
- closeable.close?.();
654
- }
655
695
  async function closeCodexStartupClientBestEffort(client) {
656
696
  if (!client) return;
657
697
  const retiredSharedClient = retireSharedCodexAppServerClientIfCurrent(client);
658
- if (!retiredSharedClient || retiredSharedClient.closed) await closeClientAndWaitIfAvailable(client);
698
+ if (!retiredSharedClient || retiredSharedClient.closed) await client.closeAndWait();
659
699
  }
660
700
  /** Retires an unsafe turn client without replacing an already-authoritative failure. */
661
701
  async function retireUnsafeCodexTurnClientBestEffort(client, operation) {
@@ -683,25 +723,48 @@ async function interruptCodexTurnAndWaitBestEffort(client, params) {
683
723
  threadId: params.threadId,
684
724
  turnId: params.turnId
685
725
  };
686
- let completion;
726
+ let cancelWatch;
687
727
  try {
688
- completion = params.turnId ? getCodexAppServerTurnRouter(client).watchNativeTurnCompletion({
728
+ if (!params.turnId) {
729
+ await client.request("turn/interrupt", requestParams, { timeoutMs });
730
+ return true;
731
+ }
732
+ const deadline = Date.now() + timeoutMs;
733
+ const started = createDeferred();
734
+ const completion = getCodexAppServerTurnRouter(client).watchNativeTurnCompletion({
689
735
  threadId: params.threadId,
690
736
  turnId: params.turnId,
691
- timeoutMs
692
- }) : void 0;
693
- await client.request("turn/interrupt", requestParams, { timeoutMs });
694
- return completion ? await completion.completion : true;
737
+ timeoutMs,
738
+ onStarted: () => started.resolve(true)
739
+ });
740
+ cancelWatch = completion.cancel;
741
+ if (completion.state !== "pending") return await completion.completion;
742
+ const requestInterrupt = async () => {
743
+ try {
744
+ await client.request("turn/interrupt", requestParams, {
745
+ timeoutMs: Math.max(1, deadline - Date.now()),
746
+ signal: completion.settledSignal
747
+ });
748
+ return true;
749
+ } catch (error) {
750
+ if (completion.state === "confirmed") return true;
751
+ if (isCodexNoActiveTurnInterruptError(error)) return false;
752
+ throw error;
753
+ }
754
+ };
755
+ if (!await requestInterrupt()) {
756
+ if (await Promise.race([completion.completion.then(() => false), started.promise]) && completion.state === "pending" && Date.now() < deadline) await requestInterrupt();
757
+ }
758
+ return await completion.completion;
695
759
  } catch (error) {
696
- if (isCodexAlreadyTerminalInterruptError(error)) return true;
697
760
  embeddedAgentLog.debug("codex app-server turn interrupt failed during abort", { error });
698
761
  return false;
699
762
  } finally {
700
- completion?.cancel();
763
+ cancelWatch?.();
701
764
  }
702
765
  }
703
766
  /** Stops native terminals on the cancelled thread without retiring peer threads. */
704
- async function terminateCodexBackgroundTerminals(client, threadId) {
767
+ async function terminateCodexBackgroundTerminals(client, threadId, oneShotCliRun = false) {
705
768
  const options = {
706
769
  timeoutMs: CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS,
707
770
  signal: AbortSignal.timeout(CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS)
@@ -717,6 +780,7 @@ async function terminateCodexBackgroundTerminals(client, threadId) {
717
780
  threadId,
718
781
  limit: 1
719
782
  }, options)).data.length > 0) throw new Error("native background terminals remain running");
783
+ if (oneShotCliRun) throw new Error("native terminal termination did not confirm process cleanup");
720
784
  }
721
785
  } catch (cause) {
722
786
  throw new Error("Codex background-terminal cleanup failed; inspect the thread's running terminals before starting more work.", { cause });
@@ -737,4 +801,4 @@ async function unsubscribeCodexThreadBestEffort(client, params) {
737
801
  }
738
802
  }
739
803
  //#endregion
740
- export { shouldRecordNativeToolTranscript as A, readNonNegativeInteger as B, isSideEffectingNativeToolItem as C, itemTitle as D, itemStatus as E, readHookOutputEntries as F, splitPlanText as H, readItem as I, readItemString as L, extractRawAssistantText as M, normalizeOptionalString$1 as N, matchesCodexSnapshotTurn as O, readCodexErrorNotificationMessage as P, readNonEmptyString as R, isNonSuccessItemStatus as S, itemName as T, readNullableString as V, readCodexNotificationTurnId as _, closeCodexStartupClientBestEffort as a, auditNativeToolUnfinishedStatus as b, isCodexAppServerUnsafeSubscriptionError as c, unsubscribeCodexThreadBestEffort as d, CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS as f, readCodexNotificationThreadId as g, isCodexNotificationForTurn as h, assertCodexThreadResumeSubscription as i, shouldSynthesizeToolProgressForItem as j, shouldClearTerminalPresentationForNativeItem as k, retireUnsafeCodexTurnClientBestEffort as l, CodexProjectionDiagnostics as m, CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS as n, interruptCodexTurnAndWaitBestEffort as o, getCodexAppServerTurnRouter as p, CodexAppServerUnsafeSubscriptionError as r, isCodexAlreadyTerminalInterruptError as s, CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS as t, terminateCodexBackgroundTerminals as u, auditNativeToolName as v, itemKind as w, isMutatingNativeToolItem as x, auditNativeToolTerminalStatus as y, readNonEmptyStringArray as z };
804
+ export { shouldRecordNativeToolTranscript as A, readNonEmptyStringArray as B, isSideEffectingNativeToolItem as C, itemTitle as D, itemStatus as E, readCodexProviderRefusal as F, readNullableString as H, readHookOutputEntries as I, readItem as L, extractRawAssistantText as M, normalizeOptionalString$1 as N, matchesCodexSnapshotTurn as O, readCodexErrorNotificationMessage as P, readItemString as R, isNonSuccessItemStatus as S, itemName as T, splitPlanText as U, readNonNegativeInteger as V, readCodexNotificationTurnId as _, closeCodexStartupClientBestEffort as a, auditNativeToolUnfinishedStatus as b, isCodexNoActiveTurnInterruptError as c, unsubscribeCodexThreadBestEffort as d, CODEX_APP_SERVER_NATIVE_TURN_WAIT_TIMEOUT_MS as f, readCodexNotificationThreadId as g, isCodexNotificationForTurn as h, assertCodexThreadResumeSubscription as i, shouldSynthesizeToolProgressForItem as j, shouldClearTerminalPresentationForNativeItem as k, retireUnsafeCodexTurnClientBestEffort as l, CodexProjectionDiagnostics as m, CODEX_APP_SERVER_UNSUBSCRIBE_TIMEOUT_MS as n, interruptCodexTurnAndWaitBestEffort as o, getCodexAppServerTurnRouter as p, CodexAppServerUnsafeSubscriptionError as r, isCodexAppServerUnsafeSubscriptionError as s, CODEX_APP_SERVER_INTERRUPT_TIMEOUT_MS as t, terminateCodexBackgroundTerminals as u, auditNativeToolName as v, itemKind as w, isMutatingNativeToolItem as x, auditNativeToolTerminalStatus as y, readNonEmptyString as z };
@@ -1,11 +1,11 @@
1
- import { $t as isJsonObject, Qt as flattenCodexDynamicToolFunctions } from "./shared-client-DxcfF9KX.js";
2
- import { ct as isMessageOnlyCodexSourceReply, et as areCodexDynamicToolFingerprintsCompatible, mt as isContextEngineBindingCompatible } from "./thread-lifecycle-DAcEJ_Om.js";
3
- import { n as readCodexMirroredSessionHistoryMessages } from "./session-history-C5J1AKzG.js";
1
+ import { a as flattenCodexDynamicToolFunctions, o as isJsonObject } from "./protocol-CAAcVIKF.js";
2
+ import { t as readCodexMirroredSessionHistoryMessages } from "./session-history-Cz-tOOYj.js";
3
+ import { Z as areCodexDynamicToolFingerprintsCompatible, at as isMessageOnlyCodexSourceReply, dt as isContextEngineBindingCompatible } from "./thread-lifecycle-D1pzRwHB.js";
4
4
  import { readNonBlankString } from "openclaw/plugin-sdk/string-coerce-runtime";
5
- import path from "node:path";
6
- import { buildBootstrapContextForFiles, buildWatchedSessionsHarnessContext, embeddedAgentLog, resolveBootstrapFilesForRun } from "openclaw/plugin-sdk/agent-harness-runtime";
7
5
  import { createHash } from "node:crypto";
6
+ import path from "node:path";
8
7
  import { resolveAgentWorkspaceDir } from "openclaw/plugin-sdk/agent-runtime";
8
+ import { buildBootstrapContextForFiles, buildWatchedSessionsHarnessContext, embeddedAgentLog, resolveBootstrapFilesForRun } from "openclaw/plugin-sdk/agent-harness-runtime";
9
9
  import { resolveBootstrapFilesForPreparation } from "openclaw/plugin-sdk/codex-mcp-projection";
10
10
  import { prepareMemorySystemPromptAddition } from "openclaw/plugin-sdk/core";
11
11
  import { MESSAGE_TOOL_DELIVERY_HINTS } from "openclaw/plugin-sdk/message-tool-delivery-hints";
@@ -32,8 +32,8 @@ const CODEX_BOOTSTRAP_CONTEXT_ORDER = /* @__PURE__ */ new Map([
32
32
  ]);
33
33
  /** Reads mirrored Codex session history for harness hooks. */
34
34
  async function readMirroredSessionHistoryMessages(params) {
35
- const { admission, ...target } = params;
36
- const messages = await readCodexMirroredSessionHistoryMessages(target, admission, "model-context");
35
+ const { admission, signal, ...target } = params;
36
+ const messages = await readCodexMirroredSessionHistoryMessages(target, admission, "model-context", signal);
37
37
  if (!messages) embeddedAgentLog.warn("failed to read mirrored session history for codex harness hooks", { sessionFile: params.sessionFile });
38
38
  return messages;
39
39
  }
@@ -214,6 +214,7 @@ function buildCodexSystemPromptReport(params) {
214
214
  injectedWorkspaceFiles: buildCodexBootstrapInjectionStats({
215
215
  bootstrapFiles: params.workspaceBootstrapContext.bootstrapFiles,
216
216
  injectedFiles: params.workspaceBootstrapContext.promptContextFiles ?? [],
217
+ omitReferenceFiles: params.omitWorkspaceReferences,
217
218
  developerInstructionFiles: [...params.workspaceBootstrapContext.threadDeveloperInstructionFiles ?? [], ...params.workspaceBootstrapContext.turnScopedDeveloperInstructionFiles ?? []],
218
219
  memoryToolRoutedBootstrapFiles: params.workspaceBootstrapContext.memoryToolRoutedBootstrapFiles ?? [],
219
220
  memoryToolRouted: params.workspaceBootstrapContext.memoryToolRouted === true
@@ -304,8 +305,9 @@ function buildCodexBootstrapInjectionStats(params) {
304
305
  injectedChars: null,
305
306
  truncated: null
306
307
  };
307
- const injectedChars = memoryToolRoutedFile ? 0 : injected?.length ?? 0;
308
- const truncated = memoryToolRoutedFile ? false : !file.missing && injectedChars < rawChars;
308
+ const omitted = memoryToolRoutedFile || params.omitReferenceFiles && readCodexIndexedContextFileContent(injectedIndex, pathValue, fileName) !== void 0;
309
+ const injectedChars = omitted ? 0 : injected?.length ?? 0;
310
+ const truncated = omitted ? false : !file.missing && injectedChars < rawChars;
309
311
  return {
310
312
  name: displayName,
311
313
  path: pathValue,
@@ -1,6 +1,5 @@
1
- import { $t as isJsonObject } from "./shared-client-DxcfF9KX.js";
2
- import { asSafeIntegerInRange, readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
3
- import { normalizeUsage } from "openclaw/plugin-sdk/agent-harness-runtime";
1
+ import { o as isJsonObject } from "./protocol-CAAcVIKF.js";
2
+ import { readStringField } from "openclaw/plugin-sdk/string-coerce-runtime";
4
3
  //#region extensions/codex/src/app-server/attempt-notifications.ts
5
4
  const CODEX_TURN_ABORT_MARKER_START = "<turn_aborted>";
6
5
  const CODEX_TURN_ABORT_MARKER_END = "</turn_aborted>";
@@ -41,10 +40,6 @@ function isAssistantCommentaryCompletionNotification(notification) {
41
40
  const item = isJsonObject(notification.params.item) ? notification.params.item : void 0;
42
41
  return Boolean(item && readStringField(item, "type") === "agentMessage" && (readStringField(item, "phase") === "commentary" || readStringField(item, "delivery") === "async"));
43
42
  }
44
- /** A retryable native error is not a terminal outcome for bounded operations. */
45
- function isRetryableErrorNotification(value) {
46
- return isJsonObject(value) && value.willRetry === true;
47
- }
48
43
  /** Returns true for terminal app-server thread status strings. */
49
44
  function isTerminalTurnStatus(status) {
50
45
  return status === "completed" || status === "interrupted" || status === "failed";
@@ -111,85 +106,4 @@ function isNonEmptyString(value) {
111
106
  return typeof value === "string" && value.length > 0;
112
107
  }
113
108
  //#endregion
114
- //#region extensions/codex/src/app-server/event-projector-usage.ts
115
- function readTokenCount(record, key) {
116
- return asSafeIntegerInRange(record[key], { min: 0 });
117
- }
118
- function readCodexThreadTokenUsage(params) {
119
- const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
120
- const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
121
- return last ? normalizeCodexResponseTokenUsage(last) : void 0;
122
- }
123
- function readCodexThreadContextSnapshot(params) {
124
- const tokenUsage = isJsonObject(params.tokenUsage) ? params.tokenUsage : void 0;
125
- const last = tokenUsage && isJsonObject(tokenUsage.last) ? tokenUsage.last : void 0;
126
- const modelContextWindow = tokenUsage ? readTokenCount(tokenUsage, "modelContextWindow") : void 0;
127
- const activeContextTokens = last ? readTokenCount(last, "totalTokens") : void 0;
128
- const inputTokens = last ? readTokenCount(last, "inputTokens") : void 0;
129
- const cachedInputTokens = last ? readTokenCount(last, "cachedInputTokens") : void 0;
130
- const cacheWriteInputTokens = last ? readTokenCount(last, "cacheWriteInputTokens") : void 0;
131
- const reasoningOutputTokens = last ? readTokenCount(last, "reasoningOutputTokens") : void 0;
132
- return {
133
- ...activeContextTokens !== void 0 ? { activeContextTokens } : {},
134
- ...cachedInputTokens !== void 0 ? { cachedInputTokens } : {},
135
- ...cacheWriteInputTokens !== void 0 ? { cacheWriteInputTokens } : {},
136
- ...inputTokens !== void 0 ? { inputTokens } : {},
137
- ...modelContextWindow && modelContextWindow > 0 ? { modelContextWindow } : {},
138
- ...inputTokens !== void 0 ? { promptTokens: inputTokens } : {},
139
- ...reasoningOutputTokens !== void 0 ? { reasoningOutputTokens } : {}
140
- };
141
- }
142
- function projectCodexThreadUsageUpdate(params, currentUsage, applyUsage, emitContext) {
143
- applyUsage(readCodexThreadTokenUsage(params) ?? currentUsage);
144
- const context = readCodexThreadContextSnapshot(params);
145
- if (Object.keys(context).length > 0) emitContext(context);
146
- }
147
- function normalizeCodexResponseTokenUsage(record) {
148
- const totalTokens = readTokenCount(record, "totalTokens");
149
- const inputTokens = readTokenCount(record, "inputTokens");
150
- const cacheRead = readTokenCount(record, "cachedInputTokens");
151
- const output = readTokenCount(record, "outputTokens");
152
- const reasoningTokens = readTokenCount(record, "reasoningOutputTokens");
153
- const cacheWrite = record.cacheWriteInputTokens === void 0 ? 0 : readTokenCount(record, "cacheWriteInputTokens");
154
- const hasCoherentInput = inputTokens !== void 0 && cacheRead !== void 0 && cacheWrite !== void 0 && cacheRead + cacheWrite <= inputTokens;
155
- const hasCoherentContext = hasCoherentInput && totalTokens !== void 0 && output !== void 0 && totalTokens === inputTokens + output;
156
- const usage = normalizeUsage({
157
- input: hasCoherentInput ? inputTokens - cacheRead - cacheWrite : void 0,
158
- output,
159
- cacheRead,
160
- cacheWrite,
161
- reasoningTokens,
162
- total: totalTokens
163
- });
164
- if (!usage) return;
165
- return {
166
- ...usage,
167
- contextUsage: hasCoherentContext ? {
168
- state: "available",
169
- promptTokens: inputTokens,
170
- totalTokens
171
- } : { state: "unavailable" }
172
- };
173
- }
174
- var CodexResponseCompletionProjection = class {
175
- constructor() {
176
- this.responseIds = /* @__PURE__ */ new Set();
177
- }
178
- get modelIterations() {
179
- return this.responseIds.size;
180
- }
181
- clear() {
182
- this.usage = void 0;
183
- }
184
- record(params, reportOutputTokens) {
185
- const responseId = readStringField(params, "responseId");
186
- if (!responseId || this.responseIds.has(responseId)) return;
187
- this.responseIds.add(responseId);
188
- const usage = isJsonObject(params.usage) ? params.usage : void 0;
189
- this.usage = usage ? normalizeCodexResponseTokenUsage(usage) : void 0;
190
- const outputTokens = this.usage?.output;
191
- if (outputTokens !== void 0) reportOutputTokens?.(outputTokens);
192
- }
193
- };
194
- //#endregion
195
- export { codexExecutionToolName as a, isPendingOpenClawDynamicToolCompletionNotification as c, isTerminalTurnStatus as d, readCodexNotificationItem as f, updateActiveTurnItemIds as h, readCodexThreadContextSnapshot as i, isRawFunctionToolOutputCompletionNotification as l, readRawResponseToolCallId as m, normalizeCodexResponseTokenUsage as n, isAssistantCommentaryCompletionNotification as o, readNotificationItemId as p, projectCodexThreadUsageUpdate as r, isCodexTurnAbortMarkerNotification as s, CodexResponseCompletionProjection as t, isRetryableErrorNotification as u };
109
+ export { isRawFunctionToolOutputCompletionNotification as a, readNotificationItemId as c, isPendingOpenClawDynamicToolCompletionNotification as i, readRawResponseToolCallId as l, isAssistantCommentaryCompletionNotification as n, isTerminalTurnStatus as o, isCodexTurnAbortMarkerNotification as r, readCodexNotificationItem as s, codexExecutionToolName as t, updateActiveTurnItemIds as u };