import type { Context, Model, ProviderSessionState, ServiceTier, StreamFunction, StreamOptions, Tool, ToolChoice } from "../types.js"; import { type CodexReasoningContext, type RequestBody } from "./openai-codex/request-transformer.js"; import type { ResponseInput } from "./openai-responses-wire.js"; export interface OpenAICodexResponsesOptions extends StreamOptions { reasoning?: "none" | "minimal" | "low" | "medium" | "high" | "xhigh"; reasoningSummary?: "auto" | "concise" | "detailed" | null; /** `reasoning.context` replay scope; defaults to `all_turns` when unset. The `all_turns` value is gated to gpt-5.4+ Codex models — older ids reject it, so it is suppressed and `context` omitted. */ reasoningContext?: CodexReasoningContext; textVerbosity?: "low" | "medium" | "high"; include?: string[]; codexMode?: boolean; toolChoice?: ToolChoice; preferWebsockets?: boolean; serviceTier?: ServiceTier; /** * Opt into the Responses Lite transport contract. Sends * `x-openai-internal-codex-responses-lite: true` on HTTP requests and on the * WebSocket upgrade (the marker is connection-scoped there, so lite and * non-lite turns never share a pooled socket), strips image detail from * input, and disables parallel tool calling — mirroring codex-rs. */ responsesLite?: boolean; /** * Extra `client_metadata` to include in the request body on both transports. * The canonical Codex envelope is `client_metadata["x-codex-turn-metadata"]` * (JSON string of thread/turn identifiers); flat keys are also accepted. */ clientMetadata?: Record; /** * Invoked when the server streams a `response.metadata` event carrying * ChatGPT moderation metadata (`metadata.openai_chatgpt_moderation_metadata`) * for first-party presentation parity. Diagnostic observer: failures are * swallowed and must not alter the stream. */ onModerationMetadata?: (metadata: unknown) => void; } type CodexTransport = "sse" | "websocket"; /** Shape of the Codex request sent on the latest provider turn. */ export interface OpenAICodexTurnRequestDiagnostics { transport: "sse" | "websocket"; previousResponseIdPresent: boolean; inputItemCount: number; inputItemTypes: string[]; firstInputItemType?: string; inputJsonBytes: number; promptCacheKey?: string; toolsHash?: string; optionsHash: string; canAppendBeforeRequest: boolean; } /** Raw provider usage plus the normalized buckets OMP displays for the latest Codex turn. */ export interface OpenAICodexTurnUsageDiagnostics { rawInputTokens: number; rawCachedTokens: number; rawUncachedTokens: number; rawOutputTokens: number; rawTotalTokens?: number; rawOrchestrationInputTokens?: number; rawOrchestrationCachedTokens?: number; rawOrchestrationOutputTokens?: number; displayedInputTokens: number; displayedOutputTokens: number; displayedCacheReadTokens: number; displayedCacheWriteTokens: number; displayedTotalTokens: number; displayedOrchestrationInputTokens: number; displayedOrchestrationCacheReadTokens: number; displayedOrchestrationOutputTokens: number; } /** Latest Codex turn request/usage diagnostics exposed to debug UIs and tests. */ export interface OpenAICodexTurnDiagnostics { request: OpenAICodexTurnRequestDiagnostics; usage?: OpenAICodexTurnUsageDiagnostics; } /** * Per-session request-shape counters and latest turn diagnostics. Despite the * name, these cover both transports. */ export interface OpenAICodexWebSocketDebugStats { fullContextRequests: number; deltaRequests: number; lastInputItems: number; lastDeltaInputItems?: number; lastPreviousResponseId?: string; lastTurn?: OpenAICodexTurnDiagnostics; } /** @internal Exported for tests. */ export declare function normalizeCodexToolChoice(choice: ToolChoice | undefined, tools?: Tool[], model?: Model<"openai-codex-responses">): string | Record | undefined; /** @internal Exported for tests. */ export declare function buildTransformedCodexRequestBody(model: Model<"openai-codex-responses">, context: Context, options: OpenAICodexResponsesOptions | undefined, promptCacheKey?: string | undefined): Promise; export declare const streamOpenAICodexResponses: StreamFunction<"openai-codex-responses">; export declare function prewarmOpenAICodexResponses(model: Model<"openai-codex-responses">, options?: Pick): Promise; export interface OpenAICodexTransportDetails { websocketPreferred: boolean; lastTransport?: CodexTransport; websocketDisabled: boolean; websocketConnected: boolean; fallbackCount: number; canAppend: boolean; prewarmed: boolean; hasSessionState: boolean; lastFallbackAt?: number; } export declare function getOpenAICodexWebSocketDebugStats(model: Model<"openai-codex-responses">, options?: { sessionId?: string; baseUrl?: string; providerSessionState?: Map; }): OpenAICodexWebSocketDebugStats | undefined; export declare function getOpenAICodexTransportDetails(model: Model<"openai-codex-responses">, options?: { sessionId?: string; baseUrl?: string; preferWebsockets?: boolean; providerSessionState?: Map; }): OpenAICodexTransportDetails; declare function convertMessages(model: Model<"openai-codex-responses">, context: Context): ResponseInput; /** @internal Exported for tests. */ export { convertMessages as convertCodexResponsesMessages }; type CodexToolPayload = { type: "function"; name: string; description: string; parameters: Record; strict?: boolean; } | { type: "custom"; name: string; description: string; format: { type: "grammar"; syntax: "lark" | "regex"; definition: string; }; }; /** @internal Exported for tests. */ export declare function convertOpenAICodexResponsesTools(tools: Tool[], model: Model<"openai-codex-responses">): CodexToolPayload[]; export declare class CodexWebSocketTransportError extends Error { constructor(detail: string); } declare class CodexProviderStreamError extends Error { readonly retryable: boolean; readonly code?: string; constructor(message: string, retryable: boolean, code?: string); } export declare function isRetryableCodexFailureEvent(rawEvent: Record): boolean; export declare function createCodexProviderStreamError(rawEvent: Record): CodexProviderStreamError;