RepoPilot

NousResearch/hermes-agent

The agent that grows with you

Healthy

Healthy across the board

HealthyDependency

Permissive license, no critical CVEs, actively maintained — safe to depend on.

HealthyFork & modify

Has a license, tests, and CI — clean foundation to fork and modify.

HealthyLearn from

Documented and popular — useful reference codebase to read through.

HealthyDeploy as-is

No critical CVEs, sane security posture — runnable as-is.

  • Last commit today
  • 33+ active contributors
  • Distributed ownership (top contributor 31% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against dependency CVEs from deps.dev and OpenSSF Scorecard

Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.

Want this for your own repo?

Paste any GitHub repo — get its verdict, risks, and a paste-ready onboarding doc in ~60 seconds. Free, no sign-up.

Embed the "Healthy" badge

Paste into your README — live-updates from the latest cached analysis.

Variant:
RepoPilot: Healthy
[![RepoPilot: Healthy](https://repopilot.app/api/badge/nousresearch/hermes-agent)](https://repopilot.app/r/nousresearch/hermes-agent)

Paste at the top of your README.md — renders inline like a shields.io badge.

Preview social card

This card auto-renders when someone shares https://repopilot.app/r/nousresearch/hermes-agent on X, Slack, or LinkedIn.

Ask AI about nousresearch/hermes-agent

Grounded in the actual source code. Pick a starter question or write your own.

Or write your own question →

Onboarding doc

Onboarding: NousResearch/hermes-agent

Generated by RepoPilot · 2026-06-27 · Source

🎯Verdict

GO — Healthy across the board

  • Last commit today
  • 33+ active contributors
  • Distributed ownership (top contributor 31% of recent commits)
  • MIT licensed
  • CI configured
  • Tests present

<sub>Computed from maintenance signals — commit recency, contributor breadth, bus factor, license, CI, tests, cross-checked against dependency CVEs from deps.dev and OpenSSF Scorecard</sub>

TL;DR

Hermes Agent is a self-improving AI agent built by Nous Research that runs a closed learning loop: it autonomously creates reusable skills from completed tasks, improves those skills during use, maintains persistent memory across sessions, and builds a user model over time. It exposes a full TUI (terminal UI) with multiline editing and slash-command autocomplete, plus multi-platform chat gateways (Telegram, Discord, Slack, WhatsApp, Signal). It is model-agnostic, routing through providers like OpenRouter, Nous Portal, NVIDIA NIM, and others via a single hermes model switch. The repo is a polyglot monorepo: a large Python backend handles the agent loop, memory, skills, and provider integrations (the core hermes CLI package published to PyPI via .github/workflows/upload_to_pypi.yml), while a TypeScript/Tauri frontend under the @hermes/bootstrap-installer package provides a signed native desktop installer UI. CI workflows in .github/workflows/ and shared actions in .github/actions/ coordinate the build, test, and deploy pipeline.

👥Who it's for

AI power users and self-hosters who want a persistent, learning agent they control — running on a $5 VPS, GPU cluster, or serverless infrastructure — without being locked to a specific model or cloud. Also targets Nous Research contributors extending provider integrations, skill libraries, or chat gateway connectors.

🌱Maturity & risk

The CI setup is comprehensive — 15+ GitHub Actions workflows covering lint, typecheck, Docker lint/build, OSV security scanning, supply-chain audit, skills-index freshness, PyPI upload, and tests — indicating serious engineering investment. The codebase is large (~50MB Python, ~8.5MB TypeScript) with a Dockerfile, .env.example, and structured CONTRIBUTING guides in multiple languages, suggesting active production use. Verdict: actively developed with production-grade infrastructure, not experimental.

The repo bundles a Tauri-based desktop installer (@hermes/bootstrap-installer) with bleeding-edge deps (TypeScript 6.0.3, Vite 8.x, React 19) that are very recent and may carry instability. The Python backend dominates at ~49MB which is opaque from the file listing alone, and the skill-learning loop introduces autonomous self-modification that could drift unpredictably. The .github/workflows/skills-index-freshness.yml workflow suggests the skills index can go stale, which is a live operational risk.

Active areas of work

Two active plan documents in .plans/ reveal in-progress work: .plans/openai-api-server.md (adding an OpenAI-compatible API server to Hermes) and .plans/streaming-support.md (implementing streaming responses). The AGENTS.md file suggests agent-specific contribution guidelines are being formalized, and the skills-index freshness workflow indicates ongoing maintenance of the autonomous skills library.

🚀Get running

git clone https://github.com/NousResearch/hermes-agent.git && cd hermes-agent && cp .env.example .env # fill in your API keys

Python backend (uses uv based on uv-lockfile-check workflow)

pip install uv && uv sync

or via pip directly

pip install -e .

Run the CLI

hermes

For the Tauri desktop installer (Node deps)

cd <installer-package-dir> && npm install && npm run tauri:dev

Daily commands:

CLI (Python)

uv run hermes

or after install:

hermes

Desktop installer (dev mode)

npm run tauri:dev

Desktop installer (production build)

npm run tauri:build

Docker

docker build -t hermes-agent . && docker run --env-file .env hermes-agent

🗺️Map of the codebase

  • agent/conversation_loop.py — Core agentic loop that drives tool-calling, LLM turns, and conversation state — the heart of the runtime.
  • agent/agent_init.py — Bootstraps the agent session, wires together providers, tools, and context — must be understood before any feature work.
  • agent/context_engine.py — Manages the context window, token budgeting, and injection of references — critical for understanding memory limits.
  • agent/agent_runtime_helpers.py — Shared utilities used across the runtime for tool dispatch, error handling, and response normalisation.
  • acp_adapter/server.py — ACP adapter HTTP server that exposes the agent as a networked service — the main external entry point.
  • agent/errors.py — Defines all custom exception types used throughout the codebase — essential for consistent error handling.
  • agent/credential_pool.py — Manages provider API keys and credential rotation — failure here silently breaks all LLM calls.

🧩Components & responsibilities

  • Conversation Loop (Python, asyncio) — Orchestrates multi-turn LLM calls, tool execution, and response streaming.
    • Failure mode: Infinite loop or hung session if tool never returns or LLM emits malformed tool calls.
  • Context Engine (Python, tiktoken-style counting) — Assembles the token-budgeted context window for each LLM call.
    • Failure mode: Context overflow or silent truncation causing model to lose critical instructions.
  • LLM Adapters (Python, provider SDKs) — Normalise provider-specific APIs (Anthropic, Gemini, Bedrock, Codex) to a common interface.
    • Failure mode: Schema drift in provider APIs causes silent wrong results or crashes.
  • Credential Pool (Python) — Manages API key selection and rotation across providers.
    • Failure mode: Expired or missing credentials cause all LLM calls to fail with auth errors.
  • ACP Adapter (Python, HTTP) — Exposes the agent as a networked ACP-compatible service.
    • Failure mode: Session state desync causes requests to be routed to wrong conversation history.
  • Browser Provider (Python, Playwright/CDP) — Abstracts browser automation backends for web-browsing tool calls.
    • Failure mode: Browser process crash leaves dangling sessions consuming resources.

🔀Data flow

  • User / ACP ClientACP Server — Sends prompt and session ID over HTTP.
  • ACP ServerConversation Loop — Passes resolved session and messages to the runtime.
  • Conversation LoopContext Engine — Requests assembled, compressed context for the current turn.
  • Conversation LoopLLM Adapter — Sends context window; receives text or tool-call response.
  • LLM AdapterCredential Pool — Fetches the active API key for the selected provider.
  • Conversation LoopTool Dispatch — Executes tool calls and feeds results back into the next LLM turn.

🛠️How to make changes

Add a new LLM provider adapter

  1. Create a new adapter module following the pattern of existing adapters (e.g. normalise chat_completion and streaming methods). (agent/anthropic_adapter.py)
  2. Register the new provider in the credential sources so API keys can be loaded. (agent/credential_sources.py)
  3. Add the provider to the credential pool's provider map so it can be selected at runtime. (agent/credential_pool.py)
  4. Wire the new adapter into the agent init so it can be instantiated during session bootstrap. (agent/agent_init.py)

Add a new agent tool

  1. Implement the tool function with the standard signature (args dict → result string/dict) and register it in the ACP tools module. (acp_adapter/tools.py)
  2. If the tool requires permission gating, add it to the permissions registry. (acp_adapter/permissions.py)
  3. Add the tool schema to the context engine so it is included in the system prompt/context. (agent/context_engine.py)
  4. Handle any new tool call branches in the runtime helper dispatch logic. (agent/agent_runtime_helpers.py)

Add a new browser provider backend

  1. Implement the new backend by subclassing or following the interface defined in the browser provider module. (agent/browser_provider.py)
  2. Register the new backend in the browser registry so it can be selected by name. (agent/browser_registry.py)

Add a new ACP adapter endpoint

  1. Add the new HTTP route handler to the ACP server, following the existing route conventions. (acp_adapter/server.py)
  2. If the endpoint involves session state, update session lifecycle handling. (acp_adapter/session.py)
  3. Emit appropriate ACP events for the new endpoint's operations. (acp_adapter/events.py)

🔧Why these technologies

  • Python (agent core) — Dominant ecosystem for LLM tooling, async support, and rapid iteration on agentic patterns.
  • Rust/Tauri (desktop installer) — Provides a lightweight, secure native desktop shell for the signed installer without shipping Electron.
  • ACP protocol (acp_adapter) — Standard agent communication protocol enables interoperability with other ACP-compatible clients and orchestrators.
  • uv (Python packaging) — Fast, reproducible dependency resolution — preferred over pip for CI and lockfile workflows.
  • Vite + TypeScript (installer UI) — Modern build tooling for the Tauri installer frontend with strong type safety.

⚖️Trade-offs already made

  • Multiple LLM provider adapters instead of a single abstraction library

    • Why: Allows fine-grained control over each provider's unique streaming, tool-calling, and auth quirks.
    • Consequence: Adding a new provider requires implementing a new adapter module rather than a one-line config change.
  • ACP adapter as a separate package from the core agent

    • Why: Keeps the agent runtime usable standalone (CLI/library) without requiring the network server.
    • Consequence: Two call paths to maintain; bugs fixed in one may not propagate to the other without deliberate effort.
  • In-process context compression rather than external vector store

    • Why: Reduces operational complexity — no external service dependency for basic long-context handling.
    • Consequence: Compression quality is limited to what fits in memory; very long sessions may lose fidelity.

🚫Non-goals (don't propose these)

  • Does not provide a managed cloud hosting service — self-hosted only
  • Does not implement its own LLM model weights or inference engine
  • Does not offer a graphical chat UI beyond the Tauri desktop installer
  • Does not handle multi-user authentication or RBAC natively

📊Code metrics

  • Avg cyclomatic complexity: ~14 — Agentic loop with multi-provider adapters, async streaming, and tool dispatch branches drives above-average cyclomatic complexity per module.
  • Largest file: agent/conversation_loop.py (900 lines)
  • Estimated quality issues: ~18 — Estimated issues include duplicated adapter boilerplate, the backup curator file, broad except clauses in error handling, and implicit coupling between context engine and adapters.

⚠️Anti-patterns to avoid

  • God module risk (Medium)agent/conversation_loop.py: The main loop likely accumulates responsibilities (tool dispatch, error handling, streaming) that could be separated into focused modules.
  • Duplicated adapter boilerplate (Medium)agent/anthropic_adapter.py, agent/gemini_native_adapter.py, agent/bedrock_adapter.py: Each provider adapter re-implements similar streaming and retry logic without a shared base class, risking divergence.
  • Credential handling spread across multiple modules (High)agent/credential_pool.py, agent/credential_persistence.py, agent/credential_sources.py: Credential logic split across three files increases the risk of inconsistent access patterns and security gaps.
  • Backup curator module (Low)agent/curator_backup.py: Presence of a *_backup.py file alongside the canonical module suggests ad-hoc versioning instead of proper branching.

🔥Performance hotspots

  • agent/context_engine.py (CPU / Latency) — Token counting and context assembly runs synchronously on every LLM turn; for long histories this is CPU-bound and blocks the event loop.
  • agent/conversation_loop.py (Concurrency) — Sequential tool execution means multi-tool turns are not parallelised, inflating end-to-end response latency.
  • agent/credential_pool.py (Concurrency / I/O) — Credential resolution on every request could become a lock contention point under high concurrency without pooling.

🪤Traps & gotchas

  1. The @hermes/bootstrap-installer package.json lists TypeScript 6.0.3 and Vite 8.x which were pre-release/bleeding-edge at time of writing — npm install may fail or warn about peer deps. 2) .envrc uses direnv with Nix — running outside a Nix shell will likely miss system-level dependencies unless you use the Dockerfile. 3) The uv lockfile check workflow (uv-lockfile-check.yml) means you must commit an updated uv.lock when changing Python deps or CI fails. 4) The skills-index freshness workflow will fail if the skills index isn't regenerated after adding new skills — don't add skills without re-running the index build. 5) Telegram/Discord gateways require separate bot tokens in .env beyond the LLM provider keys.

