control_legacy_state_compat/
control_legacy_state_compat.rs1#[path = "support/utils.rs"]
2mod _utils;
3
4use _utils::{boxed_error, cleanup_run, create_client, new_run_id, print_summary, require};
5use mubit_sdk::TransportMode;
6use serde_json::{json, Value};
7use std::error::Error;
8use std::time::Instant;
9
10#[tokio::main(flavor = "current_thread")]
11async fn main() -> Result<(), Box<dyn Error>> {
12 let name = "control_legacy_state_compat";
13 let started = Instant::now();
14 let client = create_client().await?;
15 let run_id = new_run_id("control_legacy_state_compat");
16 let linked_run_id = new_run_id("control_legacy_state_linked");
17 client.set_run_id(Some(run_id.clone()));
18 client.set_transport(TransportMode::Http);
19
20 let mut passed = true;
21 let mut detail = "validated legacy state compatibility APIs".to_string();
22 let mut metrics = json!({});
23
24 let scenario = async {
25 let set_var = client.control.set_variable(json!({"run_id": run_id, "name": "claim_status", "value_json": json!({"value": "triage"}).to_string(), "source": "explicit"})).await?;
26 let get_var = client.control.get_variable(json!({"run_id": run_id, "name": "claim_status"})).await?;
27 let list_vars = client.control.list_variables(json!({"run_id": run_id})).await?;
28 let delete_var = client.control.delete_variable(json!({"run_id": run_id, "name": "claim_status"})).await?;
29
30 let define_concept = client.control.define_concept(json!({"run_id": run_id, "name": "claim", "schema_json": json!({"type": "object", "properties": {"status": {"type": "string"}}}).to_string()})).await?;
31 let list_concepts = client.control.list_concepts(json!({"run_id": run_id})).await?;
32
33 let add_goal = client.control.add_goal(json!({"run_id": run_id, "description": "Resolve claim", "priority": "high"})).await?;
34 let goal_id = add_goal.get("id").and_then(Value::as_str).ok_or_else(|| boxed_error(format!("add_goal failed: {add_goal}")))?.to_string();
35 let child_goal = client.control.add_goal(json!({
36 "run_id": run_id,
37 "description": "Verify receipts",
38 "priority": "medium",
39 "parent_goal_id": goal_id,
40 })).await?;
41 let update_goal = client.control.update_goal(json!({"run_id": run_id, "goal_id": goal_id, "status": "suspended"})).await?;
42 let list_goals = client.control.list_goals(json!({"run_id": run_id})).await?;
43 let goal_tree = client.control.get_goal_tree(json!({"run_id": run_id, "root_goal_id": goal_id})).await?;
44
45 let submit_action = client.control.submit_action(json!({"run_id": run_id, "agent_id": "planner", "action_type": "note", "action_json": json!({"step": "inspect facts"}).to_string()})).await?;
46 let action_log = client.control.get_action_log(json!({"run_id": run_id, "limit": 10})).await?;
47 let run_cycle = client.control.run_cycle(json!({"run_id": run_id, "agent_id": "planner", "candidates": [{"action_type": "inspect", "action_json": json!({"target": "claim facts"}).to_string(), "score": 0.9, "rationale": "highest confidence"}]})).await?;
48 let cycle_history = client.control.get_cycle_history(json!({"run_id": run_id, "limit": 10})).await?;
49 let link_run = client.control.link_run(json!({"run_id": run_id, "linked_run_id": linked_run_id})).await?;
50 let unlink_run = client.control.unlink_run(json!({"run_id": run_id, "linked_run_id": linked_run_id})).await?;
51
52 require(set_var.get("success").and_then(Value::as_bool).unwrap_or(false), format!("set_variable failed: {set_var}"))?;
53 require(get_var.get("name").and_then(Value::as_str) == Some("claim_status"), format!("get_variable failed: {get_var}"))?;
54 require(list_vars.get("variables").and_then(Value::as_array).map(|items| items.iter().any(|item| item.get("name").and_then(Value::as_str) == Some("claim_status"))).unwrap_or(false), format!("list_variables failed: {list_vars}"))?;
55 require(delete_var.get("success").and_then(Value::as_bool).unwrap_or(false), format!("delete_variable failed: {delete_var}"))?;
56 require(define_concept.get("success").and_then(Value::as_bool).unwrap_or(false), format!("define_concept failed: {define_concept}"))?;
57 require(list_concepts.get("concepts").and_then(Value::as_array).map(|items| items.iter().any(|item| item.get("name").and_then(Value::as_str) == Some("claim"))).unwrap_or(false), format!("list_concepts failed: {list_concepts}"))?;
58 require(child_goal.get("id").and_then(Value::as_str).is_some(), format!("child add_goal failed: {child_goal}"))?;
59 require(update_goal.get("success").and_then(Value::as_bool).unwrap_or(false), format!("update_goal failed: {update_goal}"))?;
60 require(list_goals.get("goals").and_then(Value::as_array).map(|items| items.iter().any(|item| item.get("id").and_then(Value::as_str) == Some(goal_id.as_str()))).unwrap_or(false), format!("list_goals failed: {list_goals}"))?;
61 require(
62 goal_tree.get("root").is_some()
63 || goal_tree.get("nodes").is_some()
64 || goal_tree.get("goals").and_then(Value::as_array).is_some(),
65 format!("goal_tree failed: {goal_tree}"),
66 )?;
67 require(submit_action.get("success").and_then(Value::as_bool).unwrap_or(false), format!("submit_action failed: {submit_action}"))?;
68 require(action_log.get("entries").and_then(Value::as_array).is_some(), format!("action_log failed: {action_log}"))?;
69 let cycle_number_valid = run_cycle.get("cycle_number").and_then(Value::as_u64).is_some()
70 || run_cycle
71 .get("cycle_number")
72 .and_then(Value::as_str)
73 .map(|value| value.chars().all(|ch| ch.is_ascii_digit()))
74 .unwrap_or(false);
75 require(cycle_number_valid, format!("run_cycle failed: {run_cycle}"))?;
76 require(cycle_history.get("cycles").and_then(Value::as_array).is_some(), format!("cycle_history failed: {cycle_history}"))?;
77 require(link_run.get("success").and_then(Value::as_bool).unwrap_or(false), format!("link_run failed: {link_run}"))?;
78 require(unlink_run.get("success").and_then(Value::as_bool).unwrap_or(false), format!("unlink_run failed: {unlink_run}"))?;
79
80 metrics = json!({
81 "run_id": run_id,
82 "goal_id": goal_id,
83 "action_id": submit_action.get("action_id").cloned().unwrap_or(Value::Null),
84 "cycle_number": run_cycle.get("cycle_number").cloned().unwrap_or(Value::Null),
85 });
86 Ok::<(), Box<dyn Error>>(())
87 }
88 .await;
89
90 if let Err(err) = scenario {
91 passed = false;
92 detail = err.to_string();
93 }
94
95 let cleanup_ok = cleanup_run(&client, &run_id).await;
96 if !cleanup_ok {
97 passed = false;
98 detail = format!("{detail} | cleanup failures");
99 }
100
101 print_summary(name, passed, &detail, &metrics, started.elapsed().as_secs_f64(), cleanup_ok);
102
103 if passed { Ok(()) } else { Err(boxed_error(detail)) }
104}