Skip to content

feat(chat): enhance chat functionality with image configuration and reasoning effort options - #1211

Merged
smakosh merged 3 commits into
mainfrom
feat/playground-features
Nov 21, 2025
Merged

smakosh merged 3 commits into
mainfrom
feat/playground-features

Conversation

@smakosh

@smakosh smakosh commented Nov 20, 2025

Copy link
Copy Markdown
Member
  • Added support for customizable image aspect ratios and sizes in chat messages.
  • Introduced reasoning effort selection to improve AI response quality.
  • Updated error handling to provide more informative messages.
  • Refactored model mapping to ensure accurate capabilities detection.

This update enhances user experience by allowing more control over image generation and reasoning parameters during chat interactions.

Fixes

Summary by CodeRabbit

  • New Features

    • Reasoning effort controls (Minimal/Low/Medium/High) and image-generation settings (aspect ratio, resolution) in the chat UI
    • Root model selection with auto‑routing, preview/details for root vs provider-backed models
    • Improved error handling with a normalized error message utility and automatic chat cleanup on failures
    • Updated Resources menu and navbar layout
  • Chores

    • Bumped @llmgateway/ai-sdk-provider dependency to 2.5.0

✏️ Tip: You can customize this high-level summary in your review settings.

…easoning effort options

- Added support for customizable image aspect ratios and sizes in chat messages.
- Introduced reasoning effort selection to improve AI response quality.
- Updated error handling to provide more informative messages.
- Refactored model mapping to ensure accurate capabilities detection.

This update enhances user experience by allowing more control over image generation and reasoning parameters during chat interactions.
@smakosh smakosh self-assigned this Nov 20, 2025
@coderabbitai

coderabbitai Bot commented Nov 20, 2025

Copy link
Copy Markdown
Contributor

Walkthrough

Updates playground dependency, adds image generation and reasoning fields to chat API and client/UI, introduces root (auto-routing) model entries and filters, centralizes error-message extraction, refactors model mapping, and updates navbar resources and layout.

Changes

Cohort / File(s) Summary
Dependency bump
apps/playground/package.json
Bumped @llmgateway/ai-sdk-provider from 2.3.12.5.0.
Chat API: image & reasoning
apps/playground/src/app/api/chat/route.ts
Added image_config (aspect_ratio, image_size) and reasoning_effort to ChatRequestBody; extract and forward them into providerOptions for MCP and default streaming paths; improved structured error responses.
Chat client wiring & cleanup
apps/playground/src/components/playground/chat-page-client.tsx
Added state/props and lifecycle for reasoningEffort, imageAspectRatio, imageSize; compute supportsReasoning/supportsImageGen; include reasoning_effort and image_config when sending messages; add new-chat failure cleanup and use centralized getErrorMessage + toast.
Chat UI controls
apps/playground/src/components/playground/chat-ui.tsx
Extended ChatUIProps and UI to surface reasoning effort and image-generation selectors; conditional rendering based on supportsReasoning/supportsImageGen; image rendering tweaks and streaming image loader.
Model selector + root entries
apps/playground/src/components/model-selector.tsx, apps/playground/src/lib/mapmodels.ts
Introduced root (auto) model entries and showOnlyRoot filter; refactored entry shape (isRoot, searchText, mapping optional); mapModels emits root-level ComboboxModel per model and adjusts provider-specific IDs to providerId/m.id.
Reasoning UX message
apps/playground/src/components/ai-elements/reasoning.tsx
Adjusted getThinkingMessage control flow: prefer isStreaming branch; distinguish undefined/0 duration vs positive durations for "Thought..." messages.
Error handling centralization
apps/playground/src/lib/utils.ts, apps/playground/src/hooks/useChats.ts
Added exported getErrorMessage(error: any): string; replaced onError handlers in useCreateChat, useUpdateChat, useDeleteChat, useAddMessage to use toast.error(getErrorMessage(error)) and accept generic error param.
Navbar resources update
apps/ui/src/components/landing/navbar.tsx
Added Resources items (Providers, Docs, Compare, Contact Us), removed Chat from Resources links, and adjusted nav container layout classes.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant ChatPageClient
    participant ChatAPI as /api/chat
    participant Provider
    participant MCP as GitHub_MCP

    User->>ChatPageClient: select image/reasoning options + send message
    ChatPageClient->>ChatPageClient: build body with image_config & reasoning_effort
    ChatPageClient->>ChatAPI: POST /api/chat (body includes image_config, reasoning_effort)

    activate ChatAPI
    ChatAPI->>ChatAPI: extract image_config & reasoning_effort
    alt GitHub MCP path
        ChatAPI->>MCP: call MCP with providerOptions { image_config, reasoning_effort }
        MCP-->>ChatAPI: stream response
    else Default provider path
        ChatAPI->>Provider: stream with providerOptions { image_config, reasoning_effort }
        Provider-->>ChatAPI: stream response
    end
    ChatAPI-->>ChatPageClient: stream messages (including image blocks)
    deactivate ChatAPI

    ChatPageClient->>User: render messages, images, reasoning UI
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~50 minutes

  • Pay extra attention to:
    • apps/playground/src/components/model-selector.tsx and apps/playground/src/lib/mapmodels.ts for root vs provider entry consistency and ID format changes.
    • apps/playground/src/components/playground/chat-page-client.tsx for new state/lifecycle, new-chat cleanup, and correct propagation of image_config / reasoning_effort.
    • apps/playground/src/lib/utils.ts and usages in hooks/clients to ensure error normalization covers expected error shapes.

