@@ -54,6 +54,7 @@ def _node_official_artifact_path(run_id: str, node_id: str) -> Path | None:
5454 mapping = {
5555 "scout" : run_dir / "topic.yaml" ,
5656 "researcher" : run_dir / "research.yaml" ,
57+ "writer" : run_dir / "article_edited.md" ,
5758 "director" : run_dir / "visual_plan.json" ,
5859 "formatter" : run_dir / "formatted.html" ,
5960 }
@@ -486,27 +487,45 @@ async def api_save_article(run_id: str, body: dict):
486487
487488
488489@router .get ("/runs/{run_id}/diff" )
489- async def api_get_diff (run_id : str ):
490- """获取文章改动 diff(当前 vs 上一版本)"""
490+ async def api_get_diff (run_id : str , node : str | None = None ):
491+ """获取节点改动 diff(当前 vs 上一版本)。
492+
493+ ?node=scout → topic.yaml diff
494+ ?node=writer → article_edited.md diff (default)
495+ ?node=researcher → research.yaml diff
496+ ?node=director → visual_plan.json diff
497+ ?node=formatter → formatted.html diff
498+ """
491499 import difflib
492500
493501 run_dir = Path (__file__ ).parent .parent .parent .parent / "output" / "runs" / run_id
494- current_path = run_dir / "article_edited.md"
495- prev_path = run_dir / "article_edited.md.prev"
496- draft_path = run_dir / "article_draft.md"
502+
503+ # 确定要 diff 的文件
504+ if node and node != "writer" :
505+ artifact_path = _node_official_artifact_path (run_id , node )
506+ if not artifact_path :
507+ return JSONResponse ({"error" : f"未知节点: { node } " }, status_code = 400 )
508+ current_path = artifact_path
509+ prev_path = run_dir / f"{ artifact_path .name } .prev"
510+ draft_path = None
511+ else :
512+ # 默认: writer article
513+ current_path = run_dir / "article_edited.md"
514+ prev_path = run_dir / "article_edited.md.prev"
515+ draft_path = run_dir / "article_draft.md"
497516
498517 if not current_path .exists ():
499- return JSONResponse ({"error" : "当前文章不存在 " }, status_code = 404 )
518+ return JSONResponse ({"error" : f"当前产物不存在: { current_path . name } " }, status_code = 404 )
500519
501- # 优先用 .prev(上一次审核改稿前的版本) ,fallback 用 article_draft.md(初稿 )
520+ # 优先用 .prev,fallback 用 draft(仅 writer )
502521 if prev_path .exists ():
503522 base_path = prev_path
504523 from_label = "上一版本"
505- elif draft_path .exists ():
524+ elif draft_path and draft_path .exists ():
506525 base_path = draft_path
507526 from_label = "初稿"
508527 else :
509- return JSONResponse ({"diff" : None , "message" : "暂无历史版本" })
528+ return JSONResponse ({"diff" : None , "has_diff" : False , " message" : "暂无历史版本" })
510529
511530 current = current_path .read_text (encoding = "utf-8" ).splitlines (keepends = True )
512531 previous = base_path .read_text (encoding = "utf-8" ).splitlines (keepends = True )
@@ -518,7 +537,7 @@ async def api_get_diff(run_id: str):
518537 lineterm = ""
519538 )
520539 diff_text = "\n " .join (diff )
521- return {"diff" : diff_text }
540+ return {"diff" : diff_text , "has_diff" : bool ( diff_text . strip ()) }
522541
523542
524543# ── 节点数据 ──────────────────────────────────────────────────
@@ -1276,12 +1295,6 @@ async def api_update_settings_form(request: Request):
12761295 )
12771296
12781297
1279- # ── 审核对话同步 ──────────────────────────────────────────────
1280-
1281- # 旧的 _sync_chat_to_state 链路已退役:
1282- # 审核聊天现在直接由节点主 session 修改正式产物,再由 Python 读回并提交。
1283-
1284-
12851298# ── 内部函数 ──────────────────────────────────────────────────
12861299
12871300async def _execute_pipeline (run_id : str ):
0 commit comments