praxis_types/
events.rs

1use serde::{Deserialize, Serialize};
2
3/// Extended StreamEvent that includes both LLM streaming events and Graph orchestration events
4#[derive(Debug, Clone, Serialize, Deserialize)]
5#[serde(tag = "type", rename_all = "snake_case")]
6pub enum StreamEvent {
7    /// Graph execution started
8    InitStream {
9        run_id: String,
10        conversation_id: String,
11        timestamp: i64,
12    },
13    
14    /// Internal reasoning from LLM (streamed token-by-token)
15    Reasoning {
16        content: String,
17    },
18    
19    /// Response message from LLM (streamed token-by-token)
20    Message {
21        content: String,
22    },
23    
24    /// LLM decided to call a tool (streamed incrementally)
25    ToolCall {
26        index: u32,
27        #[serde(skip_serializing_if = "Option::is_none")]
28        id: Option<String>,
29        #[serde(skip_serializing_if = "Option::is_none")]
30        name: Option<String>,
31        #[serde(skip_serializing_if = "Option::is_none")]
32        arguments: Option<String>,
33    },
34    
35    /// Tool execution completed
36    ToolResult {
37        tool_call_id: String,
38        result: String,
39        is_error: bool,
40        duration_ms: u64,
41    },
42    
43    /// LLM streaming completed
44    Done {
45        #[serde(skip_serializing_if = "Option::is_none")]
46        finish_reason: Option<String>,
47    },
48    
49    /// Fatal error occurred
50    Error {
51        message: String,
52        #[serde(skip_serializing_if = "Option::is_none")]
53        node_id: Option<String>,
54    },
55    
56    /// Graph execution completed
57    EndStream {
58        status: String,
59        total_duration_ms: u64,
60    },
61}
62