Possibly related PRs

Suggested reviewers

  • steebchen

Pre-merge checks and finishing touches

❌ Failed checks (1 warning)
Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 18.18% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately reflects the main changes: adding image configuration options and reasoning effort selection to enhance chat functionality across multiple files.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch feat/playground-features

📜 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 fbe2d61 and 6a547ca.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (1)
  • apps/playground/package.json (1 hunks)
⏰ 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). (12)
  • GitHub Check: build-split (worker, linux/amd64)
  • GitHub Check: build-split (playground, linux/amd64)
  • GitHub Check: build-split (docs, linux/amd64)
  • GitHub Check: build-split (ui, linux/amd64)
  • GitHub Check: build-split (gateway, linux/amd64)
  • GitHub Check: build-split (api, linux/amd64)
  • GitHub Check: build-unified (linux/amd64)
  • GitHub Check: generate / run
  • GitHub Check: lint / run
  • GitHub Check: build / run
  • GitHub Check: test / run
  • GitHub Check: autofix
🔇 Additional comments (1)
apps/playground/package.json (1)

22-22: Upgrade provider to support new image and reasoning features.

The version bump from 2.3.1 to 2.5.0 is a minor upgrade and should maintain backward compatibility. This upgrade enables the new image_config and reasoning_effort capabilities referenced in the PR objectives.

Verify that downstream files properly leverage the upgraded provider's new capabilities by ensuring all chat route, UI components, and model mapping files (e.g., apps/playground/src/app/api/chat/route.ts, apps/playground/src/components/playground/chat-ui.tsx, apps/playground/src/lib/mapmodels.ts) are fully compatible with version 2.5.0 and handle the new features as expected.


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

🧹 Nitpick comments (10)
apps/playground/src/components/ai-elements/reasoning.tsx (1)

129-136: Minor copy nit: handle singular “second” when duration === 1

Right now duration = 1 produces “Thought for 1 seconds”. Consider a tiny tweak for nicer UX:

} else {
  const unit = duration === 1 ? "second" : "seconds";
  return <p>Thought for {duration} {unit}</p>;
}
apps/playground/src/lib/mapmodels.ts (1)

10-31: Tidy up root mapping: unused data and outdated comment

Functionally this mapping looks fine, but a few cleanups would reduce confusion:

  1. Outdated comment vs. implementation (Lines 34‑43, 45)
    The comment discusses possibly keeping providerId/p.modelName, but the id is now ${p.providerId}/${m.id}. That mismatch is likely to confuse future readers. I’d update the comment to describe the current contract (“IDs are providerId/m.id to match ModelSelector”) or remove the speculative bits.

  2. Unused providerInfo in rootProviders (Lines 11‑14, 17‑18)
    rootProviders spreads providerInfo, but only p.vision and p.tools are read. You can simplify to just use m.providers directly, e.g.:

    const hasVision = m.providers.some((p) => p.vision);
    const hasTools = m.providers.some((p) => p.tools);

    That avoids an extra map and unused property.

  3. Reuse hasImageGen for provider entries (Lines 17‑20, 55)
    Since hasImageGen already captures m.output?.includes("image"), you can reuse it in the per‑provider entries instead of repeating the expression:

    const hasImageGen = m.output?.includes("image");
    
    // later
    imageGen: hasImageGen,

