Skip to main content

agent_base/skill/
prompter.rs

1use std::sync::Arc;
2
3use super::{Skill, SkillPrompter};
4
5/// Lazy-loading strategy (default)
6///
7/// Only includes brief_description + instructions to call get_skill_detail
8pub struct LazySkillPrompter {
9    title: String,
10    instruction: String,
11    item_prefix: String,
12}
13
14impl Default for LazySkillPrompter {
15    fn default() -> Self {
16        Self {
17            title: "## Available Skills".to_string(),
18            instruction:
19                "> Call get_skill_detail to get detailed instructions for a Skill."
20                    .to_string(),
21            item_prefix: "- **".to_string(),
22        }
23    }
24}
25
26impl LazySkillPrompter {
27    pub fn new() -> Self {
28        Self::default()
29    }
30
31    pub fn title(mut self, title: impl Into<String>) -> Self {
32        self.title = title.into();
33        self
34    }
35
36    pub fn instruction(mut self, instruction: impl Into<String>) -> Self {
37        self.instruction = instruction.into();
38        self
39    }
40
41    pub fn item_prefix(mut self, prefix: impl Into<String>) -> Self {
42        self.item_prefix = prefix.into();
43        self
44    }
45}
46
47impl SkillPrompter for LazySkillPrompter {
48    fn build_prompt(&self, skills: &[Arc<dyn Skill>]) -> String {
49        if skills.is_empty() {
50            return String::new();
51        }
52
53        let mut prompt = String::new();
54        prompt.push_str(&self.title);
55        prompt.push('\n');
56
57        for skill in skills {
58            prompt.push_str(&format!(
59                "{}**{}**: {}\n",
60                self.item_prefix,
61                skill.name(),
62                skill.brief_description()
63            ));
64        }
65
66        prompt.push('\n');
67        prompt.push_str(&self.instruction);
68
69        prompt
70    }
71}
72
73/// Full-injection strategy
74///
75/// Injects both brief and detailed descriptions
76pub struct FullDetailPrompter;
77
78impl SkillPrompter for FullDetailPrompter {
79    fn build_prompt(&self, skills: &[Arc<dyn Skill>]) -> String {
80        if skills.is_empty() {
81            return String::new();
82        }
83
84        let mut prompt = String::from("## Available Skills\n\n");
85        for skill in skills {
86            prompt.push_str(&format!("### {}\n\n", skill.name()));
87            prompt.push_str(&skill.brief_description());
88            prompt.push_str("\n\n");
89            prompt.push_str(&skill.detailed_description());
90            prompt.push_str("\n\n---\n\n");
91        }
92        prompt
93    }
94}