@surf-kit/agent 0.2.2 → 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.
- package/dist/chat/index.cjs +625 -204
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +11 -6
- package/dist/chat/index.d.ts +11 -6
- package/dist/chat/index.js +606 -185
- package/dist/chat/index.js.map +1 -1
- package/dist/{chat--OifhIRe.d.ts → chat-BIIDOGrD.d.ts} +10 -1
- package/dist/{chat-ChYl2XjV.d.cts → chat-CGamM7Mz.d.cts} +10 -1
- package/dist/{hooks-DLfF18IU.d.cts → hooks-B1NYoLLs.d.cts} +21 -5
- package/dist/{hooks-BGs8-4GK.d.ts → hooks-CTeEqnBQ.d.ts} +21 -5
- package/dist/hooks.cjs +126 -81
- package/dist/hooks.cjs.map +1 -1
- package/dist/hooks.d.cts +3 -3
- package/dist/hooks.d.ts +3 -3
- package/dist/hooks.js +126 -81
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +686 -265
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +645 -224
- package/dist/index.js.map +1 -1
- package/dist/layouts/index.cjs +646 -225
- package/dist/layouts/index.cjs.map +1 -1
- package/dist/layouts/index.d.cts +1 -1
- package/dist/layouts/index.d.ts +1 -1
- package/dist/layouts/index.js +622 -201
- package/dist/layouts/index.js.map +1 -1
- package/dist/mcp/index.cjs +1 -1
- package/dist/mcp/index.cjs.map +1 -1
- package/dist/mcp/index.js +2 -2
- package/dist/mcp/index.js.map +1 -1
- package/dist/response/index.cjs +66 -12
- package/dist/response/index.cjs.map +1 -1
- package/dist/response/index.d.cts +2 -2
- package/dist/response/index.d.ts +2 -2
- package/dist/response/index.js +64 -10
- package/dist/response/index.js.map +1 -1
- package/dist/sources/index.cjs +30 -1
- package/dist/sources/index.cjs.map +1 -1
- package/dist/sources/index.js +30 -1
- package/dist/sources/index.js.map +1 -1
- package/dist/streaming/index.cjs +202 -93
- package/dist/streaming/index.cjs.map +1 -1
- package/dist/streaming/index.d.cts +4 -3
- package/dist/streaming/index.d.ts +4 -3
- package/dist/streaming/index.js +172 -73
- package/dist/streaming/index.js.map +1 -1
- package/dist/{streaming-DbQxScpi.d.ts → streaming-Bx-ff2tt.d.ts} +1 -1
- package/dist/{streaming-DfT22A0z.d.cts → streaming-x7umFHoP.d.cts} +1 -1
- package/package.json +15 -4
package/dist/streaming/index.js
CHANGED
|
@@ -2,7 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
// src/streaming/StreamingMessage/StreamingMessage.tsx
|
|
4
4
|
import { useEffect as useEffect2, useRef as useRef2 } from "react";
|
|
5
|
-
import {
|
|
5
|
+
import { twMerge as twMerge2 } from "tailwind-merge";
|
|
6
|
+
import { WaveLoader } from "@surf-kit/core";
|
|
6
7
|
|
|
7
8
|
// src/hooks/useCharacterDrain.ts
|
|
8
9
|
import { useState, useRef, useEffect } from "react";
|
|
@@ -31,7 +32,10 @@ function useCharacterDrain(target, msPerChar = 15) {
|
|
|
31
32
|
const elapsed = now - lastTimeRef.current;
|
|
32
33
|
const charsToAdvance = Math.floor(elapsed / msPerCharRef.current);
|
|
33
34
|
if (charsToAdvance > 0 && indexRef.current < currentTarget.length) {
|
|
34
|
-
|
|
35
|
+
let nextIndex = Math.min(indexRef.current + charsToAdvance, currentTarget.length);
|
|
36
|
+
while (nextIndex < currentTarget.length && currentTarget[nextIndex - 1].trim() === "") {
|
|
37
|
+
nextIndex++;
|
|
38
|
+
}
|
|
35
39
|
indexRef.current = nextIndex;
|
|
36
40
|
lastTimeRef.current = now;
|
|
37
41
|
setDisplayed(currentTarget.slice(0, nextIndex));
|
|
@@ -66,8 +70,77 @@ function useCharacterDrain(target, msPerChar = 15) {
|
|
|
66
70
|
return { displayed, isDraining };
|
|
67
71
|
}
|
|
68
72
|
|
|
73
|
+
// src/response/ResponseMessage/ResponseMessage.tsx
|
|
74
|
+
import React from "react";
|
|
75
|
+
import ReactMarkdown from "react-markdown";
|
|
76
|
+
import rehypeSanitize from "rehype-sanitize";
|
|
77
|
+
import { twMerge } from "tailwind-merge";
|
|
78
|
+
import { jsx } from "react/jsx-runtime";
|
|
79
|
+
function normalizeMarkdownLists(content) {
|
|
80
|
+
return content.replace(/:\s+-\s+/g, ":\n\n- ");
|
|
81
|
+
}
|
|
82
|
+
function ResponseMessage({ content, className }) {
|
|
83
|
+
return /* @__PURE__ */ jsx(
|
|
84
|
+
"div",
|
|
85
|
+
{
|
|
86
|
+
className: twMerge(
|
|
87
|
+
"text-sm leading-relaxed text-text-primary",
|
|
88
|
+
"[&_p]:my-2",
|
|
89
|
+
"[&_ul]:my-2 [&_ul]:list-disc [&_ul]:pl-6",
|
|
90
|
+
"[&_ol]:my-2 [&_ol]:list-decimal [&_ol]:pl-6",
|
|
91
|
+
"[&_li]:my-1",
|
|
92
|
+
"[&_strong]:text-text-primary [&_strong]:font-semibold",
|
|
93
|
+
"[&_em]:text-text-secondary",
|
|
94
|
+
"[&_h1]:text-lg [&_h1]:font-semibold [&_h1]:text-text-primary [&_h1]:mt-4 [&_h1]:mb-2",
|
|
95
|
+
"[&_h2]:text-base [&_h2]:font-semibold [&_h2]:text-text-primary [&_h2]:mt-3 [&_h2]:mb-1.5",
|
|
96
|
+
"[&_h3]:text-sm [&_h3]:font-semibold [&_h3]:text-accent [&_h3]:mt-2 [&_h3]:mb-1",
|
|
97
|
+
"[&_code]:bg-surface-raised [&_code]:text-accent [&_code]:px-1.5 [&_code]:py-0.5 [&_code]:rounded [&_code]:text-xs [&_code]:font-mono",
|
|
98
|
+
"[&_pre]:bg-surface-raised [&_pre]:border [&_pre]:border-border [&_pre]:rounded-xl [&_pre]:p-4 [&_pre]:overflow-x-auto",
|
|
99
|
+
"[&_hr]:my-3 [&_hr]:border-border",
|
|
100
|
+
"[&_blockquote]:border-l-2 [&_blockquote]:border-border-strong [&_blockquote]:pl-4 [&_blockquote]:text-text-secondary",
|
|
101
|
+
"[&_a]:text-accent [&_a]:underline-offset-2 [&_a]:hover:text-accent/80",
|
|
102
|
+
className
|
|
103
|
+
),
|
|
104
|
+
"data-testid": "response-message",
|
|
105
|
+
children: /* @__PURE__ */ jsx(
|
|
106
|
+
ReactMarkdown,
|
|
107
|
+
{
|
|
108
|
+
rehypePlugins: [rehypeSanitize],
|
|
109
|
+
components: {
|
|
110
|
+
script: () => null,
|
|
111
|
+
iframe: () => null,
|
|
112
|
+
p: ({ children }) => /* @__PURE__ */ jsx("p", { className: "my-2", children }),
|
|
113
|
+
ul: ({ children }) => /* @__PURE__ */ jsx("ul", { className: "my-2 list-disc pl-6", children }),
|
|
114
|
+
ol: ({ children }) => /* @__PURE__ */ jsx("ol", { className: "my-2 list-decimal pl-6", children }),
|
|
115
|
+
li: ({ children, ...props }) => {
|
|
116
|
+
let content2 = children;
|
|
117
|
+
if (props.ordered) {
|
|
118
|
+
content2 = React.Children.map(children, (child, i) => {
|
|
119
|
+
if (i === 0 && typeof child === "string") {
|
|
120
|
+
return child.replace(/^\d+[.)]\s*/, "");
|
|
121
|
+
}
|
|
122
|
+
return child;
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
return /* @__PURE__ */ jsx("li", { className: "my-1", children: content2 });
|
|
126
|
+
},
|
|
127
|
+
strong: ({ children }) => /* @__PURE__ */ jsx("strong", { className: "font-semibold", children }),
|
|
128
|
+
em: ({ children }) => /* @__PURE__ */ jsx("em", { className: "italic text-text-secondary", children }),
|
|
129
|
+
h1: ({ children }) => /* @__PURE__ */ jsx("h1", { className: "text-base font-bold mt-4 mb-2", children }),
|
|
130
|
+
h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: "text-sm font-bold mt-3 mb-1", children }),
|
|
131
|
+
h3: ({ children }) => /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mt-2 mb-1", children }),
|
|
132
|
+
hr: () => /* @__PURE__ */ jsx("hr", { className: "my-3 border-border" }),
|
|
133
|
+
code: ({ children }) => /* @__PURE__ */ jsx("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children })
|
|
134
|
+
},
|
|
135
|
+
children: normalizeMarkdownLists(content)
|
|
136
|
+
}
|
|
137
|
+
)
|
|
138
|
+
}
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
|
|
69
142
|
// src/streaming/StreamingMessage/StreamingMessage.tsx
|
|
70
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
143
|
+
import { jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
71
144
|
var phaseLabels = {
|
|
72
145
|
idle: "",
|
|
73
146
|
waiting: "Waiting...",
|
|
@@ -76,14 +149,35 @@ var phaseLabels = {
|
|
|
76
149
|
generating: "Writing...",
|
|
77
150
|
verifying: "Verifying..."
|
|
78
151
|
};
|
|
152
|
+
var CURSOR_STYLES = `
|
|
153
|
+
.sk-streaming-cursor > :not(ul,ol,blockquote):last-child::after,
|
|
154
|
+
.sk-streaming-cursor > :is(ul,ol):last-child > li:last-child::after,
|
|
155
|
+
.sk-streaming-cursor > blockquote:last-child > p:last-child::after {
|
|
156
|
+
content: "";
|
|
157
|
+
display: inline-block;
|
|
158
|
+
width: 2px;
|
|
159
|
+
height: 1em;
|
|
160
|
+
background: var(--color-accent, #38bdf8);
|
|
161
|
+
animation: sk-cursor-blink 0.8s steps(1) infinite;
|
|
162
|
+
margin-left: 2px;
|
|
163
|
+
vertical-align: text-bottom;
|
|
164
|
+
}
|
|
165
|
+
@keyframes sk-cursor-blink {
|
|
166
|
+
0%, 60% { opacity: 1; }
|
|
167
|
+
61%, 100% { opacity: 0; }
|
|
168
|
+
}
|
|
169
|
+
`;
|
|
79
170
|
function StreamingMessage({
|
|
80
171
|
stream,
|
|
81
172
|
onComplete,
|
|
173
|
+
onDraining,
|
|
82
174
|
showPhases = true,
|
|
83
175
|
className
|
|
84
176
|
}) {
|
|
85
177
|
const onCompleteRef = useRef2(onComplete);
|
|
86
178
|
onCompleteRef.current = onComplete;
|
|
179
|
+
const onDrainingRef = useRef2(onDraining);
|
|
180
|
+
onDrainingRef.current = onDraining;
|
|
87
181
|
const wasActiveRef = useRef2(stream.active);
|
|
88
182
|
useEffect2(() => {
|
|
89
183
|
if (wasActiveRef.current && !stream.active) {
|
|
@@ -92,42 +186,47 @@ function StreamingMessage({
|
|
|
92
186
|
wasActiveRef.current = stream.active;
|
|
93
187
|
}, [stream.active]);
|
|
94
188
|
const phaseLabel = phaseLabels[stream.phase];
|
|
95
|
-
const { displayed:
|
|
96
|
-
|
|
189
|
+
const { displayed: rawDisplayed, isDraining } = useCharacterDrain(stream.content);
|
|
190
|
+
const displayedContent = stream.active || isDraining ? rawDisplayed.trimEnd() : rawDisplayed;
|
|
191
|
+
useEffect2(() => {
|
|
192
|
+
onDrainingRef.current?.(isDraining);
|
|
193
|
+
}, [isDraining]);
|
|
194
|
+
const agentLabel = stream.agent ? stream.agent.replace("_agent", "").replace("_", " ") : null;
|
|
195
|
+
const showPhaseIndicator = showPhases && stream.active && stream.phase !== "idle" && !displayedContent;
|
|
196
|
+
const showCursor = (stream.active || isDraining) && !!displayedContent;
|
|
197
|
+
return /* @__PURE__ */ jsxs("div", { className: twMerge2("flex w-full flex-col items-start", className), "data-testid": "streaming-message", children: [
|
|
97
198
|
/* @__PURE__ */ jsxs("div", { "aria-live": "assertive", className: "sr-only", children: [
|
|
98
199
|
stream.active && stream.phase !== "idle" && "Response started",
|
|
99
200
|
!stream.active && stream.content && "Response complete"
|
|
100
201
|
] }),
|
|
202
|
+
showCursor && /* @__PURE__ */ jsx2("style", { children: CURSOR_STYLES }),
|
|
203
|
+
agentLabel && /* @__PURE__ */ jsx2("div", { className: "text-[11px] font-display font-semibold uppercase tracking-[0.08em] text-text-muted px-1 mb-1.5", children: agentLabel }),
|
|
101
204
|
/* @__PURE__ */ 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: [
|
|
102
|
-
|
|
205
|
+
showPhaseIndicator && /* @__PURE__ */ jsxs(
|
|
103
206
|
"div",
|
|
104
207
|
{
|
|
105
|
-
className: "flex items-center gap-2
|
|
208
|
+
className: "flex items-center gap-2 text-sm text-text-secondary",
|
|
106
209
|
"data-testid": "phase-indicator",
|
|
107
210
|
children: [
|
|
108
|
-
/* @__PURE__ */
|
|
109
|
-
/* @__PURE__ */
|
|
211
|
+
/* @__PURE__ */ jsx2("span", { "aria-hidden": "true", children: /* @__PURE__ */ jsx2(WaveLoader, { size: "sm", color: "#38bdf8" }) }),
|
|
212
|
+
/* @__PURE__ */ jsx2("span", { children: phaseLabel })
|
|
110
213
|
]
|
|
111
214
|
}
|
|
112
215
|
),
|
|
113
|
-
/* @__PURE__ */
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
"data-testid": "streaming-cursor"
|
|
121
|
-
}
|
|
122
|
-
)
|
|
123
|
-
] })
|
|
216
|
+
displayedContent && /* @__PURE__ */ jsx2(
|
|
217
|
+
ResponseMessage,
|
|
218
|
+
{
|
|
219
|
+
content: displayedContent,
|
|
220
|
+
className: showCursor ? "sk-streaming-cursor" : void 0
|
|
221
|
+
}
|
|
222
|
+
)
|
|
124
223
|
] })
|
|
125
224
|
] });
|
|
126
225
|
}
|
|
127
226
|
|
|
128
227
|
// src/streaming/ThinkingIndicator/ThinkingIndicator.tsx
|
|
129
228
|
import { useReducedMotion } from "@surf-kit/hooks";
|
|
130
|
-
import { jsx as
|
|
229
|
+
import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
131
230
|
function ThinkingIndicator({ label = "Thinking...", className }) {
|
|
132
231
|
const reducedMotion = useReducedMotion();
|
|
133
232
|
return /* @__PURE__ */ jsxs2(
|
|
@@ -137,11 +236,11 @@ function ThinkingIndicator({ label = "Thinking...", className }) {
|
|
|
137
236
|
className: `inline-flex items-center gap-2 text-sm motion-safe:animate-fadeSlideUpSm ${className ?? ""}`,
|
|
138
237
|
"data-testid": "thinking-indicator",
|
|
139
238
|
children: [
|
|
140
|
-
/* @__PURE__ */
|
|
239
|
+
/* @__PURE__ */ jsx3("span", { className: "text-text-secondary", children: label }),
|
|
141
240
|
!reducedMotion && /* @__PURE__ */ jsxs2("span", { className: "flex gap-1", "aria-hidden": "true", "data-testid": "animated-dots", children: [
|
|
142
|
-
/* @__PURE__ */
|
|
143
|
-
/* @__PURE__ */
|
|
144
|
-
/* @__PURE__ */
|
|
241
|
+
/* @__PURE__ */ jsx3("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:0ms]" }),
|
|
242
|
+
/* @__PURE__ */ jsx3("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:150ms]" }),
|
|
243
|
+
/* @__PURE__ */ jsx3("span", { className: "w-1.5 h-1.5 rounded-full bg-current animate-bounce [animation-delay:300ms]" })
|
|
145
244
|
] })
|
|
146
245
|
]
|
|
147
246
|
}
|
|
@@ -149,8 +248,8 @@ function ThinkingIndicator({ label = "Thinking...", className }) {
|
|
|
149
248
|
}
|
|
150
249
|
|
|
151
250
|
// src/streaming/ToolExecution/ToolExecution.tsx
|
|
152
|
-
import {
|
|
153
|
-
import { jsx as
|
|
251
|
+
import { WaveLoader as WaveLoader2 } from "@surf-kit/core";
|
|
252
|
+
import { jsx as jsx4, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
154
253
|
var defaultLabels = {
|
|
155
254
|
search: "Searching knowledge base...",
|
|
156
255
|
retrieve: "Retrieving documents...",
|
|
@@ -165,16 +264,16 @@ function ToolExecution({ tool, label, className }) {
|
|
|
165
264
|
role: "status",
|
|
166
265
|
"data-testid": "tool-execution",
|
|
167
266
|
children: [
|
|
168
|
-
/* @__PURE__ */
|
|
169
|
-
/* @__PURE__ */
|
|
267
|
+
/* @__PURE__ */ jsx4("span", { "aria-hidden": "true", children: /* @__PURE__ */ jsx4(WaveLoader2, { size: "sm", color: "#38bdf8" }) }),
|
|
268
|
+
/* @__PURE__ */ jsx4("span", { children: displayLabel })
|
|
170
269
|
]
|
|
171
270
|
}
|
|
172
271
|
);
|
|
173
272
|
}
|
|
174
273
|
|
|
175
274
|
// src/streaming/RetrievalProgress/RetrievalProgress.tsx
|
|
176
|
-
import {
|
|
177
|
-
import { jsx as
|
|
275
|
+
import { WaveLoader as WaveLoader3 } from "@surf-kit/core";
|
|
276
|
+
import { jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
|
|
178
277
|
function RetrievalProgress({ sources, isActive, className }) {
|
|
179
278
|
return /* @__PURE__ */ jsxs4(
|
|
180
279
|
"div",
|
|
@@ -185,18 +284,18 @@ function RetrievalProgress({ sources, isActive, className }) {
|
|
|
185
284
|
"data-testid": "retrieval-progress",
|
|
186
285
|
children: [
|
|
187
286
|
isActive && /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 text-sm text-text-secondary", children: [
|
|
188
|
-
/* @__PURE__ */
|
|
189
|
-
/* @__PURE__ */
|
|
287
|
+
/* @__PURE__ */ jsx5("span", { "aria-hidden": "true", children: /* @__PURE__ */ jsx5(WaveLoader3, { size: "sm", color: "#38bdf8" }) }),
|
|
288
|
+
/* @__PURE__ */ jsx5("span", { children: "Retrieving sources..." })
|
|
190
289
|
] }),
|
|
191
|
-
sources.length > 0 && /* @__PURE__ */
|
|
290
|
+
sources.length > 0 && /* @__PURE__ */ jsx5("ul", { className: "space-y-1", "data-testid": "source-list", children: sources.map((source, index) => /* @__PURE__ */ jsxs4(
|
|
192
291
|
"li",
|
|
193
292
|
{
|
|
194
293
|
className: "text-sm text-text-secondary flex items-center gap-2 animate-in fade-in slide-in-from-left-2",
|
|
195
294
|
style: { animationDelay: `${index * 100}ms`, animationFillMode: "both" },
|
|
196
295
|
"data-testid": "retrieval-source-item",
|
|
197
296
|
children: [
|
|
198
|
-
/* @__PURE__ */
|
|
199
|
-
/* @__PURE__ */
|
|
297
|
+
/* @__PURE__ */ jsx5("span", { className: "w-1.5 h-1.5 rounded-full bg-accent flex-shrink-0", "aria-hidden": "true" }),
|
|
298
|
+
/* @__PURE__ */ jsx5("span", { className: "truncate", children: source.title })
|
|
200
299
|
]
|
|
201
300
|
},
|
|
202
301
|
source.document_id
|
|
@@ -207,7 +306,7 @@ function RetrievalProgress({ sources, isActive, className }) {
|
|
|
207
306
|
}
|
|
208
307
|
|
|
209
308
|
// src/streaming/VerificationProgress/VerificationProgress.tsx
|
|
210
|
-
import { jsx as
|
|
309
|
+
import { jsx as jsx6, jsxs as jsxs5 } from "react/jsx-runtime";
|
|
211
310
|
function VerificationProgress({
|
|
212
311
|
isActive,
|
|
213
312
|
label = "Checking accuracy...",
|
|
@@ -230,12 +329,12 @@ function VerificationProgress({
|
|
|
230
329
|
viewBox: "0 0 24 24",
|
|
231
330
|
"aria-hidden": "true",
|
|
232
331
|
children: [
|
|
233
|
-
/* @__PURE__ */
|
|
234
|
-
/* @__PURE__ */
|
|
332
|
+
/* @__PURE__ */ jsx6("circle", { className: "opacity-25", cx: "12", cy: "12", r: "10", stroke: "currentColor", strokeWidth: "4" }),
|
|
333
|
+
/* @__PURE__ */ jsx6("path", { className: "opacity-75", fill: "currentColor", d: "M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4z" })
|
|
235
334
|
]
|
|
236
335
|
}
|
|
237
336
|
),
|
|
238
|
-
/* @__PURE__ */
|
|
337
|
+
/* @__PURE__ */ jsx6("span", { className: "text-accent animate-pulse", children: label })
|
|
239
338
|
]
|
|
240
339
|
}
|
|
241
340
|
);
|
|
@@ -243,7 +342,7 @@ function VerificationProgress({
|
|
|
243
342
|
|
|
244
343
|
// src/streaming/TypewriterText/TypewriterText.tsx
|
|
245
344
|
import { useEffect as useEffect3, useState as useState2 } from "react";
|
|
246
|
-
import { jsx as
|
|
345
|
+
import { jsx as jsx7, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
247
346
|
function TypewriterText({
|
|
248
347
|
text,
|
|
249
348
|
speed = 30,
|
|
@@ -278,14 +377,14 @@ function TypewriterText({
|
|
|
278
377
|
}, [text, speed, delay, onComplete]);
|
|
279
378
|
return /* @__PURE__ */ jsxs6("span", { className, children: [
|
|
280
379
|
displayedText,
|
|
281
|
-
showCursor && !isComplete && /* @__PURE__ */
|
|
380
|
+
showCursor && !isComplete && /* @__PURE__ */ jsx7("span", { className: "typewriter-cursor", "aria-hidden": "true" })
|
|
282
381
|
] });
|
|
283
382
|
}
|
|
284
383
|
|
|
285
384
|
// src/streaming/TypingIndicator/TypingIndicator.tsx
|
|
286
|
-
import { twMerge } from "tailwind-merge";
|
|
385
|
+
import { twMerge as twMerge3 } from "tailwind-merge";
|
|
287
386
|
import { useReducedMotion as useReducedMotion2 } from "@surf-kit/hooks";
|
|
288
|
-
import { jsx as
|
|
387
|
+
import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
289
388
|
var bounceKeyframes = `
|
|
290
389
|
@keyframes typing-bounce {
|
|
291
390
|
0%, 80%, 100% { transform: translateY(0); }
|
|
@@ -303,12 +402,12 @@ function TypingIndicator({
|
|
|
303
402
|
{
|
|
304
403
|
role: "status",
|
|
305
404
|
"aria-label": label ?? "typing",
|
|
306
|
-
className:
|
|
405
|
+
className: twMerge3("inline-flex items-center gap-2", className),
|
|
307
406
|
"data-testid": "typing-indicator",
|
|
308
407
|
children: [
|
|
309
|
-
!reducedMotion && /* @__PURE__ */
|
|
310
|
-
label && /* @__PURE__ */
|
|
311
|
-
/* @__PURE__ */
|
|
408
|
+
!reducedMotion && /* @__PURE__ */ jsx8("style", { children: bounceKeyframes }),
|
|
409
|
+
label && /* @__PURE__ */ jsx8("span", { className: "text-sm text-text-secondary", children: label }),
|
|
410
|
+
/* @__PURE__ */ jsx8("span", { className: "flex gap-1", "data-testid": "typing-dots", children: Array.from({ length: dotCount }, (_, i) => /* @__PURE__ */ jsx8(
|
|
312
411
|
"span",
|
|
313
412
|
{
|
|
314
413
|
className: "w-2 h-2 rounded-full bg-text-secondary",
|
|
@@ -325,9 +424,9 @@ function TypingIndicator({
|
|
|
325
424
|
}
|
|
326
425
|
|
|
327
426
|
// src/streaming/TextGlimmer/TextGlimmer.tsx
|
|
328
|
-
import { twMerge as
|
|
427
|
+
import { twMerge as twMerge4 } from "tailwind-merge";
|
|
329
428
|
import { useReducedMotion as useReducedMotion3 } from "@surf-kit/hooks";
|
|
330
|
-
import { jsx as
|
|
429
|
+
import { jsx as jsx9, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
331
430
|
var shimmerKeyframes = `
|
|
332
431
|
@keyframes text-shimmer {
|
|
333
432
|
0% { background-position: 200% 0; }
|
|
@@ -342,11 +441,11 @@ function TextGlimmer({ lines = 3, className }) {
|
|
|
342
441
|
{
|
|
343
442
|
role: "status",
|
|
344
443
|
"aria-label": "Loading",
|
|
345
|
-
className:
|
|
444
|
+
className: twMerge4("flex flex-col gap-2", className),
|
|
346
445
|
"data-testid": "text-glimmer",
|
|
347
446
|
children: [
|
|
348
|
-
!reducedMotion && /* @__PURE__ */
|
|
349
|
-
Array.from({ length: lines }, (_, i) => /* @__PURE__ */
|
|
447
|
+
!reducedMotion && /* @__PURE__ */ jsx9("style", { children: shimmerKeyframes }),
|
|
448
|
+
Array.from({ length: lines }, (_, i) => /* @__PURE__ */ jsx9(
|
|
350
449
|
"div",
|
|
351
450
|
{
|
|
352
451
|
className: "h-3 rounded bg-surface-raised",
|
|
@@ -368,9 +467,9 @@ function TextGlimmer({ lines = 3, className }) {
|
|
|
368
467
|
}
|
|
369
468
|
|
|
370
469
|
// src/streaming/StreamingList/StreamingList.tsx
|
|
371
|
-
import { twMerge as
|
|
470
|
+
import { twMerge as twMerge5 } from "tailwind-merge";
|
|
372
471
|
import { useReducedMotion as useReducedMotion4 } from "@surf-kit/hooks";
|
|
373
|
-
import { jsx as
|
|
472
|
+
import { jsx as jsx10, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
374
473
|
var fadeSlideInKeyframes = `
|
|
375
474
|
@keyframes fadeSlideIn {
|
|
376
475
|
from { opacity: 0; transform: translateY(8px); }
|
|
@@ -386,17 +485,17 @@ function StreamingList({
|
|
|
386
485
|
}) {
|
|
387
486
|
const reducedMotion = useReducedMotion4();
|
|
388
487
|
if (items.length === 0 && !isStreaming) {
|
|
389
|
-
return emptyMessage ? /* @__PURE__ */
|
|
488
|
+
return emptyMessage ? /* @__PURE__ */ jsx10("p", { className: twMerge5("text-sm text-text-secondary", className), "data-testid": "streaming-list-empty", children: emptyMessage }) : null;
|
|
390
489
|
}
|
|
391
490
|
return /* @__PURE__ */ jsxs9(
|
|
392
491
|
"ul",
|
|
393
492
|
{
|
|
394
493
|
"aria-live": "polite",
|
|
395
|
-
className:
|
|
494
|
+
className: twMerge5("list-none p-0 m-0", className),
|
|
396
495
|
"data-testid": "streaming-list",
|
|
397
496
|
children: [
|
|
398
|
-
!reducedMotion && /* @__PURE__ */
|
|
399
|
-
items.map((item, index) => /* @__PURE__ */
|
|
497
|
+
!reducedMotion && /* @__PURE__ */ jsx10("style", { children: fadeSlideInKeyframes }),
|
|
498
|
+
items.map((item, index) => /* @__PURE__ */ jsx10(
|
|
400
499
|
"li",
|
|
401
500
|
{
|
|
402
501
|
style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
|
|
@@ -405,16 +504,16 @@ function StreamingList({
|
|
|
405
504
|
},
|
|
406
505
|
index
|
|
407
506
|
)),
|
|
408
|
-
isStreaming && /* @__PURE__ */
|
|
507
|
+
isStreaming && /* @__PURE__ */ jsx10("li", { "data-testid": "streaming-list-loading", children: /* @__PURE__ */ jsx10(TypingIndicator, {}) })
|
|
409
508
|
]
|
|
410
509
|
}
|
|
411
510
|
);
|
|
412
511
|
}
|
|
413
512
|
|
|
414
513
|
// src/streaming/StreamingStructure/StreamingStructure.tsx
|
|
415
|
-
import { twMerge as
|
|
514
|
+
import { twMerge as twMerge6 } from "tailwind-merge";
|
|
416
515
|
import { useReducedMotion as useReducedMotion5 } from "@surf-kit/hooks";
|
|
417
|
-
import { jsx as
|
|
516
|
+
import { jsx as jsx11, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
418
517
|
var fadeSlideInKeyframes2 = `
|
|
419
518
|
@keyframes fadeSlideIn {
|
|
420
519
|
from { opacity: 0; transform: translateY(8px); }
|
|
@@ -423,13 +522,13 @@ var fadeSlideInKeyframes2 = `
|
|
|
423
522
|
`;
|
|
424
523
|
function renderValue(value, reducedMotion) {
|
|
425
524
|
if (value === null) {
|
|
426
|
-
return /* @__PURE__ */
|
|
525
|
+
return /* @__PURE__ */ jsx11("span", { className: "italic text-text-secondary", children: "null" });
|
|
427
526
|
}
|
|
428
527
|
if (value === void 0) {
|
|
429
|
-
return /* @__PURE__ */
|
|
528
|
+
return /* @__PURE__ */ jsx11("span", { className: "italic text-text-secondary", children: "undefined" });
|
|
430
529
|
}
|
|
431
530
|
if (Array.isArray(value)) {
|
|
432
|
-
return /* @__PURE__ */
|
|
531
|
+
return /* @__PURE__ */ jsx11("ol", { className: "list-decimal pl-4 m-0", children: value.map((item, i) => /* @__PURE__ */ jsx11("li", { className: "text-text-secondary text-sm", children: renderValue(item, reducedMotion) }, i)) });
|
|
433
532
|
}
|
|
434
533
|
if (typeof value === "object") {
|
|
435
534
|
return renderNestedDl(value, reducedMotion);
|
|
@@ -438,13 +537,13 @@ function renderValue(value, reducedMotion) {
|
|
|
438
537
|
}
|
|
439
538
|
function renderNestedDl(data, reducedMotion) {
|
|
440
539
|
const entries = Object.entries(data);
|
|
441
|
-
return /* @__PURE__ */
|
|
540
|
+
return /* @__PURE__ */ jsx11("dl", { className: "pl-4 m-0", "data-testid": "streaming-structure-nested", children: entries.map(([key, value]) => /* @__PURE__ */ jsxs10(
|
|
442
541
|
"div",
|
|
443
542
|
{
|
|
444
543
|
style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
|
|
445
544
|
children: [
|
|
446
|
-
/* @__PURE__ */
|
|
447
|
-
/* @__PURE__ */
|
|
545
|
+
/* @__PURE__ */ jsx11("dt", { className: "font-medium text-text-primary text-sm", children: key }),
|
|
546
|
+
/* @__PURE__ */ jsx11("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
|
|
448
547
|
]
|
|
449
548
|
},
|
|
450
549
|
key
|
|
@@ -461,23 +560,23 @@ function StreamingStructure({
|
|
|
461
560
|
"dl",
|
|
462
561
|
{
|
|
463
562
|
"aria-live": "polite",
|
|
464
|
-
className:
|
|
563
|
+
className: twMerge6("m-0", className),
|
|
465
564
|
"data-testid": "streaming-structure",
|
|
466
565
|
children: [
|
|
467
|
-
!reducedMotion && /* @__PURE__ */
|
|
566
|
+
!reducedMotion && /* @__PURE__ */ jsx11("style", { children: fadeSlideInKeyframes2 }),
|
|
468
567
|
entries.map(([key, value]) => /* @__PURE__ */ jsxs10(
|
|
469
568
|
"div",
|
|
470
569
|
{
|
|
471
570
|
style: reducedMotion ? void 0 : { animation: "fadeSlideIn 0.3s ease-out" },
|
|
472
571
|
"data-testid": "streaming-structure-entry",
|
|
473
572
|
children: [
|
|
474
|
-
/* @__PURE__ */
|
|
475
|
-
/* @__PURE__ */
|
|
573
|
+
/* @__PURE__ */ jsx11("dt", { className: "font-medium text-text-primary text-sm", children: key }),
|
|
574
|
+
/* @__PURE__ */ jsx11("dd", { className: "text-text-secondary text-sm ml-0 mb-3", children: renderValue(value, reducedMotion) })
|
|
476
575
|
]
|
|
477
576
|
},
|
|
478
577
|
key
|
|
479
578
|
)),
|
|
480
|
-
isStreaming && /* @__PURE__ */
|
|
579
|
+
isStreaming && /* @__PURE__ */ jsx11("div", { "data-testid": "streaming-structure-loading", children: /* @__PURE__ */ jsx11(TextGlimmer, { lines: 1 }) })
|
|
481
580
|
]
|
|
482
581
|
}
|
|
483
582
|
);
|