imp

package
v0.7.5 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 2, 2026 License: Apache-2.0 Imports: 26 Imported by: 0

Documentation

Overview

Package imp 实现外部小说的分阶段语义导入管线(docs/import-pipeline.md)。

模型负责理解开放语义,代码负责坐标、覆盖、类型、哈希、顺序和幂等;全部语义产物在 独立工作区(meta/import/)验证完成后,才发布到正式书籍状态。下一动作只从工件推导 (NextAction),不存会漂移的阶段枚举,恢复不依赖 from=N。

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func AnalyzeNext added in v0.7.2

func AnalyzeNext(ctx context.Context, m callModel, systemPrompt string, w *Workspace, normalized []byte, seg *Segmentation, segIdentity, promptVersion string, budget AnalyzeBudget, prof callProfile) (int, error)

AnalyzeNext 从第一份缺失分析起组一个批次并原子落盘,返回本次提交的章节数。 截断即「失败 + 缩小重组批」(默认,§9.5);批次已缩到单章仍截断则显式报告容量不足。

func Digest added in v0.7.2

func Digest(data []byte) string

Digest 计算内容摘要,沿用仓库既有约定 "sha256:"+hex(见 store/checkpoints.go)。

func Ingest added in v0.7.2

func Ingest(bookDir, sourcePath string, in Intent) (*Workspace, *Manifest, error)

Ingest 读取源文件,解码、归一化,并以目录 rename 原子创建 meta/import/ 工作区快照。 返回工作区句柄与 Manifest;调用方据此发出进度事件。

func ResumeStatus added in v0.7.2

func ResumeStatus(st *store.Store) (active, done bool, err error)

ResumeStatus 报告是否存在活动导入工作区,以及它是否已彻底完成(含正式发布对账)。 供跨重启 Engine 门禁使用(RFC §12.5):active && !done 时禁止普通创作流程消费半发布状态。

func ResumeSummary added in v0.7.2

func ResumeSummary(st *store.Store) string

ResumeSummary 生成未完成导入的一行提示(RFC §18.2);无未完成导入返回空串。 供宿主在启动/欢迎界面主动告知,避免用户只有在创作被门禁拒绝时才发现这本书停在导入半路。

func Run

func Run(ctx context.Context, deps Deps, opts Options) (<-chan Event, error)

Run 执行完整导入管线:LoadState → NextAction → 执行一个动作 → 重新读取事实。 在自己的 goroutine 中跑;返回的事件通道由本函数关闭。

Types

type Action added in v0.7.2

type Action string

Action 是 NextAction 从工作区事实推导出的下一步确定性动作。 持久状态不写会漂移的阶段枚举;下一动作只由工件推导(RFC §6.2)。

const (
	ActionIngest               Action = "ingest"
	ActionSegment              Action = "segment"
	ActionAwaitConfirmation    Action = "await_confirmation"
	ActionAnalyze              Action = "analyze"
	ActionSynthesize           Action = "synthesize"
	ActionAwaitStoryResolution Action = "await_story_resolution"
	ActionPublish              Action = "publish"
	ActionDone                 Action = "done"
)

func NextAction added in v0.7.2

func NextAction(f Facts) Action

NextAction 沿固定线性管线,返回第一份缺失或未满足的动作。纯函数,无 IO。

type AnalysisBatchResult added in v0.7.2

type AnalysisBatchResult struct {
	Chapters []ImportedChapterFacts `json:"chapters"`
}

AnalysisBatchResult 是一次批次调用的结构化返回,每元素是一章事实。

type AnalyzeBudget added in v0.7.2

type AnalyzeBudget struct {
	ContextBytes     int // 输入预算(正文 + ledger + overhead)
	MaxOutputTokens  int // 可见输出预算(completion 上限)
	PerChapterOutput int // 每章保守输出预留
	PromptOverhead   int // system/ledger 固定输入开销(字节)
}

AnalyzeBudget 是逐章分析的输入/输出双预算(RFC §9.2)。 输入以字节近似 context window;输出以每章保守事实预留近似 completion 上限。

