@bitkyc08/opencodex 2.20.0 → 2.22.0

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 (64) hide show
  1. package/AGENTS_INSTALL.md +32 -0
  2. package/README.md +1 -1
  3. package/gui/dist/assets/{index-DSK3S5HY.js → index-ClEcVlFO.js} +43 -17
  4. package/gui/dist/assets/index-DQsMZzI5.css +1 -0
  5. package/gui/dist/index.html +2 -2
  6. package/package.json +1 -1
  7. package/src/adapters/anthropic.ts +2 -28
  8. package/src/adapters/google.ts +31 -3
  9. package/src/adapters/openai-chat.ts +25 -8
  10. package/src/adapters/responses-tool-schema.ts +67 -0
  11. package/src/bridge.ts +15 -2
  12. package/src/claude/agents-inject.ts +2 -2
  13. package/src/claude/gateway-cache.ts +41 -4
  14. package/src/cli/claude.ts +1 -1
  15. package/src/cli/codex-log-guard-doctor.ts +103 -0
  16. package/src/cli/dispatch.ts +7 -1
  17. package/src/cli/help.ts +1 -1
  18. package/src/cli/models.ts +16 -6
  19. package/src/cli/observe.ts +38 -2
  20. package/src/cli/registry.ts +2 -1
  21. package/src/cli/v2.ts +34 -1
  22. package/src/codex/app-server-processes.ts +46 -26
  23. package/src/codex/catalog/effort.ts +49 -1
  24. package/src/codex/catalog/parsing.ts +64 -4
  25. package/src/codex/catalog/provider-fetch.ts +12 -0
  26. package/src/codex/catalog/sync.ts +14 -1
  27. package/src/codex/convergence.ts +2 -0
  28. package/src/codex/inject.ts +3 -3
  29. package/src/codex/log-guard/inspect.ts +506 -0
  30. package/src/codex/log-guard/lock.ts +150 -0
  31. package/src/codex/log-guard/maintenance.ts +403 -0
  32. package/src/codex/log-guard/path-safety.ts +39 -0
  33. package/src/codex/log-guard/policy.ts +44 -0
  34. package/src/codex/log-guard/processes.ts +205 -0
  35. package/src/codex/log-guard/protection.ts +489 -0
  36. package/src/codex/log-guard/sqlite-errors.ts +9 -0
  37. package/src/codex/paths.ts +5 -0
  38. package/src/codex/plugins-doctor.ts +1 -1
  39. package/src/codex/project-config-warnings.ts +2 -2
  40. package/src/generated/compatibility-version.json +93 -45
  41. package/src/images/loop.ts +15 -5
  42. package/src/providers/antigravity-models.ts +11 -1
  43. package/src/providers/model-discovery.ts +94 -6
  44. package/src/providers/quota.ts +159 -0
  45. package/src/providers/registry.ts +20 -1
  46. package/src/providers/slug-codec.ts +29 -0
  47. package/src/responses/custom-tool-compat.ts +4 -1
  48. package/src/responses/parser.ts +7 -1
  49. package/src/responses/provider-opaque-metadata.ts +73 -0
  50. package/src/responses/schema.ts +6 -0
  51. package/src/router.ts +12 -4
  52. package/src/routing/capability.ts +32 -17
  53. package/src/server/auth-cors.ts +42 -6
  54. package/src/server/index.ts +1 -0
  55. package/src/server/management/agent-settings-routes.ts +20 -2
  56. package/src/server/management/context.ts +15 -0
  57. package/src/server/management/model-routes.ts +12 -3
  58. package/src/server/management/storage-log-guard-routes.ts +186 -0
  59. package/src/server/management-api.ts +3 -1
  60. package/src/server/responses/core.ts +13 -0
  61. package/src/server/system-env.ts +1 -1
  62. package/src/types.ts +24 -2
  63. package/src/web-search/loop.ts +21 -5
  64. package/gui/dist/assets/index-DF_UFrGS.css +0 -1
@@ -10,7 +10,7 @@
10
10
  },
11
11
  {
12
12
  "path": "package.json",
13
- "sha256": "c05ac96358e4e2454545e35034a0235dd8de7f50e16f92b464f978ede80564c3"
13
+ "sha256": "23d58fd93c12138baca76f044899d82aea45768aa38f5f78c86e957e080be06b"
14
14
  },
15
15
  {
16
16
  "path": "scripts/model-metadata.source.json",
@@ -34,7 +34,7 @@
34
34
  },
35
35
  {
36
36
  "path": "src/adapters/anthropic.ts",
37
- "sha256": "7245f5ae5b5b32444fcd50144d5f752f6fde39c471b30b355d44c27531a8059a"
37
+ "sha256": "ab7791765594ed63fc57a170e2a7e760a882a17ae0d51c0f44a7fbbb789a0416"
38
38
  },
39
39
  {
40
40
  "path": "src/adapters/azure.ts",
@@ -210,7 +210,7 @@
210
210
  },
211
211
  {
212
212
  "path": "src/adapters/google.ts",
213
- "sha256": "7905d7c039bebc63a2fa968fc934570d5dedf882c474087bcf4d55e317641e63"
213
+ "sha256": "2144cb4567aefe746a3b95eb78ac280fbd6ed7bf8dc0d05a88802d526abcc4f1"
214
214
  },
215
215
  {
216
216
  "path": "src/adapters/identity.ts",
@@ -274,7 +274,7 @@
274
274
  },
