diff --git a/ui/desktop/src/App.tsx b/ui/desktop/src/App.tsx
index b6c2475f02..dac9226eee 100644
--- a/ui/desktop/src/App.tsx
+++ b/ui/desktop/src/App.tsx
@@ -44,6 +44,8 @@ import {
useAgent,
} from './hooks/useAgent';
import { useNavigation } from './hooks/useNavigation';
+import { USE_NEW_CHAT } from './updates';
+import Pair2 from './components/Pair2';
// Route Components
const HubRouteWrapper = ({
@@ -93,7 +95,20 @@ const PairRouteWrapper = ({
const resumeSessionId = searchParams.get('resumeSessionId') ?? undefined;
- return (
+ return USE_NEW_CHAT ? (
+
+ ) : (
+ Warning: BaseChat2!
void;
}
+function pushMessage(currentMessages: Message[], incomingMsg: Message): Message[] {
+ const lastMsg = currentMessages[currentMessages.length - 1];
+
+ if (lastMsg?.id && lastMsg.id === incomingMsg.id) {
+ const lastContent = lastMsg.content[lastMsg.content.length - 1];
+ const newContent = incomingMsg.content[incomingMsg.content.length - 1];
+
+ if (
+ lastContent?.type === 'text' &&
+ newContent?.type === 'text' &&
+ incomingMsg.content.length === 1
+ ) {
+ lastContent.text += newContent.text;
+ } else {
+ lastMsg.content.push(...incomingMsg.content);
+ }
+ return [...currentMessages];
+ } else {
+ return [...currentMessages, incomingMsg];
+ }
+}
+
export function useChatStream({
sessionId,
messages,
@@ -28,22 +51,24 @@ export function useChatStream({
created: Date.now(),
};
- const updatedMessages = [...messages, newMessage];
- setMessages(updatedMessages);
+ let currentMessages = [...messages, newMessage];
+ setMessages(currentMessages);
setChatState(ChatState.Streaming);
abortControllerRef.current = new AbortController();
try {
- const response = await fetch('/reply', {
+ // TODO(Douwe): this side steps our API. heyapi does support streaming though which should make
+ // this all nice & typed
+ const response = await fetch(getApiUrl('/reply'), {
method: 'POST',
- headers: { 'Content-Type': 'application/json' },
+ headers: {
+ 'Content-Type': 'application/json',
+ 'X-Secret-Key': await window.electron.getSecretKey(),
+ },
body: JSON.stringify({
session_id: sessionId,
- messages: updatedMessages.map((m) => ({
- role: m.role,
- content: m.content,
- })),
+ messages: currentMessages,
}),
signal: abortControllerRef.current.signal,
});
@@ -72,7 +97,8 @@ export function useChatStream({
if (event.message) {
const msg = event.message as Message;
- setMessages([...updatedMessages, msg]);
+ currentMessages = pushMessage(currentMessages, msg);
+ setMessages(currentMessages);
}
if (event.error) {
@@ -91,8 +117,8 @@ export function useChatStream({
}
}
}
- } catch (error: any) {
- if (error.name !== 'AbortError') {
+ } catch (error) {
+ if (error instanceof Error && error.name !== 'AbortError') {
console.error('Stream error:', error);
}
setChatState(ChatState.Idle);
diff --git a/ui/desktop/src/updates.ts b/ui/desktop/src/updates.ts
index 978b762429..f98cbfc77d 100644
--- a/ui/desktop/src/updates.ts
+++ b/ui/desktop/src/updates.ts
@@ -2,3 +2,5 @@ export const UPDATES_ENABLED = true;
export const COST_TRACKING_ENABLED = true;
export const ANNOUNCEMENTS_ENABLED = false;
export const CONFIGURATION_ENABLED = true;
+
+export const USE_NEW_CHAT = true;