Skip to content

fix(observability): demote OpenHuman backend unknown-model 400 (TAURI-RUST-2Z1)#2464

Merged
senamakel merged 3 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/tauri-rust-2z1-unknown-model-polarity
May 23, 2026
Merged

fix(observability): demote OpenHuman backend unknown-model 400 (TAURI-RUST-2Z1)#2464
senamakel merged 3 commits into
tinyhumansai:mainfrom
CodeGhost21:fix/tauri-rust-2z1-unknown-model-polarity

Conversation

@CodeGhost21
Copy link
Copy Markdown
Contributor

@CodeGhost21 CodeGhost21 commented May 21, 2026

Summary

The OpenHuman hosted backend now emits the OpenAI-compatible Model 'X' is not available. Use GET /openai/v1/models … wire body for user-configured unknown model ids. The HTTP-layer wrapper is_provider_config_rejection_http in src/openhuman/inference/provider/ops.rs was polarity-gated on provider != openhuman_backend::PROVIDER_LABEL for all config-rejection phrases — built on the older assumption that only third-party custom_openai upstreams would speak this dialect. So the per-attempt event from a user-typed unknown model id reached Sentry as a real error (TAURI-RUST-2Z1) even though the underlying condition is pure user-state.

This PR drops the polarity guard for that one specific shape via a narrow new helper is_openai_compatible_unknown_model_message, anchored on the stable /openai/v1/models remediation-hint substring. Every other config-rejection phrase (DeepSeek supported api model names are, Moonshot invalid temperature: only 1 is allowed, litellm envelopes, OpenRouter requires more credits) stays polarity-gated so a regression where our own backend started emitting one of those would still reach Sentry.

The aggregate sibling TAURI-RUST-2Z2 is already auto-demoted by the message-only classifier in core::observability::expected_error_kind (via #2239's /openai/v1/models phrase). This PR addresses the missing per-attempt half.

What changed

  • src/openhuman/inference/provider/config_rejection.rs
    • Added is_openai_compatible_unknown_model_message(body) — strict subset of the broader phrase matcher, pinned to /openai/v1/models.
    • Updated module-level polarity contract docs to call out the new exception.
  • src/openhuman/inference/provider/ops.rs
    • is_provider_config_rejection_http now bypasses the openhuman_backend polarity guard only when is_openai_compatible_unknown_model_message matches; all other config-rejection phrases retain the guard.
    • Existing doc-comment updated to reflect the exception.
  • src/openhuman/inference/provider/mod.rs
    • Re-export is_openai_compatible_unknown_model_message for cross-module access.

Test plan

  • cargo test --lib openhuman::inference::provider::config_rejection — 6 passed, including two new tests: unknown_model_helper_matches_openai_compatible_bodies (pins the exact TAURI-RUST-2Z1 wire body) and unknown_model_helper_rejects_other_config_rejection_phrases (guards the narrow-scope invariant).
  • cargo test --lib openhuman::inference::provider::ops::tests::provider_config_rejection_suppression — 7 passed, including a new test openhuman_backend_openai_compatible_unknown_model_is_suppressed plus an additional assertion in the existing openhuman_backend_same_body_is_not_suppressed test confirming TIER_LEAK_BODY and TEMP_BODY both still bypass demotion for the backend.
  • cargo test --lib openhuman::inference::provider — 272 passed, 0 failed.
  • cargo test --lib core::observability — 81 passed, 0 failed (no regression in the message-only classifier path).
  • cargo fmt clean, cargo check --lib clean (only pre-existing unrelated warnings).

Polarity rationale

The narrow helper is the polarity-safe minimum: only the OpenAI-compatible "unknown model" body shape is now treated as user-state regardless of provider. The hosted backend has deliberately adopted that wire shape to mirror the OpenAI /v1/models contract, and the same body carries the same user-state semantics whether the upstream is custom_openai, DeepSeek, OpenRouter, or our own backend. Other phrases that the backend does not emit stay actionable.

If the backend ever starts emitting one of the polarity-gated phrases in error, the existing openhuman_backend_same_body_is_not_suppressed regression test will keep firing the Sentry event so we'd see it.

Summary by CodeRabbit

  • Bug Fixes

    • Improved handling of "unknown model" errors from OpenAI-compatible services to ensure consistent behavior across all provider types, including the hosted backend.
  • Tests

    • Added test coverage for the new error handling logic, including validation across different model variants.

Review Change Stack

…-RUST-2Z1)

