From 7f7c7f969eba5149b347b33c942b286d28b57242 Mon Sep 17 00:00:00 2001 From: Oleg Shulyakov Date: Tue, 30 Sep 2025 00:17:23 +0300 Subject: [PATCH] feat(api): add NVIDIA NIM provider support - Implement NvidiaNimProvider extending CloudOpenAIProvider - Add model conversion logic for NVIDIA's API format - Register 'nvidia' provider type in inference provider factory - Update provider name from 'Nvidia' to 'Nvidia NIM' - Consolidate JSDoc comments across OpenAI provider implementations --- src/api/providers/BaseOpenAIProvider.ts | 6 ++- src/api/providers/GroqProvider.ts | 16 +----- src/api/providers/NvidiaNimProvider.ts | 69 +++++++++++++++++++++++++ src/api/providers/OpenRouterProvider.ts | 11 +--- src/api/providers/index.ts | 4 ++ src/config/inference-providers.json | 2 +- 6 files changed, 81 insertions(+), 27 deletions(-) create mode 100644 src/api/providers/NvidiaNimProvider.ts diff --git a/src/api/providers/BaseOpenAIProvider.ts b/src/api/providers/BaseOpenAIProvider.ts index 386f2fd..07c32ac 100644 --- a/src/api/providers/BaseOpenAIProvider.ts +++ b/src/api/providers/BaseOpenAIProvider.ts @@ -370,7 +370,11 @@ export class BaseOpenAIProvider * @protected */ protected jsonToModel(m: unknown): InferenceApiModel { - return m as InferenceApiModel; + const model = m as InferenceApiModel; + return { + ...model, + name: model.name || model.id, + }; } /** diff --git a/src/api/providers/GroqProvider.ts b/src/api/providers/GroqProvider.ts index 1c2c228..717b80f 100644 --- a/src/api/providers/GroqProvider.ts +++ b/src/api/providers/GroqProvider.ts @@ -55,21 +55,7 @@ export class GroqProvider extends CloudOpenAIProvider { return new GroqProvider(baseUrl, apiKey); } - /** - * Converts a raw Grok model response object into a standardized InferenceApiModel. - * - * This method transforms the Grok-specific model response format into the common - * {@link InferenceApiModel} interface used across all providers. The model name - * is formatted as "{owned_by}: {id}" for better user readability and organization - * context. - * - * @param m - The raw model object received from the Grok API. - * @returns A standardized InferenceApiModel object with id, name, and created fields. - * - * @internal - * @override - * @inheritdoc - */ + /** @inheritdoc */ protected jsonToModel(m: unknown): InferenceApiModel { const model = m as GroqModel; diff --git a/src/api/providers/NvidiaNimProvider.ts b/src/api/providers/NvidiaNimProvider.ts new file mode 100644 index 0000000..1334f5b --- /dev/null +++ b/src/api/providers/NvidiaNimProvider.ts @@ -0,0 +1,69 @@ +import { InferenceApiModel } from '../../types'; +import { CloudOpenAIProvider } from './BaseOpenAIProvider'; + +/** + * Represents a model available on the NVIDIA NIM API. + * + * This interface mirrors the structure of models returned by NVIDIA's OpenAI-compatible API endpoint. + */ +interface NvidiaModel { + id: string; + object: string; + created: number; + owned_by: string; + root: string; + parent: string; + max_model_len: number; + permission: Permission[]; +} +export interface Permission { + id: string; + object: string; + created: number; + allow_create_engine: boolean; + allow_sampling: boolean; + allow_logprobs: boolean; + allow_search_indices: boolean; + allow_view: boolean; + allow_fine_tuning: boolean; + organization: string; + group: string; + is_blocking: boolean; +} + +/** + * NVIDIA NIM provider implementation for the OpenAI-compatible API. + * + * Extends {@link CloudOpenAIProvider} to handle NVIDIA's model format and API endpoints. + * Automatically converts NVIDIA model responses into the standard {@link InferenceApiModel} format. + * + * @see https://docs.nvidia.com/nim/large-language-models/latest/api-reference.html + * + * @example + * const nvidiaProvider = NvidiaProvider.new('https://integrate.api.nvidia.com', 'your-api-key');(); + */ +export class NvidiaNimProvider extends CloudOpenAIProvider { + /** + * Creates a new instance of the NVIDIA provider. + * + * @param baseUrl - Optional base URL for the NVIDIA API endpoint. + * Defaults to the standard NVIDIA OpenAI-compatible endpoint if not provided. + * @param apiKey - API key for authentication with NVIDIA's service. + * Must be provided unless using a different auth mechanism. + * @returns A new configured `NvidiaProvider` instance. + */ + static new(baseUrl?: string, apiKey: string = ''): NvidiaNimProvider { + return new NvidiaNimProvider(baseUrl, apiKey); + } + + /** @inheritdoc */ + protected jsonToModel(m: unknown): InferenceApiModel { + const model = m as NvidiaModel; + + return { + id: model.id, + name: model.id, + created: model.created, + }; + } +} diff --git a/src/api/providers/OpenRouterProvider.ts b/src/api/providers/OpenRouterProvider.ts index af61b33..e59745f 100644 --- a/src/api/providers/OpenRouterProvider.ts +++ b/src/api/providers/OpenRouterProvider.ts @@ -71,16 +71,7 @@ export class OpenRouterProvider extends CloudOpenAIProvider { return true; } - /** - * Converts raw OpenRouter API model data into the standardized `InferenceApiModel` format. - * - * This method safely extracts and maps model metadata from the OpenRouter response schema - * to the application's internal model representation. - * - * @param m - Raw model data received from OpenRouter API (unknown type for safety) - * @returns A normalized `InferenceApiModel` object with id, name, created, description, and modalities - * @throws Will throw if `m` is not a valid OpenRouterModel or required fields are missing - */ + /** @inheritdoc */ protected jsonToModel(m: unknown): InferenceApiModel { const model = m as OpenRouterModel; return { diff --git a/src/api/providers/index.ts b/src/api/providers/index.ts index c16bd37..c3eb706 100644 --- a/src/api/providers/index.ts +++ b/src/api/providers/index.ts @@ -4,6 +4,7 @@ import { GoogleProvider } from './GoogleProvider'; import { GroqProvider } from './GroqProvider'; import { LlamaCppProvider } from './LlamaCppProvider'; import { MistralProvider } from './MistralProvider'; +import { NvidiaNimProvider } from './NvidiaNimProvider'; import { OpenRouterProvider } from './OpenRouterProvider'; const PROVIDER_CACHE = new Map(); @@ -40,6 +41,9 @@ export function getInferenceProvider( case 'mistral': provider = MistralProvider.new(baseUrl, apiKey); break; + case 'nvidia': + provider = NvidiaNimProvider.new(baseUrl, apiKey); + break; default: provider = BaseOpenAIProvider.new(baseUrl, apiKey); } diff --git a/src/config/inference-providers.json b/src/config/inference-providers.json index e5b31f9..4e7434b 100644 --- a/src/config/inference-providers.json +++ b/src/config/inference-providers.json @@ -127,7 +127,7 @@ }, "nvidia": { "baseUrl": "https://integrate.api.nvidia.com", - "name": "Nvidia", + "name": "Nvidia NIM", "icon": "assets/providers/nvidia.svg", "allowCustomBaseUrl": false, "isKeyRequired": true