mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-07-23 16:36:23 +00:00
test(gateway): pin routine-suppression + visible-carve-out contracts
- Iterate ROUTINE_COMPRESSION_STATUS_SAMPLES (formatted from the source constants the emit sites use) through _prepare_gateway_status_message on every chat platform — emission-wording drift now fails the suite without re-copying literals. - Extend the pinned NOISY_STATUS_MESSAGES with the buffered retry chatter and post-#69332 wordings. - New VISIBLE_COMPRESSION_MESSAGES negative suite: manual /compress headlines and abort/failure notices must never be swallowed by the widened regex.
This commit is contained in:
parent
9981242f88
commit
fae3ba2c44
1 changed files with 72 additions and 0 deletions
|
|
@ -2,6 +2,7 @@
|
|||
|
||||
import pytest
|
||||
|
||||
from agent.conversation_compression import ROUTINE_COMPRESSION_STATUS_SAMPLES
|
||||
from gateway.config import Platform
|
||||
from gateway.run import (
|
||||
_prepare_gateway_status_message,
|
||||
|
|
@ -40,6 +41,47 @@ NOISY_STATUS_MESSAGES = [
|
|||
"⚠ Compression summary failed: upstream error. Inserted a fallback context marker.",
|
||||
"⏱️ Rate limited. Waiting 30.0s (attempt 2/3)...",
|
||||
"⏳ Retrying in 4.2s (attempt 1/3)...",
|
||||
# Buffered overflow/attempt-cap retry chatter (replayed on retry exhaustion).
|
||||
"🗜️ Context too large (~250,000 tokens) — compressing (1/3)...",
|
||||
"🗜️ Compressed 30 → 12 messages, retrying...",
|
||||
"🗜️ Compressed ~250,000 → ~120,000 tokens, retrying...",
|
||||
"🗜️ Context reduced to 120,000 tokens (was 250,000), retrying...",
|
||||
# Post-#69332 auto-lower wording + aux-provider/lock chatter.
|
||||
(
|
||||
"⚠ Compression model small (openrouter) context is 32,000 tokens, but "
|
||||
"the main model big (anthropic)'s compression threshold was 100,000 "
|
||||
"tokens. Auto-lowered this session's threshold to 30,000 tokens so "
|
||||
"compression can run."
|
||||
),
|
||||
(
|
||||
"⚠ Configured auxiliary compression provider 'openai' is unavailable — "
|
||||
"context compression will drop middle turns without a summary. Check "
|
||||
"auxiliary.compression in config.yaml and reauthenticate that provider."
|
||||
),
|
||||
(
|
||||
"⚠ Skipping concurrent compression — another path is already "
|
||||
"compressing this session. Will retry after it finishes."
|
||||
),
|
||||
]
|
||||
|
||||
# Messages that must NEVER be swallowed by the compression-noise filter:
|
||||
# deliberate carve-outs from routine-compression silence — manual /compress
|
||||
# feedback (manual_compression_feedback.py headlines) and abort/failure
|
||||
# notices that require user action.
|
||||
VISIBLE_COMPRESSION_MESSAGES = [
|
||||
"Compressed: 30 → 12 messages",
|
||||
"Compression aborted: 30 messages preserved",
|
||||
"Compressed with fallback: 30 → 12 messages",
|
||||
"No changes from compression: 30 messages",
|
||||
(
|
||||
"⚠ Compression aborted: auth failure. No messages were dropped — "
|
||||
"conversation continues unchanged. Run /compress to retry, or /new "
|
||||
"to start a fresh session."
|
||||
),
|
||||
(
|
||||
"⚠ Compression returned an empty transcript. No session split was "
|
||||
"performed; conversation continues unchanged."
|
||||
),
|
||||
]
|
||||
|
||||
|
||||
|
|
@ -86,6 +128,36 @@ def test_all_chat_gateways_suppress_noise(platform, message):
|
|||
assert _prepare_gateway_status_message(platform, "warn", message) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("platform", CHAT_PLATFORMS)
|
||||
@pytest.mark.parametrize(
|
||||
"message", ROUTINE_COMPRESSION_STATUS_SAMPLES, ids=lambda m: m[:32]
|
||||
)
|
||||
def test_all_routine_compression_statuses_suppressed_from_source_constants(
|
||||
platform, message
|
||||
):
|
||||
"""Every ROUTINE compression status the agent actually emits is filtered.
|
||||
|
||||
Iterates the sample-formatted status strings built from the SAME
|
||||
constants the emission sites use (agent/conversation_compression.py's
|
||||
ROUTINE_COMPRESSION_STATUS_SAMPLES), so a reworded emit site that drifts
|
||||
past the noise regex fails here without anyone remembering to re-copy
|
||||
the literal into this file.
|
||||
"""
|
||||
assert _prepare_gateway_status_message(platform, "lifecycle", message) is None
|
||||
|
||||
|
||||
@pytest.mark.parametrize("platform", CHAT_PLATFORMS)
|
||||
@pytest.mark.parametrize("message", VISIBLE_COMPRESSION_MESSAGES, ids=lambda m: m[:32])
|
||||
def test_manual_compress_feedback_and_failure_notices_stay_visible(platform, message):
|
||||
"""Manual /compress feedback and abort notices must never be swallowed.
|
||||
|
||||
These are the deliberate carve-outs from routine-compression silence
|
||||
(#16775 failures, manual_compression_feedback.py) — widening the noise
|
||||
regex must not start eating them.
|
||||
"""
|
||||
assert _prepare_gateway_status_message(platform, "warn", message) == message
|
||||
|
||||
|
||||
@pytest.mark.parametrize("platform", ["whatsapp", "slack", "signal", "matrix"])
|
||||
def test_chat_gateways_redact_secret_in_provider_error(platform):
|
||||
"""Provider-error bodies carrying secrets must never reach chat users.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue