import Anthropic from '@anthropic-ai/sdk';
import { FallbackGenerator } from './fallback-generator.js';
import { QualityValidator } from './quality-validator.js';
export class OpusGenerator {
    model;
    timeoutMs;
    client;
    fallback;
    validator;
    constructor(deps) {
        this.model = deps.model ?? 'claude-opus-4-5';
        this.timeoutMs = deps.timeoutMs ?? 60_000;
        this.client = deps.client ?? new Anthropic({ apiKey: deps.apiKey }).messages;
        this.fallback = deps.fallback ?? new FallbackGenerator();
        this.validator = deps.validator ?? new QualityValidator();
    }
    async generate(request) {
        const controller = new AbortController();
        const timeout = setTimeout(() => {
            controller.abort();
        }, this.timeoutMs);
        try {
            const response = await this.client.create({
                model: this.model,
                max_tokens: 6000,
                temperature: 0.2,
                system: buildSystemPrompt(),
                messages: [{ role: 'user', content: buildUserPrompt(request) }],
            }, { signal: controller.signal });
            const text = response.content
                .filter((block) => block.type === 'text' && typeof block.text === 'string')
                .map((block) => block.text)
                .join('\n')
                .trim();
            if (response.content.some((block) => block.type === 'tool_use') || text.length === 0) {
                return await this.fallbackWithReason(request, 'tool-use-leak');
            }
            const result = parseGeneratedText(text, this.model);
            const validation = this.validator.validate(result);
            if (validation.passed) {
                return result;
            }
            return { ...result, qualityWarnings: validation.warnings };
        }
        catch {
            return await this.fallbackWithReason(request, 'timeout-or-http-error');
        }
        finally {
            clearTimeout(timeout);
        }
    }
    async fallbackWithReason(request, reason) {
        const fallback = await this.fallback.generate(request);
        return {
            ...fallback,
            qualityWarnings: [
                ...fallback.qualityWarnings,
                `Opus generator fallback used: ${reason}. Configure PLANU_ANTHROPIC_API_KEY for Opus-quality create_spec generation.`,
            ],
            fallbackReason: reason,
        };
    }
}
function buildSystemPrompt() {
    return [
        'You generate Planu unified spec.md content.',
        'Do not invoke any tools. Do not request tool use. Return markdown only.',
        'Include ## Problem, ## Acceptance Criteria, ## Technical, ## Files, and ## Verification.',
        'Acceptance criteria must include at least 3 GIVEN/WHEN/THEN items.',
        'Technical must include at least 2 TypeScript signatures relevant to the requested change.',
    ].join('\n');
}
function buildUserPrompt(request) {
    return [
        `Title: ${request.title}`,
        `Type: ${request.type}`,
        `Scope: ${request.scope}`,
        `Target: ${request.target}`,
        request.projectContext?.language ? `Language: ${request.projectContext.language}` : '',
        request.projectContext?.framework ? `Framework: ${request.projectContext.framework}` : '',
        '',
        request.description,
    ]
        .filter(Boolean)
        .join('\n');
}
function parseGeneratedText(text, model) {
    const technicalMatch = /\n## Technical\n([\s\S]*?)(?=\n## |\s*$)/.exec(`\n${text}`);
    return {
        specBody: text,
        technicalSection: technicalMatch?.[1]?.trim() ?? '',
        generatedWithModel: model,
        generatedAt: new Date().toISOString(),
        qualityWarnings: [],
    };
}
//# sourceMappingURL=opus-generator.js.map