Documentation
¶
Index ¶
- Constants
- Variables
- func MaskAPIKey(value string) string
- func ReplayDeltaText(item domain.RuntimeQueueItem) string
- type APIKeyAction
- type AgentCacheStat
- type AgentContextSnapshot
- type AgentSnapshot
- type AgentUsage
- type BudgetSentinel
- type ChapterAdvanceGate
- type CoCreateMessage
- type CoCreateReply
- type ConfiguredModel
- type Event
- type Host
- func (h *Host) Abort() bool
- func (h *Host) AdvanceOneChapter() error
- func (h *Host) AvailableThinking(role string) []agentcore.ThinkingLevel
- func (h *Host) CancelCoCreate()
- func (h *Host) Close()
- func (h *Host) CoCreateStream(ctx context.Context, history []CoCreateMessage, ...) (CoCreateReply, error)
- func (h *Host) ConfigureModels(draft ModelConfigurationDraft) error
- func (h *Host) ConfiguredModelOptions(provider string) []ConfiguredModel
- 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) CurrentThinking(role string) string
- 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) ImportFrom(ctx context.Context, opts imp.Options) (<-chan imp.Event, error)
- func (h *Host) ImportResumeHint() string
- func (h *Host) ImportSimulationProfile(ctx context.Context, path string) (<-chan sim.Event, error)
- func (h *Host) ModelConfiguration() ModelConfigurationSnapshot
- func (h *Host) PauseForCoCreate() bool
- func (h *Host) PrepareUserRules(rawPrompt string) error
- func (h *Host) Reopen(direction string) error
- func (h *Host) ReplayQueue(afterSeq int64) ([]domain.RuntimeQueueItem, error)
- func (h *Host) Resume() (string, error)
- func (h *Host) ResumeFromCoCreate(draft string) error
- func (h *Host) SetAdvanceMode(mode domain.ChapterAdvanceMode) error
- func (h *Host) SetRoleThinking(role, level string) error
- func (h *Host) Simulate(ctx context.Context) (<-chan sim.Event, error)
- func (h *Host) Snapshot() UISnapshot
- func (h *Host) StageCoCreateStream(ctx context.Context, history []CoCreateMessage, ...) (CoCreateReply, error)
- func (h *Host) StartPrepared(rawRequirement string) error
- func (h *Host) Steer(text string) error
- func (h *Host) Stream() <-chan string
- func (h *Host) SwitchModel(role, provider, model string) error
- func (h *Host) TestModelConnection(ctx context.Context, draft ModelConfigurationDraft, modelName string) error
- type ModelConfigurationDraft
- type ModelConfigurationSnapshot
- type ModelRename
- type OutlineSnapshot
- type ProviderSnapshot
- type UISnapshot
- type UsageTracker
- func (t *UsageTracker) LoadFromStore() (bool, error)
- func (t *UsageTracker) MissingAssistantUsage() int
- func (t *UsageTracker) OverallCacheBreaks() 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, task 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) SetOnCost(cb func(total float64))
- func (t *UsageTracker) SetOnMissingUsage(cb func())
- func (t *UsageTracker) Snapshot() domain.UsageState
- func (t *UsageTracker) StartAutoSave(ctx context.Context)
- func (t *UsageTracker) Totals() (cost float64, input, output, cacheRead, cacheWrite int)
- func (t *UsageTracker) WaitAutoSave()
Constants ¶
const ( CoCreateProgressThinking = "thinking" CoCreateProgressReply = "reply" )
CoCreateProgressKind 标识流式回调的内容类型。
const StreamClearSentinel = "\x00\x00CLEAR\x00\x00"
StreamClearSentinel 通过 streamCh 单条发送以示意"清空当前流式 round"。 不再用独立 clearCh —— 双通道无序导致 ✻ header 时常落到上一个 round 末尾。
Variables ¶
var ErrBookInUse = errors.New("小说目录已被另一个 ainovel-cli 实例占用")
ErrBookInUse 表示同一小说目录已被另一个进程占用。
Functions ¶
func MaskAPIKey ¶ added in v0.7.3
MaskAPIKey 仅保留足够识别凭证的首尾片段;短凭证全部隐藏。 TUI 只接收这个结果,绝不持有配置中的完整 API Key。
func ReplayDeltaText ¶
func ReplayDeltaText(item domain.RuntimeQueueItem) string
ReplayDeltaText 从运行时队列项中提取可回放的流式文本。
Types ¶
type APIKeyAction ¶ added in v0.7.3
type APIKeyAction string
const ( APIKeyKeep APIKeyAction = "keep" APIKeyReplace APIKeyAction = "replace" APIKeyClear APIKeyAction = "clear" )
type AgentCacheStat ¶ added in v0.3.1
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 ¶ added in v0.3.1
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 BudgetSentinel ¶ added in v0.5.0
type BudgetSentinel struct {
// contains filtered or unexported fields
}
BudgetSentinel 监视累计成本,执行用户的预算政策(config budget 块)。
合宪定位(architecture.md §8.3/§10):不评估模型行为——越线停机等同于用户在 那一刻手动 Abort,Host 只是代为执行一条预先签署的指令。它影响控制流,因此 不是观察者,定位为与 flow.Dispatcher 平级的 Host 政策组件;Route/工具层不感知。
停机时机:默认在子代理边界(Host 同步调用 HandleBoundary),不浪费 in-flight 章节; hardStop=true 时越线立即停。边界处理先于 flow.Dispatcher 派发下一步,Route/工具层不感知预算。
func NewBudgetSentinel ¶ added in v0.5.0
func NewBudgetSentinel(cfg bootstrap.BudgetConfig, costNow func() float64, abort func(reason string), report func(level, summary string)) *BudgetSentinel
NewBudgetSentinel 创建预算哨兵;政策未启用时返回 nil(所有方法 nil 安全)。
func (*BudgetSentinel) HandleBoundary ¶ added in v0.5.5
func (s *BudgetSentinel) HandleBoundary() bool
func (*BudgetSentinel) HandleEvent ¶ added in v0.5.0
func (s *BudgetSentinel) HandleEvent(ev agentcore.Event)
HandleEvent 在子代理边界执行待定的停机。订阅必须先于 Dispatcher。 不跳过 IsError——出错返回同样是边界,停机不应因子代理失败而推迟。
func (*BudgetSentinel) Limit ¶ added in v0.5.0
func (s *BudgetSentinel) Limit() float64
Limit 返回预算上限(UI 展示用);未启用返回 0。
func (*BudgetSentinel) OnCost ¶ added in v0.5.0
func (s *BudgetSentinel) OnCost(total float64)
OnCost 由 UsageTracker 每次记账后携带最新累计成本调用(锁外)。 一次回调可能连跨两级(normal→warned→stopPending),两次副作用各触发一次。
func (*BudgetSentinel) Refuse ¶ added in v0.5.0
func (s *BudgetSentinel) Refuse() error
Refuse 启动前置检查:预算已超返回拒绝错误(Start/Resume/Continue 恢复路径调用)。 用户上调预算 = 重新授权,新配置下 Refuse 自然放行。
type ChapterAdvanceGate ¶ added in v0.7.0
type ChapterAdvanceGate struct {
// contains filtered or unexported fields
}
ChapterAdvanceGate 是 Host 唯一的创作前进政策组件:
- AdvanceHold:执行本次干预签署的一次性暂停;
- review permit:阻止未获许可的正向新章。
它不参与 Route,不解释 Task/Reason,也不做文学判断。
func NewChapterAdvanceGate ¶ added in v0.7.0
func NewChapterAdvanceGate(s *store.Store, pause func(reason string), report func(level, summary string)) *ChapterAdvanceGate
func (*ChapterAdvanceGate) Allow ¶ added in v0.7.0
func (g *ChapterAdvanceGate) Allow(inst *flow.Instruction) (bool, error)
Allow 在 Worker 派发前执行最终许可检查。
func (*ChapterAdvanceGate) HandleBoundary ¶ added in v0.7.0
func (g *ChapterAdvanceGate) HandleBoundary() bool
HandleBoundary 消费命中的 hold,并对账章节许可。返回 true 表示 Engine 必须停止。 auto 且无 hold 时只读一次 RunMeta,不触碰 Progress/PendingCommit/checkpoint。
type CoCreateMessage ¶
CoCreateMessage 是共创对话的消息。
type CoCreateReply ¶
type CoCreateReply struct {
Message string
Prompt string
Ready bool
Suggestions []string
Raw string
}
CoCreateReply 是共创对话的 LLM 回复。Raw 保留模型完整四段原文, 用于写回 history 让下一轮模型看到自己上一轮的 [DRAFT],从而真正在 已有草稿上累积更新(仅 Message 不含 [DRAFT],会导致模型每轮凭对话重新归纳)。 Suggestions 是 AI 主动给的"接下来你可能想说",用户卡壳时按数字键一键填入输入框。
type ConfiguredModel ¶ added in v0.7.3
type ConfiguredModel struct {
Name string
ContextWindow int
ContextSource bootstrap.ContextWindowSource
}
type Event ¶
type Event struct {
ID string // 同一次调用的开始/结束共用;非调用事件为空
Time time.Time // 首次发出时间(开始时刻)
FinishedAt time.Time // 零值 = 进行中;非零 = 已完成
Failed bool // 已完成但失败(仅完成态有意义)
Category string // DISPATCH / TOOL / DECISION / 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 = Engine 层, 1 = Worker 层
Duration time.Duration // 完成时的执行耗时
RetryAt time.Time // 重试类事件:下次重试的截止时刻;UI 据此逐秒倒计时,到点即清(请求已在途)
}
Event 是 TUI 消费的结构化事件。
对于 TOOL / DISPATCH / DECISION 三类调用事件,同一次调用的开始与结束共用一个 ID: 开始时先发 FinishedAt 为零值的事件(TUI 渲染为"进行中"样式); 结束时再发一条同 ID 的事件,填入 FinishedAt + Duration(+ Failed), TUI 按 ID 定位原行原地更新,避免"开始一行、完成又一行"的冗余。
SYSTEM / ERROR / CONTEXT 等非调用类事件 ID 为空,每条独立追加。
type Host ¶
type Host struct {
// contains filtered or unexported fields
}
Host 是运行时外壳:生命周期/干预入口/事件投影/模型管理。 调度与执行在 engine(确定性循环);语义裁定在 arbiter(LLM-as-function)。
func (*Host) AdvanceOneChapter ¶ added in v0.7.0
AdvanceOneChapter 在逐章验收模式下授权一个精确章节并启动 Engine。
func (*Host) AvailableThinking ¶ added in v0.5.3
func (h *Host) AvailableThinking(role string) []agentcore.ThinkingLevel
func (*Host) CancelCoCreate ¶ added in v0.5.1
func (h *Host) CancelCoCreate()
CancelCoCreate 放弃阶段共创:清占用标记,保持暂停态(用户可在输入框继续或重启 Resume)。
func (*Host) Close ¶
func (h *Host) Close()
Close 终止引擎并关闭事件通道。
Usage 持久化语义:先取消 autoSaveLoop(它自行 flush 最后一次 dirty 状态), 再补一次同步 SaveNow 收尾。终止后 in-flight LLM 调用的最末几百 token 丢失由下次启动时 session jsonl replay 自动补回。
func (*Host) CoCreateStream ¶
func (h *Host) CoCreateStream(ctx context.Context, history []CoCreateMessage, onProgress func(kind, text string)) (CoCreateReply, error)
CoCreateStream 冷启动共创:从零澄清需求,产出整本书的创作指令。
func (*Host) ConfigureModels ¶ added in v0.7.3
func (h *Host) ConfigureModels(draft ModelConfigurationDraft) error
ConfigureModels 校验、持久化并热应用一个 provider 的模型库。
func (*Host) ConfiguredModelOptions ¶ added in v0.7.3
func (h *Host) ConfiguredModelOptions(provider string) []ConfiguredModel
func (*Host) ConfiguredModels ¶
func (*Host) ConfiguredProviders ¶
func (*Host) CurrentModelSelection ¶
func (*Host) CurrentThinking ¶ added in v0.5.2
CurrentThinking 返回某角色当前生效的推理强度原始串(供 /model 面板同步当前值)。
func (*Host) Export ¶ added in v0.4.0
Export 导出已完成章节为外部文件(当前仅支持 TXT)。
与 ImportFrom 不同:导出是只读操作(不动 Progress / Checkpoint), 因此**不要求 Engine 停机**——写作中途也可以随时导出"现阶段成品"。 只读到 Progress.CompletedChapters + 章节终稿 + 大纲 + premise 的一致快照。
func (*Host) ImportFrom ¶ added in v0.3.0
ImportFrom 启动一次外部小说语义编译导入:ingest → segment → analyze → synthesize → publish。 模型只裁定开放语义(边界/事实/综合),Go 掌管坐标/覆盖/幂等;与 Engine 运行互斥, 导入完成后由 AdvanceHold 决定是否续写。 返回的事件通道由 imp.Run 关闭,调用方负责消费(满则丢弃以防阻塞管线协程)。
func (*Host) ImportResumeHint ¶ added in v0.7.2
ImportResumeHint 返回未完成导入的一行提示(无则空串),供 TUI 启动时主动告知(RFC §18.2)。 只在启动时调用一次:内部会重算工作区各工件的 InputDigest,不适合放进快照轮询。
func (*Host) ImportSimulationProfile ¶ added in v0.4.2
ImportSimulationProfile 导入此前生成的仿写画像。
func (*Host) ModelConfiguration ¶ added in v0.7.3
func (h *Host) ModelConfiguration() ModelConfigurationSnapshot
ModelConfiguration 返回脱敏配置、可写目标和模型引用,绝不暴露现有 API Key。
func (*Host) PauseForCoCreate ¶ added in v0.5.1
PauseForCoCreate 进入阶段共创:置共创占用标记,运行中则一并暂停 Engine。 返回 false 表示无法进入(全书已完成或已在共创中),调用方忽略即可。 占用标记在共创窗口内堵住 import/simulate/start/resume/continue 的并发介入—— 运行中暂停后 lifecycle=paused,现有 ==running 互斥失效,靠该标记补缺; 已停止(idle/paused)也允许进入,规划完经 Continue 续跑。
func (*Host) PrepareUserRules ¶ added in v0.6.0
PrepareUserRules 在新建模式下生成本书用户规则快照(启动侧确定性,不进主创作 Run)。
入参是用户的**原始**创作要求(未经 BuildStartPrompt 包装)——归一化要的是用户规则本身, 不是启动脚手架。入口须在 StartPrepared 之前调用一次(quick/cocreate 两条新建路径都走这里)。
归一化失败只降级不报错(增强路径);只有快照无法落盘才返回 error 中止开书—— 后续运行将没有稳定事实源(见设计 §失败与降级)。
func (*Host) Reopen ¶ added in v0.7.2
Reopen 把已完结的书强制重开为创作态。完本与重开都是重决策:完本可由架构师裁定, 重开只能由用户显式发起(/reopen),不经模型裁定。direction 非空时登记为待处理干预, 恢复时先经 Arbiter 裁定注入(与停机期干预同通道),再续跑引擎(卷末路由派发续卷)。
func (*Host) ReplayQueue ¶
func (h *Host) ReplayQueue(afterSeq int64) ([]domain.RuntimeQueueItem, error)
func (*Host) ResumeFromCoCreate ¶ added in v0.5.1
ResumeFromCoCreate 结束阶段共创:把共创产出的后续方向作为干预注入并恢复创作。 清占用标记后复用 Continue 的停机注入路径(受预算前置约束)。 注:draft 为空时提前返回、不清标记是有意的(共创尚未结束);TUI 侧 canStart() 守卫 与此处用同一"非空"判据,保证该路径不可达,cocreating 不会因此泄漏。
func (*Host) SetAdvanceMode ¶ added in v0.7.0
func (h *Host) SetAdvanceMode(mode domain.ChapterAdvanceMode) error
SetAdvanceMode 确定性切换章节推进模式。它只写入用户运行意图, 不调用 Arbiter,也不隐式启动已经暂停的 Engine。
func (*Host) SetRoleThinking ¶ added in v0.5.2
SetRoleThinking 设置某角色(或 default)的推理强度:校验→持久化→联动 live agent→事件。 镜像 SwitchModel 的结构;与模型选择正交,可单独调整。level 为空 = 不覆盖(继承)。
func (*Host) Snapshot ¶
func (h *Host) Snapshot() UISnapshot
func (*Host) StageCoCreateStream ¶ added in v0.5.1
func (h *Host) StageCoCreateStream(ctx context.Context, history []CoCreateMessage, onProgress func(kind, text string)) (CoCreateReply, error)
StageCoCreateStream 阶段共创:在已写内容的基础上规划后续方向。 系统提示 = 阶段 prompt + 当前故事状态摘要,让助手知道"已经写了什么"。
func (*Host) StartPrepared ¶
StartPrepared 用用户的**原始**创作要求开始创作:plan_start 裁定选规划师并扩充 需求,裁定结果先固化为 事实(PlanStartRecord)再启动 Engine——恢复永远依赖已落盘事实,不重做已有裁定。 输入事实(StartPrompt)在裁定之前落盘:裁定失败时它是引擎补裁的依据, 启动失败可从任何恢复入口(Resume/继续)自愈,不是死局。
func (*Host) Steer ¶
Steer 提交用户干预(运行中随时可用;停机时裁定后视动作决定是否拉起引擎)。 TUI 通过 tea.Cmd 等待结果,因此能收到真实裁定/持久化错误而不会阻塞界面。
func (*Host) SwitchModel ¶
func (*Host) TestModelConnection ¶ added in v0.7.3
func (h *Host) TestModelConnection(ctx context.Context, draft ModelConfigurationDraft, modelName string) error
TestModelConnection 使用当前草稿构造一个真实模型客户端并发送最小请求。 它不保存配置、不切换运行时模型,也不在失败时降级到其他 Provider。
type ModelConfigurationDraft ¶ added in v0.7.3
type ModelConfigurationDraft struct {
Provider string
Type string
API string
BaseURL string
Models []bootstrap.ModelConfig
Renames []ModelRename
APIKeyAction APIKeyAction
APIKey string
}
ModelConfigurationDraft 是 /config 提交给 Host 的单个 provider 配置草稿。 只描述该 provider 的定义(协议/凭证/模型库),不含“当前用哪个”——切换归 /model。
type ModelConfigurationSnapshot ¶ added in v0.7.3
type ModelConfigurationSnapshot struct {
Providers []ProviderSnapshot
DefaultProvider string
DefaultModel string
ConfigPath string
References map[string][]string
}
func (ModelConfigurationSnapshot) ReferencesFor ¶ added in v0.7.3
func (s ModelConfigurationSnapshot) ReferencesFor(provider, model string) []string
type ModelRename ¶ added in v0.7.3
ModelRename 描述同一条模型配置的 ID 变化。它不是“删旧增新”的猜测, Host 只在 TUI 明确提交该关系时迁移 default、角色和 fallback 引用。
type OutlineSnapshot ¶
OutlineSnapshot 是大纲条目的展示摘要。
type ProviderSnapshot ¶ added in v0.7.3
type ProviderSnapshot struct {
Name string
Type string
API string
BaseURL string
Models []bootstrap.ModelConfig
HasAPIKey bool
APIKeyHint string
RequiresAPIKey bool
}
ProviderSnapshot 是供 TUI 使用的脱敏 provider 配置。
type UISnapshot ¶
type UISnapshot struct {
Provider string
NovelName string
ModelName string
ModelContextWindow int // 当前默认模型的上下文窗口(随 /model 切换实时解析)
ThinkingLevel string
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
AdvanceMode string
AdvancePermitChapter int
HasAdvanceHold bool
AdvanceHoldReason string
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 命中省下的美元(相对全按非缓存输入价计费)
BudgetLimitUSD float64 // 预算上限(config budget.book_usd);0 = 未启用
// 缓存诊断
OverallCacheCapable bool // 至少一个 role 跑过支持 prompt cache 的模型(区分"未启用"和"0% 命中")
OverallRecentCacheRead int // 滑动窗最近 N 次的 cacheRead 总和
OverallRecentInput int // 滑动窗最近 N 次的 input 总和
OverallRecentSamples int // 滑动窗内的样本数(≤ recentSampleCap)
TotalCacheBreaks int // live 检测到的缓存链断裂次数(前缀未缩短而命中骤降),详见 usage.go noteCacheBreak
// 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 ¶ added in v0.1.2
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):
- 累计命中数据 → 整体优化效果
- 滑动窗最近 N 次 → 区分前期拖累 vs 稳态低命中
- CacheCapable 标记 → 区分"未启用"和"真的 0% 命中"
线程安全。
func NewUsageTracker ¶ added in v0.1.2
func NewUsageTracker(set *bootstrap.ModelSet, store *storepkg.Store) *UsageTracker
func (*UsageTracker) LoadFromStore ¶ added in v0.4.0
func (t *UsageTracker) LoadFromStore() (bool, error)
LoadFromStore 从 store.Usage 读取持久化的快照并回填到内存。返回 true 表示 成功加载到了一份非空(schema 匹配)的状态;false 表示无文件或不可用,调用方 应继续走 session replay 一次性回填。
func (*UsageTracker) MissingAssistantUsage ¶ added in v0.3.1
func (t *UsageTracker) MissingAssistantUsage() int
MissingAssistantUsage 返回累计"收到 assistant 消息但 Usage 为 nil"的次数。 大于 0 通常意味着上游 streaming 没发 OpenAI 的 final usage chunk, UI 据此显示提示而非误以为缓存模块本身坏了。
func (*UsageTracker) OverallCacheBreaks ¶ added in v0.6.2
func (t *UsageTracker) OverallCacheBreaks() int
OverallCacheBreaks 返回 live 检测到的缓存链断裂总次数。
func (*UsageTracker) OverallCacheCapable ¶ added in v0.3.1
func (t *UsageTracker) OverallCacheCapable() bool
OverallCacheCapable 整体是否至少经过一次已知支持 cache 的模型。
func (*UsageTracker) OverallRecent ¶ added in v0.3.1
func (t *UsageTracker) OverallRecent() (cacheRead, input, samples int)
OverallRecent 返回滑动窗内(≤ recentSampleCap 次)的 cacheRead 总和、input 总和、样本数。
func (*UsageTracker) PerAgent ¶ added in v0.3.1
func (t *UsageTracker) PerAgent() []AgentUsage
PerAgent 返回各 role 累计用量。结果按 CacheRead 数量降序,未消费过 token 的 role 跳过。
func (*UsageTracker) PerModel ¶ added in v0.4.1
func (t *UsageTracker) PerModel() []AgentUsage
PerModel 返回各模型累计用量。结果按成本降序,其次按输入量降序。
func (*UsageTracker) Record ¶ added in v0.1.2
func (t *UsageTracker) Record(agentName, task string, msg agentcore.AgentMessage)
Record 把一条 agent 消息分发到累加 / 诊断两条路径。
累加只看 Usage 是否存在——"哪条消息带 Usage" 是 agentcore/litellm adapter 装配细节(上游协议把 usage 放在响应顶层),未来装配规则变了也不用动这里。 诊断要求 Role=Assistant 且 Content 非空,避免 AbortMsg / 异常恢复 / tool / user 消息污染 missingAssistantUsage 计数。
func (*UsageTracker) ReplaySessions ¶ added in v0.4.0
func (t *UsageTracker) ReplaySessions(rootDir string) (int, error)
ReplaySessions 扫 meta/sessions/agents/*.jsonl, 把每条 assistant 消息的 usage 重新累加到 tracker。返回回填条数。
调用约束:仅在 meta/usage.json 缺失时调用一次回填。 日常持久化走 SaveNow / autoSaveLoop。
精度依赖见 sessionRecord 注释的三级降级——第 3 级(Usage 和 _meta 都缺) 在更老日志或上游异常时才会触发。
func (*UsageTracker) SaveNow ¶ added in v0.4.0
func (t *UsageTracker) SaveNow() error
SaveNow 立刻把当前 snapshot 落盘。autoSaveLoop / Close 路径都通过它写。
func (*UsageTracker) SavedUSD ¶ added in v0.3.1
func (t *UsageTracker) SavedUSD() float64
SavedUSD 返回因缓存命中节省的累计美元数。
func (*UsageTracker) SetOnCost ¶ added in v0.5.0
func (t *UsageTracker) SetOnCost(cb func(total float64))
SetOnCost 注册记账回调(携带最新累计成本,锁外调用)。 必须在 Host 构造期、并发 Record 开始前调用一次。
func (*UsageTracker) SetOnMissingUsage ¶ added in v0.5.0
func (t *UsageTracker) SetOnMissingUsage(cb func())
SetOnMissingUsage 注册"首次发现 usage 缺失"的一次性回调。 必须在 Host 构造期、并发 Record 开始前调用一次。
func (*UsageTracker) Snapshot ¶ added in v0.4.0
func (t *UsageTracker) Snapshot() domain.UsageState
Snapshot 拷贝当前累计状态为可序列化的 domain.UsageState。 滑动窗 samples 不进 snapshot——它是短期诊断窗口,跨进程意义不大。
func (*UsageTracker) StartAutoSave ¶ added in v0.4.0
func (t *UsageTracker) StartAutoSave(ctx context.Context)
StartAutoSave 起一个 goroutine,监听 saveCh + debounce 落盘。ctx done 前会 把最后一次未保存的状态 flush 出去。Close 通过 cancel ctx 触发 flush + 退出。
func (*UsageTracker) Totals ¶ added in v0.1.2
func (t *UsageTracker) Totals() (cost float64, input, output, cacheRead, cacheWrite int)
Totals 返回累计总量的快照。
func (*UsageTracker) WaitAutoSave ¶ added in v0.7.3
func (t *UsageTracker) WaitAutoSave()
WaitAutoSave 等待取消后的最后一次 flush 完成。Host.Close 先调用 cancel, 再等待这里,避免 autoSaveLoop 与退出前 SaveNow 并发写同一快照。