"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.GeminiAdapter = void 0;
const DEFAULT_GEMINI_CONFIG = {
    model: "gemini-2.0-flash",
};
const GEMINI_API_BASE = "https://generativelanguage.googleapis.com/v1beta";
/**
 * Gemini Adapter — Google's Gemini API for deep reasoning with massive
 * context windows. Ideal for parsing large Anchor IDL files and
 * multi-file codebase analysis.
 */
class GeminiAdapter {
    provider = "gemini";
    config;
    get name() {
        return `Gemini (${this.config.model})`;
    }
    constructor(config) {
        this.config = { ...DEFAULT_GEMINI_CONFIG, ...config };
    }
    async available() {
        if (!this.config.apiKey)
            return false;
        try {
            const controller = new AbortController();
            const timeout = setTimeout(() => controller.abort(), 5000);
            const url = `${GEMINI_API_BASE}/models/${this.config.model}?key=${this.config.apiKey}`;
            const res = await fetch(url, { signal: controller.signal });
            clearTimeout(timeout);
            return res.ok;
        }
        catch {
            return false;
        }
    }
    async chat(messages, options) {
        const startMs = Date.now();
        // Convert to Gemini format
        const systemInstruction = messages
            .filter((m) => m.role === "system")
            .map((m) => m.content)
            .join("\n");
        const contents = messages
            .filter((m) => m.role !== "system")
            .map((m) => ({
            role: m.role === "assistant" ? "model" : "user",
            parts: [{ text: m.content }],
        }));
        const body = {
            contents,
            generationConfig: {
                temperature: options?.temperature ?? 0.1,
                maxOutputTokens: options?.maxTokens ?? 8192,
            },
        };
        if (systemInstruction) {
            body.systemInstruction = { parts: [{ text: systemInstruction }] };
        }
        // Add tool declarations if provided
        if (options?.tools && options.tools.length > 0) {
            body.tools = [
                {
                    functionDeclarations: options.tools.map((t) => this.toGeminiFunctionDecl(t)),
                },
            ];
        }
        if (options?.responseFormat === "json") {
            body.generationConfig.responseMimeType =
                "application/json";
        }
        const url = `${GEMINI_API_BASE}/models/${this.config.model}:generateContent?key=${this.config.apiKey}`;
        const res = await fetch(url, {
            method: "POST",
            headers: { "Content-Type": "application/json" },
            body: JSON.stringify(body),
        });
        if (!res.ok) {
            const text = await res.text();
            throw new Error(`Gemini error (${res.status}): ${text}`);
        }
        const data = (await res.json());
        const candidate = data.candidates?.[0];
        const parts = candidate?.content?.parts ?? [];
        // Extract text content
        const textContent = parts
            .filter((p) => "text" in p)
            .map((p) => p.text)
            .join("");
        // Extract function calls
        const toolCalls = parts
            .filter((p) => "functionCall" in p)
            .map((p, i) => ({
            id: `gemini_call_${Date.now()}_${i}`,
            name: p.functionCall.name,
            arguments: p.functionCall.args ?? {},
        }));
        const usage = data.usageMetadata;
        return {
            content: textContent,
            toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
            usage: usage
                ? {
                    promptTokens: usage.promptTokenCount ?? 0,
                    completionTokens: usage.candidatesTokenCount ?? 0,
                    totalTokens: usage.totalTokenCount ?? 0,
                }
                : undefined,
            finishReason: toolCalls.length > 0 ? "tool_calls" : "stop",
            model: this.config.model,
            latencyMs: Date.now() - startMs,
        };
    }
    toGeminiFunctionDecl(tool) {
        return {
            name: tool.name,
            description: tool.description,
            parameters: {
                type: "object",
                properties: tool.parameters.properties,
                required: tool.parameters.required ?? [],
            },
        };
    }
}
exports.GeminiAdapter = GeminiAdapter;
//# sourceMappingURL=gemini-adapter.js.map