Add GitHub Copilot Chat Support (#14842)
# Summary This commit implements Github Copilot Chat support within the existing Assistant panel/framework. It required a little bit of trickery and internal API modification, as Copilot doesn't use the same authentication-style as all of the existing providers, opting to use OAuth and a short lived API key instead of a straight API key. All existing Assistant features should work. Release Notes: - Added Github Copilot Chat support ([#4673](https://github.com/zed-industries/zed/issues/4673)). ## Screenshots <img width="1552" alt="A screenshot showing a conversation between a user and Github Copilot Chat within the Zed editor." src="https://github.com/user-attachments/assets/73eaf6a2-792b-4c40-a7fe-f763bd6417d7"> --------- Co-authored-by: Bennet Bo Fenner <bennet@zed.dev>
This commit is contained in:
parent
d93891ba63
commit
6f0655810e
14 changed files with 808 additions and 14 deletions
|
@ -1,7 +1,9 @@
|
|||
pub mod copilot_chat;
|
||||
mod copilot_completion_provider;
|
||||
pub mod request;
|
||||
mod sign_in;
|
||||
|
||||
use ::fs::Fs;
|
||||
use anyhow::{anyhow, Context as _, Result};
|
||||
use async_compression::futures::bufread::GzipDecoder;
|
||||
use async_tar::Archive;
|
||||
|
@ -27,6 +29,7 @@ use settings::SettingsStore;
|
|||
use smol::{fs, io::BufReader, stream::StreamExt};
|
||||
use std::{
|
||||
any::TypeId,
|
||||
env,
|
||||
ffi::OsString,
|
||||
mem,
|
||||
ops::Range,
|
||||
|
@ -52,10 +55,13 @@ actions!(
|
|||
|
||||
pub fn init(
|
||||
new_server_id: LanguageServerId,
|
||||
fs: Arc<dyn Fs>,
|
||||
http: Arc<dyn HttpClient>,
|
||||
node_runtime: Arc<dyn NodeRuntime>,
|
||||
cx: &mut AppContext,
|
||||
) {
|
||||
copilot_chat::init(fs, http.clone(), cx);
|
||||
|
||||
let copilot = cx.new_model({
|
||||
let node_runtime = node_runtime.clone();
|
||||
move |cx| Copilot::start(new_server_id, http, node_runtime, cx)
|
||||
|
@ -185,6 +191,10 @@ impl Status {
|
|||
pub fn is_authorized(&self) -> bool {
|
||||
matches!(self, Status::Authorized)
|
||||
}
|
||||
|
||||
pub fn is_disabled(&self) -> bool {
|
||||
matches!(self, Status::Disabled)
|
||||
}
|
||||
}
|
||||
|
||||
struct RegisteredBuffer {
|
||||
|
@ -301,6 +311,8 @@ pub struct Copilot {
|
|||
|
||||
pub enum Event {
|
||||
CopilotLanguageServerStarted,
|
||||
CopilotAuthSignedIn,
|
||||
CopilotAuthSignedOut,
|
||||
}
|
||||
|
||||
impl EventEmitter<Event> for Copilot {}
|
||||
|
@ -581,7 +593,7 @@ impl Copilot {
|
|||
}
|
||||
}
|
||||
|
||||
fn sign_out(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
pub fn sign_out(&mut self, cx: &mut ModelContext<Self>) -> Task<Result<()>> {
|
||||
self.update_sign_in_status(request::SignInStatus::NotSignedIn, cx);
|
||||
if let CopilotServer::Running(RunningCopilotServer { lsp: server, .. }) = &self.server {
|
||||
let server = server.clone();
|
||||
|
@ -928,6 +940,7 @@ impl Copilot {
|
|||
| request::SignInStatus::MaybeOk { .. }
|
||||
| request::SignInStatus::AlreadySignedIn { .. } => {
|
||||
server.sign_in_status = SignInStatus::Authorized;
|
||||
cx.emit(Event::CopilotAuthSignedIn);
|
||||
for buffer in self.buffers.iter().cloned().collect::<Vec<_>>() {
|
||||
if let Some(buffer) = buffer.upgrade() {
|
||||
self.register_buffer(&buffer, cx);
|
||||
|
@ -942,6 +955,7 @@ impl Copilot {
|
|||
}
|
||||
request::SignInStatus::Ok { user: None } | request::SignInStatus::NotSignedIn => {
|
||||
server.sign_in_status = SignInStatus::SignedOut;
|
||||
cx.emit(Event::CopilotAuthSignedOut);
|
||||
for buffer in self.buffers.iter().cloned().collect::<Vec<_>>() {
|
||||
self.unregister_buffer(&buffer);
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue