Files
writing-agent/src/libraries/registry.ts
T
chenmoranzhiandCursor bc77bc4a3c 改写回合推演技能合同,并接上画面工作流库。
旧产物名仍能读到,避免改名后上下文对不上。

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-14 08:29:28 +08:00

103 lines
2.8 KiB
TypeScript

/**
* 节点可绑定的全局库:某能力声明 libraries 后,design-step 注入对应块。
* 新库:实现 formatForPrompt,在本文件 register。
*/
import { formatImageWorkflowCatalogForPrompt } from "../image-workflow/catalog.js";
import { formatPreferenceCatalogForPrompt } from "../preference/catalog.js";
import { formatStylePackCatalogForPrompt } from "../style-pack/catalog.js";
export type LibraryProvider = {
id: string;
/** 给人看的短名 */
label: string;
/** 空串 = 库空或无可注入,跳过 */
formatForPrompt: () => string;
};
const providers = new Map<string, LibraryProvider>();
export function registerLibrary(provider: LibraryProvider): void {
const id = provider.id.trim();
if (!id) return;
providers.set(id, { ...provider, id });
}
export function getLibrary(id: string): LibraryProvider | undefined {
return providers.get(id.trim());
}
export function listRegisteredLibraries(): LibraryProvider[] {
return [...providers.values()];
}
/** 从 catalog / meta 原始值收成 id 列表 */
export function parseLibraryIds(raw: unknown): string[] | undefined {
if (!Array.isArray(raw) || raw.length === 0) return undefined;
const ids: string[] = [];
const seen = new Set<string>();
for (const item of raw) {
const id = typeof item === "string" ? item.trim() : "";
if (!id || seen.has(id)) continue;
seen.add(id);
ids.push(id);
}
return ids.length ? ids : undefined;
}
/**
* 按节点绑定的库 id 拼注入块;未知 id 忽略;库空跳过。
*/
export function formatBoundLibrariesForPrompt(
libraryIds: readonly string[] | undefined,
): string {
if (!libraryIds?.length) return "";
const blocks: string[] = [];
for (const id of libraryIds) {
const provider = providers.get(id.trim());
if (!provider) continue;
const text = provider.formatForPrompt().trim();
if (text) blocks.push(text);
}
return blocks.join("\n\n");
}
// —— 内置库 ——
registerLibrary({
id: "style-packs",
label: "文风库",
formatForPrompt: formatStylePackCatalogForPrompt,
});
registerLibrary({
id: "preferences",
label: "偏好库",
formatForPrompt: formatPreferenceCatalogForPrompt,
});
registerLibrary({
id: "image-workflows",
label: "工作流库",
formatForPrompt: formatImageWorkflowCatalogForPrompt,
});
/**
* 从模块列表收集绑定的库 id(去重、保序)。
* 对话落盘:通常传入 intake≠recipe 的模块。
*/
export function collectLibraryIdsFromModules(
modules: ReadonlyArray<{ libraries?: readonly string[] }>,
): string[] {
const ids: string[] = [];
const seen = new Set<string>();
for (const m of modules) {
for (const raw of m.libraries ?? []) {
const id = typeof raw === "string" ? raw.trim() : "";
if (!id || seen.has(id)) continue;
seen.add(id);
ids.push(id);
}
}
return ids;
}