Files
AutoZero/session/checkpoint.go
T
Sakurasan d5dac5a6fc feat: AutoZero 通用 Agent 框架(从 AutoGo 五阶段拆分完成)
llm(三协议 Provider)/ session(JSONL 持久化)/ tools(Registry、围栏、
builtin、computer)/ cdp(browser)/ skills / mcp / agent(循环、两级压缩、
编排、审批门控)+ 底座 jsonl/textx/execx/diag/scratch/spill/imagecache。

产品装配代码(config 桥接、schedule 工具、memory/plan/retro/prompt)
留在 AutoGo,宿主接入方式见 MIGRATION.md。
2026-10-26 00:54:46 +08:00

72 lines
2.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
package session
import (
"crypto/sha256"
"encoding/hex"
"fmt"
"os"
"path/filepath"
"time"
"git.gopher.ink/mirrors2/AutoZero/llm"
)
// Checkpoint 是一次上下文压缩留下的交接文档,以及它覆盖到原 transcript 的哪个位置。
//
// 它值得落盘:压缩本身只改视图,但 WebUI 每个回合都会新建 Agent。没有 sidecar,
// 新回合又要把整段历史重新摘要一遍;有了它,新回合直接从 checkpoint + 未覆盖的
// 新消息开始。Covered/TailHash 是失效保护——历史被回退或改写后,指纹对不上就
// 当作没有 checkpoint,绝不拿一份覆盖了不同消息的旧摘要继续跑。
type Checkpoint struct {
Text string `json:"text"`
Covered int `json:"covered"` // 已纳入 checkpoint 的消息条数(transcript 前缀)
TailHash string `json:"tail_hash"` // 第 Covered 条消息的指纹
UpdatedAt int64 `json:"updated_at"`
}
// CheckpointPath 是压缩交接文档的 sidecar 路径(与 .title / .run.json 同目录)。
func CheckpointPath(id string) string {
return filepath.Join(Dir(), id+".checkpoint.json")
}
// LoadCheckpoint 读取 checkpoint;缺失或损坏返回 false。
func LoadCheckpoint(id string) (Checkpoint, bool) {
if _, ok := SafeID(id); !ok {
return Checkpoint{}, false
}
var cp Checkpoint
if err := LoadState(CheckpointPath(id), &cp); err != nil {
return Checkpoint{}, false
}
return cp, cp.Text != ""
}
// SaveCheckpoint 原子写 checkpoint。
func SaveCheckpoint(id string, cp Checkpoint) error {
if _, ok := SafeID(id); !ok {
return os.ErrInvalid
}
if cp.UpdatedAt == 0 {
cp.UpdatedAt = time.Now().UnixMilli()
}
return SaveState(CheckpointPath(id), cp)
}
// RemoveCheckpoint 删除 checkpoint sidecar(会话删除时用)。
func RemoveCheckpoint(id string) {
if _, ok := SafeID(id); ok {
_ = os.Remove(CheckpointPath(id))
}
}
// MessageFingerprint 是一条消息的稳定指纹,用于识别 checkpoint 的覆盖边界。
// 只取会进模型视野的字段(role/content/tool call),不含本地 trace。
func MessageFingerprint(m llm.Message) string {
h := sha256.New()
fmt.Fprintf(h, "%s\x00%s\x00%s\x00", m.Role, m.Content, m.ToolCallID)
for _, tc := range m.ToolCalls {
fmt.Fprintf(h, "%s\x00%s\x00%s\x00", tc.ID, tc.Name, tc.Input)
}
return hex.EncodeToString(h.Sum(nil))
}