🏗️Architecture

💡Concepts to learn

  • SQLite FTS5 (Full-Text Search) — The agent's conversation history and skills index are searchable via SQLite FTS5 — understanding how FTS5 virtual tables and trigram indexes work is necessary to extend or debug the memory search features.
  • Skill / Tool Augmented LLM Agents — Hermes's core loop creates, stores, and reuses 'skills' (reusable task programs) across sessions — this is the ReAct/Toolformer-style agent pattern extended with persistence and self-improvement.
  • Tauri (Rust-backed desktop apps) — The desktop installer is built with Tauri v2, which wraps a Rust shell around a web frontend — contributors touching the installer must understand how Tauri IPC and plugin permissions work.
  • uv (Python package manager) — The project uses uv for dependency management and lockfiles instead of pip/poetry — the lockfile must be committed and kept current or CI breaks.
  • Retrieval-Augmented Generation (RAG) for agent memory — The agent searches its own past conversations and skills index using FTS5-backed retrieval — this is a form of RAG applied to agent self-knowledge rather than external documents.
  • OpenAI-compatible API server pattern — The in-progress .plans/openai-api-server.md aims to expose Hermes behind an OpenAI-compatible endpoint — understanding this protocol is essential for working on that feature.
  • Nix reproducible environments — The repo uses .envrc + Nix flakes (.github/actions/nix-setup) for reproducible CI and dev shells — without Nix awareness, environment-specific failures are hard to diagnose.
  • simonw/llm — CLI-first LLM tool with plugin-based provider support — solves a similar 'model-agnostic CLI agent' problem but without the self-improving skills loop.
  • microsoft/autogen — Multi-agent framework with skill/tool composition — direct conceptual alternative for the autonomous agent loop, different architecture (Python, no TUI or chat gateways).
  • openai/swarm — Lightweight multi-agent orchestration from OpenAI — inspiration/predecessor pattern for agent handoffs and skill routing.
  • NousResearch/hermes-function-calling — Nous Research's function-calling dataset and model work — the upstream model capability that the skills/tool-use system in this agent is built on top of.
  • python-telegram-bot/python-telegram-bot — Likely dependency for the Telegram gateway connector inside the Python backend.

