Commit graph

19484 commits

Author SHA1 Message Date
Jeeves Assistant
080bb83746 test(homeassistant): prevent unit tests from calling live instances
Two tests made real HTTP calls to homeassistant.local:8123 — on a LAN
with an actual Home Assistant instance they could turn on real lights,
and otherwise burned ~10s in network timeouts. Replace with AsyncMock at
_async_call_service and assert the exact production call signature
(domain, service, entity_id, data). 35 pass in ~0.2s.

Salvaged from PR #72634 by @jeeves-assistant.

Co-authored-by: Jeeves Assistant <jeevesassistant00@gmail.com>
2026-07-29 21:30:53 -07:00
Tony (eazye19)
9e9c220608 chore(tests): drop accidental temp guard probe file
tests/test_zz_guard_probe_tmp.py was a throwaway verification probe that
was swept into the PR #43299 salvage commit by mistake (and one of its
shell=True cases fails by design of the probe). The durable regression
coverage lives in tests/test_live_system_guard.py.
2026-07-29 21:30:53 -07:00
sunwz1115
230a2c273e test: harden yolo and kanban signal tests on macOS
Autouse fixture also resets approval_module._YOLO_MODE_FROZEN so a
HERMES_YOLO_MODE=1 host env can't poison every case (the one
startup-frozen test still patches it back explicitly). Adds the darwin
'ps -o stat=' zombie branch to _is_alive_like_dispatcher, mirroring
production hermes_cli/kanban_db.py — a no-op on Linux.

Salvaged from PR #34069 by @sunwz1115.

Co-authored-by: sunwz1115 <192549904+sunwz1115@users.noreply.github.com>
2026-07-29 21:30:53 -07:00
SmokeDev
3e7a11ca2e fix(test-runner): native Windows venv probe + glyph-safe stdio
Two Windows fixes for the canonical test runner, salvaged from #66496:

- scripts/run_tests.sh: probe the native Windows venv layout
  (Scripts/activate → Scripts/python.exe) alongside bin/activate,
  adapted to main's pytest-import-guarded loop with SKIPPED_VENVS
  reporting. Without it a python -m venv / uv venv on Git Bash/MSYS is
  never found and the runner refuses to start.
