Erlang ADK 0.8.0 release contract
View SourceStatus: release candidate validated on 2026-07-17. The complete deterministic Erlang, coverage, documentation/package, and Phoenix gates passed. The opt-in Gemini REST attempt reached Google but the configured credential shape was rejected; no paid Gemini Live pass is recorded. This is external provider evidence, not a pass, skip, or product regression. This does not claim that
v0.8.0or a Hex package has been published.
Version 0.8 focuses on operator-owned model provider profiles, native OpenAI and Anthropic request adapters, an explicit OpenAI-compatible adapter, and OpenAI Realtime bidirectional sessions. It extends the 0.7 Live runtime without replacing its Erlang-native ownership, supervision, concurrency, and backpressure contracts.
Primary wire references are the OpenAI Responses API, OpenAI Realtime WebSocket guide, Anthropic Messages API, Anthropic streaming guide, and each explicitly configured vendor's documented OpenAI-compatible Chat Completions contract.
Architectural decisions
- Binary aliases select trusted profiles. Public configuration selects a bounded binary profile ID and binary model alias. Only operator configuration contains adapter atoms, concrete model IDs, endpoints, credentials, API versions, authentication schemes, or storage/billing headers.
- Adapters are native where semantics differ. OpenAI uses Responses, Anthropic uses Messages, and compatible vendors use a separate narrow Chat Completions adapter. The implementation does not pretend these protocols have identical content, tool, streaming, or error semantics.
- Capabilities can narrow implementation, not invent it. Provider/model profile metadata is secret-free and bounded. Adapter behavior is the implementation ceiling; a profile is not evidence that a remote model or compatible deployment supports a feature.
- Credential and authority selection are generation-consistent. A keyed snapshot binds the selected adapter/endpoint/model profile to the credential lookup. Concurrent profile replacement fails closed rather than mixing generations.
- Model HTTP is bounded and origin-locked. Adapter-owned operation paths, exact scheme/host policy, verified TLS, bounded DNS resolution, no redirects, response/request/deadline limits, and streaming flow control are shared across new request providers.
- Bidirectional remains one lightweight process per session. OpenAI Realtime uses the same supervised Live session, principal checks, bounded ingress, multi-subscriber credit, tool execution boundary, and voice bridge as Gemini Live; its wire codec and fixed transport remain provider-owned.
- Audio format is negotiated from trusted status. Gemini accepts 16 kHz PCM s16le mono input and OpenAI Realtime accepts 24 kHz. The voice bridge announces the trusted provider rate before accepting audio; a caller cannot override it.
Implemented release-candidate scope
A. Profiles, credentials, and capabilities
- [x] Add a bounded
provider_profilesapplication registry with binary profile/model aliases and no untrusted atom creation. - [x] Validate known request/Live adapters, endpoint presets, structured HTTPS endpoints, model maps, secret-free capability metadata, and adapter-specific operator request options.
- [x] Resolve credentials from strict environment names, application
environment, trusted literals, or
none, while redacting public profile projections and errors. - [x] Bind profile authority to credential lookup with an opaque per-runtime keyed snapshot and fail on a changed generation.
- [x] Preserve direct atom-module provider configuration as an explicit trusted-code compatibility path.
- [x] Reject caller attempts to replace model IDs, endpoints, credentials, transports, headers, API versions, auth schemes, storage/billing settings, or Live audio rates. Allow only adapter-specific inference/runtime settings.
The complete schema and examples are in
PROVIDER_PROFILES.md.
B. Shared bounded request transport
- [x] Add provider-neutral JSON request construction with adapter-owned fixed paths, exact host/scheme policy, redirects disabled, bounded bodies and headers, and injectable deterministic transports.
- [x] Add a Gun request/stream implementation with TLS peer and hostname verification, private-address rejection by default, deadline-bounded DNS, direct connection to the checked address, explicit flow control, and a 64 KiB aggregate cap for each header or trailer block in synchronous and streaming paths.
- [x] Add an incremental bounded SSE decoder that handles arbitrary chunk boundaries, CR/LF variants, explicit empty data, event IDs, and completion without building an unbounded global line list.
- [x] Prevent ambient native-vendor keys from reaching custom origins. OpenAI and Anthropic environment keys are bound to their exact official base URLs; custom origins and all authenticated compatible endpoints require an explicitly materialized profile credential.
C. Native OpenAI Responses
- [x] Add
adk_llm_openaiwith one-shot Responses requests and incremental SSE streaming. - [x] Translate canonical bounded history for text and inline/referenced image content, function calls, and function results without exposing raw configuration as a wire-map escape hatch.
- [x] Preserve function call IDs and parallel calls; expose canonical text/function outcomes and provider metadata.
- [x] Support checked structured JSON output and operator-locked organization,
project, and
storesettings. - [x] Sanitize provider/API/transport failures so credentials, request content, and unbounded response bodies do not enter public error terms.
This adapter does not implement Chat Completions or OpenAI Realtime; those are separate contracts below.
D. Native Anthropic Messages
- [x] Add
adk_llm_anthropicwith one-shot Messages requests and incremental Anthropic SSE lifecycle decoding. - [x] Translate bounded canonical text and inline/referenced image content, tool-use blocks, tool results, parallel blocks, and role/history semantics.
- [x] Lock
anthropic-versionin operator configuration and use the nativex-api-keyheader. - [x] Support structured JSON output through the GA
output_config.formatshape derived from the existing ADK output schema. - [x] Reject invalid event ordering/content blocks and reduce remote error values to bounded structural reasons.
- [x] Validate Anthropic
max_tokenswith a minimum of one in direct and profile-selected requests.
PDF/document blocks, prompt caching, citations, extended thinking, computer use, and provider-specific beta headers are not claimed by this adapter.
E. OpenAI-compatible Chat Completions
- [x] Add
adk_llm_compatiblefor an operator-selected structured HTTPS base URL and the adapter-owned/chat/completionspath. - [x] Support
bearer,x_api_key, ornoneauthentication, with the scheme locked by the profile and no caller-injected headers. - [x] Add bounded one-shot and incremental SSE text/tool handling, canonical content translation, optional usage, tool choices, and explicitly gated response formats.
- [x] Allow a profile to disable structured output for deployments that do not implement it.
“OpenAI-compatible” is deliberately partial: vendors differ on multimodal parts, tool-call streaming, finish reasons, usage, token fields, structured output, and error envelopes. The adapter accepts only its documented subset; each target endpoint still needs provider-specific integration evidence.
F. OpenAI Realtime and bidirectional Live
- [x] Add
adk_live_openaiand a strict GA Realtime event codec for session setup, text/audio/image input, text/audio output, transcription, function calls/results, interruption, completion, usage, rate limits, and safe errors. - [x] Add a fixed
api.openai.comverified-TLS Gun WebSocket transport with credential-broker handoff, bounded frames, deadlines, no redirects, and socket-credit replenishment only after decode/admission. - [x] Allow one client action to emit multiple ordered provider frames and atomically admit that frame batch without interleaving with another caller; once sending begins, a later priority action cannot splice into the batch.
- [x] Treat browser audio-stream closure as a no-op for OpenAI. Server VAD owns
automatic commits; manual
activity_endperforms exactly one commit and response request. - [x] Publish trusted
input_audio_sample_ratein Live status and negotiate 16/24 kHz browser capture through the owner-bound voice bridge and Phoenix companion. - [x] Keep credential, module, endpoint, model ID, transport, billing headers, and sample rate out of public Live profile overrides.
OpenAI Realtime session resumption is not claimed. Browser WebRTC negotiation, ephemeral client tokens, direct browser-to-provider credentials, and durable or multi-node Live routing remain application/provider adapters. Live subscribers still receive future events only; media and side effects are not replayed.
G. Developer, documentation, and packaging integration
- [x] Extend
adk doctorwith native OpenAI/Anthropic/compatible availability and key-presence checks; extend configuration validation to recognize those adapters and binary profiles without exposing keys. - [x] Keep new source/test modules under provider, transport, profile, and
credential ownership directories rather than returning to a flat
srcortestlayout. - [x] Update the Phoenix voice path to wait for the server format frame and resample browser capture to the negotiated 16 or 24 kHz input rate.
- [x] Add deterministic request, content, stream, HTTP/SSE, profile, credential, Realtime codec/transport, multi-frame session, and voice negotiation tests.
- [x] Record the final complete deterministic Erlang gate and updated line coverage.
- [x] Record the final Phoenix/Node/assets/release gate.
- [x] Record the ExDoc/Hex package verification gate.
- [x] Record optional paid-provider evidence separately from deterministic evidence. The repository currently has opt-in Gemini REST and Gemini Live suites; no OpenAI/Anthropic paid result is implied by codec fixtures.
Release limitations
- There is no automatic provider routing, fallback, retry across vendors, cost/latency policy, or model discovery. Applications select one trusted profile alias per request/session.
- A compatible profile is not a blanket compatibility certification. Vendor deviations must be represented by bounded configuration or a dedicated adapter; arbitrary request/header transforms are intentionally absent.
- Model profile configuration is node-local application environment. Dynamic distributed rollout, persistent registry storage, KMS/HSM integration, and fleet-wide generation coordination are deployment concerns.
- Literal credentials are trusted configuration input, not encrypted secret storage. Prefer environment/application secrets populated by the deployment.
- New native request adapters do not add provider-side context caching, managed file upload, batch APIs, fine-tuning, assistants/threads, computer use, or vendor-specific search/retrieval tools.
- The existing node-local run/session/Live and Phoenix routing limitations, future-only Live delivery, Cowlib audit exception, and v0.7 security boundaries remain in force unless explicitly changed by this contract.
Release evidence ledger
These results were recorded on 2026-07-17. Historical v0.7 counts are not used
as v0.8 evidence; command details and result interpretation are in
TESTING.md and RELEASING.md.
| Gate | v0.8 candidate result |
|---|---|
| Clean compile, EUnit, Common Test, Dialyzer | Passed: 1,414 EUnit; six deterministic Common Test cases; 22 paid cases intentionally skipped; Dialyzer analyzed 235 source modules with no warnings |
| Deterministic line coverage | Passed at 74.17% against the 74% floor; the instrumented run repeated 1,414 EUnit and six deterministic Common Test passes |
| Focused provider/profile/Realtime tests | Passed 244/244; the seven-module post-audit repair set passed 67/67; focused Gemini REST header tests passed 29/29 and Live broker/transport tests passed 19/19 |
| README and example gates | Passed 30 README plus four workflow tests (34/34); all three example modules compiled with warnings as errors |
| Xref, escript, doctor, config validation | Passed; doctor reported 0.8.0 and checked configuration validated |
| ExDoc, Hex build, extracted-package compile | Passed for the 0.8.0 artifacts and package verifier |
| Phoenix ExUnit/Node/assets/release/smoke | Passed: mix precommit, 103 ExUnit, 40 Node, production assets/release, and proxy/direct-TLS smokes |
| Phoenix dependency audit | Raw audit non-zero only for the two documented Cowlib advisories; exact-exception verifier passed |
| Gemini REST paid suite | Attempt reached Google but failed HTTP 401 UNAUTHENTICATED / ACCESS_TOKEN_TYPE_UNSUPPORTED because the configured credential shape was rejected; external credential failure, not a pass or product regression |
| Gemini Live paid suite | No v0.8 paid Live pass recorded; deterministic Live evidence is tracked separately |
| OpenAI Responses/Realtime paid smoke | No repository paid-suite result recorded; deterministic evidence only |
| Anthropic Messages paid smoke | No repository paid-suite result recorded; deterministic evidence only |
| Compatible vendor smoke | No endpoint-specific remote result recorded; no blanket compatibility claim |