# All files / services/llm book-tools.ts

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

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
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104

     /**
     * 书籍生成工具集 - Tool Calling 模式
     *
     * 借鉴 OpenMAIC pblTools 做法：
     * - 用 Zod 定义输入 Schema，确保类型安全
     * - execute 函数执行实际逻辑
     * - LLM 可在生成过程中主动调用，获取上下文
     */

    import { z } from 'zod';
    import { ToolDefinition } from './index';

    // ============ 工具定义 ============

    /**
     * 创建书籍生成工具集
     * 使用工厂模式，绑定到具体书籍 ID 和 bookStore
     */
    export function createBookTools(bookId: string, bookStore: any): ToolDefinition[] {
      return [
        // 工具1：获取已生成章节的摘要，避免内容重复
        {
          name: 'get_existing_chapters',
          description:
            '获取书籍中已经生成的章节内容摘要（前500字），用于了解已有内容，避免重复，保持风格一致。返回章节列表，每项包含章节号、标题、内容摘要。',
          inputSchema: z.object({
            chapter_numbers: z
              .array(z.number())
              .optional()
              .describe('要查询的章节号列表，不传则返回所有已完成章节'),
          }),
          execute: async ({ chapter_numbers }: { chapter_numbers?: number[] }) => {
            const book = await bookStore.getById(bookId);
            if (!book) return { error: '书籍不存在', chapters: [] };

            const chapters = (book.chapters || []).filter((c: any) => {
              const hasContent = c.content && c.content.length > 0;
              const inRange = !chapter_numbers || chapter_numbers.includes(c.number);
              return hasContent && inRange;
            });

            return {
              count: chapters.length,
              chapters: chapters.map((c: any) => ({
                number: c.number,
                title: c.title,
                summary: c.content ? c.content.slice(0, 500) + (c.content.length > 500 ? '...' : '') : '',
                wordCount: c.wordCount || 0,
              })),
            };
          },
        },

        // 工具2：获取书籍大纲，了解整体结构
        {
          name: 'get_book_outline',
          description:
            '获取书籍完整大纲，包括主题、结构逻辑和所有章节规划。用于了解当前章节在全书中的位置和与其他章节的关系。',
          inputSchema: z.object({}),
          execute: async () => {
            const book = await bookStore.getById(bookId);
            if (!book?.outline) return { error: '大纲不存在' };

            return {
              mainTheme: book.outline.mainTheme,
              structureLogic: book.outline.structureLogic,
              totalChapters: book.outline.chapters.length,
              chapters: book.outline.chapters.map((c: any) => ({
                number: c.number,
                title: c.title,
                summary: c.summary,
                keyPoints: c.keyPoints,
                estimatedWords: c.estimatedWords,
              })),
            };
          },
        },

        // 工具3：标记章节需要调整（LLM 发现问题时主动报告）
        {
          name: 'report_chapter_issue',
          description:
            '当发现当前章节内容与已有章节重复、结构不合理或内容缺失时，用此工具记录问题说明。返回确认消息后继续生成改进版本。',
          inputSchema: z.object({
            chapter_number: z.number().describe('问题章节号'),
            issue_type: z
              .enum(['content_overlap', 'structure_issue', 'missing_content', 'style_inconsistency'])
              .describe('问题类型'),
            description: z.string().describe('问题描述'),
            suggestion: z.string().describe('改进建议'),
          }),
          execute: async ({ chapter_number, issue_type, description, suggestion }: any) => {
            console.log(
              `[BookTools] 章节 ${chapter_number} 发现问题: [${issue_type}] ${description}，建议: ${suggestion}`
            );
            return {
              acknowledged: true,
              message: `已记录问题，请根据建议"${suggestion}"重新生成第${chapter_number}章内容。`,
            };
          },
        },
      ];
    }