Skip to main content

vv_agent/
agent.rs

1use std::sync::Arc;
2
3use crate::guardrails::{InputGuardrail, OutputGuardrail};
4use crate::handoffs::Handoff;
5use crate::model::ModelRef;
6use crate::model_settings::ModelSettings;
7use crate::runtime::RuntimeHook;
8use crate::tools::{AgentToolBuilder, BackgroundAgentTaskBuilder};
9use crate::tools::{Tool, ToolPolicy};
10use crate::types::Metadata;
11
12#[derive(Clone)]
13pub struct Agent {
14    name: String,
15    instructions: String,
16    model: Option<ModelRef>,
17    model_settings: ModelSettings,
18    tools: Vec<Arc<dyn Tool>>,
19    handoffs: Vec<Handoff>,
20    input_guardrails: Vec<Arc<dyn InputGuardrail>>,
21    output_guardrails: Vec<Arc<dyn OutputGuardrail>>,
22    hooks: Vec<Arc<dyn RuntimeHook>>,
23    max_cycles: Option<u32>,
24    tool_use_behavior: ToolUseBehavior,
25    tool_policy: ToolPolicy,
26    metadata: Metadata,
27}
28
29impl Agent {
30    pub fn builder(name: impl Into<String>) -> AgentBuilder {
31        AgentBuilder {
32            agent: Self {
33                name: name.into(),
34                instructions: String::new(),
35                model: None,
36                model_settings: ModelSettings::default(),
37                tools: Vec::new(),
38                handoffs: Vec::new(),
39                input_guardrails: Vec::new(),
40                output_guardrails: Vec::new(),
41                hooks: Vec::new(),
42                max_cycles: None,
43                tool_use_behavior: ToolUseBehavior::default(),
44                tool_policy: ToolPolicy::default(),
45                metadata: Metadata::new(),
46            },
47        }
48    }
49
50    pub fn name(&self) -> &str {
51        &self.name
52    }
53
54    pub fn instructions(&self) -> &str {
55        &self.instructions
56    }
57
58    pub fn model(&self) -> Option<&ModelRef> {
59        self.model.as_ref()
60    }
61
62    pub fn model_settings(&self) -> &ModelSettings {
63        &self.model_settings
64    }
65
66    pub fn tools(&self) -> &[Arc<dyn Tool>] {
67        &self.tools
68    }
69
70    pub fn handoffs(&self) -> &[Handoff] {
71        &self.handoffs
72    }
73
74    pub(crate) fn input_guardrails(&self) -> &[Arc<dyn InputGuardrail>] {
75        &self.input_guardrails
76    }
77
78    pub(crate) fn output_guardrails(&self) -> &[Arc<dyn OutputGuardrail>] {
79        &self.output_guardrails
80    }
81
82    pub fn hooks(&self) -> &[Arc<dyn RuntimeHook>] {
83        &self.hooks
84    }
85
86    pub fn max_cycles(&self) -> Option<u32> {
87        self.max_cycles
88    }
89
90    pub fn tool_use_behavior(&self) -> &ToolUseBehavior {
91        &self.tool_use_behavior
92    }
93
94    pub fn tool_policy(&self) -> &ToolPolicy {
95        &self.tool_policy
96    }
97
98    pub fn metadata(&self) -> &Metadata {
99        &self.metadata
100    }
101
102    pub fn as_tool(&self) -> AgentToolBuilder {
103        AgentToolBuilder::new(self.clone())
104    }
105
106    pub fn as_background_task(&self) -> BackgroundAgentTaskBuilder {
107        BackgroundAgentTaskBuilder::new(self.clone())
108    }
109}
110
111pub struct AgentBuilder {
112    agent: Agent,
113}
114
115impl AgentBuilder {
116    pub fn instructions(mut self, instructions: impl Into<String>) -> Self {
117        self.agent.instructions = instructions.into();
118        self
119    }
120
121    pub fn model(mut self, model: ModelRef) -> Self {
122        self.agent.model = Some(model);
123        self
124    }
125
126    pub fn model_settings(mut self, settings: ModelSettings) -> Self {
127        self.agent.model_settings = settings;
128        self
129    }
130
131    pub fn tool(mut self, tool: impl Tool + 'static) -> Self {
132        self.agent.tools.push(Arc::new(tool));
133        self
134    }
135
136    pub fn tool_arc(mut self, tool: Arc<dyn Tool>) -> Self {
137        self.agent.tools.push(tool);
138        self
139    }
140
141    pub fn handoff(mut self, handoff: impl Into<Handoff>) -> Self {
142        self.agent.handoffs.push(handoff.into());
143        self
144    }
145
146    pub fn input_guardrail(mut self, guardrail: Arc<dyn InputGuardrail>) -> Self {
147        self.agent.input_guardrails.push(guardrail);
148        self
149    }
150
151    pub fn output_guardrail(mut self, guardrail: Arc<dyn OutputGuardrail>) -> Self {
152        self.agent.output_guardrails.push(guardrail);
153        self
154    }
155
156    pub fn hook(mut self, hook: Arc<dyn RuntimeHook>) -> Self {
157        self.agent.hooks.push(hook);
158        self
159    }
160
161    pub fn max_cycles(mut self, max_cycles: u32) -> Self {
162        self.agent.max_cycles = Some(max_cycles);
163        self
164    }
165
166    pub fn tool_use_behavior(mut self, behavior: ToolUseBehavior) -> Self {
167        self.agent.tool_use_behavior = behavior;
168        self
169    }
170
171    pub fn tool_policy(mut self, tool_policy: ToolPolicy) -> Self {
172        self.agent.tool_policy = tool_policy;
173        self
174    }
175
176    pub fn metadata(mut self, key: impl Into<String>, value: serde_json::Value) -> Self {
177        self.agent.metadata.insert(key.into(), value);
178        self
179    }
180
181    pub fn build(self) -> Result<Agent, String> {
182        if self.agent.name.trim().is_empty() {
183            return Err("agent name cannot be empty".to_string());
184        }
185        if self.agent.instructions.trim().is_empty() {
186            return Err("agent instructions cannot be empty".to_string());
187        }
188        Ok(self.agent)
189    }
190}
191
192#[derive(Clone, Default)]
193pub enum ToolUseBehavior {
194    #[default]
195    RunLlmAgain,
196    StopOnFirstTool,
197    StopAtTools(Vec<String>),
198}