MCPcopy Create free account
hub / github.com/Icecubesaad/OpenLLM-Studio / ChatInterface

Function ChatInterface

src/components/ChatInterface.tsx:19–212  ·  view source on GitHub ↗
({
  dbPath,
  conversation,
  messages,
  availableModels,
  isLoadingMessages = false,
  onRefreshMessages,
  onConversationPatched,
}: ChatInterfaceProps)

Source from the content-addressed store, hash-verified

17}
18
19export function ChatInterface({
20 dbPath,
21 conversation,
22 messages,
23 availableModels,
24 isLoadingMessages = false,
25 onRefreshMessages,
26 onConversationPatched,
27}: ChatInterfaceProps) {
28 const [isStreaming, setIsStreaming] = useState(false);
29 const [streamingContent, setStreamingContent] = useState('');
30 const [error, setError] = useState<string | null>(null);
31 const [pendingMessages, setPendingMessages] = useState<Message[]>([]);
32 const [isStopping, setIsStopping] = useState(false);
33 const lastSeqRef = useRef<number>(0);
34
35 const visibleMessages = pendingMessages.length > 0
36 ? [...messages, ...pendingMessages]
37 : messages;
38
39 useEffect(() => {
40 if (pendingMessages.length === 0) return;
41
42 const persistedUserMessages = new Set(
43 messages
44 .filter((message) => message.role === 'user')
45 .map((message) => `${message.role}:${message.content}:${message.conversation_id}`)
46 );
47
48 setPendingMessages((current) =>
49 current.filter((message) => !persistedUserMessages.has(`${message.role}:${message.content}:${message.conversation_id}`))
50 );
51 }, [messages, pendingMessages.length]);
52
53 useEffect(() => {
54 setPendingMessages([]);
55 let unlisten: (() => void) | undefined;
56 let mounted = true;
57
58 const setupListener = async () => {
59 const unlistenFn = await listen<{ conversation_id?: string; content: string; seq?: number }>('chat-token', (event) => {
60 if (!mounted) return;
61 if (event.payload.conversation_id && event.payload.conversation_id !== conversation.id) return;
62
63 const { content, seq } = event.payload;
64 if (content === undefined || content === null || content === '') return;
65
66 if (seq !== undefined) {
67 if (seq <= lastSeqRef.current) return;
68 lastSeqRef.current = seq;
69 }
70
71 setStreamingContent((prev) => prev + content);
72 });
73
74 return unlistenFn;
75 };
76

Callers

nothing calls this directly

Calls 1

setupListenerFunction · 0.70

Tested by

no test coverage detected