缓存卷 → 下载盘;站点快照 → 站点列表抓取;Feed → RSS;去掉猜测原因与「请…」;同步断言。 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
58 lines
2.5 KiB
TypeScript
58 lines
2.5 KiB
TypeScript
import { CapabilityError, type CapabilityRegistry } from "@umt/agent";
|
|
import { CAPABILITY_CATALOG, capabilitySpec, KnownCapabilityId } from "@umt/contracts";
|
|
import type { ServerContext } from "../types.ts";
|
|
import { createAgentCheck } from "./store.ts";
|
|
|
|
// schedule.draft_check:智能体按用户的自然语言需求起草巡检。建成「未启用」,不会自己运行;
|
|
// 用户在计划页检查、修改后再启用(授权只放行用户发起的对话,见 agent/authorize.ts)。
|
|
|
|
/** 巡检只开放只读 / 预览 / 提案类能力(与计划页表单一致),且不能再起草巡检 */
|
|
const ALLOWED = new Set(
|
|
Object.values(CAPABILITY_CATALOG)
|
|
.filter((c) => ["read", "preview", "propose"].includes(c.kind) && c.id !== "schedule.draft_check")
|
|
.map((c) => c.id as string),
|
|
);
|
|
|
|
export function registerScheduleCapabilities(registry: CapabilityRegistry, ctx: ServerContext): void {
|
|
registry.register(capabilitySpec("schedule.draft_check"), async (input) => {
|
|
const asked = [...new Set(input.capabilities ?? [])];
|
|
const caps = asked.filter((c) => KnownCapabilityId.safeParse(c).success && ALLOWED.has(c));
|
|
const dropped = asked.filter((c) => !caps.includes(c));
|
|
let row: Awaited<ReturnType<typeof createAgentCheck>>;
|
|
try {
|
|
row = await createAgentCheck(
|
|
ctx.db,
|
|
{
|
|
name: input.name,
|
|
description: "智能体按对话起草",
|
|
enabled: false,
|
|
schedule: { type: "interval", everyMs: Math.round(input.everyHours * 3600_000) },
|
|
config: {
|
|
goalTemplate: input.goal,
|
|
capabilityAllowlist: caps as KnownCapabilityId[],
|
|
budget: {
|
|
...(input.maxToolCalls ? { maxToolCalls: input.maxToolCalls } : {}),
|
|
...(input.maxDurationSec ? { maxDurationSec: input.maxDurationSec } : {}),
|
|
},
|
|
triggerCondition: input.triggerCondition ?? "always",
|
|
reportAsDecision: input.reportAsDecision ?? false,
|
|
},
|
|
},
|
|
new Date(),
|
|
);
|
|
} catch (e) {
|
|
throw new CapabilityError("precondition", `巡检没建成:${(e as Error).message}`);
|
|
}
|
|
return {
|
|
jobId: row.id,
|
|
name: row.name,
|
|
everyHours: input.everyHours,
|
|
capabilities: caps,
|
|
dropped,
|
|
enabled: false as const,
|
|
// copy-allow: 给模型看的下一步提示
|
|
next: "已建成未启用的巡检。请用户到「计划」页检查目标、间隔和能力,确认后打开开关启用。",
|
|
};
|
|
});
|
|
}
|