From 828597024e85518fc41ea1ead22945f5478b913d Mon Sep 17 00:00:00 2001 From: Yeachan-Heo Date: Wed, 1 Apr 2026 05:45:28 +0000 Subject: [PATCH] wip: telemetry claude code matching --- rust/crates/api/tests/client_integration.rs | 17 ++++++++++---- rust/crates/telemetry/src/lib.rs | 25 +++++++++++++++------ 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/rust/crates/api/tests/client_integration.rs b/rust/crates/api/tests/client_integration.rs index d95dba8..569c2fa 100644 --- a/rust/crates/api/tests/client_integration.rs +++ b/rust/crates/api/tests/client_integration.rs @@ -71,7 +71,11 @@ async fn send_message_posts_json_and_parses_response() { ); assert_eq!( request.headers.get("user-agent").map(String::as_str), - Some("clawd-code/0.1.0 (rust)") + Some("claude-code/0.1.0") + ); + assert_eq!( + request.headers.get("anthropic-beta").map(String::as_str), + Some("claude-code-20250219") ); let body: serde_json::Value = serde_json::from_str(&request.body).expect("request body should be json"); @@ -82,6 +86,7 @@ async fn send_message_posts_json_and_parses_response() { assert!(body.get("stream").is_none()); assert_eq!(body["tools"][0]["name"], json!("get_weather")); assert_eq!(body["tool_choice"]["type"], json!("auto")); + assert_eq!(body["betas"], json!(["claude-code-20250219"])); } #[tokio::test] @@ -112,7 +117,7 @@ async fn send_message_applies_request_profile_and_records_telemetry() { let client = AnthropicClient::new("test-key") .with_base_url(server.base_url()) - .with_client_identity(ClientIdentity::new("clawd-code", "9.9.9").with_runtime("rust-cli")) + .with_client_identity(ClientIdentity::new("claude-code", "9.9.9").with_runtime("rust-cli")) .with_beta("tools-2026-04-01") .with_extra_body_param("metadata", json!({"source": "clawd-code"})) .with_session_tracer(SessionTracer::new("session-telemetry", sink.clone())); @@ -128,15 +133,19 @@ async fn send_message_applies_request_profile_and_records_telemetry() { let request = captured.first().expect("server should capture request"); assert_eq!( request.headers.get("anthropic-beta").map(String::as_str), - Some("tools-2026-04-01") + Some("claude-code-20250219,tools-2026-04-01") ); assert_eq!( request.headers.get("user-agent").map(String::as_str), - Some("clawd-code/9.9.9 (rust-cli)") + Some("claude-code/9.9.9") ); let body: serde_json::Value = serde_json::from_str(&request.body).expect("request body should be json"); assert_eq!(body["metadata"]["source"], json!("clawd-code")); + assert_eq!( + body["betas"], + json!(["claude-code-20250219", "tools-2026-04-01"]) + ); let events = sink.events(); assert_eq!(events.len(), 4); diff --git a/rust/crates/telemetry/src/lib.rs b/rust/crates/telemetry/src/lib.rs index e7bf6e2..4a471cc 100644 --- a/rust/crates/telemetry/src/lib.rs +++ b/rust/crates/telemetry/src/lib.rs @@ -10,8 +10,9 @@ use serde::{Deserialize, Serialize}; use serde_json::{Map, Value}; pub const DEFAULT_ANTHROPIC_VERSION: &str = "2023-06-01"; -pub const DEFAULT_APP_NAME: &str = "clawd-code"; +pub const DEFAULT_APP_NAME: &str = "claude-code"; pub const DEFAULT_RUNTIME: &str = "rust"; +pub const DEFAULT_AGENTIC_BETA: &str = "claude-code-20250219"; #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] pub struct ClientIdentity { @@ -38,7 +39,7 @@ impl ClientIdentity { #[must_use] pub fn user_agent(&self) -> String { - format!("{}/{} ({})", self.app_name, self.app_version, self.runtime) + format!("{}/{}", self.app_name, self.app_version) } } @@ -64,7 +65,7 @@ impl AnthropicRequestProfile { Self { anthropic_version: DEFAULT_ANTHROPIC_VERSION.to_string(), client_identity, - betas: Vec::new(), + betas: vec![DEFAULT_AGENTIC_BETA.to_string()], extra_body: Map::new(), } } @@ -110,6 +111,12 @@ impl AnthropicRequestProfile { for (key, value) in &self.extra_body { object.insert(key.clone(), value.clone()); } + if !self.betas.is_empty() { + object.insert( + "betas".to_string(), + Value::Array(self.betas.iter().cloned().map(Value::String).collect()), + ); + } Ok(body) } } @@ -423,7 +430,7 @@ mod tests { #[test] fn request_profile_emits_headers_and_merges_body() { let profile = AnthropicRequestProfile::new( - ClientIdentity::new("clawd-code", "1.2.3").with_runtime("rust-cli"), + ClientIdentity::new("claude-code", "1.2.3").with_runtime("rust-cli"), ) .with_beta("tools-2026-04-01") .with_extra_body("metadata", serde_json::json!({"source": "test"})); @@ -435,11 +442,11 @@ mod tests { "anthropic-version".to_string(), DEFAULT_ANTHROPIC_VERSION.to_string() ), + ("user-agent".to_string(), "claude-code/1.2.3".to_string()), ( - "user-agent".to_string(), - "clawd-code/1.2.3 (rust-cli)".to_string() + "anthropic-beta".to_string(), + "claude-code-20250219,tools-2026-04-01".to_string(), ), - ("anthropic-beta".to_string(), "tools-2026-04-01".to_string(),), ] ); @@ -450,6 +457,10 @@ mod tests { body["metadata"]["source"], Value::String("test".to_string()) ); + assert_eq!( + body["betas"], + serde_json::json!(["claude-code-20250219", "tools-2026-04-01"]) + ); } #[test]