simonw--llm
3ac0a23381
* PauseChain primitive + chain resume from pending tool calls Two features that together give chains a first-class suspend/resume story for human-in-the-loop tools: llm.PauseChain: raise inside a tool implementation to stop the chain cleanly. Unlike other exceptions it is not converted into an error ToolResult - it propagates to the caller with .tool_call (the paused call) and .tool_results (completed sibling results) attached, and no provider call is made with a placeholder result. Failure semantics for concurrent tool execution are now defined: async sibling tasks always run to completion before a pause or hook exception propagates (gather with return_exceptions, raised after collection), so nothing is orphaned mid-flight; sync execution stops at the paused call, leaving later calls unstarted so they can safely run on resume. Chain resume: chain(messages=history, tools=...) now detects a history ending in an assistant message with unresolved tool calls - e.g. one persisted when a previous run paused or crashed - executes those calls through the normal before_call/after_call machinery (skipping any that already have results), then sends the results to the model as a standard tool-result turn. A resumed call may pause again, enabling multi-question flows. Histories where a user or assistant message follows the calls are left alone. Also adds execute_tool_calls(tool_calls_list=) for executing an explicit list. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>