omnigateway 0.9.1 → 0.10.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.
Files changed (34) hide show
  1. package/README.md +12 -4
  2. package/bin/omni.js +1790 -117
  3. package/gateway.js +2437 -244
  4. package/package.json +1 -1
  5. package/public/assets/{Chip-DJkUCwNJ.js → Chip-BeKVtewW.js} +1 -1
  6. package/public/assets/{CopyValue-CJ3ZYgvs.js → CopyValue-NTHhiCuT.js} +1 -1
  7. package/public/assets/{Lamp-D7hJcQ90.js → Lamp-C2Q3t5Mn.js} +1 -1
  8. package/public/assets/{Rack-CaxD9IY1.js → Rack-sUGRoZUx.js} +2 -2
  9. package/public/assets/{RequestTable-bXapHDrR.js → RequestTable-C2RLARWy.js} +1 -1
  10. package/public/assets/{SummaryDeck-Dt_qbFtg.js → SummaryDeck-BHXcb_Ji.js} +1 -1
  11. package/public/assets/{Toggle-C_iC6W50.js → Toggle-DwKz1aVq.js} +1 -1
  12. package/public/assets/{TokenBreakdown-C96x_g6d.js → TokenBreakdown-DM-1HvOr.js} +1 -1
  13. package/public/assets/{WindowChart-D4dcv4DX.js → WindowChart-BsonO5Py.js} +1 -1
  14. package/public/assets/{_app.accounts-CGFOyYZc.js → _app.accounts-DUYxItf0.js} +1 -1
  15. package/public/assets/{_app.console-DrCT8eLd.js → _app.console-BQJMLRv4.js} +1 -1
  16. package/public/assets/{_app.database-D32je-GL.js → _app.database-BIiajZm6.js} +1 -1
  17. package/public/assets/{_app.index-BG6mGxkv.js → _app.index-DagK0Pqp.js} +1 -1
  18. package/public/assets/{_app.keys-C1AjjeHc.js → _app.keys-DLAG_bmt.js} +1 -1
  19. package/public/assets/{_app.logs-BDLj_H_j.js → _app.logs-AyVq3lLb.js} +1 -1
  20. package/public/assets/{_app.models-Cgg7gVSF.js → _app.models-CwlkGPrx.js} +1 -1
  21. package/public/assets/{_app.plugins._pluginId-C5FSNOfN.js → _app.plugins._pluginId-BhvEnawY.js} +1 -1
  22. package/public/assets/{_app.settings-B7lKNDoh.js → _app.settings-BKA-1YLs.js} +1 -1
  23. package/public/assets/{_app.usage-DjqlIHDL.js → _app.usage-C7JEWKZM.js} +1 -1
  24. package/public/assets/{chevron-right-DJj6SEIT.js → chevron-right-S84SGCvk.js} +1 -1
  25. package/public/assets/{client-Q2fvA2EK.js → client-DCvpw0LS.js} +1 -1
  26. package/public/assets/{index-D1ewvjU0.js → index-pZbadEun.js} +3 -3
  27. package/public/assets/{login-Br_AimWR.js → login-CitmheGz.js} +1 -1
  28. package/public/assets/plus-E7qLz9CF.js +1 -0
  29. package/public/assets/{preload-helper-92RRH0nq.js → preload-helper-BC9bKUg1.js} +1 -1
  30. package/public/assets/{shared-Cp_kzH_a.js → shared-C47BfV_u.js} +1 -1
  31. package/public/assets/{trash-2-Chg8CwQf.js → trash-2-DmtElUHr.js} +1 -1
  32. package/public/index.html +4 -4
  33. package/public/shared/dashboard-sdk.js +1 -1
  34. package/public/assets/plus-CCwmaxw3.js +0 -1
