Add NVIDIA NIM provider
This commit is contained in:
@@ -32,12 +32,17 @@ interface ModelsDevModel {
|
||||
};
|
||||
modalities?: {
|
||||
input?: string[];
|
||||
output?: string[];
|
||||
};
|
||||
provider?: {
|
||||
npm?: string;
|
||||
};
|
||||
}
|
||||
|
||||
interface NvidiaNimModelListItem {
|
||||
id: string;
|
||||
}
|
||||
|
||||
interface AiGatewayModel {
|
||||
id: string;
|
||||
name?: string;
|
||||
@@ -117,6 +122,39 @@ const TOGETHER_TOGGLE_REASONING_LEVEL_MAP = {
|
||||
|
||||
const AI_GATEWAY_MODELS_URL = "https://ai-gateway.vercel.sh/v1";
|
||||
const AI_GATEWAY_BASE_URL = "https://ai-gateway.vercel.sh";
|
||||
const NVIDIA_BASE_URL = "https://integrate.api.nvidia.com/v1";
|
||||
const NVIDIA_HEADERS = {
|
||||
"NVCF-POLL-SECONDS": "3600",
|
||||
} as const;
|
||||
const NVIDIA_OPENAI_COMPAT: OpenAICompletionsCompat = {
|
||||
supportsStore: false,
|
||||
supportsDeveloperRole: false,
|
||||
supportsReasoningEffort: false,
|
||||
maxTokensField: "max_tokens",
|
||||
supportsStrictMode: false,
|
||||
supportsLongCacheRetention: false,
|
||||
};
|
||||
const NVIDIA_NIM_UNSUPPORTED_MODELS = new Set([
|
||||
"abacusai/dracarys-llama-3.1-70b-instruct",
|
||||
"bytedance/seed-oss-36b-instruct",
|
||||
"deepseek-ai/deepseek-v4-flash",
|
||||
"deepseek-ai/deepseek-v4-pro",
|
||||
"google/gemma-2-2b-it",
|
||||
"google/gemma-3n-e2b-it",
|
||||
"google/gemma-3n-e4b-it",
|
||||
"google/gemma-4-31b-it",
|
||||
"meta/llama-3.2-1b-instruct",
|
||||
"meta/llama-4-maverick-17b-128e-instruct",
|
||||
"microsoft/phi-4-mini-instruct",
|
||||
"minimaxai/minimax-m2.7",
|
||||
"mistralai/mistral-nemotron",
|
||||
"nvidia/nemotron-mini-4b-instruct",
|
||||
"qwen/qwen3-next-80b-a3b-instruct",
|
||||
"qwen/qwen3.5-122b-a10b",
|
||||
"qwen/qwen3.5-397b-a17b",
|
||||
"sarvamai/sarvam-m",
|
||||
"upstage/solar-10.7b-instruct",
|
||||
]);
|
||||
const ZAI_TOOL_STREAM_UNSUPPORTED_MODELS = new Set(["glm-4.5", "glm-4.5-air", "glm-4.5-flash", "glm-4.5v"]);
|
||||
const EAGER_TOOL_INPUT_STREAMING_UNSUPPORTED_ANTHROPIC_MODELS = new Set([
|
||||
"github-copilot:claude-haiku-4.5",
|
||||
@@ -312,6 +350,30 @@ function getBedrockBaseUrl(modelId: string): string {
|
||||
: "https://bedrock-runtime.us-east-1.amazonaws.com";
|
||||
}
|
||||
|
||||
function normalizeNvidiaModelId(modelId: string): string {
|
||||
return modelId.toLowerCase().replaceAll("_", ".");
|
||||
}
|
||||
|
||||
async function fetchNvidiaNimModelIds(): Promise<Map<string, string>> {
|
||||
try {
|
||||
console.log("Fetching models from NVIDIA NIM API...");
|
||||
const response = await fetch(`${NVIDIA_BASE_URL}/models`);
|
||||
const data = (await response.json()) as { data?: NvidiaNimModelListItem[] };
|
||||
const modelIds = new Map<string, string>();
|
||||
|
||||
for (const model of data.data ?? []) {
|
||||
modelIds.set(model.id, model.id);
|
||||
modelIds.set(normalizeNvidiaModelId(model.id), model.id);
|
||||
}
|
||||
|
||||
console.log(`Fetched ${data.data?.length ?? 0} model IDs from NVIDIA NIM`);
|
||||
return modelIds;
|
||||
} catch (error) {
|
||||
console.error("Failed to fetch NVIDIA NIM models:", error);
|
||||
return new Map();
|
||||
}
|
||||
}
|
||||
|
||||
async function fetchOpenRouterModels(): Promise<Model<any>[]> {
|
||||
try {
|
||||
console.log("Fetching models from OpenRouter API...");
|
||||
@@ -435,6 +497,7 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||
const data = await response.json();
|
||||
|
||||
const models: Model<any>[] = [];
|
||||
const nvidiaNimModelIds = data.nvidia?.models ? await fetchNvidiaNimModelIds() : new Map<string, string>();
|
||||
|
||||
// Process Amazon Bedrock models
|
||||
if (data["amazon-bedrock"]?.models) {
|
||||
@@ -836,6 +899,40 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||
}
|
||||
}
|
||||
|
||||
// Process NVIDIA NIM models
|
||||
if (data.nvidia?.models) {
|
||||
for (const [modelId, model] of Object.entries(data.nvidia.models)) {
|
||||
const m = model as ModelsDevModel;
|
||||
if (m.tool_call !== true) continue;
|
||||
if (!m.modalities?.input?.includes("text")) continue;
|
||||
if (!m.modalities?.output?.includes("text")) continue;
|
||||
|
||||
const liveModelId = nvidiaNimModelIds.get(modelId) ?? nvidiaNimModelIds.get(normalizeNvidiaModelId(modelId));
|
||||
if (!liveModelId) continue;
|
||||
if (NVIDIA_NIM_UNSUPPORTED_MODELS.has(liveModelId)) continue;
|
||||
|
||||
models.push({
|
||||
id: liveModelId,
|
||||
name: m.name || liveModelId,
|
||||
api: "openai-completions",
|
||||
provider: "nvidia",
|
||||
baseUrl: NVIDIA_BASE_URL,
|
||||
headers: { ...NVIDIA_HEADERS },
|
||||
reasoning: m.reasoning === true,
|
||||
input: m.modalities.input.includes("image") ? ["text", "image"] : ["text"],
|
||||
cost: {
|
||||
input: m.cost?.input || 0,
|
||||
output: m.cost?.output || 0,
|
||||
cacheRead: m.cost?.cache_read || 0,
|
||||
cacheWrite: m.cost?.cache_write || 0,
|
||||
},
|
||||
compat: NVIDIA_OPENAI_COMPAT,
|
||||
contextWindow: m.limit?.context || 4096,
|
||||
maxTokens: m.limit?.output || 4096,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Process Together AI models
|
||||
const togetherProvider = data.together ?? data.togetherai ?? data["together-ai"];
|
||||
if (togetherProvider?.models) {
|
||||
|
||||
Reference in New Issue
Block a user