@oh-my-pi/pi-catalog 16.1.13 → 16.1.14
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 +16 -0
- package/dist/types/compat/devin.d.ts +9 -0
- package/dist/types/provider-models/descriptors.d.ts +9 -0
- package/dist/types/provider-models/openai-compat.d.ts +7 -0
- package/dist/types/types.d.ts +21 -2
- package/dist/types/variant-collapse.d.ts +1 -0
- package/package.json +3 -3
- package/src/build.ts +3 -0
- package/src/compat/devin.ts +12 -0
- package/src/compat/openai.ts +1 -0
- package/src/discovery/devin.ts +1 -2
- package/src/model-thinking.ts +19 -0
- package/src/models.json +568 -1842
- package/src/provider-models/descriptors.ts +9 -0
- package/src/provider-models/openai-compat.ts +95 -0
- package/src/types.ts +27 -2
- package/src/variant-collapse.ts +271 -0
|
@@ -35,6 +35,7 @@ import {
|
|
|
35
35
|
openrouterModelManagerOptions,
|
|
36
36
|
qianfanModelManagerOptions,
|
|
37
37
|
qwenPortalModelManagerOptions,
|
|
38
|
+
sakanaModelManagerOptions,
|
|
38
39
|
syntheticModelManagerOptions,
|
|
39
40
|
togetherModelManagerOptions,
|
|
40
41
|
umansModelManagerOptions,
|
|
@@ -308,6 +309,14 @@ export const CATALOG_PROVIDERS = [
|
|
|
308
309
|
oauthProvider: "qwen-portal",
|
|
309
310
|
},
|
|
310
311
|
},
|
|
312
|
+
{
|
|
313
|
+
id: "sakana",
|
|
314
|
+
defaultModel: "fugu",
|
|
315
|
+
envVars: ["SAKANA_API_KEY", "FUGU_API_KEY"],
|
|
316
|
+
createModelManagerOptions: (config: ModelManagerConfig) => sakanaModelManagerOptions(config),
|
|
317
|
+
dynamicModelsAuthoritative: true,
|
|
318
|
+
catalogDiscovery: { label: "Sakana AI" },
|
|
319
|
+
},
|
|
311
320
|
{
|
|
312
321
|
id: "synthetic",
|
|
313
322
|
defaultModel: "hf:zai-org/GLM-5.1",
|
|
@@ -2520,6 +2520,101 @@ export function moonshotModelManagerOptions(
|
|
|
2520
2520
|
};
|
|
2521
2521
|
}
|
|
2522
2522
|
|
|
2523
|
+
// ---------------------------------------------------------------------------
|
|
2524
|
+
// 16.5 Sakana AI
|
|
2525
|
+
// ---------------------------------------------------------------------------
|
|
2526
|
+
|
|
2527
|
+
const SAKANA_DEFAULT_BASE_URL = "https://api.sakana.ai/v1";
|
|
2528
|
+
const SAKANA_FREE_ROUTER_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 } as const;
|
|
2529
|
+
const SAKANA_FUGU_ULTRA_COST = { input: 5, output: 30, cacheRead: 0.5, cacheWrite: 0 } as const;
|
|
2530
|
+
const SAKANA_FUGU_THINKING: ThinkingConfig = {
|
|
2531
|
+
mode: "effort",
|
|
2532
|
+
efforts: [Effort.High, Effort.XHigh],
|
|
2533
|
+
effortMap: { [Effort.XHigh]: "max" },
|
|
2534
|
+
};
|
|
2535
|
+
const SAKANA_RESPONSES_COMPAT: ModelSpec<"openai-responses">["compat"] = {
|
|
2536
|
+
includeEncryptedReasoning: false,
|
|
2537
|
+
streamIdleTimeoutMs: 300_000,
|
|
2538
|
+
};
|
|
2539
|
+
|
|
2540
|
+
function normalizeSakanaBaseUrl(baseUrl: string | undefined): string {
|
|
2541
|
+
const value = baseUrl?.trim() || SAKANA_DEFAULT_BASE_URL;
|
|
2542
|
+
const normalized = value.replace(/\/+$/, "");
|
|
2543
|
+
return normalized.endsWith("/v1") ? normalized : `${normalized}/v1`;
|
|
2544
|
+
}
|
|
2545
|
+
|
|
2546
|
+
function isSakanaFuguModelId(modelId: string): boolean {
|
|
2547
|
+
return /^fugu(?:$|-)/i.test(modelId);
|
|
2548
|
+
}
|
|
2549
|
+
|
|
2550
|
+
function createSakanaFuguStaticModel(
|
|
2551
|
+
id: string,
|
|
2552
|
+
name: string,
|
|
2553
|
+
cost: ModelSpec<"openai-responses">["cost"],
|
|
2554
|
+
): ModelSpec<"openai-responses"> {
|
|
2555
|
+
return {
|
|
2556
|
+
id,
|
|
2557
|
+
name,
|
|
2558
|
+
api: "openai-responses",
|
|
2559
|
+
provider: "sakana",
|
|
2560
|
+
baseUrl: SAKANA_DEFAULT_BASE_URL,
|
|
2561
|
+
reasoning: true,
|
|
2562
|
+
input: ["text"],
|
|
2563
|
+
cost: { ...cost },
|
|
2564
|
+
contextWindow: null,
|
|
2565
|
+
maxTokens: null,
|
|
2566
|
+
thinking: { ...SAKANA_FUGU_THINKING },
|
|
2567
|
+
compat: { ...SAKANA_RESPONSES_COMPAT },
|
|
2568
|
+
};
|
|
2569
|
+
}
|
|
2570
|
+
|
|
2571
|
+
export const SAKANA_FUGU_STATIC_MODELS: readonly ModelSpec<"openai-responses">[] = [
|
|
2572
|
+
createSakanaFuguStaticModel("fugu", "Fugu", SAKANA_FREE_ROUTER_COST),
|
|
2573
|
+
createSakanaFuguStaticModel("fugu-ultra", "Fugu Ultra", SAKANA_FUGU_ULTRA_COST),
|
|
2574
|
+
createSakanaFuguStaticModel("fugu-ultra-20260615", "Fugu Ultra 20260615", SAKANA_FUGU_ULTRA_COST),
|
|
2575
|
+
];
|
|
2576
|
+
|
|
2577
|
+
const SAKANA_FUGU_STATIC_MODEL_BY_ID = new Map(SAKANA_FUGU_STATIC_MODELS.map(model => [model.id, model] as const));
|
|
2578
|
+
|
|
2579
|
+
export interface SakanaModelManagerConfig {
|
|
2580
|
+
apiKey?: string;
|
|
2581
|
+
baseUrl?: string;
|
|
2582
|
+
fetch?: FetchImpl;
|
|
2583
|
+
}
|
|
2584
|
+
|
|
2585
|
+
export function sakanaModelManagerOptions(config?: SakanaModelManagerConfig): ModelManagerOptions<"openai-responses"> {
|
|
2586
|
+
const apiKey = config?.apiKey;
|
|
2587
|
+
const baseUrl = normalizeSakanaBaseUrl(config?.baseUrl ?? Bun.env.SAKANA_BASE_URL ?? Bun.env.FUGU_BASE_URL);
|
|
2588
|
+
const references = createBundledReferenceMap<"openai-responses">("sakana");
|
|
2589
|
+
return {
|
|
2590
|
+
providerId: "sakana",
|
|
2591
|
+
dynamicModelsAuthoritative: true,
|
|
2592
|
+
...(apiKey && {
|
|
2593
|
+
fetchDynamicModels: () =>
|
|
2594
|
+
fetchOpenAICompatibleModels({
|
|
2595
|
+
api: "openai-responses",
|
|
2596
|
+
provider: "sakana",
|
|
2597
|
+
baseUrl,
|
|
2598
|
+
apiKey,
|
|
2599
|
+
mapModel: (entry, defaults) => {
|
|
2600
|
+
const reference = references.get(defaults.id) ?? SAKANA_FUGU_STATIC_MODEL_BY_ID.get(defaults.id);
|
|
2601
|
+
const model = mapWithBundledReference(entry, defaults, reference);
|
|
2602
|
+
if (!reference && isSakanaFuguModelId(model.id)) {
|
|
2603
|
+
return {
|
|
2604
|
+
...model,
|
|
2605
|
+
reasoning: true,
|
|
2606
|
+
thinking: { ...SAKANA_FUGU_THINKING },
|
|
2607
|
+
compat: { ...SAKANA_RESPONSES_COMPAT },
|
|
2608
|
+
};
|
|
2609
|
+
}
|
|
2610
|
+
return model;
|
|
2611
|
+
},
|
|
2612
|
+
fetch: config?.fetch,
|
|
2613
|
+
}),
|
|
2614
|
+
}),
|
|
2615
|
+
};
|
|
2616
|
+
}
|
|
2617
|
+
|
|
2523
2618
|
// ---------------------------------------------------------------------------
|
|
2524
2619
|
// 17. Qwen Portal
|
|
2525
2620
|
// ---------------------------------------------------------------------------
|
package/src/types.ts
CHANGED
|
@@ -534,6 +534,7 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
|
|
|
534
534
|
supportsImageDetailOriginal: boolean;
|
|
535
535
|
requiresJuiceZeroHack: boolean;
|
|
536
536
|
supportsObfuscationOptOut: boolean;
|
|
537
|
+
streamIdleTimeoutMs?: number;
|
|
537
538
|
}
|
|
538
539
|
|
|
539
540
|
/**
|
|
@@ -554,6 +555,26 @@ export type ResolvedAnthropicCompat = Required<AnthropicCompat> & {
|
|
|
554
555
|
officialEndpoint: boolean;
|
|
555
556
|
};
|
|
556
557
|
|
|
558
|
+
/**
|
|
559
|
+
* Compatibility settings for the devin-agent (Codeium Cascade) API. Cascade
|
|
560
|
+
* selects reasoning effort only by routing to a sibling model id (the
|
|
561
|
+
* `thinking.effortRouting` baked by variant-collapse), never by a wire
|
|
562
|
+
* reasoning/effort field, so the model-thinking deriver must not invent an
|
|
563
|
+
* effort ladder from identity for these models.
|
|
564
|
+
*/
|
|
565
|
+
export interface DevinCompat {
|
|
566
|
+
/**
|
|
567
|
+
* Trust only explicit `thinking` metadata; never derive a thinking surface
|
|
568
|
+
* from model identity. A reasoning model with no explicit routed thinking
|
|
569
|
+
* resolves to `thinking: undefined` (`reasoning: true`, no controllable
|
|
570
|
+
* effort) instead of a fabricated minimal/low/medium/high ladder.
|
|
571
|
+
*/
|
|
572
|
+
trustExplicitThinkingOnly?: boolean;
|
|
573
|
+
}
|
|
574
|
+
|
|
575
|
+
/** Fully-resolved devin-agent compat view. */
|
|
576
|
+
export type ResolvedDevinCompat = Required<DevinCompat>;
|
|
577
|
+
|
|
557
578
|
/** Sparse, user-authored compat overrides for a given API (models.json / config vocabulary). */
|
|
558
579
|
export type CompatConfigOf<TApi extends Api> = TApi extends
|
|
559
580
|
| "openai-completions"
|
|
@@ -564,7 +585,9 @@ export type CompatConfigOf<TApi extends Api> = TApi extends
|
|
|
564
585
|
? OpenAICompat
|
|
565
586
|
: TApi extends "anthropic-messages"
|
|
566
587
|
? AnthropicCompat
|
|
567
|
-
:
|
|
588
|
+
: TApi extends "devin-agent"
|
|
589
|
+
? DevinCompat
|
|
590
|
+
: undefined;
|
|
568
591
|
|
|
569
592
|
/** Resolved compat for a given API: complete record, materialized once by `buildModel`. */
|
|
570
593
|
export type CompatOf<TApi extends Api> = TApi extends "openrouter"
|
|
@@ -575,7 +598,9 @@ export type CompatOf<TApi extends Api> = TApi extends "openrouter"
|
|
|
575
598
|
? ResolvedOpenAIResponsesCompat
|
|
576
599
|
: TApi extends "anthropic-messages"
|
|
577
600
|
? ResolvedAnthropicCompat
|
|
578
|
-
:
|
|
601
|
+
: TApi extends "devin-agent"
|
|
602
|
+
? ResolvedDevinCompat
|
|
603
|
+
: undefined;
|
|
579
604
|
|
|
580
605
|
// Model interface for the unified model system
|
|
581
606
|
export interface Model<TApi extends Api = Api> {
|
package/src/variant-collapse.ts
CHANGED
|
@@ -111,6 +111,55 @@ function thinkingPair(baseId: string, name: string): EffortVariantFamily {
|
|
|
111
111
|
};
|
|
112
112
|
}
|
|
113
113
|
|
|
114
|
+
type DevinTierRoutes = Partial<Record<"off" | "minimal" | "low" | "medium" | "high" | "xhigh", string>>;
|
|
115
|
+
|
|
116
|
+
function devinTierFamily(
|
|
117
|
+
id: string,
|
|
118
|
+
name: string,
|
|
119
|
+
routes: DevinTierRoutes,
|
|
120
|
+
efforts: readonly Effort[],
|
|
121
|
+
): EffortVariantFamily {
|
|
122
|
+
const routing: Partial<Record<Effort | "off", string>> = {};
|
|
123
|
+
if (routes.off) routing.off = routes.off;
|
|
124
|
+
for (const effort of efforts) {
|
|
125
|
+
switch (effort) {
|
|
126
|
+
case Effort.Minimal:
|
|
127
|
+
if (routes.minimal) {
|
|
128
|
+
routing[effort] = routes.minimal;
|
|
129
|
+
} else if (routes.low) {
|
|
130
|
+
routing[effort] = routes.low;
|
|
131
|
+
}
|
|
132
|
+
break;
|
|
133
|
+
case Effort.Low:
|
|
134
|
+
if (routes.low) routing[effort] = routes.low;
|
|
135
|
+
break;
|
|
136
|
+
case Effort.Medium:
|
|
137
|
+
if (routes.medium) routing[effort] = routes.medium;
|
|
138
|
+
break;
|
|
139
|
+
case Effort.High:
|
|
140
|
+
if (routes.high) routing[effort] = routes.high;
|
|
141
|
+
break;
|
|
142
|
+
case Effort.XHigh:
|
|
143
|
+
if (routes.xhigh) routing[effort] = routes.xhigh;
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
const members = [routes.off, routes.minimal, routes.low, routes.medium, routes.high, routes.xhigh].filter(
|
|
148
|
+
(member, index, items): member is string => typeof member === "string" && items.indexOf(member) === index,
|
|
149
|
+
);
|
|
150
|
+
return {
|
|
151
|
+
id,
|
|
152
|
+
name,
|
|
153
|
+
members,
|
|
154
|
+
routing,
|
|
155
|
+
thinking: {
|
|
156
|
+
mode: "effort",
|
|
157
|
+
efforts,
|
|
158
|
+
...(routes.off ? undefined : { requiresEffort: true }),
|
|
159
|
+
},
|
|
160
|
+
};
|
|
161
|
+
}
|
|
162
|
+
|
|
114
163
|
const GEMINI_3_FLASH_FAMILY_EFFORTS: readonly Effort[] = [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High];
|
|
115
164
|
const GEMINI_3_PRO_FAMILY_EFFORTS: readonly Effort[] = [Effort.Low, Effort.High];
|
|
116
165
|
|
|
@@ -237,6 +286,7 @@ const SHARED_CCA_FAMILIES: readonly EffortVariantFamily[] = [
|
|
|
237
286
|
routing: {},
|
|
238
287
|
thinking: { mode: "budget", efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High] },
|
|
239
288
|
},
|
|
289
|
+
|
|
240
290
|
{
|
|
241
291
|
id: "claude-opus-4-6",
|
|
242
292
|
name: "Claude Opus 4.6",
|
|
@@ -259,11 +309,232 @@ export const ANTIGRAVITY_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
|
259
309
|
export const GEMINI_CLI_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
260
310
|
families: [geminiFlashFamily("google-level"), geminiProFamily("google-level"), ...SHARED_CCA_FAMILIES],
|
|
261
311
|
};
|
|
312
|
+
export const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable = {
|
|
313
|
+
families: [
|
|
314
|
+
{
|
|
315
|
+
id: "claude-opus-4-7",
|
|
316
|
+
name: "Claude Opus 4.7",
|
|
317
|
+
members: [
|
|
318
|
+
"claude-opus-4-7-low",
|
|
319
|
+
"claude-opus-4-7-medium",
|
|
320
|
+
"claude-opus-4-7-high",
|
|
321
|
+
"claude-opus-4-7-xhigh",
|
|
322
|
+
"claude-opus-4-7-max",
|
|
323
|
+
],
|
|
324
|
+
routing: {
|
|
325
|
+
[Effort.Minimal]: "claude-opus-4-7-low",
|
|
326
|
+
[Effort.Low]: "claude-opus-4-7-medium",
|
|
327
|
+
[Effort.Medium]: "claude-opus-4-7-high",
|
|
328
|
+
[Effort.High]: "claude-opus-4-7-xhigh",
|
|
329
|
+
[Effort.XHigh]: "claude-opus-4-7-max",
|
|
330
|
+
},
|
|
331
|
+
thinking: {
|
|
332
|
+
mode: "effort",
|
|
333
|
+
efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
334
|
+
requiresEffort: true,
|
|
335
|
+
},
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
id: "claude-opus-4-7-fast",
|
|
339
|
+
name: "Claude Opus 4.7 Fast",
|
|
340
|
+
members: [
|
|
341
|
+
"claude-opus-4-7-low-fast",
|
|
342
|
+
"claude-opus-4-7-medium-fast",
|
|
343
|
+
"claude-opus-4-7-high-fast",
|
|
344
|
+
"claude-opus-4-7-xhigh-fast",
|
|
345
|
+
"claude-opus-4-7-max-fast",
|
|
346
|
+
],
|
|
347
|
+
routing: {
|
|
348
|
+
[Effort.Minimal]: "claude-opus-4-7-low-fast",
|
|
349
|
+
[Effort.Low]: "claude-opus-4-7-medium-fast",
|
|
350
|
+
[Effort.Medium]: "claude-opus-4-7-high-fast",
|
|
351
|
+
[Effort.High]: "claude-opus-4-7-xhigh-fast",
|
|
352
|
+
[Effort.XHigh]: "claude-opus-4-7-max-fast",
|
|
353
|
+
},
|
|
354
|
+
thinking: {
|
|
355
|
+
mode: "effort",
|
|
356
|
+
efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
357
|
+
requiresEffort: true,
|
|
358
|
+
},
|
|
359
|
+
},
|
|
360
|
+
{
|
|
361
|
+
id: "claude-opus-4-8",
|
|
362
|
+
name: "Claude Opus 4.8",
|
|
363
|
+
members: [
|
|
364
|
+
"claude-opus-4-8-low",
|
|
365
|
+
"claude-opus-4-8-medium",
|
|
366
|
+
"claude-opus-4-8-high",
|
|
367
|
+
"claude-opus-4-8-xhigh",
|
|
368
|
+
"claude-opus-4-8-max",
|
|
369
|
+
],
|
|
370
|
+
routing: {
|
|
371
|
+
[Effort.Minimal]: "claude-opus-4-8-low",
|
|
372
|
+
[Effort.Low]: "claude-opus-4-8-medium",
|
|
373
|
+
[Effort.Medium]: "claude-opus-4-8-high",
|
|
374
|
+
[Effort.High]: "claude-opus-4-8-xhigh",
|
|
375
|
+
[Effort.XHigh]: "claude-opus-4-8-max",
|
|
376
|
+
},
|
|
377
|
+
thinking: {
|
|
378
|
+
mode: "effort",
|
|
379
|
+
efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
380
|
+
requiresEffort: true,
|
|
381
|
+
},
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
id: "claude-opus-4-8-fast",
|
|
385
|
+
name: "Claude Opus 4.8 Fast",
|
|
386
|
+
members: [
|
|
387
|
+
"claude-opus-4-8-low-fast",
|
|
388
|
+
"claude-opus-4-8-medium-fast",
|
|
389
|
+
"claude-opus-4-8-high-fast",
|
|
390
|
+
"claude-opus-4-8-xhigh-fast",
|
|
391
|
+
"claude-opus-4-8-max-fast",
|
|
392
|
+
],
|
|
393
|
+
routing: {
|
|
394
|
+
[Effort.Minimal]: "claude-opus-4-8-low-fast",
|
|
395
|
+
[Effort.Low]: "claude-opus-4-8-medium-fast",
|
|
396
|
+
[Effort.Medium]: "claude-opus-4-8-high-fast",
|
|
397
|
+
[Effort.High]: "claude-opus-4-8-xhigh-fast",
|
|
398
|
+
[Effort.XHigh]: "claude-opus-4-8-max-fast",
|
|
399
|
+
},
|
|
400
|
+
thinking: {
|
|
401
|
+
mode: "effort",
|
|
402
|
+
efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
403
|
+
requiresEffort: true,
|
|
404
|
+
},
|
|
405
|
+
},
|
|
406
|
+
devinTierFamily(
|
|
407
|
+
"gpt-5-2",
|
|
408
|
+
"GPT-5.2",
|
|
409
|
+
{
|
|
410
|
+
off: "MODEL_GPT_5_2_NONE",
|
|
411
|
+
low: "MODEL_GPT_5_2_LOW",
|
|
412
|
+
medium: "MODEL_GPT_5_2_MEDIUM",
|
|
413
|
+
high: "MODEL_GPT_5_2_HIGH",
|
|
414
|
+
xhigh: "MODEL_GPT_5_2_XHIGH",
|
|
415
|
+
},
|
|
416
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
417
|
+
),
|
|
418
|
+
devinTierFamily(
|
|
419
|
+
"gpt-5-3-codex",
|
|
420
|
+
"GPT-5.3 Codex",
|
|
421
|
+
{
|
|
422
|
+
low: "gpt-5-3-codex-low",
|
|
423
|
+
medium: "gpt-5-3-codex-medium",
|
|
424
|
+
high: "gpt-5-3-codex-high",
|
|
425
|
+
xhigh: "gpt-5-3-codex-xhigh",
|
|
426
|
+
},
|
|
427
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
428
|
+
),
|
|
429
|
+
devinTierFamily(
|
|
430
|
+
"gpt-5-3-codex-fast",
|
|
431
|
+
"GPT-5.3 Codex Fast",
|
|
432
|
+
{
|
|
433
|
+
low: "gpt-5-3-codex-low-priority",
|
|
434
|
+
medium: "gpt-5-3-codex-medium-priority",
|
|
435
|
+
high: "gpt-5-3-codex-high-priority",
|
|
436
|
+
xhigh: "gpt-5-3-codex-xhigh-priority",
|
|
437
|
+
},
|
|
438
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
439
|
+
),
|
|
440
|
+
devinTierFamily(
|
|
441
|
+
"gpt-5-4",
|
|
442
|
+
"GPT-5.4",
|
|
443
|
+
{
|
|
444
|
+
off: "gpt-5-4-none",
|
|
445
|
+
low: "gpt-5-4-low",
|
|
446
|
+
medium: "gpt-5-4-medium",
|
|
447
|
+
high: "gpt-5-4-high",
|
|
448
|
+
xhigh: "gpt-5-4-xhigh",
|
|
449
|
+
},
|
|
450
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
451
|
+
),
|
|
452
|
+
devinTierFamily(
|
|
453
|
+
"gpt-5-4-fast",
|
|
454
|
+
"GPT-5.4 Fast",
|
|
455
|
+
{
|
|
456
|
+
off: "gpt-5-4-none-priority",
|
|
457
|
+
low: "gpt-5-4-low-priority",
|
|
458
|
+
medium: "gpt-5-4-medium-priority",
|
|
459
|
+
high: "gpt-5-4-high-priority",
|
|
460
|
+
xhigh: "gpt-5-4-xhigh-priority",
|
|
461
|
+
},
|
|
462
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
463
|
+
),
|
|
464
|
+
devinTierFamily(
|
|
465
|
+
"gpt-5-4-mini",
|
|
466
|
+
"GPT-5.4 Mini",
|
|
467
|
+
{
|
|
468
|
+
low: "gpt-5-4-mini-low",
|
|
469
|
+
medium: "gpt-5-4-mini-medium",
|
|
470
|
+
high: "gpt-5-4-mini-high",
|
|
471
|
+
xhigh: "gpt-5-4-mini-xhigh",
|
|
472
|
+
},
|
|
473
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
474
|
+
),
|
|
475
|
+
devinTierFamily(
|
|
476
|
+
"gpt-5-5",
|
|
477
|
+
"GPT-5.5",
|
|
478
|
+
{
|
|
479
|
+
off: "gpt-5-5-none",
|
|
480
|
+
low: "gpt-5-5-low",
|
|
481
|
+
medium: "gpt-5-5-medium",
|
|
482
|
+
high: "gpt-5-5-high",
|
|
483
|
+
xhigh: "gpt-5-5-xhigh",
|
|
484
|
+
},
|
|
485
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
486
|
+
),
|
|
487
|
+
devinTierFamily(
|
|
488
|
+
"gpt-5-5-fast",
|
|
489
|
+
"GPT-5.5 Fast",
|
|
490
|
+
{
|
|
491
|
+
off: "gpt-5-5-none-priority",
|
|
492
|
+
low: "gpt-5-5-low-priority",
|
|
493
|
+
medium: "gpt-5-5-medium-priority",
|
|
494
|
+
high: "gpt-5-5-high-priority",
|
|
495
|
+
xhigh: "gpt-5-5-xhigh-priority",
|
|
496
|
+
},
|
|
497
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High, Effort.XHigh],
|
|
498
|
+
),
|
|
499
|
+
devinTierFamily(
|
|
500
|
+
"gemini-3-1-pro",
|
|
501
|
+
"Gemini 3.1 Pro",
|
|
502
|
+
{
|
|
503
|
+
low: "gemini-3-1-pro-low",
|
|
504
|
+
high: "gemini-3-1-pro-high",
|
|
505
|
+
},
|
|
506
|
+
[Effort.Low, Effort.High],
|
|
507
|
+
),
|
|
508
|
+
devinTierFamily(
|
|
509
|
+
"gemini-3-5-flash",
|
|
510
|
+
"Gemini 3.5 Flash",
|
|
511
|
+
{
|
|
512
|
+
minimal: "gemini-3-5-flash-minimal",
|
|
513
|
+
low: "gemini-3-5-flash-low",
|
|
514
|
+
medium: "gemini-3-5-flash-medium",
|
|
515
|
+
high: "gemini-3-5-flash-high",
|
|
516
|
+
},
|
|
517
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High],
|
|
518
|
+
),
|
|
519
|
+
devinTierFamily(
|
|
520
|
+
"gemini-3-flash",
|
|
521
|
+
"Gemini 3 Flash",
|
|
522
|
+
{
|
|
523
|
+
minimal: "MODEL_GOOGLE_GEMINI_3_0_FLASH_MINIMAL",
|
|
524
|
+
low: "MODEL_GOOGLE_GEMINI_3_0_FLASH_LOW",
|
|
525
|
+
medium: "MODEL_GOOGLE_GEMINI_3_0_FLASH_MEDIUM",
|
|
526
|
+
high: "MODEL_GOOGLE_GEMINI_3_0_FLASH_HIGH",
|
|
527
|
+
},
|
|
528
|
+
[Effort.Minimal, Effort.Low, Effort.Medium, Effort.High],
|
|
529
|
+
),
|
|
530
|
+
],
|
|
531
|
+
};
|
|
262
532
|
|
|
263
533
|
/** Provider id → hand collapse table. The CCA providers diverge on thinking transport. */
|
|
264
534
|
export const VARIANT_COLLAPSE_TABLES: Readonly<Record<string, VariantCollapseTable>> = {
|
|
265
535
|
"google-antigravity": ANTIGRAVITY_VARIANT_COLLAPSE_TABLE,
|
|
266
536
|
"google-gemini-cli": GEMINI_CLI_VARIANT_COLLAPSE_TABLE,
|
|
537
|
+
devin: DEVIN_VARIANT_COLLAPSE_TABLE,
|
|
267
538
|
};
|
|
268
539
|
|
|
269
540
|
/**
|