From 7ddb572f5da8f303827e346320e56c5d171d6586 Mon Sep 17 00:00:00 2001 From: Benjamin Admin Date: Sat, 25 Apr 2026 16:08:19 +0200 Subject: [PATCH] fix: Pass 0b batch custom_id + result handler for numeric format Co-Authored-By: Claude Opus 4.6 (1M context) --- .../services/decomposition_pass.py | 39 +++++++++++++++++-- 1 file changed, 35 insertions(+), 4 deletions(-) diff --git a/control-pipeline/services/decomposition_pass.py b/control-pipeline/services/decomposition_pass.py index 2ad8ce9..c2ab229 100644 --- a/control-pipeline/services/decomposition_pass.py +++ b/control-pipeline/services/decomposition_pass.py @@ -3593,9 +3593,9 @@ class DecompositionPass: source_ref=obl["source_ref"], ) - ids_str = "+".join(o["candidate_id"] for o in batch) + batch_idx = i // batch_size requests.append({ - "custom_id": f"p0b_{ids_str}", + "custom_id": f"p0b_b{batch_idx:05d}", "params": { "model": ANTHROPIC_MODEL, "max_tokens": max(8192, len(batch) * 1500), @@ -3778,9 +3778,40 @@ class DecompositionPass: async def _handle_batch_result_0b( self, custom_id: str, text_content: str, stats: dict, ) -> None: - """Process a single Pass 0b batch result.""" + """Process a single Pass 0b batch result. + + custom_id formats: + - p0b_b00001 (numeric batch index — new format) + - p0b_OC-CTRL-001+OC-CTRL-002 (legacy + separated candidate IDs) + """ prefix = "p0b_" - candidate_ids = custom_id[len(prefix):].split("+") if custom_id.startswith(prefix) else [] + suffix = custom_id[len(prefix):] if custom_id.startswith(prefix) else custom_id + + # New format: p0b_b00001 — extract candidate IDs from LLM response + if suffix.startswith("b") and suffix[1:].isdigit(): + results_by_id = _parse_json_object(text_content) + if not results_by_id: + # Try single object + parsed = _parse_json_object(text_content) + if parsed and "candidate_id" in parsed: + cand_id = parsed["candidate_id"] + obl = self._load_obligation_for_0b(cand_id) + if obl: + await self._process_pass0b_control(obl, parsed, stats) + else: + stats["errors"] += 1 + return + + for cand_id, parsed in results_by_id.items(): + if not isinstance(parsed, dict): + parsed = {} + obl = self._load_obligation_for_0b(cand_id) + if obl: + await self._process_pass0b_control(obl, parsed, stats) + return + + # Legacy format: p0b_OC-CTRL-001+OC-CTRL-002 + candidate_ids = suffix.split("+") if len(candidate_ids) == 1: parsed = _parse_json_object(text_content)