Skip to main content
Track what’s new in Fleet RLM or browse all changelogs.

Week of November 2: Fleet-RLM 0.11.0

Fleet-RLM 0.11.0 shipped on November 6.

New features

Role-scoped model connections Root, Sub, Reflection, and Judge can each set their own model, api_base, api_key_env, and adapter. A role without its own model inherits the shared [llm] connection. Without a shared model, Root and Sub default to openai/system.ai.deepseek-v4-1-flash-1017. See Configure models.Workspace context in direct mode An explicitly selected direct mode inlines the Session’s files/ into its prompt, up to 1,000,000 characters. The Turn records direct_context_chars and direct_context_truncated, and the stream sends a direct_context event. See Reasoning and recursion and Stream events.

Updates

  • Breaking: config schema version 5. config/fleet.toml must set schema_version = 5. The [models] and [connections] tables are removed; configure [llm] and the role tables directly. Unprefixed LLM_BASE_URL and LLM_API_KEY are rejected; use FLEET_LLM_BASE_URL and FLEET_LLM_API_KEY. See Configuration and Troubleshooting.
  • Native DSPy configuration. Fleet uses native DSPy configuration and role adapters. Capped replies rely on DSPy’s JSON recovery instead of a Fleet re-ask.

Week of October 26 — Fleet-RLM 0.9.0 and 0.10.0

Fleet-RLM 0.9.0 shipped on October 28 and 0.10.0 on November 1. Their release notes are listed separately. This entry covers the rest of the week’s changes.

New features

Server-owned optimization experiments GEPA runs are now owned by the server, and their lifecycle is stored in PostgreSQL (0.9.0). Routes under /sessions/{session_id}/experiments list runs, start one with POST, get one with /{run_id}, cancel one with POST /{run_id}/cancel, and review candidates with POST /{run_id}/review. In the terminal, /optimize submits a server-owned run, and /experiments opens a screen where you browse runs and approve or reject candidates. Optimization requires at least one critical holdout example (fleet eval label ... --critical). See the HTTP API reference and the terminal guide.

Updates

  • Config template. Fleet now ships config/fleet.toml.example instead of config/fleet.toml. Copy it to config/fleet.toml, which Git ignores. Without the file, Fleet uses built-in defaults. A FLEET_CONFIG path that isn’t an existing file fails. Databricks mode has no built-in catalog or SQL warehouse ID. See Configuration and the quickstart.
  • Stricter API contracts. timeout_seconds is strictly validated. Workspace writes with neither or both content fields return 422. Fleet validates every SSE envelope before sending it. See the HTTP API reference and Stream events.
  • Committed Turn results include turn_id. Live completion and idempotent replay return the same committed payload. Tracing or delivery errors after the commit can no longer downgrade a success. See the HTTP API reference.
  • Native DSPy JSON recovery. Fleet no longer sends its own corrective re-ask. DSPy’s JSON recovery retries once, and that retry counts toward the Turn’s model-call budget. See Reasoning and recursion.
  • Workspace transfer spans. MLflow records spans for validation, preparation, download, and upload, with counts, attempts, backoff, and bytes. The spans never include file names or contents. See Observability.
  • Sandbox cleanup fencing. The Session stays fenced until Sandbox cleanup is confirmed. Migration 8 persists Sandbox ownership on the Session row. Turns left running after a takeover are recorded as failed and are not replayed. See Deploy with PostgreSQL.

Week of October 19 — Fleet-RLM 0.8.1

Fleet-RLM 0.8.1 shipped on October 23. Its evaluation and model changes are listed separately. This entry covers the Turn and terminal changes and the fixes merged after it.

New features

Per-Turn deadlines POST /sessions/{session_id}/turn accepts timeout_seconds, and the terminal adds /timeout <seconds|off|default>. Values are 0 or 10 to 3600 seconds. The shipped deadline stays 900 seconds. 0 turns off only Fleet’s deadline, and Daytona’s own lifecycle bounds still apply. See Run a Turn and the terminal guide.Attach local files with @ mentions Terminal @ suggestions find local files and directories as well as workspace files. Submitting uploads the selected content. Directory uploads keep their structure and skip ignored files, hidden files and symlinks. Browsing never uploads. See the terminal guide.Guided setup checklist fleet cli and /setup open a setup checklist that edits and saves .env, verifies Models, Database, MLflow and Daytona, builds or activates the Daytona snapshot, and restarts the services fleet cli owns. See the terminal guide.

