Skip to main content

replay

Function replay 

Source
pub fn replay(store: &MemoryStore, run_id: &str) -> Result<ReplaySummary>
Examples found in repository?
examples/three_minute_demo.rs (line 99)
20fn main() -> agentledger::Result<()> {
21    let mut runtime = Runtime::new();
22    runtime.register_tool(
23        ToolSpec::new(
24            "ticket.create",
25            Box::new(|args| {
26                Ok(Value::Object(state(&[
27                    ("external_id", "TICKET-1".into()),
28                    ("title", args["title"].clone()),
29                ])))
30            }),
31        )
32        .side_effect("external_write")
33        .idempotency_required(true)
34        .input_schema(Value::Object(state(&[
35            ("type", "object".into()),
36            (
37                "required",
38                Value::Array(vec![Value::String("title".to_string())]),
39            ),
40        ]))),
41    );
42    let (run_id, _) = runtime.create_run(State::new());
43
44    let first_claim = runtime.store.claim_step("worker-before-crash", &run_id, 60.0)?;
45    let first_ctx = AgentContext {
46        run_id: run_id.clone(),
47        session_id: first_claim.session_id.clone(),
48        step_id: first_claim.step_id.clone(),
49        agent_role: "SupportAgent".to_string(),
50        lease_token: first_claim.lease_token.clone(),
51        attempt: first_claim.attempt,
52        state_version: first_claim.state_version,
53        pending_patch: State::new(),
54    };
55    let ticket = runtime.call_tool(
56        &first_ctx,
57        "ticket.create",
58        state(&[
59            ("title", "Investigate failed payment".into()),
60            ("_logical_operation", "open-payment-ticket".into()),
61        ]),
62    )?;
63    runtime.store.mark_retry(
64        &run_id,
65        &first_ctx.step_id,
66        "RetryableAgentError",
67        "after external ticket create, before state commit",
68    );
69
70    let second_claim = runtime.store.claim_step("worker-after-restart", &run_id, 60.0)?;
71    let mut second_ctx = AgentContext {
72        run_id: run_id.clone(),
73        session_id: second_claim.session_id.clone(),
74        step_id: second_claim.step_id.clone(),
75        agent_role: "SupportAgent".to_string(),
76        lease_token: second_claim.lease_token.clone(),
77        attempt: second_claim.attempt,
78        state_version: second_claim.state_version,
79        pending_patch: State::new(),
80    };
81    let replayed_ticket = runtime.call_tool(
82        &second_ctx,
83        "ticket.create",
84        state(&[
85            ("title", "Investigate failed payment".into()),
86            ("_logical_operation", "open-payment-ticket".into()),
87        ]),
88    )?;
89    second_ctx.write_state("ticket", replayed_ticket);
90    second_ctx.write_state("recovered", true.into());
91    runtime.store.commit_state_patch(
92        &run_id,
93        &second_ctx.step_id,
94        &second_ctx.lease_token,
95        second_ctx.state_version,
96        second_ctx.pending_patch,
97    )?;
98
99    let summary = replay(&runtime.store, &run_id)?;
100    let ledger = runtime.store.ledger(&run_id);
101    let final_state = runtime.store.final_state(&run_id)?;
102    println!(
103        "{{\n  \"run_id\": \"{}\",\n  \"first_attempt_ok\": false,\n  \"second_attempt_ok\": true,\n  \"external_ticket_count\": 1,\n  \"actual_tool_executions\": 1,\n  \"tool_ledger_count\": {},\n  \"tool_ledger_status\": \"{}\",\n  \"first_ticket_external_id\": \"{}\",\n  \"final_state_recovered\": {},\n  \"replay\": {{\n    \"safe\": {},\n    \"event_count\": {},\n    \"tool_call_count\": {}\n  }}\n}}",
104        run_id,
105        ledger.len(),
106        ledger.first().map(|row| row.status.as_str()).unwrap_or(""),
107        get_string(&ticket, "external_id"),
108        final_state.get("recovered") == Some(&Value::Bool(true)),
109        summary.replay_safe,
110        summary.event_count,
111        summary.tool_call_count
112    );
113    Ok(())
114}