Documentation
¶
Index ¶
- Constants
- func BuildStartPrompt(prompt string) string
- func CollectUserSettings(baseDir string) (content string, files int, err error)
- func IsPlanReviewConfirm(text string) bool
- func ReplayDeltaText(item domain.RuntimeQueueItem) string
- type AgentCacheStat
- type AgentContextSnapshot
- type AgentSnapshot
- type AgentUsage
- type CoCreateMessage
- type CoCreateReply
- type Event
- type Host
- func (h *Host) Abort() bool
- func (h *Host) AppendCoCreateTranscript(transcript string)
- func (h *Host) AskUser() *tools.AskUserTool
- func (h *Host) Close()
- func (h *Host) CoCreateStream(ctx context.Context, history []CoCreateMessage, ...) (CoCreateReply, error)
- func (h *Host) ConfiguredModels(provider string) []string
- func (h *Host) ConfiguredProviders() []string
- func (h *Host) Continue(text string) error
- func (h *Host) CurrentModelSelection(role string) (string, string, bool)
- func (h *Host) Dir() string
- func (h *Host) Done() <-chan struct{}
- func (h *Host) Events() <-chan Event
- func (h *Host) Export(ctx context.Context, opts exp.Options) (*exp.Result, error)
- func (h *Host) FetchSimulationCorpus(ctx context.Context, author string, urls []string) (<-chan sim.Event, error)
- func (h *Host) HandleReviewInput(text string) (approved bool, err error)
- func (h *Host) ImportFrom(ctx context.Context, opts imp.Options) (<-chan imp.Event, error)
- func (h *Host) ImportSimulationProfile(ctx context.Context, path string) (<-chan sim.Event, error)
- func (h *Host) ReplayQueue(afterSeq int64) ([]domain.RuntimeQueueItem, error)
- func (h *Host) Resume() (string, error)
- func (h *Host) Simulate(ctx context.Context) (<-chan sim.Event, error)
- func (h *Host) Snapshot() UISnapshot
- func (h *Host) Start(prompt string) error
- func (h *Host) StartPrepared(promptText string) error
- func (h *Host) Steer(text string)
- func (h *Host) Stream() <-chan string
- func (h *Host) SwitchModel(role, provider, model string) error
- type Option
- type OutlineSnapshot
- type UISnapshot
- type UsageTracker
- func (t *UsageTracker) LoadFromStore() (bool, error)
- func (t *UsageTracker) MissingAssistantUsage() int
- func (t *UsageTracker) OverallCacheCapable() bool
- func (t *UsageTracker) OverallRecent() (cacheRead, input, samples int)
- func (t *UsageTracker) PerAgent() []AgentUsage
- func (t *UsageTracker) PerModel() []AgentUsage
- func (t *UsageTracker) Record(agentName string, msg agentcore.AgentMessage)
- func (t *UsageTracker) ReplaySessions(rootDir string) (int, error)
- func (t *UsageTracker) SaveNow() error
- func (t *UsageTracker) SavedUSD() float64
- func (t *UsageTracker) Snapshot() domain.UsageState
- func (t *UsageTracker) StartAutoSave(ctx context.Context)
- func (t *UsageTracker) Totals() (cost float64, input, output, cacheRead, cacheWrite int)
Constants ¶
const ( CoCreateProgressThinking = "thinking" CoCreateProgressReply = "reply" )
CoCreateProgressKind 标识流式回调的内容类型。
const StreamClearSentinel = "\x00\x00CLEAR\x00\x00"
StreamClearSentinel 通过 streamCh 单条发送以示意"清空当前流式 round"。 不再用独立 clearCh —— 双通道无序导致 ✻ header 时常落到上一个 round 末尾。
Variables ¶
This section is empty.
Functions ¶
func BuildStartPrompt ¶
BuildStartPrompt 将用户需求包装为 Coordinator 的启动 prompt。
func CollectUserSettings ¶ added in v0.8.0
CollectUserSettings 递归读取 baseDir/settings/ 下的文本文件, 按相对路径字典序拼接为带文件头的 Markdown 全文。 目录不存在返回空串;单文件与合计超限时截断并标注。
func IsPlanReviewConfirm ¶ added in v0.8.0
IsPlanReviewConfirm 报告文本是否为规划审阅确认词。
func ReplayDeltaText ¶
func ReplayDeltaText(item domain.RuntimeQueueItem) string
ReplayDeltaText 从运行时队列项中提取可回放的流式文本。
Types ¶
type AgentCacheStat ¶
type AgentCacheStat struct {
Role string
Model string
Input int
Output int
CacheRead int
CacheWrite int
Cost float64
Saved float64
CacheCapable bool
RecentCacheRead int
RecentInput int
RecentSamples int
}
AgentCacheStat 是单个 agent 的缓存命中累计(投影到左栏)。 HitRate = CacheRead / Input;Input 在 litellm 层已统一为"含 CacheRead"语义。
CacheCapable 用来区分两种 0% 命中:
- true → 模型支持 prompt cache,0% 是 prompt 设计差或前缀不稳定,需要优化
- false → 模型/provider 不支持 prompt cache,0% 是预期,不必排查
Recent* 是滑动窗(最近 N 次调用)的命中数据,对比累计可识别"前期拖累"vs"稳态低命中"。
type AgentContextSnapshot ¶
type AgentContextSnapshot struct {
Tokens int
ContextWindow int
Percent float64
Scope string
Strategy string
ActiveMessages int
SummaryMessages int
CompactedCount int
KeptCount int
}
AgentContextSnapshot 是 Agent 上下文使用情况。
type AgentSnapshot ¶
type AgentSnapshot struct {
Name string
State string
TaskID string
TaskKind string
Summary string
Tool string
Turn int
Context AgentContextSnapshot
UpdatedAt time.Time
}
AgentSnapshot 是 Agent 状态的展示投影。
type AgentUsage ¶
type AgentUsage struct {
Role string
Model string
Input int
Output int
CacheRead int
CacheWrite int
Cost float64
Saved float64
CacheCapable bool
RecentCacheRead int
RecentInput int
RecentSamples int
}
AgentUsage 是一个 agent 的累计用量快照(向 UI 暴露)。
type CoCreateMessage ¶
CoCreateMessage 是共创对话的消息。
type CoCreateReply ¶
type CoCreateReply struct {
Message string
Prompt string
Ready bool
StartIntent bool // 用户本轮明确要求开始创作(<start_intent> 标签)
Suggestions []string
Raw string
}
CoCreateReply 是共创对话的 LLM 回复。Raw 保留模型完整四段原文, 用于写回 history 让下一轮模型看到自己上一轮的 [DRAFT],从而真正在 已有草稿上累积更新(仅 Message 不含 [DRAFT],会导致模型每轮凭对话重新归纳)。 Suggestions 是 AI 主动给的"接下来你可能想说",用户卡壳时按数字键一键填入输入框。
type Event ¶
type Event struct {
ID string // 同一次调用的开始/结束共用;非调用事件为空
Time time.Time // 首次发出时间(开始时刻)
FinishedAt time.Time // 零值 = 进行中;非零 = 已完成
Failed bool // 已完成但失败(仅完成态有意义)
Category string // DISPATCH / TOOL / SYSTEM / REVIEW / CHECK / ERROR / CONTEXT
Agent string // 产生事件的 agent
Summary string
Detail string // 完整文案,写入日志不截断供排查;为空回退 Summary。UI 只读 Summary
Kind string // 错误分类(如 stream_idle),随日志输出供过滤/告警;为空不输出
Level string // info / warn / error / success
Depth int // 0 = coordinator 层, 1 = sub-agent 层
Duration time.Duration // 完成时的执行耗时
}
Event 是 TUI 消费的结构化事件。
对于 TOOL / DISPATCH 两类调用事件,同一次调用的开始与结束共用一个 ID: 开始时先发 FinishedAt 为零值的事件(TUI 渲染为"进行中"样式); 结束时再发一条同 ID 的事件,填入 FinishedAt + Duration(+ Failed), TUI 按 ID 定位原行原地更新,避免"开始一行、完成又一行"的冗余。
SYSTEM / ERROR / CONTEXT 等非调用类事件 ID 为空,每条独立追加。
type Host ¶
type Host struct {
// contains filtered or unexported fields
}
Host 是运行时薄外壳。 职责:启动/恢复/干预注入/事件投影/模型管理。 不做任何调度决策,不做空闲续跑。
func (*Host) AppendCoCreateTranscript ¶ added in v0.8.0
AppendCoCreateTranscript 把共创对话用户原文追加进 user_settings.md。 在已有设定(settings/ 目录内容)之后以独立章节追加;无已有内容则单独成文。
func (*Host) AskUser ¶
func (h *Host) AskUser() *tools.AskUserTool
func (*Host) Close ¶
func (h *Host) Close()
Close 终止 coordinator 并关闭事件通道。
Usage 持久化语义:先取消 autoSaveLoop(它自行 flush 最后一次 dirty 状态), 再补一次同步 SaveNow 收尾。已知缺口:AbortSilent 之后若仍有 in-flight LLM 调用回来,触发的 OnMessage → Record 会更新内存但**不会被持久化**。这部分 "最末几百 token" 的丢失在下次启动时会由 session jsonl replay 自动补回。
func (*Host) CoCreateStream ¶
func (h *Host) CoCreateStream(ctx context.Context, history []CoCreateMessage, onProgress func(kind, text string)) (CoCreateReply, error)
func (*Host) ConfiguredModels ¶
func (*Host) ConfiguredProviders ¶
func (*Host) CurrentModelSelection ¶
func (*Host) Export ¶
Export 导出已完成章节为外部文件(当前仅支持 TXT)。
与 ImportFrom 不同:导出是只读操作(不动 Progress / Checkpoint), 因此**不要求 Coordinator 空闲**——写作中途也可以随时导出"现阶段成品"。 只读到 Progress.CompletedChapters + 章节终稿 + 大纲 + premise 的一致快照。
func (*Host) FetchSimulationCorpus ¶ added in v0.9.0
func (h *Host) FetchSimulationCorpus(ctx context.Context, author string, urls []string) (<-chan sim.Event, error)
FetchSimulationCorpus 从网络抓取作者语料,落盘 simulate/personas/<作者>/。 只落语料文件不生成画像——用户检查质量后自行运行 /simulate。
func (*Host) HandleReviewInput ¶ added in v0.8.0
HandleReviewInput 处理规划审阅暂停态下的用户输入。 确认词 → 内存放行 + 落盘 PlanReviewed + Resume 进入写作,返回 true; 其他文本 → 复位提示标记后作为干预注入并恢复(Coordinator 改大纲), 处理完成后门禁会再次拦截暂停,循环直到用户确认。 前置:仅在审阅拦截态(UISnapshot.PlanReviewPending=true)下调用; 门禁未启用时不应路由到本函数。
func (*Host) ImportFrom ¶
ImportFrom 启动一次外部小说反推导入:切分 → 反推 foundation → 逐章分析落盘。 与 Coordinator 互斥;导入完成后调用方可立即 Resume() 续写。 返回的事件通道由 imp.Run 关闭,调用方负责消费(满则丢弃以防阻塞分析协程)。
func (*Host) ImportSimulationProfile ¶ added in v0.5.0
ImportSimulationProfile 导入此前生成的仿写画像。
func (*Host) ReplayQueue ¶
func (h *Host) ReplayQueue(afterSeq int64) ([]domain.RuntimeQueueItem, error)
func (*Host) Snapshot ¶
func (h *Host) Snapshot() UISnapshot
func (*Host) StartPrepared ¶
StartPrepared 使用已编排完成的启动 prompt 开始创作。
func (*Host) SwitchModel ¶
type Option ¶ added in v0.8.0
type Option func(*hostOptions)
Option 配置 Host 装配期行为。
func WithInteractive ¶ added in v0.8.0
WithInteractive 声明宿主入口是否交互式(TUI true / headless false), 决定 plan_review=auto 时规划审阅门禁是否启用。
func WithPlanReviewNotify ¶ added in v0.8.0
func WithPlanReviewNotify(fn func()) Option
WithPlanReviewNotify 注入规划审阅触发回调(headless 用它起 stdin 审阅循环)。
type OutlineSnapshot ¶
OutlineSnapshot 是大纲条目的展示摘要。
type UISnapshot ¶
type UISnapshot struct {
Provider string
NovelName string
ModelName string
ModelContextWindow int // 当前默认模型的上下文窗口(随 /model 切换实时解析)
Style string
RuntimeState string // idle / running / pausing / paused / completed
StatusLabel string
Phase string
Flow string
CurrentChapter int
TotalChapters int
CompletedCount int
TotalWordCount int
InProgressChapter int
PendingRewrites []int
RewriteReason string
PendingSteer string
PlanReviewPending bool // 规划完成待用户审阅大纲(plan_review 门禁拦截中)
RecoveryLabel string
IsRunning bool
Agents []AgentSnapshot
// 上下文
ContextTokens int
ContextWindow int
ContextPercent float64
ContextScope string
ContextStrategy string
ContextActiveMessages int
ContextSummaryCount int
ContextCompactedCount int
ContextKeptCount int
// 累计用量(整个会话,跨所有 agent 与模型切换)
TotalInputTokens int
TotalOutputTokens int
TotalCacheReadTokens int
TotalCacheWriteTokens int
TotalCostUSD float64
TotalSavedUSD float64 // 因 CacheRead 命中省下的美元(相对全按非缓存输入价计费)
// 缓存诊断
OverallCacheCapable bool // 至少一个 role 跑过支持 prompt cache 的模型(区分"未启用"和"0% 命中")
OverallRecentCacheRead int // 滑动窗最近 N 次的 cacheRead 总和
OverallRecentInput int // 滑动窗最近 N 次的 input 总和
OverallRecentSamples int // 滑动窗内的样本数(≤ recentSampleCap)
// MissingAssistantUsage > 0 通常意味着上游 streaming 没按 OpenAI
// stream_options.include_usage 协议发 final usage chunk(自建 proxy 常见),
// 导致 UsageTracker 收不到任何累计数据。UI 据此明示用户排查 backend,
// 不要让用户误以为是缓存模块本身坏了。
MissingAssistantUsage int
// 缓存 per-role 维度,按 CacheRead 降序,已过滤未消费 token 的 role
CachePerAgent []AgentCacheStat
CachePerModel []AgentCacheStat
// 基础设定
Premise string
Outline []OutlineSnapshot
Characters []string
SupportingCount int // 配角名册中的次要角色总数
RecentSupporting []string // 最近活跃的次要角色(最多 5 个,按 LastSeenChapter 倒序)
Layered bool
CurrentVolumeArc string
NextVolumeTitle string
CompassDirection string
CompassScale string
// 详情
LastCommitSummary string
LastReviewSummary string
LastCheckpointName string
RecentSummaries []string
}
UISnapshot 是 TUI 渲染所需的聚合状态快照。
type UsageTracker ¶
type UsageTracker struct {
// contains filtered or unexported fields
}
UsageTracker 累计整个会话所有 agent 的 LLM 输入/输出 token 与美元成本。
工作机制:
- 每次 agent 的 OnMessage 回调触发时调用 Record(agentName, msg)
- agentName 映射到 role(architect_* 归一为 architect),查 ModelSet 当前该 role 绑定的模型
- 用 models.DefaultRegistry 查模型价格,按非缓存输入/输出/缓存读/缓存写四项累乘
- 注册表无此模型时,退回 msg.Usage.Cost.Total(provider 自带,可能为 0)
- 模型热切换(/model)后续消息自动按新模型算价,旧消息保留旧成本
同时维护 per-role 维度(writer/editor/architect/coordinator):
- 累计命中数据 → 整体优化效果
- 滑动窗最近 N 次 → 区分前期拖累 vs 稳态低命中
- CacheCapable 标记 → 区分"未启用"和"真的 0% 命中"
线程安全。
func NewUsageTracker ¶
func NewUsageTracker(set *bootstrap.ModelSet, store *storepkg.Store) *UsageTracker
func (*UsageTracker) LoadFromStore ¶
func (t *UsageTracker) LoadFromStore() (bool, error)
LoadFromStore 从 store.Usage 读取持久化的快照并回填到内存。返回 true 表示 成功加载到了一份非空(schema 匹配)的状态;false 表示无文件或不可用,调用方 应继续走 session replay 一次性回填。
func (*UsageTracker) MissingAssistantUsage ¶
func (t *UsageTracker) MissingAssistantUsage() int
MissingAssistantUsage 返回累计"收到 assistant 消息但 Usage 为 nil"的次数。 大于 0 通常意味着上游 streaming 没发 OpenAI 的 final usage chunk, UI 据此显示提示而非误以为缓存模块本身坏了。
func (*UsageTracker) OverallCacheCapable ¶
func (t *UsageTracker) OverallCacheCapable() bool
OverallCacheCapable 整体是否至少经过一次已知支持 cache 的模型。
func (*UsageTracker) OverallRecent ¶
func (t *UsageTracker) OverallRecent() (cacheRead, input, samples int)
OverallRecent 返回滑动窗内(≤ recentSampleCap 次)的 cacheRead 总和、input 总和、样本数。
func (*UsageTracker) PerAgent ¶
func (t *UsageTracker) PerAgent() []AgentUsage
PerAgent 返回各 role 累计用量。结果按 CacheRead 数量降序,未消费过 token 的 role 跳过。
func (*UsageTracker) PerModel ¶
func (t *UsageTracker) PerModel() []AgentUsage
PerModel 返回各模型累计用量。结果按成本降序,其次按输入量降序。
func (*UsageTracker) Record ¶
func (t *UsageTracker) Record(agentName string, msg agentcore.AgentMessage)
Record 把一条 agent 消息分发到累加 / 诊断两条路径。
累加只看 Usage 是否存在——"哪条消息带 Usage" 是 agentcore/litellm adapter 装配细节(上游协议把 usage 放在响应顶层),未来装配规则变了也不用动这里。 诊断要求 Role=Assistant 且 Content 非空,避免 AbortMsg / 异常恢复 / tool / user 消息污染 missingAssistantUsage 计数。
func (*UsageTracker) ReplaySessions ¶
func (t *UsageTracker) ReplaySessions(rootDir string) (int, error)
ReplaySessions 扫 meta/sessions/coordinator.jsonl 与 meta/sessions/agents/*.jsonl, 把每条 assistant 消息的 usage 重新累加到 tracker。返回回填条数。
调用约束:仅在 meta/usage.json 缺失(首次升级或 schema 变更)时调用一次,做 历史数据回填。日常持久化走 SaveNow / autoSaveLoop。
精度依赖见 sessionRecord 注释的三级降级——第 3 级(Usage 和 _meta 都缺) 在更老日志或上游异常时才会触发。
func (*UsageTracker) SaveNow ¶
func (t *UsageTracker) SaveNow() error
SaveNow 立刻把当前 snapshot 落盘。autoSaveLoop / Close 路径都通过它写。
func (*UsageTracker) Snapshot ¶
func (t *UsageTracker) Snapshot() domain.UsageState
Snapshot 拷贝当前累计状态为可序列化的 domain.UsageState。 滑动窗 samples 不进 snapshot——它是短期诊断窗口,跨进程意义不大。
func (*UsageTracker) StartAutoSave ¶
func (t *UsageTracker) StartAutoSave(ctx context.Context)
StartAutoSave 起一个 goroutine,监听 saveCh + debounce 落盘。ctx done 前会 把最后一次未保存的状态 flush 出去。Close 通过 cancel ctx 触发 flush + 退出。
func (*UsageTracker) Totals ¶
func (t *UsageTracker) Totals() (cost float64, input, output, cacheRead, cacheWrite int)
Totals 返回累计总量的快照。
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package exp 实现已完成章节的导出能力。
|
Package exp 实现已完成章节的导出能力。 |
|
Package flow 实现垂类路由:Host 根据事实决定下一个调哪个子代理做什么。
|
Package flow 实现垂类路由:Host 根据事实决定下一个调哪个子代理做什么。 |
|
Package imp 实现外部小说章节的导入与反推。
|
Package imp 实现外部小说章节的导入与反推。 |
|
internal/host/persona/resolver.go
|
internal/host/persona/resolver.go |