fix(compression): ignore background process notifications
This commit is contained in:
@@ -177,6 +177,7 @@ MAX_ITERATIONS_SUMMARY_REQUEST = (
|
||||
"Please provide a final response summarizing what you've found and accomplished so far, "
|
||||
"without calling any more tools."
|
||||
)
|
||||
_BACKGROUND_PROCESS_NOTIFICATION_PREFIX = "[IMPORTANT: Background process "
|
||||
|
||||
|
||||
def _fresh_compaction_message_copy(msg: Dict[str, Any]) -> Dict[str, Any]:
|
||||
@@ -4582,7 +4583,8 @@ This compaction should PRIORITISE preserving all information related to the focu
|
||||
"""Recognize internal user-role rows after SessionDB projection.
|
||||
|
||||
SessionDB preserves role/content but not underscore-prefixed metadata,
|
||||
so the stable todo and continuation content markers are authoritative.
|
||||
so stable runtime-notification, todo, and continuation content markers
|
||||
are authoritative.
|
||||
"""
|
||||
if not isinstance(message, dict) or message.get("role") != "user":
|
||||
return False
|
||||
@@ -4618,6 +4620,8 @@ This compaction should PRIORITISE preserving all information related to the focu
|
||||
_LENGTH_CONTINUATION_NETWORK_STUB,
|
||||
_LENGTH_CONTINUATION_OUTPUT_LIMIT,
|
||||
} or text.startswith(
|
||||
_BACKGROUND_PROCESS_NOTIFICATION_PREFIX
|
||||
) or text.startswith(
|
||||
TODO_INJECTION_HEADER + "\n"
|
||||
) or text.startswith(
|
||||
_LENGTH_CONTINUATION_DROPPED_TOOLS_PREFIX
|
||||
|
||||
@@ -21,6 +21,7 @@ from agent.conversation_compression import (
|
||||
compress_context,
|
||||
)
|
||||
from hermes_state import SessionDB
|
||||
from tools.process_registry import format_process_notification
|
||||
from tools.todo_tool import TODO_INJECTION_HEADER
|
||||
|
||||
|
||||
@@ -237,6 +238,52 @@ def test_real_task_wins_over_trailing_max_iterations_nudge(compressor):
|
||||
assert messages[idx]["content"] == human["content"]
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"event",
|
||||
[
|
||||
pytest.param(
|
||||
{
|
||||
"type": "completion",
|
||||
"session_id": "proc_build",
|
||||
"command": "scripts/run_tests.sh tests/agent/",
|
||||
"exit_code": 0,
|
||||
"output": "42 passed",
|
||||
},
|
||||
id="completion",
|
||||
),
|
||||
pytest.param(
|
||||
{
|
||||
"type": "watch_match",
|
||||
"session_id": "proc_server",
|
||||
"command": "python server.py",
|
||||
"pattern": "Application startup complete",
|
||||
"output": "Application startup complete",
|
||||
},
|
||||
id="watch_match",
|
||||
),
|
||||
],
|
||||
)
|
||||
def test_background_process_notifications_do_not_become_compaction_anchors(
|
||||
compressor, event
|
||||
):
|
||||
notification = format_process_notification(event)
|
||||
assert notification is not None
|
||||
process_turn = {"role": "user", "content": notification}
|
||||
human = {"role": "user", "content": "Refactor the auth module and add tests."}
|
||||
messages = [
|
||||
human,
|
||||
{"role": "assistant", "content": "Working on it."},
|
||||
process_turn,
|
||||
]
|
||||
|
||||
assert ContextCompressor._is_synthetic_compression_user_turn(process_turn) is True
|
||||
assert ContextCompressor._transcript_has_real_user_turn([process_turn]) is False
|
||||
assert compressor._derive_auto_focus_topic(messages) == (
|
||||
"Recent user focus:\n- Refactor the auth module and add tests."
|
||||
)
|
||||
assert compressor._find_last_user_message_idx(messages, head_end=0) == 0
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"content",
|
||||
[
|
||||
|
||||
Reference in New Issue
Block a user