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