use crate::app::agent::approval::ApprovalManager;
use crate::app::agent::config::Config;
use crate::app::agent::memory::MemoryCategory;
use crate::app::agent::providers::ChatMessage;
use crate::app::agent::security::SecurityPolicy;
use anyhow::Result;
use std::sync::Arc;
use super::setup::CliSetup;
use crate::app::agent::agent::loop_::context::build_context;
use crate::app::agent::agent::loop_::core::{
AUTOSAVE_MIN_MESSAGE_CHARS, autosave_memory_key, run_tool_call_loop,
};
pub(crate) async fn run_single_message(
config: &Config,
setup: &CliSetup,
message: String,
temperature: f64,
) -> Result<String> {
if config.memory.auto_save && message.chars().count() >= AUTOSAVE_MIN_MESSAGE_CHARS {
let user_key = autosave_memory_key("user_msg");
let _ = setup.mem.store(&user_key, &message, MemoryCategory::Conversation, None).await;
}
let mem_context: String =
build_context(setup.mem.as_ref(), &message, config.memory.min_relevance_score).await;
let now = chrono::Local::now().format("%Y-%m-%d %H:%M:%S %Z");
let enriched = if mem_context.is_empty() {
format!("[{now}] {message}")
} else {
format!("{mem_context}[{now}] {message}")
};
let mut history = vec![ChatMessage::system(&setup.system_prompt), ChatMessage::user(&enriched)];
let approval = Some(Arc::new(ApprovalManager::from_config(&config.autonomy)));
let security =
Some(Arc::new(SecurityPolicy::from_config(&config.autonomy, &config.workspace_dir)));
let response = run_tool_call_loop(
setup.provider.as_ref(),
&mut history,
&setup.tools_registry,
setup.observer.as_ref(),
&setup.provider_name,
&setup.model_name,
temperature,
false, approval,
setup.channel_name,
&config.multimodal,
config.agent.max_tool_iterations,
None, None, None, security,
&[], )
.await?;
println!("{response}");
setup.observer.record_event(&crate::app::agent::observability::ObserverEvent::TurnComplete);
Ok(response)
}