- scripts/run_tests_parallel.py: _make_stdio_glyph_safe() reconfigures
  stdout/stderr to UTF-8 (errors=replace fallback) so the ✓/✗ progress
  glyphs cannot crash a cp1252 console when the runner is invoked
  directly (run_tests.sh's PYTHONUTF8=1 only covers the wrapped path).
  No-op on UTF-8 stdio. Ships 3 OS-independent cp1252 tests plus
  encoding=utf-8 in the runner-subprocess assertions.

Dropped from the original PR: the USERPROFILE/HOMEDRIVE/HOMEPATH/
SYSTEMROOT env-forwarding hunk — main's WIN_ENV loop already forwards
a superset (#67385/#70813).
2026-07-29 21:30:53 -07:00
Jeff Watts
0860b9804f test(tui_gateway): pin goal-command config home against collection-time _hermes_home freeze
Sibling files (test_billing_rpc etc.) import tui_gateway.server at
collection time, freezing module-level _hermes_home = get_hermes_home()
(server.py:54) to the developer's real home before conftest isolation
runs. _load_cfg() then reads the REAL ~/.hermes/config.yaml — e.g. a
local MoA preset — instead of what _write_moa_config wrote.

The server fixture now monkeypatches _hermes_home to the isolated
HERMES_HOME and resets the mtime-keyed cfg cache (_cfg_cache/_cfg_mtime/
_cfg_path); monkeypatch restores originals on teardown.

Complementary to the #57066 autouse teardown, which only restores the
cfg cache to its pre-test value and never re-points _hermes_home.

Combined tests/tui_gateway + tests/test_tui_gateway_server.py:
792 passed.

Salvaged from PR #63981 by @lEWFkRAD.
2026-07-29 21:30:53 -07:00
Tony (eazye19)
7216ca19a6 fix(tests): live-system guard treats only argv[0] as the executable
Argv-list commands now scan only argv[0] against _PROCESS_KILLERS, ending
false positives like ['cat', '.../skill'] ('skill' is a real util-linux
binary name). Wrapper executables (sh/bash/env/nohup/timeout/sudo/xargs/…)
keep full-token scanning so ['bash', '-c', 'pkill …'] and
['env', …, 'pkill', …] stay blocked; string commands are unchanged.
Adds tests/test_live_system_guard.py pinning both directions.

Salvaged from PR #43299 by @eazye19.

Co-authored-by: Tony (eazye19) <support@captureclient.net>
2026-07-29 21:30:53 -07:00
Christopher-Schulze
00cd9b2b3a test(fal): pin fal_common behavioral contracts
Contract tests for tools/fal_common.py: queue-URL normalization
(trailing slash / whitespace / empty-raises), _extract_http_status
response-vs-exc precedence and non-int rejection, the
_ManagedFalSyncClient RuntimeError guards against fal_client private
API drift, and submit()'s queue-URL + POST/json/timeout wiring.

Trimmed on landing: test_non_string_coerced_to_string (pins an
implementation accident, not a contract) per the coverage-padding
policy in AGENTS.md.

Salvaged from #52166.
2026-07-29 21:30:53 -07:00
BlutAgent
b631f80b7a fix(tests): register no_isolate and ssh pytest markers
Registers the two genuinely-unregistered markers (no_isolate, ssh) in
pyproject.toml, silencing PytestUnknownMarkWarning for tests/tools/test_mcp_*
and tests/tools/test_file_sync_perf.py.

Dropped hunk: the live_system_guard_bypass line from the original PR — that
marker is already registered dynamically via pytest_configure/addinivalue_line
in tests/conftest.py, so the ini entry would be a duplicate.

Salvaged from #71403.
2026-07-29 21:30:53 -07:00
Jeff Watts
f708a85d2e test(tui_gateway): make the tui gateway suite order-independent
Cross-file leaks made tests/tui_gateway + tests/test_tui_gateway_server.py
fail when run in one process (issue #57068):

- conftest: _hermetic_environment now re-pins hermes_state.DEFAULT_DB_PATH
  to the fake home so no test ever touches the developer's real state.db
- conftest: new autouse _reset_tui_gateway_server_state snapshots/restores
  _methods, cfg cache, db handle and _real_stdout, and tears down leftover
  sessions via the production _close_session_by_id(..., end_reason=
  "test_cleanup") boundary
- per-file fixtures scope patch.dict(sys.modules) to the import only
- drop reload()-based teardowns that duplicated atexit hooks

Conflict resolution vs main: kept main's mod._live_transports.clear() in
the test_protocol.py server fixture alongside the snapshot/restore logic.

Combined run now 792 passed / 0 failed.

Salvaged from PR #57066 by @lEWFkRAD. Fixes #57068.
2026-07-29 21:30:53 -07:00
Kyzcreig
9c28600e77 test: prove concurrency with barriers/witnesses instead of wall-clock bounds
Replace OS-scheduler-dependent elapsed-time ceilings with deterministic
concurrency proofs in three tests:

- test_context_refs_concurrent: asyncio.Barrier rendezvous — all 3 URL
  fetches must be in flight simultaneously before any returns.
- test_memory_boundary_commit: positive non-blocking witness — the
  provider call list must still be empty when the async commit returns.
- test_mem0_v3 slow-prefetch: threading.Event park/release — prefetch
  must return while the backend search is still parked.

The tests/tools/test_mcp_tool.py hunk from the original PR is dropped:
main no longer carries the 'elapsed < 2.5' assertion it targeted
(superseded by a delay-relative bound).

Salvaged from #71913.
2026-07-29 21:30:53 -07:00
fcavalcantirj
f04fd1e7ad fix(update): test runs never mutate the live checkout — pytest-guard the marker and repair paths
Guard the .lazy-refresh-incomplete marker writer (update_cmd), launch-time
recovery (main.py), and _early_recovery repair paths behind a two-condition
check: running under pytest AND the target is this live checkout. Sandboxed
tmp_path tests still exercise the real code paths.

Salvaged from PR #72002 by @fcavalcantirj. Fixes #72000.

Co-authored-by: fcavalcantirj <felipe.cavalcanti.rj@gmail.com>
2026-07-29 21:30:53 -07:00
Jakub Wolniewicz
3233de9a21 fix(tests): preserve config module identity in backup tests
(cherry picked from commit 1ac105ea50)
2026-07-29 21:30:53 -07:00
brooklyn!
788126e5ab
Merge pull request #74545 from NousResearch/bb/model-picker-hotkey
2-keypress model switching: ⌘⇧M, honest search commit, match highlighting
2026-07-29 23:27:03 -05:00
Brooklyn Nicholson
b614521fa7 feat(desktop): full cmdk-style keyboard selection in the model dropdown
Enter-commits-first was still filter-only past the first row: arrows
handed focus to Radix's own item focus, hover fought the keyboard for
which row Enter meant, and unfiltered MoA presets sat below zero model
matches as phantom commits.

The search input now owns the whole keyboard interaction over one flat
row list that mirrors exactly what's rendered (collapse, filter,
presets included — presets filter by query now too):

- no query → selection sits on the current model, Enter just closes
- typing → first match auto-selected, ↑/↓ step with wraparound (reset
  on every keystroke), Enter commits the highlighted row
- selection scrolls into view; the highlight yields while the pointer
  is in the list so hover and keyboard never disagree about Enter
2026-07-29 23:19:39 -05:00
Teknium
2d40494247 fix(tests): tolerate mid-import kanban_db in the write-guard sys.modules probe
The guard's sys.modules.get() can observe hermes_cli.kanban_db while a
lazy import is still executing on a fixture boundary — the partially
initialized module has no .connect yet (AttributeError flake in the
full-suite verification run, 1/2460 files). A half-imported module has
no callers to guard; skip this round and let the next fixture patch the
completed module.
2026-07-29 19:53:17 -07:00
joelbrilliant
ef1b06d853 fix(tests): stop the suite writing into the operator's real Hermes logs
hermes_cli/main.py calls setup_logging() at module scope. That resolves
get_hermes_home() and attaches rotating file handlers to the ROOT logger via
a QueueHandler. So merely importing it - which many test modules do, directly
or transitively - points the whole pytest session's logging at
<HERMES_HOME>/logs/agent.log and errors.log.

The _isolate_env fixture already sandboxes HERMES_HOME, but fixtures run
after collection has imported the test modules, and by then the handler holds
an absolute path to the real file. Verified by importing hermes_cli.main in a
clean interpreter and walking the queue listener: both handlers pointed at the
developer's own ~/.hermes/logs/.

Measured on a live install: 126 warnings in a personal agent.log came from
test runs rather than the running gateway - phantom 'FakeTree' Discord
registration failures and 'rejected invalid API key' entries whose paths only
exist in tests/gateway/test_api_server_runs.py. That noise makes genuine
warnings hard to find exactly when someone is debugging.

conftest is imported before any test module, so sandboxing HERMES_HOME there
closes the window. The per-test fixture still applies afterwards.

Also fixes 4 pre-existing failures: tests/gateway/test_channel_directory.py
TestBuildFromSessions was reading the operator's real sessions data for the
same reason.

Full gateway+tools suites: 66 failures on clean origin/main, 62 with this
change, 0 new. The regression guard asserts the value captured AT conftest
import - reading os.environ inside a test passes even with the fix removed,
because the per-test fixture has sandboxed it by then.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-07-29 19:53:17 -07:00
mehmetkr-31
dda289933d test(cli): fix order-dependent test_resume_quiet_stderr flake at the source
test_session_not_found_goes_to_stdout_in_full_mode passes in isolation but
fails in a full tests/cli run. Two independent leaks from the same neighbor
test conspire:

1. test_cli_init.py's _make_cli() reloads cli.py while prompt_toolkit is
   stubbed with MagicMocks and never reloads it back, so sys.modules['cli']
   is left with a mock _pt_print/_PT_ANSI and cli._cprint silently no-ops
   for every later test. Fixed by reloading cli once more with the real
   modules visible (try/finally).

2. prompt_toolkit's print_formatted_text caches its Output on the
   process-global default AppSession the first time it renders without an
   explicit output=. Under capsys (which swaps sys.stdout per test), the
   first CLI test to emit through _cprint locks that cache onto its own
   captured stdout, so later capsys tests read an empty buffer. Fixed with
   an autouse fixture in a new tests/cli/conftest.py that resets the cached
   output around each test.

Neither change touches production code or the flaky test's own assertion.

Related to #59358 (which addresses the same flaky test by mocking _cprint in
the assertion instead; this fixes the two underlying leaks at the source and
does not modify test_resume_quiet_stderr.py).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 19:53:17 -07:00
Teknium
7ac63975f7 test: fix restored-test regressions vs current main
- test_terminal_requirements.py: restore missing 'import pytest' (revert
  resurrected a parametrized test into a file whose pytest import was
  pruned on main)
- test_container_cwd_sanitize.py: _CONTAINER_BACKENDS pin now includes
  vercel_sandbox
2026-07-29 19:48:37 -07:00
Teknium
c770515e2b modernize re-added Vercel integrations: SDK 0.7.2, telemetry off, sibling-site wiring
- Bump vercel SDK pin 0.5.7 -> 0.7.2 (pyproject, lazy_deps) and regenerate uv.lock
- Disable the SDK's new default-on telemetry (VERCEL_TELEMETRY_DISABLED=1
  set before import, user-overridable) per the no-opt-out-telemetry policy
