Commit Graph
719 Commits
Author SHA1 Message Date
Michael Lam a48e47dd1c feat: separate CLI sessions in sidebar 2026-05-18 17:29:51 -07:00
nesquena-hermes 4a49226439 Stamp CHANGELOG for v0.51.91 (Release BO / stage-384 / 5-PR full sweep batch) 2026-05-18 22:45:57 +00:00
nesquena-hermes 4f90fc5339 Stage 384: PR #2544 2026-05-18 22:44:02 +00:00
nesquena-hermes 589e0bf490 Stage 384: PR #2556
# Conflicts:
#	CHANGELOG.md
2026-05-18 22:44:02 +00:00
nesquena-hermes 91099051c6 Stage 384: PR #2505
# Conflicts:
#	CHANGELOG.md
2026-05-18 22:44:02 +00:00
nesquena-hermes 2675b6266d Stage 384: PR #2520
# Conflicts:
#	CHANGELOG.md
2026-05-18 22:44:02 +00:00
Michael Lam 6917b9a0e7 fix: sanitize custom provider env hints 2026-05-18 15:18:20 -07:00
Ruslan 6d8e5031fc Merge branch 'master' into fix/archive-extract-respects-attachment-dir 2026-05-18 23:01:23 +03:00
r.kulbaev 2fe0ece991 fix(upload): scope archive extraction to per-session attachment dir
handle_upload_extract() used Path(s.workspace) as the extraction root,
bypassing HERMES_WEBUI_ATTACHMENT_DIR entirely. Route through
_session_attachment_dir(session_id) so archives land alongside
single-file uploads and session cleanup covers them.

Add tests and CHANGELOG entry.

