github nicobailon/pi-subagents v0.75.0

5 hours ago

pi-subagents 0.75.0 makes background subagents work on Pi 1.0.0 again. If async children stopped starting after you upgraded Pi, this release fixes that without any change on your side. Claude Code children can now use a specific Claude model and effort level per launch, and npm-installed external CLIs launch on Windows. Children on model routers and other virtual models now start and pass model verification, and a mistake in your config no longer silently turns off your permission or tool limits.

Highlights

  • Background subagents on Pi 1.0.0. Async children start again instead of failing with "does not provide @earendil-works/pi-agent-core/node".
  • Pick the Claude model per launch. claude-code and claude-code-writer accept a model and effort, for example model: "claude-opus-5.5:high", within your maxThinking and modelScope limits.
  • npm CLIs on Windows. claude-code, codex-exec, and cursor-agent launch CLIs that npm installed as .cmd files, still without a shell.
  • Virtual models work for children. Children on a model router or another extension-registered virtual model launch and pass verification.
  • Safer config loading. An invalid config value no longer drops authorityPolicy, permissions, or toolBudget. Loading fails instead, so nothing runs with weaker limits than you set.

Changelog

Highlights

  • Background subagents work on Pi 1.0.0 again. In 0.74.0 they failed to start with "does not provide @earendil-works/pi-agent-core/node".
  • The built-in claude-code and claude-code-writer agents can pick a Claude model and effort level per launch, for example model: "claude-opus-5.5:high".
  • On Windows, claude-code, codex-exec, and cursor-agent can now launch CLIs installed with npm.
  • Children on a virtual model from an extension, such as a model router set as subagents.defaultModel, now launch and pass model verification.
  • An invalid config value no longer silently turns off authorityPolicy, permissions, or toolBudget. Loading the config fails instead.

Added

  • The built-in claude-code and claude-code-writer agents accept a model and thinking level per launch or in agent frontmatter, and pass them to Claude Code as --model and --effort. Before, the model could only be set in your global Claude Code settings. model: "claude-opus-5.5:high" sets both; model: ":high" sets only the effort. An unknown model or level fails the launch and names it. subagents.maxThinking and an enforced subagents.modelScope apply to these launches; with an enforced scope, a launch that sets no model fails, because Claude Code's default model cannot be checked. Other external runners still reject both fields. See agents. Thanks to @lexxbyte for #2602.
  • The parent can now manage a long bash command inside a native Pi child that is granted both bash and subagent_command: command.status shows it, command.yield lets the child continue while the command keeps running, and command.cancel stops only that command. The child can do the same itself with bash's yieldTimeMs and the subagent_command tool. Commands use Pi's own shell and are stopped when the child exits, and a child that finishes with a command still running fails. Thanks to @jiuai233 for #2598.
  • Hosts that require child extensions with registerRequiredChildExtensions can pass requireForAllRunners: true. Only local Pi children can load those extensions, so with this flag a launch on an external CLI, an external job, or another machine is refused before it starts instead of running without them. The requirement stays with the run, including nested, resumed, and workflow children, even after the host removes its registration. Without the flag, external runners are skipped as before. See agents. Thanks to @doc-krieger for #2639.
  • schedule.create accepts an existing missionId, so a scheduled workflow keeps the same mission state across runs and session restarts. Schedules with a mission are saved in a new format that older pi-subagents versions reject instead of silently dropping the mission; other schedules keep the old format. Thanks to @quifox for #2616.
  • asyncWidgetCollapsed: true starts the async widget under the editor folded to one line. Clicking its header still unfolds it, and the default is unchanged. Thanks to @unrelentingfox for #2621.

Changed

  • CI now runs the clean-install test against both Pi 0.86.1 and 1.0.0, as separate jobs with separate logs. Thanks to @EightDoor for #2648.

Fixed

  • Background subagents failed to start on Pi 1.0.0 with "does not provide @earendil-works/pi-agent-core/node", because Pi 1.0.0 no longer ships that module. They now start without it, and still fail if Pi includes the module but the file is missing. Thanks to @albertgwo for #2634.
  • An invalid value for any config key no longer silently drops authorityPolicy, permissions, or toolBudget. If the config file sets any of them, loading now fails instead of continuing with an empty config that would allow what those settings forbid. (#2622)
  • A required child extension (registerRequiredChildExtensions) that throws during session_start now stops the launch. Before, Pi only reported the error, so the child still started and could send model requests without the policy the extension was meant to set up. Ordinary extensions are unchanged: their startup errors are reported and the child still starts. Thanks to @doc-krieger for reporting #2639.
  • On Windows, external-CLI agents such as claude-code, codex-exec, and cursor-agent failed with EINVAL when the CLI was installed with npm, because npm installs it as a .cmd file that Node cannot start without a shell. The runner now runs the CLI's script with Node directly, still without a shell, and refuses any other .cmd or .bat file. Thanks to @lexxbyte for tracing the cause in #2631.
  • A child could not launch on a virtual model that an extension registers with pi.registerVirtualModel(), such as a router set as subagents.defaultModel. The child looked up its model before the extension's virtual models were registered, so the name matched a model on another provider and the launch failed on that provider's missing API key. Virtual models are now registered first, and a required extension whose registration fails stops the launch. Thanks to @mauroziux for #2636 (#2635).
  • A child on a virtual model failed with model_verification_failed even when it ran correctly, because the check compared the launch model with the real model the router picked. For virtual models, the check now compares the child's selected model with the launch model. Other children are checked as before. Thanks to @mauroziux for reporting #2637 (#2635).
  • A background chain whose expand step runs an external-CLI agent such as claude-code failed with "Dynamic chain step N parallel does not support field 'runner'". Each item now runs through that agent's runner, and its output is collected like any parallel child. Thanks to @lexxbyte for reporting #2629.
  • Saving builtin agent overrides no longer risks a half-written settings file: if the save is interrupted, the previous settings stay readable. Thanks to @quifox for #2627.
  • Codex children now keep tool-call IDs in the call_id|item_id form when both parts are at most 64 characters and use only letters, digits, _, or -. Other IDs are shortened as before. Thanks to @jtabke for #2628 (#2623).
  • With Pi's built-in MCP, mcp: entries whose server or tool name contains -, such as mcp:srv/get-item, failed with "selects MCP tools that Pi's built-in MCP does not offer". pi-subagents now converts - to _ the same way Pi names the tool, so you keep writing names as the server reports them. Thanks to @sheurich for #2607.
  • Some MCP clients, such as pi-claude-bridge, send workflow: true as the string "true", which failed with an error asking for workflow: true. The string now works the same as the boolean (#2600).
  • action: "validate" now checks workflow args against the same limits as a launch: 16 fields per object, 64 items per array, depth 8, and 16 KiB total. A script that validates no longer fails at launch because of its args. (#2608)
  • The parent is now told about every tool call that stays open past the attention threshold, not only the first one in each child. Thanks to @jiuai233 for #2598.
  • Async runs now reach run-history.jsonl. Before, only foreground runs were recorded, so per-agent lookups missed every background launch. Single-step runs record the same row as a foreground run, multi-step runs record one row per child step, and a paused run records as interrupted, with a later resume recording again. Thanks to @limin411 for #2620.
  • /subagent-cost and the RPC cost method now count every round of a resumed foreground workflow child. Before, every round after the first was dropped as a duplicate, so totals came out low with no warning. Results recorded before this fix still undercount. Thanks to @chagwood for #2601.
  • /subagent-cost and the RPC cost method no longer log a missing-receipt error on every call for foreground workflows. An async workflow that has no receipt yet, such as one still running, is now listed as Async child usage unavailable instead of being left out of the total without notice. (#2614)
  • The global mission list now takes title, status, update time, and latest run from each mission's own record, so a mission no longer looks out of date because its index entry is stale. Thanks to @quifox for #2618.
  • Headless sessions now deliver goal-mission notices even when finishing background work fails. The failure is still reported to the caller. Thanks to @quifox for #2605.
  • One mission with a damaged run status or state no longer stops continuation notices for healthy goal missions. The damaged mission is reported separately. Thanks to @quifox for #2604.
  • On Linux, a runner process that exited but was not yet cleaned up by the system no longer leaves its run marked as running, or a workflow waiting for a result that will never arrive. Thanks to @quifox for #2606.
  • Saved subagent profiles with an invalid machine value are now rejected when loaded or checked, before any settings are written. machine: false still clears a pin. Thanks to @quifox for #2619.

Don't miss a new pi-subagents release

NewReleases is sending notifications on new releases.