github nicobailon/pi-subagents v0.74.0

2 hours ago

pi-subagents 0.74.0 makes workflow scripts much easier to write: the model now writes a normal js workflow code block in its reply instead of cramming the whole script into an escaped JSON string. Models that can't add a tool mid-conversation now get subagent from the start, so turning it on no longer costs a full uncached reprocess of the conversation. You can also slim the subagent tool down to the parts you actually use, and background workflows now survive /reload and session resumes. Subagent children also respect an untrusted project the same way the main session does.

Highlights

  • Workflow scripts as code blocks. Write the script in a ```js workflow block and call subagent({ workflow: true }). No more JSON escaping.
  • No cache miss when turning on subagents. On models that can't add tools mid-conversation, subagent is available from the first turn. The new toolActivation setting lets you choose.
  • A smaller tool when you want one. disabledFeatures hides feature groups you don't use. With workflow-scripts disabled, simple chain and tasks lists replace scripts.
  • Background workflows survive /reload. Running children keep going, and relaunching the same script reuses the children that already finished.
  • Children follow project trust. In an untrusted project, subagent children no longer load that project's settings, prompts, skills, or extensions.

Need to know

Who What to do
Anyone calling subagent with workflowScript or workflowScriptPath These parameters were removed. Use workflow: true with a ```js workflow block in the same reply, or workflow: "./path/to/script.js" for a file. Old calls fail with an error that shows the new forms.
RPC spawn callers Pass inline script text as script, and a path or workflow name as workflow.
Extensions that register workflow resources The names chain and tasks are now reserved.

Saved schedules and existing run records keep working without changes.

Full changelog

Highlights

  • Workflow scripts are now written as a normal ```js workflow code block in the reply and run with workflow: true, with no JSON escaping. This replaces workflowScript and workflowScriptPath.
  • On models that cannot add a tool mid-conversation, subagent is now available from the start, so turning it on no longer reprocesses the whole conversation at full price.
  • The new disabledFeatures setting hides parts of the subagent tool you do not use, and with workflow-scripts turned off you can run children with simple chain and tasks lists.
  • /reload and session resumes no longer kill running background workflows, and relaunching one reuses the children that already finished.
  • Subagent children now respect an untrusted project the same way the main session does.

Added

  • disabledFeatures in config.json removes feature groups you do not use from the subagent tool, such as agent management, watchdog, panes, missions, lane management, and per-call options like toolBudget or machine. Their parameters disappear from the tool, the tool description stops mentioning them, and calls that still use them fail with an error that names the setting. scheduledRuns.enabled: false now removes the schedule parameters the same way, and a malformed scheduledRuns value is now a config error. Nothing changes unless you opt in. With everything disabled, the tool declaration shrinks from 18,239 to 10,263 characters. See configuration. Thanks to @tmustier for #2542.
  • disabledFeatures also accepts workflow-scripts. It removes the workflow, args, preflight, globalConcurrencyLimit, and maxSubagentSpawnsPerRun parameters and the validate action, and the tool description no longer explains how to write scripts. In their place, the tool takes tasks: [{ agent, task }] to run children in parallel and chain: [{ agent, task?, as? } | { parallel: [{ agent, task }] }] to run steps in order. Chain tasks can use {task} (the top-level task), {previous}, and {outputs.name}. If a child fails, the run fails but still returns the results of the children that finished. Scripts that still arrive from RPC, /prompt-workflow, saved schedules, or delegated launches fail with an error that names the setting; /run still works. This mode saves about 2,000 more characters of tool declaration. Without it, the tool is unchanged. In both modes, extensions can no longer register workflow resources named chain or tasks. See configuration.
  • On Pi 0.99 and later without pi-mcp-adapter, mcp:server and mcp:server/tool entries in an agent's tools now select tools from Pi's built-in MCP, and the child gets exactly those tools. Servers from mcp.json work in foreground and background children; servers that extensions add with pi.registerMcpServer() work in background children. With pi-mcp-adapter installed, nothing changes. Thanks to @fmoda3 for #2555.
  • subagents.modelScope allow lists accept a scoped token, which stands for the parent session's scoped models (Pi's /scoped-models). Subagent model limits then follow Pi's model scoping without a second copy of the list. In an unscoped session, scoped means the same as inherit. Error messages list at most 8 patterns before summarizing the rest. Thanks to @coreyryanhanson for #2538.
  • subagents.agentOverrides.<name>.advertise lists an agent in the parent's agent catalog from settings, so you no longer have to copy a builtin agent file just to advertise it. Agents registered at runtime still cannot be advertised. Thanks to @strive-run for #2534.
  • Native Pi subagents can use Pi's built-in codemode tool when their tool selection allows it. It is loaded only in the child, so the main session can keep codemode off. Older Pi versions without codemode still report it as unavailable when an agent asks for it. Thanks to @albertgwo for #2574.
  • After you upgrade pi-subagents, your first interactive session shows a short notice with the highlights of each new version and a link to the changelog. It is shown once and never enters the conversation, so it does not affect the model's context or prompt cache. Fresh installs and child sessions show nothing.

Changed

  • Breaking: Workflow scripts had to be passed to the subagent tool as a JSON string, so every quote and newline was escaped. The tool now takes one workflow field with three forms: workflow: true runs the single ```js workflow code block written in the same reply; a string containing / (such as "./ci/sweep.js") loads a script file relative to cwd; any other string runs a named workflow. The workflowScript and workflowScriptPath parameters were removed, and calls that still pass them fail with an error that shows the new forms. RPC spawn takes inline script text as script and a path or workflow name as workflow. Saved schedules and run records keep working.
  • On models that cannot take a new tool mid-conversation, calling subagents_enable made the provider reprocess the whole conversation at the uncached price. New sessions on those models now start with subagent already available. Models that can add tools mid-conversation still start with subagents_enable. Resumed sessions keep the tools they had, and switching models mid-session does not change them. The new toolActivation setting in config.json chooses "auto" (the default), "dynamic" (always start with subagents_enable, the old behavior), or "eager" (always start with subagent, like --exclude-tools subagents_enable). See configuration. Thanks to @tinoy1336 for #2589.
  • After subagents_enable, the model was sometimes told to wait for the next prompt even when subagent was already usable. It is now told to check its tool list: use subagent if it is there, otherwise wait for the next prompt instead of retrying.
  • CI now runs the tool-activation smoke test as a required check. Thanks to @quifox for #2528.

