tenseleyflow/loader / 746eb32

Browse files

Compact TodoWrite observations

Authored by espadonne
SHA
746eb3219e90c66e28b67e1e972098fc86e747fc
Parents
a608f28
Tree
0d12fdb

2 changed files

StatusFile+-
M src/loader/runtime/parsing.py 39 0
M tests/test_parsing.py 36 0
src/loader/runtime/parsing.pymodified
@@ -407,5 +407,44 @@ def parse_tool_calls(
407407
 def format_tool_result(tool_name: str, result: str, is_error: bool = False) -> str:
408408
     """Format a tool result for inclusion in conversation."""
409409
 
410
+    if tool_name == "TodoWrite" and not is_error:
411
+        try:
412
+            payload = json.loads(result)
413
+        except json.JSONDecodeError:
414
+            payload = None
415
+        if isinstance(payload, dict):
416
+            todos = payload.get("new_todos", [])
417
+            if isinstance(todos, list):
418
+                completed = 0
419
+                in_progress = 0
420
+                pending = 0
421
+                next_pending: str | None = None
422
+                for item in todos:
423
+                    if not isinstance(item, dict):
424
+                        continue
425
+                    status = str(item.get("status", "")).strip().lower()
426
+                    content = str(item.get("content", "")).strip()
427
+                    if status == "completed":
428
+                        completed += 1
429
+                    elif status == "in_progress":
430
+                        in_progress += 1
431
+                        if next_pending is None and content:
432
+                            next_pending = content
433
+                    else:
434
+                        pending += 1
435
+                        if next_pending is None and content:
436
+                            next_pending = content
437
+                summary_parts = [
438
+                    "updated todo list",
439
+                    f"{completed} completed",
440
+                    f"{in_progress} in progress",
441
+                    f"{pending} pending",
442
+                ]
443
+                if next_pending:
444
+                    summary_parts.append(f"next pending: {next_pending}")
445
+                if payload.get("verification_nudge_needed") is True:
446
+                    summary_parts.append("verification should be reviewed next")
447
+                result = "; ".join(summary_parts)
448
+
410449
     prefix = "Error" if is_error else "Result"
411450
     return f"Observation [{tool_name}]: {prefix}: {result}"
tests/test_parsing.pymodified
@@ -274,3 +274,39 @@ class TestFormatToolResult:
274274
         assert "write" in result
275275
         assert "Error" in result
276276
         assert "Permission denied" in result
277
+
278
+    def test_format_todowrite_compacts_payload(self):
279
+        result = format_tool_result(
280
+            "TodoWrite",
281
+            json.dumps(
282
+                {
283
+                    "old_todos": [
284
+                        {
285
+                            "content": "Create index.html",
286
+                            "active_form": "Creating index.html",
287
+                            "status": "completed",
288
+                        }
289
+                    ],
290
+                    "new_todos": [
291
+                        {
292
+                            "content": "Create index.html",
293
+                            "active_form": "Creating index.html",
294
+                            "status": "completed",
295
+                        },
296
+                        {
297
+                            "content": "Create installation chapter (02-installation.html)",
298
+                            "active_form": "Creating installation chapter",
299
+                            "status": "pending",
300
+                        },
301
+                    ],
302
+                    "verification_nudge_needed": False,
303
+                    "store_path": "/tmp/.loader/todos/active.json",
304
+                }
305
+            ),
306
+        )
307
+        assert "Observation [TodoWrite]: Result: updated todo list" in result
308
+        assert "1 completed" in result
309
+        assert "1 pending" in result
310
+        assert "next pending: Create installation chapter (02-installation.html)" in result
311
+        assert "old_todos" not in result
312
+        assert "new_todos" not in result