275
275
  {
276
276
  "path": "src/adapters/openai-chat.ts",
277
- "sha256": "d087da38fd9706f22c1f8e1513cdebd0ecd890146d7f9c09f8abe759d6aa2548"
277
+ "sha256": "b95eb2964332647ca72f83b1684394d2013d992287a626c04134a5897ddaa251"
278
278
  },
279
279
  {
280
280
  "path": "src/adapters/openai-responses-url.ts",
@@ -288,6 +288,10 @@
288
288
  "path": "src/adapters/registry.ts",
289
289
  "sha256": "9a56ee08197bdd5b6ea12fcb847d2a89b60a600ee2536a010f4836784115d2d8"
290
290
  },
291
+ {
292
+ "path": "src/adapters/responses-tool-schema.ts",
293
+ "sha256": "affeb179617d9abfb8cd18d47b132ff02d05c4438e5395b90103c7b03c184f55"
294
+ },
291
295
  {
292
296
  "path": "src/adapters/run-turn-queue.ts",
293
297
  "sha256": "7599ccc46be13507bdec6e27095092efb0b6d84976bcffe0cca972ce08a6da62"
@@ -302,7 +306,7 @@
302
306
  },
303
307
  {
304
308
  "path": "src/bridge.ts",
305
- "sha256": "47ccd936f3abd32d98ea9f044d35acd353b16ee1c9f0f0542f4b519f63f52221"
309
+ "sha256": "3176bc017560ccec87b911a00e263aebee23dc8067b6c1d5405137e72a22e0d2"
306
310
  },
307
311
  {
308
312
  "path": "src/chat/inbound.ts",
@@ -314,7 +318,7 @@
314
318
  },
315
319
  {
316
320
  "path": "src/claude/agents-inject.ts",
317
- "sha256": "fb338b3a3290589ae91f52e6fe60bbec85e71cc4eaea8ace8588519a89c26e4d"
321
+ "sha256": "46ebe634b087860bd3c107efe17d4c54289c19845c50c729eeaf53d18b4e8247"
318
322
  },
319
323
  {
320
324
  "path": "src/claude/alias.ts",
@@ -358,7 +362,7 @@
358
362
  },
359
363
  {
360
364
  "path": "src/claude/gateway-cache.ts",
361
- "sha256": "134e7b5b18045a1909fbfcf26d952475df4057d4a6538f659dcc3d3c28be6968"
365
+ "sha256": "cb8be3d8991acecd010adb7ac4351a2aa7b75a26feaf9e0ca3749085f05897ba"
362
366
  },
363
367
  {
364
368
  "path": "src/claude/inbound-debug.ts",
@@ -426,7 +430,11 @@
426
430
  },
427
431
  {
428
432
  "path": "src/cli/claude.ts",
429
- "sha256": "5a225032c2b306dd00d5106ea215f98c3182cd61ccbf465196eb97fe8220c459"
433
+ "sha256": "7b9b5ea1fbeab889f137a3f889e89350d7205ab77102f6b46357dd825be0e08d"
434
+ },
435
+ {
436
+ "path": "src/cli/codex-log-guard-doctor.ts",
437
+ "sha256": "e6a62a5c9cbf65e900ec3523598a225f5ccd1238abb8da9cae232d60da6fdabf"
430
438
  },
431
439
  {
432
440
  "path": "src/cli/codex-shim-autorestore.ts",
@@ -450,7 +458,7 @@
450
458
  },
451
459
  {
452
460
  "path": "src/cli/dispatch.ts",
453
- "sha256": "39c48bd5eb2b3d52db34f7698f482210771eb63e5f990829aaaa2fda7fffebfc"
461
+ "sha256": "3edcfa5957813d525da64ed091f605dc70adda272cf16414d62f42a99ed5ed08"
454
462
  },
455
463
  {
456
464
  "path": "src/cli/doctor.ts",
@@ -462,7 +470,7 @@
462
470
  },
463
471
  {
464
472
  "path": "src/cli/help.ts",
465
- "sha256": "55c0ee0ad7f3261bb23dbc7e08d208e94da60343c2f7d73e626110d5bbaf1b26"
473
+ "sha256": "829453ef2aac53bc15825bc6a47320a3a0a5a9989f616fbb62e76fdfa01891ee"
466
474
  },
467
475
  {
468
476
  "path": "src/cli/index.ts",
@@ -498,11 +506,11 @@
498
506
  },
499
507
  {
500
508
  "path": "src/cli/models.ts",
501
- "sha256": "f424705f5abd97977041aeb76713db86a5869529c86d35b9a51295831c58238e"
509
+ "sha256": "a7ddece988af02fc1ebbf4f97bbed882ab70713048c65b094b62bba42b99036f"
502
510
  },
503
511
  {
504
512
  "path": "src/cli/observe.ts",
505
- "sha256": "bacc427239130ab80e94d6450b946d50011035e7d50015f323cc3cb352a0d101"
513
+ "sha256": "c403189847bbeb114e87f133e6e3612c7e3f483e8c64e579152d54f4fc83f462"
506
514
  },
507
515
  {
508
516
  "path": "src/cli/opencode.ts",
@@ -522,7 +530,7 @@
522
530
  },
523
531
  {
524
532
  "path": "src/cli/registry.ts",
525
- "sha256": "a41d54ece43183ef0f2e20cdbbec2866b470d007f4a11d5884e0afa87d52d5a8"
533
+ "sha256": "160e10cb3a5797cb7918261d804fc09d7eb264a3fbddbc9e8735eabf4bad87e7"
526
534
  },