Updates

  • Breaking: Fleet owns the Sandbox snapshot. daytona.snapshot and FLEET_DAYTONA_SNAPSHOT are removed. Fleet ships its own snapshot definition and checks it before each Turn. GEPA approval evidence tied to the old configuration identity needs revalidation. See Snapshots.
  • Host calls follow the Turn deadline. Sandbox host calls wait for the remaining Turn deadline instead of a fixed 600 seconds. See Sandbox execution.
  • Advisory progress. Turns stream advisory progress and status labels, and record deadline, duration and snapshot provenance. See Stream events.
  • Better command menu. Terminal suggestions scroll through all matches, support keyboard, page-key and mouse selection, and keep unsent drafts in input history.
  • Turn streams always end. The Turn stream now ends and releases the Session lock even when the worker stops without a final outcome. The Turn route also returns 409 after 2 seconds when the Session is busy. See Session lock.
  • History without a live runtime. History and Turn status are served from PostgreSQL without a runtime lease. A Session that loses its lease is rebuilt. See Get history.

Week of October 19 — Fleet-RLM 0.8.0

Fleet-RLM 0.8.0 ships Fleet RLM Lite. The Fleet-RLM docs pages still describe 0.7.11 and will be updated for 0.8.0 separately.

New features

Fleet RLM Lite replaces the legacy application A rewritten Python application replaces the legacy multi-package backend and TypeScript terminal. It ships a Rich and Prompt Toolkit terminal client, a FastAPI HTTP/SSE API, and DSPy Turn orchestration that runs generated Python in Daytona. Legacy APIs, CLI commands, and configuration are replaced, not kept compatible. API routes drop the /api prefix, for example POST /sessions/{session_id}/turn. Lite keeps its data in separate database tables and doesn’t migrate data from the legacy application.Hybrid routing across direct, Flex, and RLM Sessions default to hybrid mode, where a router picks the direct, flex, or rlm route for each Turn. Switch modes with /mode hybrid, /mode rlm, or /mode flex. The direct / flex / rlm vocabulary replaces the old triage labels (direct_cot, single_rlm, delegated_rlm) in events, stored Turns, and fleet eval label --route. Re-optimize compiled programs tuned against the old labels.

Updates

  • One command for the API and MLflow. fleet cli starts the API server, a local MLflow server on port 5001, and the terminal client. Run fleet cli databricks to use Databricks managed MLflow instead. fleet serve, fleet optimize --session <id>, and fleet eval cover the server, GEPA optimization, and evaluation.
  • Schema 4 configuration. config/fleet.toml now sets schema_version = 4. Credentials and database URLs come only from the environment. Invalid configuration exits with a one-line fleet: error: invalid configuration: … message.
  • Evict a Session. DELETE /sessions/{session_id} stops the Session’s Sandbox, releases its lease, and drops its runtime while keeping history. It returns 404 when the Session has no runtime and 409 while a Turn runs.
  • Faster lock conflicts. Session routes that need the Session lock return 409 after 2 seconds instead of waiting for the running Turn.
  • Idle Sandboxes restart automatically. Fleet refreshes Sandbox state from Daytona before each Turn, so a Sandbox that auto-stopped while idle restarts instead of failing the Turn.
  • rlm.max_provider_attempts is removed. Configuration files that still set it fail with a migration message. DSPy owns provider retries.
  • Shared learned notes. Root Sandboxes mount shared/learned-notes at /learned. Fleet writes each committed Turn’s learned note there as an unreviewed, redacted file, and later Sessions see the newest summaries as hints to verify. Set FLEET_SHARED_NOTES_SUBPATH to an empty value to disable the mount.

Week of October 5 — Fleet-RLM 0.7.11

New features

Reorganized Fleet-RLM documentation The Fleet-RLM docs are rewritten from source and reorganized into Overview, Quickstart, Concepts, Guides, and Reference sections. Old URLs redirect to their new pages. Start at the Fleet RLM overview.

Updates

  • Turn timeout is the only wall-clock bound. Fleet’s role LMs are now stock dspy.LM instances, copied per Turn. Per-Turn LM deadlines are retired, so runtime.turn_timeout_seconds is the only wall-clock bound on a Turn. rlm.max_provider_attempts is still validated but no longer bounds provider spend. See Turn budgets.
  • DSPy owns provider retries. Provider retries use DSPy’s native num_retries with exponential backoff instead of Fleet’s immediate-retry loop. See Role settings.
  • Iteration-based wrap-up. The wrap-up directive now follows the RLM iteration count instead of a wall-clock reserve, and wrap_up_summary no longer reports wrap_up_remaining_ms.
  • Upstream upgrades. Fleet moves to Daytona 0.220.0, FastAPI 0.142.2, and PostHog 7.63.0, and handles Daytona’s Sandbox queue-timeout and spot-eviction errors explicitly. Fleet disables FastAPI’s native telemetry so observation stays Fleet-owned. See Observability.