Fixed

  • Subagent children now follow the parent session's project trust. Before, a child in an untrusted project still loaded that project's settings, system prompt files, skills and, for background children, its extensions. Fixes #2569.
  • /reload, a session resume, or a pi-web project switch stopped running background workflows and their children, and relaunching the script ran every child again, including ones that had already finished. Background children now keep running, the workflow's notice says to relaunch it, and relaunching the same script with the same args reuses finished children and waits for running ones. Failed children run again. The stop is recorded as workflow.stopCause: "runtime-replaced". Fixes #2546.
  • Stopping a background workflow by a short id, its tool-call id, its run directory, or from the Fleet view did nothing, so the workflow and its children kept running. These stops now work, and the workflow ends as stopped. Fixes #2571.
  • Reviving a failed background workflow child with subagent({ action: "resume", id }) did not show up in the workflow: its status, receipt and keyed latest: true resume still pointed at the failed run. Workflow status now shows Revived → <run>: <state> under the failed key, keyed resume continues from the revived run, and a workflow that finishes afterwards records the revival in its receipt and completion notice. The workflow's return value is unchanged. Thanks to @l3gz for reporting #2579.
  • When a workflow script failed and stopped a sibling that was still running, the sibling got a "Workflow child failed" notice whose error began with a "Run fan-out: N/M used, K remaining" line. The notice now says the child was stopped and gives only the reason. Fixes #2562 and #2567.
  • After pi-subagents was updated on disk while Pi was running, for example by git pull in a local checkout or a package update, the first subagent call could fail with an error such as (0 , _publicExecution.isWorkflowScriptPath) is not a function, because it mixed new and old code. pi-subagents now loads all of its code shortly after a session starts, without slowing startup. After an update, run /reload or restart Pi to use the new version.
  • With Pi 0.99's codemode turned on, codemode scripts could call subagent, subagents_enable, subagent_supervisor, contact_supervisor and structured_output, none of which work from a script: a subagent run there had no progress card and was cancelled unless awaited, contact_supervisor blocked the script, and structured_output had no effect. Codemode also added the whole subagent schema to its own description, about 2,200 extra tokens per request. The model can still call these tools directly, but scripts can no longer call them. Older Pi versions are unaffected.
  • With the subagent tool registered, every request to llama.cpp (llama-server --jinja) failed with a 400 error because one parameter's pattern was not anchored at both ends, which llama.cpp requires. The pattern is now anchored and accepts the same values. Thanks to @tychart for reporting #2581.
  • With pi-mcp-adapter 3.x on Pi 0.99 or later, mcp: entries in an agent's tools looked up Pi's built-in MCP instead of the adapter, so choosing an adapter server failed the launch. The adapter now takes priority whenever it is loaded. Fixes #2575.
  • After upgrading pi-mcp-adapter to 3.1.0, mcp: tool selections for stdio servers stopped resolving, because the adapter started including inheritEnv and literalEnv in its config hash. pi-subagents now computes the same hash. Thanks to @qsgy-edge for #2539.
  • When the async widget did not have room for its full view, its compact card showed one line per run and filled the rest with blank rows, hiding a workflow's lanes. The card now shows the lanes in that space and is only as tall as its content. Thanks to @l3gz for reporting #2578.
  • The async widget and the Fleet view counted running agents differently: with a 4-lane workflow and one other run, the widget said 2 agents running and the Fleet view said 5 active agents. The widget now counts each running workflow lane and each agent of a parallel run, like the Fleet view. Thanks to @l3gz for reporting #2578.
  • Herdr's subagent count no longer counts a workflow's coordinator as a child, and it updates as soon as a foreground workflow child starts or finishes instead of up to 45 seconds later. Thanks to @xadips for #2556.
  • Dynamic tool activation now works when Pi runs inside another app, such as pi-web. Those hosts no longer print "Could not locate the running Pi installation" and no longer fall back to keeping subagent always loaded. Thanks to @q107580018 for #2526.
  • Answering a background subagent's supervisor request no longer triggers a stale "needs attention" notice afterwards. The notice now waits 60 seconds and is sent only if the request is still unanswered and the run is still active. Status views still show the request right away.
  • inheritSkills: false now also removes skills that extensions add to a child session (for example through subagents.defaultExtensions), so they no longer appear next to the agent's own skills. Thanks to @zeezooz for #2540.
  • A child that was aborted by compaction now recovers when Pi reports the compaction late. Thanks to @jiuai233 for #2537.
  • Old background runs that belong to a finished or deleted mission are now cleaned up like other old runs instead of being kept forever. Fixes #2535. Thanks to @LCorleone for #2536.
  • On Windows, the Pi interface froze for about 0.45 seconds once per process while background run cleanup waited on a PowerShell query. The query no longer blocks the interface. Thanks to @localhedge for reporting #2559.
  • On Windows, an idle session no longer checks for supervisor requests every 250 ms for its whole lifetime. Checking stops when no subagent work is pending and starts again when new work begins, as it already did on macOS. Thanks to @localhedge for reporting #2558.
  • Starting, reloading, resuming, or forking a session no longer pauses Pi while the watchdog records the current Git commit (about 50 ms per session start on Windows, even with the watchdog off). The check now runs in the background. Thanks to @localhedge for reporting #2560.
  • Worktree diffs now work with older Git versions that lack the --default-prefix option. Thanks to @quifox for #2527.
  • Updated undici from 8.10.0 to 8.10.2, outside the range of GHSA-3wwx-pv8p-q78v, so projects that install pi-subagents no longer fail npm audit because of it. pi-subagents does not use the affected WebSocket client. Thanks to @advaitpaliwal for #2548.
  • A package-discovery test no longer fails when the system temp directory is inside a Pi project. Thanks to @abdwhb-png for #2553.

Don't miss a new pi-subagents release

NewReleases is sending notifications on new releases.