@surf-kit/agent 0.2.1 → 0.3.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 (65) hide show
  1. package/LICENSE +184 -12
  2. package/README.md +1 -1
  3. package/dist/agent-identity/index.cjs +1 -0
  4. package/dist/agent-identity/index.cjs.map +1 -1
  5. package/dist/agent-identity/index.js +2 -0
  6. package/dist/agent-identity/index.js.map +1 -1
  7. package/dist/chat/index.cjs +626 -204
  8. package/dist/chat/index.cjs.map +1 -1
  9. package/dist/chat/index.d.cts +11 -6
  10. package/dist/chat/index.d.ts +11 -6
  11. package/dist/chat/index.js +608 -185
  12. package/dist/chat/index.js.map +1 -1
  13. package/dist/{chat--OifhIRe.d.ts → chat-BIIDOGrD.d.ts} +10 -1
  14. package/dist/{chat-ChYl2XjV.d.cts → chat-CGamM7Mz.d.cts} +10 -1
  15. package/dist/confidence/index.cjs +1 -0
  16. package/dist/confidence/index.cjs.map +1 -1
  17. package/dist/confidence/index.js +2 -0
  18. package/dist/confidence/index.js.map +1 -1
  19. package/dist/feedback/index.cjs +1 -0
  20. package/dist/feedback/index.cjs.map +1 -1
  21. package/dist/feedback/index.js +2 -0
  22. package/dist/feedback/index.js.map +1 -1
  23. package/dist/{hooks-DLfF18IU.d.cts → hooks-B1NYoLLs.d.cts} +21 -5
  24. package/dist/{hooks-BGs8-4GK.d.ts → hooks-CTeEqnBQ.d.ts} +21 -5
  25. package/dist/hooks.cjs +127 -81
  26. package/dist/hooks.cjs.map +1 -1
  27. package/dist/hooks.d.cts +3 -3
  28. package/dist/hooks.d.ts +3 -3
  29. package/dist/hooks.js +128 -81
  30. package/dist/hooks.js.map +1 -1
  31. package/dist/index.cjs +687 -265
  32. package/dist/index.cjs.map +1 -1
  33. package/dist/index.d.cts +3 -3
  34. package/dist/index.d.ts +3 -3
  35. package/dist/index.js +647 -224
  36. package/dist/index.js.map +1 -1
  37. package/dist/layouts/index.cjs +647 -225
  38. package/dist/layouts/index.cjs.map +1 -1
  39. package/dist/layouts/index.d.cts +1 -1
  40. package/dist/layouts/index.d.ts +1 -1
  41. package/dist/layouts/index.js +624 -201
  42. package/dist/layouts/index.js.map +1 -1
  43. package/dist/mcp/index.cjs +2 -1
  44. package/dist/mcp/index.cjs.map +1 -1
  45. package/dist/mcp/index.js +4 -2
  46. package/dist/mcp/index.js.map +1 -1
  47. package/dist/response/index.cjs +67 -12
  48. package/dist/response/index.cjs.map +1 -1
  49. package/dist/response/index.d.cts +2 -2
  50. package/dist/response/index.d.ts +2 -2
  51. package/dist/response/index.js +66 -10
  52. package/dist/response/index.js.map +1 -1
  53. package/dist/sources/index.cjs +31 -1
  54. package/dist/sources/index.cjs.map +1 -1
  55. package/dist/sources/index.js +32 -1
  56. package/dist/sources/index.js.map +1 -1
  57. package/dist/streaming/index.cjs +203 -93
  58. package/dist/streaming/index.cjs.map +1 -1
  59. package/dist/streaming/index.d.cts +4 -3
  60. package/dist/streaming/index.d.ts +4 -3
  61. package/dist/streaming/index.js +174 -73
  62. package/dist/streaming/index.js.map +1 -1
  63. package/dist/{streaming-DbQxScpi.d.ts → streaming-Bx-ff2tt.d.ts} +1 -1
  64. package/dist/{streaming-DfT22A0z.d.cts → streaming-x7umFHoP.d.cts} +1 -1
  65. package/package.json +17 -6
@@ -1,7 +1,10 @@
1
+ 'use client';
1
2
  "use strict";
3
+ var __create = Object.create;
2
4
  var __defProp = Object.defineProperty;