type Artifact added in v0.7.2

type Artifact[T any] struct {
	SchemaVersion int    `json:"schema_version"`
	InputDigest   string `json:"input_digest"`
	Payload       T      `json:"payload"`
}

Artifact 是工作区中每份语义工件的统一身份:schema 版本 + 输入摘要 + 载荷。 只有能从当前真实语义输入重建出相同 InputDigest 才可复用(RFC §6.3 / 不变量 1)。 不实现依赖图:LoadState 沿固定线性管线逐步比对 InputDigest 判定复用与失效,NextAction 据此推导下一步。

type BookSynthesis added in v0.7.2

type BookSynthesis struct {
	Premise      string                `json:"premise"`
	Characters   []domain.Character    `json:"characters"`
	WorldRules   []domain.WorldRule    `json:"world_rules"`
	Structure    []ImportedVolumeRange `json:"structure"`
	Compass      domain.StoryCompass   `json:"compass"`
	PlanningTier domain.PlanningTier   `json:"planning_tier"`
	StoryStatus  string                `json:"story_status"`
	StatusReason string                `json:"status_reason,omitempty"`
}

BookSynthesis 是最终综合结果:全局事实 + 卷弧范围(RFC §10.3)。

func Synthesize added in v0.7.2

func Synthesize(ctx context.Context, m callModel, bookPrompt, rangePrompt string, w *Workspace, facts []ImportedChapterFacts, budgetBytes, maxTokens int, prof callProfile) (*BookSynthesis, error)

Synthesize 分层综合:短书直接出 BookSynthesis;长书先出 RangeDigest 再归并(RFC §10)。 bookPrompt 描述 BookSynthesis 契约,rangePrompt 描述 RangeDigest 契约——两阶段输出结构不同, 必须各用对应系统提示词,否则模型收到 BookSynthesis 指令却被要求 RangeDigest,指令自相矛盾。

type BoundaryDecision added in v0.7.2

type BoundaryDecision struct {
	UnitID    string `json:"unit_id"`
	Anchor    string `json:"anchor,omitempty"`
	Kind      string `json:"kind"` // chapter / group / front_matter / back_matter
	Title     string `json:"title,omitempty"`
	Uncertain bool   `json:"uncertain,omitempty"`
	Reason    string `json:"reason,omitempty"`
}

BoundaryDecision 是模型对单个 owned range 的边界判断(RFC §8.2)。

type Caller added in v0.7.2

type Caller struct {
	Model   callModel
	Runtime ModelRuntime
}

Caller 是一个语义函数的模型档位:模型 + 该模型的能力事实(RFC §13.1/§17)。 segment/analyze/synthesize 各自持有档位,预算与调用选项都按各自档位派生, 廉价档位的小窗口只约束它自己的函数,不拖累其它阶段。

type ChapterAnalysisPayload added in v0.7.2

type ChapterAnalysisPayload struct {
	BatchStart int                  `json:"batch_start"`
	BatchEnd   int                  `json:"batch_end"`
	Facts      ImportedChapterFacts `json:"facts"`
}

ChapterAnalysisPayload 是单章分析工件载荷;同批次章节记录相同 BatchStart/BatchEnd。

type ChapterCommitter added in v0.7.2

type ChapterCommitter interface {
	Execute(ctx context.Context, args json.RawMessage) (json.RawMessage, error)
}

ChapterCommitter 是发布章节所需的最小接口,由 tools.CommitChapterTool 满足。 复用其 PendingCommit saga、checkpoint 与完成章节幂等检查,不复制第二套提交逻辑(RFC §12.3)。

type ChapterSpan added in v0.7.2

type ChapterSpan struct {
	Number int    `json:"number"`
	Title  string `json:"title"`
	Start  int    `json:"start_byte"`
	End    int    `json:"end_byte"`
}

ChapterSpan 是切分确认后的一个可提交章节:标题 + 归一化文本字节范围(含标题行)。

type Confirmation added in v0.7.2

type Confirmation struct {
	Method   string `json:"method"`
	Chapters int    `json:"chapters"`
}

