mirror of
https://github.com/fawney19/Aether.git
synced 2026-10-06 01:17:46 +08:00
Fix cache token accounting and tiered pricing
This commit is contained in:
@@ -26,6 +26,7 @@ impl UsageMapper {
|
||||
}
|
||||
}
|
||||
|
||||
apply_openai_cache_write_tokens(raw_usage, api_format, &mut usage);
|
||||
derive_missing_input_tokens(raw_usage, api_format, &mut usage);
|
||||
copy_explicit_total_tokens(raw_usage, api_format, &mut usage);
|
||||
usage.normalize_cache_creation_breakdown()
|
||||
@@ -45,6 +46,25 @@ impl UsageMapper {
|
||||
}
|
||||
}
|
||||
|
||||
fn apply_openai_cache_write_tokens(
|
||||
raw_usage: &serde_json::Value,
|
||||
api_format: &str,
|
||||
usage: &mut StandardizedUsage,
|
||||
) {
|
||||
if api_family(api_format).as_str() != "openai" {
|
||||
return;
|
||||
}
|
||||
for details_key in ["prompt_tokens_details", "input_tokens_details"] {
|
||||
if let Some(value) = raw_usage
|
||||
.get(details_key)
|
||||
.and_then(|details| details.get("cache_write_tokens"))
|
||||
{
|
||||
usage.set("cache_creation_tokens", value.clone());
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn map_usage(raw_usage: &serde_json::Value, api_format: &str) -> StandardizedUsage {
|
||||
UsageMapper::map(raw_usage, api_format, None)
|
||||
}
|
||||
@@ -148,10 +168,18 @@ fn base_mapping(api_format: &str) -> BTreeMap<String, String> {
|
||||
"prompt_tokens_details.cached_creation_tokens".to_string(),
|
||||
"cache_creation_tokens".to_string(),
|
||||
);
|
||||
mapping.insert(
|
||||
"prompt_tokens_details.cache_write_tokens".to_string(),
|
||||
"cache_creation_tokens".to_string(),
|
||||
);
|
||||
mapping.insert(
|
||||
"input_tokens_details.cached_creation_tokens".to_string(),
|
||||
"cache_creation_tokens".to_string(),
|
||||
);
|
||||
mapping.insert(
|
||||
"input_tokens_details.cache_write_tokens".to_string(),
|
||||
"cache_creation_tokens".to_string(),
|
||||
);
|
||||
mapping.insert(
|
||||
"completion_tokens_details.reasoning_tokens".to_string(),
|
||||
"reasoning_tokens".to_string(),
|
||||
@@ -370,6 +398,34 @@ mod tests {
|
||||
assert_eq!(usage.reasoning_tokens, 1);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maps_openai_responses_cache_write_tokens() {
|
||||
let usage = map_usage_from_response(
|
||||
&serde_json::json!({
|
||||
"usage": {
|
||||
"input_tokens": 32_963,
|
||||
"input_tokens_details": {
|
||||
"cache_write_tokens": 512,
|
||||
"cached_creation_tokens": 1,
|
||||
"cached_tokens": 30_336
|
||||
},
|
||||
"output_tokens": 129,
|
||||
"output_tokens_details": {
|
||||
"reasoning_tokens": 8
|
||||
},
|
||||
"total_tokens": 33_092
|
||||
}
|
||||
}),
|
||||
"openai:responses",
|
||||
);
|
||||
|
||||
assert_eq!(usage.input_tokens, 32_963);
|
||||
assert_eq!(usage.output_tokens, 129);
|
||||
assert_eq!(usage.cache_creation_tokens, 512);
|
||||
assert_eq!(usage.cache_read_tokens, 30_336);
|
||||
assert_eq!(usage.reasoning_tokens, 8);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn maps_openai_responses_usage_with_missing_input_from_total() {
|
||||
let usage = map_usage_from_response(
|
||||
|
||||
@@ -3242,6 +3242,8 @@ fn apply_explicit_request_cache_usage(value: &Value, usage: &mut EstimatedReques
|
||||
&[
|
||||
&["cache_creation_input_tokens"],
|
||||
&["cache_creation_tokens"],
|
||||
&["input_tokens_details", "cache_write_tokens"],
|
||||
&["prompt_tokens_details", "cache_write_tokens"],
|
||||
&["input_tokens_details", "cached_creation_tokens"],
|
||||
&["prompt_tokens_details", "cached_creation_tokens"],
|
||||
],
|
||||
|
||||
Reference in New Issue
Block a user