Skip to content

fix(code): correct editable SDK detection to scan and correlate - #5199

Merged
Mason Daugherty (mdrxy) merged 1 commit into
mainfrom
mdrxy/code/fix-editable-sdk-detection
Jul 30, 2026
Merged

fix(code): correct editable SDK detection to scan and correlate#5199
Mason Daugherty (mdrxy) merged 1 commit into
mainfrom
mdrxy/code/fix-editable-sdk-detection

Conversation

@mdrxy

Copy link
Copy Markdown
Member

dcode now detects an editable deepagents SDK install the same way the SDK itself does, so the two stop disagreeing about the same installation. A trace that previously showed lc_versions.deepagents = "0.7.0+editable" alongside dcode_client_deepagents_version = "0.7.0" for one install now reports the editable source version on both.


Why

_editable_sdk_source_root answered "is the installed deepagents editable, and where is its source?" with a single importlib.metadata.distribution("deepagents") lookup and no correlation against the running package. The SDK's _is_editable_install does more, and both extra steps guard real errors:

  • Scan every matching distribution instead of one lookup. setuptools leaves a gitignored deepagents.egg-info/ in the source tree after any local build, and the cwd is on sys.path for -c, -m, and the REPL — so from a checkout that directory is found first and carries no direct_url.json. The single-lookup form concluded "not editable" and never consulted the real editable install in site-packages. In that scenario dcode fell back to package metadata for the version while the SDK stamped +editable; after this change dcode correctly reads the version from the checkout's _version.py.
  • Correlate the record with the running package. An environment can hold several deepagents records — a wheel earlier on sys.path plus an unrelated editable checkout later on it. Crediting the wrong one labels a published install as a workspace build.

What changed

dcode's _editable_sdk_source_root now scans every installed deepagents distribution for a PEP 610 dir_info.editable: true record and credits it only when its source root contains the package find_spec would import, mirroring the SDK's logic. The correlation anchor is located with importlib.util.find_spec rather than an import, so the existing "SDK version lookup must not import the SDK" invariant (test_dcode_client_deepagents_version_does_not_import_sdk) still holds. Per-distribution metadata failures are contained so one unreadable record cannot abort the scan early; the distributions() backstop also swallows RecursionError so pathological metadata cannot make the answer depend on iteration order.

dcode keeps its own copy rather than importing the SDK helper. The SDK's scan lives in the private _is_editable_install, which only exists in releases newer than dcode's exact deepagents==0.7.0 pin — delegating would gate this fix on an SDK release and a pin bump, and add another private-SDK coupling. The mirrored tests in test_extras_info.py keep the two implementations honest.

The editability tests were reworked to patch the new seams (distributions, _running_sdk_package_root) instead of handing a fabricated direct_url.json payload to a distribution() mock. Some expectations changed for correctness reasons, not just mocking reasons: the egg-info-shadowing case now resolves the editable source version instead of falling back to metadata.

Behavior change to call out

This is not pure cleanup. In the egg-info-shadowing scenario dcode previously concluded "not editable" and reported the metadata version; it now concludes "editable" and reports the checkout's source version. That is the intended fix — developer environments will see their SDK version reported as the live source version (matching the SDK's own trace entry) rather than stale install metadata.

`_editable_sdk_source_root` used a single `distribution("deepagents")` lookup
with no correlation against the running package, so it disagreed with the SDK's
own `lc_versions.deepagents` trace entry in both directions: a source-tree
`deepagents.egg-info/` (which carries no `direct_url.json`) shadowed a real
editable install and read "not editable", while an unrelated editable record
could be credited to a published wheel install.

Port the SDK's scan-and-correlate approach into dcode: scan every installed
`deepagents` distribution for a PEP 610 editable record, and credit it only
when its source root contains the package `find_spec` would import. The probe
locates the package without importing it, preserving the "version lookup must
not import the SDK" invariant. Per-distribution metadata failures are
contained so one unreadable record cannot abort the scan, and the
`distributions()` backstop now also swallows `RecursionError` so pathological
metadata cannot make the answer iteration-order-dependent.

dcode keeps its own copy rather than importing the SDK helper: the SDK's
version is a private symbol that only exists in releases newer than dcode's
exact `deepagents` pin, so delegating would gate the fix on an SDK release and
a pin bump.
@github-actions github-actions Bot added dcode Related to `deepagents-code` fix A bug fix (PATCH) internal User is a member of the `langchain-ai` GitHub organization size: L 500-999 LOC labels Jul 30, 2026

@open-swe open-swe Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Open SWE Review: No issues found

Open SWE reviewed this PR and found no potential bugs to report.

Open in WebView Open SWE trace

