Skip to main content

hermes-jev-compact

Smarter context compression for Hermes Agent: stale tool calls are scored by TypeSafe Jev — a fast decision model built for exactly this kind of keep-or-drop judgment — instead of being pruned by age alone. What Jev says still matters stays; the dead weight goes.

Opt-in per profile (context.engine: jev). Worst case is exactly the built-in behavior: any Jev failure — transport, validation, timeout, cancel, missing key — falls back to the inherited deterministic prune.

why

The built-in compressor prunes old tool results blindly: beyond the protected tail, everything is truncated by position. That is safe, but it throws away results the conversation still depends on (a test failure three turns back, the file listing that motivated the current edit) while keeping verbose output nobody will ever reference again.

Jev fixes the targeting. For every stale tool call/result unit it answers two calibrated questions — does the call still matter? does its full output still matter? — against the whole conversation as state. The result:

  • fewer broken continuations — results the next step actually needs survive compression instead of being truncated by age.
  • smaller contexts — high-confidence dead weight (passing test logs, superseded listings, retried commands) is dropped entirely, not kept as stubs.
  • cheap judgments, not LLM summaries — Jev returns probabilities in ~70–500 ms at a fraction of a cent per prune; no generative model is consulted during the prune path.

how it works

JevContextCompressor subclasses the built-in ContextCompressor and overrides exactly one seam — _prune_old_tool_results (full-compression phase 1). The hot proactive path (prune_tool_results_only, documented deterministic/no-LLM) is untouched: it bypasses Jev entirely.

One prune, end to end:

  1. Candidates. Paired tool call + result before the prune boundary, above the char floor. Never candidates: system rows, index 0, the protected tail, unpaired calls, unusable result shapes (bytes/numbers), duplicate or out-of-order pairs (ambiguous address — fail closed).
  2. State. The whole transcript with result bodies replaced by short notes (ok, 9000 chars (omitted)) is fitted into max_state_tokens through a shrink ladder: cap call inputs → abridge long texts → collapse old texts → compact old calls → drop text-only rows → merge call runs. Pinned rows (index 0 + recent tail) shrink last.
  3. Questions. Two noul (yes/no probability) questions per call — keep the call? keep its full result? — batched into max_request_tokens and asked sequentially (so cancellation stops between asks).
  4. Decisions. keep / drop_result (truncate to a head + marker) / drop_call (remove result rows, strip the call). Pinned calls always keep.
  5. Commit gates. Output is validity-checked (no orphans either way, no duplicates, no out-of-order pairs, clean row shapes) and must shrink the transcript by ≥25% (TS reductionRatio rule) — otherwise the deterministic prune runs instead. The deterministic demote passes (dedup, arg truncation, image retire, stubs) still run after a Jev pass, so nothing the built-in compressor did is lost.

State shaping is a port of tamara/fast-jev-compaction (MIT) — see THIRD_PARTY_NOTICES.md. Deliberate divergences from upstream: sequential batches (cancellation), OpenAI row adaptation, and the 25% rule enforced in-engine rather than by the caller.

install

Works with any System One-compatible endpoint. TypeSafe's own API is the reference: get a key at console.typesafe.ai, put it in ~/.hermes/.env as TYPESAFE_API_KEY. Self-hosted routers relaying the same {model, state, questions} shape work too — just point base_url at them.

/path/to/hermes-python -m pip install hermes-jev-compact
hermes plugins enable hermes-jev-compact --no-allow-tool-override

Then opt in per profile and /reset:

context:
  engine: jev
plugins:
  entries:
    hermes-jev-compact:
      settings:
        base_url: https://api.typesafe.ai/v1   # any POST {base}/systemone endpoint
        api_key_env: TYPESAFE_API_KEY              # env var holding the key
        jev_model: jev-latest
        keep_threshold: 0.5        # noul >= this keeps the unit
        max_state_tokens: 25000    # transcript budget per request
        max_request_tokens: 30000  # state + questions budget
        truncate_head_chars: 300   # kept head of a dropped result
        request_timeout_s: 30
        min_result_chars: 8000     # results below this never become candidates

compressor (default) bypasses plugins entirely; jev only activates when named. To disable: hermes config set context.engine compressor (and optionally hermes plugins disable hermes-jev-compact), then /reset.

observability

Per-agent counters live on the compressor: jev_calls (requests made), jev_pruned_units (units dropped/truncated), jev_fallbacks (times the built-in prune ran instead). A successful pass logs its score/drop counts and fit stage; every fallback logs its reason.

development

uv sync --extra dev --locked
uv run pytest
uv run black --check src tests
uv run mypy src

Release files for hermes-jev-compact 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for hermes-jev-compact 0.1.0
File Size Uploaded
hermes_jev_compact-0.1.0.tar.gz 73.0 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for hermes-jev-compact 0.1.0
File Interpreter ABI Platform
hermes_jev_compact-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.4 kB

Release files / hermes_jev_compact-0.1.0.tar.gz

Download URL hermes_jev_compact-0.1.0.tar.gz
Size 73.0 kB
Tags Source
SHA-256 checksum
How to use checksums
d084e7fb0aab26e158d7b79d3d77e945d7b00129a49ccc765f473423f9ea2ba2
BLAKE2b-256 checksum
How to use checksums
9a7fafdfe74d0d096e3e640d66db963e1590300f33e4c3a295b8e954ca756e9c
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release files / hermes_jev_compact-0.1.0-py3-none-any.whl

Download URL hermes_jev_compact-0.1.0-py3-none-any.whl
Size 29.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d2886bb452a76563053814a53975d067482132ed5564d15c5c77da231d5bfb28
BLAKE2b-256 checksum
How to use checksums
d1b17e02a4d383abb0b817a4150a4bb17667e970cc1e7a89bd30f0078592afc7
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2026.

Transparency log

Release history Release notifications | RSS feed

0.2.1

2 release files

0.2.0

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

This release

0.1.0 This release

2 release 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