diff --git a/packages/ai/src/registry/novita.ts b/packages/ai/src/registry/novita.ts new file mode 100644 index 000000000..3b573dab6 --- /dev/null +++ b/packages/ai/src/registry/novita.ts @@ -0,0 +1,21 @@ +import { createApiKeyLogin } from "./api-key-login"; +import type { ProviderDefinition } from "./types"; + +export const loginNovita = createApiKeyLogin({ + providerLabel: "Novita", + authUrl: "https://novita.ai/settings/key-management", + instructions: "Create or copy your API key from the Novita dashboard", + promptMessage: "Paste your Novita API key", + placeholder: "sk_...", + validation: { + kind: "models-endpoint", + provider: "novita", + modelsUrl: "https://api.novita.ai/openai/v1/models", + }, +}); + +export const novitaProvider = { + id: "novita", + name: "Novita", + login: (cb: Parameters[0]) => loginNovita(cb), +} as const satisfies ProviderDefinition; diff --git a/packages/ai/src/registry/registry.ts b/packages/ai/src/registry/registry.ts index e6740996a..2d9420c49 100644 --- a/packages/ai/src/registry/registry.ts +++ b/packages/ai/src/registry/registry.ts @@ -34,6 +34,7 @@ import { minimaxCodeCnProvider } from "./minimax-code-cn"; import { mistralProvider } from "./mistral"; import { moonshotProvider } from "./moonshot"; import { nanogptProvider } from "./nanogpt"; +import { novitaProvider } from "./novita"; import { nvidiaProvider } from "./nvidia"; import { ollamaProvider } from "./ollama"; import { ollamaCloudProvider } from "./ollama-cloud"; @@ -110,6 +111,7 @@ const ALL = [ fireworksProvider, togetherProvider, nvidiaProvider, + novitaProvider, huggingfaceProvider, perplexityProvider, qianfanProvider, diff --git a/packages/catalog/src/models.json b/packages/catalog/src/models.json index 706e3b509..a4e4451e8 100644 --- a/packages/catalog/src/models.json +++ b/packages/catalog/src/models.json @@ -58324,6 +58324,2869 @@ "maxTokens": null } }, + "novita": { + "baichuan/baichuan-m2-32b": { + "id": "baichuan/baichuan-m2-32b", + "name": "BaiChuan M2 32B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.7, + "output": 0.7, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 131072, + "supportsTools": false + }, + "baidu/cobuddy": { + "id": "baidu/cobuddy", + "name": "CoBuddy", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 2.8, + "output": 11.3, + "cacheRead": 0.7, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "baidu/ernie-4.5-21B-a3b": { + "id": "baidu/ernie-4.5-21B-a3b", + "name": "ERNIE 4.5 21B A3B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.7, + "output": 2.8, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 120000, + "maxTokens": 8000, + "supportsTools": true + }, + "baidu/ernie-4.5-vl-424b-a47b": { + "id": "baidu/ernie-4.5-vl-424b-a47b", + "name": "ERNIE 4.5 VL 424B A47B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 4.2, + "output": 12.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 123000, + "maxTokens": 16000, + "supportsTools": false, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "bunny": { + "id": "bunny", + "name": "Bunny", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 32768, + "supportsTools": true + }, + "deepseek/deepseek_v3": { + "id": "deepseek/deepseek_v3", + "name": "DeepSeek V3", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 8.9, + "output": 8.9, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 64000, + "maxTokens": 16000, + "supportsTools": true + }, + "deepseek/deepseek-ocr": { + "id": "deepseek/deepseek-ocr", + "name": "DeepSeek-OCR", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0.3, + "output": 0.3, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 8192, + "supportsTools": false + }, + "deepseek/deepseek-ocr-2": { + "id": "deepseek/deepseek-ocr-2", + "name": "DeepSeek-OCR 2", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0.3, + "output": 0.3, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 8192, + "supportsTools": false + }, + "deepseek/deepseek-r1": { + "id": "deepseek/deepseek-r1", + "name": "R1", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 40, + "output": 40, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 64000, + "maxTokens": 16000, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-r1-0528": { + "id": "deepseek/deepseek-r1-0528", + "name": "R1 0528", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 7, + "output": 25, + "cacheRead": 3.5, + "cacheWrite": 0 + }, + "contextWindow": 163840, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-r1-0528-qwen3-8b": { + "id": "deepseek/deepseek-r1-0528-qwen3-8b", + "name": "DeepSeek R1 0528 Qwen3 8B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.6, + "output": 0.9, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 128000, + "maxTokens": 32000, + "supportsTools": false + }, + "deepseek/deepseek-r1-distill-llama-70b": { + "id": "deepseek/deepseek-r1-distill-llama-70b", + "name": "DeepSeek R1 Distill LLama 70B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 8, + "output": 8, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 8192, + "supportsTools": false, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-r1-turbo": { + "id": "deepseek/deepseek-r1-turbo", + "name": "DeepSeek R1 (Turbo)", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 7, + "output": 25, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 64000, + "maxTokens": 16000, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-r1/community": { + "id": "deepseek/deepseek-r1/community", + "name": "DeepSeek R1", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 40, + "output": 40, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 64000, + "maxTokens": 8000, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-v3-0324": { + "id": "deepseek/deepseek-v3-0324", + "name": "DeepSeek V3 0324", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 2.7, + "output": 11.2, + "cacheRead": 1.35, + "cacheWrite": 0 + }, + "contextWindow": 163840, + "maxTokens": 65536, + "supportsTools": true + }, + "deepseek/deepseek-v3-turbo": { + "id": "deepseek/deepseek-v3-turbo", + "name": "DeepSeek V3 (Turbo)", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 4, + "output": 13, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 64000, + "maxTokens": 16000, + "supportsTools": true + }, + "deepseek/deepseek-v3.1": { + "id": "deepseek/deepseek-v3.1", + "name": "DeepSeek V3.1", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 2.7, + "output": 10, + "cacheRead": 1.35, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-v3.1-terminus": { + "id": "deepseek/deepseek-v3.1-terminus", + "name": "DeepSeek V3.1 Terminus", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 2.7, + "output": 10, + "cacheRead": 1.35, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-v3.2": { + "id": "deepseek/deepseek-v3.2", + "name": "DeepSeek V3.2", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 2.69, + "output": 4, + "cacheRead": 1.345, + "cacheWrite": 0 + }, + "contextWindow": 163840, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-v3.2-exp": { + "id": "deepseek/deepseek-v3.2-exp", + "name": "DeepSeek V3.2 Exp", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 2.7, + "output": 4.1, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 163840, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-v3/community": { + "id": "deepseek/deepseek-v3/community", + "name": "DeepSeek V3", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 8.9, + "output": 8.9, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 64000, + "maxTokens": 8000, + "supportsTools": true + }, + "deepseek/deepseek-v4-flash": { + "id": "deepseek/deepseek-v4-flash", + "name": "DeepSeek V4 Flash", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 1.4, + "output": 2.8, + "cacheRead": 0.28, + "cacheWrite": 0 + }, + "contextWindow": 1048576, + "maxTokens": 393216, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "deepseek/deepseek-v4-pro": { + "id": "deepseek/deepseek-v4-pro", + "name": "DeepSeek V4 Pro", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 16, + "output": 32, + "cacheRead": 1.35, + "cacheWrite": 0 + }, + "contextWindow": 1048576, + "maxTokens": 393216, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "minimal": "high", + "low": "high", + "medium": "high", + "high": "high", + "xhigh": "max" + } + } + }, + "dev/glm46": { + "id": "dev/glm46", + "name": "dev/glm46", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 256000, + "maxTokens": 256000, + "supportsTools": true + }, + "google/gemma-3-12b-it": { + "id": "google/gemma-3-12b-it", + "name": "Gemma3 12B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0.5, + "output": 1, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 8192, + "supportsTools": false + }, + "google/gemma-3-27b-it": { + "id": "google/gemma-3-27b-it", + "name": "Gemma 3 27B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 1.19, + "output": 2, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 98304, + "maxTokens": 16384, + "supportsTools": false + }, + "google/gemma-4-26b-a4b-it": { + "id": "google/gemma-4-26b-a4b-it", + "name": "Gemma 4 26B A4B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 1.3, + "output": 4, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "google/gemma-4-31b-it": { + "id": "google/gemma-4-31b-it", + "name": "Gemma 4 31B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 1.4, + "output": 4, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "gryphe/mythomax-l2-13b": { + "id": "gryphe/mythomax-l2-13b", + "name": "Mythomax L2 13B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.9, + "output": 0.9, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 4096, + "maxTokens": 3200, + "supportsTools": false + }, + "gt-4p": { + "id": "gt-4p", + "name": "gt-4p", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": null, + "maxTokens": 131072, + "supportsTools": true + }, + "inclusionai/ling-2.6-1t": { + "id": "inclusionai/ling-2.6-1t", + "name": "Ling-2.6-1T", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 25, + "cacheRead": 0.6, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 32768, + "supportsTools": true + }, + "inclusionai/ling-2.6-flash": { + "id": "inclusionai/ling-2.6-flash", + "name": "Ling-2.6 Flash", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 1, + "output": 3, + "cacheRead": 0.2, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 32768, + "supportsTools": true + }, + "inclusionai/ring-2.6-1t": { + "id": "inclusionai/ring-2.6-1t", + "name": "Ring-2.6-1T", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 25, + "cacheRead": 0.6, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "kwaipilot/kat-coder-pro": { + "id": "kwaipilot/kat-coder-pro", + "name": "Kat Coder Pro", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 12, + "cacheRead": 0.6, + "cacheWrite": 0 + }, + "contextWindow": 256000, + "maxTokens": 128000, + "supportsTools": true + }, + "meta-llama/llama-3.1-8b-instruct": { + "id": "meta-llama/llama-3.1-8b-instruct", + "name": "Llama 3.1 8B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.2, + "output": 0.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 16384, + "maxTokens": 16384, + "supportsTools": false + }, + "meta-llama/llama-3.2-1b-instruct": { + "id": "meta-llama/llama-3.2-1b-instruct", + "name": "Llama 3.2 1B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.2, + "output": 0.2, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131000, + "maxTokens": 32000, + "supportsTools": false + }, + "meta-llama/llama-3.2-3b-instruct": { + "id": "meta-llama/llama-3.2-3b-instruct", + "name": "Llama 3.2 3B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.3, + "output": 0.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 32768, + "maxTokens": 32000, + "supportsTools": false + }, + "meta-llama/llama-3.3-70b-instruct": { + "id": "meta-llama/llama-3.3-70b-instruct", + "name": "Llama 3.3 70B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 1.35, + "output": 4, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 6000, + "maxTokens": 120000, + "supportsTools": true + }, + "meta-llama/llama-4-maverick-17b-128e-instruct-fp8": { + "id": "meta-llama/llama-4-maverick-17b-128e-instruct-fp8", + "name": "Llama 4 Maverick Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 2.7, + "output": 8.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 1048576, + "maxTokens": 8192, + "supportsTools": false + }, + "meta-llama/llama-4-scout-17b-16e-instruct": { + "id": "meta-llama/llama-4-scout-17b-16e-instruct", + "name": "Llama 4 Scout 17B 16E", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 1.8, + "output": 5.9, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 131072, + "supportsTools": false + }, + "microsoft/wizardlm-2-8x22b": { + "id": "microsoft/wizardlm-2-8x22b", + "name": "Wizardlm 2 8x22B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 6.2, + "output": 6.2, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 65535, + "maxTokens": 8000, + "supportsTools": false + }, + "minimax/m2-her": { + "id": "minimax/m2-her", + "name": "M2-her", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 32000, + "maxTokens": null, + "supportsTools": false + }, + "minimax/minimax-m2": { + "id": "minimax/minimax-m2", + "name": "MiniMax M2", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 12, + "cacheRead": 0.3, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "minimax/minimax-m2.1": { + "id": "minimax/minimax-m2.1", + "name": "MiniMax M2.1", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 12, + "cacheRead": 0.3, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "minimax/minimax-m2.5": { + "id": "minimax/minimax-m2.5", + "name": "MiniMax M2.5", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 12, + "cacheRead": 0.3, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131100, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "minimax/minimax-m2.5-highspeed": { + "id": "minimax/minimax-m2.5-highspeed", + "name": "MiniMax M2.5-highspeed", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 6, + "output": 24, + "cacheRead": 0.3, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131100, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "minimax/minimax-m2.7": { + "id": "minimax/minimax-m2.7", + "name": "MiniMax M2.7", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 12, + "cacheRead": 0.6, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "minimax/minimax-m2.7-highspeed": { + "id": "minimax/minimax-m2.7-highspeed", + "name": "MiniMax M2.7 highspeed", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 6, + "output": 24, + "cacheRead": 0.6, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "minimax/minimax-m3": { + "id": "minimax/minimax-m3", + "name": "MiniMax M3", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 3, + "output": 12, + "cacheRead": 0.6, + "cacheWrite": 0 + }, + "contextWindow": 1000000, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "minimaxai/minimax-m1-80k": { + "id": "minimaxai/minimax-m1-80k", + "name": "MiniMax M1", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 5.5, + "output": 22, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 1000000, + "maxTokens": 40000, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "mistralai/mistral-nemo": { + "id": "mistralai/mistral-nemo", + "name": "Mistral Nemo", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.4, + "output": 1.7, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 60288, + "maxTokens": 16000, + "supportsTools": false + }, + "moonshotai/kimi-k2-0905": { + "id": "moonshotai/kimi-k2-0905", + "name": "Kimi K2 0905", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 6, + "output": 25, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 100352, + "supportsTools": true + }, + "moonshotai/kimi-k2-instruct": { + "id": "moonshotai/kimi-k2-instruct", + "name": "Kimi K2 Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 5.7, + "output": 23, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 100352, + "supportsTools": true + }, + "moonshotai/kimi-k2-thinking": { + "id": "moonshotai/kimi-k2-thinking", + "name": "Kimi K2 Thinking", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 6, + "output": 25, + "cacheRead": 1.5, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 100352, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "requiresEffort": true + } + }, + "moonshotai/kimi-k2.5": { + "id": "moonshotai/kimi-k2.5", + "name": "Kimi K2.5", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 6, + "output": 30, + "cacheRead": 1, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 262144, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "moonshotai/kimi-k2.6": { + "id": "moonshotai/kimi-k2.6", + "name": "Kimi K2.6", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 8, + "output": 34, + "cacheRead": 1.6, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 262144, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "moonshotai/kimi-k2.7-code": { + "id": "moonshotai/kimi-k2.7-code", + "name": "Kimi K2.7 Code", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 9.5, + "output": 40, + "cacheRead": 1.9, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 262144, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "nousresearch/hermes-2-pro-llama-3-8b": { + "id": "nousresearch/hermes-2-pro-llama-3-8b", + "name": "Hermes 2 Pro Llama 3 8B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 1.4, + "output": 1.4, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 8192, + "supportsTools": false + }, + "nvidia/nemotron-3-nano-30b-a3b": { + "id": "nvidia/nemotron-3-nano-30b-a3b", + "name": "Nemotron 3 Nano 30B A3B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 0.5, + "output": 2, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "openai/gpt-oss-120b": { + "id": "openai/gpt-oss-120b", + "name": "GPT OSS 120B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 0.5, + "output": 2.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ] + } + }, + "openai/gpt-oss-20b": { + "id": "openai/gpt-oss-20b", + "name": "GPT OSS 20B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 0.4, + "output": 1.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": false, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ] + } + }, + "paddlepaddle/paddleocr-vl": { + "id": "paddlepaddle/paddleocr-vl", + "name": "PaddleOCR-VL", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0.2, + "output": 0.2, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 16384, + "maxTokens": 16384, + "supportsTools": false + }, + "qwen/qwen-2.5-72b-instruct": { + "id": "qwen/qwen-2.5-72b-instruct", + "name": "Qwen2.5 72B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 3.8, + "output": 4, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 32000, + "maxTokens": 8192, + "supportsTools": true + }, + "qwen/qwen-mt-plus": { + "id": "qwen/qwen-mt-plus", + "name": "Qwen MT Plus", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 2.5, + "output": 7.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 16384, + "maxTokens": 8192, + "supportsTools": false + }, + "qwen/qwen3-235b-a22b-fp8": { + "id": "qwen/qwen3-235b-a22b-fp8", + "name": "Qwen3 235B A22B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 2, + "output": 8, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 40960, + "maxTokens": 20000, + "supportsTools": false, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3-235b-a22b-instruct-2507": { + "id": "qwen/qwen3-235b-a22b-instruct-2507", + "name": "Qwen3 235B A22B Instruct 2507", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.9, + "output": 5.8, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 16384, + "supportsTools": true + }, + "qwen/qwen3-235b-a22b-thinking-2507": { + "id": "qwen/qwen3-235b-a22b-thinking-2507", + "name": "Qwen3 235B A22B Thinking 2507", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 3, + "output": 30, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "qwen/qwen3-coder-30b-a3b-instruct": { + "id": "qwen/qwen3-coder-30b-a3b-instruct", + "name": "Qwen3 Coder 30B A3B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.7, + "output": 2.7, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 160000, + "maxTokens": 32768, + "supportsTools": true + }, + "qwen/qwen3-coder-480b-a35b-instruct": { + "id": "qwen/qwen3-coder-480b-a35b-instruct", + "name": "Qwen3 Coder 480B A35B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 3.8, + "output": 15.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true + }, + "qwen/qwen3-coder-next": { + "id": "qwen/qwen3-coder-next", + "name": "Qwen3 Coder Next", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 2, + "output": 15, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true + }, + "qwen/qwen3-max": { + "id": "qwen/qwen3-max", + "name": "Qwen3 Max", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 21.1, + "output": 84.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true + }, + "qwen/qwen3-next-80b-a3b-instruct": { + "id": "qwen/qwen3-next-80b-a3b-instruct", + "name": "Qwen3-Next-80B-A3B-Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 1.5, + "output": 15, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true + }, + "qwen/qwen3-omni-30b-a3b-instruct": { + "id": "qwen/qwen3-omni-30b-a3b-instruct", + "name": "Qwen3 Omni 30B A3B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 2.5, + "output": 9.7, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 65536, + "maxTokens": 16384, + "supportsTools": true + }, + "qwen/qwen3-omni-30b-a3b-thinking": { + "id": "qwen/qwen3-omni-30b-a3b-thinking", + "name": "Qwen3 Omni 30B A3B Thinking", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 2.5, + "output": 9.7, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 65536, + "maxTokens": 16384, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "qwen/qwen3-vl-235b-a22b-instruct": { + "id": "qwen/qwen3-vl-235b-a22b-instruct", + "name": "Qwen3 VL 235B A22B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 3, + "output": 15, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true + }, + "qwen/qwen3-vl-235b-a22b-thinking": { + "id": "qwen/qwen3-vl-235b-a22b-thinking", + "name": "Qwen3 VL 235B A22B Thinking", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 9.8, + "output": 39.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ], + "requiresEffort": true + } + }, + "qwen/qwen3-vl-30b-a3b-instruct": { + "id": "qwen/qwen3-vl-30b-a3b-instruct", + "name": "Qwen3 VL 30B A3B Instruct", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 2, + "output": 7, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true + }, + "qwen/qwen3.5-122b-a10b": { + "id": "qwen/qwen3.5-122b-a10b", + "name": "Qwen3.5 122B-A10B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 4, + "output": 32, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.5-27b": { + "id": "qwen/qwen3.5-27b", + "name": "Qwen3.5-27B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 3, + "output": 24, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.5-35b-a3b": { + "id": "qwen/qwen3.5-35b-a3b", + "name": "Qwen3.5-35B-A3B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 2.5, + "output": 20, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.5-397b-a17b": { + "id": "qwen/qwen3.5-397b-a17b", + "name": "Qwen3.5 397B A17B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 6, + "output": 36, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.5-plus": { + "id": "qwen/qwen3.5-plus", + "name": "Qwen3.5 Plus", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 1000000, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.6-27b": { + "id": "qwen/qwen3.6-27b", + "name": "Qwen3.6 27B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 6, + "output": 36, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.6-35b-a3b": { + "id": "qwen/qwen3.6-35b-a3b", + "name": "Qwen3.6-35B-A3B", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 2.48, + "output": 14.85, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.6-plus": { + "id": "qwen/qwen3.6-plus", + "name": "Qwen3.6 Plus", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 1000000, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "qwen/qwen3.7-max": { + "id": "qwen/qwen3.7-max", + "name": "Qwen3.7 Max", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 12.5, + "output": 37.5, + "cacheRead": 2.5, + "cacheWrite": 0 + }, + "contextWindow": 1000000, + "maxTokens": 65536, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high" + ] + } + }, + "sao10k/l3-70b-euryale-v2.1": { + "id": "sao10k/l3-70b-euryale-v2.1", + "name": "L3 70B Euryale V2.1", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 14.8, + "output": 14.8, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 8192, + "supportsTools": true + }, + "sao10k/l3-8b-lunaris": { + "id": "sao10k/l3-8b-lunaris", + "name": "Sao10k L3 8B Lunaris", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.5, + "output": 0.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 8192, + "supportsTools": false + }, + "Sao10K/L3-8B-Stheno-v3.2": { + "id": "Sao10K/L3-8B-Stheno-v3.2", + "name": "L3 8B Stheno V3.2", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 0.5, + "output": 0.5, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 32000, + "supportsTools": true + }, + "sao10k/l31-70b-euryale-v2.2": { + "id": "sao10k/l31-70b-euryale-v2.2", + "name": "L31 70B Euryale V2.2", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 14.8, + "output": 14.8, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 8192, + "maxTokens": 8192, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "stepfun/step-3.7-flash": { + "id": "stepfun/step-3.7-flash", + "name": "Step 3.7 Flash", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 2, + "output": 11.5, + "cacheRead": 0.4, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 256000, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "tencent/hy3": { + "id": "tencent/hy3", + "name": "Hy3", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 0, + "output": 0, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 262144, + "maxTokens": 262144, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "thudm/glm-4-32b-0414": { + "id": "thudm/glm-4-32b-0414", + "name": "GLM-4-32B-0414", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text" + ], + "cost": { + "input": 5.5, + "output": 16.6, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 32000, + "maxTokens": 32000, + "supportsTools": true + }, + "xiaomimimo/mimo-v2.5": { + "id": "xiaomimimo/mimo-v2.5", + "name": "XiaomiMiMo/MiMo-V2.5", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 1.68, + "output": 3.36, + "cacheRead": 0.034, + "cacheWrite": 0 + }, + "contextWindow": 1048576, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ] + } + }, + "xiaomimimo/mimo-v2.5-pro": { + "id": "xiaomimimo/mimo-v2.5-pro", + "name": "XiaomiMiMo/MiMo-V2.5-Pro", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 5.22, + "output": 10.44, + "cacheRead": 0.043, + "cacheWrite": 0 + }, + "contextWindow": 1048576, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "low", + "medium", + "high" + ] + } + }, + "zai-org/autoglm-phone-9b-multilingual": { + "id": "zai-org/autoglm-phone-9b-multilingual", + "name": "AutoGLM-Phone-9B-Multilingual", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": false, + "input": [ + "text", + "image" + ], + "cost": { + "input": 0.35, + "output": 1.38, + "cacheRead": 0, + "cacheWrite": 0 + }, + "contextWindow": 65536, + "maxTokens": 65536, + "supportsTools": false + }, + "zai-org/glm-4.5-air": { + "id": "zai-org/glm-4.5-air", + "name": "zai-org/glm-4.5-air", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 1.3, + "output": 8.5, + "cacheRead": 0.25, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 98304, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-4.5v": { + "id": "zai-org/glm-4.5v", + "name": "GLM 4.5V", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 6, + "output": 18, + "cacheRead": 1.1, + "cacheWrite": 0 + }, + "contextWindow": 65536, + "maxTokens": 16384, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-4.6": { + "id": "zai-org/glm-4.6", + "name": "GLM 4.6", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 5.5, + "output": 22, + "cacheRead": 1.1, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-4.6v": { + "id": "zai-org/glm-4.6v", + "name": "GLM 4.6V", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 3, + "output": 9, + "cacheRead": 0.55, + "cacheWrite": 0 + }, + "contextWindow": 131072, + "maxTokens": 32768, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-4.7": { + "id": "zai-org/glm-4.7", + "name": "GLM 4.7", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 6, + "output": 22, + "cacheRead": 1.1, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-4.7-flash": { + "id": "zai-org/glm-4.7-flash", + "name": "GLM 4.7 Flash", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 0.7, + "output": 4, + "cacheRead": 0.1, + "cacheWrite": 0 + }, + "contextWindow": 200000, + "maxTokens": 128000, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-4.7-h": { + "id": "zai-org/glm-4.7-h", + "name": "GLM-4.7", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 6, + "output": 22, + "cacheRead": 1.1, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-5": { + "id": "zai-org/glm-5", + "name": "GLM 5", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 10, + "output": 32, + "cacheRead": 2, + "cacheWrite": 0 + }, + "contextWindow": 202800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-5-turbo": { + "id": "zai-org/glm-5-turbo", + "name": "GLM-5-Turbo", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 12, + "output": 40, + "cacheRead": 2.4, + "cacheWrite": 0 + }, + "contextWindow": 202800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-5.1": { + "id": "zai-org/glm-5.1", + "name": "GLM 5.1", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 13.8, + "output": 44, + "cacheRead": 2.6, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + }, + "zai-org/glm-5.2": { + "id": "zai-org/glm-5.2", + "name": "GLM 5.2", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text" + ], + "cost": { + "input": 14, + "output": 44, + "cacheRead": 2.6, + "cacheWrite": 0 + }, + "contextWindow": 1048576, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ], + "effortMap": { + "xhigh": "max" + } + } + }, + "zai-org/glm-5v-turbo": { + "id": "zai-org/glm-5v-turbo", + "name": "GLM-5V-Turbo", + "api": "openai-completions", + "provider": "novita", + "baseUrl": "https://api.novita.ai/openai/v1", + "reasoning": true, + "input": [ + "text", + "image" + ], + "cost": { + "input": 12, + "output": 40, + "cacheRead": 2.4, + "cacheWrite": 0 + }, + "contextWindow": 204800, + "maxTokens": 131072, + "supportsTools": true, + "thinking": { + "mode": "effort", + "efforts": [ + "minimal", + "low", + "medium", + "high", + "xhigh" + ] + } + } + }, "ollama-cloud": { "cogito-2.1:671b": { "id": "cogito-2.1:671b", @@ -92710,4 +95573,4 @@ } } } -} \ No newline at end of file +} diff --git a/packages/catalog/src/provider-models/descriptors.ts b/packages/catalog/src/provider-models/descriptors.ts index 29a80ecf4..f993a6538 100644 --- a/packages/catalog/src/provider-models/descriptors.ts +++ b/packages/catalog/src/provider-models/descriptors.ts @@ -29,6 +29,7 @@ import { mistralModelManagerOptions, moonshotModelManagerOptions, nanoGptModelManagerOptions, + novitaModelManagerOptions, nvidiaModelManagerOptions, ollamaModelManagerOptions, openaiModelManagerOptions, @@ -271,6 +272,13 @@ export const CATALOG_PROVIDERS = [ createModelManagerOptions: (config: ModelManagerConfig) => nvidiaModelManagerOptions(config), catalogDiscovery: { label: "NVIDIA" }, }, + { + id: "novita", + defaultModel: "moonshotai/kimi-k2.7-code", + envVars: ["NOVITA_API_KEY"], + createModelManagerOptions: (config: ModelManagerConfig) => novitaModelManagerOptions(config), + catalogDiscovery: { label: "Novita", allowUnauthenticated: true }, + }, { id: "ollama", defaultModel: "gpt-oss:20b", diff --git a/packages/catalog/src/provider-models/openai-compat.ts b/packages/catalog/src/provider-models/openai-compat.ts index b3e4af403..2e8cd4438 100644 --- a/packages/catalog/src/provider-models/openai-compat.ts +++ b/packages/catalog/src/provider-models/openai-compat.ts @@ -971,6 +971,100 @@ export function nvidiaModelManagerOptions( return createSimpleOpenAICompletionsOptions("nvidia", "https://integrate.api.nvidia.com/v1", config); } +// --------------------------------------------------------------------------- +// 5.5 Novita +// --------------------------------------------------------------------------- + +export interface NovitaModelManagerConfig { + apiKey?: string; + baseUrl?: string; + fetch?: FetchImpl; +} + +function novitaArrayIncludes(value: unknown, expected: string): boolean { + return Array.isArray(value) && value.some(item => item === expected); +} + +function isPublicNovitaModelId(id: string): boolean { + return !id.toLowerCase().startsWith("ai_infer_test"); +} + +function toNovitaCostPerMillion(value: unknown): number { + return toPositiveNumber(value, 0) / 1000; +} + +function getNovitaCacheReadPricePerMillion(entry: OpenAICompatibleModelRecord): number { + const pricing = entry.pricing; + if (!isRecord(pricing)) { + return 0; + } + const cacheRead = pricing.input_cache_read; + if (!isRecord(cacheRead)) { + return 0; + } + return toNovitaCostPerMillion(cacheRead.price_per_m); +} + +function mapNovitaModel( + entry: OpenAICompatibleModelRecord, + defaults: ModelSpec<"openai-completions">, + reference: ModelSpec<"openai-completions"> | undefined, +): ModelSpec<"openai-completions"> { + const model = mapWithBundledReference( + { + ...entry, + name: entry.display_name ?? entry.title ?? entry.name, + }, + defaults, + reference, + ); + return { + ...model, + reasoning: novitaArrayIncludes(entry.features, "reasoning"), + supportsTools: novitaArrayIncludes(entry.features, "function-calling"), + input: toInputCapabilities(entry.input_modalities), + cost: { + input: toNovitaCostPerMillion(entry.input_token_price_per_m), + output: toNovitaCostPerMillion(entry.output_token_price_per_m), + cacheRead: getNovitaCacheReadPricePerMillion(entry), + cacheWrite: 0, + }, + contextWindow: toPositiveNumber(entry.context_size, model.contextWindow), + maxTokens: toPositiveNumber(entry.max_output_tokens, model.maxTokens), + }; +} + +export function novitaModelManagerOptions( + config?: NovitaModelManagerConfig, +): ModelManagerOptions<"openai-completions"> { + const apiKey = config?.apiKey; + const baseUrl = config?.baseUrl ?? "https://api.novita.ai/openai/v1"; + const references = createBundledReferenceMap<"openai-completions">( + "novita" as Parameters[0], + ); + return { + providerId: "novita", + fetchDynamicModels: async () => + fetchOpenAICompatibleModels({ + api: "openai-completions", + provider: "novita", + baseUrl, + apiKey, + mapModel: (entry, defaults) => mapNovitaModel(entry, defaults, references.get(defaults.id)), + filterModel: (entry, model) => { + const active = typeof entry.status !== "number" || entry.status === 1; + return ( + active && + isPublicNovitaModelId(model.id) && + novitaArrayIncludes(entry.endpoints, "chat/completions") && + model.maxTokens !== 0 + ); + }, + fetch: config?.fetch, + }), + }; +} + // --------------------------------------------------------------------------- // 6. xAI // --------------------------------------------------------------------------- diff --git a/packages/catalog/test/novita-provider.test.ts b/packages/catalog/test/novita-provider.test.ts new file mode 100644 index 000000000..f737ec9dc --- /dev/null +++ b/packages/catalog/test/novita-provider.test.ts @@ -0,0 +1,97 @@ +import { describe, expect, test } from "bun:test"; +import { getOAuthProviders } from "@oh-my-pi/pi-ai/registry/oauth"; +import { getEnvApiKey } from "@oh-my-pi/pi-ai/stream"; +import { DEFAULT_MODEL_PER_PROVIDER, PROVIDER_DESCRIPTORS } from "@oh-my-pi/pi-catalog/provider-models/descriptors"; +import { novitaModelManagerOptions } from "@oh-my-pi/pi-catalog/provider-models/openai-compat"; + +describe("Novita built-in provider", () => { + test("registers catalog descriptor with NOVITA_API_KEY env discovery", () => { + const descriptor = PROVIDER_DESCRIPTORS.find(item => item.providerId === "novita"); + expect(descriptor).toBeDefined(); + expect(descriptor?.defaultModel).toBe("moonshotai/kimi-k2.7-code"); + expect(descriptor?.catalogDiscovery?.envVars).toContain("NOVITA_API_KEY"); + expect(descriptor?.catalogDiscovery?.allowUnauthenticated).toBe(true); + expect(DEFAULT_MODEL_PER_PROVIDER.novita).toBe("moonshotai/kimi-k2.7-code"); + }); + + test("registers Novita as an API-key login provider", () => { + const provider = getOAuthProviders().find(item => item.id === "novita"); + expect(provider?.name).toBe("Novita"); + expect(provider?.available).toBe(true); + }); + + test("resolves NOVITA_API_KEY via env", () => { + const previous = Bun.env.NOVITA_API_KEY; + Bun.env.NOVITA_API_KEY = "novita-test-key"; + try { + expect(getEnvApiKey("novita")).toBe("novita-test-key"); + } finally { + if (previous === undefined) { + delete Bun.env.NOVITA_API_KEY; + } else { + Bun.env.NOVITA_API_KEY = previous; + } + } + }); + + test("maps Novita model catalog metadata from the public OpenAI-compatible endpoint", async () => { + const requests: string[] = []; + const fetchMock = async (input: string | URL | Request): Promise => { + requests.push(input.toString()); + return Response.json({ + data: [ + { + id: "moonshotai/kimi-k2.7-code", + display_name: "Kimi K2.7 Code", + status: 1, + context_size: 262144, + max_output_tokens: 131072, + input_token_price_per_m: 9500, + output_token_price_per_m: 40000, + pricing: { + input_cache_read: { + price_per_m: 1900, + }, + }, + features: ["serverless", "function-calling", "structured-outputs", "reasoning"], + endpoints: ["chat/completions", "anthropic"], + input_modalities: ["text", "image", "video"], + }, + { + id: "qwen/qwen3-8b-fp8", + status: 4, + context_size: 128000, + max_output_tokens: 20000, + endpoints: ["chat/completions"], + input_modalities: ["text"], + }, + { + id: "ai_infer_test_1", + status: 1, + context_size: 200000, + max_output_tokens: 200000, + features: ["function-calling"], + endpoints: ["chat/completions"], + input_modalities: ["text"], + }, + ], + }); + }; + + const options = novitaModelManagerOptions({ fetch: fetchMock }); + const models = await options.fetchDynamicModels?.(); + const model = models?.find(item => item.id === "moonshotai/kimi-k2.7-code"); + + expect(requests).toEqual(["https://api.novita.ai/openai/v1/models"]); + expect(models?.map(item => item.id)).toEqual(["moonshotai/kimi-k2.7-code"]); + expect(model?.provider).toBe("novita"); + expect(model?.baseUrl).toBe("https://api.novita.ai/openai/v1"); + expect(model?.name).toBe("Kimi K2.7 Code"); + expect(model?.reasoning).toBe(true); + expect(model?.supportsTools).toBe(true); + expect(model?.input).toEqual(["text", "image"]); + expect(model?.cost).toEqual({ input: 9.5, output: 40, cacheRead: 1.9, cacheWrite: 0 }); + expect(model?.contextWindow).toBe(262144); + expect(model?.maxTokens).toBe(131072); + }); +});