Skip to content

fix(docker): include anthropic, bedrock, azure-identity extras in image#30504

Merged
benbarclay merged 1 commit into
NousResearch:mainfrom
ilonagaja509-glitch:fix/30394-docker-anthropic-package
May 27, 2026
Merged

fix(docker): include anthropic, bedrock, azure-identity extras in image#30504
benbarclay merged 1 commit into
NousResearch:mainfrom
ilonagaja509-glitch:fix/30394-docker-anthropic-package

Conversation

@ilonagaja509-glitch

Copy link
Copy Markdown
Contributor

Fixes #30394

Problem

Docker containers often run in isolated networks without access to PyPI. The lazy-install mechanism fails silently in these environments, causing ImportError when users try to use Anthropic, Bedrock, or Azure providers.

Error message:

Sorry, I encountered an error (ImportError).
The 'anthropic' package is required for the Anthropic provider. Install it with: pip install 'anthropic>=0.39.0'

Root Cause

The [all] extra was intentionally slimmed down on 2026-05-12 to avoid quarantined PyPI packages breaking installs. Provider packages like anthropic, bedrock, and azure-identity were moved to lazy-install.

However, Docker containers in air-gapped or restricted networks cannot reach PyPI at runtime, so lazy-install fails.

Solution

Add --extra anthropic, --extra bedrock, and --extra azure-identity to the Dockerfile's uv sync command so these provider packages are pre-installed in the published image.

This ensures Docker users can use these common providers without requiring runtime network access to PyPI.

Docker containers often run in isolated networks without access to PyPI.
The lazy-install mechanism fails silently in these environments, causing
ImportError when users try to use Anthropic, Bedrock, or Azure providers.

Add --extra anthropic, --extra bedrock, and --extra azure-identity to the
Dockerfile's uv sync command so these provider packages are pre-installed
in the published image.

Fixes NousResearch#30394
@alt-glitch alt-glitch added type/bug Something isn't working P2 Medium — degraded but workaround exists backend/docker Docker container execution area/docker Docker image, Compose, packaging labels May 22, 2026

@keegoid-codex keegoid-codex left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Verdict

VERDICT: approve


codex-review posting override: forced to --comment because reviewer lacks verified write permission (viewerPermission=READ; was --approve). GitHub only counts approvals from WRITE, MAINTAIN, or ADMIN reviewers.

@keegoid-cc

Copy link
Copy Markdown

[DEV SecOps] verdict: PASS
verified at b96a1a0

Scope: #30504, base main, changed file: Dockerfile only.

  • Prompt-injection: no findings. Scanned PR title/body, commit message, Dockerfile diff comments/strings, trigger fixture patterns, and bidi/zero-width controls; no matches.
  • Dependency / lockfile risk: no blocking findings. PR does not modify pyproject.toml or uv.lock; it changes Docker image install selection to include already-declared, already-locked extras: anthropic==0.86.0, boto3==1.42.89 via bedrock, azure-identity==1.25.3. PyPI registry checks succeeded: anthropic official SDK repo github.com/anthropics/anthropic-sdk-python, last-week downloads 30,578,706; boto3 AWS SDK repo github.com/boto/boto3, last-week downloads 766,216,432; azure-identity Microsoft Azure SDK repo github.com/Azure/azure-sdk-for-python, last-week downloads 49,476,052. Wheels are present for all three pinned versions; no npm-style install scripts introduced.
  • CI / workflow injection: no findings. No workflow or CI files changed; no pull_request_target, secrets.*, self-hosted runner, github.event, or inputs interpolation added.
  • Generated/copied code provenance: no findings. Diff is 6 Dockerfile lines; no generated/copied code block.
  • Lockfile sanity: PASS. Lockfile unchanged and proportional because the selected extras already exist in pyproject.toml and uv.lock.
  • Secret exposure / unsafe permission changes / suspicious egress: no findings. No secrets, chmod/chown widening, curl/wget/nc, eval, shell-wrapper expansion, or new network egress command added beyond the existing frozen uv install step.

