feat(*): 模型协议 - 升级声明式协议、扩充官方插件并完善生成任务恢复
This commit is contained in:
70
plugin-packages/embed-documentation.mjs
Normal file
70
plugin-packages/embed-documentation.mjs
Normal file
@@ -0,0 +1,70 @@
|
||||
import { readFile, readdir, writeFile } from "node:fs/promises";
|
||||
import { dirname, join } from "node:path";
|
||||
import { fileURLToPath } from "node:url";
|
||||
|
||||
const root = dirname(fileURLToPath(import.meta.url));
|
||||
const contractStart = "<!-- YINGCE_MANIFEST_CONTRACT_START -->";
|
||||
const contractEnd = "<!-- YINGCE_MANIFEST_CONTRACT_END -->";
|
||||
const recursiveDocumentationPlaceholder =
|
||||
"<当前插件的完整 documentation,由 README.md 与 docs/interface.md 拼接而成;为避免 JSON 递归,此处不重复展开正文。>";
|
||||
|
||||
function withoutGeneratedContract(document) {
|
||||
const start = document.indexOf(contractStart);
|
||||
if (start < 0) return document.trimEnd();
|
||||
const end = document.indexOf(contractEnd, start);
|
||||
if (end < 0) {
|
||||
throw new Error("docs/interface.md contains an unterminated generated manifest contract");
|
||||
}
|
||||
return `${document.slice(0, start)}${document.slice(end + contractEnd.length)}`.trimEnd();
|
||||
}
|
||||
|
||||
function renderContract(manifest) {
|
||||
const contract = JSON.parse(JSON.stringify(manifest));
|
||||
contract.documentation = recursiveDocumentationPlaceholder;
|
||||
return `${contractStart}
|
||||
## Manifest 完整接口定义
|
||||
|
||||
以下 JSON 与插件包内实际 \`manifest.json\` 逐字段一致,覆盖插件身份、权限、配置、鉴权、参数、校验、创建、Agent、查询、取消、结果下载、响应和 Agent 响应映射。\`documentation\` 字段的值就是当前完整文档;为避免文档在自身内部无限递归,JSON 中仅用等义占位文本表示正文。
|
||||
|
||||
\`\`\`json
|
||||
${JSON.stringify(contract, null, 2)}
|
||||
\`\`\`
|
||||
${contractEnd}`;
|
||||
}
|
||||
|
||||
const entries = await readdir(root, { withFileTypes: true });
|
||||
const requestedPackageIDs = new Set(process.argv.slice(2).map((value) => value.trim()).filter(Boolean));
|
||||
const packageDirectories = entries
|
||||
.filter((entry) => entry.isDirectory())
|
||||
.map((entry) => entry.name)
|
||||
.filter((name) => requestedPackageIDs.size === 0 || requestedPackageIDs.has(name))
|
||||
.sort();
|
||||
|
||||
let updated = 0;
|
||||
for (const packageID of packageDirectories) {
|
||||
const packageRoot = join(root, packageID);
|
||||
let manifestSource;
|
||||
try {
|
||||
manifestSource = await readFile(join(packageRoot, "manifest.json"), "utf8");
|
||||
} catch (error) {
|
||||
if (error?.code === "ENOENT") continue;
|
||||
throw error;
|
||||
}
|
||||
|
||||
const manifest = JSON.parse(manifestSource);
|
||||
const readme = (await readFile(join(packageRoot, "README.md"), "utf8")).trim();
|
||||
const interfacePath = join(packageRoot, "docs", "interface.md");
|
||||
const interfaceSource = await readFile(interfacePath, "utf8");
|
||||
const interfaceDocument = `${withoutGeneratedContract(interfaceSource)}\n\n${renderContract(manifest)}\n`;
|
||||
manifest.documentation = `${readme}\n\n---\n\n${interfaceDocument.trim()}\n`;
|
||||
|
||||
await writeFile(interfacePath, interfaceDocument);
|
||||
await writeFile(join(packageRoot, "manifest.json"), `${JSON.stringify(manifest, null, 2)}\n`);
|
||||
updated += 1;
|
||||
}
|
||||
|
||||
if (updated === 0) {
|
||||
throw new Error("no protocol plugin manifests were found");
|
||||
}
|
||||
|
||||
console.log(`embedded complete documentation into ${updated} protocol packages`);
|
||||
Reference in New Issue
Block a user