Kieran's opinionated (and probably slightly dumb) nix config
1{
2 lib,
3 config,
4 ...
5}:
6{
7 options.atelier.apps.crush.enable = lib.mkEnableOption "Enable Crush config";
8 config = lib.mkIf config.atelier.apps.crush.enable {
9 programs.crush = {
10 enable = true;
11 settings = {
12 mcp = {
13 context7 = {
14 type = "sse";
15 url = "https://mcp.context7.com/sse";
16 };
17 sequential-thinking = {
18 command = "bunx";
19 args = [
20 "-y"
21 "@modelcontextprotocol/server-sequential-thinking"
22 ];
23 };
24 };
25 providers = {
26 copilot = {
27 name = "Copilot";
28 type = "openai";
29 base_url = "https://api.githubcopilot.com";
30 api_key = "$(bash ~/.config/crush/copilot.sh)";
31 extra_headers = {
32 "Editor-Version" = "CRUSH/1.0";
33 "Editor-Plugin-Version" = "CRUSH/1.0";
34 "Copilot-Integration-Id" = "vscode-chat";
35 };
36 models = [
37 {
38 id = "gpt-4.1";
39 name = "Copilot: GPT-4.1";
40 cost_per_1m_in = 0;
41 cost_per_1m_out = 0;
42 cost_per_1m_in_cached = 0;
43 cost_per_1m_out_cached = 0;
44 context_window = 128000;
45 default_max_tokens = 16384;
46 can_reason = false;
47 has_reasoning_efforts = false;
48 supports_attachments = false;
49 }
50 {
51 id = "gpt-5-mini";
52 name = "Copilot: GPT-5 mini (Preview)";
53 cost_per_1m_in = 0;
54 cost_per_1m_out = 0;
55 cost_per_1m_in_cached = 0;
56 cost_per_1m_out_cached = 0;
57 context_window = 128000;
58 default_max_tokens = 64000;
59 can_reason = false;
60 has_reasoning_efforts = false;
61 supports_attachments = false;
62 }
63 {
64 id = "gpt-5";
65 name = "Copilot: GPT-5 (Preview)";
66 cost_per_1m_in = 0;
67 cost_per_1m_out = 0;
68 cost_per_1m_in_cached = 0;
69 cost_per_1m_out_cached = 0;
70 context_window = 128000;
71 default_max_tokens = 64000;
72 can_reason = false;
73 has_reasoning_efforts = false;
74 supports_attachments = false;
75 }
76 {
77 id = "gpt-4o";
78 name = "Copilot: GPT-4o";
79 cost_per_1m_in = 0;
80 cost_per_1m_out = 0;
81 cost_per_1m_in_cached = 0;
82 cost_per_1m_out_cached = 0;
83 context_window = 128000;
84 default_max_tokens = 4096;
85 can_reason = false;
86 has_reasoning_efforts = false;
87 supports_attachments = false;
88 }
89 {
90 id = "o3-mini";
91 name = "Copilot: o3-mini";
92 cost_per_1m_in = 0;
93 cost_per_1m_out = 0;
94 cost_per_1m_in_cached = 0;
95 cost_per_1m_out_cached = 0;
96 context_window = 200000;
97 default_max_tokens = 100000;
98 can_reason = false;
99 has_reasoning_efforts = false;
100 supports_attachments = false;
101 }
102 {
103 id = "claude-3.5-sonnet";
104 name = "Copilot: Claude Sonnet 3.5";
105 cost_per_1m_in = 0;
106 cost_per_1m_out = 0;
107 cost_per_1m_in_cached = 0;
108 cost_per_1m_out_cached = 0;
109 context_window = 90000;
110 default_max_tokens = 8192;
111 can_reason = true;
112 has_reasoning_efforts = false;
113 supports_attachments = true;
114 }
115 {
116 id = "claude-3.7-sonnet";
117 name = "Copilot: Claude Sonnet 3.7";
118 cost_per_1m_in = 0;
119 cost_per_1m_out = 0;
120 cost_per_1m_in_cached = 0;
121 cost_per_1m_out_cached = 0;
122 context_window = 200000;
123 default_max_tokens = 16384;
124 can_reason = true;
125 has_reasoning_efforts = false;
126 supports_attachments = true;
127 }
128 {
129 id = "claude-3.7-sonnet-thought";
130 name = "Copilot: Claude Sonnet 3.7 Thinking";
131 cost_per_1m_in = 0;
132 cost_per_1m_out = 0;
133 cost_per_1m_in_cached = 0;
134 cost_per_1m_out_cached = 0;
135 context_window = 200000;
136 default_max_tokens = 16384;
137 can_reason = true;
138 has_reasoning_efforts = false;
139 supports_attachments = true;
140 }
141 {
142 id = "claude-sonnet-4";
143 name = "Copilot: Claude Sonnet 4";
144 cost_per_1m_in = 0;
145 cost_per_1m_out = 0;
146 cost_per_1m_in_cached = 0;
147 cost_per_1m_out_cached = 0;
148 context_window = 128000;
149 default_max_tokens = 16000;
150 can_reason = true;
151 has_reasoning_efforts = false;
152 supports_attachments = true;
153 }
154 {
155 id = "gemini-2.0-flash-001";
156 name = "Copilot: Gemini 2.0 Flash";
157 cost_per_1m_in = 0;
158 cost_per_1m_out = 0;
159 cost_per_1m_in_cached = 0;
160 cost_per_1m_out_cached = 0;
161 context_window = 1000000;
162 default_max_tokens = 8192;
163 can_reason = true;
164 has_reasoning_efforts = false;
165 supports_attachments = true;
166 }
167 {
168 id = "gemini-2.5-pro";
169 name = "Copilot: Gemini 2.5 Pro (Preview)";
170 cost_per_1m_in = 0;
171 cost_per_1m_out = 0;
172 cost_per_1m_in_cached = 0;
173 cost_per_1m_out_cached = 0;
174 context_window = 128000;
175 default_max_tokens = 64000;
176 can_reason = true;
177 has_reasoning_efforts = false;
178 supports_attachments = true;
179 }
180 {
181 id = "o4-mini";
182 name = "Copilot: o4-mini (Preview)";
183 cost_per_1m_in = 0;
184 cost_per_1m_out = 0;
185 cost_per_1m_in_cached = 0;
186 cost_per_1m_out_cached = 0;
187 context_window = 128000;
188 default_max_tokens = 16384;
189 can_reason = false;
190 has_reasoning_efforts = false;
191 supports_attachments = false;
192 }
193 ];
194 };
195 hyper = {
196 name = "Charm Hyper";
197 base_url = "https://hyper.charm.sh/api/v1/openai/";
198 api_key = "$(cat /run/agenix/crush)";
199 type = "openai";
200 models = [
201 {
202 name = "Qwen 3 Coder";
203 id = "qwen3_coder";
204 context_window = 118000;
205 default_max_tokens = 20000;
206 }
207 ];
208 };
209 claude-pro = {
210 name = "Claude Pro";
211 type = "anthropic";
212 base_url = "https://api.anthropic.com";
213 api_key = "Bearer $(bunx anthropic-api-key)";
214 system_prompt_prefix = "You are Claude Code, Anthropic's official CLI for Claude.";
215 extra_headers = {
216 "anthropic-version" = "2023-06-01";
217 "anthropic-beta" = "oauth-2025-04-20";
218 };
219 models = [
220 {
221 id = "claude-opus-4-20250514";
222 name = "Claude Opus 4";
223 cost_per_1m_in = 15.0;
224 cost_per_1m_out = 75.0;
225 cost_per_1m_in_cached = 1.5;
226 cost_per_1m_out_cached = 75.0;
227 context_window = 200000;
228 default_max_tokens = 50000;
229 can_reason = true;
230 has_reasoning_efforts = true;
231 supports_attachments = true;
232 }
233 {
234 id = "claude-sonnet-4-20250514";
235 name = "Claude Sonnet 4";
236 cost_per_1m_in = 3000;
237 cost_per_1m_out = 15000;
238 cost_per_1m_in_cached = 225;
239 cost_per_1m_out_cached = 15000;
240 context_window = 200000;
241 default_max_tokens = 50000;
242 can_reason = true;
243 has_reasoning_efforts = false;
244 supports_attachments = true;
245 }
246 {
247 id = "claude-3-7-sonnet-20250219";
248 name = "Claude 3.7 Sonnet";
249 cost_per_1m_in = 2.5;
250 cost_per_1m_out = 12.0;
251 cost_per_1m_in_cached = 0.187;
252 cost_per_1m_out_cached = 12.0;
253 context_window = 200000;
254 default_max_tokens = 64000;
255 can_reason = true;
256 has_reasoning_efforts = false;
257 supports_attachments = true;
258 }
259 {
260 id = "claude-3-5-sonnet-20241022";
261 name = "Claude 3.5 Sonnet (Latest)";
262 cost_per_1m_in = 3.0;
263 cost_per_1m_out = 15.0;
264 cost_per_1m_in_cached = 0.225;
265 cost_per_1m_out_cached = 15.0;
266 context_window = 200000;
267 default_max_tokens = 8192;
268 can_reason = false;
269 has_reasoning_efforts = false;
270 supports_attachments = true;
271 }
272 {
273 id = "claude-3-5-haiku-20241022";
274 name = "Claude 3.5 Haiku";
275 cost_per_1m_in = 0.8;
276 cost_per_1m_out = 4.0;
277 cost_per_1m_in_cached = 0.06;
278 cost_per_1m_out_cached = 4.0;
279 context_window = 200000;
280 default_max_tokens = 8192;
281 can_reason = false;
282 has_reasoning_efforts = false;
283 supports_attachments = true;
284 }
285 ];
286 };
287 };
288 };
289 };
290
291 xdg.configFile."crush/copilot.sh".source = ../../../dots/copilot.sh;
292 xdg.configFile."crush/anthropic.sh".source = ../../../dots/anthropic.sh;
293 };
294}