Week of September 21 — Fleet-RLM 0.7.10

New features

Native DSPy 3.4 with async Daytona execution Fleet-RLM 0.7.10 runs the native DSPy RLM on DSPy 3.4.0 with Daytona’s direct asynchronous client and filesystem operations. Sessions keep their history and Workspace continuity across Daytona runs. Fleet exits at startup if another DSPy version is installed. See Fleet is certified on a different DSPy version.Bounded child work with partial results Recursive child execution stays bounded, reports progress, and preserves partial results when child work fails. See Recursive child RLMs and the child_progress event in Stream events.

Updates

  • More reliable Workspace tools. Workspace reads and tool outputs are bounded, and Daytona cleanup is stronger. See Sandbox tools.
  • Health probes use /health. Local health probes now call /health. See Health checks.

Week of September 14 — Fleet-RLM 0.7.7 to 0.7.9

New features

Trace feedback from the API and terminal Record a positive or negative assessment on a Session’s MLflow traces with POST /api/sessions/{session_id}/traces/feedback or the terminal’s /feedback command. Feedback goes through the public API without exposing provider secrets. See Record feedback.

Updates

  • Fresh program per Run. Fleet now builds a fresh DSPy program for every Run instead of keeping a resident Session runtime. Continuity across Turns comes from committed history, PostgreSQL, and the Workspace Volume, so don’t rely on Python variables between Turns. See Where state lives.
  • More accurate usage. SSE usage now includes delegation telemetry. Fleet fills in Turn token usage from LM histories when a provider omits totals, so usage covers llm_query and recursive child work. See Stream events.
  • Idle stop respects active Turns. Fleet no longer stops an idle Sandbox while a Turn still holds it. See Leases and admission.

Week of September 7 — Fleet-RLM

New features

Fail-soft PostHog product analytics Fleet-RLM adds optional product analytics controlled by the [posthog] policy section in config/fleet.toml. Analytics never block startup and stay disabled whenever the named token variable is absent. Every event shares one stable per-installation distinct_id, exception autocapture is off, and Fleet captures Turn failures only as sanitized failure messages. Events fire from the HTTP routes for session creation and updates, Turn creation and failure, artifact downloads, run cancellation requests, skill listing, and settings policy updates. Edit posthog.enabled, posthog.project_token_env, and posthog.host through the loopback /api/settings surface; changes apply after the next restart. See PostHog product analytics.

Updates

  • Live commands are now TOML policy. The new runtime.live_enabled key (default true) replaces the old FLEET_LIVE=1 shell switch for explicitly invoked provider, Daytona, and Prime Oolong commands. Set it to false in the selected policy to fail closed before those commands construct provider or Daytona clients. See Live commands.
  • Readable, bounded MLflow trace content. The mlflow.trace_content_mode setting is removed; fleet.toml files that still set it fail validation with an unknown-key error. Trace content is now always readable, with each field bounded by mlflow.trace_content_max_chars (default 10000). mlflow.async_logging keeps export off the Turn critical path and mlflow.trace_sampling_ratio (default 1.0) controls the fraction of Turns exported. The export boundary continues to protect credentials, connection strings, private paths, and system-prompt dumps. See MLflow policy.
  • Tightened Root action bounds with a wrap-up reserve. The shipped policy lowers the effective Root values to 12 iterations, 32 native LLM calls, and 6000 retained output characters per step. The generic DSPy fallbacks are 20, 50, and 10000, and child values remain 8, 12, and 4000. The new rlm.wrap_up_seconds reserve (default 300) directs the Root to submit its final answer instead of starting new actions when the remaining Turn time drops to the reserve. See RLM bounds and the wrap-up reserve.

Week of September 6 — Fleet-RLM

New features

