cartethyia 2.7.5 → 2.7.6

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 (263) hide show
  1. package/.env.example +4 -1
  2. package/README.md +1 -1
  3. package/dist/dashboard/assets/BannedPage-B1N603cM.js +1 -0
  4. package/dist/dashboard/assets/BannedPage-B1N603cM.js.gz +0 -0
  5. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js +3 -0
  6. package/dist/dashboard/assets/CliToolDetailPage-9q4_4NoK.js.gz +0 -0
  7. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js +1 -0
  8. package/dist/dashboard/assets/CliToolsPage-DwshGtK-.js.gz +0 -0
  9. package/dist/dashboard/assets/CombosPage-D762MIkp.js +1 -0
  10. package/dist/dashboard/assets/CombosPage-D762MIkp.js.gz +0 -0
  11. package/dist/dashboard/assets/{ConsoleLogPage-D5rol2j2.js → ConsoleLogPage-KRYjHZsX.js} +1 -1
  12. package/dist/dashboard/assets/ConsoleLogPage-KRYjHZsX.js.gz +0 -0
  13. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js +1 -0
  14. package/dist/dashboard/assets/CustomizationPage-DXsxk5uM.js.gz +0 -0
  15. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js +1 -0
  16. package/dist/dashboard/assets/HealthEventsModal-BEjAjD4F.js.gz +0 -0
  17. package/dist/dashboard/assets/{InjectSystemPromptPanel-B5nZvmf0.js → InjectSystemPromptPanel-d5v3K_Yc.js} +245 -2
  18. package/dist/dashboard/assets/InjectSystemPromptPanel-d5v3K_Yc.js.gz +0 -0
  19. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js +1 -0
  20. package/dist/dashboard/assets/LoginPage-Ccv4tjNS.js.gz +0 -0
  21. package/dist/dashboard/assets/{ModelPicker-DnQPSIA8.js → ModelPicker-C6WlpU5E.js} +1 -1
  22. package/dist/dashboard/assets/ModelPicker-C6WlpU5E.js.gz +0 -0
  23. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js +1 -0
  24. package/dist/dashboard/assets/OverviewPage-DN9fYNWA.js.gz +0 -0
  25. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js +5 -0
  26. package/dist/dashboard/assets/ProviderDetailPage-BY0ieUgz.js.gz +0 -0
  27. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +1 -0
  28. package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
  29. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js +1 -0
  30. package/dist/dashboard/assets/ProvidersPage-DNsbfea2.js.gz +0 -0
  31. package/dist/dashboard/assets/{ProxyPage-5SnUSy3j.js → ProxyPage-DxjvUzSD.js} +1 -1
  32. package/dist/dashboard/assets/ProxyPage-DxjvUzSD.js.gz +0 -0
  33. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js +1 -0
  34. package/dist/dashboard/assets/QuotaPage-OaHScjpX.js.gz +0 -0
  35. package/dist/dashboard/assets/{SettingsPage-BJtRZ4qD.js → SettingsPage-BW4AKj2H.js} +1 -1
  36. package/dist/dashboard/assets/SettingsPage-BW4AKj2H.js.gz +0 -0
  37. package/dist/dashboard/assets/SetupPage-44BZrxFC.js +1 -0
  38. package/dist/dashboard/assets/SetupPage-44BZrxFC.js.gz +0 -0
  39. package/dist/dashboard/assets/{StudioPage-BfAb5-o_.js → StudioPage-DRPavCdU.js} +4 -4
  40. package/dist/dashboard/assets/StudioPage-DRPavCdU.js.gz +0 -0
  41. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js +1 -0
  42. package/dist/dashboard/assets/ToolIcon-CfeLA-Z_.js.gz +0 -0
  43. package/dist/dashboard/assets/{UsagePage-BNzeZ2Vk.js → UsagePage-B7M7LvMM.js} +13 -13
  44. package/dist/dashboard/assets/UsagePage-B7M7LvMM.js.gz +0 -0
  45. package/dist/dashboard/assets/api-keys-KvX83mRe.js +1 -0
  46. package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
  47. package/dist/dashboard/assets/app-DRnQLhsc.js +9 -0
  48. package/dist/dashboard/assets/app-DRnQLhsc.js.gz +0 -0
  49. package/dist/dashboard/assets/app-mweRcsKp.css +2 -0
  50. package/dist/dashboard/assets/app-mweRcsKp.css.gz +0 -0
  51. package/dist/dashboard/assets/{assert-C0K-c4eo.js → assert-CidQVoNo.js} +1 -1
  52. package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
  53. package/dist/dashboard/assets/{badge-DfbhQU4k.js → badge-BaX2GTrn.js} +1 -1
  54. package/dist/dashboard/assets/badge-BaX2GTrn.js.gz +0 -0
  55. package/dist/dashboard/assets/{banner-BllT4LcF.js → banner-DFH4Bkte.js} +1 -1
  56. package/dist/dashboard/assets/banner-DFH4Bkte.js.gz +0 -0
  57. package/dist/dashboard/assets/{card-CtkX66Wd.js → card-CxDw0lK6.js} +1 -1
  58. package/dist/dashboard/assets/card-CxDw0lK6.js.gz +0 -0
  59. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js +1 -0
  60. package/dist/dashboard/assets/circle-question-mark-Cz4un8sH.js.gz +0 -0
  61. package/dist/dashboard/assets/{cli-tools-CQXVMn4P.js → cli-tools-Bwv5-zGZ.js} +1 -1
  62. package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
  63. package/dist/dashboard/assets/{clipboard-button-BQqBQd2n.js → clipboard-button-DfS1ntiq.js} +1 -1
  64. package/dist/dashboard/assets/clipboard-button-DfS1ntiq.js.gz +0 -0
  65. package/dist/dashboard/assets/dialog-BK-NRr5u.js +1 -0
  66. package/dist/dashboard/assets/dialog-BK-NRr5u.js.gz +0 -0
  67. package/dist/dashboard/assets/{drawer-BrTEZ8zu.js → drawer-QqPul6sC.js} +1 -1
  68. package/dist/dashboard/assets/drawer-QqPul6sC.js.gz +0 -0
  69. package/dist/dashboard/assets/entry-BMlYJVFj.js +1 -0
  70. package/dist/dashboard/assets/entry-BMlYJVFj.js.gz +0 -0
  71. package/dist/dashboard/assets/entry-D6WvojeD.js +4 -0
  72. package/dist/dashboard/assets/entry-D6WvojeD.js.gz +0 -0
  73. package/dist/dashboard/assets/entry-Dmx7gBiN.js +1 -0
  74. package/dist/dashboard/assets/entry-Dmx7gBiN.js.gz +0 -0
  75. package/dist/dashboard/assets/{formatters-BAACA727.js → formatters-u7JPB5BX.js} +1 -1
  76. package/dist/dashboard/assets/formatters-u7JPB5BX.js.gz +0 -0
  77. package/dist/dashboard/assets/house-h9AZlJuT.js +1 -0
  78. package/dist/dashboard/assets/house-h9AZlJuT.js.gz +0 -0
  79. package/dist/dashboard/assets/{index-FQlj0HUT.js → index-Ko4dLRnV.js} +2 -2
  80. package/dist/dashboard/assets/index-Ko4dLRnV.js.gz +0 -0
  81. package/dist/dashboard/assets/{inline-C4gU5iOL.js → inline-CHJQwxLa.js} +1 -1
  82. package/dist/dashboard/assets/inline-CHJQwxLa.js.gz +0 -0
  83. package/dist/dashboard/assets/{input-BHHX_Tmm.js → input-BlmlizVV.js} +1 -1
  84. package/dist/dashboard/assets/input-BlmlizVV.js.gz +0 -0
  85. package/dist/dashboard/assets/{layout-CajrYUnD.js → layout-Bz93I-yE.js} +1 -1
  86. package/dist/dashboard/assets/layout-Bz93I-yE.js.gz +0 -0
  87. package/dist/dashboard/assets/{list-row-Bx2I7XUe.js → list-row-Ml16KCfu.js} +1 -1
  88. package/dist/dashboard/assets/list-row-Ml16KCfu.js.gz +0 -0
  89. package/dist/dashboard/assets/{live-DNNqRbj2.js → live-7_QpnYGu.js} +1 -1
  90. package/dist/dashboard/assets/live-7_QpnYGu.js.gz +0 -0
  91. package/dist/dashboard/assets/{mutation-Rr0TIvcj.js → mutation-GU7XdEjz.js} +1 -1
  92. package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
  93. package/dist/dashboard/assets/{network-C5UBACrJ.js → network-CuMDaTzT.js} +1 -1
  94. package/dist/dashboard/assets/network-CuMDaTzT.js.gz +0 -0
  95. package/dist/dashboard/assets/numbers-CoqpaDMx.js +2 -0
  96. package/dist/dashboard/assets/numbers-CoqpaDMx.js.gz +0 -0
  97. package/dist/dashboard/assets/{pagination-Xsi9Qx04.js → pagination-B5aOoweZ.js} +1 -1
  98. package/dist/dashboard/assets/pagination-B5aOoweZ.js.gz +0 -0
  99. package/dist/dashboard/assets/providers/zai.webp +0 -0
  100. package/dist/dashboard/assets/providers/zcode.webp +0 -0
  101. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js → query-keys-YSoQOUh6.js} +1 -1
  102. package/dist/dashboard/assets/{query-keys-BloKtaXJ.js.gz → query-keys-YSoQOUh6.js.gz} +0 -0
  103. package/dist/dashboard/assets/quota-DJ1QlAOq.js +1 -0
  104. package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
  105. package/dist/dashboard/assets/{routing-in0f_IfK.js → routing-fnCsxgNO.js} +1 -1
  106. package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
  107. package/dist/dashboard/assets/{select-BLULNqTp.js → select-BHqpd-bg.js} +2 -2
  108. package/dist/dashboard/assets/select-BHqpd-bg.js.gz +0 -0
  109. package/dist/dashboard/assets/{settings-CcGczj6I.js → settings-BxslsErn.js} +1 -1
  110. package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
  111. package/dist/dashboard/assets/{stack-D2lIR0tg.js → stack-j7cXjgYX.js} +1 -1
  112. package/dist/dashboard/assets/stack-j7cXjgYX.js.gz +0 -0
  113. package/dist/dashboard/assets/{state-DTARjfiW.js → state-DHmEnLa2.js} +1 -1
  114. package/dist/dashboard/assets/state-DHmEnLa2.js.gz +0 -0
  115. package/dist/dashboard/assets/{switch-c0oPSnqW.js → switch-DmZcyTIC.js} +1 -1
  116. package/dist/dashboard/assets/switch-DmZcyTIC.js.gz +0 -0
  117. package/dist/dashboard/assets/{useMutation-m8WGNPrz.js → useMutation-CbCP4w1o.js} +1 -1
  118. package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
  119. package/dist/dashboard/index.html +2 -2
  120. package/dist/dashboard/index.html.gz +0 -0
  121. package/dist/dashboard/precompressed-assets.json +57 -57
  122. package/migrations/full-postgres/0042_add_telemetry_degenerate_stop.sql +14 -0
  123. package/migrations/lite-sqlite3/0042_add_telemetry_degenerate_stop.sql +12 -0
  124. package/package.json +1 -1
  125. package/src/boot/dependencies.ts +10 -2
  126. package/src/config/providers.ts +13 -7
  127. package/src/config/spec.ts +18 -11
  128. package/src/config/usage.ts +27 -0
  129. package/src/console/api-keys/routes.ts +19 -23
  130. package/src/console/cli-tools/contracts.ts +39 -295
  131. package/src/console/cli-tools/fs-ops.ts +29 -0
  132. package/src/console/cli-tools/injectors/claude.ts +3 -3
  133. package/src/console/cli-tools/injectors/codex.ts +6 -6
  134. package/src/console/cli-tools/injectors/driver.ts +8 -105
  135. package/src/console/cli-tools/injectors/kilo.ts +146 -21
  136. package/src/console/cli-tools/injectors/opencode.ts +28 -5
  137. package/src/console/cli-tools/routes.ts +6 -0
  138. package/src/console/cli-tools/service.ts +7 -6
  139. package/src/console/observability/contracts.ts +6 -0
  140. package/src/console/observability/store.ts +3 -0
  141. package/src/console/share/share-stats.ts +7 -9
  142. package/src/observability/event-log.ts +7 -0
  143. package/src/observability/event-query.ts +2 -0
  144. package/src/observability/telemetry-buffer.ts +7 -0
  145. package/src/persistence/schema.ts +8 -0
  146. package/src/persistence/stores/api-key-store.ts +19 -1
  147. package/src/protocol/dsml.ts +5 -76
  148. package/src/providers/adapters/compatible-adapter.ts +29 -1
  149. package/src/providers/default-registry.ts +12 -2
  150. package/src/providers/integrations/antigravity/antigravity-protocol.ts +88 -14
  151. package/src/providers/integrations/antigravity/antigravity-quota.ts +18 -6
  152. package/src/providers/integrations/antigravity/antigravity.ts +20 -11
  153. package/src/providers/integrations/cursor/cursor.ts +2 -3
  154. package/src/providers/integrations/github/github-discovery.ts +15 -2
  155. package/src/providers/integrations/github/github-oauth.ts +178 -9
  156. package/src/providers/integrations/github/github.ts +95 -14
  157. package/src/providers/integrations/kiro/kiro.ts +1 -2
  158. package/src/providers/integrations/qoder/qoder-catalog.ts +9 -3
  159. package/src/providers/integrations/qoder/qoder.ts +147 -88
  160. package/src/providers/integrations/trae/trae.ts +2 -2
  161. package/src/providers/operations/account-error-classification.ts +67 -17
  162. package/src/providers/operations/byok-wire-profile.ts +19 -15
  163. package/src/providers/provider-usage.ts +15 -49
  164. package/src/security/admission/service.ts +11 -4
  165. package/src/security/api-key-auth.ts +5 -3
  166. package/src/transport/dispatch/attempt-finalize.ts +69 -21
  167. package/src/transport/dispatch/attempt-loop.ts +22 -0
  168. package/src/transport/failure-policy.ts +15 -1
  169. package/src/transport/guards/error-lifecycle.ts +4 -0
  170. package/src/transport/request/state.ts +6 -0
  171. package/src/transport/routing/router.ts +7 -0
  172. package/src/transport/surface/reasoning-summary.ts +9 -14
  173. package/src/transport/vision-handoff.ts +83 -28
  174. package/dist/dashboard/assets/BannedPage-Cj15GsMp.js +0 -1
  175. package/dist/dashboard/assets/BannedPage-Cj15GsMp.js.gz +0 -0
  176. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js +0 -1
  177. package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js.gz +0 -0
  178. package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js +0 -1
  179. package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
  180. package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js +0 -1
  181. package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js.gz +0 -0
  182. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js +0 -1
  183. package/dist/dashboard/assets/CombosPage-DEEKkYD-.js.gz +0 -0
  184. package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js.gz +0 -0
  185. package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js +0 -1
  186. package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js.gz +0 -0
  187. package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js.gz +0 -0
  188. package/dist/dashboard/assets/LoginPage-DkXb6dx-.js +0 -1
  189. package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
  190. package/dist/dashboard/assets/ModelPicker-DnQPSIA8.js.gz +0 -0
  191. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js +0 -1
  192. package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js.gz +0 -0
  193. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js +0 -5
  194. package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js.gz +0 -0
  195. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js +0 -1
  196. package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js.gz +0 -0
  197. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js +0 -1
  198. package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js.gz +0 -0
  199. package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js.gz +0 -0
  200. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js +0 -1
  201. package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js.gz +0 -0
  202. package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js.gz +0 -0
  203. package/dist/dashboard/assets/SetupPage-WTa0sktC.js +0 -1
  204. package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
  205. package/dist/dashboard/assets/StudioPage-BfAb5-o_.js.gz +0 -0
  206. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js +0 -1
  207. package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
  208. package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js.gz +0 -0
  209. package/dist/dashboard/assets/api-keys-l29JROPv.js +0 -1
  210. package/dist/dashboard/assets/api-keys-l29JROPv.js.gz +0 -0
  211. package/dist/dashboard/assets/app--PJWq8_C.css +0 -2
  212. package/dist/dashboard/assets/app--PJWq8_C.css.gz +0 -0
  213. package/dist/dashboard/assets/app-Bgd3zANQ.js +0 -9
  214. package/dist/dashboard/assets/app-Bgd3zANQ.js.gz +0 -0
  215. package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
  216. package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
  217. package/dist/dashboard/assets/banner-BllT4LcF.js.gz +0 -0
  218. package/dist/dashboard/assets/card-CtkX66Wd.js.gz +0 -0
  219. package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
  220. package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
  221. package/dist/dashboard/assets/dialog-BEK7KP0H.js +0 -1
  222. package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
  223. package/dist/dashboard/assets/drawer-BrTEZ8zu.js.gz +0 -0
  224. package/dist/dashboard/assets/entry-CHWxbS56.js +0 -1
  225. package/dist/dashboard/assets/entry-CHWxbS56.js.gz +0 -0
  226. package/dist/dashboard/assets/entry-EBHJ3DrE.js +0 -1
  227. package/dist/dashboard/assets/entry-EBHJ3DrE.js.gz +0 -0
  228. package/dist/dashboard/assets/entry-LCS85hiq.js +0 -4
  229. package/dist/dashboard/assets/entry-LCS85hiq.js.gz +0 -0
  230. package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
  231. package/dist/dashboard/assets/github-badge-YSCE4UC2.js +0 -1
  232. package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
  233. package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
  234. package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
  235. package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
  236. package/dist/dashboard/assets/layout-CajrYUnD.js.gz +0 -0
  237. package/dist/dashboard/assets/list-row-Bx2I7XUe.js.gz +0 -0
  238. package/dist/dashboard/assets/live-DNNqRbj2.js.gz +0 -0
  239. package/dist/dashboard/assets/mutation-Rr0TIvcj.js.gz +0 -0
  240. package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
  241. package/dist/dashboard/assets/numbers-CUWAZK4J.js +0 -2
  242. package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
  243. package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
  244. package/dist/dashboard/assets/providers/zai-coding-plan.svg +0 -6
  245. package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
  246. package/dist/dashboard/assets/quota-DvQbD_sr.js +0 -1
  247. package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
  248. package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
  249. package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
  250. package/dist/dashboard/assets/settings-CcGczj6I.js.gz +0 -0
  251. package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
  252. package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
  253. package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
  254. package/dist/dashboard/assets/useMutation-m8WGNPrz.js.gz +0 -0
  255. package/src/console/cli-tools/injectors/cline.ts +0 -110
  256. package/src/console/cli-tools/injectors/copilot.ts +0 -108
  257. package/src/console/cli-tools/injectors/cowork.ts +0 -64
  258. package/src/console/cli-tools/injectors/deepseek-tui.ts +0 -85
  259. package/src/console/cli-tools/injectors/droid.ts +0 -96
  260. package/src/console/cli-tools/injectors/grok-build.ts +0 -70
  261. package/src/console/cli-tools/injectors/hermes.ts +0 -101
  262. package/src/console/cli-tools/injectors/jcode.ts +0 -115
  263. package/src/console/cli-tools/injectors/openclaw.ts +0 -161
@@ -1,76 +1,77 @@
1
1
  {
2
2
  "count": 119,
3
3
  "assets": [
4
- "assets/BannedPage-Cj15GsMp.js",
5
- "assets/ClaimGiftsButton-D83pBJ6J.js",
6
- "assets/CliToolDetailPage-DZKmVuJN.js",
7
- "assets/CliToolsPage-BIccZmeL.js",
8
- "assets/CombosPage-DEEKkYD-.js",
9
- "assets/ConsoleLogPage-D5rol2j2.js",
10
- "assets/CustomizationPage-BKj_r0rp.js",
11
- "assets/InjectSystemPromptPanel-B5nZvmf0.js",
12
- "assets/LoginPage-DkXb6dx-.js",
13
- "assets/ModelPicker-DnQPSIA8.js",
14
- "assets/OverviewPage-Ci2wQKUz.js",
15
- "assets/ProviderDetailPage-odlgYrOg.js",
16
- "assets/ProviderIcon-EfeloBn4.js",
17
- "assets/ProvidersPage-CqFBQEB8.js",
18
- "assets/ProxyPage-5SnUSy3j.js",
19
- "assets/QuotaPage-CmnMDzhP.js",
20
- "assets/SettingsPage-BJtRZ4qD.js",
21
- "assets/SetupPage-WTa0sktC.js",
22
- "assets/StudioPage-BfAb5-o_.js",
23
- "assets/ToolIcon-K1ckcDKg.js",
24
- "assets/UsagePage-BNzeZ2Vk.js",
25
- "assets/api-keys-l29JROPv.js",
26
- "assets/app--PJWq8_C.css",
27
- "assets/app-Bgd3zANQ.js",
4
+ "assets/BannedPage-B1N603cM.js",
5
+ "assets/CliToolDetailPage-9q4_4NoK.js",
6
+ "assets/CliToolsPage-DwshGtK-.js",
7
+ "assets/CombosPage-D762MIkp.js",
8
+ "assets/ConsoleLogPage-KRYjHZsX.js",
9
+ "assets/CustomizationPage-DXsxk5uM.js",
10
+ "assets/HealthEventsModal-BEjAjD4F.js",
11
+ "assets/InjectSystemPromptPanel-d5v3K_Yc.js",
12
+ "assets/LoginPage-Ccv4tjNS.js",
13
+ "assets/ModelPicker-C6WlpU5E.js",
14
+ "assets/OverviewPage-DN9fYNWA.js",
15
+ "assets/ProviderDetailPage-BY0ieUgz.js",
16
+ "assets/ProviderIcon-jjqXJDA3.js",
17
+ "assets/ProvidersPage-DNsbfea2.js",
18
+ "assets/ProxyPage-DxjvUzSD.js",
19
+ "assets/QuotaPage-OaHScjpX.js",
20
+ "assets/SettingsPage-BW4AKj2H.js",
21
+ "assets/SetupPage-44BZrxFC.js",
22
+ "assets/StudioPage-DRPavCdU.js",
23
+ "assets/ToolIcon-CfeLA-Z_.js",
24
+ "assets/UsagePage-B7M7LvMM.js",
25
+ "assets/api-keys-KvX83mRe.js",
26
+ "assets/app-DRnQLhsc.js",
27
+ "assets/app-mweRcsKp.css",
28
28
  "assets/arrow-left-CpBxkoxI.js",
29
29
  "assets/arrow-right-Dl5yKnp8.js",
30
30
  "assets/arrow-up-59ms1iiT.js",
31
- "assets/assert-C0K-c4eo.js",
31
+ "assets/assert-CidQVoNo.js",
32
32
  "assets/backup-file-gdKIlg8U.js",
33
- "assets/badge-DfbhQU4k.js",
34
- "assets/banner-BllT4LcF.js",
33
+ "assets/badge-BaX2GTrn.js",
34
+ "assets/banner-DFH4Bkte.js",
35
35
  "assets/brain-Cwed_72z.js",
36
- "assets/card-CtkX66Wd.js",
36
+ "assets/card-CxDw0lK6.js",
37
37
  "assets/chevron-left-Bf6CaTSJ.js",
38
38
  "assets/chevron-right-BXIy5l3h.js",
39
39
  "assets/circle-alert-CntYHV5v.js",
40
40
  "assets/circle-check-BU3v_mFW.js",
41
- "assets/cli-tools-CQXVMn4P.js",
42
- "assets/clipboard-button-BQqBQd2n.js",
41
+ "assets/circle-question-mark-Cz4un8sH.js",
42
+ "assets/cli-tools-Bwv5-zGZ.js",
43
+ "assets/clipboard-button-DfS1ntiq.js",
43
44
  "assets/database-Dz9N3zGd.js",
44
- "assets/dialog-BEK7KP0H.js",
45
+ "assets/dialog-BK-NRr5u.js",
45
46
  "assets/dialog-actions-B1axpEg7.js",
46
47
  "assets/download-dRFo5_Wu.js",
47
- "assets/drawer-BrTEZ8zu.js",
48
- "assets/entry-CHWxbS56.js",
49
- "assets/entry-EBHJ3DrE.js",
50
- "assets/entry-LCS85hiq.js",
48
+ "assets/drawer-QqPul6sC.js",
49
+ "assets/entry-BMlYJVFj.js",
50
+ "assets/entry-D6WvojeD.js",
51
+ "assets/entry-Dmx7gBiN.js",
51
52
  "assets/eye-C_hawfH4.js",
52
53
  "assets/eye-off-Bk5g2luF.js",
53
54
  "assets/fingerprint-pattern-BWuHtbW4.js",
54
- "assets/formatters-BAACA727.js",
55
+ "assets/formatters-u7JPB5BX.js",
55
56
  "assets/gauge-BbIMy7MB.js",
56
- "assets/github-badge-YSCE4UC2.js",
57
+ "assets/house-h9AZlJuT.js",
57
58
  "assets/image-BPaouViG.js",
58
- "assets/index-FQlj0HUT.js",
59
- "assets/inline-C4gU5iOL.js",
60
- "assets/input-BHHX_Tmm.js",
59
+ "assets/index-Ko4dLRnV.js",
60
+ "assets/inline-CHJQwxLa.js",
61
+ "assets/input-BlmlizVV.js",
61
62
  "assets/jsx-runtime-CXUMngI_.js",
62
63
  "assets/key-round-UkavsGxp.js",
63
64
  "assets/layers-2-glBbjl.js",
64
- "assets/layout-CajrYUnD.js",
65
- "assets/list-row-Bx2I7XUe.js",
66
- "assets/live-DNNqRbj2.js",
65
+ "assets/layout-Bz93I-yE.js",
66
+ "assets/list-row-Ml16KCfu.js",
67
+ "assets/live-7_QpnYGu.js",
67
68
  "assets/log-in-BmRjy60c.js",
68
69
  "assets/message-circle-CCxGwRvv.js",
69
70
  "assets/minimize-2-BTmMTK4o.js",
70
- "assets/mutation-Rr0TIvcj.js",
71
- "assets/network-C5UBACrJ.js",
72
- "assets/numbers-CUWAZK4J.js",
73
- "assets/pagination-Xsi9Qx04.js",
71
+ "assets/mutation-GU7XdEjz.js",
72
+ "assets/network-CuMDaTzT.js",
73
+ "assets/numbers-CoqpaDMx.js",
74
+ "assets/pagination-B5aOoweZ.js",
74
75
  "assets/pencil-768ysRAr.js",
75
76
  "assets/plus-DIdX_g-x.js",
76
77
  "assets/power-off-Yjw9GMJh.js",
@@ -92,23 +93,22 @@
92
93
  "assets/providers/openai-light.svg",
93
94
  "assets/providers/parallel.svg",
94
95
  "assets/providers/tokenharbor.svg",
95
- "assets/providers/zai-coding-plan.svg",
96
- "assets/query-keys-BloKtaXJ.js",
97
- "assets/quota-DvQbD_sr.js",
96
+ "assets/query-keys-YSoQOUh6.js",
97
+ "assets/quota-DJ1QlAOq.js",
98
98
  "assets/refresh-cw-BqJFk4sU.js",
99
99
  "assets/rotate-ccw-CufcqITi.js",
100
100
  "assets/route-CNSNj9Zm.js",
101
- "assets/routing-in0f_IfK.js",
101
+ "assets/routing-fnCsxgNO.js",
102
102
  "assets/scaling-nWE4Cx8f.js",
103
103
  "assets/search-JOKus9rb.js",
104
- "assets/select-BLULNqTp.js",
104
+ "assets/select-BHqpd-bg.js",
105
105
  "assets/settings-2-Ds9DQp0t.js",
106
- "assets/settings-CcGczj6I.js",
106
+ "assets/settings-BxslsErn.js",
107
107
  "assets/shield-BMQNxORh.js",
108
108
  "assets/shield-check-DVS0Foqh.js",
109
- "assets/stack-D2lIR0tg.js",
110
- "assets/state-DTARjfiW.js",
111
- "assets/switch-c0oPSnqW.js",
109
+ "assets/stack-j7cXjgYX.js",
110
+ "assets/state-DHmEnLa2.js",
111
+ "assets/switch-DmZcyTIC.js",
112
112
  "assets/terminal-0_IjPWTk.js",
113
113
  "assets/tokens-COzario9.js",
114
114
  "assets/trash-Cppn5c3R.js",
@@ -116,7 +116,7 @@
116
116
  "assets/use-modal-focus-By7oJoGd.js",
117
117
  "assets/use-reduced-motion-C4B0R6Sz.js",
118
118
  "assets/use-timeout-BwcBBRrT.js",
119
- "assets/useMutation-m8WGNPrz.js",
119
+ "assets/useMutation-CbCP4w1o.js",
120
120
  "assets/wrench-B6E1oEuY.js",
121
121
  "assets/zap-C4EeVW4q.js",
122
122
  "index.html"
@@ -0,0 +1,14 @@
1
+ -- Adds `telemetry_events.degenerate_stop` (boolean, nullable).
2
+ --
3
+ -- Marked on completed requests whose output is far smaller than the model's
4
+ -- ceiling and which ended with an ordinary `stop`. This is the signature of a
5
+ -- model truncating itself on a cached prefix: a short, cut-off reply that the
6
+ -- upstream reported as a clean stop. The column lets an operator measure how
7
+ -- often that happens instead of having to eyeball request detail.
8
+ --
9
+ -- NULL means the row predates this column (or the request never reached a
10
+ -- completed outcome). Only completed requests can carry a value.
11
+ --
12
+ -- `ADD COLUMN IF NOT EXISTS` keeps the file idempotent: a database built from a
13
+ -- newer baseline that already carries the column must not fail startup.
14
+ ALTER TABLE "telemetry_events" ADD COLUMN IF NOT EXISTS "degenerate_stop" boolean;
@@ -0,0 +1,12 @@
1
+ -- Adds `telemetry_events.degenerate_stop` (boolean, nullable) — see the
2
+ -- identically named PostgreSQL migration for why. Both backends must apply the
3
+ -- same behavior; SQLite stores it as integer (0/1).
4
+ --
5
+ -- Idempotency comes from the migration ledger, not from the statement: the
6
+ -- runner records the file inside the same transaction, so a file that has
7
+ -- already run is never re-executed. The baseline is generated from
8
+ -- `0000_baseline.sql` alone and does not carry this column.
9
+ --
10
+ -- NOTE: the runner already wraps each migration in a transaction, so this file
11
+ -- must NOT issue BEGIN/COMMIT.
12
+ ALTER TABLE "telemetry_events" ADD COLUMN "degenerate_stop" integer;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "cartethyia",
3
- "version": "2.7.5",
3
+ "version": "2.7.6",
4
4
  "description": "A powerful, self-hosted reverse proxy for OpenAI- and Anthropic-compatible AI clients, powered by native Bun and Elysia. It serves both protocols from a single server, routes every model across any configured provider, and translates requests and responses in real time — streaming and prompt caching included. Underneath it runs a full delivery engine: per-account health tracking, quota and cooldown enforcement, automatic failover across pools and providers, usage accounting, and telemetry. Point OpenCode, Cline, Claude Code, Codex, or any compatible client at Cartethyia and it keeps its native protocol while the gateway absorbs every provider-specific difference behind it. Runs on embedded SQLite or external PostgreSQL with optional Redis coordination, ships as a global CLI with a system-tray console, and needs only Bun 1.4+ alongside Node.js/npm.",
5
5
  "license": "GPL-3.0-only",
6
6
  "type": "module",
@@ -28,6 +28,7 @@ import { DrizzleProviderCatalogStore } from "../console/providers/catalog/store"
28
28
  import { InMemoryRouteSnapshotService } from "../transport/routing/route-model";
29
29
  import { RoutingEngine } from "../transport/routing/router";
30
30
  import { RedisAdmissionController } from "../transport/routing/admission";
31
+ import { admissionKey } from "../transport/routing/admission";
31
32
  import { ApiKeyAdmissionService } from "../security/admission/service";
32
33
  import { InMemoryAdmissionCounterStore } from "../security/admission/in-memory-store";
33
34
  import { RedisAdmissionCounterStore } from "../security/admission/redis-store";
@@ -479,10 +480,17 @@ export async function buildProductionDeps(): Promise<ProductionDeps> {
479
480
  owned.has(candidate.provider_account_id),
480
481
  );
481
482
  const snapshot = await routingEngine.accountInflightSnapshot(ownedCandidates);
483
+ // Map each bucket back to the account it belongs to using the same
484
+ // `admissionKey` format admission writes with — never string-slicing the
485
+ // bucket (the trailing segment is the owner tenant, not the account id).
486
+ const accountByBucket = new Map<string, string>();
487
+ for (const candidate of ownedCandidates) {
488
+ accountByBucket.set(admissionKey(candidate), candidate.provider_account_id!);
489
+ }
482
490
  const totals = new Map<string, number>();
483
491
  for (const [bucket, count] of snapshot) {
484
- const accountId = bucket.slice(bucket.lastIndexOf(":") + 1);
485
- if (!owned.has(accountId)) continue;
492
+ const accountId = accountByBucket.get(bucket);
493
+ if (accountId === undefined || !owned.has(accountId)) continue;
486
494
  totals.set(accountId, (totals.get(accountId) ?? 0) + count);
487
495
  }
488
496
  return [...totals].map(([accountId, inflight]) => ({ accountId, inflight }));
@@ -91,14 +91,20 @@ export function resolveGithubEnterpriseDomain(): string {
91
91
  }
92
92
  }
93
93
 
94
+ export type GithubCopilotMode = "opencode-copilot" | "vscode-client-real";
95
+
94
96
  /**
95
- * How cached prompt tokens are accounted. Unknown values fall back to `real`
96
- * so a typo cannot silently flip every provider to simplified accounting.
97
+ * Which GitHub Copilot wire identity the adapter uses. Defaults to
98
+ * `opencode-copilot` (raw GitHub OAuth token + minimal OpenCode headers),
99
+ * which is the proven-most-stable path (one token, no mint expiry). The
100
+ * `vscode-client-real` mode matches the VS Code reference client exactly but
101
+ * requires a freshly minted Copilot token.
97
102
  */
98
- export function resolveCacheMode(): "simplified" | "real" {
103
+ export function resolveGithubCopilotMode(): GithubCopilotMode {
99
104
  const raw = readText(
100
- "CARTETHYIA_CACHE_MODE",
101
- CONFIG_SPEC.CARTETHYIA_CACHE_MODE,
102
- ).toLowerCase();
103
- return raw === "simplified" ? "simplified" : "real";
105
+ "CARTETHYIA_GITHUB_COPILOT_MODE",
106
+ CONFIG_SPEC.CARTETHYIA_GITHUB_COPILOT_MODE,
107
+ ).trim().toLowerCase();
108
+ if (raw === "vscode-client-real") return "vscode-client-real";
109
+ return "opencode-copilot";
104
110
  }
@@ -188,6 +188,13 @@ export const CONFIG_SPEC = {
188
188
  min: 1 * 1024 * 1024,
189
189
  max: 16 * 1024 * 1024,
190
190
  },
191
+ // Input-token accounting for usage display. Providers disagree on whether
192
+ // `input_tokens` already includes cached tokens: OpenAI/DeepSeek report the
193
+ // inclusive total with a cached subset, while Anthropic reports fresh-only
194
+ // with cache reads separate. `inclusive` (default) folds cache into input so
195
+ // every provider reads alike — IN is always the whole prompt and CACHED its
196
+ // subset. `as-is` keeps the raw upstream semantics.
197
+ CARTETHYIA_USAGE_INPUT_MODE: { kind: "text", default: "inclusive" },
191
198
 
192
199
  // Upstream request timeout + retry backoff
193
200
  //
@@ -297,20 +304,20 @@ export const CONFIG_SPEC = {
297
304
  * an operator on one has no other way to point the login at it.
298
305
  */
299
306
  CARTETHYIA_GITHUB_ENTERPRISE_DOMAIN: { kind: "text", default: "" },
300
- // Only the literal true opts active ZCode accounts into daily gift claims.
301
- CARTETHYIA_ZCODE_AUTO_CLAIM: { kind: "text", default: "false" },
302
307
  /**
303
- * How cached prompt tokens are accounted.
308
+ * Which wire identity the GitHub Copilot Auto/chat path presents to the
309
+ * upstream:
304
310
  *
305
- * - `simplified` (default): the request is cache-eligible when the provider
306
- * reports a cache hit (`cached_input_tokens > 0`); every input token is
307
- * then counted as cached. A reported `0` or an absent report are both a
308
- * cache miss and stay uncached.
309
- * - `real`: the provider's reported cache numbers are kept as-is (the
310
- * pre-2.7.6 behavior). Use it when the exact per-provider split matters
311
- * more than a uniform hit-rate reading.
311
+ * - `opencode-copilot` (default): the long-lived GitHub OAuth token + minimal
312
+ * OpenCode headers. One token, no mint step, no short-lived minted-token
313
+ * expiry. This is the most stable in practice.
314
+ * - `vscode-client-real`: a freshly minted Copilot token + the full VS Code
315
+ * reference headers. Matches the VS Code client exactly, but requires the
316
+ * minted token (expires ~25 min) and the reference identity.
312
317
  */
313
- CARTETHYIA_CACHE_MODE: { kind: "text", default: "simplified" },
318
+ CARTETHYIA_GITHUB_COPILOT_MODE: { kind: "text", default: "opencode-copilot" },
319
+ // Only the literal true opts active ZCode accounts into daily gift claims.
320
+ CARTETHYIA_ZCODE_AUTO_CLAIM: { kind: "text", default: "false" },
314
321
  /**
315
322
  * Free-tier OpenCode ids the listing still advertises but upstream refuses.
316
323
  * Replaces the bundled list outright; the single token `none` trusts the
@@ -0,0 +1,27 @@
1
+ /**
2
+ * Usage input-token accounting mode.
3
+ *
4
+ * Providers disagree on whether `input_tokens` already includes cached tokens.
5
+ * OpenAI/DeepSeek report the inclusive total with a cached subset; Anthropic
6
+ * reports fresh-only with cache reads (and writes) separate. `normalizeUsage`
7
+ * reads this mode to decide whether to fold cache into input so every provider
8
+ * reads alike (`inclusive`, the default) or to keep the raw upstream semantics
9
+ * (`as-is`).
10
+ */
11
+
12
+ import { CONFIG_SPEC, readText } from "./spec";
13
+
14
+ export type UsageInputMode = "inclusive" | "as-is";
15
+
16
+ /** Resolves the operator's chosen accounting mode; defaults to inclusive. */
17
+ export function resolveUsageInputMode(): UsageInputMode {
18
+ const raw = readText(
19
+ "CARTETHYIA_USAGE_INPUT_MODE",
20
+ CONFIG_SPEC.CARTETHYIA_USAGE_INPUT_MODE,
21
+ )
22
+ .trim()
23
+ .toLowerCase();
24
+ if (raw === "inclusive") return "inclusive";
25
+ if (raw === "as-is") return "as-is";
26
+ throw new Error('CARTETHYIA_USAGE_INPUT_MODE must be "inclusive" or "as-is"');
27
+ }
@@ -41,7 +41,6 @@ import {
41
41
  } from "./contracts";
42
42
  import type { SharedKeyActivityDetail, SharedKeySummary } from "../share/share-usage";
43
43
  import { popupImageBytes } from "./share-popup-image";
44
- import { log } from "../../observability/logger";
45
44
 
46
45
  const SHARED_CHILD_SORT_COLUMNS = new Set<SharedChildSortColumn>([
47
46
  "createdAt",
@@ -87,33 +86,23 @@ export function createApiKeyOperations(config: ApiKeyConfig) {
87
86
  const topLevel = records.filter(
88
87
  (record) => record.revokedAt === undefined && record.parentKeyId === undefined,
89
88
  );
90
- // A share template's own counter never moves for child traffic, so
91
- // reporting it raw would show a template as untouched while the gateway
92
- // is refusing its recipients on the parent budget. Report the figure
93
- // the gateway actually enforces: the template's counter plus every
94
- // telemetry total the family ever recorded — revoked/deleted children
95
- // included (their spend is already spent), so the number survives
96
- // cleanup and matches the share page.
89
+ // A share template's own counter is the live family accumulator now:
90
+ // every recipient commit adds to it (see ApiKeyAdmissionService
91
+ // commitUsage), so reporting it raw gives the enforced family total.
92
+ // No telemetry add-on is needed, and adding it here would double-count.
97
93
  return Promise.all(
98
94
  topLevel.map(async (record) => {
99
95
  const response = sanitizeApiKeyResponse(record);
100
96
  if (record.keyMode !== "share") return response;
101
- const family = await config.store
102
- .sumFamilyTelemetryConsumed(authorized.tenantId, record.id)
103
- .catch((error) => {
104
- // A failed sum must not fail the whole list, but it must not
105
- // be silent either: reporting the share template's spend as 0
106
- // under-reports consumed tokens in the console list.
107
- log.warn(
108
- `[api-keys] sumFamilyTelemetryConsumed failed for key ${record.id}; reporting 0`,
109
- error as Error,
110
- );
111
- return 0;
112
- });
113
- return { ...response, tokensConsumed: response.tokensConsumed + family };
97
+ return response;
114
98
  }),
115
- );
116
- },
99
+ );
100
+ },
101
+ async listActiveBannedKeys(access: AccessDecision | undefined): Promise<ApiKeyResponse[]> {
102
+ const authorized = requireTenantScope(access, "dashboard:read");
103
+ const records = await config.store.listActiveBanned(authorized.tenantId);
104
+ return records.map(sanitizeApiKeyResponse);
105
+ },
117
106
  /** Persists a new credential order. `keyIds` must name every top-level key
118
107
  the tenant has, so a partial list cannot silently renumber rows. */
119
108
  async reorderKeys(access: AccessDecision | undefined, keyIds: readonly string[]): Promise<void> {
@@ -939,6 +928,13 @@ export function createApiKeyRoutes(config: ApiKeyConfig): AnyElysia {
939
928
  return errorResponse(error, set, "API-key operation failed");
940
929
  }
941
930
  })
931
+ .get("/banned", async ({ request, set }) => {
932
+ try {
933
+ return await factory.listActiveBannedKeys(config.accessResolver(request));
934
+ } catch (error) {
935
+ return errorResponse(error, set, "API-key operation failed");
936
+ }
937
+ })
942
938
  .post("/reorder", { body: reorderKeysBody }, async ({ request, body, set }) => {
943
939
  try {
944
940
  await factory.reorderKeys(config.accessResolver(request), body.keyIds);