@qredence/fleet 0.5.0 → 0.5.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (122) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/README.md +8 -1
  3. package/bin/fleet-prime.mjs +6 -0
  4. package/dist/web/client/assets/action-swap-roll-DX5o_33Q.js +1 -0
  5. package/dist/web/client/assets/artifacts-panel-C3yewUBP.js +1 -0
  6. package/dist/web/client/assets/artifacts-utils-N_kUFbz2.js +1 -0
  7. package/dist/web/client/assets/bot-Bs7QWJ2q.js +1 -0
  8. package/dist/web/client/assets/{chat-C64Sv6V-.js → chat-W-yOMyG_.js} +5 -5
  9. package/dist/web/client/assets/chat-command-palette-D0xDK1j4.js +1 -0
  10. package/dist/web/client/assets/command-CQzrtjyj.js +2 -0
  11. package/dist/web/client/assets/ease-vFBiNFNK.js +9 -0
  12. package/dist/web/client/assets/{fleet-pi-tool-renderer-ZKiX6Ob_.js → fleet-pi-tool-renderer-B0Y7ou0U.js} +28 -30
  13. package/dist/web/client/assets/generative-text-renderer-SS9c1kNX.js +6 -0
  14. package/dist/web/client/assets/globals-D_Hy9bT1.css +2 -0
  15. package/dist/web/client/assets/horizontal-resize-C1TpRLNC.js +1 -0
  16. package/dist/web/client/assets/index-C9FloFgj.js +12 -0
  17. package/dist/web/client/assets/{input-Clyn18XG.js → input-CqC82Agz.js} +1 -1
  18. package/dist/web/client/assets/{input-group-MxDAWX3j.js → input-group-H0TG-mkU.js} +1 -1
  19. package/dist/web/client/assets/ipython-tool-BrMePqD-.js +3 -0
  20. package/dist/web/client/assets/markdown-DG7pUdsX.js +2 -0
  21. package/dist/web/client/assets/{markdown-code-pIaEVDUU.js → markdown-code-BgMzpy7O.js} +1 -1
  22. package/dist/web/client/assets/notify-Duj26eeZ.js +1 -0
  23. package/dist/web/client/assets/{openui-renderer-NLUpAS3h.js → openui-renderer-CCfQqUfE.js} +5 -5
  24. package/dist/web/client/assets/openui-utils-DawGoQNp.js +1 -0
  25. package/dist/web/client/assets/prime-agent-artifacts-C-g1VPiW.js +5 -0
  26. package/dist/web/client/assets/{provider-catalog-Gx9qaHBM.js → provider-catalog-BZhZuKSz.js} +1 -1
  27. package/dist/web/client/assets/provider-label-jKm8v18u.js +1 -0
  28. package/dist/web/client/assets/range-65lubOFp.js +2 -0
  29. package/dist/web/client/assets/repl-panel-CCh4ly7J.js +1 -0
  30. package/dist/web/client/assets/resource-helpers-ULlyU8qK.js +2 -0
  31. package/dist/web/client/assets/resources-panel-DSU7VGX2.js +1 -0
  32. package/dist/web/client/assets/routes-DSTyx_J0.js +16 -0
  33. package/dist/web/client/assets/session-insights-panel-CQdT90Op.js +1 -0
  34. package/dist/web/client/assets/settings-dialog-CkfpTKfM.js +1 -0
  35. package/dist/web/client/assets/skeleton-loaders-fStjEeRP.js +1 -0
  36. package/dist/web/client/assets/square-terminal-BYTN_I86.js +1 -0
  37. package/dist/web/client/assets/subagent-chat-panel-D-qw4uWb.js +1 -0
  38. package/dist/web/client/assets/subagent-transcript-C7oRwEEP.js +1 -0
  39. package/dist/web/client/assets/subagents-panel-aSMWZP9p.js +1 -0
  40. package/dist/web/client/assets/{switch-ojzdMno9.js → switch-BFEBpUEU.js} +1 -1
  41. package/dist/web/client/assets/{tool-result-QvhjpNGX.js → tool-result-C2NvnN32.js} +3 -3
  42. package/dist/web/client/assets/ui-preferences-DUEFuJFj.js +1 -0
  43. package/dist/web/client/assets/workspace-panel-CjdXlEvd.js +1 -0
  44. package/dist/web/client/assets/workspace-path-nav-C0AQNZyy.js +1 -0
  45. package/dist/web/server/{_tanstack-start-manifest_v-uZddQetG-MNZGQOSA.js → _tanstack-start-manifest_v-DZc7dwm7-6ZQLGXB7.js} +23 -16
  46. package/dist/web/server/{artifacts-panel-knpQvJ-q-WJLZ76QB.js → artifacts-panel-Bt7YUzm4-NCBMXJ25.js} +39 -72
  47. package/dist/web/server/{chat-command-palette-CPv5GmGJ-22J32S6P.js → chat-command-palette-Co1L3rUY-RQLNME4T.js} +43 -20
  48. package/dist/web/server/{chunk-5277VI3D.js → chunk-2V6B62OF.js} +213 -275
  49. package/dist/web/server/{chunk-W7LNJCRJ.js → chunk-3HUI75QM.js} +75 -67
  50. package/dist/web/server/{chunk-I3FDTJFO.js → chunk-46VQY7SG.js} +6 -87
  51. package/dist/web/server/{chunk-PRT4QYOB.js → chunk-4UBOIY2S.js} +2 -35
  52. package/dist/web/server/{chunk-WTYNN6EV.js → chunk-54II5QXQ.js} +23 -1
  53. package/dist/web/server/chunk-56HSKUBD.js +1805 -0
  54. package/dist/web/server/{chunk-RPROZ2JC.js → chunk-5RQ6QAZX.js} +133 -133
  55. package/dist/web/server/{chunk-APN3LVRT.js → chunk-6D524OCJ.js} +201 -204
  56. package/dist/web/server/chunk-6GMKRR3C.js +161 -0
  57. package/dist/web/server/chunk-74QOI457.js +45 -0
  58. package/dist/web/server/{chunk-UBUXV2TW.js → chunk-AECEK3K7.js} +8 -8
  59. package/dist/web/server/chunk-AQ66E5OW.js +33 -0
  60. package/dist/web/server/{chunk-JD6EWZCU.js → chunk-AWFOBHH4.js} +50 -50
  61. package/dist/web/server/{chunk-MK3P3OBZ.js → chunk-BEMDNODD.js} +5 -5
  62. package/dist/web/server/{chunk-X2TUFLTP.js → chunk-BLVCDQ7E.js} +438 -438
  63. package/dist/web/server/chunk-FZRBAPUM.js +48 -0
  64. package/dist/web/server/chunk-G5BCQQ5N.js +34 -0
  65. package/dist/web/server/chunk-KOIPYBJF.js +3773 -0
  66. package/dist/web/server/{chunk-XYYNYFFD.js → chunk-LSIHVSUT.js} +2 -2
  67. package/dist/web/server/{chunk-KVHPE5XH.js → chunk-MDYA4NXK.js} +22 -8
  68. package/dist/web/server/chunk-NFRJDPB3.js +52 -0
  69. package/dist/web/server/chunk-P66QQWUM.js +67 -0
  70. package/dist/web/server/{chunk-4KFMONRT.js → chunk-PDRD2X5G.js} +9 -9
  71. package/dist/web/server/{chunk-XXNFEXDU.js → chunk-QJBEWT4E.js} +2 -70
  72. package/dist/web/server/{chunk-AQWTGP35.js → chunk-RX62LUDV.js} +8 -8
  73. package/dist/web/server/chunk-SR65ARVS.js +192 -0
  74. package/dist/web/server/{chunk-WK7CQS2N.js → chunk-SZ65K4CO.js} +48 -48
  75. package/dist/web/server/{chunk-C7EKOPZU.js → chunk-TO3YPLNZ.js} +89 -89
  76. package/dist/web/server/{chunk-IFV5M33X.js → chunk-UKINNXJY.js} +12 -26
  77. package/dist/web/server/chunk-VGDP4YDU.js +401 -0
  78. package/dist/web/server/{fleet-pi-tool-renderer-5vYFNeZS-IHKMLT7W.js → chunk-VRLTWOVJ.js} +46 -393
  79. package/dist/web/server/{chunk-KDSISV4P.js → chunk-WN77JNYY.js} +2 -50
  80. package/dist/web/server/{chunk-OADQILSQ.js → chunk-WZNZQNI4.js} +267 -3667
  81. package/dist/web/server/{chunk-KAWYGHDN.js → chunk-XFVL5ITL.js} +2354 -2314
  82. package/dist/web/server/{chunk-ZX3XOSYO.js → chunk-XLCTCC4W.js} +3 -3
  83. package/dist/web/server/{chunk-TTQ75CXC.js → chunk-Y4MHIA7B.js} +97 -40
  84. package/dist/web/server/fleet-pi-tool-renderer-CE45vM6T-2UQN6RJM.js +37 -0
  85. package/dist/web/server/{fork-picker-dialog-BZzfxdQd-C6SPHFAW.js → fork-picker-dialog-DCzuGelH-TN2Q5OXI.js} +5 -5
  86. package/dist/web/server/{markdown-Ct_q4D-z-VFWZRBTY.js → markdown-Boni3lHk-AZGKDNAR.js} +1 -1
  87. package/dist/web/server/{markdown-code-C_ih1bX1-5CIWT3CH.js → markdown-code-BrWukbg3-D2GN4Y77.js} +2 -2
  88. package/dist/web/server/{openui-renderer-BT5jL0Yf-XYLLN5U6.js → openui-renderer-c36_GYes-HX46N4M5.js} +14 -13
  89. package/dist/web/server/repl-panel-D9E8nkQy-L45ZNG2V.js +118 -0
  90. package/dist/web/server/{resources-panel-DNCVHTIg-PJYMXVGE.js → resources-panel-CwKh4U9f-D3VDEMDW.js} +6 -6
  91. package/dist/web/server/{router-DDxOMz3K-HRBXILHM.js → router-_ZpegqiQ-QIE44PIB.js} +1811 -1334
  92. package/dist/web/server/{routes-BX4Tv-6R-FHIZYUWW.js → routes-Ct81-8Tq-LHRMOS7R.js} +3958 -4534
  93. package/dist/web/server/server.js +3 -3
  94. package/dist/web/server/{session-insights-panel-gYkkAE8H-W4O74Z7H.js → session-insights-panel-BHZyKDTo-LRMAMA3O.js} +5 -3
  95. package/dist/web/server/{settings-dialog-BTBFLQ1P-ZENQ4KWK.js → settings-dialog-B4uUS6f--AZ4I4ZOT.js} +179 -193
  96. package/dist/web/server/{start-CLAD7RcD-56S4BWMM.js → start-BYVnok_H-IA6TWGA3.js} +1 -1
  97. package/dist/web/server/subagent-chat-panel-C97S3WID-DLOAD5TG.js +63 -0
  98. package/dist/web/server/subagents-panel-iHpvMIZy-LI6XK66M.js +181 -0
  99. package/dist/web/server/{chunk-5SZXUN3Y.js → workspace-panel-CHPoiXEo-YB4WS3MK.js} +29 -16
  100. package/package.json +15 -7
  101. package/dist/web/client/assets/artifacts-panel-8TyrNBM_.js +0 -1
  102. package/dist/web/client/assets/chat-command-palette-HpsmKfLO.js +0 -1
  103. package/dist/web/client/assets/collapsible-WCSnxhr2.js +0 -1
  104. package/dist/web/client/assets/command-DgfiCKcY.js +0 -2
  105. package/dist/web/client/assets/globals-BmxtUHFx.css +0 -2
  106. package/dist/web/client/assets/horizontal-resize-B76jjn5v.js +0 -1
  107. package/dist/web/client/assets/index-0pBr_bKy.js +0 -12
  108. package/dist/web/client/assets/markdown-BXWmNJo7.js +0 -2
  109. package/dist/web/client/assets/prime-agent-artifacts-k9JiTDZM.js +0 -5
  110. package/dist/web/client/assets/provider-brand-icon-VCebsuTD.js +0 -1
  111. package/dist/web/client/assets/range-KAaLzImH.js +0 -2
  112. package/dist/web/client/assets/resources-panel-BWuKeyrb.js +0 -1
  113. package/dist/web/client/assets/routes-BPRw0UzV.js +0 -20
  114. package/dist/web/client/assets/session-insights-panel-CPymkzZT.js +0 -1
  115. package/dist/web/client/assets/settings-dialog-6p8mjg8t.js +0 -1
  116. package/dist/web/client/assets/shared-DAI9OAw0.js +0 -2
  117. package/dist/web/client/assets/skeleton-loaders-qxIkJKCA.js +0 -1
  118. package/dist/web/client/assets/workspace-panel-C67-fqw4.js +0 -1
  119. package/dist/web/client/assets/workspace-path-nav-BrQHo6es.js +0 -9
  120. package/dist/web/server/chunk-KJ4UUAEU.js +0 -83
  121. package/dist/web/server/chunk-NGI44XRR.js +0 -334
  122. package/dist/web/server/workspace-panel-BNAXF57q-EQCBPEG4.js +0 -28
@@ -1,6 +1,3 @@
1
- import {
2
- isModelPatternEnabled
3
- } from "./chunk-WTYNN6EV.js";
4
1
  import {
5
2
  ChatModelsDiscoverRequestSchema,
6
3
  ChatProviderOAuthLoginRequestSchema,
@@ -14,10 +11,22 @@ import {
14
11
  QueryClientProvider,
15
12
  domAnimation,
16
13
  isServer
17
- } from "./chunk-4KFMONRT.js";
14
+ } from "./chunk-PDRD2X5G.js";
15
+ import {
16
+ redactSessionLabelSecrets
17
+ } from "./chunk-QK4CHLVV.js";
18
+ import {
19
+ DEFAULT_UI_PREFERENCES,
20
+ isModelPatternEnabled,
21
+ readUiPreferences
22
+ } from "./chunk-54II5QXQ.js";
18
23
  import {
19
24
  Toaster
20
- } from "./chunk-WK7CQS2N.js";
25
+ } from "./chunk-SZ65K4CO.js";
26
+ import {
27
+ drag,
28
+ layout
29
+ } from "./chunk-FAGDMGLK.js";
21
30
  import "./chunk-PKCTG7EW.js";
22
31
  import {
23
32
  Card,
@@ -25,14 +34,17 @@ import {
25
34
  CardDescription,
26
35
  CardHeader,
27
36
  CardTitle,
37
+ generatePrompt,
28
38
  validateAndNormalizeOpenUIHtmlArtifact
29
- } from "./chunk-NGI44XRR.js";
39
+ } from "./chunk-KOIPYBJF.js";
30
40
  import {
31
41
  ChatNewRequestSchema,
32
42
  ChatOpenUIArtifactUpsertRequestSchema,
33
43
  ChatPlanPresentationSchema,
34
44
  ChatPlanPresentationUpsertRequestSchema,
35
45
  ChatQuestionAnswerRequestSchema,
46
+ ChatQueueMutationRequestSchema,
47
+ ChatQueueMutationResponseSchema,
36
48
  ChatRequestSchema,
37
49
  ChatSessionMetadataSchema,
38
50
  PrimeAgentSessionPresentationSchema,
@@ -43,7 +55,7 @@ import {
43
55
  SessionIdSchema,
44
56
  UploadedAttachmentSchema,
45
57
  external_exports
46
- } from "./chunk-KAWYGHDN.js";
58
+ } from "./chunk-XFVL5ITL.js";
47
59
  import {
48
60
  KNOWN_PROVIDERS,
49
61
  OPENAI_CHAT_COMPLETIONS_PROVIDER_ID,
@@ -58,15 +70,8 @@ import {
58
70
  toInstanceSlug,
59
71
  toOccInstanceId
60
72
  } from "./chunk-RJOANOT4.js";
61
- import "./chunk-RPROZ2JC.js";
62
- import "./chunk-X2TUFLTP.js";
63
- import {
64
- redactSessionLabelSecrets
65
- } from "./chunk-QK4CHLVV.js";
66
- import {
67
- drag,
68
- layout
69
- } from "./chunk-FAGDMGLK.js";
73
+ import "./chunk-5RQ6QAZX.js";
74
+ import "./chunk-BLVCDQ7E.js";
70
75
  import "./chunk-E26EAQIM.js";
71
76
  import "./chunk-DJMHPJBP.js";
72
77
  import {
@@ -82,8 +87,8 @@ import "./chunk-JDCCC7A7.js";
82
87
  import "./chunk-L547YHC4.js";
83
88
  import "./chunk-MLKGABMK.js";
84
89
 
85
- // web/app/dist/server/assets/router-DDxOMz3K.js
86
- import { useEffect } from "react";
90
+ // web/app/dist/server/assets/router-_ZpegqiQ.js
91
+ import { useEffect, useLayoutEffect } from "react";
87
92
  import { jsx, jsxs } from "react/jsx-runtime";
88
93
  import { basename, dirname, extname, isAbsolute, join, relative, resolve, sep } from "node:path";
89
94
  import { fileURLToPath } from "node:url";
@@ -116,7 +121,7 @@ function NotFoundPage({ title = "404", description = "The requested page could n
116
121
  })
117
122
  });
118
123
  }