These are non‑blocking but will make the function easier to maintain.

Also applies to: 32-56

apps/playground/src/components/playground/chat-ui.tsx (2)

350-374: Image rendering height is fixed at 400px; consider making it responsive

The new image class

className="h-[400px] aspect-auto border rounded-lg object-cover"

gives a nice uniform grid but forces every image to 400px height, which may be tall on small screens and can over‑crop very wide images with object-cover. If you want a bit more responsiveness, consider using a max height instead:

className="max-h-[400px] w-full border rounded-lg object-cover"

so large images are constrained but smaller ones aren’t upscaled as aggressively.

The added streaming loader fallback for the last assistant message when there are no images (isLastMessage && status === "streaming") is a nice UX touch.


72-88: Verification confirms: values are correctly wired into requests

The implementation properly handles the new props:

  • Line 581 passes sendMessageWithHeaders to ChatUI as the sendMessage prop
  • The wrapper (lines 220–253) correctly merges reasoningEffort as reasoning_effort and imageConfig into the request body
  • Dependencies are tracked in the callback's dependency array
  • Combined with the ai SDK's documented behavior of merging request-level body fields with hook-level configuration, the values will reach the API call correctly.

The literal union suggestion (duplicated in props type and casts) remains valid but optional—centralizing type ReasoningEffort = "" | "minimal" | ... would improve maintainability without being essential.

apps/ui/src/components/landing/navbar.tsx (1)

84-91: Align mobile Resources menu with Next.js 15 best practices for external and mailto: links

The mobile Resources menu (lines 287-297) currently renders all resourcesItems through Next's <Link> component, including the external Docs URL and the mailto: Contact Us link. This violates Next.js 15 best practices and creates UX/type-safety issues:

  • External URLs and mailto: links should use regular anchor tags, not Link
  • Docs (external) will behave as an internal route unlike the desktop version
  • mailto: forced through Link conflicts with typed routes

Update the mobile rendering to conditionally use <a> for external entries and mailto: links, matching desktop behavior:

{resourcesItems.map((item, index) => (
  <li key={index}>
    {item.external || item.href.startsWith("mailto:") ? (
      <a
        href={item.href}
        target={item.href.startsWith("http") ? "_blank" : undefined}
        rel={item.href.startsWith("http") ? "noopener noreferrer" : undefined}
        className="text-muted-foreground hover:text-accent-foreground block duration-150"
      >
        {item.name}
      </a>
    ) : (
      <Link
        href={item.href as Route}
        className="text-muted-foreground hover:text-accent-foreground block duration-150"
        prefetch={true}
      >
        {item.name}
      </Link>
    )}
  </li>
))}

Also consider adding external: true to the Contact Us mailto: entry for consistency.

apps/playground/src/lib/utils.ts (1)

8-53: Centralized error normalization is solid; consider one more fallback path

The branching covers the common shapes (string, Zod/OpenAPI error envelope, and plain { message }), and it’s safe from runtime exceptions. To make it a bit more robust, you could also look for a message on the candidate objects you iterate (e.g., candidate.message) before falling back to the root error.message, so cases like { error: { message: "..." } } without success === false are handled as well.

apps/playground/src/app/api/chat/route.ts (2)

18-38: Align ChatRequestBody typing with actual payload (reasoning_effort)

You’re reading reasoning_effort from the body via const reasoningEffort = (body as any)?.reasoning_effort, but it isn’t declared on ChatRequestBody. Typing it there will keep the route and callers in sync and remove the any escape hatch.

For example:

 interface ChatRequestBody {
   messages: UIMessage[];
   model?: LLMGatewayChatModelId;
   apiKey?: string;
   provider?: string; // optional provider override
   mode?: "image" | "chat"; // optional hint to force image generation path
   image_config?: {
     aspect_ratio?:
       | "auto"
       | "1:1"
       | "9:16"
       | "3:4"
       | "4:3"
       | "3:2"
       | "2:3"
       | "5:4"
       | "4:5"
       | "21:9";
     image_size?: "1K" | "2K" | "4K";
   };
+  reasoning_effort?: "minimal" | "low" | "medium" | "high";
 }