527
535
  {
528
536
  "path": "src/cli/root.ts",
@@ -562,7 +570,7 @@
562
570
  },
563
571
  {
564
572
  "path": "src/cli/v2.ts",
565
- "sha256": "28dc0d12a8edcf49821655e6dc242bbab72afdfec3a67e84143a08fb42363d64"
573
+ "sha256": "c82727ac194d3e21494b73f3ca4b8c32c86bacea1f39f489477f9cc0ddf8491f"
566
574
  },
567
575
  {
568
576
  "path": "src/clients/config-export.ts",
@@ -614,7 +622,7 @@
614
622
  },
615
623
  {
616
624
  "path": "src/codex/app-server-processes.ts",
617
- "sha256": "465d55f46f7fe7e2387712a708f52b20471b86cb1ba7e860d37475d4af3e7a4b"
625
+ "sha256": "28c7fb91d8fd5c2332738e512b9d87c53ea09843191c145b0801d912e124fe9e"
618
626
  },
619
627
  {
620
628
  "path": "src/codex/app-server-restart-service.ts",
@@ -666,7 +674,7 @@
666
674
  },
667
675
  {
668
676
  "path": "src/codex/catalog/effort.ts",
669
- "sha256": "174d3b2d850be0ec3e95d13b53ec50a34d5791ddeee8d9d6fc2d0f30ac69f0b3"
677
+ "sha256": "ac208a47306bd0081e7be7a73ff483296d28ca0e23427218ce999dc53a6071c9"
670
678
  },
671
679
  {
672
680
  "path": "src/codex/catalog/filesystem-evidence.ts",
@@ -686,15 +694,15 @@
686
694
  },
687
695
  {
688
696
  "path": "src/codex/catalog/parsing.ts",
689
- "sha256": "36b9fa4face3877de4495809cae18f3ecd007e7b12e59a1dbfff8e222e884f85"
697
+ "sha256": "0998690562c0f00554630f2070205f6864d8f573ffcaa809d0def6c67f21be6c"
690
698
  },
691
699
  {
692
700
  "path": "src/codex/catalog/provider-fetch.ts",
693
- "sha256": "1fa6525a53b7bed96b8a142eebb78f83b58a5029641e8fd983fb258db1445451"
701
+ "sha256": "472501e50bc4c82cfc0df13fd534b9ca9b391f3207b8bee74543d6cc999c3d30"
694
702
  },
695
703
  {
696
704
  "path": "src/codex/catalog/sync.ts",
697
- "sha256": "8d0b1819dd73650ab99d1c9b07fdc0bd12c9db197e8554888afe4abfa1993ac8"
705
+ "sha256": "d586a2d468cf4120da088f0bdc3088751c0e7015a9fc5545dd5584804d1e3525"
698
706
  },
699
707
  {
700
708
  "path": "src/codex/codex-write-lock.ts",
@@ -706,7 +714,7 @@
706
714
  },
707
715
  {
708
716
  "path": "src/codex/convergence.ts",
709
- "sha256": "9d9e6bb02d7ec2f87de2729708b311f4bf1eb0047e74fd7cd1dc00f41cbf069c"
717
+ "sha256": "ffe1a891c51b33ace33d99bb11ca36015544189f8c4bb1966c2bb08469a163fb"
710
718
  },
711
719
  {
712
720
  "path": "src/codex/custom-model-catalog-migration.ts",
@@ -766,7 +774,7 @@
766
774
  },
767
775
  {
768
776
  "path": "src/codex/inject.ts",
769
- "sha256": "9d83aedcc214dba9c850fc904f38395d47df429a0587a677125a75b07d5f19ef"
777
+ "sha256": "fd020e956a6b7b50d256c9bdd7d585172cc7662993e4eb21fe2c55b0e2387e37"
770
778
  },
771
779
  {
772
780
  "path": "src/codex/injected-marker.ts",
@@ -788,6 +796,38 @@
788
796
  "path": "src/codex/journal.ts",
789
797
  "sha256": "f90fcb039ff2ca8ddbdfe8e9101b431e4c8d864cc18923bbbc98c671b1b7adb0"
790
798
  },
799
+ {
800
+ "path": "src/codex/log-guard/inspect.ts",
801
+ "sha256": "b2b4153ff668d3f3f89322e21bee5af375fa7f92d8f4039e8db88f1f040c8357"
802
+ },
803
+ {
804
+ "path": "src/codex/log-guard/lock.ts",
805
+ "sha256": "b4ce32198272163541652b9864f892eeff8f681e7807de67c321c6c8901b4384"
806
+ },
807
+ {
808
+ "path": "src/codex/log-guard/maintenance.ts",
809
+ "sha256": "f11d9c7d774719715a8b3b33e7573ab09eca33fa4f57e853479a4fb5d8617786"
810
+ },
811
+ {
812
+ "path": "src/codex/log-guard/path-safety.ts",
813
+ "sha256": "8df1c28dafbe16417dcc474fe06c63ec0d6b8367d47971569b4a80a17a614e16"
814
+ },
815
+ {
816
+ "path": "src/codex/log-guard/policy.ts",
817
+ "sha256": "ba282dba9271822d1778256f28dd4e8087f83dd282ce63dc06539e46db0da58b"
818
+ },
819
+ {
820
+ "path": "src/codex/log-guard/processes.ts",
821
+ "sha256": "a1388d9adfedc5918d0fdce83ae1f0577ede9a23f07789ba46ced5351a05edb1"
822
+ },
823
+ {
824
+ "path": "src/codex/log-guard/protection.ts",
825
+ "sha256": "92c1e86ec698bba7953f1e0d389383e76d1c7f05206d6beaa5f1eccc451e9b9b"
826
+ },
827
+ {
828
+ "path": "src/codex/log-guard/sqlite-errors.ts",
829
+ "sha256": "aa4335d71cf642e9b98b066af9204e6d66fff49a7f95b14c50b4c82abd1cce6f"
830
+ },
791
831
  {
792
832
  "path": "src/codex/main-account-cache.ts",
793
833
  "sha256": "1fe336e582bce085b1e37d8a1925b60e91ec667706f80d939974d41062673f6e"
@@ -862,7 +902,7 @@
862
902
  },
