pi-opencode-go-provider 1.0.6 → 1.0.8
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/README.md +6 -4
- package/index.ts +23 -6
- package/models.json +43 -5
- package/package.json +1 -1
- package/patch.json +167 -8
- package/scripts/update-models.js +44 -2
package/README.md
CHANGED
|
@@ -68,22 +68,24 @@ pi
|
|
|
68
68
|
|
|
69
69
|
| Model | API | Type | Context | Max Tokens | Input Cost | Output Cost |
|
|
70
70
|
|-------|-----|------|---------|------------|------------|-------------|
|
|
71
|
-
| DeepSeek V4 Flash | Completions | Text | 1.0M | 384K | $0.
|
|
71
|
+
| DeepSeek V4 Flash | Completions | Text | 1.0M | 384K | $0.07 | $0.14 |
|
|
72
72
|
| DeepSeek V4 Pro | Completions | Text | 1.0M | 384K | $0.43 | $0.87 |
|
|
73
73
|
| GLM-5.1 | Completions | Text | 203K | 33K | $1.40 | $4.40 |
|
|
74
74
|
| GLM-5.2 | Completions | Text | 1.0M | 131K | $1.40 | $4.40 |
|
|
75
|
-
|
|
|
75
|
+
| GPT-5.6 Luna (2x usage) | Responses | Text + Image | 1.1M | 128K | $0.10 | $0.60 |
|
|
76
|
+
| Grok 4.5 | Responses | Text + Image | 500K | 500K | $2.00 | $6.00 |
|
|
76
77
|
| Hy3 | Completions | Text | 256K | 64K | $0.14 | $0.58 |
|
|
77
78
|
| Kimi K2.6 | Completions | Text + Image | 262K | 66K | $0.95 | $4.00 |
|
|
78
79
|
| Kimi K2.7 Code | Completions | Text + Image | 262K | 262K | $0.95 | $4.00 |
|
|
79
80
|
| Kimi K3 (2x usage) | Completions | Text + Image | 1.0M | 131K | $3.00 | $15.00 |
|
|
80
81
|
| MiMo V2.5 | Completions | Text + Image | 1.0M | 128K | $0.14 | $0.28 |
|
|
81
82
|
| MiMo V2.5 Pro | Completions | Text | 1.0M | 128K | $0.43 | $0.87 |
|
|
82
|
-
| MiniMax-M2.7 |
|
|
83
|
+
| MiniMax-M2.7 | Completions | Text | 205K | 131K | $0.30 | $1.20 |
|
|
83
84
|
| MiniMax-M3 | Anthropic | Text + Image | 1.0M | 131K | $0.30 | $1.20 |
|
|
84
|
-
| Qwen3.6 Plus |
|
|
85
|
+
| Qwen3.6 Plus | Completions | Text + Image | 1.0M | 66K | $0.50 | $3.00 |
|
|
85
86
|
| Qwen3.7 Max | Anthropic | Text | 1.0M | 66K | $2.50 | $7.50 |
|
|
86
87
|
| Qwen3.7 Plus | Anthropic | Text + Image | 1.0M | 66K | $0.40 | $1.60 |
|
|
88
|
+
| Qwen3.8 Max | Anthropic | Text + Image | 1.0M | 131K | $2.00 | $6.00 |
|
|
87
89
|
*Costs are per million tokens. Prices subject to change - check [opencode.ai](https://opencode.ai) for current pricing.*
|
|
88
90
|
|
|
89
91
|
## Usage
|
package/index.ts
CHANGED
|
@@ -52,7 +52,9 @@ interface JsonModel {
|
|
|
52
52
|
cacheRead: number;
|
|
53
53
|
cacheWrite: number;
|
|
54
54
|
};
|
|
55
|
-
|
|
55
|
+
// null between transformApiModel and mergeWithEmbedded: the live /v1/models
|
|
56
|
+
// API omits context data; null = "API silent, prefer curated/default".
|
|
57
|
+
contextWindow: number | null;
|
|
56
58
|
maxTokens: number;
|
|
57
59
|
compat?: Record<string, unknown>;
|
|
58
60
|
}
|
|
@@ -185,7 +187,12 @@ function transformApiModel(apiModel: any): JsonModel {
|
|
|
185
187
|
cacheRead: apiModel.cost?.cache_read || 0,
|
|
186
188
|
cacheWrite: apiModel.cost?.cache_write || 0,
|
|
187
189
|
},
|
|
188
|
-
|
|
190
|
+
// The live /v1/models endpoint exposes only {id, object, created, owned_by}
|
|
191
|
+
// — no `limit`, no `context_length`. A literal `|| 131072` here used to make
|
|
192
|
+
// every "API silent" model truthy 131072, which then clobbered the curated
|
|
193
|
+
// 1M/262K values in mergeWithEmbedded via the `||` truthy check. Use `null`
|
|
194
|
+
// so the embedded curated value is preferred when the API is silent.
|
|
195
|
+
contextWindow: apiModel.limit?.context || apiModel.context_length || null,
|
|
189
196
|
maxTokens: apiModel.limit?.output || 0,
|
|
190
197
|
};
|
|
191
198
|
}
|
|
@@ -246,10 +253,20 @@ function mergeWithEmbedded(liveModels: JsonModel[], embeddedModels: JsonModel[])
|
|
|
246
253
|
cacheRead: liveModel.cost.cacheRead || embedded.cost.cacheRead,
|
|
247
254
|
cacheWrite: liveModel.cost.cacheWrite || embedded.cost.cacheWrite,
|
|
248
255
|
},
|
|
249
|
-
|
|
256
|
+
// Nullish coalesce: if the live API was silent (liveModel.contextWindow
|
|
257
|
+
// is null), fall through to the curated embedded value. The final
|
|
258
|
+
// `?? 131072` is the safe default for the rare case of a Custom-only
|
|
259
|
+
// model with neither live nor curated data. Using `||` here was the
|
|
260
|
+
// bug — it treated the API's 131072-fallback as authoritative and
|
|
261
|
+
// shadowed curated 1M/262K context windows.
|
|
262
|
+
contextWindow: liveModel.contextWindow ?? embedded.contextWindow ?? 131072,
|
|
250
263
|
});
|
|
251
264
|
} else {
|
|
252
|
-
|
|
265
|
+
// API-only model (no curated embedded counterpart). The Live API is silent
|
|
266
|
+
// on contextWindow for all current opencode-go models, so liveModel.contextWindow
|
|
267
|
+
// is null. Apply the safe default here so downstream consumers (e.g. pi core's
|
|
268
|
+
// formatTokenCount → count.toString()) don't crash on null.
|
|
269
|
+
result.push({ ...liveModel, contextWindow: liveModel.contextWindow ?? 131072 });
|
|
253
270
|
}
|
|
254
271
|
}
|
|
255
272
|
// Append any embedded models that the live API didn't return
|
|
@@ -346,7 +363,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
346
363
|
thinkingLevelMap: m.thinkingLevelMap,
|
|
347
364
|
input: m.input,
|
|
348
365
|
cost: m.cost,
|
|
349
|
-
contextWindow: m.contextWindow,
|
|
366
|
+
contextWindow: m.contextWindow ?? 131072,
|
|
350
367
|
maxTokens: m.maxTokens,
|
|
351
368
|
compat: m.compat,
|
|
352
369
|
})),
|
|
@@ -373,7 +390,7 @@ export default function (pi: ExtensionAPI) {
|
|
|
373
390
|
thinkingLevelMap: m.thinkingLevelMap,
|
|
374
391
|
input: m.input,
|
|
375
392
|
cost: m.cost,
|
|
376
|
-
contextWindow: m.contextWindow,
|
|
393
|
+
contextWindow: m.contextWindow ?? 131072,
|
|
377
394
|
maxTokens: m.maxTokens,
|
|
378
395
|
compat: m.compat,
|
|
379
396
|
})),
|
package/models.json
CHANGED
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
{
|
|
40
40
|
"id": "deepseek-v4-flash",
|
|
41
|
-
"name": "DeepSeek V4 Flash",
|
|
41
|
+
"name": "DeepSeek V4 Flash (2x usage)",
|
|
42
42
|
"api": "openai-completions",
|
|
43
43
|
"baseUrl": "https://opencode.ai/zen/go/v1",
|
|
44
44
|
"reasoning": true,
|
|
@@ -46,9 +46,9 @@
|
|
|
46
46
|
"text"
|
|
47
47
|
],
|
|
48
48
|
"cost": {
|
|
49
|
-
"input": 0.
|
|
50
|
-
"output": 0.
|
|
51
|
-
"cacheRead": 0.
|
|
49
|
+
"input": 0.07,
|
|
50
|
+
"output": 0.14,
|
|
51
|
+
"cacheRead": 0.0014,
|
|
52
52
|
"cacheWrite": 0
|
|
53
53
|
},
|
|
54
54
|
"contextWindow": 1000000,
|
|
@@ -182,6 +182,25 @@
|
|
|
182
182
|
"contextWindow": 1000000,
|
|
183
183
|
"maxTokens": 384000
|
|
184
184
|
},
|
|
185
|
+
{
|
|
186
|
+
"id": "qwen3.8-max",
|
|
187
|
+
"name": "Qwen3.8 Max",
|
|
188
|
+
"api": "anthropic-messages",
|
|
189
|
+
"baseUrl": "https://opencode.ai/zen/go",
|
|
190
|
+
"reasoning": true,
|
|
191
|
+
"input": [
|
|
192
|
+
"text",
|
|
193
|
+
"image"
|
|
194
|
+
],
|
|
195
|
+
"cost": {
|
|
196
|
+
"input": 2,
|
|
197
|
+
"output": 6,
|
|
198
|
+
"cacheRead": 0.25,
|
|
199
|
+
"cacheWrite": 2.5
|
|
200
|
+
},
|
|
201
|
+
"contextWindow": 1000000,
|
|
202
|
+
"maxTokens": 131072
|
|
203
|
+
},
|
|
185
204
|
{
|
|
186
205
|
"id": "mimo-v2.5",
|
|
187
206
|
"name": "MiMo V2.5",
|
|
@@ -201,6 +220,25 @@
|
|
|
201
220
|
"contextWindow": 1000000,
|
|
202
221
|
"maxTokens": 128000
|
|
203
222
|
},
|
|
223
|
+
{
|
|
224
|
+
"id": "gpt-5.6-luna",
|
|
225
|
+
"name": "GPT-5.6 Luna (2x usage)",
|
|
226
|
+
"api": "openai-completions",
|
|
227
|
+
"baseUrl": "https://opencode.ai/zen/go/v1",
|
|
228
|
+
"reasoning": true,
|
|
229
|
+
"input": [
|
|
230
|
+
"text",
|
|
231
|
+
"image"
|
|
232
|
+
],
|
|
233
|
+
"cost": {
|
|
234
|
+
"input": 0.1,
|
|
235
|
+
"output": 0.6,
|
|
236
|
+
"cacheRead": 0.01,
|
|
237
|
+
"cacheWrite": 0.125
|
|
238
|
+
},
|
|
239
|
+
"contextWindow": 1050000,
|
|
240
|
+
"maxTokens": 128000
|
|
241
|
+
},
|
|
204
242
|
{
|
|
205
243
|
"id": "grok-4.5",
|
|
206
244
|
"name": "Grok 4.5",
|
|
@@ -241,7 +279,7 @@
|
|
|
241
279
|
},
|
|
242
280
|
{
|
|
243
281
|
"id": "kimi-k3",
|
|
244
|
-
"name": "Kimi K3
|
|
282
|
+
"name": "Kimi K3",
|
|
245
283
|
"api": "openai-completions",
|
|
246
284
|
"baseUrl": "https://opencode.ai/zen/go/v1",
|
|
247
285
|
"reasoning": true,
|
package/package.json
CHANGED
package/patch.json
CHANGED
|
@@ -1,17 +1,176 @@
|
|
|
1
1
|
{
|
|
2
|
+
"glm-5.1": {
|
|
3
|
+
"compat": {
|
|
4
|
+
"supportsStore": false,
|
|
5
|
+
"supportsDeveloperRole": false,
|
|
6
|
+
"maxTokensField": "max_tokens"
|
|
7
|
+
}
|
|
8
|
+
},
|
|
2
9
|
"deepseek-v4-flash": {
|
|
3
|
-
"
|
|
4
|
-
"thinkingLevelMap": {
|
|
10
|
+
"name": "DeepSeek V4 Flash",
|
|
11
|
+
"thinkingLevelMap": {
|
|
12
|
+
"minimal": null,
|
|
13
|
+
"low": null,
|
|
14
|
+
"medium": null,
|
|
15
|
+
"high": "high",
|
|
16
|
+
"max": "max"
|
|
17
|
+
},
|
|
18
|
+
"compat": {
|
|
19
|
+
"supportsStore": false,
|
|
20
|
+
"supportsDeveloperRole": false,
|
|
21
|
+
"maxTokensField": "max_tokens",
|
|
22
|
+
"requiresReasoningContentOnAssistantMessages": true,
|
|
23
|
+
"thinkingFormat": "deepseek"
|
|
24
|
+
}
|
|
5
25
|
},
|
|
6
|
-
"
|
|
7
|
-
"
|
|
8
|
-
"
|
|
26
|
+
"minimax-m2.7": {
|
|
27
|
+
"api": "openai-completions",
|
|
28
|
+
"baseUrl": "https://opencode.ai/zen/go/v1",
|
|
29
|
+
"compat": {
|
|
30
|
+
"supportsStore": false,
|
|
31
|
+
"supportsDeveloperRole": false,
|
|
32
|
+
"maxTokensField": "max_tokens"
|
|
33
|
+
}
|
|
34
|
+
},
|
|
35
|
+
"glm-5.2": {
|
|
36
|
+
"thinkingLevelMap": {
|
|
37
|
+
"off": null,
|
|
38
|
+
"minimal": null,
|
|
39
|
+
"low": null,
|
|
40
|
+
"medium": null,
|
|
41
|
+
"high": "high",
|
|
42
|
+
"xhigh": null,
|
|
43
|
+
"max": "max"
|
|
44
|
+
},
|
|
45
|
+
"compat": {
|
|
46
|
+
"supportsStore": false,
|
|
47
|
+
"supportsDeveloperRole": false,
|
|
48
|
+
"maxTokensField": "max_tokens"
|
|
49
|
+
}
|
|
9
50
|
},
|
|
10
51
|
"kimi-k2.6": {
|
|
11
|
-
"
|
|
12
|
-
|
|
52
|
+
"thinkingLevelMap": {
|
|
53
|
+
"minimal": null,
|
|
54
|
+
"low": null,
|
|
55
|
+
"medium": null
|
|
56
|
+
},
|
|
57
|
+
"compat": {
|
|
58
|
+
"supportsStore": false,
|
|
59
|
+
"supportsDeveloperRole": false,
|
|
60
|
+
"thinkingFormat": "deepseek",
|
|
61
|
+
"supportsReasoningEffort": false,
|
|
62
|
+
"maxTokensField": "max_tokens",
|
|
63
|
+
"supportsLongCacheRetention": false
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
"hy3": {
|
|
67
|
+
"thinkingLevelMap": {
|
|
68
|
+
"off": "none",
|
|
69
|
+
"minimal": null,
|
|
70
|
+
"low": "low",
|
|
71
|
+
"medium": null,
|
|
72
|
+
"high": "high",
|
|
73
|
+
"xhigh": null,
|
|
74
|
+
"max": null
|
|
75
|
+
},
|
|
76
|
+
"compat": {
|
|
77
|
+
"supportsStore": false,
|
|
78
|
+
"supportsDeveloperRole": false,
|
|
79
|
+
"maxTokensField": "max_tokens"
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
"deepseek-v4-pro": {
|
|
83
|
+
"thinkingLevelMap": {
|
|
84
|
+
"minimal": null,
|
|
85
|
+
"low": null,
|
|
86
|
+
"medium": null,
|
|
87
|
+
"high": "high",
|
|
88
|
+
"max": "max"
|
|
89
|
+
},
|
|
90
|
+
"compat": {
|
|
91
|
+
"supportsStore": false,
|
|
92
|
+
"supportsDeveloperRole": false,
|
|
93
|
+
"maxTokensField": "max_tokens",
|
|
94
|
+
"requiresReasoningContentOnAssistantMessages": true,
|
|
95
|
+
"thinkingFormat": "deepseek"
|
|
96
|
+
}
|
|
97
|
+
},
|
|
98
|
+
"mimo-v2.5": {
|
|
99
|
+
"compat": {
|
|
100
|
+
"supportsStore": false,
|
|
101
|
+
"supportsDeveloperRole": false,
|
|
102
|
+
"maxTokensField": "max_tokens"
|
|
103
|
+
}
|
|
104
|
+
},
|
|
105
|
+
"grok-4.5": {
|
|
106
|
+
"api": "openai-responses",
|
|
107
|
+
"thinkingLevelMap": {
|
|
108
|
+
"off": null,
|
|
109
|
+
"minimal": null,
|
|
110
|
+
"low": "low",
|
|
111
|
+
"medium": "medium",
|
|
112
|
+
"high": "high",
|
|
113
|
+
"xhigh": null,
|
|
114
|
+
"max": null
|
|
115
|
+
},
|
|
116
|
+
"compat": {
|
|
117
|
+
"sessionAffinityFormat": "openai-nosession"
|
|
118
|
+
}
|
|
119
|
+
},
|
|
120
|
+
"kimi-k2.7-code": {
|
|
121
|
+
"compat": {
|
|
122
|
+
"supportsStore": false,
|
|
123
|
+
"supportsDeveloperRole": false,
|
|
124
|
+
"maxTokensField": "max_tokens"
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
"kimi-k3": {
|
|
128
|
+
"name": "Kimi K3 (2x usage)",
|
|
129
|
+
"thinkingLevelMap": {
|
|
130
|
+
"off": null,
|
|
131
|
+
"minimal": null,
|
|
132
|
+
"low": null,
|
|
133
|
+
"medium": null,
|
|
134
|
+
"high": null,
|
|
135
|
+
"xhigh": null,
|
|
136
|
+
"max": "max"
|
|
137
|
+
},
|
|
138
|
+
"compat": {
|
|
139
|
+
"supportsStore": false,
|
|
140
|
+
"supportsDeveloperRole": false,
|
|
141
|
+
"maxTokensField": "max_tokens"
|
|
142
|
+
}
|
|
143
|
+
},
|
|
144
|
+
"mimo-v2.5-pro": {
|
|
145
|
+
"compat": {
|
|
146
|
+
"supportsStore": false,
|
|
147
|
+
"supportsDeveloperRole": false,
|
|
148
|
+
"maxTokensField": "max_tokens"
|
|
149
|
+
}
|
|
150
|
+
},
|
|
151
|
+
"gpt-5.6-luna": {
|
|
152
|
+
"api": "openai-responses",
|
|
153
|
+
"thinkingLevelMap": {
|
|
154
|
+
"off": null,
|
|
155
|
+
"minimal": null,
|
|
156
|
+
"low": "low",
|
|
157
|
+
"medium": "medium",
|
|
158
|
+
"high": "high",
|
|
159
|
+
"xhigh": "xhigh",
|
|
160
|
+
"max": "max"
|
|
161
|
+
},
|
|
162
|
+
"compat": {
|
|
163
|
+
"sessionAffinityFormat": "openai-nosession"
|
|
164
|
+
}
|
|
13
165
|
},
|
|
14
166
|
"qwen3.6-plus": {
|
|
15
|
-
"
|
|
167
|
+
"api": "openai-completions",
|
|
168
|
+
"baseUrl": "https://opencode.ai/zen/go/v1",
|
|
169
|
+
"compat": {
|
|
170
|
+
"supportsStore": false,
|
|
171
|
+
"supportsDeveloperRole": false,
|
|
172
|
+
"thinkingFormat": "qwen",
|
|
173
|
+
"maxTokensField": "max_tokens"
|
|
174
|
+
}
|
|
16
175
|
}
|
|
17
176
|
}
|
package/scripts/update-models.js
CHANGED
|
@@ -101,6 +101,46 @@ function convertModel(model) {
|
|
|
101
101
|
};
|
|
102
102
|
}
|
|
103
103
|
|
|
104
|
+
// Load a layered JSON model file.
|
|
105
|
+
function loadJson(fileName) {
|
|
106
|
+
try {
|
|
107
|
+
return JSON.parse(fs.readFileSync(path.join(process.cwd(), fileName), 'utf8'));
|
|
108
|
+
} catch {
|
|
109
|
+
return fileName === 'patch.json' ? {} : [];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Deep-merge patch overrides into a model for README documentation. The
|
|
114
|
+
// generated models.json remains API-derived; only the displayed model map uses patches.
|
|
115
|
+
function applyPatch(model, patch) {
|
|
116
|
+
if (!patch) return model;
|
|
117
|
+
const result = { ...model };
|
|
118
|
+
for (const [key, value] of Object.entries(patch)) {
|
|
119
|
+
if (key === 'cost' || key === 'compat' || key === 'thinkingLevelMap') {
|
|
120
|
+
result[key] = { ...(result[key] || {}), ...value };
|
|
121
|
+
} else {
|
|
122
|
+
result[key] = value;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
if (!result.reasoning) {
|
|
126
|
+
delete result.thinkingLevelMap;
|
|
127
|
+
if (result.compat?.thinkingFormat) delete result.compat.thinkingFormat;
|
|
128
|
+
}
|
|
129
|
+
return result;
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
// Merge API models, patches, and custom models in the same order as index.ts.
|
|
133
|
+
function buildModels(baseModels, customModels, patch) {
|
|
134
|
+
const byId = new Map(baseModels.map(model => [model.id, model]));
|
|
135
|
+
for (const [id, entry] of Object.entries(patch)) {
|
|
136
|
+
if (byId.has(id)) byId.set(id, applyPatch(byId.get(id), entry));
|
|
137
|
+
}
|
|
138
|
+
for (const model of customModels) {
|
|
139
|
+
byId.set(model.id, applyPatch(model, patch[model.id]));
|
|
140
|
+
}
|
|
141
|
+
return Array.from(byId.values());
|
|
142
|
+
}
|
|
143
|
+
|
|
104
144
|
// Generate README model table row
|
|
105
145
|
function generateReadmeRow(model) {
|
|
106
146
|
const cost = model.cost || {};
|
|
@@ -238,8 +278,10 @@ async function main() {
|
|
|
238
278
|
fs.writeFileSync(modelsPath, JSON.stringify(models, null, 2) + '\n');
|
|
239
279
|
console.log(` Saved ${models.length} models to models.json`);
|
|
240
280
|
|
|
241
|
-
//
|
|
242
|
-
|
|
281
|
+
// Apply layered overrides for documentation: models.json → patch.json → custom-models.json.
|
|
282
|
+
const patch = loadJson('patch.json');
|
|
283
|
+
const customModels = Array.isArray(loadJson('custom-models.json')) ? loadJson('custom-models.json') : [];
|
|
284
|
+
updateReadme(buildModels(models, customModels, patch));
|
|
243
285
|
|
|
244
286
|
console.log('\nDone!');
|
|
245
287
|
} catch (error) {
|