copilot: Indicate whether a request is initiated by an agent to Copilot API (#33895)

Per [GitHub's documentation for VSCode's agent
mode](https://docs.github.com/en/copilot/how-tos/chat/asking-github-copilot-questions-in-your-ide#agent-mode),
a premium request is charged per user-submitted prompt. rather than per
individual request the agent makes to an LLM. This PR matches Zed's
functionality to VSCode's, accurately indicating to GitHub's API whether
a given request is initiated by the user or by an agent, allowing a user
to be metered only for prompts they send.

See also: #31068

Release Notes:

- Improve Copilot premium request tracking
This commit is contained in:
Liam 2025-07-07 08:24:17 +00:00 committed by GitHub
parent 6b456ede49
commit 83562fca77
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 30 additions and 3 deletions

View file

@ -528,6 +528,7 @@ impl CopilotChat {
pub async fn stream_completion(
request: Request,
is_user_initiated: bool,
mut cx: AsyncApp,
) -> Result<BoxStream<'static, Result<ResponseEvent>>> {
let this = cx
@ -562,7 +563,14 @@ impl CopilotChat {
};
let api_url = configuration.api_url_from_endpoint(&token.api_endpoint);
stream_completion(client.clone(), token.api_key, api_url.into(), request).await
stream_completion(
client.clone(),
token.api_key,
api_url.into(),
request,
is_user_initiated,
)
.await
}
pub fn set_configuration(
@ -697,6 +705,7 @@ async fn stream_completion(
api_key: String,
completion_url: Arc<str>,
request: Request,
is_user_initiated: bool,
) -> Result<BoxStream<'static, Result<ResponseEvent>>> {
let is_vision_request = request.messages.iter().any(|message| match message {
ChatMessage::User { content }
@ -707,6 +716,8 @@ async fn stream_completion(
_ => false,
});
let request_initiator = if is_user_initiated { "user" } else { "agent" };
let mut request_builder = HttpRequest::builder()
.method(Method::POST)
.uri(completion_url.as_ref())
@ -719,7 +730,8 @@ async fn stream_completion(
)
.header("Authorization", format!("Bearer {}", api_key))
.header("Content-Type", "application/json")
.header("Copilot-Integration-Id", "vscode-chat");
.header("Copilot-Integration-Id", "vscode-chat")
.header("X-Initiator", request_initiator);
if is_vision_request {
request_builder =