package eino import ( "context" "github.com/cloudwego/eino/compose" ) // CheckpointKV 是 compose checkpoint 的最小持久化后端:朴素的键值 + 软缺失语义。 // 生产由 bus 的 JetStream KV(*bus.KVHandle)实现(结构化满足,无需反向依赖 bus); // 单测用内存桩。键 = checkPointID(dispatcher 取 task_id),值 = compose 序列化的图状态。 type CheckpointKV interface { Get(ctx context.Context, key string) (val []byte, ok bool, err error) Put(ctx context.Context, key string, val []byte) error Delete(ctx context.Context, key string) error } // checkpointStore 把 CheckpointKV 适配成 Eino compose.CheckPointStore(Get/Set), // 并实现可选的 CheckPointDeleter(Delete)——审批恢复 / 终态后显式删 checkpoint, // 避免 KV 堆积;桶级 TTL 再兜底清理被遗弃的中断(审批人始终不处理)。 // // 中断模型:审批节点 compose.Interrupt 时,compose 把整图状态写进本 store(key=task_id); // dispatcher 据此置 waiting 并返回(释放 goroutine)。决定到达后以同 key 重入图 → 从断点恢复。 type checkpointStore struct{ kv CheckpointKV } func newCheckpointStore(kv CheckpointKV) *checkpointStore { return &checkpointStore{kv: kv} } // Get 读 checkpoint;不存在返回 (nil,false,nil),由 compose 视作"无断点、全新执行"。 func (s *checkpointStore) Get(ctx context.Context, checkPointID string) ([]byte, bool, error) { return s.kv.Get(ctx, checkPointID) } // Set 持久化一次中断的图状态。 func (s *checkpointStore) Set(ctx context.Context, checkPointID string, checkPoint []byte) error { return s.kv.Put(ctx, checkPointID, checkPoint) } // Delete 显式清理 checkpoint(实现 compose 的可选 CheckPointDeleter,结构化匹配)。 func (s *checkpointStore) Delete(ctx context.Context, checkPointID string) error { return s.kv.Delete(ctx, checkPointID) } // 编译期确认实现了 compose.CheckPointStore(Get/Set)。Delete 经结构化断言由运行时识别。 var _ compose.CheckPointStore = (*checkpointStore)(nil)