Skip to content

Commit f798f3f

Browse files
committed
fix(tui): account errors to the active route
Prefer the captured active turn route when recording provider health failures after TurnStarted clears the pending route. Keep the pending and selected routes as pre-start fallbacks, and cover the routed-turn case. Signed-off-by: Nightt <87569709+nightt5879@users.noreply.github.com>
1 parent 38da51a commit f798f3f

2 files changed

Lines changed: 36 additions & 5 deletions

File tree

crates/tui/src/tui/ui.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3001,11 +3001,8 @@ async fn run_event_loop(
30013001
recoverable: _,
30023002
} => {
30033003
let provider_before_error = app.api_provider;
3004-
let (health_provider, health_model) = app
3005-
.pending_turn_route
3006-
.as_ref()
3007-
.map(|(provider, model, _)| (*provider, model.clone()))
3008-
.unwrap_or_else(|| (provider_before_error, app.model.clone()));
3004+
let (health_provider, health_model) =
3005+
error_health_route(app, provider_before_error);
30093006
app.provider_health.record_failure(
30103007
config,
30113008
health_provider,
@@ -6780,6 +6777,19 @@ fn capture_turn_started_metadata(app: &mut App, event: &EngineEvent) {
67806777
}
67816778
}
67826779

6780+
fn error_health_route(app: &App, fallback_provider: ApiProvider) -> (ApiProvider, String) {
6781+
app.active_turn
6782+
.as_ref()
6783+
.and_then(|turn| turn.route.as_ref())
6784+
.map(|route| (route.provider, route.model.clone()))
6785+
.or_else(|| {
6786+
app.pending_turn_route
6787+
.as_ref()
6788+
.map(|(provider, model, _)| (*provider, model.clone()))
6789+
})
6790+
.unwrap_or_else(|| (fallback_provider, app.model.clone()))
6791+
}
6792+
67836793
fn record_turn_activity(app: &mut App, event: &EngineEvent, now: Instant) {
67846794
if matches!(event, EngineEvent::TurnStarted { .. }) {
67856795
app.turn_last_activity_at = Some(now);

crates/tui/src/tui/ui/tests.rs

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7234,6 +7234,27 @@ fn turn_started_route_is_captured_before_cancel_suppression() {
72347234
assert_eq!(observer.route, Some(route));
72357235
}
72367236

7237+
#[test]
7238+
fn engine_error_health_accounting_uses_active_turn_route() {
7239+
let mut app = create_test_app();
7240+
app.api_provider = ApiProvider::Deepseek;
7241+
app.model = "current-model".to_string();
7242+
let event = EngineEvent::TurnStarted {
7243+
turn_id: "routed-turn".to_string(),
7244+
created_at: chrono::Utc::now(),
7245+
route: Some(crate::core::events::TurnRoute {
7246+
provider: ApiProvider::Openai,
7247+
model: "gpt-5.5".to_string(),
7248+
auto_model: true,
7249+
}),
7250+
};
7251+
capture_turn_started_metadata(&mut app, &event);
7252+
7253+
let route = error_health_route(&app, app.api_provider);
7254+
7255+
assert_eq!(route, (ApiProvider::Openai, "gpt-5.5".to_string()));
7256+
}
7257+
72377258
#[test]
72387259
fn completion_only_hook_metadata_is_synthetic_and_non_model() {
72397260
let observed_after = chrono::Utc::now();

0 commit comments

Comments
 (0)