feat: 支持长篇小说分层架构(卷/弧/章三级结构)
This commit is contained in:
@@ -23,10 +23,22 @@ func MergeScenes(scenes []SceneDraft) (string, int) {
|
||||
// ReviewInterval 全局审阅间隔(每 N 章触发一次)。
|
||||
const ReviewInterval = 5
|
||||
|
||||
// ShouldReview 根据已完成章节数判断是否需要全局审阅。
|
||||
// ShouldReview 根据已完成章节数判断是否需要全局审阅(短篇/中篇模式)。
|
||||
func ShouldReview(completedCount int) (bool, string) {
|
||||
if completedCount > 0 && completedCount%ReviewInterval == 0 {
|
||||
return true, fmt.Sprintf("已完成 %d 章,触发全局审阅", completedCount)
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
// ShouldArcReview 长篇模式下判断是否需要弧级/卷级评审。
|
||||
// 弧结束时触发评审,替代固定间隔。
|
||||
func ShouldArcReview(isArcEnd, isVolumeEnd bool, volume, arc int) (bool, string) {
|
||||
if isVolumeEnd {
|
||||
return true, fmt.Sprintf("第 %d 卷第 %d 弧结束(卷结束),触发弧级+卷级评审", volume, arc)
|
||||
}
|
||||
if isArcEnd {
|
||||
return true, fmt.Sprintf("第 %d 卷第 %d 弧结束,触发弧级评审", volume, arc)
|
||||
}
|
||||
return false, ""
|
||||
}
|
||||
|
||||
@@ -38,6 +38,10 @@ type Progress struct {
|
||||
RewriteReason string `json:"rewrite_reason,omitempty"` // 重写原因
|
||||
StrandHistory []string `json:"strand_history,omitempty"` // 按章节顺序记录 dominant_strand
|
||||
HookHistory []string `json:"hook_history,omitempty"` // 按章节顺序记录 hook_type
|
||||
// 长篇分层追踪(仅长篇模式使用,短篇/中篇为零值)
|
||||
CurrentVolume int `json:"current_volume,omitempty"`
|
||||
CurrentArc int `json:"current_arc,omitempty"`
|
||||
Layered bool `json:"layered,omitempty"`
|
||||
}
|
||||
|
||||
// IsResumable 判断是否可以从断点恢复。
|
||||
@@ -64,6 +68,7 @@ type ContextProfile struct {
|
||||
SummaryWindow int // 加载最近 N 章摘要
|
||||
TimelineWindow int // 加载最近 N 章时间线
|
||||
FullContext bool // true = 忽略窗口,全量加载
|
||||
Layered bool // true = 启用分层摘要加载(卷摘要+弧摘要+章摘要)
|
||||
}
|
||||
|
||||
// NewContextProfile 根据总章节数计算上下文策略。
|
||||
@@ -74,7 +79,7 @@ func NewContextProfile(totalChapters int) ContextProfile {
|
||||
case totalChapters <= 50:
|
||||
return ContextProfile{SummaryWindow: 5, TimelineWindow: 10}
|
||||
default:
|
||||
return ContextProfile{SummaryWindow: 3, TimelineWindow: 8}
|
||||
return ContextProfile{SummaryWindow: 3, TimelineWindow: 8, Layered: true}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,6 +25,49 @@ type Character struct {
|
||||
Tier string `json:"tier,omitempty"` // core / important / secondary / decorative(默认 important)
|
||||
}
|
||||
|
||||
// VolumeOutline 卷级大纲(长篇分层模式)。
|
||||
type VolumeOutline struct {
|
||||
Index int `json:"index"`
|
||||
Title string `json:"title"`
|
||||
Theme string `json:"theme"` // 本卷核心冲突/主题
|
||||
Arcs []ArcOutline `json:"arcs"`
|
||||
}
|
||||
|
||||
// ArcOutline 弧级大纲。
|
||||
type ArcOutline struct {
|
||||
Index int `json:"index"` // 卷内弧序号
|
||||
Title string `json:"title"`
|
||||
Goal string `json:"goal"` // 弧目标(起承转合)
|
||||
Chapters []OutlineEntry `json:"chapters"`
|
||||
}
|
||||
|
||||
// TotalChapters 计算分层大纲的总章节数。
|
||||
func TotalChapters(volumes []VolumeOutline) int {
|
||||
n := 0
|
||||
for _, v := range volumes {
|
||||
for _, a := range v.Arcs {
|
||||
n += len(a.Chapters)
|
||||
}
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// FlattenOutline 将分层大纲展开为扁平章节列表,保持全局章节号连续。
|
||||
func FlattenOutline(volumes []VolumeOutline) []OutlineEntry {
|
||||
var result []OutlineEntry
|
||||
ch := 1
|
||||
for _, v := range volumes {
|
||||
for _, a := range v.Arcs {
|
||||
for _, e := range a.Chapters {
|
||||
e.Chapter = ch
|
||||
result = append(result, e)
|
||||
ch++
|
||||
}
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
// WorldRule 世界观规则条目。
|
||||
type WorldRule struct {
|
||||
Category string `json:"category"` // magic / technology / geography / society / other
|
||||
|
||||
@@ -35,6 +35,34 @@ type ChapterSummary struct {
|
||||
KeyEvents []string `json:"key_events"`
|
||||
}
|
||||
|
||||
// ArcSummary 弧级摘要,弧结束时由 Editor 生成。
|
||||
type ArcSummary struct {
|
||||
Volume int `json:"volume"`
|
||||
Arc int `json:"arc"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
KeyEvents []string `json:"key_events"`
|
||||
}
|
||||
|
||||
// VolumeSummary 卷级摘要,卷结束时生成。
|
||||
type VolumeSummary struct {
|
||||
Volume int `json:"volume"`
|
||||
Title string `json:"title"`
|
||||
Summary string `json:"summary"`
|
||||
KeyEvents []string `json:"key_events"`
|
||||
}
|
||||
|
||||
// CharacterSnapshot 角色状态快照,弧边界时记录。
|
||||
type CharacterSnapshot struct {
|
||||
Volume int `json:"volume"`
|
||||
Arc int `json:"arc"`
|
||||
Name string `json:"name"`
|
||||
Status string `json:"status"` // 存活/受伤/失踪...
|
||||
Power string `json:"power,omitempty"` // 能力变化
|
||||
Motivation string `json:"motivation"` // 当前动机
|
||||
Relations string `json:"relations,omitempty"` // 关键关系变化
|
||||
}
|
||||
|
||||
// CommitResult 是 commit_chapter 工具的结构化返回值。
|
||||
// 宿主程序和 Coordinator 读取此信号做控制决策。
|
||||
type CommitResult struct {
|
||||
@@ -47,4 +75,9 @@ type CommitResult struct {
|
||||
ReviewReason string `json:"review_reason,omitempty"`
|
||||
HookType string `json:"hook_type,omitempty"` // 钩子类型:crisis/mystery/desire/emotion/choice
|
||||
DominantStrand string `json:"dominant_strand,omitempty"` // 本章主导线:quest/fire/constellation
|
||||
// 长篇分层信号(仅 Layered 模式)
|
||||
ArcEnd bool `json:"arc_end,omitempty"`
|
||||
VolumeEnd bool `json:"volume_end,omitempty"`
|
||||
Volume int `json:"volume,omitempty"`
|
||||
Arc int `json:"arc,omitempty"`
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user