cursor-opencode-provider 0.6.4 → 0.6.7
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 +17 -6
- package/dist/auth.js +28 -11
- package/dist/language-model.d.ts +2 -0
- package/dist/language-model.js +273 -65
- package/dist/model-config.d.ts +3 -1
- package/dist/model-config.js +83 -19
- package/dist/opencode2/catalog.js +4 -3
- package/dist/pricing-data.d.ts +81 -0
- package/dist/pricing-data.js +85 -4
- package/dist/pricing.d.ts +10 -4
- package/dist/pricing.js +17 -8
- package/dist/protocol/exec-variants.d.ts +5 -0
- package/dist/protocol/exec-variants.js +17 -2
- package/dist/protocol/git-diff.d.ts +33 -0
- package/dist/protocol/git-diff.js +372 -0
- package/dist/protocol/messages.js +229 -6
- package/dist/protocol/progress-continuation.d.ts +25 -0
- package/dist/protocol/progress-continuation.js +92 -0
- package/dist/protocol/tools.d.ts +6 -0
- package/dist/protocol/tools.js +216 -3
- package/dist/protocol/workspace-grounding.d.ts +1 -0
- package/dist/protocol/workspace-grounding.js +8 -0
- package/dist/session.d.ts +11 -2
- package/dist/session.js +34 -5
- package/dist/usage.d.ts +14 -0
- package/dist/usage.js +26 -0
- package/package.json +1 -1
package/dist/model-config.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CURSOR_VARIANT_PARAMETERS_KEY, CURSOR_WIRE_MODEL_ID_KEY, parseCursorContextLimit, } from "./models.js";
|
|
2
|
-
import { applyCursorModelCost } from "./pricing.js";
|
|
2
|
+
import { applyCursorModelCost, hasCursorFastPricing } from "./pricing.js";
|
|
3
3
|
import { getDocumentedCursorModelContext, resolveCursorModelSupportsImages, } from "./model-metadata.js";
|
|
4
4
|
/**
|
|
5
5
|
* Cursor `ModelInfo` → OpenCode model-config mapping.
|
|
@@ -109,6 +109,9 @@ function modelInfoVariants(mi, variants) {
|
|
|
109
109
|
function isLongContextVariant(v) {
|
|
110
110
|
return v.parameterValues.some((p) => p.id === "context" && parseCursorContextLimit(p.value) === 1_000_000);
|
|
111
111
|
}
|
|
112
|
+
function isFastVariant(v) {
|
|
113
|
+
return v.parameterValues.some((p) => p.id === "fast" && p.value === "true");
|
|
114
|
+
}
|
|
112
115
|
function variantsForTier(mi, tier) {
|
|
113
116
|
return mi.variants.filter((v) => isLongContextVariant(v) === (tier === "long"));
|
|
114
117
|
}
|
|
@@ -139,10 +142,12 @@ export function thinkingSuffixBaseNames(models) {
|
|
|
139
142
|
}
|
|
140
143
|
export function modelInfoToConfig(mi, options = {}) {
|
|
141
144
|
const contextTier = options.contextTier ?? "base";
|
|
142
|
-
const variants = variantsForTier(mi, contextTier);
|
|
145
|
+
const variants = options.variants ?? variantsForTier(mi, contextTier);
|
|
143
146
|
let name = baseName(mi);
|
|
144
147
|
if (options.thinkingSuffix)
|
|
145
148
|
name += " Thinking";
|
|
149
|
+
if (options.fast)
|
|
150
|
+
name += " Fast";
|
|
146
151
|
if (contextTier === "long")
|
|
147
152
|
name += " 1M";
|
|
148
153
|
// OpenCode's context limit is static per model entry, while Cursor's context
|
|
@@ -176,8 +181,10 @@ export function modelInfoToConfig(mi, options = {}) {
|
|
|
176
181
|
const variantConfig = modelInfoVariants(mi, variants);
|
|
177
182
|
if (variantConfig)
|
|
178
183
|
config.variants = variantConfig;
|
|
179
|
-
if (contextTier === "long") {
|
|
180
|
-
const defaultVariant =
|
|
184
|
+
if (contextTier === "long" || options.fast) {
|
|
185
|
+
const defaultVariant = contextTier === "long"
|
|
186
|
+
? (variants.find((v) => v.isDefaultMax) ?? variants[0])
|
|
187
|
+
: (variants.find((v) => v.isDefaultNonMax) ?? variants[0]);
|
|
181
188
|
if (defaultVariant) {
|
|
182
189
|
config.options = {
|
|
183
190
|
[CURSOR_WIRE_MODEL_ID_KEY]: mi.id,
|
|
@@ -187,30 +194,87 @@ export function modelInfoToConfig(mi, options = {}) {
|
|
|
187
194
|
}
|
|
188
195
|
return config;
|
|
189
196
|
}
|
|
197
|
+
function speedGroups(variants, splitFast) {
|
|
198
|
+
if (!splitFast)
|
|
199
|
+
return variants.length > 0 ? [{ fast: false, variants }] : [];
|
|
200
|
+
const slow = variants.filter((variant) => !isFastVariant(variant));
|
|
201
|
+
const fast = variants.filter((variant) => isFastVariant(variant));
|
|
202
|
+
const groups = [];
|
|
203
|
+
if (slow.length > 0)
|
|
204
|
+
groups.push({ fast: false, variants: slow });
|
|
205
|
+
if (fast.length > 0)
|
|
206
|
+
groups.push({ fast: true, variants: fast });
|
|
207
|
+
return groups;
|
|
208
|
+
}
|
|
209
|
+
function uniqueCatalogId(usedIds, modelId, suffix) {
|
|
210
|
+
let id = `${modelId}${suffix}`;
|
|
211
|
+
if (!usedIds.has(id)) {
|
|
212
|
+
usedIds.add(id);
|
|
213
|
+
return id;
|
|
214
|
+
}
|
|
215
|
+
let n = 2;
|
|
216
|
+
while (true) {
|
|
217
|
+
const candidate = suffix === "-fast"
|
|
218
|
+
? `${modelId}-fast-${n}`
|
|
219
|
+
: suffix === "-1m-fast"
|
|
220
|
+
? `${modelId}-1m-${n}-fast`
|
|
221
|
+
: `${modelId}-1m-${n}`;
|
|
222
|
+
if (!usedIds.has(candidate)) {
|
|
223
|
+
usedIds.add(candidate);
|
|
224
|
+
return candidate;
|
|
225
|
+
}
|
|
226
|
+
n++;
|
|
227
|
+
}
|
|
228
|
+
}
|
|
190
229
|
export function modelsToConfig(models) {
|
|
191
230
|
const ambiguous = thinkingSuffixBaseNames(models);
|
|
192
231
|
const out = {};
|
|
193
232
|
const usedIds = new Set(models.map((m) => m.id));
|
|
194
233
|
for (const m of models) {
|
|
195
234
|
const thinkingSuffix = !!m.supportsThinking && ambiguous.has(baseName(m));
|
|
196
|
-
const
|
|
197
|
-
const
|
|
198
|
-
|
|
199
|
-
|
|
235
|
+
const splitFast = hasCursorFastPricing(m.id);
|
|
236
|
+
const groups = [];
|
|
237
|
+
for (const contextTier of ["base", "long"]) {
|
|
238
|
+
const suffixFor = (fast) => contextTier === "long" ? (fast ? "-1m-fast" : "-1m") : (fast ? "-fast" : "");
|
|
239
|
+
for (const group of speedGroups(variantsForTier(m, contextTier), splitFast)) {
|
|
240
|
+
groups.push({
|
|
241
|
+
contextTier,
|
|
242
|
+
fast: group.fast,
|
|
243
|
+
variants: group.variants,
|
|
244
|
+
suffix: suffixFor(group.fast),
|
|
245
|
+
});
|
|
246
|
+
}
|
|
200
247
|
}
|
|
201
|
-
if (
|
|
202
|
-
|
|
203
|
-
if (baseVariants.length === 0) {
|
|
204
|
-
// No separate base tier — the wire id itself is the long-context entry.
|
|
205
|
-
out[m.id] = applyCursorModelCost(`${m.id}-1m`, modelInfoToConfig(m, { thinkingSuffix, contextTier: "long" }));
|
|
248
|
+
if (groups.length === 0) {
|
|
249
|
+
out[m.id] = applyCursorModelCost(m.id, modelInfoToConfig(m, { thinkingSuffix, contextTier: "base" }));
|
|
206
250
|
continue;
|
|
207
251
|
}
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
252
|
+
const primaryIndex = groups.findIndex((group) => group.suffix === "");
|
|
253
|
+
const primary = primaryIndex >= 0 ? primaryIndex : 0;
|
|
254
|
+
for (const [index, group] of groups.entries()) {
|
|
255
|
+
const catalogId = index === primary
|
|
256
|
+
? m.id
|
|
257
|
+
: uniqueCatalogId(usedIds, m.id, group.suffix || "-fast");
|
|
258
|
+
const pricingId = group.fast ? `${m.id}-fast` : (group.contextTier === "long" ? `${m.id}-1m` : m.id);
|
|
259
|
+
const config = modelInfoToConfig(m, {
|
|
260
|
+
thinkingSuffix,
|
|
261
|
+
contextTier: group.contextTier,
|
|
262
|
+
variants: group.variants,
|
|
263
|
+
fast: group.fast,
|
|
264
|
+
});
|
|
265
|
+
if (catalogId !== m.id && !config.options) {
|
|
266
|
+
const defaultVariant = (group.contextTier === "long"
|
|
267
|
+
? group.variants.find((v) => v.isDefaultMax)
|
|
268
|
+
: group.variants.find((v) => v.isDefaultNonMax)) ?? group.variants[0];
|
|
269
|
+
if (defaultVariant) {
|
|
270
|
+
config.options = {
|
|
271
|
+
[CURSOR_WIRE_MODEL_ID_KEY]: m.id,
|
|
272
|
+
[CURSOR_VARIANT_PARAMETERS_KEY]: defaultVariant.parameterValues.map((p) => ({ ...p })),
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
out[catalogId] = applyCursorModelCost(pricingId, config);
|
|
277
|
+
}
|
|
214
278
|
}
|
|
215
279
|
return out;
|
|
216
280
|
}
|
|
@@ -46,9 +46,10 @@ export function applyCursorProvider(draft) {
|
|
|
46
46
|
/** Translate one `modelsToConfig` entry into the 2.0 `Model.Info` shape. */
|
|
47
47
|
function applyModelEntry(draft, id, entry) {
|
|
48
48
|
const options = entry.options;
|
|
49
|
-
// Long-context entries get
|
|
50
|
-
// addressing the same Cursor model
|
|
51
|
-
// provider options; 2.0 has a
|
|
49
|
+
// Long-context and Fast entries get synthetic OpenCode ids (`<id>-1m`,
|
|
50
|
+
// `<id>-fast`, `<id>-1m-fast`) while still addressing the same Cursor model
|
|
51
|
+
// on the wire. V1 smuggled that through provider options; 2.0 has a
|
|
52
|
+
// first-class `modelID` for exactly this.
|
|
52
53
|
const wireId = typeof options?.[CURSOR_WIRE_MODEL_ID_KEY] === "string"
|
|
53
54
|
? options[CURSOR_WIRE_MODEL_ID_KEY]
|
|
54
55
|
: id;
|
package/dist/pricing-data.d.ts
CHANGED
|
@@ -13,6 +13,12 @@ export declare const CURSOR_MODEL_COSTS: {
|
|
|
13
13
|
readonly cache_read: 1;
|
|
14
14
|
readonly cache_write: 12.5;
|
|
15
15
|
};
|
|
16
|
+
readonly "claude-fable-5-1": {
|
|
17
|
+
readonly input: 10;
|
|
18
|
+
readonly output: 50;
|
|
19
|
+
readonly cache_read: 0.25;
|
|
20
|
+
readonly cache_write: 12.5;
|
|
21
|
+
};
|
|
16
22
|
readonly "claude-haiku-4-5": {
|
|
17
23
|
readonly input: 1;
|
|
18
24
|
readonly output: 5;
|
|
@@ -79,6 +85,16 @@ export declare const CURSOR_MODEL_COSTS: {
|
|
|
79
85
|
readonly cache_read: 0.2;
|
|
80
86
|
readonly cache_write: 2.5;
|
|
81
87
|
};
|
|
88
|
+
readonly "composer-2.5": {
|
|
89
|
+
readonly input: 0.5;
|
|
90
|
+
readonly output: 2.5;
|
|
91
|
+
readonly cache_read: 0.2;
|
|
92
|
+
};
|
|
93
|
+
readonly "composer-2.5-fast": {
|
|
94
|
+
readonly input: 3;
|
|
95
|
+
readonly output: 15;
|
|
96
|
+
readonly cache_read: 0.5;
|
|
97
|
+
};
|
|
82
98
|
readonly "gemini-2.5-flash": {
|
|
83
99
|
readonly input: 0.3;
|
|
84
100
|
readonly output: 2.5;
|
|
@@ -109,6 +125,11 @@ export declare const CURSOR_MODEL_COSTS: {
|
|
|
109
125
|
readonly output: 3.5;
|
|
110
126
|
readonly cache_read: 0.075;
|
|
111
127
|
};
|
|
128
|
+
readonly "gemini-3.8-flash": {
|
|
129
|
+
readonly input: 0.75;
|
|
130
|
+
readonly output: 3.5;
|
|
131
|
+
readonly cache_read: 0.075;
|
|
132
|
+
};
|
|
112
133
|
readonly "glm-5.2": {
|
|
113
134
|
readonly input: 1.4;
|
|
114
135
|
readonly output: 4.4;
|
|
@@ -169,6 +190,12 @@ export declare const CURSOR_MODEL_COSTS: {
|
|
|
169
190
|
readonly output: 1.2;
|
|
170
191
|
readonly cache_read: 0.02;
|
|
171
192
|
readonly cache_write: 0.25;
|
|
193
|
+
readonly context_over_200k: {
|
|
194
|
+
readonly input: 0.4;
|
|
195
|
+
readonly output: 1.2;
|
|
196
|
+
readonly cache_read: 0.04;
|
|
197
|
+
readonly cache_write: 0.5;
|
|
198
|
+
};
|
|
172
199
|
};
|
|
173
200
|
readonly "gpt-5.6-sol": {
|
|
174
201
|
readonly input: 4;
|
|
@@ -187,6 +214,32 @@ export declare const CURSOR_MODEL_COSTS: {
|
|
|
187
214
|
readonly output: 12;
|
|
188
215
|
readonly cache_read: 0.2;
|
|
189
216
|
readonly cache_write: 2.5;
|
|
217
|
+
readonly context_over_200k: {
|
|
218
|
+
readonly input: 4;
|
|
219
|
+
readonly output: 12;
|
|
220
|
+
readonly cache_read: 0.4;
|
|
221
|
+
readonly cache_write: 5;
|
|
222
|
+
};
|
|
223
|
+
};
|
|
224
|
+
readonly "grok-4.5": {
|
|
225
|
+
readonly input: 2;
|
|
226
|
+
readonly output: 6;
|
|
227
|
+
readonly cache_read: 0.5;
|
|
228
|
+
};
|
|
229
|
+
readonly "grok-4.5-fast": {
|
|
230
|
+
readonly input: 4;
|
|
231
|
+
readonly output: 18;
|
|
232
|
+
readonly cache_read: 1;
|
|
233
|
+
};
|
|
234
|
+
readonly "grok-4.6": {
|
|
235
|
+
readonly input: 2;
|
|
236
|
+
readonly output: 6;
|
|
237
|
+
readonly cache_read: 0.5;
|
|
238
|
+
};
|
|
239
|
+
readonly "grok-4.6-fast": {
|
|
240
|
+
readonly input: 4;
|
|
241
|
+
readonly output: 12;
|
|
242
|
+
readonly cache_read: 1;
|
|
190
243
|
};
|
|
191
244
|
readonly "kimi-k2.7-code": {
|
|
192
245
|
readonly input: 0.95;
|
|
@@ -198,12 +251,21 @@ export declare const CURSOR_MODEL_COSTS: {
|
|
|
198
251
|
readonly output: 15;
|
|
199
252
|
readonly cache_read: 0.3;
|
|
200
253
|
};
|
|
254
|
+
readonly "muse-spark-1.3": {
|
|
255
|
+
readonly input: 1.25;
|
|
256
|
+
readonly output: 4.25;
|
|
257
|
+
readonly cache_read: 0.15;
|
|
258
|
+
};
|
|
201
259
|
};
|
|
202
260
|
export declare const CURSOR_MODEL_CONTEXTS: {
|
|
203
261
|
readonly "claude-fable-5": {
|
|
204
262
|
readonly maxContext: 300000;
|
|
205
263
|
readonly maxContextForMaxMode: 1000000;
|
|
206
264
|
};
|
|
265
|
+
readonly "claude-fable-5-1": {
|
|
266
|
+
readonly maxContext: 300000;
|
|
267
|
+
readonly maxContextForMaxMode: 1000000;
|
|
268
|
+
};
|
|
207
269
|
readonly "claude-haiku-4-5": {
|
|
208
270
|
readonly maxContext: 200000;
|
|
209
271
|
};
|
|
@@ -270,6 +332,10 @@ export declare const CURSOR_MODEL_CONTEXTS: {
|
|
|
270
332
|
readonly maxContext: 200000;
|
|
271
333
|
readonly maxContextForMaxMode: 1000000;
|
|
272
334
|
};
|
|
335
|
+
readonly "gemini-3.8-flash": {
|
|
336
|
+
readonly maxContext: 200000;
|
|
337
|
+
readonly maxContextForMaxMode: 1000000;
|
|
338
|
+
};
|
|
273
339
|
readonly "glm-5.2": {
|
|
274
340
|
readonly maxContext: 200000;
|
|
275
341
|
};
|
|
@@ -301,6 +367,7 @@ export declare const CURSOR_MODEL_CONTEXTS: {
|
|
|
301
367
|
};
|
|
302
368
|
readonly "gpt-5.6-luna": {
|
|
303
369
|
readonly maxContext: 272000;
|
|
370
|
+
readonly maxContextForMaxMode: 1000000;
|
|
304
371
|
};
|
|
305
372
|
readonly "gpt-5.6-sol": {
|
|
306
373
|
readonly maxContext: 272000;
|
|
@@ -308,6 +375,7 @@ export declare const CURSOR_MODEL_CONTEXTS: {
|
|
|
308
375
|
};
|
|
309
376
|
readonly "gpt-5.6-terra": {
|
|
310
377
|
readonly maxContext: 272000;
|
|
378
|
+
readonly maxContextForMaxMode: 1000000;
|
|
311
379
|
};
|
|
312
380
|
readonly "grok-4.5": {
|
|
313
381
|
readonly maxContext: 256000;
|
|
@@ -322,11 +390,18 @@ export declare const CURSOR_MODEL_CONTEXTS: {
|
|
|
322
390
|
readonly maxContext: 200000;
|
|
323
391
|
readonly maxContextForMaxMode: 1000000;
|
|
324
392
|
};
|
|
393
|
+
readonly "muse-spark-1.3": {
|
|
394
|
+
readonly maxContext: 300000;
|
|
395
|
+
readonly maxContextForMaxMode: 1000000;
|
|
396
|
+
};
|
|
325
397
|
};
|
|
326
398
|
export declare const CURSOR_MODEL_CAPABILITIES: {
|
|
327
399
|
readonly "claude-fable-5": {
|
|
328
400
|
readonly supportsImages: true;
|
|
329
401
|
};
|
|
402
|
+
readonly "claude-fable-5-1": {
|
|
403
|
+
readonly supportsImages: true;
|
|
404
|
+
};
|
|
330
405
|
readonly "claude-haiku-4-5": {
|
|
331
406
|
readonly supportsImages: true;
|
|
332
407
|
};
|
|
@@ -378,6 +453,9 @@ export declare const CURSOR_MODEL_CAPABILITIES: {
|
|
|
378
453
|
readonly "gemini-3.7-flash": {
|
|
379
454
|
readonly supportsImages: true;
|
|
380
455
|
};
|
|
456
|
+
readonly "gemini-3.8-flash": {
|
|
457
|
+
readonly supportsImages: true;
|
|
458
|
+
};
|
|
381
459
|
readonly "glm-5.2": {
|
|
382
460
|
readonly supportsImages: false;
|
|
383
461
|
};
|
|
@@ -426,4 +504,7 @@ export declare const CURSOR_MODEL_CAPABILITIES: {
|
|
|
426
504
|
readonly "kimi-k3": {
|
|
427
505
|
readonly supportsImages: true;
|
|
428
506
|
};
|
|
507
|
+
readonly "muse-spark-1.3": {
|
|
508
|
+
readonly supportsImages: true;
|
|
509
|
+
};
|
|
429
510
|
};
|
package/dist/pricing-data.js
CHANGED
|
@@ -13,6 +13,12 @@ export const CURSOR_MODEL_COSTS = {
|
|
|
13
13
|
"cache_read": 1,
|
|
14
14
|
"cache_write": 12.5
|
|
15
15
|
},
|
|
16
|
+
"claude-fable-5-1": {
|
|
17
|
+
"input": 10,
|
|
18
|
+
"output": 50,
|
|
19
|
+
"cache_read": 0.25,
|
|
20
|
+
"cache_write": 12.5
|
|
21
|
+
},
|
|
16
22
|
"claude-haiku-4-5": {
|
|
17
23
|
"input": 1,
|
|
18
24
|
"output": 5,
|
|
@@ -79,6 +85,16 @@ export const CURSOR_MODEL_COSTS = {
|
|
|
79
85
|
"cache_read": 0.2,
|
|
80
86
|
"cache_write": 2.5
|
|
81
87
|
},
|
|
88
|
+
"composer-2.5": {
|
|
89
|
+
"input": 0.5,
|
|
90
|
+
"output": 2.5,
|
|
91
|
+
"cache_read": 0.2
|
|
92
|
+
},
|
|
93
|
+
"composer-2.5-fast": {
|
|
94
|
+
"input": 3,
|
|
95
|
+
"output": 15,
|
|
96
|
+
"cache_read": 0.5
|
|
97
|
+
},
|
|
82
98
|
"gemini-2.5-flash": {
|
|
83
99
|
"input": 0.3,
|
|
84
100
|
"output": 2.5,
|
|
@@ -109,6 +125,11 @@ export const CURSOR_MODEL_COSTS = {
|
|
|
109
125
|
"output": 3.5,
|
|
110
126
|
"cache_read": 0.075
|
|
111
127
|
},
|
|
128
|
+
"gemini-3.8-flash": {
|
|
129
|
+
"input": 0.75,
|
|
130
|
+
"output": 3.5,
|
|
131
|
+
"cache_read": 0.075
|
|
132
|
+
},
|
|
112
133
|
"glm-5.2": {
|
|
113
134
|
"input": 1.4,
|
|
114
135
|
"output": 4.4,
|
|
@@ -168,7 +189,13 @@ export const CURSOR_MODEL_COSTS = {
|
|
|
168
189
|
"input": 0.2,
|
|
169
190
|
"output": 1.2,
|
|
170
191
|
"cache_read": 0.02,
|
|
171
|
-
"cache_write": 0.25
|
|
192
|
+
"cache_write": 0.25,
|
|
193
|
+
"context_over_200k": {
|
|
194
|
+
"input": 0.4,
|
|
195
|
+
"output": 1.2,
|
|
196
|
+
"cache_read": 0.04,
|
|
197
|
+
"cache_write": 0.5
|
|
198
|
+
}
|
|
172
199
|
},
|
|
173
200
|
"gpt-5.6-sol": {
|
|
174
201
|
"input": 4,
|
|
@@ -186,7 +213,33 @@ export const CURSOR_MODEL_COSTS = {
|
|
|
186
213
|
"input": 2,
|
|
187
214
|
"output": 12,
|
|
188
215
|
"cache_read": 0.2,
|
|
189
|
-
"cache_write": 2.5
|
|
216
|
+
"cache_write": 2.5,
|
|
217
|
+
"context_over_200k": {
|
|
218
|
+
"input": 4,
|
|
219
|
+
"output": 12,
|
|
220
|
+
"cache_read": 0.4,
|
|
221
|
+
"cache_write": 5
|
|
222
|
+
}
|
|
223
|
+
},
|
|
224
|
+
"grok-4.5": {
|
|
225
|
+
"input": 2,
|
|
226
|
+
"output": 6,
|
|
227
|
+
"cache_read": 0.5
|
|
228
|
+
},
|
|
229
|
+
"grok-4.5-fast": {
|
|
230
|
+
"input": 4,
|
|
231
|
+
"output": 18,
|
|
232
|
+
"cache_read": 1
|
|
233
|
+
},
|
|
234
|
+
"grok-4.6": {
|
|
235
|
+
"input": 2,
|
|
236
|
+
"output": 6,
|
|
237
|
+
"cache_read": 0.5
|
|
238
|
+
},
|
|
239
|
+
"grok-4.6-fast": {
|
|
240
|
+
"input": 4,
|
|
241
|
+
"output": 12,
|
|
242
|
+
"cache_read": 1
|
|
190
243
|
},
|
|
191
244
|
"kimi-k2.7-code": {
|
|
192
245
|
"input": 0.95,
|
|
@@ -197,6 +250,11 @@ export const CURSOR_MODEL_COSTS = {
|
|
|
197
250
|
"input": 3,
|
|
198
251
|
"output": 15,
|
|
199
252
|
"cache_read": 0.3
|
|
253
|
+
},
|
|
254
|
+
"muse-spark-1.3": {
|
|
255
|
+
"input": 1.25,
|
|
256
|
+
"output": 4.25,
|
|
257
|
+
"cache_read": 0.15
|
|
200
258
|
}
|
|
201
259
|
};
|
|
202
260
|
export const CURSOR_MODEL_CONTEXTS = {
|
|
@@ -204,6 +262,10 @@ export const CURSOR_MODEL_CONTEXTS = {
|
|
|
204
262
|
"maxContext": 300000,
|
|
205
263
|
"maxContextForMaxMode": 1000000
|
|
206
264
|
},
|
|
265
|
+
"claude-fable-5-1": {
|
|
266
|
+
"maxContext": 300000,
|
|
267
|
+
"maxContextForMaxMode": 1000000
|
|
268
|
+
},
|
|
207
269
|
"claude-haiku-4-5": {
|
|
208
270
|
"maxContext": 200000
|
|
209
271
|
},
|
|
@@ -270,6 +332,10 @@ export const CURSOR_MODEL_CONTEXTS = {
|
|
|
270
332
|
"maxContext": 200000,
|
|
271
333
|
"maxContextForMaxMode": 1000000
|
|
272
334
|
},
|
|
335
|
+
"gemini-3.8-flash": {
|
|
336
|
+
"maxContext": 200000,
|
|
337
|
+
"maxContextForMaxMode": 1000000
|
|
338
|
+
},
|
|
273
339
|
"glm-5.2": {
|
|
274
340
|
"maxContext": 200000
|
|
275
341
|
},
|
|
@@ -300,14 +366,16 @@ export const CURSOR_MODEL_CONTEXTS = {
|
|
|
300
366
|
"maxContextForMaxMode": 1000000
|
|
301
367
|
},
|
|
302
368
|
"gpt-5.6-luna": {
|
|
303
|
-
"maxContext": 272000
|
|
369
|
+
"maxContext": 272000,
|
|
370
|
+
"maxContextForMaxMode": 1000000
|
|
304
371
|
},
|
|
305
372
|
"gpt-5.6-sol": {
|
|
306
373
|
"maxContext": 272000,
|
|
307
374
|
"maxContextForMaxMode": 1000000
|
|
308
375
|
},
|
|
309
376
|
"gpt-5.6-terra": {
|
|
310
|
-
"maxContext": 272000
|
|
377
|
+
"maxContext": 272000,
|
|
378
|
+
"maxContextForMaxMode": 1000000
|
|
311
379
|
},
|
|
312
380
|
"grok-4.5": {
|
|
313
381
|
"maxContext": 256000
|
|
@@ -321,12 +389,19 @@ export const CURSOR_MODEL_CONTEXTS = {
|
|
|
321
389
|
"kimi-k3": {
|
|
322
390
|
"maxContext": 200000,
|
|
323
391
|
"maxContextForMaxMode": 1000000
|
|
392
|
+
},
|
|
393
|
+
"muse-spark-1.3": {
|
|
394
|
+
"maxContext": 300000,
|
|
395
|
+
"maxContextForMaxMode": 1000000
|
|
324
396
|
}
|
|
325
397
|
};
|
|
326
398
|
export const CURSOR_MODEL_CAPABILITIES = {
|
|
327
399
|
"claude-fable-5": {
|
|
328
400
|
"supportsImages": true
|
|
329
401
|
},
|
|
402
|
+
"claude-fable-5-1": {
|
|
403
|
+
"supportsImages": true
|
|
404
|
+
},
|
|
330
405
|
"claude-haiku-4-5": {
|
|
331
406
|
"supportsImages": true
|
|
332
407
|
},
|
|
@@ -378,6 +453,9 @@ export const CURSOR_MODEL_CAPABILITIES = {
|
|
|
378
453
|
"gemini-3.7-flash": {
|
|
379
454
|
"supportsImages": true
|
|
380
455
|
},
|
|
456
|
+
"gemini-3.8-flash": {
|
|
457
|
+
"supportsImages": true
|
|
458
|
+
},
|
|
381
459
|
"glm-5.2": {
|
|
382
460
|
"supportsImages": false
|
|
383
461
|
},
|
|
@@ -425,5 +503,8 @@ export const CURSOR_MODEL_CAPABILITIES = {
|
|
|
425
503
|
},
|
|
426
504
|
"kimi-k3": {
|
|
427
505
|
"supportsImages": true
|
|
506
|
+
},
|
|
507
|
+
"muse-spark-1.3": {
|
|
508
|
+
"supportsImages": true
|
|
428
509
|
}
|
|
429
510
|
};
|
package/dist/pricing.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cursor model token pricing for OpenCode cost reporting.
|
|
3
3
|
*
|
|
4
|
-
* Rates come from Cursor's public docs (
|
|
4
|
+
* Rates come from Cursor's public docs (Cursor Models + Other Models tables).
|
|
5
5
|
* Generated data lives in `pricing-data.ts`; regenerate with
|
|
6
6
|
* `bun run generate:pricing`. Unknown / unpublished models get no `cost`.
|
|
7
7
|
*/
|
|
@@ -32,22 +32,28 @@ export type CursorPricingCoverage = {
|
|
|
32
32
|
};
|
|
33
33
|
/**
|
|
34
34
|
* Models we expose that Cursor does not currently publish numeric rates for
|
|
35
|
-
*
|
|
35
|
+
* (Auto is billed at the routed model's list price).
|
|
36
36
|
*/
|
|
37
|
-
export declare const CURSOR_UNPRICED_MODEL_IDS: readonly ["default"
|
|
37
|
+
export declare const CURSOR_UNPRICED_MODEL_IDS: readonly ["default"];
|
|
38
38
|
export declare function validateOpenCodeModelCost(value: unknown, path?: string): {
|
|
39
39
|
valid: boolean;
|
|
40
40
|
errors: string[];
|
|
41
41
|
};
|
|
42
42
|
export declare function isOpenCodeModelCost(value: unknown): value is OpenCodeModelCost;
|
|
43
|
-
/** Strip synthetic OpenCode
|
|
43
|
+
/** Strip synthetic OpenCode suffixes (`…-1m`, `…-1m-2`, `…-1m-fast`, …). */
|
|
44
44
|
export declare function wireModelIdForPricing(modelId: string): {
|
|
45
45
|
baseId: string;
|
|
46
46
|
longContextEntry: boolean;
|
|
47
47
|
};
|
|
48
|
+
/**
|
|
49
|
+
* True when Cursor publishes a distinct Fast rate for this wire model id.
|
|
50
|
+
* Catalog code uses this to split Fast variants into a `-fast` entry.
|
|
51
|
+
*/
|
|
52
|
+
export declare function hasCursorFastPricing(modelId: string): boolean;
|
|
48
53
|
/**
|
|
49
54
|
* Look up classic OpenCode cost for a catalog / wire model id.
|
|
50
55
|
* Synthetic `-1m` entries retain both base and documented long-context rates.
|
|
56
|
+
* Synthetic `-fast` entries are stored as their own keys.
|
|
51
57
|
*/
|
|
52
58
|
export declare function getCursorModelCost(modelId: string): OpenCodeModelCost | undefined;
|
|
53
59
|
export declare function applyCursorModelCost<T extends Record<string, unknown>>(modelId: string, entry: T): T & {
|
package/dist/pricing.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Cursor model token pricing for OpenCode cost reporting.
|
|
3
3
|
*
|
|
4
|
-
* Rates come from Cursor's public docs (
|
|
4
|
+
* Rates come from Cursor's public docs (Cursor Models + Other Models tables).
|
|
5
5
|
* Generated data lives in `pricing-data.ts`; regenerate with
|
|
6
6
|
* `bun run generate:pricing`. Unknown / unpublished models get no `cost`.
|
|
7
7
|
*/
|
|
8
8
|
import { CURSOR_MODEL_COSTS } from "./pricing-data.js";
|
|
9
9
|
/**
|
|
10
10
|
* Models we expose that Cursor does not currently publish numeric rates for
|
|
11
|
-
*
|
|
11
|
+
* (Auto is billed at the routed model's list price).
|
|
12
12
|
*/
|
|
13
|
-
export const CURSOR_UNPRICED_MODEL_IDS = ["default"
|
|
13
|
+
export const CURSOR_UNPRICED_MODEL_IDS = ["default"];
|
|
14
14
|
const UNPRICED = new Set(CURSOR_UNPRICED_MODEL_IDS);
|
|
15
15
|
function isRecord(value) {
|
|
16
16
|
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
@@ -47,12 +47,20 @@ export function validateOpenCodeModelCost(value, path = "cost") {
|
|
|
47
47
|
export function isOpenCodeModelCost(value) {
|
|
48
48
|
return validateOpenCodeModelCost(value).valid;
|
|
49
49
|
}
|
|
50
|
-
/** Strip synthetic OpenCode
|
|
50
|
+
/** Strip synthetic OpenCode suffixes (`…-1m`, `…-1m-2`, `…-1m-fast`, …). */
|
|
51
51
|
export function wireModelIdForPricing(modelId) {
|
|
52
|
-
const match = /^(.*)-1m(
|
|
53
|
-
if (
|
|
54
|
-
return { baseId:
|
|
55
|
-
|
|
52
|
+
const match = /^(.*)-1m(?:-\d+)?(-fast)?$/.exec(modelId);
|
|
53
|
+
if (match) {
|
|
54
|
+
return { baseId: `${match[1]}${match[2] ?? ""}`, longContextEntry: true };
|
|
55
|
+
}
|
|
56
|
+
return { baseId: modelId, longContextEntry: false };
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* True when Cursor publishes a distinct Fast rate for this wire model id.
|
|
60
|
+
* Catalog code uses this to split Fast variants into a `-fast` entry.
|
|
61
|
+
*/
|
|
62
|
+
export function hasCursorFastPricing(modelId) {
|
|
63
|
+
return Object.prototype.hasOwnProperty.call(CURSOR_MODEL_COSTS, `${modelId}-fast`);
|
|
56
64
|
}
|
|
57
65
|
function asMutableCost(value) {
|
|
58
66
|
const copy = { input: value.input, output: value.output };
|
|
@@ -68,6 +76,7 @@ function asMutableCost(value) {
|
|
|
68
76
|
/**
|
|
69
77
|
* Look up classic OpenCode cost for a catalog / wire model id.
|
|
70
78
|
* Synthetic `-1m` entries retain both base and documented long-context rates.
|
|
79
|
+
* Synthetic `-fast` entries are stored as their own keys.
|
|
71
80
|
*/
|
|
72
81
|
export function getCursorModelCost(modelId) {
|
|
73
82
|
const { baseId } = wireModelIdForPricing(modelId);
|
|
@@ -22,3 +22,8 @@ export declare const CURSOR_EXEC_VARIANTS: readonly CursorExecVariant[];
|
|
|
22
22
|
export declare function cursorExecVariantByRequestField(field: number): CursorExecVariant | undefined;
|
|
23
23
|
export declare function cursorExecVariantByRequestName(name: string): CursorExecVariant | undefined;
|
|
24
24
|
export declare function describeCursorExecVariant(field: number | undefined): string;
|
|
25
|
+
/**
|
|
26
|
+
* `ForceBackgroundShellResult` / `ForceBackgroundSubagentResult` status.
|
|
27
|
+
* Cursor CLI `ForceBackgroundStatus`: 0 unspecified, 1 ok, 2 error.
|
|
28
|
+
*/
|
|
29
|
+
export declare const FORCE_BACKGROUND_STATUS_ERROR = 2;
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
export const CURSOR_EXEC_VARIANTS = [
|
|
2
|
-
{ requestField: 2, requestName: "shell_args", resultField: 2, resultName: "shell_result", handling: "
|
|
2
|
+
{ requestField: 2, requestName: "shell_args", resultField: 2, resultName: "shell_result", handling: "opencode-tool" },
|
|
3
3
|
{ requestField: 3, requestName: "write_args", resultField: 3, resultName: "write_result", handling: "opencode-tool" },
|
|
4
4
|
{ requestField: 4, requestName: "delete_args", resultField: 4, resultName: "delete_result", handling: "opencode-tool" },
|
|
5
5
|
{ requestField: 5, requestName: "grep_args", resultField: 5, resultName: "grep_result", handling: "opencode-tool" },
|
|
6
6
|
{ requestField: 7, requestName: "read_args", resultField: 7, resultName: "read_result", handling: "opencode-tool" },
|
|
7
7
|
{ requestField: 8, requestName: "ls_args", resultField: 8, resultName: "ls_result", handling: "opencode-tool" },
|
|
8
|
+
// Dedicated Cursor read_lints (#9) is not planned. OpenCode only presents
|
|
9
|
+
// LSP errors on write/edit/apply_patch output plus GET /lsp status / navigation.
|
|
8
10
|
{ requestField: 9, requestName: "diagnostics_args", resultField: 9, resultName: "diagnostics_result", handling: "unsupported" },
|
|
9
11
|
{ requestField: 10, requestName: "request_context_args", resultField: 10, resultName: "request_context_result", handling: "provider-control" },
|
|
10
12
|
{ requestField: 11, requestName: "mcp_args", resultField: 11, resultName: "mcp_result", handling: "opencode-tool" },
|
|
@@ -23,12 +25,13 @@ export const CURSOR_EXEC_VARIANTS = [
|
|
|
23
25
|
{ requestField: 31, requestName: "force_background_subagent_args", resultField: 31, resultName: "force_background_subagent_result", handling: "unsupported" },
|
|
24
26
|
{ requestField: 36, requestName: "mcp_state_exec_args", resultField: 36, resultName: "mcp_state_exec_result", handling: "provider-control" },
|
|
25
27
|
{ requestField: 37, requestName: "subagent_await_args", resultField: 37, resultName: "subagent_await_result", handling: "unsupported" },
|
|
28
|
+
// OpenCode has no Auto-review / `--auto-review` mode. Not planned: keep the typed soft-deny.
|
|
26
29
|
{ requestField: 38, requestName: "smart_mode_classifier_args", resultField: 38, resultName: "smart_mode_classifier_result", handling: "unsupported" },
|
|
27
30
|
{ requestField: 40, requestName: "canvas_diagnostics_args", resultField: 40, resultName: "canvas_diagnostics_result", handling: "unsupported" },
|
|
28
31
|
{ requestField: 41, requestName: "shell_allowlist_precheck_args", resultField: 41, resultName: "shell_allowlist_precheck_result", handling: "unsupported" },
|
|
29
32
|
{ requestField: 42, requestName: "mcp_allowlist_precheck_args", resultField: 42, resultName: "mcp_allowlist_precheck_result", handling: "unsupported" },
|
|
30
33
|
{ requestField: 43, requestName: "web_fetch_allowlist_precheck_args", resultField: 43, resultName: "web_fetch_allowlist_precheck_result", handling: "unsupported" },
|
|
31
|
-
{ requestField: 44, requestName: "git_diff_request", resultField: 44, resultName: "git_diff_response", handling: "
|
|
34
|
+
{ requestField: 44, requestName: "git_diff_request", resultField: 44, resultName: "git_diff_response", handling: "provider-control" },
|
|
32
35
|
{ requestField: 45, requestName: "pi_read_args", resultField: 46, resultName: "pi_read_result", handling: "opencode-tool" },
|
|
33
36
|
{ requestField: 46, requestName: "pi_bash_args", resultField: 47, resultName: "pi_bash_result", handling: "opencode-tool" },
|
|
34
37
|
{ requestField: 47, requestName: "pi_edit_args", resultField: 48, resultName: "pi_edit_result", handling: "opencode-tool" },
|
|
@@ -36,6 +39,13 @@ export const CURSOR_EXEC_VARIANTS = [
|
|
|
36
39
|
{ requestField: 49, requestName: "pi_grep_args", resultField: 50, resultName: "pi_grep_result", handling: "opencode-tool" },
|
|
37
40
|
{ requestField: 50, requestName: "pi_find_args", resultField: 51, resultName: "pi_find_result", handling: "opencode-tool" },
|
|
38
41
|
{ requestField: 51, requestName: "pi_ls_args", resultField: 52, resultName: "pi_ls_result", handling: "opencode-tool" },
|
|
42
|
+
// Mini-SWE request #52 pairs with ShellResult at #55 (Pi-style offset; #55
|
|
43
|
+
// request is accept_hook_additional_contexts, not a variant).
|
|
44
|
+
// Mini-SWE / SWE-agent bash is not planned (same surface as Auto-review). Keep the typed soft-deny.
|
|
45
|
+
{ requestField: 52, requestName: "mini_swe_agent_bash_args", resultField: 55, resultName: "mini_swe_agent_bash_result", handling: "unsupported" },
|
|
46
|
+
{ requestField: 53, requestName: "conversation_search_args", resultField: 53, resultName: "conversation_search_result", handling: "unsupported" },
|
|
47
|
+
{ requestField: 54, requestName: "agent_store_conflict_args", resultField: 54, resultName: "agent_store_conflict_result", handling: "unsupported" },
|
|
48
|
+
{ requestField: 56, requestName: "adopt_args", resultField: 56, resultName: "adopt_result", handling: "unsupported" },
|
|
39
49
|
];
|
|
40
50
|
const BY_REQUEST_FIELD = new Map(CURSOR_EXEC_VARIANTS.map((variant) => [variant.requestField, variant]));
|
|
41
51
|
const BY_REQUEST_NAME = new Map(CURSOR_EXEC_VARIANTS.map((variant) => [variant.requestName, variant]));
|
|
@@ -53,3 +63,8 @@ export function describeCursorExecVariant(field) {
|
|
|
53
63
|
return `unknown request field #${field}`;
|
|
54
64
|
return `${variant.requestName} (request field #${variant.requestField}, expected result ${variant.resultName} field #${variant.resultField}, handling=${variant.handling})`;
|
|
55
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* `ForceBackgroundShellResult` / `ForceBackgroundSubagentResult` status.
|
|
68
|
+
* Cursor CLI `ForceBackgroundStatus`: 0 unspecified, 1 ok, 2 error.
|
|
69
|
+
*/
|
|
70
|
+
export const FORCE_BACKGROUND_STATUS_ERROR = 2;
|