hermes-agent/gateway
Soju06 7b3dcee928 feat(cache): persist the exact bytes sent to the API in an api_content sidecar
The first LLM call of every gateway turn gets ~0% provider prompt-cache
hit rate (in-turn calls: 97-99%) because the bytes sent for a turn's
user message are not the bytes replayed next turn: memory-prefetch and
pre_llm_call context are injected into the API copy only, the #48677
persist override writes cleaned content to the DB row, and
get_messages_as_conversation sanitize/strips user and assistant content
on load. Any of these diverges the request prefix at that message and
re-prefills everything after it — measured 27.9s for the first call vs
2.4-5.8s cached at a median ~156k-token context.

Persist what you send: a nullable messages.api_content column stores the
exact content string sent to the API when it differs from the clean
stored content, and replay substitutes it verbatim (no sanitize, no
strip). The injection composition lives in one helper
(turn_context.compose_user_api_content); the turn prologue stamps its
output onto the live user message, the api_messages build sends the
stamped bytes, and every outgoing copy pops the field so it never
reaches a provider. The crash-resilience user-turn persist moves after
prefetch/pre_llm_call so the user row is written once with its final
sidecar; _ensure_db_session stays before preflight compression (session
rotation needs the parent row under PRAGMA foreign_keys=ON). The
current-turn index trackers are re-anchored after compaction rebuilds
the message list, in-place preflight compaction backfills the stamp onto
the already-inserted row, and gateway replay forwards the sidecar only
when the replay pipeline did not rewrite the content. Rewrite paths that
would leave stale bytes (historical image strip, merge-summary-into-
tail, consecutive-user repair merge, stale-confirmation redaction) drop
the sidecar; the chat-completions transport and the max-iterations
summary path strip it defensively. codex_app_server and MoA turns are
excluded from stamping because their wire bytes differ from the
composition. A missing or dropped sidecar degrades to today's behavior
(one cache-boundary miss), never to wrong content.
2026-07-19 08:25:35 +05:30
..
assets chore: limit generic status phrases to long-running notifications 2026-07-05 06:29:26 -07:00
builtin_hooks remove: BOOT.md built-in hook (#17093) 2026-04-28 09:50:27 -07:00
platforms fix(gateway): invalidate pending STT cache when media merges into event 2026-07-19 07:27:29 +05:30
relay fix(relay): normalize a 0/negative max_message_length at the descriptor boundary 2026-07-16 07:21:23 -07:00
__init__.py docs(gateway): mention Weixin in gateway help and docstrings 2026-05-12 17:08:51 -07:00
authz_mixin.py fix(gateway): multiplex secret_scope for authz, Slack, webhooks 2026-07-16 05:39:58 -07:00
cgroup_cleanup.py fix: satisfy ruff encoding + windows-footgun lints for cgroup reaper 2026-06-28 02:05:50 -07:00
channel_directory.py fix(gateway): offload channel directory session scans 2026-07-09 06:27:04 -07:00
code_skew.py fix(gateway): refuse model switch on stale checkout to avoid env_float ImportError 2026-06-24 04:16:54 +05:30
config.py feat(gateway): live per-tool status line on Slack 2026-07-18 12:28:59 -07:00
cwd_placeholder.py fix(gateway): resolve terminal.cwd placeholders per backend and mount mode 2026-07-04 13:28:47 -07:00
dead_targets.py fix(gateway): skip confirmed-dead delivery targets (deleted groups, blocked bots) (#55115) 2026-06-29 13:23:29 -07:00
delivery.py refactor(gateway): share error-text blob between not_found classifiers 2026-07-01 15:11:38 +05:30
display_config.py feat(gateway): live per-tool status line on Slack 2026-07-18 12:28:59 -07:00
drain_control.py feat(gateway): suppress home-channel shutdown broadcast on flagged drains (#54824) 2026-06-29 12:18:11 -07:00
hooks.py feat(hooks): expose thread_id and chat_type in agent:start/end context (#41672) 2026-06-07 19:16:36 -07:00
kanban_watchers.py fix(kanban): route notifier wake via profile chokepoint; harden review findings 2026-07-02 00:05:48 +05:30
memory_monitor.py Port from cline/cline#10343: periodic gateway memory logging (#27102) 2026-05-16 12:55:23 -07:00
message_timestamps.py feat(gateway): inject stable human-readable message timestamps 2026-06-16 15:49:59 -07:00
mirror.py refactor: consolidate gateway session metadata into state.db (#58899) 2026-07-05 14:01:03 -07:00
pairing.py fix: merge split gateway pairing stores 2026-07-07 02:18:17 -07:00
platform_registry.py perf(startup): lazy-load gateway platform adapters (#54448) 2026-06-28 15:11:59 -07:00
profile_routing.py fix(gateway): profile routing — conjunctive matching + universal gateway_runner 2026-07-15 09:50:05 -07:00
readiness.py fix(gateway): ground readiness in live runtime state 2026-07-11 08:42:21 -07:00
response_filters.py fix(gateway): tolerate punctuation on silence markers 2026-07-05 02:12:26 -07:00
restart.py fix(gateway): preserve external supervisor ownership 2026-07-16 05:08:56 -07:00
restart_loop_guard.py fix(gateway,cron): guard cron model-tool path + add auto-resume loop breaker (#30719) 2026-07-01 02:48:36 -07:00
rich_sent_store.py style(profile): frame comments around what the code does 2026-06-30 15:30:06 -07:00
run.py feat(cache): persist the exact bytes sent to the API in an api_content sidecar 2026-07-19 08:25:35 +05:30
runtime_footer.py chore: prune unused imports and duplicate import redefinitions 2026-05-28 22:26:25 -07:00
scale_to_zero.py feat(gateway): scale-to-zero idle detection + dormant-quiesce (Phase 0) 2026-06-24 18:47:18 -07:00
session.py feat(cache): persist the exact bytes sent to the API in an api_content sidecar 2026-07-19 08:25:35 +05:30
session_context.py fix(delegate): declare stateless channel in one-shot and cron so delegate_task returns results 2026-07-18 00:05:25 -07:00
shutdown_forensics.py chore: ruff auto-fixes — collapsible-else-if, if-stmt-min-max, dict.fromkeys (#23926) 2026-05-11 11:03:29 -07:00
shutdown_watchdog.py fix: drain logs + release PID/lock before watchdog os._exit, drop infographic PNG 2026-07-18 19:53:00 +05:30
slash_access.py feat(gateway): per-platform admin/user split for slash commands (salvage of #4443) (#23373) 2026-05-10 12:33:54 -07:00
slash_commands.py feat(cache): persist the exact bytes sent to the API in an api_content sidecar 2026-07-19 08:25:35 +05:30
status.py fix(gateway): launchd ThrottleInterval + portable respawn-storm circuit breaker 2026-07-18 19:38:21 +05:30
status_phrases.py chore: limit generic status phrases to long-running notifications 2026-07-05 06:29:26 -07:00
sticker_cache.py fix: guard yaml.safe_load, flock unlock, TOCTOU races, and atomic writes 2026-05-19 00:12:41 -07:00
stream_consumer.py fix(discord): persist streamed final delivery 2026-07-18 14:01:33 -07:00
stream_dispatch.py feat(gateway): structured stream-event protocol + Telegram draft formatting parity (#37250) 2026-06-02 00:33:50 -07:00
stream_events.py feat(gateway): structured stream-event protocol + Telegram draft formatting parity (#37250) 2026-06-02 00:33:50 -07:00
systemd_notify.py fix(gateway): recover Discord websocket and event-loop stalls 2026-07-18 20:01:55 +05:30
whatsapp_identity.py fix(whatsapp): resolve LID aliases on modern platforms/ session layout 2026-06-28 02:05:26 -07:00