- Move _model_flow_ai_gateway into hermes_cli/model_setup_flows.py (god-file
  decomposition landed after the removal)
- Widen post-removal backend sets that vercel_sandbox missed: terminal_tool
  container_backend + _CONTAINER_BACKENDS, file_tools fallback set,
  env_probe._REMOTE_BACKENDS, approval._should_skip_container_guards,
  prompt_builder probe container_config
- Add terminal.vercel_runtime to config_defaults + TERMINAL_CONFIG_ENV_MAP
- Re-add vercel dependency group to nix #full variant (reverts #33773 workaround)
- Update restored tests to current contracts: upload-only credential sync-back
  (bcfc7458fa), registry-derived provider env list, parametrized backend fixture,
  drop tests superseded on main (slack wizard move #41112, nous status format)
2026-07-29 19:48:37 -07:00
Teknium
ad12df6ba4 Revert "remove Vercel AI Gateway and Vercel Sandbox (#33067)"
This reverts commit febc4cfec0.
2026-07-29 19:48:37 -07:00
Teknium
0524eccdd8 chore: contributor mapping for mattmiller@comfy.org (@mattmillerai) 2026-07-29 19:48:30 -07:00
Teknium
d9101bef0a fix(mcp): curate comfy-cloud default tool set + drop legacy packaging line
- tools.default_enabled: 20-tool curated subset (discovery, generation,
  job lifecycle, billing). The server exposes ~37 tools; all-enabled adds
  ~16-22k tokens of schema to every API call — larger than the entire
  Hermes core toolset (~12.7k). Curated default lands at ~9-12k. Batch,
  saved/shared workflow, and App Mode tools remain opt-in via
  'hermes mcp configure comfy-cloud'.
- report_session_summary excluded from defaults per telemetry policy
  (no outbound telemetry without explicit user opt-in).
- description trimmed to catalog guideline length.
- revert pyproject data-files line: the per-entry packaging enforcement
  was removed (no-pip policy); blender/unreal-engine entries have no
  data-files lines either.
2026-07-29 19:48:30 -07:00
Matt Miller
fee0eae6d8 feat(mcp): add Comfy Cloud to the MCP catalog (remote HTTP + native OAuth 2.1)
New catalog entry for Comfy Cloud's hosted remote MCP server at
https://cloud.comfy.org/mcp — Streamable HTTP with native MCP OAuth 2.1
(Dynamic Client Registration + PKCE), the same shape as the linear entry.
Nothing to install locally; Hermes's MCP client handles discovery and the
browser flow on first connect.

The server exposes ~30 tools for AI generation on Comfy Cloud: image /
video / audio / 3D via ComfyUI workflows (submit_workflow), curated
templates (run_template), and partner models like Flux, Kling, and Veo
(partner_generate), plus job lifecycle and discovery tools.
tools.default_enabled is left unset so the install-time checklist starts
all-on, mirroring the linear entry.

Also adds the per-entry data-files target in pyproject.toml per the
one-target-per-entry pattern documented there.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-29 19:48:30 -07:00
hermes-seaeye[bot]
5a23e3c522
fmt(js): npm run fix on merge (#74544)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-07-30 02:33:41 +00:00
Brooklyn Nicholson
789d69271a feat(desktop): ⌘⇧M opens the model menu on the pane under the pointer
composer.modelPicker shipped unbound and opened the full-screen picker
dialog. It now defaults to ⌘⇧M — the chord LibreChat, Open WebUI, and
Cherry Studio independently converged on — and toggles the composer
pill's live dropdown instead, search field ready: ⌘⇧M → 'gr' → Enter
switches model in two keypresses.

Routing follows the tab-verb convention (#74447): the request lands on
the chat surface in the hovered zone first, then the active composer,
skipping hidden keep-alive tabs. With no chat surface on screen
(settings, profiles) the keybind falls back to the full dialog; with
the gateway closed the pill opens the dialog like a click would.
2026-07-29 21:26:22 -05:00
Brooklyn Nicholson
33bbf24a62 fix(desktop): make the composer model dropdown's search commit honestly
Two fixes to the pill dropdown's filter, following the consensus across
VS Code, Zed, Open WebUI, and Cherry Studio:

- The pinned current model no longer rides along on a query it doesn't
  match. It sat above the real matches looking like the top result, so
  typing 'grok' and committing landed you back on the current model.
- Enter in the search field commits the first visible match (VS Code's
  'so Enter works without pressing DownArrow first'). Radix highlights
  nothing until an arrow key, so Enter used to dead-end; now
  open → type → Enter is the whole switch.

Matched letters also render through HighlightMatches like the other
searchable pickers.
2026-07-29 21:26:22 -05:00
Brooklyn Nicholson
611c6aab76 feat(desktop): highlight matched letters in searchable pickers
Typing in the model picker dialog, edit-models dialog, or command
palette now marks WHY each row matched: every occurrence of the query
(per-term for the palette's AND matcher) renders as an accent-colored
semantic <mark>. cmdk's scorer exposes no match ranges, so the shared
HighlightMatches primitive mirrors each surface's own filter semantics
instead: literal substring for the pickers, split-on-whitespace terms
with merged overlapping ranges for the palette.
2026-07-29 21:26:10 -05:00
brooklyn!
dd51931bfd
Merge pull request #74526 from NousResearch/bb/tab-restore-homing
fix(desktop): ⌘R lands on main — cold-start resume clobbers the persisted active tab
2026-07-29 21:25:03 -05:00
Teknium
f1120ada4d chore: contributor mappings for FraserHum + AlexxRussell (#72542/#73982 salvage) 2026-07-29 19:11:05 -07:00
Alexander Russell
cea4c3362d fix(gateway): collect quoted/spaced/home-relative MEDIA paths into the history dedup set
Salvaged from PR #73982 by Alexander Russell (@AlexxRussell) — the
collector half only. _collect_history_media_paths used only
_TOOL_MEDIA_RE, which misses quoted and spaced paths that the delivery
pipeline's extract_media grammar accepts; run text content through the
same extractor so the surviving dedup consumers (auto-append lane and
bare-path filter) see every path that could actually have been
delivered.

The PR's other halves (post-stream dedup snapshot plumbing, canonical
path comparison in _deliver_media_from_response, queued-followup
snapshot union) are moot after #74495 removed the post-stream history
filter entirely.
2026-07-29 19:11:05 -07:00
Fraser Humphries
8f4122efd2 test(gateway): cover current-turn TTS media dedup 2026-07-29 19:11:05 -07:00
Fraser Humphries
4dc9fb8008 fix(gateway): exclude current-turn media from dedup 2026-07-29 19:11:05 -07:00
Brooklyn Nicholson
4aa672b23e fix(desktop): stop cold-start resume homing focus to the workspace tab (⌘R tab persistence)
The layout tree persists the active tab, but every reload landed on main
anyway: boot's route resume sets $selectedStoredSessionId, and the
selection listener in store/session-states.ts treats every selection
change as a navigation — noteActiveTreeGroup(null) +
revealTreePane('workspace') — fronting the workspace tab over the
persisted active tile and then persisting that clobber.

A cold-start restore is a re-attachment, not a navigation, so
use-route-resume now arms a one-shot (markSelectionRestore) before
dispatching the window's FIRST resume; the selection listener consumes
it and skips homing exactly once. Every later resume — sidebar click,
route change, reconnect — homes as before, and starting on /new
consumes boot status too so a subsequent session open still homes.
2026-07-29 20:57:04 -05:00
Teknium
0bd82a8a84 chore: contributor mapping for eapwrk (honcho salvage, #67576) 2026-07-29 18:55:10 -07:00
Teknium
aae6e52005 test: opt install-ladder tests back into lazy installs under the hermetic gate
The HERMES_DISABLE_LAZY_INSTALLS=1 conftest gate (from #43782) correctly
blocks real mid-run pip installs suite-wide, but
TestInstallDependenciesRunner exercises the install ladder itself against
a fully mocked subprocess.run — it needs the gate open. Same
both-directions override pattern tests/tools/test_lazy_deps.py already
uses. Sibling sweep of all install_specs/_pip_install/ensurepip test
files: 274 tests green.
2026-07-29 18:55:10 -07:00
eapwrk
bd1a850fa2 fix(honcho): network-hermetic unit tests + lazy async writer start
Re-port of PR #67576:
- plugins/memory/honcho/session.py: start the async writer thread lazily on
  first enqueue via _ensure_async_writer (idempotent, lock-guarded) instead
  of eagerly in __init__; shutdown tolerates a never-started thread
- tests/honcho_plugin/conftest.py: package-wide socket guard so no honcho
  unit test can reach a live server
- tests/honcho_plugin/test_network_isolation.py: regression tests
- test_async_memory.py / test_oauth_flow.py: rebased hunks onto the pruned
  suite (pruned tests not resurrected)

Salvaged-from: #67576
Co-authored-by: eapwrk <eapwrk@gmail.com>
2026-07-29 18:55:10 -07:00
y0shualee
8d009e4f3e test: guard browser and Keychain side effects suite-wide (#35404)
Re-port of PR #35464 onto the rewritten hermetic conftest:
- autouse _neutralize_webbrowser fixture records open/open_new/open_new_tab
  and webbrowser.get() instead of launching a real browser
- autouse _neutralize_macos_keychain_creds defaults the Anthropic Keychain
  reader to None, with an opt-in allow_macos_keychain marker
- regression tests in tests/test_hermetic_side_effect_guards.py
- tests/agent/test_anthropic_keychain.py opts in via pytestmark

Salvaged-from: #35464
Co-authored-by: y0shualee <yuxiangl490@gmail.com>
2026-07-29 18:55:10 -07:00
Rod Boev
e461e86502 test(cli): remove importlib.reload seam from web_server session-token tests (#38034)
Extract _resolve_session_token() in hermes_cli/web_server.py so tests can
exercise token resolution directly instead of importlib.reload(ws), which
re-executed the whole module mid-suite (fresh FastAPI app + token) and
split module identity between test and app state.

Salvaged from PR #39038 by @rodboev (maintainer-endorsed direction);
rebased onto the rewritten test_web_server.py — dropped the PR's hunks for
test_falls_back_to_random_token's old body (test deleted in the prune,
re-added here in the PR's new form).

Co-authored-by: Rod Boev <rod.boev@gmail.com>
2026-07-29 18:55:10 -07:00
Jasmine Naderi
7ba456e98d fix(test): fail-closed kanban write guard prevents real HERMES_HOME pollution (#69283)
Autouse conftest fixture patches kanban_db.connect to refuse writes whose
resolved DB path lands under the REAL kanban root (captured at conftest
import time, before fixtures rewire the environment). Deny-list, not
allow-list, so hermetic tests moving HERMES_HOME to sibling tempdirs are
unaffected. Lazily attaches only when hermes_cli.kanban_db is already in
sys.modules.

Salvaged from PR #69385 by @smfworks; rebased by hand onto the pruned
conftest and adapted to guard on the resolved DB path (explicit db_path
or kanban_db_path()) rather than kanban_home() alone.

Co-authored-by: Jasmine Naderi <jasmine@smfworks.com>
2026-07-29 18:55:10 -07:00
AIalliAI
74d9110a7a test(tui): scope close_race orphan-cleanup assert to own session key
test_session_create_close_race_does_not_orphan_worker asserted the
process-global len(unregistered_keys) >= 1: a leaked _build thread from
another session.create test in the same shard can append a foreign key
and falsely satisfy the assert. Scope both the wait loop and the assert
to this test's own stored_session_id, matching the own-key scoping the
no-race companion test already uses for the same flake class.

Salvaged from PR #46189 by @AIalliAI (rebased onto the pruned suite).
2026-07-29 18:55:10 -07:00
Jorkey Liu
05afea65f4 fix(session): resolve default state DB path at call time
DEFAULT_DB_PATH in hermes_state.py is computed at import time, freezing
the developer's real ~/.hermes even when a test fixture (or runtime
profile switch) later redirects HERMES_HOME. Any default SessionDB() —
e.g. gateway SessionStore — then opened the real state.db.

Add _default_db_path(): resolves get_hermes_home() fresh at call time,
while a deliberately re-pointed DEFAULT_DB_PATH (the established
monkeypatch escape hatch) still wins via an import-time snapshot
comparison, preserving existing test behavior. SessionDB.__init__ and
session_search's requirement check now use the resolver; explicit
db_path arguments are untouched.

Reimplemented from PR #11875 by @JorkeyLiu (original diff predates the
hermes_state rewrite); regression test ported and modernized.
2026-07-29 18:55:10 -07:00
Jasmine Naderi
3e54a366e7 fix(test): patch _launch_configured_cwd in completion tests for hermeticity (#70041)
tui_gateway/server.py freezes _hermes_home at import time, so
_launch_configured_cwd() reads the developer's real config.yaml even
under the per-test HERMES_HOME redirect. Any absolute terminal.cwd in
the real config made _completion_cwd() ignore monkeypatch.chdir and
broke the completion tests on a pristine checkout.

Patch _launch_configured_cwd to None in the autouse _reset_fuzzy_cache
fixture and add a regression test pinning that _completion_cwd resolves
via os.getcwd() under tests.

Salvaged from PR #70148 by @smfworks (rebased onto the pruned suite).
2026-07-29 18:55:10 -07:00
webtecnica
66c4c9c0b1 fix(tests): forward Windows location vars through the hermetic runner; patch Path.home() in hindsight _clean_env
Combines the Windows-hermeticity cluster (#67512 by @webtecnica, earliest;
#71112 by @Sanjays2402; #67196 by @anatolijlaptev1991-ctrl) into one fix:

- scripts/run_tests.sh: env -i forwarded only HOME, but native Windows
  CPython resolves Path.home() from USERPROFILE (or HOMEDRIVE+HOMEPATH),
  stdlib paths from LOCALAPPDATA/APPDATA, ssl/sockets need SYSTEMROOT,
  tempfile needs TEMP/TMP — the strip broke collection tree-wide on
  native Windows (issues #67385, #70813). Location vars (never
  credentials) are now forwarded, each only when actually set, so
  POSIX runs are byte-for-byte unchanged (probe-verified both ways).
  PYTHONUTF8=1 added for legacy-codepage consoles printing the
  runner's glyphs.
- tests/plugins/memory/test_hindsight_provider.py: _clean_env patched
  HOME only; on Windows Path.home() ignores HOME. Now patches
  Path.home directly into tmp_path (from #67196).

Not ported: #71112's guard test — it regex-reads run_tests.sh source,
which the test policy bans (never read source code in tests).

Fixes #67385. Fixes #70813.
2026-07-29 18:55:10 -07:00
Omar Baradei
2472793b1d Refresh on upstream/main: resolve conflicts (no behavior change)
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-07-29 18:55:10 -07:00
Kyzcreig
bcec6c8d39 fix(test): hermetic env-detection tests — pin container/supervisor/HOME probes (#422)
The restart-routing, systemd-support, and subprocess-HOME tests asserted
branch behavior but left part of the real probe surface unmocked, so they
fail when the suite itself runs inside a container (self-hosted CI) or a
launchd-descended shell:

- /restart routing tests: the handler also consults the real /.dockerenv —
  extract the inline probe to gateway.restart.is_container_restart_context()
  (patchable seam, no behavior change) and pin it False; scrub ALL four
  supervisor env markers (ambient XPC_SERVICE_NAME on macOS flipped one).
- supports_systemd_services tests: pin shutil.which('systemctl') and
  is_container() so the test asserts the branch, not the host.
- copilot ACP real-HOME test: pin is_container() (auto mode prefers profile
  home in containers) and scrub ambient HERMES_REAL_HOME/TERMINAL_HOME_MODE.

97 tests green on macOS dev box AND inside a docker CI runner container.

Co-authored-by: Kyzcreig <9063726+Kyzcreig@users.noreply.github.com>
2026-07-29 18:55:10 -07:00
jethac
2c37b1af25 test(approval): event-based waits for blocking-approval E2E polls (PR #63522 port)
Manual port of @jethac's #63522 onto the pruned tree: 3 of the original
6 fixed-budget poll sites survive (3-concurrent-agents wait, session-A/B
routing wait, two-session queue wait). Replaced each 2.5-5s hard-ceiling
poll loop with the PR's _wait_until(predicate) helper — generous 30s
ceiling reached only on genuine failure, instant return on the green
path, assert with message instead of silent fall-through.

Dropped: the 3 hunks targeting pruned code, and the unrelated
scripts/release.py mailmap hunk (AUTHOR_MAP is frozen; contributor
mapping handled via contributors/emails/).
2026-07-29 18:55:10 -07:00
Teknium
67435c9a02 fix(tests): restore original module identities after vision-routing reloads (#61597)
_fresh_modules() in test_vision_routing_31179.py deleted agent.image_routing
(+siblings) from sys.modules and never restored the ORIGINAL modules — the
reloaded copies leaked. Any later same-process test holding function refs to
the original module (test_image_routing.py) then patched the reloaded copy
via mock.patch string targets, making patches invisible: order-dependent
failures (repro: 31179 file first → 2 failures; reversed → green).

Autouse fixture now snapshots the affected sys.modules entries and restores
them on teardown. Both orders + solo runs verified green.

Masked by the per-file-isolated canonical runner; bites anyone running
pytest tests/agent/ directly.
2026-07-29 18:55:10 -07:00
Fangliquan
483b9e3328 test(tests): assert SessionDB timeout without wall-clock
Replace elapsed-time checks with captured Future.result(timeout=...) values so the hang regression stays deterministic under parallel CI load.
2026-07-29 18:55:10 -07:00
Teknium
646761c783 fix(gateway): widen explicit-MEDIA resend fix to the streaming path + log bare-path suppression
Companion to the cherry-picked #74158 fix (non-streaming path):

- gateway/run.py: remove the identical history-dedup filter from
  _deliver_media_from_response — the post-stream rescan is explicit-only
  by design (#20834), so every MEDIA tag it finds is a deliberate
  attachment request; drop the now-unused history_media_paths parameter
  and its call-site plumbing.
- gateway/platforms/base.py: log suppressed bare local file paths on the
  surviving local_files history dedup (#73771 observability ask).
- tests: focused regression file covering explicit resend delivery on
  both lanes, current-turn tool-echo poisoning, surviving bare-path
  dedup + its log line, and the upstream auto-append dedup invariant.

Fixes #73771
2026-07-29 18:33:38 -07:00
webtecnica
7a83f44c4a fix(gateway): preserve explicit send-image requests from session-wide MEDIA dedup
Closes #73771

The session-wide MEDIA dedup in  (base.py)
filtered ALL media paths against prior-turn history, including explicit
MEDIA: tags the model deliberately included in its response text. When a
user asked the agent to resend an image, the dedup silently swallowed it
because that path already existed in the session transcript.

The dedup is already handled correctly by the auto-append path in
 (run.py), which scopes its scan to the current turn and
filters against  via .
The base.py filter was redundant for auto-appended tags and harmful for
explicit ones.

Fix: remove the dedup filter on  in base.py while preserving
the  variable for the  dedup (bare file
paths, which lack run.py protection).
2026-07-29 18:33:38 -07:00