1use anyhow::Result;
4use std::sync::Arc;
5
6use oxi_agent::{ProviderResolver, ToolRegistry};
7use oxi_ai::{Model, ModelRegistry, Provider, ProviderRegistry};
8
9use crate::agent_builder::AgentBuilder;
10
11pub struct Oxi {
19 providers: Arc<ProviderRegistry>,
20 models: Arc<ModelRegistry>,
21 tools: Arc<ToolRegistry>,
22 include_builtins: bool,
24}
25
26impl Oxi {
27 pub fn agent(&self, config: oxi_agent::AgentConfig) -> AgentBuilder<'_> {
29 AgentBuilder::new(self, config)
30 }
31
32 pub fn providers(&self) -> &ProviderRegistry {
34 &self.providers
35 }
36
37 pub fn models(&self) -> &ModelRegistry {
39 &self.models
40 }
41
42 pub fn tools(&self) -> Arc<ToolRegistry> {
44 Arc::clone(&self.tools)
45 }
46
47 pub fn resolve_model(&self, model_id: &str) -> Result<Model> {
51 let parts: Vec<&str> = model_id.splitn(2, '/').collect();
52 let (provider, model) = if parts.len() == 2 {
53 (parts[0], parts[1])
54 } else {
55 ("anthropic", parts[0])
56 };
57 self.models
58 .lookup(provider, model)
59 .ok_or_else(|| anyhow::anyhow!("Model '{}' not found", model_id))
60 }
61
62 pub fn create_provider(&self, name: &str) -> Result<Arc<dyn Provider>> {
67 if let Some(p) = self.providers.get_custom(name) {
69 return Ok(p);
70 }
71 if self.include_builtins {
73 if let Some(p) = oxi_ai::create_builtin_provider(name) {
74 return Ok(Arc::from(p));
75 }
76 }
77 Err(anyhow::anyhow!("Provider '{}' not found", name))
78 }
79
80 pub fn providers_arc(&self) -> Arc<ProviderRegistry> {
82 Arc::clone(&self.providers)
83 }
84
85 pub fn models_arc(&self) -> Arc<ModelRegistry> {
87 Arc::clone(&self.models)
88 }
89
90 pub fn has_builtins(&self) -> bool {
92 self.include_builtins
93 }
94}
95
96impl ProviderResolver for Oxi {
98 fn resolve_provider(&self, name: &str) -> Option<Arc<dyn Provider>> {
99 self.create_provider(name).ok()
100 }
101
102 fn resolve_model(&self, model_id: &str) -> Option<Model> {
103 self.resolve_model(model_id).ok()
104 }
105}
106
107pub struct OxiBuilder {
109 providers: ProviderRegistry,
110 models: ModelRegistry,
111 tools: ToolRegistry,
112 include_builtins: bool,
113}
114
115impl OxiBuilder {
116 pub fn new() -> Self {
118 Self {
119 providers: ProviderRegistry::new(),
120 models: ModelRegistry::new(),
121 tools: ToolRegistry::new(),
122 include_builtins: false,
123 }
124 }
125
126 pub fn with_builtins(mut self) -> Self {
131 self.models = ModelRegistry::from_static();
132 self.include_builtins = true;
133 self
134 }
135
136 pub fn provider(self, name: &str, p: impl Provider + 'static) -> Self {
138 self.providers.register(name, p);
139 self
140 }
141
142 pub fn tool(self, tool: impl oxi_agent::AgentTool + 'static) -> Self {
144 self.tools.register(tool);
145 self
146 }
147
148 pub fn model(self, model: Model) -> Self {
150 self.models.register(model);
151 self
152 }
153
154 pub fn build(self) -> Oxi {
156 Oxi {
157 providers: Arc::new(self.providers),
158 models: Arc::new(self.models),
159 tools: Arc::new(self.tools),
160 include_builtins: self.include_builtins,
161 }
162 }
163}
164
165impl Default for OxiBuilder {
166 fn default() -> Self {
167 Self::new()
168 }
169}