From c84dc392be7fe44abf5882c67966fd4a7df82b7a Mon Sep 17 00:00:00 2001 From: Gustavo Hoirisch Date: Tue, 29 Jul 2025 19:01:18 +1000 Subject: [PATCH] feat(githubcopilot): add ability to fetch supported models (#2717) Signed-off-by: Gustavo Hoirisch --- crates/goose/src/providers/githubcopilot.rs | 41 +++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/crates/goose/src/providers/githubcopilot.rs b/crates/goose/src/providers/githubcopilot.rs index 096cec58..831209b2 100644 --- a/crates/goose/src/providers/githubcopilot.rs +++ b/crates/goose/src/providers/githubcopilot.rs @@ -424,4 +424,45 @@ impl Provider for GithubCopilotProvider { emit_debug_trace(&self.model, &payload, &response, &usage); Ok((message, ProviderUsage::new(model, usage))) } + + /// Fetch supported models from GitHub Copliot; returns Err on failure, Ok(None) if not present + async fn fetch_supported_models_async(&self) -> Result>, ProviderError> { + let (endpoint, token) = self.get_api_info().await?; + let url = format!("{}/models", endpoint); + + let mut headers = http::HeaderMap::new(); + headers.insert(http::header::ACCEPT, "application/json".parse().unwrap()); + headers.insert( + http::header::CONTENT_TYPE, + "application/json".parse().unwrap(), + ); + headers.insert("Copilot-Integration-Id", "vscode-chat".parse().unwrap()); + headers.insert( + http::header::AUTHORIZATION, + format!("Bearer {}", token).parse().unwrap(), + ); + + let response = self.client.get(url).headers(headers).send().await?; + + let json: serde_json::Value = response.json().await?; + + let arr = match json.get("data").and_then(|v| v.as_array()) { + Some(arr) => arr, + None => return Ok(None), + }; + let mut models: Vec = arr + .iter() + .filter_map(|m| { + if let Some(s) = m.as_str() { + Some(s.to_string()) + } else if let Some(obj) = m.as_object() { + obj.get("id").and_then(|v| v.as_str()).map(str::to_string) + } else { + None + } + }) + .collect(); + models.sort(); + Ok(Some(models)) + } }