Shared, atomic Turn budget Each Turn now owns one shared, atomic budget. Provider attempts, retries, adapter repairs, Tool calls, recursive children, retained execution output, and finalization all draw from the same allowance, so parallel children cannot double-count against it. When a Turn exhausts a budget dimension, Fleet stops admitting that kind of work and moves the Root toward finalization. Six policy keys control the budget, each with a committed default:
  • rlm.max_provider_attempts (2048) — Turn-wide ceiling on provider admissions, including retries and adapter repairs.
  • rlm.max_tool_calls (256) — Turn-wide ceiling on Fleet Tool calls.
  • rlm.max_execution_output_chars (4000) — character cap per retained interpreter output.
  • rlm.max_execution_output_bytes (2000000) — Turn-wide byte ceiling on retained interpreter output.
  • rlm.execution_timeout_s (300) — timeout for a single sandbox execution.
  • rlm.finalization_attempts (2) — provider attempts reserved for the Root final answer.
See Turn budget.

Updates

  • Runtime variant selector. The new runtime.variant policy key selects the execution architecture. legacy is the default and only implemented value; Fleet rejects unsupported values at startup, and policies that omit the key keep the legacy behavior. runtime.environment still selects the provider environment independently. See Runtime variant.
  • Public contracts unchanged. HTTP routes, the SSE vocabulary, and Tool contracts are identical, so existing clients need no changes.

Week of September 4 — Fleet-RLM

New features

Published security model Fleet-RLM’s security model is now a formal, public reference. It covers the threat model and the guarantees you can rely on:
  • Loopback-only binds by default. Non-loopback binds require an explicit --allow-non-loopback-bind.
  • Sanitized public API errors that never leak exception text or credentials.
  • A 10 MiB attachment cap with strict filename and Workspace path validation.
  • Optional expected_sha256 preconditions that guard writes, edits, and deletes against clobbering changed content.
  • Layered SSRF defenses on URL fetches: globally routable addresses only, a 3-redirect cap, a 10-second timeout, and byte caps.
  • Skill guardrails. Skills can never register executable Tools.
All model-generated code runs inside a Daytona Sandbox, never on the host. Report vulnerabilities to contact@qredence.ai. See Security model.Glossary of core terms A new glossary defines the state and execution vocabulary used across Fleet-RLM, including Session, Turn, Run, Claim, Checkpoint, Runtime Event, Interpreter Lease, Skill Card, Workspace Memory, and Taint. API responses, SSE events, and docs pages now share one vocabulary. See Glossary.

Week of August 29 — Fleet-RLM 0.7.5

New features

Session-scoped resident RLM runtime A healthy Session now reuses one native dspy.RLM, one caller-owned interpreter, and one Root Sandbox across sequential clean Turns, so ordinary Python variables persist between Turns. Failed, cancelled, timed-out, or otherwise uncertain Turns taint the runtime; before the next Turn Fleet rotates to a fresh interpreter and Sandbox and rehydrates only durable state. See Daytona runtime and Sessions and persistence.Durable Session History via dspy.History Every Root Turn now receives the full committed Session conversation as a dspy.History input field on the Signature, one {"request": ..., "answer": ...} record per committed Turn. The bounded previews and the read_session_history Tool remain as compatible surfaces. See DSPy integration.Isolated native child RLMs with immutable Session snapshots Each delegated native child receives the delegated prompt, the current request, a committed History snapshot, bounded Session context, and the forked Root/Sub model policy, plus its own fresh RLM, interpreter, and Sandbox. Children never observe the live Root interpreter. See Recursive RLM.

Updates

  • Public contracts preserved. HTTP routes, OpenAPI, SSE vocabulary and ordering, Tool contracts, configuration keys, database schema, and CLI behavior are unchanged in 0.7.5.
  • Faster first Turns via session Sandbox pre-warm. POST /api/sessions now schedules a best-effort background pre-warm that acquires a Root Sandbox, applies the canonical Volume layout, and persists the binding. The first Turn reuses the bound Sandbox, dropping the first-Turn sandbox path from ~8-10s to ~2s. Pre-warm is transparent: a Turn racing the pre-warm waits it out or makes it yield, and a failed pre-warm falls back to normal acquisition. See Daytona runtime.
  • Parallel Volume layout. Canonical Volume directory creation now runs depth-level batches concurrently, cutting the layout phase by 31% at p50 and 59% at p95. Cold paths that don’t benefit from pre-warm, such as recursive child Sandboxes, get the same tail reduction.
  • Daytona SDK bumped to ==0.207.0. Every SDK surface Fleet uses is unchanged or additive-only, so Sandbox behavior is identical. The SDK’s new warm pools are not adopted: Fleet mounts a workspace-scoped volume on every production Sandbox create, which the pool contract excludes.
  • Dependency lock refreshed. About 60 transitive packages move to their newest releases within declared ranges. Certified pins (dspy==3.3.1, fastapi==0.141.1, gepa==0.1.4) are unchanged, and the unused httpx2 dependency is removed.

