Files
UHD_Media_Tool/apps/server/test/schedules/draft-check-capability.test.ts

77 lines
3.2 KiB
TypeScript

import { afterAll, beforeAll, describe, expect, it } from "vitest";
import { createCapabilityRegistry } from "../../src/modules/agent/capability-registry.ts";
import { registerScheduleCapabilities } from "../../src/modules/schedules/capabilities.ts";
import { createHarness, type Harness, pgAvailable } from "../sources-identity/harness.ts";
// schedule.draft_check:智能体按对话起草巡检 → 建成未启用的 agent_check;只读能力白名单;只放行用户发起的对话
const pg = await pgAvailable();
// biome-ignore lint/suspicious/noExplicitAny: 能力输出按 schema 校验过,测试里直接取字段
type Any = any;
describe.skipIf(!pg)("起草巡检能力(真实 PG)", () => {
let h: Harness;
beforeAll(async () => {
h = await createHarness("draftcheck");
const registry = createCapabilityRegistry({ logger: h.ctx.logger, db: h.db, settings: h.ctx.settings });
registerScheduleCapabilities(registry, h.ctx);
(h.ctx as { capabilities: unknown }).capabilities = registry;
}, 120_000);
afterAll(async () => {
await h?.close();
});
const run = async (trigger: "user" | "schedule") =>
(
await h.db
.insertInto("agent_run")
.values({ trigger, goal: "起草巡检", status: "running", mode: "execute" } as never)
.returning("id")
.executeTakeFirstOrThrow()
).id;
const invoke = (input: Record<string, unknown>, agentRunId: string) =>
h.ctx.capabilities.invoke("schedule.draft_check", input, {
actorId: "agent",
taskId: crypto.randomUUID(),
agentRunId,
scopeIds: [],
signal: new AbortController().signal,
source: "agent",
}) as Promise<Any>;
const input = {
name: "失败下载日报",
goal: "检查下载器里失败或卡住的任务,有就写一段话汇报",
everyHours: 24,
capabilities: ["download.list", "downloader.list", "download.submit", "not.exists"],
triggerCondition: "stalled_downloads",
reportAsDecision: true,
};
it("对话里起草:建成未启用的巡检;写入 / 不存在的能力去掉", async () => {
const out = await invoke(input, await run("user"));
expect(out).toMatchObject({
enabled: false,
capabilities: ["download.list", "downloader.list"],
dropped: ["download.submit", "not.exists"],
});
const job = await h.db
.selectFrom("scheduled_job")
.selectAll()
.where("id", "=", out.jobId)
.executeTakeFirstOrThrow();
expect(job).toMatchObject({ kind: "agent_check", enabled: false, builtin: false, name: "失败下载日报" });
expect(job.schedule).toMatchObject({ type: "interval", everyMs: 24 * 3600_000 });
expect(job.config).toMatchObject({
goalTemplate: input.goal,
capabilityAllowlist: ["download.list", "downloader.list"],
triggerCondition: "stalled_downloads",
reportAsDecision: true,
});
});
it("定时巡检的会话里不能再起草巡检", async () => {
const before = await h.db.selectFrom("scheduled_job").select("id").execute();
await expect(invoke(input, await run("schedule"))).rejects.toThrow(/用户发起的对话/);
expect(await h.db.selectFrom("scheduled_job").select("id").execute()).toHaveLength(before.length);
});
});