fix(openai): support reasoning effort#101
Conversation
📝 WalkthroughWalkthroughAdds an optional ChangesReasoning Effort Configuration
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
Review rate limit: 4/5 reviews remaining, refill in 12 minutes. Comment |
🔒 Container Vulnerability Scan (hub-migrations - amd64)Click to expand results |
🔒 Container Vulnerability Scan (hub-migrations - arm64)Click to expand results |
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@src/providers/azure/provider.rs`:
- Around line 27-30: The Azure path gives precedence to base.reasoning_effort
when constructing reasoning_effort (variable reasoning_effort using
base.reasoning_effort and base.reasoning), but the legacy validation still
checks payload.reasoning first and can reject a request even when
base.reasoning_effort is present; update the Azure validation logic so it
mirrors construction precedence: if base.reasoning_effort (or reasoning_effort
after construction) is present, skip/avoid validating legacy payload.reasoning,
otherwise validate payload.reasoning as before. Locate and change the validation
block that references payload.reasoning in the Azure provider to only run when
base.reasoning_effort is None (or when reasoning_effort is None), keeping the
variable names reasoning_effort, base.reasoning_effort, base.reasoning, and
payload.reasoning as references.
In `@src/providers/openai/provider.rs`:
- Around line 26-30: The validation path currently validates legacy
payload.reasoning before the conversion fallback, causing requests with a valid
base.reasoning_effort and an invalid base.reasoning to be rejected; update the
validation logic to mirror the conversion precedence used when building
reasoning_effort: first accept and validate base.reasoning_effort if present,
and only if it is None perform the legacy conversion/validation via
base.reasoning and to_openai_effort(); adjust the validator that checks
payload.reasoning to only run when base.reasoning_effort is absent so the
precedence is consistent with the reasoning_effort initialization.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 6ef84bca-aacb-4080-9754-7618e58dbd2e
📒 Files selected for processing (3)
src/models/chat.rssrc/providers/azure/provider.rssrc/providers/openai/provider.rs
🔒 Container Vulnerability Scan (hub - amd64)Click to expand results |
🔒 Container Vulnerability Scan (hub - arm64)Click to expand results |
There was a problem hiding this comment.
♻️ Duplicate comments (1)
src/providers/openai/provider.rs (1)
88-97:⚠️ Potential issue | 🟠 Major | ⚡ Quick winAdd direct validation for top-level
reasoning_effort.When
reasoning_effortis present, invalid values (including whitespace-only) currently bypass validation and are sent downstream. This keeps validation behavior inconsistent with legacyreasoningand defers a user input error to the provider call path.Suggested fix
- if payload.reasoning_effort.is_none() { + if let Some(effort) = payload.reasoning_effort.as_deref() { + let effort = effort.trim(); + if !["low", "medium", "high"].contains(&effort) { + tracing::error!("Invalid reasoning_effort: {}", effort); + return Err(StatusCode::BAD_REQUEST); + } + } else { if let Some(reasoning) = &payload.reasoning { if let Err(e) = reasoning.validate() { tracing::error!("Invalid reasoning config: {}", e); return Err(StatusCode::BAD_REQUEST); } } }🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/providers/openai/provider.rs` around lines 88 - 97, The top-level payload.reasoning_effort is not validated when present, so invalid/whitespace-only values get sent downstream; update the same validation flow used for legacy payload.reasoning by validating payload.reasoning_effort when Some(...) and returning Err(StatusCode::BAD_REQUEST) on failure: call the same validation routine (or replicate its checks: trim/empty and semantic validation) and log errors via tracing::error! (consistent with reasoning.validate() handling), ensuring behavior matches OpenAIChatCompletionRequest::from precedence.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Duplicate comments:
In `@src/providers/openai/provider.rs`:
- Around line 88-97: The top-level payload.reasoning_effort is not validated
when present, so invalid/whitespace-only values get sent downstream; update the
same validation flow used for legacy payload.reasoning by validating
payload.reasoning_effort when Some(...) and returning
Err(StatusCode::BAD_REQUEST) on failure: call the same validation routine (or
replicate its checks: trim/empty and semantic validation) and log errors via
tracing::error! (consistent with reasoning.validate() handling), ensuring
behavior matches OpenAIChatCompletionRequest::from precedence.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 7eda2a90-130a-4ffa-b852-c4a36ef9843e
📒 Files selected for processing (2)
src/providers/azure/provider.rssrc/providers/openai/provider.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- src/providers/azure/provider.rs
There was a problem hiding this comment.
🧹 Nitpick comments (1)
src/providers/azure/provider.rs (1)
286-330: 🏗️ Heavy liftAdd one provider-level test for the
chat_completionsguard path.These tests cover conversion well, but they don’t directly lock behavior in
AzureProvider::chat_completions(Line 87). A regression there could reintroduce the old rejection path even with a valid top-level effort. Consider adding one async/provider-level test where top-levelreasoning_effortis set and legacyreasoningis invalid, and assert it is not rejected at validation time.🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@src/providers/azure/provider.rs` around lines 286 - 330, Add an async provider-level test that ensures AzureProvider::chat_completions accepts a request with a top-level reasoning_effort when a legacy nested Reasoning is invalid: create a #[tokio::test] async fn (e.g., accepts_top_level_effort_over_legacy_rejection) that builds the same base_request, sets req.reasoning_effort = Some("minimal".to_string()) and sets req.reasoning = Some(ReasoningConfig { effort: None, ..Default::default() }) or otherwise invalid legacy reasoning, constructs an AzureProvider instance (matching existing test setup), calls provider.chat_completions(req).await and asserts the call succeeds (is Ok) or does not return the old validation/rejection error; reference AzureProvider::chat_completions and AzureChatCompletionRequest conversion to locate where to wire the request.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Nitpick comments:
In `@src/providers/azure/provider.rs`:
- Around line 286-330: Add an async provider-level test that ensures
AzureProvider::chat_completions accepts a request with a top-level
reasoning_effort when a legacy nested Reasoning is invalid: create a
#[tokio::test] async fn (e.g., accepts_top_level_effort_over_legacy_rejection)
that builds the same base_request, sets req.reasoning_effort =
Some("minimal".to_string()) and sets req.reasoning = Some(ReasoningConfig {
effort: None, ..Default::default() }) or otherwise invalid legacy reasoning,
constructs an AzureProvider instance (matching existing test setup), calls
provider.chat_completions(req).await and asserts the call succeeds (is Ok) or
does not return the old validation/rejection error; reference
AzureProvider::chat_completions and AzureChatCompletionRequest conversion to
locate where to wire the request.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: 346a015b-79a4-4745-9c79-af6ac986f8c8
📒 Files selected for processing (2)
src/providers/azure/provider.rssrc/providers/openai/provider.rs
🚧 Files skipped from review as they are similar to previous changes (1)
- src/providers/openai/provider.rs
Summary by CodeRabbit
New Features
Behavior Change
Tests