@@
- const { messages, model, apiKey, provider, image_config }: ChatRequestBody =
-   body;
+ const {
+   messages,
+   model,
+   apiKey,
+   provider,
+   image_config,
+   reasoning_effort,
+ }: ChatRequestBody = body;
@@
- const reasoningEffort = (body as any)?.reasoning_effort || undefined;
+ const reasoningEffort = reasoning_effort;

Also applies to: 49-52, 63-64


97-121: Reasoning/image providerOptions wiring is consistent; minor optional tightening

The way reasoningEffort and image_config are threaded into providerOptions for both the MCP and default paths is coherent, and the conditional spread in the default path avoids sending providerOptions when nothing is set.

If you want symmetry and slightly cleaner payloads, you could mirror that pattern in the MCP branch so providerOptions is only sent when at least one of reasoningEffort or image_config is defined (and omit reasoning_effort when undefined), but the current logic is functionally fine.

Also applies to: 128-144

apps/playground/src/components/playground/chat-page-client.tsx (1)

6-7: Error handling and new‑chat cleanup flow are well thought out, with a tiny state nit

Using getErrorMessage plus toast.error across useChat’s onError, the image/tool JSON parse blocks, and handleUserMessage gives you consistent, user-friendly errors. The logic to delete a just-created chat when the first response or first user message fails (using isNewChatRef and chatIdRef) is also a good safeguard against orphaned chats.

One minor nit: if ensureCurrentChat throws before a chat is created, isNewChatRef.current stays true from handleUserMessage, even though there is no active chat. It doesn’t break anything because all cleanup paths also check chatIdRef.current, but you could reset it in that catch to keep the ref strictly accurate.

Also applies to: 21-22, 26-27, 102-126, 315-328, 386-410, 416-448

apps/playground/src/components/model-selector.tsx (1)

60-66: Coerce checkbox checked state to boolean when updating filters

FilterState.hideUnstable and FilterState.showOnlyRoot are declared as booleans, but onCheckedChange from the Checkbox component typically receives a CheckedState (boolean | "indeterminate"). Passing checked through directly into updateFilter means those fields can end up with "indeterminate" at runtime.

It would be a small type/semantics improvement to coerce explicitly, e.g.:

<Checkbox
  id="show-root"
  checked={filters.showOnlyRoot}
- onCheckedChange={(checked) =>
-   updateFilter("showOnlyRoot", checked)
- }
+ onCheckedChange={(checked) =>
+   updateFilter("showOnlyRoot", checked === true)
+ }
/>
@@
<Checkbox
  id="hide-unstable"
  checked={filters.hideUnstable}
- onCheckedChange={(checked) =>
-   updateFilter("hideUnstable", checked)
- }
+ onCheckedChange={(checked) =>
+   updateFilter("hideUnstable", checked === true)
+ }
/>

This keeps FilterState strictly boolean while preserving current UX.

Also applies to: 295-307, 319-327, 503-516, 644-649

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 31f8f27 and 7b686fa.

⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml
📒 Files selected for processing (10)
  • apps/playground/package.json (1 hunks)
  • apps/playground/src/app/api/chat/route.ts (5 hunks)
  • apps/playground/src/components/ai-elements/reasoning.tsx (1 hunks)
  • apps/playground/src/components/model-selector.tsx (19 hunks)
  • apps/playground/src/components/playground/chat-page-client.tsx (13 hunks)
  • apps/playground/src/components/playground/chat-ui.tsx (6 hunks)
  • apps/playground/src/hooks/useChats.ts (5 hunks)
  • apps/playground/src/lib/mapmodels.ts (1 hunks)
  • apps/playground/src/lib/utils.ts (1 hunks)
  • apps/ui/src/components/landing/navbar.tsx (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (7)
apps/playground/src/lib/utils.ts (1)
packages/logger/src/index.ts (1)
  • error (153-160)
apps/playground/src/lib/mapmodels.ts (1)
packages/models/src/providers.ts (1)
  • providers (21-302)
apps/playground/src/app/api/chat/route.ts (1)
packages/db/src/schema.ts (1)
  • message (538-560)
apps/playground/src/hooks/useChats.ts (1)
apps/playground/src/lib/utils.ts (1)
  • getErrorMessage (8-54)
apps/playground/src/components/model-selector.tsx (5)
packages/models/src/models.ts (2)
  • ProviderModelMapping (51-158)
  • ModelDefinition (162-214)
packages/models/src/providers.ts (2)
  • ProviderDefinition (1-19)
  • providers (21-302)
apps/ui/src/lib/model-utils.ts (3)
  • getProviderForModel (29-35)
  • formatPrice (3-14)
  • formatContextSize (16-27)
apps/playground/src/lib/utils.ts (1)
  • cn (4-6)
apps/ui/src/lib/components/providers-icons.tsx (1)
  • getProviderIcon (1171-1184)
apps/playground/src/components/playground/chat-ui.tsx (2)
apps/playground/src/components/ui/image-zoom.tsx (1)
  • ImageZoom (16-52)
apps/playground/src/components/ai-elements/loader.tsx (1)
  • Loader (87-97)
apps/playground/src/components/playground/chat-page-client.tsx (2)
apps/playground/src/lib/utils.ts (1)
  • getErrorMessage (8-54)
apps/playground/src/hooks/useChats.ts (3)
  • useCreateChat (50-64)
  • useAddMessage (98-111)
  • useDeleteChat (82-96)
⏰ 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). (12)
  • GitHub Check: build-split (docs, linux/amd64)
  • GitHub Check: build-split (ui, linux/amd64)
  • GitHub Check: build-split (worker, linux/amd64)
  • GitHub Check: build-split (playground, linux/amd64)
  • GitHub Check: build-split (gateway, linux/amd64)
  • GitHub Check: build-split (api, linux/amd64)
  • GitHub Check: build-unified (linux/amd64)
  • GitHub Check: test / run
  • GitHub Check: build / run
  • GitHub Check: generate / run
  • GitHub Check: lint / run
  • GitHub Check: autofix
🔇 Additional comments (6)
apps/playground/package.json (1)

18-24: Confirm @llmgateway/ai-sdk-provider 2.4.0 compatibility

The version bump looks reasonable, but please double‑check that existing usages of the provider (chat route, streaming, providerOptions, image/reasoning options) match any API changes in 2.4.0 (e.g., required fields, option names).

apps/ui/src/components/landing/navbar.tsx (1)

147-150: Navbar container width/padding change looks reasonable

The updated base container (max-w-7xl px-6) plus tighter scrolled state (max-w-6xl lg:px-5) should be fine; just sanity‑check in design review that the width jump on scroll is the desired effect and doesn’t feel jittery.

apps/playground/src/components/playground/chat-ui.tsx (1)

429-429: Footer container shrink behavior change is fine

Switching from flex-shrink-0 to shrink-0 keeps the prompt area fixed-height at the bottom in modern Tailwind and should behave identically; no issues here.

apps/playground/src/hooks/useChats.ts (1)

5-6: Consistent error handling via getErrorMessage looks good

Using toast.error(getErrorMessage(error)) across all mutations gives you uniform, more resilient error messaging regardless of the error shape, and relaxing the onError parameter type aligns with that utility.

Also applies to: 54-63, 70-79, 86-95, 102-111

apps/playground/src/components/playground/chat-page-client.tsx (1)

64-81: Reasoning and image configuration wiring matches model capabilities nicely

The new reasoningEffort, imageAspectRatio, and imageSize state, plus the supportsImages, supportsImageGen, and supportsReasoning selectors, correctly derive capabilities from ComboboxModel/ModelDefinition and keep the UI in sync. The useEffect that clears reasoningEffort when switching to a non‑reasoning model is a good safety net.

sendMessageWithHeaders only sends reasoning_effort and image_config when applicable and when image generation is supported, which keeps the API payload lean and avoids hitting models with unsupported options. Passing all of these props through to ChatUI completes the circuit cleanly.

Also applies to: 85-86, 186-201, 220-253, 493-498, 588-595

apps/playground/src/components/model-selector.tsx (1)

60-66: Root (auto‑routing) model support and preview UX are well integrated

The approach of modeling root entries via isRoot with value = model.id, alongside provider‑specific entries with value = providerId/model.id, is consistent with how selectedModelId/selectedProviderId are parsed. The filters and search use normalized searchText, root entries respect showOnlyRoot and stability rules, and the desktop preview + details dialog cleanly distinguish root (sparkles + auto‑select copy) from provider‑backed mappings, including pricing and capabilities.

This aligns nicely with the rest of the model mapping/types and should make the root vs provider experience clear to users.

