fix(code): gate Hooks v2 behind DEEPAGENTS_CODE_EXPERIMENTAL - #5146
Merged
Johannes du Plessis (johannes117) merged 7 commits intoJul 29, 2026
Merged
Conversation
Hooks v2 is still in progress but already runs user-authored hook commands in every session. `_load_runtime` is the only production site that builds a `HooksRuntime`, so returning `None` there unless the experimental flag is truthy leaves the manager inert (client lifecycle events no-op) and strips `hooks_server_events` from the graph context, which keeps the server middleware gate closed too. Legacy v1 hooks keep firing as before. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Johannes du Plessis (johannes117)
marked this pull request as ready for review
July 29, 2026 17:08
`TestLiveApprovalModeWrites` probes session-state construction by patching `HooksRuntime.create`, which no longer runs unless `DEEPAGENTS_CODE_EXPERIMENTAL` is set, so both tests enable the flag. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
The previous push did not create a `pull_request` CI run. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Johannes du Plessis (johannes117)
marked this pull request as ready for review
July 29, 2026 18:23
Resolved `hooks/manager.py`: kept main's trust-aware `_load_runtime` signature and docstring, plus the `DEEPAGENTS_CODE_EXPERIMENTAL` gate. Also gated the new project-hooks trust prompt on the same flag, so startup does not ask users to trust hooks that cannot run. Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Also drop the remaining test adaptations from this gate PR.
Johannes du Plessis (johannes117)
enabled auto-merge (squash)
July 29, 2026 18:57
Existing Hooks v2 tests need `DEEPAGENTS_CODE_EXPERIMENTAL` now that runtime load and middleware mount are gated behind it.
Alexander Olsen (aolsenjazz)
self-requested a review
July 29, 2026 19:44
Alexander Olsen (aolsenjazz)
approved these changes
Jul 29, 2026
Johannes du Plessis (johannes117)
deleted the
open-swe/hooks-v2-experimental-gate
branch
July 29, 2026 19:44
Marcelo5444
pushed a commit
to Marcelo5444/deepagents
that referenced
this pull request
Jul 30, 2026
…hain-ai#5146) Hooks v2 now runs only when `DEEPAGENTS_CODE_EXPERIMENTAL` is enabled; legacy hooks are unaffected. --- Hooks v2 is still in progress but already loads and runs user-authored hook commands in every session. `_load_runtime` is the only production site that builds a `HooksRuntime`, so returning `None` there unless the experimental flag is truthy leaves `HooksManager` inert — client lifecycle events no-op and transcripts are discarded — and `apply_hooks_context` strips the hook snapshot id and server-event gate from the graph context, which keeps `ServerHooksMiddleware` closed for `PreToolUse`, `PostToolUse`, `Stop`, and subagent events. Legacy hooks dispatch through a separate path guarded by `has_handlers` checks, so they keep firing exactly as before. Gating at that single seam was preferred over per-call-site checks: every other `HooksManager` construction already passes no runtime, so one gate covers both the interactive and headless clients plus `reload`. Two existing `TestLiveApprovalModeWrites` tests patch `HooksRuntime.create` as their session-construction probe, so they now enable the flag explicitly. <details> <summary>Test plan</summary> - `tests/unit_tests/hooks` (173), `test_app.py` (1341), `test_non_interactive.py` (116), Textual adapter + offload (290), agent / tool-stream / legacy-hooks / local-context / server-helpers (468) all pass. - New `test_hooks_v2_requires_experimental_flag` asserts `HooksManager.create(...).enabled` flips with the flag. </details> Made by [Open SWE](https://openswe.vercel.app/agents/019faecf-b901-755b-abc4-e2c4f5e90726) --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Mason Daugherty (mdrxy)
pushed a commit
that referenced
this pull request
Jul 30, 2026
> [!CAUTION] > Merging this PR will automatically publish to **PyPI** and create a **GitHub release**. For the full release process, see [`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md). --- _Release notes preview: keep this section in sync with the package `CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`, not this PR description — keep them aligned anyway so the PR stays an accurate historical record for reviewers and anyone returning later._ --- ## [0.1.50](deepagents-code==0.1.49...deepagents-code==0.1.50) (2026-07-30) ### Highlights - Added project hooks workspace trust and expanded Hooks v2 support with client and server lifecycle events plus runtime feedback ([#5105](#5105), [#5104](#5104), [#4997](#4997), [#5045](#5045)). - Added an option to mute the “YOLO is active” toast ([#5103](#5103)). - Made the splash screen `thread` ID clickable to copy it ([#5173](#5173)). - Show `ask_user` answers directly on the answered tool row ([#5100](#5100)). - Show a toast when submitting an empty required `ask_user` answer ([#5095](#5095)). - Added thread message counts to the Debug Console ([#5117](#5117)). ### Fixes and improvements - Gated Hooks v2 behind `DEEPAGENTS_CODE_EXPERIMENTAL` and improved hook resume stability across identity and Command tool results ([#5146](#5146), [#5176](#5176)). - Kept server hook state out of task results ([#5164](#5164)). - Stopped duplicate Auto transcript events during interrupt replay ([#5157](#5157)). - Kept `/update` and `/install --package` prompts responsive ([#5127](#5127)). - Refreshed the `/threads` cache after each turn ([#5174](#5174)). - Anchored toasts above the chat input and added a toast when media is dropped into a free-text question ([#5101](#5101), [#5099](#5099)). - Improved thread status message styling and links ([#5118](#5118)). - Made resume hints echo the launched command name ([#5119](#5119)). - Scoped selection copy to the clicked screen ([#5140](#5140)). - Ignored mouse hits on detached widgets ([#5114](#5114)). _End release notes preview._ --- > [!NOTE] > A **New Contributors** section is appended to the GitHub release notes automatically at publish time (see [Release Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline), step 2). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com> Co-authored-by: Johannes du Plessis <johannes@langchain.dev>
Mason Daugherty (mdrxy)
pushed a commit
that referenced
this pull request
Jul 30, 2026
Hooks v2 now runs only when `DEEPAGENTS_CODE_EXPERIMENTAL` is enabled; legacy hooks are unaffected. --- Hooks v2 is still in progress but already loads and runs user-authored hook commands in every session. `_load_runtime` is the only production site that builds a `HooksRuntime`, so returning `None` there unless the experimental flag is truthy leaves `HooksManager` inert — client lifecycle events no-op and transcripts are discarded — and `apply_hooks_context` strips the hook snapshot id and server-event gate from the graph context, which keeps `ServerHooksMiddleware` closed for `PreToolUse`, `PostToolUse`, `Stop`, and subagent events. Legacy hooks dispatch through a separate path guarded by `has_handlers` checks, so they keep firing exactly as before. Gating at that single seam was preferred over per-call-site checks: every other `HooksManager` construction already passes no runtime, so one gate covers both the interactive and headless clients plus `reload`. Two existing `TestLiveApprovalModeWrites` tests patch `HooksRuntime.create` as their session-construction probe, so they now enable the flag explicitly. <details> <summary>Test plan</summary> - `tests/unit_tests/hooks` (173), `test_app.py` (1341), `test_non_interactive.py` (116), Textual adapter + offload (290), agent / tool-stream / legacy-hooks / local-context / server-helpers (468) all pass. - New `test_hooks_v2_requires_experimental_flag` asserts `HooksManager.create(...).enabled` flips with the flag. </details> Made by [Open SWE](https://openswe.vercel.app/agents/019faecf-b901-755b-abc4-e2c4f5e90726) --------- Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Mason Daugherty (mdrxy)
pushed a commit
that referenced
this pull request
Jul 30, 2026
> [!CAUTION] > Merging this PR will automatically publish to **PyPI** and create a **GitHub release**. For the full release process, see [`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md). --- _Release notes preview: keep this section in sync with the package `CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`, not this PR description — keep them aligned anyway so the PR stays an accurate historical record for reviewers and anyone returning later._ --- ## [0.1.50](deepagents-code==0.1.49...deepagents-code==0.1.50) (2026-07-30) ### Highlights - Added project hooks workspace trust and expanded Hooks v2 support with client and server lifecycle events plus runtime feedback ([#5105](#5105), [#5104](#5104), [#4997](#4997), [#5045](#5045)). - Added an option to mute the “YOLO is active” toast ([#5103](#5103)). - Made the splash screen `thread` ID clickable to copy it ([#5173](#5173)). - Show `ask_user` answers directly on the answered tool row ([#5100](#5100)). - Show a toast when submitting an empty required `ask_user` answer ([#5095](#5095)). - Added thread message counts to the Debug Console ([#5117](#5117)). ### Fixes and improvements - Gated Hooks v2 behind `DEEPAGENTS_CODE_EXPERIMENTAL` and improved hook resume stability across identity and Command tool results ([#5146](#5146), [#5176](#5176)). - Kept server hook state out of task results ([#5164](#5164)). - Stopped duplicate Auto transcript events during interrupt replay ([#5157](#5157)). - Kept `/update` and `/install --package` prompts responsive ([#5127](#5127)). - Refreshed the `/threads` cache after each turn ([#5174](#5174)). - Anchored toasts above the chat input and added a toast when media is dropped into a free-text question ([#5101](#5101), [#5099](#5099)). - Improved thread status message styling and links ([#5118](#5118)). - Made resume hints echo the launched command name ([#5119](#5119)). - Scoped selection copy to the clicked screen ([#5140](#5140)). - Ignored mouse hits on detached widgets ([#5114](#5114)). _End release notes preview._ --- > [!NOTE] > A **New Contributors** section is appended to the GitHub release notes automatically at publish time (see [Release Pipeline](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md#release-pipeline), step 2). --------- Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> Co-authored-by: langchain-oss-automated-triage[bot] <248757908+langchain-oss-automated-triage[bot]@users.noreply.github.com> Co-authored-by: Johannes du Plessis <johannes@langchain.dev>
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.
Hooks v2 now runs only when
DEEPAGENTS_CODE_EXPERIMENTALis enabled; legacy hooks are unaffected.Hooks v2 is still in progress but already loads and runs user-authored hook commands in every session.
_load_runtimeis the only production site that builds aHooksRuntime, so returningNonethere unless the experimental flag is truthy leavesHooksManagerinert — client lifecycle events no-op and transcripts are discarded — andapply_hooks_contextstrips the hook snapshot id and server-event gate from the graph context, which keepsServerHooksMiddlewareclosed forPreToolUse,PostToolUse,Stop, and subagent events. Legacy hooks dispatch through a separate path guarded byhas_handlerschecks, so they keep firing exactly as before.Gating at that single seam was preferred over per-call-site checks: every other
HooksManagerconstruction already passes no runtime, so one gate covers both the interactive and headless clients plusreload.Two existing
TestLiveApprovalModeWritestests patchHooksRuntime.createas their session-construction probe, so they now enable the flag explicitly.Test plan
tests/unit_tests/hooks(173),test_app.py(1341),test_non_interactive.py(116), Textual adapter + offload (290), agent / tool-stream / legacy-hooks / local-context / server-helpers (468) all pass.test_hooks_v2_requires_experimental_flagassertsHooksManager.create(...).enabledflips with the flag.Made by Open SWE