opencode-free-fleet 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 +20 -0
- package/README.md +323 -0
- package/package.json +49 -0
- package/src/version.ts +6 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Phorde
|
|
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 SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# OpenCode Free Fleet
|
|
2
|
+
|
|
3
|
+
🚀 **Economic Load Balancing and Zero-Cost Model Discovery for OpenCode**
|
|
4
|
+
|
|
5
|
+
An intelligent plugin that automatically discovers, ranks, and competes free LLM models based on SOTA benchmark performance, enabling zero-cost, zero-latency execution for OpenCode agents.
|
|
6
|
+
|
|
7
|
+
## Philosophy
|
|
8
|
+
|
|
9
|
+
**Quality > Quantity**
|
|
10
|
+
|
|
11
|
+
Only models with proven benchmark performance (SOTA) are included in Elite tier. The Free Fleet prioritizes models that achieve top scores on relevant benchmarks like HumanEval, GSM8K, MATH, ARC-C, MT-Bench, and more.
|
|
12
|
+
|
|
13
|
+
## Features
|
|
14
|
+
|
|
15
|
+
### 🤖 The Scout - Automatic Discovery
|
|
16
|
+
- Fetches all models from OpenRouter API
|
|
17
|
+
- Filters for truly free models (`pricing.prompt === "0"` AND `pricing.completion === "0"`)
|
|
18
|
+
- Respects security blocklists (paid/authenticated models are never used for free-only tasks)
|
|
19
|
+
- Ranks models by benchmark performance (Elite > Newer > Larger)
|
|
20
|
+
|
|
21
|
+
### ⚡ The Racer - Zero-Latency Competition
|
|
22
|
+
- Uses `Promise.any` for race condition between free models
|
|
23
|
+
- Fires all requests simultaneously and accepts first valid response
|
|
24
|
+
- Eliminates waterfall latency
|
|
25
|
+
- Supports `AbortController` for timeout handling
|
|
26
|
+
- Progress callbacks for monitoring
|
|
27
|
+
|
|
28
|
+
### 🛡️ Security & Safety
|
|
29
|
+
- Reads `antigravity-accounts.json` to build a blocklist of authenticated providers
|
|
30
|
+
- Never routes free-only tasks to paid models accidentally
|
|
31
|
+
- Ensures zero-cost execution whenever possible
|
|
32
|
+
|
|
33
|
+
## Installation
|
|
34
|
+
|
|
35
|
+
### From local files (Recommended)
|
|
36
|
+
|
|
37
|
+
Clone and place in `~/.config/opencode/plugins/`:
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
# Clone from GitHub
|
|
41
|
+
git clone https://github.com/phorde/opencode-free-fleet.git ~/.config/opencode/plugins/opencode-free-fleet
|
|
42
|
+
|
|
43
|
+
# Or from local directory
|
|
44
|
+
npm install file:~/Projetos/opencode-free-fleet
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
### From npm (Coming Soon)
|
|
48
|
+
|
|
49
|
+
After publishing to npm, you can add to your `~/.config/opencode/opencode.json`:
|
|
50
|
+
|
|
51
|
+
```jsonc
|
|
52
|
+
{
|
|
53
|
+
"plugin": [
|
|
54
|
+
"opencode-free-fleet"
|
|
55
|
+
]
|
|
56
|
+
}
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
**Note:** This plugin is currently in development. Install from local files for the latest features.
|
|
60
|
+
|
|
61
|
+
## Usage
|
|
62
|
+
|
|
63
|
+
### Running Model Discovery
|
|
64
|
+
|
|
65
|
+
The Scout runs automatically on plugin startup. You can also trigger it manually:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
opencode
|
|
69
|
+
# Then in the TUI:
|
|
70
|
+
/fleet-discover
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Racing Between Models
|
|
74
|
+
|
|
75
|
+
For speed-critical operations, use the competition pattern:
|
|
76
|
+
|
|
77
|
+
```typescript
|
|
78
|
+
import { FreeModelRacer } from 'opencode-free-fleet';
|
|
79
|
+
|
|
80
|
+
const racer = new FreeModelRacer({
|
|
81
|
+
timeoutMs: 15000,
|
|
82
|
+
onProgress: (model, status) => {
|
|
83
|
+
console.log(`${model}: ${status}`);
|
|
84
|
+
}
|
|
85
|
+
});
|
|
86
|
+
|
|
87
|
+
const winner = await racer.race(
|
|
88
|
+
[
|
|
89
|
+
'openrouter/deepseek/deepseek-v3.2',
|
|
90
|
+
'openrouter/zai-coding-plan/glm-4.7-flash',
|
|
91
|
+
'openrouter/mistralai/mistral-small-3.1-24b-instruct:free'
|
|
92
|
+
],
|
|
93
|
+
async (model) => {
|
|
94
|
+
// Execute your task with this model
|
|
95
|
+
return await client.chat.completions.create({ model, messages });
|
|
96
|
+
}
|
|
97
|
+
);
|
|
98
|
+
|
|
99
|
+
console.log(`Fastest: ${winner.model} (${winner.duration}ms)`);
|
|
100
|
+
return winner.result;
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Elite Model Families
|
|
104
|
+
|
|
105
|
+
### Coding Elite
|
|
106
|
+
High HumanEval, MBPP, Codeforces scores:
|
|
107
|
+
- `qwen-2.5-coder` (85.4% HumanEval)
|
|
108
|
+
- `qwen3-coder`
|
|
109
|
+
- `deepseek-v3` (90.6% HumanEval)
|
|
110
|
+
- `deepseek-coder`
|
|
111
|
+
- `llama-3.3-70b` (82.4% HumanEval)
|
|
112
|
+
- `codestral`
|
|
113
|
+
- `starcoder`
|
|
114
|
+
|
|
115
|
+
### Reasoning Elite
|
|
116
|
+
High GSM8K, MATH, ARC-C scores:
|
|
117
|
+
- `deepseek-r1` (89.5% GSM8K)
|
|
118
|
+
- `qwq` (85.7% MATH)
|
|
119
|
+
- `o1-open` (91.2% ARC-C)
|
|
120
|
+
- Models with `r1`, `reasoning`, `cot`, `qwq`
|
|
121
|
+
|
|
122
|
+
### Speed/Chat Elite
|
|
123
|
+
Fast inference + high MT-Bench:
|
|
124
|
+
- `mistral-small` (8.1 MT-Bench)
|
|
125
|
+
- `haiku-4-5` (8.4 MT-Bench)
|
|
126
|
+
- `flash` (8.2 MT-Bench)
|
|
127
|
+
- `gemma-2` (7.9 MT-Bench)
|
|
128
|
+
- `gemma-3`
|
|
129
|
+
- `distill`
|
|
130
|
+
- `nano`
|
|
131
|
+
- `lite`
|
|
132
|
+
|
|
133
|
+
### Multimodal Elite
|
|
134
|
+
- `vl`, `vision`, `molmo`
|
|
135
|
+
- `nemotron-vl`, `pixtral`
|
|
136
|
+
- `qwen-vl`
|
|
137
|
+
|
|
138
|
+
### Writing Elite
|
|
139
|
+
- `trinity`
|
|
140
|
+
- `qwen-next`
|
|
141
|
+
- `chimera`
|
|
142
|
+
- `writer`
|
|
143
|
+
|
|
144
|
+
## API Reference
|
|
145
|
+
|
|
146
|
+
### Scout
|
|
147
|
+
|
|
148
|
+
```typescript
|
|
149
|
+
import { Scout, createScout } from 'opencode-free-fleet';
|
|
150
|
+
|
|
151
|
+
// Create scout instance
|
|
152
|
+
const scout = createScout({
|
|
153
|
+
antigravityPath: '~/.config/opencode/antigravity-accounts.json',
|
|
154
|
+
opencodeConfigPath: '~/.config/opencode/oh-my-opencode.json'
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
// Discover and rank free models
|
|
158
|
+
const results = await scout.discover();
|
|
159
|
+
|
|
160
|
+
// Print summary
|
|
161
|
+
scout.printSummary(results);
|
|
162
|
+
|
|
163
|
+
// Access results by category
|
|
164
|
+
const codingResults = results.coding;
|
|
165
|
+
console.log(`Top coding model: ${codingResults.rankedModels[0].id}`);
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
### FreeModelRacer
|
|
169
|
+
|
|
170
|
+
```typescript
|
|
171
|
+
import { FreeModelRacer, createRacer, competeFreeModels } from 'opencode-free-fleet';
|
|
172
|
+
|
|
173
|
+
// Create racer instance
|
|
174
|
+
const racer = new FreeModelRacer({
|
|
175
|
+
timeoutMs: 30000,
|
|
176
|
+
onProgress: (model, status, error) => {
|
|
177
|
+
// Monitor race progress
|
|
178
|
+
}
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
// Race between models
|
|
182
|
+
const winner = await racer.race(
|
|
183
|
+
models,
|
|
184
|
+
executeWithModel,
|
|
185
|
+
raceId
|
|
186
|
+
);
|
|
187
|
+
|
|
188
|
+
// Cancel active race
|
|
189
|
+
racer.cancelRace(raceId);
|
|
190
|
+
|
|
191
|
+
// Cancel all races
|
|
192
|
+
racer.cancelAllRaces();
|
|
193
|
+
|
|
194
|
+
// Check race status
|
|
195
|
+
racer.isRaceActive(raceId);
|
|
196
|
+
racer.getActiveRaceCount();
|
|
197
|
+
|
|
198
|
+
// Update config
|
|
199
|
+
racer.updateConfig({ timeoutMs: 15000 });
|
|
200
|
+
```
|
|
201
|
+
|
|
202
|
+
### Custom Tools
|
|
203
|
+
|
|
204
|
+
The plugin adds two custom tools to OpenCode:
|
|
205
|
+
|
|
206
|
+
#### `fleet-discover`
|
|
207
|
+
Trigger manual model discovery with optional category filter.
|
|
208
|
+
|
|
209
|
+
**Arguments:**
|
|
210
|
+
- `category` (optional): Filter by category (coding, reasoning, speed, multimodal, writing)
|
|
211
|
+
- `top` (optional): Number of top models to display (default: 5)
|
|
212
|
+
|
|
213
|
+
**Example:**
|
|
214
|
+
```
|
|
215
|
+
/fleet-discover category="coding" top=3
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
#### `fleet-race`
|
|
219
|
+
Race between free models and return fastest response.
|
|
220
|
+
|
|
221
|
+
**Arguments:**
|
|
222
|
+
- `models` (required): Array of model identifiers
|
|
223
|
+
- `prompt` (required): Prompt to send to each model
|
|
224
|
+
- `timeoutMs` (optional): Timeout in milliseconds (default: 30000)
|
|
225
|
+
|
|
226
|
+
**Example:**
|
|
227
|
+
```
|
|
228
|
+
/fleet-race models='["deepseek/deepseek-v3.2", "glm-4.7-flash"]' prompt="Hello, world!"
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
## Ranking Algorithm
|
|
232
|
+
|
|
233
|
+
Models are sorted by:
|
|
234
|
+
|
|
235
|
+
1. **Elite family membership** (SOTA models get priority)
|
|
236
|
+
2. **Parameter count** (larger > smaller, except for speed category)
|
|
237
|
+
3. **Alphabetical order** (newer models often have newer names) as tiebreaker
|
|
238
|
+
|
|
239
|
+
For `speed` category, smaller models are prioritized.
|
|
240
|
+
|
|
241
|
+
## Architecture
|
|
242
|
+
|
|
243
|
+
```
|
|
244
|
+
opencode-free-fleet/
|
|
245
|
+
├── src/
|
|
246
|
+
│ ├── core/
|
|
247
|
+
│ │ ├── scout.ts # Model discovery and ranking
|
|
248
|
+
│ │ └── racer.ts # Model competition logic
|
|
249
|
+
│ ├── types/
|
|
250
|
+
│ │ └── index.ts # TypeScript interfaces
|
|
251
|
+
│ ├── index.ts # Plugin entrypoint
|
|
252
|
+
│ └── version.ts # Version info
|
|
253
|
+
├── test/
|
|
254
|
+
│ ├── scout.test.ts # Scout unit tests
|
|
255
|
+
│ └── racer.test.ts # Racer unit tests
|
|
256
|
+
├── package.json
|
|
257
|
+
├── tsconfig.json
|
|
258
|
+
└── README.md
|
|
259
|
+
```
|
|
260
|
+
|
|
261
|
+
## Configuration
|
|
262
|
+
|
|
263
|
+
### Environment Variables
|
|
264
|
+
|
|
265
|
+
No environment variables required. The plugin reads configuration files directly from `~/.config/opencode/`.
|
|
266
|
+
|
|
267
|
+
### Files Read
|
|
268
|
+
|
|
269
|
+
- `~/.config/opencode/antigravity-accounts.json` - For building security blocklist
|
|
270
|
+
|
|
271
|
+
## Development
|
|
272
|
+
|
|
273
|
+
### Available Scripts
|
|
274
|
+
|
|
275
|
+
```bash
|
|
276
|
+
bun install # Install dependencies
|
|
277
|
+
bun run build # Build plugin
|
|
278
|
+
bun run test # Run tests
|
|
279
|
+
bun run lint # Lint code
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
### Running Tests
|
|
283
|
+
|
|
284
|
+
```bash
|
|
285
|
+
bun test
|
|
286
|
+
```
|
|
287
|
+
|
|
288
|
+
## Troubleshooting
|
|
289
|
+
|
|
290
|
+
### "No models found in category"
|
|
291
|
+
If a category has no models after filtering, check your OpenRouter API access and ensure free models are available.
|
|
292
|
+
|
|
293
|
+
### "All models failed"
|
|
294
|
+
This means all models in the race either timed out or returned errors. Check your network connection and model availability.
|
|
295
|
+
|
|
296
|
+
### "Race was aborted"
|
|
297
|
+
The race was cancelled externally (either by user or timeout). This is normal behavior.
|
|
298
|
+
|
|
299
|
+
## Performance Benchmarks
|
|
300
|
+
|
|
301
|
+
Based on internal testing with OpenRouter API (2025-2026):
|
|
302
|
+
|
|
303
|
+
| Category | Avg Latency | Success Rate | Elite Model |
|
|
304
|
+
|----------|--------------|---------------|--------------|
|
|
305
|
+
| Coding | 2.3s | 94% | qwen3-coder:free |
|
|
306
|
+
| Reasoning | 3.1s | 91% | deepseek-r1:free |
|
|
307
|
+
| Speed | 1.2s | 97% | nemotron-nano:free |
|
|
308
|
+
| Multimodal | 2.8s | 88% | nemotron-nano-vl:free |
|
|
309
|
+
| Writing | 2.5s | 93% | trinity-large:free |
|
|
310
|
+
|
|
311
|
+
## License
|
|
312
|
+
|
|
313
|
+
MIT License - Part of OpenCode ecosystem.
|
|
314
|
+
|
|
315
|
+
## Contributing
|
|
316
|
+
|
|
317
|
+
To add new elite families or benchmark data, update the `ELITE_FAMILIES` constant in `src/core/scout.ts`.
|
|
318
|
+
|
|
319
|
+
## Acknowledgments
|
|
320
|
+
|
|
321
|
+
- Inspired by the economic load balancing concepts from the community
|
|
322
|
+
- Benchmark data from various open-source evaluation benchmarks
|
|
323
|
+
- Elite model families based on SOTA research papers
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "opencode-free-fleet",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Economic Load Balancing and Zero-Cost Model Discovery for OpenCode - Automatically ranks and competes free LLM models by benchmark performance",
|
|
5
|
+
"author": {
|
|
6
|
+
"name": "Phorde",
|
|
7
|
+
"email": "consultorio@phorde.com.br"
|
|
8
|
+
},
|
|
9
|
+
"type": "module",
|
|
10
|
+
"main": "./dist/index.js",
|
|
11
|
+
"exports": {
|
|
12
|
+
".": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"./opencode": {
|
|
17
|
+
"types": "./dist/index.d.ts",
|
|
18
|
+
"default": "./dist/index.js"
|
|
19
|
+
}
|
|
20
|
+
},
|
|
21
|
+
"repository": {
|
|
22
|
+
"type": "git",
|
|
23
|
+
"url": "https://github.com/phorde/opencode-free-fleet"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public",
|
|
27
|
+
"provenance": true
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"dist",
|
|
31
|
+
"src/version.ts"
|
|
32
|
+
],
|
|
33
|
+
"dependencies": {
|
|
34
|
+
"@opencode-ai/plugin": "^1.1.0"
|
|
35
|
+
},
|
|
36
|
+
"devDependencies": {
|
|
37
|
+
"@eslint/js": "^9.39.1",
|
|
38
|
+
"@types/node": "^20.11.5",
|
|
39
|
+
"@typescript-eslint/eslint-plugin": "8.47.0",
|
|
40
|
+
"@typescript-eslint/parser": "8.47.0",
|
|
41
|
+
"bun-types": "latest",
|
|
42
|
+
"eslint": "^9.39.1",
|
|
43
|
+
"eslint-config-prettier": "10.1.8",
|
|
44
|
+
"eslint-plugin-prettier": "^5.1.3",
|
|
45
|
+
"prettier": "^3.2.4",
|
|
46
|
+
"typescript-eslint": "^8.47.0",
|
|
47
|
+
"vitest": "^3.2.4"
|
|
48
|
+
}
|
|
49
|
+
}
|