Commit Graph

40856 Commits

Author SHA1 Message Date
ethernet
75bbb461d5 Merge branch 'rev/docs' into ethie/pm-clean 2026-09-21 19:52:57 -04:00
ethernet
e4dad098dd docs: python bridge, TLS guard removal, and strict profile config reads
updating.md never said what requires-python >=3.11,<3.15 with every dep
gated on >=3.14 means for users: only 3.14 runs Hermes, the wider range
only lets pre-PM venvs run one more hermes update, and pip/brew installs
on older interpreters get a dependency-less package.

security.md described truststore but not that the startup CA guard,
SSLConfigurationError and HERMES_SKIP_SSL_GUARD are gone, or that the
CA env vars are still read by plain requests/urllib calls.

pm.plugins_state.read_home_selection raises on any unparsable profile
config.yaml and that blocks dependency prep for every home; plugins.md
and profiles.md now say so.
2026-09-21 18:42:52 -04:00
ethernet
e5fc42468e docs: document both Termux APT channels
termux.md only described the canary suite while release_artifacts.py and
the bundled-release workflow publish releases/termux/stable (suite
hermes-stable) for tagged releases. Lead with stable, show how to opt
into canary, and name the channels in the README instead of a bare
"prerelease".
2026-09-21 18:41:25 -04:00
ethernet
b8454c4b93 test: port main's heartbeat test to the platforms() marker
linux_only was retired on this branch; collection refuses the legacy marker.
2026-09-21 18:41:10 -04:00
ethernet
fc0fc20603 docs: drop installer flags install.sh/install.ps1 no longer accept
install.sh rejects --no-skills with "unknown option" (rc=1) and neither
installer has --skip-computer-use / -SkipComputerUse: the installer no
longer pre-installs cua-driver at all. Point the skills page at the setup
prompt / hermes skills opt-out, and describe cua-driver as the PM-pinned
package that hermes computer-use install prepares (it never runs the
upstream installer now).
2026-09-21 18:40:26 -04:00
ethernet
7fee3350be docs: describe pm-owned dependency paths instead of retired modules
google_chat.md still routed --install-deps through tools.lazy_deps and
HERMES_LAZY_INSTALL_TARGET; the plugin calls pm.sync_venv and the Docker
venv is read-only. windows-native.md named hermes_cli/dep_ensure.py and
install.ps1 -Ensure, neither of which exists; features call pm.ensure.
desktop.md and updating.md promised an automatic corrupt-zip retry and
npmmirror fallback for the Electron download; build_prepared_desktop runs
the build once and a failed product aborts the update, so document the
manual recovery (clear the @electron/get cache, set ELECTRON_MIRROR,
rebuild) instead.
2026-09-21 18:39:38 -04:00
ethernet
1f38e868ea docs: register the pm/release developer pages in the sidebar
The five pages moved from docs/ into website/docs/developer-guide were
never added to sidebars.ts, so the site did not link them, and they kept
repo-relative links (../tests/..., ../scripts/..., ../website/docs/...)
that only resolved from the old docs/ location. Register them under a
Packaging & Releases category and point the repo-file links at GitHub;
package-management.md now links the moved completion note in place.
2026-09-21 18:37:43 -04:00
ethernet
fea1f34000 Merge remote-tracking branch 'origin/main' into ethie/pm-clean
# Conflicts:
#	tests/tools/test_code_execution.py
2026-09-21 18:21:37 -04:00
Angello Picasso
66db0a01bb feat(catalog): add jev-curator plugin 2026-09-21 15:20:32 -07:00
ethernet
f999b5ecd2 wip fixin stuff 2026-09-21 18:19:03 -04:00
brooklyn!
5ee87bf9ee fix(desktop): fade status drawer content before folding 2026-09-21 17:18:18 -05:00
simpolism
1ae6f650f9 fix(compaction): invalidate pre-checkpoint usage anchors 2026-09-21 15:09:02 -07:00
teknium1
10659d3536 docs(caching): list every machine-paced source for cache_ttl: auto
The config comment and both docs pages named six of the eight sources in
MACHINE_PACED_SOURCES; "tool" and "batch" were missing, so an operator
reading the docs could not predict the tier those sessions get.
2026-09-21 15:07:39 -07:00
teknium1
23301d705c feat(caching): prompt_caching.cache_ttl: auto picks the 1h tier for human-paced sessions, 5m for machine-paced ones
The 1h Anthropic cache tier writes at 2x base (5m: 1.25x) and only pays off when
turns are more than five minutes apart. That is exactly the shape of an interactive
session a person parks and resumes, and exactly not the shape of a subagent, cron
run, one-shot or webhook that calls every few seconds and is gone. A single global
`cache_ttl` cannot be right for both, so operators leave it on 5m and pay a full
context re-write every time they come back to a CLI session after a coffee.

