wip: telemetry claude code matching
This commit is contained in:
@@ -71,7 +71,11 @@ async fn send_message_posts_json_and_parses_response() {
|
|||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
request.headers.get("user-agent").map(String::as_str),
|
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 =
|
let body: serde_json::Value =
|
||||||
serde_json::from_str(&request.body).expect("request body should be json");
|
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!(body.get("stream").is_none());
|
||||||
assert_eq!(body["tools"][0]["name"], json!("get_weather"));
|
assert_eq!(body["tools"][0]["name"], json!("get_weather"));
|
||||||
assert_eq!(body["tool_choice"]["type"], json!("auto"));
|
assert_eq!(body["tool_choice"]["type"], json!("auto"));
|
||||||
|
assert_eq!(body["betas"], json!(["claude-code-20250219"]));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
@@ -112,7 +117,7 @@ async fn send_message_applies_request_profile_and_records_telemetry() {
|
|||||||
|
|
||||||
let client = AnthropicClient::new("test-key")
|
let client = AnthropicClient::new("test-key")
|
||||||
.with_base_url(server.base_url())
|
.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_beta("tools-2026-04-01")
|
||||||
.with_extra_body_param("metadata", json!({"source": "clawd-code"}))
|
.with_extra_body_param("metadata", json!({"source": "clawd-code"}))
|
||||||
.with_session_tracer(SessionTracer::new("session-telemetry", sink.clone()));
|
.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");
|
let request = captured.first().expect("server should capture request");
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
request.headers.get("anthropic-beta").map(String::as_str),
|
request.headers.get("anthropic-beta").map(String::as_str),
|
||||||
Some("tools-2026-04-01")
|
Some("claude-code-20250219,tools-2026-04-01")
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
request.headers.get("user-agent").map(String::as_str),
|
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 =
|
let body: serde_json::Value =
|
||||||
serde_json::from_str(&request.body).expect("request body should be json");
|
serde_json::from_str(&request.body).expect("request body should be json");
|
||||||
assert_eq!(body["metadata"]["source"], json!("clawd-code"));
|
assert_eq!(body["metadata"]["source"], json!("clawd-code"));
|
||||||
|
assert_eq!(
|
||||||
|
body["betas"],
|
||||||
|
json!(["claude-code-20250219", "tools-2026-04-01"])
|
||||||
|
);
|
||||||
|
|
||||||
let events = sink.events();
|
let events = sink.events();
|
||||||
assert_eq!(events.len(), 4);
|
assert_eq!(events.len(), 4);
|
||||||
|
|||||||
@@ -10,8 +10,9 @@ use serde::{Deserialize, Serialize};
|
|||||||
use serde_json::{Map, Value};
|
use serde_json::{Map, Value};
|
||||||
|
|
||||||
pub const DEFAULT_ANTHROPIC_VERSION: &str = "2023-06-01";
|
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_RUNTIME: &str = "rust";
|
||||||
|
pub const DEFAULT_AGENTIC_BETA: &str = "claude-code-20250219";
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
|
||||||
pub struct ClientIdentity {
|
pub struct ClientIdentity {
|
||||||
@@ -38,7 +39,7 @@ impl ClientIdentity {
|
|||||||
|
|
||||||
#[must_use]
|
#[must_use]
|
||||||
pub fn user_agent(&self) -> String {
|
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 {
|
Self {
|
||||||
anthropic_version: DEFAULT_ANTHROPIC_VERSION.to_string(),
|
anthropic_version: DEFAULT_ANTHROPIC_VERSION.to_string(),
|
||||||
client_identity,
|
client_identity,
|
||||||
betas: Vec::new(),
|
betas: vec![DEFAULT_AGENTIC_BETA.to_string()],
|
||||||
extra_body: Map::new(),
|
extra_body: Map::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -110,6 +111,12 @@ impl AnthropicRequestProfile {
|
|||||||
for (key, value) in &self.extra_body {
|
for (key, value) in &self.extra_body {
|
||||||
object.insert(key.clone(), value.clone());
|
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)
|
Ok(body)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -423,7 +430,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn request_profile_emits_headers_and_merges_body() {
|
fn request_profile_emits_headers_and_merges_body() {
|
||||||
let profile = AnthropicRequestProfile::new(
|
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_beta("tools-2026-04-01")
|
||||||
.with_extra_body("metadata", serde_json::json!({"source": "test"}));
|
.with_extra_body("metadata", serde_json::json!({"source": "test"}));
|
||||||
@@ -435,11 +442,11 @@ mod tests {
|
|||||||
"anthropic-version".to_string(),
|
"anthropic-version".to_string(),
|
||||||
DEFAULT_ANTHROPIC_VERSION.to_string()
|
DEFAULT_ANTHROPIC_VERSION.to_string()
|
||||||
),
|
),
|
||||||
|
("user-agent".to_string(), "claude-code/1.2.3".to_string()),
|
||||||
(
|
(
|
||||||
"user-agent".to_string(),
|
"anthropic-beta".to_string(),
|
||||||
"clawd-code/1.2.3 (rust-cli)".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"],
|
body["metadata"]["source"],
|
||||||
Value::String("test".to_string())
|
Value::String("test".to_string())
|
||||||
);
|
);
|
||||||
|
assert_eq!(
|
||||||
|
body["betas"],
|
||||||
|
serde_json::json!(["claude-code-20250219", "tools-2026-04-01"])
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user