chutes-plugin 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 zenobi.us
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,387 @@
1
+ # chutes-plugin
2
+
3
+ Chutes Models Plugin for OpenCode - Access 58+ state-of-the-art AI models through the Chutes API.
4
+
5
+ > An OpenCode plugin that integrates Chutes AI models with dynamic synchronization, conflict-free naming, and seamless OpenCode integration.
6
+
7
+ ## Features
8
+
9
+ - **Dynamic Model Sync**: Automatically fetches latest models from `https://llm.chutes.ai/v1/models`
10
+ - **58+ Models**: Access reasoning, coding, vision, and general-purpose models
11
+ - **Conflict-Free Naming**: All models prefixed with `chutes/` to avoid conflicts
12
+ - **Streaming Support**: Real-time response streaming for chat completions
13
+ - **Intelligent Caching**: Model metadata cached for performance
14
+ - **Comprehensive Tools**: `chutes_list_models`, `chutes_refresh_models`, `chutes_status`
15
+ - **Slash Commands**: `/chutes-models` for easy access
16
+
17
+ ## Available Models
18
+
19
+ The plugin provides access to models including:
20
+
21
+ ### Reasoning Models
22
+
23
+ - `chutes/deepseek-ai/DeepSeek-R1` - Advanced reasoning model
24
+ - `chutes/deepseek-ai/DeepSeek-R1-0528-TEE` - Confidential compute reasoning
25
+ - `chutes/Qwen/Qwen3-235B-A22B-Thinking-2507` - Large-scale thinking model
26
+
27
+ ### Coding Models
28
+
29
+ - `chutes/Qwen/Qwen2.5-Coder-32B-Instruct` - Specialized code generation
30
+ - `chutes/mistralai/Devstral-2-123B-Instruct-2512` - Devstral coding model
31
+ - `chutes/Qwen/Qwen3-Coder-480B-A35B-Instruct-FP8-TEE` - Large code model
32
+
33
+ ### Vision Models
34
+
35
+ - `chutes/Qwen/Qwen3-VL-235B-A22B-Instruct` - Vision-language model
36
+ - `chutes/unsloth/gemma-3-27b-it` - Multimodal Gemma
37
+ - `chutes/OpenGVLab/InternVL3-78B-TEE` - InternVL vision model
38
+
39
+ ### General Purpose
40
+
41
+ - `chutes/Qwen/Qwen3-32B` - Balanced general model
42
+ - `chutes/deepseek-ai/DeepSeek-V3` - High-performance general model
43
+ - `chutes/NousResearch/Hermes-4-405B-FP8-TEE` - Large general model
44
+
45
+ ## Getting Started
46
+
47
+ ### 1. Install the Plugin
48
+
49
+ Create or edit `~/.config/opencode/config.json`:
50
+
51
+ ```json
52
+ {
53
+ "plugins": ["chutes-plugin"]
54
+ }
55
+ ```
56
+
57
+ ### 2. Connect Your API Token
58
+
59
+ Use OpenCode's built-in `/connect` command to securely store your Chutes API token:
60
+
61
+ ```
62
+ /connect chutes
63
+ ```
64
+
65
+ Follow the prompts to enter your Chutes API token. The token will be securely stored in `~/.local/share/opencode/auth.json`.
66
+
67
+ Alternatively, you can manually create the auth file:
68
+
69
+ ```json
70
+ {
71
+ "chutes": {
72
+ "type": "api",
73
+ "key": "your-chutes-api-token-here"
74
+ }
75
+ }
76
+ ```
77
+
78
+ You can get your API token from [chutes.ai](https://chutes.ai).
79
+
80
+ ### 3. Restart OpenCode
81
+
82
+ Restart OpenCode to load the plugin. Models will be automatically fetched on startup.
83
+
84
+ ## Configuration
85
+
86
+ ### API Token Storage
87
+
88
+ The plugin reads your Chutes API token from OpenCode's secure auth storage:
89
+
90
+ - **Primary**: Use `/connect chutes` command (recommended)
91
+ - **Manual**: Create `~/.local/share/opencode/auth.json`:
92
+
93
+ ```json
94
+ {
95
+ "chutes": {
96
+ "type": "api",
97
+ "key": "your-chutes-api-token-here"
98
+ }
99
+ }
100
+ ```
101
+
102
+ ### Configuration Options
103
+
104
+ ```json
105
+ {
106
+ "plugins": ["chutes-plugin"],
107
+ "chutes": {
108
+ "autoRefresh": true,
109
+ "refreshInterval": 3600,
110
+ "defaultModel": "chutes/Qwen/Qwen3-32B",
111
+ "modelFilter": ["Qwen/*", "DeepSeek/*"]
112
+ }
113
+ }
114
+ ```
115
+
116
+ | Option | Type | Default | Description |
117
+ | ----------------- | -------- | ------- | ---------------------------------------- |
118
+ | `autoRefresh` | boolean | `true` | Auto-sync models on startup |
119
+ | `refreshInterval` | number | `3600` | Cache TTL in seconds (1 hour) |
120
+ | `defaultModel` | string | - | Default model for chat |
121
+ | `modelFilter` | string[] | - | Optional model whitelist (glob patterns) |
122
+
123
+ ## Usage
124
+
125
+ ### Using Tools
126
+
127
+ #### List Available Models
128
+
129
+ ```typescript
130
+ // List all models
131
+ await chutes_list_models({});
132
+
133
+ // Filter by provider
134
+ await chutes_list_models({
135
+ owned_by: 'Qwen',
136
+ });
137
+
138
+ // Filter by feature
139
+ await chutes_list_models({
140
+ feature: 'reasoning',
141
+ });
142
+
143
+ // Filter by name
144
+ await chutes_list_models({
145
+ filter: 'DeepSeek',
146
+ });
147
+ ```
148
+
149
+ #### Refresh Model List
150
+
151
+ ```typescript
152
+ // Refresh from API
153
+ await chutes_refresh_models({});
154
+
155
+ // Force refresh even if cache is valid
156
+ await chutes_refresh_models({
157
+ force: true,
158
+ });
159
+ ```
160
+
161
+ #### Check Plugin Status
162
+
163
+ ```typescript
164
+ // Check cache status and model count
165
+ await chutes_status();
166
+ ```
167
+
168
+ ### Using Slash Commands
169
+
170
+ #### `/chutes-models`
171
+
172
+ Browse available Chutes models:
173
+
174
+ ```
175
+ /chutes-models
176
+ ```
177
+
178
+ ### Programmatic Usage
179
+
180
+ ```typescript
181
+ import { ChutesPlugin } from 'chutes-plugin';
182
+
183
+ const plugin = await ChutesPlugin();
184
+
185
+ // Access tools
186
+ plugin.tool.chutes_list_models({...});
187
+ plugin.tool.chutes_refresh_models({...});
188
+ plugin.tool.chutes_status({...});
189
+
190
+ // Configure
191
+ await plugin.config({
192
+ chutes: {
193
+ apiToken: "your-token"
194
+ }
195
+ });
196
+ ```
197
+
198
+ ## Model Pricing
199
+
200
+ Models are priced per 1 million tokens. Example pricing:
201
+
202
+ | Model | Input ($/1M) | Output ($/1M) |
203
+ | -------------------------------- | ------------ | ------------- |
204
+ | `chutes/Qwen/Qwen3-32B` | $0.08 | $0.24 |
205
+ | `chutes/deepseek-ai/DeepSeek-R1` | $0.30 | $1.20 |
206
+ | `chutes/unsloth/gemma-3-4b-it` | $0.01 | $0.03 |
207
+
208
+ Full pricing is available in the model list.
209
+
210
+ ## Architecture
211
+
212
+ ```
213
+ src/
214
+ ├── index.ts # Main plugin entry point
215
+ ├── api/
216
+ │ ├── chat.ts # Chat completions client
217
+ │ └── errors.ts # Error classes
218
+ ├── models/
219
+ │ ├── types.ts # TypeScript types
220
+ │ ├── fetcher.ts # Model synchronization
221
+ │ ├── cache.ts # Model caching
222
+ │ └── registry.ts # Model naming registry
223
+ ├── tools/
224
+ │ └── index.ts # Plugin tools
225
+ ├── config/
226
+ │ └── schema.ts # Configuration validation
227
+ └── commands/
228
+ └── chutes-models.md # /chutes-models command
229
+ ```
230
+
231
+ ## Development
232
+
233
+ ### Build
234
+
235
+ ```bash
236
+ mise run build
237
+ # or
238
+ bun build ./src/index.ts --outdir dist --target bun
239
+ ```
240
+
241
+ ### Test
242
+
243
+ ```bash
244
+ mise run test
245
+ # or
246
+ bun test
247
+ ```
248
+
249
+ ### Lint
250
+
251
+ ```bash
252
+ mise run lint
253
+ # or
254
+ bun run eslint src/
255
+ ```
256
+
257
+ ### Format
258
+
259
+ ```bash
260
+ mise run format
261
+ # or
262
+ bun run prettier --write src/
263
+ ```
264
+
265
+ ## Publishing
266
+
267
+ ### Version Bump
268
+
269
+ ```bash
270
+ # Bump version (patch, minor, or major)
271
+ npm version patch # 1.0.0 -> 1.0.1
272
+ npm version minor # 1.0.0 -> 1.1.0
273
+ npm version major # 1.0.0 -> 2.0.0
274
+ ```
275
+
276
+ ### Publish to npm
277
+
278
+ ```bash
279
+ # Login to npm (first time only)
280
+ npm login
281
+
282
+ # Publish the package
283
+ npm publish
284
+
285
+ # Publish with access to public (for scoped packages)
286
+ npm publish --access public
287
+ ```
288
+
289
+ ### Pre-release
290
+
291
+ ```bash
292
+ # Create a beta release
293
+ npm version prerelease --preid=beta
294
+ npm publish --tag beta
295
+ ```
296
+
297
+ ## API Reference
298
+
299
+ ### ChutesClient
300
+
301
+ ```typescript
302
+ import { ChutesClient } from './api/chat';
303
+
304
+ const client = new ChutesClient({
305
+ apiBaseUrl: 'https://llm.chutes.ai/v1',
306
+ apiToken: 'your-token',
307
+ });
308
+
309
+ // Non-streaming completion
310
+ const response = await client.createChatCompletion({
311
+ model: 'Qwen/Qwen3-32B',
312
+ messages: [{ role: 'user', content: 'Hello!' }],
313
+ });
314
+
315
+ // Streaming completion
316
+ for await (const chunk of client.createChatCompletionStream(request)) {
317
+ console.log(chunk.choices[0]?.delta?.content);
318
+ }
319
+ ```
320
+
321
+ ### ModelFetcher
322
+
323
+ ```typescript
324
+ import { ModelFetcher } from './models/fetcher';
325
+
326
+ const fetcher = new ModelFetcher({
327
+ apiBaseUrl: 'https://llm.chutes.ai/v1',
328
+ cacheTtlSeconds: 3600,
329
+ });
330
+
331
+ fetcher.setApiToken('your-token');
332
+
333
+ // Fetch models
334
+ const models = await fetcher.fetchModels();
335
+
336
+ // Get cached models
337
+ const cached = fetcher.getCachedModels();
338
+
339
+ // Force refresh
340
+ await fetcher.refreshModels(true);
341
+ ```
342
+
343
+ ## Troubleshooting
344
+
345
+ ### "No API token configured"
346
+
347
+ Ensure you've connected your Chutes API token using the `/connect chutes` command or created `~/.local/share/opencode/auth.json` with your token.
348
+
349
+ ### "Model not found"
350
+
351
+ Use `chutes_list_models` to see available models. Model IDs must be prefixed with `chutes/`.
352
+
353
+ ### "Rate limit exceeded"
354
+
355
+ Wait a moment and retry. Consider reducing request frequency.
356
+
357
+ ### Models not appearing
358
+
359
+ 1. Check your API token is valid
360
+ 2. Run `chutes_refresh_models({ force: true })`
361
+ 3. Check plugin status with `chutes_status`
362
+
363
+ ## Contributing
364
+
365
+ 1. Fork the repository
366
+ 2. Create a feature branch
367
+ 3. Make your changes
368
+ 4. Run tests and linting
369
+ 5. Submit a pull request
370
+
371
+ ## License
372
+
373
+ MIT License. See the [LICENSE](LICENSE) file for details.
374
+
375
+ ## Author
376
+
377
+ Gianmarco Martinelli <mark182@gmail.com>
378
+
379
+ ## Repository
380
+
381
+ https://github.com/zenobi-us/chutes-plugin
382
+
383
+ ## Chutes API
384
+
385
+ - Models API: `https://llm.chutes.ai/v1/models`
386
+ - Chat API: `https://llm.chutes.ai/v1/chat/completions`
387
+ - Documentation: https://docs.chutes.ai