Hindsight memory provider missing-dependency handling
NousResearch/hermes-agent · cluster 8873 · agent
Data as of
Nothing open on GitHub. Fix merged in #21818. Check it covers your case.
The short answer
- Known?
- Yes. 10 related items grouped here, 4 issues already closed.
- Fix event
- A fix was merged to main in PR #21818. Check it covers your case. No release data is tracked.
- Tracker
- The maintainers' tracker marks this
partially resolved, deciding PRs #21818, #38530. That is separate from the fix event. - Still open
- Nothing open on GitHub.
These issues and fixes center on the hindsight-client package being absent, optional, or lost, causing gateway crashes or silent failures. Work covers import guards, early failure, optional dependency declarations, and baking the client into Docker images.
Open issues0
Open PRs0
Fixes on record
-
#21818 feat(deps): add hindsight-client as optional dependency
files:
pyproject.tomlShow the diff
-
pyproject.toml@@ -55,6 +55,7 @@ dependencies = [ modal = ["modal>=1.0.0,<2"] daytona = ["daytona>=0.148.0,<1"] vercel = ["vercel>=0.5.7,<0.6.0"] +hindsight = ["hindsight-client>=0.4.22"] dev = ["debugpy>=1.8.0,<2", "pytest>=9.0.2,<10", "pytest-asyncio>=1.3.0,<2", "pytest-xdist>=3.0,<4", "pytest-split>=0.9,<1", "mcp>=1.2.0,<2", "ty>=0.0.1a29,<0.0.22", "ruff"] messaging = ["python-telegram-bot[webhooks]>=22.6,<23", "discord.py[voice]>=2.7.1,<3", "aiohttp>=3.13.3,<4", "slack-bolt>=1.18.0,<2", "slack-sdk>=3.27.0,<4", "qrcode>=7.0,<8"] cron = [] # croniter is now a core dependency; this extra kept for back-compat -
uv.lock@@ -8,10 +8,6 @@ resolution-markers = [ "python_full_version < '3.12'", ] -[options] -exclude-newer = "2026-05-01T22:46:56.926194148Z" -exclude-newer-span = "P7D" - [[package]] name = "agent-client-protocol" version = "0.9.0" @@ -1273,6 +1269,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e0/c3/7f67dea8ccf8fdcb9c99033bbe3e90b9e7395415843accb81428c441be2d/debugpy-1.8.20-py2.py3-none-any.whl", hash = "sha256:5be9bed9ae3be00665a06acaa48f8329d2b9632f15fd09f6a9a8c8d9907e54d7", size = 5337658, upload-time = "2026-01-29T23:04:17.404Z" }, ] +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + [[package]] name = "deprecated" version = "1.3.1" @@ -2014,6 +2019,7 @@ all = [ { name = "ptyprocess", marker = "sys_platform != 'win32'" }, { name = "pytest" }, { name = "pytest-asyncio" }, + { name = "pytest-split" }, { name = "pytest-xdist" }, { name = "python-telegram-bot", extra = ["webhooks"] }, { name = "pywinpty", marker = "sys_platform == 'win32'" }, @@ -2026,6 +2032,7 @@ all = [ { name = "ty" }, { name = "uvicorn", extra = ["standard"] }, { name = "vercel" }, + { name = "youtube-transcript-api" }, ] bedrock = [ { name = "boto3" }, @@ -2044,6 +2051,7 @@ dev = [ { name = "mcp" }, { name = "pytest" }, { name = "pytest-asyncio" }, + { name = "pytest-split" }, { name = "pytest-xdist" }, { name = "ruff" }, { name = "ty" }, @@ -2062,6 +2070,9 @@ google = [ { name = "google-auth-httplib2" }, { name = "google-auth-oauthlib" }, ] +hindsight = [ + { name = "hindsight-client" }, +] homeassistant = [ { name = "aiohttp" }, ] @@ -2162,6 +2173,9 @@ web = [ yc-bench = [ { name = "yc-bench", marker = "python_full_version >= '3.12'" }, ] +youtube = [ + { name = "youtube-transcript-api" }, +] [package.metadata] requires-dist = [ @@ -2234,6 +2248,8 @@ requires-dist = [ { name = "hermes-agent", extras = ["voice"], marker = "extra == 'all'" }, { name = "hermes-agent", extras = ["web"], marker = "extra == 'all'" }, { name = "hermes-agent", extras = ["web"], marker = "extra == 'termux-all'" }, + { name = "hermes-agent", extras = ["youtube"], marker = "extra == 'all'" }, + { name = "hindsight-client", marker = "extra == 'hindsight'", specifier = ">=0.4.22" }, { name = "honcho-ai", marker = "extra == 'honcho'", specifier = ">=2.0.1,<3" }, { name = "httpx", extras = ["socks"], specifier = ">=0.28.1,<1" }, { name = "jinja2", specifier = ">=3.1.5,<4" }, @@ -2255,6 +2271,7 @@ requires-dist = [ { name = "pyjwt", extras = ["crypto"], specifier = ">=2.12.0,<3" }, { name = "pytest", marker = "extra == 'dev'", specifier = ">=9.0.2,<10" }, { name = "pytest-asyncio", marker = "extra == 'dev'", specifier = ">=1.3.0,<2" }, + { name = "pytest-split", marker = "extra == 'dev'", specifier = ">=0.9,<1" }, { name = "pytest-xdist", marker = "extra == 'dev'", specifier = ">=3.0,<4" }, { name = "python-dotenv", specifier = ">=1.2.1,<2" }, { name = "python-telegram-bot", extras = ["webhooks"], marker = "extra == 'messaging'", specifier = ">=22.6,<23" }, @@ -2283,8 +2300,9 @@ requires-dist = [ { name = "vercel", marker = "extra == 'vercel'", specifier = ">=0.5.7,<0.6.0" }, { name = "wandb", marker = "extra == 'rl'", specifier = ">=0.15.0,<1" }, { name = "yc-bench", marker = "python_full_version >= '3.12' and extra == 'yc-bench'", git = "https://github.com/collinear-ai/yc-bench.git?rev=bfb0c88062450f46341bd9a5298903fc2e952a5c" }, + { name = "youtube-transcript-api", marker = "extra == 'youtube'", specifier = ">=1.2.0" }, ] -provides-extras = ["modal", "daytona", "vercel", "dev", "messaging", "cron", "slack", "matrix", "cli", "tts-premium", "voice", "pty", "honcho", "mcp", "homeassistant", "sms", "computer-use", "acp", "mistral", "bedrock", "termux", "termux-all", "dingtalk", "feishu", "google", "web", "rl", "yc-bench", "all"] +provides-extras = ["modal", "daytona", "vercel", "hindsight", "dev", "messaging", "cron", "slack", "matrix", "cli", "tts-premium", "voice", "pty", "honcho", "mcp", "homeassistant", "sms", "computer-use", "acp", "mistral", "bedrock", "termux", "termux-all", "dingtalk", "feishu", "google", "youtube", "web", "rl", "yc-bench", "all"] [[package]] name = "hf-transfer" @@ -2350,6 +2368,23 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/4e/46/1ba8d36f8290a4b98f78898bdce2b0e8fe6d9a59df34a1399eb61a8d877f/hf_xet-1.3.1-cp37-abi3-win_arm64.whl", hash = "sha256:851b1be6597a87036fe7258ce7578d5df3c08176283b989c3b165f94125c5097", size = 3500490, upload-time = "2026-02-25T00:58:00.667Z" }, ] +[[package]] +name = "hindsight-client" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aiohttp" }, + { name = "aiohttp-retry" }, + { name = "pydantic" }, + { name = "python-dateutil" }, + { name = "typing-extensions" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/26/8b8efa4be21fc3ba12ade3b1353d87f9837ec0d3ec2607e8adbf85bc9c63/hindsight_client-0.6.1.tar.gz", hash = "sha256:314d0bb9e13622e15586ba1586a799726d405b27bc20d78872474b5d6d96cd51", size = 99833, upload-time = "2026-05-08T13:01:23.537Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/4f/a1d0bc33ef933ecc52e76dc1514163594d25836a5d303c256a61bb61445d/hindsight_client-0.6.1-py3-none-any.whl", hash = "sha256:9fdda176ab50f7cec8d7339c6608c148f0cd9ad7e65d9d76192f2db730bc330a", size = 249379, upload-time = "2026-05-08T13:01:22.035Z" }, +] + [[package]] name = "honcho-ai" version = "2.0.1" @@ -4439,6 +4474,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/e5/35/f8b19922b6a25bc0880171a2f1a003eaeb93657475193ab516fd87cac9da/pytest_asyncio-1.3.0-py3-none-any.whl", hash = "sha256:611e26147c7f77640e6d0a92a38ed17c3e9848063698d5c93d5aa7aa11cebff5", size = 15075, upload-time = "2025-11-10T16:07:45.537Z" }, ] +[[package]] +name = "pytest-split" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/16/8af4c5f2ceb3640bb1f78dfdf5c184556b10dfe9369feaaad7ff1c13f329/pytest_split-0.11.0.tar.gz", hash = "sha256:8ebdb29cc72cc962e8eb1ec07db1eeb98ab25e215ed8e3216f6b9fc7ce0ec2b5", size = 13421, upload-time = "2026-02-03T09:14:31.469Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ae/a1/d4423657caaa8be9b31e491592b49cebdcfd434d3e74512ce71f6ec39905/pytest_split-0.11.0-py3-none-any.whl", hash = "sha256:899d7c0f5730da91e2daf283860eb73b503259cb416851a65599368849c7f382", size = 11911, upload-time = "2026-02-03T09:14:33.708Z" }, +] + [[package]] name = "pytest-xdist" version = "3.8.0" @@ -6165,6 +6212,19 @@ dependencies = [ { name = "typer", marker = "python_full_version >= '3.12'" }, ] +[[package]] +name = "youtube-transcript-api" +version = "1.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "defusedxml" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/60/43/4104185a2eaa839daa693b30e15c37e7e58795e8e09ec414f22b3db54bec/youtube_transcript_api-1.2.4.tar.gz", hash = "sha256:b72d0e96a335df599d67cee51d49e143cff4f45b84bcafc202ff51291603ddcd", size = 469839, upload-time = "2026-01-29T09:09:17.088Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/be/95/129ea37efd6cd6ed00f62baae6543345c677810b8a3bf0026756e1d3cf3c/youtube_transcript_api-1.2.4-py3-none-any.whl", hash = "sha256:03878759356da5caf5edac77431780b91448fb3d8c21d4496015bdc8a7bc43ff", size = 485227, upload-time = "2026-01-29T09:09:15.427Z" }, +] + [[package]] name = "zipp" version = "3.23.0"
-
-
#38530 fix(docker): bake hindsight-client into the image (#38128)
files:
Dockerfile,tests/tools/test_dockerfile_pid1_reaping.pyShow the diff
-
Dockerfile@@ -157,10 +157,17 @@ RUN npm install --prefer-offline --no-audit && \ # so Docker users can use these providers without requiring runtime # lazy-install access to PyPI (often blocked in containerized envs). # +# The hindsight memory provider's client (hindsight-client) is baked in +# for the same reason: it lazy-installs into /opt/hermes/.venv at first +# use, which lives inside the (immutable) image layer rather than the +# mounted /opt/data volume, so it is lost on every container recreate / +# image update and recall/retain then fails with +# `ModuleNotFoundError: No module named 'hindsight_client'` (#38128). +# # The editable link is created after the source copy below. COPY pyproject.toml uv.lock ./ RUN touch ./README.md -RUN uv sync --frozen --no-install-project --extra all --extra messaging --extra anthropic --extra bedrock --extra azure-identity +RUN uv sync --frozen --no-install-project --extra all --extra messaging --extra anthropic --extra bedrock --extra azure-identity --extra hindsight # ---------- Source code ---------- # .dockerignore excludes node_modules, so the installs above survive. -
tests/tools/test_dockerfile_pid1_reaping.py@@ -172,6 +172,23 @@ def test_dockerfile_preinstalls_gateway_messaging_dependencies(dockerfile_text): ) +def test_dockerfile_preinstalls_hindsight_memory_dependency(dockerfile_text): + sync_steps = [ + step for step in _run_steps(dockerfile_text) + if "uv sync" in step and "--no-install-project" in step + ] + + assert sync_steps, "Dockerfile must install Python dependencies with uv sync" + assert any("--extra hindsight" in step for step in sync_steps), ( + "Published Docker images must preload the [hindsight] extra so the " + "native Hindsight memory provider's client (hindsight-client) is baked " + "into /opt/hermes/.venv. It lazy-installs into the image layer (not the " + "mounted /opt/data volume), so without baking it in recall/retain fails " + "with `ModuleNotFoundError: No module named 'hindsight_client'` after " + "every container recreate / image update (#38128)." + ) + + def test_dockerfile_builds_tui_assets(dockerfile_text): assert any( "ui-tui" in step and "npm" in step and "run build" in step
-
4 PRs closed without merging
From the close comments: done elsewhere 2 · duplicate 1 · superseded by another PR 1
-
#18882 fix(hindsight): guard against missing hindsight-client in cloud/external modes · done elsewhere →
6c44471 -
#18924 fix(memory): guard hindsight_client import to prevent gateway crash when package missing · superseded by another PR →
55ac056,#18876 -
#22586 fix(memory): probe hindsight_client import in is_available (#18875) · duplicate →
#18882,#18924,#18875 -
#32976 fix(hindsight): guard missing cloud client dependency · done elsewhere →
6c44471
Closed issues · 4
- Closed#8873[Setup]: Hindsight-client required to use hindsight as memory provider, but can't be installed with non-container nixos config
- Closed#18875Hindsight memory provider crashes gateway with no error when hindsight-client not installed
- Closed#18876Hindsight memory provider crashes gateway when hindsight-client not installed
- Closed#38128[Bug]: Docker Hindsight memory provider loses hindsight-client after container recreate/update
How this cluster was grouped
-
Link evidence (
partly structural links): some members are connected by structural evidence (shared changed files, or a closing/superseded reference); the rest are joined by an automated relevance judgement over their text. - Members outside that structural core may belong to a different underlying problem.
-
Pairwise link density
0.19: the share of item pairs that carry a link, counting a structural link in full and a relevance-only link at 0.36.1.00means every pair is linked.
Pick up a Lab task
Check whether a fix covers the open issues here, with your own agent. Bring back evidence for maintainers.
Open the Lab