pub struct CheckpointOptions {
pub run_id: Option<String>,
pub label: Option<String>,
pub context_snapshot: String,
pub metadata: Option<Value>,
pub user_id: Option<String>,
pub agent_id: Option<String>,
}Fields§
§run_id: Option<String>§label: Option<String>§context_snapshot: String§metadata: Option<Value>§user_id: Option<String>§agent_id: Option<String>Implementations§
Source§impl CheckpointOptions
impl CheckpointOptions
Sourcepub fn new(context_snapshot: impl Into<String>) -> Self
pub fn new(context_snapshot: impl Into<String>) -> Self
Examples found in repository?
examples/helper_mas_learning_loop.rs (lines 46-48)
14async fn main() -> Result<(), Box<dyn Error>> {
15 let name = "helper_mas_learning_loop";
16 let started = Instant::now();
17 let client = create_client().await?;
18 let run_id = new_run_id("helper_mas_learning_loop");
19 client.set_run_id(Some(run_id.clone()));
20 client.set_transport(TransportMode::Http);
21
22 let mut passed = true;
23 let mut detail = "validated helper MAS checkpoint/outcome/strategies flow".to_string();
24 let mut metrics = json!({});
25
26 let scenario = async {
27 let mut register = RegisterAgentOptions::new("planner");
28 register.run_id = Some(run_id.clone());
29 register.role = "planner".to_string();
30 register.read_scopes = vec!["rule".to_string(), "lesson".to_string(), "fact".to_string()];
31 register.write_scopes = vec!["lesson".to_string(), "trace".to_string()];
32 register.shared_memory_lanes = vec!["knowledge".to_string(), "history".to_string()];
33 client.register_agent(register).await?;
34
35 let mut remember = RememberOptions::new(
36 "If a retry succeeds after token signer rotation, record it as a reusable recovery pattern.",
37 );
38 remember.run_id = Some(run_id.clone());
39 remember.agent_id = Some("planner".to_string());
40 remember.intent = Some("lesson".to_string());
41 remember.lesson_type = Some("success".to_string());
42 remember.lesson_scope = Some("session".to_string());
43 remember.lesson_importance = Some("high".to_string());
44 client.remember(remember).await?;
45
46 let mut checkpoint = CheckpointOptions::new(
47 "Planner isolated the recovery path to token signer rotation.",
48 );
49 checkpoint.run_id = Some(run_id.clone());
50 checkpoint.label = Some("pre-compaction-1".to_string());
51 checkpoint.metadata = Some(json!({ "stage": "analysis" }));
52 checkpoint.agent_id = Some("planner".to_string());
53 let checkpoint_response = client.checkpoint(checkpoint).await?;
54
55 let mut list_agents = ListAgentsOptions::default();
56 list_agents.run_id = Some(run_id.clone());
57 let agents = client.list_agents(list_agents).await?;
58
59 let lessons = client.control.lessons(json!({ "run_id": run_id, "limit": 10 })).await?;
60 let lesson_id = lessons
61 .get("lessons")
62 .and_then(|value| value.as_array())
63 .and_then(|items| items.first())
64 .and_then(|item| item.get("id"))
65 .and_then(|value| value.as_str())
66 .ok_or_else(|| boxed_error(format!("expected at least one lesson to record outcome against: {lessons}")))?
67 .to_string();
68
69 let mut outcome = RecordOutcomeOptions::new(lesson_id, "success");
70 outcome.run_id = Some(run_id.clone());
71 outcome.signal = 0.75;
72 outcome.rationale = "Recovery succeeded after following the stored lesson.".to_string();
73 outcome.agent_id = Some("planner".to_string());
74 let outcome_response = client.record_outcome(outcome).await?;
75
76 let mut strategies = SurfaceStrategiesOptions::default();
77 strategies.run_id = Some(run_id.clone());
78 strategies.lesson_types = vec!["success".to_string(), "failure".to_string()];
79 strategies.max_strategies = 5;
80 let strategy_response = client.surface_strategies(strategies).await?;
81
82 require(
83 checkpoint_response
84 .get("success")
85 .and_then(|value| value.as_bool())
86 .unwrap_or(false),
87 format!("checkpoint failed: {checkpoint_response}"),
88 )?;
89 let agent_count = agents
90 .get("agents")
91 .and_then(|value| value.as_array())
92 .map(|items| items.len())
93 .unwrap_or(0);
94 require(agent_count == 1, format!("agent registration missing: {agents}"))?;
95 require(
96 outcome_response
97 .get("success")
98 .and_then(|value| value.as_bool())
99 .unwrap_or(false),
100 format!("record_outcome failed: {outcome_response}"),
101 )?;
102 let strategy_count = strategy_response
103 .get("strategies")
104 .and_then(|value| value.as_array())
105 .map(|items| items.len())
106 .unwrap_or(0);
107
108 metrics = json!({
109 "run_id": run_id,
110 "checkpoint_id": checkpoint_response.get("checkpoint_id").cloned().unwrap_or(serde_json::Value::Null),
111 "agent_count": agent_count,
112 "strategy_count": strategy_count,
113 });
114
115 Ok::<(), Box<dyn Error>>(())
116 }
117 .await;
118
119 if let Err(err) = scenario {
120 passed = false;
121 detail = err.to_string();
122 }
123
124 let cleanup_ok = cleanup_run(&client, &run_id).await;
125 if !cleanup_ok {
126 passed = false;
127 detail = format!("{detail} | cleanup failures");
128 }
129
130 print_summary(
131 name,
132 passed,
133 &detail,
134 &metrics,
135 started.elapsed().as_secs_f64(),
136 cleanup_ok,
137 );
138
139 if passed {
140 Ok(())
141 } else {
142 Err(boxed_error(detail))
143 }
144}More examples
examples/public/03_checkpoint_reflect_outcome.rs (lines 46-48)
14async fn main() -> Result<(), Box<dyn Error>> {
15 let name = "public_03_checkpoint_reflect_outcome";
16 let started = Instant::now();
17 let client = create_client().await?;
18 let run_id = new_run_id("public_03_checkpoint_reflect_outcome");
19 client.set_run_id(Some(run_id.clone()));
20 client.set_transport(TransportMode::Http);
21
22 let mut passed = true;
23 let mut detail = "validated helper MAS checkpoint/outcome/strategies flow".to_string();
24 let mut metrics = json!({});
25
26 let scenario = async {
27 let mut register = RegisterAgentOptions::new("planner");
28 register.run_id = Some(run_id.clone());
29 register.role = "planner".to_string();
30 register.read_scopes = vec!["rule".to_string(), "lesson".to_string(), "fact".to_string()];
31 register.write_scopes = vec!["lesson".to_string(), "trace".to_string()];
32 register.shared_memory_lanes = vec!["knowledge".to_string(), "history".to_string()];
33 client.register_agent(register).await?;
34
35 let mut remember = RememberOptions::new(
36 "If a retry succeeds after token signer rotation, record it as a reusable recovery pattern.",
37 );
38 remember.run_id = Some(run_id.clone());
39 remember.agent_id = Some("planner".to_string());
40 remember.intent = Some("lesson".to_string());
41 remember.lesson_type = Some("success".to_string());
42 remember.lesson_scope = Some("session".to_string());
43 remember.lesson_importance = Some("high".to_string());
44 client.remember(remember).await?;
45
46 let mut checkpoint = CheckpointOptions::new(
47 "Planner isolated the recovery path to token signer rotation.",
48 );
49 checkpoint.run_id = Some(run_id.clone());
50 checkpoint.label = Some("pre-compaction-1".to_string());
51 checkpoint.metadata = Some(json!({ "stage": "analysis" }));
52 checkpoint.agent_id = Some("planner".to_string());
53 let checkpoint_response = client.checkpoint(checkpoint).await?;
54
55 let mut list_agents = ListAgentsOptions::default();
56 list_agents.run_id = Some(run_id.clone());
57 let agents = client.list_agents(list_agents).await?;
58
59 let lessons = client.control.lessons(json!({ "run_id": run_id, "limit": 10 })).await?;
60 let lesson_id = lessons
61 .get("lessons")
62 .and_then(|value| value.as_array())
63 .and_then(|items| items.first())
64 .and_then(|item| item.get("id"))
65 .and_then(|value| value.as_str())
66 .ok_or_else(|| boxed_error(format!("expected at least one lesson to record outcome against: {lessons}")))?
67 .to_string();
68
69 let mut outcome = RecordOutcomeOptions::new(lesson_id, "success");
70 outcome.run_id = Some(run_id.clone());
71 outcome.signal = 0.75;
72 outcome.rationale = "Recovery succeeded after following the stored lesson.".to_string();
73 outcome.agent_id = Some("planner".to_string());
74 let outcome_response = client.record_outcome(outcome).await?;
75
76 let mut strategies = SurfaceStrategiesOptions::default();
77 strategies.run_id = Some(run_id.clone());
78 strategies.lesson_types = vec!["success".to_string(), "failure".to_string()];
79 strategies.max_strategies = 5;
80 let strategy_response = client.surface_strategies(strategies).await?;
81
82 require(
83 checkpoint_response
84 .get("success")
85 .and_then(|value| value.as_bool())
86 .unwrap_or(false),
87 format!("checkpoint failed: {checkpoint_response}"),
88 )?;
89 let agent_count = agents
90 .get("agents")
91 .and_then(|value| value.as_array())
92 .map(|items| items.len())
93 .unwrap_or(0);
94 require(agent_count == 1, format!("agent registration missing: {agents}"))?;
95 require(
96 outcome_response
97 .get("success")
98 .and_then(|value| value.as_bool())
99 .unwrap_or(false),
100 format!("record_outcome failed: {outcome_response}"),
101 )?;
102 let strategy_count = strategy_response
103 .get("strategies")
104 .and_then(|value| value.as_array())
105 .map(|items| items.len())
106 .unwrap_or(0);
107
108 metrics = json!({
109 "run_id": run_id,
110 "checkpoint_id": checkpoint_response.get("checkpoint_id").cloned().unwrap_or(serde_json::Value::Null),
111 "agent_count": agent_count,
112 "strategy_count": strategy_count,
113 });
114
115 Ok::<(), Box<dyn Error>>(())
116 }
117 .await;
118
119 if let Err(err) = scenario {
120 passed = false;
121 detail = err.to_string();
122 }
123
124 let cleanup_ok = cleanup_run(&client, &run_id).await;
125 if !cleanup_ok {
126 passed = false;
127 detail = format!("{detail} | cleanup failures");
128 }
129
130 print_summary(
131 name,
132 passed,
133 &detail,
134 &metrics,
135 started.elapsed().as_secs_f64(),
136 cleanup_ok,
137 );
138
139 if passed {
140 Ok(())
141 } else {
142 Err(boxed_error(detail))
143 }
144}examples/public/08_multi_agent_claims_or_support_flow.rs (line 56)
11async fn main() -> Result<(), Box<dyn Error>> {
12 let name = "public_08_multi_agent_claims_or_support_flow";
13 let started = Instant::now();
14 let client = create_client().await?;
15 let run_id = new_run_id("public_claims_flow");
16 client.set_run_id(Some(run_id.clone()));
17 client.set_transport(TransportMode::Http);
18
19 let mut passed = true;
20 let mut detail = "validated multi-agent claims/support flow".to_string();
21 let mut metrics = json!({});
22
23 let scenario = async {
24 for (agent_id, role, read_scopes, write_scopes) in [
25 ("intake", "intake", vec!["fact", "archive_block"], vec!["fact", "archive_block", "trace"]),
26 ("coverage", "coverage", vec!["fact", "rule", "archive_block", "handoff", "feedback"], vec!["fact", "trace", "lesson"]),
27 ("reviewer", "reviewer", vec!["fact", "archive_block", "handoff", "feedback", "rule"], vec!["feedback", "rule"]),
28 ] {
29 let mut agent = RegisterAgentOptions::new(agent_id);
30 agent.run_id = Some(run_id.clone());
31 agent.role = role.to_string();
32 agent.read_scopes = read_scopes.into_iter().map(String::from).collect();
33 agent.write_scopes = write_scopes.into_iter().map(String::from).collect();
34 agent.shared_memory_lanes = vec!["knowledge".into(), "history".into()];
35 client.register_agent(agent).await?;
36 }
37
38 let mut fact = RememberOptions::new("Policy P-8842 covers windshield damage with a 250 GBP deductible.");
39 fact.run_id = Some(run_id.clone());
40 fact.agent_id = Some("intake".into());
41 fact.intent = Some("fact".into());
42 fact.metadata = Some(json!({"claim_id": "CLM-8842", "source": "intake-form"}));
43 client.remember(fact).await?;
44
45 let mut archive = ArchiveOptions::new("Exact adjuster note: customer confirmed the damage happened on the motorway and no third party was involved.", "adjuster_note");
46 archive.run_id = Some(run_id.clone());
47 archive.agent_id = Some("intake".into());
48 archive.origin_agent_id = Some("intake".into());
49 archive.source_attempt_id = Some("attempt-1".into());
50 archive.source_tool = Some("claim-review".into());
51 archive.labels = vec!["claims".into(), "coverage".into()];
52 archive.family = Some("windshield".into());
53 let archived = client.archive(archive).await?;
54 let reference_id = archived.get("reference_id").and_then(|v| v.as_str()).ok_or_else(|| boxed_error(format!("archive reference missing: {archived}")))?.to_string();
55
56 let mut checkpoint = CheckpointOptions::new("Coverage verified deductible and adjuster note before escalation.");
57 checkpoint.run_id = Some(run_id.clone());
58 checkpoint.label = Some("pre-review".into());
59 checkpoint.agent_id = Some("coverage".into());
60 checkpoint.metadata = Some(json!({"claim_id": "CLM-8842"}));
61 let checkpoint_response = client.checkpoint(checkpoint).await?;
62
63 let mut handoff = HandoffOptions::new("claim-8842", "coverage", "reviewer", "Review whether the adjuster note is enough to approve the claim.");
64 handoff.run_id = Some(run_id.clone());
65 handoff.requested_action = "review".into();
66 handoff.metadata = Some(json!({"claim_id": "CLM-8842"}));
67 let handoff_response = client.handoff(handoff).await?;
68 let handoff_id = handoff_response.get("handoff_id").and_then(|v| v.as_str()).ok_or_else(|| boxed_error(format!("handoff id missing: {handoff_response}")))?.to_string();
69
70 let mut feedback = FeedbackOptions::new(handoff_id.clone(), "approve");
71 feedback.run_id = Some(run_id.clone());
72 feedback.from_agent_id = Some("reviewer".into());
73 feedback.comments = "Deductible and adjuster note are sufficient for routing.".into();
74 feedback.metadata = Some(json!({"claim_id": "CLM-8842"}));
75 let feedback_response = client.feedback(feedback).await?;
76
77 let mut context_opts = GetContextOptions::default();
78 context_opts.run_id = Some(run_id.clone());
79 context_opts.query = Some("Prepare the final claims routing summary.".into());
80 context_opts.agent_id = Some("coverage".into());
81 context_opts.sections = vec!["archive".into(), "facts".into(), "handoffs".into(), "feedback".into()];
82 context_opts.mode = Some("sections".into());
83 let context = client.get_context(context_opts).await?;
84
85 let mut dereference = DereferenceOptions::new(reference_id.clone());
86 dereference.run_id = Some(run_id.clone());
87 dereference.agent_id = Some("coverage".into());
88 let exact = client.dereference(dereference).await?;
89
90 let mut recall = RecallOptions::new("What deductible applies and what did the adjuster confirm?");
91 recall.run_id = Some(run_id.clone());
92 recall.agent_id = Some("coverage".into());
93 recall.entry_types = vec!["fact".into(), "archive_block".into(), "feedback".into()];
94 let recall_response = client.recall(recall).await?;
95
96 require(checkpoint_response.get("success").and_then(|v| v.as_bool()).unwrap_or(false), format!("checkpoint failed: {checkpoint_response}"))?;
97 require(handoff_response.get("success").and_then(|v| v.as_bool()).unwrap_or(false), format!("handoff failed: {handoff_response}"))?;
98 require(feedback_response.get("success").and_then(|v| v.as_bool()).unwrap_or(false), format!("feedback failed: {feedback_response}"))?;
99 require(exact.get("found").and_then(|v| v.as_bool()).unwrap_or(false), format!("dereference failed: {exact}"))?;
100 let context_text = context.get("context_block").and_then(|v| v.as_str()).unwrap_or("").to_lowercase();
101 let recall_text = recall_response.get("final_answer").and_then(|v| v.as_str()).unwrap_or("").to_lowercase();
102 let has_archive_source = context
103 .get("sources")
104 .and_then(|v| v.as_array())
105 .map(|sources| {
106 sources.iter().any(|source| {
107 source
108 .get("entry_type")
109 .and_then(|v| v.as_str())
110 == Some("archive_block")
111 })
112 })
113 .unwrap_or(false);
114 let exact_refs_surfaced = context
115 .get("exact_references_surfaced")
116 .and_then(|v| v.as_u64())
117 .unwrap_or(0);
118 require(
119 context_text.contains("adjuster note")
120 || context_text.contains("motorway")
121 || has_archive_source
122 || exact_refs_surfaced > 0,
123 format!("expected explicit or telemetry-backed exact reuse in context: {context}"),
124 )?;
125 require(recall_text.contains("250") && (recall_text.contains("motorway") || recall_text.contains("third party")), format!("expected recall to include fact + archive content: {recall_response}"))?;
126
127 metrics = json!({
128 "run_id": run_id,
129 "handoff_id": handoff_id,
130 "reference_id": reference_id,
131 "feedback_id": feedback_response.get("feedback_id").cloned().unwrap_or(serde_json::Value::Null),
132 });
133 Ok::<(), Box<dyn Error>>(())
134 }
135 .await;
136
137 if let Err(err) = scenario {
138 passed = false;
139 detail = err.to_string();
140 }
141
142 let cleanup_ok = cleanup_run(&client, &run_id).await;
143 if !cleanup_ok {
144 passed = false;
145 detail = format!("{detail} | cleanup failures");
146 }
147
148 print_summary(name, passed, &detail, &metrics, started.elapsed().as_secs_f64(), cleanup_ok);
149 if passed { Ok(()) } else { Err(boxed_error(detail)) }
150}examples/public/10_full_learning_loop_smoke.rs (line 123)
16async fn main() -> Result<(), Box<dyn Error>> {
17 let name = "public_10_full_learning_loop_smoke";
18 let started = Instant::now();
19 let client = create_client().await?;
20 let run_id = new_run_id("public_10_full_learning_loop_smoke");
21 client.set_run_id(Some(run_id.clone()));
22 client.set_transport(TransportMode::Http);
23
24 let mut passed = true;
25 let mut detail = "validated all helper flows".to_string();
26 let mut metrics = json!({});
27
28 let scenario = async {
29 let mut remember = RememberOptions::new("Policy limit is 5000 and claimant city is Leeds.");
30 remember.run_id = Some(run_id.clone());
31 remember.agent_id = Some("planner".to_string());
32 remember.intent = Some("fact".to_string());
33 remember.metadata = Some(json!({"suite": "all-helpers", "family": "claims"}));
34 remember.importance = Some("high".to_string());
35 remember.occurrence_time = Some(std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).unwrap().as_secs() as i64 - 86400);
36 let remember_response = client.remember(remember).await?;
37
38 let mut lesson = RememberOptions::new("If city is missing from the latest step, check stored claim facts before escalating.");
39 lesson.run_id = Some(run_id.clone());
40 lesson.agent_id = Some("planner".to_string());
41 lesson.intent = Some("lesson".to_string());
42 lesson.lesson_type = Some("success".to_string());
43 lesson.lesson_scope = Some("session".to_string());
44 lesson.lesson_importance = Some("high".to_string());
45 let lesson_response = client.remember(lesson).await?;
46
47 let mut mental_model = RememberOptions::new(
48 "Claims case overview: Policy limit 5000 GBP, claimant city Leeds, \
49 missing-city branch resolved via stored claim facts. Lesson: check stored facts before escalating.",
50 );
51 mental_model.run_id = Some(run_id.clone());
52 mental_model.agent_id = Some("planner".to_string());
53 mental_model.intent = Some("mental_model".to_string());
54 mental_model.importance = Some("critical".to_string());
55 mental_model.metadata = Some(json!({"suite": "all-helpers", "entity": "claims-case", "consolidated": true}));
56 let mental_model_response = client.remember(mental_model).await?;
57
58 let mut recall = RecallOptions::new("What is the policy limit?");
59 recall.run_id = Some(run_id.clone());
60 recall.agent_id = Some("planner".to_string());
61 recall.limit = 5;
62 let recall_response = client.recall(recall).await?;
63
64 let mut context = GetContextOptions::default();
65 context.run_id = Some(run_id.clone());
66 context.query = Some("Prepare a short adjuster summary".to_string());
67 context.agent_id = Some("planner".to_string());
68 context.limit = Some(6);
69 context.max_token_budget = Some(700);
70 let context_response = client.get_context(context).await?;
71
72 let mut health = MemoryHealthOptions::default();
73 health.run_id = Some(run_id.clone());
74 health.limit = 50;
75 let health_response = client.memory_health(health).await?;
76
77 let mut diagnose = DiagnoseOptions::new("policy limit lookup returned empty");
78 diagnose.run_id = Some(run_id.clone());
79 diagnose.error_type = Some("retrieval".to_string());
80 diagnose.limit = 5;
81 let diagnose_response = client.diagnose(diagnose).await?;
82
83 let mut reflect = ReflectOptions::default();
84 reflect.run_id = Some(run_id.clone());
85 let reflect_response = client.reflect(reflect).await?;
86
87 let mut register = RegisterAgentOptions::new("planner");
88 register.run_id = Some(run_id.clone());
89 register.role = "planner".to_string();
90 register.read_scopes = vec!["fact".into(), "lesson".into(), "rule".into(), "mental_model".into(), "archive_block".into(), "handoff".into(), "feedback".into()];
91 register.write_scopes = vec!["fact".into(), "trace".into(), "lesson".into(), "observation".into(), "archive_block".into()];
92 register.shared_memory_lanes = vec!["knowledge".into(), "history".into()];
93 let register_response = client.register_agent(register).await?;
94
95 let mut list_agents = ListAgentsOptions::default();
96 list_agents.run_id = Some(run_id.clone());
97 let agents_response = client.list_agents(list_agents).await?;
98
99 let mut archive = ArchiveOptions::new(
100 "Exact adjuster note: claimant confirmed city is Leeds during triage.",
101 "adjuster_note",
102 );
103 archive.run_id = Some(run_id.clone());
104 archive.agent_id = Some("planner".to_string());
105 archive.origin_agent_id = Some("planner".to_string());
106 archive.source_attempt_id = Some("attempt-1".to_string());
107 archive.source_tool = Some("phone_call".to_string());
108 archive.labels = vec!["claims".to_string(), "triage".to_string()];
109 archive.family = Some("claims-adjustment".to_string());
110 archive.metadata = Some(json!({"case": "all-helpers"}));
111 let archive_response = client.archive(archive).await?;
112 let reference_id = archive_response
113 .get("reference_id")
114 .and_then(Value::as_str)
115 .ok_or_else(|| boxed_error(format!("archive reference missing: {archive_response}")))?
116 .to_string();
117
118 let mut dereference = DereferenceOptions::new(reference_id.clone());
119 dereference.run_id = Some(run_id.clone());
120 dereference.agent_id = Some("planner".to_string());
121 let dereference_response = client.dereference(dereference).await?;
122
123 let mut checkpoint = CheckpointOptions::new("Planner captured claim facts before window compaction.");
124 checkpoint.run_id = Some(run_id.clone());
125 checkpoint.label = Some("pre-compaction".to_string());
126 checkpoint.metadata = Some(json!({"stage": "analysis"}));
127 checkpoint.agent_id = Some("planner".to_string());
128 let checkpoint_response = client.checkpoint(checkpoint).await?;
129
130 let lessons_response = client.control.lessons(json!({"run_id": run_id, "limit": 20})).await?;
131 let lesson_id = lessons_response
132 .get("lessons")
133 .and_then(Value::as_array)
134 .and_then(|items| items.iter().find_map(|item| item.get("id").and_then(Value::as_str)))
135 .ok_or_else(|| boxed_error(format!("expected lesson id for outcome flow: {lessons_response}")))?
136 .to_string();
137
138 let mut outcome = RecordOutcomeOptions::new(lesson_id, "success");
139 outcome.run_id = Some(run_id.clone());
140 outcome.signal = 0.75;
141 outcome.rationale = "Planner reused stored claim fact and resolved the missing-city branch.".to_string();
142 outcome.agent_id = Some("planner".to_string());
143 let outcome_response = client.record_outcome(outcome).await?;
144
145 let mut strategies = SurfaceStrategiesOptions::default();
146 strategies.run_id = Some(run_id.clone());
147 strategies.lesson_types = vec!["success".to_string(), "rule".to_string()];
148 strategies.max_strategies = 5;
149 let strategies_response = client.surface_strategies(strategies).await?;
150
151 let mut handoff = HandoffOptions::new(
152 "claim-1",
153 "planner",
154 "reviewer",
155 "Review whether the stored claimant city is sufficient for routing.",
156 );
157 handoff.run_id = Some(run_id.clone());
158 handoff.requested_action = "review".to_string();
159 handoff.metadata = Some(json!({"team": "claims"}));
160 let handoff_response = client.handoff(handoff).await?;
161 let handoff_id = handoff_response
162 .get("handoff_id")
163 .and_then(Value::as_str)
164 .ok_or_else(|| boxed_error(format!("handoff id missing: {handoff_response}")))?
165 .to_string();
166
167 let mut feedback = FeedbackOptions::new(handoff_id.clone(), "approve");
168 feedback.run_id = Some(run_id.clone());
169 feedback.comments = "Stored fact is sufficient; proceed without escalation.".to_string();
170 feedback.from_agent_id = Some("reviewer".to_string());
171 feedback.metadata = Some(json!({"team": "claims"}));
172 let feedback_response = client.feedback(feedback).await?;
173
174 require(remember_response.get("job_id").is_some() || remember_response.get("accepted").and_then(Value::as_bool).unwrap_or(false), format!("remember failed: {remember_response}"))?;
175 require(mental_model_response.get("job_id").is_some() || mental_model_response.get("accepted").and_then(Value::as_bool).unwrap_or(false), format!("mental_model remember failed: {mental_model_response}"))?;
176 require(lesson_response.get("job_id").is_some() || lesson_response.get("accepted").and_then(Value::as_bool).unwrap_or(false), format!("lesson remember failed: {lesson_response}"))?;
177 require(recall_response.get("final_answer").is_some() || recall_response.get("evidence").is_some(), format!("recall failed: {recall_response}"))?;
178 require(context_response.get("sources").and_then(Value::as_array).is_some(), format!("context malformed: {context_response}"))?;
179 require(health_response.get("entry_counts").and_then(Value::as_object).is_some(), format!("memory_health malformed: {health_response}"))?;
180 require(diagnose_response.get("failure_lessons").and_then(Value::as_array).is_some(), format!("diagnose malformed: {diagnose_response}"))?;
181 require(reflect_response.get("lessons").and_then(Value::as_array).is_some(), format!("reflect malformed: {reflect_response}"))?;
182 require(register_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("register_agent failed: {register_response}"))?;
183 require(agents_response.get("agents").and_then(Value::as_array).map(|items| !items.is_empty()).unwrap_or(false), format!("list_agents failed: {agents_response}"))?;
184 require(archive_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("archive failed: {archive_response}"))?;
185 require(dereference_response.get("found").and_then(Value::as_bool).unwrap_or(false), format!("dereference failed: {dereference_response}"))?;
186 require(checkpoint_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("checkpoint failed: {checkpoint_response}"))?;
187 require(outcome_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("record_outcome failed: {outcome_response}"))?;
188 require(strategies_response.get("strategies").and_then(Value::as_array).is_some(), format!("surface_strategies malformed: {strategies_response}"))?;
189 require(handoff_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("handoff failed: {handoff_response}"))?;
190 require(feedback_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("feedback failed: {feedback_response}"))?;
191
192 let strategy_count = strategies_response
193 .get("strategies")
194 .and_then(Value::as_array)
195 .map(|items| items.len())
196 .unwrap_or(0);
197 let agent_count = agents_response
198 .get("agents")
199 .and_then(Value::as_array)
200 .map(|items| items.len())
201 .unwrap_or(0);
202 let lesson_count = lessons_response
203 .get("lessons")
204 .and_then(Value::as_array)
205 .map(|items| items.len())
206 .unwrap_or(0);
207
208 metrics = json!({
209 "run_id": run_id,
210 "agent_count": agent_count,
211 "strategy_count": strategy_count,
212 "reference_id": reference_id,
213 "lesson_count": lesson_count,
214 });
215
216 Ok::<(), Box<dyn Error>>(())
217 }
218 .await;
219
220 if let Err(err) = scenario {
221 passed = false;
222 detail = err.to_string();
223 }
224
225 let cleanup_ok = cleanup_run(&client, &run_id).await;
226 if !cleanup_ok {
227 passed = false;
228 detail = format!("{detail} | cleanup failures");
229 }
230
231 print_summary(name, passed, &detail, &metrics, started.elapsed().as_secs_f64(), cleanup_ok);
232
233 if passed { Ok(()) } else { Err(boxed_error(detail)) }
234}examples/helper_all_helpers.rs (line 111)
16async fn main() -> Result<(), Box<dyn Error>> {
17 let name = "helper_all_helpers";
18 let started = Instant::now();
19 let client = create_client().await?;
20 let run_id = new_run_id("helper_all_helpers");
21 client.set_run_id(Some(run_id.clone()));
22 client.set_transport(TransportMode::Http);
23
24 let mut passed = true;
25 let mut detail = "validated all helper flows".to_string();
26 let mut metrics = json!({});
27
28 let scenario = async {
29 let mut remember = RememberOptions::new("Policy limit is 5000 and claimant city is Leeds.");
30 remember.run_id = Some(run_id.clone());
31 remember.agent_id = Some("planner".to_string());
32 remember.intent = Some("fact".to_string());
33 remember.metadata = Some(json!({"suite": "all-helpers", "family": "claims"}));
34 remember.importance = Some("high".to_string());
35 let remember_response = client.remember(remember).await?;
36
37 let mut lesson = RememberOptions::new("If city is missing from the latest step, check stored claim facts before escalating.");
38 lesson.run_id = Some(run_id.clone());
39 lesson.agent_id = Some("planner".to_string());
40 lesson.intent = Some("lesson".to_string());
41 lesson.lesson_type = Some("success".to_string());
42 lesson.lesson_scope = Some("session".to_string());
43 lesson.lesson_importance = Some("high".to_string());
44 let lesson_response = client.remember(lesson).await?;
45
46 let mut recall = RecallOptions::new("What is the policy limit?");
47 recall.run_id = Some(run_id.clone());
48 recall.agent_id = Some("planner".to_string());
49 recall.limit = 5;
50 let recall_response = client.recall(recall).await?;
51
52 let mut context = GetContextOptions::default();
53 context.run_id = Some(run_id.clone());
54 context.query = Some("Prepare a short adjuster summary".to_string());
55 context.agent_id = Some("planner".to_string());
56 context.limit = Some(6);
57 context.max_token_budget = Some(700);
58 let context_response = client.get_context(context).await?;
59
60 let mut health = MemoryHealthOptions::default();
61 health.run_id = Some(run_id.clone());
62 health.limit = 50;
63 let health_response = client.memory_health(health).await?;
64
65 let mut diagnose = DiagnoseOptions::new("policy limit lookup returned empty");
66 diagnose.run_id = Some(run_id.clone());
67 diagnose.error_type = Some("retrieval".to_string());
68 diagnose.limit = 5;
69 let diagnose_response = client.diagnose(diagnose).await?;
70
71 let mut reflect = ReflectOptions::default();
72 reflect.run_id = Some(run_id.clone());
73 let reflect_response = client.reflect(reflect).await?;
74
75 let mut register = RegisterAgentOptions::new("planner");
76 register.run_id = Some(run_id.clone());
77 register.role = "planner".to_string();
78 register.read_scopes = vec!["fact".into(), "lesson".into(), "rule".into(), "archive_block".into(), "handoff".into(), "feedback".into()];
79 register.write_scopes = vec!["fact".into(), "trace".into(), "lesson".into(), "observation".into(), "archive_block".into()];
80 register.shared_memory_lanes = vec!["knowledge".into(), "history".into()];
81 let register_response = client.register_agent(register).await?;
82
83 let mut list_agents = ListAgentsOptions::default();
84 list_agents.run_id = Some(run_id.clone());
85 let agents_response = client.list_agents(list_agents).await?;
86
87 let mut archive = ArchiveOptions::new(
88 "Exact adjuster note: claimant confirmed city is Leeds during triage.",
89 "adjuster_note",
90 );
91 archive.run_id = Some(run_id.clone());
92 archive.agent_id = Some("planner".to_string());
93 archive.origin_agent_id = Some("planner".to_string());
94 archive.source_attempt_id = Some("attempt-1".to_string());
95 archive.source_tool = Some("phone_call".to_string());
96 archive.labels = vec!["claims".to_string(), "triage".to_string()];
97 archive.family = Some("claims-adjustment".to_string());
98 archive.metadata = Some(json!({"case": "all-helpers"}));
99 let archive_response = client.archive(archive).await?;
100 let reference_id = archive_response
101 .get("reference_id")
102 .and_then(Value::as_str)
103 .ok_or_else(|| boxed_error(format!("archive reference missing: {archive_response}")))?
104 .to_string();
105
106 let mut dereference = DereferenceOptions::new(reference_id.clone());
107 dereference.run_id = Some(run_id.clone());
108 dereference.agent_id = Some("planner".to_string());
109 let dereference_response = client.dereference(dereference).await?;
110
111 let mut checkpoint = CheckpointOptions::new("Planner captured claim facts before window compaction.");
112 checkpoint.run_id = Some(run_id.clone());
113 checkpoint.label = Some("pre-compaction".to_string());
114 checkpoint.metadata = Some(json!({"stage": "analysis"}));
115 checkpoint.agent_id = Some("planner".to_string());
116 let checkpoint_response = client.checkpoint(checkpoint).await?;
117
118 let lessons_response = client.control.lessons(json!({"run_id": run_id, "limit": 20})).await?;
119 let lesson_id = lessons_response
120 .get("lessons")
121 .and_then(Value::as_array)
122 .and_then(|items| items.iter().find_map(|item| item.get("id").and_then(Value::as_str)))
123 .ok_or_else(|| boxed_error(format!("expected lesson id for outcome flow: {lessons_response}")))?
124 .to_string();
125
126 let mut outcome = RecordOutcomeOptions::new(lesson_id, "success");
127 outcome.run_id = Some(run_id.clone());
128 outcome.signal = 0.75;
129 outcome.rationale = "Planner reused stored claim fact and resolved the missing-city branch.".to_string();
130 outcome.agent_id = Some("planner".to_string());
131 let outcome_response = client.record_outcome(outcome).await?;
132
133 let mut strategies = SurfaceStrategiesOptions::default();
134 strategies.run_id = Some(run_id.clone());
135 strategies.lesson_types = vec!["success".to_string(), "rule".to_string()];
136 strategies.max_strategies = 5;
137 let strategies_response = client.surface_strategies(strategies).await?;
138
139 let mut handoff = HandoffOptions::new(
140 "claim-1",
141 "planner",
142 "reviewer",
143 "Review whether the stored claimant city is sufficient for routing.",
144 );
145 handoff.run_id = Some(run_id.clone());
146 handoff.requested_action = "review".to_string();
147 handoff.metadata = Some(json!({"team": "claims"}));
148 let handoff_response = client.handoff(handoff).await?;
149 let handoff_id = handoff_response
150 .get("handoff_id")
151 .and_then(Value::as_str)
152 .ok_or_else(|| boxed_error(format!("handoff id missing: {handoff_response}")))?
153 .to_string();
154
155 let mut feedback = FeedbackOptions::new(handoff_id.clone(), "approve");
156 feedback.run_id = Some(run_id.clone());
157 feedback.comments = "Stored fact is sufficient; proceed without escalation.".to_string();
158 feedback.from_agent_id = Some("reviewer".to_string());
159 feedback.metadata = Some(json!({"team": "claims"}));
160 let feedback_response = client.feedback(feedback).await?;
161
162 let scratch_run = format!("{run_id}_forget");
163 let mut scratch = RememberOptions::new("Scratch run for forget helper coverage.");
164 scratch.run_id = Some(scratch_run.clone());
165 scratch.agent_id = Some("planner".to_string());
166 scratch.intent = Some("fact".to_string());
167 scratch.metadata = Some(json!({"suite": "all-helpers", "temporary": true}));
168 let scratch_response = client.remember(scratch).await?;
169
170 let forget_response = client
171 .forget(ForgetOptions::for_run(scratch_run.clone()))
172 .await?;
173
174 let mut forgotten = RecallOptions::new("What temporary scratch fact exists?");
175 forgotten.run_id = Some(scratch_run.clone());
176 forgotten.limit = 3;
177 let forgotten_response = client.recall(forgotten).await?;
178
179 require(remember_response.get("job_id").is_some() || remember_response.get("accepted").and_then(Value::as_bool).unwrap_or(false), format!("remember failed: {remember_response}"))?;
180 require(lesson_response.get("job_id").is_some() || lesson_response.get("accepted").and_then(Value::as_bool).unwrap_or(false), format!("lesson remember failed: {lesson_response}"))?;
181 require(recall_response.get("final_answer").is_some() || recall_response.get("evidence").is_some(), format!("recall failed: {recall_response}"))?;
182 require(context_response.get("sources").and_then(Value::as_array).is_some(), format!("context malformed: {context_response}"))?;
183 require(health_response.get("entry_counts").and_then(Value::as_object).is_some(), format!("memory_health malformed: {health_response}"))?;
184 require(diagnose_response.get("failure_lessons").and_then(Value::as_array).is_some(), format!("diagnose malformed: {diagnose_response}"))?;
185 require(reflect_response.get("lessons").and_then(Value::as_array).is_some(), format!("reflect malformed: {reflect_response}"))?;
186 require(register_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("register_agent failed: {register_response}"))?;
187 require(agents_response.get("agents").and_then(Value::as_array).map(|items| !items.is_empty()).unwrap_or(false), format!("list_agents failed: {agents_response}"))?;
188 require(archive_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("archive failed: {archive_response}"))?;
189 require(dereference_response.get("found").and_then(Value::as_bool).unwrap_or(false), format!("dereference failed: {dereference_response}"))?;
190 require(checkpoint_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("checkpoint failed: {checkpoint_response}"))?;
191 require(outcome_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("record_outcome failed: {outcome_response}"))?;
192 require(strategies_response.get("strategies").and_then(Value::as_array).is_some(), format!("surface_strategies malformed: {strategies_response}"))?;
193 require(handoff_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("handoff failed: {handoff_response}"))?;
194 require(feedback_response.get("success").and_then(Value::as_bool).unwrap_or(false), format!("feedback failed: {feedback_response}"))?;
195 require(scratch_response.get("job_id").is_some() || scratch_response.get("accepted").and_then(Value::as_bool).unwrap_or(false), format!("scratch remember failed: {scratch_response}"))?;
196 require(forget_response.get("success").and_then(Value::as_bool).unwrap_or(true), format!("forget failed: {forget_response}"))?;
197 let scratch_fact_visible = forgotten_response
198 .get("evidence")
199 .and_then(Value::as_array)
200 .map(|items| {
201 items.iter().any(|item| {
202 item.get("run_id").and_then(Value::as_str) == Some(scratch_run.as_str())
203 || item
204 .get("content")
205 .and_then(Value::as_str)
206 .map(|content| {
207 content
208 .to_ascii_lowercase()
209 .contains("scratch run for forget helper coverage")
210 })
211 .unwrap_or(false)
212 })
213 })
214 .unwrap_or(false);
215 require(!scratch_fact_visible, format!("scratch fact should be forgotten even if same-user lessons still surface: {forgotten_response}"))?;
216
217 let strategy_count = strategies_response
218 .get("strategies")
219 .and_then(Value::as_array)
220 .map(|items| items.len())
221 .unwrap_or(0);
222 let agent_count = agents_response
223 .get("agents")
224 .and_then(Value::as_array)
225 .map(|items| items.len())
226 .unwrap_or(0);
227 let lesson_count = lessons_response
228 .get("lessons")
229 .and_then(Value::as_array)
230 .map(|items| items.len())
231 .unwrap_or(0);
232
233 metrics = json!({
234 "run_id": run_id,
235 "agent_count": agent_count,
236 "strategy_count": strategy_count,
237 "reference_id": reference_id,
238 "lesson_count": lesson_count,
239 "forgotten_run": scratch_run,
240 });
241
242 Ok::<(), Box<dyn Error>>(())
243 }
244 .await;
245
246 if let Err(err) = scenario {
247 passed = false;
248 detail = err.to_string();
249 }
250
251 let cleanup_ok = cleanup_run(&client, &run_id).await;
252 if !cleanup_ok {
253 passed = false;
254 detail = format!("{detail} | cleanup failures");
255 }
256
257 print_summary(name, passed, &detail, &metrics, started.elapsed().as_secs_f64(), cleanup_ok);
258
259 if passed { Ok(()) } else { Err(boxed_error(detail)) }
260}Trait Implementations§
Source§impl Clone for CheckpointOptions
impl Clone for CheckpointOptions
Source§fn clone(&self) -> CheckpointOptions
fn clone(&self) -> CheckpointOptions
Returns a duplicate of the value. Read more
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
Performs copy-assignment from
source. Read moreAuto Trait Implementations§
impl Freeze for CheckpointOptions
impl RefUnwindSafe for CheckpointOptions
impl Send for CheckpointOptions
impl Sync for CheckpointOptions
impl Unpin for CheckpointOptions
impl UnsafeUnpin for CheckpointOptions
impl UnwindSafe for CheckpointOptions
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoRequest<T> for T
impl<T> IntoRequest<T> for T
Source§fn into_request(self) -> Request<T>
fn into_request(self) -> Request<T>
Wrap the input message
T in a tonic::Request