""" 爽文工作流 Tool 注册。 """ from __future__ import annotations import json from typing import Any, Dict, Optional try: from backend.models.agent import TurnContext from backend.services.fiction_chapter_service import run_chapter from backend.services.fiction_coarse_service import run_coarse_outline from backend.services.fiction_event_plan_service import run_event_plan from backend.services.fiction_open_book_service import run_open_book from backend.services.tool_registry import ToolRegistry except ImportError: from models.agent import TurnContext from services.fiction_chapter_service import run_chapter from services.fiction_coarse_service import run_coarse_outline from services.fiction_event_plan_service import run_event_plan from services.fiction_open_book_service import run_open_book from services.tool_registry import ToolRegistry async def fiction_open_book(ctx: TurnContext) -> None: """fiction.open_book — 根据用户灵感优化开书方案(不创建书籍目录)。""" request = ctx.request_data or {} inspiration = str(request.get("inspiration") or request.get("intro") or "").strip() profile_id = request.get("profile_id") or request.get("profileId") api_config = request.get("api_config") or request.get("apiConfig") result = await run_open_book( inspiration, profile_id=profile_id, api_config=api_config, ) payload = result.model_dump() ctx.request_data["fictionOpenBookResult"] = payload ctx.generated_content = json.dumps(payload, ensure_ascii=False) async def fiction_coarse(ctx: TurnContext) -> None: """fiction.coarse — 生成本书粗纲事件链,写入 metadata.json。""" request = ctx.request_data or {} book_id = str(request.get("book_id") or request.get("bookId") or "").strip() if not book_id: raise ValueError("book_id 不能为空") profile_id = request.get("profile_id") or request.get("profileId") api_config = request.get("api_config") or request.get("apiConfig") result = await run_coarse_outline( book_id, profile_id=profile_id, api_config=api_config, ) payload = result.model_dump() ctx.request_data["fictionCoarseResult"] = payload ctx.generated_content = json.dumps(payload, ensure_ascii=False) async def fiction_event_plan(ctx: TurnContext) -> None: """fiction.event_plan — 为粗纲事件生成 flowStepsPlan + chapterPlan。""" request = ctx.request_data or {} book_id = str(request.get("book_id") or request.get("bookId") or "").strip() if not book_id: raise ValueError("book_id 不能为空") profile_id = request.get("profile_id") or request.get("profileId") api_config = request.get("api_config") or request.get("apiConfig") event_id = request.get("event_id") or request.get("eventId") result = await run_event_plan( book_id, profile_id=profile_id, api_config=api_config, event_id=event_id, ) payload = result.model_dump() ctx.request_data["fictionEventPlanResult"] = payload ctx.generated_content = json.dumps(payload, ensure_ascii=False) async def fiction_chapter(ctx: TurnContext) -> None: """fiction.chapter — 根据 chapterPlan brief 撰写正文,写入 chapters/{seq}.json。""" request = ctx.request_data or {} book_id = str(request.get("book_id") or request.get("bookId") or "").strip() if not book_id: raise ValueError("book_id 不能为空") profile_id = request.get("profile_id") or request.get("profileId") api_config = request.get("api_config") or request.get("apiConfig") seq = request.get("seq") or request.get("chapterSeq") result = await run_chapter( book_id, profile_id=profile_id, api_config=api_config, seq=int(seq) if seq is not None else None, ) payload = result.model_dump() ctx.request_data["fictionChapterResult"] = payload ctx.generated_content = json.dumps(payload, ensure_ascii=False) def register_fiction_tools(registry: ToolRegistry) -> None: registry.register( "fiction.open_book", fiction_open_book, description="根据用户创作灵感优化爽文开书方案,返回 guide 草稿与推荐情绪流", parameters={ "type": "object", "properties": { "inspiration": {"type": "string", "description": "用户创作灵感/简介"}, "profile_id": {"type": "string", "description": "API 配置 profile ID"}, "api_config": { "type": "object", "description": "可选 inline API 配置", }, }, "required": ["inspiration"], }, ) registry.register( "fiction.coarse", fiction_coarse, description="根据本书 guide 与 L1 全局指南生成粗纲,写入 metadata.coarseOutline", parameters={ "type": "object", "properties": { "book_id": {"type": "string", "description": "书籍 ID"}, "profile_id": {"type": "string", "description": "API 配置 profile ID"}, "api_config": {"type": "object", "description": "可选 inline API 配置"}, }, "required": ["book_id"], }, ) registry.register( "fiction.event_plan", fiction_event_plan, description="为粗纲事件随机选情绪流并生成 flowStepsPlan + chapterPlan", parameters={ "type": "object", "properties": { "book_id": {"type": "string", "description": "书籍 ID"}, "event_id": { "type": "string", "description": "可选,仅规划指定粗纲事件;缺省则规划全部", }, "profile_id": {"type": "string", "description": "API 配置 profile ID"}, "api_config": {"type": "object", "description": "可选 inline API 配置"}, }, "required": ["book_id"], }, ) registry.register( "fiction.chapter", fiction_chapter, description="根据 chapterPlan brief 撰写章节正文,写入 chapters 目录", parameters={ "type": "object", "properties": { "book_id": {"type": "string", "description": "书籍 ID"}, "seq": { "type": "integer", "description": "可选,指定章节序号;缺省则写下一未写章", }, "profile_id": {"type": "string", "description": "API 配置 profile ID"}, "api_config": {"type": "object", "description": "可选 inline API 配置"}, }, "required": ["book_id"], }, ) # 模块加载时注册到默认 registry try: from services.tool_registry import default_tool_registry register_fiction_tools(default_tool_registry) except Exception: pass