cartethyia 2.7.3 → 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-2TJD37Hb.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-xefJNRmJ.js → CliToolDetailPage-DZKmVuJN.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-DZKmVuJN.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-Rj9iHQ3F.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-BKj_r0rp.js +1 -0
- 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-C4w7vea-.js → LoginPage-DkXb6dx-.js} +1 -1
- package/dist/dashboard/assets/LoginPage-DkXb6dx-.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-BtPcAfot.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-5SnUSy3j.js +9 -0
- 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-BQS0Rx_u.js → SetupPage-WTa0sktC.js} +1 -1
- package/dist/dashboard/assets/SetupPage-WTa0sktC.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-TP7voAQ0.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-C0YYuZJ4.js → assert-C0K-c4eo.js} +1 -1
- package/dist/dashboard/assets/assert-C0K-c4eo.js.gz +0 -0
- package/dist/dashboard/assets/{badge-B_DMpMJN.js → badge-DfbhQU4k.js} +1 -1
- package/dist/dashboard/assets/badge-DfbhQU4k.js.gz +0 -0
- package/dist/dashboard/assets/{banner-DMrMPmth.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-Be5Uzamx.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-muFRphDu.js → cli-tools-CQXVMn4P.js} +1 -1
- package/dist/dashboard/assets/cli-tools-CQXVMn4P.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-DOfrVmsi.js → clipboard-button-BQqBQd2n.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-BQqBQd2n.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-C9omdjQt.js → dialog-BEK7KP0H.js} +1 -1
- package/dist/dashboard/assets/dialog-BEK7KP0H.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-Bm8WKaGY.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-q5HwZ8nN.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-BTScrQpe.js → formatters-BAACA727.js} +1 -1
- package/dist/dashboard/assets/formatters-BAACA727.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-Orjuzemr.js → github-badge-YSCE4UC2.js} +1 -1
- package/dist/dashboard/assets/github-badge-YSCE4UC2.js.gz +0 -0
- package/dist/dashboard/assets/{index-cPrX5vn6.js → index-FQlj0HUT.js} +2 -2
- package/dist/dashboard/assets/index-FQlj0HUT.js.gz +0 -0
- package/dist/dashboard/assets/{inline-Dvux8w-0.js → inline-C4gU5iOL.js} +1 -1
- package/dist/dashboard/assets/inline-C4gU5iOL.js.gz +0 -0
- package/dist/dashboard/assets/{input-CU1Rgf3p.js → input-BHHX_Tmm.js} +1 -1
- package/dist/dashboard/assets/input-BHHX_Tmm.js.gz +0 -0
- package/dist/dashboard/assets/{layout-C_7A6H55.js → layout-CajrYUnD.js} +1 -1
- package/dist/dashboard/assets/{layout-C_7A6H55.js.gz → layout-CajrYUnD.js.gz} +0 -0
- package/dist/dashboard/assets/{list-row-CzFvogbj.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/minimize-2-BTmMTK4o.js +1 -0
- package/dist/dashboard/assets/minimize-2-BTmMTK4o.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-JJGQm8TD.js → mutation-Rr0TIvcj.js} +1 -1
- package/dist/dashboard/assets/mutation-Rr0TIvcj.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/{query-keys-CLaNz8Xz.js → query-keys-BloKtaXJ.js} +1 -1
- package/dist/dashboard/assets/query-keys-BloKtaXJ.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-BEH32QOC.js → routing-in0f_IfK.js} +1 -1
- package/dist/dashboard/assets/routing-in0f_IfK.js.gz +0 -0
- package/dist/dashboard/assets/{select-B3iTetHN.js → select-BLULNqTp.js} +2 -2
- 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-KrOrm7JZ.js → stack-D2lIR0tg.js} +1 -1
- package/dist/dashboard/assets/stack-D2lIR0tg.js.gz +0 -0
- package/dist/dashboard/assets/{state-DLS7IDMy.js → state-DTARjfiW.js} +1 -1
- package/dist/dashboard/assets/state-DTARjfiW.js.gz +0 -0
- package/dist/dashboard/assets/{switch-42ItvbAs.js → switch-c0oPSnqW.js} +1 -1
- package/dist/dashboard/assets/switch-c0oPSnqW.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-Dmnfh1Ue.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 +59 -57
- package/migrations/full-postgres/0027_qoder_identity_genuine_seed.sql +9 -10
- package/migrations/full-postgres/0032_add_provider_pool_accounts.sql +53 -0
- package/migrations/full-postgres/0033_add_api_key_ban.sql +9 -0
- package/migrations/full-postgres/0034_add_api_key_ban_until.sql +7 -0
- package/migrations/full-postgres/0035_align_pool_account_status_enum.sql +21 -0
- 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/0027_qoder_identity_genuine_seed.sql +9 -10
- package/migrations/lite-sqlite3/0032_add_provider_pool_accounts.sql +44 -0
- package/migrations/lite-sqlite3/0033_add_api_key_ban.sql +8 -0
- package/migrations/lite-sqlite3/0034_add_api_key_ban_until.sql +5 -0
- package/migrations/lite-sqlite3/0035_align_pool_account_status_enum.sql +6 -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 -5
- package/scripts/cli/update.ts +15 -41
- package/src/boot/app.ts +67 -10
- 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 +8 -4
- 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 +92 -31
- package/src/console/api-keys/routes.ts +131 -6
- package/src/console/audit/routes.ts +3 -3
- package/src/console/auth/access.ts +4 -4
- package/src/console/auth/account-reset.ts +5 -5
- 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 +40 -34
- 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 +11 -9
- package/src/console/backup/export-endpoint.ts +11 -12
- package/src/console/backup/nine-router.ts +1 -7
- package/src/console/backup/routes.ts +32 -36
- 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 +4 -4
- package/src/console/cli-tools/service.ts +1 -1
- package/src/console/cli-tools/store.ts +2 -2
- package/src/console/console-router-guards.ts +2 -2
- package/src/console/console-router.ts +36 -4
- package/src/console/dashboard-assets.ts +9 -9
- package/src/console/data-management/routes.ts +3 -3
- package/src/console/domain-registration.ts +18 -4
- 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 +5 -1
- package/src/console/observability/live.ts +34 -21
- package/src/console/observability/logs.ts +4 -4
- package/src/console/observability/performance.ts +3 -3
- package/src/console/observability/routes.ts +3 -3
- package/src/console/observability/sse.ts +62 -8
- package/src/console/observability/store.ts +36 -20
- package/src/console/providers/catalog/catalog-projections.ts +1 -1
- package/src/console/providers/catalog/contracts.ts +82 -22
- package/src/console/providers/catalog/model-operations.ts +1 -1
- package/src/console/providers/catalog/provider-operations.ts +110 -17
- package/src/console/providers/catalog/public-model-store.ts +0 -0
- package/src/console/providers/catalog/routes.ts +30 -6
- package/src/console/providers/catalog/store-helpers.ts +349 -326
- package/src/console/providers/catalog/store.ts +1662 -1292
- package/src/console/providers/detail/routes.ts +4 -4
- package/src/console/providers/oauth/callback-listener.ts +100 -18
- package/src/console/providers/oauth/routes.ts +95 -16
- 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 +285 -67
- package/src/console/quota/account-test-egress.ts +4 -4
- 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/model/routes.ts +3 -3
- package/src/console/routing/pools/contracts.ts +13 -10
- package/src/console/routing/pools/import-parse.ts +3 -3
- package/src/console/routing/pools/operations.ts +14 -7
- package/src/console/routing/pools/probe-verdict.ts +8 -3
- package/src/console/routing/pools/relay-deploy.ts +12 -12
- package/src/console/routing/pools/routes.ts +3 -3
- package/src/console/routing/pools/store.ts +21 -1
- package/src/console/settings/contracts.ts +29 -2
- package/src/console/settings/routes.ts +3 -3
- package/src/console/settings/store.ts +20 -0
- package/src/console/share/share-router.ts +112 -44
- package/src/console/share/share-stats.ts +109 -39
- 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 +42 -6
- 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 +256 -98
- 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 +76 -5
- package/src/network/pool/agent.ts +7 -6
- package/src/network/pool/byte-accounting.ts +1 -1
- package/src/network/pool/resolver.ts +55 -51
- package/src/network/pool/selector.ts +150 -136
- package/src/network/pool-cooldown-store.ts +71 -16
- package/src/network/pool-health-machine.ts +22 -2
- package/src/network/rate-limit-verdict.ts +68 -0
- package/src/network/retry.ts +1 -1
- package/src/network/ssrf.ts +24 -75
- package/src/observability/event-log.ts +2 -2
- package/src/observability/event-query.ts +286 -214
- 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/telemetry-status.ts +1 -1
- 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 +10 -5
- package/src/persistence/dialect.ts +5 -1
- package/src/persistence/readiness.ts +19 -7
- package/src/persistence/redis.ts +1 -1
- package/src/persistence/schema.ts +177 -45
- package/src/persistence/shared-cache.ts +2 -2
- package/src/persistence/sort-order.ts +1 -1
- package/src/persistence/stores/api-key-store.ts +109 -4
- package/src/persistence/stores/share-store.ts +20 -8
- package/src/persistence/stores/telemetry-store.ts +1 -1
- 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 +12 -16
- package/src/protocol/dsml.ts +3 -49
- package/src/protocol/gateway-error.ts +6 -3
- package/src/protocol/image-clamp.ts +2 -2
- package/src/protocol/image-generation.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 +27 -12
- package/src/protocol/response/codex.ts +2 -2
- package/src/protocol/response/gemini.ts +1 -1
- package/src/protocol/response/messages.ts +6 -6
- package/src/protocol/response/omp-tool-call-markup.ts +1 -1
- package/src/protocol/response/responses.ts +3 -3
- package/src/protocol/sse-decoder.ts +64 -4
- 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 +8 -8
- 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/protocol/upstream/send-claude-messages.ts +3 -3
- package/src/providers/adapters/base-adapter.ts +1 -1
- package/src/providers/adapters/compatible-adapter.ts +44 -5
- 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/authentication/oauth-refresh-service.ts +2 -2
- package/src/providers/bundled-discovery-providers.ts +6 -30
- package/src/providers/configured-openai-providers.ts +82 -97
- package/src/providers/configured-provider.ts +1 -1
- 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 +50 -15
- package/src/providers/discovery/probing-service.ts +18 -20
- package/src/providers/integrations/agentrouter/agentrouter.ts +14 -5
- package/src/providers/integrations/alibabacp/alibabacp.ts +2 -2
- package/src/providers/integrations/anthropic.ts +4 -11
- 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 +15 -26
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +2 -2
- 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-discovery-shared.ts +37 -6
- package/src/providers/integrations/buddy/buddy-identity.ts +108 -1
- package/src/providers/integrations/buddy/buddy-media.ts +16 -16
- 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 +5 -16
- package/src/providers/integrations/buddy/codebuddy/shared.ts +30 -9
- package/src/providers/integrations/buddy/workbuddy/provider.ts +6 -10
- package/src/providers/integrations/buddy/workbuddy/shared.ts +21 -3
- package/src/providers/integrations/claude/claude-betas.ts +1 -1
- package/src/providers/integrations/claude/claude-cch.ts +148 -148
- package/src/providers/integrations/claude/claude-credentials.ts +1 -1
- package/src/providers/integrations/claude/claude-slow-lane-retry.ts +1 -1
- package/src/providers/integrations/claude/claude.ts +3 -10
- package/src/providers/integrations/claude/fallback-credit.ts +3 -7
- package/src/providers/integrations/cline/cline.ts +2 -2
- package/src/providers/integrations/cloudflareai/cloudflareai.ts +4 -7
- package/src/providers/integrations/codex/codex-device-code.ts +101 -101
- package/src/providers/integrations/codex/codex-errors.ts +1 -1
- package/src/providers/integrations/codex/codex-oauth.ts +0 -1
- package/src/providers/integrations/codex/codex.ts +14 -15
- package/src/providers/integrations/commandcode/commandcode.ts +76 -116
- package/src/providers/integrations/commandcode/quota.ts +132 -48
- package/src/providers/integrations/cursor/cursor-http2.ts +11 -14
- 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 +53 -20
- 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 +13 -13
- package/src/providers/integrations/gemini.ts +11 -11
- 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 +47 -20
- 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 +88 -42
- package/src/providers/integrations/inferhub.ts +4 -11
- package/src/providers/integrations/kilo/kilo-oauth.ts +1 -1
- package/src/providers/integrations/kimi/kimi.ts +4 -11
- 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 +91 -78
- package/src/providers/integrations/muse/muse-oauth.ts +0 -1
- package/src/providers/integrations/muse/muse-quota.ts +0 -4
- package/src/providers/integrations/muse/muse.ts +6 -9
- package/src/providers/integrations/opencode/fingerprint.ts +7 -5
- package/src/providers/integrations/opencode/provider.ts +17 -24
- package/src/providers/integrations/perplexity.ts +2 -2
- package/src/providers/integrations/qoder/qoder-catalog.ts +132 -17
- package/src/providers/integrations/qoder/qoder-checkin.ts +26 -8
- package/src/providers/integrations/qoder/qoder-native-identity-store.ts +9 -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 +22 -28
- package/src/providers/integrations/qoder/qoder-sse.ts +159 -0
- package/src/providers/integrations/qoder/qoder-umid.ts +33 -38
- package/src/providers/integrations/qoder/qoder-virtual.ts +14 -2
- package/src/providers/integrations/qoder/qoder.ts +521 -63
- 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/tokenharbor.ts +2 -2
- 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 +59 -19
- package/src/providers/integrations/xai/xai-oauth.ts +5 -5
- package/src/providers/integrations/zcode/oauth.ts +1 -1
- 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 +22 -6
- package/src/providers/operations/provider-credential-service.ts +35 -6
- package/src/providers/operations/upstream-deadline.ts +3 -3
- package/src/providers/provider-contracts.ts +65 -10
- package/src/providers/provider-credential-resolver.ts +1 -1
- 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-registry.ts +4 -4
- package/src/providers/provider-usage.ts +81 -16
- package/src/providers/quota/cache.ts +29 -0
- package/src/providers/quota/quota-contracts.ts +28 -10
- package/src/providers/quota/refresh.ts +29 -6
- package/src/providers/quota/snapshot.ts +94 -0
- package/src/providers/search/search-provider.ts +6 -8
- package/src/providers/search/search-providers.ts +2 -1
- package/src/security/abuse.ts +8 -8
- package/src/security/admission/reasons.ts +17 -17
- package/src/security/admission/service.ts +2 -2
- package/src/security/admission/ttl.ts +61 -61
- package/src/security/api-key-auth.ts +20 -8
- 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/coerce.ts +19 -0
- package/src/shared/invoke-guard.ts +47 -0
- package/src/transport/contracts.ts +13 -4
- package/src/transport/dispatch/attempt-finalize.ts +5 -4
- package/src/transport/dispatch/attempt-loop.ts +10 -7
- package/src/transport/dispatch/capture-policy.ts +34 -37
- package/src/transport/dispatch/empty-stream.ts +28 -25
- package/src/transport/dispatch/generation.ts +33 -53
- package/src/transport/dispatch/leases.ts +8 -8
- package/src/transport/dispatch/native-shared.ts +127 -0
- package/src/transport/dispatch/proxy-request.ts +10 -8
- package/src/transport/dispatch/responses-compact.ts +35 -56
- package/src/transport/dispatch/retry-policy.ts +4 -67
- package/src/transport/dispatch/stream-bridge.ts +1 -1
- package/src/transport/dispatch/streaming/encoder.ts +18 -72
- package/src/transport/dispatch/streaming/finalize.ts +11 -10
- 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 +27 -55
- package/src/transport/dispatch/token-count.ts +49 -46
- package/src/transport/dispatch/websearch.ts +24 -50
- package/src/transport/drain-endpoint.ts +3 -3
- package/src/transport/failure-policy.ts +19 -6
- package/src/transport/guards/auth-guard.ts +6 -11
- package/src/transport/guards/body-policy.ts +7 -7
- package/src/transport/guards/error-lifecycle.ts +18 -3
- package/src/transport/guards/guard-errors.ts +7 -3
- package/src/transport/guards/headroom-guard.ts +2 -2
- package/src/transport/guards/pipeline.ts +7 -7
- package/src/transport/guards/readiness-guard.ts +16 -2
- package/src/transport/guards/request-context.ts +15 -20
- package/src/transport/request/preparer.ts +306 -27
- 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 +5 -20
- 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 +113 -19
- package/src/transport/routing/route-model.ts +131 -38
- package/src/transport/routing/router.ts +154 -39
- package/src/transport/shutdown-notice.ts +21 -9
- 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 +3 -3
- package/src/transport/surface/content-parts.ts +1 -1
- package/src/transport/surface/dialects.ts +2 -2
- package/src/transport/surface/messages/encode.ts +1 -1
- 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-2TJD37Hb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-xefJNRmJ.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-Rj9iHQ3F.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-JEbYJFxw.js +0 -1
- package/dist/dashboard/assets/CombosPage-JEbYJFxw.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-C3xx_inM.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-C3xx_inM.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js +0 -1
- package/dist/dashboard/assets/CustomizationPage-Dw306gJU.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-jaBo1TWV.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-C4w7vea-.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-BtPcAfot.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js +0 -1
- package/dist/dashboard/assets/OverviewPage-CGC5gNs1.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.js +0 -4
- package/dist/dashboard/assets/ProviderDetailPage-DQcthNGt.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-0OsXRGXe.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-0OsXRGXe.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-DdPc8slb.js +0 -9
- package/dist/dashboard/assets/ProxyPage-DdPc8slb.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-Ci5O4BnH.js +0 -1
- package/dist/dashboard/assets/QuotaPage-Ci5O4BnH.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CDZjTt87.js +0 -1
- package/dist/dashboard/assets/SettingsPage-CDZjTt87.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-BQS0Rx_u.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-BAL5npBC.js +0 -1
- package/dist/dashboard/assets/SortableList-BAL5npBC.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-TP7voAQ0.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-Cj_fEzhg.js +0 -56
- package/dist/dashboard/assets/UsagePage-Cj_fEzhg.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-MbI7e7rt.js +0 -1
- package/dist/dashboard/assets/api-keys-MbI7e7rt.js.gz +0 -0
- package/dist/dashboard/assets/app-B2vyPoII.css +0 -2
- package/dist/dashboard/assets/app-B2vyPoII.css.gz +0 -0
- package/dist/dashboard/assets/assert-C0YYuZJ4.js.gz +0 -0
- package/dist/dashboard/assets/badge-B_DMpMJN.js.gz +0 -0
- package/dist/dashboard/assets/banner-DMrMPmth.js.gz +0 -0
- package/dist/dashboard/assets/card-Be5Uzamx.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-muFRphDu.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-DOfrVmsi.js.gz +0 -0
- package/dist/dashboard/assets/dialog-C9omdjQt.js.gz +0 -0
- package/dist/dashboard/assets/drawer-Bm8WKaGY.js.gz +0 -0
- package/dist/dashboard/assets/entry-DS90gUks.js +0 -1
- package/dist/dashboard/assets/entry-DS90gUks.js.gz +0 -0
- package/dist/dashboard/assets/entry-j40LJotO.js +0 -4
- package/dist/dashboard/assets/entry-j40LJotO.js.gz +0 -0
- package/dist/dashboard/assets/entry-q5HwZ8nN.js.gz +0 -0
- package/dist/dashboard/assets/formatters-BTScrQpe.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-Orjuzemr.js.gz +0 -0
- package/dist/dashboard/assets/index-cPrX5vn6.js.gz +0 -0
- package/dist/dashboard/assets/inline-Dvux8w-0.js.gz +0 -0
- package/dist/dashboard/assets/input-CU1Rgf3p.js.gz +0 -0
- package/dist/dashboard/assets/list-row-CzFvogbj.js.gz +0 -0
- package/dist/dashboard/assets/live-KaG15HLQ.js +0 -1
- package/dist/dashboard/assets/live-KaG15HLQ.js.gz +0 -0
- package/dist/dashboard/assets/minimize-2-D-MN8W8a.js +0 -1
- package/dist/dashboard/assets/minimize-2-D-MN8W8a.js.gz +0 -0
- package/dist/dashboard/assets/mutation-JJGQm8TD.js.gz +0 -0
- package/dist/dashboard/assets/numbers-BNDZnsUE.js +0 -2
- package/dist/dashboard/assets/numbers-BNDZnsUE.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-CLaNz8Xz.js.gz +0 -0
- package/dist/dashboard/assets/quota-DZGyp0N5.js +0 -1
- package/dist/dashboard/assets/quota-DZGyp0N5.js.gz +0 -0
- package/dist/dashboard/assets/routing-BEH32QOC.js.gz +0 -0
- package/dist/dashboard/assets/select-B3iTetHN.js.gz +0 -0
- package/dist/dashboard/assets/settings-Dt3Eqbnq.js +0 -1
- package/dist/dashboard/assets/settings-Dt3Eqbnq.js.gz +0 -0
- package/dist/dashboard/assets/stack-KrOrm7JZ.js.gz +0 -0
- package/dist/dashboard/assets/state-DLS7IDMy.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-42ItvbAs.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-Dmnfh1Ue.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-wvwCi4Eh.js → app-Bgd3zANQ.js} +0 -0
- /package/dist/dashboard/assets/{app-wvwCi4Eh.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
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
|
-
}
|
|
@@ -6,12 +6,14 @@ export type GatewayErrorCode =
|
|
|
6
6
|
| "capability_unsupported"
|
|
7
7
|
| "ambiguous_model"
|
|
8
8
|
| "model_not_found"
|
|
9
|
+
| "model_not_allowed"
|
|
9
10
|
| "upstream_not_found"
|
|
10
11
|
| "context_length_exceeded"
|
|
11
12
|
| "request_too_large"
|
|
12
13
|
| "accounts_unavailable"
|
|
13
14
|
| "accounts_rate_limited"
|
|
14
15
|
| "capacity_exhausted"
|
|
16
|
+
| "upstream_overloaded"
|
|
15
17
|
| "provider_capacity_exhausted"
|
|
16
18
|
| "upstream_queued"
|
|
17
19
|
| "proxy_pool_capacity_exceeded"
|
|
@@ -22,8 +24,10 @@ export type GatewayErrorCode =
|
|
|
22
24
|
| "proxy_pool_unhealthy"
|
|
23
25
|
| "invalid_pool_limits"
|
|
24
26
|
| "admission_unavailable"
|
|
27
|
+
| "route_unavailable"
|
|
25
28
|
| "slug_reserved"
|
|
26
29
|
| "quota_exceeded"
|
|
30
|
+
| "rate_limited"
|
|
27
31
|
| "authentication_failed"
|
|
28
32
|
| "policy_rejected"
|
|
29
33
|
| "invalid_request"
|
|
@@ -52,8 +56,7 @@ export type GatewayErrorCode =
|
|
|
52
56
|
| "proxy_unreachable"
|
|
53
57
|
| "tool_call_loop_detected"
|
|
54
58
|
| "client_router_denied"
|
|
55
|
-
| "shutting_down"
|
|
56
|
-
| "restart_for_update";
|
|
59
|
+
| "shutting_down";
|
|
57
60
|
|
|
58
61
|
/** Identifies which boundary produced a safe public error. */
|
|
59
62
|
export type GatewayErrorOrigin = "cartethyia" | "upstream" | "network";
|
|
@@ -226,7 +229,7 @@ export function capabilityUnsupported(
|
|
|
226
229
|
return new GatewayError(
|
|
227
230
|
"capability_unsupported",
|
|
228
231
|
400,
|
|
229
|
-
`The selected route does not support capability: ${capability}
|
|
232
|
+
`The selected route does not support capability: ${capability} (request {requestId}). Drop the ${capability} part of the request, or route to a model that accepts it. Know your tools — this one just isn't in the box 🧰`,
|
|
230
233
|
{ capability, ...details },
|
|
231
234
|
);
|
|
232
235
|
}
|
|
@@ -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;
|
|
@@ -22,7 +22,7 @@ const OPENAI_ASPECT_RATIOS: Readonly<Record<string, string>> = {
|
|
|
22
22
|
export function imagePrompt(body: Record<string, unknown>): string {
|
|
23
23
|
if (typeof body.prompt === "string" && body.prompt.trim().length > 0) return body.prompt;
|
|
24
24
|
if (!Array.isArray(body.messages)) {
|
|
25
|
-
throw new GatewayError("invalid_request", 400, "prompt is required");
|
|
25
|
+
throw new GatewayError("invalid_request", 400, "prompt is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
26
26
|
}
|
|
27
27
|
const texts: string[] = [];
|
|
28
28
|
for (const message of body.messages) {
|
|
@@ -41,7 +41,7 @@ export function imagePrompt(body: Record<string, unknown>): string {
|
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
43
|
const prompt = texts.join("\n").trim();
|
|
44
|
-
if (prompt.length === 0) throw new GatewayError("invalid_request", 400, "prompt is required");
|
|
44
|
+
if (prompt.length === 0) throw new GatewayError("invalid_request", 400, "prompt is required (request {requestId}). Check the shape of what you sent — then resend 🪞");
|
|
45
45
|
return prompt;
|
|
46
46
|
}
|
|
47
47
|
|
|
@@ -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> {
|
package/src/protocol/registry.ts
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import type { CanonicalEvent, CanonicalRequest, WireFamily } from "./canonical-model";
|
|
2
|
+
import type { DialectPolicy } from "./translation/dialect/types";
|
|
3
|
+
import type { ThinkingConfig } from "./translation/dialect/thinking-ladder";
|
|
2
4
|
|
|
3
|
-
|
|
5
|
+
interface CodecContext {
|
|
4
6
|
readonly isOAuth?: boolean;
|
|
5
7
|
readonly sessionId?: string;
|
|
6
8
|
readonly supportsPromptCaching?: boolean;
|
|
@@ -13,6 +15,16 @@ export interface CodecContext {
|
|
|
13
15
|
* deployment default; only wire encoders that clamp images read it.
|
|
14
16
|
*/
|
|
15
17
|
readonly maxBytesOverride?: number;
|
|
18
|
+
/**
|
|
19
|
+
* Resolved wire dialect (see `translation/dialect`). Absent = the codec's
|
|
20
|
+
* own default behavior (today's exact bytes).
|
|
21
|
+
*/
|
|
22
|
+
readonly dialectPolicy?: DialectPolicy;
|
|
23
|
+
/**
|
|
24
|
+
* Resolved thinking config (see `translation/dialect/thinking-ladder`).
|
|
25
|
+
* Absent = the codec's own default behavior (today's exact clamp/ladder).
|
|
26
|
+
*/
|
|
27
|
+
readonly thinking?: ThinkingConfig;
|
|
16
28
|
}
|
|
17
29
|
|
|
18
30
|
/**
|
|
@@ -27,7 +39,13 @@ type CodecModule =
|
|
|
27
39
|
readonly family: "messages";
|
|
28
40
|
readonly encodeWireRequest: (
|
|
29
41
|
request: CanonicalRequest,
|
|
30
|
-
options?: {
|
|
42
|
+
options?: {
|
|
43
|
+
readonly isOAuth?: boolean;
|
|
44
|
+
readonly maxBytesOverride?: number;
|
|
45
|
+
readonly dialectPolicy?: DialectPolicy;
|
|
46
|
+
readonly thinking?: ThinkingConfig;
|
|
47
|
+
readonly maxOutputTokens?: number;
|
|
48
|
+
},
|
|
31
49
|
) => Record<string, unknown>;
|
|
32
50
|
readonly decodeWireResponse: (
|
|
33
51
|
json: Record<string, unknown>,
|
|
@@ -48,6 +66,8 @@ type CodecModule =
|
|
|
48
66
|
readonly supportsPromptCaching?: boolean;
|
|
49
67
|
readonly tokenLimitField?: "max_tokens" | "max_completion_tokens";
|
|
50
68
|
readonly promptCacheKey?: string;
|
|
69
|
+
readonly dialectPolicy?: DialectPolicy;
|
|
70
|
+
readonly thinking?: ThinkingConfig;
|
|
51
71
|
},
|
|
52
72
|
) => Record<string, unknown>;
|
|
53
73
|
readonly decodeWireResponse: (
|
|
@@ -58,6 +78,7 @@ type CodecModule =
|
|
|
58
78
|
body: ReadableStream<Uint8Array>,
|
|
59
79
|
request: CanonicalRequest,
|
|
60
80
|
signal?: AbortSignal,
|
|
81
|
+
options?: { readonly dialectPolicy?: DialectPolicy },
|
|
61
82
|
) => AsyncIterable<CanonicalEvent>;
|
|
62
83
|
}
|
|
63
84
|
| {
|
|
@@ -67,6 +88,9 @@ type CodecModule =
|
|
|
67
88
|
options?: {
|
|
68
89
|
readonly supportsPromptCaching?: boolean;
|
|
69
90
|
readonly promptCacheKey?: string;
|
|
91
|
+
readonly dialectPolicy?: DialectPolicy;
|
|
92
|
+
readonly thinking?: ThinkingConfig;
|
|
93
|
+
readonly maxOutputTokens?: number;
|
|
70
94
|
},
|
|
71
95
|
) => Record<string, unknown>;
|
|
72
96
|
readonly decodeWireResponse: (
|
|
@@ -89,8 +113,10 @@ type CodecModule =
|
|
|
89
113
|
*
|
|
90
114
|
* The dynamic import is awaited by the caller. Wire encoding happens before the
|
|
91
115
|
* upstream request is issued, so the cost is paid once, on the first request,
|
|
92
|
-
*
|
|
93
|
-
*
|
|
116
|
+
* The cost is paid once, on the first request for that family, because wire
|
|
117
|
+
* encoding happens before the upstream request is issued. There is no preload
|
|
118
|
+
* at boot: no family is knowable then, and eagerly loading all three codecs
|
|
119
|
+
* would defeat the ~50 MiB of resident memory this indirection removes.
|
|
94
120
|
*/
|
|
95
121
|
const codecCache = new Map<WireFamily, Promise<CodecModule>>();
|
|
96
122
|
|
|
@@ -103,8 +129,8 @@ const codecCache = new Map<WireFamily, Promise<CodecModule>>();
|
|
|
103
129
|
* a gateway instance only ever serves one family.
|
|
104
130
|
*
|
|
105
131
|
* The cost is paid once, on the first request for that family, because wire
|
|
106
|
-
* encoding happens before the upstream request is issued.
|
|
107
|
-
*
|
|
132
|
+
* encoding happens before the upstream request is issued. No boot-time preload
|
|
133
|
+
* exists — see the note on `codecCache` above.
|
|
108
134
|
*/
|
|
109
135
|
async function loadCodec(wireFamily: WireFamily): Promise<CodecModule> {
|
|
110
136
|
const cached = codecCache.get(wireFamily);
|
|
@@ -127,15 +153,6 @@ async function loadCodec(wireFamily: WireFamily): Promise<CodecModule> {
|
|
|
127
153
|
return promise;
|
|
128
154
|
}
|
|
129
155
|
|
|
130
|
-
/**
|
|
131
|
-
* Warms the codec module for a wire family during boot so the first request
|
|
132
|
-
* does not pay the dynamic-import cost. Safe to call concurrently; the cache
|
|
133
|
-
* deduplicates.
|
|
134
|
-
*/
|
|
135
|
-
export function preloadCodec(wireFamily: WireFamily): Promise<void> {
|
|
136
|
-
return loadCodec(wireFamily).then(() => undefined);
|
|
137
|
-
}
|
|
138
|
-
|
|
139
156
|
export async function encodeWireRequest(
|
|
140
157
|
wireFamily: WireFamily,
|
|
141
158
|
request: CanonicalRequest,
|
|
@@ -148,6 +165,11 @@ export async function encodeWireRequest(
|
|
|
148
165
|
...(context?.maxBytesOverride === undefined
|
|
149
166
|
? {}
|
|
150
167
|
: { maxBytesOverride: context.maxBytesOverride }),
|
|
168
|
+
...(context?.maxOutputTokens === undefined
|
|
169
|
+
? {}
|
|
170
|
+
: { maxOutputTokens: context.maxOutputTokens }),
|
|
171
|
+
...(context?.dialectPolicy === undefined ? {} : { dialectPolicy: context.dialectPolicy }),
|
|
172
|
+
...(context?.thinking === undefined ? {} : { thinking: context.thinking }),
|
|
151
173
|
});
|
|
152
174
|
}
|
|
153
175
|
if (codec.family === "chat") {
|
|
@@ -164,6 +186,8 @@ export async function encodeWireRequest(
|
|
|
164
186
|
...(context?.promptCacheKey === undefined
|
|
165
187
|
? {}
|
|
166
188
|
: { promptCacheKey: context.promptCacheKey }),
|
|
189
|
+
...(context?.dialectPolicy === undefined ? {} : { dialectPolicy: context.dialectPolicy }),
|
|
190
|
+
...(context?.thinking === undefined ? {} : { thinking: context.thinking }),
|
|
167
191
|
});
|
|
168
192
|
}
|
|
169
193
|
return codec.encodeWireRequest(request, {
|
|
@@ -173,6 +197,11 @@ export async function encodeWireRequest(
|
|
|
173
197
|
...(context?.promptCacheKey === undefined
|
|
174
198
|
? {}
|
|
175
199
|
: { promptCacheKey: context.promptCacheKey }),
|
|
200
|
+
...(context?.maxOutputTokens === undefined
|
|
201
|
+
? {}
|
|
202
|
+
: { maxOutputTokens: context.maxOutputTokens }),
|
|
203
|
+
...(context?.dialectPolicy === undefined ? {} : { dialectPolicy: context.dialectPolicy }),
|
|
204
|
+
...(context?.thinking === undefined ? {} : { thinking: context.thinking }),
|
|
176
205
|
});
|
|
177
206
|
}
|
|
178
207
|
|
|
@@ -206,6 +235,12 @@ export function decodeWireStream(
|
|
|
206
235
|
yield* codec.decodeWireStream(body, context?.signal, context?.isOAuth ?? false);
|
|
207
236
|
return;
|
|
208
237
|
}
|
|
238
|
+
if (codec.family === "chat") {
|
|
239
|
+
yield* codec.decodeWireStream(body, request, context?.signal, {
|
|
240
|
+
...(context?.dialectPolicy === undefined ? {} : { dialectPolicy: context.dialectPolicy }),
|
|
241
|
+
});
|
|
242
|
+
return;
|
|
243
|
+
}
|
|
209
244
|
yield* codec.decodeWireStream(body, request, context?.signal);
|
|
210
245
|
}
|
|
211
246
|
return decode();
|
|
@@ -8,15 +8,19 @@ import { isWebSearchTool } from "../../protocol/translation/search";
|
|
|
8
8
|
import { pickWireSupportedControls } from "../../protocol/translation/capabilities";
|
|
9
9
|
import { normalizeWireMaxTokens } from "../../protocol/translation/normalize";
|
|
10
10
|
import { resolveWireMaxTokens } from "../../protocol/translation/quirks";
|
|
11
|
-
import {
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
} from "../../protocol/translation/thinking";
|
|
11
|
+
import { DEFAULT_DIALECT_POLICIES } from "../../protocol/translation/dialect/rules";
|
|
12
|
+
import type { DialectPolicy } from "../../protocol/translation/dialect/types";
|
|
13
|
+
import type { ThinkingConfig } from "../../protocol/translation/dialect/thinking-ladder";
|
|
14
|
+
import { resolveThinkingForModel } from "../../protocol/translation/dialect/thinking-ladder";
|
|
15
|
+
import { clampThinkingLevelForModel } from "../../protocol/translation/dialect/model-thinking";
|
|
15
16
|
import { isClaudeBillingHeaderText, resolveImageSource } from "../codecs";
|
|
16
17
|
import { resolvePromptCacheKey } from "../../providers/operations/session-resolution";
|
|
17
18
|
import { reasoningEffortFromIntent } from "../../protocol/reasoning";
|
|
18
19
|
import { parseChatResponseToEvents, decodeChatSseStream } from "../response/chat";
|
|
19
20
|
|
|
21
|
+
/** Fallback when no resolved policy is supplied — today's exact behavior. */
|
|
22
|
+
const DEFAULT_CHAT_DIALECT_POLICY: DialectPolicy = DEFAULT_DIALECT_POLICIES.openai;
|
|
23
|
+
|
|
20
24
|
/**
|
|
21
25
|
* OpenAI `input_audio.format` accepts only the discrete ids `wav`/`mp3`, never a
|
|
22
26
|
* MIME type. The canonical `audio` part carries a `media_type`; map it here and
|
|
@@ -182,15 +186,31 @@ export function canonicalToChatPayload(
|
|
|
182
186
|
readonly tokenLimitField?: "max_tokens" | "max_completion_tokens";
|
|
183
187
|
readonly maxOutputTokens?: number;
|
|
184
188
|
readonly promptCacheKey?: string;
|
|
189
|
+
readonly dialectPolicy?: DialectPolicy;
|
|
190
|
+
readonly thinking?: ThinkingConfig;
|
|
185
191
|
} = {},
|
|
186
192
|
): Record<string, unknown> {
|
|
193
|
+
const policy = options.dialectPolicy ?? DEFAULT_CHAT_DIALECT_POLICY;
|
|
194
|
+
const resolvedThinking = options.thinking ?? resolveThinkingForModel(request.model, "", "chat");
|
|
187
195
|
const supportsPromptCaching = options.supportsPromptCaching ?? true;
|
|
188
|
-
const tokenLimitField = options.tokenLimitField ??
|
|
196
|
+
const tokenLimitField = options.tokenLimitField ?? policy.maxTokensField;
|
|
197
|
+
const reasoningField = policy.reasoningContentField;
|
|
198
|
+
const carryReasoning = (has: boolean, text: string): Record<string, unknown> =>
|
|
199
|
+
has && reasoningField !== undefined ? { [reasoningField]: text } : {};
|
|
189
200
|
const messages: Array<Record<string, unknown>> = [];
|
|
201
|
+
const systemTexts: string[] = [];
|
|
190
202
|
if (request.system?.length) {
|
|
191
203
|
for (const p of request.system) {
|
|
192
|
-
if (p.kind === "text" && !isClaudeBillingHeaderText(p.text))
|
|
193
|
-
|
|
204
|
+
if (p.kind === "text" && !isClaudeBillingHeaderText(p.text)) systemTexts.push(p.text);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (systemTexts.length > 0) {
|
|
208
|
+
if (policy.supportsMultipleSystemMessages) {
|
|
209
|
+
for (const text of systemTexts) messages.push({ role: "system", content: text });
|
|
210
|
+
} else {
|
|
211
|
+
// Strict chat templates (Qwen Portal / Alibaba / MiniMax) accept a single
|
|
212
|
+
// system message; join the canonical system parts into one.
|
|
213
|
+
messages.push({ role: "system", content: systemTexts.join("\n") });
|
|
194
214
|
}
|
|
195
215
|
}
|
|
196
216
|
if (request.instructions?.length) {
|
|
@@ -217,6 +237,12 @@ export function canonicalToChatPayload(
|
|
|
217
237
|
(c): c is Extract<typeof c, { kind: "text" }> => c.kind === "text",
|
|
218
238
|
);
|
|
219
239
|
const content = textParts.length ? textParts.map((c) => c.text).join("\n") : null;
|
|
240
|
+
// DeepSeek V4 requires the assistant content field to be present on a
|
|
241
|
+
// tool-call turn; a null content would be rejected verbatim.
|
|
242
|
+
const effectiveContent =
|
|
243
|
+
policy.requiresAssistantContentForToolCalls && (content === null || content.length === 0)
|
|
244
|
+
? ""
|
|
245
|
+
: content;
|
|
220
246
|
// Reasoning must survive on a tool-call turn, not just on plain assistant
|
|
221
247
|
// turns. Providers in thinking mode require the previous turn's reasoning
|
|
222
248
|
// to be replayed, and the tool-call turn is exactly where a thinking
|
|
@@ -237,9 +263,9 @@ export function canonicalToChatPayload(
|
|
|
237
263
|
const hasReasoning = m.content.some((c) => c.kind === "reasoning");
|
|
238
264
|
messages.push({
|
|
239
265
|
role: "assistant",
|
|
240
|
-
content,
|
|
266
|
+
content: effectiveContent,
|
|
241
267
|
tool_calls: toolCalls,
|
|
242
|
-
...(hasReasoning
|
|
268
|
+
...carryReasoning(hasReasoning, reasoningContent),
|
|
243
269
|
});
|
|
244
270
|
} else if (m.role === "tool") {
|
|
245
271
|
for (const p of m.content) {
|
|
@@ -332,9 +358,7 @@ export function canonicalToChatPayload(
|
|
|
332
358
|
messages.push({
|
|
333
359
|
role: m.role,
|
|
334
360
|
content: parts,
|
|
335
|
-
...(m.role === "assistant" && hasReasoning
|
|
336
|
-
? { reasoning_content: reasoningContent }
|
|
337
|
-
: {}),
|
|
361
|
+
...carryReasoning(m.role === "assistant" && hasReasoning, reasoningContent),
|
|
338
362
|
});
|
|
339
363
|
} else {
|
|
340
364
|
// A user turn whose toolResult parts were all folded out above has
|
|
@@ -374,7 +398,7 @@ export function canonicalToChatPayload(
|
|
|
374
398
|
messages.push({
|
|
375
399
|
role: "assistant",
|
|
376
400
|
content: "",
|
|
377
|
-
|
|
401
|
+
...carryReasoning(true, reasoningContent),
|
|
378
402
|
});
|
|
379
403
|
continue;
|
|
380
404
|
}
|
|
@@ -401,9 +425,7 @@ export function canonicalToChatPayload(
|
|
|
401
425
|
messages.push({
|
|
402
426
|
role: m.role,
|
|
403
427
|
content,
|
|
404
|
-
...(m.role === "assistant" && hasReasoning
|
|
405
|
-
? { reasoning_content: reasoningContent }
|
|
406
|
-
: {}),
|
|
428
|
+
...carryReasoning(m.role === "assistant" && hasReasoning, reasoningContent),
|
|
407
429
|
});
|
|
408
430
|
}
|
|
409
431
|
}
|
|
@@ -458,7 +480,7 @@ export function canonicalToChatPayload(
|
|
|
458
480
|
};
|
|
459
481
|
});
|
|
460
482
|
}
|
|
461
|
-
if (request.tool_choice) {
|
|
483
|
+
if (request.tool_choice && policy.supportsToolChoice) {
|
|
462
484
|
if (typeof request.tool_choice === "object" && request.tool_choice.type === "allowed_tools") {
|
|
463
485
|
payload["tool_choice"] = {
|
|
464
486
|
type: "allowed_tools",
|
|
@@ -484,11 +506,16 @@ export function canonicalToChatPayload(
|
|
|
484
506
|
// is what the Codex encoder already uses); deriving it here instead of in
|
|
485
507
|
// each codec is what keeps a translated request from silently losing it.
|
|
486
508
|
if (request.reasoning !== undefined) {
|
|
487
|
-
const effort =
|
|
509
|
+
const effort = clampThinkingLevelForModel(
|
|
510
|
+
resolvedThinking,
|
|
488
511
|
reasoningEffortFromIntent(request.reasoning),
|
|
489
|
-
resolveSupportedReasoningEfforts(request.model, "chat"),
|
|
490
512
|
);
|
|
491
513
|
if (effort !== undefined) payload["reasoning_effort"] = effort;
|
|
514
|
+
// Qwen chat templates select thinking with `enable_thinking` (plus optional
|
|
515
|
+
// `thinking_budget`) instead of `reasoning_effort`.
|
|
516
|
+
if (policy.thinkingFormat === "qwen" && effort !== undefined) {
|
|
517
|
+
payload["enable_thinking"] = true;
|
|
518
|
+
}
|
|
492
519
|
}
|
|
493
520
|
// Stream controls the caller asked for are forwarded upstream so a
|
|
494
521
|
// pass-through provider can honor them (the local encoder honors them too).
|
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
* `provider_options` key that opts one request into the Daybreak
|
|
28
28
|
* `access_programs.cyber` member. See the UNCONFIRMED note at its use site.
|
|
29
29
|
*/
|
|
30
|
-
|
|
30
|
+
const CODEX_ACCESS_PROGRAMS_CYBER_OPTION = "codex_access_programs_cyber";
|
|
31
31
|
|
|
32
32
|
/**
|
|
33
33
|
* Removes `access_programs` from an already-built Codex Responses payload.
|