import { logEvent } from "./logger.js";
import { imageToolChoice, tools } from "./responsesTools.js";
import { emptyResponseError } from "./responsesErrors.js";
import { GENERATE_DEVELOPER_PROMPT, GENERATE_NO_SEARCH_DEVELOPER_PROMPT, buildUserTextPrompt, } from "./oauthProxy.js";
const MAX_RETRIES = 2;
export async function retryPromptOnlyJsonImage({ postResponses, ctx, provider, prompt, mode, model, quality, size, moderation, requestId, signal, initial, referencesDroppedOnRetry, webSearchDroppedOnRetry, reasoningEffort, }) {
    if (provider === "api")
        return null;
    const retryKind = "prompt_only_with_developer";
    const retryMeta = {
        retryKind,
        initialEventCount: initial.eventCount,
        initialEventTypes: initial.eventTypes,
        referencesDroppedOnRetry,
        developerPromptDroppedOnRetry: false,
        webSearchDroppedOnRetry,
    };
    const developerPrompt = webSearchDroppedOnRetry
        ? GENERATE_NO_SEARCH_DEVELOPER_PROMPT
        : GENERATE_DEVELOPER_PROMPT;
    let lastRetry = null;
    for (let attempt = 1; attempt <= MAX_RETRIES; attempt++) {
        logEvent("oauth", "retry_attempt", { requestId, attempt, maxRetries: MAX_RETRIES, ...retryMeta });
        try {
            lastRetry = await postResponses({
                ctx,
                provider,
                scope: "oauth-fallback",
                requestId,
                maxImages: 1,
                signal,
                payload: {
                    model,
                    input: [
                        { role: "developer", content: developerPrompt },
                        { role: "user", content: buildUserTextPrompt(prompt, mode, { webSearchEnabled: false }) },
                    ],
                    tools: tools(false, { quality, size, moderation }),
                    tool_choice: imageToolChoice(true),
                    reasoning: { effort: reasoningEffort || "low" },
                    stream: false,
                },
            });
        }
        catch (e) {
            if (attempt === MAX_RETRIES) {
                if (e && typeof e === "object")
                    Object.assign(e, retryMeta);
                throw e;
            }
            logEvent("oauth", "retry_error", { requestId, attempt, error: e.message, status: e.status, code: e.code });
            continue;
        }
        const image = lastRetry.images[0];
        if (image?.b64) {
            logEvent("oauth", "retry_image", { requestId, retryKind, attempt, imageChars: image.b64.length });
            return { b64: image.b64, usage: lastRetry.usage, webSearchCalls: initial.webSearchCalls, revisedPrompt: image.revisedPrompt, text: lastRetry.text, ...retryMeta };
        }
        logEvent("oauth", "retry_no_image", { requestId, retryKind, attempt, fallbackEventCount: lastRetry.eventCount });
    }
    const diagSource = lastRetry ?? initial;
    throw emptyResponseError("No image data received after retries", diagSource, {
        provider,
        model,
        quality,
        size,
        moderation,
        webSearchEnabled: false,
        refsCount: 0,
        inputImageCount: 0,
        promptChars: typeof prompt === "string" ? prompt.length : 0,
        toolTypes: ["image_generation"],
        toolChoiceKind: "image_generation",
        ...retryMeta,
        fallbackEventCount: diagSource.eventCount,
        fallbackEventTypes: diagSource.eventTypes,
        fallbackImageCallSeen: diagSource.diagnostics.imageCallSeen,
        fallbackImageResultCount: diagSource.diagnostics.imageResultCount,
    });
}
