@surf-kit/agent 0.3.0 → 0.4.1
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 +131 -41
- package/dist/chat/index.cjs.map +1 -1
- package/dist/chat/index.d.cts +3 -2
- package/dist/chat/index.d.ts +3 -2
- package/dist/chat/index.js +132 -42
- package/dist/chat/index.js.map +1 -1
- package/dist/{chat-CGamM7Mz.d.cts → chat-BRY3xGg_.d.cts} +1 -1
- package/dist/{chat-BIIDOGrD.d.ts → chat-CcKc6OAR.d.ts} +1 -1
- package/dist/{hooks-CTeEqnBQ.d.ts → hooks-BLeiVk-x.d.ts} +3 -2
- package/dist/{hooks-B1NYoLLs.d.cts → hooks-CSGGLd7j.d.cts} +3 -2
- package/dist/hooks.cjs +41 -11
- 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 +41 -11
- package/dist/hooks.js.map +1 -1
- package/dist/index.cjs +131 -41
- 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 +136 -46
- package/dist/index.js.map +1 -1
- package/dist/layouts/index.cjs +131 -41
- 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 +134 -44
- package/dist/layouts/index.js.map +1 -1
- package/dist/response/index.cjs +34 -3
- package/dist/response/index.cjs.map +1 -1
- package/dist/response/index.d.cts +1 -1
- package/dist/response/index.d.ts +1 -1
- package/dist/response/index.js +35 -4
- package/dist/response/index.js.map +1 -1
- package/dist/streaming/index.cjs +14 -3
- package/dist/streaming/index.cjs.map +1 -1
- package/dist/streaming/index.d.cts +2 -2
- package/dist/streaming/index.d.ts +2 -2
- package/dist/streaming/index.js +14 -3
- package/dist/streaming/index.js.map +1 -1
- package/dist/{streaming-x7umFHoP.d.cts → streaming-BHPXnwwo.d.cts} +3 -1
- package/dist/{streaming-Bx-ff2tt.d.ts → streaming-C6mbU7My.d.ts} +3 -1
- package/package.json +5 -4
package/dist/layouts/index.cjs
CHANGED
|
@@ -76,6 +76,8 @@ function reducer(state, action) {
|
|
|
76
76
|
return { ...state, streamPhase: action.phase };
|
|
77
77
|
case "STREAM_CONTENT":
|
|
78
78
|
return { ...state, streamingContent: state.streamingContent + action.content };
|
|
79
|
+
case "STREAM_CONTENT_RESET":
|
|
80
|
+
return { ...state, streamingContent: "" };
|
|
79
81
|
case "STREAM_AGENT":
|
|
80
82
|
return { ...state, streamingAgent: action.agent };
|
|
81
83
|
case "SEND_SUCCESS":
|
|
@@ -121,6 +123,7 @@ function useAgentChat(config) {
|
|
|
121
123
|
configRef.current = config;
|
|
122
124
|
const lastUserMessageRef = (0, import_react.useRef)(null);
|
|
123
125
|
const lastUserAttachmentsRef = (0, import_react.useRef)(void 0);
|
|
126
|
+
const abortControllerRef = (0, import_react.useRef)(null);
|
|
124
127
|
const sendMessage = (0, import_react.useCallback)(
|
|
125
128
|
async (content, attachments) => {
|
|
126
129
|
const { apiUrl, streamPath = "/chat/stream", headers: headersOrFn, timeout = 3e4, bodyExtra } = configRef.current;
|
|
@@ -136,7 +139,15 @@ function useAgentChat(config) {
|
|
|
136
139
|
};
|
|
137
140
|
dispatch({ type: "SEND_START", message: userMessage });
|
|
138
141
|
const controller = new AbortController();
|
|
142
|
+
abortControllerRef.current = controller;
|
|
139
143
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
144
|
+
const ctx = {
|
|
145
|
+
accumulatedContent: "",
|
|
146
|
+
agentResponse: null,
|
|
147
|
+
capturedAgent: null,
|
|
148
|
+
capturedConversationId: null,
|
|
149
|
+
hadStreamError: false
|
|
150
|
+
};
|
|
140
151
|
try {
|
|
141
152
|
const url = `${apiUrl}${streamPath}`;
|
|
142
153
|
const mergedHeaders = {
|
|
@@ -157,13 +168,6 @@ function useAgentChat(config) {
|
|
|
157
168
|
}));
|
|
158
169
|
}
|
|
159
170
|
const body = JSON.stringify(requestBody);
|
|
160
|
-
const ctx = {
|
|
161
|
-
accumulatedContent: "",
|
|
162
|
-
agentResponse: null,
|
|
163
|
-
capturedAgent: null,
|
|
164
|
-
capturedConversationId: null,
|
|
165
|
-
hadStreamError: false
|
|
166
|
-
};
|
|
167
171
|
const handleEvent = (event) => {
|
|
168
172
|
switch (event.type) {
|
|
169
173
|
case "agent":
|
|
@@ -177,6 +181,10 @@ function useAgentChat(config) {
|
|
|
177
181
|
ctx.accumulatedContent += event.content;
|
|
178
182
|
dispatch({ type: "STREAM_CONTENT", content: event.content });
|
|
179
183
|
break;
|
|
184
|
+
case "delta_reset":
|
|
185
|
+
ctx.accumulatedContent = "";
|
|
186
|
+
dispatch({ type: "STREAM_CONTENT_RESET" });
|
|
187
|
+
break;
|
|
180
188
|
case "done":
|
|
181
189
|
ctx.agentResponse = event.response;
|
|
182
190
|
ctx.capturedConversationId = event.conversation_id ?? null;
|
|
@@ -260,10 +268,26 @@ function useAgentChat(config) {
|
|
|
260
268
|
} catch (err) {
|
|
261
269
|
clearTimeout(timeoutId);
|
|
262
270
|
if (err.name === "AbortError") {
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
271
|
+
if (ctx.accumulatedContent) {
|
|
272
|
+
const partialMessage = {
|
|
273
|
+
id: generateMessageId(),
|
|
274
|
+
role: "assistant",
|
|
275
|
+
content: ctx.accumulatedContent,
|
|
276
|
+
agent: ctx.capturedAgent ?? void 0,
|
|
277
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
278
|
+
};
|
|
279
|
+
dispatch({
|
|
280
|
+
type: "SEND_SUCCESS",
|
|
281
|
+
message: partialMessage,
|
|
282
|
+
streamingContent: ctx.accumulatedContent,
|
|
283
|
+
conversationId: ctx.capturedConversationId
|
|
284
|
+
});
|
|
285
|
+
} else {
|
|
286
|
+
dispatch({
|
|
287
|
+
type: "SEND_ERROR",
|
|
288
|
+
error: { code: "ABORTED", message: "Request stopped", retryable: true }
|
|
289
|
+
});
|
|
290
|
+
}
|
|
267
291
|
} else {
|
|
268
292
|
dispatch({
|
|
269
293
|
type: "SEND_ERROR",
|
|
@@ -274,6 +298,8 @@ function useAgentChat(config) {
|
|
|
274
298
|
}
|
|
275
299
|
});
|
|
276
300
|
}
|
|
301
|
+
} finally {
|
|
302
|
+
abortControllerRef.current = null;
|
|
277
303
|
}
|
|
278
304
|
},
|
|
279
305
|
[state.conversationId]
|
|
@@ -301,6 +327,9 @@ function useAgentChat(config) {
|
|
|
301
327
|
await sendMessage(lastUserMessageRef.current, lastUserAttachmentsRef.current);
|
|
302
328
|
}
|
|
303
329
|
}, [sendMessage]);
|
|
330
|
+
const stop = (0, import_react.useCallback)(() => {
|
|
331
|
+
abortControllerRef.current?.abort();
|
|
332
|
+
}, []);
|
|
304
333
|
const reset = (0, import_react.useCallback)(() => {
|
|
305
334
|
dispatch({ type: "RESET" });
|
|
306
335
|
lastUserMessageRef.current = null;
|
|
@@ -312,6 +341,7 @@ function useAgentChat(config) {
|
|
|
312
341
|
loadConversation,
|
|
313
342
|
submitFeedback,
|
|
314
343
|
retry,
|
|
344
|
+
stop,
|
|
315
345
|
reset
|
|
316
346
|
};
|
|
317
347
|
return { state, actions };
|
|
@@ -331,6 +361,7 @@ var import_core2 = require("@surf-kit/core");
|
|
|
331
361
|
var import_react2 = __toESM(require("react"), 1);
|
|
332
362
|
var import_react_markdown = __toESM(require("react-markdown"), 1);
|
|
333
363
|
var import_rehype_sanitize = __toESM(require("rehype-sanitize"), 1);
|
|
364
|
+
var import_remark_gfm = __toESM(require("remark-gfm"), 1);
|
|
334
365
|
var import_tailwind_merge = require("tailwind-merge");
|
|
335
366
|
var import_jsx_runtime = require("react/jsx-runtime");
|
|
336
367
|
function normalizeMarkdownLists(content) {
|
|
@@ -355,6 +386,10 @@ function ResponseMessage({ content, className }) {
|
|
|
355
386
|
"[&_pre]:bg-surface-raised [&_pre]:border [&_pre]:border-border [&_pre]:rounded-xl [&_pre]:p-4 [&_pre]:overflow-x-auto",
|
|
356
387
|
"[&_hr]:my-3 [&_hr]:border-border",
|
|
357
388
|
"[&_blockquote]:border-l-2 [&_blockquote]:border-border-strong [&_blockquote]:pl-4 [&_blockquote]:text-text-secondary",
|
|
389
|
+
"[&_table]:w-full [&_table]:text-sm [&_table]:border-collapse [&_table]:my-2",
|
|
390
|
+
"[&_thead]:border-b [&_thead]:border-border",
|
|
391
|
+
"[&_th]:text-left [&_th]:px-2 [&_th]:py-1.5 [&_th]:font-semibold",
|
|
392
|
+
"[&_td]:px-2 [&_td]:py-1.5 [&_td]:border-t [&_td]:border-border/50",
|
|
358
393
|
"[&_a]:text-accent [&_a]:underline-offset-2 [&_a]:hover:text-accent/80",
|
|
359
394
|
className
|
|
360
395
|
),
|
|
@@ -362,6 +397,7 @@ function ResponseMessage({ content, className }) {
|
|
|
362
397
|
children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
363
398
|
import_react_markdown.default,
|
|
364
399
|
{
|
|
400
|
+
remarkPlugins: [import_remark_gfm.default],
|
|
365
401
|
rehypePlugins: [import_rehype_sanitize.default],
|
|
366
402
|
components: {
|
|
367
403
|
script: () => null,
|
|
@@ -387,7 +423,11 @@ function ResponseMessage({ content, className }) {
|
|
|
387
423
|
h2: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h2", { className: "text-sm font-bold mt-3 mb-1", children }),
|
|
388
424
|
h3: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("h3", { className: "text-sm font-semibold mt-2 mb-1", children }),
|
|
389
425
|
hr: () => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("hr", { className: "my-3 border-border" }),
|
|
390
|
-
code: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children })
|
|
426
|
+
code: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children }),
|
|
427
|
+
table: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: "overflow-x-auto my-2", children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("table", { className: "w-full text-sm border-collapse", children }) }),
|
|
428
|
+
thead: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("thead", { className: "border-b border-border", children }),
|
|
429
|
+
th: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("th", { className: "text-left px-2 py-1.5 font-semibold", children }),
|
|
430
|
+
td: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime.jsx)("td", { className: "px-2 py-1.5 border-t border-border/50", children })
|
|
391
431
|
},
|
|
392
432
|
children: normalizeMarkdownLists(content)
|
|
393
433
|
}
|
|
@@ -397,6 +437,8 @@ function ResponseMessage({ content, className }) {
|
|
|
397
437
|
}
|
|
398
438
|
|
|
399
439
|
// src/response/StructuredResponse/StructuredResponse.tsx
|
|
440
|
+
var import_react_markdown2 = __toESM(require("react-markdown"), 1);
|
|
441
|
+
var import_rehype_sanitize2 = __toESM(require("rehype-sanitize"), 1);
|
|
400
442
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
401
443
|
function tryParse(value) {
|
|
402
444
|
if (value === void 0 || value === null) return null;
|
|
@@ -409,6 +451,25 @@ function tryParse(value) {
|
|
|
409
451
|
}
|
|
410
452
|
return value;
|
|
411
453
|
}
|
|
454
|
+
function InlineMarkdown({ text }) {
|
|
455
|
+
return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
456
|
+
import_react_markdown2.default,
|
|
457
|
+
{
|
|
458
|
+
rehypePlugins: [import_rehype_sanitize2.default],
|
|
459
|
+
components: {
|
|
460
|
+
// Unwrap block-level <p> so content stays inline within its parent
|
|
461
|
+
p: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children }),
|
|
462
|
+
strong: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("strong", { className: "font-semibold", children }),
|
|
463
|
+
em: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("em", { className: "italic", children }),
|
|
464
|
+
code: ({ children }) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children }),
|
|
465
|
+
// Prevent block elements that would break layout
|
|
466
|
+
script: () => null,
|
|
467
|
+
iframe: () => null
|
|
468
|
+
},
|
|
469
|
+
children: text
|
|
470
|
+
}
|
|
471
|
+
);
|
|
472
|
+
}
|
|
412
473
|
function renderSteps(data) {
|
|
413
474
|
const steps = tryParse(data.steps);
|
|
414
475
|
if (!steps || !Array.isArray(steps)) return null;
|
|
@@ -421,7 +482,7 @@ function renderSteps(data) {
|
|
|
421
482
|
children: i + 1
|
|
422
483
|
}
|
|
423
484
|
),
|
|
424
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-text-primary leading-relaxed", children: step })
|
|
485
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-text-primary leading-relaxed", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(InlineMarkdown, { text: step }) })
|
|
425
486
|
] }, i)) });
|
|
426
487
|
}
|
|
427
488
|
function renderTable(data) {
|
|
@@ -487,7 +548,7 @@ function renderList(data) {
|
|
|
487
548
|
title && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: "text-xs font-semibold uppercase tracking-wider text-text-secondary mb-1", children: title }),
|
|
488
549
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("ul", { className: "flex flex-col gap-1.5", children: items.map((item, i) => /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("li", { className: "flex items-start gap-2.5", children: [
|
|
489
550
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-accent", "aria-hidden": "true" }),
|
|
490
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-text-primary leading-relaxed", children: item })
|
|
551
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: "text-sm text-text-primary leading-relaxed", children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(InlineMarkdown, { text: item }) })
|
|
491
552
|
] }, i)) })
|
|
492
553
|
] });
|
|
493
554
|
}
|
|
@@ -926,24 +987,46 @@ function MessageBubble({
|
|
|
926
987
|
var import_jsx_runtime8 = require("react/jsx-runtime");
|
|
927
988
|
function MessageThread({ messages, streamingSlot, showAgent, showSources, showConfidence, showVerification, hideLastAssistant, userBubbleClassName, className }) {
|
|
928
989
|
const scrollRef = (0, import_react4.useRef)(null);
|
|
929
|
-
const
|
|
930
|
-
const isProgrammaticScroll = (0, import_react4.useRef)(false);
|
|
990
|
+
const shouldAutoScroll = (0, import_react4.useRef)(true);
|
|
931
991
|
const hasStreaming = !!streamingSlot;
|
|
932
992
|
const scrollToBottom = (0, import_react4.useCallback)(() => {
|
|
933
993
|
const el = scrollRef.current;
|
|
934
|
-
if (el &&
|
|
935
|
-
isProgrammaticScroll.current = true;
|
|
994
|
+
if (el && shouldAutoScroll.current) {
|
|
936
995
|
el.scrollTop = el.scrollHeight;
|
|
937
996
|
}
|
|
938
997
|
}, []);
|
|
998
|
+
(0, import_react4.useEffect)(() => {
|
|
999
|
+
const el = scrollRef.current;
|
|
1000
|
+
if (!el) return;
|
|
1001
|
+
const onWheel = (e) => {
|
|
1002
|
+
if (e.deltaY < 0) {
|
|
1003
|
+
shouldAutoScroll.current = false;
|
|
1004
|
+
}
|
|
1005
|
+
};
|
|
1006
|
+
const onPointerDown = () => {
|
|
1007
|
+
el.dataset.userPointer = "1";
|
|
1008
|
+
};
|
|
1009
|
+
const onPointerUp = () => {
|
|
1010
|
+
delete el.dataset.userPointer;
|
|
1011
|
+
};
|
|
1012
|
+
el.addEventListener("wheel", onWheel, { passive: true });
|
|
1013
|
+
el.addEventListener("pointerdown", onPointerDown);
|
|
1014
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
1015
|
+
return () => {
|
|
1016
|
+
el.removeEventListener("wheel", onWheel);
|
|
1017
|
+
el.removeEventListener("pointerdown", onPointerDown);
|
|
1018
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
1019
|
+
};
|
|
1020
|
+
}, []);
|
|
939
1021
|
const handleScroll = (0, import_react4.useCallback)(() => {
|
|
940
|
-
if (isProgrammaticScroll.current) {
|
|
941
|
-
isProgrammaticScroll.current = false;
|
|
942
|
-
return;
|
|
943
|
-
}
|
|
944
1022
|
const el = scrollRef.current;
|
|
945
1023
|
if (!el) return;
|
|
946
|
-
|
|
1024
|
+
const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
|
|
1025
|
+
if (nearBottom) {
|
|
1026
|
+
shouldAutoScroll.current = true;
|
|
1027
|
+
} else if (el.dataset.userPointer) {
|
|
1028
|
+
shouldAutoScroll.current = false;
|
|
1029
|
+
}
|
|
947
1030
|
}, []);
|
|
948
1031
|
(0, import_react4.useEffect)(scrollToBottom, [messages.length, scrollToBottom]);
|
|
949
1032
|
(0, import_react4.useEffect)(() => {
|
|
@@ -956,6 +1039,11 @@ function MessageThread({ messages, streamingSlot, showAgent, showSources, showCo
|
|
|
956
1039
|
raf = requestAnimationFrame(tick);
|
|
957
1040
|
return () => cancelAnimationFrame(raf);
|
|
958
1041
|
}, [hasStreaming, scrollToBottom]);
|
|
1042
|
+
(0, import_react4.useEffect)(() => {
|
|
1043
|
+
if (!hasStreaming) {
|
|
1044
|
+
shouldAutoScroll.current = true;
|
|
1045
|
+
}
|
|
1046
|
+
}, [hasStreaming]);
|
|
959
1047
|
return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
|
|
960
1048
|
"div",
|
|
961
1049
|
{
|
|
@@ -1087,6 +1175,7 @@ function AttachmentPreview({
|
|
|
1087
1175
|
}
|
|
1088
1176
|
function MessageComposer({
|
|
1089
1177
|
onSend,
|
|
1178
|
+
onStop,
|
|
1090
1179
|
isLoading = false,
|
|
1091
1180
|
placeholder = "Type a message...",
|
|
1092
1181
|
className
|
|
@@ -1296,16 +1385,16 @@ function MessageComposer({
|
|
|
1296
1385
|
"button",
|
|
1297
1386
|
{
|
|
1298
1387
|
type: "button",
|
|
1299
|
-
onClick: handleSend,
|
|
1300
|
-
disabled: !canSend,
|
|
1301
|
-
"aria-label": "Send message",
|
|
1388
|
+
onClick: isLoading && onStop ? onStop : handleSend,
|
|
1389
|
+
disabled: !canSend && !isLoading,
|
|
1390
|
+
"aria-label": isLoading ? "Stop generating" : "Send message",
|
|
1302
1391
|
className: (0, import_tailwind_merge6.twMerge)(
|
|
1303
1392
|
"absolute bottom-3 right-3",
|
|
1304
1393
|
"inline-flex items-center justify-center",
|
|
1305
1394
|
"w-9 h-9 rounded-full",
|
|
1306
1395
|
"transition-all duration-200",
|
|
1307
1396
|
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
|
|
1308
|
-
canSend ? "bg-accent text-white hover:bg-accent-hover active:scale-90 shadow-md shadow-accent/25" : isLoading ? "bg-text-muted/20 text-text-secondary hover:bg-text-muted/30" : "bg-transparent text-text-muted/40 cursor-default"
|
|
1397
|
+
canSend ? "bg-accent text-white hover:bg-accent-hover active:scale-90 shadow-md shadow-accent/25" : isLoading ? "bg-text-muted/20 text-text-secondary hover:bg-text-muted/30 cursor-pointer" : "bg-transparent text-text-muted/40 cursor-default"
|
|
1309
1398
|
),
|
|
1310
1399
|
children: isLoading ? /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(StopIcon, {}) : /* @__PURE__ */ (0, import_jsx_runtime9.jsx)(ArrowUpIcon, {})
|
|
1311
1400
|
}
|
|
@@ -1461,9 +1550,10 @@ var phaseLabels = {
|
|
|
1461
1550
|
verifying: "Verifying..."
|
|
1462
1551
|
};
|
|
1463
1552
|
var CURSOR_STYLES = `
|
|
1464
|
-
.sk-streaming-cursor > :not(ul,ol,blockquote):last-child::after,
|
|
1553
|
+
.sk-streaming-cursor > :not(ul,ol,blockquote,div:has(table)):last-child::after,
|
|
1465
1554
|
.sk-streaming-cursor > :is(ul,ol):last-child > li:last-child::after,
|
|
1466
|
-
.sk-streaming-cursor > blockquote:last-child > p:last-child::after
|
|
1555
|
+
.sk-streaming-cursor > blockquote:last-child > p:last-child::after,
|
|
1556
|
+
.sk-streaming-cursor > div:has(table):last-child table tbody tr:last-child td:last-child::after {
|
|
1467
1557
|
content: "";
|
|
1468
1558
|
display: inline-block;
|
|
1469
1559
|
width: 2px;
|
|
@@ -1597,7 +1687,7 @@ function AgentChat({
|
|
|
1597
1687
|
onQuestionSelect: handleQuestionSelect
|
|
1598
1688
|
}
|
|
1599
1689
|
),
|
|
1600
|
-
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MessageComposer, { onSend: handleSend, isLoading: state.isLoading })
|
|
1690
|
+
/* @__PURE__ */ (0, import_jsx_runtime12.jsx)(MessageComposer, { onSend: handleSend, onStop: actions.stop, isLoading: state.isLoading })
|
|
1601
1691
|
]
|
|
1602
1692
|
}
|
|
1603
1693
|
);
|
|
@@ -1618,14 +1708,14 @@ function ConversationList({
|
|
|
1618
1708
|
"nav",
|
|
1619
1709
|
{
|
|
1620
1710
|
"aria-label": "Conversation list",
|
|
1621
|
-
className: (0, import_tailwind_merge10.twMerge)("flex flex-col
|
|
1711
|
+
className: (0, import_tailwind_merge10.twMerge)("flex flex-col flex-1 min-h-0", className),
|
|
1622
1712
|
children: [
|
|
1623
|
-
onNew && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "
|
|
1713
|
+
onNew && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "px-5 pt-1 pb-3 border-b border-border", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
|
|
1624
1714
|
"button",
|
|
1625
1715
|
{
|
|
1626
1716
|
type: "button",
|
|
1627
1717
|
onClick: onNew,
|
|
1628
|
-
className: "w-full px-4 py-2
|
|
1718
|
+
className: "w-full px-4 py-2 rounded-lg text-sm font-medium border border-border text-text-secondary hover:text-text-primary hover:bg-surface hover:border-border-strong transition-colors duration-150",
|
|
1629
1719
|
children: "New conversation"
|
|
1630
1720
|
}
|
|
1631
1721
|
) }),
|
|
@@ -1636,9 +1726,9 @@ function ConversationList({
|
|
|
1636
1726
|
"li",
|
|
1637
1727
|
{
|
|
1638
1728
|
className: (0, import_tailwind_merge10.twMerge)(
|
|
1639
|
-
"flex items-start
|
|
1640
|
-
"hover:bg-surface",
|
|
1641
|
-
isActive
|
|
1729
|
+
"flex items-start transition-colors duration-150",
|
|
1730
|
+
"hover:bg-surface-raised",
|
|
1731
|
+
isActive ? "bg-accent-subtlest border-l-[3px] border-l-accent" : "border-l-[3px] border-l-transparent"
|
|
1642
1732
|
),
|
|
1643
1733
|
children: [
|
|
1644
1734
|
/* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
@@ -1647,10 +1737,10 @@ function ConversationList({
|
|
|
1647
1737
|
type: "button",
|
|
1648
1738
|
onClick: () => onSelect(conversation.id),
|
|
1649
1739
|
"aria-current": isActive ? "true" : void 0,
|
|
1650
|
-
className: "flex-1 min-w-0 text-left px-
|
|
1740
|
+
className: "flex-1 min-w-0 text-left px-5 py-2.5",
|
|
1651
1741
|
children: [
|
|
1652
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-sm font-medium text-
|
|
1653
|
-
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-xs text-
|
|
1742
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-sm font-medium text-text-primary truncate", children: conversation.title }),
|
|
1743
|
+
/* @__PURE__ */ (0, import_jsx_runtime13.jsx)("div", { className: "text-xs text-text-muted truncate mt-0.5 leading-relaxed", children: conversation.lastMessage })
|
|
1654
1744
|
]
|
|
1655
1745
|
}
|
|
1656
1746
|
),
|
|
@@ -1660,7 +1750,7 @@ function ConversationList({
|
|
|
1660
1750
|
type: "button",
|
|
1661
1751
|
onClick: () => onDelete(conversation.id),
|
|
1662
1752
|
"aria-label": `Delete ${conversation.title}`,
|
|
1663
|
-
className: "shrink-0 p-1.5 m-2 rounded-lg text-
|
|
1753
|
+
className: "shrink-0 p-1.5 m-2 rounded-lg text-text-muted hover:text-status-error hover:bg-status-error/10 transition-colors duration-150",
|
|
1664
1754
|
children: /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(
|
|
1665
1755
|
"svg",
|
|
1666
1756
|
{
|
|
@@ -1687,7 +1777,7 @@ function ConversationList({
|
|
|
1687
1777
|
conversation.id
|
|
1688
1778
|
);
|
|
1689
1779
|
}),
|
|
1690
|
-
conversations.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { className: "px-
|
|
1780
|
+
conversations.length === 0 && /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("li", { className: "px-5 py-12 text-center", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-sm text-text-muted font-body", children: "No conversations yet" }) })
|
|
1691
1781
|
] })
|
|
1692
1782
|
]
|
|
1693
1783
|
}
|