|
@@ -271,6 +271,70 @@ describe("ArchitectAgent", () => {
|
|
|
expect(result.pendingHooks).toContain("| H13 | 22 | 舆情操盘 | 待推进 | 0 | 51-60章 | 庄蔓出场后逐步揭露(初始线索:一家自媒体公司在多个旧案节点同步接单) |");
|
|
expect(result.pendingHooks).toContain("| H13 | 22 | 舆情操盘 | 待推进 | 0 | 51-60章 | 庄蔓出场后逐步揭露(初始线索:一家自媒体公司在多个旧案节点同步接单) |");
|
|
|
});
|
|
});
|
|
|
|
|
|
|
|
|
|
+ it("accepts section labels with spacing and punctuation drift from non-strict models", async () => {
|
|
|
|
|
+ const agent = new ArchitectAgent({
|
|
|
|
|
+ client: {
|
|
|
|
|
+ provider: "openai",
|
|
|
|
|
+ apiFormat: "chat",
|
|
|
|
|
+ stream: false,
|
|
|
|
|
+ defaults: {
|
|
|
|
|
+ temperature: 0.7,
|
|
|
|
|
+ maxTokens: 4096,
|
|
|
|
|
+ thinkingBudget: 0, maxTokensCap: null,
|
|
|
|
|
+ extra: {},
|
|
|
|
|
+ },
|
|
|
|
|
+ },
|
|
|
|
|
+ model: "test-model",
|
|
|
|
|
+ projectRoot: process.cwd(),
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const book: BookConfig = {
|
|
|
|
|
+ id: "format-drift-book",
|
|
|
|
|
+ title: "格式漂移测试",
|
|
|
|
|
+ platform: "other",
|
|
|
|
|
+ genre: "other",
|
|
|
|
|
+ status: "active",
|
|
|
|
|
+ targetChapters: 20,
|
|
|
|
|
+ chapterWordCount: 2200,
|
|
|
|
|
+ language: "zh",
|
|
|
|
|
+ createdAt: "2026-04-01T00:00:00.000Z",
|
|
|
|
|
+ updatedAt: "2026-04-01T00:00:00.000Z",
|
|
|
|
|
+ };
|
|
|
|
|
+
|
|
|
|
|
+ vi.spyOn(agent as unknown as { chat: (...args: unknown[]) => Promise<unknown> }, "chat")
|
|
|
|
|
+ .mockResolvedValue({
|
|
|
|
|
+ content: [
|
|
|
|
|
+ "=== Section:Story Bible ===",
|
|
|
|
|
+ "# 故事圣经",
|
|
|
|
|
+ "",
|
|
|
|
|
+ "=== section: Volume Outline ===",
|
|
|
|
|
+ "# 卷纲",
|
|
|
|
|
+ "",
|
|
|
|
|
+ "=== SECTION: book-rules ===",
|
|
|
|
|
+ "---",
|
|
|
|
|
+ "version: \"1.0\"",
|
|
|
|
|
+ "---",
|
|
|
|
|
+ "",
|
|
|
|
|
+ "=== SECTION : current state ===",
|
|
|
|
|
+ "# 当前状态",
|
|
|
|
|
+ "",
|
|
|
|
|
+ "=== SECTION: pending hooks ===",
|
|
|
|
|
+ "| hook_id | 起始章节 | 类型 | 状态 | 最近推进 | 预期回收 | 备注 |",
|
|
|
|
|
+ "| --- | --- | --- | --- | --- | --- | --- |",
|
|
|
|
|
+ "| H01 | 1 | mystery | open | 0 | 10章 | 初始钩子 |",
|
|
|
|
|
+ ].join("\n"),
|
|
|
|
|
+ usage: ZERO_USAGE,
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
|
|
+ const result = await agent.generateFoundation(book);
|
|
|
|
|
+
|
|
|
|
|
+ expect(result.storyBible).toBe("# 故事圣经");
|
|
|
|
|
+ expect(result.volumeOutline).toBe("# 卷纲");
|
|
|
|
|
+ expect(result.bookRules).toContain("version: \"1.0\"");
|
|
|
|
|
+ expect(result.currentState).toBe("# 当前状态");
|
|
|
|
|
+ expect(result.pendingHooks).toContain("| H01 | 1 | mystery | open | 0 | 10章 | 初始钩子 |");
|
|
|
|
|
+ });
|
|
|
|
|
+
|
|
|
it("throws when a required foundation section is missing", async () => {
|
|
it("throws when a required foundation section is missing", async () => {
|
|
|
const agent = new ArchitectAgent({
|
|
const agent = new ArchitectAgent({
|
|
|
client: {
|
|
client: {
|