mermaid_cli/providers/model/
meta.rs1use std::collections::HashMap;
14
15use async_trait::async_trait;
16
17use mermaid_domain::ChatRequest;
18use mermaid_model::models::adapters::meta::MetaAdapter;
19use mermaid_model::models::{Model, ModelCapabilities, ModelConfig, ModelError, Result};
20
21use super::super::ctx::{FinalResponse, StreamContext, StreamEvent};
22use super::ModelProvider;
23
24pub use mermaid_model::models::adapters::meta::{DEFAULT_API_KEY_ENV, DEFAULT_BASE_URL};
25
26pub struct MetaProvider {
28 adapter: MetaAdapter,
29 capabilities: ModelCapabilities,
30}
31
32impl MetaProvider {
33 pub fn new(
41 api_key: String,
42 model_name: String,
43 base_url: String,
44 extra_headers: HashMap<String, String>,
45 ) -> Result<Self> {
46 let adapter = MetaAdapter::new(api_key, model_name, base_url, extra_headers)?;
47 let capabilities = Model::capabilities(&adapter).clone();
48 Ok(Self {
49 adapter,
50 capabilities,
51 })
52 }
53}
54
55#[async_trait]
56impl ModelProvider for MetaProvider {
57 fn capabilities(&self) -> &ModelCapabilities {
58 &self.capabilities
59 }
60
61 async fn chat(&self, request: ChatRequest, ctx: StreamContext) -> Result<FinalResponse> {
62 let config = ModelConfig::from(&request);
63 let chat_fut = self
64 .adapter
65 .chat(&request.messages, &config, Some(ctx.sink.clone()));
66
67 let response = tokio::select! {
71 biased;
72 _ = ctx.token.cancelled() => {
73 return Err(ModelError::Cancelled);
74 },
75 r = chat_fut => r?,
76 };
77
78 let usage = response.usage.clone();
79 let provider_continuation = response.provider_continuation.clone();
80 let stop_reason = response.stop_reason.clone();
81 let _ = ctx
84 .sink
85 .send(StreamEvent::Done {
86 usage: usage.clone(),
87 provider_continuation: provider_continuation.clone(),
88 stop_reason: stop_reason.clone(),
89 })
90 .await;
91
92 Ok(FinalResponse {
93 usage,
94 provider_continuation,
95 tool_calls: response.tool_calls.unwrap_or_default(),
96 stop_reason,
97 })
98 }
99}