Skip to content
2 min read · 384 words

@nhtio/adk/batteries/llm/openai_responses/adapter

Cross-environment executor adapter for the OpenAI Responses API.

Remarks

Cross-environment LLM adapter for the OpenAI Responses wire shape — a flat input: Item[] array (not messages[]), where a tool call and its result are two SIBLING top-level items (function_call / function_call_output), and the system prompt defaults to a top-level instructions string rather than a leading message item.

The adapter is built around the same three pluggable layers as openai_chat_completions:

  1. Translation helpers — the swappable functions exported from ./helpers turn ADK primitives into Responses wire shapes. Consumers override individual helpers via options.helpers.*.
  2. Three-layer options merging — constructor baseline, per-executor() overrides, and per-iteration ctx.stash.openaiResponses overrides combine with key-by-key precedence for headers/helpers/retry and wholesale replacement for everything else. The merged shape is re-validated on every iteration.
  3. Cross-env transport — hand-rolled fetch + SSE parsing, mirroring openai_chat_completions/adapter.ts's transport exactly. No openai SDK dependency.

This adapter is STATELESS by design: store: false is always sent (never a settable option), and the full input array is resent every iteration. There is no [DONE] sentinel on the Responses SSE stream — termination is response.completed / .incomplete / .failed; EOF without one of these is a best-effort recovery, not a hard failure: it warn-logs and drains whatever was accumulated rather than nacking with E_OPENAI_RESPONSES_STREAM_ERROR (that exception is reserved for a genuine stream-level error, e.g. the connection itself failing).

Recoverable-failure handling: a 400 whose body matches invalid_encrypted_content drops every reasoning item from the resolved input and retries the request once — a documented real-world failure mode when a persisted reasoning Thought outlives a server-side key rotation. A 400 matching the reasoning/output-item pairing violation phrases translates to E_OPENAI_RESPONSES_REASONING_REPLAY_REJECTED instead of a generic HTTP error.

background is NOT supported: this executor has no polling/resumption loop for a queued/in_progress background response (the Responses API's async mode; see https://platform.openai.com/docs/guides/background), so background: true is rejected up front by the options schema (E_INVALID_OPENAI_RESPONSES_OPTIONS, see validation.ts) rather than reaching this executor at all — accepting it here would otherwise fall straight into the ordinary streaming/non-streaming response handling below and treat the initial queued/in_progress response body as a complete, empty answer, silently discarding whatever the background job eventually produces.

Classes

ClassDescription
OpenAIResponsesAdapterOpinionated cross-environment LLM adapter for the OpenAI Responses wire shape.