use anthropic_async::AnthropicConfig;
use anthropic_async::Client;
use anthropic_async::types::common::*;
use anthropic_async::types::content::*;
use anthropic_async::types::messages::*;
use serde_json::json;
use wiremock::Mock;
use wiremock::MockServer;
use wiremock::ResponseTemplate;
use wiremock::matchers::header;
use wiremock::matchers::header_exists;
use wiremock::matchers::method;
use wiremock::matchers::path;
#[tokio::test]
async fn test_messages_create_with_caching() {
let server = MockServer::start().await;
Mock::given(method("POST"))
.and(path("/v1/messages"))
.and(header_exists("x-api-key"))
.and(header("anthropic-version", "2023-06-01"))
.respond_with(ResponseTemplate::new(200).set_body_json(json!({
"id": "msg_123",
"type": "message",
"role": "assistant",
"content": [{
"type": "text",
"text": "Hello!"
}],
"model": "claude-3-5-sonnet",
"usage": {
"input_tokens": 100,
"output_tokens": 10,
"cache_creation_input_tokens": 80,
"cache_read_input_tokens": 0
}
})))
.mount(&server)
.await;
let req = MessagesCreateRequest {
model: "claude-3-5-sonnet".into(),
max_tokens: 64,
system: Some(SystemParam::Blocks(vec![
TextBlockParam::with_cache_control("You are helpful", CacheControl::ephemeral_1h()),
])),
messages: vec![MessageParam {
role: MessageRole::User,
content: MessageContentParam::Blocks(vec![ContentBlockParam::Text {
text: "Hello".into(),
citations: None,
cache_control: Some(CacheControl::ephemeral_5m()),
}]),
}],
..Default::default()
};
let cfg = AnthropicConfig::new()
.with_api_key("test-key")
.with_api_base(server.uri());
let client = Client::with_config(cfg);
let response = client.messages().create(req).await.unwrap();
assert_eq!(response.kind, "message");
assert_eq!(
response.usage.unwrap().cache_creation_input_tokens.unwrap(),
80
);
}
#[tokio::test]
async fn test_ttl_ordering_validation() {
let server = MockServer::start().await;
let req = MessagesCreateRequest {
model: "claude-3-5-sonnet".into(),
max_tokens: 64,
system: Some(SystemParam::Blocks(vec![
TextBlockParam::with_cache_control(
"System",
CacheControl::ephemeral_5m(), ),
])),
messages: vec![MessageParam {
role: MessageRole::User,
content: MessageContentParam::Blocks(vec![ContentBlockParam::Text {
text: "User".into(),
citations: None,
cache_control: Some(CacheControl::ephemeral_1h()), }]),
}],
..Default::default()
};
let cfg = AnthropicConfig::new()
.with_api_key("test-key")
.with_api_base(server.uri());
let client = Client::with_config(cfg);
let err = client.messages().create(req).await.unwrap_err();
match err {
anthropic_async::AnthropicError::Config(msg) => {
assert!(msg.contains("TTL ordering"));
}
_ => panic!("Expected Config error"),
}
}