cartethyia 2.7.4 → 2.7.5
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 +2 -0
- package/README.md +17 -5
- package/dist/dashboard/assets/{BannedPage-ChG5svFb.js → BannedPage-Cj15GsMp.js} +1 -1
- package/dist/dashboard/assets/BannedPage-Cj15GsMp.js.gz +0 -0
- package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js +1 -0
- package/dist/dashboard/assets/ClaimGiftsButton-D83pBJ6J.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-BIcWQun7.js → CliToolDetailPage-DZKmVuJN.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-Bf2VelDe.js → CliToolsPage-BIccZmeL.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BIccZmeL.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DEEKkYD-.js +1 -0
- package/dist/dashboard/assets/CombosPage-DEEKkYD-.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-D5rol2j2.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-ggeMSjte.js → CustomizationPage-BKj_r0rp.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-BKj_r0rp.js.gz +0 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js +656 -0
- package/dist/dashboard/assets/InjectSystemPromptPanel-B5nZvmf0.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-U6AKaJcF.js → LoginPage-DkXb6dx-.js} +1 -1
- package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-BMS2t8BA.js → ModelPicker-DnQPSIA8.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-DnQPSIA8.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js +1 -0
- package/dist/dashboard/assets/OverviewPage-Ci2wQKUz.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js +5 -0
- package/dist/dashboard/assets/ProviderDetailPage-odlgYrOg.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-EfeloBn4.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-CqFBQEB8.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-lsrx7NYg.js → ProxyPage-5SnUSy3j.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-5SnUSy3j.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js +1 -0
- package/dist/dashboard/assets/QuotaPage-CmnMDzhP.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js +1 -0
- package/dist/dashboard/assets/SettingsPage-BJtRZ4qD.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-f0DE1h0-.js → SetupPage-WTa0sktC.js} +1 -1
- package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-Cq5tW7hW.js → StudioPage-BfAb5-o_.js} +3 -3
- package/dist/dashboard/assets/StudioPage-BfAb5-o_.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js +56 -0
- package/dist/dashboard/assets/UsagePage-BNzeZ2Vk.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-l29JROPv.js +1 -0
- package/dist/dashboard/assets/api-keys-l29JROPv.js.gz +0 -0
- package/dist/dashboard/assets/app--PJWq8_C.css +2 -0
- package/dist/dashboard/assets/app--PJWq8_C.css.gz +0 -0
- package/dist/dashboard/assets/assert-C0K-c4eo.js +1 -0
- package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
- package/dist/dashboard/assets/{badge-D9CS6dZk.js → badge-DfbhQU4k.js} +1 -1
- package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
- package/dist/dashboard/assets/{banner-DympBNq4.js → banner-BllT4LcF.js} +1 -1
- package/dist/dashboard/assets/banner-BllT4LcF.js.gz +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/{card-ibRWU_uT.js → card-CtkX66Wd.js} +1 -1
- package/dist/dashboard/assets/card-CtkX66Wd.js.gz +0 -0
- package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js +1 -0
- package/dist/dashboard/assets/chevron-left-Bf6CaTSJ.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-CQXVMn4P.js +1 -0
- package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-DJm-9pz7.js → clipboard-button-BQqBQd2n.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-8fiE6tec.js → dialog-BEK7KP0H.js} +1 -1
- package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-CqGYeOrd.js → drawer-BrTEZ8zu.js} +1 -1
- package/dist/dashboard/assets/drawer-BrTEZ8zu.js.gz +0 -0
- package/dist/dashboard/assets/entry-CHWxbS56.js +1 -0
- package/dist/dashboard/assets/entry-CHWxbS56.js.gz +0 -0
- package/dist/dashboard/assets/{entry-BSAsYsmV.js → entry-EBHJ3DrE.js} +1 -1
- package/dist/dashboard/assets/entry-EBHJ3DrE.js.gz +0 -0
- package/dist/dashboard/assets/entry-LCS85hiq.js +4 -0
- package/dist/dashboard/assets/entry-LCS85hiq.js.gz +0 -0
- package/dist/dashboard/assets/{formatters-D-MTJxMr.js → formatters-BAACA727.js} +1 -1
- package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-CPK47xQx.js → github-badge-YSCE4UC2.js} +1 -1
- package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
- package/dist/dashboard/assets/{index-DBNPOfhV.js → index-FQlj0HUT.js} +2 -2
- package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BT0zntEr.js → inline-C4gU5iOL.js} +1 -1
- package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
- package/dist/dashboard/assets/{input-Da2ZViWg.js → input-BHHX_Tmm.js} +1 -1
- package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
- package/dist/dashboard/assets/{layout-BXNeLw6M.js → layout-CajrYUnD.js} +1 -1
- package/dist/dashboard/assets/layout-CajrYUnD.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-BycOrrIV.js → list-row-Bx2I7XUe.js} +1 -1
- package/dist/dashboard/assets/list-row-Bx2I7XUe.js.gz +0 -0
- package/dist/dashboard/assets/live-DNNqRbj2.js +1 -0
- package/dist/dashboard/assets/live-DNNqRbj2.js.gz +0 -0
- package/dist/dashboard/assets/network-C5UBACrJ.js +1 -0
- package/dist/dashboard/assets/network-C5UBACrJ.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CUWAZK4J.js +2 -0
- package/dist/dashboard/assets/numbers-CUWAZK4J.js.gz +0 -0
- package/dist/dashboard/assets/pagination-Xsi9Qx04.js +1 -0
- package/dist/dashboard/assets/pagination-Xsi9Qx04.js.gz +0 -0
- package/dist/dashboard/assets/quota-DvQbD_sr.js +1 -0
- package/dist/dashboard/assets/quota-DvQbD_sr.js.gz +0 -0
- package/dist/dashboard/assets/routing-in0f_IfK.js +1 -0
- package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
- package/dist/dashboard/assets/{select-BIYIBkMU.js → select-BLULNqTp.js} +1 -1
- package/dist/dashboard/assets/select-BLULNqTp.js.gz +0 -0
- package/dist/dashboard/assets/settings-CcGczj6I.js +1 -0
- package/dist/dashboard/assets/settings-CcGczj6I.js.gz +0 -0
- package/dist/dashboard/assets/shield-BMQNxORh.js +1 -0
- package/dist/dashboard/assets/shield-BMQNxORh.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DfgnFDWY.js → stack-D2lIR0tg.js} +1 -1
- package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
- package/dist/dashboard/assets/{state-CkfdYWel.js → state-DTARjfiW.js} +1 -1
- package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
- package/dist/dashboard/assets/{switch-SYm237HG.js → switch-c0oPSnqW.js} +1 -1
- package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-BQqCRNIi.js → useMutation-m8WGNPrz.js} +1 -1
- package/dist/dashboard/assets/useMutation-m8WGNPrz.js.gz +0 -0
- package/dist/dashboard/console-backgrounds.jpg +0 -0
- package/dist/dashboard/console-backgrounds_initial.jpg +0 -0
- package/dist/dashboard/index.html +2 -2
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +56 -55
- package/migrations/full-postgres/0036_system_prompt_presets_refs.sql +10 -0
- package/migrations/full-postgres/0037_share_concurrency_scope.sql +3 -0
- package/migrations/full-postgres/0038_add_accounts_quota_snapshot.sql +7 -0
- package/migrations/full-postgres/0039_add_telemetry_provider_model_indexes.sql +13 -0
- package/migrations/full-postgres/0040_add_models_dialect.sql +3 -0
- package/migrations/full-postgres/0041_add_daily_checkin_ledger_account_fk.sql +7 -0
- package/migrations/lite-sqlite3/0036_system_prompt_presets_refs.sql +14 -0
- package/migrations/lite-sqlite3/0037_share_concurrency_scope.sql +3 -0
- package/migrations/lite-sqlite3/0038_add_accounts_quota_snapshot.sql +4 -0
- package/migrations/lite-sqlite3/0039_add_telemetry_provider_model_indexes.sql +6 -0
- package/migrations/lite-sqlite3/0040_add_models_dialect.sql +3 -0
- package/migrations/lite-sqlite3/0041_add_daily_checkin_ledger_account_fk.sql +26 -0
- package/package.json +4 -6
- package/scripts/cli/update.ts +15 -41
- package/src/boot/app.ts +58 -2
- package/src/boot/dependencies.ts +786 -732
- package/src/boot/lifecycle.ts +11 -12
- package/src/config/cooldowns.ts +34 -55
- package/src/config/network.ts +1 -1
- package/src/config/package-paths.ts +1 -1
- package/src/config/providers.ts +13 -14
- package/src/config/resources.ts +0 -5
- package/src/config/runtime.ts +2 -5
- package/src/config/spec.ts +26 -6
- package/src/console/api-keys/ban-constants.ts +38 -0
- package/src/console/api-keys/contracts.ts +71 -62
- package/src/console/api-keys/routes.ts +48 -12
- package/src/console/auth/access.ts +4 -4
- package/src/console/auth/account-reset.ts +1 -1
- package/src/console/auth/audit-recorder.ts +1 -1
- package/src/console/auth/lockout.ts +7 -3
- package/src/console/auth/row-coercion.ts +57 -12
- package/src/console/auth/session-resolver.ts +1 -1
- package/src/console/auth/session-service.ts +8 -2
- package/src/console/auth/session.ts +37 -31
- package/src/console/auth/setup-service.ts +4 -3
- package/src/console/auth/user-store.ts +1 -1
- package/src/console/backup/9router-map.ts +0 -3
- package/src/console/backup/contracts.ts +9 -9
- package/src/console/backup/export-endpoint.ts +5 -6
- package/src/console/backup/nine-router.ts +1 -7
- package/src/console/backup/routes.ts +29 -33
- package/src/console/backup/service.ts +468 -468
- package/src/console/backup/store.ts +47 -29
- package/src/console/backup/validate.ts +11 -1
- package/src/console/cli-tools/contracts.ts +7 -7
- package/src/console/cli-tools/injectors/cline.ts +110 -110
- package/src/console/cli-tools/injectors/codex.ts +181 -181
- package/src/console/cli-tools/injectors/copilot.ts +108 -108
- package/src/console/cli-tools/injectors/driver.ts +247 -247
- package/src/console/cli-tools/injectors/jcode.ts +115 -115
- package/src/console/cli-tools/injectors/openclaw.ts +161 -161
- package/src/console/cli-tools/injectors/opencode.ts +153 -153
- package/src/console/cli-tools/routes.ts +1 -1
- package/src/console/cli-tools/service.ts +1 -1
- package/src/console/cli-tools/store.ts +2 -2
- package/src/console/console-router.ts +32 -0
- package/src/console/dashboard-assets.ts +9 -9
- package/src/console/domain-registration.ts +16 -2
- package/src/console/inferhub/client.ts +0 -7
- package/src/console/inferhub/key-store.ts +1 -1
- package/src/console/inferhub/normalize.ts +2 -2
- package/src/console/inferhub/routes.ts +1 -1
- package/src/console/inferhub/types.ts +1 -1
- package/src/console/observability/contracts.ts +1 -1
- package/src/console/observability/live.ts +31 -18
- package/src/console/observability/logs.ts +1 -1
- package/src/console/observability/sse.ts +62 -8
- package/src/console/observability/store.ts +20 -4
- package/src/console/providers/catalog/catalog-projections.ts +1 -1
- package/src/console/providers/catalog/contracts.ts +39 -0
- package/src/console/providers/catalog/model-operations.ts +1 -1
- package/src/console/providers/catalog/provider-operations.ts +95 -17
- package/src/console/providers/catalog/public-model-store.ts +0 -0
- package/src/console/providers/catalog/routes.ts +27 -3
- package/src/console/providers/catalog/store.ts +147 -8
- package/src/console/providers/detail/routes.ts +1 -1
- package/src/console/providers/oauth/callback-listener.ts +100 -18
- package/src/console/providers/oauth/routes.ts +92 -13
- package/src/console/quota/account-quota-global.ts +41 -3
- package/src/console/quota/account-quota-shared.ts +10 -3
- package/src/console/quota/account-quota-tenant.ts +259 -66
- package/src/console/quota/daily-growth-job.ts +308 -0
- package/src/console/quota/native-identity.ts +2 -2
- package/src/console/quota/quota-view.ts +1 -1
- package/src/console/remote-support/routes.ts +1 -1
- package/src/console/remote-support/service.ts +2 -2
- package/src/console/routing/model/contracts.ts +1 -1
- package/src/console/routing/pools/contracts.ts +2 -2
- package/src/console/routing/pools/import-parse.ts +3 -3
- package/src/console/routing/pools/relay-deploy.ts +3 -3
- package/src/console/settings/contracts.ts +29 -2
- package/src/console/settings/store.ts +20 -0
- package/src/console/share/share-router.ts +100 -32
- package/src/console/share/share-stats.ts +4 -4
- package/src/console/share/share-usage.ts +1 -1
- package/src/console/shared/errors.ts +2 -2
- package/src/console/shared/object.ts +18 -0
- package/src/console/shared/read-through-cache.ts +4 -4
- package/src/console/shared/transaction.ts +14 -0
- package/src/console/system-prompt/contracts.ts +89 -12
- package/src/console/system-prompt/routes.ts +98 -45
- package/src/console/updates/apply-update.ts +244 -0
- package/src/console/updates/routes.ts +252 -97
- package/src/main.ts +11 -5
- package/src/network/http2-bidi.ts +1 -1
- package/src/network/ip-utils.ts +298 -0
- package/src/network/outbound-fetch.ts +1 -1
- package/src/network/pool/agent.ts +7 -6
- package/src/network/pool/byte-accounting.ts +1 -1
- package/src/network/pool/resolver.ts +16 -12
- package/src/network/pool/selector.ts +150 -136
- package/src/network/pool-health-machine.ts +1 -1
- package/src/network/rate-limit-verdict.ts +1 -1
- package/src/network/retry.ts +1 -1
- package/src/network/ssrf.ts +20 -71
- package/src/observability/event-log.ts +2 -2
- package/src/observability/event-query.ts +59 -291
- package/src/observability/log-sanitize.ts +1 -1
- package/src/observability/metrics.ts +4 -4
- package/src/observability/payload-capture.ts +6 -5
- package/src/observability/payload-store.ts +1 -1
- package/src/observability/runtime-metrics.ts +1 -1
- package/src/observability/telemetry-buffer.ts +12 -3
- package/src/observability/telemetry-reconciliation.ts +3 -3
- package/src/observability/token-speed.ts +1 -1
- package/src/persistence/connection-url.ts +1 -1
- package/src/persistence/db-handle.ts +1 -1
- package/src/persistence/db-pg.ts +2 -2
- package/src/persistence/db-sqlite.ts +3 -3
- package/src/persistence/dialect.ts +5 -1
- package/src/persistence/readiness.ts +1 -1
- package/src/persistence/redis.ts +1 -1
- package/src/persistence/schema.ts +113 -40
- package/src/persistence/shared-cache.ts +2 -2
- package/src/persistence/sort-order.ts +1 -1
- package/src/persistence/stores/api-key-store.ts +10 -1
- package/src/persistence/stores/share-store.ts +20 -8
- package/src/persistence/system-prompt-store.ts +63 -18
- package/src/persistence/tenant-preferences.ts +1 -1
- package/src/persistence/ttl-cache.ts +3 -3
- package/src/persistence/usage-flush.ts +7 -2
- package/src/protocol/canonical-model.ts +1 -1
- package/src/protocol/codecs.ts +6 -10
- package/src/protocol/dsml.ts +3 -49
- package/src/protocol/image-clamp.ts +2 -2
- package/src/protocol/reasoning-text.ts +1 -1
- package/src/protocol/reasoning.ts +7 -52
- package/src/protocol/registry.ts +50 -15
- package/src/protocol/request/chat.ts +46 -19
- package/src/protocol/request/codex.ts +1 -1
- package/src/protocol/request/messages.ts +46 -14
- package/src/protocol/request/responses.ts +19 -10
- package/src/protocol/response/chat.ts +25 -10
- package/src/protocol/response/codex.ts +1 -1
- package/src/protocol/response/messages.ts +1 -1
- package/src/protocol/response/omp-tool-call-markup.ts +1 -1
- package/src/protocol/response/responses.ts +1 -1
- package/src/protocol/sse-decoder.ts +50 -1
- package/src/protocol/stop-reason.ts +2 -2
- package/src/protocol/think-split.ts +347 -0
- package/src/protocol/translation/attachment-integrity.ts +3 -3
- package/src/protocol/translation/cache-controls.ts +8 -20
- package/src/protocol/translation/capabilities.ts +6 -6
- package/src/protocol/translation/dialect/deepseek.ts +10 -0
- package/src/protocol/translation/dialect/inband.ts +39 -0
- package/src/protocol/translation/dialect/model-thinking.ts +89 -0
- package/src/protocol/translation/dialect/qwen.ts +114 -0
- package/src/protocol/translation/dialect/resolver.ts +83 -0
- package/src/protocol/translation/dialect/rules.ts +93 -0
- package/src/protocol/translation/dialect/thinking-ladder.ts +245 -0
- package/src/protocol/translation/dialect/types.ts +58 -0
- package/src/protocol/translation/quirks.ts +18 -4
- package/src/protocol/translation/thinking.ts +12 -252
- package/src/protocol/translation/tool-id.ts +3 -3
- package/src/protocol/translation/tool-repair.ts +1 -1
- package/src/protocol/upstream/post-json.ts +6 -1
- package/src/providers/adapters/compatible-adapter.ts +42 -3
- package/src/providers/authentication/jwt-validator.ts +0 -5
- package/src/providers/authentication/oauth-client.ts +254 -253
- package/src/providers/authentication/oauth-flow-store.ts +42 -7
- package/src/providers/bundled-discovery-providers.ts +6 -30
- package/src/providers/configured-openai-providers.ts +82 -97
- package/src/providers/default-registry.ts +23 -35
- package/src/providers/discovery/catalog/catalog-format.ts +13 -2
- package/src/providers/discovery/discovery-types.ts +0 -1
- package/src/providers/discovery/openai-model-discovery.ts +2 -2
- package/src/providers/discovery/probe-phases.ts +48 -13
- package/src/providers/discovery/probing-service.ts +6 -8
- package/src/providers/integrations/agentrouter/agentrouter.ts +12 -2
- package/src/providers/integrations/antigravity/antigravity-oauth.ts +0 -1
- package/src/providers/integrations/antigravity/antigravity-protocol.ts +0 -14
- package/src/providers/integrations/antigravity/antigravity.ts +2 -2
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +1 -1
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +20 -4
- package/src/providers/integrations/buddy/buddy-cli-headers.ts +19 -52
- package/src/providers/integrations/buddy/buddy-identity.ts +86 -0
- package/src/providers/integrations/buddy/buddy-oauth-shared.ts +1 -1
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +1 -2
- package/src/providers/integrations/buddy/codebuddy/provider.ts +4 -15
- package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
- package/src/providers/integrations/buddy/workbuddy/provider.ts +5 -9
- package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
- package/src/providers/integrations/claude/claude-cch.ts +148 -148
- package/src/providers/integrations/claude/fallback-credit.ts +3 -7
- package/src/providers/integrations/cline/cline.ts +1 -1
- package/src/providers/integrations/codex/codex-device-code.ts +101 -101
- package/src/providers/integrations/codex/codex-oauth.ts +0 -1
- package/src/providers/integrations/commandcode/commandcode.ts +75 -115
- package/src/providers/integrations/commandcode/quota.ts +131 -51
- package/src/providers/integrations/cursor/cursor-http2.ts +0 -3
- package/src/providers/integrations/cursor/cursor-quota.ts +2 -6
- package/src/providers/integrations/cursor/cursor-request.ts +0 -87
- package/src/providers/integrations/cursor/cursor-shared.ts +0 -4
- package/src/providers/integrations/cursor/cursor.ts +38 -5
- package/src/providers/integrations/cursor/protocol/framing.ts +0 -56
- package/src/providers/integrations/cursor/protocol/messages.ts +0 -96
- package/src/providers/integrations/factory/factory.ts +9 -9
- package/src/providers/integrations/github/github-discovery.ts +55 -10
- package/src/providers/integrations/github/github-oauth.ts +6 -5
- package/src/providers/integrations/github/github.ts +41 -14
- package/src/providers/integrations/grok/grok-oauth.ts +261 -261
- package/src/providers/integrations/grok/grok-quota-frame.ts +1 -1
- package/src/providers/integrations/grok/grok-quota.ts +16 -7
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +0 -5
- package/src/providers/integrations/grok/grok-ratelimit.ts +3 -0
- package/src/providers/integrations/grok/grok.ts +86 -36
- package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
- package/src/providers/integrations/kiro/kiro-cache.ts +31 -0
- package/src/providers/integrations/kiro/kiro-catalog.ts +31 -5
- package/src/providers/integrations/kiro/kiro-discovery.ts +47 -43
- package/src/providers/integrations/kiro/kiro-machine-id.ts +6 -3
- package/src/providers/integrations/kiro/kiro-oauth.ts +523 -255
- package/src/providers/integrations/kiro/kiro-quota.ts +35 -47
- package/src/providers/integrations/kiro/kiro-request.ts +8 -11
- package/src/providers/integrations/kiro/kiro-stream.ts +13 -0
- package/src/providers/integrations/kiro/kiro.ts +81 -68
- package/src/providers/integrations/muse/muse-oauth.ts +0 -1
- package/src/providers/integrations/muse/muse-quota.ts +0 -4
- package/src/providers/integrations/opencode/fingerprint.ts +7 -5
- package/src/providers/integrations/opencode/provider.ts +17 -24
- package/src/providers/integrations/qoder/qoder-catalog.ts +85 -8
- package/src/providers/integrations/qoder/qoder-oauth.ts +165 -25
- package/src/providers/integrations/qoder/qoder-quota.ts +48 -6
- package/src/providers/integrations/qoder/qoder-realm.ts +10 -31
- package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
- package/src/providers/integrations/qoder/qoder-umid.ts +21 -25
- package/src/providers/integrations/qoder/qoder-virtual.ts +12 -0
- package/src/providers/integrations/qoder/qoder.ts +354 -62
- package/src/providers/integrations/shared/connect.ts +0 -54
- package/src/providers/integrations/shared/hash.ts +15 -0
- package/src/providers/integrations/shared/session-cache.ts +136 -0
- package/src/providers/integrations/trae/trae-cache.ts +7 -87
- package/src/providers/integrations/trae/trae-catalog.ts +1 -6
- package/src/providers/integrations/trae/trae-protocol.ts +17 -8
- package/src/providers/integrations/trae/trae-realm.ts +0 -7
- package/src/providers/integrations/trae/trae.ts +53 -10
- package/src/providers/integrations/xai/xai-oauth.ts +5 -5
- package/src/providers/integrations/zcode-start-plan/gifts.ts +265 -0
- package/src/providers/integrations/zcode-start-plan/oauth.ts +154 -0
- package/src/providers/integrations/zcode-start-plan/provider.ts +131 -0
- package/src/providers/integrations/zcode-start-plan/quota.ts +152 -0
- package/src/providers/integrations/zcode-start-plan/zcode_prompt.json +10 -0
- package/src/providers/operations/account-error-classification.ts +131 -116
- package/src/providers/operations/account-health-service.ts +31 -39
- package/src/providers/operations/account-reset-service.ts +58 -1
- package/src/providers/operations/cli-platform.ts +31 -5
- package/src/providers/operations/client-version-resolver.ts +4 -6
- package/src/providers/operations/client-versions.ts +10 -7
- package/src/providers/operations/provider-catalog-seeder.ts +2 -0
- package/src/providers/operations/provider-catalog-service.ts +18 -2
- package/src/providers/operations/provider-credential-service.ts +19 -2
- package/src/providers/provider-contracts.ts +18 -7
- package/src/providers/provider-metadata.ts +17 -2
- package/src/providers/provider-model-definition.ts +22 -1
- package/src/providers/provider-probe.ts +4 -2
- package/src/providers/provider-usage.ts +81 -16
- package/src/providers/quota/cache.ts +29 -0
- package/src/providers/quota/quota-contracts.ts +4 -0
- package/src/providers/quota/refresh.ts +27 -4
- package/src/providers/quota/snapshot.ts +94 -0
- package/src/providers/search/search-provider.ts +1 -3
- package/src/providers/search/search-providers.ts +2 -1
- package/src/security/abuse.ts +4 -4
- package/src/security/admission/service.ts +2 -2
- package/src/security/admission/ttl.ts +61 -61
- package/src/security/api-key-auth.ts +16 -4
- package/src/security/client-router-fingerprint.ts +4 -4
- package/src/security/credential-codec.ts +3 -3
- package/src/security/csrf.ts +2 -2
- package/src/security/ip-boundary.ts +16 -189
- package/src/security/model-access-rule.ts +1 -1
- package/src/security/outbound-headers.ts +18 -0
- package/src/shared/invoke-guard.ts +47 -0
- package/src/transport/contracts.ts +13 -4
- package/src/transport/dispatch/attempt-finalize.ts +1 -1
- package/src/transport/dispatch/capture-policy.ts +34 -37
- package/src/transport/dispatch/empty-stream.ts +23 -20
- package/src/transport/dispatch/generation.ts +25 -45
- package/src/transport/dispatch/native-shared.ts +127 -0
- package/src/transport/dispatch/proxy-request.ts +3 -1
- package/src/transport/dispatch/responses-compact.ts +25 -46
- package/src/transport/dispatch/streaming/encoder.ts +18 -72
- package/src/transport/dispatch/streaming/finalize.ts +2 -2
- package/src/transport/dispatch/streaming/stream.ts +7 -3
- package/src/transport/dispatch/streaming/thinking-loop.ts +1 -1
- package/src/transport/dispatch/systemone.ts +20 -48
- package/src/transport/dispatch/token-count.ts +41 -38
- package/src/transport/dispatch/websearch.ts +19 -45
- package/src/transport/drain-endpoint.ts +1 -1
- package/src/transport/failure-policy.ts +6 -0
- package/src/transport/guards/auth-guard.ts +0 -6
- package/src/transport/guards/body-policy.ts +3 -3
- package/src/transport/guards/headroom-guard.ts +1 -1
- package/src/transport/guards/pipeline.ts +1 -1
- package/src/transport/guards/request-context.ts +12 -17
- package/src/transport/request/preparer.ts +286 -7
- package/src/transport/request/rtk/compress-request.ts +3 -3
- package/src/transport/request/rtk/rtk-constants.ts +2 -2
- package/src/transport/request/rtk/rtk-filters.ts +8 -8
- package/src/transport/request/state.ts +1 -13
- package/src/transport/request/system-prompt-injection.ts +74 -11
- package/src/transport/request/tenant-preferences.ts +22 -0
- package/src/transport/routing/candidate-index.ts +2 -2
- package/src/transport/routing/round-robin.ts +1 -1
- package/src/transport/routing/route-catalog.ts +17 -18
- package/src/transport/routing/route-model.ts +126 -33
- package/src/transport/routing/router.ts +152 -37
- package/src/transport/shutdown-notice.ts +2 -2
- package/src/transport/surface/adapters.ts +3 -3
- package/src/transport/surface/chat/encode.ts +7 -7
- package/src/transport/surface/chat/parse.ts +7 -7
- package/src/transport/surface/completion.ts +2 -2
- package/src/transport/surface/content-parts.ts +1 -1
- package/src/transport/surface/dialects.ts +2 -2
- package/src/transport/surface/messages/parse.ts +3 -3
- package/src/transport/surface/responses/adapter.ts +1 -1
- package/src/transport/surface/responses/errors.ts +0 -9
- package/src/transport/vision-handoff-cache.ts +58 -0
- package/src/transport/vision-handoff.ts +376 -0
- package/src/workers/account-identity-sweep.ts +2 -2
- package/src/workers/buddy-growth-tasks.ts +392 -346
- package/src/workers/daily-checkin.ts +102 -49
- package/src/workers/maintenance-lease.ts +2 -35
- package/src/workers/oauth-refresh-sweep.ts +8 -1
- package/src/workers/quota-refresh-sweep.ts +120 -82
- package/src/workers/scheduler.ts +67 -4
- package/src/workers/sweep-runner.ts +24 -5
- package/src/workers/zcode-gift-claim.ts +108 -0
- package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js +0 -1
- package/dist/dashboard/assets/AccountCooldown-Bjo92Qat.js.gz +0 -0
- package/dist/dashboard/assets/BannedPage-ChG5svFb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BIcWQun7.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-Bf2VelDe.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-DCgm5g6g.js +0 -1
- package/dist/dashboard/assets/CombosPage-DCgm5g6g.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-a8mD0QF1.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-ggeMSjte.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-DzSWzE_j.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-U6AKaJcF.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BMS2t8BA.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js +0 -1
- package/dist/dashboard/assets/OverviewPage-D2D4IiHl.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js +0 -5
- package/dist/dashboard/assets/ProviderDetailPage-CrNf7j_X.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js +0 -1
- package/dist/dashboard/assets/ProviderIcon-FB6yS4v1.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-BSDbquc1.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-lsrx7NYg.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js +0 -1
- package/dist/dashboard/assets/QuotaPage-L0skzML8.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js +0 -1
- package/dist/dashboard/assets/SettingsPage-CmAbjRHW.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-f0DE1h0-.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-ClzpwyET.js +0 -1
- package/dist/dashboard/assets/SortableList-ClzpwyET.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-Cq5tW7hW.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js +0 -56
- package/dist/dashboard/assets/UsagePage-Dfc9rWQn.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-C38iXoO4.js +0 -1
- package/dist/dashboard/assets/api-keys-C38iXoO4.js.gz +0 -0
- package/dist/dashboard/assets/app-a159k0ub.css +0 -2
- package/dist/dashboard/assets/app-a159k0ub.css.gz +0 -0
- package/dist/dashboard/assets/assert-DbRA8EG2.js +0 -15
- package/dist/dashboard/assets/assert-DbRA8EG2.js.gz +0 -0
- package/dist/dashboard/assets/badge-D9CS6dZk.js.gz +0 -0
- package/dist/dashboard/assets/banner-DympBNq4.js.gz +0 -0
- package/dist/dashboard/assets/card-ibRWU_uT.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js +0 -1
- package/dist/dashboard/assets/cli-tools-63qBGaRw.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-DJm-9pz7.js.gz +0 -0
- package/dist/dashboard/assets/dialog-8fiE6tec.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CqGYeOrd.js.gz +0 -0
- package/dist/dashboard/assets/entry-BSAsYsmV.js.gz +0 -0
- package/dist/dashboard/assets/entry-CiIQULZD.js +0 -4
- package/dist/dashboard/assets/entry-CiIQULZD.js.gz +0 -0
- package/dist/dashboard/assets/entry-Daz0lJ-W.js +0 -1
- package/dist/dashboard/assets/entry-Daz0lJ-W.js.gz +0 -0
- package/dist/dashboard/assets/formatters-D-MTJxMr.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-CPK47xQx.js.gz +0 -0
- package/dist/dashboard/assets/index-DBNPOfhV.js.gz +0 -0
- package/dist/dashboard/assets/inline-BT0zntEr.js.gz +0 -0
- package/dist/dashboard/assets/input-Da2ZViWg.js.gz +0 -0
- package/dist/dashboard/assets/layout-BXNeLw6M.js.gz +0 -0
- package/dist/dashboard/assets/list-row-BycOrrIV.js.gz +0 -0
- package/dist/dashboard/assets/live-DCQNZpF7.js +0 -1
- package/dist/dashboard/assets/live-DCQNZpF7.js.gz +0 -0
- package/dist/dashboard/assets/network-9Yj2ZyLo.js +0 -1
- package/dist/dashboard/assets/network-9Yj2ZyLo.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CEagj6ZZ.js +0 -2
- package/dist/dashboard/assets/numbers-CEagj6ZZ.js.gz +0 -0
- package/dist/dashboard/assets/quota-Caw7wqci.js +0 -1
- package/dist/dashboard/assets/quota-Caw7wqci.js.gz +0 -0
- package/dist/dashboard/assets/routing-CO9zCUus.js +0 -1
- package/dist/dashboard/assets/routing-CO9zCUus.js.gz +0 -0
- package/dist/dashboard/assets/select-BIYIBkMU.js.gz +0 -0
- package/dist/dashboard/assets/settings-jS3-PNSA.js +0 -1
- package/dist/dashboard/assets/settings-jS3-PNSA.js.gz +0 -0
- package/dist/dashboard/assets/stack-DfgnFDWY.js.gz +0 -0
- package/dist/dashboard/assets/state-CkfdYWel.js.gz +0 -0
- package/dist/dashboard/assets/stream-retry-5QnVuSSo.js +0 -1
- package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
- package/dist/dashboard/assets/switch-SYm237HG.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-BQqCRNIi.js.gz +0 -0
- package/src/network/response-headers.ts +0 -39
- package/src/protocol/response/dsml.ts +0 -38
- package/src/providers/integrations/xiaomi-mimo/think-stream.ts +0 -229
- /package/dist/dashboard/assets/{app-BayTTy01.js → app-Bgd3zANQ.js} +0 -0
- /package/dist/dashboard/assets/{app-BayTTy01.js.gz → app-Bgd3zANQ.js.gz} +0 -0
- /package/dist/dashboard/assets/brand/{og_bansos.webp → og_bansos_initial.webp} +0 -0
- /package/dist/dashboard/assets/brand/{og_image.webp → og_image_initial.webp} +0 -0
|
@@ -7,7 +7,7 @@ import { createHash, randomBytes, randomInt } from "node:crypto";
|
|
|
7
7
|
import { and, desc, eq, isNull, or, sql, type SQL } from "drizzle-orm";
|
|
8
8
|
import type { CartethyiaDatabase } from "../db-handle";
|
|
9
9
|
import { lockRows } from "../dialect";
|
|
10
|
-
import { apiKeys, shareLinks, sharePopups, type ShareLinkKind, type ApiKeyModelAccessMode } from "../schema";
|
|
10
|
+
import { apiKeys, shareLinks, sharePopups, type ShareLinkKind, type ApiKeyModelAccessMode, type ApiKeyConcurrencyScope } from "../schema";
|
|
11
11
|
|
|
12
12
|
/** Hashes a share bearer token for storage and lookup. */
|
|
13
13
|
/**
|
|
@@ -38,7 +38,7 @@ function addressMatches(address: string): SQL {
|
|
|
38
38
|
}
|
|
39
39
|
|
|
40
40
|
/** Newly created share-link metadata. */
|
|
41
|
-
|
|
41
|
+
interface ShareLinkRecord {
|
|
42
42
|
readonly id: string;
|
|
43
43
|
readonly apiKeyId: string;
|
|
44
44
|
readonly kind: ShareLinkKind;
|
|
@@ -61,7 +61,7 @@ export interface ShareLinkSummary {
|
|
|
61
61
|
}
|
|
62
62
|
|
|
63
63
|
/** A stable link's encrypted token, or null when it predates token retention. */
|
|
64
|
-
|
|
64
|
+
interface ShareLinkToken {
|
|
65
65
|
readonly id: string;
|
|
66
66
|
readonly apiKeyId: string;
|
|
67
67
|
readonly kind: ShareLinkKind;
|
|
@@ -86,6 +86,7 @@ export interface ShareLinkPolicy {
|
|
|
86
86
|
readonly monthlyTokenLimit: number | null;
|
|
87
87
|
readonly lifetimeTokenBudget: number | null;
|
|
88
88
|
readonly maxConcurrentRequests: number | null;
|
|
89
|
+
readonly concurrencyScope: ApiKeyConcurrencyScope;
|
|
89
90
|
readonly modelAccessMode: ApiKeyModelAccessMode | null;
|
|
90
91
|
readonly modelList: readonly string[] | null;
|
|
91
92
|
readonly modelPrefix: string | null;
|
|
@@ -102,13 +103,13 @@ export interface ShareLinkPolicy {
|
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
/** Public template fields authorized for a valid enrollment-link lookup. */
|
|
105
|
-
|
|
106
|
+
interface ShareApiKeyRow extends ShareLinkPolicy {
|
|
106
107
|
readonly active: boolean;
|
|
107
108
|
readonly createdAt: string;
|
|
108
109
|
}
|
|
109
110
|
|
|
110
111
|
/** A personal key revealed by its handoff link. */
|
|
111
|
-
|
|
112
|
+
interface ShareHandoffRow extends ShareLinkPolicy {
|
|
112
113
|
/** Encrypted personal credential; null when the row predates secret storage. */
|
|
113
114
|
readonly keyEncrypted: Buffer | null;
|
|
114
115
|
}
|
|
@@ -118,7 +119,7 @@ export interface ShareHandoffRow extends ShareLinkPolicy {
|
|
|
118
119
|
* public lookup answers with a discriminated result instead of the caller
|
|
119
120
|
* guessing which endpoint to try.
|
|
120
121
|
*/
|
|
121
|
-
|
|
122
|
+
type ShareLinkResolution =
|
|
122
123
|
| { readonly kind: "enroll"; readonly key: ShareApiKeyRow }
|
|
123
124
|
| { readonly kind: "handoff"; readonly key: ShareHandoffRow };
|
|
124
125
|
|
|
@@ -136,7 +137,7 @@ export type ShareLinkOutcome =
|
|
|
136
137
|
| { readonly ok: true; readonly resolution: ShareLinkResolution }
|
|
137
138
|
| { readonly ok: false; readonly refusal: ShareLinkRefusal };
|
|
138
139
|
|
|
139
|
-
|
|
140
|
+
interface SharedApiKeyMaterial {
|
|
140
141
|
readonly keyHash: string;
|
|
141
142
|
readonly keyPrefix: string;
|
|
142
143
|
readonly clientIp: string;
|
|
@@ -145,7 +146,7 @@ export interface SharedApiKeyMaterial {
|
|
|
145
146
|
readonly nameHint?: string;
|
|
146
147
|
}
|
|
147
148
|
|
|
148
|
-
|
|
149
|
+
type SharedApiKeyIssueResult =
|
|
149
150
|
| {
|
|
150
151
|
readonly kind: "issued";
|
|
151
152
|
readonly apiKeyId: string;
|
|
@@ -185,6 +186,7 @@ function mapShareRow(key: ApiKeyRow, link: ShareLinkRow, popup?: PopupRow): Shar
|
|
|
185
186
|
monthlyTokenLimit: key.monthlyTokenLimit,
|
|
186
187
|
lifetimeTokenBudget: key.lifetimeTokenBudget,
|
|
187
188
|
maxConcurrentRequests: key.maxConcurrentRequests,
|
|
189
|
+
concurrencyScope: key.concurrencyScope ?? "family",
|
|
188
190
|
modelAccessMode: key.modelAccessMode as ApiKeyModelAccessMode | null,
|
|
189
191
|
modelList: key.modelList as readonly string[] | null,
|
|
190
192
|
modelPrefix: key.modelPrefix,
|
|
@@ -213,6 +215,7 @@ function mapHandoffRow(key: ApiKeyRow, link: ShareLinkRow, popup?: PopupRow): Sh
|
|
|
213
215
|
monthlyTokenLimit: key.monthlyTokenLimit,
|
|
214
216
|
lifetimeTokenBudget: key.lifetimeTokenBudget,
|
|
215
217
|
maxConcurrentRequests: key.maxConcurrentRequests,
|
|
218
|
+
concurrencyScope: key.concurrencyScope ?? "family",
|
|
216
219
|
modelAccessMode: key.modelAccessMode as ApiKeyModelAccessMode | null,
|
|
217
220
|
modelList: key.modelList as readonly string[] | null,
|
|
218
221
|
modelPrefix: key.modelPrefix,
|
|
@@ -557,6 +560,12 @@ export class DrizzleShareLinkStore implements ShareLinkStore {
|
|
|
557
560
|
// Nullable policy columns stay NULL; `model_access_mode` takes its
|
|
558
561
|
// NOT NULL default ('whitelist'). Keep in sync with migration 0029 and
|
|
559
562
|
// `normalizeShareChildPolicy` in `src/console/backup/store.ts`.
|
|
563
|
+
//
|
|
564
|
+
// Exception: a template with `concurrencyScope: "per_key"` lets each
|
|
565
|
+
// recipient carry its own concurrency cap, so the cap is copied to the
|
|
566
|
+
// child at issue (the child's admission identity is its own id, not the
|
|
567
|
+
// parent's). The `family` default keeps child caps NULL — they inherit
|
|
568
|
+
// the parent's cap through auth.
|
|
560
569
|
const [child] = await tx
|
|
561
570
|
.insert(apiKeys)
|
|
562
571
|
.values({
|
|
@@ -571,6 +580,9 @@ export class DrizzleShareLinkStore implements ShareLinkStore {
|
|
|
571
580
|
keyPrefix: material.keyPrefix,
|
|
572
581
|
keyEncrypted: null,
|
|
573
582
|
lifetimeTokensConsumed: 0,
|
|
583
|
+
...(parent.concurrencyScope === "per_key"
|
|
584
|
+
? { concurrencyScope: "per_key" as const, maxConcurrentRequests: parent.maxConcurrentRequests }
|
|
585
|
+
: {}),
|
|
574
586
|
})
|
|
575
587
|
.returning({ id: apiKeys.id, tenantId: apiKeys.tenantId, createdAt: apiKeys.createdAt });
|
|
576
588
|
if (!child) throw new Error("shared API-key insert returned no row");
|
|
@@ -7,15 +7,20 @@ import { eq } from "drizzle-orm";
|
|
|
7
7
|
import type { CartethyiaDatabase } from "./db-handle";
|
|
8
8
|
import { tenantSystemPrompts } from "./schema";
|
|
9
9
|
import type {
|
|
10
|
-
|
|
11
|
-
|
|
10
|
+
ScopePromptRef,
|
|
11
|
+
SystemPromptPreset,
|
|
12
12
|
TenantSystemPrompts,
|
|
13
13
|
} from "../console/system-prompt/contracts";
|
|
14
14
|
import {
|
|
15
15
|
EMPTY_TENANT_SYSTEM_PROMPTS,
|
|
16
|
+
SYSTEM_PROMPT_ALIAS_LIMIT,
|
|
17
|
+
SYSTEM_PROMPT_COMBO_LIMIT,
|
|
16
18
|
SYSTEM_PROMPT_MODEL_LIMIT,
|
|
19
|
+
SYSTEM_PROMPT_PRESET_LIMIT,
|
|
17
20
|
SYSTEM_PROMPT_PROVIDER_LIMIT,
|
|
18
21
|
isPromptSetting,
|
|
22
|
+
isScopePromptRef,
|
|
23
|
+
isSystemPromptPreset,
|
|
19
24
|
parseSystemPromptModelKey,
|
|
20
25
|
} from "../console/system-prompt/contracts";
|
|
21
26
|
import { bumpSettingsRevision } from "./settings-revision";
|
|
@@ -23,6 +28,24 @@ import { bumpSettingsRevision } from "./settings-revision";
|
|
|
23
28
|
/** The stored row, normalized. Absent row reads as the empty configuration. */
|
|
24
29
|
export type StoredTenantSystemPrompts = TenantSystemPrompts;
|
|
25
30
|
|
|
31
|
+
/**
|
|
32
|
+
* Normalizes one scope reference value. Accepts the new `{ kind, ... }` shape
|
|
33
|
+
* and the legacy per-provider entry shape (`{ followGlobal, setting? }`) so a
|
|
34
|
+
* hand-edited or pre-migration row stays valid. Invalid values become
|
|
35
|
+
* `undefined` (the caller drops the key).
|
|
36
|
+
*/
|
|
37
|
+
function normalizeScopeRef(value: unknown, legacyProviderEntry?: boolean): ScopePromptRef | undefined {
|
|
38
|
+
if (isScopePromptRef(value)) return value;
|
|
39
|
+
if (legacyProviderEntry && typeof value === "object" && value !== null) {
|
|
40
|
+
const candidate = value as { followGlobal?: unknown; setting?: unknown };
|
|
41
|
+
if (candidate.followGlobal === true) return { kind: "global" };
|
|
42
|
+
if (candidate.followGlobal === false && isPromptSetting(candidate.setting)) {
|
|
43
|
+
return { kind: "custom", setting: candidate.setting };
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
return undefined;
|
|
47
|
+
}
|
|
48
|
+
|
|
26
49
|
/**
|
|
27
50
|
* Reads the tenant's stored configuration, defensively normalized: a
|
|
28
51
|
* hand-edited or legacy row must not poison the dispatch path, so malformed
|
|
@@ -35,8 +58,11 @@ export async function readTenantSystemPrompts(
|
|
|
35
58
|
const rows = await db
|
|
36
59
|
.select({
|
|
37
60
|
global: tenantSystemPrompts.global,
|
|
61
|
+
presets: tenantSystemPrompts.presets,
|
|
38
62
|
providers: tenantSystemPrompts.providers,
|
|
39
63
|
models: tenantSystemPrompts.models,
|
|
64
|
+
combos: tenantSystemPrompts.combos,
|
|
65
|
+
aliases: tenantSystemPrompts.aliases,
|
|
40
66
|
})
|
|
41
67
|
.from(tenantSystemPrompts)
|
|
42
68
|
.where(eq(tenantSystemPrompts.tenantId, tenantId))
|
|
@@ -44,30 +70,43 @@ export async function readTenantSystemPrompts(
|
|
|
44
70
|
const row = rows[0];
|
|
45
71
|
if (row === undefined) return EMPTY_TENANT_SYSTEM_PROMPTS;
|
|
46
72
|
|
|
47
|
-
const
|
|
48
|
-
for (const [
|
|
49
|
-
if (
|
|
50
|
-
const candidate = entry as Partial<ProviderPromptEntry>;
|
|
51
|
-
if (typeof candidate.followGlobal !== "boolean") continue;
|
|
52
|
-
if (candidate.followGlobal === false) {
|
|
53
|
-
if (!isPromptSetting(candidate.setting)) continue;
|
|
54
|
-
providers[providerId] = { followGlobal: false, setting: candidate.setting };
|
|
55
|
-
} else {
|
|
56
|
-
providers[providerId] = { followGlobal: true };
|
|
57
|
-
}
|
|
73
|
+
const presets: Record<string, SystemPromptPreset> = {};
|
|
74
|
+
for (const [id, preset] of Object.entries(row.presets ?? {})) {
|
|
75
|
+
if (isSystemPromptPreset(preset) && preset.id === id) presets[id] = preset;
|
|
58
76
|
}
|
|
59
77
|
|
|
60
|
-
const
|
|
61
|
-
for (const [
|
|
78
|
+
const providers: Record<string, ScopePromptRef> = {};
|
|
79
|
+
for (const [providerId, value] of Object.entries(row.providers ?? {})) {
|
|
80
|
+
const ref = normalizeScopeRef(value, true);
|
|
81
|
+
if (ref !== undefined) providers[providerId] = ref;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
const models: Record<string, ScopePromptRef> = {};
|
|
85
|
+
for (const [key, value] of Object.entries(row.models ?? {})) {
|
|
62
86
|
if (parseSystemPromptModelKey(key) === null) continue;
|
|
63
|
-
|
|
64
|
-
models[key] =
|
|
87
|
+
const ref = normalizeScopeRef(value);
|
|
88
|
+
if (ref !== undefined) models[key] = ref;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
const combos: Record<string, ScopePromptRef> = {};
|
|
92
|
+
for (const [name, value] of Object.entries(row.combos ?? {})) {
|
|
93
|
+
const ref = normalizeScopeRef(value);
|
|
94
|
+
if (ref !== undefined) combos[name] = ref;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const aliases: Record<string, ScopePromptRef> = {};
|
|
98
|
+
for (const [name, value] of Object.entries(row.aliases ?? {})) {
|
|
99
|
+
const ref = normalizeScopeRef(value);
|
|
100
|
+
if (ref !== undefined) aliases[name] = ref;
|
|
65
101
|
}
|
|
66
102
|
|
|
67
103
|
return {
|
|
68
|
-
global: row.global !== null &&
|
|
104
|
+
global: row.global !== null && isScopePromptRef(row.global) ? row.global : null,
|
|
105
|
+
presets,
|
|
69
106
|
providers,
|
|
70
107
|
models,
|
|
108
|
+
combos,
|
|
109
|
+
aliases,
|
|
71
110
|
};
|
|
72
111
|
}
|
|
73
112
|
|
|
@@ -79,12 +118,18 @@ export async function writeTenantSystemPrompts(
|
|
|
79
118
|
): Promise<void> {
|
|
80
119
|
// Keep the row bounded even though the API already enforces the caps: a
|
|
81
120
|
// direct store caller must not be able to plant an unbounded map.
|
|
121
|
+
const presets = Object.entries(next.presets).slice(0, SYSTEM_PROMPT_PRESET_LIMIT);
|
|
82
122
|
const providers = Object.entries(next.providers).slice(0, SYSTEM_PROMPT_PROVIDER_LIMIT);
|
|
83
123
|
const models = Object.entries(next.models).slice(0, SYSTEM_PROMPT_MODEL_LIMIT);
|
|
124
|
+
const combos = Object.entries(next.combos).slice(0, SYSTEM_PROMPT_COMBO_LIMIT);
|
|
125
|
+
const aliases = Object.entries(next.aliases).slice(0, SYSTEM_PROMPT_ALIAS_LIMIT);
|
|
84
126
|
const values = {
|
|
85
127
|
global: next.global,
|
|
128
|
+
presets: Object.fromEntries(presets),
|
|
86
129
|
providers: Object.fromEntries(providers),
|
|
87
130
|
models: Object.fromEntries(models),
|
|
131
|
+
combos: Object.fromEntries(combos),
|
|
132
|
+
aliases: Object.fromEntries(aliases),
|
|
88
133
|
updatedAt: new Date(),
|
|
89
134
|
};
|
|
90
135
|
await db
|
|
@@ -29,7 +29,7 @@ export class DrizzlePreferencesReader implements PreferencesReader {
|
|
|
29
29
|
}
|
|
30
30
|
}
|
|
31
31
|
|
|
32
|
-
|
|
32
|
+
interface CachedPreferencesReaderOptions {
|
|
33
33
|
readonly ttlMs?: number;
|
|
34
34
|
readonly maxEntries?: number;
|
|
35
35
|
readonly revision?: () => number;
|
|
@@ -7,13 +7,13 @@ import { dedupeRequest } from "../network/deduplication";
|
|
|
7
7
|
* - Revision-aware key invalidation
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
|
|
10
|
+
interface TtlCacheOptions {
|
|
11
11
|
readonly ttlMs?: number;
|
|
12
12
|
readonly maxEntries?: number;
|
|
13
13
|
readonly now?: () => number;
|
|
14
14
|
}
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
interface TtlCacheEntry<T> {
|
|
17
17
|
readonly value: T;
|
|
18
18
|
readonly at: number;
|
|
19
19
|
}
|
|
@@ -134,7 +134,7 @@ export class TtlCache<T> {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
/** One TTL-sized cache inside a {@link TtlCacheFamily}. */
|
|
137
|
-
|
|
137
|
+
interface TtlCacheFamilyOptions {
|
|
138
138
|
/** TTL applied when a caller does not pass its own. */
|
|
139
139
|
readonly defaultTtlMs: number;
|
|
140
140
|
/** Entry cap per TTL-sized cache. */
|
|
@@ -65,14 +65,19 @@ async function writeLifetimeDeltas(
|
|
|
65
65
|
// text and the join against a uuid key fails. SQLite stores the key as text
|
|
66
66
|
// and rejects `UPDATE ... FROM (VALUES ...)` outright, so the same rows are
|
|
67
67
|
// a SELECT with named columns instead.
|
|
68
|
-
const
|
|
68
|
+
const sqlite = sqliteDialect();
|
|
69
|
+
const source = sqlite
|
|
69
70
|
? `(${rows.map((row) => `SELECT '${row.apiKeyId}' AS id, ${row.delta} AS delta`).join(" UNION ALL ")})`
|
|
70
71
|
: `(VALUES ${rows.map((row) => `('${row.apiKeyId}'::uuid, ${row.delta}::bigint)`).join(", ")}) AS v(id, delta)`;
|
|
72
|
+
// PostgreSQL already carries its alias in `source`; only the bare SQLite
|
|
73
|
+
// subquery needs the trailing alias appended. Emitting both (`AS v(id, delta) v`)
|
|
74
|
+
// is a syntax error on Postgres, so the flush silently never ran.
|
|
75
|
+
const from = sqlite ? `${source} v` : source;
|
|
71
76
|
await db.execute(sql.raw(`
|
|
72
77
|
UPDATE "api_keys"
|
|
73
78
|
SET "lifetime_tokens_consumed" =
|
|
74
79
|
COALESCE("api_keys"."lifetime_tokens_consumed", 0) + v.delta
|
|
75
|
-
FROM ${
|
|
80
|
+
FROM ${from}
|
|
76
81
|
WHERE "api_keys"."id" = v.id
|
|
77
82
|
`));
|
|
78
83
|
}
|
|
@@ -614,7 +614,7 @@ export function hasEncryptedReasoning(parts: readonly ContentPart[]): boolean {
|
|
|
614
614
|
* concurrent preflights would be an aliasing hazard; the memoized summary and
|
|
615
615
|
* its extension set are treated as read-only.)
|
|
616
616
|
*/
|
|
617
|
-
|
|
617
|
+
interface PartSummary {
|
|
618
618
|
readonly hasImage: boolean;
|
|
619
619
|
readonly hasDocument: boolean;
|
|
620
620
|
readonly hasAudio: boolean;
|
package/src/protocol/codecs.ts
CHANGED
|
@@ -89,7 +89,7 @@ export function hash32(input: string): number {
|
|
|
89
89
|
return hash;
|
|
90
90
|
}
|
|
91
91
|
|
|
92
|
-
|
|
92
|
+
const CLAUDE_TOOL_PREFIX = "_";
|
|
93
93
|
|
|
94
94
|
export type ClaudeWireObject = Record<string, unknown>;
|
|
95
95
|
|
|
@@ -408,13 +408,9 @@ export function isClaudeBillingHeaderText(text: string): boolean {
|
|
|
408
408
|
// Well-formed UTF-16 coercion
|
|
409
409
|
|
|
410
410
|
export function toWellFormedString(value: string): string {
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
return value.replace(
|
|
415
|
-
/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,
|
|
416
|
-
"\uFFFD",
|
|
417
|
-
);
|
|
411
|
+
// String.prototype.toWellFormed is ES2024; guaranteed by Bun ≥1.4, the only
|
|
412
|
+
// supported runtime.
|
|
413
|
+
return value.toWellFormed();
|
|
418
414
|
}
|
|
419
415
|
|
|
420
416
|
export function toWellFormedDeep(value: unknown): unknown {
|
|
@@ -873,7 +869,7 @@ export const BARE_ROOT_ENDPOINTS: Partial<Record<WireFamily, string>> = {
|
|
|
873
869
|
};
|
|
874
870
|
|
|
875
871
|
/** An image part's provider-neutral source, resolved from any supported origin shape. */
|
|
876
|
-
|
|
872
|
+
interface ResolvedImageSource {
|
|
877
873
|
/** URL or `data:` URI. Mutually usable with `fileId`. */
|
|
878
874
|
url?: string;
|
|
879
875
|
/** Files API reference (Chat/Responses `file_id`). */
|
|
@@ -883,7 +879,7 @@ export interface ResolvedImageSource {
|
|
|
883
879
|
}
|
|
884
880
|
|
|
885
881
|
/** An RFC 2397 base64 `data:` URL split into the media type and bytes it carries. */
|
|
886
|
-
|
|
882
|
+
interface DataUrlPayload {
|
|
887
883
|
/** The declared media type (the `image/png` of `data:image/png;base64,…`). */
|
|
888
884
|
readonly mediaType: string;
|
|
889
885
|
/** The base64 payload, with the `data:` prefix and media type removed. */
|
package/src/protocol/dsml.ts
CHANGED
|
@@ -24,7 +24,7 @@ export interface DsmlToolCall {
|
|
|
24
24
|
readonly arguments: string;
|
|
25
25
|
}
|
|
26
26
|
|
|
27
|
-
|
|
27
|
+
interface DsmlRecovery {
|
|
28
28
|
readonly calls: readonly DsmlToolCall[];
|
|
29
29
|
readonly clean: string;
|
|
30
30
|
}
|
|
@@ -63,7 +63,7 @@ const DEFAULT_MAX_BLOCK_BYTES = 256 * 1024;
|
|
|
63
63
|
const TOOL_NAME = /^[A-Za-z0-9_][A-Za-z0-9_.:-]{0,63}$/;
|
|
64
64
|
|
|
65
65
|
/** Escapes regex metacharacters so a `|` separator is literal, not alternation. */
|
|
66
|
-
|
|
66
|
+
function escapeRegExp(value: string): string {
|
|
67
67
|
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
68
68
|
}
|
|
69
69
|
|
|
@@ -79,7 +79,7 @@ function uuidId(_call: { readonly name: string }, _index: number, _seq: number):
|
|
|
79
79
|
return `call_${randomUUID().replace(/-/g, "").slice(0, 16)}`;
|
|
80
80
|
}
|
|
81
81
|
|
|
82
|
-
|
|
82
|
+
interface DsmlParseResult {
|
|
83
83
|
readonly text: string;
|
|
84
84
|
readonly calls: readonly DsmlToolCall[];
|
|
85
85
|
}
|
|
@@ -306,15 +306,6 @@ function parseFuzzyDsml(text: string, options: DsmlParseOptions): DsmlRecovery {
|
|
|
306
306
|
return { calls, clean };
|
|
307
307
|
}
|
|
308
308
|
|
|
309
|
-
/**
|
|
310
|
-
* Recovers DSML tool calls from one plain-text string using the Qoder fuzzy
|
|
311
|
-
* dialect. Always returns `{ calls, clean }` — no-DSML input returns the text
|
|
312
|
-
* unchanged with no calls.
|
|
313
|
-
*/
|
|
314
|
-
export function parseFuzzyDsmlToolCalls(text: string): DsmlRecovery {
|
|
315
|
-
return parseFuzzyDsml(text, {});
|
|
316
|
-
}
|
|
317
|
-
|
|
318
309
|
/**
|
|
319
310
|
* Recovers DSML tool calls from one plain-text string. The dialect is chosen
|
|
320
311
|
* by `options.fuzzy`; each dialect keeps its exact public shape:
|
|
@@ -338,40 +329,3 @@ export function parseDsmlToolCalls(
|
|
|
338
329
|
const recovered = [...first.calls, ...last.calls];
|
|
339
330
|
return recovered.length === 0 ? undefined : { text: `${first.text}${last.text}`.trim(), calls: recovered };
|
|
340
331
|
}
|
|
341
|
-
|
|
342
|
-
/**
|
|
343
|
-
* The holdable tail of a content chunk: a short suffix that looks like the
|
|
344
|
-
* start of a DSML tag and may finish in the next frame. Empty when there is
|
|
345
|
-
* nothing worth holding. Mirrors `_dsml_tail_hold` in the reference bridge.
|
|
346
|
-
*/
|
|
347
|
-
export function dsmlTailHold(text: string): string {
|
|
348
|
-
const at = text.lastIndexOf("<");
|
|
349
|
-
if (at < 0 || text.length - at > 24) return "";
|
|
350
|
-
const tail = text.slice(at);
|
|
351
|
-
// A complete tag already — nothing to wait for.
|
|
352
|
-
if (tail.includes(">")) return "";
|
|
353
|
-
const body = tail.replace(/\uFF5C/g, "|").toUpperCase().slice(1).replace(/^\//, "");
|
|
354
|
-
if (body.length === 0) return tail; // bare "<" or "</"
|
|
355
|
-
if (!body.startsWith("|")) return "";
|
|
356
|
-
const rest = body.slice(1);
|
|
357
|
-
if (rest.length === 0) return tail;
|
|
358
|
-
if ("DSML".startsWith(rest) || rest.startsWith("DSML")) return tail;
|
|
359
|
-
return "";
|
|
360
|
-
}
|
|
361
|
-
|
|
362
|
-
const DSML_CLOSE_TAG_RE = /<\/(?:[^>]*DSML[^>]*|parameter|invoke|calls|tool_calls|function_calls)\s*>\s*$/i;
|
|
363
|
-
|
|
364
|
-
/**
|
|
365
|
-
* Removes leftover DSML closing tags from the tail of a text. Anchored to the
|
|
366
|
-
* end and looped, so several trailing tags come off one per pass; a closing
|
|
367
|
-
* tag in the middle of a text is not residue and is preserved.
|
|
368
|
-
*/
|
|
369
|
-
export function stripDsmlCloseTags(text: string): string {
|
|
370
|
-
let previous: string | null = null;
|
|
371
|
-
let out = text.trimEnd();
|
|
372
|
-
while (previous !== out) {
|
|
373
|
-
previous = out;
|
|
374
|
-
out = out.replace(DSML_CLOSE_TAG_RE, "").trimEnd();
|
|
375
|
-
}
|
|
376
|
-
return out;
|
|
377
|
-
}
|
|
@@ -69,7 +69,7 @@ export interface ImageClampInput {
|
|
|
69
69
|
readonly maxBytesOverride?: number;
|
|
70
70
|
}
|
|
71
71
|
|
|
72
|
-
|
|
72
|
+
interface ImageClampDecision {
|
|
73
73
|
readonly action: ImageClampAction;
|
|
74
74
|
readonly reason: ImageClampReason;
|
|
75
75
|
/** Longest edge allowed for this image, given how many the request carries. */
|
|
@@ -96,7 +96,7 @@ export function base64DecodedByteLength(data: string): number {
|
|
|
96
96
|
}
|
|
97
97
|
|
|
98
98
|
/** The per-image longest-edge ceiling for a request carrying `imageCount` images. */
|
|
99
|
-
|
|
99
|
+
function imageClampMaxDimensionPx(imageCount: number): number {
|
|
100
100
|
return imageCount > IMAGE_CLAMP_MANY_IMAGE_COUNT
|
|
101
101
|
? IMAGE_CLAMP_MANY_IMAGE_MAX_DIMENSION_PX
|
|
102
102
|
: IMAGE_CLAMP_MAX_DIMENSION_PX;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** The reasoning-shaped part this reads. Structural, so any reasoning part —
|
|
2
2
|
* including a `ContentPart` narrowed to `kind: "reasoning"` — is accepted. */
|
|
3
|
-
|
|
3
|
+
interface ReasoningTextSource {
|
|
4
4
|
readonly payload?: unknown;
|
|
5
5
|
readonly summary?: string;
|
|
6
6
|
readonly opaque?: boolean;
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { CanonicalRequest, ReasoningEffort, ReasoningIntent } from "./canonical-model";
|
|
2
2
|
import { budgetToLevel } from "./translation/thinking";
|
|
3
3
|
import { isRecord } from "./codecs";
|
|
4
|
+
import { DEEPSEEK_DEFAULT_EFFORT } from "./translation/dialect/thinking-ladder";
|
|
4
5
|
|
|
5
6
|
/**
|
|
6
7
|
* The effective reasoning effort for a canonical intent, deriving one from an
|
|
@@ -47,7 +48,7 @@ export function applyDeepSeekReasoning(payload: Record<string, unknown>): void {
|
|
|
47
48
|
if (thinking === undefined) payload["thinking"] = { type: "enabled" };
|
|
48
49
|
else if (type.length === 0) thinking["type"] = "enabled";
|
|
49
50
|
if (typeof payload["reasoning_effort"] !== "string" || payload["reasoning_effort"].length === 0)
|
|
50
|
-
payload["reasoning_effort"] =
|
|
51
|
+
payload["reasoning_effort"] = DEEPSEEK_DEFAULT_EFFORT;
|
|
51
52
|
}
|
|
52
53
|
|
|
53
54
|
/**
|
|
@@ -151,59 +152,13 @@ export function geminiThinkingOutputFloor(reasoning: CanonicalRequest["reasoning
|
|
|
151
152
|
|
|
152
153
|
/**
|
|
153
154
|
* Minimum output budget for a caller whose requested effort the ladder could
|
|
154
|
-
* not serve as asked.
|
|
155
|
+
* not serve as asked. See the module doc for why both clamp directions need it.
|
|
156
|
+
* Only ever raises, and only to the model's own catalog limit.
|
|
155
157
|
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
* serves `high` and nothing else — and a request for `max` may be clamped down
|
|
159
|
-
* to it. Either way the caller sized `max_tokens` for the effort it asked for,
|
|
160
|
-
* and effort is not free: the applied level spends its budget on reasoning
|
|
161
|
-
* before it writes the answer, so an answer that fit in 2048 tokens of visible
|
|
162
|
-
* text no longer fits once the reasoning share is taken out of the same 2048.
|
|
163
|
-
*
|
|
164
|
-
* Both directions need the floor, because the mismatch is what costs tokens,
|
|
165
|
-
* not its sign. A caller who asked for `max` with a 2048-token answer in mind
|
|
166
|
-
* is owed the same headroom as one who asked for `low`: the applied level is
|
|
167
|
-
* `high` either way, and `high` reasons out of that 2048 regardless.
|
|
168
|
-
*
|
|
169
|
-
* The symptom this removes is a truncated answer that an agent retries from
|
|
170
|
-
* the top — reading as a loop ("let me do / let me go / let me do it") rather
|
|
171
|
-
* than as a short limit.
|
|
172
|
-
*
|
|
173
|
-
* Only ever raises, and only to the model's own catalog limit: a caller whose
|
|
174
|
-
* effort was served exactly as asked keeps its number, and no provider is
|
|
175
|
-
* asked for more output than it declares.
|
|
158
|
+
* Re-exported from `translation/dialect/model-thinking` (the canonical helper);
|
|
159
|
+
* this shim keeps existing importers (e.g. buddy-chat-shared) stable.
|
|
176
160
|
*/
|
|
177
|
-
export
|
|
178
|
-
requested: string | undefined,
|
|
179
|
-
applied: string | undefined,
|
|
180
|
-
modelOutputLimit: number | undefined,
|
|
181
|
-
): number | undefined {
|
|
182
|
-
if (requested === undefined || applied === undefined) return undefined;
|
|
183
|
-
const from = BUDDY_LEVEL_RANK[requested.trim().toLowerCase()];
|
|
184
|
-
const to = BUDDY_LEVEL_RANK[applied.trim().toLowerCase()];
|
|
185
|
-
if (from === undefined || to === undefined || from === to) return undefined;
|
|
186
|
-
if (modelOutputLimit === undefined || !Number.isFinite(modelOutputLimit) || modelOutputLimit <= 0)
|
|
187
|
-
return undefined;
|
|
188
|
-
// Leave headroom instead of claiming the whole catalog limit: the caller's
|
|
189
|
-
// number was a real preference about answer size, and the goal is to stop
|
|
190
|
-
// truncating, not to spend the model's ceiling on every turn.
|
|
191
|
-
return Math.max(CLAMPED_EFFORT_MIN_OUTPUT_TOKENS, Math.floor(modelOutputLimit / 2));
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
const CLAMPED_EFFORT_MIN_OUTPUT_TOKENS = 16_384;
|
|
195
|
-
|
|
196
|
-
const BUDDY_LEVEL_RANK: Readonly<Record<string, number>> = {
|
|
197
|
-
off: 0,
|
|
198
|
-
none: 0,
|
|
199
|
-
instant: 1,
|
|
200
|
-
minimal: 2,
|
|
201
|
-
low: 3,
|
|
202
|
-
medium: 4,
|
|
203
|
-
high: 5,
|
|
204
|
-
xhigh: 6,
|
|
205
|
-
max: 7,
|
|
206
|
-
};
|
|
161
|
+
export { outputFloorFor as clampedEffortOutputFloor } from "./translation/dialect/model-thinking";
|
|
207
162
|
|
|
208
163
|
/** Builds the Anthropic thinking block from canonical reasoning intent. */
|
|
209
164
|
export function buildAnthropicThinkingPayload(reasoning: ReasoningIntent): Record<string, unknown> {
|