cartethyia 2.8.0 → 2.8.1
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 -3
- package/dist/dashboard/assets/{BannedPage-Cc0vKpMG.js → BannedPage-Dq530awD.js} +1 -1
- package/dist/dashboard/assets/BannedPage-Dq530awD.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-Bqj2aa1T.js → CliToolDetailPage-DZzaS-7S.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-DZzaS-7S.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-CXsaOAO2.js → CliToolsPage-DaZZ3cqP.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-DaZZ3cqP.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-BeLpJ4ma.js → CombosPage-BlC_xdkX.js} +1 -1
- package/dist/dashboard/assets/CombosPage-BlC_xdkX.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-DnV0uZ3m.js → ConsoleLogPage-D-rqeVtG.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-D-rqeVtG.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-CBxAjo63.js → CustomizationPage-7xT5yg2E.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-7xT5yg2E.js.gz +0 -0
- package/dist/dashboard/assets/{HealthEventsModal-B5yEE0k6.js → HealthEventsModal-Clq8E9cW.js} +1 -1
- package/dist/dashboard/assets/HealthEventsModal-Clq8E9cW.js.gz +0 -0
- package/dist/dashboard/assets/{InjectSystemPromptPanel-BWFLECmz.js → InjectSystemPromptPanel-6Teoq9Se.js} +1 -1
- package/dist/dashboard/assets/InjectSystemPromptPanel-6Teoq9Se.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-CgoPc5B9.js → LoginPage-CZuI0MAR.js} +1 -1
- package/dist/dashboard/assets/LoginPage-CZuI0MAR.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-D9bFQern.js → ModelPicker-C1hNTlkr.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-C1hNTlkr.js.gz +0 -0
- package/dist/dashboard/assets/{OverviewPage-B_p4tL8k.js → OverviewPage-0yfhSI1C.js} +1 -1
- package/dist/dashboard/assets/OverviewPage-0yfhSI1C.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-xqTxdQ4c.js +8 -0
- package/dist/dashboard/assets/ProviderDetailPage-xqTxdQ4c.js.gz +0 -0
- package/dist/dashboard/assets/{ProviderIcon-D_0PiZtg.js → ProviderIcon-Ddhm1InL.js} +1 -1
- package/dist/dashboard/assets/ProviderIcon-Ddhm1InL.js.gz +0 -0
- package/dist/dashboard/assets/{ProvidersPage-CLI2bJTK.js → ProvidersPage-C3fYuu6i.js} +1 -1
- package/dist/dashboard/assets/ProvidersPage-C3fYuu6i.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-CHtJtZ3u.js +9 -0
- package/dist/dashboard/assets/ProxyPage-CHtJtZ3u.js.gz +0 -0
- package/dist/dashboard/assets/{QuotaPage-DA-a1iSN.js → QuotaPage-D1RV_2BX.js} +1 -1
- package/dist/dashboard/assets/QuotaPage-D1RV_2BX.js.gz +0 -0
- package/dist/dashboard/assets/{SettingsPage-CctTga2C.js → SettingsPage-BzZAvYSX.js} +1 -1
- package/dist/dashboard/assets/SettingsPage-BzZAvYSX.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-febLU4r1.js → SetupPage--s-EfEIL.js} +1 -1
- package/dist/dashboard/assets/SetupPage--s-EfEIL.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-M6fvR5Wz.js → StudioPage-BjXFGSK4.js} +1 -1
- package/dist/dashboard/assets/StudioPage-BjXFGSK4.js.gz +0 -0
- package/dist/dashboard/assets/{UsagePage-nyeuRqz9.js → UsagePage-CP8F8BN7.js} +1 -1
- package/dist/dashboard/assets/UsagePage-CP8F8BN7.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-BFOlvrJC.js → api-keys-2hc12Uz2.js} +1 -1
- package/dist/dashboard/assets/api-keys-2hc12Uz2.js.gz +0 -0
- package/dist/dashboard/assets/app-DGXbNfAR.css +2 -0
- package/dist/dashboard/assets/app-DGXbNfAR.css.gz +0 -0
- package/dist/dashboard/assets/{assert-CqTLw5e7.js → assert-BMcj1xZE.js} +1 -1
- package/dist/dashboard/assets/assert-BMcj1xZE.js.gz +0 -0
- package/dist/dashboard/assets/{badge-C83EqLB0.js → badge-DkRUuVfz.js} +1 -1
- package/dist/dashboard/assets/badge-DkRUuVfz.js.gz +0 -0
- package/dist/dashboard/assets/{banner-D1xn7pIe.js → banner-CDjW841Q.js} +1 -1
- package/dist/dashboard/assets/banner-CDjW841Q.js.gz +0 -0
- package/dist/dashboard/assets/{card-DU3Lq5Lm.js → card-Bto5UlL9.js} +1 -1
- package/dist/dashboard/assets/card-Bto5UlL9.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-Dw1U_drK.js → cli-tools-DaH6g9hL.js} +1 -1
- package/dist/dashboard/assets/cli-tools-DaH6g9hL.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-CEL5Sg_J.js → clipboard-button-BYKBCzjk.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-BYKBCzjk.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-BjFR5UHy.js → dialog-DL0Zftwv.js} +1 -1
- package/dist/dashboard/assets/dialog-DL0Zftwv.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-HvBW0AjI.js → drawer-Dpx_UXaS.js} +1 -1
- package/dist/dashboard/assets/drawer-Dpx_UXaS.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CECVELyy.js → entry-BV7-1NoM.js} +1 -1
- package/dist/dashboard/assets/entry-BV7-1NoM.js.gz +0 -0
- package/dist/dashboard/assets/{entry-DYYofQ7W.js → entry-CGvdNU6r.js} +1 -1
- package/dist/dashboard/assets/entry-CGvdNU6r.js.gz +0 -0
- package/dist/dashboard/assets/{entry-BSu3gFlt.js → entry-DScKYvZj.js} +3 -3
- package/dist/dashboard/assets/entry-DScKYvZj.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-DLW4i8zK.js → formatters-BS3DZlZj.js} +1 -1
- package/dist/dashboard/assets/formatters-BS3DZlZj.js.gz +0 -0
- package/dist/dashboard/assets/{index-1-fCqe64.js → index-SQnvvTWX.js} +2 -2
- package/dist/dashboard/assets/index-SQnvvTWX.js.gz +0 -0
- package/dist/dashboard/assets/{inline-DGvU2oLK.js → inline-Dl-cuLK0.js} +1 -1
- package/dist/dashboard/assets/inline-Dl-cuLK0.js.gz +0 -0
- package/dist/dashboard/assets/{input-iNnO1X2K.js → input-Bfx0EzRc.js} +1 -1
- package/dist/dashboard/assets/input-Bfx0EzRc.js.gz +0 -0
- package/dist/dashboard/assets/{layout-0q8UGypb.js → layout-BxhbQ_JS.js} +1 -1
- package/dist/dashboard/assets/layout-BxhbQ_JS.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-C0w2bQjJ.js → list-row-D49Y4ptn.js} +1 -1
- package/dist/dashboard/assets/list-row-D49Y4ptn.js.gz +0 -0
- package/dist/dashboard/assets/{live-M5aJ_xCa.js → live-CbVTdX9V.js} +1 -1
- package/dist/dashboard/assets/live-CbVTdX9V.js.gz +0 -0
- package/dist/dashboard/assets/{network-BKeQGT3K.js → network-JGvDveof.js} +1 -1
- package/dist/dashboard/assets/network-JGvDveof.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-CivAk3da.js → numbers-Dw6kiew-.js} +1 -1
- package/dist/dashboard/assets/numbers-Dw6kiew-.js.gz +0 -0
- package/dist/dashboard/assets/{pagination-CpzvI5ep.js → pagination-iUoI8GeE.js} +1 -1
- package/dist/dashboard/assets/pagination-iUoI8GeE.js.gz +0 -0
- package/dist/dashboard/assets/providers/sensenova-intl.png +0 -0
- package/dist/dashboard/assets/providers/sensenova.png +0 -0
- package/dist/dashboard/assets/{routing-BFQX2VBc.js → routing-8jZr-3WE.js} +1 -1
- package/dist/dashboard/assets/routing-8jZr-3WE.js.gz +0 -0
- package/dist/dashboard/assets/{select-CXbck0jG.js → select-oO1FxMVb.js} +1 -1
- package/dist/dashboard/assets/select-oO1FxMVb.js.gz +0 -0
- package/dist/dashboard/assets/{settings-C_XvMHh9.js → settings-CLr3kdIx.js} +1 -1
- package/dist/dashboard/assets/settings-CLr3kdIx.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DggRiCxE.js → stack-Y3pDteZr.js} +1 -1
- package/dist/dashboard/assets/stack-Y3pDteZr.js.gz +0 -0
- package/dist/dashboard/assets/{state-ClFzfbYp.js → state-CArX_Iak.js} +1 -1
- package/dist/dashboard/assets/state-CArX_Iak.js.gz +0 -0
- package/dist/dashboard/assets/{switch-CTIFxKqS.js → switch-DwlwmDO-.js} +1 -1
- package/dist/dashboard/assets/switch-DwlwmDO-.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BClG3yWj.js → useMutation-DJ9GYEgf.js} +1 -1
- package/dist/dashboard/assets/useMutation-DJ9GYEgf.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 +51 -51
- package/migrations/full-postgres/0047_add_provider_device_flow_proxy.sql +17 -0
- package/migrations/lite-sqlite3/0047_add_provider_device_flow_proxy.sql +19 -0
- package/package.json +1 -1
- package/src/boot/app.ts +1 -1
- package/src/boot/dependencies.ts +4 -6
- package/src/config/providers.ts +6 -5
- package/src/config/spec.ts +8 -8
- package/src/console/backup/nine-router.ts +71 -10
- package/src/console/backup/service.ts +8 -1
- package/src/console/console-router.ts +1 -1
- package/src/console/domain-registration.ts +7 -2
- package/src/console/inferhub/client.ts +1 -1
- package/src/console/observability/live.ts +2 -2
- package/src/console/providers/catalog/contracts.ts +9 -3
- package/src/console/providers/catalog/model-operations.ts +2 -3
- package/src/console/providers/catalog/provider-operations.ts +1 -1
- package/src/console/providers/catalog/routes.ts +2 -2
- package/src/console/providers/catalog/store.ts +1914 -1907
- package/src/console/providers/detail/routes.ts +1 -0
- package/src/console/providers/detail/store.ts +4 -0
- package/src/console/providers/oauth/callback-listener.ts +30 -11
- package/src/console/providers/oauth/device-egress.ts +123 -0
- package/src/console/providers/oauth/routes.ts +123 -16
- package/src/console/quota/account-quota-tenant.ts +5 -5
- package/src/console/quota/account-test-egress.ts +2 -2
- package/src/console/quota/daily-growth-job.ts +1 -1
- package/src/console/routing/pools/contracts.ts +1 -1
- package/src/console/routing/pools/operations.ts +1 -1
- package/src/console/routing/pools/probe-verdict.ts +2 -2
- package/src/console/routing/pools/relay-deploy.ts +1 -1
- package/src/console/routing/pools/store.ts +4 -4
- package/src/network/client.ts +67 -0
- package/src/network/egress/bidi-session.ts +322 -0
- package/src/network/egress/dial.ts +201 -0
- package/src/network/egress/factory.ts +191 -0
- package/src/network/{outbound-fetch.ts → egress/fetch.ts} +195 -29
- package/src/network/egress/tls-profile.ts +123 -0
- package/src/network/egress/ws.ts +175 -0
- package/src/network/{types.ts → pool/agent-config.ts} +1 -1
- package/src/network/pool/agent.ts +2 -2
- package/src/network/{pool-cooldown-store.ts → pool/cooldown-store.ts} +7 -7
- package/src/network/{pool-health-machine.ts → pool/health.ts} +205 -6
- package/src/network/pool/resolver.ts +10 -849
- package/src/network/pool/selector.ts +2 -2
- package/src/network/ssrf.ts +1 -1
- package/src/network/{retry.ts → util/retry.ts} +1 -1
- package/src/observability/telemetry-buffer.ts +1 -1
- package/src/persistence/schema.ts +9 -0
- package/src/persistence/ttl-cache.ts +1 -1
- package/src/protocol/codecs.ts +58 -1
- package/src/protocol/request/messages.ts +31 -18
- package/src/protocol/response/messages.ts +34 -7
- package/src/protocol/translation/quirks.ts +15 -0
- package/src/protocol/upstream/send-claude-messages.ts +2 -2
- package/src/providers/adapters/compatible-adapter.ts +5 -0
- package/src/providers/authentication/oauth-client.ts +40 -6
- package/src/providers/authentication/oauth-device-flow.ts +7 -3
- package/src/providers/authentication/oauth-flow-store.ts +82 -1
- package/src/providers/authentication/oauth-refresh-service.ts +766 -739
- package/src/providers/default-registry.ts +76 -0
- package/src/providers/discovery/discovery-types.ts +7 -0
- package/src/providers/discovery/probe-phases.ts +6 -2
- package/src/providers/discovery/probing-service.ts +7 -0
- package/src/providers/integrations/antigravity/antigravity-protocol.ts +11 -0
- package/src/providers/integrations/buddy/account.ts +969 -0
- package/src/providers/integrations/buddy/capabilities.ts +10 -10
- package/src/providers/integrations/buddy/{buddy-catalog-shared.ts → catalog.ts} +198 -136
- package/src/providers/integrations/buddy/{buddy-chat-shared.ts → chat.ts} +5 -5
- package/src/providers/integrations/buddy/codebuddy/index.ts +429 -0
- package/src/providers/integrations/buddy/codebuddy/shared.ts +4 -4
- package/src/providers/integrations/buddy/{buddy-identity.ts → headers.ts} +138 -140
- package/src/providers/integrations/buddy/lifecycle.ts +1018 -0
- package/src/providers/integrations/buddy/{buddy-media.ts → media.ts} +1 -1
- package/src/providers/integrations/cline/cline-oauth.ts +10 -5
- package/src/providers/integrations/cline/cline.ts +3 -4
- package/src/providers/integrations/clixad/clixad-oauth.ts +98 -0
- package/src/providers/integrations/clixad/clixad-quota.ts +132 -0
- package/src/providers/integrations/clixad/provider.ts +145 -0
- package/src/providers/integrations/codex/codex-oauth.ts +8 -5
- package/src/providers/integrations/cursor/cursor-auth.ts +1 -1
- package/src/providers/integrations/cursor/cursor-hardening.ts +279 -0
- package/src/providers/integrations/cursor/cursor-http2.ts +605 -6
- package/src/providers/integrations/cursor/cursor-shared.ts +1 -1
- package/src/providers/integrations/cursor/cursor.ts +485 -70
- package/src/providers/integrations/deepai/deepai-catalog.ts +149 -0
- package/src/providers/integrations/deepai/deepai-common.ts +145 -0
- package/src/providers/integrations/deepai/deepai-oauth.ts +129 -0
- package/src/providers/integrations/deepai/deepai-quota.ts +97 -0
- package/src/providers/integrations/deepai/provider.ts +42 -0
- package/src/providers/integrations/devin/devin-auth.ts +7 -0
- package/src/providers/integrations/factory/factory-oauth.ts +16 -7
- package/src/providers/integrations/freebuff/freebuff.ts +2 -2
- package/src/providers/integrations/freepi/freepi-catalog.ts +5 -0
- package/src/providers/integrations/freepi/freepi-discovery.ts +2 -2
- package/src/providers/integrations/freepi/freepi-headers.ts +2 -2
- package/src/providers/integrations/freepi/freepi-protocol.ts +11 -2
- package/src/providers/integrations/freepi/freepi-realm.ts +0 -3
- package/src/providers/integrations/freepi/freepi-session.ts +158 -0
- package/src/providers/integrations/freepi/freepi.ts +80 -54
- package/src/providers/integrations/github/github-discovery.ts +30 -13
- package/src/providers/integrations/github/github-oauth.ts +217 -44
- package/src/providers/integrations/github/github-quota.ts +22 -5
- package/src/providers/integrations/github/github.ts +40 -32
- package/src/providers/integrations/grok/grok-oauth.ts +4 -4
- package/src/providers/integrations/hermes/hermes-oauth.ts +3 -3
- package/src/providers/integrations/hermes/hermes.ts +34 -5
- package/src/providers/integrations/kilo/kilo-oauth.ts +4 -4
- package/src/providers/integrations/kilo/kilo.ts +1 -1
- package/src/providers/integrations/kimi/kimi-oauth.ts +3 -3
- package/src/providers/integrations/kiro/kiro-oauth.ts +2 -2
- package/src/providers/integrations/muse/muse-oauth.ts +5 -5
- package/src/providers/integrations/opencode/fingerprint.ts +1 -1
- package/src/providers/integrations/openrouter/provider.ts +1 -1
- package/src/providers/integrations/perch/perch-protocol.ts +0 -3
- package/src/providers/integrations/perch/perch.ts +3 -3
- package/src/providers/integrations/qoder/claim-qoder-credits.ts +1 -1
- package/src/providers/integrations/qoder/qoder-adapter.ts +19 -113
- package/src/providers/integrations/qoder/qoder-auth.ts +8 -1
- package/src/providers/integrations/qoder/qoder-catalog.ts +1 -1
- package/src/providers/integrations/qoder/qoder-chat.ts +25 -8
- package/src/providers/integrations/qoder/qoder-checkin.ts +1 -1
- package/src/providers/integrations/qoder/qoder-cosy.ts +37 -9
- package/src/providers/integrations/qoder/qoder-oauth.ts +9 -2
- package/src/providers/integrations/qoder/qoder-realm.ts +13 -36
- package/src/providers/integrations/qoder/qoder-sse.ts +447 -68
- package/src/providers/integrations/qoder/qoder-types.ts +9 -0
- package/src/providers/integrations/qoder/qoder.ts +3 -25
- package/src/providers/integrations/sensenova/provider.ts +144 -0
- package/src/providers/integrations/trae/trae-quota.ts +15 -1
- package/src/providers/integrations/vercel/provider.ts +117 -0
- package/src/providers/integrations/vercel/vercel-quota.ts +96 -0
- package/src/providers/integrations/xai/xai-oauth.ts +5 -5
- package/src/providers/integrations/zcode-start-plan/gifts.ts +1 -1
- package/src/providers/integrations/zcode-start-plan/oauth.ts +3 -3
- package/src/providers/integrations/zro/zro.ts +2 -1
- package/src/providers/operations/account-refresh-status.ts +14 -0
- package/src/providers/operations/client-versions.ts +95 -30
- package/src/providers/operations/oauth-refresh-lead.ts +46 -22
- package/src/providers/operations/provider-caches.ts +1 -1
- package/src/providers/operations/provider-credential-service.ts +22 -25
- package/src/providers/operations/session-resolution.ts +17 -1
- package/src/providers/provider-contracts.ts +2 -2
- package/src/providers/provider-metadata.ts +30 -0
- package/src/providers/quota/quota-contracts.ts +2 -0
- package/src/providers/quota/refresh.ts +25 -3
- package/src/security/ip-boundary.ts +1 -1
- package/src/transport/dispatch/attempt-finalize.ts +1 -1
- package/src/transport/dispatch/attempt-loop.ts +3 -3
- package/src/transport/dispatch/handler-deps.ts +1 -1
- package/src/transport/dispatch/leases.ts +1 -1
- package/src/transport/dispatch/retry-policy.ts +1 -1
- package/src/transport/dispatch/streaming/finalize.ts +2 -2
- package/src/transport/dispatch/streaming/stream.ts +1 -1
- package/src/transport/dispatch/upstream.ts +1 -1
- package/src/transport/shutdown-notice.ts +1 -1
- package/src/workers/buddy-growth-tasks.ts +8 -8
- package/src/workers/daily-checkin.ts +4 -4
- package/src/workers/quota-refresh-sweep.ts +1 -1
- package/src/workers/zcode-gift-claim.ts +1 -1
- package/dist/dashboard/assets/BannedPage-Cc0vKpMG.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-Bqj2aa1T.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-CXsaOAO2.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-BeLpJ4ma.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-DnV0uZ3m.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-CBxAjo63.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-B5yEE0k6.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-BWFLECmz.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-CgoPc5B9.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-D9bFQern.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-B_p4tL8k.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js +0 -8
- package/dist/dashboard/assets/ProviderDetailPage-rs5E2rxv.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-D_0PiZtg.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-CLI2bJTK.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js +0 -9
- package/dist/dashboard/assets/ProxyPage-BwNC_-Cx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-DA-a1iSN.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CctTga2C.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-febLU4r1.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-M6fvR5Wz.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-nyeuRqz9.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-BFOlvrJC.js.gz +0 -0
- package/dist/dashboard/assets/app-Dx2QgsNj.css +0 -2
- package/dist/dashboard/assets/app-Dx2QgsNj.css.gz +0 -0
- package/dist/dashboard/assets/assert-CqTLw5e7.js.gz +0 -0
- package/dist/dashboard/assets/badge-C83EqLB0.js.gz +0 -0
- package/dist/dashboard/assets/banner-D1xn7pIe.js.gz +0 -0
- package/dist/dashboard/assets/card-DU3Lq5Lm.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-Dw1U_drK.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-CEL5Sg_J.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BjFR5UHy.js.gz +0 -0
- package/dist/dashboard/assets/drawer-HvBW0AjI.js.gz +0 -0
- package/dist/dashboard/assets/entry-BSu3gFlt.js.gz +0 -0
- package/dist/dashboard/assets/entry-CECVELyy.js.gz +0 -0
- package/dist/dashboard/assets/entry-DYYofQ7W.js.gz +0 -0
- package/dist/dashboard/assets/formatters-DLW4i8zK.js.gz +0 -0
- package/dist/dashboard/assets/index-1-fCqe64.js.gz +0 -0
- package/dist/dashboard/assets/inline-DGvU2oLK.js.gz +0 -0
- package/dist/dashboard/assets/input-iNnO1X2K.js.gz +0 -0
- package/dist/dashboard/assets/layout-0q8UGypb.js.gz +0 -0
- package/dist/dashboard/assets/list-row-C0w2bQjJ.js.gz +0 -0
- package/dist/dashboard/assets/live-M5aJ_xCa.js.gz +0 -0
- package/dist/dashboard/assets/network-BKeQGT3K.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CivAk3da.js.gz +0 -0
- package/dist/dashboard/assets/pagination-CpzvI5ep.js.gz +0 -0
- package/dist/dashboard/assets/routing-BFQX2VBc.js.gz +0 -0
- package/dist/dashboard/assets/select-CXbck0jG.js.gz +0 -0
- package/dist/dashboard/assets/settings-C_XvMHh9.js.gz +0 -0
- package/dist/dashboard/assets/stack-DggRiCxE.js.gz +0 -0
- package/dist/dashboard/assets/state-ClFzfbYp.js.gz +0 -0
- package/dist/dashboard/assets/switch-CTIFxKqS.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BClG3yWj.js.gz +0 -0
- package/src/console/providers/catalog/discover-constants.ts +0 -6
- package/src/network/pool-health.ts +0 -198
- package/src/providers/integrations/buddy/buddy-checkin.ts +0 -521
- package/src/providers/integrations/buddy/buddy-cli-headers.ts +0 -76
- package/src/providers/integrations/buddy/buddy-conversation-headers.ts +0 -130
- package/src/providers/integrations/buddy/buddy-discovery-shared.ts +0 -234
- package/src/providers/integrations/buddy/buddy-growth-shared.ts +0 -496
- package/src/providers/integrations/buddy/buddy-oauth-shared.ts +0 -341
- package/src/providers/integrations/buddy/buddy-quota-shared.ts +0 -417
- package/src/providers/integrations/buddy/buddy-server-tools.ts +0 -240
- package/src/providers/integrations/buddy/buddy-usage-shared.ts +0 -221
- package/src/providers/integrations/buddy/buddy-usage-store.ts +0 -181
- package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +0 -37
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +0 -188
- package/src/providers/integrations/buddy/codebuddy/oauth.ts +0 -47
- package/src/providers/integrations/buddy/codebuddy/provider.ts +0 -179
- package/src/providers/integrations/buddy/codebuddy/quota.ts +0 -154
- package/src/providers/integrations/qoder/chat-proto.ts +0 -328
- package/src/providers/integrations/qoder/qoder-grpc.ts +0 -870
- package/src/providers/integrations/qoder/qoder-ide.ts +0 -481
- /package/dist/dashboard/assets/{app-DIXLjojg.js → app-C0gTXEoN.js} +0 -0
- /package/dist/dashboard/assets/{app-DIXLjojg.js.gz → app-C0gTXEoN.js.gz} +0 -0
- /package/src/network/{http2-bidi.ts → bidi.ts} +0 -0
- /package/src/network/pool/{byte-accounting.ts → accounting.ts} +0 -0
- /package/src/network/pool/{pool-scripts.ts → scripts.ts} +0 -0
- /package/src/network/pool/{pool-state.ts → state.ts} +0 -0
- /package/src/network/{backoff.ts → util/backoff.ts} +0 -0
- /package/src/network/{deduplication.ts → util/dedupe.ts} +0 -0
- /package/src/network/{ip-utils.ts → util/ip.ts} +0 -0
- /package/src/network/{rate-limit-verdict.ts → verdict.ts} +0 -0
|
@@ -1,130 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* The conversation and tracing header family the buddy upstream expects.
|
|
3
|
-
*
|
|
4
|
-
* A live WorkBuddy request answered `400 · 11128 "conversation id missing"` —
|
|
5
|
-
* "This call failed channel verification, possibly because it was not sent from
|
|
6
|
-
* an official client" — while carrying only `x-session-id` and `user-agent`.
|
|
7
|
-
* The reference gateway always sends a whole family of conversation IDs on chat
|
|
8
|
-
* (`injectConversationHeaders`), and its own comment is unambiguous about one of
|
|
9
|
-
* them: `X-Conversation-Request-ID` is the turn-level aggregation primary key
|
|
10
|
-
* and is **mandatory**.
|
|
11
|
-
*
|
|
12
|
-
* Four layers, each with its own lifetime, which is why one ID is not enough:
|
|
13
|
-
*
|
|
14
|
-
* - `X-Conversation-ID` — conversation-scoped, stable across turns. Passed
|
|
15
|
-
* through from the client when one arrives; otherwise omitted, never invented,
|
|
16
|
-
* so the upstream does not build a conversation the caller never had.
|
|
17
|
-
* - `X-Conversation-Request-ID` / `X-Root-Request-ID` — turn-scoped aggregation
|
|
18
|
-
* key. Mandatory: every tool call, retry, failover and degradation inside one
|
|
19
|
-
* user send reuses the same value so the backend aggregates them into one
|
|
20
|
-
* record instead of fragmenting.
|
|
21
|
-
* - `X-Conversation-Message-ID` = `X-Request-ID` — message-scoped, fresh per
|
|
22
|
-
* outbound message.
|
|
23
|
-
* - `X-B3-TraceId` / `X-B3-SpanId` / `X-B3-Sampled` — the B3 trace family.
|
|
24
|
-
*
|
|
25
|
-
* B3 is stricter than the rest: its spec accepts only a 16- or 32-character hex
|
|
26
|
-
* trace id and a 16-character hex span id. An inbound conversation id is
|
|
27
|
-
* arbitrary (it may carry dashes or be non-hex), and putting it straight into
|
|
28
|
-
* `X-B3-TraceId` breaks trace correlation — so it is validated and falls back to
|
|
29
|
-
* the message id, which is always 32 hex.
|
|
30
|
-
*/
|
|
31
|
-
|
|
32
|
-
/** A 32-character hex id, the shape the upstream's own message ids use. */
|
|
33
|
-
function newMessageId(): string {
|
|
34
|
-
return crypto.randomUUID().replaceAll("-", "");
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
/** Renders a 32-char hex id as a dashed UUID (`8-4-4-4-12`). */
|
|
38
|
-
function toUuidHex(hex: string): string {
|
|
39
|
-
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
/** True when `value` is a valid B3 trace id: 16 or 32 hex characters. */
|
|
43
|
-
function isValidTraceId(value: string): boolean {
|
|
44
|
-
if (value.length !== 16 && value.length !== 32) return false;
|
|
45
|
-
return /^[0-9a-fA-F]+$/.test(value);
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
export interface BuddyConversationIds {
|
|
49
|
-
/**
|
|
50
|
-
* Conversation-scoped id, stable across turns. `undefined` means the client
|
|
51
|
-
* sent none, and the header is then omitted rather than fabricated.
|
|
52
|
-
*/
|
|
53
|
-
readonly conversationId?: string | undefined;
|
|
54
|
-
/**
|
|
55
|
-
* Turn-scoped aggregation key. When absent a fresh one is generated, because
|
|
56
|
-
* the header is mandatory and a call without it is what drew `11128`.
|
|
57
|
-
*/
|
|
58
|
-
readonly conversationRequestId?: string | undefined;
|
|
59
|
-
/** Inbound trace id to pass through; falls back to the conversation request id. */
|
|
60
|
-
readonly traceId?: string | undefined;
|
|
61
|
-
/**
|
|
62
|
-
* Wire format for the two message-scoped ids (`x-conversation-message-id`,
|
|
63
|
-
* `x-request-id`).
|
|
64
|
-
*
|
|
65
|
-
* The reference emits these as dashed UUIDs on the desktop product
|
|
66
|
-
* and as 32-hex on CLI traffic (`build_attempt_headers` converts only the
|
|
67
|
-
* message/request ids, and only for the desktop profiles). The turn
|
|
68
|
-
* aggregation key (`x-conversation-request-id` / `x-root-request-id`) and the
|
|
69
|
-
* B3/W3C trace ids stay hex in both styles, because B3's spec accepts only
|
|
70
|
-
* hex. Default `"hex"`.
|
|
71
|
-
*/
|
|
72
|
-
readonly messageIdStyle?: "hex" | "uuid" | undefined;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Builds the conversation/tracing headers for one outbound chat request.
|
|
77
|
-
*
|
|
78
|
-
* Returns only headers that should be *added* — `x-request-id` is included
|
|
79
|
-
* because the reference sets it from the same message id as
|
|
80
|
-
* `X-Conversation-Message-ID`, and a caller that already sends its own must
|
|
81
|
-
* merge this underneath rather than over it.
|
|
82
|
-
*/
|
|
83
|
-
export function buddyConversationHeaders(
|
|
84
|
-
ids: BuddyConversationIds = {},
|
|
85
|
-
): Record<string, string> {
|
|
86
|
-
const conversationRequestId =
|
|
87
|
-
ids.conversationRequestId && ids.conversationRequestId.trim().length > 0
|
|
88
|
-
? ids.conversationRequestId.trim()
|
|
89
|
-
: newMessageId();
|
|
90
|
-
const messageId = newMessageId();
|
|
91
|
-
// The message-scoped ids may render as a dashed UUID (WorkBuddy desktop) or
|
|
92
|
-
// as 32-hex (CLI); the raw hex is still what the B3/W3C trace ids derive from.
|
|
93
|
-
const messageHeaderValue = ids.messageIdStyle === "uuid" ? toUuidHex(messageId) : messageId;
|
|
94
|
-
const traceId =
|
|
95
|
-
ids.traceId && ids.traceId.trim().length > 0 ? ids.traceId.trim() : conversationRequestId;
|
|
96
|
-
const b3TraceId = isValidTraceId(conversationRequestId) ? conversationRequestId : messageId;
|
|
97
|
-
|
|
98
|
-
const headers: Record<string, string> = {
|
|
99
|
-
"x-conversation-request-id": conversationRequestId,
|
|
100
|
-
"x-conversation-message-id": messageHeaderValue,
|
|
101
|
-
"x-request-id": messageHeaderValue,
|
|
102
|
-
"x-root-request-id": conversationRequestId,
|
|
103
|
-
"x-trace-id": traceId,
|
|
104
|
-
// W3C trace context alongside the B3 set below: the upstream reads both,
|
|
105
|
-
// and every reference request carries `traceparent`, so sending only the
|
|
106
|
-
// B3 half leaves a header the channel check expects absent.
|
|
107
|
-
traceparent: `00-${b3TraceId}-${messageId.slice(0, 16)}-01`,
|
|
108
|
-
"x-b3-traceid": b3TraceId,
|
|
109
|
-
"x-b3-spanid": messageId.slice(0, 16),
|
|
110
|
-
"x-b3-sampled": "1",
|
|
111
|
-
};
|
|
112
|
-
// Always sent, invented when the caller gave none.
|
|
113
|
-
//
|
|
114
|
-
// `x-conversation-id` is mandatory, and a chat request without it is refused
|
|
115
|
-
// with `400 · 11-128 "request illegal"` — an error that names neither the
|
|
116
|
-
// header nor the channel, and which reads like a block rather than a missing
|
|
117
|
-
// field. Isolated against the live API by removing one header at a time:
|
|
118
|
-
// only `x-conversation-id`, `x-conversation-request-id` and
|
|
119
|
-
// `x-conversation-message-id` are required; the B3/W3C trace set, the
|
|
120
|
-
// stainless set, the agent block and the IDE block are all optional.
|
|
121
|
-
//
|
|
122
|
-
// Inventing one when the caller has none is still the right default: the id
|
|
123
|
-
// is per-dispatch here, so a caller with no session is not claiming a session
|
|
124
|
-
// it never had — and withholding the header only guarantees a refusal.
|
|
125
|
-
headers["x-conversation-id"] =
|
|
126
|
-
ids.conversationId !== undefined && ids.conversationId.trim().length > 0
|
|
127
|
-
? ids.conversationId.trim()
|
|
128
|
-
: newMessageId();
|
|
129
|
-
return headers;
|
|
130
|
-
}
|
|
@@ -1,234 +0,0 @@
|
|
|
1
|
-
import { asNumber as sharedAsNumber, asRecord } from "../../../shared/coerce";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Model discovery for the buddy family (CodeBuddy intl / CN).
|
|
5
|
-
*
|
|
6
|
-
* The two sites are protocol-isomorphic but NOT path-isomorphic, and the
|
|
7
|
-
* difference is load-bearing: the international site answers
|
|
8
|
-
* `/v2/enterprises/personal/models`, while the CN site answers
|
|
9
|
-
* `/console/enterprises/personal/models`. Probing the CN path on an
|
|
10
|
-
* international host returns HTTP 500 from the edge (APISIX) rather than 404 —
|
|
11
|
-
* so a single shared path silently fails every intl sync while looking like an
|
|
12
|
-
* upstream outage.
|
|
13
|
-
*
|
|
14
|
-
* Both shapes answer `{ code, msg, data: { models, agents } }`, not the OpenAI
|
|
15
|
-
* `{data:[…]}` envelope the shared OpenAI-compatible discovery reads, which is
|
|
16
|
-
* why this needs its own reader.
|
|
17
|
-
*
|
|
18
|
-
* Two filters decide what is actually callable, and both come from the payload:
|
|
19
|
-
* - `disabled` rows are advertised but not served;
|
|
20
|
-
* - when an `agents` entry named `cli` carries a model list, that list is the
|
|
21
|
-
* roster the CLI identity may call. The console publishes models a web
|
|
22
|
-
* session can reach but a CLI token cannot, and listing those would offer
|
|
23
|
-
* routes that answer with an upstream rejection.
|
|
24
|
-
*
|
|
25
|
-
* The static catalog beside each provider stays as the fallback for a site
|
|
26
|
-
* whose directory is unreachable: discovery adds and corrects rows, it does not
|
|
27
|
-
* replace the bundled list.
|
|
28
|
-
*/
|
|
29
|
-
import type { ModelDefinition } from "../../provider-model-definition";
|
|
30
|
-
import { makeBuddyModel, type BuddyRawEntry } from "./buddy-catalog-shared";
|
|
31
|
-
import { buddyAccountUid } from "./buddy-oauth-shared";
|
|
32
|
-
|
|
33
|
-
/** Console directory path on the CN site (`copilot.tencent.com`). */
|
|
34
|
-
export const BUDDY_CN_MODELS_PATH = "/console/enterprises/personal/models" as const;
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Console directory path on the international site (`codebuddy.ai`). The CN
|
|
38
|
-
* path above answers 500 on these hosts.
|
|
39
|
-
*/
|
|
40
|
-
export const BUDDY_INTL_MODELS_PATH = "/v2/enterprises/personal/models" as const;
|
|
41
|
-
|
|
42
|
-
/**
|
|
43
|
-
* Remote config path, answered on every realm's chat host.
|
|
44
|
-
*
|
|
45
|
-
* Both reference gateways treat this as the primary model catalog and the
|
|
46
|
-
* personal-models paths above as the narrower fallback: `/v3/config` carries
|
|
47
|
-
* the same `{ code, msg, data: { models, agents } }` envelope plus the
|
|
48
|
-
* per-product rosters the personal path does not always publish. It is tried
|
|
49
|
-
* first, and a failure falls through to the path the caller already passes, so
|
|
50
|
-
* a host that does not answer it behaves exactly as it does today.
|
|
51
|
-
*/
|
|
52
|
-
export const BUDDY_CONFIG_PATH = "/v3/config" as const;
|
|
53
|
-
|
|
54
|
-
/** Envelope code the console directory answers on success. */
|
|
55
|
-
const BUDDY_OK_CODE = 0;
|
|
56
|
-
|
|
57
|
-
interface BuddyDirectoryRow {
|
|
58
|
-
readonly id?: unknown;
|
|
59
|
-
readonly name?: unknown;
|
|
60
|
-
readonly disabled?: unknown;
|
|
61
|
-
readonly maxInputTokens?: unknown;
|
|
62
|
-
readonly maxOutputTokens?: unknown;
|
|
63
|
-
readonly supportsImages?: unknown;
|
|
64
|
-
readonly supportsToolCall?: unknown;
|
|
65
|
-
readonly supportsReasoning?: unknown;
|
|
66
|
-
readonly tags?: unknown;
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
/**
|
|
70
|
-
* Strips the version segment a provider's base URL carries so a directory path
|
|
71
|
-
* that starts with its own `/v2` does not join into `/v2/v2/…`.
|
|
72
|
-
*
|
|
73
|
-
* The CodeBuddy intl base URL is `https://www.codebuddy.ai/v2` (the chat
|
|
74
|
-
* endpoint is the version-less `/chat/completions` under it), while the model
|
|
75
|
-
* directory lives at the absolute `/v2/enterprises/personal/models`. Joining
|
|
76
|
-
* the two verbatim doubles the segment and the edge answers 404.
|
|
77
|
-
*/
|
|
78
|
-
function siteOrigin(baseUrl: string): string {
|
|
79
|
-
return baseUrl.replace(/\/+$/, "").replace(/\/v\d+$/, "");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function asNumber(value: unknown): number | null {
|
|
83
|
-
return sharedAsNumber(value) ?? null;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
/**
|
|
87
|
-
* Reads one site's console directory into catalog rows.
|
|
88
|
-
*
|
|
89
|
-
* Returns `null` when the endpoint is unusable (non-200, unparseable body, or a
|
|
90
|
-
* non-zero envelope code) so the caller reports a failed sync instead of
|
|
91
|
-
* persisting an empty roster over a working catalog.
|
|
92
|
-
*/
|
|
93
|
-
export async function fetchBuddyDirectoryModels(args: {
|
|
94
|
-
readonly siteUrl: string;
|
|
95
|
-
readonly providerId: string;
|
|
96
|
-
readonly credential: string;
|
|
97
|
-
readonly modelsPath: string;
|
|
98
|
-
readonly endpoint: string | undefined;
|
|
99
|
-
readonly signal?: AbortSignal | undefined;
|
|
100
|
-
readonly fetcher?: typeof fetch | undefined;
|
|
101
|
-
}): Promise<readonly ModelDefinition[] | null> {
|
|
102
|
-
const fetcher = args.fetcher ?? globalThis.fetch;
|
|
103
|
-
// Fetch both catalog scopes and merge them. `/v3/config` is ranked higher and
|
|
104
|
-
// is the primary source (matches the reference gateways), but the personal
|
|
105
|
-
// models path carries models the v3 response does not always publish — so a
|
|
106
|
-
// single-source read can silently miss models that are callable. Merging with
|
|
107
|
-
// dedupe by model id gives the union, mirroring the upstream codebuddy2api
|
|
108
|
-
// catalog aggregation. Each failure falls through to the other source, so a
|
|
109
|
-
// host that answers only one behaves exactly as it does today.
|
|
110
|
-
const v3 = await fetchBuddyDirectoryOnce(args, fetcher, BUDDY_CONFIG_PATH);
|
|
111
|
-
const personal = await fetchBuddyDirectoryOnce(args, fetcher, args.modelsPath);
|
|
112
|
-
if (v3 !== null && personal !== null) return mergeBuddyDirectories(v3, personal);
|
|
113
|
-
return v3 ?? personal;
|
|
114
|
-
}
|
|
115
|
-
|
|
116
|
-
/**
|
|
117
|
-
* Merges two buddy directory reads into one roster, preserving each source's
|
|
118
|
-
* declaration order and de-duplicating by model id. `primary` wins when both
|
|
119
|
-
* sources declare the same id; models present only in `supplemental` are
|
|
120
|
-
* appended. Both lists are already filtered (disabled/CLI-roster/not-chat),
|
|
121
|
-
* so the merge only has to combine them.
|
|
122
|
-
*/
|
|
123
|
-
function mergeBuddyDirectories(
|
|
124
|
-
primary: readonly ModelDefinition[],
|
|
125
|
-
supplemental: readonly ModelDefinition[],
|
|
126
|
-
): readonly ModelDefinition[] {
|
|
127
|
-
const seen = new Set<string>();
|
|
128
|
-
const merged: ModelDefinition[] = [];
|
|
129
|
-
for (const model of primary) {
|
|
130
|
-
if (seen.has(model.modelId)) continue;
|
|
131
|
-
seen.add(model.modelId);
|
|
132
|
-
merged.push(model);
|
|
133
|
-
}
|
|
134
|
-
for (const model of supplemental) {
|
|
135
|
-
if (seen.has(model.modelId)) continue;
|
|
136
|
-
seen.add(model.modelId);
|
|
137
|
-
merged.push(model);
|
|
138
|
-
}
|
|
139
|
-
return merged;
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
/** Reads one directory path; `null` on any transport, status, or shape miss. */
|
|
143
|
-
async function fetchBuddyDirectoryOnce(
|
|
144
|
-
args: {
|
|
145
|
-
readonly siteUrl: string;
|
|
146
|
-
readonly providerId: string;
|
|
147
|
-
readonly credential: string;
|
|
148
|
-
readonly endpoint: string | undefined;
|
|
149
|
-
readonly signal?: AbortSignal | undefined;
|
|
150
|
-
},
|
|
151
|
-
fetcher: typeof fetch,
|
|
152
|
-
path: string,
|
|
153
|
-
): Promise<readonly ModelDefinition[] | null> {
|
|
154
|
-
// The directory scores by account: an access token's `sub` is the uid. An
|
|
155
|
-
// opaque API key carries no identity, and the endpoint still answers for it,
|
|
156
|
-
// so the header is declared absent rather than guessed.
|
|
157
|
-
const uid = buddyAccountUid(args.credential);
|
|
158
|
-
let response: Response;
|
|
159
|
-
try {
|
|
160
|
-
response = await fetcher(`${siteOrigin(args.siteUrl)}${path}`, {
|
|
161
|
-
method: "GET",
|
|
162
|
-
headers: {
|
|
163
|
-
accept: "application/json",
|
|
164
|
-
authorization: `Bearer ${args.credential}`,
|
|
165
|
-
"x-product": "SaaS",
|
|
166
|
-
...(uid === undefined ? { "x-no-user-id": "1" } : { "x-user-id": uid }),
|
|
167
|
-
"x-no-enterprise-id": "1",
|
|
168
|
-
"x-no-department-info": "1",
|
|
169
|
-
},
|
|
170
|
-
...(args.signal === undefined ? {} : { signal: args.signal }),
|
|
171
|
-
});
|
|
172
|
-
} catch {
|
|
173
|
-
return null;
|
|
174
|
-
}
|
|
175
|
-
if (!response.ok) return null;
|
|
176
|
-
let body: unknown;
|
|
177
|
-
try {
|
|
178
|
-
body = await response.json();
|
|
179
|
-
} catch {
|
|
180
|
-
return null;
|
|
181
|
-
}
|
|
182
|
-
const envelope = asRecord(body);
|
|
183
|
-
if (envelope === undefined || envelope["code"] !== BUDDY_OK_CODE) return null;
|
|
184
|
-
const data = asRecord(envelope["data"]);
|
|
185
|
-
const rawModels = data?.["models"];
|
|
186
|
-
if (!Array.isArray(rawModels)) return null;
|
|
187
|
-
|
|
188
|
-
// The CLI agent's roster, when published, is the callable subset.
|
|
189
|
-
const agents = data?.["agents"];
|
|
190
|
-
let cliRoster: Set<string> | undefined;
|
|
191
|
-
if (Array.isArray(agents)) {
|
|
192
|
-
for (const entry of agents) {
|
|
193
|
-
const agent = asRecord(entry);
|
|
194
|
-
if (agent?.["name"] !== "cli") continue;
|
|
195
|
-
const listed = agent["models"];
|
|
196
|
-
if (Array.isArray(listed) && listed.length > 0) {
|
|
197
|
-
cliRoster = new Set(listed.filter((id): id is string => typeof id === "string"));
|
|
198
|
-
}
|
|
199
|
-
break;
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
const entries: BuddyRawEntry[] = [];
|
|
204
|
-
const seen = new Set<string>();
|
|
205
|
-
for (const entry of rawModels) {
|
|
206
|
-
const model = asRecord(entry) as BuddyDirectoryRow | undefined;
|
|
207
|
-
const id = model?.id;
|
|
208
|
-
if (typeof id !== "string" || id.length === 0 || seen.has(id)) continue;
|
|
209
|
-
if (model?.disabled === true) continue;
|
|
210
|
-
// Completion, NES, and codewise rows are not chat models. Listing them
|
|
211
|
-
// offers a route that 400s on a chat request. A declared output of 256 or
|
|
212
|
-
// less is the same signal: a completion model published with a chat-sized
|
|
213
|
-
// name. `text-to-image` is an image row, served by the image roster.
|
|
214
|
-
const lowerId = id.toLowerCase();
|
|
215
|
-
if (lowerId.startsWith("nes-") || lowerId.startsWith("completion-") || lowerId.startsWith("codewise-")) continue;
|
|
216
|
-
const output = asNumber(model?.maxOutputTokens);
|
|
217
|
-
if (output !== null && output <= 256) continue;
|
|
218
|
-
const tags = model?.tags;
|
|
219
|
-
if (Array.isArray(tags) && tags.some((tag) => typeof tag === "string" && tag.toLowerCase() === "text-to-image")) continue;
|
|
220
|
-
if (cliRoster !== undefined && !cliRoster.has(id)) continue;
|
|
221
|
-
seen.add(id);
|
|
222
|
-
entries.push([
|
|
223
|
-
id,
|
|
224
|
-
typeof model?.name === "string" && model.name.length > 0 ? model.name : id,
|
|
225
|
-
model?.supportsReasoning === true,
|
|
226
|
-
model?.supportsImages === true,
|
|
227
|
-
asNumber(model?.maxInputTokens),
|
|
228
|
-
asNumber(model?.maxOutputTokens),
|
|
229
|
-
model?.supportsToolCall === true,
|
|
230
|
-
]);
|
|
231
|
-
}
|
|
232
|
-
if (entries.length === 0) return null;
|
|
233
|
-
return entries.map((entry) => makeBuddyModel(entry, args.providerId, args.endpoint));
|
|
234
|
-
}
|