Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions apps/aether-gateway/src/data/state/integrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const MAX_RESPONSE_BODY_SIZE_KEY: &str = "max_response_body_size";

fn usage_request_record_level_from_value(value: Option<&Value>) -> UsageRequestRecordLevel {
let Some(value) = value.and_then(Value::as_str).map(str::trim) else {
return UsageRequestRecordLevel::Full;
return UsageRequestRecordLevel::Basic;
};

if value.eq_ignore_ascii_case("basic")
Expand Down Expand Up @@ -423,14 +423,14 @@ mod tests {
}

#[tokio::test]
async fn usage_runtime_access_defaults_missing_request_record_level_to_full() {
async fn usage_runtime_access_defaults_missing_request_record_level_to_basic() {
let state = GatewayDataState::disabled();

let level = UsageRuntimeAccess::request_record_level(&state)
.await
.expect("missing request record level should fall back");

assert_eq!(level, UsageRequestRecordLevel::Full);
assert_eq!(level, UsageRequestRecordLevel::Basic);
}

#[tokio::test]
Expand All @@ -444,7 +444,7 @@ mod tests {
.await
.expect("body capture policy should read");

assert_eq!(policy.record_level, UsageRequestRecordLevel::Full);
assert_eq!(policy.record_level, UsageRequestRecordLevel::Basic);
assert_eq!(policy.max_request_body_bytes, Some(1234));
assert_eq!(policy.max_response_body_bytes, Some(5678));
}
Expand Down
32 changes: 20 additions & 12 deletions apps/aether-gateway/src/execution_runtime/stream/execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5550,14 +5550,18 @@ mod tests {
async fn execute_stream_from_frame_stream_decodes_non_success_windsurf_connect_error_body() {
let usage_repository = Arc::new(InMemoryUsageReadRepository::default());
let request_candidate_repository = Arc::new(InMemoryRequestCandidateRepository::default());
let data_state =
crate::data::GatewayDataState::with_request_candidate_and_usage_repository_for_tests(
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]);
let state = AppState::new()
.expect("app state should build")
.with_data_state_for_tests(
crate::data::GatewayDataState::with_request_candidate_and_usage_repository_for_tests(
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
),
)
.with_data_state_for_tests(data_state)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
..UsageRuntimeConfig::default()
Expand Down Expand Up @@ -6586,14 +6590,18 @@ mod tests {

let usage_repository = Arc::new(InMemoryUsageReadRepository::default());
let request_candidate_repository = Arc::new(InMemoryRequestCandidateRepository::default());
let data_state =
crate::data::GatewayDataState::with_request_candidate_and_usage_repository_for_tests(
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]);
let state = AppState::new()
.expect("app state should build")
.with_data_state_for_tests(
crate::data::GatewayDataState::with_request_candidate_and_usage_repository_for_tests(
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
),
)
.with_data_state_for_tests(data_state)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
..UsageRuntimeConfig::default()
Expand Down
58 changes: 43 additions & 15 deletions apps/aether-gateway/src/tests/usage/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -335,7 +335,11 @@ async fn gateway_truncates_deep_request_echo_for_local_openai_chat_sync_usage_im
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -491,10 +495,10 @@ async fn gateway_applies_system_max_request_body_size_to_local_openai_chat_sync_
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
)
.with_system_config_values_for_tests([(
"max_request_body_size".to_string(),
json!(128),
)]),
.with_system_config_values_for_tests([
("request_record_level".to_string(), json!("full")),
("max_request_body_size".to_string(), json!(128)),
]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -769,7 +773,11 @@ async fn gateway_records_failed_usage_when_all_local_openai_chat_candidates_exha
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -895,7 +903,11 @@ async fn gateway_records_failed_usage_when_sync_runtime_transport_is_unavailable
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -1070,7 +1082,11 @@ async fn gateway_records_failed_usage_for_claude_runtime_miss_without_execution_
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -1273,7 +1289,11 @@ async fn gateway_handles_local_openai_chat_stream_report_with_local_reporting_wh
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -1445,10 +1465,10 @@ async fn gateway_preserves_stream_usage_when_max_response_body_size_truncates_ca
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
)
.with_system_config_values_for_tests([(
"max_response_body_size".to_string(),
json!(128),
)]),
.with_system_config_values_for_tests([
("request_record_level".to_string(), json!("full")),
("max_response_body_size".to_string(), json!(128)),
]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -1699,7 +1719,11 @@ async fn gateway_records_failed_usage_when_all_local_claude_cli_candidates_are_s
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down Expand Up @@ -2001,7 +2025,11 @@ fn gateway_keeps_failed_usage_request_capture_lightweight_for_large_local_claude
Arc::clone(&request_candidate_repository),
Arc::clone(&usage_repository),
DEVELOPMENT_ENCRYPTION_KEY,
),
)
.with_system_config_values_for_tests([(
"request_record_level".to_string(),
json!("full"),
)]),
)
.with_usage_runtime_for_tests(UsageRuntimeConfig {
enabled: true,
Expand Down
19 changes: 5 additions & 14 deletions crates/aether-usage-runtime/src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ pub trait UsageBillingEventEnricher: Send + Sync {

#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum UsageRequestRecordLevel {
Basic,
#[default]
Basic,
Full,
}

Expand All @@ -44,7 +44,7 @@ pub struct UsageBodyCapturePolicy {
impl Default for UsageBodyCapturePolicy {
fn default() -> Self {
Self {
record_level: UsageRequestRecordLevel::Full,
record_level: UsageRequestRecordLevel::Basic,
max_request_body_bytes: Some(DEFAULT_USAGE_REQUEST_BODY_CAPTURE_LIMIT_BYTES),
max_response_body_bytes: Some(DEFAULT_USAGE_RESPONSE_BODY_CAPTURE_LIMIT_BYTES),
}
Expand Down Expand Up @@ -559,10 +559,7 @@ mod tests {
use async_trait::async_trait;
use serde_json::json;

use super::{
UsageBillingEventEnricher, UsageBodyCapturePolicy, UsageRequestRecordLevel,
UsageRuntimeAccess,
};
use super::{UsageBillingEventEnricher, UsageBodyCapturePolicy, UsageRuntimeAccess};
use crate::worker::ManualProxyNodeCounter;
use crate::{
apply_usage_body_capture_policy_to_event, UsageEvent, UsageEventData, UsageEventType,
Expand Down Expand Up @@ -763,7 +760,7 @@ mod tests {
}

#[test]
fn basic_request_record_level_strips_body_capture_but_preserves_derived_fields() {
fn default_body_capture_policy_strips_body_capture_but_preserves_derived_fields() {
let mut event = UsageEvent::new(
UsageEventType::Failed,
"req-basic-1",
Expand All @@ -788,13 +785,7 @@ mod tests {
},
);

apply_usage_body_capture_policy_to_event(
UsageBodyCapturePolicy {
record_level: UsageRequestRecordLevel::Basic,
..UsageBodyCapturePolicy::default()
},
&mut event,
);
apply_usage_body_capture_policy_to_event(UsageBodyCapturePolicy::default(), &mut event);

assert_eq!(event.data.total_tokens, Some(42));
assert_eq!(event.data.error_message.as_deref(), Some("upstream failed"));
Expand Down
Loading