cartethyia 2.7.8 → 2.7.9
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 +0 -1
- package/README.md +29 -59
- package/dist/dashboard/assets/BannedPage-BxoG1MrL.js +1 -0
- package/dist/dashboard/assets/BannedPage-BxoG1MrL.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-BRWKPQPf.js → CliToolDetailPage-ixwgKk53.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-ixwgKk53.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-BP-Y5iHN.js → CliToolsPage-BmttNV3U.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BmttNV3U.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-BE3qwwfC.js +1 -0
- package/dist/dashboard/assets/CombosPage-BE3qwwfC.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-CRZdmMIX.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-CRZdmMIX.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-Dv_FJ6Er.js +1 -0
- package/dist/dashboard/assets/CustomizationPage-Dv_FJ6Er.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-CoVrw2sM.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-CoVrw2sM.js.gz +0 -0
- package/dist/dashboard/assets/{InjectSystemPromptPanel-Cv-2Ol_K.js → InjectSystemPromptPanel-BOoO8rpz.js} +2 -2
- package/dist/dashboard/assets/InjectSystemPromptPanel-BOoO8rpz.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-bKfz_b1K.js → LoginPage-ChJuNNVN.js} +1 -1
- package/dist/dashboard/assets/LoginPage-ChJuNNVN.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-B-WQxx_H.js → ModelPicker-BZAJtPg1.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-BZAJtPg1.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-BE40s3u5.js +1 -0
- package/dist/dashboard/assets/OverviewPage-BE40s3u5.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-sfLoQtPV.js +8 -0
- package/dist/dashboard/assets/ProviderDetailPage-sfLoQtPV.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-CQ6bPUf_.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-CQ6bPUf_.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-DcepmPWo.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-DcepmPWo.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-emlTuxz6.js → ProxyPage-BJ87Pp0U.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-BJ87Pp0U.js.gz +0 -0
- package/dist/dashboard/assets/{QuotaPage-CMJKNYWb.js → QuotaPage-gkSyRAKa.js} +1 -1
- package/dist/dashboard/assets/QuotaPage-gkSyRAKa.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-C5HPWqEv.js +1 -0
- package/dist/dashboard/assets/SettingsPage-C5HPWqEv.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-CUZrKs9r.js → SetupPage-CFNcATJJ.js} +1 -1
- package/dist/dashboard/assets/SetupPage-CFNcATJJ.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-jWmUdDpy.js → StudioPage-YoD4tY5l.js} +1 -1
- package/dist/dashboard/assets/StudioPage-YoD4tY5l.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-DxjaAhb_.js +56 -0
- package/dist/dashboard/assets/UsagePage-DxjaAhb_.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-BTlkq_Uk.js +1 -0
- package/dist/dashboard/assets/api-keys-BTlkq_Uk.js.gz +0 -0
- package/dist/dashboard/assets/app-BX2nnKqs.css +2 -0
- package/dist/dashboard/assets/app-BX2nnKqs.css.gz +0 -0
- package/dist/dashboard/assets/assert-CndthXFQ.js +1 -0
- package/dist/dashboard/assets/assert-CndthXFQ.js.gz +0 -0
- package/dist/dashboard/assets/{badge-DyI_mJfi.js → badge-DdbT_7Am.js} +1 -1
- package/dist/dashboard/assets/badge-DdbT_7Am.js.gz +0 -0
- package/dist/dashboard/assets/ban-durations-B58FyRxC.js +1 -0
- package/dist/dashboard/assets/ban-durations-B58FyRxC.js.gz +0 -0
- package/dist/dashboard/assets/{banner-B-yXtCqb.js → banner-CsGN-nbm.js} +1 -1
- package/dist/dashboard/assets/banner-CsGN-nbm.js.gz +0 -0
- package/dist/dashboard/assets/brand/bansos_page.webp +0 -0
- package/dist/dashboard/assets/brand/denia_bansos.webp +0 -0
- package/dist/dashboard/assets/brand/favicon.webp +0 -0
- package/dist/dashboard/assets/brand/login_register.webp +0 -0
- package/dist/dashboard/assets/brand/login_register_initial.webp +0 -0
- package/dist/dashboard/assets/brand/og_bansos.webp +0 -0
- package/dist/dashboard/assets/brand/og_image.webp +0 -0
- package/dist/dashboard/assets/brand/sidebar_ico.webp +0 -0
- package/dist/dashboard/assets/{card-_HwAEqFF.js → card-mgZ_TLLZ.js} +1 -1
- package/dist/dashboard/assets/card-mgZ_TLLZ.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-A1-v8-03.js +1 -0
- package/dist/dashboard/assets/cli-tools-A1-v8-03.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-ByjCk0o9.js → clipboard-button-CJ4Zty89.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-CJ4Zty89.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-BZhOlfz-.js → dialog-B5L2jPQ_.js} +1 -1
- package/dist/dashboard/assets/dialog-B5L2jPQ_.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-BADqIRYP.js → drawer-DkjUouAj.js} +1 -1
- package/dist/dashboard/assets/drawer-DkjUouAj.js.gz +0 -0
- package/dist/dashboard/assets/{entry-COaC-irN.js → entry-B-LVLV6o.js} +1 -1
- package/dist/dashboard/assets/entry-B-LVLV6o.js.gz +0 -0
- package/dist/dashboard/assets/entry-CAhdYl3B.js +1 -0
- package/dist/dashboard/assets/entry-CAhdYl3B.js.gz +0 -0
- package/dist/dashboard/assets/entry-D2xD0Tmd.js +4 -0
- package/dist/dashboard/assets/entry-D2xD0Tmd.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-DcHJyRiu.js → formatters-CrsdLVsn.js} +1 -1
- package/dist/dashboard/assets/formatters-CrsdLVsn.js.gz +0 -0
- package/dist/dashboard/assets/{index-CgKmFngv.js → index-BU64Lqvp.js} +2 -2
- package/dist/dashboard/assets/index-BU64Lqvp.js.gz +0 -0
- package/dist/dashboard/assets/{inline-B2BirKry.js → inline-B2aDLyyg.js} +1 -1
- package/dist/dashboard/assets/inline-B2aDLyyg.js.gz +0 -0
- package/dist/dashboard/assets/{input-D-qV9dKY.js → input-BCVkdR9d.js} +1 -1
- package/dist/dashboard/assets/input-BCVkdR9d.js.gz +0 -0
- package/dist/dashboard/assets/{layout-B7tVWhtV.js → layout-DNcAdMK-.js} +1 -1
- package/dist/dashboard/assets/layout-DNcAdMK-.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-CtkGE3bF.js → list-row-DgrIH0hw.js} +1 -1
- package/dist/dashboard/assets/list-row-DgrIH0hw.js.gz +0 -0
- package/dist/dashboard/assets/{live-DGizF06-.js → live-Cae01iu8.js} +1 -1
- package/dist/dashboard/assets/live-Cae01iu8.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-GU7XdEjz.js → mutation-BQ0ccH_A.js} +1 -1
- package/dist/dashboard/assets/mutation-BQ0ccH_A.js.gz +0 -0
- package/dist/dashboard/assets/{network-C9UE-bOr.js → network-CRib7H_2.js} +1 -1
- package/dist/dashboard/assets/network-CRib7H_2.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-BnAd22a_.js → numbers-BKQE8Xpz.js} +1 -1
- package/dist/dashboard/assets/numbers-BKQE8Xpz.js.gz +0 -0
- package/dist/dashboard/assets/{pagination-BAywyMzS.js → pagination-ecPvG_8g.js} +1 -1
- package/dist/dashboard/assets/pagination-ecPvG_8g.js.gz +0 -0
- package/dist/dashboard/assets/providers/devin.svg +9 -0
- package/dist/dashboard/assets/providers/devin.svg.gz +0 -0
- package/dist/dashboard/assets/providers/windsurf.svg +10 -0
- package/dist/dashboard/assets/providers/windsurf.svg.gz +0 -0
- package/dist/dashboard/assets/{query-keys-YSoQOUh6.js → query-keys-IKLh0YFd.js} +1 -1
- package/dist/dashboard/assets/query-keys-IKLh0YFd.js.gz +0 -0
- package/dist/dashboard/assets/routing-Ckm1UXuC.js +1 -0
- package/dist/dashboard/assets/routing-Ckm1UXuC.js.gz +0 -0
- package/dist/dashboard/assets/{select-BCOcv8WK.js → select-ChoFWyKz.js} +1 -1
- package/dist/dashboard/assets/select-ChoFWyKz.js.gz +0 -0
- package/dist/dashboard/assets/settings-CKjFPlKW.js +1 -0
- package/dist/dashboard/assets/settings-CKjFPlKW.js.gz +0 -0
- package/dist/dashboard/assets/{stack-ByKt3Q1g.js → stack-DWCwU3fh.js} +1 -1
- package/dist/dashboard/assets/stack-DWCwU3fh.js.gz +0 -0
- package/dist/dashboard/assets/{state-DXbGTx7N.js → state-Cg3VL5J_.js} +1 -1
- package/dist/dashboard/assets/state-Cg3VL5J_.js.gz +0 -0
- package/dist/dashboard/assets/story/25817331.webp +0 -0
- package/dist/dashboard/assets/story/Shorekeeper.webp +0 -0
- package/dist/dashboard/assets/story/cartethyia-god.webp +0 -0
- package/dist/dashboard/assets/story/fleurdelys_plus.webp +0 -0
- package/dist/dashboard/assets/story/jinhsi-blossom.webp +0 -0
- package/dist/dashboard/assets/story/phrolova-a.webp +0 -0
- package/dist/dashboard/assets/story/requestdeniawokkjpg.webp +0 -0
- package/dist/dashboard/assets/story/wuthering-waves-hiyuki-aemeath-hiyuki-rover.webp +0 -0
- package/dist/dashboard/assets/{switch-ZeTsW623.js → switch-Db70BMix.js} +1 -1
- package/dist/dashboard/assets/switch-Db70BMix.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-CbCP4w1o.js → useMutation-BqdE0LuM.js} +1 -1
- package/dist/dashboard/assets/useMutation-BqdE0LuM.js.gz +0 -0
- package/dist/dashboard/console-backgrounds.webp +0 -0
- package/dist/dashboard/console-backgrounds_initial.webp +0 -0
- package/dist/dashboard/donation/qris-risun-marke.webp +0 -0
- package/dist/dashboard/index.html +3 -3
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +57 -55
- package/migrations/full-postgres/0044_add_models_warning_metadata.sql +10 -0
- package/migrations/full-postgres/0045_migrate_workbuddy_to_codebuddy.sql +156 -0
- package/migrations/lite-sqlite3/0044_add_models_warning_metadata.sql +11 -0
- package/migrations/lite-sqlite3/0045_migrate_workbuddy_to_codebuddy.sql +156 -0
- package/package.json +1 -1
- package/src/boot/dependencies.ts +11 -3
- package/src/config/cooldowns.ts +1 -1
- package/src/config/spec.ts +0 -6
- package/src/console/api-keys/routes.ts +11 -4
- package/src/console/console-router.ts +7 -0
- package/src/console/dashboard-assets.ts +5 -5
- package/src/console/domain-registration.ts +27 -0
- package/src/console/ip-bans/routes.ts +99 -0
- package/src/console/providers/catalog/catalog-projections.ts +5 -2
- package/src/console/providers/catalog/contracts.ts +123 -0
- package/src/console/providers/catalog/model-operations.ts +122 -10
- package/src/console/providers/catalog/provider-operations.ts +116 -8
- package/src/console/providers/catalog/public-model-store.ts +0 -0
- package/src/console/providers/catalog/routes.ts +64 -4
- package/src/console/providers/catalog/store-helpers.ts +30 -1
- package/src/console/providers/catalog/store.ts +243 -3
- package/src/console/quota/account-quota-global.ts +89 -1
- package/src/console/quota/native-identity.ts +2 -0
- package/src/console/settings/contracts.ts +18 -0
- package/src/console/settings/store.ts +32 -0
- package/src/console/system-prompt/contracts.ts +0 -1
- package/src/main.ts +1 -0
- package/src/observability/event-query.ts +18 -4
- package/src/persistence/dialect.ts +12 -0
- package/src/persistence/schema.ts +20 -2
- package/src/protocol/dsml.ts +1 -1
- package/src/protocol/gateway-error.ts +1 -0
- package/src/protocol/reasoning.ts +1 -1
- package/src/protocol/request/chat.ts +4 -4
- package/src/protocol/request/messages.ts +1 -1
- package/src/protocol/response/gemini.ts +6 -1
- package/src/protocol/sse-decoder.ts +25 -8
- package/src/protocol/stream-error-frames.ts +13 -3
- package/src/protocol/translation/quirks.ts +1 -1
- package/src/protocol/translation/tool-repair.ts +2 -2
- package/src/protocol/upstream/send-claude-messages.ts +15 -4
- package/src/protocol/upstream-parsing.ts +1 -1
- package/src/providers/adapters/compatible-adapter.ts +7 -5
- package/src/providers/authentication/oauth-refresh-service.ts +149 -36
- package/src/providers/default-registry.ts +68 -3
- package/src/providers/discovery/discovery-types.ts +12 -0
- package/src/providers/discovery/probe-phases.ts +61 -30
- package/src/providers/discovery/probing-service.ts +279 -164
- package/src/providers/integrations/antigravity/antigravity-protocol.ts +117 -2
- package/src/providers/integrations/antigravity/antigravity.ts +13 -2
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +72 -34
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +18 -18
- package/src/providers/integrations/buddy/buddy-checkin.ts +17 -39
- package/src/providers/integrations/buddy/buddy-conversation-headers.ts +2 -2
- package/src/providers/integrations/buddy/buddy-discovery-shared.ts +5 -5
- package/src/providers/integrations/buddy/buddy-identity.ts +70 -0
- package/src/providers/integrations/buddy/buddy-media.ts +4 -5
- package/src/providers/integrations/buddy/buddy-oauth-shared.ts +2 -2
- package/src/providers/integrations/buddy/buddy-quota-shared.ts +1 -1
- package/src/providers/integrations/buddy/buddy-usage-shared.ts +1 -3
- package/src/providers/integrations/buddy/capabilities.ts +4 -41
- package/src/providers/integrations/buddy/codebuddy/cn-catalog.ts +2 -1
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +20 -1
- package/src/providers/integrations/buddy/codebuddy/provider.ts +2 -2
- package/src/providers/integrations/buddy/codebuddy/shared.ts +6 -10
- package/src/providers/integrations/cursor/cursor-catalog.ts +2 -0
- package/src/providers/integrations/cursor/cursor-exec.ts +738 -0
- package/src/providers/integrations/cursor/cursor-http2.ts +2 -0
- package/src/providers/integrations/cursor/cursor-request.ts +9 -8
- package/src/providers/integrations/cursor/cursor-shared.ts +19 -1
- package/src/providers/integrations/cursor/cursor.ts +50 -30
- package/src/providers/integrations/cursor/protocol/tool-canonical.ts +26 -100
- package/src/providers/integrations/devin/devin-auth.ts +353 -0
- package/src/providers/integrations/devin/devin-catalog.ts +207 -0
- package/src/providers/integrations/devin/devin-http.ts +91 -0
- package/src/providers/integrations/devin/devin-quota.ts +214 -0
- package/src/providers/integrations/devin/devin-shared.ts +111 -0
- package/src/providers/integrations/devin/devin.ts +539 -0
- package/src/providers/integrations/devin/protocol/devin-proto.ts +584 -0
- package/src/providers/integrations/devin/protocol/framing.ts +124 -0
- package/src/providers/integrations/factory/factory.ts +2 -2
- package/src/providers/integrations/freepi/freepi-catalog.ts +60 -0
- package/src/providers/integrations/freepi/freepi-discovery.ts +82 -0
- package/src/providers/integrations/freepi/freepi-headers.ts +21 -0
- package/src/providers/integrations/freepi/freepi-oauth.ts +142 -0
- package/src/providers/integrations/freepi/freepi-protocol.ts +242 -0
- package/src/providers/integrations/freepi/freepi-quota.ts +126 -0
- package/src/providers/integrations/freepi/freepi-realm.ts +35 -0
- package/src/providers/integrations/freepi/freepi.ts +292 -0
- package/src/providers/integrations/gemini.ts +2 -2
- package/src/providers/integrations/hermes/hermes-oauth.ts +94 -0
- package/src/providers/integrations/hermes.ts +4 -12
- package/src/providers/integrations/opencode/fingerprint.ts +1 -1
- package/src/providers/integrations/perch/perch-catalog.ts +105 -0
- package/src/providers/integrations/perch/perch-oauth.ts +170 -0
- package/src/providers/integrations/perch/perch-protocol.ts +211 -0
- package/src/providers/integrations/perch/perch-quota.ts +137 -0
- package/src/providers/integrations/perch/perch-realm.ts +82 -0
- package/src/providers/integrations/perch/perch-system-prompt.ts +13 -0
- package/src/providers/integrations/perch/perch.ts +315 -0
- package/src/providers/integrations/perch/saffron-system-prompt.txt +8 -0
- package/src/providers/integrations/qoder/chat-proto.ts +328 -328
- package/src/providers/integrations/qoder/claim-qoder-credits.ts +1 -1
- package/src/providers/integrations/qoder/qoder-adapter.ts +89 -28
- package/src/providers/integrations/qoder/qoder-cache.ts +32 -0
- package/src/providers/integrations/qoder/qoder-catalog.ts +6 -1
- package/src/providers/integrations/qoder/qoder-checkin.ts +2 -2
- package/src/providers/integrations/qoder/qoder-grpc.ts +210 -6
- package/src/providers/integrations/qoder/qoder-ide.ts +5 -1
- package/src/providers/integrations/qoder/qoder-identity-cache.ts +184 -0
- package/src/providers/integrations/qoder/qoder-native-identity-store.ts +83 -18
- package/src/providers/integrations/qoder/qoder-realm.ts +9 -6
- package/src/providers/integrations/qoder/qoder-umid.ts +109 -342
- package/src/providers/integrations/qoder/qoder-virtual.ts +33 -1
- package/src/providers/integrations/qoder/qoder.ts +3 -6
- package/src/providers/integrations/trae/trae-catalog.ts +9 -14
- package/src/providers/integrations/trae/trae-headers.ts +36 -11
- package/src/providers/integrations/trae/trae-oauth.ts +14 -17
- package/src/providers/integrations/trae/trae-protocol.ts +3 -6
- package/src/providers/integrations/trae/trae-quota.ts +103 -21
- package/src/providers/integrations/trae/trae-realm.ts +36 -15
- package/src/providers/integrations/trae/trae.ts +97 -7
- package/src/providers/operations/account-error-classification.ts +66 -1
- package/src/providers/operations/account-health-service.ts +192 -26
- package/src/providers/operations/account-refresh-status.ts +284 -0
- package/src/providers/operations/account-tier.ts +67 -0
- package/src/providers/operations/client-versions.ts +37 -99
- package/src/providers/operations/cooldown-rules.ts +61 -0
- package/src/providers/operations/provider-catalog-seeder.ts +4 -0
- package/src/providers/provider-contracts.ts +29 -0
- package/src/providers/provider-metadata.ts +59 -4
- package/src/providers/provider-model-definition.ts +36 -0
- package/src/providers/quota/refresh.ts +21 -0
- package/src/security/abuse.ts +71 -0
- package/src/transport/dispatch/proxy-request.ts +1 -0
- package/src/transport/dispatch/streaming/stream.ts +1 -0
- package/src/transport/dispatch/upstream.ts +4 -1
- package/src/transport/failure-policy.ts +113 -7
- package/src/transport/routing/router.ts +25 -1
- package/src/transport/surface/messages/adapter.ts +2 -1
- package/src/transport/surface/responses/encode.ts +12 -1
- package/src/workers/daily-checkin.ts +1 -1
- package/src/workers/quota-refresh-sweep.ts +1 -1
- package/src/workers/scheduler.ts +22 -4
- package/dist/dashboard/assets/BannedPage-DeIbIiBU.js +0 -1
- package/dist/dashboard/assets/BannedPage-DeIbIiBU.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BRWKPQPf.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-BP-Y5iHN.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-B7JHozVa.js +0 -1
- package/dist/dashboard/assets/CombosPage-B7JHozVa.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-GX7iGGcu.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-GX7iGGcu.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-HVonbGEa.js +0 -1
- package/dist/dashboard/assets/CustomizationPage-HVonbGEa.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-xaut4OJ9.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-xaut4OJ9.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-Cv-2Ol_K.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-bKfz_b1K.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-B-WQxx_H.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-Z9pJZFo8.js +0 -1
- package/dist/dashboard/assets/OverviewPage-Z9pJZFo8.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CMeDBxR1.js +0 -7
- package/dist/dashboard/assets/ProviderDetailPage-CMeDBxR1.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js +0 -1
- package/dist/dashboard/assets/ProviderIcon-jjqXJDA3.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BXPdOpG4.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-BXPdOpG4.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-emlTuxz6.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-CMJKNYWb.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-BSy7EwGo.js +0 -1
- package/dist/dashboard/assets/SettingsPage-BSy7EwGo.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-CUZrKs9r.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-jWmUdDpy.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-5F9tGVGG.js +0 -56
- package/dist/dashboard/assets/UsagePage-5F9tGVGG.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-KvX83mRe.js +0 -1
- package/dist/dashboard/assets/api-keys-KvX83mRe.js.gz +0 -0
- package/dist/dashboard/assets/app-BEsU8hKs.css +0 -2
- package/dist/dashboard/assets/app-BEsU8hKs.css.gz +0 -0
- package/dist/dashboard/assets/assert-CidQVoNo.js +0 -1
- package/dist/dashboard/assets/assert-CidQVoNo.js.gz +0 -0
- package/dist/dashboard/assets/badge-DyI_mJfi.js.gz +0 -0
- package/dist/dashboard/assets/banner-B-yXtCqb.js.gz +0 -0
- package/dist/dashboard/assets/brand/bansos_page.png +0 -0
- package/dist/dashboard/assets/brand/denia_bansos.jpg +0 -0
- package/dist/dashboard/assets/brand/favicon.jpg +0 -0
- package/dist/dashboard/assets/brand/login_register.jpg +0 -0
- package/dist/dashboard/assets/brand/login_register_initial.jpg +0 -0
- package/dist/dashboard/assets/brand/og_bansos.jpg +0 -0
- package/dist/dashboard/assets/brand/og_image.jpg +0 -0
- package/dist/dashboard/assets/brand/sidebar_ico.jpg +0 -0
- package/dist/dashboard/assets/card-_HwAEqFF.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js +0 -1
- package/dist/dashboard/assets/cli-tools-Bwv5-zGZ.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-ByjCk0o9.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BZhOlfz-.js.gz +0 -0
- package/dist/dashboard/assets/drawer-BADqIRYP.js.gz +0 -0
- package/dist/dashboard/assets/entry-COaC-irN.js.gz +0 -0
- package/dist/dashboard/assets/entry-Ca7LSCet.js +0 -4
- package/dist/dashboard/assets/entry-Ca7LSCet.js.gz +0 -0
- package/dist/dashboard/assets/entry-PDd27uCd.js +0 -1
- package/dist/dashboard/assets/entry-PDd27uCd.js.gz +0 -0
- package/dist/dashboard/assets/formatters-DcHJyRiu.js.gz +0 -0
- package/dist/dashboard/assets/index-CgKmFngv.js.gz +0 -0
- package/dist/dashboard/assets/inline-B2BirKry.js.gz +0 -0
- package/dist/dashboard/assets/input-D-qV9dKY.js.gz +0 -0
- package/dist/dashboard/assets/layout-B7tVWhtV.js.gz +0 -0
- package/dist/dashboard/assets/list-row-CtkGE3bF.js.gz +0 -0
- package/dist/dashboard/assets/live-DGizF06-.js.gz +0 -0
- package/dist/dashboard/assets/minimize-2-BTmMTK4o.js +0 -1
- package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
- package/dist/dashboard/assets/mutation-GU7XdEjz.js.gz +0 -0
- package/dist/dashboard/assets/network-C9UE-bOr.js.gz +0 -0
- package/dist/dashboard/assets/numbers-BnAd22a_.js.gz +0 -0
- package/dist/dashboard/assets/pagination-BAywyMzS.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-YSoQOUh6.js.gz +0 -0
- package/dist/dashboard/assets/routing-fnCsxgNO.js +0 -1
- package/dist/dashboard/assets/routing-fnCsxgNO.js.gz +0 -0
- package/dist/dashboard/assets/select-BCOcv8WK.js.gz +0 -0
- package/dist/dashboard/assets/settings-BxslsErn.js +0 -1
- package/dist/dashboard/assets/settings-BxslsErn.js.gz +0 -0
- package/dist/dashboard/assets/stack-ByKt3Q1g.js.gz +0 -0
- package/dist/dashboard/assets/state-DXbGTx7N.js.gz +0 -0
- package/dist/dashboard/assets/switch-ZeTsW623.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-CbCP4w1o.js.gz +0 -0
- package/dist/dashboard/console-backgrounds.jpg +0 -0
- package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
- package/dist/dashboard/donation/qris-risun-marke.png +0 -0
- package/src/providers/integrations/buddy/turing-device-token.ts +0 -262
- package/src/providers/integrations/buddy/workbuddy/cn-oauth.ts +0 -30
- package/src/providers/integrations/buddy/workbuddy/cn-provider.ts +0 -58
- package/src/providers/integrations/buddy/workbuddy/oauth.ts +0 -31
- package/src/providers/integrations/buddy/workbuddy/provider.ts +0 -209
- package/src/providers/integrations/buddy/workbuddy/quota.ts +0 -161
- package/src/providers/integrations/buddy/workbuddy/shared.ts +0 -285
- /package/dist/dashboard/assets/{app-CTxoqyYB.js → app-B7kIWFm5.js} +0 -0
- /package/dist/dashboard/assets/{app-CTxoqyYB.js.gz → app-B7kIWFm5.js.gz} +0 -0
|
@@ -1,262 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* TuringShield device-token integration for the buddy providers.
|
|
3
|
-
*
|
|
4
|
-
* WorkBuddy/CodeBuddy desktop clients derive `X-Device-Token` from Tencent's
|
|
5
|
-
* TuringShield SDK (native addon + DLL, channel 400111). The upstream risk
|
|
6
|
-
* control expects that header on chat traffic, and the official desktop app
|
|
7
|
-
* always presents either a real token or an `X-Device-Token-Error` — never
|
|
8
|
-
* neither.
|
|
9
|
-
*
|
|
10
|
-
* The SDK is a proprietary native binary shipped inside this repository under
|
|
11
|
-
* `vendor/turing-sdk/` (extracted from the WorkBuddy desktop app, channel
|
|
12
|
-
* 400111). `CARTETHYIA_TURING_SDK_PATH` remains as an optional override for
|
|
13
|
-
* deployments that bring their own copy. When neither is present the service
|
|
14
|
-
* falls back to the same "sdk_not_initialized" failure state the desktop app
|
|
15
|
-
* emits when the SDK cannot run.
|
|
16
|
-
*
|
|
17
|
-
* Loading and calling the SDK is safe: `configure()` is local-only, and
|
|
18
|
-
* `fetchDeviceToken()` performs the SDK's normal network exchange with the
|
|
19
|
-
* Turing endpoint (the same call the desktop client makes). On platforms
|
|
20
|
-
* without native support (non-win32/darwin) the service degrades to the
|
|
21
|
-
* fallback.
|
|
22
|
-
*/
|
|
23
|
-
import { existsSync } from "node:fs";
|
|
24
|
-
import path from "node:path";
|
|
25
|
-
import { createHash } from "node:crypto";
|
|
26
|
-
import { log } from "../../../observability/logger";
|
|
27
|
-
import { resolvePackagePath } from "../../../config/package-paths";
|
|
28
|
-
|
|
29
|
-
/** Channel assigned to the WorkBuddy desktop product (see cli/product.json). */
|
|
30
|
-
export const TURING_CHANNEL_ID = 400111;
|
|
31
|
-
|
|
32
|
-
/** Per-provider SDK configuration (payload identity sent to Turing). */
|
|
33
|
-
export interface TuringSdkConfig {
|
|
34
|
-
readonly channelId: number;
|
|
35
|
-
readonly productName: string;
|
|
36
|
-
readonly productVersion: string;
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/** Canonical config for the WorkBuddy profile. */
|
|
40
|
-
export const WORKBUDDY_TURING_CONFIG: TuringSdkConfig = {
|
|
41
|
-
channelId: TURING_CHANNEL_ID,
|
|
42
|
-
productName: "WorkBuddy AI",
|
|
43
|
-
productVersion: "5.8.4",
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
/** Canonical config for the CodeBuddy profile (same SDK, distinct payload). */
|
|
47
|
-
export const CODEBUDDY_TURING_CONFIG: TuringSdkConfig = {
|
|
48
|
-
channelId: TURING_CHANNEL_ID,
|
|
49
|
-
productName: "CodeBuddy",
|
|
50
|
-
productVersion: "4.12.1",
|
|
51
|
-
};
|
|
52
|
-
|
|
53
|
-
/** Mirror the desktop client's service defaults (main-bootstrap.js). */
|
|
54
|
-
const DEFAULT_REQUEST_TIMEOUT_MS = 15_000;
|
|
55
|
-
const DEFAULT_REFRESH_INTERVAL_MS = 5 * 60_000;
|
|
56
|
-
const DEFAULT_RETRY_BASE_DELAY_MS = 30_000;
|
|
57
|
-
const DEFAULT_RETRY_MAX_DELAY_MS = 5 * 60_000;
|
|
58
|
-
const MAX_BACKOFF_LEVEL = 20;
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Resolve the directory holding the Turing SDK native files, or null.
|
|
62
|
-
*
|
|
63
|
-
* Priority: `CARTETHYIA_TURING_SDK_PATH` override → bundled copy in
|
|
64
|
-
* `vendor/turing-sdk/build/Release/` under the package root (works both in
|
|
65
|
-
* source and in the compiled binary, where `CARTETHYIA_PACKAGE_ROOT` points at
|
|
66
|
-
* `/app`).
|
|
67
|
-
*/
|
|
68
|
-
export function resolveTuringSdkRoot(): string | null {
|
|
69
|
-
const env = process.env["CARTETHYIA_TURING_SDK_PATH"];
|
|
70
|
-
if (env !== undefined && env.trim().length > 0) return env.trim();
|
|
71
|
-
// Bundled SDK (committed in vendor/).
|
|
72
|
-
const bundled = resolvePackagePath("vendor", "turing-sdk", "build", "Release");
|
|
73
|
-
if (existsSync(path.join(bundled, "turing_sdk.node"))) return bundled;
|
|
74
|
-
return null;
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
/** Pure header decision, matching the desktop app's `token || error` contract. */
|
|
78
|
-
export function turingHeadersForRequest(args: {
|
|
79
|
-
token?: string;
|
|
80
|
-
error?: string;
|
|
81
|
-
cliIdentity?: boolean;
|
|
82
|
-
}): Record<string, string> {
|
|
83
|
-
if (args.cliIdentity) return {};
|
|
84
|
-
const token = args.token?.trim();
|
|
85
|
-
if (token !== undefined && token.length > 0) return { "x-device-token": token };
|
|
86
|
-
const error = args.error?.trim();
|
|
87
|
-
if (error !== undefined && error.length > 0) return { "x-device-token-error": error };
|
|
88
|
-
return { "x-device-token-error": "sdk_not_initialized" };
|
|
89
|
-
}
|
|
90
|
-
|
|
91
|
-
/** Stable identifier for logs (never the token itself). */
|
|
92
|
-
function logDeviceFingerprint(): string {
|
|
93
|
-
const parts = [process.platform, process.arch, process.env["COMPUTERNAME"] ?? process.env["HOSTNAME"] ?? ""];
|
|
94
|
-
return createHash("sha256").update(parts.join("|")).digest("hex").slice(0, 12);
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export class TuringDeviceTokenService {
|
|
98
|
-
private binding: { configure(...a: unknown[]): unknown; fetchDeviceToken(o: unknown): unknown } | null = null;
|
|
99
|
-
private loadAttempted = false;
|
|
100
|
-
private configured = false;
|
|
101
|
-
|
|
102
|
-
private cachedToken: string | undefined;
|
|
103
|
-
private cachedError: string | undefined;
|
|
104
|
-
private cachedAt = 0;
|
|
105
|
-
private consecutiveFailures = 0;
|
|
106
|
-
private nextRetryAt = 0;
|
|
107
|
-
private inflight: Promise<string> | undefined;
|
|
108
|
-
|
|
109
|
-
constructor(private readonly config: TuringSdkConfig = WORKBUDDY_TURING_CONFIG) {}
|
|
110
|
-
|
|
111
|
-
private ensureLoaded(): boolean {
|
|
112
|
-
if (this.loadAttempted) return this.configured;
|
|
113
|
-
this.loadAttempted = true;
|
|
114
|
-
const root = resolveTuringSdkRoot();
|
|
115
|
-
if (root === null) {
|
|
116
|
-
log.warn("[turing-sdk] no SDK root (env unset & vendor missing); device token fallback active");
|
|
117
|
-
return false;
|
|
118
|
-
}
|
|
119
|
-
const nodePath = path.join(root, "turing_sdk.node");
|
|
120
|
-
if (!existsSync(nodePath)) {
|
|
121
|
-
log.warn("[turing-sdk] turing_sdk.node not found at " + nodePath);
|
|
122
|
-
return false;
|
|
123
|
-
}
|
|
124
|
-
try {
|
|
125
|
-
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
126
|
-
const loaded: unknown = require(nodePath);
|
|
127
|
-
if (loaded === null || typeof loaded !== "object" || typeof (loaded as Record<string, unknown>)["configure"] !== "function") {
|
|
128
|
-
log.warn("[turing-sdk] native addon loaded but exposes no configure()");
|
|
129
|
-
return false;
|
|
130
|
-
}
|
|
131
|
-
const binding = loaded as NonNullable<TuringDeviceTokenService["binding"]>;
|
|
132
|
-
binding.configure(this.config.channelId, this.config.productName, this.config.productVersion);
|
|
133
|
-
this.binding = binding;
|
|
134
|
-
this.configured = true;
|
|
135
|
-
log.info(
|
|
136
|
-
"[turing-sdk] native SDK configured (channel " + this.config.channelId +
|
|
137
|
-
", product " + this.config.productName + " " + this.config.productVersion +
|
|
138
|
-
", " + logDeviceFingerprint() + ")",
|
|
139
|
-
);
|
|
140
|
-
} catch (error) {
|
|
141
|
-
log.warn("[turing-sdk] failed to load/configure native SDK: " + (error instanceof Error ? error.message : String(error)));
|
|
142
|
-
this.binding = null;
|
|
143
|
-
}
|
|
144
|
-
return this.configured;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
/** Returns a real token when the SDK can produce one; undefined otherwise. */
|
|
148
|
-
async fetchDeviceToken(): Promise<string | undefined> {
|
|
149
|
-
if (!this.ensureLoaded()) return undefined;
|
|
150
|
-
const now = Date.now();
|
|
151
|
-
if (this.inflight) return this.inflight;
|
|
152
|
-
const task = this.performFetch().finally(() => {
|
|
153
|
-
this.inflight = undefined;
|
|
154
|
-
});
|
|
155
|
-
this.inflight = task;
|
|
156
|
-
try {
|
|
157
|
-
const token = await task;
|
|
158
|
-
this.cachedToken = token;
|
|
159
|
-
this.cachedError = undefined;
|
|
160
|
-
this.cachedAt = now;
|
|
161
|
-
this.consecutiveFailures = 0;
|
|
162
|
-
this.nextRetryAt = 0;
|
|
163
|
-
return token;
|
|
164
|
-
} catch (error) {
|
|
165
|
-
const message = error instanceof Error ? error.message : String(error);
|
|
166
|
-
this.cachedError = message.replace(/[^\x20-\x7E]/g, "").slice(0, 64);
|
|
167
|
-
this.consecutiveFailures += 1;
|
|
168
|
-
const level = Math.min(Math.max(0, this.consecutiveFailures - 1), MAX_BACKOFF_LEVEL);
|
|
169
|
-
const delay = Math.min(DEFAULT_RETRY_BASE_DELAY_MS * 2 ** level, DEFAULT_RETRY_MAX_DELAY_MS);
|
|
170
|
-
this.nextRetryAt = Date.now() + delay;
|
|
171
|
-
return undefined;
|
|
172
|
-
}
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
private async performFetch(): Promise<string> {
|
|
176
|
-
const binding = this.binding;
|
|
177
|
-
if (!binding) throw new Error("sdk_not_initialized");
|
|
178
|
-
const timeoutMs = DEFAULT_REQUEST_TIMEOUT_MS;
|
|
179
|
-
const promise = binding.fetchDeviceToken({
|
|
180
|
-
usingCachedMessage: true,
|
|
181
|
-
includesOutdatedMessage: false,
|
|
182
|
-
includesDeviceInfo: true,
|
|
183
|
-
timeoutMs,
|
|
184
|
-
});
|
|
185
|
-
const token = await this.withTimeout(Promise.resolve(promise) as Promise<string>, timeoutMs);
|
|
186
|
-
const text = typeof token === "string" ? token : String(token ?? "");
|
|
187
|
-
if (text.trim().length === 0) throw new Error("Turing SDK returned an empty device token");
|
|
188
|
-
return text.trim();
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
private async withTimeout(promise: Promise<string>, ms: number): Promise<string> {
|
|
192
|
-
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
193
|
-
try {
|
|
194
|
-
return await Promise.race([
|
|
195
|
-
promise,
|
|
196
|
-
new Promise<string>((_, reject) => {
|
|
197
|
-
timer = setTimeout(() => reject(new Error("Turing SDK device token request timed out after " + ms + "ms")), ms);
|
|
198
|
-
timer.unref?.();
|
|
199
|
-
}),
|
|
200
|
-
]);
|
|
201
|
-
} finally {
|
|
202
|
-
if (timer !== undefined) clearTimeout(timer);
|
|
203
|
-
}
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Headers for one buddy request. Ensures a cached token exists (refreshing
|
|
208
|
-
* in the background when stale), then returns the desktop `token || error`
|
|
209
|
-
* contract.
|
|
210
|
-
*/
|
|
211
|
-
async headersForRequest(cliIdentity?: boolean, requested?: TuringSdkConfig): Promise<Record<string, string>> {
|
|
212
|
-
// The Turing SDK rejects a channelId change after initialization. Keep the
|
|
213
|
-
// first config that actually configures the binding; later conflicting
|
|
214
|
-
// requests are warned once and keep serving the active token.
|
|
215
|
-
if (requested !== undefined) {
|
|
216
|
-
const activeOrMine = this.configured ? this.config : requested;
|
|
217
|
-
if (this.configured && (requested.channelId !== this.config.channelId || requested.productName !== this.config.productName)) {
|
|
218
|
-
log.warn("[turing-sdk] ignoring conflicting SDK config (channel " + requested.channelId + ", " + requested.productName + "); active is channel " + this.config.channelId + ", " + this.config.productName);
|
|
219
|
-
} else {
|
|
220
|
-
void activeOrMine;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
let token: string | undefined = this.cachedToken;
|
|
224
|
-
let error: string | undefined = this.cachedError;
|
|
225
|
-
const now = Date.now();
|
|
226
|
-
if (token === undefined) {
|
|
227
|
-
if (now < this.nextRetryAt) {
|
|
228
|
-
// Keep whatever we had; still within backoff.
|
|
229
|
-
} else {
|
|
230
|
-
token = await this.fetchDeviceToken();
|
|
231
|
-
if (token === undefined) error = this.cachedError;
|
|
232
|
-
}
|
|
233
|
-
} else if (now - this.cachedAt >= DEFAULT_REFRESH_INTERVAL_MS) {
|
|
234
|
-
// Stale: refresh opportunistically but keep serving the cached token.
|
|
235
|
-
void this.fetchDeviceToken();
|
|
236
|
-
}
|
|
237
|
-
return turingHeadersForRequest({
|
|
238
|
-
...(token === undefined ? {} : { token }),
|
|
239
|
-
...(error === undefined ? {} : { error }),
|
|
240
|
-
...(cliIdentity === undefined ? {} : { cliIdentity }),
|
|
241
|
-
});
|
|
242
|
-
}
|
|
243
|
-
}
|
|
244
|
-
|
|
245
|
-
/**
|
|
246
|
-
* Process-wide services keyed by their SDK config (channel/product). Each
|
|
247
|
-
* provider identity gets its own service so its payload (productName,
|
|
248
|
-
* productVersion) is used when the SDK is first configured. The underlying
|
|
249
|
-
* native addon is shared, but configure() runs per instance.
|
|
250
|
-
*/
|
|
251
|
-
const servicesByConfig = new Map<string, TuringDeviceTokenService>();
|
|
252
|
-
export function getTuringDeviceTokenService(
|
|
253
|
-
config: TuringSdkConfig = WORKBUDDY_TURING_CONFIG,
|
|
254
|
-
): TuringDeviceTokenService {
|
|
255
|
-
const key = `${config.channelId}:${config.productName}`;
|
|
256
|
-
let service = servicesByConfig.get(key);
|
|
257
|
-
if (service === undefined) {
|
|
258
|
-
service = new TuringDeviceTokenService(config);
|
|
259
|
-
servicesByConfig.set(key, service);
|
|
260
|
-
}
|
|
261
|
-
return service;
|
|
262
|
-
}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
// WorkBuddy CN device login shares WorkBuddy's contract on its China domain.
|
|
2
|
-
import {
|
|
3
|
-
buildWorkBuddyUserAgent,
|
|
4
|
-
getWorkBuddyCnClientVersion,
|
|
5
|
-
getWorkBuddyCliVersion,
|
|
6
|
-
} from "../../../operations/client-versions";
|
|
7
|
-
import { providerBaseUrl } from "../../../provider-metadata";
|
|
8
|
-
import {
|
|
9
|
-
BuddyOAuthClient,
|
|
10
|
-
coercingResponseCode,
|
|
11
|
-
type BuddyOAuthVariant,
|
|
12
|
-
} from "../buddy-oauth-shared";
|
|
13
|
-
import { WORKBUDDY_CN_DOMAIN } from "./cn-provider";
|
|
14
|
-
|
|
15
|
-
const baseUrl = providerBaseUrl("workbuddycn");
|
|
16
|
-
|
|
17
|
-
export const WORKBUDDY_CN_OAUTH_VARIANT: BuddyOAuthVariant = {
|
|
18
|
-
providerId: "workbuddycn",
|
|
19
|
-
providerLabel: "WorkBuddy CN",
|
|
20
|
-
domain: WORKBUDDY_CN_DOMAIN,
|
|
21
|
-
platform: "CLI",
|
|
22
|
-
userAgent: async () =>
|
|
23
|
-
buildWorkBuddyUserAgent(getWorkBuddyCnClientVersion(), getWorkBuddyCliVersion()),
|
|
24
|
-
deviceStartUrl: `${baseUrl}/v2/plugin/auth/state`,
|
|
25
|
-
devicePollUrl: `${baseUrl}/v2/plugin/auth/token`,
|
|
26
|
-
refreshUrl: `${baseUrl}/v2/plugin/auth/token/refresh`,
|
|
27
|
-
responseCode: coercingResponseCode,
|
|
28
|
-
};
|
|
29
|
-
|
|
30
|
-
export const workBuddyCnOAuthClient = new BuddyOAuthClient(WORKBUDDY_CN_OAUTH_VARIANT);
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
// WorkBuddy CN uses the WorkBuddy contract on its China domain.
|
|
2
|
-
import { BuddyMediaAdapter } from "../buddy-media";
|
|
3
|
-
import type { ProviderAdapter } from "../../../provider-contracts";
|
|
4
|
-
import type { DiscoveryInput } from "../../../discovery/discovery-types";
|
|
5
|
-
import type { ModelDefinition } from "../../../provider-model-definition";
|
|
6
|
-
import { providerBaseUrl } from "../../../provider-metadata";
|
|
7
|
-
import { getWorkBuddyCnClientVersion } from "../../../operations/client-versions";
|
|
8
|
-
import { BUDDY_CN_MODELS_PATH, fetchBuddyDirectoryModels } from "../buddy-discovery-shared";
|
|
9
|
-
import { CODEBUDDY_CN_MODELS } from "../codebuddy/cn-provider";
|
|
10
|
-
import { workbuddyPrePayload, WORKBUDDY_SYSTEM_PROMPT } from "./provider";
|
|
11
|
-
import { workbuddyAdapterConfig, workbuddyHeaders, WORKBUDDY_CHAT_PATH } from "./shared";
|
|
12
|
-
|
|
13
|
-
export const WORKBUDDY_CN_PROVIDER_ID = "workbuddycn" as const;
|
|
14
|
-
export const WORKBUDDY_CN_DOMAIN = "www.workbuddy.cn" as const;
|
|
15
|
-
export const WORKBUDDY_CN_BASE_URL = providerBaseUrl(WORKBUDDY_CN_PROVIDER_ID);
|
|
16
|
-
|
|
17
|
-
export const WORKBUDDY_CN_MODELS: readonly ModelDefinition[] = [
|
|
18
|
-
...CODEBUDDY_CN_MODELS.map((model) => ({
|
|
19
|
-
...model,
|
|
20
|
-
endpointPath: WORKBUDDY_CHAT_PATH,
|
|
21
|
-
})),
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
export async function discoverWorkBuddyCnModels(
|
|
25
|
-
input: DiscoveryInput,
|
|
26
|
-
): Promise<readonly ModelDefinition[] | null> {
|
|
27
|
-
return fetchBuddyDirectoryModels({
|
|
28
|
-
siteUrl: WORKBUDDY_CN_BASE_URL,
|
|
29
|
-
providerId: WORKBUDDY_CN_PROVIDER_ID,
|
|
30
|
-
credential: input.credential,
|
|
31
|
-
// The CN host answers the `/console/…` directory, exactly like the CodeBuddy
|
|
32
|
-
// CN host does; the international path was inherited from the intl provider
|
|
33
|
-
// and the CN edge answers it with a 500 rather than a 404.
|
|
34
|
-
modelsPath: BUDDY_CN_MODELS_PATH,
|
|
35
|
-
endpoint: WORKBUDDY_CHAT_PATH,
|
|
36
|
-
...(input.signal ? { signal: input.signal } : {}),
|
|
37
|
-
...(input.fetcher ? { fetcher: input.fetcher } : {}),
|
|
38
|
-
});
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
export function createWorkBuddyCnAdapter(fetchImpl?: typeof fetch): ProviderAdapter {
|
|
42
|
-
return new BuddyMediaAdapter(
|
|
43
|
-
workbuddyAdapterConfig({
|
|
44
|
-
providerId: WORKBUDDY_CN_PROVIDER_ID,
|
|
45
|
-
baseUrl: WORKBUDDY_CN_BASE_URL,
|
|
46
|
-
domain: WORKBUDDY_CN_DOMAIN,
|
|
47
|
-
prePayload: workbuddyPrePayload,
|
|
48
|
-
...(fetchImpl ? { fetchImpl } : {}),
|
|
49
|
-
}),
|
|
50
|
-
{
|
|
51
|
-
variant: "IDE",
|
|
52
|
-
systemPrompt: WORKBUDDY_SYSTEM_PROMPT,
|
|
53
|
-
baseUrl: WORKBUDDY_CN_BASE_URL,
|
|
54
|
-
buildHeaders: (context) =>
|
|
55
|
-
workbuddyHeaders(context, undefined, WORKBUDDY_CN_DOMAIN, getWorkBuddyCnClientVersion()),
|
|
56
|
-
},
|
|
57
|
-
);
|
|
58
|
-
}
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
// WorkBuddy OAuth — browser-assisted state polling (non-PKCE) plus refresh.
|
|
2
|
-
// Canonical provider ID: workbuddy (international / WorkBuddy AI).
|
|
3
|
-
import { providerBaseUrl } from "../../../provider-metadata";
|
|
4
|
-
import { buildWorkBuddyUserAgent } from "../../../operations/client-versions";
|
|
5
|
-
import {
|
|
6
|
-
BuddyOAuthClient,
|
|
7
|
-
coercingResponseCode,
|
|
8
|
-
type BuddyOAuthVariant,
|
|
9
|
-
} from "../buddy-oauth-shared";
|
|
10
|
-
import { WORKBUDDY_DOMAIN } from "./shared";
|
|
11
|
-
|
|
12
|
-
export const WORKBUDDY_DEVICE_START_URL = `${providerBaseUrl("workbuddy")}/v2/plugin/auth/state`;
|
|
13
|
-
export const WORKBUDDY_DEVICE_POLL_URL = `${providerBaseUrl("workbuddy")}/v2/plugin/auth/token`;
|
|
14
|
-
export const WORKBUDDY_REFRESH_URL = `${providerBaseUrl("workbuddy")}/v2/plugin/auth/token/refresh`;
|
|
15
|
-
|
|
16
|
-
/** The international WorkBuddy gateway: `CLI` platform, `WorkBuddy AI` identity. */
|
|
17
|
-
export const WORKBUDDY_OAUTH_VARIANT: BuddyOAuthVariant = {
|
|
18
|
-
providerId: "workbuddy",
|
|
19
|
-
providerLabel: "WorkBuddy",
|
|
20
|
-
domain: WORKBUDDY_DOMAIN,
|
|
21
|
-
platform: "CLI",
|
|
22
|
-
userAgent: async () => {
|
|
23
|
-
return buildWorkBuddyUserAgent();
|
|
24
|
-
},
|
|
25
|
-
deviceStartUrl: WORKBUDDY_DEVICE_START_URL,
|
|
26
|
-
devicePollUrl: WORKBUDDY_DEVICE_POLL_URL,
|
|
27
|
-
refreshUrl: WORKBUDDY_REFRESH_URL,
|
|
28
|
-
responseCode: coercingResponseCode,
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
export const workBuddyOAuthClient = new BuddyOAuthClient(WORKBUDDY_OAUTH_VARIANT);
|
|
@@ -1,209 +0,0 @@
|
|
|
1
|
-
// WorkBuddy international adapter — exact provider contract.
|
|
2
|
-
// Canonical provider ID: workbuddy
|
|
3
|
-
// Base (manifest-owned) → Chat: base + /v2/chat/completions
|
|
4
|
-
// Auth: Authorization Bearer for both api_key and oauth
|
|
5
|
-
// Stream: force stream=true upstream, factory reaggregates for non-stream callers
|
|
6
|
-
// Headers: official desktop-client identity (WorkBuddy AI brand) with fresh
|
|
7
|
-
// correlation IDs + account-stable device headers per dispatch
|
|
8
|
-
// Payload: leading WorkBuddy system prompt + typed user content, reasoning_summary
|
|
9
|
-
// auto only when reasoning_effort requested
|
|
10
|
-
|
|
11
|
-
import { BuddyMediaAdapter } from "../buddy-media";
|
|
12
|
-
import { providerBaseUrl } from "../../../provider-metadata";
|
|
13
|
-
import { GatewayError } from "../../../../protocol/gateway-error";
|
|
14
|
-
import type { CanonicalRequest } from "../../../../protocol/canonical-model";
|
|
15
|
-
import type { ProviderAdapter, ProviderDispatchContext, ProviderDispatchTarget } from "../../../provider-contracts";
|
|
16
|
-
import type { ModelDefinition } from "../../../provider-model-definition";
|
|
17
|
-
import type { DiscoveryInput } from "../../../discovery/discovery-types";
|
|
18
|
-
import {
|
|
19
|
-
WORKBUDDY_CHAT_PATH,
|
|
20
|
-
WORKBUDDY_DOMAIN,
|
|
21
|
-
workbuddyAdapterConfig,
|
|
22
|
-
workbuddyHeaders,
|
|
23
|
-
} from "./shared";
|
|
24
|
-
import {
|
|
25
|
-
BUDDY_SHARED_RAW,
|
|
26
|
-
BUDDY_IMAGE_MODEL_ID_SET,
|
|
27
|
-
BUDDY_VIDEO_MODEL_ID_SET,
|
|
28
|
-
makeBuddyModel,
|
|
29
|
-
makeBuddyImageModels,
|
|
30
|
-
makeBuddyVideoModels,
|
|
31
|
-
type BuddyRawEntry,
|
|
32
|
-
} from "../buddy-catalog-shared";
|
|
33
|
-
import { BUDDY_INTL_MODELS_PATH, fetchBuddyDirectoryModels } from "../buddy-discovery-shared";
|
|
34
|
-
import {
|
|
35
|
-
applyBuddySystemPrompt,
|
|
36
|
-
buddyPrePayloadCommon,
|
|
37
|
-
injectBuddyParallelToolCalls,
|
|
38
|
-
normalizeBuddyToolNames,
|
|
39
|
-
} from "../buddy-chat-shared";
|
|
40
|
-
|
|
41
|
-
// Constants — public contract
|
|
42
|
-
export const WORKBUDDY_PROVIDER_ID = "workbuddy" as const;
|
|
43
|
-
export const WORKBUDDY_BASE_URL = providerBaseUrl("workbuddy");
|
|
44
|
-
|
|
45
|
-
// Payload hook — provider semantics
|
|
46
|
-
// - force stream=true
|
|
47
|
-
// - reasoning_summary auto only when reasoning_effort requested
|
|
48
|
-
// - leading WorkBuddy system prompt + typed user content normalization
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Leading system turn for this variant.
|
|
52
|
-
*
|
|
53
|
-
* The upstream validates that the wire opens with a `system` turn and treats
|
|
54
|
-
* that prompt as the calling channel's identity: forwarding caller text in its
|
|
55
|
-
* place answers `400 · 11128 "Illegal API invocation from an unapproved
|
|
56
|
-
* channel"`. So this prompt is a wire contract, not merely a product choice —
|
|
57
|
-
* see the sibling in `codebuddy.ts`.
|
|
58
|
-
*
|
|
59
|
-
* The text is deliberately neutral: a simple helpful-assistant persona with no
|
|
60
|
-
* client/CLI branding, kept minimal so it reads naturally to any model and
|
|
61
|
-
* does not advertise a channel identity upstream.
|
|
62
|
-
*/
|
|
63
|
-
export const WORKBUDDY_SYSTEM_PROMPT = "You are a helpful assistant.";
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Reconstructs generic function declarations when a later tool-history turn
|
|
67
|
-
* arrives without the client's current `tools` array. WorkBuddy validates the
|
|
68
|
-
* Chat Completions envelope against every historical tool call, so forwarding
|
|
69
|
-
* `tool_calls`/`tool` messages without declarations yields model_param_invalid.
|
|
70
|
-
*/
|
|
71
|
-
function restoreHistoricalToolDefinitions(
|
|
72
|
-
payload: Record<string, unknown>,
|
|
73
|
-
messages: readonly Record<string, unknown>[],
|
|
74
|
-
): void {
|
|
75
|
-
const historicalNames = new Set<string>();
|
|
76
|
-
for (const message of messages) {
|
|
77
|
-
if (message["role"] !== "assistant" || !Array.isArray(message["tool_calls"])) continue;
|
|
78
|
-
for (const rawCall of message["tool_calls"]) {
|
|
79
|
-
if (!rawCall || typeof rawCall !== "object") continue;
|
|
80
|
-
const call = rawCall as Record<string, unknown>;
|
|
81
|
-
const functionValue =
|
|
82
|
-
call["function"] && typeof call["function"] === "object"
|
|
83
|
-
? (call["function"] as Record<string, unknown>)
|
|
84
|
-
: undefined;
|
|
85
|
-
const name = functionValue?.["name"];
|
|
86
|
-
if (typeof name === "string" && name.trim().length > 0) historicalNames.add(name);
|
|
87
|
-
}
|
|
88
|
-
}
|
|
89
|
-
if (historicalNames.size === 0) return;
|
|
90
|
-
|
|
91
|
-
const existing = Array.isArray(payload["tools"])
|
|
92
|
-
? (payload["tools"] as Array<Record<string, unknown>>)
|
|
93
|
-
: [];
|
|
94
|
-
const definedNames = new Set<string>();
|
|
95
|
-
for (const rawTool of existing) {
|
|
96
|
-
if (!rawTool || typeof rawTool !== "object") continue;
|
|
97
|
-
const tool = rawTool as Record<string, unknown>;
|
|
98
|
-
const functionValue =
|
|
99
|
-
tool["function"] && typeof tool["function"] === "object"
|
|
100
|
-
? (tool["function"] as Record<string, unknown>)
|
|
101
|
-
: tool;
|
|
102
|
-
if (typeof functionValue["name"] === "string") definedNames.add(functionValue["name"]);
|
|
103
|
-
}
|
|
104
|
-
const recovered = [...historicalNames]
|
|
105
|
-
.filter((name) => !definedNames.has(name))
|
|
106
|
-
.map((name) => ({
|
|
107
|
-
type: "function",
|
|
108
|
-
function: {
|
|
109
|
-
name,
|
|
110
|
-
description: "Recovered from historical tool calls.",
|
|
111
|
-
parameters: { type: "object", additionalProperties: true },
|
|
112
|
-
},
|
|
113
|
-
}));
|
|
114
|
-
if (recovered.length > 0) payload["tools"] = [...existing, ...recovered];
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
export function workbuddyPrePayload(
|
|
119
|
-
payload: Record<string, unknown>,
|
|
120
|
-
request: CanonicalRequest,
|
|
121
|
-
candidate: ProviderDispatchTarget,
|
|
122
|
-
context?: ProviderDispatchContext,
|
|
123
|
-
): void {
|
|
124
|
-
// International ladder. This hook is shared by `workbuddy` and `workbuddycn`
|
|
125
|
-
// (see workbuddy/cn-provider.ts): the CN effort ladders in the reference
|
|
126
|
-
// gateways are a CodeBuddy-CN concern, so `workbuddycn` deliberately stays on
|
|
127
|
-
// the intl table. Switch to `"cn"` only if a live CN WorkBuddy account proves
|
|
128
|
-
// it serves levels the intl table clamps.
|
|
129
|
-
buddyPrePayloadCommon(payload, request, "intl", context);
|
|
130
|
-
const rawModel = payload["model"];
|
|
131
|
-
const source =
|
|
132
|
-
typeof rawModel === "string" && rawModel.length > 0 ? rawModel : candidate.model_id;
|
|
133
|
-
if (!source) throw new GatewayError("invalid_request", 400, "WorkBuddy model is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
134
|
-
const messages = payload["messages"];
|
|
135
|
-
if (Array.isArray(messages)) {
|
|
136
|
-
const normalizedMessages = messages as Array<Record<string, unknown>>;
|
|
137
|
-
applyBuddySystemPrompt(
|
|
138
|
-
normalizedMessages,
|
|
139
|
-
WORKBUDDY_SYSTEM_PROMPT,
|
|
140
|
-
context?.tenant_system_prompt,
|
|
141
|
-
);
|
|
142
|
-
restoreHistoricalToolDefinitions(payload, normalizedMessages);
|
|
143
|
-
}
|
|
144
|
-
normalizeBuddyToolNames(payload);
|
|
145
|
-
injectBuddyParallelToolCalls(payload, request);
|
|
146
|
-
void request;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
// Model catalog — WorkBuddy international catalog.
|
|
150
|
-
// Static seed derived from the reference gateway's model.json (context/output
|
|
151
|
-
// limits) plus its global effort table; `reasoning` marks models with a
|
|
152
|
-
// declared reasoning-effort scale.
|
|
153
|
-
const WORKBUDDY_RAW: readonly BuddyRawEntry[] = BUDDY_SHARED_RAW;
|
|
154
|
-
|
|
155
|
-
function makeWorkBuddyModels(providerId: "workbuddy" | "workbuddycn"): readonly ModelDefinition[] {
|
|
156
|
-
return [
|
|
157
|
-
...WORKBUDDY_RAW.filter(
|
|
158
|
-
(entry) => !BUDDY_IMAGE_MODEL_ID_SET.has(entry[0]) && !BUDDY_VIDEO_MODEL_ID_SET.has(entry[0]),
|
|
159
|
-
).map((entry) => makeBuddyModel(entry, providerId, WORKBUDDY_CHAT_PATH)),
|
|
160
|
-
// WorkBuddy's base URL carries no version segment, so the image rows need the
|
|
161
|
-
// same explicit path the chat rows use — the generic default would produce a
|
|
162
|
-
// URL this upstream answers with a 405.
|
|
163
|
-
...makeBuddyImageModels(providerId, WORKBUDDY_CHAT_PATH),
|
|
164
|
-
...makeBuddyVideoModels(providerId, "/v2/videos/generations"),
|
|
165
|
-
];
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
export const WORKBUDDY_MODELS: readonly ModelDefinition[] = makeWorkBuddyModels("workbuddy");
|
|
169
|
-
|
|
170
|
-
/**
|
|
171
|
-
* Reads WorkBuddy's live console directory.
|
|
172
|
-
*
|
|
173
|
-
* The static `WORKBUDDY_MODELS` above is the fallback: this is what the "Fetch
|
|
174
|
-
* models" action persists, and it carries the upstream's own limits and
|
|
175
|
-
* capability flags rather than the seed's snapshot of them.
|
|
176
|
-
*/
|
|
177
|
-
export async function discoverWorkBuddyModels(
|
|
178
|
-
input: DiscoveryInput,
|
|
179
|
-
): Promise<readonly ModelDefinition[] | null> {
|
|
180
|
-
return fetchBuddyDirectoryModels({
|
|
181
|
-
siteUrl: WORKBUDDY_BASE_URL,
|
|
182
|
-
providerId: WORKBUDDY_PROVIDER_ID,
|
|
183
|
-
credential: input.credential,
|
|
184
|
-
modelsPath: BUDDY_INTL_MODELS_PATH,
|
|
185
|
-
endpoint: WORKBUDDY_CHAT_PATH,
|
|
186
|
-
...(input.signal ? { signal: input.signal } : {}),
|
|
187
|
-
...(input.fetcher ? { fetcher: input.fetcher } : {}),
|
|
188
|
-
});
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
// Public factory — uses the OpenAI-compatible factory but forces provider semantics.
|
|
192
|
-
// Supports both api_key and oauth via Authorization Bearer (factory handles both).
|
|
193
|
-
export function createWorkBuddyAdapter(fetchImpl?: typeof fetch): ProviderAdapter {
|
|
194
|
-
return new BuddyMediaAdapter(
|
|
195
|
-
workbuddyAdapterConfig({
|
|
196
|
-
providerId: WORKBUDDY_PROVIDER_ID,
|
|
197
|
-
baseUrl: WORKBUDDY_BASE_URL,
|
|
198
|
-
prePayload: workbuddyPrePayload,
|
|
199
|
-
...(fetchImpl ? { fetchImpl } : {}),
|
|
200
|
-
}),
|
|
201
|
-
{
|
|
202
|
-
variant: "IDE",
|
|
203
|
-
systemPrompt: WORKBUDDY_SYSTEM_PROMPT,
|
|
204
|
-
baseUrl: WORKBUDDY_BASE_URL,
|
|
205
|
-
buildHeaders: (context, request) =>
|
|
206
|
-
workbuddyHeaders(context, request, WORKBUDDY_DOMAIN, undefined, true),
|
|
207
|
-
},
|
|
208
|
-
);
|
|
209
|
-
}
|