@zb2947244682/supernovel 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (131) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +122 -0
  3. package/dist/adapters/aiAdapter.d.ts +21 -0
  4. package/dist/adapters/aiAdapter.d.ts.map +1 -0
  5. package/dist/adapters/aiAdapter.js +196 -0
  6. package/dist/adapters/aiAdapter.js.map +1 -0
  7. package/dist/adapters/index.d.ts +11 -0
  8. package/dist/adapters/index.d.ts.map +1 -0
  9. package/dist/adapters/index.js +20 -0
  10. package/dist/adapters/index.js.map +1 -0
  11. package/dist/adapters/logger.d.ts +9 -0
  12. package/dist/adapters/logger.d.ts.map +1 -0
  13. package/dist/adapters/logger.js +22 -0
  14. package/dist/adapters/logger.js.map +1 -0
  15. package/dist/adapters/storageAdapter.d.ts +20 -0
  16. package/dist/adapters/storageAdapter.d.ts.map +1 -0
  17. package/dist/adapters/storageAdapter.js +190 -0
  18. package/dist/adapters/storageAdapter.js.map +1 -0
  19. package/dist/adapters/validationAdapter.d.ts +16 -0
  20. package/dist/adapters/validationAdapter.d.ts.map +1 -0
  21. package/dist/adapters/validationAdapter.js +33 -0
  22. package/dist/adapters/validationAdapter.js.map +1 -0
  23. package/dist/bus/commands.d.ts +70 -0
  24. package/dist/bus/commands.d.ts.map +1 -0
  25. package/dist/bus/commands.js +34 -0
  26. package/dist/bus/commands.js.map +1 -0
  27. package/dist/bus/dispatcher.d.ts +4 -0
  28. package/dist/bus/dispatcher.d.ts.map +1 -0
  29. package/dist/bus/dispatcher.js +313 -0
  30. package/dist/bus/dispatcher.js.map +1 -0
  31. package/dist/bus/effectRunner.d.ts +11 -0
  32. package/dist/bus/effectRunner.d.ts.map +1 -0
  33. package/dist/bus/effectRunner.js +117 -0
  34. package/dist/bus/effectRunner.js.map +1 -0
  35. package/dist/bus/index.d.ts +4 -0
  36. package/dist/bus/index.d.ts.map +1 -0
  37. package/dist/bus/index.js +6 -0
  38. package/dist/bus/index.js.map +1 -0
  39. package/dist/config/paths.d.ts +13 -0
  40. package/dist/config/paths.d.ts.map +1 -0
  41. package/dist/config/paths.js +53 -0
  42. package/dist/config/paths.js.map +1 -0
  43. package/dist/core/effects.d.ts +109 -0
  44. package/dist/core/effects.d.ts.map +1 -0
  45. package/dist/core/effects.js +42 -0
  46. package/dist/core/effects.js.map +1 -0
  47. package/dist/core/errors.d.ts +28 -0
  48. package/dist/core/errors.d.ts.map +1 -0
  49. package/dist/core/errors.js +56 -0
  50. package/dist/core/errors.js.map +1 -0
  51. package/dist/core/index.d.ts +12 -0
  52. package/dist/core/index.d.ts.map +1 -0
  53. package/dist/core/index.js +18 -0
  54. package/dist/core/index.js.map +1 -0
  55. package/dist/core/jsonUtils.d.ts +13 -0
  56. package/dist/core/jsonUtils.d.ts.map +1 -0
  57. package/dist/core/jsonUtils.js +130 -0
  58. package/dist/core/jsonUtils.js.map +1 -0
  59. package/dist/core/logger.d.ts +16 -0
  60. package/dist/core/logger.d.ts.map +1 -0
  61. package/dist/core/logger.js +59 -0
  62. package/dist/core/logger.js.map +1 -0
  63. package/dist/core/ports.d.ts +57 -0
  64. package/dist/core/ports.d.ts.map +1 -0
  65. package/dist/core/ports.js +3 -0
  66. package/dist/core/ports.js.map +1 -0
  67. package/dist/core/rag/consistency.d.ts +51 -0
  68. package/dist/core/rag/consistency.d.ts.map +1 -0
  69. package/dist/core/rag/consistency.js +239 -0
  70. package/dist/core/rag/consistency.js.map +1 -0
  71. package/dist/core/rag/contextAssembler.d.ts +44 -0
  72. package/dist/core/rag/contextAssembler.d.ts.map +1 -0
  73. package/dist/core/rag/contextAssembler.js +278 -0
  74. package/dist/core/rag/contextAssembler.js.map +1 -0
  75. package/dist/core/rag/index.d.ts +12 -0
  76. package/dist/core/rag/index.d.ts.map +1 -0
  77. package/dist/core/rag/index.js +15 -0
  78. package/dist/core/rag/index.js.map +1 -0
  79. package/dist/core/rag/knowledgeGraph.d.ts +72 -0
  80. package/dist/core/rag/knowledgeGraph.d.ts.map +1 -0
  81. package/dist/core/rag/knowledgeGraph.js +227 -0
  82. package/dist/core/rag/knowledgeGraph.js.map +1 -0
  83. package/dist/core/rag/summaries.d.ts +57 -0
  84. package/dist/core/rag/summaries.d.ts.map +1 -0
  85. package/dist/core/rag/summaries.js +251 -0
  86. package/dist/core/rag/summaries.js.map +1 -0
  87. package/dist/core/rag/types.d.ts +201 -0
  88. package/dist/core/rag/types.d.ts.map +1 -0
  89. package/dist/core/rag/types.js +4 -0
  90. package/dist/core/rag/types.js.map +1 -0
  91. package/dist/core/rag/vectorStore.d.ts +68 -0
  92. package/dist/core/rag/vectorStore.d.ts.map +1 -0
  93. package/dist/core/rag/vectorStore.js +211 -0
  94. package/dist/core/rag/vectorStore.js.map +1 -0
  95. package/dist/core/types.d.ts +246 -0
  96. package/dist/core/types.d.ts.map +1 -0
  97. package/dist/core/types.js +3 -0
  98. package/dist/core/types.js.map +1 -0
  99. package/dist/core/usecases/generateChapter.d.ts +26 -0
  100. package/dist/core/usecases/generateChapter.d.ts.map +1 -0
  101. package/dist/core/usecases/generateChapter.js +132 -0
  102. package/dist/core/usecases/generateChapter.js.map +1 -0
  103. package/dist/core/usecases/generateChapterRAG.d.ts +40 -0
  104. package/dist/core/usecases/generateChapterRAG.d.ts.map +1 -0
  105. package/dist/core/usecases/generateChapterRAG.js +221 -0
  106. package/dist/core/usecases/generateChapterRAG.js.map +1 -0
  107. package/dist/core/usecases/generateOutline.d.ts +19 -0
  108. package/dist/core/usecases/generateOutline.d.ts.map +1 -0
  109. package/dist/core/usecases/generateOutline.js +129 -0
  110. package/dist/core/usecases/generateOutline.js.map +1 -0
  111. package/dist/core/usecases/generateWorld.d.ts +18 -0
  112. package/dist/core/usecases/generateWorld.d.ts.map +1 -0
  113. package/dist/core/usecases/generateWorld.js +189 -0
  114. package/dist/core/usecases/generateWorld.js.map +1 -0
  115. package/dist/core/usecases/parseRequirements.d.ts +20 -0
  116. package/dist/core/usecases/parseRequirements.d.ts.map +1 -0
  117. package/dist/core/usecases/parseRequirements.js +95 -0
  118. package/dist/core/usecases/parseRequirements.js.map +1 -0
  119. package/dist/core/usecases/validateNovel.d.ts +29 -0
  120. package/dist/core/usecases/validateNovel.d.ts.map +1 -0
  121. package/dist/core/usecases/validateNovel.js +156 -0
  122. package/dist/core/usecases/validateNovel.js.map +1 -0
  123. package/dist/shell/cli.d.ts +3 -0
  124. package/dist/shell/cli.d.ts.map +1 -0
  125. package/dist/shell/cli.js +158 -0
  126. package/dist/shell/cli.js.map +1 -0
  127. package/dist/shell/index.d.ts +3 -0
  128. package/dist/shell/index.d.ts.map +1 -0
  129. package/dist/shell/index.js +279 -0
  130. package/dist/shell/index.js.map +1 -0
  131. package/package.json +69 -0
