Repository navigation
Stravia v0.3.0
Added
- Windows NSIS installers now include English and Simplified Chinese. The first interactive install offers a language choice defaulting to the Windows UI language when it matches; later installs and uninstalls reuse the saved choice. Passive updater installs still skip wizard pages and reuse a saved installer language.
StraviaReadnow extracts Office documents — docx, xlsx, pptx, doc, xls, and ppt — to paginated Markdown snapshots, with ZIP central-directory preflight, container magic validation, and encrypted-CFB identification; all CPU work runs on the blocking pool under cancellation and deadlines. Embedded images deduplicate by content bytes into Artifacts (decodable ones normalized to JPEG, originals retained with a recorded limitation), and image markers in the Markdown resolve tosa:links.?question=routes documents through Media Understanding,?download=1downloads without parsing, and?rawis explicitly rejected.- Devin Provider support uses the
devin-connectConnect-RPC protocol with binary Protobuf streaming, an OAuth PKCE authentication driver, model discovery, allowance monitoring, and usage parsing that reports cached and reasoning tokens. Devin model families aggregate related selectors into one logical model record; request content redaction neutralizes competing-vendor identity fingerprints, and selector matching covers speed lanes and the 1M-context tier. - Command Code Provider support (
command-code) ships as a built-in catalog Provider with NDJSON streaming, CLI envelope encoding, and allowance monitoring that chains whoami, credits, subscriptions, and summary calls to report window quotas, point balances, and billing periods. - Vendor Options let Providers declare non-secret behavior toggles such as zero data retention; the WebUI provider editor renders them dynamically and persists them per Provider.
- Routes accept a default thinking level applied when the client does not specify a reasoning instruction, clamped at runtime to the Route's Supported Thinking Levels. The model editor exposes the default with validation, and unrepresentable thinking controls degrade to Hidden on read instead of guessing wire shapes — explicit submissions of unrepresentable controls still fail with
THINKING_CONTROL_UNREPRESENTABLE. - Usage analytics gains a
/stats/seriesendpoint with caller-selected bucket size and timezone offset aligned to local wall-clock time, a token-activity heatmap that adapts columns to container width, per-Provider average output speed, and pie charts for model distribution and input/output/cache-read/cache-write token composition. - Provider allowances load tiered and asynchronously: the list returns targets immediately while background fetches resolve each snapshot, concurrent requests for one Provider coalesce, and the WebUI renders the shell first with per-Provider loading and error states before the aggregate view resolves.
- DeepSeek balance reporting now surfaces CNY and USD accounts as separate currency-keyed rows, filters exhausted balances, and retains one USD record when the account is fully depleted.
- The desktop client's settings are consolidated under Client Settings: a LAN-binding toggle switches the gateway listener between
127.0.0.1and0.0.0.0with a retry loop that shrinks the rebind window, silent start and launch-at-login preferences control whether the main window appears on startup, and the external address display offers one-click URL copy. The tray menu follows the WebUI language without a startup flicker, drops the Copy Proxy URL entry, and left-click now only raises the main window. - The observation inspector renders the diagnostic execution flow as a flattened, numbered timeline (R1, R2, …) with "continues from" links that jump to the parent Run, inter-Run gap rows distinguishing client-tool execution from idle waits, and process events grouped into collapsible counts. Scrolling to the top of an Interaction conversation auto-loads earlier events with the scroll anchor preserved.
- Interaction chains now hide Runs that never delivered client-visible output and ended in failure; hidden nodes appear through the Failed Requests list or deep links, and Interactions containing failed Runs show a diamond failure state at their terminal node. A minimum-chain-token slider filters chains below a threshold on the logs page, whose default time window is now ten minutes.
- Debug Trace data can be cleared through an admin endpoint and UI action; per-Run and global Debug Trace capacity caps are removed in favor of tracked retained bytes, and clearing marks active Traces partial via
debug_data_cleared. - Provider Model records match model IDs leniently — case-insensitive on the rightmost
/-separated segment — with ambiguity rejected, and unmatched models receive conservativebaremetadata (256K context, text modality, reasoning and tool calling) that stays upgradeable to registered specifications on later syncs. - The WebUI marks Media Understanding, Web Search, and Artifacts features with a Beta badge.
- Browser-search profiles and HTTP-search cookies persist local search identities; Google search shares the browser profile and gates preflights on valid cookies, while fetch keeps its own isolated cookie store.
- Vendor form text now comes from per-plugin locale catalogs compiled into each Wasm component. Fields, groups, options, channels, OAuth inputs, and validation messages follow the interface language with an English fallback; changing language preserves the current form and does not rerun plugin validation.
- Vendor plugins can now be uninstalled from the management page, including unavailable installations and dedicated plugins previously bundled with the program. Confirmation explains interrupted calls and sign-ins; saved connections, credentials, models, bindings, history, and plugin data remain. The embedded base plugin stays protected, and reinstalling retained data may require explicit compatibility-reset confirmation.
- Vendor Plugins provide self-contained Wasmtime Components with a versioned WIT contract, shared SDK, and build-time-pinned codecs. The program embeds only the base fallback, which retains every existing integration except Codex, Grok, Command Code, and Devin. Those four dedicated packages completely own their supplier identities without per-channel, per-capability, or failure fallback and are published as separate release attachments for local import. Default builds produce a base-only manifest for Core; the explicit all-vendors release build produces a separate five-component build manifest. Releases publish only the four dedicated Components as
stravia-vendor-{vendor_id}-v{version}.wasm, covered by the unifiedSHA256SUMS; the build manifest itself is not published. Server and Desktop share plugin import, update previews, declarative configuration, standard OAuth, and explicit network-origin review; installation does not require a marketplace or online dependencies. - Media Generation exposes one
generatetool through platform-managed model calls and MCP. Image generation and editing use saved Routes backed by capable Vendor plugins—including locally imported Codex OAuth—plus safe reference ingestion and Principal-scoped Artifacts with actual image metadata. The configuration-only Advanced Features page supports English/Chinese and light/dark themes. Per-key automatic injection is independent and defaults off on SQLite and PostgreSQL upgrades; retries reuse existing Route policy and may consume quota more than once.
Changed
- Breaking: The desktop bundle identifier changed from
com.stravia.ai-gatewaytocn.stravia.agent-infra. Identifier-derived storage — the desktop data root, logs, window geometry, saved port preference, and WebView profile — starts fresh under the new identity, and data left under the old identifier is not migrated. Republished artifacts keep the 0.3.0 version, so installs already running 0.3.0 are not offered this build through the updater; reinstall manually to move to the new identity. - Breaking: Server and Desktop now keep managed local state beneath one resolved data root: SQLite at
db/gateway.db, diagnostics underdiagnostics/, rebuildable catalogs undercache/, and browser/host state understate/. SQLite configuration no longer accepts a separate path;--configdoes not redirect the data root. Pre-0.3.0 database layouts are not auto-upgraded — the server refuses to start on a legacy layout, and operators must stop every host using the source (including any external SQLite root) and runstravia-tools migrate-data --from <old-data-root> --to <new-data-root>(optionally--config <legacy server.toml>and--webview-from <legacy WebView dir>), which plans a verified copy by default and publishes it with--apply --source-stoppedwithout deleting source data. Desktop restart and autostart retain the selected root. - Breaking: Artifact creation returns upload-session credentials only; the final Artifact ID is returned on completion. Identical complete bytes and exact MIME under the same Principal now keep one identity across ingestion paths, multipart boundaries, concurrent uploads, and restarts. Re-uploading never shortens retention and can retain expired content again after full validation. Legacy random IDs and stored histories are not rewritten.
- Breaking:
StraviaReadnow accepts onlypath:search://replacesquery://, search filters/continuation move into the search query, and resource options use#stravia?. Stravia-managed domain blacklists are removed; allowed domains constrain final report sources. Owned and public images default to understanding, HTML/text default to readable content, and explicitdownload=1avoids model execution. Strict raw decoding, line selections, and immutable 32 KiB/200-line text pages support complete long-line continuation. Long search/media answers paginate only their delivery copy; full history remains intact. Local Search uses Revision 3 and rejects incompatible old continuations. Empty text Artifacts are supported without changing the database schema. - Breaking: Reversible redaction markers now use
<!-- stravia-redaction-marker:rm_<32 lowercase hex> -->with inline-path and streaming restoration. Migration 46 converts valid legacy mappings, preserving identifiers, credentials, and lifecycle state; the old~stravia-secret:…~marker no longer parses or restores, so clients and sessions depending on it must start over. - Breaking: Platform identities now use a 28-character random ID and 55-character SHA-256 base-26 encoding; legacy Artifact URLs, History Markers, redaction references, media and search citations, and cross-protocol tool-call IDs no longer parse. Old databases and history are not migrated or rewritten — callers establish sessions against a fresh database and the new protocol shapes.
- Breaking: The batch
POST /provider-allowances/refreshendpoint is removed. Callers list allowance targets viaGET /provider-allowancesand fetch each snapshot viaGET /provider-allowances/{provider_id};POST /provider-allowances/{provider_id}/refreshremains for single-Provider refresh. - Migration 44 allows multiple Media Understanding sources to share one JPEG derivative, including a source mapping to itself, while preserving existing mappings and cascade cleanup. Reports cite only declared current/ancestor sources with a displayed derivative; failed or losing mapping writes never delete shared content.
- The hourly usage statistics endpoint is replaced by
/stats/serieswithbucket(seconds) andtz_offsetparameters; reported usage keeps net input (cache reads deducted per attempt) and output (reasoning included) semantics across admin queries, projections, and statistics. - Desktop no longer exposes provider-allowance commands (
list_provider_allowances,get_provider_allowance,refresh_provider_allowance) or their capabilities; allowance monitoring remains available through the admin API and WebUI. - Observation canvases no longer mount every new card at the origin for measurement. Shared node and handle geometry enables viewport culling before the first mount; unchanged nodes retain their identity, and long-chain ancestry checks reuse traversed prefixes without changing causal links.
- Streaming Observation now seals immutable text blocks at 16 KiB or approximately two seconds, batches event and summary writes, and compresses new blocks only when storage decreases. Existing rows remain unchanged. The inspector separates unsaved live previews from committed history, loads events incrementally, and pages older records. Ordinary detail reads no longer flush writers; Debug Bundle issuance flushes only the selected Interaction before fixing its complete snapshot. A process crash may lose pending observation text from the normal two-second window.
- Live observation canvases load summary-only interaction/root snapshots and fetch ordinary Run details only for the selected inspector. Context links use bounded batch queries and migration 42's equivalent SQLite/PostgreSQL partial indexes; filters, complete causal roots, and fixed time windows retain their existing semantics.
- Debug Wire and canonical checkpoints now enter Trace directly instead of adding an ordinary observation row per record. Four-direction ZIP capture, manifest updates, SSE replay, and fixed snapshot cutoffs remain available. Existing history is not rewritten or deleted.
- OpenCode Zen free-tier (
-freesuffix) models are filtered from discovery, capability queries, and record management, and intercepted in the execution path to prevent upstream 400 rejections. - Provider creation and editing now share connection-draft orchestration. Preview, save, and OAuth binding lock editing and dismissal until they settle; waiting for interactive sign-in remains cancellable. Reauthorization still saves automatically, and a saved configuration with failed OAuth binding stays an explicit partial success without overwriting the draft. Browser refresh or tab closure can only show the native leaving warning; forced exit cannot cancel an issued write.
- Thinking levels now resolve against each selected Target's non-Hidden mappings rather than being clamped to the Route-wide intersection: exact match first, then the nearest higher level, then the nearest lower level. Failover restarts from the original requested level, so
offcan resolve upward and different Targets may use different effective levels. A Target with no visible mappings is skipped for an explicit client level, while a Route default is dropped and execution continues without a thinking instruction. Supported Thinking Levels remain a conservative intersection for management, model discovery, and client configuration exports; their fields and formats are unchanged. - Desktop windows now open at 1440×900 when space permits and remember their last position, size, and maximized state. Restored windows are kept within the available display work area when monitor layouts change.
- Breaking: Vendor plugins now require
stravia:vendor@0.4.0and must be rebuilt and re-imported with the updated host. The contract adds localized display metadata and exact WebSocket continuation identity;0.3.0Components are incompatible. Configuration keys, values, credentials, client APIs, database schemas, and data-format epochs are unchanged. Restoring an unavailable plugin still compares its recorded data compatibility without discarding data merely because its old display metadata cannot be decoded. - Local Web Search and Fetch again use
wreqfor ordinary HTTP requests and an installed Chrome/Chromium for browser rendering. The Local editor restores browser-path selection (STRAVIA_CHROME_PATHor automatic detection when unset); the container bundles Chromium. Existing Moli browser-profile and search-cookie files remain untouched but are no longer used, so local search identity does not persist across restarts. - Breaking: SQLite and PostgreSQL use a frozen baseline as their compatibility floor; the pre-baseline historical migration chain remains removed. Databases already using that baseline upgrade through data-preserving incremental migrations. Unknown, incomplete, failed, or checksum-mismatched histories are rejected without deleting data.
stravia-tools migrate-datarelocates supported-prefix data roots without modifying the source schema; destination startup applies remaining migrations. Pre-baseline layouts anddatabase.pathconversion remain unsupported. The previously removed persisted-data aliases, legacy trace decoding, and unused static gateway credential are not restored. - Route storage rows, runtime configuration, and management projections have separate types. Route storage keys, client Route IDs, Provider IDs, upstream model IDs, and Target IDs occupy distinct identity spaces.
- Provider Model snapshots explicitly distinguish unregistered, imported, and edited specifications. ID-only discovery no longer invents capabilities, modalities, or context limits; synchronization preserves imported and manually edited specifications and rejects stale revisions. Existing snapshots retain their metadata and are conservatively marked edited with unknown provenance.
- Breaking: Route writes accept only
targetsfor Target configuration; writabletarget_provider,target_model, and caller-supplied Target IDs are removed. Omitted Targets preserve existing rows and policies. Nullable fields distinguish omission from explicit clearing, and invalid replacements leave the complete Route unchanged. - Canonical Item metadata and references are typed while preserving the current persisted JSON contract and v6 history. Conflicting semantic items with the same referenced identity are rejected as
item_reference_ambiguousinstead of selecting the last match. - JavaScript tooling now uses Bun 1.4.2 across development, builds, checks, and tests. CLI entry points and dependency installation explicitly use Bun rather than selecting the installed Node.js runtime; Rust and Python test runners are unchanged.
- CI test workflows avoid duplicate pinned/stable Rust execution when compiler releases match, reuse the production WebUI build for Playwright, and report per-case SQLite/PostgreSQL storage timings. Authentication fixtures now use a deterministic local upstream with temporary resources cleaned up; Rust tests continue to use cargo test.
- Web Search, Media, and Web Provider rule coverage now avoids six redundant full Gateway initializations while retaining persistence and error contracts; token activity layout coverage reuses one page navigation across all granularities.
- Breaking: Public resource references now use
stravia://artifacts/<artifact-id>,stravia://turns/<turn-id>, andstravia://turns/<turn-id>/sources/<ordinal>.StraviaRead, Web Search, Media Understanding, Media Generation, bridge markers, and reports usepath/previous_pathand complete URI citations;sa:,[sc:...],[sm:...],[st:...], raw Turn IDs, and the Open Responsesstravia:media_resultextension are removed without compatibility aliases. Persisted Artifact IDs, TurnNode IDs, upload/download grants, tool call IDs, and existing history bytes are not rewritten; callers must migrate to the new public shapes, and old history references may fail rather than being silently rewritten. Standard Responsesid/previous_response_idand agent-result protocolidremain unchanged. - Provider connections now keep their saved UUID separate from the supplier identity used to select a Vendor profile and channel. Plugins own upstream inference, authentication, model discovery, allowance normalization, refresh, full-search, and image-generation behavior while the host retains scheduling, network authorization, cancellation, retries, history, and Artifact ownership. External search supports Provider-only Route Targets and does not accept continuation; Local search retains its existing continuation contract.
- Existing cloud connection settings migrate out of credential storage into non-secret Vendor Options on both SQLite and PostgreSQL. Explicit Vendor Options take precedence, while saved secrets and connection identities remain intact.
- The base component covers the complete bundled Provider Catalog through a build-generated static registry. Compatible brands retain their adapter-family behavior without inheriting unrelated OAuth channels. Native account inventories and channel-specific curated lists remain authoritative despite saved catalog-origin markers; directory-backed profiles keep their scoped inventory, and explicit static lists override either source.
- The embedded base Component loads directly from program memory and is not written to
plugins/artifacts/. Locally imported dedicated plugins and base replacements remain immutable, content-addressed instance files there; SQL keeps installation metadata and business/private state, never Wasm bytes. Data migration copies imported artifacts with the instance root, and deployments using local imports must pair those files with the database for complete backups—a remote PostgreSQL backup alone is insufficient. - Compatible plugin updates keep active calls on their original version. The embedded base plugin upgrades forward automatically unless locally replaced, including selective resets of data incompatible with the bundled version; affected connection IDs and reset categories are logged. Codex, Grok, Command Code, and Devin have no embedded version to restore or auto-upgrade and remain locally managed after import; reducing the embedded set does not delete their existing installations or data. Data-incompatible local updates and manual restoration still require explicit discard confirmation, cancel that Vendor's active work, and reject late writes; selective resets retain Provider identities, Route/Target bindings, history, and confirmed usage. Restoring the embedded base version exposes downgrade and compatibility consequences before confirmation; an unavailable base installation can be restored directly without first importing a replacement.
- History storage now deduplicates repeated instructions, tool definitions, and response profiles within each Principal, without compression or changing replay semantics. SQLite and PostgreSQL keep explicit content references with branch-safe retention. Debug segments independently deduplicate metadata and payloads; exports restore complete records.
stravia-tools migrate-data --optimize-storageverifies and optimizes an offline SQLite destination copy, preserving source data for rollback and reclaiming free pages only in the copy. Older binaries cannot read the new storage representation. - Wire Debug captures four raw directions at application transport boundaries. Only HTTP
Authorizationheader values are masked before queueing; other credentials, content, and media may remain recoverable, so bundles remain sensitive diagnostic data. Historical Trace records remain unchanged. - Runtime logs now also persist to rolling files alongside console output. The server writes under
<data-dir>/logs/stravia-server.<date>.log; the desktop app writesstravia-desktop.<date>.loginto the same log directory asdesktop-startup.log. Both keep the seven most recent files. The desktop log level followsSTRAVIA_LOG_LEVELand defaults to debug. - Upstream transport failures now carry the underlying network cause (for example a reset or TLS error) in the recorded failure message, so the failed-requests view identifies the actual break instead of a generic transport label.
Removed
- Linux musl server release archives and their Zig-based static build jobs. Linux server archives now ship only GNU builds for x86_64 and ARM64.
- Removed Nix flake packaging, the NixOS service module, and their release/cache jobs. Server deployments use release archives or the container image.
Fixed
- Request Records now aggregate chain-token filters once per root instead of repeating the same sum for each interaction, preserving thresholds, counts, and pagination. Canvas focus restores readable target cards independently of the whole-graph overview; programmatic positioning no longer pauses live follow or triggers edge pagination. Layouts reclaim space after branches disappear, and snapshot-scoped parent indexes reduce long-chain link and selection work without changing causal links or stored history.
- Target cooldown now recovers through one traffic-driven half-open probe rather than reopening to concurrent requests. Failed probes restart the configured cooldown without normal or provider-internal retries; complete success restores scheduling, while cancellation releases the probe and stale outcomes cannot overwrite a newer state. Removed the separate fixed 3-failure/30-second health filter. Model destination indicators now reflect runtime cooldown/probe states, refresh independently of unsaved edits, and show explicit read failures instead of stale green status.
- Usage analytics token totals (overview, hourly, model, and API Key aggregates) now accumulate reported values across successful Target attempts. Failed or still-running attempts never carry confirmed usage, and one attempt's unreported field no longer forces a whole group total to
null; a total staysnullonly when no completed attempt reported that metric. - Responses now preserves generic Thinking as full reasoning content in both streaming and non-streaming output and saved client history. Exact tool-result replays no longer split Interactions or incorrectly branch from older responses because of a summary/content mismatch. Native reasoning summaries remain distinct from full content; existing history and observation links are not rewritten.
- Usage analytics, API Key lists, and Model lists now complete their first load when dependency queries finish before the main query. Loading, refresh, and list error states read every participating query before combining results, preventing stale snapshots from leaving pages on skeletons or losing retry feedback.
- Codex V2 remote compaction now preserves native states completed by
response.output_item.donewhen the terminal response omits them, instead of failing withprotocol_lossy_rejected. Explicitly conflicting terminal states remain rejected, and legacy standalone compact errors are still forwarded without a local summary or implicit V2 conversion. - Interaction status now accounts for unambiguous client-tool results on sibling Runs, without rewriting historical Run outcomes or masking genuinely pending branches. Database projections and Debug Bundles use the same evidence rule. Startup reconciles stale aggregates and marks unresolved waiting leaves Interrupted (
process_restarted), preserving delivered history, retention, and later continuation. - Waiting-client Interaction branches now become Disconnected when their WebSocket connection closes, without changing successful delivery or Generation Chain history. WebSocket finalization uses the stream task's final tool-handoff state, including closure races; later valid continuations can resume the same Interaction. Normal HTTP/SSE completion and older records without connection ownership are not treated as evidence of disconnection.
- Client-tool observations deduplicate replayed results only within a proven call boundary and retained, same-principal Run ancestry, comparing redacted contents and error state. New handoffs, sibling branches, changed results, and missing/null result boundaries remain distinct; migration 43 adds lookup indexes without copying stored bodies. Late inspector responses can no longer restore a closed or replaced selection.
- Generation history discovery now ignores application and internal tracking metadata while preserving complete message semantics, tool-result associations, protected reasoning, and unclassified protocol extensions. Startup rebuilds older derived prefix indexes without rewriting original history or parent links.
- Interaction Observation keeps exact pending-tool continuations in the same Interaction even when they include user reminders, without a time limit. Exact follow-ups received within two seconds of the parent response's complete delivery also stay together and can reactivate a completed Interaction; this diagnostic rule includes fast human follow-ups and does not alter model input or execution. Grouping reasons and immutable delivery timestamps survive observation delays and restarts.
- Streaming Responses reasoning items now seal before a new message, tool call, or ordinary item starts, keeping
output_item.doneordering consistent withoutput_indexand reopening a fresh reasoning item when consecutive reasoning blocks are interrupted. - Tool-call completion events now emit as soon as an item finishes instead of waiting for the terminal response, without duplicate completions on response end.
- Markdown rendering escapes raw HTML (title, script, img, and similar), keeping model output visible without executing markup.
- Codex HTTP requests no longer send
service_tier: auto, which upstream rejected with a 400 error. - Devin pricing fields decode fixed32 values without float-precision noise.
- The desktop app disables Tauri's default drag handler so Windows HTML5 drag-and-drop works again.
- Provider connections created through the service picker now retain their profile's catalog association and discover scoped model metadata, including reasoning effort levels. Existing connections with missing associations recover through model synchronization without a schema migration; explicit inventories, account-level discovery, and manually edited specifications remain intact.
- Interaction Observation no longer panics when Unicode text directly precedes a URL in input previews or other redacted text; URL credentials remain masked and surrounding text is preserved.
- Explicit Provider Model re-import now atomically updates its snapshot, cost rules, generated Target mappings, and configuration notification while preserving current manual mappings and Target identities. Stale revisions, unsupported manual controls, and errors during transactional writes no longer leave partially updated snapshots or Target mappings; successful responses make the complete update available to new requests on the current instance.
- Current tool continuations keep the same Interaction and follow the actual source Run when edited history makes strict Generation matching fall back to an earlier parent. Generation links and model input remain unchanged; historical tool-result replay and ambiguous sources still cannot trigger a merge. Existing observations are not regrouped.
- Request-record token filters now temporarily include estimated input for running model turns before upstream usage arrives, including standalone system instructions and tool definitions rather than only message history, so large requests can appear immediately. Confirmed usage replaces the estimate; estimates never enter usage totals or billing.
- Vendor inference no longer rejects valid streams after 32 metadata events before the first output. A per-attempt 1 MiB estimated pre-output buffer budget replaces the count limit without blocking the first output or normal completion; Devin suppresses repeated model identifiers while retaining model changes and same-frame usage.
- Devin model discovery again declares text input/output, image input when supported, and family-specific reasoning controls. Effort levels and thinking toggles match the pre-plugin behavior, while fixed-effort models do not expose an unsupported picker.
- Active vendor response streams no longer fail at 300 seconds because of an independent HTTP total timeout. Default and explicitly proxied connections retain the shared operation deadline and cancellation behavior.
- Codex
store=falsecontinuations now retain stable connection identities and require the exact available WebSocket response tip before sending an upstream ID. Disconnected, evicted, busy, or advanced connections fall back to full history before sending, without consuming retry budget. Explicit upstream continuation rejection can replay full history at most once under the existing recovery budget, never after response events begin. - Interaction canvases keep confirmed Generation Chain parent links solid when retained-tail diagnostics identify the same source; cross-root diagnostic links remain dashed.
- The service picker again shows localized sign-in methods instead of internal capability names, omits capability badges, and prefers model-directory logos before falling back to bundled icons.
- An empty hidden-round ledger no longer turns confirmed response usage into unknown usage. Streaming and buffered Responses preserve known zero values without inventing values for unreported usage.
- Observation attribution reuses ancestor windows from the same Generation Chain traversal instead of repeatedly restoring overlapping histories for each retained-tail candidate. Confirmed-parent diagnostics, ambiguity checks, Principal isolation, and resource limits remain unchanged.
- Attachment normalization preserves Artifact error categories: invalid input stays a client error, while storage failures return sanitized server errors. SQLite Artifact sweeping releases the database writer during object I/O and keeps its object lock until in-flight deletion settles, including caller cancellation; re-upload repairs expired objects before making them readable again.
- Observation reserves queue space for lifecycle records, preserves completion ordering, and reconciles missing activity terminals only after the last observer is released, without ending live background tools or discarding confirmed usage. Missing parent observations and failed Generation history commits remain explicit diagnostics. Completed interactions display earlier request failures separately, and delivered non-text output no longer appears undelivered.
- Observation now coalesces adjacent same-scope text before enqueueing, preventing fine-grained streaming bursts from displacing request admission and completion records. Existing missing observations and split interaction links are not reconstructed.
- Redacted Responses continuations selected by Route ID retain native continuation when the upstream reports effective generation or reasoning defaults.
- Local response-delivery deadlines no longer count as upstream failures or put a Target into cooldown.
- Cross-protocol Responses continuations retain the selected upstream response ID without mistaking client projection for a Hook rewrite. Deadline failures preserve their typed terminal error under stream backpressure, and independent search/image calls retain confirmed or unknown usage in request statistics.
- Continuation and authentication recovery retain the original Wasm component and cancellation generation across compatible updates. OAuth token rotation preserves account affinity, while reconnecting invalidates prior native state. Real upstream 401 responses can use the host's bounded authentication recovery, including GitLab auxiliary tokens; 403 responses are not refreshed or replayed.
- Explicit model-directory endpoints preserve supplier authentication and their configured paths. Plugin-update cancellation remains cancellation in external search and image-generation results instead of becoming an upstream failure.
- Route editing distinguishes unavailable capability metadata from confirmed unsupported capabilities and offers retry. Plugin availability is localized, and compatible-update previews no longer claim that active authorization sessions will be cancelled.
- Target cooldown now uses one consecutive upstream-failure count across internal retries, transport recovery, and later requests. The default retry budget of 5 starts cooldown on the sixth failure rather than the first committed-stream disconnect; complete success resets the count. Cancellation and local preparation failures do not count, half-open probes remain single-attempt, and output already delivered to clients is never transparently replayed.
- Immediate continuations now wait for matching in-process Generation commits before discovering or materializing their parent, preventing stale-parent Interaction branches without serializing unrelated requests. Failed or cancelled writes never publish resumable history, and observation backpressure cannot hold execution.
- Responses stream errors preserve canonical failure categories from upstream decoding through public delivery. Transport failures use the interoperable
server_errorcode; permanent request and quota errors no longer inherit a retryable generic stream category. Nested dated error envelopes, diagnostic masking, terminal ordering, and the no-replay boundary after client output commit remain intact. - Desktop startup failures now retain an independent recovery window with safe diagnostics, bounded startup logs, restart, and exit instead of disappearing. Optional desktop integrations degrade to warnings; failed silent launches become visible, failed-window close exits, and native dialogs cover window-creation errors without resetting or repairing stored data.
- HTTP and Responses WebSocket failures retain redacted, length-bounded cause chains and transport-stage diagnostics, including observed response state, known HTTP status, and WebSocket close codes, without changing retries or completion semantics.
- Wire Debug capture preserves each observed application-protocol chunk, including malformed, incomplete, and non-UTF-8 bytes, without JSON/SSE/NDJSON reassembly or media externalization; complete and partial Trace status remains tied to capture/storage boundaries rather than protocol parseability. Plugin HTTP capture keeps concurrent responses isolated even at the same URL, so initialization and auxiliary calls cannot consume inference records.
- Responses streams now close indexed reasoning items on their authoritative
ItemDone, preserving late signatures and preventing already-completed thinking from being replayed after subsequent tool calls by OMP. Terminal responses retain the same items without duplicate completion events. - Devin multi-turn tool continuations preserve signed thinking without separating tool calls from their matching results, fixing
invalid_argumentfailures with OMP Responses history. Historical user images and images returned by client tools remain attached to their original messages instead of being replaced or silently discarded. - Devin request encoding groups Responses assistant text, signed reasoning, and parallel tool calls into native prompts without combining independent historical signatures. Within one Devin response, interleaved text, thinking, and signature deltas retain their response-wide identity; replay omits response
output_idfrom native history prompts, matching the native CLI. Top-level tool descriptions use numbered sentences and list items while preserving fenced code and JSON paragraphs, followed by XML escaping. - Codex OAuth now presents client version
0.156.1on model discovery and generation requests, unhiding version-gated models such asgpt-6-solandgpt-6-lunathat the0.153.0pin silently omitted.
Full Changelog: v0.2.2...v0.3.0