Measured on one install (2 days of per-call API logs, Claude via the Nous route):
63% of interactive cache-write tokens were cold re-writes after a 5-60 minute idle
gap; 1h would cut interactive write cost ~42% while costing ~49% more on subagents
and ~23% more on cron. `auto` resolves once per session from the session source
(`_session_source_for_agent`): 1h for cli/tui/desktop/messaging platforms, 5m for
subagent, cron, oneshot, webhook, kanban, api. Auxiliary/stub calls keep 5m; the
delegate_tool child clamp (#104168) still applies. Default stays "5m".
2026-09-21 15:07:39 -07:00
teknium1
edff33853a chore(terminal): diet the heartbeat schema description
Every tool schema rides every API call; the first draft read like docs (111 est. tokens).
Kept the two facts the model needs — when to use it and what it delivers — the rest lives in
tools-reference.md.
2026-09-21 15:02:49 -07:00
teknium1
9acd0d33b6 fix(code_execution): heartbeat is a background-only terminal modifier, blocked in the sandbox
The execute_code sandbox refuses background/notify modifiers on terminal(); heartbeat implies
notify and rides the same delivery path, so it joins the blocked set (and the stub-drift test's
mirror of it).
2026-09-21 15:02:49 -07:00
teknium1
65b0ff38ea feat(terminal): heartbeat notifications for long background processes
`terminal(background=true, heartbeat=N)` emits a `heartbeat` event every N seconds
(floor 60) carrying only the output produced since the previous one, plus the usual
completion notice. The agent stays current on a long bounded job (merge train, full
test suite, deploy) and reacts to a failure within N seconds instead of at exit.

Why: `notify=true` fires once at exit, so multi-hour merge trains ran silently — the
parent's prompt cache went cold and every "what's up" cost 5–10 rediscovery calls;
30 days of batch sessions show 4,930 hand status polls (14% of all tool calls).
`notify=[pattern]` cannot serve this: its lifetime cap (8) exists precisely to stop
periodic output from flooding the agent.

Mechanism: one daemon timer thread for every heartbeat session (reader threads block
on the pipe and cannot keep time); delta output via a total-ingested counter over the
rolling buffer; heartbeats only where the completion notice can be delivered (same
async-support/subagent gates), never after exit. `heartbeat_seconds` is checkpointed.
Rendered on CLI, gateway and TUI through the existing process-notification paths.
2026-09-21 15:02:49 -07:00
ethernet
fc4b1958dc Merge remote-tracking branch 'origin/main' into ethie/pm-clean 2026-09-21 17:55:47 -04:00
hermes-seaeye[bot]
87ff1c2f77 fmt(js): npm run fix on merge (#118563)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-21 21:54:36 +00:00
ethernet
00a9dbc60b fix(desktop): eslint import order + padding after the origin/main merge
The merge landed main's `minimize-to-tray` and `hud-modifier-types` modules next to
ours, leaving two `perfectionist/sort-imports` errors — the only blocking failures in
the `JS & TS checks` job (`apps/desktop :: check:lint`):

  electron/main.ts:321      ./minimize-to-tray before ./native-auth-decisions
  src/global.d.ts:6         ../electron/hud-modifier-types before ../electron/machine-profile

Resolved with the workspace's own `npm run fix` (eslint --fix + prettier), which also
pads the `padding-line-between-statements` warnings it can. Lint is 0 errors after.
2026-09-21 17:50:44 -04:00
brooklyn!
5d3f84c0dd fix(models): regenerate the stale catalog blocking CI 2026-09-21 16:47:50 -05:00
brooklyn!
7ff69689d0 fix(desktop): distinguish HUD helper failures and explain tray closing 2026-09-21 16:47:50 -05:00
brooklyn!
b7fdf2d504 fix(desktop): hide the main window on Close while tray mode is enabled 2026-09-21 16:47:50 -05:00
brooklyn!
d0381cea91 fix(desktop): build and verify the Windows HUD helper without an SDK 2026-09-21 16:47:50 -05:00
ethernet
14b3232cbd fix(test-runner): key the scratch root by user, not a shared literal
The runner's per-run temp roots live under a fixed `/var/tmp/hermes-pytest`, chosen for
real reasons (disk-backed, not hidden, short enough for AF_UNIX sun_path). But a fixed
literal in a world-writable sticky dir belongs to whoever creates it first: a root-owned
root — a container or system-service run — makes every later `makedirs`/`mkdtemp` there
fail with EPERM for every other user on the host, with no way back that does not need
root. That is exactly what happened on luna: /var/tmp/hermes-pytest is root:root 755, so
every local suite run by the login user died at `runner crashed: PermissionError(13)`
before collecting a single test.

Key the name by uid (with the same non-/var/tmp fallback), so no run can be blocked by
another user's leftovers. Invariant test: two uids never share a scratch root, and the
root is created under the expected parent.
2026-09-21 17:24:29 -04:00
ethernet
05609d2092 merge: origin/main (19 commits) into ethie/pm-clean
Conflicts, all inside the local-runtime / local-models subsystem:

- hermes_cli/local_runtime/binaries.py, hermes_cli/web_routers/local_models.py:
  main's own transfer machinery (urllib ranged download, shutil.move publish) is
  retired here — pm/downloader owns every fetch. Took ours.
- tests/hermes_cli/test_local_runtime_downloads.py: deleted here (its subject,
  binaries._download, is gone); kept deleted.
- tests/hermes_cli/test_local_models_routes.py: ours (the pause/resume suite) plus
  main's held-finished-file contract, re-seamed onto the pm downloader.

main's fix 515412f415 ("wait out a held finished download instead of copying it and
failing") is re-homed so it fits the PM model: the Windows rename that fails while an
antivirus or indexing scan still holds a just-closed multi-gigabyte file is now handled
once, in pm/downloader.replace_when_released, which is the single publish path for PM
archives and model files alike. A cleanup that cannot remove its leftover can no longer
mask the error that left it.

Tests: helper retries a transient refusal and lands the file; gives up with the
plain-language message chained to the OS error; a download publishes through two refused
renames with nothing left behind; a stuck hold reports the rename error, not the failed
cleanup. Route-level: the job lands the file and reports done.
2026-09-21 17:24:14 -04:00
ethernet
acb82a62d0 fix some bundle issues 2026-09-21 16:45:34 -04:00
Jeffrey Quesnelle
7b3c7aef31 Merge pull request #117926 from NousResearch/fix/local-model-download-rename
Local models: wait out a held finished download instead of copying it and failing
2026-09-21 16:40:12 -04:00
kshitijk4poor
4a75fad06a fix(website): keep the compact selects from overrunning their column
At 601px the select columns were squeezed to 89/103/113px while the selects
are floored at 120px, so each control overran its neighbour (row scrollWidth
603 vs 569 clientWidth). Hold the same floor on the column, letting the
search field absorb the shrink instead.

The plugins panel had the same viewport-drift the drawer had: leaving the
mobile band left `filtersOpen` true, so `aria-expanded` stayed "true" on the
hidden toggle. Reset it from the same media query.
2026-09-22 02:02:30 +05:30
kshitijk4poor
6c91f1b8ba chore(website): drop the unreachable Categories toggle and dead control CSS
The new compact controls hid `.sidebarToggle` at every width — the 1024px
block's `.layout > .sidebarToggle` rule outranks the later 900px
`display: flex` — so its button, `activeCatBadge` and three CSS blocks were
unreachable, and the drawer's `onKeyDown` was shadowed by the focus trap's
capture-phase listener. Delete them.

Also drop declarations that cannot paint under `display: contents`
(`padding`/`border-bottom`/`backdrop-filter`/`background !important` on
`.controlsBar` at <=600px), the redundant `.compactSort` hide (its parent is
already hidden), and the empty effect left over on the plugins page.

`.filterPanel.filterPanelOpen` keeps the open panel working regardless of
source order instead of relying on the 600px block coming last.
2026-09-22 02:02:30 +05:30
kshitijk4poor
c125b005a6 fix(website): stop the filters panel from jumping the page
Tapping Filters scrolled 391px even when the panel was already on screen,
because the handler called `scrollIntoView({ block: "start" })` on every
open. Reveal it from an effect instead, with `block: "nearest"`, and keep the
click handler a plain state toggle (the cancelled rAF no longer rides along
on the handler).
2026-09-22 02:02:30 +05:30
kshitijk4poor
e2ee6c7be3 fix(website): drop the drawer state when the viewport leaves mobile
Opening the filters drawer at <=600px and then resizing to a wider viewport
left `sidebarOpen` true: the hidden toggle kept `aria-expanded="true"`, and
coming back to mobile silently reopened the drawer and re-locked body scroll.

Reset it in the matchMedia sync, and name the query constant so it stays in
step with the `max-width: 600px` CSS blocks it mirrors.
2026-09-22 02:02:30 +05:30
kshitijk4poor
e4b05b0ef5 fix(website): keep the compact bar pinned inside the picker embed
`?embed=picker` hides the navbar and pins the controls bar to the frame top,
but that override still names `.controlsBar` — which is `display: contents`
at <=600px, so the sticky element (`.controlsTopRow`) kept its 60px navbar
offset and left a dead 60px gap with cards sliding under it. Extend the
override to the row, and add the same rule to the skills page, which had no
picker offset at all.
2026-09-22 02:02:30 +05:30
kshitijk4poor
c846b2a4e7 fix(website): give compact filter selects room for their own value
Between 601px and ~870px the compact selects were squeezed to as little as
13px of text area (SOURCE needed 64px), so the control displayed no
readable value while the pills it replaced were hidden — the band had no
way to see the active filter.

Floor the selects at 7.5rem, let the search field shrink to 8rem instead of
12rem, and drop the uppercase labels below 820px where they leave no room.
2026-09-22 02:02:30 +05:30
kshitijk4poor
bf84ba4a24 fix(website): keep the compact directory bar legible in light theme
The new sticky control bar hardcoded the dark surface
(`rgba(7, 7, 13, 0.94)` plus gold borders and a gold-on-gold count badge),
but the site respects `prefers-color-scheme`, so light-mode users got dark
text on a near-black bar: the Filters label measured 1.00 contrast (1.5 by
pixel sample) and the skills search input dropped from 3.34 to 1.12.

Use the theme tokens instead — `--ifm-navbar-background-color` and
`--ifm-hr-border-color` resolve to the previous dark values exactly — and
scope the gold gem/border accents to the dark theme, with
`--ifm-color-emphasis-*` for light mode.
2026-09-22 02:02:30 +05:30
unsupportedpastels
df3e62457b fix(website): compact plugin and skill directory headers
(cherry picked from commit 38ef7b7784e8561f04105fcd0fd7d30bbea6674c)
2026-09-22 02:02:30 +05:30
rob-maron
0f9fc3434e add xiaomi mimo v2.6 2026-09-21 13:28:28 -07:00
teknium1
e7c5141f1c chore(contributors): map robchristiansen13 noreply email 2026-09-21 13:14:22 -07:00
teknium1
977a4f7265 test(mcp): fold the constraint-fragment tests into two invariants
One test pins the contract (if/then/else + oneOf/not fragments survive
normalization and validate with the intended semantics, using the NBX
set_effects shape from #107141), one pins the guard (root and declared
nested objects still get the #4651 dangling-required repair).
2026-09-21 13:14:22 -07:00
chelsealong
dc0915ce35 fix(moonshot): stop stamping a synthetic type on if/then/else nodes
_repair_schema didn't recurse into if/then/else, so a bare conditional
wrapper (e.g. an allOf branch expressing "when goal is set, mode must be
one of ...") fell through _fill_missing_type's default and was stamped
with type: "string". That corrupts the schema: the wrapper's actual
instance is an object, so Moonshot (and any strict validator) now
rejects every real argument against it.

if/then/else are added to the recursed node keys, and _fill_missing_type
leaves a bare conditional node untyped instead of defaulting to "string"
since it constrains the parent instance rather than describing its own
shape.
2026-09-21 13:14:22 -07:00
Rob Christiansen
070c7cf00a fix(mcp): keep required-only constraint fragments in tool schemas
_repair_object_shape() treated every dict carrying `required` as an object
declaration. A constraint fragment — {"required": ["chain"]} inside an
allOf/oneOf/anyOf/if branch, with no properties and no type — is not one.
Repairing it synthesised `properties: {}` and then pruned every name out of
`required`, so sibling branches collapsed into identical always-true schemas
and the enclosing oneOf had two matches: the tool appeared in the catalog and
every call failed validation.

Only the parameters-schema root still receives the dangling-`required` repair,
which is the single node handed to providers as the argument object.
2026-09-21 13:14:22 -07:00
brooklyn!
fca3221df4 fix(desktop): give HUD gestures their own keybindings page 2026-09-21 14:42:45 -05:00
brooklyn!
d00c951523 fix(desktop): remove persistent HUD gesture status chrome 2026-09-21 14:42:45 -05:00
ethernet
4efb36f81e merge: integrate upstream desktop features through PM preparation
Merge origin/main at 8e806ae1b2. Keep native helper compilation in
prepareDesktopNativeDependencies and keep bundling/beforePack consume-only.
Bind helper sources and headers into preparation identities and cache keys;
copy admitted executable resources beside node_modules and preserve signing
semantics in product freshness checks.

Verified desktop typecheck, focused native/packaging/UI and gateway/cache
tests, and the real Linux preparation/copy/Xvfb execution path. Incoming
upstream anti-slop findings remain unchanged; no baseline was raised.
2026-09-21 15:17:44 -04:00
686f6c61
1a90fad0f5 fix(gateway): retain partial answers after returned errors
Carry the partial-answer flag on failed completion frames and retain a replay body when no text deltas arrived. Preserve streamed segments and keep error-only, successful, and interrupted results out of this path.

Adapted from https://github.com/NousResearch/hermes-agent/pull/76112. The OpenCode terminal-stream reproductions in https://github.com/NousResearch/hermes-agent/pull/85724 are covered by existing routing and usage handling; leave those safeguards unchanged.

Co-authored-by: Jeffgithub0029 <gxalong@gmail.com>
Co-authored-by: brooklyn! <brooklyn.bb.nicholson@gmail.com>
2026-09-21 13:58:56 -05:00
hermes-seaeye[bot]
d82832eb3d fmt(js): npm run fix on merge (#118451)
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-09-21 18:51:47 +00:00
ethernet
e34c0316a2 fix(api): queue terminal events after worker commentary 2026-09-21 14:50:22 -04:00
ethernet
980a70dd74 test(install-e2e): navigate historical updates and permit unattended quit 2026-09-21 14:49:33 -04:00
ethernet
b265e87678 test: synchronize observable state and reuse prepared PM fixtures 2026-09-21 14:49:05 -04:00
ethernet
b22c8add14 fix(pm): stream bootstrap output on Windows Python 3.11 2026-09-21 14:49:05 -04:00