@@ -0,0 +1,221 @@
1
+ // UseCase: 使用RAG生成章节(支持长篇一致性)
2
+ import { Effects } from '../effects.js';
3
+ import { AppError } from '../errors.js';
4
+ import { globalContextAssembler, globalConsistencyChecker, globalVectorStore, globalSummaryManager, generateSimpleEmbedding } from '../rag/index.js';
5
+ /**
6
+ * 使用RAG生成章节
7
+ */
8
+ export function generateChapterRAG(input) {
9
+ const { project, volumeNumber, chapterNumber, useRAG = true } = input;
10
+ // 查找章节蓝图
11
+ const volume = project.outline.volumes.find(v => v.number === volumeNumber);
12
+ if (!volume) {
13
+ throw new AppError('NOT_FOUND', `卷 ${volumeNumber} 不存在`);
14
+ }
15
+ const blueprint = volume.chapters.find(c => c.number === chapterNumber);
16
+ if (!blueprint) {
17
+ throw new AppError('NOT_FOUND', `第 ${chapterNumber} 章不存在`);
18
+ }
19
+ // 构建上下文
20
+ let contextPrompt;
21
+ let ragContext = null;
22
+ if (useRAG) {
23
+ // 使用RAG组装上下文
24
+ ragContext = globalContextAssembler.assembleContext(project, blueprint);
25
+ contextPrompt = globalContextAssembler.formatContextForPrompt(ragContext);
26
+ }
27
+ else {
28
+ // 使用传统上下文
29
+ contextPrompt = buildTraditionalContext(project, blueprint);
30
+ }
31
+ // 构建写作提示
32
+ const systemPrompt = buildSystemPrompt(project, blueprint, ragContext);
33
+ const userPrompt = buildUserPrompt(contextPrompt, blueprint, project);
34
+ const effect = Effects.aiChat([
35
+ { role: 'system', content: systemPrompt },
36
+ { role: 'user', content: userPrompt }
37
+ ], input.config);
38
+ return {
39
+ result: {},
40
+ effects: [
41
+ effect,
42
+ Effects.logProgress('generating', project.chapters.length + 1, project.outline.volumes.reduce((sum, v) => sum + v.chapters.length, 0), `正在生成第${volumeNumber}卷第${chapterNumber}章...`)
43
+ ]
44
+ };
45
+ }
46
+ /**
47
+ * 构建传统上下文(作为回退)
48
+ */
49
+ function buildTraditionalContext(project, blueprint) {
50
+ const prevChapter = project.chapters.find(c => c.volume === blueprint.volume && c.number === blueprint.number - 1);
51
+ const relevantChars = project.worldState.characters.filter(c => blueprint.scenes.some(s => s.characters.includes(c.id)));
52
+ let context = `## 第${blueprint.volume}卷第${blueprint.number}章:${blueprint.title}
53
+
54
+ ### 大纲要求
55
+ 功能:${blueprint.function}
56
+ 情绪走向:${blueprint.emotionalArc}
57
+
58
+ ### 角色档案
59
+ ${relevantChars.map(c => `
60
+ ${c.name}:
61
+ - 性格:${c.personality.coreTraits.join(', ')}
62
+ - 动机:${c.motivation}
63
+ - 当前状态:${c.currentState.status}
64
+ `).join('\n')}
65
+ `;
66
+ if (prevChapter) {
67
+ context += `
68
+ ### 前一章结尾
69
+ ${prevChapter.content.slice(-500)}
70
+ `;
71
+ }
72
+ return context;
73
+ }
74
+ /**
75
+ * 构建系统提示词
76
+ */
77
+ function buildSystemPrompt(project, blueprint, ragContext) {
78
+ let prompt = `你是一位专业的小说作家,擅长创作长篇小说。
79
+
80
+ 写作要求:
81
+ 1. 严格遵循大纲的功能要求
82
+ 2. 保持角色性格一致性
83
+ 3. 场景切换自然流畅
84
+ 4. 对话符合角色身份
85
+ 5. 描写细腻,有画面感
86
+ 6. 情绪走向符合大纲设计
87
+ 7. 埋设和回收指定的伏笔
88
+ 8. 字数控制在${project.requirements.wordsPerChapter}字左右
89
+
90
+ 重要:直接输出章节正文,不要添加章节标题(如"第X章"),系统会自动添加。`;
91
+ // 如果有RAG上下文,添加一致性提醒
92
+ if (ragContext) {
93
+ prompt += `
94
+
95
+ 一致性要求:
96
+ - 角色状态必须与前文一致
97
+ - 不要引入违背世界观设定的能力或物品
98
+ - 伏笔回收要有逻辑铺垫
99
+ - 时间线要保持连续`;
100
+ // 如果有待回收伏笔,特别说明
101
+ if (ragContext.pendingHooks && ragContext.pendingHooks.length > 0) {
102
+ prompt += `
103
+
104
+ 本章节涉及以下伏笔:
105
+ ${ragContext.pendingHooks.slice(0, 5).map((h) => `- ${h}`).join('\n')}`;
106
+ }
107
+ }
108
+ return prompt;
109
+ }
110
+ /**
111
+ * 构建用户提示词
112
+ */
113
+ function buildUserPrompt(contextPrompt, blueprint, project) {
114
+ return `${contextPrompt}
115
+
116
+ ===
117
+
118
+ 请开始写作第${blueprint.volume}卷第${blueprint.number}章「${blueprint.title}」(约${project.requirements.wordsPerChapter}字)
119
+
120
+ 场景设计:
121
+ ${blueprint.scenes.map((s, i) => `
122
+ 场景${i + 1}:
123
+ - 地点:${s.location}
124
+ - 角色:${s.characters.join(', ')}
125
+ - 事件:${s.event}
126
+ `).join('\n')}
127
+
128
+ 直接输出正文内容,不要添加标题:`;
129
+ }
130
+ /**
131
+ * 解析AI响应为章节
132
+ */
133
+ export function parseChapterFromAIResponse(aiContent, blueprint) {
134
+ // 清理AI可能添加的标题
135
+ let content = aiContent.trim();
136
+ // 移除常见的标题格式
137
+ content = content.replace(/^#+\s*第[\d一二三四五六七八九十]+章[::]?.*\n*/m, '');
138
+ content = content.replace(/^第[\d一二三四五六七八九十]+章[::]?.*\n*/m, '');
139
+ content = content.replace(/^#+\s*.+\n*/m, '');
140
+ return {
141
+ id: blueprint.id,
142
+ volume: blueprint.volume,
143
+ number: blueprint.number,
144
+ title: blueprint.title,
145
+ content: content.trim(),
146
+ summary: '',
147
+ wordCount: content.length,
148
+ extractedFacts: [],
149
+ characterStateChanges: [],
150
+ newRelationships: [],
151
+ validationResults: []
152
+ };
153
+ }
154
+ /**
155
+ * 提取章节摘要(使用AI)
156
+ */
157
+ export function extractChapterSummary(chapter, config) {
158
+ const systemPrompt = `请为以下小说章节提取:
159
+ 1. 简短摘要(50字以内,概括主要情节)
160
+ 2. 关键事件列表(2-5个)
161
+
162
+ 以JSON格式输出:
163
+ {
164
+ "summary": "摘要内容",
165
+ "keyEvents": ["事件1", "事件2"]
166
+ }`;
167
+ const userPrompt = `章节标题:${chapter.title}
168
+
169
+ 内容:
170
+ ${chapter.content.slice(0, 1500)}...
171
+
172
+ 请提取摘要和关键事件:`;
173
+ return {
174
+ result: { summary: '', keyEvents: [] },
175
+ effects: [Effects.aiChat([
176
+ { role: 'system', content: systemPrompt },
177
+ { role: 'user', content: userPrompt }
178
+ ], config)]
179
+ };
180
+ }
181
+ /**
182
+ * 检查章节一致性
183
+ */
184
+ export function checkChapterConsistency(chapter, project) {
185
+ const violations = globalConsistencyChecker.checkChapter(chapter, project);
186
+ const summary = globalConsistencyChecker.summarizeViolations(violations);
187
+ return {
188
+ result: {
189
+ violations,
190
+ passed: summary.errors === 0
191
+ },
192
+ effects: [
193
+ Effects.logInfo(`一致性检查完成`, {
194
+ errors: summary.errors,
195
+ warnings: summary.warnings
196
+ })
197
+ ]
198
+ };
199
+ }
200
+ /**
201
+ * 更新RAG索引
202
+ */
203
+ export function updateRAGIndex(chapter, project, summary, keyEvents) {
204
+ // 创建章节嵌入
205
+ const embedding = generateSimpleEmbedding(chapter.content);
206
+ globalVectorStore.addChapterEmbedding({
207
+ chapterId: `chapter-${chapter.volume}-${chapter.number}`,
208
+ volumeNumber: chapter.volume,
209
+ chapterNumber: chapter.number,
210
+ embedding,
211
+ content: chapter.content,
212
+ summary: summary || `第${chapter.volume}卷第${chapter.number}章:${chapter.title}`,
213
+ keyEvents: keyEvents || [],
214
+ charactersInvolved: (chapter.characterStateChanges || []).map((c) => c.characterId),
215
+ locationsInvolved: [],
216
+ createdAt: new Date().toISOString()
217
+ });
218
+ // 更新摘要管理器
219
+ globalSummaryManager.addChapterSummary(chapter, summary);
220
+ }
221
+ //# sourceMappingURL=generateChapterRAG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateChapterRAG.js","sourceRoot":"","sources":["../../../src/core/usecases/generateChapterRAG.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import type { NovelRequirements, WorldState, NovelOutline, AIConfig } from '../types.js';
2
+ import type { WithEffects } from '../effects.js';
3
+ export interface GenerateOutlineInput {
4
+ requirements: NovelRequirements;
5
+ worldState: WorldState;
6
+ config: AIConfig;
7
+ }
8
+ export interface GenerateOutlineOutput {
9
+ outline: NovelOutline;
10
+ }
11
+ /**
12
+ * 生成大纲
13
+ */
14
+ export declare function generateOutline(input: GenerateOutlineInput): WithEffects<GenerateOutlineOutput>;
15
+ /**
16
+ * 解析AI响应为大纲
17
+ */
18
+ export declare function parseOutlineFromAIResponse(aiContent: string): NovelOutline;
19
+ //# sourceMappingURL=generateOutline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateOutline.d.ts","sourceRoot":"","sources":["../../../src/core/usecases/generateOutline.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACzF,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,MAAM,WAAW,oBAAoB;IACnC,YAAY,EAAE,iBAAiB,CAAC;IAChC,UAAU,EAAE,UAAU,CAAC;IACvB,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,qBAAqB;IACpC,OAAO,EAAE,YAAY,CAAC;CACvB;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,KAAK,EAAE,oBAAoB,GAAG,WAAW,CAAC,qBAAqB,CAAC,CAsG/F;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,CAuB1E"}
@@ -0,0 +1,129 @@
1
+ // UseCase: 生成大纲
2
+ // 纯函数:输入需求和世界状态,输出大纲
3
+ import { Effects } from '../effects.js';
4
+ import { extractJSONFromAIResponse, safeJSONParse } from '../jsonUtils.js';
5
+ /**
6
+ * 生成大纲
7
+ */
8
+ export function generateOutline(input) {
9
+ const systemPrompt = `你是一位专业的大纲规划师。请根据需求和世界设定生成完整的大纲。
10
+
11
+ 输出JSON格式:
12
+ {
13
+ "title": "小说标题",
14
+ "subtitle": "副标题(可选)",
15
+ "theme": "主题",
16
+ "coreQuestion": "全书核心问题(主角要解决的根本问题)",
17
+ "emotionalArc": "情感弧线(主角的情感变化轨迹)",
18
+ "climax": "高潮描述",
19
+ "ending": "结局描述",
20
+ "volumes": [
21
+ {
22
+ "number": 1,
23
+ "title": "卷标题",
24
+ "function": "本卷功能",
25
+ "coreTask": "本卷核心任务",
26
+ "endingState": "卷末状态",
27
+ "mainConflict": "核心矛盾",
28
+ "twist": "卷末转折",
29
+ "arcSummaries": ["情节概要1"],
30
+ "chapters": [
31
+ {
32
+ "id": "ch_1_1",
33
+ "number": 1,
34
+ "title": "章节标题",
35
+ "function": "本章功能描述(推动什么情节)",
36
+ "scenes": [
37
+ {
38
+ "id": "scene_1_1_1",
39
+ "location": "场景地点ID",
40
+ "characters": ["在场角色ID"],
41
+ "event": "发生的事件",
42
+ "infoRevealed": ["揭示的信息"]
43
+ }
44
+ ],
45
+ "emotionalArc": "情绪走向",
46
+ "hooksToPlant": ["要埋的伏笔ID"],
47
+ "hooksToResolve": ["要收的伏笔ID"],
48
+ "worldStateChanges": ["世界状态变更"],
49
+ "expectedWordCount": 3000
50
+ }
51
+ ]
52
+ }
53
+ ]
54
+ }
55
+
56
+ 规划要求:
57
+ 1. 每章必须有明确功能,不允许纯"过渡水章"
58
+ 2. 每章至少推进一条主线
59
+ 3. 伏笔埋设和回收要按计划进行
60
+ 4. 情绪弧线要合理变化,有起伏
61
+ 5. 场景设计要符合地点设定
62
+ 6. 角色行为要符合性格档案
63
+ 7. 章节之间要有因果联系,不是孤立事件
64
+
65
+ 只输出JSON。`;
66
+ const chaptersPerVolume = input.requirements.chaptersPerVolume || [5];
67
+ const userPrompt = `请为以下小说生成大纲:
68
+
69
+ ## 需求
70
+ 标题:${input.requirements.title}
71
+ 题材:${input.requirements.genre}
72
+ 总卷数:${input.requirements.totalVolumes || 1}
73
+ 每卷章节:${chaptersPerVolume.join(', ')}
74
+ 每章字数:${input.requirements.wordsPerChapter}
75
+
76
+ ## 世界设定
77
+ 世界观:${input.worldState.background?.substring(0, 200) || input.worldState.worldview?.substring(0, 200)}...
78
+
79
+ 角色:
80
+ ${input.worldState.characters.map(c => `- ${c.name}: ${c.motivation?.substring(0, 50)}`).join('\n')}
81
+
82
+ 地点:
83
+ ${input.worldState.locations.map(l => `- ${l.name}: ${l.description?.substring(0, 50)}`).join('\n')}
84
+
85
+ 伏笔:
86
+ ${input.worldState.foreshadowings.map(h => `- ${h.id}: ${h.content?.substring(0, 30)} (埋设:${h.setupChapter}, 回收:${h.plannedResolution})`).join('\n')}
87
+
88
+ ## 创意
89
+ ${input.requirements.rawInput}
90
+
91
+ 请生成完整大纲JSON。`;
92
+ const effect = Effects.aiChat([
93
+ { role: 'system', content: systemPrompt },
94
+ { role: 'user', content: userPrompt }
95
+ ], input.config);
96
+ return {
97
+ result: {},
98
+ effects: [
99
+ effect,
100
+ Effects.logProgress('outline', 2, 5, '正在生成大纲...')
101
+ ]
102
+ };
103
+ }
104
+ /**
105
+ * 解析AI响应为大纲
106
+ */
107
+ export function parseOutlineFromAIResponse(aiContent) {
108
+ const jsonStr = extractJSONFromAIResponse(aiContent);
109
+ const parsed = safeJSONParse(jsonStr);
110
+ // 确保每个 chapter 都有正确的 volume 属性
111
+ const volumes = (parsed.volumes || []).map((vol) => ({
112
+ ...vol,
113
+ chapters: (vol.chapters || []).map((ch) => ({
114
+ ...ch,
115
+ volume: vol.number // 确保每个 chapter 继承所在 volume 的 number
116
+ }))
117
+ }));
118
+ return {
119
+ title: parsed.title || '未命名',
120
+ subtitle: parsed.subtitle,
121
+ theme: parsed.theme || '',
122
+ coreQuestion: parsed.coreQuestion || '',
123
+ emotionalArc: parsed.emotionalArc || '',
124
+ climax: parsed.climax || '',
125
+ ending: parsed.ending || '',
126
+ volumes
127
+ };
128
+ }
129
+ //# sourceMappingURL=generateOutline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateOutline.js","sourceRoot":"","sources":["../../../src/core/usecases/generateOutline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ import type { NovelRequirements, WorldState, AIConfig } from '../types.js';
2
+ import type { WithEffects } from '../effects.js';
3
+ export interface GenerateWorldInput {
4
+ requirements: NovelRequirements;
5
+ config: AIConfig;
6
+ }
7
+ export interface GenerateWorldOutput {
8
+ worldState: WorldState;
9
+ }
10
+ /**
11
+ * 生成世界设定
12
+ */
13
+ export declare function generateWorld(input: GenerateWorldInput): WithEffects<GenerateWorldOutput>;
14
+ /**
15
+ * 解析AI响应为世界状态
16
+ */
17
+ export declare function parseWorldFromAIResponse(aiContent: string): WorldState;
18
+ //# sourceMappingURL=generateWorld.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateWorld.d.ts","sourceRoot":"","sources":["../../../src/core/usecases/generateWorld.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC3E,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAIjD,MAAM,WAAW,kBAAkB;IACjC,YAAY,EAAE,iBAAiB,CAAC;IAChC,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,UAAU,CAAC;CACxB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,KAAK,EAAE,kBAAkB,GAAG,WAAW,CAAC,mBAAmB,CAAC,CAmKzF;AAED;;GAEG;AACH,wBAAgB,wBAAwB,CAAC,SAAS,EAAE,MAAM,GAAG,UAAU,CAoBtE"}
@@ -0,0 +1,189 @@
1
+ // UseCase: 生成世界设定
2
+ // 纯函数:输入需求,输出世界状态
3
+ import { Effects } from '../effects.js';
4
+ import { extractJSONFromAIResponse, safeJSONParse } from '../jsonUtils.js';
5
+ /**
6
+ * 生成世界设定
7
+ */
8
+ export function generateWorld(input) {
9
+ const systemPrompt = `你是一位专业的小说世界构建师。请根据需求生成完整的世界设定。
10
+
11
+ 输出JSON格式:
12
+ {
13
+ "background": "世界观背景描述(300-500字,包括背景、历史、社会结构)",
14
+ "worldview": "世界观概述",
15
+ "characters": [
16
+ {
17
+ "id": "char_001",
18
+ "name": "角色名",
19
+ "identity": "身份/角色定位",
20
+ "aliases": ["别名"],
21
+ "gender": "male/female/other",
22
+ "age": "年龄描述",
23
+ "appearance": {
24
+ "height": "身高",
25
+ "build": "体型",
26
+ "distinctiveFeatures": ["显著特征1", "显著特征2"],
27
+ "commonAttire": "常见穿着"
28
+ },
29
+ "personality": {
30
+ "coreTraits": ["核心特质1", "核心特质2"],
31
+ "weaknesses": ["弱点1"],
32
+ "catchphrases": ["口头禅"],
33
+ "speechStyle": "说话风格描述",
34
+ "surfaceBehaviors": ["表面行为1"]
35
+ },
36
+ "background": {
37
+ "origin": "出身背景",
38
+ "keyExperiences": ["关键经历1", "关键经历2"]
39
+ },
40
+ "motivation": "核心动机(50字内)",
41
+ "abilities": {
42
+ "acquired": ["已有能力1", "已有能力2"],
43
+ "notYetAcquired": ["未获得能力1"],
44
+ "limitDescription": "能力限制描述"
45
+ },
46
+ "arc": {
47
+ "type": "flat/growth/fall/transformation",
48
+ "stages": ["阶段1", "阶段2"]
49
+ },
50
+ "currentState": {
51
+ "location": "当前位置",
52
+ "health": "健康状态",
53
+ "items": ["持有物品1"],
54
+ "knownInfo": ["已知信息1"],
55
+ "unknownInfo": ["未知信息1"],
56
+ "emotion": "当前情绪",
57
+ "currentEmotion": "当前情绪",
58
+ "emotionSource": "情绪来源",
59
+ "status": "当前状态"
60
+ }
61
+ }
62
+ ],
63
+ "locations": [
64
+ {
65
+ "id": "loc_001",
66
+ "name": "地点名",
67
+ "type": "类型",
68
+ "region": "所属区域",
69
+ "description": "描述(100字内)",
70
+ "keyLandmarks": ["地标1", "地标2"],
71
+ "distances": {"其他地点ID": "距离描述"},
72
+ "socialEnvironment": "社会环境",
73
+ "currentSeasonWeather": "当前季节天气",
74
+ "significance": "重要性"
75
+ }
76
+ ],
77
+ "rules": [
78
+ {
79
+ "id": "rule_001",
80
+ "category": "magic/social/info-transmission/physics",
81
+ "content": "规则内容",
82
+ "exceptions": "例外情况(可选)"
83
+ }
84
+ ],
85
+ "relationships": [
86
+ {
87
+ "fromId": "角色ID",
88
+ "toId": "角色ID",
89
+ "type": "关系类型",
90
+ "direction": "unidirectional/bidirectional/hidden",
91
+ "description": "描述"
92
+ }
93
+ ],
94
+ "timeline": [
95
+ {
96
+ "id": "event_001",
97
+ "date": "第1卷开始前",
98
+ "description": "事件描述",
99
+ "characters": ["涉及角色ID"],
100
+ "location": "发生地点",
101
+ "impact": "影响"
102
+ }
103
+ ],
104
+ "foreshadowings": [
105
+ {
106
+ "id": "hook_001",
107
+ "content": "伏笔内容",
108
+ "setupChapter": "计划埋设章节",
109
+ "plannedResolution": "计划回收章节",
110
+ "reminderPlan": "中间提醒节奏"
111
+ }
112
+ ],
113
+ "facts": [
114
+ {
115
+ "id": "fact_001",
116
+ "content": "事实内容",
117
+ "effectiveTime": "生效时间",
118
+ "isActive": true
119
+ }
120
+ ],
121
+ "plotThreads": [
122
+ {
123
+ "id": "thread_001",
124
+ "name": "叙事线名称",
125
+ "description": "描述",
126
+ "status": "active/paused/completed"
127
+ }
128
+ ]
129
+ }
130
+
131
+ 构建要求:
132
+ 1. 角色数量:主角1-2人,重要配角2-4人,功能性角色若干
133
+ 2. 角色必须有明确叙事功能,避免功能重复
134
+ 3. 地点要有距离关系,便于后续计算旅途时间
135
+ 4. 规则要覆盖:力量体系、社会规则、信息传播
136
+ 5. 关系图谱要有张力和冲突,不只是友好关系
137
+ 6. 伏笔要可追踪,计划回收点明确
138
+ 7. 事实表用于追踪可变更的世界状态
139
+
140
+ 重要:必须输出完整、格式正确的JSON,确保所有数组和对象都正确闭合。不要输出任何JSON之外的内容。`;
141
+ const userPrompt = `请为以下小说生成世界设定:
142
+
143
+ 标题:${input.requirements.title}
144
+ 题材:${input.requirements.genre}${input.requirements.subGenre ? '/' + input.requirements.subGenre : ''}
145
+ 基调:${input.requirements.tone}
146
+ 风格参考:${input.requirements.styleReference || '无'}
147
+ 必须包含:${input.requirements.requiredElements?.join(', ') || '无'}
148
+ 禁止元素:${input.requirements.forbiddenElements?.join(', ') || '无'}
149
+
150
+ 创意描述:
151
+ ${input.requirements.rawInput}
152
+
153
+ 请生成完整的世界设定JSON。`;
154
+ const effect = Effects.aiChat([
155
+ { role: 'system', content: systemPrompt },
156
+ { role: 'user', content: userPrompt }
157
+ ], input.config);
158
+ return {
159
+ result: {},
160
+ effects: [
161
+ effect,
162
+ Effects.logProgress('world-building', 1, 5, '正在生成世界设定...')
163
+ ]
164
+ };
165
+ }
166
+ /**
167
+ * 解析AI响应为世界状态
168
+ */
169
+ export function parseWorldFromAIResponse(aiContent) {
170
+ const jsonStr = extractJSONFromAIResponse(aiContent);
171
+ const parsed = safeJSONParse(jsonStr);
172
+ return {
173
+ background: parsed.background || parsed.worldview || '',
174
+ worldview: parsed.worldview || '',
175
+ characters: parsed.characters || [],
176
+ locations: parsed.locations || [],
177
+ rules: parsed.rules || [],
178
+ relationships: parsed.relationships || [],
179
+ timeline: parsed.timeline || [],
180
+ foreshadowings: parsed.foreshadowings?.map((h) => ({
181
+ ...h,
182
+ status: 'planted',
183
+ reminderCount: 0
184
+ })) || [],
185
+ facts: parsed.facts || [],
186
+ plotThreads: parsed.plotThreads || []
187
+ };
188
+ }
189
+ //# sourceMappingURL=generateWorld.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generateWorld.js","sourceRoot":"","sources":["../../../src/core/usecases/generateWorld.ts"],"names":[],"mappings":"AAAA,kBAAkB;AAClB,kBAAkB;AAIlB,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAC;AACxC,OAAO,EAAE,yBAAyB,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAW3E;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,KAAyB;IACrD,MAAM,YAAY,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oDAmI6B,CAAC;IAEnD,MAAM,UAAU,GAAG;;KAEhB,KAAK,CAAC,YAAY,CAAC,KAAK;KACxB,KAAK,CAAC,YAAY,CAAC,KAAK,GAAG,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,GAAG,GAAG,KAAK,CAAC,YAAY,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE;KAC/F,KAAK,CAAC,YAAY,CAAC,IAAI;OACrB,KAAK,CAAC,YAAY,CAAC,cAAc,IAAI,GAAG;OACxC,KAAK,CAAC,YAAY,CAAC,gBAAgB,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG;OACtD,KAAK,CAAC,YAAY,CAAC,iBAAiB,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG;;;EAG5D,KAAK,CAAC,YAAY,CAAC,QAAQ;;gBAEb,CAAC;IAEf,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAC3B;QACE,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,YAAY,EAAE;QACzC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,UAAU,EAAE;KACtC,EACD,KAAK,CAAC,MAAM,CACb,CAAC;IAEF,OAAO;QACL,MAAM,EAAE,EAAyB;QACjC,OAAO,EAAE;YACP,MAAM;YACN,OAAO,CAAC,WAAW,CAAC,gBAAgB,EAAE,CAAC,EAAE,CAAC,EAAE,aAAa,CAAC;SAC3D;KACF,CAAC;AACJ,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,wBAAwB,CAAC,SAAiB;IACxD,MAAM,OAAO,GAAG,yBAAyB,CAAC,SAAS,CAAC,CAAC;IACrD,MAAM,MAAM,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;IAEtC,OAAO;QACL,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,MAAM,CAAC,SAAS,IAAI,EAAE;QACvD,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;QACjC,UAAU,EAAE,MAAM,CAAC,UAAU,IAAI,EAAE;QACnC,SAAS,EAAE,MAAM,CAAC,SAAS,IAAI,EAAE;QACjC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;QACzB,aAAa,EAAE,MAAM,CAAC,aAAa,IAAI,EAAE;QACzC,QAAQ,EAAE,MAAM,CAAC,QAAQ,IAAI,EAAE;QAC/B,cAAc,EAAE,MAAM,CAAC,cAAc,EAAE,GAAG,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC;YACtD,GAAG,CAAC;YACJ,MAAM,EAAE,SAAS;YACjB,aAAa,EAAE,CAAC;SACjB,CAAC,CAAC,IAAI,EAAE;QACT,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC,WAAW,IAAI,EAAE;KACtC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,20 @@
1
+ import type { NovelRequirements, AIConfig } from '../types.js';
2
+ import type { WithEffects } from '../effects.js';
3
+ export interface ParseRequirementsInput {
4
+ userPrompt: string;
5
+ config: AIConfig;
6
+ }
7
+ export interface ParseRequirementsOutput {
8
+ requirements: NovelRequirements;
9
+ }
10
+ /**
11
+ * 解析用户自然语言需求为结构化需求
12
+ * 纯函数:只构建AI请求,不执行I/O
13
+ */
14
+ export declare function parseRequirements(input: ParseRequirementsInput): WithEffects<ParseRequirementsOutput>;
15
+ /**
16
+ * 解析AI响应为NovelRequirements
17
+ * 这个函数处理AI返回的JSON字符串
18
+ */
19
+ export declare function parseRequirementsFromAIResponse(aiContent: string): NovelRequirements;
20
+ //# sourceMappingURL=parseRequirements.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parseRequirements.d.ts","sourceRoot":"","sources":["../../../src/core/usecases/parseRequirements.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,iBAAiB,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAC/D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAKjD,MAAM,WAAW,sBAAsB;IACrC,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,QAAQ,CAAC;CAClB;AAED,MAAM,WAAW,uBAAuB;IACtC,YAAY,EAAE,iBAAiB,CAAC;CACjC;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,sBAAsB,GAC5B,WAAW,CAAC,uBAAuB,CAAC,CAsDtC;AAED;;;GAGG;AACH,wBAAgB,+BAA+B,CAAC,SAAS,EAAE,MAAM,GAAG,iBAAiB,CAgCpF"}