Talk to Hermes — streaming, conversational voice with barge-in — Voice mode used to mean: speak, wait for the whole reply to generate, then listen to one long audio file. Now Hermes speaks clause-by-clause as the response streams, you can i
Wake words and hands-free control — Say your own open-vocabulary wake phrase ("hey Hermes", or anything you pick) and Hermes starts listening — detection runs on-device, so no audio leaves your machine while it waits. Multi-profile voice ro
Voice on every platform — Send a voice note to Hermes on WhatsApp, Feishu, DingTalk, LINE, QQ, Photon, or Weixin and it's transcribed and answered; auto-TTS replies are delivered platform-aware (opus where platforms want opus, captions atta
Research you can trust — grounded citations with fact-checking — The new grounded-citations skill makes Hermes produce research where every claim is backed by a verifiable source: quotes are matched against the actual page text (not halluci
Fixes #85235 ## What & why The fallback-chain dedup compares each entry's provider id as a raw, lowercased string. A provider reachable under two ids — the canonical models.dev id (`opencode`) and a legacy rename alias (`opencode-zen`, the pre-rename name that survives only as a compatibility alias) — is kept as two separate slots in the chain. That shifts t
## Summary Adds an opt-in config flag, `openrouter.show_all_models: true`, that makes the OpenRouter picker return **every live model supporting tool-calling** from `GET /v1/models` instead of only the curated subset. Default behavior is unchanged (curated list). This lets BYOK users — or anyone who wants the full list — see models that aren't in the curated
## What does this PR do? Adds `delegation.fallback_providers` so subagents can run on a fallback chain that differs from the parent agent's top-level `fallback_providers`. Today `_build_child_agent` unconditionally passes the parent's `_fallback_chain` as the child's `fallback_model`, so a subagent pinned to a cheap/fast provider still fails over to the main
## Summary - preserve the user's governing outcome separately from the current subtask, latest correction, and one reference-only next step in local compaction handoffs - validate the continuation schema before persistence, including deterministic fallback and no-user-provenance paths - keep micro-compaction noncanonical while preserving chronological author
## Summary - make model-facing `delegate_task` calls synchronous by default so parents receive every subagent result before concluding - preserve detached execution behind explicit `background=true` for independent work - keep orchestrator workers synchronous even if a model supplies `background=true` - update the tool schema, bundled skill reference, and de
## What does this PR do? `scripts/install.sh` still provisioned Hermes-managed **Node 22**, whose stock npm is **11.16.0**. Root `engines.npm` is `<11.10.0 || >=11.17.0` (npm 11.10–11.16 ignore `.npmrc` `min-release-age-exclude`, so that band is fatal under `engine-strict=true`). A fresh managed install therefore dies at the first `npm ci` with EBADENGINE —
## Summary - classify local POSIX `EMFILE`/`ENFILE` descriptor exhaustion in gateway error envelopes - show a static, actionable gateway-host diagnostic on chat surfaces without leaking local paths or exception details - preserve raw diagnostics for programmatic/local/API/webhook surfaces and avoid rewriting ordinary prose - add focused gateway classificatio
## Summary - add a separate `nous-blue-contrast` dashboard theme that preserves the existing Nous Blue chrome while using a dark navy embedded terminal - add an independently selectable TUI/CLI skin with a complete high-contrast Nous Blue palette - expose both additions through existing catalogs and settings, with user documentation ## Motivation The existin
## What does this PR do? In-place context compaction already rewrites the transcript atomically via `archive_and_compact()`, then called `update_system_prompt()` in a **second** write. A crash or SQLite failure between those two commits left a session with compacted messages and the old system prompt (split-brain on resume). Rotation already published prompt
## What does this PR do? WhatsApp **self-chat** is the owner's personal number, not a public bot. With the default `WHATSAPP_DM_POLICY=pairing`, unknown DMs still received `Here's your pairing code: …` — confusing and unprofessional (#84706). Self-chat now defaults unauthorized DMs to **ignore**, even when `dm_policy` is `pairing`. An explicit `unauthorized_
## Description Adds an Arabic translation of `README.md`. Arabic is already a supported language in the product (`agent/i18n.py`, desktop/web `ar.ts` locales) but had no README translation. ### Changes made: - Added `README.ar.md` following the `README.ur-pk.md` conventions: `<div dir="rtl">` wrapper, `<div dir="ltr">` around code blocks and command tables.
Fixes #85251 ## Problem `_manage_thinking_signatures` in `agent/anthropic_adapter.py` strips **all** thinking blocks from replayed assistant turns for third-party Anthropic-Messages endpoints. MiniMax was grouped into that generic "cannot validate them and will reject them outright" bucket, but that premise does not hold for MiniMax: it returns *signed* thin
## Summary Closes part of #83390 (the pre-existing DeepSeek thinking-leak on `title_generation`). The `title_generator.py` docstring claimed thinking was disabled, but `generate_title()` set neither `reasoning_config` nor `reasoning_effort`. On reasoning-aware providers whose default is thinking ON (DeepSeek V4 family, including via OpenCode Go), the model b
## Summary - Treat disabled native MCP server entries as inactive configuration. - Prevent startup discovery from opening when all configured servers are disabled. - Preserve agent-plugin MCP detection. ## Test plan - `uv run --with pytest python -m pytest -q tests/hermes_cli/test_mcp_startup.py` - Result: 4 passed, 1 warning. The change is based directly on
## What does this PR do? The offline dataset pipeline loaded every trajectory into RAM, then created one coroutine per row and `asyncio.gather(*tasks)`. The semaphore only capped in-flight API calls — not task/closure count or retained results — so large JSONL dumps OOM'd. Sampling now streams HuggingFace rows (streaming load when the hub supports it) and re
## Summary - close `task_runs` left running after their task is blocked, terminal, or moved to a successor run - preserve task workflow state and write a correlated `run_reconciled` audit event transactionally - defer reconciliation while the detached run still records a live PID - run the repair in the existing opt-out orphan-reconciliation dispatch phase #
## Summary The no-progress detector keyed on `(signature, result_hash)`, so any repeat whose *result* differed reset the streak. Two mechanisms exploited that in live sessions, and a third survived even after signature counting: 1. The context compressor rewrites an older duplicate tool body to `[Duplicate tool output ...]`, which changes the hash. 2. Tools
## What does this PR do? Adds SayGM through Hermes' `ProviderProfile` architecture so users get safe live model discovery, curated fallbacks, output limits, and the provider-specific Sol request adjustment. Static prices are intentionally omitted because SayGM routing prices can change at runtime. ## Related Issue Fixes #85325 ## Type of Change - [x] ✨ New f
## What does this PR do? Libera.Chat [forbids LLM-powered agents](https://libera.chat/news/bot-policy-update). Hermes still used `irc.libera.chat` as the example host in IRC setup, plugin env docs, and the user guide, so the recommended configuration walked users into a policy violation. Examples now point at a local IRCd (`127.0.0.1`). Setup text says so ex
## What does this PR do? Adds a clear **Report a problem on GitHub** action to Desktop Settings → About for users who do not know where or how to file a bug. The action opens an editable GitHub issue draft in the system browser with a small allowlist of diagnostics Desktop already knows: app version, platform, Electron version, and a validated short source r
Fixes HTTP 400 error (invalid reasoning value 'xhigh') when reasoning effort is set to xhigh on OpenAI-compatible and Nous Portal endpoints. Clamps xhigh -> high and minimal -> low before assembling reasoning extra_body.
## What does this PR do? Micro-compaction spliced the rolling summary into the in-memory transcript, then called `_sync_micro_compact_to_db` and swallowed any exception. Resume then loaded the still-active originals on top of the already-compacted list. Rehydrated marker text and generated micro summaries also skipped the batch path's strict redaction, so a
## Summary Fix two gaps in the tool-loop no-progress guardrail that let repeated successful bookkeeping calls survive indefinitely: 1. Count repeated identical **tool signatures**, not repeated result hashes. - Context compression can replace a repeated tool body with `[Duplicate tool output — same content as a more recent call]`. - Some tools intentionally
## Problem On Homebrew/Nix installs the launchd-supervised gateway logs `No adapter available for <platform>` for every bundled messaging platform (telegram, discord, slack, …), even when the plugin is enabled, the SDK is installed, and the token is valid. The identical setup works when started from a shell. ## Root cause The `hermes` wrapper exports resourc
## Summary Adds `HookRegistry.emit_waterfall()` — a Cordis-style **around-middleware** dispatch mode for gateway event hooks. This is the Hermes port of the waterfall primitive DeepSeek Harness uses for its tool execution pipeline (`tools/pre-execute` → `tools/execute` → `tools/post-execute`), where cooperative listeners mutate a shared request and delegate
## Summary Add a non-failing `Source Checkout` section to `hermes doctor` so users can tell whether the running Hermes install is clean upstream, behind/ahead of its upstream, or dirty with local live patches. The section reports: - current branch / detached state and short HEAD - upstream ahead/behind counts when an upstream is configured - tracked local mo
## Fix for #85335 ### Problem When a Hermes Desktop is configured to connect to a Nous-managed cloud agent (e.g. `https://ares-3009.agents.nousresearch.com`) and that backend returns **HTTP 503 Service Unavailable**, the error surfaces as a generic 'Hermes backend did not become ready: 503: ...' message with no guidance that the cloud server itself is down.
## Summary - identify each direct, user-visible Kanban terminal notification with a versioned `hermes_kanban_notification` envelope - preserve existing subscription chat/thread routing metadata while keeping the stored subscription mapping unchanged - retain the distinct `hermes_kanban_wake` envelope on the later synthetic internal wake, including determinis
## Summary Fixes #84572 by making Desktop represent existing Hindsight `local_embedded` configuration honestly without bypassing the setup flow that installs its runtime dependencies. - preserves an existing `local_embedded` mode as a disabled, read-only select option instead of displaying the Cloud default - exposes the embedded LLM provider, base URL, mode
## Summary - prime the pooled read path before attaching SQLite trace callbacks - trace the same connection that `_read_ctx()` will borrow during FTS searches - restore deterministic query-count coverage for context projection ## Root cause The test opened a fresh read connection with `_get_read_conn()` and attached a trace callback to it. Since the read pat
## Reproduction On Hermes 0.20.0, an explicit openai-codex prompt succeeds against the ChatGPT backend, but the Codex quota helper returns no data because the pool-only OAuth path omits ChatGPT-Account-Id and receives HTTP 401. Desktop and gateway /usage also show Nous credits solely because a Nous login exists, even while openai-codex is active. ## Fix - de
## Problem On Linux, the auto-installed `hermes.desktop` menu entry can be silently broken. `resolve_exec_command()` writes `Exec=<argv[0]> desktop`, and when Hermes is launched through a venv wrapper script (e.g. `~/.local/bin/hermes` doing `exec venv/bin/python .../hermes-agent/hermes "$@"`), `argv[0]` is the in-checkout `./hermes` Python script. That scri
## Summary - add configurable Discord decision channels where 👍 approves and 👎 rejects bot-authored decision messages - isolate each reacted decision into its own session so rapid approvals cannot interrupt or overwrite one another - enforce existing user/channel authorization, ignore bot reactions, and preserve first-reaction semantics while allowing retry
## What does this PR do? Redacts opaque `access_key` and `ticket` values from `ws://` and `wss://` endpoint query strings before they reach logs or tool output. The redaction is deliberately limited to WebSocket transport URLs. Ordinary `http://` and `https://` links keep the existing passthrough behavior so OAuth callbacks, magic links, and pre-signed URLs
## Summary Adds a native **MCP Streamable-HTTP endpoint** to the Hermes API server (gateway), so MCP clients (e.g. Open WebUI) can consume agent tools directly from the gateway process — replacing the need for a separate MCP bridge service. Also makes tool-progress visible to strict OpenAI-stream clients by additionally emitting standard `chat.completion.chu
## Description Updates the supermemory plugin to explicitly support self-hosting by prompting for the ase_url during hermes memory setup and saving it to supermemory.json. This removes the need for users to manually edit supermemory.json prior to running the setup wizard, smoothing out the user experience for local installations while adhering to the config
Related to #85301 The current web API layer already scopes `/api/mcp/*` requests through the global management-profile mechanism. This adds a focused regression test for `api.getMcpServers()` so switching profiles cannot silently regress to reading the dashboard process profile. Checks: - `npx vitest run --config vitest.config.ts src/lib/api.test.ts` (8 pass
## Summary Cron jobs pinned to a dead model failed with HTTP 402 for days, ignoring `fallback_providers`. The cron layer only had fallback at the resolve stage (credential-dead) but not at runtime 402 — a pinned dead model (quota exhausted / plan removed) made the job fail forever with `Fallbacks=None`. ## Change (`cron/scheduler.py`) - **Dead-model 402 dete
## What does this PR do? Extends the #80622 active-turn guard to one merged-carrier shape that still escaped it. When compaction merges its summary into an assistant tail message, the carrier keeps `role="assistant"`, the assistant's prior prose, and any inherited `tool_calls`. If that merged carrier immediately follows a completed assistant response with `f
## Summary The sherpa wake-word engine hardcoded BPE tokenization (`text2token` + `bpe.model`), which only covers Latin-script phrases on the default English GigaSpeech model. The wenetspeech KWS model — sherpa-onnx's Chinese counterpart — is **pinyin-modeled** (声母/韵母 phonemes) and ships no `bpe.model`, so pointing `wake_word.sherpa.model_dir` at it crashed
## Summary - Treat the checkout-root and TUI `npm install` operations as required steps in `scripts/install.sh`. - Propagate dependency-install failures through both the monolithic installer and the `node-deps` stage, restore tracked lockfile churn, and suppress success output when installation fails. - Preserve successful installs and the existing best-effo
## What Anchor the Telegram MarkdownV2 fenced-code protection regex to line starts so it only matches **standalone** fenced code blocks, and stop it from swallowing **inline** triple-backtick spans. Fixes #85381. ## Why In `plugins/platforms/telegram/adapter.py`, `format_message()` protects fenced code blocks before MarkdownV2 escaping with: ```python r'(```
Adds a single bounded StartupCoordinator path before the first prompt build. Startup context is attached once to the first user sidecar, receipts are immutable and redacted, duplicate injectors are rejected, and system-prompt bytes remain stable. Cold diagnostic callers avoid loading optional plugin and MCP runtimes.\n\nValidation: canonical scripts/run_test
Allows automatic titles to use the deterministic path without enabling later model-based title upgrades. The default behavior remains unchanged.\n\nValidation: canonical scripts/run_tests.sh; 35 title tests passed.\n\nRelated: #85194
## What Fixes two WhatsApp pairing bugs from #85391 that together strand users in a restart loop against an "enabled but not paired" precondition no restart can satisfy. Fixes #85391 (Bugs 1 & 2). Bug 3 in the issue is a minor packaging/UX note (dependency-less bridge copy under the install root) and is left for a follow-up. ## Bug 1 — wizard paired into a d
- persist exact backend ownership and coordinate shutdown so failed starts and app relaunches do not leave resource-heavy servers behind - park inactive panes and use a weighted protected-session cache so hidden transcripts no longer grow renderer memory without bound - preserve active, stateful, and terminal surfaces while validating lifecycle behavior acro
## Problem The desktop app's passive update check ("Settings → About → Check now", and the background auto-check) can report **"You're on the latest version" while the checkout is thousands of commits behind the official repo.** `checkUpdates()` in `apps/desktop/electron/main.ts` only probed the official repo when the local git origin was the **official SSH*