Commit Graph
1114 Commits
Author SHA1 Message Date
Calvin Ng 5239b1323e fix(models): make GLM-5.3 the silent default model (#144810)
GLM-5.2 became the silent default (the model Hermes lands on when the user
never picked one) in #64635 as a capable low-cost pick. GLM-5.3 has since
superseded it at about the same price on Nous Portal and OpenRouter, with
the same 1M context, and both curated catalogs already list it.

Move every copy of the default together:

- PREFERRED_SILENT_DEFAULT_MODEL and the OpenRouter "default" description.
- The "default": true label in website/static/api/model-catalog.json,
  regenerated with scripts/build_model_catalog.py, so clients rotate from
  their cached catalog without a release.
- The TUI's _resolve_model last resort, which hardcoded "z-ai/glm-5.2" and
  would drift on every rotation; it now reads the constant from the
  data-only models_catalog_static module.
- The example manifest in the model catalog reference docs.

The new TUI test pins the no-model fallback to the constant, and the
manifest contract test is renamed since it checks whatever the constant is.
2026-10-26 03:50:53 +00:00
unsupportedpastels 395c673739 fix(webapp): point to --no-open when a private launch opened no visible browser
On macOS webbrowser.open can return True with no page the user sees: over SSH osascript opens the browser on the Mac's own screen, and a sandboxed browser may refuse a file: page in a hidden folder. After a private launch, say how to get the link. The docs no longer say an SSH session always prints the link: that holds on the BSDs and illumos. The private-launch docstring notes that on macOS the URL reaches osascript on stdin, so the page mainly protects the BSDs and illumos.
2026-10-25 23:32:04 -04:00
unsupportedpastels 166bc0f822 fix(webapp): open private launch links through a user-only page
Where nothing checks who redeems a one-use launch link (macOS, the BSDs, illumos, WSL), hermes webapp printed it, and any local user who read it first could redeem it within its 60 s. TCP loopback has no peer-credential call on those platforms. The launcher now writes the link into a 0600 page in the gateway home's user-only webapp folder and opens that page, so the browser launcher's command line carries only the page's path and nothing is printed. It still prints the link where it cannot open a browser and on WSL.

Refs #144648 (WA-12)
2026-10-25 23:32:04 -04:00
Teknium bbe207c593 refactor(config): ship the seam with the file backend only
The seam had a selector and reserved members that nothing in this PR
uses: HERMES_CONFIG_BACKEND accepted only `file` (every other value
exited), the .env override existed only to decide when to refuse,
UserLayer.locks/provenance and ConfigBackend.locked() were always empty,
and the supports_file_tooling()/require_file_tooling() checks at ten
file-copy sites were always true. All of it is for the remote backend
(#122509), so it lands there with the code that makes it real.

get_config_backend() now returns the file backend. The env var, its
docs row, the dotenv override, ConfigBackendUnavailable and the
file-tooling gates are gone, with the tests that covered them. The
explicit-file routing test now proves a non-config.yaml path never
consults the backend.

probe_config_readable() calls a probe_readable() protocol method
instead of an isinstance(FileBackend) check, and version_token()
documents how it treats an int-led version.
2026-10-25 18:54:09 -07:00
kshitijk4poor 32ea245ded docs(config): document HERMES_CONFIG_BACKEND; correct the hermes_time fallback comment
- The environment-variable reference had no row for HERMES_CONFIG_BACKEND,
  a selector that stops Hermes at startup when set to anything but
  `file`. Added, with where it is read from and a link to the developer
  guide.
- hermes_time called the config backend module "dependency-free"; its
  file backend imports utils. Say what the fallback actually does.
2026-10-25 18:54:09 -07:00
Teknium f219708926 feat(tts): fold voice search into text_to_speech's ElevenLabs schema (find_voices)
Teknium: the ElevenLabs variant of text_to_speech is where voice search belongs, not a
separate tts_voices tool. The ElevenLabs schema now carries voice_id plus a find_voices
object (text optional there); other providers' schema is byte-identical to main.

Live search findings folded in: the library is the default source and sorts by a year of
usage (most-used first); use_case (e.g. characters_animation) and sort filters; library
voices with a custom credit rate show credit_rate; the description tells the model the
library matches words literally, so a role word that finds nothing ('dwarf') falls back to
describing the sound ('gravelly old' + filters).
2026-10-25 15:58:23 -07:00
Teknium c975831fbc feat(tts): let the agent pick ElevenLabs voices (voice_id + paginated tts_voices search)
With tts.provider: elevenlabs, text_to_speech gains an optional voice_id and a new
tts_voices tool searches the user's account voices (/v2/voices) or the public
Voice Library (/v1/shared-voices) with query/gender/age/accent/language filters and
an opaque next_page cursor. Both are gated on the ElevenLabs provider (dynamic
schema override + check_fn), so every other provider's surface is unchanged. A
per-call voice_id never rewrites config; a stale one sent under another provider is
ignored with a warning.
2026-10-25 15:58:23 -07:00
emozilla bf8e96e233 docs(webapp): say that on Windows nothing checks who spends a launch link
The guides and the launcher's docstring said, or implied, that on Linux and Windows the gateway
checks who redeems a one-use launch link. Only Linux does: on Windows the check returns yes for
every connection, and the link is protected because it travels only in the browser launcher's
command line, which other standard users cannot read. A reader weighing a shared Windows machine
was told the server authenticates the browser when it does not.

The peer check's docstring, the launcher's module docstring, the CLI reference and the Desktop
guide now say what each platform does: Linux checks the connection's user, Windows relies on the
launcher's private command line, and macOS, the BSDs and WSL print the link instead.
2026-10-25 03:22:38 -07:00
emozilla b70215d46a fix(webapp): hermes webapp under WSL prints a launch link the Windows browser can use
Under WSL2 the Windows browser reaches the gateway's loopback port through WSL's localhost relay, and
inside Linux that connection belongs to root. The gateway treated WSL as Linux: it gave hermes webapp
a launch link that only a connection owned by the gateway's user may spend, so every link was
refused, and the page told the user it "was already used or has expired. Run hermes webapp again",
which failed the same way. The loopback Webapp could not be opened from Windows at all.

The connection cannot be tied to the user there (any Windows account can reach the relayed port), so
WSL now takes the macOS path: the link is printed for the user to open by hand and spends without
the peer check. Native Linux keeps the check. Live on this machine's WSL2 (NAT): before, curl.exe from
Windows arrived as uid 0 and got 403; after, the printed link spent with 200.
2026-10-25 03:22:37 -07:00
emozilla e77feea88d fix(webapp): on the LAN, open the address Web Access registered Nous sign-in for
With the Webapp on every interface (`webapp.host: 0.0.0.0`) and no `webapp.public_url`, `hermes
webapp` on the host opened the loopback address. Web Access Start registers Nous sign-in for the
LAN address's callback, so a sign-in started there sent the Portal a callback for 127.0.0.1 that it
had never seen, and failed.

For a launch behind the sign-in gate the gateway now opens, in order: `webapp.public_url` when set,
as before; on the LAN, the address in Start's `webapp/sign-in-registration.json`, while that is
still this machine's LAN address and the Webapp's port (a moved address or port would send the
browser elsewhere); otherwise the loopback address, which still serves a password provider and
sign-in set up by hand for it. Native clients keep the loopback address. The docs say so.
2026-10-25 03:22:32 -07:00
emozilla b140bf4039 fix(webapp): print a one-use link on macOS instead of the long-lived browser credential
Where nothing can check who redeems a launch link (macOS and the BSDs), `hermes webapp` printed the
gateway's browser credential as `#hermes-session=<token>`. That link signed a browser in as the user
until the next sign-out, and when Hermes ran the command through its terminal tool the credential
landed in the transcript.

The gateway now mints a launch ticket there too: the same one-use, 60-second link Linux and Windows
get, which spends without the peer check, as a window ticket does. `hermes webapp` prints it with its
lifetime and still never passes it to a browser launcher, whose arguments other local users can read.
A copy that leaks is spent once the user opens it and dead after 60 seconds, instead of working until
the next sign-out. The docs describe the macOS link as the one-use link it now is.
2026-10-25 03:22:31 -07:00
emozilla 9538b1b040 fix(webapp): end the account tokens of a signed-out browser login on the Webapp too
A browser that signs in to the gated Webapp keeps the sign-in provider's access and refresh token
in its cookies. Only the cookie path checked the login's binding to the browser credential, so
after `hermes webapp --sign-out` those tokens still worked when presented on their own: the access
token as `Authorization: Bearer` (enough to mint a host-terminal ticket) and the refresh token on
`/auth/native/refresh`, where the bundled password provider hands out a new 30-day refresh token
every time. Refusing a recorded list of those tokens would not hold: the password provider decodes
base64 leniently, so another spelling of the same token, such as the quoted value the cookie
stores, verifies too.

On the gateway's Webapp behind the sign-in gate, a provider token now works on its own only when
the listener gave it to a native app's RFC 8252 sign-in (`/auth/native/token`, then each
`/auth/native/refresh`). The listener keeps a digest of each such token until it expires, in
`webapp/native-sign-in-tokens.json` in the gateway home, so native apps stay signed in across a
sign-out and a restart. A browser login's tokens work only as that login's cookies, which
sign-out, or a credential replaced while no gateway ran, already ends. The standalone dashboard
and the gateway's private listener keep main's behaviour. `hermes webapp --sign-out` and the docs
now say that those tokens end and that native apps stay signed in.
2026-10-25 03:22:31 -07:00
emozilla 7e2972f249 fix(webapp): open the Webapp's public URL to sign in when webapp.public_url is set
Behind the sign-in gate, hermes webapp opened the gateway's loopback address even when
webapp.public_url was set. Sign-in started there and kept its state cookie on the loopback
address, but its callback is built on the public URL, so an OAuth sign-in such as the Nous
account's came back to an address without that cookie and failed with "Missing PKCE state
cookie".

A gated launch now opens the listener's own public URL, path prefix kept, with the profile
query after it, so sign-in starts and finishes on the same address. Without a public URL it
still opens the loopback address, and native clients keep dialling loopback. The CLI and
configuration docs say which address is opened.
2026-10-25 03:22:30 -07:00
emozilla ac64150960 docs(webapp): describe sign-out behind the sign-in gate and where launch links work
The Webapp docs said `hermes webapp --sign-out` signs out the tabs a launch link signed in. They
now say it also signs out every browser that signed in with a dashboard account behind the
sign-in gate, closes Bot Desktop viewers with the rest of a tab's connections, reports how many
connections it closed, waits for a gateway that is still starting, and replaces the stored
credential itself only when no gateway runs. The private-link fallback is documented for the BSDs
as well as macOS, and the developer guide records how a Webapp login is bound to the browser
session token (the hermes_webapp_signin cookie).
2026-10-25 03:22:25 -07:00
emozilla fbdf0b0f22 docs(webapp): say what turns the Webapp's sign-in on and what the gateway does around it
The docs said only a 0.0.0.0 or :: host turns on the Webapp's sign-in gate. A public URL does too,
on a loopback host, and `hermes webapp` then opens the Webapp's address instead of a one-use link.
The configuration reference, the Desktop guide, the `hermes webapp` reference and the gateway
sessions guide now name both triggers (webapp.public_url, not dashboard.public_url), say that the
listener native clients use never asks for sign-in, and say that a taken Webapp port replaces the
browser sign-in so open tabs need `hermes webapp` again.
2026-10-25 03:22:24 -07:00
emozilla 7f1e623c71 docs(webapp): sign-in behind the gate, sign-out and the terminal
Documents what hermes webapp does behind the sign-in gate, that sign-out closes open tabs, the
gateway restart after fixing an unavailable Webapp, terminal file drop and the terminal's starting
folder.
2026-10-25 03:22:21 -07:00
emozilla 7979fb2ce3 docs(webapp): document the gateway-served Webapp
Configuration, the hermes webapp command, the Desktop guide's browser
section, and the operator credential in the gateway session notes.
2026-10-25 03:22:17 -07:00
Teknium e3f1dced6b docs: plugin workspaces solve only for the installing platform 2026-10-24 19:27:03 -07:00
akfoster 8607c509f0 fix(pm): avoid delaying available mirrors 2026-10-24 18:47:41 -07:00
akfoster 938be3a6d4 fix(pm): tolerate failed periodic checkpoints 2026-10-24 18:47:41 -07:00
akfoster e5470c9888 feat(pm): preserve progress across interrupted downloads 2026-10-24 18:47:41 -07:00
Teknium ab80e122c0 test(gateway): messaging /refine after the cached agent is gone, warm vs cold
A real gateway with a user-plugin messaging platform and a loopback model:
a resident /refine, then a restart (which drops the cached agent the way
the idle sweep does, without the sweep's one-minute first pass) and a cold
/refine on the same chat. The cold summary must land in that chat and its
review request must equal the resident one (model, provider routing,
session id, prefill, tools). Red on the previous base: "Nothing to refine
yet - send a message first."

Docs: the messaging slash table says /refine works on a chat left idle.
2026-10-24 06:16:10 -07:00
Teknium 14e1e43a23 docs: name each YOLO source's reach; sampling never prompts the user 2026-10-23 16:54:27 -07:00
Teknium aa82d233cf docs: YOLO / approvals.mode off skip the MCP trust prompt, not the spend limit 2026-10-23 16:54:27 -07:00
Teknium ad81947668 docs(mcp): deleting an Always entry leaves the granting chat's copy until it ends 2026-10-23 16:16:43 -07:00
Teknium 3ee9fcfbb5 docs(mcp): what the trust-gate and one-shot consent prompts offer 2026-10-23 16:16:43 -07:00
ethernet be82958af5 fix(nix): the dev shell's HERMES_PYTHON carries its own dependencies
The shell pointed HERMES_PYTHON at the bare pm-pinned interpreter and reached
the uv2nix site-packages only through PYTHONPATH. Every consumer that replaces
PYTHONPATH (Ink's gateway bootstrap, image attachments, run_tests.sh's env -i)
got an interpreter with no dependencies, so 'hermes --tui' in the shell failed
with 'No module named ruamel'.

devVenv re-homes uv2nix's editable venv onto the pinned interpreter: a real
pyvenv.cfg whose home is the lock's python, devPython's site-packages, and
console scripts re-shebanged onto it. HERMES_PYTHON, VIRTUAL_ENV, python,
pytest and pm are now one interpreter and the shell sets no PYTHONPATH.

The shipped package and the shell share one tool list: runtimeDeps takes
ripgrep and ffmpeg from pm/lock.json too. Reverts the run_tests.sh PYTHONPATH
passthrough, which leaked a caller's PYTHONPATH into every HERMES_PYTHON run.
The dev-venv-self-contained check runs the venv under env -i.
2026-10-23 17:20:39 -04:00
Teknium 7152bf009a fix(install): browser opt-out uses the name every PM release accepts
install.sh --skip-browser / --no-playwright and install.ps1 -SkipBrowser
now hand PM `--without agent-browser` again instead of `--without chromium`.

The downloaded installer is the newest script, but by default it installs
the stable tag, whose PM (v0.22.5) rejects `--without chromium` with
"--without accepts only optional default packages (agent-browser,
cua-driver)" and exits 1, failing the whole install. The new PM already
reads `agent-browser` as `chromium` (pm.defaults.RETIRED_DEFAULTS), so the
legacy spelling works against both the stable tag and main. Direct
`hermes pm install --without chromium` stays valid on the new PM.
2026-10-23 01:43:17 -07:00
Teknium 7ba9d256bd docs(browser): browser_cdp and browser_dialog still need a configured CDP endpoint
The tools reference and the browser page said all four browser tools work on
launched and cloud sessions. browser_cdp and browser_dialog are gated on a
static endpoint (_browser_cdp_check: /browser connect, BROWSER_CDP_URL or
browser.cdp_url) and are absent otherwise. The pages (and their zh-Hans
mirrors) say so again; "Requires environment" is back to "CDP endpoint".

Review: https://github.com/NousResearch/hermes-agent/pull/143146#discussion_r4351613180
2026-10-23 01:43:04 -07:00
Teknium 05cf03e982 docs(browser): describe the corrected v52 and Camofox migration rules
engine: auto / headed: false yield to AGENT_BROWSER_*, a relative profile is pinned, unquoted
backend: off gets the notice, and only pre-split Camofox homes (CAMOFOX_URL or cloud_provider) convert.
2026-10-23 01:42:11 -07:00
Teknium 0b69853adf docs(browser): browser_exec is the only browser path; Camofox is a plugin
Rewrite the browser feature page, configuration, tools/toolsets/env-var/pm
references, docker, windows, bot-screen, termux/installation and the secondary
developer-guide/integration/feature pages (EN + zh-Hans): drop agent-browser,
the built-in browser_* tools, browser.backend and /browser use; document
browser.executable_path / browser.user_data_dir / browser.chromium_args and the
AGENT_BROWSER_* migration; point Camofox users to 'hermes plugins install camofox'.
2026-10-23 01:41:25 -07:00
Teknium bf3f1f7159 docs: Quick Setup keeps a model imported from another agent 2026-10-22 22:29:09 -07:00
ethernet e2adc90f82 feat(nix): dev shell runs the pm-pinned tool set
The dev shell took uv, node, ripgrep and ffmpeg from nixpkgs, so it ran
different versions than pm/lock.json ships (uv 0.11.32 vs 0.13.5, node
26.5.0 vs 26.12.1, ffmpeg 8.1.2 vs 9.0.1). Compose its tool set from
nix/pm-packages.nix instead, and wrap the pinned npm onto the pinned node
so `npm` and `node` are one generation.

pm-packages.nix also shipped every artifact nested under its archive's
versioned directory ($out/node-v26.12.1-linux-x64/bin/node), so no consumer
could reach them through PATH; flatten that and link root-level executables
into $out/bin.

git and openssh stay nixpkgs: the lock carries no Linux artifact for either.
2026-10-22 17:25:38 -04:00
ethernet 562c9df251 feat(pm): pm update and pm lock --bump regenerate the installers' bootstrap pins
The curl|sh and irm|iex installers bootstrap uv (and, on Windows, git)
before any checkout exists, so they carry those pins as fragments that
scripts/gen-bootstrap-pins.py derives from pm/lock.json. Both re-pin
paths wrote only the lock: `pm update uv` left the installers on the old
uv, and the bootstrap-installer drift check failed until someone ran the
generator by hand.

Run the generator after either path saves the lock. It keys off the
saved lockfile's own checkout, so a fixture lock outside a checkout
regenerates nothing.
2026-10-22 17:25:38 -04:00
Teknium d7db4d109d refactor: OpenClaw migration leaves core too; first-time setup offers the agent-importers plugin
`hermes claw` (hermes_cli/claw.py) and the openclaw-migration optional skill
moved into the agent-importers plugin (hermes-official-plugins #140/#141), which
keeps `hermes claw migrate|cleanup` as the older spelling of
`hermes import-agent openclaw`. Core drops them with their tests (ported to the
plugin) and the eval leg that loaded the skill's script.

Setup: hermes_cli/setup_agent_import.py replaces setup_migration's OpenClaw
offer. On a first-time `hermes setup` it checks ~/.openclaw (or ~/.clawdbot /
~/.moltbot), ~/.claude, ~/.codex and ~/.cursor; when any is found it asks
"Import your setup from <found>?" (default yes), shows a checklist when more
than one was found, installs agent-importers through the normal catalog install
(or enables it when present), then runs `hermes import-agent <agent>` for each
pick in a child process, which previews and asks first. OpenClaw gets
--migrate-secrets, as core's step did. Nothing found, a no, or
HERMES_NONINTERACTIVE: no prompt, nothing installed. The skip-configured-section
offer now follows any import that changed config.yaml or .env.

LEFT_CORE: `claw` joins the agent-importers row as old_cli, so `hermes claw`
without the plugin names the install. No automatic install for it: an OpenClaw
migration is one-shot and leaves no state that needs the plugin later.

Docs: import guide, OpenClaw guide, cli-commands, quickstart, bundled
cli-reference; locale tips and README pointers.
2026-10-22 11:22:12 -07:00
Teknium 1342ab8553 refactor: move hermes import-agent out of core into the agent-importers plugin
The Claude Code / Codex CLI importer (hermes_cli/agent_import.py,
agent_import_sync.py, the import-agent subparser and its tests) now
ships as the official agent-importers catalog plugin, which also adds
Cursor. The command spelling, flags and the per-profile import-sync.json
manifest are unchanged.

Migration: a LEFT_CORE row (cli=import-agent) makes the old spelling,
run without the plugin, print the install line for the active home.
Only homes with a registered sync source (import-sync.json, which
scheduled --sync runs read) get the plugin installed automatically; a
one-shot import leaves no other trace, so everyone else installs it when
they next need it.

hermes profile create --sync-imports keeps copying import-sync.json (a
plain file at the profile root); it no longer imports the importer.
2026-10-22 11:22:12 -07:00
Teknium d99af4187b refactor: move the Singularity terminal backend out of core into the singularity catalog plugin
The Singularity/Apptainer backend (tools/environments/singularity.py) now ships
as the official 'singularity' plugin in NousResearch/hermes-official-plugins,
registered through the terminal-environment provider seam under the same
backend name and config keys (terminal.backend: singularity,
terminal.singularity_image / TERMINAL_SINGULARITY_IMAGE, terminal.container_*).

- 'singularity' leaves BUILTIN_BACKEND_NAMES so the plugin can register it;
  every hardcoded classification set drops it (the provider declares
  is_remote/is_container/supports_streams instead).
- LEFT_CORE gains a singularity row: homes whose terminal.backend (or .env
  TERMINAL_ENV) is singularity get the catalog plugin once, on hermes update
  or agent/gateway start. An unknown-backend error for 'singularity' names
  the install command (new row field terminal_backend).
- A plugin backend receives its per-task '<backend>_image' override; batch
  runs register one for the active backend.
- BaseEnvironment's sudo-probe knob is renamed _passwordless_sudo_probe_supported:
  plugin backends set it, and the old spelling trips the install scanner.
- Core's scratch-dir disk warning and process-exit sweep were Singularity-only
  and move to the plugin; the singularity setup row, dashboard probe/row and
  config defaults/bridges go too. Docs point at the plugin.
2026-10-22 05:26:10 -07:00
Jeffrey Quesnelle 4e58c721c8 Merge pull request #140121 from Potrock/feat/mcp-events-webhook
feat(mcp): webhook-mode MCP events client (experimental)
2026-10-21 21:39:02 -04:00
Teknium e3a962d087 refactor(mcp): Hermes as an MCP server leaves core for the mcp-serve plugin
`hermes mcp serve` (mcp_serve.py) moves to the official mcp-serve plugin in
hermes-official-plugins, which registers `hermes mcp-serve` and also carries
the `--tools` mode from #83364.

- delete mcp_serve.py and tests/test_mcp_serve.py (the suite moved with it)
- drop the serve subparser, its dispatcher branch, the mcp agent-subcommand
  row and the inline MCP discovery path only `mcp serve` reached
- LEFT_CORE row (command + old_command): `hermes mcp serve` and a bare
  `hermes mcp-serve` without the plugin print the new spelling and the
  install line on stderr. MCP clients live outside Hermes, so no home shows
  the feature in use and nothing installs automatically.
- docs, locale tips and the bundled cli-reference point at the plugin

agent/transports/hermes_tools_mcp_server.py stays: the codex_app_server
runtime launches it as its hermes-tools MCP server.
2026-10-21 17:06:03 -07:00
ethernet 3fa571a51a feat(pm): pm update --skip-target leaves a target's pins alone
The termux pool lags nodejs.org, so one bionic 404 blocked a node bump for
every shipped target even though termux is off by default in release.py.
--skip-target drops the target from resolution; _pin_artifacts already
keeps rows for targets the decision does not cover, so the old pin stays.
2026-10-21 17:13:56 -04:00
Maciej Lisiewski 5aa2f1b56c fix(deps): bump certifi 2026.5.20 → 2026.10.19 (critical, GHSA-6q48-6c7w-9gw2)
certifi 2026.10.19 drops the emSign roots whose intermediate CA keys
were compromised. It was published 2026-10-20, inside the 3-day
`exclude-newer` lock quarantine, and holding a CA revocation for the
quarantine keeps the compromised root trusted for those days.

CA trust stores therefore get the one per-package exemption
(`exclude-newer-package = { certifi = false }`). The packaging contract
test now allows exemptions only for CA-trust packages and only as a
full opt-out, so any other package or a dated exemption still fails.
The pm/AGENTS.md and package-management docs state the exemption.
2026-10-21 20:59:52 +02:00
emozilla a05c6475fd docs(mcp): add the events key to the config reference
The MCP config reference and the MCP guide's config table did not list
events. Both now do, and the reference lists the event utility tools and
says why they are not capability-gated. The guide notes that with lazy: true
or idle_timeout_seconds a subscription can lapse until the next connection
resubscribes it.
2026-10-21 11:08:04 -04:00
Teknium 2fe303419f docs(mcp): tool costs and per-chat spend limits for MCP servers and portable packages
Also keeps a package's declared costs on a same-name native override and logs
which keys were carried.
2026-10-21 04:12:11 -07:00
Teknium f40965b200 fix(desktop): a stale-gateway restart no longer turns the app's restart call into the gateway
Desktop restarts a ready gateway that runs older code (785f1c86a6) with a
bounded, piped `hermes gateway restart` client. With no installed service,
`_cmd_restart` falls back to stop + `run_gateway()` in the FOREGROUND, so the
client itself became the new gateway: a Desktop child that never exits (the
"gateway restart exited" line is never logged), is killed at the 120 s client
timeout, and holds app quit open. install-e2e caught it on Linux HEAD -> NEXT
installer-script legs ("Desktop did not close gracefully", job timeout); the
Models-page "Restart Hermes" goes through the same function. The updater's
recovery restart (update_restart_recovery) runs the same command under a 90 s
captured timeout and kills a service-less gateway the same way.

`hermes gateway restart --detach` starts the fallback's replacement the way
`gateway ensure` starts an absent owner (spawn_unmanaged_gateway) and returns.
Desktop and the recovery restart pass it. Service, external-supervisor and
Windows-task restarts are unchanged, and a person typing the command keeps
today's foreground behaviour. The choice lives in the gateway_supervised_restart
sibling, so the gateway.py facade does not grow.
2026-10-21 00:16:22 -07:00
Mariano Nicolini d1400be1f3 fix(krea): review follow-ups: edits keep their framing, schema follows the stored model, Krea 3 wording 2026-10-20 12:30:50 -07:00
Teknium 9e6360a009 feat(gateway): ask y/N before a lifecycle verb interrupts live sessions
The live-session guard refused outright and needed a flag to proceed. On a
terminal it now lists the live turns, cron jobs and delegations and asks y/N
(default no); -y/--yes skips the question. With no terminal (scripts, cron,
Desktop, the update) it still refuses unless --yes is passed. --interrupt stays
as an alias, so the update recovery and dashboard callers are unchanged.
2026-10-20 06:33:34 -07:00
kassdin 44248a0b39 fix(cli): restore snapshots through an offline gateway handoff 2026-10-20 15:03:19 +05:30
Teknium c0015464f0 Merge pull request #141501 from NousResearch/fix/pkg13-cli-queue
fix(cli): classic CLI /queue goes into the gateway's durable FIFO (#134889 N5)
2026-10-19 12:12:46 -07:00
Teknium d439b578d1 docs(cli): /queue's shared gateway queue, move refusal, lost-answer note
The /queue docs said move acts on the pending queue mid-run; it is
refused for prompts the gateway holds. They now also say that
/queue list|rm|edit|clear act on the session's shared gateway queue
(every window's and automation's queued prompts), that queue-mode Enter
uses the same queue, and that a slash command typed after your own
/queue prompt waits briefly for its turn.

Code notes: what a QueueOutcomeUnknown leaves behind (the turn runs
once but is not painted live here), and why an unknown /queue admission
stays tracked and is re-read once per pending list.

Refs #134889 (N5)
2026-10-19 11:56:22 -07:00
Teknium ced2a39350 feat(plugins): hermes plugins update with no name offers every plugin update
Running `hermes plugins update` without a name now runs the check-updates
probe, lists the plugins the update path can actually move (catalog re-pin,
git pull), names every one it skips and why (pinned, needs fixing, unknown,
pip distributions Hermes never upgrades — #132494), asks once, and updates
each through cmd_update so per-plugin consent prompts still apply. One
failure does not stop the rest; the summary quotes each failure's reason.

Without a terminal nothing moves unless --yes is passed; --yes runs the
updates with interactive=False, so consent stays fail-closed.
2026-10-19 06:07:41 -07:00