Skip to content

feat(api): enhance reasoning content checks - #813

Merged
steebchen merged 3 commits into
mainfrom
feat/apicontent
Sep 14, 2025
Merged

steebchen merged 3 commits into
mainfrom
feat/apicontent

Conversation

@steebchen

@steebchen steebchen commented Sep 14, 2025

Copy link
Copy Markdown
Member

Conditionally enforce reasoning content validation for OpenAI responses when USE_RESPONSES_API is enabled. Prevent unnecessary checks for other providers.

Summary by CodeRabbit

  • Tests
    • Updated end-to-end reasoning tests to better handle provider-specific behavior.
    • Applies the same gating to streaming and non-streaming checks so reasoning content is only asserted when appropriate for the provider and configuration.
    • Skips reasoning content assertions for OpenAI when the Responses API is not enabled; other providers retain prior behavior.
    • No changes to public APIs or user-facing features.

Conditionally enforce reasoning content validation for OpenAI responses when `USE_RESPONSES_API`
is enabled. Prevent unnecessary checks for other providers.
@coderabbitai

coderabbitai Bot commented Sep 14, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

E2E tests updated to cast the selected reasoning provider to ProviderModelMapping, use optional chaining for reasoning fields, and gate assertions so reasoning_content is skipped for OpenAI when USE_RESPONSES_API is not enabled or when reasoningOutput === "omit". (46 words)

Changes