863
903
  {
864
904
  "path": "src/codex/paths.ts",
865
- "sha256": "8137c05a2ef4d15094d0dd53b8ebe2d2324dfd005f4b74ecd390a8454c67f2c2"
905
+ "sha256": "f14512fec482d38044172cee72532372bb32757f964b4c2c90f1349c4d07c32c"
866
906
  },
867
907
  {
868
908
  "path": "src/codex/plan.ts",
@@ -870,7 +910,7 @@
870
910
  },
871
911
  {
872
912
  "path": "src/codex/plugins-doctor.ts",
873
- "sha256": "8e43ea761676d4e93f53461f689995143c4c123e7c83d7948906af0a29cd0540"
913
+ "sha256": "51344b58e99a143d2c7d397481e5b2a26c86ab0a1c61db5b153068793e4d3cab"
874
914
  },
875
915
  {
876
916
  "path": "src/codex/pool-rotation.ts",
@@ -878,7 +918,7 @@
878
918
  },
879
919
  {
880
920
  "path": "src/codex/project-config-warnings.ts",
881
- "sha256": "801d2308cef14ee36ae7740a1a94d54876331b6878d5b2c23a1a1f4bdfd6d93a"
921
+ "sha256": "b7543a8d5bd7ff439398480360d9f8b5840ade77e1db19155994d298136ef868"
882
922
  },
883
923
  {
884
924
  "path": "src/codex/prompt-journal.ts",
@@ -1022,7 +1062,7 @@
1022
1062
  },
1023
1063
  {
1024
1064
  "path": "src/images/loop.ts",
1025
- "sha256": "172baea637ae1314e3e45886abc906a2308497d6eca913557255d3f14a92e8cc"
1065
+ "sha256": "83036ac88b0a13eac64a0e4b170a89616daf5a1090eff83a499b891bd323ba18"
1026
1066
  },
1027
1067
  {
1028
1068
  "path": "src/images/plan.ts",
@@ -1958,7 +1998,7 @@
1958
1998
  },
1959
1999
  {
1960
2000
  "path": "src/providers/antigravity-models.ts",
1961
- "sha256": "005e17707703842d91d9b18aa6f28375bda6b49efff07cb7642c597ee0bcdc8b"
2001
+ "sha256": "1382f985bf4fdf525fb4425d5040e7244460f441f492b22ddc493226e5b778d1"
1962
2002
  },
1963
2003
  {
1964
2004
  "path": "src/providers/api-keys.ts",
@@ -2014,7 +2054,7 @@
2014
2054
  },
2015
2055
  {
2016
2056
  "path": "src/providers/model-discovery.ts",
2017
- "sha256": "298d6f169883bfd5de3b6059fb3ae71c07328d0cec85cf4e188b80e78a50edc6"
2057
+ "sha256": "bcf2a1b01dc8cdad91bd2b2e3ee935107e203905649985ee57691d33e3fed9c9"
2018
2058
  },
2019
2059
  {
2020
2060
  "path": "src/providers/model-rename-migration.ts",
@@ -2054,11 +2094,11 @@
2054
2094
  },
2055
2095
  {
2056
2096
  "path": "src/providers/quota.ts",
2057
- "sha256": "fa2d207d569be34fd50fd72b90389e3e4147c5101cce4318629f3f21172a5e9a"
2097
+ "sha256": "828c4304b6b67d2a71d85141f8da0d2a59453f782c3de46a1905e68903750375"
2058
2098
  },
2059
2099
  {
2060
2100
  "path": "src/providers/registry.ts",
2061
- "sha256": "3b29779cc4495c35097d941a40f915cb98af1813423cab8da5039daf166e857b"
2101
+ "sha256": "363d273b5dbf67ed5b3491578f18c5d408d10b546a21a4a7cad3697606a47047"
2062
2102
  },
2063
2103
  {
2064
2104
  "path": "src/providers/request-pacing.ts",
@@ -2070,7 +2110,7 @@
2070
2110
  },
2071
2111
  {
2072
2112
  "path": "src/providers/slug-codec.ts",
2073
- "sha256": "01a82a23ee8046e280d9fdc85769233ccc7bc67d1866fe475f4f2efe33136aca"
2113
+ "sha256": "733bfa8cb48e8e9baa678f5aefbf579f7eaa5eb05b16433779bd26e39b41ffe8"
2074
2114
  },
2075
2115
  {
2076
2116
  "path": "src/providers/static-model-discovery.ts",
@@ -2090,7 +2130,7 @@
2090
2130
  },
2091
2131
  {
2092
2132
  "path": "src/responses/custom-tool-compat.ts",
2093
- "sha256": "8e082bf45123416643f7071211e36a8ad4b3e21d19a44e01c1fe5aa3dc2aa213"
2133
+ "sha256": "332474e1d891bbc8a23a0bb76d99f96ae8f369ef325e324af0040e0b17cf6616"
2094
2134
  },
2095
2135
  {
2096
2136
  "path": "src/responses/hosted-tool-policy.ts",
@@ -2098,7 +2138,11 @@
2098
2138
  },
2099
2139
  {
2100
2140
  "path": "src/responses/parser.ts",
2101
- "sha256": "255aab86fab5d6b2beedfcae1aced4cb69406b2c1d1e72bb6c0ca56337bfb0f1"
2141
+ "sha256": "bd1d2ad40ffc8b17453f657f9453d1a29c81d568a19826a0fb62e9af3175f7ae"
2142
+ },
2143
+ {
2144
+ "path": "src/responses/provider-opaque-metadata.ts",
2145
+ "sha256": "a452108841dcb07d21e43832aae70a66bbf26a8a6c9eb52c8c9ef11120dfb234"
2102
2146
  },
2103
2147
  {
2104
2148
  "path": "src/responses/reasoning-envelope.ts",
@@ -2110,7 +2154,7 @@
2110
2154
  },
2111
2155
  {
2112
2156
  "path": "src/responses/schema.ts",
2113
- "sha256": "25b063cae8ed65348ab6f5fe2df67d16b63f7432c7c6db154b2a9fbe8b467653"
2157
+ "sha256": "3cc771b346cc5577c182674b899356448a23b1dca7f681013982c71ae17791a1"
2114
2158
  },
2115
2159
  {
2116
2160
  "path": "src/responses/spill-store.ts",
@@ -2126,7 +2170,7 @@
2126
2170
  },
2127
2171
  {
2128
2172
  "path": "src/router.ts",
2129
- "sha256": "7366badf3a6ace0ae2f044bcab0872e6179bb7bc2f5c7d5a5e35d5655a26d39f"
2173
+ "sha256": "574c51a5c95350217d72b6fa82b06806251e6706265866e909fec729882f82fb"
2130
2174
  },
2131
2175
  {
2132
2176
  "path": "src/routing/analytics.ts",
@@ -2134,7 +2178,7 @@
2134
2178
  },
2135
2179
  {
2136
2180
  "path": "src/routing/capability.ts",
2137
- "sha256": "02349faa5d03510aa8b6a3e2b2eebc6f4afe15ffe424cf5a49a28b643158f4c1"
2181
+ "sha256": "00606e95e636abd8612bb6825c6cb8c2a62ca1eb396ebebba64501f34cd0e060"
2138
2182
  },
2139
2183
  {
2140
2184
  "path": "src/routing/compatibility/assemble.ts",
@@ -2230,7 +2274,7 @@
2230
2274
  },
2231
2275
  {
2232
2276
  "path": "src/server/auth-cors.ts",
2233
- "sha256": "baca73b0b188683eed9b4708d954d9089e6eaeae4ef88487c1435582988baf58"
2277
+ "sha256": "412a504bd8c3df8fcc0b33de12f321f16a103168e278357de13cd479336073e9"
2234
2278
  },
2235
2279
  {
2236
2280
  "path": "src/server/background-lifecycle.ts",
@@ -2278,7 +2322,7 @@
2278
2322
  },
2279
2323
  {
2280
2324
  "path": "src/server/index.ts",
2281
- "sha256": "e909c5777cac73894273ab6ce9a0e635dc55a74de726cc6a6f71c4409a695ba2"
2325
+ "sha256": "2745fca63c657742f90c22f2a251a3bf1702aca0c5c5b24cfab9d01dad39cd93"
2282
2326
  },
2283
2327
  {
2284
2328
  "path": "src/server/lifecycle.ts",
@@ -2298,7 +2342,7 @@
2298
2342
  },
2299
2343
  {
2300
2344
  "path": "src/server/management-api.ts",
2301
- "sha256": "0a513030e2b730393d86c87ad237f1e9f35e64586d8736c91c69fed6aaabb60d"
2345
+ "sha256": "4736d3b1030eff60d06b22e3339bb25f66062d9d3bf0c2becc701f5b10bcc032"
2302
2346
  },
2303
2347
  {
2304
2348
  "path": "src/server/management-auth.ts",
@@ -2306,7 +2350,7 @@
2306
2350
  },
2307
2351
  {
2308
2352
  "path": "src/server/management/agent-settings-routes.ts",
2309
- "sha256": "2e470534a00bfe47ca3c76688373c72650c60032d7d1ff56d3b57f3cadff3907"
2353
+ "sha256": "d22e53a8f698e29c78905944a8c696522a0fe468bda72da4fb5f6491aa0b0cc6"
2310
2354
  },
2311
2355
  {
2312
2356
  "path": "src/server/management/api-access.ts",
@@ -2330,7 +2374,7 @@
2330
2374
  },
2331
2375
  {
2332
2376
  "path": "src/server/management/context.ts",
2333
- "sha256": "3c5d032849dbbe1036ceb748c5eb2f8b4bcf63816d5d8878e953ee3202c08f91"
2377
+ "sha256": "85564a590d77fb49f7aab7a0cf4729ca6d704bcef4b3a68b5a437d87809aa212"
2334
2378
  },
2335
2379
  {
2336
2380
  "path": "src/server/management/integration-routes.ts",
@@ -2350,7 +2394,7 @@
2350
2394
  },
