@oh-my-pi/pi-catalog 17.3.5 → 17.3.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/CHANGELOG.md +31 -0
- package/dist/types/discovery/cursor-gen/agent_pb.d.ts +88 -3
- package/dist/types/identity/family.d.ts +13 -1
- package/dist/types/model-thinking.d.ts +6 -2
- package/dist/types/provider-models/descriptors.d.ts +3 -2
- package/dist/types/types.d.ts +12 -1
- package/dist/types/variant-collapse.d.ts +2 -0
- package/package.json +4 -4
- package/src/compat/openai.ts +27 -1
- package/src/discovery/codex.ts +133 -29
- package/src/discovery/cursor-gen/agent_pb.ts +614 -519
- package/src/discovery/cursor.ts +14 -1
- package/src/identity/family.ts +21 -1
- package/src/model-cache.ts +67 -6
- package/src/model-thinking.ts +38 -6
- package/src/models.json +685 -215
- package/src/provider-models/cache-provider-id.ts +3 -1
- package/src/provider-models/descriptors.ts +3 -2
- package/src/provider-models/openai-compat.ts +83 -3
- package/src/types.ts +12 -0
- package/src/variant-collapse.ts +67 -34
|
@@ -73,8 +73,10 @@ export function resolveModelCacheProviderId(providerId: string, options: ModelCa
|
|
|
73
73
|
case "openrouter":
|
|
74
74
|
return "openrouter:pseudo-api";
|
|
75
75
|
case "vllm": {
|
|
76
|
+
// v2: qwen3.8 rows cached before the reasoning/template-effort upgrade
|
|
77
|
+
// carry `reasoning: false` and must be refetched.
|
|
76
78
|
const baseUrl = options.baseUrl ?? getDefaultModelDiscoveryBaseUrl(providerId)!;
|
|
77
|
-
return `vllm:${Bun.hash(baseUrl).toString(36)}`;
|
|
79
|
+
return `vllm:models-v2:${Bun.hash(baseUrl).toString(36)}`;
|
|
78
80
|
}
|
|
79
81
|
default:
|
|
80
82
|
return providerId;
|
|
@@ -474,17 +474,18 @@ export const CATALOG_PROVIDERS = [
|
|
|
474
474
|
defaultModel: "openai/gpt-oss-120b",
|
|
475
475
|
envVars: ["COREWEAVE_API_KEY", "WANDB_API_KEY"],
|
|
476
476
|
createModelManagerOptions: (config: ModelManagerConfig) => coreWeaveModelManagerOptions(config),
|
|
477
|
+
dynamicModelsAuthoritative: true,
|
|
477
478
|
catalogDiscovery: { label: "CoreWeave Serverless Inference" },
|
|
478
479
|
},
|
|
479
480
|
{
|
|
480
481
|
id: "xai",
|
|
481
|
-
defaultModel: "grok-4.
|
|
482
|
+
defaultModel: "grok-4.6",
|
|
482
483
|
envVars: ["XAI_API_KEY"],
|
|
483
484
|
createModelManagerOptions: (config: ModelManagerConfig) => xaiModelManagerOptions(config),
|
|
484
485
|
},
|
|
485
486
|
{
|
|
486
487
|
id: "xai-oauth",
|
|
487
|
-
defaultModel: "grok-4.
|
|
488
|
+
defaultModel: "grok-4.6",
|
|
488
489
|
envVars: ["XAI_OAUTH_TOKEN", "XAI_API_KEY"],
|
|
489
490
|
createModelManagerOptions: (config: ModelManagerConfig) => xaiOAuthModelManagerOptions(config),
|
|
490
491
|
catalogDiscovery: {
|
|
@@ -16,6 +16,7 @@ import {
|
|
|
16
16
|
isGrokReasoningEffortCapable,
|
|
17
17
|
isKimiK3ModelId,
|
|
18
18
|
isKimiModelId,
|
|
19
|
+
isQwen38PlusTemplateEffortModelId,
|
|
19
20
|
isReasoningGlmModelId,
|
|
20
21
|
} from "../identity/family";
|
|
21
22
|
import { resolveModelReference } from "../identity/reference";
|
|
@@ -1073,10 +1074,61 @@ export interface GmiCloudModelManagerConfig {
|
|
|
1073
1074
|
fetch?: FetchImpl;
|
|
1074
1075
|
}
|
|
1075
1076
|
|
|
1077
|
+
/**
|
|
1078
|
+
* Map a discovered GMI Cloud model to a full spec.
|
|
1079
|
+
*
|
|
1080
|
+
* GMI's `/v1/models` returns only bare `{id}` rows, so discovery defaults carry
|
|
1081
|
+
* no limits, reasoning, or thinking metadata. When a gmi-cloud bundled
|
|
1082
|
+
* reference exists (the seeded default) it supplies GMI's published tariff and
|
|
1083
|
+
* limits directly. Every other id is an open-weight model GMI resells under its
|
|
1084
|
+
* canonical id (`deepseek-ai/…`, `moonshotai/…`, `zai-org/…`, `Qwen/…`), so its
|
|
1085
|
+
* intrinsic capabilities — context window, output limit, reasoning, thinking
|
|
1086
|
+
* ladder — are recovered from any bundled upstream entry via the canonical
|
|
1087
|
+
* reference index. Pricing is deliberately never borrowed across providers:
|
|
1088
|
+
* GMI's per-model tariff is unknown for these ids, so cost stays zeroed rather
|
|
1089
|
+
* than inheriting another provider's rate.
|
|
1090
|
+
*/
|
|
1091
|
+
function mapGmiCloudModel(
|
|
1092
|
+
entry: OpenAICompatibleModelRecord,
|
|
1093
|
+
defaults: ModelSpec<"openai-completions">,
|
|
1094
|
+
reference: ModelSpec<"openai-completions"> | undefined,
|
|
1095
|
+
): ModelSpec<"openai-completions"> {
|
|
1096
|
+
if (reference) {
|
|
1097
|
+
return mapWithBundledReference(entry, defaults, reference);
|
|
1098
|
+
}
|
|
1099
|
+
const canonical = resolveModelReference(defaults.id, getBundledModelReferenceIndex()) as
|
|
1100
|
+
| ModelSpec<"openai-completions">
|
|
1101
|
+
| undefined;
|
|
1102
|
+
if (!canonical) {
|
|
1103
|
+
return { ...defaults, name: toModelName(entry.name, defaults.name) };
|
|
1104
|
+
}
|
|
1105
|
+
const contextWindow = canonical.contextWindow ?? defaults.contextWindow;
|
|
1106
|
+
const maxTokens =
|
|
1107
|
+
canonical.maxTokens != null && contextWindow != null
|
|
1108
|
+
? Math.min(canonical.maxTokens, contextWindow)
|
|
1109
|
+
: (canonical.maxTokens ?? defaults.maxTokens);
|
|
1110
|
+
return {
|
|
1111
|
+
...defaults,
|
|
1112
|
+
name: toModelName(entry.name, canonical.name ?? defaults.name),
|
|
1113
|
+
reasoning: canonical.reasoning,
|
|
1114
|
+
input: canonical.input,
|
|
1115
|
+
...(canonical.thinking && { thinking: canonical.thinking }),
|
|
1116
|
+
contextWindow,
|
|
1117
|
+
maxTokens,
|
|
1118
|
+
};
|
|
1119
|
+
}
|
|
1120
|
+
|
|
1076
1121
|
export function gmiCloudModelManagerOptions(
|
|
1077
1122
|
config?: GmiCloudModelManagerConfig,
|
|
1078
1123
|
): ModelManagerOptions<"openai-completions"> {
|
|
1079
|
-
return
|
|
1124
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
1125
|
+
api: "openai-completions",
|
|
1126
|
+
providerId: "gmi-cloud",
|
|
1127
|
+
defaultBaseUrl: GMI_CLOUD_BASE_URL,
|
|
1128
|
+
config,
|
|
1129
|
+
requireApiKey: true,
|
|
1130
|
+
mapModel: mapGmiCloudModel,
|
|
1131
|
+
});
|
|
1080
1132
|
}
|
|
1081
1133
|
|
|
1082
1134
|
// ---------------------------------------------------------------------------
|
|
@@ -2980,6 +3032,10 @@ export const ALIBABA_TOKEN_PLAN_DISCOVERED_MODEL_LIMITS: Readonly<Record<string,
|
|
|
2980
3032
|
contextWindow: 1_000_000,
|
|
2981
3033
|
maxTokens: 384_000,
|
|
2982
3034
|
},
|
|
3035
|
+
"deepseek-v4-pro-0813": {
|
|
3036
|
+
contextWindow: 1_000_000,
|
|
3037
|
+
maxTokens: 384_000,
|
|
3038
|
+
},
|
|
2983
3039
|
"deepseek-v3.2": {
|
|
2984
3040
|
contextWindow: 131_072,
|
|
2985
3041
|
maxTokens: 65_536,
|
|
@@ -4994,6 +5050,11 @@ export function vllmModelManagerOptions(config?: VllmModelManagerConfig): ModelM
|
|
|
4994
5050
|
return {
|
|
4995
5051
|
...model,
|
|
4996
5052
|
contextWindow: toPositiveNumber(entry.max_model_len, model.contextWindow),
|
|
5053
|
+
// vLLM's /v1/models reports no reasoning capability. Qwen 3.8+
|
|
5054
|
+
// open weights always think (the template cannot disable it), so
|
|
5055
|
+
// light up the effort dial; buildModel derives the template
|
|
5056
|
+
// ladder from the id + local-backend compat.
|
|
5057
|
+
reasoning: model.reasoning || isQwen38PlusTemplateEffortModelId(model.id),
|
|
4997
5058
|
};
|
|
4998
5059
|
},
|
|
4999
5060
|
fetch: config?.fetch,
|
|
@@ -5071,8 +5132,18 @@ export interface GithubCopilotModelManagerConfig {
|
|
|
5071
5132
|
|
|
5072
5133
|
const COPILOT_ANTHROPIC_MODEL_PATTERN = /^claude-(haiku|sonnet|opus|fable|mythos)-\d/;
|
|
5073
5134
|
const isCopilotResponsesModelId = (modelId: string): boolean =>
|
|
5074
|
-
modelId === "grok-4.5" ||
|
|
5075
|
-
|
|
5135
|
+
modelId === "grok-4.5" ||
|
|
5136
|
+
modelId === "grok-4.6" ||
|
|
5137
|
+
modelId.startsWith("gpt-5") ||
|
|
5138
|
+
modelId.startsWith("oswe") ||
|
|
5139
|
+
modelId.startsWith("mai-");
|
|
5140
|
+
const COPILOT_CACHE_INVALIDATED_MODEL_IDS = [
|
|
5141
|
+
"grok-4.5",
|
|
5142
|
+
"grok-4.5-1m",
|
|
5143
|
+
"grok-4.6",
|
|
5144
|
+
"grok-4.6-1m",
|
|
5145
|
+
"mai-code-1-flash-picker",
|
|
5146
|
+
];
|
|
5076
5147
|
|
|
5077
5148
|
function inferCopilotApi(modelId: string): Api {
|
|
5078
5149
|
if (COPILOT_ANTHROPIC_MODEL_PATTERN.test(modelId)) {
|
|
@@ -5705,8 +5776,17 @@ const OPENCODE_ZEN_API_RESOLUTION = createOpenCodeApiResolution("https://opencod
|
|
|
5705
5776
|
// /zen/go/v1/chat/completions route does not work for this model while
|
|
5706
5777
|
// /zen/go/v1/responses does (user-verified against the live gateway,
|
|
5707
5778
|
// 2026-08-08; Flash only — deepseek-v4-pro serves fine on chat completions).
|
|
5779
|
+
//
|
|
5780
|
+
// muse-spark-1.2 / muse-spark-1.2-contributor are the same inverse case: the
|
|
5781
|
+
// Go gateway's /zen/go/v1/models discovery drops the `provider.npm` hint, so
|
|
5782
|
+
// without an override they fall through to openai-completions even though the
|
|
5783
|
+
// gateway only serves them at /zen/go/v1/responses (@ai-sdk/openai per
|
|
5784
|
+
// https://opencode.ai/docs/go/#endpoints). The completions parser then closes
|
|
5785
|
+
// the stream with no finish_reason on every tool-call turn (#8957).
|
|
5708
5786
|
const OPENCODE_GO_API_RESOLUTION = createOpenCodeApiResolution("https://opencode.ai/zen/go", {
|
|
5709
5787
|
"deepseek-v4-flash": "openai-responses",
|
|
5788
|
+
"muse-spark-1.2": "openai-responses",
|
|
5789
|
+
"muse-spark-1.2-contributor": "openai-responses",
|
|
5710
5790
|
"minimax-m2.7": "openai-completions",
|
|
5711
5791
|
"minimax-m3": "openai-completions",
|
|
5712
5792
|
"minimax-m3-free": "openai-completions",
|
package/src/types.ts
CHANGED
|
@@ -259,6 +259,16 @@ export interface OpenAICompat {
|
|
|
259
259
|
* Non-Qwen templates ignore the flag, so the auto-detection is safe.
|
|
260
260
|
*/
|
|
261
261
|
qwenPreserveThinking?: boolean;
|
|
262
|
+
/**
|
|
263
|
+
* Route the requested thinking effort onto the Qwen 3.8+ chat template's
|
|
264
|
+
* `reasoning_effort` kwarg (`low`/`medium`/`xhigh`; template default
|
|
265
|
+
* `xhigh`). Emitted inside `chat_template_kwargs` for both Qwen dialects
|
|
266
|
+
* (plus the top-level field on the `qwen` dialect, which newer llama.cpp
|
|
267
|
+
* builds map natively). Without it the qwen dialects only toggle
|
|
268
|
+
* `enable_thinking` and the template always thinks at its `xhigh` default.
|
|
269
|
+
* Default: auto-detected (Qwen 3.8+ id on a local llama.cpp-style backend).
|
|
270
|
+
*/
|
|
271
|
+
qwenTemplateReasoningEffort?: boolean;
|
|
262
272
|
/** Whether assistant tool-call messages must include non-empty content. Default: false. */
|
|
263
273
|
requiresAssistantContentForToolCalls?: boolean;
|
|
264
274
|
/** Whether the provider supports the `tool_choice` parameter. Default: true. */
|
|
@@ -604,6 +614,7 @@ export interface ResolvedOpenAISharedCompat {
|
|
|
604
614
|
allowsSyntheticReasoningContentForToolCalls: boolean;
|
|
605
615
|
replayReasoningContent: boolean;
|
|
606
616
|
qwenPreserveThinking: boolean;
|
|
617
|
+
qwenTemplateReasoningEffort: boolean;
|
|
607
618
|
requiresThinkingAsText: boolean;
|
|
608
619
|
requiresMistralToolIds: boolean;
|
|
609
620
|
requiresToolResultName: boolean;
|
|
@@ -669,6 +680,7 @@ export type ResolvedOpenAICompat = ResolvedOpenAISharedCompat &
|
|
|
669
680
|
| "allowsSyntheticReasoningContentForToolCalls"
|
|
670
681
|
| "replayReasoningContent"
|
|
671
682
|
| "qwenPreserveThinking"
|
|
683
|
+
| "qwenTemplateReasoningEffort"
|
|
672
684
|
| "requiresThinkingAsText"
|
|
673
685
|
| "requiresMistralToolIds"
|
|
674
686
|
| "requiresToolResultName"
|
package/src/variant-collapse.ts
CHANGED
|
@@ -111,19 +111,20 @@ function thinkingPair(baseId: string, name: string): EffortVariantFamily {
|
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
-
type
|
|
114
|
+
type TierRoutes = Partial<Record<"off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max", string>>;
|
|
115
115
|
|
|
116
116
|
/** Devin families with a `-max` sibling: five wire tiers, `low` floor. */
|
|
117
117
|
const DEVIN_FIVE_TIER_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High, Effort.XHigh, Effort.Max];
|
|
118
118
|
/** Pre-5.6 Devin GPT families top out at `-xhigh`: four wire tiers, `low` floor. */
|
|
119
119
|
const DEVIN_FOUR_TIER_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High, Effort.XHigh];
|
|
120
120
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
121
|
+
/**
|
|
122
|
+
* Build one effort-tier family from a tier→wire-id map: routing keeps only the
|
|
123
|
+
* listed efforts, `members` dedupes the targets in tier order, and thinking is
|
|
124
|
+
* `mode: "effort"` (mandatory when the family has no `off` route). Shared by the
|
|
125
|
+
* Devin and Cursor tables, whose per-effort siblings follow the same shape.
|
|
126
|
+
*/
|
|
127
|
+
function tierFamily(id: string, name: string, routes: TierRoutes, efforts: readonly Effort[]): EffortVariantFamily {
|
|
127
128
|
const routing: Partial<Record<Effort | "off", string>> = {};
|
|
128
129
|
if (routes.off) routing.off = routes.off;
|
|
129
130
|
for (const effort of efforts) {
|
|
@@ -177,7 +178,7 @@ function devinTierFamily(
|
|
|
177
178
|
function devinGpt56Families(variant: "luna" | "sol" | "terra", name: string): readonly EffortVariantFamily[] {
|
|
178
179
|
const base = `gpt-5-6-${variant}`;
|
|
179
180
|
return [
|
|
180
|
-
|
|
181
|
+
tierFamily(
|
|
181
182
|
base,
|
|
182
183
|
name,
|
|
183
184
|
{
|
|
@@ -190,7 +191,7 @@ function devinGpt56Families(variant: "luna" | "sol" | "terra", name: string): re
|
|
|
190
191
|
},
|
|
191
192
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
192
193
|
),
|
|
193
|
-
|
|
194
|
+
tierFamily(
|
|
194
195
|
`${base}-fast`,
|
|
195
196
|
`${name} Fast`,
|
|
196
197
|
{
|
|
@@ -395,7 +396,7 @@ export const GEMINI_CLI_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
395
396
|
};
|
|
396
397
|
export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
397
398
|
families: [
|
|
398
|
-
|
|
399
|
+
tierFamily(
|
|
399
400
|
"claude-opus-5",
|
|
400
401
|
"Claude Opus 5",
|
|
401
402
|
{
|
|
@@ -407,7 +408,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
407
408
|
},
|
|
408
409
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
409
410
|
),
|
|
410
|
-
|
|
411
|
+
tierFamily(
|
|
411
412
|
"claude-opus-5-fast",
|
|
412
413
|
"Claude Opus 5 Fast",
|
|
413
414
|
{
|
|
@@ -419,7 +420,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
419
420
|
},
|
|
420
421
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
421
422
|
),
|
|
422
|
-
|
|
423
|
+
tierFamily(
|
|
423
424
|
"claude-fable-5",
|
|
424
425
|
"Claude Fable 5",
|
|
425
426
|
{
|
|
@@ -431,7 +432,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
431
432
|
},
|
|
432
433
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
433
434
|
),
|
|
434
|
-
|
|
435
|
+
tierFamily(
|
|
435
436
|
"claude-sonnet-5",
|
|
436
437
|
"Claude Sonnet 5",
|
|
437
438
|
{
|
|
@@ -443,7 +444,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
443
444
|
},
|
|
444
445
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
445
446
|
),
|
|
446
|
-
|
|
447
|
+
tierFamily(
|
|
447
448
|
"claude-opus-4-7",
|
|
448
449
|
"Claude Opus 4.7",
|
|
449
450
|
{
|
|
@@ -455,7 +456,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
455
456
|
},
|
|
456
457
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
457
458
|
),
|
|
458
|
-
|
|
459
|
+
tierFamily(
|
|
459
460
|
"claude-opus-4-7-fast",
|
|
460
461
|
"Claude Opus 4.7 Fast",
|
|
461
462
|
{
|
|
@@ -467,7 +468,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
467
468
|
},
|
|
468
469
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
469
470
|
),
|
|
470
|
-
|
|
471
|
+
tierFamily(
|
|
471
472
|
"claude-opus-4-8",
|
|
472
473
|
"Claude Opus 4.8",
|
|
473
474
|
{
|
|
@@ -479,7 +480,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
479
480
|
},
|
|
480
481
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
481
482
|
),
|
|
482
|
-
|
|
483
|
+
tierFamily(
|
|
483
484
|
"claude-opus-4-8-fast",
|
|
484
485
|
"Claude Opus 4.8 Fast",
|
|
485
486
|
{
|
|
@@ -491,7 +492,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
491
492
|
},
|
|
492
493
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
493
494
|
),
|
|
494
|
-
|
|
495
|
+
tierFamily(
|
|
495
496
|
"gpt-5-2",
|
|
496
497
|
"GPT-5.2",
|
|
497
498
|
{
|
|
@@ -503,7 +504,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
503
504
|
},
|
|
504
505
|
DEVIN_FOUR_TIER_EFFORTS,
|
|
505
506
|
),
|
|
506
|
-
|
|
507
|
+
tierFamily(
|
|
507
508
|
"gpt-5-3-codex",
|
|
508
509
|
"GPT-5.3 Codex",
|
|
509
510
|
{
|
|
@@ -514,7 +515,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
514
515
|
},
|
|
515
516
|
DEVIN_FOUR_TIER_EFFORTS,
|
|
516
517
|
),
|
|
517
|
-
|
|
518
|
+
tierFamily(
|
|
518
519
|
"gpt-5-3-codex-fast",
|
|
519
520
|
"GPT-5.3 Codex Fast",
|
|
520
521
|
{
|
|
@@ -525,7 +526,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
525
526
|
},
|
|
526
527
|
DEVIN_FOUR_TIER_EFFORTS,
|
|
527
528
|
),
|
|
528
|
-
|
|
529
|
+
tierFamily(
|
|
529
530
|
"gpt-5-4",
|
|
530
531
|
"GPT-5.4",
|
|
531
532
|
{
|
|
@@ -537,7 +538,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
537
538
|
},
|
|
538
539
|
DEVIN_FOUR_TIER_EFFORTS,
|
|
539
540
|
),
|
|
540
|
-
|
|
541
|
+
tierFamily(
|
|
541
542
|
"gpt-5-4-fast",
|
|
542
543
|
"GPT-5.4 Fast",
|
|
543
544
|
{
|
|
@@ -549,7 +550,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
549
550
|
},
|
|
550
551
|
DEVIN_FOUR_TIER_EFFORTS,
|
|
551
552
|
),
|
|
552
|
-
|
|
553
|
+
tierFamily(
|
|
553
554
|
"gpt-5-4-mini",
|
|
554
555
|
"GPT-5.4 Mini",
|
|
555
556
|
{
|
|
@@ -560,7 +561,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
560
561
|
},
|
|
561
562
|
DEVIN_FOUR_TIER_EFFORTS,
|
|
562
563
|
),
|
|
563
|
-
|
|
564
|
+
tierFamily(
|
|
564
565
|
"gpt-5-5",
|
|
565
566
|
"GPT-5.5",
|
|
566
567
|
{
|
|
@@ -572,7 +573,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
572
573
|
},
|
|
573
574
|
DEVIN_FOUR_TIER_EFFORTS,
|
|
574
575
|
),
|
|
575
|
-
|
|
576
|
+
tierFamily(
|
|
576
577
|
"gpt-5-5-fast",
|
|
577
578
|
"GPT-5.5 Fast",
|
|
578
579
|
{
|
|
@@ -587,7 +588,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
587
588
|
...devinGpt56Families("luna", "GPT-5.6 Luna"),
|
|
588
589
|
...devinGpt56Families("sol", "GPT-5.6 Sol"),
|
|
589
590
|
...devinGpt56Families("terra", "GPT-5.6 Terra"),
|
|
590
|
-
|
|
591
|
+
tierFamily(
|
|
591
592
|
"kimi-k3",
|
|
592
593
|
"Kimi K3",
|
|
593
594
|
{
|
|
@@ -597,7 +598,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
597
598
|
},
|
|
598
599
|
[Effort.Low, Effort.High, Effort.Max],
|
|
599
600
|
),
|
|
600
|
-
|
|
601
|
+
tierFamily(
|
|
601
602
|
"swe-1-7",
|
|
602
603
|
"SWE-1.7",
|
|
603
604
|
{
|
|
@@ -606,7 +607,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
606
607
|
},
|
|
607
608
|
[Effort.Medium, Effort.Max],
|
|
608
609
|
),
|
|
609
|
-
|
|
610
|
+
tierFamily(
|
|
610
611
|
"grok-4-5",
|
|
611
612
|
"Grok 4.5",
|
|
612
613
|
{
|
|
@@ -616,7 +617,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
616
617
|
},
|
|
617
618
|
[Effort.Low, Effort.Medium, Effort.High],
|
|
618
619
|
),
|
|
619
|
-
|
|
620
|
+
tierFamily(
|
|
620
621
|
"inkling",
|
|
621
622
|
"Inkling",
|
|
622
623
|
{
|
|
@@ -629,7 +630,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
629
630
|
},
|
|
630
631
|
DEVIN_FIVE_TIER_EFFORTS,
|
|
631
632
|
),
|
|
632
|
-
|
|
633
|
+
tierFamily(
|
|
633
634
|
"gemini-3-1-pro",
|
|
634
635
|
"Gemini 3.1 Pro",
|
|
635
636
|
{
|
|
@@ -638,7 +639,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
638
639
|
},
|
|
639
640
|
[Effort.Low, Effort.High],
|
|
640
641
|
),
|
|
641
|
-
|
|
642
|
+
tierFamily(
|
|
642
643
|
"gemini-3-5-flash",
|
|
643
644
|
"Gemini 3.5 Flash",
|
|
644
645
|
{
|
|
@@ -649,7 +650,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
649
650
|
},
|
|
650
651
|
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High],
|
|
651
652
|
),
|
|
652
|
-
|
|
653
|
+
tierFamily(
|
|
653
654
|
"gemini-3-6-flash",
|
|
654
655
|
"Gemini 3.6 Flash",
|
|
655
656
|
{
|
|
@@ -660,7 +661,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
660
661
|
},
|
|
661
662
|
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High],
|
|
662
663
|
),
|
|
663
|
-
|
|
664
|
+
tierFamily(
|
|
664
665
|
"gemini-3-flash",
|
|
665
666
|
"Gemini 3 Flash",
|
|
666
667
|
{
|
|
@@ -694,7 +695,7 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
694
695
|
},
|
|
695
696
|
// GLM-5.2 1M — paid variants that consume weekly quota. Collapse the
|
|
696
697
|
// three 1M-context variants into one entry with proper effort routing.
|
|
697
|
-
|
|
698
|
+
tierFamily(
|
|
698
699
|
"glm-5-2-1m",
|
|
699
700
|
"GLM-5.2 1M",
|
|
700
701
|
{
|
|
@@ -707,11 +708,43 @@ export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
707
708
|
],
|
|
708
709
|
};
|
|
709
710
|
|
|
711
|
+
/** Cursor's Grok tier tokens equal the effort id, so routing is a direct map. */
|
|
712
|
+
const CURSOR_GROK_45_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High];
|
|
713
|
+
const CURSOR_GROK_46_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High, Effort.XHigh];
|
|
714
|
+
|
|
715
|
+
/**
|
|
716
|
+
* Cursor serves Grok 4.5/4.6 as per-effort sibling ids
|
|
717
|
+
* (`cursor-grok-4.6-low|-medium|-high|-xhigh`) alongside a parallel `-fast`
|
|
718
|
+
* service-tier lane (`-low-fast`, …). Each lane collapses into its own logical
|
|
719
|
+
* model — the `-fast` axis is a sibling family, never a second routing
|
|
720
|
+
* dimension — with effort routing onto the live sibling wire ids.
|
|
721
|
+
*/
|
|
722
|
+
function cursorGrokFamilies(version: "4.5" | "4.6", efforts: readonly Effort[]): readonly EffortVariantFamily[] {
|
|
723
|
+
const build = (fast: boolean): EffortVariantFamily => {
|
|
724
|
+
const suffix = fast ? "-fast" : "";
|
|
725
|
+
const routes: TierRoutes = {};
|
|
726
|
+
for (const effort of efforts) {
|
|
727
|
+
routes[effort] = `cursor-grok-${version}-${effort}${suffix}`;
|
|
728
|
+
}
|
|
729
|
+
return tierFamily(`cursor-grok-${version}${suffix}`, `Grok ${version}${fast ? " Fast" : ""}`, routes, efforts);
|
|
730
|
+
};
|
|
731
|
+
return [build(false), build(true)];
|
|
732
|
+
}
|
|
733
|
+
|
|
734
|
+
/** `cursor` Grok families: per-effort siblings collapsed per service-tier lane. */
|
|
735
|
+
export const CURSOR_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
736
|
+
families: [
|
|
737
|
+
...cursorGrokFamilies("4.5", CURSOR_GROK_45_EFFORTS),
|
|
738
|
+
...cursorGrokFamilies("4.6", CURSOR_GROK_46_EFFORTS),
|
|
739
|
+
],
|
|
740
|
+
};
|
|
741
|
+
|
|
710
742
|
/** Provider id → hand collapse table. The CCA providers diverge on thinking transport. */
|
|
711
743
|
export const VARIANT_COLLAPSE_TABLES: Readonly<Record<string, VariantCollapseTable>> = {
|
|
712
744
|
"google-antigravity": ANTIGRAVITY_VARIANT_COLLAPSE_TABLE,
|
|
713
745
|
"google-gemini-cli": GEMINI_CLI_VARIANT_COLLAPSE_TABLE,
|
|
714
746
|
devin: DEVIN_VARIANT_COLLAPSE_TABLE,
|
|
747
|
+
cursor: CURSOR_VARIANT_COLLAPSE_TABLE,
|
|
715
748
|
};
|
|
716
749
|
|
|
717
750
|
/**
|