The single- and multi-level suspend/restore tests gated their slow
leaf tool on a manual release channel closed 50ms after cancel().
That sleep was a guess at how long the suspend signal takes to reach
the running sub-agent, so the post-tool turn boundary could observe
the release before cancellation and complete the run instead of
checkpointing, making the assertions timing-dependent.
Expose the per-run suspend signal through SuspendSignalFrom in an
export_test shim and have the leaf tools block on it directly. The
tool now returns only once the graceful-suspend signal has actually
propagated to its agent, so suspension is observed deterministically
without sleeps or release channels.
Signed-off-by: Bryan Frimin <bryan@probo.com>
Propagate graceful-suspend signals through detached run contexts and let
only opt-in suspendable tools re-attach cancellation, so AsTool sub-agents
can checkpoint and restore across nested trees while leaf tools keep
running detached.
Add focused agent and worker tests for single and multi-level suspend/
restore flows, plus heartbeat lease-loss and nested-restore error paths to
harden functional behavior under failure conditions.
Signed-off-by: Bryan Frimin <bryan@probo.com>
JSON null unmarshals into an empty string, so the presence-only
key check let {"input":null} through, running the nested agent
with a blank user message.
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
executeSingleTool had three exit paths but only the success path
emitted all end signals. The interrupted path (nested agent
approval) skipped OnToolEnd and StreamEventToolEnd entirely,
leaving hook consumers with an unpaired OnToolStart. The error
path also missed StreamEventToolEnd and AgentHooks.OnToolEnd.
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
jsonSchemaFor panicked on unsupported types, which meant
FunctionTool, NewOutputType, and RunTyped would crash the
process during setup rather than returning a normal error.
Signed-off-by: Bryan Frimin <bryan@getprobo.com>
The agentTool.Execute method accepted {} despite the schema
marking input as required. Unlike functionTool, it skipped
required-field validation, silently sending an empty message
to the sub-agent.
Signed-off-by: Bryan Frimin <bryan@getprobo.com>