barreloflube commited on
Commit
620331c
·
1 Parent(s): b2069e9

fix: Improve error handling and dynamic configuration for HuggingFace OAuth and chat memory

Browse files
src/lib/chat/memory.ts CHANGED
@@ -57,7 +57,7 @@ export class DexieChatMemory extends BaseChatMessageHistory {
57
  const chatModel = CHAT_MODELS.find((m) => m.model === this.config.default_chat_model);
58
  const embeddingModel = EMBEDDING_MODELS.find((m) => m.model === this.config.default_embedding_model);
59
 
60
- if (!chatModel || !embeddingModel) {
61
  throw new Error("Chat or embedding models are not configured.");
62
  }
63
 
@@ -67,7 +67,7 @@ export class DexieChatMemory extends BaseChatMessageHistory {
67
  createdAt: Date.now(),
68
  updatedAt: Date.now(),
69
  model: chatModel.model,
70
- embedding_model: embeddingModel.model,
71
  enabled_tools: [],
72
  messages: [],
73
  };
 
57
  const chatModel = CHAT_MODELS.find((m) => m.model === this.config.default_chat_model);
58
  const embeddingModel = EMBEDDING_MODELS.find((m) => m.model === this.config.default_embedding_model);
59
 
60
+ if (!chatModel) {
61
  throw new Error("Chat or embedding models are not configured.");
62
  }
63
 
 
67
  createdAt: Date.now(),
68
  updatedAt: Date.now(),
69
  model: chatModel.model,
70
+ embedding_model: embeddingModel?.model || '',
71
  enabled_tools: [],
72
  messages: [],
73
  };