Residual risk: Docker image size and provider import behavior are functional/ops concerns outside this security gate; registry ownership-transfer history is not directly exposed by PyPI APIs, but package identity, repository provenance, upload metadata, hashes, and download health checked clean for the pinned versions above.

@keegoid-codex keegoid-codex left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Severity

  • low. Dockerfile-only install selection; no runtime code path changed.

VERDICT: approve


codex-review posting override: forced to --comment because reviewer lacks verified write permission (viewerPermission=READ; was --approve). GitHub only counts approvals from WRITE, MAINTAIN, or ADMIN reviewers.

@keegoid-cc

Copy link
Copy Markdown

[DEV SecOps] verdict: PASS
verified at b96a1a0

Categories:

  • Prompt-injection: no findings. Scanned PR title/body, commit message, and Dockerfile diff for trigger phrases and hidden Unicode steering controls.
  • Dependency / lockfile: no blocking findings. Dockerfile line 85 now enables existing extras only: anthropic==0.86.0, boto3==1.42.89 via bedrock, and azure-identity==1.25.3. uv sync --frozen continues to require the existing uv.lock; direct pins are present in the lock with PyPI hashes. Registry spot-check: official Anthropic SDK, AWS SDK for Python, and Microsoft Azure Identity packages; weekly downloads observed via pypistats: anthropic 30,578,706; boto3 766,216,432; azure-identity 49,476,052. No manifest or lockfile churn in this PR.
  • CI / workflow injection: no findings. No workflow/CI files touched; no ${{ inputs.* }} / ${{ github.event.* }} run interpolation, pull_request_target, new secrets reads, or self-hosted runner labels.
  • Generated/copied code provenance: no findings. Diff is a small Dockerfile command/comment change, not copied/generated code block.
  • Secret exposure / credential handling: no findings. No secrets, tokens, private keys, or credential paths added.
  • Ops/security regression: no blocking findings. Change increases Docker image dependency surface by preinstalling three provider SDK extras, but does so through pinned, locked PyPI packages at build time and avoids runtime lazy-install network access for those providers.

Read-only checks used: GitHub PR metadata/API diff pinned to the SHA above; Dockerfile/pyproject/uv.lock static inspection; prompt-injection trigger scan; PyPI + pypistats direct-package registry spot-check. No PR code executed.

Residual risk: PyPI ownership-transfer history is not exposed by the public PyPI JSON API; mitigated by official vendor package identities, high package age/downloads, and existing uv.lock hashes. Transitive package risk remains the same class as the existing locked optional extras; this PR does not alter lock contents.

@benbarclay benbarclay left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the fix — the bug is real and the scope is right.

I verified the premise against current origin/main (1e71b71):

  • pyproject.toml's [all] extra (line 179) explicitly excludes anthropic, bedrock, azure-identity per the 2026-05-12 lazy-install policy.
  • Dockerfile currently runs uv sync --frozen --no-install-project --extra all --extra messaging, so those provider packages are not in the published image.
  • tools/lazy_deps.py registers provider.anthropic, provider.bedrock, provider.azure_identity — these install from PyPI at first use, which is exactly what air-gapped Docker users can't do. Issue #30394 (Rocky9 docker) reproduces this cleanly.

The diff itself (5 added, 1 removed) is minimal and correct.

One blocking concern: this ships a CVE-vulnerable anthropic pin

There's a latent version drift on main that this PR would expose to all Docker users:

