Commit graph

1293 commits

Author SHA1 Message Date
Teknium
d0dcb9a5fd
fix(update): consolidate pre-update backups into one gated mechanism (#65754)
hermes update ran TWO separate pre-update backup mechanisms: the
config-gated full zip (updates.pre_update_backup, default off) and an
unconditional quick state snapshot added for #15733 that ignored the
user's setting entirely. On a large state.db (observed: 24 GB) the
'cheap' snapshot silently added ~60s to every update and ate 24 GB of
disk in state-snapshots/.

Now there is ONE mechanism, gated by updates.pre_update_backup with
three modes:

- quick (new default): state snapshot of critical small files (pairing
  JSONs, cron jobs, config, auth, per-profile DBs). Files over 1 GiB
  are skipped with a warning so a bloated state.db can never stall the
  update again.
- full: the quick snapshot plus the HERMES_HOME zip (old 'true'
  behavior; --backup forces it for one run).
- off: nothing runs — an explicit opt-out now disables the quick
  snapshot too (--no-backup does the same per-run).

Legacy booleans are honored: true -> full, false -> off.

_run_pre_update_backup() now returns the quick-snapshot id so the
post-update cron-jobs restore safety net (#34600) keeps working; the
snapshot moved from the post-fetch site to the pre-mutation site,
which also covers the zip-fallback update path it previously missed.
2026-07-16 08:47:25 -07:00
Christopher
dd9e75335c fix(gateway): skip port-conflicting multiplex profiles 2026-07-16 07:17:55 -07:00
Teknium
75c878217d fix(moa): route per-slot reasoning effort through the canonical parser
_clean_reasoning_effort kept its own whitelist that stopped at 'max',
silently dropping 'ultra' from MoA slot configs. Route it through
hermes_constants.parse_reasoning_effort — the same one-source-of-truth
fix the salvaged commit applies to the gateway — so future effort
levels can't drift here either. Docs updated to list ultra.

Follow-up to salvaged PR #64012.
2026-07-16 06:14:58 -07:00
teknium1
261b0f8240 docs(mcp): document redirect_uri proxied callbacks + redirect_host WAF workaround
Adds the proxied-callback option to the remote/headless OAuth section,
links the mcp-oauth-remote-gateway skill for fully headless gateways,
and documents the WAF pitfall behind redirect_host.
2026-07-16 06:14:34 -07:00
nima20002000
53adb3fd97 feat(config): add get and unset commands 2026-07-16 05:44:43 -07:00
embwl0x
bfb51fec81 docs(gateway): document external restart contract 2026-07-16 05:08:56 -07:00
embwl0x
caf5f27e30 fix(gateway): preserve external supervisor ownership 2026-07-16 05:08:56 -07:00
kocaemre
681852a5b9 docs: address audit review feedback 2026-07-16 04:47:40 -07:00
Teknium
176a98c39a docs: refresh salvaged audit fixes against current main
PR #36051's values went stale since May 31: session-store SCHEMA_VERSION
is now 21 (PR said 14), and the dashboard ships 8 built-in themes
(PR said 7). Also document the v16/v18/v20 data migrations added since.
2026-07-16 04:47:40 -07:00
kocaemre
a710becd6c docs: fix 25 documentation/code inconsistencies (audit round 3)
Cross-checked website/docs against the source at main HEAD and corrected
documented commands, env vars, config keys, headers, and default values
that don't match the code. Docs-only; no behavioral changes.

Refs #36048

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-07-16 04:47:40 -07:00
Marcelo
1a323d608e feat: add LM Studio JIT load mode 2026-07-16 15:23:14 +05:30
teknium1
5f171e36ab chore(skills/mcp-oauth-remote-gateway): move to optional-skills + modernize
- Move skills/mcp/ -> optional-skills/mcp/ (niche remote-deployment
  workflow; bundled tier is for daily-driver skills)
- Frontmatter: description 421 -> 57 chars, add platforms gating
  [linux, macos] (bash pipelines + gateway hosts), credit Ben Barclay
  first in author
- Document the built-in flow's own escape hatches (paste-back prompt,
  ssh -N -L port-forward) as cheap first fallbacks before manual
  token surgery; scope the skill to no-TTY messaging-gateway contexts
- Frame execution through the terminal / execute_code tools
- Tests: tests/skills/test_mcp_oauth_remote_gateway_skill.py covers
  all four diagnostic branches, atomic --write persistence, 0600
  perms, httpx UA on the wire, no-secrets-in-stdout, and frontmatter
  invariants (9 passing)
- Regen auto-gen docs page + one-line catalog row + sidebar entry
  (scoped; unrelated generator drift reverted)
2026-07-16 01:28:32 -07:00
kshitijk4poor
92876effe2 fix(webhook): make dual-stack bind exclusive
Disable address reuse so an existing family-specific listener cannot silently split traffic with the webhook server. Normalize wildcard bind hosts for local CLI URLs and align setup documentation with the dual-stack default.
2026-07-16 12:36:51 +05:30
Teknium
b6c11a35ac refactor(skills): adapt salvaged references to the MCP-tool surface, bump to 2.1.0
Follow-up on kshitijk4poor's cherry-picked references:
- pitfalls.md rewritten from the raw-socket blender_exec() frame to the
  MCP-tool frame (dropped 'MCP server is optional, talk to the socket
  directly' — now the anti-pattern; dropped TCP-helper internals items;
  kept all bpy/addon knowledge: empty code results in 5.x, temp-file
  readback, ops-vs-data context, engine names by version, GPU setup)
- recipes.md: blender_exec -> execute_blender_code in the agent-side
  verification snippet
- SKILL.md: reference-file table added to Quick Reference, version
  2.1.0, kshitijk4poor added to authors
- docs page regenerated (scoped to this skill)
2026-07-15 12:28:13 -07:00
Teknium
bd7e480236
fix(compression): give fallback candidates their own timeout budget + escalate repeat-timeout cooldowns (#65143)
Fixes #62452. Two amplifiers turned one slow auxiliary route into a
per-turn multi-minute stall:

1. Fallback candidates inherited the exact effective_timeout the primary
   was called with. When the primary's deadline was short (tuned or
   already burned), an independently healthy fallback died on the same
   clock — the reporter's 163k-token compression needed ~90s on the
   fallback and got the primary's 30s, every turn. fallback_chain
   entries may now declare their own 'timeout' (seconds); both fallback
   candidate call sites (sync + async) resolve it via
   _fallback_entry_timeout, label-scoped so only configured-chain
   candidates are affected. No entry timeout → task-level timeout,
   preserving existing behavior.

2. A session whose transcript structurally cannot be summarized within
   the deadline re-attempted every 60s, re-burning the full timeout on
   every subsequent turn. Consecutive timeout-class failures now
   escalate the cooldown 60s → 300s → 900s (capped); any successful
   summary or session reset clears the streak. Timeout classification
   takes precedence over the streaming-closed 30s rung ('timed out'
   also matches _is_connection_error) and now recognizes the SDK's
   'Request timed out.' phrasing.

Fail-safe behavior is unchanged: all messages are preserved when every
candidate fails; the cooldown only spaces out retries.
2026-07-15 12:28:09 -07:00
Teknium
647520f83e fix(gateway): gate profile routing on multiplex_profiles + widen batch-key routing to all adapters
Follow-ups on the salvaged #20096 profile-routing feature:

- _profile_name_for_source now returns None unless gateway.multiplex_profiles
  is on. Routing stamps source.profile, which namespaces session/batch keys,
  but the profile-scoped agent run only activates under multiplexing — without
  the gate, configured routes with multiplexing off split batch/session keys
  into agent:<profile> while the agent still ran from agent:main.
- Widen the profile-aware _text_batch_key fix from Discord to every adapter
  that builds batch keys via build_session_key (telegram, whatsapp, matrix,
  feishu, wecom, weixin) — routing is platform-generic, so the batch-key
  namespace fix must be too.
- Downgrade the no-route-matched log from INFO to DEBUG (fired on every
  unrouted inbound message).
- GatewayConfig.to_dict(): serialize profile_routes as plain dicts
  (ProfileRoute dataclasses are not JSON-safe).
- Docs: correct the 'independent of multiplexing' claim in
  docs/profile-routing.md (routing requires multiplexing), fix the
  platform-only specificity row (0, not 1), and document profile_routes in
  website/docs/user-guide/multi-profile-gateways.md.
- Tests: pin the multiplex gate (routes ignored when off, active when on,
  build_source end-to-end stays in agent:main when off).
2026-07-15 09:50:05 -07:00
Teknium
6efec39ecf
refactor(skills): rework blender-mcp skill around the catalog MCP entry (#65066)
The optional blender-mcp skill predates the blender MCP catalog entry
(#64463) and taught the agent to hand-roll raw TCP JSON to the addon's
socket on port 9876 from execute_code — bypassing the catalog's version
pinning and install-time tool curation.

Reworked to v2.0.0 as the companion skill for the catalog entry:
- prerequisites now go through 'hermes mcp install blender'
- interaction surface is the four curated MCP tools, not a raw socket
- keeps the valuable content: addon setup, bpy recipes (materials,
  keyframes, render-to-file), pitfalls (timeouts, absolute paths,
  object mode), plus new pitfalls (xvfb headless, no-sandbox warning,
  remote-host path resolution)
- explicit anti-pattern note: do not hand-roll TCP to 9876
- description shortened to <=60 chars per skill authoring standards

alireza78a's original bpy patterns and pitfalls are preserved and
credited. Docs page regenerated via generate-skill-docs.py (scoped to
this skill only; unrelated generator drift left untouched).
2026-07-15 09:49:42 -07:00
LeonSGP43
08015c3a8f fix(gateway): suppress hidden-only incomplete codex turns 2026-07-15 09:48:24 -07:00
Teknium
b34e565957 feat(models): catalog-labeled silent default — GLM-5.2 marked "default": true in the model catalog
The remote model catalog (website/static/api/model-catalog.json) now labels
exactly one entry per provider block with "default": true — z-ai/glm-5.2 for
both OpenRouter and Nous Portal. That labeled entry is the model Hermes
silently lands on when the user never picked one, and it can be rotated by
editing the manifest alone: no release needed.

- model_catalog.py: get_default_model_from_cache() reads the label from the
  in-process/disk cache only — never triggers a network fetch, so hot
  resolution paths (agent build, gateway session setup) stay network-free.
- models.py: get_preferred_silent_default_model() resolves catalog label
  first, PREFERRED_SILENT_DEFAULT_MODEL constant second (offline/fresh
  install). _PROVIDER_SILENT_DEFAULT_OVERRIDES dict replaced by
  _SILENT_DEFAULT_PROVIDERS routing through the shared resolver.
  fetch_openrouter_models() preserves the "default" badge through live
  /v1/models refreshes so the picker shows it.
- scripts/build_model_catalog.py: generator emits the default label so
  regeneration can't drop it.
- website/docs/reference/model-catalog.md: schema documents the new field.
- Salvaged from PR #61141 (@HumphreySun98): bare-provider /model switches
  (/model nous) route through the cost-safe default instead of curated
  entry [0].
- tests: catalog-label precedence, constant fallback, stale-label fallback,
  cache-only (no network) guarantee, and a shipped-manifest contract test
  pinning the labeled entry to PREFERRED_SILENT_DEFAULT_MODEL.

E2E (temp HERMES_HOME): fresh-install constant fallback, shipped-manifest
label read, release-free rotation (relabeled cache -> new default across
models.py, tui_gateway, and gateway empty-model paths) all verified.
2026-07-15 00:10:31 -07:00
Teknium
0bb3a82c53 refactor(moa): drop auxiliary-task reasoning knob in favor of per-slot preset config
The just-merged auxiliary.<task>.reasoning_effort shorthand applied
ensemble-wide to MoA (one value for every advisor) — wrong granularity.
Per-slot preset config supersedes it:

  moa:
    presets:
      deep_review:
        reference_models:
          - {provider: ..., model: ..., reasoning_effort: low}
          - {provider: ..., model: ..., reasoning_effort: xhigh}
        aggregator:
          {provider: ..., model: ..., reasoning_effort: high}

- Remove reasoning_effort from the moa_reference/moa_aggregator
  DEFAULT_CONFIG blocks; _get_task_extra_body now warns-and-ignores the
  key on MoA tasks, pointing at the preset config
- Guard tests: MoA aux blocks must not regrow the key; task-level value
  is rejected with the pointer warning
- Docs: configuration.md notes the MoA exception and links the MoA page
2026-07-14 21:08:22 -07:00
Justin Schille
3dca75b45c feat(moa): support per-slot reasoning effort 2026-07-14 21:08:22 -07:00
Teknium
df5700ebe3
feat(auxiliary): per-task reasoning_effort for auxiliary models (#64597)
Every auxiliary task block (vision, web_extract, compression,
title_generation, curator, background_review, moa_reference, ...) now
accepts a reasoning_effort shorthand:

  auxiliary:
    compression:
      reasoning_effort: low
    vision:
      reasoning_effort: none

_get_task_extra_body() folds it into extra_body.reasoning, which every
auxiliary wire already translates: chat.completions passes it through,
the Codex Responses adapter maps it to top-level reasoning/include, and
the Anthropic auxiliary adapter now forwards it into
build_anthropic_kwargs(reasoning_config=...) (previously hardcoded None).

An explicit extra_body.reasoning on the same task wins over the
shorthand. Invalid levels are ignored with a warning. Empty string
(the shipped default) is a no-op — zero behavior change.

Config: reasoning_effort added to all 16 auxiliary task blocks in
DEFAULT_CONFIG (no version bump — deep-merge handles new keys).
2026-07-14 14:07:43 -07:00
kshitijk4poor
4554fe128a fix(slack): complete agent view workspace routing 2026-07-14 13:58:36 -07:00
ScotterMonk
d9cdb81923 feat(config): support per-model reasoning_effort overrides
Add agent.reasoning_overrides dict to config.yaml. Users can now set
a reasoning_effort per model, overriding the global agent.reasoning_effort.

Example:
  agent:
    reasoning_effort: "medium"       # global default
    reasoning_overrides:
      "openrouter/anthropic/claude-opus-4.5": "xhigh"
      "openai/gpt-5": "low"
      "claude-sonnet-4.6": "high"    # bare model name also works

The helper is spelling-tolerant: override keys match regardless of
provider prefix or dots-vs-dashes normalization, so users can write
keys in any sensible form and they'll match.

Resolution priority:
1. Session-scoped /reasoning --session override (gateway only; unchanged)
2. Per-model override from agent.reasoning_overrides (spelling-tolerant)
3. Global agent.reasoning_effort (existing)
4. Provider default (unchanged)

Wired into:
- CLI startup (cli.py)
- Messaging gateway agent construction (gateway/run.py)
- Desktop/TUI _load_reasoning_config (tui_gateway/server.py)
- Cron job scheduler (cron/scheduler.py)
- /model mid-session switch (agent/agent_runtime_helpers.py)
  + _primary_runtime now tracks reasoning_config for correct fallback recovery
- Fallback activation (agent/chat_completion_helpers.py::try_activate_fallback)
  + Re-resolves reasoning_config for the fallback model (best-effort)

Closes #21256 (per-model reasoning_effort defaults).

Note: no hermes config set agent.reasoning_overrides.<model> support;
users edit the YAML directly. _set_nested splits on "." and would
corrupt model keys containing version dots.
2026-07-14 11:46:40 -07:00
kshitijk4poor
33dfb7e4ec docs: add Upstage Solar to provider docs (env vars, fallback table, --provider list) 2026-07-15 00:09:24 +05:30
HexLab98
55d826ccef fix(file-safety): distinguish safe-root write denial from credential blocks
Return actionable errors when HERMES_WRITE_SAFE_ROOT blocks a path instead of
labeling every denial as a protected credential file. Wire the helper through
write_file, patch, delete/move, and the Copilot ACP shim; sync docs examples.
2026-07-14 17:09:40 +05:30
HexLab98
1b5ceec2a0 docs: clarify write safety, HERMES_WRITE_SAFE_ROOT, and file-mutation verifier
Document that safe-root violations are hard-blocked (not approval-gated),
add a security guide section for write_file/patch guards, and link cron
and verifier docs so users trust the footer over agent summaries.
2026-07-14 17:09:40 +05:30
kshitijk4poor
52cafa6f8e follow-up: integrate agent nudge + dispatcher retry docs and tests
- Nudge text now warns that repeated protocol violations will block the
  task and require manual intervention, so the model understands the
  consequence of ignoring the nudge.
- Kanban docs restructured to clearly separate the two defense layers:
  agent-side prevention (nudge, from #64350) and dispatcher-side
  recovery (bounded retry, from this PR).
- Two new integration tests verifying the nudge mentions blocking and
  that the agent-side and dispatcher-side budgets are independent.
2026-07-14 16:47:33 +05:30
slow4cyl
3cd8feb63c docs(kanban): worker-lifecycle + events table reflect the bounded protocol-violation retry
Fold in kevinb361's suggested lifecycle wording (#61817 conceded in favor of
this PR) and update the second stale site his sweep didn't cover: the
task-events table still said the dispatcher 'auto-blocks immediately instead
of retrying'. Both now describe the violation-only streak: protocol_violation
fires on every violation (its payload marker feeds the budget), below-budget
runs return the task to ready, and gave_up + auto-block happen only when the
consecutive streak reaches _PROTOCOL_VIOLATION_FAILURE_LIMIT (default 3,
per-task max_retries overriding).
2026-07-14 16:47:33 +05:30
Teknium
89bd0fba90
feat(codex): redeem banked usage-limit resets via /usage reset (#64280)
OpenAI lets ChatGPT-plan Codex users bank rate-limit reset credits, but
until now they could only be redeemed from the Codex CLI/app or the
website. This wires the same backend API into Hermes:

- /usage on the openai-codex provider now shows "You have N resets
  banked - use /usage reset to activate" (parsed from the
  rate_limit_reset_credits field the /usage endpoint already returns).
- New /usage reset subcommand (CLI + gateway) redeems one banked
  credit via POST .../rate-limit-reset-credits/consume with a UUID
  idempotency key, mirroring codex-rs backend-client semantics
  (PathStyle /wham vs /api/codex, ChatGPT-Account-Id header,
  reset/nothing_to_reset/no_credit/already_redeemed outcomes).
- Guard: redemption is refused while no rate-limit window is fully
  exhausted, since a banked reset restores the FULL 5h + weekly
  allowance and spending it early wastes it. /usage reset --force
  overrides. Zero banked credits and non-codex providers are refused
  with clear messages; nothing_to_reset reports the credit was NOT
  spent.
- i18n: new gateway.usage.unknown_subcommand / reset_wrong_provider
  keys across all 16 locales; docs updated (cli.md, messaging index).

Tested with unit tests plus a real-socket E2E against a local fake
Codex backend exercising redeem/guard/force and the /usage hint.
2026-07-14 03:23:19 -07:00
teknium1
af250d8494 docs(delegation): clarify background lifetime 2026-07-13 07:28:21 -07:00
teknium1
d0e9a42cec fix(delegation): harden durable completion delivery 2026-07-13 07:28:21 -07:00
hellno
b03c94dbed fix(approval): emit observer hooks for smart verdicts 2026-07-13 02:00:09 -07:00
Teknium
8030b01a2a fix(kanban): harden durable artifact handoff 2026-07-12 23:09:41 -07:00
Teknium
7c19eb80a8 docs(dashboard): align approval mode guidance 2026-07-12 17:42:42 -07:00
teknium1
837077dfae fix(api): stop producers after run transport expires 2026-07-12 04:15:47 -07:00
brooklyn!
04c7d104a7
Merge pull request #61885 from embwl0x/agent/tui-secret-overlay-expiry
fix(tui): dismiss expired sensitive prompts
2026-07-12 05:50:24 -05:00
teknium1
51382ac244 fix(skills): bind bundles to exact files and origins 2026-07-12 02:59:27 -07:00
Teknium
7550c594ce
feat(reasoning): add max and ultra effort levels (#62650) 2026-07-12 00:26:49 -07:00
Teknium
62a76bd3d5
feat: make smart approvals the default (#62661) 2026-07-12 00:25:55 -07:00
teknium1
6142203bd7 fix(gateway): ground readiness in live runtime state 2026-07-11 08:42:21 -07:00
teknium1
31152ae108 fix(providers): align Fireworks integration with project policy 2026-07-11 05:43:35 -07:00
ethernet
5e849942c3 feat(dev): add isolated sandbox script for local dev
scripts/desktop-sandbox.sh runs a Hermes desktop instance in an isolated
sandbox — separate HERMES_HOME, separate Electron userData, and a
distinct
app name (HERMES_DESKTOP_APP_NAME) so it doesn't compete with the main
desktop instance's single-instance lock.

Two modes:
- Ephemeral (default): temp dir, cleaned up on exit
- --persistent: stored under .hermes-sandbox/ in the worktree git root,
  survives restarts for repeat testing

In the Nix devShell the script is available as 'sandbox'.

Also makes APP_NAME overridable via HERMES_DESKTOP_APP_NAME in main.ts —
app.setName() runs before requestSingleInstanceLock(), so the overridden
name changes the lock key. collectRelaunchEnv already preserves
HERMES_DESKTOP_* vars through self-update relaunches; test updated to
cover the new env var.
2026-07-10 18:51:49 -04:00
embwl0x
f618984c64 fix(tui): dismiss expired sensitive prompts 2026-07-10 14:45:43 -04:00
kshitijk4poor
a0032f5f92 fix(routing): preserve profile and delegation parity 2026-07-10 13:10:45 +05:30
Gille
3aeaf3755d fix(nous): forward provider routing through Portal 2026-07-10 13:10:45 +05:30
Teknium
aabfedcac0
docs(webhook): complete filters + route-scripts coverage across doc surfaces (#60983)
Follow-up to #60944 (webhook payload filters and route scripts):
- reference/cli-commands.md (en+zh): document the new --script option on
  'hermes webhook subscribe'
- zh-Hans user-guide webhooks.md: mirror the Payload Filters and Script
  Filters/Transforms sections plus the filters/script route properties
  (the salvage shipped English-only docs)
- hermes-agent skill webhooks reference: teach the agent the filters/
  script surface so agent-driven subscriptions can use them
2026-07-08 11:56:24 -07:00
Grace
0cf2e39c41 feat(gateway): add webhook payload filters 2026-07-08 08:10:55 -07:00
teknium1
db9e3e4ef9 docs(discord): troubleshoot silent fail-closed denials
Docs portion of PR #57067: 'bot connects but never replies' section
pointing at the gateway.log warning and the allowlist/policy knobs.

Co-authored-by: ooovenenoso <120500656+ooovenenoso@users.noreply.github.com>
2026-07-07 17:01:08 -07:00
Teknium
551f00109d
docs(sessions): unify export docs under one overview section (#60554)
Restructures the five parallel export sections into a single 'Export
Sessions' section: a format table (jsonl/md/qmd/html/trace + --only
user-prompts), one shared-filters paragraph covering all formats, and
per-format subsections nested beneath. EN + zh-Hans.
2026-07-07 16:29:27 -07:00