Week of August 25 — Fleet-RLM 0.7.4

Updates

  • Certified DSPy runtime: exactly dspy==3.3.1. Fleet now pins the published dspy==3.3.1 release and fails closed before any provider, database, or Daytona resource is constructed when any other version is installed, including neighboring patches, prereleases, and local builds. --help stays reachable on any runtime. The official gepa==0.1.4 optimizer contracts back the bounded development smoke path; production optimization remains fail-closed. See DSPy integration.
  • One accountable owner per Turn. Turn ownership is collapsed into TurnCoordinator under one explicit ownership-deletion contract, and recursive child lease and cleanup contract to a single Daytona owner with a fenced child deadline. Cancelled children can no longer orphan Sandboxes.
  • Certification gates on real credentials and shipped artifacts. Live credentialed certification lanes exercise the certified composition against real provider credentials, release certification binds to the built wheel/sdist artifact identity, and behavior-freeze gates lock recursive delegation, stream settlement, and operator evidence retention against certified behavior.

Fixes

  • Hardened volume and artifact integrity lanes, closed an unawaited staging cleanup coroutine on supervisor-saturation fallback, and hardened recovery cancellation so failure paths settle without leaked tasks or files.

Week of August 15 — Fleet-RLM 0.7.0

New features

Policy-controlled MLflow tracing across profiles Fleet now wires MLflow tracing directly from config/fleet.toml policy: managed profiles export to a Databricks destination, and interactive profiles export to the supervised local MLflow server that fleet cli runs on 127.0.0.1:5001. At app boot the runtime applies set_tracking_uri, set_experiment, and mlflow.dspy.autolog() from the resolved policy, then opens a fail-soft fleet_turn root span on every live Turn. Managed profiles read FLEET_MLFLOW_EXPERIMENT_NAME, FLEET_MLFLOW_TRACE_CATALOG, FLEET_MLFLOW_TRACE_SCHEMA, FLEET_MLFLOW_TRACE_TABLE_PREFIX, and FLEET_MLFLOW_TRACING_SQL_WAREHOUSE_ID; benchmark profiles keep tracing off. See Observability and Configuration reference.Operator-facing traceId on Turns Live Turns now carry a traceId on the existing SSE messageMetadata, on TUI run status, and on durable assistant UI metadata, so operators can jump from a Turn straight to its DSPy trace without new SSE chunk types or Turn-path coupling. Export remains fail-soft — a broken tracing destination never fails a Turn.

Updates

  • DSPy pinned to 3.3.0. The native Fleet RLM integration is migrated from 3.3.0b1 to the final DSPy 3.3.0 release, preserving max_iterations while adapting to DSPy’s finalized construction and caller-owned interpreter contract. Native Turns, live per-iteration observation, recursive children, and deterministic test composition retain their event and cleanup behavior. Fleet no longer projects a second token-level dspy.streamify protocol. See DSPy integration.
  • fastapi[standard] bumped to ==0.141.1. Takes the 0.140.x dependency-solver memory refactors and SSE/streaming endpoint fixes. Schema generation is byte-identical for the routed API surface, so openapi.yaml and the pi-tui generated types are unchanged.
  • Daytona SDK bumped to ==0.202.0. Picks up the Daytona event-subscription expiry-worker fix and the 0.201.0/0.202.0 SDK additions with no code changes. httpx2 is re-locked at 2.9.1.
  • Provider/profile matrix aligned with config/fleet.toml. Interactive profiles (daytona, daytona-recursive) use OpenCode Go with 16,000-token roles; managed and benchmark profiles use the Databricks AI Gateway with 8,000-token roles. The profile matrix and .env.example resolve credentials from the selected policy instead of assuming one provider.
  • Bounded no-progress repair in the Daytona interpreter. A repeated identical interpreter action that makes no progress now returns one bounded repair message (“Repeated interpreter action produced no progress…”) instead of terminating the Turn immediately. Only a second consecutive identical repeat raises RunNoProgressError. Empty and oversized intermediate code keep their direct repair messages, and any different action resets the counter. Models gain one bounded recovery step on repetitive loops before the Turn is stopped.
  • Required pi-tui install step. uv sync does not install the terminal client’s Node dependencies. Run pnpm --dir tools/fleet-tui install --frozen-lockfile before fleet cli. See Install fleet-rlm.

