Skip to main content

skilllite_agent/types/
feedback.rs

1//! EVO-1: Execution feedback types for evolution engine.
2
3use serde::{Deserialize, Serialize};
4
5/// Structured feedback collected from each agent loop execution.
6/// Used by the evolution engine to evaluate rule/skill effectiveness.
7#[derive(Debug, Clone, Default)]
8pub struct ExecutionFeedback {
9    pub total_tools: usize,
10    pub failed_tools: usize,
11    pub replans: usize,
12    pub iterations: usize,
13    pub elapsed_ms: u64,
14    pub context_overflow_retries: usize,
15    pub task_completed: bool,
16    /// Brief task description (generalized, not user's original text).
17    pub task_description: Option<String>,
18    /// Names of planning rules that were matched for this task.
19    pub rules_used: Vec<String>,
20    /// Per-tool execution details.
21    pub tools_detail: Vec<ToolExecDetail>,
22}
23
24/// Per-tool execution outcome.
25#[derive(Debug, Clone, Serialize, Deserialize)]
26pub struct ToolExecDetail {
27    pub tool: String,
28    pub success: bool,
29}
30
31/// User feedback signal classified from the next user message.
32#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize, Default)]
33pub enum FeedbackSignal {
34    ExplicitPositive,
35    ExplicitNegative,
36    #[default]
37    Neutral,
38}
39
40impl FeedbackSignal {
41    pub fn as_str(&self) -> &'static str {
42        match self {
43            Self::ExplicitPositive => "pos",
44            Self::ExplicitNegative => "neg",
45            Self::Neutral => "neutral",
46        }
47    }
48}
49
50/// Classify user feedback from the next message (simple keyword matching).
51/// ~80% accuracy is sufficient; evolution is gradual and tolerates noise.
52pub fn classify_user_feedback(next_user_message: &str) -> FeedbackSignal {
53    let msg = next_user_message.to_lowercase();
54    let negative = [
55        "不对",
56        "错了",
57        "重来",
58        "重新",
59        "wrong",
60        "redo",
61        "fix",
62        "不是这样",
63        "不行",
64        "有问题",
65        "bug",
66        "失败",
67    ];
68    let positive = [
69        "好的",
70        "谢谢",
71        "完美",
72        "不错",
73        "thanks",
74        "great",
75        "perfect",
76        "可以",
77        "没问题",
78        "很好",
79        "nice",
80        "done",
81        "ok",
82    ];
83    if negative.iter().any(|k| msg.contains(k)) {
84        FeedbackSignal::ExplicitNegative
85    } else if positive.iter().any(|k| msg.contains(k)) {
86        FeedbackSignal::ExplicitPositive
87    } else {
88        FeedbackSignal::Neutral
89    }
90}
91
92/// Action type for skill evolution (generate new or refine existing).
93#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
94pub enum SkillAction {
95    #[default]
96    None,
97    Generate,
98    Refine,
99}