"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    var desc = Object.getOwnPropertyDescriptor(m, k);
    if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
      desc = { enumerable: true, get: function() { return m[k]; } };
    }
    Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
    if (k2 === undefined) k2 = k;
    o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
    Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
    o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
    var ownKeys = function(o) {
        ownKeys = Object.getOwnPropertyNames || function (o) {
            var ar = [];
            for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
            return ar;
        };
        return ownKeys(o);
    };
    return function (mod) {
        if (mod && mod.__esModule) return mod;
        var result = {};
        if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
        __setModuleDefault(result, mod);
        return result;
    };
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.loadApiProvider = loadApiProvider;
exports.loadApiProviders = loadApiProviders;
const chalk_1 = __importDefault(require("chalk"));
const dedent_1 = __importDefault(require("dedent"));
const fs_1 = __importDefault(require("fs"));
const js_yaml_1 = __importDefault(require("js-yaml"));
const path_1 = __importDefault(require("path"));
const cliState_1 = __importDefault(require("./cliState"));
const esm_1 = require("./esm");
const logger_1 = __importDefault(require("./logger"));
const ai21_1 = require("./providers/ai21");
const anthropic_1 = require("./providers/anthropic");
const azure_1 = require("./providers/azure");
const bam_1 = require("./providers/bam");
const bedrock_1 = require("./providers/bedrock");
const browser_1 = require("./providers/browser");
const cloudera_1 = require("./providers/cloudera");
const CloudflareAiProviders = __importStar(require("./providers/cloudflare-ai"));
const cohere_1 = require("./providers/cohere");
const fal_1 = require("./providers/fal");
const golangCompletion_1 = require("./providers/golangCompletion");
const groq_1 = require("./providers/groq");
const http_1 = require("./providers/http");
const huggingface_1 = require("./providers/huggingface");
const llama_1 = require("./providers/llama");
const localai_1 = require("./providers/localai");
const manualInput_1 = require("./providers/manualInput");
const mistral_1 = require("./providers/mistral");
const ollama_1 = require("./providers/ollama");
const openai_1 = require("./providers/openai");
const packageParser_1 = require("./providers/packageParser");
const palm_1 = require("./providers/palm");
const portkey_1 = require("./providers/portkey");
const pythonCompletion_1 = require("./providers/pythonCompletion");
const replicate_1 = require("./providers/replicate");
const scriptCompletion_1 = require("./providers/scriptCompletion");
const sequence_1 = require("./providers/sequence");
const simulatedUser_1 = require("./providers/simulatedUser");
const togetherai_1 = require("./providers/togetherai");
const vertex_1 = require("./providers/vertex");
const voyage_1 = require("./providers/voyage");
const watsonx_1 = require("./providers/watsonx");
const webhook_1 = require("./providers/webhook");
const websocket_1 = require("./providers/websocket");
const xai_1 = require("./providers/xai");
const bestOfN_1 = __importDefault(require("./redteam/providers/bestOfN"));
const crescendo_1 = __importDefault(require("./redteam/providers/crescendo"));
const goat_1 = __importDefault(require("./redteam/providers/goat"));
const iterative_1 = __importDefault(require("./redteam/providers/iterative"));
const iterativeImage_1 = __importDefault(require("./redteam/providers/iterativeImage"));
const iterativeTree_1 = __importDefault(require("./redteam/providers/iterativeTree"));
const file_1 = require("./util/file");
const invariant_1 = __importDefault(require("./util/invariant"));
const templates_1 = require("./util/templates");
// FIXME(ian): Make loadApiProvider handle all the different provider types (string, ProviderOptions, ApiProvider, etc), rather than the callers.
async function loadApiProvider(providerPath, context = {}) {
    const { options = {}, basePath, env } = context;
    const providerOptions = {
        id: options.id,
        config: {
            ...options.config,
            basePath,
        },
        env,
    };
    let ret;
    providerPath = (0, templates_1.getNunjucksEngine)().renderString(providerPath, {});
    if (providerPath.startsWith('file://') &&
        (providerPath.endsWith('.yaml') ||
            providerPath.endsWith('.yml') ||
            providerPath.endsWith('.json'))) {
        const filePath = providerPath.slice('file://'.length);
        const modulePath = path_1.default.isAbsolute(filePath)
            ? filePath
            : path_1.default.join(basePath || process.cwd(), filePath);
        let fileContent;
        if (providerPath.endsWith('.json')) {
            fileContent = JSON.parse(fs_1.default.readFileSync(modulePath, 'utf8'));
        }
        else {
            fileContent = js_yaml_1.default.load(fs_1.default.readFileSync(modulePath, 'utf8'));
        }
        (0, invariant_1.default)(fileContent, `Provider config ${filePath} is undefined`);
        (0, invariant_1.default)(fileContent.id, `Provider config ${filePath} must have an id`);
        logger_1.default.info(`Loaded provider ${fileContent.id} from ${filePath}`);
        ret = await loadApiProvider(fileContent.id, { ...context, options: fileContent });
    }
    else if (providerPath === 'echo') {
        ret = {
            id: () => 'echo',
            callApi: async (input) => ({ output: input }),
        };
    }
    else if (providerPath.startsWith('cloudera:')) {
        const modelName = providerPath.split(':')[1];
        ret = new cloudera_1.ClouderaAiChatCompletionProvider(modelName, {
            ...providerOptions,
            config: providerOptions.config || {},
        });
    }
    else if (providerPath.startsWith('exec:')) {
        // Load script module
        const scriptPath = providerPath.split(':')[1];
        ret = new scriptCompletion_1.ScriptCompletionProvider(scriptPath, providerOptions);
    }
    else if (providerPath.startsWith('python:') ||
        (providerPath.startsWith('file://') &&
            (providerPath.endsWith('.py') || providerPath.includes('.py:')))) {
        const scriptPath = providerPath.startsWith('file://')
            ? providerPath.slice('file://'.length)
            : providerPath.split(':').slice(1).join(':');
        ret = new pythonCompletion_1.PythonProvider(scriptPath, providerOptions);
    }
    else if (providerPath.startsWith('openai:')) {
        // Load OpenAI module
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits.slice(2).join(':');
        if (modelType === 'chat') {
            ret = new openai_1.OpenAiChatCompletionProvider(modelName || 'gpt-4o-mini', providerOptions);
        }
        else if (modelType === 'embedding' || modelType === 'embeddings') {
            ret = new openai_1.OpenAiEmbeddingProvider(modelName || 'text-embedding-3-large', providerOptions);
        }
        else if (modelType === 'completion') {
            ret = new openai_1.OpenAiCompletionProvider(modelName || 'gpt-3.5-turbo-instruct', providerOptions);
        }
        else if (modelType === 'moderation') {
            ret = new openai_1.OpenAiModerationProvider(modelName || 'omni-moderation-latest', providerOptions);
        }
        else if (openai_1.OpenAiChatCompletionProvider.OPENAI_CHAT_MODEL_NAMES.includes(modelType)) {
            ret = new openai_1.OpenAiChatCompletionProvider(modelType, providerOptions);
        }
        else if (openai_1.OpenAiCompletionProvider.OPENAI_COMPLETION_MODEL_NAMES.includes(modelType)) {
            ret = new openai_1.OpenAiCompletionProvider(modelType, providerOptions);
        }
        else if (modelType === 'assistant') {
            ret = new openai_1.OpenAiAssistantProvider(modelName, providerOptions);
        }
        else if (modelType === 'image') {
            ret = new openai_1.OpenAiImageProvider(modelName, providerOptions);
        }
        else {
            // Assume user did not provide model type, and it's a chat model
            logger_1.default.warn(`Unknown OpenAI model type: ${modelType}. Treating it as a chat model. Use one of the following providers: openai:chat:<model name>, openai:completion:<model name>, openai:embeddings:<model name>, openai:image:<model name>`);
            ret = new openai_1.OpenAiChatCompletionProvider(modelType, providerOptions);
        }
    }
    else if (providerPath.startsWith('azure:') || providerPath.startsWith('azureopenai:')) {
        // Load Azure OpenAI module
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const deploymentName = splits[2];
        if (modelType === 'chat') {
            ret = new azure_1.AzureChatCompletionProvider(deploymentName, providerOptions);
        }
        else if (modelType === 'assistant') {
            ret = new azure_1.AzureAssistantProvider(deploymentName, providerOptions);
        }
        else if (modelType === 'embedding' || modelType === 'embeddings') {
            ret = new azure_1.AzureEmbeddingProvider(deploymentName || 'text-embedding-ada-002', providerOptions);
        }
        else if (modelType === 'completion') {
            ret = new azure_1.AzureCompletionProvider(deploymentName, providerOptions);
        }
        else {
            throw new Error(`Unknown Azure model type: ${modelType}. Use one of the following providers: azure:chat:<model name>, azure:assistant:<assistant id>, azure:completion:<model name>`);
        }
    }
    else if (providerPath.startsWith('openrouter:')) {
        const splits = providerPath.split(':');
        const modelName = splits.slice(1).join(':');
        ret = new openai_1.OpenAiChatCompletionProvider(modelName, {
            ...providerOptions,
            config: {
                ...providerOptions.config,
                apiBaseUrl: 'https://openrouter.ai/api/v1',
                apiKeyEnvar: 'OPENROUTER_API_KEY',
                passthrough: {
                    // Pass through OpenRouter-specific options
                    // https://openrouter.ai/docs/requests
                    ...(providerOptions.config.transforms && {
                        transforms: providerOptions.config.transforms,
                    }),
                    ...(providerOptions.config.models && { models: providerOptions.config.models }),
                    ...(providerOptions.config.route && { route: providerOptions.config.route }),
                    ...(providerOptions.config.provider && { provider: providerOptions.config.provider }),
                },
            },
        });
    }
    else if (providerPath.startsWith('github:')) {
        const splits = providerPath.split(':');
        const modelName = splits.slice(1).join(':');
        ret = new openai_1.OpenAiChatCompletionProvider(modelName, {
            ...providerOptions,
            config: {
                ...providerOptions.config,
                apiBaseUrl: 'https://models.inference.ai.azure.com',
                apiKeyEnvar: 'GITHUB_TOKEN',
            },
        });
    }
    else if (providerPath.startsWith('perplexity:')) {
        const splits = providerPath.split(':');
        const modelName = splits.slice(1).join(':');
        ret = new openai_1.OpenAiChatCompletionProvider(modelName, {
            ...providerOptions,
            config: {
                ...providerOptions.config,
                apiBaseUrl: 'https://api.perplexity.ai',
                apiKeyEnvar: 'PERPLEXITY_API_KEY',
            },
        });
    }
    else if (providerPath.startsWith('hyperbolic:')) {
        const splits = providerPath.split(':');
        const modelName = splits.slice(1).join(':');
        ret = new openai_1.OpenAiChatCompletionProvider(modelName, {
            ...providerOptions,
            config: {
                ...providerOptions.config,
                apiBaseUrl: 'https://api.hyperbolic.xyz/v1',
                apiKeyEnvar: 'HYPERBOLIC_API_KEY',
            },
        });
    }
    else if (providerPath.startsWith('deepseek:')) {
        const splits = providerPath.split(':');
        const modelName = splits.slice(1).join(':') || 'deepseek-chat';
        ret = new openai_1.OpenAiChatCompletionProvider(modelName, {
            ...providerOptions,
            config: {
                ...providerOptions.config,
                apiBaseUrl: 'https://api.deepseek.com/v1',
                apiKeyEnvar: 'DEEPSEEK_API_KEY',
            },
        });
    }
    else if (providerPath.startsWith('f5')) {
        const splits = providerPath.split(':');
        let endpoint = splits.slice(1).join(':');
        if (endpoint.startsWith('/')) {
            endpoint = endpoint.slice(1);
        }
        ret = new openai_1.OpenAiChatCompletionProvider(endpoint, {
            ...providerOptions,
            config: {
                ...providerOptions.config,
                apiBaseUrl: providerOptions.config?.apiBaseUrl + '/' + endpoint,
                apiKeyEnvar: 'F5_API_KEY',
            },
        });
    }
    else if (providerPath.startsWith('togetherai:')) {
        ret = (0, togetherai_1.createTogetherAiProvider)(providerPath, {
            config: providerOptions,
            env: context.env,
        });
    }
    else if (providerPath.startsWith('xai:')) {
        ret = (0, xai_1.createXAIProvider)(providerPath, {
            config: providerOptions,
            env: context.env,
        });
    }
    else if (providerPath.startsWith('portkey:')) {
        const splits = providerPath.split(':');
        const modelName = splits.slice(1).join(':');
        ret = new portkey_1.PortkeyChatCompletionProvider(modelName, providerOptions);
    }
    else if (providerPath.startsWith('anthropic:')) {
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits[2];
        if (modelType === 'messages') {
            ret = new anthropic_1.AnthropicMessagesProvider(modelName, providerOptions);
        }
        else if (modelType === 'completion') {
            ret = new anthropic_1.AnthropicCompletionProvider(modelName, providerOptions);
        }
        else if (anthropic_1.AnthropicCompletionProvider.ANTHROPIC_COMPLETION_MODELS.includes(modelType)) {
            ret = new anthropic_1.AnthropicCompletionProvider(modelType, providerOptions);
        }
        else {
            throw new Error(`Unknown Anthropic model type: ${modelType}. Use one of the following providers: anthropic:messages:<model name>, anthropic:completion:<model name>`);
        }
    }
    else if (providerPath.startsWith('voyage:')) {
        ret = new voyage_1.VoyageEmbeddingProvider(providerPath.split(':')[1], providerOptions);
    }
    else if (providerPath.startsWith('watsonx:')) {
        const splits = providerPath.split(':');
        const modelName = splits.slice(1).join(':');
        ret = new watsonx_1.WatsonXProvider(modelName, providerOptions);
    }
    else if (providerPath.startsWith('bedrock:')) {
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits.slice(2).join(':');
        if (modelType === 'completion') {
            // Backwards compatibility: `completion` used to be required
            ret = new bedrock_1.AwsBedrockCompletionProvider(modelName, providerOptions);
        }
        else if (modelType === 'embeddings' || modelType === 'embedding') {
            ret = new bedrock_1.AwsBedrockEmbeddingProvider(modelName, providerOptions);
        }
        else {
            ret = new bedrock_1.AwsBedrockCompletionProvider(`${modelType}${modelName ? `:${modelName}` : ''}`, providerOptions);
        }
    }
    else if (providerPath.startsWith('huggingface:') || providerPath.startsWith('hf:')) {
        const splits = providerPath.split(':');
        if (splits.length < 3) {
            throw new Error(`Invalid Huggingface provider path: ${providerPath}. Use one of the following providers: huggingface:feature-extraction:<model name>, huggingface:text-generation:<model name>, huggingface:text-classification:<model name>, huggingface:token-classification:<model name>`);
        }
        const modelName = splits.slice(2).join(':');
        if (splits[1] === 'feature-extraction') {
            ret = new huggingface_1.HuggingfaceFeatureExtractionProvider(modelName, providerOptions);
        }
        else if (splits[1] === 'sentence-similarity') {
            ret = new huggingface_1.HuggingfaceSentenceSimilarityProvider(modelName, providerOptions);
        }
        else if (splits[1] === 'text-generation') {
            ret = new huggingface_1.HuggingfaceTextGenerationProvider(modelName, providerOptions);
        }
        else if (splits[1] === 'text-classification') {
            ret = new huggingface_1.HuggingfaceTextClassificationProvider(modelName, providerOptions);
        }
        else if (splits[1] === 'token-classification') {
            ret = new huggingface_1.HuggingfaceTokenExtractionProvider(modelName, providerOptions);
        }
        else {
            throw new Error(`Invalid Huggingface provider path: ${providerPath}. Use one of the following providers: huggingface:feature-extraction:<model name>, huggingface:text-generation:<model name>, huggingface:text-classification:<model name>, huggingface:token-classification:<model name>`);
        }
    }
    else if (providerPath.startsWith('replicate:')) {
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits.slice(2).join(':');
        if (modelType === 'moderation') {
            ret = new replicate_1.ReplicateModerationProvider(modelName, providerOptions);
        }
        else if (modelType === 'image') {
            ret = new replicate_1.ReplicateImageProvider(modelName, providerOptions);
        }
        else {
            // By default, there is no model type.
            ret = new replicate_1.ReplicateProvider(modelName ? modelType + ':' + modelName : modelType, providerOptions);
        }
    }
    else if (providerPath.startsWith('fal:')) {
        const [_, modelType, modelName] = providerPath.split(':');
        if (modelType === 'image') {
            ret = new fal_1.FalImageGenerationProvider(modelName, providerOptions);
        }
        else {
            throw new Error(`Invalid fal provider path: ${providerPath}. Use one of the following providers: fal:image:<model name>`);
        }
    }
    else if (providerPath.startsWith('bam:')) {
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits.slice(2).join(':');
        if (modelType === 'chat') {
            ret = new bam_1.BAMChatProvider(modelName || 'ibm/granite-13b-chat-v2', providerOptions);
        }
        else {
            throw new Error(`Invalid BAM provider: ${providerPath}. Use one of the following providers: bam:chat:<model name>`);
        }
    }
    else if (providerPath.startsWith('cloudflare-ai:')) {
        // Load Cloudflare AI
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const deploymentName = splits[2];
        if (modelType === 'chat') {
            ret = new CloudflareAiProviders.CloudflareAiChatCompletionProvider(deploymentName, providerOptions);
        }
        else if (modelType === 'embedding' || modelType === 'embeddings') {
            ret = new CloudflareAiProviders.CloudflareAiEmbeddingProvider(deploymentName, providerOptions);
        }
        else if (modelType === 'completion') {
            ret = new CloudflareAiProviders.CloudflareAiCompletionProvider(deploymentName, providerOptions);
        }
        else {
            throw new Error(`Unknown Cloudflare AI model type: ${modelType}. Use one of the following providers: cloudflare-ai:chat:<model name>, cloudflare-ai:completion:<model name>, cloudflare-ai:embedding:`);
        }
    }
    else if (providerPath.startsWith('webhook:')) {
        const webhookUrl = providerPath.substring('webhook:'.length);
        ret = new webhook_1.WebhookProvider(webhookUrl, providerOptions);
    }
    else if (providerPath === 'llama' || providerPath.startsWith('llama:')) {
        const modelName = providerPath.split(':')[1];
        ret = new llama_1.LlamaProvider(modelName, providerOptions);
    }
    else if (providerPath.startsWith('ollama:')) {
        const splits = providerPath.split(':');
        const firstPart = splits[1];
        if (firstPart === 'chat') {
            const modelName = splits.slice(2).join(':');
            ret = new ollama_1.OllamaChatProvider(modelName, providerOptions);
        }
        else if (firstPart === 'completion') {
            const modelName = splits.slice(2).join(':');
            ret = new ollama_1.OllamaCompletionProvider(modelName, providerOptions);
        }
        else if (firstPart === 'embedding' || firstPart === 'embeddings') {
            const modelName = splits.slice(2).join(':');
            ret = new ollama_1.OllamaEmbeddingProvider(modelName, providerOptions);
        }
        else {
            // Default to completion provider
            const modelName = splits.slice(1).join(':');
            ret = new ollama_1.OllamaCompletionProvider(modelName, providerOptions);
        }
    }
    else if (providerPath.startsWith('palm:') || providerPath.startsWith('google:')) {
        const modelName = providerPath.split(':')[1];
        ret = new palm_1.PalmChatProvider(modelName, providerOptions);
    }
    else if (providerPath.startsWith('vertex:')) {
        const splits = providerPath.split(':');
        const firstPart = splits[1];
        if (firstPart === 'chat') {
            ret = new vertex_1.VertexChatProvider(splits.slice(2).join(':'), providerOptions);
        }
        else if (firstPart === 'embedding' || firstPart === 'embeddings') {
            ret = new vertex_1.VertexEmbeddingProvider(splits.slice(2).join(':'), providerOptions);
        }
        else {
            // Default to chat provider
            ret = new vertex_1.VertexChatProvider(splits.slice(1).join(':'), providerOptions);
        }
    }
    else if (providerPath.startsWith('mistral:')) {
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits.slice(2).join(':');
        if (modelType === 'embedding' || modelType === 'embeddings') {
            ret = new mistral_1.MistralEmbeddingProvider(providerOptions);
        }
        else {
            ret = new mistral_1.MistralChatCompletionProvider(modelName || modelType, providerOptions);
        }
    }
    else if (providerPath.startsWith('cohere:')) {
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits.slice(2).join(':');
        if (modelType === 'embedding' || modelType === 'embeddings') {
            ret = new cohere_1.CohereEmbeddingProvider(modelName, providerOptions);
        }
        else if (modelType === 'chat' || modelType === undefined) {
            ret = new cohere_1.CohereChatCompletionProvider(modelName || modelType, providerOptions);
        }
        else {
            // Default to chat provider for any other model type
            ret = new cohere_1.CohereChatCompletionProvider(providerPath.substring('cohere:'.length), providerOptions);
        }
    }
    else if (providerPath.startsWith('localai:')) {
        const splits = providerPath.split(':');
        const modelType = splits[1];
        const modelName = splits[2];
        if (modelType === 'chat') {
            ret = new localai_1.LocalAiChatProvider(modelName, providerOptions);
        }
        else if (modelType === 'completion') {
            ret = new localai_1.LocalAiCompletionProvider(modelName, providerOptions);
        }
        else if (modelType === 'embedding' || modelType === 'embeddings') {
            ret = new localai_1.LocalAiEmbeddingProvider(modelName, providerOptions);
        }
        else {
            ret = new localai_1.LocalAiChatProvider(modelType, providerOptions);
        }
    }
    else if (providerPath.startsWith('adaline:')) {
        const splits = providerPath.split(':');
        if (splits.length < 4) {
            throw new Error(`Invalid adaline provider path: ${providerPath}. path format should be 'adaline:<provider_name>:<model_type>:<model_name>' eg. 'adaline:openai:chat:gpt-4o'`);
        }
        const providerName = splits[1];
        const modelType = splits[2];
        const modelName = splits[3];
        const { AdalineGatewayChatProvider, AdalineGatewayEmbeddingProvider } = await Promise.resolve().then(() => __importStar(require('./providers/adaline.gateway')));
        if (modelType === 'embedding' || modelType === 'embeddings') {
            ret = new AdalineGatewayEmbeddingProvider(providerName, modelName, providerOptions);
        }
        else {
            ret = new AdalineGatewayChatProvider(providerName, modelName, providerOptions);
        }
    }
    else if (providerPath.startsWith('http:') ||
        providerPath.startsWith('https:') ||
        providerPath === 'http' ||
        providerPath === 'https') {
        ret = new http_1.HttpProvider(providerPath, providerOptions);
    }
    else if (providerPath.startsWith('ws:') ||
        providerPath.startsWith('wss:') ||
        providerPath === 'websocket' ||
        providerPath === 'ws' ||
        providerPath === 'wss') {
        ret = new websocket_1.WebSocketProvider(providerPath, providerOptions);
    }
    else if (providerPath === 'browser') {
        ret = new browser_1.BrowserProvider(providerPath, providerOptions);
    }
    else if (providerPath === 'promptfoo:manual-input') {
        ret = new manualInput_1.ManualInputProvider(providerOptions);
    }
    else if (providerPath === 'promptfoo:redteam:crescendo') {
        ret = new crescendo_1.default(providerOptions.config);
    }
    else if (providerPath === 'promptfoo:redteam:goat') {
        ret = new goat_1.default(providerOptions.config);
    }
    else if (providerPath === 'promptfoo:redteam:best-of-n') {
        ret = new bestOfN_1.default(providerOptions.config);
    }
    else if (providerPath === 'promptfoo:redteam:iterative') {
        ret = new iterative_1.default(providerOptions.config);
    }
    else if (providerPath === 'promptfoo:redteam:iterative:image') {
        ret = new iterativeImage_1.default(providerOptions.config);
    }
    else if (providerPath === 'promptfoo:redteam:iterative:tree') {
        ret = new iterativeTree_1.default(providerOptions.config);
    }
    else if (providerPath === 'promptfoo:simulated-user') {
        ret = new simulatedUser_1.SimulatedUser(providerOptions);
    }
    else if (providerPath === 'sequence') {
        ret = new sequence_1.SequenceProvider(providerOptions);
    }
    else if (providerPath.startsWith('groq:')) {
        const modelName = providerPath.split(':')[1];
        ret = new groq_1.GroqProvider(modelName, providerOptions);
    }
    else if (providerPath.startsWith('ai21:')) {
        const modelName = providerPath.split(':')[1];
        ret = new ai21_1.AI21ChatCompletionProvider(modelName, providerOptions);
    }
    else if (providerPath.startsWith('golang:') ||
        (providerPath.startsWith('file://') &&
            (providerPath.endsWith('.go') || providerPath.includes('.go:')))) {
        const scriptPath = providerPath.startsWith('file://')
            ? providerPath.slice('file://'.length)
            : providerPath.split(':').slice(1).join(':');
        ret = new golangCompletion_1.GolangProvider(scriptPath, providerOptions);
    }
    else if (providerPath.startsWith('package:')) {
        ret = await (0, packageParser_1.parsePackageProvider)(providerPath, basePath || process.cwd(), providerOptions);
    }
    else if ((0, file_1.isJavascriptFile)(providerPath)) {
        if (providerPath.startsWith('file://')) {
            providerPath = providerPath.slice('file://'.length);
        }
        // Load custom module
        const modulePath = path_1.default.isAbsolute(providerPath)
            ? providerPath
            : path_1.default.join(basePath || process.cwd(), providerPath);
        const CustomApiProvider = await (0, esm_1.importModule)(modulePath);
        ret = new CustomApiProvider(options);
    }
    else {
        logger_1.default.error((0, dedent_1.default) `
      Could not identify provider: ${chalk_1.default.bold(providerPath)}.

      ${chalk_1.default.white((0, dedent_1.default) `
        Please check your configuration and ensure the provider is correctly specified.

        For more information on supported providers, visit: `)} ${chalk_1.default.cyan('https://promptfoo.dev/docs/providers/')}
    `);
        process.exit(1);
    }
    ret.transform = options.transform;
    ret.delay = options.delay;
    ret.label || (ret.label = (0, templates_1.getNunjucksEngine)().renderString(String(options.label || ''), {}));
    return ret;
}
async function loadApiProviders(providerPaths, options = {}) {
    const { basePath } = options;
    const env = options.env || cliState_1.default.config?.env;
    if (typeof providerPaths === 'string') {
        return [await loadApiProvider(providerPaths, { basePath, env })];
    }
    else if (typeof providerPaths === 'function') {
        return [
            {
                id: () => 'custom-function',
                callApi: providerPaths,
            },
        ];
    }
    else if (Array.isArray(providerPaths)) {
        return Promise.all(providerPaths.map((provider, idx) => {
            if (typeof provider === 'string') {
                return loadApiProvider(provider, { basePath, env });
            }
            else if (typeof provider === 'function') {
                return {
                    id: provider.label ? () => provider.label : () => `custom-function-${idx}`,
                    callApi: provider,
                };
            }
            else if (provider.id) {
                // List of ProviderConfig objects
                return loadApiProvider(provider.id, {
                    options: provider,
                    basePath,
                    env,
                });
            }
            else {
                // List of { id: string, config: ProviderConfig } objects
                const id = Object.keys(provider)[0];
                const providerObject = provider[id];
                const context = { ...providerObject, id: providerObject.id || id };
                return loadApiProvider(id, { options: context, basePath, env });
            }
        }));
    }
    throw new Error('Invalid providers list');
}
exports.default = {
    OpenAiCompletionProvider: openai_1.OpenAiCompletionProvider,
    OpenAiChatCompletionProvider: openai_1.OpenAiChatCompletionProvider,
    OpenAiAssistantProvider: openai_1.OpenAiAssistantProvider,
    OpenAiEmbeddingProvider: openai_1.OpenAiEmbeddingProvider,
    OpenAiImageProvider: openai_1.OpenAiImageProvider,
    OpenAiModerationProvider: openai_1.OpenAiModerationProvider,
    AnthropicCompletionProvider: anthropic_1.AnthropicCompletionProvider,
    AnthropicMessagesProvider: anthropic_1.AnthropicMessagesProvider,
    ReplicateProvider: replicate_1.ReplicateProvider,
    ReplicateImageProvider: replicate_1.ReplicateImageProvider,
    ReplicateModerationProvider: replicate_1.ReplicateModerationProvider,
    LocalAiCompletionProvider: localai_1.LocalAiCompletionProvider,
    LocalAiChatProvider: localai_1.LocalAiChatProvider,
    LocalAiEmbeddingProvider: localai_1.LocalAiEmbeddingProvider,
    BAMChatProvider: bam_1.BAMChatProvider,
    BAMEmbeddingProvider: bam_1.BAMEmbeddingProvider,
    GroqProvider: groq_1.GroqProvider,
    MistralChatCompletionProvider: mistral_1.MistralChatCompletionProvider,
    MistralEmbeddingProvider: mistral_1.MistralEmbeddingProvider,
    AI21ChatCompletionProvider: ai21_1.AI21ChatCompletionProvider,
    AzureAssistantProvider: azure_1.AzureAssistantProvider,
    AzureChatCompletionProvider: azure_1.AzureChatCompletionProvider,
    AzureCompletionProvider: azure_1.AzureCompletionProvider,
    AzureEmbeddingProvider: azure_1.AzureEmbeddingProvider,
    ClouderaAiChatCompletionProvider: cloudera_1.ClouderaAiChatCompletionProvider,
    // Backwards compatibility for Azure rename 2024-11-09 / 0.96.0
    AzureOpenAiAssistantProvider: azure_1.AzureAssistantProvider,
    AzureOpenAiChatCompletionProvider: azure_1.AzureChatCompletionProvider,
    AzureOpenAiCompletionProvider: azure_1.AzureCompletionProvider,
    AzureOpenAiEmbeddingProvider: azure_1.AzureEmbeddingProvider,
    AwsBedrockCompletionProvider: bedrock_1.AwsBedrockCompletionProvider,
    AwsBedrockEmbeddingProvider: bedrock_1.AwsBedrockEmbeddingProvider,
    BrowserProvider: browser_1.BrowserProvider,
    CohereChatCompletionProvider: cohere_1.CohereChatCompletionProvider,
    CohereEmbeddingProvider: cohere_1.CohereEmbeddingProvider,
    FalImageGenerationProvider: fal_1.FalImageGenerationProvider,
    GolangProvider: golangCompletion_1.GolangProvider,
    HttpProvider: http_1.HttpProvider,
    HuggingfaceFeatureExtractionProvider: huggingface_1.HuggingfaceFeatureExtractionProvider,
    HuggingfaceSentenceSimilarityProvider: huggingface_1.HuggingfaceSentenceSimilarityProvider,
    HuggingfaceTextClassificationProvider: huggingface_1.HuggingfaceTextClassificationProvider,
    HuggingfaceTextGenerationProvider: huggingface_1.HuggingfaceTextGenerationProvider,
    HuggingfaceTokenExtractionProvider: huggingface_1.HuggingfaceTokenExtractionProvider,
    LlamaProvider: llama_1.LlamaProvider,
    ManualInputProvider: manualInput_1.ManualInputProvider,
    OllamaEmbeddingProvider: ollama_1.OllamaEmbeddingProvider,
    OllamaCompletionProvider: ollama_1.OllamaCompletionProvider,
    OllamaChatProvider: ollama_1.OllamaChatProvider,
    PalmChatProvider: palm_1.PalmChatProvider,
    PortkeyChatCompletionProvider: portkey_1.PortkeyChatCompletionProvider,
    PythonProvider: pythonCompletion_1.PythonProvider,
    ScriptCompletionProvider: scriptCompletion_1.ScriptCompletionProvider,
    VertexChatProvider: vertex_1.VertexChatProvider,
    VertexEmbeddingProvider: vertex_1.VertexEmbeddingProvider,
    VoyageEmbeddingProvider: voyage_1.VoyageEmbeddingProvider,
    WebhookProvider: webhook_1.WebhookProvider,
    WebSocketProvider: websocket_1.WebSocketProvider,
    loadApiProvider,
    WatsonXProvider: watsonx_1.WatsonXProvider,
};
//# sourceMappingURL=providers.js.map