1use crate::config::AgentConfig;
2use std::collections::HashMap;
3
4pub trait BamlRegistry: Sized {
23 fn new() -> Self;
24 fn add_llm_client(
25 &mut self,
26 name: &str,
27 provider_type: &str,
28 options: HashMap<String, serde_json::Value>,
29 );
30 fn set_primary_client(&mut self, name: &str);
31}
32
33pub struct AgentEngine {
35 config: AgentConfig,
36}
37
38impl AgentEngine {
39 pub fn new(config: AgentConfig) -> Self {
40 Self { config }
41 }
42
43 pub fn build_registry<R: BamlRegistry>(&self) -> Result<R, String> {
48 if !self.config.providers.contains_key(&self.config.default_provider) {
49 return Err(format!(
50 "default provider '{}' is not configured",
51 self.config.default_provider
52 ));
53 }
54
55 let mut registry = R::new();
56
57 for (name, conf) in &self.config.providers {
58 let mut options: HashMap<String, serde_json::Value> = HashMap::new();
59 options.insert("model".into(), serde_json::json!(conf.model));
60
61 if let Some(url) = &conf.base_url {
62 options.insert("base_url".into(), serde_json::json!(url));
63 }
64 if let Some(loc) = &conf.location {
65 options.insert("location".into(), serde_json::json!(loc));
66 }
67 if let Some(pid) = &conf.project_id {
68 options.insert("project_id".into(), serde_json::json!(pid));
69 }
70 if let Some(env_var) = &conf.api_key_env_var {
71 options.insert("api_key".into(), serde_json::json!(format!("env.{}", env_var)));
72 }
73
74 registry.add_llm_client(name, &conf.provider_type, options);
75 }
76
77 registry.set_primary_client(&self.config.default_provider);
78 Ok(registry)
79 }
80
81 pub fn config(&self) -> &AgentConfig {
82 &self.config
83 }
84}