Week of May 12 – May 19

New features

Fleet-RLM 0.5.3 — backend-driven runtime settings The Settings page now renders typed runtime options and diagnostics directly from backend descriptors, so available configuration always matches what the server actually supports. See Configuration reference.Fleet-RLM — “About this instance” panel A new Settings panel surfaces the running service version, environment, and feature flags so you can confirm exactly what’s deployed before filing an issue. Powered by the new /api/v1/info endpoint in the HTTP API reference.Fleet-RLM — MLflow observability and auto-assessment MLflow span processors now emit richer trace metadata, and you can wire scorer schedules to run automated assessment loops over completed sessions. See Observability.

Updates

  • Session titles auto-derive from the first user message when no title is set, so conversations get human-readable labels without manual renaming. (fleet-rlm)
  • Workbench UI polish — refined sidepanel controls, event display, and composer prompt overhead for a cleaner workspace.
  • Runtime stack alignment — Fleet-RLM is now tested and published against Daytona 0.176, DSPy 3.2.1, Pydantic 2.13.4, SQLModel 0.0.38, Psycopg 3.3.4, Typer 0.25.1, and Uvicorn 0.47.0. Update your environment to match — see Installation.
  • Fleet-RLM 0.5.31 patch release with a synced OpenAPI schema for frontend and SDK consumers.

Bug fixes

  • History page restored. Conversation titles and transcript replay now show correctly when the durable session store only contains placeholder rows — the History view falls back to local conversation history instead of rendering opaque IDs.
  • Resilient analytics initialization. PostHog callback registration no longer fails in threaded environments; it retries under a settings lock when needed.
  • Hardened recursive delegation. Remote document context, degraded child execution metadata, and chunk-document aliases are handled more defensively, so partial failures surface clearly instead of returning stale evidence. See Recursive RLM.
  • Frontend dependency security patches applied to address Dependabot alerts.

Week of June 29 — Fleet-RLM 0.6.2

New features

Bring-your-own-key (BYOK) LLM provider profiles Hosted deployments running AUTH_MODE=neon can now bind their own planner and delegate LLM credentials per tenant/user. API keys are encrypted at rest with Fernet under FLEET_SECRET_ENCRYPTION_KEY, and responses only ever return has_api_key plus a masked preview — plaintext keys never cross the API surface, and the runtime does not mutate the process environment to route requests. See Configuration and HTTP API — LLM provider profiles.Per-workspace encrypted Daytona credentials PATCH /api/v1/runtime/settings under AUTH_MODE=neon now persists each workspace’s DAYTONA_* keys as encrypted workspace_runtime_settings ciphertext instead of returning 403 forbidden. Chat and runtime paths resolve the per-user Daytona config first and fall back to the server-level env only if none is set. Non-Daytona keys remain local-only. See HTTP API reference.LiteLLM custom-provider opt-in hint Two new environment variables — DSPY_LM_CUSTOM_PROVIDER and DSPY_DELEGATE_LM_CUSTOM_PROVIDER — let OpenAI-compatible bare-model endpoints pass an explicit custom_llm_provider hint to LiteLLM. The runtime no longer force-sets custom_llm_provider="openai" for every bare model with an api_base, so Anthropic and other non-OpenAI providers stop receiving OpenAI-format requests. See Configuration.PATCH /api/v1/runtime/settings reports skipped keys Responses now include a skipped field listing masked-round-trip keys that were intentionally not persisted, so clients can distinguish updated keys from ignored no-op saves.

Updates

  • FastAPI pinned to ==0.139.0. Installs are reproducible on the current validated FastAPI release instead of floating forward against a >=0.138.2 floor.
  • litellm policy hardened. LiteLLM is installed only as DSPy’s transitive dependency; [tool.uv].override-dependencies still pins litellm>=1.87.0 to close 7 documented CVEs. A parse-time invariant test fails if litellm is ever re-added to direct deps or removed from the override pin.
  • Neon multi-tenant migrations. llm_role_bindings is now UUID-PK’d and scoped by tenant_id / user_id / workspace_id; the workspace_runtime_settings unique constraint is tightened to (tenant_id, workspace_id) so the settings upsert is tenant-aware.
  • README rewritten around the actual routed surfaces (/app/workspace, /app/optimization, /app/volumes, /app/settings) and the current make / pnpm validation lanes.

