1use crate::{Endpoint, Origin, Role, TokenCounts, TokenSemantics, UsageBasis};
2use chrono::{DateTime, Utc};
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
7pub struct Location {
8 pub record_index: u64,
9 pub line_no: u64,
10 pub byte_start: u64,
11 pub byte_end: u64,
12 pub event_index: usize,
13}
14
15#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
16pub struct Located<T> {
17 pub location: Location,
18 pub at: Option<DateTime<Utc>>,
19 pub timestamp_text: Option<String>,
20 pub record_id: Option<String>,
21 pub record_type: Option<String>,
22 pub session_id: Option<String>,
23 pub message_id: Option<String>,
24 pub value: T,
25}
26
27#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
28#[non_exhaustive]
29pub enum Event {
30 Meta(MetaUpdate),
31 Message(Message),
32 ToolCall(ToolCall),
33 ToolResult(ToolResult),
34 Usage(Usage),
35}
36
37#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
38pub struct MetaUpdate {
39 pub session_id: Option<String>,
40 pub cwd: Option<String>,
41 pub git_branch: Option<String>,
42 pub model: Option<String>,
43 pub origin: Option<Origin>,
44 pub agent_version: Option<String>,
45 pub source: Option<Value>,
47 pub originator: Option<String>,
48 pub thread_source: Option<String>,
49}
50
51#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
52pub struct Message {
53 pub role: Role,
54 pub text: String,
55 pub text_segments: Vec<std::ops::Range<usize>>,
56 pub is_meta: bool,
57 pub is_sidechain: bool,
58 pub parent_id: Option<String>,
59}
60impl Message {
61 pub fn first_text(&self) -> Option<&str> {
63 self.text.get(self.text_segments.first()?.clone())
64 }
65}
66
67#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
68pub struct ToolCall {
69 pub kind: crate::ToolCallKind,
70 pub id: Option<String>,
71 pub name: String,
72 pub arguments: ToolArgs,
73}
74
75#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
76#[non_exhaustive]
77pub enum ToolArgs {
78 Json(Value),
79 RawString(String),
80 Missing,
81}
82
83#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
84pub struct ToolResult {
85 pub call_id: Option<String>,
86 pub is_error: Option<bool>,
87 pub text: String,
88 #[serde(default, skip_serializing_if = "Option::is_none")]
90 pub output: Option<Value>,
91}
92
93#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
94pub struct Usage {
95 pub adjustments: Vec<crate::UsageAdjustment>,
96 pub dedup_key: Option<String>,
99 pub model: Option<String>,
100 pub counts: TokenCounts,
101 pub cumulative: Option<TokenCounts>,
102 pub semantics: TokenSemantics,
103 pub basis: UsageBasis,
104 pub stop_reason: Option<String>,
105 pub endpoint: Endpoint,
106 pub inference_geo: Option<String>,
108}
109
110#[derive(Debug, Clone, Copy, PartialEq, Eq)]
113pub struct EventKinds(u8);
114impl Default for EventKinds {
115 fn default() -> Self {
116 Self::ALL
117 }
118}
119impl EventKinds {
120 pub const META: Self = Self(1);
121 pub const MESSAGE: Self = Self(2);
122 pub const TOOL_CALL: Self = Self(4);
123 pub const TOOL_RESULT: Self = Self(8);
124 pub const USAGE: Self = Self(16);
125 pub const ALL: Self = Self(31);
126 pub fn contains(self, other: Self) -> bool {
127 self.0 & other.0 == other.0
128 }
129 pub fn union(self, other: Self) -> Self {
130 Self(self.0 | other.0)
131 }
132 pub(crate) fn includes(self, event: &Event) -> bool {
133 let bit = match event {
134 Event::Meta(_) => 1,
135 Event::Message(_) => 2,
136 Event::ToolCall(_) => 4,
137 Event::ToolResult(_) => 8,
138 Event::Usage(_) => 16,
139 };
140 self.0 & bit != 0
141 }
142}