返回 DeepSeek-Reasonix
workspace_turn_changes.go
根目录 / desktop / workspace_turn_changes.go
1 package main
2
3 import (
4 "reasonix/internal/checkpoint"
5 "reasonix/internal/provider"
6 "unicode/utf8"
7 )
8
9 type TurnCheckLogView struct {
10 Output string `json:"output"`
11 Truncated bool `json:"truncated"`
12 }
13
14 // TurnCheckLog uses the existing archived tool-result reader, scoped to the
15 // session that supplied the check's exact call ID. It never executes a command.
16 func (a *App) TurnCheckLog(tabID, sessionPath, toolID, resultID string) *TurnCheckLogView {
17 _, ctrl, ok := a.workspaceChangesTarget(tabID)
18 if !ok || ctrl == nil || sessionPath == "" || ctrl.SessionPath() != sessionPath || toolID == "" || resultID == "" {
19 return nil
20 }
21 var source *provider.Message
22 for _, message := range ctrl.History() {
23 if message.Role == provider.RoleTool && message.ID == resultID && message.ToolCallID == toolID {
24 source = &message
25 break
26 }
27 }
28 if source == nil || ctrl.SessionPath() != sessionPath {
29 return nil
30 }
31 output := source.RawContent
32 if output == "" {
33 output = source.Content
34 }
35 truncated := len(output) > workspaceChangeDetailLimit
36 if truncated {
37 output = output[len(output)-workspaceChangeDetailLimit:]
38 for len(output) > 0 && !utf8.RuneStart(output[0]) {
39 output = output[1:]
40 }
41 }
42 return &TurnCheckLogView{Output: output, Truncated: truncated}
43 }
44
45 // WorkspaceTurnChanges reads one frozen turn from the addressed session. The
46 // session path is a correlation token only; it never authorizes reading a path.
47 func (a *App) WorkspaceTurnChanges(tabID, sessionPath string, turn int, resultID string) *checkpoint.TurnChanges {
48 _, ctrl, ok := a.workspaceChangesTarget(tabID)
49 if !ok || ctrl == nil || turn < 0 || sessionPath == "" || ctrl.SessionPath() != sessionPath {
50 return (*checkpoint.Store)(nil).TurnChanges(turn)
51 }
52 result := ctrl.CheckpointTurnChanges(turn)
53 if ctrl.SessionPath() != sessionPath || resultID == "" || result.ID != resultID {
54 return (*checkpoint.Store)(nil).TurnChanges(turn)
55 }
56 return result.Summary()
57 }
58
59 // WorkspaceTurnChangeDetail only returns a path already present in that turn.
60 func (a *App) WorkspaceTurnChangeDetail(tabID, sessionPath string, turn int, resultID, path string) *checkpoint.TurnFile {
61 _, ctrl, ok := a.workspaceChangesTarget(tabID)
62 if !ok || ctrl == nil || turn < 0 || sessionPath == "" || ctrl.SessionPath() != sessionPath {
63 return nil
64 }
65 result := ctrl.CheckpointTurnChanges(turn)
66 if ctrl.SessionPath() != sessionPath || resultID == "" || result.ID != resultID {
67 return nil
68 }
69 for _, file := range result.Files {
70 if file.Path == path {
71 return &file
72 }
73 }
74 return nil
75 }
76
76 lines GO