Bug fixes

  • Legacy XOR-encrypted profile ciphertext keeps decrypting. After rotation, the runtime tries FLEET_SECRET_ENCRYPTION_KEY, DEV_JWT_SECRET, and change-me in turn until a stored row decrypts — old rows are no longer bricked by rotating in a real Fernet key.
  • No cross-tenant BYOK leak from the connectivity probe. POST /runtime/tests/lm no longer mutates the shared LmDeps.planner_lm singleton; the per-user planner is invoked directly, so a smoke test can never swap another user’s in-flight chat onto a foreign BYOK LM.
  • Decrypt failures are observable. GET /api/v1/runtime/settings logs when a stored DAYTONA_API_KEY fails to decrypt (without leaking the value), and the PATCH path treats an empty incoming value for a key with an existing stored credential as a no-op — a failed GET can no longer enable an empty save that wipes the stored key.

Week of June 17 — Fleet-RLM 0.6.0

New features

Workbench sidepanel with Trajectories, Graph, and Volume tabs A workspace-local collapsible sidepanel now sits alongside the chat. Trajectories renders the session trace timeline, Graph renders a React Flow parent/child span view backed by persisted MLflow/debug spans, and Volume embeds a searchable Daytona volume tree with resizable desktop split and inline file preview. Chat stays the primary surface; the sidepanel starts closed and can resize up to 75% of the workspace width. See Concepts — Observability.Per-trace performance summaries The session trace debug contract now carries span durations, token counts, output sizes, selected-skill metadata, and adapter fallback signals per trace. The sidepanel can diagnose slow or noisy RLM runs directly from the same durable trace lookup used by the timeline and graph.Active skill injection into the sandbox Selected scaffold-skill markdown is injected as a sandbox variable for RLM turns, document turns, and workspace turns — the REPL sees the skill without stuffing full instructions into every model prompt.Bounded RLM action-generation token budget Operators can cap the action-prompt token budget separately from REPL output truncation. The effective budget is exposed in runtime settings metadata and attributed on every trace so slow turns can be traced back to their action-generation configuration.

Updates

  • GEPA is now the only supported public optimizer. MIPROv2 was removed from the unified optimization pipeline. CLI, API, manifests, and the Optimization UI all target one optimizer contract. See the CLI reference.
  • Unified RuntimeEvent streaming. Runtime, persistence, and Web UI consumers now share one typed streaming contract for execution start, step, and completion frames — the public Workbench frame shapes are unchanged.
  • Hardened session trace lookup. Trajectories and Graph now populate from live session traces after a message completes, even before the frontend has a durable session id — trace lookup resolves both durable chat-session ids and runtime websocket external_session_id values.
  • Frontend feature-module reorganization. Feature entrypoints are now the public boundary; routes and layout consume stable feature contracts and import-boundary linting blocks deep coupling. shadcn-style primitives were migrated from Radix wrappers to Base UI primitives while preserving the existing button, tooltip, popover, dialog, menu, scroll-area, and toggle contracts.
  • Compact local chat-history persistence. Local storage now stores session previews and durable session ids instead of full rendered transcripts, so quota failures never break chat saves.
  • RLM action generation compacted. Long REPL histories are compacted before action generation and driven through JSONAdapter, so long-running sessions spend fewer tokens on prior tool output and avoid avoidable chat-adapter fallback retries.

Removed

  • MIPROv2 public optimizer surface. Review bundles, CLI flags, and API requests no longer advertise a second optimizer.
  • Retired Tool UI helpers. Option-list and shared action helpers were removed after Agent Elements became the canonical tool-rendering path.

Notes

  • GET /api/v1/optimization/runs/compare remains API-ready; the Compare tab UI is deferred to v1.1.

Week of June 11 — Fleet-RLM 0.5.50

New features

MIPROv2 as an optional offline optimizer The unified offline optimization pipeline now accepts MIPROv2 alongside the default GEPA backend. Pass --optimizer miprov2 to fleet-rlm optimize, or send "optimizer": "miprov2" in the body of POST /api/v1/optimization/runs. CLI, API, MLflow run metadata, and review bundles share the same runner, so existing GEPA tooling keeps working unchanged. See the DSPy integration guide and the CLI reference.Native dspy.RLM large-input support Large documents and workspace context now ship to the sandbox through DSPy’s upstream SandboxSerializable contract. Use LargeDocument or WorkspaceContext from fleet_rlm.runtime.sandbox_types on a signature input field, and dspy.RLM injects the payload into the REPL as a native Python dict while the LM only sees a short preview. Custom signatures that previously relied on Fleet-maintained variable-mode wrappers should switch to these types. See DSPy integration.

