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 | /** * 基础策略 - 共享的 graph 执行、进度监控、错误处理逻辑 */ import { StateGraph, END } from '@langchain/langgraph'; import { GraphState } from '../graph'; import { bookStore } from '../book-generator.store'; import { startProgressMonitor } from '../fault-tolerance'; /** 基础策略选项 */ export interface BaseStrategyOptions { name: string; description: string; buildGraph: () => ReturnType<typeof buildAndCompile>; } function buildAndCompile() { const workflow = new StateGraph(GraphState); return { workflow, addEdge: workflow.addEdge.bind(workflow) }; } /** * 运行一个 LangGraph 工作流并处理结果 * 所有策略的 graph 执行逻辑相同,只是 graph 结构不同 */ export async function runGraphWorkflow( bookId: string, initialState: typeof GraphState.State, workflow: StateGraph<typeof GraphState.State, any, any, any, any> ): Promise<void> { await bookStore.update(bookId, { genStage: 'outlining', progress: 0 }); const stopMonitor = startProgressMonitor(bookId); try { const graph = workflow.compile(); const stream = await graph.stream(initialState); for await (const step of stream) { const stepName = Object.keys(step).join(','); if (stepName !== 'progress') { console.log(`[Graph] Step:`, stepName); } } // 检查最终状态 const finalBook = await bookStore.getById(bookId); if (finalBook && finalBook.genStage !== 'failed') { const finalStage = finalBook.genStage || 'content_completed'; const stageUpdate: any = { progress: 100 }; if (['content_completed', 'audio_generating', 'audio_completed'].includes(finalStage)) { stageUpdate.genStage = finalStage; } await bookStore.update(bookId, stageUpdate); // 只有最终态 video_completed 才自动发布 if (finalStage === 'video_completed') { await bookStore.publishAlbum(bookId); } console.log(`[Strategy] 生成完成,genStage: ${finalStage}`); } else { console.log('[Strategy] 生成失败,保持 failed 状态'); } } catch (error) { console.error('[Strategy] 生成失败:', error); // 尝试从数据库获取当前真实阶段,作为 failedStage let failedStage = 'outlining'; try { const currentBook = await bookStore.getById(bookId); if (currentBook?.genStage) { failedStage = currentBook.genStage; } } catch { /* 取不到就用默认值 */ } await bookStore.update(bookId, { genStage: 'failed', failedStage, errorMsg: error instanceof Error ? error.message : '生成失败', }); } finally { stopMonitor(); } } |