package eino import ( "encoding/json" "github.com/cloudwego/eino/schema" ) // board 的字段全是未导出的,而 Eino 的 checkpoint 序列化器只认导出字段——若直接让 compose // 持久化 board,会落成空、resume 丢全部执行态。Eino 对「同时实现 json.Marshaler+Unmarshaler」 // 的类型改走自定义 JSON(见 internal/serialization checkMarshaler),故给 *board 实现一对 JSON // 方法、映射到导出 DTO,即可把整个黑板按需持久化,而无需把 board 字段全导出(牵连几十处调用点)。 // // 不持久化 fatalErr(error,transient——中断点处必为 nil):审批中断时图尚未失败, // 它是单次 Invoke 内的致命错标志,跨 resume 无意义。rejected 同理在中断点为 false, // 但仍带上以求快照完整、零歧义。 type boardSnapshot struct { UID string `json:"uid,omitempty"` SID string `json:"sid,omitempty"` Query string `json:"query,omitempty"` UseVoice bool `json:"use_voice,omitempty"` Profile string `json:"profile,omitempty"` History []*schema.Message `json:"history,omitempty"` KB string `json:"kb,omitempty"` Refs []string `json:"refs,omitempty"` ToolOut []string `json:"tool_out,omitempty"` Sections []reportSection `json:"sections,omitempty"` Answer string `json:"answer,omitempty"` AgentOut []string `json:"agent_out,omitempty"` Rejected bool `json:"rejected,omitempty"` } // MarshalJSON 把黑板序列化为快照(Eino checkpoint 经此持久化整图执行态)。 func (b *board) MarshalJSON() ([]byte, error) { return json.Marshal(boardSnapshot{ UID: b.uid, SID: b.sid, Query: b.query, UseVoice: b.useVoice, Profile: b.profile, History: b.history, KB: b.kb, Refs: b.refs, ToolOut: b.toolOut, Sections: b.sections, Answer: b.answer, AgentOut: b.agentOut, Rejected: b.rejected, }) } // UnmarshalJSON 从快照还原黑板(resume 时 Eino 据此重建中断前的执行态)。 func (b *board) UnmarshalJSON(data []byte) error { var s boardSnapshot if err := json.Unmarshal(data, &s); err != nil { return err } b.uid = s.UID b.sid = s.SID b.query = s.Query b.useVoice = s.UseVoice b.profile = s.Profile b.history = s.History b.kb = s.KB b.refs = s.Refs b.toolOut = s.ToolOut b.sections = s.Sections b.answer = s.Answer b.agentOut = s.AgentOut b.rejected = s.Rejected return nil } // 注册 *board 的序列化类型名:Eino checkpoint 的 State 是 any,持久化时记类型名、 // resume 时据名还原具体类型再走 UnmarshalJSON。名字一经上线不可改(旧 checkpoint 据此解码)。 func init() { schema.RegisterName[*board]("sundynix_board") }