v2.4.0
v2.4.0 — the orchestration release
The last pillar from the June research. Zero new dependencies, 162 tests, 30 runnable examples.
⚠ Behavior change
Budgets default to unlimited. Budget() no longer caps anything (previously an implicit 50-step / 10-minute cap). The rule: what you define is enforced; what you don't define is no restriction. If you relied on the implicit cap, pass Budget(steps=50, duration_seconds=600) explicitly.
Handoff graphs (optional)
Sequential multi-agent workflows where the edge is a permission boundary: each node is one run_agent call with its own policy/tools/budget — role boundaries enforced by policy, not prompts. Route with a pure Python Router or a compile-time-validated YAML edge table; route on denial counts (only possible because policy is first-class); max_transitions always enforced; durability composes (whole-workflow resume with zero model calls). The kernel knows nothing about graphs.
Timeouts
Budget.step_timeout_seconds— a hung model call fails the run instead of hanging forever (durability-safe).inline_executor(timeout_seconds=…)— bounds in-process tools; the action fails, the run survives.
Fixed
run_in_subprocess/subprocess_executornow work for tools defined in a script's__main__(multiprocessing-style remap). Previously every script-defined sandboxed tool failed withsandbox exited 1.
Examples
27 (graphs, 4 acts) · 28 (full-stack capstone) · 29 (memory gating, OWASP ASI06) · 30 (FinOps chargeback) · 18 modernized to the executor seam · 24 + JSONL store / lynx trace / bundle_changed.
Note: the sdist's CHANGELOG carries these entries under '[Unreleased]' (header sectioning landed one commit after the tag — cosmetic only; code and version are correct).