From 016eead8b417390d466762c874a7e23b8c07bbcb Mon Sep 17 00:00:00 2001 From: Auto Date: Sun, 1 Feb 2026 16:42:56 +0200 Subject: [PATCH] fix: update log prefix when batch agent moves between features The output reader was stamping every line with the primary feature ID (e.g., [Feature #24]) even after the agent claimed a new feature in the batch. Now parses feature_claim_and_get calls in the output stream and switches the prefix to the newly claimed feature ID, so logs correctly show [Feature #30] once the agent moves on. Co-Authored-By: Claude Opus 4.5 --- parallel_orchestrator.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/parallel_orchestrator.py b/parallel_orchestrator.py index 10d0923..d31db0b 100644 --- a/parallel_orchestrator.py +++ b/parallel_orchestrator.py @@ -22,6 +22,7 @@ import asyncio import atexit import logging import os +import re import signal import subprocess import sys @@ -1116,6 +1117,11 @@ class ParallelOrchestrator: return True + # Pattern to detect when a batch agent claims a new feature + _CLAIM_FEATURE_PATTERN = re.compile( + r"feature_claim_and_get\b.*?['\"]?feature_id['\"]?\s*[:=]\s*(\d+)" + ) + def _read_output( self, feature_id: int | None, @@ -1124,6 +1130,7 @@ class ParallelOrchestrator: agent_type: Literal["coding", "testing"] = "coding", ): """Read output from subprocess and emit events.""" + current_feature_id = feature_id try: if proc.stdout is None: proc.wait() @@ -1132,11 +1139,17 @@ class ParallelOrchestrator: if abort.is_set(): break line = line.rstrip() + # Detect when a batch agent claims a new feature + claim_match = self._CLAIM_FEATURE_PATTERN.search(line) + if claim_match: + claimed_id = int(claim_match.group(1)) + if claimed_id != current_feature_id: + current_feature_id = claimed_id if self.on_output is not None: - self.on_output(feature_id or 0, line) + self.on_output(current_feature_id or 0, line) else: # Both coding and testing agents now use [Feature #X] format - print(f"[Feature #{feature_id}] {line}", flush=True) + print(f"[Feature #{current_feature_id}] {line}", flush=True) proc.wait() finally: # CRITICAL: Kill the process tree to clean up any child processes (e.g., Claude CLI)