agtrace_engine/domain/
events.rs

1use agtrace_types::{AgentEvent, EventPayload};
2
3/// Filters for including/excluding event types.
4///
5/// Supports both allowlist (`only`) and blocklist (`hide`) patterns
6/// for event type filtering.
7pub struct EventFilters {
8    /// Event types to exclude (blocklist).
9    pub hide: Option<Vec<String>>,
10    /// Event types to include exclusively (allowlist).
11    pub only: Option<Vec<String>>,
12}
13
14/// Filter events by type using inclusion/exclusion patterns.
15///
16/// Applies `only` filter first (if present), then `hide` filter.
17/// Supported patterns: "user", "assistant"/"message", "tool",
18/// "reasoning", "token"/"tokenusage", "notification"/"info".
19pub fn filter_events(events: &[AgentEvent], filters: EventFilters) -> Vec<AgentEvent> {
20    let mut filtered = events.to_vec();
21
22    if let Some(only_patterns) = filters.only {
23        filtered.retain(|e| {
24            only_patterns.iter().any(|pattern| {
25                let pattern_lower = pattern.to_lowercase();
26                match &e.payload {
27                    EventPayload::User(_) => pattern_lower == "user",
28                    EventPayload::Message(_) => {
29                        pattern_lower == "assistant" || pattern_lower == "message"
30                    }
31                    EventPayload::ToolCall(_) | EventPayload::ToolResult(_) => {
32                        pattern_lower == "tool"
33                    }
34                    EventPayload::Reasoning(_) => pattern_lower == "reasoning",
35                    EventPayload::TokenUsage(_) => {
36                        pattern_lower == "token" || pattern_lower == "tokenusage"
37                    }
38                    EventPayload::Notification(_) => {
39                        pattern_lower == "notification" || pattern_lower == "info"
40                    }
41                }
42            })
43        });
44    }
45
46    if let Some(hide_patterns) = filters.hide {
47        filtered.retain(|e| {
48            !hide_patterns.iter().any(|pattern| {
49                let pattern_lower = pattern.to_lowercase();
50                match &e.payload {
51                    EventPayload::User(_) => pattern_lower == "user",
52                    EventPayload::Message(_) => {
53                        pattern_lower == "assistant" || pattern_lower == "message"
54                    }
55                    EventPayload::ToolCall(_) | EventPayload::ToolResult(_) => {
56                        pattern_lower == "tool"
57                    }
58                    EventPayload::Reasoning(_) => pattern_lower == "reasoning",
59                    EventPayload::TokenUsage(_) => {
60                        pattern_lower == "token" || pattern_lower == "tokenusage"
61                    }
62                    EventPayload::Notification(_) => {
63                        pattern_lower == "notification" || pattern_lower == "info"
64                    }
65                }
66            })
67        });
68    }
69
70    filtered
71}