"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
    return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.MicrosoftFoundryProvider = void 0;
const identity_1 = require("@azure/identity");
const ai_projects_1 = require("@azure/ai-projects");
const logger_1 = __importDefault(require("../../logger"));
class MicrosoftFoundryProvider {
    constructor(config, options = {}) {
        this.config = options.config || {};
        this.providerConfig = config;
        try {
            // Initialize Azure credentials
            // Use ClientSecretCredential if credentials are provided, otherwise use DefaultAzureCredential
            let credential;
            if (this.providerConfig.azureClientId && this.providerConfig.azureClientSecret && this.providerConfig.azureTenantId) {
                logger_1.default.debug('[Microsoft Foundry Provider]: Using ClientSecretCredential for authentication');
                credential = new identity_1.ClientSecretCredential(this.providerConfig.azureTenantId, this.providerConfig.azureClientId, this.providerConfig.azureClientSecret);
            }
            else {
                logger_1.default.debug('[Microsoft Foundry Provider]: Using DefaultAzureCredential for authentication');
                credential = new identity_1.DefaultAzureCredential();
            }
            this.projectClient = new ai_projects_1.AIProjectClient(this.providerConfig.projectEndpoint, credential);
            // Verify the client was created
            if (!this.projectClient) {
                throw new Error('Failed to create AIProjectClient');
            }
            logger_1.default.debug(`[Microsoft Foundry Provider]: Successfully created AIProjectClient with endpoint: ${this.providerConfig.projectEndpoint}`);
        }
        catch (err) {
            logger_1.default.error(`[Microsoft Foundry Provider]: Failed to initialize client: ${String(err)}`);
            if (err instanceof Error && (err.message.includes('CredentialUnavailableError') || err.message.includes('authentication'))) {
                throw new Error(`Azure authentication failed. Please provide Azure credentials (Client ID, Secret, Tenant ID) or run: az login --scope https://ai.azure.com/.default\n\nOriginal error: ${err.message}`);
            }
            throw new Error(`Failed to initialize Microsoft Foundry client: ${String(err)}`);
        }
    }
    id() {
        return `microsoft-foundry:${this.providerConfig.agentName}`;
    }
    async getAgentByName(agentName) {
        for await (const agent of this.projectClient.agents.listAgents()) {
            if (agent.name === agentName) {
                return agent;
            }
        }
        throw new Error(`Agent with name '${agentName}' not found`);
    }
    async initializeAgent() {
        if (this.agent && this.openAIClient) {
            return;
        }
        try {
            // Verify projectClient is initialized
            if (!this.projectClient) {
                throw new Error('Project client is not initialized');
            }
            // Retrieve Agent by name (latest version) - using the exact API from Azure example
            // Using type assertion since TypeScript definitions may not include all methods
            logger_1.default.debug(`[Microsoft Foundry Provider]: Attempting to retrieve agent: ${this.providerConfig.agentName}`);
            const projectClientAny = this.projectClient;
            // Check if agents property exists
            if (!projectClientAny.agents) {
                const availableProps = Object.keys(projectClientAny).join(', ');
                throw new Error(`Agents client not found. Available properties: ${availableProps}`);
            }
            const agentsClient = projectClientAny.agents;
            // Check if the agentName is already an ID (starts with 'asst')
            if (this.providerConfig.agentName.startsWith('asst_')) {
                // It's an ID, use it directly
                logger_1.default.debug(`[Microsoft Foundry Provider]: Using agent ID: ${this.providerConfig.agentName}`);
                const getMethod = agentsClient.get?.bind(agentsClient) || agentsClient.getAgent?.bind(agentsClient);
                if (getMethod) {
                    this.agent = await getMethod(this.providerConfig.agentName);
                }
                else {
                    throw new Error('Failed to find agent retrieval method for ID');
                }
            }
            else {
                try {
                    this.agent = await this.getAgentByName(this.providerConfig.agentName);
                }
                catch (nameError) {
                    if (nameError.message?.includes("Expected an ID that begins with 'asst'")) {
                        throw new Error(`Agent name '${this.providerConfig.agentName}' provided, but SDK requires an agent ID (starting with 'asst_'). Please provide the agent ID instead, or ensure the agent name matches exactly.`);
                    }
                    throw nameError;
                }
            }
            if (!this.agent) {
                throw new Error(`Agent '${this.providerConfig.agentName}' not found`);
            }
            logger_1.default.debug(`[Microsoft Foundry Provider]: Retrieved agent - name: ${this.agent.versions?.latest?.name || this.agent.name || this.providerConfig.agentName}, id: ${this.agent.id || 'unknown'}`);
            // Get OpenAI client from project client - using the exact API from Azure example
            logger_1.default.debug('[Microsoft Foundry Provider]: Getting OpenAI client...');
            this.openAIClient = await this.projectClient.getAzureOpenAIClient();
            if (!this.openAIClient) {
                throw new Error('OpenAI client is null or undefined');
            }
            logger_1.default.debug('[Microsoft Foundry Provider]: Successfully initialized agent and OpenAI client');
        }
        catch (err) {
            logger_1.default.error(`[Microsoft Foundry Provider]: Failed to initialize agent: ${String(err)}`);
            if (err instanceof Error) {
                logger_1.default.error(`[Microsoft Foundry Provider]: Error stack: ${err.stack}`);
                // Check if it's an authentication error
                if (err.message.includes('ChainedTokenCredential') || err.message.includes('CredentialUnavailableError') || err.message.includes('authentication failed')) {
                    const authError = `Azure authentication failed: ${err.message}`;
                    throw new Error(authError);
                }
                throw new Error(`Failed to initialize Microsoft Foundry agent: ${err.message}`);
            }
            throw new Error(`Failed to initialize Microsoft Foundry agent: ${String(err)}`);
        }
    }
    async callApi(prompt, context) {
        await this.initializeAgent();
        try {
            // Create conversation with initial user message
            logger_1.default.debug('[Microsoft Foundry Provider]: Creating conversation...');
            const conversation = await this.openAIClient.conversations.create({
                items: [{ type: 'message', role: 'user', content: prompt }],
            });
            logger_1.default.debug(`[Microsoft Foundry Provider]: Created conversation with id: ${conversation.id}`);
            // Generate response using the agent
            logger_1.default.debug('[Microsoft Foundry Provider]: Generating response...');
            const response = await this.openAIClient.responses.create({
                conversation: conversation.id,
            }, {
                body: { agent: { name: this.agent.name, type: 'agent_reference' } },
            });
            logger_1.default.debug(`[Microsoft Foundry Provider]: Response output: ${response.output_text}`);
            return {
                output: response.output_text,
                metadata: {
                    conversationId: conversation.id,
                    agentName: this.agent.name,
                    agentId: this.agent.id,
                },
            };
        }
        catch (err) {
            logger_1.default.error(`[Microsoft Foundry Provider]: Error calling API: ${String(err)}`);
            return {
                error: `Microsoft Foundry API error: ${String(err)}`,
            };
        }
    }
}
exports.MicrosoftFoundryProvider = MicrosoftFoundryProvider;
//# sourceMappingURL=microsoft-foundry.js.map