v0.51.19 — 15-PR contributor sweep + 1 in-stage absorb#1829
Merged
nesquena-hermes merged 37 commits intomasterfrom May 7, 2026
Merged
v0.51.19 — 15-PR contributor sweep + 1 in-stage absorb#1829nesquena-hermes merged 37 commits intomasterfrom
nesquena-hermes merged 37 commits intomasterfrom
Conversation
Detect IPv6 addresses (containing ':') in QuietHTTPServer.__init__ and set address_family to AF_INET6 before socket creation, fixing EAFNOSUPPORT when binding to :: or ::1. Also updates the loopback check to recognize ::1 and the container warning to mention :: as the IPv6 equivalent of 0.0.0.0. Documents IPv6 usage in HERMES_WEBUI_HOST env var description.
Without symlinks=True, mise/asdf shared-library Python builds on macOS
default venv to copy mode. The copied python3 binary still references
@executable_path/../lib/libpython3.X.dylib in its load command, but the
dylib is never copied into .venv/lib — so any import in the new venv
(starting with ensurepip) aborts with SIGABRT.
Reproduces with mise's cpython 3.13.9 build:
[bootstrap] Creating local virtualenv at .../.venv
[bootstrap] ERROR: Command '[".../.venv/bin/python3.13", "-m",
"ensurepip", "--upgrade", "--default-pip"]' died with
<Signals.SIGABRT: 6>.
Symlinking the interpreter keeps @executable_path resolving back to the
original install where libpython lives. uv-managed Pythons already
symlink by default; mise's do not.
Addresses review feedback on PR #1815: 1. Extend the inline comment to note that CPython's venv falls back to copy mode when symlink creation fails (e.g. older Windows without SeCreateSymbolicLinkPrivilege), so symlinks=True is safe to set unconditionally — no platform branching needed. 2. Add a regression test that asserts EnvBuilder is called with symlinks=True. Cheap insurance against a future "simplify" pass removing the flag without realising it's load-bearing on macOS.
`discover_agent_dir()` only checked four hard-coded layouts:
- HERMES_WEBUI_AGENT_DIR
- $HERMES_HOME/hermes-agent
- <webui-parent>/hermes-agent
- ~/.hermes/hermes-agent / ~/hermes-agent
Users who clone hermes-agent somewhere else (e.g. ~/Projects/GitHub/hermes-agent)
hit:
[bootstrap] ERROR: Python environment cannot import both WebUI dependencies
and Hermes Agent. Set HERMES_WEBUI_PYTHON to the Hermes Agent venv Python
or install the WebUI requirements into that environment.
…even though the `hermes` CLI is on PATH and works fine. The CLI is a
console-script with a venv-relative shebang:
#!/path/to/hermes-agent/venv/bin/python3
After the explicit candidates miss, fall back to introspecting that shebang
and walking up parents until we find `run_agent.py`. That's a reliable
pointer to the install root regardless of where the user cloned the repo.
Tests cover happy path, no `hermes` on PATH, missing/invalid shebang,
shebang pointing outside any agent install (e.g. /usr/bin/python3), and
explicit candidates winning over the shebang fallback.
Verified end-to-end: with hermes-agent at a non-standard path,
`uv run bootstrap.py` now succeeds without any HERMES_WEBUI_AGENT_DIR
override.
Addresses review feedback on PR #1817: 1. Extend the `_agent_dir_from_hermes_cli` docstring to spell out that the shebang fallback is a last-resort discovery step, not an override. Stale clones in known candidate paths still win — same precedence as today, but now documented so a future maintainer doesn't get the wrong idea. 2. Drop the misleading "install exists but no run_agent.py" comment in `test_returns_none_when_shebang_interpreter_does_not_walk_to_run_agent`. The test exercises a shebang pointing at /usr/bin/python3 whose parents never reach a run_agent.py — it doesn't actually need a fake install dir at all. Renamed for accuracy and removed the unused _make_agent_install call.
…on + harden bootstrap test isolation Two in-stage fixes for v0.51.19 batch: 1) api/config.py — add resolve_alias=False param to _resolve_configured_provider_id() and pass it from resolve_model_provider(). The PR #1818 swap from _resolve_provider_alias() to _resolve_configured_provider_id() was correct for active-provider/badge surfaces but broke #1625's local-server-provider literal-preservation contract: 'ollama' → 'custom' and 'lm-studio' → 'lmstudio' alias-collapse caused _LOCAL_SERVER_PROVIDERS membership check to miss, breaking the model-id full-path preservation for LM Studio/Ollama. The new flag preserves the raw provider value when called from resolve_model_provider, and named-custom-slug + base-url fallback both still run unchanged. 2) tests/test_bootstrap_discover_agent.py — pin Path.home() in _isolate_discover_agent_dir so the hard-coded 'Path.home() / .hermes / hermes-agent' / 'Path.home() / hermes-agent' candidates in discover_agent_dir() can't pick up the dev machine's real install. The original PR #1817 isolation helper covered HERMES_HOME, HERMES_WEBUI_AGENT_DIR, and REPO_ROOT but missed the Path.home() leak. Both surfaced on full pytest pre-release gate, fixed in stage, ship in v0.51.19. Tests: full suite green.
… absorb - 15 contributor PRs across backend (workspace, IPv6, bootstrap pair, named custom provider routing, quota cards, live Codex models), frontend (sessions trio: optimistic-row preservation, cross-surface continuation, session-owned approval prompts; ui trio: workspace metadata strip, error toast Copy + hover-pause, file picker + HTML preview interactions), streaming (workspace-prefix dedupe), and ops (workspace user-turn repair script). - 1 in-stage absorb on api/config.py: gate _resolve_configured_provider_id alias resolution behind resolve_alias flag so resolve_model_provider preserves raw provider strings for #1625 _LOCAL_SERVER_PROVIDERS literal-match. - 1 in-stage test absorb on test_bootstrap_discover_agent.py: pin Path.home() in isolation helper so PR #1817 tests don't pick up the dev machine's real ~/.hermes/hermes-agent. - 4747 → 4790 collected (+43). 4776 pass + 11 skip + 1 xfail + 2 xpass. - Browser API harness 11/11 green. JS syntax 5/5 clean. - Opus advisor SHIP verdict, 0 MUST-FIX, 0 SHOULD-FIX in-release. Closes #1792, #1795, #1796, #1800, #1806, #1807, #1694.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
v0.51.19 — 15-PR contributor sweep + 1 in-stage absorb
Single-commit release rolling up 15 contributor PRs spanning workspace robustness, IPv6 server bind, bootstrap path discovery, named custom provider routing, quota cards (Codex/Anthropic), live Codex model listing, sidebar/composer/approval correctness, and historical-transcript repair tooling.
Constituent PRs
Backend / config
_clean_workspace_list()was destructive on macOS TCC denial; replaced with non-destructive_safe_resolve()+_workspace_access_error()that distinguishes missing/inaccessible.model.provider: <custom_providers[].name>now normalizes tocustom:<name>slug at config-resolution time. Three new helpers + base-url-to-named-slug fallback + dedup of stale base-url-derivedcustom:*slugs.QuietHTTPServer.__init__flipsaddress_family = socket.AF_INET6when host string contains':'. Loopback warning gate adds::1.bootstrap.pyvenvsymlinks=True. Fixes SIGABRT-on-import for shared-library mise/asdf Python on macOS.hermesCLI shebang #1817 by @Saik0s —bootstrap.pydiscover agent dir viahermesCLI shebang. Last-resort fallback for non-standard agent install paths.Backend / providers
/api/provider/quotato OAuth-backed providers (openai-codex,anthropic) viacron_profile_context_for_home-wrapped agent calls.hermes_cli.models.provider_model_ids("openai-codex")instead of static_PROVIDER_MODELSsnapshot.Frontend / sessions
_mergeOptimisticFirstTurnSessionsgated on_isOptimisticFirstTurnSessionRow._cross_surface_child_session; frontend keeps marked rows top-level instead of nesting.Frontend / ui
m.contentunchanged.Streaming
Ops
In-stage absorbs (during pre-release gate)
api/config.py— Addedresolve_alias=Falseflag to_resolve_configured_provider_id()soresolve_model_provider()preserves raw'ollama'/'lm-studio'/'vllm'etc. provider strings for_LOCAL_SERVER_PROVIDERSset membership in bug(config): resolve_model_provider() strips provider prefix on local model servers — LM Studio loads duplicate instance with default settings #1625's full-model-id-preservation contract. PR fix: route named custom provider model selections #1818's swap was correct for active-provider/badge surfaces but broke this branch via_resolve_provider_aliascollapsing'ollama' → 'custom'.tests/test_bootstrap_discover_agent.py— PinnedPath.home()in_isolate_discover_agent_dirso PR fix(bootstrap): discover agent dir viahermesCLI shebang #1817's tests don't pick up the dev machine's real~/.hermes/hermes-agent. Test-only.Tests
node -c)Pre-release verification
custom_providers[].name == "ollama"+ non-loopback base_url combo (partial bug(config): resolve_model_provider() strips provider prefix on local model servers — LM Studio loads duplicate instance with default settings #1625 regression for narrow config)_cron_env_lockprocess-wide serialization on quota fetches across profilesMaintainer triage
maintainer-review. Targets same Bug: WebUI fails to resolve API key for named custom provider (Ollama) — generates unsettable env var name #1806 root as fix: route named custom provider model selections #1818 but at runtime layer with 96 LOC of branchy logic and zero tests; complementary in principle but needs tests + dedup with fix: route named custom provider model selections #1818's helpers post-merge before mergeable. Posted structured comment with three actionable asks.Closes #1792, #1795, #1796, #1800, #1806, #1807, #1694.