import { writeFileSync } from "node:fs"; import { pyDumps, readRun, type J } from "./py.ts"; // 任务书 15 第 4.3 节的材料:几次运行的全部最终入口(认领时)和第 1 轮提案,写成一个 items.json,交给 jevroutes.ts 问 Jev。 // 逐行移植对照材料里的 items.py,输出和 Python 的 json.dump(..., ensure_ascii=False, indent=0) 逐字节一致。 // node eval/route/items.ts <输出 items.json> <运行目录名>... // 运行目录是 /home/iomgaa/inforsi-eval/<运行目录名>/study/ledger.sqlite,只读打开。 const [out, ...runs] = process.argv.slice(2); if (out === undefined || runs.length === 0) throw new Error("用法:node eval/route/items.ts <输出 items.json> <运行目录名>..."); function* walk(o: J): Generator { if (typeof o === "string") yield o; else if (Array.isArray(o)) for (const v of o) yield* walk(v); else if (o !== null && typeof o === "object") for (const v of Object.values(o)) yield* walk(v); } const count = (s: string, sub: string) => s.split(sub).length - 1; const items: Array> = []; for (const run of runs) { const rows = readRun(run); // 最终入口:第一条认领调用的记录里,入口全文最多的那段文字,按"### 入口 e-"切开。 for (const [k, c] of rows) { if (k !== "callStarted" || !pyDumps(c, false).includes("r0-claim")) continue; let txt = ""; let best = -1; for (const s of walk(c)) { const n = count(s, "### 入口 e-"); if (n > best) [txt, best] = [s, n]; } for (const p of txt.split(/\n(?=### 入口 e-)/).slice(1)) { const m = /^### 入口 (e-researcher-\d-\d+):(.*?)(作者 (researcher-\d))\n([\s\S]*)/.exec(p); if (m === null) throw new Error(`${run} 的认领材料里有一段入口对不上格式:${p.slice(0, 80)}`); const body = m[4]!.split("\n## ")[0]!.trim(); items.push({ run, id: m[1]!, kind: "entry", name: m[2]!, author: m[3]!, text: body }); } break; } for (const [k, c] of rows) { if (k !== "submission" || c.kind !== "proposal") continue; const cc = c.content; const t = cc.body + "\n\n因子:\n" + cc.factors.map((f: J) => `- ${f.name}:${f.method}`).join("\n"); items.push({ run, id: c.item, kind: "proposal", name: cc.body.split("\n")[0].replace(/^[# ]+/, ""), author: c.author, text: t }); } } const indent0 = (o: Record) => "{\n" + Object.entries(o).map(([k, v]) => `${pyDumps(k, false)}: ${pyDumps(v, false)}`).join(",\n") + "\n}"; writeFileSync(out, "[\n" + items.map(indent0).join(",\n") + "\n]"); console.log(items.length); items.forEach((x, i) => console.log(i, x["run"]!.slice(11), x["id"], [...x["text"]!].length, [...x["name"]!].slice(0, 70).join("")));