First release of the terminal UI on latest, still in development. The launcher resolves a prebuilt binary from the platform package for macOS (arm64, x64) or Linux (arm64, x64; static musl), falling back to CODEWORK_TUI_BIN. Nothing is downloaded at runtime, and Windows is not supported.
The TUI connects to the server named in CODEWORK_RPC_SERVER instead of starting its own, and shows a reconnecting state after a dropped connection instead of failing the turn.
Added automatic retry of transient provider failures in the harness loop. A turn whose request fails with a rate limit, overload, 5xx, timeout or dropped connection, including one that fails mid-stream, is retried with exponential backoff. Configure it with a top-level retry block in settings.jsonc: { "maxRetries": 3, "baseDelayMs": 2000, "maxDelayMs": 60000 }, where maxRetries: 0 turns it off. Quota errors are never retried, and a server that asks to wait longer than maxDelayMs fails the turn. Each failed attempt stays in the session as an aborted entry that the model never sees, and clients receive session.retry.scheduled and session.retry.finished events to show progress.
Fixed
Fixed an interrupted turn never reporting session.turn.aborted. The cleanup that settles the turn’s open draft and publishes the event was skipped on interruption, so the draft was only cleaned up on the session’s next run.
Added optIn to plugin definitions. An opt-in plugin is selected like any other but runs only when a settings entry turns it on: { "plugin": "<id>", "enabled": true }.
Added Paths to the plugin context: the harness’s own home, bin, cache, data and log directories on the host.
Added prepareArguments, constrainedSampling and encodeDetails to tool definitions, to repair common argument shapes before validation, constrain how the provider generates arguments, and control the details stored with a result.
Added readBytes and scanLines to the sandbox filesystem. scanLines returns a bounded window of a file’s lines; a remote backend runs the scan inside the sandbox (Scan.script) so only the window crosses the network.
Added SandboxMutation, which serializes the harness’s own read-modify-write of one file across parallel tool calls. Every mount layer provides it through withMutation.
Added spillPath to the runtime config and sandbox mounts: where oversized tool output is written inside the sandbox, /tmp by default.
Added idleTimeoutMs to model options in settings, defaulting to 300000.
Breaking Changes
A sandbox filesystem Provider must now implement readBytes and scanLines. A backend that only runs processes can use readBytesViaShell and Scan.script.
Added idleTimeoutMs to the request options in aikit. A stream that goes this long without a chunk is aborted as a retryable timeout, so a dead connection fails instead of waiting out timeoutMs. It defaults to 300000 in model.options.
Added the normalizeOptionalNulls export, which drops the null a strict tool call sends for an omitted optional argument whose schema does not accept null. validateToolArguments now applies it.
Changed
A usage-limit error now classifies as Quota instead of RateLimit, so it is not retried. This covers codes such as insufficient_quota and usage_limit_exceeded, and messages about credit balance, billing or an exhausted quota. A limit that names a per-minute or per-second window still counts as a rate limit.
An Anthropic model that cannot disable thinking now records providerThinkingLevel: "high" when asked to run with thinking off, since the request runs at that default effort. The effort is sent on the wire; a caller’s own effort provider option still wins.
Fixed
Fixed tools with constrainedSampling: { type: "json_schema" } being rejected by Anthropic and other strict providers. aikit set strict: true but sent the original schema; it now converts it to the strict subset (closed objects, every property required, optional ones nullable). A "prefer" tool whose schema the provider cannot express in strict mode, such as Anthropic with minimum, is sent non-strict; a "require" tool throws.
Breaking Changes
model.options.maxRetries, the retry inside the provider SDK, now defaults to 0 (was 3). The SDK retried silently, only before the stream started, and also retried quota errors. Combined with the loop retry, one outage would have cost up to 16 requests. Set it per model if an endpoint needs it.
resolveOpenAICodexToolConstraint now resolves grammar constraints only, and Message.resolveJsonSchemaConstraint is removed; convertTools handles JSON-schema strictness for every provider.
Covers every change since 0.9.2, the last release on the latest tag, including 0.9.3, which only shipped as dev and canary builds.
Added
Added the getEnvApiKey export, so a caller can check whether a provider has an API key in the environment using the same lookup aikit applies when it opens that provider.
Added gpt-6-luna to the OpenAI Codex catalog. The Codex backend serves it to ChatGPT accounts, with every reasoning level from low to max and reasoning off.
Changed
Updated @ai-sdk/openai to ^4.0.81 and @ai-sdk/provider to ^4.0.19.
Fixed
Fixed images reaching models that cannot read them. For a model whose input does not include "image", each image in a user message is now replaced with (image omitted: model does not support images) and each image in a tool result with (tool image omitted: model does not support images); consecutive images collapse to one placeholder. The message and tool result are kept, so the model still knows an image was there. Previously a user image was silently dropped, which removed an image-only message entirely, and a tool-result image was sent anyway, which providers often reject. Vision models are unchanged.
Fixed retry-after-ms and an HTTP-date retry-after being ignored when normalizing a provider failure. Only a retry-after given in seconds was read, so retryAfterMs was missing and a retry could come before the server’s requested wait.
Fixed OpenAI and Codex reasoning levels that the API rejects. minimal is no longer offered for gpt-5.4 through gpt-6 and is clamped to low, since these models reject it. xhigh and max are now offered on gpt-5.6 and gpt-6 models through the OpenAI API, and max stays off gpt-5.5 and earlier. OpenAI gpt-5.6 and gpt-6 models now turn reasoning off with none, as do Codex gpt-5.5, gpt-5.6-luna and gpt-6-luna.
Fixed gpt-6-luna ignoring a request to turn reasoning off. @ai-sdk/openai 4.0.66 dropped reasoningEffort: "none" for the model; aikit now requires 4.0.81.
Fixed every request to Claude Sonnet 5.5, Opus 5.5 and the Fable 5 models failing when no reasoning level was set. aikit sent thinking: {type: "disabled"}, which these models reject; they cannot turn thinking off, so aikit now leaves thinking to the model.
Fixed Claude thinking levels. xhigh and max are now offered on Opus 4.7 and 4.8, the Sonnet 5, Opus 5 and Fable 5 families, and max on Sonnet 4.6 and Opus 4.6; previously these requests were clamped down to high.
Fixed Claude Sonnet 4.5’s context window on the Anthropic API, which is 200k tokens, not 1M (1M needs a beta header). Responses were sized against the wrong window, so long sessions failed with a context overflow instead of a shorter answer.
Fixed a prompt that already overflows the context window failing as an invalid max_output_tokens. The response ceiling is no longer shrunk below 16 tokens, the smallest OpenAI accepts, so the provider’s context overflow error reaches the caller and isContextOverflow recognises it.
Fixed conversations started on OpenAI Codex failing when continued on OpenAI, Anthropic or OpenRouter. Codex tool call IDs (call_…|fc_…) exceed the 64-character call_id limit of OpenAI and of OpenRouter upstreams such as Meta, and contain characters Anthropic rejects; they are now shortened to the unique call part for those providers.
Fixed a provider error sent mid-stream, such as OpenAI’s context_length_exceeded event, being reported as an Unknown failure. It is now classified by its status and code like an error returned before the stream starts, so the same overflow is an InvalidRequest either way.
Internal
The OpenAI, Codex, Anthropic and OpenRouter live e2e suites now run against a model matrix: gpt-6-luna through gpt-5.4-nano for OpenAI, gpt-6-luna, gpt-5.6-luna and gpt-5.5 for Codex, Claude Sonnet 4.6 through Fable 5.1 plus the 4.5 generation for Anthropic, and Muse Spark 1.3, GLM 5.3 Flash, DeepSeek V4.1 Flash and Gemini 3.8 Flash for OpenRouter. New suites cover every reasoning level, context overflow, cross-model and cross-provider handoff, and prompt caching.