@oh-my-pi/pi-catalog 16.1.13 → 16.1.15
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 +574 -1848
- package/src/provider-models/descriptors.ts +9 -0
- package/src/provider-models/openai-compat.ts +104 -0
- package/src/types.ts +27 -2
- package/src/variant-collapse.ts +271 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,22 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
+
## [16.1.14] - 2026-06-22
|
|
6
|
+
|
|
7
|
+
### Added
|
|
8
|
+
|
|
9
|
+
- Added Sakana AI provider support with Fugu model integration
|
|
10
|
+
- Added Sakana AI/Fugu provider catalog entries with Fugu model discovery and Responses API metadata
|
|
11
|
+
- Added support for "xhigh" reasoning tier across model configurations
|
|
12
|
+
- Added configuration for new models GCP-5.4 Mini, GPT-5.5, and variants
|
|
13
|
+
- Added `devin` variant collapse table to streamline model tiering
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Updated reasoning label pattern to include "minimal" and "max" efforts
|
|
18
|
+
- Simplified model identification logic for Devin-powered reasoning models
|
|
19
|
+
- Refactored variant routing to consolidate and standardize tier definitions
|
|
20
|
+
|
|
5
21
|
## [16.1.13] - 2026-06-22
|
|
6
22
|
|
|
7
23
|
### Added
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { ModelSpec, ResolvedDevinCompat } from "../types";
|
|
2
|
+
/**
|
|
3
|
+
* Resolve devin-agent (Codeium Cascade) compat. Cascade has no wire
|
|
4
|
+
* reasoning/effort field — effort is selected by routing to a sibling model id
|
|
5
|
+
* (the `thinking.effortRouting` baked by variant-collapse). So the thinking
|
|
6
|
+
* deriver must never fabricate an effort ladder from identity for these models;
|
|
7
|
+
* only explicit routed metadata counts.
|
|
8
|
+
*/
|
|
9
|
+
export declare function buildDevinCompat(_spec: ModelSpec<"devin-agent">): ResolvedDevinCompat;
|
|
@@ -266,6 +266,15 @@ export declare const CATALOG_PROVIDERS: readonly [{
|
|
|
266
266
|
readonly label: "Qwen Portal";
|
|
267
267
|
readonly oauthProvider: "qwen-portal";
|
|
268
268
|
};
|
|
269
|
+
}, {
|
|
270
|
+
readonly id: "sakana";
|
|
271
|
+
readonly defaultModel: "fugu";
|
|
272
|
+
readonly envVars: readonly ["SAKANA_API_KEY", "FUGU_API_KEY"];
|
|
273
|
+
readonly createModelManagerOptions: (config: ModelManagerConfig) => import("..").ModelManagerOptions<"openai-responses", unknown>;
|
|
274
|
+
readonly dynamicModelsAuthoritative: true;
|
|
275
|
+
readonly catalogDiscovery: {
|
|
276
|
+
readonly label: "Sakana AI";
|
|
277
|
+
};
|
|
269
278
|
}, {
|
|
270
279
|
readonly id: "synthetic";
|
|
271
280
|
readonly defaultModel: "hf:zai-org/GLM-5.1";
|
|
@@ -313,6 +313,13 @@ export interface MoonshotModelManagerConfig {
|
|
|
313
313
|
fetch?: FetchImpl;
|
|
314
314
|
}
|
|
315
315
|
export declare function moonshotModelManagerOptions(config?: MoonshotModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
316
|
+
export declare const SAKANA_FUGU_STATIC_MODELS: readonly ModelSpec<"openai-responses">[];
|
|
317
|
+
export interface SakanaModelManagerConfig {
|
|
318
|
+
apiKey?: string;
|
|
319
|
+
baseUrl?: string;
|
|
320
|
+
fetch?: FetchImpl;
|
|
321
|
+
}
|
|
322
|
+
export declare function sakanaModelManagerOptions(config?: SakanaModelManagerConfig): ModelManagerOptions<"openai-responses">;
|
|
316
323
|
export interface QwenPortalModelManagerConfig {
|
|
317
324
|
apiKey?: string;
|
|
318
325
|
baseUrl?: string;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -439,6 +439,7 @@ export interface ResolvedOpenAIResponsesCompat extends ResolvedOpenAISharedCompa
|
|
|
439
439
|
supportsImageDetailOriginal: boolean;
|
|
440
440
|
requiresJuiceZeroHack: boolean;
|
|
441
441
|
supportsObfuscationOptOut: boolean;
|
|
442
|
+
streamIdleTimeoutMs?: number;
|
|
442
443
|
}
|
|
443
444
|
/**
|
|
444
445
|
* OpenRouter is a pseudo API: runtime dispatch can use either Responses
|
|
@@ -456,10 +457,28 @@ export type ResolvedAnthropicCompat = Required<AnthropicCompat> & {
|
|
|
456
457
|
*/
|
|
457
458
|
officialEndpoint: boolean;
|
|
458
459
|
};
|
|
460
|
+
/**
|
|
461
|
+
* Compatibility settings for the devin-agent (Codeium Cascade) API. Cascade
|
|
462
|
+
* selects reasoning effort only by routing to a sibling model id (the
|
|
463
|
+
* `thinking.effortRouting` baked by variant-collapse), never by a wire
|
|
464
|
+
* reasoning/effort field, so the model-thinking deriver must not invent an
|
|
465
|
+
* effort ladder from identity for these models.
|
|
466
|
+
*/
|
|
467
|
+
export interface DevinCompat {
|
|
468
|
+
/**
|
|
469
|
+
* Trust only explicit `thinking` metadata; never derive a thinking surface
|
|
470
|
+
* from model identity. A reasoning model with no explicit routed thinking
|
|
471
|
+
* resolves to `thinking: undefined` (`reasoning: true`, no controllable
|
|
472
|
+
* effort) instead of a fabricated minimal/low/medium/high ladder.
|
|
473
|
+
*/
|
|
474
|
+
trustExplicitThinkingOnly?: boolean;
|
|
475
|
+
}
|
|
476
|
+
/** Fully-resolved devin-agent compat view. */
|
|
477
|
+
export type ResolvedDevinCompat = Required<DevinCompat>;
|
|
459
478
|
/** Sparse, user-authored compat overrides for a given API (models.json / config vocabulary). */
|
|
460
|
-
export type CompatConfigOf<TApi extends Api> = TApi extends "openai-completions" | "openrouter" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" ? OpenAICompat : TApi extends "anthropic-messages" ? AnthropicCompat : undefined;
|
|
479
|
+
export type CompatConfigOf<TApi extends Api> = TApi extends "openai-completions" | "openrouter" | "openai-responses" | "azure-openai-responses" | "openai-codex-responses" ? OpenAICompat : TApi extends "anthropic-messages" ? AnthropicCompat : TApi extends "devin-agent" ? DevinCompat : undefined;
|
|
461
480
|
/** Resolved compat for a given API: complete record, materialized once by `buildModel`. */
|
|
462
|
-
export type CompatOf<TApi extends Api> = TApi extends "openrouter" ? ResolvedOpenRouterCompat : TApi extends "openai-completions" ? ResolvedOpenAICompat : TApi extends "openai-responses" | "azure-openai-responses" | "openai-codex-responses" ? ResolvedOpenAIResponsesCompat : TApi extends "anthropic-messages" ? ResolvedAnthropicCompat : undefined;
|
|
481
|
+
export type CompatOf<TApi extends Api> = TApi extends "openrouter" ? ResolvedOpenRouterCompat : TApi extends "openai-completions" ? ResolvedOpenAICompat : TApi extends "openai-responses" | "azure-openai-responses" | "openai-codex-responses" ? ResolvedOpenAIResponsesCompat : TApi extends "anthropic-messages" ? ResolvedAnthropicCompat : TApi extends "devin-agent" ? ResolvedDevinCompat : undefined;
|
|
463
482
|
export interface Model<TApi extends Api = Api> {
|
|
464
483
|
id: string;
|
|
465
484
|
/**
|
|
@@ -57,6 +57,7 @@ export interface VariantCollapseTable {
|
|
|
57
57
|
export declare const ANTIGRAVITY_VARIANT_COLLAPSE_TABLE: VariantCollapseTable;
|
|
58
58
|
/** `google-gemini-cli` (cloudcode-pa): Gemini 3.x on the level transport (official CLI parity). */
|
|
59
59
|
export declare const GEMINI_CLI_VARIANT_COLLAPSE_TABLE: VariantCollapseTable;
|
|
60
|
+
export declare const DEVIN_VARIANT_COLLAPSE_TABLE: VariantCollapseTable;
|
|
60
61
|
/** Provider id → hand collapse table. The CCA providers diverge on thinking transport. */
|
|
61
62
|
export declare const VARIANT_COLLAPSE_TABLES: Readonly<Record<string, VariantCollapseTable>>;
|
|
62
63
|
/**
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@oh-my-pi/pi-catalog",
|
|
4
|
-
"version": "16.1.
|
|
4
|
+
"version": "16.1.15",
|
|
5
5
|
"description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
|
|
6
6
|
"homepage": "https://omp.sh",
|
|
7
7
|
"author": "Can Boluk",
|
|
@@ -34,12 +34,12 @@
|
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
36
|
"@bufbuild/protobuf": "^2.12.0",
|
|
37
|
-
"@oh-my-pi/pi-utils": "16.1.
|
|
37
|
+
"@oh-my-pi/pi-utils": "16.1.15",
|
|
38
38
|
"arktype": "^2.2.0",
|
|
39
39
|
"zod": "^4"
|
|
40
40
|
},
|
|
41
41
|
"devDependencies": {
|
|
42
|
-
"@oh-my-pi/pi-ai": "16.1.
|
|
42
|
+
"@oh-my-pi/pi-ai": "16.1.15",
|
|
43
43
|
"@types/bun": "^1.3.14"
|
|
44
44
|
},
|
|
45
45
|
"engines": {
|
package/src/build.ts
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
* compat per request.
|
|
11
11
|
*/
|
|
12
12
|
import { buildAnthropicCompat } from "./compat/anthropic";
|
|
13
|
+
import { buildDevinCompat } from "./compat/devin";
|
|
13
14
|
import { buildOpenAICompat, buildOpenAIResponsesCompat, buildOpenRouterCompat } from "./compat/openai";
|
|
14
15
|
import { resolveModelThinking } from "./model-thinking";
|
|
15
16
|
import type { Api, CompatOf, Model, ModelSpec } from "./types";
|
|
@@ -38,6 +39,8 @@ export function buildCompat(spec: ModelSpec<Api>): CompatOf<Api> {
|
|
|
38
39
|
return buildOpenAIResponsesCompat(spec as ModelSpec<"openai-responses">);
|
|
39
40
|
case "anthropic-messages":
|
|
40
41
|
return buildAnthropicCompat(spec as ModelSpec<"anthropic-messages">);
|
|
42
|
+
case "devin-agent":
|
|
43
|
+
return buildDevinCompat(spec as ModelSpec<"devin-agent">);
|
|
41
44
|
default:
|
|
42
45
|
return undefined;
|
|
43
46
|
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ModelSpec, ResolvedDevinCompat } from "../types";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Resolve devin-agent (Codeium Cascade) compat. Cascade has no wire
|
|
5
|
+
* reasoning/effort field — effort is selected by routing to a sibling model id
|
|
6
|
+
* (the `thinking.effortRouting` baked by variant-collapse). So the thinking
|
|
7
|
+
* deriver must never fabricate an effort ladder from identity for these models;
|
|
8
|
+
* only explicit routed metadata counts.
|
|
9
|
+
*/
|
|
10
|
+
export function buildDevinCompat(_spec: ModelSpec<"devin-agent">): ResolvedDevinCompat {
|
|
11
|
+
return { trustExplicitThinkingOnly: true };
|
|
12
|
+
}
|
package/src/compat/openai.ts
CHANGED
|
@@ -535,6 +535,7 @@ export function buildOpenAIResponsesCompat(spec: OpenAIResponsesSpecLike): Resol
|
|
|
535
535
|
emptyLengthFinishIsContextError: spec.provider === "ollama",
|
|
536
536
|
usesOpenAIToolCallIdLimit: spec.provider === "openai",
|
|
537
537
|
promptCacheSessionHeader: spec.provider === "xai-oauth" ? "x-grok-conv-id" : undefined,
|
|
538
|
+
streamIdleTimeoutMs: spec.compat?.streamIdleTimeoutMs,
|
|
538
539
|
};
|
|
539
540
|
applyCompatOverrides(compat, spec.compat);
|
|
540
541
|
if (spec.compat?.reasoningDisableMode === undefined) {
|
package/src/discovery/devin.ts
CHANGED
|
@@ -17,9 +17,8 @@ const DEFAULT_CONTEXT_WINDOW = 200_000;
|
|
|
17
17
|
const DEFAULT_MAX_TOKENS = 64_000;
|
|
18
18
|
|
|
19
19
|
/** Best-effort match for labels whose wording implies a thinking / reasoning-effort variant. */
|
|
20
|
-
const REASONING_LABEL_PATTERN = /think|thinking|high|medium|low|xhigh|reasoning/i;
|
|
20
|
+
const REASONING_LABEL_PATTERN = /think|thinking|minimal|high|medium|low|xhigh|max|reasoning/i;
|
|
21
21
|
const NO_REASONING_LABEL_PATTERN = /\bno thinking\b/i;
|
|
22
|
-
|
|
23
22
|
function supportsDevinThinking(config: ClientModelConfig): boolean {
|
|
24
23
|
if (NO_REASONING_LABEL_PATTERN.test(config.label)) return false;
|
|
25
24
|
return config.modelInfo?.modelFeatures?.supportsThinking === true || REASONING_LABEL_PATTERN.test(config.label);
|
package/src/model-thinking.ts
CHANGED
|
@@ -35,6 +35,7 @@ import type {
|
|
|
35
35
|
CompatOf,
|
|
36
36
|
Model,
|
|
37
37
|
ModelSpec,
|
|
38
|
+
ResolvedDevinCompat,
|
|
38
39
|
ResolvedOpenAICompat,
|
|
39
40
|
ResolvedOpenAIResponsesCompat,
|
|
40
41
|
ThinkingConfig,
|
|
@@ -61,6 +62,10 @@ const GPT_5_1_CODEX_MINI_EFFORTS: readonly Effort[] = [Effort.Medium, Effort.Hig
|
|
|
61
62
|
const LOW_MEDIUM_HIGH_REASONING_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High];
|
|
62
63
|
const GLM_52_HIGH_MAX_REASONING_EFFORTS: readonly Effort[] = [Effort.High, Effort.XHigh];
|
|
63
64
|
|
|
65
|
+
const FUGU_REASONING_EFFORTS: readonly Effort[] = [Effort.High, Effort.XHigh];
|
|
66
|
+
const FUGU_REASONING_EFFORT_MAP: Readonly<EffortMap> = {
|
|
67
|
+
[Effort.XHigh]: "max",
|
|
68
|
+
};
|
|
64
69
|
type EffortMap = Partial<Record<Effort, string>>;
|
|
65
70
|
|
|
66
71
|
const GROQ_QWEN3_32B_REASONING_EFFORT_MAP: Readonly<EffortMap> = {
|
|
@@ -153,6 +158,10 @@ export function resolveModelThinking<TApi extends Api>(
|
|
|
153
158
|
if (spec.thinking && Array.isArray(spec.thinking.efforts) && spec.thinking.efforts.length > 0) {
|
|
154
159
|
return fillThinkingWireDefaults(spec, compat, spec.thinking);
|
|
155
160
|
}
|
|
161
|
+
// Cascade selects effort only by routing to a sibling model id, so a Devin
|
|
162
|
+
// model with no explicit routed thinking has no controllable surface —
|
|
163
|
+
// never fabricate an effort ladder from identity.
|
|
164
|
+
if ((compat as ResolvedDevinCompat | undefined)?.trustExplicitThinkingOnly === true) return undefined;
|
|
156
165
|
// Empty/malformed explicit metadata is treated as absent — infer instead.
|
|
157
166
|
return deriveThinking(spec, compat);
|
|
158
167
|
}
|
|
@@ -301,6 +310,9 @@ function getModelDefinedEfforts<TApi extends Api>(
|
|
|
301
310
|
return GLM_52_HIGH_MAX_REASONING_EFFORTS;
|
|
302
311
|
}
|
|
303
312
|
}
|
|
313
|
+
if (isSakanaFuguReasoningModel(spec)) {
|
|
314
|
+
return FUGU_REASONING_EFFORTS;
|
|
315
|
+
}
|
|
304
316
|
return isOpenAICompatReasoningApi(spec.api) &&
|
|
305
317
|
(isMinimaxM2FamilyModelId(spec.id) ||
|
|
306
318
|
isOpenAIGptOssModelId(spec.id) ||
|
|
@@ -377,6 +389,9 @@ function inferDetectedEffortMap<TApi extends Api>(
|
|
|
377
389
|
if (isOllamaCloudGlm52ReasoningEffortModel(spec)) {
|
|
378
390
|
return GLM_52_XHIGH_MAX_EFFORT_MAP;
|
|
379
391
|
}
|
|
392
|
+
if (isSakanaFuguReasoningModel(spec)) {
|
|
393
|
+
return FUGU_REASONING_EFFORT_MAP;
|
|
394
|
+
}
|
|
380
395
|
if (!isOpenAICompatReasoningApi(spec.api)) {
|
|
381
396
|
return undefined;
|
|
382
397
|
}
|
|
@@ -400,6 +415,10 @@ function inferDetectedEffortMap<TApi extends Api>(
|
|
|
400
415
|
return map;
|
|
401
416
|
}
|
|
402
417
|
|
|
418
|
+
function isSakanaFuguReasoningModel<TApi extends Api>(spec: ModelSpec<TApi>): boolean {
|
|
419
|
+
return spec.provider === "sakana" && /^fugu(?:$|-)/i.test(spec.id);
|
|
420
|
+
}
|
|
421
|
+
|
|
403
422
|
function isDeepseekReasoningModel<TApi extends Api>(spec: ModelSpec<TApi>): boolean {
|
|
404
423
|
if (!spec.reasoning) return false;
|
|
405
424
|
const lowerId = spec.id.toLowerCase();
|