src/pages/chat/components/Messages.tsx CHANGED
@@ -23,10 +23,17 @@ export const Messages = React.memo(({
23
  const { id } = useParams();
24
  const viewportRef = React.useRef<HTMLDivElement>(null);
25
  const [showScrollToBottom, setShowScrollToBottom] = React.useState(false);
 
26
 
27
  const handleScroll = React.useCallback((event: Event) => {
28
  const viewport = event.target as HTMLDivElement;
29
  const isNotAtBottom = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight > 10;
 
 
 
 
 
 
30
  setShowScrollToBottom(isNotAtBottom);
31
  }, []);
32
 
@@ -39,6 +46,7 @@ export const Messages = React.memo(({
39
  });
40
  }, []);
41
 
 
42
  React.useEffect(() => {
43
  const viewport = viewportRef.current;
44
  if (!viewport) return;
@@ -46,8 +54,76 @@ export const Messages = React.memo(({
46
  viewport.addEventListener('scroll', handleScroll);
47
  // Initial check for scroll position
48
  handleScroll({ target: viewport } as unknown as Event);
49
- return () => viewport.removeEventListener('scroll', handleScroll);
50
- }, [handleScroll]);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
51
 
52
  if (id === "new" || !messages) {
53
  return <div className="flex-1 min-h-0"><ScrollArea className="h-full" /></div>;
@@ -99,7 +175,7 @@ export const Messages = React.memo(({
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" />
 
23
  const { id } = useParams();
24
  const viewportRef = React.useRef<HTMLDivElement>(null);
25
  const [showScrollToBottom, setShowScrollToBottom] = React.useState(false);
26
+ const initialLoadRef = React.useRef(true);
27
 
28
  const handleScroll = React.useCallback((event: Event) => {
29
  const viewport = event.target as HTMLDivElement;
30
  const isNotAtBottom = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight > 10;
31
+ console.log('Scroll position:', {
32
+ scrollHeight: viewport.scrollHeight,
33
+ scrollTop: viewport.scrollTop,
34
+ clientHeight: viewport.clientHeight,
35
+ isNotAtBottom
36
+ });
37
  setShowScrollToBottom(isNotAtBottom);
38
  }, []);
39
 
 
46
  });
47
  }, []);
48
 
49
+ // Effect for handling scroll events
50
  React.useEffect(() => {
51
  const viewport = viewportRef.current;
52
  if (!viewport) return;
 
54
  viewport.addEventListener('scroll', handleScroll);
55
  // Initial check for scroll position
56
  handleScroll({ target: viewport } as unknown as Event);
57
+
58
+ // Check scroll position after a short delay to account for content rendering
59
+ const checkTimeout = setTimeout(() => {
60
+ handleScroll({ target: viewport } as unknown as Event);
61
+ }, 100);
62
+
63
+ return () => {
64
+ viewport.removeEventListener('scroll', handleScroll);
65
+ clearTimeout(checkTimeout);
66
+ };
67
+ }, [handleScroll, messages, streamingAIMessageChunks]);
68
+
69
+ // Effect for initial scroll to bottom on page load
70
+ React.useEffect(() => {
71
+ if (initialLoadRef.current && messages && messages.length > 0 && viewportRef.current) {
72
+ // Use a timeout to ensure content is rendered before scrolling
73
+ const initialScrollTimeout = setTimeout(() => {
74
+ if (viewportRef.current) {
75
+ viewportRef.current.scrollTo({
76
+ top: viewportRef.current.scrollHeight,
77
+ behavior: 'smooth'
78
+ });
79
+ initialLoadRef.current = false;
80
+ }
81
+ }, 100);
82
+
83
+ return () => clearTimeout(initialScrollTimeout);
84
+ }
85
+ }, [messages]);
86
+
87
+ // Reset initialLoadRef when chat ID changes
88
+ React.useEffect(() => {
89
+ // Reset the initial load flag when the chat ID changes
90
+ initialLoadRef.current = true;
91
+
92
+ // Attempt to scroll to bottom after a short delay
93
+ if (id && id !== "new") {
94
+ const resetScrollTimeout = setTimeout(() => {
95
+ if (viewportRef.current && messages && messages.length > 0) {
96
+ viewportRef.current.scrollTo({
97
+ top: viewportRef.current.scrollHeight,
98
+ behavior: 'smooth'
99
+ });
100
+ }
101
+ }, 200);
102
+
103
+ return () => clearTimeout(resetScrollTimeout);
104
+ }
105
+ }, [id]);
106
+
107
+ // Scroll to bottom when streaming messages change
108
+ React.useEffect(() => {
109
+ // Only auto-scroll if we're already near the bottom or if this is the first message chunk
110
+ if (viewportRef.current && streamingAIMessageChunks.length > 0) {
111
+ const viewport = viewportRef.current;
112
+ const isNearBottom = viewport.scrollHeight - viewport.scrollTop - viewport.clientHeight < 100;
113
+
114
+ if (isNearBottom || streamingAIMessageChunks.length === 1) {
115
+ // Use requestAnimationFrame to ensure smooth scrolling during streaming
116
+ requestAnimationFrame(() => {
117
+ if (viewportRef.current) {
118
+ viewportRef.current.scrollTo({
119
+ top: viewportRef.current.scrollHeight,
120
+ behavior: streamingAIMessageChunks.length === 1 ? 'smooth' : 'auto'
121
+ });
122
+ }
123
+ });
124
+ }
125
+ }
126
+ }, [streamingAIMessageChunks]);
127
 
128
  if (id === "new" || !messages) {
129
  return <div className="flex-1 min-h-0"><ScrollArea className="h-full" /></div>;
 
175
  <Button
176
  variant="secondary"
177
  size="icon"
178
+ className="absolute z-50 bottom-4 left-1/2 -translate-x-1/2 rounded-full shadow-md hover:bg-accent bg-background/80 backdrop-blur-sm"
179
  onClick={scrollToBottom}
180
  >
181
  <ArrowDown className="h-4 w-4" />
src/pages/home/components/Providers.tsx CHANGED
@@ -24,9 +24,9 @@ export const Providers = ({ config }: ProvidersProps) => {
24
 
25
  const handleHuggingFaceOAuth = () => {
26
  const clientId = import.meta.env.VITE_HF_CLIENT_ID;
27
- const redirectUri = import.meta.env.VITE_HF_REDIRECT_URI;
28
 
29
- if (!clientId || !redirectUri) {
30
  toast.error("HuggingFace OAuth configuration is missing");
31
  return;
32
  }
 
24
 
25
  const handleHuggingFaceOAuth = () => {
26
  const clientId = import.meta.env.VITE_HF_CLIENT_ID;
27
+ const redirectUri = window.location.origin + '/integrations/huggingface-callback';
28
 
29
+ if (!clientId) {
30
  toast.error("HuggingFace OAuth configuration is missing");
31
  return;
32
  }
src/pages/integrations/huggingface-callback.tsx CHANGED
@@ -33,7 +33,7 @@ export function HuggingFaceCallback() {
33
  grant_type: "authorization_code",
34
  client_id: import.meta.env.VITE_HF_CLIENT_ID,
35
  client_secret: import.meta.env.VITE_HF_CLIENT_SECRET,
36
- redirect_uri: import.meta.env.VITE_HF_REDIRECT_URI,
37
  code,
38
  }),
39
  });
 
33
  grant_type: "authorization_code",
34
  client_id: import.meta.env.VITE_HF_CLIENT_ID,
35
  client_secret: import.meta.env.VITE_HF_CLIENT_SECRET,
36
+ redirect_uri: window.location.origin + '/integrations/huggingface-callback',
37
  code,
38
  }),
39
  });