import type { CodexCompactionContext, CodexCompactionRequestContext, Context, Model, ProviderSessionState, ServiceTier, StreamFunction, StreamOptions, Tool, ToolChoice } from "../types.js"; import { type CodexLiteShapedBody, 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" | "max"; reasoningSummary?: "auto" | "concise" | "detailed" | null; /** Explicit `reasoning.context` replay scope. Omitted by default so Codex applies its native request policy. */ reasoningContext?: CodexReasoningContext; textVerbosity?: "low" | "medium" | "high"; codexMode?: boolean; toolChoice?: ToolChoice; preferWebsockets?: boolean; serviceTier?: ServiceTier; /** * Responses Lite transport override; defaults to the model's catalog * `useResponsesLite` flag (codex-rs `use_responses_lite`). 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), moves instructions/tools * into input items, strips image detail, and disables parallel tool * calling — mirroring codex-rs. */ responsesLite?: boolean; /** * Additional fields embedded in the canonical * `client_metadata["x-codex-turn-metadata"]` JSON blob. Reserved identity * keys are ignored; extras are never emitted as top-level metadata fields. */ clientMetadata?: Record; /** * Turn id of the initiating (parent) Codex turn for nested requests such as * subagent spawns (codex-rs `parent_turn_id`, #35835). Emitted both as the * flat `client_metadata.parent_turn_id` key and inside the * `x-codex-turn-metadata` JSON blob; blank values are ignored. The key is * reserved: `clientMetadata` extras cannot supply it. */ parentTurnId?: string; /** * 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; } /** Raw V2 compaction body accepted by the Codex transport selector. */ export interface OpenAICodexCompactionBody extends CodexLiteShapedBody { model: string; [key: string]: unknown; } /** Transport controls for a provider-native Codex V2 compaction stream. */ export interface OpenAICodexCompactionStreamOptions extends OpenAICodexResponsesOptions { apiKey: string; } /** Inputs for synthesizing Codex request identity outside the normal stream path. */ export interface OpenAICodexCompatibilityMetadataOptions { sessionId?: string; providerSessionState?: Map; requestKind: OpenAICodexRequestKind; compaction?: CodexCompactionRequestContext; startNewTurn?: boolean; turnStartedAtUnixMs?: number; clientMetadata?: Readonly>; /** Parent Codex turn id for nested requests; see {@link OpenAICodexResponsesOptions.parentTurnId}. */ parentTurnId?: string; /** Add the direct installation header required by `/responses/compact`. */ includeInstallationHeader?: boolean; } /** Canonical Codex body metadata and compatibility headers for one request. */ export interface OpenAICodexCompatibilityMetadata { clientMetadata: Record; headers: Record; } /** Live Codex session state to preserve after a successful history rewrite. */ export interface OpenAICodexCompactionResetOptions { providerSessionState?: Map; sessionId?: string; compaction: CodexCompactionContext; } /** Add the selected wire implementation to one logical compaction context. */ export declare function createOpenAICodexCompactionRequestContext(options: { context: CodexCompactionContext | undefined; implementation: "responses" | "responses_compaction_v2" | "responses_compact"; }): CodexCompactionRequestContext | undefined; /** * Host integration boundary for just-in-time `x-oai-attestation` header * values (codex-rs `AttestationProvider`). Resolves to the full header value * — an `{"v":1,"s":0,"t":"v1.…"}` envelope — or `undefined` when no * attestation should be sent. */ export type CodexAttestationProvider = () => Promise; /** * Install the process-wide attestation hook consulted for upstream Codex * requests (codex-rs stores its provider on `ModelClient` construction). The * hook is only consulted for ChatGPT-OAuth credentials and runs just-in-time * per request; WebSocket handshakes resolve once per connection because the * header is connection-scoped there. */ export declare function setCodexAttestationProvider(provider: CodexAttestationProvider | undefined): void; /** * Resolve the `x-oai-attestation` header value for one upstream request. * Gated on ChatGPT-OAuth credentials (a Codex JWT carries `chatgpt_account_id`; * codex-rs gates on `auth.is_chatgpt_auth()`). A throwing hook degrades to no * header rather than failing the request. */ export declare function getCodexAttestationHeader(accountId: string | undefined): Promise; 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; } /** Request classification encoded in Codex turn metadata. */ export type OpenAICodexRequestKind = "turn" | "prewarm" | "compaction"; /** * Synthesize Codex request identity for raw provider routes such as remote * compaction while reusing the live session's thread, window, and turn. */ export declare function createOpenAICodexCompatibilityMetadata(options: OpenAICodexCompatibilityMetadataOptions): OpenAICodexCompatibilityMetadata; /** * Invalidate Codex history-dependent transport state after compaction while * retaining the session identity and live connection. */ export declare function resetOpenAICodexHistoryAfterCompaction(options: OpenAICodexCompactionResetOptions): void; /** @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; /** * Open a provider-native V2 compaction stream through Codex's WebSocket-first * transport, replaying WebSocket transport failures over SSE. */ export declare function openCodexCompactionEventStream(model: Model<"openai-codex-responses">, body: OpenAICodexCompactionBody, options: OpenAICodexCompactionStreamOptions): 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; hasTurnState: 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; /** Resolve a Codex Responses endpoint exactly as the chat and compaction transports do. */ export declare function resolveCodexResponsesUrl(baseUrl: string | undefined): string; declare function convertMessages(model: Model<"openai-codex-responses">, context: Context): ResponseInput; /** @internal Exported for tests. */ export { convertMessages as convertCodexResponsesMessages }; type CodexToolPayload = { type: "computer"; name?: never; } | { 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;