camel_component_llm/
lib.rs1pub mod bundle;
13pub mod config;
14pub mod cost;
15pub mod endpoint;
16pub mod error;
17pub mod headers;
18pub mod producer;
19pub mod producer_cache;
20pub mod provider;
21pub mod provider_factory;
22
23pub use bundle::LlmBundle;
24pub use config::{
25 LlmEndpointConfig, LlmGlobalConfig, LlmOperation, LlmProviderConfig, MockProviderConfig,
26 OllamaProviderConfig, OpenaiProviderConfig,
27};
28pub use cost::PricingTable;
29pub use error::LlmError;
30pub use provider::{
31 ChatEvent, ChatMessage, ChatRequest, ChatRole, EmbedRequest, EmbedResponse, EmittedToolCall,
32 FinishReason, LlmProvider, LlmUsage, ToolChoice, ToolDefinition,
33};
34
35use std::sync::Arc;
36
37use camel_component_api::{CamelError, Component, ComponentContext, Endpoint};
38use provider_factory::ProviderMap;
39
40pub struct LlmComponent {
41 providers: Arc<ProviderMap>,
42 config: Arc<LlmGlobalConfig>,
43}
44
45impl LlmComponent {
46 pub fn new(config: LlmGlobalConfig) -> Result<Self, CamelError> {
47 let providers = provider_factory::build_provider_map(&config).map_err(CamelError::from)?;
48 Ok(Self {
49 providers: Arc::new(providers),
50 config: Arc::new(config),
51 })
52 }
53
54 pub fn from_parts(config: LlmGlobalConfig, providers: ProviderMap) -> Self {
55 Self {
56 providers: Arc::new(providers),
57 config: Arc::new(config),
58 }
59 }
60
61 pub fn providers(&self) -> &ProviderMap {
62 &self.providers
63 }
64
65 pub fn config(&self) -> &LlmGlobalConfig {
66 &self.config
67 }
68}
69
70impl Component for LlmComponent {
71 fn scheme(&self) -> &str {
72 "llm"
73 }
74
75 fn create_endpoint(
76 &self,
77 uri: &str,
78 _ctx: &dyn ComponentContext,
79 ) -> Result<Box<dyn Endpoint>, CamelError> {
80 let endpoint_config = LlmEndpointConfig::from_uri(uri)?;
81
82 let provider_name = endpoint::resolve_provider_name(&endpoint_config, &self.config)?;
84
85 let provider = self.providers.get(provider_name).ok_or_else(|| {
86 CamelError::InvalidUri(format!("provider '{}' not found in config", provider_name))
87 })?;
88
89 if endpoint_config.operation == LlmOperation::Embed && !provider.supports_embed() {
90 return Err(CamelError::InvalidUri(format!(
91 "provider '{}' does not support embed",
92 provider_name
93 )));
94 }
95
96 Ok(Box::new(endpoint::LlmEndpoint::new(
97 uri.to_string(),
98 endpoint_config,
99 Arc::clone(&self.providers),
100 Arc::clone(&self.config),
101 )))
102 }
103}