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, RejectionCache};
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 rejections: RejectionCache,
32}
33
34impl MetaProvider {
35 pub fn new(
43 api_key: String,
44 model_name: String,
45 base_url: String,
46 extra_headers: HashMap<String, String>,
47 ) -> Result<Self> {
48 let adapter = MetaAdapter::new(api_key, model_name, base_url, extra_headers)?;
49 let capabilities = Model::capabilities(&adapter).clone();
50 Ok(Self {
51 adapter,
52 capabilities,
53 rejections: RejectionCache::default(),
54 })
55 }
56}
57
58#[async_trait]
59impl ModelProvider for MetaProvider {
60 fn capabilities(&self) -> &ModelCapabilities {
61 &self.capabilities
62 }
63
64 async fn chat(&self, request: ChatRequest, ctx: StreamContext) -> Result<FinalResponse> {
65 let config = ModelConfig::from(&request);
66 let chat_fut = self
67 .adapter
68 .chat(&request.messages, &config, Some(ctx.sink.clone()));
69
70 let learned_model = Model::name(&self.adapter).to_string();
73 let memory = self.adapter.param_memory();
74 self.rejections.seed("meta", &learned_model, memory).await;
75
76 let response = tokio::select! {
80 biased;
81 _ = ctx.token.cancelled() => {
82 return Err(ModelError::Cancelled);
83 },
84 r = chat_fut => {
85 self.rejections.persist("meta", &learned_model, memory).await;
86 r?
87 },
88 };
89
90 let usage = response.usage.clone();
91 let provider_continuation = response.provider_continuation.clone();
92 let stop_reason = response.stop_reason.clone();
93 let _ = ctx
96 .sink
97 .send(StreamEvent::Done {
98 usage: usage.clone(),
99 provider_continuation: provider_continuation.clone(),
100 stop_reason: stop_reason.clone(),
101 })
102 .await;
103
104 Ok(FinalResponse {
105 usage,
106 provider_continuation,
107 tool_calls: response.tool_calls.unwrap_or_default(),
108 stop_reason,
109 })
110 }
111}