aiclient_api/providers/copilot/
client.rs1use anyhow::{bail, Context, Result};
2use reqwest::header::HeaderMap;
3
4use crate::config::types::AccountType;
5
6pub struct CopilotClient {
7 client: reqwest::Client,
8 base_url: String,
9}
10
11impl CopilotClient {
12 pub fn new(account_type: &AccountType) -> Self {
13 let base_url = match account_type {
14 AccountType::Individual => "https://api.githubcopilot.com",
15 AccountType::Business => "https://api.business.githubcopilot.com",
16 AccountType::Enterprise => "https://api.enterprise.githubcopilot.com",
17 }
18 .to_string();
19
20 Self {
21 client: reqwest::Client::new(),
22 base_url,
23 }
24 }
25
26 pub fn base_url(&self) -> &str {
27 &self.base_url
28 }
29
30 pub fn http_client(&self) -> &reqwest::Client {
31 &self.client
32 }
33
34 pub async fn chat_completions(
35 &self,
36 headers: HeaderMap,
37 body: serde_json::Value,
38 _stream: bool,
39 ) -> Result<reqwest::Response> {
40 let url = format!("{}/chat/completions", self.base_url);
41 let resp = self
42 .client
43 .post(&url)
44 .headers(headers)
45 .json(&body)
46 .send()
47 .await
48 .context("Failed to send chat completions request")?;
49
50 if !resp.status().is_success() {
51 let status = resp.status();
52 let err_body = resp.text().await.unwrap_or_default();
53 bail!("Chat completions request failed: HTTP {} - {}", status, err_body);
54 }
55
56 Ok(resp)
57 }
58
59 pub async fn messages(
60 &self,
61 headers: HeaderMap,
62 body: serde_json::Value,
63 _stream: bool,
64 ) -> Result<reqwest::Response> {
65 let url = format!("{}/v1/messages", self.base_url);
66 let resp = self
67 .client
68 .post(&url)
69 .headers(headers)
70 .json(&body)
71 .send()
72 .await
73 .context("Failed to send messages request")?;
74
75 if !resp.status().is_success() {
76 let status = resp.status();
77 let err_body = resp.text().await.unwrap_or_default();
78 bail!("Messages request failed: HTTP {} - {}", status, err_body);
79 }
80
81 Ok(resp)
82 }
83}