返回 DeepSeek-Reasonix
goal_runtime_view.go
根目录 / internal / control / goal_runtime_view.go
1 package control
2
3 import "fmt"
4
5 // GoalRuntimeView is the host-side runtime summary exposed to frontends.
6 type GoalRuntimeView struct {
7 TurnsUsed int `json:"turnsUsed"`
8 TurnsLimit int `json:"turnsLimit"`
9 TokensUsed int `json:"tokensUsed"`
10 RequestsUsed int `json:"requestsUsed,omitempty"`
11 WorkDurationMs int64 `json:"workDurationMs,omitempty"`
12 TokensLimit int `json:"tokensLimit"`
13 NoProgressTurns int `json:"noProgressTurns"`
14 NoProgressLimit int `json:"noProgressLimit"`
15 LastReason string `json:"lastReason,omitempty"`
16 StopCause string `json:"stopCause,omitempty"`
17 BudgetExtensions int `json:"budgetExtensions"`
18 }
19
20 func (g *goalMachine) runtimeView() GoalRuntimeView {
21 g.mu.Lock()
22 defer g.mu.Unlock()
23 last := g.lastEvaluatorReason
24 if last == "" {
25 last = g.lastContinuationReason
26 }
27 return GoalRuntimeView{
28 TurnsUsed: g.turnsUsed, TurnsLimit: 0,
29 TokensUsed: g.tokensUsed, RequestsUsed: g.requestsUsed,
30 WorkDurationMs: g.workDurationMs,
31 TokensLimit: g.tokensLimit, NoProgressTurns: g.noProgressTurns,
32 NoProgressLimit: 0, LastReason: last,
33 StopCause: g.stopCause, BudgetExtensions: 0,
34 }
35 }
36
37 // GoalWorkDurationText renders cumulative active Goal work time without
38 // including pauses between Runs.
39 func GoalWorkDurationText(durationMs int64) string {
40 if durationMs <= 0 {
41 return "0s"
42 }
43 totalSeconds := max(int64(1), (durationMs+500)/1000)
44 if totalSeconds < 60 {
45 return fmt.Sprintf("%ds", totalSeconds)
46 }
47 totalMinutes := (totalSeconds + 30) / 60
48 if totalMinutes < 60 {
49 return fmt.Sprintf("%dm", totalMinutes)
50 }
51 hours, minutes := totalMinutes/60, totalMinutes%60
52 if minutes == 0 {
53 return fmt.Sprintf("%dh", hours)
54 }
55 return fmt.Sprintf("%dh %dm", hours, minutes)
56 }
57
57 lines GO