@recombine-ai/bosun 0.5.1 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/build/client/_app/immutable/assets/0.DHvyfZ2Z.css +1 -0
  2. package/build/client/_app/immutable/assets/0.DHvyfZ2Z.css.br +0 -0
  3. package/build/client/_app/immutable/assets/0.DHvyfZ2Z.css.gz +0 -0
  4. package/build/client/_app/immutable/chunks/{CXaO9BO2.js → B6g_JkSM.js} +1 -1
  5. package/build/client/_app/immutable/chunks/B6g_JkSM.js.br +0 -0
  6. package/build/client/_app/immutable/chunks/B6g_JkSM.js.gz +0 -0
  7. package/build/client/_app/immutable/chunks/{C232NBSx.js → BcH1VEVU.js} +1 -1
  8. package/build/client/_app/immutable/chunks/BcH1VEVU.js.br +0 -0
  9. package/build/client/_app/immutable/chunks/BcH1VEVU.js.gz +0 -0
  10. package/build/client/_app/immutable/chunks/{BPR9ibgw.js → C0bQ35Gc.js} +1 -1
  11. package/build/client/_app/immutable/chunks/C0bQ35Gc.js.br +0 -0
  12. package/build/client/_app/immutable/chunks/C0bQ35Gc.js.gz +0 -0
  13. package/build/client/_app/immutable/chunks/{C9f-9-Wt.js → CEH18jSl.js} +1 -1
  14. package/build/client/_app/immutable/chunks/CEH18jSl.js.br +0 -0
  15. package/build/client/_app/immutable/chunks/CEH18jSl.js.gz +0 -0
  16. package/build/client/_app/immutable/chunks/{CKb0QqXx.js → CSuN09OQ.js} +1 -1
  17. package/build/client/_app/immutable/chunks/CSuN09OQ.js.br +0 -0
  18. package/build/client/_app/immutable/chunks/CSuN09OQ.js.gz +0 -0
  19. package/build/client/_app/immutable/chunks/DUMGgJTb.js +5 -0
  20. package/build/client/_app/immutable/chunks/DUMGgJTb.js.br +0 -0
  21. package/build/client/_app/immutable/chunks/DUMGgJTb.js.gz +0 -0
  22. package/build/client/_app/immutable/chunks/{BAbuLHvf.js → Deds-Bu4.js} +1 -1
  23. package/build/client/_app/immutable/chunks/Deds-Bu4.js.br +0 -0
  24. package/build/client/_app/immutable/chunks/Deds-Bu4.js.gz +0 -0
  25. package/build/client/_app/immutable/chunks/Dt0j4sZQ.js +2 -0
  26. package/build/client/_app/immutable/chunks/Dt0j4sZQ.js.br +0 -0
  27. package/build/client/_app/immutable/chunks/Dt0j4sZQ.js.gz +0 -0
  28. package/build/client/_app/immutable/chunks/{5mKQEBmA.js → DxquQJx9.js} +1 -1
  29. package/build/client/_app/immutable/chunks/DxquQJx9.js.br +0 -0
  30. package/build/client/_app/immutable/chunks/DxquQJx9.js.gz +0 -0
  31. package/build/client/_app/immutable/chunks/{COR6mdUG.js → V9U6b0dU.js} +1 -1
  32. package/build/client/_app/immutable/chunks/V9U6b0dU.js.br +0 -0
  33. package/build/client/_app/immutable/chunks/V9U6b0dU.js.gz +0 -0
  34. package/build/client/_app/immutable/entry/{app.oAXSW36_.js → app.DKvvDDfZ.js} +2 -2
  35. package/build/client/_app/immutable/entry/app.DKvvDDfZ.js.br +0 -0
  36. package/build/client/_app/immutable/entry/app.DKvvDDfZ.js.gz +0 -0
  37. package/build/client/_app/immutable/entry/start.BqlKjodc.js +1 -0
  38. package/build/client/_app/immutable/entry/start.BqlKjodc.js.br +2 -0
  39. package/build/client/_app/immutable/entry/start.BqlKjodc.js.gz +0 -0
  40. package/build/client/_app/immutable/nodes/{0.BVv0ZVNF.js → 0.CN5KvOdW.js} +1 -1
  41. package/build/client/_app/immutable/nodes/0.CN5KvOdW.js.br +0 -0
  42. package/build/client/_app/immutable/nodes/0.CN5KvOdW.js.gz +0 -0
  43. package/build/client/_app/immutable/nodes/{1.BocieXSV.js → 1.B9DiMnGP.js} +1 -1
  44. package/build/client/_app/immutable/nodes/1.B9DiMnGP.js.br +0 -0
  45. package/build/client/_app/immutable/nodes/1.B9DiMnGP.js.gz +0 -0
  46. package/build/client/_app/immutable/nodes/{15.CSwvVdKE.js → 15.DVTjsvsv.js} +1 -1
  47. package/build/client/_app/immutable/nodes/15.DVTjsvsv.js.br +0 -0
  48. package/build/client/_app/immutable/nodes/15.DVTjsvsv.js.gz +0 -0
  49. package/build/client/_app/immutable/nodes/2.Be6ngYER.js +35 -0
  50. package/build/client/_app/immutable/nodes/2.Be6ngYER.js.br +0 -0
  51. package/build/client/_app/immutable/nodes/2.Be6ngYER.js.gz +0 -0
  52. package/build/client/_app/immutable/nodes/{3.Ck1xHlrV.js → 3.CyJzwuPu.js} +1 -1
  53. package/build/client/_app/immutable/nodes/3.CyJzwuPu.js.br +0 -0
  54. package/build/client/_app/immutable/nodes/3.CyJzwuPu.js.gz +0 -0
  55. package/build/client/_app/immutable/nodes/{4.ChQxJfCA.js → 4.Ln69Bcug.js} +1 -1
  56. package/build/client/_app/immutable/nodes/4.Ln69Bcug.js.br +0 -0
  57. package/build/client/_app/immutable/nodes/4.Ln69Bcug.js.gz +0 -0
  58. package/build/client/_app/immutable/nodes/{5.zSWDxriP.js → 5.CvOWF9PV.js} +1 -1
  59. package/build/client/_app/immutable/nodes/5.CvOWF9PV.js.br +0 -0
  60. package/build/client/_app/immutable/nodes/5.CvOWF9PV.js.gz +0 -0
  61. package/build/client/_app/immutable/nodes/8.W_hIdUQV.js +2 -0
  62. package/build/client/_app/immutable/nodes/8.W_hIdUQV.js.br +0 -0
  63. package/build/client/_app/immutable/nodes/8.W_hIdUQV.js.gz +0 -0
  64. package/build/client/_app/immutable/nodes/{9.DRayViio.js → 9.DBodeuqK.js} +1 -1
  65. package/build/client/_app/immutable/nodes/9.DBodeuqK.js.br +0 -0
  66. package/build/client/_app/immutable/nodes/9.DBodeuqK.js.gz +0 -0
  67. package/build/client/_app/version.json +1 -1
  68. package/build/client/_app/version.json.br +0 -0
  69. package/build/client/_app/version.json.gz +0 -0
  70. package/build/server/chunks/{0-DWCTA9UP.js → 0-DRboob7o.js} +3 -3
  71. package/build/server/chunks/{0-DWCTA9UP.js.map → 0-DRboob7o.js.map} +1 -1
  72. package/build/server/chunks/{1-BQuoNKyB.js → 1-CN0hcf5T.js} +2 -2
  73. package/build/server/chunks/{1-BQuoNKyB.js.map → 1-CN0hcf5T.js.map} +1 -1
  74. package/build/server/chunks/{15-A9aJ00Nj.js → 15-BglDKcWD.js} +3 -3
  75. package/build/server/chunks/{15-A9aJ00Nj.js.map → 15-BglDKcWD.js.map} +1 -1
  76. package/build/server/chunks/{2-Dxx2KPQl.js → 2-BJlFzksb.js} +3 -3
  77. package/build/server/chunks/{2-Dxx2KPQl.js.map → 2-BJlFzksb.js.map} +1 -1
  78. package/build/server/chunks/{3-B1_UzEKm.js → 3-CyyHUkrh.js} +3 -3
  79. package/build/server/chunks/{3-B1_UzEKm.js.map → 3-CyyHUkrh.js.map} +1 -1
  80. package/build/server/chunks/{4-CDrszL6M.js → 4-C6AwWXAp.js} +3 -3
  81. package/build/server/chunks/{4-CDrszL6M.js.map → 4-C6AwWXAp.js.map} +1 -1
  82. package/build/server/chunks/5-BECI2rwz.js +9 -0
  83. package/build/server/chunks/{5-BZLccXTR.js.map → 5-BECI2rwz.js.map} +1 -1
  84. package/build/server/chunks/{8-DKi0Ar-v.js → 8-CFQq9WtG.js} +3 -3
  85. package/build/server/chunks/{8-DKi0Ar-v.js.map → 8-CFQq9WtG.js.map} +1 -1
  86. package/build/server/chunks/{9-Bm1zqhnj.js → 9-CC9KFXZB.js} +2 -2
  87. package/build/server/chunks/{9-Bm1zqhnj.js.map → 9-CC9KFXZB.js.map} +1 -1
  88. package/build/server/chunks/{AgentSidebar-DUAwX8yz.js → AgentSidebar-BHphbGfv.js} +2 -2
  89. package/build/server/chunks/{AgentSidebar-DUAwX8yz.js.map → AgentSidebar-BHphbGfv.js.map} +1 -1
  90. package/build/server/chunks/{ChatStepTrace-BraUG8oN.js → ChatStepTrace-Dy9ryvqZ.js} +18 -5
  91. package/build/server/chunks/ChatStepTrace-Dy9ryvqZ.js.map +1 -0
  92. package/build/server/chunks/{Icon-zMNuTF_-.js → Icon-C98HpfFT.js} +5 -1
  93. package/build/server/chunks/Icon-C98HpfFT.js.map +1 -0
  94. package/build/server/chunks/{_layout.svelte-D7OHpm3Z.js → _layout.svelte-BoUClC-X.js} +3 -3
  95. package/build/server/chunks/{_layout.svelte-D7OHpm3Z.js.map → _layout.svelte-BoUClC-X.js.map} +1 -1
  96. package/build/server/chunks/{_layout.svelte-DccBBHFo.js → _layout.svelte-DfPEqRLq.js} +22 -4
  97. package/build/server/chunks/_layout.svelte-DfPEqRLq.js.map +1 -0
  98. package/build/server/chunks/{_page.svelte-87WiaCHD.js → _page.svelte-CBh9OOQz.js} +3 -3
  99. package/build/server/chunks/{_page.svelte-87WiaCHD.js.map → _page.svelte-CBh9OOQz.js.map} +1 -1
  100. package/build/server/chunks/{_page.svelte-Ct157UWV.js → _page.svelte-DR3jiCLg.js} +3 -3
  101. package/build/server/chunks/{_page.svelte-Ct157UWV.js.map → _page.svelte-DR3jiCLg.js.map} +1 -1
  102. package/build/server/chunks/{_page.svelte-BRsvOt3E.js → _page.svelte-Dl2WmUCF.js} +3 -3
  103. package/build/server/chunks/{_page.svelte-BRsvOt3E.js.map → _page.svelte-Dl2WmUCF.js.map} +1 -1
  104. package/build/server/chunks/{_page.svelte-CaMij-Vg.js → _page.svelte-mAhccGhM.js} +384 -94
  105. package/build/server/chunks/_page.svelte-mAhccGhM.js.map +1 -0
  106. package/build/server/index.js +1 -1
  107. package/build/server/index.js.map +1 -1
  108. package/build/server/manifest.js +10 -10
  109. package/build/server/manifest.js.map +1 -1
  110. package/package.json +1 -1
  111. package/src/backend/lib/get-agent-factories.ts +45 -1
  112. package/src/backend/region/router.ts +7 -20
  113. package/src/backend/roleplay/agents.ts +40 -13
  114. package/src/backend/roleplay/router.ts +158 -3
  115. package/src/backend/roleplay/variants.spec.ts +53 -0
  116. package/src/backend/roleplay/variants.ts +325 -0
  117. package/src/backend/tests/analyze.ts +62 -1
  118. package/src/backend/tests/data.ts +97 -84
  119. package/src/backend/tests/router.ts +19 -49
  120. package/src/backend/tests/suite.ts +50 -6
  121. package/build/client/_app/immutable/assets/0.oanZa5fp.css +0 -1
  122. package/build/client/_app/immutable/assets/0.oanZa5fp.css.br +0 -0
  123. package/build/client/_app/immutable/assets/0.oanZa5fp.css.gz +0 -0
  124. package/build/client/_app/immutable/chunks/5mKQEBmA.js.br +0 -0
  125. package/build/client/_app/immutable/chunks/5mKQEBmA.js.gz +0 -0
  126. package/build/client/_app/immutable/chunks/BAbuLHvf.js.br +0 -0
  127. package/build/client/_app/immutable/chunks/BAbuLHvf.js.gz +0 -0
  128. package/build/client/_app/immutable/chunks/BH51oU1k.js +0 -2
  129. package/build/client/_app/immutable/chunks/BH51oU1k.js.br +0 -0
  130. package/build/client/_app/immutable/chunks/BH51oU1k.js.gz +0 -0
  131. package/build/client/_app/immutable/chunks/BPR9ibgw.js.br +0 -0
  132. package/build/client/_app/immutable/chunks/BPR9ibgw.js.gz +0 -0
  133. package/build/client/_app/immutable/chunks/C232NBSx.js.br +0 -0
  134. package/build/client/_app/immutable/chunks/C232NBSx.js.gz +0 -0
  135. package/build/client/_app/immutable/chunks/C9f-9-Wt.js.br +0 -0
  136. package/build/client/_app/immutable/chunks/C9f-9-Wt.js.gz +0 -0
  137. package/build/client/_app/immutable/chunks/CKb0QqXx.js.br +0 -0
  138. package/build/client/_app/immutable/chunks/CKb0QqXx.js.gz +0 -0
  139. package/build/client/_app/immutable/chunks/COR6mdUG.js.br +0 -0
  140. package/build/client/_app/immutable/chunks/COR6mdUG.js.gz +0 -0
  141. package/build/client/_app/immutable/chunks/CXaO9BO2.js.br +0 -0
  142. package/build/client/_app/immutable/chunks/CXaO9BO2.js.gz +0 -0
  143. package/build/client/_app/immutable/chunks/jPRwMprt.js +0 -5
  144. package/build/client/_app/immutable/chunks/jPRwMprt.js.br +0 -0
  145. package/build/client/_app/immutable/chunks/jPRwMprt.js.gz +0 -0
  146. package/build/client/_app/immutable/entry/app.oAXSW36_.js.br +0 -0
  147. package/build/client/_app/immutable/entry/app.oAXSW36_.js.gz +0 -0
  148. package/build/client/_app/immutable/entry/start.C3H3zN_Q.js +0 -1
  149. package/build/client/_app/immutable/entry/start.C3H3zN_Q.js.br +0 -2
  150. package/build/client/_app/immutable/entry/start.C3H3zN_Q.js.gz +0 -0
  151. package/build/client/_app/immutable/nodes/0.BVv0ZVNF.js.br +0 -0
  152. package/build/client/_app/immutable/nodes/0.BVv0ZVNF.js.gz +0 -0
  153. package/build/client/_app/immutable/nodes/1.BocieXSV.js.br +0 -0
  154. package/build/client/_app/immutable/nodes/1.BocieXSV.js.gz +0 -0
  155. package/build/client/_app/immutable/nodes/15.CSwvVdKE.js.br +0 -0
  156. package/build/client/_app/immutable/nodes/15.CSwvVdKE.js.gz +0 -0
  157. package/build/client/_app/immutable/nodes/2.IJ8N1LYx.js +0 -35
  158. package/build/client/_app/immutable/nodes/2.IJ8N1LYx.js.br +0 -0
  159. package/build/client/_app/immutable/nodes/2.IJ8N1LYx.js.gz +0 -0
  160. package/build/client/_app/immutable/nodes/3.Ck1xHlrV.js.br +0 -0
  161. package/build/client/_app/immutable/nodes/3.Ck1xHlrV.js.gz +0 -0
  162. package/build/client/_app/immutable/nodes/4.ChQxJfCA.js.br +0 -0
  163. package/build/client/_app/immutable/nodes/4.ChQxJfCA.js.gz +0 -0
  164. package/build/client/_app/immutable/nodes/5.zSWDxriP.js.br +0 -0
  165. package/build/client/_app/immutable/nodes/5.zSWDxriP.js.gz +0 -0
  166. package/build/client/_app/immutable/nodes/8.B6qN8uAv.js +0 -2
  167. package/build/client/_app/immutable/nodes/8.B6qN8uAv.js.br +0 -0
  168. package/build/client/_app/immutable/nodes/8.B6qN8uAv.js.gz +0 -0
  169. package/build/client/_app/immutable/nodes/9.DRayViio.js.br +0 -0
  170. package/build/client/_app/immutable/nodes/9.DRayViio.js.gz +0 -0
  171. package/build/server/chunks/5-BZLccXTR.js +0 -9
  172. package/build/server/chunks/ChatStepTrace-BraUG8oN.js.map +0 -1
  173. package/build/server/chunks/Icon-zMNuTF_-.js.map +0 -1
  174. package/build/server/chunks/_layout.svelte-DccBBHFo.js.map +0 -1
  175. package/build/server/chunks/_page.svelte-CaMij-Vg.js.map +0 -1
