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}
69
70#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
71pub struct EditorEvent {
72 pub operation: String,
73 pub file_extension: Option<String>,
74 pub vim_mode: bool,
75 pub copilot_enabled: bool,
76 pub copilot_enabled_for_language: bool,
77}
78
79// Needed for clients sending old copilot_event types
80#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
81pub struct CopilotEvent {
82 pub suggestion_id: Option<String>,
83 pub suggestion_accepted: bool,
84 pub file_extension: Option<String>,
85}
86
87#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
88pub struct InlineCompletionEvent {
89 pub provider: String,
90 pub suggestion_accepted: bool,
91 pub file_extension: Option<String>,
92}
93
94#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
95pub struct CallEvent {
96 pub operation: String,
97 pub room_id: Option<u64>,
98 pub channel_id: Option<u64>,
99}
100
101#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
102pub struct AssistantEvent {
103 pub conversation_id: Option<String>,
104 pub kind: AssistantKind,
105 pub model: String,
106 pub response_latency: Option<Duration>,
107 pub error_message: Option<String>,
108}
109
110#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
111pub struct CpuEvent {
112 pub usage_as_percentage: f32,
113 pub core_count: u32,
114}
115
116#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
117pub struct MemoryEvent {
118 pub memory_in_bytes: u64,
119 pub virtual_memory_in_bytes: u64,
120}
121
122#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
123pub struct ActionEvent {
124 pub source: String,
125 pub action: String,
126}
127
128#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
129pub struct EditEvent {
130 pub duration: i64,
131 pub environment: String,
132}
133
134#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
135pub struct SettingEvent {
136 pub setting: String,
137 pub value: String,
138}
139
140#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
141pub struct ExtensionEvent {
142 pub extension_id: Arc<str>,
143 pub version: Arc<str>,
144}
145
146#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
147pub struct AppEvent {
148 pub operation: String,
149}
150
151#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
152pub struct BacktraceFrame {
153 pub ip: usize,
154 pub symbol_addr: usize,
155 pub base: Option<usize>,
156 pub symbols: Vec<String>,
157}
158
159#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
160pub struct HangReport {
161 pub backtrace: Vec<BacktraceFrame>,
162 pub app_version: Option<SemanticVersion>,
163 pub os_name: String,
164 pub os_version: Option<String>,
165 pub architecture: String,
166 pub installation_id: Option<String>,
167}
168
169#[derive(Serialize, Deserialize)]
170pub struct LocationData {
171 pub file: String,
172 pub line: u32,
173}
174
175#[derive(Serialize, Deserialize)]
176pub struct Panic {
177 pub thread: String,
178 pub payload: String,
179 #[serde(skip_serializing_if = "Option::is_none")]
180 pub location_data: Option<LocationData>,
181 pub backtrace: Vec<String>,
182 pub app_version: String,
183 pub release_channel: String,
184 pub os_name: String,
185 pub os_version: Option<String>,
186 pub architecture: String,
187 pub panicked_on: i64,
188 #[serde(skip_serializing_if = "Option::is_none")]
189 pub installation_id: Option<String>,
190 pub session_id: String,
191}
192
193#[derive(Serialize, Deserialize)]
194pub struct PanicRequest {
195 pub panic: Panic,
196}