返回 DeepSeek-Reasonix
history_test.go
根目录 / internal / transcript / history_test.go
1 package transcript
2
3 import (
4 "testing"
5
6 "reasonix/internal/agent"
7 "reasonix/internal/provider"
8 )
9
10 // A cancelled attempt persists its partial output through
11 // agent.InterruptedStreamRecord, which carries no message id when the stream
12 // never reached one. Two of them used to derive the same last-resort record
13 // address, and NewProjection then rejected the whole session.
14 func TestHistoryKeepsDerivedRecordIdentitiesUnique(t *testing.T) {
15 messages := []provider.Message{
16 {ID: "user-1", Role: provider.RoleUser, Content: "do the thing"},
17 agent.InterruptedStreamRecord("", "first partial", ""),
18 agent.InterruptedStreamRecord("", "second partial", ""),
19 }
20 rows := History(messages, HistoryOptions{})
21 seen := make(map[string]int, len(rows))
22 for index, row := range rows {
23 if row.RecordID == "" {
24 t.Fatalf("row %d has no record identity: %+v", index, row)
25 }
26 if previous, exists := seen[row.RecordID]; exists {
27 t.Fatalf("rows %d and %d share record identity %q", previous, index, row.RecordID)
28 }
29 seen[row.RecordID] = index
30 }
31 if _, err := NewProjection(testIdentity, rows, 0); err != nil {
32 t.Fatalf("projection rejected an interrupted-attempt history: %v", err)
33 }
34 }
35
36 // Two persisted records that really do claim one canonical identity are
37 // corruption, not a derived collision. They must still fail the projection.
38 func TestHistoryKeepsCanonicalDuplicatesRejected(t *testing.T) {
39 messages := []provider.Message{
40 {ID: "user-1", Role: provider.RoleUser, Content: "do the thing"},
41 {ID: "result-one", Role: provider.RoleTool, ToolCallID: "reused-call", Content: "first result"},
42 {ID: "result-two", Role: provider.RoleTool, ToolCallID: "reused-call", Content: "second result"},
43 }
44 if _, err := NewProjection(testIdentity, History(messages, HistoryOptions{}), 0); err == nil {
45 t.Fatal("projection accepted two records claiming tool:reused-call")
46 }
47 }
48
48 lines GO