Skip to content
All releases
CHANGELOG

v0.3.0-beta.22

Cancel is now the single way to stop a Loop run, and it stops the run's own sessions instead of asking politely. Runtime selection reads live provider catalogs, so the models you pick match what the provider offers.…

BETAFeatures · 2Bug Fixes · 9

This beta makes Loop cancellation forceful and removes Kill, rebuilds runtime selection on live provider catalogs, and lets a parent Loop reconfigure one child run. It also restores prompting for managed sessions and closes regressions across extensions, worktrees, Profiles, fan-out rosters, and conversation clear.

🎉 Features

  • Rebuild ACP runtime catalogs (#498)
  • Support child Loop config overrides (#494)

🐛 Bug Fixes

  • Allow extension loops to call owned tools (#503)
  • Honor selected orchestrated implementer (#502)
  • Externalize oversized loop action results (#510)
  • Force loop cancellation (#509)
  • Enable prompts for managed sessions (#517)
  • Preserve sparse fan-out roster rows (#518)
  • Scope Loop extension tools to worktrees (#519)
  • Preserve profile-scoped extension Agent skills (#516)
  • Prevent session cancel and clear races (#523)

Release Notes

Cancel is now the single way to stop a Loop run, and it stops the run's own sessions instead of asking politely. Runtime selection reads live provider catalogs, so the models you pick match what the provider offers. Managed sessions accept prompts again, and Loop work stays inside the extension, Profile, and worktree it was scoped to.

Breaking Changes

Cancel now stops a Loop run for real, and public Kill operations are gone

Loop cancellation commits the terminal state before cleanup and stops every session that run owns, so a canceled run leaves nothing alive. Because cancel is now forceful, the separate Kill operation is removed from every public surface. (#509)

  • Removed CLI commands: compozy loop kill and compozy loop node kill.
  • Removed HTTP and UDS routes: POST /workspaces/{workspace_id}/loop-runs/{run_id}/kill and POST /workspaces/{workspace_id}/loop-runs/{run_id}/nodes/{node_id}/kill.
  • Removed native tools: compozy__loop_kill and compozy__loop_node_kill.
  • Public run transition and event vocabulary now exposes only cancellation. Stored node_killed events are projected as canceled.
  • Authored Loop DSL now accepts on_parent_close: terminate or abandon. Stored cancel values are normalized to terminate.
  • compozy__loop_cancel and compozy__loop_node_cancel — and their CLI, HTTP, UDS, and Web equivalents — now terminalize immediately instead of requesting cooperative cancellation.
  • Sessions the run only borrowed are left running, workspace isolation is preserved, and a cleanup that fails is retried durably.

Callers still using a Kill route, command, or tool must move to the matching cancel surface; there is no public alias.

Features

Runtime selection reads live model catalogs

Model discovery and runtime configuration are rebuilt around logical model identities and live provider catalogs, so what you pick in CompozyOS matches what the provider actually offers. (#498)

  • Authored model IDs are separate from the transport aliases a provider expects, so a Loop or Agent keeps working when a provider renames its wire identifier.
  • Catalogs are discovered and stored with a five-minute freshness window, refreshed on a timer and on read, and fall back to the last successful result when a provider is unreachable.
  • Cursor launch aliases resolve before the process starts, including the Grok 4.5 and 4.6 Reasoning and Fast combinations. Opus 5 is visible offline while live discovery stays authoritative.
  • Hermes is treated as a discoverable ACP agent with handshake readiness diagnostics. OpenClaw stays described as a provider-managed bridge instead of showing model, Reasoning, or Fast controls it does not have.
  • Curated models can declare default_speed; live models outside the curated fallback are admitted, and selected model and Fast settings survive inheritance and restart projection.
  • Speed and typed acp_options are available on Agent definitions, session and prompt overrides, roles, Loops, Tasks, the CLI, HTTP, UDS, native tools, extension contracts, OpenAPI, and the SDKs. The shared Runtime Selector is wired into Agent, session, role, Loop, Task, and onboarding surfaces.
  • The New Session dialog no longer carries a first-message box. Create the session, then send the first prompt from the composer. This was a Web-only field; no API payload changed.

This ships database migrations 00093 through 00097 and regenerated contract output.

A parent Loop can reconfigure one child run

The reserved run-loop action accepts an optional params.config_overrides object, so a parent Loop can give one child run its own iteration limits, budgets, environment, reattempt behavior, and runtime selection without touching the child's stored configuration. (#494)

  • Works with both await and detach.
  • Exact node-output references stay typed, and unknown literal fields are rejected before the child starts.
  • Override values can be filled from templates.
  • The override set is closed and excludes operator-owned lifecycle and request-expiry policy.
  • The Loop editor exposes the overrides as JSON, and malformed JSON, unknown settings, wrong types, or trailing data block the run instead of failing mid-flight.
  • If Goal binding fails while a run is starting, the task run is terminalized instead of staying live.

Large Loop action results survive instead of breaking the run

A Loop action can now return a payload larger than the task-run envelope without losing coordinator restart safety. Results up to 16 KiB stay inline; anything larger is stored in the existing Loop blob store and read back byte for byte through a workspace-authorized paging resource. A result above the action budget fails with the typed action_result_too_large error before the task completes, so the lease is released instead of the run stalling. (#510)

  • Adds compozy task run result, task-run result paging over HTTP and UDS, the Host API tasks/runs/result resource, and the compozy__task_run_result native tool.
  • compozy__tool_list now returns deterministic pages so the global tool-result limit stays enforceable; compozy__tool_info still returns full descriptors.
  • The Task UI shows and copies bounded results.
  • Spec-cycle Task fan-out is a hard cut from embedded bodies to path plus body_ref.

No config.toml key was added or removed — the existing tool-result budget remains the source of truth.

Fixes

App status asks the app instead of guessing from the process

compozy app status and compozy app open decided whether the desktop app was running by matching a recorded process ID and its start timestamp. When that timestamp comparison did not line up, a perfectly healthy app was reported as not running, and app open refused to reuse it. Both commands now probe the app's own control socket and take its answer. (#494)

  • A control channel that reports not running, or is unavailable, still resolves to "not running" instead of failing the command.
  • Any other probe failure is surfaced as an error rather than silently read as a stopped app.

An extension Loop can call the tools its own extension ships

A code-backed extension can contribute both Loops and tools, but the external-source policy stopped a contributed Loop from resolving a tool owned by that same extension, so the action failed with unknown_action_kind. The manifest owner is now preserved through resource loading, compilation, executed snapshots, and hydration, and execution adds exactly that same-owner extension source to the normal allow set. (#503)

  • Trusted-source status is never granted, and tools from other extensions stay denied.
  • Loop schema compilation snapshots the operator registry once per compilation instead of reprojecting it repeatedly.
  • Extension installation and enablement retry transient SQLITE_BUSY conflicts, and lifecycle tokens prevent stale cleanup from disabling a replacement installation.

Loop extension tools run in the worktree the Loop selected

Extension tools invoked from a Loop now resolve against the selected ready worktree instead of the workspace root, so work stays where the run was pointed. Direct and root-scoped calls are unchanged. (#519)

  • Web Loop environment authoring is limited to inherit, workspace root, and a named worktree; directory and per-run values set through the API or CLI remain visible and read-only.
  • A worktree is resolved by workspace ID and worktree ref and must be ready before it is used.
  • Removing a worktree now takes an exclusive usage lease, so compozy worktree remove and the matching delete route report that an operation is in progress while a Loop action is holding that worktree, instead of pulling it out from under the run.

You can talk to managed sessions again

The Web composer now follows prompt authority instead of lifecycle ownership, so eligible user, system, coordinator, and spawned sessions can all be prompted while active or stopped. An eligible stopped session resumes under the same durable session ID and transcript. (#517)

  • The composer's stop control now cancels the current turn instead of stopping the whole session, so you can interrupt one answer and keep going.
  • Managed sessions still cannot be renamed, cleared, attached, archived, deleted, or stopped as a whole.
  • Dream, maintenance, archived, transitional, and unrecoverable sessions stay read-only.
  • Session lifecycle docs and the official CompozyOS skill describe the new prompt boundary.

Orchestrated task delivery uses the implementer you picked

implement-tasks running in mode=orchestrated replaced your selected implementer Agent with code_implementer. The typed Agent input now flows through the orchestrated objective, the conductor skill, and compozy spawn, so every worker runs as the Agent you chose and keeps its identity, Agent-local Skills, permissions, provider defaults, and category runtime overrides. (#502)

  • code_implementer is still the default, so omitting the input behaves as before.
  • A recovered session whose Agent does not match fails closed instead of being adopted silently.
  • Settlement still requires completed Task frontmatter and zero live workers created by the conductor.

Profile-scoped extension Agents keep their own Skills

An extension Agent scoped to one Profile leaked into default, and Agent-local Skill lookup could read the wrong Agent definition. CompozyOS now publishes the already-projected Agent set and resolves Agent-scoped Skill queries through the selected global, Profile, or Workspace lens, passing the concrete Agent definition to the Skill registry. (#516)

  • Two Agents with the same name in different Profiles stay isolated, and skill list|where|view --for-agent returns each one's own Skill body.
  • Profile-only scope keeps both the Profile ID and the Profile name.
  • No command, flag, route, or payload shape changed — existing reads simply return the correctly scoped resources.

Canceling a prompt and clearing a conversation no longer collide

Two timing failures met in the same flow — cancel an active prompt, clear the conversation, keep using the session. Both are fixed. (#523)

  • A late prompt cancel could cancel the next turn. Prompt cancellation now owns only the active request and becomes a no-op once that prompt has settled; the whole-session session/cancel is sent exactly once, and only by Stop.
  • Because of that, an ACP agent process no longer receives a session/cancel notification when a single prompt is canceled — only the SDK's request-scoped $/cancel_request. An agent that aborted a turn by listening for session/cancel must handle the request-scoped cancellation instead.
  • A transcript read could land inside the conversation-clear replacement window, report session not found, and drive the clear endpoint to HTTP 500. The finalization barrier is now published as soon as the conversation-operation lock is taken and held through stop, backup, database replacement, and restart, so readers wait for the clear instead of seeing a session that appears to be missing.

A fan-out roster shows only the workers that exist

Fan-out roster projection treated the highest stored item index as a contiguous range, so a run holding only item 2, or items 2 and 5, invented rows for the missing indexes and left them pending forever. Roster rows, rollups, and run progress now project the exact stored item indexes. (#518)

  • Response shapes and routes are unchanged across CLI, HTTP, UDS, compozy__loop_runs, and Web; the same reads now return correct results.
  • The Loop running guide and the official CompozyOS skill document sparse-index behavior, and clarify that not_taken requires durable route evidence.

Compare v0.3.0-beta.21...v0.3.0-beta.22

Contributors
Release assets

30 files published by the GitHub release workflow.

Browse downloads