@@ -1,11 +1,11 @@
1
1
  import { B as Button } from './Button-DZYrr6c0.js';
2
2
  import { D as Dropdown } from './Dropdown-Bz9eHilg.js';
3
3
  import { b as attr_class, s as stringify, e as ensure_array_like, a as attr, g as clsx, c as attr_style } from './index2-BuOY2QE4.js';
4
- import { I as Icon } from './Icon-zMNuTF_-.js';
4
+ import { I as Icon } from './Icon-C98HpfFT.js';
5
5
  import { X as escape_html } from './context-zH5kvtGY.js';
6
6
  import { t as trpc } from './trpc-client-Bucti7HD.js';
7
7
  import { g as getEditWorkspaceContext, P as Panel } from './edit-workspace-context-OTOIRCI0.js';
8
- import { C as ChatApiCallTrace, a as ChatConversationalTrace, b as ChatStepTrace } from './ChatStepTrace-BraUG8oN.js';
8
+ import { C as ChatApiCallTrace, a as ChatConversationalTrace, b as ChatStepTrace } from './ChatStepTrace-Dy9ryvqZ.js';
9
9
  import { b as chatContent, i as isApiCallTrace, d as isStepTrace, e as isConversationalTrace, l as logContent } from './log-content.svelte-B3ZvaoLs.js';
