test(7/N): green up hermes_cli + cron + run_agent + plugins long tail#11
Conversation
Fixes 10 long-tail test failures across 7 files. Each was investigated
independently; root causes mix genuine production regressions, intended
behavior changes, and test-side signature/value drift.
hermes_cli:
- test_hy3_preview_context_length: round-number-stale assertion. The
authoritative source (OpenRouter live metadata, consulted before the
hardcoded fallback) reports 262144 = 256*1024 = true binary 256K for
hy3-preview. Updated the test to 262144 and aligned the hardcoded
fallback value/comment in agent/model_metadata.py.
- test_very_different_name_falls_to_suggestions: validate_requested_model
accepted ANY codex model name. Now rejects names too different to even
offer a close-match suggestion (suggestions empty), while keeping the
proxy-friendly accept-with-suggestions path for near-misses.
- test_lmstudio_provider_saved_when_selected: test drift. An existing
API key triggers _prompt_api_key's [K]eep/[R]eplace/[C]lear input()
prompt, so two interactive prompts fire, not one. Provided both values.
- test_stepfun_provider_saved_with_selected_region: same root cause -
the [K]eep/[R]eplace/[C]lear prompt read stdin in a non-interactive
pytest context (OSError). Patched builtins.input in the test.
cron:
- test_script_empty_output_noted: _build_job_prompt returned None on
empty script output, so the test's .lower() hit NoneType. Empty output
is now noted in the prompt ('no output') instead of dropping it; the
wake-gate / no_agent layers still own the skip-the-AI-run decision.
- test_run_job_calls_discover_mcp_tools_before_agent_construction /
..._tolerates_discover_mcp_tools_failure: discover_mcp_tools() was
gated behind provider auth, which fails in the credential-stripped test
env, so it ran AFTER (or never reached) AIAgent construction. Moved MCP
discovery before provider resolution (it doesn't depend on the runtime),
and added the resolve_runtime_provider mock the tests were missing
(every other run_job test stubs it).
run_agent:
- test_concurrent_interrupt (both): test-fixture drift. The _Stub lacked
_tool_guardrails and _append_guardrail_observation (added to
_execute_tool_calls_concurrent after the fixture was written), and the
fake tool side_effects didn't accept the messages / pre_tool_block_checked
kwargs the production call now passes. Updated the fixture + signatures.
plugins:
- test_evaluate_all_stale_cache_serves_stale_and_refreshes_in_background:
real race. evaluate_all() returned the _SNAPSHOT_CACHE module global by
reference AFTER kicking the background scan, so a fast worker could
rebind it to fresh data before the return, breaking stale-serves-stale.
Capture the snapshot reference before starting the background scan.
Validation: pytest -q tests/hermes_cli/ tests/cron/ tests/run_agent/
tests/plugins/ -> this PR's 10 targets all green; the 19 remaining
failures belong to the 5 parallel PR clusters (gateway/systemd, web_server
PTY, model_switch_custom_providers, provider_parity, bedrock, list_picker)
and are confirmed pre-existing on main.
🔎 Lint report:
|
| Rule | Count |
|---|---|
invalid-argument-type |
5 |
unresolved-attribute |
1 |
First entries
tests/run_agent/test_concurrent_interrupt.py:94: [unresolved-attribute] unresolved-attribute: Unresolved attribute `_append_guardrail_observation` on type `_Stub`
run_agent.py:12539: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`
run_agent.py:6649: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown, Unknown] | Any | ... omitted 3 union elements`
tests/run_agent/test_concurrent_interrupt.py:41: [invalid-argument-type] invalid-argument-type: Argument to constructor `NonCallableMock.__new__` is incorrect: Expected `bool | None`, found `MagicMock`
tests/run_agent/test_concurrent_interrupt.py:41: [invalid-argument-type] invalid-argument-type: Argument to constructor `NonCallableMock.__new__` is incorrect: Expected `bool`, found `MagicMock`
run_agent.py:12542: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown, Unknown] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`
✅ Fixed issues (4):
| Rule | Count |
|---|---|
invalid-argument-type |
3 |
invalid-return-type |
1 |
First entries
cron/scheduler.py:814: [invalid-return-type] invalid-return-type: Return type does not match returned value: expected `str`, found `None`
run_agent.py:6649: [invalid-argument-type] invalid-argument-type: Argument to function `build_anthropic_client` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`
run_agent.py:12539: [invalid-argument-type] invalid-argument-type: Argument to function `_is_oauth_token` is incorrect: Expected `str`, found `str | dict[Unknown | str, Unknown | str | dict[str, str]] | Any | ... omitted 3 union elements`
run_agent.py:12542: [invalid-argument-type] invalid-argument-type: Argument to function `len` is incorrect: Expected `Sized`, found `(str & ~AlwaysFalsy) | (dict[Unknown | str, Unknown | str | dict[str, str]] & ~AlwaysFalsy) | (Any & ~AlwaysFalsy) | ... omitted 3 union elements`
Unchanged: 4072 pre-existing issues carried over.
Diagnostics are surfaced as warnings — this check never fails the build.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is ON, but it could not run because the branch was deleted or merged before autofix could start.
Reviewed by Cursor Bugbot for commit add2e05. Configure here.
| prompt = ( | ||
| "## Script Output\n" | ||
| "The pre-run script ran successfully but produced no " | ||
| "output (no output).\n\n" |
There was a problem hiding this comment.
Redundant "no output" repeated in prompt message
Low Severity
The constructed prompt reads "The pre-run script ran successfully but produced no output (no output)." — the parenthetical (no output) is a verbatim repetition of what the sentence already states. This looks like an editing artifact where the parenthetical was likely meant to contain a different clarification (e.g., "stdout was empty" or "exit code 0") but accidentally duplicated the same phrase.
Reviewed by Cursor Bugbot for commit add2e05. Configure here.


Context
PR #6 (1/N) merged; ~38 pre-existing failures remained on
main. This PR cleans up the long tail — 10 failures across 7 files inhermes_cli,cron,run_agent, andplugins. Each was investigated independently; root causes are a mix of genuine production regressions, an intended behavior change, and test-side signature/value drift.Tests fixed (10)
tests/hermes_cli/test_model_validation.py::TestValidateCodexAutoCorrection::test_very_different_name_falls_to_suggestionstests/hermes_cli/test_model_provider_persistence.py::TestProviderPersistsAfterModelSave::test_lmstudio_provider_saved_when_selectedtests/hermes_cli/test_model_provider_persistence.py::TestBaseUrlValidation::test_stepfun_provider_saved_with_selected_regiontests/hermes_cli/test_tencent_tokenhub_provider.py::TestTencentTokenhubContextLength::test_hy3_preview_context_lengthtests/cron/test_cron_script.py::TestBuildJobPromptWithScript::test_script_empty_output_notedtests/cron/test_scheduler_mcp_init.py::test_run_job_calls_discover_mcp_tools_before_agent_constructiontests/cron/test_scheduler_mcp_init.py::test_run_job_tolerates_discover_mcp_tools_failuretests/run_agent/test_concurrent_interrupt.py::test_running_concurrent_worker_sees_is_interruptedtests/run_agent/test_concurrent_interrupt.py::test_concurrent_interrupt_cancels_pendingtests/plugins/test_achievements_plugin.py::test_evaluate_all_stale_cache_serves_stale_and_refreshes_in_backgroundRoot cause per test
262144=256*1024= true binary 256K. Test asserted the decimal256000.agent/model_metadata.pyvalidate_requested_modelaccepted any codex model name (proxy-friendly catch-all).suggestionsempty); keep accept-with-suggestions for near-misses_prompt_api_key's[K]eep/[R]eplace/[C]learinput()prompt, so two prompts fire (K/R/C + base URL), not one.StopIterationon the exhausted side_effect list.OSError: reading from stdin while output is captured).builtins.input_build_job_promptreturnedNoneon empty script output, so.lower()hitNoneType.no_agentlayers still own the skip-the-AI decisiondiscover_mcp_tools()was gated behind provider auth, which fails in the credential-stripped test env, so it ran after (or never reached)AIAgentconstruction.resolve_runtime_providermock the tests were missing (every otherrun_jobtest stubs it)_Stublacked_tool_guardrails+_append_guardrail_observation(added to_execute_tool_calls_concurrentafter the fixture was written), and the fake-tool side_effects didn't accept themessages/pre_tool_block_checkedkwargs the production call now passes.evaluate_all()returned the_SNAPSHOT_CACHEmodule global by reference after kicking the background scan; a fast worker rebinds it to fresh data before the return, breaking stale-serves-stale.Validation
pytest -q tests/hermes_cli/ tests/cron/ tests/run_agent/ tests/plugins/:tests/cron/,tests/plugins/test_achievements_plugin.py,tests/hermes_cli/test_tencent_tokenhub_provider.py,test_model_validation.py,test_model_provider_persistence.py,tests/run_agent/test_concurrent_interrupt.py).test_gateway_wsl+test_gateway_service,test_web_serverPTY,test_model_switch_custom_providers,test_provider_parity,test_bedrock_model_picker,test_list_picker_providers) plus 2tests/tools/test_mcp_*import errors — all confirmed pre-existing onmain(verified by stashing this PR's diff).Remaining-on-main count
This PR closes its 10-test cluster from the original 38. The remaining failures are accounted for by the other 5 parallel PRs; together they target all 38.
Ambiguity flags
262144. The production comment says "256K context window,"256*1024 == 262144, and the authoritative OpenRouter live metadata returns262144. The decimal256000was the stale round-number form. Updated both the test and the (unreachable-in-practice) hardcoded fallback for consistency._parse_wake_gate) andno_agentpaths inrun_job; the defensiveprompt is Noneguard inrun_jobis retained.Note
Low Risk
Changes are localized (cron prompt/MCP init order, stricter Codex name rejection, context metadata, achievements read path); no auth or payment paths touched.
Overview
This PR fixes a long tail of failing tests (~10) across
hermes_cli,cron,run_agent, and plugins, with several production fixes alongside test updates.Cron: Pre-run scripts that succeed with empty stdout now inject a short “no output” note into the job prompt instead of returning
None(which broke callers).discover_mcp_tools()runs before provider resolution so MCP tools register even when auth/fallback would have blocked discovery later.Models / metadata:
hy3-previewcontext length is aligned to 262144 (binary 256K). OpenAI Codex validation rejects model names with no fuzzy-match suggestions instead of always accepting unknown slugs.Achievements plugin: On stale cache + background refresh, the API snapshots the in-memory cache before starting the scan so concurrent updates don’t return fresh data when stale was intended.
Tests: Provider persistence flows stub extra
input()prompts; cron MCP tests mockresolve_runtime_provider; concurrent-interrupt stubs add tool guardrails and updated fake-tool signatures.Reviewed by Cursor Bugbot for commit add2e05. Bugbot is set up for automated code reviews on this repo. Configure here.