Cohort / File(s) Summary of Changes
E2E tests (reasoning gating & typing)
apps/gateway/src/api.e2e.ts
- Cast provider lookup to ProviderModelMapping
- Use optional chaining for reasoning fields (reasoningProvider?.reasoningOutput)
- Add gating booleans (useResponsesApi, isOpenAI) and require reasoningOutput !== "omit" and `(!isOpenAI

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant T as Test Runner
  participant G as Gateway E2E Test
  participant P as Provider Config
  participant E as Env (USE_RESPONSES_API)

  T->>G: Run reasoning (non-streaming/streaming) test
  G->>P: Find provider where reasoning === true
  Note right of G: Cast to ProviderModelMapping\nUse optional chaining for reasoning fields
  G->>E: Read USE_RESPONSES_API
  alt Assert reasoning_content
    Note over G,P: reasoningOutput !== "omit"\nand (NOT (providerId === "openai" AND USE_RESPONSES_API !== "true"))
    G->>G: Assert `reasoning_content` present
  else Skip assertion
    G->>G: Do not assert `reasoning_content`
  end
  G-->>T: Test result
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title Check ✅ Passed The title "feat(api): enhance reasoning content checks" succinctly and accurately summarizes the primary change — it indicates an API-focused feature that modifies reasoning content validation, is concise, and follows conventional commit style so a teammate can quickly understand the main intent.
Docstring Coverage ✅ Passed No functions found in the changes. Docstring coverage check skipped.
✨ Finishing touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/apicontent

📜 Recent review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between bb7e650 and af84186.

📒 Files selected for processing (1)
  • apps/gateway/src/api.e2e.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • apps/gateway/src/api.e2e.ts
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: e2e / run
  • GitHub Check: build / run

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

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

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
apps/gateway/src/api.e2e.ts (1)

869-884: Extend the same gating to “reasoning + tool calls” for consistency.

Currently this block enforces reasoning_content regardless of USE_RESPONSES_API; bring it in line with the other tests.

-        if (
-          (reasoningProvider as ProviderModelMapping)?.reasoningOutput !==
-          "omit"
-        ) {
+        const useResponsesApi = process.env.USE_RESPONSES_API === "true";
+        const isOpenAI = reasoningProvider?.providerId === "openai";
+        if (
+          reasoningProvider?.reasoningOutput !== "omit" &&
+          (!useResponsesApi || isOpenAI)
+        ) {
🧹 Nitpick comments (2)
apps/gateway/src/api.e2e.ts (2)

632-636: Fix misleading inline comment.

The comment says “only enforce ... for openai on the responses API” but the surrounding condition negated it. After applying the corrected logic, keep the comment as “When using the Responses API, only enforce ... for OpenAI.”

Also applies to: 750-754


626-629: Prefer a type guard over assertion casts.

Use a predicate type guard to avoid as and keep types sound.

Example:

const reasoningProvider = providers?.find(
  (p: ProviderModelMapping): p is ProviderModelMapping & { reasoning: true } =>
    p.reasoning === true,
);

Also applies to: 744-747

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f47b9e9 and bb7e650.

📒 Files selected for processing (1)
  • apps/gateway/src/api.e2e.ts (2 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.{ts,tsx,js,jsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Always use top-level import; never use require() or dynamic import()

Always use top-level import; never use require or dynamic imports

Files:

  • apps/gateway/src/api.e2e.ts
{apps/{api,gateway}/**/*.ts,packages/db/**/*.ts}

📄 CodeRabbit inference engine (CLAUDE.md)

{apps/{api,gateway}/**/*.ts,packages/db/**/*.ts}: For database reads, use Drizzle’s db().query.

.findMany() or db().query.
.findFirst()
Use Drizzle ORM with the latest object syntax

Files:

  • apps/gateway/src/api.e2e.ts
**/*.e2e.ts

📄 CodeRabbit inference engine (AGENTS.md)

Name end-to-end test files with the .e2e.ts suffix

Files:

  • apps/gateway/src/api.e2e.ts
apps/{api,gateway}/**/*.{ts,tsx}

📄 CodeRabbit inference engine (AGENTS.md)

apps/{api,gateway}/**/*.{ts,tsx}: Use Drizzle ORM with the latest object syntax for database access
For reads, use db().query.

.findMany() or db().query.
.findFirst()
After API route changes, run pnpm generate to update OpenAPI schemas

Files:

  • apps/gateway/src/api.e2e.ts
🧬 Code graph analysis (1)
apps/gateway/src/api.e2e.ts (1)
packages/models/src/models.ts (1)
  • ProviderModelMapping (23-100)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: build / run
  • GitHub Check: e2e / run
🔇 Additional comments (1)
apps/gateway/src/api.e2e.ts (1)

626-638: Fix inverted gating: only enforce reasoning checks for OpenAI when USE_RESPONSES_API=true

Current condition inverts intent — it enforces checks for non‑OpenAI when USE_RESPONSES_API="true". Apply the following change (apps/gateway/src/api.e2e.ts ~lines 626–638):

-      ) as ProviderModelMapping;
+      );
-      if (
-        reasoningProvider?.reasoningOutput !== "omit" &&
-        !(
-          // only enforce reasoning content checks for openai on the responses API
-          (
-            process.env.USE_RESPONSES_API === "true" &&
-            reasoningProvider?.providerId === "openai"
-          )
-        )
-      ) {
+      const useResponsesApi = process.env.USE_RESPONSES_API === "true";
+      const isOpenAI = reasoningProvider?.providerId === "openai";
+      // When using the Responses API, only enforce reasoning_content checks for OpenAI.
+      if (
+        reasoningProvider?.reasoningOutput !== "omit" &&
+        (!useResponsesApi || isOpenAI)
+      ) {

Remove the unnecessary as ProviderModelMapping cast (nit). Tests couldn't be executed in the sandbox (ENOENT: /home/jailuser/apps). Run locally to confirm:

USE_RESPONSES_API=true pnpm -C apps/gateway test -t "reasoning"
USE_RESPONSES_API=false pnpm -C apps/gateway test -t "reasoning"

Comment on lines 744 to 756
const reasoningProvider = providers?.find(
(p: ProviderModelMapping) => p.reasoning === true,
);
) as ProviderModelMapping;
if (
(reasoningProvider as ProviderModelMapping)?.reasoningOutput !== "omit"
reasoningProvider?.reasoningOutput !== "omit" &&
!(
// only enforce reasoning content checks for openai on the responses API
(
process.env.USE_RESPONSES_API === "true" &&
reasoningProvider?.providerId === "openai"
)
)
) {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Same inversion in streaming reasoning test; align gating and remove unsafe cast.

Mirror the corrected logic from the non‑streaming test so we only enforce for OpenAI when Responses API is enabled.

-      ) as ProviderModelMapping;
-      if (
-        reasoningProvider?.reasoningOutput !== "omit" &&
-        !(
-          // only enforce reasoning content checks for openai on the responses API
-          (
-            process.env.USE_RESPONSES_API === "true" &&
-            reasoningProvider?.providerId === "openai"
-          )
-        )
-      ) {
+      );
+      const useResponsesApi = process.env.USE_RESPONSES_API === "true";
+      const isOpenAI = reasoningProvider?.providerId === "openai";
+      // When using the Responses API, only enforce reasoning_content checks for OpenAI.
+      if (
+        reasoningProvider?.reasoningOutput !== "omit" &&
+        (!useResponsesApi || isOpenAI)
+      ) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const reasoningProvider = providers?.find(
(p: ProviderModelMapping) => p.reasoning === true,
);
) as ProviderModelMapping;
if (
(reasoningProvider as ProviderModelMapping)?.reasoningOutput !== "omit"
reasoningProvider?.reasoningOutput !== "omit" &&
!(
// only enforce reasoning content checks for openai on the responses API
(
process.env.USE_RESPONSES_API === "true" &&
reasoningProvider?.providerId === "openai"
)
)
) {
const reasoningProvider = providers?.find(
(p: ProviderModelMapping) => p.reasoning === true,
);
const useResponsesApi = process.env.USE_RESPONSES_API === "true";
const isOpenAI = reasoningProvider?.providerId === "openai";
// When using the Responses API, only enforce reasoning_content checks for OpenAI.
if (
reasoningProvider?.reasoningOutput !== "omit" &&
(!useResponsesApi || isOpenAI)
) {
🤖 Prompt for AI Agents
In apps/gateway/src/api.e2e.ts around lines 744 to 756, the streaming reasoning
test uses an inverted gating condition and an unsafe cast; change the logic to
mirror the non-streaming test so reasoning content checks are enforced only when
process.env.USE_RESPONSES_API === "true" AND the selected providerId ===
"openai", and remove the unsafe "as ProviderModelMapping" cast by properly
typing or narrowing the result of providers?.find (e.g., check for undefined
before accessing properties or use a typed predicate) so the condition becomes:
if (reasoningProvider?.reasoningOutput !== "omit" &&
process.env.USE_RESPONSES_API === "true" && reasoningProvider?.providerId ===
"openai") { ... }.

Refactor conditional checks for reasoning content validation by introducing reusable variables and improving readability.
Applies consistent behavior for "USE_RESPONSES_API" and "providerId" conditions.
Update conditional logic for enforcing reasoning content checks to properly handle `reasoningOutput` and `USE_RESPONSES_API` variables.
Prevent unintended validation skips for OpenAI responses.
@steebchen
steebchen enabled auto-merge September 14, 2025 18:21
@steebchen
steebchen added this pull request to the merge queue Sep 14, 2025
Merged via the queue into main with commit 6686678 Sep 14, 2025
10 of 11 checks passed
@steebchen
steebchen deleted the feat/apicontent branch September 14, 2025 18:27
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.

1 participant