Headline: tool dispatch is no longer strictly serial. When the model emits multiple parallelSafe-annotated tool calls in one turn, the loop races them together via Promise.allSettled; non-parallelSafe calls form serial barriers, so read-after-write order still holds. Tool yields and history append still land in declared order regardless of which call settles first.
The TUI's SubagentRow becomes SubagentLiveStack: 1 → rich card, 2..max → compact rows, > max → "+N more running…" fold.
Closes umbrella #325.
Tool dispatch
ToolDefinition.parallelSafe?: boolean— opt-in, defaultfalse. Built-in read-only filesystem, web,recall_memory,semantic_search, isolated child loops (run_skill,spawn_subagent), and in-memory job queries opt in. Mutating tools stay default. (#326)- Loop dispatch chunks consecutive
parallelSafecalls and races them; unsafe calls form barriers.runOneToolCallextracts per-call lifecycle (PreToolUse + dispatch + PostToolUse). New env knobs:REASONIX_PARALLEL_MAX(default 3, hard max 16) andREASONIX_TOOL_DISPATCH=serial(escape hatch). (#327)
TUI
SubagentEventcarries a stablerunIdper spawn;useSubagentkeeps an array of in-flight activities;SubagentLiveStackrenders 1..max → compact rows + "+N more" fold. (#327)
Docs
docs/ARCHITECTURE.mdPillar 1 gains a "Parallel tool dispatch" section. (#328)
Install
npm i -g reasonix@0.29.0