cartethyia 2.5.2 → 2.5.4
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/dist/dashboard/assets/{BannedPage-MsQaeQTs.js → BannedPage-C2orBsI2.js} +1 -1
- package/dist/dashboard/assets/BannedPage-C2orBsI2.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js +1 -0
- package/dist/dashboard/assets/CliToolDetailPage-DUcZ6pMB.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-DfWHTJ7v.js → CliToolsPage-BV6pxVQo.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BV6pxVQo.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-BrCBQDAc.js → CombosPage-Bsan4679.js} +1 -1
- package/dist/dashboard/assets/CombosPage-Bsan4679.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-C6Uh33er.js → ConsoleLogPage-CW-wPmJ6.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-CW-wPmJ6.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-8aS9hyJu.js → CustomizationPage-0p8uX7vB.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-0p8uX7vB.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-BjqSMfko.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-C8hKyXBe.js → LoginPage-BvzCx8Kr.js} +1 -1
- package/dist/dashboard/assets/LoginPage-BvzCx8Kr.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-CWkTUtpX.js → ModelPicker-BY1aKEkP.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-BY1aKEkP.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js +1 -0
- package/dist/dashboard/assets/OverviewPage-DOQpy1y0.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-ecxyUMzt.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js +1 -0
- package/dist/dashboard/assets/ProvidersPage-Js9jUPSb.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js +7 -0
- package/dist/dashboard/assets/ProxyPage-J3TBi3Kx.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js +1 -0
- package/dist/dashboard/assets/QuotaPage-C1gZS6xr.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js +1 -0
- package/dist/dashboard/assets/SettingsPage-CS86ho5X.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-CXjUlfqr.js → SetupPage-DDbMQsoo.js} +1 -1
- package/dist/dashboard/assets/SetupPage-DDbMQsoo.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-C-_oD3F2.js → SortableList-CB3Z7VTf.js} +1 -1
- package/dist/dashboard/assets/SortableList-CB3Z7VTf.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-u9IxmYOI.js → StudioPage-D95UCPHI.js} +3 -3
- package/dist/dashboard/assets/StudioPage-D95UCPHI.js.gz +0 -0
- package/dist/dashboard/assets/{UsagePage-BEVLVrwP.js → UsagePage-Cnae9SWA.js} +13 -13
- package/dist/dashboard/assets/UsagePage-Cnae9SWA.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-uNywYlfv.js → api-keys-VY68Mhd1.js} +1 -1
- package/dist/dashboard/assets/api-keys-VY68Mhd1.js.gz +0 -0
- package/dist/dashboard/assets/app-COlK95oi.css +2 -0
- package/dist/dashboard/assets/app-COlK95oi.css.gz +0 -0
- package/dist/dashboard/assets/{assert-NHwYq95t.js → assert-Chi7pCnt.js} +1 -1
- package/dist/dashboard/assets/assert-Chi7pCnt.js.gz +0 -0
- package/dist/dashboard/assets/{badge-6uzDDvqs.js → badge-D4pQapKj.js} +1 -1
- package/dist/dashboard/assets/badge-D4pQapKj.js.gz +0 -0
- package/dist/dashboard/assets/{banner-4_WNg2WZ.js → banner-DH6cg-_B.js} +1 -1
- package/dist/dashboard/assets/banner-DH6cg-_B.js.gz +0 -0
- package/dist/dashboard/assets/{card--AtFedAq.js → card-BKqlUOe4.js} +1 -1
- package/dist/dashboard/assets/card-BKqlUOe4.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-B3e7dx3N.js → cli-tools-fTgljTGA.js} +1 -1
- package/dist/dashboard/assets/cli-tools-fTgljTGA.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-NreUx6c8.js → clipboard-button-D5Ys_sM0.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-D5Ys_sM0.js.gz +0 -0
- package/dist/dashboard/assets/database-Dz9N3zGd.js +1 -0
- package/dist/dashboard/assets/database-Dz9N3zGd.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-BtpsJU98.js → dialog-BYj-8WuK.js} +1 -1
- package/dist/dashboard/assets/dialog-BYj-8WuK.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-WwwtzihF.js → drawer-CmXIZ6H1.js} +1 -1
- package/dist/dashboard/assets/drawer-CmXIZ6H1.js.gz +0 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js +1 -0
- package/dist/dashboard/assets/entry-CBg5zeu8.js.gz +0 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js +1 -0
- package/dist/dashboard/assets/entry-CQBr6U9c.js.gz +0 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js +4 -0
- package/dist/dashboard/assets/entry-CgdSAzEV.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-D_eM3IgG.js → github-badge-BlptL8Uf.js} +1 -1
- package/dist/dashboard/assets/github-badge-BlptL8Uf.js.gz +0 -0
- package/dist/dashboard/assets/{index-DCBtROoK.js → index-js6TJvdr.js} +2 -2
- package/dist/dashboard/assets/index-js6TJvdr.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BcNGF8Gr.js → inline-DUWDSmDV.js} +1 -1
- package/dist/dashboard/assets/inline-DUWDSmDV.js.gz +0 -0
- package/dist/dashboard/assets/{input-BG41et9G.js → input-LVjgZq4f.js} +1 -1
- package/dist/dashboard/assets/input-LVjgZq4f.js.gz +0 -0
- package/dist/dashboard/assets/{layout-C8mer_Ak.js → layout-CPfxpsfy.js} +1 -1
- package/dist/dashboard/assets/layout-CPfxpsfy.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-Gh_W4OR_.js → list-row-DupvLfDx.js} +1 -1
- package/dist/dashboard/assets/list-row-DupvLfDx.js.gz +0 -0
- package/dist/dashboard/assets/{live-BJGYRBnR.js → live-C4pEJUqI.js} +1 -1
- package/dist/dashboard/assets/live-C4pEJUqI.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js +1 -0
- package/dist/dashboard/assets/model-bans-BRiuufkB.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-BkoLM5Ba.js → mutation-B4ROwk8L.js} +1 -1
- package/dist/dashboard/assets/mutation-B4ROwk8L.js.gz +0 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js +2 -0
- package/dist/dashboard/assets/numbers-YNcHvRY7.js.gz +0 -0
- package/dist/dashboard/assets/{query-keys-D7wX2vM5.js → query-keys-gmjzC3RS.js} +1 -1
- package/dist/dashboard/assets/{query-keys-D7wX2vM5.js.gz → query-keys-gmjzC3RS.js.gz} +0 -0
- package/dist/dashboard/assets/{routing-CcusqXA7.js → routing-C7tBT5o-.js} +1 -1
- package/dist/dashboard/assets/routing-C7tBT5o-.js.gz +0 -0
- package/dist/dashboard/assets/{select-DsX5QT8K.js → select-WUCXorXw.js} +2 -2
- package/dist/dashboard/assets/select-WUCXorXw.js.gz +0 -0
- package/dist/dashboard/assets/{settings-mpmXTgUa.js → settings-C_zKl1GS.js} +1 -1
- package/dist/dashboard/assets/settings-C_zKl1GS.js.gz +0 -0
- package/dist/dashboard/assets/{stack-DwLmjUFK.js → stack-_3O0F8Xn.js} +1 -1
- package/dist/dashboard/assets/stack-_3O0F8Xn.js.gz +0 -0
- package/dist/dashboard/assets/{state-DYdQmdAl.js → state-BgTxHcJS.js} +1 -1
- package/dist/dashboard/assets/state-BgTxHcJS.js.gz +0 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js +1 -0
- package/dist/dashboard/assets/switch-DEjTtOWf.js.gz +0 -0
- package/dist/dashboard/assets/terminal-0_IjPWTk.js +1 -0
- package/dist/dashboard/assets/terminal-0_IjPWTk.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-w4u4CVue.js → useMutation-BWSC0UAS.js} +1 -1
- package/dist/dashboard/assets/useMutation-BWSC0UAS.js.gz +0 -0
- package/dist/dashboard/assets/zap-C4EeVW4q.js +1 -0
- package/dist/dashboard/assets/zap-C4EeVW4q.js.gz +0 -0
- package/dist/dashboard/donation/qris-risun-marke.png +0 -0
- package/dist/dashboard/index.html +1 -1
- package/dist/dashboard/index.html.gz +0 -0
- package/dist/dashboard/precompressed-assets.json +54 -54
- package/package.json +1 -1
- package/scripts/cli/autostart.ts +237 -0
- package/scripts/cli/command/console-menu.ts +244 -246
- package/scripts/cli/command/tray.ts +208 -204
- package/scripts/cli/command/update.ts +27 -10
- package/scripts/cli/main.ts +28 -1
- package/src/boot/app.ts +693 -693
- package/src/boot/dependencies.ts +646 -616
- package/src/config/spec.ts +81 -2
- package/src/config/telemetry.ts +46 -0
- package/src/console/api-keys/bucket-spend.ts +15 -4
- package/src/console/backup/contracts.ts +15 -2
- package/src/console/backup/routes.ts +52 -1
- package/src/console/backup/service.ts +60 -4
- package/src/console/console-router.ts +8 -0
- package/src/console/data-management/contracts.ts +93 -0
- package/src/console/data-management/operations.ts +229 -0
- package/src/console/data-management/routes.ts +104 -0
- package/src/console/domain-registration.ts +39 -0
- package/src/console/observability/contracts.ts +524 -485
- package/src/console/observability/store.ts +1115 -1018
- package/src/console/providers/catalog/contracts.ts +6 -0
- package/src/console/providers/catalog/provider-operations.ts +20 -0
- package/src/console/providers/catalog/routes.ts +7 -0
- package/src/console/providers/catalog/store.ts +22 -1
- package/src/console/quota/account-quota-shared.ts +52 -39
- package/src/console/quota/refresh.ts +441 -429
- package/src/console/routing/pools/import-parse.ts +206 -0
- package/src/console/routing/pools/operations.ts +543 -501
- package/src/console/routing/pools/routes.ts +181 -164
- package/src/console/settings/contracts.ts +37 -0
- package/src/console/settings/store.ts +51 -0
- package/src/console/share/share-router.ts +6 -9
- package/src/console/updates/routes.ts +16 -0
- package/src/main.ts +10 -0
- package/src/observability/event-compaction.ts +315 -0
- package/src/observability/event-day-index.ts +442 -0
- package/src/observability/event-log.ts +152 -3
- package/src/observability/payload-capture.ts +373 -344
- package/src/observability/payload-store.ts +440 -366
- package/src/observability/telemetry-status.ts +28 -16
- package/src/persistence/health-event-flush.ts +36 -0
- package/src/persistence/schema.ts +1402 -1360
- package/src/persistence/stores/api-key-store.ts +6 -0
- package/src/persistence/stores/share-store.ts +583 -556
- package/src/persistence/stores/telemetry-store.ts +237 -214
- package/src/protocol/codecs.ts +1 -2
- package/src/protocol/image-clamp.ts +19 -1
- package/src/protocol/registry.ts +8 -0
- package/src/protocol/request/gemini.ts +9 -2
- package/src/protocol/request/messages.ts +14 -2
- package/src/protocol/response/gemini.ts +18 -4
- package/src/providers/adapters/compatible-adapter.ts +3 -0
- package/src/providers/bundled-discovery-providers.ts +122 -119
- package/src/providers/configured-openai-providers.ts +136 -134
- package/src/providers/default-registry.ts +5 -4
- package/src/providers/discovery/openai-model-discovery.ts +5 -0
- package/src/providers/discovery/openrouter-free-roster.ts +15 -17
- package/src/providers/integrations/antigravity/antigravity-quota.ts +11 -3
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +4 -4
- package/src/providers/integrations/buddy/workbuddy/shared.ts +201 -200
- package/src/providers/integrations/cline/cline-quota.ts +132 -128
- package/src/providers/integrations/codex/codex-headers.ts +25 -39
- package/src/providers/integrations/codex/codex.ts +2 -29
- package/src/providers/integrations/cursor/cursor-quota.ts +310 -0
- package/src/providers/integrations/cursor/cursor-request.ts +616 -471
- package/src/providers/integrations/cursor/cursor-session-manager.ts +319 -281
- package/src/providers/integrations/cursor/cursor.ts +1485 -960
- package/src/providers/integrations/cursor/protocol/messages.ts +25 -0
- package/src/providers/integrations/factory/factory.ts +8 -1
- package/src/providers/integrations/gemini.ts +6 -1
- package/src/providers/integrations/grok/grok-quota.ts +279 -177
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +73 -0
- package/src/providers/integrations/grok/grok-ratelimit.ts +218 -0
- package/src/providers/integrations/opencode/provider.ts +531 -532
- package/src/providers/integrations/qoder/qoder-quota.ts +192 -0
- package/src/providers/integrations/tokenharbor.ts +2 -2
- package/src/providers/integrations/trae/trae-catalog.ts +5 -3
- package/src/providers/integrations/trae/trae-quota.ts +384 -0
- package/src/providers/operations/account-health-service.ts +1523 -1457
- package/src/providers/operations/client-versions.ts +9 -2
- package/src/providers/provider-contracts.ts +7 -0
- package/src/providers/provider-metadata.ts +13 -1
- package/src/providers/quota/quota-support.ts +8 -0
- package/src/security/api-key-auth.ts +504 -494
- package/src/transport/dispatch/attempt-finalize.ts +46 -5
- package/src/transport/dispatch/generation.ts +6 -0
- package/src/transport/dispatch/proxy-request.ts +33 -1
- package/src/transport/dispatch/ratelimit-capture.ts +37 -0
- package/src/transport/dispatch/streaming/stream.ts +30 -2
- package/src/transport/dispatch/upstream.ts +9 -0
- package/src/transport/request/preparer.ts +7 -6
- package/src/transport/request/state.ts +9 -0
- package/src/transport/request/tenant-preferences.ts +60 -0
- package/src/transport/routing/route-catalog.ts +854 -799
- package/dist/dashboard/assets/BannedPage-MsQaeQTs.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-BO9nKg9w.js +0 -1
- package/dist/dashboard/assets/CliToolDetailPage-BO9nKg9w.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-DfWHTJ7v.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-BrCBQDAc.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-C6Uh33er.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-8aS9hyJu.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-qomXThxX.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-qomXThxX.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-C8hKyXBe.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-CWkTUtpX.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-C-ExCy1V.js +0 -1
- package/dist/dashboard/assets/OverviewPage-C-ExCy1V.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-tr811uaF.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage-tr811uaF.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BS9IEpvv.js +0 -1
- package/dist/dashboard/assets/ProvidersPage-BS9IEpvv.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-Rn_qXScb.js +0 -7
- package/dist/dashboard/assets/ProxyPage-Rn_qXScb.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-BihkgQSq.js +0 -1
- package/dist/dashboard/assets/QuotaPage-BihkgQSq.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-DhiEjm6T.js +0 -1
- package/dist/dashboard/assets/SettingsPage-DhiEjm6T.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-CXjUlfqr.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-C-_oD3F2.js.gz +0 -0
- package/dist/dashboard/assets/StudioPage-u9IxmYOI.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-BEVLVrwP.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-uNywYlfv.js.gz +0 -0
- package/dist/dashboard/assets/app-DxivpfYG.css +0 -2
- package/dist/dashboard/assets/app-DxivpfYG.css.gz +0 -0
- package/dist/dashboard/assets/assert-NHwYq95t.js.gz +0 -0
- package/dist/dashboard/assets/badge-6uzDDvqs.js.gz +0 -0
- package/dist/dashboard/assets/banner-4_WNg2WZ.js.gz +0 -0
- package/dist/dashboard/assets/card--AtFedAq.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-B3e7dx3N.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-NreUx6c8.js.gz +0 -0
- package/dist/dashboard/assets/dialog-BtpsJU98.js.gz +0 -0
- package/dist/dashboard/assets/download-A0SW9OCW.js +0 -1
- package/dist/dashboard/assets/download-A0SW9OCW.js.gz +0 -0
- package/dist/dashboard/assets/drawer-WwwtzihF.js.gz +0 -0
- package/dist/dashboard/assets/entry-Dj9AR0gY.js +0 -4
- package/dist/dashboard/assets/entry-Dj9AR0gY.js.gz +0 -0
- package/dist/dashboard/assets/entry-TJIye_jT.js +0 -1
- package/dist/dashboard/assets/entry-TJIye_jT.js.gz +0 -0
- package/dist/dashboard/assets/entry-jy9_4-Ke.js +0 -1
- package/dist/dashboard/assets/entry-jy9_4-Ke.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-D_eM3IgG.js.gz +0 -0
- package/dist/dashboard/assets/index-DCBtROoK.js.gz +0 -0
- package/dist/dashboard/assets/inline-BcNGF8Gr.js.gz +0 -0
- package/dist/dashboard/assets/input-BG41et9G.js.gz +0 -0
- package/dist/dashboard/assets/layout-C8mer_Ak.js.gz +0 -0
- package/dist/dashboard/assets/list-row-Gh_W4OR_.js.gz +0 -0
- package/dist/dashboard/assets/live-BJGYRBnR.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-DeVLDA7I.js +0 -1
- package/dist/dashboard/assets/model-bans-DeVLDA7I.js.gz +0 -0
- package/dist/dashboard/assets/mutation-BkoLM5Ba.js.gz +0 -0
- package/dist/dashboard/assets/numbers-Bs4LOOuf.js +0 -2
- package/dist/dashboard/assets/numbers-Bs4LOOuf.js.gz +0 -0
- package/dist/dashboard/assets/routing-CcusqXA7.js.gz +0 -0
- package/dist/dashboard/assets/select-DsX5QT8K.js.gz +0 -0
- package/dist/dashboard/assets/settings-mpmXTgUa.js.gz +0 -0
- package/dist/dashboard/assets/sparkles-BRaRUxAU.js +0 -1
- package/dist/dashboard/assets/sparkles-BRaRUxAU.js.gz +0 -0
- package/dist/dashboard/assets/stack-DwLmjUFK.js.gz +0 -0
- package/dist/dashboard/assets/state-DYdQmdAl.js.gz +0 -0
- package/dist/dashboard/assets/switch-CidSfbG7.js +0 -1
- package/dist/dashboard/assets/switch-CidSfbG7.js.gz +0 -0
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js +0 -1
- package/dist/dashboard/assets/terminal-Bd4ee8TA.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-w4u4CVue.js.gz +0 -0
- /package/dist/dashboard/assets/{app-CafWtVXA.js → app-DCQZRmHY.js} +0 -0
- /package/dist/dashboard/assets/{app-CafWtVXA.js.gz → app-DCQZRmHY.js.gz} +0 -0
|
@@ -1,128 +1,132 @@
|
|
|
1
|
-
import type { FetchLike, ProviderQuotaResult, ProviderQuotaWindow } from "../../quota/quota-contracts";
|
|
2
|
-
import { authCredential, getJson, record, text } from "../../quota/quota-contracts";
|
|
3
|
-
import { parseLimitWindows } from "../../quota/quota-limit-windows";
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
* `x-
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
*
|
|
21
|
-
*
|
|
22
|
-
*
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
*
|
|
27
|
-
* the
|
|
28
|
-
*
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"x-platform":
|
|
38
|
-
"x-
|
|
39
|
-
"x-client-
|
|
40
|
-
"x-
|
|
41
|
-
"x-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
//
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
const
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
):
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
const
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
1
|
+
import type { FetchLike, ProviderQuotaResult, ProviderQuotaWindow } from "../../quota/quota-contracts";
|
|
2
|
+
import { authCredential, getJson, record, text } from "../../quota/quota-contracts";
|
|
3
|
+
import { parseLimitWindows } from "../../quota/quota-limit-windows";
|
|
4
|
+
import { getClineCliVersion, getClineSdkVersion } from "../../operations/client-versions";
|
|
5
|
+
import { clinePlatform, clinePlatformVersion } from "../../operations/cli-platform";
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* Quota headers always carry the currently resolved CLI version.
|
|
9
|
+
*
|
|
10
|
+
* The two version headers are two different versions and must stay that way.
|
|
11
|
+
* `x-client-version` is the Cline CLI the operator is running (`cline` on npm),
|
|
12
|
+
* from the shared pooler. `x-core-version` is the `@cline/sdk` version — a
|
|
13
|
+
* separate npm package with its own release line, though one the CLI pins as a
|
|
14
|
+
* dependency. This used to send the *client* version in both slots, so the
|
|
15
|
+
* billing surface was told our core was `4.1.23`, a vscode extension version
|
|
16
|
+
* that `@cline/sdk` never published.
|
|
17
|
+
*
|
|
18
|
+
* Both surfaces now send the same pairing (`cliVersion` / `sdkVersion`) and the
|
|
19
|
+
* same `cline-cli` client type. A header the upstream can validate is not
|
|
20
|
+
* cosmetic: an implausible core version is exactly what a "please update and
|
|
21
|
+
* re-authenticate" refusal is shaped like, and it is indistinguishable from a
|
|
22
|
+
* dead credential from the response alone.
|
|
23
|
+
*
|
|
24
|
+
* Header identity is not what gates these endpoints: probing `/users/me`,
|
|
25
|
+
* `/users/me/plan` and `/users/me/plan/usage-limits` with no identity headers,
|
|
26
|
+
* the SDK identity and the CLI identity all returned identical responses. The
|
|
27
|
+
* 404 from the plan routes is "no plan history found for user", i.e. account
|
|
28
|
+
* state, not a rejected client.
|
|
29
|
+
*/
|
|
30
|
+
function clineQuotaHeaders(): Record<string, string> {
|
|
31
|
+
const version = getClineCliVersion();
|
|
32
|
+
return {
|
|
33
|
+
accept: "application/json",
|
|
34
|
+
"content-type": "application/json",
|
|
35
|
+
"user-agent": `Cline/${version}`,
|
|
36
|
+
"x-platform": clinePlatform(),
|
|
37
|
+
"x-platform-version": clinePlatformVersion(),
|
|
38
|
+
"x-client-type": "cline-cli",
|
|
39
|
+
"x-client-version": version,
|
|
40
|
+
"x-core-version": getClineSdkVersion(),
|
|
41
|
+
"x-is-multiroot": "false",
|
|
42
|
+
};
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
const CLINE_WINDOW_LABELS: Readonly<Record<string, string>> = {
|
|
46
|
+
five_hour: "5 Hour",
|
|
47
|
+
weekly: "7 Day",
|
|
48
|
+
monthly: "30 Day",
|
|
49
|
+
};
|
|
50
|
+
|
|
51
|
+
/** Reads Cline's `limits[]` array — one entry per billing window. */
|
|
52
|
+
function usageWindows(value: unknown): readonly ProviderQuotaWindow[] {
|
|
53
|
+
return [
|
|
54
|
+
...parseLimitWindows(value, {
|
|
55
|
+
kindPaths: ["type"],
|
|
56
|
+
percentPaths: ["percentUsed"],
|
|
57
|
+
resetPaths: ["resetsAt"],
|
|
58
|
+
limitPaths: ["limit", "entitlement", "total"],
|
|
59
|
+
usedPaths: ["used", "usedCredits"],
|
|
60
|
+
// Cline reports a percentage and a ceiling but no absolute used value,
|
|
61
|
+
// so the absolute is derived rather than left null.
|
|
62
|
+
deriveUsed: (_entry, usedPercent, limit) =>
|
|
63
|
+
usedPercent !== null && limit !== null ? (limit * usedPercent) / 100 : null,
|
|
64
|
+
labelFor: (kind) => CLINE_WINDOW_LABELS[kind] ?? null,
|
|
65
|
+
fallbackLabel: (kind) => kind,
|
|
66
|
+
}),
|
|
67
|
+
];
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function isMissingPlanHistory(reason: unknown): boolean {
|
|
71
|
+
const message =
|
|
72
|
+
reason instanceof Error ? reason.message : typeof reason === "string" ? reason : "";
|
|
73
|
+
return /\b404\b|\bno plan history\b/i.test(message);
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/** Envelope marking a resolved secret as an api key rather than an OAuth grant. */
|
|
77
|
+
export const CLINE_API_KEY_PREFIX = "cline-api-key:" as const;
|
|
78
|
+
|
|
79
|
+
/** Wraps a resolved api_key secret so the collector can route it to /models. */
|
|
80
|
+
export function markClineApiKeyCredential(credential: string): string {
|
|
81
|
+
return credential.startsWith(CLINE_API_KEY_PREFIX) ? credential : `${CLINE_API_KEY_PREFIX}${credential}`;
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export async function fetchClineQuota(
|
|
85
|
+
credential: string,
|
|
86
|
+
fetcher: FetchLike,
|
|
87
|
+
): Promise<ProviderQuotaResult> {
|
|
88
|
+
const isApiKey = credential.startsWith(CLINE_API_KEY_PREFIX);
|
|
89
|
+
const bearer = isApiKey ? credential.slice(CLINE_API_KEY_PREFIX.length) : null;
|
|
90
|
+
|
|
91
|
+
let headers: Record<string, string>;
|
|
92
|
+
if (isApiKey && bearer) {
|
|
93
|
+
// An api key is its own bearer token: `Authorization: Bearer sk_...`, with
|
|
94
|
+
// no `workos:` prefix.
|
|
95
|
+
//
|
|
96
|
+
// Prefixing it is what produced "Unauthorized: please make sure you're
|
|
97
|
+
// using the latest version of Cline and re-authenticate" — verified against
|
|
98
|
+
// a live key, where the same key returned 200 on `/users/me` bare and 401
|
|
99
|
+
// once `workos:` was prepended. The message names a version problem, so it
|
|
100
|
+
// reads as a client the upstream refuses rather than a malformed header,
|
|
101
|
+
// which is why it went unrecognised for so long.
|
|
102
|
+
headers = { ...clineQuotaHeaders(), authorization: `Bearer ${bearer}` };
|
|
103
|
+
} else {
|
|
104
|
+
const fields = authCredential(credential);
|
|
105
|
+
const access = text(fields.accessToken);
|
|
106
|
+
if (!access) throw new Error("Cline credential has no access token.");
|
|
107
|
+
headers = {
|
|
108
|
+
...clineQuotaHeaders(),
|
|
109
|
+
authorization: `Bearer ${access.startsWith("workos:") ? access : `workos:${access}`}`,
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
const me = record(await getJson("https://api.cline.bot/api/v1/users/me", headers, fetcher));
|
|
113
|
+
const userId = text(me?.id);
|
|
114
|
+
if (!userId) throw new Error("Cline account response has no user id.");
|
|
115
|
+
const [planRaw, limitsRaw] = await Promise.allSettled([
|
|
116
|
+
getJson("https://api.cline.bot/api/v1/users/me/plan", headers, fetcher),
|
|
117
|
+
getJson("https://api.cline.bot/api/v1/users/me/plan/usage-limits", headers, fetcher),
|
|
118
|
+
]);
|
|
119
|
+
const plan = record(planRaw.status === "fulfilled" ? planRaw.value : null);
|
|
120
|
+
const limitsFailed = limitsRaw.status === "rejected";
|
|
121
|
+
const windows = usageWindows(limitsRaw.status === "fulfilled" ? limitsRaw.value : null);
|
|
122
|
+
const error =
|
|
123
|
+
limitsFailed && !isMissingPlanHistory(limitsRaw.reason)
|
|
124
|
+
? "Failed to fetch quota limits."
|
|
125
|
+
: null;
|
|
126
|
+
return {
|
|
127
|
+
source: "cline",
|
|
128
|
+
plan: text(record(plan?.plan)?.displayName) ?? text(plan?.displayName) ?? "Cline",
|
|
129
|
+
windows,
|
|
130
|
+
error,
|
|
131
|
+
};
|
|
132
|
+
}
|
|
@@ -16,31 +16,38 @@ interface CodexIdentityHeadersOptions {
|
|
|
16
16
|
readonly sessionId?: string | undefined;
|
|
17
17
|
readonly threadId?: string | undefined;
|
|
18
18
|
readonly windowId?: string | undefined;
|
|
19
|
-
readonly turnId?: string | undefined;
|
|
20
|
-
readonly parentTurnId?: string | undefined;
|
|
21
|
-
readonly conversationId?: string | undefined;
|
|
22
|
-
readonly installationId?: string | undefined;
|
|
23
19
|
readonly turnMetadataJson?: string | undefined;
|
|
24
20
|
readonly betaFeatures?: string | undefined;
|
|
25
21
|
readonly subAgent?: string | undefined;
|
|
26
22
|
readonly responsesLite?: boolean | undefined;
|
|
27
23
|
readonly turnState?: string | undefined;
|
|
28
|
-
readonly modelsEtag?: string | undefined;
|
|
29
|
-
/**
|
|
30
|
-
* `x-codex-routing-hint: model=<slug>[;tier=<service_tier>]` — codex-rs
|
|
31
|
-
* sends this on every ChatGPT-OAuth Responses/compaction/WebSocket
|
|
32
|
-
* request. Callers compute the value; absent/empty omits the header.
|
|
33
|
-
*/
|
|
34
|
-
readonly routingHint?: string | undefined;
|
|
35
24
|
}
|
|
36
25
|
|
|
26
|
+
/**
|
|
27
|
+
* Assembles the request headers the reference ChatGPT-OAuth Responses
|
|
28
|
+
* dispatch sends (`codex-rs` rust-v0.160.0):
|
|
29
|
+
*
|
|
30
|
+
* - default client headers (`default_headers`): `originator`, `user-agent`
|
|
31
|
+
* (no `version` header at this tag);
|
|
32
|
+
* - auth (`add_auth_headers`): `authorization`, `chatgpt-account-id`;
|
|
33
|
+
* - per-request extras (`build_responses_options`): `x-codex-beta-features`?,
|
|
34
|
+
* `x-codex-turn-state`?, `x-oai-attestation`?, lite header when Responses
|
|
35
|
+
* Lite, the compatibility projection (`x-codex-window-id`,
|
|
36
|
+
* `x-codex-turn-metadata`, `x-codex-parent-thread-id`?, `x-openai-subagent`?);
|
|
37
|
+
* - transport options (`ApiResponsesOptions` + stream wrapper):
|
|
38
|
+
* `x-client-request-id` / `session-id` / `thread-id` / `x-openai-subagent`?.
|
|
39
|
+
*
|
|
40
|
+
* Identity values that moved into the body (`client_metadata` — installation,
|
|
41
|
+
* turn id, parent turn id) are absent here by design. `conversation-id`,
|
|
42
|
+
* `turn-id`, `parent-turn-id` direct headers and `x-codex-routing-hint`
|
|
43
|
+
* (WebSocket-only at this tag) are not emitted.
|
|
44
|
+
*/
|
|
37
45
|
export function buildCodexIdentityHeaders(
|
|
38
46
|
options: CodexIdentityHeadersOptions,
|
|
39
47
|
): Record<string, string> {
|
|
40
48
|
const headers: Record<string, string> = {};
|
|
41
49
|
headers["user-agent"] = buildCodexUserAgent(options.version);
|
|
42
50
|
headers["originator"] = "codex_cli_rs";
|
|
43
|
-
headers["version"] = options.version;
|
|
44
51
|
const token =
|
|
45
52
|
options.credential.secret === undefined
|
|
46
53
|
? undefined
|
|
@@ -50,37 +57,19 @@ export function buildCodexIdentityHeaders(
|
|
|
50
57
|
(token === undefined ? undefined : getCodexAccountId(token));
|
|
51
58
|
if (accountId !== undefined && accountId.length > 0)
|
|
52
59
|
headers["chatgpt-account-id"] = accountId;
|
|
53
|
-
headers["OpenAI-Beta"] = "responses=experimental";
|
|
54
60
|
if (options.attestation !== undefined && options.attestation.length > 0)
|
|
55
61
|
headers["x-oai-attestation"] = options.attestation;
|
|
56
62
|
if (options.residency !== undefined && options.residency.length > 0)
|
|
57
63
|
headers["x-openai-internal-codex-residency"] = options.residency;
|
|
58
64
|
if (options.sessionId !== undefined && options.sessionId.length > 0) {
|
|
59
65
|
headers["session-id"] = options.sessionId;
|
|
60
|
-
headers["x-client-request-id"] = options.sessionId;
|
|
61
|
-
if (
|
|
62
|
-
options.conversationId === undefined ||
|
|
63
|
-
options.conversationId.length === 0
|
|
64
|
-
) {
|
|
65
|
-
headers["conversation-id"] = options.sessionId;
|
|
66
|
-
}
|
|
67
66
|
}
|
|
68
|
-
if (options.threadId !== undefined && options.threadId.length > 0)
|
|
67
|
+
if (options.threadId !== undefined && options.threadId.length > 0) {
|
|
69
68
|
headers["thread-id"] = options.threadId;
|
|
69
|
+
headers["x-client-request-id"] = options.threadId;
|
|
70
|
+
}
|
|
70
71
|
if (options.windowId !== undefined && options.windowId.length > 0)
|
|
71
72
|
headers["x-codex-window-id"] = options.windowId;
|
|
72
|
-
if (options.turnId !== undefined && options.turnId.length > 0)
|
|
73
|
-
headers["turn-id"] = options.turnId;
|
|
74
|
-
if (options.parentTurnId !== undefined && options.parentTurnId.length > 0)
|
|
75
|
-
headers["parent-turn-id"] = options.parentTurnId;
|
|
76
|
-
if (options.conversationId !== undefined && options.conversationId.length > 0)
|
|
77
|
-
headers["conversation-id"] = options.conversationId;
|
|
78
|
-
if (
|
|
79
|
-
options.installationId !== undefined &&
|
|
80
|
-
options.installationId.length > 0
|
|
81
|
-
) {
|
|
82
|
-
headers["x-codex-installation-id"] = options.installationId;
|
|
83
|
-
}
|
|
84
73
|
if (
|
|
85
74
|
options.turnMetadataJson !== undefined &&
|
|
86
75
|
options.turnMetadataJson.length > 0
|
|
@@ -99,12 +88,6 @@ export function buildCodexIdentityHeaders(
|
|
|
99
88
|
if (options.turnState !== undefined && options.turnState.length > 0) {
|
|
100
89
|
headers["x-codex-turn-state"] = options.turnState;
|
|
101
90
|
}
|
|
102
|
-
if (options.modelsEtag !== undefined && options.modelsEtag.length > 0) {
|
|
103
|
-
headers["x-models-etag"] = options.modelsEtag;
|
|
104
|
-
}
|
|
105
|
-
if (options.routingHint !== undefined && options.routingHint.length > 0) {
|
|
106
|
-
headers["x-codex-routing-hint"] = options.routingHint;
|
|
107
|
-
}
|
|
108
91
|
return headers;
|
|
109
92
|
}
|
|
110
93
|
|
|
@@ -118,6 +101,7 @@ export function createCodexRequestMetadata(args: {
|
|
|
118
101
|
windowId: string;
|
|
119
102
|
turnId: string;
|
|
120
103
|
parentTurnId?: string;
|
|
104
|
+
subAgent?: string;
|
|
121
105
|
requestKind?: string;
|
|
122
106
|
turnStartedAtUnixMs?: number;
|
|
123
107
|
compaction?: Record<string, unknown>;
|
|
@@ -150,6 +134,8 @@ export function createCodexRequestMetadata(args: {
|
|
|
150
134
|
};
|
|
151
135
|
if (args.parentTurnId !== undefined && args.parentTurnId.length > 0)
|
|
152
136
|
clientMetadata["parent_turn_id"] = args.parentTurnId;
|
|
137
|
+
if (args.subAgent !== undefined && args.subAgent.length > 0)
|
|
138
|
+
clientMetadata["x-openai-subagent"] = args.subAgent;
|
|
153
139
|
clientMetadata["x-codex-turn-metadata"] = turnMetadataJson;
|
|
154
140
|
return { clientMetadata, turnMetadataJson };
|
|
155
141
|
}
|
|
@@ -551,8 +551,8 @@ export function createCodexAdapter(
|
|
|
551
551
|
const subAgent = config.subagent;
|
|
552
552
|
const installationOverride = config.installation_id_override;
|
|
553
553
|
|
|
554
|
-
// Per-session state for sticky routing (x-codex-turn-state
|
|
555
|
-
//
|
|
554
|
+
// Per-session state for sticky routing (x-codex-turn-state) and identity
|
|
555
|
+
// reuse. Bounded LRU + TTL: an unbounded map would leak
|
|
556
556
|
// memory forever under a long-running process serving many distinct
|
|
557
557
|
// Codex sessions.
|
|
558
558
|
const sessionStates = new Map<
|
|
@@ -639,16 +639,13 @@ export function createCodexAdapter(
|
|
|
639
639
|
const state = getSessionState(sessionId);
|
|
640
640
|
if (state === undefined) return;
|
|
641
641
|
let turnState: string | null = null;
|
|
642
|
-
let modelsEtag: string | null = null;
|
|
643
642
|
if (headers instanceof Headers) {
|
|
644
643
|
turnState = headers.get("x-codex-turn-state");
|
|
645
|
-
modelsEtag = headers.get("x-models-etag");
|
|
646
644
|
} else if (typeof headers === "object") {
|
|
647
645
|
const rec = headers as Record<string, string>;
|
|
648
646
|
for (const [k, v] of Object.entries(rec)) {
|
|
649
647
|
const lower = k.toLowerCase();
|
|
650
648
|
if (lower === "x-codex-turn-state") turnState = v;
|
|
651
|
-
if (lower === "x-models-etag") modelsEtag = v;
|
|
652
649
|
}
|
|
653
650
|
}
|
|
654
651
|
if (
|
|
@@ -658,9 +655,6 @@ export function createCodexAdapter(
|
|
|
658
655
|
) {
|
|
659
656
|
state.turnState = turnState;
|
|
660
657
|
}
|
|
661
|
-
if (modelsEtag !== null && modelsEtag.length > 0) {
|
|
662
|
-
state.modelsEtag = modelsEtag;
|
|
663
|
-
}
|
|
664
658
|
}
|
|
665
659
|
|
|
666
660
|
return {
|
|
@@ -700,13 +694,10 @@ export function createCodexAdapter(
|
|
|
700
694
|
sessionId: identity.session_id,
|
|
701
695
|
threadId: identity.thread_id,
|
|
702
696
|
windowId: identity.window_id,
|
|
703
|
-
turnId: identity.turn_id,
|
|
704
|
-
installationId,
|
|
705
697
|
turnMetadataJson,
|
|
706
698
|
betaFeatures: betaRemoteCompaction
|
|
707
699
|
? "remote_compaction_v2"
|
|
708
700
|
: undefined,
|
|
709
|
-
routingHint: `model=${body["model"] as string}`,
|
|
710
701
|
}),
|
|
711
702
|
};
|
|
712
703
|
const { res, release } = await postUpstreamJson(
|
|
@@ -919,7 +910,6 @@ export function createCodexAdapter(
|
|
|
919
910
|
let rawWindowId = nonEmpty(request.window_id);
|
|
920
911
|
let rawTurnId = nonEmpty(request.turn_id);
|
|
921
912
|
const rawParentTurnId = nonEmpty(request.parent_turn_id);
|
|
922
|
-
const rawConversationId = nonEmpty(request.conversation_id);
|
|
923
913
|
|
|
924
914
|
const installationId = await getInstallationIdCached();
|
|
925
915
|
|
|
@@ -970,9 +960,6 @@ export function createCodexAdapter(
|
|
|
970
960
|
const turnStartedAtUnixMs = Date.now();
|
|
971
961
|
sessionState.turnStartedAtUnixMs = turnStartedAtUnixMs;
|
|
972
962
|
|
|
973
|
-
// If conversation_id not supplied, mirror session_id (reference behavior).
|
|
974
|
-
const conversationId = rawConversationId ?? effectiveSessionId;
|
|
975
|
-
|
|
976
963
|
const token =
|
|
977
964
|
context.credential.secret === undefined
|
|
978
965
|
? undefined
|
|
@@ -998,12 +985,6 @@ export function createCodexAdapter(
|
|
|
998
985
|
const betaFeatures = betaRemoteCompaction
|
|
999
986
|
? "remote_compaction_v2"
|
|
1000
987
|
: undefined;
|
|
1001
|
-
// `x-codex-routing-hint` mirrors codex-rs (`codexRoutingHint`): the
|
|
1002
|
-
// Codex adapter is OAuth-family only, so the hint is always emitted.
|
|
1003
|
-
const serviceTier = request.generation_controls.service_tier;
|
|
1004
|
-
const routingHint = serviceTier
|
|
1005
|
-
? `model=${request.model};tier=${serviceTier}`
|
|
1006
|
-
: `model=${request.model}`;
|
|
1007
988
|
|
|
1008
989
|
const headers: Record<string, string> = {
|
|
1009
990
|
"content-type": "application/json",
|
|
@@ -1020,19 +1001,11 @@ export function createCodexAdapter(
|
|
|
1020
1001
|
sessionId: effectiveSessionId,
|
|
1021
1002
|
threadId,
|
|
1022
1003
|
windowId,
|
|
1023
|
-
turnId,
|
|
1024
|
-
...(rawParentTurnId === undefined
|
|
1025
|
-
? {}
|
|
1026
|
-
: { parentTurnId: rawParentTurnId }),
|
|
1027
|
-
conversationId,
|
|
1028
|
-
installationId,
|
|
1029
1004
|
turnMetadataJson,
|
|
1030
1005
|
betaFeatures,
|
|
1031
1006
|
subAgent,
|
|
1032
1007
|
responsesLite,
|
|
1033
1008
|
turnState: sessionState.turnState,
|
|
1034
|
-
modelsEtag: sessionState.modelsEtag,
|
|
1035
|
-
routingHint,
|
|
1036
1009
|
}),
|
|
1037
1010
|
);
|
|
1038
1011
|
const outboundFetch = context.outbound_fetch ?? fetchFn;
|