Skip to content

adding openrouter image example#350

Merged
jherr merged 2 commits intomainfrom
openrouter-image
Mar 7, 2026
Merged

adding openrouter image example#350
jherr merged 2 commits intomainfrom
openrouter-image

Conversation

@jherr
Copy link
Contributor

@jherr jherr commented Mar 7, 2026

🎯 Changes

Just adds an openrouter example for image generation to the testing panel.

✅ Checklist

  • I have followed the steps in the Contributing guide.
  • I have tested this code locally with pnpm run test:pr.

🚀 Release Impact

  • This change affects published code, and I have generated a changeset.
  • This change is docs/CI/dev-only (no release).

Summary by CodeRabbit

Release Notes

  • New Features
    • Added OpenRouter as an image generation provider option with Gemini 3.1 Flash Image support and configurable image sizes
    • Improved image generation logging to display accurate counts of generated images

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 7, 2026

📝 Walkthrough

Walkthrough

This 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

Cohort / File(s) Summary
OpenRouter Provider - API Logic
testing/panel/src/routes/api.image.ts
Extended Provider type to include 'openrouter'. Added default model mapping per provider. Integrated openRouterImage(model) adapter call for the openrouter provider. Replaced hardcoded Gemini and OpenAI model fallbacks with dynamic model parameter usage. Updated completion log to display actual generated image count instead of generic header.
OpenRouter Provider - UI Configuration
testing/panel/src/routes/image.tsx
Extended Provider type to include 'openrouter'. Added new provider entry to PROVIDERS configuration with id, display name, and supported image size options for the openrouter provider, enabling UI selection of the new provider.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~12 minutes

Poem

🐰 A whisker-twitching tale we share,
OpenRouter joins the provider care!
Default models, adapters aligned,
New sizes in UI, all redesigned,
Logs now count what truly appears,
Hopping forward, through the gears! 🚀

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title 'adding openrouter image example' directly and accurately describes the main change: introducing OpenRouter as a new provider option for image generation in the testing panel.
Description check ✅ Passed The pull request description follows the required template structure with all sections present: Changes, Checklist, and Release Impact. The Changes section clearly states the purpose, and both checklists are included.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
  • 📝 Generate docstrings (stacked PR)
  • 📝 Generate docstrings (commit on current branch)
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch openrouter-image

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.

@nx-cloud
Copy link

nx-cloud bot commented Mar 7, 2026

View your CI Pipeline Execution ↗ for commit c16389e

Command Status Duration Result
nx affected --targets=test:sherif,test:knip,tes... ✅ Succeeded 37s View ↗
nx run-many --targets=build --exclude=examples/** ✅ Succeeded 35s View ↗

☁️ Nx Cloud last updated this comment at 2026-03-07 15:30:16 UTC

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 7, 2026

Open in StackBlitz

@tanstack/ai

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai@350

@tanstack/ai-anthropic

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-anthropic@350

@tanstack/ai-client

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-client@350

@tanstack/ai-devtools-core

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-devtools-core@350

@tanstack/ai-fal

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-fal@350

@tanstack/ai-gemini

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-gemini@350

@tanstack/ai-grok

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-grok@350

@tanstack/ai-groq

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-groq@350

@tanstack/ai-ollama

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-ollama@350

@tanstack/ai-openai

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-openai@350

@tanstack/ai-openrouter

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-openrouter@350

@tanstack/ai-preact

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-preact@350

@tanstack/ai-react

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-react@350

@tanstack/ai-react-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-react-ui@350

@tanstack/ai-solid

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-solid@350

@tanstack/ai-solid-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-solid-ui@350

@tanstack/ai-svelte

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-svelte@350

@tanstack/ai-vue

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vue@350

@tanstack/ai-vue-ui

npm i https://pkg.pr.new/TanStack/ai/@tanstack/ai-vue-ui@350

@tanstack/preact-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/preact-ai-devtools@350

@tanstack/react-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/react-ai-devtools@350

@tanstack/solid-ai-devtools

npm i https://pkg.pr.new/TanStack/ai/@tanstack/solid-ai-devtools@350

commit: 1fc2d13

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

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 (1)
testing/panel/src/routes/api.image.ts (1)

5-5: Import the OpenRouter image adapter from the /adapters subpath.

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 /adapters export 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

📥 Commits

Reviewing files that changed from the base of the PR and between 1e0f993 and c16389e.

📒 Files selected for processing (2)
  • testing/panel/src/routes/api.image.ts
  • testing/panel/src/routes/image.tsx

Comment on lines 16 to 39
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),
}),
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

cat -n testing/panel/src/routes/api.image.ts

Repository: 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.

@jherr jherr merged commit 7c7832e into main Mar 7, 2026
5 checks passed
@jherr jherr deleted the openrouter-image branch March 7, 2026 15:49
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