hermes-agent/tests/tools
Teknium 31f70d1f2a
fix(ci): recover 38 failing tests on main (#17642)
CI Tests workflow has been red on main for 40+ consecutive runs. This
commit recovers every failure visible in run 25130722163 (most recent
completed run prior to this PR).

Root causes, by group:

Test-mock drift after product landed (fix: update mocks)
- test_mcp_structured_content / test_mcp_dynamic_discovery (6 tests):
  product added _rpc_lock (#02ae15222) and _schedule_tools_refresh
  (#1350d12b0) without updating sibling test files. Install a real
  asyncio.Lock inside the fake run-loop and patch at _schedule_tools_refresh.
- test_session.py: renamed normalize_whatsapp_identifier → canonical_
  whatsapp_identifier upstream; keep a local alias so the legacy tests
  keep working.
- test_run_progress_topics Slack DM test: PR #8006 made Slack default
  tool_progress=off; explicitly set it to 'all' in the test fixture so
  the progress-callback path still runs. Also read tool_progress_callback
  at call time rather than freezing it in FakeAgent.__init__ — production
  assigns it AFTER construction.
- test_tui_gateway_server session-create/close race: session.create now
  defers _start_agent_build behind a 50ms timer — wait for the build
  thread to enter _make_agent before closing, otherwise the orphan-
  cleanup path never runs.
- test_protocol session.resume: product get_messages_as_conversation now
  takes include_ancestors kwarg; accept **_kwargs in the test stub.
- test_copilot_acp_client redaction: redactor is OFF by default (snapshots
  HERMES_REDACT_SECRETS at import); patch agent.redact._REDACT_ENABLED=True
  for the duration of the test.
- test_minimax_provider: after #17171, dots in non-Anthropic model names
  stay dots even with preserve_dots=False. Assert the new invariant
  rather than the old 'broken for MiniMax' behavior.
- test_update_autostash: updater now scans `ps -A` for dashboard PIDs;
  the test's catch-all subprocess.run stub needed stdout/stderr fields.
- test_accretion_caps: read_timestamps dict is populated lazily when
  os.path.getmtime succeeds. Use .get("read_timestamps", {}) to tolerate
  CI filesystems where the stat races file creation.

Change-detector tests (fix: rewrite as structural invariants)
- test_credential_sources_registry_has_expected_steps: was a frozen set
  comparison that broke when minimax-oauth was added. Rewrite as an
  invariant check (every step has description, no dupes, core steps
  present) per AGENTS.md 'don't write change-detector tests'.

xdist ordering / test pollution (fix: reset state, use module-local patches)
- test_setup vercel: sibling test saved VERCEL_PROJECT_ID='project' to
  os.environ via save_env_value() and never cleared it. monkeypatch.delenv
  the VERCEL_* vars in the link-file test.
- test_clipboard TestIsWsl: GitHub Actions is on Azure VMs whose real
  /proc/version often contains 'microsoft'. Patching builtins.open with
  mock_open didn't reliably intercept hermes_constants.is_wsl's call in
  xdist workers that had already cached _wsl_detected=True from an
  earlier test. Patch hermes_constants.open directly and add
  teardown_method to reset the cache after each test.

Pytest-asyncio cancellation hangs (fix: bound product await with timeout)
- test_session_split_brain_11016 (3 params) + test_gateway_shutdown
  cancel-inflight: under pytest-asyncio 1.3.0, 'await task' and
  'asyncio.gather(cancelled_tasks)' can stall for 30s when the cancelled
  task's finally block awaits typing-task cleanup. Bound both with
  asyncio.wait_for(..., timeout=5.0) and asyncio.shield — the stragglers
  are released from adapter tracking and allowed to finish unwinding in
  the background. This is also a legitimate hardening: a wedged finally
  shouldn't stall the caller's dispatch or a gateway shutdown.

Orphan UI config (fix: merge tiny tab into messaging category)
- test_web_server test_no_single_field_categories: the telegram.reactions
  config field lived in its own 'telegram' schema category with no
  siblings. Fold it under 'discord' via _CATEGORY_MERGE so the dashboard
  doesn't render an orphan single-field tab.

Local verification: 38/38 originally-failing tests pass; 4044/4044
gateway tests pass; 684/684 targeted subset (all 16 touched test files)
passes.
2026-04-29 20:05:32 -07:00
..
__init__.py
…
test_accretion_caps.py fix(ci): recover 38 failing tests on main (#17642) 2026-04-29 20:05:32 -07:00
test_ansi_strip.py
…
test_approval.py
…
test_approval_heartbeat.py
…
test_approval_plugin_hooks.py
…
test_base_environment.py
…
test_browser_camofox.py
…
test_browser_camofox_persistence.py
…
test_browser_camofox_state.py
…
test_browser_cdp_override.py
…
test_browser_cdp_tool.py
…
test_browser_chromium_check.py fix(browser): detect missing Chromium and fail fast with actionable error (#17039) 2026-04-28 07:03:44 -07:00
test_browser_cleanup.py
…
test_browser_cloud_fallback.py
…
test_browser_console.py
…
test_browser_content_none_guard.py
…
test_browser_hardening.py
…
test_browser_homebrew_paths.py fix(browser): detect missing Chromium and fail fast with actionable error (#17039) 2026-04-28 07:03:44 -07:00
test_browser_hybrid_routing.py
…
test_browser_orphan_reaper.py
…
test_browser_secret_exfil.py
…
test_browser_ssrf_local.py
…
test_browser_supervisor.py
…
test_budget_config.py
…
test_checkpoint_manager.py
…
test_clarify_tool.py
…
test_clipboard.py fix(ci): recover 38 failing tests on main (#17642) 2026-04-29 20:05:32 -07:00
test_code_execution.py perf(tui): avoid importing classic CLI during tool discovery 2026-04-28 22:42:17 -05:00
test_code_execution_modes.py
…
test_command_guards.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_config_null_guard.py
…
test_credential_files.py
…
test_credential_pool_env_fallback.py
…
test_cron_approval_mode.py
…
test_cron_prompt_injection.py
…
test_cronjob_tools.py fix(cron): accept list-form deliver values so deliver=['telegram'] works (#17456) 2026-04-29 06:35:34 -07:00
test_daytona_environment.py
…
test_debug_helpers.py
…
test_delegate.py
…
test_delegate_subagent_timeout_diagnostic.py
…
test_delegate_toolset_scope.py
…
test_discord_tool.py
…
test_docker_environment.py feat(docker): run container as host user to avoid root-owned bind mounts 2026-04-29 16:16:43 +10:00
test_docker_find.py
…
test_dockerfile_pid1_reaping.py fix(docker): materialize bundled TUI Ink package (#16690) 2026-04-28 15:11:47 -05:00
test_env_passthrough.py
…
test_feishu_tools.py
…
test_file_operations.py
…
test_file_operations_edge_cases.py
…
test_file_ops_cwd_tracking.py
…
test_file_read_guards.py
…
test_file_staleness.py
…
test_file_state_registry.py
…
test_file_sync.py
…
test_file_sync_back.py
…
test_file_sync_perf.py
…
test_file_tools.py
…
test_file_tools_container_config.py
…
test_file_tools_live.py
…
test_file_write_safety.py
…
test_force_dangerous_override.py
…
test_fuzzy_match.py
…
test_hardline_blocklist.py fix: address self-review findings for Vercel Sandbox salvage 2026-04-29 07:22:33 -07:00
test_hidden_dir_filter.py
…
test_homeassistant_tool.py
…
test_image_generation.py
…
test_image_generation_env.py
…
test_image_generation_plugin_dispatch.py
…
test_init_session_cwd_respect.py fix(cli): respect terminal.cwd config in local terminal backend 2026-04-28 22:16:08 -07:00
test_interrupt.py
…
test_llm_content_none_guard.py
…
test_local_background_child_hang.py
…
test_local_env_blocklist.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_local_interrupt_cleanup.py
…
test_local_shell_init.py
…
test_local_tempdir.py
…
test_managed_browserbase_and_modal.py
…
test_managed_media_gateways.py
…
test_managed_modal_environment.py
…
test_managed_server_tool_support.py
…
test_managed_tool_gateway.py
…
test_mcp_circuit_breaker.py
…
test_mcp_dynamic_discovery.py fix(ci): recover 38 failing tests on main (#17642) 2026-04-29 20:05:32 -07:00
test_mcp_oauth.py
…
test_mcp_oauth_bidirectional.py
…
test_mcp_oauth_cold_load_expiry.py
…
test_mcp_oauth_integration.py
…
test_mcp_oauth_manager.py
…
test_mcp_probe.py
…
test_mcp_reconnect_signal.py
…
test_mcp_stability.py
…
test_mcp_structured_content.py fix(ci): recover 38 failing tests on main (#17642) 2026-04-29 20:05:32 -07:00
test_mcp_tool.py fix(mcp): preserve nullable schema coercion 2026-04-28 04:58:03 -07:00
test_mcp_tool_401_handling.py
…
test_mcp_tool_issue_948.py
…
test_mcp_tool_session_expired.py
…
test_memory_tool.py
…
test_memory_tool_import_fallback.py
…
test_mixture_of_agents_tool.py
…
test_modal_bulk_upload.py
…
test_modal_sandbox_fixes.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_modal_snapshot_isolation.py
…
test_notify_on_complete.py
…
test_osv_check.py
…
test_parse_env_var.py
…
test_patch_parser.py
…
test_process_registry.py fix(process): reconcile session.exited against real child exit in poll/wait (#17430) 2026-04-29 04:59:21 -07:00
test_read_loop_detection.py
…
test_registry.py revert: computer-use cua-driver (PR #16919) (#16927) 2026-04-28 01:57:21 -07:00
test_resolve_path.py
…
test_rl_training_tool.py
…
test_schema_sanitizer.py
…
test_search_hidden_dirs.py
…
test_send_message_missing_platforms.py
…
test_send_message_tool.py
…
test_session_search.py
…
test_shared_container_task_id.py
…
test_signal_media.py
…
test_singularity_preflight.py
…
test_skill_env_passthrough.py
…
test_skill_improvements.py
…
test_skill_manager_tool.py feat(skills): refuse skill_manage writes on pinned skills (#17562) 2026-04-29 10:28:25 -07:00
test_skill_size_limits.py
…
test_skill_usage.py fix(curator): defense-in-depth gates against bundled/hub skills 2026-04-28 22:33:33 -07:00
test_skill_view_path_check.py
…
test_skill_view_traversal.py
…
test_skills_guard.py
…
test_skills_hub.py
…
test_skills_hub_clawhub.py
…
test_skills_sync.py
…
test_skills_tool.py fix: address self-review findings for Vercel Sandbox salvage 2026-04-29 07:22:33 -07:00
test_spotify_client.py
…
test_ssh_bulk_upload.py
…
test_ssh_environment.py
…
test_symlink_prefix_confusion.py
…
test_sync_back_backends.py
…
test_terminal_compound_background.py
…
test_terminal_config_env_sync.py feat(docker): run container as host user to avoid root-owned bind mounts 2026-04-29 16:16:43 +10:00
test_terminal_exit_semantics.py
…
test_terminal_foreground_timeout_cap.py
…
test_terminal_none_command_guard.py
…
test_terminal_output_transform_hook.py
…
test_terminal_requirements.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_terminal_timeout_output.py
…
test_terminal_tool.py
…
test_terminal_tool_pty_fallback.py
…
test_terminal_tool_requirements.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_threaded_process_handle.py
…
test_tirith_security.py
…
test_todo_tool.py
…
test_tool_backend_helpers.py
…
test_tool_call_parsers.py
…
test_tool_output_limits.py
…
test_tool_result_storage.py
…
test_transcription.py
…
test_transcription_dotenv_fallback.py fix(stt): resolve API keys from ~/.hermes/.env via get_env_value (#17140) 2026-04-29 06:25:20 -07:00
test_transcription_tools.py
…
test_tts_dotenv_fallback.py fix(tts): tolerate missing hermes_cli.config in tts_tool import 2026-04-29 06:25:20 -07:00
test_tts_gemini.py
…
test_tts_kittentts.py
…
test_tts_max_text_length.py
…
test_tts_mistral.py
…
test_tts_speed.py
…
test_url_safety.py
…
test_vercel_sandbox_environment.py feat: add Vercel Sandbox backend 2026-04-29 07:22:33 -07:00
test_vision_tools.py
…
test_voice_cli_integration.py
…
test_voice_mode.py
…
test_watch_patterns.py
…
test_web_tools_config.py ✨ feat(web): expose search result limit 2026-04-28 02:09:30 -07:00
test_web_tools_tavily.py
…
test_website_policy.py
…
test_windows_compat.py
…
test_write_deny.py
…
test_yolo_mode.py
…
test_zombie_process_cleanup.py
…