From c7ee59968a346a625cf34822620a685857b453ec Mon Sep 17 00:00:00 2001 From: gilesb Date: Wed, 7 Jan 2026 14:55:59 +0000 Subject: [PATCH] fix: identity effect links to GitHub, others to rose-ash MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Identity effect is part of artdag package on GitHub - Other effects (dog) link to rose-ash effects repo with commit hash - Added effect_url field to RunStatus for proper URL storage - Extract repo_url from provenance instead of building it 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 --- server.py | 19 +++++++++++++------ tasks.py | 30 ++++++++++++++++++++---------- 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/server.py b/server.py index a5af277..f56abdc 100644 --- a/server.py +++ b/server.py @@ -95,6 +95,7 @@ class RunStatus(BaseModel): error: Optional[str] = None celery_task_id: Optional[str] = None effects_commit: Optional[str] = None + effect_url: Optional[str] = None # URL to effect source code username: Optional[str] = None # Owner of the run @@ -317,10 +318,11 @@ async def get_run(run_id: str): run.completed_at = datetime.now(timezone.utc).isoformat() run.output_hash = result.get("output", {}).get("content_hash") - # Extract effects commit from provenance + # Extract effects info from provenance effects = result.get("effects", []) if effects: run.effects_commit = effects[0].get("repo_commit") + run.effect_url = effects[0].get("repo_url") # Cache the output output_path = Path(result.get("output", {}).get("local_path", "")) @@ -893,10 +895,11 @@ async def ui_detail_page(run_id: str): run.status = "completed" run.completed_at = datetime.now(timezone.utc).isoformat() run.output_hash = result.get("output", {}).get("content_hash") - # Extract effects commit + # Extract effects info from provenance effects = result.get("effects", []) if effects: run.effects_commit = effects[0].get("repo_commit") + run.effect_url = effects[0].get("repo_url") output_path = Path(result.get("output", {}).get("local_path", "")) if output_path.exists(): cache_file(output_path) @@ -905,8 +908,10 @@ async def ui_detail_page(run_id: str): run.error = str(task.result) save_run(run) - # Build effect URL - use commit hash if available - if run.effects_commit and run.effects_commit != "unknown": + # Use stored effect URL or build fallback + if run.effect_url: + effect_url = run.effect_url + elif run.effects_commit and run.effects_commit != "unknown": effect_url = f"https://git.rose-ash.com/art-dag/effects/src/commit/{run.effects_commit}/{run.recipe}" else: effect_url = f"https://git.rose-ash.com/art-dag/effects/src/branch/main/{run.recipe}" @@ -1030,12 +1035,13 @@ async def ui_detail_page(run_id: str): "status": run.status, "recipe": run.recipe, "effects_commit": run.effects_commit, - "effect_url": effect_url, + "effect_url": run.effect_url or effect_url, "inputs": run.inputs, "output_hash": run.output_hash, "output_name": run.output_name, "created_at": run.created_at, "completed_at": run.completed_at, + "username": run.username, "error": run.error }, indent=2) @@ -1066,10 +1072,11 @@ async def ui_run_partial(run_id: str): run.status = "completed" run.completed_at = datetime.now(timezone.utc).isoformat() run.output_hash = result.get("output", {}).get("content_hash") - # Extract effects commit + # Extract effects info from provenance effects = result.get("effects", []) if effects: run.effects_commit = effects[0].get("repo_commit") + run.effect_url = effects[0].get("repo_url") output_path = Path(result.get("output", {}).get("local_path", "")) if output_path.exists(): cache_file(output_path) diff --git a/tasks.py b/tasks.py index 8d339db..73b8906 100644 --- a/tasks.py +++ b/tasks.py @@ -125,8 +125,25 @@ def render_effect(self, input_hash: str, effect_name: str, output_name: str) -> if output_hash != expected_hash: raise ValueError(f"Output hash mismatch: expected {expected_hash}, got {output_hash}") - # Get effects repo commit - effects_commit = get_effects_commit() + # Build effect info based on source + if effect_name == "identity": + # Identity is from artdag package on GitHub + effect_info = { + "name": f"effect:{effect_name}", + "content_hash": REGISTRY[f"effect:{effect_name}"]["hash"], + "repo": "github", + "repo_url": "https://github.com/gilesbradshaw/art-dag/blob/main/artdag/nodes/effect.py" + } + else: + # Other effects from rose-ash effects repo + effects_commit = get_effects_commit() + effect_info = { + "name": f"effect:{effect_name}", + "content_hash": REGISTRY[f"effect:{effect_name}"]["hash"], + "repo": "rose-ash", + "repo_commit": effects_commit, + "repo_url": f"https://git.rose-ash.com/art-dag/effects/src/commit/{effects_commit}/{effect_name}" + } # Build provenance provenance = { @@ -141,14 +158,7 @@ def render_effect(self, input_hash: str, effect_name: str, output_name: str) -> "inputs": [ {"content_hash": input_hash} ], - "effects": [ - { - "name": f"effect:{effect_name}", - "content_hash": REGISTRY[f"effect:{effect_name}"]["hash"], - "repo_commit": effects_commit, - "repo_url": f"https://git.rose-ash.com/art-dag/effects/src/commit/{effects_commit}/{effect_name}" - } - ], + "effects": [effect_info], "infrastructure": { "software": {"name": "infra:artdag", "content_hash": REGISTRY["infra:artdag"]["hash"]}, "hardware": {"name": "infra:giles-hp", "content_hash": REGISTRY["infra:giles-hp"]["hash"]}