Skip to main content

vasari_core/schema/
plan.rs

1use serde::{Deserialize, Serialize};
2use serde_json::json;
3
4use super::NodeId;
5use crate::hash::node_id;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct Plan {
9    pub id: NodeId,
10    pub intent_ids: Vec<NodeId>,
11    pub steps: Vec<PlanStep>,
12    pub parent_ids: Vec<NodeId>,
13    #[serde(default = "default_schema_version")]
14    pub schema_version: String,
15}
16
17fn default_schema_version() -> String {
18    "1".to_string()
19}
20
21/// One step in a plan. Steps are sub-records of Plan, not standalone nodes.
22/// Actions reference steps via (plan_id, step_index).
23#[derive(Debug, Clone, Serialize, Deserialize)]
24pub struct PlanStep {
25    pub goal: String,
26    pub constraints: Vec<String>,
27}
28
29impl Plan {
30    pub fn new(intent_ids: Vec<NodeId>, steps: Vec<PlanStep>, parent_ids: Vec<NodeId>) -> Self {
31        let id = NodeId(node_id(&Self::hash_input(&intent_ids, &steps, &parent_ids)));
32        Self {
33            id,
34            intent_ids,
35            steps,
36            parent_ids,
37            schema_version: default_schema_version(),
38        }
39    }
40
41    fn hash_input(
42        intent_ids: &[NodeId],
43        steps: &[PlanStep],
44        parent_ids: &[NodeId],
45    ) -> serde_json::Value {
46        json!({
47            "type": "plan",
48            "intent_ids": intent_ids.iter().map(|id| id.as_str()).collect::<Vec<_>>(),
49            "steps": steps.iter().map(|s| json!({
50                "goal": s.goal,
51                "constraints": s.constraints,
52            })).collect::<Vec<_>>(),
53            "parent_ids": parent_ids.iter().map(|id| id.as_str()).collect::<Vec<_>>(),
54        })
55    }
56}