package domain import ( "fmt" "reflect" "testing" ) func TestExchangeHistoryOwnershipAndBranches(t *testing.T) { control := &CacheControl{Type: CacheControlEphemeral, TTL: "1h"} source := []RenderedMessage{{Role: RoleSystem, Content: "", CacheControl: control}, {Role: RoleUser, Content: "question"}} initial := CaptureExchange(nil, "first", source, " answer ") first := CaptureExchange(initial, "second", []RenderedMessage{{Role: RoleUser, Content: "follow-up"}}, "reply") second := CaptureExchange(initial, "third", []RenderedMessage{{Role: RoleDeveloper, Content: "other"}}, "") source[0].Content = "changed" control.TTL = "changed" got := initial.Messages() want := []RenderedMessage{{Role: RoleSystem, Content: "", CacheControl: &CacheControl{Type: CacheControlEphemeral, TTL: "1h"}}, {Role: RoleUser, Content: "question"}, {Role: RoleAssistant, Content: " answer "}} if !reflect.DeepEqual(got, want) { t.Fatalf("initial messages = %#v, want %#v", got, want) } got[0].CacheControl.TTL = "mutated" got[1].Content = "mutated" if !reflect.DeepEqual(initial.Messages(), want) { t.Fatal("returned messages changed retained history") } if first.RunID() != "second" || first.ParentRunID() != "first" || first.MessageCount() != 5 { t.Fatal("incorrect branch metadata") } if second.ParentRunID() != "first" || second.Messages()[3].Content != "other" || second.Messages()[4].Content != "" { t.Fatal("incorrect sibling history") } if first.Messages()[3].Content != "follow-up" || !reflect.DeepEqual(initial.Messages(), want) { t.Fatal("branches changed each other or their parent") } } func TestExchangeManyTurns(t *testing.T) { var exchange *Exchange const turns = 2000 for i := 0; i < turns; i++ { exchange = CaptureExchange(exchange, fmt.Sprint(i), []RenderedMessage{{Role: RoleUser, Content: fmt.Sprint(i)}}, fmt.Sprint(i)) } messages := exchange.Messages() if len(messages) != turns*2 || exchange.MessageCount() != len(messages) { t.Fatalf("unexpected history length: %d", len(messages)) } for i := 0; i < turns; i++ { if messages[2*i].Content != fmt.Sprint(i) || messages[2*i+1].Role != RoleAssistant || messages[2*i+1].Content != fmt.Sprint(i) { t.Fatalf("unexpected turn %d: %#v", i, messages[2*i:2*i+2]) } } }