cartethyia 2.7.9 → 2.8.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.
- package/.env.example +3 -2
- package/dist/dashboard/assets/{BannedPage-BxoG1MrL.js → BannedPage-Cc0vKpMG.js} +1 -1
- package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-ixwgKk53.js → CliToolDetailPage-Bqj2aa1T.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-Bqj2aa1T.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-BmttNV3U.js → CliToolsPage-CXsaOAO2.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-CXsaOAO2.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-BE3qwwfC.js → CombosPage-BeLpJ4ma.js} +1 -1
- package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-CRZdmMIX.js → ConsoleLogPage-DnV0uZ3m.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-Dv_FJ6Er.js → CustomizationPage-CBxAjo63.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js.gz +0 -0
- package/dist/dashboard/assets/{InjectSystemPromptPanel-BOoO8rpz.js → InjectSystemPromptPanel-BWFLECmz.js} +2 -2
- package/dist/dashboard/assets/InjectSystemPromptPanel-BWFLECmz.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-ChJuNNVN.js → LoginPage-CgoPc5B9.js} +1 -1
- package/dist/dashboard/assets/LoginPage-CgoPc5B9.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-BZAJtPg1.js → ModelPicker-D9bFQern.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-D9bFQern.js.gz +0 -0
- package/dist/dashboard/assets/{OverviewPage-BE40s3u5.js → OverviewPage-B_p4tL8k.js} +1 -1
- package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js +8 -0
- package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js.gz +0 -0
- package/dist/dashboard/assets/{ProviderIcon-CQ6bPUf_.js → ProviderIcon-D_0PiZtg.js} +1 -1
- package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-BJ87Pp0U.js → ProxyPage-BwNC_-Cx.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js +1 -0
- package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js.gz +0 -0
- package/dist/dashboard/assets/{SettingsPage-C5HPWqEv.js → SettingsPage-CctTga2C.js} +1 -1
- package/dist/dashboard/assets/SettingsPage-CctTga2C.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-CFNcATJJ.js → SetupPage-febLU4r1.js} +1 -1
- package/dist/dashboard/assets/SetupPage-febLU4r1.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-YoD4tY5l.js → StudioPage-M6fvR5Wz.js} +1 -1
- package/dist/dashboard/assets/StudioPage-M6fvR5Wz.js.gz +0 -0
- package/dist/dashboard/assets/{UsagePage-DxjaAhb_.js → UsagePage-nyeuRqz9.js} +1 -1
- package/dist/dashboard/assets/UsagePage-nyeuRqz9.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-BTlkq_Uk.js → api-keys-BFOlvrJC.js} +1 -1
- package/dist/dashboard/assets/api-keys-BFOlvrJC.js.gz +0 -0
- package/dist/dashboard/assets/app-Dx2QgsNj.css +2 -0
- package/dist/dashboard/assets/app-Dx2QgsNj.css.gz +0 -0
- package/dist/dashboard/assets/assert-CqTLw5e7.js +1 -0
- package/dist/dashboard/assets/assert-CqTLw5e7.js.gz +0 -0
- package/dist/dashboard/assets/{badge-DdbT_7Am.js → badge-C83EqLB0.js} +1 -1
- package/dist/dashboard/assets/badge-C83EqLB0.js.gz +0 -0
- package/dist/dashboard/assets/{banner-CsGN-nbm.js → banner-D1xn7pIe.js} +1 -1
- package/dist/dashboard/assets/banner-D1xn7pIe.js.gz +0 -0
- package/dist/dashboard/assets/{card-mgZ_TLLZ.js → card-DU3Lq5Lm.js} +1 -1
- package/dist/dashboard/assets/card-DU3Lq5Lm.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-A1-v8-03.js → cli-tools-Dw1U_drK.js} +1 -1
- package/dist/dashboard/assets/cli-tools-Dw1U_drK.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-CJ4Zty89.js → clipboard-button-CEL5Sg_J.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-CEL5Sg_J.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-B5L2jPQ_.js → dialog-BjFR5UHy.js} +1 -1
- package/dist/dashboard/assets/dialog-BjFR5UHy.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-DkjUouAj.js → drawer-HvBW0AjI.js} +1 -1
- package/dist/dashboard/assets/drawer-HvBW0AjI.js.gz +0 -0
- package/dist/dashboard/assets/entry-BSu3gFlt.js +4 -0
- package/dist/dashboard/assets/entry-BSu3gFlt.js.gz +0 -0
- package/dist/dashboard/assets/{entry-B-LVLV6o.js → entry-CECVELyy.js} +1 -1
- package/dist/dashboard/assets/entry-CECVELyy.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CAhdYl3B.js → entry-DYYofQ7W.js} +1 -1
- package/dist/dashboard/assets/entry-DYYofQ7W.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-CrsdLVsn.js → formatters-DLW4i8zK.js} +1 -1
- package/dist/dashboard/assets/formatters-DLW4i8zK.js.gz +0 -0
- package/dist/dashboard/assets/{index-BU64Lqvp.js → index-1-fCqe64.js} +2 -2
- package/dist/dashboard/assets/index-1-fCqe64.js.gz +0 -0
- package/dist/dashboard/assets/{inline-B2aDLyyg.js → inline-DGvU2oLK.js} +1 -1
- package/dist/dashboard/assets/inline-DGvU2oLK.js.gz +0 -0
- package/dist/dashboard/assets/{input-BCVkdR9d.js → input-iNnO1X2K.js} +1 -1
- package/dist/dashboard/assets/input-iNnO1X2K.js.gz +0 -0
- package/dist/dashboard/assets/{layout-DNcAdMK-.js → layout-0q8UGypb.js} +1 -1
- package/dist/dashboard/assets/layout-0q8UGypb.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-DgrIH0hw.js → list-row-C0w2bQjJ.js} +1 -1
- package/dist/dashboard/assets/list-row-C0w2bQjJ.js.gz +0 -0
- package/dist/dashboard/assets/{live-Cae01iu8.js → live-M5aJ_xCa.js} +1 -1
- package/dist/dashboard/assets/live-M5aJ_xCa.js.gz +0 -0
- package/dist/dashboard/assets/{network-CRib7H_2.js → network-BKeQGT3K.js} +1 -1
- package/dist/dashboard/assets/network-BKeQGT3K.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-BKQE8Xpz.js → numbers-CivAk3da.js} +1 -1
- package/dist/dashboard/assets/numbers-CivAk3da.js.gz +0 -0
- package/dist/dashboard/assets/{pagination-ecPvG_8g.js → pagination-CpzvI5ep.js} +1 -1
- package/dist/dashboard/assets/pagination-CpzvI5ep.js.gz +0 -0
- package/dist/dashboard/assets/providers/zro.svg +3 -0
- package/dist/dashboard/assets/providers/zro.svg.gz +0 -0
- package/dist/dashboard/assets/quota-DiPD6UKH.js +1 -0
- package/dist/dashboard/assets/quota-DiPD6UKH.js.gz +0 -0
- package/dist/dashboard/assets/{routing-Ckm1UXuC.js → routing-BFQX2VBc.js} +1 -1
- package/dist/dashboard/assets/routing-BFQX2VBc.js.gz +0 -0
- package/dist/dashboard/assets/{select-ChoFWyKz.js → select-CXbck0jG.js} +2 -2
- package/dist/dashboard/assets/select-CXbck0jG.js.gz +0 -0
- package/dist/dashboard/assets/{settings-CKjFPlKW.js → settings-C_XvMHh9.js} +1 -1
- package/dist/dashboard/assets/settings-C_XvMHh9.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DWCwU3fh.js → stack-DggRiCxE.js} +1 -1
- package/dist/dashboard/assets/stack-DggRiCxE.js.gz +0 -0
- package/dist/dashboard/assets/{state-Cg3VL5J_.js → state-ClFzfbYp.js} +1 -1
- package/dist/dashboard/assets/state-ClFzfbYp.js.gz +0 -0
- package/dist/dashboard/assets/{switch-Db70BMix.js → switch-CTIFxKqS.js} +1 -1
- package/dist/dashboard/assets/switch-CTIFxKqS.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BqdE0LuM.js → useMutation-BClG3yWj.js} +1 -1
- package/dist/dashboard/assets/useMutation-BClG3yWj.js.gz +0 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +54 -53
- package/migrations/full-postgres/0046_add_accounts_quota_plan_fetched_at.sql +7 -0
- package/migrations/lite-sqlite3/0046_add_accounts_quota_plan_fetched_at.sql +4 -0
- package/package.json +1 -1
- package/src/boot/app.ts +10 -13
- package/src/boot/dependencies.ts +1 -1
- package/src/boot/flush.ts +20 -0
- package/src/boot/lifecycle.ts +7 -5
- package/src/config/routing.ts +26 -0
- package/src/config/spec-metadata.ts +72 -0
- package/src/config/spec.ts +20 -0
- package/src/console/api-keys/contracts.ts +12 -1
- package/src/console/api-keys/routes.ts +40 -28
- package/src/console/auth/account-reset.ts +7 -9
- package/src/console/backup/contracts.ts +4 -0
- package/src/console/backup/export-endpoint.ts +7 -5
- package/src/console/cli-tools/service.ts +6 -12
- package/src/console/console-router-guards.ts +23 -16
- package/src/console/domain-registration.ts +0 -2
- package/src/console/inferhub/normalize.ts +24 -28
- package/src/console/inferhub/types.ts +3 -0
- package/src/console/ip-bans/routes.ts +7 -13
- package/src/console/observability/store.ts +0 -53
- package/src/console/providers/catalog/contracts.ts +2 -2
- package/src/console/providers/catalog/discover-constants.ts +6 -0
- package/src/console/providers/catalog/routes.ts +1 -0
- package/src/console/providers/catalog/store.ts +21 -16
- package/src/console/quota/account-quota-global.ts +14 -24
- package/src/console/quota/account-quota-shared.ts +49 -0
- package/src/console/quota/account-quota-tenant.ts +6 -18
- package/src/console/quota/quota-view.ts +19 -3
- package/src/console/routing/pools/operations.ts +31 -46
- package/src/console/shared/errors.ts +33 -6
- package/src/main.ts +2 -3
- package/src/network/pool/byte-accounting.ts +3 -2
- package/src/network/pool/selector.ts +182 -39
- package/src/network/pool-cooldown-store.ts +89 -14
- package/src/network/pool-health.ts +49 -61
- package/src/network/rate-limit-verdict.ts +1 -1
- package/src/network/ssrf.ts +6 -6
- package/src/observability/event-log.ts +7 -361
- package/src/observability/performance-metrics.ts +9 -0
- package/src/observability/runtime-metrics.ts +14 -9
- package/src/observability/telemetry-buffer.ts +15 -25
- package/src/observability/telemetry-reconciliation.ts +9 -37
- package/src/observability/telemetry-row.ts +125 -0
- package/src/persistence/db-mode.ts +4 -1
- package/src/persistence/dialect.ts +18 -0
- package/src/persistence/migrate.ts +6 -3
- package/src/persistence/schema.ts +8 -0
- package/src/persistence/ttl-cache.ts +20 -2
- package/src/protocol/codecs.ts +1 -1
- package/src/protocol/dsml.ts +34 -86
- package/src/protocol/markup-stream-parser.ts +195 -0
- package/src/protocol/reasoning-text.ts +19 -0
- package/src/protocol/request/chat.ts +10 -10
- package/src/protocol/request/gemini.ts +8 -2
- package/src/protocol/request/messages.ts +3 -4
- package/src/protocol/response/chat.ts +12 -20
- package/src/protocol/response/omp-tool-call-markup.ts +43 -86
- package/src/protocol/response/responses.ts +18 -2
- package/src/protocol/stop-reason.ts +23 -1
- package/src/protocol/think-split.ts +112 -0
- package/src/protocol/translation/dialect/qwen.ts +26 -58
- package/src/providers/adapters/compatible-adapter.ts +71 -12
- package/src/providers/authentication/oauth-client.ts +1 -1
- package/src/providers/authentication/oauth-device-flow.ts +98 -8
- package/src/providers/authentication/oauth-refresh-service.ts +30 -49
- package/src/providers/configured-provider.ts +148 -0
- package/src/providers/default-registry.ts +61 -36
- package/src/providers/discovery/probe-phases.ts +14 -4
- package/src/providers/discovery/probing-service.ts +15 -2
- package/src/providers/integrations/alibabacp/alibabacp-models.ts +1 -2
- package/src/providers/integrations/{dashscope-models.ts → alibabacp/dashscope-models.ts} +2 -2
- package/src/providers/integrations/antigravity/antigravity-protocol.ts +5 -1
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +173 -17
- package/src/providers/integrations/buddy/buddy-identity.ts +19 -6
- package/src/providers/integrations/buddy/capabilities.ts +2 -2
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +3 -0
- package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -0
- package/src/providers/integrations/buddy/codebuddy/shared.ts +37 -22
- package/src/providers/integrations/claude/claude-quota.ts +14 -17
- package/src/providers/integrations/cline/cline.ts +2 -2
- package/src/providers/integrations/commandcode/quota.ts +22 -28
- package/src/providers/integrations/cursor/cursor-auth.ts +0 -8
- package/src/providers/integrations/cursor/cursor-exec.ts +9 -2
- package/src/providers/integrations/cursor/cursor-request.ts +26 -12
- package/src/providers/integrations/cursor/cursor-shared.ts +7 -4
- package/src/providers/integrations/cursor/cursor.ts +89 -40
- package/src/providers/integrations/cursor/protocol/messages.ts +22 -29
- package/src/providers/integrations/cursor/protocol/protobuf-schema.ts +37 -0
- package/src/providers/integrations/devin/protocol/devin-proto.ts +1 -27
- package/src/providers/integrations/factory/factory-oauth.ts +17 -44
- package/src/providers/integrations/freebuff/assets/official-system-manager.txt +88 -0
- package/src/providers/integrations/freebuff/assets/official-system-worker.txt +57 -0
- package/src/providers/integrations/freebuff/assets/official-tools.json +1070 -0
- package/src/providers/integrations/freebuff/freebuff-catalog.ts +120 -0
- package/src/providers/integrations/freebuff/freebuff-constants.ts +1233 -0
- package/src/providers/integrations/freebuff/freebuff-discovery.ts +108 -0
- package/src/providers/integrations/freebuff/freebuff-oauth.ts +240 -0
- package/src/providers/integrations/freebuff/freebuff-quota.ts +260 -0
- package/src/providers/integrations/freebuff/freebuff-virtual.ts +89 -0
- package/src/providers/integrations/freebuff/freebuff.ts +682 -0
- package/src/providers/integrations/grok/grok-oauth.ts +48 -45
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +10 -17
- package/src/providers/integrations/grok/grok-turn-index.ts +11 -16
- package/src/providers/integrations/{hermes.ts → hermes/hermes.ts} +9 -9
- package/src/providers/integrations/hermes/index.ts +2 -0
- package/src/providers/integrations/kiro/kiro-catalog.ts +17 -1
- package/src/providers/integrations/kiro/kiro-discovery.ts +10 -12
- package/src/providers/integrations/kiro/kiro-quota.ts +8 -4
- package/src/providers/integrations/kiro/kiro.ts +15 -19
- package/src/providers/integrations/ollamacloud/index.ts +2 -0
- package/src/providers/integrations/{ollamacloud-models.ts → ollamacloud/models.ts} +2 -2
- package/src/providers/integrations/{ollamacloud-quota.ts → ollamacloud/quota.ts} +3 -3
- package/src/providers/integrations/opencode/opencode-go-quota.ts +2 -8
- package/src/providers/integrations/perch/perch-credential.ts +25 -0
- package/src/providers/integrations/perch/perch-protocol.ts +0 -3
- package/src/providers/integrations/perch/perch-quota.ts +2 -16
- package/src/providers/integrations/perch/perch.ts +3 -13
- package/src/providers/integrations/qoder/claim-qoder-credits.ts +18 -59
- package/src/providers/integrations/qoder/qoder-adapter.ts +1 -12
- package/src/providers/integrations/qoder/qoder-auth.ts +101 -29
- package/src/providers/integrations/qoder/qoder-catalog.ts +20 -5
- package/src/providers/integrations/qoder/qoder-chat.ts +7 -21
- package/src/providers/integrations/qoder/qoder-checkin.ts +4 -4
- package/src/providers/integrations/qoder/qoder-grpc.ts +0 -1
- package/src/providers/integrations/qoder/qoder-ide.ts +0 -107
- package/src/providers/integrations/qoder/qoder.ts +0 -1
- package/src/providers/integrations/trae/trae-protocol.ts +9 -5
- package/src/providers/integrations/trae/trae-quota.ts +6 -28
- package/src/providers/integrations/trae/trae-realm.ts +38 -0
- package/src/providers/integrations/trae/trae.ts +7 -24
- package/src/providers/integrations/zcode-start-plan/provider.ts +226 -23
- package/src/providers/integrations/zcode-start-plan/quota.ts +19 -2
- package/src/providers/integrations/zro/zro.ts +204 -0
- package/src/providers/operations/account-error-classification.ts +199 -307
- package/src/providers/operations/account-health-service.ts +82 -1
- package/src/providers/operations/account-refresh-status.ts +22 -37
- package/src/providers/operations/account-tier.ts +15 -16
- package/src/providers/operations/client-version-resolver.ts +1 -1
- package/src/providers/operations/client-versions.ts +5 -51
- package/src/providers/operations/cooldown-rules.ts +11 -16
- package/src/providers/operations/{model-catalog-cache.ts → provider-caches.ts} +68 -16
- package/src/providers/operations/provider-catalog-service.ts +1 -1
- package/src/providers/operations/provider-credential-service.ts +102 -32
- package/src/providers/operations/provider-rules/github.ts +48 -0
- package/src/providers/operations/provider-rules/grok.ts +33 -0
- package/src/providers/operations/provider-rules/inception.ts +49 -0
- package/src/providers/operations/provider-rules/index.ts +32 -0
- package/src/providers/operations/provider-rules/perch.ts +37 -0
- package/src/providers/operations/provider-rules/qoder.ts +70 -0
- package/src/providers/operations/provider-rules/trae.ts +81 -0
- package/src/providers/provider-contracts.ts +4 -2
- package/src/providers/{provider-credential-resolver.ts → provider-credentials.ts} +40 -3
- package/src/providers/provider-metadata.ts +40 -10
- package/src/providers/provider-probe.ts +15 -1
- package/src/providers/provider-registry.ts +42 -33
- package/src/providers/quota/quota-limit-windows.ts +16 -5
- package/src/providers/quota/quota-support.ts +1 -1
- package/src/providers/quota/quota-window-parser.ts +90 -18
- package/src/providers/quota/refresh.ts +75 -18
- package/src/security/api-key-auth-cache.ts +1 -1
- package/src/security/api-key-auth.ts +6 -2
- package/src/transport/dispatch/attempt-finalize.ts +14 -13
- package/src/transport/dispatch/attempt-loop.ts +71 -17
- package/src/transport/dispatch/generation.ts +2 -8
- package/src/transport/dispatch/native-shared.ts +25 -0
- package/src/transport/dispatch/proxy-request.ts +8 -46
- package/src/transport/dispatch/responses-compact.ts +2 -8
- package/src/transport/dispatch/streaming/finalize.ts +9 -6
- package/src/transport/dispatch/streaming/stream.ts +8 -36
- package/src/transport/dispatch/systemone.ts +2 -8
- package/src/transport/dispatch/token-count.ts +2 -6
- package/src/transport/dispatch/upstream.ts +63 -0
- package/src/transport/drain-endpoint.ts +31 -4
- package/src/transport/failure-policy.ts +16 -30
- package/src/transport/guards/body-policy.ts +7 -1
- package/src/transport/guards/error-lifecycle.ts +13 -1
- package/src/transport/guards/request-context.ts +22 -14
- package/src/transport/request/preparer.ts +81 -71
- package/src/transport/routing/bounded-lru.ts +14 -0
- package/src/transport/routing/drain-reserve.ts +129 -0
- package/src/transport/routing/plan-gate.ts +7 -1
- package/src/transport/routing/round-robin.ts +60 -0
- package/src/transport/routing/route-catalog.ts +123 -111
- package/src/transport/routing/route-model.ts +51 -9
- package/src/transport/routing/router.ts +393 -32
- package/src/transport/surface/adapters.ts +11 -2
- package/src/transport/surface/chat/adapter.ts +2 -2
- package/src/transport/surface/chat/encode.ts +47 -4
- package/src/transport/surface/chat/parse.ts +2 -12
- package/src/transport/surface/completion.ts +44 -33
- package/src/transport/surface/content-parts.ts +21 -0
- package/src/transport/surface/messages/adapter.ts +7 -1
- package/src/transport/surface/messages/encode.ts +11 -3
- package/src/transport/surface/messages/parse.ts +2 -1
- package/src/transport/surface/messages/stream.ts +33 -17
- package/src/transport/surface/responses/encode.ts +22 -5
- package/src/transport/surface/responses/parse.ts +3 -11
- package/dist/dashboard/assets/BannedPage-BxoG1MrL.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-ixwgKk53.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-BmttNV3U.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-BE3qwwfC.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-CRZdmMIX.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-Dv_FJ6Er.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-CoVrw2sM.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-CoVrw2sM.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-BOoO8rpz.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-ChJuNNVN.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BZAJtPg1.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-BE40s3u5.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-sfLoQtPV.js +0 -8
- package/dist/dashboard/assets/ProviderDetailPage-sfLoQtPV.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-CQ6bPUf_.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-DcepmPWo.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-DcepmPWo.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-BJ87Pp0U.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-gkSyRAKa.js +0 -1
- package/dist/dashboard/assets/QuotaPage-gkSyRAKa.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-C5HPWqEv.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-CFNcATJJ.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-YoD4tY5l.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-DxjaAhb_.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-BTlkq_Uk.js.gz +0 -0
- package/dist/dashboard/assets/app-BX2nnKqs.css +0 -2
- package/dist/dashboard/assets/app-BX2nnKqs.css.gz +0 -0
- package/dist/dashboard/assets/assert-CndthXFQ.js +0 -1
- package/dist/dashboard/assets/assert-CndthXFQ.js.gz +0 -0
- package/dist/dashboard/assets/badge-DdbT_7Am.js.gz +0 -0
- package/dist/dashboard/assets/banner-CsGN-nbm.js.gz +0 -0
- package/dist/dashboard/assets/card-mgZ_TLLZ.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-A1-v8-03.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-CJ4Zty89.js.gz +0 -0
- package/dist/dashboard/assets/dialog-B5L2jPQ_.js.gz +0 -0
- package/dist/dashboard/assets/drawer-DkjUouAj.js.gz +0 -0
- package/dist/dashboard/assets/entry-B-LVLV6o.js.gz +0 -0
- package/dist/dashboard/assets/entry-CAhdYl3B.js.gz +0 -0
- package/dist/dashboard/assets/entry-D2xD0Tmd.js +0 -4
- package/dist/dashboard/assets/entry-D2xD0Tmd.js.gz +0 -0
- package/dist/dashboard/assets/formatters-CrsdLVsn.js.gz +0 -0
- package/dist/dashboard/assets/index-BU64Lqvp.js.gz +0 -0
- package/dist/dashboard/assets/inline-B2aDLyyg.js.gz +0 -0
- package/dist/dashboard/assets/input-BCVkdR9d.js.gz +0 -0
- package/dist/dashboard/assets/layout-DNcAdMK-.js.gz +0 -0
- package/dist/dashboard/assets/list-row-DgrIH0hw.js.gz +0 -0
- package/dist/dashboard/assets/live-Cae01iu8.js.gz +0 -0
- package/dist/dashboard/assets/network-CRib7H_2.js.gz +0 -0
- package/dist/dashboard/assets/numbers-BKQE8Xpz.js.gz +0 -0
- package/dist/dashboard/assets/pagination-ecPvG_8g.js.gz +0 -0
- package/dist/dashboard/assets/quota-DJ1QlAOq.js +0 -1
- package/dist/dashboard/assets/quota-DJ1QlAOq.js.gz +0 -0
- package/dist/dashboard/assets/routing-Ckm1UXuC.js.gz +0 -0
- package/dist/dashboard/assets/select-ChoFWyKz.js.gz +0 -0
- package/dist/dashboard/assets/settings-CKjFPlKW.js.gz +0 -0
- package/dist/dashboard/assets/stack-DWCwU3fh.js.gz +0 -0
- package/dist/dashboard/assets/state-Cg3VL5J_.js.gz +0 -0
- package/dist/dashboard/assets/switch-Db70BMix.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BqdE0LuM.js.gz +0 -0
- package/src/providers/bundled-discovery-providers.ts +0 -98
- package/src/providers/configured-openai-providers.ts +0 -120
- package/src/providers/operations/model-discovery-cache.ts +0 -34
- package/src/providers/operations/probe-fetch.ts +0 -15
- package/src/providers/operations/provider-version-cache.ts +0 -30
- package/src/providers/provider-capabilities.ts +0 -33
- package/src/providers/provider-credential-envelope.ts +0 -43
- /package/dist/dashboard/assets/{app-B7kIWFm5.js → app-DIXLjojg.js} +0 -0
- /package/dist/dashboard/assets/{app-B7kIWFm5.js.gz → app-DIXLjojg.js.gz} +0 -0
|
@@ -1,13 +1,14 @@
|
|
|
1
1
|
/** xAI Grok Build device-code OAuth client. */
|
|
2
|
-
import { devicePollBackoff, nonEmptyTrimmedString, parseDeviceAuthStart, postFormTokenRequest, readJsonResponse } from "../../authentication/oauth-flow-store";
|
|
2
|
+
import { devicePollBackoff, nonEmptyTrimmedString, parseDeviceAuthStart, postFormTokenRequest, readJsonResponse, record } from "../../authentication/oauth-flow-store";
|
|
3
3
|
import type {
|
|
4
4
|
OAuthDeviceFlowContext,
|
|
5
5
|
OAuthDevicePollResult,
|
|
6
6
|
OAuthDeviceStartResult,
|
|
7
|
+
OAuthExchangeResult,
|
|
7
8
|
} from "../../authentication/oauth-flow-store";
|
|
8
9
|
import type { OAuthTokenRefreshResult } from "../../authentication/oauth-refresh-service";
|
|
9
10
|
import { OAuthDeviceFlow } from "../../authentication/oauth-device-flow";
|
|
10
|
-
import type { FetchLike } from "../../authentication/oauth-client";
|
|
11
|
+
import type { FetchLike, NormalizedTokenResponse } from "../../authentication/oauth-client";
|
|
11
12
|
import { XAI_AUTH_SERVER } from "../xai/xai-oauth";
|
|
12
13
|
|
|
13
14
|
/**
|
|
@@ -178,56 +179,58 @@ export class GrokOAuthClient extends OAuthDeviceFlow {
|
|
|
178
179
|
}
|
|
179
180
|
|
|
180
181
|
override async pollDeviceAuth(deviceAuthId: string, _context?: OAuthDeviceFlowContext): Promise<OAuthDevicePollResult> {
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
const response = await this.fetchFn(GROK_TOKEN_URL, {
|
|
187
|
-
method: "POST",
|
|
188
|
-
headers: authHeaders(),
|
|
189
|
-
body,
|
|
182
|
+
return this.pollGenericDeviceAuth(deviceAuthId, {
|
|
183
|
+
tokenUrl: GROK_TOKEN_URL,
|
|
184
|
+
deviceAuthUrl: GROK_DEVICE_URL,
|
|
185
|
+
clientId: GROK_CLIENT_ID,
|
|
186
|
+
formHeaders: authHeaders(),
|
|
190
187
|
});
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
const
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
protected override unparsablePollReason(_status: number): string {
|
|
191
|
+
return "grok token endpoint returned invalid JSON";
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
protected override preVerdict(payload: unknown): OAuthDevicePollResult | undefined {
|
|
195
|
+
const root = record(payload) ?? {};
|
|
196
|
+
// Grok votes on the `error` field before the status: a 200 body can still
|
|
197
|
+
// state the poll state, and a pending/slow_down answer is honored wherever
|
|
198
|
+
// it appears on the wire.
|
|
199
|
+
return devicePollBackoff(nonEmptyTrimmedString(root.error), root.interval);
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
protected override pollFailureReason(
|
|
203
|
+
status: number,
|
|
204
|
+
errorKey: string | undefined,
|
|
205
|
+
errorDescription: string | undefined,
|
|
206
|
+
): string {
|
|
207
|
+
// Grok's wire prefers the human-readable description over the error code,
|
|
208
|
+
// and falls back to the generic phrasing only when both are absent.
|
|
209
|
+
return nonEmptyTrimmedString(errorDescription) ?? nonEmptyTrimmedString(errorKey) ?? `token polling failed (${status})`;
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
protected override missingTokenReason(errorKey: string | undefined, errorDescription: string | undefined): string {
|
|
204
213
|
// A 2xx is not by itself a completed authorization: the endpoint can answer
|
|
205
214
|
// 200 with an `error` field and no token. Returning `failed` rather than
|
|
206
215
|
// letting the shared parser throw keeps the verdict inside the poll
|
|
207
216
|
// contract — the dashboard's poll error path stops polling but shows no
|
|
208
217
|
// reason, so a throw would look like a spinner that never ends.
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
}
|
|
218
|
-
const result = this.parseTokenResponse(payload);
|
|
219
|
-
const identity = await fetchGrokIdentity(result.access, this.fetchFn);
|
|
218
|
+
return nonEmptyTrimmedString(errorDescription) ?? nonEmptyTrimmedString(errorKey) ?? "grok token response omitted access_token";
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
protected override async afterDeviceTokenExchange(
|
|
222
|
+
_payload: unknown,
|
|
223
|
+
normalized: NormalizedTokenResponse,
|
|
224
|
+
): Promise<OAuthExchangeResult> {
|
|
225
|
+
const identity = await fetchGrokIdentity(normalized.access, this.fetchFn);
|
|
220
226
|
const authState = grokAuthState(identity);
|
|
221
|
-
return {
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
...(authState === undefined ? {} : { auth_state: authState }),
|
|
229
|
-
}),
|
|
230
|
-
};
|
|
227
|
+
return this.toExchangeResult({
|
|
228
|
+
...normalized,
|
|
229
|
+
...(identity.label === undefined ? {} : { accountLabel: identity.label }),
|
|
230
|
+
// Omitted when the proxy reported nothing, which leaves any stored
|
|
231
|
+
// state alone rather than blanking it.
|
|
232
|
+
...(authState === undefined ? {} : { auth_state: authState }),
|
|
233
|
+
});
|
|
231
234
|
}
|
|
232
235
|
|
|
233
236
|
override async refresh(refreshToken: string, signal?: AbortSignal): Promise<OAuthTokenRefreshResult> {
|
|
@@ -12,6 +12,7 @@
|
|
|
12
12
|
// Keyed by account id: two Grok accounts carry different buckets, and a reading
|
|
13
13
|
// filed against the wrong one is worse than no reading at all.
|
|
14
14
|
|
|
15
|
+
import { TtlCache } from "../../../persistence/ttl-cache";
|
|
15
16
|
import type { ProviderQuotaWindow } from "../../quota/quota-contracts";
|
|
16
17
|
import { grokHeaderRequestsWindow, grokHeaderWindow, type GrokRateLimitReading } from "./grok-ratelimit";
|
|
17
18
|
|
|
@@ -27,39 +28,31 @@ const SNAPSHOT_TTL_MS = 5 * 60 * 1000;
|
|
|
27
28
|
|
|
28
29
|
interface Snapshot {
|
|
29
30
|
readonly windows: readonly ProviderQuotaWindow[];
|
|
30
|
-
readonly capturedAt: number;
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
-
|
|
33
|
+
// Bounded FIFO cache keyed by account id; the TTL and `maxEntries` cap are
|
|
34
|
+
// enforced by the cache itself (oldest-first eviction past 4096 entries).
|
|
35
|
+
const snapshots = new TtlCache<Snapshot>({
|
|
36
|
+
ttlMs: SNAPSHOT_TTL_MS,
|
|
37
|
+
maxEntries: 4096,
|
|
38
|
+
});
|
|
34
39
|
|
|
35
40
|
/** Files a reading captured from a real dispatch against one account. */
|
|
36
41
|
export function rememberGrokRateLimit(
|
|
37
42
|
accountId: string,
|
|
38
43
|
reading: GrokRateLimitReading,
|
|
39
|
-
now = Date.now(),
|
|
40
44
|
): void {
|
|
41
45
|
const windows = [grokHeaderWindow(reading), grokHeaderRequestsWindow(reading)].filter(
|
|
42
46
|
(value): value is ProviderQuotaWindow => value !== null,
|
|
43
47
|
);
|
|
44
48
|
if (windows.length === 0) return;
|
|
45
|
-
snapshots.set(accountId, { windows
|
|
46
|
-
if (snapshots.size > 4096) {
|
|
47
|
-
// Bounded: an unbounded map keyed by account is a leak dressed as a cache.
|
|
48
|
-
for (const [key, value] of snapshots) {
|
|
49
|
-
if (now - value.capturedAt > SNAPSHOT_TTL_MS) snapshots.delete(key);
|
|
50
|
-
}
|
|
51
|
-
}
|
|
49
|
+
snapshots.set(accountId, { windows });
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
/** The stored window for one account, or `null` when none is fresh enough. */
|
|
55
|
-
export function storedGrokRateLimit(accountId: string
|
|
53
|
+
export function storedGrokRateLimit(accountId: string): readonly ProviderQuotaWindow[] | null {
|
|
56
54
|
const snapshot = snapshots.get(accountId);
|
|
57
|
-
|
|
58
|
-
if (now - snapshot.capturedAt > SNAPSHOT_TTL_MS) {
|
|
59
|
-
snapshots.delete(accountId);
|
|
60
|
-
return null;
|
|
61
|
-
}
|
|
62
|
-
return snapshot.windows;
|
|
55
|
+
return snapshot?.windows ?? null;
|
|
63
56
|
}
|
|
64
57
|
|
|
65
58
|
/** Test seam. */
|
|
@@ -13,19 +13,25 @@
|
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
15
|
import type { CanonicalRequest } from "../../../protocol/canonical-model";
|
|
16
|
+
import { TtlCache } from "../../../persistence/ttl-cache";
|
|
16
17
|
|
|
17
18
|
/** Idle window after which a session's remembered index is discarded. */
|
|
18
19
|
const SESSION_TTL_MS = 30 * 60_000;
|
|
19
20
|
|
|
20
|
-
/** Bound on remembered sessions;
|
|
21
|
+
/** Bound on remembered sessions; least-recently-used is evicted past this. */
|
|
21
22
|
const MAX_SESSIONS = 5_000;
|
|
22
23
|
|
|
23
24
|
interface TurnEntry {
|
|
24
25
|
readonly turn: number;
|
|
25
|
-
lastUsedAt: number;
|
|
26
26
|
}
|
|
27
27
|
|
|
28
|
-
|
|
28
|
+
// Bounded, LRU-ordered: a session re-inserts on every use so the newest
|
|
29
|
+
// session is the last evicted, exactly as the previous delete-then-set Map.
|
|
30
|
+
const turns = new TtlCache<TurnEntry>({
|
|
31
|
+
ttlMs: SESSION_TTL_MS,
|
|
32
|
+
maxEntries: MAX_SESSIONS,
|
|
33
|
+
lru: true,
|
|
34
|
+
});
|
|
29
35
|
const requestTurns = new WeakMap<object, number>();
|
|
30
36
|
|
|
31
37
|
/** User turns in the request, floored at 1 (a turn is never index 0). */
|
|
@@ -58,25 +64,14 @@ export function resolveGrokTurnIndex(
|
|
|
58
64
|
}
|
|
59
65
|
if (sessionId === undefined || sessionId.length === 0) return fromInput;
|
|
60
66
|
|
|
61
|
-
const
|
|
62
|
-
const previous = turns.get(sessionId);
|
|
63
|
-
const remembered =
|
|
64
|
-
previous !== undefined && now - previous.lastUsedAt <= SESSION_TTL_MS
|
|
65
|
-
? previous.turn
|
|
66
|
-
: undefined;
|
|
67
|
+
const remembered = turns.get(sessionId)?.turn;
|
|
67
68
|
|
|
68
69
|
// A full-history client already reports the true index; a delta-style client
|
|
69
70
|
// reports 1 every time, so the stored index is advanced by one for it.
|
|
70
71
|
const turn = remembered === undefined ? fromInput : Math.max(fromInput, remembered + 1);
|
|
71
72
|
|
|
72
73
|
// Re-insert so the entry is newest for eviction order.
|
|
73
|
-
turns.
|
|
74
|
-
if (turns.size >= MAX_SESSIONS) {
|
|
75
|
-
const oldest = turns.keys().next();
|
|
76
|
-
if (!oldest.done) turns.delete(oldest.value);
|
|
77
|
-
}
|
|
78
|
-
turns.set(sessionId, { turn, lastUsedAt: now });
|
|
74
|
+
turns.set(sessionId, { turn });
|
|
79
75
|
if (requestKey !== undefined) requestTurns.set(requestKey, turn);
|
|
80
76
|
return turn;
|
|
81
77
|
}
|
|
82
|
-
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { CanonicalRequest } from "
|
|
2
|
-
import type { ProviderDispatchTarget } from "
|
|
3
|
-
import type { ApiKeyProviderSpec } from "
|
|
4
|
-
import { isRecord } from "
|
|
5
|
-
import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "
|
|
6
|
-
import { getHermesVersion } from "
|
|
7
|
-
import { clineReasoningReplayPrepares } from "
|
|
1
|
+
import type { CanonicalRequest } from "../../../protocol/canonical-model";
|
|
2
|
+
import type { ProviderDispatchTarget } from "../../provider-contracts";
|
|
3
|
+
import type { ApiKeyProviderSpec } from "../../configured-provider";
|
|
4
|
+
import { isRecord } from "../../../protocol/codecs";
|
|
5
|
+
import { boundedUpstreamArray, boundedUpstreamNumber, sanitizeUpstreamLabel } from "../../provider-sanitize";
|
|
6
|
+
import { getHermesVersion } from "../../operations/client-versions";
|
|
7
|
+
import { clineReasoningReplayPrepares } from "../buddy/buddy-chat-shared";
|
|
8
8
|
|
|
9
9
|
const HERMES_PROVIDER_ID = "hermes" as const;
|
|
10
10
|
|
|
@@ -57,8 +57,8 @@ function injectHermesTags(
|
|
|
57
57
|
|
|
58
58
|
|
|
59
59
|
|
|
60
|
-
import { defineModel } from "
|
|
61
|
-
import type { ModelDefinition } from "
|
|
60
|
+
import { defineModel } from "../../provider-model-definition";
|
|
61
|
+
import type { ModelDefinition } from "../../provider-model-definition";
|
|
62
62
|
|
|
63
63
|
/**
|
|
64
64
|
* Offline fallback: the free rows as the live catalog last reported them.
|
|
@@ -15,6 +15,22 @@ export const KIRO_GENERATE_PATH = "/generateAssistantResponse" as const;
|
|
|
15
15
|
/** AWS region shape, checked before a region is interpolated into a URL. */
|
|
16
16
|
export const AWS_REGION_PATTERN = /^[a-z]{2}-[a-z]+-\d{1,2}$/;
|
|
17
17
|
|
|
18
|
+
/**
|
|
19
|
+
* Maps an auth method onto the `TokenType` header the 1.4.62 client sends.
|
|
20
|
+
*
|
|
21
|
+
* Observed map (`qje`): `api_key → API_KEY`, `external_idp → EXTERNAL_IDP`,
|
|
22
|
+
* `idc → SSO_OIDC`, `machine_token → KIRO_MACHINE_TOKEN`. Google/GitHub/
|
|
23
|
+
* Builder-ID sessions send no `TokenType` header. Every surface (dispatch,
|
|
24
|
+
* usage, discovery) must classify the same account identically or the upstream
|
|
25
|
+
* sees one credential as different token types across surfaces.
|
|
26
|
+
*/
|
|
27
|
+
export function kiroTokenTypeHeader(authMethod: string | undefined): string | undefined {
|
|
28
|
+
if (authMethod === "api_key") return "API_KEY";
|
|
29
|
+
if (authMethod === "external_idp") return "EXTERNAL_IDP";
|
|
30
|
+
if (authMethod === "idc") return "SSO_OIDC";
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
|
|
18
34
|
/** Fallback region when no (or an invalid) region is configured. */
|
|
19
35
|
export const KIRO_DEFAULT_REGION = "us-east-1" as const;
|
|
20
36
|
|
|
@@ -37,7 +53,7 @@ export const KIRO_MANAGEMENT_HOST_TEMPLATE = "https://management.{region}.kiro.d
|
|
|
37
53
|
* The upstream has no `minimal` or `max` tier on either schema, so the ladder
|
|
38
54
|
* stops at `xhigh` and the builder maps the canonical extremes onto it.
|
|
39
55
|
*/
|
|
40
|
-
const KIRO_EFFORTS = ["low", "medium", "high", "xhigh"] as const;
|
|
56
|
+
export const KIRO_EFFORTS = ["low", "medium", "high", "xhigh"] as const;
|
|
41
57
|
|
|
42
58
|
/**
|
|
43
59
|
* One Kiro model row.
|
|
@@ -22,14 +22,19 @@ import {
|
|
|
22
22
|
} from "../../operations/client-versions";
|
|
23
23
|
import { machineIdForAuthState } from "./kiro-machine-id";
|
|
24
24
|
import { resolveKiroProfileArn } from "./kiro-profile";
|
|
25
|
-
import {
|
|
25
|
+
import {
|
|
26
|
+
AWS_REGION_PATTERN,
|
|
27
|
+
KIRO_DEFAULT_REGION,
|
|
28
|
+
KIRO_EFFORTS,
|
|
29
|
+
KIRO_GENERATE_PATH,
|
|
30
|
+
KIRO_MODELS,
|
|
31
|
+
KIRO_MANAGEMENT_HOST_TEMPLATE,
|
|
32
|
+
kiroTokenTypeHeader,
|
|
33
|
+
} from "./kiro-catalog";
|
|
26
34
|
|
|
27
35
|
/** Longest model list this will read; the upstream sends a few dozen at most. */
|
|
28
36
|
const MAX_DISCOVERED_MODELS = 500;
|
|
29
37
|
|
|
30
|
-
/** Effort tiers the models that accept an effort field advertise. */
|
|
31
|
-
const KIRO_EFFORTS = ["low", "medium", "high", "xhigh"] as const;
|
|
32
|
-
|
|
33
38
|
/** The management service target used in `x-amz-target`. */
|
|
34
39
|
const KIRO_MANAGEMENT_TARGET = "KiroControlPlaneBearerService.ListAvailableModels" as const;
|
|
35
40
|
|
|
@@ -105,14 +110,7 @@ export async function fetchKiroModels(
|
|
|
105
110
|
// `TokenType`; social/Builder-ID sessions send none. Mirror the client's
|
|
106
111
|
// `qje` map and the probe verified against the live service.
|
|
107
112
|
const authMethod = options.authState?.["authMethod"];
|
|
108
|
-
const tokenType =
|
|
109
|
-
authMethod === "api_key"
|
|
110
|
-
? "API_KEY"
|
|
111
|
-
: authMethod === "external_idp"
|
|
112
|
-
? "EXTERNAL_IDP"
|
|
113
|
-
: authMethod === "idc"
|
|
114
|
-
? "SSO_OIDC"
|
|
115
|
-
: undefined;
|
|
113
|
+
const tokenType = kiroTokenTypeHeader(typeof authMethod === "string" ? authMethod : undefined);
|
|
116
114
|
if (tokenType !== undefined) headers["TokenType"] = tokenType;
|
|
117
115
|
response = await fetcher(`${host}/List-Available-Models?${params.toString()}`, {
|
|
118
116
|
headers,
|
|
@@ -34,7 +34,12 @@ import {
|
|
|
34
34
|
} from "../../operations/client-versions";
|
|
35
35
|
import { machineIdForAuthState } from "./kiro-machine-id";
|
|
36
36
|
import { resolveKiroProfileArn } from "./kiro-profile";
|
|
37
|
-
import {
|
|
37
|
+
import {
|
|
38
|
+
AWS_REGION_PATTERN,
|
|
39
|
+
KIRO_DEFAULT_REGION,
|
|
40
|
+
KIRO_MANAGEMENT_HOST_TEMPLATE,
|
|
41
|
+
kiroTokenTypeHeader,
|
|
42
|
+
} from "./kiro-catalog";
|
|
38
43
|
|
|
39
44
|
/**
|
|
40
45
|
* The fetcher shape this module needs: a plain callable. `FetchLike` from the
|
|
@@ -82,9 +87,8 @@ function usageHeaders(credential: string, auth: KiroQuotaAuth): Record<string, s
|
|
|
82
87
|
"user-agent": buildKiroRuntimeUserAgent(version, auth.machineId),
|
|
83
88
|
"x-kiro-machineid": auth.machineId,
|
|
84
89
|
};
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
else if (auth.authMethod === "idc") headers["TokenType"] = "SSO_OIDC";
|
|
90
|
+
const tokenType = kiroTokenTypeHeader(auth.authMethod);
|
|
91
|
+
if (tokenType !== undefined) headers["TokenType"] = tokenType;
|
|
88
92
|
return headers;
|
|
89
93
|
}
|
|
90
94
|
|
|
@@ -59,6 +59,7 @@ import {
|
|
|
59
59
|
kiroContextWindow,
|
|
60
60
|
KIRO_GENERATE_PATH,
|
|
61
61
|
KIRO_RUNTIME_HOST_TEMPLATE,
|
|
62
|
+
kiroTokenTypeHeader,
|
|
62
63
|
} from "./kiro-catalog";
|
|
63
64
|
import { resolveInboundSessionId } from "../../operations/session-resolution";
|
|
64
65
|
import { KiroStreamDecoder, isKiroTruncationReason, type KiroUsage } from "./kiro-stream";
|
|
@@ -180,19 +181,6 @@ export function kiroEndpoint(authState: KiroAuthState | undefined): string {
|
|
|
180
181
|
*/
|
|
181
182
|
export const KIRO_RUNTIME_AWS_JSON_TARGET = "KiroRuntimeService.GenerateAssistantResponse" as const;
|
|
182
183
|
|
|
183
|
-
/**
|
|
184
|
-
* Maps an auth method onto the `TokenType` header the 1.4.62 client sends.
|
|
185
|
-
*
|
|
186
|
-
* Observed map (`qje`): `api_key → API_KEY`, `external_idp → EXTERNAL_IDP`,
|
|
187
|
-
* `idc → SSO_OIDC`, `machine_token → KIRO_MACHINE_TOKEN`. Google/GitHub/
|
|
188
|
-
* Builder-ID sessions send no `TokenType` header.
|
|
189
|
-
*/
|
|
190
|
-
const KIRO_TOKEN_TYPE: Readonly<Record<string, string>> = {
|
|
191
|
-
api_key: "API_KEY",
|
|
192
|
-
external_idp: "EXTERNAL_IDP",
|
|
193
|
-
idc: "SSO_OIDC",
|
|
194
|
-
};
|
|
195
|
-
|
|
196
184
|
/**
|
|
197
185
|
* Builds the request headers.
|
|
198
186
|
*
|
|
@@ -230,7 +218,7 @@ export function kiroHeaders(
|
|
|
230
218
|
"x-amz-user-agent": buildKiroAmzUserAgent(version, machineId),
|
|
231
219
|
authorization: `Bearer ${secret}`,
|
|
232
220
|
};
|
|
233
|
-
const tokenType = authMethod
|
|
221
|
+
const tokenType = kiroTokenTypeHeader(authMethod);
|
|
234
222
|
if (tokenType !== undefined) {
|
|
235
223
|
headers["TokenType"] = tokenType;
|
|
236
224
|
}
|
|
@@ -377,9 +365,17 @@ class KiroAdapter implements ProviderAdapter {
|
|
|
377
365
|
effortPath !== undefined
|
|
378
366
|
? undefined
|
|
379
367
|
: (request.reasoning?.budget_tokens ?? kiroThinkingBudgetForEffort(requestedEffort));
|
|
368
|
+
// One resolution per dispatch: the resolver mints a fresh UUID only when
|
|
369
|
+
// the request carries no session, conversation id, or derivable opening
|
|
370
|
+
// turn, so resolving twice here would give `conversationId` and
|
|
371
|
+
// `rootConversationId` two different UUIDs — contradicting the client rule
|
|
372
|
+
// (`rootConversationId ?? conversationId`). The same id feeds the session
|
|
373
|
+
// cache estimator at stream end, so its key matches what the request
|
|
374
|
+
// presented upstream.
|
|
375
|
+
const conversationId = resolveKiroConversationId(request, context);
|
|
380
376
|
const built = buildKiroWireRequest(request, {
|
|
381
|
-
conversationId
|
|
382
|
-
rootConversationId:
|
|
377
|
+
conversationId,
|
|
378
|
+
rootConversationId: conversationId,
|
|
383
379
|
modelId,
|
|
384
380
|
profileArn: resolveProfileArn(context),
|
|
385
381
|
...(effortPath === undefined || effort === undefined ? {} : { effortPath, effort }),
|
|
@@ -414,7 +410,7 @@ class KiroAdapter implements ProviderAdapter {
|
|
|
414
410
|
}, "upstream");
|
|
415
411
|
}
|
|
416
412
|
|
|
417
|
-
yield* this.#stream(response.body, built.value, request,
|
|
413
|
+
yield* this.#stream(response.body, built.value, request, conversationId);
|
|
418
414
|
}
|
|
419
415
|
|
|
420
416
|
/**
|
|
@@ -471,7 +467,7 @@ class KiroAdapter implements ProviderAdapter {
|
|
|
471
467
|
stream: ReadableStream<Uint8Array>,
|
|
472
468
|
built: KiroWireRequest,
|
|
473
469
|
request: CanonicalRequest,
|
|
474
|
-
|
|
470
|
+
conversationId: string,
|
|
475
471
|
): AsyncIterable<CanonicalEvent> {
|
|
476
472
|
const decoder = new KiroStreamDecoder();
|
|
477
473
|
const reader = stream.getReader();
|
|
@@ -605,7 +601,7 @@ class KiroAdapter implements ProviderAdapter {
|
|
|
605
601
|
reader.releaseLock();
|
|
606
602
|
}
|
|
607
603
|
|
|
608
|
-
const finalUsage = kiroUsage(usage, request.model, outputText, request.messages,
|
|
604
|
+
const finalUsage = kiroUsage(usage, request.model, outputText, request.messages, conversationId);
|
|
609
605
|
yield {
|
|
610
606
|
type: "usage",
|
|
611
607
|
sequence_number: sequence++,
|
|
@@ -16,8 +16,8 @@
|
|
|
16
16
|
* All six serve the chat wire (none is a Responses-native id), and all report
|
|
17
17
|
* `supported_in_api: true` on the live roster.
|
|
18
18
|
*/
|
|
19
|
-
import { defineModel } from "
|
|
20
|
-
import type { ModelDefinition } from "
|
|
19
|
+
import { defineModel } from "../../provider-model-definition";
|
|
20
|
+
import type { ModelDefinition } from "../../provider-model-definition";
|
|
21
21
|
|
|
22
22
|
export const OLLAMACLOUD_PROVIDER_ID = "ollamacloud" as const;
|
|
23
23
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { FetchLike, ProviderQuotaResult } from "
|
|
2
|
-
import { getJson, record, text } from "
|
|
3
|
-
import { parseQuotaWindows } from "
|
|
1
|
+
import type { FetchLike, ProviderQuotaResult } from "../../quota/quota-contracts";
|
|
2
|
+
import { getJson, record, text } from "../../quota/quota-contracts";
|
|
3
|
+
import { parseQuotaWindows } from "../../quota/quota-window-parser";
|
|
4
4
|
|
|
5
5
|
async function fetchPlan(fetcher: FetchLike, headers: Record<string, string>): Promise<string> {
|
|
6
6
|
try {
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
getJson,
|
|
3
|
+
isoDate,
|
|
3
4
|
type FetchLike,
|
|
4
5
|
type ProviderQuotaResult,
|
|
5
6
|
type ProviderQuotaWindow,
|
|
@@ -42,13 +43,6 @@ function labelFor(kind: string): string {
|
|
|
42
43
|
return kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
43
44
|
}
|
|
44
45
|
|
|
45
|
-
function resetIso(value: string | null | undefined): string | null {
|
|
46
|
-
if (typeof value !== "string" || value.trim() === "") return null;
|
|
47
|
-
const parsed = Date.parse(value);
|
|
48
|
-
if (!Number.isFinite(parsed)) return null;
|
|
49
|
-
return new Date(parsed).toISOString();
|
|
50
|
-
}
|
|
51
|
-
|
|
52
46
|
/**
|
|
53
47
|
* One window, or `undefined` when the upstream omitted what makes it usable.
|
|
54
48
|
*
|
|
@@ -75,7 +69,7 @@ function windowFor(
|
|
|
75
69
|
accounting: "independent",
|
|
76
70
|
usedPercent: percent,
|
|
77
71
|
remainingPercent: 100 - percent,
|
|
78
|
-
resetsAt:
|
|
72
|
+
resetsAt: isoDate(raw.resetsAt),
|
|
79
73
|
};
|
|
80
74
|
}
|
|
81
75
|
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
// Perch credential-envelope parsing.
|
|
2
|
+
//
|
|
3
|
+
// Perch accounts authenticate via Supabase OAuth (PKCE), and the stored secret
|
|
4
|
+
// is the OAuth envelope JSON with `accessToken` (or `access_token`). Both the
|
|
5
|
+
// dispatch adapter and the quota collector need the access token out of that
|
|
6
|
+
// envelope; the parse is shared here and each surface keeps its own fallback
|
|
7
|
+
// for a secret that is not an envelope.
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* Reads the access token out of a stored Perch OAuth envelope.
|
|
11
|
+
*
|
|
12
|
+
* Returns the token when the secret parses as JSON and carries `accessToken`
|
|
13
|
+
* (or `access_token`) as a string; `null` when it is not such an envelope
|
|
14
|
+
* (not JSON, or JSON without a token field). The caller decides what a
|
|
15
|
+
* `null` means for its surface.
|
|
16
|
+
*/
|
|
17
|
+
export function parsePerchCredentialToken(secret: string): string | null {
|
|
18
|
+
try {
|
|
19
|
+
const parsed = JSON.parse(secret) as Record<string, unknown>;
|
|
20
|
+
const found = parsed["accessToken"] ?? parsed["access_token"];
|
|
21
|
+
return typeof found === "string" ? found : null;
|
|
22
|
+
} catch {
|
|
23
|
+
return null;
|
|
24
|
+
}
|
|
25
|
+
}
|
|
@@ -27,9 +27,6 @@ import { PERCH_STARTER_PINS } from "./perch-realm";
|
|
|
27
27
|
/** Default hosted model id when the account endpoint is unreachable. */
|
|
28
28
|
export const PERCH_DEFAULT_CHAT_MODEL = "wandb-kimi-k2-6";
|
|
29
29
|
|
|
30
|
-
/** App origin (model-call + ticket + account + plan endpoints). */
|
|
31
|
-
export const PERCH_APP_URL = "https://app.perchai.app";
|
|
32
|
-
|
|
33
30
|
/** The CLI user-agent the upstream recognizes as a CLI surface. */
|
|
34
31
|
export const PERCH_CLI_USER_AGENT = "perchai-cli/unknown";
|
|
35
32
|
|
|
@@ -11,21 +11,7 @@ import type { FetchLike, ProviderQuotaResult, ProviderQuotaWindow } from "../../
|
|
|
11
11
|
import { cleanError, percentWindow, text } from "../../quota/quota-contracts";
|
|
12
12
|
import type { QuotaCollectionContext } from "../../quota/quota-support";
|
|
13
13
|
import { PERCH_APP_URL } from "./perch-realm";
|
|
14
|
-
|
|
15
|
-
interface PerchSessionCredential {
|
|
16
|
-
readonly accessToken?: string;
|
|
17
|
-
readonly access_token?: string;
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
function credentialToken(credential: string): string {
|
|
21
|
-
try {
|
|
22
|
-
const parsed = JSON.parse(credential) as PerchSessionCredential;
|
|
23
|
-
const found = parsed.accessToken ?? parsed.access_token;
|
|
24
|
-
return typeof found === "string" ? found : "";
|
|
25
|
-
} catch {
|
|
26
|
-
return credential.trim();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
14
|
+
import { parsePerchCredentialToken } from "./perch-credential";
|
|
29
15
|
|
|
30
16
|
async function readAccount(
|
|
31
17
|
baseUrl: string,
|
|
@@ -61,7 +47,7 @@ export async function fetchPerchQuota(
|
|
|
61
47
|
_context?: QuotaCollectionContext,
|
|
62
48
|
): Promise<ProviderQuotaResult> {
|
|
63
49
|
try {
|
|
64
|
-
const token =
|
|
50
|
+
const token = parsePerchCredentialToken(credential) ?? "";
|
|
65
51
|
const account = await readAccount(PERCH_APP_URL, token, fetcher);
|
|
66
52
|
if (!account) {
|
|
67
53
|
return { source: "perch", plan: null, windows: [], error: "Perch account endpoint unavailable" };
|
|
@@ -28,7 +28,6 @@ import {
|
|
|
28
28
|
} from "../../provider-contracts";
|
|
29
29
|
import { usageFromProvider } from "../../provider-usage";
|
|
30
30
|
import {
|
|
31
|
-
PERCH_APP_URL,
|
|
32
31
|
PERCH_CLI_USER_AGENT,
|
|
33
32
|
PERCH_SAFFRON_SYSTEM_PROMPT,
|
|
34
33
|
buildPerchModelCallBody,
|
|
@@ -39,7 +38,8 @@ import {
|
|
|
39
38
|
PERCH_MODEL_PINS,
|
|
40
39
|
PERCH_MODEL_ROOST_TIERS,
|
|
41
40
|
} from "./perch-catalog";
|
|
42
|
-
import { PERCH_PROVIDER_ID } from "./perch-realm";
|
|
41
|
+
import { PERCH_APP_URL, PERCH_PROVIDER_ID } from "./perch-realm";
|
|
42
|
+
import { parsePerchCredentialToken } from "./perch-credential";
|
|
43
43
|
|
|
44
44
|
interface PerchAdapterOptions {
|
|
45
45
|
readonly providerId?: string;
|
|
@@ -126,7 +126,7 @@ export class PerchAdapter implements ProviderAdapter {
|
|
|
126
126
|
}
|
|
127
127
|
const secret = readCredentialSecret(context.credential, "Perch credential is required");
|
|
128
128
|
const modelId = candidate.model_id || request.model || "standard";
|
|
129
|
-
const access =
|
|
129
|
+
const access = parsePerchCredentialToken(secret) ?? secret.trim();
|
|
130
130
|
// Probes pass a validated outbound fetch (with capture wrapped around it);
|
|
131
131
|
// live dispatch passes one too. `globalThis.fetch` here silently split the
|
|
132
132
|
// probe from the route's egress policy and left Request Detail empty.
|
|
@@ -281,16 +281,6 @@ function normalizePerchUsage(usage: Record<string, unknown>): Record<string, unk
|
|
|
281
281
|
return out;
|
|
282
282
|
}
|
|
283
283
|
|
|
284
|
-
function parseAccessToken(secret: string): string {
|
|
285
|
-
try {
|
|
286
|
-
const parsed = JSON.parse(secret) as Record<string, unknown>;
|
|
287
|
-
const found = parsed["accessToken"] ?? parsed["access_token"];
|
|
288
|
-
return typeof found === "string" ? found : secret.trim();
|
|
289
|
-
} catch {
|
|
290
|
-
return secret.trim();
|
|
291
|
-
}
|
|
292
|
-
}
|
|
293
|
-
|
|
294
284
|
/**
|
|
295
285
|
* Builds an upstream verdict for the Perch surface. `origin: "upstream"` is
|
|
296
286
|
* what lets the account health machine see the failure: `attempt-finalize`
|