@oh-my-pi/pi-catalog 17.2.10 → 17.2.12
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 +15 -0
- package/dist/types/compat/bedrock.d.ts +1 -1
- package/dist/types/provider-models/openai-compat.d.ts +11 -0
- package/dist/types/types.d.ts +13 -0
- package/package.json +4 -4
- package/src/compat/bedrock.ts +28 -1
- package/src/models.json +5314 -2054
- package/src/provider-models/openai-compat.ts +331 -302
- package/src/types.ts +13 -0
- package/src/variant-collapse.ts +105 -4
|
@@ -18,7 +18,7 @@ import {
|
|
|
18
18
|
} from "../identity/family";
|
|
19
19
|
import { resolveModelReference } from "../identity/reference";
|
|
20
20
|
import type { ModelManagerOptions } from "../model-manager";
|
|
21
|
-
import { getBundledModels } from "../models";
|
|
21
|
+
import { type GeneratedProvider, getBundledModels } from "../models";
|
|
22
22
|
import type { Api, FetchImpl, Model, ModelSpec, OpenAICompat, Provider, ThinkingConfig } from "../types";
|
|
23
23
|
import { discoveryFetch, isAnthropicOAuthToken, isRecord, toBoolean, toNumber, toPositiveNumber } from "../utils";
|
|
24
24
|
import { ALIBABA_TOKEN_PLAN_BASE_URL, parseAlibabaTokenPlanCredential } from "../wire/alibaba-token-plan";
|
|
@@ -592,60 +592,68 @@ function resolveSimpleProviderHeaders(
|
|
|
592
592
|
return typeof headers === "function" ? headers() : headers;
|
|
593
593
|
}
|
|
594
594
|
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
595
|
+
type OpenAICompatibleModelManagerBuilderOptions<TApi extends Api> = {
|
|
596
|
+
api: TApi;
|
|
597
|
+
providerId: GeneratedProvider;
|
|
598
|
+
defaultBaseUrl: string;
|
|
599
|
+
config?: SimpleProviderConfig;
|
|
600
|
+
headers?: SimpleProviderDiscoveryHeaders;
|
|
601
|
+
dynamicModelsAuthoritative?: true;
|
|
602
|
+
requireApiKey?: true;
|
|
603
|
+
filterModel?: (
|
|
604
|
+
entry: OpenAICompatibleModelRecord,
|
|
605
|
+
model: ModelSpec<TApi>,
|
|
606
|
+
references: Map<string, ModelSpec<TApi>>,
|
|
607
|
+
) => boolean;
|
|
608
|
+
mapModel: (
|
|
609
|
+
entry: OpenAICompatibleModelRecord,
|
|
610
|
+
defaults: ModelSpec<TApi>,
|
|
611
|
+
reference: ModelSpec<TApi> | undefined,
|
|
612
|
+
) => ModelSpec<TApi> | null;
|
|
613
|
+
};
|
|
614
|
+
|
|
615
|
+
function createOpenAICompatibleModelManagerOptions<TApi extends Api>(
|
|
616
|
+
options: OpenAICompatibleModelManagerBuilderOptions<TApi>,
|
|
617
|
+
): ModelManagerOptions<TApi> {
|
|
618
|
+
const apiKey = options.config?.apiKey;
|
|
619
|
+
const baseUrl = options.config?.baseUrl ?? options.defaultBaseUrl;
|
|
620
|
+
const references = createBundledReferenceMap<TApi>(options.providerId);
|
|
621
|
+
const filterModel = options.filterModel;
|
|
603
622
|
return {
|
|
604
|
-
providerId,
|
|
605
|
-
...(
|
|
623
|
+
providerId: options.providerId,
|
|
624
|
+
...(options.dynamicModelsAuthoritative && { dynamicModelsAuthoritative: true }),
|
|
625
|
+
...((!options.requireApiKey || apiKey) && {
|
|
606
626
|
fetchDynamicModels: () =>
|
|
607
627
|
fetchOpenAICompatibleModels({
|
|
608
|
-
api:
|
|
609
|
-
provider: providerId,
|
|
628
|
+
api: options.api,
|
|
629
|
+
provider: options.providerId,
|
|
610
630
|
baseUrl,
|
|
611
631
|
apiKey,
|
|
612
|
-
headers: resolveSimpleProviderHeaders(
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
fetch: config?.fetch,
|
|
632
|
+
...(options.headers && { headers: resolveSimpleProviderHeaders(options.headers) }),
|
|
633
|
+
...(filterModel && {
|
|
634
|
+
filterModel: (entry, model) => filterModel(entry, model, references),
|
|
635
|
+
}),
|
|
636
|
+
mapModel: (entry, defaults) => options.mapModel(entry, defaults, references.get(defaults.id)),
|
|
637
|
+
fetch: options.config?.fetch,
|
|
618
638
|
}),
|
|
619
639
|
}),
|
|
620
640
|
};
|
|
621
641
|
}
|
|
622
642
|
|
|
623
|
-
function
|
|
643
|
+
export function createSimpleOpenAICompletionsOptions(
|
|
624
644
|
providerId: Parameters<typeof getBundledModels>[0],
|
|
625
645
|
defaultBaseUrl: string,
|
|
626
646
|
config?: SimpleProviderConfig,
|
|
627
|
-
): ModelManagerOptions<"openai-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
const references = createBundledReferenceMap<"openai-responses">(providerId);
|
|
631
|
-
return {
|
|
647
|
+
): ModelManagerOptions<"openai-completions"> {
|
|
648
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
649
|
+
api: "openai-completions",
|
|
632
650
|
providerId,
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
apiKey,
|
|
640
|
-
headers: resolveSimpleProviderHeaders(config?.headers),
|
|
641
|
-
mapModel: (entry, defaults) => {
|
|
642
|
-
const reference = references.get(defaults.id);
|
|
643
|
-
return mapWithBundledReference(entry, defaults, reference);
|
|
644
|
-
},
|
|
645
|
-
fetch: config?.fetch,
|
|
646
|
-
}),
|
|
647
|
-
}),
|
|
648
|
-
};
|
|
651
|
+
defaultBaseUrl,
|
|
652
|
+
config,
|
|
653
|
+
headers: config?.headers,
|
|
654
|
+
requireApiKey: true,
|
|
655
|
+
mapModel: mapWithBundledReference,
|
|
656
|
+
});
|
|
649
657
|
}
|
|
650
658
|
|
|
651
659
|
function createSimpleAnthropicProviderOptions(
|
|
@@ -865,27 +873,15 @@ export interface OpenAIModelManagerConfig {
|
|
|
865
873
|
}
|
|
866
874
|
|
|
867
875
|
export function openaiModelManagerOptions(config?: OpenAIModelManagerConfig): ModelManagerOptions<"openai-responses"> {
|
|
868
|
-
|
|
869
|
-
|
|
870
|
-
const references = createBundledReferenceMap<"openai-responses">("openai");
|
|
871
|
-
return {
|
|
876
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
877
|
+
api: "openai-responses",
|
|
872
878
|
providerId: "openai",
|
|
873
|
-
|
|
874
|
-
|
|
875
|
-
|
|
876
|
-
|
|
877
|
-
|
|
878
|
-
|
|
879
|
-
apiKey,
|
|
880
|
-
filterModel: (_entry, model) => isLikelyOpenAIResponsesModelId(model.id, references),
|
|
881
|
-
mapModel: (entry, defaults) => {
|
|
882
|
-
const reference = references.get(defaults.id);
|
|
883
|
-
return mapWithBundledReference(entry, defaults, reference);
|
|
884
|
-
},
|
|
885
|
-
fetch: config?.fetch,
|
|
886
|
-
}),
|
|
887
|
-
}),
|
|
888
|
-
};
|
|
879
|
+
defaultBaseUrl: "https://api.openai.com/v1",
|
|
880
|
+
config,
|
|
881
|
+
requireApiKey: true,
|
|
882
|
+
filterModel: (_entry, model, references) => isLikelyOpenAIResponsesModelId(model.id, references),
|
|
883
|
+
mapModel: mapWithBundledReference,
|
|
884
|
+
});
|
|
889
885
|
}
|
|
890
886
|
|
|
891
887
|
/** First-party gpt-5.6 SKUs that accept `reasoning: { mode: "pro" }` on the Responses APIs. */
|
|
@@ -1036,27 +1032,15 @@ export interface CerebrasModelManagerConfig {
|
|
|
1036
1032
|
export function cerebrasModelManagerOptions(
|
|
1037
1033
|
config?: CerebrasModelManagerConfig,
|
|
1038
1034
|
): ModelManagerOptions<"openai-completions"> {
|
|
1039
|
-
|
|
1040
|
-
|
|
1041
|
-
const references = createBundledReferenceMap<"openai-completions">("cerebras");
|
|
1042
|
-
return {
|
|
1035
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
1036
|
+
api: "openai-completions",
|
|
1043
1037
|
providerId: "cerebras",
|
|
1044
|
-
|
|
1045
|
-
|
|
1046
|
-
|
|
1047
|
-
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
apiKey,
|
|
1051
|
-
mapModel: (entry, defaults) => {
|
|
1052
|
-
const reference = references.get(defaults.id);
|
|
1053
|
-
const model = mapWithBundledReference(entry, defaults, reference);
|
|
1054
|
-
return applyCerebrasDiscoveryOverrides(model);
|
|
1055
|
-
},
|
|
1056
|
-
fetch: config?.fetch,
|
|
1057
|
-
}),
|
|
1058
|
-
}),
|
|
1059
|
-
};
|
|
1038
|
+
defaultBaseUrl: "https://api.cerebras.ai/v1",
|
|
1039
|
+
config,
|
|
1040
|
+
requireApiKey: true,
|
|
1041
|
+
mapModel: (entry, defaults, reference) =>
|
|
1042
|
+
applyCerebrasDiscoveryOverrides(mapWithBundledReference(entry, defaults, reference)),
|
|
1043
|
+
});
|
|
1060
1044
|
}
|
|
1061
1045
|
|
|
1062
1046
|
// ---------------------------------------------------------------------------
|
|
@@ -1160,31 +1144,23 @@ function mapNovitaModel(
|
|
|
1160
1144
|
export function novitaModelManagerOptions(
|
|
1161
1145
|
config?: NovitaModelManagerConfig,
|
|
1162
1146
|
): ModelManagerOptions<"openai-completions"> {
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
const references = createBundledReferenceMap<"openai-completions">("novita");
|
|
1166
|
-
return {
|
|
1147
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
1148
|
+
api: "openai-completions",
|
|
1167
1149
|
providerId: "novita",
|
|
1150
|
+
defaultBaseUrl: "https://api.novita.ai/openai/v1",
|
|
1151
|
+
config,
|
|
1168
1152
|
dynamicModelsAuthoritative: true,
|
|
1169
|
-
|
|
1170
|
-
|
|
1171
|
-
|
|
1172
|
-
|
|
1173
|
-
|
|
1174
|
-
|
|
1175
|
-
|
|
1176
|
-
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
|
|
1180
|
-
isPublicNovitaModelId(model.id) &&
|
|
1181
|
-
novitaArrayIncludes(entry.endpoints, "chat/completions") &&
|
|
1182
|
-
toPositiveNumber(entry.max_output_tokens, 0) > 0
|
|
1183
|
-
);
|
|
1184
|
-
},
|
|
1185
|
-
fetch: config?.fetch,
|
|
1186
|
-
}),
|
|
1187
|
-
};
|
|
1153
|
+
filterModel: (entry, model) => {
|
|
1154
|
+
const active = typeof entry.status !== "number" || entry.status === 1;
|
|
1155
|
+
return (
|
|
1156
|
+
active &&
|
|
1157
|
+
isPublicNovitaModelId(model.id) &&
|
|
1158
|
+
novitaArrayIncludes(entry.endpoints, "chat/completions") &&
|
|
1159
|
+
toPositiveNumber(entry.max_output_tokens, 0) > 0
|
|
1160
|
+
);
|
|
1161
|
+
},
|
|
1162
|
+
mapModel: mapNovitaModel,
|
|
1163
|
+
});
|
|
1188
1164
|
}
|
|
1189
1165
|
|
|
1190
1166
|
// ---------------------------------------------------------------------------
|
|
@@ -1453,11 +1429,14 @@ export function xaiOAuthModelManagerOptions(
|
|
|
1453
1429
|
): ModelManagerOptions<"openai-responses"> {
|
|
1454
1430
|
const defaultBaseUrl = "https://api.x.ai/v1";
|
|
1455
1431
|
const resolvedBaseUrl = config?.baseUrl ?? defaultBaseUrl;
|
|
1456
|
-
const base =
|
|
1457
|
-
"
|
|
1432
|
+
const base = createOpenAICompatibleModelManagerOptions({
|
|
1433
|
+
api: "openai-responses",
|
|
1434
|
+
providerId: "xai-oauth",
|
|
1458
1435
|
defaultBaseUrl,
|
|
1459
1436
|
config,
|
|
1460
|
-
|
|
1437
|
+
requireApiKey: true,
|
|
1438
|
+
mapModel: mapWithBundledReference,
|
|
1439
|
+
});
|
|
1461
1440
|
// Static seed handed to the runtime model manager so the picker populates on
|
|
1462
1441
|
// a fresh login even before `fetchDynamicModels` fires (it is gated on
|
|
1463
1442
|
// `config.apiKey` at construction time, and OAuth tokens resolve later via
|
|
@@ -1510,28 +1489,16 @@ export interface AimlApiModelManagerConfig {
|
|
|
1510
1489
|
export function aimlApiModelManagerOptions(
|
|
1511
1490
|
config?: AimlApiModelManagerConfig,
|
|
1512
1491
|
): ModelManagerOptions<"openai-completions"> {
|
|
1513
|
-
|
|
1514
|
-
|
|
1515
|
-
const references = createBundledReferenceMap<"openai-completions">("aimlapi");
|
|
1516
|
-
return {
|
|
1492
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
1493
|
+
api: "openai-completions",
|
|
1517
1494
|
providerId: "aimlapi",
|
|
1495
|
+
defaultBaseUrl: "https://api.aimlapi.com/v1",
|
|
1496
|
+
config,
|
|
1518
1497
|
dynamicModelsAuthoritative: true,
|
|
1519
|
-
|
|
1520
|
-
|
|
1521
|
-
|
|
1522
|
-
|
|
1523
|
-
provider: "aimlapi",
|
|
1524
|
-
baseUrl,
|
|
1525
|
-
apiKey,
|
|
1526
|
-
filterModel: (_entry, model) => isLikelyAimlApiChatModelId(model.id),
|
|
1527
|
-
mapModel: (entry, defaults) => {
|
|
1528
|
-
const reference = references.get(defaults.id);
|
|
1529
|
-
return mapWithBundledReference(entry, defaults, reference);
|
|
1530
|
-
},
|
|
1531
|
-
fetch: config?.fetch,
|
|
1532
|
-
}),
|
|
1533
|
-
}),
|
|
1534
|
-
};
|
|
1498
|
+
requireApiKey: true,
|
|
1499
|
+
filterModel: (_entry, model) => isLikelyAimlApiChatModelId(model.id),
|
|
1500
|
+
mapModel: mapWithBundledReference,
|
|
1501
|
+
});
|
|
1535
1502
|
}
|
|
1536
1503
|
|
|
1537
1504
|
// ---------------------------------------------------------------------------
|
|
@@ -2699,24 +2666,13 @@ export interface AlibabaCodingPlanModelManagerConfig {
|
|
|
2699
2666
|
export function alibabaCodingPlanModelManagerOptions(
|
|
2700
2667
|
config?: AlibabaCodingPlanModelManagerConfig,
|
|
2701
2668
|
): ModelManagerOptions<"openai-completions"> {
|
|
2702
|
-
|
|
2703
|
-
|
|
2704
|
-
const references = createBundledReferenceMap<"openai-completions">("alibaba-coding-plan");
|
|
2705
|
-
return {
|
|
2669
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
2670
|
+
api: "openai-completions",
|
|
2706
2671
|
providerId: "alibaba-coding-plan",
|
|
2707
|
-
|
|
2708
|
-
|
|
2709
|
-
|
|
2710
|
-
|
|
2711
|
-
baseUrl,
|
|
2712
|
-
apiKey,
|
|
2713
|
-
mapModel: (entry, defaults) => {
|
|
2714
|
-
const reference = references.get(defaults.id);
|
|
2715
|
-
return mapWithBundledReference(entry, defaults, reference);
|
|
2716
|
-
},
|
|
2717
|
-
fetch: config?.fetch,
|
|
2718
|
-
}),
|
|
2719
|
-
};
|
|
2672
|
+
defaultBaseUrl: "https://coding-intl.dashscope.aliyuncs.com/v1",
|
|
2673
|
+
config,
|
|
2674
|
+
mapModel: mapWithBundledReference,
|
|
2675
|
+
});
|
|
2720
2676
|
}
|
|
2721
2677
|
|
|
2722
2678
|
// ---------------------------------------------------------------------------
|
|
@@ -2733,6 +2689,17 @@ const ALIBABA_TOKEN_PLAN_REASONING: ThinkingConfig = {
|
|
|
2733
2689
|
mode: "effort",
|
|
2734
2690
|
efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High],
|
|
2735
2691
|
};
|
|
2692
|
+
// Qwen3.8-Max combines Qwen's binary thinking toggle with OpenAI-style
|
|
2693
|
+
// `reasoning_effort`. The base Qwen view encodes disabled turns; reasoning
|
|
2694
|
+
// requests swap to the OpenAI effort dialect and explicitly enable thinking.
|
|
2695
|
+
const ALIBABA_TOKEN_PLAN_QWEN_EFFORT_COMPAT: OpenAICompat = {
|
|
2696
|
+
...ALIBABA_TOKEN_PLAN_COMPAT,
|
|
2697
|
+
supportsReasoningEffort: true,
|
|
2698
|
+
whenThinking: {
|
|
2699
|
+
thinkingFormat: "openai",
|
|
2700
|
+
extraBody: { enable_thinking: true },
|
|
2701
|
+
},
|
|
2702
|
+
};
|
|
2736
2703
|
|
|
2737
2704
|
export const ALIBABA_TOKEN_PLAN_STATIC_MODELS: readonly ModelSpec<"openai-completions">[] = [
|
|
2738
2705
|
{
|
|
@@ -2756,6 +2723,24 @@ export const ALIBABA_TOKEN_PLAN_STATIC_MODELS: readonly ModelSpec<"openai-comple
|
|
|
2756
2723
|
supportsReasoningEffort: true,
|
|
2757
2724
|
},
|
|
2758
2725
|
},
|
|
2726
|
+
{
|
|
2727
|
+
id: "qwen3.8-max",
|
|
2728
|
+
name: "Qwen3.8 Max",
|
|
2729
|
+
api: "openai-completions",
|
|
2730
|
+
provider: "alibaba-token-plan",
|
|
2731
|
+
baseUrl: ALIBABA_TOKEN_PLAN_BASE_URL,
|
|
2732
|
+
reasoning: true,
|
|
2733
|
+
input: ["text", "image"],
|
|
2734
|
+
cost: ALIBABA_TOKEN_PLAN_COST,
|
|
2735
|
+
contextWindow: 1_000_000,
|
|
2736
|
+
maxTokens: 131_072,
|
|
2737
|
+
thinking: {
|
|
2738
|
+
mode: "effort",
|
|
2739
|
+
efforts: [Effort.Low, Effort.Medium, Effort.XHigh],
|
|
2740
|
+
defaultLevel: Effort.XHigh,
|
|
2741
|
+
},
|
|
2742
|
+
compat: ALIBABA_TOKEN_PLAN_QWEN_EFFORT_COMPAT,
|
|
2743
|
+
},
|
|
2759
2744
|
{
|
|
2760
2745
|
id: "qwen3.7-max",
|
|
2761
2746
|
name: "Qwen3.7 Max",
|
|
@@ -2834,6 +2819,64 @@ export const ALIBABA_TOKEN_PLAN_STATIC_MODELS: readonly ModelSpec<"openai-comple
|
|
|
2834
2819
|
},
|
|
2835
2820
|
];
|
|
2836
2821
|
|
|
2822
|
+
/**
|
|
2823
|
+
* Metadata for Alibaba Token Plan models that are dynamically discovered but not
|
|
2824
|
+
* in the static catalog. Context window and max tokens are sourced from
|
|
2825
|
+
* official model documentation and provider catalogs. Unknown future models
|
|
2826
|
+
* remain available with null limits instead of assigning unsafe guessed limits.
|
|
2827
|
+
*/
|
|
2828
|
+
export interface AlibabaTokenPlanModelLimits {
|
|
2829
|
+
contextWindow: number;
|
|
2830
|
+
maxTokens: number;
|
|
2831
|
+
}
|
|
2832
|
+
|
|
2833
|
+
export const ALIBABA_TOKEN_PLAN_DISCOVERED_MODEL_LIMITS: Readonly<Record<string, AlibabaTokenPlanModelLimits>> = {
|
|
2834
|
+
"qwen3.6-plus": {
|
|
2835
|
+
contextWindow: 1_000_000,
|
|
2836
|
+
maxTokens: 65_536,
|
|
2837
|
+
},
|
|
2838
|
+
"qwen3.8-max": {
|
|
2839
|
+
contextWindow: 1_000_000,
|
|
2840
|
+
maxTokens: 131_072,
|
|
2841
|
+
},
|
|
2842
|
+
"deepseek-v4-flash": {
|
|
2843
|
+
contextWindow: 1_000_000,
|
|
2844
|
+
maxTokens: 384_000,
|
|
2845
|
+
},
|
|
2846
|
+
"deepseek-v4-flash-0731": {
|
|
2847
|
+
contextWindow: 1_000_000,
|
|
2848
|
+
maxTokens: 384_000,
|
|
2849
|
+
},
|
|
2850
|
+
"deepseek-v3.2": {
|
|
2851
|
+
contextWindow: 131_072,
|
|
2852
|
+
maxTokens: 65_536,
|
|
2853
|
+
},
|
|
2854
|
+
"glm-5.1": {
|
|
2855
|
+
contextWindow: 202_752,
|
|
2856
|
+
maxTokens: 128_000,
|
|
2857
|
+
},
|
|
2858
|
+
"glm-5": {
|
|
2859
|
+
contextWindow: 202_752,
|
|
2860
|
+
maxTokens: 16_384,
|
|
2861
|
+
},
|
|
2862
|
+
"kimi-k2.7-code": {
|
|
2863
|
+
contextWindow: 262_144,
|
|
2864
|
+
maxTokens: 262_144,
|
|
2865
|
+
},
|
|
2866
|
+
"kimi-k2.6": {
|
|
2867
|
+
contextWindow: 262_144,
|
|
2868
|
+
maxTokens: 262_144,
|
|
2869
|
+
},
|
|
2870
|
+
"kimi-k2.5": {
|
|
2871
|
+
contextWindow: 262_144,
|
|
2872
|
+
maxTokens: 98_304,
|
|
2873
|
+
},
|
|
2874
|
+
"minimax-m2.5": {
|
|
2875
|
+
contextWindow: 196_608,
|
|
2876
|
+
maxTokens: 32_768,
|
|
2877
|
+
},
|
|
2878
|
+
};
|
|
2879
|
+
|
|
2837
2880
|
const ALIBABA_TOKEN_PLAN_NON_CHAT_MODEL_PREFIXES = [
|
|
2838
2881
|
"fun-asr",
|
|
2839
2882
|
"happyhorse-",
|
|
@@ -2888,10 +2931,19 @@ export function alibabaTokenPlanModelManagerOptions(
|
|
|
2888
2931
|
baseUrl: defaults.baseUrl,
|
|
2889
2932
|
};
|
|
2890
2933
|
}
|
|
2891
|
-
|
|
2892
|
-
|
|
2934
|
+
const normalizedId = defaults.id.trim().toLowerCase();
|
|
2935
|
+
const limits = ALIBABA_TOKEN_PLAN_DISCOVERED_MODEL_LIMITS[normalizedId];
|
|
2936
|
+
const enriched = limits
|
|
2937
|
+
? {
|
|
2938
|
+
...defaults,
|
|
2939
|
+
contextWindow: limits.contextWindow,
|
|
2940
|
+
maxTokens: limits.maxTokens,
|
|
2941
|
+
}
|
|
2942
|
+
: defaults;
|
|
2943
|
+
|
|
2944
|
+
if (normalizedId.startsWith("deepseek-v4")) {
|
|
2893
2945
|
return {
|
|
2894
|
-
...
|
|
2946
|
+
...enriched,
|
|
2895
2947
|
reasoning: true,
|
|
2896
2948
|
thinking: {
|
|
2897
2949
|
mode: "effort" as const,
|
|
@@ -2899,7 +2951,7 @@ export function alibabaTokenPlanModelManagerOptions(
|
|
|
2899
2951
|
},
|
|
2900
2952
|
};
|
|
2901
2953
|
}
|
|
2902
|
-
return
|
|
2954
|
+
return enriched;
|
|
2903
2955
|
},
|
|
2904
2956
|
fetch: config?.fetch,
|
|
2905
2957
|
}),
|
|
@@ -3452,29 +3504,20 @@ export interface VeniceModelManagerConfig {
|
|
|
3452
3504
|
export function veniceModelManagerOptions(
|
|
3453
3505
|
config?: VeniceModelManagerConfig,
|
|
3454
3506
|
): ModelManagerOptions<"openai-completions"> {
|
|
3455
|
-
|
|
3456
|
-
|
|
3457
|
-
const references = createBundledReferenceMap<"openai-completions">("venice");
|
|
3458
|
-
return {
|
|
3507
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
3508
|
+
api: "openai-completions",
|
|
3459
3509
|
providerId: "venice",
|
|
3460
|
-
|
|
3461
|
-
|
|
3462
|
-
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
|
|
3469
|
-
|
|
3470
|
-
|
|
3471
|
-
maxTokens: clampKimiK27CodeMaxTokens(defaults.id, model.maxTokens),
|
|
3472
|
-
compat: { ...model.compat, supportsUsageInStreaming: false },
|
|
3473
|
-
};
|
|
3474
|
-
},
|
|
3475
|
-
fetch: config?.fetch,
|
|
3476
|
-
}),
|
|
3477
|
-
};
|
|
3510
|
+
defaultBaseUrl: "https://api.venice.ai/api/v1",
|
|
3511
|
+
config,
|
|
3512
|
+
mapModel: (entry, defaults, reference) => {
|
|
3513
|
+
const model = mapWithBundledReference(entry, defaults, reference);
|
|
3514
|
+
return {
|
|
3515
|
+
...model,
|
|
3516
|
+
maxTokens: clampKimiK27CodeMaxTokens(defaults.id, model.maxTokens),
|
|
3517
|
+
compat: { ...model.compat, supportsUsageInStreaming: false },
|
|
3518
|
+
};
|
|
3519
|
+
},
|
|
3520
|
+
});
|
|
3478
3521
|
}
|
|
3479
3522
|
|
|
3480
3523
|
// ---------------------------------------------------------------------------
|
|
@@ -3490,83 +3533,66 @@ export interface BasetenModelManagerConfig {
|
|
|
3490
3533
|
export function basetenModelManagerOptions(
|
|
3491
3534
|
config?: BasetenModelManagerConfig,
|
|
3492
3535
|
): ModelManagerOptions<"openai-completions"> {
|
|
3493
|
-
|
|
3494
|
-
|
|
3495
|
-
const references = createBundledReferenceMap<"openai-completions">("baseten");
|
|
3496
|
-
return {
|
|
3536
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
3537
|
+
api: "openai-completions",
|
|
3497
3538
|
providerId: "baseten",
|
|
3539
|
+
defaultBaseUrl: "https://inference.baseten.co/v1",
|
|
3540
|
+
config,
|
|
3498
3541
|
dynamicModelsAuthoritative: true,
|
|
3499
|
-
|
|
3500
|
-
|
|
3501
|
-
|
|
3502
|
-
|
|
3503
|
-
|
|
3504
|
-
|
|
3505
|
-
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
|
|
3510
|
-
|
|
3511
|
-
|
|
3512
|
-
|
|
3513
|
-
|
|
3514
|
-
|
|
3515
|
-
|
|
3516
|
-
|
|
3517
|
-
|
|
3518
|
-
|
|
3519
|
-
|
|
3520
|
-
|
|
3521
|
-
|
|
3522
|
-
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
|
|
3526
|
-
const pricing = raw.pricing ?? {};
|
|
3527
|
-
const cost = {
|
|
3528
|
-
input: toPositiveNumber(pricing.prompt, 0) * 1_000_000,
|
|
3529
|
-
output: toPositiveNumber(pricing.completion, 0) * 1_000_000,
|
|
3530
|
-
cacheRead: toPositiveNumber(pricing.input_cache_read, 0) * 1_000_000,
|
|
3531
|
-
cacheWrite: 0,
|
|
3532
|
-
};
|
|
3542
|
+
requireApiKey: true,
|
|
3543
|
+
mapModel: (entry, defaults, reference) => {
|
|
3544
|
+
const raw = entry as Record<string, unknown> & {
|
|
3545
|
+
supported_features?: unknown;
|
|
3546
|
+
input_modalities?: unknown;
|
|
3547
|
+
pricing?: Record<string, unknown>;
|
|
3548
|
+
};
|
|
3549
|
+
const features = Array.isArray(raw.supported_features) ? raw.supported_features : [];
|
|
3550
|
+
const modalities = Array.isArray(raw.input_modalities) ? raw.input_modalities : [];
|
|
3551
|
+
|
|
3552
|
+
const isBasetenNativeReasoning =
|
|
3553
|
+
defaults.id === "openai/gpt-oss-120b" ||
|
|
3554
|
+
defaults.id === "deepseek-ai/DeepSeek-V4-Pro" ||
|
|
3555
|
+
defaults.id === "zai-org/GLM-5.2";
|
|
3556
|
+
const reasoning =
|
|
3557
|
+
isBasetenNativeReasoning && (features.includes("reasoning") || features.includes("reasoning_effort"));
|
|
3558
|
+
const supportsTools = features.includes("tools") ? undefined : false;
|
|
3559
|
+
const vision = modalities.includes("image") || (reference?.input.includes("image") ?? false);
|
|
3560
|
+
|
|
3561
|
+
const pricing = raw.pricing ?? {};
|
|
3562
|
+
const cost = {
|
|
3563
|
+
input: toPositiveNumber(pricing.prompt, 0) * 1_000_000,
|
|
3564
|
+
output: toPositiveNumber(pricing.completion, 0) * 1_000_000,
|
|
3565
|
+
cacheRead: toPositiveNumber(pricing.input_cache_read, 0) * 1_000_000,
|
|
3566
|
+
cacheWrite: 0,
|
|
3567
|
+
};
|
|
3533
3568
|
|
|
3534
|
-
|
|
3535
|
-
|
|
3536
|
-
reference?.contextWindow ?? defaults.contextWindow,
|
|
3537
|
-
);
|
|
3538
|
-
const maxTokens = toPositiveNumber(
|
|
3539
|
-
raw.max_completion_tokens,
|
|
3540
|
-
reference?.maxTokens ?? defaults.maxTokens,
|
|
3541
|
-
);
|
|
3569
|
+
const contextWindow = toPositiveNumber(raw.context_length, reference?.contextWindow ?? defaults.contextWindow);
|
|
3570
|
+
const maxTokens = toPositiveNumber(raw.max_completion_tokens, reference?.maxTokens ?? defaults.maxTokens);
|
|
3542
3571
|
|
|
3543
|
-
|
|
3572
|
+
const baseModel = mapWithBundledReference(entry, defaults, reference);
|
|
3544
3573
|
|
|
3545
|
-
|
|
3546
|
-
|
|
3547
|
-
|
|
3548
|
-
|
|
3549
|
-
|
|
3550
|
-
|
|
3551
|
-
|
|
3552
|
-
|
|
3553
|
-
|
|
3574
|
+
// Baseten's reasoning router accepts only the high/max
|
|
3575
|
+
// effort tiers for its GLM-5.2 and gpt-oss routes.
|
|
3576
|
+
const isEffortReasoning = defaults.id === "openai/gpt-oss-120b" || defaults.id === "zai-org/GLM-5.2";
|
|
3577
|
+
const thinking = isEffortReasoning
|
|
3578
|
+
? {
|
|
3579
|
+
mode: "effort" as const,
|
|
3580
|
+
efforts: [Effort.High, Effort.Max],
|
|
3581
|
+
}
|
|
3582
|
+
: undefined;
|
|
3554
3583
|
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
|
|
3559
|
-
|
|
3560
|
-
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
}),
|
|
3568
|
-
}),
|
|
3569
|
-
};
|
|
3584
|
+
return {
|
|
3585
|
+
...baseModel,
|
|
3586
|
+
reasoning,
|
|
3587
|
+
input: vision ? ["text", "image"] : ["text"],
|
|
3588
|
+
cost,
|
|
3589
|
+
contextWindow,
|
|
3590
|
+
maxTokens,
|
|
3591
|
+
...(thinking ? { thinking } : {}),
|
|
3592
|
+
...(supportsTools === false ? { supportsTools } : {}),
|
|
3593
|
+
};
|
|
3594
|
+
},
|
|
3595
|
+
});
|
|
3570
3596
|
}
|
|
3571
3597
|
|
|
3572
3598
|
// ---------------------------------------------------------------------------
|
|
@@ -3763,7 +3789,14 @@ export interface MetaModelManagerConfig {
|
|
|
3763
3789
|
|
|
3764
3790
|
export function metaModelManagerOptions(config?: MetaModelManagerConfig): ModelManagerOptions<"openai-responses"> {
|
|
3765
3791
|
return {
|
|
3766
|
-
...
|
|
3792
|
+
...createOpenAICompatibleModelManagerOptions({
|
|
3793
|
+
api: "openai-responses",
|
|
3794
|
+
providerId: "meta",
|
|
3795
|
+
defaultBaseUrl: META_MODEL_API_BASE_URL,
|
|
3796
|
+
config,
|
|
3797
|
+
requireApiKey: true,
|
|
3798
|
+
mapModel: mapWithBundledReference,
|
|
3799
|
+
}),
|
|
3767
3800
|
staticModels: META_MUSE_STATIC_MODELS,
|
|
3768
3801
|
};
|
|
3769
3802
|
}
|
|
@@ -3798,67 +3831,56 @@ const MOONSHOT_KIMI_K3_THINKING: ThinkingConfig = { mode: "effort", efforts: [Ef
|
|
|
3798
3831
|
export function moonshotModelManagerOptions(
|
|
3799
3832
|
config?: MoonshotModelManagerConfig,
|
|
3800
3833
|
): ModelManagerOptions<"openai-completions"> {
|
|
3801
|
-
|
|
3802
|
-
|
|
3803
|
-
// inherits this baseUrl) at the Kimi China platform `api.moonshot.cn`; an
|
|
3804
|
-
// explicit `config.baseUrl` still wins. Mirrors LITELLM_BASE_URL/LM_STUDIO_BASE_URL. (#2883)
|
|
3805
|
-
const baseUrl = config?.baseUrl ?? Bun.env.MOONSHOT_BASE_URL ?? "https://api.moonshot.ai/v1";
|
|
3806
|
-
const references = createBundledReferenceMap<"openai-completions">("moonshot");
|
|
3807
|
-
return {
|
|
3834
|
+
return createOpenAICompatibleModelManagerOptions({
|
|
3835
|
+
api: "openai-completions",
|
|
3808
3836
|
providerId: "moonshot",
|
|
3809
|
-
|
|
3810
|
-
|
|
3811
|
-
|
|
3812
|
-
|
|
3813
|
-
|
|
3814
|
-
|
|
3815
|
-
|
|
3816
|
-
|
|
3817
|
-
|
|
3818
|
-
|
|
3819
|
-
|
|
3820
|
-
|
|
3821
|
-
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3826
|
-
|
|
3827
|
-
|
|
3828
|
-
|
|
3829
|
-
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
|
|
3844
|
-
|
|
3845
|
-
|
|
3846
|
-
|
|
3847
|
-
|
|
3848
|
-
|
|
3849
|
-
|
|
3850
|
-
|
|
3851
|
-
|
|
3852
|
-
|
|
3853
|
-
|
|
3854
|
-
|
|
3855
|
-
|
|
3856
|
-
};
|
|
3857
|
-
},
|
|
3858
|
-
fetch: config?.fetch,
|
|
3859
|
-
}),
|
|
3860
|
-
}),
|
|
3861
|
-
};
|
|
3837
|
+
// `MOONSHOT_BASE_URL` redirects discovery (and the streaming request that
|
|
3838
|
+
// inherits this baseUrl) at the Kimi China platform `api.moonshot.cn`; an
|
|
3839
|
+
// explicit `config.baseUrl` still wins. Mirrors LITELLM_BASE_URL/LM_STUDIO_BASE_URL. (#2883)
|
|
3840
|
+
defaultBaseUrl: Bun.env.MOONSHOT_BASE_URL ?? "https://api.moonshot.ai/v1",
|
|
3841
|
+
config,
|
|
3842
|
+
requireApiKey: true,
|
|
3843
|
+
mapModel: (entry, defaults, reference) => {
|
|
3844
|
+
const model = mapWithBundledReference(entry, defaults, reference);
|
|
3845
|
+
const id = model.id.toLowerCase();
|
|
3846
|
+
// Kimi K3 is discovered but has no bundled/models.dev reference, so the
|
|
3847
|
+
// generic dynamic defaults would report it "Free" with no capabilities
|
|
3848
|
+
// (#5756). Stamp the official pricing/limits when the endpoint doesn't
|
|
3849
|
+
// carry them, and mark it reasoning + vision. K3 always reasons via
|
|
3850
|
+
// `reasoning_effort: "max"` and does NOT use the K2.x `thinking` block,
|
|
3851
|
+
// so its thinking config is the single-tier `max` scale — the wire path
|
|
3852
|
+
// routes it through `reasoning_effort` (see `buildOpenAICompat`).
|
|
3853
|
+
if (!reference && isKimiK3ModelId(id)) {
|
|
3854
|
+
const isZeroCost = model.cost.input === 0 && model.cost.output === 0 && model.cost.cacheRead === 0;
|
|
3855
|
+
return {
|
|
3856
|
+
...model,
|
|
3857
|
+
reasoning: true,
|
|
3858
|
+
input: ["text", "image"],
|
|
3859
|
+
cost: isZeroCost ? { ...MOONSHOT_KIMI_K3_COST } : model.cost,
|
|
3860
|
+
contextWindow: model.contextWindow ?? MOONSHOT_KIMI_K3_CONTEXT_WINDOW,
|
|
3861
|
+
maxTokens: model.maxTokens ?? MOONSHOT_KIMI_K3_MAX_TOKENS,
|
|
3862
|
+
thinking: model.thinking ?? { ...MOONSHOT_KIMI_K3_THINKING },
|
|
3863
|
+
};
|
|
3864
|
+
}
|
|
3865
|
+
// Moonshot's K2.x family (K2.5, K2.6, kimi-k2-thinking, …) is reasoning-capable
|
|
3866
|
+
// and vision-capable on the native API. Without these flags the openai-completions
|
|
3867
|
+
// path skips the z.ai-format `thinking` block, and Moonshot K2.6 stalls on first
|
|
3868
|
+
// turn because its endpoint expects an explicit `thinking: {type}` (#2113). Match
|
|
3869
|
+
// the bundled K2.5 metadata for every K2.x id we discover.
|
|
3870
|
+
const isKimiK2Reasoning = id.includes("thinking") || /(^|\/)kimi-k2(?:\.\d+)?(?:[-:]|$)/.test(id);
|
|
3871
|
+
const isVision = id.includes("vision") || id.includes("vl") || /(^|\/)kimi-k2(?:\.\d+)?(?:[-:]|$)/.test(id);
|
|
3872
|
+
return {
|
|
3873
|
+
...model,
|
|
3874
|
+
reasoning: isKimiK2Reasoning || model.reasoning,
|
|
3875
|
+
input: isVision ? ["text", "image"] : model.input,
|
|
3876
|
+
thinking:
|
|
3877
|
+
model.thinking ??
|
|
3878
|
+
(isKimiK2Reasoning
|
|
3879
|
+
? { mode: "effort", efforts: [Effort.Minimal, Effort.Low, Effort.Medium, Effort.High] }
|
|
3880
|
+
: undefined),
|
|
3881
|
+
};
|
|
3882
|
+
},
|
|
3883
|
+
});
|
|
3862
3884
|
}
|
|
3863
3885
|
|
|
3864
3886
|
// ---------------------------------------------------------------------------
|
|
@@ -5508,7 +5530,14 @@ const OPENCODE_ZEN_API_RESOLUTION = createOpenCodeApiResolution("https://opencod
|
|
|
5508
5530
|
// anthropic-style requests to /v1/messages and the gateway would return its
|
|
5509
5531
|
// `Page Not Found` HTML (issue #887 for the qwen/m2.7 entries; minimax-m3
|
|
5510
5532
|
// and minimax-m3-free added under #1617 for the same root cause).
|
|
5533
|
+
//
|
|
5534
|
+
// deepseek-v4-flash is the inverse case: it falls through to
|
|
5535
|
+
// openai-completions by default, but the Go gateway's
|
|
5536
|
+
// /zen/go/v1/chat/completions route does not work for this model while
|
|
5537
|
+
// /zen/go/v1/responses does (user-verified against the live gateway,
|
|
5538
|
+
// 2026-08-08; Flash only — deepseek-v4-pro serves fine on chat completions).
|
|
5511
5539
|
const OPENCODE_GO_API_RESOLUTION = createOpenCodeApiResolution("https://opencode.ai/zen/go", {
|
|
5540
|
+
"deepseek-v4-flash": "openai-responses",
|
|
5512
5541
|
"minimax-m2.7": "openai-completions",
|
|
5513
5542
|
"minimax-m3": "openai-completions",
|
|
5514
5543
|
"minimax-m3-free": "openai-completions",
|