feat(inference): cut wire-equivalent BYOK cloud slugs to crate-native (Motion B)#4780
Conversation
… (Motion B) create_chat_model now routes the wire-equivalent BYOK cloud slugs through a crate-native tinyagents OpenAiModel instead of a ProviderModel-wrapped host provider, after the managed + local-runtime short-circuits. Eligibility (conservative — anything uncertain stays on the Provider path): - Anthropic / None auth → always eligible (their endpoints have no /v1/responses, so the host's dormant responses-fallback is behavior-neutral). - Bearer → eligible only with no /v1/responses fallback, no openai-codex OAuth, and no codex account header — i.e. plain chat-completions Bearer providers (DeepSeek, Groq, Mistral, xAI, ...). - openai (Responses API + codex-oauth), custom proxy slugs (may serve /v1/responses), and the managed OpenhumanJwt entry return None and stay host-side (deferred to the crate /responses port, Phase 3). Shared resolution: extract resolve_cloud_slug (entry, effective model with default_model fallback + abstract-tier remapping, key, codex routing) and refactor make_cloud_provider_by_slug onto it — so eligible slugs resolve IDENTICALLY on both paths and only the wire client differs. The existing cloud-slug tests verify the legacy path is behavior-preserved. Safety: the crate OpenAiModel wire is the same one the managed backend uses in production. The same enforce_local_only_inference + verify_session_active gate the Provider path applies runs before building. Temperature rides the per-call ModelRequest (managed/local parity; @<temp> suffix still bakes an override); cloud providers accept a system role so merge_system stays off (parity with OpenAiCompatibleProvider::new). Tests: bearer (deepseek) + anthropic-auth slugs flip crate-native; openai / local / managed / unconfigured decline. Lib compiles clean locally (OOM before finish); full verification on CI, incl. the host cloud-slug regression tests. Claude-Session: https://claude.ai/code/session_01U8NDGbt9tKj443VquzycLB
|
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in: 47 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
Comment |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 3997101499
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| // fallback, and the managed `OpenhumanJwt` entry stay on the `Provider` path. | ||
| let auth = match entry.auth_style { | ||
| AuthStyle::Anthropic => CompatAuthStyle::Anthropic, | ||
| AuthStyle::None => CompatAuthStyle::None, |
There was a problem hiding this comment.
Keep no-auth custom clouds on the provider path
For an AuthStyle::None cloud slug whose endpoint needs the legacy chat-completions-404 → /v1/responses retry, this arm now unconditionally builds the crate OpenAiModel, which the surrounding comment says has no responses fallback. The repo already guards that exact no-auth custom-cloud behavior in cloud_provider_falls_back_to_responses_on_404, so callers using create_chat_model(_with_model_id) with such a provider will now fail on the first /chat/completions 404 instead of retrying /responses; please apply the same fallback eligibility check used for Bearer or leave AuthStyle::None on the Provider path unless the endpoint is known chat-only.
Useful? React with 👍 / 👎.
Summary
create_chat_modelnow routes DeepSeek / Groq / Mistral / xAI / Anthropic-auth / keyless cloud providers through a crate-nativeOpenAiModelinstead of aProviderModel-wrapped host provider.resolve_cloud_slug(entry + effective model + key + codex routing) and refactors the legacymake_cloud_provider_by_slugonto it, so eligible slugs resolve identically on both paths — only the wire client differs.openai(Responses API + codex-OAuth), custom proxy slugs (may serve/v1/responses), and the managedOpenhumanJwtentry stay on theProviderpath.Problem
The inference migration (#4249) is moving provider construction off
Box<dyn Provider>onto the crateChatModel. The managed backend and local runtimes are already crate-native (#4769); the common non-OpenAI BYOK cloud providers were still built as hostOpenAiCompatibleProviders.Solution
try_create_cloud_slug_chat_modelflips only the subset the crateOpenAiModelserves with byte-identical wire semantics — Anthropic/None auth (always; their endpoints have no/v1/responses) and plain-Bearer with no/v1/responsesfallback and no codex-OAuth. It reuses the sharedresolve_cloud_slug, runs the sameenforce_local_only_inference+verify_session_activegate theProviderpath applies, and builds viamake_crate_openai_chat_model(temperature rides the per-call request;merge_systemoff, matchingOpenAiCompatibleProvider::new). Everything uncertain returnsNoneand falls through unchanged.Submission Checklist
openai/ local / managed / unconfigured-slug all decline (theNonefall-through cases). Plus the pre-existingmake_cloud_provider_by_slugcloud-slug tests, which now also assert the shared-resolver refactor is behavior-preserving.rust-core-coveragejob on the changedfactory.rslines.## Related— N/A: none.## Related.Impact
OpenAiCompatibleProvider→ crateOpenAiModel) with identical resolution.openai/codex, custom proxy slugs, and the managed entry are unchanged. Zero intended behavior change.compatible*.rsremains (still servesopenai/codex +create_chat_providercallers) until the crate/responsesport.Related
/v1/responsessupport to flipopenai/codex + custom-proxy slugs, then deletecompatible*.rs.AI Authored PR Metadata
Linear Issue
Commit & Branch
feat/inference-byok-cloud-cutover399710149Validation Run
pnpm --filter openhuman-app format:check— N/A: noapp/changes.pnpm typecheck— N/A: noapp/changes.create_chat_model_routes_*_cloud_slug_to_crate_native,try_create_cloud_slug_declines_openai_and_non_cloud, + the existingmake_cloud_provider_by_slugcloud-slug tests.cargo fmtclean;cargo check --libreached 0 errors locally (OOM-killed before finishing on the contended dev box); full compile/test on CI.app/src-taurichanges.Validation Blocked
command:fullcargo test --lib/ live per-provider wire-parityerror:shared dev box OOM-kills the full lib build; no live cloud test environmentimpact:wire parity rests on the crateOpenAiModelbeing the same client the managed backend uses in production + the shared resolver keeping resolution identical; verified structurally + by the host cloud-slug regression tests on CIBehavior Changes
Parity Contract
resolve_cloud_slug; session/privacy gate preserved; temperature/merge-system parityProviderpath)Duplicate / Superseded PR Handling
https://claude.ai/code/session_01U8NDGbt9tKj443VquzycLB