use crate::agent::swarm::knowledge::SharedKnowledge;
use crate::agent::swarm::knowledge::types::{
BlackboardKind, KnowledgeSnapshot, SnapshotAnnouncement, SnapshotBlackboard, SnapshotFact,
SnapshotFileRead,
};
impl SharedKnowledge {
pub async fn snapshot(&self) -> KnowledgeSnapshot {
let inner = self.inner.read().await;
let facts = inner
.facts
.values()
.map(|f| SnapshotFact {
agent_id: f.agent_id.clone(),
topic: f.topic.clone(),
content: f.content.clone(),
})
.collect();
let files_read = inner
.files_read
.values()
.map(|f| SnapshotFileRead {
agent_id: f.agent_id.clone(),
path: f.path.clone(),
summary: f.summary.clone(),
line_count: f.line_count,
})
.collect();
let announcements = inner
.announcements
.iter()
.map(|a| SnapshotAnnouncement {
agent_id: a.agent_id.clone(),
message: a.message.clone(),
})
.collect();
let blackboard = inner
.blackboard
.values()
.map(|b| SnapshotBlackboard {
key: b.key.clone(),
value: b.value.clone(),
author: b.author.clone(),
kind: format!("{:?}", b.kind),
votes_for: b.votes_for.clone(),
votes_against: b.votes_against.clone(),
})
.collect();
KnowledgeSnapshot {
facts,
files_read,
announcements,
blackboard,
}
}
pub async fn restore(&self, snapshot: KnowledgeSnapshot) {
for fact in snapshot.facts {
self.post_fact(&fact.agent_id, &fact.topic, &fact.content)
.await;
}
for file in snapshot.files_read {
self.record_file_read(&file.agent_id, &file.path, &file.summary, file.line_count)
.await;
}
for ann in snapshot.announcements {
self.announce(&ann.agent_id, &ann.message).await;
}
for bb in snapshot.blackboard {
let kind = match bb.kind.as_str() {
"Proposal" => BlackboardKind::Proposal,
"Decision" => BlackboardKind::Decision,
"Status" => BlackboardKind::Status,
"Claim" => BlackboardKind::Claim,
_ => BlackboardKind::Status,
};
self.post_to_blackboard(&bb.key, &bb.value, &bb.author, kind)
.await;
let mut inner = self.inner.write().await;
if let Some(entry) = inner.blackboard.get_mut(&bb.key) {
entry.votes_for = bb.votes_for;
entry.votes_against = bb.votes_against;
}
}
}
pub async fn save_to_file(&self, path: &std::path::Path) -> std::io::Result<()> {
let snapshot = self.snapshot().await;
let json = serde_json::to_string_pretty(&snapshot).map_err(std::io::Error::other)?;
tokio::fs::write(path, json).await
}
pub async fn load_from_file(&self, path: &std::path::Path) -> std::io::Result<()> {
let json = tokio::fs::read_to_string(path).await?;
let snapshot: KnowledgeSnapshot =
serde_json::from_str(&json).map_err(std::io::Error::other)?;
self.restore(snapshot).await;
Ok(())
}
}