1use std::collections::HashMap;
8
9use cel_context::{
10 ContentRole, ContextContribution, ContextElement, ContextMerger, ContextSource, ElementState,
11 StreamStatus,
12};
13
14fn main() {
15 let json_output = std::env::args().any(|arg| arg == "--json");
16
17 let mut merger = ContextMerger::new().with_defaults("Incident Review", "Checkout Flow");
18 merger.push(
19 ContextContribution::new(
20 "metrics_stream",
21 vec![
22 element(
23 "metric:checkout:error_rate",
24 "metric",
25 "Checkout error rate is above threshold",
26 Some("7.2%"),
27 ContextSource::External,
28 ContentRole::Content,
29 ),
30 element(
31 "metric:checkout:p95_latency",
32 "metric",
33 "Checkout p95 latency is elevated",
34 Some("1840ms"),
35 ContextSource::External,
36 ContentRole::Content,
37 ),
38 ],
39 )
40 .with_app("Incident Review")
41 .with_window("Checkout Flow")
42 .with_stream_status(StreamStatus {
43 accessibility: false,
44 display: false,
45 network: true,
46 signals: true,
47 vision: false,
48 audio_capture: false,
49 }),
50 );
51 merger.push(ContextContribution::new(
52 "support_tickets",
53 vec![element(
54 "ticket:1842",
55 "ticket",
56 "Users report payment confirmation page timing out",
57 Some("priority=high"),
58 ContextSource::External,
59 ContentRole::Content,
60 )],
61 ));
62 merger.push(ContextContribution::new(
63 "browser_dom",
64 vec![element(
65 "dom:button:retry-payment",
66 "button",
67 "Retry payment",
68 None,
69 ContextSource::Cdp,
70 ContentRole::Interactive,
71 )],
72 ));
73 merger.push(ContextContribution::new(
74 "service_logs",
75 vec![element(
76 "log:payment-service:timeout",
77 "log_event",
78 "payment-service timed out calling card processor",
79 Some("Timeout after 3000ms"),
80 ContextSource::External,
81 ContentRole::Content,
82 )],
83 ));
84
85 let ctx = merger.build();
86
87 if json_output {
88 println!("{}", serde_json::to_string_pretty(&ctx).unwrap());
89 return;
90 }
91
92 println!("=== Agent Context Snapshot ===");
93 println!("App: {}", ctx.app);
94 println!("Window: {}", ctx.window);
95 println!("Timestamp: {} ms", ctx.timestamp_ms);
96 println!("Elements: {}", ctx.elements.len());
97 println!();
98
99 for (i, elem) in ctx.elements.iter().enumerate() {
100 let label = elem.label.as_deref().unwrap_or("(no label)");
101 let value = elem.value.as_deref().unwrap_or("");
102 println!(
103 " {:>2}. [{:.2}] {:12} {:48} {:18} {:?}",
104 i + 1,
105 elem.confidence,
106 elem.element_type,
107 label,
108 value,
109 elem.source
110 );
111 }
112}
113
114fn element(
115 id: &str,
116 element_type: &str,
117 label: &str,
118 value: Option<&str>,
119 source: ContextSource,
120 content_role: ContentRole,
121) -> ContextElement {
122 ContextElement {
123 id: id.into(),
124 label: Some(label.into()),
125 description: None,
126 element_type: element_type.into(),
127 value: value.map(String::from),
128 bounds: None,
129 state: ElementState::default(),
130 parent_id: None,
131 actions: Vec::new(),
132 confidence: 0.0,
133 source,
134 content_role,
135 properties: HashMap::new(),
136 }
137}