mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-31 19:16:29 +00:00
Bug fixes: - hermes-agent.nix: fold makeWrapper line continuations into the optionalStrings. When rev == null (dirty trees), the empty expansion left a dangling backslash that ended the command early and ran `--suffix PYTHONPATH ...` as its own shell command (exit 127). Clean trees passed CI; dirty trees with extraPythonPackages failed. - nixosModules.nix: delete duplicated extraPlugins assertions block. - nixosModules.nix: stop setting deprecated MESSAGING_CWD (which made the module trigger hermes' own startup deprecation warning); inject terminal.cwd into the generated config instead. cfg.settings wins via recursiveUpdate; container mode maps to the in-container path. Rebuild scope: - lib.nix: exclude flake.nix, flake.lock, root docs (AGENTS.md etc), and skills/ + optional-skills/ from pythonSrc — SKILL.md edits and flake tweaks no longer rebuild the Python venv. Skills ship solely via HERMES_BUNDLED_SKILLS / HERMES_OPTIONAL_SKILLS (same mechanism as Homebrew packaging). optional-mcps stays: pyproject lists its manifests as explicit data-files. - hermes-agent.nix: symlink skills/plugins/locales/web_dist/ui-tui into $out instead of cp -r — the wrapper drv is near-instant when only the venv changed. checks.nix uses find -L through symlinks and gains optional-skills assertions. Dev/release venv split: - python.nix: venvName param; hermes-agent.nix builds hermesDevVenv ([all] + [dev]: pytest, ruff, ty, debugpy) alongside the release venv. The devShell hook exports HERMES_PYTHON pointing at the dev venv only (and now always, not just on stamp hits), so nix develop never pulls the release venv. Local uv fallback installs [all,dev]. - run_tests.sh: fall back to $HERMES_PYTHON when no local venv exists. Cleanliness: - callHermesArgs.nix: shared callPackage args imported + spread by packages.nix and overlays.nix (one place to add flake inputs). - lib.nix: drop dead npmDepsSrc export; gate set -x behind DEBUG=1 in update-npm-lockfile / fix-lockfiles; comment why fix-lockfiles deliberately omits -e. - hermes-agent.nix: filter __pycache__ from bundled skills. Verified: nix flake check exit 0 (all 16 checks); built .#default, .#tui, .#web; devshell closure contains only hermes-agent-dev-env; run_tests.sh works via HERMES_PYTHON with no local venv.
85 lines
3.7 KiB
Bash
Executable file
85 lines
3.7 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# Canonical test runner for hermes-agent. Run this instead of calling
|
|
# `pytest` directly to guarantee your local run matches CI behavior.
|
|
#
|
|
# What this script enforces:
|
|
# * Per-file isolation via scripts/run_tests_parallel.py — each test
|
|
# file runs in its own freshly-spawned `python -m pytest <file>`
|
|
# subprocess. No xdist, no shared workers, no module-level leakage
|
|
# between files.
|
|
# * TZ=UTC, LANG=C.UTF-8, PYTHONHASHSEED=0 (deterministic)
|
|
# * Env vars blanked (conftest.py also does this, but this
|
|
# is belt-and-suspenders for anyone running pytest outside our
|
|
# conftest path — e.g. on a single file)
|
|
# * Proper venv activation (probes .venv, venv, then ~/.hermes/...)
|
|
#
|
|
# Usage:
|
|
# scripts/run_tests.sh # full suite
|
|
# scripts/run_tests.sh -j 4 # cap parallelism
|
|
# scripts/run_tests.sh tests/agent/ # discover only here
|
|
# scripts/run_tests.sh tests/agent/ tests/acp/ # multiple roots
|
|
# scripts/run_tests.sh tests/foo.py # single file
|
|
# scripts/run_tests.sh tests/foo.py -- --tb=long # path + pytest args
|
|
# scripts/run_tests.sh -- -v --tb=long # pytest args only
|
|
#
|
|
# Everything after a literal '--' is passed through to each per-file
|
|
# pytest invocation. Positional path arguments before '--' override
|
|
# the default discovery root (tests/).
|
|
|
|
set -euo pipefail
|
|
|
|
# ── Locate repo root ────────────────────────────────────────────────────────
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
REPO_ROOT="$(cd "$SCRIPT_DIR/.." && pwd)"
|
|
|
|
# ── Locate python ───────────────────────────────────────────────────────────
|
|
# Probe local venvs first; fall back to the Nix devShell's dev venv
|
|
# (HERMES_PYTHON points at hermes-agent-dev-env, which ships [dev]
|
|
# extras: pytest, pytest-asyncio, pytest-timeout, ruff, ty).
|
|
VENV=""
|
|
for candidate in "$REPO_ROOT/.venv" "$REPO_ROOT/venv" "$HOME/.hermes/hermes-agent/venv"; do
|
|
if [ -f "$candidate/bin/activate" ]; then
|
|
VENV="$candidate"
|
|
break
|
|
fi
|
|
done
|
|
|
|
if [ -n "$VENV" ]; then
|
|
PYTHON="$VENV/bin/python"
|
|
elif [ -n "${HERMES_PYTHON:-}" ] && [ -x "$HERMES_PYTHON" ]; then
|
|
PYTHON="$HERMES_PYTHON"
|
|
echo "▶ no local venv — using Nix dev venv via HERMES_PYTHON: $PYTHON"
|
|
else
|
|
echo "error: no virtualenv found in $REPO_ROOT/.venv or $REPO_ROOT/venv," >&2
|
|
echo " and HERMES_PYTHON is not set (enter the Nix devShell or create a venv)" >&2
|
|
exit 1
|
|
fi
|
|
|
|
|
|
# ── Live-gateway plugin (computed before we drop env) ───────────────────────
|
|
EXTRA_PYTHONPATH=""
|
|
EXTRA_PYTEST_PLUGINS=""
|
|
if [ -f "$HOME/.hermes/pytest_live_guard.py" ]; then
|
|
EXTRA_PYTHONPATH="$HOME/.hermes"
|
|
EXTRA_PYTEST_PLUGINS="pytest_live_guard"
|
|
fi
|
|
|
|
|
|
# ── Run in hermetic env ──────────────────────────────────────────────────────
|
|
# env -i: start with empty environment, opt-in only what we need.
|
|
# No credential var can leak — you'd have to explicitly add it here.
|
|
echo "▶ running per-file parallel test suite via run_tests_parallel.py"
|
|
echo " (TZ=UTC LANG=C.UTF-8 PYTHONHASHSEED=0; clean env)"
|
|
|
|
cd "$REPO_ROOT"
|
|
|
|
exec env -i \
|
|
PATH="$PATH" \
|
|
HOME="$HOME" \
|
|
TZ=UTC \
|
|
LANG=C.UTF-8 \
|
|
LC_ALL=C.UTF-8 \
|
|
PYTHONHASHSEED=0 \
|
|
${EXTRA_PYTHONPATH:+PYTHONPATH="$EXTRA_PYTHONPATH"} \
|
|
${EXTRA_PYTEST_PLUGINS:+PYTEST_PLUGINS="$EXTRA_PYTEST_PLUGINS"} \
|
|
"$PYTHON" "$SCRIPT_DIR/run_tests_parallel.py" "$@"
|