2351
2395
  {
2352
2396
  "path": "src/server/management/model-routes.ts",
2353
- "sha256": "2a4b0b72eec0e4487831e9236c4f911214052bc1b3d195ee46db109b3891e003"
2397
+ "sha256": "de001901177f757c8a611f808e63ae55f64c6d81a9a5db6f29ac6bbb28f5c6f9"
2354
2398
  },
2355
2399
  {
2356
2400
  "path": "src/server/management/model-rows.ts",
@@ -2392,6 +2436,10 @@
2392
2436
  "path": "src/server/management/sidebar-routes.ts",
2393
2437
  "sha256": "0926c61288d6344456516c4208ea788192739d5d4c47c5566baf861313b75301"
2394
2438
  },
2439
+ {
2440
+ "path": "src/server/management/storage-log-guard-routes.ts",
2441
+ "sha256": "76491da8b595410593405d8ae7fbfa0b870653277f801b75c01086fa69ca3445"
2442
+ },
2395
2443
  {
2396
2444
  "path": "src/server/management/sync-response.ts",
2397
2445
  "sha256": "580cd5b67c1b1c7ac2a25262da00dc4dd31c7959e506622fc13a2f240d800786"
@@ -2506,7 +2554,7 @@
2506
2554
  },
2507
2555
  {
2508
2556
  "path": "src/server/responses/core.ts",
2509
- "sha256": "d60f902c7c496690e701e2bd0217adb1df8b7f2fcb4c43cc9ec9afc74d8a80b8"
2557
+ "sha256": "8a4539f6e9fd8a7016bc7562316525f7ce0f236481ec51c63d14a6ca253d1786"
2510
2558
  },
2511
2559
  {
2512
2560
  "path": "src/server/responses/empty-completion-guard.ts",
@@ -2570,7 +2618,7 @@
2570
2618
  },
2571
2619
  {
2572
2620
  "path": "src/server/system-env.ts",
2573
- "sha256": "d9d569ea71f74a84f8618dd2e43a21ea5917141aafdfe0def47eca17ce95e7f4"
2621
+ "sha256": "4ba855172048295bd4933bcdade706a901fbf96b345c98e226c548bd32720a6e"
2574
2622
  },
2575
2623
  {
2576
2624
  "path": "src/server/windows-tcp-drop.ts",
@@ -2666,7 +2714,7 @@
2666
2714
  },
2667
2715
  {
2668
2716
  "path": "src/types.ts",
2669
- "sha256": "7e20fa8bd3052a6869623060cfa67c1654115046daf65a42087d07465785b38a"
2717
+ "sha256": "a1aa12232d1424a93598402de73b7455bf5d33892c67ef0772b8c60a44f64560"
2670
2718
  },
2671
2719
  {
2672
2720
  "path": "src/update/badge.ts",
@@ -2782,7 +2830,7 @@
2782
2830
  },
2783
2831
  {
2784
2832
  "path": "src/web-search/loop.ts",
2785
- "sha256": "7934594b240697a96d081114d0922655f3e3d4d4b8a4f6518bf5d339e35d353a"
2833
+ "sha256": "a9c911108de03ec2ef1dce18d221b255f6015ce05a7949c38a33b1b6ac1fbff2"
2786
2834
  },
2787
2835
  {
2788
2836
  "path": "src/web-search/parse.ts",
@@ -14,8 +14,9 @@ import type { AdapterRequest, IncomingMeta, ProviderAdapter } from "../adapters/
14
14
  import { existsSync } from "node:fs";
15
15
  import { pathToFileURL } from "node:url";
16
16
  import { createAdapterEventQueue } from "../adapters/run-turn-queue";
17
- import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderContinuationState, OcxRequestOptions, OcxThinkingContent, OcxUsage, RateLimitRetryPolicy } from "../types";
17
+ import type { AdapterEvent, OcxMessage, OcxParsedRequest, OcxProviderContinuationState, OcxProviderOpaqueToolCallMetadata, OcxRequestOptions, OcxThinkingContent, OcxUsage, RateLimitRetryPolicy } from "../types";
18
18
  import { namespacedToolName, toolChoiceToolPredicate } from "../types";
19
+ import { cloneProviderOpaqueToolCallMetadata } from "../responses/provider-opaque-metadata";
19
20
  import type { AttemptRecoveryKind } from "../usage/log";
20
21
  import { bridgeToResponsesSSE } from "../bridge";
21
22
  import { clearableDeadline, idleDeadline } from "../lib/abort";
@@ -93,6 +94,11 @@ interface ImageCall {
93
94
  id: string;
94
95
  name: string;
95
96
  args: string;
97
+ /**
98
+ * Provider-opaque metadata from the originating part (issue #1735). Stored PER CALL: a
99
+ * signature belongs to one specific part, so parallel calls must not share one value.
100
+ */
101
+ providerMetadata?: OcxProviderOpaqueToolCallMetadata;
96
102
  }
97
103
 
