feat(pipeline): Pipeline 图持久化 — GraphStore 实现

新增 GraphStore trait 和 MemoryGraphStore 实现:
- save/load/delete/list_ids 异步接口
- 可选文件持久化到 JSON 目录
- 启动时从磁盘加载已保存的图

SkillOrchestrationDriver 集成:
- 新增 with_graph_store() 构造函数
- graph_id 路径从硬编码错误改为从 GraphStore 查找
- 无 store 时返回明确的错误信息

修复了 "Graph loading by ID not yet implemented" 的 TODO
This commit is contained in:
iven
2026-03-30 00:25:38 +08:00
parent f3f586efef
commit eed26a1ce4
3 changed files with 150 additions and 3 deletions

View File

@@ -13,12 +13,22 @@ use super::OrchestrationActionDriver;
pub struct SkillOrchestrationDriver {
/// Skill registry for executing skills
skill_registry: Arc<zclaw_skills::SkillRegistry>,
/// Graph store for persisting/loading graphs by ID
graph_store: Option<Arc<dyn zclaw_skills::orchestration::GraphStore>>,
}
impl SkillOrchestrationDriver {
/// Create a new orchestration driver
pub fn new(skill_registry: Arc<zclaw_skills::SkillRegistry>) -> Self {
Self { skill_registry }
Self { skill_registry, graph_store: None }
}
/// Create with graph persistence
pub fn with_graph_store(
skill_registry: Arc<zclaw_skills::SkillRegistry>,
graph_store: Arc<dyn zclaw_skills::orchestration::GraphStore>,
) -> Self {
Self { skill_registry, graph_store: Some(graph_store) }
}
}
@@ -38,8 +48,11 @@ impl OrchestrationActionDriver for SkillOrchestrationDriver {
serde_json::from_value::<SkillGraph>(graph_value.clone())
.map_err(|e| format!("Failed to parse graph: {}", e))?
} else if let Some(id) = graph_id {
// Load graph from registry (TODO: implement graph storage)
return Err(format!("Graph loading by ID not yet implemented: {}", id));
// Load graph from store
self.graph_store.as_ref()
.ok_or_else(|| "Graph store not configured. Cannot resolve graph_id.".to_string())?
.load(id).await
.ok_or_else(|| format!("Graph not found: {}", id))?
} else {
return Err("Either graph_id or graph must be provided".to_string());
};