返回 DeepSeek-Reasonix
chat_tui_goal.go
根目录 / internal / cli / chat_tui_goal.go
1 package cli
2
3 import (
4 "fmt"
5 "strings"
6
7 tea "charm.land/bubbletea/v2"
8
9 "reasonix/internal/control"
10 "reasonix/internal/i18n"
11 )
12
13 func (m *chatTUI) noticeDeprecatedGoalBudget(cmd control.GoalCommand) {
14 if cmd.DeprecatedBudgetFlag {
15 m.notice(control.GoalBudgetFlagDeprecatedNotice)
16 }
17 }
18
19 func activateGoalDriverAfterRebuild(ctrl control.SessionAPI) control.SessionAPI {
20 if concrete, ok := ctrl.(*control.Controller); ok {
21 concrete.ActivateGoalDriverAfterRebuild()
22 }
23 return ctrl
24 }
25
26 func (m *chatTUI) setGoalCommand(cmd control.GoalCommand, input string) tea.Cmd {
27 canonical, exclusive := m.ctrl.(interface{ UsesExclusiveSession() bool })
28 if exclusive && canonical.UsesExclusiveSession() {
29 if err := m.ctrl.SetGoalDurable(cmd.Text); err != nil {
30 m.echoLocalCommand(input)
31 m.notice("goal: " + err.Error())
32 return nil
33 }
34 } else {
35 m.ctrl.SetGoalWithResearchMode(cmd.Text, cmd.ResearchMode)
36 }
37 m.planMode = false
38 m.ctrl.SetPlanMode(false)
39 m.ctrl.GoalStrict(cmd.Strict)
40 if m.ctrl.GoalStatus() != control.GoalStatusRunning {
41 m.echoLocalCommand(input)
42 return nil
43 }
44 m.notice(fmt.Sprintf(i18n.M.GoalSetFmt, control.ShortGoalForNotice(m.ctrl.Goal())))
45 return m.startTurn("Start pursuing the active goal now.", input, input)
46 }
47
48 func (m *chatTUI) runGoalSubcommand(input string) tea.Cmd {
49 cmd, ok := control.ParseGoalCommand(input)
50 if !ok {
51 m.echoLocalCommand(input)
52 m.notice(i18n.M.GoalEmpty)
53 return nil
54 }
55 switch m.noticeDeprecatedGoalBudget(cmd); cmd.Action {
56 case control.GoalCommandSet:
57 return m.setGoalCommand(cmd, input)
58 case control.GoalCommandClear:
59 m.echoLocalCommand(input)
60 canonical, exclusive := m.ctrl.(interface{ UsesExclusiveSession() bool })
61 if exclusive && canonical.UsesExclusiveSession() {
62 if err := m.ctrl.SetGoalDurable(""); err != nil {
63 m.notice("goal: " + err.Error())
64 break
65 }
66 } else {
67 m.ctrl.ClearGoal()
68 }
69 m.notice(i18n.M.GoalCleared)
70 case control.GoalCommandPause:
71 m.echoLocalCommand(input)
72 if !m.ctrl.PauseGoal() {
73 m.notice(i18n.M.GoalNotRunning)
74 }
75 case control.GoalCommandResume:
76 m.echoLocalCommand(input)
77 if !m.ctrl.ResumeGoal() {
78 m.notice(i18n.M.GoalNotPaused)
79 }
80 default:
81 m.echoLocalCommand(input)
82 goal := m.ctrl.Goal()
83 if strings.TrimSpace(goal) == "" {
84 m.notice(i18n.M.GoalEmpty)
85 break
86 }
87 m.notice(fmt.Sprintf(i18n.M.GoalCurrentFmt, goal))
88 rt := m.ctrl.GoalRuntime()
89 m.notice(fmt.Sprintf(i18n.M.GoalRuntimeFmt,
90 rt.TurnsUsed, rt.RequestsUsed, rt.TokensUsed,
91 control.GoalWorkDurationText(rt.WorkDurationMs)))
92 if rt.LastReason != "" {
93 m.notice(fmt.Sprintf("%s: %s", i18n.M.GoalRuntimeLastReason, rt.LastReason))
94 }
95 if rt.StopCause != "" {
96 m.notice(fmt.Sprintf(i18n.M.GoalPausedFmt, rt.StopCause))
97 }
98 }
99 return nil
100 }
101
101 lines GO