zeroclaw_providers/
model_pin.rs1use 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}