Commit Graph

14 Commits

Author SHA1 Message Date
ethernet
683e845357 refactor(stt): look up whisper.cpp through pm directly
Salvage follow-up to #132976. hermes_platform/resolver/whisper.py only
wrapped pm.installed_package(), which tools/ already calls directly
elsewhere (agent-browser, cua-driver, tirith).
2026-10-05 12:37:46 -04:00
Ryan Hill
13978ae5db fix(stt): bundle whisper.cpp CPU for Windows ARM64 2026-10-05 12:37:46 -04:00
Teknium
a4140eebb1 docs: root AGENTS.md becomes a hub; area rules move where they load
The root file is project context and was 38.7k chars, past the context-file budget
(20k floor, 30,720 on a 128k window), so every session lost its middle: routing table,
testing rules, code-shape rules. It now keeps the two invariants, a condensed rubric
(every rule kept), environment, structure, one-line rules that apply everywhere and the
routing table (11.8k).

Moved verbatim to where they load: Testing -> new tests/AGENTS.md; dependency pinning and
PM ownership -> new pm/AGENTS.md; machine facts -> new hermes_platform/AGENTS.md;
session-scoped tool availability -> tools/AGENTS.md; the full rubric with its real-close
examples -> developer-guide/contributing.md. Pointers in lint, checker messages, docs
and test comments name the new homes.
2026-10-04 23:05:42 -07:00
teknium1
b412ee9206 fix(platform): an unreadable GPU classifies as unknown, so requires.gpu fails open as documented
When every DRM card's vendor file or every Windows display adapter's
MatchingDeviceId was unreadable, classify_gpu_vendors returned 'none' and
availability refused with unsupported_gpu, contradicting the documented
'unreadable GPU passes' rule. Windows now records an unreadable numbered
adapter as an empty id so the classifier sees it.

Also drops the type-narrowing assert in availability() and makes
_action's gpu_label required.
2026-10-03 10:26:12 -07:00
alt-glitch
f1c79255fe feat(plugins): requires.gpu gates a plugin server on the host's GPU vendor
A portable plugin can now declare `requires: {gpu: nvidia}` for an MCP
server. On a host without an NVIDIA GPU, Hermes then refuses the
install, hides the server's tools, and the catalog card says "needs an
NVIDIA GPU". The check is the existing
`hermes_platform.host.facts.gpu_class()` read.

The requirement is independent of `app:`. The RTX Remix Toolkit is the
first consumer: it is a package the user unpacks anywhere, so there is
no install location to check, but it needs an NVIDIA GPU.

An unreadable GPU (`unknown`) passes, so a failed registry or sysfs
read does not lock out a machine that has the GPU. Only `nvidia` is
accepted: gpu_class() reports the highest-priority vendor, which
answers the question exactly for NVIDIA and not for AMD or Intel.

