hermes-agent/agent
Michael Jordan 186cad02f9 feat(agent): per-turn micro-compaction to amortize context compression
Batch compaction pauses a session for one large summarization once the
window fills. Micro-compaction spreads that cost out: after each completed
turn, `finalize_turn` folds the single oldest un-absorbed exchange
(assistant message plus its tool results) into a rolling summary, so the
work happens in small increments during post-turn idle time instead of one
long stall.

Mechanics:
  - a cursor tracks the first message not yet absorbed, recovered from the
    transcript's last summary marker when in-memory state is unavailable;
  - protected head and tail windows are never touched, so the system prompt
    and recent turns stay verbatim;
  - the absorbed span is replaced by a marker carrying the usual
    `_compressed_summary` metadata, so resume, handoff and `/compress`
    treat it exactly like a batch summary;
  - `archive_and_compact` keeps the session DB in step, otherwise the
    append-only flush would leave the original rows active and a resume
    would double-load both summary and originals;
  - when the rolling summary itself passes a token threshold it is
    defragged: re-summarized in one shot and the cursor jumps to the tail;
  - an exchange the summarizer can't handle is retried a bounded number of
    times, then skipped, so one poison exchange can't stall every turn.

Keep only the newest summary marker. The rolling summary is cumulative, so
each marker already contains everything the previous ones held; leaving them
stacked near-duplicate copies of the same text, each with its own heading and
end-marker scaffolding, and the transcript grew on every turn instead of
shrinking. Measured over six turns on a 12-exchange conversation with tool
output: 4104 -> 4797 tokens before, 4104 -> 2572 after.

