返回 DeepSeek-Reasonix
rewind_head.go
根目录 / internal / control / rewind_head.go
1 package control
2
3 import (
4 "log/slog"
5
6 "reasonix/internal/agent"
7 )
8
9 // undoHeadRewind returns the controller to the head it left through an
10 // in-place conversation rewind, provided nothing was added on the rewind head
11 // since: the empty rewind head is retired and its parent becomes current. A
12 // rewind head that was continued stays a version and undo leaves it alone.
13 func (c *Controller) undoHeadRewind() bool {
14 sess := c.headBranchSession()
15 if sess == nil {
16 return false
17 }
18 ref, ok := sess.Head()
19 if !ok {
20 return false
21 }
22 path := c.SessionPath()
23 heads, err := agent.ListSessionHeads(path)
24 if err != nil {
25 return false
26 }
27 var current *agent.SessionHead
28 for i := range heads {
29 if heads[i].ID == ref.HeadID {
30 current = &heads[i]
31 }
32 }
33 if current == nil || current.Kind != agent.HeadKindRewind || current.LeafID != current.ForkFrom || current.ParentHead == "" {
34 return false
35 }
36 c.snapshotMu.Lock()
37 defer c.snapshotMu.Unlock()
38 if err := sess.SwitchHead(path, current.ParentHead); err != nil {
39 slog.Warn("controller: undo could not return to the parent head", "path", path, "head", current.ParentHead, "err", err)
40 return false
41 }
42 c.afterHeadSwitch(path)
43 if err := agent.RetireSessionHead(path, current.ID); err != nil {
44 slog.Warn("controller: undo left the empty rewind head in place", "path", path, "head", current.ID, "err", err)
45 }
46 return true
47 }
48
48 lines GO