🪄PR ideas

To work on one of these in Claude Code or Cursor, paste: Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.

Add unit tests for acp_adapter auth, permissions, and provenance modules

The acp_adapter package contains security-critical modules (auth.py, permissions.py, provenance.py) with no corresponding test files visible in the repo. These modules govern agent authentication, permission gating, and provenance tracking — bugs here could expose users to privilege escalation or data leakage. Adding focused unit tests would improve confidence and make the CI workflow in .github/workflows/tests.yml actually exercise these paths.

  • [ ] Create tests/acp_adapter/test_auth.py covering token validation, rejection of invalid/missing credentials, and edge cases in acp_adapter/auth.py
  • [ ] Create tests/acp_adapter/test_permissions.py asserting that permission checks in acp_adapter/permissions.py correctly allow/deny based on role/scope inputs
  • [ ] Create tests/acp_adapter/test_provenance.py verifying that provenance records in acp_adapter/provenance.py are correctly constructed and serialized
  • [ ] Create tests/acp_adapter/test_session.py covering session creation, expiry, and teardown logic in acp_adapter/session.py
  • [ ] Ensure the new tests are picked up by the existing .github/workflows/tests.yml CI job (check the test discovery config and add the new path if needed)

Implement the streaming support plan documented in .plans/streaming-support.md

