v2026.6.9
Added
-
initrunner tool new "<description>"scaffolds a custom tool from natural language. It generates a plain-Pythontype: custommodule plus a pytest stub using the configured model, AST-validates the source before writing (the module is never imported during scaffolding), retries once on a validation failure, and prints a paste-readytools:snippet. Generated functions default toasync def, take config and secrets through an injectedtool_configdict, and avoid sandbox-blocked imports.--outputsets the module name (and retargets the generated test's import to match). -
initrunner run <role> --devadds a developer REPL. It turns off streaming and the status spinner so abreakpoint()in a custom tool owns the terminal forpdb, and enables in-session tool hot-attach. -
In-REPL
/tool add <module>and/reload./tool addappends atype: customtool and rebuilds the agent in place (reloading an edited module), so a freshly scaffolded tool is callable on the next turn with the conversation preserved;/reloadrebuilds the agent after an edit torole.yaml. Both run through a newAgentHandlethat swaps the live agent under a lock and carries_template_values/_memory_store/_resume_contextonto the rebuilt agent. -
initrunner plan <role>predicts a run without calling the model. A new command that reports reachable tools (function-level via builder introspection), would-fire initguard policy decisions, applied guardrails, the sandbox that would engage, armed triggers, and a heuristic token/USD cost. Supports--prompt(sizes the cost estimate and surfaces the prompt'stool_searchsubset),--no-introspect(type-level only),--no-sandbox-probe, and--json. It never raises: a tool whose builder fails or opens a connection is reported at type level with a caveat.
Fixed
- Async custom tools wrapped by the audit-hook sandbox stay coroutines.
build_custom_toolsetnow wraps anasync deftool with an async sandbox wrapper instead of the sync wrapper, which previously returned an un-awaited coroutine. - Cron cost projections work in
cost estimateandplan.estimate_role_cost_syncconstructedcroniterwithout a timezone-aware base, soget_next()returned naive datetimes that failed the 24h firing-window comparison and silently dropped the daily/monthly estimate; it now passes a UTC base.