@surf-kit/agent 0.3.0 → 0.4.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 +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/chat/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { a as ChatMessage, A as Attachment, b as ConversationSummary } from '../chat-
|
|
2
|
+
import { a as ChatMessage, A as Attachment, b as ConversationSummary } from '../chat-CcKc6OAR.js';
|
|
3
3
|
import React from 'react';
|
|
4
4
|
import '../agent-BNSmiexZ.js';
|
|
5
5
|
|
|
@@ -47,11 +47,12 @@ declare function MessageBubble({ message, showAgent, showSources, showConfidence
|
|
|
47
47
|
|
|
48
48
|
type MessageComposerProps = {
|
|
49
49
|
onSend: (content: string, attachments?: Attachment[]) => void;
|
|
50
|
+
onStop?: () => void;
|
|
50
51
|
isLoading?: boolean;
|
|
51
52
|
placeholder?: string;
|
|
52
53
|
className?: string;
|
|
53
54
|
};
|
|
54
|
-
declare function MessageComposer({ onSend, isLoading, placeholder, className, }: MessageComposerProps): react_jsx_runtime.JSX.Element;
|
|
55
|
+
declare function MessageComposer({ onSend, onStop, isLoading, placeholder, className, }: MessageComposerProps): react_jsx_runtime.JSX.Element;
|
|
55
56
|
|
|
56
57
|
type WelcomeScreenProps = {
|
|
57
58
|
title?: string;
|
package/dist/chat/index.js
CHANGED
|
@@ -34,6 +34,8 @@ function reducer(state, action) {
|
|
|
34
34
|
return { ...state, streamPhase: action.phase };
|
|
35
35
|
case "STREAM_CONTENT":
|
|
36
36
|
return { ...state, streamingContent: state.streamingContent + action.content };
|
|
37
|
+
case "STREAM_CONTENT_RESET":
|
|
38
|
+
return { ...state, streamingContent: "" };
|
|
37
39
|
case "STREAM_AGENT":
|
|
38
40
|
return { ...state, streamingAgent: action.agent };
|
|
39
41
|
case "SEND_SUCCESS":
|
|
@@ -79,6 +81,7 @@ function useAgentChat(config) {
|
|
|
79
81
|
configRef.current = config;
|
|
80
82
|
const lastUserMessageRef = useRef(null);
|
|
81
83
|
const lastUserAttachmentsRef = useRef(void 0);
|
|
84
|
+
const abortControllerRef = useRef(null);
|
|
82
85
|
const sendMessage = useCallback(
|
|
83
86
|
async (content, attachments) => {
|
|
84
87
|
const { apiUrl, streamPath = "/chat/stream", headers: headersOrFn, timeout = 3e4, bodyExtra } = configRef.current;
|
|
@@ -94,7 +97,15 @@ function useAgentChat(config) {
|
|
|
94
97
|
};
|
|
95
98
|
dispatch({ type: "SEND_START", message: userMessage });
|
|
96
99
|
const controller = new AbortController();
|
|
100
|
+
abortControllerRef.current = controller;
|
|
97
101
|
const timeoutId = setTimeout(() => controller.abort(), timeout);
|
|
102
|
+
const ctx = {
|
|
103
|
+
accumulatedContent: "",
|
|
104
|
+
agentResponse: null,
|
|
105
|
+
capturedAgent: null,
|
|
106
|
+
capturedConversationId: null,
|
|
107
|
+
hadStreamError: false
|
|
108
|
+
};
|
|
98
109
|
try {
|
|
99
110
|
const url = `${apiUrl}${streamPath}`;
|
|
100
111
|
const mergedHeaders = {
|
|
@@ -115,13 +126,6 @@ function useAgentChat(config) {
|
|
|
115
126
|
}));
|
|
116
127
|
}
|
|
117
128
|
const body = JSON.stringify(requestBody);
|
|
118
|
-
const ctx = {
|
|
119
|
-
accumulatedContent: "",
|
|
120
|
-
agentResponse: null,
|
|
121
|
-
capturedAgent: null,
|
|
122
|
-
capturedConversationId: null,
|
|
123
|
-
hadStreamError: false
|
|
124
|
-
};
|
|
125
129
|
const handleEvent = (event) => {
|
|
126
130
|
switch (event.type) {
|
|
127
131
|
case "agent":
|
|
@@ -135,6 +139,10 @@ function useAgentChat(config) {
|
|
|
135
139
|
ctx.accumulatedContent += event.content;
|
|
136
140
|
dispatch({ type: "STREAM_CONTENT", content: event.content });
|
|
137
141
|
break;
|
|
142
|
+
case "delta_reset":
|
|
143
|
+
ctx.accumulatedContent = "";
|
|
144
|
+
dispatch({ type: "STREAM_CONTENT_RESET" });
|
|
145
|
+
break;
|
|
138
146
|
case "done":
|
|
139
147
|
ctx.agentResponse = event.response;
|
|
140
148
|
ctx.capturedConversationId = event.conversation_id ?? null;
|
|
@@ -218,10 +226,26 @@ function useAgentChat(config) {
|
|
|
218
226
|
} catch (err) {
|
|
219
227
|
clearTimeout(timeoutId);
|
|
220
228
|
if (err.name === "AbortError") {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
229
|
+
if (ctx.accumulatedContent) {
|
|
230
|
+
const partialMessage = {
|
|
231
|
+
id: generateMessageId(),
|
|
232
|
+
role: "assistant",
|
|
233
|
+
content: ctx.accumulatedContent,
|
|
234
|
+
agent: ctx.capturedAgent ?? void 0,
|
|
235
|
+
timestamp: /* @__PURE__ */ new Date()
|
|
236
|
+
};
|
|
237
|
+
dispatch({
|
|
238
|
+
type: "SEND_SUCCESS",
|
|
239
|
+
message: partialMessage,
|
|
240
|
+
streamingContent: ctx.accumulatedContent,
|
|
241
|
+
conversationId: ctx.capturedConversationId
|
|
242
|
+
});
|
|
243
|
+
} else {
|
|
244
|
+
dispatch({
|
|
245
|
+
type: "SEND_ERROR",
|
|
246
|
+
error: { code: "ABORTED", message: "Request stopped", retryable: true }
|
|
247
|
+
});
|
|
248
|
+
}
|
|
225
249
|
} else {
|
|
226
250
|
dispatch({
|
|
227
251
|
type: "SEND_ERROR",
|
|
@@ -232,6 +256,8 @@ function useAgentChat(config) {
|
|
|
232
256
|
}
|
|
233
257
|
});
|
|
234
258
|
}
|
|
259
|
+
} finally {
|
|
260
|
+
abortControllerRef.current = null;
|
|
235
261
|
}
|
|
236
262
|
},
|
|
237
263
|
[state.conversationId]
|
|
@@ -259,6 +285,9 @@ function useAgentChat(config) {
|
|
|
259
285
|
await sendMessage(lastUserMessageRef.current, lastUserAttachmentsRef.current);
|
|
260
286
|
}
|
|
261
287
|
}, [sendMessage]);
|
|
288
|
+
const stop = useCallback(() => {
|
|
289
|
+
abortControllerRef.current?.abort();
|
|
290
|
+
}, []);
|
|
262
291
|
const reset = useCallback(() => {
|
|
263
292
|
dispatch({ type: "RESET" });
|
|
264
293
|
lastUserMessageRef.current = null;
|
|
@@ -270,6 +299,7 @@ function useAgentChat(config) {
|
|
|
270
299
|
loadConversation,
|
|
271
300
|
submitFeedback,
|
|
272
301
|
retry,
|
|
302
|
+
stop,
|
|
273
303
|
reset
|
|
274
304
|
};
|
|
275
305
|
return { state, actions };
|
|
@@ -289,6 +319,7 @@ import { Badge as Badge2 } from "@surf-kit/core";
|
|
|
289
319
|
import React from "react";
|
|
290
320
|
import ReactMarkdown from "react-markdown";
|
|
291
321
|
import rehypeSanitize from "rehype-sanitize";
|
|
322
|
+
import remarkGfm from "remark-gfm";
|
|
292
323
|
import { twMerge } from "tailwind-merge";
|
|
293
324
|
import { jsx } from "react/jsx-runtime";
|
|
294
325
|
function normalizeMarkdownLists(content) {
|
|
@@ -313,6 +344,10 @@ function ResponseMessage({ content, className }) {
|
|
|
313
344
|
"[&_pre]:bg-surface-raised [&_pre]:border [&_pre]:border-border [&_pre]:rounded-xl [&_pre]:p-4 [&_pre]:overflow-x-auto",
|
|
314
345
|
"[&_hr]:my-3 [&_hr]:border-border",
|
|
315
346
|
"[&_blockquote]:border-l-2 [&_blockquote]:border-border-strong [&_blockquote]:pl-4 [&_blockquote]:text-text-secondary",
|
|
347
|
+
"[&_table]:w-full [&_table]:text-sm [&_table]:border-collapse [&_table]:my-2",
|
|
348
|
+
"[&_thead]:border-b [&_thead]:border-border",
|
|
349
|
+
"[&_th]:text-left [&_th]:px-2 [&_th]:py-1.5 [&_th]:font-semibold",
|
|
350
|
+
"[&_td]:px-2 [&_td]:py-1.5 [&_td]:border-t [&_td]:border-border/50",
|
|
316
351
|
"[&_a]:text-accent [&_a]:underline-offset-2 [&_a]:hover:text-accent/80",
|
|
317
352
|
className
|
|
318
353
|
),
|
|
@@ -320,6 +355,7 @@ function ResponseMessage({ content, className }) {
|
|
|
320
355
|
children: /* @__PURE__ */ jsx(
|
|
321
356
|
ReactMarkdown,
|
|
322
357
|
{
|
|
358
|
+
remarkPlugins: [remarkGfm],
|
|
323
359
|
rehypePlugins: [rehypeSanitize],
|
|
324
360
|
components: {
|
|
325
361
|
script: () => null,
|
|
@@ -345,7 +381,11 @@ function ResponseMessage({ content, className }) {
|
|
|
345
381
|
h2: ({ children }) => /* @__PURE__ */ jsx("h2", { className: "text-sm font-bold mt-3 mb-1", children }),
|
|
346
382
|
h3: ({ children }) => /* @__PURE__ */ jsx("h3", { className: "text-sm font-semibold mt-2 mb-1", children }),
|
|
347
383
|
hr: () => /* @__PURE__ */ jsx("hr", { className: "my-3 border-border" }),
|
|
348
|
-
code: ({ children }) => /* @__PURE__ */ jsx("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children })
|
|
384
|
+
code: ({ children }) => /* @__PURE__ */ jsx("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children }),
|
|
385
|
+
table: ({ children }) => /* @__PURE__ */ jsx("div", { className: "overflow-x-auto my-2", children: /* @__PURE__ */ jsx("table", { className: "w-full text-sm border-collapse", children }) }),
|
|
386
|
+
thead: ({ children }) => /* @__PURE__ */ jsx("thead", { className: "border-b border-border", children }),
|
|
387
|
+
th: ({ children }) => /* @__PURE__ */ jsx("th", { className: "text-left px-2 py-1.5 font-semibold", children }),
|
|
388
|
+
td: ({ children }) => /* @__PURE__ */ jsx("td", { className: "px-2 py-1.5 border-t border-border/50", children })
|
|
349
389
|
},
|
|
350
390
|
children: normalizeMarkdownLists(content)
|
|
351
391
|
}
|
|
@@ -355,7 +395,9 @@ function ResponseMessage({ content, className }) {
|
|
|
355
395
|
}
|
|
356
396
|
|
|
357
397
|
// src/response/StructuredResponse/StructuredResponse.tsx
|
|
358
|
-
import
|
|
398
|
+
import ReactMarkdown2 from "react-markdown";
|
|
399
|
+
import rehypeSanitize2 from "rehype-sanitize";
|
|
400
|
+
import { Fragment, jsx as jsx2, jsxs } from "react/jsx-runtime";
|
|
359
401
|
function tryParse(value) {
|
|
360
402
|
if (value === void 0 || value === null) return null;
|
|
361
403
|
if (typeof value === "string") {
|
|
@@ -367,6 +409,25 @@ function tryParse(value) {
|
|
|
367
409
|
}
|
|
368
410
|
return value;
|
|
369
411
|
}
|
|
412
|
+
function InlineMarkdown({ text }) {
|
|
413
|
+
return /* @__PURE__ */ jsx2(
|
|
414
|
+
ReactMarkdown2,
|
|
415
|
+
{
|
|
416
|
+
rehypePlugins: [rehypeSanitize2],
|
|
417
|
+
components: {
|
|
418
|
+
// Unwrap block-level <p> so content stays inline within its parent
|
|
419
|
+
p: ({ children }) => /* @__PURE__ */ jsx2(Fragment, { children }),
|
|
420
|
+
strong: ({ children }) => /* @__PURE__ */ jsx2("strong", { className: "font-semibold", children }),
|
|
421
|
+
em: ({ children }) => /* @__PURE__ */ jsx2("em", { className: "italic", children }),
|
|
422
|
+
code: ({ children }) => /* @__PURE__ */ jsx2("code", { className: "bg-surface-sunken rounded px-1 py-0.5 text-xs font-mono", children }),
|
|
423
|
+
// Prevent block elements that would break layout
|
|
424
|
+
script: () => null,
|
|
425
|
+
iframe: () => null
|
|
426
|
+
},
|
|
427
|
+
children: text
|
|
428
|
+
}
|
|
429
|
+
);
|
|
430
|
+
}
|
|
370
431
|
function renderSteps(data) {
|
|
371
432
|
const steps = tryParse(data.steps);
|
|
372
433
|
if (!steps || !Array.isArray(steps)) return null;
|
|
@@ -379,7 +440,7 @@ function renderSteps(data) {
|
|
|
379
440
|
children: i + 1
|
|
380
441
|
}
|
|
381
442
|
),
|
|
382
|
-
/* @__PURE__ */ jsx2("span", { className: "text-sm text-text-primary leading-relaxed", children: step })
|
|
443
|
+
/* @__PURE__ */ jsx2("span", { className: "text-sm text-text-primary leading-relaxed", children: /* @__PURE__ */ jsx2(InlineMarkdown, { text: step }) })
|
|
383
444
|
] }, i)) });
|
|
384
445
|
}
|
|
385
446
|
function renderTable(data) {
|
|
@@ -445,7 +506,7 @@ function renderList(data) {
|
|
|
445
506
|
title && /* @__PURE__ */ jsx2("p", { className: "text-xs font-semibold uppercase tracking-wider text-text-secondary mb-1", children: title }),
|
|
446
507
|
/* @__PURE__ */ jsx2("ul", { className: "flex flex-col gap-1.5", children: items.map((item, i) => /* @__PURE__ */ jsxs("li", { className: "flex items-start gap-2.5", children: [
|
|
447
508
|
/* @__PURE__ */ jsx2("span", { className: "mt-1.5 h-1.5 w-1.5 shrink-0 rounded-full bg-accent", "aria-hidden": "true" }),
|
|
448
|
-
/* @__PURE__ */ jsx2("span", { className: "text-sm text-text-primary leading-relaxed", children: item })
|
|
509
|
+
/* @__PURE__ */ jsx2("span", { className: "text-sm text-text-primary leading-relaxed", children: /* @__PURE__ */ jsx2(InlineMarkdown, { text: item }) })
|
|
449
510
|
] }, i)) })
|
|
450
511
|
] });
|
|
451
512
|
}
|
|
@@ -884,24 +945,46 @@ function MessageBubble({
|
|
|
884
945
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
885
946
|
function MessageThread({ messages, streamingSlot, showAgent, showSources, showConfidence, showVerification, hideLastAssistant, userBubbleClassName, className }) {
|
|
886
947
|
const scrollRef = useRef2(null);
|
|
887
|
-
const
|
|
888
|
-
const isProgrammaticScroll = useRef2(false);
|
|
948
|
+
const shouldAutoScroll = useRef2(true);
|
|
889
949
|
const hasStreaming = !!streamingSlot;
|
|
890
950
|
const scrollToBottom = useCallback2(() => {
|
|
891
951
|
const el = scrollRef.current;
|
|
892
|
-
if (el &&
|
|
893
|
-
isProgrammaticScroll.current = true;
|
|
952
|
+
if (el && shouldAutoScroll.current) {
|
|
894
953
|
el.scrollTop = el.scrollHeight;
|
|
895
954
|
}
|
|
896
955
|
}, []);
|
|
956
|
+
useEffect(() => {
|
|
957
|
+
const el = scrollRef.current;
|
|
958
|
+
if (!el) return;
|
|
959
|
+
const onWheel = (e) => {
|
|
960
|
+
if (e.deltaY < 0) {
|
|
961
|
+
shouldAutoScroll.current = false;
|
|
962
|
+
}
|
|
963
|
+
};
|
|
964
|
+
const onPointerDown = () => {
|
|
965
|
+
el.dataset.userPointer = "1";
|
|
966
|
+
};
|
|
967
|
+
const onPointerUp = () => {
|
|
968
|
+
delete el.dataset.userPointer;
|
|
969
|
+
};
|
|
970
|
+
el.addEventListener("wheel", onWheel, { passive: true });
|
|
971
|
+
el.addEventListener("pointerdown", onPointerDown);
|
|
972
|
+
window.addEventListener("pointerup", onPointerUp);
|
|
973
|
+
return () => {
|
|
974
|
+
el.removeEventListener("wheel", onWheel);
|
|
975
|
+
el.removeEventListener("pointerdown", onPointerDown);
|
|
976
|
+
window.removeEventListener("pointerup", onPointerUp);
|
|
977
|
+
};
|
|
978
|
+
}, []);
|
|
897
979
|
const handleScroll = useCallback2(() => {
|
|
898
|
-
if (isProgrammaticScroll.current) {
|
|
899
|
-
isProgrammaticScroll.current = false;
|
|
900
|
-
return;
|
|
901
|
-
}
|
|
902
980
|
const el = scrollRef.current;
|
|
903
981
|
if (!el) return;
|
|
904
|
-
|
|
982
|
+
const nearBottom = el.scrollHeight - el.scrollTop - el.clientHeight < 80;
|
|
983
|
+
if (nearBottom) {
|
|
984
|
+
shouldAutoScroll.current = true;
|
|
985
|
+
} else if (el.dataset.userPointer) {
|
|
986
|
+
shouldAutoScroll.current = false;
|
|
987
|
+
}
|
|
905
988
|
}, []);
|
|
906
989
|
useEffect(scrollToBottom, [messages.length, scrollToBottom]);
|
|
907
990
|
useEffect(() => {
|
|
@@ -914,6 +997,11 @@ function MessageThread({ messages, streamingSlot, showAgent, showSources, showCo
|
|
|
914
997
|
raf = requestAnimationFrame(tick);
|
|
915
998
|
return () => cancelAnimationFrame(raf);
|
|
916
999
|
}, [hasStreaming, scrollToBottom]);
|
|
1000
|
+
useEffect(() => {
|
|
1001
|
+
if (!hasStreaming) {
|
|
1002
|
+
shouldAutoScroll.current = true;
|
|
1003
|
+
}
|
|
1004
|
+
}, [hasStreaming]);
|
|
917
1005
|
return /* @__PURE__ */ jsxs6(
|
|
918
1006
|
"div",
|
|
919
1007
|
{
|
|
@@ -1045,6 +1133,7 @@ function AttachmentPreview({
|
|
|
1045
1133
|
}
|
|
1046
1134
|
function MessageComposer({
|
|
1047
1135
|
onSend,
|
|
1136
|
+
onStop,
|
|
1048
1137
|
isLoading = false,
|
|
1049
1138
|
placeholder = "Type a message...",
|
|
1050
1139
|
className
|
|
@@ -1254,16 +1343,16 @@ function MessageComposer({
|
|
|
1254
1343
|
"button",
|
|
1255
1344
|
{
|
|
1256
1345
|
type: "button",
|
|
1257
|
-
onClick: handleSend,
|
|
1258
|
-
disabled: !canSend,
|
|
1259
|
-
"aria-label": "Send message",
|
|
1346
|
+
onClick: isLoading && onStop ? onStop : handleSend,
|
|
1347
|
+
disabled: !canSend && !isLoading,
|
|
1348
|
+
"aria-label": isLoading ? "Stop generating" : "Send message",
|
|
1260
1349
|
className: twMerge6(
|
|
1261
1350
|
"absolute bottom-3 right-3",
|
|
1262
1351
|
"inline-flex items-center justify-center",
|
|
1263
1352
|
"w-9 h-9 rounded-full",
|
|
1264
1353
|
"transition-all duration-200",
|
|
1265
1354
|
"focus-visible:outline-2 focus-visible:outline-offset-2 focus-visible:outline-accent",
|
|
1266
|
-
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"
|
|
1355
|
+
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"
|
|
1267
1356
|
),
|
|
1268
1357
|
children: isLoading ? /* @__PURE__ */ jsx9(StopIcon, {}) : /* @__PURE__ */ jsx9(ArrowUpIcon, {})
|
|
1269
1358
|
}
|
|
@@ -1419,9 +1508,10 @@ var phaseLabels = {
|
|
|
1419
1508
|
verifying: "Verifying..."
|
|
1420
1509
|
};
|
|
1421
1510
|
var CURSOR_STYLES = `
|
|
1422
|
-
.sk-streaming-cursor > :not(ul,ol,blockquote):last-child::after,
|
|
1511
|
+
.sk-streaming-cursor > :not(ul,ol,blockquote,div:has(table)):last-child::after,
|
|
1423
1512
|
.sk-streaming-cursor > :is(ul,ol):last-child > li:last-child::after,
|
|
1424
|
-
.sk-streaming-cursor > blockquote:last-child > p:last-child::after
|
|
1513
|
+
.sk-streaming-cursor > blockquote:last-child > p:last-child::after,
|
|
1514
|
+
.sk-streaming-cursor > div:has(table):last-child table tbody tr:last-child td:last-child::after {
|
|
1425
1515
|
content: "";
|
|
1426
1516
|
display: inline-block;
|
|
1427
1517
|
width: 2px;
|
|
@@ -1555,7 +1645,7 @@ function AgentChat({
|
|
|
1555
1645
|
onQuestionSelect: handleQuestionSelect
|
|
1556
1646
|
}
|
|
1557
1647
|
),
|
|
1558
|
-
/* @__PURE__ */ jsx12(MessageComposer, { onSend: handleSend, isLoading: state.isLoading })
|
|
1648
|
+
/* @__PURE__ */ jsx12(MessageComposer, { onSend: handleSend, onStop: actions.stop, isLoading: state.isLoading })
|
|
1559
1649
|
]
|
|
1560
1650
|
}
|
|
1561
1651
|
);
|
|
@@ -1576,14 +1666,14 @@ function ConversationList({
|
|
|
1576
1666
|
"nav",
|
|
1577
1667
|
{
|
|
1578
1668
|
"aria-label": "Conversation list",
|
|
1579
|
-
className: twMerge10("flex flex-col
|
|
1669
|
+
className: twMerge10("flex flex-col flex-1 min-h-0", className),
|
|
1580
1670
|
children: [
|
|
1581
|
-
onNew && /* @__PURE__ */ jsx13("div", { className: "
|
|
1671
|
+
onNew && /* @__PURE__ */ jsx13("div", { className: "px-5 pt-1 pb-3 border-b border-border", children: /* @__PURE__ */ jsx13(
|
|
1582
1672
|
"button",
|
|
1583
1673
|
{
|
|
1584
1674
|
type: "button",
|
|
1585
1675
|
onClick: onNew,
|
|
1586
|
-
className: "w-full px-4 py-2
|
|
1676
|
+
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",
|
|
1587
1677
|
children: "New conversation"
|
|
1588
1678
|
}
|
|
1589
1679
|
) }),
|
|
@@ -1594,9 +1684,9 @@ function ConversationList({
|
|
|
1594
1684
|
"li",
|
|
1595
1685
|
{
|
|
1596
1686
|
className: twMerge10(
|
|
1597
|
-
"flex items-start
|
|
1598
|
-
"hover:bg-surface",
|
|
1599
|
-
isActive
|
|
1687
|
+
"flex items-start transition-colors duration-150",
|
|
1688
|
+
"hover:bg-surface-raised",
|
|
1689
|
+
isActive ? "bg-accent-subtlest border-l-[3px] border-l-accent" : "border-l-[3px] border-l-transparent"
|
|
1600
1690
|
),
|
|
1601
1691
|
children: [
|
|
1602
1692
|
/* @__PURE__ */ jsxs11(
|
|
@@ -1605,10 +1695,10 @@ function ConversationList({
|
|
|
1605
1695
|
type: "button",
|
|
1606
1696
|
onClick: () => onSelect(conversation.id),
|
|
1607
1697
|
"aria-current": isActive ? "true" : void 0,
|
|
1608
|
-
className: "flex-1 min-w-0 text-left px-
|
|
1698
|
+
className: "flex-1 min-w-0 text-left px-5 py-2.5",
|
|
1609
1699
|
children: [
|
|
1610
|
-
/* @__PURE__ */ jsx13("div", { className: "text-sm font-medium text-
|
|
1611
|
-
/* @__PURE__ */ jsx13("div", { className: "text-xs text-
|
|
1700
|
+
/* @__PURE__ */ jsx13("div", { className: "text-sm font-medium text-text-primary truncate", children: conversation.title }),
|
|
1701
|
+
/* @__PURE__ */ jsx13("div", { className: "text-xs text-text-muted truncate mt-0.5 leading-relaxed", children: conversation.lastMessage })
|
|
1612
1702
|
]
|
|
1613
1703
|
}
|
|
1614
1704
|
),
|
|
@@ -1618,7 +1708,7 @@ function ConversationList({
|
|
|
1618
1708
|
type: "button",
|
|
1619
1709
|
onClick: () => onDelete(conversation.id),
|
|
1620
1710
|
"aria-label": `Delete ${conversation.title}`,
|
|
1621
|
-
className: "shrink-0 p-1.5 m-2 rounded-lg text-
|
|
1711
|
+
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",
|
|
1622
1712
|
children: /* @__PURE__ */ jsxs11(
|
|
1623
1713
|
"svg",
|
|
1624
1714
|
{
|
|
@@ -1645,7 +1735,7 @@ function ConversationList({
|
|
|
1645
1735
|
conversation.id
|
|
1646
1736
|
);
|
|
1647
1737
|
}),
|
|
1648
|
-
conversations.length === 0 && /* @__PURE__ */ jsx13("li", { className: "px-
|
|
1738
|
+
conversations.length === 0 && /* @__PURE__ */ jsx13("li", { className: "px-5 py-12 text-center", children: /* @__PURE__ */ jsx13("span", { className: "text-sm text-text-muted font-body", children: "No conversations yet" }) })
|
|
1649
1739
|
] })
|
|
1650
1740
|
]
|
|
1651
1741
|
}
|