The repo contains a design document at .plans/streaming-support.md that describes planned streaming support, but the feature appears to be unimplemented (no streaming-related source files are visible in the partial file tree). Implementing this plan is high-value because streaming responses are essential for a good UX in an AI agent product and is likely blocking downstream integrations. A contributor can use the existing plan doc as a spec to produce a concrete PR.

  • [ ] Read .plans/streaming-support.md thoroughly and extract the agreed interface/contract
  • [ ] Add server-sent event (SSE) or WebSocket streaming support to acp_adapter/server.py, following the architecture described in the plan
  • [ ] Update acp_adapter/events.py to define typed streaming event models that match the plan's event schema
  • [ ] Add integration tests in tests/acp_adapter/test_streaming.py that assert incremental chunks are emitted correctly and that the stream terminates cleanly on completion and on error
  • [ ] Update the acp_registry/agent.json capability declaration if streaming changes the advertised agent capabilities
  • [ ] Add a short 'Streaming' section to the relevant README or docs referencing the new capability

Add a Rust/Tauri-specific CI workflow for the bootstrap-installer

The package.json reveals a Tauri-based bootstrap installer (@hermes/bootstrap-installer) with tauri:build and tauri:build:debug scripts, but inspecting .github/workflows/ shows workflows only for Python (tests.yml), TypeScript (typecheck.yml), linting, and Docker — there is no workflow that compiles the Tauri/Rust layer or runs tauri build in CI. Without this, regressions in the installer's Rust code or its Tauri plugin bindings (plugin-shell, plugin-process, plugin-dialog) go undetected until a human tries a release build.

  • [ ] Create .github/workflows/tauri-build.yml that triggers on pull_request and push to main
  • [ ] Set up the workflow matrix to build on ubuntu-latest, macos-latest, and windows-latest to catch platform-specific issues with the installer
  • [ ] Use the existing .github/actions/nix-setup/action.yml for Linux if applicable, otherwise install Rust stable + the required system libs (webkit2gtk on Linux, Xcode CLI on macOS)
  • [ ] Add a step that runs npm ci followed by npm run tauri:build:debug inside the installer package directory to validate the full Rust+frontend compile
  • [ ] Cache Rust/Cargo artifacts using actions/cache keyed on Cargo.lock to keep build times reasonable

