/**
 * LLM calls for workflow steps via Claude Code subprocess.
 *
 * Spawns `claude --print` as a child process with the resolved prompt.
 * Claude Code handles its own OAuth authentication internally — no
 * credential reading, token refresh, or API endpoint logic needed here.
 * This is the same mechanism the admin chat uses (claude-agent.ts).
 *
 * Two spawn modes:
 *
 *   ONE-SHOT (no mcpServers)
 *   ────────────────────────
 *   VALIDATE PROMPT
 *     │
 *     ├─ empty → throw (no silent fallback)
 *     │
 *     v
 *   SPAWN claude --print --model <model> --max-turns 1
 *     │
 *     ├─ ENOENT (not in PATH) → throw
 *     ├─ non-zero exit → throw with stderr + stdout
 *     ├─ timeout → SIGTERM → throw
 *     ├─ empty stdout → throw
 *     └─ stdout text → return
 *
 *   AGENTIC (mcpServers declared)
 *   ─────────────────────────────
 *   VALIDATE PROMPT
 *     │
 *     v
 *   WRITE TEMP MCP CONFIG (mkdtemp + writeFile)
 *     │
 *     ├─ disk error → throw (cleanup skipped — nothing to clean)
 *     │
 *     v
 *   SPAWN claude --print --model <model> --max-turns <N>
 *         --mcp-config <tmp/mcp.json> --strict-mcp-config
 *         --permission-mode dontAsk
 *     │
 *     ├─ same error paths as one-shot
 *     │
 *     v
 *   CLEANUP TEMP CONFIG (finally — always runs)
 *     │
 *     ├─ ENOENT → swallow (already cleaned or never written)
 *     └─ other error → log, don't throw (cleanup must not mask spawn error)
 *
 * probeLlmHealth() shares the same spawn path with a trivial "pong"
 * prompt and a shorter timeout. Used as the pre-flight check before
 * executing workflow LLM steps (Task 74 — graceful degradation).
 */
import type { McpServerConfig } from "./step-resolver.js";
interface SpawnedChildLike {
    stdout: {
        on(event: "data", cb: (chunk: Buffer) => void): void;
    };
    stderr: {
        on(event: "data", cb: (chunk: Buffer) => void): void;
    };
    on(event: "close", cb: (code: number | null) => void): void;
    on(event: "error", cb: (err: Error) => void): void;
    kill(signal?: string): void;
}
type SpawnFn = (cmd: string, args: string[], opts: unknown) => SpawnedChildLike;
export interface LlmCallParams {
    prompt: string;
    model: string;
    maxTokens?: number;
    timeoutMs: number;
    /** MCP server bindings for agentic steps. */
    mcpServers?: Record<string, McpServerConfig>;
    /** Max agent turns (default 1, or 10 when mcpServers present). */
    maxTurns?: number;
    /**
     * Optional spawn function override — used only by tests to inject a
     * fake child process. Production callers must omit this.
     */
    _spawn?: SpawnFn;
}
export interface ProbeLlmHealthParams {
    model: string;
    /** Probe timeout — defaults to 10 seconds. */
    timeoutMs?: number;
    /** Test-only spawn injection. */
    _spawn?: SpawnFn;
}
export interface ProbeResult {
    ok: boolean;
    latencyMs: number;
    /** Set when ok is false. One-line error summary suitable for logs and
     *  substitution into fallback template `{{_error}}`. */
    error?: string;
}
/**
 * Why readAdminModel returns a tuple instead of string | null:
 * the caller persists the result into WorkflowRun.error, which the admin
 * agent reads. A silent null collapsed six distinct failure modes (ENOENT,
 * EACCES, parse error, missing field, wrong type, empty string) into a
 * single error string asserting "adminModel both unset" — which was often
 * a lie (the file existed and was correct; something else had failed).
 * The tuple surfaces the exact reason so the persisted error and the
 * stderr log agree, and the admin agent knows whether to inspect the
 * file, the permissions, the path, or a concurrent-write race.
 */
export type AdminModelReason = "ok" | "enoent" | "eacces" | "fs_error" | "parse_error" | "field_missing" | "field_wrong_type" | "field_empty";
export interface AdminModelResolution {
    /** Model ID when reason is "ok"; null for every failure mode. */
    model: string | null;
    reason: AdminModelReason;
    /** Absolute path attempted — included in failure logs so the operator
     *  can inspect the exact file that was read. */
    path: string;
    /** Underlying error message for fs_error and parse_error. */
    error?: string;
}
/**
 * Read the account's adminModel from account.json.
 * Returns {model, reason, path, error?} — callers branch on .model (null
 * means fail) and may surface .reason/.path into user-visible errors.
 */
export declare function readAdminModel(platformRoot: string, accountId: string): AdminModelResolution;
/**
 * Execute an LLM call by spawning Claude Code.
 *
 * When mcpServers is provided, spawns in agentic mode: writes a temp
 * config file, adds --mcp-config and --strict-mcp-config flags, and
 * uses the step's maxTurns (or default 10) instead of 1.
 *
 * Returns the model's text response. The caller is responsible for
 * parsing the response (JSON or raw text) via parseStepOutput().
 */
export declare function executeLlmCall(params: LlmCallParams): Promise<string>;
/**
 * Lightweight pre-flight probe for LLM availability.
 *
 * Spawns `claude --print` with a trivial prompt ("pong") and a short
 * timeout. Any failure mode that would cause a real LLM step to fail
 * (missing binary, dead OAuth token, Anthropic outage, network partition)
 * also fails this probe — it is the strongest available signal short
 * of running the real workflow.
 *
 * Called at most once per workflow run, only when the workflow contains
 * at least one LLM step. Per-step spawn failures mid-run are handled
 * separately by the workflow-execute convergence arm.
 *
 *   SUCCESS  →  { ok: true, latencyMs }
 *   FAILURE  →  { ok: false, latencyMs, error: one-line summary }
 */
export declare function probeLlmHealth(params: ProbeLlmHealthParams): Promise<ProbeResult>;
export {};
//# sourceMappingURL=llm-call.d.ts.map