返回 DeepSeek-Reasonix
rewind.go
根目录 / internal / serve / rewind.go
1 package serve
2
3 import (
4 "encoding/json"
5 "net/http"
6
7 "reasonix/internal/control"
8 )
9
10 // rewind rewinds the session to a checkpoint.
11 func (s *Server) rewind(w http.ResponseWriter, r *http.Request) {
12 var body struct {
13 Turn int `json:"turn"`
14 Scope string `json:"scope"` // "code", "conversation", "both"
15 }
16 if err := json.NewDecoder(r.Body).Decode(&body); err != nil || body.Turn < 0 {
17 http.Error(w, "missing turn", http.StatusBadRequest)
18 return
19 }
20 scope := control.RewindBoth
21 switch body.Scope {
22 case "both":
23 case "code":
24 scope = control.RewindCode
25 case "conversation":
26 scope = control.RewindConversation
27 default:
28 http.Error(w, "scope must be code, conversation, or both", http.StatusBadRequest)
29 return
30 }
31 // Rewind may intentionally switch to a fork. Serialize the controller and
32 // lease handoff with every other session-path-changing endpoint.
33 s.bindMu.Lock()
34 defer s.bindMu.Unlock()
35 if !s.validateExpectedSessionLocked(w, r) {
36 return
37 }
38 if err := s.ctl().Rewind(body.Turn, scope); err != nil {
39 http.Error(w, err.Error(), http.StatusInternalServerError)
40 return
41 }
42 if scope != control.RewindCode {
43 s.bc.ResetSession()
44 }
45 w.WriteHeader(http.StatusNoContent)
46 }
47
47 lines GO