Updates

  • DSPy pinned to 3.3.0b1. Fleet now depends on the upstream DSPy RLM and SandboxSerializable contracts directly; the local DSPy monkeypatch modules have been removed. Programs that build modules through fleet_rlm.runtime.modules keep working without changes.
  • Unified dspy.streamify chat streaming. Direct, tool-using, and recursive RLM turns now share one WebSocket replay path with response-first DSPy signatures. The public Workbench WebSocket frame shapes are unchanged — existing clients require no updates. See Observability — WebSocket execution events.
  • Centralized DSPy observability callback registration. MLflow and PostHog callbacks are now registered once through a shared registry that stays lazy, deduplicated, and visible to worker-thread DSPy contexts. Optional observability stays optional — no configuration changes are required.

Removed

  • Variable-mode wrappers and local DSPy patch modules. Retired together with archived optimization/history frontend clients and legacy bare WebSocket frame parsing. The supported surface is the generated OpenAPI client and the canonical WebSocket event envelope.

Week of May 23 — Fleet-RLM 0.5.40

New features

Canonical API error envelope across all HTTP and WebSocket routes Every error response on /api/v1/* now returns the same { code, message, detail } JSON shape, including FastAPI validation errors and unknown-route 404s served by Starlette. Branch on the stable code field instead of parsing message. See HTTP and WebSocket API.Volume access security boundaries GET /api/v1/runtime/volume/tree and /api/v1/runtime/volume/file now enforce explicit canonical roots and return 403 forbidden for paths outside them. The tree endpoint accepts a new max_entries parameter (default 200, max 1000) and reports max_depth, max_entries, and entries_returned so clients can tell when a listing was clipped. File previews include sha256, encoding (utf-8, utf-8-lossy, or binary), and a binary flag so you can deduplicate or short-circuit on non-text files. See Volume access boundaries.Offline-only DSPy module flag GET /api/v1/optimization/modules entries now carry an offline_only field (default true) so optimization UIs know which modules can only be tuned through the offline endpoints, not from live traffic.

Updates

  • Health probe shape clarified. GET /health now returns status: "live" instead of ok: true. The legacy ok field has been removed. (HTTP API reference)
  • Readiness 503 carries component state. GET /ready now returns the same ReadyResponse body on 503, so monitoring probes can read which component is missing or degraded from a failing response. The redundant planner_configured field was removed — read planner instead.
  • Sandbox environment variables are redacted. The env_vars field on sandbox responses no longer surfaces raw secret values.
  • Recursive RLM delegation, DSPy signatures, and streaming contracts redesigned around clearer service boundaries while preserving the public Workbench WebSocket frame shapes.
  • Daytona VFS and evidence substrate redesigned with explicit security boundaries between child workspaces, mounted volumes, and evidence staging. See Daytona runtime.
  • CLI now emits structured errors matching the canonical API envelope. See the CLI reference.

Removed

  • Memory API retired. /api/v1/memory* is no longer part of the supported HTTP surface. Memory item browsing has been removed from the API navigation and OpenAPI schema. Clients that depended on listing memory items should migrate to the session endpoints under /api/v1/sessions/*.

Week of May 20

Updates

Fleet-RLM — decoupled WebSocket streaming runtime Turn execution no longer runs inline with the WebSocket handler. Each user message is processed in a background task that builds its own agent context and publishes execution events through a shared event emitter. The same emitter fans out frames to every subscriber on /api/v1/ws/execution and /api/v1/ws/execution/events, so a dropped or reconnected client no longer cancels the turn. No client changes are required — frame shapes are unchanged. See Observability and HTTP and WebSocket API.Fleet-RLM — Entra JWKS cache and joserfc token validation AUTH_MODE=entra now uses joserfc instead of PyJWT for token verification and ships with a built-in JWKS cache (5-minute TTL) that falls back to the last-known keyset if Entra’s JWKS endpoint is unreachable. Bearer-token validation, tid/aud/iss enforcement, and tenant admission behavior are unchanged. See Deployment.

Bug fixes

  • Final assistant text no longer duplicated in replay. The terminal trajectory step now omits the planner’s intermediate thought, so reopening a session replays the assistant’s final response once instead of twice. (Sessions and persistence)
  • Frontend WebSocket parser prefers step.output for final frames. Execution-step envelopes with kind: "final" now surface the actual response text instead of the internal label.
Last modified on November 10, 2026