A registered server on such a host reports the new `unsupported_gpu`
state, carried through the gateway contract and the Plugins tab, with
a sentence that names the GPU instead of "Install <app>".
2026-10-03 10:26:12 -07:00
Ryan Hill
7e66781c2c docs(local-models): refer to N1X by product name 2026-09-28 16:36:38 -07:00
Ryan Hill
cba90a19b8 refactor(local-models): simplify PCI identity matching 2026-09-28 16:22:00 -07:00
Ryan Hill
dd2a047607 fix(local-models): identify N1X by PCI vendor/device ID 2026-09-28 16:05:20 -07:00
teknium1
91fbaa8d3b feat(platform): RAM total and GPU class host facts
The install snapshot needs coarse hardware facts, and machine facts belong in
hermes_platform.host (root AGENTS.md). ram_total_bytes reads /proc/meminfo,
sysctl hw.memsize or GlobalMemoryStatusEx; gpu_class reads /proc/driver/nvidia
and DRM PCI vendor ids on Linux, the display-adapter registry class on Windows,
and native arm64 on macOS. Both are cached per process, take no env input and
never spawn a subprocess or load a driver library, so the daily snapshot can
call them on its path. A discrete vendor wins over an integrated one on hybrid
machines.
2026-09-28 12:43:03 -07:00
teknium1
e0fae5566a fix: Hermes's own lint, activate, tui and MCP launchers use PM's node/npx/uv, never the user's
Post-write .js/.ts lint on the local backend runs PM's node/npx instead of
the terminal shell's PATH (user dirs first). pm.activate always puts the
store dirs in front, also on drift, activating only packages whose whole
chain is installed. tui_gateway puts the store dirs ahead of ~/.local/bin.
Bare npx/npm/node/uv/uvx MCP commands resolve to PM's copies; the system
fallback tables are gone and an absolute command: stays the user's.
2026-09-27 22:30:55 -07:00
Hermes Agent
678a4762b8 fix(mcp): move uv/uvx known-dir table into hermes_platform resolver
The #37589 uv/uvx fallback spelled its directory table (~/.local/bin,
/opt/homebrew/bin, /usr/local/bin) inline in _launcher_fallback, which the
managed-runtime ratchet flags as an unreviewed known_path_table outside
hermes_platform/. known_dirs is the module whose contract is 'every table in
Hermes lives here', so add uv_tool_dirs() there and compose it at the call
site. Behavior is unchanged: same four directories probed in the same order
(managed <home>/bin first, then uv's install order), bare uv/uvx still
resolves under a GUI-style PATH that lacks them.
2026-09-25 18:31:02 -05:00
Siddharth Balyan
eb5d735e9a Application-backed MCP servers: live endpoint per attempt, tools follow app liveness, errors and the tool catalog say why (NS-943) (#119050)
* feat: expose interactive and live endpoint facts

* feat: hydrate application-backed MCP liveness

* feat: export interactive session fact

* fix: classify unsupported declared hosts

* test(mcp): a runtime file without a token connects without an Authorization header

* fix(mcp): server_json liveness fields default to http/token/pid; an invalid declaration degrades to static instead of failing the server task

* fix(mcp): a connected server is offerable regardless of the interactive-session rule; the rule only shapes the not-connected sentence

* test(mcp): follow main's ToolSearchConfig fields and patch _bump_server_error at its origin module
2026-09-22 17:54:42 +05:30
Siddharth Balyan
4094ab610d hermes_platform.resolver: locate/inspect/probe tiers, AppResolver, gh lookup migrated (NS-921) (#118065)
* feat(platform): resolver core with locate/inspect/probe tiers and ordered candidates

Every resource lookup needs one result shape and one cost contract. `locate` reads
metadata only, `inspect` may open files and call OS APIs in-process, `probe` is fresh
and the only tier that may spawn or connect. `Resolution.candidates` keeps probe order
so fan-out consumers can try every present binary.
Linear NS-921.

* feat(platform): AppResolver over AppDef with plist, PE, registry, and server.json sources

Desktop apps need presence, version, and liveness as separate observations. The runtime
file's bearer token is parsed, used for one request, and discarded inside the probe;
no public type carries it. Endpoints are accepted only when loopback with a numeric port.

* refactor(copilot): gh candidates through locate_command and the Homebrew table

First consumer of the resolver. The gh token probe still tries every present binary in
order; the allowlist loses its two copilot_auth rows.

* feat(platform): availability() over an application declaration

locate() + inspect() only, never probes; the fail-closed _version in
app.py treats a vendor's plist/PE/registry entry as untrusted input.
Salvaged from PR #118122; reads any object with requires_app,
min_version, app_for(os) — nothing here imports the MCP catalog.

* feat(platform): application declarations parsed into AppDef per OS

The parser slice of PR #118122's catalog manifest, re-homed as a
catalog-free module: whoever owns an MCP server declares the app it
fronts per OS and what it needs, and registers it here. Stdlib +
hermes_platform.resolver only. register/lookup/clear are the one seam
the MCP check_fn and the skill gate both read.

* feat(mcp): check_fn honours a registered application declaration

_make_check_fn ANDs the declared app's availability into the
connection-alive check; with nothing registered for the server the
behaviour is the pre-PR3 connection check. Provenance is explicit
registration, not endpoint matching. Returns a plain bool: the registry
caches bool(fn()).

* feat(skills): requires_apps gate through registered declarations

Offer-time filter beside environments:; names resolve through
hermes_platform.declaration, an unknown name hides the skill (fail
closed). The disk snapshot carries requires_apps and the fast path
re-evaluates it (snapshot version bumped to 3): app presence is a host
fact that changes without SKILL.md changing.

* docs: application declarations page

The plugin-facing schema reference: app: and requires: blocks,
availability() states, and the two gates that read the registry.
Registered under Extending > Plugins in the docs sidebar.

* test(platform): declaration parser, availability, gates

The PR3 app-block tests re-homed off the catalog: fixtures are dicts
passed to parse_declaration, the check_fn gate keys on explicit
registration (not endpoint matching), and the import-hygiene probe now
covers hermes_platform.declaration and resolver.availability.
2026-09-22 17:08:30 +05:30
alt-glitch
48ed4e5364 feat(platform): hermes_platform.host with machine facts, runtime predicates, SoC recognizer
Host facts and runtime predicates need one stdlib-only source that stays correct under architecture emulation.
Hardware recognition reads host facts, not environment variables or GPU proxies.
The package boundary gives later resolvers and catalog checks a shared foundation.
Linear NS-920.
2026-09-22 01:13:23 -07:00