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 = "http"; 15 url = "https://mcp.context7.com/mcp"; 16 headers = { 17 CONTEXT7_API_KEY = "$(cat /run/agenix/context7)"; 18 }; 19 }; 20 sequential-thinking = { 21 command = "bunx"; 22 args = [ 23 "-y" 24 "@modelcontextprotocol/server-sequential-thinking" 25 ]; 26 }; 27 }; 28 providers = { 29 copilot = { 30 name = "Copilot"; 31 type = "openai"; 32 base_url = "https://api.githubcopilot.com"; 33 api_key = "$(bash ~/.config/crush/copilot.sh)"; 34 extra_headers = { 35 "Editor-Version" = "CRUSH/1.0"; 36 "Editor-Plugin-Version" = "CRUSH/1.0"; 37 "Copilot-Integration-Id" = "vscode-chat"; 38 }; 39 models = [ 40 { 41 id = "gpt-4.1"; 42 name = "Copilot: GPT-4.1"; 43 cost_per_1m_in = 0; 44 cost_per_1m_out = 0; 45 cost_per_1m_in_cached = 0; 46 cost_per_1m_out_cached = 0; 47 context_window = 128000; 48 default_max_tokens = 16384; 49 can_reason = true; 50 has_reasoning_efforts = false; 51 supports_attachments = true; 52 } 53 { 54 id = "gpt-5-mini"; 55 name = "Copilot: GPT-5 mini"; 56 cost_per_1m_in = 0; 57 cost_per_1m_out = 0; 58 cost_per_1m_in_cached = 0; 59 cost_per_1m_out_cached = 0; 60 context_window = 264000; 61 default_max_tokens = 64000; 62 can_reason = true; 63 has_reasoning_efforts = false; 64 supports_attachments = true; 65 } 66 { 67 id = "gpt-5"; 68 name = "Copilot: GPT-5"; 69 cost_per_1m_in = 0; 70 cost_per_1m_out = 0; 71 cost_per_1m_in_cached = 0; 72 cost_per_1m_out_cached = 0; 73 context_window = 400000; 74 default_max_tokens = 128000; 75 can_reason = true; 76 has_reasoning_efforts = false; 77 supports_attachments = true; 78 } 79 { 80 id = "gpt-4o"; 81 name = "Copilot: GPT-4o"; 82 cost_per_1m_in = 0; 83 cost_per_1m_out = 0; 84 cost_per_1m_in_cached = 0; 85 cost_per_1m_out_cached = 0; 86 context_window = 128000; 87 default_max_tokens = 4096; 88 can_reason = true; 89 has_reasoning_efforts = false; 90 supports_attachments = true; 91 } 92 { 93 id = "grok-code-fast-1"; 94 name = "Copilot: Grok Code Fast 1"; 95 cost_per_1m_in = 0; 96 cost_per_1m_out = 0; 97 cost_per_1m_in_cached = 0; 98 cost_per_1m_out_cached = 0; 99 context_window = 128000; 100 default_max_tokens = 64000; 101 can_reason = true; 102 has_reasoning_efforts = false; 103 supports_attachments = false; 104 } 105 { 106 id = "gpt-5-codex"; 107 name = "Copilot: GPT-5-Codex (Preview)"; 108 cost_per_1m_in = 0; 109 cost_per_1m_out = 0; 110 cost_per_1m_in_cached = 0; 111 cost_per_1m_out_cached = 0; 112 context_window = 400000; 113 default_max_tokens = 128000; 114 can_reason = true; 115 has_reasoning_efforts = false; 116 supports_attachments = true; 117 } 118 { 119 id = "claude-3.5-sonnet"; 120 name = "Copilot: Claude Sonnet 3.5"; 121 cost_per_1m_in = 0; 122 cost_per_1m_out = 0; 123 cost_per_1m_in_cached = 0; 124 cost_per_1m_out_cached = 0; 125 context_window = 90000; 126 default_max_tokens = 8192; 127 can_reason = true; 128 has_reasoning_efforts = false; 129 supports_attachments = true; 130 } 131 { 132 id = "claude-sonnet-4"; 133 name = "Copilot: Claude Sonnet 4"; 134 cost_per_1m_in = 0; 135 cost_per_1m_out = 0; 136 cost_per_1m_in_cached = 0; 137 cost_per_1m_out_cached = 0; 138 context_window = 216000; 139 default_max_tokens = 16000; 140 can_reason = true; 141 has_reasoning_efforts = false; 142 supports_attachments = true; 143 } 144 { 145 id = "claude-sonnet-4.5"; 146 name = "Copilot: Claude Sonnet 4.5"; 147 cost_per_1m_in = 0; 148 cost_per_1m_out = 0; 149 cost_per_1m_in_cached = 0; 150 cost_per_1m_out_cached = 0; 151 context_window = 144000; 152 default_max_tokens = 16000; 153 can_reason = true; 154 has_reasoning_efforts = false; 155 supports_attachments = true; 156 } 157 { 158 id = "claude-haiku-4.5"; 159 name = "Copilot: Claude Haiku 4.5"; 160 cost_per_1m_in = 0; 161 cost_per_1m_out = 0; 162 cost_per_1m_in_cached = 0; 163 cost_per_1m_out_cached = 0; 164 context_window = 144000; 165 default_max_tokens = 16000; 166 can_reason = true; 167 has_reasoning_efforts = false; 168 supports_attachments = true; 169 } 170 { 171 id = "gemini-2.5-pro"; 172 name = "Copilot: Gemini 2.5 Pro"; 173 cost_per_1m_in = 0; 174 cost_per_1m_out = 0; 175 cost_per_1m_in_cached = 0; 176 cost_per_1m_out_cached = 0; 177 context_window = 128000; 178 default_max_tokens = 64000; 179 can_reason = true; 180 has_reasoning_efforts = false; 181 supports_attachments = true; 182 } 183 ]; 184 }; 185 hyper = { 186 name = "Charm Hyper"; 187 base_url = "https://hyper.charm.sh/api/v1/openai/"; 188 api_key = "$(cat /run/agenix/crush)"; 189 type = "openai"; 190 models = [ 191 { 192 name = "Qwen 3 Coder"; 193 id = "qwen3_coder"; 194 context_window = 118000; 195 default_max_tokens = 20000; 196 } 197 ]; 198 }; 199 claude-pro = { 200 name = "Claude Pro"; 201 type = "anthropic"; 202 base_url = "https://api.anthropic.com"; 203 api_key = "Bearer $(bunx anthropic-api-key)"; 204 system_prompt_prefix = "You are Claude Code, Anthropic's official CLI for Claude."; 205 extra_headers = { 206 "anthropic-version" = "2023-06-01"; 207 "anthropic-beta" = "oauth-2025-04-20"; 208 }; 209 models = [ 210 { 211 id = "claude-haiku-4-5-20251001"; 212 name = "Claude Haiku 4.5"; 213 cost_per_1m_in = 3.0; 214 cost_per_1m_out = 15.0; 215 cost_per_1m_in_cached = 0.225; 216 cost_per_1m_out_cached = 15.0; 217 context_window = 200000; 218 default_max_tokens = 8192; 219 can_reason = true; 220 has_reasoning_efforts = false; 221 supports_attachments = true; 222 } 223 { 224 id = "claude-sonnet-4-5-20250929"; 225 name = "Claude Sonnet 4.5"; 226 cost_per_1m_in = 3.0; 227 cost_per_1m_out = 15.0; 228 cost_per_1m_in_cached = 0.225; 229 cost_per_1m_out_cached = 15.0; 230 context_window = 200000; 231 default_max_tokens = 64000; 232 can_reason = true; 233 has_reasoning_efforts = false; 234 supports_attachments = true; 235 } 236 { 237 id = "claude-opus-4-1-20250805"; 238 name = "Claude Opus 4.1"; 239 cost_per_1m_in = 15.0; 240 cost_per_1m_out = 75.0; 241 cost_per_1m_in_cached = 1.5; 242 cost_per_1m_out_cached = 75.0; 243 context_window = 200000; 244 default_max_tokens = 32000; 245 can_reason = true; 246 has_reasoning_efforts = true; 247 supports_attachments = true; 248 } 249 { 250 id = "claude-opus-4-20250514"; 251 name = "Claude Opus 4"; 252 cost_per_1m_in = 15.0; 253 cost_per_1m_out = 75.0; 254 cost_per_1m_in_cached = 1.5; 255 cost_per_1m_out_cached = 75.0; 256 context_window = 200000; 257 default_max_tokens = 32000; 258 can_reason = true; 259 has_reasoning_efforts = true; 260 supports_attachments = true; 261 } 262 { 263 id = "claude-sonnet-4-20250514"; 264 name = "Claude Sonnet 4"; 265 cost_per_1m_in = 3.0; 266 cost_per_1m_out = 15.0; 267 cost_per_1m_in_cached = 0.225; 268 cost_per_1m_out_cached = 15.0; 269 context_window = 200000; 270 default_max_tokens = 64000; 271 can_reason = true; 272 has_reasoning_efforts = false; 273 supports_attachments = true; 274 } 275 { 276 id = "claude-3-7-sonnet-20250219"; 277 name = "Claude Sonnet 3.7"; 278 cost_per_1m_in = 2.5; 279 cost_per_1m_out = 12.0; 280 cost_per_1m_in_cached = 0.187; 281 cost_per_1m_out_cached = 12.0; 282 context_window = 200000; 283 default_max_tokens = 64000; 284 can_reason = true; 285 has_reasoning_efforts = false; 286 supports_attachments = true; 287 } 288 { 289 id = "claude-3-5-haiku-20241022"; 290 name = "Claude Haiku 3.5"; 291 cost_per_1m_in = 0.8; 292 cost_per_1m_out = 4.0; 293 cost_per_1m_in_cached = 0.06; 294 cost_per_1m_out_cached = 4.0; 295 context_window = 200000; 296 default_max_tokens = 8192; 297 can_reason = true; 298 has_reasoning_efforts = false; 299 supports_attachments = true; 300 } 301 { 302 id = "claude-3-haiku-20240307"; 303 name = "Claude Haiku 3"; 304 cost_per_1m_in = 0.25; 305 cost_per_1m_out = 1.25; 306 cost_per_1m_in_cached = 0.03; 307 cost_per_1m_out_cached = 1.25; 308 context_window = 200000; 309 default_max_tokens = 4096; 310 can_reason = true; 311 has_reasoning_efforts = false; 312 supports_attachments = true; 313 } 314 { 315 id = "claude-3-opus-20240229"; 316 name = "Claude Opus 3"; 317 cost_per_1m_in = 15.0; 318 cost_per_1m_out = 75.0; 319 cost_per_1m_in_cached = 1.5; 320 cost_per_1m_out_cached = 75.0; 321 context_window = 200000; 322 default_max_tokens = 8192; 323 can_reason = true; 324 has_reasoning_efforts = false; 325 supports_attachments = true; 326 } 327 ]; 328 }; 329 }; 330 }; 331 }; 332 333 xdg.configFile."crush/copilot.sh".source = ../../../dots/copilot.sh; 334 }; 335}