98
104
  /**
@@ -109,13 +115,13 @@ function scanEventsForImageCall(events: AdapterEvent[], toolNames: Set<string>):
109
115
  const calls: ImageCall[] = [];
110
116
  const passthrough: AdapterEvent[] = [];
111
117
  let hasRealToolCall = false;
112
- let pending: { name: string; id: string; argsBuf: string; events: AdapterEvent[] } | null = null;
118
+ let pending: { name: string; id: string; argsBuf: string; events: AdapterEvent[]; providerMetadata?: OcxProviderOpaqueToolCallMetadata } | null = null;
113
119
  const flushPending = (): void => {
114
120
  if (!pending) return;
115
121
  if (toolNames.has(pending.name)) {
116
122
  // Unterminated image call still carries buffered args — fulfill so malformed JSON
117
123
  // becomes a normal tool_result error instead of silently vanishing.
118
- calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf });
124
+ calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf, providerMetadata: pending.providerMetadata });
119
125
  } else {
120
126
  passthrough.push(...pending.events);
121
127
  hasRealToolCall = true;
@@ -125,14 +131,14 @@ function scanEventsForImageCall(events: AdapterEvent[], toolNames: Set<string>):
125
131
  for (const e of events) {
126
132
  if (e.type === "tool_call_start") {
127
133
  flushPending();
128
- pending = { name: e.name, id: e.id, argsBuf: "", events: [e] };
134
+ pending = { name: e.name, id: e.id, argsBuf: "", events: [e], providerMetadata: e.providerMetadata };
129
135
  } else if (e.type === "tool_call_delta" && pending) {
130
136
  pending.argsBuf += e.arguments;
131
137
  pending.events.push(e);
132
138
  } else if (e.type === "tool_call_end" && pending) {
133
139
  pending.events.push(e);
134
140
  if (toolNames.has(pending.name)) {
135
- calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf });
141
+ calls.push({ id: pending.id, name: pending.name, args: pending.argsBuf, providerMetadata: pending.providerMetadata });
136
142
  } else {
137
143
  passthrough.push(...pending.events);
138
144
  hasRealToolCall = true;
@@ -871,6 +877,10 @@ export async function runWithImageBridge(deps: ImageBridgeDeps): Promise<Respons
871
877
  id: call.id,
872
878
  name: call.name,
873
879
  arguments: args,
880
+ // Clone per call: parallel media calls each keep their own signature.
881
+ ...(cloneProviderOpaqueToolCallMetadata(call.providerMetadata)
882
+ ? { providerMetadata: cloneProviderOpaqueToolCallMetadata(call.providerMetadata) }
883
+ : {}),
874
884
  })),
875
885
  ],
876
886
  timestamp: now,
@@ -331,7 +331,17 @@ export function parseAntigravityAvailableModels(
331
331
  out.push({
332
332
  id,
333
333
  ...(antigravityPositiveInteger(info.maxTokens) ? { contextWindow: antigravityPositiveInteger(info.maxTokens) } : {}),
334
- inputModalities: info.supportsImages === true ? ["text", "image"] : ["text"],
334
+ // Tri-state, deliberately not a ternary: `true` asserts image support,
335
+ // `false` asserts against it, and ABSENT is unknown. Collapsing absent into
336
+ // `["text"]` let routing read it as a confident `image: false` (#1796). The
337
+ // strict catalog still receives its `["text"]` compatibility default
338
+ // downstream via ensureStrictCatalogFields; only the routing-evidence
339
+ // channel stays honest about what was never asserted.
340
+ ...(info.supportsImages === true
341
+ ? { inputModalities: ["text", "image"] as string[] }
342
+ : info.supportsImages === false
343
+ ? { inputModalities: ["text"] as string[] }
344
+ : {}),
335
345
  });
336
346
  }
337
347
  return out;
@@ -99,7 +99,12 @@ export function providerModelDiscoverySpecError(spec: ProviderModelDiscoverySpec
99
99
  return "discovery path must be a query-free relative/origin path";
100
100
  }
101
101
  if (path.includes("\\")) return "discovery path must use forward slashes";
102
- if (path.split("/").some(segment => segment.replace(/%2e/gi, ".") === "..")) {
102
+ const segments = path.split("/");
103
+ if (segments.some((segment, index) => {
104
+ const decoded = segment.replace(/%2e/gi, ".");
105
+ if (decoded !== "..") return false;
106
+ return index !== 0 || segments.filter(s => s.replace(/%2e/gi, ".") === "..").length !== 1;
107
+ })) {
103
108
  return "discovery path must not contain parent-directory segments";
104
109
  }
105
110
  }
@@ -326,12 +331,83 @@ export function extractModelEnvelopeRows(
326
331
  }
327
332
 
328
333
  /** Validate, bound, deduplicate, and declaratively filter OpenAI `{data:[...]}` or top-level arrays (Together `#617`). */