Confirmation 是切分确认工件,绑定当前 segmentation(RFC §8.4)。

type Deps

type Deps struct {
	Store         *store.Store
	CommitChapter ChapterCommitter
	Segment       Caller
	Analyze       Caller
	Synthesize    Caller // range digest 与 book synthesis 同档位(同一综合阶段)
	Prompts       Prompts
	Budgets       RunBudgets
}

Deps 是 runner 的窄依赖(RFC §17)。三个语义函数各自声明模型档位; Host 默认全部落 architect,配置层可把机械性更强的函数指到更便宜档位(RFC §13.1)。

type Event

type Event struct {
	Time      time.Time
	Stage     Stage
	Current   int       // 章节/区间进度
	Total     int       // 总数
	Message   string    // 人类可读描述
	Level     string    // ""=普通进度;"warn"=退避重试/校验重问等警示状态
	Key       string    // 非空时 UI 对同 Key 连续事件原地更新(如 7 次退避在一行变动),对齐事件面板 ID 机制
	RetryAt   time.Time // 非零 = 下次重试的截止时刻;UI 据此逐秒倒计时渲染,到点即清(请求已在途)
	Err       error     // StageError 时携带
	Continued bool      // StageDone 时由 Host 置位:是否已自动接力启动 Engine(--continue × auto)
}

Event 是导入流程对外发出的进度事件。Event 是投影,不参与恢复。

type Facts added in v0.7.2

type Facts struct {
	WorkspaceReady   bool // manifest + intent + source 三件套齐备
	Segmented        bool
	Confirmed        bool
	ExpectedChapters int // 切分确认的章节总数(阶段二起填充)
	AnalyzedChapters int // 从第 1 章起连续、InputDigest 匹配的分析数(阶段三起填充)
	Synthesized      bool
	StoryUncertain   bool
	StoryResolved    bool
	Published        bool // 正式工件与 synthesis 完全一致(阶段五起填充)
}

Facts 是从工作区读出的、决定下一动作所需的最小事实快照。 把纯决策(NextAction)与 IO(LoadState)分离:NextAction 对同一 Facts 恒定(RFC §20.1)。

func CollectFacts added in v0.7.2

func CollectFacts(st *store.Store, w *Workspace) (Facts, error)

CollectFacts 组合工作区事实与正式发布对账,是 ResumeStatus/ResumeSummary/runner 的统一事实入口。发布对账的期望章数优先取新鲜切分;切分因 prompt 版本 / 指导升级 而失配时,退回工件里当时确认的章数——已发布书的正式章节正是按那份切分落库的, 用当前版本重算 digest 对账反而对不上任何东西。

func LoadState added in v0.7.2

func LoadState(w *Workspace) (Facts, error)

LoadState 从工作区读出当前事实快照(仅工作区,不含正式 Store)。 线性短路:每一步都校验工件 InputDigest 与当前上游可重建的摘要一致,任一步失配即视为该步未完成, 下游事实保持 false,交 NextAction 从此处重做——这才让「改切分/prompt 版本/源」自然失效下游(RFC §6.2/§6.3 / 不变量 1)。 Published 由调用方按正式发布对账补齐(统一走 CollectFacts)。

type FailureMeta added in v0.7.2

type FailureMeta struct {
	Stage         string `json:"stage"`
	Detail        string `json:"detail"`
	StopReason    string `json:"stop_reason,omitempty"`
	PrefixSalvage string `json:"prefix_salvage,omitempty"` // available:N / unavailable
}

FailureMeta 是最近一次失败的诊断元数据(RFC §14.2)。

type Foundation added in v0.7.2

type Foundation struct {
	PlanningTier domain.PlanningTier
	Premise      string
	Characters   []domain.Character
	WorldRules   []domain.WorldRule
	Volumes      []domain.VolumeOutline
	Compass      domain.StoryCompass
	Closed       bool
}

Foundation 是从 BookSynthesis + 逐章事实组装出的正式领域对象集(发布前完整校验,RFC §11)。

func AssembleFoundation added in v0.7.2

