From e3c71e052db7ecc6ee9954f7950b8f2e8dd56f0b Mon Sep 17 00:00:00 2001 From: webtecnica Date: Sun, 16 Aug 2026 23:18:26 -0300 Subject: [PATCH] feat(delegation): record model/provider in live-transcript manifest (#telemetry) --- tests/tools/test_delegation_live_log.py | 34 +++++++++++++++++++++++++ tools/delegate_tool.py | 2 +- tools/delegation_live_log.py | 9 +++++-- 3 files changed, 42 insertions(+), 3 deletions(-) diff --git a/tests/tools/test_delegation_live_log.py b/tests/tools/test_delegation_live_log.py index cdc5485c9d..201b129087 100644 --- a/tests/tools/test_delegation_live_log.py +++ b/tests/tools/test_delegation_live_log.py @@ -255,6 +255,40 @@ def test_manifest_goal_is_redacted(): assert "deploy using" in goal, "redaction must not blank the goal entirely" +def test_manifest_includes_model_and_provider(): + """The manifest.json should record the model and provider used for the delegation.""" + delegation_id, _writers, _paths = create_live_transcripts( + [{"goal": "task 1"}, {"goal": "task 2"}], + model="openrouter/gpt-4o", + provider="openrouter", + ) + + manifest = json.loads( + (live_transcript_root() / delegation_id / "manifest.json").read_text( + encoding="utf-8" + ) + ) + assert manifest["model"] == "openrouter/gpt-4o" + assert manifest["provider"] == "openrouter" + # tasks array should not be affected + assert len(manifest["tasks"]) == 2 + + +def test_manifest_model_provider_are_optional_and_default_none(): + """When not provided, model and provider should be null in the manifest.""" + delegation_id, _writers, _paths = create_live_transcripts( + [{"goal": "task without model"}] + ) + + manifest = json.loads( + (live_transcript_root() / delegation_id / "manifest.json").read_text( + encoding="utf-8" + ) + ) + assert manifest["model"] is None + assert manifest["provider"] is None + + def test_no_file_in_the_dispatch_directory_carries_the_raw_key(): """Whole-directory sweep: every artefact dispatch writes is covered.""" delegation_id, _writers, _paths = create_live_transcripts( diff --git a/tools/delegate_tool.py b/tools/delegate_tool.py index a8da6988a5..1141ed46d7 100644 --- a/tools/delegate_tool.py +++ b/tools/delegate_tool.py @@ -3626,7 +3626,7 @@ def delegate_task( ) live_deleg_id, live_writers, live_paths = create_live_transcripts( - task_list, context + task_list, context, model=creds.get("model"), provider=creds.get("provider") ) # Capture the ORIGINATING session's wake target BEFORE any child agent is diff --git a/tools/delegation_live_log.py b/tools/delegation_live_log.py index 86415c96c7..d355740be6 100644 --- a/tools/delegation_live_log.py +++ b/tools/delegation_live_log.py @@ -313,6 +313,8 @@ def create_live_transcripts( task_list: List[Dict[str, Any]], context: Optional[str] = None, delegation_id: Optional[str] = None, + model: Optional[str] = None, + provider: Optional[str] = None, ) -> tuple[Optional[str], List[Optional[LiveTranscriptWriter]], List[str]]: """Create one pre-headered writer per task + a manifest.json. @@ -339,7 +341,7 @@ def create_live_transcripts( paths.append(str(w.path)) if not paths: return None, [None] * n, [] - _write_manifest(deleg_id, task_list, paths) + _write_manifest(deleg_id, task_list, paths, model=model, provider=provider) return deleg_id, writers, paths except Exception as exc: logger.debug("Live transcript creation failed: %s", exc) @@ -351,12 +353,15 @@ def _manifest_path(delegation_id: str) -> Path: def _write_manifest(delegation_id: str, task_list: List[Dict[str, Any]], - paths: List[str]) -> None: + paths: List[str], model: Optional[str] = None, + provider: Optional[str] = None) -> None: try: manifest = { "delegation_id": delegation_id, "started": time.strftime("%Y-%m-%d %H:%M:%S"), "task_count": len(task_list), + "model": model, + "provider": provider, "tasks": [ { "index": i,