zeta2: Send snapshot event (#50126)

Ben Kunkle created

Closes #ISSUE

Before you mark this PR as ready for review, make sure that you have:
- [ ] Added a solid test coverage and/or screenshots from doing manual
testing
- [ ] Done a self-review taking into account security and performance
aspects
- [ ] Aligned any UI changes with the [UI
checklist](https://github.com/zed-industries/zed/blob/main/CONTRIBUTING.md#uiux-checklist)

Release Notes:

- N/A *or* Added/Fixed/Improved ...

Change summary

crates/edit_prediction/src/cursor_excerpt.rs |  7 ++
crates/edit_prediction/src/zeta.rs           | 45 ++++++++++++++++++++++
2 files changed, 50 insertions(+), 2 deletions(-)

Detailed changes

crates/edit_prediction/src/cursor_excerpt.rs 🔗

@@ -13,6 +13,7 @@ pub fn compute_excerpt_ranges(
     let editable_150 = compute_editable_range(snapshot, position, 150);
     let editable_180 = compute_editable_range(snapshot, position, 180);
     let editable_350 = compute_editable_range(snapshot, position, 350);
+    let full_512 = compute_editable_range(snapshot, position, 512);
 
     let editable_150_context_350 =
         expand_context_syntactically_then_linewise(snapshot, editable_150.clone(), 350);
@@ -21,14 +22,16 @@ pub fn compute_excerpt_ranges(
     let editable_350_context_150 =
         expand_context_syntactically_then_linewise(snapshot, editable_350.clone(), 150);
 
-    let full_start_row = editable_150_context_350
+    let full_start_row = full_512
         .start
         .row
+        .min(editable_150_context_350.start.row)
         .min(editable_180_context_350.start.row)
         .min(editable_350_context_150.start.row);
-    let full_end_row = editable_150_context_350
+    let full_end_row = full_512
         .end
         .row
+        .max(editable_150_context_350.end.row)
         .max(editable_180_context_350.end.row)
         .max(editable_350_context_150.end.row);
 

crates/edit_prediction/src/zeta.rs 🔗

@@ -308,6 +308,8 @@ pub fn request_prediction_with_zeta(
                         edits,
                         cursor_position,
                         received_response_at,
+                        full_context_offset_range,
+                        editable_range_in_buffer,
                     )),
                 )),
                 usage,
@@ -329,6 +331,8 @@ pub fn request_prediction_with_zeta(
             edits,
             cursor_position,
             received_response_at,
+            full_context_offset_range,
+            editable_range_in_buffer,
         )) = prediction
         else {
             return Ok(Some(EditPredictionResult {
@@ -337,6 +341,47 @@ pub fn request_prediction_with_zeta(
             }));
         };
 
+        if can_collect_data {
+            cx.spawn({
+                let weak_buffer = edited_buffer.downgrade();
+                let context_anchor_range =
+                    edited_buffer_snapshot.anchor_range_around(full_context_offset_range);
+                let editable_anchor_range =
+                    edited_buffer_snapshot.anchor_range_around(editable_range_in_buffer);
+                let request_id = id.0.clone();
+                async move |cx| {
+                    cx.background_executor()
+                        .timer(std::time::Duration::from_secs(30))
+                        .await;
+
+                    let Some(buffer) = weak_buffer.upgrade() else {
+                        return;
+                    };
+                    let (new_cursor_region, editable_range_in_excerpt) =
+                        buffer.read_with(cx, |buffer, _| {
+                            let context_start =
+                                buffer.offset_for_anchor(&context_anchor_range.start);
+                            let editable_range_in_excerpt = (buffer
+                                .offset_for_anchor(&editable_anchor_range.start)
+                                - context_start)
+                                ..(buffer.offset_for_anchor(&editable_anchor_range.end)
+                                    - context_start);
+                            let text = buffer
+                                .text_for_range(context_anchor_range)
+                                .collect::<String>();
+                            (text, editable_range_in_excerpt)
+                        });
+                    telemetry::event!(
+                        "Edit Prediction Snapshot",
+                        request_id,
+                        new_cursor_region,
+                        editable_range_in_excerpt,
+                    );
+                }
+            })
+            .detach();
+        }
+
         Ok(Some(
             EditPredictionResult::new(
                 id,