cartethyia 2.5.3 → 2.5.4
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.
- package/dist/dashboard/assets/{BannedPage-hfCzi-Ux.js → BannedPage-C2orBsI2.js} +1 -1
- package/dist/dashboard/assets/BannedPage-C2orBsI2.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js +1 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-DEDyKBlC.js → CliToolsPage-BV6pxVQo.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BV6pxVQo.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-CfuYiQ8Z.js → CombosPage-Bsan4679.js} +1 -1
- package/dist/dashboard/assets/CombosPage-Bsan4679.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-bsLuZmYH.js → ConsoleLogPage-CW-wPmJ6.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-CW-wPmJ6.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-_UWhwziJ.js → CustomizationPage-0p8uX7vB.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-0p8uX7vB.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-DDVIfZGW.js → LoginPage-BvzCx8Kr.js} +1 -1
- package/dist/dashboard/assets/LoginPage-BvzCx8Kr.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-CWkTUtpX.js → ModelPicker-BY1aKEkP.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-BY1aKEkP.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js +1 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js +7 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js +1 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js +1 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-D6pmQ86L.js → SetupPage-DDbMQsoo.js} +1 -1
- package/dist/dashboard/assets/SetupPage-DDbMQsoo.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-DWvKiuSl.js → SortableList-CB3Z7VTf.js} +1 -1
- package/dist/dashboard/assets/SortableList-CB3Z7VTf.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-CmkUrgdj.js → StudioPage-D95UCPHI.js} +3 -3
- package/dist/dashboard/assets/StudioPage-D95UCPHI.js.gz +0 -0
- package/dist/dashboard/assets/{UsagePage-B47uOydr.js → UsagePage-Cnae9SWA.js} +13 -13
- package/dist/dashboard/assets/UsagePage-Cnae9SWA.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-uNywYlfv.js → api-keys-VY68Mhd1.js} +1 -1
- package/dist/dashboard/assets/api-keys-VY68Mhd1.js.gz +0 -0
- package/dist/dashboard/assets/app-COlK95oi.css +2 -0
- package/dist/dashboard/assets/app-COlK95oi.css.gz +0 -0
- package/dist/dashboard/assets/{assert-NHwYq95t.js → assert-Chi7pCnt.js} +1 -1
- package/dist/dashboard/assets/assert-Chi7pCnt.js.gz +0 -0
- package/dist/dashboard/assets/{badge-6uzDDvqs.js → badge-D4pQapKj.js} +1 -1
- package/dist/dashboard/assets/badge-D4pQapKj.js.gz +0 -0
- package/dist/dashboard/assets/{banner-4_WNg2WZ.js → banner-DH6cg-_B.js} +1 -1
- package/dist/dashboard/assets/banner-DH6cg-_B.js.gz +0 -0
- package/dist/dashboard/assets/{card--AtFedAq.js → card-BKqlUOe4.js} +1 -1
- package/dist/dashboard/assets/card-BKqlUOe4.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-B3e7dx3N.js → cli-tools-fTgljTGA.js} +1 -1
- package/dist/dashboard/assets/cli-tools-fTgljTGA.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-NreUx6c8.js → clipboard-button-D5Ys_sM0.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-D5Ys_sM0.js.gz +0 -0
- package/dist/dashboard/assets/database-Dz9N3zGd.js +1 -0
- package/dist/dashboard/assets/database-Dz9N3zGd.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-BtpsJU98.js → dialog-BYj-8WuK.js} +1 -1
- package/dist/dashboard/assets/dialog-BYj-8WuK.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-WwwtzihF.js → drawer-CmXIZ6H1.js} +1 -1
- package/dist/dashboard/assets/drawer-CmXIZ6H1.js.gz +0 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js +1 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js.gz +0 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js +1 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js.gz +0 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js +4 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-D_eM3IgG.js → github-badge-BlptL8Uf.js} +1 -1
- package/dist/dashboard/assets/github-badge-BlptL8Uf.js.gz +0 -0
- package/dist/dashboard/assets/{index-BydyKaDz.js → index-js6TJvdr.js} +2 -2
- package/dist/dashboard/assets/index-js6TJvdr.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BcNGF8Gr.js → inline-DUWDSmDV.js} +1 -1
- package/dist/dashboard/assets/inline-DUWDSmDV.js.gz +0 -0
- package/dist/dashboard/assets/{input-BG41et9G.js → input-LVjgZq4f.js} +1 -1
- package/dist/dashboard/assets/input-LVjgZq4f.js.gz +0 -0
- package/dist/dashboard/assets/{layout-C8mer_Ak.js → layout-CPfxpsfy.js} +1 -1
- package/dist/dashboard/assets/layout-CPfxpsfy.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-Gh_W4OR_.js → list-row-DupvLfDx.js} +1 -1
- package/dist/dashboard/assets/list-row-DupvLfDx.js.gz +0 -0
- package/dist/dashboard/assets/{live-BJGYRBnR.js → live-C4pEJUqI.js} +1 -1
- package/dist/dashboard/assets/live-C4pEJUqI.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js +1 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-BkoLM5Ba.js → mutation-B4ROwk8L.js} +1 -1
- package/dist/dashboard/assets/mutation-B4ROwk8L.js.gz +0 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js +2 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js.gz +0 -0
- package/dist/dashboard/assets/{query-keys-D7wX2vM5.js → query-keys-gmjzC3RS.js} +1 -1
- package/dist/dashboard/assets/{query-keys-D7wX2vM5.js.gz → query-keys-gmjzC3RS.js.gz} +0 -0
- package/dist/dashboard/assets/{routing-CcusqXA7.js → routing-C7tBT5o-.js} +1 -1
- package/dist/dashboard/assets/routing-C7tBT5o-.js.gz +0 -0
- package/dist/dashboard/assets/{select-BO6h8yNv.js → select-WUCXorXw.js} +2 -2
- package/dist/dashboard/assets/select-WUCXorXw.js.gz +0 -0
- package/dist/dashboard/assets/{settings-mpmXTgUa.js → settings-C_zKl1GS.js} +1 -1
- package/dist/dashboard/assets/settings-C_zKl1GS.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DwLmjUFK.js → stack-_3O0F8Xn.js} +1 -1
- package/dist/dashboard/assets/stack-_3O0F8Xn.js.gz +0 -0
- package/dist/dashboard/assets/{state-DYdQmdAl.js → state-BgTxHcJS.js} +1 -1
- package/dist/dashboard/assets/state-BgTxHcJS.js.gz +0 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js +1 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js.gz +0 -0
- package/dist/dashboard/assets/terminal-0_IjPWTk.js +1 -0
- package/dist/dashboard/assets/terminal-0_IjPWTk.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-w4u4CVue.js → useMutation-BWSC0UAS.js} +1 -1
- package/dist/dashboard/assets/useMutation-BWSC0UAS.js.gz +0 -0
- package/dist/dashboard/assets/zap-C4EeVW4q.js +1 -0
- package/dist/dashboard/assets/zap-C4EeVW4q.js.gz +0 -0
- package/dist/dashboard/donation/qris-risun-marke.png +0 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +54 -54
- package/package.json +1 -1
- package/scripts/cli/autostart.ts +237 -0
- package/scripts/cli/command/console-menu.ts +4 -8
- package/scripts/cli/command/update.ts +27 -10
- package/scripts/cli/main.ts +28 -1
- package/src/boot/app.ts +693 -693
- package/src/boot/dependencies.ts +646 -616
- package/src/config/spec.ts +55 -0
- package/src/config/telemetry.ts +46 -0
- package/src/console/api-keys/bucket-spend.ts +15 -4
- package/src/console/backup/contracts.ts +15 -2
- package/src/console/console-router.ts +8 -0
- package/src/console/data-management/contracts.ts +93 -0
- package/src/console/data-management/operations.ts +229 -0
- package/src/console/data-management/routes.ts +104 -0
- package/src/console/domain-registration.ts +39 -0
- package/src/console/observability/contracts.ts +524 -485
- package/src/console/observability/store.ts +1115 -1018
- package/src/console/providers/catalog/contracts.ts +6 -0
- package/src/console/providers/catalog/provider-operations.ts +20 -0
- package/src/console/providers/catalog/routes.ts +7 -0
- package/src/console/providers/catalog/store.ts +22 -1
- package/src/console/quota/account-quota-shared.ts +52 -39
- package/src/console/quota/refresh.ts +441 -429
- package/src/console/routing/pools/import-parse.ts +206 -0
- package/src/console/routing/pools/operations.ts +543 -501
- package/src/console/routing/pools/routes.ts +181 -164
- package/src/console/settings/contracts.ts +37 -0
- package/src/console/settings/store.ts +51 -0
- package/src/console/updates/routes.ts +16 -0
- package/src/main.ts +10 -0
- package/src/observability/event-compaction.ts +315 -0
- package/src/observability/event-day-index.ts +442 -0
- package/src/observability/event-log.ts +152 -3
- package/src/observability/payload-capture.ts +8 -1
- package/src/observability/payload-store.ts +440 -376
- package/src/persistence/health-event-flush.ts +36 -0
- package/src/persistence/schema.ts +1402 -1360
- package/src/persistence/stores/telemetry-store.ts +237 -214
- package/src/protocol/codecs.ts +1 -2
- package/src/protocol/image-clamp.ts +19 -1
- package/src/protocol/registry.ts +8 -0
- package/src/protocol/request/gemini.ts +9 -2
- package/src/protocol/request/messages.ts +14 -2
- package/src/providers/adapters/compatible-adapter.ts +3 -0
- package/src/providers/bundled-discovery-providers.ts +122 -119
- package/src/providers/configured-openai-providers.ts +136 -134
- package/src/providers/default-registry.ts +5 -4
- package/src/providers/discovery/openai-model-discovery.ts +5 -0
- package/src/providers/discovery/openrouter-free-roster.ts +15 -17
- package/src/providers/integrations/cline/cline-quota.ts +132 -125
- package/src/providers/integrations/codex/codex-headers.ts +25 -39
- package/src/providers/integrations/codex/codex.ts +2 -29
- package/src/providers/integrations/cursor/cursor-quota.ts +310 -0
- package/src/providers/integrations/cursor/cursor-request.ts +616 -471
- package/src/providers/integrations/cursor/cursor-session-manager.ts +319 -281
- package/src/providers/integrations/cursor/cursor.ts +1485 -960
- package/src/providers/integrations/cursor/protocol/messages.ts +25 -0
- package/src/providers/integrations/factory/factory.ts +8 -1
- package/src/providers/integrations/gemini.ts +6 -1
- package/src/providers/integrations/grok/grok-quota.ts +279 -177
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +73 -0
- package/src/providers/integrations/grok/grok-ratelimit.ts +218 -0
- package/src/providers/integrations/opencode/provider.ts +12 -13
- package/src/providers/integrations/qoder/qoder-quota.ts +192 -0
- package/src/providers/integrations/trae/trae-quota.ts +384 -0
- package/src/providers/operations/account-health-service.ts +1523 -1480
- package/src/providers/provider-contracts.ts +7 -0
- package/src/providers/provider-metadata.ts +6 -0
- package/src/providers/quota/quota-support.ts +8 -0
- package/src/security/api-key-auth.ts +504 -494
- package/src/transport/dispatch/generation.ts +6 -0
- package/src/transport/dispatch/proxy-request.ts +24 -1
- package/src/transport/dispatch/ratelimit-capture.ts +37 -0
- package/src/transport/dispatch/streaming/stream.ts +14 -0
- package/src/transport/dispatch/upstream.ts +9 -0
- package/src/transport/request/preparer.ts +7 -6
- package/src/transport/request/state.ts +9 -0
- package/src/transport/request/tenant-preferences.ts +60 -0
- package/src/transport/routing/route-catalog.ts +58 -10
- package/dist/dashboard/assets/BannedPage-hfCzi-Ux.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DLGqYEwI.js +0 -1
- package/dist/dashboard/assets/CliToolDetailPage-DLGqYEwI.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-DEDyKBlC.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-CfuYiQ8Z.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-bsLuZmYH.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-_UWhwziJ.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-Cjfc5WFS.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-Cjfc5WFS.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-DDVIfZGW.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-CWkTUtpX.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-B53YYMng.js +0 -1
- package/dist/dashboard/assets/OverviewPage-B53YYMng.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-B0KaAQf0.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage-B0KaAQf0.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Dx31DgIO.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-Dx31DgIO.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-BpnR4kXT.js +0 -7
- package/dist/dashboard/assets/ProxyPage-BpnR4kXT.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-BpOQCnun.js +0 -1
- package/dist/dashboard/assets/QuotaPage-BpOQCnun.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-DV1eo2J_.js +0 -1
- package/dist/dashboard/assets/SettingsPage-DV1eo2J_.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-D6pmQ86L.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-DWvKiuSl.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-CmkUrgdj.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-B47uOydr.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-uNywYlfv.js.gz +0 -0
- package/dist/dashboard/assets/app-DxivpfYG.css +0 -2
- package/dist/dashboard/assets/app-DxivpfYG.css.gz +0 -0
- package/dist/dashboard/assets/assert-NHwYq95t.js.gz +0 -0
- package/dist/dashboard/assets/badge-6uzDDvqs.js.gz +0 -0
- package/dist/dashboard/assets/banner-4_WNg2WZ.js.gz +0 -0
- package/dist/dashboard/assets/card--AtFedAq.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-B3e7dx3N.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-NreUx6c8.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BtpsJU98.js.gz +0 -0
- package/dist/dashboard/assets/download-A0SW9OCW.js +0 -1
- package/dist/dashboard/assets/download-A0SW9OCW.js.gz +0 -0
- package/dist/dashboard/assets/drawer-WwwtzihF.js.gz +0 -0
- package/dist/dashboard/assets/entry-CkryrIea.js +0 -4
- package/dist/dashboard/assets/entry-CkryrIea.js.gz +0 -0
- package/dist/dashboard/assets/entry-TJIye_jT.js +0 -1
- package/dist/dashboard/assets/entry-TJIye_jT.js.gz +0 -0
- package/dist/dashboard/assets/entry-jy9_4-Ke.js +0 -1
- package/dist/dashboard/assets/entry-jy9_4-Ke.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-D_eM3IgG.js.gz +0 -0
- package/dist/dashboard/assets/index-BydyKaDz.js.gz +0 -0
- package/dist/dashboard/assets/inline-BcNGF8Gr.js.gz +0 -0
- package/dist/dashboard/assets/input-BG41et9G.js.gz +0 -0
- package/dist/dashboard/assets/layout-C8mer_Ak.js.gz +0 -0
- package/dist/dashboard/assets/list-row-Gh_W4OR_.js.gz +0 -0
- package/dist/dashboard/assets/live-BJGYRBnR.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-DeVLDA7I.js +0 -1
- package/dist/dashboard/assets/model-bans-DeVLDA7I.js.gz +0 -0
- package/dist/dashboard/assets/mutation-BkoLM5Ba.js.gz +0 -0
- package/dist/dashboard/assets/numbers-Bs4LOOuf.js +0 -2
- package/dist/dashboard/assets/numbers-Bs4LOOuf.js.gz +0 -0
- package/dist/dashboard/assets/routing-CcusqXA7.js.gz +0 -0
- package/dist/dashboard/assets/select-BO6h8yNv.js.gz +0 -0
- package/dist/dashboard/assets/settings-mpmXTgUa.js.gz +0 -0
- package/dist/dashboard/assets/sparkles-BRaRUxAU.js +0 -1
- package/dist/dashboard/assets/sparkles-BRaRUxAU.js.gz +0 -0
- package/dist/dashboard/assets/stack-DwLmjUFK.js.gz +0 -0
- package/dist/dashboard/assets/state-DYdQmdAl.js.gz +0 -0
- package/dist/dashboard/assets/switch-CidSfbG7.js +0 -1
- package/dist/dashboard/assets/switch-CidSfbG7.js.gz +0 -0
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js +0 -1
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-w4u4CVue.js.gz +0 -0
- /package/dist/dashboard/assets/{app-CafWtVXA.js → app-DCQZRmHY.js} +0 -0
- /package/dist/dashboard/assets/{app-CafWtVXA.js.gz → app-DCQZRmHY.js.gz} +0 -0
|
@@ -1,119 +1,122 @@
|
|
|
1
|
-
import type { ProviderModule } from "./provider-registry";
|
|
2
|
-
import {
|
|
3
|
-
GENERIC_API_KEY_SPECS,
|
|
4
|
-
VERSIONED_ROOT_API_KEY_SPECS,
|
|
5
|
-
} from "./configured-openai-providers";
|
|
6
|
-
import { createApiKeyAdapter, type ApiKeyProviderSpec } from "./configured-provider";
|
|
7
|
-
|
|
8
|
-
/**
|
|
9
|
-
* Providers whose adapter and catalog discovery are the same bearer-auth
|
|
10
|
-
* OpenAI-compatible contract. Providers with static catalogs or additional
|
|
11
|
-
* upstream behavior remain declared beside their special handling.
|
|
12
|
-
*/
|
|
13
|
-
export const DISCOVERY_BACKED_PROVIDER_IDS = [
|
|
14
|
-
"groq",
|
|
15
|
-
"together",
|
|
16
|
-
"deepinfra",
|
|
17
|
-
"siliconflow",
|
|
18
|
-
"siliconflowcn",
|
|
19
|
-
"novita",
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
type
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
1
|
+
import type { ProviderModule } from "./provider-registry";
|
|
2
|
+
import {
|
|
3
|
+
GENERIC_API_KEY_SPECS,
|
|
4
|
+
VERSIONED_ROOT_API_KEY_SPECS,
|
|
5
|
+
} from "./configured-openai-providers";
|
|
6
|
+
import { createApiKeyAdapter, type ApiKeyProviderSpec } from "./configured-provider";
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* Providers whose adapter and catalog discovery are the same bearer-auth
|
|
10
|
+
* OpenAI-compatible contract. Providers with static catalogs or additional
|
|
11
|
+
* upstream behavior remain declared beside their special handling.
|
|
12
|
+
*/
|
|
13
|
+
export const DISCOVERY_BACKED_PROVIDER_IDS = [
|
|
14
|
+
"groq",
|
|
15
|
+
"together",
|
|
16
|
+
"deepinfra",
|
|
17
|
+
"siliconflow",
|
|
18
|
+
"siliconflowcn",
|
|
19
|
+
"novita",
|
|
20
|
+
"larprouter",
|
|
21
|
+
"venice",
|
|
22
|
+
"nanogpt",
|
|
23
|
+
"baseten",
|
|
24
|
+
"synthetic",
|
|
25
|
+
"stepfun",
|
|
26
|
+
"sakana",
|
|
27
|
+
"helmcode",
|
|
28
|
+
"coralbricks",
|
|
29
|
+
"aiand",
|
|
30
|
+
"wafer",
|
|
31
|
+
"firepass",
|
|
32
|
+
"zhipucoding",
|
|
33
|
+
"dashscope",
|
|
34
|
+
"qianfan",
|
|
35
|
+
] as const;
|
|
36
|
+
|
|
37
|
+
export type DiscoveryBackedProviderId = (typeof DISCOVERY_BACKED_PROVIDER_IDS)[number];
|
|
38
|
+
|
|
39
|
+
type DiscoveryBackedCapabilities = Pick<
|
|
40
|
+
ProviderModule,
|
|
41
|
+
"endpointPathsByWireFamily" | "loadAdapter" | "loadModelDiscovery"
|
|
42
|
+
>;
|
|
43
|
+
|
|
44
|
+
type ModelDiscoveryFactory = NonNullable<ProviderModule["loadModelDiscovery"]>;
|
|
45
|
+
type OpenAIModelDiscoveryFactory = (
|
|
46
|
+
providerId: string,
|
|
47
|
+
options?: {
|
|
48
|
+
readonly headers?: (credential: string) => Readonly<Record<string, string>>;
|
|
49
|
+
},
|
|
50
|
+
) => ModelDiscoveryFactory;
|
|
51
|
+
|
|
52
|
+
const DISCOVERY_BACKED_PROVIDER_SPECS = {
|
|
53
|
+
groq: VERSIONED_ROOT_API_KEY_SPECS.groq,
|
|
54
|
+
larprouter: GENERIC_API_KEY_SPECS.larprouter,
|
|
55
|
+
together: GENERIC_API_KEY_SPECS.together,
|
|
56
|
+
deepinfra: VERSIONED_ROOT_API_KEY_SPECS.deepinfra,
|
|
57
|
+
siliconflow: GENERIC_API_KEY_SPECS.siliconflow,
|
|
58
|
+
siliconflowcn: GENERIC_API_KEY_SPECS.siliconflowcn,
|
|
59
|
+
novita: VERSIONED_ROOT_API_KEY_SPECS.novita,
|
|
60
|
+
venice: VERSIONED_ROOT_API_KEY_SPECS.venice,
|
|
61
|
+
nanogpt: GENERIC_API_KEY_SPECS.nanogpt,
|
|
62
|
+
baseten: GENERIC_API_KEY_SPECS.baseten,
|
|
63
|
+
synthetic: GENERIC_API_KEY_SPECS.synthetic,
|
|
64
|
+
stepfun: GENERIC_API_KEY_SPECS.stepfun,
|
|
65
|
+
sakana: GENERIC_API_KEY_SPECS.sakana,
|
|
66
|
+
helmcode: GENERIC_API_KEY_SPECS.helmcode,
|
|
67
|
+
coralbricks: GENERIC_API_KEY_SPECS.coralbricks,
|
|
68
|
+
aiand: GENERIC_API_KEY_SPECS.aiand,
|
|
69
|
+
wafer: GENERIC_API_KEY_SPECS.wafer,
|
|
70
|
+
firepass: VERSIONED_ROOT_API_KEY_SPECS.firepass,
|
|
71
|
+
zhipucoding: VERSIONED_ROOT_API_KEY_SPECS.zhipucoding,
|
|
72
|
+
dashscope: GENERIC_API_KEY_SPECS.dashscope,
|
|
73
|
+
qianfan: VERSIONED_ROOT_API_KEY_SPECS.qianfan,
|
|
74
|
+
} satisfies Readonly<Record<DiscoveryBackedProviderId, ApiKeyProviderSpec>>;
|
|
75
|
+
|
|
76
|
+
function discoveryBackedCapabilities(
|
|
77
|
+
providerId: DiscoveryBackedProviderId,
|
|
78
|
+
spec: ApiKeyProviderSpec,
|
|
79
|
+
openAIModelDiscovery: OpenAIModelDiscoveryFactory,
|
|
80
|
+
): DiscoveryBackedCapabilities {
|
|
81
|
+
return {
|
|
82
|
+
...(spec.endpoint_paths_by_wire_family === undefined
|
|
83
|
+
? {}
|
|
84
|
+
: { endpointPathsByWireFamily: spec.endpoint_paths_by_wire_family }),
|
|
85
|
+
loadAdapter: async () => createApiKeyAdapter(spec),
|
|
86
|
+
loadModelDiscovery: openAIModelDiscovery(providerId, {
|
|
87
|
+
headers: (credential) => ({ authorization: `Bearer ${credential}` }),
|
|
88
|
+
}),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Creates the standard provider capability table using the registry's shared
|
|
94
|
+
* discovery loader, keeping its lazy import and authentication behavior intact.
|
|
95
|
+
*/
|
|
96
|
+
export function createDiscoveryBackedProviderCapabilities(
|
|
97
|
+
openAIModelDiscovery: OpenAIModelDiscoveryFactory,
|
|
98
|
+
): Readonly<Record<DiscoveryBackedProviderId, DiscoveryBackedCapabilities>> {
|
|
99
|
+
return {
|
|
100
|
+
groq: discoveryBackedCapabilities("groq", DISCOVERY_BACKED_PROVIDER_SPECS.groq, openAIModelDiscovery),
|
|
101
|
+
together: discoveryBackedCapabilities("together", DISCOVERY_BACKED_PROVIDER_SPECS.together, openAIModelDiscovery),
|
|
102
|
+
deepinfra: discoveryBackedCapabilities("deepinfra", DISCOVERY_BACKED_PROVIDER_SPECS.deepinfra, openAIModelDiscovery),
|
|
103
|
+
siliconflow: discoveryBackedCapabilities("siliconflow", DISCOVERY_BACKED_PROVIDER_SPECS.siliconflow, openAIModelDiscovery),
|
|
104
|
+
siliconflowcn: discoveryBackedCapabilities("siliconflowcn", DISCOVERY_BACKED_PROVIDER_SPECS.siliconflowcn, openAIModelDiscovery),
|
|
105
|
+
novita: discoveryBackedCapabilities("novita", DISCOVERY_BACKED_PROVIDER_SPECS.novita, openAIModelDiscovery),
|
|
106
|
+
larprouter: discoveryBackedCapabilities("larprouter", DISCOVERY_BACKED_PROVIDER_SPECS.larprouter, openAIModelDiscovery),
|
|
107
|
+
venice: discoveryBackedCapabilities("venice", DISCOVERY_BACKED_PROVIDER_SPECS.venice, openAIModelDiscovery),
|
|
108
|
+
nanogpt: discoveryBackedCapabilities("nanogpt", DISCOVERY_BACKED_PROVIDER_SPECS.nanogpt, openAIModelDiscovery),
|
|
109
|
+
baseten: discoveryBackedCapabilities("baseten", DISCOVERY_BACKED_PROVIDER_SPECS.baseten, openAIModelDiscovery),
|
|
110
|
+
synthetic: discoveryBackedCapabilities("synthetic", DISCOVERY_BACKED_PROVIDER_SPECS.synthetic, openAIModelDiscovery),
|
|
111
|
+
stepfun: discoveryBackedCapabilities("stepfun", DISCOVERY_BACKED_PROVIDER_SPECS.stepfun, openAIModelDiscovery),
|
|
112
|
+
sakana: discoveryBackedCapabilities("sakana", DISCOVERY_BACKED_PROVIDER_SPECS.sakana, openAIModelDiscovery),
|
|
113
|
+
helmcode: discoveryBackedCapabilities("helmcode", DISCOVERY_BACKED_PROVIDER_SPECS.helmcode, openAIModelDiscovery),
|
|
114
|
+
coralbricks: discoveryBackedCapabilities("coralbricks", DISCOVERY_BACKED_PROVIDER_SPECS.coralbricks, openAIModelDiscovery),
|
|
115
|
+
aiand: discoveryBackedCapabilities("aiand", DISCOVERY_BACKED_PROVIDER_SPECS.aiand, openAIModelDiscovery),
|
|
116
|
+
wafer: discoveryBackedCapabilities("wafer", DISCOVERY_BACKED_PROVIDER_SPECS.wafer, openAIModelDiscovery),
|
|
117
|
+
firepass: discoveryBackedCapabilities("firepass", DISCOVERY_BACKED_PROVIDER_SPECS.firepass, openAIModelDiscovery),
|
|
118
|
+
zhipucoding: discoveryBackedCapabilities("zhipucoding", DISCOVERY_BACKED_PROVIDER_SPECS.zhipucoding, openAIModelDiscovery),
|
|
119
|
+
dashscope: discoveryBackedCapabilities("dashscope", DISCOVERY_BACKED_PROVIDER_SPECS.dashscope, openAIModelDiscovery),
|
|
120
|
+
qianfan: discoveryBackedCapabilities("qianfan", DISCOVERY_BACKED_PROVIDER_SPECS.qianfan, openAIModelDiscovery),
|
|
121
|
+
};
|
|
122
|
+
}
|
|
@@ -1,135 +1,137 @@
|
|
|
1
|
-
import type { ApiKeyProviderSpec } from "./configured-provider";
|
|
2
|
-
import type { ProviderId } from "./provider-contracts";
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Builtin providers whose entire adapter contract is "bearer auth against the
|
|
6
|
-
* provider's `BUNDLED_PROVIDER_METADATA` base URL, OpenAI-compatible chat +
|
|
7
|
-
* responses, `/v1`-prefixed paths". They carry no catalog, no OAuth, and no
|
|
8
|
-
* provider-specific payload hook, so they share one spec shape rather than
|
|
9
|
-
* one module each.
|
|
10
|
-
*
|
|
11
|
-
* `base_url` is resolved per provider by `providerBaseUrl(provider_id)`.
|
|
12
|
-
*
|
|
13
|
-
* These providers list their models through live `/v1/models` discovery rather
|
|
14
|
-
* than a static catalog: every one of them republishes an aggregator's whole
|
|
15
|
-
* roster, which changes faster than a committed array can. Each registry row
|
|
16
|
-
* pairs this spec with `openAIModelDiscovery`.
|
|
17
|
-
*/
|
|
18
|
-
export const GENERIC_API_KEY_PROVIDER_IDS = [
|
|
19
|
-
"
|
|
20
|
-
"
|
|
21
|
-
"
|
|
22
|
-
"
|
|
23
|
-
"
|
|
24
|
-
"
|
|
25
|
-
"
|
|
26
|
-
"
|
|
27
|
-
"
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"
|
|
38
|
-
"
|
|
39
|
-
|
|
40
|
-
//
|
|
41
|
-
//
|
|
42
|
-
//
|
|
43
|
-
//
|
|
44
|
-
//
|
|
45
|
-
//
|
|
46
|
-
//
|
|
47
|
-
//
|
|
48
|
-
//
|
|
49
|
-
//
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
*
|
|
55
|
-
*
|
|
56
|
-
*
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
*
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
"
|
|
65
|
-
"
|
|
66
|
-
"
|
|
67
|
-
"
|
|
68
|
-
"
|
|
69
|
-
"
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
*
|
|
98
|
-
*
|
|
99
|
-
*
|
|
100
|
-
*
|
|
101
|
-
*
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
//
|
|
108
|
-
//
|
|
109
|
-
//
|
|
110
|
-
//
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
1
|
+
import type { ApiKeyProviderSpec } from "./configured-provider";
|
|
2
|
+
import type { ProviderId } from "./provider-contracts";
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Builtin providers whose entire adapter contract is "bearer auth against the
|
|
6
|
+
* provider's `BUNDLED_PROVIDER_METADATA` base URL, OpenAI-compatible chat +
|
|
7
|
+
* responses, `/v1`-prefixed paths". They carry no catalog, no OAuth, and no
|
|
8
|
+
* provider-specific payload hook, so they share one spec shape rather than
|
|
9
|
+
* one module each.
|
|
10
|
+
*
|
|
11
|
+
* `base_url` is resolved per provider by `providerBaseUrl(provider_id)`.
|
|
12
|
+
*
|
|
13
|
+
* These providers list their models through live `/v1/models` discovery rather
|
|
14
|
+
* than a static catalog: every one of them republishes an aggregator's whole
|
|
15
|
+
* roster, which changes faster than a committed array can. Each registry row
|
|
16
|
+
* pairs this spec with `openAIModelDiscovery`.
|
|
17
|
+
*/
|
|
18
|
+
export const GENERIC_API_KEY_PROVIDER_IDS = [
|
|
19
|
+
"larprouter",
|
|
20
|
+
"mistral",
|
|
21
|
+
"fireworks",
|
|
22
|
+
"nvidia",
|
|
23
|
+
"gmi",
|
|
24
|
+
"ollamacloud",
|
|
25
|
+
"together",
|
|
26
|
+
"siliconflow",
|
|
27
|
+
"siliconflowcn",
|
|
28
|
+
"nanogpt",
|
|
29
|
+
"baseten",
|
|
30
|
+
"synthetic",
|
|
31
|
+
"stepfun",
|
|
32
|
+
"sakana",
|
|
33
|
+
"helmcode",
|
|
34
|
+
"coralbricks",
|
|
35
|
+
"aiand",
|
|
36
|
+
"wafer",
|
|
37
|
+
"coreweave",
|
|
38
|
+
"qwen-portal",
|
|
39
|
+
"dashscope",
|
|
40
|
+
// `deepseek` is intentionally absent: it dispatches on the Anthropic Messages
|
|
41
|
+
// wire at its `/anthropic` root, not the OpenAI chat/responses wires, so it
|
|
42
|
+
// carries a dedicated entry in `default-registry.ts` instead.
|
|
43
|
+
//
|
|
44
|
+
// The aggregators below are absent for a different reason: their base URL is
|
|
45
|
+
// already rooted at a version segment that the `/v1`-prefixed path this shape
|
|
46
|
+
// pins would duplicate (`/openai/v1`, `/v1/openai`, `/v3/openai`, `/api/v1`,
|
|
47
|
+
// `/v2`, and `/inference/v1`), so `joinUrl` would produce
|
|
48
|
+
// `…/v1/v1/chat/completions`. They use `versionedRootApiKeySpec` instead,
|
|
49
|
+
// which pins the path below the version root — the same reason `cerebras`
|
|
50
|
+
// declares `/chat/completions` explicitly.
|
|
51
|
+
] as const;
|
|
52
|
+
|
|
53
|
+
/**
|
|
54
|
+
* Ids whose base URL already ends at a version segment.
|
|
55
|
+
*
|
|
56
|
+
* `joinUrl` is plain concatenation and nothing rewrites a declared path, so a
|
|
57
|
+
* base already rooted at a version plus a `/v1/…` path doubles the segment and
|
|
58
|
+
* every request 404s. These specs therefore declare the path *below* the
|
|
59
|
+
* version root. That is the provider stating the truth about its own wire, not
|
|
60
|
+
* a correction applied to it: a wrong path now reaches the operator as the
|
|
61
|
+
* wrong URL instead of being quietly rewritten into a different address.
|
|
62
|
+
*/
|
|
63
|
+
export const VERSIONED_ROOT_API_KEY_PROVIDER_IDS = [
|
|
64
|
+
"groq",
|
|
65
|
+
"deepinfra",
|
|
66
|
+
"novita",
|
|
67
|
+
"venice",
|
|
68
|
+
"qianfan",
|
|
69
|
+
"zhipucoding",
|
|
70
|
+
"firepass",
|
|
71
|
+
] as const;
|
|
72
|
+
|
|
73
|
+
export type VersionedRootApiKeyProviderId =
|
|
74
|
+
(typeof VERSIONED_ROOT_API_KEY_PROVIDER_IDS)[number];
|
|
75
|
+
|
|
76
|
+
function versionedRootApiKeySpec(providerId: ProviderId): ApiKeyProviderSpec {
|
|
77
|
+
return {
|
|
78
|
+
provider_id: providerId,
|
|
79
|
+
endpoint_paths_by_wire_family: {
|
|
80
|
+
chat: "/chat/completions",
|
|
81
|
+
responses: "/responses",
|
|
82
|
+
},
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
export const VERSIONED_ROOT_API_KEY_SPECS = {
|
|
87
|
+
groq: versionedRootApiKeySpec("groq"),
|
|
88
|
+
deepinfra: versionedRootApiKeySpec("deepinfra"),
|
|
89
|
+
novita: versionedRootApiKeySpec("novita"),
|
|
90
|
+
venice: versionedRootApiKeySpec("venice"),
|
|
91
|
+
qianfan: versionedRootApiKeySpec("qianfan"),
|
|
92
|
+
zhipucoding: versionedRootApiKeySpec("zhipucoding"),
|
|
93
|
+
firepass: versionedRootApiKeySpec("firepass"),
|
|
94
|
+
} satisfies Readonly<Record<VersionedRootApiKeyProviderId, ApiKeyProviderSpec>>;
|
|
95
|
+
|
|
96
|
+
/**
|
|
97
|
+
* One id that has both a generic spec and a registry row.
|
|
98
|
+
*
|
|
99
|
+
* Exported so the registry can be checked against the spec list rather than
|
|
100
|
+
* repeating the id as a string: `discoveryBackedProvider` takes this type, so a
|
|
101
|
+
* row naming a provider with no spec is a compile error instead of an
|
|
102
|
+
* `undefined` adapter at first dispatch.
|
|
103
|
+
*/
|
|
104
|
+
export type GenericApiKeyProviderId = (typeof GENERIC_API_KEY_PROVIDER_IDS)[number];
|
|
105
|
+
|
|
106
|
+
function genericApiKeySpec(providerId: GenericApiKeyProviderId): ApiKeyProviderSpec {
|
|
107
|
+
// These roots are *not* bare hosts — every one of them already ends at `/v1`
|
|
108
|
+
// — so the path is declared below that root. It used to be pinned from
|
|
109
|
+
// `BARE_ROOT_ENDPOINTS` and silently corrected at dispatch, which meant the
|
|
110
|
+
// declared path was wrong for all of them and nothing said so. Both spec
|
|
111
|
+
// shapes now declare the same thing, so this is the one implementation.
|
|
112
|
+
return versionedRootApiKeySpec(providerId);
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export const GENERIC_API_KEY_SPECS = {
|
|
116
|
+
larprouter: genericApiKeySpec("larprouter"),
|
|
117
|
+
mistral: genericApiKeySpec("mistral"),
|
|
118
|
+
fireworks: genericApiKeySpec("fireworks"),
|
|
119
|
+
nvidia: genericApiKeySpec("nvidia"),
|
|
120
|
+
gmi: genericApiKeySpec("gmi"),
|
|
121
|
+
ollamacloud: genericApiKeySpec("ollamacloud"),
|
|
122
|
+
together: genericApiKeySpec("together"),
|
|
123
|
+
siliconflow: genericApiKeySpec("siliconflow"),
|
|
124
|
+
siliconflowcn: genericApiKeySpec("siliconflowcn"),
|
|
125
|
+
nanogpt: genericApiKeySpec("nanogpt"),
|
|
126
|
+
baseten: genericApiKeySpec("baseten"),
|
|
127
|
+
synthetic: genericApiKeySpec("synthetic"),
|
|
128
|
+
stepfun: genericApiKeySpec("stepfun"),
|
|
129
|
+
sakana: genericApiKeySpec("sakana"),
|
|
130
|
+
helmcode: genericApiKeySpec("helmcode"),
|
|
131
|
+
coralbricks: genericApiKeySpec("coralbricks"),
|
|
132
|
+
aiand: genericApiKeySpec("aiand"),
|
|
133
|
+
wafer: genericApiKeySpec("wafer"),
|
|
134
|
+
coreweave: genericApiKeySpec("coreweave"),
|
|
135
|
+
dashscope: genericApiKeySpec("dashscope"),
|
|
136
|
+
"qwen-portal": genericApiKeySpec("qwen-portal"),
|
|
135
137
|
} satisfies Readonly<Record<GenericApiKeyProviderId, ApiKeyProviderSpec>>;
|
|
@@ -314,10 +314,7 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
314
314
|
loadAuthentication: oauthCapability(() => import("./integrations/cursor/cursor-auth"), "cursorOAuthClient", {
|
|
315
315
|
withRefresher: true,
|
|
316
316
|
}),
|
|
317
|
-
|
|
318
|
-
// or the API evidence, and inventing one would publish a balance this
|
|
319
|
-
// gateway cannot measure.
|
|
320
|
-
//
|
|
317
|
+
loadQuotaCollector: quotaCapability(() => import("./integrations/cursor/cursor-quota"), "fetchCursorQuota"),
|
|
321
318
|
// The roster is per-account and per-plan, and Cursor declares each model's
|
|
322
319
|
// capabilities, so discovery is the catalog rather than a static list.
|
|
323
320
|
loadModelDiscovery: async () => async ({ credential, fetcher }) =>
|
|
@@ -483,6 +480,7 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
483
480
|
// device flow, so the issued token is used exactly as issued until the
|
|
484
481
|
// operator re-runs login — same shape as Kilo Code.
|
|
485
482
|
loadAuthentication: oauthCapability(() => import("./integrations/qoder/qoder-oauth"), "qoderOAuthClient"),
|
|
483
|
+
loadQuotaCollector: quotaCapability(() => import("./integrations/qoder/qoder-quota"), "fetchQoderQuota"),
|
|
486
484
|
// Discovery signed by the account's own COSY identity: the model list is
|
|
487
485
|
// per-account and per-realm, and a GET without the signed body is 403.
|
|
488
486
|
loadModelDiscovery: qoderDiscovery("intl", "qoder"),
|
|
@@ -498,6 +496,7 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
498
496
|
// `QODER_REALMS.cn` — its own login/token/userinfo hosts, client id, and
|
|
499
497
|
// native redirect.
|
|
500
498
|
loadAuthentication: oauthCapability(() => import("./integrations/qoder/qoder-oauth"), "qoderCnOAuthClient"),
|
|
499
|
+
loadQuotaCollector: quotaCapability(() => import("./integrations/qoder/qoder-quota"), "fetchQoderCnQuota"),
|
|
501
500
|
loadModelDiscovery: qoderDiscovery("cn", "qodercn"),
|
|
502
501
|
},
|
|
503
502
|
trae: {
|
|
@@ -507,6 +506,7 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
507
506
|
// keeps it alive, so the refresher is registered rather than optional:
|
|
508
507
|
// without it the account dies at first expiry.
|
|
509
508
|
loadAuthentication: oauthCapability(() => import("./integrations/trae/trae-oauth"), "traeOAuthClient", { withRefresher: true }),
|
|
509
|
+
loadQuotaCollector: quotaCapability(() => import("./integrations/trae/trae-quota"), "fetchTraeQuota"),
|
|
510
510
|
// Live model list is intl-unsupported: upstream answers `403 no schema
|
|
511
511
|
// found`, so discovery returning nothing is the truthful result and the
|
|
512
512
|
// static roster above stays authoritative.
|
|
@@ -518,6 +518,7 @@ export const PROVIDER_CAPABILITIES = {
|
|
|
518
518
|
// The CN client, not the intl one: the exchange runs on the CN account
|
|
519
519
|
// host, and a refresh posted to the intl host is refused.
|
|
520
520
|
loadAuthentication: oauthCapability(() => import("./integrations/trae/trae-oauth"), "traeCnOAuthClient", { withRefresher: true }),
|
|
521
|
+
loadQuotaCollector: quotaCapability(() => import("./integrations/trae/trae-quota"), "fetchTraeCnQuota"),
|
|
521
522
|
loadModelDiscovery: traeDiscovery("cn", "traecn"),
|
|
522
523
|
},
|
|
523
524
|
inferhub: {
|
|
@@ -49,6 +49,11 @@ export async function fetchOpenAICompatibleModels(
|
|
|
49
49
|
const parsedContext =
|
|
50
50
|
positiveNumber(entry.context_length) ??
|
|
51
51
|
positiveNumber((entry as Record<string, unknown>).input_token_limit) ??
|
|
52
|
+
// `context_window` is the spelling an OpenAI-shaped catalog uses for
|
|
53
|
+
// its own field. Unread, every model on such an upstream fell to the
|
|
54
|
+
// 200_000 default below and was advertised at the same wrong window no
|
|
55
|
+
// matter what the upstream reported — a 1M model shown as 200k.
|
|
56
|
+
positiveNumber((entry as Record<string, unknown>).context_window) ??
|
|
52
57
|
positiveNumber(entry.contextWindow) ??
|
|
53
58
|
positiveNumber(entry.max_input_tokens) ??
|
|
54
59
|
modalityContextLimit(entry);
|