@openclaw/codex 2026.9.1-beta.1 → 2026.9.2

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 (81) hide show
  1. package/dist/api.js +8 -9
  2. package/dist/{attempt-client-cleanup-bfsmcQ6m.js → attempt-client-cleanup-Bp1ZOnk2.js} +105 -75
  3. package/dist/attempt-context-CSazkWns.js +634 -0
  4. package/dist/{auth-binding-B4FfbcCg.js → auth-binding-Ds_QVm-X.js} +18 -3
  5. package/dist/{bounded-turn-B7iBUcuP.js → bounded-turn-DxGJRYbY.js} +53 -57
  6. package/dist/{capabilities-BRMh0aIq.js → capabilities-B1mgvpP8.js} +2 -1
  7. package/dist/cli-metadata.js +1 -1
  8. package/dist/{command-formatters-DEsIufkt.js → command-formatters-DSbGMXA0.js} +5 -4
  9. package/dist/{command-handlers-D_-1_qRp.js → command-handlers-DOJvGv6-.js} +243 -148
  10. package/dist/{compact-BglNFZrQ.js → compact-Y_xBqrHN.js} +109 -65
  11. package/dist/{config-giW8X0QA.js → config-CyapYSji.js} +328 -374
  12. package/dist/config-utils-C57JiJrU.js +69 -0
  13. package/dist/{context-compaction-activity-BOeJf7yo.js → context-compaction-activity-CMla5FPJ.js} +4 -1
  14. package/dist/{conversation-binding-data-CW2GuupV.js → conversation-binding-data-BiodpIzq.js} +2 -1
  15. package/dist/doctor-contract-api.js +144 -14
  16. package/dist/{dynamic-tools-Dnlfa--w.js → dynamic-tools-BwpvTxaX.js} +1119 -1135
  17. package/dist/{effective-mcp-catalog-CTeGrnfO.js → effective-mcp-catalog-CY9Jn4bA.js} +4 -3
  18. package/dist/{event-projector-assistant-message-C5-Ds8mA.js → event-projector-assistant-message-B9kp6iGC.js} +15 -6
  19. package/dist/event-projector-usage-ZqEVbAEY.js +212 -0
  20. package/dist/{harness-Csz0F-DK.js → harness-Czh2Sdoc.js} +65 -52
  21. package/dist/harness.js +1 -1
  22. package/dist/{image-payload-sanitizer-CnfoUPCE.js → image-payload-sanitizer-tupAr-2o.js} +29 -15
  23. package/dist/index.js +495 -457
  24. package/dist/{isolated-completion-Cv6FqygM.js → isolated-completion-CRh-51AK.js} +9 -21
  25. package/dist/{managed-binary-DFYK4DWq.js → managed-binary-DcpnJF9x.js} +117 -80
  26. package/dist/media-understanding-provider.js +1 -1
  27. package/dist/model-catalog-DT5vo6qo.js +101 -0
  28. package/dist/{models-TS3HBU-q.js → models-CcrgSMQR.js} +26 -29
  29. package/dist/{native-subagent-monitor-4Mfq2HDs.js → native-subagent-monitor-B3bvQGcg.js} +63 -122
  30. package/dist/{node-exec-server.runtime-BpWqJO1V.js → node-exec-server.runtime-nfbUOtUB.js} +10 -7
  31. package/dist/{plugin-approval-roundtrip-bUm777tR.js → plugin-approval-roundtrip-aQVdyL5g.js} +30 -3
  32. package/dist/{plugin-marketplace-discovery-B9DvaAG-.js → plugin-marketplace-discovery-B7gHXJ3d.js} +44 -30
  33. package/dist/{plugin-metadata-cache-CTCT3w5L.js → plugin-metadata-cache-BwCLTY_U.js} +6 -6
  34. package/dist/provider-capabilities-BpG9Ltc5.js +101 -0
  35. package/dist/{rate-limits-C5_D8Gmb.js → rate-limits-Fx_l4eNa.js} +3 -2
  36. package/dist/{sandbox-guard-kuWTn9C5.js → request-C8H22rPi.js} +195 -2
  37. package/dist/{run-attempt-DYc0QCBF.js → run-attempt-BzthFQSM.js} +1616 -2634
  38. package/dist/{runtime-artifact-BvyT1uyd.js → runtime-artifact-Bh_gf6-t.js} +22 -15
  39. package/dist/{session-binding-Bcynfd-_.js → session-binding-4Ki04sW-.js} +282 -399
  40. package/dist/session-binding-record-CyaXZvTe.js +270 -0
  41. package/dist/{session-catalog-DaLKVtpH.js → session-catalog-B47uwekb.js} +812 -504
  42. package/dist/{session-cli-DMc4oS2w.js → session-cli-BjLhpmS1.js} +1 -1
  43. package/dist/session-history-DWmMqiqW.js +93 -0
  44. package/dist/session-history-read-LHldwvyh.js +36 -0
  45. package/dist/session-history-worker-runtime.js +48 -0
  46. package/dist/session-history.worker-zZVcx0ME.js +267 -0
  47. package/dist/session-history.worker.js +2 -0
  48. package/dist/session-initialization-BCFVnLL4.js +75 -0
  49. package/dist/{session-permission-policy-BrNH1bjy.js → session-permission-policy-BaueHmSj.js} +2 -2
  50. package/dist/session-retirement-DNdmYdFc.js +97 -0
  51. package/dist/{session-upstream-marker-BIkusb95.js → session-upstream-marker-DReTpGz6.js} +20 -4
  52. package/dist/settled-turn-context-BOM3Y1pl.js +45 -0
  53. package/dist/settled-turn-finalizer-BI-b1sry.js +115 -0
  54. package/dist/{shared-client-DKz23hHY.js → shared-client-CKhX2kFt.js} +3659 -847
  55. package/dist/{side-question-DjA_jsNe.js → side-question-B6DWAw1A.js} +168 -81
  56. package/dist/{thread-lifecycle-L7oEkTlq.js → thread-lifecycle-DPK30jad.js} +2412 -2145
  57. package/dist/{thread-ownership-DZeuKH1j.js → thread-ownership-CbucAmmp.js} +27 -16
  58. package/dist/thread-policy-CTalhWFy.js +105 -0
  59. package/dist/{plugin-app-cache-key-C1CAdfcP.js → thread-resume-BLgqkUc1.js} +61 -9
  60. package/dist/{transcript-mirror-DsCMWBca.js → transcript-mirror-_njEB84z.js} +114 -110
  61. package/dist/transcript-mirror-attestation-Byl34PC-.js +76 -0
  62. package/dist/transport-stdio-CzTngV0j.js +728 -0
  63. package/dist/{upstream-prompt-provenance-CFmsKwr9.js → upstream-prompt-provenance-LphB8slG.js} +8 -4
  64. package/dist/upstream-session-fork-1fwbNKzQ.js +886 -0
  65. package/dist/{usage-ROIaW3wo.js → usage-i9fv5-4m.js} +3 -3
  66. package/dist/{web-search-provider.runtime-ClaNPV7N.js → web-search-provider.runtime-DKQn67A7.js} +3 -3
  67. package/openclaw.plugin.json +1 -30
  68. package/package.json +6 -6
  69. package/dist/binding-connection-BMvPX73o.js +0 -45
  70. package/dist/command-rpc-CCeCkf_v.js +0 -90
  71. package/dist/event-projector-usage-Bk1I90Bg.js +0 -328
  72. package/dist/incognito-session-ET_ufDH-.js +0 -2
  73. package/dist/model-catalog-i9rNBthX.js +0 -48
  74. package/dist/protocol-validators-VeJxxJ0U.js +0 -2421
  75. package/dist/request-DXXGHko0.js +0 -157
  76. package/dist/session-catalog-home-id-BNwAJ9D7.js +0 -18
  77. package/dist/session-retirement-CcNC3YSY.js +0 -36
  78. package/dist/settled-turn-finalizer-Dc3ApjU4.js +0 -328
  79. package/dist/thread-resume-BE9qNEW0.js +0 -30
  80. package/dist/transport-stdio-DhoGy33Z.js +0 -99
  81. package/dist/upstream-session-fork-DlaHxSLC.js +0 -326
@@ -1,31 +1,27 @@
1
- import { G as CodexAppServerRpcError, J as consumeCodexAppServerLiveThread, et as retainCodexAppServerLiveThread, o as getLeasedSharedCodexAppServerClient, p as releaseLeasedSharedCodexAppServerClient, vt as isJsonObject } from "./shared-client-DKz23hHY.js";
2
- import { d as sessionBindingIdentity, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-Bcynfd-_.js";
3
- import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, d as unsubscribeCodexThreadBestEffort, g as readCodexNotificationThreadId, r as CodexAppServerUnsafeSubscriptionError, s as isCodexAlreadyTerminalInterruptError } from "./attempt-client-cleanup-bfsmcQ6m.js";
4
- import { i as readCodexThreadContextSnapshot, x as readCodexNotificationItem } from "./event-projector-usage-Bk1I90Bg.js";
5
- import { t as isIncognitoSessionKey } from "./incognito-session-ET_ufDH-.js";
6
- import { t as resumeCodexAppServerThread } from "./thread-resume-BE9qNEW0.js";
7
- import { n as resolveCodexNativeExecutionBlock } from "./sandbox-guard-kuWTn9C5.js";
8
- import { t as isSameCodexAppServerThreadOwner } from "./thread-ownership-DZeuKH1j.js";
9
- import { n as resolveCodexBindingAppServerConnection } from "./binding-connection-BMvPX73o.js";
10
- import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-BOeJf7yo.js";
1
+ import { l as sessionBindingIdentity } from "./session-binding-record-CyaXZvTe.js";
2
+ import { B as isJsonObject } from "./config-CyapYSji.js";
3
+ import { Mt as retainCodexAppServerLiveThread, U as isCodexAppServerPrewriteRequestCancellationError, c as getLeasedSharedCodexAppServerClient, h as releaseLeasedSharedCodexAppServerClient, q as CodexAppServerRpcError, wt as consumeCodexAppServerLiveThread } from "./shared-client-CKhX2kFt.js";
4
+ import { l as resolveCodexSessionBinding, t as CODEX_APP_SERVER_BINDING_GUARDED_REQUEST_TIMEOUT_MS } from "./session-binding-4Ki04sW-.js";
5
+ import { _ as readCodexNotificationTurnId, a as closeCodexStartupClientBestEffort, c as isCodexNoActiveTurnInterruptError, d as unsubscribeCodexThreadBestEffort, g as readCodexNotificationThreadId, r as CodexAppServerUnsafeSubscriptionError } from "./attempt-client-cleanup-Bp1ZOnk2.js";
6
+ import { n as readCodexThreadContextSnapshot, u as readCodexNotificationItem } from "./event-projector-usage-ZqEVbAEY.js";
7
+ import { t as resumeCodexAppServerThread } from "./thread-resume-BLgqkUc1.js";
8
+ import { l as isIncognitoSessionKey, o as withCodexAppServerThreadMutation, t as isSameCodexAppServerThreadOwner } from "./thread-ownership-CbucAmmp.js";
9
+ import { r as assertCodexSupervisionThreadLineage, s as resolveCodexBindingAppServerConnection } from "./thread-policy-CTalhWFy.js";
10
+ import { s as resolveCodexNativeExecutionBlock } from "./request-C8H22rPi.js";
11
+ import { t as persistCodexContextCompactionActivity } from "./context-compaction-activity-CMla5FPJ.js";
11
12
  import { asOptionalRecord } from "openclaw/plugin-sdk/string-coerce-runtime";
13
+ import { resolveDefaultAgentId } from "openclaw/plugin-sdk/agent-scope-runtime";
12
14
  import { createDeferred } from "openclaw/plugin-sdk/extension-shared";
13
15
  import { embeddedAgentLog, resolveCompactionTimeoutMs } from "openclaw/plugin-sdk/agent-harness-runtime";
14
- import { resolveAgentDir as resolveAgentDir$1 } from "openclaw/plugin-sdk/agent-runtime";
15
- import { resolveDefaultAgentId as resolveDefaultAgentId$1 } from "openclaw/plugin-sdk/agent-scope-runtime";
16
+ import { resolveAgentDir as resolveAgentDir$2 } from "openclaw/plugin-sdk/agent-runtime";
16
17
  import { AsyncLocalStorage } from "node:async_hooks";
17
18
  import { coerceErrorMessage } from "openclaw/plugin-sdk/error-runtime";
18
- import { KeyedAsyncQueue } from "openclaw/plugin-sdk/keyed-async-queue";
19
19
  import { createDedupeCache } from "openclaw/plugin-sdk/dedupe-runtime";
20
20
  //#region extensions/codex/src/app-server/compact.ts
21
- /**
22
- * Native Codex app-server compaction bridge for bound OpenClaw sessions.
23
- */
24
21
  const warnedIgnoredCompactionOverrides = createDedupeCache({
25
22
  ttlMs: 0,
26
23
  maxSize: 4096
27
24
  });