Ref #2247
2026-05-18 21:22:02 +03:00
Michael Lam e94827f460 fix: stop replaying reasoning-only history 2026-05-18 10:50:42 -07:00
Michael Lam b23fb6ccaa feat(runtime): route goal through adapter seam 2026-05-18 10:30:26 -07:00
Hermes Agent 42b97d15f6 fix: clear fallback streaming warnings 2026-05-18 12:21:59 -05:00
nesquena-hermes 26718cdfc7 Stamp CHANGELOG for v0.51.90 (Release BN / stage-383 / 10-PR full sweep batch) 2026-05-18 16:46:53 +00:00
nesquena-hermes 63d75df818 Stage 383: PR #2530
# Conflicts:
#	CHANGELOG.md
2026-05-18 16:44:36 +00:00
nesquena-hermes d161e9a074 Stage 383: PR #2528
# Conflicts:
#	CHANGELOG.md
2026-05-18 16:44:36 +00:00
nesquena-hermes 69b2289671 Stage 383: PR #2512
# Conflicts:
#	CHANGELOG.md
2026-05-18 16:44:36 +00:00
nesquena-hermes c7badae039 Stage 383: PR #2515
# Conflicts:
#	CHANGELOG.md
2026-05-18 16:44:35 +00:00
nesquena-hermes 75f6d2a03c Stage 383: PR #2522
# Conflicts:
#	CHANGELOG.md
2026-05-18 16:44:35 +00:00
nesquena-hermes 3bf2b10a68 Stage 383: PR #2509
# Conflicts:
#	CHANGELOG.md
2026-05-18 16:44:35 +00:00
nesquena-hermes cd7ee68e02 Stage 383: PR #2511
# Conflicts:
#	CHANGELOG.md
2026-05-18 16:44:35 +00:00
Frank Song 0cd62ab474 fix: keep kanban drag drop from opening detail 2026-05-18 22:13:04 +08:00
Michael Lam b76d698a79 fix: guard new conversation cold-start clicks 2026-05-18 06:48:05 -07:00
Michael Lam f3f9f3ed40 fix: allow keyless named custom endpoints 2026-05-18 04:27:31 -07:00
Michael Lam 037652308d fix: load remote models for named custom providers 2026-05-18 01:08:09 -07:00
Frank Song 9d6eb5f0df Fix board selector label overlap 2026-05-18 16:02:56 +08:00
Michael Lam 9f1ff51950 docs(runtime): tighten queue goal gate 2026-05-17 23:17:46 -07:00
Dennis Soong 516d2a588c fix: show auto-compression elapsed time 2026-05-18 13:08:38 +08:00
Frank Song 46029e0b1c docs: align uiux demo theme controls 2026-05-18 12:50:25 +08:00
Michael Lam 2a3c4abc60 docs(runtime): define queue goal control gate 2026-05-17 21:06:13 -07:00
nesquena-hermes 04e08391c4 Stamp CHANGELOG for v0.51.89 (Release BM / stage-382 / 6-PR full sweep batch) 2026-05-18 03:56:54 +00:00
nesquena-hermes 715017924c Stage 382: PR #2503 2026-05-18 03:45:42 +00:00
nesquena-hermes cec1e87d04 Stage 382: PR #2500 (with whitespace polish on panels.js + ARCHITECTURE.md) 2026-05-18 03:45:02 +00:00
nesquena-hermes 42c677b223 Stage 382: PR #2496 2026-05-18 03:43:59 +00:00
nesquena-hermes ea1261d03b Stage 382: PR #2501 2026-05-18 03:43:26 +00:00
nesquena-hermes f731f1fa43 Stage 382: PR #2499 2026-05-18 03:43:01 +00:00
nesquena-hermes e919da8705 Stamp CHANGELOG for v0.51.88 (Release BL / stage-381 / 3-PR security + UX + lineage batch) 2026-05-18 01:44:41 +00:00
nesquena-hermes a27f8c8c24 Merge pull request #2487 from Michaelyklam/docs/issue-1925-approval-clarify-gate
docs(runtime): define approval clarify control gate
2026-05-17 18:22:59 -07:00
nesquena-hermes 944c634f97 Stamp CHANGELOG for v0.51.87 (Release BK / stage-380, also restore v0.51.86 block clobbered during rebase) 2026-05-18 01:18:53 +00:00
nesquena-hermes 669e815a73 Stage 380: PR #2482
# Conflicts:
#	CHANGELOG.md
#	docker_init.bash
2026-05-18 01:16:19 +00:00
nesquena-hermes c1671d1e5e Stage 380: PR #2490
# Conflicts:
#	CHANGELOG.md
2026-05-18 01:14:28 +00:00
Michaelyklam d9e6dcf3ef docs(runtime): define approval clarify control gate 2026-05-18 01:06:26 +00:00
Frank Song 144aac28b9 docs: note Android AVF ARM64 field report (refs #2364)
Add a narrow README note for the community ARM64 Android AVF field
report: Hermes Agent + WebUI running inside a Debian 12 VM on a
mid-range Android phone with cloud-hosted inference.

The note frames the report as a compatibility signal rather than an
official support baseline or provider/model benchmark, and records
practical mobile caveats around first-install compile time, Android
tab reloads, and battery optimization.

Refs #2364
Closes nesquena/hermes-webui#2483

Co-authored-by: Frank Song <franksong2702@gmail.com>
2026-05-18 00:51:41 +00:00
nesquena-hermes 70f371c8b9 fix(docker): stage agent source to writable build dir before pip install
The Docker smoke gate added in this same PR caught a real production
regression on its very first CI run. v0.51.84 (PR #2470) mounted
hermes-agent-src read-only on the WebUI side and widened the chown
prune to keep the read-only walk happy, but missed that the WebUI's
startup also runs:

    uv pip install "$_agent_src[all]"

against the same now-read-only mount. setuptools' egg_info step writes
hermes_agent.egg-info/ inside the source tree even under PEP 517 build
isolation (this is by design -- PEP 517 isolates the BUILD environment,
not the source tree's metadata directory). On a :ro mount this returns
EROFS, the install fails, error_exit fires, and every multi-container
deploy dies at startup. The smoke gate flagged it on both the
two-container and three-container variants.

The fix
-------
Stage the agent source into a writable build dir under /tmp BEFORE
invoking pip install, then point pip at the staged copy.

  _stage_src="/tmp/hermes-agent-build"
  rm -rf "$_stage_src" && mkdir -p "$_stage_src"
  rsync -a --exclude='*.egg-info' --exclude='build' --exclude='dist' \
        --exclude='__pycache__' --exclude='.git' \
        "$_agent_src"/ "$_stage_src"/
  uv pip install "$_stage_src[all]" ...
  rm -rf "$_stage_src"

The exclusion list matters: when setuptools sees a pre-baked *.egg-info,
build, or dist directory, it takes a timestamp-update code path that
also reads/writes inside that directory -- which itself fails on a :ro
source. Excluding them keeps the build on the fresh-build path
unconditionally.

rsync is in the production image (Dockerfile line 41-44). For users
running custom WebUI images without rsync, the script falls back to
cp -a + post-copy rm -rf of the same artifacts.

Tests
-----
Two new source-level invariants in tests/test_docker_docs_and_readonly.py:

  test_docker_init_stages_agent_source_for_writable_install
    -- asserts _stage_src=... is declared
    -- asserts every `uv pip install ...[all]` line uses _stage_src,
       NOT raw $_agent_src

  test_docker_init_excludes_egg_info_during_staging
    -- asserts the staging path excludes *.egg-info (rsync exclude
       form or cp-fallback's explicit rm -rf both pass)

These would have caught the v0.51.84 regression at the source level
(once written; they're new). The Docker runtime smoke gate is the
durable defence for the broader class of :ro x init-script
interactions, since source-level invariants only catch what they're
written to catch.

Verification
------------
- pytest tests/test_docker_docs_and_readonly.py: 11 passed (9 existing
  + 2 new)
- pytest tests/ -q --timeout=60: 5891 passed, 6 skipped (was 5889;
  delta is exactly the 2 new tests)
- bash -n docker_init.bash: clean

Once this lands, the Docker smoke gate's two/three-container variants
should go green, completing the self-validating loop.
2026-05-18 00:21:31 +00:00
nesquena-hermes 5b6f69c884 ci(docker): runtime smoke gate for Docker init logic
Closes the source-only-test gap that let v0.51.84's :ro-mount x chown -h
{} + startup regression reach review with 5800+ green pytests. Adds a
new GitHub Actions workflow .github/workflows/docker-smoke.yml that
actually runs 'docker compose up' against each compose variant.

Triggers
--------
Path-filtered on pull_request + push to master:
  Dockerfile, docker_init.bash, docker-compose*.yml, .dockerignore,
  .env.docker.example, .github/workflows/docker-smoke.yml itself.
Also workflow_dispatch for manual runs.

Jobs
----
1. compose-config -- preflight that 'docker compose config' parses each
   of the three compose files. Cheap, fast, catches schema/interpolation
   drift in parallel before any container starts.

2. smoke (matrix: single / two-container / three-container) -- for each
   variant:
   a. Reap any leftover hermes-smoke-* containers/volumes/networks from
      prior runs (defence-in-depth on self-hosted runners; hosted runners
      are fresh).
   b. docker build -t ghcr.io/nesquena/hermes-webui:latest .
      Critical: the multi-container compose files reference the GHCR
      image. Without this retag, multi-container smoke would test the
      previously-released image, NOT the PR's docker_init.bash / Dockerfile
      changes. With the retag, Compose's default pull_policy=missing keeps
      the local build in place and the PR is genuinely exercised.
   c. mktemp -d for ephemeral HERMES_HOME + HERMES_WORKSPACE so the
      runner's host filesystem is never touched.
   d. docker compose up -d --wait --wait-timeout 120 (Dockerfile carries a
      HEALTHCHECK so --wait blocks on 'healthy', not just 'running').
   e. curl /health probe with a 30-attempt x 2s poll loop as headroom for
      the multi-container variants' Python dep install phase.
   f. grep startup logs for known-bad signatures:
        EROFS | Read-only file system | Traceback | PermissionError |
        error_exit | groupmod: cannot | usermod: cannot |
        Failed to set (UID|GID|owner|permissions|ownership)
      These are the exact patterns that would have flagged #2470 in real
      time. Failed-to-set is anchored to specific objects to avoid false
      positives on benign locale/library bootstrap warnings.
   g. trap on EXIT: docker compose down -v --remove-orphans + rm -rf the
      ephemeral host paths, regardless of how the job exited.

Safety
------
- permissions: contents: read only -- no GITHUB_TOKEN write scope.
- Fork PRs run with no secrets (standard pull_request, not
  pull_request_target).
- No host bind mounts; no ~/.hermes exposure; no network egress beyond
  what compose itself needs to pull the agent image.
- timeout-minutes: 15 on the smoke job as a hard ceiling against a
  hung docker build.
- Per-run COMPOSE_PROJECT name (hermes-smoke-VARIANT-RUNID-ATTEMPT)
  so concurrent runs or reruns can't clobber each other.

Out of scope for v1 (per design review)
---------------------------------------
- HERMES_WEBUI_SMOKE_TEST env flag in docker_init.bash -- production-code
  footgun that would let any leaked env var silently exit before
  serving traffic.
- --user 60000:60000 -- incompatible with the image's root-init phase
  and would skip the very chown branch we are guarding against.
- Local-runnable scripts/docker-smoke-test.sh -- defer until CI gating
  ships and we see what contributors actually trip over.
- Hadolint / yamllint -- separate lint workflow, follow-up PR.
- Podman runtime smoke -- defer until a podman-specific bug ships.

Pre-merge verification
----------------------
- actionlint: clean
- YAML parse: clean (3 triggers, 2 jobs, 3-variant matrix)
- bash -n on all 6 run-blocks: clean
- pytest tests/ -q --timeout=60: 5889 passed, 6 skipped (no test impact;
  workflow-only change)
- Opus design review on the brief (REVISE -> minimum scope adopted)
- Opus implementation review on this workflow (APPROVE)
2026-05-18 00:09:41 +00:00
nesquena-hermes 9543addd3d Stage 379 fix: remove stray CHANGELOG entry mis-attributing #2461 to v0.51.83 (Opus catch) 2026-05-17 23:41:15 +00:00
nesquena-hermes 0dc527517c Stamp CHANGELOG for v0.51.86 (Release BJ / stage-379 / 4-PR review-bypass batch) 2026-05-17 23:36:11 +00:00
nesquena-hermes 50d4f4cfb9 Stage 379: PR #2480
# Conflicts:
#	CHANGELOG.md
2026-05-17 23:35:19 +00:00
nesquena-hermes 6f9cead15e Stage 379: PR #2479 2026-05-17 23:35:18 +00:00
nesquena-hermes 935d9e6402 Stage 379: PR #2461
# Conflicts:
#	CHANGELOG.md
2026-05-17 23:35:18 +00:00
Michael Lam 310d69bed8 docs: inventory agent source boundary 2026-05-17 16:11:29 -07:00