# All files / modules/book-generator/strategies per-chapter.strategy.ts

0% Statements 0/43
0% Branches 0/1
0% Functions 0/1
0% Lines 0/43

Press n or j to go to the next uncovered block, b, p or k for the previous block.

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67

     /**
     * 策略3 - Per-Chapter（逐章内聚）
     *
     * 工作流：
     *   plan_book → generate_outline → per_chapter (批量并行)
     *
     * 特点：
     *   先生成章大纲（仅章节列表），然后每章独立生成内部结构+内容
     *   各章可并行执行（并发数可配置）
     *   调用量：~1(规划) + 1(大纲) + N(章节数) 次 AI
     */

    import { StateGraph, END } from '@langchain/langgraph';
    import { GraphState } from '../graph';
    import { planBookNode } from '../nodes/plan.node';
    import { generateOutlineNode } from '../nodes/outline.node';
    import { perChapterNode } from '../nodes/per-chapter.node';
    import { runGraphWorkflow } from './base';
    import { GenerationStrategy } from './types';

    export class PerChapterStrategy implements GenerationStrategy {
      readonly name = 'per-chapter' as const;
      readonly description = '逐章内聚：先生成章大纲，然后每章独立并行生成结构+内容';

      async generate(
        bookId: string,
        topic: string,
        bookScale: string,
        genLevel: number,
        userSpecifiedGenLevel?: number
      ): Promise<void> {
        console.log(`[Strategy-per-chapter] 开始, bookId=${bookId}, scale=${bookScale}, genLevel=${genLevel}, userSpecified=${userSpecifiedGenLevel}`);

        const workflow = new StateGraph(GraphState)
          .addNode('plan_book', planBookNode)
          .addNode('generate_outline', generateOutlineNode)
          .addNode('per_chapter', perChapterNode)
          .setEntryPoint('plan_book')
          .addEdge('plan_book', 'generate_outline')
          .addEdge('generate_outline', 'per_chapter')
          .addEdge('per_chapter', END);

        const initialState: typeof GraphState.State = {
          bookId,
          topic,
          bookScale,
          genLevel,
          userSpecifiedGenLevel,
          userId: '',
          description: undefined,
          bookPlan: undefined,
          currentChapter: 0,
          completedChapters: [],
          finished: false,
          error: undefined,
          progress: 0,
          failedChapters: [],
          qualityPassed: true,
          rewriteCount: 0,
          maxRewriteCount: 3,
          qualityResult: undefined,
        };

        await runGraphWorkflow(bookId, initialState, workflow);
      }
    }