1use agentledger::{
2 OmpLedgerBridge, OmpModelCall, OmpSession, OmpStateChange, OmpToolExecution, OmpToolProposal,
3 OmpTurn, Runtime, State, Value,
4};
5
6fn state(items: &[(&str, Value)]) -> State {
7 items
8 .iter()
9 .map(|(key, value)| ((*key).to_string(), value.clone()))
10 .collect()
11}
12
13fn main() -> agentledger::Result<()> {
14 let runtime = Runtime::new();
15 let mut bridge = OmpLedgerBridge::new(runtime, "omp-demo");
16 let run_id = bridge.record_session_started(OmpSession {
17 session_id: "omp-session-1".to_string(),
18 initial_state: state(&[("task", "review contract".into())]),
19 metadata: state(&[("runtime", "synthetic-omp".into())]),
20 ..Default::default()
21 })?;
22 bridge.record_turn_started(OmpTurn {
23 session_id: "omp-session-1".to_string(),
24 turn_id: "turn-1".to_string(),
25 agent_role: "OMPPlanner".to_string(),
26 metadata: state(&[("phase", "planning".into())]),
27 ..Default::default()
28 })?;
29 bridge.record_model_call(OmpModelCall {
30 session_id: "omp-session-1".to_string(),
31 turn_id: "turn-1".to_string(),
32 provider: "openai-compatible-gateway".to_string(),
33 model: "legal-router".to_string(),
34 request: state(&[(
35 "messages",
36 Value::Array(vec![Value::Object(state(&[
37 ("role", "user".into()),
38 ("content", "find payment clause".into()),
39 ]))]),
40 )]),
41 response: state(&[(
42 "tool_calls",
43 Value::Array(vec![Value::Object(state(&[
44 ("name", "contract.search".into()),
45 (
46 "arguments",
47 Value::Object(state(&[("clause", "payment".into())])),
48 ),
49 ]))]),
50 )]),
51 usage: state(&[
52 ("input_tokens", Value::Number(12.0)),
53 ("output_tokens", Value::Number(7.0)),
54 ("total_tokens", Value::Number(19.0)),
55 ]),
56 total_usd: 0.003,
57 ..Default::default()
58 })?;
59 bridge.record_tool_proposal(OmpToolProposal {
60 session_id: "omp-session-1".to_string(),
61 turn_id: "turn-1".to_string(),
62 tool_name: "contract.search".to_string(),
63 arguments: state(&[("clause", "payment".into())]),
64 provider: Some("openai-compatible-gateway".to_string()),
65 model: Some("legal-router".to_string()),
66 reason: Some("model proposed a contract search".to_string()),
67 ..Default::default()
68 })?;
69 bridge.record_tool_execution(OmpToolExecution {
70 session_id: "omp-session-1".to_string(),
71 turn_id: "turn-1".to_string(),
72 tool_name: "contract.search".to_string(),
73 arguments: state(&[("clause", "payment".into())]),
74 result: Some(Value::Object(state(&[
75 ("matches", Value::Array(vec!["Section 9.2".into()])),
76 ("external_id", "search-001".into()),
77 ]))),
78 ledger_status: Some("SUCCEEDED".to_string()),
79 ..Default::default()
80 })?;
81 bridge.record_state_change(OmpStateChange {
82 session_id: "omp-session-1".to_string(),
83 turn_id: Some("turn-1".to_string()),
84 reason: "persist normalized runtime-adjacent state".to_string(),
85 patch: state(&[("memory_version", Value::Number(1.0))]),
86 before_snapshot: Some(Value::Object(state(&[("memory_version", Value::Number(0.0))]))),
87 after_snapshot: Some(Value::Object(state(&[("memory_version", Value::Number(1.0))]))),
88 diff: Some(Value::Object(state(&[(
89 "memory_version",
90 Value::Array(vec![Value::Number(0.0), Value::Number(1.0)]),
91 )]))),
92 ..Default::default()
93 })?;
94 bridge.record_turn_completed(OmpTurn {
95 session_id: "omp-session-1".to_string(),
96 turn_id: "turn-1".to_string(),
97 state_patch: state(&[("last_tool", "contract.search".into())]),
98 ..Default::default()
99 })?;
100
101 let events = bridge
102 .runtime
103 .store
104 .events(&run_id)
105 .iter()
106 .map(|event| event.event_type.clone())
107 .collect::<Vec<_>>();
108 let final_state = bridge.runtime.store.final_state(&run_id)?;
109 let rendered_events = format!("{:?}", events);
110 let memory_version = match final_state.get("memory_version") {
111 Some(Value::Number(value)) => *value,
112 _ => 0.0,
113 };
114 let last_tool = match final_state.get("last_tool") {
115 Some(Value::String(value)) => value.as_str(),
116 _ => "",
117 };
118 println!(
119 concat!(
120 "{{\n",
121 " \"run_id\": \"{}\",\n",
122 " \"events\": {},\n",
123 " \"tool_ledger_count\": {},\n",
124 " \"final_state_memory_version\": {},\n",
125 " \"final_state_last_tool\": \"{}\"\n",
126 "}}"
127 ),
128 run_id,
129 rendered_events,
130 bridge.runtime.store.ledger(&run_id).len(),
131 memory_version,
132 last_tool
133 );
134 Ok(())
135}