Files
UHD_Media_Tool/spikes/deno/packages/contracts/src/capability.ts
T
2026-09-27 18:24:08 +08:00

281 lines
6.9 KiB
TypeScript

import { z } from "zod";
import { ApiScope } from "./common";
/**
* 能力调用上下文(REQ §10.3)。产品自有接口,不是 Pi SDK 原生 API。
* signal 由任务取消传播而来。
*/
export interface CapabilityContext {
actorId: string;
taskId: string;
scopeIds: string[];
signal: AbortSignal;
}
/** 变更计划:由业务端生成与保存,审批绑定 id + payloadHash + expectedRevision */
export const MutationPlan = z.object({
id: z.string(),
operation: z.string(),
targetIds: z.array(z.string()),
expectedRevision: z.number().int().nonnegative(),
evidenceIds: z.array(z.string()),
payloadHash: z.string(),
requiresApproval: z.boolean(),
});
export type MutationPlan = z.infer<typeof MutationPlan>;
/** 能力风险级别 */
export const CapabilityRisk = z.enum(["read", "preview", "write", "destructive"]);
export type CapabilityRisk = z.infer<typeof CapabilityRisk>;
/** 能力 ID:`域.动作`,如 download.submit */
export const CapabilityId = z.string().regex(/^[a-z][a-z0-9]*\.[a-z][a-z0-9_]*$/);
export type CapabilityId = z.infer<typeof CapabilityId>;
/** 能力定义(注册中心元数据;处理器在 server 侧挂载) */
export interface CapabilityDefinition<I extends z.ZodType = z.ZodType, O extends z.ZodType = z.ZodType> {
id: CapabilityId;
version: number;
description: string;
input: I;
output: O;
scopes: string[];
risk: CapabilityRisk;
idempotent: boolean;
supportsPreview: boolean;
}
// ── 能力描述符与首批能力(任务书 §3.1-9;REQ §10.3) ──
/** 风险级别:low 只读;medium 预览/可撤回写入;high 触发下载、文件变更或策略发布 */
export const RiskLevel = z.enum(["low", "medium", "high"]);
export type RiskLevel = z.infer<typeof RiskLevel>;
/** 接口类别(REQ §12.3):read / preview / propose / approve / execute */
export const CapabilityKind = z.enum(["read", "preview", "propose", "approve", "execute"]);
export type CapabilityKind = z.infer<typeof CapabilityKind>;
/** 首批能力 ID */
export const CAPABILITY_IDS = [
"catalog.lookup",
"release.search",
"release.inspect",
"identity.resolve",
"download.plan",
"download.submit",
"organize.plan",
"organize.execute",
"task.inspect",
"task.retry",
"task.cancel",
"policy.preview",
"policy.apply",
"inventory.query",
] as const;
export const KnownCapabilityId = z.enum(CAPABILITY_IDS);
export type KnownCapabilityId = z.infer<typeof KnownCapabilityId>;
/** schema 引用:指向 contracts 中导出的 schema 名(如 "ReleaseSearchInput"),便于序列化给 UI/MCP 列表 */
export const SchemaRef = z.string().regex(/^[A-Z][A-Za-z0-9]*$/);
/** 能力注册中心的可序列化描述(处理器在 server 侧挂载;模型只能看到白名单内的描述) */
export const CapabilityDescriptor = z.object({
id: CapabilityId,
version: z.number().int().min(1),
title: z.string().min(1),
description: z.string().min(1),
kind: CapabilityKind,
inputSchema: SchemaRef,
outputSchema: SchemaRef,
/** 调用所需 API scope */
scope: ApiScope,
riskLevel: RiskLevel,
idempotent: z.boolean(),
supportsPreview: z.boolean(),
});
export type CapabilityDescriptor = z.infer<typeof CapabilityDescriptor>;
/** 首批能力的描述(inputSchema/outputSchema 名对应 capabilities-io.ts 中的导出) */
export const CAPABILITY_CATALOG: Record<KnownCapabilityId, CapabilityDescriptor> = {
"catalog.lookup": d(
"catalog.lookup",
"查作品",
"按标题/别名/外部 ID 查本地作品与元数据候选",
"read",
"CatalogLookup",
"read",
"low",
true,
false,
),
"release.search": d(
"release.search",
"搜资源",
"先查本地资源索引与站点快照,不足时对已开启站点实时补查",
"read",
"ReleaseSearch",
"read",
"low",
true,
false,
),
"release.inspect": d(
"release.inspect",
"看资源详情",
"读取站点资源详情、文件清单、促销与解析结果",
"read",
"ReleaseInspect",
"read",
"low",
true,
false,
),
"identity.resolve": d(
"identity.resolve",
"识别身份",
"为观察/资源提出身份映射;高证据自动接受,歧义进入待处理",
"propose",
"IdentityResolve",
"organize.execute",
"medium",
true,
true,
),
"download.plan": d(
"download.plan",
"生成下载计划",
"评估候选并生成带 Slot/预算预留的下载计划(不提交)",
"preview",
"DownloadPlan",
"organize.execute",
"medium",
true,
true,
),
"download.submit": d(
"download.submit",
"提交下载",
"按已保存的计划提交到下载器;校验授权与硬阈值",
"execute",
"DownloadSubmit",
"organize.execute",
"high",
true,
false,
),
"organize.plan": d(
"organize.plan",
"生成整理计划",
"冻结源/目标路径、操作类型与前置条件",
"preview",
"OrganizePlan",
"organize.read",
"low",
true,
true,
),
"organize.execute": d(
"organize.execute",
"执行整理",
"执行已保存的整理计划(Copy/Move),生成整理记录",
"execute",
"OrganizeExecute",
"organize.execute",
"high",
true,
false,
),
"task.inspect": d(
"task.inspect",
"查看任务",
"读取任务状态、业务时间线与错误",
"read",
"TaskInspect",
"read",
"low",
true,
false,
),
"task.retry": d(
"task.retry",
"重试任务",
"对失败/死信任务重新排队;副作用经操作账本去重",
"execute",
"TaskRetry",
"organize.execute",
"medium",
true,
false,
),
"task.cancel": d(
"task.cancel",
"取消任务",
"停止未来步骤,不撤销已完成的外部动作",
"execute",
"TaskCancel",
"organize.execute",
"medium",
true,
false,
),
"policy.preview": d(
"policy.preview",
"预览策略",
"用历史数据回放策略草案,展示新增命中与误排除",
"preview",
"PolicyPreview",
"read",
"low",
true,
true,
),
"policy.apply": d(
"policy.apply",
"发布策略",
"发布策略版本(需授权);不直接执行 JavaScript",
"execute",
"PolicyApply",
"admin",
"high",
true,
true,
),
"inventory.query": d(
"inventory.query",
"查库存",
"查询本地资产、Slot 满足度与外部库存证据",
"read",
"InventoryQuery",
"read",
"low",
true,
false,
),
};
function d(
id: KnownCapabilityId,
title: string,
description: string,
kind: CapabilityKind,
schemaBase: string,
scope: ApiScope,
riskLevel: RiskLevel,
idempotent: boolean,
supportsPreview: boolean,
): CapabilityDescriptor {
return {
id,
version: 1,
title,
description,
kind,
inputSchema: `${schemaBase}Input`,
outputSchema: `${schemaBase}Output`,
scope,
riskLevel,
idempotent,
supportsPreview,
};
}