"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.HALLUCINATION_MODEL_NAME = exports.AUDIO_MODEL_NAME = exports.MULTIMODAL_MODEL_NAME = void 0;
exports.setDefaultCompletionProviders = setDefaultCompletionProviders;
exports.setDefaultEmbeddingProviders = setDefaultEmbeddingProviders;
exports.getDefaultProviders = getDefaultProviders;
const envars_1 = require("../envars");
const logger_1 = __importDefault(require("../logger"));
const constants_1 = require("../constants");
const findWorkspaceProvider_1 = require("../util/findWorkspaceProvider/findWorkspaceProvider");
const index_1 = require("./index");
const defaults_1 = require("./anthropic/defaults");
const chat_1 = require("./azure/chat");
const embedding_1 = require("./azure/embedding");
const moderation_1 = require("./azure/moderation");
const util_1 = require("./google/util");
const vertex_1 = require("./google/vertex");
const huggingfaceRouter_1 = require("./huggingfaceRouter");
const defaults_2 = require("./mistral/defaults");
const defaults_3 = require("./openai/defaults");
const deepgram_1 = require("./stt/deepgram");
const lodash_1 = __importDefault(require("lodash"));
const COMPLETION_PROVIDERS = [
    'gradingJsonProvider',
    'gradingProvider',
    'llmRubricProvider',
    'suggestionsProvider',
    'synthesizeProvider',
];
const EMBEDDING_PROVIDERS = ['embeddingProvider'];
/** Azure deployment name (not always equal to OpenAI model id). Override via AZURE_OPENAI_AUDIO_DEPLOYMENT_NAME. */
const DefaultAzureOpenAiAudioDeploymentName = 'gpt-audio-1.5';
const DefaultHuggingfaceVideoModelName = 'Qwen/Qwen3-VL-235B-A22B-Instruct:novita';
let defaultCompletionProvider;
let defaultEmbeddingProvider;
exports.MULTIMODAL_MODEL_NAME = 'qwen3-vl-30b';
exports.AUDIO_MODEL_NAME = 'gpt-audio-1.5';
exports.HALLUCINATION_MODEL_NAME = 'halloumi';
/**
 * This will override all of the completion type providers defined in the constant COMPLETION_PROVIDERS
 * @param provider - The provider to set as the default completion provider.
 */
async function setDefaultCompletionProviders(provider) {
    defaultCompletionProvider = provider;
}
async function setDefaultEmbeddingProviders(provider) {
    defaultEmbeddingProvider = provider;
}
/**
 * Helper function to create ApiProvider from database provider config
 * Maps providerName from DB to provider path and creates provider instance
 */
