Skip to content

fix(observability): skip Sentry for vision-disabled RAM-tier errors (OPENHUMAN-TAURI-3B)#1623

Merged
senamakel merged 2 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/observability-skip-vision-ram-tier-3b
May 13, 2026
Merged

fix(observability): skip Sentry for vision-disabled RAM-tier errors (OPENHUMAN-TAURI-3B)#1623
senamakel merged 2 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/observability-skip-vision-ram-tier-3b

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

@CodeGhost21 CodeGhost21 commented May 13, 2026

Summary

  • Adds ExpectedErrorKind::LocalAiCapabilityUnavailable to the observability classifier so RAM-tier "vision disabled" / "vision unavailable" responses stop being captured as Sentry errors.
  • Anchors the substring match on "for this RAM tier", the shared marker emitted from assets.rs (Vision is disabled for this RAM tier…) and vision_embed.rs (vision summaries are unavailable for this RAM tier…).
  • Logged at info! in report_expected_message, mirroring the existing LocalAiDisabled path — sentry-tracing records a breadcrumb, not an error.

Fixes OPENHUMAN-TAURI-3B (28 occurrences in 4 days on openhuman@0.53.35, surfaced via openhuman.local_ai_download_assetrpc.invoke_method).

Why this is noise, not signal

The local-AI service deliberately returns this error so the UI can prompt the user to bump tiers when their hardware doesn't support vision. It's a pure user-state condition with no remediable Sentry signal — same shape as the existing local ai is disabled skip. Today it flows through rpc.invoke_method and gets captured by report_error_or_expected for every download attempt.

Test plan

  • cargo test --lib core::observability:: — 13 tests pass, including the two new classifier tests.
  • classifies_local_ai_capability_unavailable_errors covers both canonical wire shapes plus the wrapped rpc.invoke_method failed: … form that hits the classifier in production.
  • does_not_classify_unrelated_messages_as_capability_unavailable pins the anchor so unrelated RAM-mentioning messages aren't silenced.
  • cargo check --lib — no new warnings.
  • cargo fmt.

Summary by CodeRabbit

  • Bug Fixes

    • More accurate detection of local-AI “capability unavailable” messages and changed handling so these are logged as informational skips rather than reported as errors.
  • Tests

    • Added tests covering canonical and wrapped capability-unavailable messages and ensuring unrelated mentions are not misclassified.

Review Change Stack

…PENHUMAN-TAURI-3B)

`local_ai_download_asset` returns a deliberate user-state error when a
user on a 0–4 GB RAM tier requests the vision asset:

    "Vision is disabled for this RAM tier. Switch to the 4-8 GB tier
     or above to enable it."

It also has a sibling shape emitted from `vision_embed.rs` when a vision
summarization call is made on the same tier:

    "vision summaries are unavailable for this RAM tier. Use OCR-only
     summarization or switch to a higher local AI tier."

Both are surfaced for the UI to act on (prompt the user to bump tiers) —
they carry no remediable signal for Sentry. Today they flow through
`rpc.invoke_method` → `report_error_or_expected`, which captures them as
error events (28 occurrences in the last 4 days against `openhuman@0.53.35`).

Extend `expected_error_kind` with a new `LocalAiCapabilityUnavailable`
variant, anchored on the shared substring `"for this RAM tier"`. The
classifier is intentionally narrow so unrelated messages that mention
RAM in other contexts (sizing, doc refs) are not silenced.

Logged at `info!` via `report_expected_message` so the sentry-tracing
layer records at most a breadcrumb, not an error event — same pattern as
`LocalAiDisabled`.

Tests:
- `classifies_local_ai_capability_unavailable_errors` exercises both
  canonical wire shapes plus the wrapped `rpc.invoke_method failed: …`
  shape that reaches the classifier in production.
- `does_not_classify_unrelated_messages_as_capability_unavailable`
  pins the anchor so future tier-related messages don't accidentally
  silence unrelated paths.
@CodeGhost21 CodeGhost21 requested a review from a team May 13, 2026 10:49
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 13, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f35f94d0-b09d-4b80-be85-4340e89fac9f

📥 Commits

Reviewing files that changed from the base of the PR and between e5d5954 and d6b94c0.

📒 Files selected for processing (1)
  • src/core/observability.rs
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/core/observability.rs

📝 Walkthrough

Walkthrough

Recognize local-AI "capability unavailable for this ram tier" messages in observability: new ExpectedErrorKind variant and helper classify them, and matched errors are logged at info level instead of reported as errors; tests added for positive and negative cases.

Changes

Local AI Capability Unavailable Error Handling

