"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.LmChatNvidia = void 0;
const openai_1 = require("@langchain/openai");
const ai_utilities_1 = require("@n8n/ai-utilities");
const n8n_workflow_1 = require("n8n-workflow");
const error_handling_1 = require("../../vendors/OpenAi/helpers/error-handling");
const NEMOTRON_FALLBACK_MODELS = [
    'nvidia/llama-3.3-nemotron-super-49b-v1',
    'nvidia/llama-3.1-nemotron-70b-instruct',
    'nvidia/llama-3.1-nemotron-nano-8b-v1',
    'nvidia/nemotron-4-340b-instruct',
    'nvidia/nemotron-mini-4b-instruct',
];
class LmChatNvidia {
    constructor() {
        this.description = {
            displayName: 'NVIDIA Nemotron Chat Model',
            name: 'lmChatNvidia',
            icon: { light: 'file:nvidia.svg', dark: 'file:nvidia.dark.svg' },
            group: ['transform'],
            version: [1],
            description: 'NVIDIA Nemotron models from build.nvidia.com or self-hosted NIM',
            defaults: {
                name: 'NVIDIA Nemotron Chat Model',
            },
            codex: {
                categories: ['AI'],
                subcategories: {
                    AI: ['Language Models', 'Root Nodes'],
                    'Language Models': ['Chat Models (Recommended)'],
                },
                resources: {
                    primaryDocumentation: [
                        {
                            url: 'https://docs.n8n.io/integrations/builtin/cluster-nodes/sub-nodes/n8n-nodes-langchain.lmchatnvidia/',
                        },
                    ],
                },
            },
            inputs: [],
            outputs: [n8n_workflow_1.NodeConnectionTypes.AiLanguageModel],
            outputNames: ['Model'],
            credentials: [
                {
                    name: 'nvidiaApi',
                    required: true,
                },
            ],
            requestDefaults: {
                ignoreHttpStatusErrors: true,
                baseURL: '={{ $credentials?.url }}',
            },
            properties: [
                (0, ai_utilities_1.getConnectionHintNoticeField)([n8n_workflow_1.NodeConnectionTypes.AiChain, n8n_workflow_1.NodeConnectionTypes.AiAgent]),
                {
                    displayName: 'If using JSON response format, you must include word "json" in the prompt in your chain or agent.',
                    name: 'notice',
                    type: 'notice',
                    default: '',
                    displayOptions: {
                        show: {
                            '/options.responseFormat': ['json_object'],
                        },
                    },
                },
                {
                    displayName: 'Model',
                    name: 'model',
                    type: 'options',
                    description: 'The Nemotron model which will generate the completion. <a href="https://build.nvidia.com/models">Learn more</a>.',
                    typeOptions: {
                        loadOptions: {
                            routing: {
                                request: {
                                    method: 'GET',
                                    url: '/models',
                                },
                                output: {
                                    postReceive: [
                                        {
                                            type: 'rootProperty',
                                            properties: {
                                                property: 'data',
                                            },
                                        },
                                        {
                                            type: 'filter',
                                            properties: {
                                                pass: '={{ /nemotron/i.test($responseItem.id) }}',
                                            },
                                        },
                                        {
                                            type: 'setKeyValue',
                                            properties: {
                                                name: '={{$responseItem.id}}',
                                                value: '={{$responseItem.id}}',
                                            },
                                        },
                                        {
                                            type: 'sort',
                                            properties: {
                                                key: 'name',
                                            },
                                        },
                                    ],
                                },
                            },
                        },
                    },
                    routing: {
                        send: {
                            type: 'body',
                            property: 'model',
                        },
                    },
                    default: 'nvidia/llama-3.3-nemotron-super-49b-v1',
                    options: NEMOTRON_FALLBACK_MODELS.map((id) => ({ name: id, value: id })),
                },
                {
                    displayName: 'Options',
                    name: 'options',
                    placeholder: 'Add Option',
                    description: 'Additional options to add',
                    type: 'collection',
                    default: {},
                    options: [
                        {
                            displayName: 'Frequency Penalty',
                            name: 'frequencyPenalty',
                            default: 0,
                            typeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },
                            description: "Positive values penalize new tokens based on their existing frequency in the text so far, decreasing the model's likelihood to repeat the same line verbatim",
                            type: 'number',
                        },
                        {
                            displayName: 'Maximum Number of Tokens',
                            name: 'maxTokens',
                            default: -1,
                            description: 'The maximum number of tokens to generate in the completion. Use -1 for the model default.',
                            type: 'number',
                        },
                        {
                            displayName: 'Response Format',
                            name: 'responseFormat',
                            default: 'text',
                            type: 'options',
                            options: [
                                {
                                    name: 'Text',
                                    value: 'text',
                                    description: 'Regular text response',
                                },
                                {
                                    name: 'JSON',
                                    value: 'json_object',
                                    description: 'Enables JSON mode, which should guarantee the message the model generates is valid JSON',
                                },
                            ],
                        },
                        {
                            displayName: 'Presence Penalty',
                            name: 'presencePenalty',
                            default: 0,
                            typeOptions: { maxValue: 2, minValue: -2, numberPrecision: 1 },
                            description: "Positive values penalize new tokens based on whether they appear in the text so far, increasing the model's likelihood to talk about new topics",
                            type: 'number',
                        },
                        {
                            displayName: 'Sampling Temperature',
                            name: 'temperature',
                            default: 0.7,
                            typeOptions: { maxValue: 2, minValue: 0, numberPrecision: 1 },
                            description: 'Controls randomness: Lowering results in less random completions. As the temperature approaches zero, the model will become deterministic and repetitive.',
                            type: 'number',
                        },
                        {
                            displayName: 'Timeout',
                            name: 'timeout',
                            default: 360000,
                            description: 'Maximum amount of time a request is allowed to take in milliseconds',
                            type: 'number',
                        },
                        {
                            displayName: 'Max Retries',
                            name: 'maxRetries',
                            default: 2,
                            description: 'Maximum number of retries to attempt',
                            type: 'number',
                        },
                        {
                            displayName: 'Top P',
                            name: 'topP',
                            default: 1,
                            typeOptions: { maxValue: 1, minValue: 0, numberPrecision: 1 },
                            description: 'Controls diversity via nucleus sampling: 0.5 means half of all likelihood-weighted options are considered. We generally recommend altering this or temperature but not both.',
                            type: 'number',
                        },
                    ],
                },
            ],
        };
    }
    async supplyData(itemIndex) {
        const credentials = await this.getCredentials('nvidiaApi');
        const modelName = this.getNodeParameter('model', itemIndex);
        const options = this.getNodeParameter('options', itemIndex, {});
        const timeout = options.timeout;
        const configuration = {
            baseURL: credentials.url,
            fetchOptions: {
                dispatcher: (0, ai_utilities_1.getProxyAgent)(credentials.url, {
                    headersTimeout: timeout,
                    bodyTimeout: timeout,
                }),
            },
        };
        const model = new openai_1.ChatOpenAI({
            apiKey: credentials.apiKey || 'unused',
            model: modelName,
            ...options,
            timeout,
            maxRetries: options.maxRetries ?? 2,
            configuration,
            callbacks: [new ai_utilities_1.N8nLlmTracing(this)],
            modelKwargs: options.responseFormat
                ? {
                    response_format: { type: options.responseFormat },
                }
                : undefined,
            onFailedAttempt: (0, ai_utilities_1.makeN8nLlmFailedAttemptHandler)(this, error_handling_1.openAiFailedAttemptHandler),
        });
        return {
            response: model,
        };
    }
}
exports.LmChatNvidia = LmChatNvidia;
//# sourceMappingURL=LmChatNvidia.node.js.map