package/gateway.js CHANGED
@@ -4687,8 +4687,8 @@ class FileTypeParser {
4687
4687
  if (jsonSize > 12 && this.buffer.length >= jsonSize + 16) {
4688
4688
  try {
4689
4689
  const header = new TextDecoder().decode(this.buffer.subarray(16, jsonSize + 16));
4690
- const json8 = JSON.parse(header);
4691
- if (json8.files) {
4690
+ const json10 = JSON.parse(header);
4691
+ if (json10.files) {
4692
4692
  return {
4693
4693
  ext: "asar",
4694
4694
  mime: "application/x-asar"
@@ -28911,6 +28911,12 @@ var ANTHROPIC_MODELS = {
28911
28911
  defaultModel: "claude-opus-5",
28912
28912
  authTypes: ["oauth", "apiKey"],
28913
28913
  models: [
28914
+ {
28915
+ id: "claude-fable-5-1",
28916
+ label: "Claude Fable 5.1",
28917
+ pricing: { input: 10, output: 50, cacheRead: 0.25, cacheWrite5m: 12.5, cacheWrite1h: 20 },
28918
+ limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
28919
+ },
28914
28920
  {
28915
28921
  id: "claude-fable-5",
28916
28922
  label: "Claude Fable 5",
@@ -28926,7 +28932,7 @@ var ANTHROPIC_MODELS = {
28926
28932
  {
28927
28933
  id: "claude-sonnet-5",
28928
28934
  label: "Claude Sonnet 5",
28929
- pricing: { input: 3, output: 15, cacheRead: 0.3, cacheWrite5m: 3.75, cacheWrite1h: 6 },
28935
+ pricing: { input: 2, output: 10, cacheRead: 0.2, cacheWrite5m: 2.5, cacheWrite1h: 4 },
28930
28936
  limits: { contextWindow: 1e6, maxOutputTokens: 128000 }
28931
28937
  },
28932
28938
  {
@@ -28964,6 +28970,144 @@ var anthropicDescriptor = {
28964
28970
  }
28965
28971
  };
28966
28972
 
28973
+ // packages/providers/src/antigravity/models.ts
28974
+ var MAX_OUTPUT_TOKENS = 65536;
28975
+ var PRO_MAX_OUTPUT_TOKENS = 65535;
28976
+ var FREE = { input: 0, output: 0, cacheRead: 0, cacheWrite5m: 0, cacheWrite1h: 0 };
28977
+ var FLASH_LIMITS = { contextWindow: 1048576, maxOutputTokens: MAX_OUTPUT_TOKENS };
28978
+ var PRO_LIMITS = { contextWindow: 1048576, maxOutputTokens: PRO_MAX_OUTPUT_TOKENS };
28979
+ var ANTIGRAVITY_MODELS = {
28980
+ defaultModel: "gemini-3.8-flash-high",
28981
+ authTypes: ["oauth"],
28982
+ models: [
28983
+ {
28984
+ id: "gemini-3.8-flash-high",
28985
+ label: "Gemini 3.8 Flash (High)",
28986
+ pricing: FREE,
28987
+ limits: FLASH_LIMITS
28988
+ },
28989
+ {
28990
+ id: "gemini-3.8-flash-medium",
28991
+ label: "Gemini 3.8 Flash (Medium)",
28992
+ pricing: FREE,
28993
+ limits: FLASH_LIMITS
28994
+ },
28995
+ {
28996
+ id: "gemini-3.8-flash-low",
28997
+ label: "Gemini 3.8 Flash (Low)",
28998
+ pricing: FREE,
28999
+ limits: FLASH_LIMITS
29000
+ },
29001
+ {
29002
+ id: "gemini-3.7-flash-high",
29003
+ label: "Gemini 3.7 Flash (High)",
29004
+ pricing: FREE,
29005
+ limits: FLASH_LIMITS
29006
+ },
29007
+ {
29008
+ id: "gemini-3.7-flash-medium",
29009
+ label: "Gemini 3.7 Flash (Medium)",
29010
+ pricing: FREE,
29011
+ limits: FLASH_LIMITS
29012
+ },
29013
+ {
29014
+ id: "gemini-3.7-flash-low",
29015
+ label: "Gemini 3.7 Flash (Low)",
29016
+ pricing: FREE,
29017
+ limits: FLASH_LIMITS
29018
+ },
29019
+ {
29020
+ id: "gemini-3.6-flash-high",
29021
+ label: "Gemini 3.6 Flash (High)",
29022
+ pricing: FREE,
29023
+ limits: FLASH_LIMITS
29024
+ },
29025
+ {
29026
+ id: "gemini-3.6-flash-medium",
29027
+ label: "Gemini 3.6 Flash (Medium)",
29028
+ pricing: FREE,
29029
+ limits: FLASH_LIMITS
29030
+ },
29031
+ {
29032
+ id: "gemini-3.6-flash-low",
29033
+ label: "Gemini 3.6 Flash (Low)",
29034
+ pricing: FREE,
29035
+ limits: FLASH_LIMITS
29036
+ },
29037
+ {
29038
+ id: "gemini-3-flash-agent",
29039
+ label: "Gemini 3.5 Flash (High)",
29040
+ pricing: FREE,
29041
+ limits: FLASH_LIMITS
29042
+ },
29043
+ {
29044
+ id: "gemini-3.5-flash-low",
29045
+ label: "Gemini 3.5 Flash (Medium)",
29046
+ pricing: FREE,
29047
+ limits: FLASH_LIMITS
29048
+ },
29049
+ {
29050
+ id: "gemini-3.5-flash-extra-low",
29051
+ label: "Gemini 3.5 Flash (Low)",
29052
+ pricing: FREE,
29053
+ limits: FLASH_LIMITS
29054
+ },
29055
+ {
29056
+ id: "gemini-3-flash",
29057
+ label: "Gemini 3 Flash",
29058
+ pricing: FREE,
29059
+ limits: FLASH_LIMITS
29060
+ },
29061
+ {
29062
+ id: "gemini-3.5-flash-lite",
29063
+ label: "Gemini 3.5 Flash Lite",
29064
+ pricing: FREE,
29065
+ limits: PRO_LIMITS
29066
+ },
29067
+ {
29068
+ id: "gemini-3.1-pro-high",
29069
+ label: "Gemini 3.1 Pro (High)",
29070
+ pricing: FREE,
29071
+ limits: PRO_LIMITS
29072
+ },
29073
+ {
29074
+ id: "gemini-3.1-pro-low",
29075
+ label: "Gemini 3.1 Pro (Low)",
29076
+ pricing: FREE,
29077
+ limits: PRO_LIMITS
29078
+ },
29079
+ {
29080
+ id: "gemini-3.1-flash-lite",
29081
+ label: "Gemini 3.1 Flash Lite",
29082
+ pricing: FREE,
29083
+ limits: PRO_LIMITS
29084
+ },
29085
+ {
29086
+ id: "gemini-2.5-pro",
29087
+ label: "Gemini 2.5 Pro",
29088
+ pricing: FREE,
29089
+ limits: PRO_LIMITS
29090
+ }
29091
+ ]
29092
+ };
29093
+
29094
+ // packages/providers/src/antigravity/descriptor.ts
29095
+ var antigravityDescriptor = {
29096
+ id: "antigravity",
29097
+ capabilities: { tools: true, images: true, reasoning: true },
29098
+ writeOverInput: { fiveMinute: 0, oneHour: 0 },
29099
+ catalog: ANTIGRAVITY_MODELS,
29100
+ modelPrefixes: ["gemini-"],
29101
+ callback: { uri: "http://127.0.0.1:51121/callback", label: "Antigravity" },
29102
+ presentation: {
29103
+ label: "Antigravity",
29104
+ order: 6,
29105
+ tone: "violet",
29106
+ colour: { light: "oklch(0.52 0.14 277)", dark: "oklch(0.74 0.14 277)" },
29107
+ pasteHint: "Approve in a browser on the gateway's own machine \u2014 or SSH-forward port 51121 first. When it redirects to 127.0.0.1, paste the whole URL."
29108
+ }
29109
+ };
29110
+
28967
29111
  // packages/providers/src/custom/models.ts
28968
29112
  var CUSTOM_MODELS = {
28969
29113
  defaultModel: "",
@@ -28980,7 +29124,7 @@ var customDescriptor = {
28980
29124
  modelPrefixes: [],
28981
29125
  presentation: {
28982
29126
  label: "OpenAI Compatible",
28983
- order: 6,
29127
+ order: 8,
28984
29128
  tone: "cyan",
28985
29129
  colour: { light: "oklch(0.5 0.03 258)", dark: "oklch(0.72 0.03 258)" },
28986
29130
  pasteHint: "Enter endpoint metadata and API key."
@@ -29305,35 +29449,90 @@ var kimiDescriptor = {
29305
29449
  }
29306
29450
  };
29307
29451
 
29452
+ // packages/providers/src/muse/models.ts
29453
+ var MUSE_MODELS = {
29454
+ defaultModel: "muse-spark-1.3",
29455
+ authTypes: ["oauth", "apiKey"],
29456
+ models: [
29457
+ {
29458
+ id: "muse-spark-1.3",
29459
+ label: "Muse Spark 1.3",
29460
+ pricing: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite5m: 0, cacheWrite1h: 0 },
29461
+ limits: { contextWindow: 1048576, maxOutputTokens: 943718 }
29462
+ },
29463
+ {
29464
+ id: "muse-spark-1.3-contributor",
29465
+ label: "Muse Spark 1.3 \u2014 Meta trains on this traffic",
29466
+ pricing: { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite5m: 0, cacheWrite1h: 0 },
29467
+ limits: { contextWindow: 1048576, maxOutputTokens: 943718 }
29468
+ },
29469
+ {
29470
+ id: "muse-spark-1.2",
29471
+ label: "Muse Spark 1.2",
29472
+ pricing: { input: 1.25, output: 4.25, cacheRead: 0.15, cacheWrite5m: 0, cacheWrite1h: 0 },
29473
+ limits: { contextWindow: 1048576, maxOutputTokens: 943718 }
29474
+ },
29475
+ {
29476
+ id: "muse-spark-1.2-contributor",
29477
+ label: "Muse Spark 1.2 \u2014 Meta trains on this traffic",
29478
+ pricing: { input: 0.1, output: 0.2, cacheRead: 0.002, cacheWrite5m: 0, cacheWrite1h: 0 },
29479
+ limits: { contextWindow: 1048576, maxOutputTokens: 943718 }
29480
+ }
29481
+ ]
29482
+ };
29483
+
29484
+ // packages/providers/src/muse/descriptor.ts
29485
+ var museDescriptor = {
29486
+ id: "muse",
29487
+ capabilities: { tools: true, images: true, reasoning: true },
29488
+ writeOverInput: { fiveMinute: 0, oneHour: 0 },
29489
+ catalog: MUSE_MODELS,
29490
+ modelPrefixes: ["muse-", "muse-spark"],
29491
+ presentation: {
29492
+ label: "Muse",
29493
+ order: 7,
29494
+ tone: "azure",
29495
+ colour: { light: "oklch(0.55 0.23 262)", dark: "oklch(0.72 0.17 262)" },
29496
+ pasteHint: "Enter the code on Meta's device page. This dialog finishes on its own."
29497
+ }
29498
+ };
29499
+
29308
29500
  // packages/providers/src/openai/models.ts
29309
29501
  var OPENAI_MODELS = {
29310
29502
  defaultModel: "gpt-5.6",
29311
29503
  authTypes: ["oauth", "apiKey"],
29312
29504
  models: [
29505
+ {
29506
+ id: "gpt-6-astra",
29507
+ label: "GPT-6 Astra",
29508
+ pricing: { input: 10, output: 50, cacheRead: 1, cacheWrite5m: 0, cacheWrite1h: 0 },
29509
+ limits: { contextWindow: 922000, maxOutputTokens: 128000 },
29510
+ oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
29511
+ },
29313
29512
  {
29314
29513
  id: "gpt-5.6",
29315
29514
  label: "GPT-5.6 \u2014 routes to Sol",
29316
- pricing: { input: 5, output: 30, cacheRead: 0.5, cacheWrite5m: 0, cacheWrite1h: 0 },
29515
+ pricing: { input: 4, output: 20, cacheRead: 0.4, cacheWrite5m: 0, cacheWrite1h: 0 },
29317
29516
  limits: { contextWindow: 922000, maxOutputTokens: 128000 },
29318
29517
  oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
29319
29518
  },
29320
29519
  {
29321
29520
  id: "gpt-5.6-sol",
29322
- label: "GPT-5.6 Sol \u2014 deepest reasoning",
29323
- pricing: { input: 5, output: 30, cacheRead: 0.5, cacheWrite5m: 0, cacheWrite1h: 0 },
29521
+ label: "GPT-5.6 Sol",
29522
+ pricing: { input: 4, output: 20, cacheRead: 0.4, cacheWrite5m: 0, cacheWrite1h: 0 },
29324
29523
  limits: { contextWindow: 922000, maxOutputTokens: 128000 },
29325
29524
  oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
29326
29525
  },
29327
29526
  {
29328
29527
  id: "gpt-5.6-terra",
29329
- label: "GPT-5.6 Terra \u2014 balanced",
29528
+ label: "GPT-5.6 Terra",
29330
29529
  pricing: { input: 2, output: 12, cacheRead: 0.2, cacheWrite5m: 0, cacheWrite1h: 0 },
29331
29530
  limits: { contextWindow: 922000, maxOutputTokens: 128000 },
29332
29531
  oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
29333
29532
  },
29334
29533
  {
29335
29534
  id: "gpt-5.6-luna",
29336
- label: "GPT-5.6 Luna \u2014 fastest",
29535
+ label: "GPT-5.6 Luna",
29337
29536
  pricing: { input: 0.2, output: 1.2, cacheRead: 0.02, cacheWrite5m: 0, cacheWrite1h: 0 },
29338
29537
  limits: { contextWindow: 922000, maxOutputTokens: 128000 },
29339
29538
  oauthLimits: { contextWindow: 272000, maxOutputTokens: 128000 }
@@ -29371,6 +29570,8 @@ var PROVIDER_DESCRIPTORS = {
29371
29570
  kimi: kimiDescriptor,
29372
29571
  kilo: kiloDescriptor,
29373
29572
  grok: grokDescriptor,
29573
+ antigravity: antigravityDescriptor,
29574
+ muse: museDescriptor,
29374
29575
  custom: customDescriptor
29375
29576
  };
29376
29577
  Object.setPrototypeOf(PROVIDER_DESCRIPTORS, null);
@@ -29520,6 +29721,19 @@ function loadConfig(env) {
29520
29721
  const bodyLoggingAllowed = TRUTHY.has((env.OMNI_BODY_LOGGING_ALLOWED ?? "").trim().toLowerCase());
29521
29722
  const rawLogLevel = env.OMNI_LOG_LEVEL?.trim();
29522
29723
  const logLevel = parseLogLevel(rawLogLevel);
29724
+ const metricsToken = env.OMNI_METRICS_TOKEN?.trim() || null;
29725
+ const rawMaxSeries = env.OMNI_METRICS_MAX_SERIES ?? "5000";
29726
+ const metricsMaxSeries = Number(rawMaxSeries);
29727
+ if (!DECIMAL_INTEGER.test(rawMaxSeries) || metricsMaxSeries < 1) {
29728
+ throw new Error(`OMNI_METRICS_MAX_SERIES must be a positive integer, got "${rawMaxSeries}"`);
29729
+ }
29730
+ const otlpEndpoint = env.OMNI_OTLP_ENDPOINT?.trim().replace(/\/+$/, "") || null;
29731
+ const otlpHeaders = env.OMNI_OTLP_HEADERS?.trim() || null;
29732
+ const rawTraceSample = env.OMNI_TRACE_SAMPLE ?? "1.0";
29733
+ const traceSample = Number(rawTraceSample);
29734
+ if (!Number.isFinite(traceSample) || traceSample < 0 || traceSample > 1) {
29735
+ throw new Error(`OMNI_TRACE_SAMPLE must be between 0 and 1, got "${rawTraceSample}"`);
29736
+ }
29523
29737
  return {
29524
29738
  logLevel: logLevel ?? "info",
29525
29739
  logLevelFallbackFrom: logLevel === null && rawLogLevel ? rawLogLevel : null,
@@ -29533,7 +29747,12 @@ function loadConfig(env) {
29533
29747
  logFile: logFile === undefined || logFile.length === 0 ? null : logFile,
29534
29748
  clusterMode,
29535
29749
  databaseUrl: clusterMode ? databaseUrl ?? null : null,
29536
- redisUrl: clusterMode ? redisUrl ?? null : null
29750
+ redisUrl: clusterMode ? redisUrl ?? null : null,
29751
+ metricsToken,
29752
+ metricsMaxSeries,
29753
+ otlpEndpoint,
29754
+ otlpHeaders,
29755
+ traceSample
29537
29756
  };
29538
29757
  }
29539
29758
  // packages/control/src/oauth/pending.ts
@@ -29732,7 +29951,8 @@ function codecAdapter(id, capabilities2, codec2, origins) {
29732
29951
  const res = await req.http({
29733
29952
  provider: id,
29734
29953
  ...sendable,
29735
- signal: req.signal
29954
+ signal: req.signal,
29955
+ ...req.requestId === undefined ? {} : { requestId: req.requestId }
29736
29956
  });
29737
29957
  if (res.status < 200 || res.status >= 300) {
29738
29958
  const text = await res.text().catch(() => "");
@@ -29890,6 +30110,38 @@ var anthropicBodyOrder = [
29890
30110
  "stream"
29891
30111
  ];
29892
30112
 
30113
+ // packages/providers/src/antigravity/profile.ts
30114
+ var ANTIGRAVITY_IDE_VERSION = env("OMNI_ANTIGRAVITY_IDE_VERSION", "2.12.2");
30115
+ var PLATFORM = "darwin/arm64";
30116
+ var antigravityProfile = {
30117
+ headers: [
30118
+ [
30119
+ "User-Agent",
30120
+ env("OMNI_UA_ANTIGRAVITY", `antigravity/ide/${ANTIGRAVITY_IDE_VERSION} ${PLATFORM}`)
30121
+ ],
30122
+ ["Content-Type", "application/json"],
30123
+ ["Accept", "text/event-stream"]
30124
+ ],
30125
+ order: envOrder("OMNI_ORDER_ANTIGRAVITY", [
30126
+ "Host",
30127
+ "Content-Type",
30128
+ "Authorization",
30129
+ "User-Agent",
30130
+ "X-Goog-Api-Client",
30131
+ "Accept",
30132
+ "Accept-Encoding",
30133
+ "Content-Length"
30134
+ ])
30135
+ };
30136
+ var antigravityBodyOrder = [
30137
+ "project",
30138
+ "requestId",
30139
+ "model",
30140
+ "userAgent",
30141
+ "requestType",
30142
+ "request"
30143
+ ];
30144
+
29893
30145
  // packages/providers/src/custom/profile.ts
29894
30146
  var customProfile = { headers: [], order: [] };
29895
30147
  var customBodyOrder = [];
@@ -30011,6 +30263,43 @@ var kimiBodyOrder = [
30011
30263
  "stream"
30012
30264
  ];
30013
30265
 
30266
+ // packages/providers/src/muse/profile.ts
30267
+ var MUSE_CLI_VERSION = env("OMNI_MUSE_CLI_VERSION", "1.0.3");
30268
+ var museProfile = {
30269
+ headers: [
30270
+ ["User-Agent", env("OMNI_UA_MUSE", `muse-code/${MUSE_CLI_VERSION}`)],
30271
+ ["x-api-version", env("OMNI_MUSE_API_VERSION", "1.0.0")],
30272
+ ["Accept", "text/event-stream"]
30273
+ ],
30274
+ order: envOrder("OMNI_ORDER_MUSE", [
30275
+ "Host",
30276
+ "Content-Type",
30277
+ "Authorization",
30278
+ "x-meta-ai-gateway-session-id",
30279
+ "x-api-version",
30280
+ "Accept",
30281
+ "User-Agent",
30282
+ "Accept-Encoding",
30283
+ "Content-Length"
30284
+ ])
30285
+ };
30286
+ var museBodyOrder = [
30287
+ "model",
30288
+ "stream",
30289
+ "input",
30290
+ "instructions",
30291
+ "store",
30292
+ "reasoning",
30293
+ "prompt_cache_key",
30294
+ "max_output_tokens",
30295
+ "temperature",
30296
+ "tools",
30297
+ "tool_choice",
30298
+ "include",
30299
+ "parallel_tool_calls",
30300
+ "metadata"
30301
+ ];
30302
+
30014
30303
  // packages/providers/src/openai/profile.ts
30015
30304
  var OPENAI_CLI_VERSION = env("OMNI_OPENAI_CLI_VERSION", "0.144.1");
30016
30305
  var OPENAI_UA_PLATFORM = env("OMNI_OPENAI_UA_PLATFORM", "Windows 10.0.26200");
@@ -30067,6 +30356,8 @@ var BODY_ORDER = {
30067
30356
  kimi: kimiBodyOrder,
30068
30357
  kilo: kiloBodyOrder,
30069
30358
  grok: grokBodyOrder,
30359
+ antigravity: antigravityBodyOrder,
30360
+ muse: museBodyOrder,
30070
30361
  custom: customBodyOrder
30071
30362
  };
30072
30363
  Object.setPrototypeOf(BODY_ORDER, null);
@@ -30160,6 +30451,8 @@ var PROVIDER_MODEL_CATALOG = {
30160
30451
  kimi: KIMI_MODELS,
30161
30452
  kilo: KILO_MODELS,
30162
30453
  grok: GROK_MODELS,
30454
+ antigravity: ANTIGRAVITY_MODELS,
30455
+ muse: MUSE_MODELS,
30163
30456
  custom: CUSTOM_MODELS
30164
30457
  };
30165
30458
  Object.setPrototypeOf(PROVIDER_MODEL_CATALOG, null);
@@ -30190,6 +30483,8 @@ var PROFILES = {
30190
30483
  kimi: kimiProfile,
30191
30484
  kilo: kiloProfile,
30192
30485
  grok: grokProfile,
30486
+ antigravity: antigravityProfile,
30487
+ muse: museProfile,
30193
30488
  custom: customProfile
30194
30489
  };
30195
30490
  Object.setPrototypeOf(PROFILES, null);
@@ -31474,6 +31769,751 @@ var anthropicOAuthFlow = {
31474
31769
  return parseAnthropicUsage(parsed(res.body), now());
31475
31770
  }
31476
31771
  };
31772
+ // packages/providers/src/antigravity/codec.ts
31773
+ import { createHash as createHash2 } from "crypto";
31774
+
31775
+ // packages/providers/src/antigravity/decode.ts
31776
+ var STOP_REASON2 = {
31777
+ STOP: "endTurn",
31778
+ MAX_TOKENS: "maxTokens",
31779
+ SAFETY: "contentFilter",
31780
+ PROHIBITED_CONTENT: "contentFilter",
31781
+ SPII: "contentFilter",
31782
+ BLOCKLIST: "contentFilter",
31783
+ RECITATION: "contentFilter"
31784
+ };
31785
+ var ERROR_CODE = {
31786
+ RESOURCE_EXHAUSTED: "RATE_LIMIT",
31787
+ UNAUTHENTICATED: "AUTH",
31788
+ PERMISSION_DENIED: "AUTH",
31789
+ INVALID_ARGUMENT: "BAD_REQUEST",
31790
+ FAILED_PRECONDITION: "BAD_REQUEST",
31791
+ UNAVAILABLE: "UPSTREAM",
31792
+ INTERNAL: "UPSTREAM",
31793
+ DEADLINE_EXCEEDED: "TIMEOUT"
31794
+ };
31795
+ function json3(data) {
31796
+ try {
31797
+ const value = JSON.parse(data);
31798
+ return typeof value === "object" && value !== null ? value : null;
31799
+ } catch {
31800
+ return null;
31801
+ }
31802
+ }
31803
+ function count(value) {
31804
+ return typeof value === "number" && Number.isFinite(value) ? value : 0;
31805
+ }
31806
+ function usageOf(meta3) {
31807
+ return usageFromPromptTotal(count(meta3?.promptTokenCount), count(meta3?.candidatesTokenCount) + count(meta3?.thoughtsTokenCount), count(meta3?.cachedContentTokenCount));
31808
+ }
31809
+ async function* decodeAntigravityStream(messages) {
31810
+ let started = false;
31811
+ let terminal = false;
31812
+ let nextIndex = 0;
31813
+ let toolCalls = 0;
31814
+ let open2 = null;
31815
+ const closeOpen = function* () {
31816
+ if (open2 === null)
31817
+ return;
31818
+ yield { type: "blockEnd", index: open2.index };
31819
+ open2 = null;
31820
+ };
31821
+ for await (const message of messages) {
31822
+ if (message.data === "[DONE]")
31823
+ continue;
31824
+ const frame = json3(message.data);
31825
+ if (frame === null)
31826
+ continue;
31827
+ const failure = frame.error ?? frame.response?.error;
31828
+ if (failure !== undefined) {
31829
+ terminal = true;
31830
+ yield* closeOpen();
31831
+ const status = String(failure.status ?? "");
31832
+ const code = (Object.hasOwn(ERROR_CODE, status) ? ERROR_CODE[status] : undefined) ?? "UPSTREAM";
31833
+ yield {
31834
+ type: "error",
31835
+ code,
31836
+ message: String(failure.message ?? "upstream error"),
31837
+ retryable: RETRYABLE[code]
31838
+ };
31839
+ return;
31840
+ }
31841
+ const response = frame.response;
31842
+ if (response === undefined)
31843
+ continue;
31844
+ const blocked = response.promptFeedback?.blockReason;
31845
+ if (blocked !== undefined && (response.candidates ?? []).length === 0) {
31846
+ terminal = true;
31847
+ if (!started)
31848
+ yield { type: "start", id: "", model: "" };
31849
+ yield* closeOpen();
31850
+ yield { type: "end", stopReason: "contentFilter", usage: usageOf(response.usageMetadata) };
31851
+ return;
31852
+ }
31853
+ if (!started) {
31854
+ started = true;
31855
+ yield {
31856
+ type: "start",
31857
+ id: String(response.responseId ?? ""),
31858
+ model: String(response.modelVersion ?? "")
31859
+ };
31860
+ }
31861
+ const candidates = response.candidates ?? [];
31862
+ if (candidates.length > 1) {
31863
+ terminal = true;
31864
+ yield* closeOpen();
31865
+ yield {
31866
+ type: "error",
31867
+ code: "UPSTREAM",
31868
+ message: `Antigravity returned ${candidates.length} candidates, which cannot be represented`,
31869
+ retryable: false
31870
+ };
31871
+ return;
31872
+ }
31873
+ const candidate = candidates[0];
31874
+ for (const part of candidate?.content?.parts ?? []) {
31875
+ const call = part.functionCall;
31876
+ if (call !== undefined && typeof call.name === "string") {
31877
+ yield* closeOpen();
31878
+ const index = nextIndex++;
31879
+ yield {
31880
+ type: "blockStart",
31881
+ index,
31882
+ block: {
31883
+ type: "toolUse",
31884
+ id: typeof call.id === "string" && call.id.length > 0 ? call.id : `fc_${toolCalls}`,
31885
+ name: call.name
31886
+ }
31887
+ };
31888
+ yield {
31889
+ type: "blockDelta",
31890
+ index,
31891
+ delta: { type: "toolJson", partial: JSON.stringify(call.args ?? {}) }
31892
+ };
31893
+ yield { type: "blockEnd", index };
31894
+ toolCalls++;
31895
+ continue;
31896
+ }
31897
+ if (typeof part.text !== "string")
31898
+ continue;
31899
+ const kind = part.thought === true ? "thinking" : "text";
31900
+ if (open2 === null || open2.kind !== kind) {
31901
+ yield* closeOpen();
31902
+ open2 = { kind, index: nextIndex++ };
31903
+ yield { type: "blockStart", index: open2.index, block: { type: kind } };
31904
+ }
31905
+ yield {
31906
+ type: "blockDelta",
31907
+ index: open2.index,
31908
+ delta: kind === "thinking" ? { type: "thinking", text: part.text } : { type: "text", text: part.text }
31909
+ };
31910
+ }
31911
+ const finish = candidate?.finishReason;
31912
+ if (finish === undefined || finish === null)
31913
+ continue;
31914
+ terminal = true;
31915
+ yield* closeOpen();
31916
+ const raw = String(finish);
31917
+ if (raw === "MALFORMED_FUNCTION_CALL") {
31918
+ yield {
31919
+ type: "error",
31920
+ code: "BAD_REQUEST",
31921
+ message: "the model emitted a malformed function call",
31922
+ retryable: false
31923
+ };
31924
+ return;
31925
+ }
31926
+ const mapped = Object.hasOwn(STOP_REASON2, raw) ? STOP_REASON2[raw] : undefined;
31927
+ if (mapped === undefined) {
31928
+ yield {
31929
+ type: "error",
31930
+ code: "UPSTREAM",
31931
+ message: `unrecognized Antigravity finish reason "${raw}"`,
31932
+ retryable: false
31933
+ };
31934
+ return;
31935
+ }
31936
+ yield {
31937
+ type: "end",
31938
+ stopReason: toolCalls > 0 ? "toolUse" : mapped,
31939
+ usage: usageOf(response.usageMetadata)
31940
+ };
31941
+ return;
31942
+ }
31943
+ if (!terminal) {
31944
+ yield* closeOpen();
31945
+ yield {
31946
+ type: "error",
31947
+ code: "UPSTREAM",
31948
+ message: "upstream stream ended before the response finished",
31949
+ retryable: RETRYABLE.UPSTREAM
31950
+ };
31951
+ }
31952
+ }
31953
+
31954
+ // packages/providers/src/antigravity/wire.ts
31955
+ var SIGNATURE_BYPASS = "skip_thought_signature_validator";
31956
+ function toolNamesById(req) {
31957
+ const names = new Map;
31958
+ for (const message of req.messages) {
31959
+ for (const block of message.content) {
31960
+ if (block.type === "toolUse")
31961
+ names.set(block.id, block.name);
31962
+ }
31963
+ }
31964
+ return names;
31965
+ }
31966
+ function mergeSameRole(contents) {
31967
+ const merged = [];
31968
+ for (const entry of contents) {
31969
+ const last = merged[merged.length - 1];
31970
+ if (last !== undefined && last.role === entry.role)
31971
+ last.parts.push(...entry.parts);
31972
+ else
31973
+ merged.push({ role: entry.role, parts: [...entry.parts] });
31974
+ }
31975
+ return merged;
31976
+ }
31977
+ var hasCacheControl = (block) => ("cacheControl" in block) && block.cacheControl !== undefined;
31978
+ function encodeToolChoice2(choice) {
31979
+ switch (choice.type) {
31980
+ case "auto":
31981
+ return { functionCallingConfig: { mode: "AUTO" } };
31982
+ case "any":
31983
+ return { functionCallingConfig: { mode: "ANY" } };
31984
+ case "none":
31985
+ return { functionCallingConfig: { mode: "NONE" } };
31986
+ case "tool":
31987
+ return { functionCallingConfig: { mode: "ANY", allowedFunctionNames: [choice.name] } };
31988
+ }
31989
+ }
31990
+ function toAntigravityWire(req, model, identity) {
31991
+ const degradations = [];
31992
+ const note = (d) => {
31993
+ if (!degradations.includes(d))
31994
+ degradations.push(d);
31995
+ };
31996
+ const names = toolNamesById(req);
31997
+ const contents = [];
31998
+ for (const message of req.messages) {
31999
+ const parts = [];
32000
+ if (message.role === "system")
32001
+ note("antigravity:system-turn-as-user");
32002
+ let role = message.role === "assistant" ? "model" : "user";
32003
+ for (const block of message.content) {
32004
+ if (hasCacheControl(block))
32005
+ note("antigravity:cache-control-dropped");
32006
+ switch (block.type) {
32007
+ case "text":
32008
+ parts.push({ text: block.text });
32009
+ break;
32010
+ case "image":
32011
+ parts.push({ inlineData: { mimeType: block.mediaType, data: block.data } });
32012
+ break;
32013
+ case "thinking":
32014
+ note("antigravity:thinking-dropped");
32015
+ break;
32016
+ case "toolUse":
32017
+ parts.push({
32018
+ thoughtSignature: SIGNATURE_BYPASS,
32019
+ functionCall: { name: block.name, args: block.input }
32020
+ });
32021
+ break;
32022
+ case "toolResult": {
32023
+ const name = names.get(block.toolUseId);
32024
+ if (name === undefined)
32025
+ note("antigravity:tool-result-unmatched");
32026
+ if (block.isError === true)
32027
+ note("antigravity:tool-result-error-flag-dropped");
32028
+ parts.push({
32029
+ functionResponse: {
32030
+ name: name ?? block.toolUseId,
32031
+ response: { output: block.content }
32032
+ }
32033
+ });
32034
+ role = "user";
32035
+ break;
32036
+ }
32037
+ case "providerNative":
32038
+ note("antigravity:provider-native-block-dropped");
32039
+ break;
32040
+ }
32041
+ }
32042
+ if (parts.length > 0)
32043
+ contents.push({ role, parts });
32044
+ }
32045
+ const request2 = { contents: mergeSameRole(contents) };
32046
+ const system = systemText(req.system, "antigravity", note);
32047
+ if (system !== undefined && system.length > 0) {
32048
+ request2.systemInstruction = { parts: [{ text: system }] };
32049
+ }
32050
+ const generationConfig = {};
32051
+ if (req.maxTokens !== undefined)
32052
+ generationConfig.maxOutputTokens = req.maxTokens;
32053
+ if (req.temperature !== undefined)
32054
+ generationConfig.temperature = req.temperature;
32055
+ if (req.stopSequences !== undefined)
32056
+ generationConfig.stopSequences = req.stopSequences;
32057
+ if (req.reasoning !== undefined) {
32058
+ switch (req.reasoning.mode) {
32059
+ case "off":
32060
+ generationConfig.thinkingConfig = { thinkingBudget: 0, includeThoughts: false };
32061
+ break;
32062
+ case "budget":
32063
+ generationConfig.thinkingConfig = {
32064
+ thinkingBudget: req.reasoning.budgetTokens,
32065
+ includeThoughts: req.reasoning.budgetTokens !== 0
32066
+ };
32067
+ break;
32068
+ case "adaptive":
32069
+ generationConfig.thinkingConfig = {
32070
+ includeThoughts: req.reasoning.display !== "omitted"
32071
+ };
32072
+ if (req.reasoning.effort !== undefined)
32073
+ note("antigravity:reasoning-effort-dropped");
32074
+ break;
32075
+ }
32076
+ }
32077
+ const max = generationConfig.maxOutputTokens;
32078
+ if (max !== undefined && max > MAX_OUTPUT_TOKENS) {
32079
+ generationConfig.maxOutputTokens = MAX_OUTPUT_TOKENS;
32080
+ note("antigravity:max-tokens-clamped");
32081
+ }
32082
+ const budget = generationConfig.thinkingConfig?.thinkingBudget;
32083
+ if (budget !== undefined && budget > 0) {
32084
+ const ceiling = generationConfig.maxOutputTokens;
32085
+ if (ceiling === undefined || ceiling <= budget) {
32086
+ generationConfig.maxOutputTokens = Math.min(budget + 1, MAX_OUTPUT_TOKENS);
32087
+ }
32088
+ }
32089
+ if (Object.keys(generationConfig).length > 0)
32090
+ request2.generationConfig = generationConfig;
32091
+ if (req.tools !== undefined) {
32092
+ const portable = req.tools.filter((t) => t.kind === "portable");
32093
+ if (portable.length !== req.tools.length)
32094
+ note("antigravity:provider-tool-dropped");
32095
+ if (portable.length > 0) {
32096
+ request2.tools = [
32097
+ {
32098
+ functionDeclarations: portable.map((t) => ({
32099
+ name: t.name,
32100
+ description: t.description,
32101
+ parameters: t.inputSchema
32102
+ }))
32103
+ }
32104
+ ];
32105
+ }
32106
+ }
32107
+ if (req.toolChoice !== undefined)
32108
+ request2.toolConfig = encodeToolChoice2(req.toolChoice);
32109
+ Object.assign(request2, req.vendor?.antigravity ?? {});
32110
+ return {
32111
+ body: {
32112
+ project: identity.project,
32113
+ requestId: identity.requestId,
32114
+ model,
32115
+ userAgent: "antigravity",
32116
+ requestType: "agent",
32117
+ request: request2
32118
+ },
32119
+ degradations
32120
+ };
32121
+ }
32122
+
32123
+ // packages/providers/src/antigravity/codec.ts
32124
+ var URL2 = "https://daily-cloudcode-pa.googleapis.com/v1internal:streamGenerateContent?alt=sse";
32125
+ var REQUEST_NAMESPACE = "omni-antigravity-req";
32126
+ function derivedRequestId(seed) {
32127
+ const h = createHash2("sha256").update(`${REQUEST_NAMESPACE}:${seed}`).digest("hex");
32128
+ const variant = (Number.parseInt(h[16], 16) & 3 | 8).toString(16);
32129
+ return [
32130
+ h.slice(0, 8),
32131
+ h.slice(8, 12),
32132
+ `4${h.slice(13, 16)}`,
32133
+ `${variant}${h.slice(17, 20)}`,
32134
+ h.slice(20, 32)
32135
+ ].join("-");
32136
+ }
32137
+ function projectOf(input2) {
32138
+ const stored = input2.credentials.providerData.projectId;
32139
+ const project = typeof stored === "string" ? stored.trim() : "";
32140
+ if (project.length === 0) {
32141
+ throw input2.fail("AUTH", "antigravity credential has no Cloud Code project; reconnect the account");
32142
+ }
32143
+ return project;
32144
+ }
32145
+ var antigravityCodec = {
32146
+ buildRequest(input2) {
32147
+ const accessToken = input2.credentials.accessToken;
32148
+ if (accessToken === null || accessToken.length === 0) {
32149
+ throw input2.fail("AUTH", "antigravity credential has no access token");
32150
+ }
32151
+ const project = projectOf(input2);
32152
+ const requestId = input2.requestId !== undefined && input2.requestId.length > 0 ? input2.requestId : derivedRequestId(`${input2.model}:${project}`);
32153
+ const { body, degradations } = toAntigravityWire(input2.request, input2.model, {
32154
+ project,
32155
+ requestId
32156
+ });
32157
+ const protocol = [["Authorization", `Bearer ${accessToken}`]];
32158
+ const headers = orderHeaders(mergeHeaders(antigravityProfile.headers, protocol), antigravityProfile.order);
32159
+ return {
32160
+ request: {
32161
+ url: URL2,
32162
+ method: "POST",
32163
+ headers,
32164
+ body: JSON.stringify(body)
32165
+ },
32166
+ degradations
32167
+ };
32168
+ },
32169
+ decode({ body }) {
32170
+ return decodeAntigravityStream(parseSse(body));
32171
+ }
32172
+ };
32173
+
32174
+ // packages/providers/src/antigravity/index.ts
32175
+ var antigravityAdapter = codecAdapter("antigravity", antigravityDescriptor.capabilities, antigravityCodec);
32176
+ // packages/providers/src/antigravity/oauth.ts
32177
+ var MASK = "omnigateway-public-v1";
32178
+ function unmask(bytes) {
32179
+ let out = "";
32180
+ for (let i = 0;i < bytes.length; i++) {
32181
+ out += String.fromCharCode(bytes[i] ^ MASK.charCodeAt(i % MASK.length));
32182
+ }
32183
+ return out;
32184
+ }
32185
+ var ANTIGRAVITY_CLIENT_ID = unmask([
32186
+ 94,
32187
+ 93,
32188
+ 89,
32189
+ 88,
32190
+ 87,
32191
+ 81,
32192
+ 66,
32193
+ 85,
32194
+ 65,
32195
+ 81,
32196
+ 76,
32197
+ 20,
32198
+ 65,
32199
+ 88,
32200
+ 22,
32201
+ 1,
32202
+ 1,
32203
+ 16,
32204
+ 94,
32205
+ 31,
32206
+ 95,
32207
+ 93,
32208
+ 5,
32209
+ 92,
32210
+ 88,
32211
+ 11,
32212
+ 2,
32213
+ 6,
32214
+ 0,
32215
+ 69,
32216
+ 82,
32217
+ 76,
32218
+ 91,
32219
+ 4,
32220
+ 26,
32221
+ 14,
32222
+ 3,
32223
+ 3,
32224
+ 11,
32225
+ 25,
32226
+ 17,
32227
+ 5,
32228
+ 95,
32229
+ 94,
32230
+ 11,
32231
+ 25,
32232
+ 73,
32233
+ 0,
32234
+ 4,
32235
+ 21,
32236
+ 4,
32237
+ 79,
32238
+ 30,
32239
+ 66,
32240
+ 31,
32241
+ 18,
32242
+ 14,
32243
+ 9,
32244
+ 28,
32245
+ 16,
32246
+ 72,
32247
+ 4,
32248
+ 82,
32249
+ 0,
32250
+ 3,
32251
+ 26,
32252
+ 12,
32253
+ 9,
32254
+ 21,
32255
+ 90,
32256
+ 6,
32257
+ 24,
32258
+ 12
32259
+ ]);
32260
+ var CLIENT_ID2 = ANTIGRAVITY_CLIENT_ID;
32261
+ var CLIENT_SECRET = unmask([
32262
+ 40,
32263
+ 34,
32264
+ 45,
32265
+ 58,
32266
+ 55,
32267
+ 57,
32268
+ 89,
32269
+ 46,
32270
+ 66,
32271
+ 89,
32272
+ 63,
32273
+ 122,
32274
+ 34,
32275
+ 65,
32276
+ 90,
32277
+ 90,
32278
+ 37,
32279
+ 7,
32280
+ 97,
32281
+ 60,
32282
+ 0,
32283
+ 2,
32284
+ 33,
32285
+ 44,
32286
+ 81,
32287
+ 20,
32288
+ 57,
32289
+ 55,
32290
+ 81,
32291
+ 13,
32292
+ 87,
32293
+ 8,
32294
+ 105,
32295
+ 49,
32296
+ 19
32297
+ ]);
32298
+ var AUTHORIZE_URL2 = "https://accounts.google.com/o/oauth2/v2/auth";
32299
+ var TOKEN_URL2 = "https://oauth2.googleapis.com/token";
32300
+ var USERINFO_URL = "https://www.googleapis.com/oauth2/v1/userinfo?alt=json";
32301
+ var CODE_ASSIST = "https://cloudcode-pa.googleapis.com/v1internal";
32302
+ var LOAD_CODE_ASSIST_URL = `${CODE_ASSIST}:loadCodeAssist`;
32303
+ var ONBOARD_USER_URL = `${CODE_ASSIST}:onboardUser`;
32304
+ var QUOTA_SUMMARY_URL = `${CODE_ASSIST}:retrieveUserQuotaSummary`;
32305
+ var SCOPES2 = [
32306
+ "https://www.googleapis.com/auth/cloud-platform",
32307
+ "https://www.googleapis.com/auth/userinfo.email",
32308
+ "https://www.googleapis.com/auth/userinfo.profile",
32309
+ "https://www.googleapis.com/auth/cclog",
32310
+ "https://www.googleapis.com/auth/experimentsandconfigs"
32311
+ ].join(" ");
32312
+ var IDE_METADATA = { ideType: "ANTIGRAVITY" };
32313
+ var DEFAULT_TIER = "legacy-tier";
32314
+ function parseTokenResponse(value) {
32315
+ const record2 = recordOf(value);
32316
+ if (record2 === null || typeof record2.access_token !== "string")
32317
+ return null;
32318
+ return {
32319
+ accessToken: record2.access_token,
32320
+ refreshToken: typeof record2.refresh_token === "string" ? record2.refresh_token : null,
32321
+ expiresIn: typeof record2.expires_in === "number" ? record2.expires_in : null
32322
+ };
32323
+ }
32324
+ async function* postToken2(body, fail) {
32325
+ const res = yield postJsonRequest(TOKEN_URL2, antigravityProfile, {
32326
+ contentType: "application/x-www-form-urlencoded",
32327
+ body: new URLSearchParams(body).toString()
32328
+ });
32329
+ const parsed2 = parsed(res.body);
32330
+ if (res.status < 200 || res.status >= 300) {
32331
+ throw fail(tokenErrorCode(res.status), tokenErrorMessage(res.status, parsed2));
32332
+ }
32333
+ const token = parseTokenResponse(parsed2);
32334
+ if (token === null)
32335
+ throw fail("AUTH", "token endpoint returned no access_token");
32336
+ return token;
32337
+ }
32338
+ function projectFrom(value) {
32339
+ const record2 = recordOf(value);
32340
+ if (record2 === null)
32341
+ return "";
32342
+ const project = record2.cloudaicompanionProject;
32343
+ if (typeof project === "string")
32344
+ return project.trim();
32345
+ const nested = recordOf(project);
32346
+ const id = nested?.id;
32347
+ return typeof id === "string" ? id.trim() : "";
32348
+ }
32349
+ function tierFrom(value) {
32350
+ const record2 = recordOf(value);
32351
+ const tiers = record2?.allowedTiers;
32352
+ if (Array.isArray(tiers)) {
32353
+ for (const entry of tiers) {
32354
+ const tier = recordOf(entry);
32355
+ if (tier?.isDefault === true && typeof tier.id === "string")
32356
+ return tier.id;
32357
+ }
32358
+ }
32359
+ const current = recordOf(record2?.currentTier);
32360
+ return typeof current?.id === "string" ? current.id : DEFAULT_TIER;
32361
+ }
32362
+ function codeAssistRequest(url2, accessToken, body) {
32363
+ return postJsonRequest(url2, antigravityProfile, {
32364
+ contentType: "application/json",
32365
+ body: JSON.stringify(body),
32366
+ extraHeaders: [["Authorization", `Bearer ${accessToken}`]]
32367
+ });
32368
+ }
32369
+ async function* bootstrapProject(accessToken) {
32370
+ const loaded = yield codeAssistRequest(LOAD_CODE_ASSIST_URL, accessToken, {
32371
+ metadata: IDE_METADATA
32372
+ });
32373
+ const body = loaded.status >= 200 && loaded.status < 300 ? parsed(loaded.body) : null;
32374
+ const tier = tierFrom(body);
32375
+ const existing = projectFrom(body);
32376
+ if (existing.length > 0)
32377
+ return { projectId: existing, tier };
32378
+ const onboarded = yield codeAssistRequest(ONBOARD_USER_URL, accessToken, {
32379
+ tier_id: tier,
32380
+ metadata: IDE_METADATA
32381
+ });
32382
+ if (onboarded.status < 200 || onboarded.status >= 300)
32383
+ return { projectId: "", tier };
32384
+ const operation = recordOf(parsed(onboarded.body));
32385
+ return { projectId: projectFrom(operation?.response), tier };
32386
+ }
32387
+ async function* readEmail(accessToken) {
32388
+ const res = yield getJsonRequest(USERINFO_URL, antigravityProfile, { accessToken });
32389
+ if (res.status < 200 || res.status >= 300)
32390
+ return null;
32391
+ const record2 = recordOf(parsed(res.body));
32392
+ const email3 = record2?.email;
32393
+ return typeof email3 === "string" && email3.trim().length > 0 ? email3 : null;
32394
+ }
32395
+ function toResult2(token, fallbackRefresh, accountEmail, providerData, now) {
32396
+ return {
32397
+ secrets: {
32398
+ accessToken: token.accessToken,
32399
+ refreshToken: token.refreshToken ?? fallbackRefresh,
32400
+ apiKey: null,
32401
+ idToken: null
32402
+ },
32403
+ expiresAt: token.expiresIn === null ? null : now() + token.expiresIn * 1000,
32404
+ accountEmail,
32405
+ providerData
32406
+ };
32407
+ }
32408
+ var GEMINI_GROUP = /\bgemini\b/;
32409
+ function windowOf(bucket) {
32410
+ const text = `${String(bucket.bucketId ?? "")} ${String(bucket.displayName ?? "")}`.toLowerCase();
32411
+ if (/\bweekly\b|\bweek\b/.test(text))
32412
+ return "weekly";
32413
+ if (/\b5\s*-?\s*hour|\b5h\b|\bfive\s*hour/.test(text))
32414
+ return "fiveHour";
32415
+ return null;
32416
+ }
32417
+ function groupsOf(value) {
32418
+ const root = recordOf(value);
32419
+ if (root === null)
32420
+ return [];
32421
+ if (Array.isArray(root.groups))
32422
+ return root.groups;
32423
+ const nested = recordOf(root.quotaSummary)?.groups;
32424
+ return Array.isArray(nested) ? nested : [];
32425
+ }
32426
+ function parseAntigravityQuota(value, now) {
32427
+ const windows = [];
32428
+ for (const groupValue of groupsOf(value)) {
32429
+ const group = recordOf(groupValue);
32430
+ if (group === null)
32431
+ continue;
32432
+ if (!GEMINI_GROUP.test(String(group.displayName ?? "").toLowerCase()))
32433
+ continue;
32434
+ const buckets = Array.isArray(group.buckets) ? group.buckets : [];
32435
+ for (const bucketValue of buckets) {
32436
+ const bucket = recordOf(bucketValue);
32437
+ if (bucket === null || bucket.disabled === true)
32438
+ continue;
32439
+ const windowType = windowOf(bucket);
32440
+ if (windowType === null)
32441
+ continue;
32442
+ const fraction = numberOf(bucket, ["remainingFraction"]);
32443
+ if (fraction === null)
32444
+ continue;
32445
+ const remaining = Math.max(0, Math.min(1, fraction));
32446
+ windows.push({
32447
+ windowType,
32448
+ used: Math.round((1 - remaining) * 100),
32449
+ limit: 100,
32450
+ resetsAt: resetAtOf(bucket, { absolute: ["resetTime"] }, now),
32451
+ windowMs: null
32452
+ });
32453
+ }
32454
+ }
32455
+ return reportFrom(windows);
32456
+ }
32457
+ var antigravityOAuthFlow = {
32458
+ kind: "pkce",
32459
+ supportsManualPaste: true,
32460
+ async* start({ redirectUri, randomState }) {
32461
+ const state = randomState();
32462
+ const url2 = new URL(AUTHORIZE_URL2);
32463
+ url2.searchParams.set("client_id", CLIENT_ID2);
32464
+ url2.searchParams.set("response_type", "code");
32465
+ url2.searchParams.set("redirect_uri", redirectUri);
32466
+ url2.searchParams.set("scope", SCOPES2);
32467
+ url2.searchParams.set("state", state);
32468
+ url2.searchParams.set("access_type", "offline");
32469
+ url2.searchParams.set("prompt", "consent");
32470
+ return {
32471
+ authorizeUrl: url2.toString(),
32472
+ pending: { verifier: "", challenge: "", state, redirectUri }
32473
+ };
32474
+ },
32475
+ async* exchange({ code, pending, fail, now }) {
32476
+ const [rawCode, pastedState] = code.split("#");
32477
+ if (pastedState !== undefined && pastedState !== pending.state) {
32478
+ throw fail("AUTH", "authorization state mismatch");
32479
+ }
32480
+ const token = yield* postToken2({
32481
+ grant_type: "authorization_code",
32482
+ client_id: CLIENT_ID2,
32483
+ client_secret: CLIENT_SECRET,
32484
+ code: (rawCode ?? "").trim(),
32485
+ redirect_uri: pending.redirectUri
32486
+ }, fail);
32487
+ const email3 = yield* readEmail(token.accessToken);
32488
+ const { projectId, tier } = yield* bootstrapProject(token.accessToken);
32489
+ return toResult2(token, null, email3, { projectId, tier }, now);
32490
+ },
32491
+ async* refresh({ refreshToken, providerData, fail, now }) {
32492
+ const token = yield* postToken2({
32493
+ grant_type: "refresh_token",
32494
+ client_id: CLIENT_ID2,
32495
+ client_secret: CLIENT_SECRET,
32496
+ refresh_token: refreshToken
32497
+ }, fail);
32498
+ return toResult2(token, refreshToken, null, providerData, now);
32499
+ },
32500
+ async* usage({ secrets, providerData, now }) {
32501
+ const project = typeof providerData.projectId === "string" ? providerData.projectId : "";
32502
+ if (project.trim().length === 0)
32503
+ return null;
32504
+ const res = yield {
32505
+ ...postJsonRequest(QUOTA_SUMMARY_URL, antigravityProfile, {
32506
+ contentType: "application/json",
32507
+ body: JSON.stringify({ project }),
32508
+ extraHeaders: [["Authorization", `Bearer ${secrets.accessToken}`]]
32509
+ }),
32510
+ timeoutMs: SHORT_TIMEOUT_MS
32511
+ };
32512
+ if (!usageReadable(res.status, "antigravity"))
32513
+ return null;
32514
+ return parseAntigravityQuota(parsed(res.body), now());
32515
+ }
32516
+ };
31477
32517
  // packages/providers/src/grok/device.ts
31478
32518
  import { randomUUID } from "crypto";
31479
32519
  function mintGrokDevice() {
@@ -31487,10 +32527,10 @@ function grokDeviceHeaders(providerData) {
31487
32527
  }
31488
32528
 
31489
32529
  // packages/providers/src/grok/oauth.ts
31490
- var CLIENT_ID2 = "b1a00492-073a-47ea-816f-4c329264a828";
32530
+ var CLIENT_ID3 = "b1a00492-073a-47ea-816f-4c329264a828";
31491
32531
  var ISSUER = "https://auth.x.ai";
31492
32532
  var DISCOVERY_URL = `${ISSUER}/.well-known/openid-configuration`;
31493
- var SCOPES2 = [
32533
+ var SCOPES3 = [
31494
32534
  "openid",
31495
32535
  "profile",
31496
32536
  "email",
@@ -31536,7 +32576,7 @@ async function* discover(fail) {
31536
32576
  tokenUrl: trustedEndpoint(parsed2.token_endpoint, "token_endpoint", fail)
31537
32577
  };
31538
32578
  }
31539
- function parseTokenResponse(value) {
32579
+ function parseTokenResponse2(value) {
31540
32580
  if (!isRecord2(value) || typeof value.access_token !== "string")
31541
32581
  return null;
31542
32582
  return {
@@ -31552,15 +32592,15 @@ function emailFromIdToken(idToken) {
31552
32592
  if (parts.length !== 3 || payload === undefined || payload.length === 0)
31553
32593
  return null;
31554
32594
  try {
31555
- const json3 = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
31556
- if (!isRecord2(json3))
32595
+ const json4 = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
32596
+ if (!isRecord2(json4))
31557
32597
  return null;
31558
- return typeof json3.email === "string" && json3.email.trim().length > 0 ? json3.email : null;
32598
+ return typeof json4.email === "string" && json4.email.trim().length > 0 ? json4.email : null;
31559
32599
  } catch {
31560
32600
  return null;
31561
32601
  }
31562
32602
  }
31563
- async function* postToken2(tokenUrl, body, fail) {
32603
+ async function* postToken3(tokenUrl, body, fail) {
31564
32604
  const res = yield postJsonRequest(tokenUrl, grokProfile, {
31565
32605
  contentType: "application/x-www-form-urlencoded",
31566
32606
  body: new URLSearchParams(body).toString()
@@ -31569,7 +32609,7 @@ async function* postToken2(tokenUrl, body, fail) {
31569
32609
  if (res.status < 200 || res.status >= 300) {
31570
32610
  throw fail(tokenErrorCode(res.status), tokenErrorMessage(res.status, parsed2));
31571
32611
  }
31572
- const token = parseTokenResponse(parsed2);
32612
+ const token = parseTokenResponse2(parsed2);
31573
32613
  if (token === null) {
31574
32614
  throw fail("AUTH", "token endpoint returned no access_token");
31575
32615
  }
@@ -31579,7 +32619,7 @@ function agentIdFrom(providerData) {
31579
32619
  const stored = providerData.agentId;
31580
32620
  return typeof stored === "string" && stored.trim().length > 0 ? stored : mintGrokDevice().agentId;
31581
32621
  }
31582
- function toResult2(token, fallbackRefresh, agentId, now) {
32622
+ function toResult3(token, fallbackRefresh, agentId, now) {
31583
32623
  return {
31584
32624
  secrets: {
31585
32625
  accessToken: token.accessToken,
@@ -31601,9 +32641,9 @@ var grokOAuthFlow = {
31601
32641
  const state = randomState();
31602
32642
  const url2 = new URL(authorizeUrl);
31603
32643
  url2.searchParams.set("response_type", "code");
31604
- url2.searchParams.set("client_id", CLIENT_ID2);
32644
+ url2.searchParams.set("client_id", CLIENT_ID3);
31605
32645
  url2.searchParams.set("redirect_uri", redirectUri);
31606
- url2.searchParams.set("scope", SCOPES2);
32646
+ url2.searchParams.set("scope", SCOPES3);
31607
32647
  url2.searchParams.set("code_challenge", challenge);
31608
32648
  url2.searchParams.set("code_challenge_method", "S256");
31609
32649
  url2.searchParams.set("state", state);
@@ -31617,19 +32657,19 @@ var grokOAuthFlow = {
31617
32657
  throw fail("AUTH", "authorization state mismatch");
31618
32658
  }
31619
32659
  const { tokenUrl } = yield* discover(fail);
31620
- const token = yield* postToken2(tokenUrl, {
32660
+ const token = yield* postToken3(tokenUrl, {
31621
32661
  grant_type: "authorization_code",
31622
32662
  code: (rawCode ?? "").trim(),
31623
32663
  redirect_uri: pending.redirectUri,
31624
- client_id: CLIENT_ID2,
32664
+ client_id: CLIENT_ID3,
31625
32665
  code_verifier: pending.verifier
31626
32666
  }, fail);
31627
- return toResult2(token, null, mintGrokDevice().agentId, now);
32667
+ return toResult3(token, null, mintGrokDevice().agentId, now);
31628
32668
  },
31629
32669
  async* refresh({ refreshToken, providerData, fail, now }) {
31630
32670
  const { tokenUrl } = yield* discover(fail);
31631
- const token = yield* postToken2(tokenUrl, { grant_type: "refresh_token", client_id: CLIENT_ID2, refresh_token: refreshToken }, fail);
31632
- return toResult2(token, refreshToken, agentIdFrom(providerData), now);
32671
+ const token = yield* postToken3(tokenUrl, { grant_type: "refresh_token", client_id: CLIENT_ID3, refresh_token: refreshToken }, fail);
32672
+ return toResult3(token, refreshToken, agentIdFrom(providerData), now);
31633
32673
  }
31634
32674
  };
31635
32675
 
@@ -31789,9 +32829,9 @@ function kimiDeviceHeaders(providerData) {
31789
32829
  }
31790
32830
 
31791
32831
  // packages/providers/src/kimi/oauth.ts
31792
- var CLIENT_ID3 = "17e5f671-d194-4dfb-9706-5516cb48c098";
32832
+ var CLIENT_ID4 = "17e5f671-d194-4dfb-9706-5516cb48c098";
31793
32833
  var DEVICE_CODE_URL = "https://auth.kimi.com/api/oauth/device_authorization";
31794
- var TOKEN_URL2 = "https://auth.kimi.com/api/oauth/token";
32834
+ var TOKEN_URL3 = "https://auth.kimi.com/api/oauth/token";
31795
32835
  var USAGE_URL2 = "https://api.kimi.com/coding/v1/usages";
31796
32836
  var DEFAULT_INTERVAL_SECONDS = 5;
31797
32837
  var PENDING_ERRORS = new Set(["authorization_pending", "slow_down"]);
@@ -31845,7 +32885,7 @@ function deviceCodeFrom2(value, fail) {
31845
32885
  async function* post(url2, body, device, fail, keepPolling) {
31846
32886
  const res = yield postJsonRequest(url2, kimiProfile, {
31847
32887
  contentType: "application/x-www-form-urlencoded",
31848
- body: new URLSearchParams({ ...body, client_id: CLIENT_ID3 }).toString(),
32888
+ body: new URLSearchParams({ ...body, client_id: CLIENT_ID4 }).toString(),
31849
32889
  extraHeaders: kimiDeviceHeaders(device)
31850
32890
  });
31851
32891
  const parsed2 = parsed(res.body);
@@ -31876,7 +32916,7 @@ function deviceFrom(source) {
31876
32916
  function deviceForBegin(deviceId) {
31877
32917
  return { ...mintKimiDevice(), deviceId };
31878
32918
  }
31879
- function toResult3(token, device, fallbackRefresh, now) {
32919
+ function toResult4(token, device, fallbackRefresh, now) {
31880
32920
  return {
31881
32921
  secrets: {
31882
32922
  accessToken: token.accessToken,
@@ -31931,17 +32971,17 @@ var kimiOAuthFlow = {
31931
32971
  throw fail("INTERNAL", "kimi exchange requires a pending flow produced by begin()");
31932
32972
  }
31933
32973
  const device = deviceFrom(pending.extra);
31934
- const token = tokenFrom(yield* post(TOKEN_URL2, {
32974
+ const token = tokenFrom(yield* post(TOKEN_URL3, {
31935
32975
  grant_type: "urn:ietf:params:oauth:grant-type:device_code",
31936
32976
  device_code: pending.deviceCode,
31937
32977
  device_id: device.deviceId
31938
32978
  }, device, fail, keepPolling), fail);
31939
- return toResult3(token, device, null, now);
32979
+ return toResult4(token, device, null, now);
31940
32980
  },
31941
32981
  async* refresh({ refreshToken, providerData, fail, keepPolling, now }) {
31942
32982
  const device = deviceFrom(providerData);
31943
- const token = tokenFrom(yield* post(TOKEN_URL2, { grant_type: "refresh_token", refresh_token: refreshToken, device_id: device.deviceId }, device, fail, keepPolling), fail);
31944
- return toResult3(token, device, refreshToken, now);
32983
+ const token = tokenFrom(yield* post(TOKEN_URL3, { grant_type: "refresh_token", refresh_token: refreshToken, device_id: device.deviceId }, device, fail, keepPolling), fail);
32984
+ return toResult4(token, device, refreshToken, now);
31945
32985
  },
31946
32986
  async* usage({ secrets, providerData, now }) {
31947
32987
  if (secrets.accessToken === null)
@@ -31957,13 +32997,225 @@ var kimiOAuthFlow = {
31957
32997
  }
31958
32998
  };
31959
32999
 
33000
+ // packages/providers/src/muse/endpoint.ts
33001
+ var TRUSTED_HOST2 = "meta.ai";
33002
+ var MUSE_DEFAULT_BASE_URL = "https://api.meta.ai/v1";
33003
+ function trustedBaseUrl(value) {
33004
+ if (typeof value !== "string" || value.length === 0)
33005
+ return null;
33006
+ let url2;
33007
+ try {
33008
+ url2 = new URL(value);
33009
+ } catch {
33010
+ return null;
33011
+ }
33012
+ if (url2.protocol !== "https:")
33013
+ return null;
33014
+ const host2 = url2.hostname;
33015
+ if (host2 !== TRUSTED_HOST2 && !host2.endsWith(`.${TRUSTED_HOST2}`))
33016
+ return null;
33017
+ return `${url2.origin}${url2.pathname}`.replace(/\/$/, "");
33018
+ }
33019
+ function museResponsesUrl(providerData) {
33020
+ return `${trustedBaseUrl(providerData.baseUrl) ?? MUSE_DEFAULT_BASE_URL}/responses`;
33021
+ }
33022
+
33023
+ // packages/providers/src/muse/oauth.ts
33024
+ var AUTH_BASE = "https://auth.meta.com";
33025
+ var DEVICE_CODE_URL2 = `${AUTH_BASE}/oidc/device/authorization/`;
33026
+ var TOKEN_URL4 = `${AUTH_BASE}/oidc/device/token/`;
33027
+ var MINT_URL = "https://api.meta.ai/muse-code/key";
33028
+ var CLIENT_ID5 = "1031625952748946";
33029
+ var DEVICE_CODE_GRANT = "urn:ietf:params:oauth:grant-type:device_code";
33030
+ var FALLBACK_VERIFICATION_URL2 = "https://auth.meta.com/oauth/device/";
33031
+ var DEFAULT_INTERVAL_SECONDS2 = 5;
33032
+ var PENDING_ERRORS2 = new Set(["authorization_pending", "slow_down"]);
33033
+ function isRecord5(value) {
33034
+ return typeof value === "object" && value !== null;
33035
+ }
33036
+ function recordFrom3(value) {
33037
+ return isRecord5(value) ? value : null;
33038
+ }
33039
+ function stringFrom3(value, field) {
33040
+ const candidate = value[field];
33041
+ return typeof candidate === "string" && candidate.trim().length > 0 ? candidate : null;
33042
+ }
33043
+ function positiveNumberFrom3(value, field) {
33044
+ const candidate = value[field];
33045
+ return typeof candidate === "number" && Number.isFinite(candidate) && candidate > 0 ? candidate : null;
33046
+ }
33047
+ function tokenFrom2(value, fail) {
33048
+ const record2 = recordFrom3(value);
33049
+ const accessToken = record2 === null ? null : stringFrom3(record2, "access_token");
33050
+ if (record2 === null || accessToken === null) {
33051
+ throw fail("AUTH", "token endpoint returned no access_token");
33052
+ }
33053
+ return {
33054
+ accessToken,
33055
+ refreshToken: stringFrom3(record2, "refresh_token"),
33056
+ expiresIn: positiveNumberFrom3(record2, "expires_in")
33057
+ };
33058
+ }
33059
+ function deviceCodeFrom3(value, fail) {
33060
+ const record2 = recordFrom3(value);
33061
+ const deviceCode = record2 === null ? null : stringFrom3(record2, "device_code");
33062
+ const userCode = record2 === null ? null : stringFrom3(record2, "user_code");
33063
+ if (record2 === null || deviceCode === null || userCode === null) {
33064
+ throw fail("AUTH", "device authorization response missing user_code or verification_uri");
33065
+ }
33066
+ return {
33067
+ deviceCode,
33068
+ userCode,
33069
+ verificationUri: stringFrom3(record2, "verification_uri_complete") ?? stringFrom3(record2, "verification_uri") ?? FALLBACK_VERIFICATION_URL2,
33070
+ interval: positiveNumberFrom3(record2, "interval") ?? DEFAULT_INTERVAL_SECONDS2
33071
+ };
33072
+ }
33073
+ async function* postForm(url2, body, fail, keepPolling) {
33074
+ const res = yield postJsonRequest(url2, museProfile, {
33075
+ contentType: "application/x-www-form-urlencoded",
33076
+ body: new URLSearchParams({ ...body, client_id: CLIENT_ID5 }).toString(),
33077
+ extraHeaders: [["Accept", "application/json"]]
33078
+ });
33079
+ const parsed2 = parsed(res.body);
33080
+ if (res.status >= 200 && res.status < 300)
33081
+ return parsed2;
33082
+ const record2 = recordFrom3(parsed2);
33083
+ const code = record2 === null ? `http_${res.status}` : stringFrom3(record2, "error") ?? `http_${res.status}`;
33084
+ if (PENDING_ERRORS2.has(code))
33085
+ throw keepPolling(code);
33086
+ if (code === "expired_token") {
33087
+ throw fail("AUTH", "muse device code expired; start the authorization again");
33088
+ }
33089
+ throw fail(tokenErrorCode(res.status), tokenErrorMessage(res.status, parsed2));
33090
+ }
33091
+ async function* mint(accessToken, fail) {
33092
+ const res = yield postJsonRequest(MINT_URL, museProfile, {
33093
+ contentType: "application/json",
33094
+ body: "{}",
33095
+ extraHeaders: [
33096
+ ["Authorization", `Bearer ${accessToken}`],
33097
+ ["Accept", "application/json"]
33098
+ ]
33099
+ });
33100
+ const parsed2 = parsed(res.body);
33101
+ if (res.status < 200 || res.status >= 300) {
33102
+ if (res.status === 401 || res.status === 403) {
33103
+ throw fail("AUTH", "muse rejected the saved login; reconnect the account or use a different one");
33104
+ }
33105
+ if (res.status === 429) {
33106
+ throw fail("RATE_LIMIT", `muse rate limited the key mint: http_${res.status}`);
33107
+ }
33108
+ throw fail("UPSTREAM", `muse key mint failed: http_${res.status}`);
33109
+ }
33110
+ const record2 = recordFrom3(parsed2);
33111
+ if (record2 === null) {
33112
+ throw fail("UPSTREAM", "muse key mint returned an unusable response");
33113
+ }
33114
+ if (record2.require_payment === true) {
33115
+ throw fail("AUTH", "muse requires a payment method on the Meta account; add one at https://dev.meta.ai and reconnect");
33116
+ }
33117
+ const apiKey = stringFrom3(record2, "api_key");
33118
+ if (apiKey === null) {
33119
+ throw fail("AUTH", "muse key mint returned an empty api key; finish onboarding at https://dev.meta.ai and reconnect");
33120
+ }
33121
+ return {
33122
+ apiKey,
33123
+ email: stringFrom3(record2, "user_email"),
33124
+ tierName: stringFrom3(record2, "subs_tier_name"),
33125
+ subscriptionActive: record2.is_subs_active === true,
33126
+ baseUrl: trustedBaseUrl(record2.base_url),
33127
+ usage: record2.subs_usage
33128
+ };
33129
+ }
33130
+ function toResult5(token, key, fallbackRefresh, now) {
33131
+ return {
33132
+ secrets: {
33133
+ accessToken: token.accessToken,
33134
+ refreshToken: token.refreshToken ?? fallbackRefresh,
33135
+ apiKey: key.apiKey,
33136
+ idToken: null
33137
+ },
33138
+ expiresAt: token.expiresIn === null ? null : now() + token.expiresIn * 1000,
33139
+ accountEmail: key.email,
33140
+ providerData: {
33141
+ ...key.tierName === null ? {} : { subscriptionTier: key.tierName },
33142
+ subscriptionActive: key.subscriptionActive,
33143
+ ...key.baseUrl === null ? {} : { baseUrl: key.baseUrl }
33144
+ }
33145
+ };
33146
+ }
33147
+ var museOAuthFlow = {
33148
+ kind: "device",
33149
+ supportsManualPaste: false,
33150
+ needsDeviceId: false,
33151
+ async* start() {
33152
+ return {
33153
+ authorizeUrl: FALLBACK_VERIFICATION_URL2,
33154
+ pending: { verifier: "", challenge: "", state: "", redirectUri: "" }
33155
+ };
33156
+ },
33157
+ async* begin({ fail, keepPolling }) {
33158
+ const response = deviceCodeFrom3(yield* postForm(DEVICE_CODE_URL2, {}, fail, keepPolling), fail);
33159
+ return {
33160
+ authorizeUrl: response.verificationUri,
33161
+ userCode: response.userCode,
33162
+ pending: {
33163
+ verifier: "",
33164
+ challenge: "",
33165
+ state: "",
33166
+ redirectUri: "",
33167
+ deviceCode: response.deviceCode,
33168
+ interval: response.interval
33169
+ }
33170
+ };
33171
+ },
33172
+ async* exchange({ pending, fail, keepPolling, now }) {
33173
+ if (pending.deviceCode === undefined) {
33174
+ throw fail("INTERNAL", "muse exchange requires a pending flow produced by begin()");
33175
+ }
33176
+ const token = tokenFrom2(yield* postForm(TOKEN_URL4, { grant_type: DEVICE_CODE_GRANT, device_code: pending.deviceCode }, fail, keepPolling), fail);
33177
+ return toResult5(token, yield* mint(token.accessToken, fail), null, now);
33178
+ },
33179
+ async* refresh({ refreshToken, fail, keepPolling, now }) {
33180
+ const token = tokenFrom2(yield* postForm(TOKEN_URL4, { grant_type: "refresh_token", refresh_token: refreshToken }, fail, keepPolling), fail);
33181
+ return toResult5(token, yield* mint(token.accessToken, fail), refreshToken, now);
33182
+ },
33183
+ async* usage({ secrets, now }) {
33184
+ if (secrets.accessToken === null)
33185
+ return null;
33186
+ const res = yield postJsonRequest(MINT_URL, museProfile, {
33187
+ contentType: "application/json",
33188
+ body: "{}",
33189
+ extraHeaders: [
33190
+ ["Authorization", `Bearer ${secrets.accessToken}`],
33191
+ ["Accept", "application/json"]
33192
+ ]
33193
+ });
33194
+ if (!usageReadable(res.status, "muse"))
33195
+ return null;
33196
+ const record2 = recordOf(parsed(res.body));
33197
+ return record2 === null ? null : parseMuseUsage(record2.subs_usage, now());
33198
+ }
33199
+ };
33200
+ function parseMuseUsage(value, now) {
33201
+ const root = recordOf(value);
33202
+ if (root === null)
33203
+ return null;
33204
+ const window2 = recordOf(root.window);
33205
+ const mins = window2 === null ? null : numberOf(window2, ["window_duration_mins"]);
33206
+ return reportFrom([
33207
+ windowFrom(root.window, "fiveHour", now, mins === null ? null : mins * 60000),
33208
+ windowFrom(root.weekly, "weekly", now)
33209
+ ]);
33210
+ }
33211
+
31960
33212
  // packages/providers/src/openai/oauth.ts
31961
- var CLIENT_ID4 = "app_EMoamEEZ73f0CkXaXp7hrann";
31962
- var AUTHORIZE_URL2 = "https://auth.openai.com/oauth/authorize";
31963
- var TOKEN_URL3 = "https://auth.openai.com/oauth/token";
31964
- var SCOPES3 = "openid profile email offline_access";
33213
+ var CLIENT_ID6 = "app_EMoamEEZ73f0CkXaXp7hrann";
33214
+ var AUTHORIZE_URL3 = "https://auth.openai.com/oauth/authorize";
33215
+ var TOKEN_URL5 = "https://auth.openai.com/oauth/token";
33216
+ var SCOPES4 = "openid profile email offline_access";
31965
33217
  var USAGE_URL3 = "https://chatgpt.com/backend-api/wham/usage";
31966
- function isRecord5(value) {
33218
+ function isRecord6(value) {
31967
33219
  return typeof value === "object" && value !== null;
31968
33220
  }
31969
33221
  function nonBlankStringOrNull(value) {
@@ -31979,20 +33231,20 @@ function decodeClaims(idToken) {
31979
33231
  return { email: null, accountId: null };
31980
33232
  }
31981
33233
  try {
31982
- const json3 = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
31983
- if (!isRecord5(json3))
33234
+ const json4 = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
33235
+ if (!isRecord6(json4))
31984
33236
  return { email: null, accountId: null };
31985
- const auth = json3["https://api.openai.com/auth"];
33237
+ const auth = json4["https://api.openai.com/auth"];
31986
33238
  return {
31987
- email: typeof json3.email === "string" ? json3.email : null,
31988
- accountId: isRecord5(auth) ? nonBlankStringOrNull(auth.chatgpt_account_id) : null
33239
+ email: typeof json4.email === "string" ? json4.email : null,
33240
+ accountId: isRecord6(auth) ? nonBlankStringOrNull(auth.chatgpt_account_id) : null
31989
33241
  };
31990
33242
  } catch {
31991
33243
  return { email: null, accountId: null };
31992
33244
  }
31993
33245
  }
31994
- function parseTokenResponse2(value) {
31995
- if (!isRecord5(value) || typeof value.access_token !== "string")
33246
+ function parseTokenResponse3(value) {
33247
+ if (!isRecord6(value) || typeof value.access_token !== "string")
31996
33248
  return null;
31997
33249
  return {
31998
33250
  accessToken: value.access_token,
@@ -32001,22 +33253,22 @@ function parseTokenResponse2(value) {
32001
33253
  idToken: typeof value.id_token === "string" ? value.id_token : null
32002
33254
  };
32003
33255
  }
32004
- async function* postToken3(body, fail) {
32005
- const res = yield postJsonRequest(TOKEN_URL3, openaiProfile, {
33256
+ async function* postToken4(body, fail) {
33257
+ const res = yield postJsonRequest(TOKEN_URL5, openaiProfile, {
32006
33258
  contentType: "application/x-www-form-urlencoded",
32007
- body: new URLSearchParams({ ...body, client_id: CLIENT_ID4 }).toString()
33259
+ body: new URLSearchParams({ ...body, client_id: CLIENT_ID6 }).toString()
32008
33260
  });
32009
33261
  const parsed2 = parsed(res.body);
32010
33262
  if (res.status < 200 || res.status >= 300) {
32011
33263
  throw fail(tokenErrorCode(res.status), tokenErrorMessage(res.status, parsed2));
32012
33264
  }
32013
- const token = parseTokenResponse2(parsed2);
33265
+ const token = parseTokenResponse3(parsed2);
32014
33266
  if (token === null) {
32015
33267
  throw fail("AUTH", "token endpoint returned no access_token");
32016
33268
  }
32017
33269
  return token;
32018
33270
  }
32019
- function toResult4(token, fallbackRefresh, now, fallbackAccountId = null) {
33271
+ function toResult6(token, fallbackRefresh, now, fallbackAccountId = null) {
32020
33272
  const claims = decodeClaims(token.idToken);
32021
33273
  return {
32022
33274
  secrets: {
@@ -32074,11 +33326,11 @@ var openaiOAuthFlow = {
32074
33326
  async* start({ redirectUri, pkce, randomState }) {
32075
33327
  const { verifier, challenge } = pkce();
32076
33328
  const state = randomState();
32077
- const url2 = new URL(AUTHORIZE_URL2);
32078
- url2.searchParams.set("client_id", CLIENT_ID4);
33329
+ const url2 = new URL(AUTHORIZE_URL3);
33330
+ url2.searchParams.set("client_id", CLIENT_ID6);
32079
33331
  url2.searchParams.set("response_type", "code");
32080
33332
  url2.searchParams.set("redirect_uri", redirectUri);
32081
- url2.searchParams.set("scope", SCOPES3);
33333
+ url2.searchParams.set("scope", SCOPES4);
32082
33334
  url2.searchParams.set("code_challenge", challenge);
32083
33335
  url2.searchParams.set("code_challenge_method", "S256");
32084
33336
  url2.searchParams.set("id_token_add_organizations", "true");
@@ -32093,17 +33345,17 @@ var openaiOAuthFlow = {
32093
33345
  if (pastedState !== undefined && pastedState !== pending.state) {
32094
33346
  throw fail("AUTH", "authorization state mismatch");
32095
33347
  }
32096
- const token = yield* postToken3({
33348
+ const token = yield* postToken4({
32097
33349
  grant_type: "authorization_code",
32098
33350
  code: (rawCode ?? "").trim(),
32099
33351
  redirect_uri: pending.redirectUri,
32100
33352
  code_verifier: pending.verifier
32101
33353
  }, fail);
32102
- return toResult4(token, null, now);
33354
+ return toResult6(token, null, now);
32103
33355
  },
32104
33356
  async* refresh({ refreshToken, providerData, fail, now }) {
32105
- const token = yield* postToken3({ grant_type: "refresh_token", refresh_token: refreshToken, scope: SCOPES3 }, fail);
32106
- return toResult4(token, refreshToken, now, accountIdFromProviderData(providerData));
33357
+ const token = yield* postToken4({ grant_type: "refresh_token", refresh_token: refreshToken, scope: SCOPES4 }, fail);
33358
+ return toResult6(token, refreshToken, now, accountIdFromProviderData(providerData));
32107
33359
  },
32108
33360
  async* usage({ secrets, providerData, now }) {
32109
33361
  if (secrets.accessToken === null)
@@ -32126,7 +33378,9 @@ function builtinOAuthFlows() {
32126
33378
  ["openai", openaiOAuthFlow],
32127
33379
  ["kimi", kimiOAuthFlow],
32128
33380
  ["kilo", kiloOAuthFlow],
32129
- ["grok", grokOAuthFlow]
33381
+ ["grok", grokOAuthFlow],
33382
+ ["antigravity", antigravityOAuthFlow],
33383
+ ["muse", museOAuthFlow]
32130
33384
  ];
32131
33385
  }
32132
33386
  // packages/providers/src/custom/decode.ts
@@ -32154,7 +33408,7 @@ function reasoningText(delta) {
32154
33408
  return [];
32155
33409
  }).join("");
32156
33410
  }
32157
- function json3(data) {
33411
+ function json4(data) {
32158
33412
  try {
32159
33413
  const v = JSON.parse(data);
32160
33414
  return typeof v === "object" && v !== null ? v : null;
@@ -32176,7 +33430,7 @@ async function* decodeCustomChat(messages) {
32176
33430
  done = true;
32177
33431
  break;
32178
33432
  }
32179
- const d = json3(msg.data);
33433
+ const d = json4(msg.data);
32180
33434
  if (d === null)
32181
33435
  continue;
32182
33436
  if (!started && (d.id !== undefined || d.model !== undefined)) {
@@ -32334,7 +33588,7 @@ async function* decodeCustomResponses(messages) {
32334
33588
  };
32335
33589
  return;
32336
33590
  }
32337
- const d = json3(msg.data);
33591
+ const d = json4(msg.data);
32338
33592
  if (d === null)
32339
33593
  continue;
32340
33594
  switch (msg.event) {
@@ -32722,10 +33976,10 @@ var customCodec = {
32722
33976
  // packages/providers/src/custom/index.ts
32723
33977
  var customAdapter = codecAdapter("custom", customDescriptor.capabilities, customCodec);
32724
33978
  // packages/providers/src/grok/codec.ts
32725
- import { createHash as createHash3 } from "crypto";
33979
+ import { createHash as createHash4 } from "crypto";
32726
33980
 
32727
33981
  // packages/providers/src/grok/decode.ts
32728
- var ERROR_CODE = {
33982
+ var ERROR_CODE2 = {
32729
33983
  rate_limit_exceeded: "RATE_LIMIT",
32730
33984
  insufficient_quota: "QUOTA_EXHAUSTED",
32731
33985
  invalid_api_key: "AUTH",
@@ -32759,7 +34013,7 @@ var KNOWN_EVENTS2 = new Set([
32759
34013
  "response.failed",
32760
34014
  "error"
32761
34015
  ]);
32762
- function json4(data) {
34016
+ function json5(data) {
32763
34017
  try {
32764
34018
  const v = JSON.parse(data);
32765
34019
  return typeof v === "object" && v !== null ? v : null;
@@ -32794,7 +34048,7 @@ async function* decodeGrokResponses(messages) {
32794
34048
  };
32795
34049
  return;
32796
34050
  }
32797
- const d = json4(msg.data);
34051
+ const d = json5(msg.data);
32798
34052
  if (d === null)
32799
34053
  continue;
32800
34054
  switch (msg.event) {
@@ -32897,7 +34151,7 @@ async function* decodeGrokResponses(messages) {
32897
34151
  terminal = true;
32898
34152
  const err = d.response?.error ?? d.error ?? {};
32899
34153
  const raw = String(err.code ?? err.type);
32900
- const code = (Object.hasOwn(ERROR_CODE, raw) ? ERROR_CODE[raw] : undefined) ?? "UPSTREAM";
34154
+ const code = (Object.hasOwn(ERROR_CODE2, raw) ? ERROR_CODE2[raw] : undefined) ?? "UPSTREAM";
32901
34155
  yield {
32902
34156
  type: "error",
32903
34157
  code,
@@ -32921,9 +34175,9 @@ async function* decodeGrokResponses(messages) {
32921
34175
  }
32922
34176
 
32923
34177
  // packages/providers/src/grok/wire.ts
32924
- import { createHash as createHash2 } from "crypto";
34178
+ import { createHash as createHash3 } from "crypto";
32925
34179
  var MAX_TOOLS = 200;
32926
- function encodeToolChoice2(c) {
34180
+ function encodeToolChoice3(c) {
32927
34181
  switch (c.type) {
32928
34182
  case "auto":
32929
34183
  return "auto";
@@ -32937,7 +34191,7 @@ function encodeToolChoice2(c) {
32937
34191
  }
32938
34192
  function promptCacheKey(instructions, firstInput) {
32939
34193
  const stable = JSON.stringify({ instructions, firstInput });
32940
- return createHash2("sha256").update(stable).digest("hex").slice(0, 32);
34194
+ return createHash3("sha256").update(stable).digest("hex").slice(0, 32);
32941
34195
  }
32942
34196
  function toGrokWire(req, model) {
32943
34197
  const degradations = [];
@@ -33030,7 +34284,7 @@ function toGrokWire(req, model) {
33030
34284
  }));
33031
34285
  }
33032
34286
  if (req.toolChoice !== undefined)
33033
- body.tool_choice = encodeToolChoice2(req.toolChoice);
34287
+ body.tool_choice = encodeToolChoice3(req.toolChoice);
33034
34288
  if (req.reasoning !== undefined && req.reasoning.mode !== "off") {
33035
34289
  if (req.reasoning.mode === "budget") {
33036
34290
  note("grok:reasoning-budget-dropped");
@@ -33048,7 +34302,7 @@ var PROXY_URL = "https://cli-chat-proxy.grok.com/v1/responses";
33048
34302
  var API_URL = "https://api.x.ai/v1/responses";
33049
34303
  var CONV_NAMESPACE = "omni-grok-conv";
33050
34304
  function derivedUuid(value) {
33051
- const h = createHash3("sha256").update(`${CONV_NAMESPACE}:${value}`).digest("hex");
34305
+ const h = createHash4("sha256").update(`${CONV_NAMESPACE}:${value}`).digest("hex");
33052
34306
  const variant = (Number.parseInt(h[16], 16) & 3 | 8).toString(16);
33053
34307
  return [
33054
34308
  h.slice(0, 8),
@@ -33117,15 +34371,28 @@ function nodeHttpClient(options = {}) {
33117
34371
  const startedAt = now();
33118
34372
  let traced = false;
33119
34373
  const trace = (status, failed = false) => {
33120
- if (traced || !logger2.enabled("debug"))
34374
+ if (traced)
33121
34375
  return;
33122
34376
  traced = true;
34377
+ const durationMs = now() - startedAt;
34378
+ try {
34379
+ options.onResponseHead?.({
34380
+ provider: req.provider,
34381
+ host: url2.host,
34382
+ path: url2.pathname,
34383
+ ...status === undefined ? {} : { status },
34384
+ durationMs,
34385
+ ...req.requestId === undefined ? {} : { requestId: req.requestId }
34386
+ });
34387
+ } catch {}
34388
+ if (!logger2.enabled("debug"))
34389
+ return;
33123
34390
  logger2.debug("upstream http", {
33124
34391
  provider: req.provider,
33125
34392
  status,
33126
34393
  host: url2.host,
33127
34394
  path: url2.pathname,
33128
- durationMs: now() - startedAt,
34395
+ durationMs,
33129
34396
  reason: failed ? "transport error" : undefined
33130
34397
  });
33131
34398
  };
@@ -33218,7 +34485,7 @@ function reasoningText2(delta) {
33218
34485
  return [];
33219
34486
  }).join("");
33220
34487
  }
33221
- function json5(data) {
34488
+ function json6(data) {
33222
34489
  try {
33223
34490
  const v = JSON.parse(data);
33224
34491
  return typeof v === "object" && v !== null ? v : null;
@@ -33240,7 +34507,7 @@ async function* decodeKiloChat(messages) {
33240
34507
  done = true;
33241
34508
  break;
33242
34509
  }
33243
- const d = json5(msg.data);
34510
+ const d = json6(msg.data);
33244
34511
  if (d === null)
33245
34512
  continue;
33246
34513
  if (!started && (d.id !== undefined || d.model !== undefined)) {
@@ -33340,7 +34607,7 @@ async function* decodeKiloChat(messages) {
33340
34607
  }
33341
34608
 
33342
34609
  // packages/providers/src/kilo/wire.ts
33343
- function encodeToolChoice3(c) {
34610
+ function encodeToolChoice4(c) {
33344
34611
  switch (c.type) {
33345
34612
  case "auto":
33346
34613
  return "auto";
@@ -33451,7 +34718,7 @@ function toKiloWire(req, model) {
33451
34718
  }));
33452
34719
  }
33453
34720
  if (req.toolChoice !== undefined)
33454
- body.tool_choice = encodeToolChoice3(req.toolChoice);
34721
+ body.tool_choice = encodeToolChoice4(req.toolChoice);
33455
34722
  if (req.reasoning !== undefined && req.reasoning.mode !== "off") {
33456
34723
  if (req.reasoning.mode === "budget") {
33457
34724
  body.reasoning = { max_tokens: req.reasoning.budgetTokens };
@@ -33510,7 +34777,7 @@ var FINISH2 = {
33510
34777
  tool_calls: "toolUse",
33511
34778
  content_filter: "contentFilter"
33512
34779
  };
33513
- function json6(data) {
34780
+ function json7(data) {
33514
34781
  try {
33515
34782
  const v = JSON.parse(data);
33516
34783
  return typeof v === "object" && v !== null ? v : null;
@@ -33532,7 +34799,7 @@ async function* decodeChat(messages) {
33532
34799
  done = true;
33533
34800
  break;
33534
34801
  }
33535
- const d = json6(msg.data);
34802
+ const d = json7(msg.data);
33536
34803
  if (d === null)
33537
34804
  continue;
33538
34805
  if (!started && (d.id !== undefined || d.model !== undefined)) {
@@ -33616,7 +34883,7 @@ async function* decodeChat(messages) {
33616
34883
  }
33617
34884
 
33618
34885
  // packages/providers/src/kimi/wire.ts
33619
- function encodeToolChoice4(c) {
34886
+ function encodeToolChoice5(c) {
33620
34887
  switch (c.type) {
33621
34888
  case "auto":
33622
34889
  return "auto";
@@ -33707,7 +34974,7 @@ function toChatWire(req, model, vendor = "kimi") {
33707
34974
  }));
33708
34975
  }
33709
34976
  if (req.toolChoice !== undefined)
33710
- body.tool_choice = encodeToolChoice4(req.toolChoice);
34977
+ body.tool_choice = encodeToolChoice5(req.toolChoice);
33711
34978
  if (req.reasoning !== undefined)
33712
34979
  note("kimi:reasoning-dropped");
33713
34980
  Object.assign(body, req.vendor?.[vendor] ?? {});
@@ -33747,8 +35014,8 @@ var kimiCodec = {
33747
35014
 
33748
35015
  // packages/providers/src/kimi/index.ts
33749
35016
  var kimiAdapter = codecAdapter("kimi", kimiDescriptor.capabilities, kimiCodec);
33750
- // packages/providers/src/openai/decode.ts
33751
- var ERROR_CODE2 = {
35017
+ // packages/providers/src/muse/decode.ts
35018
+ var ERROR_CODE3 = {
33752
35019
  rate_limit_exceeded: "RATE_LIMIT",
33753
35020
  insufficient_quota: "QUOTA_EXHAUSTED",
33754
35021
  invalid_api_key: "AUTH",
@@ -33783,7 +35050,7 @@ var KNOWN_EVENTS3 = new Set([
33783
35050
  "response.failed",
33784
35051
  "error"
33785
35052
  ]);
33786
- function json7(data) {
35053
+ function json8(data) {
33787
35054
  try {
33788
35055
  const v = JSON.parse(data);
33789
35056
  return typeof v === "object" && v !== null ? v : null;
@@ -33791,7 +35058,7 @@ function json7(data) {
33791
35058
  return null;
33792
35059
  }
33793
35060
  }
33794
- async function* decodeResponses(messages, options = {}) {
35061
+ async function* decodeMuseResponses(messages, options = {}) {
33795
35062
  const nativeReasoning = options.nativeReasoning === true;
33796
35063
  const indices = new Map;
33797
35064
  let next = 0;
@@ -33811,6 +35078,406 @@ async function* decodeResponses(messages, options = {}) {
33811
35078
  if (msg.data === "[DONE]")
33812
35079
  continue;
33813
35080
  if (!KNOWN_EVENTS3.has(msg.event)) {
35081
+ yield {
35082
+ type: "error",
35083
+ code: "UPSTREAM",
35084
+ message: `unrecognized muse stream event "${msg.event}"`,
35085
+ retryable: false
35086
+ };
35087
+ return;
35088
+ }
35089
+ const d = json8(msg.data);
35090
+ if (d === null)
35091
+ continue;
35092
+ switch (msg.event) {
35093
+ case "response.created":
35094
+ yield {
35095
+ type: "start",
35096
+ id: String(d.response?.id ?? ""),
35097
+ model: String(d.response?.model ?? "")
35098
+ };
35099
+ break;
35100
+ case "response.output_item.added": {
35101
+ const item = d.item ?? {};
35102
+ if (item.type === "reasoning") {
35103
+ ownsBlock.add(d.output_index ?? 0);
35104
+ yield {
35105
+ type: "blockStart",
35106
+ index: irIndex(d.output_index ?? 0),
35107
+ block: nativeReasoning ? { type: "providerNative", provider: "muse", blockType: "reasoning", data: {} } : { type: "thinking" }
35108
+ };
35109
+ } else if (item.type === "function_call") {
35110
+ sawToolCall = true;
35111
+ ownsBlock.add(d.output_index ?? 0);
35112
+ yield {
35113
+ type: "blockStart",
35114
+ index: irIndex(d.output_index ?? 0),
35115
+ block: { type: "toolUse", id: String(item.call_id), name: String(item.name) }
35116
+ };
35117
+ }
35118
+ break;
35119
+ }
35120
+ case "response.content_part.added":
35121
+ if (d.part?.type === "output_text") {
35122
+ yield {
35123
+ type: "blockStart",
35124
+ index: irIndex(d.output_index ?? 0, d.content_index ?? 0),
35125
+ block: { type: "text" }
35126
+ };
35127
+ }
35128
+ break;
35129
+ case "response.output_text.delta":
35130
+ yield {
35131
+ type: "blockDelta",
35132
+ index: irIndex(d.output_index ?? 0, d.content_index ?? 0),
35133
+ delta: { type: "text", text: String(d.delta ?? "") }
35134
+ };
35135
+ break;
35136
+ case "response.reasoning_summary_text.delta":
35137
+ yield {
35138
+ type: "blockDelta",
35139
+ index: irIndex(d.output_index ?? 0),
35140
+ delta: nativeReasoning ? {
35141
+ type: "providerNative",
35142
+ provider: "muse",
35143
+ deltaType: "reasoning_summary_text.delta",
35144
+ data: { text: String(d.delta ?? "") }
35145
+ } : { type: "thinking", text: String(d.delta ?? "") }
35146
+ };
35147
+ break;
35148
+ case "response.function_call_arguments.delta":
35149
+ yield {
35150
+ type: "blockDelta",
35151
+ index: irIndex(d.output_index ?? 0),
35152
+ delta: { type: "toolJson", partial: String(d.delta ?? "") }
35153
+ };
35154
+ break;
35155
+ case "response.content_part.done":
35156
+ yield { type: "blockEnd", index: irIndex(d.output_index ?? 0, d.content_index ?? 0) };
35157
+ break;
35158
+ case "response.output_item.done": {
35159
+ const outputIndex = d.output_index ?? 0;
35160
+ if (ownsBlock.delete(outputIndex)) {
35161
+ const item = d.item ?? {};
35162
+ if (nativeReasoning && item.type === "reasoning") {
35163
+ yield {
35164
+ type: "blockDelta",
35165
+ index: irIndex(outputIndex),
35166
+ delta: {
35167
+ type: "providerNative",
35168
+ provider: "muse",
35169
+ deltaType: "response.output_item.done",
35170
+ fold: "merge",
35171
+ data: item
35172
+ }
35173
+ };
35174
+ }
35175
+ yield { type: "blockEnd", index: irIndex(outputIndex) };
35176
+ }
35177
+ break;
35178
+ }
35179
+ case "response.completed":
35180
+ case "response.incomplete": {
35181
+ terminal = true;
35182
+ const r = d.response ?? {};
35183
+ const reason = r.incomplete_details?.reason;
35184
+ let stopReason = sawToolCall ? "toolUse" : "endTurn";
35185
+ if (reason === "max_output_tokens")
35186
+ stopReason = "maxTokens";
35187
+ else if (reason === "content_filter")
35188
+ stopReason = "contentFilter";
35189
+ else if (reason !== undefined || msg.event === "response.incomplete" || r.status !== undefined && r.status !== "completed") {
35190
+ yield {
35191
+ type: "error",
35192
+ code: "UPSTREAM",
35193
+ message: reason !== undefined ? `unrecognized muse incomplete reason "${String(reason)}"` : r.status !== undefined && r.status !== "incomplete" ? `muse reported terminal response status "${String(r.status)}"` : "muse reported the response incomplete without a reason",
35194
+ retryable: false
35195
+ };
35196
+ break;
35197
+ }
35198
+ yield {
35199
+ type: "end",
35200
+ stopReason,
35201
+ usage: usageFromPromptTotal(r.usage?.input_tokens ?? 0, r.usage?.output_tokens ?? 0, r.usage?.input_tokens_details?.cached_tokens ?? r.usage?.prompt_tokens_details?.cached_tokens ?? 0)
35202
+ };
35203
+ break;
35204
+ }
35205
+ case "response.failed":
35206
+ case "error": {
35207
+ terminal = true;
35208
+ const err = d.response?.error ?? d.error ?? {};
35209
+ const raw = String(err.code ?? err.type);
35210
+ const code = (Object.hasOwn(ERROR_CODE3, raw) ? ERROR_CODE3[raw] : undefined) ?? "UPSTREAM";
35211
+ yield {
35212
+ type: "error",
35213
+ code,
35214
+ message: String(err.message ?? "upstream error"),
35215
+ retryable: RETRYABLE[code]
35216
+ };
35217
+ break;
35218
+ }
35219
+ default:
35220
+ break;
35221
+ }
35222
+ }
35223
+ if (!terminal) {
35224
+ yield {
35225
+ type: "error",
35226
+ code: "UPSTREAM",
35227
+ message: "upstream stream ended before response completion",
35228
+ retryable: RETRYABLE.UPSTREAM
35229
+ };
35230
+ }
35231
+ }
35232
+
35233
+ // packages/providers/src/muse/wire.ts
35234
+ import { createHash as createHash5 } from "crypto";
35235
+ function suppliedKey(req) {
35236
+ const vendor = req.vendor?.openai;
35237
+ for (const name of ["prompt_cache_key", "session_id"]) {
35238
+ const value = vendor?.[name];
35239
+ if (typeof value === "string" && value.length > 0)
35240
+ return value;
35241
+ }
35242
+ return;
35243
+ }
35244
+ function cacheKey(req, instructions, firstInput) {
35245
+ const stable = req.conversationId !== undefined && req.conversationId.length > 0 ? JSON.stringify({ conversation: req.conversationId }) : JSON.stringify({ instructions, firstInput: firstInput ?? null });
35246
+ return createHash5("sha256").update(stable).digest("hex").slice(0, 32);
35247
+ }
35248
+ function repairOrphanedCalls(input2) {
35249
+ const answered = new Set;
35250
+ for (const item of input2) {
35251
+ const record2 = item;
35252
+ if (record2.type === "function_call_output" && typeof record2.call_id === "string") {
35253
+ answered.add(record2.call_id);
35254
+ }
35255
+ }
35256
+ for (let i = input2.length - 1;i >= 0; i--) {
35257
+ const record2 = input2[i];
35258
+ if (record2.type !== "function_call" || typeof record2.call_id !== "string")
35259
+ continue;
35260
+ if (answered.has(record2.call_id))
35261
+ continue;
35262
+ input2.splice(i + 1, 0, { type: "function_call_output", call_id: record2.call_id, output: "" });
35263
+ }
35264
+ }
35265
+ function encodeToolChoice6(c) {
35266
+ switch (c.type) {
35267
+ case "auto":
35268
+ return "auto";
35269
+ case "any":
35270
+ return "required";
35271
+ case "none":
35272
+ return "none";
35273
+ case "tool":
35274
+ return { type: "function", name: c.name };
35275
+ }
35276
+ }
35277
+ function toMuseWire(req, model) {
35278
+ const degradations = [];
35279
+ const input2 = [];
35280
+ const note = (d) => {
35281
+ if (!degradations.includes(d))
35282
+ degradations.push(d);
35283
+ };
35284
+ if (req.betas?.includes(CONTEXT_1M_BETA))
35285
+ note("muse:context-1m-dropped");
35286
+ for (const message of req.messages) {
35287
+ const parts = [];
35288
+ const asDeveloper = message.role === "system";
35289
+ if (asDeveloper)
35290
+ note("muse:system-turn-as-developer");
35291
+ const role = asDeveloper ? "developer" : message.role;
35292
+ const flush = () => {
35293
+ if (parts.length === 0)
35294
+ return;
35295
+ input2.push({ type: "message", role, content: [...parts] });
35296
+ parts.length = 0;
35297
+ };
35298
+ for (const block of message.content) {
35299
+ switch (block.type) {
35300
+ case "text":
35301
+ parts.push({
35302
+ type: role === "assistant" ? "output_text" : "input_text",
35303
+ text: block.text
35304
+ });
35305
+ break;
35306
+ case "image":
35307
+ parts.push({
35308
+ type: "input_image",
35309
+ image_url: `data:${block.mediaType};base64,${block.data}`
35310
+ });
35311
+ break;
35312
+ case "thinking":
35313
+ note("muse:thinking-dropped");
35314
+ break;
35315
+ case "toolUse":
35316
+ flush();
35317
+ input2.push({
35318
+ type: "function_call",
35319
+ call_id: block.id,
35320
+ name: block.name,
35321
+ arguments: JSON.stringify(block.input)
35322
+ });
35323
+ break;
35324
+ case "toolResult":
35325
+ flush();
35326
+ input2.push({
35327
+ type: "function_call_output",
35328
+ call_id: block.toolUseId,
35329
+ output: block.content
35330
+ });
35331
+ break;
35332
+ case "providerNative":
35333
+ if (block.provider === "muse") {
35334
+ flush();
35335
+ const { id: _id, ...rest } = block.data;
35336
+ input2.push({ type: block.blockType, ...rest });
35337
+ break;
35338
+ }
35339
+ note("muse:foreign-native-block-dropped");
35340
+ break;
35341
+ }
35342
+ }
35343
+ flush();
35344
+ }
35345
+ repairOrphanedCalls(input2);
35346
+ const body = { model, input: input2, stream: req.stream, store: false };
35347
+ const instructions = systemText(req.system, "muse", note);
35348
+ if (instructions !== undefined && instructions.length > 0)
35349
+ body.instructions = instructions;
35350
+ if (req.maxTokens !== undefined)
35351
+ body.max_output_tokens = req.maxTokens;
35352
+ if (req.temperature !== undefined)
35353
+ body.temperature = req.temperature;
35354
+ if (req.tools !== undefined) {
35355
+ const portable = req.tools.filter((t) => t.kind === "portable");
35356
+ if (portable.length !== req.tools.length)
35357
+ note("muse:provider-tool-dropped");
35358
+ body.tools = portable.map((t) => ({
35359
+ type: "function",
35360
+ name: t.name,
35361
+ description: t.description,
35362
+ parameters: t.inputSchema
35363
+ }));
35364
+ }
35365
+ if (req.toolChoice !== undefined)
35366
+ body.tool_choice = encodeToolChoice6(req.toolChoice);
35367
+ if (req.reasoning !== undefined && req.reasoning.mode !== "off") {
35368
+ if (req.reasoning.mode === "budget") {
35369
+ note("muse:reasoning-budget-dropped");
35370
+ } else {
35371
+ const effort = req.reasoning.effort ?? "medium";
35372
+ body.reasoning = { effort, summary: "auto" };
35373
+ }
35374
+ }
35375
+ const key = suppliedKey(req) ?? cacheKey(req, instructions ?? "", input2[0]);
35376
+ Object.assign(body, req.vendor?.openai ?? {});
35377
+ body.prompt_cache_key = key;
35378
+ return { body, degradations, cacheKey: key };
35379
+ }
35380
+
35381
+ // packages/providers/src/muse/codec.ts
35382
+ var museCodec = {
35383
+ buildRequest(input2) {
35384
+ const { body, degradations, cacheKey: cacheKey2 } = toMuseWire(input2.request, input2.model);
35385
+ if (input2.credentials.apiKey === null) {
35386
+ throw input2.fail("AUTH", "muse credential has no model api key");
35387
+ }
35388
+ const protocol = [
35389
+ ["Content-Type", "application/json"],
35390
+ ["Authorization", `Bearer ${input2.credentials.apiKey}`],
35391
+ ["x-meta-ai-gateway-session-id", cacheKey2]
35392
+ ];
35393
+ const headers = orderHeaders(mergeHeaders(museProfile.headers, protocol), museProfile.order);
35394
+ const include = body.include;
35395
+ const nativeReasoning = Array.isArray(include) && include.includes("reasoning.encrypted_content");
35396
+ return {
35397
+ decodeState: { nativeReasoning },
35398
+ request: {
35399
+ url: museResponsesUrl(input2.credentials.providerData),
35400
+ method: "POST",
35401
+ headers,
35402
+ body: JSON.stringify(orderFields({ ...body, stream: true }, museBodyOrder))
35403
+ },
35404
+ degradations
35405
+ };
35406
+ },
35407
+ decode({ body, decodeState }) {
35408
+ const state = decodeState;
35409
+ return decodeMuseResponses(parseSse(body), {
35410
+ nativeReasoning: state?.nativeReasoning === true
35411
+ });
35412
+ }
35413
+ };
35414
+
35415
+ // packages/providers/src/muse/index.ts
35416
+ var museAdapter = codecAdapter("muse", museDescriptor.capabilities, museCodec);
35417
+ // packages/providers/src/openai/decode.ts
35418
+ var ERROR_CODE4 = {
35419
+ rate_limit_exceeded: "RATE_LIMIT",
35420
+ insufficient_quota: "QUOTA_EXHAUSTED",
35421
+ invalid_api_key: "AUTH",
35422
+ server_error: "UPSTREAM",
35423
+ context_length_exceeded: "BAD_REQUEST",
35424
+ content_policy_violation: "CONTENT_FILTER"
35425
+ };
35426
+ var KNOWN_EVENTS4 = new Set([
35427
+ "keepalive",
35428
+ "response.created",
35429
+ "response.queued",
35430
+ "response.in_progress",
35431
+ "response.output_item.added",
35432
+ "response.output_item.done",
35433
+ "response.content_part.added",
35434
+ "response.content_part.done",
35435
+ "response.output_text.delta",
35436
+ "response.output_text.done",
35437
+ "response.output_text.annotation.added",
35438
+ "response.refusal.delta",
35439
+ "response.refusal.done",
35440
+ "response.reasoning_summary_part.added",
35441
+ "response.reasoning_summary_part.done",
35442
+ "response.reasoning_summary_text.delta",
35443
+ "response.reasoning_summary_text.done",
35444
+ "response.reasoning_text.delta",
35445
+ "response.reasoning_text.done",
35446
+ "response.function_call_arguments.delta",
35447
+ "response.function_call_arguments.done",
35448
+ "response.completed",
35449
+ "response.incomplete",
35450
+ "response.failed",
35451
+ "error"
35452
+ ]);
35453
+ function json9(data) {
35454
+ try {
35455
+ const v = JSON.parse(data);
35456
+ return typeof v === "object" && v !== null ? v : null;
35457
+ } catch {
35458
+ return null;
35459
+ }
35460
+ }
35461
+ async function* decodeResponses(messages, options = {}) {
35462
+ const nativeReasoning = options.nativeReasoning === true;
35463
+ const indices = new Map;
35464
+ let next = 0;
35465
+ const irIndex = (outputIndex, contentIndex = 0) => {
35466
+ const key = `${outputIndex}:${contentIndex}`;
35467
+ const existing = indices.get(key);
35468
+ if (existing !== undefined)
35469
+ return existing;
35470
+ const assigned = next++;
35471
+ indices.set(key, assigned);
35472
+ return assigned;
35473
+ };
35474
+ let sawToolCall = false;
35475
+ let terminal = false;
35476
+ const ownsBlock = new Set;
35477
+ for await (const msg of messages) {
35478
+ if (msg.data === "[DONE]")
35479
+ continue;
35480
+ if (!KNOWN_EVENTS4.has(msg.event)) {
33814
35481
  yield {
33815
35482
  type: "error",
33816
35483
  code: "UPSTREAM",
@@ -33819,7 +35486,7 @@ async function* decodeResponses(messages, options = {}) {
33819
35486
  };
33820
35487
  return;
33821
35488
  }
33822
- const d = json7(msg.data);
35489
+ const d = json9(msg.data);
33823
35490
  if (d === null)
33824
35491
  continue;
33825
35492
  switch (msg.event) {
@@ -33940,7 +35607,7 @@ async function* decodeResponses(messages, options = {}) {
33940
35607
  terminal = true;
33941
35608
  const err = d.response?.error ?? d.error ?? {};
33942
35609
  const raw = String(err.code ?? err.type);
33943
- const code = (Object.hasOwn(ERROR_CODE2, raw) ? ERROR_CODE2[raw] : undefined) ?? "UPSTREAM";
35610
+ const code = (Object.hasOwn(ERROR_CODE4, raw) ? ERROR_CODE4[raw] : undefined) ?? "UPSTREAM";
33944
35611
  yield {
33945
35612
  type: "error",
33946
35613
  code,
@@ -33964,8 +35631,8 @@ async function* decodeResponses(messages, options = {}) {
33964
35631
  }
33965
35632
 
33966
35633
  // packages/providers/src/openai/wire.ts
33967
- import { createHash as createHash4 } from "crypto";
33968
- function suppliedKey(req) {
35634
+ import { createHash as createHash6 } from "crypto";
35635
+ function suppliedKey2(req) {
33969
35636
  const vendor = req.vendor?.openai;
33970
35637
  for (const name of ["prompt_cache_key", "session_id"]) {
33971
35638
  const value = vendor?.[name];
@@ -33974,11 +35641,11 @@ function suppliedKey(req) {
33974
35641
  }
33975
35642
  return;
33976
35643
  }
33977
- function cacheKey(req, instructions, firstInput) {
35644
+ function cacheKey2(req, instructions, firstInput) {
33978
35645
  const stable = req.conversationId !== undefined && req.conversationId.length > 0 ? JSON.stringify({ conversation: req.conversationId }) : JSON.stringify({ instructions, firstInput: firstInput ?? null });
33979
- return createHash4("sha256").update(stable).digest("hex").slice(0, 32);
35646
+ return createHash6("sha256").update(stable).digest("hex").slice(0, 32);
33980
35647
  }
33981
- function repairOrphanedCalls(input2) {
35648
+ function repairOrphanedCalls2(input2) {
33982
35649
  const answered = new Set;
33983
35650
  for (const item of input2) {
33984
35651
  const record2 = item;
@@ -33995,7 +35662,7 @@ function repairOrphanedCalls(input2) {
33995
35662
  input2.splice(i + 1, 0, { type: "function_call_output", call_id: record2.call_id, output: "" });
33996
35663
  }
33997
35664
  }
33998
- function encodeToolChoice5(c) {
35665
+ function encodeToolChoice7(c) {
33999
35666
  switch (c.type) {
34000
35667
  case "auto":
34001
35668
  return "auto";
@@ -34077,7 +35744,7 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
34077
35744
  }
34078
35745
  flush();
34079
35746
  }
34080
- repairOrphanedCalls(input2);
35747
+ repairOrphanedCalls2(input2);
34081
35748
  const body = { model, input: input2, stream: req.stream, store: false };
34082
35749
  const instructions = systemText(req.system, "openai", note);
34083
35750
  if (instructions !== undefined && instructions.length > 0)
@@ -34106,7 +35773,7 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
34106
35773
  }));
34107
35774
  }
34108
35775
  if (req.toolChoice !== undefined)
34109
- body.tool_choice = encodeToolChoice5(req.toolChoice);
35776
+ body.tool_choice = encodeToolChoice7(req.toolChoice);
34110
35777
  if (req.reasoning !== undefined && req.reasoning.mode !== "off") {
34111
35778
  if (req.reasoning.mode === "budget") {
34112
35779
  degradations.push("openai:reasoning-budget-dropped");
@@ -34115,7 +35782,7 @@ function toResponsesWire(req, model, opts = { oauth: false }) {
34115
35782
  body.reasoning = { effort, summary: "auto" };
34116
35783
  }
34117
35784
  }
34118
- const key = suppliedKey(req) ?? cacheKey(req, instructions ?? "", input2[0]);
35785
+ const key = suppliedKey2(req) ?? cacheKey2(req, instructions ?? "", input2[0]);
34119
35786
  Object.assign(body, req.vendor?.openai ?? {});
34120
35787
  body.prompt_cache_key = key;
34121
35788
  return { body, degradations, cacheKey: key };
@@ -34127,14 +35794,14 @@ var API_URL3 = "https://api.openai.com/v1/responses";
34127
35794
  var openaiCodec = {
34128
35795
  buildRequest(input2) {
34129
35796
  const oauth = input2.credentials.accessToken !== null;
34130
- const { body, degradations, cacheKey: cacheKey2 } = toResponsesWire(input2.request, input2.model, { oauth });
35797
+ const { body, degradations, cacheKey: cacheKey3 } = toResponsesWire(input2.request, input2.model, { oauth });
34131
35798
  const protocol = [["Content-Type", "application/json"]];
34132
35799
  if (oauth) {
34133
35800
  protocol.push(["Authorization", `Bearer ${input2.credentials.accessToken}`]);
34134
35801
  const accountId = input2.credentials.providerData.accountId;
34135
35802
  if (typeof accountId === "string")
34136
35803
  protocol.push(["chatgpt-account-id", accountId]);
34137
- protocol.push(["session_id", cacheKey2]);
35804
+ protocol.push(["session_id", cacheKey3]);
34138
35805
  } else if (input2.credentials.apiKey !== null) {
34139
35806
  protocol.push(["Authorization", `Bearer ${input2.credentials.apiKey}`]);
34140
35807
  } else {
@@ -34169,6 +35836,8 @@ var ADAPTERS = {
34169
35836
  kimi: kimiAdapter,
34170
35837
  kilo: kiloAdapter,
34171
35838
  grok: grokAdapter,
35839
+ antigravity: antigravityAdapter,
35840
+ muse: museAdapter,
34172
35841
  custom: customAdapter
34173
35842
  };
34174
35843
  Object.setPrototypeOf(ADAPTERS, null);
@@ -35780,7 +37449,7 @@ import { join as join3 } from "path";
35780
37449
 
35781
37450
  // packages/plugin-api/src/version.ts
35782
37451
  var PLUGIN_API_VERSION = 3;
35783
- var DASHBOARD_SDK_VERSION = "0.1.6";
37452
+ var DASHBOARD_SDK_VERSION = "0.1.8";
35784
37453
  // packages/plugin-api/src/manifest.ts
35785
37454
  var CAPABILITIES = [
35786
37455
  "storage",
@@ -36218,7 +37887,7 @@ function createRefresher(deps) {
36218
37887
  };
36219
37888
  }
36220
37889
  // packages/control/src/pluginProviders.ts
36221
- function isRecord6(value) {
37890
+ function isRecord7(value) {
36222
37891
  return typeof value === "object" && value !== null && !Array.isArray(value);
36223
37892
  }
36224
37893
  function isNumber(value) {
@@ -36229,7 +37898,7 @@ function checkAt(ok, id, path, expected) {
36229
37898
  throw new Error(`provider ${id} descriptor: ${path} must be ${expected}`);
36230
37899
  }
36231
37900
  function checkLimits(id, path, value) {
36232
- checkAt(isRecord6(value), id, path, "an object");
37901
+ checkAt(isRecord7(value), id, path, "an object");
36233
37902
  const limits = value;
36234
37903
  checkAt(isNumber(limits.contextWindow), id, `${path}.contextWindow`, "a finite number");
36235
37904
  checkAt(isNumber(limits.maxOutputTokens), id, `${path}.maxOutputTokens`, "a finite number");
@@ -36247,19 +37916,19 @@ function checkDescriptor(id, record2) {
36247
37916
  }
36248
37917
  }
36249
37918
  const capabilities2 = record2.capabilities;
36250
- checkAt(isRecord6(capabilities2), id, "capabilities", "an object");
37919
+ checkAt(isRecord7(capabilities2), id, "capabilities", "an object");
36251
37920
  for (const flag of ["tools", "images", "reasoning"]) {
36252
37921
  const value = capabilities2[flag];
36253
37922
  checkAt(typeof value === "boolean", id, `capabilities.${flag}`, "a boolean");
36254
37923
  }
36255
37924
  const write = record2.writeOverInput;
36256
- checkAt(isRecord6(write), id, "writeOverInput", "an object");
37925
+ checkAt(isRecord7(write), id, "writeOverInput", "an object");
36257
37926
  for (const ttl of ["fiveMinute", "oneHour"]) {
36258
37927
  const value = write[ttl];
36259
37928
  checkAt(isNumber(value), id, `writeOverInput.${ttl}`, "a finite number");
36260
37929
  }
36261
37930
  const catalog2 = record2.catalog;
36262
- checkAt(isRecord6(catalog2), id, "catalog", "an object");
37931
+ checkAt(isRecord7(catalog2), id, "catalog", "an object");
36263
37932
  const entry = catalog2;
36264
37933
  checkAt(typeof entry.defaultModel === "string", id, "catalog.defaultModel", "a string");
36265
37934
  checkAt(Array.isArray(entry.authTypes), id, "catalog.authTypes", "an array");
@@ -36270,11 +37939,11 @@ function checkDescriptor(id, record2) {
36270
37939
  checkAt(Array.isArray(entry.models), id, "catalog.models", "an array");
36271
37940
  for (const [index, model] of entry.models.entries()) {
36272
37941
  const at = `catalog.models[${index}]`;
36273
- checkAt(isRecord6(model), id, at, "an object");
37942
+ checkAt(isRecord7(model), id, at, "an object");
36274
37943
  const choice = model;
36275
37944
  checkAt(typeof choice.id === "string", id, `${at}.id`, "a string");
36276
37945
  checkAt(typeof choice.label === "string", id, `${at}.label`, "a string");
36277
- checkAt(isRecord6(choice.pricing), id, `${at}.pricing`, "an object");
37946
+ checkAt(isRecord7(choice.pricing), id, `${at}.pricing`, "an object");
36278
37947
  const pricing = choice.pricing;
36279
37948
  for (const field of ["input", "output", "cacheRead", "cacheWrite5m", "cacheWrite1h"]) {
36280
37949
  checkAt(isNumber(pricing[field]), id, `${at}.pricing.${field}`, "a finite number");
@@ -36290,13 +37959,13 @@ function checkDescriptor(id, record2) {
36290
37959
  checkAt(typeof prefix === "string", id, `modelPrefixes[${index}]`, "a string");
36291
37960
  }
36292
37961
  const presentation = record2.presentation;
36293
- checkAt(isRecord6(presentation), id, "presentation", "an object");
37962
+ checkAt(isRecord7(presentation), id, "presentation", "an object");
36294
37963
  const shown = presentation;
36295
37964
  for (const field of ["label", "tone"]) {
36296
37965
  checkAt(typeof shown[field] === "string", id, `presentation.${field}`, "a string");
36297
37966
  }
36298
37967
  checkAt(isNumber(shown.order), id, "presentation.order", "a finite number");
36299
- checkAt(isRecord6(shown.colour), id, "presentation.colour", "an object");
37968
+ checkAt(isRecord7(shown.colour), id, "presentation.colour", "an object");
36300
37969
  for (const scheme of ["light", "dark"]) {
36301
37970
  const value = shown.colour[scheme];
36302
37971
  checkAt(typeof value === "string", id, `presentation.colour.${scheme}`, "a string");
@@ -36308,7 +37977,7 @@ function checkDescriptor(id, record2) {
36308
37977
  function validateOAuthFlow(id, value) {
36309
37978
  if (value === undefined)
36310
37979
  return;
36311
- if (!isRecord6(value))
37980
+ if (!isRecord7(value))
36312
37981
  throw new Error(`provider ${id} oauth must be an object`);
36313
37982
  const kind = value.kind;
36314
37983
  if (kind !== "pkce" && kind !== "device") {
@@ -36847,6 +38516,7 @@ var WINDOW_MS2 = {
36847
38516
  "1w": 7 * 24 * 60 * 60 * 1000
36848
38517
  };
36849
38518
  // apps/gateway/src/app.ts
38519
+ import { timingSafeEqual } from "crypto";
36850
38520
  import { existsSync, realpathSync as realpathSync3 } from "fs";
36851
38521
  import { resolve as resolve3, sep as sep3 } from "path";
36852
38522
 
@@ -37939,13 +39609,13 @@ function IsSeparator(pattern, index) {
37939
39609
  function IsGroup(pattern) {
37940
39610
  if (!(IsOpenParen(pattern, 0) && IsCloseParen(pattern, pattern.length - 1)))
37941
39611
  return false;
37942
- let count = 0;
39612
+ let count2 = 0;
37943
39613
  for (let index = 0;index < pattern.length; index++) {
37944
39614
  if (IsOpenParen(pattern, index))
37945
- count += 1;
39615
+ count2 += 1;
37946
39616
  if (IsCloseParen(pattern, index))
37947
- count -= 1;
37948
- if (count === 0 && index !== pattern.length - 1)
39617
+ count2 -= 1;
39618
+ if (count2 === 0 && index !== pattern.length - 1)
37949
39619
  return false;
37950
39620
  }
37951
39621
  return true;
@@ -37954,13 +39624,13 @@ function InGroup(pattern) {
37954
39624
  return pattern.slice(1, pattern.length - 1);
37955
39625
  }
37956
39626
  function IsPrecedenceOr(pattern) {
37957
- let count = 0;
39627
+ let count2 = 0;
37958
39628
  for (let index = 0;index < pattern.length; index++) {
37959
39629
  if (IsOpenParen(pattern, index))
37960
- count += 1;
39630
+ count2 += 1;
37961
39631
  if (IsCloseParen(pattern, index))
37962
- count -= 1;
37963
- if (IsSeparator(pattern, index) && count === 0)
39632
+ count2 -= 1;
39633
+ if (IsSeparator(pattern, index) && count2 === 0)
37964
39634
  return true;
37965
39635
  }
37966
39636
  return false;
@@ -37973,14 +39643,14 @@ function IsPrecedenceAnd(pattern) {
37973
39643
  return false;
37974
39644
  }
37975
39645
  function Or(pattern) {
37976
- let [count, start] = [0, 0];
39646
+ let [count2, start] = [0, 0];
37977
39647
  const expressions = [];
37978
39648
  for (let index = 0;index < pattern.length; index++) {
37979
39649
  if (IsOpenParen(pattern, index))
37980
- count += 1;
39650
+ count2 += 1;
37981
39651
  if (IsCloseParen(pattern, index))
37982
- count -= 1;
37983
- if (IsSeparator(pattern, index) && count === 0) {
39652
+ count2 -= 1;
39653
+ if (IsSeparator(pattern, index) && count2 === 0) {
37984
39654
  const range2 = pattern.slice(start, index);
37985
39655
  if (range2.length > 0)
37986
39656
  expressions.push(TemplateLiteralParse(range2));
@@ -38000,13 +39670,13 @@ function And(pattern) {
38000
39670
  function Group(value, index) {
38001
39671
  if (!IsOpenParen(value, index))
38002
39672
  throw new TemplateLiteralParserError(`TemplateLiteralParser: Index must point to open parens`);
38003
- let count = 0;
39673
+ let count2 = 0;
38004
39674
  for (let scan = index;scan < value.length; scan++) {
38005
39675
  if (IsOpenParen(value, scan))
38006
- count += 1;
39676
+ count2 += 1;
38007
39677
  if (IsCloseParen(value, scan))
38008
- count -= 1;
38009
- if (count === 0)
39678
+ count2 -= 1;
39679
+ if (count2 === 0)
38010
39680
  return [index, scan];
38011
39681
  }
38012
39682
  throw new TemplateLiteralParserError(`TemplateLiteralParser: Unclosed group parens in expression`);
@@ -38776,8 +40446,8 @@ function FromNumberRight(left, right) {
38776
40446
  function FromNumber(left, right) {
38777
40447
  return IsStructuralRight(right) ? StructuralRight(left, right) : exports_type.IsObject(right) ? FromObjectRight(left, right) : exports_type.IsRecord(right) ? FromRecordRight(left, right) : exports_type.IsInteger(right) || exports_type.IsNumber(right) ? ExtendsResult.True : ExtendsResult.False;
38778
40448
  }
38779
- function IsObjectPropertyCount(schema, count) {
38780
- return Object.getOwnPropertyNames(schema.properties).length === count;
40449
+ function IsObjectPropertyCount(schema, count2) {
40450
+ return Object.getOwnPropertyNames(schema.properties).length === count2;
38781
40451
  }
38782
40452
  function IsObjectStringLike(schema) {
38783
40453
  return IsObjectArrayLike(schema);
@@ -44246,7 +45916,7 @@ var emptySchema = {
44246
45916
 
44247
45917
  // node_modules/.bun/elysia@1.4.30+7c910760591f72db/node_modules/elysia/dist/error.mjs
44248
45918
  var env2 = typeof Bun < "u" ? Bun.env : typeof process < "u" ? process?.env : undefined;
44249
- var ERROR_CODE3 = Symbol("ElysiaErrorCode");
45919
+ var ERROR_CODE5 = Symbol("ElysiaErrorCode");
44250
45920
  var isProduction = (env2?.NODE_ENV ?? env2?.ENV) === "production";
44251
45921
  var emptyHttpStatus = {
44252
45922
  101: undefined,
@@ -48819,7 +50489,7 @@ c.defs=definitions
48819
50489
  schema: app.router.history,
48820
50490
  definitions: app.definitions.type,
48821
50491
  tee,
48822
- ERROR_CODE: ERROR_CODE3,
50492
+ ERROR_CODE: ERROR_CODE5,
48823
50493
  parseCookie: hasCookie ? parseCookie : undefined,
48824
50494
  signCookie: hasCookie ? signCookie : undefined,
48825
50495
  Cookie: hasCookie ? Cookie : undefined,
@@ -49092,7 +50762,7 @@ return mapResponse(${saveResponse}error,set${adapter.mapResponseContext})}`;
49092
50762
  return Function("inject", `"use strict";
49093
50763
  ` + fnLiteral)({
49094
50764
  mapResponse: app["~adapter"].handler.mapResponse,
49095
- ERROR_CODE: ERROR_CODE3,
50765
+ ERROR_CODE: ERROR_CODE5,
49096
50766
  ElysiaCustomStatusResponse,
49097
50767
  ValidationError,
49098
50768
  TransformDecodeError,
@@ -50575,12 +52245,12 @@ var _Elysia = class _Elysia2 {
50575
52245
  error(name, error61) {
50576
52246
  switch (typeof name) {
50577
52247
  case "string":
50578
- return error61.prototype[ERROR_CODE3] = name, this.definitions.error[name] = error61, this;
52248
+ return error61.prototype[ERROR_CODE5] = name, this.definitions.error[name] = error61, this;
50579
52249
  case "function":
50580
52250
  return this.definitions.error = name(this.definitions.error), this;
50581
52251
  }
50582
52252
  for (const [code, error210] of Object.entries(name))
50583
- error210.prototype[ERROR_CODE3] = code, this.definitions.error[code] = error210;
52253
+ error210.prototype[ERROR_CODE5] = code, this.definitions.error[code] = error210;
50584
52254
  return this;
50585
52255
  }
50586
52256
  onError(options, handler) {
@@ -51324,11 +52994,13 @@ class ApiKeyRateLimiter {
51324
52994
  store;
51325
52995
  now;
51326
52996
  logger;
52997
+ onRejected;
51327
52998
  constructor(deps) {
51328
52999
  this.store = deps.store;
51329
53000
  this.now = deps.now;
51330
53001
  this.logger = deps.logger ?? noopLogger;
51331
53002
  this.coord = deps.coord ?? memoryCoord();
53003
+ this.onRejected = deps.onRejected;
51332
53004
  }
51333
53005
  async admit(keyId, limits, requestId) {
51334
53006
  if (!anyLimit(limits))
@@ -51403,6 +53075,9 @@ class ApiKeyRateLimiter {
51403
53075
  const exact = await this.exactReset(keyId, window2, now, requestId);
51404
53076
  const resolved = exact === null ? violation : { ...violation, resetAt: exact };
51405
53077
  const headroom = exact === null || window2 === null ? decision.headroom : withReset(decision.headroom, window2, exact);
53078
+ try {
53079
+ this.onRejected?.(violation.dimension, violation.window);
53080
+ } catch {}
51406
53081
  throw new RateLimitExceeded(retryAfterMs(resolved, now), headroom);
51407
53082
  }
51408
53083
  async exactReset(keyId, window2, now, requestId) {
@@ -51501,6 +53176,61 @@ function withReset(headroom, window2, resetAt) {
51501
53176
  return corrected;
51502
53177
  }
51503
53178
 
53179
+ // apps/gateway/src/dispatch/loadRegistry.ts
53180
+ var PREFIX6 = "load:";
53181
+ var SLOT_TTL_MS = 300000;
53182
+ function createLoadRegistry(coord = memoryCoord()) {
53183
+ const local = new Map;
53184
+ const providers = new Map;
53185
+ let remote = new Map;
53186
+ return {
53187
+ acquire(credentialId, model, provider) {
53188
+ const key = healthKey(credentialId, model);
53189
+ local.set(key, (local.get(key) ?? 0) + 1);
53190
+ if (provider !== undefined)
53191
+ providers.set(provider, (providers.get(provider) ?? 0) + 1);
53192
+ coord.gauge.acquire(PREFIX6 + key, SLOT_TTL_MS);
53193
+ let released = false;
53194
+ return () => {
53195
+ if (released)
53196
+ return;
53197
+ released = true;
53198
+ const next = (local.get(key) ?? 0) - 1;
53199
+ if (next > 0)
53200
+ local.set(key, next);
53201
+ else
53202
+ local.delete(key);
53203
+ if (provider !== undefined) {
53204
+ const providerCount = (providers.get(provider) ?? 0) - 1;
53205
+ if (providerCount > 0)
53206
+ providers.set(provider, providerCount);
53207
+ else
53208
+ providers.delete(provider);
53209
+ }
53210
+ coord.gauge.release(PREFIX6 + key);
53211
+ };
53212
+ },
53213
+ counts() {
53214
+ const out = new Map(local);
53215
+ for (const [key, count2] of remote) {
53216
+ if (count2 > (out.get(key) ?? 0))
53217
+ out.set(key, count2);
53218
+ }
53219
+ return out;
53220
+ },
53221
+ localCounts() {
53222
+ return new Map(providers);
53223
+ },
53224
+ async refresh() {
53225
+ const held = await coord.gauge.snapshot(PREFIX6);
53226
+ const sample = new Map;
53227
+ for (const [key, count2] of held)
53228
+ sample.set(key.slice(PREFIX6.length), count2);
53229
+ remote = sample;
53230
+ }
53231
+ };
53232
+ }
53233
+
51504
53234
  // apps/gateway/src/dispatch/snapshotCache.ts
51505
53235
  function createRoutingSnapshotCache(store, logger2 = noopLogger) {
51506
53236
  let snapshot = null;
@@ -51571,7 +53301,7 @@ function createRoutingSnapshotCache(store, logger2 = noopLogger) {
51571
53301
  }
51572
53302
 
51573
53303
  // apps/gateway/src/egress/anthropic.ts
51574
- var STOP_REASON2 = {
53304
+ var STOP_REASON3 = {
51575
53305
  endTurn: "end_turn",
51576
53306
  maxTokens: "max_tokens",
51577
53307
  stopSequence: "stop_sequence",
@@ -51668,7 +53398,7 @@ async function* anthropicStream(events, requestId) {
51668
53398
  case "end":
51669
53399
  yield frame("message_delta", {
51670
53400
  type: "message_delta",
51671
- delta: { stop_reason: STOP_REASON2[event.stopReason], stop_sequence: null },
53401
+ delta: { stop_reason: STOP_REASON3[event.stopReason], stop_sequence: null },
51672
53402
  usage: {
51673
53403
  input_tokens: event.usage.inputTokens,
51674
53404
  output_tokens: event.usage.outputTokens,
@@ -51711,7 +53441,7 @@ function anthropicResponse(collected, requestId) {
51711
53441
  return { type: "text", text: "" };
51712
53442
  }
51713
53443
  }),
51714
- stop_reason: STOP_REASON2[collected.stopReason],
53444
+ stop_reason: STOP_REASON3[collected.stopReason],
51715
53445
  stop_sequence: null,
51716
53446
  usage: {
51717
53447
  input_tokens: collected.usage.inputTokens,
@@ -52339,7 +54069,7 @@ function zodDetail(issue2) {
52339
54069
  }
52340
54070
  return issue2.message;
52341
54071
  }
52342
- function isRecord7(value) {
54072
+ function isRecord8(value) {
52343
54073
  return typeof value === "object" && value !== null;
52344
54074
  }
52345
54075
  function extraFields(body2, known) {
@@ -52474,7 +54204,7 @@ async function readJson(request2) {
52474
54204
  }
52475
54205
  async function readJsonRecord(request2) {
52476
54206
  const body2 = await readJson(request2);
52477
- return isRecord7(body2) ? body2 : null;
54207
+ return isRecord8(body2) ? body2 : null;
52478
54208
  }
52479
54209
  function apiErrorResponse(error61) {
52480
54210
  const gatewayError = error61 instanceof GatewayError ? error61 : new GatewayError("INTERNAL", "internal error");
@@ -53714,10 +55444,10 @@ function classifyGrep(executable, args) {
53714
55444
  else if (argument === "-n" || argument === "--line-number")
53715
55445
  lineNumber = true;
53716
55446
  else if (["-C", "-A", "-B", "--context", "--after-context", "--before-context"].includes(argument)) {
53717
- const count = args[++index];
53718
- if (count === undefined || !/^\d+$/.test(count))
55447
+ const count2 = args[++index];
55448
+ if (count2 === undefined || !/^\d+$/.test(count2))
53719
55449
  return;
53720
- const value = Number(count);
55450
+ const value = Number(count2);
53721
55451
  if (argument === "-C" || argument === "--context") {
53722
55452
  beforeContext = value;
53723
55453
  afterContext = value;
@@ -53939,12 +55669,12 @@ class ParserBudget {
53939
55669
  constructor(inputCodeUnits) {
53940
55670
  this.inputCodeUnits = inputCodeUnits;
53941
55671
  }
53942
- chargeRecords(count) {
53943
- this.records += count;
55672
+ chargeRecords(count2) {
55673
+ this.records += count2;
53944
55674
  return this.records <= 1e5;
53945
55675
  }
53946
- chargeCodeUnits(count) {
53947
- this.codeUnits += count;
55676
+ chargeCodeUnits(count2) {
55677
+ this.codeUnits += count2;
53948
55678
  return this.codeUnits <= this.inputCodeUnits * 3;
53949
55679
  }
53950
55680
  }
@@ -54003,8 +55733,8 @@ function renderSelection(input2, selected, unit = "lines") {
54003
55733
  return renderGaps(input2, selected, (start, end) => `... ${end - start + 1} ${unit} omitted ...`);
54004
55734
  }
54005
55735
  function selectBlock(input2, selected, block) {
54006
- const count = block.end - block.start + 1;
54007
- if (!input2.budget.chargeRecords(count))
55736
+ const count2 = block.end - block.start + 1;
55737
+ if (!input2.budget.chargeRecords(count2))
54008
55738
  return false;
54009
55739
  for (let index = block.start;index <= block.end; index++)
54010
55740
  selected.add(index);
@@ -54328,8 +56058,8 @@ function renderGroups(input2, groups) {
54328
56058
  return;
54329
56059
  }
54330
56060
  if (group.entryCount > 12) {
54331
- const count = group.entryCount - 12;
54332
- if (!append(`... ${count} ${count === 1 ? "entry" : "entries"} omitted from ${group.key} ...`))
56061
+ const count2 = group.entryCount - 12;
56062
+ if (!append(`... ${count2} ${count2 === 1 ? "entry" : "entries"} omitted from ${group.key} ...`))
54333
56063
  return;
54334
56064
  }
54335
56065
  }
@@ -54352,12 +56082,12 @@ function subtreeCounts(input2, node2, classified) {
54352
56082
  let entries = 0;
54353
56083
  let ambiguous = false;
54354
56084
  for (const child of node2.children) {
54355
- const count = subtreeCounts(input2, child, classified);
54356
- if (count === undefined)
56085
+ const count2 = subtreeCounts(input2, child, classified);
56086
+ if (count2 === undefined)
54357
56087
  return;
54358
- directories += count.directories;
54359
- entries += count.entries;
54360
- ambiguous ||= count.ambiguous;
56088
+ directories += count2.directories;
56089
+ entries += count2.entries;
56090
+ ambiguous ||= count2.ambiguous;
54361
56091
  }
54362
56092
  return { directories, entries, ambiguous };
54363
56093
  }
@@ -54377,12 +56107,12 @@ function appendSubtree(input2, output2, node2, classified) {
54377
56107
  let entries = 0;
54378
56108
  let ambiguous = false;
54379
56109
  for (const child of omitted) {
54380
- const count = subtreeCounts(input2, child, classified);
54381
- if (count === undefined)
56110
+ const count2 = subtreeCounts(input2, child, classified);
56111
+ if (count2 === undefined)
54382
56112
  return false;
54383
- directories += count.directories;
54384
- entries += count.entries;
54385
- ambiguous ||= count.ambiguous;
56113
+ directories += count2.directories;
56114
+ entries += count2.entries;
56115
+ ambiguous ||= count2.ambiguous;
54386
56116
  }
54387
56117
  if (ambiguous)
54388
56118
  return false;
@@ -55060,8 +56790,8 @@ function compressTests(input2, executable = "unknown") {
55060
56790
  break;
55061
56791
  end++;
55062
56792
  }
55063
- const count = end - start + 1;
55064
- if (!input2.budget.chargeRecords(count))
56793
+ const count2 = end - start + 1;
56794
+ if (!input2.budget.chargeRecords(count2))
55065
56795
  return text;
55066
56796
  for (let index = start;index <= end; index++)
55067
56797
  selected.add(index);
@@ -55473,7 +57203,7 @@ async function routeLog(store, requestId, target, logger2 = noopLogger, broadcas
55473
57203
  }
55474
57204
  }
55475
57205
  }
55476
- async function finishLog(store, log, keyId, logger2 = noopLogger, bodies, debit, emit, broadcast) {
57206
+ async function finishLog(store, log, keyId, logger2 = noopLogger, bodies, debit, emit, broadcast, telemetry, trace) {
55477
57207
  let appended = true;
55478
57208
  try {
55479
57209
  await store.usage.append({ ...log, apiKeyId: keyId });
@@ -55517,13 +57247,106 @@ async function finishLog(store, log, keyId, logger2 = noopLogger, bodies, debit,
55517
57247
  report(logger2, "failed to publish a resource invalidation", log.id, error61);
55518
57248
  }
55519
57249
  }
55520
- if (bodies === undefined)
55521
- return;
57250
+ if (bodies !== undefined) {
57251
+ try {
57252
+ await bodies(log);
57253
+ } catch (error61) {
57254
+ report(logger2, "failed to persist request bodies", log.id, error61);
57255
+ }
57256
+ }
57257
+ try {
57258
+ telemetry?.record(log, keyId, trace ?? null);
57259
+ } catch (error61) {
57260
+ report(logger2, "failed to record request telemetry", log.id, error61);
57261
+ }
55522
57262
  try {
55523
- await bodies(log);
57263
+ telemetry?.flush(log.id, trace ?? null);
55524
57264
  } catch (error61) {
55525
- report(logger2, "failed to persist request bodies", log.id, error61);
57265
+ report(logger2, "failed to export request telemetry", log.id, error61);
57266
+ }
57267
+ }
57268
+
57269
+ // apps/gateway/src/telemetry/spans.ts
57270
+ var TRACEPARENT = /^[\da-f]{2}-([\da-f]{32})-([\da-f]{16})-([\da-f]{2})(?:-[\da-f]+)*$/i;
57271
+ var ZERO_TRACE = "0".repeat(32);
57272
+ var ZERO_SPAN = "0".repeat(16);
57273
+ function parseTraceparent(value) {
57274
+ if (value === null)
57275
+ return null;
57276
+ const match = TRACEPARENT.exec(value);
57277
+ const traceId = match?.[1]?.toLowerCase();
57278
+ const parentSpanId = match?.[2]?.toLowerCase();
57279
+ const flags = match?.[3];
57280
+ if (traceId === undefined || parentSpanId === undefined || flags === undefined)
57281
+ return null;
57282
+ if (traceId === ZERO_TRACE || parentSpanId === ZERO_SPAN)
57283
+ return null;
57284
+ return { traceId, parentSpanId, sampled: (Number.parseInt(flags, 16) & 1) === 1 };
57285
+ }
57286
+ function randomHex(bytes) {
57287
+ const out = new Uint8Array(bytes);
57288
+ crypto.getRandomValues(out);
57289
+ return [...out].map((byte2) => byte2.toString(16).padStart(2, "0")).join("");
57290
+ }
57291
+ function createTrace(opts) {
57292
+ const id = opts.id ?? (() => randomHex(8));
57293
+ return {
57294
+ startedAt: opts.startedAt,
57295
+ traceId: opts.traceparent?.traceId ?? `${id()}${id()}`.slice(0, 32),
57296
+ parentSpanId: opts.traceparent?.parentSpanId ?? null,
57297
+ spanIds: [],
57298
+ spans: [],
57299
+ activeAttempt: null,
57300
+ routeSpan: null,
57301
+ nextId: id
57302
+ };
57303
+ }
57304
+ function addSpan(trace, name, parent, startMs, endMs, attrs) {
57305
+ try {
57306
+ const id = trace.spans.length;
57307
+ trace.spanIds.push(trace.nextId());
57308
+ trace.spans.push({ id, parent, name, startMs, endMs, attrs });
57309
+ return id;
57310
+ } catch {
57311
+ return -1;
57312
+ }
57313
+ }
57314
+ function otlpAttrs(attrs) {
57315
+ const out = [];
57316
+ for (const [key, value] of Object.entries(attrs)) {
57317
+ if (value === undefined)
57318
+ continue;
57319
+ out.push(typeof value === "number" ? { key, value: { intValue: String(value) } } : { key, value: { stringValue: value } });
55526
57320
  }
57321
+ return out;
57322
+ }
57323
+ function encodeTrace(trace, serviceVersion) {
57324
+ const spans = trace.spans.map((span) => {
57325
+ const parentSpanId = span.parent === null ? trace.parentSpanId : trace.spanIds[span.parent] ?? trace.parentSpanId;
57326
+ return {
57327
+ traceId: trace.traceId,
57328
+ spanId: trace.spanIds[span.id] ?? trace.nextId(),
57329
+ ...parentSpanId === null ? {} : { parentSpanId },
57330
+ name: span.name,
57331
+ startTimeUnixNano: String(BigInt(Math.round(trace.startedAt + span.startMs)) * 1000000n),
57332
+ endTimeUnixNano: String(BigInt(Math.round(trace.startedAt + span.endMs)) * 1000000n),
57333
+ attributes: otlpAttrs(span.attrs),
57334
+ status: { code: span.attrs.code === undefined ? 0 : 2 }
57335
+ };
57336
+ });
57337
+ return {
57338
+ resourceSpans: [
57339
+ {
57340
+ resource: {
57341
+ attributes: [
57342
+ { key: "service.name", value: { stringValue: "omnigateway" } },
57343
+ { key: "service.version", value: { stringValue: serviceVersion } }
57344
+ ]
57345
+ },
57346
+ scopeSpans: [{ spans }]
57347
+ }
57348
+ ]
57349
+ };
55527
57350
  }
55528
57351
 
55529
57352
  // apps/gateway/src/dispatch/attempt.ts
@@ -55708,6 +57531,7 @@ async function dispatch(request2, deps, signal, requestId) {
55708
57531
  return fail(code, describeError(error61, "unresolvable model"));
55709
57532
  }
55710
57533
  await deps.loadRegistry.refresh();
57534
+ const routeStartedAt = deps.now();
55711
57535
  const { candidates, excluded } = rank({
55712
57536
  request: dispatchRequest,
55713
57537
  model,
@@ -55717,6 +57541,15 @@ async function dispatch(request2, deps, signal, requestId) {
55717
57541
  load: deps.loadRegistry.counts(),
55718
57542
  providers: deps.providers
55719
57543
  });
57544
+ if (deps.trace !== null && deps.trace !== undefined) {
57545
+ deps.trace.routeSpan = addSpan(deps.trace, "dispatch.route", 0, routeStartedAt - startedAt, deps.now() - startedAt, {
57546
+ candidates: candidates.length,
57547
+ ...candidates[0] === undefined ? {} : {
57548
+ chosen_provider: candidates[0].target.provider,
57549
+ chosen_model: candidates[0].target.model
57550
+ }
57551
+ });
57552
+ }
55720
57553
  logger2.debug("routing candidates ranked", {
55721
57554
  requestId,
55722
57555
  requestedModel: request2.model,
@@ -55744,7 +57577,7 @@ async function dispatch(request2, deps, signal, requestId) {
55744
57577
  const eager = {
55745
57578
  credentialId: head.credential.id,
55746
57579
  model: head.target.model,
55747
- release: deps.loadRegistry.acquire(head.credential.id, head.target.model)
57580
+ release: deps.loadRegistry.acquire(head.credential.id, head.target.model, head.target.provider)
55748
57581
  };
55749
57582
  let eagerHeld = true;
55750
57583
  releaseOnAbort = () => eager.release();
@@ -55755,7 +57588,14 @@ async function dispatch(request2, deps, signal, requestId) {
55755
57588
  const persistHealth = async (candidate, transition) => {
55756
57589
  const credentialId = candidate.credential.id;
55757
57590
  const { model: model2 } = candidate.target;
55758
- await deps.store.credentials.updateHealth(credentialId, model2, (current) => transition(current ?? blankHealth(credentialId, model2)));
57591
+ await deps.store.credentials.updateHealth(credentialId, model2, (current) => {
57592
+ const before = current ?? blankHealth(credentialId, model2);
57593
+ const after = transition(before);
57594
+ try {
57595
+ deps.telemetry?.breaker(candidate.target.provider, before.breakerState, after.breakerState);
57596
+ } catch {}
57597
+ return after;
57598
+ });
55759
57599
  };
55760
57600
  async function* run() {
55761
57601
  try {
@@ -55774,7 +57614,17 @@ async function dispatch(request2, deps, signal, requestId) {
55774
57614
  const adoptable = eagerHeld && eager.credentialId === candidate.credential.id && eager.model === candidate.target.model;
55775
57615
  if (adoptable)
55776
57616
  eagerHeld = false;
55777
- const releaseSlot = adoptable ? eager.release : deps.loadRegistry.acquire(candidate.credential.id, candidate.target.model);
57617
+ const releaseSlot = adoptable ? eager.release : deps.loadRegistry.acquire(candidate.credential.id, candidate.target.model, candidate.target.provider);
57618
+ const attemptStartedAt = deps.now();
57619
+ let attemptCode;
57620
+ if (deps.trace !== null && deps.trace !== undefined) {
57621
+ deps.trace.activeAttempt = addSpan(deps.trace, "dispatch.attempt", 0, attemptStartedAt - startedAt, attemptStartedAt - startedAt, {
57622
+ attempt: i + 1,
57623
+ provider: candidate.target.provider,
57624
+ model: candidate.target.model,
57625
+ credential_id: candidate.credential.id
57626
+ });
57627
+ }
55778
57628
  try {
55779
57629
  log.attempts = i + 1;
55780
57630
  log.credentialId = candidate.credential.id;
@@ -55838,6 +57688,9 @@ async function dispatch(request2, deps, signal, requestId) {
55838
57688
  if (event.type === "blockDelta" && !committed) {
55839
57689
  committed = true;
55840
57690
  log.ttftMs = deps.now() - startedAt;
57691
+ if (deps.trace !== null && deps.trace !== undefined && deps.trace.activeAttempt !== null) {
57692
+ addSpan(deps.trace, "stream.commit", deps.trace.activeAttempt, log.ttftMs, log.ttftMs, { provider: candidate.target.provider, model: candidate.target.model });
57693
+ }
55841
57694
  logger2.debug("stream committed", {
55842
57695
  requestId,
55843
57696
  provider: candidate.target.provider,
@@ -55920,6 +57773,7 @@ async function dispatch(request2, deps, signal, requestId) {
55920
57773
  throw signal.reason;
55921
57774
  const classifiedError = deadlineAt !== null && dispatchSignal.aborted ? { code: "TIMEOUT" } : classify(error61);
55922
57775
  const { code: code2 } = classifiedError;
57776
+ attemptCode = code2;
55923
57777
  const message2 = describeError(error61, "attempt failed");
55924
57778
  lastError = rewrap(classifiedError, message2);
55925
57779
  if (error61 instanceof GatewayError)
@@ -55993,6 +57847,15 @@ async function dispatch(request2, deps, signal, requestId) {
55993
57847
  }
55994
57848
  }
55995
57849
  } finally {
57850
+ if (deps.trace !== null && deps.trace !== undefined && deps.trace.activeAttempt !== null) {
57851
+ const span = deps.trace.spans[deps.trace.activeAttempt];
57852
+ if (span !== undefined) {
57853
+ span.endMs = deps.now() - startedAt;
57854
+ if (attemptCode !== undefined)
57855
+ span.attrs = { ...span.attrs, code: attemptCode };
57856
+ }
57857
+ deps.trace.activeAttempt = null;
57858
+ }
55996
57859
  releaseSlot();
55997
57860
  }
55998
57861
  }
@@ -56064,48 +57927,6 @@ function waitForCancellation(promise2, signal) {
56064
57927
  });
56065
57928
  }
56066
57929
 
56067
- // apps/gateway/src/dispatch/loadRegistry.ts
56068
- var PREFIX6 = "load:";
56069
- var SLOT_TTL_MS = 300000;
56070
- function createLoadRegistry(coord = memoryCoord()) {
56071
- const local = new Map;
56072
- let remote = new Map;
56073
- return {
56074
- acquire(credentialId, model) {
56075
- const key = healthKey(credentialId, model);
56076
- local.set(key, (local.get(key) ?? 0) + 1);
56077
- coord.gauge.acquire(PREFIX6 + key, SLOT_TTL_MS);
56078
- let released = false;
56079
- return () => {
56080
- if (released)
56081
- return;
56082
- released = true;
56083
- const next = (local.get(key) ?? 0) - 1;
56084
- if (next > 0)
56085
- local.set(key, next);
56086
- else
56087
- local.delete(key);
56088
- coord.gauge.release(PREFIX6 + key);
56089
- };
56090
- },
56091
- counts() {
56092
- const out = new Map(local);
56093
- for (const [key, count] of remote) {
56094
- if (count > (out.get(key) ?? 0))
56095
- out.set(key, count);
56096
- }
56097
- return out;
56098
- },
56099
- async refresh() {
56100
- const held = await coord.gauge.snapshot(PREFIX6);
56101
- const sample = new Map;
56102
- for (const [key, count] of held)
56103
- sample.set(key.slice(PREFIX6.length), count);
56104
- remote = sample;
56105
- }
56106
- };
56107
- }
56108
-
56109
57930
  // apps/gateway/src/ingress/anthropicTools.ts
56110
57931
  var TOOL_FIELDS = {
56111
57932
  cache_control: cacheControlSchema.nullable(),
@@ -56623,10 +58444,10 @@ function toIrToolChoice(c) {
56623
58444
  }
56624
58445
  var EFFORTS = REASONING_EFFORTS;
56625
58446
  function readEffort(body2) {
56626
- if (!isRecord7(body2))
58447
+ if (!isRecord8(body2))
56627
58448
  return;
56628
58449
  const outputConfig = body2.output_config;
56629
- if (!isRecord7(outputConfig))
58450
+ if (!isRecord8(outputConfig))
56630
58451
  return;
56631
58452
  const effort = outputConfig.effort;
56632
58453
  return EFFORTS.find((level) => level === effort);
@@ -56921,7 +58742,7 @@ function parseOpenAIRequest(body2, headers) {
56921
58742
  }
56922
58743
 
56923
58744
  // apps/gateway/src/ingress/responses.ts
56924
- import { createHash as createHash5 } from "crypto";
58745
+ import { createHash as createHash7 } from "crypto";
56925
58746
  var reasoning = exports_external.object({
56926
58747
  effort: exports_external.enum(REASONING_EFFORTS).optional(),
56927
58748
  summary: exports_external.string().optional()
@@ -56987,7 +58808,7 @@ function toIrReasoning2(r) {
56987
58808
  };
56988
58809
  }
56989
58810
  function clampCallId(raw) {
56990
- return raw.length <= 64 ? raw : createHash5("sha256").update(raw).digest("hex");
58811
+ return raw.length <= 64 ? raw : createHash7("sha256").update(raw).digest("hex");
56991
58812
  }
56992
58813
  function roleOf(raw) {
56993
58814
  if (raw === "assistant")
@@ -56997,7 +58818,7 @@ function roleOf(raw) {
56997
58818
  return "user";
56998
58819
  }
56999
58820
  function contentPart(part2) {
57000
- if (!isRecord7(part2))
58821
+ if (!isRecord8(part2))
57001
58822
  throw new GatewayError("BAD_REQUEST", "input: content part must be an object");
57002
58823
  const type = part2.type;
57003
58824
  if (type === "input_text" || type === "output_text") {
@@ -57037,7 +58858,7 @@ function readInputItems(items) {
57037
58858
  messages.push({ role, content });
57038
58859
  };
57039
58860
  for (const raw of items) {
57040
- if (!isRecord7(raw))
58861
+ if (!isRecord8(raw))
57041
58862
  throw new GatewayError("BAD_REQUEST", "input: item must be an object");
57042
58863
  const type = raw.type ?? (raw.role === undefined ? undefined : "message");
57043
58864
  switch (type) {
@@ -57093,7 +58914,7 @@ function jsonArguments(raw, callId) {
57093
58914
  const text = typeof raw === "string" ? raw : "";
57094
58915
  try {
57095
58916
  const parsed2 = text === "" ? {} : JSON.parse(text);
57096
- return isRecord7(parsed2) ? parsed2 : { value: parsed2 };
58917
+ return isRecord8(parsed2) ? parsed2 : { value: parsed2 };
57097
58918
  } catch {
57098
58919
  throw new GatewayError("BAD_REQUEST", `input: arguments for call ${safeToken(callId)} are not valid JSON`);
57099
58920
  }
@@ -57102,7 +58923,7 @@ var TOOL_NAME = /^[A-Za-z0-9_-]{1,128}$/;
57102
58923
  function readTools(raw) {
57103
58924
  const tools2 = [];
57104
58925
  for (const entry of raw) {
57105
- if (!isRecord7(entry))
58926
+ if (!isRecord8(entry))
57106
58927
  throw new GatewayError("BAD_REQUEST", "tools: each tool must be an object");
57107
58928
  const type = typeof entry.type === "string" ? entry.type : "";
57108
58929
  const declared = typeof entry.name === "string" ? entry.name : "";
@@ -57115,7 +58936,7 @@ function readTools(raw) {
57115
58936
  kind: "portable",
57116
58937
  name: declared,
57117
58938
  ...description === undefined ? {} : { description },
57118
- inputSchema: type === "custom" ? { type: "object", properties: { input: { type: "string" } }, required: ["input"] } : isRecord7(entry.parameters) ? entry.parameters : { type: "object" }
58939
+ inputSchema: type === "custom" ? { type: "object", properties: { input: { type: "string" } }, required: ["input"] } : isRecord8(entry.parameters) ? entry.parameters : { type: "object" }
57119
58940
  });
57120
58941
  continue;
57121
58942
  }
@@ -57130,10 +58951,10 @@ function readTools(raw) {
57130
58951
  }
57131
58952
  function customToolNames(body2) {
57132
58953
  const names = new Set;
57133
- if (!isRecord7(body2) || !Array.isArray(body2.tools))
58954
+ if (!isRecord8(body2) || !Array.isArray(body2.tools))
57134
58955
  return names;
57135
58956
  for (const entry of body2.tools) {
57136
- if (isRecord7(entry) && entry.type === "custom" && typeof entry.name === "string") {
58957
+ if (isRecord8(entry) && entry.type === "custom" && typeof entry.name === "string") {
57137
58958
  names.add(entry.name);
57138
58959
  }
57139
58960
  }
@@ -57330,6 +59151,7 @@ async function bodyCollectorFor(deps, key) {
57330
59151
  async function handle(deps, rateLimiter, surface, request2) {
57331
59152
  const requestId = deps.requestId();
57332
59153
  const startedAt = deps.now();
59154
+ const trace = deps.telemetry?.startRequest(requestId, startedAt, request2.headers.get("traceparent"), surface, deps.rand()) ?? null;
57333
59155
  let keyId = null;
57334
59156
  let requestedModel = "";
57335
59157
  let outcome = null;
@@ -57411,6 +59233,7 @@ async function handle(deps, rateLimiter, surface, request2) {
57411
59233
  const dispatched = await dispatch(chatRequest, {
57412
59234
  ...deps,
57413
59235
  ...captured === null ? {} : { http: captured.wrap(deps.http) },
59236
+ trace,
57414
59237
  async onRoute(target) {
57415
59238
  if (began) {
57416
59239
  await routeLog(deps.store, requestId, target, deps.logger, deps.broadcaster);
@@ -57448,7 +59271,7 @@ async function handle(deps, rateLimiter, surface, request2) {
57448
59271
  reportRejection(deps.logger, requestId, completed, gatewayError, surface);
57449
59272
  }
57450
59273
  logged = true;
57451
- await finishLog(deps.store, completed, keyId, deps.logger, writeBodies, debit, deps.emit, deps.broadcaster);
59274
+ await finishLog(deps.store, completed, keyId, deps.logger, writeBodies, debit, deps.emit, deps.broadcaster, deps.telemetry, trace);
57452
59275
  };
57453
59276
  if (chatRequest.stream) {
57454
59277
  const frames = surface === "anthropic" ? anthropicStream(dispatched.events, requestId) : surface === "responses" ? responsesStream(dispatched.events, render2()) : openaiStream(dispatched.events, requestId, Math.floor(deps.now() / 1000));
@@ -57489,7 +59312,7 @@ async function handle(deps, rateLimiter, surface, request2) {
57489
59312
  if (collector !== null && !logged)
57490
59313
  collector.client.response = rejection;
57491
59314
  if (!logged)
57492
- await finishLog(deps.store, completed, keyId, deps.logger, writeBodies, debit, deps.emit, deps.broadcaster);
59315
+ await finishLog(deps.store, completed, keyId, deps.logger, writeBodies, debit, deps.emit, deps.broadcaster, deps.telemetry, trace);
57493
59316
  if (!cancelled)
57494
59317
  reportRejection(deps.logger, requestId, completed, gatewayError, surface);
57495
59318
  return jsonResponse(rejection, HTTP_STATUS[gatewayError.code], {
@@ -57770,11 +59593,11 @@ function topicClass(topic) {
57770
59593
  return null;
57771
59594
  }
57772
59595
  var MAX_TOPIC = 128;
57773
- function isRecord8(value) {
59596
+ function isRecord9(value) {
57774
59597
  return typeof value === "object" && value !== null && !Array.isArray(value);
57775
59598
  }
57776
59599
  function parseClientFrame(raw) {
57777
- if (!isRecord8(raw))
59600
+ if (!isRecord9(raw))
57778
59601
  return null;
57779
59602
  const { id, type, topic } = raw;
57780
59603
  if (id !== undefined && typeof id !== "string")
@@ -57980,16 +59803,16 @@ function createChannelRegistry(deps) {
57980
59803
  cancelReport = undefined;
57981
59804
  if (!live)
57982
59805
  return;
57983
- for (const [pluginId, count] of dropsSinceReport) {
57984
- logger2.warn("plugin channel broadcast dropped", { plugin: pluginId, count });
59806
+ for (const [pluginId, count2] of dropsSinceReport) {
59807
+ logger2.warn("plugin channel broadcast dropped", { plugin: pluginId, count: count2 });
57985
59808
  }
57986
59809
  dropsSinceReport.clear();
57987
- for (const [pluginId, count] of unencodableSinceReport) {
57988
- logger2.warn("plugin channel payload could not be serialised", { plugin: pluginId, count });
59810
+ for (const [pluginId, count2] of unencodableSinceReport) {
59811
+ logger2.warn("plugin channel payload could not be serialised", { plugin: pluginId, count: count2 });
57989
59812
  }
57990
59813
  unencodableSinceReport.clear();
57991
- for (const [pluginId, count] of errorsSinceReport) {
57992
- logger2.warn("plugin channel handler failed", { plugin: pluginId, count });
59814
+ for (const [pluginId, count2] of errorsSinceReport) {
59815
+ logger2.warn("plugin channel handler failed", { plugin: pluginId, count: count2 });
57993
59816
  }
57994
59817
  errorsSinceReport.clear();
57995
59818
  };
@@ -58457,7 +60280,7 @@ function createRing(limits) {
58457
60280
  }
58458
60281
 
58459
60282
  // apps/gateway/src/version.ts
58460
- var VERSION = "0.9.1";
60283
+ var VERSION = "0.10.0";
58461
60284
 
58462
60285
  // apps/gateway/src/app.ts
58463
60286
  var ADMIN_SESSION_TTL_MS = 12 * 60 * 60 * 1000;
@@ -58495,10 +60318,22 @@ function createApp(deps) {
58495
60318
  const nodeId = deps.nodeId ?? crypto.randomUUID();
58496
60319
  const logger2 = deps.logger ?? noopLogger;
58497
60320
  const rand = deps.rand ?? Math.random;
58498
- const http = deps.http ?? nodeHttpClient({ logger: logger2, now });
60321
+ const http = deps.http ?? nodeHttpClient({
60322
+ logger: logger2,
60323
+ now,
60324
+ ...deps.telemetry === undefined ? {} : { onResponseHead: deps.telemetry.httpHead }
60325
+ });
58499
60326
  const adapters = deps.adapters ?? ADAPTERS;
58500
60327
  const requestId = deps.requestId ?? (() => `req_${crypto.randomUUID()}`);
58501
- const rateLimiter = deps.rateLimiter ?? new ApiKeyRateLimiter({ store: deps.store, now, logger: logger2, coord });
60328
+ const loadRegistry = deps.loadRegistry ?? createLoadRegistry(coord);
60329
+ const telemetry = deps.telemetry;
60330
+ const rateLimiter = deps.rateLimiter ?? new ApiKeyRateLimiter({
60331
+ store: deps.store,
60332
+ now,
60333
+ logger: logger2,
60334
+ coord,
60335
+ ...telemetry === undefined ? {} : { onRejected: telemetry.rateLimit }
60336
+ });
58502
60337
  const snapshots = createRoutingSnapshotCache(deps.store, logger2);
58503
60338
  const ROUTING_TOPIC = "routing";
58504
60339
  deps.store.routing.subscribe((change) => {
@@ -58563,7 +60398,17 @@ function createApp(deps) {
58563
60398
  ok: true,
58564
60399
  mode: deps.mode ?? "single",
58565
60400
  nodeId,
58566
- coord: "healthy" in coord && !coord.healthy() ? "fallback" : "ok"
60401
+ coord: deps.coordHealthy?.() === false ? "fallback" : "ok"
60402
+ })).use(deps.metricsToken === undefined || telemetry === undefined ? new Elysia : new Elysia().get("/metrics", ({ request: request2 }) => {
60403
+ const supplied = request2.headers.get("authorization");
60404
+ const expected = `Bearer ${deps.metricsToken}`;
60405
+ const actualBytes = Buffer.from(supplied ?? "");
60406
+ const expectedBytes = Buffer.from(expected);
60407
+ if (actualBytes.length !== expectedBytes.length || !timingSafeEqual(actualBytes, expectedBytes)) {
60408
+ return new Response(null, { status: 401 });
60409
+ }
60410
+ const coordFallback = deps.coordHealthy?.() === false;
60411
+ return new Response(telemetry.scrape(loadRegistry.localCounts?.() ?? new Map, registry2.stats(), coordFallback), { headers: { "content-type": "text/plain; version=0.0.4; charset=utf-8" } });
58567
60412
  })).use(proxyRoutes({
58568
60413
  store: deps.store,
58569
60414
  snapshots,
@@ -58576,9 +60421,10 @@ function createApp(deps) {
58576
60421
  rateLimiter,
58577
60422
  logger: logger2,
58578
60423
  coord,
58579
- ...deps.loadRegistry === undefined ? {} : { loadRegistry: deps.loadRegistry },
60424
+ loadRegistry,
58580
60425
  bodyLoggingAllowed: deps.bodyLoggingAllowed === true,
58581
60426
  ...deps.emit === undefined ? {} : { emit: deps.emit },
60427
+ ...telemetry === undefined ? {} : { telemetry },
58582
60428
  broadcaster
58583
60429
  })).use(adminRoutes({
58584
60430
  store: deps.store,
@@ -59188,9 +61034,9 @@ function startMaintenance(deps) {
59188
61034
  });
59189
61035
  }, SWEEP_INTERVAL_MS2);
59190
61036
  const prune = async () => {
59191
- await deps.store.usage.sweepPending(deps.now()).then((count) => {
59192
- if (count > 0)
59193
- logger2.info("retired interrupted requests", { count });
61037
+ await deps.store.usage.sweepPending(deps.now()).then((count2) => {
61038
+ if (count2 > 0)
61039
+ logger2.info("retired interrupted requests", { count: count2 });
59194
61040
  }).catch((error61) => {
59195
61041
  logger2.error("pending sweep failed", { reason: describeError(error61, "unknown") });
59196
61042
  });
@@ -59315,8 +61161,8 @@ function createPluginEventBus(opts) {
59315
61161
  }
59316
61162
  }
59317
61163
  }
59318
- for (const [pluginId, count] of errorsSinceReport) {
59319
- logger2.warn("plugin event handler failed", { plugin: pluginId, count });
61164
+ for (const [pluginId, count2] of errorsSinceReport) {
61165
+ logger2.warn("plugin event handler failed", { plugin: pluginId, count: count2 });
59320
61166
  }
59321
61167
  errorsSinceReport.clear();
59322
61168
  if (droppedSinceReport > 0) {
@@ -59847,6 +61693,340 @@ function startJournalPoll(deps, source, logger2) {
59847
61693
  };
59848
61694
  }
59849
61695
 
61696
+ // apps/gateway/src/telemetry/otlp.ts
61697
+ function createOtlpExporter(opts) {
61698
+ const queue = [];
61699
+ const send = opts.fetch ?? fetch;
61700
+ const schedule = opts.schedule ?? ((run, ms) => {
61701
+ const timer = setInterval(run, ms);
61702
+ timer.unref?.();
61703
+ return () => clearInterval(timer);
61704
+ });
61705
+ let reporting = false;
61706
+ const exporter = {
61707
+ enqueue(trace) {
61708
+ try {
61709
+ const encoded = JSON.stringify(encodeTrace(trace, opts.version ?? "unknown"));
61710
+ if (queue.length >= opts.capacity) {
61711
+ opts.registry.add("omni_otlp_spans_dropped_total", { reason: "queue_full" });
61712
+ return;
61713
+ }
61714
+ queue.push(encoded);
61715
+ } catch {
61716
+ opts.registry.add("omni_otlp_spans_dropped_total", { reason: "encode" });
61717
+ }
61718
+ },
61719
+ async flush() {
61720
+ if (queue.length === 0)
61721
+ return;
61722
+ const encoded = queue.splice(0, opts.batchMax);
61723
+ try {
61724
+ const bodies = encoded.map((body2) => JSON.parse(body2));
61725
+ const resourceSpans = bodies.flatMap((body2) => body2.resourceSpans);
61726
+ const response = await send(`${opts.endpoint.replace(/\/+$/, "")}/v1/traces`, {
61727
+ method: "POST",
61728
+ headers: { "content-type": "application/json", ...opts.headers },
61729
+ body: JSON.stringify({ resourceSpans })
61730
+ });
61731
+ if (!response.ok)
61732
+ throw new Error(`collector returned ${response.status}`);
61733
+ reporting = false;
61734
+ } catch {
61735
+ if (!reporting)
61736
+ opts.logger?.warn("trace export failed", { reason: "collector unavailable" });
61737
+ reporting = true;
61738
+ }
61739
+ },
61740
+ queued: () => queue.length,
61741
+ stop() {
61742
+ cancel();
61743
+ }
61744
+ };
61745
+ const cancel = schedule(() => void exporter.flush(), opts.intervalMs);
61746
+ return exporter;
61747
+ }
61748
+
61749
+ // apps/gateway/src/telemetry/registry.ts
61750
+ var DEFINITIONS = {
61751
+ omni_requests_total: { help: "Requests completed by this process.", type: "counter" },
61752
+ omni_request_duration_seconds: { help: "Request duration in seconds.", type: "histogram" },
61753
+ omni_ttft_seconds: { help: "Streaming time to first token in seconds.", type: "histogram" },
61754
+ omni_tokens_total: { help: "Billable tokens completed by this process.", type: "counter" },
61755
+ omni_cost_usd_total: { help: "Request cost in US dollars.", type: "counter" },
61756
+ omni_upstream_duration_seconds: {
61757
+ help: "Provider response-head duration in seconds.",
61758
+ type: "histogram"
61759
+ },
61760
+ omni_inflight: { help: "Provider requests in flight in this process.", type: "gauge" },
61761
+ omni_breaker_open: { help: "Credential breakers observed open in this process.", type: "gauge" },
61762
+ omni_ratelimit_rejected_total: { help: "API-key rate-limit refusals.", type: "counter" },
61763
+ omni_stream_connections: { help: "Live stream connections in this process.", type: "gauge" },
61764
+ omni_stream_queued: { help: "Stream frames queued in this process.", type: "gauge" },
61765
+ omni_stream_dropped_total: { help: "Stream frames dropped in this process.", type: "counter" },
61766
+ omni_coord_fallback: {
61767
+ help: "Whether this process is using coordination fallback.",
61768
+ type: "gauge"
61769
+ },
61770
+ omni_metrics_series_folded_total: {
61771
+ help: "Metric series folded into api_key_id other.",
61772
+ type: "counter"
61773
+ },
61774
+ omni_otlp_spans_dropped_total: { help: "Spans dropped before OTLP export.", type: "counter" },
61775
+ omni_build_info: { help: "Gateway build information.", type: "gauge" }
61776
+ };
61777
+ var HISTOGRAM_BUCKETS = [0.005, 0.01, 0.025, 0.05, 0.1, 0.25, 0.5, 1, 2.5, 5, 10, 30, 60];
61778
+ function labelKey(labels) {
61779
+ return Object.entries(labels).sort(([a], [b]) => a.localeCompare(b)).map(([key, value]) => `${key.length}:${key}${value.length}:${value}`).join("");
61780
+ }
61781
+ function createMetricRegistry(opts) {
61782
+ const series = new Map;
61783
+ const rawSeries = new Set;
61784
+ const folded = new Set;
61785
+ const normalize = (name, labels) => {
61786
+ const copy = { ...labels };
61787
+ const raw = `${name}:${labelKey(copy)}`;
61788
+ if (rawSeries.has(raw))
61789
+ return copy;
61790
+ if (rawSeries.size < opts.maxSeries || copy.api_key_id === undefined) {
61791
+ rawSeries.add(raw);
61792
+ return copy;
61793
+ }
61794
+ copy.api_key_id = "other";
61795
+ if (!folded.has(raw)) {
61796
+ folded.add(raw);
61797
+ change("omni_metrics_series_folded_total", {}, 1, false);
61798
+ }
61799
+ return copy;
61800
+ };
61801
+ const change = (name, labels, value, replace) => {
61802
+ const normalized = normalize(name, labels);
61803
+ const key = labelKey(normalized);
61804
+ const table = series.get(name) ?? new Map;
61805
+ const current = table.get(key) ?? { labels: normalized, value: 0 };
61806
+ current.value = replace ? value : current.value + value;
61807
+ table.set(key, current);
61808
+ series.set(name, table);
61809
+ return current;
61810
+ };
61811
+ return {
61812
+ add(name, labels, value = 1) {
61813
+ change(name, labels, value, false);
61814
+ },
61815
+ set(name, labels, value) {
61816
+ change(name, labels, value, true);
61817
+ },
61818
+ observe(name, value, labels) {
61819
+ const current = change(name, labels, value, false);
61820
+ current.count = (current.count ?? 0) + 1;
61821
+ const buckets = current.buckets ?? HISTOGRAM_BUCKETS.map(() => 0);
61822
+ for (let i = 0;i < HISTOGRAM_BUCKETS.length; i++) {
61823
+ if (value <= HISTOGRAM_BUCKETS[i])
61824
+ buckets[i] = (buckets[i] ?? 0) + 1;
61825
+ }
61826
+ current.buckets = buckets;
61827
+ },
61828
+ value(name, labels) {
61829
+ return series.get(name)?.get(labelKey(labels))?.value ?? 0;
61830
+ },
61831
+ snapshot() {
61832
+ return {
61833
+ at: opts.now(),
61834
+ metrics: Object.entries(DEFINITIONS).map(([name, definition]) => ({
61835
+ name,
61836
+ ...definition,
61837
+ samples: [...series.get(name)?.values() ?? []].map((sample) => definition.type === "histogram" ? {
61838
+ labels: sample.labels,
61839
+ value: sample.value,
61840
+ sum: sample.value,
61841
+ count: sample.count ?? 0,
61842
+ buckets: sample.buckets ?? HISTOGRAM_BUCKETS.map(() => 0)
61843
+ } : { labels: sample.labels, value: sample.value })
61844
+ })).filter((metric) => metric.samples.length > 0)
61845
+ };
61846
+ }
61847
+ };
61848
+ }
61849
+
61850
+ // apps/gateway/src/telemetry/render.ts
61851
+ function escapeLabel(value) {
61852
+ return value.replaceAll("\\", "\\\\").replaceAll(`
61853
+ `, "\\n").replaceAll('"', "\\\"");
61854
+ }
61855
+ function labels(labels2, extra) {
61856
+ const entries = Object.entries(labels2);
61857
+ if (extra !== undefined)
61858
+ entries.push([extra[0], extra[1]]);
61859
+ if (entries.length === 0)
61860
+ return "";
61861
+ return `{${entries.map(([key, value]) => `${key}="${escapeLabel(value)}"`).join(",")}}`;
61862
+ }
61863
+ function number4(value) {
61864
+ if (value === Number.POSITIVE_INFINITY)
61865
+ return "+Inf";
61866
+ if (value === Number.NEGATIVE_INFINITY)
61867
+ return "-Inf";
61868
+ if (Number.isNaN(value))
61869
+ return "NaN";
61870
+ return String(value);
61871
+ }
61872
+ function renderPrometheus(snapshot) {
61873
+ const out = [];
61874
+ for (const metric of snapshot.metrics) {
61875
+ out.push(`# HELP ${metric.name} ${metric.help}`, `# TYPE ${metric.name} ${metric.type}`);
61876
+ for (const sample of metric.samples) {
61877
+ if (metric.type !== "histogram" || !("buckets" in sample)) {
61878
+ out.push(`${metric.name}${labels(sample.labels)} ${number4(sample.value)}`);
61879
+ continue;
61880
+ }
61881
+ for (let i = 0;i < HISTOGRAM_BUCKETS.length; i++) {
61882
+ out.push(`${metric.name}_bucket${labels(sample.labels, ["le", String(HISTOGRAM_BUCKETS[i])])} ${number4(sample.buckets[i] ?? 0)}`);
61883
+ }
61884
+ out.push(`${metric.name}_bucket${labels(sample.labels, ["le", "+Inf"])} ${sample.count}`, `${metric.name}_sum${labels(sample.labels)} ${number4(sample.sum)}`, `${metric.name}_count${labels(sample.labels)} ${sample.count}`);
61885
+ }
61886
+ }
61887
+ return `${out.join(`
61888
+ `)}
61889
+ `;
61890
+ }
61891
+
61892
+ // apps/gateway/src/telemetry/index.ts
61893
+ function parseOtlpHeaders(value) {
61894
+ const headers = {};
61895
+ if (value === null)
61896
+ return headers;
61897
+ for (const entry of value.split(",")) {
61898
+ const at = entry.indexOf("=");
61899
+ if (at <= 0)
61900
+ continue;
61901
+ const key = entry.slice(0, at).trim();
61902
+ if (key.length > 0)
61903
+ headers[key] = entry.slice(at + 1).trim();
61904
+ }
61905
+ return headers;
61906
+ }
61907
+ function codeAttr(value) {
61908
+ return value === "interrupted" || /^[A-Z_]{1,32}$/.test(value) ? { code: value } : {};
61909
+ }
61910
+ function createTelemetry(opts) {
61911
+ const registry2 = createMetricRegistry({ maxSeries: opts.maxSeries, now: opts.now });
61912
+ const traces = new Map;
61913
+ const openBreakers = new Map;
61914
+ const exporter = opts.exporter ?? (opts.otlpEndpoint === null ? null : createOtlpExporter({
61915
+ endpoint: opts.otlpEndpoint,
61916
+ headers: opts.otlpHeaders,
61917
+ capacity: 1e4,
61918
+ batchMax: 512,
61919
+ intervalMs: 5000,
61920
+ registry: registry2,
61921
+ ...opts.logger === undefined ? {} : { logger: opts.logger },
61922
+ version: opts.version
61923
+ }));
61924
+ if (opts.metricsEnabled)
61925
+ registry2.set("omni_build_info", { version: opts.version }, 1);
61926
+ return {
61927
+ metricsEnabled: opts.metricsEnabled,
61928
+ tracingEnabled: exporter !== null,
61929
+ registry: registry2,
61930
+ startRequest(requestId, startedAt, traceparent, surface, rand) {
61931
+ if (exporter === null)
61932
+ return null;
61933
+ const inbound = parseTraceparent(traceparent);
61934
+ if (inbound !== null ? !inbound.sampled : rand >= opts.traceSample)
61935
+ return null;
61936
+ const trace = createTrace({ startedAt, traceparent: inbound });
61937
+ addSpan(trace, "gateway.request", null, 0, 0, { surface });
61938
+ traces.set(requestId, trace);
61939
+ return trace;
61940
+ },
61941
+ record(log, keyId, trace) {
61942
+ if (opts.metricsEnabled) {
61943
+ const provider = log.resolvedProvider ?? "";
61944
+ const model = log.resolvedModel ?? log.requestedModel;
61945
+ const key = keyId ?? "";
61946
+ registry2.add("omni_requests_total", {
61947
+ provider,
61948
+ model,
61949
+ status: String(log.status),
61950
+ code: log.errorCode ?? "",
61951
+ api_key_id: key
61952
+ });
61953
+ registry2.observe("omni_request_duration_seconds", log.durationMs / 1000, {
61954
+ provider,
61955
+ model
61956
+ });
61957
+ if (log.ttftMs !== null)
61958
+ registry2.observe("omni_ttft_seconds", log.ttftMs / 1000, { provider, model });
61959
+ for (const [kind, value] of [
61960
+ ["input", log.inputTokens],
61961
+ ["output", log.outputTokens],
61962
+ ["cache_read", log.cacheReadTokens],
61963
+ ["cache_write", log.cacheWriteTokens]
61964
+ ]) {
61965
+ registry2.add("omni_tokens_total", { provider, model, api_key_id: key, kind }, value);
61966
+ }
61967
+ registry2.add("omni_cost_usd_total", { provider, model, api_key_id: key }, log.costUsd);
61968
+ }
61969
+ if (trace !== null) {
61970
+ const root = trace.spans[0];
61971
+ if (root !== undefined) {
61972
+ root.endMs = log.durationMs;
61973
+ root.attrs = {
61974
+ ...root.attrs,
61975
+ requested_model: log.requestedModel,
61976
+ api_key_id: keyId ?? "",
61977
+ status: log.status,
61978
+ ...log.errorCode === null ? {} : codeAttr(log.errorCode)
61979
+ };
61980
+ }
61981
+ }
61982
+ },
61983
+ flush(requestId, trace) {
61984
+ traces.delete(requestId);
61985
+ if (trace !== null)
61986
+ exporter?.enqueue(trace);
61987
+ },
61988
+ httpHead(event) {
61989
+ if (opts.metricsEnabled)
61990
+ registry2.observe("omni_upstream_duration_seconds", event.durationMs / 1000, {
61991
+ provider: event.provider
61992
+ });
61993
+ const trace = event.requestId === undefined ? undefined : traces.get(event.requestId);
61994
+ if (trace === undefined)
61995
+ return;
61996
+ const endMs = Math.max(0, opts.now() - trace.startedAt);
61997
+ addSpan(trace, "provider.http", trace.activeAttempt ?? null, Math.max(0, endMs - event.durationMs), endMs, {
61998
+ provider: event.provider,
61999
+ host: event.host,
62000
+ path: event.path,
62001
+ ...event.status === undefined ? {} : { status: event.status }
62002
+ });
62003
+ },
62004
+ breaker(provider, before, after) {
62005
+ if (!opts.metricsEnabled || before === after)
62006
+ return;
62007
+ const count2 = Math.max(0, (openBreakers.get(provider) ?? 0) + (after === "open" ? 1 : before === "open" ? -1 : 0));
62008
+ openBreakers.set(provider, count2);
62009
+ registry2.set("omni_breaker_open", { provider }, count2);
62010
+ },
62011
+ rateLimit(dimension, window2) {
62012
+ if (opts.metricsEnabled)
62013
+ registry2.add("omni_ratelimit_rejected_total", { dimension, window: window2 ?? "none" });
62014
+ },
62015
+ scrape(localInflight, streams, coordFallback) {
62016
+ for (const [provider, value] of localInflight)
62017
+ registry2.set("omni_inflight", { provider }, value);
62018
+ registry2.set("omni_stream_connections", {}, streams.connections);
62019
+ registry2.set("omni_stream_queued", {}, streams.queued);
62020
+ registry2.set("omni_stream_dropped_total", {}, streams.dropped);
62021
+ registry2.set("omni_coord_fallback", {}, coordFallback ? 1 : 0);
62022
+ return renderPrometheus(registry2.snapshot());
62023
+ },
62024
+ stop() {
62025
+ exporter?.stop();
62026
+ }
62027
+ };
62028
+ }
62029
+
59850
62030
  // apps/gateway/src/index.ts
59851
62031
  function stdoutLogger(level) {
59852
62032
  return createLogger({
@@ -59915,7 +62095,17 @@ async function main() {
59915
62095
  logger2.info("retired interrupted requests", { count: swept });
59916
62096
  const console2 = consoleSource(config2.logFile);
59917
62097
  logger2.info("console log source resolved", { reason: console2.source.kind });
59918
- const http = nodeHttpClient({ logger: logger2, now });
62098
+ const telemetry = createTelemetry({
62099
+ metricsEnabled: config2.metricsToken !== null,
62100
+ maxSeries: config2.metricsMaxSeries,
62101
+ otlpEndpoint: config2.otlpEndpoint,
62102
+ otlpHeaders: parseOtlpHeaders(config2.otlpHeaders),
62103
+ traceSample: config2.traceSample,
62104
+ now,
62105
+ version: VERSION,
62106
+ logger: logger2
62107
+ });
62108
+ const http = nodeHttpClient({ logger: logger2, now, onResponseHead: telemetry.httpHead });
59919
62109
  const shared = config2.clusterMode && config2.redisUrl !== null ? redisCoord({ url: config2.redisUrl, logger: logger2, now }) : null;
59920
62110
  const coord = shared ?? memoryCoord({ now });
59921
62111
  const lease = { coord, nodeId };
@@ -59986,6 +62176,8 @@ async function main() {
59986
62176
  broadcaster,
59987
62177
  ring: streamRing,
59988
62178
  channels: pluginChannels,
62179
+ telemetry,
62180
+ ...config2.metricsToken === null ? {} : { metricsToken: config2.metricsToken },
59989
62181
  bodyLoggingAllowed: config2.bodyLoggingAllowed,
59990
62182
  plugins: loadedPlugins.plugins.map((plugin) => ({ id: plugin.id, routes: plugin.routes })),
59991
62183
  pluginUi: loadedPlugins.plugins,
@@ -60043,6 +62235,7 @@ async function main() {
60043
62235
  streamRegistry.closeAll(1001, "restart");
60044
62236
  streamRegistry.stop();
60045
62237
  broadcaster.stop();
62238
+ telemetry.stop();
60046
62239
  pluginChannels.stop();
60047
62240
  }
60048
62241
  ],