/**
 * Claude Messages API format conversion layer.
 *
 * Provides a request parser (Claude -> NeuroLink), a response serializer
 * (NeuroLink -> Claude), a streaming SSE state machine, and an error
 * envelope helper.  Together they allow NeuroLink to act as a
 * drop-in Claude API proxy.
 *
 * Reference: https://docs.anthropic.com/en/api/messages
 */
import type { ClaudeErrorResponse, ClaudeRequest, ClaudeResponse, ContentBlockType, InternalResult, ParsedClaudeRequest, StreamLifecycleState } from "../types/index.js";
/** Generate a unique message id in the Claude format. */
export declare function generateMessageId(): string;
/** Generate a Claude-format tool use ID (`toolu_` + 24 random chars). */
export declare function generateToolUseId(): string;
/**
 * Reset the internal id counter (useful in tests).
 * @internal
 */
export declare function _resetIdCounter(): void;
/**
 * Parse an incoming Claude Messages API request into an intermediate
 * representation consumable by NeuroLink's generate/stream pipeline.
 *
 * Handles:
 * - System prompt extraction (string or content-block array)
 * - Message flattening (text + image blocks)
 * - Tool definition conversion
 * - tool_choice mapping
 * - top_p pass-through
 * - thinking configuration
 */
export declare function parseClaudeRequest(body: ClaudeRequest): ParsedClaudeRequest;
/**
 * Serialize a NeuroLink GenerateResult into a Claude Messages API response.
 */
export declare function serializeClaudeResponse(result: InternalResult, requestModel: string): ClaudeResponse;
/**
 * Build a Claude-compatible error envelope.
 */
export declare function buildClaudeError(status: number, message: string, errorType?: string): ClaudeErrorResponse;
/**
 * Format a single SSE frame (one `event:` + `data:` pair).
 */
export declare function formatSSE(eventType: string, data: unknown): string;
/**
 * Stateful SSE serializer that emits a well-formed Claude SSE stream.
 *
 * Tracks both lifecycle state (`idle` -> `streaming` -> `done`) and the
 * current content block type (`text`, `thinking`, `tool_use`). Each
 * content block gets a unique, monotonically increasing `blockIndex`.
 *
 * Usage:
 * ```ts
 * const sse = new ClaudeStreamSerializer(requestModel, inputTokens);
 *
 * // Thinking deltas
 * for await (const thought of thinkingStream) {
 *   yield* sse.pushThinkingDelta(thought);
 * }
 *
 * // Text deltas
 * for await (const chunk of textStream) {
 *   yield* sse.pushDelta(chunk);
 * }
 *
 * // Tool use
 * yield* sse.pushToolUse(toolId, toolName, toolInput);
 *
 * // Finalize
 * yield* sse.finish(outputTokens, finishReason);
 * ```
 */
export declare class ClaudeStreamSerializer {
    private state;
    private currentBlockType;
    private sawToolUseBlock;
    private blockIndex;
    private hasOpenedBlock;
    private outputTokens;
    private messageStarted;
    private readonly messageId;
    private readonly model;
    private readonly inputTokens;
    constructor(model: string, inputTokens?: number);
    /** Current lifecycle state (exposed for testing). */
    getState(): StreamLifecycleState;
    /** Current content block type (exposed for testing). */
    getCurrentBlockType(): ContentBlockType;
    /** Current block index (exposed for testing). */
    getBlockIndex(): number;
    /**
     * Emit a ping event frame.  The actual periodic timer is wired in
     * the route handler; this method just formats the SSE frame.
     */
    static pingEvent(): string;
    /**
     * Emit `message_start` and initial ping if not already done.
     */
    private ensureMessageStarted;
    /**
     * Close the current content block if one is open.
     */
    private closeCurrentBlock;
    /**
     * Open a new content block of the given type.
     * Increments blockIndex for each new block.
     */
    private openBlock;
    /**
     * Emit the opening frames: message_start and ping.
     * The first actual content decides which content block opens next.
     */
    start(): Generator<string>;
    /**
     * Push a text delta.  Returns zero or more SSE frames.
     * If currently in a thinking block, the thinking block is closed first.
     */
    pushDelta(text: string): Generator<string>;
    /**
     * Push a thinking delta.  Returns zero or more SSE frames.
     * If currently in a text or tool_use block, that block is closed first
     * and a new thinking block is opened.
     */
    pushThinkingDelta(text: string): Generator<string>;
    /**
     * Push a complete tool use block.
     *
     * 1. Closes any open content block
     * 2. Emits `content_block_start` with `{type: "tool_use", id, name}`
     * 3. JSON-stringifies the input, chunks it into ~100 char segments
     * 4. Emits `content_block_delta` with `{type: "input_json_delta", partial_json}` per chunk
     * 5. Emits `content_block_stop`
     */
    pushToolUse(id: string, name: string, input: unknown): Generator<string>;
    /**
     * Finalize the stream: content_block_stop, message_delta, message_stop.
     */
    finish(outputTokens?: number, finishReason?: string): Generator<string>;
    /**
     * Emit an error event.  Transitions to terminal ERROR state.
     */
    emitError(status: number, message: string): Generator<string>;
}
