fix(gateway): sync /model and /personality with CLI pattern - #150
Conversation
c95bd84 to
07fcb94
Compare
|
Rebased on Saw the model display resolution in e09ef6b that config.yaml fallback is the right call. This PR picks up where that left off and covers the two remaining pieces: Table 👇
just bringing the gateway commands in line with how the CLI already handles these operations. Do not merge if the intention for the
|
|
Thanks! |
…odel-personality-commands fix(gateway): sync /model and /personality with CLI pattern
…odel-personality-commands fix(gateway): sync /model and /personality with CLI pattern
… — error bars + agent nudge
Vote-share forecasts now express + render per-candidate uncertainty. The parallel
form (chosen for consistency with the live data, which already stores it): the payload
stays {candidate: share} (machine-scoreable as-is), and per-candidate 90% intervals
live in metadata.candidate_share_intervals_pp = {candidate: {p05, median, p95}}.
- dashboard._candidate_intervals normalizes that metadata to {candidate: {lo, mid, hi}}
on the workspace item (None when absent/malformed; inverted lo>hi dropped).
- HistogramBar gains an optional `interval`; histogram() appends ` [lo–hi]` so each
candidate bar shows its spread next to the point share. distributionBars attaches
the interval per candidate by label.
- protocol nudge: a vote-share forecast should carry candidate_share_intervals_pp so
the Desk draws an error bar per candidate — quantify each candidate's spread, not
just a point share.
Tests: _candidate_intervals normalization (+ malformed -> None), distributionBars
interval attachment, histogram [lo–hi] suffix. TUI type-check + 98 chart/workspace
tests green; bundle rebuilt; forecasting dashboard/protocol regression green.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…high + 10 med + lows) A multi-agent review of NousResearch#150/NousResearch#138/NousResearch#137/NousResearch#139 confirmed 21 findings. Fixed: HIGH (NousResearch#139): forecast.theses ran inline on the gateway dispatch thread while doing per-thesis N+1 work — it can stall interrupt/approval RPCs on a large book. Added it to _LONG_HANDLERS (thread pool) + a routing regression test. Also: one shared ForecastLedger per call (was two), error code 5008 (was a colliding 5021), _num excludes bool, and the CLI dashboard now renders factors too (parity with the RPC/tool; matches its docstring). NousResearch#150 (vote-share intervals): intervals silently dropped on the fraction-scale path (the PMF branch never attached them) — now attached on both branches. Interval lookup now tolerates case/whitespace divergence from the scorer/hook key normalization. And the intervals (always percentage-points) are rescaled to the payload's scale, so a fraction-scale share renders `0.70 [0.50-0.85]` not `0.70 [50-85]`. NousResearch#138 (readiness benchmarks): evaluating with the default --last window or a --dataset filter could hide the freshly-run suite (a closed gap looked reopened / zero closed) — the improve path now evaluates over ALL runs, unfiltered. Dropped `naive` (can't beat baselines, so it can't close the edge gap). The tool mirror wraps the run in try/except. NousResearch#137 (cycle --agent): selection now filters on alert.scope_type == "question" (a domain/topic/portfolio alert's scope_ref is not a question; this also keeps a question-scoped domain_error_profile_applies trigger). --max-questions now counts processed (expensive) LLM runs, not just commits, so it actually caps. --max-iterations 0 is honored (was coerced to 12). Deferred (noted): a per-candidate central-within-interval COMMIT gate (a new backend invariant mirroring central_within) — warrants its own pass. New tests cover every fix above. Full tests/forecasting + tests/tools + gateway regression green (6834 passed); TUI type-check + 99 chart/workspace tests green; bundle rebuilt. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…odel-personality-commands fix(gateway): sync /model and /personality with CLI pattern
… (DAN-2503) (NousResearch#150) v0.20 regression from the fork sync: _select_under_lock() called self._select_unlocked(model=model), but `model` is undefined in that scope and _select_unlocked(self, *, refresh=True) does not accept a `model` kwarg at all. pool.select() therefore raised NameError: name 'model' is not defined. Call chain: cron run_job -> resolve_runtime_provider -> pool.select() -> _select_under_lock -> NameError. Every cron job that resolves a runtime provider failed (fusion-watchdog, Signal Scanner Unified, KB Research Unified, Config Integrity Watchdog, ...) — the whole cron fleet was down post-v0.20-deploy. Fix: return self._select_unlocked() (drop the dead kwarg). The model= arg was leftover from an incomplete refactor in the upstream sync; no code path supplies model here and _select_unlocked has no model parameter. Co-authored-by: Claude <noreply@anthropic.com>
…-2503) (NousResearch#151) Second v0.20 regression in the same incomplete "model lockouts" feature as NousResearch#150. _available_entries() referenced `if model_lockouts_active: continue` (line 1968) but model_lockouts_active is never defined anywhere in the codebase — like the `model` kwarg in NousResearch#150, it was leftover from an incomplete refactor that never wired model-aware selection through select -> _select_under_lock -> _select_unlocked -> _available_entries (none of which take a model param). After NousResearch#150 fixed the first NameError (model), pool.select() advanced one step and hit this one: NameError: name 'model_lockouts_active' is not defined. Same root cause, same fix class: drop the dead check. Restores pre-feature behavior (entries available; the lockout feature never worked, so nothing is lost). Verified on mfc1: hot-patched deployed checkout + restarted + triggered fusion-watchdog -> "Ran now: succeeded." (cron fleet unblocked). Co-authored-by: Claude <noreply@anthropic.com>
Issue
When a user runs /model on Discord (or any gateway platform), it
displays "anthropic/claude-opus-4.6" the hardcoded fallback (or nothing on accounts of other users) even
though the agent is actually using the model from config.yaml (e.g.
minimax-m2.5). Running /model reports success, but the next
message still uses whatever config.yaml says. Similarly, /personality
reports success but the personality never changes.
To reproduce:
Fix
Align gateway
/modeland/personalitycommand handlers with howthe CLI chat (
hermes chat) already handles them. reading from andwriting to
config.yamlinstead of environment variables.builds on the patterns established by @teknium1 in:
save_config_valueand the CLI/model+/personalityhandlers were introduced with config.yaml asthe source of truth
config.yaml per message.
The gateway command handlers were the last piece that hadn't caught
up to this pattern as they still wrote to env vars that the agent init
immediately overrides from config.yaml.
Changes
Not trying to intro new pattern/style, uses the same yaml read-modify-write
approach already present in the gateway's
_handle_set_home_command./modeldisplay now resolves from config.yaml using the same chainas the agent init, instead of the HERMES_MODEL env var fallback
/model <name>persists tomodel.defaultin config.yaml (matchingCLI's
save_config_value("model.default", ...)at cli.py:1656)/personality <name>writes toagent.system_promptin config.yamland updates the in-memory ephemeral prompt (matching CLI's
save_config_value("agent.system_prompt", ...)at cli.py:1386)HERMES_PERSONALITYenv var write (zeroconsumers in the codebase)
Test plan
/model(no args) → should show model from config.yaml/model other-model→/modelagain → should showother-model/personality pirate→/new→ send a message → pirate-style response~/.hermes/config.yamlafter each → values persistedTested on: Linux (WSL2), Discord