1use std::fmt;
2use std::{path::Path, sync::Arc};
3
4use serde::{Deserialize, Serialize};
5use util::rel_path::RelPath;
6
7#[derive(Debug, Clone, Serialize)]
8pub struct AutocompleteRequest {
9 pub debug_info: Arc<str>,
10 pub repo_name: String,
11 pub branch: Option<String>,
12 pub file_path: Arc<Path>,
13 pub file_contents: String,
14 pub recent_changes: String,
15 pub cursor_position: usize,
16 pub original_file_contents: String,
17 pub file_chunks: Vec<FileChunk>,
18 pub retrieval_chunks: Vec<RetrievalChunk>,
19 pub recent_user_actions: Vec<UserAction>,
20 pub multiple_suggestions: bool,
21 pub privacy_mode_enabled: bool,
22 pub changes_above_cursor: bool,
23}
24
25#[derive(Debug, Clone, Serialize)]
26pub struct FileChunk {
27 pub file_path: String,
28 pub start_line: usize,
29 pub end_line: usize,
30 pub content: String,
31 pub timestamp: Option<u64>,
32}
33
34#[derive(Debug, Clone, Serialize)]
35pub struct RetrievalChunk {
36 pub file_path: String,
37 pub start_line: usize,
38 pub end_line: usize,
39 pub content: String,
40 pub timestamp: u64,
41}
42
43#[derive(Debug, Clone, Serialize)]
44pub struct UserAction {
45 pub action_type: ActionType,
46 pub line_number: usize,
47 pub offset: usize,
48 pub file_path: String,
49 pub timestamp: u64,
50}
51
52#[allow(dead_code)]
53#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize)]
54#[serde(rename_all = "SCREAMING_SNAKE_CASE")]
55pub enum ActionType {
56 CursorMovement,
57 InsertChar,
58 DeleteChar,
59 InsertSelection,
60 DeleteSelection,
61}
62
63#[derive(Debug, Clone, Deserialize)]
64pub struct AutocompleteResponse {
65 pub autocomplete_id: String,
66 pub start_index: usize,
67 pub end_index: usize,
68 pub completion: String,
69 #[allow(dead_code)]
70 pub confidence: f64,
71 #[allow(dead_code)]
72 pub logprobs: Option<serde_json::Value>,
73 #[allow(dead_code)]
74 pub finish_reason: Option<String>,
75 #[allow(dead_code)]
76 pub elapsed_time_ms: u64,
77 #[allow(dead_code)]
78 #[serde(default, rename = "completions")]
79 pub additional_completions: Vec<AdditionalCompletion>,
80}
81
82#[allow(dead_code)]
83#[derive(Debug, Clone, Deserialize)]
84pub struct AdditionalCompletion {
85 pub start_index: usize,
86 pub end_index: usize,
87 pub completion: String,
88 pub confidence: f64,
89 pub autocomplete_id: String,
90 pub logprobs: Option<serde_json::Value>,
91 pub finish_reason: Option<String>,
92}
93
94pub(crate) fn write_event(event: crate::Event, f: &mut impl fmt::Write) -> fmt::Result {
95 match event {
96 crate::Event::BufferChange {
97 old_snapshot,
98 new_snapshot,
99 ..
100 } => {
101 let old_path = old_snapshot
102 .file()
103 .map(|f| f.path().as_ref())
104 .unwrap_or(RelPath::unix("untitled").unwrap());
105 let new_path = new_snapshot
106 .file()
107 .map(|f| f.path().as_ref())
108 .unwrap_or(RelPath::unix("untitled").unwrap());
109 if old_path != new_path {
110 // TODO confirm how to do this for sweep
111 // writeln!(f, "User renamed {:?} to {:?}\n", old_path, new_path)?;
112 }
113
114 let diff = language::unified_diff(&old_snapshot.text(), &new_snapshot.text());
115 if !diff.is_empty() {
116 write!(
117 f,
118 "File: {}:\n{}\n",
119 new_path.display(util::paths::PathStyle::Posix),
120 diff
121 )?
122 }
123
124 fmt::Result::Ok(())
125 }
126 }
127}
128
129pub(crate) fn debug_info(cx: &gpui::App) -> Arc<str> {
130 format!(
131 "Zed v{version} ({sha}) - OS: {os} - Zed v{version}",
132 version = release_channel::AppVersion::global(cx),
133 sha = release_channel::AppCommitSha::try_global(cx)
134 .map_or("unknown".to_string(), |sha| sha.full()),
135 os = client::telemetry::os_name(),
136 )
137 .into()
138}