func AssembleFoundation(s *BookSynthesis, facts []ImportedChapterFacts, closed bool, fallbackName string) (*Foundation, error)

AssembleFoundation 用综合语义 + 逐章事实组装正式 Foundation 并完整校验。 closed 是 story_status 裁定后的收束事实;fallbackName 用于正文无法确认书名时的推断标题。

type ImportedArcRange added in v0.7.2

type ImportedArcRange struct {
	Title        string `json:"title"`
	Goal         string `json:"goal"`
	StartChapter int    `json:"start_chapter"`
	EndChapter   int    `json:"end_chapter"`
}

ImportedArcRange / ImportedVolumeRange:综合只返回卷弧范围,不重复输出所有章节(RFC §10.3)。

type ImportedChapterFacts added in v0.7.2

type ImportedChapterFacts struct {
	Chapter             int                        `json:"chapter"`
	Title               string                     `json:"title"`
	Summary             string                     `json:"summary"`
	KeyEvents           []string                   `json:"key_events"`
	CoreEvent           string                     `json:"core_event"`
	Hook                string                     `json:"hook,omitempty"`
	Scenes              []string                   `json:"scenes,omitempty"`
	Characters          []string                   `json:"characters,omitempty"`
	CharacterEvidence   []ImportedCharacterFact    `json:"character_evidence,omitempty"`
	WorldEvidence       []ImportedWorldFact        `json:"world_evidence,omitempty"`
	TimelineEvents      []domain.TimelineEvent     `json:"timeline_events,omitempty"`
	ForeshadowUpdates   []domain.ForeshadowUpdate  `json:"foreshadow_updates,omitempty"`
	RelationshipChanges []domain.RelationshipEntry `json:"relationship_changes,omitempty"`
	StateChanges        []domain.StateChange       `json:"state_changes,omitempty"`
	HookType            string                     `json:"hook_type"`
	DominantStrand      string                     `json:"dominant_strand"`
}

ImportedChapterFacts 是单章反推的结构化产物(RFC §9.1)。

type ImportedCharacterFact added in v0.7.2

type ImportedCharacterFact struct {
	Chapter int    `json:"chapter"`
	Name    string `json:"name"`
	Note    string `json:"note,omitempty"`
}

ImportedCharacterFact / ImportedWorldFact 是用于全书综合的紧凑观察,不直接写正式角色或世界规则。 至少携带章节号,使综合结果有稳定来源(RFC §9.1)。

type ImportedVolumeRange added in v0.7.2

type ImportedVolumeRange struct {
	Title string             `json:"title"`
	Theme string             `json:"theme"`
	Arcs  []ImportedArcRange `json:"arcs"`
}

type ImportedWorldFact added in v0.7.2

type ImportedWorldFact struct {
	Chapter  int    `json:"chapter"`
	Category string `json:"category,omitempty"`
	Fact     string `json:"fact"`
}

type Intent added in v0.7.2

type Intent struct {
	Version             int    `json:"version"`
	AutoConfirm         bool   `json:"auto_confirm,omitempty"`
	StoryResolution     string `json:"story_resolution,omitempty"` // open / closed
	ContinueAfterImport bool   `json:"continue_after_import,omitempty"`
}

Intent 保存启动导入时的显式用户授权,恢复后仍必须遵守,不由工件猜出,Runner 不静默改写(RFC §6.1)。

type Manifest added in v0.7.2

type Manifest struct {
	Version          int    `json:"version"`
	SourceName       string `json:"source_name"`
	RawSHA256        string `json:"raw_sha256"`
	NormalizedSHA256 string `json:"normalized_sha256"`
	Encoding         string `json:"encoding"`
	SizeBytes        int64  `json:"size_bytes"`
	CreatedAt        string `json:"created_at"`
}

Manifest 对应唯一归一化源快照,是工作区身份而非派生工件(RFC §6.1)。 不保存绝对源路径,避免泄露机器目录并消除移动文件带来的恢复问题。

type MatterSpan added in v0.7.2

