barreloflube commited on
Commit
9249538
·
1 Parent(s): 12621bc

feat: add stop generation functionality and UI improvements

Browse files
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.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: "++id, title, createdAt, updatedAt, model, embedding_model, enabled_tools, messages",
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="flex flex-row-reverse flex-wrap-reverse gap-1 p-1">
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={onSendMessage}
74
- disabled={isGenerating}
 
 
 
 
 
 
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 z-50 bg-background/80 backdrop-blur-sm"
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 {