feat(opencode-zen): update catalog pricing and Kimi models
This commit is contained in:
parent
da71eaebd2
commit
13aff10673
@ -54,10 +54,10 @@ describe("getOpencodeZenStaticFallbackModels", () => {
|
|||||||
it("returns an array of models", () => {
|
it("returns an array of models", () => {
|
||||||
const models = getOpencodeZenStaticFallbackModels();
|
const models = getOpencodeZenStaticFallbackModels();
|
||||||
expect(Array.isArray(models)).toBe(true);
|
expect(Array.isArray(models)).toBe(true);
|
||||||
expect(models.length).toBe(9);
|
expect(models.length).toBe(11);
|
||||||
});
|
});
|
||||||
|
|
||||||
it("includes Claude, GPT, Gemini, and GLM models", () => {
|
it("includes Claude, GPT, Gemini, GLM, and Kimi models", () => {
|
||||||
const models = getOpencodeZenStaticFallbackModels();
|
const models = getOpencodeZenStaticFallbackModels();
|
||||||
const ids = models.map((m) => m.id);
|
const ids = models.map((m) => m.id);
|
||||||
|
|
||||||
@ -66,6 +66,7 @@ describe("getOpencodeZenStaticFallbackModels", () => {
|
|||||||
expect(ids).toContain("gpt-5.1-codex");
|
expect(ids).toContain("gpt-5.1-codex");
|
||||||
expect(ids).toContain("gemini-3-pro");
|
expect(ids).toContain("gemini-3-pro");
|
||||||
expect(ids).toContain("glm-4.7");
|
expect(ids).toContain("glm-4.7");
|
||||||
|
expect(ids).toContain("kimi-k2.5");
|
||||||
});
|
});
|
||||||
|
|
||||||
it("returns valid ModelDefinitionConfig objects", () => {
|
it("returns valid ModelDefinitionConfig objects", () => {
|
||||||
|
|||||||
@ -1,8 +1,9 @@
|
|||||||
/**
|
/**
|
||||||
* OpenCode Zen model catalog with dynamic fetching, caching, and static fallback.
|
* OpenCode Zen model catalog with dynamic fetching, caching, and static fallback.
|
||||||
*
|
*
|
||||||
* OpenCode Zen is a $200/month subscription that provides proxy access to multiple
|
* OpenCode Zen is a pay-as-you-go gateway that provides proxy access to multiple
|
||||||
* AI models (Claude, GPT, Gemini, etc.) through a single API endpoint.
|
* AI models (Claude, GPT, Gemini, etc.) through a single API endpoint. Pricing is
|
||||||
|
* per 1M tokens; credit card fees are passed through at cost.
|
||||||
*
|
*
|
||||||
* API endpoint: https://opencode.ai/zen/v1
|
* API endpoint: https://opencode.ai/zen/v1
|
||||||
* Auth URL: https://opencode.ai/auth
|
* Auth URL: https://opencode.ai/auth
|
||||||
@ -70,6 +71,10 @@ export const OPENCODE_ZEN_MODEL_ALIASES: Record<string, string> = {
|
|||||||
// GLM (free)
|
// GLM (free)
|
||||||
glm: "glm-4.7",
|
glm: "glm-4.7",
|
||||||
"glm-free": "glm-4.7",
|
"glm-free": "glm-4.7",
|
||||||
|
|
||||||
|
// Kimi (free)
|
||||||
|
kimi: "kimi-k2.5",
|
||||||
|
"kimi-free": "kimi-k2.5-free",
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -89,7 +94,7 @@ export function resolveOpencodeZenModelApi(modelId: string): ModelApi {
|
|||||||
if (lower.startsWith("gpt-")) {
|
if (lower.startsWith("gpt-")) {
|
||||||
return "openai-responses";
|
return "openai-responses";
|
||||||
}
|
}
|
||||||
if (lower.startsWith("claude-") || lower.startsWith("minimax-")) {
|
if (lower.startsWith("claude-") || lower.startsWith("minimax-") || lower.startsWith("kimi-")) {
|
||||||
return "anthropic-messages";
|
return "anthropic-messages";
|
||||||
}
|
}
|
||||||
if (lower.startsWith("gemini-")) {
|
if (lower.startsWith("gemini-")) {
|
||||||
@ -103,7 +108,7 @@ export function resolveOpencodeZenModelApi(modelId: string): ModelApi {
|
|||||||
*/
|
*/
|
||||||
function supportsImageInput(modelId: string): boolean {
|
function supportsImageInput(modelId: string): boolean {
|
||||||
const lower = modelId.toLowerCase();
|
const lower = modelId.toLowerCase();
|
||||||
if (lower.includes("glm") || lower.includes("minimax")) {
|
if (lower.includes("glm") || lower.includes("minimax") || lower.includes("kimi")) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
@ -113,30 +118,34 @@ const MODEL_COSTS: Record<
|
|||||||
string,
|
string,
|
||||||
{ input: number; output: number; cacheRead: number; cacheWrite: number }
|
{ input: number; output: number; cacheRead: number; cacheWrite: number }
|
||||||
> = {
|
> = {
|
||||||
"gpt-5.1-codex": {
|
|
||||||
input: 1.07,
|
|
||||||
output: 8.5,
|
|
||||||
cacheRead: 0.107,
|
|
||||||
cacheWrite: 0,
|
|
||||||
},
|
|
||||||
"claude-opus-4-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
|
||||||
"gemini-3-pro": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 },
|
|
||||||
"gpt-5.1-codex-mini": {
|
|
||||||
input: 0.25,
|
|
||||||
output: 2,
|
|
||||||
cacheRead: 0.025,
|
|
||||||
cacheWrite: 0,
|
|
||||||
},
|
|
||||||
"gpt-5.1": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 },
|
|
||||||
"glm-4.7": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
|
||||||
"gemini-3-flash": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 },
|
|
||||||
"gpt-5.1-codex-max": {
|
|
||||||
input: 1.25,
|
|
||||||
output: 10,
|
|
||||||
cacheRead: 0.125,
|
|
||||||
cacheWrite: 0,
|
|
||||||
},
|
|
||||||
"gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 },
|
"gpt-5.2": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 },
|
||||||
|
"gpt-5.2-codex": { input: 1.75, output: 14, cacheRead: 0.175, cacheWrite: 0 },
|
||||||
|
"gpt-5.1": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 },
|
||||||
|
"gpt-5.1-codex": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 },
|
||||||
|
"gpt-5.1-codex-max": { input: 1.25, output: 10, cacheRead: 0.125, cacheWrite: 0 },
|
||||||
|
"gpt-5.1-codex-mini": { input: 0.25, output: 2, cacheRead: 0.025, cacheWrite: 0 },
|
||||||
|
"gpt-5": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 },
|
||||||
|
"gpt-5-codex": { input: 1.07, output: 8.5, cacheRead: 0.107, cacheWrite: 0 },
|
||||||
|
"gpt-5-nano": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
"claude-opus-4-5": { input: 5, output: 25, cacheRead: 0.5, cacheWrite: 6.25 },
|
||||||
|
"claude-opus-4-1": { input: 15, output: 75, cacheRead: 1.5, cacheWrite: 18.75 },
|
||||||
|
"claude-sonnet-4-5": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
||||||
|
"claude-sonnet-4": { input: 3, output: 15, cacheRead: 0.3, cacheWrite: 3.75 },
|
||||||
|
"claude-haiku-4-5": { input: 1, output: 5, cacheRead: 0.1, cacheWrite: 1.25 },
|
||||||
|
"claude-3-5-haiku": { input: 0.8, output: 4, cacheRead: 0.08, cacheWrite: 1 },
|
||||||
|
"gemini-3-pro": { input: 2, output: 12, cacheRead: 0.2, cacheWrite: 0 },
|
||||||
|
"gemini-3-flash": { input: 0.5, output: 3, cacheRead: 0.05, cacheWrite: 0 },
|
||||||
|
"minimax-m2.1": { input: 0.3, output: 1.2, cacheRead: 0.1, cacheWrite: 0 },
|
||||||
|
"minimax-m2.1-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
"glm-4.7": { input: 0.6, output: 2.2, cacheRead: 0.1, cacheWrite: 0 },
|
||||||
|
"glm-4.7-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
"glm-4.6": { input: 0.6, output: 2.2, cacheRead: 0.1, cacheWrite: 0 },
|
||||||
|
"kimi-k2.5": { input: 0.6, output: 3, cacheRead: 0.08, cacheWrite: 0 },
|
||||||
|
"kimi-k2.5-free": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
"kimi-k2-thinking": { input: 0.4, output: 2.5, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
"kimi-k2": { input: 0.4, output: 2.5, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
"qwen3-coder": { input: 0.45, output: 1.5, cacheRead: 0, cacheWrite: 0 },
|
||||||
|
"big-pickle": { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
const DEFAULT_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
const DEFAULT_COST = { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 };
|
||||||
@ -151,6 +160,8 @@ const MODEL_CONTEXT_WINDOWS: Record<string, number> = {
|
|||||||
"gemini-3-flash": 1048576,
|
"gemini-3-flash": 1048576,
|
||||||
"gpt-5.1-codex-max": 400000,
|
"gpt-5.1-codex-max": 400000,
|
||||||
"gpt-5.2": 400000,
|
"gpt-5.2": 400000,
|
||||||
|
"kimi-k2.5": 256000,
|
||||||
|
"kimi-k2.5-free": 256000,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getDefaultContextWindow(modelId: string): number {
|
function getDefaultContextWindow(modelId: string): number {
|
||||||
@ -167,6 +178,8 @@ const MODEL_MAX_TOKENS: Record<string, number> = {
|
|||||||
"gemini-3-flash": 65536,
|
"gemini-3-flash": 65536,
|
||||||
"gpt-5.1-codex-max": 128000,
|
"gpt-5.1-codex-max": 128000,
|
||||||
"gpt-5.2": 128000,
|
"gpt-5.2": 128000,
|
||||||
|
"kimi-k2.5": 8192,
|
||||||
|
"kimi-k2.5-free": 8192,
|
||||||
};
|
};
|
||||||
|
|
||||||
function getDefaultMaxTokens(modelId: string): number {
|
function getDefaultMaxTokens(modelId: string): number {
|
||||||
@ -203,6 +216,8 @@ const MODEL_NAMES: Record<string, string> = {
|
|||||||
"gemini-3-flash": "Gemini 3 Flash",
|
"gemini-3-flash": "Gemini 3 Flash",
|
||||||
"gpt-5.1-codex-max": "GPT-5.1 Codex Max",
|
"gpt-5.1-codex-max": "GPT-5.1 Codex Max",
|
||||||
"gpt-5.2": "GPT-5.2",
|
"gpt-5.2": "GPT-5.2",
|
||||||
|
"kimi-k2.5": "Kimi K2.5",
|
||||||
|
"kimi-k2.5-free": "Kimi K2.5 Free",
|
||||||
};
|
};
|
||||||
|
|
||||||
function formatModelName(modelId: string): string {
|
function formatModelName(modelId: string): string {
|
||||||
@ -230,6 +245,8 @@ export function getOpencodeZenStaticFallbackModels(): ModelDefinitionConfig[] {
|
|||||||
"gemini-3-flash",
|
"gemini-3-flash",
|
||||||
"gpt-5.1-codex-max",
|
"gpt-5.1-codex-max",
|
||||||
"gpt-5.2",
|
"gpt-5.2",
|
||||||
|
"kimi-k2.5",
|
||||||
|
"kimi-k2.5-free",
|
||||||
];
|
];
|
||||||
|
|
||||||
return modelIds.map(buildModelDefinition);
|
return modelIds.map(buildModelDefinition);
|
||||||
|
|||||||
@ -588,7 +588,7 @@ export async function applyAuthChoiceApiProviders(
|
|||||||
[
|
[
|
||||||
"OpenCode Zen provides access to Claude, GPT, Gemini, and more models.",
|
"OpenCode Zen provides access to Claude, GPT, Gemini, and more models.",
|
||||||
"Get your API key at: https://opencode.ai/auth",
|
"Get your API key at: https://opencode.ai/auth",
|
||||||
"Requires an active OpenCode Zen subscription.",
|
"Billing is pay-as-you-go; add credits in the OpenCode Zen dashboard.",
|
||||||
].join("\n"),
|
].join("\n"),
|
||||||
"OpenCode Zen",
|
"OpenCode Zen",
|
||||||
);
|
);
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user