Layer / File(s) Summary
Error kind variant and detection logic
src/core/observability.rs
LocalAiCapabilityUnavailable variant added to ExpectedErrorKind; expected_error_kind calls is_local_ai_capability_unavailable_message which detects messages anchored on "for this ram tier".
Routing and test coverage
src/core/observability.rs
report_expected_message logs LocalAiCapabilityUnavailable at info level with a "skipped expected local-ai capability-unavailable" message; unit tests cover canonical, RPC-wrapped, and negative RAM-tier cases.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • tinyhumansai/openhuman#1669: Similar changes extending ExpectedErrorKind and routing local-AI skipped expected cases through report_expected_message.
  • tinyhumansai/openhuman#1601: Related observability classification updates touching expected_error_kind and report_error_or_expected.

Suggested reviewers

  • senamakel

Poem

🐰 I sniffed a log that whispered, "not enough RAM,"
I thumped my foot, then softened my ham.
Now the message naps at info, calm and mild,
No horned alarms — just a courteous smile.
Hooray for logs that keep the treehouse styled.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main change: adding observability handling to skip Sentry for RAM-tier vision-disabled errors, which aligns with the core modification of extending ExpectedErrorKind to recognize and appropriately classify local-AI capability-unavailable messages.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 13, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

PR #1623 Review — fix(observability): skip Sentry for vision-disabled RAM-tier errors

Walkthrough

Adds a third expected-error variant, LocalAiCapabilityUnavailable, to ExpectedErrorKind in src/core/observability.rs. When the local-AI service rejects a request because the user's RAM tier doesn't support vision, the error now routes to tracing::info! instead of being captured as a Sentry event. Correctly motivated: these are deliberate user-state signals (28 occurrences in 4 days on v0.53.35), not bugs. Implementation follows the existing LocalAiDisabled pattern exactly.

Changes

File Summary
src/core/observability.rs Adds LocalAiCapabilityUnavailable variant; is_local_ai_capability_unavailable_message classifier anchored on "for this ram tier"; match arm in report_expected_message logging at info!; 2 new test functions

Comments

[minor] Short warning-field form not pinned in tests

assets.rs also emits a shorter form "Vision is disabled for this RAM tier." (just a period, no trailing sentence) as a warning field. The classifier handles it correctly (substring is present), but the test suite only covers the full-sentence forms. Consider adding it as a third entry in the for raw in [...] loop — one line, zero extra scaffolding:

"Vision is disabled for this RAM tier.",

[nitpick] Inline source-location comment in classifier body

The docstring above is_local_ai_capability_unavailable_message already documents the emitting sites, but a short inline comment in the function body itself would make it obvious to future developers adding a third capability gate:

fn is_local_ai_capability_unavailable_message(lower: &str) -> bool {
    // Anchor shared by local_ai/service/assets.rs (ensure_capability_ready)
    // and local_ai/service/vision_embed.rs (summarize).
    lower.contains("for this ram tier")
}

Take or leave — the existing docstring covers intent well.

Verified / Looks Good

  • Anchor "for this ram tier" is present verbatim in both emitting sites (assets.rs, vision_embed.rs) after to_ascii_lowercase()
  • is_local_ai_capability_unavailable_message is correctly private (fn, not pub fn)
  • New variant is additive — ExpectedErrorKind derives PartialEq, Eq, match is exhaustive
  • Log level info! matches LocalAiDisabled precedent; ApiKeyMissing uses warn! (intentional distinction)
  • No PII in logged messages
  • No new deps, no module layout violations
  • Tests cover positive (2 canonical shapes + RPC-wrapped) and negative (2 unrelated RAM mentions) paths
  • All 17 CI checks pass, coverage gate ≥80% met

Overall: Clean, well-scoped fix. One minor suggestion (pin the short form in tests), one nitpick. Would approve as-is or with the minor addressed.

@senamakel senamakel self-assigned this May 13, 2026
@senamakel
Copy link
Copy Markdown
Member

pr-manager follow-up — merge conflict resolved, reviewer suggestions applied.

Changes applied (commit abb4fc8)

Quality checks

  • `cargo fmt` — clean
  • `cargo check` — passes (pre-existing warnings only, none introduced by this PR)
  • `cargo test --lib core::observability` — 19/19 pass
  • Pre-push hooks (Prettier, ESLint, rust fmt/check) — all passed

Note

This is a cross-repo PR. The commit was pushed to `senamakel/openhuman:pr/1623` (the user's fork). The contributor's fork (`CodeGhost21/openhuman`) is not updated by this push. A maintainer can merge from the fork branch or cherry-pick abb4fc8 onto the PR branch directly.

…p-vision-ram-tier-3b

# Conflicts:
#	src/core/observability.rs
@senamakel senamakel merged commit cf27eff into tinyhumansai:main May 13, 2026
24 checks passed
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants