/**
 * 0.14.2 — streaming → non-streaming fallback synthesizer.
 *
 * When a streaming /v1/messages request fires the first-token watchdog
 * (no visible chunk arrived within the adaptive budget), the previous
 * behaviour was to surface a `stream_first_token_timeout` recovery
 * wording event. That's correct for "the model is genuinely dead" but
 * burns a turn when the issue is just that the route streams poorly
 * (e.g. some cloud kimi-code variants buffer the entire response
 * server-side before flushing).
 *
 * Strategy:
 *   1. On first-token watchdog fire with zero chunks seen, re-issue the
 *      same body with `stream: false` against the *same* model/route
 *   2. On success → synthesize a complete Anthropic SSE event sequence
 *      from the non-streaming JSON and write it through the still-open
 *      `text/event-stream` response
 *   3. On failure → fall through to the existing recovery wording path
 *
 * Why we don't need a header rewrite: the streaming response headers
 * (text/event-stream, transfer-encoding chunked, etc) were already
 * written at handleMessagesStream entry. The synthesized events are
 * standard Anthropic SSE — clients consume them identically to a
 * real stream. From the client's POV the request just had high
 * latency to first chunk.
 *
 * Anti-pattern guard (project memory):
 *   - We don't port OwlCC's tengu `SystemAPIErrorMessage` heartbeat —
 *     that's an upstream-specific protocol
 *   - We don't gate this on a "foreground vs background" source flag —
 *     owlcoda has no such distinction (all queries are foreground in
 *     the local-first model)
 *   - We don't add telemetry callbacks — log to local trace only
 *
 * Disable: set `middleware.streamFallbackToNonStreamingEnabled = false`
 * to skip the fallback and use the 0.14.1 wording-only path.
 */
import type { ServerResponse } from 'node:http';
import type { OwlCodaConfig } from '../config.js';
import type { AnthropicMessagesRequest, AnthropicMessagesResponse } from '../types.js';
/** Whether the fallback should be attempted on first-token watchdog fire. */
export declare function isFallbackEnabled(middleware: {
    streamFallbackToNonStreamingEnabled?: boolean;
} | undefined): boolean;
/** Build the non-streaming retry body. Same shape as `body` but with
 *  `stream` removed (route should default to non-streaming when absent). */
export declare function buildNonStreamingRetryBody(body: AnthropicMessagesRequest): AnthropicMessagesRequest;
/**
 * Synthesize an Anthropic SSE event sequence from a non-streaming
 * response and write it through `res`. Caller is responsible for
 * calling `res.end()` after this returns.
 *
 * Event sequence (matches Anthropic Messages streaming spec):
 *
 *   message_start  → carries id, model, role, usage (input only)
 *   for each content block:
 *     content_block_start  → {type, [name, id, ...]}
 *     content_block_delta  → carries the full text / thinking / input
 *                            in a single "delta" — clients accumulate
 *                            the same way they would for many small deltas
 *     content_block_stop
 *   message_delta  → stop_reason + usage.output_tokens
 *   message_stop
 *
 * `text` blocks emit `text_delta`, `thinking` blocks emit
 * `thinking_delta`, `tool_use` blocks emit a single `input_json_delta`
 * containing the JSON-stringified input. Unknown block types are
 * skipped silently (caller may want to log).
 */
export declare function synthesizeSseFromResponse(res: ServerResponse, json: AnthropicMessagesResponse): void;
/**
 * Attempt the non-streaming fallback fetch. Returns the parsed JSON on
 * success, or `null` to signal the caller should proceed with the
 * existing error wording path.
 *
 * This is intentionally lean — it does NOT thread through the full
 * fallback chain / circuit breaker / retry middleware. The fallback is
 * a single-shot best-effort retry. If the user has reached this code
 * path, the streaming attempt already exhausted its budget; we just
 * try once more on the same route in non-streaming mode and either
 * synthesize or give up.
 */
export declare function fetchNonStreamingFallback(endpointUrl: string, headers: Record<string, string>, retryBody: AnthropicMessagesRequest, signal: AbortSignal, timeoutMs: number, route?: {
    translate: boolean;
    backendModel: string;
    requestModel: string;
    config: OwlCodaConfig;
}): Promise<AnthropicMessagesResponse | null>;
