90 lines · 2.9 KB · Rust
RawDownload
use anthropic::{AnthropicError, ANTHROPIC_API_URL};use anyhow::{anyhow, Context as _, Result};use client::telemetry::Telemetry;use gpui::BackgroundExecutor;use http_client::{AsyncBody, HttpClient, Method, Request as HttpRequest};use std::env;use std::sync::Arc;use telemetry_events::{AssistantEvent, AssistantKind, AssistantPhase};use util::ResultExt; use crate::provider::anthropic::PROVIDER_ID as ANTHROPIC_PROVIDER_ID; pub fn report_assistant_event(    event: AssistantEvent,    telemetry: Option<Arc<Telemetry>>,    client: Arc<dyn HttpClient>,    model_api_key: Option<String>,    executor: &BackgroundExecutor,) {    if let Some(telemetry) = telemetry.as_ref() {        telemetry.report_assistant_event(event.clone());        if telemetry.metrics_enabled() && event.model_provider == ANTHROPIC_PROVIDER_ID {            executor                .spawn(async move {                    report_anthropic_event(event, client, model_api_key)                        .await                        .log_err();                })                .detach();        }    }} async fn report_anthropic_event(    event: AssistantEvent,    client: Arc<dyn HttpClient>,    model_api_key: Option<String>,) -> Result<(), AnthropicError> {    let api_key = match model_api_key {        Some(key) => key,        None => {            return Err(AnthropicError::Other(anyhow!(                "Anthropic API key is not set"            )));        }    };     let uri = format!("{ANTHROPIC_API_URL}/v1/log/zed");    let request_builder = HttpRequest::builder()        .method(Method::POST)        .uri(uri)        .header("X-Api-Key", api_key)        .header("Content-Type", "application/json");    let serialized_event: serde_json::Value = serde_json::json!({        "completion_type": match event.kind {            AssistantKind::Inline => "natural_language_completion_in_editor",            AssistantKind::InlineTerminal => "natural_language_completion_in_terminal",            AssistantKind::Panel => "conversation_message",        },        "event": match event.phase {            AssistantPhase::Response => "response",            AssistantPhase::Invoked => "invoke",            AssistantPhase::Accepted => "accept",            AssistantPhase::Rejected => "reject",        },        "metadata": {            "language_name": event.language_name,            "message_id": event.message_id,            "platform": env::consts::OS,        }    });     let request = request_builder        .body(AsyncBody::from(serialized_event.to_string()))        .context("failed to construct request body")?;     let response = client        .send(request)        .await        .context("failed to send request to Anthropic")?;     if response.status().is_success() {        return Ok(());    }     return Err(AnthropicError::Other(anyhow!(        "Failed to log: {}",        response.status(),    )));}