10
10
  import { I as Input } from './Input-DZT3Mm_-.js';
11
11
  import '@trpc/client';
@@ -199,45 +199,119 @@ function computeSuggestions(rawQuery, history, limit = 5) {
199
199
  if (!history.length) return [];
200
200
  const trimmedRaw = rawQuery.trim();
201
201
  const trimmedRawLower = trimmedRaw.toLowerCase();
202
- const normalizedQueryExact = normalizePrefixKey(rawQuery, true);
203
- const normalizedQueryPrefix = normalizePrefixKey(rawQuery, false);
204
- if (!normalizedQueryExact) return [];
202
+ const normalizedQuery = normalizeMatchText(rawQuery, false).text;
205
203
  const consumeTrailingSeparators = /\s$/u.test(rawQuery);
204
+ if (!normalizeMatchText(rawQuery, true).text) return [];
206
205
  const matches = [];
207
206
  for (const item of history) {
208
- const normalizedCandidate = normalizePrefixKey(item.text);
209
- if (!normalizedCandidate) continue;
207
+ const normalizedCandidate = normalizeMatchText(item.text);
208
+ if (!normalizedCandidate.text) continue;
210
209
  if (item.text.trim().toLowerCase() === trimmedRawLower) continue;
211
- if (!normalizedCandidate.startsWith(normalizedQueryPrefix)) continue;
212
- const end = prefixEndIndexIgnoringPunctuation(
210
+ const match = findMatch(
211
+ normalizedCandidate,
213
212
  item.text,
214
- normalizedQueryPrefix,
213
+ normalizedQuery,
215
214
  consumeTrailingSeparators
216
- ) ?? rawQuery.length;
217
- matches.push({ item, prefixEndIndex: Math.max(0, Math.min(item.text.length, end)) });
215
+ );
216
+ if (!match) continue;
217
+ matches.push({ item, match });
218
218
  }
219
219
  matches.sort((a, b) => {
220
+ if (a.match.kindRank !== b.match.kindRank) return a.match.kindRank - b.match.kindRank;
221
+ if (a.match.span !== b.match.span) return a.match.span - b.match.span;
222
+ if (a.match.start !== b.match.start) return a.match.start - b.match.start;
220
223
  if (a.item.lastSeen !== b.item.lastSeen) return b.item.lastSeen - a.item.lastSeen;
221
224
  if (a.item.uses !== b.item.uses) return b.item.uses - a.item.uses;
222
225
  return a.item.text.length - b.item.text.length;
223
226
  });
224
- return matches.slice(0, limit).slice().reverse().map((m) => ({
227
+ return matches.slice(0, limit).map((m) => ({
225
228
  text: m.item.text,
226
- prefixEndIndex: m.prefixEndIndex,
227
- segments: buildSegments(m.item.text, [[0, m.prefixEndIndex]])
229
+ prefixEndIndex: m.match.prefixEndIndex,
230
+ segments: buildSegments(m.item.text, m.match.ranges)
228
231
  }));
229
232
  }
230
- function normalizePrefixKey(value, trimEnd = true) {
231
- const lower = value.toLowerCase();
232
- let spaced;
233
+ function normalizeMatchText(value, trimEnd = true) {
234
+ const chars = [];
235
+ const ranges = [];
236
+ for (let i = 0; i < value.length; i++) {
237
+ const token = normalizeChar(value[i]);
238
+ if (token === " ") {
239
+ if (!chars.length) continue;
240
+ const last = chars.length - 1;
241
+ if (chars[last] === " ") {
242
+ ranges[last][1] = i + 1;
243
+ continue;
244
+ }
245
+ }
246
+ chars.push(token);
247
+ ranges.push([i, i + 1]);
248
+ }
249
+ if (trimEnd && chars[chars.length - 1] === " ") {
250
+ chars.pop();
251
+ ranges.pop();
252
+ }
253
+ return { text: chars.join(""), ranges };
254
+ }
255
+ function normalizeChar(ch) {
256
+ if (/\s/u.test(ch)) return " ";
233
257
  try {
234
- spaced = lower.replace(/[\p{P}\p{S}]/gu, " ");
258
+ return /[\p{P}\p{S}]/u.test(ch) ? " " : ch.toLowerCase();
235
259
  } catch {
236
- spaced = lower.replace(/[^a-z0-9\s]/gi, " ");
260
+ return /[^a-z0-9\s]/i.test(ch) ? " " : ch.toLowerCase();
261
+ }
262
+ }
263
+ function findMatch(normalizedCandidate, rawCandidate, normalizedQuery, consumeTrailingSeparators) {
264
+ if (!normalizedCandidate.text) return null;
265
+ if (normalizedCandidate.text.startsWith(normalizedQuery)) {
266
+ const end = prefixEndIndexIgnoringPunctuation(rawCandidate, normalizedQuery, consumeTrailingSeparators) ?? rawCandidate.length;
267
+ const clampedEnd = Math.max(0, Math.min(rawCandidate.length, end));
268
+ return {
269
+ kindRank: 0,
270
+ start: 0,
271
+ span: normalizedQuery.length,
272
+ ranges: [[0, clampedEnd]],
273
+ prefixEndIndex: clampedEnd
274
+ };
237
275
  }
238
- const collapsed = spaced.replace(/\s+/g, " ");
239
- const trimStart = collapsed.replace(/^\s+/u, "");
240
- return trimEnd ? trimStart.replace(/\s+$/u, "") : trimStart;
276
+ const substringIndex = normalizedCandidate.text.indexOf(normalizedQuery);
277
+ if (substringIndex !== -1) {
278
+ return {
279
+ kindRank: getSubstringKindRank(
280
+ normalizedCandidate.text,
281
+ substringIndex,
282
+ normalizedQuery.length
283
+ ),
284
+ start: substringIndex,
285
+ span: normalizedQuery.length,
286
+ ranges: normalizedSliceToRawRanges(
287
+ normalizedCandidate,
288
+ substringIndex,
289
+ substringIndex + normalizedQuery.length
290
+ ),
291
+ prefixEndIndex: rawCandidate.length
292
+ };
293
+ }
294
+ return null;
295
+ }
296
+ function isWordBoundary(value, index) {
297
+ if (index <= 0) return true;
298
+ return value[index - 1] === " ";
299
+ }
300
+ function isWordEndBoundary(value, index) {
301
+ if (index >= value.length) return true;
302
+ return value[index] === " ";
303
+ }
304
+ function getSubstringKindRank(value, start, length) {
305
+ const startsAtBoundary = isWordBoundary(value, start);
306
+ const endsAtBoundary = isWordEndBoundary(value, start + length);
307
+ if (startsAtBoundary && endsAtBoundary) return 1;
308
+ if (startsAtBoundary) return 2;
309
+ return 3;
310
+ }
311
+ function normalizedSliceToRawRanges(normalized, start, end) {
312
+ const clampedStart = Math.max(0, Math.min(normalized.ranges.length, start));
313
+ const clampedEnd = Math.max(clampedStart, Math.min(normalized.ranges.length, end));
314
+ return mergeRanges(normalized.ranges.slice(clampedStart, clampedEnd));
241
315
  }
242
316
  function prefixEndIndexIgnoringPunctuation(candidate, normalizedQuery, consumeTrailingSeparators) {
243
317
  if (!normalizedQuery) return null;
@@ -298,10 +372,11 @@ function prefixEndIndexIgnoringPunctuation(candidate, normalizedQuery, consumeTr
298
372
  return null;
299
373
  }
300
374
  function buildSegments(text, ranges) {
301
- if (!ranges.length) return [{ text, matched: false }];
375
+ const merged = mergeRanges(ranges);
376
+ if (!merged.length) return [{ text, matched: false }];
302
377
  const segments = [];
303
378
  let cursor = 0;
304
- for (const [start, end] of ranges) {
379
+ for (const [start, end] of merged) {
305
380
  if (start > cursor) {
306
381
  segments.push({ text: text.slice(cursor, start), matched: false });
307
382
  }
@@ -313,6 +388,22 @@ function buildSegments(text, ranges) {
313
388
  }
314
389
  return segments.filter((s) => s.text.length > 0);
315
390
  }
391
+ function mergeRanges(ranges) {
392
+ if (!ranges.length) return [];
393
+ const sorted = ranges.map(([start, end]) => [Math.max(0, start), Math.max(0, end)]).filter(([start, end]) => end > start).sort((a, b) => a[0] - b[0] || a[1] - b[1]);
394
+ if (!sorted.length) return [];
395
+ const merged = [[sorted[0][0], sorted[0][1]]];
396
+ for (let i = 1; i < sorted.length; i++) {
397
+ const [start, end] = sorted[i];
398
+ const current = merged[merged.length - 1];
399
+ if (start <= current[1]) {
400
+ current[1] = Math.max(current[1], end);
401
+ continue;
402
+ }
403
+ merged.push([start, end]);
404
+ }
405
+ return merged;
406
+ }
316
407
  function PlaygroundChat($$renderer, $$props) {
317
408
  $$renderer.component(($$renderer2) => {
318
409
  let {
@@ -322,12 +413,21 @@ function PlaygroundChat($$renderer, $$props) {
322
413
  analyzeDisabled = false,
323
414
  onAnalyzeTrace,
324
415
  onRegenerateTrace,
325
- onRevertToState
416
+ onRevertToState,
417
+ onSeeVariants,
418
+ variantSourceTrace = null,
419
+ variantChoices = [],
420
+ variantLoading = false,
421
+ variantApplyingId = null,
422
+ variantError = null,
423
+ onRegenerateVariants,
424
+ onChooseOriginalVariant
326
425
  } = $$props;
327
426
  let text = "";
328
427
  let imageUrlInputValue = "";
329
428
  let inputEl = null;
330
429
  let ghostTextStyle = "";
430
+ let aiGenerating = false;
331
431
  let userHistory = [];
332
432
  let inputFocused = false;
333
433
  let autocompleteDismissed = false;
@@ -341,7 +441,9 @@ function PlaygroundChat($$renderer, $$props) {
341
441
  if (!selectedSuggestion) return "";
342
442
  return selectedSuggestion.text.slice(selectedSuggestion.prefixEndIndex);
343
443
  })();
444
+ const showGenerateAction = (() => !variantSourceTrace && true && text.trim().length === 0)();
344
445
  const dropdownOpen = (() => {
446
+ if (variantSourceTrace) return false;
345
447
  if (!inputFocused) return false;
346
448
  if (autocompleteDismissed) return false;
347
449
  return suggestions.length > 0;
@@ -414,6 +516,9 @@ function PlaygroundChat($$renderer, $$props) {
414
516
  function isRenderableConversationalMessage(trace) {
415
517
  return trace.eventName === "received-message" || trace.eventName === "llm-handler-stream-requested" || trace.eventName === "finished-main-streaming-step" || trace.eventName === "sent-message" || trace.eventName === "transfer-requested";
416
518
  }
519
+ function isVariantEligibleTrace(trace) {
520
+ return !!(agentId && agentId.trim()) && trace.eventName !== "transfer-requested" && (trace.eventName === "finished-main-streaming-step" || trace.eventName === "sent-message");
521
+ }
417
522
  function extractUserText(raw) {
418
523
  const value = String(raw ?? "").trim();
419
524
  if (!value) return "";
@@ -474,6 +579,29 @@ function PlaygroundChat($$renderer, $$props) {
474
579
  return false;
475
580
  });
476
581
  })();
582
+ const lastVariantEligibleTrace = (() => {
583
+ for (let index = renderableEntries.length - 1; index >= 0; index--) {
584
+ const entry = renderableEntries[index];
585
+ if (!isConversationalTrace(entry)) continue;
586
+ if (!isVariantEligibleTrace(entry)) continue;
587
+ return entry;
588
+ }
589
+ return null;
590
+ })();
591
+ const aiResponseContext = (() => {
592
+ const trace = lastVariantEligibleTrace;
593
+ if (!trace) return null;
594
+ try {
595
+ const input = buildAnalyzeTraceInput(trace);
596
+ return {
597
+ model: input.model,
598
+ stringifiedConversation: input.stringifiedConversation,
599
+ response: input.response
600
+ };
601
+ } catch {
602
+ return null;
603
+ }
604
+ })();
477
605
  function findMainStepTraceForConversationTrace(idx) {
478
606
  for (let i = idx - 1; i >= 0; i--) {
479
607
  const entry = chatContent[i];
@@ -540,6 +668,31 @@ function PlaygroundChat($$renderer, $$props) {
540
668
  console.error(e);
541
669
  }
542
670
  }
671
+ async function handleGenerateUserResponse() {
672
+ if (aiGenerating) return;
673
+ const request = aiResponseContext;
674
+ if (!request) return;
675
+ autocompleteDismissed = true;
676
+ selectedSuggestionIndex = null;
677
+ aiGenerating = true;
678
+ try {
679
+ const result = await trpc.agents.generateUserResponse.mutate(request);
680
+ text = result.text;
681
+ autocompleteDismissed = true;
682
+ selectedSuggestionIndex = null;
683
+ requestAnimationFrame(() => {
684
+ try {
685
+ inputEl?.focus();
686
+ inputEl?.setSelectionRange(result.text.length, result.text.length);
687
+ } catch {
688
+ }
689
+ });
690
+ } catch (e) {
691
+ console.error("Failed to generate suggested user response", e);
692
+ } finally {
693
+ aiGenerating = false;
694
+ }
695
+ }
543
696
  let $$settled = true;
544
697
  let $$inner_renderer;
545
698
  function $$render_inner($$renderer3) {
@@ -607,7 +760,12 @@ function PlaygroundChat($$renderer, $$props) {
607
760
  analyzeDisabled,
608
761
  onAnalyze: onAnalyzeTrace ? handleAnalyzeTrace : void 0,
609
762
  onRegenerate: onRegenerateTrace,
610
- onRevert: onRevertToState ? handleRevertTrace : void 0
763
+ onRevert: onRevertToState ? handleRevertTrace : void 0,
764
+ showSeeVariants: !!onSeeVariants && !variantSourceTrace && entry === lastVariantEligibleTrace,
765
+ onSeeVariants,
766
+ variantSelectionState: variantSourceTrace && entry === variantSourceTrace ? "source" : "none",
767
+ onSelectInVariantMode: variantApplyingId === null && variantSourceTrace && entry === variantSourceTrace ? onChooseOriginalVariant : void 0,
768
+ suppressActionRow: !!variantSourceTrace && entry === variantSourceTrace
611
769
  });
612
770
  } else {
613
771
  $$renderer4.push("<!--[!-->");
@@ -624,78 +782,130 @@ function PlaygroundChat($$renderer, $$props) {
624
782
  }
625
783
  $$renderer4.push(`<!--]-->`);
626
784
  }
627
- $$renderer4.push(`<!--]--></div></div>`);
628
- }
629
- $$renderer4.push(`<!--]--></div> <form class="absolute bottom-2 left-2 right-2 z-10 flex gap-2 rounded"><div class="relative flex-1">`);
630
- if (dropdownOpen) {
631
- $$renderer4.push("<!--[-->");
632
- $$renderer4.push(`<div class="absolute bottom-full left-0 right-0 mb-1 max-h-60 overflow-y-auto rounded-lg border border-rc-gray-110 bg-rc-gray-930 shadow-inner-white-soft backdrop-blur-2xl" role="listbox"><!--[-->`);
633
- const each_array_1 = ensure_array_like(suggestions);
634
- for (let idx = 0, $$length = each_array_1.length; idx < $$length; idx++) {
635
- let s = each_array_1[idx];
636
- $$renderer4.push(`<button type="button" role="option"${attr("aria-selected", selectedSuggestionIndex === idx)} tabindex="-1"${attr_class(`w-full select-none border-b border-rc-gray-110 px-3 py-2 text-left font-semibold text-rc-gray-100 last:border-b-0 hover:bg-rc-gray-700/70 ${stringify(selectedSuggestionIndex === idx ? "bg-rc-gray-700/70" : "")}`)}><!--[-->`);
637
- const each_array_2 = ensure_array_like(s.segments);
638
- for (let $$index_1 = 0, $$length2 = each_array_2.length; $$index_1 < $$length2; $$index_1++) {
639
- let seg = each_array_2[$$index_1];
640
- $$renderer4.push(`<span${attr_class(clsx(seg.matched ? "text-rc-green-200" : ""))}>${escape_html(seg.text)}</span>`);
785
+ $$renderer4.push(`<!--]--></div> `);
786
+ if (variantSourceTrace && entry === variantSourceTrace) {
787
+ $$renderer4.push("<!--[-->");
788
+ $$renderer4.push(`<div class="ml-7 mt-2 flex flex-col gap-2">`);
789
+ if (variantLoading) {
790
+ $$renderer4.push("<!--[-->");
791
+ $$renderer4.push(`<div class="rounded-lg border border-rc-green-450 bg-transparent px-3 py-2 text-sm text-rc-gray-300">Generating 9 more variants…</div>`);
792
+ } else {
793
+ $$renderer4.push("<!--[!-->");
794
+ }
795
+ $$renderer4.push(`<!--]--> `);
796
+ if (variantError) {
797
+ $$renderer4.push("<!--[-->");
798
+ $$renderer4.push(`<div class="rounded-lg border border-red-500/70 bg-red-950/20 px-3 py-2 text-sm text-red-200">${escape_html(variantError)}</div>`);
799
+ } else {
800
+ $$renderer4.push("<!--[!-->");
801
+ }
802
+ $$renderer4.push(`<!--]--> <!--[-->`);
803
+ const each_array_1 = ensure_array_like(variantChoices);
804
+ for (let $$index = 0, $$length2 = each_array_1.length; $$index < $$length2; $$index++) {
805
+ let variant = each_array_1[$$index];
806
+ $$renderer4.push(`<button type="button"${attr("disabled", variantApplyingId !== null, true)}${attr_class(`w-full max-w-[83%] cursor-pointer rounded-lg border border-rc-green-450 bg-transparent p-2 pt-1 text-left text-rc-gray-100 backdrop-blur-md transition-colors hover:bg-rc-green-700 focus:outline-none focus-visible:outline-none disabled:cursor-wait disabled:opacity-70 ${stringify(variantApplyingId === variant.id ? "bg-rc-green-700" : "")}`)}><div class="whitespace-pre-line break-words">${escape_html(variant.text)}</div></button>`);
641
807
  }
642
- $$renderer4.push(`<!--]--></button>`);
808
+ $$renderer4.push(`<!--]--></div>`);
809
+ } else {
810
+ $$renderer4.push("<!--[!-->");
643
811
  }
644
812
  $$renderer4.push(`<!--]--></div>`);
645
- } else {
646
- $$renderer4.push("<!--[!-->");
647
813
  }
648
- $$renderer4.push(`<!--]--> `);
649
- Input($$renderer4, {
650
- variant: "chat",
651
- placeholder: "Enter user's message...",
652
- autocomplete: "off",
653
- onfocus: handleInputFocus,
654
- onblur: handleInputBlur,
655
- oninput: handleInput,
656
- onkeydown: handleInputKeydown,
657
- get value() {
658
- return text;
659
- },
660
- set value($$value) {
661
- text = $$value;
662
- $$settled = false;
663
- },
664
- get el() {
665
- return inputEl;
666
- },
667
- set el($$value) {
668
- inputEl = $$value;
669
- $$settled = false;
670
- }
671
- });
672
- $$renderer4.push(`<!----> `);
673
- if (selectedSuggestionIndex !== null && ghostSuffix) {
814
+ $$renderer4.push(`<!--]--></div> `);
815
+ if (variantSourceTrace) {
674
816
  $$renderer4.push("<!--[-->");
675
- $$renderer4.push(`<div class="pointer-events-none absolute inset-0 z-10 overflow-hidden rounded-lg" aria-hidden="true"><div class="whitespace-pre text-rc-gray-400/70"${attr_style(ghostTextStyle)}><span class="invisible">${escape_html(text)}</span><span>${escape_html(ghostSuffix)}</span></div></div>`);
817
+ $$renderer4.push(`<div class="absolute bottom-2 left-2 right-2 z-10 flex items-center gap-3 rounded-lg border border-rc-green-450 bg-rc-gray-930/90 px-3 py-3 font-semibold text-rc-gray-100 shadow-inner-white-soft backdrop-blur-3xl"><span>Choose a variant above to continue</span> <button type="button"${attr("disabled", !onRegenerateVariants || variantLoading || variantApplyingId !== null, true)} class="rounded border-0 bg-transparent px-1 py-0.5 text-rc-gray-300 transition-colors hover:bg-rc-gray-900 hover:text-rc-gray-100 focus:outline-none focus-visible:outline-none disabled:cursor-wait disabled:opacity-50">Regenerate</button> <button type="button" class="rounded border-0 bg-transparent px-1 py-0.5 text-rc-gray-300 transition-colors hover:bg-rc-gray-900 hover:text-rc-gray-100 focus:outline-none focus-visible:outline-none">Cancel</button></div>`);
676
818
  } else {
677
819
  $$renderer4.push("<!--[!-->");
820
+ $$renderer4.push(`<form class="absolute bottom-2 left-2 right-2 z-10 flex gap-2 rounded"><div class="relative flex-1">`);
821
+ if (dropdownOpen) {
822
+ $$renderer4.push("<!--[-->");
823
+ $$renderer4.push(`<div class="absolute bottom-full left-0 right-0 mb-1 max-h-60 overflow-y-auto rounded-lg border border-rc-gray-110 bg-rc-gray-930 shadow-inner-white-soft backdrop-blur-2xl" role="listbox"><!--[-->`);
824
+ const each_array_2 = ensure_array_like(suggestions);
825
+ for (let idx = 0, $$length = each_array_2.length; idx < $$length; idx++) {
826
+ let s = each_array_2[idx];
827
+ $$renderer4.push(`<button type="button" role="option"${attr("aria-selected", selectedSuggestionIndex === idx)} tabindex="-1"${attr_class(`w-full select-none border-b border-rc-gray-110 px-3 py-2 text-left font-semibold text-rc-gray-100 last:border-b-0 hover:bg-rc-gray-700/70 ${stringify(selectedSuggestionIndex === idx ? "bg-rc-gray-700/70" : "")}`)}><!--[-->`);
828
+ const each_array_3 = ensure_array_like(s.segments);
829
+ for (let $$index_2 = 0, $$length2 = each_array_3.length; $$index_2 < $$length2; $$index_2++) {
830
+ let seg = each_array_3[$$index_2];
831
+ $$renderer4.push(`<span${attr_class(clsx(seg.matched ? "text-rc-green-200" : ""))}>${escape_html(seg.text)}</span>`);
832
+ }
833
+ $$renderer4.push(`<!--]--></button>`);
834
+ }
835
+ $$renderer4.push(`<!--]--></div>`);
836
+ } else {
837
+ $$renderer4.push("<!--[!-->");
838
+ }
839
+ $$renderer4.push(`<!--]--> `);
840
+ Input($$renderer4, {
841
+ variant: "chat",
842
+ placeholder: aiGenerating ? "Generating" : "Enter user's message...",
843
+ autocomplete: "off",
844
+ readonly: aiGenerating,
845
+ onfocus: handleInputFocus,
846
+ onblur: handleInputBlur,
847
+ oninput: handleInput,
848
+ onkeydown: handleInputKeydown,
849
+ get value() {
850
+ return text;
851
+ },
852
+ set value($$value) {
853
+ text = $$value;
854
+ $$settled = false;
855
+ },
856
+ get el() {
857
+ return inputEl;
858
+ },
859
+ set el($$value) {
860
+ inputEl = $$value;
861
+ $$settled = false;
862
+ }
863
+ });
864
+ $$renderer4.push(`<!----> `);
865
+ if (selectedSuggestionIndex !== null && ghostSuffix) {
866
+ $$renderer4.push("<!--[-->");
867
+ $$renderer4.push(`<div class="pointer-events-none absolute inset-0 z-10 overflow-hidden rounded-lg" aria-hidden="true"><div class="whitespace-pre text-rc-gray-400/70"${attr_style(ghostTextStyle)}><span class="invisible">${escape_html(text)}</span><span>${escape_html(ghostSuffix)}</span></div></div>`);
868
+ } else {
869
+ $$renderer4.push("<!--[!-->");
870
+ }
871
+ $$renderer4.push(`<!--]--></div> `);
872
+ Button($$renderer4, {
873
+ size: "small",
874
+ variant: "secondary",
875
+ disabled: aiGenerating,
876
+ onclick: () => true,
877
+ children: ($$renderer5) => {
878
+ Icon($$renderer5, { name: "paperclip" });
879
+ },
880
+ $$slots: { default: true }
881
+ });
882
+ $$renderer4.push(`<!----> `);
883
+ Button($$renderer4, {
884
+ size: "small",
885
+ type: showGenerateAction ? "button" : "submit",
886
+ title: showGenerateAction ? "Generate response" : void 0,
887
+ "aria-label": showGenerateAction ? "Generate response" : "Send message",
888
+ disabled: aiGenerating || showGenerateAction && !aiResponseContext,
889
+ onclick: (event) => {
890
+ if (!showGenerateAction) return;
891
+ event.preventDefault();
892
+ void handleGenerateUserResponse();
893
+ },
894
+ children: ($$renderer5) => {
895
+ if (showGenerateAction) {
896
+ $$renderer5.push("<!--[-->");
897
+ Icon($$renderer5, { name: "sparkles" });
898
+ } else {
899
+ $$renderer5.push("<!--[!-->");
900
+ Icon($$renderer5, { name: "send" });
901
+ }
902
+ $$renderer5.push(`<!--]-->`);
903
+ },
904
+ $$slots: { default: true }
905
+ });
906
+ $$renderer4.push(`<!----></form>`);
678
907
  }
679
- $$renderer4.push(`<!--]--></div> `);
680
- Button($$renderer4, {
681
- size: "small",
682
- variant: "secondary",
683
- onclick: () => true,
684
- children: ($$renderer5) => {
685
- Icon($$renderer5, { name: "paperclip" });
686
- },
687
- $$slots: { default: true }
688
- });
689
- $$renderer4.push(`<!----> `);
690
- Button($$renderer4, {
691
- size: "small",
692
- type: "submit",
693
- children: ($$renderer5) => {
694
- Icon($$renderer5, { name: "send" });
695
- },
696
- $$slots: { default: true }
697
- });
698
- $$renderer4.push(`<!----></form>`);
908
+ $$renderer4.push(`<!--]-->`);
699
909
  }
700
910
  });
701
911
  $$renderer3.push(`<!---->`);
@@ -712,6 +922,7 @@ function _page($$renderer, $$props) {
712
922
  $$renderer.component(($$renderer2) => {
713
923
  const { state: workspace, actions } = getEditWorkspaceContext();
714
924
  let analyzeRunning = false;
925
+ let variantMode = null;
715
926
  let copied = null;
716
927
  let copyTimer = null;
717
928
  let copyMenuOpen = false;
@@ -818,6 +1029,7 @@ function _page($$renderer, $$props) {
818
1029
  }
819
1030
  }
820
1031
  function handleNewChat() {
1032
+ clearVariantMode();
821
1033
  actions.closePopover();
822
1034
  actions.closeContextPopover();
823
1035
  actions.selectState(null);
@@ -834,6 +1046,7 @@ function _page($$renderer, $$props) {
834
1046
  return { text: trimmed };
835
1047
  }
836
1048
  function handleRegenerateTrace(trace) {
1049
+ clearVariantMode();
837
1050
  const rawPrevStateId = trace?.bosunPrevStateId;
838
1051
  const prevStateId = typeof rawPrevStateId === "string" && rawPrevStateId.trim() ? rawPrevStateId : null;
839
1052
  const rawUserMessage = typeof trace?.bosunUserMessage === "string" && trace.bosunUserMessage || null;
@@ -853,6 +1066,75 @@ function _page($$renderer, $$props) {
853
1066
  imageUrl: message.imageUrl
854
1067
  });
855
1068
  }
1069
+ function clearVariantMode() {
1070
+ variantMode = null;
1071
+ }
1072
+ function currentVariantPromptUpdate() {
1073
+ const stepName = workspace.currentStep?.name?.trim();
1074
+ if (!stepName) return null;
1075
+ const prompt = workspace.promptDrafts[stepName];
1076
+ if (typeof prompt !== "string") return null;
1077
+ return { step: stepName, prompt };
1078
+ }
1079
+ function rawUserMessageForTrace(trace) {
1080
+ const rawUserMessage = typeof trace?.bosunUserMessage === "string" ? trace.bosunUserMessage : null;
1081
+ if (rawUserMessage && rawUserMessage.trim()) return rawUserMessage;
1082
+ const traceStateId = trace?.bosunStateId;
1083
+ if (typeof traceStateId !== "string" || !traceStateId.trim()) return null;
1084
+ const state = workspace.agentStates.find((entry) => entry.id === traceStateId);
1085
+ const candidate = typeof state?.userMessage === "string" ? state.userMessage.trim() : "";
1086
+ return candidate || null;
1087
+ }
1088
+ async function requestVariants(trace) {
1089
+ const targetStateId = typeof trace?.bosunStateId === "string" && trace.bosunStateId.trim() ? trace.bosunStateId.trim() : null;
1090
+ if (!workspace.agentId || !targetStateId) return;
1091
+ const rawUserMessage = rawUserMessageForTrace(trace);
1092
+ if (!rawUserMessage) return;
1093
+ const prevStateId = typeof trace?.bosunPrevStateId === "string" && trace.bosunPrevStateId.trim() ? trace.bosunPrevStateId.trim() : null;
1094
+ const promptUpdate = currentVariantPromptUpdate();
1095
+ await actions.flushPromptSave();
1096
+ variantMode = {
1097
+ sourceTrace: trace,
1098
+ targetStateId,
1099
+ choices: [],
1100
+ loading: true,
1101
+ applyingId: null,
1102
+ error: null
1103
+ };
1104
+ try {
1105
+ const choices = await trpc.agents.generateVariants.mutate({
1106
+ agentId: workspace.agentId,
1107
+ region: workspace.region,
1108
+ prevStateId,
1109
+ rawUserMessage,
1110
+ context: workspace.context,
1111
+ promptUpdate,
1112
+ count: 9
1113
+ });
1114
+ if (!variantMode || variantMode.sourceTrace !== trace || variantMode.targetStateId !== targetStateId) return;
1115
+ variantMode = { ...variantMode, choices, loading: false, error: null };
1116
+ } catch (error) {
1117
+ console.error("Failed to generate variants", error);
1118
+ if (!variantMode || variantMode.sourceTrace !== trace || variantMode.targetStateId !== targetStateId) return;
1119
+ variantMode = {
1120
+ ...variantMode,
1121
+ choices: [],
1122
+ loading: false,
1123
+ error: typeof error?.message === "string" ? error.message : "Failed to generate variants"
1124
+ };
1125
+ }
1126
+ }
1127
+ function handleSeeVariants(trace) {
1128
+ void requestVariants(trace);
1129
+ }
1130
+ function handleRegenerateVariants() {
1131
+ const sourceTrace = variantMode?.sourceTrace;
1132
+ if (!sourceTrace) return;
1133
+ void requestVariants(sourceTrace);
1134
+ }
1135
+ function handleChooseOriginalVariant() {
1136
+ clearVariantMode();
1137
+ }
856
1138
  let $$settled = true;
857
1139
  let $$inner_renderer;
858
1140
  function $$render_inner($$renderer3) {
@@ -1002,7 +1284,7 @@ function _page($$renderer, $$props) {
1002
1284
  $$slots: { default: true }
1003
1285
  });
1004
1286
  $$renderer3.push(`<!----></div></div> <div class="min-h-0 flex-1">`);
1005
- if (!workspace.wsLoaded) {
1287
+ if (!workspace.wsLoaded || !workspace.chatReady) {
1006
1288
  $$renderer3.push("<!--[-->");
1007
1289
  $$renderer3.push(`<div class="flex h-full items-center justify-center text-sm text-rc-gray-300">Connecting…</div>`);
1008
1290
  } else {
@@ -1020,7 +1302,15 @@ function _page($$renderer, $$props) {
1020
1302
  analyzeDisabled: analyzeRunning,
1021
1303
  onAnalyzeTrace: handleAnalyzeTrace,
1022
1304
  onRegenerateTrace: handleRegenerateTrace,
1023
- onRevertToState: (stateId) => actions.selectState(stateId)
1305
+ onRevertToState: (stateId) => actions.selectState(stateId),
1306
+ onSeeVariants: handleSeeVariants,
1307
+ variantSourceTrace: variantMode?.sourceTrace ?? null,
1308
+ variantChoices: variantMode?.choices ?? [],
1309
+ variantLoading: variantMode?.loading ?? false,
1310
+ variantApplyingId: variantMode?.applyingId ?? null,
1311
+ variantError: variantMode?.error ?? null,
1312
+ onRegenerateVariants: handleRegenerateVariants,
1313
+ onChooseOriginalVariant: handleChooseOriginalVariant
1024
1314
  });
1025
1315
  $$renderer3.push(`<!----></div>`);
1026
1316
  }
@@ -1038,4 +1328,4 @@ function _page($$renderer, $$props) {
1038
1328
  }
1039
1329
 
1040
1330
  export { _page as default };
1041
- //# sourceMappingURL=_page.svelte-CaMij-Vg.js.map
1331
+ //# sourceMappingURL=_page.svelte-mAhccGhM.js.map