334
+ /**
335
+ * Metadata a sibling `models[]` array may contribute to an ALREADY-ADMITTED
336
+ * `data[]` row (#1797).
337
+ *
338
+ * llama.cpp serves a dual-envelope body: an Ollama-style `models[]` array
339
+ * carrying `capabilities` alongside the OpenAI-style `data[]` array carrying
340
+ * `meta`, so the two halves of one model's metadata never meet and a server
341
+ * that truthfully advertises "multimodal" produced an image-blind row.
342
+ *
343
+ * Two boundaries make this safe, and both were added after review found the
344
+ * first attempt unsound:
345
+ *
346
+ * 1. It runs AFTER admission filtering. Enriching first let a sibling supply
347
+ * the exact field a provider filter requires — reproduced against the real
348
+ * Chutes policy, where a row lacking `supported_features: ["tools"]` was
349
+ * admitted once a same-id sibling provided it. Enrichment may change what is
350
+ * KNOWN about a model, never WHICH models are published.
351
+ * 2. Only the capability keys #1797 needs are copied. A blanket "fill every
352
+ * absent key" made the untrusted `models[]` array a way into any field the
353
+ * pipeline consumes.
354
+ *
355
+ * The list deliberately EXCLUDES `supported_features` and `features`, even
356
+ * though both are capability-shaped: they are the two keys real provider
357
+ * filters test (`registry.ts:1591` requires `supported_features` to contain
358
+ * "tools"; `registry.ts:1883` tests `features.tool_use`). Ordering already
359
+ * prevents a sibling from flipping an admission verdict, but a key that is
360
+ * both enrichable and filter-relevant is one refactor away from becoming a
361
+ * bypass again. #1797 does not need them.
362
+ */
363
+ const SIBLING_ENRICHABLE_KEYS = new Set(["capabilities", "modalities", "input_modalities"]);
364
+
365
+ type SiblingIndex = Map<string, Record<string, unknown> | null>;
366
+
367
+ function buildSiblingIndex(value: unknown, limit: number): SiblingIndex | null {
368
+ const record = plainObject(value);
369
+ const sibling = record?.models;
370
+ if (!Array.isArray(sibling) || sibling.length === 0 || sibling.length > limit) return null;
371
+
372
+ const byId: SiblingIndex = new Map();
373
+ for (const raw of sibling) {
374
+ const entry = plainObject(raw);
375
+ if (!entry) continue;
376
+ for (const key of ["id", "model", "name"]) {
377
+ const id = entry[key];
378
+ if (typeof id !== "string" || id.length === 0) continue;
379
+ // `null` marks an ambiguous id: two sibling entries claim it, so neither
380
+ // can be attributed with confidence and both are ignored.
381
+ byId.set(id, byId.has(id) && byId.get(id) !== entry ? null : entry);
382
+ }
383
+ }
384
+ return byId.size > 0 ? byId : null;
385
+ }
386
+
387
+ function enrichAdmittedModel(item: ProviderModelsApiItem, siblings: SiblingIndex): ProviderModelsApiItem {
388
+ const extra = siblings.get(item.id);
389
+ if (!extra) return item;
390
+ let merged: Record<string, unknown> | null = null;
391
+ for (const key of SIBLING_ENRICHABLE_KEYS) {
392
+ if (!(key in extra) || key in item) continue;
393
+ merged ??= { ...(item as Record<string, unknown>) };
394
+ merged[key] = extra[key];
395
+ }
396
+ return (merged ?? item) as ProviderModelsApiItem;
397
+ }
398
+
399
+ function plainObject(value: unknown): Record<string, unknown> | null {
400
+ return typeof value === "object" && value !== null && !Array.isArray(value)
401
+ ? value as Record<string, unknown>
402
+ : null;
403
+ }
329
404
  export function extractProviderModelItems(
330
405
  value: unknown,
331
406
  discovery: ResolvedProviderModelDiscovery,
332
407
  ): ProviderModelItemsResult {
333
408
  const limit = positiveIntegerAtMost(discovery.maxModels, MODEL_DISCOVERY_MAX_MODELS);
334
409
  let data: unknown[];
410
+ let siblings: SiblingIndex | null = null;
335
411
  if (Array.isArray(value)) {
336
412
  // Together-style top-level /models arrays. Catalog discovery must not treat a stray
337
413
  // `models` key on openai-chat responses as valid — only `data` envelopes or top-level arrays.
@@ -341,6 +417,7 @@ export function extractProviderModelItems(
341
417
  const envelope = extractModelEnvelopeRows(value, discovery.maxModels, ["data"]);
342
418
  if (!envelope.ok) return envelope;
343
419
  data = envelope.rows;
420
+ siblings = buildSiblingIndex(value, limit);
344
421
  }
345
422
 
346
423
  const items: ProviderModelsApiItem[] = [];
@@ -351,11 +428,22 @@ export function extractProviderModelItems(
351
428
  }
352
429
  const id = (raw as { id?: unknown }).id;
353
430
  if (!isValidModelDiscoveryModelId(id)) return { ok: false, reason: "invalid_shape" };
354
- const normalizedId = id;
355
- const item = raw as ProviderModelsApiItem;
356
- if (!providerModelMatchesDiscoveryFilter(item, discovery.spec?.filter) || seen.has(normalizedId)) continue;
357
- seen.add(normalizedId);
358
- items.push(item);
431
+ const prefix = discovery.spec?.stripIdPrefix;
432
+ let finalId = id;
433
+ if (prefix && finalId.startsWith(prefix)) {
434
+ finalId = finalId.slice(prefix.length);
435
+ if (!isValidModelDiscoveryModelId(finalId)) continue;
436
+ }
437
+ const item = finalId === id ? raw as ProviderModelsApiItem : { ...(raw as ProviderModelsApiItem), id: finalId };
438
+ // Admission is decided on the ORIGINAL `data[]` row, before any sibling
439
+ // enrichment. Merging first let a `models[]` entry supply the very field a
440
+ // provider filter requires — reproduced against the real Chutes policy,
441
+ // where a row lacking `supported_features: ["tools"]` was admitted once a
442
+ // same-id sibling provided it. Enrichment must never change WHICH models
443
+ // are published, only what is known about an already-admitted one.
444
+ if (!providerModelMatchesDiscoveryFilter(item, discovery.spec?.filter) || seen.has(finalId)) continue;
445
+ seen.add(finalId);
446
+ items.push(siblings ? enrichAdmittedModel(item, siblings) : item);
359
447
  }
360
448
  return { ok: true, items, rawCount: data.length };
361
449
  }