3
5
  var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
4
6
  var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
5
8
  var __hasOwnProp = Object.prototype.hasOwnProperty;
6
9
  var __export = (target, all) => {
7
10
  for (var name in all)
@@ -15,6 +18,14 @@ var __copyProps = (to, from, except, desc) => {
15
18
  }
16
19
  return to;
17
20
  };
21
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
22
+ // If the importer is in node compatibility mode or this is not an ESM
23
+ // file that has been converted to a CommonJS file using a Babel-
24
+ // compatible transform (i.e. "__esModule" has not been set), then set
25
+ // "default" to the CommonJS "module.exports" for node compatibility.
26
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
27
+ mod
28
+ ));
18
29
  var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
19
30
 
20
31
  // src/streaming/index.ts
@@ -34,7 +45,8 @@ __export(streaming_exports, {
34
45
  module.exports = __toCommonJS(streaming_exports);
35
46
 
36
47
  // src/streaming/StreamingMessage/StreamingMessage.tsx
37
- var import_react2 = require("react");
48
+ var import_react3 = require("react");
49
+ var import_tailwind_merge2 = require("tailwind-merge");
38
50
  var import_core = require("@surf-kit/core");
39
51
 
40
52
  // src/hooks/useCharacterDrain.ts
@@ -64,7 +76,10 @@ function useCharacterDrain(target, msPerChar = 15) {
64
76
  const elapsed = now - lastTimeRef.current;
65
77
  const charsToAdvance = Math.floor(elapsed / msPerCharRef.current);
66
78
  if (charsToAdvance > 0 && indexRef.current < currentTarget.length) {
67
- const nextIndex = Math.min(indexRef.current + charsToAdvance, currentTarget.length);
79
+ let nextIndex = Math.min(indexRef.current + charsToAdvance, currentTarget.length);
80
+ while (nextIndex < currentTarget.length && currentTarget[nextIndex - 1].trim() === "") {
81
+ nextIndex++;
82
+ }
68
83
  indexRef.current = nextIndex;
69
84
  lastTimeRef.current = now;
70
85
  setDisplayed(currentTarget.slice(0, nextIndex));
@@ -99,8 +114,77 @@ function useCharacterDrain(target, msPerChar = 15) {
99
114
  return { displayed, isDraining };
100
115
  }
101
116
 
102
- // src/streaming/StreamingMessage/StreamingMessage.tsx
117
+ // src/response/ResponseMessage/ResponseMessage.tsx
118
+ var import_react2 = __toESM(require("react"), 1);
119
+ var import_react_markdown = __toESM(require("react-markdown"), 1);
120
+ var import_rehype_sanitize = __toESM(require("rehype-sanitize"), 1);
121
+ var import_tailwind_merge = require("tailwind-merge");
103
122
  var import_jsx_runtime = require("react/jsx-runtime");
123
+ function normalizeMarkdownLists(content) {
124
+ return content.replace(/:\s+-\s+/g, ":\n\n- ");
125
+ }
126
+ function ResponseMessage({ content, className }) {
127
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
128
+ "div",
129
+ {
130
+ className: (0, import_tailwind_merge.twMerge)(
131
+ "text-sm leading-relaxed text-text-primary",
132
+ "[&_p]:my-2",
133
+ "[&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-6",
134
+ "[&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-6",
135
+ "[&_li]:my-1",
136
+ "[&_strong]:text-text-primary [&_strong]:font-semibold",
137
+ "[&_em]:text-text-secondary",
138
+ "[&_h1]:text-lg [&_h1]:font-semibold [&_h1]:text-text-primary [&_h1]:mt-4 [&_h1]:mb-2",
139
+ "[&_h2]:text-base [&_h2]:font-semibold [&_h2]:text-text-primary [&_h2]:mt-3 [&_h2]:mb-1.5",
140
+ "[&_h3]:text-sm [&_h3]:font-semibold [&_h3]:text-accent [&_h3]:mt-2 [&_h3]:mb-1",
141
+ "[&_code]:bg-surface-raised [&_code]:text-accent [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-xs [&_code]:font-mono",
142
+ "[&_pre]:bg-surface-raised [&_pre]:border [&_pre]:border-border [&_pre]:rounded-xl [&_pre]:p-4 [&_pre]:overflow-x-auto",
143
+ "[&_hr]:my-3 [&_hr]:border-border",
144
+ "[&_blockquote]:border-l-2 [&_blockquote]:border-border-strong [&_blockquote]:pl-4 [&_blockquote]:text-text-secondary",
145
+ "[&_a]:text-accent [&_a]:underline-offset-2 [&_a]:hover:text-accent/80",
146
+ className
147
+ ),
148
+ "data-testid": "response-message",
149
+ children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
150
+ import_react_markdown.default,
151
+ {
152
+ rehypePlugins: [import_rehype_sanitize.default],
153
+ components: {
154
+ script: () => null,
155
+ iframe: () => null,
156
+ p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: "my-2", children }),
157
+ ul: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ul", { className: "my-2 list-disc pl-6", children }),
158
+ ol: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("ol", { className: "my-2 list-decimal pl-6", children }),
159
+ li: ({ children, ...props }) => {
160
+ let content2 = children;
161
+ if (props.ordered) {
162
+ content2 = import_react2.default.Children.map(children, (child, i) => {
163
+ if (i === 0 && typeof child === "string") {
164
+ return child.replace(/^\d+[.)]\s*/, "");
165
+ }
166
+ return child;
167
+ });
168
+ }
169
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)("li", { className: "my-1", children: content2 });
170
+ },
171
+ strong: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { className: "font-semibold", children }),
172
+ em: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("em", { className: "italic text-text-secondary", children }),
173
+ h1: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h1", { className: "text-base font-bold mt-4 mb-2", children }),
174
+ h2: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-sm font-bold mt-3 mb-1", children }),
175
+ h3: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-sm font-semibold mt-2 mb-1", children }),
176
+ hr: () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { className: "my-3 border-border" }),
177
+ code: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children })
178
+ },
179
+ children: normalizeMarkdownLists(content)
180
+ }
181
+ )
182
+ }
183
+ );
184
+ }
185
+
186
+ // src/streaming/StreamingMessage/StreamingMessage.tsx
187
+ var import_jsx_runtime2 = require("react/jsx-runtime");
104
188
  var phaseLabels = {
105
189
  idle: "",
106
190
  waiting: "Waiting...",
@@ -109,72 +193,98 @@ var phaseLabels = {
109
193
  generating: "Writing...",
110
194
  verifying: "Verifying..."
111
195
  };
196
+ var CURSOR_STYLES = `
197
+ .sk-streaming-cursor > :not(ul,ol,blockquote):last-child::after,
198
+ .sk-streaming-cursor > :is(ul,ol):last-child > li:last-child::after,
199
+ .sk-streaming-cursor > blockquote:last-child > p:last-child::after {
200
+ content: "";
201
+ display: inline-block;
202
+ width: 2px;
203
+ height: 1em;
204
+ background: var(--color-accent, #38bdf8);
205
+ animation: sk-cursor-blink 0.8s steps(1) infinite;
206
+ margin-left: 2px;
207
+ vertical-align: text-bottom;
208
+ }
209
+ @keyframes sk-cursor-blink {
210
+ 0%, 60% { opacity: 1; }
211
+ 61%, 100% { opacity: 0; }
212
+ }
213
+ `;
112
214
  function StreamingMessage({
113
215
  stream,
114
216
  onComplete,
217
+ onDraining,
115
218
  showPhases = true,
116
219
  className
117
220
  }) {
118
- const onCompleteRef = (0, import_react2.useRef)(onComplete);
221
+ const onCompleteRef = (0, import_react3.useRef)(onComplete);
119
222
  onCompleteRef.current = onComplete;
120
- const wasActiveRef = (0, import_react2.useRef)(stream.active);
121
- (0, import_react2.useEffect)(() => {
223
+ const onDrainingRef = (0, import_react3.useRef)(onDraining);
224
+ onDrainingRef.current = onDraining;
225
+ const wasActiveRef = (0, import_react3.useRef)(stream.active);
226
+ (0, import_react3.useEffect)(() => {
122
227
  if (wasActiveRef.current && !stream.active) {
123
228
  onCompleteRef.current?.();
124
229
  }
125
230
  wasActiveRef.current = stream.active;
126
231
  }, [stream.active]);
127
232
  const phaseLabel = phaseLabels[stream.phase];
128
- const { displayed: displayedContent } = useCharacterDrain(stream.content);
129
- return /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className, "data-testid": "streaming-message", children: [
130
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { "aria-live": "assertive", className: "sr-only", children: [
233
+ const { displayed: rawDisplayed, isDraining } = useCharacterDrain(stream.content);
234
+ const displayedContent = stream.active || isDraining ? rawDisplayed.trimEnd() : rawDisplayed;
235
+ (0, import_react3.useEffect)(() => {
236
+ onDrainingRef.current?.(isDraining);
237
+ }, [isDraining]);
238
+ const agentLabel = stream.agent ? stream.agent.replace("_agent", "").replace("_", " ") : null;
239
+ const showPhaseIndicator = showPhases && stream.active && stream.phase !== "idle" && !displayedContent;
240
+ const showCursor = (stream.active || isDraining) && !!displayedContent;
241
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: (0, import_tailwind_merge2.twMerge)("flex w-full flex-col items-start", className), "data-testid": "streaming-message", children: [
242
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { "aria-live": "assertive", className: "sr-only", children: [
131
243
  stream.active && stream.phase !== "idle" && "Response started",
132
244
  !stream.active && stream.content && "Response complete"
133
245
  ] }),
134
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "max-w-[88%] px-4 py-3 rounded-[18px] rounded-tl-[4px] bg-surface border border-border motion-safe:animate-springFromLeft", children: [
135
- showPhases && stream.active && stream.phase !== "idle" && /* @__PURE__ */ (0, import_jsx_runtime.jsxs)(
246
+ showCursor && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("style", { children: CURSOR_STYLES }),
247
+ agentLabel && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("div", { className: "text-[11px] font-display font-semibold uppercase tracking-[0.08em] text-text-muted px-1 mb-1.5", children: agentLabel }),
248
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: "max-w-[88%] px-4 py-3 rounded-[18px] rounded-tl-[4px] bg-surface border border-border motion-safe:animate-springFromLeft", children: [
249
+ showPhaseIndicator && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
136
250
  "div",
137
251
  {
138
- className: "flex items-center gap-2 mb-2 text-sm text-text-secondary",
252
+ className: "flex items-center gap-2 text-sm text-text-secondary",
139
253
  "data-testid": "phase-indicator",
140
254
  children: [
141
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(import_core.Spinner, { size: "sm" }) }),
142
- /* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { children: phaseLabel })
255
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_core.WaveLoader, { size: "sm", color: "#38bdf8" }) }),
256
+ /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { children: phaseLabel })
143
257
  ]
144
258
  }
145
259
  ),
146
- /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: "text-sm leading-relaxed text-text-primary whitespace-pre-wrap", children: [
147
- displayedContent,
148
- stream.active && /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
149
- "span",
150
- {
151
- className: "inline-block w-0.5 h-4 bg-accent align-text-bottom animate-pulse ml-0.5",
152
- "aria-hidden": "true",
153
- "data-testid": "streaming-cursor"
154
- }
155
- )
156
- ] })
260
+ displayedContent && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
261
+ ResponseMessage,
262
+ {
263
+ content: displayedContent,
264
+ className: showCursor ? "sk-streaming-cursor" : void 0
265
+ }
266
+ )
157
267
  ] })
158
268
  ] });
159
269
  }
160
270
 
161
271
  // src/streaming/ThinkingIndicator/ThinkingIndicator.tsx
162
272
  var import_hooks = require("@surf-kit/hooks");
163
- var import_jsx_runtime2 = require("react/jsx-runtime");
273
+ var import_jsx_runtime3 = require("react/jsx-runtime");
164
274
  function ThinkingIndicator({ label = "Thinking...", className }) {
165
275
  const reducedMotion = (0, import_hooks.useReducedMotion)();
166
- return /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
276
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
167
277
  "span",
168
278
  {
169
279
  role: "status",
170
280
  className: `inline-flex items-center gap-2 text-sm motion-safe:animate-fadeSlideUpSm ${className ?? ""}`,
171
281
  "data-testid": "thinking-indicator",
172
282
  children: [
173
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-text-secondary", children: label }),
174
- !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { className: "flex gap-1", "aria-hidden": "true", "data-testid": "animated-dots", children: [
175
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:0ms]" }),
176
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:150ms]" }),
177
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:300ms]" })
283
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "text-text-secondary", children: label }),
284
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("span", { className: "flex gap-1", "aria-hidden": "true", "data-testid": "animated-dots", children: [
285
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:0ms]" }),
286
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:150ms]" }),
287
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:300ms]" })
178
288
  ] })
179
289
  ]
180
290
  }
@@ -183,7 +293,7 @@ function ThinkingIndicator({ label = "Thinking...", className }) {
183
293
 
184
294
  // src/streaming/ToolExecution/ToolExecution.tsx
185
295
  var import_core2 = require("@surf-kit/core");
186
- var import_jsx_runtime3 = require("react/jsx-runtime");
296
+ var import_jsx_runtime4 = require("react/jsx-runtime");
187
297
  var defaultLabels = {
188
298
  search: "Searching knowledge base...",
189
299
  retrieve: "Retrieving documents...",
@@ -191,15 +301,15 @@ var defaultLabels = {
191
301
  };
192
302
  function ToolExecution({ tool, label, className }) {
193
303
  const displayLabel = label ?? defaultLabels[tool] ?? `Running ${tool}...`;
194
- return /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
304
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
195
305
  "div",
196
306
  {
197
307
  className: `flex items-center gap-2 text-sm text-text-secondary ${className ?? ""}`,
198
308
  role: "status",
199
309
  "data-testid": "tool-execution",
200
310
  children: [
201
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_core2.Spinner, { size: "sm" }) }),
202
- /* @__PURE__ */ (0, import_jsx_runtime3.jsx)("span", { children: displayLabel })
311
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core2.WaveLoader, { size: "sm", color: "#38bdf8" }) }),
312
+ /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: displayLabel })
203
313
  ]
204
314
  }
205
315
  );
@@ -207,9 +317,9 @@ function ToolExecution({ tool, label, className }) {
207
317
 
208
318
  // src/streaming/RetrievalProgress/RetrievalProgress.tsx
209
319
  var import_core3 = require("@surf-kit/core");
210
- var import_jsx_runtime4 = require("react/jsx-runtime");
320
+ var import_jsx_runtime5 = require("react/jsx-runtime");
211
321
  function RetrievalProgress({ sources, isActive, className }) {
212
- return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
322
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
213
323
  "div",
214
324
  {
215
325
  className: `space-y-2 ${className ?? ""}`,
@@ -217,19 +327,19 @@ function RetrievalProgress({ sources, isActive, className }) {
217
327
  "aria-label": isActive ? `Retrieving sources, ${sources.length} found so far` : `${sources.length} sources found`,
218
328
  "data-testid": "retrieval-progress",
219
329
  children: [
220
- isActive && /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: "flex items-center gap-2 text-sm text-text-secondary", children: [
221
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_core3.Spinner, { size: "sm" }) }),
222
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { children: "Retrieving sources..." })
330
+ isActive && /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)("div", { className: "flex items-center gap-2 text-sm text-text-secondary", children: [
331
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { "aria-hidden": "true", children: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_core3.WaveLoader, { size: "sm", color: "#38bdf8" }) }),
332
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { children: "Retrieving sources..." })
223
333
  ] }),
