Commit Graph

2233 Commits

Author SHA1 Message Date
Mason Daugherty 02f6eae1d3 Merge remote-tracking branch 'origin/main' into nm/dcode-tools-allowlist
# Conflicts:
#	libs/code/deepagents_code/agent.py
#	libs/code/deepagents_code/main.py
#	libs/code/tests/unit_tests/test_agent.py
#	libs/code/tests/unit_tests/test_main_acp_mode.py
2026-07-17 16:43:27 -04:00
Mason Daugherty a8a05f58f2 feat(code): shutdown toast for deferred exits (#4830)
When quitting waits for unfinished work, `deepagents-code` now shows a
brief "Finishing pending work before exit…" toast so the pause reads as
intentional rather than a hang.

---

`DeepAgentsApp.exit()` only defers teardown when it must wait for an
in-flight agent worker or pending fire-and-forget hooks. That wait was
previously silent, so a user pressing quit could think the app had
frozen. This adds a single toast on exactly that deferred path.

The notification is emitted before scheduling the `_graceful_exit`
coroutine. Because scheduling returns control to the event loop and
teardown is deferred behind at least one `await`, Textual's message pump
gets an opportunity to render the toast before `super().exit()` runs.
Immediate/idle exits skip this branch entirely, no delay is introduced,
and the existing two-second grace period is untouched. A repeated/forced
exit hits the existing force-quit guard before reaching the notify, so
the toast is never duplicated (including when both wait conditions
apply).

Made by [Open
SWE](https://openswe.vercel.app/agents/26e6d24a-3180-4334-b655-4075767ae45b)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 15:57:36 -04:00
Mason Daugherty 3f82114c37 refactor(code): drop config list/ls aliases for config show (#4783)
`dcode config list`/`dcode config ls` are removed; use `dcode config
show` (add `--verbose` to see all option keys).

---

`config list`/`config ls` duplicated `config show`, so this removes both
parser aliases and makes `config show` the sole command for displaying
effective config values and their sources. Drops `list_mode`, the
`config list` JSON label/catalog special-casing, backward-compat
comments, and now-dead paths; `config show --json` keeps effective-only
fields (catalog folded in only with `--verbose`) and always labels the
payload `"config show"`. User-facing suggestions now point at `config
show`/`config show --verbose`. Backward compatibility is intentionally
not preserved.

### Breaking change

`config list --json` was the machine-readable catalog endpoint (its JSON
envelope `command` field was `"config list"` and it always folded in
catalog fields). It is gone: the command no longer parses, and the
catalog fields are now available via `config show --verbose --json`
(payload labeled `"config show"`). Any machine consumer of `config list
--json` must migrate.

Made by [Open
SWE](https://openswe.vercel.app/agents/7351f382-9468-b4dc-2df4-03eaf75ef12f)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 15:48:59 -04:00
dependabot[bot] 68adab563c chore(deps): bump torch from 2.12.1 to 2.13.0 in /libs/talon (#4827)
Bumps [torch](https://github.com/pytorch/pytorch) from 2.12.1 to 2.13.0.
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/pytorch/pytorch/releases">torch's
releases</a>.</em></p>
<blockquote>
<h1>PyTorch 2.13.0 Release Notes</h1>
<ul>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#highlights">Highlights</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#backwards-incompatible-changes">Backwards
Incompatible Changes</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#deprecations">Deprecations</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#new-features">New
Features</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#improvements">Improvements</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#bug-fixes">Bug
fixes</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#performance">Performance</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#documentation">Documentation</a></li>
<li><a
href="https://github.com/pytorch/pytorch/blob/HEAD/#developers">Developers</a></li>
</ul>
<h1>Highlights</h1>
<!-- raw HTML omitted -->
<p>For more details about these highlighted features, you can look at
the release blogpost. Below are the full release notes for this
release.</p>
<h1>Tracked Regressions</h1>
<h3>ROCm wheels break <code>torch.compile</code> on CPU in environments
without a GPU</h3>
<p>Running a <code>torch==2.13.0+rocm7.2</code> wheel in an environment
where no GPU is available (<code>torch.cuda.is_available()</code> is
<code>False</code>) breaks <code>torch.compile</code> on the CPU path:
the first compile raises <code>RuntimeError: Can't detect vectorized ISA
for CPU</code> (<a
href="https://redirect.github.com/pytorch/pytorch/issues/189194">#189194</a>).
This is a regression from <code>torch==2.12.1+rocm7.2</code>, which
compiles CPU code fine (detecting e.g. <code>VecAVX2</code>) in the same
setup. The 2.13 ROCm wheel appears to rely on something present in the
ROCm builder image to detect the CPU vectorized ISA, so it works when
run on a ROCm image but fails on a plain CPU-only image.</p>
<p>Workaround: run the <code>+rocm</code> wheel on a ROCm image, or
install a standard CPU/CUDA build for GPU-less environments.</p>
<h1>Backwards Incompatible Changes</h1>
<ul>
<li>
<p>Stop building CPython 3.13t (free-threaded) binaries (<a
href="https://redirect.github.com/pytorch/pytorch/issues/182951">#182951</a>)</p>
<p>Upstream <code>pypa/manylinux</code> removed CPython 3.13t
(free-threaded) on 2026-05-07, because 3.13t
was experimental and has been superseded by the now-non-experimental
CPython 3.14t. As a result,
PyTorch 2.13 no longer ships <code>cp313t</code> wheels (Linux, Triton,
and related artifacts). Users on the
free-threaded interpreter should move to Python 3.14t.</p>
<p>PyTorch 2.12:</p>
<pre lang="bash"><code># cp313t (free-threaded 3.13) wheels were
available
python3.13t -m pip install torch
</code></pre>
<p>PyTorch 2.13:</p>
</li>
</ul>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/pytorch/pytorch/commit/cf30153c4c131c8164ee7798e5022d810682e2cb"><code>cf30153</code></a>
[release/2.13] Strip +PTX from CUDA arch list on release/RC builds (<a
href="https://redirect.github.com/pytorch/pytorch/issues/188914">#188914</a>)
...</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/3e3e24bd95b010f8f74915f0c30476906e60d4fc"><code>3e3e24b</code></a>
[release/2.13] Restrict cuda-bindings to Python &lt; 3.15 for CUDA 12.9
builds (...</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/7986b068032abf5e22ea51fe7fea63ef5bcaf3b1"><code>7986b06</code></a>
[release/2.13] Bump binary build timeout 280 -&gt; 400 minutes (<a
href="https://redirect.github.com/pytorch/pytorch/issues/188551">#188551</a>)</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/0bdbc268e08fba9debac8f35a8a12e9c008ec0fd"><code>0bdbc26</code></a>
[release/2.13] Add CUDA 12.9 to TORCH_CUDA_ARCH_LIST tables (<a
href="https://redirect.github.com/pytorch/pytorch/issues/188443">#188443</a>)</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/9cabb45ca6e6ed3bb4645c929bcfd07691651f74"><code>9cabb45</code></a>
[release/2.13] Update manywheel docker image pin to 78e737ad (<a
href="https://redirect.github.com/pytorch/pytorch/issues/188409">#188409</a>)</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/78e737ad29420ffc4800e677c51e2a852caf8359"><code>78e737a</code></a>
[release/2.13] Revert &quot;Tighten generalized scatter graph target (<a
href="https://redirect.github.com/pytorch/pytorch/issues/184075">#184075</a>)&quot;
(#...</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/0bb9b5bc24bed3278488372d62d9f2235e9e77e3"><code>0bb9b5b</code></a>
[release/2.13] Revert &quot;dynamo: round-trip torch.cuda.stream ctx mgr
across gr...</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/aaac2bfe460c04a4d41e83e03452d2347f7142b9"><code>aaac2bf</code></a>
[release/2.13] Revert &quot;[Reland] Port D104346887/PR 182675 for
index_add fast ...</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/933081368c3ab64fa2e953217e413b3ba52844e3"><code>9330813</code></a>
Fix build_with_debinfo.py broken by CONFIGURE_DEPENDS globbing (<a
href="https://redirect.github.com/pytorch/pytorch/issues/188192">#188192</a>)</li>
<li><a
href="https://github.com/pytorch/pytorch/commit/4e077a7dcf29167db9e97d86cc62f431905e09f7"><code>4e077a7</code></a>
Remove setuptools upper bound (<a
href="https://redirect.github.com/pytorch/pytorch/issues/188190">#188190</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/pytorch/pytorch/compare/v2.12.1...v2.13.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=torch&package-manager=uv&previous-version=2.12.1&new-version=2.13.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/deepagents/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-17 15:17:41 -04:00
Mason Daugherty a915c590df fix(code): keep chat input responsive during /restart (#4808)
Typing in the chat input is no longer blocked while the `/restart`
command respawns the server.

---

Running `/restart` froze the chat input until the server finished
respawning. `_handle_restart_command` awaited the multi-second
`_restart_server_manual` (`server_proc.restart()`) directly on the
Textual message pump, so key events stopped being forwarded and the chat
input was "blocked". This is the same class of bug fixed for the MCP
viewer `Ctrl+R` reconnect path in #4753 — the fix runs the respawn as a
detached `asyncio.create_task` (mirroring the MCP viewer/force-reconnect
paths), keeping the pump free so keystrokes stay live and queued
messages drain once `ServerReady` fires.

Made by [Open
SWE](https://openswe.vercel.app/agents/a27e2ef4-b392-c236-f410-c1b9ebc533aa)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 15:11:09 -04:00
Mason Daugherty 7408378896 fix(code): disentangle version diagnostics for editable installs (#4816)
Editable installs conflated three distinct version facts, so `/version`,
`--version`, and `doctor` could silently report a single number that hid
stale metadata or a broken SDK dependency pin. Version diagnostics now
separate the live source version, the installed distribution metadata
version, and the `deepagents` requirement that `deepagents-code`
declares — reporting the source version as primary for editable
installs, showing the installed metadata alongside it when they drift,
and flagging an actionable mismatch when the installed SDK metadata does
not satisfy the declared requirement.

---

A new structured `DistributionVersion`/`VersionReport` representation in
`extras_info` is the single source of truth these surfaces render.
`resolve_sdk_version()` is preserved as a thin compatibility wrapper so
existing callers are untouched.

- `/version`, `--version`, and `doctor` render the same facts: an
editable SDK is now clearly identified (not just editable
`deepagents-code`), source/metadata drift shows both versions, and an
unsatisfied requirement (compared via `packaging.Requirement`) is
surfaced as `required by deepagents-code: <version> — mismatch`.
- `doctor` marks a dependency-requirement mismatch unhealthy, while
treating source/metadata drift as informational since it is normal while
editing SDK source.
- Normal non-editable output is unchanged when all versions agree, and
version collection stays fully offline and best-effort (no
`uv`/`pip`/PyPI, no subprocess).
- No package versions or dependency pins were changed.

Two existing `doctor` integration tests now isolate the SDK requirement
check so they stay deterministic regardless of the workspace's
intentional prerelease pin; the mismatch and drift paths have dedicated
new coverage.

Made by [Open
SWE](https://openswe.vercel.app/agents/1145d1a5-ba8a-abbb-e5b7-039e9c2a5b04)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 15:09:44 -04:00
Mason Daugherty 69520118a7 fix(code): keep task timers monotonic across nested subagent HITL (#4771)
Fixed dcode TUI `task` elapsed timers resetting when a nested subagent
reached a human-in-the-loop approval checkpoint.

---

A long-running `task [general-purpose]` row's elapsed timer reset to
zero whenever a nested subagent hit a HITL approval checkpoint. The
interrupt handler paused/resumed *every* tracked tool row, and
`ToolCallMessage.pause_running()`/`set_running()` clear and reassign
`_start_time` — so an unrelated nested child's (or sibling subagent's)
approval restarted the outer `task` timers. This scopes pause/resume to
only the rows an interrupt actually owns (matched by tool name + args
via the new `_interrupt_owned_tool_rows` helper). Untracked nested-child
interrupts now own no outer row, so outer and sibling `task` timers stay
monotonic and completed `Took …` durations reflect full execution time.
A tool awaiting its own initial approval still pauses then resumes as
before.

Made by [Open
SWE](https://openswe.vercel.app/agents/5c0ae962-c16b-6e04-ada4-d4d76826adb9)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 15:02:28 -04:00
Mason Daugherty 4e618f07b4 fix(code): drop uv install tip from /version update hint (#4822)
The `/version` command's update-available line hard-coded `uv tool
install -U deepagents-code`, which is stale guidance now that dcode
auto-updates on relaunch and offers `/update` and `dcode update`. It now
points at the relaunch/auto-update path when auto-update is enabled, and
at `/update` or `dcode update` otherwise.

---

Made by [Open
SWE](https://openswe.vercel.app/agents/a8b54b7c-cc2f-e6cc-a034-61a8578b8a04)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:57:06 -04:00
Mason Daugherty 487b25f885 fix(code): keep goal criteria proposal when marker clear fails (#4785)
Fixed `/goal` criteria being discarded when clearing the completed
criteria request from the thread failed.

---

Follow-up to #4784. When a YOLO `/goal` criteria run succeeds, cleanup
clears the `goal_criteria_request` marker before syncing but ignored a
failed clear (checkpoint write failure). A stale marker still naming the
just-completed request then made the sync
(`_sync_goal_rubric_state_from_thread`) and restore
(`_restore_goal_rubric_state`) paths strip the freshly generated
`_pending_goal_*` payload, so no review/YOLO acceptance mounted and the
criteria were silently lost. The marker now supersedes a proposal only
when it names a *different* request than the pending proposal's request
id.

Made by [Open
SWE](https://openswe.vercel.app/agents/6f2018c7-ffa3-ac12-4dab-8eed1142e4c4)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:49:28 -04:00
Mason Daugherty c2c27d621b fix(code): quiet MCP auth-skip debug logging for known patterns (#4805)
Reduce noisy full-traceback DEBUG logs when an MCP server is skipped
because it requires authentication; the actionable warning and a concise
debug line remain.

---

When an MCP server is skipped during discovery because it needs
authentication — either a token-refresh (`reauth`) failure or an RFC
9728 `401` OAuth challenge — `deepagents-code` logged the entire anyio
`ExceptionGroup` / httpx traceback at DEBUG via `exc_info`, on top of
the actionable WARNING. For these already-classified, expected outcomes
the traceback adds no diagnostic value and just floods debug output.

These two recognized branches now emit a concise single-line DEBUG
breadcrumb (the exception class name only). The full traceback is still
logged for genuinely unknown discovery errors (the `else` branch) and
for classifier failures, so real anomalies stay debuggable. The
user-facing WARNING is unchanged apart from dropping the now-inaccurate
"the original error is in debug logs" note from the reauth message.

Made by [Open
SWE](https://openswe.vercel.app/agents/a5ab799b-1747-0d65-16b6-ee0ccccee0c4)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:49:01 -04:00
Mason Daugherty 2ddb551bd7 feat(code): expand truncated task descriptions on click or Ctrl+O (#4811)
A long `task` tool description is rendered on a dim line truncated at
120 characters, but the full text was previously unreachable. This makes
the truncated preview expandable: clicking the description region or
pressing Ctrl+O toggles between the truncated and full description,
mirroring the collapsible command/code affordance on `execute`/`js_eval`
rows.

---

The `task` description now owns Ctrl+O when it is truncated (like an
expandable command/code block), while any expandable tool output stays
reachable by clicking its own region. A "click or Ctrl+O to
expand/collapse" hint is shown beside a truncated description.

<details>
<summary>Test plan</summary>

- Added `TestToolCallMessageTaskDescription` covering expandability
detection, the toggle swap, and click routing.
- Added an app-level Ctrl+O routing test that prefers a truncated `task`
description over expandable output.
- Updated existing Ctrl+O routing tests to account for the new
higher-priority branch.

</details>

Made by [Open
SWE](https://openswe.vercel.app/agents/f5d64d3e-e6e2-d1cf-f52c-0ecbd8829ef4)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:48:01 -04:00
Mason Daugherty f5c3259246 style(code): show enabled plugin status in green (#4821)
In the installed plugin details view, the `Status: ✓ Enabled` line was
rendered `dim` like every other status line. This styles it with the
`$success` theme color so a successful load reads as green, matching the
semantic coloring used elsewhere in the TUI. Other status lines
(error/disabled/pending, and the secondary MCP restart note) stay `dim`.

Made by [Open
SWE](https://openswe.vercel.app/agents/d3174852-cfc9-43f5-f431-56993468deaf)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:47:00 -04:00
Mason Daugherty ea825386b3 fix(code): keep paste placeholder when backspacing newline below it (#4757)
Fixed the `dcode` chat input deleting a collapsed `[Pasted text #N]` (or
`[image N]`) placeholder when backspacing the line break on the line
below it; the line break is now removed while the placeholder is
preserved.

---

In the `dcode` chat input, pasting large text collapses it into a
`[Pasted text #N]` placeholder. Pressing Enter to add a newline and then
backspacing from the start of that new line deleted the entire
placeholder instead of just rejoining the lines.

The cause is in `_find_placeholder_span`: its backwards-delete branch
treats any whitespace immediately after a placeholder as an
auto-inserted trailing separator and swallows the whole token with it.
Since `str.isspace()` also matches a newline, backspacing a line break
below a placeholder removed the placeholder. Restricting that branch to
a literal space (the separator actually auto-inserted after media
placeholders) lets a newline fall through to the default backspace,
which removes only the line break and leaves the cursor at the end of
the placeholder line. The same fix is applied to the shared base text
area used by the inline prompts.

Made by [Open
SWE](https://openswe.vercel.app/agents/79b11ee1-f326-668a-e659-c990811f4e29)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:45:04 -04:00
Mason Daugherty be8e5214a0 style(code): drop hardcoded indent from ls and write_todos output (#4762)
`ls` and `write_todos` results in the `deepagents-code` TUI now align
flush under the output-gutter glyph, matching other tools, instead of
being indented an extra four spaces.

---

The `ls` and `write_todos` renderers in the terminal UI prefixed every
row with four hardcoded spaces, so their entries rendered at a 4-space
hanging indent under the `⎿` output-gutter glyph. Every other tool
formatter (`grep`, `glob`, `read_file`, `execute`) sits flush after that
gutter, and the gutter layout already owns alignment for soft-wrapped
lines — so the extra pad just produced an inconsistent gap between the
glyph and the first item. This emits bare rows for both formatters and
also drops the matching indent from the todo stats header and
empty-state, so the whole block stays flush and consistent. The todo
continuation-line hang-indent auto-adjusts since it derives from the
status-label width.

Made by [Open
SWE](https://openswe.vercel.app/agents/c5dec078-214f-79a6-2417-4b0014e0944e)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:44:39 -04:00
Mason Daugherty 77603c69e2 feat(code): debug-log skill-name override collisions (#4772)
Deep Agents Code now emits a `DEBUG` log when a higher-precedence skill
overrides another skill with the same name, aiding skill-resolution
debugging.

---

Skill sources (built-in, plugin, global, project) are merged by
precedence and a higher-precedence skill silently replaces a
lower-precedence one with the same name. This override is intentional
and unchanged; this PR makes it diagnosable by routing both
skill-discovery merge points — the CLI `skills list` loader
(`skills/load.py`) and the runtime `PluginSkillsMiddleware` — through a
shared `merge_skill` helper that emits a `DEBUG` log on each effective
replacement, recording the skill name plus the previous and replacement
source paths and labels.

Made by [Open
SWE](https://openswe.vercel.app/agents/5f97f80c-bed1-0fa5-d0b1-ce67060df37c)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:43:17 -04:00
Mason Daugherty 45baf6c7a4 fix(code): probe unreachable Ollama daemon once per reload (#4806)
When an Ollama daemon is down, discovery no longer probes it twice or
emits duplicate, out-of-order debug logs at startup — it probes and logs
"not detected" once per reload.

---

Ollama discovery runs from two startup callers — `get_available_models`
and `get_model_profiles` — that both call
`_get_ollama_installed_models`. Empty results were never cached, so an
unreachable daemon was probed twice per reload and logged `Ollama daemon
not detected ...` twice. Because the second `not detected` (from
`get_model_profiles`) landed right after the first pass's `discovery
returned no models` line, the two appeared out of order even though each
individual pass logs in the correct order.

This tracks endpoints that fail the TCP presence preflight in
`_ollama_unreachable_endpoints` and negatively-caches their empty
result, so the probe and log happen once. A *reachable* daemon that
simply reports no models is still left uncached, preserving recovery of
a later `ollama pull` without `/reload` (covered by the existing
`test_empty_installed_model_discovery_not_cached`).

Made by [Open
SWE](https://openswe.vercel.app/agents/7b64e449-2a7e-f258-17a1-5ffe933608a3)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:39:44 -04:00
Mason Daugherty 4d483fdf39 fix(code): count only running tools in live tool-group line (#4809)
Fix the live tool-group progress line in `dcode` so it counts only the
tools still running instead of every tool in the step.

---

The collapsed tool-group summary's live progress line summarizes the
whole assistant step instead of what is actually still running. Because
it aggregates every tool in the group, finished calls keep being
reported as in progress — e.g. it shows `Running 1 shell command,
running 2 agents…` even after the shell command and one of the agents
have completed.

This builds the present-tense line from only the still-pending members,
so finished calls drop out as they complete. The past-tense line (shown
once everything finishes) continues to summarize every tool that ran.
The cached present phrasing now rebuilds whenever the set of running
members changes, not just when the group grows.

Made by [Open
SWE](https://openswe.vercel.app/agents/25ed04be-b8ed-97c9-a600-d24d80c02162)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:35:09 -04:00
Mason Daugherty 20089a5370 feat(code): persist Debug Console Ctrl+L clear across reopen (#4812)
Clearing the Debug Console (`Ctrl+\`) traceback/log tail with `Ctrl+L`
now persists across closing and reopening the console for the process
lifetime, instead of re-populating from the in-memory buffer on the next
open.

---

The console modal is recreated fresh on every open and, on mount,
replays everything still retained in the always-on in-memory ring
buffer. `Ctrl+L` (`action_clear_view`) was deliberately a view-only
clear that advanced only the current instance's render cursor, so
closing and reopening replayed the buffer and the "cleared" records came
back.

This adds a process-lifetime "cleared upto" cursor owned by the app.
`DebugConsoleScreen` gains keyword-only `cleared_upto` (seeds its render
cursor so a prior clear is honored on open) and `on_clear` (reports the
new cursor when `Ctrl+L` fires). `DeepAgentsApp` stores the cursor in
`_debug_console_cleared_upto`, seeds each new console from it, and
persists updates via the callback.

The change stays strictly view-only: the shared ring buffer is never
mutated, other diagnostics are unaffected, and records logged *after* a
clear still appear. Clearing is by emission time, matching the existing
in-session semantics.

Made by [Open
SWE](https://openswe.vercel.app/agents/58c9cc66-afbe-b468-729d-375b731bbf71)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:28:41 -04:00
Mason Daugherty 2d6b2ceeda fix(code): make markdown AppMessage output selectable (#4814)
`/version` output (and incognito shell output) is now selectable and
copyable.

---

The output from the `/version` command could not be selected or copied.
Those tables — and incognito shell output — render through
`AppMessage(markdown=True)`, which produced a raw Rich renderable.
Textual only supports text selection over `Content`/`Text` visuals, so a
`RichVisual` carries none of the per-cell offset metadata selection
relies on and its text is neither highlightable nor copyable.

This renders the muted markdown to segments and rebuilds it as
`Content`, laid out to the widget's current width, so the
tables/rules/emphasis look the same but the text is now selectable and
copyable. Trailing padding is trimmed per line so copies stay clean.

Made by [Open
SWE](https://openswe.vercel.app/agents/f705adb2-3ebb-25a2-7ebd-ddce94887917)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 14:27:14 -04:00
Mason Daugherty 41123924da fix(code): surface langchain-quickjs in /version core deps (#4813)
`/version` now lists `langchain-quickjs` under its "Core dependencies"
section for editable installs.

---

`langchain-quickjs` powers the built-in interpreter and is a core
runtime dependency (declared directly in `dependencies`, not as an
optional extra). It was previously invisible in `/version`: the
"Installed optional dependencies" table only reads packages gated by
`extra == "..."` markers (and the `quickjs` extra is intentionally
empty), while the curated `CORE_DEPENDENCIES` list that drives the "Core
dependencies" section did not include it.

Adding it to `CORE_DEPENDENCIES` surfaces its resolved version alongside
the other LangChain-ecosystem packages, which helps diagnose editable
environments where a local checkout of the partner package may be
overriding the released one. The section is only rendered for editable
installs, matching existing behavior.

The `CORE_DEPENDENCIES`-driven tests iterate the tuple generically, so
they cover the new entry without modification.

Made by [Open
SWE](https://openswe.vercel.app/agents/e258f95b-7cc4-33f3-52f0-32d4aa4c13fd)

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-17 13:06:14 -04:00
github-actions[bot] 18679a1a88 release(deepagents-code): 0.1.42 (#4793)
> [!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`. The published GitHub release body is extracted from the
merged `CHANGELOG.md` by `release.yml`, not from this PR description._

---


##
[0.1.42](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.41...deepagents-code==0.1.42)
(2026-07-17)

### Features

- Plugins are now generally available.
([#4797](https://github.com/langchain-ai/deepagents/issues/4797))
- Added search to the plugin list and now summarize plugin changes after
reloads.
([#4765](https://github.com/langchain-ai/deepagents/issues/4765),
[#4767](https://github.com/langchain-ai/deepagents/issues/4767))
- Added Kimi K3 to the OpenRouter model selector.
([#4803](https://github.com/langchain-ai/deepagents/issues/4803))
- Added hidden `connect` and `reconnect` keywords for `/restart`.
([#4807](https://github.com/langchain-ai/deepagents/issues/4807))
- Debug Console thread IDs can now be clicked to copy, with an added
LangSmith link.
([#4760](https://github.com/langchain-ai/deepagents/issues/4760))
- Added auto-approve (YOLO) mode to trace metadata.
([#4764](https://github.com/langchain-ai/deepagents/issues/4764))

### Bug Fixes

- Improved plugin marketplace loading and onboarding, including
asynchronous marketplace additions and polish for empty marketplace
states.
([#4766](https://github.com/langchain-ai/deepagents/issues/4766),
[#4759](https://github.com/langchain-ai/deepagents/issues/4759))
- Clarified plugin component discovery and reload status.
([#4774](https://github.com/langchain-ai/deepagents/issues/4774))
- Avoided blocking MCP OAuth token refresh.
([#4770](https://github.com/langchain-ai/deepagents/issues/4770))
- Restored keyboard focus for marketplace details.
([#4763](https://github.com/langchain-ai/deepagents/issues/4763))
- Dismissed the startup tip when submitting an initial prompt with `-m`.
([#4779](https://github.com/langchain-ai/deepagents/issues/4779))

_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>
2026-07-16 23:24:16 -04:00
Johannes du Plessis 3da6e471c2 feat(code): make plugins generally available (#4797)
Plugins are now available by default in deepagents-code without setting
`DEEPAGENTS_CODE_EXPERIMENTAL`.

This removes the flag gates from CLI and slash-command discovery, plugin
skills and MCP loading, and reload behavior while preserving the flag
for unrelated experimental features.

Made by [Open
SWE](https://openswe.vercel.app/agents/019f6c79-6211-734f-b05c-a5a3401c8a6b)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-07-16 23:06:34 -04:00
Mason Daugherty 3b2ffce923 fix(code): avoid blocking MCP OAuth token refresh (#4770)
Fixes MCP OAuth token refresh crashing tool calls under `langgraph dev`
with a `NodeCancelledError`.

---

OAuth refresh previously performed token-file work synchronously.
BlockBuster could interrupt that work, cancel session initialization,
and leave its `AsyncExitStack` to be finalized from another task. Users
then saw errors such as:

Attempted to exit cancel scope in a different task than it was entered
in

Token-file I/O now runs in worker threads. Writes are serialized, token
and expiry values are read from one snapshot, and cancellation waits for
token writes and refresh-lock acquisition or release to finish before
propagating. Partial MCP sessions are closed by the task that created
them without hiding the original failure.

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 22:47:49 -04:00
Johannes du Plessis 0d1bb6a122 fix(code): add marketplaces asynchronously (#4766)
Plugin marketplaces are now added asynchronously with visible progress
and recoverable errors.

---

Marketplace additions now run in a Textual thread worker so repository
and network work cannot block the UI. The modal displays an animated
spinner, prevents duplicate submissions and cancellation while busy, and
restores the source field with an actionable error after failure.

## Screenshots
<img width="867" height="1004" alt="Screenshot 2026-07-16 at 11 44
16 AM"
src="https://github.com/user-attachments/assets/031831a0-aa97-4d43-ac9b-e7cbcd7ce13f"
/>


Made by [Open
SWE](https://openswe.vercel.app/agents/019f6785-019d-75b7-86c1-c35cc55cdf5d)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
2026-07-16 22:30:15 -04:00
Johannes du Plessis 9cad2f00dd feat(code): summarize plugin changes on reload (#4767)
Plugin management now reminds users to reload and `/reload` summarizes
plugin changes.

---

Surfaces a `/reload` reminder after relevant plugin-manager changes and
compares the pre-change plugin state with reload discovery. The reload
report now summarizes added, removed, and changed plugins.

## Screenshots
<img width="862" height="447" alt="Screenshot 2026-07-16 at 11 19 51 AM"
src="https://github.com/user-attachments/assets/1900856b-7ddb-47a1-8bc2-d5dbfb8701cc"
/>

Made by [Open
SWE](https://openswe.vercel.app/agents/019f6784-519d-73cc-9f67-9a46c88d1de9)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-07-16 21:38:52 -04:00
Nick Hollon 671c578006 feat(evals): flat cross-category shard pool for unified evals (#4745)
## What

Replace the serialized per-provider / per-category eval jobs with one
dynamically-drained **per-model pool spanning all three categories**. A
shard is a 1-task unit carrying its own `(category, dataset, agent_impl,
task)`; `unified_prep` emits a per-model flat matrix and one `eval` job
drains it. `max_parallel`/`model_parallel` are **derived** from
`concurrency`+`rollouts`; `MAX_SHARDS` 64→200 with proportional
per-category packing above the cap. Per-category aggregation keeps the
tier-2 scorecard (`aggregate_unified.py`) unchanged. `harbor.yml`'s
single-dataset path decouples `shard_parallel` from `n_shards` for
dynamic dispatch (no-op at the default `n_shards=10`).

## Validated (CI, docker sandbox, bare harness)

- **Lite single-model** (`gpt-5.6-terra`): complete scorecard across all
3 categories, macro pass@3 0.479 (context 0.0 → 0.625 after the fixes
below).
- **Multi-model** (`gpt-5.6-terra` + `anthropic:claude-sonnet-5`): both
per-model pools run concurrently under `model_parallel`, total-job guard
holds (68 shards), and the non-OpenAI agent runs with the OpenAI judge.

## Fixes folded in (found during the dry-runs)

- Context corpus populate + judge `OPENAI_API_KEY` now read the
per-shard `matrix.*` values (they were gated on the leaf inputs, which
the flat design leaves empty).
- LangSmith experiment name scoped per category (fixes the cross-dataset
run double-count).

## Dependency

Needs the harbor build-lock fix
([harbor-framework/harbor#2340](https://github.com/harbor-framework/harbor/pull/2340))
via `harbor_package_override` until it's released — pin
`nick-hollon-lc/harbor@27a6eac8` meanwhile.

---------

Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-07-16 17:45:06 -04:00
Mason Daugherty 99250ee174 feat(code): add reconnect/connect hidden keywords for /restart (#4807)
Typing "reconnect" or "connect" in the slash-command autocomplete now
surfaces the `/restart` command, which respawns the agent server.

Adds `reconnect` and `connect` to the `hidden_keywords` for the
`/restart` `SlashCommand` entry so fuzzy matching finds it under those
common terms. These keywords are never displayed and don't appear in the
commands catalog, so no regeneration is needed.

Made by [Open
SWE](https://openswe.vercel.app/agents/05f60126-f5ea-25a4-3b3b-84127a4a529b)

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 17:23:14 -04:00
Johannes du Plessis a6c20b1a4d feat(code): add plugin list search (#4765)
Plugin screens now support filtering available and installed plugins by
name or description.

---

Add keyboard-accessible search to available and installed plugin lists
so users can filter by plugin name or description, clear searches with
Escape, and see explicit no-results states.

## Screenshots
<img width="860" height="987" alt="Screenshot 2026-07-16 at 11 27 22 AM"
src="https://github.com/user-attachments/assets/523be30d-c3cd-4aae-bb36-5441c3454d6b"
/>


Made by [Open
SWE](https://openswe.vercel.app/agents/019f6784-b613-735d-bb42-f6e0c69c3956)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
2026-07-16 17:19:35 -04:00
Mason Daugherty fc94bb7da9 feat(code): add Kimi K3 to model selector under OpenRouter (#4803)
Add Kimi K3 to the model selector under the OpenRouter provider.

Made by [Open
SWE](https://openswe.vercel.app/agents/74c5c230-fc6c-57ce-320b-3379bae51abd)

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 16:48:26 -04:00
Mason Daugherty 29d6046998 chore(deps): require langchain-quickjs 0.3.3 (#4802)
Raise the minimum supported `langchain-quickjs` version to `0.3.3` in
Deep Agents Code, the SDK quickjs extra, and evals now that the release
is available on PyPI.

Refresh the corresponding lockfiles, including the `langchain` and
`langgraph` versions required by `langchain-quickjs==0.3.3`.
2026-07-16 16:45:06 -04:00
dependabot[bot] 177a6d3874 chore(deps): bump mcp from 1.27.2 to 1.28.1 in /libs/talon (#4799)
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mcp&package-manager=uv&previous-version=1.27.2&new-version=1.28.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/deepagents/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-07-16 16:37:22 -04:00
dependabot[bot] b17d1b3ebe chore(deps): bump mcp from 1.26.0 to 1.28.1 in /libs/evals (#4800)
[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=mcp&package-manager=uv&previous-version=1.26.0&new-version=1.28.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore this major version` will close this PR and stop
Dependabot creating any more for this major version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this minor version` will close this PR and stop
Dependabot creating any more for this minor version (unless you reopen
the PR or upgrade to it yourself)
- `@dependabot ignore this dependency` will close this PR and stop
Dependabot creating any more for this dependency (unless you reopen the
PR or upgrade to it yourself)
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/langchain-ai/deepagents/network/alerts).

</details>

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
2026-07-16 16:32:49 -04:00
github-actions[bot] f7ed5d85c6 release(langchain-quickjs): 0.3.3 (#4372)
> [!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`. The published GitHub release body is extracted from the
merged `CHANGELOG.md` by `release.yml`, not from this PR description._

---


##
[0.3.3](https://github.com/langchain-ai/deepagents/compare/langchain-quickjs==0.3.2...langchain-quickjs==0.3.3)
(2026-07-16)

### Bug Fixes

* Propagate JS `task()` subagent interrupts
([#4401](https://github.com/langchain-ai/deepagents/issues/4401))
([0b30e49](https://github.com/langchain-ai/deepagents/commit/0b30e494d59187de2e6e23db062abbf835a6d265))
* Correct `eval` await description
([#4371](https://github.com/langchain-ai/deepagents/issues/4371))
([4ab860f](https://github.com/langchain-ai/deepagents/commit/4ab860f007832821bd303809d7c2c1d2c86a6528))

---

_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>
2026-07-16 16:24:12 -04:00
Mason Daugherty 0b30e494d5 fix(quickjs): propagate JS task() subagent interrupts (#4401)
QuickJS exposes a JavaScript `task()` helper so an eval can fan out work
to Deep Agents subagents, but that helper was not quite equivalent to
the normal `task` tool path. When a JS-launched subagent hit HITL, the
nested `GraphInterrupt` was caught and rendered as an eval error instead
of reaching LangGraph’s normal interrupt machinery; the bridge also
skipped the parent runtime config and child tool call id when invoking
the underlying task tool.

## Changes

- Preserve the parent `ToolRuntime.config` and pass a synthetic child
`tool_call_id` when `call_subagent_task_tool` invokes the Deep Agents
task tool. This keeps subagent dispatch closer to the normal `ToolNode`
path, including config-driven behavior such as thread/run metadata and
runtime context propagation.
- Let `GraphInterrupt` bubble through both the subagent helper and the
QuickJS `task()` bridge. Other validation/runtime failures are still
wrapped as eval errors, but LangGraph interrupts remain control-flow
signals rather than being converted into `<error
type="GraphInterrupt">...`.
2026-07-16 13:10:54 -07:00
Mason Daugherty 2d35507b5c feat(code): Debug Console thread ID click-to-copy with LangSmith link (#4760)
Debug Console (`Ctrl+\`) thread ID is now click-to-copy and shows a
clickable `(langsmith)` trace link.

---

The in-app Debug Console (`Ctrl+\`) now lets you click the Thread ID
snapshot row to copy it to the clipboard, and appends a clickable inline
`(langsmith)` trace link next to it once the thread's LangSmith URL
resolves. The URL lookup runs in a background worker with a short
timeout (mirroring the welcome banner), so it never blocks opening the
overlay and degrades to no link on failure.

Made by [Open
SWE](https://openswe.vercel.app/agents/7f7451e4-5850-04d6-b76e-ef6dea6300a4)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 16:00:58 -04:00
Mason Daugherty d88601ed58 feat(code): trace auto-approve (YOLO) mode in trace metadata (#4764)
Auto-approve ("YOLO") runs are now labeled with
`dcode_auto_approve=True` in LangSmith trace metadata, making them
filterable.

---

Auto-approve ("YOLO") mode — the `Shift+Tab` toggle / `--auto-approve` —
sets `interrupt_on = {}` so tools run with no HITL gate, but nothing
recorded that state in LangSmith traces, so YOLO runs weren't
filterable. The `coding-agent-v1` contract's `approval_policy` key can't
help here: it's scoped to root/interrupted runs and would leak onto
every descendant run (and fail contract validation) if stamped
trace-wide.

This adds a non-contract diagnostic `dcode_auto_approve=True` metadata
key in `build_stream_config`, mirroring the existing
`dcode_experimental` pattern (only stamped when active). Interactive
turns pass `session_state.auto_approve`; headless turns pass the
resolved `use_auto_approve` (which reflects "tools run without HITL
because shell is unrestricted or disabled" — the same `auto_approve`
flag the graph consumes). Metadata is sampled once at turn start, so a
mid-turn toggle doesn't relabel that turn's trace.

New keyword-only `auto_approve` param defaults to `False`, so the change
is additive and backward-compatible.

Made by [Open
SWE](https://openswe.vercel.app/agents/31881cb9-2c33-7505-1b1a-fd453e84ea5a)

## References
- Plan:
https://openswe.vercel.app/agents/31881cb9-2c33-7505-1b1a-fd453e84ea5a/plan

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 15:01:58 -04:00
Mason Daugherty 78f9f5fcb3 test(code): isolate ambient env and global dotenv in unit tests (#4778)
Make the Deep Agents Code unit tests hermetic so they no longer depend
on the developer's real environment, `~/.deepagents/.env`, or the
checkout-path length.

Ambient MCP trust vars
(`DEEPAGENTS_CODE_DANGEROUSLY_ENABLE_PROJECT_MCP_SERVERS` and friends),
`DEEPAGENTS_CODE_DEBUG_NOTIFICATIONS`, and
`DEEPAGENTS_CODE_EXPERIMENTAL` can be loaded from the developer's global
dotenv at `deepagents_code.config` import time — before fixtures run —
and `/reload` rereads that global dotenv and restores them. The
dangerous MCP allowlist intentionally replaces scoped TOML approvals
(breaking trust-list/selective-project-trust assertions), the debug var
changes notification suppression, and a restored experimental flag
breaks the `/reload` plugin-summary test. Separately,
`TestBranchDisplay::test_short_branch_name_not_truncated` let a long
real CWD consume the status bar, leaving the branch widget zero width.

Approach (test-only; no production behavior changes):
- New autouse fixture redirects `config._GLOBAL_DOTENV_PATH` to a
nonexistent `tmp_path` file so dotenv rereads (e.g. `/reload`) are
inert.
- New autouse fixture clears `DEEPAGENTS_CODE_DEBUG_NOTIFICATIONS`; the
existing MCP-trust fixture already removes the trust vars (docstring
expanded to explain why).
- The short-branch test now hides the CWD via `HIDE_CWD`, consistent
with neighboring branch-display tests, so path length can't starve the
widget.

Tests that intentionally exercise dotenv loading already set
`_GLOBAL_DOTENV_PATH` and their inputs explicitly in the test body
(after the isolation fixtures), so they are unaffected.

Made by [Open
SWE](https://openswe.vercel.app/agents/234e9ee9-f18a-e812-4187-aae8190e4711)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 15:01:44 -04:00
Mason Daugherty 8acd414a2e fix(code): dismiss startup tip on -m initial submission (#4779)
The splash tip above the chat input is now dismissed when the TUI is
launched with an initial prompt (`-m`), skill (`--skill`), or goal
(`--goal`), matching interactive submissions.

---

When launching the TUI with `dcode -m "msg"`, the splash tip above the
chat input stayed visible, unlike a normal interactive prompt which
clears it.

The tip was only dismissed inside `_submit_input`, the shared path for
interactive and external prompts. Startup submissions from `-m` (as well
as `--skill` and `--goal`) run through `_submit_initial_submission`
instead, which dispatches directly to `_handle_user_message` /
`_invoke_skill` / `_handle_goal_command` and never dismissed the tip.
This adds a `_dismiss_startup_tip()` call at the top of
`_submit_initial_submission` so all startup submission paths match
interactive behavior.

Made by [Open
SWE](https://openswe.vercel.app/agents/2d2a8fdc-c71c-58c6-287a-6d4109d24bbb)

---------

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 15:01:10 -04:00
Johannes du Plessis e821d3dd26 fix(code): restore marketplace details keyboard focus [closes DCD-50] (#4763)
## Description
Marketplace detail controls ignored Tab and Shift+Tab because those
bindings only attempted to switch tabs. Cycle enabled detail options
with wraparound while preserving existing list-tab and Escape behavior.

## Release Note
Marketplace detail controls now support visible, predictable Tab and
Shift+Tab keyboard navigation.

## Test Plan
- [x] Navigate marketplace details forward, backward, and through
wraparound with a Textual pilot test.

Made by [Open
SWE](https://openswe.vercel.app/agents/019f6783-f3db-727b-ad05-65934c0a9505)

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 11:28:44 -07:00
Dariel Dato-on 5bff73b94e chore(acp): rename py.typed.py to the proper py.typed file (#4792)
`deepagents-acp` now ships a valid `py.typed` marker, so type checkers
treat it as a typed package.
2026-07-16 14:20:47 -04:00
Johannes du Plessis 7d707b840f fix(code): clarify plugin component discovery and reload status (#4774)
Closes
[DCD-49](https://linear.app/langchain/issue/DCD-49/plugins-fix-installed-component-discovery-and-status-messaging)

Plugin manager status and component messaging now reflect what
deepagents-code actually loads, and Enabled only appears after
`/reload`.

---

Plugins that only ship `agents/`/`commands/`/`hooks` (e.g.
`pr-review-toolkit`) now report those as unsupported instead of “no
components discovered.” Discover preview and installed status
distinguish pending `/reload`, enabled, and error.

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
Co-authored-by: Mason Daugherty <mason@langchain.dev>
2026-07-16 17:55:39 +00:00
Johannes du Plessis ab2e101d02 fix(code): improve empty marketplace onboarding and list polish (#4759)
Closes
[DCD-48](https://linear.app/langchain/issue/DCD-48/plugins-improve-empty-marketplace-onboarding-and-list-polish)


`/plugins` empty Discover state now links straight to adding a
marketplace, with clearer marketplace error and enabled-status styling.

---

Make `/plugins` easier to onboard and a bit clearer to scan:

- empty Discover state offers a direct Add marketplace action
- marketplaces list gets a divider and styled load-error labels
- plugin rows use per-chip styling; enabled stays bold on highlight and
`$success` in details

---------

Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Mason Daugherty <github@mdrxy.com>
2026-07-16 17:41:36 +00:00
github-actions[bot] d46a2cb033 release(deepagents-code): 0.1.41 (#4790)
> [!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`. The published GitHub release body is extracted from the
merged `CHANGELOG.md` by `release.yml`, not from this PR description._

---


##
[0.1.41](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.40...deepagents-code==0.1.41)
(2026-07-16)

### Bug Fixes

- Pinned `filelock` below 3.30 to avoid blocking imports
([#4786](https://github.com/langchain-ai/deepagents/issues/4786))

_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>
2026-07-16 08:36:30 -04:00
Mason Daugherty f9b7d75f24 fix(code): pin filelock below 3.30 to avoid blocking import (#4786)
`filelock` 3.30.0 runs a blocking temp-directory probe
(`_probe_link_follow_symlinks`) at import time. `deepagents-code`
imports `filelock` (via `mcp_auth`) on the async server-graph startup
path, so Blockbuster rejects the resulting `os.getcwd` call and the
graph fails its readiness check with `BlockingError: Blocking call to
os.getcwd`, aborting startup entirely. The broad `>=3.12,<4.0.0` range
let a fresh install resolve the just-released 3.30.0, which is why even
downgrading `deepagents-code` reproduced it.

Capping at `<3.30` keeps resolution on 3.29.x. A follow-up can make the
`filelock` import loop-safe (e.g. warm it up off the event loop) and
relax the cap.

## Release Note
Fix `deepagents-code` startup failure (`BlockingError: Blocking call to
os.getcwd`) caused by `filelock` 3.30.0.

## Test Plan
- [ ] `dcode` launches cleanly with `filelock` resolved to 3.29.x

Made by [Open
SWE](https://openswe.vercel.app/agents/a27d2d36-4e59-b0b2-edbb-228bc6e557c9)

Co-authored-by: open-swe[bot] <open-swe@users.noreply.github.com>
2026-07-16 07:57:49 -04:00
langsmith-fleet[bot] d13d299a0f chore(deps): Bump nltk for CVE-2026-54293 (#4787)
## Summary
- bump `nltk` in `libs/evals` from 3.9.4 to 3.10.0
- raise the minimum `nltk` dependency bound to 3.10.0
- include the new `defusedxml` transitive dependency required by NLTK
3.10.0

## Security
Fixes Dependabot alert 576 / GHSA-p4gq-832x-fm9v / CVE-2026-54293. The
advisory marks `nltk<=3.9.4` vulnerable; 3.10.0 includes hardened
resource loading against path traversal.

## Validation
- `uv lock --project libs/evals --locked --offline`

Note: I attempted to install/use Socket Firewall for package-manager
protection, but the SFW binary download returned HTTP 502 in the
sandbox. I avoided registry-resolving package-manager updates and used
PyPI release metadata plus offline lock validation instead.

Co-authored-by: Langster <security-agent@langchain.dev>
2026-07-15 23:21:37 -07:00
github-actions[bot] 019489edb9 release(deepagents-code): 0.1.40 (#4734)
> [!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`. The published GitHub release body is extracted from the
merged `CHANGELOG.md` by `release.yml`, not from this PR description._

---


##
[0.1.40](https://github.com/langchain-ai/deepagents/compare/deepagents-code==0.1.39...deepagents-code==0.1.40)
(2026-07-16)

### Features

- Added plugin marketplace support
([#4554](https://github.com/langchain-ai/deepagents/issues/4554)).
- Added an “always allow” option to the project MCP approval prompt
([#4562](https://github.com/langchain-ai/deepagents/issues/4562)).
- Improved `/goal` workflows: criteria generation now runs server-side,
YOLO mode auto-accepts criteria, goals complete after satisfied grading,
and goal review editing now supports `Ctrl+X`
([#4754](https://github.com/langchain-ai/deepagents/issues/4754),
[#4784](https://github.com/langchain-ai/deepagents/issues/4784),
[#4781](https://github.com/langchain-ai/deepagents/issues/4781),
[#4780](https://github.com/langchain-ai/deepagents/issues/4780)).
- Reasoning effort now persists across restarts
([#4728](https://github.com/langchain-ai/deepagents/issues/4728)).
- Added a toast prompting you to re-paste when a chat paste collapses
([#4742](https://github.com/langchain-ai/deepagents/issues/4742)).

### Bug Fixes

- Tool calls awaiting approval are now surfaced correctly
([#4739](https://github.com/langchain-ai/deepagents/issues/4739)).
- Fixed transcript tail hydration when scrolled to the bottom edge
([#4733](https://github.com/langchain-ai/deepagents/issues/4733)).
- Kept chat input responsive during MCP viewer `Ctrl+R` reconnects
([#4753](https://github.com/langchain-ai/deepagents/issues/4753)).
- Improved inline free-text prompts by sharing paste handling and
matching primary-input `Ctrl+D` behavior
([#4736](https://github.com/langchain-ai/deepagents/issues/4736),
[#4729](https://github.com/langchain-ai/deepagents/issues/4729)).
- Fixed local offloaded tool results to use the real filesystem
([#4740](https://github.com/langchain-ai/deepagents/issues/4740)).
- Cleaned offloaded history when deleting a thread
([#4751](https://github.com/langchain-ai/deepagents/issues/4751)).
- Removed duplicated content from the system prompt by overwriting the
base prompt
([#4516](https://github.com/langchain-ai/deepagents/issues/4516)).
- Closed subprocess transport during install teardown
([#4735](https://github.com/langchain-ai/deepagents/issues/4735)).
- Added targeted `uv` constraints for prerelease dependencies
([#4744](https://github.com/langchain-ai/deepagents/issues/4744)).

_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>
2026-07-15 23:35:57 -04:00
Mason Daugherty cc662f236d feat(code): auto-accept /goal criteria in YOLO mode (#4784)
YOLO mode now automatically accepts successfully generated `/goal`
acceptance criteria, including amendments, regenerated proposals, and
proposals restored from a thread.

---

When someone creates, amends, or regenerates a `/goal` while YOLO mode
is enabled, dcode still generates acceptance criteria but now accepts a
successful proposal without interrupting the workflow with an
interactive review.

Automatic acceptance reads the live per-thread approval mode and follows
the same persistence and continuation path as selecting “Accept proposed
criteria.” Turning YOLO on also resolves a proposal already awaiting
review, while turning it off before generation finishes preserves the
manual review. Failed, cancelled, rejected, stale, and superseded
proposals remain fail-closed, and review widgets, futures, tasks, and
focus are cleaned up when automatic acceptance takes over.

Manual goal review and standalone `/rubric` behavior are unchanged. The
transcript explains when YOLO accepted criteria automatically, and
`/goal show` continues to expose the accepted objective and criteria.
2026-07-15 23:24:29 -04:00
Mason Daugherty 682ce0fc76 fix(code): complete goals after satisfied grading (#4781)
Accepted `/goal` objectives now automatically transition to `complete`
when their current goal-backed work turn finishes with a satisfied
acceptance-criteria grade. Completed goals remain visible through `/goal
show` but no longer affect later ordinary turns.

---

An accepted `/goal` should finish when its own final rubric grade says
every criterion is satisfied. Previously the agent also had to call
`update_goal(status="complete", ...)`, manual mode requested another
approval, and successful completion removed the goal record entirely.
That made completion depend on approval mode and left `/goal show` with
nothing to report.

Completion now requires a validated grading event observed live during
the current goal-backed work turn, a matching grading-run identifier in
the checkpoint, and a turn that finishes without aborting. Criteria
generation, thread restoration, standalone `/rubric` grading, unrelated
or ungraded turns, stale persisted grader state, and unknown grader
verdicts cannot complete a goal. If a satisfied grade arrives before an
interrupted turn, the goal remains active and the UI explains that it
will be checked again on the next turn.

Completion is persisted transactionally; if that write fails, the active
goal and any agent-provided note remain available for a later retry.
Completed goals retain their objective, acceptance criteria, status, and
completion note while no longer driving subsequent work or grading.
Agents may still call `update_goal(status="complete", ...)` to provide a
completion note, but the call is optional. Manual and YOLO modes use the
same completion path without a completion approval prompt.
2026-07-15 21:30:00 -04:00
Mason Daugherty 641b906157 feat(code): add Ctrl+X to goal review editing (#4780)
`Ctrl+X` now opens the active `/goal` criteria or rejection-feedback
field in the configured external editor.

---

When a user was editing proposed goal criteria or entering regeneration
feedback, `Ctrl+X` still opened the unrelated chat draft because the
priority app binding always targeted the composer. This moved focus out
of the review and made external-editor composition unusable in both
goal-review modes.

`Ctrl+X` now detects the active goal-review field and opens its complete
logical value, including expanded collapsed-paste content, in `$VISUAL`
or `$EDITOR`. Saved text returns to the same field without submitting;
cancellation or failure preserves the existing value and focus. Hidden,
stale, detached, or unfocused goal editors fall through to the unchanged
chat-input behavior.
2026-07-15 20:36:40 -04:00
Mason Daugherty 9fdd498937 feat(code): move /goal criteria generation server-side (#4754)
`/goal` acceptance-criteria drafting now runs on the agent server and
can use conversation, repository, web, and explicitly read-only
configured MCP context while preserving resumable review state.

---

Previously, `/goal` proposals were drafted in the client process from
the explicit objective, so remote or sandbox repository context and
references to the current conversation were unavailable. This moves
proposal and amendment drafting into a nested agent in the main server
graph, where it can use recent conversation context, bounded read-only
repository search, `fetch_url`, optional web search, and configured MCP
tools explicitly annotated as read-only.

Repository context remains read-only and repository-rooted across
backends: local reads use a virtual project root, while sandbox reads
are constrained to the provider's declared working directory, including
canonical-path checks that reject symlink escapes.

Proposals are stored as pending checkpoint state rather than chat
messages, so review survives remote interrupts and resumes without
polluting the coding conversation. Each proposal is correlated with its
originating request, and criteria requests are cleared after success,
failure, or cancellation without clearing newer requests. Cancelling
criteria generation stops the server run without adding normal
chat-interruption messages. The client refreshes checkpoint state after
generation and reuses the existing accept, edit, and reject flow; model
profile overrides now cross the client/server boundary consistently.
2026-07-15 17:17:41 -04:00