const DEFAULT_GITHUB_CONFIG = {
    model: "openai/gpt-4o-mini",
    baseUrl: "https://models.inference.ai.azure.com",
};
/**
 * GitHub Models Adapter — Access frontier models through GitHub's
 * models marketplace. Uses the OpenAI-compatible chat completions
 * endpoint under the hood.
 *
 * Requires a GitHub PAT with the `models` scope.
 * Browse available models: https://github.com/marketplace/models
 */
export class GitHubModelsAdapter {
    provider = "github";
    config;
    get name() {
        return `GitHub Models (${this.config.model})`;
    }
    constructor(config) {
        this.config = { ...DEFAULT_GITHUB_CONFIG, ...config };
    }
    async available() {
        if (!this.config.token)
            return false;
        try {
            const controller = new AbortController();
            const timeout = setTimeout(() => controller.abort(), 5000);
            // GitHub Models uses an OpenAI-compatible endpoint
            // Just test auth by hitting the models list
            const res = await fetch(`${this.config.baseUrl}/models`, {
                headers: { Authorization: `Bearer ${this.config.token}` },
                signal: controller.signal,
            });
            clearTimeout(timeout);
            // 200 = authenticated, 401 = bad token
            return res.ok || res.status === 200;
        }
        catch {
            // If the models endpoint doesn't exist, still try — the chat
            // endpoint is what matters. Assume available if token is set.
            return !!this.config.token;
        }
    }
    async chat(messages, options) {
        const startMs = Date.now();
        // GitHub Models uses the OpenAI chat completions format
        const actualModel = this.config.model.includes("/")
            ? this.config.model.split("/").pop()
            : this.config.model;
        const body = {
            model: actualModel,
            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.token}`,
            },
            body: JSON.stringify(body),
        });
        if (!res.ok) {
            const text = await res.text();
            throw new Error(`GitHub Models 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=github-adapter.js.map