feat: allow HITL to review materialized tool calls - #12517
Conversation
Allow BlockingConfirmationStrategy and ConfirmationHook to show inputs_from_state values alongside LLM arguments when include_state_inputs is enabled. Materialization reuses the same _inject_state_args logic used at execution time so the approval view matches what the tool will receive. Hook-level flag propagates to strategies via transient state so both levels can opt in. Fixes deepset-ai#12060
|
@lorenzozanee is attempting to deploy a commit to the deepset Team on Vercel. A member of the Team first needs to authorize it. |
|
|
|
Hi @lorenzozanee, thanks for your interest in contributing to Haystack! 🙏 This is an automated message to help us keep the review queue healthy. |
|
Hi @lorenzozanee, thanks a lot for your contribution! 🙏 We noticed that the Contributor License Agreement (CLA) check ( To get your PR reviewed, please sign the CLA via the link in the |
Related Issues
Proposed Changes:
HITL currently shows only the LLM-produced arguments, while tools with
inputs_from_statereceive additional values fromStateat execution time. The reviewer therefore approves an incomplete view of the call.This PR adds an opt-in mode to surface fully materialized calls before execution:
BlockingConfirmationStrategy(include_state_inputs=True)andConfirmationHook(include_state_inputs=True)materializeinputs_from_statevia the same_inject_state_argsused bytool_calling._run_toolFalsefor backward compatibilityConfirmationHook(include_state_inputs=True)covers the wildcard*caseState-typed parameters are shown as"<State>"to avoid dumping whole stateStatemissing keys are handled without errorThe materialization happens at
before_tooltime from the currentStatesnapshot, matching execution-time injection for the stable single-tool case. For multi-tool batches where an earlier tool writes a key read by a later one, the approved view reflects the state at approval time; the existing per-batch re-materialization at dispatch still determines the final execution value.How did you test it?
inputs_from_state={"selected_customer_id":"customer_id"}andState(selected_customer_id="cust_84319"): without the flag the UI sees{"reason":"duplicate"}, with the flag it sees{"reason":"duplicate","customer_id":"cust_84319"}andfinal_tool_paramsmatchestest/hooks/human_in_the_loop(99 passed) andtest/components/agents/test_agent_hitl.py(7 passed) including new casesTestMaterializedStateInputsfor strategy and hook propagationto_dict/from_dictround-trips for bothBlockingConfirmationStrategyandConfirmationHookhatch run fmtcleanNotes for the reviewer
Opt-in only, no behavior change by default. Follow-up provenance labeling (
llm_argvsstate_injected) and redaction can build on this materialization path without changing the approval contract.Checklist