@gajae-code/ai 0.13.2 → 0.14.0
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 +61 -2
- package/dist/types/auth-broker/client.d.ts +9 -1
- package/dist/types/auth-broker/redact.d.ts +7 -0
- package/dist/types/auth-broker/remote-store.d.ts +50 -9
- package/dist/types/auth-broker/types.d.ts +14 -0
- package/dist/types/auth-broker/wire-schemas.d.ts +25 -0
- package/dist/types/auth-storage.d.ts +200 -6
- package/dist/types/core.d.ts +1 -0
- package/dist/types/model-cache.d.ts +4 -1
- package/dist/types/model-manager.d.ts +11 -0
- package/dist/types/provider-models/openai-compat.d.ts +5 -0
- package/dist/types/provider-models/special.d.ts +3 -0
- package/dist/types/providers/anthropic.d.ts +31 -0
- package/dist/types/providers/cursor.d.ts +9 -1
- package/dist/types/providers/kiro-codewhisperer.d.ts +8 -0
- package/dist/types/providers/mock.d.ts +8 -0
- package/dist/types/providers/register-builtins.d.ts +1 -0
- package/dist/types/providers/transform-messages.d.ts +18 -0
- package/dist/types/types.d.ts +34 -8
- package/dist/types/usage/grok-cli.d.ts +5 -0
- package/dist/types/usage.d.ts +6 -0
- package/dist/types/utils/discovery/openai-compatible.d.ts +5 -0
- package/dist/types/utils/event-stream.d.ts +4 -2
- package/dist/types/utils/fallback-transport.d.ts +10 -0
- package/dist/types/utils/http-inspector.d.ts +1 -0
- package/dist/types/utils/idle-iterator.d.ts +13 -1
- package/dist/types/utils/json-parse.d.ts +19 -0
- package/dist/types/utils/oauth/callback-server.d.ts +13 -0
- package/dist/types/utils/oauth/kiro.d.ts +71 -0
- package/dist/types/utils/oauth/types.d.ts +1 -1
- package/dist/types/utils/parse-bind.d.ts +8 -5
- package/dist/types/utils/tool-call-healing.d.ts +7 -0
- package/dist/types/utils/tool-choice-capability.d.ts +11 -0
- package/package.json +3 -2
- package/src/auth-broker/client.ts +30 -0
- package/src/auth-broker/redact.ts +15 -0
- package/src/auth-broker/refresher.ts +4 -2
- package/src/auth-broker/remote-store.ts +693 -70
- package/src/auth-broker/server.ts +57 -12
- package/src/auth-broker/types.ts +16 -0
- package/src/auth-broker/wire-schemas.ts +21 -0
- package/src/auth-gateway/server.ts +84 -19
- package/src/auth-storage.ts +985 -41
- package/src/core.ts +1 -0
- package/src/model-cache.ts +23 -4
- package/src/model-manager.ts +70 -11
- package/src/model-thinking.ts +45 -1
- package/src/models.json +9604 -1932
- package/src/openai-completions-compat.ts +2 -1
- package/src/provider-models/descriptors.ts +7 -1
- package/src/provider-models/openai-compat.ts +52 -28
- package/src/provider-models/special.ts +12 -0
- package/src/providers/amazon-bedrock.ts +2 -1
- package/src/providers/anthropic.ts +831 -27
- package/src/providers/cursor.ts +83 -3
- package/src/providers/kiro-codewhisperer.ts +572 -0
- package/src/providers/mock.ts +15 -2
- package/src/providers/ollama.ts +9 -2
- package/src/providers/openai-codex-responses.ts +16 -9
- package/src/providers/openai-completions.ts +6 -1
- package/src/providers/openai-responses-shared.ts +180 -18
- package/src/providers/register-builtins.ts +24 -2
- package/src/providers/transform-messages.ts +64 -1
- package/src/stream.ts +25 -2
- package/src/types.ts +36 -7
- package/src/usage/grok-cli.ts +86 -1
- package/src/usage.ts +7 -0
- package/src/utils/discovery/openai-compatible.ts +89 -4
- package/src/utils/event-stream.ts +11 -2
- package/src/utils/fallback-transport.ts +44 -2
- package/src/utils/http-inspector.ts +1 -0
- package/src/utils/idle-iterator.ts +29 -6
- package/src/utils/json-parse.ts +80 -0
- package/src/utils/oauth/callback-server.ts +31 -1
- package/src/utils/oauth/index.ts +14 -1
- package/src/utils/oauth/kiro.ts +448 -0
- package/src/utils/oauth/synthetic.ts +2 -3
- package/src/utils/oauth/types.ts +1 -0
- package/src/utils/parse-bind.ts +27 -0
- package/src/utils/tool-call-healing.ts +13 -2
- package/src/utils/tool-choice-capability.ts +386 -6
package/src/core.ts
CHANGED
|
@@ -23,6 +23,7 @@ export {
|
|
|
23
23
|
PROVIDER_RUNTIME_DESCRIPTORS,
|
|
24
24
|
type ProviderRuntimeDescriptor,
|
|
25
25
|
} from "./providers/register-builtins";
|
|
26
|
+
export { hasAdjacentPrivateThinkingBlocks } from "./providers/transform-messages";
|
|
26
27
|
export * from "./rate-limit-utils";
|
|
27
28
|
export * from "./stream";
|
|
28
29
|
export * from "./types";
|
package/src/model-cache.ts
CHANGED
|
@@ -6,7 +6,7 @@ import { Database } from "bun:sqlite";
|
|
|
6
6
|
import { getModelDbPath } from "@gajae-code/utils/dirs";
|
|
7
7
|
import type { Api, Model } from "./types";
|
|
8
8
|
|
|
9
|
-
const CACHE_SCHEMA_VERSION =
|
|
9
|
+
const CACHE_SCHEMA_VERSION = 5;
|
|
10
10
|
|
|
11
11
|
interface CacheRow {
|
|
12
12
|
provider_id: string;
|
|
@@ -14,6 +14,8 @@ interface CacheRow {
|
|
|
14
14
|
updated_at: number;
|
|
15
15
|
authoritative: number;
|
|
16
16
|
static_fingerprint: string;
|
|
17
|
+
dynamic_model_ids: string | null;
|
|
18
|
+
dynamic_model_provenance: string | null;
|
|
17
19
|
models: string;
|
|
18
20
|
}
|
|
19
21
|
|
|
@@ -33,6 +35,9 @@ interface CacheEntry<TApi extends Api = Api> {
|
|
|
33
35
|
* match — the cache already incorporates the same static state.
|
|
34
36
|
*/
|
|
35
37
|
staticFingerprint: string;
|
|
38
|
+
/** IDs returned by the authoritative dynamic provider catalog, when retained. */
|
|
39
|
+
dynamicModelIds: string[] | undefined;
|
|
40
|
+
dynamicModelProvenance: string | undefined;
|
|
36
41
|
}
|
|
37
42
|
|
|
38
43
|
let sharedDb: Database | null = null;
|
|
@@ -56,6 +61,8 @@ function getDb(dbPath?: string): Database {
|
|
|
56
61
|
updated_at INTEGER NOT NULL,
|
|
57
62
|
authoritative INTEGER NOT NULL DEFAULT 0,
|
|
58
63
|
static_fingerprint TEXT NOT NULL DEFAULT '',
|
|
64
|
+
dynamic_model_ids TEXT,
|
|
65
|
+
dynamic_model_provenance TEXT,
|
|
59
66
|
models TEXT NOT NULL
|
|
60
67
|
)
|
|
61
68
|
`);
|
|
@@ -81,7 +88,13 @@ function migrateCacheSchema(db: Database): void {
|
|
|
81
88
|
if (!columns.some(column => column.name === "static_fingerprint")) {
|
|
82
89
|
db.run("ALTER TABLE model_cache ADD COLUMN static_fingerprint TEXT NOT NULL DEFAULT ''");
|
|
83
90
|
}
|
|
84
|
-
|
|
91
|
+
if (!columns.some(column => column.name === "dynamic_model_ids")) {
|
|
92
|
+
db.run("ALTER TABLE model_cache ADD COLUMN dynamic_model_ids TEXT");
|
|
93
|
+
}
|
|
94
|
+
if (!columns.some(column => column.name === "dynamic_model_provenance")) {
|
|
95
|
+
db.run("ALTER TABLE model_cache ADD COLUMN dynamic_model_provenance TEXT");
|
|
96
|
+
}
|
|
97
|
+
db.run("UPDATE model_cache SET version = ? WHERE version IN (2, 3, 4)", [CACHE_SCHEMA_VERSION]);
|
|
85
98
|
}
|
|
86
99
|
|
|
87
100
|
export function readModelCache<TApi extends Api>(
|
|
@@ -105,6 +118,8 @@ export function readModelCache<TApi extends Api>(
|
|
|
105
118
|
authoritative: row.authoritative === 1,
|
|
106
119
|
updatedAt: row.updated_at,
|
|
107
120
|
staticFingerprint: row.static_fingerprint ?? "",
|
|
121
|
+
dynamicModelIds: row.dynamic_model_ids === null ? undefined : (JSON.parse(row.dynamic_model_ids) as string[]),
|
|
122
|
+
dynamicModelProvenance: row.dynamic_model_provenance ?? undefined,
|
|
108
123
|
};
|
|
109
124
|
} catch {
|
|
110
125
|
return null;
|
|
@@ -118,18 +133,22 @@ export function writeModelCache<TApi extends Api>(
|
|
|
118
133
|
authoritative: boolean,
|
|
119
134
|
staticFingerprint: string,
|
|
120
135
|
dbPath?: string,
|
|
136
|
+
dynamicModelIds?: readonly string[],
|
|
137
|
+
dynamicModelProvenance?: string,
|
|
121
138
|
): void {
|
|
122
139
|
try {
|
|
123
140
|
const db = getDb(dbPath);
|
|
124
141
|
db.run(
|
|
125
|
-
`INSERT OR REPLACE INTO model_cache (provider_id, version, updated_at, authoritative, static_fingerprint, models)
|
|
126
|
-
VALUES (?, ?, ?, ?, ?, ?)`,
|
|
142
|
+
`INSERT OR REPLACE INTO model_cache (provider_id, version, updated_at, authoritative, static_fingerprint, dynamic_model_ids, dynamic_model_provenance, models)
|
|
143
|
+
VALUES (?, ?, ?, ?, ?, ?, ?, ?)`,
|
|
127
144
|
[
|
|
128
145
|
providerId,
|
|
129
146
|
CACHE_SCHEMA_VERSION,
|
|
130
147
|
updatedAt,
|
|
131
148
|
authoritative ? 1 : 0,
|
|
132
149
|
staticFingerprint,
|
|
150
|
+
dynamicModelIds === undefined ? null : JSON.stringify(dynamicModelIds),
|
|
151
|
+
dynamicModelProvenance ?? null,
|
|
133
152
|
JSON.stringify(models),
|
|
134
153
|
],
|
|
135
154
|
);
|
package/src/model-manager.ts
CHANGED
|
@@ -43,6 +43,8 @@ export interface ModelManagerOptions<TApi extends Api = Api, TModelsDevPayload =
|
|
|
43
43
|
now?: () => number;
|
|
44
44
|
/** Optional guard that must permit cache publication. Default: writes are permitted. */
|
|
45
45
|
canPublishCache?: () => boolean;
|
|
46
|
+
/** Credential-and-endpoint identity required to reuse dynamic catalog IDs. */
|
|
47
|
+
cacheDynamicModelProvenance?: string;
|
|
46
48
|
}
|
|
47
49
|
|
|
48
50
|
/**
|
|
@@ -56,8 +58,17 @@ export interface ModelManagerOptions<TApi extends Api = Api, TModelsDevPayload =
|
|
|
56
58
|
export interface ModelResolutionResult<TApi extends Api = Api> {
|
|
57
59
|
models: Model<TApi>[];
|
|
58
60
|
stale: boolean;
|
|
61
|
+
/** Whether the cache row consulted for this resolution was still within its TTL. */
|
|
62
|
+
cacheFresh: boolean;
|
|
63
|
+
/** Whether the consulted cache row was authoritative. */
|
|
64
|
+
cacheAuthoritative: boolean;
|
|
59
65
|
/** Whether this resolution successfully fetched dynamic models. */
|
|
60
66
|
fetched: boolean;
|
|
67
|
+
/**
|
|
68
|
+
* IDs returned by a current authoritative dynamic provider catalog. This is
|
|
69
|
+
* deliberately distinct from `models`, which merges static and cached data.
|
|
70
|
+
*/
|
|
71
|
+
dynamicModelIds?: readonly string[];
|
|
61
72
|
}
|
|
62
73
|
|
|
63
74
|
/**
|
|
@@ -125,14 +136,19 @@ export async function resolveProviderModels<TApi extends Api = Api, TModelsDevPa
|
|
|
125
136
|
const cache = readModelCache<TApi>(options.providerId, ttlMs, now, dbPath);
|
|
126
137
|
const dynamicFetcher = options.fetchDynamicModels;
|
|
127
138
|
const hasDynamicFetcher = typeof dynamicFetcher === "function";
|
|
128
|
-
const
|
|
139
|
+
const cacheDynamicModelIdsCurrent =
|
|
140
|
+
cache?.dynamicModelIds !== undefined &&
|
|
141
|
+
cache.dynamicModelProvenance !== undefined &&
|
|
142
|
+
cache.dynamicModelProvenance === options.cacheDynamicModelProvenance;
|
|
143
|
+
const cacheProvenanceMismatch = cache?.dynamicModelIds !== undefined && !cacheDynamicModelIdsCurrent;
|
|
144
|
+
const hasAuthoritativeCache =
|
|
145
|
+
!hasDynamicFetcher ||
|
|
146
|
+
((cache?.authoritative ?? false) && (cache?.dynamicModelIds === undefined || cacheDynamicModelIdsCurrent));
|
|
129
147
|
const cacheAgeMs = cache ? now() - cache.updatedAt : Number.POSITIVE_INFINITY;
|
|
130
|
-
const shouldFetchFromNetwork =
|
|
131
|
-
strategy
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
cacheAgeMs,
|
|
135
|
-
);
|
|
148
|
+
const shouldFetchFromNetwork =
|
|
149
|
+
cacheProvenanceMismatch && strategy !== "offline"
|
|
150
|
+
? true
|
|
151
|
+
: shouldFetchRemoteSources(strategy, cache?.fresh ?? false, hasAuthoritativeCache, cacheAgeMs);
|
|
136
152
|
const staticFingerprint = fingerprintStatic(staticModels);
|
|
137
153
|
|
|
138
154
|
// Cold-start fast path: when a fresh, authoritative cache exists, the network
|
|
@@ -149,13 +165,38 @@ export async function resolveProviderModels<TApi extends Api = Api, TModelsDevPa
|
|
|
149
165
|
) {
|
|
150
166
|
const cachedModels = passModelList<TApi>(cache.models);
|
|
151
167
|
if (!hasStaticTransportDrift(staticModels, cachedModels)) {
|
|
152
|
-
return {
|
|
168
|
+
return {
|
|
169
|
+
models: cachedModels,
|
|
170
|
+
stale: false,
|
|
171
|
+
cacheFresh: true,
|
|
172
|
+
cacheAuthoritative: true,
|
|
173
|
+
fetched: false,
|
|
174
|
+
dynamicModelIds:
|
|
175
|
+
strategy === "online-if-uncached" && cacheDynamicModelIdsCurrent ? cache.dynamicModelIds : undefined,
|
|
176
|
+
};
|
|
153
177
|
}
|
|
154
178
|
const repairedModels = mergeDynamicModels(staticModels, cachedModels);
|
|
155
179
|
if (options.canPublishCache?.() ?? true) {
|
|
156
|
-
writeModelCache(
|
|
180
|
+
writeModelCache(
|
|
181
|
+
options.providerId,
|
|
182
|
+
now(),
|
|
183
|
+
repairedModels,
|
|
184
|
+
true,
|
|
185
|
+
staticFingerprint,
|
|
186
|
+
dbPath,
|
|
187
|
+
cache.dynamicModelIds,
|
|
188
|
+
cache.dynamicModelProvenance,
|
|
189
|
+
);
|
|
157
190
|
}
|
|
158
|
-
return {
|
|
191
|
+
return {
|
|
192
|
+
models: repairedModels,
|
|
193
|
+
stale: false,
|
|
194
|
+
cacheFresh: true,
|
|
195
|
+
cacheAuthoritative: true,
|
|
196
|
+
fetched: false,
|
|
197
|
+
dynamicModelIds:
|
|
198
|
+
strategy === "online-if-uncached" && cacheDynamicModelIdsCurrent ? cache.dynamicModelIds : undefined,
|
|
199
|
+
};
|
|
159
200
|
}
|
|
160
201
|
|
|
161
202
|
const [fetchedModelsDevModels, fetchedDynamicModels] = shouldFetchFromNetwork
|
|
@@ -176,7 +217,16 @@ export async function resolveProviderModels<TApi extends Api = Api, TModelsDevPa
|
|
|
176
217
|
mergeDynamicModels(mergeModelSources(staticModels, modelsDevModels), dynamicModels),
|
|
177
218
|
);
|
|
178
219
|
if (options.canPublishCache?.() ?? true) {
|
|
179
|
-
writeModelCache(
|
|
220
|
+
writeModelCache(
|
|
221
|
+
options.providerId,
|
|
222
|
+
now(),
|
|
223
|
+
snapshotModels,
|
|
224
|
+
true,
|
|
225
|
+
staticFingerprint,
|
|
226
|
+
dbPath,
|
|
227
|
+
dynamicModels.map(model => model.id),
|
|
228
|
+
options.cacheDynamicModelProvenance,
|
|
229
|
+
);
|
|
180
230
|
}
|
|
181
231
|
} else {
|
|
182
232
|
// Dynamic fetch failed — update cache with a non-authoritative snapshot so
|
|
@@ -202,7 +252,16 @@ export async function resolveProviderModels<TApi extends Api = Api, TModelsDevPa
|
|
|
202
252
|
return {
|
|
203
253
|
models,
|
|
204
254
|
stale: !dynamicAuthoritative,
|
|
255
|
+
cacheFresh: cache?.fresh ?? false,
|
|
256
|
+
cacheAuthoritative: cache?.authoritative ?? false,
|
|
205
257
|
fetched: shouldFetchFromNetwork && dynamicFetchSucceeded,
|
|
258
|
+
dynamicModelIds: dynamicFetchSucceeded
|
|
259
|
+
? dynamicModels.map(model => model.id)
|
|
260
|
+
: shouldUseFreshCacheAsAuthoritative
|
|
261
|
+
? cacheDynamicModelIdsCurrent
|
|
262
|
+
? cache?.dynamicModelIds
|
|
263
|
+
: undefined
|
|
264
|
+
: undefined,
|
|
206
265
|
};
|
|
207
266
|
}
|
|
208
267
|
|
package/src/model-thinking.ts
CHANGED
|
@@ -53,11 +53,16 @@ const DEFAULT_REASONING_EFFORTS_WITH_XHIGH_AND_MAX: readonly Effort[] = [
|
|
|
53
53
|
];
|
|
54
54
|
const GEMINI_3_PRO_EFFORTS: readonly Effort[] = [Effort.Low, Effort.High];
|
|
55
55
|
const GEMINI_3_FLASH_EFFORTS: readonly Effort[] = [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High];
|
|
56
|
+
// Gemini 3.7 Flash dropped `minimal`; the official API returns an error for it.
|
|
57
|
+
// https://ai.google.dev/gemini-api/docs/models/gemini-3.7-flash
|
|
58
|
+
const GEMINI_3_7_FLASH_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High];
|
|
56
59
|
const GPT_5_2_PLUS_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High, Effort.XHigh];
|
|
57
60
|
const GPT_5_6_PLUS_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High, Effort.XHigh, Effort.Max];
|
|
58
61
|
const GPT_5_5_DEFAULT_EFFORT = Effort.XHigh;
|
|
59
62
|
const KIMI_K3_EFFORTS: readonly Effort[] = [Effort.Low, Effort.High, Effort.Max];
|
|
60
63
|
const DEEPSEEK_V4_FLASH_0731_EFFORTS: readonly Effort[] = [Effort.Low, Effort.High, Effort.Max];
|
|
64
|
+
const GROK_4_5_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High];
|
|
65
|
+
const GROK_4_6_EFFORTS: readonly Effort[] = [Effort.Low, Effort.Medium, Effort.High, Effort.XHigh];
|
|
61
66
|
|
|
62
67
|
const GPT_5_1_CODEX_MINI_EFFORTS: readonly Effort[] = [Effort.Medium, Effort.High];
|
|
63
68
|
const CLOUDFLARE_AI_GATEWAY_BASE_URL = "https://gateway.ai.cloudflare.com/v1/<account>/<gateway>/anthropic";
|
|
@@ -206,10 +211,16 @@ export function refreshModelThinking<TApi extends Api>(model: ApiModel<TApi>): A
|
|
|
206
211
|
export function applyGeneratedModelPolicies(models: ApiModel<Api>[]): void {
|
|
207
212
|
for (let index = 0; index < models.length; index++) {
|
|
208
213
|
const source = models[index]!;
|
|
214
|
+
if (source.provider === "xai" && (source.id === "grok-4.5" || source.id === "grok-4.6")) {
|
|
215
|
+
source.reasoning = true;
|
|
216
|
+
}
|
|
209
217
|
if (source.provider === "alibaba-token-plan" && source.id === "deepseek-v4-flash-0731") {
|
|
210
218
|
source.reasoning = true;
|
|
211
219
|
source.name = "DeepSeek V4 Flash 0731";
|
|
212
220
|
}
|
|
221
|
+
if (source.id.split("/").at(-1)?.toLowerCase() === "muse-spark-1.2") {
|
|
222
|
+
source.reasoning = true;
|
|
223
|
+
}
|
|
213
224
|
const model = refreshModelThinking(source);
|
|
214
225
|
applyGeneratedModelPolicy(model);
|
|
215
226
|
models[index] = model;
|
|
@@ -460,6 +471,17 @@ function applyGeneratedModelPolicy(model: ApiModel<Api>): void {
|
|
|
460
471
|
if (model.provider === "zai" && model.id === "glm-5.2") {
|
|
461
472
|
model.contextWindow = 1_000_000;
|
|
462
473
|
}
|
|
474
|
+
// GLM-5.3 always thinks and exposes only low/high/max reasoning_effort.
|
|
475
|
+
// https://z.ai/blog/glm-5.3#api-changes-in-glm-5-3
|
|
476
|
+
if (model.provider === "zai" && model.id === "glm-5.3") {
|
|
477
|
+
model.thinking = {
|
|
478
|
+
mode: "effort",
|
|
479
|
+
minLevel: Effort.Low,
|
|
480
|
+
maxLevel: Effort.Max,
|
|
481
|
+
defaultLevel: Effort.Max,
|
|
482
|
+
levels: [Effort.Low, Effort.High, Effort.Max],
|
|
483
|
+
};
|
|
484
|
+
}
|
|
463
485
|
if (model.provider === "alibaba-token-plan" && model.id === "deepseek-v4-flash-0731") {
|
|
464
486
|
model.contextWindow = 1_000_000;
|
|
465
487
|
model.maxTokens = 384_000;
|
|
@@ -471,6 +493,9 @@ function applyGeneratedModelPolicy(model: ApiModel<Api>): void {
|
|
|
471
493
|
requiresReasoningContentForToolCalls: true,
|
|
472
494
|
};
|
|
473
495
|
}
|
|
496
|
+
if (model.provider === "xai" && (model.id === "grok-4.5" || model.id === "grok-4.6")) {
|
|
497
|
+
model.maxTokens = Math.min(model.maxTokens, 64_000);
|
|
498
|
+
}
|
|
474
499
|
// MiniMax-M3's official Token Plan routes expose a 1M context window.
|
|
475
500
|
// Scope the correction to the four first-class regional MiniMax routes
|
|
476
501
|
// (canonical id plus the Anthropic Token Plan `[1m]` id); unrelated
|
|
@@ -664,6 +689,12 @@ function expandEffortRange(thinking: ThinkingConfig): readonly Effort[] {
|
|
|
664
689
|
}
|
|
665
690
|
|
|
666
691
|
function inferSupportedEfforts<TApi extends Api>(parsedModel: ParsedModel, model: ApiModel<TApi>): readonly Effort[] {
|
|
692
|
+
if (model.provider === "xai" && model.id === "grok-4.5") {
|
|
693
|
+
return GROK_4_5_EFFORTS;
|
|
694
|
+
}
|
|
695
|
+
if (model.provider === "xai" && model.id === "grok-4.6") {
|
|
696
|
+
return GROK_4_6_EFFORTS;
|
|
697
|
+
}
|
|
667
698
|
if (model.provider === "kimi-code" && model.id === "k3") {
|
|
668
699
|
return KIMI_K3_EFFORTS;
|
|
669
700
|
}
|
|
@@ -699,7 +730,13 @@ function inferGeminiSupportedEfforts(model: GeminiModel): readonly Effort[] {
|
|
|
699
730
|
if (!semverGte(model.version, "3.0")) {
|
|
700
731
|
return DEFAULT_REASONING_EFFORTS;
|
|
701
732
|
}
|
|
702
|
-
|
|
733
|
+
if (model.kind === "pro") {
|
|
734
|
+
return GEMINI_3_PRO_EFFORTS;
|
|
735
|
+
}
|
|
736
|
+
if (semverGte(model.version, "3.7")) {
|
|
737
|
+
return GEMINI_3_7_FLASH_EFFORTS;
|
|
738
|
+
}
|
|
739
|
+
return GEMINI_3_FLASH_EFFORTS;
|
|
703
740
|
}
|
|
704
741
|
|
|
705
742
|
function inferAnthropicSupportedEfforts<TApi extends Api>(
|
|
@@ -730,6 +767,13 @@ function inferAnthropicSupportedEfforts<TApi extends Api>(
|
|
|
730
767
|
}
|
|
731
768
|
|
|
732
769
|
function inferFallbackEfforts<TApi extends Api>(model: ApiModel<TApi>): readonly Effort[] {
|
|
770
|
+
// Meta documents Muse Spark 1.2 as accepting the full minimal..xhigh
|
|
771
|
+
// reasoning range. Keep that capability provider-independent so runtime
|
|
772
|
+
// model discovery/merge cannot downgrade the bundled OpenRouter entry to
|
|
773
|
+
// the generic openai-completions ceiling of `high`.
|
|
774
|
+
if (model.id.split("/").at(-1)?.toLowerCase() === "muse-spark-1.2") {
|
|
775
|
+
return DEFAULT_REASONING_EFFORTS_WITH_XHIGH;
|
|
776
|
+
}
|
|
733
777
|
if (model.api === "anthropic-messages") {
|
|
734
778
|
return DEFAULT_REASONING_EFFORTS_WITH_XHIGH;
|
|
735
779
|
}
|