Improve provider reliability and usage visibility
This commit is contained in:
@@ -502,6 +502,10 @@ impl ProviderRun {
|
||||
self.model_retries
|
||||
}
|
||||
|
||||
pub fn max_model_retries_per_turn(&self) -> u32 {
|
||||
self.limits.max_model_retries_per_turn
|
||||
}
|
||||
|
||||
pub fn is_terminal(&self) -> bool {
|
||||
matches!(
|
||||
self.state,
|
||||
@@ -665,20 +669,20 @@ impl ProviderRun {
|
||||
}
|
||||
ProviderRunState::Failed { failure } => match failure.kind {
|
||||
ProviderRunFailureKind::ModelCall
|
||||
if !failure
|
||||
if failure
|
||||
.source
|
||||
.as_ref()
|
||||
.is_some_and(|source| !source.recoverable) =>
|
||||
.is_none_or(|source| source.recoverable) =>
|
||||
{
|
||||
return Err(invalid(
|
||||
"model-call failure lacks a non-recoverable source".to_string(),
|
||||
));
|
||||
}
|
||||
ProviderRunFailureKind::RetryLimitExceeded
|
||||
if !failure
|
||||
if failure
|
||||
.source
|
||||
.as_ref()
|
||||
.is_some_and(|source| source.recoverable) =>
|
||||
.is_none_or(|source| !source.recoverable) =>
|
||||
{
|
||||
return Err(invalid(
|
||||
"retry-limit failure lacks a recoverable source".to_string(),
|
||||
|
||||
@@ -223,15 +223,21 @@ impl ToolEvent {
|
||||
|
||||
#[derive(Clone, Debug, Default, PartialEq, Eq, Serialize, Deserialize)]
|
||||
pub struct Usage {
|
||||
/// Input tokens not served by or written to a provider prompt cache.
|
||||
pub input_tokens: u64,
|
||||
pub output_tokens: u64,
|
||||
/// Input tokens served from the provider prompt cache.
|
||||
pub cached_input_tokens: u64,
|
||||
/// Input tokens written to the provider prompt cache.
|
||||
pub cache_creation_input_tokens: u64,
|
||||
}
|
||||
|
||||
impl Usage {
|
||||
pub fn total_tokens(&self) -> u64 {
|
||||
self.input_tokens.saturating_add(self.output_tokens)
|
||||
self.input_tokens
|
||||
.saturating_add(self.cached_input_tokens)
|
||||
.saturating_add(self.cache_creation_input_tokens)
|
||||
.saturating_add(self.output_tokens)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -268,6 +274,9 @@ pub enum AgentEvent {
|
||||
TurnStarted {
|
||||
runtime_request_id: String,
|
||||
},
|
||||
/// A transport heartbeat proving that the current model stream is still connected.
|
||||
/// Consumers should use this to refresh idle timeouts without rendering output.
|
||||
KeepAlive,
|
||||
TextDelta {
|
||||
text: String,
|
||||
},
|
||||
|
||||
@@ -26,9 +26,9 @@ fn truncates_large_tool_results_for_provider_request() {
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn usage_total_excludes_cached_breakdown_to_avoid_double_counting() {
|
||||
fn usage_total_combines_disjoint_cache_and_miss_buckets() {
|
||||
let usage = Usage {
|
||||
input_tokens: 100,
|
||||
input_tokens: 10,
|
||||
output_tokens: 25,
|
||||
cached_input_tokens: 80,
|
||||
cache_creation_input_tokens: 10,
|
||||
|
||||
Reference in New Issue
Block a user