feat(sdk,code,quickjs): lean system prompt by default, restorable - #4859
Conversation
Ship the no-system-prompt behavior as the SDK default. BASE_AGENT_PROMPT
is now empty and the built-in middleware system-prompt fragments
(todo / filesystem / skills / subagent / memory) are suppressed. Tools
and their schema descriptions are untouched, so the default agent stays
functional.
Both removed pieces are restorable:
- The authored base prose moves to a new exported DEFAULT_AGENT_PROMPT;
restore with system_prompt={"base": DEFAULT_AGENT_PROMPT}.
- New create_deep_agent(builtin_middleware_prompts=False) gates the
middleware guidance across the main, subagent, and general-purpose
stacks; pass True to restore it.
The Code CLI passes builtin_middleware_prompts=True so its shipped
behavior is unchanged (its own system_prompt.md base already overrides
the SDK base).
The control over the built-in middleware system-prompt fragments is internal wiring for first-party harnesses (the Code CLI), not a public knob, so rename the create_deep_agent parameter from builtin_middleware_prompts to _builtin_middleware_prompts, matching the repo's _permissions convention. The publicly restorable piece (the base prose) stays public via DEFAULT_AGENT_PROMPT.
OpenSWE review flagged that suppressing the skills and memory middleware system prompts silently disables those features. Their fragment is the only channel that surfaces the loaded skill index and memory content (no tool carries it), and both middleware are built only when the caller passes skills=/memory=. Exempt Skills and Memory from suppression so they always emit their fragment regardless of _builtin_middleware_prompts. The flag still governs the pure usage-guidance prose (todo / filesystem / subagent / async-subagent); their tools (and the task tool's available- agent list) keep the model's discovery intact. Also regenerate the quickjs SDK-drift smoke snapshots for the now-empty base and suppressed usage prose.
…ressed Audit follow-up to the middleware suppression. FilesystemMiddleware's system_prompt bundles usage-guidance prose with a dynamic host-path routing section (virtual->host mapping for the `execute` shell on a CompositeBackend with FilesystemBackend routes). Suppressing the prose via system_prompt="" dropped the routing too, which is essential per-backend config the model cannot reconstruct from tool descriptions. Treat routing as config, not prose: append it whenever the execute tool is active, even when the system_prompt is overridden or suppressed. The non-custom (system_prompt=None) path is unchanged and byte-identical, so existing snapshots do not move; only the suppressed path regains routing. The eval harness could not have caught this: make_bare_graph uses a single LocalShellBackend and make_tau3_graph a StateBackend, so the routing section was always empty in evals.
Make the middleware-prose control public and reframe it: it trims the built-in tool-usage guidance prose that duplicates the tool schemas, not "all middleware prompts". Rename `_builtin_middleware_prompts` (default False) to `trim_duplicate_tool_prompts` (default True); the polarity flips so the trimmed/lean behavior stays the default. Skills, memory, and the filesystem host-path routing section are never trimmed (they carry information the tool schemas do not). The Code CLI now passes `trim_duplicate_tool_prompts=False` to keep its full guidance.
| system_prompt=resolved_system_prompt, | ||
| # The SDK trims the built-in tool-usage guidance prose by default; the | ||
| # CLI keeps it to preserve its shipped behavior. | ||
| trim_duplicate_tool_prompts=False, |
There was a problem hiding this comment.
I don't think we should leave this configurable. who would ever want this to be False? IMO we change the prompts in 0.7.
There was a problem hiding this comment.
ok what if someone really wants it back?
There was a problem hiding this comment.
removed for now
| - `prefix`: text before the base (same as passing a bare string). | ||
| - `base`: replace the built-in base prompt; omit the key to keep | ||
| it, or set it to `None` to drop the base entirely. | ||
| - `base`: replace the base prompt; omit the key to keep the default |
There was a problem hiding this comment.
we intend to drop the system_prompt configurability that was added earlier in the 0.7 alpha period. I appreciate keeping things consistent but this will just add merge conflicts when we revert.
| # The default base prompt is empty, so no authored base prose is added. | ||
| assert "You are a deep agent" not in content |
There was a problem hiding this comment.
should we just delete this assertion? do snapshot tests cover?
There was a problem hiding this comment.
yeah fixed now
Per review: the tool-prose trimming should not be configurable. Remove the public `trim_duplicate_tool_prompts` flag from `create_deep_agent` and always trim the built-in tool-usage guidance that duplicates the tool schemas (todo / filesystem / subagent / async-subagent). The Code CLI no longer opts out, so its shipped prompt drops that redundant prose too (its own system_prompt.md already covers tool usage). Skills, memory, and the filesystem host-path routing section are still never trimmed. Also revert the consistency edits to the `system_prompt` docstring to avoid merge conflicts when that config is reverted, and drop the redundant "no base prose" assertions now covered by the empty-base snapshots.
| backend=backend, | ||
| custom_tool_descriptions=_profile.tool_description_overrides, | ||
| _permissions=permissions, | ||
| system_prompt="", |
There was a problem hiding this comment.
how do we feel about all the dead code here?
| backend=backend, | ||
| custom_tool_descriptions=_profile.tool_description_overrides, | ||
| _permissions=permissions, | ||
| system_prompt="", |
There was a problem hiding this comment.
if we haven't already, we need to audit the content we're losing from system prompts (i.e., is not duplicated in tool descriptions) and convince ourselves we don't want them.
some things we lose:
- behavior around large tool result eviction (I guess you can infer what happened from the tool messages?)
- virtual mount paths for execute
- guidance not to call todo list multiple times in parallel
…iptions The audit of what prompt-trimming drops surfaced two medium-severity items not otherwise recoverable from the tool schemas. Migrate them into the always-visible tool descriptions (the durable channel) so they survive: - read_file / grep: large tool results are offloaded to files under a large_tool_results/ directory, and how to read / search them. - check_async_task / list_async_tasks: statuses shown earlier in the conversation are stale, so re-check rather than reporting a prior status. Add guard tests and regenerate the *_tools.json smoke snapshots.
… root Per review: offloaded tool results live under the configured artifacts_root (e.g. /workspace/large_tool_results/...), not always /large_tool_results/. The static grep guidance now names the `large_tool_results/` subdirectory inside the artifacts root (/large_tool_results/ by default) rather than implying root, and read_file simply points at the exact path the tool message provides.
Eliminate the build-then-blank pattern. The deepagents-owned middleware (filesystem / subagent / async-subagent) now default to emitting no built-in tool-usage prose, so create_deep_agent no longer constructs full prompts and suppresses them with system_prompt="". Delete FilesystemMiddleware's now-unreachable dynamic prompt build (and its helper + unit tests); it emits only the dynamic host-path routing section, which is empty for non-composite backends. TodoListMiddleware is langchain's, so it is the one middleware still passed system_prompt="". The trimmed prose stays available as constants (FILESYSTEM_SYSTEM_PROMPT, EXECUTION_SYSTEM_PROMPT, TASK_SYSTEM_PROMPT, ASYNC_TASK_SYSTEM_PROMPT) for callers who want to add it back. Net behavior is unchanged (still trimmed); snapshots are untouched.
…ants Follow-up to the lean-default refactor. Remove the now-unused built-in tool-usage prose entirely: FILESYSTEM_SYSTEM_PROMPT, EXECUTION_SYSTEM_PROMPT, TASK_SYSTEM_PROMPT, ASYNC_TASK_SYSTEM_PROMPT, and the dead filesystem prompt-rendering helpers (_FILESYSTEM_SYSTEM_PROMPT_TEMPLATE, _build_fs_tools_section, _FS_TOOL_DESCRIPTION_LINES). Also drop the integration test that asserted the removed execution-prose behavior. No behavior change (the constants were unused after the previous commit); snapshots are untouched.
| """ | ||
|
|
||
|
|
||
| BASE_AGENT_PROMPT = "" |
There was a problem hiding this comment.
what's the point of this?
…-prompt # Conflicts: # libs/deepagents/deepagents/middleware/filesystem.py # libs/deepagents/tests/unit_tests/test_middleware.py # libs/partners/quickjs/uv.lock
…-prompt # Conflicts: # libs/deepagents/deepagents/middleware/filesystem.py # libs/deepagents/deepagents/middleware/summarization.py # libs/deepagents/tests/integration_tests/test_filesystem_middleware.py
| ) | ||
|
|
||
| __all__ = [ | ||
| "BASE_AGENT_PROMPT", |
There was a problem hiding this comment.
idt we should export this
| messages: Required[Annotated[list[AnyMessage], DeltaChannel(_messages_delta_reducer, snapshot_frequency=50)]] # ty: ignore[invalid-argument-type] | ||
|
|
||
|
|
||
| BASE_AGENT_PROMPT = """You are a deep agent, an AI assistant that helps users accomplish tasks using tools. You respond with text and tool calls. The user can see your responses and tool outputs in real time. |
There was a problem hiding this comment.
i thought we wanted to remove this whole thing
## Summary The SDK currently ships authored base prose plus middleware guidance that largely duplicates the tool schemas. This change adopts a more lean default: no authored base prompt, no duplicate built-in usage prose, and concise tool descriptions. Skills, memory, custom system prompts, custom tool descriptions, and required filesystem routing context remain intact. The legacy base-prompt surface is removed rather than preserved as a default path. ## Changes ### Default prompt - Remove the authored default base prompt and its obsolete public surface. - Suppress LangChain's default todo middleware prompt while leaving deepagents-owned middleware prompt-free by default. - Remove unused filesystem, subagent, async-subagent, and execution prompt constants and exports. ### Durable tool guidance - Keep large-result recovery guidance in `read_file` and `grep` descriptions. - Keep async task status freshness guidance in `check_async_task` and `list_async_tasks` descriptions. - Trim filesystem and task descriptions to their purpose and load-bearing constraints. - Build grep and execute descriptions from the configured filesystem tool set so they do not recommend unavailable tools. ### Token impact Offline (`o200k_base`, default-agent tool schemas): | Tool | Before | After | Delta | | --- | ---: | ---: | ---: | | `task` | 1,664 | 389 | -77% | | `read_file` | 728 | 494 | -32% | | `grep` | 688 | 555 | -19% | | `edit_file` | 273 | 257 | -6% | | `glob` | 217 | 172 | -21% | | `write_file` | 177 | 177 | — | | `delete` | 146 | 146 | — | | `ls` | 111 | 111 | — | | **Total** | **4,005** | **2,302** | **-43%** | For a default-agent `hello` turn, input tokens drop from 5,395 to 1,895 (-65%). ### Evaluation results The lean prompt matched the baseline on correctness (0.81) and solve rate (0.635 vs. 0.634). Unified evaluation macro and micro scores improved from 0.413 to 0.437 and from 0.371 to 0.394, respectively. (see more detailed results in langchain-ai/deepagents#5009 and langchain-ai/deepagents#4859)
> [!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.0](deepagents==0.6.12...deepagents==0.7.0) (2026-07-29) See [the docs](https://docs.langchain.com/oss/python/releases/changelog#deepagents-v0-7-0) for curated release notes. ### ⚠ BREAKING CHANGES * `create_deep_agent` no longer includes `TodoListMiddleware` by default, the `write_todos` tool, `todos` state channel, and todo-planning prompt are now absent. Pass `middleware=[TodoListMiddleware()]` to restore them on the main agent; add it to each `SubAgent`'s middleware to restore them there. ([#4929](#4929)) ([9340518](9340518)) * Default agent prompts are now lean: the authored base prompt is empty, and tool-usage prose that duplicates tool schemas is trimmed. `BASE_AGENT_PROMPT` is deprecated (removal in `deepagents==0.9.0`) but remains importable and still returns the previous authored prompt verbatim; pass it as `create_deep_agent(system_prompt=BASE_AGENT_PROMPT)` to restore the old behavior. ([#4859](#4859)) ([#4979](#4979)) ([a8d1b32](a8d1b32)) ([d9f54fc](d9f54fc)) * The built-in tool-usage prompt constants `TASK_SYSTEM_PROMPT`, `ASYNC_TASK_SYSTEM_PROMPT`, `SUMMARIZATION_SYSTEM_PROMPT`, `FILESYSTEM_SYSTEM_PROMPT`, and `EXECUTION_SYSTEM_PROMPT` are removed, and the `system_prompt` default on `SubAgentMiddleware`, `AsyncSubAgentMiddleware`, `SummarizationToolMiddleware`, and `create_summarization_tool_middleware` is now `None`, which injects no prose. Pass your own string to restore prompt text. ([#4859](#4859)) ([a8d1b32](a8d1b32)) * `FilesystemBackend` and `LocalShellBackend` now default to `virtual_mode=True`. Filesystem paths are anchored under `root_dir`, `..` traversal is rejected, and paths resolving outside `root_dir` raise `ValueError`. Previously an unspecified `virtual_mode` emitted a deprecation warning and fell back to `False`, where absolute host paths were used as-is and `..` could escape `root_dir`. Pass `virtual_mode=False` explicitly to restore the old filesystem behavior. ([#4541](#4541)) ([540a0fa](540a0fa)) * Agents now see a destructive, recursive `delete` filesystem tool whenever the backend supports it, and filesystem permissions classify `delete` as a write operation — so an existing rule allowing writes to a path also authorizes recursively deleting that subtree unless a narrower deny or interrupt rule covers the target. Because recursive deletes affect descendants, deny and interrupt checks use bulk path overlap instead of exact-path matching. To keep the previous behavior, add a deny or interrupt rule, or omit `delete` from `FilesystemMiddleware(tools=...)`. Missing paths return a not-found error, `CompositeBackend` reports an unsupported-operation error when a routed sub-backend cannot delete, and the tool is hidden from the model entirely when the backend itself does not implement it. ([#3659](#3659)) ([#3691](#3691)) ([#3765](#3765)) ([#3851](#3851)) ([f2a21ec](f2a21ec)) * `write_file` can now create a file if it is missing and replaces it entirely if it already exists, instead of returning a file-exists error. The `write_file` tool description no longer requires reading the file first. There is no "create-only" compatibility mode. Workflows, prompts, tests, or guardrails that relied on the file-exists error to force `edit_file` usage or to protect existing content must omit `write_file`, add explicit permission or interrupt rules, or use `edit_file` where preserving existing content matters. ([#4109](#4109)) ([2506fcc](2506fcc)) * Removed deprecated backend compatibility shims. Callers must pass concrete `BackendProtocol` instances (not factories), configure `StoreBackend` with an explicit `namespace`, and use the current `ls` / `glob` / `grep` / `ReadResult` APIs. ([#4541](#4541)) ([540a0fa](540a0fa)) * The deprecated `files_update` attribute and constructor keyword are removed from `WriteResult` and `EditResult`. Custom backends must stop passing `files_update=`, and callers must stop reading `result.files_update`; state writes are emitted directly by `StateBackend`. ([#4541](#4541)) ([540a0fa](540a0fa)) * Removed the deprecated `BackendProtocol` methods `ls_info`, `als_info`, `glob_info`, `aglob_info`, `grep_raw`, and `agrep_raw`. Use `ls` / `glob` / `grep` and their async counterparts. ([#4541](#4541)) ([540a0fa](540a0fa)) * `SummarizationMiddleware(history_path_prefix=...)` was removed and now raises `TypeError`. Configure `CompositeBackend(artifacts_root=...)` instead. ([#4541](#4541)) ([540a0fa](540a0fa)) * Agent-facing `ls` and `glob` tool output now renders empty results as `No files found` instead of `[]`; direct backend APIs continue to return structured empty `LsResult` and `GlobResult` values. Callers that parse tool output should update those checks. ([#3709](#3709)) ([efafd1e](efafd1e)) * `read_file` no longer renders raw text with a fixed-width `cat -n`-style line-number gutter and tab separator. Line and continuation markers are dynamically aligned and separated from source content by two spaces, and the `LINE_NUMBER_WIDTH` constant is removed from `deepagents.backends.utils` and `deepagents.middleware.filesystem`. Callers that parse raw tool output should update those parsers. ([#4561](#4561)) ([cf057b4](cf057b4)) ### Features * Custom middleware passed to `create_deep_agent(..., middleware=[...])` can replace a default middleware instance when `.name` matches, so defaults such as `SummarizationMiddleware` can be overridden without also excluding the built-in instance. ([#4251](#4251)) ([90c8472](90c8472)) * `FilesystemMiddleware(tools=[...])` accepts a keyword-only allowlist of built-in filesystem tools, typed by the newly exported `FsToolName` literal (`"ls"`, `"read_file"`, `"write_file"`, `"edit_file"`, `"delete"`, `"glob"`, `"grep"`, `"execute"`); pass `"all"` or omit the argument to keep every tool. A list must include `"read_file"` or the constructor raises `ValueError`. Omitted built-in tools are non-executable, and custom user tools are unaffected. ([#4325](#4325)) ([#4698](#4698)) ([704a70d](704a70d)) ([9709525](9709525)) * Shorten LLM-facing descriptions for the `task` tool and filesystem tools (`read_file`, `grep`, `edit_file`, `glob`, `execute`). ([#5009](#5009)) ([761f5f0](761f5f0)) * `GrepResult` and `GlobResult` now carry a `truncated` flag so supporting backends can return valid partial results when a match cap or backend deadline is reached; agent-facing tool output adds a note telling the model to narrow the search. `FilesystemBackend` returns partial `grep` and `glob` results on its backend timeout rather than erroring, while other backend or middleware timeouts may still return errors. Its `glob` also gains brace expansion such as `*.{py,md}` (already supported by the state and store backends). ([#4063](#4063)) ([ef591e7](ef591e7)) * The agent-facing `grep` match cap is configurable: `FilesystemMiddleware(grep_max_count=...)` sets the default (`1000`; `None` disables it) and the model can override it per call through the tool's new `max_count` argument. `grep` / `agrep` on `BackendProtocol` and all built-in backends accept a keyword-only `max_count`. Local ripgrep output is streamed and terminated once the cap is reached. Direct `FilesystemBackend.grep()` callers can request surrounding lines with keyword-only `context_lines`. ([#4570](#4570)) ([#4706](#4706)) ([8e86f5e](8e86f5e)) ([65230df](65230df)) * Paginated built-in `read_file` responses report the returned source-line range and next `offset`; total and remaining line counts are included when the backend knows the file length. Resume offsets remain safe when sandbox or middleware limits shorten the visible page. ([#4540](#4540)) ([8321194](8321194)) * Optional video frame extraction for `read_file`, enabled by the new `deepagents[video]` extra. Video files are sampled into JPEG frames, with `offset` and `limit` interpreted as seconds. Without the extra, existing generic video/file content-block behavior remains. ([#4094](#4094)) ([b927147](b927147)) * `FilesystemMiddleware` can capture oversized `execute` tool output directly inside the sandbox artifact path on compatible, opted-in `BaseSandbox` implementations to reduce round trips; `LangSmithSandbox` opts in by default. ([#4230](#4230)) ([02f5bd7](02f5bd7)) * Automatically enable Fireworks prompt-cache session affinity when a compatible `langchain-fireworks` installation is available. ([#4598](#4598)) ([5d878bf](5d878bf)) * Add a built-in NVIDIA Nemotron 3 Ultra harness profile and NVIDIA NIM app-origin attribution. ([#4192](#4192)) ([#4455](#4455)) ([d5a60ec](d5a60ec)) ([4cb4749](4cb4749)) * `RubricMiddleware` now accepts any positive `max_iterations` cap instead of enforcing a hard upper bound. ([#4405](#4405)) ([d6692a7](d6692a7)) ### Bug Fixes * Keep fields marked with `PrivateStateAttr`, including fields declared through `create_deep_agent(state_schema=...)`, out of subagent inputs and returned parent-state updates. ([#4587](#4587)) ([a4662c0](a4662c0)) * Preserve `ContextT` through the `create_deep_agent(..., middleware=[...])` type annotation so type checkers accept context-aware middleware when a matching `context_schema` is passed. ([#4055](#4055)) ([7be76c7](7be76c7)) * Accept YAML list values as well as comma-separated strings for skill `allowed-tools` frontmatter, and make skill truncation warnings actionable with field name, path, length, configured limit, and impact. ([#4140](#4140)) ([#4141](#4141)) ([d62534c](d62534c)) ([2f5f5b8](2f5f5b8)) * Align filesystem instructions with the tools that remain after allowlist and backend-capability filtering, so agents no longer reference hidden `grep`/`glob` tools or prohibit equivalent shell search when dedicated search tools are unavailable. ([#4920](#4920)) ([#4921](#4921)) ([d3650c7](d3650c7)) ([b65cc00](b65cc00)) * Propagate default-backend failures from `CompositeBackend.ls("/")` and `CompositeBackend.als("/")` instead of returning successful route-only listings. ([#4925](#4925)) ([4c3b166](4c3b166)) * Correct `CompositeBackend.glob` / `CompositeBackend.aglob` routing so explicit default-backend paths such as `/tools` do not also return files from routed backends such as `/memories`. ([#4531](#4531)) ([cbdb0a7](cbdb0a7)) * Propagate default- and routed-backend failures from root `CompositeBackend.glob(..., path=None)` / `aglob(..., path=None)` and `path="/"` searches instead of returning incomplete successful results. ([#4063](#4063)) ([ef591e7](ef591e7)) * Constrain sandbox `glob` and slash-pattern `grep` searches to their declared search root by treating leading `/` as search-root-relative, rejecting `..` traversal segments, and filtering symlink-resolved matches outside the root. ([#4588](#4588)) ([c6c7213](c6c7213)) * Unify `grep(..., glob=...)` include-glob semantics across filesystem and in-memory backends: basename patterns like `*.py` match at any depth, and slash-containing patterns like `src/**/*.py` match relative paths consistently. ([#3936](#3936)) ([feab6e0](feab6e0)) * Improve agent-facing `grep` descriptions and no-match hints to steer regex-looking patterns toward literal searches, route slash-containing sandbox include-globs correctly, and shorten default search timeouts so bad patterns and huge trees return guidance faster. ([#4168](#4168)) ([b1dbf5e](b1dbf5e)) * Align sandbox delete behavior with other backends by returning not-found errors for missing paths, and avoid over-blocking unrelated sibling deletes when deny rules use glob patterns. ([#4321](#4321)) ([d77496b](d77496b)) * Improve rubric grader failure diagnostics with configured model, structured-output strategy, and integer HTTP status when available. ([#4938](#4938)) ([#4967](#4967)) ([f51d3a0](f51d3a0)) ([bca70aa](bca70aa)) * Emit `max_iterations_reached` as the terminal `RubricMiddleware` status when the iteration cap is exhausted, instead of a final `needs_revision` event that will not loop. ([#4406](#4406)) ([a51c8d2](a51c8d2)) * Handle missing async subagent URLs consistently in `check_async_task` and `cancel_async_task`. ([#3967](#3967)) ([b0d92c0](b0d92c0)) ### Performance Improvements * Run LangSmith sandbox commands over the async client. ([#5061](#5061)) ([0d08747](0d08747)) --- _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: Mason Daugherty <github@mdrxy.com>
…ngchain-ai#4859) ## Problem The SDK shipped a full authored base prompt plus built-in middleware tool-usage prose that largely duplicates the tools' own schemas. The System Prompt Experiments found no arm statistically distinguishable, so parsimony argues for the leanest agent. ## Change - `BASE_AGENT_PROMPT = ""`; the authored prose is preserved as an exported `DEFAULT_AGENT_PROMPT` (restore via `system_prompt={"base": DEFAULT_AGENT_PROMPT}`). - The built-in tool-usage guidance prose that duplicates the tool schemas (todo / filesystem / subagent) is trimmed unconditionally. This applies everywhere, including the Code CLI (its own `system_prompt.md` already covers tool usage). - Skills/memory content and the filesystem host-path routing section are never trimmed: they carry information the schemas don't. ## Testing deepagents + quickjs unit suites, `ruff`, and `ty` all green. Deferred (non-blocking): profile tuning-suffix hooks unchanged, `libs/acp` on the trimmed default, persona-to-user-memory not seeded.
> [!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.0](langchain-ai/deepagents@deepagents==0.6.12...deepagents==0.7.0) (2026-07-29) See [the docs](https://docs.langchain.com/oss/python/releases/changelog#deepagents-v0-7-0) for curated release notes. ### ⚠ BREAKING CHANGES * `create_deep_agent` no longer includes `TodoListMiddleware` by default, the `write_todos` tool, `todos` state channel, and todo-planning prompt are now absent. Pass `middleware=[TodoListMiddleware()]` to restore them on the main agent; add it to each `SubAgent`'s middleware to restore them there. ([langchain-ai#4929](langchain-ai#4929)) ([9340518](langchain-ai@9340518)) * Default agent prompts are now lean: the authored base prompt is empty, and tool-usage prose that duplicates tool schemas is trimmed. `BASE_AGENT_PROMPT` is deprecated (removal in `deepagents==0.9.0`) but remains importable and still returns the previous authored prompt verbatim; pass it as `create_deep_agent(system_prompt=BASE_AGENT_PROMPT)` to restore the old behavior. ([langchain-ai#4859](langchain-ai#4859)) ([langchain-ai#4979](langchain-ai#4979)) ([a8d1b32](langchain-ai@a8d1b32)) ([d9f54fc](langchain-ai@d9f54fc)) * The built-in tool-usage prompt constants `TASK_SYSTEM_PROMPT`, `ASYNC_TASK_SYSTEM_PROMPT`, `SUMMARIZATION_SYSTEM_PROMPT`, `FILESYSTEM_SYSTEM_PROMPT`, and `EXECUTION_SYSTEM_PROMPT` are removed, and the `system_prompt` default on `SubAgentMiddleware`, `AsyncSubAgentMiddleware`, `SummarizationToolMiddleware`, and `create_summarization_tool_middleware` is now `None`, which injects no prose. Pass your own string to restore prompt text. ([langchain-ai#4859](langchain-ai#4859)) ([a8d1b32](langchain-ai@a8d1b32)) * `FilesystemBackend` and `LocalShellBackend` now default to `virtual_mode=True`. Filesystem paths are anchored under `root_dir`, `..` traversal is rejected, and paths resolving outside `root_dir` raise `ValueError`. Previously an unspecified `virtual_mode` emitted a deprecation warning and fell back to `False`, where absolute host paths were used as-is and `..` could escape `root_dir`. Pass `virtual_mode=False` explicitly to restore the old filesystem behavior. ([langchain-ai#4541](langchain-ai#4541)) ([540a0fa](langchain-ai@540a0fa)) * Agents now see a destructive, recursive `delete` filesystem tool whenever the backend supports it, and filesystem permissions classify `delete` as a write operation — so an existing rule allowing writes to a path also authorizes recursively deleting that subtree unless a narrower deny or interrupt rule covers the target. Because recursive deletes affect descendants, deny and interrupt checks use bulk path overlap instead of exact-path matching. To keep the previous behavior, add a deny or interrupt rule, or omit `delete` from `FilesystemMiddleware(tools=...)`. Missing paths return a not-found error, `CompositeBackend` reports an unsupported-operation error when a routed sub-backend cannot delete, and the tool is hidden from the model entirely when the backend itself does not implement it. ([langchain-ai#3659](langchain-ai#3659)) ([langchain-ai#3691](langchain-ai#3691)) ([langchain-ai#3765](langchain-ai#3765)) ([langchain-ai#3851](langchain-ai#3851)) ([f2a21ec](langchain-ai@f2a21ec)) * `write_file` can now create a file if it is missing and replaces it entirely if it already exists, instead of returning a file-exists error. The `write_file` tool description no longer requires reading the file first. There is no "create-only" compatibility mode. Workflows, prompts, tests, or guardrails that relied on the file-exists error to force `edit_file` usage or to protect existing content must omit `write_file`, add explicit permission or interrupt rules, or use `edit_file` where preserving existing content matters. ([langchain-ai#4109](langchain-ai#4109)) ([2506fcc](langchain-ai@2506fcc)) * Removed deprecated backend compatibility shims. Callers must pass concrete `BackendProtocol` instances (not factories), configure `StoreBackend` with an explicit `namespace`, and use the current `ls` / `glob` / `grep` / `ReadResult` APIs. ([langchain-ai#4541](langchain-ai#4541)) ([540a0fa](langchain-ai@540a0fa)) * The deprecated `files_update` attribute and constructor keyword are removed from `WriteResult` and `EditResult`. Custom backends must stop passing `files_update=`, and callers must stop reading `result.files_update`; state writes are emitted directly by `StateBackend`. ([langchain-ai#4541](langchain-ai#4541)) ([540a0fa](langchain-ai@540a0fa)) * Removed the deprecated `BackendProtocol` methods `ls_info`, `als_info`, `glob_info`, `aglob_info`, `grep_raw`, and `agrep_raw`. Use `ls` / `glob` / `grep` and their async counterparts. ([langchain-ai#4541](langchain-ai#4541)) ([540a0fa](langchain-ai@540a0fa)) * `SummarizationMiddleware(history_path_prefix=...)` was removed and now raises `TypeError`. Configure `CompositeBackend(artifacts_root=...)` instead. ([langchain-ai#4541](langchain-ai#4541)) ([540a0fa](langchain-ai@540a0fa)) * Agent-facing `ls` and `glob` tool output now renders empty results as `No files found` instead of `[]`; direct backend APIs continue to return structured empty `LsResult` and `GlobResult` values. Callers that parse tool output should update those checks. ([langchain-ai#3709](langchain-ai#3709)) ([efafd1e](langchain-ai@efafd1e)) * `read_file` no longer renders raw text with a fixed-width `cat -n`-style line-number gutter and tab separator. Line and continuation markers are dynamically aligned and separated from source content by two spaces, and the `LINE_NUMBER_WIDTH` constant is removed from `deepagents.backends.utils` and `deepagents.middleware.filesystem`. Callers that parse raw tool output should update those parsers. ([langchain-ai#4561](langchain-ai#4561)) ([cf057b4](langchain-ai@cf057b4)) ### Features * Custom middleware passed to `create_deep_agent(..., middleware=[...])` can replace a default middleware instance when `.name` matches, so defaults such as `SummarizationMiddleware` can be overridden without also excluding the built-in instance. ([langchain-ai#4251](langchain-ai#4251)) ([90c8472](langchain-ai@90c8472)) * `FilesystemMiddleware(tools=[...])` accepts a keyword-only allowlist of built-in filesystem tools, typed by the newly exported `FsToolName` literal (`"ls"`, `"read_file"`, `"write_file"`, `"edit_file"`, `"delete"`, `"glob"`, `"grep"`, `"execute"`); pass `"all"` or omit the argument to keep every tool. A list must include `"read_file"` or the constructor raises `ValueError`. Omitted built-in tools are non-executable, and custom user tools are unaffected. ([langchain-ai#4325](langchain-ai#4325)) ([langchain-ai#4698](langchain-ai#4698)) ([704a70d](langchain-ai@704a70d)) ([9709525](langchain-ai@9709525)) * Shorten LLM-facing descriptions for the `task` tool and filesystem tools (`read_file`, `grep`, `edit_file`, `glob`, `execute`). ([langchain-ai#5009](langchain-ai#5009)) ([761f5f0](langchain-ai@761f5f0)) * `GrepResult` and `GlobResult` now carry a `truncated` flag so supporting backends can return valid partial results when a match cap or backend deadline is reached; agent-facing tool output adds a note telling the model to narrow the search. `FilesystemBackend` returns partial `grep` and `glob` results on its backend timeout rather than erroring, while other backend or middleware timeouts may still return errors. Its `glob` also gains brace expansion such as `*.{py,md}` (already supported by the state and store backends). ([langchain-ai#4063](langchain-ai#4063)) ([ef591e7](langchain-ai@ef591e7)) * The agent-facing `grep` match cap is configurable: `FilesystemMiddleware(grep_max_count=...)` sets the default (`1000`; `None` disables it) and the model can override it per call through the tool's new `max_count` argument. `grep` / `agrep` on `BackendProtocol` and all built-in backends accept a keyword-only `max_count`. Local ripgrep output is streamed and terminated once the cap is reached. Direct `FilesystemBackend.grep()` callers can request surrounding lines with keyword-only `context_lines`. ([langchain-ai#4570](langchain-ai#4570)) ([langchain-ai#4706](langchain-ai#4706)) ([8e86f5e](langchain-ai@8e86f5e)) ([65230df](langchain-ai@65230df)) * Paginated built-in `read_file` responses report the returned source-line range and next `offset`; total and remaining line counts are included when the backend knows the file length. Resume offsets remain safe when sandbox or middleware limits shorten the visible page. ([langchain-ai#4540](langchain-ai#4540)) ([8321194](langchain-ai@8321194)) * Optional video frame extraction for `read_file`, enabled by the new `deepagents[video]` extra. Video files are sampled into JPEG frames, with `offset` and `limit` interpreted as seconds. Without the extra, existing generic video/file content-block behavior remains. ([langchain-ai#4094](langchain-ai#4094)) ([b927147](langchain-ai@b927147)) * `FilesystemMiddleware` can capture oversized `execute` tool output directly inside the sandbox artifact path on compatible, opted-in `BaseSandbox` implementations to reduce round trips; `LangSmithSandbox` opts in by default. ([langchain-ai#4230](langchain-ai#4230)) ([02f5bd7](langchain-ai@02f5bd7)) * Automatically enable Fireworks prompt-cache session affinity when a compatible `langchain-fireworks` installation is available. ([langchain-ai#4598](langchain-ai#4598)) ([5d878bf](langchain-ai@5d878bf)) * Add a built-in NVIDIA Nemotron 3 Ultra harness profile and NVIDIA NIM app-origin attribution. ([langchain-ai#4192](langchain-ai#4192)) ([langchain-ai#4455](langchain-ai#4455)) ([d5a60ec](langchain-ai@d5a60ec)) ([4cb4749](langchain-ai@4cb4749)) * `RubricMiddleware` now accepts any positive `max_iterations` cap instead of enforcing a hard upper bound. ([langchain-ai#4405](langchain-ai#4405)) ([d6692a7](langchain-ai@d6692a7)) ### Bug Fixes * Keep fields marked with `PrivateStateAttr`, including fields declared through `create_deep_agent(state_schema=...)`, out of subagent inputs and returned parent-state updates. ([langchain-ai#4587](langchain-ai#4587)) ([a4662c0](langchain-ai@a4662c0)) * Preserve `ContextT` through the `create_deep_agent(..., middleware=[...])` type annotation so type checkers accept context-aware middleware when a matching `context_schema` is passed. ([langchain-ai#4055](langchain-ai#4055)) ([7be76c7](langchain-ai@7be76c7)) * Accept YAML list values as well as comma-separated strings for skill `allowed-tools` frontmatter, and make skill truncation warnings actionable with field name, path, length, configured limit, and impact. ([langchain-ai#4140](langchain-ai#4140)) ([langchain-ai#4141](langchain-ai#4141)) ([d62534c](langchain-ai@d62534c)) ([2f5f5b8](langchain-ai@2f5f5b8)) * Align filesystem instructions with the tools that remain after allowlist and backend-capability filtering, so agents no longer reference hidden `grep`/`glob` tools or prohibit equivalent shell search when dedicated search tools are unavailable. ([langchain-ai#4920](langchain-ai#4920)) ([langchain-ai#4921](langchain-ai#4921)) ([d3650c7](langchain-ai@d3650c7)) ([b65cc00](langchain-ai@b65cc00)) * Propagate default-backend failures from `CompositeBackend.ls("/")` and `CompositeBackend.als("/")` instead of returning successful route-only listings. ([langchain-ai#4925](langchain-ai#4925)) ([4c3b166](langchain-ai@4c3b166)) * Correct `CompositeBackend.glob` / `CompositeBackend.aglob` routing so explicit default-backend paths such as `/tools` do not also return files from routed backends such as `/memories`. ([langchain-ai#4531](langchain-ai#4531)) ([cbdb0a7](langchain-ai@cbdb0a7)) * Propagate default- and routed-backend failures from root `CompositeBackend.glob(..., path=None)` / `aglob(..., path=None)` and `path="/"` searches instead of returning incomplete successful results. ([langchain-ai#4063](langchain-ai#4063)) ([ef591e7](langchain-ai@ef591e7)) * Constrain sandbox `glob` and slash-pattern `grep` searches to their declared search root by treating leading `/` as search-root-relative, rejecting `..` traversal segments, and filtering symlink-resolved matches outside the root. ([langchain-ai#4588](langchain-ai#4588)) ([c6c7213](langchain-ai@c6c7213)) * Unify `grep(..., glob=...)` include-glob semantics across filesystem and in-memory backends: basename patterns like `*.py` match at any depth, and slash-containing patterns like `src/**/*.py` match relative paths consistently. ([langchain-ai#3936](langchain-ai#3936)) ([feab6e0](langchain-ai@feab6e0)) * Improve agent-facing `grep` descriptions and no-match hints to steer regex-looking patterns toward literal searches, route slash-containing sandbox include-globs correctly, and shorten default search timeouts so bad patterns and huge trees return guidance faster. ([langchain-ai#4168](langchain-ai#4168)) ([b1dbf5e](langchain-ai@b1dbf5e)) * Align sandbox delete behavior with other backends by returning not-found errors for missing paths, and avoid over-blocking unrelated sibling deletes when deny rules use glob patterns. ([langchain-ai#4321](langchain-ai#4321)) ([d77496b](langchain-ai@d77496b)) * Improve rubric grader failure diagnostics with configured model, structured-output strategy, and integer HTTP status when available. ([langchain-ai#4938](langchain-ai#4938)) ([langchain-ai#4967](langchain-ai#4967)) ([f51d3a0](langchain-ai@f51d3a0)) ([bca70aa](langchain-ai@bca70aa)) * Emit `max_iterations_reached` as the terminal `RubricMiddleware` status when the iteration cap is exhausted, instead of a final `needs_revision` event that will not loop. ([langchain-ai#4406](langchain-ai#4406)) ([a51c8d2](langchain-ai@a51c8d2)) * Handle missing async subagent URLs consistently in `check_async_task` and `cancel_async_task`. ([langchain-ai#3967](langchain-ai#3967)) ([b0d92c0](langchain-ai@b0d92c0)) ### Performance Improvements * Run LangSmith sandbox commands over the async client. ([langchain-ai#5061](langchain-ai#5061)) ([0d08747](langchain-ai@0d08747)) --- _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: Mason Daugherty <github@mdrxy.com>
> [!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.0](deepagents==0.6.12...deepagents==0.7.0) (2026-07-29) See [the docs](https://docs.langchain.com/oss/python/releases/changelog#deepagents-v0-7-0) for curated release notes. ### ⚠ BREAKING CHANGES * `create_deep_agent` no longer includes `TodoListMiddleware` by default, the `write_todos` tool, `todos` state channel, and todo-planning prompt are now absent. Pass `middleware=[TodoListMiddleware()]` to restore them on the main agent; add it to each `SubAgent`'s middleware to restore them there. ([#4929](#4929)) ([9340518](9340518)) * Default agent prompts are now lean: the authored base prompt is empty, and tool-usage prose that duplicates tool schemas is trimmed. `BASE_AGENT_PROMPT` is deprecated (removal in `deepagents==0.9.0`) but remains importable and still returns the previous authored prompt verbatim; pass it as `create_deep_agent(system_prompt=BASE_AGENT_PROMPT)` to restore the old behavior. ([#4859](#4859)) ([#4979](#4979)) ([a8d1b32](a8d1b32)) ([d9f54fc](d9f54fc)) * The built-in tool-usage prompt constants `TASK_SYSTEM_PROMPT`, `ASYNC_TASK_SYSTEM_PROMPT`, `SUMMARIZATION_SYSTEM_PROMPT`, `FILESYSTEM_SYSTEM_PROMPT`, and `EXECUTION_SYSTEM_PROMPT` are removed, and the `system_prompt` default on `SubAgentMiddleware`, `AsyncSubAgentMiddleware`, `SummarizationToolMiddleware`, and `create_summarization_tool_middleware` is now `None`, which injects no prose. Pass your own string to restore prompt text. ([#4859](#4859)) ([a8d1b32](a8d1b32)) * `FilesystemBackend` and `LocalShellBackend` now default to `virtual_mode=True`. Filesystem paths are anchored under `root_dir`, `..` traversal is rejected, and paths resolving outside `root_dir` raise `ValueError`. Previously an unspecified `virtual_mode` emitted a deprecation warning and fell back to `False`, where absolute host paths were used as-is and `..` could escape `root_dir`. Pass `virtual_mode=False` explicitly to restore the old filesystem behavior. ([#4541](#4541)) ([540a0fa](540a0fa)) * Agents now see a destructive, recursive `delete` filesystem tool whenever the backend supports it, and filesystem permissions classify `delete` as a write operation — so an existing rule allowing writes to a path also authorizes recursively deleting that subtree unless a narrower deny or interrupt rule covers the target. Because recursive deletes affect descendants, deny and interrupt checks use bulk path overlap instead of exact-path matching. To keep the previous behavior, add a deny or interrupt rule, or omit `delete` from `FilesystemMiddleware(tools=...)`. Missing paths return a not-found error, `CompositeBackend` reports an unsupported-operation error when a routed sub-backend cannot delete, and the tool is hidden from the model entirely when the backend itself does not implement it. ([#3659](#3659)) ([#3691](#3691)) ([#3765](#3765)) ([#3851](#3851)) ([f2a21ec](f2a21ec)) * `write_file` can now create a file if it is missing and replaces it entirely if it already exists, instead of returning a file-exists error. The `write_file` tool description no longer requires reading the file first. There is no "create-only" compatibility mode. Workflows, prompts, tests, or guardrails that relied on the file-exists error to force `edit_file` usage or to protect existing content must omit `write_file`, add explicit permission or interrupt rules, or use `edit_file` where preserving existing content matters. ([#4109](#4109)) ([2506fcc](2506fcc)) * Removed deprecated backend compatibility shims. Callers must pass concrete `BackendProtocol` instances (not factories), configure `StoreBackend` with an explicit `namespace`, and use the current `ls` / `glob` / `grep` / `ReadResult` APIs. ([#4541](#4541)) ([540a0fa](540a0fa)) * The deprecated `files_update` attribute and constructor keyword are removed from `WriteResult` and `EditResult`. Custom backends must stop passing `files_update=`, and callers must stop reading `result.files_update`; state writes are emitted directly by `StateBackend`. ([#4541](#4541)) ([540a0fa](540a0fa)) * Removed the deprecated `BackendProtocol` methods `ls_info`, `als_info`, `glob_info`, `aglob_info`, `grep_raw`, and `agrep_raw`. Use `ls` / `glob` / `grep` and their async counterparts. ([#4541](#4541)) ([540a0fa](540a0fa)) * `SummarizationMiddleware(history_path_prefix=...)` was removed and now raises `TypeError`. Configure `CompositeBackend(artifacts_root=...)` instead. ([#4541](#4541)) ([540a0fa](540a0fa)) * Agent-facing `ls` and `glob` tool output now renders empty results as `No files found` instead of `[]`; direct backend APIs continue to return structured empty `LsResult` and `GlobResult` values. Callers that parse tool output should update those checks. ([#3709](#3709)) ([efafd1e](efafd1e)) * `read_file` no longer renders raw text with a fixed-width `cat -n`-style line-number gutter and tab separator. Line and continuation markers are dynamically aligned and separated from source content by two spaces, and the `LINE_NUMBER_WIDTH` constant is removed from `deepagents.backends.utils` and `deepagents.middleware.filesystem`. Callers that parse raw tool output should update those parsers. ([#4561](#4561)) ([cf057b4](cf057b4)) ### Features * Custom middleware passed to `create_deep_agent(..., middleware=[...])` can replace a default middleware instance when `.name` matches, so defaults such as `SummarizationMiddleware` can be overridden without also excluding the built-in instance. ([#4251](#4251)) ([90c8472](90c8472)) * `FilesystemMiddleware(tools=[...])` accepts a keyword-only allowlist of built-in filesystem tools, typed by the newly exported `FsToolName` literal (`"ls"`, `"read_file"`, `"write_file"`, `"edit_file"`, `"delete"`, `"glob"`, `"grep"`, `"execute"`); pass `"all"` or omit the argument to keep every tool. A list must include `"read_file"` or the constructor raises `ValueError`. Omitted built-in tools are non-executable, and custom user tools are unaffected. ([#4325](#4325)) ([#4698](#4698)) ([704a70d](704a70d)) ([9709525](9709525)) * Shorten LLM-facing descriptions for the `task` tool and filesystem tools (`read_file`, `grep`, `edit_file`, `glob`, `execute`). ([#5009](#5009)) ([761f5f0](761f5f0)) * `GrepResult` and `GlobResult` now carry a `truncated` flag so supporting backends can return valid partial results when a match cap or backend deadline is reached; agent-facing tool output adds a note telling the model to narrow the search. `FilesystemBackend` returns partial `grep` and `glob` results on its backend timeout rather than erroring, while other backend or middleware timeouts may still return errors. Its `glob` also gains brace expansion such as `*.{py,md}` (already supported by the state and store backends). ([#4063](#4063)) ([ef591e7](ef591e7)) * The agent-facing `grep` match cap is configurable: `FilesystemMiddleware(grep_max_count=...)` sets the default (`1000`; `None` disables it) and the model can override it per call through the tool's new `max_count` argument. `grep` / `agrep` on `BackendProtocol` and all built-in backends accept a keyword-only `max_count`. Local ripgrep output is streamed and terminated once the cap is reached. Direct `FilesystemBackend.grep()` callers can request surrounding lines with keyword-only `context_lines`. ([#4570](#4570)) ([#4706](#4706)) ([8e86f5e](8e86f5e)) ([65230df](65230df)) * Paginated built-in `read_file` responses report the returned source-line range and next `offset`; total and remaining line counts are included when the backend knows the file length. Resume offsets remain safe when sandbox or middleware limits shorten the visible page. ([#4540](#4540)) ([8321194](8321194)) * Optional video frame extraction for `read_file`, enabled by the new `deepagents[video]` extra. Video files are sampled into JPEG frames, with `offset` and `limit` interpreted as seconds. Without the extra, existing generic video/file content-block behavior remains. ([#4094](#4094)) ([b927147](b927147)) * `FilesystemMiddleware` can capture oversized `execute` tool output directly inside the sandbox artifact path on compatible, opted-in `BaseSandbox` implementations to reduce round trips; `LangSmithSandbox` opts in by default. ([#4230](#4230)) ([02f5bd7](02f5bd7)) * Automatically enable Fireworks prompt-cache session affinity when a compatible `langchain-fireworks` installation is available. ([#4598](#4598)) ([5d878bf](5d878bf)) * Add a built-in NVIDIA Nemotron 3 Ultra harness profile and NVIDIA NIM app-origin attribution. ([#4192](#4192)) ([#4455](#4455)) ([d5a60ec](d5a60ec)) ([4cb4749](4cb4749)) * `RubricMiddleware` now accepts any positive `max_iterations` cap instead of enforcing a hard upper bound. ([#4405](#4405)) ([d6692a7](d6692a7)) ### Bug Fixes * Keep fields marked with `PrivateStateAttr`, including fields declared through `create_deep_agent(state_schema=...)`, out of subagent inputs and returned parent-state updates. ([#4587](#4587)) ([a4662c0](a4662c0)) * Preserve `ContextT` through the `create_deep_agent(..., middleware=[...])` type annotation so type checkers accept context-aware middleware when a matching `context_schema` is passed. ([#4055](#4055)) ([7be76c7](7be76c7)) * Accept YAML list values as well as comma-separated strings for skill `allowed-tools` frontmatter, and make skill truncation warnings actionable with field name, path, length, configured limit, and impact. ([#4140](#4140)) ([#4141](#4141)) ([d62534c](d62534c)) ([2f5f5b8](2f5f5b8)) * Align filesystem instructions with the tools that remain after allowlist and backend-capability filtering, so agents no longer reference hidden `grep`/`glob` tools or prohibit equivalent shell search when dedicated search tools are unavailable. ([#4920](#4920)) ([#4921](#4921)) ([d3650c7](d3650c7)) ([b65cc00](b65cc00)) * Propagate default-backend failures from `CompositeBackend.ls("/")` and `CompositeBackend.als("/")` instead of returning successful route-only listings. ([#4925](#4925)) ([4c3b166](4c3b166)) * Correct `CompositeBackend.glob` / `CompositeBackend.aglob` routing so explicit default-backend paths such as `/tools` do not also return files from routed backends such as `/memories`. ([#4531](#4531)) ([cbdb0a7](cbdb0a7)) * Propagate default- and routed-backend failures from root `CompositeBackend.glob(..., path=None)` / `aglob(..., path=None)` and `path="/"` searches instead of returning incomplete successful results. ([#4063](#4063)) ([ef591e7](ef591e7)) * Constrain sandbox `glob` and slash-pattern `grep` searches to their declared search root by treating leading `/` as search-root-relative, rejecting `..` traversal segments, and filtering symlink-resolved matches outside the root. ([#4588](#4588)) ([c6c7213](c6c7213)) * Unify `grep(..., glob=...)` include-glob semantics across filesystem and in-memory backends: basename patterns like `*.py` match at any depth, and slash-containing patterns like `src/**/*.py` match relative paths consistently. ([#3936](#3936)) ([feab6e0](feab6e0)) * Improve agent-facing `grep` descriptions and no-match hints to steer regex-looking patterns toward literal searches, route slash-containing sandbox include-globs correctly, and shorten default search timeouts so bad patterns and huge trees return guidance faster. ([#4168](#4168)) ([b1dbf5e](b1dbf5e)) * Align sandbox delete behavior with other backends by returning not-found errors for missing paths, and avoid over-blocking unrelated sibling deletes when deny rules use glob patterns. ([#4321](#4321)) ([d77496b](d77496b)) * Improve rubric grader failure diagnostics with configured model, structured-output strategy, and integer HTTP status when available. ([#4938](#4938)) ([#4967](#4967)) ([f51d3a0](f51d3a0)) ([bca70aa](bca70aa)) * Emit `max_iterations_reached` as the terminal `RubricMiddleware` status when the iteration cap is exhausted, instead of a final `needs_revision` event that will not loop. ([#4406](#4406)) ([a51c8d2](a51c8d2)) * Handle missing async subagent URLs consistently in `check_async_task` and `cancel_async_task`. ([#3967](#3967)) ([b0d92c0](b0d92c0)) ### Performance Improvements * Run LangSmith sandbox commands over the async client. ([#5061](#5061)) ([0d08747](0d08747)) --- _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: Mason Daugherty <github@mdrxy.com>
Problem
The SDK shipped a full authored base prompt plus built-in middleware tool-usage prose that largely duplicates the tools' own schemas. The System Prompt Experiments found no arm statistically distinguishable, so parsimony argues for the leanest agent.
Change
BASE_AGENT_PROMPT = ""; the authored prose is preserved as an exportedDEFAULT_AGENT_PROMPT(restore viasystem_prompt={"base": DEFAULT_AGENT_PROMPT}).system_prompt.mdalready covers tool usage).