/** * OpenAI Chat Completions API format conversion layer. * * Provides a request parser (OpenAI -> NeuroLink), a response serializer * (NeuroLink -> OpenAI), a streaming SSE state machine, and an error * envelope helper. Together they allow NeuroLink to act as a * drop-in OpenAI API proxy. * * Reference: https://platform.openai.com/docs/api-reference/chat/create */ import type { ClaudeRequest, ClaudeResponse, InternalResult, OpenAICompletionRequest, OpenAICompletionResponse, OpenAIErrorResponse, ParsedOpenAIRequest, StreamLifecycleState } from "../types/index.js"; /** Generate a unique chat completion ID in the OpenAI format. */ export declare function generateChatCompletionId(): string; /** Generate an OpenAI-format tool call ID (`call_` + random chars). */ export declare function generateOpenAIToolCallId(): string; /** * Parse an incoming OpenAI Chat Completions request into an intermediate * representation consumable by NeuroLink's generate/stream pipeline. * * Handles: * - System prompt extraction from system messages * - Message flattening (text + image parts) * - Tool definition conversion * - tool_choice mapping * - top_p, temperature, max_tokens pass-through */ export declare function parseOpenAIRequest(body: OpenAICompletionRequest): ParsedOpenAIRequest; /** * Serialize a NeuroLink GenerateResult into an OpenAI Chat Completions response. */ export declare function serializeOpenAIResponse(result: InternalResult, requestModel: string): OpenAICompletionResponse; /** * Build an OpenAI-compatible error envelope. */ export declare function buildOpenAIError(status: number, message: string): OpenAIErrorResponse; /** * Format a single OpenAI SSE frame. * OpenAI uses only `data:` lines (no `event:` prefix unlike Claude). */ export declare function formatOpenAISSE(data: unknown): string; /** * Stateful SSE serializer that emits a well-formed OpenAI streaming response. * * Tracks lifecycle state (`idle` -> `streaming` -> `done`) and the current * tool call index for multi-tool streaming. * * Usage: * ```ts * const sse = new OpenAIStreamSerializer(requestModel); * * // Start the stream * yield* sse.start(); * * // Text deltas * for await (const chunk of textStream) { * yield* sse.pushDelta(chunk); * } * * // Tool use * yield* sse.pushToolUse(toolId, toolName, toolInput); * * // Finalize * yield* sse.finish("stop", usage); * ``` */ export declare class OpenAIStreamSerializer { private state; private readonly id; private readonly model; private started; private toolCallIndex; constructor(model: string); /** Current lifecycle state (exposed for testing). */ getState(): StreamLifecycleState; private makeChunk; /** * Emit the opening frame with `role: "assistant"`. */ start(): Generator; /** * Push a text content delta. */ pushDelta(text: string): Generator; /** * Push the start of a tool call (id, name, empty arguments). */ pushToolCallStart(id: string, name: string): Generator; /** * Push an arguments delta for the current tool call. */ pushToolCallArgDelta(index: number, argsChunk: string): Generator; /** * Push a complete tool use: emits tool call start followed by chunked * argument deltas (~100 chars per chunk). */ pushToolUse(id: string, name: string, input: unknown): Generator; /** * Finalize the stream: emit finish_reason chunk, then `data: [DONE]`. */ finish(finishReason?: string, usage?: { input: number; output: number; total: number; }): Generator; /** * Emit an error event. Transitions to terminal ERROR state. */ emitError(message: string): Generator; } /** * Convert an OpenAI Chat Completions request to a Claude Messages API request. * * Used by the OpenAI proxy endpoint to internally loopback requests targeting * Claude models through the proxy's native /v1/messages passthrough path, * so they benefit from OAuth account rotation, retry, SSE interception, etc. */ export declare function convertOpenAIToClaudeRequest(openai: OpenAICompletionRequest): ClaudeRequest; /** * Convert a non-streaming Claude Messages response to an OpenAI Chat * Completions response by bridging through {@link InternalResult}. */ export declare function convertClaudeToOpenAIResponse(claude: ClaudeResponse, requestModel: string): OpenAICompletionResponse; /** * Create a TransformStream that parses Claude Messages API SSE events from * the upstream response and re-emits them as OpenAI Chat Completions SSE * frames. * * Handles the canonical Claude SSE event types: * - message_start -> emits the opening `role: "assistant"` chunk * - content_block_start -> text block: no-op; tool_use block: emit tool call start * - content_block_delta -> text_delta: emit content delta; * input_json_delta: emit tool call argument delta * - content_block_stop -> no-op * - message_delta -> captures stop_reason and output token usage * - message_stop -> emits the final `finish_reason` chunk + `[DONE]` */ export declare function createClaudeToOpenAIStreamTransform(requestModel: string): TransformStream;