返回 DeepSeek-Reasonix
turn_orchestrator_boundary_test.go
根目录 / internal / control / turn_orchestrator_boundary_test.go
1 package control
2
3 import (
4 "context"
5 "path/filepath"
6 "testing"
7
8 "reasonix/internal/agent"
9 "reasonix/internal/event"
10 )
11
12 func TestTurnOrchestratorCheckpointBoundaryPrecedesUserMessage(t *testing.T) {
13 dir := t.TempDir()
14 path := filepath.Join(dir, "session.jsonl")
15 sess := agent.NewSession("sys")
16 exec := agent.New(nil, nil, sess, agent.Options{}, event.Discard)
17 runner := &recordingSessionRunner{session: sess}
18 c := newOwnedTestController(t, Options{
19 Runner: runner,
20 Executor: exec,
21 SessionDir: dir,
22 SessionPath: path,
23 Label: "test",
24 })
25
26 o := newTurnOrchestrator(c)
27 if err := o.runTurnWithRawDisplay(context.Background(), "write the test", "write the test", ""); err != nil {
28 t.Fatal(err)
29 }
30
31 if !c.CheckpointHasBoundary(0) {
32 t.Fatal("checkpoint boundary should be available for the orchestrated turn")
33 }
34 if len(sess.Messages) != 2 || sess.Messages[1].Content != "write the test" {
35 t.Fatalf("session messages after turn = %+v, want system + user", sess.Messages)
36 }
37 loaded, err := agent.LoadSession(path)
38 if err != nil {
39 t.Fatal(err)
40 }
41 if len(loaded.Messages) != 2 {
42 t.Fatalf("saved messages = %d, want system + user", len(loaded.Messages))
43 }
44 meta, ok, err := agent.LoadBranchMeta(path)
45 if err != nil || !ok {
46 t.Fatalf("load branch meta ok=%v err=%v", ok, err)
47 }
48 if meta.UpdatedAt.IsZero() {
49 t.Fatal("activity meta should be marked after transcript changes")
50 }
51 if err := c.Rewind(0, RewindConversation); err != nil {
52 t.Fatal(err)
53 }
54 // A rewind now moves the runtime to an independent child session. The
55 // boundary precedes the user message, so one message remains and the parent
56 // source stays unchanged as read-only history.
57 live := exec.Session()
58 if live == nil || len(live.Messages) != 1 {
59 t.Fatalf("rewind did not truncate the live transcript: %+v", live)
60 }
61 if c.SessionPath() == path {
62 t.Fatalf("rewind must move to an independent child: path=%q", c.SessionPath())
63 }
64 parent, err := agent.LoadSession(path)
65 if err != nil || len(parent.Messages) != 2 {
66 t.Fatalf("parent chain changed: %+v err=%v", parent, err)
67 }
68 }
69
69 lines GO