Skip to main content

zeroclaw_providers/
model_pin.rs

1use super::ModelProvider;
2use super::traits::{
3    ChatMessage, ChatRequest, ChatResponse, StreamChunk, StreamEvent, StreamOptions, StreamResult,
4};
5use async_trait::async_trait;
6use futures_util::stream::BoxStream;
7
8pub struct ModelPinnedProvider {
9    alias: String,
10    pinned_model: String,
11    inner: Box<dyn ModelProvider>,
12}
13
14impl ModelPinnedProvider {
15    pub fn new(alias: &str, pinned_model: &str, inner: Box<dyn ModelProvider>) -> Self {
16        Self {
17            alias: alias.to_string(),
18            pinned_model: pinned_model.to_string(),
19            inner,
20        }
21    }
22}
23
24#[async_trait]
25impl ModelProvider for ModelPinnedProvider {
26    fn capabilities(&self) -> super::traits::ProviderCapabilities {
27        self.inner.capabilities()
28    }
29
30    fn default_temperature(&self) -> f64 {
31        self.inner.default_temperature()
32    }
33
34    fn default_max_tokens(&self) -> u32 {
35        self.inner.default_max_tokens()
36    }
37
38    fn default_timeout_secs(&self) -> u64 {
39        self.inner.default_timeout_secs()
40    }
41
42    fn default_base_url(&self) -> Option<&str> {
43        self.inner.default_base_url()
44    }
45
46    fn default_wire_api(&self) -> &str {
47        self.inner.default_wire_api()
48    }
49
50    fn convert_tools(&self, tools: &[zeroclaw_api::tool::ToolSpec]) -> super::traits::ToolsPayload {
51        self.inner.convert_tools(tools)
52    }
53
54    fn supports_native_tools(&self) -> bool {
55        self.inner.supports_native_tools()
56    }
57
58    fn supports_vision(&self) -> bool {
59        self.inner.supports_vision()
60    }
61
62    fn supports_streaming(&self) -> bool {
63        self.inner.supports_streaming()
64    }
65
66    fn supports_streaming_tool_events(&self) -> bool {
67        self.inner.supports_streaming_tool_events()
68    }
69
70    async fn list_models(&self) -> anyhow::Result<Vec<String>> {
71        self.inner.list_models().await
72    }
73
74    async fn warmup(&self) -> anyhow::Result<()> {
75        self.inner.warmup().await
76    }
77
78    async fn chat_with_system(
79        &self,
80        system_prompt: Option<&str>,
81        message: &str,
82        _model: &str,
83        temperature: Option<f64>,
84    ) -> anyhow::Result<String> {
85        self.inner
86            .chat_with_system(system_prompt, message, &self.pinned_model, temperature)
87            .await
88    }
89
90    async fn chat_with_history(
91        &self,
92        messages: &[ChatMessage],
93        _model: &str,
94        temperature: Option<f64>,
95    ) -> anyhow::Result<String> {
96        self.inner
97            .chat_with_history(messages, &self.pinned_model, temperature)
98            .await
99    }
100
101    async fn chat(
102        &self,
103        request: ChatRequest<'_>,
104        _model: &str,
105        temperature: Option<f64>,
106    ) -> anyhow::Result<ChatResponse> {
107        self.inner
108            .chat(request, &self.pinned_model, temperature)
109            .await
110    }
111
112    async fn chat_with_tools(
113        &self,
114        messages: &[ChatMessage],
115        tools: &[serde_json::Value],
116        _model: &str,
117        temperature: Option<f64>,
118    ) -> anyhow::Result<ChatResponse> {
119        self.inner
120            .chat_with_tools(messages, tools, &self.pinned_model, temperature)
121            .await
122    }
123
124    fn stream_chat_with_system(
125        &self,
126        system_prompt: Option<&str>,
127        message: &str,
128        _model: &str,
129        temperature: Option<f64>,
130        options: StreamOptions,
131    ) -> BoxStream<'static, StreamResult<StreamChunk>> {
132        self.inner.stream_chat_with_system(
133            system_prompt,
134            message,
135            &self.pinned_model,
136            temperature,
137            options,
138        )
139    }
140
141    fn stream_chat_with_history(
142        &self,
143        messages: &[ChatMessage],
144        _model: &str,
145        temperature: Option<f64>,
146        options: StreamOptions,
147    ) -> BoxStream<'static, StreamResult<StreamChunk>> {
148        self.inner
149            .stream_chat_with_history(messages, &self.pinned_model, temperature, options)
150    }
151
152    fn stream_chat(
153        &self,
154        request: ChatRequest<'_>,
155        _model: &str,
156        temperature: Option<f64>,
157        options: StreamOptions,
158    ) -> BoxStream<'static, StreamResult<StreamEvent>> {
159        self.inner
160            .stream_chat(request, &self.pinned_model, temperature, options)
161    }
162}
163
164impl zeroclaw_api::attribution::Attributable for ModelPinnedProvider {
165    fn role(&self) -> zeroclaw_api::attribution::Role {
166        self.inner.role()
167    }
168    fn alias(&self) -> &str {
169        &self.alias
170    }
171}