async function createProviderFromConfig(providerConfig, env) {
    try {
        const { providerName, config } = providerConfig;
        // Map common provider names to provider paths
        // Format: providerName -> providerPath (e.g., 'azure' -> 'azure:chat:modelName')
        const providerPathMap = {
            'azure': 'azure:chat',
            'azure-speech': 'azure:chat',
            'openai': 'openai:chat',
            'anthropic': 'anthropic:messages',
            'gpt-4': 'openai:chat:gpt-4',
            'gpt-4o': 'openai:chat:gpt-4o',
            'gpt-4o-audio-preview': 'azure:chat:gpt-4o-audio-preview',
            'gpt-audio': 'azure:chat:gpt-audio',
            'gpt-audio-1.5': 'azure:chat:gpt-audio-1.5',
            'gpt-audio-2025-08-28': 'azure:chat:gpt-audio-2025-08-28',
            'gpt-4.1': 'openai:chat:gpt-4',
            'claude': 'anthropic:messages:claude-3-5-sonnet-20241022',
            'halloumi': 'openai:chat:halloumi',
            'qwen3-vl-30b': 'huggingface:Qwen/Qwen3-VL-235B-A22B-Instruct:novita',
            'text-embedding-3-small': 'openai:embedding:text-embedding-3-small',
        };
        // Get model name from config if available, otherwise use providerName
        const modelName = config?.modelName || config?.model || providerName;
        let providerPath = providerPathMap[providerName.toLowerCase()] || providerName;
        // If providerPath doesn't contain model, append modelName if available
        if (modelName && !providerPath.includes(':') && modelName !== providerName) {
            providerPath = `${providerPath}:${modelName}`;
        }
        // Create provider with config from database
        const providerOptions = {
            id: providerPath,
            config: {
                ...config,
                ...(config?.env ? { env: config.env } : {}),
            },
            env,
        };
        const provider = await (0, index_1.loadApiProvider)(providerPath, {
            options: providerOptions,
            env,
        });
        logger_1.default.debug(`Created provider from DB config: ${providerName} -> ${providerPath}`);
        return provider;
    }
    catch (error) {
        logger_1.default.warn(`Failed to create provider from DB config ${providerConfig.providerName}: ${error}`);
        return null;
    }
}
// Helper function to get default providers based on credentials (fallback logic)
const getFallbackProviders = async (env, preferAzure, preferAnthropic, hasAnthropicCredentials, hasOpenAiCredentials) => {
    const deepgramProvider = new deepgram_1.DeepGramSttProvider();
    const videoModel = (0, envars_1.getEnvString)('HUGGINGFACE_VIDEO_MODEL') ||
        env?.HUGGINGFACE_VIDEO_MODEL ||
        DefaultHuggingfaceVideoModelName;
    const huggingfaceVideoProvider = new huggingfaceRouter_1.HuggingfaceRouterChatProvider(videoModel);
    const hallucinationModel = (0, envars_1.getEnvString)('HUGGINGFACE_HALLUCINATION_MODEL') ||
        env?.HUGGINGFACE_HALLUCINATION_MODEL ||
        'oumi-ai/HallOumi-8B:featherless-ai';
    const hallucinationProvider = new huggingfaceRouter_1.HuggingfaceRouterChatProvider(hallucinationModel);
    if (preferAzure) {
        logger_1.default.debug('Using Azure OpenAI default providers (fallback)');
        const deploymentName = (0, envars_1.getEnvString)('AZURE_OPENAI_DEPLOYMENT_NAME') || env?.AZURE_OPENAI_DEPLOYMENT_NAME;
        if (!deploymentName) {
            throw new Error('AZURE_OPENAI_DEPLOYMENT_NAME must be set when using Azure OpenAI');
        }
        const embeddingDeploymentName = (0, envars_1.getEnvString)('AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME') ||
            env?.AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME ||
            deploymentName;
        const audioDeploymentName = (0, envars_1.getEnvString)('AZURE_OPENAI_AUDIO_DEPLOYMENT_NAME') ||
            env?.AZURE_OPENAI_AUDIO_DEPLOYMENT_NAME ||
            DefaultAzureOpenAiAudioDeploymentName;
        const azureProvider = new chat_1.AzureChatCompletionProvider(deploymentName, { env });
        const azureAudioProvider = new chat_1.AzureChatCompletionProvider(audioDeploymentName, { env });
        const azureEmbeddingProvider = new embedding_1.AzureEmbeddingProvider(embeddingDeploymentName, {
            env,
        });
        return {
            embeddingProvider: azureEmbeddingProvider,
            gradingJsonProvider: azureProvider,
            gradingProvider: azureProvider,
            moderationProvider: defaults_3.DefaultModerationProvider,
            suggestionsProvider: azureProvider,
            synthesizeProvider: azureProvider,
            audioProvider: azureAudioProvider,
            sttProvider: deepgramProvider,
            videoProvider: huggingfaceVideoProvider,
            hallucinationProvider,
        };
    }
    else if (preferAnthropic) {
        logger_1.default.debug('Using Anthropic default providers (fallback)');
        const anthropicProviders = (0, defaults_1.getAnthropicProviders)(env);
        return {
            embeddingProvider: defaults_3.DefaultEmbeddingProvider, // TODO(ian): Voyager instead?
            gradingJsonProvider: anthropicProviders.gradingJsonProvider,
            gradingProvider: anthropicProviders.gradingProvider,
            llmRubricProvider: anthropicProviders.llmRubricProvider,
            moderationProvider: defaults_3.DefaultModerationProvider,
            suggestionsProvider: anthropicProviders.suggestionsProvider,
            synthesizeProvider: anthropicProviders.synthesizeProvider,
            audioProvider: defaults_3.DefaultAudioGradingProvider, // TODO: Change this
            sttProvider: deepgramProvider,
            videoProvider: huggingfaceVideoProvider,
            hallucinationProvider,
        };
    }
    else if (!(0, envars_1.getEnvString)('OPENAI_API_KEY') &&
        !env?.OPENAI_API_KEY &&
        (await (0, util_1.hasGoogleDefaultCredentials)())) {
        logger_1.default.debug('Using Google default providers (fallback)');
        return {
            embeddingProvider: vertex_1.DefaultEmbeddingProvider,
            gradingJsonProvider: vertex_1.DefaultGradingProvider,
            gradingProvider: vertex_1.DefaultGradingProvider,
            moderationProvider: defaults_3.DefaultModerationProvider,
            suggestionsProvider: vertex_1.DefaultGradingProvider,
            synthesizeProvider: vertex_1.DefaultGradingProvider,
            audioProvider: defaults_3.DefaultAudioGradingProvider, // TODO: Change this
            sttProvider: deepgramProvider,
            videoProvider: huggingfaceVideoProvider,
            hallucinationProvider,
        };
    }
    else if (!(0, envars_1.getEnvString)('OPENAI_API_KEY') &&
        !env?.OPENAI_API_KEY &&
        !hasAnthropicCredentials &&
        !(await (0, util_1.hasGoogleDefaultCredentials)()) &&
        ((0, envars_1.getEnvString)('MISTRAL_API_KEY') || env?.MISTRAL_API_KEY)) {
        logger_1.default.debug('Using Mistral default providers (fallback)');
        return {
            embeddingProvider: defaults_2.DefaultEmbeddingProvider,
            gradingJsonProvider: defaults_2.DefaultGradingJsonProvider,
            gradingProvider: defaults_2.DefaultGradingProvider,
            moderationProvider: defaults_3.DefaultModerationProvider,
            suggestionsProvider: defaults_2.DefaultSuggestionsProvider,
            synthesizeProvider: defaults_2.DefaultSynthesizeProvider,
            audioProvider: defaults_3.DefaultAudioGradingProvider, // TODO: Change this
            sttProvider: deepgramProvider,
            videoProvider: huggingfaceVideoProvider,
            hallucinationProvider,
        };
    }
    else {
        logger_1.default.debug('Using OpenAI default providers (fallback)');
        return {
            embeddingProvider: defaults_3.DefaultEmbeddingProvider,
            gradingJsonProvider: defaults_3.DefaultGradingJsonProvider,
            gradingProvider: defaults_3.DefaultGradingProvider,
            moderationProvider: defaults_3.DefaultModerationProvider,
            suggestionsProvider: defaults_3.DefaultSuggestionsProvider,
            synthesizeProvider: defaults_3.DefaultGradingJsonProvider,
            audioProvider: defaults_3.DefaultAudioGradingProvider,
            sttProvider: deepgramProvider,
            videoProvider: huggingfaceVideoProvider,
            hallucinationProvider,
        };
    }
};
async function getDefaultProviders(env, workspaceId = '') {
    // Fetch workspace-specific providers from database if workspaceId is provided
    let workspaceProviders = new Map();
    if (lodash_1.default.isEmpty(workspaceId) === false && workspaceId !== 'undefined') {
        const providerTypes = [
            constants_1.PROVIDER_TYPE.TTS,
            constants_1.PROVIDER_TYPE.STT,
            constants_1.PROVIDER_TYPE.MAIN_EVAL_MODEL,
            constants_1.PROVIDER_TYPE.AUDIO_EVAL_MODEL,
            constants_1.PROVIDER_TYPE.AUDIO_GENERATION_MODEL,
            constants_1.PROVIDER_TYPE.HALLUCINATION_MODEL,
            constants_1.PROVIDER_TYPE.VISUAL_EVAL_MODEL,
            constants_1.PROVIDER_TYPE.PROMPT_INJECTION,
            constants_1.PROVIDER_TYPE.CONTENT_SAFETY,
            constants_1.PROVIDER_TYPE.PHONE_PROVIDER,
            constants_1.PROVIDER_TYPE.EMBEDDING_MODEL,
        ];
        workspaceProviders = await (0, findWorkspaceProvider_1.findProviders)(workspaceId, providerTypes);
        if (workspaceProviders.size > 0) {
            logger_1.default.debug(`Found ${workspaceProviders.size} workspace-specific provider(s) for workspace ${workspaceId}`);
        }
    }
    // Check for provider credentials (for fallback logic)
    const hasAnthropicCredentials = Boolean((0, envars_1.getEnvString)('ANTHROPIC_API_KEY') || env?.ANTHROPIC_API_KEY);
    const hasOpenAiCredentials = Boolean((0, envars_1.getEnvString)('OPENAI_API_KEY') || env?.OPENAI_API_KEY);
    const preferAnthropic = !hasOpenAiCredentials && hasAnthropicCredentials;
    const preferAzure = true;
    // Get fallback providers first (will be used if DB providers not found)
    const fallbackProviders = await getFallbackProviders(env, preferAzure, preferAnthropic, hasAnthropicCredentials, hasOpenAiCredentials);
    const providers = { ...fallbackProviders };
    // Override with database providers if found
    const audioGenerationModel = workspaceProviders.get(constants_1.PROVIDER_TYPE.AUDIO_GENERATION_MODEL);
    const audioEvalModel = workspaceProviders.get(constants_1.PROVIDER_TYPE.AUDIO_EVAL_MODEL);
    if (audioGenerationModel) {
        const dbAudioProvider = await createProviderFromConfig(audioGenerationModel, env);
        if (dbAudioProvider) {
            providers.audioProvider = dbAudioProvider;
            logger_1.default.debug(`Using workspace audio generation model: ${audioGenerationModel.providerName}`);
        }
    }
    else if (audioEvalModel) {
        const dbAudioProvider = await createProviderFromConfig(audioEvalModel, env);
        if (dbAudioProvider) {
            providers.audioProvider = dbAudioProvider;
            logger_1.default.debug(`Using workspace audio eval model: ${audioEvalModel.providerName}`);
        }
    }
    const embeddingModel = workspaceProviders.get(constants_1.PROVIDER_TYPE.EMBEDDING_MODEL);
    if (embeddingModel) {
        const dbEmbeddingProvider = await createProviderFromConfig(embeddingModel, env);
        if (dbEmbeddingProvider) {
            providers.embeddingProvider = dbEmbeddingProvider;
            logger_1.default.debug(`Using workspace embedding model: ${embeddingModel.providerName}`);
        }
    }
    const mainEvalModel = workspaceProviders.get(constants_1.PROVIDER_TYPE.MAIN_EVAL_MODEL);
    if (mainEvalModel) {
        const dbMainEvalProvider = await createProviderFromConfig(mainEvalModel, env);
        if (dbMainEvalProvider) {
            providers.gradingJsonProvider = dbMainEvalProvider;
            providers.gradingProvider = dbMainEvalProvider;
            providers.suggestionsProvider = dbMainEvalProvider;
            providers.synthesizeProvider = dbMainEvalProvider;
            logger_1.default.debug(`Using workspace main eval model: ${mainEvalModel.providerName}`);
        }
    }
    const sttProvider = workspaceProviders.get(constants_1.PROVIDER_TYPE.STT);
    if (sttProvider) {
        const dbSttProvider = await createProviderFromConfig(sttProvider, env);
        if (dbSttProvider) {
            providers.sttProvider = dbSttProvider;
            logger_1.default.debug(`Using workspace STT provider: ${sttProvider.providerName}`);
        }
    }
    const hallucinationModel = workspaceProviders.get(constants_1.PROVIDER_TYPE.HALLUCINATION_MODEL);
    if (hallucinationModel) {
        const dbHallucinationProvider = await createProviderFromConfig(hallucinationModel, env);
        if (dbHallucinationProvider) {
            providers.hallucinationProvider = dbHallucinationProvider;
            logger_1.default.debug(`Using workspace hallucination model: ${hallucinationModel.providerName}`);
        }
    }
    const visualEvalModel = workspaceProviders.get(constants_1.PROVIDER_TYPE.VISUAL_EVAL_MODEL);
    if (visualEvalModel) {
        const dbVisualEvalProvider = await createProviderFromConfig(visualEvalModel, env);
        if (dbVisualEvalProvider) {
            providers.videoProvider = dbVisualEvalProvider;
            logger_1.default.debug(`Using workspace video eval model: ${visualEvalModel.providerName}`);
        }
    }
    // Log other workspace provider types for future implementation
    const otherProviderTypes = [
        // PROVIDER_TYPE.TTS, Handled separately in convertTextToAudioWithProvider
        constants_1.PROVIDER_TYPE.PROMPT_INJECTION,
        constants_1.PROVIDER_TYPE.CONTENT_SAFETY,
        // PROVIDER_TYPE.PHONE_PROVIDER, Default is Twilio
    ];
    otherProviderTypes.forEach((providerType) => {
        const provider = workspaceProviders.get(providerType);
        if (provider) {
            logger_1.default.debug(`Workspace has custom ${providerType} configured: ${provider.providerName} (using default for now)`);
            // TODO: Implement provider factories for these types when needed
        }
    });
    // If Azure Content Safety endpoint is available, use it for moderation
    if ((0, envars_1.getEnvString)('AZURE_CONTENT_SAFETY_ENDPOINT') || env?.AZURE_CONTENT_SAFETY_ENDPOINT) {
        providers.moderationProvider = new moderation_1.AzureModerationProvider('text-content-safety', { env });
    }
    if (defaultCompletionProvider) {
        logger_1.default.debug(`Overriding default completion provider: ${defaultCompletionProvider.id()}`);
        COMPLETION_PROVIDERS.forEach((provider) => {
            providers[provider] = defaultCompletionProvider;
        });
    }
    if (defaultEmbeddingProvider) {
        EMBEDDING_PROVIDERS.forEach((provider) => {
            providers[provider] = defaultEmbeddingProvider;
        });
    }
    return providers;
}
//# sourceMappingURL=defaults.js.map