The OpenHuman hosted backend now emits the OpenAI-compatible "Model 'X' is
not available. Use GET /openai/v1/models …" wire body for user-configured
unknown model ids — a body shape the polarity guard in
`is_provider_config_rejection_http` had previously assumed only third-party
`custom_openai` upstreams would speak. Result: the per-attempt event
reached Sentry as a real error (TAURI-RUST-2Z1) even though the underlying
condition is pure user-state (the user typed an unknown model id and
configured `model_fallbacks` with `custom:`-prefixed variants that the
backend also rejected).

Drop the polarity guard for that one body shape via a new narrow helper
`is_openai_compatible_unknown_model_message` anchored on the
`/openai/v1/models` remediation hint. Other config-rejection phrases
(DeepSeek `supported api model names are`, Moonshot `invalid temperature`,
litellm envelopes, OpenRouter `requires more credits`) stay polarity-gated
so a regression where our own backend started emitting them would still
reach Sentry.

The aggregate sibling TAURI-RUST-2Z2 is already auto-demoted by the
message-only classifier in `core::observability::expected_error_kind`
(via tinyhumansai#2239's `/openai/v1/models` phrase).
@CodeGhost21 CodeGhost21 requested a review from a team May 21, 2026 19:55
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 21, 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: 5f10aa0a-b908-4e46-a70b-62f289612c9c

📥 Commits

Reviewing files that changed from the base of the PR and between c9ab4b9 and 8ac8a1f.

📒 Files selected for processing (3)
  • src/openhuman/inference/provider/config_rejection.rs
  • src/openhuman/inference/provider/mod.rs
  • src/openhuman/inference/provider/ops.rs

📝 Walkthrough

Walkthrough

This PR adds a new classifier for OpenAI-compatible "unknown model" error messages and integrates it into the HTTP rejection suppression logic. The classifier detects the specific wire shape via the /openai/v1/models remediation hint, and suppresses those payloads as user-state regardless of provider, including the OpenHuman backend. All other config-rejection phrases retain the existing provider-polarity guard.

Changes

Unknown Model Suppression

Layer / File(s) Summary
Unknown model classifier definition and tests
src/openhuman/inference/provider/config_rejection.rs, src/openhuman/inference/provider/mod.rs
New public predicate is_openai_compatible_unknown_model_message() detects the /openai/v1/models remediation hint substring in error bodies; module documentation clarifies this as a polarity exception; test coverage verifies the classifier matches hosted-backend/third-party unknown-model bodies and does not match other config-rejection phrases; function is re-exported via the provider module.
HTTP rejection suppression integration
src/openhuman/inference/provider/ops.rs
is_provider_config_rejection_http() now suppresses OpenAI-compatible unknown-model messages regardless of provider, including OpenHuman backend, while preserving the backend-vs-non-backend polarity guard for all other config-rejection phrases; test suite updated to verify backend non-suppression of tier-leak/temperature bodies and backend suppression of unknown-model variants.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~22 minutes

Possibly related PRs

  • tinyhumansai/openhuman#2346: Uses is_provider_config_rejection_http in streaming paths for logging/suppression, so the behavior change in this PR directly impacts how those streaming config-rejection errors are handled.
  • tinyhumansai/openhuman#2239: Extends the provider-config-rejection pipeline with ProviderConfigRejection wiring and suppression, overlapping with the main PR's new predicate and modified is_provider_config_rejection_http behavior.
  • tinyhumansai/openhuman#2309: Touches the same config_rejection.rs classification logic; the main PR adds an OpenAI-compatible unknown-model exception while the retrieved PR expands the generic phrase matcher, both refining what payloads are treated as deterministic user-state.

Suggested labels

working, bug

Suggested reviewers

  • senamakel
  • graycyrus

Poem

🐰 A model's name was deemed unknown,
So /openai/v1/models made its moan.
Now OpenHuman heeds the call,
Classifies the error—and suppresses all!
User-state it stays, both far and wide,
No more polarity guards to hide. 🎯

🚥 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 pull request title clearly and specifically describes the main change: demoting OpenHuman backend unknown-model 400 errors to suppress user-state observability noise.
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 coderabbitai Bot added working A PR that is being worked on by the team. bug labels May 21, 2026
coderabbitai[bot]
coderabbitai Bot previously approved these changes May 21, 2026
@senamakel senamakel self-assigned this May 23, 2026
# Conflicts:
#	src/openhuman/inference/provider/mod.rs
@senamakel senamakel merged commit fe37b13 into tinyhumansai:main May 23, 2026
22 of 25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug working A PR that is being worked on by the team.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants