@bitkyc08/opencodex 2.14.0 → 2.14.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 (60) hide show
  1. package/README.md +55 -0
  2. package/gui/dist/assets/index-DUCH59lJ.css +1 -0
  3. package/gui/dist/assets/index-DUyQeU1j.js +76 -0
  4. package/gui/dist/index.html +2 -2
  5. package/package.json +1 -1
  6. package/src/adapters/command-code.ts +46 -6
  7. package/src/adapters/cursor/request-builder.ts +54 -10
  8. package/src/adapters/cursor/tool-definitions.ts +24 -0
  9. package/src/adapters/kiro.ts +10 -1
  10. package/src/adapters/openai-chat-url.ts +11 -0
  11. package/src/adapters/openai-chat.ts +7 -4
  12. package/src/adapters/openai-responses-url.ts +14 -0
  13. package/src/adapters/openai-responses.ts +111 -2
  14. package/src/adapters/tool-catalog-nudge.ts +26 -4
  15. package/src/bridge.ts +50 -3
  16. package/src/cli/init.ts +4 -17
  17. package/src/codex/auth-api.ts +2 -74
  18. package/src/codex/catalog/effort.ts +2 -1
  19. package/src/codex/catalog/metadata.ts +62 -12
  20. package/src/codex/catalog/native-models.ts +27 -0
  21. package/src/codex/catalog/parsing.ts +27 -8
  22. package/src/codex/catalog/provider-fetch.ts +47 -5
  23. package/src/codex/catalog/sync.ts +31 -8
  24. package/src/codex/catalog.ts +1 -1
  25. package/src/codex/features.ts +14 -3
  26. package/src/codex/model-cache.ts +7 -1
  27. package/src/codex/native-main-claim.ts +13 -2
  28. package/src/config.ts +79 -4
  29. package/src/generated/compatibility-version.json +74 -46
  30. package/src/lab/ledger/store.ts +0 -18
  31. package/src/lab/subject/installation-salt.ts +13 -2
  32. package/src/lib/app-owned-memory-stores.ts +22 -0
  33. package/src/lib/tool-argument-integers.ts +158 -0
  34. package/src/oauth/nous.ts +58 -9
  35. package/src/providers/base-url-choices.ts +10 -0
  36. package/src/providers/command-code-efforts.ts +18 -0
  37. package/src/providers/model-rename-migration.ts +202 -0
  38. package/src/providers/model-rename-startup.ts +28 -0
  39. package/src/providers/openai-tier-startup.ts +31 -2
  40. package/src/providers/quota.ts +9 -2
  41. package/src/providers/registry.ts +17 -10
  42. package/src/responses/spill-store.ts +5 -1
  43. package/src/responses/state.ts +50 -2
  44. package/src/router.ts +12 -1
  45. package/src/server/index.ts +3 -2
  46. package/src/server/management/api-key-usage.ts +31 -5
  47. package/src/server/management/config-routes.ts +51 -16
  48. package/src/server/management/logs-usage-routes.ts +48 -10
  49. package/src/server/management/provider-routes.ts +2 -1
  50. package/src/server/management/usage-summary-cache.ts +7 -1
  51. package/src/server/responses/collaboration.ts +12 -2
  52. package/src/server/responses/core.ts +33 -17
  53. package/src/server/responses/fetch-helpers.ts +12 -1
  54. package/src/server/responses/ws-upstream.ts +199 -0
  55. package/src/server/startup-health-cache.ts +12 -0
  56. package/src/usage/log.ts +430 -12
  57. package/src/vision/index.ts +25 -4
  58. package/src/vision/timeout-bounds.ts +9 -0
  59. package/gui/dist/assets/index-BNVYzdn0.css +0 -1
  60. package/gui/dist/assets/index-Co12XTT-.js +0 -76
package/src/config.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { execFileSync } from "node:child_process";
2
2
  import { createHash, randomUUID } from "node:crypto";
3
- import { chmodSync, copyFileSync, existsSync, linkSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, truncateSync, unlinkSync, writeFileSync } from "node:fs";
3
+ import { chmodSync, constants as fsConstants, copyFileSync, existsSync, linkSync, lstatSync, mkdirSync, readFileSync, realpathSync, renameSync, truncateSync, unlinkSync, writeFileSync } from "node:fs";
4
4
  import { homedir } from "node:os";
5
5
  import { dirname, join, resolve } from "node:path";
6
6
  import { Database } from "bun:sqlite";
@@ -373,7 +373,21 @@ export class OpenAiTierBackupRollbackError extends Error {
373
373
  }
374
374
 
375
375
  export class OpenAiTierBackupCollisionError extends Error {
376
- constructor() { super("Existing OpenAI tier backup differs from the current config"); this.name = "OpenAiTierBackupCollisionError"; }
376
+ readonly configPath?: string;
377
+ constructor(configPath?: string) {
378
+ super("Existing OpenAI tier backup differs from the current config");
379
+ this.name = "OpenAiTierBackupCollisionError";
380
+ this.configPath = configPath;
381
+ }
382
+ }
383
+
384
+ export class OpenAiTierRollbackPreserveError extends Error {
385
+ readonly code?: "missing" | "not-rollback" | "mismatch" | "exhausted";
386
+ constructor(message: string, options?: ErrorOptions & { code?: OpenAiTierRollbackPreserveError["code"] }) {
387
+ super(message, options);
388
+ this.name = "OpenAiTierRollbackPreserveError";
389
+ this.code = options?.code;
390
+ }
377
391
  }
378
392
 
379
393
  export class OpenAiTierBackupSecretResidualError extends Error {
@@ -461,7 +475,7 @@ export function backupConfigBeforeOpenAiTierMigration(
461
475
  // point would be surprising and potentially destructive.
462
476
  const backupBytes = io.read(backup);
463
477
  if (classifyOpenAiTierBackup(backupBytes) === "rollback") {
464
- throw new OpenAiTierBackupCollisionError();
478
+ throw new OpenAiTierBackupCollisionError(source);
465
479
  }
466
480
  console.warn("[openai-provider-migration] Replacing stale pre-migration backup (post-migration config was rewritten since last migration).");
467
481
  io.unlink(backup);
@@ -516,7 +530,7 @@ export function backupConfigBeforeOpenAiTierMigration(
516
530
  } catch (cause) {
517
531
  if (!isAlreadyExistsError(cause)) throw cause;
518
532
  const winner = io.read(backup);
519
- if (!sameBytes(original, winner)) throw new OpenAiTierBackupCollisionError();
533
+ if (!sameBytes(original, winner)) throw new OpenAiTierBackupCollisionError(source);
520
534
  scrubUnpublishedTemp();
521
535
  return "reused";
522
536
  }
@@ -552,6 +566,67 @@ export function backupConfigBeforeOpenAiTierMigration(
552
566
  }
553
567
  }
554
568
 
569
+ export interface OpenAiTierRollbackPreserveIO {
570
+ exists(path: string): boolean;
571
+ read(path: string): Uint8Array;
572
+ copyExclusive(source: string, destination: string): void;
573
+ unlink(path: string): void;
574
+ }
575
+
576
+ const DEFAULT_ROLLBACK_PRESERVE_IO: OpenAiTierRollbackPreserveIO = {
577
+ exists: existsSync,
578
+ read: target => readFileSync(target),
579
+ copyExclusive: (source, destination) => {
580
+ copyFileSync(source, destination, fsConstants.COPYFILE_EXCL);
581
+ },
582
+ unlink: unlinkSync,
583
+ };
584
+
585
+ const OPENAI_TIER_ROLLBACK_PRESERVE_ATTEMPTS = 16;
586
+
587
+ /**
588
+ * Copy a rollback-classified `.pre-openai-tiers-v2.bak` to a unique
589
+ * `.pre-openai-tiers-v1-rollback.<timestamp>[suffix].bak` path, then unlink the
590
+ * blocking v2 name. The original bytes are copied with no-replace publication;
591
+ * the v2 path is removed only after the copy is verified. Shared by startup
592
+ * migration recovery and `ocx init` cleanup so the two paths cannot drift.
593
+ */
594
+ export function preserveOpenAiTierRollbackSnapshot(
595
+ configPath = getConfigPath(),
596
+ io: OpenAiTierRollbackPreserveIO = DEFAULT_ROLLBACK_PRESERVE_IO,
597
+ ): string {
598
+ const backup = `${configPath}.pre-openai-tiers-v2.bak`;
599
+ if (!io.exists(backup)) {
600
+ throw new OpenAiTierRollbackPreserveError("OpenAI tier rollback backup is missing", { code: "missing" });
601
+ }
602
+ const original = io.read(backup);
603
+ if (classifyOpenAiTierBackup(original) !== "rollback") {
604
+ throw new OpenAiTierRollbackPreserveError("OpenAI tier backup is not a rollback snapshot", { code: "not-rollback" });
605
+ }
606
+ for (let attempt = 0; attempt < OPENAI_TIER_ROLLBACK_PRESERVE_ATTEMPTS; attempt++) {
607
+ const preserved = `${configPath}.pre-openai-tiers-v1-rollback.${Date.now()}${attempt ? `-${attempt}` : ""}.bak`;
608
+ try {
609
+ io.copyExclusive(backup, preserved);
610
+ } catch (error) {
611
+ if (isAlreadyExistsError(error)) continue;
612
+ throw error;
613
+ }
614
+ let copied: Uint8Array;
615
+ try {
616
+ copied = io.read(preserved);
617
+ } catch (error) {
618
+ throw new OpenAiTierRollbackPreserveError("Failed to read preserved rollback snapshot", { cause: error, code: "mismatch" });
619
+ }
620
+ if (!sameBytes(original, copied)) {
621
+ try { io.unlink(preserved); } catch { /* keep the original backup; incomplete copy is best-effort */ }
622
+ throw new OpenAiTierRollbackPreserveError("Preserved rollback snapshot does not match source bytes", { code: "mismatch" });
623
+ }
624
+ io.unlink(backup);
625
+ return preserved;
626
+ }
627
+ throw new OpenAiTierRollbackPreserveError("Unable to find a unique rollback snapshot path", { code: "exhausted" });
628
+ }
629
+
555
630
  /**
556
631
  * Expand a leading `~` to the home directory in user-supplied paths
557
632
  * (OPENCODEX_HOME/CODEX_HOME set from GUIs/service files where no shell expanded it).
@@ -10,7 +10,7 @@
10
10
  },
11
11
  {
12
12
  "path": "package.json",
13
- "sha256": "e26551c48502bd6a0c8d98eaf138efef1fa4c8741b0cea797ecc22cb05e74643"
13
+ "sha256": "e9ef4aa5a62aa64f795882518ae1821b3b49b5ce002310f3b1b5e5b512abdc05"
14
14
  },
15
15
  {
16
16
  "path": "scripts/model-metadata.source.json",
@@ -50,7 +50,7 @@
50
50
  },
51
51
  {
52
52
  "path": "src/adapters/command-code.ts",
53
- "sha256": "15fbd5b5caf01708823e75855e0159965b10b7604ee61c4e5dc9bd94bc143513"
53
+ "sha256": "e92d27e7988deaad93169778a57ca0afbf2f94b1ea14ba382618ea7617f14e3f"
54
54
  },
55
55
  {
56
56
  "path": "src/adapters/cursor.ts",
@@ -158,7 +158,7 @@
158
158
  },
159
159
  {
160
160
  "path": "src/adapters/cursor/request-builder.ts",
161
- "sha256": "d2a9a7fe975c4c858df2bcb5b2b2c5ba43a931b1a959a18dcc504613fabc1eb1"
161
+ "sha256": "b2c76bb40171e70827c0119c28f246f41332dbc6965035abe37054220795ea30"
162
162
  },
163
163
  {
164
164
  "path": "src/adapters/cursor/thread-continuity.ts",
@@ -166,7 +166,7 @@
166
166
  },
167
167
  {
168
168
  "path": "src/adapters/cursor/tool-definitions.ts",
169
- "sha256": "66f6c5c6b6f25c0d58cd63f6a23b8e3bf4192ac8f3608b1cfe37c9bec7d5901c"
169
+ "sha256": "be643963a3f36fe2c68bafb3f3a82ba5e9b59114d689f79cf83383c5852ff34f"
170
170
  },
171
171
  {
172
172
  "path": "src/adapters/cursor/transport-retry.ts",
@@ -262,19 +262,27 @@
262
262
  },
263
263
  {
264
264
  "path": "src/adapters/kiro.ts",
265
- "sha256": "a134e30227b79c9ee6c64124f40f86150b06b5f1175dde565f31f14679a499e8"
265
+ "sha256": "c396bcf9810a1381f71957f95ed8399a13e240f5dc6be878c8836dfa7ca66f52"
266
266
  },
267
267
  {
268
268
  "path": "src/adapters/mimo-free.ts",
269
269
  "sha256": "d267d57747f6208850c64b695ee0028748ad1e352a1fd488799e6b4abdb736ef"
270
270
  },
271
+ {
272
+ "path": "src/adapters/openai-chat-url.ts",
273
+ "sha256": "3309bcebcf21f35e5a395187a06db326173cd0a7a652a5ecb8abc20713eb8f96"
274
+ },
271
275
  {
272
276
  "path": "src/adapters/openai-chat.ts",
273
- "sha256": "86f37048af20ddbdd635a3e8f60369441c8d9481745fcf071ccbbe4daf7bc54b"
277
+ "sha256": "1fcd9a2da1e675026fa2ac03b396cefa7cd62e3c1baf27844bbe7fd589c70275"
278
+ },
279
+ {
280
+ "path": "src/adapters/openai-responses-url.ts",
281
+ "sha256": "b3acd48b0b8fcda9f2ebedb51ebfd619e1c1d1adaeca2f6965db853e6ffdc6e4"
274
282
  },
275
283
  {
276
284
  "path": "src/adapters/openai-responses.ts",
277
- "sha256": "67c8971279554b0e63c2bf85981189f92f27fe3f73a618a8198f7e4980fda14b"
285
+ "sha256": "9c8d4483c0dacf3bf0562f08fe61b43d3c3107f1a978d66fc916c3da5dfe1d17"
278
286
  },
279
287
  {
280
288
  "path": "src/adapters/run-turn-queue.ts",
@@ -282,7 +290,7 @@
282
290
  },
283
291
  {
284
292
  "path": "src/adapters/tool-catalog-nudge.ts",
285
- "sha256": "b20b726a97b85e4199ad2bcf2dfebf4040b392224e9f3b9671b00abb2c54ca81"
293
+ "sha256": "bf2bc3f1860ef7264df4a2f438df55cc46326c31e1a16e37f1d92b5446b5937b"
286
294
  },
287
295
  {
288
296
  "path": "src/adapters/upstream-http-error.ts",
@@ -290,7 +298,7 @@
290
298
  },
291
299
  {
292
300
  "path": "src/bridge.ts",
293
- "sha256": "20c2c4b1f40828b01a223e64c415dd34c98acb0fcd78ece6dab7bfee333a5b22"
301
+ "sha256": "137c6d4b5cc3e7c932fed242b5200469171ae786b4835bec7f667f15a1d79a75"
294
302
  },
295
303
  {
296
304
  "path": "src/chat/inbound.ts",
@@ -458,7 +466,7 @@
458
466
  },
459
467
  {
460
468
  "path": "src/cli/init.ts",
461
- "sha256": "211045465b1ecf46b0653234b8339425d42ee2fbcbdf216525ec6ed57ab20b3e"
469
+ "sha256": "753945880735c59dd35f3e2143a9b032945769f3ef9d8f5859c64b4493db39d0"
462
470
  },
463
471
  {
464
472
  "path": "src/cli/integrations.ts",
@@ -602,7 +610,7 @@
602
610
  },
603
611
  {
604
612
  "path": "src/codex/auth-api.ts",
605
- "sha256": "97574253fcd338991070c295871373254ebf6d5924a41c7aca96cecfc865b3ea"
613
+ "sha256": "074bef369e3d1e300c051076088e01408183d5e95db1b405a0c0f5301e3a37d7"
606
614
  },
607
615
  {
608
616
  "path": "src/codex/auth-collision.ts",
@@ -630,7 +638,7 @@
630
638
  },
631
639
  {
632
640
  "path": "src/codex/catalog.ts",
633
- "sha256": "b3a69c6d7093c4acd570f02e2704d8e3c804c14114e461444d208e9d69db1670"
641
+ "sha256": "ae99f51a899f5fdd753b1bd605b47d8f658885648cf26e5d1d001b5f75bb8134"
634
642
  },
635
643
  {
636
644
  "path": "src/codex/catalog/account-models.ts",
@@ -646,7 +654,7 @@
646
654
  },
647
655
  {
648
656
  "path": "src/codex/catalog/effort.ts",
649
- "sha256": "f76a68fa34639b16c044990af869b4be5e6dd326741b7c0e3f0f9655f22f4da3"
657
+ "sha256": "c859382789a4edf333b0e269dac54ff3a29cb205de9d07e36979a20c93fbef02"
650
658
  },
651
659
  {
652
660
  "path": "src/codex/catalog/filesystem-evidence.ts",
@@ -658,23 +666,23 @@
658
666
  },
659
667
  {
660
668
  "path": "src/codex/catalog/metadata.ts",
661
- "sha256": "49066e273177f772fa0adc6ee9ecb8258e3b9591d244d01fc3f6fdf0d2e695a6"
669
+ "sha256": "da2aff0057e1b98d62e481043b2f16fb9679b4df4226e9754963b7262fde2691"
662
670
  },
663
671
  {
664
672
  "path": "src/codex/catalog/native-models.ts",
665
- "sha256": "86d7789553db1b2d70f7183c39fab59921dd704403370a0a8a7909adeff78e02"
673
+ "sha256": "3d8a70d56fee1cf503da01c62608b338c3ec293114d1825c0bd1f96f817cda99"
666
674
  },
667
675
  {
668
676
  "path": "src/codex/catalog/parsing.ts",
669
- "sha256": "630f020fda702d07a90f1ff147a03ca284d69e32482d4e4c3020c25cd988e4ce"
677
+ "sha256": "2c3e16a4615e98d0bea0acee6994661eddeb7df80488a44d4bec253bb7ca1e79"
670
678
  },
671
679
  {
672
680
  "path": "src/codex/catalog/provider-fetch.ts",
673
- "sha256": "9f2bb70bcc8efe942b13c7b94cb06387948a2db8baba9042114787f3a5de8931"
681
+ "sha256": "61c35c9a09ada9c79f2b2979612e6ef618d735afa0b33d5f5915b5ab2e39ccde"
674
682
  },
675
683
  {
676
684
  "path": "src/codex/catalog/sync.ts",
677
- "sha256": "06b4ffdf20f60e81ba881e2390e099910aaa14da8b95ce4568471e5757af7861"
685
+ "sha256": "6f2846d1b03ffb21b73381ba833703f14b303532c0ef028945cd463ecc639beb"
678
686
  },
679
687
  {
680
688
  "path": "src/codex/codex-write-lock.ts",
@@ -706,7 +714,7 @@
706
714
  },
707
715
  {
708
716
  "path": "src/codex/features.ts",
709
- "sha256": "5a3aade98f3aaeb40e8e86c46c1b95f194f67ad27aa12152a0ce1ebf29cae0d2"
717
+ "sha256": "f6e64aa07c4ac8330df679a2b613fac84029d2fe1b8f0d5e8ace27ea664dda16"
710
718
  },
711
719
  {
712
720
  "path": "src/codex/generation.ts",
@@ -782,7 +790,7 @@
782
790
  },
783
791
  {
784
792
  "path": "src/codex/model-cache.ts",
785
- "sha256": "26c3b39ad812d8d102bd418486e9902b56e6280369a03a40cf34b0f4b6b5bd27"
793
+ "sha256": "f49cb78b3af7487d1da6f9bbb578615a75644f1a176e5ca89096186219456e94"
786
794
  },
787
795
  {
788
796
  "path": "src/codex/native-main-admission.ts",
@@ -794,7 +802,7 @@
794
802
  },
795
803
  {
796
804
  "path": "src/codex/native-main-claim.ts",
797
- "sha256": "565253a6bcf94e2444f75bf4bda9bdd713af17ad7330c4677571792cbcd75590"
805
+ "sha256": "64f5c342243e8420859ba013d987f6d1514b79f57dde662ae721ff9a8da2cf38"
798
806
  },
799
807
  {
800
808
  "path": "src/codex/native-main-lock-file.ts",
@@ -958,7 +966,7 @@
958
966
  },
959
967
  {
960
968
  "path": "src/config.ts",
961
- "sha256": "dbbabcdc1f62870ed69ecc6da675b7f82705d3f97179ad4841ad4ca368cd5932"
969
+ "sha256": "d98507303396605a2f698448295572038d6f30f3593af58910d04ecec918e9b8"
962
970
  },
963
971
  {
964
972
  "path": "src/generated/model-metadata.ts",
@@ -1314,7 +1322,7 @@
1314
1322
  },
1315
1323
  {
1316
1324
  "path": "src/lab/ledger/store.ts",
1317
- "sha256": "a81290c3d76479d303f66dc75d45f3bbd7b68d3a3f5dc04b5ab20f96a63bf2fb"
1325
+ "sha256": "75d8b2581e5766aa5d2b66432f396456a6b12e2a4a2286745b2ba32bc67bf3a7"
1318
1326
  },
1319
1327
  {
1320
1328
  "path": "src/lab/live/credential-lease.ts",
@@ -1442,7 +1450,7 @@
1442
1450
  },
1443
1451
  {
1444
1452
  "path": "src/lab/subject/installation-salt.ts",
1445
- "sha256": "6decbe8942ba547b7e59d4e4eeb6216d9b733bb5e2ddc3c601777dc9f58fa2ac"
1453
+ "sha256": "292ae399517d544d12d1d009510baa43fb150b24e4dcccadc6b5d4db151c2911"
1446
1454
  },
1447
1455
  {
1448
1456
  "path": "src/lab/subject/protocol-subject.ts",
@@ -1466,7 +1474,7 @@
1466
1474
  },
1467
1475
  {
1468
1476
  "path": "src/lib/app-owned-memory-stores.ts",
1469
- "sha256": "d4852d93145f8a765bf0374bd37e734970e2eb50bb559ea8a42f3921aa05e8c9"
1477
+ "sha256": "947c1cd5bdff6e15de778a76eb4d2d4cf103bf482354d2736003807b2e8d409c"
1470
1478
  },
1471
1479
  {
1472
1480
  "path": "src/lib/app-owned-memory.ts",
@@ -1644,6 +1652,10 @@
1644
1652
  "path": "src/lib/token-estimate.ts",
1645
1653
  "sha256": "2c3cc4b8193166ca100197ca22202b06ac98c02547ffe32f3e0f8720190b9897"
1646
1654
  },
1655
+ {
1656
+ "path": "src/lib/tool-argument-integers.ts",
1657
+ "sha256": "f0a2d8dea66735881d7aebf98ebe3b2657fb6422f540289e0aba1721d17ec990"
1658
+ },
1647
1659
  {
1648
1660
  "path": "src/lib/translator-budget.ts",
1649
1661
  "sha256": "872d5d35eb0d2ee099fc4ab4bf3b9331c6207d4282f61f2c1b11a5a36c00d981"
@@ -1774,7 +1786,7 @@
1774
1786
  },
1775
1787
  {
1776
1788
  "path": "src/oauth/nous.ts",
1777
- "sha256": "76013229a77a53b3eab34d14f73e84ecef693f4e7939e37414570cb5ff751549"
1789
+ "sha256": "49fb089b01a8a118e575069d2308912b7fd661ef882913193b0e9f4d8df28201"
1778
1790
  },
1779
1791
  {
1780
1792
  "path": "src/oauth/pkce.ts",
@@ -1818,7 +1830,7 @@
1818
1830
  },
1819
1831
  {
1820
1832
  "path": "src/providers/base-url-choices.ts",
1821
- "sha256": "ec5f3f084616f79dde7149d1bb5dc88bb9b3c406cd08698e499863c15c375c7f"
1833
+ "sha256": "f75c050dd851d38fd90335def782699aea43f89930dfff95060fa88d9724a9a6"
1822
1834
  },
1823
1835
  {
1824
1836
  "path": "src/providers/codex-capacity.ts",
@@ -1826,7 +1838,7 @@
1826
1838
  },
1827
1839
  {
1828
1840
  "path": "src/providers/command-code-efforts.ts",
1829
- "sha256": "437845ad99e09307450889f149dd7770a69770dbcd4d024506f560e739804292"
1841
+ "sha256": "279cf80e7d2a3e2019f23bb8761f4cb7a6a58d0ce754b974e1b3d759c76bbff1"
1830
1842
  },
1831
1843
  {
1832
1844
  "path": "src/providers/context-cap.ts",
@@ -1868,13 +1880,21 @@
1868
1880
  "path": "src/providers/model-discovery.ts",
1869
1881
  "sha256": "298d6f169883bfd5de3b6059fb3ae71c07328d0cec85cf4e188b80e78a50edc6"
1870
1882
  },
1883
+ {
1884
+ "path": "src/providers/model-rename-migration.ts",
1885
+ "sha256": "cc3bd468dba3387eff13aedaa1fc48e68ea328fb5bc77c02d17bd84dce5e6393"
1886
+ },
1887
+ {
1888
+ "path": "src/providers/model-rename-startup.ts",
1889
+ "sha256": "8a143284d736759bf63c8cb296c19e61dec9596dfc781d8dd87038778153f55f"
1890
+ },
1871
1891
  {
1872
1892
  "path": "src/providers/openai-sidecar.ts",
1873
1893
  "sha256": "d07ec55e8600563fa9cbdb9e535cfecb8163b8235aa44547c9359f6ca8ce62d1"
1874
1894
  },
1875
1895
  {
1876
1896
  "path": "src/providers/openai-tier-startup.ts",
1877
- "sha256": "5dc89dd548d71a5f5e25b85a5f924125f4faeb74c23a327f74294eb40ba414d0"
1897
+ "sha256": "41256c1ef4b2271168a52dcfb3ab986077cfa8edc0386230a01f5b196155ca42"
1878
1898
  },
1879
1899
  {
1880
1900
  "path": "src/providers/openai-tiers.ts",
@@ -1898,11 +1918,11 @@
1898
1918
  },
1899
1919
  {
1900
1920
  "path": "src/providers/quota.ts",
1901
- "sha256": "d2d0f30c3e8dad900c8dce0ba0278a975f809b5e39830def8d59fe8663aefa99"
1921
+ "sha256": "fa2d207d569be34fd50fd72b90389e3e4147c5101cce4318629f3f21172a5e9a"
1902
1922
  },
1903
1923
  {
1904
1924
  "path": "src/providers/registry.ts",
1905
- "sha256": "e840dcdf478cfcdee036d8de79a849a4ed303f7f25a01a4caff616d57b0d3855"
1925
+ "sha256": "cfa71c40b3f93b2e21e62838ddbfb42ff93577b077f6aadbe34158089aedb307"
1906
1926
  },
1907
1927
  {
1908
1928
  "path": "src/providers/slug-codec.ts",
@@ -1946,11 +1966,11 @@
1946
1966
  },
1947
1967
  {
1948
1968
  "path": "src/responses/spill-store.ts",
1949
- "sha256": "f16559b63a214861cbbc47908653b831ae7ade2aa88f1cfd3c0907373d668f99"
1969
+ "sha256": "c0cd3343d0803eb6d14203f19d6ee38f33110042d8aa896cc9f60bd422ca8f21"
1950
1970
  },
1951
1971
  {
1952
1972
  "path": "src/responses/state.ts",
1953
- "sha256": "7d5586e7b48ced98e9ca38ee077fc828a53ab2425651c258688b43fb608542e7"
1973
+ "sha256": "59952393060143aae734770fbf78761a8cc69e5b6335c6452bdf5ac7da686bb4"
1954
1974
  },
1955
1975
  {
1956
1976
  "path": "src/responses/tool-groups.ts",
@@ -1958,7 +1978,7 @@
1958
1978
  },
1959
1979
  {
1960
1980
  "path": "src/router.ts",
1961
- "sha256": "a431e4b5b86e615cdcb2ccb635b3c285bc8579dc93ec2d41f53af1ebb97cdc5a"
1981
+ "sha256": "8d555a3112f6f5aee67f4768880638f729baa145885bce9bd4e4cd5fcce34f7b"
1962
1982
  },
1963
1983
  {
1964
1984
  "path": "src/routing/analytics.ts",
@@ -2094,7 +2114,7 @@
2094
2114
  },
2095
2115
  {
2096
2116
  "path": "src/server/index.ts",
2097
- "sha256": "5bd284761bb05a0069f10c6cd6a686b2a600665de5d77e39579936b77747ebca"
2117
+ "sha256": "cff5571eb50f6ec315fa2f3ddd835d3bdd25b59c94a5b991771f066ad3e3ffc2"
2098
2118
  },
2099
2119
  {
2100
2120
  "path": "src/server/lifecycle.ts",
@@ -2130,7 +2150,7 @@
2130
2150
  },
2131
2151
  {
2132
2152
  "path": "src/server/management/api-key-usage.ts",
2133
- "sha256": "37ef0b22cb1b7b2a03177c39cf609ebe40183aeadeab11462a17e67cc2e6848f"
2153
+ "sha256": "86a9fbebb6986d115b46e32da123b706d9ee773881bfa5e13b9d87554d89001f"
2134
2154
  },
2135
2155
  {
2136
2156
  "path": "src/server/management/body.ts",
@@ -2142,7 +2162,7 @@
2142
2162
  },
2143
2163
  {
2144
2164
  "path": "src/server/management/config-routes.ts",
2145
- "sha256": "999e5668ca4cfe4f0bade38b11546fc40382c3396d5c50e46cd019f0e0fd50f8"
2165
+ "sha256": "621ca958cebfdf9e4486af305f31b950768b045a666b5dbf4da5ea4c7153a805"
2146
2166
  },
2147
2167
  {
2148
2168
  "path": "src/server/management/context.ts",
@@ -2162,7 +2182,7 @@
2162
2182
  },
2163
2183
  {
2164
2184
  "path": "src/server/management/logs-usage-routes.ts",
2165
- "sha256": "bcd6c00783c78a3dd1a5b71a482f15595fefcf07610506729e309bd312b3e2f2"
2185
+ "sha256": "645c8902e0d3b589a5b20a7d607fb9b40197f34a4c73945a4bf9fd91336bf15e"
2166
2186
  },
2167
2187
  {
2168
2188
  "path": "src/server/management/model-routes.ts",
@@ -2182,7 +2202,7 @@
2182
2202
  },
2183
2203
  {
2184
2204
  "path": "src/server/management/provider-routes.ts",
2185
- "sha256": "d5a5a4980f1a5cf56a994a8d2b454c86c376ec9161b3e67903b1fc768bf59cf2"
2205
+ "sha256": "af98e4f45ae93adcc5e66e2b51f0dc08c0a3406924b5a63b97698dcdc1eeeb1d"
2186
2206
  },
2187
2207
  {
2188
2208
  "path": "src/server/management/request-history-routes.ts",
@@ -2218,7 +2238,7 @@
2218
2238
  },
2219
2239
  {
2220
2240
  "path": "src/server/management/usage-summary-cache.ts",
2221
- "sha256": "fb1b889f645afb2efb02f49d78f3390c504d073867af627ace9d29f97318fc9f"
2241
+ "sha256": "a8a386202dac11802e51c3bef85ce868363f80ed05aef9db3775109e40a2aba2"
2222
2242
  },
2223
2243
  {
2224
2244
  "path": "src/server/management/vision-sidecar-options.ts",
@@ -2306,7 +2326,7 @@
2306
2326
  },
2307
2327
  {
2308
2328
  "path": "src/server/responses/collaboration.ts",
2309
- "sha256": "e3bcb01890c2d5e3b2f5032de223a537455c21bf06a134e4f5c828c6b56dc243"
2329
+ "sha256": "bfeef4d9bf5538d850446d5805769779518b62f8ef33693ecfd1c48f8545093e"
2310
2330
  },
2311
2331
  {
2312
2332
  "path": "src/server/responses/compact.ts",
@@ -2314,7 +2334,7 @@
2314
2334
  },
2315
2335
  {
2316
2336
  "path": "src/server/responses/core.ts",
2317
- "sha256": "d3152413a69957fd952e0f6dd8a5e0837aea6d1f0a71f4693580e4176221f317"
2337
+ "sha256": "c67fdae5470a8d0c234e24d7d062bf351ec35c911550363c8d73199f4059fc95"
2318
2338
  },
2319
2339
  {
2320
2340
  "path": "src/server/responses/encrypted-payload.ts",
@@ -2322,7 +2342,7 @@
2322
2342
  },
2323
2343
  {
2324
2344
  "path": "src/server/responses/fetch-helpers.ts",
2325
- "sha256": "5763bccb7c460cc4031f45c728bce9db14f8af010face733108216232ef07d13"
2345
+ "sha256": "c0dd5255a485b23fcef54378cd1ea2eac40f7824952050f8e9db9c3d02f0e2d2"
2326
2346
  },
2327
2347
  {
2328
2348
  "path": "src/server/responses/passthrough-error.ts",
@@ -2340,6 +2360,10 @@
2340
2360
  "path": "src/server/responses/upstream-error.ts",
2341
2361
  "sha256": "e74ff94134f82d594891242b49d03619771f938bde3dc4b6c96a527510da2546"
2342
2362
  },
2363
+ {
2364
+ "path": "src/server/responses/ws-upstream.ts",
2365
+ "sha256": "f697ac29a3b1965c4d77531abd69ed382d938ed503c951834205cffe6d8e9757"
2366
+ },
2343
2367
  {
2344
2368
  "path": "src/server/search.ts",
2345
2369
  "sha256": "62a6c940ca5d967ea2a766e6d864c6df77e74130c99d0cacf4f4380cb01fbb5a"
@@ -2358,7 +2382,7 @@
2358
2382
  },
2359
2383
  {
2360
2384
  "path": "src/server/startup-health-cache.ts",
2361
- "sha256": "2ef39b33ec79cd6f8d1bf9040ce1510c32142a643d7a9e2ba56690fe23995da5"
2385
+ "sha256": "0193264ad0f951085d774e052342385aa5043fa2b0dbd5fba224a4b790604f1f"
2362
2386
  },
2363
2387
  {
2364
2388
  "path": "src/server/system-env.ts",
@@ -2514,7 +2538,7 @@
2514
2538
  },
2515
2539
  {
2516
2540
  "path": "src/usage/log.ts",
2517
- "sha256": "b96cacb9e6eaac59eeaee8f5124a985cc0d14169364401eec80a10a8d3a24a76"
2541
+ "sha256": "db69314bab2520a05889a3cef8c1de042ecdcdb67792f687399eb23c140e2c75"
2518
2542
  },
2519
2543
  {
2520
2544
  "path": "src/usage/summary.ts",
@@ -2546,12 +2570,16 @@
2546
2570
  },
2547
2571
  {
2548
2572
  "path": "src/vision/index.ts",
2549
- "sha256": "187d229d74b6fda82e3ad4117c2bb5f17ccfadb213ef728a48c39ef32f17f510"
2573
+ "sha256": "b3c27892a17ea2176c2b6361830800772a6efea5681fff570b3ca5da77626bbc"
2550
2574
  },
2551
2575
  {
2552
2576
  "path": "src/vision/reasoning.ts",
2553
2577
  "sha256": "7b5ba571d9e727304f9cc053baaf82a5023fd2dad92f7fbf01af7edb8cfca21a"
2554
2578
  },
2579
+ {
2580
+ "path": "src/vision/timeout-bounds.ts",
2581
+ "sha256": "65a3124c6817cda51eb529520652576ffb1e92db433112162c0065104954eaba"
2582
+ },
2555
2583
  {
2556
2584
  "path": "src/web-search/anthropic-executor.ts",
2557
2585
  "sha256": "dc7be63143d4ba70cb5e8127fe2d5231bbabb724ee4715a091bfcc336d48eb32"
@@ -25,7 +25,6 @@ export interface LedgerStore {
25
25
  replay(): ReplayResult;
26
26
  }
27
27
 
28
- const eventIdIndexByLedger = new Map<string, Set<string>>();
29
28
  const LEDGER_LOCK_STALE_MS = 60_000;
30
29
  const LEDGER_LOCK_WAIT_MS = 5_000;
31
30
 
@@ -157,21 +156,6 @@ function withLedgerLock<T>(ledgerPath: string, fn: () => T): T {
157
156
  }
158
157
  }
159
158
 
160
- /** Load or build the in-memory event-id index for a ledger path. */
161
- function loadEventIdIndex(ledgerPath: string): Set<string> {
162
- let index = eventIdIndexByLedger.get(ledgerPath);
163
- if (!index) {
164
- index = new Set();
165
- if (existsSync(ledgerPath)) {
166
- for (const event of replayLabLedger(ledgerPath).events) {
167
- index.add(event.eventId);
168
- }
169
- }
170
- eventIdIndexByLedger.set(ledgerPath, index);
171
- }
172
- return index;
173
- }
174
-
175
159
  /** Durable append of one validated event as a single JSONL line + fsync. */
176
160
  export function appendLabEvent(ledgerPath: string, event: LabEvent): void {
177
161
  const validated = validateLabEvent(event);
@@ -192,7 +176,6 @@ export function appendLabEvent(ledgerPath: string, event: LabEvent): void {
192
176
  } finally {
193
177
  closeSync(fd);
194
178
  }
195
- loadEventIdIndex(ledgerPath).add(validated.eventId);
196
179
  }
197
180
 
198
181
  /**
@@ -209,7 +192,6 @@ export function appendLabEventIfAbsent(ledgerPath: string, event: LabEvent): boo
209
192
  fresh.add(row.eventId);
210
193
  }
211
194
  }
212
- eventIdIndexByLedger.set(ledgerPath, fresh);
213
195
  if (fresh.has(validated.eventId)) return false;
214
196
  appendLabEvent(ledgerPath, validated);
215
197
  return true;
@@ -4,9 +4,20 @@ import { dirname } from "node:path";
4
4
  import { labInstallationSaltPath, labRoot } from "../paths";
5
5
 
6
6
  const SALT_BYTES = 32;
7
- const installationSaltCache = new Map<string, Uint8Array>();
7
+ export const INSTALLATION_SALT_CACHE_MAX_ENTRIES = 16;
8
+ export const installationSaltCache = new Map<string, Uint8Array>();
8
9
  const UNSUPPORTED_DIRECTORY_FSYNC_CODES = new Set(["EINVAL", "ENOTSUP", "EOPNOTSUPP", "ENOSYS"]);
9
10
 
11
+ export function rememberInstallationSalt(path: string, salt: Uint8Array): void {
12
+ installationSaltCache.delete(path);
13
+ installationSaltCache.set(path, salt);
14
+ while (installationSaltCache.size > INSTALLATION_SALT_CACHE_MAX_ENTRIES) {
15
+ const oldest = installationSaltCache.keys().next().value;
16
+ if (oldest === undefined) break;
17
+ installationSaltCache.delete(oldest);
18
+ }
19
+ }
20
+
10
21
  function readSaltFile(path: string): Uint8Array {
11
22
  const bytes = readFileSync(path);
12
23
  if (bytes.byteLength !== SALT_BYTES) {
@@ -17,7 +28,7 @@ function readSaltFile(path: string): Uint8Array {
17
28
 
18
29
  function cacheSalt(path: string, salt: Uint8Array): Uint8Array {
19
30
  const cached = new Uint8Array(salt);
20
- installationSaltCache.set(path, cached);
31
+ rememberInstallationSalt(path, cached);
21
32
  return new Uint8Array(cached);
22
33
  }
23
34
 
@@ -34,6 +34,10 @@ import {
34
34
  evictOldestUsageSummaryForBudget,
35
35
  usageSummaryRetainedStoreSnapshot,
36
36
  } from "../server/management/usage-summary-cache";
37
+ import {
38
+ discardRetainedUsageSnapshot,
39
+ retainedUsageSnapshotStats,
40
+ } from "../usage/log";
37
41
  import {
38
42
  cursorBlobRetainedStoreSnapshot,
39
43
  evictOldestCursorBlobForBudget,
@@ -57,6 +61,18 @@ function ringSnapshot(metrics: { entries: number; bytes: number; oldestAt: numbe
57
61
  };
58
62
  }
59
63
 
64
+ /** The retained usage tail is a single all-or-nothing entry: evicting it drops the whole tail. */
65
+ function usageSnapshotRetainedStoreSnapshot(): RetainedStoreSnapshot {
66
+ const stats = retainedUsageSnapshotStats();
67
+ return {
68
+ count: stats.count,
69
+ bytes: stats.bytes,
70
+ evictableBytes: stats.bytes,
71
+ pinnedBytes: 0,
72
+ oldestAt: stats.oldestAt,
73
+ };
74
+ }
75
+
60
76
  function providerDebugSnapshot(): RetainedStoreSnapshot {
61
77
  return ringSnapshot(debugBufferMetrics());
62
78
  }
@@ -134,6 +150,12 @@ export const APP_OWNED_RETAINED_STORE_REGISTRATIONS = [
134
150
  snapshot: usageSummaryRetainedStoreSnapshot,
135
151
  evictOldest: evictOldestUsageSummaryForBudget,
136
152
  },
153
+ {
154
+ id: "usage_snapshot",
155
+ category: "caches",
156
+ snapshot: usageSnapshotRetainedStoreSnapshot,
157
+ evictOldest: discardRetainedUsageSnapshot,
158
+ },
137
159
  {
138
160
  id: "cursor_blobs",
139
161
  category: "blobs",