Path Version Status
tools/lazy_deps.py line 81 anthropic==0.87.0 CVE-patched (per the inline comment + PR #26830)
pyproject.toml [anthropic] extra (line 72) anthropic==0.86.0 CVE-2026-34450, CVE-2026-34452
uv.lock anthropic 0.86.0 matches the extra

This drift was introduced when the v0.14.0 release commit (a91a57f) accidentally reverted the [anthropic] extra from 0.87.0 back to 0.86.0. The lazy-install path stayed on the patched 0.87.0, so host users using lazy-install today get the fix.

But this PR routes Docker users through the [anthropic] extra — i.e. they would get baked-in 0.86.0, with both CVEs present. That's a security regression versus the current behavior where Docker users either: (a) don't use Anthropic at all (today's broken case), or (b) lazy-install and pick up 0.87.0.

The fix is small and parallels what #26830 already did:

-anthropic = ["anthropic==0.86.0"]
+anthropic = ["anthropic==0.87.0"]  # CVE-2026-34450, CVE-2026-34452

…plus a uv lock regeneration (only the anthropic entry + its hashes should move; see the uv.lock portion of d725407 for the shape).

Could you fold that into this PR? Once [anthropic] is back at 0.87.0, the Docker include is unambiguously a safety improvement.

Other observations (non-blocking)

  • Image size: adding bedrock pulls in boto3 (~50–80MB unpacked). That's the right tradeoff for an "include common providers" change, just worth being explicit so a future image-size audit doesn't try to revert this. The Dockerfile comment you added covers the rationale well.
  • Scope: I considered whether exa, firecrawl, fal, etc. should also be pulled in for the same air-gapped argument. I think keeping this PR narrowly scoped to the providers from the linked issue is right — pulling in more lazy-install extras is a separate policy conversation (and messaging, matrix, slack are even more loaded since matrix has the python-olm Windows-build issue called out in pyproject.toml's [all] comment). The current scope is defensible.
  • Secops bot flagged this as PASS on supply-chain grounds and I agree with that read — the extras are already declared, already locked, and the diff doesn't churn the lockfile.

LGTM modulo the anthropic pin bump. Once that's in I'll re-review and land it.

@benbarclay benbarclay left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Approving to unblock the merge.

Confirmed with @teknium1 offline that the anthropic 0.86.0 → 0.87.0 bump (CVE-2026-34450, CVE-2026-34452) is being handled separately. That keeps this PR cleanly scoped to the air-gapped-Docker fix from #30394, where it belongs.

For posterity: the relevant CVEs are SDK filesystem-memory-tool issues that aren't directly exploitable from hermes-agent's call paths (per Teknium's commit message on the original bump in d725407 / #26830 — "Not directly exploitable since hermes-agent doesn't use the SDK's filesystem memory tool"), so shipping 0.86.0 in a published image for the short window between this merge and the version bump is acceptable hygiene-level exposure, not a directly exploitable vulnerability.

Thanks for the clean fix. Merging.

@benbarclay benbarclay merged commit bb65beb into NousResearch:main May 27, 2026
gweeteve pushed a commit to gweeteve/hermes-agent that referenced this pull request Jun 2, 2026
…394-docker-anthropic-package

fix(docker): include anthropic, bedrock, azure-identity extras in image

Fixes NousResearch#30394. Air-gapped/restricted-network Docker containers can't reach
PyPI for lazy-install, so `--extra anthropic --extra bedrock --extra
azure-identity` are now added to the Dockerfile's `uv sync` so these
provider packages are baked into the published image.

The [all] extra deliberately excludes these (per the 2026-05-12
lazy-install policy on [all]) to keep `uv sync --locked` from breaking
when one of their pinned versions gets PyPI-quarantined. The Dockerfile
adds them back via additive --extra flags, mirroring the existing
--extra messaging pattern (issue NousResearch#24698 / test_dockerfile_pid1_reaping.py).

Follow-up: separate PR will bump pyproject.toml's [anthropic] extra
from 0.86.0 to 0.87.0 to converge with tools/lazy_deps.py's
CVE-patched pin (CVE-2026-34450, CVE-2026-34452).
benbarclay added a commit that referenced this pull request Jun 3, 2026
The native Hindsight memory provider lazy-installs hindsight-client into
/opt/hermes/.venv at first use (tools/lazy_deps.py: memory.hindsight).
That venv lives inside the immutable image layer, not the mounted
/opt/data volume, so the dependency is wiped on every container recreate
/ image update. After an update, profile config still points at Hindsight
and the Hindsight server is healthy, but recall/retain fails with:

    ModuleNotFoundError: No module named 'hindsight_client'

The manual workaround (uv pip install hindsight-client inside the running
container) doesn't survive the next recreate, and pip-install-into-.venv
is not an officially supported durable Docker workflow.

Fix: add --extra hindsight to the image's uv sync line, same pattern as
the --extra anthropic/bedrock/azure-identity providers (#30504) and
--extra messaging (#24698) — bake the optional dependency into the build
layer so it survives container recreate. The pyproject [hindsight] pin
(hindsight-client==0.6.1) already matches tools/lazy_deps.py and uv.lock,
so this is a pure additive --extra with no lockfile churn.

Verified: 'uv sync --frozen --no-install-project --extra hindsight'
against the committed uv.lock installs hindsight-client 0.6.1 and the
module imports cleanly.

Adds a regression test (mirrors test_dockerfile_preinstalls_gateway_
messaging_dependencies) so a future Dockerfile cleanup can't silently
drop the extra.
Yuki-14544869 pushed a commit to Yuki-14544869/hermes-agent that referenced this pull request Jun 4, 2026
NousResearch#38530)

The native Hindsight memory provider lazy-installs hindsight-client into
/opt/hermes/.venv at first use (tools/lazy_deps.py: memory.hindsight).
That venv lives inside the immutable image layer, not the mounted
/opt/data volume, so the dependency is wiped on every container recreate
/ image update. After an update, profile config still points at Hindsight
and the Hindsight server is healthy, but recall/retain fails with:

    ModuleNotFoundError: No module named 'hindsight_client'

The manual workaround (uv pip install hindsight-client inside the running
container) doesn't survive the next recreate, and pip-install-into-.venv
is not an officially supported durable Docker workflow.

Fix: add --extra hindsight to the image's uv sync line, same pattern as
the --extra anthropic/bedrock/azure-identity providers (NousResearch#30504) and
--extra messaging (NousResearch#24698) — bake the optional dependency into the build
layer so it survives container recreate. The pyproject [hindsight] pin
(hindsight-client==0.6.1) already matches tools/lazy_deps.py and uv.lock,
so this is a pure additive --extra with no lockfile churn.

Verified: 'uv sync --frozen --no-install-project --extra hindsight'
against the committed uv.lock installs hindsight-client 0.6.1 and the
module imports cleanly.

Adds a regression test (mirrors test_dockerfile_preinstalls_gateway_
messaging_dependencies) so a future Dockerfile cleanup can't silently
drop the extra.
davidgut1982 pushed a commit to davidgut1982/hermes-agent that referenced this pull request Jun 5, 2026
NousResearch#38530)

The native Hindsight memory provider lazy-installs hindsight-client into
/opt/hermes/.venv at first use (tools/lazy_deps.py: memory.hindsight).
That venv lives inside the immutable image layer, not the mounted
/opt/data volume, so the dependency is wiped on every container recreate
/ image update. After an update, profile config still points at Hindsight
and the Hindsight server is healthy, but recall/retain fails with:

    ModuleNotFoundError: No module named 'hindsight_client'

The manual workaround (uv pip install hindsight-client inside the running
container) doesn't survive the next recreate, and pip-install-into-.venv
is not an officially supported durable Docker workflow.

Fix: add --extra hindsight to the image's uv sync line, same pattern as
the --extra anthropic/bedrock/azure-identity providers (NousResearch#30504) and
--extra messaging (NousResearch#24698) — bake the optional dependency into the build
layer so it survives container recreate. The pyproject [hindsight] pin
(hindsight-client==0.6.1) already matches tools/lazy_deps.py and uv.lock,
so this is a pure additive --extra with no lockfile churn.

Verified: 'uv sync --frozen --no-install-project --extra hindsight'
against the committed uv.lock installs hindsight-client 0.6.1 and the
module imports cleanly.

Adds a regression test (mirrors test_dockerfile_preinstalls_gateway_
messaging_dependencies) so a future Dockerfile cleanup can't silently
drop the extra.
changman pushed a commit to changman/hermes-agent that referenced this pull request Jun 10, 2026
NousResearch#38530)

The native Hindsight memory provider lazy-installs hindsight-client into
/opt/hermes/.venv at first use (tools/lazy_deps.py: memory.hindsight).
That venv lives inside the immutable image layer, not the mounted
/opt/data volume, so the dependency is wiped on every container recreate
/ image update. After an update, profile config still points at Hindsight
and the Hindsight server is healthy, but recall/retain fails with:

    ModuleNotFoundError: No module named 'hindsight_client'

The manual workaround (uv pip install hindsight-client inside the running
container) doesn't survive the next recreate, and pip-install-into-.venv
is not an officially supported durable Docker workflow.

Fix: add --extra hindsight to the image's uv sync line, same pattern as
the --extra anthropic/bedrock/azure-identity providers (NousResearch#30504) and
--extra messaging (NousResearch#24698) — bake the optional dependency into the build
layer so it survives container recreate. The pyproject [hindsight] pin
(hindsight-client==0.6.1) already matches tools/lazy_deps.py and uv.lock,
so this is a pure additive --extra with no lockfile churn.

Verified: 'uv sync --frozen --no-install-project --extra hindsight'
against the committed uv.lock installs hindsight-client 0.6.1 and the
module imports cleanly.

Adds a regression test (mirrors test_dockerfile_preinstalls_gateway_
messaging_dependencies) so a future Dockerfile cleanup can't silently
drop the extra.
alt-glitch pushed a commit that referenced this pull request Jun 14, 2026
…nthropic-package

fix(docker): include anthropic, bedrock, azure-identity extras in image

Fixes #30394. Air-gapped/restricted-network Docker containers can't reach
PyPI for lazy-install, so `--extra anthropic --extra bedrock --extra
azure-identity` are now added to the Dockerfile's `uv sync` so these
provider packages are baked into the published image.

The [all] extra deliberately excludes these (per the 2026-05-12
lazy-install policy on [all]) to keep `uv sync --locked` from breaking
when one of their pinned versions gets PyPI-quarantined. The Dockerfile
adds them back via additive --extra flags, mirroring the existing
--extra messaging pattern (issue #24698 / test_dockerfile_pid1_reaping.py).

Follow-up: separate PR will bump pyproject.toml's [anthropic] extra
from 0.86.0 to 0.87.0 to converge with tools/lazy_deps.py's
CVE-patched pin (CVE-2026-34450, CVE-2026-34452).
alt-glitch pushed a commit that referenced this pull request Jun 14, 2026
The native Hindsight memory provider lazy-installs hindsight-client into
/opt/hermes/.venv at first use (tools/lazy_deps.py: memory.hindsight).
That venv lives inside the immutable image layer, not the mounted
/opt/data volume, so the dependency is wiped on every container recreate
/ image update. After an update, profile config still points at Hindsight
and the Hindsight server is healthy, but recall/retain fails with:

    ModuleNotFoundError: No module named 'hindsight_client'

The manual workaround (uv pip install hindsight-client inside the running
container) doesn't survive the next recreate, and pip-install-into-.venv
is not an officially supported durable Docker workflow.

Fix: add --extra hindsight to the image's uv sync line, same pattern as
the --extra anthropic/bedrock/azure-identity providers (#30504) and
--extra messaging (#24698) — bake the optional dependency into the build
layer so it survives container recreate. The pyproject [hindsight] pin
(hindsight-client==0.6.1) already matches tools/lazy_deps.py and uv.lock,
so this is a pure additive --extra with no lockfile churn.

Verified: 'uv sync --frozen --no-install-project --extra hindsight'
against the committed uv.lock installs hindsight-client 0.6.1 and the
module imports cleanly.

Adds a regression test (mirrors test_dockerfile_preinstalls_gateway_
messaging_dependencies) so a future Dockerfile cleanup can't silently
drop the extra.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/docker Docker image, Compose, packaging backend/docker Docker container execution P2 Medium — degraded but workaround exists type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: docker镜像缺少'anthropic'包

5 participants