Documentation
¶
Index ¶
- Constants
- Variables
- func LogEvent(ev Event)
- func MaskAPIKey(value string) 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) CheckChapterRevisions() ([]int, error)
- 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) FileLogError() 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) SyncChapterRevisions(ctx context.Context) (*revision.Result, error)
- func (h *Host) TestModelConnection(ctx context.Context, draft ModelConfigurationDraft, modelName string) error
- type ModelConfigurationDraft
- type ModelConfigurationSnapshot
- type ModelRename
- type NewOption
- 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 identifies the content type of a streaming callback.
const StreamClearSentinel = "\x00\x00CLEAR\x00\x00"
StreamClearSentinel gửi một mục qua streamCh để báo hiệu "xoá round đang stream". Không dùng clearCh riêng nữa — hai kênh không có thứ tự khiến header ✻ hay rơi xuống cuối round trước.
Variables ¶
var ErrBookInUse = errors.New("Thư mục truyện đã bị một instance " + buildversion.AppName + " khác chiếm")
ErrBookInUse nghĩa là cùng thư mục truyện đã bị một tiến trình khác chiếm. Nêu đúng tên chương trình từ AppName, vì đây là thông báo người dùng đọc được và phải khớp với tên binary họ sẽ chạy.
Functions ¶
func LogEvent ¶
func LogEvent(ev Event)
LogEvent records one UI / runtime event through the process logger. Summary is the display text; Detail is the full diagnostic payload and is used as the log body whenever it is present.
func MaskAPIKey ¶
MaskAPIKey chỉ giữ đầu-cuối vừa đủ nhận diện chứng thực; key ngắn che hết. TUI chỉ nhận kết quả này, không bao giờ giữ API Key đầy đủ trong cấu hình.
Types ¶
type APIKeyAction ¶
type APIKeyAction string
const ( APIKeyKeep APIKeyAction = "keep" APIKeyReplace APIKeyAction = "replace" APIKeyClear APIKeyAction = "clear" )
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 is a single agent's cumulative cache hits (projected into the left column). HitRate = CacheRead / Input; Input already carries the "includes CacheRead" semantics at the litellm layer.
CacheCapable distinguishes the two kinds of 0% hit rate:
- true -> the model supports prompt cache, 0% means a badly designed prompt or an unstable prefix, and needs optimizing
- false -> the model/provider does not support prompt cache, 0% is expected and needs no investigation
Recent* is the hit data of the sliding window (the last N calls); comparing it with the cumulative total identifies "an early-drag problem" vs "a steady low hit rate".
type AgentContextSnapshot ¶
type AgentContextSnapshot struct {
Tokens int
ContextWindow int
Percent float64
Scope string
Strategy string
ActiveMessages int
SummaryMessages int
CompactedCount int
KeptCount int
}
AgentContextSnapshot is the Agent context usage.
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 is the display projection of an Agent's state.
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 is a snapshot of one agent's cumulative usage (exposed to the UI).
type BudgetSentinel ¶
type BudgetSentinel struct {
// contains filtered or unexported fields
}
BudgetSentinel theo dõi chi phí tích luỹ và thực thi chính sách ngân sách của người dùng (khối budget trong cấu hình).
Định vị hợp lý (architecture.md §8.3/§10): không đánh giá hành vi model — dừng khi vượt hạn tương đương Abort thủ công của người dùng vào đúng thời điểm đó, Host chỉ thay họ thực thi một chỉ lệnh đã ký trước. Nó ảnh hưởng dòng điều khiển nên không phải quan sát viên, mà là thành phần chính sách của Host ngang hàng với flow.Dispatcher; tầng Route/công cụ không biết tới.
Thời điểm dừng: mặc định ở ranh giới tác vụ con (Host gọi đồng bộ HandleBoundary), không phí chương đang chạy dở; hardStop=true thì dừng ngay khi vượt. Xử lý ranh giới diễn ra trước khi flow.Dispatcher phát việc kế tiếp; tầng Route/công cụ không biết tới ngân sách.
func NewBudgetSentinel ¶
func NewBudgetSentinel(cfg bootstrap.BudgetConfig, costNow func() float64, abort func(reason string), report func(level, summary string)) *BudgetSentinel
NewBudgetSentinel tạo cảnh báo ngân sách; trả nil khi chính sách không bật (mọi method đều nil-safe).
func (*BudgetSentinel) HandleBoundary ¶
func (s *BudgetSentinel) HandleBoundary() bool
func (*BudgetSentinel) HandleEvent ¶
func (s *BudgetSentinel) HandleEvent(ev agentcore.Event)
HandleEvent thực hiện lệnh dừng đang chờ ở ranh giới tác vụ con. Phải đăng ký trước Dispatcher. Không bỏ qua IsError — trả về lỗi cũng là một ranh giới, việc dừng không nên bị hoãn vì tác vụ con thất bại.
func (*BudgetSentinel) Limit ¶
func (s *BudgetSentinel) Limit() float64
Limit trả về trần ngân sách (để TUI hiển thị); trả 0 khi không bật.
func (*BudgetSentinel) OnCost ¶
func (s *BudgetSentinel) OnCost(total float64)
OnCost do UsageTracker gọi sau mỗi lần ghi sổ, mang theo chi phí tích luỹ mới nhất (ngoài khoá). Một lần callback có thể nhảy qua hai cấp (normal→warned→stopPending), mỗi tác dụng phụ kích hoạt đúng một lần.
func (*BudgetSentinel) Refuse ¶
func (s *BudgetSentinel) Refuse() error
Refuse là kiểm tra trước khi chạy: trả lỗi từ chối nếu đã vượt ngân sách (được gọi ở các đường Start/Resume/Continue). Người dùng tăng ngân sách = cấp quyền lại, với cấu hình mới thì Refuse tự nhiên cho qua.
type ChapterAdvanceGate ¶
type ChapterAdvanceGate struct {
// contains filtered or unexported fields
}
ChapterAdvanceGate là thành phần chính sách tiến viết duy nhất của Host:
- AdvanceHold: thực hiện lần tạm dừng một lần mà can thiệp này đã ký;
- review permit: chặn chương mới tiến về phía trước khi chưa được cấp quyền.
Nó không tham gia Route, không diễn giải Task/Reason, cũng không đưa ra phán đoán văn chương.
func NewChapterAdvanceGate ¶
func NewChapterAdvanceGate(s *store.Store, pause func(reason string), report func(level, summary string)) *ChapterAdvanceGate
func (*ChapterAdvanceGate) Allow ¶
func (g *ChapterAdvanceGate) Allow(inst *flow.Instruction) (bool, error)
Allow thực hiện kiểm tra giấy phép cuối cùng trước khi phát việc cho Worker.
func (*ChapterAdvanceGate) HandleBoundary ¶
func (g *ChapterAdvanceGate) HandleBoundary() bool
HandleBoundary tiêu thụ hold trúng và đối soát giấy phép chương. Trả true nghĩa là Engine phải dừng. Khi ở auto và không có hold thì chỉ đọc RunMeta một lần, không đụng Progress/PendingCommit/checkpoint.
type CoCreateMessage ¶
CoCreateMessage is a message of the co-create conversation.
type CoCreateReply ¶
type CoCreateReply struct {
Message string
Prompt string
Ready bool
Suggestions []string
Raw string
}
CoCreateReply is the LLM reply of the co-create conversation. Raw keeps the model's complete four-part original text, which is written back into history so the next round sees its own previous [DRAFT], and therefore really accumulates updates on top of the existing draft (with only Message, the model would re-summarise from the conversation every round). Suggestions is the AI's proactive "here is what you might want to say next"; when the user is stuck, a number key fills it into the input box in one keystroke.
type ConfiguredModel ¶
type ConfiguredModel struct {
Name string
ContextWindow int
ContextSource bootstrap.ContextWindowSource
}
type Event ¶
type Event struct {
ID string // shared by the start and the end of one call; empty for non-call events
Time time.Time // when it was first emitted (the start moment)
FinishedAt time.Time // zero value = in progress; non-zero = finished
Failed bool // finished but failed (only meaningful in the finished state)
Category string // DISPATCH / MODEL / TOOL / DECISION / SYSTEM / REVIEW / CHECK / ERROR / CONTEXT
Agent string // the agent that produced the event
Summary string
Detail string // full text, written to the log untruncated for troubleshooting; falls back to Summary when empty. The UI only reads Summary
Kind string // error classification (e.g. stream_idle), emitted with the log for filtering/alerting; not emitted when empty
Level string // info / warn / error / success
Depth int // 0 = Engine layer, 1 = Worker layer
Duration time.Duration // how long the execution took, once finished
RetryAt time.Time // retry events: the deadline of the next retry; the UI counts down second by second from it and clears at zero (the request is already in flight)
}
Event is a structured event consumed by the TUI.
For call events (MODEL / TOOL / DISPATCH / DECISION) the start and the end of one call share a single ID: at the start an event with a zero FinishedAt is emitted first (the TUI renders it in the "in progress" style); at the end another event with the same ID is emitted, filling in FinishedAt + Duration (+ Failed), and the TUI locates the original row by ID and updates it in place, avoiding the redundancy of
"a row for the start and another row for the finish". Non-call events (SYSTEM / ERROR / CONTEXT) have an
type Host ¶
type Host struct {
// contains filtered or unexported fields
}
Host là vỏ runtime: vòng đời / cửa vào can thiệp / chiếu sự kiện / quản lý model. Lập lịch và thực thi nằm ở engine (vòng lặp tất định); định đoạn ngữ nghĩa nằm ở arbiter (LLM-as-function).
func (*Host) AdvanceOneChapter ¶
AdvanceOneChapter cấp quyền cho đúng một chương ở chế độ duyệt từng chương rồi khởi động Engine.
func (*Host) AvailableThinking ¶
func (h *Host) AvailableThinking(role string) []agentcore.ThinkingLevel
func (*Host) CancelCoCreate ¶
func (h *Host) CancelCoCreate()
CancelCoCreate bỏ dở đồng sáng tác: xóa cờ chiếm, giữ trạng thái tạm dừng (người dùng có thể nhập tiếp ở ô nhập hoặc khởi động lại để Resume).
func (*Host) CheckChapterRevisions ¶
func (*Host) Close ¶
func (h *Host) Close()
Close dừng Engine và đóng kênh sự kiện.
Ngữ nghĩa lưu bền của Usage: trước hết hủy autoSaveLoop (nó tự flush lần trạng thái dirty cuối), rồi gọi thêm một SaveNow đồng bộ để chốt. Sau khi dừng, vài trăm token cuối của lệnh gọi LLM đang dở có thể mất, nhưng sẽ được bù tự động bằng replay session jsonl ở lần khởi động sau.
func (*Host) CoCreateStream ¶
func (h *Host) CoCreateStream(ctx context.Context, history []CoCreateMessage, onProgress func(kind, text string)) (CoCreateReply, error)
CoCreateStream đồng sáng tác khởi đầu từ số 0: làm rõ yêu cầu và sinh chỉ đạo sáng tác cho cả cuốn.
func (*Host) ConfigureModels ¶
func (h *Host) ConfigureModels(draft ModelConfigurationDraft) error
ConfigureModels kiểm tra, lưu và áp nóng kho model của một provider.
func (*Host) ConfiguredModelOptions ¶
func (h *Host) ConfiguredModelOptions(provider string) []ConfiguredModel
func (*Host) ConfiguredModels ¶
func (*Host) ConfiguredProviders ¶
func (*Host) Continue ¶
Continue is called when the user types in the input box after pausing: it locks in the intervention and makes sure the Engine runs again.
func (*Host) CurrentModelSelection ¶
func (*Host) CurrentThinking ¶
CurrentThinking trả về chuỗi mức suy luận đang có hiệu lực của một vai trò (để /model đồng bộ giá trị hiện tại).
func (*Host) Export ¶
Export xuất các chương đã hoàn thành ra file ngoài (hiện chỉ hỗ trợ TXT).
Khác với ImportFrom: xuất là thao tác chỉ đọc (không đụng Progress / Checkpoint), nên **không yêu cầu Engine dừng** — kể cả khi đang viết cũng xuất được "thành phẩm tại thời điểm này". Chỉ đọc một snapshot nhất quán gồm Progress.CompletedChapters + bản chính thức chương + dàn ý + premise.
func (*Host) FileLogError ¶
FileLogError trả về lỗi khởi tạo log file lúc dựng; không đổi trong suốt vòng đời của Host.
func (*Host) ImportFrom ¶
ImportFrom chạy một lần nhập biên dịch ngữ nghĩa truyện ngoài: ingest → segment → analyze → synthesize → publish. Model chỉ định đoạn phần ngữ nghĩa mở (biên/độ kiện/tổng hợp), Go phụ trách toạ độ/ghi đè/idempotent; loại trừ với Engine đang chạy, sau khi nhập xong thì AdvanceHold quyết định có viết tiếp hay không. Kênh sự kiện trả về do imp.Run đóng; bên gọi chịu trách nhiệm tiêu thụ (đầy thì bỏ để không chặn goroutine pipeline).
func (*Host) ImportResumeHint ¶
ImportResumeHint trả về một dòng nhắc về lần nhập chưa xong (rỗng nếu không có), để TUI chủ động báo lúc khởi động (RFC §18.2). Chỉ gọi một lần lúc khởi động: bên trong tính lại InputDigest của từng artifact trong workspace, không hợp đặt vào vòng poll snapshot.
func (*Host) ImportSimulationProfile ¶
ImportSimulationProfile nhập hồ sơ văn phong đã sinh từ trước.
func (*Host) ModelConfiguration ¶
func (h *Host) ModelConfiguration() ModelConfigurationSnapshot
ModelConfiguration trả về cấu hình đã che, đích ghi và tham chiếu model, không bao giờ lộ API Key hiện có.
func (*Host) PauseForCoCreate ¶
PauseForCoCreate vào đồng sáng tác giai đoạn: đặt cờ chiếm đồng sáng tác, nếu đang chạy thì tạm dừng Engine luôn. Trả false nghĩa là không vào được (đã xong sách hoặc đang trong đồng sáng tác), bên gọi có thể bỏ qua. Cờ chiếm trong cửa sổ đồng sáng tác chặn can thiệp chồng nhau từ import/simulate/start/resume/continue — khi tạm dừng lúc đang chạy thì lifecycle=paused, ràng buộc loại trừ ==running mất hiệu lực, nên phải có cờ này bù; đã dừng (idle/paused) vẫn cho vào, xong phần quy hoạch sẽ chạy tiếp qua Continue.
func (*Host) PrepareUserRules ¶
PrepareUserRules sinh snapshot quy tắc người dùng cho cuốn sách này ở chế độ tạo mới (tất định phía khởi động, không đi vào Run sáng tác chính).
Đầu vào là yêu cầu sáng tác **gốc** của người dùng (chưa bọc qua BuildStartPrompt) — thứ cần chuẩn hóa là chính quy tắc của người dùng, không phải khung khởi động. Cửa vào phải được gọi một lần trước StartPrepared (cả hai đường tạo mới quick/cocreate đều đi qua đây).
Chuẩn hóa hỏng chỉ hạ cấp, không báo lỗi (đường tăng cường); chỉ khi không ghi được snapshot mới trả error để dừng việc tạo truyện — nếu không thì các lần chạy sau sẽ không có nguồn dữ kiện ổn định (xem thiết kế §thất bại và hạ cấp).
func (*Host) Reopen ¶
Reopen mở lại cuốn đã hoàn thành thành trạng thái đang viết. Xong sách và mở lại đều là quyết định nặng: xong sách có thể do kiến trúc sư định đoạn, còn mở lại chỉ người dùng chủ động yêu cầu (/reopen), không qua định đoạn của model. direction khác rỗng được ghi là can thiệp chờ xử lý; khi khôi phục, Arbiter sẽ định đoạn rồi chèn (cùng kênh với can thiệp lúc dừng), sau đó Engine chạy tiếp (định tuyến cuối tập sẽ phát ra tập tiếp theo).
func (*Host) ReplayQueue ¶
func (h *Host) ReplayQueue(afterSeq int64) ([]domain.RuntimeQueueItem, error)
func (*Host) Resume ¶
Resume chế độ khôi phục: sinh resume prompt từ checkpoint + progress rồi khởi động.
func (*Host) ResumeFromCoCreate ¶
ResumeFromCoCreate kết thúc đồng sáng tác: chèn hướng đi tiếp do đồng sáng tác sinh ra thành can thiệp rồi khôi phục việc viết. Sau khi xóa cờ chiếm, tái dùng đường chèn của Continue khi đã dừng (vẫn chịu ràng buộc ngân sách trước). Lưu ý: draft rỗng thì trả về sớm mà không xóa cờ là cố ý (đồng sáng tác chưa kết thúc); phía TUI dùng cùng một tiêu chí "không rỗng" ở canStart(), nên đường này không tới được và cocreating không bị rò.
func (*Host) SetAdvanceMode ¶
func (h *Host) SetAdvanceMode(mode domain.ChapterAdvanceMode) error
SetAdvanceMode chuyển chế độ đẩy chương theo cách tất định. Nó chỉ ghi ý định chạy của người dùng, không gọi Arbiter và không tự khởi động Engine đang tạm dừng.
func (*Host) SetRoleThinking ¶
SetRoleThinking đặt mức suy luận cho một vai trò (hoặc default): kiểm tra → lưu bền → liên kết agent đang chạy → sự kiện. Cấu trúc đối xứng với SwitchModel; độc lập với việc chọn model nên chỉnh riêng được. level rỗng = không ghi đè (kế thừa).
func (*Host) Snapshot ¶
func (h *Host) Snapshot() UISnapshot
func (*Host) StageCoCreateStream ¶
func (h *Host) StageCoCreateStream(ctx context.Context, history []CoCreateMessage, onProgress func(kind, text string)) (CoCreateReply, error)
StageCoCreateStream đồng sáng tác theo giai đoạn: quy hoạch hướng đi tiếp dựa trên phần đã viết. Prompt hệ thống = prompt giai đoạn + tóm tắt trạng thái câu chuyện hiện tại, để trợ lý biết "đã viết đến đâu".
func (*Host) StartPrepared ¶
StartPrepared bắt đầu viết từ yêu cầu sáng tác **gốc** của người dùng: định đoạn plan_start chọn kiến trúc sư và mở rộng yêu cầu, kết quả định đoạn được cố thành dữ kiện trước (PlanStartRecord) rồi mới khởi động Engine — mọi lần khôi phục luôn dựa trên dữ kiện đã ghi đĩa, không làm lại định đoạn đã có. Dữ kiện đầu vào (StartPrompt) được ghi đĩa trước khi định đoạn: nếu định đoạn hỏng thì đây là căn cứ để Engine bù định đoạn, nên khởi động hỏng vẫn tự lành từ mọi cửa khôi phục (Resume/tiếp tục), không phải ngõ cụt.
func (*Host) Steer ¶
Steer submits a user intervention (allowed at any point while running; once paused, whether the Engine is pulled back up afterwards depends on the action). The TUI waits on the result through a tea.Cmd, so it sees the real lock-in/persist error without blocking the interface.
func (*Host) SwitchModel ¶
func (*Host) SyncChapterRevisions ¶
func (*Host) TestModelConnection ¶
func (h *Host) TestModelConnection(ctx context.Context, draft ModelConfigurationDraft, modelName string) error
TestModelConnection dùng bản nháp hiện tại dựng một client model thật và gửi request tối thiểu. Không lưu cấu hình, không chuyển model runtime, thất bại cũng không rớt sang Provider khác.
type ModelConfigurationDraft ¶
type ModelConfigurationDraft struct {
Provider string
Type string
API string
BaseURL string
Models []bootstrap.ModelConfig
Renames []ModelRename
APIKeyAction APIKeyAction
APIKey string
}
ModelConfigurationDraft là bản nháp một provider mà /config gửi cho Host. Chỉ mô tả định nghĩa provider (giao thức/chứng thực/kho model), không gồm "đang dùng cái nào" — chuyển model là việc của /model.
type ModelConfigurationSnapshot ¶
type ModelConfigurationSnapshot struct {
Providers []ProviderSnapshot
DefaultProvider string
DefaultModel string
ConfigPath string
References map[string][]string
}
func (ModelConfigurationSnapshot) ReferencesFor ¶
func (s ModelConfigurationSnapshot) ReferencesFor(provider, model string) []string
type ModelRename ¶
ModelRename mô tả việc đổi ID của cùng một cấu hình model. Nó không phải phỏng đoán "xóa cũ thêm mới" — Host chỉ chuyển default, vai trò và tham chiếu fallback khi TUI gửi tường minh quan hệ này.
type NewOption ¶
type NewOption func(*newOptions)
NewOption configures the Host construction process; the runtime resources are still owned by Host.
func WithFileLog ¶
WithFileLog gives Host a runtime log session. The log is opened only after the novel-directory lease is taken, and closed once Host has closed all logs. If opening fails the current process logger keeps being used, and the caller must handle that error explicitly through FileLogError.
type OutlineSnapshot ¶
OutlineSnapshot is the display summary of an outline entry.
type ProviderSnapshot ¶
type ProviderSnapshot struct {
Name string
Type string
API string
BaseURL string
Models []bootstrap.ModelConfig
HasAPIKey bool
APIKeyHint string
RequiresAPIKey bool
}
ProviderSnapshot là cấu hình provider đã che API key, để TUI hiển thị.
type UISnapshot ¶
type UISnapshot struct {
Provider string
BookTitle string
ModelName string
ModelContextWindow int // context window of the current default model (resolved live on /model switch)
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
// cumulative usage (whole session, across all agents and model switches)
TotalInputTokens int
TotalOutputTokens int
TotalCacheReadTokens int
TotalCacheWriteTokens int
TotalCostUSD float64
TotalSavedUSD float64 // USD saved thanks to CacheRead hits (relative to billing every input at the non-cached input price)
BudgetLimitUSD float64 // budget cap (config budget.book_usd); 0 = not enabled
// cache diagnostics
OverallCacheCapable bool // at least one role has run a model that supports prompt cache (distinguishes "not enabled" from "0% hit rate")
OverallRecentCacheRead int // sum of cacheRead over the most recent N samples in the sliding window
OverallRecentInput int // sum of input over the most recent N samples in the sliding window
OverallRecentSamples int // number of samples in the sliding window (<= recentSampleCap)
TotalCacheBreaks int // number of cache-chain breaks detected live (the prefix did not shorten while the hit rate dropped), see noteCacheBreak in usage.go
// MissingAssistantUsage > 0 usually means the upstream streaming did not send the final usage
// chunk per the OpenAI stream_options.include_usage protocol (common with self-hosted proxies),
// so the UsageTracker receives no cumulative data at all. The UI tells the user to inspect the backend,
// rather than letting them think the cache module itself is broken.
MissingAssistantUsage int
// cache per-role dimension, sorted by CacheRead descending, with roles that never consumed tokens filtered out
CachePerAgent []AgentCacheStat
CachePerModel []AgentCacheStat
// base settings
Synopsis string
Premise string
Outline []OutlineSnapshot
Characters []string
SupportingCount int // total number of supporting characters recorded for the chapter
RecentSupporting []string // most recently active supporting characters (at most 5, sorted by LastSeenChapter descending)
Layered bool
CurrentVolumeArc string
NextVolumeTitle string
CompassDirection string
CompassScale string
// details
LastCommitSummary string
LastReviewSummary string
LastCheckpointName string
RecentSummaries []string
}
UISnapshot is the aggregate state snapshot the TUI needs for rendering.
type UsageTracker ¶
type UsageTracker struct {
// contains filtered or unexported fields
}
UsageTracker accumulates the LLM input/output tokens and dollar cost of every agent for the whole session.
How it works:
- Record(agentName, msg) is called on every agent OnMessage callback
- agentName maps to a role (architect_* is normalized to architect), then the model currently bound to that role is looked up in ModelSet
- models.DefaultRegistry supplies the model price, multiplied across four items: non-cached input / output / cache read / cache write
- when the model is not in the registry, fall back to msg.Usage.Cost.Total (whatever the provider reported, possibly 0)
- after a hot model switch (/model) later messages are priced with the new model while old messages keep their old cost
It also maintains a per-role dimension (writer/editor/architect):
- cumulative hit data -> the overall optimization effect
- the sliding window of the last N calls -> tells early drag apart from a steady low hit rate
- the CacheCapable flag -> tells "not enabled" apart from "really a 0% hit rate"
Thread-safe.
func NewUsageTracker ¶
func NewUsageTracker(set *bootstrap.ModelSet, store *storepkg.Store) *UsageTracker
func (*UsageTracker) LoadFromStore ¶
func (t *UsageTracker) LoadFromStore() (bool, error)
LoadFromStore reads the persisted snapshot from store.Usage and back-fills it into memory. true means a non-empty (schema matching) state was loaded successfully; false means there is no file or it is unusable, and the caller should keep going with a one-off back-fill from the session replay.
func (*UsageTracker) MissingAssistantUsage ¶
func (t *UsageTracker) MissingAssistantUsage() int
MissingAssistantUsage returns the cumulative count of "an assistant message was received but Usage is nil". Greater than 0 usually means the upstream streaming did not send OpenAI's final usage chunk, and the UI shows a hint instead of letting the user think the cache module itself is broken.
func (*UsageTracker) OverallCacheBreaks ¶
func (t *UsageTracker) OverallCacheBreaks() int
OverallCacheBreaks returns the total number of cache-chain breaks detected live.
func (*UsageTracker) OverallCacheCapable ¶
func (t *UsageTracker) OverallCacheCapable() bool
OverallCacheCapable reports whether the whole run has been through a model known to support cache at least once.
func (*UsageTracker) OverallRecent ¶
func (t *UsageTracker) OverallRecent() (cacheRead, input, samples int)
OverallRecent returns the cacheRead total, the input total and the sample count inside the sliding window (at most recentSampleCap calls).
func (*UsageTracker) PerAgent ¶
func (t *UsageTracker) PerAgent() []AgentUsage
PerAgent returns the cumulative usage per role, sorted by CacheRead descending, skipping roles that never consumed tokens.
func (*UsageTracker) PerModel ¶
func (t *UsageTracker) PerModel() []AgentUsage
PerModel returns the cumulative usage per model, sorted by cost descending and then by input volume descending.
func (*UsageTracker) Record ¶
func (t *UsageTracker) Record(agentName, task string, msg agentcore.AgentMessage)
Record dispatches one agent message onto two paths: accumulation and diagnostics.
Accumulation only looks at whether Usage exists - "which messages carry Usage" is an agentcore/litellm adapter assembly detail (the upstream protocol puts usage at the top level of the response), so if the assembly rules ever change, nothing here has to change. Diagnostics require Role=Assistant and non-empty Content so that AbortMsg / abnormal recovery / tool / user messages do not pollute the missingAssistantUsage counter.
func (*UsageTracker) ReplaySessions ¶
func (t *UsageTracker) ReplaySessions(rootDir string) (int, error)
ReplaySessions scans meta/sessions/agents/*.jsonl, re-accumulates the usage of every assistant message into the tracker, and returns the number of back-filled records.
Call constraint: called exactly once for back-filling, only when meta/usage.json is missing. Regular persistence goes through SaveNow / autoSaveLoop.
The accuracy relies on the three-level fallback described in the sessionRecord comment - the third level (both Usage and _meta missing) only triggers on older logs or upstream anomalies.
func (*UsageTracker) SaveNow ¶
func (t *UsageTracker) SaveNow() error
SaveNow writes the current snapshot to disk immediately. The autoSaveLoop / Close paths both write through it.
func (*UsageTracker) SavedUSD ¶
func (t *UsageTracker) SavedUSD() float64
SavedUSD returns the cumulative dollars saved by cache hits.
func (*UsageTracker) SetOnCost ¶
func (t *UsageTracker) SetOnCost(cb func(total float64))
SetOnCost registers the accounting callback (carrying the latest cumulative cost, called outside the lock). It must be called once during Host construction, before concurrent Record calls start.
func (*UsageTracker) SetOnMissingUsage ¶
func (t *UsageTracker) SetOnMissingUsage(cb func())
SetOnMissingUsage registers the one-shot callback for the first time usage is found missing. It must be called once during Host construction, before concurrent Record calls start.
func (*UsageTracker) Snapshot ¶
func (t *UsageTracker) Snapshot() domain.UsageState
Snapshot copies the current cumulative state into a serializable domain.UsageState. The sliding-window samples do not go into the snapshot - it is a short-term diagnostic window and little of it carries across processes.
func (*UsageTracker) StartAutoSave ¶
func (t *UsageTracker) StartAutoSave(ctx context.Context)
StartAutoSave starts a goroutine that listens on saveCh and writes to disk with a debounce. Before ctx is done it flushes the last unsaved state. Close triggers that flush and the exit by cancelling ctx.
func (*UsageTracker) Totals ¶
func (t *UsageTracker) Totals() (cost float64, input, output, cacheRead, cacheWrite int)
Totals returns a snapshot of the cumulative totals.
func (*UsageTracker) WaitAutoSave ¶
func (t *UsageTracker) WaitAutoSave()
WaitAutoSave waits for the final flush after cancellation. Host.Close calls cancel first and then waits here, so autoSaveLoop does not race the pre-exit SaveNow over the same snapshot.
Source Files
¶
Directories
¶
| Path | Synopsis |
|---|---|
|
Package exp implements the export of completed chapters.
|
Package exp implements the export of completed chapters. |
|
Package imp implements the staged semantic import pipeline for external novels (docs/import-pipeline.md).
|
Package imp implements the staged semantic import pipeline for external novels (docs/import-pipeline.md). |