feat(AI服务):lpt-ai 独立服务初始版本

- Fastify + TypeScript,OpenAI 兼容接口对接 SiliconFlow
- POST /ai/aggregate-report:残片聚合为学习报告(支持预期对比)
- POST /ai/generate-mind-map:生成思维导图缩进大纲(与后端解析格式一致)
- Key 从环境变量读取且日志脱敏,未配置时返回 503 由调用方降级
- prompt 模板集中管理,vitest 单元测试
This commit is contained in:
2026-07-03 23:48:51 +08:00
commit 44c07d28bd
11 changed files with 4187 additions and 0 deletions
+46
View File
@@ -0,0 +1,46 @@
import { describe, expect, it } from "vitest";
import { aggregateReportPrompt, generateMindMapPrompt } from "./prompts.js";
describe("aggregateReportPrompt", () => {
it("包含全部残片和任务名", () => {
const messages = aggregateReportPrompt("Java 并发", [
{ content: "corePoolSize 是核心线程数" },
{ content: "workQueue 满后创建新线程", createdTime: "2026-07-01" },
]);
expect(messages).toHaveLength(2);
expect(messages[0].role).toBe("system");
expect(messages[1].content).toContain("Java 并发");
expect(messages[1].content).toContain("corePoolSize");
expect(messages[1].content).toContain("workQueue");
expect(messages[1].content).toContain("2026-07-01");
});
it("有预期时包含预期内容和对比要求", () => {
const messages = aggregateReportPrompt(
"Java 并发",
[{ content: "x" }],
"理解线程池核心参数",
);
expect(messages[1].content).toContain("理解线程池核心参数");
expect(messages[0].content).toContain("预期");
});
it("无预期时不包含预期块", () => {
const messages = aggregateReportPrompt("Java 并发", [{ content: "x" }]);
expect(messages[1].content).not.toContain("预期目标");
});
});
describe("generateMindMapPrompt", () => {
it("要求输出缩进大纲且包含全部输入", () => {
const messages = generateMindMapPrompt(
"Java 并发",
"并发编程学习",
["报告一"],
["残片一", "残片二"],
);
expect(messages[0].content).toContain("缩进");
expect(messages[1].content).toContain("报告一");
expect(messages[1].content).toContain("残片二");
});
});