#!/usr/bin/env python3 """生成可灵任务对账表(供与账单核对)""" import datetime import json import urllib.request from pathlib import Path import yaml opener = urllib.request.build_opener(urllib.request.ProxyHandler({})) urllib.request.install_opener(opener) CFG = Path.home() / "workbuddy-agent-os" / "agent-local" / "tools" / "ave" / "config" / "local.yaml" AVE = Path.home() / "workbuddy-agent-os" / "agent-local" / "runtime" / "ave" cfg = yaml.safe_load(CFG.read_text(encoding="utf-8")) k = cfg["kling"] hdr = {"Authorization": f"Bearer {k['api_key']}"} base = k["base_url"] with urllib.request.urlopen( urllib.request.Request(base + "/v1/videos/text2video", headers=hdr), timeout=30) as r: vids = json.loads(r.read().decode()).get("data") or [] local_files = [] for p in AVE.rglob("*.mp4"): local_files.append((p.stat().st_mtime, str(p.relative_to(AVE)))) local_files.sort(reverse=True) NOTES = { "934535832286281787": "首次验证 kling-v3 可用", "934536473163501607": "端到端流程 wf_5d5ffff0fc06 镜头1", "934536909153013802": "端到端流程 wf_5d5ffff0fc06 镜头2", "934537556619169795": "端到端流程 wf_5d5ffff0fc06 镜头3", "934539639007219781": "口播线验证(oral_verify2)", "934540864327012427": "并发生成测试 镜头1", "934540864352174168": "并发生成测试 镜头2", "934540864385880141": "并发生成测试 镜头3", "934542570569990201": "流程测试", "934612690390495243": "P2 编排通电验证", "934618791945191489": "完整链路验证 镜头1", "934618965245431828": "完整链路验证 镜头2", } now = datetime.datetime.now().strftime("%Y-%m-%d %H:%M") lines = ["# 可灵任务对账表", "", f"生成时间:{now}", "", "## 全部任务", "", "| 时间 | 任务号 | 状态 | 时长 | 用途 |", "|:--|:--|:--|:--|:--|"] today_cnt = today_sec = 0 rows = sorted(vids, key=lambda t: -int(t.get("created_at") or 0)) for t in rows: ms = int(t.get("created_at") or 0) dts = datetime.datetime.fromtimestamp(ms / 1000).strftime("%Y-%m-%d %H:%M") vs = (t.get("task_result") or {}).get("videos") or [] dur = float(vs[0].get("duration", 5) or 5) if vs else 5.0 note = NOTES.get(str(t.get("task_id")), "(历史任务)") if dts.startswith("2026-10-01"): today_cnt += 1 today_sec += dur lines.append(f"| {dts} | `{t.get('task_id')}` | {t.get('task_status')} | {dur:.1f}s | {note} |") total_sec = sum( float(((t.get("task_result") or {}).get("videos") or [{}])[0].get("duration", 5) or 5) for t in rows ) lines += ["", f"**今天(2026-10-01):{today_cnt} 条 / {today_sec:.1f} 秒**", f"**全部:{len(rows)} 条 / {total_sec:.1f} 秒**", "", "## 费用估算(按不同单价档)", "", "| 单价档 | 今天 | 全部 |", "|:--|:--|:--|", f"| ¥0.6/秒(无声 720P) | ¥{today_sec * 0.6:.1f} | ¥{total_sec * 0.6:.1f} |", f"| ¥1.2/秒(有声 / 1080P) | ¥{today_sec * 1.2:.1f} | ¥{total_sec * 1.2:.1f} |", f"| ¥2.4/秒(高配) | ¥{today_sec * 2.4:.1f} | ¥{total_sec * 2.4:.1f} |", "", "> ⚠️ 以上为**估算**。准确金额请以可灵控制台「消费明细」为准。", "> 若单价与我估算不符,请把明细发我,我核对后调整代码里的计费参数。", "", "## 本地产物文件(最新 20 个)", ""] for mt, rel in local_files[:20]: dts = datetime.datetime.fromtimestamp(mt).strftime("%m-%d %H:%M") lines.append(f"- `{dts}` {rel}") out = AVE / "可灵任务对账表.md" out.write_text("\n".join(lines), encoding="utf-8") print(f"✅ 已生成: {out}") print(f" 今天 {today_cnt} 条 / {today_sec:.1f} 秒 · 全部 {len(rows)} 条 / {total_sec:.1f} 秒")