claude_code_switcher/templates/
k2.rs

1//! K2 (Moonshot) AI provider template implementation
2
3use crate::{
4    settings::{
5        ClaudeSettings, EndpointConfig, HTTPConfig, ModelConfig, Permissions, ProviderConfig,
6    },
7    snapshots::SnapshotScope,
8    templates::Template,
9};
10use std::collections::HashMap;
11
12/// K2 AI provider template
13#[derive(Debug, Clone)]
14pub struct K2Template;
15
16impl Template for K2Template {
17    fn template_type(&self) -> crate::templates::TemplateType {
18        crate::templates::TemplateType::K2
19    }
20
21    fn env_var_name(&self) -> &'static str {
22        "MOONSHOT_API_KEY"
23    }
24
25    fn display_name(&self) -> &'static str {
26        "K2 (Moonshot)"
27    }
28
29    fn description(&self) -> &'static str {
30        "Moonshot K2 API - Advanced conversational AI with large context"
31    }
32
33    fn create_settings(&self, api_key: &str, scope: &SnapshotScope) -> ClaudeSettings {
34        let mut settings = ClaudeSettings::new();
35
36        if matches!(scope, SnapshotScope::Common | SnapshotScope::All) {
37            settings.provider = Some(ProviderConfig {
38                id: "moonshot".to_string(),
39                metadata: None,
40            });
41
42            settings.model = Some(ModelConfig {
43                name: "kimi-k2-0905-preview".to_string(),
44                metadata: None,
45            });
46
47            settings.endpoint = Some(EndpointConfig {
48                id: "moonshot".to_string(),
49                api_base: "https://api.moonshot.cn/v1".to_string(),
50                api_key: None,
51                endpoint_id: None,
52                metadata: None,
53            });
54
55            settings.http = Some(HTTPConfig {
56                timeout_ms: Some(30000),
57                max_retries: Some(3),
58                retry_backoff_factor: Some(2.0),
59            });
60
61            settings.permissions = Some(Permissions {
62                allow_network_access: Some(true),
63                allow_filesystem_access: Some(true),
64                allow_command_execution: Some(false),
65            });
66        }
67
68        if matches!(scope, SnapshotScope::Env | SnapshotScope::All) {
69            let mut env = HashMap::new();
70            env.insert("ANTHROPIC_API_KEY".to_string(), api_key.to_string());
71            env.insert("ANTHROPIC_AUTH_TOKEN".to_string(), api_key.to_string());
72            env.insert(
73                "ANTHROPIC_BASE_URL".to_string(),
74                "https://api.moonshot.cn/v1".to_string(),
75            );
76            env.insert(
77                "ANTHROPIC_MODEL".to_string(),
78                "kimi-k2-0905-preview".to_string(),
79            );
80            env.insert(
81                "ANTHROPIC_SMALL_FAST_MODEL".to_string(),
82                "kimi-k2-0905-preview".to_string(),
83            );
84            env.insert(
85                "ANTHROPIC_DEFAULT_SONNET_MODEL".to_string(),
86                "kimi-k2-0905-preview".to_string(),
87            );
88            env.insert("API_TIMEOUT_MS".to_string(), "600000".to_string());
89            env.insert(
90                "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC".to_string(),
91                "1".to_string(),
92            );
93            settings.environment = Some(env);
94        }
95
96        settings
97    }
98}
99
100/// K2 Thinking AI provider template
101#[derive(Debug, Clone)]
102pub struct K2ThinkingTemplate;
103
104impl Template for K2ThinkingTemplate {
105    fn template_type(&self) -> crate::templates::TemplateType {
106        crate::templates::TemplateType::K2Thinking
107    }
108
109    fn env_var_name(&self) -> &'static str {
110        "MOONSHOT_API_KEY"
111    }
112
113    fn display_name(&self) -> &'static str {
114        "K2 Thinking (Moonshot)"
115    }
116
117    fn description(&self) -> &'static str {
118        "Moonshot K2 Thinking API - High-speed reasoning with 256K context"
119    }
120
121    fn create_settings(&self, api_key: &str, scope: &SnapshotScope) -> ClaudeSettings {
122        let mut settings = ClaudeSettings::new();
123
124        if matches!(scope, SnapshotScope::Common | SnapshotScope::All) {
125            settings.provider = Some(ProviderConfig {
126                id: "moonshot".to_string(),
127                metadata: Some(HashMap::from([(
128                    "thinking".to_string(),
129                    "true".to_string(),
130                )])),
131            });
132
133            settings.model = Some(ModelConfig {
134                name: "kimi-k2-thinking".to_string(),
135                metadata: None,
136            });
137
138            settings.endpoint = Some(EndpointConfig {
139                id: "moonshot".to_string(),
140                api_base: "https://api.moonshot.cn/anthropic".to_string(),
141                api_key: None,
142                endpoint_id: None,
143                metadata: None,
144            });
145
146            settings.http = Some(HTTPConfig {
147                timeout_ms: Some(30000),
148                max_retries: Some(3),
149                retry_backoff_factor: Some(2.0),
150            });
151
152            settings.permissions = Some(Permissions {
153                allow_network_access: Some(true),
154                allow_filesystem_access: Some(true),
155                allow_command_execution: Some(false),
156            });
157        }
158
159        if matches!(scope, SnapshotScope::Env | SnapshotScope::All) {
160            let mut env = HashMap::new();
161            env.insert("ANTHROPIC_AUTH_TOKEN".to_string(), api_key.to_string());
162            env.insert(
163                "ANTHROPIC_BASE_URL".to_string(),
164                "https://api.moonshot.cn/anthropic".to_string(),
165            );
166            env.insert(
167                "ANTHROPIC_MODEL".to_string(),
168                "kimi-k2-thinking".to_string(),
169            );
170            env.insert(
171                "ANTHROPIC_SMALL_FAST_MODEL".to_string(),
172                "kimi-k2-thinking".to_string(),
173            );
174            env.insert("API_TIMEOUT_MS".to_string(), "600000".to_string());
175            env.insert(
176                "CLAUDE_CODE_DISABLE_NONESSENTIAL_TRAFFIC".to_string(),
177                "1".to_string(),
178            );
179            settings.environment = Some(env);
180        }
181
182        settings
183    }
184}
185
186/// Create K2 template settings (legacy compatibility function)
187pub fn create_k2_template(api_key: &str, scope: &SnapshotScope) -> ClaudeSettings {
188    let template = K2Template;
189    template.create_settings(api_key, scope)
190}
191
192/// Create K2 Thinking template settings (legacy compatibility function)
193pub fn create_k2_thinking_template(api_key: &str, scope: &SnapshotScope) -> ClaudeSettings {
194    let template = K2ThinkingTemplate;
195    template.create_settings(api_key, scope)
196}