Skip to main content

imp_core/agent/
turn_assessment.rs

1use super::{ContinueReason, StopReason};
2
3#[derive(Debug, Clone, PartialEq, Eq)]
4pub(super) enum NextAction {
5    Continue {
6        prompt: String,
7        reason: ContinueReason,
8    },
9    Stop {
10        reason: NextActionStopReason,
11    },
12}
13
14pub(super) type NextActionStopReason = StopReason;
15#[derive(Debug, Clone, PartialEq, Eq)]
16pub(super) struct RuntimeEvidence {
17    pub(super) repeated_action: bool,
18    pub(super) execution_stop_reason: Option<NextActionStopReason>,
19    pub(super) work_completed: bool,
20    pub(super) execution_debt: bool,
21    pub(super) execution_evidence: bool,
22    pub(super) planning_only_progress: bool,
23}
24
25#[derive(Debug, Clone, PartialEq, Eq)]
26pub(super) struct ManaEvidence {
27    pub(super) stop_reason: Option<NextActionStopReason>,
28}
29
30#[derive(Debug, Clone, PartialEq, Eq)]
31pub(super) struct TextFallbackEvidence {
32    pub(super) planner_stop_reason: Option<NextActionStopReason>,
33    pub(super) execution_stop_reason: Option<NextActionStopReason>,
34}
35
36#[derive(Debug, Clone, PartialEq, Eq)]
37pub(super) struct ContinueRecommendation {
38    pub(super) prompt: String,
39    pub(super) reason: ContinueReason,
40}
41
42#[derive(Debug, Clone, PartialEq, Eq)]
43pub struct NextActionAssessment {
44    pub runtime: NextActionRuntimeEvidence,
45    pub mana: NextActionManaEvidence,
46    pub text_fallback: NextActionTextFallbackEvidence,
47    pub continue_recommendation: Option<NextActionContinueRecommendation>,
48    pub chosen_action: NextActionDebugView,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq)]
52pub struct NextActionRuntimeEvidence {
53    pub repeated_action: bool,
54    pub execution_stop_reason: Option<String>,
55    pub work_completed: bool,
56    pub execution_debt: bool,
57    pub execution_evidence: bool,
58    pub planning_only_progress: bool,
59}
60
61#[derive(Debug, Clone, PartialEq, Eq)]
62pub struct NextActionManaEvidence {
63    pub stop_reason: Option<String>,
64}
65
66#[derive(Debug, Clone, PartialEq, Eq)]
67pub struct NextActionTextFallbackEvidence {
68    pub planner_stop_reason: Option<String>,
69    pub execution_stop_reason: Option<String>,
70}
71
72#[derive(Debug, Clone, PartialEq, Eq)]
73pub struct NextActionContinueRecommendation {
74    pub prompt: String,
75    pub reason: String,
76}
77
78#[derive(Debug, Clone, PartialEq, Eq)]
79pub enum NextActionDebugView {
80    Continue { prompt: String, reason: String },
81    Stop { reason: String },
82}
83
84#[derive(Debug, Clone, PartialEq, Eq)]
85pub(super) struct PostTurnAssessment {
86    pub(super) runtime: RuntimeEvidence,
87    pub(super) mana: ManaEvidence,
88    pub(super) text_fallback: TextFallbackEvidence,
89    pub(super) continue_recommendation: Option<ContinueRecommendation>,
90}
91
92impl PostTurnAssessment {
93    pub(super) fn into_next_action(self) -> NextAction {
94        if self.runtime.repeated_action {
95            return NextAction::Stop {
96                reason: NextActionStopReason::RepeatedAction,
97            };
98        }
99
100        if let Some(reason) = self.runtime.execution_stop_reason {
101            return NextAction::Stop { reason };
102        }
103
104        if self.runtime.work_completed {
105            return NextAction::Stop {
106                reason: NextActionStopReason::WorkCompleted,
107            };
108        }
109
110        if let Some(reason) = self.mana.stop_reason {
111            return NextAction::Stop { reason };
112        }
113
114        if let Some(reason) = self.text_fallback.planner_stop_reason {
115            return NextAction::Stop { reason };
116        }
117
118        if let Some(reason) = self.text_fallback.execution_stop_reason {
119            return NextAction::Stop { reason };
120        }
121
122        if let Some(continue_recommendation) = self.continue_recommendation {
123            return NextAction::Continue {
124                prompt: continue_recommendation.prompt,
125                reason: continue_recommendation.reason,
126            };
127        }
128
129        if self.runtime.planning_only_progress {
130            return NextAction::Stop {
131                reason: NextActionStopReason::NoProgress,
132            };
133        }
134
135        NextAction::Stop {
136            reason: NextActionStopReason::NoAutomaticFollowUp,
137        }
138    }
139
140    pub(super) fn debug_view(&self) -> NextActionAssessment {
141        let chosen_action = match self.clone().into_next_action() {
142            NextAction::Continue { prompt, reason } => NextActionDebugView::Continue {
143                prompt,
144                reason: reason.as_str().to_string(),
145            },
146            NextAction::Stop { reason } => NextActionDebugView::Stop {
147                reason: reason.as_str().to_string(),
148            },
149        };
150
151        NextActionAssessment {
152            runtime: NextActionRuntimeEvidence {
153                repeated_action: self.runtime.repeated_action,
154                execution_stop_reason: self
155                    .runtime
156                    .execution_stop_reason
157                    .map(|reason| reason.as_str().to_string()),
158                work_completed: self.runtime.work_completed,
159                execution_debt: self.runtime.execution_debt,
160                execution_evidence: self.runtime.execution_evidence,
161                planning_only_progress: self.runtime.planning_only_progress,
162            },
163            mana: NextActionManaEvidence {
164                stop_reason: self
165                    .mana
166                    .stop_reason
167                    .map(|reason| reason.as_str().to_string()),
168            },
169            text_fallback: NextActionTextFallbackEvidence {
170                planner_stop_reason: self
171                    .text_fallback
172                    .planner_stop_reason
173                    .map(|reason| reason.as_str().to_string()),
174                execution_stop_reason: self
175                    .text_fallback
176                    .execution_stop_reason
177                    .map(|reason| reason.as_str().to_string()),
178            },
179            continue_recommendation: self.continue_recommendation.clone().map(|recommendation| {
180                NextActionContinueRecommendation {
181                    prompt: recommendation.prompt,
182                    reason: recommendation.reason.as_str().to_string(),
183                }
184            }),
185            chosen_action,
186        }
187    }
188}