fix(code): authorize Auto actions from ask_user selections - #4946
Closed
Mason Daugherty (mdrxy) wants to merge 4 commits into
Closed
fix(code): authorize Auto actions from ask_user selections#4946Mason Daugherty (mdrxy) wants to merge 4 commits into
ask_user selections#4946Mason Daugherty (mdrxy) wants to merge 4 commits into
Conversation
ask_user selectionsask_user selections
Member
Author
|
Superseded by #4993. The replacement carries forward this PR's server-owned, same-turn Closing this PR in favor of #4993. |
Mason Daugherty (mdrxy)
added a commit
that referenced
this pull request
Jul 23, 2026
Supersedes #4946 Supersedes #4947 Auto mode no longer interrupts users when an action is already covered by their explicit `ask_user` selection or when the agent is performing the built-in conversation-compaction operation. --- Previously, Auto mode could ask users to approve an action immediately after they selected it in an `ask_user` prompt. It could also pause autonomous work to approve `compact_conversation`, even though compaction is an internal maintenance operation without an externally consequential effect. The two cases now follow separate trust rules: - Server-created, same-turn receipts allow the authorization classifier to consider only the user's selected answer for the exact subsequent action. The receipt is bound to the LangGraph execution thread, the active turn, and the originating `ask_user` tool call, and is validated against the full checkpoint history so it survives conversation compaction. Only the latest `ask_user` exchange in the turn is admitted; model-authored questions, unselected choices, and prior answers are excluded. Invalid, stale, ambiguous, or overly broad consent continues through the normal approval path. - The trusted built-in `compact_conversation` operation is deterministically allowed without classifier or human review. The exemption is guarded by exact tool-object identity, not by name, so a caller-supplied tool with the same name cannot exploit it. At most one trusted compaction call is allowed per action batch; duplicates are denied without classifier review, and that denial is preserved across all fallback paths. <details> <summary>Test plan</summary> Targeted Auto-mode, ask_user, agent-wiring, and Textual-adapter tests: ``` uv run --group test pytest tests/unit_tests/test_ask_user_middleware.py \ tests/unit_tests/test_auto_mode.py \ tests/unit_tests/tui/test_textual_adapter.py::TestExecuteTaskTextualTurnMarkers \ tests/unit_tests/test_agent.py::test_cli_context_schema_fields_mirror_typed_dict \ tests/unit_tests/test_agent.py::TestCreateCliAgentInterpreterWiring \ --disable-socket --allow-unix-socket --benchmark-disable -q ``` Result: 135 passed. Full package unit tests: ``` make test ``` Result: 10617 passed, 4 skipped, 6 pre-existing failures in `TestLangsmithSecretRedaction` (env-dependent, fail on clean `origin/main`). Lint, format, type check, and commands catalog: ``` make lint ``` Result: All checks passed. A real LangGraph interrupt/resume test (`test_real_agent_resume_forwards_ask_user_receipt_to_classifier`) verifies the full path: `ask_user` interrupt → checkpoint resume → receipt minting with real `execution_info.thread_id` → classifier sees `same_turn_user_answers` → action executes without a second HITL prompt. A compiled-graph identity test (`test_compiled_agent_preserves_canonical_compaction_tool_identity`) verifies the canonical `CLICompactionMiddleware` tool object survives `create_deep_agent`'s middleware merge into the compiled `ToolNode`, and that `AutoModeHITLMiddleware._trusted_compaction_tool` references that same object. The 6 `TestLangsmithSecretRedaction` failures are pre-existing and env-dependent (real LangSmith credentials in the local environment); they fail identically on clean `origin/main` and are unrelated to this change. </details>
Marcelo5444
pushed a commit
to Marcelo5444/deepagents
that referenced
this pull request
Jul 30, 2026
Supersedes langchain-ai#4946 Supersedes langchain-ai#4947 Auto mode no longer interrupts users when an action is already covered by their explicit `ask_user` selection or when the agent is performing the built-in conversation-compaction operation. --- Previously, Auto mode could ask users to approve an action immediately after they selected it in an `ask_user` prompt. It could also pause autonomous work to approve `compact_conversation`, even though compaction is an internal maintenance operation without an externally consequential effect. The two cases now follow separate trust rules: - Server-created, same-turn receipts allow the authorization classifier to consider only the user's selected answer for the exact subsequent action. The receipt is bound to the LangGraph execution thread, the active turn, and the originating `ask_user` tool call, and is validated against the full checkpoint history so it survives conversation compaction. Only the latest `ask_user` exchange in the turn is admitted; model-authored questions, unselected choices, and prior answers are excluded. Invalid, stale, ambiguous, or overly broad consent continues through the normal approval path. - The trusted built-in `compact_conversation` operation is deterministically allowed without classifier or human review. The exemption is guarded by exact tool-object identity, not by name, so a caller-supplied tool with the same name cannot exploit it. At most one trusted compaction call is allowed per action batch; duplicates are denied without classifier review, and that denial is preserved across all fallback paths. <details> <summary>Test plan</summary> Targeted Auto-mode, ask_user, agent-wiring, and Textual-adapter tests: ``` uv run --group test pytest tests/unit_tests/test_ask_user_middleware.py \ tests/unit_tests/test_auto_mode.py \ tests/unit_tests/tui/test_textual_adapter.py::TestExecuteTaskTextualTurnMarkers \ tests/unit_tests/test_agent.py::test_cli_context_schema_fields_mirror_typed_dict \ tests/unit_tests/test_agent.py::TestCreateCliAgentInterpreterWiring \ --disable-socket --allow-unix-socket --benchmark-disable -q ``` Result: 135 passed. Full package unit tests: ``` make test ``` Result: 10617 passed, 4 skipped, 6 pre-existing failures in `TestLangsmithSecretRedaction` (env-dependent, fail on clean `origin/main`). Lint, format, type check, and commands catalog: ``` make lint ``` Result: All checks passed. A real LangGraph interrupt/resume test (`test_real_agent_resume_forwards_ask_user_receipt_to_classifier`) verifies the full path: `ask_user` interrupt → checkpoint resume → receipt minting with real `execution_info.thread_id` → classifier sees `same_turn_user_answers` → action executes without a second HITL prompt. A compiled-graph identity test (`test_compiled_agent_preserves_canonical_compaction_tool_identity`) verifies the canonical `CLICompactionMiddleware` tool object survives `create_deep_agent`'s middleware merge into the compiled `ToolNode`, and that `AutoModeHITLMiddleware._trusted_compaction_tool` references that same object. The 6 `TestLangsmithSecretRedaction` failures are pre-existing and env-dependent (real LangSmith credentials in the local environment); they fail identically on clean `origin/main` and are unrelated to this change. </details>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
In Auto mode, answering an
ask_userprompt now authorizes the exact action the user selected, so the agent no longer stalls asking the user to retype a choice they just made.Auto mode's action classifier previously accepted only literal chat-input text as evidence of user consent. A selection made through an
ask_userprompt became an ordinary tool result, which the classifier is required to treat as untrusted context. As a result, after the user picked an option such as "Rebase my new local commit onto the remote branch, then push," the follow-up action was still denied and the agent looped back asking the user to explicitly re-authorize the same command.When the user answers an
ask_userprompt,dcodenow records a server-owned authorization receipt bound to the current thread, turn, and originating tool call. The classifier admits these validated same-turn answers as consent evidence, resolving references such as "run it" or a selected option without requiring the user to restate the command.The grant is deliberately narrow:
dcodefor the current turn count; model- or tool-authored text cannot forge one, and the model-authored question is never treated as consent.ask_usercall, so stale, cross-turn, cross-thread, duplicated, or replayed receipts are ignored.