Conversation
📝 WalkthroughWalkthroughThis pull request adds support for a new 'openrouter' provider to the image generation system. It extends the Provider type, implements default model mappings per provider, wires the openrouter adapter into the API flow, replaces hardcoded model fallbacks with dynamic selections, and updates completion log output to display the actual image count. Changes
Sequence DiagramsequenceDiagram
participant Client
participant ImageAPI as Image API<br/>(api.image.ts)
participant Adapter as Provider Adapter<br/>(openRouterImage)
participant OpenRouter as OpenRouter Service
Client->>ImageAPI: POST /api/image<br/>(provider: 'openrouter', size, count)
ImageAPI->>ImageAPI: Select model from<br/>provider mapping
ImageAPI->>Adapter: openRouterImage(model)
Adapter->>OpenRouter: Generate images
OpenRouter-->>Adapter: Image results
Adapter-->>ImageAPI: Image data
ImageAPI->>ImageAPI: Log: 'Generated<br/>N images'
ImageAPI-->>Client: Image response
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches
🧪 Generate unit tests (beta)
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. Comment |
|
View your CI Pipeline Execution ↗ for commit c16389e
☁️ Nx Cloud last updated this comment at |
@tanstack/ai
@tanstack/ai-anthropic
@tanstack/ai-client
@tanstack/ai-devtools-core
@tanstack/ai-fal
@tanstack/ai-gemini
@tanstack/ai-grok
@tanstack/ai-groq
@tanstack/ai-ollama
@tanstack/ai-openai
@tanstack/ai-openrouter
@tanstack/ai-preact
@tanstack/ai-react
@tanstack/ai-react-ui
@tanstack/ai-solid
@tanstack/ai-solid-ui
@tanstack/ai-svelte
@tanstack/ai-vue
@tanstack/ai-vue-ui
@tanstack/preact-ai-devtools
@tanstack/react-ai-devtools
@tanstack/solid-ai-devtools
commit: |
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Nitpick comments (1)
testing/panel/src/routes/api.image.ts (1)
5-5: Import the OpenRouter image adapter from the/adapterssubpath.This new import goes through the package root instead of the tree-shakeable adapter entrypoint the repo expects for provider implementations. Please switch it to the specialized
/adaptersexport if this package exposes it as well.Based on learnings, "Create individual adapter implementations for each provider capability (text, embed, summarize, image) with separate exports to enable tree-shaking".
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed. In `@testing/panel/src/routes/api.image.ts` at line 5, The import currently pulls openRouterImage from the package root; change it to use the tree-shakeable adapter entry by importing openRouterImage from the adapters subpath (e.g., import { openRouterImage } from '@tanstack/ai-openrouter/adapters') so the image adapter uses the specialized export; update the import statement referencing openRouterImage and verify the package exposes that adapter export and run tests/build to confirm no breakage.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@testing/panel/src/routes/api.image.ts`:
- Around line 16-39: Validate incoming request JSON with a Zod schema that
enforces provider as a union of allowed providers and model as an optional
string constrained to the expected shape before using provider/model; parse the
body and use the validated result to set provider/model (instead of reading
data.provider/body.provider directly), then if Zod parsing fails return a 400
error. After validation, use the narrowed provider value to lookup defaultModels
and adapterConfig safely (symbols to update: provider, model, defaultModels,
adapterConfig, createImageOptions, geminiImage, openaiImage, openRouterImage) so
adapterConfig[provider] cannot be undefined and per-provider model options are
type-safe.
---
Nitpick comments:
In `@testing/panel/src/routes/api.image.ts`:
- Line 5: The import currently pulls openRouterImage from the package root;
change it to use the tree-shakeable adapter entry by importing openRouterImage
from the adapters subpath (e.g., import { openRouterImage } from
'@tanstack/ai-openrouter/adapters') so the image adapter uses the specialized
export; update the import statement referencing openRouterImage and verify the
package exposes that adapter export and run tests/build to confirm no breakage.
ℹ️ Review info
⚙️ Run configuration
Configuration used: defaults
Review profile: CHILL
Plan: Pro
Run ID: ebac8a9b-2e88-4007-a325-b7be40278a63
📒 Files selected for processing (2)
testing/panel/src/routes/api.image.tstesting/panel/src/routes/image.tsx
| const provider: Provider = data.provider || body.provider || 'openai' | ||
| const model: string = data.model || body.model || 'gpt-image-1' | ||
|
|
||
| const defaultModels: Record<Provider, string> = { | ||
| openai: 'gpt-image-1', | ||
| gemini: 'gemini-2.0-flash-preview-image-generation', | ||
| openrouter: 'google/gemini-3.1-flash-image-preview', | ||
| } | ||
| const model: string = | ||
| data.model || body.model || defaultModels[provider] | ||
|
|
||
| try { | ||
| // Pre-define typed adapter configurations with full type inference | ||
| // Model is passed to the adapter factory function for type-safe autocomplete | ||
| const adapterConfig = { | ||
| gemini: () => | ||
| createImageOptions({ | ||
| adapter: geminiImage( | ||
| (model || 'gemini-2.0-flash-preview-image-generation') as any, | ||
| ), | ||
| adapter: geminiImage(model as any), | ||
| }), | ||
| openai: () => | ||
| createImageOptions({ | ||
| adapter: openaiImage((model || 'gpt-image-1') as any), | ||
| adapter: openaiImage(model as any), | ||
| }), | ||
| openrouter: () => | ||
| createImageOptions({ | ||
| adapter: openRouterImage(model as any), | ||
| }), |
There was a problem hiding this comment.
🧩 Analysis chain
🏁 Script executed:
cat -n testing/panel/src/routes/api.image.tsRepository: TanStack/ai
Length of output: 3327
Add runtime validation for provider and model parameters using Zod before adapter initialization.
The request.json() call is untyped and provider/model are used without validation. Unknown providers like "foo" reach adapterConfig[provider]() at line 43, which returns undefined, throwing a TypeError caught and returned as a 500 status. Invalid inputs should return 400 (client error) instead. Implement a Zod schema to validate the request structure and narrow provider/model pairs at the entry point, before indexing defaultModels and adapterConfig.
Per coding guidelines: use Zod for runtime schema validation and type-safe per-model configuration with provider options typed based on the selected model.
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.
In `@testing/panel/src/routes/api.image.ts` around lines 16 - 39, Validate
incoming request JSON with a Zod schema that enforces provider as a union of
allowed providers and model as an optional string constrained to the expected
shape before using provider/model; parse the body and use the validated result
to set provider/model (instead of reading data.provider/body.provider directly),
then if Zod parsing fails return a 400 error. After validation, use the narrowed
provider value to lookup defaultModels and adapterConfig safely (symbols to
update: provider, model, defaultModels, adapterConfig, createImageOptions,
geminiImage, openaiImage, openRouterImage) so adapterConfig[provider] cannot be
undefined and per-provider model options are type-safe.
🎯 Changes
Just adds an openrouter example for image generation to the testing panel.
✅ Checklist
pnpm run test:pr.🚀 Release Impact
Summary by CodeRabbit
Release Notes