@mdrxy
Mason Daugherty (mdrxy) merged commit 4693ee7 into main Jul 30, 2026
58 checks passed
@mdrxy
Mason Daugherty (mdrxy) deleted the mdrxy/code/fix-editable-sdk-detection branch July 30, 2026 17:59
Mason Daugherty (mdrxy) added a commit that referenced this pull request Jul 30, 2026
`dcode` now detects an editable `deepagents` SDK install the same way
the SDK itself does, so the two stop disagreeing about the same
installation. A trace that previously showed `lc_versions.deepagents =
"0.7.0+editable"` alongside `dcode_client_deepagents_version = "0.7.0"`
for one install now reports the editable source version on both.

---

## Why

`_editable_sdk_source_root` answered "is the installed `deepagents`
editable, and where is its source?" with a single
`importlib.metadata.distribution("deepagents")` lookup and no
correlation against the running package. The SDK's
`_is_editable_install` does more, and both extra steps guard real
errors:

- **Scan every matching distribution instead of one lookup.**
`setuptools` leaves a gitignored `deepagents.egg-info/` in the source
tree after any local build, and the cwd is on `sys.path` for `-c`, `-m`,
and the REPL — so from a checkout that directory is found *first* and
carries no `direct_url.json`. The single-lookup form concluded "not
editable" and never consulted the real editable install in
site-packages. In that scenario dcode fell back to package metadata for
the version while the SDK stamped `+editable`; after this change dcode
correctly reads the version from the checkout's `_version.py`.
- **Correlate the record with the running package.** An environment can
hold several `deepagents` records — a wheel earlier on `sys.path` plus
an unrelated editable checkout later on it. Crediting the wrong one
labels a published install as a workspace build.

## What changed

dcode's `_editable_sdk_source_root` now scans every installed
`deepagents` distribution for a PEP 610 `dir_info.editable: true` record
and credits it only when its source root contains the package
`find_spec` would import, mirroring the SDK's logic. The correlation
anchor is located with `importlib.util.find_spec` rather than an
`import`, so the existing "SDK version lookup must not import the SDK"
invariant (`test_dcode_client_deepagents_version_does_not_import_sdk`)
still holds. Per-distribution metadata failures are contained so one
unreadable record cannot abort the scan early; the `distributions()`
backstop also swallows `RecursionError` so pathological metadata cannot
make the answer depend on iteration order.

**dcode keeps its own copy rather than importing the SDK helper.** The
SDK's scan lives in the private `_is_editable_install`, which only
exists in releases newer than dcode's exact `deepagents==0.7.0` pin —
delegating would gate this fix on an SDK release and a pin bump, and add
another private-SDK coupling. The mirrored tests in
`test_extras_info.py` keep the two implementations honest.

The editability tests were reworked to patch the new seams
(`distributions`, `_running_sdk_package_root`) instead of handing a
fabricated `direct_url.json` payload to a `distribution()` mock. Some
expectations changed for correctness reasons, not just mocking reasons:
the egg-info-shadowing case now resolves the editable source version
instead of falling back to metadata.

## Behavior change to call out

This is not pure cleanup. In the egg-info-shadowing scenario dcode
previously concluded "not editable" and reported the metadata version;
it now concludes "editable" and reports the checkout's source version.
That is the intended fix — developer environments will see their SDK
version reported as the live source version (matching the SDK's own
trace entry) rather than stale install metadata.
Mason Daugherty (mdrxy) pushed a commit that referenced this pull request Jul 31, 2026
> [!CAUTION]
> Merging this PR will automatically publish to **PyPI** and create a
**GitHub release**.

For the full release process, see
[`.github/RELEASING.md`](https://github.com/langchain-ai/deepagents/blob/main/.github/RELEASING.md).

---

_Release notes preview: keep this section in sync with the package
`CHANGELOG.md`. Publish reads the merged CHANGELOG via `release.yml`,
not this PR description — keep them aligned anyway so the PR stays an
accurate historical record for reviewers and anyone returning later._

---


##
[0.1.51](deepagents-code==0.1.50...deepagents-code==0.1.51)
(2026-07-31)

### Features

- The status bar and usage view now show the running session cost.
([#5036](#5036))
- Removed redundant `shell` and `web_search` prompt guidance.
([#5213](#5213))
- After switching threads, Deep Agents now points back to the previous
thread.
([#5172](#5172))
- Leaving `/mcp` with pending toggles now prompts you to reconnect.
([#5211](#5211))
- `dcode config get` now accepts configuration sections.
([#5134](#5134))

### Fixes

- Kept the `/goal` criteria prompt responsive.
([#5142](#5142))
- Improved goal handling so underspecified objectives can be resolved
from conversation context.
([#5201](#5201))
- Released the turn when an interrupted worker never starts.
([#5196](#5196))
- Hid timestamp footers together with their associated rows.
([#5167](#5167))
- Fixed editable SDK detection by scanning and correlating SDK locations
more accurately.
([#5199](#5199))
- Improved `doctor` output to explain why it may not have a
latest-version answer.
([#5209](#5209))

_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>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

dcode Related to `deepagents-code` fix A bug fix (PATCH) internal User is a member of the `langchain-ai` GitHub organization size: L 500-999 LOC

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant