Skip to main content

agentguard-spend-hermes

One-step install of AgentGuard™ Spend into Hermes Agent (Nous Research).

Adds local spend caps + Ed25519-signed audit logs to every Anthropic and OpenAI call your Hermes agent makes. No proxy. No cloud component. Prompts and provider keys never leave your machine.

Built for Hermes's unattended-by-default workflow: cron jobs, sleep loops, multi-platform messaging bridges (Telegram, Discord, Slack, WhatsApp, Signal).

Install

# In the same virtualenv as Hermes
uv pip install agentguard-spend-hermes

That's it. Hermes's plugin manager auto-discovers the plugin via the hermes_agent.plugins entry point on next startup.

First-run auto-bootstrap

On first Hermes startup after install, the plugin:

  1. Generates ~/.hermes/agentguard/private.key + public.key (Ed25519). The directory is created 0700 and the private key 0600, owner-only from the moment it is created.
  2. Writes a default policy.yaml ($5/day soft cap downgrades Opus → Sonnet, $20/day hard cap blocks, $2/min burst guard)
  3. Monkey-patches the Anthropic and OpenAI client constructors so every LLM call is policy-checked + signed

You'll see in the Hermes log:

agentguard-spend: wrote default policy to ~/.hermes/agentguard/policy.yaml (locale: en-US)
agentguard-spend: generated signing keypair (private=..., public=...)
agentguard-spend: active (anthropic=True, openai=early, policy=...)

The policy file is localized to your system locale at first-write (en-US, es-419, or pt-BR).

When a cap fires

Downgrade (soft cap):

[hermes] anthropic.messages.create model=claude-opus-4-7
[agentguard] downgrade: claude-opus-4-7 -> claude-sonnet-4-6 (daily soft cap)
[hermes] continuing with sonnet

Block (hard cap):

[hermes] anthropic.messages.create model=claude-opus-4-7
[agentguard] block: hard daily ceiling exceeded
[hermes] AgentGuardBlockedError raised — agent halts this turn

Configure

Edit ~/.hermes/agentguard/policy.yaml and restart Hermes. Example:

id: hermes-default-v1
name: Hermes default caps
version: 1
effectiveFrom: "2026-01-01T00:00:00Z"
mode: enforce

scope:
  tenantId: hermes-personal

caps:
  - amountCents: 500     # $5/day soft cap
    window: per_day
    action: downgrade
    downgradeTo: claude-sonnet-4-6
  - amountCents: 2000    # $20/day hard cap
    window: per_day
    action: block
  - amountCents: 200     # $2/minute burst guard
    window: per_minute
    action: block

Disable temporarily

export AGENTGUARD_DISABLE=1   # plugin loads but does nothing

Per-agent spend caps

There is no per-cap scope: field. A SpendCap is amountCents, window, action, and optionally downgradeTo / reason. Spend is bucketed by the policy's scope, not by anything on the individual cap, so one policy file is one budget and a cap cannot carve itself out of it.

To give each bridge its own budget, run one Hermes process per bridge, each with its own HERMES_HOME (so it gets its own policy.yaml and its own ledger) and a matching HERMES_AGENT_ID:

# Telegram bridge process
export HERMES_HOME=~/.hermes-telegram
export HERMES_AGENT_ID=hermes-telegram

# Discord bridge process
export HERMES_HOME=~/.hermes-discord
export HERMES_AGENT_ID=hermes-discord

# Cron job
export HERMES_HOME=~/.hermes-cron
export HERMES_AGENT_ID=hermes-cron

Then pin each policy to that agent:

# ~/.hermes-telegram/agentguard/policy.yaml
scope:
  tenantId: hermes-personal
  agentId: hermes-telegram   # must equal that process's HERMES_AGENT_ID

caps:
  - amountCents: 1000        # $10/day for the Telegram bridge
    window: per_day
    action: block

