import { MAX_OUTPUT_TOKENS, MODEL_CAPABILITIES, } from "@superblocksteam/library-shared/types";
import { getLogger } from "../../util/logger.js";
const INTERLEAVED_THINKING_BETA = "interleaved-thinking-2025-05-14";
const EFFORT_BETA = "effort-2025-11-24";
/**
 * Models that require Anthropic's adaptive-thinking API + `output_config.effort`.
 *
 * Opus 4.7 rejects `thinking: { type: "enabled" }` with a 400. We hardcode
 * effort to `"high"` for these models regardless of other thinking flags —
 * the legacy `budgetTokens` knob does not apply.
 */
const ADAPTIVE_EFFORT_MODELS = new Set(["claude-opus-4-7"]);
const HARDCODED_EFFORT = "high";
export function usesAdaptiveEffort(coreModel) {
    return coreModel !== undefined && ADAPTIVE_EFFORT_MODELS.has(coreModel);
}
/**
 * Builds the provider-specific thinking config for a given core model.
 *
 * This is a pure function so retries that swap models (e.g. opus-4-7 →
 * sonnet-4-6 → opus-4-7) can call it per attempt to emit the shape the
 * current model accepts. See {@link usesAdaptiveEffort}.
 */
export function buildThinkingProviderOptions(coreModel, params) {
    const { thinkingEnabled, thinkingBudgetTokens, interleavedThinking } = params;
    if (usesAdaptiveEffort(coreModel)) {
        const anthropic = {
            thinking: { type: "adaptive", display: "summarized" },
            effort: HARDCODED_EFFORT,
        };
        const bedrockBetas = [EFFORT_BETA];
        if (interleavedThinking) {
            bedrockBetas.push(INTERLEAVED_THINKING_BETA);
        }
        const bedrock = {
            additionalModelRequestFields: {
                thinking: { type: "adaptive", display: "summarized" },
                output_config: { effort: HARDCODED_EFFORT },
                anthropic_beta: bedrockBetas,
            },
        };
        const headers = interleavedThinking
            ? { "anthropic-beta": INTERLEAVED_THINKING_BETA }
            : {};
        return { anthropic, bedrock, headers };
    }
    if (!thinkingEnabled) {
        return { headers: {} };
    }
    const anthropic = {
        thinking: { type: "enabled", budgetTokens: thinkingBudgetTokens },
    };
    const bedrock = {
        additionalModelRequestFields: {
            thinking: { type: "enabled", budget_tokens: thinkingBudgetTokens },
            anthropic_beta: [INTERLEAVED_THINKING_BETA],
        },
    };
    const headers = interleavedThinking
        ? { "anthropic-beta": INTERLEAVED_THINKING_BETA }
        : {};
    return { anthropic, bedrock, headers };
}
/**
 * Processes LLM config and returns the configuration options for AI SDK calls.
 *
 * @param llmConfig - The LLM provider configuration
 * @param defaultBudgetTokens - Default thinking budget if not specified (default: 5000)
 * @param logContext - Optional context string for logging
 */
export function processLLMConfig(llmConfig, defaultBudgetTokens = 5000, logContext) {
    const logger = getLogger();
    const thinkingEnabled = llmConfig?.thinkingEnabled ?? true;
    let thinkingBudgetTokens = llmConfig?.thinkingBudgetTokens
        ? parseInt(llmConfig.thinkingBudgetTokens)
        : defaultBudgetTokens;
    const interleavedThinking = llmConfig?.interleavedThinking ?? true;
    const maxOutputTokens = MAX_OUTPUT_TOKENS;
    const coreModel = llmConfig?.coreModel;
    // Budget validation is only meaningful for the legacy enabled+budgetTokens
    // path. Adaptive-effort models ignore budgetTokens entirely.
    if (thinkingEnabled && !usesAdaptiveEffort(coreModel)) {
        const modelKey = coreModel ?? "claude-sonnet-4-5";
        const modelCaps = MODEL_CAPABILITIES[modelKey];
        const modelMaxOutput = modelCaps?.maxOutputTokens ?? 64_000;
        const total = maxOutputTokens + thinkingBudgetTokens;
        if (total > modelMaxOutput) {
            const adjustedThinkingBudget = modelMaxOutput - maxOutputTokens;
            logger.warn(`maxOutputTokens (${maxOutputTokens}) + thinkingBudget (${thinkingBudgetTokens}) = ${total} ` +
                `exceeds model max (${modelMaxOutput}). Reducing thinkingBudget to ${adjustedThinkingBudget}.`);
            thinkingBudgetTokens = Math.max(0, adjustedThinkingBudget);
        }
    }
    if (logContext) {
        getLogger().info(`${logContext} LLM Provider Config: provider=${llmConfig?.provider || "bedrock (default)"}, ` +
            `coreModel=${coreModel ?? "unset"}, thinking=${thinkingEnabled}, ` +
            `budget=${thinkingBudgetTokens}, interleaved=${interleavedThinking}`);
    }
    const thinkingOptions = buildThinkingProviderOptions(coreModel, {
        thinkingEnabled,
        thinkingBudgetTokens,
        interleavedThinking,
    });
    const providerOptions = thinkingOptions.anthropic && thinkingOptions.bedrock
        ? {
            anthropic: thinkingOptions.anthropic,
            bedrock: thinkingOptions.bedrock,
        }
        : undefined;
    return {
        thinkingEnabled,
        thinkingBudgetTokens,
        interleavedThinking,
        maxOutputTokens,
        providerOptions,
        headers: thinkingOptions.headers,
    };
}
//# sourceMappingURL=llm-config-utils.js.map