Also applies to: 128-140, 161-207, 337-378, 682-743, 825-974, 987-1041

Comment thread apps/playground/src/app/api/chat/route.ts
- Simplified the construction of provider options by directly spreading reasoning effort and image configuration into the request.
- Removed unnecessary nesting of provider options, enhancing code readability and maintainability.

This change improves the clarity of the chat API's request structure while maintaining existing functionality.

@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: 2

♻️ Duplicate comments (1)
apps/playground/src/app/api/chat/route.ts (1)

133-138: Do not return raw error objects to clients; sanitize and guard status

Returning details: error risks leaking internal metadata (SDK response objects, config, etc.) and may break if the error carries non‑serializable fields. Using error.status directly can also produce invalid HTTP codes.

A safer pattern is to log the full error server‑side and expose only a minimal, sanitized shape:

- } catch (error: any) {
-   const message = error.message || "LLM Gateway request failed";
-   const status = error.status || 500;
-   return new Response(JSON.stringify({ error: message, details: error }), {
-     status,
-   });
- }
+ } catch (error: any) {
+   console.error("LLM Gateway chat route error", error);
+
+   const message =
+     typeof error?.message === "string"
+       ? error.message
+       : "LLM Gateway request failed";
+
+   const status =
+     typeof error?.status === "number" &&
+     error.status >= 400 &&
+     error.status <= 599
+       ? error.status
+       : 500;
+
+   const safeDetails =
+     process.env.NODE_ENV === "development"
+       ? {
+           code: error?.code,
+           status: error?.status,
+           type: error?.type,
+         }
+       : undefined;
+
+   return new Response(
+     JSON.stringify({
+       error: message,
+       ...(safeDetails && { details: safeDetails }),
+     }),
+     { status },
+   );
+ }

This keeps logs useful while avoiding accidental data leakage in responses.

🧹 Nitpick comments (1)
apps/playground/src/app/api/chat/route.ts (1)

50-51: Avoid any for request body; type reasoning_effort (and githubToken) in ChatRequestBody

Right now image_config is typed, but reasoning_effort (and githubToken) are pulled via (body as any). That undermines the benefit of ChatRequestBody and makes field name typos harder to catch.

Consider extending ChatRequestBody with these fields and reading them via destructuring instead of any, e.g.:

interface ChatRequestBody {
  messages: UIMessage[];
  model?: LLMGatewayChatModelId;
  apiKey?: string;
  provider?: string;
  mode?: "image" | "chat";
  image_config?: { /* ... */ };
  githubToken?: string;
  reasoning_effort?: string; // or a narrower union if you have one
}

// ...

const {
  messages,
  model,
  apiKey,
  provider,
  image_config,
  githubToken,
  reasoning_effort,
}: ChatRequestBody = body;

const tokenForMcp = githubTokenHeader || githubToken;
const reasoningEffort = reasoning_effort;

This keeps the server route aligned with the client payload and avoids silent shape drift.

Also applies to: 63-63

📜 Review details

Configuration used: CodeRabbit UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 7b686fa and fbe2d61.

📒 Files selected for processing (1)
  • apps/playground/src/app/api/chat/route.ts (5 hunks)
🧰 Additional context used
🧬 Code graph analysis (1)
apps/playground/src/app/api/chat/route.ts (1)
packages/db/src/schema.ts (1)
  • message (538-560)
⏰ 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). (10)
  • GitHub Check: build-split (playground, linux/amd64)
  • GitHub Check: build-split (docs, linux/amd64)
  • GitHub Check: build-split (api, linux/amd64)
  • GitHub Check: build-split (ui, linux/amd64)
  • GitHub Check: build-split (gateway, linux/amd64)
  • GitHub Check: build-unified (linux/amd64)
  • GitHub Check: build / run
  • GitHub Check: test / run
  • GitHub Check: lint / run
  • GitHub Check: autofix

Comment thread apps/playground/src/app/api/chat/route.ts
Comment thread apps/playground/src/app/api/chat/route.ts
@smakosh
smakosh added this pull request to the merge queue Nov 21, 2025
Merged via the queue into main with commit f42cb3b Nov 21, 2025
20 checks passed
@smakosh
smakosh deleted the feat/playground-features branch November 21, 2025 06:55
@coderabbitai coderabbitai Bot mentioned this pull request Dec 17, 2025
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