Skip to content

Commit 47d6812

Browse files
committed
feat: enhance chat message handling and structure
- Updated ChatMessage and ChatConsole components to support structured message contents, allowing for both text and action types. - Refactored message rendering logic to improve clarity and maintainability. - Modified type definitions in llm.d.ts to include optional properties for better flexibility in chat message management. - Enhanced styling for action items and improved user experience during message streaming.
1 parent db37777 commit 47d6812

File tree

4 files changed

+320
-135
lines changed

4 files changed

+320
-135
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ lib/
2929
**/dist
3030
**/node_modules
3131
**/package-lock.json
32+
**/pkg
3233
dist_local/
3334

3435
stats.html

src/components/ui/chat/ChatConsole.vue

Lines changed: 64 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -83,25 +83,23 @@ const loadConversationMessages = debounce(async (conversationId: string) => {
8383
isLoadingMessages.value = true;
8484
try {
8585
const res = await get(`/ai/chat/conversations/${conversationId}/messages`);
86-
const messages = (res.data || []).map((msg: ChatMessage) => ({
87-
role: msg.role as ChatMessageRole,
88-
content: msg.content || '',
89-
timestamp: new Date(msg.created_ts || Date.now()),
90-
conversationId: msg.conversation_id,
91-
isStreaming: false,
92-
}));
86+
const messages = (res.data || []).map((msg: any) => {
87+
const message: ChatMessage = {
88+
...msg,
89+
timestamp: new Date(msg.created_ts || Date.now()),
90+
};
91+
return message;
92+
});
9393
9494
messages.sort(
95-
(a: ChatMessageType, b: ChatMessageType) =>
96-
a.timestamp.getTime() - b.timestamp.getTime()
95+
(a: ChatMessage, b: ChatMessage) =>
96+
(a.timestamp?.getTime() || 0) - (b.timestamp?.getTime() || 0)
9797
);
9898
9999
chatHistory.splice(0, chatHistory.length, ...messages);
100100
currentConversationId.value = conversationId;
101101
} catch (error) {
102102
console.error('Failed to load conversation messages:', error);
103-
const errorMessage =
104-
error instanceof Error ? error.message : 'Failed to load messages';
105103
} finally {
106104
isLoadingMessages.value = false;
107105
// Scroll to bottom after loading messages
@@ -255,7 +253,7 @@ const resetChatbotConfig = () => {
255253
};
256254
257255
// Initialize chat history
258-
const chatHistory = reactive<ChatMessageType[]>([]);
256+
const chatHistory = reactive<ChatMessage[]>([]);
259257
260258
// Message handling
261259
const sendMessage = async (message: string) => {
@@ -268,16 +266,20 @@ const sendMessage = async (message: string) => {
268266
role: 'user',
269267
content: message,
270268
timestamp: new Date(),
269+
conversation_id: currentConversationId.value || '',
270+
status: 'completed',
271271
});
272272
// Scroll to bottom after adding user message
273273
messageListRef.value?.scrollToBottom();
274274
275275
const responseIndex = chatHistory.length;
276276
chatHistory.push({
277-
role: 'system',
278-
content: '',
277+
role: 'assistant',
279278
timestamp: new Date(),
280279
isStreaming: true,
280+
conversation_id: currentConversationId.value || '',
281+
status: 'pending',
282+
contentsMap: {},
281283
});
282284
// Scroll to bottom after adding system message placeholder
283285
messageListRef.value?.scrollToBottom();
@@ -377,15 +379,16 @@ const sendStreamingRequest = async (
377379
const reader = response.body!.getReader();
378380
const decoder = new TextDecoder();
379381
let buffer = '';
380-
let fullResponse = '';
381382
382383
const processStream = async () => {
383384
try {
384385
const { value, done } = await reader.read();
385386
387+
const currentMessage = chatHistory[responseIndex];
388+
386389
if (done) {
387-
if (chatHistory[responseIndex]) {
388-
chatHistory[responseIndex].isStreaming = false;
390+
if (currentMessage) {
391+
currentMessage.isStreaming = false;
389392
// Scroll to bottom when streaming is complete
390393
messageListRef.value?.scrollToBottom();
391394
}
@@ -400,36 +403,67 @@ const sendStreamingRequest = async (
400403
for (const line of lines) {
401404
if (line.startsWith('data:')) {
402405
try {
406+
// Event data
403407
const eventData = line.slice(5).trim();
408+
409+
// Skip if empty
404410
if (eventData === '') continue;
405411
412+
// Parse stream message
406413
const chunk: ChatbotStreamMessage = JSON.parse(eventData);
407414
415+
// Initial update with conversation id
408416
if (chunk.is_initial) {
409417
currentConversationId.value = chunk.conversation_id!;
410418
continue;
411419
}
412420
421+
// Update conversation title
413422
if (chunk.conversation_title) {
414423
if (!currentConversation.value) {
415-
currentConversation.value = {
416-
title: chunk.conversation_title,
417-
};
418-
} else {
419-
currentConversation.value.title =
420-
chunk.conversation_title;
424+
currentConversation.value = {};
421425
}
426+
currentConversation.value.title = chunk.conversation_title;
422427
}
423428
424-
fullResponse += chunk.content || '';
425-
if (chatHistory[responseIndex]) {
426-
chatHistory[responseIndex].content = fullResponse;
427-
chatHistory[responseIndex].conversationId =
428-
chunk.conversation_id;
429-
// Scroll to bottom during streaming
430-
messageListRef.value?.scrollToBottom();
429+
// Get chunk content
430+
const contentKey = chunk.key || '';
431+
if (!currentMessage.contents?.length) {
432+
currentMessage.contents = [];
433+
}
434+
const contentIndex = currentMessage.contents.findIndex(
435+
c => c.key === contentKey
436+
);
437+
if (contentIndex >= 0) {
438+
// Update existing content
439+
const content = currentMessage.contents[contentIndex];
440+
if (chunk.type === 'text') {
441+
content.content += chunk.content || '';
442+
if (chunk.is_text_done) {
443+
content.isStreaming = false;
444+
}
445+
} else if (chunk.type === 'action') {
446+
currentMessage.contents[contentIndex] = {
447+
...content,
448+
...chunk,
449+
};
450+
}
451+
} else {
452+
// Add new content
453+
if (chunk.type === 'text') {
454+
const newContent: ChatMessageContent = {
455+
...chunk,
456+
isStreaming: true,
457+
};
458+
currentMessage.contents.push(newContent);
459+
} else if (chunk.type === 'action') {
460+
currentMessage.contents.push({
461+
...chunk,
462+
});
463+
}
431464
}
432465
466+
// Final response
433467
if (chunk.is_done) {
434468
if (chatHistory[responseIndex]) {
435469
chatHistory[responseIndex].isStreaming = false;

0 commit comments

Comments
 (0)