AskUserMiddleware(
self,
*,
system_prompt: str = ASK_USER_SYSTEM_PROMPT,
tool_description: str = ASK_USER_TOOL_DESCRIPTIONMiddleware that provides an ask_user tool for interactive questioning.
This middleware adds an ask_user tool that allows agents to ask the user
questions during execution. Questions can be free-form text, multiple choice
(pick exactly one), or multi-select (pick one or more).
The tool uses LangGraph interrupts to pause execution and wait for user input.
System-level instructions injected into every LLM
request to guide ask_user usage.
Description string passed to the ask_user tool
decorator, visible to the LLM in the tool schema.
Omit hook inputs from traces by default; set a TracePolicy to override.
Log a rejected ask_user call, then pass the result through.
ToolNode converts an argument ValidationError into an error
ToolMessage before it reaches here, and it logs nothing itself, so
without this a model sending malformed arguments ā or looping on them ā
leaves no operator-visible record at all. The user sees only a red
ask_user row in the transcript.
The result type is the discriminant: _ask_user always returns a
Command, so a ToolMessage here means the call never entered the tool
body. That keeps this off the _parse_answers error path, which reports
a malformed resume payload inside a Command and logs itself.
Nothing is caught. An exception from the body must stay fatal, and
GraphBubbleUp from interrupt() must keep bubbling.
Async twin of wrap_tool_call.
Defined so the async path keeps executing tools asynchronously. With
only the sync wrapper present, ToolNode falls back to running the tool
through _execute_tool_sync.
Inject the ask_user system prompt.
Inject the ask_user system prompt (async).