返回 DeepSeek-Reasonix
context_report.go
根目录 / internal / agent / context_report.go
1 package agent
2
3 import "reasonix/internal/provider"
4
5 // ContextReport is a point-in-time view of context pressure: the declared
6 // window, the thresholds derived from it, what the model currently sees, and how
7 // the last maintenance pass ended. A misconfigured window and a genuinely full
8 // one produce the same notices, so the numbers behind the decision have to be
9 // inspectable rather than inferred.
10 type ContextReport struct {
11 Window int
12 HardCeiling int
13 OutputBudget int
14
15 LatestPrompt int
16 CanonicalTokens int
17 ProjectionTokens int
18 Projected bool
19
20 SoftThreshold int
21 SnipThreshold int
22 FoldThreshold int
23 ForceThreshold int
24
25 LastTrigger string
26 LastMode string
27 LastSource int
28 LastResult int
29 CacheState string
30 BlockedReason string
31 }
32
33 // ContextReport samples the current context state. Compaction is disabled when
34 // Window is zero, in which case the thresholds carry no meaning.
35 func (a *Agent) ContextReport() ContextReport {
36 if a == nil {
37 return ContextReport{}
38 }
39 rep := ContextReport{
40 Window: a.contextWindow,
41 HardCeiling: a.hardInputCeiling(),
42 OutputBudget: a.maxOutputTokens,
43 CacheState: a.CacheState(),
44 }
45 if u := a.sess.output.lastUsage.Load(); u != nil {
46 rep.LatestPrompt = u.LatestPromptTokens()
47 }
48 if a.sess.conversation != nil {
49 canonical, _ := a.sess.conversation.snapshotMessagesVersion()
50 rep.CanonicalTokens = a.estimatedPromptTokens(provider.ModelMessages(canonical))
51 }
52 visible := a.modelVisibleMessages()
53 rep.ProjectionTokens = a.estimatedPromptTokens(provider.ModelMessages(visible))
54 rep.Projected = rep.ProjectionTokens != rep.CanonicalTokens
55
56 if a.contextWindow > 0 {
57 rep.FoldThreshold = a.compactTrigger()
58 if _, reason := a.contextMaintenanceBlocked(a.contextMaintenanceInputHash(visible), 0); reason != "" {
59 rep.BlockedReason = reason
60 }
61 }
62
63 a.sess.compactionMu.Lock()
64 st := a.sess.compactionState
65 a.sess.compactionMu.Unlock()
66 // Prefer LastReceipt; fall back to legacy top-level mirrors from older sidecars.
67 if r := st.LastReceipt; r != nil && r.Status == "applied" {
68 rep.LastTrigger = r.Trigger
69 if r.Action == "summary" {
70 rep.LastMode = CompactionModeSummarized
71 } else if r.Action != "" {
72 rep.LastMode = r.Action
73 }
74 rep.LastSource, rep.LastResult = r.InputTokens, r.ResultTokens
75 } else {
76 rep.LastTrigger, rep.LastMode = st.LastTrigger, st.LastMode
77 rep.LastSource, rep.LastResult = st.LastSourceTokens, st.LastResultTokens
78 }
79 if rep.BlockedReason == "" {
80 if r := st.LastReceipt; r != nil && (r.Status == "blocked" || r.Status == "failed") {
81 rep.BlockedReason = r.Reason
82 } else {
83 rep.BlockedReason = st.BlockedReason
84 }
85 }
86 return rep
87 }
88
88 lines GO