use crate::context::{ContextConfig, ExecutionLimits};
use crate::provider::context_translation::ContextTranslationStrategy;
use crate::provider::{ModelConfig, ResponseFormat, StreamProvider};
use crate::types::*;
use std::sync::Arc;
pub type ConvertToLlmFn = Arc<dyn Fn(&[AgentMessage]) -> Vec<Message> + Send + Sync>;
pub type TransformContextFn = Arc<dyn Fn(Vec<AgentMessage>) -> Vec<AgentMessage> + Send + Sync>;
pub type GetMessagesFn = Box<dyn Fn() -> Vec<AgentMessage> + Send + Sync>;
pub type BeforeLoopFn = Arc<dyn Fn(&[AgentMessage], usize) -> bool + Send + Sync>;
pub type AfterLoopFn = Arc<dyn Fn(&[AgentMessage], &Usage) + Send + Sync>;
pub type BeforeTurnFn = Arc<dyn Fn(&[AgentMessage], usize) -> bool + Send + Sync>;
pub type AfterTurnFn = Arc<dyn Fn(&[AgentMessage], &Usage) + Send + Sync>;
pub type BeforeToolExecutionFn = Arc<dyn Fn(&str, &str, &serde_json::Value) -> bool + Send + Sync>;
pub type AfterToolExecutionFn = Arc<dyn Fn(&str, &str, bool) + Send + Sync>;
pub type BeforeToolExecutionUpdateFn = Arc<dyn Fn(&str, &str, &str) -> bool + Send + Sync>;
pub type AfterToolExecutionUpdateFn = Arc<dyn Fn(&str, &str, &str) + Send + Sync>;
pub type OnErrorFn = Arc<dyn Fn(&str) + Send + Sync>;
pub type BeforeCompactionStartFn = Arc<dyn Fn(usize, usize) -> bool + Send + Sync>;
pub type AfterCompactionEndFn = Arc<dyn Fn(usize, usize, usize, usize) + Send + Sync>;
pub struct AgentLoopConfig {
pub model_config: ModelConfig,
pub provider_override: Option<Arc<dyn StreamProvider>>,
pub thinking_level: ThinkingLevel,
pub max_tokens: Option<u32>,
pub temperature: Option<f32>,
pub convert_to_llm: Option<ConvertToLlmFn>,
pub transform_context: Option<TransformContextFn>,
pub get_steering_messages: Option<GetMessagesFn>,
pub get_follow_up_messages: Option<GetMessagesFn>,
pub context_config: Option<ContextConfig>,
pub execution_limits: Option<ExecutionLimits>,
pub cache_config: CacheConfig,
pub tool_execution: ToolExecutionStrategy,
pub tool_timeout: Option<std::time::Duration>,
pub retry_config: crate::provider::retry::RetryConfig,
pub before_turn: Option<BeforeTurnFn>,
pub after_turn: Option<AfterTurnFn>,
pub before_loop: Option<BeforeLoopFn>,
pub after_loop: Option<AfterLoopFn>,
pub before_tool_execution: Option<BeforeToolExecutionFn>,
pub after_tool_execution: Option<AfterToolExecutionFn>,
pub before_tool_execution_update: Option<BeforeToolExecutionUpdateFn>,
pub after_tool_execution_update: Option<AfterToolExecutionUpdateFn>,
pub on_error: Option<OnErrorFn>,
pub before_compaction_start: Option<BeforeCompactionStartFn>,
pub after_compaction_end: Option<AfterCompactionEndFn>,
pub input_filters: Vec<Arc<dyn InputFilter>>,
pub first_turn_trigger: TurnTrigger,
pub config_id: Option<String>,
pub context_translation: Option<Arc<dyn ContextTranslationStrategy>>,
pub prun_pending: Option<Arc<std::sync::Mutex<Vec<crate::tools::prun::PrunRequest>>>>,
pub response_format: ResponseFormat,
}