cartethyia 2.4.5 → 2.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +4 -1
- package/README.md +63 -13
- package/dist/dashboard/assets/AccountCooldown-ChpdzxRH.js.gz +0 -0
- package/dist/dashboard/assets/BannedPage-9igfctfZ.js +1 -0
- package/dist/dashboard/assets/BannedPage-9igfctfZ.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-BzGevuql.js → CliToolDetailPage-ZRr2K2sF.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-ZRr2K2sF.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-BaRM_7We.js → CliToolsPage-D3xqZbN-.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-D3xqZbN-.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-CVnQPBBz.js +1 -0
- package/dist/dashboard/assets/CombosPage-CVnQPBBz.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-u6W1UXSc.js +1 -0
- package/dist/dashboard/assets/ConsoleLogPage-u6W1UXSc.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-DqUGcoH0.js → CustomizationPage-CTTpCb25.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-CTTpCb25.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-C5XpWlvy.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-C5XpWlvy.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-DbhTGfhb.js → LoginPage-DHoB3Agn.js} +1 -1
- package/dist/dashboard/assets/LoginPage-DHoB3Agn.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-oQ-SDXp8.js +1 -0
- package/dist/dashboard/assets/ModelPicker-oQ-SDXp8.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-BrY4SgIt.js +1 -0
- package/dist/dashboard/assets/OverviewPage-BrY4SgIt.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-D9VSt7T_.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-D9VSt7T_.js.gz +0 -0
- package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js +1 -0
- package/dist/dashboard/assets/ProviderIcon-CmfzxpVM.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Df77V5I5.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-Df77V5I5.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-CDfxP7AC.js +7 -0
- package/dist/dashboard/assets/ProxyPage-CDfxP7AC.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-CY4o2t4p.js +1 -0
- package/dist/dashboard/assets/QuotaPage-CY4o2t4p.js.gz +0 -0
- package/dist/dashboard/assets/{SettingsPage-YxRml8AT.js → SettingsPage-CvjZxHE4.js} +1 -1
- package/dist/dashboard/assets/SettingsPage-CvjZxHE4.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-D3nza7LH.js +1 -0
- package/dist/dashboard/assets/SetupPage-D3nza7LH.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-Bol1ASmI.js → SortableList-Dtt12WT1.js} +1 -1
- package/dist/dashboard/assets/SortableList-Dtt12WT1.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-CbK3hXvU.js +31 -0
- package/dist/dashboard/assets/StudioPage-CbK3hXvU.js.gz +0 -0
- package/dist/dashboard/assets/ToolIcon-K1ckcDKg.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-BQlWbWg2.js +56 -0
- package/dist/dashboard/assets/UsagePage-BQlWbWg2.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-BmDbsior.js +1 -0
- package/dist/dashboard/assets/api-keys-BmDbsior.js.gz +0 -0
- package/dist/dashboard/assets/app-BbpSarVV.css +2 -0
- package/dist/dashboard/assets/app-BbpSarVV.css.gz +0 -0
- package/dist/dashboard/assets/{app-BDJWMThu.js → app-C-Y4oZT0.js} +3 -3
- package/dist/dashboard/assets/app-C-Y4oZT0.js.gz +0 -0
- package/dist/dashboard/assets/arrow-left-CpBxkoxI.js.gz +0 -0
- package/dist/dashboard/assets/arrow-right-Dl5yKnp8.js.gz +0 -0
- package/dist/dashboard/assets/assert-BHfaei-X.js +1 -0
- package/dist/dashboard/assets/assert-BHfaei-X.js.gz +0 -0
- package/dist/dashboard/assets/backup-file-gdKIlg8U.js.gz +0 -0
- package/dist/dashboard/assets/{badge-BwmwEOgA.js → badge-DpXT4Ixt.js} +1 -1
- package/dist/dashboard/assets/badge-DpXT4Ixt.js.gz +0 -0
- package/dist/dashboard/assets/{banner-BKBfKTqn.js → banner-CSAAWLJv.js} +1 -1
- package/dist/dashboard/assets/banner-CSAAWLJv.js.gz +0 -0
- package/dist/dashboard/assets/brain-Cwed_72z.js.gz +0 -0
- package/dist/dashboard/assets/{card-BTdbRFFg.js → card-DEhRXXw4.js} +1 -1
- package/dist/dashboard/assets/card-DEhRXXw4.js.gz +0 -0
- package/dist/dashboard/assets/check-D69FzdvC.js.gz +0 -0
- package/dist/dashboard/assets/chevron-right-BXIy5l3h.js.gz +0 -0
- package/dist/dashboard/assets/circle-alert-CntYHV5v.js.gz +0 -0
- package/dist/dashboard/assets/circle-check-BU3v_mFW.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-B0wBq-RL.js +1 -0
- package/dist/dashboard/assets/cli-tools-B0wBq-RL.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-DOo6EU8O.js +1 -0
- package/dist/dashboard/assets/clipboard-button-DOo6EU8O.js.gz +0 -0
- package/dist/dashboard/assets/cog-CdWhsajs.js.gz +0 -0
- package/dist/dashboard/assets/copy-ngmQ9zcZ.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-iocKA3jr.js → dialog-BvQeBMfP.js} +1 -1
- package/dist/dashboard/assets/dialog-BvQeBMfP.js.gz +0 -0
- package/dist/dashboard/assets/dialog-actions-B1axpEg7.js.gz +0 -0
- package/dist/dashboard/assets/download-A0SW9OCW.js.gz +0 -0
- package/dist/dashboard/assets/download-dRFo5_Wu.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-CDKOTZdY.js → drawer-CMwPXwQB.js} +1 -1
- package/dist/dashboard/assets/drawer-CMwPXwQB.js.gz +0 -0
- package/dist/dashboard/assets/entry-D4O2229X.js +1 -0
- package/dist/dashboard/assets/entry-D4O2229X.js.gz +0 -0
- package/dist/dashboard/assets/entry-DKvr5Q9K.js +1 -0
- package/dist/dashboard/assets/entry-DKvr5Q9K.js.gz +0 -0
- package/dist/dashboard/assets/entry-FQCejoDY.js +4 -0
- package/dist/dashboard/assets/entry-FQCejoDY.js.gz +0 -0
- package/dist/dashboard/assets/eye-C_hawfH4.js.gz +0 -0
- package/dist/dashboard/assets/eye-off-Bk5g2luF.js.gz +0 -0
- package/dist/dashboard/assets/fingerprint-pattern-BWuHtbW4.js.gz +0 -0
- package/dist/dashboard/assets/gauge-BbIMy7MB.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-zliLvBwr.js +1 -0
- package/dist/dashboard/assets/github-badge-zliLvBwr.js.gz +0 -0
- package/dist/dashboard/assets/image-BPaouViG.js.gz +0 -0
- package/dist/dashboard/assets/{index-C4hXfAMs.js → index-CXm3FIyt.js} +2 -2
- package/dist/dashboard/assets/index-CXm3FIyt.js.gz +0 -0
- package/dist/dashboard/assets/{inline-DCejSLlA.js → inline-D1IlZZ8H.js} +1 -1
- package/dist/dashboard/assets/inline-D1IlZZ8H.js.gz +0 -0
- package/dist/dashboard/assets/{input-Bn4_kNav.js → input-BpVZdrbc.js} +1 -1
- package/dist/dashboard/assets/input-BpVZdrbc.js.gz +0 -0
- package/dist/dashboard/assets/jsx-runtime-CXUMngI_.js.gz +0 -0
- package/dist/dashboard/assets/key-round-UkavsGxp.js.gz +0 -0
- package/dist/dashboard/assets/layers-2-glBbjl.js.gz +0 -0
- package/dist/dashboard/assets/{layout-Bv-NxqZ5.js → layout-BioLW7gN.js} +1 -1
- package/dist/dashboard/assets/layout-BioLW7gN.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-BLA0sldD.js → list-row-CwVcGAIc.js} +1 -1
- package/dist/dashboard/assets/list-row-CwVcGAIc.js.gz +0 -0
- package/dist/dashboard/assets/{live-YlifPYox.js → live-yfEJFF9T.js} +1 -1
- package/dist/dashboard/assets/live-yfEJFF9T.js.gz +0 -0
- package/dist/dashboard/assets/log-in-BmRjy60c.js.gz +0 -0
- package/dist/dashboard/assets/message-circle-CCxGwRvv.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-CT-TxSNX.js +1 -0
- package/dist/dashboard/assets/model-bans-CT-TxSNX.js.gz +0 -0
- package/dist/dashboard/assets/mutation-BkoLM5Ba.js +1 -0
- package/dist/dashboard/assets/mutation-BkoLM5Ba.js.gz +0 -0
- package/dist/dashboard/assets/numbers-CFL4_Dqc.js.gz +0 -0
- package/dist/dashboard/assets/pencil-768ysRAr.js.gz +0 -0
- package/dist/dashboard/assets/plus-DIdX_g-x.js.gz +0 -0
- package/dist/dashboard/assets/power-off-Yjw9GMJh.js +1 -0
- package/dist/dashboard/assets/power-off-Yjw9GMJh.js.gz +0 -0
- package/dist/dashboard/assets/privacy-mode-GM8bej85.js +1 -0
- package/dist/dashboard/assets/privacy-mode-GM8bej85.js.gz +0 -0
- package/dist/dashboard/assets/providers/agentrouter.svg.gz +0 -0
- package/dist/dashboard/assets/providers/aihubmix.svg.gz +0 -0
- package/dist/dashboard/assets/providers/alibaba-coding-plan.svg.gz +0 -0
- package/dist/dashboard/assets/providers/alibaba.svg.gz +0 -0
- package/dist/dashboard/assets/providers/antigravity.svg.gz +0 -0
- package/dist/dashboard/assets/providers/bai.svg.gz +0 -0
- package/dist/dashboard/assets/providers/blackbox.svg.gz +0 -0
- package/dist/dashboard/assets/providers/claude-code.svg.gz +0 -0
- package/dist/dashboard/assets/providers/cursor.webp +0 -0
- package/dist/dashboard/assets/providers/exa.svg.gz +0 -0
- package/dist/dashboard/assets/providers/gmi-cloud.svg.gz +0 -0
- package/dist/dashboard/assets/providers/inferhub.svg.gz +0 -0
- package/dist/dashboard/assets/providers/muse.svg.gz +0 -0
- package/dist/dashboard/assets/providers/nous-research.svg.gz +0 -0
- package/dist/dashboard/assets/providers/openai-light.svg.gz +0 -0
- package/dist/dashboard/assets/providers/parallel.svg.gz +0 -0
- package/dist/dashboard/assets/providers/tokenharbor.svg.gz +0 -0
- package/dist/dashboard/assets/providers/trae.webp +0 -0
- package/dist/dashboard/assets/providers/zai-coding-plan.svg.gz +0 -0
- package/dist/dashboard/assets/{query-keys-ROf-g1Wi.js → query-keys-D7wX2vM5.js} +1 -1
- package/dist/dashboard/assets/query-keys-D7wX2vM5.js.gz +0 -0
- package/dist/dashboard/assets/quota-DZGyp0N5.js.gz +0 -0
- package/dist/dashboard/assets/refresh-cw-BqJFk4sU.js.gz +0 -0
- package/dist/dashboard/assets/rotate-ccw-CufcqITi.js.gz +0 -0
- package/dist/dashboard/assets/route-CNSNj9Zm.js.gz +0 -0
- package/dist/dashboard/assets/routing-Cs6jl49L.js +1 -0
- package/dist/dashboard/assets/routing-Cs6jl49L.js.gz +0 -0
- package/dist/dashboard/assets/scaling-nWE4Cx8f.js.gz +0 -0
- package/dist/dashboard/assets/search-JOKus9rb.js.gz +0 -0
- package/dist/dashboard/assets/select-C0Rer3gF.js +41 -0
- package/dist/dashboard/assets/select-C0Rer3gF.js.gz +0 -0
- package/dist/dashboard/assets/settings-CfcTcOyU.js +1 -0
- package/dist/dashboard/assets/settings-CfcTcOyU.js.gz +0 -0
- package/dist/dashboard/assets/shield-check-DVS0Foqh.js.gz +0 -0
- package/dist/dashboard/assets/sparkles-BRaRUxAU.js.gz +0 -0
- package/dist/dashboard/assets/{stack-C1kTcOmP.js → stack-C9_uUjaA.js} +1 -1
- package/dist/dashboard/assets/stack-C9_uUjaA.js.gz +0 -0
- package/dist/dashboard/assets/{state-DHKdg-pm.js → state-DA0B95UQ.js} +1 -1
- package/dist/dashboard/assets/state-DA0B95UQ.js.gz +0 -0
- package/dist/dashboard/assets/stream-retry-5QnVuSSo.js.gz +0 -0
- package/dist/dashboard/assets/{switch-DIDeAiz9.js → switch-Cittxy-x.js} +1 -1
- package/dist/dashboard/assets/switch-Cittxy-x.js.gz +0 -0
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js +1 -0
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js.gz +0 -0
- package/dist/dashboard/assets/toast-CNt_jzO4.js +2 -0
- package/dist/dashboard/assets/toast-CNt_jzO4.js.gz +0 -0
- package/dist/dashboard/assets/tokens-DDxMbSRL.js.gz +0 -0
- package/dist/dashboard/assets/trash-Cppn5c3R.js.gz +0 -0
- package/dist/dashboard/assets/use-clipboard-B0Sy03fE.js.gz +0 -0
- package/dist/dashboard/assets/use-presence-BSZEBx7U.js.gz +0 -0
- package/dist/dashboard/assets/use-reduced-motion-C4B0R6Sz.js.gz +0 -0
- package/dist/dashboard/assets/use-timeout-BwcBBRrT.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-DVmwOKU-.js → useMutation-BQKMcJ1H.js} +1 -1
- package/dist/dashboard/assets/useMutation-BQKMcJ1H.js.gz +0 -0
- package/dist/dashboard/assets/wrench-B6E1oEuY.js.gz +0 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +122 -0
- package/migrations/full-postgres/0013_add_providers_tenant_id_index.sql +22 -0
- package/migrations/full-postgres/0014_add_provider_accounts_tenant_id_index.sql +21 -0
- package/migrations/full-postgres/0015_add_payload_stages.sql +18 -0
- package/migrations/full-postgres/0016_add_share_link_slug.sql +20 -0
- package/migrations/full-postgres/0017_add_models_pro_only.sql +18 -0
- package/migrations/full-postgres/0018_add_accounts_quota_plan.sql +18 -0
- package/migrations/full-postgres/0019_add_models_free_tier.sql +15 -0
- package/migrations/lite-sqlite3/0000_baseline.sql +4 -2
- package/migrations/lite-sqlite3/0013_add_providers_tenant_id_index.sql +4 -0
- package/migrations/lite-sqlite3/0014_add_provider_accounts_tenant_id_index.sql +4 -0
- package/migrations/lite-sqlite3/0015_add_payload_stages.sql +18 -0
- package/migrations/lite-sqlite3/0016_add_share_link_slug.sql +20 -0
- package/migrations/lite-sqlite3/0017_add_models_pro_only.sql +18 -0
- package/migrations/lite-sqlite3/0018_add_accounts_quota_plan.sql +18 -0
- package/migrations/lite-sqlite3/0019_add_models_free_tier.sql +15 -0
- package/package.json +26 -30
- package/scripts/cli/{carte-launcher.cjs → bin/carte.cjs} +8 -8
- package/scripts/cli/{cli-launcher.cjs → bin/cartethyia.cjs} +167 -134
- package/scripts/cli/command/admin.ts +65 -0
- package/scripts/cli/command/console-menu.ts +246 -0
- package/scripts/cli/{doctor.ts → command/doctor.ts} +257 -258
- package/scripts/cli/{setup.ts → command/setup.ts} +8 -12
- package/scripts/cli/command/start.ts +77 -0
- package/scripts/cli/command/tray.ts +165 -0
- package/scripts/cli/command/update.ts +23 -0
- package/scripts/cli/{runtime-state.ts → gateway/drain-token.ts} +78 -78
- package/scripts/cli/gateway/instance-lock.ts +105 -0
- package/scripts/cli/gateway/spawn.ts +173 -0
- package/scripts/cli/gateway/stop.ts +51 -0
- package/scripts/cli/main.ts +94 -0
- package/scripts/cli/support/bun.ts +27 -0
- package/scripts/cli/support/env.ts +99 -0
- package/scripts/cli/support/platform.ts +64 -0
- package/scripts/cli/support/services.ts +88 -0
- package/scripts/cli/support/startup-signal.ts +23 -0
- package/scripts/cli/{version.ts → support/version.ts} +1 -1
- package/scripts/cli/tray/hidden-window.vbs +28 -0
- package/scripts/cli/{tray.ts → tray/index.ts} +3 -3
- package/scripts/cli/{tray.ps1 → tray/windows.ps1} +107 -98
- package/scripts/cli/ui/background.ts +110 -0
- package/src/boot/app.ts +23 -7
- package/src/boot/dependencies.ts +55 -13
- package/src/boot/elysia-typebox-bridge.ts +37 -0
- package/src/boot/lifecycle.ts +2 -0
- package/src/config/cooldowns.ts +138 -138
- package/src/config/providers.ts +31 -5
- package/src/config/runtime.ts +19 -3
- package/src/config/spec.ts +20 -0
- package/src/console/api-keys/contracts.ts +414 -391
- package/src/console/api-keys/routes.ts +880 -870
- package/src/console/auth/account-reset-store.ts +14 -0
- package/src/console/auth/account-reset.ts +3 -2
- package/src/console/auth/setup-service.ts +6 -3
- package/src/console/backup/routes.ts +8 -0
- package/src/console/cli-tools/contracts.ts +6 -6
- package/src/console/console-router.ts +5 -3
- package/src/console/dashboard-assets.ts +81 -11
- package/src/console/domain-registration.ts +9 -2
- package/src/console/observability/contracts.ts +475 -423
- package/src/console/observability/routes.ts +31 -6
- package/src/console/observability/store.ts +1015 -912
- package/src/console/providers/catalog/contracts.ts +31 -0
- package/src/console/providers/catalog/provider-operations.ts +8 -0
- package/src/console/providers/catalog/public-model-store.ts +91 -60
- package/src/console/providers/catalog/store.ts +1532 -1521
- package/src/console/providers/oauth/callback-listener.ts +18 -3
- package/src/console/providers/oauth/routes.ts +38 -15
- package/src/console/quota/account-quota-tenant.ts +9 -6
- package/src/console/quota/refresh.ts +19 -0
- package/src/console/response-compression.ts +69 -2
- package/src/console/routing/pools/probe-verdict.ts +72 -0
- package/src/console/share/share-router.ts +7 -4
- package/src/console/share/share-stats.ts +12 -5
- package/src/console/shared/read-through-cache.ts +133 -7
- package/src/console/updates/repository-updates.ts +39 -34
- package/src/console/updates/routes.ts +162 -4
- package/src/main.ts +3 -0
- package/src/network/http2-bidi.ts +85 -0
- package/src/network/outbound-fetch.ts +87 -24
- package/src/network/pool/agent.ts +478 -460
- package/src/network/pool/resolver.ts +1104 -544
- package/src/network/pool-health-machine.ts +12 -5
- package/src/observability/event-log.ts +29 -8
- package/src/observability/metrics.ts +40 -13
- package/src/observability/payload-capture.ts +344 -324
- package/src/observability/runtime-metrics.ts +7 -0
- package/src/persistence/db-pg.ts +9 -3
- package/src/persistence/db-sqlite.ts +497 -495
- package/src/persistence/health-event-flush.ts +137 -0
- package/src/persistence/migrate.ts +181 -129
- package/src/persistence/schema.ts +1360 -1257
- package/src/persistence/settings-revision.ts +25 -0
- package/src/persistence/shared-cache.ts +217 -0
- package/src/persistence/stores/share-store.ts +556 -528
- package/src/persistence/usage-flush.ts +61 -1
- package/src/protocol/canonical-model.ts +23 -1
- package/src/protocol/response/chat.ts +143 -10
- package/src/protocol/response/codex.ts +9 -75
- package/src/protocol/response/omp-tool-call-markup.ts +221 -0
- package/src/protocol/tool-identity.ts +43 -9
- package/src/providers/authentication/jwt-validator.ts +130 -187
- package/src/providers/authentication/oauth-flow-store.ts +16 -9
- package/src/providers/default-registry.ts +177 -1
- package/src/providers/discovery/catalog/catalog-format.ts +20 -0
- package/src/providers/discovery/models-dev-catalog.ts +39 -22
- package/src/providers/discovery/openai-model-discovery.ts +39 -3
- package/src/providers/discovery/openrouter-free-roster.ts +98 -0
- package/src/providers/discovery/probe-wire.ts +29 -5
- package/src/providers/discovery/probing-service.ts +1022 -1001
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +42 -2
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +913 -914
- package/src/providers/integrations/buddy/buddy-cli-headers.ts +88 -0
- package/src/providers/integrations/buddy/buddy-conversation-headers.ts +22 -5
- package/src/providers/integrations/buddy/buddy-discovery-shared.ts +33 -1
- package/src/providers/integrations/buddy/buddy-identity.ts +46 -0
- package/src/providers/integrations/buddy/buddy-oauth-shared.ts +37 -1
- package/src/providers/integrations/buddy/buddy-usage-store.ts +40 -5
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +4 -0
- package/src/providers/integrations/buddy/codebuddy/provider.ts +180 -175
- package/src/providers/integrations/buddy/codebuddy/shared.ts +115 -73
- package/src/providers/integrations/buddy/workbuddy/cn-provider.ts +5 -2
- package/src/providers/integrations/buddy/workbuddy/provider.ts +206 -204
- package/src/providers/integrations/buddy/workbuddy/quota.ts +172 -159
- package/src/providers/integrations/buddy/workbuddy/shared.ts +200 -171
- package/src/providers/integrations/claude/claude.ts +606 -582
- package/src/providers/integrations/cline/cline-quota.ts +18 -16
- package/src/providers/integrations/cline/cline.ts +539 -468
- package/src/providers/integrations/codex/codex.ts +5 -8
- package/src/providers/integrations/commandcode/commandcode.ts +675 -541
- package/src/providers/integrations/commandcode/discovery.ts +116 -0
- package/src/providers/integrations/commandcode/quota.ts +160 -0
- package/src/providers/integrations/cursor/cursor-auth.ts +418 -0
- package/src/providers/integrations/cursor/cursor-catalog.ts +368 -0
- package/src/providers/integrations/cursor/cursor-http2.ts +300 -0
- package/src/providers/integrations/cursor/cursor-identity.ts +92 -0
- package/src/providers/integrations/cursor/cursor-request.ts +471 -0
- package/src/providers/integrations/cursor/cursor-session-manager.ts +281 -0
- package/src/providers/integrations/cursor/cursor-shared.ts +108 -0
- package/src/providers/integrations/cursor/cursor.ts +960 -0
- package/src/providers/integrations/cursor/protocol/framing.ts +129 -0
- package/src/providers/integrations/cursor/protocol/messages.ts +2355 -0
- package/src/providers/integrations/cursor/protocol/struct.ts +305 -0
- package/src/providers/integrations/factory/factory-oauth.ts +7 -11
- package/src/providers/integrations/github/github.ts +4 -4
- package/src/providers/integrations/hermes.ts +79 -8
- package/src/providers/integrations/kilo/kilo-discovery.ts +10 -1
- package/src/providers/integrations/kilo/kilo.ts +153 -146
- package/src/providers/integrations/opencode/opencode-go-quota.ts +130 -0
- package/src/providers/integrations/opencode/provider.ts +532 -499
- package/src/providers/integrations/openrouter/provider.ts +139 -281
- package/src/providers/integrations/qoder/qoder-catalog.ts +450 -0
- package/src/providers/integrations/qoder/qoder-oauth.ts +310 -263
- package/src/providers/integrations/qoder/qoder-realm.ts +106 -0
- package/src/providers/integrations/qoder/qoder-virtual.ts +77 -0
- package/src/providers/integrations/qoder/qoder.ts +865 -730
- package/src/providers/integrations/shared/install-id.ts +29 -2
- package/src/providers/integrations/trae/trae-catalog.ts +190 -0
- package/src/providers/integrations/trae/trae-headers.ts +149 -0
- package/src/providers/integrations/trae/trae-oauth.ts +773 -0
- package/src/providers/integrations/trae/trae-protocol.ts +400 -0
- package/src/providers/integrations/trae/trae-realm.ts +220 -0
- package/src/providers/integrations/trae/trae.ts +458 -0
- package/src/providers/operations/account-health-service.ts +107 -10
- package/src/providers/operations/client-versions.ts +143 -6
- package/src/providers/operations/model-catalog-cache.ts +18 -3
- package/src/providers/operations/provider-catalog-seeder.ts +95 -86
- package/src/providers/operations/provider-catalog-service.ts +76 -0
- package/src/providers/operations/provider-credential-service.ts +46 -7
- package/src/providers/provider-contracts.ts +76 -0
- package/src/providers/provider-metadata.ts +78 -6
- package/src/providers/provider-model-definition.ts +373 -349
- package/src/security/api-key-auth.ts +126 -8
- package/src/transport/contracts.ts +3 -0
- package/src/transport/dispatch/attempt-finalize.ts +39 -2
- package/src/transport/dispatch/attempt-loop.ts +530 -513
- package/src/transport/dispatch/empty-stream.ts +17 -26
- package/src/transport/dispatch/generation.ts +88 -21
- package/src/transport/dispatch/leases.ts +99 -2
- package/src/transport/dispatch/proxy-request.ts +60 -3
- package/src/transport/dispatch/streaming/finalize.ts +16 -1
- package/src/transport/dispatch/streaming/stream.ts +22 -2
- package/src/transport/dispatch/upstream.ts +19 -1
- package/src/transport/failure-policy.ts +20 -0
- package/src/transport/guards/auth-guard.ts +26 -1
- package/src/transport/guards/body-policy.ts +5 -4
- package/src/transport/request/preparer.ts +103 -0
- package/src/transport/request/state.ts +14 -0
- package/src/transport/routing/plan-gate.ts +45 -0
- package/src/transport/routing/route-catalog.ts +799 -738
- package/src/transport/routing/route-model.ts +52 -1
- package/src/transport/routing/router.ts +51 -0
- package/src/transport/surface/chat/encode.ts +18 -31
- package/src/transport/surface/messages/stream.ts +3 -2
- package/src/transport/translation/tool-repair.ts +37 -16
- package/src/workers/account-identity-sweep.ts +14 -12
- package/src/workers/daily-checkin.ts +62 -0
- package/src/workers/quota-refresh-sweep.ts +27 -2
- package/dist/dashboard/assets/BannedPage-DUrXpp-X.js +0 -1
- package/dist/dashboard/assets/CombosPage-B7ETkfVH.js +0 -1
- package/dist/dashboard/assets/ConsoleLogPage-AisQzCI1.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-BNflDm_f.js +0 -1
- package/dist/dashboard/assets/ModelPicker-CAiPR5Vd.js +0 -1
- package/dist/dashboard/assets/OverviewPage-C3NIzsDx.js +0 -1
- package/dist/dashboard/assets/ProviderDetailPage-BK8i5B5X.js +0 -3
- package/dist/dashboard/assets/ProviderIcon-paOCq8I0.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-CvCVgm1e.js +0 -1
- package/dist/dashboard/assets/ProxyPage-DjabkuzP.js +0 -7
- package/dist/dashboard/assets/QuotaPage-Dxe0B0iu.js +0 -1
- package/dist/dashboard/assets/SetupPage-BaD4P_jW.js +0 -1
- package/dist/dashboard/assets/StudioPage-CLP4le3U.js +0 -31
- package/dist/dashboard/assets/UsagePage-Djes-Epy.js +0 -56
- package/dist/dashboard/assets/api-keys-CjIGQhe7.js +0 -1
- package/dist/dashboard/assets/app-Cjgo4-Lf.css +0 -2
- package/dist/dashboard/assets/assert-Bwh6DJTK.js +0 -1
- package/dist/dashboard/assets/cli-tools-DccaOfhX.js +0 -1
- package/dist/dashboard/assets/clipboard-button-DQmMikNQ.js +0 -1
- package/dist/dashboard/assets/entry-Cpi0rph1.js +0 -4
- package/dist/dashboard/assets/entry-Dm3PpDCO.js +0 -1
- package/dist/dashboard/assets/entry-keNDZ_Wz.js +0 -1
- package/dist/dashboard/assets/github-badge-BuAJr8oU.js +0 -1
- package/dist/dashboard/assets/model-bans-CVvHZ-qz.js +0 -1
- package/dist/dashboard/assets/mutation-BIizFZav.js +0 -1
- package/dist/dashboard/assets/privacy-mode-CQjbZ3xk.js +0 -1
- package/dist/dashboard/assets/routing-jntw9-Ui.js +0 -1
- package/dist/dashboard/assets/select-CGUuTQmj.js +0 -41
- package/dist/dashboard/assets/settings-BAS6QbmJ.js +0 -1
- package/dist/dashboard/assets/sliders-horizontal-ClG7dBeJ.js +0 -1
- package/dist/dashboard/assets/terminal-C9mZ4Ugm.js +0 -1
- package/dist/dashboard/assets/toast-DKAdP2mo.js +0 -2
- package/scripts/cli/cli.ts +0 -771
- package/scripts/operations/probe-egress.ts +0 -335
- package/scripts/operations/restart.ts +0 -120
- package/scripts/shared/env.ts +0 -269
- /package/{tray-assets → scripts/cli/tray/assets}/cartethyia.ico +0 -0
- /package/{tray-assets → scripts/cli/tray/assets}/cartethyia.png +0 -0
- /package/scripts/cli/{menu.ts → ui/prompt.ts} +0 -0
- /package/scripts/cli/{wordmark.ts → ui/wordmark.ts} +0 -0
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Recovers the tool-call envelope some models occasionally emit as assistant
|
|
3
|
+
* text instead of OpenAI `tool_calls`.
|
|
4
|
+
*
|
|
5
|
+
* The wire shape is the captured `<tool_calls:8hex>` / `<tool_call:8hex>` /
|
|
6
|
+
* `<arg_key:8hex>` / `<arg_value:8hex>` form. Only complete envelopes are
|
|
7
|
+
* interpreted. Calls are returned only when their names were declared on the
|
|
8
|
+
* request; an undeclared name is never promoted into executable tool input.
|
|
9
|
+
*/
|
|
10
|
+
export interface OmpTextToolCall {
|
|
11
|
+
readonly id: string;
|
|
12
|
+
readonly name: string;
|
|
13
|
+
readonly arguments: string;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
/** Text remaining after complete tool envelopes are removed. */
|
|
17
|
+
export interface OmpTextToolCallResult {
|
|
18
|
+
readonly text: string;
|
|
19
|
+
readonly calls: readonly OmpTextToolCall[];
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
const OPEN_PREFIX = "<tool_calls:";
|
|
23
|
+
const OPEN_PATTERN = /^<tool_calls:([0-9a-f]{8})>/;
|
|
24
|
+
const TOOL_NAME_PATTERN = /^[A-Za-z0-9_][A-Za-z0-9_.:-]{0,63}$/;
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Incrementally removes complete captured tool envelopes from text.
|
|
28
|
+
*
|
|
29
|
+
* The parser holds a possible envelope across SSE deltas, so a split opening
|
|
30
|
+
* tag, argument tag, or closing tag is never emitted as visible prose. At
|
|
31
|
+
* end-of-stream an unterminated envelope is dropped, not executed or leaked.
|
|
32
|
+
*/
|
|
33
|
+
export class OmpToolCallMarkupParser {
|
|
34
|
+
readonly #allowedNames: ReadonlySet<string>;
|
|
35
|
+
#pending = "";
|
|
36
|
+
#callSequence = 0;
|
|
37
|
+
|
|
38
|
+
constructor(allowedNames: ReadonlySet<string>) {
|
|
39
|
+
this.#allowedNames = allowedNames;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/** Feeds one content or reasoning delta and returns only settled text. */
|
|
43
|
+
push(chunk: string): OmpTextToolCallResult {
|
|
44
|
+
this.#pending += chunk;
|
|
45
|
+
let cursor = 0;
|
|
46
|
+
let text = "";
|
|
47
|
+
const calls: OmpTextToolCall[] = [];
|
|
48
|
+
|
|
49
|
+
for (;;) {
|
|
50
|
+
const openIndex = this.#pending.indexOf(OPEN_PREFIX, cursor);
|
|
51
|
+
if (openIndex < 0) {
|
|
52
|
+
const safeEnd = this.#settledEnd(cursor);
|
|
53
|
+
text += this.#pending.slice(cursor, safeEnd);
|
|
54
|
+
cursor = safeEnd;
|
|
55
|
+
break;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
text += this.#pending.slice(cursor, openIndex);
|
|
59
|
+
const remainder = this.#pending.slice(openIndex);
|
|
60
|
+
const opening = OPEN_PATTERN.exec(remainder);
|
|
61
|
+
if (opening === null || opening[1] === undefined) {
|
|
62
|
+
if (this.#couldBeOpening(remainder)) {
|
|
63
|
+
cursor = openIndex;
|
|
64
|
+
break;
|
|
65
|
+
}
|
|
66
|
+
text += "<";
|
|
67
|
+
cursor = openIndex + 1;
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
const marker = opening[1];
|
|
72
|
+
const openTag = opening[0];
|
|
73
|
+
const closeTag = `</tool_calls:${marker}>`;
|
|
74
|
+
const closeIndex = this.#pending.indexOf(closeTag, openIndex + openTag.length);
|
|
75
|
+
if (closeIndex < 0) {
|
|
76
|
+
cursor = openIndex;
|
|
77
|
+
break;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const envelopeEnd = closeIndex + closeTag.length;
|
|
81
|
+
const block = this.#pending.slice(openIndex, envelopeEnd);
|
|
82
|
+
const parsed = parseEnvelope(block, marker);
|
|
83
|
+
if (parsed === undefined) {
|
|
84
|
+
text += block;
|
|
85
|
+
} else if (parsed.some((call) => !this.#allowedNames.has(call.name))) {
|
|
86
|
+
// A syntactically valid call to an undeclared tool is model text, not
|
|
87
|
+
// authority to invoke a tool the client did not offer.
|
|
88
|
+
text += block;
|
|
89
|
+
} else {
|
|
90
|
+
for (const call of parsed) {
|
|
91
|
+
calls.push({
|
|
92
|
+
id: `call_omp_${marker}_${this.#callSequence++}`,
|
|
93
|
+
name: call.name,
|
|
94
|
+
arguments: call.arguments,
|
|
95
|
+
});
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
cursor = envelopeEnd;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
this.#pending = this.#pending.slice(cursor);
|
|
102
|
+
return { text, calls };
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
/**
|
|
106
|
+
* Settles trailing text. A complete internal envelope cannot remain here;
|
|
107
|
+
* an unfinished envelope is deliberately discarded rather than leaked.
|
|
108
|
+
*/
|
|
109
|
+
flush(): OmpTextToolCallResult {
|
|
110
|
+
const pending = this.#pending;
|
|
111
|
+
this.#pending = "";
|
|
112
|
+
if (this.#couldBeOpening(pending) || OPEN_PATTERN.test(pending)) {
|
|
113
|
+
return { text: "", calls: [] };
|
|
114
|
+
}
|
|
115
|
+
return { text: pending, calls: [] };
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
#settledEnd(start: number): number {
|
|
119
|
+
const remaining = this.#pending.slice(start);
|
|
120
|
+
const maxPrefixLength = Math.min(OPEN_PREFIX.length - 1, remaining.length);
|
|
121
|
+
for (let length = maxPrefixLength; length > 0; length -= 1) {
|
|
122
|
+
if (OPEN_PREFIX.startsWith(remaining.slice(-length))) {
|
|
123
|
+
return this.#pending.length - length;
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
return this.#pending.length;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
#couldBeOpening(value: string): boolean {
|
|
130
|
+
if (value.length < OPEN_PREFIX.length) return OPEN_PREFIX.startsWith(value);
|
|
131
|
+
if (!value.startsWith(OPEN_PREFIX)) return false;
|
|
132
|
+
const suffix = value.slice(OPEN_PREFIX.length);
|
|
133
|
+
return /^[0-9a-f]{0,8}$/.test(suffix) || /^[0-9a-f]{8}$/.test(suffix) && !value.endsWith(">");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
/**
|
|
138
|
+
* Parses complete envelopes from one settled response field.
|
|
139
|
+
*
|
|
140
|
+
* The same parser backs JSON responses and streaming responses so recovery
|
|
141
|
+
* semantics do not differ merely because the upstream selected `stream`.
|
|
142
|
+
*/
|
|
143
|
+
export function parseOmpToolCallMarkup(
|
|
144
|
+
text: string,
|
|
145
|
+
allowedNames: ReadonlySet<string>,
|
|
146
|
+
): OmpTextToolCallResult {
|
|
147
|
+
const parser = new OmpToolCallMarkupParser(allowedNames);
|
|
148
|
+
const first = parser.push(text);
|
|
149
|
+
const last = parser.flush();
|
|
150
|
+
return { text: first.text + last.text, calls: first.calls };
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Parses a complete captured tool envelope, returning undefined for malformed
|
|
155
|
+
* structure. Argument values are JSON-decoded when they contain valid JSON;
|
|
156
|
+
* otherwise their exact text is preserved as a string.
|
|
157
|
+
*/
|
|
158
|
+
function parseEnvelope(block: string, marker: string): readonly Omit<OmpTextToolCall, "id">[] | undefined {
|
|
159
|
+
const openTag = `<tool_calls:${marker}>`;
|
|
160
|
+
const closeTag = `</tool_calls:${marker}>`;
|
|
161
|
+
if (!block.startsWith(openTag) || !block.endsWith(closeTag)) return undefined;
|
|
162
|
+
|
|
163
|
+
const body = block.slice(openTag.length, -closeTag.length);
|
|
164
|
+
const calls: Omit<OmpTextToolCall, "id">[] = [];
|
|
165
|
+
const callPattern = new RegExp(`<tool_call:${marker}>([\\s\\S]*?)</tool_call:${marker}>`, "g");
|
|
166
|
+
let cursor = 0;
|
|
167
|
+
|
|
168
|
+
for (const match of body.matchAll(callPattern)) {
|
|
169
|
+
const index = match.index;
|
|
170
|
+
const full = match[0];
|
|
171
|
+
const callBody = match[1];
|
|
172
|
+
if (index === undefined || full === undefined || callBody === undefined) return undefined;
|
|
173
|
+
if (body.slice(cursor, index).trim().length > 0) return undefined;
|
|
174
|
+
|
|
175
|
+
const keyTag = `<arg_key:${marker}>`;
|
|
176
|
+
const firstKey = callBody.indexOf(keyTag);
|
|
177
|
+
const name = (firstKey < 0 ? callBody : callBody.slice(0, firstKey)).trim();
|
|
178
|
+
if (!TOOL_NAME_PATTERN.test(name)) return undefined;
|
|
179
|
+
|
|
180
|
+
const argumentBody = firstKey < 0 ? "" : callBody.slice(firstKey);
|
|
181
|
+
const pairPattern = new RegExp(
|
|
182
|
+
`<arg_key:${marker}>([\\s\\S]*?)</arg_key:${marker}>\\s*<arg_value:${marker}>([\\s\\S]*?)</arg_value:${marker}>`,
|
|
183
|
+
"g",
|
|
184
|
+
);
|
|
185
|
+
const argumentsObject: Record<string, unknown> = {};
|
|
186
|
+
let argumentCursor = 0;
|
|
187
|
+
for (const pair of argumentBody.matchAll(pairPattern)) {
|
|
188
|
+
const pairIndex = pair.index;
|
|
189
|
+
const pairFull = pair[0];
|
|
190
|
+
const key = pair[1]?.trim();
|
|
191
|
+
const value = pair[2];
|
|
192
|
+
if (
|
|
193
|
+
pairIndex === undefined ||
|
|
194
|
+
pairFull === undefined ||
|
|
195
|
+
key === undefined ||
|
|
196
|
+
key.length === 0 ||
|
|
197
|
+
value === undefined ||
|
|
198
|
+
argumentBody.slice(argumentCursor, pairIndex).trim().length > 0
|
|
199
|
+
) {
|
|
200
|
+
return undefined;
|
|
201
|
+
}
|
|
202
|
+
argumentsObject[key] = parseArgumentValue(value);
|
|
203
|
+
argumentCursor = pairIndex + pairFull.length;
|
|
204
|
+
}
|
|
205
|
+
if (argumentBody.slice(argumentCursor).trim().length > 0) return undefined;
|
|
206
|
+
|
|
207
|
+
calls.push({ name, arguments: JSON.stringify(argumentsObject) });
|
|
208
|
+
cursor = index + full.length;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
if (calls.length === 0 || body.slice(cursor).trim().length > 0) return undefined;
|
|
212
|
+
return calls;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function parseArgumentValue(value: string): unknown {
|
|
216
|
+
try {
|
|
217
|
+
return JSON.parse(value) as unknown;
|
|
218
|
+
} catch {
|
|
219
|
+
return value;
|
|
220
|
+
}
|
|
221
|
+
}
|
|
@@ -7,12 +7,33 @@ export interface ToolCallState {
|
|
|
7
7
|
}
|
|
8
8
|
|
|
9
9
|
/**
|
|
10
|
-
* Per-state argument fragments
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
10
|
+
* Per-state argument fragments and their joined snapshot.
|
|
11
|
+
*
|
|
12
|
+
* The snapshot is cached on the CHUNK ARRAY, not on the state, because the
|
|
13
|
+
* array is deliberately handed forward from a superseded state to its
|
|
14
|
+
* replacement and mutated in place — so a reader holding the older
|
|
15
|
+
* `ToolCallState` still observes the newest total. Caching per state would
|
|
16
|
+
* freeze each state at the value it had when created and silently break that
|
|
17
|
+
* invariant (pinned by test/protocol/tool-identity.test.ts).
|
|
18
|
+
*
|
|
19
|
+
* The cache is dropped on push, so N deltas cost O(N) total: without it each
|
|
20
|
+
* read re-joined the whole array, and a reader that slices the string per
|
|
21
|
+
* delta — as the Messages stream does — re-joined and re-sliced once per
|
|
22
|
+
* fragment, which is O(n²) over a large tool argument.
|
|
14
23
|
*/
|
|
15
24
|
const argumentChunks = new WeakMap<ToolCallState, string[]>();
|
|
25
|
+
const argumentJoined = new WeakMap<string[], string>();
|
|
26
|
+
|
|
27
|
+
/** The accumulated arguments, joining only when a fragment has been added. */
|
|
28
|
+
function joinedArguments(state: ToolCallState): string {
|
|
29
|
+
const chunks = argumentChunks.get(state);
|
|
30
|
+
if (chunks === undefined) return "";
|
|
31
|
+
const cached = argumentJoined.get(chunks);
|
|
32
|
+
if (cached !== undefined) return cached;
|
|
33
|
+
const value = chunks.join("");
|
|
34
|
+
argumentJoined.set(chunks, value);
|
|
35
|
+
return value;
|
|
36
|
+
}
|
|
16
37
|
|
|
17
38
|
/**
|
|
18
39
|
* Single tool-call tracking home: id/index/arguments-accumulation keyed by
|
|
@@ -60,17 +81,17 @@ export function trackToolCall(
|
|
|
60
81
|
tracker.nextIndex = Math.max(tracker.nextIndex, index + 1);
|
|
61
82
|
const prior = tracker.states.get(tool.id);
|
|
62
83
|
const name = tool.name ?? prior?.name;
|
|
63
|
-
// Append the fragment in O(1) amortized
|
|
64
|
-
//
|
|
65
|
-
//
|
|
66
|
-
// along one call id (superseded states are never read after replacement).
|
|
84
|
+
// Append the fragment in O(1) amortized. The chunk array is shared forward
|
|
85
|
+
// along one call id, so the joined cache is keyed on the array and dropped
|
|
86
|
+
// here: the next read re-joins once and re-caches.
|
|
67
87
|
const chunks =
|
|
68
88
|
prior !== undefined ? (argumentChunks.get(prior) ?? [prior.arguments]) : [];
|
|
69
89
|
chunks.push(tool.args ?? "");
|
|
90
|
+
argumentJoined.delete(chunks);
|
|
70
91
|
const state: ToolCallState = {
|
|
71
92
|
id: tool.id || prior?.id || "",
|
|
72
93
|
get arguments() {
|
|
73
|
-
return
|
|
94
|
+
return joinedArguments(state);
|
|
74
95
|
},
|
|
75
96
|
index,
|
|
76
97
|
};
|
|
@@ -80,6 +101,19 @@ export function trackToolCall(
|
|
|
80
101
|
return { index, isFirst: prior === undefined, state };
|
|
81
102
|
}
|
|
82
103
|
|
|
104
|
+
/**
|
|
105
|
+
* The not-yet-emitted tail of a call's arguments, from `offset`.
|
|
106
|
+
*
|
|
107
|
+
* Reads the cached joined string rather than re-joining the chunk array, so a
|
|
108
|
+
* caller that asks once per delta — as the Messages stream does — stays
|
|
109
|
+
* linear in the total argument length instead of quadratic. The `slice` itself
|
|
110
|
+
* is unavoidable: the caller needs the tail, and its own length is the output.
|
|
111
|
+
*/
|
|
112
|
+
export function argumentsFrom(state: ToolCallState, offset: number): string {
|
|
113
|
+
const all = joinedArguments(state);
|
|
114
|
+
return offset <= 0 ? all : all.slice(offset);
|
|
115
|
+
}
|
|
116
|
+
|
|
83
117
|
// ===== Emission ledger =====
|
|
84
118
|
|
|
85
119
|
/**
|