The two agentId values have to match. A policy applies only to calls whose scope matches every field the policy sets, so a policy.scope.agentId naming an agent the process is not running as means the policy never matches and every call is allowed. Omit agentId from scope: (the bootstrapped default) and the policy governs whatever that process runs as.

Spend windows are tracked in-process, so two processes never share a live budget even if you point them at the same policy. The signed ledger on disk is the durable record.

Verify the audit log

Every decision is appended to ~/.hermes/agentguard/decisions.ndjson (one signed, hash-chained JSON entry per line). The file appears on the first guarded LLM call and survives restarts, so the chain keeps extending across runs.

from agentguard_spend import verify_chain
import pathlib, json

public_key = pathlib.Path("~/.hermes/agentguard/public.key").expanduser().read_bytes()
entries_path = pathlib.Path("~/.hermes/agentguard/decisions.ndjson").expanduser()
entries = [json.loads(line) for line in entries_path.read_text().splitlines()]
result = verify_chain(entries, public_key)
print("OK" if result.ok else f"Chain broken at #{result.sequence}: {result.reason}")

What this plugin does NOT change in Hermes

  • Hermes's request retry logic
  • Hermes's credential refresh flow
  • Hermes's interrupt / cancel pattern
  • Hermes's MCP / tool-call layer
  • Any of the existing skills

Strictly an LLM-call-intercept layer between Hermes and the Anthropic/OpenAI wire.

Localization

Block traces render in the active locale:

  • 🇺🇸 en-US (default)
  • 🇲🇽 🇦🇷 🇨🇴 🇨🇱 es-419 (Latin American Spanish)
  • 🇧🇷 pt-BR (Brazilian Portuguese)

Resolution chain: explicit AGENTGUARD_LOCALE env var → LC_ALL / LC_MESSAGES / LANG → system locale → en-US fallback.

License

BUSL-1.1. Free for production deployments processing up to 10,000 enforcement calls per calendar month. Commercial licensing for higher volumes or service redistribution: invest@agentguard.run.

Patents

Protected by 7 U.S. patent-pending applications (App. Nos. 63/983,615; 63/983,621; 63/983,843; 63/984,626; 64/071,781; 64/071,789; plus DV-2026-007 in active filing). See https://agentguard.run/patents.

Links

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

agentguard_spend_hermes-0.2.1.tar.gz (17.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

agentguard_spend_hermes-0.2.1-py3-none-any.whl (14.9 kB view details)

Uploaded Python 3

File details

Details for the file agentguard_spend_hermes-0.2.1.tar.gz.

File metadata

  • Download URL: agentguard_spend_hermes-0.2.1.tar.gz
  • Upload date:
  • Size: 17.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/7.0.0 CPython/3.11.14

File hashes

Hashes for agentguard_spend_hermes-0.2.1.tar.gz
Algorithm Hash digest
SHA256 843d11372cef66b119a63f42ab47a82286c1207e87820736f6a08ff067a6ee6d
MD5 a017e0359228d957c90edacc5ad0ff30
BLAKE2b-256 3e214e18201da300d8eaf9ba95dcc4649e55735f98ecb599a3149f62ffc482ab

See more details on using hashes here.

File details

Details for the file agentguard_spend_hermes-0.2.1-py3-none-any.whl.

File metadata

File hashes

Hashes for agentguard_spend_hermes-0.2.1-py3-none-any.whl
Algorithm Hash digest
SHA256 7bb6b0b81a31e0f1c6423d1c30b570737e972a96797e711a2b25e5a602aa1c8c
MD5 65737a5b5cf4f108c0bf6d1ede39c4c3
BLAKE2b-256 e8427422b45a6fa96ed80a756e888218733778c1a64ffee96cf396c86f6b64d0

See more details on using hashes here.

Release history Release notifications | RSS feed

0.2.3

2 files

0.2.2

2 files

This release

0.2.1 This release

2 files

0.2.0

2 files

0.1.4

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page