🌿Good first issues

  1. Add unit tests for the skills freshness check logic — .github/workflows/skills-index-freshness.yml exists but there are no visible test files for the underlying freshness detection code, making it a regression risk. 2) Document the .env.example variables inline — each variable currently lacks a comment explaining its purpose, required format, and which feature it gates. 3) Add a CONTRIBUTING.md section specifically for adding new LLM providers, since the README lists 10+ providers but there's no developer guide showing the interface a new provider adapter must implement.

Top contributors

Click to expand

📝Recent commits

Click to expand
  • f53b184 — fix(ci): pass secrets down to docker workflows (ethernet8023)
  • 190e1ff — fix(redact): mask passwords in lowercase/dotted config keys (#53590) (teknium1)
  • 917f6bd — fix(tools): let vision pick any provider+model, not just OpenRouter (#53606) (teknium1)
  • 9c81c93 — fix(approval): honour tirith_fail_open=false on Tirith ImportError (#20733) (Beandon13)
  • fe1c1c1 — fix(session_search): demote cron below interactive sessions in discover ranking (#53597) (teknium1)
  • cd592c1 — feat(send_message): native WhatsApp media delivery via Baileys bridge (#53598) (teknium1)
  • 88c0246 — fix(mcp): never permanently wedge the circuit breaker on a dead transport (#53599) (teknium1)
  • dbc925b — Guard oversized Telegram video downloads (r266-tech)
  • 02b32e2 — fix(moa): call reference + aggregator models through their provider's real route (#53580) (teknium1)
  • 3fe16e3 — fix(fallback): attach credential pool after provider switch (herbalizer404)

🔒Security observations

  • High · Unpinned/Overly Broad Dependency Version Ranges — package.json (dependencies and devDependencies). Multiple critical dependencies use caret (^) version ranges allowing automatic minor/patch upgrades, which can silently introduce malicious or vulnerable versions. Notably: react ^19.2.4, vite ^8.0.16, @tauri-apps/api ^2.0.0, @tauri-apps/plugin-shell ^2.0.0, lucide-react ^0.577.0, and others. The @tauri-apps/plugin-shell dependency is particularly sensitive as it provides native OS shell access from the frontend — a supply-chain compromise here could enable remote code execution. Fix: Pin all production dependencies to exact versions (remove ^ and ~ prefixes). Use a lockfile (package-lock.json or yarn.lock) and verify integrity with checksums. Implement Subresource Integrity (SRI) checks and enable npm audit in CI pipelines. Pay special attention to @tauri-apps/plugin-shell given its elevated privilege surface.
  • High · Tauri Shell Plugin Exposure – Potential Command Injection Vector — package.json -> dependencies -> @tauri-apps/plugin-shell. The dependency @tauri-apps/plugin-shell ^2.0.0 is included in production dependencies, granting the frontend (React/Vite web layer) the ability to invoke native OS shell commands via Tauri's IPC bridge. If any user-controlled input is passed unsanitized to shell invocations, this constitutes a direct command injection vulnerability leading to full host compromise. The installer context (scripts/install.ps1) further amplifies this risk. Fix: Audit all usages of @tauri-apps/plugin-shell to ensure no user-supplied data is interpolated into shell commands. Prefer @tauri-apps/api invoke commands with strict argument whitelisting. In Tauri's tauri.conf.json, scope shell permissions to the minimum required executables and disable the 'execute' capability for all paths not explicitly needed. Consider using tauri's allowlist to restrict shell access.
  • High · Sensitive API Keys in Environment Configuration Without Vault Integration — .env.example, .envrc, Dockerfile. The .env.example file documents multiple sensitive API keys (OPENROUTER_API_KEY, NovitaAI keys, and likely others given the truncated content) stored as plain environment variables. In a containerized deployment (Dockerfile visible), these secrets risk being baked into image layers if ARG/ENV instructions are used carelessly, or leaked via docker inspect, container logs, or process enumeration (/proc/self/environ). The .envrc file (direnv) may also expose secrets in shell history or to other local processes. Fix: Use a secrets management solution (e.g., HashiCorp Vault, AWS Secrets Manager, Docker secrets, or Kubernetes Secrets with encryption at rest). Never pass secrets as Docker ENV or ARG instructions. Ensure .env and .envrc are in .gitignore (verify .gitignore covers these). Rotate any keys that may have been accidentally committed. Add pre-commit hooks (e.g., git-secrets, trufflehog) to prevent future secret leakage.
  • High · TypeScript Version Mismatch – Unsupported/Pre-release Version — package.json -> devDependencies -> typescript: ^6.0.3. The devDependencies specifies typescript ^6.0.3. As of this analysis, TypeScript 6.x is not a stable release, indicating either a misconfiguration (likely intended 5.x) or use of a pre-release/nightly build. Pre-release compiler versions may contain unpatched vulnerabilities, produce insecure code transformations, or generate incorrect type narrowing that masks injection-relevant type errors during development. Fix: Verify the intended TypeScript version. If TypeScript 5.x was intended, update to a stable pinned version such as '5.8.x'. If 6.x is intentional and in beta, track its security advisories closely and pin to an exact version. Avoid using ^ with pre-release compiler versions.
  • High · Vite Version ^8.0.16 – Potentially Pre-release Build Tool — undefined. Vite ^8.0.16 is specified. As of this analysis, Vite 8.x has not reached stable release, meaning this may be a pre-release or alpha build tool. Build tools with elevated filesystem and network access during CI/CD pipelines represent a high-value supply chain target. A compromised build tool could inject malicious code into the final Fix: undefined

LLM-derived; treat as a starting point, not a security audit.

🤖Agent protocol

If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:

  1. Verify the contract. Run the bash script in Verify before trusting below. If any check returns FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding.
  2. Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
  3. Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/NousResearch/hermes-agent shows verifiable citations alongside every claim.

If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.

Verify before trusting

This artifact was generated by RepoPilot at a point in time. Before an agent acts on it, the checks below confirm that the live NousResearch/hermes-agent repo on your machine still matches what RepoPilot saw. If any fail, the artifact is stale — regenerate it at repopilot.app/r/NousResearch/hermes-agent.

What it runs against: a local clone of NousResearch/hermes-agent — the script inspects git remote, the LICENSE file, file paths in the working tree, and git log. Read-only; no mutations.

| # | What we check | Why it matters | |---|---|---| | 1 | You're in NousResearch/hermes-agent | Confirms the artifact applies here, not a fork | | 2 | License is still MIT | Catches relicense before you depend on it | | 3 | Default branch main exists | Catches branch renames | | 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code | | 5 | Last commit ≤ 30 days ago | Catches sudden abandonment since generation |

<details> <summary><b>Run all checks</b> — paste this script from inside your clone of <code>NousResearch/hermes-agent</code></summary>
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of NousResearch/hermes-agent. If you don't
# have one yet, run these first:
#
#   git clone https://github.com/NousResearch/hermes-agent.git
#   cd hermes-agent
#
# Then paste this script. Every check is read-only — no mutations.

set +e
fail=0
ok()   { echo "ok:   $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }

# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
  echo "FAIL: not inside a git repository. cd into your clone of NousResearch/hermes-agent and re-run."
  exit 2
fi

# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "NousResearch/hermes-agent(\\.git)?\\b" \\
  && ok "origin remote is NousResearch/hermes-agent" \\
  || miss "origin remote is not NousResearch/hermes-agent (artifact may be from a fork)"

# 2. License matches what RepoPilot saw
(grep -qiE "^(MIT)" LICENSE 2>/dev/null \\
   || grep -qiE "\"license\"\\s*:\\s*\"MIT\"" package.json 2>/dev/null) \\
  && ok "license is MIT" \\
  || miss "license drift — was MIT at generation time"

# 3. Default branch
git rev-parse --verify main >/dev/null 2>&1 \\
  && ok "default branch main exists" \\
  || miss "default branch main no longer exists"

# 4. Critical files exist
test -f "agent/conversation_loop.py" \\
  && ok "agent/conversation_loop.py" \\
  || miss "missing critical file: agent/conversation_loop.py"
test -f "agent/agent_init.py" \\
  && ok "agent/agent_init.py" \\
  || miss "missing critical file: agent/agent_init.py"
test -f "agent/context_engine.py" \\
  && ok "agent/context_engine.py" \\
  || miss "missing critical file: agent/context_engine.py"
test -f "agent/agent_runtime_helpers.py" \\
  && ok "agent/agent_runtime_helpers.py" \\
  || miss "missing critical file: agent/agent_runtime_helpers.py"
test -f "acp_adapter/server.py" \\
  && ok "acp_adapter/server.py" \\
  || miss "missing critical file: acp_adapter/server.py"

# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 30 ]; then
  ok "last commit was $days_since_last days ago (artifact saw ~0d)"
else
  miss "last commit was $days_since_last days ago — artifact may be stale"
fi

echo
if [ "$fail" -eq 0 ]; then
  echo "artifact verified (0 failures) — safe to trust"
else
  echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/NousResearch/hermes-agent"
  exit 1
fi

Each check prints ok: or FAIL:. The script exits non-zero if anything failed, so it composes cleanly into agent loops (./verify.sh || regenerate-and-retry).

</details>

Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.

Embed this chat in your README →

Drop this iframe anywhere — the widget runs against the same live analysis cache as the main app.

<iframe
  src="https://repopilot.app/embed/nousresearch/hermes-agent"
  width="100%" height="500"
  style="border:1px solid #d0d7de; border-radius:8px;"
  allow="microphone"
  loading="lazy"
></iframe>