{"id":49371058,"url":"https://github.com/mssteuer/lossless-hermes-py","last_synced_at":"2026-04-27T23:04:16.048Z","repository":{"id":351594264,"uuid":"1211248931","full_name":"mssteuer/lossless-hermes-py","owner":"mssteuer","description":"Lossless Context Management (LCM) for Hermes Agent — DAG-based conversation summarization that never forgets. Python port of lossless-claw.","archived":false,"fork":false,"pushed_at":"2026-04-15T18:27:13.000Z","size":107,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-15T18:27:27.744Z","etag":null,"topics":["ai-agents","claude-code","context-management","dag","llm","lossless","python","sqlite","summarization"],"latest_commit_sha":null,"homepage":null,"language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mssteuer.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-15T07:53:05.000Z","updated_at":"2026-04-15T18:27:17.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/mssteuer/lossless-hermes-py","commit_stats":null,"previous_names":["mssteuer/lossless-hermes-py"],"tags_count":null,"template":false,"template_full_name":null,"purl":"pkg:github/mssteuer/lossless-hermes-py","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mssteuer%2Flossless-hermes-py","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mssteuer%2Flossless-hermes-py/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mssteuer%2Flossless-hermes-py/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mssteuer%2Flossless-hermes-py/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mssteuer","download_url":"https://codeload.github.com/mssteuer/lossless-hermes-py/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mssteuer%2Flossless-hermes-py/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32358511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-27T20:07:02.737Z","status":"ssl_error","status_checked_at":"2026-04-27T20:07:00.910Z","response_time":128,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ai-agents","claude-code","context-management","dag","llm","lossless","python","sqlite","summarization"],"created_at":"2026-04-27T23:04:14.491Z","updated_at":"2026-04-27T23:04:16.039Z","avatar_url":"https://github.com/mssteuer.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"# lossless-hermes-py\n\n[![PyPI version](https://img.shields.io/pypi/v/lossless-hermes-py.svg)](https://pypi.org/project/lossless-hermes-py/)\n[![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](https://opensource.org/licenses/MIT)\n\n**DAG-based lossless context management for LLM conversations. Never lose a message — summarize them into a directed acyclic graph.**\n\nA Python port of [lossless-claw](https://github.com/Martian-Engineering/lossless-claw) for use with [Hermes Agent](https://hermes.nousresearch.com) or as a standalone library.\n\n---\n\n## What It Does\n\nLong conversations with LLMs hit context window limits. The typical solution is to truncate or naively summarize, losing information permanently. Lossless Context Management (LCM) takes a different approach: it builds a **directed acyclic graph of summaries** that compresses older messages while preserving the ability to drill back into any detail.\n\nYour conversation never loses information. It just gets more compact.\n\nSee the animated visualization at [losslesscontext.ai](https://losslesscontext.ai).\n\n## How It Works\n\nLCM operates in two compaction passes that build a summary DAG:\n\n**Leaf pass** — When the context window fills up, raw messages (excluding a protected \"fresh tail\" of recent messages) are chunked and summarized into **leaf nodes** at depth 0. Each leaf summary covers a group of messages and links back to the originals.\n\n**Condensed pass** — When enough leaf summaries accumulate, they are themselves summarized into **condensed nodes** at depth 1. This process repeats upward: depth-1 summaries get condensed into depth-2, and so on. The result is a tree-like DAG where the root captures the entire conversation at high compression, and any branch can be expanded to recover full detail.\n\n**Context assembly** reconstructs the optimal prompt by combining:\n- The highest-level summaries (covering the full history compactly)\n- The fresh tail (recent messages kept verbatim for continuity)\n\n**Cache-aware compaction** adapts to prompt caching behavior. When the cache is hot (high hit rate), compaction backs off to avoid invalidating cached prefixes. When the cache is cold, compaction runs more aggressively.\n\n**Agent tools** (`lcm_grep`, `lcm_expand`, `lcm_describe`) let the LLM search and drill into compacted history on demand, recovering detail without keeping everything in context.\n\n## Installation\n\n### Hermes Agent Plugin (recommended)\n\n```bash\nhermes plugins install mssteuer/lossless-hermes-py\n```\n\nThen enable the engine in `~/.hermes/config.yaml` (top level, not under `agent:`):\n\n```yaml\ncontext:\n  engine: lossless-hermes\n```\n\n**(Optional)** Configure a dedicated summarization model via environment variables in `~/.hermes/.env`:\n\n```bash\nLCM_SUMMARY_MODEL=gpt-4o-mini\nLCM_SUMMARY_PROVIDER=openai\n```\n\nOr edit the plugin's `plugin.yaml` directly:\n\n```bash\nnano ~/.hermes/plugins/lossless-hermes/plugin.yaml\n```\n\nRestart the gateway:\n\n```bash\nhermes gateway restart\n```\n\nThe agent will now have `lcm_grep`, `lcm_describe`, and `lcm_expand` tools available.\n\n### Via pip\n\n```bash\npip install lossless-hermes-py\n```\n\nThis is useful for standalone library usage (see below) or if you prefer managing Python packages separately. For use with Hermes, the `hermes plugins install` method above is simpler.\n\n### Standalone Usage\n\nLCM also works as a standalone library without Hermes:\n\n```python\nfrom lossless_hermes import LcmContextEngine\n\nengine = LcmContextEngine(\n    model=\"gpt-4o-mini\",\n    provider=\"openai\",\n    config_context_length=128000,\n)\n\n# Start a session\nengine.on_session_start(\"my-session\")\n\n# Check if compaction is needed\nif engine.should_compress(prompt_tokens=100000):\n    compressed = engine.compress(messages, current_tokens=100000)\n```\n\n## Configuration\n\nSettings are resolved with three-tier precedence: **environment variables \u003e plugin.yaml \u003e defaults**.\n\n### Key Settings\n\n| Setting | Default | Description |\n|---|---|---|\n| `enabled` | `true` | Enable/disable LCM |\n| `context_threshold` | `0.75` | Fraction of context window that triggers compaction |\n| `fresh_tail_count` | `64` | Number of recent messages kept verbatim |\n| `fresh_tail_max_tokens` | `null` | Optional token budget cap for fresh tail |\n| `leaf_chunk_tokens` | `20000` | Max tokens per leaf chunk |\n| `leaf_target_tokens` | `2400` | Target summary size for leaf nodes |\n| `condensed_target_tokens` | `2000` | Target summary size for condensed nodes |\n| `leaf_min_fanout` | `8` | Minimum messages per leaf chunk |\n| `condensed_min_fanout` | `4` | Minimum summaries per condensed chunk |\n| `condensed_min_fanout_hard` | `2` | Hard minimum for condensed chunks |\n| `incremental_max_depth` | `1` | Max depth levels to compact per pass |\n| `summary_provider` | `\"\"` | LLM provider for summarization (falls back to host agent's provider) |\n| `summary_model` | `\"\"` | Model for summarization (falls back to host agent's model) |\n| `summary_timeout_ms` | `60000` | Timeout for summarization calls |\n| `circuit_breaker_threshold` | `5` | Consecutive failures before circuit opens |\n| `circuit_breaker_cooldown_ms` | `1800000` | Cooldown before retrying after circuit break (30 min) |\n\n### Cache-Aware Compaction\n\n```yaml\nconfig:\n  cache_aware_compaction:\n    enabled: true\n    cache_ttl_seconds: 300\n    max_cold_cache_catchup_passes: 2\n    hot_cache_pressure_factor: 4\n    hot_cache_budget_headroom_ratio: 0.2\n    cold_cache_observation_threshold: 3\n```\n\n### Dynamic Leaf Chunk Sizing\n\n```yaml\nconfig:\n  dynamic_leaf_chunk_tokens:\n    enabled: true\n    max: 40000\n```\n\n### Environment Variables\n\nAll config keys can be set via environment variables with the `LCM_` prefix:\n\n```bash\nexport LCM_SUMMARY_MODEL=\"gemini-2.5-flash\"\nexport LCM_FRESH_TAIL_COUNT=32\nexport LCM_CONTEXT_THRESHOLD=0.8\n```\n\n## Tools\n\nLCM exposes three tools that the agent can call to interact with compacted history:\n\n### `lcm_grep`\n\nSearch conversation history and summaries using FTS5 full-text search or regex.\n\n```json\n{\n  \"query\": \"database migration strategy\",\n  \"mode\": \"full_text\",\n  \"include_messages\": true,\n  \"include_summaries\": true,\n  \"limit\": 20\n}\n```\n\n### `lcm_describe`\n\nGet the current LCM state: summary statistics, DAG depth, message counts, recent compaction activity.\n\n```json\n{\n  \"include_stats\": true,\n  \"include_recent\": true\n}\n```\n\n### `lcm_expand`\n\nDrill into specific content. Expand a message to see its full text, a summary to see its children and linked messages, or search for related content across conversations.\n\n```json\n{\n  \"target_type\": \"summary\",\n  \"target_id\": \"abc123\"\n}\n```\n\n```json\n{\n  \"target_type\": \"related\",\n  \"query\": \"authentication flow\",\n  \"limit\": 10\n}\n```\n\n## Architecture\n\n```\nsrc/lossless_hermes/\n    __init__.py          # LcmContextEngine — main plugin class, Hermes integration\n    compaction.py        # CompactionEngine — leaf/condensed passes, cache-aware policy\n    assembler.py         # ContextAssembler — reconstructs optimal context from DAG\n    summarizer.py        # LLM summarization with circuit breaker pattern\n    retrieval.py         # RetrievalEngine — FTS5 search, related content discovery\n    tokens.py            # Unicode-aware token estimation (CJK, emoji)\n    tools.py             # lcm_grep, lcm_describe, lcm_expand tool implementations\n    db/\n        config.py        # Three-tier config resolution (env \u003e yaml \u003e defaults)\n        connection.py    # SQLite connection management (WAL mode)\n        migration.py     # Schema migrations\n    store/\n        conversation.py  # ConversationStore — messages, parts, sequences\n        summary.py       # SummaryStore — DAG nodes, edges, depth stats\n        identity.py      # Content identity hashing for deduplication\n```\n\n### Storage\n\nSQLite with WAL mode for concurrent reads. FTS5 virtual tables for full-text search across messages and summaries. All data is local — no external services beyond the LLM provider.\n\n## Differences from the TypeScript Version\n\nThis is a Python port of the original [lossless-claw](https://github.com/Martian-Engineering/lossless-claw) TypeScript implementation. Key adaptations:\n\n- **Target platform**: [Hermes Agent](https://hermes.nousresearch.com) (NousResearch) Python plugin system instead of OpenClaw\n- **Plugin interface**: Implements the Hermes `ContextEngine` base class with `register()` entry point\n- **LLM calls**: Provider-agnostic via configurable summarizer rather than being tied to a specific SDK\n- **Default summarization model**: Gemini 2.5 Flash (configurable to any model)\n- **Async model**: Synchronous by default (matching the Hermes plugin interface) rather than async-first\n- **Config resolution**: Three-tier env/yaml/defaults pattern adapted for Python conventions\n- **Token estimation**: Custom Unicode-aware estimator (`tokens.py`) with CJK and emoji handling\n- **Database**: Same SQLite/FTS5 approach, using Python's built-in `sqlite3` module\n- **Standalone support**: Works both as a Hermes plugin and as a standalone library — the `ContextEngine` import is optional\n\nThe core algorithm — DAG-based compaction with leaf and condensed passes, fresh-tail protection, cache-aware compaction policies — is a faithful port of the original.\n\n## Credits\n\n- **[lossless-claw](https://github.com/Martian-Engineering/lossless-claw)** by Josh Lehman / [Martian Engineering](https://github.com/Martian-Engineering) (MIT License) — the original TypeScript implementation this project is ported from\n- **[The LCM Paper](https://papers.voltropy.com/LCM)** by Voltropy — the academic foundation for lossless context management\n- **[Hermes Agent](https://github.com/NousResearch/hermes)** by NousResearch — the target platform whose context engine plugin system this integrates with\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmssteuer%2Flossless-hermes-py","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmssteuer%2Flossless-hermes-py","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmssteuer%2Flossless-hermes-py/lists"}