@nhtio/adk/batteries/llm/openai_chat_completions/adapter
Cross-environment executor adapter for OpenAI Chat Completions compatible endpoints.
Remarks
Cross-environment LLM adapter for the OpenAI Chat Completions wire shape. Chat Completions was chosen as the ADK's reference adapter because it is the de-facto interchange format for the majority of OpenAI-compatible gateways (vLLM, Together, Groq, Fireworks, Ollama, Azure OpenAI, OpenRouter, DeepSeek, Mistral La Plateforme, and most self-hosted deployments). Its tool-call synthetic-history shape (role: 'assistant', tool_calls: [...] followed by role: 'tool' with tool_call_id) is the lowest-common-denominator that every conformant gateway accepts.
The adapter is built around three pluggable layers:
- Translation helpers — the thirteen swappable functions exported from
./helpersturn ADK primitives (@nhtio/adk!Tokenizable, @nhtio/adk!Memory, @nhtio/adk!Message, @nhtio/adk!Thought, @nhtio/adk!ToolCall, @nhtio/adk!Tool, @nhtio/adk!ArtifactTool, @nhtio/adk!SpooledArtifact) into Chat Completions wire shapes. Consumers override individual helpers viaoptions.helpers.*to customise envelope formats, bucket ordering, thought surfacing, or JSON Schema generation without forking the adapter. - Three-layer options merging — constructor baseline, per-
executor()overrides, and per-iterationctx.stash.openaiChatCompletionsoverrides combine with key-by-key precedence forheaders/helpers/retryand wholesale replacement for everything else. The merged shape is re-validated on every iteration so a malformed stash override fails loud, not silently. - Cross-env transport — uses
globalThis.fetch,TextDecoder,AbortController, andAbortSignal.anyonly. No Node-specific primitives; works unchanged in browser, edge, and server runtimes. SSE framing is hand-parsed against\n\nseparators so the streaming path has no dependency on a particular SSE library.
Per-iteration flow (steps 1–9 of the plan):
- Merge constructor / executor / stash options and re-validate.
- Resolve helpers, falling back to bundled
default*for each unset field. - Forge artifact-query tools by walking
ctx.turnToolCalls, collecting uniqueSpooledArtifactconstructors, calling<Ctor>.forgeTools(ctx)on each, and merging the results withctx.tools. - Pre-render every persisted tool-call result into the prompt-ready string the timeline will use, cached by
tc.id. - When
tokenEncoding !== null, sum the token weight of every persisted bucket and throw @nhtio/adk/batteries!E_OPENAI_CHAT_COMPLETIONS_CONTEXT_OVERFLOW when the total exceedscontextWindow. - Build the request body via
buildChatCompletionsHistory; carry vendor-opaque reasoning blocks through the_adk_reasoning_payloadsside-channel. - POST with a linked
AbortSignal, retry loop respectingretry.*, and a request-timeout watchdog that arms before fetch and clears once response headers arrive. - Streaming path: SSE parse via
response.body.getReader()+TextDecoder; surface deltas throughhelpers.reportMessage/reportThought/reportToolCall; assemble tool-call deltas via the accumulator; persistMessage/Thought/ToolCallrecords on[DONE]. - Non-streaming path: single
response.json(); same persistence + tool-execution loop.
Classes
| Class | Description |
|---|---|
| OpenAIChatCompletionsAdapter | Opinionated cross-environment LLM adapter for the OpenAI Chat Completions wire shape. |