fix(prax): cap monitor agent events per batch to prevent doom-scrolling

This commit is contained in:
AIOSAI
2026-05-15 14:02:40 -07:00
parent ac10726567
commit b2625e244f
3 changed files with 65 additions and 4 deletions
-1
View File
@@ -1 +0,0 @@
{"file": "/home/patrick/Projects/AIPass/src/aipass/drone/apps/modules/git_module.py", "errors": [{"line": 671, "message": "E501: Line too long (193 > 120)"}]}
@@ -535,11 +535,15 @@ class MonitoringFileHandler(FileSystemEventHandler):
# CLAUDE CODE AGENT ACTIVITY PARSING (JSONL sessions)
# =========================================================================
_MAX_AGENT_EVENTS_PER_BATCH = 3
def _parse_agent_activity(self, file_path, branch):
"""Parse Claude Code session JSONL to show agent actions.
Returns True if an event was emitted (or deduped), False on failure.
Iterates forward through new lines, emitting all distinct actions.
Iterates forward through all new lines (for model extraction), but only
emits the last few distinct actions to prevent doom-scrolling when large
batches accumulate between polls or after compaction resets.
"""
try:
path_key = str(file_path)
@@ -560,6 +564,9 @@ class MonitoringFileHandler(FileSystemEventHandler):
if not lines:
return True
pending_actions = []
last_seen = self._last_agent_action.get(path_key)
for line in lines:
try:
entry = _json.loads(line)
@@ -575,10 +582,12 @@ class MonitoringFileHandler(FileSystemEventHandler):
if not action_text:
continue
if self._last_agent_action.get(path_key) == action_text:
if action_text == last_seen:
continue
self._last_agent_action[path_key] = action_text
last_seen = action_text
pending_actions.append(action_text)
for action_text in pending_actions[-self._MAX_AGENT_EVENTS_PER_BATCH :]:
tagged_branch = self._tag_branch_with_model(path_key, branch)
evt = MonitoringEvent(
priority=1,
@@ -591,6 +600,9 @@ class MonitoringFileHandler(FileSystemEventHandler):
if self._event_queue:
self._event_queue.enqueue(evt)
if pending_actions:
self._last_agent_action[path_key] = pending_actions[-1]
return True
except Exception as e:
@@ -1763,6 +1763,56 @@ class TestParseAgentActivity:
result = handler._parse_agent_activity(mock_path, "PRAX")
assert result is True
def test_batch_cap_limits_emitted_events(self):
"""Should only emit last N events when batch exceeds cap."""
mod, _, _, _, queue = _import_filesystem_handler()
handler = _make_handler(mod, queue=queue)
mock_path = MagicMock()
mock_path.__str__ = MagicMock(return_value="/fake/claude.jsonl")
mock_path.name = "claude.jsonl"
entries = []
tools = ["Read", "Edit", "Write", "Grep", "Glob", "Bash"]
for i, tool in enumerate(tools):
entries.append(
{
"type": "assistant",
"message": {"content": [{"type": "tool_use", "name": tool, "input": {"file_path": f"f{i}.py"}}]},
}
)
data = "\n".join(json.dumps(e) for e in entries) + "\n"
mock_path.stat.return_value.st_size = len(data)
with patch("builtins.open", _mopen(read_data=data)):
result = handler._parse_agent_activity(mock_path, "PRAX")
assert result is True
cap = mod.MonitoringFileHandler._MAX_AGENT_EVENTS_PER_BATCH
assert queue.enqueue.call_count == cap
def test_batch_cap_emits_tail_not_head(self):
"""Should emit the last actions in a large batch, not the first."""
mod, mock_eq, _, _, queue = _import_filesystem_handler()
handler = _make_handler(mod, queue=queue)
mock_path = MagicMock()
mock_path.__str__ = MagicMock(return_value="/fake/claude.jsonl")
mock_path.name = "claude.jsonl"
entries = []
for i in range(6):
entries.append(
{
"type": "assistant",
"message": {"content": [{"type": "tool_use", "name": f"Tool{i}", "input": {}}]},
}
)
data = "\n".join(json.dumps(e) for e in entries) + "\n"
mock_path.stat.return_value.st_size = len(data)
with patch("builtins.open", _mopen(read_data=data)):
handler._parse_agent_activity(mock_path, "PRAX")
cap = mod.MonitoringFileHandler._MAX_AGENT_EVENTS_PER_BATCH
assert queue.enqueue.call_count == cap
last_call_kwargs = mock_eq.MonitoringEvent.call_args_list[-1][1]
assert "Tool5" in last_call_kwargs["message"]
first_call_kwargs = mock_eq.MonitoringEvent.call_args_list[-cap][1]
assert "Tool3" in first_call_kwargs["message"]
# =============================================
# CHECK COMMAND INDICATOR TESTS