1use crate::llm::{Client, Model, Response};
2use crate::settings::LlmBackendSettings;
3use anyhow::Result;
4use llm_connector::types::Tool;
5use llm_connector::StreamFormat;
6use tokio_stream::wrappers::UnboundedReceiverStream;
7
8pub struct Service {
16 client: Client,
17 model: String,
18}
19
20impl Service {
21 pub fn new(config: &LlmBackendSettings) -> Result<Self> {
23 let client = Client::new(config)?;
24 let model = match config {
25 LlmBackendSettings::OpenAI { model, .. } => model.clone(),
26 LlmBackendSettings::Anthropic { model, .. } => model.clone(),
27 LlmBackendSettings::Ollama { model, .. } => model.clone(),
28 LlmBackendSettings::Aliyun { model, .. } => model.clone(),
29 LlmBackendSettings::Zhipu { model, .. } => model.clone(),
30 LlmBackendSettings::Volcengine { model, .. } => model.clone(),
31 LlmBackendSettings::Tencent { model, .. } => model.clone(),
32 };
33
34 Ok(Self { client, model })
35 }
36
37 pub async fn chat(
41 &self,
42 model: Option<&str>,
43 messages: Vec<llm_connector::types::Message>,
44 tools: Option<Vec<Tool>>,
45 ) -> Result<Response> {
46 let model = model.unwrap_or(&self.model);
47 self.client.chat(model, messages, tools).await
48 }
49
50 pub async fn chat_stream_ollama(
54 &self,
55 model: Option<&str>,
56 messages: Vec<llm_connector::types::Message>,
57 format: StreamFormat,
58 ) -> Result<UnboundedReceiverStream<String>> {
59 let model = model.unwrap_or(&self.model);
60 self.client.chat_stream_with_format(model, messages, format).await
61 }
62
63 pub async fn chat_stream_openai(
67 &self,
68 model: Option<&str>,
69 messages: Vec<llm_connector::types::Message>,
70 tools: Option<Vec<Tool>>,
71 format: StreamFormat,
72 ) -> Result<UnboundedReceiverStream<String>> {
73 let model = model.unwrap_or(&self.model);
74 self.client.chat_stream_openai(model, messages, tools, format).await
75 }
76
77 pub async fn list_models(&self) -> Result<Vec<Model>> {
79 self.client.list_models().await
80 }
81
82 pub async fn validate_model(&self, model: &str) -> Result<bool> {
84 let available_models = self.client.list_models().await?;
85 Ok(available_models.iter().any(|m| m.id == model))
86 }
87}