use async_trait::async_trait;
use phi_core::agent_loop::AgentLoopConfig;
use phi_core::agents::{Agent, AgentBuildError, BasicAgent};
use phi_core::provider::ModelConfig;
use phi_core::*;
use std::sync::Arc;
use tokio::sync::mpsc;
struct ForgetfulAgent;
#[async_trait]
impl Agent for ForgetfulAgent {
async fn prompt_messages_with_sender(
&mut self,
_messages: Vec<AgentMessage>,
_tx: mpsc::UnboundedSender<AgentEvent>,
) {
}
async fn continue_loop_with_sender(
&mut self,
_tx: mpsc::UnboundedSender<AgentEvent>,
_kind: ContinuationKind,
) {
}
fn messages(&self) -> &[AgentMessage] {
&[]
}
fn is_streaming(&self) -> bool {
false
}
fn agent_id(&self) -> &str {
"forgetful"
}
fn session_id(&self) -> &str {
"forgetful"
}
fn clear_messages(&mut self) {}
fn append_message(&mut self, _msg: AgentMessage) {}
fn replace_messages(&mut self, _msgs: Vec<AgentMessage>) {}
fn save_messages(&self) -> Result<String, serde_json::Error> {
Ok(String::new())
}
fn restore_messages(&mut self, _json: &str) -> Result<(), serde_json::Error> {
Ok(())
}
fn set_tools(&mut self, _tools: Vec<Arc<dyn AgentTool>>) {}
fn abort(&self) {}
fn reset(&mut self) {}
}
#[test]
fn custom_agent_without_model_config_returns_err_not_panic() {
let agent = ForgetfulAgent;
match agent.build_config() {
Err(AgentBuildError::MissingModelConfig) => {}
Ok(_) => panic!("expected Err(MissingModelConfig), got Ok"),
}
}
#[test]
fn missing_model_config_error_display_is_descriptive() {
let err = AgentBuildError::MissingModelConfig;
let s = format!("{}", err);
assert!(
s.contains("model_config"),
"error message should mention model_config; got: {}",
s
);
}
#[test]
fn basic_agent_build_config_returns_ok_when_constructed_normally() {
let agent = BasicAgent::new(ModelConfig::anthropic("m", "n", "k"));
let cfg: AgentLoopConfig = agent.build_config().unwrap();
assert_eq!(cfg.model_config.id, "m");
}
#[tokio::test]
async fn basic_agent_prompt_still_works_end_to_end() {
use phi_core::provider::MockProvider;
let mut agent = BasicAgent::new(ModelConfig::anthropic("m", "n", "k"))
.with_provider_override(Arc::new(MockProvider::text("hello back")));
let (tx, mut rx) = mpsc::unbounded_channel();
agent
.prompt_messages_with_sender(
vec![AgentMessage::Llm(LlmMessage::new(Message::user("hi")))],
tx,
)
.await;
let mut saw_end = false;
while let Ok(ev) = rx.try_recv() {
if matches!(ev, AgentEvent::AgentEnd { .. }) {
saw_end = true;
}
}
assert!(saw_end);
}