Skip to content

Commit 84d64a8

Browse files
author
CodeWhale Bot
committed
fix(tui): repair PR #5726 gate surface — clippy, accounting and wire-route tests
CI-form clippy repairs on the checkpoint head: - box MailboxMessage::TokenUsage.route (large_enum_variant) with call-site and test updates in subagent_routing and mailbox - needless_return in session_manager lock-file open, doc_lazy_continuation in translation, obfuscated_if_else in provider_lake - route resolver + provider lake alignment for the opencode_zen wire-route expectations (Responses/AnthropicMessages vs ChatCompletions) Verified locally: - cargo test -p codewhale-tui --locked --lib: 11596 passed, 6 failed — the 6 are the pre-existing main-baseline sandbox::read_guard symlink family that #5724 makes whole-fn-unix; zero Slice-A regressions - auto_review_guardian family 7/7 (accounting + denial + cache replay) - web vitest run of crates/tui/src/runtime_web/app.test.mjs: 28/28 - CI-form clippy clean (previous session) Signed-off-by: CodeWhale Bot <bot@codewhale.net>
1 parent 1a03b23 commit 84d64a8

12 files changed

Lines changed: 84 additions & 53 deletions

File tree

crates/config/src/route/resolver.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -259,12 +259,16 @@ impl RouteResolver {
259259
// Capabilities and pricing belong to the exact provider endpoint
260260
// offering that reported them. Reusing a provider enum and a
261261
// first-party model id against a custom compatible endpoint does
262-
// not prove that proxy serves the same canonical model, protocol,
263-
// limits, modality, tool, reasoning, or billing contract. Keep the
262+
// not prove that proxy serves the same canonical model, limits,
263+
// modality, tool, reasoning, or billing contract. Keep the
264264
// caller's wire model id, but clear every unowned offering fact at
265265
// the authority boundary instead of presenting it as verified.
266+
// The endpoint_key/protocol stays: it is the provider adapter's
267+
// wire contract (a model-aware roster row or fixed policy), not an
268+
// endpoint-catalog fact, and coercing it to Chat would silently
269+
// change how a Responses- or Messages-bound route speaks.
270+
// Deepseek's custom-endpoint Chat pass-through is handled above.
266271
selected.canonical_model = None;
267-
selected.endpoint_key = "chat".to_string();
268272
selected.limits = RouteLimits::default();
269273
selected.capabilities = RouteCapabilities::default();
270274
selected.pricing = PricingSku::UnknownOrStale;

crates/tui/src/core/engine/tests.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4102,14 +4102,14 @@ fn subagent_mailbox_keeps_lifecycle_events_reliable() {
41024102
&MailboxMessage::TokenUsage {
41034103
agent_id: "agent_a".to_string(),
41044104
source_id: "response-a".to_string(),
4105-
route: crate::cost_status::EffectiveRouteEnvelope::capture(
4105+
route: Box::new(crate::cost_status::EffectiveRouteEnvelope::capture(
41064106
None,
41074107
ApiProvider::Deepseek,
41084108
"deepseek",
41094109
"model",
41104110
Some(ApiProvider::Deepseek.default_base_url()),
41114111
chrono::Utc::now(),
4112-
),
4112+
)),
41134113
usage: Usage::default(),
41144114
}
41154115
));
@@ -4196,14 +4196,14 @@ fn subagent_mailbox_never_samples_lifecycle_or_usage_events() {
41964196
&MailboxMessage::TokenUsage {
41974197
agent_id: "agent_a".to_string(),
41984198
source_id: "response-a".to_string(),
4199-
route: crate::cost_status::EffectiveRouteEnvelope::capture(
4199+
route: Box::new(crate::cost_status::EffectiveRouteEnvelope::capture(
42004200
None,
42014201
ApiProvider::Deepseek,
42024202
"deepseek",
42034203
"model",
42044204
Some(ApiProvider::Deepseek.default_base_url()),
42054205
chrono::Utc::now(),
4206-
),
4206+
)),
42074207
usage: Usage::default(),
42084208
},
42094209
start,
@@ -5659,8 +5659,11 @@ async fn normal_repl_kernel_persists_across_user_turns() {
56595659
assert_eq!(first_turn.usage.output_tokens, 11);
56605660
let child_usage_event = {
56615661
let mut events = handle.rx_event.write().await;
5662+
// Kernel child calls carry their own routed cost receipt, so their
5663+
// per-call telemetry arrives as `RoutedTurnUsage` rather than the
5664+
// parent-route `TurnUsage` receipt.
56625665
std::iter::from_fn(|| events.try_recv().ok()).find_map(|event| match event {
5663-
Event::TurnUsage { usage, .. }
5666+
Event::RoutedTurnUsage { usage, .. }
56645667
if usage.input_tokens == 7 && usage.output_tokens == 11 =>
56655668
{
56665669
Some(usage)
@@ -7395,7 +7398,12 @@ async fn collect_guardian_journey_with_receipts(
73957398
"duplicate tool result"
73967399
);
73977400
}
7398-
Event::TurnUsage { usage, .. } => usage_events.push(usage),
7401+
// Guardian consults carry their own routed receipt; both the
7402+
// parent-route and routed per-call telemetry count as reaching
7403+
// the cost UI.
7404+
Event::TurnUsage { usage, .. } | Event::RoutedTurnUsage { usage, .. } => {
7405+
usage_events.push(usage);
7406+
}
73997407
Event::ToolGateDecision {
74007408
tool_id,
74017409
gate,

crates/tui/src/provider_lake.rs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -586,28 +586,28 @@ pub(crate) fn runtime_catalog_resolver_for_identity(
586586
if !exact_matches && let LivePartitionOwner::BuiltIn(identity) = &partition_owner {
587587
authoritative.remove(identity);
588588
}
589-
let fallback = (provider != ApiProvider::Custom)
590-
.then(|| {
591-
live.models_dev
592-
.as_ref()
593-
.map(|models_dev| {
594-
models_dev
595-
.offerings
596-
.iter()
597-
.filter(|row| catalog_partition_key(&row.provider) == catalog_key)
598-
.cloned()
599-
.collect::<Vec<_>>()
600-
})
601-
.unwrap_or_default()
602-
})
603-
.unwrap_or_default();
604-
let custom_rows = (provider == ApiProvider::Custom && exact_matches)
605-
.then(|| {
606-
exact_partition
607-
.map(|partition| partition.offerings.clone())
608-
.unwrap_or_default()
609-
})
610-
.unwrap_or_default();
589+
let fallback = if provider == ApiProvider::Custom {
590+
Vec::new()
591+
} else {
592+
live.models_dev
593+
.as_ref()
594+
.map(|models_dev| {
595+
models_dev
596+
.offerings
597+
.iter()
598+
.filter(|row| catalog_partition_key(&row.provider) == catalog_key)
599+
.cloned()
600+
.collect::<Vec<_>>()
601+
})
602+
.unwrap_or_default()
603+
};
604+
let custom_rows = if provider == ApiProvider::Custom && exact_matches {
605+
exact_partition
606+
.map(|partition| partition.offerings.clone())
607+
.unwrap_or_default()
608+
} else {
609+
Vec::new()
610+
};
611611
(exact_matches, authoritative, fallback, custom_rows)
612612
} else {
613613
(

crates/tui/src/runtime_threads.rs

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8894,7 +8894,10 @@ impl RuntimeThreadManager {
88948894
self.append_routed_usage_to_turn(
88958895
&turn_id,
88968896
&source_id,
8897-
EffectiveRouteUsage { route, usage },
8897+
EffectiveRouteUsage {
8898+
route: *route,
8899+
usage,
8900+
},
88988901
)?;
88998902
}
89008903
}

crates/tui/src/runtime_threads/tests.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5962,7 +5962,7 @@ async fn monitor_separates_lifecycle_start_from_billing_dispatch_and_child_usage
59625962
message: crate::tools::subagent::MailboxMessage::TokenUsage {
59635963
agent_id: "agent_child".to_string(),
59645964
source_id: "response-child".to_string(),
5965-
route: crate::cost_status::EffectiveRouteEnvelope {
5965+
route: Box::new(crate::cost_status::EffectiveRouteEnvelope {
59665966
provider: ApiProvider::OpenaiCodex,
59675967
provider_identity: "codex-child".to_string(),
59685968
model: "gpt-5.5".to_string(),
@@ -5973,7 +5973,7 @@ async fn monitor_separates_lifecycle_start_from_billing_dispatch_and_child_usage
59735973
provider_live_pricing: None,
59745974
billing_mode: crate::cost_status::RouteBillingMode::Subscription,
59755975
dispatched_at,
5976-
},
5976+
}),
59775977
usage: Usage {
59785978
input_tokens: 3,
59795979
output_tokens: 2,
@@ -6106,7 +6106,7 @@ async fn monitor_separates_lifecycle_start_from_billing_dispatch_and_child_usage
61066106
message: crate::tools::subagent::MailboxMessage::TokenUsage {
61076107
agent_id: "agent-child-second".to_string(),
61086108
source_id: "response-child-second".to_string(),
6109-
route: crate::cost_status::EffectiveRouteEnvelope {
6109+
route: Box::new(crate::cost_status::EffectiveRouteEnvelope {
61106110
provider: ApiProvider::OpenaiCodex,
61116111
provider_identity: "codex-child".to_string(),
61126112
model: "gpt-5.5".to_string(),
@@ -6117,7 +6117,7 @@ async fn monitor_separates_lifecycle_start_from_billing_dispatch_and_child_usage
61176117
provider_live_pricing: None,
61186118
billing_mode: crate::cost_status::RouteBillingMode::Subscription,
61196119
dispatched_at: Utc::now(),
6120-
},
6120+
}),
61216121
usage: Usage {
61226122
input_tokens: 5,
61236123
output_tokens: 1,

crates/tui/src/session_manager.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ fn open_private_lock_file(path: &Path) -> io::Result<fs::File> {
124124
let file = options.open(path)?;
125125
validate_private_regular_file(&file, path)?;
126126
file.set_permissions(fs::Permissions::from_mode(0o600))?;
127-
return Ok(file);
127+
Ok(file)
128128
}
129129
#[cfg(windows)]
130130
{
@@ -133,7 +133,7 @@ fn open_private_lock_file(path: &Path) -> io::Result<fs::File> {
133133
options.custom_flags(FILE_FLAG_OPEN_REPARSE_POINT);
134134
let file = options.open(path)?;
135135
validate_private_regular_file(&file, path)?;
136-
return Ok(file);
136+
Ok(file)
137137
}
138138
#[cfg(all(not(unix), not(windows)))]
139139
{

crates/tui/src/tools/subagent/mailbox.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,9 @@ pub enum MailboxMessage {
8484
/// this across direct durability, mailbox replay, and restart dedupe.
8585
source_id: String,
8686
/// Immutable provider/model/billing evidence captured before the
87-
/// child request was sent.
88-
route: crate::cost_status::EffectiveRouteEnvelope,
87+
/// child request was sent. Boxed: the envelope dwarfs every other
88+
/// variant, and mailboxes queue many messages.
89+
route: Box<crate::cost_status::EffectiveRouteEnvelope>,
8990
/// Provider usage payload, including cache-hit/cache-miss fields.
9091
usage: Usage,
9192
},
@@ -141,7 +142,7 @@ impl MailboxMessage {
141142
Self::TokenUsage {
142143
agent_id: agent_id.into(),
143144
source_id: source_id.into(),
144-
route,
145+
route: Box::new(route),
145146
usage,
146147
}
147148
}
@@ -618,7 +619,7 @@ mod tests {
618619
MailboxMessage::TokenUsage {
619620
agent_id: "a9".into(),
620621
source_id: "response-a9".into(),
621-
route: test_route(ApiProvider::Deepseek, "deepseek-v4-flash"),
622+
route: Box::new(test_route(ApiProvider::Deepseek, "deepseek-v4-flash")),
622623
usage: Usage {
623624
input_tokens: 100,
624625
output_tokens: 50,

crates/tui/src/tools/subagent/tests.rs

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20902,6 +20902,19 @@ mod child_permission_gate {
2090220902
#[cfg(not(windows))]
2090320903
const GUARDIAN_PIPELINE: &str = "echo built | cat";
2090420904

20905+
/// [`GUARDIAN_PIPELINE`] with a caller-chosen marker, for tests that
20906+
/// need to recognize their own output.
20907+
fn guardian_marker_pipeline(marker: &str) -> String {
20908+
#[cfg(windows)]
20909+
{
20910+
format!("echo {marker} | Out-String")
20911+
}
20912+
#[cfg(not(windows))]
20913+
{
20914+
format!("echo {marker} | cat")
20915+
}
20916+
}
20917+
2090520918
#[tokio::test]
2090620919
async fn auto_review_consults_the_guardian_and_runs_an_allowed_call_with_a_receipt() {
2090720920
let (_server, client) = guardian_mock(
@@ -21004,7 +21017,7 @@ mod child_permission_gate {
2100421017
.execute(
2100521018
"agent_gate",
2100621019
"bash",
21007-
json!({"command": "echo guardian-missing-usage | cat"}),
21020+
json!({"command": guardian_marker_pipeline("guardian-missing-usage")}),
2100821021
)
2100921022
.await
2101021023
.expect("semantic guardian success remains usable");
@@ -21044,7 +21057,7 @@ mod child_permission_gate {
2104421057
.await;
2104521058
let (registry, mut rx, manager) =
2104621059
worker_registry(ApprovalMode::Auto, false, true, Some(client));
21047-
let input = json!({"command": "echo guardian-cache-regression | cat"});
21060+
let input = json!({"command": guardian_marker_pipeline("guardian-cache-regression")});
2104821061

2104921062
for _ in 0..2 {
2105021063
let output = registry

crates/tui/src/tui/subagent_routing.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1331,7 +1331,7 @@ mod tests {
13311331
&MailboxMessage::TokenUsage {
13321332
agent_id: "agent_route".to_string(),
13331333
source_id: "response-route".to_string(),
1334-
route: test_route(crate::config::ApiProvider::Openrouter, "vendor/model-real"),
1334+
route: Box::new(test_route(crate::config::ApiProvider::Openrouter, "vendor/model-real")),
13351335
usage: crate::models::Usage::default(),
13361336
},
13371337
);
@@ -1353,7 +1353,7 @@ mod tests {
13531353
&MailboxMessage::TokenUsage {
13541354
agent_id: "agent_spend".to_string(),
13551355
source_id: "response-1".to_string(),
1356-
route: route.clone(),
1356+
route: Box::new(route.clone()),
13571357
usage: crate::models::Usage {
13581358
input_tokens: 1_000,
13591359
output_tokens: 40,
@@ -1367,7 +1367,7 @@ mod tests {
13671367
&MailboxMessage::TokenUsage {
13681368
agent_id: "agent_spend".to_string(),
13691369
source_id: "response-2".to_string(),
1370-
route,
1370+
route: Box::new(route),
13711371
usage: crate::models::Usage {
13721372
input_tokens: 2_000,
13731373
output_tokens: 60,

crates/tui/src/tui/translation.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,12 @@
1010
//!
1111
//! - `needs_translation()` — heuristic to detect if text is predominantly
1212
//! English and should be translated.
13+
//!
1314
//! The event loop dispatches focused translation requests through the exact
1415
//! provider/model client frozen for the originating turn. The dedicated agent
1516
//! receives only the source text and returns only the translation — no tool
1617
//! calls or conversation history.
18+
//!
1719
//! - `TranslationStatus` — tracks per-message translation status in the UI.
1820
1921
/// Heuristic threshold: if more than this fraction of alphabetic characters

0 commit comments

Comments
 (0)