yoyo_evolve_demo/
yoyo_evolve_demo.rs1use serde_json::json;
2use yoagent_state::{
3 ActorRef, ExpectedEffect, NodeId, PatchId, PatchStatus, Precondition, StatePatch, YoAgentState,
4 changed_file_ops, diff_artifact, parse_git_name_status, project_ref,
5};
6
7#[tokio::main]
8async fn main() -> Result<(), Box<dyn std::error::Error>> {
9 let state = YoAgentState::load(yoagent_state::MemoryEventStore::new()).await?;
10 let actor = ActorRef::agent("yoyo-evolve");
11
12 let failure = NodeId::new("failure_retry_timeout");
13 state
14 .record_failure(
15 actor.clone(),
16 failure.clone(),
17 "Retry eval fails after timeout",
18 "The retry attempt count is reset when the timeout cancels the future.",
19 )
20 .await?;
21
22 let changed = parse_git_name_status(
23 "M crates/yoagent-runtime/src/tool.rs\nA crates/yoagent-runtime/tests/retry.rs\n",
24 );
25 let patch_id = PatchId::new("patch_retry_timeout");
26 let mut patch = StatePatch::new(
27 patch_id.clone(),
28 "Persist retry state across timeout",
29 "Move attempt count into RetryState and keep it outside the cancelled future.",
30 actor.clone(),
31 );
32 patch.base_project_ref = Some(project_ref(
33 "yoagent",
34 Some("main".to_string()),
35 Some("abc123".to_string()),
36 None,
37 ));
38 patch.evidence.push(failure);
39 patch
40 .preconditions
41 .push(Precondition::ProjectCommitIs("abc123".to_string()));
42 patch.expected_effects.push(ExpectedEffect::TestPasses {
43 name: "tool_retry_survives_timeout".to_string(),
44 });
45 patch.artifacts.push(diff_artifact(
46 ".yoyo/artifacts/patch_retry_timeout.diff",
47 "Persist retry state and add timeout regression test",
48 "abc123",
49 &changed,
50 ));
51 patch
52 .ops
53 .extend(changed_file_ops(patch_id.clone(), &changed));
54
55 state.propose_patch(patch).await?;
56 state
57 .record_eval_result(
58 actor,
59 NodeId::new("eval_retry_timeout"),
60 patch_id.clone(),
61 "cargo test tool_retry_survives_timeout",
62 true,
63 )
64 .await?;
65 state
66 .record_decision(
67 ActorRef::user("yuanhao"),
68 NodeId::new("decision_promote_retry_timeout"),
69 patch_id.clone(),
70 true,
71 "Regression test passed",
72 )
73 .await?;
74 state
75 .update_patch_status(
76 patch_id.clone(),
77 PatchStatus::Promoted,
78 Some("Promoted as commit def456".to_string()),
79 )
80 .await?;
81
82 let lineage = state.lineage(NodeId::new(patch_id.0)).await;
83 println!("{}", lineage.to_markdown());
84 println!(
85 "changed_files={}",
86 json!(changed.iter().map(|file| &file.path).collect::<Vec<_>>())
87 );
88 Ok(())
89}