Files
xc_agent_platform_demo/scripts/dry_run.py

108 lines
4.1 KiB
Python
Raw Normal View History

#!/usr/bin/env python3
"""Generate a dry-run adaptation report (no platform side effects).
Reads config/candidates.example.json (or DRY_RUN_CANDIDATES path).
Writes reports/dry-run-<Asia/Shanghai-timestamp>.md
"""
from __future__ import annotations
import json
import os
import sys
from datetime import datetime
from pathlib import Path
from zoneinfo import ZoneInfo
ROOT = Path(__file__).resolve().parents[1]
TZ = ZoneInfo("Asia/Shanghai")
def _load_candidates(path: Path) -> list[dict]:
data = json.loads(path.read_text(encoding="utf-8"))
if isinstance(data, list):
return data
if isinstance(data, dict) and "candidates" in data:
return list(data["candidates"])
raise SystemExit(f"unexpected candidates schema in {path}")
def _render(candidates: list[dict], ts: str, src: Path) -> str:
lines = [
f"# Dry-run 适配建议报告 — {ts} (Asia/Shanghai)",
"",
"> **模式:dry-run** — 本报告不产生平台侧真实提交。",
"> **需 Victor 人工提交**:请登录模盒控制台按草稿确认后手工提交。",
"> **积分:待平台核实**(发布智能体本身不得分;成功适配按账本计)。",
"",
"## 闸门状态",
"",
f"- ALLOW_LIVE_SUBMIT is 1: {os.environ.get('ALLOW_LIVE_SUBMIT', '0').strip() == '1'}",
f"- LIVE_CONFIRM set: {'yes' if os.environ.get('LIVE_CONFIRM', '').strip() else 'no'}",
f"- STRATEGY_ID present: {'yes' if os.environ.get('STRATEGY_ID', '').strip() else 'no'}",
"",
"## 输入",
"",
f"- 候选文件:`{src}`",
f"- 候选条数:{len(candidates)}",
"",
"## 建议草稿(字段示意,非真实 POST)",
"",
]
for i, c in enumerate(candidates, 1):
model = c.get("modelAddress") or c.get("model_id") or "(missing model_id)"
lines.append(f"### {i}. `{model}`")
lines.append("")
lines.append("```json")
draft = {
"modelAddress": model,
"taskType": c.get("taskType", "text-generation"),
"targetGpu": c.get("targetGpu", "(unset)"),
"framework": c.get("framework", "(unset)"),
"strategyId": "<PLATFORM_INJECTED_STRATEGY_ID>",
"configParams": "<from build-config — not fetched in Phase1 dry-run>",
"notes": c.get("notes", ""),
}
lines.append(json.dumps(draft, ensure_ascii=False, indent=2))
lines.append("```")
lines.append("")
lines.append("- 风险:Phase1 未做唯一性/硬门预检;提交前请对照 do-not-resubmit 与队列空位。")
lines.append("- **需 Victor 人工提交**(或经双重闸门的受控 live;本骨架默认拒绝 live)。")
lines.append("- **积分:待平台核实**")
lines.append("")
lines.extend(
[
"## 后续对接(Phase2)",
"",
"- **待对接 pending-submit**:尚未读取 `/workspace/modelhub-adapt/pending-submit.md`,未验证 A→B、PASS、硬门与 do-not-resubmit;本报告仅保留输入顺序。",
"- 适配 W1 优先;同一 100 队列,≥95 全体停交;空位先 A 再 B,人工核验后决定,不凭示例报告提交。",
"- 禁止 Makefile / 脚本调用 `/api/adapt/task/add` 或 `/agent_platform/strategies*` 写接口。",
"",
]
)
return "\n".join(lines)
def main() -> None:
src = Path(
os.environ.get(
"DRY_RUN_CANDIDATES",
str(ROOT / "config" / "candidates.example.json"),
)
)
if not src.is_file():
raise SystemExit(f"candidates file not found: {src}")
candidates = _load_candidates(src)
now = datetime.now(TZ)
ts = now.strftime("%Y%m%d-%H%M%S")
out_dir = ROOT / "reports"
out_dir.mkdir(parents=True, exist_ok=True)
out_path = out_dir / f"dry-run-{ts}.md"
out_path.write_text(_render(candidates, now.strftime("%Y-%m-%d %H:%M:%S"), src), encoding="utf-8")
print(f"Wrote {out_path}")
if __name__ == "__main__":
main()