feat(sdk): add subagent conversation forking - #5714
Merged
Merged
Conversation
Member
|
Closes #4668 — with a shape difference worth noting:
Same underlying capability: forked subagent gets the parent's effective history (same summarization-cutoff logic as isolated subagents) plus the task description. Isolated-by-default is unchanged. Ninaad R. Rao (@NinaadRao) — if the per-call Unaffected related issues: #1359, #2440, #3838, #2512. (Also editing the PR description to include the |
Mason Daugherty (mdrxy)
requested changes
Aug 21, 2026
Mason Daugherty (mdrxy)
left a comment
Member
There was a problem hiding this comment.
- Forks probably shouldn't run prompt-producing middleware. Today a fork builds its middleware stack like any other subagent.
MemoryMiddleware,SkillsMiddleware, and any profile extras each append to the system prompt. But then_ForkSystemMessageMiddlewareruns last and replaces the whole thing with the captured parent message. So that work happens on every call and is thrown away every time. Since a fork's prompt is definitionally the parent's captured prompt, I think we can skip prompt-producing middleware at fork construction and set the captured message as the fork's static prompt? - A forked spec with
system_promptshould raise, not silently drop it. TheNeverannotation only helps typed users; at runtime_resolved_declarative_specfilters the key out, soForkedSubAgent(system_prompt="You are a SQL expert...")runs without complaint and the prompt is silently discarded (the kind of misroutingrequired mode="fork"seems to be designed to prevent). AValueErrorin_validate_subagent_mode(or a sibling validator) would make bad config loud. - Reject duplicate subagent names. The context leak Open SWE flagged is currently avoided only because
subagents_by_nameandsubagent_graphsboth happen to resolve duplicates last-write-wins. That agreement is incidental: aValueErroron duplicate names removes the whole class of bug instead of relying on two maps staying in lockstep.
Contributor
Author
|
Thushanth Bengre (thushanth-bengre-langchain)
force-pushed
the
bengret/feat-subagent-forking
branch
from
August 25, 2026 19:52
e7daa52 to
ff41d48
Compare
Mason Daugherty (mdrxy)
approved these changes
Aug 27, 2026
Thushanth Bengre (thushanth-bengre-langchain)
force-pushed
the
bengret/feat-subagent-forking
branch
from
August 28, 2026 14:38
409bf96 to
01c42f9
Compare
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
…ompt Not needed for type safety -- ty rejects system_prompt on a forked spec either way, whether or not the field is declared. Runtime validation in _validate_subagent_mode already enforces this independently. Removing it also brings system_prompt in line with how skills is already handled (runtime-only, no type-level override), since skills can't get the same treatment -- it's declared on the shared _SubAgentBase, and TypedDict doesn't allow overriding an inherited field's type.
… and cache-parity
…im task-tool-mirror docstring
Thushanth Bengre (thushanth-bengre-langchain)
force-pushed
the
bengret/feat-subagent-forking
branch
from
August 28, 2026 18:15
01c42f9 to
5227e5c
Compare
5 tasks
Thushanth Bengre (thushanth-bengre-langchain)
added a commit
to langchain-ai/deepagentsjs
that referenced
this pull request
Aug 30, 2026
…fety fixes (#800) ## Summary This PR backports a set of fixes that landed later in Python `deepagents`'s equivalent feature (langchain-ai/deepagents#5714) ## What's included - **Dynamic system-message capture and replay** — a fork now gets the parent's actual composed system message (skills, memory, etc.), not a stale static copy, so the prompt cache can hit. - **Identity-preserving preamble** — tells a fork it's continuing a prior conversation, not receiving a fresh request. - **Recursion refusal** — a fork's task tool refuses re-delegation instead of recursing. - **Tool-description hint for the parent** — marks forked subagents in the task tool listing so the parent knows they don't need context restated. - **Memory-middleware parity fix** — forks no longer get memoryMiddleware mirrored in, matching Python. ## Testing - New unit tests: skills-injected system message replay into a fork, rejection of `skills` on a `ForkedSubAgent` at construction, a fork's own attempt to delegate again being refused rather than recursing, and `parentSystemMessageMiddleware` only being installed when a declarative fork is actually present. --------- Signed-off-by: Thushanth Bengre <thushanth.bengre@langchain.dev> Co-authored-by: Hunter Lovell <40191806+hntrl@users.noreply.github.com>
Co-authored-by: Chester Curme <chester.curme@gmail.com>
…m_prompt` param (#6016) Currently: 1. `system_prompt` is forbidden on `ForkedSubAgent` specs 2. `parent_system_prompt` is (usually) required to be passed into SubAgentMiddleware for forked subagents (In `create_deep_agent`, `parent_system_prompt` specifies the base prompt that is not built by middleware.) We can avoid introducing a new param by just allowing `system_prompt` on forked subagent specs. So for forked subagents, `create_deep_agent` appends (1) the parent agent system prompt, and (2) any `system_prompt` found in the spec. Once we do this, we can do away with `ForkedSubAgent` and just have `["handoff", "fork"]` as allowed values for `mode` on SubAgent specs.
ccurme (ccurme)
approved these changes
Sep 1, 2026
Hunter Lovell (hntrl)
approved these changes
Sep 1, 2026
Hunter Lovell (hntrl)
pushed a commit
that referenced
this pull request
Sep 1, 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.7.12](deepagents==0.7.11...deepagents==0.7.12) (2026-09-01) ### Features - Added subagent conversation forking in the SDK ([#5714](#5714)). ### Bug Fixes - Fixed glob sorting to tolerate missing `modified_at` values in the SDK ([#4376](#4376)). _End release notes preview._ --- > [!NOTE] > A **community contributors** list and a **Special thanks** section (crediting the users who filed the issues this release's PRs closed) are 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 3). --------- 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>
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.
Closes #4668.
Adds
ForkedSubAgent, a subagent spec that inherits the parent's effective conversation history and exact system prompt instead of only seeing the task description — useful when a subagent is delegated deep into an investigation and shouldn't have to re-derive context the parent already gathered.mode="fork"is required rather than optional onForkedSubAgent, sinceSubAgent.system_promptis also optional — making both optional would let the two specs collapse into the same shape and get silently misrouted between forking and isolated behavior.Reconstructs history using the same summarization-cutoff logic as isolated subagents (now shared via a common helper), drops the parent's still-unresolved trailing tool-call message so the forked prefix matches what was actually cached, and mirrors in a fresh memory middleware instance when
memory=is configured. Experimental, flagged as such in the docstrings.Note: #4668 proposed a per-call
fork: boolflag on thetasktool; this implements the capability as a spec-levelForkedSubAgenttype instead. A per-call flag can be layered on as a follow-up if the tool-level ergonomics are wanted.