119
- var globals_default = "/assets/globals-BmxtUHFx.css";
124
+ var globals_default = "/assets/globals-D_Hy9bT1.css";
120
125
  function makeQueryClient() {
121
126
  return new QueryClient({ defaultOptions: { queries: {
122
127
  staleTime: 6e4,
@@ -162,16 +167,22 @@ var Route$27 = createRootRoute({
162
167
  shellComponent: RootDocument
163
168
  });
164
169
  function RootComponent() {
170
+ useLayoutEffect(() => {
171
+ const preferences = readUiPreferences();
172
+ document.documentElement.dataset.density = preferences.density;
173
+ document.documentElement.classList.toggle("reduce-motion", preferences.motion === "reduced");
174
+ }, []);
165
175
  useEffect(() => {
166
176
  }, []);
167
- return /* @__PURE__ */ jsx(MotionRuntime, { children: /* @__PURE__ */ jsx(QueryClientProvider, {
177
+ return /* @__PURE__ */ jsx(MotionRuntime, { children: /* @__PURE__ */ jsxs(QueryClientProvider, {
168
178
  client: getQueryClient(),
169
- children: /* @__PURE__ */ jsx(Outlet, {})
179
+ children: [/* @__PURE__ */ jsx(Outlet, {}), null]
170
180
  }) });
171
181
  }
172
182
  function RootDocument({ children }) {
173
183
  return /* @__PURE__ */ jsxs("html", {
174
184
  lang: "en",
185
+ "data-density": DEFAULT_UI_PREFERENCES.density,
175
186
  children: [/* @__PURE__ */ jsx("head", { children: /* @__PURE__ */ jsx(HeadContent, {}) }), /* @__PURE__ */ jsxs("body", { children: [
176
187
  children,
177
188
  /* @__PURE__ */ jsx(Toaster, {}),
@@ -179,7 +190,7 @@ function RootDocument({ children }) {
179
190
  ] })]
180
191
  });
181
192
  }
182
- var $$splitComponentImporter = () => import("./routes-BX4Tv-6R-FHIZYUWW.js");
193
+ var $$splitComponentImporter = () => import("./routes-Ct81-8Tq-LHRMOS7R.js");
183
194
  var Route$26 = createFileRoute("/")({ component: lazyRouteComponent($$splitComponentImporter, "component") });
184
195
  var ManagedAttachmentValidationError = class extends Error {
185
196
  status;
@@ -326,639 +337,6 @@ function sessionCommandResultText(command, presentation, initialRefinementCount)
326
337
  if (command.name === "goal") return presentation.goal?.objective ? `Goal ${presentation.goal.status}: ${presentation.goal.objective}` : "No active goal.";
327
338
  return `/${command.name} completed.`;
328
339
  }
329
- function resolveField(obj, path) {
330
- if (!path || obj == null) return void 0;
331
- if (!path.includes(".")) return obj[path];
332
- let cur = obj;
333
- for (const p of path.split(".")) {
334
- if (cur == null) return void 0;
335
- cur = cur[p];
336
- }
337
- return cur;
338
- }
339
- function toNumber(val) {
340
- if (typeof val === "number") return val;
341
- if (typeof val === "string") {
342
- const n = Number(val);
343
- return isNaN(n) ? 0 : n;
344
- }
345
- if (typeof val === "boolean") return val ? 1 : 0;
346
- return 0;
347
- }
348
- var BUILTINS = {
349
- Count: {
350
- name: "Count",
351
- signature: "Count(array) \u2192 number",
352
- description: "Returns array length",
353
- fn: (arr) => Array.isArray(arr) ? arr.length : 0
354
- },
355
- First: {
356
- name: "First",
357
- signature: "First(array) \u2192 element",
358
- description: "Returns first element of array",
359
- fn: (arr) => Array.isArray(arr) ? arr[0] ?? null : null
360
- },
361
- Last: {
362
- name: "Last",
363
- signature: "Last(array) \u2192 element",
364
- description: "Returns last element of array",
365
- fn: (arr) => Array.isArray(arr) ? arr[arr.length - 1] ?? null : null
366
- },
367
- Sum: {
368
- name: "Sum",
369
- signature: "Sum(numbers[]) \u2192 number",
370
- description: "Sum of numeric array",
371
- fn: (arr) => Array.isArray(arr) ? arr.reduce((a, b) => a + toNumber(b), 0) : 0
372
- },
373
- Avg: {
374
- name: "Avg",
375
- signature: "Avg(numbers[]) \u2192 number",
376
- description: "Average of numeric array",
377
- fn: (arr) => Array.isArray(arr) && arr.length ? arr.reduce((a, b) => a + toNumber(b), 0) / arr.length : 0
378
- },
379
- Min: {
380
- name: "Min",
381
- signature: "Min(numbers[]) \u2192 number",
382
- description: "Minimum value in array",
383
- fn: (arr) => Array.isArray(arr) && arr.length ? arr.reduce((acc, b) => Math.min(acc, toNumber(b)), toNumber(arr[0])) : 0
384
- },
385
- Max: {
386
- name: "Max",
387
- signature: "Max(numbers[]) \u2192 number",
388
- description: "Maximum value in array",
389
- fn: (arr) => Array.isArray(arr) && arr.length ? arr.reduce((acc, b) => Math.max(acc, toNumber(b)), toNumber(arr[0])) : 0
390
- },
391
- Sort: {
392
- name: "Sort",
393
- signature: "Sort(array, field, direction?) \u2192 sorted array",
394
- description: 'Sort array by field. Direction: "asc" (default) or "desc"',
395
- fn: (arr, field, dir) => {
396
- if (!Array.isArray(arr)) return arr;
397
- const f = String(field ?? "");
398
- const desc = String(dir ?? "asc") === "desc";
399
- return [...arr].sort((a, b) => {
400
- const av = f ? resolveField(a, f) : a;
401
- const bv = f ? resolveField(b, f) : b;
402
- const aIsNumeric = typeof av === "number" || typeof av === "string" && !isNaN(Number(av)) && av !== "";
403
- const bIsNumeric = typeof bv === "number" || typeof bv === "string" && !isNaN(Number(bv)) && bv !== "";
404
- if (aIsNumeric && bIsNumeric) {
405
- const diff = toNumber(av) - toNumber(bv);
406
- return desc ? -diff : diff;
407
- }
408
- const cmp = String(av ?? "").localeCompare(String(bv ?? ""));
409
- return desc ? -cmp : cmp;
410
- });
411
- }
412
- },
413
- Filter: {
414
- name: "Filter",
415
- signature: 'Filter(array, field, operator: "==" | "!=" | ">" | "<" | ">=" | "<=" | "contains", value) \u2192 filtered array',
416
- description: "Filter array by field value",
417
- fn: (arr, field, op, value) => {
418
- if (!Array.isArray(arr)) return [];
419
- const f = String(field ?? "");
420
- const o = String(op ?? "==");
421
- return arr.filter((item) => {
422
- const v = f ? resolveField(item, f) : item;
423
- switch (o) {
424
- case "==":
425
- return v == value;
426
- case "!=":
427
- return v != value;
428
- case ">":
429
- return toNumber(v) > toNumber(value);
430
- case "<":
431
- return toNumber(v) < toNumber(value);
432
- case ">=":
433
- return toNumber(v) >= toNumber(value);
434
- case "<=":
435
- return toNumber(v) <= toNumber(value);
436
- case "contains":
437
- return String(v ?? "").includes(String(value ?? ""));
438
- default:
439
- return false;
440
- }
441
- });
442
- }
443
- },
444
- Round: {
445
- name: "Round",
446
- signature: "Round(number, decimals?) \u2192 number",
447
- description: "Round to N decimal places (default 0)",
448
- fn: (n, decimals) => {
449
- const num = toNumber(n);
450
- const d = decimals != null ? toNumber(decimals) : 0;
451
- const factor = Math.pow(10, d);
452
- return Math.round(num * factor) / factor;
453
- }
454
- },
455
- Abs: {
456
- name: "Abs",
457
- signature: "Abs(number) \u2192 number",
458
- description: "Absolute value",
459
- fn: (n) => Math.abs(toNumber(n))
460
- },
461
- Floor: {
462
- name: "Floor",
463
- signature: "Floor(number) \u2192 number",
464
- description: "Round down to nearest integer",
465
- fn: (n) => Math.floor(toNumber(n))
466
- },
467
- Ceil: {
468
- name: "Ceil",
469
- signature: "Ceil(number) \u2192 number",
470
- description: "Round up to nearest integer",
471
- fn: (n) => Math.ceil(toNumber(n))
472
- }
473
- };
474
- var LAZY_BUILTINS = /* @__PURE__ */ new Set(["Each"]);
475
- var LAZY_BUILTIN_DEFS = { Each: {
476
- signature: "Each(array, varName, template)",
477
- description: "Evaluate template for each element. varName is the loop variable \u2014 use it ONLY inside the template expression (inline). Do NOT create a separate statement for the template."
478
- } };
479
- var ACTION_NAMES = /* @__PURE__ */ new Set(["Action", ...Object.keys({
480
- Run: "run",
481
- ToAssistant: "continue_conversation",
482
- OpenUrl: "open_url",
483
- Set: "set",
484
- Reset: "reset"
485
- })]);
486
- [
487
- ...Object.keys(BUILTINS),
488
- ...LAZY_BUILTINS,
489
- ...ACTION_NAMES
490
- ];
491
- function jsonSchemaTypeStr(schema) {
492
- const type = schema.type;
493
- if (type === "string") {
494
- const enumVals = schema.enum;
495
- if (enumVals) return enumVals.map((v) => `"${v}"`).join(" | ");
496
- return "string";
497
- }
498
- if (type === "number" || type === "integer") return "number";
499
- if (type === "boolean") return "boolean";
500
- if (type === "array") {
501
- const items = schema.items;
502
- if (items) return `${jsonSchemaTypeStr(items)}[]`;
503
- return "any[]";
504
- }
505
- if (type === "object") {
506
- const props = schema.properties;
507
- if (props && Object.keys(props).length > 0) {
508
- const required = schema.required ?? [];
509
- return `{${Object.entries(props).map(([k, v]) => {
510
- return `${k}${required.includes(k) ? "" : "?"}: ${jsonSchemaTypeStr(v)}`;
511
- }).join(", ")}}`;
512
- }
513
- return "object";
514
- }
515
- return "any";
516
- }
517
- function defaultForSchema(schema) {
518
- const type = schema.type;
519
- if (type === "string") return "";
520
- if (type === "number" || type === "integer") return 0;
521
- if (type === "boolean") return false;
522
- if (type === "array") return [];
523
- if (type === "object") {
524
- const props = schema.properties;
525
- if (props && Object.keys(props).length > 0) {
526
- const result = {};
527
- for (const [k, v] of Object.entries(props)) result[k] = defaultForSchema(v);
528
- return result;
529
- }
530
- return {};
531
- }
532
- return null;
533
- }
534
- var PREAMBLE = `You are an AI assistant that responds using openui-lang, a declarative UI language. Your ENTIRE response must be valid openui-lang code \u2014 no markdown, no explanations, just openui-lang.`;
535
- function syntaxRules(rootName, flags) {
536
- const lines = [
537
- "## Syntax Rules",
538
- "",
539
- "1. Each statement is on its own line: `identifier = Expression`",
540
- `2. \`root\` is the entry point \u2014 every program must define \`root = ${rootName}(...)\``,
541
- '3. Expressions are: strings ("..."), numbers, booleans (true/false), null, arrays ([...]), objects ({...}), or component calls TypeName(arg1, arg2, ...)',
542
- "4. Use references for readability: define `name = ...` on one line, then use `name` later",
543
- "5. EVERY variable (except root) MUST be referenced by at least one other variable. Unreferenced variables are silently dropped and will NOT render. Always include defined variables in their parent's children/items array.",
544
- '6. Arguments are POSITIONAL (order matters, not names). Write `Stack([children], "row", "l")` NOT `Stack([children], direction: "row", gap: "l")` \u2014 colon syntax is NOT supported and silently breaks',
545
- "7. Optional arguments can be omitted from the end"
546
- ];
547
- let ruleNum = 8;
548
- if (flags.bindings) lines.push(`${ruleNum++}. Declare mutable state with \`$varName = defaultValue\`. Components marked with \`$binding\` can read/write these. Undeclared $variables are auto-created with null default.`);
549
- if (flags.supportsExpressions) lines.push(`${ruleNum++}. String concatenation: \`"text" + $var + "more"\``, `${ruleNum++}. Dot member access: \`query.field\` reads a field; on arrays it extracts that field from every element`, `${ruleNum++}. Index access: \`arr[0]\`, \`data[index]\``, `${ruleNum++}. Arithmetic operators: +, -, *, /, % (work on numbers; + is string concat when either side is a string)`, `${ruleNum++}. Comparison: ==, !=, >, <, >=, <=`, `${ruleNum++}. Logical: &&, ||, ! (prefix)`, `${ruleNum++}. Ternary: \`condition ? valueIfTrue : valueIfFalse\``, `${ruleNum++}. Parentheses for grouping: \`(a + b) * c\``);
550
- lines.push("- Strings use double quotes with backslash escaping");
551
- return lines.join("\n");
552
- }
553
- function builtinFunctionsSection() {
554
- const builtinLines = Object.values(BUILTINS).map((b) => `@${b.signature} \u2014 ${b.description}`);
555
- const lazyLines = Object.values(LAZY_BUILTIN_DEFS).map((b) => `@${b.signature} \u2014 ${b.description}`);
556
- return `## Built-in Functions
557
-
558
- Data functions prefixed with \`@\` to distinguish from components. These are the ONLY functions available \u2014 do NOT invent new ones.
559
- Use @-prefixed built-in functions (@Count, @Sum, @Avg, @Min, @Max, @Round) on Query results \u2014 do NOT hardcode computed values.
560
-
561
- ${[...builtinLines, ...lazyLines].join("\n")}
562
-
563
- Builtins compose \u2014 output of one is input to the next:
564
- \`@Count(@Filter(data.rows, "field", "==", "val"))\` for KPIs/chart values, \`@Round(@Avg(data.rows.score), 1)\`, \`@Each(data.rows, "item", Comp(item.field))\` for per-item rendering.
565
- Array pluck: \`data.rows.field\` extracts a field from every row \u2192 use with @Sum, @Avg, charts, tables.
566
-
567
- IMPORTANT @Each rule: The loop variable (e.g. "item") is ONLY available inside the @Each template expression. Always inline the template \u2014 do NOT extract it to a separate statement.
568
- CORRECT: \`Col("Actions", @Each(rows, "t", Button("Edit", Action([@Set($id, t.id)]))))\`
569
- WRONG: \`myBtn = Button("Edit", Action([@Set($id, t.id)]))\` then \`Col("Actions", @Each(rows, "t", myBtn))\` \u2014 t is undefined in myBtn.`;
570
- }
571
- function querySection() {
572
- return `## Query \u2014 Live Data Fetching
573
-
574
- Fetch data from available tools. Returns defaults instantly, swaps in real data when it arrives.
575
-
576
- \`\`\`
577
- metrics = Query("tool_name", {arg1: value, arg2: $binding}, {defaultField: 0, defaultData: []}, refreshInterval?)
578
- \`\`\`
579
-
580
- - First arg: tool name (string)
581
- - Second arg: arguments object (may reference $bindings \u2014 re-fetches automatically on change)
582
- - Third arg: default data (rendered immediately before fetch resolves)
583
- - Fourth arg (optional): refresh interval in seconds (e.g. 30 for auto-refresh every 30s)
584
- - Use dot access on results: metrics.totalEvents, metrics.data.day (array pluck)
585
- - Query results must use regular identifiers: \`metrics = Query(...)\`, NOT \`$metrics = Query(...)\`
586
- - Manual refresh: \`Button("Refresh", Action([@Run(query1), @Run(query2)]), "secondary")\` \u2014 re-fetches the listed queries
587
- - Refresh all queries: create Action with @Run for each query`;
588
- }
589
- function mutationSection() {
590
- return `## Mutation \u2014 Write Operations
591
-
592
- Execute state-changing tool calls (create, update, delete). Unlike Query (auto-fetches on render), Mutation fires only on button click via Action.
593
-
594
- \`\`\`
595
- result = Mutation("tool_name", {arg1: $binding, arg2: "value"})
596
- \`\`\`
597
-
598
- - First arg: tool name (string)
599
- - Second arg: arguments object (evaluated with current $binding values at click time)
600
- - result.status: "idle" | "loading" | "success" | "error"
601
- - result.data: tool response on success
602
- - result.error: error message on failure
603
- - Mutation results use regular identifiers: \`result = Mutation(...)\`, NOT \`$result\`
604
- - Show loading state: \`result.status == "loading" ? TextContent("Saving...") : null\``;
605
- }
606
- function actionSection(flags) {
607
- const steps = ['- @ToAssistant("message") \u2014 Send a message to the assistant (for conversational buttons like "Tell me more", "Explain this")', '- @OpenUrl("https://...") \u2014 Navigate to a URL'];
608
- if (flags.bindings) steps.push("- @Set($variable, value) \u2014 Set a $variable to a specific value", '- @Reset($var1, $var2, ...) \u2014 Reset $variables to their declared defaults (e.g. @Reset($title, $priority) restores $title="" and $priority="medium")');
609
- if (flags.toolCalls) steps.unshift("- @Run(queryOrMutationRef) \u2014 Execute a Mutation or re-fetch a Query (ref must be a declared Query/Mutation)");
610
- const examples = [];
611
- if (flags.toolCalls) examples.push(`Example \u2014 mutation + refresh + reset (PREFERRED pattern):
612
- \`\`\`
613
- $binding = "default"
614
- result = Mutation("tool_name", {field: $binding})
615
- data = Query("tool_name", {}, {rows: []})
616
- onSubmit = Action([@Run(result), @Run(data), @Reset($binding)])
617
- \`\`\``);
618
- examples.push(`Example \u2014 simple nav:
619
- \`\`\`
620
- viewBtn = Button("View", Action([@OpenUrl("https://example.com")]))
621
- \`\`\``);
622
- const rules = ['- Action can be assigned to a variable or inlined: Button("Go", onSubmit) and Button("Go", Action([...])) both work'];
623
- if (flags.toolCalls) rules.push("- If a @Run(mutation) step fails, remaining steps are skipped (halt on failure)", "- @Run(queryRef) re-fetches the query (fire-and-forget, cannot fail)");
624
- return `## Action \u2014 Button Behavior
625
-
626
- Action([@steps...]) wires button clicks to operations. Steps are @-prefixed built-in actions. Steps execute in order.
627
- Buttons without an explicit Action prop automatically send their label to the assistant (equivalent to Action([@ToAssistant(label)])).
628
-
629
- Available steps:
630
- ${steps.join("\n")}
631
-
632
- ${examples.join("\n\n")}
633
-
634
- ${rules.join("\n")}`;
635
- }
636
- function interactiveFiltersSection() {
637
- return `## Interactive Filters
638
-
639
- To let the user filter data with a dropdown:
640
- 1. Declare a $variable with a default: \`$dateRange = "14"\`
641
- 2. Create a Select with name, items, and binding: \`Select("dateRange", [SelectItem("7", "Last 7 days"), ...], null, null, $dateRange)\`
642
- 3. Wrap in FormControl for a label: \`FormControl("Date Range", Select(...))\`
643
- 4. Pass $dateRange in Query args: \`Query("tool", {dateRange: $dateRange}, {defaults})\`
644
- 5. When the user changes the Select, $dateRange updates and the Query automatically re-fetches
645
-
646
- FILTER WIRING RULE: If a $binding filter is visible in the UI, EVERY relevant Query MUST reference that $binding in its args. Never show a filter dropdown while hardcoding the query args.
647
-
648
- Rules for $variables:
649
- - $variables hold simple values (strings or numbers), NOT arrays or objects
650
- - $variables must be bound to a Select/Input component via the value argument (last positional arg) to be interactive
651
- - Queries must use regular identifiers (NOT $variables): \`metrics = Query(...)\` not \`$metrics = Query(...)\`
652
- - **Auto-declare**: You do NOT need to explicitly declare $variables. If you use \`$foo\` without declaring it, the parser auto-creates \`$foo = null\`. You can still declare explicitly to set a default: \`$days = "14"\`
653
-
654
- ## Forms
655
-
656
- Simple form \u2014 no $bindings needed. Field values are managed internally by the Form via the name prop:
657
- \`\`\`
658
- contactForm = Form("contact", submitBtn, [nameField, emailField])
659
- nameField = FormControl("Name", Input("name", "Your name", "text", {required: true}))
660
- emailField = FormControl("Email", Input("email", "your@email.com", "email", {required: true, email: true}))
661
- submitBtn = Button("Submit")
662
- \`\`\`
663
-
664
- Use $bindings when you need to read field values elsewhere (in Action context, Query args, or conditionals). They are auto-declared:
665
- \`\`\`
666
- $role = "engineer"
667
- contactForm = Form("contact", submitBtn, [nameField, emailField, roleField])
668
- nameField = FormControl("Name", Input("name", "Enter your name", "text", {required: true}, $name))
669
- emailField = FormControl("Email", Input("email", "Enter your email", "email", {required: true, email: true}, $email))
670
- roleField = FormControl("Role", Select("role", [SelectItem("engineer", "Engineer"), SelectItem("designer", "Designer"), SelectItem("pm", "PM")], null, {required: true}, $role))
671
- submitBtn = Button("Submit")
672
- \`\`\`
673
-
674
- For form + mutation patterns (create, refresh, reset), see the Action section example above.
675
-
676
- IMPORTANT: Always add validation rules to form fields used with Mutations. Use OBJECT syntax: {required: true, email: true, minLength: 8}. The renderer shows error messages automatically and blocks submit when validation fails.`;
677
- }
678
- function editModeSection() {
679
- return `## Edit Mode
680
-
681
- The runtime merges by statement name: same name = replace, new name = append.
682
- Output ONLY statements that changed or are new. Everything else is kept automatically.
683
-
684
- ### Delete
685
- To remove a component, update the parent to exclude it from its children array. Orphaned statements are automatically garbage-collected.
686
- Example \u2014 remove chart: \`root = Stack([header, kpiRow, table])\` \u2014 chart is no longer in the children list, so it and any statements only it referenced are auto-deleted.
687
-
688
- ### Patch size guide
689
- - Changing a title or label: 1 statement
690
- - Adding a component: 2-3 statements (the new component + parent update)
691
- - Removing a component: 1 statement (re-declare parent without the removed child)
692
- - Adding a filter + wiring to query: 3-5 statements
693
- - Restructuring into tabs: 5-10 statements
694
-
695
- ### Rules
696
- - Reuse existing statement names exactly \u2014 do not rename
697
- - Do NOT re-emit unchanged statements \u2014 the runtime keeps them
698
- - A typical edit patch is 1-10 statements, not 20+
699
- - If the existing code already satisfies the request, output only the root statement
700
- - NEVER output the entire program as a patch. Only output what actually changes
701
- - If you are about to output more than 10 statements, reconsider \u2014 most edits need fewer`;
702
- }
703
- function streamingRules(rootName, flags) {
704
- const steps = [`1. \`root = ${rootName}(...)\` \u2014 UI shell appears immediately`];
705
- if (flags.supportsExpressions) {
706
- steps.push("2. $variable declarations \u2014 state ready for bindings");
707
- steps.push("3. Query statements \u2014 defaults resolve immediately so components render with data");
708
- steps.push("4. Component definitions \u2014 fill in with data already available");
709
- steps.push("5. Data values \u2014 leaf content last");
710
- } else {
711
- steps.push("2. Component definitions \u2014 fill in as they stream");
712
- steps.push("3. Data values \u2014 leaf content last");
713
- }
714
- return `## Hoisting & Streaming (CRITICAL)
715
-
716
- openui-lang supports hoisting: a reference can be used BEFORE it is defined. The parser resolves all references after the full input is parsed.
717
-
718
- During streaming, the output is re-parsed on every chunk. Undefined references are temporarily unresolved and appear once their definitions stream in. This creates a progressive top-down reveal \u2014 structure first, then data fills in.
719
-
720
- **Recommended statement order for optimal streaming:**
721
- ${steps.join("\n")}
722
-
723
- Always write the root = ${rootName}(...) statement first so the UI shell appears immediately, even before child data has streamed in.`;
724
- }
725
- function inlineModeSection() {
726
- return `## Inline Mode
727
-
728
- You are in inline mode. You can respond in two ways:
729
-
730
- ### 1. Code response (when the user wants to CREATE or CHANGE the UI)
731
- Wrap openui-lang code in triple-backtick fences. You can include explanatory text before/after:
732
-
733
- Here's your dashboard:
734
-
735
- \`\`\`openui-lang
736
- root = RootComp([header, content])
737
- header = SomeHeader("Title")
738
- content = SomeContent("Hello world")
739
- \`\`\`
740
-
741
- I created a simple layout with a header.
742
-
743
- ### 2. Text-only response (when the user asks a QUESTION)
744
- If the user asks "what is this?", "explain the chart", "how does this work", etc. \u2014 respond with plain text. Do NOT output any openui-lang code. The existing dashboard stays unchanged.
745
-
746
- ### Rules
747
- - When the user asks for changes, output ONLY the changed/new statements in a fenced block
748
- - When the user asks a question, respond with text only \u2014 NO code. The dashboard stays unchanged.
749
- - The parser extracts code from fences automatically. Text outside fences is shown as chat.`;
750
- }
751
- function toolWorkflowSection() {
752
- return `## Data Workflow
753
-
754
- When tools are available, follow this workflow:
755
- 1. FIRST: Call the most relevant tool to inspect the real data shape before generating code
756
- 2. Use Query() for READ operations (data that should stay live) \u2014 NEVER hardcode tool results as literal arrays or objects
757
- 3. Use Mutation() for WRITE operations (create, update, delete) \u2014 triggered by button clicks via Action([@Run(mutationRef)])
758
- 4. Use the real data from step 1 as condensed Query defaults (3-5 rows) so the UI renders immediately
759
- 5. Use @-prefixed builtins (@Count, @Filter, @Sort, @Sum) on Query results for KPIs and aggregations \u2014 the runtime evaluates these live on every refresh
760
- 6. Hardcoded arrays are ONLY for static display data (labels, options) where no tool exists
761
-
762
- WRONG \u2014 you called a tool and got data back, but you inlined the results:
763
- \`\`\`
764
- openCount = 2
765
- item1 = SomeComp("first item title")
766
- item2 = SomeComp("second item title")
767
- list = Stack([item1, item2])
768
- chart = SomeChart(["A", "B"], [12, 8])
769
- \`\`\`
770
- This is static \u2014 it shows stale data and won't update. Creating item1, item2, item3... manually is ALWAYS wrong when a tool exists.
771
-
772
- RIGHT \u2014 use Query() for live data, Mutation() for writes, @builtins to derive values:
773
- \`\`\`
774
- data = Query("tool_name", {}, {rows: []})
775
- openCount = @Count(@Filter(data.rows, "field", "==", "value"))
776
- list = @Each(data.rows, "item", SomeComp(item.title, item.field))
777
- createResult = Mutation("create_tool", {title: $title})
778
- submitBtn = Button("Create", Action([@Run(createResult), @Run(data), @Reset($title)]))
779
- \`\`\`
780
- Everything derives from the Query \u2014 when data refreshes, the entire dashboard updates automatically.`;
781
- }
782
- function importantRules(rootName, flags) {
783
- const verifyLines = [`1. root = ${rootName}(...) is the FIRST line (for optimal streaming).`, "2. Every referenced name is defined. Every defined name (other than root) is reachable from root."];
784
- if (flags.toolCalls) verifyLines.push("3. Every Query result is referenced by at least one component.");
785
- if (flags.bindings) verifyLines.push(`${flags.toolCalls ? "4" : "3"}. Every $binding appears in at least one component or expression.`);
786
- if (flags.toolCalls && flags.bindings) verifyLines.push("5. Every visible filter $binding appears in at least one Query args object.");
787
- return `## Important Rules
788
- - When asked about data, generate realistic/plausible data
789
- - Choose components that best represent the content (tables for comparisons, charts for trends, forms for input, etc.)
790
-
791
- ## Final Verification
792
- Before finishing, walk your output and verify:
793
- ${verifyLines.join("\n")}`;
794
- }
795
- function renderToolSignature(tool) {
796
- let args = "";
797
- if (tool.inputSchema) {
798
- const props = tool.inputSchema.properties;
799
- const required = tool.inputSchema.required ?? [];
800
- if (props && Object.keys(props).length > 0) args = Object.entries(props).map(([k, v]) => {
801
- return `${k}${required.includes(k) ? "" : "?"}: ${jsonSchemaTypeStr(v)}`;
802
- }).join(", ");
803
- }
804
- let returnType = "";
805
- if (tool.outputSchema) returnType = ` \u2192 ${jsonSchemaTypeStr(tool.outputSchema)}`;
806
- let line = `- ${tool.name}(${args})${returnType}`;
807
- if (tool.description) line += `
808
- ${tool.description}`;
809
- return line;
810
- }
811
- function renderToolsSection(tools) {
812
- const lines = [];
813
- const stringTools = [];
814
- const specTools = [];
815
- for (const tool of tools) if (typeof tool === "string") stringTools.push(tool);
816
- else specTools.push(tool);
817
- lines.push("## Available Tools");
818
- lines.push("");
819
- lines.push("Use these with Query() for read operations or Mutation() for write operations. The LLM decides which is appropriate based on the tool's purpose.");
820
- lines.push("");
821
- for (const t of stringTools) lines.push(`- ${t}`);
822
- for (const t of specTools) lines.push(renderToolSignature(t));
823
- const toolsWithOutput = specTools.filter((t) => t.outputSchema);
824
- if (toolsWithOutput.length > 0) {
825
- lines.push("");
826
- lines.push("### Default values for Query results");
827
- lines.push("");
828
- lines.push("Use these shapes as minimal Query defaults:");
829
- for (const t of toolsWithOutput) {
830
- const defaults = defaultForSchema(t.outputSchema);
831
- lines.push(`- ${t.name}: \`${JSON.stringify(defaults)}\``);
832
- }
833
- }
834
- lines.push("");
835
- lines.push("CRITICAL: Use ONLY the tools listed above in Query() and Mutation() calls. Do NOT invent or guess tool names. If the user asks for functionality that doesn't match any available tool, use realistic mock data instead of fabricating a tool call.");
836
- return lines.join("\n");
837
- }
838
- function generateComponentSignatures(spec, flags) {
839
- const lines = [
840
- "## Component Signatures",
841
- "",
842
- "Arguments marked with ? are optional. Sub-components can be inline or referenced; prefer references for better streaming."
843
- ];
844
- if (flags.usesActionExpression) {
845
- const allSteps = [
846
- flags.toolCalls ? "@Run" : "",
847
- "@ToAssistant",
848
- "@OpenUrl",
849
- flags.bindings ? "@Set" : "",
850
- flags.bindings ? "@Reset" : ""
851
- ].filter(Boolean);
852
- lines.push(`Props typed \`ActionExpression\` accept an Action([@steps...]) expression. See the Action section for available steps (${allSteps.join(", ")}).`);
853
- }
854
- if (flags.bindings || Object.values(spec.components).some((c) => c.signature?.includes("$binding"))) lines.push("Props marked `$binding<type>` accept a `$variable` reference for two-way binding.");
855
- const formatSig = (comp) => comp.description ? `${comp.signature} \u2014 ${comp.description}` : comp.signature;
856
- if (spec.componentGroups?.length) {
857
- const grouped = /* @__PURE__ */ new Set();
858
- for (const group of spec.componentGroups) {
859
- lines.push("", `### ${group.name}`);
860
- for (const name of group.components) {
861
- if (grouped.has(name)) continue;
862
- const comp = spec.components[name];
863
- if (!comp) continue;
864
- grouped.add(name);
865
- lines.push(formatSig(comp));
866
- }
867
- if (group.notes?.length) for (const note of group.notes) lines.push(note);
868
- }
869
- const ungrouped = Object.keys(spec.components).filter((n) => !grouped.has(n));
870
- if (ungrouped.length) {
871
- lines.push("", "### Other");
872
- for (const name of ungrouped) {
873
- const comp = spec.components[name];
874
- lines.push(formatSig(comp));
875
- }
876
- }
877
- } else {
878
- lines.push("");
879
- for (const [, comp] of Object.entries(spec.components)) lines.push(formatSig(comp));
880
- }
881
- return lines.join("\n");
882
- }
883
- function generatePrompt(spec) {
884
- const rootName = spec.root ?? "Root";
885
- const hasTools = !!spec.tools?.length;
886
- const toolCalls = spec.toolCalls ?? hasTools;
887
- const bindings = spec.bindings ?? toolCalls;
888
- const supportsExpressions = toolCalls || bindings;
889
- const usesActionExpression = Object.values(spec.components).some((c) => c.signature?.includes("ActionExpression"));
890
- const parts = [];
891
- parts.push(spec.preamble ?? PREAMBLE);
892
- parts.push("");
893
- parts.push(syntaxRules(rootName, {
894
- supportsExpressions,
895
- bindings
896
- }));
897
- parts.push("");
898
- parts.push(generateComponentSignatures(spec, {
899
- toolCalls,
900
- bindings,
901
- usesActionExpression
902
- }));
903
- if (supportsExpressions) {
904
- parts.push("");
905
- parts.push(builtinFunctionsSection());
906
- }
907
- if (toolCalls) {
908
- parts.push("");
909
- parts.push(querySection());
910
- parts.push("");
911
- parts.push(mutationSection());
912
- }
913
- if (usesActionExpression) {
914
- parts.push("");
915
- parts.push(actionSection({
916
- toolCalls,
917
- bindings
918
- }));
919
- }
920
- if (toolCalls && bindings) {
921
- parts.push("");
922
- parts.push(interactiveFiltersSection());
923
- }
924
- if (toolCalls) {
925
- parts.push("");
926
- parts.push(toolWorkflowSection());
927
- }
928
- if (spec.tools?.length) {
929
- parts.push("");
930
- parts.push(renderToolsSection(spec.tools));
931
- }
932
- parts.push("");
933
- parts.push(streamingRules(rootName, { supportsExpressions }));
934
- const allExamples = [...spec.examples ?? [], ...spec.toolExamples ?? []];
935
- if (allExamples.length) {
936
- parts.push("");
937
- parts.push("## Examples");
938
- parts.push("");
939
- for (const ex of allExamples) {
940
- parts.push(ex);
941
- parts.push("");
942
- }
943
- }
944
- if (spec.editMode) {
945
- parts.push("");
946
- parts.push(editModeSection());
947
- }
948
- if (spec.inlineMode) {
949
- parts.push("");
950
- parts.push(inlineModeSection());
951
- }
952
- parts.push(importantRules(rootName, {
953
- toolCalls,
954
- bindings
955
- }));
956
- if (spec.additionalRules?.length) {
957
- parts.push("");
958
- for (const rule of spec.additionalRules) parts.push(`- ${rule}`);
959
- }
960
- return parts.join("\n");
961
- }
962
340
  var openUIPromptSpec = {
963
341
  components: {
964
342
  Root: {
@@ -994,8 +372,8 @@ var openUIPromptSpec = {
994
372
  description: "A button that triggers interactive actions or conversational updates."
995
373
  },
996
374
  PanelAction: {
997
- signature: 'PanelAction(label: string, panel: "resources" | "workspace" | "artifacts" | "session-insights", relativePath?: any, focus?: boolean)',
998
- description: "A trusted local action that opens Resources, Workspace, Artifacts, or Session insights. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
375
+ signature: 'PanelAction(label: string, panel: "resources" | "workspace" | "artifacts" | "repl" | "subagents" | "session-insights", relativePath?: any, focus?: boolean)',
376
+ description: "A trusted local action that opens Resources, Workspace, Artifacts, REPL, Subagents, or Session insights. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
999
377
  },
1000
378
  Input: {
1001
379
  signature: 'Input(name: string, value: $binding<string>, placeholder?: string, type?: "text" | "email" | "number" | "password" | "search", disabled?: boolean)',
@@ -1317,6 +695,8 @@ var openUIPromptSpec = {
1317
695
  "resources",
1318
696
  "workspace",
1319
697
  "artifacts",
698
+ "repl",
699
+ "subagents",
1320
700
  "session-insights"
1321
701
  ]
1322
702
  },
@@ -1332,7 +712,7 @@ var openUIPromptSpec = {
1332
712
  "focus"
1333
713
  ],
1334
714
  additionalProperties: false,
1335
- description: "A trusted local action that opens Resources, Workspace, Artifacts, or Session insights. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
715
+ description: "A trusted local action that opens Resources, Workspace, Artifacts, REPL, Subagents, or Session insights. relativePath selects a contained workspace-relative path and is valid only for Workspace and Artifacts panels."
1336
716
  },
1337
717
  Input: {
1338
718
  type: "object",
@@ -3057,6 +2437,15 @@ function extractToolErrorText(result) {
3057
2437
  }
3058
2438
  return "Tool execution failed";
3059
2439
  }
2440
+ function extractToolBackgroundOutput(result) {
2441
+ if (!result || typeof result !== "object") return void 0;
2442
+ const record2 = result;
2443
+ if (typeof record2.backgroundOutput === "string") return record2.backgroundOutput;
2444
+ if (record2.details && typeof record2.details === "object") {
2445
+ const details = record2.details;
2446
+ if (typeof details.backgroundOutput === "string") return details.backgroundOutput;
2447
+ }
2448
+ }
3060
2449
  function toChatMessagesFromAgentMessages(messages, sessionId) {
3061
2450
  const output = [];
3062
2451
  for (const [index, message] of messages.entries()) {
@@ -3083,6 +2472,7 @@ function toChatMessagesFromAgentMessages(messages, sessionId) {
3083
2472
  const errorText = isError ? extractToolErrorText(result) : void 0;
3084
2473
  const errorEnvelope = errorText ? createFleetErrorEnvelope(errorText) : void 0;
3085
2474
  const durationMs = typeof result.durationMs === "number" ? result.durationMs : typeof result.details?.durationMs === "number" ? result.details.durationMs : void 0;
2475
+ const backgroundOutput = extractToolBackgroundOutput(result);
3086
2476
  let attached = false;
3087
2477
  if (toolCallId) for (let messageIndex = output.length - 1; messageIndex >= 0 && !attached; messageIndex -= 1) {
3088
2478
  const candidate = output[messageIndex];
@@ -3096,6 +2486,7 @@ function toChatMessagesFromAgentMessages(messages, sessionId) {
3096
2486
  output: toolResultOutput(result),
3097
2487
  result: toolResultOutput(result),
3098
2488
  ...durationMs !== void 0 ? { durationMs } : {},
2489
+ ...backgroundOutput !== void 0 ? { backgroundOutput } : {},
3099
2490
  ...errorEnvelope ? { error: errorEnvelope } : {}
3100
2491
  };
3101
2492
  output[messageIndex] = {
@@ -3115,6 +2506,7 @@ function toChatMessagesFromAgentMessages(messages, sessionId) {
3115
2506
  output: toolResultOutput(result),
3116
2507
  result: toolResultOutput(result),
3117
2508
  ...durationMs !== void 0 ? { durationMs } : {},
2509
+ ...backgroundOutput !== void 0 ? { backgroundOutput } : {},
3118
2510
  ...errorEnvelope ? { error: errorEnvelope } : {}
3119
2511
  }]
3120
2512
  });
@@ -3146,7 +2538,9 @@ function createEventMapperState(init) {
3146
2538
  inRun: false,
3147
2539
  presentation: init?.presentation ?? createEmptyPrimeAgentSessionPresentation(),
3148
2540
  activeUserBashId: void 0,
3149
- userBashSequence: 0
2541
+ userBashSequence: 0,
2542
+ rlmChildOverrides: new Map(init?.rlmChildOverrides),
2543
+ rlmChildRuntimeOverrides: /* @__PURE__ */ new Map()
3150
2544
  };
3151
2545
  }
3152
2546
  function resetRun(state) {
@@ -3252,7 +2646,9 @@ function computeRlmExecutionTree(rootSessionId, children, activeNodeId) {
3252
2646
  ...activeNodeId ? { activeNodeId } : {}
3253
2647
  };
3254
2648
  }
3255
- function safeRlmChild(child) {
2649
+ function safeRlmChild(child, override) {
2650
+ const childLastHeardFrom = child.lastHeardFrom;
2651
+ const lastHeardFrom = override?.lastHeardFrom ?? (typeof childLastHeardFrom === "number" ? childLastHeardFrom : void 0);
3256
2652
  return {
3257
2653
  id: child.id,
3258
2654
  ...child.parentId ? { parentId: child.parentId } : {},
@@ -3260,7 +2656,7 @@ function safeRlmChild(child) {
3260
2656
  ...child.sessionName ? { sessionName: child.sessionName } : {},
3261
2657
  ...child.model ? { model: child.model } : {},
3262
2658
  label: child.label,
3263
- status: child.status,
2659
+ status: override?.status ?? child.status,
3264
2660
  ...child.durationMs !== void 0 ? { durationMs: child.durationMs } : {},
3265
2661
  ...child.answerPreview ? { answerPreview: child.answerPreview } : {},
3266
2662
  ...child.toolUseCount !== void 0 ? { toolUseCount: child.toolUseCount } : {},
@@ -3269,9 +2665,63 @@ function safeRlmChild(child) {
3269
2665
  ...child.activity ? { activity: child.activity } : {},
3270
2666
  ...child.repliedSinceTask !== void 0 ? { repliedSinceTask: child.repliedSinceTask } : {},
3271
2667
  ...child.error ? { error: child.error } : {},
2668
+ ...lastHeardFrom !== void 0 ? { lastHeardFrom } : {},
3272
2669
  timestamp: Date.now()
3273
2670
  };
3274
2671
  }
2672
+ function rlmArtifactStatus(status) {
2673
+ if (status === "cancelled") return "cancelled";
2674
+ if (status === "error" || status === "failed") return "error";
2675
+ if (status === "done") return "success";
2676
+ return "running";
2677
+ }
2678
+ function applyRlmChildStatusOverrides(state, overrides) {
2679
+ for (const [childId, override] of overrides) state.rlmChildOverrides.set(childId, override);
2680
+ let changed = false;
2681
+ const rawRlmChildren = state.presentation.rlmChildren.map((child) => {
2682
+ const override = state.rlmChildOverrides.get(child.id);
2683
+ const runtimeOverride = state.rlmChildRuntimeOverrides.get(child.id);
2684
+ const status = override?.status ?? runtimeOverride?.status ?? child.status;
2685
+ const lastHeardFrom = override ? override.lastHeardFrom : runtimeOverride?.lastHeardFrom ?? child.lastHeardFrom;
2686
+ if (status === child.status && lastHeardFrom === child.lastHeardFrom) return child;
2687
+ changed = true;
2688
+ return {
2689
+ ...child,
2690
+ status,
2691
+ ...lastHeardFrom !== void 0 ? { lastHeardFrom } : {}
2692
+ };
2693
+ });
2694
+ if (!changed) return [];
2695
+ const rlmTree = computeRlmExecutionTree(state.sessionId, rawRlmChildren, state.presentation.rlmTree?.activeNodeId);
2696
+ const rlmChildren = rawRlmChildren.map((child) => {
2697
+ const treeNode = rlmTree.nodes[child.id];
2698
+ return treeNode ? {
2699
+ ...child,
2700
+ depth: treeNode.depth,
2701
+ childrenIds: treeNode.childrenIds
2702
+ } : child;
2703
+ });
2704
+ const updatedArtifacts = state.presentation.artifactRuns.map((run) => ({
2705
+ ...run,
2706
+ artifacts: run.artifacts.map((artifact) => {
2707
+ if (artifact.kind !== "rlm" || !artifact.sourceToolCallId) return artifact;
2708
+ const child = rlmChildren.find((entry) => entry.id === artifact.sourceToolCallId);
2709
+ if (!child) return artifact;
2710
+ return {
2711
+ ...artifact,
2712
+ status: rlmArtifactStatus(child.status),
2713
+ output: child,
2714
+ timestamp: child.timestamp
2715
+ };
2716
+ })
2717
+ }));
2718
+ return [emitPresentation(state, {
2719
+ ...state.presentation,
2720
+ rlmChildren,
2721
+ rlmTree,
2722
+ artifactRuns: updatedArtifacts
2723
+ })];
2724
+ }
3275
2725
  function safeGoal(goal) {
3276
2726
  return {
3277
2727
  active: goal.active,
@@ -3561,6 +3011,7 @@ function mapCoreAgentEvent(state, event) {
3561
3011
  }
3562
3012
  case "tool_execution_update": {
3563
3013
  const { category, toolName, serverName } = categorizeTool(event.toolName);
3014
+ const backgroundOutput = extractToolBackgroundOutput(event.partialResult);
3564
3015
  return [{
3565
3016
  type: "tool",
3566
3017
  part: upsertCurrentToolPart(state, {
@@ -3571,7 +3022,8 @@ function mapCoreAgentEvent(state, event) {
3571
3022
  toolCallId: event.toolCallId,
3572
3023
  state: "input-streaming",
3573
3024
  input: event.args,
3574
- result: event.partialResult
3025
+ result: event.partialResult,
3026
+ ...backgroundOutput !== void 0 ? { backgroundOutput } : {}
3575
3027
  }),
3576
3028
  messageId: state.currentMessageId
3577
3029
  }];
@@ -3581,6 +3033,7 @@ function mapCoreAgentEvent(state, event) {
3581
3033
  const errorText = event.isError ? extractToolErrorText(event.result) : void 0;
3582
3034
  const errorEnvelope = errorText ? createFleetErrorEnvelope(errorText) : void 0;
3583
3035
  const durationMs = typeof event.result?.durationMs === "number" ? event.result.durationMs : typeof event.result?.details?.durationMs === "number" ? event.result.details.durationMs : void 0;
3036
+ const backgroundOutput = extractToolBackgroundOutput(event.result);
3584
3037
  return [{
3585
3038
  type: "tool",
3586
3039
  part: upsertCurrentToolPart(state, {
@@ -3593,6 +3046,7 @@ function mapCoreAgentEvent(state, event) {
3593
3046
  output: event.result,
3594
3047
  result: event.result,
3595
3048
  ...durationMs !== void 0 ? { durationMs } : {},
3049
+ ...backgroundOutput !== void 0 ? { backgroundOutput } : {},
3596
3050
  ...errorEnvelope ? { error: errorEnvelope } : {}
3597
3051
  }),
3598
3052
  messageId: state.currentMessageId
@@ -3766,7 +3220,12 @@ function mapSessionSpecificEvent(state, event) {
3766
3220
  serviceTier: event.serviceTier
3767
3221
  })];
3768
3222
  case "rlm_child_update": {
3769
- const child = safeRlmChild(event.child);
3223
+ const runtimeChild = safeRlmChild(event.child);
3224
+ state.rlmChildRuntimeOverrides.set(event.child.id, {
3225
+ status: runtimeChild.status,
3226
+ ...runtimeChild.lastHeardFrom !== void 0 ? { lastHeardFrom: runtimeChild.lastHeardFrom } : {}
3227
+ });
3228
+ const child = safeRlmChild(event.child, state.rlmChildOverrides.get(event.child.id));
3770
3229
  const rawRlmChildren = state.presentation.rlmChildren.filter((entry) => entry.id !== child.id);
3771
3230
  rawRlmChildren.push(child);
3772
3231
  const rlmTree = computeRlmExecutionTree(state.sessionId, rawRlmChildren, child.id);
@@ -3789,7 +3248,7 @@ function mapSessionSpecificEvent(state, event) {
3789
3248
  sourceToolCallId: child.id,
3790
3249
  kind: "rlm",
3791
3250
  title: child.label,
3792
- status: child.status === "cancelled" ? "cancelled" : child.status === "error" ? "error" : child.status === "done" ? "success" : "running",
3251
+ status: rlmArtifactStatus(child.status),
3793
3252
  output: child,
3794
3253
  timestamp: child.timestamp
3795
3254
  };
@@ -3952,7 +3411,14 @@ function mapAgentConnectionEvent(state, event) {
3952
3411
  resetRun(state);
3953
3412
  const events = [];
3954
3413
  if (event.snapshot.parent || event.snapshot.children) {
3955
- const rawRlmChildren = (event.snapshot.children ?? []).map(safeRlmChild);
3414
+ const rawRlmChildren = (event.snapshot.children ?? []).map((child) => {
3415
+ const runtimeChild = safeRlmChild(child);
3416
+ state.rlmChildRuntimeOverrides.set(child.id, {
3417
+ status: runtimeChild.status,
3418
+ ...runtimeChild.lastHeardFrom !== void 0 ? { lastHeardFrom: runtimeChild.lastHeardFrom } : {}
3419
+ });
3420
+ return safeRlmChild(child, state.rlmChildOverrides.get(child.id));
3421
+ });
3956
3422
  const rlmTree = computeRlmExecutionTree(state.sessionId, rawRlmChildren);
3957
3423
  const rlmChildren = rawRlmChildren.map((c) => {
3958
3424
  const treeNode = rlmTree.nodes[c.id];
@@ -4283,6 +3749,9 @@ var RingBuffer = class {
4283
3749
  size() {
4284
3750
  return this.entries.length;
4285
3751
  }
3752
+ latestSequence() {
3753
+ return this.entries.at(-1)?.seq ?? 0;
3754
+ }
4286
3755
  clear() {
4287
3756
  this.entries.length = 0;
4288
3757
  this.nextSeq = 1;
@@ -4511,10 +3980,76 @@ function isSessionNotResumableError(error) {
4511
3980
  const message = error instanceof Error ? error.message : String(error);
4512
3981
  return SESSION_NOT_RESUMABLE_PATTERNS.some((pattern) => pattern.test(message));
4513
3982
  }
3983
+ function sessionSummaryIdentifiers(summary) {
3984
+ return [
3985
+ summary.id,
3986
+ summary.sessionId,
3987
+ summary.activeSessionId
3988
+ ].flatMap((value) => typeof value === "string" && value.length > 0 ? [value] : []);
3989
+ }
3990
+ function sessionSummaryParentIdentifiers(summary) {
3991
+ return [summary.parentSessionId, summary.parentActiveSessionId].flatMap((value) => typeof value === "string" && value.length > 0 ? [value] : []);
3992
+ }
3993
+ function sessionSummaryPath(summary) {
3994
+ return typeof summary.sessionFile === "string" && summary.sessionFile.length > 0 ? resolve(summary.sessionFile) : void 0;
3995
+ }
3996
+ function sessionSummaryParentPaths(summary) {
3997
+ return [summary.parentSessionPath].flatMap((value) => typeof value === "string" && value.length > 0 ? [resolve(value)] : []);
3998
+ }
3999
+ function hasSessionLineage(candidate, rootIdentifiers, rootPaths, sessionsByIdentifier, sessionsByPath) {
4000
+ const pending = [candidate];
4001
+ const visited = /* @__PURE__ */ new Set();
4002
+ while (pending.length > 0) {
4003
+ const current = pending.pop();
4004
+ if (!current || visited.has(current)) continue;
4005
+ visited.add(current);
4006
+ for (const parentId of sessionSummaryParentIdentifiers(current)) {
4007
+ if (rootIdentifiers.has(parentId)) return true;
4008
+ const parent = sessionsByIdentifier.get(parentId);
4009
+ if (parent && !visited.has(parent)) pending.push(parent);
4010
+ }
4011
+ for (const parentPath of sessionSummaryParentPaths(current)) {
4012
+ if (rootPaths.has(parentPath)) return true;
4013
+ const parent = sessionsByPath.get(parentPath);
4014
+ if (parent && !visited.has(parent)) pending.push(parent);
4015
+ }
4016
+ }
4017
+ return false;
4018
+ }
4019
+ async function sessionLineagePaths(sessionPath) {
4020
+ const paths = /* @__PURE__ */ new Set();
4021
+ let currentPath = resolve(sessionPath);
4022
+ while (!paths.has(currentPath)) {
4023
+ paths.add(currentPath);
4024
+ try {
4025
+ const parentSession = (await SessionManager.openAsync(currentPath)).getHeader()?.parentSession;
4026
+ if (!parentSession) break;
4027
+ currentPath = resolve(dirname(currentPath), parentSession);
4028
+ } catch {
4029
+ break;
4030
+ }
4031
+ }
4032
+ return paths;
4033
+ }
4034
+ function rlmChildStatusOverride(summary) {
4035
+ const status = summary.statusLabel === "failed" || summary.workerState === "failed" ? "failed" : summary.statusLabel === "recovering" || summary.workerState === "recovering" ? "recovering" : void 0;
4036
+ const lastHeardFrom = summary.lastHeardFromAt ? Date.parse(summary.lastHeardFromAt) : NaN;
4037
+ return {
4038
+ ...status ? { status } : {},
4039
+ ...Number.isFinite(lastHeardFrom) ? { lastHeardFrom } : {}
4040
+ };
4041
+ }
4042
+ function effectiveRlmChildStatus(child, summary) {
4043
+ return rlmChildStatusOverride(summary).status ?? child.status;
4044
+ }
4514
4045
  var PrimeBridge = class {
4515
4046
  #sessions = /* @__PURE__ */ new Map();
4516
4047
  #listeners = /* @__PURE__ */ new Set();
4517
4048
  #ringBuffers = /* @__PURE__ */ new Map();
4049
+ #rlmChildStreams = /* @__PURE__ */ new Map();
4050
+ #rlmChildStreamInitializations = /* @__PURE__ */ new Map();
4051
+ #rlmChildMetadataRefreshes = /* @__PURE__ */ new Map();
4052
+ #rlmChildMetadataRefreshPending = /* @__PURE__ */ new Set();
4518
4053
  #dialogs;
4519
4054
  #kernelTimeoutMs;
4520
4055
  #ringBufferCapacity;
@@ -4601,6 +4136,15 @@ var PrimeBridge = class {
4601
4136
  }
4602
4137
  /** Test-only: reset state. */
4603
4138
  resetForTests() {
4139
+ for (const stream of this.#rlmChildStreams.values()) {
4140
+ stream.closed = true;
4141
+ stream.removeWatcherListener();
4142
+ stream.watcher.close().catch(() => void 0);
4143
+ }
4144
+ this.#rlmChildStreams.clear();
4145
+ this.#rlmChildStreamInitializations.clear();
4146
+ this.#rlmChildMetadataRefreshes.clear();
4147
+ this.#rlmChildMetadataRefreshPending.clear();
4604
4148
  for (const session of this.#sessions.values()) {
4605
4149
  session.unsubscribe();
4606
4150
  session.connection.dispose().catch(() => void 0);
@@ -4751,6 +4295,7 @@ var PrimeBridge = class {
4751
4295
  if (frame.type === "presentation") this.#persistPresentation(sessionId, sessionPath, frame.presentation);
4752
4296
  this.#dispatch(sessionId, frame);
4753
4297
  }
4298
+ if (event.type === "session_resynced" || event.type === "session_event" && event.event.type === "rlm_child_update") this.#queueRlmChildMetadataRefresh(sessionId);
4754
4299
  });
4755
4300
  const bridgeSession = {
4756
4301
  sessionId,
@@ -4843,6 +4388,363 @@ var PrimeBridge = class {
4843
4388
  async listSessions(cwd) {
4844
4389
  return this.#sessionLister(cwd);
4845
4390
  }
4391
+ async #resolveRlmLineage(sessions2, rootSessionId, rootSessionPath) {
4392
+ const sessionsByIdentifier = /* @__PURE__ */ new Map();
4393
+ const sessionsByPath = /* @__PURE__ */ new Map();
4394
+ for (const session of sessions2) {
4395
+ for (const identifier of sessionSummaryIdentifiers(session)) if (!sessionsByIdentifier.has(identifier)) sessionsByIdentifier.set(identifier, session);
4396
+ const path = sessionSummaryPath(session);
4397
+ if (path && !sessionsByPath.has(path)) sessionsByPath.set(path, session);
4398
+ }
4399
+ const rootIdentifiers = /* @__PURE__ */ new Set([rootSessionId]);
4400
+ const rootPaths = new Set(await sessionLineagePaths(rootSessionPath));
4401
+ const rootSummary = sessionsByIdentifier.get(rootSessionId);
4402
+ if (rootSummary) {
4403
+ for (const identifier of sessionSummaryIdentifiers(rootSummary)) rootIdentifiers.add(identifier);
4404
+ for (const path of sessionSummaryParentPaths(rootSummary)) rootPaths.add(path);
4405
+ }
4406
+ for (const rootPath of rootPaths) {
4407
+ const rootAncestor = sessionsByPath.get(rootPath);
4408
+ if (!rootAncestor) continue;
4409
+ for (const identifier of sessionSummaryIdentifiers(rootAncestor)) rootIdentifiers.add(identifier);
4410
+ }
4411
+ return {
4412
+ sessionsByIdentifier,
4413
+ sessionsByPath,
4414
+ rootIdentifiers,
4415
+ rootPaths
4416
+ };
4417
+ }
4418
+ async #findAuthorizedRlmChild(parentSessionId, childId) {
4419
+ const parent = this.#sessions.get(parentSessionId);
4420
+ const child = parent?.mapperState.presentation.rlmChildren.find((entry) => entry.id === childId);
4421
+ if (!parent || !child) return void 0;
4422
+ const sessions2 = await this.#sessionLister();
4423
+ const { sessionsByIdentifier, sessionsByPath, rootIdentifiers, rootPaths } = await this.#resolveRlmLineage(sessions2, parentSessionId, parent.sessionPath);
4424
+ const summary = sessions2.find((candidate) => candidate.rlmChildId === childId && hasSessionLineage(candidate, rootIdentifiers, rootPaths, sessionsByIdentifier, sessionsByPath));
4425
+ return summary ? {
4426
+ parent,
4427
+ child,
4428
+ summary
4429
+ } : void 0;
4430
+ }
4431
+ #queueRlmChildMetadataRefresh(rootSessionId) {
4432
+ this.#rlmChildMetadataRefreshPending.add(rootSessionId);
4433
+ if (this.#rlmChildMetadataRefreshes.has(rootSessionId)) return;
4434
+ const refresh = (async () => {
4435
+ while (this.#rlmChildMetadataRefreshPending.delete(rootSessionId)) await this.#refreshRlmChildMetadata(rootSessionId);
4436
+ })();
4437
+ this.#rlmChildMetadataRefreshes.set(rootSessionId, refresh);
4438
+ refresh.finally(() => {
4439
+ if (this.#rlmChildMetadataRefreshes.get(rootSessionId) === refresh) this.#rlmChildMetadataRefreshes.delete(rootSessionId);
4440
+ }).catch(() => void 0);
4441
+ }
4442
+ async #refreshRlmChildMetadata(rootSessionId) {
4443
+ const parent = this.#sessions.get(rootSessionId);
4444
+ if (!parent) return;
4445
+ let sessions2;
4446
+ try {
4447
+ sessions2 = await this.#sessionLister();
4448
+ } catch {
4449
+ for (const child of parent.mapperState.presentation.rlmChildren) parent.mapperState.rlmChildOverrides.delete(child.id);
4450
+ for (const frame of applyRlmChildStatusOverrides(parent.mapperState, /* @__PURE__ */ new Map())) this.#dispatch(rootSessionId, frame);
4451
+ return;
4452
+ }
4453
+ const { sessionsByIdentifier, sessionsByPath, rootIdentifiers, rootPaths } = await this.#resolveRlmLineage(sessions2, rootSessionId, parent.sessionPath);
4454
+ const overrides = /* @__PURE__ */ new Map();
4455
+ for (const child of parent.mapperState.presentation.rlmChildren) {
4456
+ const summary = sessions2.find((candidate) => candidate.rlmChildId === child.id && hasSessionLineage(candidate, rootIdentifiers, rootPaths, sessionsByIdentifier, sessionsByPath));
4457
+ if (summary) overrides.set(child.id, rlmChildStatusOverride(summary));
4458
+ else parent.mapperState.rlmChildOverrides.delete(child.id);
4459
+ }
4460
+ const frames = applyRlmChildStatusOverrides(parent.mapperState, overrides);
4461
+ for (const frame of frames) {
4462
+ if (frame.type === "presentation") this.#persistPresentation(rootSessionId, parent.sessionPath, frame.presentation);
4463
+ this.#dispatch(rootSessionId, frame);
4464
+ }
4465
+ }
4466
+ #childStreamStatus(child, summary) {
4467
+ const status = summary ? effectiveRlmChildStatus(child, summary) : child.status;
4468
+ if (status === "error" || status === "failed") return "error";
4469
+ if (status === "running" || status === "recovering") return "streaming";
4470
+ return "ready";
4471
+ }
4472
+ async #closeRlmChildStream(stream) {
4473
+ if (stream.closed) return;
4474
+ stream.closed = true;
4475
+ if (this.#rlmChildStreams.get(stream.key) === stream) this.#rlmChildStreams.delete(stream.key);
4476
+ stream.buffering = false;
4477
+ stream.bufferedEvents.length = 0;
4478
+ stream.removeWatcherListener();
4479
+ await stream.watcher.close().catch(() => void 0);
4480
+ this.#ringBuffers.delete(stream.channelId);
4481
+ }
4482
+ async #publicRlmChildStream(stream, resume) {
4483
+ const requestedCursor = resume?.lastEventId && resume.lastEventId > 0 ? resume.lastEventId : 0;
4484
+ const generationMatches = resume?.streamGeneration === stream.streamGeneration;
4485
+ const buffer = this.#ringBufferFor(stream.channelId);
4486
+ const latest = buffer.latestSequence();
4487
+ const cursorOverflowed = generationMatches && requestedCursor > 0 ? buffer.replaySince(requestedCursor).overflowed : false;
4488
+ const canResume = generationMatches && requestedCursor > 0 && (requestedCursor === 0 || requestedCursor <= latest) && !cursorOverflowed;
4489
+ if (!canResume && !stream.snapshot.terminal && (resume?.streamGeneration !== void 0 || requestedCursor > 0)) await this.#refreshRlmChildSnapshot(stream);
4490
+ const refreshedLatest = buffer.latestSequence();
4491
+ const includeSnapshot = !canResume || stream.snapshot.terminal === true;
4492
+ const cursorReset = (resume?.streamGeneration !== void 0 || requestedCursor > 0) && !canResume;
4493
+ const replayFrom = canResume ? requestedCursor : stream.snapshot.terminal ? refreshedLatest : stream.replayFrom;
4494
+ let released = false;
4495
+ return {
4496
+ sessionId: stream.streamSessionId,
4497
+ projectId: stream.projectId,
4498
+ snapshot: stream.snapshot,
4499
+ channelId: stream.channelId,
4500
+ streamGeneration: stream.streamGeneration,
4501
+ mode: "live",
4502
+ resumeAccepted: canResume,
4503
+ cursorReset,
4504
+ replayFrom,
4505
+ includeSnapshot,
4506
+ release: async () => {
4507
+ if (released) return;
4508
+ released = true;
4509
+ stream.refs = Math.max(0, stream.refs - 1);
4510
+ if (stream.refs === 0) await this.#closeRlmChildStream(stream);
4511
+ }
4512
+ };
4513
+ }
4514
+ async #refreshRlmChildSnapshot(stream) {
4515
+ if (stream.closed) return;
4516
+ stream.buffering = true;
4517
+ const tracked = stream.refreshTail.catch(() => void 0).then(async () => {
4518
+ if (stream.closed) return;
4519
+ const messages = toChatMessagesFromAgentMessages(await stream.watcher.getMessages(), stream.canonicalSessionId);
4520
+ if (stream.closed) return;
4521
+ stream.snapshot = {
4522
+ ...stream.snapshot,
4523
+ messages,
4524
+ presentation: stream.mapperState.presentation
4525
+ };
4526
+ this.#dispatch(stream.channelId, stream.snapshot);
4527
+ stream.replayFrom = this.#ringBufferFor(stream.channelId).latestSequence();
4528
+ }).catch(() => void 0);
4529
+ stream.refreshTail = tracked;
4530
+ await tracked;
4531
+ if (stream.refreshTail === tracked) {
4532
+ stream.buffering = false;
4533
+ for (const event of stream.bufferedEvents.splice(0)) this.#handleRlmChildEvent(stream, event);
4534
+ }
4535
+ }
4536
+ #queueRlmChildSnapshot(stream) {
4537
+ this.#refreshRlmChildSnapshot(stream);
4538
+ }
4539
+ #handleRlmChildEvent(stream, event) {
4540
+ if (stream.closed) return;
4541
+ if (event.type === "session_event") {
4542
+ if (event.event.type === "agent_start" || event.event.type === "turn_start") stream.snapshot = {
4543
+ ...stream.snapshot,
4544
+ status: "streaming",
4545
+ terminal: false
4546
+ };
4547
+ if (event.event.type === "agent_end" || event.event.type === "turn_end") stream.snapshot = {
4548
+ ...stream.snapshot,
4549
+ status: "ready"
4550
+ };
4551
+ }
4552
+ if (event.type === "closed") stream.snapshot = {
4553
+ ...stream.snapshot,
4554
+ status: event.error ? "error" : "ready",
4555
+ terminal: true
4556
+ };
4557
+ const frames = mapAgentConnectionEvent(stream.mapperState, event);
4558
+ for (const frame of frames) {
4559
+ if (frame.type === "error") stream.snapshot = {
4560
+ ...stream.snapshot,
4561
+ status: "error"
4562
+ };
4563
+ this.#dispatch(stream.channelId, frame);
4564
+ }
4565
+ if (event.type === "session_event" && event.event.type === "rlm_child_update") this.#queueRlmChildMetadataRefresh(stream.parentSessionId);
4566
+ if (event.type === "session_replaced" || event.type === "session_resynced" || event.type === "closed" || event.type === "session_event" && (event.event.type === "agent_end" || event.event.type === "turn_end")) this.#queueRlmChildSnapshot(stream);
4567
+ }
4568
+ async #loadAuthorizedRlmChildTranscript(authorized) {
4569
+ const { summary: childSummary } = authorized;
4570
+ if (!childSummary.sessionFile) return void 0;
4571
+ const sessionManager = await SessionManager.openAsync(childSummary.sessionFile);
4572
+ const sessionId = sessionManager.getSessionId();
4573
+ if (sessionId !== childSummary.sessionId && sessionId !== childSummary.id) return void 0;
4574
+ const agentMessages = sessionManager.buildSessionContext().messages;
4575
+ const messages = toChatMessagesFromAgentMessages(agentMessages, sessionId);
4576
+ const presentation = initialPresentationForSession(agentMessages, void 0, void 0, void 0, void 0, sessionId, await loadManagedPrimePresentation({ sessionPath: childSummary.sessionFile }));
4577
+ return {
4578
+ sessionId,
4579
+ projectId: await getPrimeConfig().projectRegistry.projectIdForSession(sessionId, sessionManager.getCwd()),
4580
+ messages,
4581
+ presentation
4582
+ };
4583
+ }
4584
+ async #snapshotOnlyRlmChildStream(authorized, resume) {
4585
+ const transcript = await this.#loadAuthorizedRlmChildTranscript(authorized).catch(() => void 0);
4586
+ if (!transcript) return void 0;
4587
+ const streamGeneration = crypto.randomUUID();
4588
+ const snapshot2 = {
4589
+ type: "session_snapshot",
4590
+ session: {
4591
+ sessionId: transcript.sessionId,
4592
+ projectId: transcript.projectId
4593
+ },
4594
+ messages: transcript.messages,
4595
+ presentation: transcript.presentation,
4596
+ status: this.#childStreamStatus(authorized.child, authorized.summary),
4597
+ terminal: true
4598
+ };
4599
+ return {
4600
+ sessionId: transcript.sessionId,
4601
+ projectId: transcript.projectId,
4602
+ snapshot: snapshot2,
4603
+ channelId: `snapshot:${authorized.parent.sessionId}:${authorized.child.id}:${streamGeneration}`,
4604
+ streamGeneration,
4605
+ mode: "snapshot-only",
4606
+ resumeAccepted: false,
4607
+ cursorReset: resume?.streamGeneration !== void 0 || (resume?.lastEventId ?? 0) > 0,
4608
+ replayFrom: 0,
4609
+ includeSnapshot: true,
4610
+ release: async () => void 0
4611
+ };
4612
+ }
4613
+ async #initializeRlmChildStream(authorized) {
4614
+ const { child, summary, parent } = authorized;
4615
+ const runtimeIds = [
4616
+ summary.activeSessionId,
4617
+ child.activeSessionId,
4618
+ summary.sessionId,
4619
+ summary.id,
4620
+ child.id
4621
+ ].filter((value) => typeof value === "string" && value.length > 0);
4622
+ let watcher;
4623
+ let streamSessionId;
4624
+ for (const runtimeId of [...new Set(runtimeIds)]) {
4625
+ try {
4626
+ watcher = await parent.connection.watchSession(runtimeId);
4627
+ } catch {
4628
+ watcher = void 0;
4629
+ }
4630
+ if (watcher) {
4631
+ streamSessionId = runtimeId;
4632
+ break;
4633
+ }
4634
+ }
4635
+ if (!watcher || !streamSessionId) return void 0;
4636
+ const pendingEvents = [];
4637
+ let buffering = true;
4638
+ let removeWatcherListener = () => void 0;
4639
+ try {
4640
+ removeWatcherListener = watcher.subscribe((event) => {
4641
+ if (buffering) pendingEvents.push(event);
4642
+ else {
4643
+ const stream2 = this.#rlmChildStreams.get(`${parent.sessionId}:${child.id}`);
4644
+ if (!stream2) return;
4645
+ if (stream2.buffering) stream2.bufferedEvents.push(event);
4646
+ else this.#handleRlmChildEvent(stream2, event);
4647
+ }
4648
+ });
4649
+ const agentMessages = await watcher.getMessages();
4650
+ const persistedPresentation = summary.sessionFile ? await loadManagedPrimePresentation({ sessionPath: summary.sessionFile }) : void 0;
4651
+ const canonicalSessionId = summary.sessionId || streamSessionId;
4652
+ const override = rlmChildStatusOverride(summary);
4653
+ const presentation = initialPresentationForSession(agentMessages, summary.sessionName ?? child.sessionName ?? child.label, summary.thinkingLevel, void 0, child.recap ?? summary.summary, canonicalSessionId, persistedPresentation);
4654
+ const mapperState = createEventMapperState({
4655
+ sessionId: canonicalSessionId,
4656
+ presentation,
4657
+ rlmChildOverrides: /* @__PURE__ */ new Map([[child.id, override]])
4658
+ });
4659
+ const projectId = await getPrimeConfig().projectRegistry.projectIdForSession(canonicalSessionId, summary.cwd);
4660
+ const streamGeneration = crypto.randomUUID();
4661
+ const stream = {
4662
+ key: `${parent.sessionId}:${child.id}`,
4663
+ parentSessionId: parent.sessionId,
4664
+ childId: child.id,
4665
+ streamSessionId,
4666
+ canonicalSessionId,
4667
+ channelId: `child:${parent.sessionId}:${child.id}:${streamGeneration}`,
4668
+ streamGeneration,
4669
+ projectId,
4670
+ child,
4671
+ summary,
4672
+ watcher,
4673
+ mapperState,
4674
+ snapshot: {
4675
+ type: "session_snapshot",
4676
+ session: {
4677
+ sessionId: canonicalSessionId,
4678
+ projectId
4679
+ },
4680
+ messages: toChatMessagesFromAgentMessages(agentMessages, canonicalSessionId),
4681
+ presentation,
4682
+ status: this.#childStreamStatus(child, summary)
4683
+ },
4684
+ replayFrom: 0,
4685
+ refs: 1,
4686
+ closed: false,
4687
+ buffering: false,
4688
+ bufferedEvents: [],
4689
+ removeWatcherListener,
4690
+ refreshTail: Promise.resolve()
4691
+ };
4692
+ this.#rlmChildStreams.set(stream.key, stream);
4693
+ this.#ringBufferFor(stream.channelId);
4694
+ buffering = false;
4695
+ for (const event of pendingEvents.splice(0)) this.#handleRlmChildEvent(stream, event);
4696
+ return stream;
4697
+ } catch {
4698
+ buffering = false;
4699
+ removeWatcherListener();
4700
+ await watcher.close().catch(() => void 0);
4701
+ return;
4702
+ }
4703
+ }
4704
+ /**
4705
+ * Open a read-only stream for an authorized RLM child. Completed and cold
4706
+ * children use a one-shot snapshot and never resume a runtime session.
4707
+ */
4708
+ async openRlmChildStream(parentSessionId, childId, resume) {
4709
+ const authorized = await this.#findAuthorizedRlmChild(parentSessionId, childId);
4710
+ if (!authorized) return void 0;
4711
+ const key = `${parentSessionId}:${childId}`;
4712
+ const existing = this.#rlmChildStreams.get(key);
4713
+ if (existing) {
4714
+ existing.refs += 1;
4715
+ return this.#publicRlmChildStream(existing, resume);
4716
+ }
4717
+ const status = effectiveRlmChildStatus(authorized.child, authorized.summary);
4718
+ if (status !== "running" && status !== "recovering") return this.#snapshotOnlyRlmChildStream(authorized, resume);
4719
+ const pending = this.#rlmChildStreamInitializations.get(key);
4720
+ if (pending) {
4721
+ const stream = await pending;
4722
+ if (!stream) return void 0;
4723
+ stream.refs += 1;
4724
+ return this.#publicRlmChildStream(stream, resume);
4725
+ }
4726
+ const initialization = this.#initializeRlmChildStream(authorized);
4727
+ this.#rlmChildStreamInitializations.set(key, initialization);
4728
+ try {
4729
+ const stream = await initialization;
4730
+ if (!stream) return void 0;
4731
+ return this.#publicRlmChildStream(stream, resume);
4732
+ } finally {
4733
+ if (this.#rlmChildStreamInitializations.get(key) === initialization) this.#rlmChildStreamInitializations.delete(key);
4734
+ }
4735
+ }
4736
+ /**
4737
+ * Load a completed RLM child without resuming it as a live session.
4738
+ *
4739
+ * Child transcripts can be stored outside the parent's configured session
4740
+ * directory. Authorization is therefore based on both the live parent's
4741
+ * presentation and the daemon's lineage metadata, never on a browser-
4742
+ * supplied filesystem path.
4743
+ */
4744
+ async loadRlmChildTranscript(parentSessionId, childId) {
4745
+ const authorized = await this.#findAuthorizedRlmChild(parentSessionId, childId);
4746
+ return authorized ? this.#loadAuthorizedRlmChildTranscript(authorized) : void 0;
4747
+ }
4846
4748
  async deleteSession(sessionId) {
4847
4749
  let existing = this.#sessions.get(sessionId);
4848
4750
  if (!existing) {
@@ -4868,6 +4770,11 @@ var PrimeBridge = class {
4868
4770
  await pendingPresentationWrite?.catch(() => void 0);
4869
4771
  if (this.#presentationWrites.get(existing.sessionId) === pendingPresentationWrite) this.#presentationWrites.delete(existing.sessionId);
4870
4772
  this.#dialogs.cancelAll(existing.sessionId, "server-shutdown");
4773
+ for (const childStream of [...this.#rlmChildStreams.values()]) {
4774
+ if (childStream.parentSessionId !== existing.sessionId) continue;
4775
+ childStream.refs = 0;
4776
+ await this.#closeRlmChildStream(childStream);
4777
+ }
4871
4778
  existing.unsubscribe();
4872
4779
  await existing.connection.abort().catch(() => void 0);
4873
4780
  await this.#openUIPromptTransitions.get(existing.sessionId)?.catch(() => void 0);
@@ -4956,6 +4863,18 @@ var PrimeBridge = class {
4956
4863
  async followUp(sessionId, text) {
4957
4864
  await this.#requireSession(sessionId).connection.followUp(text);
4958
4865
  }
4866
+ async deleteQueuedMessage(sessionId, lane, index, expectedText) {
4867
+ const session = this.#requireSession(sessionId);
4868
+ const status = await session.connection.mutateQueuedMessage(lane, index, expectedText, { type: "delete" });
4869
+ const queue = await session.connection.getQueue();
4870
+ return {
4871
+ status,
4872
+ queue: {
4873
+ steering: [...queue.steering],
4874
+ followUp: [...queue.followUp]
4875
+ }
4876
+ };
4877
+ }
4959
4878
  async abort(sessionId) {
4960
4879
  const session = this.#requireSession(sessionId);
4961
4880
  this.#dialogs.cancelAll(sessionId, "user-abort");
@@ -5779,103 +5698,162 @@ function normalizeSseReplayEvent(event) {
5779
5698
  if (!event || typeof event !== "object" || !("frame" in event)) return event;
5780
5699
  return event.frame ?? event;
5781
5700
  }
5782
- function handleChatEventsGet(request) {
5783
- return wrapApiHandler(async () => {
5784
- const url = new URL(request.url);
5785
- const sessionId = url.searchParams.get("sessionId");
5786
- if (!sessionId) return Response.json({ message: "SSE requires ?sessionId=" }, { status: 400 });
5787
- const lastEventIdRaw = request.headers.get("last-event-id") ?? url.searchParams.get("lastEventId");
5788
- const parsedLastEventId = lastEventIdRaw ? Number.parseInt(lastEventIdRaw, 10) : 0;
5789
- const lastEventId = Number.isFinite(parsedLastEventId) && parsedLastEventId > 0 ? parsedLastEventId : 0;
5790
- const bridge = getBridge();
5791
- const encoder = new TextEncoder();
5792
- let heartbeat;
5793
- let removeListener;
5794
- const stream = new ReadableStream({
5795
- async start(controller) {
5796
- let closed = false;
5797
- const enqueue = (data) => {
5798
- if (closed) return;
5799
- try {
5800
- controller.enqueue(encoder.encode(data));
5801
- } catch {
5802
- closed = true;
5803
- }
5804
- };
5805
- const write = (chunk) => {
5806
- const lines = [
5807
- chunk.id !== void 0 ? `id: ${chunk.id}
5701
+ function lastEventIdFor(request, url) {
5702
+ const raw = request.headers.get("last-event-id") ?? url.searchParams.get("lastEventId");
5703
+ const parsed = raw ? Number.parseInt(raw, 10) : 0;
5704
+ return Number.isFinite(parsed) && parsed > 0 ? parsed : 0;
5705
+ }
5706
+ function createSseResponse(request, bridge, source, lastEventId) {
5707
+ const encoder = new TextEncoder();
5708
+ let heartbeat;
5709
+ let removeListener;
5710
+ let cleaned = false;
5711
+ let released = false;
5712
+ const releaseSource = () => {
5713
+ if (released) return;
5714
+ released = true;
5715
+ const release = source.release;
5716
+ if (release) release().catch(() => void 0);
5717
+ };
5718
+ const stream = new ReadableStream({
5719
+ async start(controller) {
5720
+ let closed = false;
5721
+ const enqueue = (data) => {
5722
+ if (closed) return;
5723
+ try {
5724
+ controller.enqueue(encoder.encode(data));
5725
+ } catch {
5726
+ closed = true;
5727
+ }
5728
+ };
5729
+ const write = (chunk) => {
5730
+ const lines = [
5731
+ chunk.id !== void 0 ? `id: ${chunk.id}
5808
5732
  ` : "",
5809
- `event: message
5810
- `,
5811
- `data: ${JSON.stringify(chunk.data)}
5733
+ "event: message\n",
5734
+ `data: ${JSON.stringify(chunk.data)}
5812
5735
 
5813
5736
  `
5814
- ];
5815
- enqueue(lines.join(""));
5816
- };
5817
- write({ data: {
5818
- type: "connected",
5819
- sessionId,
5820
- adapterCapabilities: FLEET_ADAPTER_CAPABILITIES
5821
- } });
5822
- let liveCursor = lastEventId;
5823
- let pendingQuestionIds = lastEventId === 0 ? new Set(bridge.pendingDialogsFor(sessionId).map((dialog) => dialog.toolCallId)) : null;
5824
- const flush = () => {
5825
- const { replayed } = bridge.replaySince(sessionId, liveCursor);
5826
- for (const entry of replayed) {
5827
- liveCursor = entry.seq;
5828
- const event = normalizeSseReplayEvent(entry.event);
5829
- if (!shouldReplaySseEvent(event, pendingQuestionIds)) continue;
5830
- write({
5831
- id: entry.seq,
5832
- data: event
5833
- });
5834
- }
5835
- pendingQuestionIds = null;
5836
- };
5837
- removeListener = bridge.addEventListener((sid) => {
5838
- if (sid !== sessionId) return;
5839
- flush();
5840
- });
5841
- if (lastEventId > 0) {
5842
- const { overflowed } = bridge.replaySince(sessionId, lastEventId);
5843
- if (overflowed) write({ data: {
5737
+ ];
5738
+ enqueue(lines.join(""));
5739
+ };
5740
+ const cleanup = () => {
5741
+ if (cleaned) return;
5742
+ cleaned = true;
5743
+ closed = true;
5744
+ if (heartbeat) clearInterval(heartbeat);
5745
+ removeListener?.();
5746
+ releaseSource();
5747
+ try {
5748
+ controller.close();
5749
+ } catch {
5750
+ }
5751
+ };
5752
+ const channelId = source.channelId ?? source.sessionId;
5753
+ let readyToFlush = false;
5754
+ let resyncSent = false;
5755
+ let liveCursor = source.replayFrom ?? lastEventId;
5756
+ let pendingQuestionIds = liveCursor === 0 ? new Set(bridge.pendingDialogsFor(source.sessionId).map((dialog) => dialog.toolCallId)) : null;
5757
+ const flush = () => {
5758
+ if (!readyToFlush || resyncSent || closed) return;
5759
+ const { replayed, overflowed } = bridge.replaySince(channelId, liveCursor);
5760
+ if (overflowed) {
5761
+ resyncSent = true;
5762
+ write({ data: {
5844
5763
  type: "state",
5845
5764
  state: {
5846
5765
  name: "agent_settled",
5847
5766
  message: "resync-required"
5848
5767
  }
5849
5768
  } });
5769
+ pendingQuestionIds = null;
5770
+ return;
5850
5771
  }
5851
- flush();
5852
- heartbeat = setInterval(() => {
5853
- enqueue(`: heartbeat
5854
-
5855
- `);
5856
- }, 15e3);
5857
- request.signal.addEventListener("abort", () => {
5858
- if (closed) return;
5859
- closed = true;
5860
- if (heartbeat) clearInterval(heartbeat);
5861
- removeListener?.();
5862
- try {
5863
- controller.close();
5864
- } catch {
5772
+ for (const entry of replayed) {
5773
+ liveCursor = entry.seq;
5774
+ const event = normalizeSseReplayEvent(entry.event);
5775
+ if (!shouldReplaySseEvent(event, pendingQuestionIds)) continue;
5776
+ write({
5777
+ id: entry.seq,
5778
+ data: event
5779
+ });
5780
+ if (event && typeof event === "object" && event.type === "session_snapshot" && event.terminal === true) {
5781
+ cleanup();
5782
+ return;
5865
5783
  }
5866
- });
5867
- },
5868
- cancel() {
5869
- if (heartbeat) clearInterval(heartbeat);
5870
- removeListener?.();
5784
+ }
5785
+ pendingQuestionIds = null;
5786
+ };
5787
+ removeListener = bridge.addEventListener((sessionId) => {
5788
+ if (sessionId === channelId) flush();
5789
+ });
5790
+ write({ data: {
5791
+ type: "connected",
5792
+ sessionId: source.sessionId,
5793
+ adapterCapabilities: FLEET_ADAPTER_CAPABILITIES,
5794
+ ...source.streamGeneration ? { streamGeneration: source.streamGeneration } : {},
5795
+ ...source.cursorReset ? { cursorReset: true } : {},
5796
+ ...source.resumeAccepted ? { resumeAccepted: true } : {}
5797
+ } });
5798
+ if (source.includeSnapshot !== false && source.initialSnapshot) write({ data: source.initialSnapshot });
5799
+ readyToFlush = true;
5800
+ if (source.initialSnapshot?.terminal === true) {
5801
+ cleanup();
5802
+ return;
5871
5803
  }
5872
- });
5873
- return new Response(stream, { headers: {
5874
- "Content-Type": "text/event-stream; charset=utf-8",
5875
- "Cache-Control": "no-cache, no-store",
5876
- Connection: "keep-alive",
5877
- "X-Accel-Buffering": "no"
5878
- } });
5804
+ flush();
5805
+ if (closed || cleaned) return;
5806
+ heartbeat = setInterval(() => enqueue(": heartbeat\n\n"), 15e3);
5807
+ request.signal.addEventListener("abort", cleanup, { once: true });
5808
+ },
5809
+ cancel() {
5810
+ if (heartbeat) clearInterval(heartbeat);
5811
+ removeListener?.();
5812
+ releaseSource();
5813
+ cleaned = true;
5814
+ }
5815
+ });
5816
+ return new Response(stream, { headers: {
5817
+ "Content-Type": "text/event-stream; charset=utf-8",
5818
+ "Cache-Control": "no-cache, no-store",
5819
+ Connection: "keep-alive",
5820
+ "X-Accel-Buffering": "no"
5821
+ } });
5822
+ }
5823
+ function handleChatEventsGet(request) {
5824
+ return wrapApiHandler(async () => {
5825
+ const url = new URL(request.url);
5826
+ const sessionIdParam = url.searchParams.get("sessionId");
5827
+ const parentSessionIdParam = url.searchParams.get("parentSessionId");
5828
+ const childIdParam = url.searchParams.get("childId");
5829
+ const streamGenerationParam = url.searchParams.get("streamGeneration");
5830
+ if (parentSessionIdParam !== null || childIdParam !== null || streamGenerationParam !== null) {
5831
+ if (sessionIdParam || !parentSessionIdParam || !childIdParam) return Response.json({ message: "GET /api/chat/events requires both ?parentSessionId= and ?childId= for child streams" }, { status: 400 });
5832
+ const parentSessionId = SessionIdSchema.safeParse(parentSessionIdParam);
5833
+ const childId = SessionIdSchema.safeParse(childIdParam);
5834
+ if (!parentSessionId.success || !childId.success) return Response.json({ message: "Invalid subagent stream identifiers" }, { status: 400 });
5835
+ if (streamGenerationParam !== null && !/^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$/.test(streamGenerationParam)) return Response.json({ message: "Invalid child stream generation" }, { status: 400 });
5836
+ const childStream = await getBridge().openRlmChildStream(parentSessionId.data, childId.data, {
5837
+ ...streamGenerationParam ? { streamGeneration: streamGenerationParam } : {},
5838
+ lastEventId: lastEventIdFor(request, url)
5839
+ });
5840
+ if (!childStream) return Response.json({ message: "Unknown live subagent stream" }, { status: 404 });
5841
+ return createSseResponse(request, getBridge(), {
5842
+ sessionId: childStream.sessionId,
5843
+ channelId: childStream.channelId,
5844
+ streamGeneration: childStream.streamGeneration,
5845
+ resumeAccepted: childStream.resumeAccepted,
5846
+ cursorReset: childStream.cursorReset,
5847
+ replayFrom: childStream.replayFrom,
5848
+ includeSnapshot: childStream.includeSnapshot,
5849
+ initialSnapshot: childStream.snapshot,
5850
+ release: childStream.release
5851
+ }, lastEventIdFor(request, url));
5852
+ }
5853
+ if (!sessionIdParam) return Response.json({ message: "SSE requires ?sessionId=" }, { status: 400 });
5854
+ const sessionId = SessionIdSchema.safeParse(sessionIdParam);
5855
+ if (!sessionId.success) return Response.json({ message: "Invalid session identifier" }, { status: 400 });
5856
+ return createSseResponse(request, getBridge(), { sessionId: sessionId.data }, lastEventIdFor(request, url));
5879
5857
  });
5880
5858
  }
5881
5859
  var BodySchema$1 = external_exports.object({
@@ -6733,6 +6711,28 @@ var MODELS = {
6733
6711
  contextWindow: 1e6,
6734
6712
  maxTokens: 128e3
6735
6713
  },
6714
+ "anthropic.claude-fable-5-1": {
6715
+ id: "anthropic.claude-fable-5-1",
6716
+ name: "Claude Fable 5.1",
6717
+ api: "bedrock-converse-stream",
6718
+ provider: "amazon-bedrock",
6719
+ baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
6720
+ reasoning: true,
6721
+ thinkingLevelMap: {
6722
+ "off": null,
6723
+ "xhigh": "xhigh",
6724
+ "max": "max"
6725
+ },
6726
+ input: ["text", "image"],
6727
+ cost: {
6728
+ input: 10,
6729
+ output: 50,
6730
+ cacheRead: 0.25,
6731
+ cacheWrite: 12.5
6732
+ },
6733
+ contextWindow: 1e6,
6734
+ maxTokens: 128e3
6735
+ },
6736
6736
  "anthropic.claude-haiku-4-5-20251001-v1:0": {
6737
6737
  id: "anthropic.claude-haiku-4-5-20251001-v1:0",
6738
6738
  name: "Claude Haiku 4.5",
@@ -7320,6 +7320,28 @@ var MODELS = {
7320
7320
  contextWindow: 1e6,
7321
7321
  maxTokens: 128e3
7322
7322
  },
7323
+ "global.anthropic.claude-fable-5-1": {
7324
+ id: "global.anthropic.claude-fable-5-1",
7325
+ name: "Claude Fable 5.1 (Global)",
7326
+ api: "bedrock-converse-stream",
7327
+ provider: "amazon-bedrock",
7328
+ baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
7329
+ reasoning: true,
7330
+ thinkingLevelMap: {
7331
+ "off": null,
7332
+ "xhigh": "xhigh",
7333
+ "max": "max"
7334
+ },
7335
+ input: ["text", "image"],
7336
+ cost: {
7337
+ input: 10,
7338
+ output: 50,
7339
+ cacheRead: 0.25,
7340
+ cacheWrite: 12.5
7341
+ },
7342
+ contextWindow: 1e6,
7343
+ maxTokens: 128e3
7344
+ },
7323
7345
  "global.anthropic.claude-haiku-4-5-20251001-v1:0": {
7324
7346
  id: "global.anthropic.claude-haiku-4-5-20251001-v1:0",
7325
7347
  name: "Claude Haiku 4.5 (Global)",
@@ -7505,10 +7527,10 @@ var MODELS = {
7505
7527
  },
7506
7528
  input: ["text", "image"],
7507
7529
  cost: {
7508
- input: 0.22,
7509
- output: 1.32,
7510
- cacheRead: 0.022,
7511
- cacheWrite: 0.275
7530
+ input: 0.2,
7531
+ output: 1.2,
7532
+ cacheRead: 0.02,
7533
+ cacheWrite: 0.25
7512
7534
  },
7513
7535
  contextWindow: 105e4,
7514
7536
  maxTokens: 128e3
@@ -7527,10 +7549,10 @@ var MODELS = {
7527
7549
  },
7528
7550
  input: ["text", "image"],
7529
7551
  cost: {
7530
- input: 5.5,
7531
- output: 33,
7532
- cacheRead: 0.55,
7533
- cacheWrite: 6.875
7552
+ input: 4,
7553
+ output: 20,
7554
+ cacheRead: 0.4,
7555
+ cacheWrite: 5
7534
7556
  },
7535
7557
  contextWindow: 105e4,
7536
7558
  maxTokens: 128e3
@@ -7549,10 +7571,10 @@ var MODELS = {
7549
7571
  },
7550
7572
  input: ["text", "image"],
7551
7573
  cost: {
7552
- input: 2.2,
7553
- output: 13.2,
7554
- cacheRead: 0.22,
7555
- cacheWrite: 2.75
7574
+ input: 2,
7575
+ output: 12,
7576
+ cacheRead: 0.2,
7577
+ cacheWrite: 2.5
7556
7578
  },
7557
7579
  contextWindow: 105e4,
7558
7580
  maxTokens: 128e3
@@ -8190,10 +8212,10 @@ var MODELS = {
8190
8212
  },
8191
8213
  input: ["text", "image"],
8192
8214
  cost: {
8193
- input: 5.5,
8194
- output: 33,
8195
- cacheRead: 0.55,
8196
- cacheWrite: 6.875
8215
+ input: 4.4,
8216
+ output: 22,
8217
+ cacheRead: 0.44,
8218
+ cacheWrite: 5.5
8197
8219
  },
8198
8220
  contextWindow: 105e4,
8199
8221
  maxTokens: 128e3
@@ -8463,6 +8485,28 @@ var MODELS = {
8463
8485
  contextWindow: 1e6,
8464
8486
  maxTokens: 128e3
8465
8487
  },
8488
+ "us.anthropic.claude-fable-5-1": {
8489
+ id: "us.anthropic.claude-fable-5-1",
8490
+ name: "Claude Fable 5.1 (US)",
8491
+ api: "bedrock-converse-stream",
8492
+ provider: "amazon-bedrock",
8493
+ baseUrl: "https://bedrock-runtime.us-east-1.amazonaws.com",
8494
+ reasoning: true,
8495
+ thinkingLevelMap: {
8496
+ "off": null,
8497
+ "xhigh": "xhigh",
8498
+ "max": "max"
8499
+ },
8500
+ input: ["text", "image"],
8501
+ cost: {
8502
+ input: 11,
8503
+ output: 55,
8504
+ cacheRead: 0.275,
8505
+ cacheWrite: 13.75
8506
+ },
8507
+ contextWindow: 1e6,
8508
+ maxTokens: 128e3
8509
+ },
8466
8510
  "us.anthropic.claude-haiku-4-5-20251001-v1:0": {
8467
8511
  id: "us.anthropic.claude-haiku-4-5-20251001-v1:0",
8468
8512
  name: "Claude Haiku 4.5 (US)",
@@ -8845,6 +8889,28 @@ var MODELS = {
8845
8889
  contextWindow: 1e6,
8846
8890
  maxTokens: 128e3
8847
8891
  },
8892
+ "claude-fable-5-1": {
8893
+ id: "claude-fable-5-1",
8894
+ name: "Claude Fable 5.1",
8895
+ api: "anthropic-messages",
8896
+ provider: "anthropic",
8897
+ baseUrl: "https://api.anthropic.com",
8898
+ reasoning: true,
8899
+ thinkingLevelMap: {
8900
+ "off": null,
8901
+ "xhigh": "xhigh",
8902
+ "max": "max"
8903
+ },
8904
+ input: ["text", "image"],
8905
+ cost: {
8906
+ input: 10,
8907
+ output: 50,
8908
+ cacheRead: 0.25,
8909
+ cacheWrite: 12.5
8910
+ },
8911
+ contextWindow: 1e6,
8912
+ maxTokens: 128e3
8913
+ },
8848
8914
  "claude-haiku-4-5": {
8849
8915
  id: "claude-haiku-4-5",
8850
8916
  name: "Claude Haiku 4.5 (latest)",
@@ -10793,6 +10859,42 @@ var MODELS = {
10793
10859
  },
10794
10860
  contextWindow: 262144,
10795
10861
  maxTokens: 256e3
10862
+ },
10863
+ "@cf/zai-org/glm-5.3": {
10864
+ id: "@cf/zai-org/glm-5.3",
10865
+ name: "Glm 5.3",
10866
+ api: "openai-completions",
10867
+ provider: "cloudflare-workers-ai",
10868
+ baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1",
10869
+ compat: { "sendSessionAffinityHeaders": true },
10870
+ reasoning: true,
10871
+ input: ["text"],
10872
+ cost: {
10873
+ input: 1.4,
10874
+ output: 4.4,
10875
+ cacheRead: 0.26,
10876
+ cacheWrite: 0
10877
+ },
10878
+ contextWindow: 1310720,
10879
+ maxTokens: 1310720
10880
+ },
10881
+ "@cf/zai-org/glm-5.3-flash": {
10882
+ id: "@cf/zai-org/glm-5.3-flash",
10883
+ name: "Glm 5.3 Flash",
10884
+ api: "openai-completions",
10885
+ provider: "cloudflare-workers-ai",
10886
+ baseUrl: "https://api.cloudflare.com/client/v4/accounts/{CLOUDFLARE_ACCOUNT_ID}/ai/v1",
10887
+ compat: { "sendSessionAffinityHeaders": true },
10888
+ reasoning: true,
10889
+ input: ["text", "image"],
10890
+ cost: {
10891
+ input: 0.15,
10892
+ output: 0.5,
10893
+ cacheRead: 0.03,
10894
+ cacheWrite: 0
10895
+ },
10896
+ contextWindow: 1310720,
10897
+ maxTokens: 1048576
10796
10898
  }
10797
10899
  },
10798
10900
  "deepseek": {
@@ -10856,23 +10958,6 @@ var MODELS = {
10856
10958
  }
10857
10959
  },
10858
10960
  "fireworks": {
10859
- "accounts/fireworks/models/deepseek-v4-flash": {
10860
- id: "accounts/fireworks/models/deepseek-v4-flash",
10861
- name: "DeepSeek V4 Flash",
10862
- api: "anthropic-messages",
10863
- provider: "fireworks",
10864
- baseUrl: "https://api.fireworks.ai/inference",
10865
- reasoning: true,
10866
- input: ["text"],
10867
- cost: {
10868
- input: 0.14,
10869
- output: 0.28,
10870
- cacheRead: 0.028,
10871
- cacheWrite: 0
10872
- },
10873
- contextWindow: 1e6,
10874
- maxTokens: 384e3
10875
- },
10876
10961
  "accounts/fireworks/models/deepseek-v4-flash-0731": {
10877
10962
  id: "accounts/fireworks/models/deepseek-v4-flash-0731",
10878
10963
  name: "DeepSeek V4 Flash 0731",
@@ -10890,23 +10975,6 @@ var MODELS = {
10890
10975
  contextWindow: 1e6,
10891
10976
  maxTokens: 384e3
10892
10977
  },
10893
- "accounts/fireworks/models/deepseek-v4-pro": {
10894
- id: "accounts/fireworks/models/deepseek-v4-pro",
10895
- name: "DeepSeek V4 Pro",
10896
- api: "anthropic-messages",
10897
- provider: "fireworks",
10898
- baseUrl: "https://api.fireworks.ai/inference",
10899
- reasoning: true,
10900
- input: ["text"],
10901
- cost: {
10902
- input: 1.74,
10903
- output: 3.48,
10904
- cacheRead: 0.145,
10905
- cacheWrite: 0
10906
- },
10907
- contextWindow: 1e6,
10908
- maxTokens: 384e3
10909
- },
10910
10978
  "accounts/fireworks/models/deepseek-v4-pro-0813": {
10911
10979
  id: "accounts/fireworks/models/deepseek-v4-pro-0813",
10912
10980
  name: "DeepSeek V4 Pro 0813",
@@ -10941,35 +11009,52 @@ var MODELS = {
10941
11009
  contextWindow: 1048575,
10942
11010
  maxTokens: 131072
10943
11011
  },
10944
- "accounts/fireworks/models/gpt-oss-120b": {
10945
- id: "accounts/fireworks/models/gpt-oss-120b",
10946
- name: "GPT OSS 120B",
11012
+ "accounts/fireworks/models/glm-5p3": {
11013
+ id: "accounts/fireworks/models/glm-5p3",
11014
+ name: "GLM 5.3",
10947
11015
  api: "anthropic-messages",
10948
11016
  provider: "fireworks",
10949
11017
  baseUrl: "https://api.fireworks.ai/inference",
10950
11018
  reasoning: true,
10951
11019
  input: ["text"],
11020
+ cost: {
11021
+ input: 1.4,
11022
+ output: 4.4,
11023
+ cacheRead: 0.26,
11024
+ cacheWrite: 0
11025
+ },
11026
+ contextWindow: 1e6,
11027
+ maxTokens: 131072
11028
+ },
11029
+ "accounts/fireworks/models/glm-5p3-flash": {
11030
+ id: "accounts/fireworks/models/glm-5p3-flash",
11031
+ name: "GLM 5.3 Flash",
11032
+ api: "anthropic-messages",
11033
+ provider: "fireworks",
11034
+ baseUrl: "https://api.fireworks.ai/inference",
11035
+ reasoning: true,
11036
+ input: ["text", "image"],
10952
11037
  cost: {
10953
11038
  input: 0.15,
10954
- output: 0.6,
10955
- cacheRead: 0.015,
11039
+ output: 0.5,
11040
+ cacheRead: 0.029,
10956
11041
  cacheWrite: 0
10957
11042
  },
10958
- contextWindow: 131072,
10959
- maxTokens: 32768
11043
+ contextWindow: 1e6,
11044
+ maxTokens: 131072
10960
11045
  },
10961
- "accounts/fireworks/models/gpt-oss-20b": {
10962
- id: "accounts/fireworks/models/gpt-oss-20b",
10963
- name: "GPT OSS 20B",
11046
+ "accounts/fireworks/models/gpt-oss-120b": {
11047
+ id: "accounts/fireworks/models/gpt-oss-120b",
11048
+ name: "GPT OSS 120B",
10964
11049
  api: "anthropic-messages",
10965
11050
  provider: "fireworks",
10966
11051
  baseUrl: "https://api.fireworks.ai/inference",
10967
11052
  reasoning: true,
10968
11053
  input: ["text"],
10969
11054
  cost: {
10970
- input: 0.07,
10971
- output: 0.3,
10972
- cacheRead: 0.035,
11055
+ input: 0.15,
11056
+ output: 0.6,
11057
+ cacheRead: 0.015,
10973
11058
  cacheWrite: 0
10974
11059
  },
10975
11060
  contextWindow: 131072,
@@ -11052,23 +11137,6 @@ var MODELS = {
11052
11137
  contextWindow: 1048576,
11053
11138
  maxTokens: 131072
11054
11139
  },
11055
- "accounts/fireworks/models/minimax-m2p7": {
11056
- id: "accounts/fireworks/models/minimax-m2p7",
11057
- name: "MiniMax-M2.7",
11058
- api: "anthropic-messages",
11059
- provider: "fireworks",
11060
- baseUrl: "https://api.fireworks.ai/inference",
11061
- reasoning: true,
11062
- input: ["text"],
11063
- cost: {
11064
- input: 0.3,
11065
- output: 1.2,
11066
- cacheRead: 0.06,
11067
- cacheWrite: 0
11068
- },
11069
- contextWindow: 196608,
11070
- maxTokens: 196608
11071
- },
11072
11140
  "accounts/fireworks/models/minimax-m3": {
11073
11141
  id: "accounts/fireworks/models/minimax-m3",
11074
11142
  name: "MiniMax-M3",
@@ -11188,57 +11256,6 @@ var MODELS = {
11188
11256
  contextWindow: 1048575,
11189
11257
  maxTokens: 131072
11190
11258
  },
11191
- "accounts/fireworks/routers/kimi-k2p6-fast": {
11192
- id: "accounts/fireworks/routers/kimi-k2p6-fast",
11193
- name: "Kimi K2.6 Fast",
11194
- api: "anthropic-messages",
11195
- provider: "fireworks",
11196
- baseUrl: "https://api.fireworks.ai/inference",
11197
- reasoning: true,
11198
- input: ["text", "image"],
11199
- cost: {
11200
- input: 2,
11201
- output: 8,
11202
- cacheRead: 0.3,
11203
- cacheWrite: 0
11204
- },
11205
- contextWindow: 262e3,
11206
- maxTokens: 262e3
11207
- },
11208
- "accounts/fireworks/routers/kimi-k2p6-turbo": {
11209
- id: "accounts/fireworks/routers/kimi-k2p6-turbo",
11210
- name: "Kimi K2.6 Turbo",
11211
- api: "anthropic-messages",
11212
- provider: "fireworks",
11213
- baseUrl: "https://api.fireworks.ai/inference",
11214
- reasoning: true,
11215
- input: ["text", "image"],
11216
- cost: {
11217
- input: 2,
11218
- output: 8,
11219
- cacheRead: 0.3,
11220
- cacheWrite: 0
11221
- },
11222
- contextWindow: 262e3,
11223
- maxTokens: 262e3
11224
- },
11225
- "accounts/fireworks/routers/kimi-k2p7-code-fast": {
11226
- id: "accounts/fireworks/routers/kimi-k2p7-code-fast",
11227
- name: "Kimi K2.7 Code Fast",
11228
- api: "anthropic-messages",
11229
- provider: "fireworks",
11230
- baseUrl: "https://api.fireworks.ai/inference",
11231
- reasoning: true,
11232
- input: ["text", "image"],
11233
- cost: {
11234
- input: 1.9,
11235
- output: 8,
11236
- cacheRead: 0.38,
11237
- cacheWrite: 0
11238
- },
11239
- contextWindow: 262e3,
11240
- maxTokens: 262e3
11241
- },
11242
11259
  "accounts/fireworks/routers/kimi-k3-fast": {
11243
11260
  id: "accounts/fireworks/routers/kimi-k3-fast",
11244
11261
  name: "Kimi K3 Fast",
@@ -11622,9 +11639,9 @@ var MODELS = {
11622
11639
  reasoning: true,
11623
11640
  input: ["text", "image"],
11624
11641
  cost: {
11625
- input: 1.5,
11626
- output: 7.5,
11627
- cacheRead: 0.15,
11642
+ input: 0.75,
11643
+ output: 3.75,
11644
+ cacheRead: 0.075,
11628
11645
  cacheWrite: 0
11629
11646
  },
11630
11647
  contextWindow: 1e6,
@@ -11923,7 +11940,7 @@ var MODELS = {
11923
11940
  input: 0.2,
11924
11941
  output: 1.2,
11925
11942
  cacheRead: 0.02,
11926
- cacheWrite: 0
11943
+ cacheWrite: 0.25
11927
11944
  },
11928
11945
  contextWindow: 105e4,
11929
11946
  maxTokens: 128e3
@@ -11949,10 +11966,10 @@ var MODELS = {
11949
11966
  },
11950
11967
  input: ["text", "image"],
11951
11968
  cost: {
11952
- input: 2.5,
11953
- output: 15,
11954
- cacheRead: 0.25,
11955
- cacheWrite: 3.125
11969
+ input: 2,
11970
+ output: 10,
11971
+ cacheRead: 0.2,
11972
+ cacheWrite: 2.5
11956
11973
  },
11957
11974
  contextWindow: 105e4,
11958
11975
  maxTokens: 128e3
@@ -11981,7 +11998,7 @@ var MODELS = {
11981
11998
  input: 2,
11982
11999
  output: 12,
11983
12000
  cacheRead: 0.2,
11984
- cacheWrite: 0
12001
+ cacheWrite: 2.5
11985
12002
  },
11986
12003
  contextWindow: 105e4,
11987
12004
  maxTokens: 128e3
@@ -12424,23 +12441,6 @@ var MODELS = {
12424
12441
  contextWindow: 1048576,
12425
12442
  maxTokens: 65536
12426
12443
  },
12427
- "gemini-robotics-er-1.6-preview": {
12428
- id: "gemini-robotics-er-1.6-preview",
12429
- name: "Gemini Robotics-ER 1.6 Preview",
12430
- api: "google-generative-ai",
12431
- provider: "google",
12432
- baseUrl: "https://generativelanguage.googleapis.com/v1beta",
12433
- reasoning: true,
12434
- input: ["text", "image"],
12435
- cost: {
12436
- input: 1,
12437
- output: 5,
12438
- cacheRead: 0,
12439
- cacheWrite: 0
12440
- },
12441
- contextWindow: 131072,
12442
- maxTokens: 65536
12443
- },
12444
12444
  "gemma-4-26b-a4b-it": {
12445
12445
  id: "gemma-4-26b-a4b-it",
12446
12446
  name: "Gemma 4 26B A4B IT",
@@ -12837,6 +12837,23 @@ var MODELS = {
12837
12837
  },
12838
12838
  contextWindow: 131072,
12839
12839
  maxTokens: 16384
12840
+ },
12841
+ "qwen/qwen3.8-27b": {
12842
+ id: "qwen/qwen3.8-27b",
12843
+ name: "Qwen3.8 27B",
12844
+ api: "openai-completions",
12845
+ provider: "groq",
12846
+ baseUrl: "https://api.groq.com/openai/v1",
12847
+ reasoning: true,
12848
+ input: ["text", "image"],
12849
+ cost: {
12850
+ input: 0.8,
12851
+ output: 4,
12852
+ cacheRead: 0,
12853
+ cacheWrite: 0
12854
+ },
12855
+ contextWindow: 131042,
12856
+ maxTokens: 16384
12840
12857
  }
12841
12858
  },
12842
12859
  "huggingface": {
@@ -12856,7 +12873,7 @@ var MODELS = {
12856
12873
  cacheWrite: 0
12857
12874
  },
12858
12875
  contextWindow: 204800,
12859
- maxTokens: 128e3
12876
+ maxTokens: 131072
12860
12877
  },
12861
12878
  "MiniMaxAI/MiniMax-M2.1": {
12862
12879
  id: "MiniMaxAI/MiniMax-M2.1",
@@ -12928,7 +12945,7 @@ var MODELS = {
12928
12945
  cacheWrite: 0
12929
12946
  },
12930
12947
  contextWindow: 524288,
12931
- maxTokens: 128e3
12948
+ maxTokens: 512e3
12932
12949
  },
12933
12950
  "Qwen/Qwen2.5-Coder-32B-Instruct": {
12934
12951
  id: "Qwen/Qwen2.5-Coder-32B-Instruct",
@@ -14072,6 +14089,42 @@ var MODELS = {
14072
14089
  },
14073
14090
  contextWindow: 262144,
14074
14091
  maxTokens: 131072
14092
+ },
14093
+ "zai-org/GLM-5.3": {
14094
+ id: "zai-org/GLM-5.3",
14095
+ name: "GLM-5.3",
14096
+ api: "openai-completions",
14097
+ provider: "huggingface",
14098
+ baseUrl: "https://router.huggingface.co/v1",
14099
+ compat: { "supportsDeveloperRole": false },
14100
+ reasoning: true,
14101
+ input: ["text"],
14102
+ cost: {
14103
+ input: 1.4,
14104
+ output: 4.4,
14105
+ cacheRead: 0,
14106
+ cacheWrite: 0
14107
+ },
14108
+ contextWindow: 1048576,
14109
+ maxTokens: 131072
14110
+ },
14111
+ "zai-org/GLM-5.3-Flash": {
14112
+ id: "zai-org/GLM-5.3-Flash",
14113
+ name: "GLM-5.3-Flash",
14114
+ api: "openai-completions",
14115
+ provider: "huggingface",
14116
+ baseUrl: "https://router.huggingface.co/v1",
14117
+ compat: { "supportsDeveloperRole": false },
14118
+ reasoning: true,
14119
+ input: ["text", "image"],
14120
+ cost: {
14121
+ input: 0.15,
14122
+ output: 0.5,
14123
+ cacheRead: 0,
14124
+ cacheWrite: 0
14125
+ },
14126
+ contextWindow: 1048576,
14127
+ maxTokens: 131072
14075
14128
  }
14076
14129
  },
14077
14130
  "kimi-coding": {
@@ -14765,6 +14818,23 @@ var MODELS = {
14765
14818
  },
14766
14819
  contextWindow: 32e3,
14767
14820
  maxTokens: 32e3
14821
+ },
14822
+ "zai-glm-5-2": {
14823
+ id: "zai-glm-5-2",
14824
+ name: "GLM-5.2",
14825
+ api: "mistral-conversations",
14826
+ provider: "mistral",
14827
+ baseUrl: "https://api.mistral.ai",
14828
+ reasoning: true,
14829
+ input: ["text"],
14830
+ cost: {
14831
+ input: 1.4,
14832
+ output: 4.4,
14833
+ cacheRead: 0.14,
14834
+ cacheWrite: 0
14835
+ },
14836
+ contextWindow: 1e6,
14837
+ maxTokens: 131072
14768
14838
  }
14769
14839
  },
14770
14840
  "moonshotai": {
@@ -16360,6 +16430,28 @@ var MODELS = {
16360
16430
  contextWindow: 1e6,
16361
16431
  maxTokens: 128e3
16362
16432
  },
16433
+ "claude-fable-5-1": {
16434
+ id: "claude-fable-5-1",
16435
+ name: "Claude Fable 5.1",
16436
+ api: "anthropic-messages",
16437
+ provider: "opencode",
16438
+ baseUrl: "https://opencode.ai/zen",
16439
+ reasoning: true,
16440
+ thinkingLevelMap: {
16441
+ "off": null,
16442
+ "xhigh": "xhigh",
16443
+ "max": "max"
16444
+ },
16445
+ input: ["text", "image"],
16446
+ cost: {
16447
+ input: 10,
16448
+ output: 50,
16449
+ cacheRead: 0.25,
16450
+ cacheWrite: 12.5
16451
+ },
16452
+ contextWindow: 1e6,
16453
+ maxTokens: 128e3
16454
+ },
16363
16455
  "claude-haiku-4-5": {
16364
16456
  id: "claude-haiku-4-5",
16365
16457
  name: "Claude Haiku 4.5",
@@ -17206,23 +17298,6 @@ var MODELS = {
17206
17298
  contextWindow: 256e3,
17207
17299
  maxTokens: 256e3
17208
17300
  },
17209
- "hy3-free": {
17210
- id: "hy3-free",
17211
- name: "Hy3 Free",
17212
- api: "openai-completions",
17213
- provider: "opencode",
17214
- baseUrl: "https://opencode.ai/zen/v1",
17215
- reasoning: true,
17216
- input: ["text"],
17217
- cost: {
17218
- input: 0,
17219
- output: 0,
17220
- cacheRead: 0,
17221
- cacheWrite: 0
17222
- },
17223
- contextWindow: 19e4,
17224
- maxTokens: 64e3
17225
- },
17226
17301
  "kimi-k2.5": {
17227
17302
  id: "kimi-k2.5",
17228
17303
  name: "Kimi K2.5",
@@ -17300,6 +17375,23 @@ var MODELS = {
17300
17375
  contextWindow: 1048576,
17301
17376
  maxTokens: 131072
17302
17377
  },
17378
+ "ling-3.0-flash-fin-free": {
17379
+ id: "ling-3.0-flash-fin-free",
17380
+ name: "Ling 3.0 Flash Fin Free",
17381
+ api: "openai-completions",
17382
+ provider: "opencode",
17383
+ baseUrl: "https://opencode.ai/zen/v1",
17384
+ reasoning: true,
17385
+ input: ["text"],
17386
+ cost: {
17387
+ input: 0,
17388
+ output: 0,
17389
+ cacheRead: 0,
17390
+ cacheWrite: 0
17391
+ },
17392
+ contextWindow: 262144,
17393
+ maxTokens: 32768
17394
+ },
17303
17395
  "mimo-v2.5-free": {
17304
17396
  id: "mimo-v2.5-free",
17305
17397
  name: "MiMo V2.5 Free",
@@ -17469,23 +17561,6 @@ var MODELS = {
17469
17561
  },
17470
17562
  contextWindow: 262144,
17471
17563
  maxTokens: 65536
17472
- },
17473
- "x-preview-f-free": {
17474
- id: "x-preview-f-free",
17475
- name: "Ox Alpha Free (Unlimited)",
17476
- api: "openai-completions",
17477
- provider: "opencode",
17478
- baseUrl: "https://opencode.ai/zen/v1",
17479
- reasoning: true,
17480
- input: ["text", "image"],
17481
- cost: {
17482
- input: 0,
17483
- output: 0,
17484
- cacheRead: 0,
17485
- cacheWrite: 0
17486
- },
17487
- contextWindow: 1e6,
17488
- maxTokens: 131072
17489
17564
  }
17490
17565
  },
17491
17566
  "opencode-go": {
@@ -17627,6 +17702,23 @@ var MODELS = {
17627
17702
  contextWindow: 1e6,
17628
17703
  maxTokens: 131072
17629
17704
  },
17705
+ "glm-5.3-flash": {
17706
+ id: "glm-5.3-flash",
17707
+ name: "GLM-5.3-Flash (2x usage)",
17708
+ api: "openai-completions",
17709
+ provider: "opencode-go",
17710
+ baseUrl: "https://opencode.ai/zen/go/v1",
17711
+ reasoning: true,
17712
+ input: ["text", "image"],
17713
+ cost: {
17714
+ input: 0.075,
17715
+ output: 0.25,
17716
+ cacheRead: 0.015,
17717
+ cacheWrite: 0
17718
+ },
17719
+ contextWindow: 1e6,
17720
+ maxTokens: 131072
17721
+ },
17630
17722
  "gpt-5.6-luna": {
17631
17723
  id: "gpt-5.6-luna",
17632
17724
  name: "GPT-5.6 Luna",
@@ -17669,21 +17761,38 @@ var MODELS = {
17669
17761
  },
17670
17762
  "hy3": {
17671
17763
  id: "hy3",
17672
- name: "Hy3 (8x usage)",
17764
+ name: "Hy3",
17673
17765
  api: "openai-completions",
17674
17766
  provider: "opencode-go",
17675
17767
  baseUrl: "https://opencode.ai/zen/go/v1",
17676
17768
  reasoning: true,
17677
17769
  input: ["text"],
17678
17770
  cost: {
17679
- input: 0.0175,
17680
- output: 0.0725,
17681
- cacheRead: 4375e-6,
17771
+ input: 0.14,
17772
+ output: 0.58,
17773
+ cacheRead: 0.035,
17682
17774
  cacheWrite: 0
17683
17775
  },
17684
17776
  contextWindow: 256e3,
17685
17777
  maxTokens: 64e3
17686
17778
  },
17779
+ "hy4-preview": {
17780
+ id: "hy4-preview",
17781
+ name: "Hy4 preview",
17782
+ api: "openai-completions",
17783
+ provider: "opencode-go",
17784
+ baseUrl: "https://opencode.ai/zen/go/v1",
17785
+ reasoning: true,
17786
+ input: ["text"],
17787
+ cost: {
17788
+ input: 0.834,
17789
+ output: 2.501,
17790
+ cacheRead: 0.042,
17791
+ cacheWrite: 0
17792
+ },
17793
+ contextWindow: 1024e3,
17794
+ maxTokens: 64e3
17795
+ },
17687
17796
  "kimi-k2.6": {
17688
17797
  id: "kimi-k2.6",
17689
17798
  name: "Kimi K2.6",
@@ -17846,23 +17955,6 @@ var MODELS = {
17846
17955
  contextWindow: 1048576,
17847
17956
  maxTokens: 131072
17848
17957
  },
17849
- "ox-alpha-free": {
17850
- id: "ox-alpha-free",
17851
- name: "Ox Alpha Free (Unlimited)",
17852
- api: "openai-completions",
17853
- provider: "opencode-go",
17854
- baseUrl: "https://opencode.ai/zen/go/v1",
17855
- reasoning: true,
17856
- input: ["text", "image"],
17857
- cost: {
17858
- input: 0,
17859
- output: 0,
17860
- cacheRead: 0,
17861
- cacheWrite: 0
17862
- },
17863
- contextWindow: 1e6,
17864
- maxTokens: 131072
17865
- },
17866
17958
  "qwen3.6-plus": {
17867
17959
  id: "qwen3.6-plus",
17868
17960
  name: "Qwen3.6 Plus",
@@ -17915,6 +18007,23 @@ var MODELS = {
17915
18007
  contextWindow: 1e6,
17916
18008
  maxTokens: 65536
17917
18009
  },
18010
+ "qwen3.8-flash": {
18011
+ id: "qwen3.8-flash",
18012
+ name: "Qwen3.8 Flash",
18013
+ api: "openai-completions",
18014
+ provider: "opencode-go",
18015
+ baseUrl: "https://opencode.ai/zen/go/v1",
18016
+ reasoning: true,
18017
+ input: ["text", "image"],
18018
+ cost: {
18019
+ input: 0.15,
18020
+ output: 0.47,
18021
+ cacheRead: 0.016,
18022
+ cacheWrite: 0.2
18023
+ },
18024
+ contextWindow: 1e6,
18025
+ maxTokens: 131072
18026
+ },
17918
18027
  "qwen3.8-max": {
17919
18028
  id: "qwen3.8-max",
17920
18029
  name: "Qwen3.8 Max",
@@ -18152,6 +18261,32 @@ var MODELS = {
18152
18261
  contextWindow: 1e6,
18153
18262
  maxTokens: 128e3
18154
18263
  },
18264
+ "anthropic/claude-fable-5.1": {
18265
+ id: "anthropic/claude-fable-5.1",
18266
+ name: "Anthropic: Claude Fable 5.1",
18267
+ api: "openai-completions",
18268
+ provider: "openrouter",
18269
+ baseUrl: "https://openrouter.ai/api/v1",
18270
+ reasoning: true,
18271
+ thinkingLevelMap: {
18272
+ "off": null,
18273
+ "minimal": null,
18274
+ "low": "low",
18275
+ "medium": "medium",
18276
+ "high": "high",
18277
+ "xhigh": "xhigh",
18278
+ "max": "max"
18279
+ },
18280
+ input: ["text", "image"],
18281
+ cost: {
18282
+ input: 0,
18283
+ output: 0,
18284
+ cacheRead: 0,
18285
+ cacheWrite: 0
18286
+ },
18287
+ contextWindow: 1e6,
18288
+ maxTokens: 128e3
18289
+ },
18155
18290
  "anthropic/claude-haiku-4.5": {
18156
18291
  id: "anthropic/claude-haiku-4.5",
18157
18292
  name: "Anthropic: Claude Haiku 4.5",
@@ -18306,31 +18441,6 @@ var MODELS = {
18306
18441
  contextWindow: 1e6,
18307
18442
  maxTokens: 128e3
18308
18443
  },
18309
- "anthropic/claude-opus-4.7-fast": {
18310
- id: "anthropic/claude-opus-4.7-fast",
18311
- name: "Anthropic: Claude Opus 4.7 (Fast)",
18312
- api: "openai-completions",
18313
- provider: "openrouter",
18314
- baseUrl: "https://openrouter.ai/api/v1",
18315
- reasoning: true,
18316
- thinkingLevelMap: {
18317
- "minimal": null,
18318
- "low": "low",
18319
- "medium": "medium",
18320
- "high": "high",
18321
- "xhigh": "xhigh",
18322
- "max": "max"
18323
- },
18324
- input: ["text", "image"],
18325
- cost: {
18326
- input: 30,
18327
- output: 150,
18328
- cacheRead: 3,
18329
- cacheWrite: 37.5
18330
- },
18331
- contextWindow: 1e6,
18332
- maxTokens: 128e3
18333
- },
18334
18444
  "anthropic/claude-opus-4.8": {
18335
18445
  id: "anthropic/claude-opus-4.8",
18336
18446
  name: "Anthropic: Claude Opus 4.8",
@@ -18356,31 +18466,6 @@ var MODELS = {
18356
18466
  contextWindow: 1e6,
18357
18467
  maxTokens: 128e3
18358
18468
  },
18359
- "anthropic/claude-opus-4.8-fast": {
18360
- id: "anthropic/claude-opus-4.8-fast",
18361
- name: "Anthropic: Claude Opus 4.8 (Fast)",
18362
- api: "openai-completions",
18363
- provider: "openrouter",
18364
- baseUrl: "https://openrouter.ai/api/v1",
18365
- reasoning: true,
18366
- thinkingLevelMap: {
18367
- "minimal": null,
18368
- "low": "low",
18369
- "medium": "medium",
18370
- "high": "high",
18371
- "xhigh": "xhigh",
18372
- "max": "max"
18373
- },
18374
- input: ["text", "image"],
18375
- cost: {
18376
- input: 10,
18377
- output: 50,
18378
- cacheRead: 1,
18379
- cacheWrite: 12.5
18380
- },
18381
- contextWindow: 1e6,
18382
- maxTokens: 128e3
18383
- },
18384
18469
  "anthropic/claude-opus-5": {
18385
18470
  id: "anthropic/claude-opus-5",
18386
18471
  name: "Claude Opus 5",
@@ -18406,31 +18491,6 @@ var MODELS = {
18406
18491
  contextWindow: 1e6,
18407
18492
  maxTokens: 128e3
18408
18493
  },
18409
- "anthropic/claude-opus-5-fast": {
18410
- id: "anthropic/claude-opus-5-fast",
18411
- name: "Claude Opus 5 (Fast)",
18412
- api: "openai-completions",
18413
- provider: "openrouter",
18414
- baseUrl: "https://openrouter.ai/api/v1",
18415
- reasoning: true,
18416
- thinkingLevelMap: {
18417
- "minimal": null,
18418
- "low": "low",
18419
- "medium": "medium",
18420
- "high": "high",
18421
- "xhigh": "xhigh",
18422
- "max": "max"
18423
- },
18424
- input: ["text", "image"],
18425
- cost: {
18426
- input: 10,
18427
- output: 50,
18428
- cacheRead: 1,
18429
- cacheWrite: 12.5
18430
- },
18431
- contextWindow: 1e6,
18432
- maxTokens: 128e3
18433
- },
18434
18494
  "anthropic/claude-sonnet-4": {
18435
18495
  id: "anthropic/claude-sonnet-4",
18436
18496
  name: "Anthropic: Claude Sonnet 4",
@@ -18552,30 +18612,13 @@ var MODELS = {
18552
18612
  },
18553
18613
  input: ["text"],
18554
18614
  cost: {
18555
- input: 0.22,
18556
- output: 0.85,
18615
+ input: 0.25,
18616
+ output: 0.7999999999999999,
18557
18617
  cacheRead: 0.06,
18558
18618
  cacheWrite: 0
18559
18619
  },
18560
18620
  contextWindow: 262144,
18561
- maxTokens: 235929
18562
- },
18563
- "arcee-ai/virtuoso-large": {
18564
- id: "arcee-ai/virtuoso-large",
18565
- name: "Arcee AI: Virtuoso Large",
18566
- api: "openai-completions",
18567
- provider: "openrouter",
18568
- baseUrl: "https://openrouter.ai/api/v1",
18569
- reasoning: false,
18570
- input: ["text"],
18571
- cost: {
18572
- input: 0.75,
18573
- output: 1.2,
18574
- cacheRead: 0,
18575
- cacheWrite: 0
18576
- },
18577
- contextWindow: 131072,
18578
- maxTokens: 64e3
18621
+ maxTokens: 8e4
18579
18622
  },
18580
18623
  "auto": {
18581
18624
  id: "auto",
@@ -18965,13 +19008,13 @@ var MODELS = {
18965
19008
  },
18966
19009
  input: ["text"],
18967
19010
  cost: {
18968
- input: 0.26,
18969
- output: 0.38,
18970
- cacheRead: 0.13,
19011
+ input: 0.26899999999999996,
19012
+ output: 0.39999999999999997,
19013
+ cacheRead: 0.13449999999999998,
18971
19014
  cacheWrite: 0
18972
19015
  },
18973
19016
  contextWindow: 163840,
18974
- maxTokens: 147456
19017
+ maxTokens: 65536
18975
19018
  },
18976
19019
  "deepseek/deepseek-v3.2-exp": {
18977
19020
  id: "deepseek/deepseek-v3.2-exp",
@@ -19020,9 +19063,9 @@ var MODELS = {
19020
19063
  },
19021
19064
  input: ["text"],
19022
19065
  cost: {
19023
- input: 0.088606,
19024
- output: 0.177212,
19025
- cacheRead: 0.017721200000000003,
19066
+ input: 0.07476000000000001,
19067
+ output: 0.14952000000000001,
19068
+ cacheRead: 0.014952,
19026
19069
  cacheWrite: 0
19027
19070
  },
19028
19071
  contextWindow: 1048576,
@@ -19049,9 +19092,9 @@ var MODELS = {
19049
19092
  },
19050
19093
  input: ["text"],
19051
19094
  cost: {
19052
- input: 0.06,
19053
- output: 0.12,
19054
- cacheRead: 0.012,
19095
+ input: 0.065,
19096
+ output: 0.18,
19097
+ cacheRead: 0.016,
19055
19098
  cacheWrite: 0
19056
19099
  },
19057
19100
  contextWindow: 1310720,
@@ -19107,13 +19150,13 @@ var MODELS = {
19107
19150
  },
19108
19151
  input: ["text"],
19109
19152
  cost: {
19110
- input: 0.87,
19111
- output: 1.74,
19112
- cacheRead: 0.0725,
19153
+ input: 1.5999999999999999,
19154
+ output: 3.1999999999999997,
19155
+ cacheRead: 0.135,
19113
19156
  cacheWrite: 0
19114
19157
  },
19115
19158
  contextWindow: 1048576,
19116
- maxTokens: 384e3
19159
+ maxTokens: 393216
19117
19160
  },
19118
19161
  "deepseek/deepseek-v4-pro-0813": {
19119
19162
  id: "deepseek/deepseek-v4-pro-0813",
@@ -19136,13 +19179,13 @@ var MODELS = {
19136
19179
  },
19137
19180
  input: ["text"],
19138
19181
  cost: {
19139
- input: 1.122,
19140
- output: 3.366,
19141
- cacheRead: 0.037399999999999996,
19182
+ input: 0.66,
19183
+ output: 1.9800000000000002,
19184
+ cacheRead: 0.022,
19142
19185
  cacheWrite: 0
19143
19186
  },
19144
19187
  contextWindow: 1048576,
19145
- maxTokens: 943717
19188
+ maxTokens: 384e3
19146
19189
  },
19147
19190
  "dots-studio/dots-3-note-preview:free": {
19148
19191
  id: "dots-studio/dots-3-note-preview:free",
@@ -19553,10 +19596,10 @@ var MODELS = {
19553
19596
  },
19554
19597
  input: ["text", "image"],
19555
19598
  cost: {
19556
- input: 0.375,
19557
- output: 1.875,
19558
- cacheRead: 0.0375,
19559
- cacheWrite: 0.0208333333333333
19599
+ input: 0.75,
19600
+ output: 3.75,
19601
+ cacheRead: 0.075,
19602
+ cacheWrite: 0.0416666666666667
19560
19603
  },
19561
19604
  contextWindow: 1048576,
19562
19605
  maxTokens: 65536
@@ -19592,7 +19635,7 @@ var MODELS = {
19592
19635
  cacheRead: 0.04,
19593
19636
  cacheWrite: 0
19594
19637
  },
19595
- contextWindow: 262144,
19638
+ contextWindow: 131072,
19596
19639
  maxTokens: 117964
19597
19640
  },
19598
19641
  "google/gemma-4-26b-a4b-it": {
@@ -19716,6 +19759,31 @@ var MODELS = {
19716
19759
  contextWindow: 131072,
19717
19760
  maxTokens: 117964
19718
19761
  },
19762
+ "ibm-granite/granite-4.2-8b": {
19763
+ id: "ibm-granite/granite-4.2-8b",
19764
+ name: "IBM: Granite 4.2 8B",
19765
+ api: "openai-completions",
19766
+ provider: "openrouter",
19767
+ baseUrl: "https://openrouter.ai/api/v1",
19768
+ reasoning: true,
19769
+ thinkingLevelMap: {
19770
+ "minimal": null,
19771
+ "low": "low",
19772
+ "medium": null,
19773
+ "high": "high",
19774
+ "xhigh": null,
19775
+ "max": null
19776
+ },
19777
+ input: ["text"],
19778
+ cost: {
19779
+ input: 0.09999999999999999,
19780
+ output: 0.15,
19781
+ cacheRead: 0.049999999999999996,
19782
+ cacheWrite: 0
19783
+ },
19784
+ contextWindow: 131072,
19785
+ maxTokens: 117964
19786
+ },
19719
19787
  "inception/mercury-2": {
19720
19788
  id: "inception/mercury-2",
19721
19789
  name: "Inception: Mercury 2",
@@ -19741,6 +19809,31 @@ var MODELS = {
19741
19809
  contextWindow: 128e3,
19742
19810
  maxTokens: 5e4
19743
19811
  },
19812
+ "inception/mercury-2.5-preview": {
19813
+ id: "inception/mercury-2.5-preview",
19814
+ name: "Inception: Mercury 2.5 Preview",
19815
+ api: "openai-completions",
19816
+ provider: "openrouter",
19817
+ baseUrl: "https://openrouter.ai/api/v1",
19818
+ reasoning: true,
19819
+ thinkingLevelMap: {
19820
+ "minimal": null,
19821
+ "low": "low",
19822
+ "medium": "medium",
19823
+ "high": "high",
19824
+ "xhigh": null,
19825
+ "max": null
19826
+ },
19827
+ input: ["text"],
19828
+ cost: {
19829
+ input: 0.04,
19830
+ output: 0.15,
19831
+ cacheRead: 4e-3,
19832
+ cacheWrite: 0
19833
+ },
19834
+ contextWindow: 26e4,
19835
+ maxTokens: 65536
19836
+ },
19744
19837
  "inclusionai/ling-3.0-flash": {
19745
19838
  id: "inclusionai/ling-3.0-flash",
19746
19839
  name: "Ling-3.0-flash",
@@ -19767,22 +19860,31 @@ var MODELS = {
19767
19860
  contextWindow: 262144,
19768
19861
  maxTokens: 32768
19769
19862
  },
19770
- "kwaipilot/kat-coder-air-v2.5": {
19771
- id: "kwaipilot/kat-coder-air-v2.5",
19772
- name: "Kwaipilot: KAT-Coder-Air V2.5",
19863
+ "inclusionai/ling-3.0-flash-fin:free": {
19864
+ id: "inclusionai/ling-3.0-flash-fin:free",
19865
+ name: "Ling 3.0 Flash Fin (free)",
19773
19866
  api: "openai-completions",
19774
19867
  provider: "openrouter",
19775
19868
  baseUrl: "https://openrouter.ai/api/v1",
19776
- reasoning: false,
19869
+ compat: { "supportsReasoningEffort": false },
19870
+ reasoning: true,
19871
+ thinkingLevelMap: {
19872
+ "minimal": null,
19873
+ "low": null,
19874
+ "medium": null,
19875
+ "high": "high",
19876
+ "xhigh": null,
19877
+ "max": null
19878
+ },
19777
19879
  input: ["text"],
19778
19880
  cost: {
19779
- input: 0.15,
19780
- output: 0.6,
19781
- cacheRead: 0.03,
19881
+ input: 0,
19882
+ output: 0,
19883
+ cacheRead: 0,
19782
19884
  cacheWrite: 0
19783
19885
  },
19784
- contextWindow: 256e3,
19785
- maxTokens: 8e4
19886
+ contextWindow: 262144,
19887
+ maxTokens: 32768
19786
19888
  },
19787
19889
  "kwaipilot/kat-coder-pro-v2": {
19788
19890
  id: "kwaipilot/kat-coder-pro-v2",
@@ -19799,7 +19901,7 @@ var MODELS = {
19799
19901
  cacheWrite: 0
19800
19902
  },
19801
19903
  contextWindow: 262144,
19802
- maxTokens: 8e4
19904
+ maxTokens: 144e3
19803
19905
  },
19804
19906
  "kwaipilot/kat-coder-pro-v2.5": {
19805
19907
  id: "kwaipilot/kat-coder-pro-v2.5",
@@ -19815,8 +19917,8 @@ var MODELS = {
19815
19917
  cacheRead: 0.15,
19816
19918
  cacheWrite: 0
19817
19919
  },
19818
- contextWindow: 256e3,
19819
- maxTokens: 8e4
19920
+ contextWindow: 262144,
19921
+ maxTokens: 235929
19820
19922
  },
19821
19923
  "liquid/lfm-2.5-2.6b:free": {
19822
19924
  id: "liquid/lfm-2.5-2.6b:free",
@@ -19932,12 +20034,12 @@ var MODELS = {
19932
20034
  input: ["text", "image"],
19933
20035
  cost: {
19934
20036
  input: 0.19999999999999998,
19935
- output: 0.7999999999999999,
20037
+ output: 0.696,
19936
20038
  cacheRead: 0,
19937
20039
  cacheWrite: 0
19938
20040
  },
19939
20041
  contextWindow: 1048576,
19940
- maxTokens: 16384
20042
+ maxTokens: 115200
19941
20043
  },
19942
20044
  "meta-llama/llama-4-scout": {
19943
20045
  id: "meta-llama/llama-4-scout",
@@ -19948,13 +20050,13 @@ var MODELS = {
19948
20050
  reasoning: false,
19949
20051
  input: ["text", "image"],
19950
20052
  cost: {
19951
- input: 0.11,
19952
- output: 0.33999999999999997,
19953
- cacheRead: 0.055,
20053
+ input: 0.09999999999999999,
20054
+ output: 0.3,
20055
+ cacheRead: 0,
19954
20056
  cacheWrite: 0
19955
20057
  },
19956
20058
  contextWindow: 1310720,
19957
- maxTokens: 8192
20059
+ maxTokens: 16384
19958
20060
  },
19959
20061
  "meta/muse-glimmer-30b": {
19960
20062
  id: "meta/muse-glimmer-30b",
@@ -19974,13 +20076,13 @@ var MODELS = {
19974
20076
  },
19975
20077
  input: ["text", "image"],
19976
20078
  cost: {
19977
- input: 0.35,
19978
- output: 1.5,
20079
+ input: 0.3,
20080
+ output: 1.2,
19979
20081
  cacheRead: 0.04,
19980
20082
  cacheWrite: 0
19981
20083
  },
19982
20084
  contextWindow: 131072,
19983
- maxTokens: 117964
20085
+ maxTokens: 16384
19984
20086
  },
19985
20087
  "meta/muse-spark-1.1": {
19986
20088
  id: "meta/muse-spark-1.1",
@@ -20299,9 +20401,9 @@ var MODELS = {
20299
20401
  reasoning: false,
20300
20402
  input: ["text"],
20301
20403
  cost: {
20302
- input: 0.44,
20303
- output: 2.2,
20304
- cacheRead: 0.044,
20404
+ input: 0.39999999999999997,
20405
+ output: 2,
20406
+ cacheRead: 0.04,
20305
20407
  cacheWrite: 0
20306
20408
  },
20307
20409
  contextWindow: 262144,
@@ -20575,8 +20677,8 @@ var MODELS = {
20575
20677
  cacheRead: 0.01,
20576
20678
  cacheWrite: 0
20577
20679
  },
20578
- contextWindow: 32e3,
20579
- maxTokens: 25600
20680
+ contextWindow: 32768,
20681
+ maxTokens: 26214
20580
20682
  },
20581
20683
  "moonshotai/kimi-k2": {
20582
20684
  id: "moonshotai/kimi-k2",
@@ -20710,9 +20812,9 @@ var MODELS = {
20710
20812
  },
20711
20813
  input: ["text", "image"],
20712
20814
  cost: {
20713
- input: 0.67,
20815
+ input: 0.66,
20714
20816
  output: 3.4,
20715
- cacheRead: 0.19,
20817
+ cacheRead: 0.18,
20716
20818
  cacheWrite: 0
20717
20819
  },
20718
20820
  contextWindow: 262144,
@@ -20815,11 +20917,11 @@ var MODELS = {
20815
20917
  cost: {
20816
20918
  input: 0.049999999999999996,
20817
20919
  output: 0.19999999999999998,
20818
- cacheRead: 0.03,
20920
+ cacheRead: 0.024999999999999998,
20819
20921
  cacheWrite: 0
20820
20922
  },
20821
20923
  contextWindow: 262144,
20822
- maxTokens: 235929
20924
+ maxTokens: 228e3
20823
20925
  },
20824
20926
  "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free": {
20825
20927
  id: "nvidia/nemotron-3-nano-omni-30b-a3b-reasoning:free",
@@ -20914,13 +21016,13 @@ var MODELS = {
20914
21016
  },
20915
21017
  input: ["text"],
20916
21018
  cost: {
20917
- input: 0.6,
20918
- output: 3.5999999999999996,
20919
- cacheRead: 0.19999999999999998,
21019
+ input: 0.5,
21020
+ output: 2.2,
21021
+ cacheRead: 0.09999999999999999,
20920
21022
  cacheWrite: 0
20921
21023
  },
20922
- contextWindow: 512288,
20923
- maxTokens: 461059
21024
+ contextWindow: 262144,
21025
+ maxTokens: 16384
20924
21026
  },
20925
21027
  "nvidia/nemotron-3-ultra-550b-a55b:free": {
20926
21028
  id: "nvidia/nemotron-3-ultra-550b-a55b:free",
@@ -22478,13 +22580,13 @@ var MODELS = {
22478
22580
  reasoning: false,
22479
22581
  input: ["text"],
22480
22582
  cost: {
22481
- input: 0.09,
22482
- output: 0.55,
22483
- cacheRead: 0,
22583
+ input: 0.0875,
22584
+ output: 0.35,
22585
+ cacheRead: 0.0175,
22484
22586
  cacheWrite: 0
22485
22587
  },
22486
22588
  contextWindow: 262144,
22487
- maxTokens: 16384
22589
+ maxTokens: 235929
22488
22590
  },
22489
22591
  "qwen/qwen3-235b-a22b-thinking-2507": {
22490
22592
  id: "qwen/qwen3-235b-a22b-thinking-2507",
@@ -22860,13 +22962,13 @@ var MODELS = {
22860
22962
  reasoning: false,
22861
22963
  input: ["text", "image"],
22862
22964
  cost: {
22863
- input: 0.13,
22864
- output: 0.52,
22965
+ input: 0.15,
22966
+ output: 0.6,
22865
22967
  cacheRead: 0,
22866
22968
  cacheWrite: 0
22867
22969
  },
22868
22970
  contextWindow: 262144,
22869
- maxTokens: 32768
22971
+ maxTokens: 16384
22870
22972
  },
22871
22973
  "qwen/qwen3-vl-30b-a3b-thinking": {
22872
22974
  id: "qwen/qwen3-vl-30b-a3b-thinking",
@@ -22974,13 +23076,13 @@ var MODELS = {
22974
23076
  },
22975
23077
  input: ["text", "image"],
22976
23078
  cost: {
22977
- input: 0.26,
22978
- output: 2.08,
23079
+ input: 0.29,
23080
+ output: 2.4,
22979
23081
  cacheRead: 0,
22980
23082
  cacheWrite: 0
22981
23083
  },
22982
23084
  contextWindow: 262144,
22983
- maxTokens: 235929
23085
+ maxTokens: 81920
22984
23086
  },
22985
23087
  "qwen/qwen3.5-27b": {
22986
23088
  id: "qwen/qwen3.5-27b",
@@ -23208,8 +23310,8 @@ var MODELS = {
23208
23310
  },
23209
23311
  input: ["text", "image"],
23210
23312
  cost: {
23211
- input: 0.14,
23212
- output: 1,
23313
+ input: 0.09999999999999999,
23314
+ output: 0.8999999999999999,
23213
23315
  cacheRead: 0.049999999999999996,
23214
23316
  cacheWrite: 0
23215
23317
  },
@@ -23396,7 +23498,7 @@ var MODELS = {
23396
23498
  cacheWrite: 0
23397
23499
  },
23398
23500
  contextWindow: 1048576,
23399
- maxTokens: 131072
23501
+ maxTokens: 262144
23400
23502
  },
23401
23503
  "qwen/qwen3.8-27b": {
23402
23504
  id: "qwen/qwen3.8-27b",
@@ -23423,6 +23525,32 @@ var MODELS = {
23423
23525
  contextWindow: 1e6,
23424
23526
  maxTokens: 131072
23425
23527
  },
23528
+ "qwen/qwen3.8-flash": {
23529
+ id: "qwen/qwen3.8-flash",
23530
+ name: "Qwen: Qwen3.8 Flash",
23531
+ api: "openai-completions",
23532
+ provider: "openrouter",
23533
+ baseUrl: "https://openrouter.ai/api/v1",
23534
+ compat: { "supportsReasoningEffort": false },
23535
+ reasoning: true,
23536
+ thinkingLevelMap: {
23537
+ "minimal": null,
23538
+ "low": null,
23539
+ "medium": null,
23540
+ "high": "high",
23541
+ "xhigh": null,
23542
+ "max": null
23543
+ },
23544
+ input: ["text", "image"],
23545
+ cost: {
23546
+ input: 0.15,
23547
+ output: 0.47,
23548
+ cacheRead: 0.016,
23549
+ cacheWrite: 0.19999999999999998
23550
+ },
23551
+ contextWindow: 1e6,
23552
+ maxTokens: 131072
23553
+ },
23426
23554
  "qwen/qwen3.8-max": {
23427
23555
  id: "qwen/qwen3.8-max",
23428
23556
  name: "Qwen: Qwen3.8 Max",
@@ -23551,32 +23679,6 @@ var MODELS = {
23551
23679
  contextWindow: 131072,
23552
23680
  maxTokens: 16384
23553
23681
  },
23554
- "stealth/ox-alpha": {
23555
- id: "stealth/ox-alpha",
23556
- name: "Ox Alpha",
23557
- api: "openai-completions",
23558
- provider: "openrouter",
23559
- baseUrl: "https://openrouter.ai/api/v1",
23560
- reasoning: true,
23561
- thinkingLevelMap: {
23562
- "off": null,
23563
- "minimal": null,
23564
- "low": "low",
23565
- "medium": null,
23566
- "high": "high",
23567
- "xhigh": null,
23568
- "max": "max"
23569
- },
23570
- input: ["text", "image"],
23571
- cost: {
23572
- input: 0,
23573
- output: 0,
23574
- cacheRead: 0,
23575
- cacheWrite: 0
23576
- },
23577
- contextWindow: 1048576,
23578
- maxTokens: 131072
23579
- },
23580
23682
  "stepfun/step-3.5-flash": {
23581
23683
  id: "stepfun/step-3.5-flash",
23582
23684
  name: "StepFun: Step 3.5 Flash",
@@ -23647,9 +23749,9 @@ var MODELS = {
23647
23749
  },
23648
23750
  input: ["text"],
23649
23751
  cost: {
23650
- input: 0.13199999999999998,
23651
- output: 0.5279999999999999,
23652
- cacheRead: 0.032999999999999995,
23752
+ input: 0.0825,
23753
+ output: 0.33,
23754
+ cacheRead: 0.020625,
23653
23755
  cacheWrite: 0
23654
23756
  },
23655
23757
  contextWindow: 262144,
@@ -23680,6 +23782,31 @@ var MODELS = {
23680
23782
  contextWindow: 262144,
23681
23783
  maxTokens: 235929
23682
23784
  },
23785
+ "tencent/hy4-preview": {
23786
+ id: "tencent/hy4-preview",
23787
+ name: "Tencent: Hy4 preview",
23788
+ api: "openai-completions",
23789
+ provider: "openrouter",
23790
+ baseUrl: "https://openrouter.ai/api/v1",
23791
+ reasoning: true,
23792
+ thinkingLevelMap: {
23793
+ "minimal": null,
23794
+ "low": "low",
23795
+ "medium": null,
23796
+ "high": "high",
23797
+ "xhigh": null,
23798
+ "max": null
23799
+ },
23800
+ input: ["text"],
23801
+ cost: {
23802
+ input: 0.834,
23803
+ output: 2.501,
23804
+ cacheRead: 0.041999999999999996,
23805
+ cacheWrite: 0
23806
+ },
23807
+ contextWindow: 1048576,
23808
+ maxTokens: 64e3
23809
+ },
23683
23810
  "thedrummer/unslopnemo-12b": {
23684
23811
  id: "thedrummer/unslopnemo-12b",
23685
23812
  name: "TheDrummer: UnslopNemo 12B",
@@ -23714,13 +23841,13 @@ var MODELS = {
23714
23841
  },
23715
23842
  input: ["text", "image"],
23716
23843
  cost: {
23717
- input: 0.95,
23844
+ input: 1,
23718
23845
  output: 4.05,
23719
- cacheRead: 0.16,
23846
+ cacheRead: 0.16999999999999998,
23720
23847
  cacheWrite: 0
23721
23848
  },
23722
23849
  contextWindow: 1048576,
23723
- maxTokens: 262144
23850
+ maxTokens: 471859
23724
23851
  },
23725
23852
  "thinkingmachines/inkling-small": {
23726
23853
  id: "thinkingmachines/inkling-small",
@@ -24127,13 +24254,13 @@ var MODELS = {
24127
24254
  },
24128
24255
  input: ["text"],
24129
24256
  cost: {
24130
- input: 0.5,
24131
- output: 2,
24132
- cacheRead: 0.09999999999999999,
24257
+ input: 0.43,
24258
+ output: 1.75,
24259
+ cacheRead: 0.08,
24133
24260
  cacheWrite: 0
24134
24261
  },
24135
24262
  contextWindow: 204800,
24136
- maxTokens: 131072
24263
+ maxTokens: 16384
24137
24264
  },
24138
24265
  "z-ai/glm-4.6v": {
24139
24266
  id: "z-ai/glm-4.6v",
@@ -24283,13 +24410,13 @@ var MODELS = {
24283
24410
  },
24284
24411
  input: ["text"],
24285
24412
  cost: {
24286
- input: 1.26,
24287
- output: 3.9600000000000004,
24288
- cacheRead: 0.234,
24413
+ input: 0.966,
24414
+ output: 3.036,
24415
+ cacheRead: 0.1794,
24289
24416
  cacheWrite: 0
24290
24417
  },
24291
24418
  contextWindow: 204800,
24292
- maxTokens: 182476
24419
+ maxTokens: 128e3
24293
24420
  },
24294
24421
  "z-ai/glm-5.2": {
24295
24422
  id: "z-ai/glm-5.2",
@@ -24364,7 +24491,33 @@ var MODELS = {
24364
24491
  cacheRead: 0.26,
24365
24492
  cacheWrite: 0
24366
24493
  },
24367
- contextWindow: 1048576,
24494
+ contextWindow: 1310720,
24495
+ maxTokens: 131072
24496
+ },
24497
+ "z-ai/glm-5.3-flash": {
24498
+ id: "z-ai/glm-5.3-flash",
24499
+ name: "Z.ai: GLM 5.3 Flash",
24500
+ api: "openai-completions",
24501
+ provider: "openrouter",
24502
+ baseUrl: "https://openrouter.ai/api/v1",
24503
+ reasoning: true,
24504
+ thinkingLevelMap: {
24505
+ "off": null,
24506
+ "minimal": null,
24507
+ "low": "low",
24508
+ "medium": null,
24509
+ "high": "high",
24510
+ "xhigh": null,
24511
+ "max": "max"
24512
+ },
24513
+ input: ["text", "image"],
24514
+ cost: {
24515
+ input: 0.075,
24516
+ output: 0.25,
24517
+ cacheRead: 0.015,
24518
+ cacheWrite: 0
24519
+ },
24520
+ contextWindow: 1310720,
24368
24521
  maxTokens: 131072
24369
24522
  },
24370
24523
  "z-ai/glm-5v-turbo": {
@@ -24516,9 +24669,9 @@ var MODELS = {
24516
24669
  },
24517
24670
  input: ["text"],
24518
24671
  cost: {
24519
- input: 0.03,
24520
- output: 0.075,
24521
- cacheRead: 7e-3,
24672
+ input: 0.049980000000000004,
24673
+ output: 0.09996000000000001,
24674
+ cacheRead: 0.009996000000000001,
24522
24675
  cacheWrite: 0
24523
24676
  },
24524
24677
  contextWindow: 1310720,
@@ -24542,10 +24695,10 @@ var MODELS = {
24542
24695
  },
24543
24696
  input: ["text", "image"],
24544
24697
  cost: {
24545
- input: 0.375,
24546
- output: 1.875,
24547
- cacheRead: 0.0375,
24548
- cacheWrite: 0.0208333333333333
24698
+ input: 0.75,
24699
+ output: 3.75,
24700
+ cacheRead: 0.075,
24701
+ cacheWrite: 0.0416666666666667
24549
24702
  },
24550
24703
  contextWindow: 1048576,
24551
24704
  maxTokens: 65536
@@ -24695,13 +24848,13 @@ var MODELS = {
24695
24848
  },
24696
24849
  input: ["text"],
24697
24850
  cost: {
24698
- input: 1.4,
24699
- output: 4.4,
24700
- cacheRead: 0.26,
24851
+ input: 1.17,
24852
+ output: 3.9600000000000004,
24853
+ cacheRead: 0.234,
24701
24854
  cacheWrite: 0
24702
24855
  },
24703
- contextWindow: 1048576,
24704
- maxTokens: 131072
24856
+ contextWindow: 1310720,
24857
+ maxTokens: 943718
24705
24858
  }
24706
24859
  },
24707
24860
  "prime-inference": {
@@ -25119,8 +25272,8 @@ var MODELS = {
25119
25272
  reasoning: false,
25120
25273
  input: ["text"],
25121
25274
  cost: {
25122
- input: 0.5,
25123
- output: 1.5,
25275
+ input: 0.4,
25276
+ output: 1.3,
25124
25277
  cacheRead: 0,
25125
25278
  cacheWrite: 0
25126
25279
  },
@@ -25143,8 +25296,8 @@ var MODELS = {
25143
25296
  reasoning: false,
25144
25297
  input: ["text"],
25145
25298
  cost: {
25146
- input: 1.25,
25147
- output: 1.5,
25299
+ input: 0.27,
25300
+ output: 1.12,
25148
25301
  cacheRead: 0,
25149
25302
  cacheWrite: 0
25150
25303
  },
@@ -25176,8 +25329,8 @@ var MODELS = {
25176
25329
  },
25177
25330
  input: ["text"],
25178
25331
  cost: {
25179
- input: 0.56,
25180
- output: 1.68,
25332
+ input: 0.6,
25333
+ output: 1.7,
25181
25334
  cacheRead: 0,
25182
25335
  cacheWrite: 0
25183
25336
  },
@@ -25209,8 +25362,8 @@ var MODELS = {
25209
25362
  },
25210
25363
  input: ["text"],
25211
25364
  cost: {
25212
- input: 0.45,
25213
- output: 1.5,
25365
+ input: 0.27,
25366
+ output: 1,
25214
25367
  cacheRead: 0,
25215
25368
  cacheWrite: 0
25216
25369
  },
@@ -25242,13 +25395,13 @@ var MODELS = {
25242
25395
  },
25243
25396
  input: ["text"],
25244
25397
  cost: {
25245
- input: 0.28,
25246
- output: 0.42,
25398
+ input: 0.3705,
25399
+ output: 1.1115,
25247
25400
  cacheRead: 0,
25248
25401
  cacheWrite: 0
25249
25402
  },
25250
25403
  contextWindow: 163840,
25251
- maxTokens: 147456,
25404
+ maxTokens: 65536,
25252
25405
  featured: true
25253
25406
  },
25254
25407
  "deepseek/deepseek-v3.2-exp": {
@@ -25276,8 +25429,8 @@ var MODELS = {
25276
25429
  },
25277
25430
  input: ["text"],
25278
25431
  cost: {
25279
- input: 0.28,
25280
- output: 0.42,
25432
+ input: 0.27,
25433
+ output: 0.41,
25281
25434
  cacheRead: 0,
25282
25435
  cacheWrite: 0
25283
25436
  },
@@ -25310,8 +25463,8 @@ var MODELS = {
25310
25463
  },
25311
25464
  input: ["text"],
25312
25465
  cost: {
25313
- input: 0.14,
25314
- output: 0.28,
25466
+ input: 0.44,
25467
+ output: 1.32,
25315
25468
  cacheRead: 0,
25316
25469
  cacheWrite: 0
25317
25470
  },
@@ -25345,8 +25498,8 @@ var MODELS = {
25345
25498
  },
25346
25499
  input: ["text"],
25347
25500
  cost: {
25348
- input: 0.14,
25349
- output: 0.28,
25501
+ input: 0.44,
25502
+ output: 1.32,
25350
25503
  cacheRead: 0,
25351
25504
  cacheWrite: 0
25352
25505
  },
@@ -25379,13 +25532,13 @@ var MODELS = {
25379
25532
  },
25380
25533
  input: ["text"],
25381
25534
  cost: {
25382
- input: 2.1,
25383
- output: 4.4,
25535
+ input: 1.91,
25536
+ output: 3.83,
25384
25537
  cacheRead: 0,
25385
25538
  cacheWrite: 0
25386
25539
  },
25387
25540
  contextWindow: 1048576,
25388
- maxTokens: 384e3,
25541
+ maxTokens: 393216,
25389
25542
  featured: true
25390
25543
  },
25391
25544
  "google/gemini-2.5-flash": {
@@ -25619,6 +25772,39 @@ var MODELS = {
25619
25772
  contextWindow: 1048576,
25620
25773
  maxTokens: 65536
25621
25774
  },
25775
+ "google/gemini-3.7-flash": {
25776
+ id: "google/gemini-3.7-flash",
25777
+ name: "Gemini 3.7 Flash",
25778
+ api: "openai-completions",
25779
+ provider: "prime-inference",
25780
+ baseUrl: "https://api.pinference.ai/api/v1",
25781
+ compat: {
25782
+ "supportsStore": false,
25783
+ "supportsDeveloperRole": false,
25784
+ "supportsReasoningEffort": true,
25785
+ "maxTokensField": "max_tokens",
25786
+ "supportsStrictMode": false
25787
+ },
25788
+ reasoning: true,
25789
+ thinkingLevelMap: {
25790
+ "off": null,
25791
+ "minimal": null,
25792
+ "low": "low",
25793
+ "medium": "medium",
25794
+ "high": "high",
25795
+ "xhigh": null,
25796
+ "max": null
25797
+ },
25798
+ input: ["text", "image"],
25799
+ cost: {
25800
+ input: 1.35,
25801
+ output: 6.75,
25802
+ cacheRead: 0,
25803
+ cacheWrite: 0
25804
+ },
25805
+ contextWindow: 1048576,
25806
+ maxTokens: 65536
25807
+ },
25622
25808
  "google/gemma-3-27b-it": {
25623
25809
  id: "google/gemma-3-27b-it",
25624
25810
  name: "Gemma 3 27B IT",
@@ -25640,7 +25826,7 @@ var MODELS = {
25640
25826
  cacheRead: 0,
25641
25827
  cacheWrite: 0
25642
25828
  },
25643
- contextWindow: 262144,
25829
+ contextWindow: 131072,
25644
25830
  maxTokens: 117964
25645
25831
  },
25646
25832
  "meta-llama/Llama-3.2-1B-Instruct": {
@@ -25659,8 +25845,8 @@ var MODELS = {
25659
25845
  reasoning: false,
25660
25846
  input: ["text"],
25661
25847
  cost: {
25662
- input: 0.03,
25663
- output: 0.21,
25848
+ input: 0.027,
25849
+ output: 0.201,
25664
25850
  cacheRead: 0,
25665
25851
  cacheWrite: 0
25666
25852
  },
@@ -25683,8 +25869,8 @@ var MODELS = {
25683
25869
  reasoning: false,
25684
25870
  input: ["text"],
25685
25871
  cost: {
25686
- input: 0.1,
25687
- output: 0.34,
25872
+ input: 0.0509,
25873
+ output: 0.335,
25688
25874
  cacheRead: 0,
25689
25875
  cacheWrite: 0
25690
25876
  },
@@ -25707,8 +25893,8 @@ var MODELS = {
25707
25893
  reasoning: false,
25708
25894
  input: ["text"],
25709
25895
  cost: {
25710
- input: 0.9,
25711
- output: 0.9,
25896
+ input: 1.04,
25897
+ output: 2.253,
25712
25898
  cacheRead: 0,
25713
25899
  cacheWrite: 0
25714
25900
  },
@@ -25731,13 +25917,46 @@ var MODELS = {
25731
25917
  reasoning: false,
25732
25918
  input: ["text", "image"],
25733
25919
  cost: {
25734
- input: 0.27,
25735
- output: 0.88,
25920
+ input: 0.35,
25921
+ output: 1.15,
25736
25922
  cacheRead: 0,
25737
25923
  cacheWrite: 0
25738
25924
  },
25739
25925
  contextWindow: 1048576,
25740
- maxTokens: 16384
25926
+ maxTokens: 115200
25927
+ },
25928
+ "meta/muse-spark-1.2": {
25929
+ id: "meta/muse-spark-1.2",
25930
+ name: "Muse Spark 1.2",
25931
+ api: "openai-completions",
25932
+ provider: "prime-inference",
25933
+ baseUrl: "https://api.pinference.ai/api/v1",
25934
+ compat: {
25935
+ "supportsStore": false,
25936
+ "supportsDeveloperRole": false,
25937
+ "supportsReasoningEffort": true,
25938
+ "maxTokensField": "max_tokens",
25939
+ "supportsStrictMode": false
25940
+ },
25941
+ reasoning: true,
25942
+ thinkingLevelMap: {
25943
+ "off": null,
25944
+ "minimal": "minimal",
25945
+ "low": "low",
25946
+ "medium": "medium",
25947
+ "high": "high",
25948
+ "xhigh": "xhigh",
25949
+ "max": null
25950
+ },
25951
+ input: ["text", "image"],
25952
+ cost: {
25953
+ input: 1.25,
25954
+ output: 4.25,
25955
+ cacheRead: 0,
25956
+ cacheWrite: 0
25957
+ },
25958
+ contextWindow: 1048576,
25959
+ maxTokens: 943718
25741
25960
  },
25742
25961
  "minimax/minimax-m2.5": {
25743
25962
  id: "minimax/minimax-m2.5",
@@ -25765,8 +25984,8 @@ var MODELS = {
25765
25984
  },
25766
25985
  input: ["text"],
25767
25986
  cost: {
25768
- input: 0.3,
25769
- output: 1.2,
25987
+ input: 0.6,
25988
+ output: 2.4,
25770
25989
  cacheRead: 0,
25771
25990
  cacheWrite: 0
25772
25991
  },
@@ -25881,8 +26100,8 @@ var MODELS = {
25881
26100
  reasoning: false,
25882
26101
  input: ["text"],
25883
26102
  cost: {
25884
- input: 0.1,
25885
- output: 0.25,
26103
+ input: 0.165,
26104
+ output: 0.17,
25886
26105
  cacheRead: 0,
25887
26106
  cacheWrite: 0
25888
26107
  },
@@ -25913,8 +26132,8 @@ var MODELS = {
25913
26132
  },
25914
26133
  input: ["text", "image"],
25915
26134
  cost: {
25916
- input: 0.1875,
25917
- output: 0.75,
26135
+ input: 0.165,
26136
+ output: 0.66,
25918
26137
  cacheRead: 0,
25919
26138
  cacheWrite: 0
25920
26139
  },
@@ -25937,8 +26156,8 @@ var MODELS = {
25937
26156
  reasoning: false,
25938
26157
  input: ["text"],
25939
26158
  cost: {
25940
- input: 2,
25941
- output: 6,
26159
+ input: 2.2,
26160
+ output: 6.6,
25942
26161
  cacheRead: 0,
25943
26162
  cacheWrite: 0
25944
26163
  },
@@ -25961,8 +26180,8 @@ var MODELS = {
25961
26180
  reasoning: false,
25962
26181
  input: ["text"],
25963
26182
  cost: {
25964
- input: 1.2,
25965
- output: 5,
26183
+ input: 0.6,
26184
+ output: 2.5,
25966
26185
  cacheRead: 0,
25967
26186
  cacheWrite: 0
25968
26187
  },
@@ -25995,7 +26214,7 @@ var MODELS = {
25995
26214
  input: ["text", "image"],
25996
26215
  cost: {
25997
26216
  input: 0.6,
25998
- output: 3.2,
26217
+ output: 3,
25999
26218
  cacheRead: 0,
26000
26219
  cacheWrite: 0
26001
26220
  },
@@ -26061,8 +26280,8 @@ var MODELS = {
26061
26280
  },
26062
26281
  input: ["text", "image"],
26063
26282
  cost: {
26064
- input: 1.0925,
26065
- output: 4.6,
26283
+ input: 1.9,
26284
+ output: 8,
26066
26285
  cacheRead: 0,
26067
26286
  cacheWrite: 0
26068
26287
  },
@@ -26094,8 +26313,8 @@ var MODELS = {
26094
26313
  },
26095
26314
  input: ["text", "image"],
26096
26315
  cost: {
26097
- input: 3,
26098
- output: 15,
26316
+ input: 3.45,
26317
+ output: 17.25,
26099
26318
  cacheRead: 0,
26100
26319
  cacheWrite: 0
26101
26320
  },
@@ -26128,13 +26347,13 @@ var MODELS = {
26128
26347
  },
26129
26348
  input: ["text"],
26130
26349
  cost: {
26131
- input: 0.05,
26132
- output: 0.2,
26350
+ input: 0.06,
26351
+ output: 0.24,
26133
26352
  cacheRead: 0,
26134
26353
  cacheWrite: 0
26135
26354
  },
26136
26355
  contextWindow: 262144,
26137
- maxTokens: 235929,
26356
+ maxTokens: 228e3,
26138
26357
  featured: true
26139
26358
  },
26140
26359
  "nvidia/nemotron-3-super-120b-a12b": {
@@ -26162,7 +26381,7 @@ var MODELS = {
26162
26381
  input: ["text"],
26163
26382
  cost: {
26164
26383
  input: 0.3,
26165
- output: 0.9,
26384
+ output: 0.65,
26166
26385
  cacheRead: 0,
26167
26386
  cacheWrite: 0
26168
26387
  },
@@ -26453,31 +26672,6 @@ var MODELS = {
26453
26672
  contextWindow: 4e5,
26454
26673
  maxTokens: 128e3
26455
26674
  },
26456
- "openai/gpt-5.2-chat": {
26457
- id: "openai/gpt-5.2-chat",
26458
- name: "GPT 5.2 Chat",
26459
- api: "openai-completions",
26460
- provider: "prime-inference",
26461
- baseUrl: "https://api.pinference.ai/api/v1",
26462
- compat: {
26463
- "supportsStore": false,
26464
- "supportsDeveloperRole": false,
26465
- "supportsReasoningEffort": true,
26466
- "maxTokensField": "max_tokens",
26467
- "supportsStrictMode": false
26468
- },
26469
- reasoning: false,
26470
- thinkingLevelMap: { "xhigh": "xhigh" },
26471
- input: ["text", "image"],
26472
- cost: {
26473
- input: 1.75,
26474
- output: 14,
26475
- cacheRead: 0,
26476
- cacheWrite: 0
26477
- },
26478
- contextWindow: 128e3,
26479
- maxTokens: 32e3
26480
- },
26481
26675
  "openai/gpt-5.2-pro": {
26482
26676
  id: "openai/gpt-5.2-pro",
26483
26677
  name: "GPT 5.2 PRO",
@@ -26762,8 +26956,8 @@ var MODELS = {
26762
26956
  },
26763
26957
  input: ["text", "image"],
26764
26958
  cost: {
26765
- input: 1,
26766
- output: 6,
26959
+ input: 0.2,
26960
+ output: 1.2,
26767
26961
  cacheRead: 0,
26768
26962
  cacheWrite: 0
26769
26963
  },
@@ -26955,8 +27149,8 @@ var MODELS = {
26955
27149
  },
26956
27150
  input: ["text"],
26957
27151
  cost: {
26958
- input: 0.15,
26959
- output: 0.6,
27152
+ input: 0.35,
27153
+ output: 0.75,
26960
27154
  cacheRead: 0,
26961
27155
  cacheWrite: 0
26962
27156
  },
@@ -27021,8 +27215,8 @@ var MODELS = {
27021
27215
  },
27022
27216
  input: ["text"],
27023
27217
  cost: {
27024
- input: 0.1,
27025
- output: 0.19,
27218
+ input: 0.09,
27219
+ output: 0.18,
27026
27220
  cacheRead: 0,
27027
27221
  cacheWrite: 0
27028
27222
  },
@@ -27054,8 +27248,8 @@ var MODELS = {
27054
27248
  },
27055
27249
  input: ["text"],
27056
27250
  cost: {
27057
- input: 0.065,
27058
- output: 0.13,
27251
+ input: 0.06,
27252
+ output: 0.12,
27059
27253
  cacheRead: 0,
27060
27254
  cacheWrite: 0
27061
27255
  },
@@ -27078,13 +27272,13 @@ var MODELS = {
27078
27272
  reasoning: false,
27079
27273
  input: ["text"],
27080
27274
  cost: {
27081
- input: 0.22,
27082
- output: 0.88,
27275
+ input: 0.25,
27276
+ output: 1,
27083
27277
  cacheRead: 0,
27084
27278
  cacheWrite: 0
27085
27279
  },
27086
27280
  contextWindow: 262144,
27087
- maxTokens: 16384
27281
+ maxTokens: 235929
27088
27282
  },
27089
27283
  "qwen/qwen3-30b-a3b-instruct-2507": {
27090
27284
  id: "qwen/qwen3-30b-a3b-instruct-2507",
@@ -27102,8 +27296,8 @@ var MODELS = {
27102
27296
  reasoning: false,
27103
27297
  input: ["text"],
27104
27298
  cost: {
27105
- input: 0.2,
27106
- output: 0.8,
27299
+ input: 0.13,
27300
+ output: 0.52,
27107
27301
  cacheRead: 0,
27108
27302
  cacheWrite: 0
27109
27303
  },
@@ -27160,7 +27354,7 @@ var MODELS = {
27160
27354
  reasoning: false,
27161
27355
  input: ["text"],
27162
27356
  cost: {
27163
- input: 2,
27357
+ input: 0.975,
27164
27358
  output: 4.875,
27165
27359
  cacheRead: 0,
27166
27360
  cacheWrite: 0
@@ -27184,7 +27378,7 @@ var MODELS = {
27184
27378
  reasoning: false,
27185
27379
  input: ["text"],
27186
27380
  cost: {
27187
- input: 0.5,
27381
+ input: 0.3,
27188
27382
  output: 1.5,
27189
27383
  cacheRead: 0,
27190
27384
  cacheWrite: 0
@@ -27234,8 +27428,8 @@ var MODELS = {
27234
27428
  reasoning: false,
27235
27429
  input: ["text", "image"],
27236
27430
  cost: {
27237
- input: 0.4,
27238
- output: 1.9,
27431
+ input: 0.3,
27432
+ output: 1.5,
27239
27433
  cacheRead: 0,
27240
27434
  cacheWrite: 0
27241
27435
  },
@@ -27268,7 +27462,7 @@ var MODELS = {
27268
27462
  },
27269
27463
  input: ["text", "image"],
27270
27464
  cost: {
27271
- input: 1,
27465
+ input: 0.98,
27272
27466
  output: 4,
27273
27467
  cacheRead: 0,
27274
27468
  cacheWrite: 0
@@ -27293,13 +27487,13 @@ var MODELS = {
27293
27487
  reasoning: false,
27294
27488
  input: ["text", "image"],
27295
27489
  cost: {
27296
- input: 0.25,
27297
- output: 1,
27490
+ input: 0.2,
27491
+ output: 0.7,
27298
27492
  cacheRead: 0,
27299
27493
  cacheWrite: 0
27300
27494
  },
27301
27495
  contextWindow: 262144,
27302
- maxTokens: 32768
27496
+ maxTokens: 16384
27303
27497
  },
27304
27498
  "qwen/qwen3-vl-8b-instruct": {
27305
27499
  id: "qwen/qwen3-vl-8b-instruct",
@@ -27317,8 +27511,8 @@ var MODELS = {
27317
27511
  reasoning: false,
27318
27512
  input: ["text", "image"],
27319
27513
  cost: {
27320
- input: 0.18,
27321
- output: 0.7,
27514
+ input: 0.117,
27515
+ output: 0.455,
27322
27516
  cacheRead: 0,
27323
27517
  cacheWrite: 0
27324
27518
  },
@@ -27350,8 +27544,8 @@ var MODELS = {
27350
27544
  },
27351
27545
  input: ["text", "image"],
27352
27546
  cost: {
27353
- input: 0.3125,
27354
- output: 1.8,
27547
+ input: 0.25,
27548
+ output: 1.3,
27355
27549
  cacheRead: 0,
27356
27550
  cacheWrite: 0
27357
27551
  },
@@ -27449,8 +27643,8 @@ var MODELS = {
27449
27643
  },
27450
27644
  input: ["text", "image"],
27451
27645
  cost: {
27452
- input: 0.3,
27453
- output: 1.8,
27646
+ input: 0.25,
27647
+ output: 1.25,
27454
27648
  cacheRead: 0,
27455
27649
  cacheWrite: 0
27456
27650
  },
@@ -27588,9 +27782,42 @@ var MODELS = {
27588
27782
  cacheRead: 0,
27589
27783
  cacheWrite: 0
27590
27784
  },
27591
- contextWindow: 2e6,
27592
- maxTokens: 3e4,
27593
- featured: true
27785
+ contextWindow: 2e6,
27786
+ maxTokens: 3e4,
27787
+ featured: true
27788
+ },
27789
+ "x-ai/grok-4.6": {
27790
+ id: "x-ai/grok-4.6",
27791
+ name: "Grok 4.6",
27792
+ api: "openai-completions",
27793
+ provider: "prime-inference",
27794
+ baseUrl: "https://api.pinference.ai/api/v1",
27795
+ compat: {
27796
+ "supportsStore": false,
27797
+ "supportsDeveloperRole": false,
27798
+ "supportsReasoningEffort": true,
27799
+ "maxTokensField": "max_tokens",
27800
+ "supportsStrictMode": false
27801
+ },
27802
+ reasoning: true,
27803
+ thinkingLevelMap: {
27804
+ "off": null,
27805
+ "minimal": null,
27806
+ "low": "low",
27807
+ "medium": "medium",
27808
+ "high": "high",
27809
+ "xhigh": "xhigh",
27810
+ "max": null
27811
+ },
27812
+ input: ["text", "image"],
27813
+ cost: {
27814
+ input: 2,
27815
+ output: 6,
27816
+ cacheRead: 0,
27817
+ cacheWrite: 0
27818
+ },
27819
+ contextWindow: 5e5,
27820
+ maxTokens: 45e4
27594
27821
  },
27595
27822
  "xiaomi/mimo-v2.5": {
27596
27823
  id: "xiaomi/mimo-v2.5",
@@ -27617,8 +27844,8 @@ var MODELS = {
27617
27844
  },
27618
27845
  input: ["text", "image"],
27619
27846
  cost: {
27620
- input: 0.4,
27621
- output: 2,
27847
+ input: 0.168,
27848
+ output: 0.336,
27622
27849
  cacheRead: 0,
27623
27850
  cacheWrite: 0
27624
27851
  },
@@ -27650,8 +27877,8 @@ var MODELS = {
27650
27877
  },
27651
27878
  input: ["text"],
27652
27879
  cost: {
27653
- input: 1,
27654
- output: 3,
27880
+ input: 0.48024,
27881
+ output: 1.5,
27655
27882
  cacheRead: 0,
27656
27883
  cacheWrite: 0
27657
27884
  },
@@ -27755,7 +27982,7 @@ var MODELS = {
27755
27982
  cacheWrite: 0
27756
27983
  },
27757
27984
  contextWindow: 204800,
27758
- maxTokens: 131072
27985
+ maxTokens: 16384
27759
27986
  },
27760
27987
  "z-ai/glm-4.7": {
27761
27988
  id: "z-ai/glm-4.7",
@@ -27783,7 +28010,7 @@ var MODELS = {
27783
28010
  input: ["text"],
27784
28011
  cost: {
27785
28012
  input: 0.6,
27786
- output: 2.65,
28013
+ output: 2.2,
27787
28014
  cacheRead: 0,
27788
28015
  cacheWrite: 0
27789
28016
  },
@@ -27815,8 +28042,8 @@ var MODELS = {
27815
28042
  },
27816
28043
  input: ["text"],
27817
28044
  cost: {
27818
- input: 0.1,
27819
- output: 0.43,
28045
+ input: 0.07,
28046
+ output: 0.4,
27820
28047
  cacheRead: 0,
27821
28048
  cacheWrite: 0
27822
28049
  },
@@ -27848,8 +28075,8 @@ var MODELS = {
27848
28075
  },
27849
28076
  input: ["text"],
27850
28077
  cost: {
27851
- input: 1.2,
27852
- output: 3.5,
28078
+ input: 1,
28079
+ output: 3.2,
27853
28080
  cacheRead: 0,
27854
28081
  cacheWrite: 0
27855
28082
  },
@@ -27882,13 +28109,13 @@ var MODELS = {
27882
28109
  },
27883
28110
  input: ["text"],
27884
28111
  cost: {
27885
- input: 1.75,
27886
- output: 5.5,
28112
+ input: 1.4,
28113
+ output: 4.4,
27887
28114
  cacheRead: 0,
27888
28115
  cacheWrite: 0
27889
28116
  },
27890
28117
  contextWindow: 204800,
27891
- maxTokens: 182476,
28118
+ maxTokens: 128e3,
27892
28119
  featured: true
27893
28120
  },
27894
28121
  "z-ai/glm-5.2": {
@@ -27916,8 +28143,8 @@ var MODELS = {
27916
28143
  },
27917
28144
  input: ["text"],
27918
28145
  cost: {
27919
- input: 1.68,
27920
- output: 5.28,
28146
+ input: 1.54,
28147
+ output: 4.84,
27921
28148
  cacheRead: 0,
27922
28149
  cacheWrite: 0
27923
28150
  },
@@ -27956,7 +28183,41 @@ var MODELS = {
27956
28183
  cacheRead: 0,
27957
28184
  cacheWrite: 0
27958
28185
  },
27959
- contextWindow: 1048576,
28186
+ contextWindow: 1310720,
28187
+ maxTokens: 131072
28188
+ },
28189
+ "z-ai/glm-5.3-flash": {
28190
+ id: "z-ai/glm-5.3-flash",
28191
+ name: "GLM 5.3 Flash",
28192
+ api: "openai-completions",
28193
+ provider: "prime-inference",
28194
+ baseUrl: "https://api.pinference.ai/api/v1",
28195
+ compat: {
28196
+ "supportsStore": false,
28197
+ "supportsDeveloperRole": false,
28198
+ "supportsReasoningEffort": false,
28199
+ "maxTokensField": "max_tokens",
28200
+ "supportsStrictMode": false,
28201
+ "thinkingFormat": "zai"
28202
+ },
28203
+ reasoning: true,
28204
+ thinkingLevelMap: {
28205
+ "off": null,
28206
+ "minimal": null,
28207
+ "low": "low",
28208
+ "medium": null,
28209
+ "high": "high",
28210
+ "xhigh": null,
28211
+ "max": "max"
28212
+ },
28213
+ input: ["text", "image"],
28214
+ cost: {
28215
+ input: 0.15,
28216
+ output: 0.5,
28217
+ cacheRead: 0,
28218
+ cacheWrite: 0
28219
+ },
28220
+ contextWindow: 1310720,
27960
28221
  maxTokens: 131072
27961
28222
  }
27962
28223
  },
@@ -28397,11 +28658,11 @@ var MODELS = {
28397
28658
  cost: {
28398
28659
  input: 2,
28399
28660
  output: 6,
28400
- cacheRead: 0.19999999999999998,
28661
+ cacheRead: 0.25,
28401
28662
  cacheWrite: 0
28402
28663
  },
28403
28664
  contextWindow: 262144,
28404
- maxTokens: 131072
28665
+ maxTokens: 128e3
28405
28666
  },
28406
28667
  "alibaba/qwen3.8-27b": {
28407
28668
  id: "alibaba/qwen3.8-27b",
@@ -28412,14 +28673,48 @@ var MODELS = {
28412
28673
  reasoning: true,
28413
28674
  input: ["text", "image"],
28414
28675
  cost: {
28415
- input: 0.55,
28416
- output: 3.3000000000000003,
28417
- cacheRead: 0.11,
28418
- cacheWrite: 0
28676
+ input: 0.5,
28677
+ output: 3,
28678
+ cacheRead: 0.09999999999999999,
28679
+ cacheWrite: 0.625
28419
28680
  },
28420
28681
  contextWindow: 1e6,
28421
28682
  maxTokens: 131072
28422
28683
  },
28684
+ "alibaba/qwen3.8-flash": {
28685
+ id: "alibaba/qwen3.8-flash",
28686
+ name: "Qwen 3.8 Flash",
28687
+ api: "anthropic-messages",
28688
+ provider: "vercel-ai-gateway",
28689
+ baseUrl: "https://ai-gateway.vercel.sh",
28690
+ reasoning: true,
28691
+ input: ["text", "image"],
28692
+ cost: {
28693
+ input: 0.16,
28694
+ output: 0.47,
28695
+ cacheRead: 0.016,
28696
+ cacheWrite: 0.19999999999999998
28697
+ },
28698
+ contextWindow: 991e3,
28699
+ maxTokens: 128e3
28700
+ },
28701
+ "alibaba/qwen3.8-flash-next": {
28702
+ id: "alibaba/qwen3.8-flash-next",
28703
+ name: "Qwen 3.8 Flash Next",
28704
+ api: "anthropic-messages",
28705
+ provider: "vercel-ai-gateway",
28706
+ baseUrl: "https://ai-gateway.vercel.sh",
28707
+ reasoning: true,
28708
+ input: ["text", "image"],
28709
+ cost: {
28710
+ input: 0.12,
28711
+ output: 0.39999999999999997,
28712
+ cacheRead: 0.01,
28713
+ cacheWrite: 0
28714
+ },
28715
+ contextWindow: 1048576,
28716
+ maxTokens: 1048576
28717
+ },
28423
28718
  "alibaba/qwen3.8-max": {
28424
28719
  id: "alibaba/qwen3.8-max",
28425
28720
  name: "Qwen 3.8 Max",
@@ -28544,6 +28839,28 @@ var MODELS = {
28544
28839
  contextWindow: 1e6,
28545
28840
  maxTokens: 128e3
28546
28841
  },
28842
+ "anthropic/claude-fable-5.1": {
28843
+ id: "anthropic/claude-fable-5.1",
28844
+ name: "Claude Fable 5.1",
28845
+ api: "anthropic-messages",
28846
+ provider: "vercel-ai-gateway",
28847
+ baseUrl: "https://ai-gateway.vercel.sh",
28848
+ reasoning: true,
28849
+ thinkingLevelMap: {
28850
+ "off": null,
28851
+ "xhigh": "xhigh",
28852
+ "max": "max"
28853
+ },
28854
+ input: ["text", "image"],
28855
+ cost: {
28856
+ input: 10,
28857
+ output: 50,
28858
+ cacheRead: 0.25,
28859
+ cacheWrite: 12.5
28860
+ },
28861
+ contextWindow: 1e6,
28862
+ maxTokens: 128e3
28863
+ },
28547
28864
  "anthropic/claude-haiku-4.5": {
28548
28865
  id: "anthropic/claude-haiku-4.5",
28549
28866
  name: "Claude Haiku 4.5",
@@ -29009,8 +29326,8 @@ var MODELS = {
29009
29326
  cacheRead: 7e-3,
29010
29327
  cacheWrite: 0
29011
29328
  },
29012
- contextWindow: 1e6,
29013
- maxTokens: 384e3
29329
+ contextWindow: 1048576,
29330
+ maxTokens: 1048576
29014
29331
  },
29015
29332
  "deepseek/deepseek-v4-pro": {
29016
29333
  id: "deepseek/deepseek-v4-pro",
@@ -29021,13 +29338,13 @@ var MODELS = {
29021
29338
  reasoning: true,
29022
29339
  input: ["text"],
29023
29340
  cost: {
29024
- input: 1.74,
29025
- output: 3.48,
29026
- cacheRead: 0.14,
29341
+ input: 0.66,
29342
+ output: 1.9800000000000002,
29343
+ cacheRead: 0.022,
29027
29344
  cacheWrite: 0
29028
29345
  },
29029
- contextWindow: 1048600,
29030
- maxTokens: 1048600
29346
+ contextWindow: 1e6,
29347
+ maxTokens: 384e3
29031
29348
  },
29032
29349
  "deepseek/deepseek-v4-pro-0813": {
29033
29350
  id: "deepseek/deepseek-v4-pro-0813",
@@ -29301,6 +29618,40 @@ var MODELS = {
29301
29618
  contextWindow: 256e3,
29302
29619
  maxTokens: 32e3
29303
29620
  },
29621
+ "inclusionai/ling-3.0-flash-fin": {
29622
+ id: "inclusionai/ling-3.0-flash-fin",
29623
+ name: "Ling 3.0 Flash Fin",
29624
+ api: "anthropic-messages",
29625
+ provider: "vercel-ai-gateway",
29626
+ baseUrl: "https://ai-gateway.vercel.sh",
29627
+ reasoning: true,
29628
+ input: ["text"],
29629
+ cost: {
29630
+ input: 0,
29631
+ output: 0,
29632
+ cacheRead: 0,
29633
+ cacheWrite: 0
29634
+ },
29635
+ contextWindow: 256e3,
29636
+ maxTokens: 32e3
29637
+ },
29638
+ "inclusionai/ling-3.0-flash-fin-free": {
29639
+ id: "inclusionai/ling-3.0-flash-fin-free",
29640
+ name: "Ling 3.0 Flash Fin (Free)",
29641
+ api: "anthropic-messages",
29642
+ provider: "vercel-ai-gateway",
29643
+ baseUrl: "https://ai-gateway.vercel.sh",
29644
+ reasoning: true,
29645
+ input: ["text"],
29646
+ cost: {
29647
+ input: 0,
29648
+ output: 0,
29649
+ cacheRead: 0,
29650
+ cacheWrite: 0
29651
+ },
29652
+ contextWindow: 256e3,
29653
+ maxTokens: 32e3
29654
+ },
29304
29655
  "interfaze/interfaze-beta": {
29305
29656
  id: "interfaze/interfaze-beta",
29306
29657
  name: "Interfaze Beta",
@@ -29626,7 +29977,7 @@ var MODELS = {
29626
29977
  },
29627
29978
  "minimax/minimax-m2.7": {
29628
29979
  id: "minimax/minimax-m2.7",
29629
- name: "Minimax M2.7",
29980
+ name: "MiniMax M2.7",
29630
29981
  api: "anthropic-messages",
29631
29982
  provider: "vercel-ai-gateway",
29632
29983
  baseUrl: "https://ai-gateway.vercel.sh",
@@ -29643,7 +29994,7 @@ var MODELS = {
29643
29994
  },
29644
29995
  "minimax/minimax-m2.7-free": {
29645
29996
  id: "minimax/minimax-m2.7-free",
29646
- name: "Minimax M2.7 (Free)",
29997
+ name: "MiniMax M2.7 (Free)",
29647
29998
  api: "anthropic-messages",
29648
29999
  provider: "vercel-ai-gateway",
29649
30000
  baseUrl: "https://ai-gateway.vercel.sh",
@@ -29689,8 +30040,8 @@ var MODELS = {
29689
30040
  cacheRead: 0.06,
29690
30041
  cacheWrite: 0
29691
30042
  },
29692
- contextWindow: 1e6,
29693
- maxTokens: 1e6
30043
+ contextWindow: 512e3,
30044
+ maxTokens: 512e3
29694
30045
  },
29695
30046
  "minimax/minimax-m3-free": {
29696
30047
  id: "minimax/minimax-m3-free",
@@ -29992,7 +30343,7 @@ var MODELS = {
29992
30343
  cost: {
29993
30344
  input: 0.95,
29994
30345
  output: 4,
29995
- cacheRead: 0.19,
30346
+ cacheRead: 0.16,
29996
30347
  cacheWrite: 0
29997
30348
  },
29998
30349
  contextWindow: 256e3,
@@ -30128,8 +30479,8 @@ var MODELS = {
30128
30479
  input: ["text"],
30129
30480
  cost: {
30130
30481
  input: 0.049999999999999996,
30131
- output: 0.15,
30132
- cacheRead: 0.049999999999999996,
30482
+ output: 0.19999999999999998,
30483
+ cacheRead: 0.01,
30133
30484
  cacheWrite: 0
30134
30485
  },
30135
30486
  contextWindow: 262144,
@@ -31481,13 +31832,30 @@ var MODELS = {
31481
31832
  reasoning: true,
31482
31833
  input: ["text"],
31483
31834
  cost: {
31484
- input: 0.13199999999999998,
31485
- output: 0.5279999999999999,
31486
- cacheRead: 0.032999999999999995,
31835
+ input: 0.14,
31836
+ output: 0.58,
31837
+ cacheRead: 0.035,
31487
31838
  cacheWrite: 0
31488
31839
  },
31489
- contextWindow: 256e3,
31490
- maxTokens: 128e3
31840
+ contextWindow: 262144,
31841
+ maxTokens: 262144
31842
+ },
31843
+ "tencent/hy4-preview": {
31844
+ id: "tencent/hy4-preview",
31845
+ name: "Tencent Hy4 Preview",
31846
+ api: "anthropic-messages",
31847
+ provider: "vercel-ai-gateway",
31848
+ baseUrl: "https://ai-gateway.vercel.sh",
31849
+ reasoning: true,
31850
+ input: ["text"],
31851
+ cost: {
31852
+ input: 0.834,
31853
+ output: 2.501,
31854
+ cacheRead: 0.041999999999999996,
31855
+ cacheWrite: 0
31856
+ },
31857
+ contextWindow: 1024e3,
31858
+ maxTokens: 64e3
31491
31859
  },
31492
31860
  "thinkingmachines/inkling": {
31493
31861
  id: "thinkingmachines/inkling",
@@ -31557,6 +31925,23 @@ var MODELS = {
31557
31925
  contextWindow: 105e4,
31558
31926
  maxTokens: 131e3
31559
31927
  },
31928
+ "xiaomi/mimo-v2.5-pro-ultraspeed": {
31929
+ id: "xiaomi/mimo-v2.5-pro-ultraspeed",
31930
+ name: "MiMo V2.5 Pro UltraSpeed",
31931
+ api: "anthropic-messages",
31932
+ provider: "vercel-ai-gateway",
31933
+ baseUrl: "https://ai-gateway.vercel.sh",
31934
+ reasoning: true,
31935
+ input: ["text"],
31936
+ cost: {
31937
+ input: 1.305,
31938
+ output: 2.61,
31939
+ cacheRead: 0.0108,
31940
+ cacheWrite: 0
31941
+ },
31942
+ contextWindow: 1048576,
31943
+ maxTokens: 131072
31944
+ },
31560
31945
  "zai/glm-4.5": {
31561
31946
  id: "zai/glm-4.5",
31562
31947
  name: "GLM 4.5",
@@ -31772,11 +32157,28 @@ var MODELS = {
31772
32157
  cost: {
31773
32158
  input: 1.4,
31774
32159
  output: 4.4,
31775
- cacheRead: 0.26,
32160
+ cacheRead: 0.14,
32161
+ cacheWrite: 0
32162
+ },
32163
+ contextWindow: 1e6,
32164
+ maxTokens: 1e6
32165
+ },
32166
+ "zai/glm-5.3-flash": {
32167
+ id: "zai/glm-5.3-flash",
32168
+ name: "GLM 5.3 Flash",
32169
+ api: "anthropic-messages",
32170
+ provider: "vercel-ai-gateway",
32171
+ baseUrl: "https://ai-gateway.vercel.sh",
32172
+ reasoning: true,
32173
+ input: ["text", "image"],
32174
+ cost: {
32175
+ input: 0.15,
32176
+ output: 0.5,
32177
+ cacheRead: 0.03,
31776
32178
  cacheWrite: 0
31777
32179
  },
31778
32180
  contextWindow: 1e6,
31779
- maxTokens: 12800
32181
+ maxTokens: 131e3
31780
32182
  },
31781
32183
  "zai/glm-5v-turbo": {
31782
32184
  id: "zai/glm-5v-turbo",
@@ -32443,6 +32845,50 @@ var MODELS = {
32443
32845
  },
32444
32846
  contextWindow: 1e6,
32445
32847
  maxTokens: 131072
32848
+ },
32849
+ "glm-5.3-flash": {
32850
+ id: "glm-5.3-flash",
32851
+ name: "GLM-5.3-Flash",
32852
+ api: "openai-completions",
32853
+ provider: "zai",
32854
+ baseUrl: "https://api.z.ai/api/coding/paas/v4",
32855
+ compat: {
32856
+ "supportsDeveloperRole": false,
32857
+ "thinkingFormat": "zai",
32858
+ "zaiToolStream": true
32859
+ },
32860
+ reasoning: true,
32861
+ input: ["text", "image"],
32862
+ cost: {
32863
+ input: 0,
32864
+ output: 0,
32865
+ cacheRead: 0,
32866
+ cacheWrite: 0
32867
+ },
32868
+ contextWindow: 1e6,
32869
+ maxTokens: 131072
32870
+ },
32871
+ "glm-5.3-highspeed": {
32872
+ id: "glm-5.3-highspeed",
32873
+ name: "GLM-5.3 Highspeed",
32874
+ api: "openai-completions",
32875
+ provider: "zai",
32876
+ baseUrl: "https://api.z.ai/api/coding/paas/v4",
32877
+ compat: {
32878
+ "supportsDeveloperRole": false,
32879
+ "thinkingFormat": "zai",
32880
+ "zaiToolStream": true
32881
+ },
32882
+ reasoning: true,
32883
+ input: ["text"],
32884
+ cost: {
32885
+ input: 0,
32886
+ output: 0,
32887
+ cacheRead: 0,
32888
+ cacheWrite: 0
32889
+ },
32890
+ contextWindow: 1e6,
32891
+ maxTokens: 131072
32446
32892
  }
32447
32893
  }
32448
32894
  };
@@ -33379,6 +33825,13 @@ function handleChatQuestionPost(request) {
33379
33825
  return Response.json({ ok: true });
33380
33826
  });
33381
33827
  }
33828
+ function handleChatQueueMutationPost(request) {
33829
+ return wrapApiHandler(async () => {
33830
+ const body = ChatQueueMutationRequestSchema.parse(await request.json().catch(() => ({})));
33831
+ const result = await getBridge().deleteQueuedMessage(body.sessionId, body.lane, body.index, body.expectedText);
33832
+ return Response.json(ChatQueueMutationResponseSchema.parse(result));
33833
+ });
33834
+ }
33382
33835
  function packageSourceToString(source) {
33383
33836
  if (typeof source === "string") return { name: source };
33384
33837
  return {
@@ -33461,6 +33914,25 @@ function handleChatResumePost(request) {
33461
33914
  function handleChatSessionGet(request) {
33462
33915
  return wrapApiHandler(async () => {
33463
33916
  const url = new URL(request.url);
33917
+ const parentSessionId = url.searchParams.get("parentSessionId");
33918
+ const childId = url.searchParams.get("childId");
33919
+ if (parentSessionId || childId) {
33920
+ if (!parentSessionId || !childId) return Response.json({ message: "GET /api/chat/session requires both ?parentSessionId= and ?childId=" }, { status: 400 });
33921
+ const parsedParentSessionId = SessionIdSchema.safeParse(parentSessionId);
33922
+ const parsedChildId = SessionIdSchema.safeParse(childId);
33923
+ if (!parsedParentSessionId.success || !parsedChildId.success) return Response.json({ message: "Invalid subagent session identifiers" }, { status: 400 });
33924
+ const child = await getBridge().loadRlmChildTranscript(parsedParentSessionId.data, parsedChildId.data);
33925
+ if (!child) return Response.json({ message: "Unknown subagent transcript" }, { status: 404 });
33926
+ return Response.json({
33927
+ session: {
33928
+ sessionId: child.sessionId,
33929
+ projectId: child.projectId
33930
+ },
33931
+ messages: child.messages,
33932
+ planPresentations: [],
33933
+ presentation: child.presentation
33934
+ });
33935
+ }
33464
33936
  const sessionId = url.searchParams.get("sessionId");
33465
33937
  const requestedProjectId = url.searchParams.get("projectId");
33466
33938
  const openUI = url.searchParams.get("openUI") === "true";
@@ -33525,6 +33997,7 @@ function normalizeSessionListRow(source) {
33525
33997
  if (!sessionId || !cwd) throw new Error("The Prime Agent session listing returned an invalid session entry");
33526
33998
  const createdAt = timestampValue(raw.created) ?? timestampValue(raw.modified) ?? (/* @__PURE__ */ new Date()).toISOString();
33527
33999
  const updatedAt = timestampValue(raw.modified) ?? timestampValue(raw.created) ?? createdAt;
34000
+ const isSubagent = typeof raw.runtimeKind === "string" ? raw.runtimeKind === "subagent" : Boolean(raw.rlmChildId ?? raw.rlmParentNodeId ?? raw.parentActiveSessionId ?? raw.parentSessionId ?? raw.parentSessionPath);
33528
34001
  return {
33529
34002
  source,
33530
34003
  sessionId,
@@ -33533,7 +34006,8 @@ function normalizeSessionListRow(source) {
33533
34006
  createdAt,
33534
34007
  updatedAt,
33535
34008
  messageCount: messageCountValue(raw.messageCount),
33536
- firstMessage: typeof raw.firstMessage === "string" ? raw.firstMessage : ""
34009
+ firstMessage: typeof raw.firstMessage === "string" ? raw.firstMessage : "",
34010
+ isSubagent
33537
34011
  };
33538
34012
  }
33539
34013
  function sessionStatus(info, live) {
@@ -33573,7 +34047,8 @@ function handleProjectsGet(_request) {
33573
34047
  updatedAt: session.updatedAt,
33574
34048
  status: sessionStatus(session.source, getBridge().getSession(session.sessionId)),
33575
34049
  messageCount: session.messageCount,
33576
- firstMessage: session.firstMessage ? redactSessionLabelSecrets(session.firstMessage) : ""
34050
+ firstMessage: session.firstMessage ? redactSessionLabelSecrets(session.firstMessage) : "",
34051
+ ...session.isSubagent ? { isSubagent: true } : {}
33577
34052
  };
33578
34053
  })
33579
34054
  });
@@ -33637,7 +34112,8 @@ function handleChatSessionsGet(_request) {
33637
34112
  updatedAt: session.updatedAt,
33638
34113
  status: sessionStatus(session.source, liveSession),
33639
34114
  messageCount: session.messageCount,
33640
- firstMessage: session.firstMessage
34115
+ firstMessage: session.firstMessage,
34116
+ ...session.isSubagent ? { isSubagent: true } : {}
33641
34117
  };
33642
34118
  }));
33643
34119
  return Response.json({ sessions: projectId ? formatted.filter((session) => session.projectId === projectId) : formatted });
@@ -33981,7 +34457,8 @@ var Route$11 = createFileRoute("/api/chat/resume")({ server: { handlers: { POST:
33981
34457
  var Route$10 = createFileRoute("/api/chat/session")({ server: { handlers: {
33982
34458
  GET: ({ request }) => new URL(request.url).searchParams.has("attachmentId") ? handleChatAttachmentGet(request) : handleChatSessionGet(request),
33983
34459
  POST: ({ request }) => handleChatAttachmentsPost(request),
33984
- PUT: ({ request }) => handleChatPlanPresentationPut(request)
34460
+ PUT: ({ request }) => handleChatPlanPresentationPut(request),
34461
+ PATCH: ({ request }) => handleChatQueueMutationPost(request)
33985
34462
  } } });
33986
34463
  var Route$9 = createFileRoute("/api/chat/sessions")({ server: { handlers: {
33987
34464
  DELETE: ({ request }) => handleChatSessionDelete(request),