fix: improve chat flow and cleanup

Awaits sendMessage before navigating to prevent race conditions. Passes
agentId to startGeneration for correct agent resolution. Adds topic
deletion via Ctrl+Alt+Backspace shortcut. Adds date/time prefix to user
messages in LLM context. Fixes reasoning-container typo.
This commit is contained in:
Zoe
2026-04-27 12:06:46 -05:00
parent 9bd4b36094
commit 03a0c3587b
5 changed files with 37 additions and 24 deletions
+1 -1
View File
@@ -72,7 +72,7 @@ const toggleReasoning = async () => {
:class="reasoningOpen ? '' : '-rotate-90'"></span> :class="reasoningOpen ? '' : '-rotate-90'"></span>
</button> </button>
<div v-if="reasoningOpen" ref="containerRef" @scroll="handleScroll" <div v-if="reasoningOpen" ref="containerRef" @scroll="handleScroll"
:class="['reasoning-contaizner max-h-[min(40vh,320px)] overflow-y-auto [scrollbar-width:thin] [scrollbar-color:#888_transparent] [scrollbar-gutter:stable]', scrollState]"> :class="['reasoning-container max-h-[min(40vh,320px)] overflow-y-auto [scrollbar-width:thin] [scrollbar-color:#888_transparent] [scrollbar-gutter:stable]', scrollState]">
<div class="p-2"> <div class="p-2">
<MarkdownRenderer :finished="part.finished" :id="part.id" :content="part.content!" /> <MarkdownRenderer :finished="part.finished" :id="part.id" :content="part.content!" />
</div> </div>
+12 -11
View File
@@ -55,25 +55,26 @@ const handleSubmit = async (message: BaseMessage, model: ModelWithProvider | nul
const { sendMessage, startGeneration } = await useChat(topic.id, false); const { sendMessage, startGeneration } = await useChat(topic.id, false);
sendMessage(message).then(async res => { const res = await sendMessage(message);
if (res.ok === false) { if (res.ok === false) {
console.error('Failed to send message:', res.error); console.error('Failed to send message:', res.error);
pendingMessage.value = null; pendingMessage.value = null;
await navigateTo(`/agent/${route.params.id}`); await navigateTo(`/agent/${route.params.id}`);
nextTick(() => { nextTick(() => {
inputValue.value = message; inputValue.value = message;
}); });
}
}); return;
}
await navigateTo(`/agent/${route.params.id}/topic/${topic.id}`); await navigateTo(`/agent/${route.params.id}/topic/${topic.id}`);
autoRenameTopic(topic.id); autoRenameTopic(topic.id);
return startGeneration(model); return startGeneration(model, undefined, route.params.id as string);
}; };
</script> </script>
+20 -7
View File
@@ -8,7 +8,7 @@ const rootStart = Date.now();
const chatPaneWrapper = ref<HTMLElement | null>(null); const chatPaneWrapper = ref<HTMLElement | null>(null);
const inputValue = ref<BaseMessage>({ content: '', fileIds: [] }); const inputValue = ref<BaseMessage>({ content: '', fileIds: [] });
const route = useRoute(); const route = useRoute();
const { getAgent } = await useAgents(); const { getAgent, deleteTopic } = await useAgents();
const { open: sidebarOpen, openSidebar } = useSidebar(); const { open: sidebarOpen, openSidebar } = useSidebar();
const { providers, allModels } = await useModels(); const { providers, allModels } = await useModels();
const { addShortcut } = useKeyboardShortcuts(); const { addShortcut } = useKeyboardShortcuts();
@@ -84,12 +84,6 @@ const handleRegenerate = async (message: Message) => {
} }
} }
const handleDelete = async (rootMessage: Message) => {
await $fetch(`/api/messages/${rootMessage.id}`, {
method: 'DELETE',
});
}
const flatMessages = computed(() => { const flatMessages = computed(() => {
const messages: Message[] = []; const messages: Message[] = [];
@@ -103,6 +97,17 @@ const flatMessages = computed(() => {
return messages; return messages;
}); });
const handleDelete = async (rootMessage: Message) => {
await $fetch(`/api/messages/${rootMessage.id}`, {
method: 'DELETE',
});
if (flatMessages.value.length === 0) {
await navigateTo(`/agent/${route.params.id}`);
deleteTopic(route.params.id as string, topicId.value);
}
}
const activeGeneration = computed(() => { const activeGeneration = computed(() => {
if (topic.value === null) return null; if (topic.value === null) return null;
const generations = flatMessages.value.flatMap(message => message.generation); const generations = flatMessages.value.flatMap(message => message.generation);
@@ -190,6 +195,14 @@ addShortcut(['ctrl', 'alt', 'arrowright'], async (event) => {
} }
}) })
addShortcut(['ctrl', 'alt', 'backspace'], async (event) => {
event.preventDefault();
event.stopPropagation();
await navigateTo(`/agent/${route.params.id}`);
deleteTopic(route.params.id as string, topicId.value);
})
onMounted(() => { onMounted(() => {
scrollToBottom('instant'); scrollToBottom('instant');
}); });
+1 -1
View File
@@ -117,7 +117,7 @@ const handleChatSubmit = async (message: BaseMessage, model: ModelWithProvider |
autoRenameTopic(topic.id); autoRenameTopic(topic.id);
return startGeneration(model); return startGeneration(model, undefined, targetAgent.id);
}; };
onMounted(() => { onMounted(() => {
+3 -4
View File
@@ -57,8 +57,6 @@ export const marshallMessages = (agent: Agent, messages: Readonly<MessageEntity[
for (const message of messages) { for (const message of messages) {
switch (message.role) { switch (message.role) {
case 'user': { case 'user': {
console.log("marshalling user message", message);
const attachments = message.attachments.map(attachment => { const attachments = message.attachments.map(attachment => {
if (attachment.file.mimeType.startsWith('image/')) { if (attachment.file.mimeType.startsWith('image/')) {
return { return {
@@ -75,12 +73,13 @@ export const marshallMessages = (agent: Agent, messages: Readonly<MessageEntity[
}; };
}) as (FilePart | ImagePart)[]; }) as (FilePart | ImagePart)[];
let messageDate = new Date(message.createdAt);
marshalledMessages.push({ marshalledMessages.push({
role: 'user', role: 'user',
content: [ content: [
{ {
type: 'text', type: 'text',
text: message.content! text: `[${messageDate.toDateString()} ${messageDate.toLocaleTimeString()}]: ${message.content!}`
}, },
...attachments, ...attachments,
], ],
@@ -216,4 +215,4 @@ export const marshallMessages = (agent: Agent, messages: Readonly<MessageEntity[
} }
return Ok(marshalledMessages); return Ok(marshalledMessages);
}; };