cartethyia 2.5.9 → 2.6.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 +15 -42
- package/README.md +11 -10
- package/dist/dashboard/assets/{BannedPage-Brvuj_Eb.js → BannedPage-l6XMnfr9.js} +1 -1
- package/dist/dashboard/assets/BannedPage-l6XMnfr9.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolDetailPage-CqfXtI3y.js → CliToolDetailPage-DwOzAW45.js} +1 -1
- package/dist/dashboard/assets/CliToolDetailPage-DwOzAW45.js.gz +0 -0
- package/dist/dashboard/assets/{CliToolsPage-GQeS91bg.js → CliToolsPage-BT3Up3QA.js} +1 -1
- package/dist/dashboard/assets/CliToolsPage-BT3Up3QA.js.gz +0 -0
- package/dist/dashboard/assets/{CombosPage-BDRsTXBB.js → CombosPage-6kYIUpzR.js} +1 -1
- package/dist/dashboard/assets/CombosPage-6kYIUpzR.js.gz +0 -0
- package/dist/dashboard/assets/{ConsoleLogPage-zP8AFHX0.js → ConsoleLogPage-zRnj1mlR.js} +1 -1
- package/dist/dashboard/assets/ConsoleLogPage-zRnj1mlR.js.gz +0 -0
- package/dist/dashboard/assets/{CustomizationPage-BmfrNZ14.js → CustomizationPage-C7m-H1Rz.js} +1 -1
- package/dist/dashboard/assets/CustomizationPage-C7m-H1Rz.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js +1 -0
- package/dist/dashboard/assets/HealthEventsModal-C8MR_BdB.js.gz +0 -0
- package/dist/dashboard/assets/{LoginPage-DoreIgm8.js → LoginPage-CbphLvjg.js} +1 -1
- package/dist/dashboard/assets/LoginPage-CbphLvjg.js.gz +0 -0
- package/dist/dashboard/assets/{ModelPicker-C7pDb41R.js → ModelPicker-DVny4S5_.js} +1 -1
- package/dist/dashboard/assets/ModelPicker-DVny4S5_.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js +1 -0
- package/dist/dashboard/assets/OverviewPage-DABu2Wgt.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js +3 -0
- package/dist/dashboard/assets/ProviderDetailPage-C15x9q13.js.gz +0 -0
- package/dist/dashboard/assets/{ProvidersPage-BnoPgA7w.js → ProvidersPage-Dfb2896L.js} +1 -1
- package/dist/dashboard/assets/ProvidersPage-Dfb2896L.js.gz +0 -0
- package/dist/dashboard/assets/{ProxyPage-Bq_TGgdb.js → ProxyPage-BaCIdAUt.js} +1 -1
- package/dist/dashboard/assets/ProxyPage-BaCIdAUt.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js +1 -0
- package/dist/dashboard/assets/QuotaPage-BsdoCIw1.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js +1 -0
- package/dist/dashboard/assets/SettingsPage-KVJFh3Ip.js.gz +0 -0
- package/dist/dashboard/assets/{SetupPage-Day3mCOn.js → SetupPage-D4g6vOGc.js} +1 -1
- package/dist/dashboard/assets/SetupPage-D4g6vOGc.js.gz +0 -0
- package/dist/dashboard/assets/{SortableList-DQxllnB5.js → SortableList-C93i14BD.js} +1 -1
- package/dist/dashboard/assets/SortableList-C93i14BD.js.gz +0 -0
- package/dist/dashboard/assets/{StudioPage-uMExoWu1.js → StudioPage-SgQpymjm.js} +1 -1
- package/dist/dashboard/assets/{StudioPage-uMExoWu1.js.gz → StudioPage-SgQpymjm.js.gz} +0 -0
- package/dist/dashboard/assets/{UsagePage-DXa1oR-4.js → UsagePage-BFME-eba.js} +2 -2
- package/dist/dashboard/assets/UsagePage-BFME-eba.js.gz +0 -0
- package/dist/dashboard/assets/{api-keys-DQYLQxpW.js → api-keys-C23S9sgp.js} +1 -1
- package/dist/dashboard/assets/api-keys-C23S9sgp.js.gz +0 -0
- package/dist/dashboard/assets/{app-BIt446yE.js → app-2KhtHCv9.js} +1 -1
- package/dist/dashboard/assets/{app-BIt446yE.js.gz → app-2KhtHCv9.js.gz} +0 -0
- package/dist/dashboard/assets/app-CEeaMHOy.css +2 -0
- package/dist/dashboard/assets/app-CEeaMHOy.css.gz +0 -0
- package/dist/dashboard/assets/{assert-C9FD_JwJ.js → assert-DU6qrMA_.js} +1 -1
- package/dist/dashboard/assets/assert-DU6qrMA_.js.gz +0 -0
- package/dist/dashboard/assets/{badge-CR72dasT.js → badge-CKsF123d.js} +1 -1
- package/dist/dashboard/assets/badge-CKsF123d.js.gz +0 -0
- package/dist/dashboard/assets/{banner-CI9_eSfO.js → banner-8j7uChA9.js} +1 -1
- package/dist/dashboard/assets/banner-8j7uChA9.js.gz +0 -0
- package/dist/dashboard/assets/{card-DS7CQEsO.js → card-CdsSlWA3.js} +1 -1
- package/dist/dashboard/assets/card-CdsSlWA3.js.gz +0 -0
- package/dist/dashboard/assets/{cli-tools-CNqzrfdb.js → cli-tools-BaFUuFFF.js} +1 -1
- package/dist/dashboard/assets/cli-tools-BaFUuFFF.js.gz +0 -0
- package/dist/dashboard/assets/{clipboard-button-611pSsaX.js → clipboard-button-uL5aYLfW.js} +1 -1
- package/dist/dashboard/assets/clipboard-button-uL5aYLfW.js.gz +0 -0
- package/dist/dashboard/assets/{dialog-k37exjNt.js → dialog-C07hr5_G.js} +1 -1
- package/dist/dashboard/assets/dialog-C07hr5_G.js.gz +0 -0
- package/dist/dashboard/assets/{drawer-CX7N8ucR.js → drawer-BPO1TcKH.js} +1 -1
- package/dist/dashboard/assets/drawer-BPO1TcKH.js.gz +0 -0
- package/dist/dashboard/assets/{entry-CTP8AyiS.js → entry-Bz_CtDfC.js} +1 -1
- package/dist/dashboard/assets/entry-Bz_CtDfC.js.gz +0 -0
- package/dist/dashboard/assets/entry-CwPRKk0d.js +4 -0
- package/dist/dashboard/assets/entry-CwPRKk0d.js.gz +0 -0
- package/dist/dashboard/assets/entry-GJRbmrpA.js +1 -0
- package/dist/dashboard/assets/entry-GJRbmrpA.js.gz +0 -0
- package/dist/dashboard/assets/{github-badge-sltk1qUi.js → github-badge-DmQreSDd.js} +1 -1
- package/dist/dashboard/assets/github-badge-DmQreSDd.js.gz +0 -0
- package/dist/dashboard/assets/{index-z3zDOSMM.js → index-Bblu6erR.js} +2 -2
- package/dist/dashboard/assets/index-Bblu6erR.js.gz +0 -0
- package/dist/dashboard/assets/{inline-BhY2sSnO.js → inline-C9dCYaBZ.js} +1 -1
- package/dist/dashboard/assets/inline-C9dCYaBZ.js.gz +0 -0
- package/dist/dashboard/assets/{input-V1umFiBk.js → input-CjCnXweJ.js} +1 -1
- package/dist/dashboard/assets/input-CjCnXweJ.js.gz +0 -0
- package/dist/dashboard/assets/{layout-BBOYycyS.js → layout-V6y8DAkl.js} +1 -1
- package/dist/dashboard/assets/layout-V6y8DAkl.js.gz +0 -0
- package/dist/dashboard/assets/{list-row-1zzZYM0B.js → list-row-CM1AaG_y.js} +1 -1
- package/dist/dashboard/assets/list-row-CM1AaG_y.js.gz +0 -0
- package/dist/dashboard/assets/{live-BivGfuUs.js → live-ta6GMb-8.js} +1 -1
- package/dist/dashboard/assets/live-ta6GMb-8.js.gz +0 -0
- package/dist/dashboard/assets/{model-bans-CmffjLuG.js → model-bans-BmYTmbAk.js} +1 -1
- package/dist/dashboard/assets/model-bans-BmYTmbAk.js.gz +0 -0
- package/dist/dashboard/assets/{mutation-46P0oWMe.js → mutation-g_fduiNw.js} +1 -1
- package/dist/dashboard/assets/mutation-g_fduiNw.js.gz +0 -0
- package/dist/dashboard/assets/{numbers-DkfMR5Qs.js → numbers-BOevJzdz.js} +1 -1
- package/dist/dashboard/assets/numbers-BOevJzdz.js.gz +0 -0
- package/dist/dashboard/assets/{query-keys-BFhGpwR1.js → query-keys-UETqfytp.js} +1 -1
- package/dist/dashboard/assets/query-keys-UETqfytp.js.gz +0 -0
- package/dist/dashboard/assets/{routing-CAb4F37R.js → routing-BPUo-W8d.js} +1 -1
- package/dist/dashboard/assets/routing-BPUo-W8d.js.gz +0 -0
- package/dist/dashboard/assets/{select-C6MMiaio.js → select-C980c4cz.js} +1 -1
- package/dist/dashboard/assets/select-C980c4cz.js.gz +0 -0
- package/dist/dashboard/assets/{settings-DNX9sydi.js → settings--3hxSyry.js} +1 -1
- package/dist/dashboard/assets/settings--3hxSyry.js.gz +0 -0
- package/dist/dashboard/assets/{stack-BHTfXdz_.js → stack-_gfTdLVB.js} +1 -1
- package/dist/dashboard/assets/stack-_gfTdLVB.js.gz +0 -0
- package/dist/dashboard/assets/{state-mPDRlQkl.js → state-2c5V4zo7.js} +1 -1
- package/dist/dashboard/assets/state-2c5V4zo7.js.gz +0 -0
- package/dist/dashboard/assets/{switch-DOmJxg7H.js → switch-Dkke7Naf.js} +1 -1
- package/dist/dashboard/assets/switch-Dkke7Naf.js.gz +0 -0
- package/dist/dashboard/assets/{useMutation-Dem0lXQj.js → useMutation-EDFRkn1i.js} +1 -1
- package/dist/dashboard/assets/useMutation-EDFRkn1i.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 +51 -51
- package/migrations/README.md +52 -52
- package/migrations/full-postgres/0020_add_telemetry_event_analytics.sql +77 -0
- package/migrations/full-postgres/0021_add_api_key_concurrency_tolerance.sql +13 -0
- package/migrations/full-postgres/0022_add_inferhub_config_key.sql +17 -0
- package/migrations/full-postgres/0023_drop_api_key_concurrency_tolerance.sql +13 -0
- package/migrations/lite-sqlite3/0020_add_telemetry_event_analytics.sql +69 -0
- package/migrations/lite-sqlite3/0021_add_api_key_concurrency_tolerance.sql +13 -0
- package/migrations/lite-sqlite3/0022_add_inferhub_config_key.sql +17 -0
- package/migrations/lite-sqlite3/0023_drop_api_key_concurrency_tolerance.sql +13 -0
- package/package.json +96 -97
- package/scripts/cli/admin.ts +126 -125
- package/scripts/cli/autostart.ts +237 -237
- package/scripts/cli/background.ts +120 -110
- package/scripts/cli/bin/carte.cjs +8 -8
- package/scripts/cli/bin/cartethyia.cjs +167 -167
- package/scripts/cli/console-menu.ts +308 -275
- package/scripts/cli/controller.ts +145 -0
- package/scripts/cli/doctor.ts +1 -1
- package/scripts/cli/env.ts +99 -99
- package/scripts/cli/gateway.ts +264 -261
- package/scripts/{health.ts → cli/health.ts} +4 -4
- package/scripts/cli/instance.ts +234 -224
- package/scripts/cli/main.ts +188 -164
- package/scripts/cli/platform.ts +64 -64
- package/scripts/cli/prompt.ts +275 -107
- package/scripts/cli/services.ts +88 -88
- package/scripts/cli/setup.ts +445 -445
- package/scripts/cli/start.ts +85 -82
- package/scripts/cli/startup-signal.ts +23 -23
- package/scripts/cli/telemetry.ts +70 -0
- package/scripts/cli/tray/index.ts +263 -263
- package/scripts/cli/tray/windows.ps1 +107 -107
- package/scripts/cli/tray.ts +192 -208
- package/scripts/cli/update.ts +39 -39
- package/scripts/cli/version.ts +67 -67
- package/scripts/cli/wordmark.ts +58 -58
- package/src/boot/app.ts +16 -1
- package/src/boot/dependencies.ts +128 -25
- package/src/config/package-paths.ts +24 -0
- package/src/config/resources.ts +137 -0
- package/src/config/runtime.ts +133 -76
- package/src/config/spec.ts +30 -29
- package/src/config/telemetry.ts +0 -25
- package/src/console/api-keys/bucket-spend.ts +14 -17
- package/src/console/api-keys/contracts.ts +410 -410
- package/src/console/api-keys/routes.ts +12 -0
- package/src/console/audit/store.ts +2 -3
- package/src/console/auth/setup-service.ts +8 -1
- package/src/console/backup/routes.ts +7 -0
- package/src/console/backup/service.ts +463 -463
- package/src/console/backup/store.ts +16 -11
- package/src/console/backup/validate.ts +1 -4
- package/src/console/cli-tools/fs-ops.ts +18 -2
- package/src/console/data-management/contracts.ts +1 -8
- package/src/console/data-management/operations.ts +61 -48
- package/src/console/data-management/routes.ts +4 -2
- package/src/console/domain-registration.ts +25 -3
- package/src/console/inferhub/client.ts +139 -0
- package/src/console/inferhub/key-store.ts +129 -0
- package/src/console/inferhub/normalize.ts +347 -0
- package/src/console/inferhub/routes.ts +411 -0
- package/src/console/inferhub/store.ts +109 -0
- package/src/console/inferhub/types.ts +183 -0
- package/src/console/observability/contracts.ts +2 -41
- package/src/console/observability/store.ts +176 -371
- package/src/console/providers/catalog/public-model-store.ts +0 -0
- package/src/console/providers/catalog/store.ts +23 -36
- package/src/console/quota/account-quota-shared.ts +52 -52
- package/src/console/quota/account-quota-tenant.ts +16 -24
- package/src/console/quota/refresh.ts +441 -441
- package/src/console/remote-support/service.ts +270 -114
- package/src/console/routing/pools/import-parse.ts +206 -206
- package/src/console/routing/pools/operations.ts +543 -543
- package/src/console/routing/pools/probe-verdict.ts +132 -132
- package/src/console/routing/pools/routes.ts +181 -181
- package/src/console/routing/pools/store.ts +1 -1
- package/src/console/settings/contracts.ts +42 -40
- package/src/console/settings/store.ts +25 -25
- package/src/console/share/share-stats.ts +22 -4
- package/src/console/share/share-usage.ts +30 -4
- package/src/console/shared/cursor.ts +15 -0
- package/src/console/updates/repository-updates.ts +40 -39
- package/src/console/updates/routes.ts +12 -0
- package/src/main.ts +13 -5
- package/src/network/pool/resolver.ts +1104 -1104
- package/src/observability/client-name.ts +22 -0
- package/src/observability/event-log.ts +5 -29
- package/src/observability/event-query.ts +690 -0
- package/src/observability/log-ring.ts +26 -2
- package/src/observability/log-sanitize.ts +118 -0
- package/src/observability/logger.ts +17 -13
- package/src/observability/metrics.ts +35 -0
- package/src/observability/payload-capture.ts +114 -41
- package/src/observability/payload-store.ts +249 -24
- package/src/observability/raw-event-writer.ts +118 -0
- package/src/observability/runtime-metrics.ts +71 -1
- package/src/observability/telemetry-buffer.ts +100 -17
- package/src/observability/telemetry-reconciliation.ts +417 -0
- package/src/persistence/boot.ts +20 -9
- package/src/persistence/db-pg.ts +13 -0
- package/src/persistence/db-sqlite.ts +569 -497
- package/src/persistence/dialect.ts +3 -2
- package/src/persistence/migrate.ts +181 -181
- package/src/persistence/schema.ts +1496 -1406
- package/src/persistence/shared-cache.ts +5 -1
- package/src/persistence/stores/api-key-store.ts +581 -581
- package/src/persistence/stores/telemetry-store.ts +124 -63
- package/src/protocol/reasoning-text.ts +30 -0
- package/src/protocol/registry.ts +2 -0
- package/src/protocol/response/chat.ts +33 -7
- package/src/protocol/response/codex.ts +14 -2
- package/src/protocol/response/messages.ts +5 -2
- package/src/providers/authentication/oauth-flow-store.ts +3 -10
- package/src/providers/bundled-discovery-providers.ts +122 -122
- package/src/providers/default-registry.ts +14 -0
- package/src/providers/discovery/catalog/catalog-blob.ts +18 -18
- package/src/providers/discovery/models-dev-catalog.ts +354 -354
- package/src/providers/discovery/probe-phases.ts +43 -7
- package/src/providers/discovery/probing-service.ts +70 -32
- package/src/providers/integrations/antigravity/antigravity.ts +9 -2
- package/src/providers/integrations/buddy/buddy-catalog-shared.ts +85 -17
- package/src/providers/integrations/buddy/buddy-chat-shared.ts +934 -934
- package/src/providers/integrations/buddy/buddy-checkin.ts +5 -9
- package/src/providers/integrations/buddy/buddy-discovery-shared.ts +3 -7
- package/src/providers/integrations/buddy/buddy-quota-shared.ts +3 -1
- package/src/providers/integrations/buddy/capabilities.ts +4 -0
- package/src/providers/integrations/buddy/codebuddy/cn-provider.ts +57 -49
- package/src/providers/integrations/buddy/codebuddy/provider.ts +180 -180
- package/src/providers/integrations/buddy/workbuddy/provider.ts +206 -206
- package/src/providers/integrations/buddy/workbuddy/quota.ts +161 -161
- package/src/providers/integrations/claude/claude-quota.ts +2 -2
- package/src/providers/integrations/claude/claude-user-profiles.ts +3 -2
- package/src/providers/integrations/claude/claude.ts +3 -4
- package/src/providers/integrations/cline/cline.ts +94 -8
- package/src/providers/integrations/codex/codex.ts +61 -37
- package/src/providers/integrations/cursor/cursor-catalog.ts +368 -368
- package/src/providers/integrations/cursor/cursor-http2.ts +300 -300
- package/src/providers/integrations/cursor/cursor-identity.ts +2 -4
- package/src/providers/integrations/cursor/cursor-request.ts +11 -0
- package/src/providers/integrations/cursor/cursor.ts +29 -17
- package/src/providers/integrations/cursor/protocol/framing.ts +129 -129
- package/src/providers/integrations/cursor/protocol/messages.ts +2380 -2380
- package/src/providers/integrations/cursor/protocol/struct.ts +305 -305
- package/src/providers/integrations/cursor/protocol/tool-canonical.ts +275 -0
- package/src/providers/integrations/github/github.ts +3 -1
- package/src/providers/integrations/grok/grok-quota.ts +279 -279
- package/src/providers/integrations/grok/grok-ratelimit-store.ts +73 -73
- package/src/providers/integrations/grok/grok-ratelimit.ts +218 -218
- package/src/providers/integrations/hermes.ts +7 -1
- package/src/providers/integrations/inferhub.ts +201 -73
- package/src/providers/integrations/kilo/kilo.ts +152 -152
- package/src/providers/integrations/kiro/kiro-machine-id.ts +2 -4
- package/src/providers/integrations/opencode/provider.ts +2 -0
- package/src/providers/integrations/openrouter/provider.ts +129 -129
- package/src/providers/integrations/qoder/qoder-quota.ts +193 -192
- package/src/providers/integrations/qoder/qoder-realm.ts +106 -106
- package/src/providers/integrations/trae/trae-headers.ts +17 -48
- package/src/providers/integrations/trae/trae-oauth.ts +4 -26
- package/src/providers/integrations/trae/trae-quota.ts +389 -384
- package/src/providers/integrations/trae/trae-realm.ts +15 -2
- package/src/providers/integrations/trae/trae.ts +22 -24
- package/src/providers/integrations/xiaomi-mimo/think-stream.ts +100 -24
- package/src/providers/integrations/zcode/oauth.ts +1 -1
- package/src/providers/operations/account-health-service.ts +605 -279
- package/src/providers/provider-metadata.ts +12 -1
- package/src/providers/provider-model-definition.ts +373 -373
- package/src/providers/provider-probe.ts +3 -0
- package/src/providers/quota/quota-contracts.ts +3 -7
- package/src/providers/search/search-provider.ts +2 -6
- package/src/security/admission/contracts.ts +10 -0
- package/src/security/admission/in-memory-store.ts +89 -14
- package/src/security/admission/lua.ts +191 -182
- package/src/security/admission/redis-store.ts +30 -0
- package/src/security/admission/service.ts +18 -0
- package/src/security/api-key-auth-cache.ts +96 -0
- package/src/security/api-key-auth.ts +11 -100
- package/src/security/client-router-fingerprint.ts +3 -7
- package/src/security/ip-boundary.ts +7 -3
- package/src/shared/coerce.ts +67 -0
- package/src/shared/hash.ts +6 -0
- package/src/shared/time.ts +7 -0
- package/src/transport/dispatch/attempt-finalize.ts +26 -138
- package/src/transport/dispatch/attempt-loop.ts +103 -81
- package/src/transport/dispatch/capture-policy.ts +78 -0
- package/src/transport/dispatch/proxy-request.ts +4 -2
- package/src/transport/dispatch/streaming/encoder.ts +111 -5
- package/src/transport/dispatch/streaming/stream.ts +19 -2
- package/src/transport/dispatch/streaming/thinking-loop.ts +300 -0
- package/src/transport/failure-policy.ts +27 -0
- package/src/transport/guards/abuse-guard.ts +2 -2
- package/src/transport/guards/auth-guard.ts +17 -0
- package/src/transport/guards/body-policy.ts +3 -2
- package/src/transport/guards/concurrency-guard.ts +89 -13
- package/src/transport/guards/early-rejection-capture.ts +43 -3
- package/src/transport/guards/error-lifecycle.ts +10 -2
- package/src/transport/guards/guard-errors.ts +23 -0
- package/src/transport/guards/headroom-guard.ts +41 -7
- package/src/transport/guards/pipeline.ts +24 -0
- package/src/transport/guards/request-context.ts +2 -1
- package/src/transport/routing/admission.ts +51 -9
- package/src/transport/routing/bounded-lru.ts +49 -0
- package/src/transport/routing/candidate-index.ts +88 -0
- package/src/transport/routing/reservations.ts +121 -7
- package/src/transport/routing/round-robin.ts +10 -22
- package/src/transport/routing/route-catalog.ts +26 -13
- package/src/transport/routing/route-model.ts +22 -2
- package/src/transport/routing/router.ts +53 -31
- package/src/transport/surface/chat/encode.ts +2 -3
- package/src/transport/surface/chat/parse.ts +2 -1
- package/src/transport/surface/dialects.ts +11 -3
- package/src/transport/surface/messages/encode.ts +2 -1
- package/src/transport/surface/messages/parse.ts +3 -1
- package/src/transport/surface/messages/stream.ts +2 -6
- package/src/workers/maintenance-lease.ts +200 -0
- package/src/workers/scheduler.ts +101 -1
- package/dist/dashboard/assets/BannedPage-Brvuj_Eb.js.gz +0 -0
- package/dist/dashboard/assets/CliToolDetailPage-CqfXtI3y.js.gz +0 -0
- package/dist/dashboard/assets/CliToolsPage-GQeS91bg.js.gz +0 -0
- package/dist/dashboard/assets/CombosPage-BDRsTXBB.js.gz +0 -0
- package/dist/dashboard/assets/ConsoleLogPage-zP8AFHX0.js.gz +0 -0
- package/dist/dashboard/assets/CustomizationPage-BmfrNZ14.js.gz +0 -0
- package/dist/dashboard/assets/HealthEventsModal-Dn3M6WZc.js +0 -1
- package/dist/dashboard/assets/HealthEventsModal-Dn3M6WZc.js.gz +0 -0
- package/dist/dashboard/assets/LoginPage-DoreIgm8.js.gz +0 -0
- package/dist/dashboard/assets/ModelPicker-C7pDb41R.js.gz +0 -0
- package/dist/dashboard/assets/OverviewPage-CvvD1Ugk.js +0 -1
- package/dist/dashboard/assets/OverviewPage-CvvD1Ugk.js.gz +0 -0
- package/dist/dashboard/assets/ProviderDetailPage-Clbn1gsW.js +0 -3
- package/dist/dashboard/assets/ProviderDetailPage-Clbn1gsW.js.gz +0 -0
- package/dist/dashboard/assets/ProvidersPage-BnoPgA7w.js.gz +0 -0
- package/dist/dashboard/assets/ProxyPage-Bq_TGgdb.js.gz +0 -0
- package/dist/dashboard/assets/QuotaPage-D9DHXvom.js +0 -1
- package/dist/dashboard/assets/QuotaPage-D9DHXvom.js.gz +0 -0
- package/dist/dashboard/assets/SettingsPage-7xV8WkWL.js +0 -1
- package/dist/dashboard/assets/SettingsPage-7xV8WkWL.js.gz +0 -0
- package/dist/dashboard/assets/SetupPage-Day3mCOn.js.gz +0 -0
- package/dist/dashboard/assets/SortableList-DQxllnB5.js.gz +0 -0
- package/dist/dashboard/assets/UsagePage-DXa1oR-4.js.gz +0 -0
- package/dist/dashboard/assets/api-keys-DQYLQxpW.js.gz +0 -0
- package/dist/dashboard/assets/app-CX_Z8cMs.css +0 -2
- package/dist/dashboard/assets/app-CX_Z8cMs.css.gz +0 -0
- package/dist/dashboard/assets/assert-C9FD_JwJ.js.gz +0 -0
- package/dist/dashboard/assets/badge-CR72dasT.js.gz +0 -0
- package/dist/dashboard/assets/banner-CI9_eSfO.js.gz +0 -0
- package/dist/dashboard/assets/card-DS7CQEsO.js.gz +0 -0
- package/dist/dashboard/assets/cli-tools-CNqzrfdb.js.gz +0 -0
- package/dist/dashboard/assets/clipboard-button-611pSsaX.js.gz +0 -0
- package/dist/dashboard/assets/dialog-k37exjNt.js.gz +0 -0
- package/dist/dashboard/assets/drawer-CX7N8ucR.js.gz +0 -0
- package/dist/dashboard/assets/entry-B9Xvtnfj.js +0 -1
- package/dist/dashboard/assets/entry-B9Xvtnfj.js.gz +0 -0
- package/dist/dashboard/assets/entry-ByMGkR3C.js +0 -4
- package/dist/dashboard/assets/entry-ByMGkR3C.js.gz +0 -0
- package/dist/dashboard/assets/entry-CTP8AyiS.js.gz +0 -0
- package/dist/dashboard/assets/github-badge-sltk1qUi.js.gz +0 -0
- package/dist/dashboard/assets/index-z3zDOSMM.js.gz +0 -0
- package/dist/dashboard/assets/inline-BhY2sSnO.js.gz +0 -0
- package/dist/dashboard/assets/input-V1umFiBk.js.gz +0 -0
- package/dist/dashboard/assets/layout-BBOYycyS.js.gz +0 -0
- package/dist/dashboard/assets/list-row-1zzZYM0B.js.gz +0 -0
- package/dist/dashboard/assets/live-BivGfuUs.js.gz +0 -0
- package/dist/dashboard/assets/model-bans-CmffjLuG.js.gz +0 -0
- package/dist/dashboard/assets/mutation-46P0oWMe.js.gz +0 -0
- package/dist/dashboard/assets/numbers-DkfMR5Qs.js.gz +0 -0
- package/dist/dashboard/assets/query-keys-BFhGpwR1.js.gz +0 -0
- package/dist/dashboard/assets/routing-CAb4F37R.js.gz +0 -0
- package/dist/dashboard/assets/select-C6MMiaio.js.gz +0 -0
- package/dist/dashboard/assets/settings-DNX9sydi.js.gz +0 -0
- package/dist/dashboard/assets/stack-BHTfXdz_.js.gz +0 -0
- package/dist/dashboard/assets/state-mPDRlQkl.js.gz +0 -0
- package/dist/dashboard/assets/switch-DOmJxg7H.js.gz +0 -0
- package/dist/dashboard/assets/useMutation-Dem0lXQj.js.gz +0 -0
- package/scripts/build/aot.ts +0 -143
- package/scripts/build/build.ts +0 -24
- package/scripts/build/compile.ts +0 -88
- package/scripts/build/restart.ts +0 -120
- package/scripts/build/start.ts +0 -25
- package/src/observability/event-compaction.ts +0 -317
- package/src/observability/event-day-index.ts +0 -440
|
@@ -159,8 +159,21 @@ export const TRAE_REALMS: Readonly<Record<TraeRealm, TraeRealmConfig>> = {
|
|
|
159
159
|
modelListSupported: true,
|
|
160
160
|
},
|
|
161
161
|
intl: {
|
|
162
|
-
|
|
163
|
-
|
|
162
|
+
// SG is the primary, not a fallback. Region-routing is a property of the
|
|
163
|
+
// account, not the deployment: an account provisioned into `sg` only
|
|
164
|
+
// authenticates against the SG host, and sending it to the US core answers
|
|
165
|
+
// `1001 "we are not able to authenticate you"`. Accounts with a captured
|
|
166
|
+
// region still resolve to their own host through `TRAE_REGION_CORE_HOSTS`,
|
|
167
|
+
// so moving the default only changes the answer for accounts whose region
|
|
168
|
+
// was never recorded — and SG serves the wider international roster, which
|
|
169
|
+
// makes it the better bet for those than US.
|
|
170
|
+
// Inlined rather than read from `TRAE_REGION_CORE_HOSTS` below: that map is
|
|
171
|
+
// declared after this one, and a `const` forward reference throws at module
|
|
172
|
+
// init. The value must stay identical to `TRAE_REGION_CORE_HOSTS.sg`.
|
|
173
|
+
core: "https://coresg-normal.trae.ai",
|
|
174
|
+
// US stays reachable as a fallback: an account that really is US-provisioned
|
|
175
|
+
// but has no stored region still has to have somewhere to land.
|
|
176
|
+
coreFallbacks: ["https://core-normal.traeapi.us", "https://core-normal.trae.ai"],
|
|
164
177
|
account: "https://grow-normal.trae.ai",
|
|
165
178
|
accountFallbacks: ["https://grow-normal.traeapi.us"],
|
|
166
179
|
pay: "https://grow-normal.traeapi.us",
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
// Trae adapter.
|
|
2
2
|
//
|
|
3
3
|
// Realm-aware: `trae` (intl) and `traecn` (CN) share this code but nothing of
|
|
4
|
-
// the address
|
|
5
|
-
//
|
|
6
|
-
// here comes from `getTraeVersion()` (a live resolver) rather than a constant.
|
|
4
|
+
// the address or the roster. Both realms authenticate with
|
|
5
|
+
// `Authorization: Cloud-IDE-JWT <token>` per the Trae 1.107.1 bundle.
|
|
7
6
|
|
|
8
7
|
import { GatewayError } from "../../../protocol/gateway-error";
|
|
9
8
|
import type { CanonicalEvent, CanonicalRequest, CanonicalStopReason } from "../../../protocol/canonical-model";
|
|
@@ -16,7 +15,6 @@ import {
|
|
|
16
15
|
type ProviderId,
|
|
17
16
|
} from "../../provider-contracts";
|
|
18
17
|
import { mapUpstreamHttpError } from "../../../transport/failure-policy";
|
|
19
|
-
import { getTraeVersion } from "../../operations/client-versions";
|
|
20
18
|
import { abortGatewayError, createUpstreamDeadlineLifecycle } from "../../operations/upstream-deadline";
|
|
21
19
|
import { TRAE_CN_MODELS, TRAE_INTL_MODELS, traeMaxContextWindow } from "./trae-catalog";
|
|
22
20
|
import { buildTraeHeaders } from "./trae-headers";
|
|
@@ -92,14 +90,6 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
92
90
|
readonly provider_id: ProviderId;
|
|
93
91
|
private readonly realm: TraeRealm;
|
|
94
92
|
private readonly fetchFn: typeof fetch;
|
|
95
|
-
/**
|
|
96
|
-
* Maps a frame's `index` to the call id seen for it.
|
|
97
|
-
*
|
|
98
|
-
* Argument fragments arrive without the id, so the association has to be
|
|
99
|
-
* remembered between frames rather than read from the fragment itself.
|
|
100
|
-
*/
|
|
101
|
-
readonly #toolCallIds = new Map<string, string>();
|
|
102
|
-
|
|
103
93
|
constructor(options: TraeAdapterOptions = {}) {
|
|
104
94
|
this.provider_id = (options.providerId ?? TRAE_PROVIDER_ID) as ProviderId;
|
|
105
95
|
this.realm = options.realm ?? "intl";
|
|
@@ -124,9 +114,6 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
124
114
|
const outboundFetch =
|
|
125
115
|
(context.outbound_fetch as unknown as typeof fetch | undefined) ?? this.fetchFn;
|
|
126
116
|
|
|
127
|
-
// intl refuses a stale client version with 4015, so the resolved version is
|
|
128
|
-
// part of every request rather than a startup detail.
|
|
129
|
-
const version = getTraeVersion();
|
|
130
117
|
const auth = traeAuth(secret, context.credential.account_id);
|
|
131
118
|
const body = buildTraeChatBody(modelId, request, this.realm);
|
|
132
119
|
/**
|
|
@@ -144,7 +131,6 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
144
131
|
realm: this.realm,
|
|
145
132
|
token: auth.token,
|
|
146
133
|
uid: auth.uid,
|
|
147
|
-
clientVersion: version,
|
|
148
134
|
stream: true,
|
|
149
135
|
});
|
|
150
136
|
|
|
@@ -192,6 +178,9 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
192
178
|
yield { type: "response_start", sequence_number: seq++, model: requestModel } as CanonicalEvent;
|
|
193
179
|
let stopReason: CanonicalStopReason = "stop";
|
|
194
180
|
let usage: Record<string, unknown> | undefined;
|
|
181
|
+
// Tool ids are scoped to one stream. Argument-only frames from a later
|
|
182
|
+
// request must never inherit an earlier request's id at the same index.
|
|
183
|
+
const toolCallIds = new Map<string, string>();
|
|
195
184
|
/**
|
|
196
185
|
* Tool calls arrive fragmented across frames and the id is not repeated.
|
|
197
186
|
*
|
|
@@ -212,8 +201,12 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
212
201
|
continue;
|
|
213
202
|
}
|
|
214
203
|
if (frame.event === "error") {
|
|
215
|
-
const data = frame.data as { message?: unknown };
|
|
216
|
-
const message = typeof data.message === "string"
|
|
204
|
+
const data = frame.data as { message?: unknown; code?: unknown };
|
|
205
|
+
const message = typeof data.message === "string" && data.message.length > 0
|
|
206
|
+
? data.message
|
|
207
|
+
: typeof data.code === "number" || typeof data.code === "string"
|
|
208
|
+
? `Trae stream error (upstream code ${data.code})`
|
|
209
|
+
: "Trae stream error";
|
|
217
210
|
throw new GatewayError("platform_unavailable", 502, message, {}, "upstream");
|
|
218
211
|
}
|
|
219
212
|
if (typeof frame.data !== "object" || frame.data === null) continue;
|
|
@@ -245,7 +238,7 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
245
238
|
content: { kind: "reasoning", payload: null, summary: flatReasoning },
|
|
246
239
|
} as CanonicalEvent;
|
|
247
240
|
}
|
|
248
|
-
yield* this.#toolCallDeltas(record["tool_calls"], announced, () => seq++);
|
|
241
|
+
yield* this.#toolCallDeltas(record["tool_calls"], announced, toolCallIds, () => seq++);
|
|
249
242
|
if (typeof record["finish_reason"] === "string") {
|
|
250
243
|
stopReason = STOP_REASONS[record["finish_reason"] as string] ?? "stop";
|
|
251
244
|
}
|
|
@@ -277,8 +270,9 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
277
270
|
} as CanonicalEvent;
|
|
278
271
|
}
|
|
279
272
|
if (typeof payload["finish_reason"] === "string") {
|
|
280
|
-
stopReason = STOP_REASONS[payload["finish_reason"]] ?? "stop";
|
|
273
|
+
stopReason = STOP_REASONS[payload["finish_reason"] as string] ?? "stop";
|
|
281
274
|
}
|
|
275
|
+
yield* this.#toolCallDeltas(payload["tool_calls"], announced, toolCallIds, () => seq++);
|
|
282
276
|
if (typeof payload["usage"] === "object" && payload["usage"] !== null) {
|
|
283
277
|
usage = payload["usage"] as Record<string, unknown>;
|
|
284
278
|
}
|
|
@@ -311,6 +305,7 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
311
305
|
async *#toolCallDeltas(
|
|
312
306
|
raw: unknown,
|
|
313
307
|
announced: Set<string>,
|
|
308
|
+
toolCallIds: Map<string, string>,
|
|
314
309
|
nextSeq: () => number,
|
|
315
310
|
): AsyncIterable<CanonicalEvent> {
|
|
316
311
|
if (!Array.isArray(raw)) return;
|
|
@@ -326,7 +321,7 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
326
321
|
const slot = `idx:${index}`;
|
|
327
322
|
|
|
328
323
|
if (declaredId.length > 0) {
|
|
329
|
-
|
|
324
|
+
toolCallIds.set(slot, declaredId);
|
|
330
325
|
// The closing frame repeats a known id with no payload; emitting it
|
|
331
326
|
// again would append a duplicate empty call.
|
|
332
327
|
if (announced.has(declaredId)) continue;
|
|
@@ -338,11 +333,11 @@ class TraeAdapter implements ProviderAdapter {
|
|
|
338
333
|
name: name ?? "",
|
|
339
334
|
arguments_delta: "",
|
|
340
335
|
} as CanonicalEvent;
|
|
341
|
-
continue;
|
|
336
|
+
if (args.length === 0) continue;
|
|
342
337
|
}
|
|
343
338
|
|
|
344
339
|
if (args.length === 0) continue;
|
|
345
|
-
const id =
|
|
340
|
+
const id = toolCallIds.get(slot);
|
|
346
341
|
if (id === undefined) continue;
|
|
347
342
|
yield {
|
|
348
343
|
type: "tool_call_delta",
|
|
@@ -400,7 +395,10 @@ export async function discoverTraeModels(input: {
|
|
|
400
395
|
readonly providerId?: string;
|
|
401
396
|
/** Account region, so the listing is asked of the host that serves it. */
|
|
402
397
|
readonly region?: string;
|
|
403
|
-
}): Promise<readonly {
|
|
398
|
+
}): Promise<readonly {
|
|
399
|
+
id: string;
|
|
400
|
+
ctx: number | undefined;
|
|
401
|
+
}[]> {
|
|
404
402
|
const headers = buildTraeHeaders({
|
|
405
403
|
realm: input.realm,
|
|
406
404
|
token: input.token,
|
|
@@ -39,15 +39,40 @@ const CLOSE_TAGS = ["</thinking>", "</think>"] as const;
|
|
|
39
39
|
* Both case variants pass through: `<Think>` and `<THINK>` survived everyone's
|
|
40
40
|
* normalizer long enough for them not to be the leak this closes.
|
|
41
41
|
*/
|
|
42
|
+
/**
|
|
43
|
+
* Removes visible thinking tags, leaving any that sit inside a code span or
|
|
44
|
+
* fence alone.
|
|
45
|
+
*
|
|
46
|
+
* A tag inside backticks is the *subject* of the answer — documentation or a
|
|
47
|
+
* code sample showing the tag — not markup the upstream leaked, so stripping it
|
|
48
|
+
* would silently rewrite the answer.
|
|
49
|
+
*/
|
|
42
50
|
export function stripThinkingTags(value: string): string {
|
|
43
51
|
if (!value.includes("<")) return value;
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
.
|
|
52
|
+
const pattern = /<think(?:ing)?\b[^>]*>|<\/think(?:ing)?\s*>|`+/g;
|
|
53
|
+
let out = "";
|
|
54
|
+
let last = 0;
|
|
55
|
+
let ticks = 0;
|
|
56
|
+
for (const match of value.matchAll(pattern)) {
|
|
57
|
+
const text = match[0];
|
|
58
|
+
const index = match.index ?? 0;
|
|
59
|
+
if (text.startsWith("`")) {
|
|
60
|
+
// A fence and an inline span are both just "inside code" here: the
|
|
61
|
+
// distinguishing case (a newline closing an unterminated span) cannot
|
|
62
|
+
// affect a tag already indexed in a settled string.
|
|
63
|
+
if (ticks === 0) {
|
|
64
|
+
ticks = text.length;
|
|
65
|
+
} else if (text.length === ticks) {
|
|
66
|
+
ticks = 0;
|
|
67
|
+
}
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
// Inside code: keep the tag verbatim.
|
|
71
|
+
if (ticks > 0) continue;
|
|
72
|
+
out += value.slice(last, index);
|
|
73
|
+
last = index + text.length;
|
|
74
|
+
}
|
|
75
|
+
return out + value.slice(last);
|
|
51
76
|
}
|
|
52
77
|
|
|
53
78
|
/** The longest suffix of `text` that is a proper prefix of any tag. */
|
|
@@ -74,6 +99,14 @@ export interface ThinkSplit {
|
|
|
74
99
|
readonly reasoning: string;
|
|
75
100
|
}
|
|
76
101
|
|
|
102
|
+
/** A tag match plus the code state at the match, so the caller commits it. */
|
|
103
|
+
interface TagMatch {
|
|
104
|
+
readonly index: number;
|
|
105
|
+
readonly length: number;
|
|
106
|
+
readonly codeTicks: number;
|
|
107
|
+
readonly codeFenced: boolean;
|
|
108
|
+
}
|
|
109
|
+
|
|
77
110
|
/**
|
|
78
111
|
* Splits one upstream text chunk into answer text and reasoning text.
|
|
79
112
|
*
|
|
@@ -83,6 +116,14 @@ export interface ThinkSplit {
|
|
|
83
116
|
export class MimoThinkSplitter {
|
|
84
117
|
#buffer = "";
|
|
85
118
|
#inReasoning = false;
|
|
119
|
+
/** Backtick run that opened the code span/fence we are inside; 0 when not in
|
|
120
|
+
* code. A tag inside a code span is the *subject* of the answer — a doc or a
|
|
121
|
+
* code sample mentioning `<think>` — not a delimiter, so it must survive
|
|
122
|
+
* verbatim instead of splitting the stream. */
|
|
123
|
+
#codeTicks = 0;
|
|
124
|
+
/** Whether `#codeTicks` opened a fenced block (closes on its own line) rather
|
|
125
|
+
* than an inline span. */
|
|
126
|
+
#codeFenced = false;
|
|
86
127
|
|
|
87
128
|
/** Feeds a chunk; returns the text/reasoning split for everything settled. */
|
|
88
129
|
push(chunk: string): ThinkSplit {
|
|
@@ -94,14 +135,14 @@ export class MimoThinkSplitter {
|
|
|
94
135
|
if (!this.#inReasoning) {
|
|
95
136
|
const opened = this.#findOpen();
|
|
96
137
|
if (opened === undefined) break;
|
|
97
|
-
text += this.#
|
|
138
|
+
text += this.#consumeUpTo(opened);
|
|
98
139
|
this.#buffer = this.#buffer.slice(opened.index + opened.length);
|
|
99
140
|
this.#inReasoning = true;
|
|
100
141
|
continue;
|
|
101
142
|
}
|
|
102
143
|
const closed = this.#findClose();
|
|
103
144
|
if (closed === undefined) break;
|
|
104
|
-
reasoning += this.#
|
|
145
|
+
reasoning += this.#consumeUpTo(closed);
|
|
105
146
|
this.#buffer = this.#buffer.slice(closed.index + closed.length);
|
|
106
147
|
this.#inReasoning = false;
|
|
107
148
|
}
|
|
@@ -125,29 +166,64 @@ export class MimoThinkSplitter {
|
|
|
125
166
|
flush(): ThinkSplit {
|
|
126
167
|
const rest = this.#buffer;
|
|
127
168
|
this.#buffer = "";
|
|
169
|
+
this.#codeTicks = 0;
|
|
170
|
+
this.#codeFenced = false;
|
|
128
171
|
return this.#inReasoning
|
|
129
172
|
? { text: "", reasoning: rest }
|
|
130
173
|
: { text: stripThinkingTags(rest), reasoning: "" };
|
|
131
174
|
}
|
|
132
175
|
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
176
|
+
/** Returns the text before a tag and commits the code state at it. */
|
|
177
|
+
#consumeUpTo(match: TagMatch): string {
|
|
178
|
+
this.#codeTicks = match.codeTicks;
|
|
179
|
+
this.#codeFenced = match.codeFenced;
|
|
180
|
+
return this.#buffer.slice(0, match.index);
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
#findOpen(): TagMatch | undefined {
|
|
184
|
+
return this.#findTag(OPEN_TAGS);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
#findClose(): TagMatch | undefined {
|
|
188
|
+
return this.#findTag(CLOSE_TAGS);
|
|
141
189
|
}
|
|
142
190
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
191
|
+
/**
|
|
192
|
+
* The earliest occurrence of any of `tags` that is *not* inside a code span
|
|
193
|
+
* or fence, scanning left to right so code state is tracked exactly once per
|
|
194
|
+
* position. Returns the match and the code state at it, so `push` can commit
|
|
195
|
+
* that state when it consumes the tag.
|
|
196
|
+
*/
|
|
197
|
+
#findTag(tags: readonly string[]): TagMatch | undefined {
|
|
198
|
+
const buffer = this.#buffer;
|
|
199
|
+
let ticks = this.#codeTicks;
|
|
200
|
+
let fenced = this.#codeFenced;
|
|
201
|
+
for (let i = 0; i < buffer.length; i++) {
|
|
202
|
+
const char = buffer[i];
|
|
203
|
+
if (char === "`") {
|
|
204
|
+
let run = 1;
|
|
205
|
+
while (buffer[i + run] === "`") run++;
|
|
206
|
+
if (ticks === 0) {
|
|
207
|
+
ticks = run;
|
|
208
|
+
// Three or more backticks open a fence rather than an inline span.
|
|
209
|
+
fenced = run >= 3;
|
|
210
|
+
} else if (run === ticks) {
|
|
211
|
+
ticks = 0;
|
|
212
|
+
fenced = false;
|
|
213
|
+
}
|
|
214
|
+
i += run - 1;
|
|
215
|
+
continue;
|
|
216
|
+
}
|
|
217
|
+
// A newline closes an inline span that never closed on its own line; a
|
|
218
|
+
// fence runs to a closing line instead.
|
|
219
|
+
if (char === "\n" && ticks > 0 && !fenced) ticks = 0;
|
|
220
|
+
if (char !== "<" || ticks > 0) continue;
|
|
221
|
+
for (const tag of tags) {
|
|
222
|
+
if (!buffer.startsWith(tag, i)) continue;
|
|
223
|
+
return { index: i, length: tag.length, codeTicks: ticks, codeFenced: fenced };
|
|
224
|
+
}
|
|
149
225
|
}
|
|
150
|
-
return
|
|
226
|
+
return undefined;
|
|
151
227
|
}
|
|
152
228
|
}
|
|
153
229
|
|