Off switch: `compression.micro_compact: false` (default on).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-31 17:44:19 +05:30
..
lsp perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
monitoring feat(monitoring): add hermes.gateway.background_delegations (unit/slot count) 2026-07-25 02:30:20 +00:00
pet fix: remove dead f-string prefixes via ruff F541 (216 sites) (#52336) 2026-07-05 13:42:46 -07:00
proxy_sources fix(windows): sweep remaining unguarded text-mode subprocess sites codebase-wide 2026-07-24 11:45:57 -07:00
secret_sources refactor: single build_subprocess_env() factory for all child-process spawns (profile + secret-scrub single owner) 2026-07-29 10:14:11 -07:00
transports chore: remove unused imports and dead locals (ruff F401/F841 sweep) 2026-07-29 11:53:39 -07:00
__init__.py fix(agent): preload jiter native parser 2026-05-28 00:20:11 -07:00
account_usage.py fix(auth): detect upstream Codex quota resets and lift stale pool cooldowns (#69494) 2026-07-22 10:58:22 -07:00
agent_init.py feat(agent): per-turn micro-compaction to amortize context compression 2026-07-31 17:44:19 +05:30
agent_runtime_helpers.py refactor(agent): single-owner call_id + reasoning_content sanitization policies (wire-parity verified) 2026-07-29 12:29:39 -07:00
anthropic_adapter.py nous portal anthropic wire 2026-07-27 11:53:48 -04:00
async_utils.py refactor(gateway): dedupe detached-task consumer + reconnect backoff policy 2026-07-18 20:01:55 +05:30
aux_accounting.py feat(analytics): record auxiliary model usage per task in session accounting (#65537) 2026-07-16 04:23:12 -07:00
auxiliary_client.py Revert "remove Vercel AI Gateway and Vercel Sandbox (#33067)" 2026-07-29 19:48:37 -07:00
azure_identity_adapter.py
backend_identity.py refactor(fallback): single owner for backend identity and failure-scoped skips 2026-07-26 23:41:54 -07:00
background_review.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
battery.py feat(status-bar): add /battery toggle for a color-coded battery read-out 2026-07-21 13:54:11 -05:00
bedrock_adapter.py feat(bedrock): add Converse API prompt caching (cachePoint) 2026-07-23 11:45:07 -07:00
billing_links.py feat(billing): shared cross-surface out-of-credits signal 2026-07-22 18:08:59 -05:00
billing_usage.py chore: remove unused imports and dead locals (ruff F401/F841 sweep) 2026-07-29 11:53:39 -07:00
billing_view.py chore: remove unused imports and dead locals (ruff F401/F841 sweep) 2026-07-29 11:53:39 -07:00
bounded_response.py fix(agents): bound streaming error-response body reads 2026-07-05 14:00:20 -07:00
browser_provider.py
browser_registry.py style: restore PEP8 blank-line separation after dead-code removal 2026-05-29 04:22:27 -07:00
chat_completion_helpers.py perf(config): stop deepcopying config on per-turn read-only paths 2026-07-29 11:33:41 -07:00
codex_responses_adapter.py refactor(agent): single-owner call_id + reasoning_content sanitization policies (wire-parity verified) 2026-07-29 12:29:39 -07:00
codex_runtime.py chore: remove unused imports and dead locals (ruff F401/F841 sweep) 2026-07-29 11:53:39 -07:00
coding_context.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
context_breakdown.py feat(cli,gateway): unify /context into a visual context-usage breakdown 2026-07-26 18:06:21 -07:00
context_compressor.py feat(agent): per-turn micro-compaction to amortize context compression 2026-07-31 17:44:19 +05:30
context_engine.py fix(context-engine): snapshot select_context read-only inputs; scope on_turn_complete coverage doc 2026-07-23 19:44:35 -07:00
context_references.py fix(context): keep @ref tokens inline instead of stripping them from the prompt 2026-07-27 22:55:18 -05:00
conversation_compression.py fix(compression): copy-on-write in image-shrink recovery so degraded images never reach stored history 2026-07-28 20:04:58 +05:30
conversation_loop.py feat(gateway): iMessage-style message reactions — storage, RPC, agent tool, model context 2026-07-30 00:08:28 -05:00
copilot_acp_client.py fix(core,cli,gateway,plugins): add encoding='utf-8' to read_text() calls 2026-07-24 17:10:39 -07:00
credential_persistence.py feat(auth): make xAI Grok OAuth device-code-only, drop loopback login 2026-07-02 13:17:41 -07:00
credential_pool.py fix: break unbounded 401 retry loop in credential pool OAuth path 2026-07-24 15:50:36 -07:00
credential_sources.py fix(windows): sweep remaining bare read_text/write_text sites + linter rule 2026-07-24 17:10:39 -07:00
credits_tracker.py fix(credits): reintroduce grant_spent, gated on an in-session crossing (#73634) 2026-07-28 21:36:23 +00:00
curator.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
curator_backup.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
delegation_context.py fix(kanban): harden delegated-child mutation boundary 2026-07-23 07:33:36 -07:00
display.py feat(gateway): live per-tool status line on Slack 2026-07-18 12:28:59 -07:00
error_classifier.py fix(errors): log when the empty-stub guard and malformed-body classification fire 2026-07-27 20:27:56 -07:00
errors.py fix(moa): surface stale presets without retries 2026-07-17 13:49:12 -07:00
file_safety.py fix(secrets): harden encrypted Bitwarden cache 2026-07-22 04:40:07 -07:00
gemini_native_adapter.py fix(gemini): sweep hardcoded Gemini default models to gemini-3.6-flash (#32360) 2026-07-28 18:17:56 -07:00
gemini_schema.py fix(gemini): preserve typed enum constraints as strings 2026-07-26 20:59:16 -07:00
i18n.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
image_gen_provider.py feat(image-gen): add image-to-image / editing to image_generate (#48705) 2026-06-18 22:13:07 -07:00
image_gen_registry.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
image_routing.py feat(image_routing): accept vision alias for custom provider models 2026-07-23 08:32:09 -07:00
insights.py perf(state): apply per-call token accounting on a background single-writer queue 2026-07-28 18:47:54 +05:30
iteration_budget.py feat: raise default tool-calling iteration limit from 90 to 500 2026-07-26 12:54:45 -07:00
jiter_preload.py fix(agent): preload jiter native parser 2026-05-28 00:20:11 -07:00
kanban_stop.py follow-up: integrate agent nudge + dispatcher retry docs and tests 2026-07-14 16:47:33 +05:30
learn_prompt.py fix(learn): honor requirements mixed with sources in /learn requests (#55956) 2026-06-30 16:56:01 -07:00
learning_graph.py fix(learning_graph): guard non-dict metadata so /journey can't crash 2026-07-01 16:25:48 -05:00
learning_graph_render.py chore: remove unused imports and dead locals (ruff F401/F841 sweep) 2026-07-29 11:53:39 -07:00
learning_mutations.py refactor(journey): route memory mutations through MemoryStore atomic I/O 2026-06-30 15:16:21 -05:00
lmstudio_reasoning.py fix(lmstudio): clamp max/ultra reasoning effort to LM Studio's ceiling 2026-07-16 07:57:51 -07:00
manual_compression_feedback.py fix(compress): classify unconfirmed lock-acquire failures and cover all manual-compress surfaces 2026-07-23 08:19:14 -07:00
markdown_tables.py
memory_manager.py fix(memory): honor disabled toolsets for provider tools 2026-07-24 13:00:53 +05:30
memory_provider.py fix(backup): capture memory-provider state stored outside HERMES_HOME (#50325) 2026-06-21 12:03:46 -07:00
message_content.py fix(openviking): preserve structured sync attribution 2026-06-19 15:23:41 +08:00
message_sanitization.py refactor(agent): single-owner call_id + reasoning_content sanitization policies (wire-parity verified) 2026-07-29 12:29:39 -07:00
moa_loop.py refactor(moa): co-locate guidance peel with attach, add round-trip contract 2026-07-28 01:10:05 +05:30
moa_trace.py fix(moa): capture streamed aggregator output into full-turn traces (#56312) 2026-07-01 04:07:46 -07:00
model_metadata.py Revert "remove Vercel AI Gateway and Vercel Sandbox (#33067)" 2026-07-29 19:48:37 -07:00
models_dev.py Revert "remove Vercel AI Gateway and Vercel Sandbox (#33067)" 2026-07-29 19:48:37 -07:00
moonshot_schema.py fix(agent): inject empty required array on Moonshot object schemas 2026-07-20 11:05:52 -07:00
nous_rate_guard.py fix: decode config and state files as UTF-8 on non-UTF-8 locales 2026-07-24 17:10:39 -07:00
onboarding.py feat(surfaces): route busy-input corrections through active-turn redirect 2026-07-22 12:10:58 -05:00
oneshot.py feat(agent): one-shot LLM helper + llm.oneshot gateway RPC (#51261) 2026-06-23 08:01:50 +00:00
plugin_llm.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
portal_tags.py feat(portal): ambient conversation context entangles aux/MoA/delegate calls 2026-07-16 01:13:43 -07:00
process_bootstrap.py fix(agent): apply pool-level keepalive to the process_bootstrap sibling builder 2026-07-05 03:14:55 -07:00
prompt_builder.py modernize re-added Vercel integrations: SDK 0.7.2, telemetry off, sibling-site wiring 2026-07-29 19:48:37 -07:00
prompt_caching.py perf(caching): selective copy instead of deepcopy entire history 2026-07-28 20:04:58 +05:30
rate_limit_tracker.py
reactions.py feat(agent): core affection reaction detector + reaction_callback 2026-07-10 05:41:59 -05:00
reasoning_timeouts.py fix(compression): coherent context_length setter — no-op guard, re-floor on new window, un-strandable init log 2026-07-28 20:04:58 +05:30
redact.py fix(tests): eliminate flaky/broken tests — shadow sys.path inserts, unmocked network in compressor tests, stale-SDK feishu pin guard, quadratic redact regexes 2026-07-29 15:12:28 -07:00
relay_llm.py fix(relay): preserve provider stream errors 2026-07-28 09:58:43 -07:00
relay_runtime.py fix(relay): close logical calls in stack order 2026-07-28 10:19:53 -07:00
relay_tools.py Reapply "feat(observability): integrate NeMo Relay runtime and shared metrics" 2026-07-27 21:10:51 -07:00
replay_cleanup.py refactor: shared helpers for api_content sidecar pop/drop/extract 2026-07-19 08:25:35 +05:30
retry_utils.py refactor: single shared Retry-After parser 2026-07-29 10:13:50 -07:00
runtime_cwd.py fix(agent): scope install-tree guard to fallback-picked cwds, allow cli/tui in-tree dev 2026-07-16 04:32:23 -07:00
secret_scope.py fix(secrets): scope BWS-injected provider keys 2026-07-22 04:39:17 -07:00
shell_hooks.py feat(delegate): expose redacted child tool history 2026-07-26 20:36:47 -07:00
skill_bundles.py fix(gateway): apply platform-disabled skill gate to bundle invocations (#59156) 2026-07-05 14:48:11 -07:00
skill_commands.py fix(gateway): project a /skill turn onto its invocation for every client 2026-07-28 03:44:17 -05:00
skill_preprocessing.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
skill_utils.py Merge origin/main into feat/hsp-sync-client 2026-07-29 13:01:36 -07:00
ssl_guard.py fix(ssl): detect and repair a missing certifi cacert.pem via existing venv-repair infra 2026-07-24 15:53:38 -07:00
ssl_verify.py fix(agent): honor custom CA certs on aux client + harden TLS resolution 2026-07-02 04:51:56 +05:30
stream_diag.py feat(agent): buffer retry/fallback status, surface only on terminal failure (#33816) 2026-05-28 04:53:27 -07:00
stream_single_writer.py fix(streaming): make the single-writer fence best-effort so a missing guard can't crash a turn (#66448) 2026-07-17 18:31:09 +00:00
subagent_lifecycle.py chore: remove unused imports and dead locals (ruff F401/F841 sweep) 2026-07-29 11:53:39 -07:00
subdirectory_hints.py fix(subdirectory_hints): catch RuntimeError from Path.expanduser() 2026-07-01 04:55:15 -07:00
subscription_view.py feat(cli): plan catalog on Free + plan= deep link + top-up/auto-refill copy split (#68689) 2026-07-22 08:11:09 +05:30
system_prompt.py refactor(agent): share static-prefix reconstruction, memoize failed rebuilds 2026-07-28 01:10:05 +05:30
think_scrubber.py fix(agent): re-arm think scrubber boundary after stream flush 2026-07-16 01:07:29 +05:30
thinking_timeout_guidance.py fix(agent): detect thinking-timeout for reasoning models and surface actionable guidance instead of misleading file-write advice 2026-06-25 19:00:48 -07:00
thread_scoped_output.py fix(bg-review): scope stdout/stderr silencing to the worker thread (#55966) 2026-06-30 17:28:33 -07:00
title_generator.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
tool_dispatch_helpers.py fix(agent): canonicalise paths in parallel-batch planner to prevent same-file concurrent mutation 2026-07-16 04:26:32 -07:00
tool_executor.py refactor(agent): remove the inter-tool delay 2026-07-29 15:21:26 -07:00
tool_guardrails.py refactor(guardrails): make runaway-loop caps per-turn, not session-total 2026-07-26 21:27:45 -07:00
tool_result_classification.py fix(agent): preserve none vs unknown tool effects (#61783) 2026-07-11 05:41:58 -07:00
trace_upload.py fix(windows): sweep remaining unguarded text-mode subprocess sites codebase-wide 2026-07-24 11:45:57 -07:00
trajectory.py
transcription_provider.py
transcription_registry.py fix(deepinfra): harden multimodal provider routing 2026-07-14 02:59:39 +05:30
tts_provider.py
tts_registry.py feat(providers): Support DeepInfra as an LLM provider 2026-07-14 02:59:39 +05:30
turn_context.py Merge upstream main into fix/hermes-relay-anthropic-context 2026-07-28 08:10:58 -07:00
turn_finalizer.py feat(agent): per-turn micro-compaction to amortize context compression 2026-07-31 17:44:19 +05:30
turn_retry_state.py feat(agent): add active-turn redirect core primitive 2026-07-22 12:02:40 -05:00
turn_summary.py fix(cli): report unknown line deltas for content-free diffs instead of +0 -0 2026-07-26 17:47:51 -07:00
usage_pricing.py Revert "remove Vercel AI Gateway and Vercel Sandbox (#33067)" 2026-07-29 19:48:37 -07:00
verification_evidence.py fix(state): make journal mode canonical and behaviorally verified 2026-07-29 18:13:09 -07:00
verification_stop.py flux3 messaging system fixes 2026-07-30 15:20:09 -07:00
verify_hooks.py feat(agent): add pre_verify hook and verify-on-stop coding guidance 2026-06-30 00:59:29 -05:00
vertex_adapter.py security(vertex): route credential/project/region resolution through the profile secret scope 2026-07-02 06:07:56 +05:30
video_gen_provider.py feat(providers): Support DeepInfra as an LLM provider 2026-07-14 02:59:39 +05:30
video_gen_registry.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00
web_search_provider.py fix(web): widen config-aware env resolution to exa/parallel/tavily/brave-free providers 2026-07-06 02:42:24 -07:00
web_search_registry.py perf: use load_config_readonly() at read-only call sites in agent/ 2026-07-29 15:28:15 -07:00