阶段4-tool契约: register支持CapabilityMeta(决策8 meta可选+新能力强制), 新增registerAll显式注册入口双入口过渡(决策9), RUNTIME_ERROR_CODES错误码固化+audit校验, 规范v1同步收紧
This commit is contained in:
1 parent
e691b9fa78
commit
b54311d467
6 files changed
+197
-4
No files matched your search
@@ -0,0 +1,35 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { createEngine } from "../engine/engine";
|
||||
import { capabilityCount, capabilityIds, getCapabilityMeta } from "../engine/registry";
|
||||
import { isKnownErrorCode } from "../engine/error-codes";
|
||||
import { capabilityDomains, registerAll } from "./register-all";
|
||||
import "./index";
|
||||
|
||||
describe("registerAll 显式注册入口", () => {
|
||||
it("副作用入口已注册全量包内能力,registerAll 全量幂等", async () => {
|
||||
// 包内 capabilities/index 注册 719 个 id(909 快照 = 包内 + 宿主浏览器能力)
|
||||
const before = capabilityCount();
|
||||
expect(before).toBeGreaterThan(700);
|
||||
const engine = await registerAll(createEngine());
|
||||
expect(engine).toBeDefined();
|
||||
expect(capabilityCount()).toBe(before);
|
||||
});
|
||||
|
||||
it("按子集注册:只拉起指定域,未知域报错", async () => {
|
||||
expect(capabilityDomains).toContain("excelCom");
|
||||
await expect(registerAll(createEngine(), ["excelCom", "no-such-domain"])).rejects.toThrow("未知能力域");
|
||||
await registerAll(createEngine(), ["files"]);
|
||||
expect(getCapabilityMeta).toBeDefined();
|
||||
});
|
||||
|
||||
it("meta(任务 4.1):老能力允许缺省;已声明 meta 的能力错误码必须在稳定清单内", () => {
|
||||
// 全量注册后的每个 meta,其 errorCodes 都必须落在 RUNTIME_ERROR_CODES 清单内
|
||||
for (const id of capabilityIds()) {
|
||||
const meta = getCapabilityMeta(id);
|
||||
if (!meta) continue;
|
||||
for (const code of meta.errorCodes ?? []) {
|
||||
expect(isKnownErrorCode(code), `${id} 的错误码 ${code} 未登记 error-codes.ts`).toBe(true);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -0,0 +1,59 @@
|
||||
import type { RpaEngine } from "../engine/engine";
|
||||
|
||||
/**
|
||||
* 显式注册入口(任务 4.2,决策点 9:双入口过渡)。
|
||||
*
|
||||
* - 旧入口:`import "@rpa/core/capabilities"` 副作用注册全量(宿主/测试继续使用);
|
||||
* - 新入口:`await registerAll(engine, groups?)` 按 subset 显式拉起,供
|
||||
* Agent-Employee 等宿主按需注册。阶段 6 迁移时切显式入口、删副作用入口。
|
||||
*
|
||||
* 引擎当前持有全局注册表(阶段 1 决策 2),拉起模块即完成对全局表的注册,
|
||||
* 返回 engine 以便链式使用。
|
||||
*/
|
||||
const DOMAINS: Record<string, () => Promise<unknown>> = {
|
||||
control: () => import("./control"),
|
||||
files: () => import("./files"),
|
||||
http: () => import("./http"),
|
||||
data: () => import("./data"),
|
||||
office: () => import("./office"),
|
||||
desktop: () => import("./desktop"),
|
||||
desktopUia: () => import("./desktop-uia"),
|
||||
time: () => import("./time-caps"),
|
||||
windowsSystem: () => import("./windows-system"),
|
||||
ftp: () => import("./ftp"),
|
||||
ocr: () => import("./ocr-caps"),
|
||||
pdf: () => import("./pdf"),
|
||||
word: () => import("./word"),
|
||||
wordExtended: () => import("./word-extended"),
|
||||
message: () => import("./message"),
|
||||
vision: () => import("./vision"),
|
||||
cvVision: () => import("./cv-vision"),
|
||||
extended: () => import("./extended"),
|
||||
systemExtended: () => import("./system-extended"),
|
||||
officeFileExtended: () => import("./office-file-extended"),
|
||||
officeAliases: () => import("./office-aliases"),
|
||||
excelCommon: () => import("./excel-common"),
|
||||
excelCom: () => import("./excel-com"),
|
||||
dataExtended: () => import("./data-extended"),
|
||||
utilityExtended: () => import("./utility-extended"),
|
||||
dataTableCommon: () => import("./data-table-common"),
|
||||
basicEncryption: () => import("./basic-encryption"),
|
||||
mailRemaining: () => import("./mail-remaining"),
|
||||
remainingCore: () => import("./remaining-core"),
|
||||
commonFinal: () => import("./common-final"),
|
||||
humanDialog: () => import("./human-dialog"),
|
||||
aiService: () => import("./ai-service"),
|
||||
windowExtended: () => import("./window-extended")
|
||||
};
|
||||
|
||||
export async function registerAll(engine: RpaEngine, groups?: string[]): Promise<RpaEngine> {
|
||||
const wanted = groups && groups.length ? groups : Object.keys(DOMAINS);
|
||||
for (const group of wanted) {
|
||||
const load = DOMAINS[group];
|
||||
if (!load) throw new Error(`未知能力域:${group}(可选:${Object.keys(DOMAINS).join(", ")})`);
|
||||
await load();
|
||||
}
|
||||
return engine;
|
||||
}
|
||||
|
||||
export const capabilityDomains = Object.keys(DOMAINS);
|
||||
Reference in new issue
Block a user