52 lines
3.0 KiB
TypeScript
52 lines
3.0 KiB
TypeScript
import path from "node:path";
|
||
import { fileURLToPath } from "node:url";
|
||
import { readFile } from "node:fs/promises";
|
||
import { SessionRegistry } from "../packages/harness/src/session.js";
|
||
const root = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
|
||
process.loadEnvFile(path.join(root, ".env"));
|
||
const registry = new SessionRegistry(root);
|
||
const session = await registry.create();
|
||
await registry.models.configure(session.sessionId, {
|
||
providerId: "anthropic", api: "anthropic-messages",
|
||
baseUrl: process.env.LLM_BASE_URL!, modelId: process.env.AGENT_MODEL!,
|
||
apiKey: process.env.ANTHROPIC_API_KEY!, supportsImages: false,
|
||
});
|
||
const toolNames: string[] = [];
|
||
let skillRead = false;
|
||
let reportRead = false;
|
||
registry.events.subscribe(session.sessionId, (event) => {
|
||
if (event.type === "approval.required") {
|
||
if (event.payload.toolName === "save_report_draft")
|
||
registry.approvals.resolve(String(event.payload.approvalId), "approved");
|
||
else registry.approvals.resolve(String(event.payload.approvalId), "denied");
|
||
}
|
||
if (event.type === "tool.requested") {
|
||
const args = event.payload.arguments as { path?: string };
|
||
if (event.payload.toolName === "read" && args.path?.includes("demo-report/SKILL.md")) skillRead = true;
|
||
if (event.payload.toolName === "read" && args.path?.endsWith("report.md")) reportRead = true;
|
||
}
|
||
if (event.type === "tool.completed") toolNames.push(String(event.payload.toolName));
|
||
});
|
||
try {
|
||
await registry.run(session, "请使用 demo-report Skill,读取 demo-account 最近7天演示数据,分析 Campaign,生成含3条建议的报告草稿。保存后读取报告并核对指标,明确验收是否通过。只使用演示数据,不调用网络或真实账户工具。");
|
||
const deadline = Date.now() + 240_000;
|
||
while (session.busy && Date.now() < deadline) await new Promise(resolve => setTimeout(resolve, 500));
|
||
if (session.busy) { await registry.cancel(session.sessionId); throw new Error("DEMO_TIMEOUT"); }
|
||
const report = await readFile(path.join(session.workspace.root, "report.md"), "utf8");
|
||
const normalized = report.replace(/[,,]/g, "");
|
||
const checks = {
|
||
skillRead, metricsCalled: toolNames.includes("mock_ads_metrics"),
|
||
reportSaved: toolNames.includes("save_report_draft"), reportRead,
|
||
demoLabel: report.includes("演示"),
|
||
metrics: ["12400", "860000", "17200", "620", "37200"].every(n => normalized.includes(n)),
|
||
campaign: report.includes("Prospecting Video"),
|
||
ctr: /2(?:\.0+)?\s*%/.test(report),
|
||
cpa: /CPA[\s\S]{0,80}?20/i.test(report),
|
||
roas: /ROAS[\s\S]{0,80}?3/i.test(report),
|
||
completed: registry.events.listAfter(session.sessionId, 0).some(e => e.type === "run.completed"),
|
||
noToolErrors: !registry.events.listAfter(session.sessionId, 0).some(e => e.type === "tool.failed"),
|
||
};
|
||
console.log(JSON.stringify({ checks, tools: toolNames, report: path.join(session.workspace.root, "report.md") }, null, 2));
|
||
if (!Object.values(checks).every(Boolean)) process.exitCode = 1;
|
||
} finally { session.agent?.dispose(); }
|