use std::sync::Arc;
use zeph_llm::any::AnyProvider;
use crate::agent::agent_tests::{
MockChannel, MockToolExecutor, create_test_registry, mock_provider,
};
fn base_agent() -> crate::agent::Agent<MockChannel> {
let provider = mock_provider(vec!["initial response".into()]);
let channel = MockChannel::new(vec![]);
let registry = create_test_registry();
let executor = MockToolExecutor::no_tools();
crate::agent::Agent::new(provider, channel, registry, None, 5, executor)
}
#[tokio::test]
async fn process_user_message_applies_override_written_just_before_it_is_called() {
let slot: Arc<parking_lot::RwLock<Option<AnyProvider>>> =
Arc::new(parking_lot::RwLock::new(None));
let mut agent = base_agent().with_provider_override(Arc::clone(&slot));
*slot.write() = Some(mock_provider(vec!["override response".into()]));
agent
.process_user_message("hi".to_string(), vec![])
.await
.unwrap();
let sent = agent.channel.sent_messages();
assert!(
sent.iter().any(|m| m.contains("override response")),
"process_user_message must apply a provider_override written just before it runs, \
within that same call — not one turn later; got: {sent:?}"
);
assert!(
sent.iter().all(|m| !m.contains("initial response")),
"the stale pre-override provider must not be used once an override is pending; got: {sent:?}"
);
}
#[tokio::test]
async fn process_user_message_is_noop_override_when_slot_empty() {
let slot: Arc<parking_lot::RwLock<Option<AnyProvider>>> =
Arc::new(parking_lot::RwLock::new(None));
let mut agent = base_agent().with_provider_override(Arc::clone(&slot));
agent
.process_user_message("hi".to_string(), vec![])
.await
.unwrap();
let sent = agent.channel.sent_messages();
assert!(
sent.iter().any(|m| m.contains("initial response")),
"with no pending override, the original provider must still be used; got: {sent:?}"
);
}