返回 DeepSeek-Reasonix
transcript_terminal_test.go
根目录 / internal / control / transcript_terminal_test.go
1 package control
2
3 import (
4 "path/filepath"
5 "testing"
6 "time"
7
8 "reasonix/internal/agent"
9 "reasonix/internal/agent/testutil"
10 "reasonix/internal/event"
11 "reasonix/internal/provider"
12 "reasonix/internal/tool"
13 "reasonix/internal/transcript"
14 )
15
16 func TestTranscriptRetainsProtocolRecoveryAfterProviderFailure(t *testing.T) {
17 p := &manualProtocolProvider{MockProvider: testutil.NewMock("strict", testutil.ErrorTurn(&provider.APIError{Status: 400, Body: `{"model":"deepseek"}`}))}
18 session := agent.NewSession("system")
19 session.Add(provider.Message{Role: provider.RoleAssistant, Content: "earlier", ReasoningContent: "proof"})
20 a := agent.New(p, tool.NewRegistry(), session, agent.Options{}, event.Discard)
21 dir := t.TempDir()
22 path := filepath.Join(dir, "session.jsonl")
23 if err := session.Save(path); err != nil {
24 t.Fatal(err)
25 }
26 done := make(chan event.Event, 1)
27 c := newOwnedTestController(t, Options{Runner: a, Executor: a, SessionDir: dir, SessionPath: path, Sink: event.FuncSink(func(e event.Event) {
28 if e.Kind == event.TurnDone {
29 done <- e
30 }
31 })})
32 defer c.Close()
33 c.Send("next")
34 select {
35 case e := <-done:
36 if e.Err == nil || e.ProtocolRecovery == nil {
37 t.Fatal("expected recoverable provider failure")
38 }
39 case <-time.After(5 * time.Second):
40 t.Fatal("turn did not settle")
41 }
42 action := a.PendingProtocolRecovery()
43 if action == nil {
44 t.Fatal("missing recovery token")
45 }
46 check := func(rows []transcript.Message) {
47 t.Helper()
48 for _, row := range rows {
49 if row.ProtocolRecovery != nil && row.ProtocolRecovery.ID == action.ID && row.Pending {
50 return
51 }
52 }
53 t.Fatal("authoritative display lost the pending recovery action")
54 }
55 snap, err := c.TranscriptSnapshot(transcript.PageRequest{})
56 if err != nil {
57 t.Fatal(err)
58 }
59 var rows []transcript.Message
60 for _, r := range snap.Records {
61 rows = append(rows, r.Message)
62 }
63 check(rows)
64 checkpoint, exists, err := transcript.LoadCheckpoint(path)
65 if err != nil || !exists {
66 t.Fatalf("checkpoint: %v", err)
67 }
68 check(checkpoint.Records)
69 if checkpoint.CoveredThroughSeq != snap.CoveredThroughSeq {
70 t.Fatal("checkpoint coverage drifted")
71 }
72 }
73
73 lines GO