Skip to content

Commit 57c4c2b

Browse files
authored
Merge pull request #2158 from dgageot/fix-timestamps
fix: use event timestamps for user messages in SessionFromEvents
2 parents 55148f7 + 639db94 commit 57c4c2b

1 file changed

Lines changed: 39 additions & 10 deletions

File tree

pkg/evaluation/save.go

Lines changed: 39 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -63,20 +63,29 @@ func SessionFromEvents(events []map[string]any, title string, questions []string
6363

6464
// Add user questions as initial messages.
6565
// For multi-turn evals, these are interleaved with agent responses
66-
// as they appear in the event stream. The first question is added
67-
// upfront; subsequent questions are inserted when a stream_stopped
68-
// event indicates the agent finished processing the previous turn.
66+
// as they appear in the event stream. User messages are added when
67+
// a "user_message" event is encountered (which carries the correct
68+
// timestamp), or when a "stream_stopped" event indicates the agent
69+
// finished processing the previous turn in a multi-turn eval.
70+
// If no "user_message" event is found before the first agent response,
71+
// the question is added with the timestamp of that first response.
6972
questionIdx := 0
70-
addNextQuestion := func() {
73+
userMessageAdded := false
74+
addNextQuestion := func(timestamp string) {
7175
if questionIdx < len(questions) {
72-
sess.AddMessage(session.UserMessage(questions[questionIdx]))
76+
msg := &session.Message{
77+
Message: chat.Message{
78+
Role: chat.MessageRoleUser,
79+
Content: questions[questionIdx],
80+
CreatedAt: timestamp,
81+
},
82+
}
83+
sess.AddMessage(msg)
7384
questionIdx++
85+
userMessageAdded = true
7486
}
7587
}
7688

77-
// Add the first question
78-
addNextQuestion()
79-
8089
// Track current assistant message being built
8190
var currentContent strings.Builder
8291
var currentReasoningContent strings.Builder
@@ -122,7 +131,19 @@ func SessionFromEvents(events []map[string]any, title string, questions []string
122131
eventTimestamp := parseEventTimestamp(event)
123132

124133
switch eventType {
134+
case "user_message":
135+
// Use the event timestamp for the user message instead of time.Now()
136+
if !userMessageAdded {
137+
addNextQuestion(eventTimestamp)
138+
}
139+
125140
case "agent_choice":
141+
// Ensure a user message has been added before the first agent response.
142+
// This handles event streams that lack a "user_message" event.
143+
if !userMessageAdded {
144+
addNextQuestion(eventTimestamp)
145+
}
146+
126147
// Accumulate agent response content
127148
if content, ok := event["content"].(string); ok {
128149
currentContent.WriteString(content)
@@ -237,14 +258,22 @@ func SessionFromEvents(events []map[string]any, title string, questions []string
237258
// Flush final assistant message
238259
flushAssistantMessage()
239260

240-
// In multi-turn evals, add the next user question after each turn
241-
addNextQuestion()
261+
// In multi-turn evals, add the next user question after each turn.
262+
// Reset the flag so the next user_message event (or agent_choice
263+
// fallback) will add the question for the next turn.
264+
userMessageAdded = false
242265
}
243266
}
244267

245268
// Flush any remaining content
246269
flushAssistantMessage()
247270

271+
// Add any remaining questions that weren't added via user_message or
272+
// agent_choice events (e.g. when the event stream is empty).
273+
for questionIdx < len(questions) {
274+
addNextQuestion(time.Now().Format(time.RFC3339))
275+
}
276+
248277
return sess
249278
}
250279

0 commit comments

Comments
 (0)