Skip to main content

phi_agent/agent/
factory.rs

1use std::sync::Arc;
2
3use anyhow::Result;
4use agent_base::{AgentBuilder, AgentRuntime, AgentResult, ReasoningEffort, RunOutcome, RuntimeEvent, SafetyConfig, SessionId};
5
6use crate::agent::builder::base_agent_builder;
7
8/// phi-agent configuration (tool-agnostic)
9#[derive(Clone)]
10pub struct PhiAgentConfig {
11    pub model: String,
12    pub enable_thinking: bool,
13    pub thinking_budget: Option<u64>,
14    pub thinking_effort: ReasoningEffort,
15    pub safety: SafetyConfig,
16}
17
18/// A built Agent instance.
19///
20/// Wraps AgentRuntime with common operations behind a simpler API.
21#[derive(Clone)]
22pub struct PhiAgent {
23    runtime: AgentRuntime,
24    pub config: PhiAgentConfig,
25}
26
27impl PhiAgent {
28    /// Create a pre-configured AgentBuilder.
29    ///
30    /// Equivalent to `base_agent_builder(llm_client).system_prompt(system_prompt)`,
31    /// after which you register tools, middleware, and approval handlers,
32    /// then call `Self::build`.
33    pub fn builder(
34        llm_client: Arc<dyn agent_base::LlmClient>,
35        system_prompt: String,
36    ) -> AgentBuilder {
37        base_agent_builder(llm_client).system_prompt(system_prompt)
38    }
39
40    /// Build from an AgentBuilder.
41    pub fn build(builder: AgentBuilder, config: PhiAgentConfig) -> Result<Self> {
42        let runtime = builder.build()?;
43        Ok(Self { runtime, config })
44    }
45
46    /// Create an agent session.
47    pub async fn create_session(&self) -> SessionId {
48        self.runtime.create_session().await
49    }
50
51    /// Execute one turn.
52    pub async fn run_turn<F>(
53        &self,
54        session_id: SessionId,
55        query: &str,
56        on_event: F,
57    ) -> AgentResult<RunOutcome>
58    where
59        F: FnMut(RuntimeEvent) -> AgentResult<()> + Send,
60    {
61        self.runtime.run_turn(session_id, query, on_event).await
62    }
63
64    /// Cancel the currently executing turn.
65    pub fn cancel(&self) {
66        self.runtime.cancel();
67    }
68
69    /// Check whether the agent has been cancelled.
70    pub fn is_cancelled(&self) -> bool {
71        self.runtime.is_cancelled()
72    }
73
74    /// Set the reasoning effort.
75    pub async fn set_reasoning_effort(&self, effort: ReasoningEffort) {
76        self.runtime.set_reasoning_effort(effort).await;
77    }
78}