@linxiraos/pi-catalog 1.1.4 → 1.1.6
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 +5 -3
- package/dist/types/identity/family.d.ts +15 -11
- package/dist/types/model-manager.d.ts +20 -4
- package/dist/types/provider-models/descriptors.d.ts +20 -1
- package/dist/types/provider-models/models-dev-policies.d.ts +8 -0
- package/dist/types/provider-models/openai-compat.d.ts +56 -4
- package/dist/types/types.d.ts +2 -2
- package/dist/types/wire/cloudflare-ai-gateway.d.ts +18 -0
- package/package.json +5 -5
- package/src/compat/openai.ts +2 -0
- package/src/identity/family.ts +43 -24
- package/src/identity/priority.ts +1 -0
- package/src/model-manager.ts +121 -72
- package/src/model-thinking.ts +19 -0
- package/src/models.json +8777 -1081
- package/src/provider-models/cache-provider-id.ts +4 -1
- package/src/provider-models/descriptors.ts +19 -1
- package/src/provider-models/models-dev-policies.ts +38 -0
- package/src/provider-models/openai-compat.ts +488 -66
- package/src/types.ts +10 -2
- package/src/variant-collapse.ts +1 -1
- package/src/wire/cloudflare-ai-gateway.ts +44 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,11 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
## [Unreleased]
|
|
4
4
|
|
|
5
|
-
## [1.1.
|
|
5
|
+
## [1.1.6] - 2026-08-30
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
- 同步上游 OMP v18.0.9(`cc14e04f075d`)。
|
|
8
|
+
|
|
9
|
+
## [1.1.5] - 2026-08-26
|
|
8
10
|
|
|
9
|
-
-
|
|
11
|
+
- 同步上游 OMP v18.0.5 / v18.0.6:新增 DeepInfra / Yolo-Auto 提供商标识。
|
|
10
12
|
|
|
11
13
|
## [1.1.3] - 2026-08-25
|
|
12
14
|
|
|
@@ -145,24 +145,28 @@ export declare const supportsCodexReasoningSummary: (modelId: string) => boolean
|
|
|
145
145
|
export declare const isOpenAISamplingRestrictedModelId: (modelId: string) => boolean;
|
|
146
146
|
/**
|
|
147
147
|
* Reasoning-capable GLM coding SKUs: glm-4.5 and up on the base / `-air` /
|
|
148
|
-
* `-turbo` lines
|
|
149
|
-
* `-
|
|
150
|
-
* keeps newly-bumped integers (`glm-5.
|
|
151
|
-
* allowlist.
|
|
148
|
+
* `-turbo` lines, plus `-flash` from GLM-5.3-Flash on. Excludes the vision
|
|
149
|
+
* (`…v`) shape, the non-reasoning `-flashx`/`-preview` variants, and pre-4.5
|
|
150
|
+
* ids. Matching the family keeps newly-bumped integers (`glm-5.4`, `glm-6`, …)
|
|
151
|
+
* covered without a per-id allowlist.
|
|
152
152
|
*/
|
|
153
153
|
export declare const isReasoningGlmModelId: (modelId: string) => boolean;
|
|
154
154
|
/** GLM-5.2+ coding SKUs accept `reasoning_effort` in addition to binary thinking. */
|
|
155
155
|
export declare const isGlm52ReasoningEffortModelId: (modelId: string) => boolean;
|
|
156
156
|
/**
|
|
157
|
-
* GLM-5.3+
|
|
158
|
-
* host-specific),
|
|
159
|
-
* ladder on every host, and thinking can
|
|
160
|
-
* `thinking.type` must always be `enabled`. Matching
|
|
161
|
-
* bumps (`glm-5.4`, `glm-6`, …) covered while excluding
|
|
162
|
-
* shape and the non-reasoning `-
|
|
157
|
+
* GLM-5.3+ reasoning-effort SKUs. Unlike GLM-5.2 (whose dialect is
|
|
158
|
+
* host-specific), the base, `-air`, `-turbo`, and `-flash` variants expose a
|
|
159
|
+
* uniform wire-exact `low`/`high`/`max` ladder on every host, and thinking can
|
|
160
|
+
* no longer be disabled — `thinking.type` must always be `enabled`. Matching
|
|
161
|
+
* the family keeps future bumps (`glm-5.4`, `glm-6`, …) covered while excluding
|
|
162
|
+
* the vision (`…v`) shape and the non-reasoning `-flashx`/`-preview` variants.
|
|
163
163
|
*/
|
|
164
164
|
export declare const isGlm53ReasoningEffortModelId: (modelId: string) => boolean;
|
|
165
|
-
/**
|
|
165
|
+
/**
|
|
166
|
+
* GLM SKUs that accept image input: the `v` that attaches to the version
|
|
167
|
+
* (`glm-4v`, `glm-4.5v`) and the natively multimodal `-flash` line from
|
|
168
|
+
* GLM-5.3-Flash on, whose id carries no `v` marker.
|
|
169
|
+
*/
|
|
166
170
|
export declare const isGlmVisionModelId: (modelId: string) => boolean;
|
|
167
171
|
/**
|
|
168
172
|
* Coarse vendor-lineage token for "are two models the same family?" checks
|
|
@@ -11,6 +11,8 @@ export interface ModelsDevFallback<TApi extends Api = Api, TPayload = unknown> {
|
|
|
11
11
|
fetch(): Promise<TPayload>;
|
|
12
12
|
/** Maps payload into provider models. */
|
|
13
13
|
map(payload: TPayload, providerId: Provider): readonly ModelSpec<TApi>[];
|
|
14
|
+
/** When true, mapped rows can add model ids but cannot replace static metadata. */
|
|
15
|
+
additiveOnly?: boolean;
|
|
14
16
|
}
|
|
15
17
|
/**
|
|
16
18
|
* Configuration for provider model resolution.
|
|
@@ -45,18 +47,25 @@ export interface ModelManagerOptions<TApi extends Api = Api, TModelsDevPayload =
|
|
|
45
47
|
/** Clock override for deterministic tests. */
|
|
46
48
|
now?: () => number;
|
|
47
49
|
}
|
|
50
|
+
/**
|
|
51
|
+
* Catalog source that most recently refreshed the resolved provider snapshot.
|
|
52
|
+
*/
|
|
53
|
+
export type ModelResolutionSource = "bundled" | "cache" | "models.dev" | "provider";
|
|
48
54
|
/**
|
|
49
55
|
* Resolution result.
|
|
50
56
|
*
|
|
51
57
|
* `stale` is false when the resolved catalog is authoritative for the selected provider:
|
|
52
|
-
* - a
|
|
58
|
+
* - a provider endpoint fetch succeeded in this call (an empty catalog is still
|
|
53
59
|
* authoritative for the cycle, so downstream pruning of removed models runs),
|
|
60
|
+
* - a models.dev fetch succeeded for a provider without endpoint discovery,
|
|
54
61
|
* - a still-fresh authoritative cache was reused in `online-if-uncached` mode, or
|
|
55
|
-
* - the provider has no
|
|
62
|
+
* - the provider has no remote fetcher configured.
|
|
56
63
|
*/
|
|
57
64
|
export interface ModelResolutionResult<TApi extends Api = Api> {
|
|
58
65
|
models: Model<TApi>[];
|
|
59
66
|
stale: boolean;
|
|
67
|
+
source: ModelResolutionSource;
|
|
68
|
+
updatedAt?: number;
|
|
60
69
|
}
|
|
61
70
|
/**
|
|
62
71
|
* Stateful facade over provider model resolution.
|
|
@@ -70,8 +79,15 @@ export interface ModelManager<TApi extends Api = Api> {
|
|
|
70
79
|
export declare function createModelManager<TApi extends Api = Api, TModelsDevPayload = unknown>(options: ModelManagerOptions<TApi, TModelsDevPayload>): ModelManager<TApi>;
|
|
71
80
|
/**
|
|
72
81
|
* Resolves provider models with source precedence:
|
|
73
|
-
* static -> stencil.so ->
|
|
82
|
+
* static -> cached fallback -> stencil.so -> dynamic.
|
|
74
83
|
*
|
|
75
|
-
* Later sources override earlier ones by model id.
|
|
84
|
+
* Later sources override earlier ones by model id. Cached rows participate only
|
|
85
|
+
* when at least one configured remote source did not refresh successfully.
|
|
76
86
|
*/
|
|
77
87
|
export declare function resolveProviderModels<TApi extends Api = Api, TModelsDevPayload = unknown>(options: ModelManagerOptions<TApi, TModelsDevPayload>, strategy?: ModelRefreshStrategy): Promise<ModelResolutionResult<TApi>>;
|
|
88
|
+
/**
|
|
89
|
+
* Return the versioned, low-collision model-cache identity for a static provider
|
|
90
|
+
* slice. Results are cached by array reference so repeat cold-start paths skip
|
|
91
|
+
* the JSON serialization and hash.
|
|
92
|
+
*/
|
|
93
|
+
export declare function fingerprintStaticModels<TApi extends Api>(models: readonly (ModelSpec<TApi> | Model<TApi>)[], dynamicModelsAuthoritative?: boolean): string;
|
|
@@ -97,6 +97,16 @@ export declare const CATALOG_PROVIDERS: readonly [{
|
|
|
97
97
|
readonly envVars: readonly ["CURSOR_API_KEY"];
|
|
98
98
|
readonly oauthProvider: "cursor";
|
|
99
99
|
};
|
|
100
|
+
}, {
|
|
101
|
+
readonly id: "deepinfra";
|
|
102
|
+
readonly defaultModel: "deepseek-ai/DeepSeek-V4-Flash-0731";
|
|
103
|
+
readonly envVars: readonly ["DEEPINFRA_API_KEY"];
|
|
104
|
+
readonly createModelManagerOptions: (config: ModelManagerConfig) => import("../index.js").ModelManagerOptions<"openai-completions", unknown>;
|
|
105
|
+
readonly dynamicModelsAuthoritative: true;
|
|
106
|
+
readonly catalogDiscovery: {
|
|
107
|
+
readonly label: "DeepInfra";
|
|
108
|
+
readonly allowUnauthenticated: true;
|
|
109
|
+
};
|
|
100
110
|
}, {
|
|
101
111
|
readonly id: "deepseek";
|
|
102
112
|
readonly defaultModel: "deepseek-v4-pro";
|
|
@@ -361,7 +371,7 @@ export declare const CATALOG_PROVIDERS: readonly [{
|
|
|
361
371
|
readonly dynamicModelsAuthoritative: true;
|
|
362
372
|
}, {
|
|
363
373
|
readonly id: "synthetic";
|
|
364
|
-
readonly defaultModel: "hf:zai-org/GLM-5.
|
|
374
|
+
readonly defaultModel: "hf:zai-org/GLM-5.2";
|
|
365
375
|
readonly envVars: readonly ["SYNTHETIC_API_KEY"];
|
|
366
376
|
readonly createModelManagerOptions: (config: ModelManagerConfig) => import("../index.js").ModelManagerOptions<"openai-completions", unknown>;
|
|
367
377
|
readonly dynamicModelsAuthoritative: true;
|
|
@@ -469,6 +479,15 @@ export declare const CATALOG_PROVIDERS: readonly [{
|
|
|
469
479
|
readonly defaultModel: "mimo-v2.5";
|
|
470
480
|
readonly envVars: readonly ["XIAOMI_TOKEN_PLAN_SGP_API_KEY"];
|
|
471
481
|
readonly createModelManagerOptions: (config: ModelManagerConfig) => import("../index.js").ModelManagerOptions<"openai-completions", unknown>;
|
|
482
|
+
}, {
|
|
483
|
+
readonly id: "yolo-auto";
|
|
484
|
+
readonly defaultModel: "deepseek-flash-v4";
|
|
485
|
+
readonly envVars: readonly ["YOLO_AUTO_API_KEY"];
|
|
486
|
+
readonly createModelManagerOptions: (config: ModelManagerConfig) => import("../index.js").ModelManagerOptions<"openai-completions", unknown>;
|
|
487
|
+
readonly dynamicModelsAuthoritative: true;
|
|
488
|
+
readonly catalogDiscovery: {
|
|
489
|
+
readonly label: "Yolo-Auto";
|
|
490
|
+
};
|
|
472
491
|
}, {
|
|
473
492
|
readonly id: "zai";
|
|
474
493
|
readonly defaultModel: "glm-5.3";
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { Api, ModelSpec } from "../types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Remove models.dev rows that OMP cannot route successfully.
|
|
4
|
+
*
|
|
5
|
+
* Generation and runtime refresh share this policy so a live catalog cannot
|
|
6
|
+
* reintroduce selectors deliberately excluded from the bundled catalog.
|
|
7
|
+
*/
|
|
8
|
+
export declare function filterModelsDevCatalogRows<TApi extends Api>(models: readonly ModelSpec<TApi>[]): ModelSpec<TApi>[];
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { ModelManagerOptions } from "../model-manager.js";
|
|
1
|
+
import type { ModelManagerOptions, ModelsDevFallback } from "../model-manager.js";
|
|
2
2
|
import { getBundledModels } from "../models.js";
|
|
3
3
|
import type { Api, FetchImpl, ModelSpec, Provider } from "../types.js";
|
|
4
4
|
import { ALIBABA_TOKEN_PLAN_BASE_URL } from "../wire/alibaba-token-plan.js";
|
|
@@ -32,9 +32,12 @@ export interface ModelsDevModel {
|
|
|
32
32
|
* The frame magic is sniffed rather than trusting content-type so plain-JSON
|
|
33
33
|
* responses (test stubs, fallback mirrors) parse identically.
|
|
34
34
|
*
|
|
35
|
-
* Fetched fully once per
|
|
36
|
-
* request, repeat callers send a
|
|
37
|
-
*
|
|
35
|
+
* Fetched fully once per fetch context: concurrent callers sharing a fetch
|
|
36
|
+
* implementation reuse one transport request, while repeat callers send a
|
|
37
|
+
* conditional GET that the server answers with `304`. Each subscriber may stop
|
|
38
|
+
* waiting independently; the shared transport retains its own hard deadline.
|
|
39
|
+
* Transient failures reuse the last in-memory payload for callers that only
|
|
40
|
+
* need best-effort metadata.
|
|
38
41
|
*/
|
|
39
42
|
export declare function fetchWellKnownModels(fetchImpl?: FetchImpl, signal?: AbortSignal): Promise<unknown>;
|
|
40
43
|
/**
|
|
@@ -161,6 +164,19 @@ export interface NovitaModelManagerConfig {
|
|
|
161
164
|
}
|
|
162
165
|
/** Builds Novita's public model-discovery manager. */
|
|
163
166
|
export declare function novitaModelManagerOptions(config?: NovitaModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
167
|
+
export declare const DEEPINFRA_BASE_URL = "https://api.deepinfra.com/v1/openai";
|
|
168
|
+
/** DeepInfra OpenAI-compatible discovery configuration. */
|
|
169
|
+
export interface DeepinfraModelManagerConfig {
|
|
170
|
+
apiKey?: string;
|
|
171
|
+
baseUrl?: string;
|
|
172
|
+
fetch?: FetchImpl;
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Builds DeepInfra's model-discovery manager. The catalog endpoint is public,
|
|
176
|
+
* so discovery (and keyless `gen:models` generation) works without an API key;
|
|
177
|
+
* model availability at runtime is still gated on credentials by the registry.
|
|
178
|
+
*/
|
|
179
|
+
export declare function deepinfraModelManagerOptions(config?: DeepinfraModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
164
180
|
export interface XaiModelManagerConfig {
|
|
165
181
|
apiKey?: string;
|
|
166
182
|
baseUrl?: string;
|
|
@@ -528,6 +544,29 @@ export interface AiandModelManagerConfig {
|
|
|
528
544
|
* pricing metadata, so discovery is authoritative over the bundled seed.
|
|
529
545
|
*/
|
|
530
546
|
export declare function aiandModelManagerOptions(config?: AiandModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
547
|
+
/**
|
|
548
|
+
* Documented Yolo-Auto catalog (yolo-auto.com/docs, 2026-08) bundled so the
|
|
549
|
+
* provider is usable when generation and first boot have no live key. The
|
|
550
|
+
* flat-rate `/v1/models` response is authoritative once discovery runs.
|
|
551
|
+
* The compat block mirrors the provider's documented wire surface: the API
|
|
552
|
+
* speaks the generic chat template with `reasoning_effort` support and rejects
|
|
553
|
+
* the `developer` role and `store` param.
|
|
554
|
+
*/
|
|
555
|
+
export declare const YOLO_AUTO_STATIC_MODELS: readonly ModelSpec<"openai-completions">[];
|
|
556
|
+
export interface YoloAutoModelManagerConfig {
|
|
557
|
+
apiKey?: string;
|
|
558
|
+
baseUrl?: string;
|
|
559
|
+
fetch?: FetchImpl;
|
|
560
|
+
}
|
|
561
|
+
/**
|
|
562
|
+
* Yolo-Auto model manager: OpenAI-compatible chat completions at the
|
|
563
|
+
* flat-rate `deepseek-flash-v4` endpoint. Live `/v1/models` discovery replaces the
|
|
564
|
+
* bundled seed once a key is stored or present in `YOLO_AUTO_API_KEY`. Models
|
|
565
|
+
* the provider adds later inherit metadata (reasoning, thinking, context)
|
|
566
|
+
* from the global bundled reference index, so new ids work without a per-id
|
|
567
|
+
* code change.
|
|
568
|
+
*/
|
|
569
|
+
export declare function yoloAutoModelManagerOptions(config?: YoloAutoModelManagerConfig): ModelManagerOptions<"openai-completions">;
|
|
531
570
|
export interface QwenPortalModelManagerConfig {
|
|
532
571
|
apiKey?: string;
|
|
533
572
|
baseUrl?: string;
|
|
@@ -649,3 +688,16 @@ export interface ModelsDevProviderDescriptor {
|
|
|
649
688
|
export declare function mapModelsDevToModels(data: Record<string, unknown>, descriptors: readonly ModelsDevProviderDescriptor[]): ModelSpec<Api>[];
|
|
650
689
|
/** All provider descriptors for models.dev data mapping in generate-models.ts. */
|
|
651
690
|
export declare const MODELS_DEV_PROVIDER_DESCRIPTORS: readonly ModelsDevProviderDescriptor[];
|
|
691
|
+
/** Providers whose bundled catalog can receive additive models.dev updates at runtime. */
|
|
692
|
+
export declare const MODELS_DEV_CATALOG_PROVIDER_IDS: readonly string[];
|
|
693
|
+
/**
|
|
694
|
+
* Build the shared models.dev fallback for one known provider.
|
|
695
|
+
*
|
|
696
|
+
* Provider managers sharing one fetch implementation reuse its conditional
|
|
697
|
+
* catalog session. Each mapped provider slice is persisted independently so
|
|
698
|
+
* startup can restore it without parsing the full catalog.
|
|
699
|
+
*
|
|
700
|
+
* `timeoutMs` bounds the catalog request. It is configurable for callers with a
|
|
701
|
+
* stricter startup budget and for deterministic timeout tests.
|
|
702
|
+
*/
|
|
703
|
+
export declare function modelsDevCatalogFallback(providerId: string, fetchImpl?: FetchImpl, timeoutMs?: number): ModelsDevFallback<Api> | undefined;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -121,8 +121,8 @@ export interface Usage {
|
|
|
121
121
|
total: number;
|
|
122
122
|
};
|
|
123
123
|
}
|
|
124
|
-
export type OpenAIReasoningFormat = "openai" | "openrouter" | "zai" | "kimi" | "qwen" | "qwen-chat-template";
|
|
125
|
-
export type OpenAIReasoningDisableMode = "omit" | "lowest-effort" | "none-effort" | "openrouter-enabled-false" | "venice-disable-thinking" | "zai-thinking-disabled" | "qwen-enable-thinking-false" | "qwen-template-false";
|
|
124
|
+
export type OpenAIReasoningFormat = "openai" | "openrouter" | "zai" | "kimi" | "qwen" | "qwen-chat-template" | "chat-template";
|
|
125
|
+
export type OpenAIReasoningDisableMode = "omit" | "lowest-effort" | "none-effort" | "openrouter-enabled-false" | "venice-disable-thinking" | "zai-thinking-disabled" | "qwen-enable-thinking-false" | "qwen-template-false" | "chat-template-thinking-false";
|
|
126
126
|
export type OpenAIStreamMarkupHealingPattern = "kimi" | "dsml" | "qwen" | "thinking";
|
|
127
127
|
/**
|
|
128
128
|
* Compatibility settings for openai-completions API.
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/** Provider-native AI Gateway prefix before the upstream route segment. */
|
|
2
|
+
export declare const CLOUDFLARE_AI_GATEWAY_BASE_URL = "https://gateway.ai.cloudflare.com/v1/<account>/<gateway>";
|
|
3
|
+
/** Anthropic Messages passthrough endpoint. */
|
|
4
|
+
export declare const CLOUDFLARE_AI_GATEWAY_ANTHROPIC_BASE_URL = "https://gateway.ai.cloudflare.com/v1/<account>/<gateway>/anthropic";
|
|
5
|
+
/** OpenAI Responses passthrough endpoint. */
|
|
6
|
+
export declare const CLOUDFLARE_AI_GATEWAY_OPENAI_BASE_URL = "https://gateway.ai.cloudflare.com/v1/<account>/<gateway>/openai";
|
|
7
|
+
/** OpenAI-compatible Workers AI endpoint. */
|
|
8
|
+
export declare const CLOUDFLARE_AI_GATEWAY_COMPAT_BASE_URL = "https://gateway.ai.cloudflare.com/v1/<account>/<gateway>/compat";
|
|
9
|
+
/** Opaque API-key credential payload persisted by Cloudflare AI Gateway login. */
|
|
10
|
+
export interface CloudflareAiGatewayCredential {
|
|
11
|
+
token: string;
|
|
12
|
+
accountId?: string;
|
|
13
|
+
gatewayId?: string;
|
|
14
|
+
}
|
|
15
|
+
/** Parse both structured login credentials and legacy plain gateway tokens. */
|
|
16
|
+
export declare function parseCloudflareAiGatewayCredential(value: string): CloudflareAiGatewayCredential | null;
|
|
17
|
+
/** Serialize the gateway token with the routing identifiers collected during login. */
|
|
18
|
+
export declare function serializeCloudflareAiGatewayCredential(token: string, accountId: string, gatewayId: string): string;
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"type": "module",
|
|
3
3
|
"name": "@linxiraos/pi-catalog",
|
|
4
|
-
"version": "1.1.
|
|
5
|
-
"description": "Model catalog for
|
|
4
|
+
"version": "1.1.6",
|
|
5
|
+
"description": "Model catalog for omp: bundled model database, provider discovery descriptors, model identity, classification, and equivalence",
|
|
6
6
|
"homepage": "https://linxira-os.github.io/zeta/",
|
|
7
7
|
"author": "Can Boluk",
|
|
8
8
|
"license": "MIT",
|
|
@@ -34,11 +34,11 @@
|
|
|
34
34
|
"gen:proto": "bun scripts/generate-protocols.ts"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@linxiraos/pi-omptype": "1.1.
|
|
38
|
-
"@linxiraos/pi-utils": "1.1.
|
|
37
|
+
"@linxiraos/pi-omptype": "1.1.6",
|
|
38
|
+
"@linxiraos/pi-utils": "1.1.6"
|
|
39
39
|
},
|
|
40
40
|
"devDependencies": {
|
|
41
|
-
"@linxiraos/pi-ai": "1.1.
|
|
41
|
+
"@linxiraos/pi-ai": "1.1.6",
|
|
42
42
|
"@types/bun": "^1.3.14"
|
|
43
43
|
},
|
|
44
44
|
"engines": {
|
package/src/compat/openai.ts
CHANGED
package/src/identity/family.ts
CHANGED
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
|
|
10
10
|
import {
|
|
11
11
|
bareModelId,
|
|
12
|
+
type GlmModel,
|
|
12
13
|
isAnthropicAdaptiveGenAtLeast,
|
|
13
14
|
isFableOrMythos,
|
|
14
15
|
parseAnthropicModel,
|
|
@@ -283,19 +284,35 @@ export const isOpenAISamplingRestrictedModelId = memo((modelId: string): boolean
|
|
|
283
284
|
return isOpenAIWireGen5Plus(modelId) || O_SERIES_REASONING_RE.test(bare);
|
|
284
285
|
});
|
|
285
286
|
|
|
287
|
+
/**
|
|
288
|
+
* GLM SKU shapes that carry the reasoning ladders. `base`/`air`/`turbo` have
|
|
289
|
+
* always been reasoning lines; `flash` joins at GLM-5.3-Flash, the first flash
|
|
290
|
+
* SKU whose thinking is mandatory (pre-5.3 `-flash` SKUs are non-reasoning).
|
|
291
|
+
* `flashx` and `preview` stay out.
|
|
292
|
+
*/
|
|
293
|
+
function isGlmReasoningVariant(glm: GlmModel): boolean {
|
|
294
|
+
switch (glm.variant) {
|
|
295
|
+
case "base":
|
|
296
|
+
case "air":
|
|
297
|
+
case "turbo":
|
|
298
|
+
return true;
|
|
299
|
+
case "flash":
|
|
300
|
+
return semverGte(glm.version, "5.3");
|
|
301
|
+
default:
|
|
302
|
+
return false;
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
286
306
|
/**
|
|
287
307
|
* Reasoning-capable GLM coding SKUs: glm-4.5 and up on the base / `-air` /
|
|
288
|
-
* `-turbo` lines
|
|
289
|
-
* `-
|
|
290
|
-
* keeps newly-bumped integers (`glm-5.
|
|
291
|
-
* allowlist.
|
|
308
|
+
* `-turbo` lines, plus `-flash` from GLM-5.3-Flash on. Excludes the vision
|
|
309
|
+
* (`…v`) shape, the non-reasoning `-flashx`/`-preview` variants, and pre-4.5
|
|
310
|
+
* ids. Matching the family keeps newly-bumped integers (`glm-5.4`, `glm-6`, …)
|
|
311
|
+
* covered without a per-id allowlist.
|
|
292
312
|
*/
|
|
293
313
|
export const isReasoningGlmModelId = memo((modelId: string): boolean => {
|
|
294
314
|
const glm = parseGlmModel(bareModelId(modelId));
|
|
295
|
-
if (!glm || glm.vision) {
|
|
296
|
-
return false;
|
|
297
|
-
}
|
|
298
|
-
if (glm.variant !== "base" && glm.variant !== "air" && glm.variant !== "turbo") {
|
|
315
|
+
if (!glm || glm.vision || !isGlmReasoningVariant(glm)) {
|
|
299
316
|
return false;
|
|
300
317
|
}
|
|
301
318
|
return semverGte(glm.version, "4.5");
|
|
@@ -304,37 +321,39 @@ export const isReasoningGlmModelId = memo((modelId: string): boolean => {
|
|
|
304
321
|
/** GLM-5.2+ coding SKUs accept `reasoning_effort` in addition to binary thinking. */
|
|
305
322
|
export const isGlm52ReasoningEffortModelId = memo((modelId: string): boolean => {
|
|
306
323
|
const glm = parseGlmModel(bareModelId(modelId));
|
|
307
|
-
if (!glm || glm.vision) {
|
|
308
|
-
return false;
|
|
309
|
-
}
|
|
310
|
-
if (glm.variant !== "base" && glm.variant !== "air" && glm.variant !== "turbo") {
|
|
324
|
+
if (!glm || glm.vision || !isGlmReasoningVariant(glm)) {
|
|
311
325
|
return false;
|
|
312
326
|
}
|
|
313
327
|
return semverGte(glm.version, "5.2");
|
|
314
328
|
});
|
|
315
329
|
|
|
316
330
|
/**
|
|
317
|
-
* GLM-5.3+
|
|
318
|
-
* host-specific),
|
|
319
|
-
* ladder on every host, and thinking can
|
|
320
|
-
* `thinking.type` must always be `enabled`. Matching
|
|
321
|
-
* bumps (`glm-5.4`, `glm-6`, …) covered while excluding
|
|
322
|
-
* shape and the non-reasoning `-
|
|
331
|
+
* GLM-5.3+ reasoning-effort SKUs. Unlike GLM-5.2 (whose dialect is
|
|
332
|
+
* host-specific), the base, `-air`, `-turbo`, and `-flash` variants expose a
|
|
333
|
+
* uniform wire-exact `low`/`high`/`max` ladder on every host, and thinking can
|
|
334
|
+
* no longer be disabled — `thinking.type` must always be `enabled`. Matching
|
|
335
|
+
* the family keeps future bumps (`glm-5.4`, `glm-6`, …) covered while excluding
|
|
336
|
+
* the vision (`…v`) shape and the non-reasoning `-flashx`/`-preview` variants.
|
|
323
337
|
*/
|
|
324
338
|
export const isGlm53ReasoningEffortModelId = memo((modelId: string): boolean => {
|
|
325
339
|
const glm = parseGlmModel(bareModelId(modelId));
|
|
326
|
-
if (!glm || glm.vision) {
|
|
327
|
-
return false;
|
|
328
|
-
}
|
|
329
|
-
if (glm.variant !== "base" && glm.variant !== "air" && glm.variant !== "turbo") {
|
|
340
|
+
if (!glm || glm.vision || !isGlmReasoningVariant(glm)) {
|
|
330
341
|
return false;
|
|
331
342
|
}
|
|
332
343
|
return semverGte(glm.version, "5.3");
|
|
333
344
|
});
|
|
334
345
|
|
|
335
|
-
/**
|
|
346
|
+
/**
|
|
347
|
+
* GLM SKUs that accept image input: the `v` that attaches to the version
|
|
348
|
+
* (`glm-4v`, `glm-4.5v`) and the natively multimodal `-flash` line from
|
|
349
|
+
* GLM-5.3-Flash on, whose id carries no `v` marker.
|
|
350
|
+
*/
|
|
336
351
|
export const isGlmVisionModelId = memo((modelId: string): boolean => {
|
|
337
|
-
|
|
352
|
+
const glm = parseGlmModel(bareModelId(modelId));
|
|
353
|
+
if (!glm) {
|
|
354
|
+
return false;
|
|
355
|
+
}
|
|
356
|
+
return glm.vision || (glm.variant === "flash" && semverGte(glm.version, "5.3"));
|
|
338
357
|
});
|
|
339
358
|
|
|
340
359
|
/**
|