Commit Graph
4 Commits
Author SHA1 Message Date
nesquena-hermes f8007d43f3 v0.50.257: 4 Opus pre-release follow-ups + CHANGELOG + test fixes for #1415
stage-257 batch (PRs #1402 + #1415):

Opus pre-release advisor caught 4 issues in stage-257:

1. MUST-FIX (security): api/oauth.py::_write_auth_json — tmp.replace()
   preserves the temp file umask (0644 default), so OAuth access/refresh
   tokens landed world-readable on shared systems. Fix: tmp.chmod(0o600)
   BEFORE rename, with try/except OSError that warns but does not abort.

2. SHOULD-FIX: _handle_cron_history and _handle_cron_run_detail accepted
   job_id as a path component without validation. Mirrors the rollback
   path-traversal vector caught in v0.50.255 (#1405). Path() / .. does NOT
   normalize. New regex ^[A-Za-z0-9_-][A-Za-z0-9_.-]{0,63}$ with explicit
   . / .. rejection.

3. SHOULD-FIX: _handle_cron_history int(offset)/int(limit) raised
   ValueError on malformed input → confusing 500. Now try/except + clamp
   to (max(0, offset), max(1, min(500, limit))).

4. NIT: same regex applied to _handle_cron_run_detail (defense-in-depth
   even though path-resolve check would catch it downstream).

PR #1415 follow-up: 8 pre-existing tests in test_issue1106 and
test_custom_provider_display_name asserted bare model IDs but #1415
changes named-custom-provider IDs to @custom:NAME:model form when active
provider differs. Tests updated to use _strip_at_prefix helper to keep
checking the same invariant in the new shape.

4 regression tests in test_v050257_opus_followups.py + 8 fixed pre-existing
tests. Full suite: 3602 passed, 0 failed.
2026-05-01 18:30:41 +00:00
nesquena-hermes 2d8bccdd96 fix(tests): add autouse cache-isolation fixture to get_available_models test files
Fixes the CI failure introduced by #817: test_model_resolver::test_custom_endpoint_uses_model_config_api_key_for_model_discovery was failing with KeyError: 'auth' due to the 60s TTL cache in get_available_models() being populated by test_byok_model_dropdown.py tests that ran earlier. Added autouse _isolate_models_cache fixture to 5 test files. Full suite 1747/1747, QA harness green.
2026-04-21 17:41:05 -07:00
nesquena-hermes a1c5c395e5 fix(tests): pin _cfg_mtime in _models_with_cfg to prevent ordering-dependent failure — v0.50.109 (fixes #754) (#756)
## Summary

Fixes the ordering-dependent test failure in `test_custom_provider_display_name.py` (issue #754).

**Root cause:** `_models_with_cfg()` patches `config.cfg` then calls `get_available_models()`. That function checks `config.yaml`'s mtime on every call — if it has changed since the last `reload_config()`, it calls `reload_config()` again, which reads from disk and silently overwrites the patch. Any test that writes `config.yaml` (e.g. via `save_settings()`) before this test runs changes the mtime and triggers the reload.

**Fix:** Pin `config._cfg_mtime` to the current `config.yaml` mtime before calling `get_available_models()`, then restore it in the `finally` block. This is the same pattern already used in `test_model_resolver.py` (lines 249, 393).

**Also restores `_cfg_mtime`** in the `finally` block so the patch leaves no side effects on subsequent tests.

## Tests

1510 passed — the previously-flaky test now passes regardless of which tests ran before it.

Closes #754
2026-04-20 00:39:24 -07:00
Hermes Agent 3e1ba1b783 fix(models): show named custom provider label in model dropdown instead of generic 'Custom'
When a custom_providers entry in config.yaml has a 'name' field (e.g. 'Agent37'),
the web UI model picker now uses that name as the group header instead of the
generic 'Custom' label.

Previously all custom_providers entries were bucketed under 'custom' which
rendered as 'Custom' in the dropdown optgroup — losing the named identity the
user set up during onboarding.

Changes:
- Track named custom providers as 'custom:<slug>' keys internally so multiple
  named providers can coexist as separate groups
- When building model groups, emit each named provider under its own display
  name (e.g. 'Agent37') rather than falling through to the generic label
- Unnamed entries (no 'name' field) still fall back to the 'Custom' group
- When all entries are named, the bare 'Custom' bucket is suppressed

Adds 7 tests covering single named provider, multiple named providers,
multiple models in same named provider, unnamed fallback, and mixed cases.

Fixes #557
2026-04-16 01:09:39 +00:00