HEGI turns conversations from several Hermes research agents into meeting episodes,
structured minutes, action items, revision-safe archives, Telegram reports, and Memory
Forest recommendations. It is distributed as hermes-hegi, imported as hegi, and
registered with Hermes under the plugin key hegi-telegram.
HEGI 2.1.1 is a standalone plugin. It does not patch Hermes, copy code into the Hermes
installation, or depend on private Hermes modules. The package uses the public plugin
context for CLI registration, pre_gateway_dispatch, LLM access, and tool dispatch. It
calls the Telegram Bot API through its own adapter.
- Reads configured Hermes SQLite databases in read-only mode and de-duplicates messages from the same Telegram conversation.
- Detects quiet research meetings and operational incidents, then generates source-linked Korean minutes with agent positions and activity records kept separate.
- Writes Markdown and JSON archives with revision suffixes and copies them to a configured NAS only when that destination is available.
- Sends four checkpointed Telegram report parts and resumes after partial delivery.
- Searches Memory Forest, explains duplicate and novelty findings, and creates an STM Draft only after an authenticated professor command.
- Persists notification and approval jobs in SQLite so the embedded worker can recover from gateway restarts and step-level failures.
HEGI treats a Memory Forest commit as a privileged, professor-authorized operation. The following settings are enforced and cannot be relaxed by configuration:
memory:
auto_commit: false
auto_draft: false
require_professor_approval: true
approval:
allow_autonomous_commit: false
require_reply_or_meeting_id: true
require_fresh_search: true
require_draft_validation: true
require_post_commit_validation: true
require_audit: true
require_index: true
require_backup: trueThe gateway hook checks the Telegram platform, target chat, professor allowlist, message
identity, and report reply or explicit meeting_id. It only writes a short, idempotent
SQLite job and wakes the worker. The hook does not call an LLM, MCP, Memory Forest,
Telegram HTTP, or a subprocess.
The worker performs a fresh Memory Forest search, validates the Draft, calls approve and
commit as separate steps, and then runs validate, audit, index, and backup. Duplicate,
conflicting, ambiguous, low-recall, or no_memory cases stop closed. A restart after a
successful commit resumes post-commit maintenance without committing again.
Automated tests use fake backends and never make a real Memory Forest commit. A live professor-authorized commit must remain unclaimed unless a new authenticated professor approval message was received and the resulting commit was observed during that run. See Memory safety policy.
Hermes loads HEGI through one of two public entry points:
- A directory installation loads the repository root
__init__.py, which importshegi.hermes_plugin.registerby relative import. - A Python installation discovers
hegi-telegram = "hegi.hermes_plugin"in thehermes_agent.pluginsentry-point group.
Registration adds the hermes hegi CLI first and the pre_gateway_dispatch hook second.
Missing configuration does not stop plugin discovery. HEGI starts one daemon thread only
after configuration and host adapters are ready. That embedded worker runs while the
Hermes gateway process is running, reloads changed configuration, shares a process lock
for the state database, and records failures as dead letters.
The pipeline is:
Hermes SQLite databases (read-only)
-> durable message buffer -> episode detection -> ctx.llm analysis
-> ctx.dispatch_tool Memory search -> quality gate
-> local archive / optional NAS copy -> Telegram report
-> authenticated approval queue -> fresh search -> validated STM Draft
-> private approve -> commit -> validate -> audit -> index -> backup
| Component | Supported range |
|---|---|
| Python | 3.11, 3.12, 3.13 |
| Hermes Agent | 0.18.1 or newer |
| Primary production host | Linux or WSL with one Hermes gateway process |
| Windows | Python 3.12 import, configuration, parser, and state subset |
hermes-agent is deliberately absent from this package's dependencies, so installing
HEGI cannot replace the host's Hermes version. hegi doctor checks the installed host and
the plugin APIs it needs.
As of 1 August 2026, upstream Hermes main invokes pre_gateway_dispatch on the normal
incoming-message path but does not invoke it consistently on the active-session busy path.
The generic fix in NousResearch/hermes-agent#16489
is open and its checks are green. Until it is merged, send an approval command again after
the active session is idle if Hermes placed the first command in the follow-up queue. Do
not bypass HEGI's approval checks.
Hermes can install the repository as a directory plugin and enable it in one command:
hermes plugins install icerain-cmd/hermes-hegi --enableHEGI does not request permission to override built-in tools. If you install it disabled, enable it explicitly without that grant:
hermes plugins enable hegi-telegram --no-allow-tool-overrideInstall a tagged source tree or a downloaded release wheel into the same Python environment as Hermes, then enable the discovered entry point:
python -m pip install "git+https://github.com/icerain-cmd/hermes-hegi.git@v2.1.1"
hermes plugins enable hegi-telegram --no-allow-tool-overrideor:
python -m pip install ./hermes_hegi-2.1.1-py3-none-any.whl
hermes plugins enable hegi-telegram --no-allow-tool-overrideThe standard setup flow previews discovery before it writes HEGI's configuration:
hermes plugins install icerain-cmd/hermes-hegi --enable
hermes hegi setup --dry-run
hermes hegi setup --apply
hermes hegi doctorSetup detects the Hermes root, Memory Curator runtime, Telegram environment file, group chat, professor allowlist, participating agent databases, Memory Forest project, and archive path. It prints masked identifiers. If discovery is incomplete or ambiguous, provide explicit values instead of accepting a guess:
hermes hegi setup --dry-run \
--hermes-root /path/to/hermes-home \
--runtime-home /path/to/runtime-home \
--chat-id '<telegram-chat-id>' \
--professor-user-id '<telegram-user-id>' \
--project '<memory-project>'--apply writes only <runtime-home>/hegi/config.yaml, with mode 0600, and backs up an
existing config. HEGI keeps runtime data at:
<runtime-home>/hegi/config.yaml
<runtime-home>/hegi/state.db
<runtime-home>/hegi/archive/
Keep TELEGRAM_BOT_TOKEN in the runtime .env selected by telegram.curator_env. Never
put the token, real chat IDs, professor IDs, state database, or archive in this repository.
Restart the gateway after installation or a plugin update, then run the checks:
hermes gateway restart
hermes hegi doctor
hermes hegi doctor --json
hermes hegi status
hermes hegi run-once --diagnostic
hermes hegi run-once --dry-runrun-once --diagnostic streams a stable raw SQLite snapshot into private temporary
storage, checks configuration, the supported schema version and required invariants,
integrity, and aggregate queue
counts there, and verifies that the operating database and sidecars did not change. It
never constructs the pipeline or calls the LLM, Memory Forest, Telegram, archive, or run
logger. On Linux and WSL it opens SQLite artifacts with O_NOATIME; configuration and env
files are read, so their filesystem access timestamps are outside this logical no-write
guarantee.
The existing run-once --dry-run remains a stateful pipeline simulation for backward
compatibility. It may use the configured LLM and Memory Forest search tools and may
update HEGI's local state, retries, dead letters, cursors, buffers, and run log. It does
not write an archive, send a Telegram report, consume the source range, approve a Draft,
or commit a memory. Use --send only when you intend to archive and deliver a real report:
hermes hegi run-once --sendThe gateway must stay running for normal operation because the HEGI worker lives inside
that process. New installations must not create or start a separate hegi.service; two
workers pointed at the same state database can duplicate work.
The CLI surface is:
| Command | Purpose |
|---|---|
| `hermes hegi setup [--dry-run | --apply]` |
hermes hegi doctor [--json] |
Check Hermes APIs, configuration, tools, token, paths, and schema |
hermes hegi status |
Print episode, queue, notification, and dead-letter counts |
hermes hegi run-once --diagnostic |
Inspect a stable private state snapshot with no HEGI data writes or external calls |
| `hermes hegi run-once [--dry-run | --send]` |
| `hermes hegi migrate [--dry-run | --apply]` |
hermes hegi export-diagnostics [--output FILE] |
Write a redacted diagnostic JSON file with mode 0600 |
hermes hegi uninstall --keep-data |
Disable HEGI while retaining config, state, and archives |
The hegi console script offers the same parser. Prefer hermes hegi for commands that
need ctx.llm or ctx.dispatch_tool from the running Hermes environment.
Operations guide · Troubleshooting
Back up the runtime before upgrading. For a directory installation:
hermes plugins update hegi-telegram
hermes hegi migrate --dry-run
hermes hegi migrate --apply
hermes gateway restart
hermes hegi doctor
hermes hegi run-once --diagnosticFor a Python installation, install the intended wheel or tag with python -m pip install --upgrade ..., then run the same migrate, restart, doctor, and diagnostic sequence. Schema
migrations are additive. Do not downgrade or restore state.db without a migration-specific
rollback plan.
Existing HEGI users can reuse the current config, state database, archive, delivery checkpoints, and approval history. Start with the non-mutating migration command:
scripts/migrate-existing-install.sh --dry-run \
--runtime-home /path/to/runtime-homeReview the detected paths, backup destination, old service state, and printed rollback command. Apply only after the dry-run is correct:
scripts/migrate-existing-install.sh --apply \
--runtime-home /path/to/runtime-homeThe script backs up configuration, SQLite state, the legacy plugin directory, and service
status, then seals those artifacts with a version marker and SHA-256 manifest before
installing the standalone plugin. It reuses the existing runtime paths and disables an
old hegi.service unless --keep-old-service is present. That option is for a controlled
transition only; never run the old service and embedded worker concurrently.
Full migration runbook · In-tree migration background
The migration script prints the exact backup directory and rollback command. Preview it before applying:
scripts/rollback.sh --dry-run \
--runtime-home /path/to/runtime-home \
--backup-dir /path/to/migration-backup
scripts/rollback.sh --apply \
--runtime-home /path/to/runtime-home \
--backup-dir /path/to/migration-backupRollback verifies the marker, complete artifact set, and all checksums before it changes
plugin or gateway state. It then disables hegi-telegram, restores the backed-up config
and legacy plugin, and preserves the current state.db by default. Add --restore-db
only after you have separately saved the current database and accepted losing all state
written since migration. Add --enable-old-service only when the embedded worker is no
longer active.
python -m venv .venv
. .venv/bin/activate
python -m pip install --upgrade pip
python -m pip install -e ".[dev]"
ruff check .
python -m compileall hegi
pytest -q
python -m build
twine check dist/*
scripts/smoke-test.shTests use temporary directories, fake Telegram transports, and fake Memory Forest
backends. Contributors must not introduce a direct production import from agent,
tools, gateway, hermes_cli, hermes_constants, or utils. See
CONTRIBUTING.md.
HEGI was developed on icerain-cmd/hermes-agent branch feature/hegi-v2 and proposed in
NousResearch/hermes-agent#70603.
Hermes integration policy called for a standalone plugin, so version 2.1.0 moved the HEGI
package and tests into this repository without the Hermes core changes from that pull
request. NOTICE.md records the exact source commit.
HEGI is released under the MIT License. Security reports belong in private GitHub vulnerability reporting, not a public issue. Read SECURITY.md before sharing diagnostics.