fix(ui): use server timestamps for chat messages (#332) (#367)

This commit is contained in:
haidang1810 authored and GitHub committed 2026-03-23 15:17:31 +07:00
1 parent f9b8ae1b76
commit 19d7d86030
5 files changed
+21 -2

No files matched your search

+6
View File
@@ -3,6 +3,7 @@ package providers
import (
"context"
"encoding/json"
"time"
)
// Options keys used in ChatRequest.Options across providers.
@@ -111,6 +112,11 @@ type Message struct {
// RawAssistantContent carries raw provider content blocks through tool loop iterations.
// Anthropic requires thinking blocks to be passed back exactly as received.
RawAssistantContent json.RawMessage `json:"-"`
// CreatedAt records when this message was added to the session.
// Pointer type so that older messages (stored before this field existed) deserialize as nil,
// allowing the frontend to fall back to synthetic timestamps.
CreatedAt *time.Time `json:"created_at,omitempty"`
}
// ToolCall represents a tool invocation requested by the LLM.
+6
View File
@@ -140,6 +140,12 @@ func (s *PGSessionStore) AddMessage(ctx context.Context, key string, msg provide
s.mu.Lock()
defer s.mu.Unlock()
// Stamp message creation time if not already set.
if msg.CreatedAt == nil {
now := time.Now()
msg.CreatedAt = &now
}
data := s.getOrInit(ctx, key)
data.Messages = append(data.Messages, msg)
data.Updated = time.Now()
@@ -90,7 +90,10 @@ export function useChatMessages(sessionKey: string, agentId: string) {
const msgs: ChatMessage[] = allMsgs.map((m: Message, i: number) => {
const chatMsg: ChatMessage = {
...m,
timestamp: Date.now() - (allMsgs.length - i) * 1000,
// Use server-provided created_at; fall back to synthetic spacing for older messages.
timestamp: m.created_at
? new Date(m.created_at).getTime()
: Date.now() - (allMsgs.length - i) * 1000,
};
// Convert persisted media_refs to mediaItems for gallery display
if (m.role === "assistant" && m.media_refs && m.media_refs.length > 0) {
@@ -73,7 +73,10 @@ export function SessionDetailPage({
allMsgs.map((m, i) => {
const chatMsg: ChatMessage = {
...m,
timestamp: Date.now() - (allMsgs.length - i) * 1000,
// Use server-provided created_at; fall back to synthetic spacing for older messages.
timestamp: m.created_at
? new Date(m.created_at).getTime()
: Date.now() - (allMsgs.length - i) * 1000,
};
// Reconstruct toolDetails for assistant messages with tool_calls
if (m.role === "assistant" && m.tool_calls && m.tool_calls.length > 0) {
+1
View File
@@ -34,6 +34,7 @@ export interface Message {
tool_call_id?: string;
is_error?: boolean;
media_refs?: { id: string; mime_type: string; kind: string; path?: string }[];
created_at?: string; // ISO 8601 timestamp from server; absent for older messages
}
export interface ToolCall {