224
- sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("ul", { className: "space-y-1", "data-testid": "source-list", children: sources.map((source, index) => /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(
334
+ sources.length > 0 && /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("ul", { className: "space-y-1", "data-testid": "source-list", children: sources.map((source, index) => /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
225
335
  "li",
226
336
  {
227
337
  className: "text-sm text-text-secondary flex items-center gap-2 animate-in fade-in slide-in-from-left-2",
228
338
  style: { animationDelay: `${index * 100}ms`, animationFillMode: "both" },
229
339
  "data-testid": "retrieval-source-item",
230
340
  children: [
231
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-accent flex-shrink-0", "aria-hidden": "true" }),
232
- /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { className: "truncate", children: source.title })
341
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "w-1.5 h-1.5 rounded-full bg-accent flex-shrink-0", "aria-hidden": "true" }),
342
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate", children: source.title })
233
343
  ]
234
344
  },
235
345
  source.document_id
@@ -240,21 +350,21 @@ function RetrievalProgress({ sources, isActive, className }) {
240
350
  }
241
351
 
242
352
  // src/streaming/VerificationProgress/VerificationProgress.tsx
243
- var import_jsx_runtime5 = require("react/jsx-runtime");
353
+ var import_jsx_runtime6 = require("react/jsx-runtime");
244
354
  function VerificationProgress({
245
355
  isActive,
246
356
  label = "Checking accuracy...",
247
357
  className
248
358
  }) {
249
359
  if (!isActive) return null;
250
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
360
+ return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
251
361
  "div",
252
362
  {
253
363
  className: `flex items-center gap-2 text-sm ${className ?? ""}`,
254
364
  role: "status",
255
365
  "data-testid": "verification-progress",
256
366
  children: [
257
- /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(
367
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)(
258
368
  "svg",
259
369
  {
260
370
  className: "w-4 h-4 animate-spin text-accent",
@@ -263,20 +373,20 @@ function VerificationProgress({
263
373
  viewBox: "0 0 24 24",
264
374
  "aria-hidden": "true",
265
375
  children: [
266
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
267
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
376
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
377
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
268
378
  ]
269
379
  }
270
380
  ),
271
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-accent animate-pulse", children: label })
381
+ /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "text-accent animate-pulse", children: label })
272
382
  ]
273
383
  }
274
384
  );
275
385
  }
276
386
 
277
387
  // src/streaming/TypewriterText/TypewriterText.tsx
278
- var import_react3 = require("react");
279
- var import_jsx_runtime6 = require("react/jsx-runtime");
388
+ var import_react4 = require("react");
389
+ var import_jsx_runtime7 = require("react/jsx-runtime");
280
390
  function TypewriterText({
281
391
  text,
282
392
  speed = 30,
@@ -285,9 +395,9 @@ function TypewriterText({
285
395
  className = "",
286
396
  showCursor = true
287
397
  }) {
288
- const [displayedText, setDisplayedText] = (0, import_react3.useState)("");
289
- const [isComplete, setIsComplete] = (0, import_react3.useState)(false);
290
- (0, import_react3.useEffect)(() => {
398
+ const [displayedText, setDisplayedText] = (0, import_react4.useState)("");
399
+ const [isComplete, setIsComplete] = (0, import_react4.useState)(false);
400
+ (0, import_react4.useEffect)(() => {
291
401
  setDisplayedText("");
292
402
  setIsComplete(false);
293
403
  let index = 0;
@@ -309,16 +419,16 @@ function TypewriterText({
309
419
  clearInterval(interval);
310
420
  };
311
421
  }, [text, speed, delay, onComplete]);
312
- return /* @__PURE__ */ (0, import_jsx_runtime6.jsxs)("span", { className, children: [
422
+ return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className, children: [
313
423
  displayedText,
314
- showCursor && !isComplete && /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("span", { className: "typewriter-cursor", "aria-hidden": "true" })
424
+ showCursor && !isComplete && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "typewriter-cursor", "aria-hidden": "true" })
315
425
  ] });
316
426
  }
317
427
 
318
428
  // src/streaming/TypingIndicator/TypingIndicator.tsx
319
- var import_tailwind_merge = require("tailwind-merge");
429
+ var import_tailwind_merge3 = require("tailwind-merge");
320
430
  var import_hooks2 = require("@surf-kit/hooks");
321
- var import_jsx_runtime7 = require("react/jsx-runtime");
431
+ var import_jsx_runtime8 = require("react/jsx-runtime");
322
432
  var bounceKeyframes = `
323
433
  @keyframes typing-bounce {
324
434
  0%, 80%, 100% { transform: translateY(0); }
@@ -331,17 +441,17 @@ function TypingIndicator({
331
441
  className
332
442
  }) {
333
443
  const reducedMotion = (0, import_hooks2.useReducedMotion)();
334
- return /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(
444
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
335
445
  "span",
336
446
  {
337
447
  role: "status",
338
448
  "aria-label": label ?? "typing",
339
- className: (0, import_tailwind_merge.twMerge)("inline-flex items-center gap-2", className),
449
+ className: (0, import_tailwind_merge3.twMerge)("inline-flex items-center gap-2", className),
340
450
  "data-testid": "typing-indicator",
341
451
  children: [
342
- !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("style", { children: bounceKeyframes }),
343
- label && /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "text-sm text-text-secondary", children: label }),
344
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "flex gap-1", "data-testid": "typing-dots", children: Array.from({ length: dotCount }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
452
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: bounceKeyframes }),
453
+ label && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "text-sm text-text-secondary", children: label }),
454
+ /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("span", { className: "flex gap-1", "data-testid": "typing-dots", children: Array.from({ length: dotCount }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
345
455
  "span",
346
456
  {
347
457
  className: "w-2 h-2 rounded-full bg-text-secondary",
@@ -358,9 +468,9 @@ function TypingIndicator({
358
468
  }
359
469
 
360
470
  // src/streaming/TextGlimmer/TextGlimmer.tsx
361
- var import_tailwind_merge2 = require("tailwind-merge");
471
+ var import_tailwind_merge4 = require("tailwind-merge");
362
472
  var import_hooks3 = require("@surf-kit/hooks");
363
- var import_jsx_runtime8 = require("react/jsx-runtime");
473
+ var import_jsx_runtime9 = require("react/jsx-runtime");
364
474
  var shimmerKeyframes = `
365
475
  @keyframes text-shimmer {
366
476
  0% { background-position: 200% 0; }
@@ -370,16 +480,16 @@ var shimmerKeyframes = `
370
480
  var widthPattern = ["100%", "90%", "60%"];
371
481
  function TextGlimmer({ lines = 3, className }) {
372
482
  const reducedMotion = (0, import_hooks3.useReducedMotion)();
373
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
483
+ return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
374
484
  "div",
375
485
  {
376
486
  role: "status",
377
487
  "aria-label": "Loading",
378
- className: (0, import_tailwind_merge2.twMerge)("flex flex-col gap-2", className),
488
+ className: (0, import_tailwind_merge4.twMerge)("flex flex-col gap-2", className),
379
489
  "data-testid": "text-glimmer",
380
490
  children: [
381
- !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime8.jsx)("style", { children: shimmerKeyframes }),
382
- Array.from({ length: lines }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(
491
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: shimmerKeyframes }),
492
+ Array.from({ length: lines }, (_, i) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
383
493
  "div",
384
494
  {
385
495
  className: "h-3 rounded bg-surface-raised",
@@ -401,9 +511,9 @@ function TextGlimmer({ lines = 3, className }) {
401
511
  }
402
512
 
403
513
  // src/streaming/StreamingList/StreamingList.tsx
404
- var import_tailwind_merge3 = require("tailwind-merge");
514
+ var import_tailwind_merge5 = require("tailwind-merge");
405
515
  var import_hooks4 = require("@surf-kit/hooks");
406
- var import_jsx_runtime9 = require("react/jsx-runtime");
516
+ var import_jsx_runtime10 = require("react/jsx-runtime");
407
517
  var fadeSlideInKeyframes = `
408
518
  @keyframes fadeSlideIn {
409
519
  from { opacity: 0; transform: translateY(8px); }
@@ -419,17 +529,17 @@ function StreamingList({
419
529
  }) {
420
530
  const reducedMotion = (0, import_hooks4.useReducedMotion)();
421
531
  if (items.length === 0 && !isStreaming) {
422
- return emptyMessage ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("p", { className: (0, import_tailwind_merge3.twMerge)("text-sm text-text-secondary", className), "data-testid": "streaming-list-empty", children: emptyMessage }) : null;
532
+ return emptyMessage ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("p", { className: (0, import_tailwind_merge5.twMerge)("text-sm text-text-secondary", className), "data-testid": "streaming-list-empty", children: emptyMessage }) : null;
423
533
  }
424
- return /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
534
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
425
535
  "ul",
426
536
  {
427
537
  "aria-live": "polite",
428
- className: (0, import_tailwind_merge3.twMerge)("list-none p-0 m-0", className),
538
+ className: (0, import_tailwind_merge5.twMerge)("list-none p-0 m-0", className),
429
539
  "data-testid": "streaming-list",
430
540
  children: [
431
- !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("style", { children: fadeSlideInKeyframes }),
432
- items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(
541
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: fadeSlideInKeyframes }),
542
+ items.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
433
543
  "li",
434
544
  {
435
545
  style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
@@ -438,16 +548,16 @@ function StreamingList({
438
548
  },
439
549
  index
440
550
  )),
441
- isStreaming && /* @__PURE__ */ (0, import_jsx_runtime9.jsx)("li", { "data-testid": "streaming-list-loading", children: /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(TypingIndicator, {}) })
551
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("li", { "data-testid": "streaming-list-loading", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TypingIndicator, {}) })
442
552
  ]
443
553
  }
444
554
  );
445
555
  }
446
556
 
447
557
  // src/streaming/StreamingStructure/StreamingStructure.tsx
448
- var import_tailwind_merge4 = require("tailwind-merge");
558
+ var import_tailwind_merge6 = require("tailwind-merge");
449
559
  var import_hooks5 = require("@surf-kit/hooks");
450
- var import_jsx_runtime10 = require("react/jsx-runtime");
560
+ var import_jsx_runtime11 = require("react/jsx-runtime");
451
561
  var fadeSlideInKeyframes2 = `
452
562
  @keyframes fadeSlideIn {
453
563
  from { opacity: 0; transform: translateY(8px); }
@@ -456,13 +566,13 @@ var fadeSlideInKeyframes2 = `
456
566
  `;
457
567
  function renderValue(value, reducedMotion) {
458
568
  if (value === null) {
459
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "italic text-text-secondary", children: "null" });
569
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "italic text-text-secondary", children: "null" });
460
570
  }
461
571
  if (value === void 0) {
462
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "italic text-text-secondary", children: "undefined" });
572
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "italic text-text-secondary", children: "undefined" });
463
573
  }
464
574
  if (Array.isArray(value)) {
465
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("ol", { className: "list-decimal pl-4 m-0", children: value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("li", { className: "text-text-secondary text-sm", children: renderValue(item, reducedMotion) }, i)) });
575
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("ol", { className: "list-decimal pl-4 m-0", children: value.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("li", { className: "text-text-secondary text-sm", children: renderValue(item, reducedMotion) }, i)) });
466
576
  }
467
577
  if (typeof value === "object") {
468
578
  return renderNestedDl(value, reducedMotion);
@@ -471,13 +581,13 @@ function renderValue(value, reducedMotion) {
471
581
  }
472
582
  function renderNestedDl(data, reducedMotion) {
473
583
  const entries = Object.entries(data);
474
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dl", { className: "pl-4 m-0", "data-testid": "streaming-structure-nested", children: entries.map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
584
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dl", { className: "pl-4 m-0", "data-testid": "streaming-structure-nested", children: entries.map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
475
585
  "div",
476
586
  {
477
587
  style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
478
588
  children: [
479
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dt", { className: "font-medium text-text-primary text-sm", children: key }),
480
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
589
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { className: "font-medium text-text-primary text-sm", children: key }),
590
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
481
591
  ]
482
592
  },
483
593
  key
@@ -490,27 +600,27 @@ function StreamingStructure({
490
600
  }) {
491
601
  const reducedMotion = (0, import_hooks5.useReducedMotion)();
492
602
  const entries = Object.entries(data);
493
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
603
+ return /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
494
604
  "dl",
495
605
  {
496
606
  "aria-live": "polite",
497
- className: (0, import_tailwind_merge4.twMerge)("m-0", className),
607
+ className: (0, import_tailwind_merge6.twMerge)("m-0", className),
498
608
  "data-testid": "streaming-structure",
499
609
  children: [
500
- !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("style", { children: fadeSlideInKeyframes2 }),
501
- entries.map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(
610
+ !reducedMotion && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("style", { children: fadeSlideInKeyframes2 }),
611
+ entries.map(([key, value]) => /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(
502
612
  "div",
503
613
  {
504
614
  style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
505
615
  "data-testid": "streaming-structure-entry",
506
616
  children: [
507
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dt", { className: "font-medium text-text-primary text-sm", children: key }),
508
- /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
617
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dt", { className: "font-medium text-text-primary text-sm", children: key }),
618
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
509
619
  ]
510
620
  },
511
621
  key
512
622
  )),
513
- isStreaming && /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("div", { "data-testid": "streaming-structure-loading", children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(TextGlimmer, { lines: 1 }) })
623
+ isStreaming && /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("div", { "data-testid": "streaming-structure-loading", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(TextGlimmer, { lines: 1 }) })
514
624
  ]
515
625
  }
516
626
  );