feat: 功能清单进智能体提示,补字幕按功能模块约定改为样板
- 外围功能模块(补字幕、原站视图、桌面模式、网页搜索、MCP、定时任务)声明 manifest,与 FEATURES 一一对应; 系统提示「能力地图」末尾列出外围功能(没有开关,能力只列本次可用的) - 补字幕:订阅 organization.finished(认出值得补字幕的整理,自动补字幕还没做,不建任务), 写入字幕后在同一事务发 subtitle.written;原有行为不变 Co-Authored-By: Claude Opus 5.5 <[email protected]> Claude-Session: https://claude.ai/code/session_01Cxwgnn2pbzQ7rXv3rq7fei
This commit is contained in:
1 parent
1db689d9a7
commit
7aa5182f3d
14 files changed
+237
-17
No files matched your search
@@ -18,6 +18,7 @@ export {
|
||||
type IntentRoute,
|
||||
needsApproval,
|
||||
type RouteStep,
|
||||
renderFeatures,
|
||||
} from "./layers/capabilities.ts";
|
||||
export { renderEnvironment } from "./layers/environment.ts";
|
||||
export { AGENT_REPORT_FORMAT, REPORT_FORMAT } from "./layers/report.ts";
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { AUTHORIZED_KINDS, CAPABILITY_CATALOG, type KnownCapabilityId } from "@umt/contracts";
|
||||
import { AUTHORIZED_KINDS, CAPABILITY_CATALOG, FEATURES, type KnownCapabilityId } from "@umt/contracts";
|
||||
import type { PromptSection } from "../types.ts";
|
||||
|
||||
// 第 3 层:能力地图,按用户意图组织("要查健康 → …","要查下载 → …")。工具描述里已有每个能力"何时用 / 何时不用",
|
||||
@@ -190,6 +190,20 @@ export function renderRoutes(available: ReadonlySet<string>): string[] {
|
||||
return out;
|
||||
}
|
||||
|
||||
/**
|
||||
* 功能清单(ADR-006):外围功能各一行,说明做什么、入口在哪、智能体能不能做。清单来自 contracts 的 FEATURES
|
||||
* (服务端模块的 manifest 指向同一份),功能都已启用、没有开关;能力只列本次可用的。
|
||||
*/
|
||||
export function renderFeatures(available: ReadonlySet<string>): string[] {
|
||||
return [
|
||||
"- 外围功能(都已启用,没有开关;用户问到时按这里指路):",
|
||||
...FEATURES.map((f) => {
|
||||
const caps = f.capabilities.filter((c) => available.has(c));
|
||||
return ` - ${f.name}:${f.summary}${f.usage}${caps.length ? `(能力:${caps.join("、")})` : ""}`;
|
||||
}),
|
||||
];
|
||||
}
|
||||
|
||||
export function capabilityLayer(capabilities: readonly string[] | undefined): PromptSection {
|
||||
if (!capabilities?.length) return { layer: "capabilities", title: "能力地图", lines: [] };
|
||||
const available = new Set(capabilities);
|
||||
@@ -202,6 +216,7 @@ export function capabilityLayer(capabilities: readonly string[] | undefined): Pr
|
||||
"按用户意图选路线,箭头是常用顺序;只做回答问题需要的几步。标「需要批准」的没有授权时会被拒绝或出审批卡。",
|
||||
...routes,
|
||||
...CAPABILITY_TIPS.map((t) => `- ${t}`),
|
||||
...renderFeatures(available),
|
||||
],
|
||||
};
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
import { CAPABILITY_CATALOG, FEATURES } from "@umt/contracts";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { buildLayeredPrompt, renderFeatures } from "../src/index.ts";
|
||||
|
||||
// 功能清单(ADR-006):外围功能的 manifest 进系统提示「能力地图」一节,让智能体知道有哪些功能、入口在哪;没有开关。
|
||||
|
||||
const section = (p: string, title: string) => {
|
||||
const start = p.indexOf(`## ${title}`);
|
||||
const rest = p.slice(start);
|
||||
const next = rest.indexOf("\n## ", 3);
|
||||
return next < 0 ? rest : rest.slice(0, next);
|
||||
};
|
||||
|
||||
describe("功能清单进系统提示", () => {
|
||||
it("能力地图里列出每个外围功能的名称、说明与入口", () => {
|
||||
const p = buildLayeredPrompt({ kind: "chat", role: "x", goal: "y", capabilities: ["download.list"] });
|
||||
const map = section(p, "能力地图");
|
||||
expect(map).toContain("外围功能(都已启用,没有开关");
|
||||
for (const f of FEATURES) expect(map).toContain(` - ${f.name}:${f.summary}`);
|
||||
expect(map).toContain("作品页「补字幕」");
|
||||
});
|
||||
|
||||
it("功能的能力只列本次可用的;没给的能力 ID 不出现在清单里", () => {
|
||||
const lines = renderFeatures(new Set(["web.search"]));
|
||||
const web = lines.find((l) => l.includes("网页搜索"))!;
|
||||
expect(web).toContain("(能力:web.search)");
|
||||
const text = lines.join("\n");
|
||||
for (const id of Object.keys(CAPABILITY_CATALOG)) if (id !== "web.search") expect(text).not.toContain(id);
|
||||
});
|
||||
|
||||
it("没有能力的会话(视觉子流程)不带功能清单", () => {
|
||||
const p = buildLayeredPrompt({ kind: "vision", role: "x", goal: "y" });
|
||||
expect(p).not.toContain("外围功能");
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user