mirror of
https://github.com/fawney19/Aether.git
synced 2026-09-02 01:10:23 +08:00
fix: 修正时间戳精度、TTL 定价匹配逻辑及账单快照展示
- 将 created_at_unix_ms 从 current_unix_secs 改为 current_unix_ms,修正候选尝试和跳过记录的时间戳精度 - formula_engine: TTL 定价从「<=上限」模糊匹配改为精确匹配,null 值改为回退到基础价格而非透传 - 新增 ttl_pricing_requires_exact_match 和 ttl_pricing_null_value_falls_back_to_base_tier_value 测试用例 - service: 新增 5min/1h cache TTL 的端到端计费验证测试 - RequestDetailDrawer: 优先从 billing_snapshot 读取已解析的价格和费用,正确展示当前 TTL 对应的缓存创建/读取价格,修正输入/输出/缓存费用列的数据来源
This commit is contained in:
@@ -9,7 +9,7 @@ use crate::ai_pipeline::{
|
||||
resolve_local_decision_execution_runtime_auth_context, ConversionMode, ExecutionStrategy,
|
||||
GatewayControlDecision, PlannerAppState,
|
||||
};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::{current_unix_ms, current_unix_secs};
|
||||
use crate::{append_execution_contract_fields_to_value, AppState, GatewayError};
|
||||
|
||||
use super::{
|
||||
@@ -105,7 +105,7 @@ pub(crate) async fn materialize_local_same_format_provider_candidate_attempts(
|
||||
)
|
||||
.await;
|
||||
|
||||
let created_at_unix_ms = current_unix_secs();
|
||||
let created_at_unix_ms = current_unix_ms();
|
||||
let mut attempts = Vec::with_capacity(candidates.len());
|
||||
let mut affinity_remembered = false;
|
||||
for (candidate_index, candidate) in candidates.into_iter().enumerate() {
|
||||
|
||||
@@ -21,7 +21,7 @@ use crate::ai_pipeline::transport::{
|
||||
use crate::ai_pipeline::{
|
||||
collect_control_headers, ConversionMode, ExecutionStrategy, PlannerAppState,
|
||||
};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::current_unix_ms;
|
||||
use crate::{
|
||||
append_execution_contract_fields_to_value, AppState, GatewayControlSyncDecisionResponse,
|
||||
EXECUTION_RUNTIME_STREAM_DECISION_ACTION, EXECUTION_RUNTIME_SYNC_DECISION_ACTION,
|
||||
@@ -365,7 +365,7 @@ pub(super) async fn mark_skipped_local_same_format_provider_candidate(
|
||||
candidate_id,
|
||||
input.required_capabilities.as_ref(),
|
||||
skip_reason,
|
||||
current_unix_secs(),
|
||||
current_unix_ms(),
|
||||
"gateway local same-format decision failed to persist skipped candidate",
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::ai_pipeline::{
|
||||
resolve_local_decision_execution_runtime_auth_context, GatewayControlDecision,
|
||||
};
|
||||
use crate::ai_pipeline::{GatewayAuthApiKeySnapshot, PlannerAppState};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::{current_unix_ms, current_unix_secs};
|
||||
use crate::{AppState, GatewayError};
|
||||
|
||||
pub(super) const GEMINI_FILES_CANDIDATE_API_FORMAT: &str = "gemini:chat";
|
||||
@@ -102,7 +102,7 @@ pub(super) async fn materialize_local_gemini_files_candidate_attempts(
|
||||
)
|
||||
.await;
|
||||
|
||||
let created_at_unix_ms = current_unix_secs();
|
||||
let created_at_unix_ms = current_unix_ms();
|
||||
let mut attempts = Vec::with_capacity(candidates.len());
|
||||
let mut affinity_remembered = false;
|
||||
for (candidate_index, candidate) in candidates.into_iter().enumerate() {
|
||||
@@ -174,7 +174,7 @@ pub(super) async fn mark_skipped_local_gemini_files_candidate(
|
||||
candidate_id,
|
||||
input.required_capabilities.as_ref(),
|
||||
skip_reason,
|
||||
current_unix_secs(),
|
||||
current_unix_ms(),
|
||||
"gateway local gemini files failed to persist skipped candidate",
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::ai_pipeline::{
|
||||
resolve_local_decision_execution_runtime_auth_context, GatewayControlDecision,
|
||||
};
|
||||
use crate::ai_pipeline::{GatewayAuthApiKeySnapshot, PlannerAppState};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::{current_unix_ms, current_unix_secs};
|
||||
use crate::AppState;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -148,7 +148,7 @@ async fn materialize_local_video_create_candidate_attempts(
|
||||
input.required_capabilities.as_ref(),
|
||||
)
|
||||
.await;
|
||||
let created_at_unix_ms = current_unix_secs();
|
||||
let created_at_unix_ms = current_unix_ms();
|
||||
let mut attempts = Vec::with_capacity(candidates.len());
|
||||
let mut affinity_remembered = false;
|
||||
|
||||
@@ -220,7 +220,7 @@ pub(super) async fn mark_skipped_local_video_candidate(
|
||||
candidate_id,
|
||||
input.required_capabilities.as_ref(),
|
||||
skip_reason,
|
||||
current_unix_secs(),
|
||||
current_unix_ms(),
|
||||
"gateway local video decision failed to persist skipped candidate",
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -17,7 +17,7 @@ use crate::ai_pipeline::{
|
||||
GatewayControlDecision,
|
||||
};
|
||||
use crate::ai_pipeline::{GatewayAuthApiKeySnapshot, PlannerAppState};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::{current_unix_ms, current_unix_secs};
|
||||
use crate::{append_execution_contract_fields_to_value, AppState, GatewayError};
|
||||
|
||||
use super::{
|
||||
@@ -145,7 +145,7 @@ pub(super) async fn materialize_local_standard_candidate_attempts(
|
||||
)
|
||||
.await;
|
||||
|
||||
let created_at_unix_ms = current_unix_secs();
|
||||
let created_at_unix_ms = current_unix_ms();
|
||||
let mut attempts = Vec::with_capacity(candidates.len());
|
||||
let mut affinity_remembered = false;
|
||||
for (candidate_index, candidate) in candidates.into_iter().enumerate() {
|
||||
|
||||
@@ -14,7 +14,7 @@ use crate::ai_pipeline::transport::{
|
||||
};
|
||||
use crate::ai_pipeline::{collect_control_headers, ConversionMode, ExecutionStrategy};
|
||||
use crate::ai_pipeline::{LocalResolvedOAuthRequestAuth, PlannerAppState};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::current_unix_ms;
|
||||
use crate::{
|
||||
append_execution_contract_fields_to_value, AppState, GatewayControlSyncDecisionResponse,
|
||||
EXECUTION_RUNTIME_STREAM_DECISION_ACTION, EXECUTION_RUNTIME_SYNC_DECISION_ACTION,
|
||||
@@ -390,7 +390,7 @@ pub(super) async fn mark_skipped_local_standard_candidate(
|
||||
candidate_id,
|
||||
input.required_capabilities.as_ref(),
|
||||
skip_reason,
|
||||
current_unix_secs(),
|
||||
current_unix_ms(),
|
||||
"gateway local standard decision failed to persist skipped candidate",
|
||||
)
|
||||
.await;
|
||||
|
||||
@@ -12,7 +12,7 @@ use crate::ai_pipeline::planner::candidate_affinity::{
|
||||
};
|
||||
use crate::ai_pipeline::GatewayAuthApiKeySnapshot;
|
||||
use crate::ai_pipeline::{ConversionMode, ExecutionStrategy, PlannerAppState};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::{current_unix_ms, current_unix_secs};
|
||||
use crate::{append_execution_contract_fields_to_value, AppState};
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
@@ -57,7 +57,7 @@ pub(crate) async fn mark_skipped_local_openai_chat_candidate(
|
||||
candidate_id,
|
||||
input.required_capabilities.as_ref(),
|
||||
skip_reason,
|
||||
current_unix_secs(),
|
||||
current_unix_ms(),
|
||||
"gateway local openai chat decision failed to persist skipped candidate",
|
||||
)
|
||||
.await;
|
||||
@@ -77,7 +77,7 @@ pub(crate) async fn materialize_local_openai_chat_candidate_attempts(
|
||||
input.required_capabilities.as_ref(),
|
||||
)
|
||||
.await;
|
||||
let created_at_unix_ms = current_unix_secs();
|
||||
let created_at_unix_ms = current_unix_ms();
|
||||
let mut attempts = Vec::with_capacity(candidates.len());
|
||||
let mut affinity_remembered = false;
|
||||
|
||||
|
||||
@@ -18,7 +18,7 @@ use crate::ai_pipeline::{
|
||||
GatewayControlDecision,
|
||||
};
|
||||
use crate::ai_pipeline::{GatewayAuthApiKeySnapshot, PlannerAppState};
|
||||
use crate::clock::current_unix_secs;
|
||||
use crate::clock::{current_unix_ms, current_unix_secs};
|
||||
use crate::{append_execution_contract_fields_to_value, AppState, GatewayError};
|
||||
|
||||
use super::LocalOpenAiCliSpec;
|
||||
@@ -152,7 +152,7 @@ pub(crate) async fn materialize_local_openai_cli_candidate_attempts(
|
||||
)
|
||||
.await;
|
||||
|
||||
let created_at_unix_ms = current_unix_secs();
|
||||
let created_at_unix_ms = current_unix_ms();
|
||||
let mut attempts = Vec::with_capacity(candidates.len());
|
||||
let mut affinity_remembered = false;
|
||||
for (candidate_index, candidate) in candidates.into_iter().enumerate() {
|
||||
@@ -314,7 +314,7 @@ pub(crate) async fn mark_skipped_local_openai_cli_candidate(
|
||||
candidate_id,
|
||||
input.required_capabilities.as_ref(),
|
||||
skip_reason,
|
||||
current_unix_secs(),
|
||||
current_unix_ms(),
|
||||
"gateway local openai cli decision failed to persist skipped candidate",
|
||||
)
|
||||
.await;
|
||||
|
||||
Reference in New Issue
Block a user