type MatterSpan struct {
	Kind  string `json:"kind"`
	Title string `json:"title,omitempty"`
	Start int    `json:"start_byte"`
	End   int    `json:"end_byte"`
}

MatterSpan 是卷/篇标题或明确的附属区域。

type ModelRuntime added in v0.7.2

type ModelRuntime struct {
	ContextTokens   int                     // 输入上下文上限(token)
	MaxOutputTokens int                     // 单次可见输出上限(token)
	Thinking        agentcore.ThinkingLevel // 已按能力 resolve;ThinkingAuto("") 表示不显式发送
}

ModelRuntime 承载 imp 语义调用所需的模型能力事实,由 Host 在边界探测后注入(RFC §13/§17)。 让双预算随 context/completion 自然放大、thinking 随能力发送;全零值时回退保守默认, 行为与接入能力前一致。结构化输出不按 provider 能力发 response_format(见 callProfile 注释)。

type Options

type Options struct {
	SourcePath      string // 新导入必填;恢复时可空
	AutoConfirm     bool   // --yes:覆盖校验通过后自动接受切分
	StoryResolution string // --story=open|closed:仅 synthesis 返回 uncertain 时预选
	ContinueAfter   bool   // --continue:不创建导入完成 Hold
	Guidance        string // --guide:自然语言切分指导,落盘工作区后自然使旧切分失配重识别
	// AcceptSegmentation:TUI 预览后的显式人工确认(y)。一次性放行当前切分,不写 intent;
	// 与 --yes 的区别:--yes 是未看预览的盲授权,不放行带容错说明(Notes)的切分,y 是看过预览的裁定。
	AcceptSegmentation bool
}

Options 控制一次导入。恢复时字段可空,直接从活动工作区与已保存 Intent 推导。

type Prompts

type Prompts struct {
	Segment    string
	Analyze    string
	Synthesize string
	Range      string
}

Prompts 是各语义函数的系统提示词。综合分两阶段:Synthesize 出全书 BookSynthesis, Range 出长书连续区间 RangeDigest;两者输出结构不同,须各用对应提示词。

type RangeDigest added in v0.7.2

type RangeDigest struct {
	StartChapter    int      `json:"start_chapter"`
	EndChapter      int      `json:"end_chapter"`
	Plot            string   `json:"plot"`
	Characters      []string `json:"characters,omitempty"`
	WorldFacts      []string `json:"world_facts,omitempty"`
	OpenedThreads   []string `json:"opened_threads,omitempty"`
	ResolvedThreads []string `json:"resolved_threads,omitempty"`
}

RangeDigest 是长书 Map 阶段的连续区间摘要,输出受单区间约束(RFC §10.2)。

type RunBudgets added in v0.7.2

type RunBudgets struct {
	MaxUnitBytes         int
	SegmentChunkBytes    int
	SegmentContextMargin int
	SegmentMaxTokens     int
	Analyze              AnalyzeBudget
	SynthesizeRangeBytes int
	SynthesizeMaxTokens  int
}

RunBudgets 是各语义函数的输入/输出预算。第一版用保守常量; 未来应由当前 architect 模型的 context window / completion 上限推导,使批次随能力自然放大(RFC §9.2/§21)。

func DefaultRunBudgets added in v0.7.2

func DefaultRunBudgets() RunBudgets

DefaultRunBudgets 返回保守默认预算,用于模型能力未知(探测失败)时兜底。

type Segmentation added in v0.7.2

type Segmentation struct {
	Chapters  []ChapterSpan `json:"chapters"`
	Matter    []MatterSpan  `json:"matter,omitempty"`    // group / front / back
	Uncertain []int         `json:"uncertain,omitempty"` // 标记 uncertain 的章节号,供预览提示
	Notes     []string      `json:"notes,omitempty"`     // 切分期需人工核对的说明(如空正文占位标题并入前段)
}

Segmentation 是全文覆盖校验通过的切分结果(confirmation 与逐章分析的上游)。

func Segment added in v0.7.2

func Segment(ctx context.Context, m callModel, systemPrompt string, normalized []byte, units []SourceUnit, guidance string, chunkBytes, contextMargin, maxTokens int, prof callProfile, w *Workspace, identity string) (*Segmentation, error)

