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; /** 能力风险级别 */ export const CapabilityRisk = z.enum(["read", "preview", "write", "destructive"]); export type CapabilityRisk = z.infer; /** 能力 ID:`域.动作`,如 download.submit */ export const CapabilityId = z.string().regex(/^[a-z][a-z0-9]*\.[a-z][a-z0-9_]*$/); export type CapabilityId = z.infer; /** 能力定义(注册中心元数据;处理器在 server 侧挂载) */ export interface CapabilityDefinition { 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; /** 接口类别(REQ §12.3):read / preview / propose / approve / execute */ export const CapabilityKind = z.enum(["read", "preview", "propose", "approve", "execute"]); export type CapabilityKind = z.infer; /** 首批能力 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; /** 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; /** 首批能力的描述(inputSchema/outputSchema 名对应 capabilities-io.ts 中的导出) */ export const CAPABILITY_CATALOG: Record = { "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, }; }