// Introspection helper — bridges the registry to the existing CLI-style
// "give me a string back" pattern that distill / consolidate / intent
// already use.
//
// Callers don't want to know about LlmMessage[] / ChatResult. They have
// a flat prompt string and a per-call deadline; they want a Promise<{
// text, costUsd }> back. This file does that mapping in one place so
// every introspection caller stays a 1-line change.
import { logger as rootLogger } from '../logger.js';
import { getProvider } from './registry.js';
import { LlmProviderError } from './provider-base.js';
const log = rootLogger.child({ component: 'llm-introspection' });
/**
 * Try to satisfy the introspection request via the configured backend
 * for `role`. Returns null when:
 *   - no provider is wired for this role, OR
 *   - the provider call failed (errors are logged + classified, never
 *     re-thrown — the caller's fallback path takes over).
 *
 * The "return null on failure" contract is exactly what distill /
 * consolidate / intent want: they then fall back to spawning their
 * CLI agent and the user notices nothing.
 */
export async function tryIntrospect(input) {
    const provider = getProvider(input.role);
    if (!provider)
        return null;
    const messages = [{ role: 'user', content: input.prompt }];
    const startedAt = Date.now();
    try {
        const result = await provider.chat(messages, {
            system: input.system,
            timeoutMs: input.timeoutMs ?? 30_000,
            signal: input.signal,
            temperature: input.temperature,
            model: input.model,
        });
        return {
            text: result.text,
            usage: result.usage,
            backendName: provider.name,
            providerType: provider.providerType,
            durationMs: Date.now() - startedAt,
        };
    }
    catch (err) {
        const transient = err instanceof LlmProviderError ? err.transient : false;
        const httpStatus = err instanceof LlmProviderError ? err.httpStatus : undefined;
        log.warn({
            event: 'llm.introspect.failed',
            role: input.role,
            backend: provider.name,
            providerType: provider.providerType,
            transient,
            httpStatus,
            err: err instanceof Error ? err.message : String(err),
        });
        return null;
    }
}
export async function tryIntrospectChain(input) {
    if (!input.roles || input.roles.length === 0)
        return null;
    const tried = [];
    for (const role of input.roles) {
        tried.push(role);
        const r = await tryIntrospect({
            role,
            prompt: input.prompt,
            system: input.system,
            timeoutMs: input.perRoleTimeoutMs ?? input.timeoutMs ?? 30_000,
            signal: input.signal,
            temperature: input.temperature,
            model: input.model,
        });
        if (r) {
            log.info({
                event: 'llm.introspect.chain.success',
                role, attempts: tried.length, totalRoles: input.roles.length,
            });
            return { ...r, triedRoles: tried.slice() };
        }
    }
    log.info({
        event: 'llm.introspect.chain.exhausted',
        attempts: tried.length, roles: tried.join(','),
    });
    return null;
}
//# sourceMappingURL=introspection.js.map