|
@@ -560,6 +560,20 @@ ${antiText}
|
|
|
}
|
|
}
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+ // Read marathon outline if it exists
|
|
|
|
|
+ let marathonOutline = '';
|
|
|
|
|
+ try {
|
|
|
|
|
+ const moRes = await fetch('/api/novel/files', {
|
|
|
|
|
+ method: 'POST',
|
|
|
|
|
+ headers: { 'Content-Type': 'application/json' },
|
|
|
|
|
+ body: JSON.stringify({ action: 'read', projectPath, filePath: 'world_state/marathon-outline.md' }),
|
|
|
|
|
+ });
|
|
|
|
|
+ if (moRes.ok) {
|
|
|
|
|
+ const moData = await moRes.json();
|
|
|
|
|
+ if (moData.content) marathonOutline = moData.content;
|
|
|
|
|
+ }
|
|
|
|
|
+ } catch { /* ignore */ }
|
|
|
|
|
+
|
|
|
const worldContext = buildLayeredContext(
|
|
const worldContext = buildLayeredContext(
|
|
|
worldStateFiles,
|
|
worldStateFiles,
|
|
|
loreFiles,
|
|
loreFiles,
|
|
@@ -568,7 +582,13 @@ ${antiText}
|
|
|
rollingSummaries
|
|
rollingSummaries
|
|
|
);
|
|
);
|
|
|
|
|
|
|
|
- const prompt = await buildGenerationPrompt(worldContext);
|
|
|
|
|
|
|
+ const marathonSection = marathonOutline
|
|
|
|
|
+ ? `## 马拉松大纲(第${chapterIndex}章在整体弧中的位置)\n${marathonOutline}`
|
|
|
|
|
+ : '';
|
|
|
|
|
+
|
|
|
|
|
+ const prompt = await buildGenerationPrompt(
|
|
|
|
|
+ marathonSection ? `${marathonSection}\n\n${worldContext}` : worldContext
|
|
|
|
|
+ );
|
|
|
|
|
|
|
|
const response = await fetch('/api/stream-proxy', {
|
|
const response = await fetch('/api/stream-proxy', {
|
|
|
method: 'POST',
|
|
method: 'POST',
|