const DEFAULT_OPENAI_CONFIG = {
    model: "gpt-4o-mini",
    baseUrl: "https://api.openai.com/v1",
};
/**
 * OpenAI Adapter — For rapid code refactoring, structured JSON output,
 * and native function calling. Works with any OpenAI-compatible API.
 */
export class OpenAIAdapter {
    provider = "openai";
    config;
    get name() {
        return `OpenAI (${this.config.model})`;
    }
    constructor(config) {
        this.config = { ...DEFAULT_OPENAI_CONFIG, ...config };
    }
    async available() {
        if (!this.config.apiKey)
            return false;
        try {
            const controller = new AbortController();
            const timeout = setTimeout(() => controller.abort(), 5000);
            const res = await fetch(`${this.config.baseUrl}/models`, {
                headers: { Authorization: `Bearer ${this.config.apiKey}` },
                signal: controller.signal,
            });
            clearTimeout(timeout);
            return res.ok;
        }
        catch {
            return false;
        }
    }
    async chat(messages, options) {
        const startMs = Date.now();
        const body = {
            model: this.config.model,
            messages: messages.map((m) => {
                const msg = {
                    role: m.role,
                    content: m.content,
                };
                if (m.toolCallId)
                    msg.tool_call_id = m.toolCallId;
                if (m.name)
                    msg.name = m.name;
                return msg;
            }),
            temperature: options?.temperature ?? 0.1,
            max_tokens: options?.maxTokens ?? 4096,
        };
        // Add tools for function calling
        if (options?.tools && options.tools.length > 0) {
            body.tools = options.tools.map((t) => this.toOpenAITool(t));
            body.tool_choice = "auto";
        }
        if (options?.responseFormat === "json") {
            body.response_format = { type: "json_object" };
        }
        if (options?.stop) {
            body.stop = options.stop;
        }
        const res = await fetch(`${this.config.baseUrl}/chat/completions`, {
            method: "POST",
            headers: {
                "Content-Type": "application/json",
                Authorization: `Bearer ${this.config.apiKey}`,
            },
            body: JSON.stringify(body),
        });
        if (!res.ok) {
            const text = await res.text();
            throw new Error(`OpenAI error (${res.status}): ${text}`);
        }
        const data = (await res.json());
        const choice = data.choices?.[0];
        const message = choice?.message;
        // Extract tool calls
        const toolCalls = (message?.tool_calls ?? []).map((tc) => ({
            id: tc.id,
            name: tc.function.name,
            arguments: this.safeParseArgs(tc.function.arguments),
        }));
        return {
            content: message?.content ?? "",
            toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
            usage: data.usage
                ? {
                    promptTokens: data.usage.prompt_tokens,
                    completionTokens: data.usage.completion_tokens,
                    totalTokens: data.usage.total_tokens,
                }
                : undefined,
            finishReason: choice?.finish_reason === "tool_calls" ? "tool_calls" : "stop",
            model: data.model ?? this.config.model,
            latencyMs: Date.now() - startMs,
        };
    }
    toOpenAITool(tool) {
        return {
            type: "function",
            function: {
                name: tool.name,
                description: tool.description,
                parameters: tool.parameters,
            },
        };
    }
    safeParseArgs(raw) {
        try {
            return JSON.parse(raw);
        }
        catch {
            return { _raw: raw };
        }
    }
}
//# sourceMappingURL=openai-adapter.js.map