28
- const codexNativeCompactionQueue = new KeyedAsyncQueue();
29
25
  const CODEX_NATIVE_COMPACTION_INTERRUPT_GRACE_MS = 3e4;
30
26
  function watchCodexNativeCompactionCompletion(params) {
31
27
  const runOutsideBindingLease = AsyncLocalStorage.snapshot();
@@ -82,7 +78,7 @@ function watchCodexNativeCompactionCompletion(params) {
82
78
  threadId: params.threadId,
83
79
  turnId: compactionTurnId
84
80
  }, { timeoutMs: Math.max(1, params.interruptGraceMs) }).catch((error) => {
85
- if (isCodexAlreadyTerminalInterruptError(error)) {
81
+ if (isCodexNoActiveTurnInterruptError(error)) {
86
82
  if (compactionItemCompleted) {
87
83
  complete();
88
84
  return;
@@ -196,7 +192,7 @@ function watchCodexNativeCompactionCompletion(params) {
196
192
  async function runExclusiveCodexNativeCompaction(threadId, signal, run) {
197
193
  signal?.throwIfAborted();
198
194
  let started = false;
199
- const queued = codexNativeCompactionQueue.enqueue(threadId, async () => {
195
+ const queued = withCodexAppServerThreadMutation(threadId, async () => {
200
196
  started = true;
201
197
  signal?.throwIfAborted();
202
198
  return run();
@@ -282,7 +278,7 @@ async function compactCodexNativeThread(params, options) {
282
278
  config: params.config,
283
279
  sessionKey: params.sandboxSessionKey ?? params.sessionKey,
284
280
  sessionId: params.sessionId,
285
- agentId: params.agentId,
281
+ agentId: params.sandboxAgentId ?? params.agentId,
286
282
  sandbox,
287
283
  surface: "native compaction"
288
284
  });
@@ -297,7 +293,33 @@ async function compactCodexNativeThread(params, options) {
297
293
  agentId: params.agentId,
298
294
  config: params.config
299
295
  });
300
- const initialBinding = await options.bindingStore.read(bindingIdentity);
296
+ const abortedResult = (expectedThreadId, currentThreadId = expectedThreadId) => options.allowNonManualNativeRequest ? skippedCodexNativeCompactionResult(params, {
297
+ reason: "codex app-server compaction aborted before native compaction",
298
+ code: "aborted_before_native_compaction",
299
+ request: options.nativeCompactionRequest ?? "after_context_engine",
300
+ ...expectedThreadId ? {
301
+ expectedThreadId,
302
+ currentThreadId
303
+ } : {}
304
+ }) : {
305
+ ok: false,
306
+ compacted: false,
307
+ reason: "codex app-server compaction aborted while waiting to start"
308
+ };
309
+ let resolvedBinding;
310
+ try {
311
+ resolvedBinding = await resolveCodexSessionBinding({
312
+ bindingStore: options.bindingStore,
313
+ identity: bindingIdentity,
314
+ config: params.config,
315
+ storePath: params.sessionTarget?.storePath,
316
+ signal: params.abortSignal
317
+ });
318
+ } catch (error) {
319
+ if (!params.abortSignal?.aborted) throw error;
320
+ return abortedResult(options.bindingStore.read(bindingIdentity)?.threadId);
321
+ }
322
+ const { binding: initialBinding, assertCurrent } = resolvedBinding;
301
323
  if (!initialBinding?.threadId) return failedCodexThreadBindingCompactionResult(params, {
302
324
  reason: "no codex app-server thread binding",
303
325
  recovery: "missing_thread_binding"
@@ -317,13 +339,13 @@ async function compactCodexNativeThread(params, options) {
317
339
  let connection;
318
340
  try {
319
341
  const config = params.config ?? {};
320
- const agentId = params.agentId ?? readAgentIdFromSessionKey(params.sessionKey) ?? resolveDefaultAgentId$1(config);
342
+ const agentId = params.agentId ?? readAgentIdFromSessionKey(params.sessionKey) ?? resolveDefaultAgentId(config);
321
343
  connection = resolveCodexBindingAppServerConnection({
322
344
  binding,
323
345
  authProfileId: requestedAuthProfileId ?? binding.authProfileId,
324
346
  pluginConfig: options.pluginConfig,
325
347
  config,
326
- agentDir: resolveAgentDir$1(config, agentId)
348
+ agentDir: resolveAgentDir$2(config, agentId)
327
349
  });
328
350
  } catch (error) {
329
351
  return {
@@ -350,6 +372,7 @@ async function compactCodexNativeThread(params, options) {
350
372
  };
351
373
  try {
352
374
  return await runExclusiveCodexNativeCompaction(binding.threadId, params.abortSignal, async () => {
375
+ assertCurrent();
353
376
  const client = await clientFactory({
354
377
  startOptions: appServer.start,
355
378
  ...preparedApiKey ? { preparedAuth: {
@@ -357,7 +380,8 @@ async function compactCodexNativeThread(params, options) {
357
380
  apiKey: preparedApiKey
358
381
  } } : { authProfileId: connection.clientAuthProfileId },
359
382
  agentDir: params.agentDir,
360
- config: params.config
383
+ config: params.config,
384
+ assertCurrent
361
385
  });
362
386
  let releaseThreadSubscription;
363
387
  let retainedThreadOwnership;
@@ -392,30 +416,44 @@ async function compactCodexNativeThread(params, options) {
392
416
  if (await options.bindingStore.mutate(bindingIdentity, {
393
417
  kind: "clear",
394
418
  threadId: binding.threadId
395
- })) return;
396
- if ((await options.bindingStore.read(bindingIdentity))?.threadId !== binding.threadId) return;
419
+ }, assertCurrent)) return;
420
+ if (options.bindingStore.read(bindingIdentity)?.threadId !== binding.threadId) return;
397
421
  throw new Error("failed to detach unconfirmed codex app-server thread binding");
398
422
  }
399
423
  });
400
424
  const acquireThreadSubscription = async (timeoutMs) => {
401
425
  if (!isIncognitoSessionKey(params.sessionKey)) {
402
426
  retainedThreadOwnership = await consumeCodexAppServerLiveThread(client, binding.threadId);
403
- if (!retainedThreadOwnership) await resumeCodexAppServerThread({
404
- client,
405
- abandonClient: async () => closeCodexStartupClientBestEffort(client),
406
- request: {
427
+ if (!retainedThreadOwnership) {
428
+ const resumed = await resumeCodexAppServerThread({
429
+ client,
430
+ abandonClient: async () => closeCodexStartupClientBestEffort(client),
431
+ request: {
432
+ threadId: binding.threadId,
433
+ excludeTurns: true
434
+ },
435
+ timeoutMs: timeoutMs ?? appServer.requestTimeoutMs,
436
+ assertCurrent,
437
+ ...params.abortSignal ? { signal: params.abortSignal } : {}
438
+ });
439
+ releaseThreadSubscription = async () => releaseCompactionThread(binding.threadId);
440
+ assertCodexSupervisionThreadLineage(binding, resumed.thread);
441
+ } else if (binding.connectionScope === "supervision") {
442
+ releaseThreadSubscription = async () => retainedThreadOwnership?.release(binding.threadId);
443
+ const { thread } = await client.request("thread/read", {
407
444
  threadId: binding.threadId,
408
- excludeTurns: true
409
- },
410
- timeoutMs: timeoutMs ?? appServer.requestTimeoutMs,
411
- ...params.abortSignal ? { signal: params.abortSignal } : {}
412
- });
413
- releaseThreadSubscription = async () => releaseCompactionThread(binding.threadId);
445
+ includeTurns: false
446
+ }, { assertCurrent });
447
+ assertCurrent();
448
+ retainedThreadOwnership.assertCurrent();
449
+ assertCodexSupervisionThreadLineage(binding, thread);
450
+ }
451
+ releaseThreadSubscription ??= async () => releaseCompactionThread(binding.threadId);
414
452
  }
415
453
  };
416
454
  try {
417
455
  const guardedResult = await options.bindingStore.withLease(bindingIdentity, async () => {
418
- const currentBinding = await options.bindingStore.read(bindingIdentity);
456
+ const currentBinding = options.bindingStore.read(bindingIdentity);
419
457
  if (params.abortSignal?.aborted) {
420
458
  if (!options.allowNonManualNativeRequest) params.abortSignal.throwIfAborted();
421
459
  return {
@@ -429,6 +467,7 @@ async function compactCodexNativeThread(params, options) {
429
467
  })
430
468
  };
431
469
  }
470
+ assertCurrent();
432
471
  if (!currentBinding || !isSameNativeCompactionBinding(currentBinding, binding)) {
433
472
  embeddedAgentLog.warn("codex app-server compaction could not use the thread binding because it changed", {
434
473
  sessionId: params.sessionId,
@@ -459,23 +498,38 @@ async function compactCodexNativeThread(params, options) {
459
498
  sessionId: params.sessionId,
460
499
  bindingStore: options.bindingStore,
461
500
  identity: bindingIdentity,
462
- binding
501
+ binding,
502
+ assertCurrent
463
503
  });
504
+ assertCurrent();
464
505
  try {
465
506
  completionWatch.beginRequest();
466
- if (guardedRequestTimeoutMs === void 0) await client.request("thread/compact/start", { threadId: binding.threadId });
467
- else await client.request("thread/compact/start", { threadId: binding.threadId }, { timeoutMs: guardedRequestTimeoutMs });
507
+ await client.request("thread/compact/start", { threadId: binding.threadId }, {
508
+ ...guardedRequestTimeoutMs === void 0 ? {} : { timeoutMs: guardedRequestTimeoutMs },
509
+ assertCurrent: () => {
510
+ try {
511
+ assertCurrent();
512
+ } catch (error) {
513
+ compactionRequestDefinitelyRejected = true;
514
+ throw error;
515
+ }
516
+ }
517
+ });
468
518
  return {
469
519
  started: true,
470
520
  accepted: true
471
521
  };
472
522
  } catch (error) {
473
- if (error instanceof CodexAppServerRpcError) {
474
- await options.bindingStore.mutate(bindingIdentity, {
475
- kind: "set",
476
- binding
477
- });
478
- compactionRequestDefinitelyRejected = !isCodexThreadNotFoundError(error);
523
+ compactionRequestDefinitelyRejected ||= isCodexAppServerPrewriteRequestCancellationError(error);
524
+ if (compactionRequestDefinitelyRejected || error instanceof CodexAppServerRpcError) {
525
+ completionWatch.confirmRequestRejected();
526
+ if (!compactionRequestDefinitelyRejected) {
527
+ await options.bindingStore.mutate(bindingIdentity, {
528
+ kind: "set",
529
+ binding
530
+ }, assertCurrent);
531
+ compactionRequestDefinitelyRejected = !isCodexThreadNotFoundError(error);
532
+ }
479
533
  }
480
534
  return {
481
535
  started: true,
@@ -486,8 +540,7 @@ async function compactCodexNativeThread(params, options) {
486
540
  });
487
541
  if (!guardedResult.started) return guardedResult.result;
488
542
  if (!guardedResult.accepted) {
489
- if (guardedResult.error instanceof CodexAppServerRpcError) completionWatch.confirmRequestRejected();
490
- else await completionWatch.retireUnconfirmedRequest(`codex app-server compaction start was unconfirmed: ${coerceErrorMessage(guardedResult.error)}`);
543
+ if (!compactionRequestDefinitelyRejected && !(guardedResult.error instanceof CodexAppServerRpcError)) await completionWatch.retireUnconfirmedRequest(`codex app-server compaction start was unconfirmed: ${coerceErrorMessage(guardedResult.error)}`);
491
544
  throw guardedResult.error;
492
545
  }
493
546
  embeddedAgentLog.info("started codex app-server compaction", {
@@ -495,6 +548,7 @@ async function compactCodexNativeThread(params, options) {
495
548
  threadId: binding.threadId
496
549
  });
497
550
  const completion = await completionWatch.completion;
551
+ assertCurrent();
498
552
  if (!completion.completed) throw new Error(completion.reason);
499
553
  tokensAfter = completion.tokensAfter;
500
554
  if (completion.turnId && completion.itemId) await persistCodexContextCompactionActivity({
@@ -507,6 +561,7 @@ async function compactCodexNativeThread(params, options) {
507
561
  itemId: completion.itemId,
508
562
  timestamp: Date.now()
509
563
  });
564
+ assertCurrent();
510
565
  embeddedAgentLog.info("completed codex app-server compaction", {
511
566
  sessionId: params.sessionId,
512
567
  threadId: binding.threadId
@@ -534,8 +589,10 @@ async function compactCodexNativeThread(params, options) {
534
589
  try {
535
590
  if ((compactionSucceeded || compactionRequestDefinitelyRejected) && retainedThreadOwnership) {
536
591
  const ownership = retainedThreadOwnership;
537
- if (!(isSameCodexAppServerThreadOwner(await options.bindingStore.read(bindingIdentity), binding) && await options.bindingStore.withLease(bindingIdentity, async () => {
538
- if (!isSameCodexAppServerThreadOwner(await options.bindingStore.read(bindingIdentity), binding)) return false;
592
+ const currentBinding = options.bindingStore.read(bindingIdentity);
593
+ if (!(isSameCodexAppServerThreadOwner(currentBinding, binding) && await options.bindingStore.withLease(bindingIdentity, async () => {
594
+ const leasedBinding = options.bindingStore.read(bindingIdentity);
595
+ if (!isSameCodexAppServerThreadOwner(leasedBinding, binding)) return false;
539
596
  return await retainCodexAppServerLiveThread(client, binding.threadId, ownership.release, ownership.configFingerprint, ownership.serviceTier);
540
597
  }))) await releaseThreadSubscription?.();
541
598
  } else await releaseThreadSubscription?.();
@@ -561,20 +618,7 @@ async function compactCodexNativeThread(params, options) {
561
618
  });
562
619
  });
563
620
  } catch (error) {
564
- if (params.abortSignal?.aborted) {
565
- if (options.allowNonManualNativeRequest) return skippedCodexNativeCompactionResult(params, {
566
- reason: "codex app-server compaction aborted before native compaction",
567
- code: "aborted_before_native_compaction",
568
- request: options.nativeCompactionRequest ?? "after_context_engine",
569
- expectedThreadId: initialBinding.threadId,
570
- currentThreadId: binding.threadId
571
- });
572
- return {
573
- ok: false,
574
- compacted: false,
575
- reason: "codex app-server compaction aborted while waiting to start"
576
- };
577
- }
621
+ if (params.abortSignal?.aborted) return abortedResult(initialBinding.threadId, binding.threadId);
578
622
  throw error;
579
623
  }
580
624
  }
@@ -635,7 +679,7 @@ async function clearContextEngineProjectionBeforeNativeCompaction(params) {
635
679
  ...contextEngineBinding,
636
680
  projection: void 0
637
681
  } }
638
- });
682
+ }, params.assertCurrent);
639
683
  embeddedAgentLog.info("cleared codex context-engine projection before native compaction", {
640
684
  sessionId: params.sessionId,
641
685
  threadId: params.binding.threadId,