NewYour coding agent can read the release notes before it upgrades.Set up the MCP server →
Unified LLM service layer for Flutter/Dart (Rust core, 325 providers, C ABI via dart:ffi)
Last release 10 days ago
28 Sep 2026
Ships fairly regularly
a new release about every 4 weeks
Nearly every release is documented
notes for 3 of 3 stable releases
Nothing withdrawn
no release was ever pulled
2 months old
3 releases · first in 2026
One column per month.
chore(release): bump to 0.5.0 and document breaking changes by @eric8810 in #195
Full Changelog: v0.3.0...v0.5.0
Breaking release. 13 PRs since 0.3.0: the cross-language error model stabilized behind one opaque C-ABI error pointer, the request pipeline aligned with the AI SDK (core-owned retries, timeouts, stream lifecycle, video start/status split), tool inputs parsed and validated at the Core boundary with host-side repair in every binding, WebSocket proxy support plus ElevenLabs realtime transcription, and SSRF hardening for provider-supplied download URLs.
Rust (aimux-core / aimux-provider-utils)
RetryError { maxRetriesExceeded | errorNotRetryable } preserves the
full attempt history; Full Jitter drives the exponential branch; server
retry-after hints are honored exactly. Providers declare policy
through retry_config(); Core executes it around
do_generate/do_stream. stream_text now requires a tokio runtime
(its pump task spawns unconditionally).VideoModel splits into do_start/do_status with a Core-owned poll
loop; generate_video validates n (0 is InvalidArgument before any
network call), batches by max_videos_per_call concurrently, and mints
one idempotency key per batch — billable starts replay safely.parseToolCall contract. Invalid
calls return as tool calls marked invalid: true with a typed error
(NoSuchTool / InvalidToolInput / ToolCallRepair; 16-variant
contract, compile-time exhaustive). GenerateContent::ToolCall.input
is String (was serde_json::Value); a compatibility deserializer
accepts the legacy object shape.to_chat_completion_stream_with_deferred_tool_calls, the
defer_tool_calls flag): the OpenAI stream always forwards provider
tool-input deltas and does not reflect repair (#192).send / send_timed / send_stream_timed /
send_with_retry_raw and the JSON-path ErrorStructure are replaced
by single-exchange helpers (post_json_to_api, post_form_data_to_api,
post_to_api, get_from_api) dispatching to typed response handlers —
exactly one fetch attempt and one recorded exchange per call; retry,
timeouts and backoff belong to Core (#164).C ABI
aimux_error_t * (#158): every
fallible function returns NULL on success (result in a trailing
out-parameter) or one owned error, released exactly once with
aimux_error_free(). The caller-allocated AimuxError struct,
aimux_error_clear and the error_value projection are removed. One
unified code space: AiMuxError 1–17 (4 retired slots, 14 = Retry),
RecordingError 100–105, C-boundary failures 200–206; a non-NULL error
never reports code 0.aimux_error_request_id is removed — request ids ride in response
headers (#164).aimux_tool_call_repair_context,
aimux_apply_tool_call_repair,
aimux_apply_tool_call_repair_to_result) let any host repair an
invalid call in its own language; safe to call from inside a stream
callback.Node / Python (native bindings)
instanceof across
sync throws, promise rejections, streams and workers; the serialized
errorValue/error_value companion is removed (#158).All eight bindings
VideoPollOptions
surface (#164); recoverable stream-frame errors keep the stream alive
(forwarded as data on the plain path, skipped on the chunk-typed
OpenAI path).repairToolCall (RFC-0035) (#192): the binding runs the
user's repair function in the host language and re-validates through
the pure core functions; non-streaming results are patched before
decoding, OpenAI-format outputs repaired then converted.Go
Close is no longer a join (#157): every native owner is an atomic
handle; Close never waits for an in-flight C call, and owners must
not be copied after first use (go vet flags it). Router/Moa
constructors reject any invalid member handle instead of silently
dropping it.ws_connect honors
the global ProxyConfig (HTTP CONNECT tunnel with Basic proxy auth,
no_proxy suffix matching); SOCKS and https-scheme proxies fail loudly
as UnsupportedFunctionality; wss tunnels run rustls with webpki-roots.
Proxy credentials never reach error strings; IPv6 proxy hosts work.scribe_v2_realtime streaming transcription
(RFC-0034 P2) (#184) — realtime WS sessions with commit-on-last-chunk
semantics, partial/committed transcript mapping, timestamped finals,
and 14 documented error events classified retry/terminal; non-pcm/ulaw
formats fail fast without connecting.{error:{message,code}} (ElevenLabs
FastAPI, AssemblyAI, Deepgram, fal, Hume) (#164).TranscriptionSession.Close vs
NextPart(-1), a backpressured stream vs Model.Close); FFI
Router/MoA silently dropped dead member handles mid-construction.aimux) (#155/#156).{} on the OpenAI wire instead of invalid JSON
(#165).invalid: true call instead
of aborting the stream (#165).Retry-After HTTP-date hints no longer read as "absent" through the
C ABI (#164).transcribe / rerank / search accept options
(max_retries, timeout were unreachable), and
search("cats", {query: "dogs"}) no longer silently searches for dogs
(#164).close() no longer deadlocks the
three threads (#192).staticlib never goes through cargo's link step — the 0.5.0 xcframework
hit pub.dev's 256MiB uncompressed package limit and was rejected. The
iOS build now uses an LTO-off profile and strips debug/local symbols:
each slice drops from ~128MB to ~15MB.fix_tool crate, and unused
workspace deps (schemars, proc-macro2, syn, quote) (#169).aimux_error_request_id (C ABI) — request ids ride in response
headers (#164).fix(release): flutter-publish embeds iOS xcframework from artifact root by @eric8810 in #29
Full Changelog: v0.2.1...v0.3.0
Note truncated.
Breaking release. 196 commits since 0.2.1: observability primitives (recording / replay / sessions / tracing), composite models, streaming transcription, a reworked error model across the C ABI and all eight bindings, a browser console, and a large provider-correctness sweep.
Rust (aimux-core / aimux-provider-utils)
AiMuxError::RateLimited gained message: String (now
RateLimited { retry_after_ms, message }); #[serde(default)] keeps
old payloads deserializable, but the generated TypeScript marks
message required — update exhaustive destructuring.GenerateTextOptions / CallOptions / StreamTextResult gained public
fields (session_id, recording/trace controls, stream-result metadata).
Use struct-update (..Default::default()) instead of exhaustive
initializers.shared_client() / shared_streaming_client() (aimux-provider-utils)
now return Result<&'static Client, AiMuxError>: client-build failures
(TLS backend, resource exhaustion) surface as a sticky, non-retryable
ApiCall instead of aborting the host process (#147).C ABI & the six FFI bindings (Kotlin / Java / Swift / Go / Flutter / C)
AimuxError out-parameter with typed
code + HTTP status + retry hint; the JSON error envelope, the streaming
on_error callback, and aimux_last_error() are removed.topK is now Double (was Long — 40.5 truncated
silently); published artifacts require JDK 17 (jvmToolchain(17)).topK likewise typed as double-valued (#106).init_recording_ring(0) now throws instead of a silent no-op
(consistent across all seven languages).Python / Node (native bindings)
next_part) / rejecting (nextPart) the typed hierarchy, and part
payloads are no longer wrapped in a {"Ok": ...} envelope — both now
match the C-ABI session shape and the other six bindings (#145/#150).
Code that parsed the envelope manually must catch the exception.Recorder /
JsonlRecorder plus a bounded in-memory RingRecorder with drop
counting; layer-B HTTP choke-point recording (per-attempt, streaming,
credential redaction); mock & request replay with matchers and the
aimux-replay CLI; cross-binding exposure via C ABI, Python, Node, Go,
Swift, Kotlin, Java, Flutter; config_snapshot() captures the minimal
provider/model identity. aimux_recording_try_flush FFI export reports
write failures (sticky first error) across the ABI (#133/#137).session_id groups related calls;
SessionStore + SessionInferer with query APIs in all bindings;
session-cache trajectory export.TraceLayer, verdict engine, and
RingTraceStore detect prompt-cache hits from provider headers
(vLLM / SGLang / LMCache behaviours), with cluster/route-aware gating;
exposed in every binding.aimux-cli cache-probe client (RFC-0025) — offline / session /
provider probing over the trace store.generateOpenAIOutput
across all eight bindings.Provider::list_models and
get_model_specs with reasoning/capability metadata.LanguageModel wrappers, usable from every
binding with zero call-site changes:
RouterModel (RFC-0021) routes each call to one child model through a
pluggable Router strategy (built-ins: RuleRouter, WeightedRouter)
with automatic fallback to the remaining children on failure.MoaModel (RFC-0022) implements mixture-of-agents in a single call:
reference models run in parallel, their outputs are spliced into an
aggregator prompt, and the aggregated answer is returned — no agent
loop involved.streamText aggregation, generateObject,
top-level result aggregation (reasoning / sources / files /
responseMessages), proxy configuration, rawFinishReason, logprobs,
usage.raw, streaming warnings, includeRawChunks,
ResponseMetadata.timestamp.aimux-web console (RFC-0029) — browser-based model-call testing
and trace visualization, shipped as release artifacts.0600, masked hints only, and plaintext
entry is loopback-gated (non-loopback binds fall back to env:VAR
references).ProviderWithConfig (Go), full ProviderOptions for
provider() (Python), optional recording-ring capacity in every
language.Provider correctness
functionResponse.name now uses the tool name instead of the
opaque call id (multi-turn tool calls no longer 400) (#127).Finish part
(contract parity with OpenAI/Google) (#128); assistant reasoning —
including its signature — is echoed back when thinking is enabled
(#131/#138).try_flush instead of a silent Ok, and the completion barrier requires
the input record before finalizing (#110/#133).ApiCall/NoSuchProvider fields with unified retry
classification (#94); retry config honored for vertex/anthropic-aws;
credential-source accuracy for xai/open-responses; real provider
identity surfaced on the OpenAI chat path.nextPart is
actually reachable (#116/#144); close-race read/write locks for handle
types in Kotlin/Java/Flutter; Python exposes recording / mock-replay /
get_model_specs with typed exceptions.Tests & fixtures
top_k drift that hid for
months is regression-locked (#106).# Errors docs),
rustdoc -D warnings in CI, ts-rs type-drift check, ProviderName
generator-drift check.docs/quality-audit/round4/; unused-dependency sweep; rustdoc errors
47 → 0.aimux_last_error() (C ABI) — replaced by the AimuxError out-param.on_error callback.fix(go): correct Go binding doc examples that fail to build/run by @cunninghamcard-bit in #11
Full Changelog: v0.2.0...v0.2.1
Full Changelog: v0.2.0...v0.2.1
Patch release following 0.2.0. First Maven Central (Java + Kotlin) and pub.dev (Flutter) release; Rust / Node / Python re-released to stay aligned with the new bindings.
Your coding agent can read these notes before it upgrades. Set up the MCP server →