From f78b2862715f5c05bfc8d58703d46c24bb9d826e 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 125edc4cc6..5c36b6264e 100644 --- a/src/openhuman/inference/provider/config_rejection.rs +++ b/src/openhuman/inference/provider/config_rejection.rs @@ -148,6 +148,17 @@ pub fn is_provider_config_rejection_message(body: &str) -> bool { // this is the `type` field used by litellm/Anthropic-style // envelopes for the same class of user-state error. "not_found_error", + // 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(); @@ -288,6 +299,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 5fa4ca81a7affd899000af70315b271c8e7e30b5 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())], ); } }