Segment 对整份归一化文本做语义切分:逐 owned 区间调用模型识别边界,再全文覆盖校验。 contextMargin 上下文单元数,chunkBytes owned 区间字节预算,maxTokens 单次输出预算。 w 非空时逐块落盘边界缓存(identity = segmentInputDigest):单块可达数分钟,任何一块失败 不应重付已完成块的调用——与 analyze 逐章、synthesize 逐区间同一哲学,此前切分是 唯一没有阶段内持久化的昂贵阶段,一处失败即全部重来。

func (*Segmentation) Content added in v0.7.2

func (s *Segmentation) Content(normalized []byte, i int) string

Content 返回第 i 个章节的归一化正文(含标题行)。

type SourceUnit added in v0.7.2

type SourceUnit struct {
	ID        string `json:"id"`   // L1257;超预算行拆为 L1257.1、L1257.2
	Line      int    `json:"line"` // 1 起
	Part      int    `json:"part"` // 0=整行;虚拟分片 1..N
	StartByte int    `json:"start_byte"`
	EndByte   int    `json:"end_byte"`
	Text      string `json:"text"`
}

SourceUnit 是模型可引用的稳定坐标(RFC §7.3)。 ID 仅用于展示与模型引用;所有顺序/包含/递增判断一律按 (Line, Part) 数值序,禁止对 ID 字符串做字典序比较。

type Stage

type Stage string

Stage 表示导入流程的当前阶段,仅用于 UI 展示,不是恢复事实源(RFC §14.1)。

const (
	StageIngesting            Stage = "ingesting"
	StageSegmenting           Stage = "segmenting"
	StageAwaitingConfirmation Stage = "awaiting_confirmation"
	StageAnalyzing            Stage = "analyzing"
	StageSynthesizing         Stage = "synthesizing"
	StageAwaitingStoryStatus  Stage = "awaiting_story_status"
	StageValidating           Stage = "validating"
	StagePublishing           Stage = "publishing"
	StageDone                 Stage = "done"
	StageError                Stage = "error"
)

type StoryResolution added in v0.7.2

type StoryResolution struct {
	Choice string `json:"choice"` // open / closed
}

StoryResolution 是 uncertain 故事状态的用户裁定,绑定当前 synthesis(RFC §10.4)。

type Workspace added in v0.7.2

type Workspace struct {
	// contains filtered or unexported fields
}

Workspace 是 <书根>/meta/import/ 目录的原子工件读写句柄。

func OpenWorkspace added in v0.7.2

func OpenWorkspace(bookDir string) *Workspace

OpenWorkspace 返回指向书根下 meta/import/ 的句柄;不保证目录已存在,用 Active() 判断。

func (*Workspace) Active added in v0.7.2

func (w *Workspace) Active() bool

Active 判断是否存在已发布的活动工作区。meta/import/ 不存在就不算活动, 半初始化目录以 meta/import.init-* 形态存在,不会被误判为活动(RFC §6.1)。

func (*Workspace) Dir added in v0.7.2

func (w *Workspace) Dir() string

Dir 返回工作区绝对路径(诊断与失败工件落点用)。

func (*Workspace) LoadGuidance added in v0.7.2

func (w *Workspace) LoadGuidance() (string, error)

LoadGuidance 读取用户切分指导(RFC §18.3);缺失即无指导。 指导与 source.txt 同为切分的语义输入而非派生工件,由显式 --guide 更新, 内容变化使 segmentation 及其下游 InputDigest 自然失配。

func (*Workspace) LoadIntent added in v0.7.2

func (w *Workspace) LoadIntent() (*Intent, error)

LoadIntent 读取用户启动授权。

func (*Workspace) LoadManifest added in v0.7.2

func (w *Workspace) LoadManifest() (*Manifest, error)

LoadManifest 读取工作区源快照身份。

func (*Workspace) LoadSource added in v0.7.2

func (w *Workspace) LoadSource() ([]byte, error)

LoadSource 读取归一化源快照文本。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL