Commit
·
9249538
1
Parent(s):
12621bc
feat: add stop generation functionality and UI improvements
Browse files- package-lock.json +0 -0
- package.json +1 -2
- src/lib/chat/memory.ts +1 -1
- src/pages/chat/components/DocumentBadgesScrollArea.tsx +4 -2
- src/pages/chat/components/Input.tsx +10 -2
- src/pages/chat/components/Messages.tsx +1 -1
- src/pages/chat/page.tsx +6 -0
- src/pages/chat/types.ts +1 -0
package-lock.json
ADDED
The diff for this file is too large to render.
See raw diff
|
|
package.json
CHANGED
@@ -2,7 +2,6 @@
|
|
2 |
"name": "react-vite-ui",
|
3 |
"private": true,
|
4 |
"version": "0.0.1",
|
5 |
-
"homepage": "https://mantrakp04.github.io/sheer",
|
6 |
"type": "module",
|
7 |
"scripts": {
|
8 |
"dev": "vite",
|
@@ -51,7 +50,7 @@
|
|
51 |
"buffer": "^6.0.3",
|
52 |
"class-variance-authority": "^0.7.1",
|
53 |
"clsx": "^2.1.1",
|
54 |
-
"cmdk": "1.0.
|
55 |
"date-fns": "^4.1.0",
|
56 |
"dexie": "^4.0.11",
|
57 |
"dexie-react-hooks": "^1.1.7",
|
|
|
2 |
"name": "react-vite-ui",
|
3 |
"private": true,
|
4 |
"version": "0.0.1",
|
|
|
5 |
"type": "module",
|
6 |
"scripts": {
|
7 |
"dev": "vite",
|
|
|
50 |
"buffer": "^6.0.3",
|
51 |
"class-variance-authority": "^0.7.1",
|
52 |
"clsx": "^2.1.1",
|
53 |
+
"cmdk": "^1.0.4",
|
54 |
"date-fns": "^4.1.0",
|
55 |
"dexie": "^4.0.11",
|
56 |
"dexie-react-hooks": "^1.1.7",
|
src/lib/chat/memory.ts
CHANGED
@@ -17,7 +17,7 @@ export class ChatHistoryDB extends Dexie {
|
|
17 |
constructor() {
|
18 |
super("chat_history");
|
19 |
this.version(1).stores({
|
20 |
-
sessions: "
|
21 |
});
|
22 |
}
|
23 |
}
|
|
|
17 |
constructor() {
|
18 |
super("chat_history");
|
19 |
this.version(1).stores({
|
20 |
+
sessions: "id, title, createdAt, updatedAt, model, embedding_model, enabled_tools, messages",
|
21 |
});
|
22 |
}
|
23 |
}
|
src/pages/chat/components/DocumentBadgesScrollArea.tsx
CHANGED
@@ -11,6 +11,7 @@ interface DocumentBadgesScrollAreaProps {
|
|
11 |
removeable?: boolean;
|
12 |
maxHeight?: string;
|
13 |
className?: string;
|
|
|
14 |
}
|
15 |
|
16 |
export const DocumentBadgesScrollArea = React.memo(({
|
@@ -19,10 +20,11 @@ export const DocumentBadgesScrollArea = React.memo(({
|
|
19 |
onRemove,
|
20 |
removeable = true,
|
21 |
maxHeight = "100px",
|
22 |
-
className = ""
|
|
|
23 |
}: DocumentBadgesScrollAreaProps) => (
|
24 |
<ScrollArea className={cn("w-full", className)} style={{ maxHeight }}>
|
25 |
-
<div className=
|
26 |
{documents.map((document) => (
|
27 |
<DocumentBadge
|
28 |
key={document.id}
|
|
|
11 |
removeable?: boolean;
|
12 |
maxHeight?: string;
|
13 |
className?: string;
|
14 |
+
rowReverse?: boolean;
|
15 |
}
|
16 |
|
17 |
export const DocumentBadgesScrollArea = React.memo(({
|
|
|
20 |
onRemove,
|
21 |
removeable = true,
|
22 |
maxHeight = "100px",
|
23 |
+
className = "",
|
24 |
+
rowReverse = true,
|
25 |
}: DocumentBadgesScrollAreaProps) => (
|
26 |
<ScrollArea className={cn("w-full", className)} style={{ maxHeight }}>
|
27 |
+
<div className={`flex ${rowReverse ? "flex-row-reverse" : "flex-row"} flex-wrap-reverse gap-1 p-1`}>
|
28 |
{documents.map((document) => (
|
29 |
<DocumentBadge
|
30 |
key={document.id}
|
src/pages/chat/components/Input.tsx
CHANGED
@@ -25,6 +25,7 @@ export const Input = React.memo(({
|
|
25 |
handleAttachmentRemove,
|
26 |
selectedModelName,
|
27 |
isGenerating,
|
|
|
28 |
}: InputProps) => {
|
29 |
return (
|
30 |
<div className="flex flex-col w-1/2 mx-auto bg-muted rounded-md p-1">
|
@@ -34,6 +35,7 @@ export const Input = React.memo(({
|
|
34 |
onPreview={setPreviewDocument}
|
35 |
onRemove={handleAttachmentRemove}
|
36 |
maxHeight="100px"
|
|
|
37 |
/>
|
38 |
)}
|
39 |
<AutosizeTextarea
|
@@ -70,8 +72,14 @@ export const Input = React.memo(({
|
|
70 |
variant="default"
|
71 |
size="icon"
|
72 |
className="rounded-full"
|
73 |
-
onClick={
|
74 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
75 |
>
|
76 |
{isGenerating ? (
|
77 |
<Loader2 className="h-4 w-4 animate-spin" />
|
|
|
25 |
handleAttachmentRemove,
|
26 |
selectedModelName,
|
27 |
isGenerating,
|
28 |
+
stopGenerating,
|
29 |
}: InputProps) => {
|
30 |
return (
|
31 |
<div className="flex flex-col w-1/2 mx-auto bg-muted rounded-md p-1">
|
|
|
35 |
onPreview={setPreviewDocument}
|
36 |
onRemove={handleAttachmentRemove}
|
37 |
maxHeight="100px"
|
38 |
+
rowReverse={false}
|
39 |
/>
|
40 |
)}
|
41 |
<AutosizeTextarea
|
|
|
72 |
variant="default"
|
73 |
size="icon"
|
74 |
className="rounded-full"
|
75 |
+
onClick={() => {
|
76 |
+
if (isGenerating) {
|
77 |
+
// stop the generation
|
78 |
+
stopGenerating();
|
79 |
+
} else {
|
80 |
+
onSendMessage();
|
81 |
+
}
|
82 |
+
}}
|
83 |
>
|
84 |
{isGenerating ? (
|
85 |
<Loader2 className="h-4 w-4 animate-spin" />
|
src/pages/chat/components/Messages.tsx
CHANGED
@@ -99,7 +99,7 @@ export const Messages = React.memo(({
|
|
99 |
<Button
|
100 |
variant="secondary"
|
101 |
size="icon"
|
102 |
-
className="absolute left-1/2 -translate-x-1/2 bottom-4 rounded-full shadow-md hover:bg-accent
|
103 |
onClick={scrollToBottom}
|
104 |
>
|
105 |
<ArrowDown className="h-4 w-4" />
|
|
|
99 |
<Button
|
100 |
variant="secondary"
|
101 |
size="icon"
|
102 |
+
className="absolute left-1/2 -translate-x-1/2 z-50 bottom-4 rounded-full shadow-md hover:bg-accent bg-background/80 backdrop-blur-sm"
|
103 |
onClick={scrollToBottom}
|
104 |
>
|
105 |
<ArrowDown className="h-4 w-4" />
|
src/pages/chat/page.tsx
CHANGED
@@ -174,6 +174,11 @@ export function ChatPage() {
|
|
174 |
generateMessage(id, content, [], isGenerating, setIsGenerating, setStreamingHumanMessage, setStreamingAIMessageChunks, chatManager, setInput, setAttachments);
|
175 |
}, [id, chatSession, isGenerating, chatHistoryDB.sessions, chatManager]);
|
176 |
|
|
|
|
|
|
|
|
|
|
|
177 |
return (
|
178 |
<div className="flex flex-col h-screen p-2">
|
179 |
<Messages
|
@@ -205,6 +210,7 @@ export function ChatPage() {
|
|
205 |
handleAttachmentRemove={handleAttachmentRemove}
|
206 |
selectedModelName={selectedModelName}
|
207 |
isGenerating={isGenerating}
|
|
|
208 |
/>
|
209 |
<FilePreviewDialog
|
210 |
document={previewDocument}
|
|
|
174 |
generateMessage(id, content, [], isGenerating, setIsGenerating, setStreamingHumanMessage, setStreamingAIMessageChunks, chatManager, setInput, setAttachments);
|
175 |
}, [id, chatSession, isGenerating, chatHistoryDB.sessions, chatManager]);
|
176 |
|
177 |
+
const stopGenerating = React.useCallback(() => {
|
178 |
+
chatManager.controller.abort();
|
179 |
+
setIsGenerating(false);
|
180 |
+
}, [chatManager, setIsGenerating]);
|
181 |
+
|
182 |
return (
|
183 |
<div className="flex flex-col h-screen p-2">
|
184 |
<Messages
|
|
|
210 |
handleAttachmentRemove={handleAttachmentRemove}
|
211 |
selectedModelName={selectedModelName}
|
212 |
isGenerating={isGenerating}
|
213 |
+
stopGenerating={stopGenerating}
|
214 |
/>
|
215 |
<FilePreviewDialog
|
216 |
document={previewDocument}
|
src/pages/chat/types.ts
CHANGED
@@ -39,6 +39,7 @@ export interface InputProps {
|
|
39 |
handleAttachmentFileUpload: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
40 |
handleAttachmentUrlUpload: () => void;
|
41 |
handleAttachmentRemove: (docId: string) => void;
|
|
|
42 |
}
|
43 |
|
44 |
export interface FilePreviewDialogProps {
|
|
|
39 |
handleAttachmentFileUpload: (event: React.ChangeEvent<HTMLInputElement>) => void;
|
40 |
handleAttachmentUrlUpload: () => void;
|
41 |
handleAttachmentRemove: (docId: string) => void;
|
42 |
+
stopGenerating: () => void;
|
43 |
}
|
44 |
|
45 |
export interface FilePreviewDialogProps {
|