1use semantic_version::SemanticVersion;
2use serde::{Deserialize, Serialize};
3use std::{fmt::Display, sync::Arc, time::Duration};
4
5#[derive(Serialize, Deserialize, Debug)]
6pub struct EventRequestBody {
7 pub installation_id: Option<String>,
8 pub metrics_id: Option<String>,
9 pub session_id: Option<String>,
10 pub is_staff: Option<bool>,
11 pub app_version: String,
12 pub os_name: String,
13 pub os_version: Option<String>,
14 pub architecture: String,
15 pub release_channel: Option<String>,
16 pub events: Vec<EventWrapper>,
17}
18
19impl EventRequestBody {
20 pub fn semver(&self) -> Option<SemanticVersion> {
21 self.app_version.parse().ok()
22 }
23}
24
25#[derive(Serialize, Deserialize, Debug)]
26pub struct EventWrapper {
27 pub signed_in: bool,
28 pub milliseconds_since_first_event: i64,
29 #[serde(flatten)]
30 pub event: Event,
31}
32
33#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
34#[serde(rename_all = "snake_case")]
35pub enum AssistantKind {
36 Panel,
37 Inline,
38}
39
40impl Display for AssistantKind {
41 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
42 write!(
43 f,
44 "{}",
45 match self {
46 Self::Panel => "panel",
47 Self::Inline => "inline",
48 }
49 )
50 }
51}
52
53#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
54#[serde(tag = "type")]
55pub enum Event {
56 Editor(EditorEvent),
57 Copilot(CopilotEvent), // Needed for clients sending old copilot_event types
58 InlineCompletion(InlineCompletionEvent),
59 Call(CallEvent),
60 Assistant(AssistantEvent),
61 Cpu(CpuEvent),
62 Memory(MemoryEvent),
63 App(AppEvent),
64 Setting(SettingEvent),
65 Extension(ExtensionEvent),
66 Edit(EditEvent),
67 Action(ActionEvent),
68 Repl(ReplEvent),
69}
70
71#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
72pub struct EditorEvent {
73 pub operation: String,
74 pub file_extension: Option<String>,
75 pub vim_mode: bool,
76 pub copilot_enabled: bool,
77 pub copilot_enabled_for_language: bool,
78}
79
80// Needed for clients sending old copilot_event types
81#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
82pub struct CopilotEvent {
83 pub suggestion_id: Option<String>,
84 pub suggestion_accepted: bool,
85 pub file_extension: Option<String>,
86}
87
88#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
89pub struct InlineCompletionEvent {
90 pub provider: String,
91 pub suggestion_accepted: bool,
92 pub file_extension: Option<String>,
93}
94
95#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
96pub struct CallEvent {
97 pub operation: String,
98 pub room_id: Option<u64>,
99 pub channel_id: Option<u64>,
100}
101
102#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
103pub struct AssistantEvent {
104 pub conversation_id: Option<String>,
105 pub kind: AssistantKind,
106 pub model: String,
107 pub response_latency: Option<Duration>,
108 pub error_message: Option<String>,
109}
110
111#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
112pub struct CpuEvent {
113 pub usage_as_percentage: f32,
114 pub core_count: u32,
115}
116
117#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
118pub struct MemoryEvent {
119 pub memory_in_bytes: u64,
120 pub virtual_memory_in_bytes: u64,
121}
122
123#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
124pub struct ActionEvent {
125 pub source: String,
126 pub action: String,
127}
128
129#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
130pub struct EditEvent {
131 pub duration: i64,
132 pub environment: String,
133}
134
135#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
136pub struct SettingEvent {
137 pub setting: String,
138 pub value: String,
139}
140
141#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
142pub struct ExtensionEvent {
143 pub extension_id: Arc<str>,
144 pub version: Arc<str>,
145}
146
147#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
148pub struct AppEvent {
149 pub operation: String,
150}
151
152#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
153pub struct ReplEvent {
154 pub kernel_language: String,
155 pub kernel_status: String,
156 pub repl_session_id: String,
157}
158
159#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
160pub struct BacktraceFrame {
161 pub ip: usize,
162 pub symbol_addr: usize,
163 pub base: Option<usize>,
164 pub symbols: Vec<String>,
165}
166
167#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
168pub struct HangReport {
169 pub backtrace: Vec<BacktraceFrame>,
170 pub app_version: Option<SemanticVersion>,
171 pub os_name: String,
172 pub os_version: Option<String>,
173 pub architecture: String,
174 pub installation_id: Option<String>,
175}
176
177#[derive(Serialize, Deserialize)]
178pub struct LocationData {
179 pub file: String,
180 pub line: u32,
181}
182
183#[derive(Serialize, Deserialize)]
184pub struct Panic {
185 pub thread: String,
186 pub payload: String,
187 #[serde(skip_serializing_if = "Option::is_none")]
188 pub location_data: Option<LocationData>,
189 pub backtrace: Vec<String>,
190 pub app_version: String,
191 pub release_channel: String,
192 pub os_name: String,
193 pub os_version: Option<String>,
194 pub architecture: String,
195 pub panicked_on: i64,
196 #[serde(skip_serializing_if = "Option::is_none")]
197 pub installation_id: Option<String>,
198 pub session_id: String,
199}
200
201#[derive(Serialize, Deserialize)]
202pub struct PanicRequest {
203 pub panic: Panic,
204}