import type { ActorCapabilities } from "./actor-contract.js"; import type { CuaAction, CuaProvider, CuaSafetyCheck, CuaTurn } from "./computer-use.js"; import type { ReasoningEffort } from "./reasoning-effort.js"; export declare const OPENAI_RESPONSES_CU_CAPABILITIES: ActorCapabilities; export declare const DEFAULT_OPENAI_CU_MODEL = "gpt-5.6-sol"; /** * The effort a request carries when a lab declares none. Exported because a default that only * exists as a literal inside the provider is exactly how it stayed invisible: the lab surface has * to be able to say what will actually run (#497). */ export declare const DEFAULT_OPENAI_CU_REASONING_EFFORT: ReasoningEffort; /** * Map an OpenAI computer action object to a provider-neutral CuaAction, or null * for an unknown type. Every coordinate and field is read defensively so a * malformed action never throws and a non-number coordinate becomes 0. */ export declare function openAiActionToCua(action: unknown): CuaAction | null; export interface ParsedOpenAiResponse { turn: CuaTurn; callIds: string[]; outputItems: unknown[]; } /** * Parse a Responses API response into a provider-neutral CuaTurn plus the * computer_call ids (needed to build the next turn's call outputs) and the raw * output items (needed for ZDR explicit-context continuation). Pure: no network, * no mutation of the input. Optional CuaTurn fields are only set when present so * the result satisfies exactOptionalPropertyTypes. */ export declare function parseOpenAiResponse(raw: unknown): ParsedOpenAiResponse; export type OpenAiReasoningSummary = "auto" | "concise" | "detailed"; export interface OpenAiCuContext { model: string; instructions: string; reasoningEffort: ReasoningEffort; maxOutputTokens?: number; /** When set, request provider-sanctioned reasoning summaries (#427). Absent = do not ask. */ reasoningSummary?: OpenAiReasoningSummary; safetyIdentifier?: string; } /** Build the first-turn request body: instructions + an initial user text input. */ export declare function buildInitialRequest(ctx: OpenAiCuContext): Record; /** * Build one computer_call_output for a pending call id, carrying the latest * screenshot as an inline data URL. Acknowledged safety checks (if any) are * echoed back so the model can proceed past a check the harness approved. * * The screenshot param is `Buffer | undefined` because CuaObservation.screenshot is now * optional (a non-vision executor omits it). This provider is a VISION model (it sets * requiresFrame), so a missing frame is a hard error here — defense-in-depth: the loop's * per-turn requiresFrame guard already fails closed before this is reached, but throwing keeps * the mapper self-validating and isolable. */ export declare function buildCallOutput(callId: string, screenshot: Buffer | undefined, acknowledged?: CuaSafetyCheck[]): Record; export interface ContinuationRequestArgs { ctx: OpenAiCuContext; previousResponseId: string | undefined; callOutputs: object[]; contextHint?: string; explicitContextItems?: unknown[]; } /** * Build a continuation request body. Two modes: * - default: thread server-side state via previous_response_id and send only the * new call outputs (plus an optional hint). * - explicit-context (ZDR): no previous_response_id; the prior output items are * re-sent inline ahead of the new call outputs so the model has full context * without the server retaining any. */ export declare function buildContinuationRequest(args: ContinuationRequestArgs): Record; /** The opt-in gate for response wire capture: a directory path, or unset for off. */ export declare const WIRE_CAPTURE_ENV = "HUMANISH_CUA_WIRE_CAPTURE_DIR"; /** * Deep-copy a captured wire value with every string — object keys included — * passed through the shared redactText, so a secret-shaped echo in a response * can never persist to disk. Pure; non-string primitives pass through unchanged. */ export declare function redactWireJson(value: unknown): unknown; /** Deterministic ordered capture file name for the 1-based nth provider call. */ export declare function wireCaptureFileName(callNumber: number): string; /** * The minimal slice of the fetch contract the shim depends on. Injecting this * (rather than importing a fetch type) keeps the module dependency-free and lets * CI tests run with a fake that never touches the network. */ export type FetchLike = (url: string, init: { method: string; headers: Record; body: string; signal?: AbortSignal; }) => Promise<{ ok: boolean; status: number; text(): Promise; json(): Promise; /** Optional so a scripted fake need not carry headers; the real fetch Response does. */ headers?: { get(name: string): string | null; }; }>; /** The longest wait a provider's Retry-After hint can impose on one retry. */ export declare const RETRY_AFTER_CAP_MS = 60000; /** * Parse a Retry-After header (delay-seconds or an HTTP-date) into milliseconds from `now`; * undefined when absent or unreadable. OpenAI's 2026-09-02 change added `429 slow_down` and * `503 server_is_overloaded`, both of which may carry it; a fixed 200/400/800 ms backoff against * a 20 s hint burns every retry inside the hint and ends the lane for nothing. */ export declare function retryAfterMs(value: string | null | undefined, now: number): number | undefined; export declare function namedProviderErrorCode(bodyText: string): string | undefined; export interface OpenAiResponsesProviderOptions { apiKey: string; model?: string; /** * How hard the model is asked to think per turn. Absent = the provider default below. * The vocabulary is the documented union across models; SUPPORT IS MODEL-DEPENDENT, so an * unsupported level surfaces as the provider's own first-turn error rather than a silent * downgrade to something the trace would then misreport. See src/reasoning-effort.ts. */ reasoningEffort?: ReasoningEffort; /** Optional positive integer output limit per response, including reasoning. Not a spend cap. */ maxOutputTokens?: number; /** * Reasoning-summary capture (#427). Defaults to "auto" (the provider picks the best * summarizer the model supports); "off" never asks. If the account/model rejects the * request (e.g. an org not verified for reasoning summaries), the provider latches * summaries off for the session and retries the same turn — the run degrades to * exactly the pre-#427 behavior instead of failing after spend. Absence stays honest: * no summary means no `reasoning` trace items and `counts.reasonings` stays 0. */ reasoningSummary?: OpenAiReasoningSummary | "off"; safetyIdentifier?: string; endpoint?: string; fetchFn?: FetchLike; maxRetries?: number; /** Internal strict-accounting policy: one HTTP dispatch, including policy negotiation. * Used by capped sequential sessions; missing usage must stop before another paid request. */ singleDispatch?: boolean; delayFn?: (ms: number) => Promise; zeroDataRetention?: boolean; /** * Environment for the wire-capture gate (HUMANISH_CUA_WIRE_CAPTURE_DIR — see the * module header). Injectable so deterministic tests control the gate without * mutating process.env. Defaults to process.env. */ env?: Record; } /** * Create a stateful CuaProvider backed by the OpenAI Responses API. The first * turn opens a session (buildInitialRequest); subsequent turns send the prior * call outputs (with the latest screenshot) and thread state via * previous_response_id, transparently falling back to explicit-context mode if * the account rejects server-side retention. Transient HTTP failures are retried * with exponential backoff. Returns ONLY a CuaTurn from nextTurn; nothing * sensitive (the key, the request body, the screenshot, the raw response body) * is ever returned or logged. */ export declare function createOpenAiResponsesProvider(options: OpenAiResponsesProviderOptions): CuaProvider;