use oxibrain_core::extraction::ExtractMechanism;
use oxibrain_ports::LlmPort;
use std::sync::Arc;
pub fn from_env() -> anyhow::Result<(Arc<dyn LlmPort>, String, ExtractMechanism)> {
let provider =
std::env::var("OXIBRAIN_LLM_PROVIDER").unwrap_or_else(|_| "anthropic".to_string());
match provider.as_str() {
"anthropic" => {
let key = std::env::var("ANTHROPIC_API_KEY").map_err(|_| {
anyhow::anyhow!("ANTHROPIC_API_KEY not set (required for extraction)")
})?;
let model = std::env::var("ANTHROPIC_MODEL")
.or_else(|_| std::env::var("OXIBRAIN_MODEL"))
.unwrap_or_else(|_| "claude-sonnet-4-5".to_string());
Ok((
Arc::new(oxibrain_llm_http::AnthropicLlm::new(key, model.clone())),
model,
ExtractMechanism::ToolCall,
))
}
"openai" => {
let key = std::env::var("OPENAI_API_KEY")
.map_err(|_| anyhow::anyhow!("OPENAI_API_KEY not set (required for extraction)"))?;
let model = std::env::var("OPENAI_MODEL")
.or_else(|_| std::env::var("OXIBRAIN_MODEL"))
.unwrap_or_else(|_| "gpt-4o".to_string());
Ok((
Arc::new(oxibrain_llm_http::OpenAiLlm::new(key, model.clone())),
model,
ExtractMechanism::JsonSchema,
))
}
other => {
anyhow::bail!("unknown OXIBRAIN_LLM_PROVIDER={other} (expected: anthropic|openai)")
}
}
}
pub fn config(
model_id: String,
mechanism: ExtractMechanism,
) -> oxibrain_core::extraction::ExtractorConfig {
use oxibrain_core::registry::CORE_V1_MAJOR;
oxibrain_core::extraction::ExtractorConfig {
model_id,
prompt_version: 1,
registry_major: CORE_V1_MAJOR,
mechanism,
max_tokens: 8192,
model_digest: None,
}
}