/**
 * Backend API client for GATI MCP Server
 *
 * This module provides HTTP client functions to interact with the GATI backend API
 * instead of direct database access. This eliminates the need for native SQLite bindings
 * and makes the MCP server work across all platforms.
 */
let config = {
    backendUrl: process.env.BACKEND_URL || 'http://localhost:8000',
};
/**
 * Set backend configuration
 */
export function setBackendConfig(newConfig) {
    config = { ...config, ...newConfig };
}
/**
 * Get backend configuration
 */
export function getBackendConfig() {
    return config;
}
/**
 * Make HTTP request to backend API
 */
async function apiRequest(endpoint, options = {}) {
    const url = `${config.backendUrl}${endpoint}`;
    try {
        const response = await fetch(url, {
            ...options,
            headers: {
                'Content-Type': 'application/json',
                ...options.headers,
            },
        });
        if (!response.ok) {
            const errorText = await response.text();
            throw new Error(`Backend API error (${response.status}): ${errorText}`);
        }
        return await response.json();
    }
    catch (error) {
        if (error.message && error.message.includes('fetch')) {
            throw new Error(`Failed to connect to backend at ${config.backendUrl}. Is the backend running? Run 'gati start' to start it.`);
        }
        throw error;
    }
}
/**
 * List all agents
 */
export async function listAgents() {
    const agents = await apiRequest('/api/agents');
    // Map backend response to our interface (backend uses avg_cost, formatters expect avg_cost_per_run)
    return agents.map(agent => ({
        ...agent,
        avg_cost_per_run: agent.avg_cost || 0,
    }));
}
/**
 * Get agent statistics
 */
export async function getAgentStats(agentName) {
    try {
        const agent = await apiRequest(`/api/agents/${encodeURIComponent(agentName)}`);
        // Map backend response to our interface
        return {
            ...agent,
            avg_cost_per_run: agent.avg_cost || 0,
        };
    }
    catch (error) {
        if (error.message.includes('404')) {
            return null;
        }
        throw error;
    }
}
/**
 * Get runs for an agent
 */
export async function listRuns(agentName, limit = 20, offset = 0) {
    return apiRequest(`/api/agents/${encodeURIComponent(agentName)}/runs?limit=${limit}&offset=${offset}`);
}
/**
 * Get run details by agent name and run name
 */
export async function getRunByName(agentName, runName) {
    try {
        const run = await apiRequest(`/api/runs/${encodeURIComponent(agentName)}/${encodeURIComponent(runName)}`);
        // Ensure event_count is included
        return {
            ...run,
            event_count: run.event_count || 0,
        };
    }
    catch (error) {
        if (error.message && error.message.includes('404')) {
            return null;
        }
        throw error;
    }
}
/**
 * Get run timeline (chronological events)
 */
export async function getRunTimeline(agentName, runName) {
    try {
        const response = await apiRequest(`/api/runs/${encodeURIComponent(agentName)}/${encodeURIComponent(runName)}/timeline`);
        return response.events || [];
    }
    catch (error) {
        if (error.message.includes('404')) {
            return [];
        }
        throw error;
    }
}
/**
 * Get execution trace (hierarchical events)
 */
export async function getExecutionTrace(agentName, runName) {
    try {
        const response = await apiRequest(`/api/runs/${encodeURIComponent(agentName)}/${encodeURIComponent(runName)}/trace`);
        return response.events || [];
    }
    catch (error) {
        if (error.message.includes('404')) {
            return [];
        }
        throw error;
    }
}
/**
 * Get global metrics
 */
export async function getGlobalMetrics() {
    return apiRequest('/api/metrics/summary');
}
/**
 * Search events (using backend API if available, otherwise return empty)
 * Note: Backend may not have a search endpoint, so this is a placeholder
 */
export async function searchEvents(agentName, eventType, startTime, endTime, limit = 100) {
    // For now, if we need search, we can get all runs for an agent and filter
    // This is a simplified implementation
    if (!agentName) {
        // Get all agents and their runs - simplified for now
        const agents = await listAgents();
        const allEvents = [];
        for (const agent of agents.slice(0, 10)) { // Limit to first 10 agents
            const runs = await listRuns(agent.name, 10, 0);
            for (const run of runs) {
                const events = await getRunTimeline(agent.name, run.run_name);
                allEvents.push(...events);
            }
        }
        return allEvents.slice(0, limit);
    }
    // Get runs for specific agent
    const runs = await listRuns(agentName, 50, 0);
    const allEvents = [];
    for (const run of runs) {
        const events = await getRunTimeline(agentName, run.run_name);
        allEvents.push(...events);
    }
    // Filter by event type if provided
    let filtered = eventType
        ? allEvents.filter(e => e.event_type === eventType)
        : allEvents;
    // Filter by time range if provided
    if (startTime) {
        filtered = filtered.filter(e => new Date(e.timestamp) >= startTime);
    }
    if (endTime) {
        filtered = filtered.filter(e => new Date(e.timestamp) <= endTime);
    }
    return filtered.slice(0, limit);
}
/**
 * Get cost breakdown by model
 * Note: This may need to be implemented in the backend or calculated from events
 */
export async function getCostBreakdown(agentName) {
    // For now, get events and calculate cost breakdown
    // This is a simplified implementation
    const events = agentName
        ? await searchEvents(agentName, 'llm_call', undefined, undefined, 1000)
        : await searchEvents(undefined, 'llm_call', undefined, undefined, 1000);
    const breakdown = {};
    for (const event of events) {
        if (event.event_type === 'llm_call' && event.data?.model) {
            const model = event.data.model;
            if (!breakdown[model]) {
                breakdown[model] = {
                    model,
                    total_cost: 0,
                    total_tokens_in: 0,
                    total_tokens_out: 0,
                    call_count: 0,
                };
            }
            breakdown[model].total_cost += event.data.cost || 0;
            breakdown[model].total_tokens_in += event.data.tokens_in || 0;
            breakdown[model].total_tokens_out += event.data.tokens_out || 0;
            breakdown[model].call_count += 1;
        }
    }
    return Object.values(breakdown);
}
//# sourceMappingURL=client.js.map