pub struct ForgetOptions {
pub run_id: Option<String>,
pub lesson_id: Option<String>,
}Fields§
§run_id: Option<String>§lesson_id: Option<String>Implementations§
Source§impl ForgetOptions
impl ForgetOptions
Sourcepub fn for_run(run_id: impl Into<String>) -> Self
pub fn for_run(run_id: impl Into<String>) -> Self
Examples found in repository?
examples/helper_all_helpers.rs (line 171)
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}pub fn for_lesson(lesson_id: impl Into<String>) -> Self
Trait Implementations§
Source§impl Clone for ForgetOptions
impl Clone for ForgetOptions
Source§fn clone(&self) -> ForgetOptions
fn clone(&self) -> ForgetOptions
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 moreSource§impl Debug for ForgetOptions
impl Debug for ForgetOptions
Source§impl Default for ForgetOptions
impl Default for ForgetOptions
Source§fn default() -> ForgetOptions
fn default() -> ForgetOptions
Returns the “default value” for a type. Read more
Auto Trait Implementations§
impl Freeze for ForgetOptions
impl RefUnwindSafe for ForgetOptions
impl Send for ForgetOptions
impl Sync for ForgetOptions
impl Unpin for ForgetOptions
impl UnsafeUnpin for ForgetOptions
impl UnwindSafe for ForgetOptions
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