From 0392452f6cd28f1e7a67453e407b5ff7215621de Mon Sep 17 00:00:00 2001 From: oxoxDev Date: Tue, 26 May 2026 16:07:39 +0530 Subject: [PATCH 1/2] feat(inference/config_rejection): anchor "may not be available on your provider" (Sentry TAURI-RUST-1V) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add the canonical phrase from `reliable.rs:332` to the ProviderConfigRejection classifier. `reliable.rs` rolls every exhausted fallback into `All providers/models failed. Attempts:\n…\nThe model `` may not be available on your provider. Configure a fallback chain via `reliability.model_fallbacks` in …`, which the composio triage subscriber re-reports to Sentry. The remediation lives entirely in the user's `reliability.model_fallbacks` config; Sentry has no remediation path. Drops the bulk of self-hosted Sentry TAURI-RUST-1V (10,692 events / 14d on `tauri-rust` project, dominated by `gemini-3-flash-preview`-style ProviderConfigRejection rollups). Sentry-Issue: TAURI-RUST-1V --- .../inference/provider/config_rejection.rs | 46 +++++++++++++++++++ 1 file changed, 46 insertions(+) diff --git a/src/openhuman/inference/provider/config_rejection.rs b/src/openhuman/inference/provider/config_rejection.rs index 1a5aeb104e..a2033237a0 100644 --- a/src/openhuman/inference/provider/config_rejection.rs +++ b/src/openhuman/inference/provider/config_rejection.rs @@ -204,6 +204,17 @@ pub fn is_provider_config_rejection_message(body: &str) -> bool { // -4FS, -4F6, -2YA, -4KR, -4KH, -4KY — ~458 events). The user // must pick a tool-capable model; Sentry has no remediation. "does not support tools", + // TAURI-RUST-1V — reliable-provider chain rolls up exhausted + // fallbacks into `All providers/models failed. Attempts:\n…\nThe + // model `` may not be available on your provider. Configure + // a fallback chain via `reliability.model_fallbacks` in …`. + // Emitted at `src/openhuman/inference/provider/reliable.rs:332`. + // The remediation is "fix your `model_fallbacks` config" — pure + // user-config, nothing Sentry can act on. Anchor on the canonical + // remediation phrase so this doesn't collide with unrelated + // mentions of model availability (`reliable.rs:332` is the sole + // producer in-tree). + "may not be available on your provider", ]; let lower = body.to_ascii_lowercase(); @@ -491,6 +502,41 @@ mod tests { } } + #[test] + fn detects_reliable_chain_exhaustion_rollup() { + // TAURI-RUST-1V — `reliable.rs:325` rolls every attempt into + // `All providers/models failed. Attempts:\n…\nThe model `` + // may not be available on your provider. Configure a fallback + // chain via `reliability.model_fallbacks` in …`. The wrapped err + // bubbles to `memory_sync::composio::bus` which previously + // emitted it as a raw `tracing::error!` — 10.7k events / 14d on + // self-hosted Sentry. The remediation lives entirely in the + // user's `reliability.model_fallbacks` config; Sentry has no + // remediation path. + let rollup = "All providers/models failed. Attempts:\n\ + provider=openhuman model=gemini-3-flash-preview attempt 1/3: \ + non_retryable; error=custom_openai API error (404 Not Found): \ + ...\n\ + The model `gemini-3-flash-preview` may not be available on \ + your provider. Configure a fallback chain via \ + `reliability.model_fallbacks` in your config to route around \ + unavailable models."; + assert!( + is_provider_config_rejection_message(rollup), + "TAURI-RUST-1V multi-line rollup must classify as provider config-rejection" + ); + + // Single-line `reliable.rs:332` emission (without the outer + // rollup wrapper) also matches — defensive against callers that + // surface only the inner remediation message. + let bare = "The model `chat-v1` may not be available on your provider. \ + Configure a fallback chain via `reliability.model_fallbacks` in …"; + assert!( + is_provider_config_rejection_message(bare), + "bare `may not be available on your provider` phrase must classify" + ); + } + #[test] fn unknown_model_helper_matches_openai_compatible_bodies() { // TAURI-RUST-2Z1 — the OpenHuman hosted backend now emits the From 1733f06b3269f1e2f0dc9546f1b72d630638b40f Mon Sep 17 00:00:00 2001 From: oxoxDev Date: Tue, 26 May 2026 16:07:48 +0530 Subject: [PATCH 2/2] fix(composio/triage): route triage failure through observability classifier (Sentry TAURI-RUST-1V) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Swap the raw `tracing::error!` at memory_sync/composio/bus.rs:354 with `crate::core::observability::report_error_or_expected` so user-config / budget-exhausted rollups from the upstream provider chain get demoted to info-level breadcrumbs instead of surfacing as Sentry errors. Pairs with the new `may not be available on your provider` anchor in `is_provider_config_rejection_message` — together they neutralise the self-hosted Sentry TAURI-RUST-1V noise (10,692 events / 14d) whose inner attempts the provider layer already correctly demoted but whose outer rollup escaped via this raw error emit. Genuine triage runtime bugs that don't classify still reach Sentry unchanged. Sentry-Issue: TAURI-RUST-1V --- src/openhuman/memory_sync/composio/bus.rs | 24 +++++++++++++++++++---- 1 file changed, 20 insertions(+), 4 deletions(-) diff --git a/src/openhuman/memory_sync/composio/bus.rs b/src/openhuman/memory_sync/composio/bus.rs index c22a8e4749..4436b094de 100644 --- a/src/openhuman/memory_sync/composio/bus.rs +++ b/src/openhuman/memory_sync/composio/bus.rs @@ -352,10 +352,26 @@ impl EventHandler for ComposioTriggerSubscriber { ); } Err(e) => { - tracing::error!( - label = %envelope.display_label, - error = %e, - "[composio][triage] run_triage failed" + // Route through the central observability classifier + // so user-config / budget-exhausted / provider-state + // rollups from `reliable.rs` (e.g. `The model + // \`\` may not be available on your provider …`) + // get demoted to info-level breadcrumbs instead of + // surfacing as raw Sentry errors. Previously this + // call used `tracing::error!` directly and bypassed + // the classifier — 10.7k events / 14d on self-hosted + // Sentry TAURI-RUST-1V, dominated by + // ProviderConfigRejection-class rollups whose inner + // attempts the provider layer already demoted. + let detail = format!( + "[composio][triage] run_triage failed (label={}): {e:#}", + envelope.display_label + ); + crate::core::observability::report_error_or_expected( + detail.as_str(), + "composio", + "trigger_triage", + &[("label", envelope.display_label.as_str())], ); } }