Skip to content

Commit ebdad7f

Browse files
authored
feat(ai-openai): add gpt-image-2 to image model meta (#625)
* feat(ai-openai): add gpt-image-2 to image model meta Adds `gpt-image-2` to OPENAI_IMAGE_MODELS so it can be used through openaiImage adapters. Reuses the gpt-image-1 provider-options/size shape (quality, background, output_format, output_compression, moderation, partial_images; sizes 1024x1024 / 1536x1024 / 1024x1536 / auto) and extends size + prompt-length validators. Also updates the media-generation skill and image-generation doc page to list the new model. * fix(ai-openrouter): restore web_fetch in tool capabilities map The model-metadata sync in #623 regenerated `OpenRouterChatModelToolCapabilitiesByName` with `['web_search']` only, which made `webFetchTool()` (added in #611) unassignable to any OpenRouter text adapter and broke the per-model type-safety test. Add `'web_fetch'` back so the existing tests compile.
1 parent 27d30c9 commit ebdad7f

8 files changed

Lines changed: 68 additions & 8 deletions

File tree

.changeset/openai-gpt-image-2.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
'@tanstack/ai-openai': minor
3+
---
4+
5+
Add `gpt-image-2` to the OpenAI image model list. The new model is exposed
6+
through the same tree-shakeable `openaiImage` adapter as `gpt-image-1` and
7+
shares its provider options (`quality`, `background`, `output_format`,
8+
`output_compression`, `moderation`, `partial_images`) and size set
9+
(`1024x1024`, `1536x1024`, `1024x1536`, `auto`).
10+
11+
```ts
12+
import { openaiImage } from '@tanstack/ai-openai/adapters'
13+
import { generate } from '@tanstack/ai'
14+
15+
const adapter = openaiImage({ apiKey: process.env.OPENAI_API_KEY! })
16+
17+
const result = await generate({
18+
adapter,
19+
model: 'gpt-image-2',
20+
prompt: 'A watercolor fox in a snowy forest',
21+
})
22+
```
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'@tanstack/ai-openrouter': patch
3+
---
4+
5+
Restore `web_fetch` in `OpenRouterChatModelToolCapabilitiesByName` so `webFetchTool()` is assignable to OpenRouter text adapters again. The recent model-metadata sync (#623) regenerated this map with `web_search` only, breaking the per-model type-safety tests added in #611.

docs/media/image-generation.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ All image adapters support these common options:
9090

9191
| Model | Supported Sizes |
9292
|-------|----------------|
93+
| `gpt-image-2` | `1024x1024`, `1536x1024`, `1024x1536`, `auto` |
9394
| `gpt-image-1` | `1024x1024`, `1536x1024`, `1024x1536`, `auto` |
9495
| `gpt-image-1-mini` | `1024x1024`, `1536x1024`, `1024x1536`, `auto` |
9596
| `dall-e-3` | `1024x1024`, `1792x1024`, `1024x1792` |
@@ -138,11 +139,11 @@ const result = await generateImage({
138139

139140
OpenAI models support model-specific Model Options:
140141

141-
#### GPT-Image-1 / GPT-Image-1-Mini
142+
#### GPT-Image-2 / GPT-Image-1 / GPT-Image-1-Mini
142143

143144
```typescript
144145
const result = await generateImage({
145-
adapter: openaiImage('gpt-image-1'),
146+
adapter: openaiImage('gpt-image-2'),
146147
prompt: 'A cat wearing a hat',
147148
modelOptions: {
148149
quality: 'high', // 'high' | 'medium' | 'low' | 'auto'
@@ -223,6 +224,7 @@ interface GeneratedImage {
223224

224225
| Model | Images per Request |
225226
|-------|-------------------|
227+
| `gpt-image-2` | 1-10 |
226228
| `gpt-image-1` | 1-10 |
227229
| `gpt-image-1-mini` | 1-10 |
228230
| `dall-e-3` | 1 |

packages/typescript/ai-openai/src/adapters/image.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ export interface OpenAIImageConfig extends OpenAIClientConfig {}
3131
* OpenAI Image Generation Adapter
3232
*
3333
* Tree-shakeable adapter for OpenAI image generation functionality.
34-
* Supports gpt-image-1, gpt-image-1-mini, dall-e-3, and dall-e-2 models.
34+
* Supports gpt-image-2, gpt-image-1, gpt-image-1-mini, dall-e-3, and dall-e-2 models.
3535
*
3636
* Features:
3737
* - Model-specific type-safe provider options

packages/typescript/ai-openai/src/image/image-provider-options.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,7 @@ export type OpenAIImageProviderOptions =
181181
* Used by the core AI types to narrow providerOptions based on the selected model.
182182
*/
183183
export type OpenAIImageModelProviderOptionsByName = {
184+
'gpt-image-2': GptImage1ProviderOptions
184185
'gpt-image-1': GptImage1ProviderOptions
185186
'gpt-image-1-mini': GptImage1MiniProviderOptions
186187
'dall-e-3': DallE3ProviderOptions
@@ -191,6 +192,7 @@ export type OpenAIImageModelProviderOptionsByName = {
191192
* Type-only map from model name to its supported sizes.
192193
*/
193194
export type OpenAIImageModelSizeByName = {
195+
'gpt-image-2': GptImageSize
194196
'gpt-image-1': GptImageSize
195197
'gpt-image-1-mini': GptImageSize
196198
'dall-e-3': DallE3Size
@@ -217,6 +219,7 @@ export function validateImageSize(
217219
if (!size || size === 'auto') return
218220

219221
const validSizes: Record<string, Array<string>> = {
222+
'gpt-image-2': ['1024x1024', '1536x1024', '1024x1536', 'auto'],
220223
'gpt-image-1': ['1024x1024', '1536x1024', '1024x1536', 'auto'],
221224
'gpt-image-1-mini': ['1024x1024', '1536x1024', '1024x1536', 'auto'],
222225
'dall-e-3': ['1024x1024', '1792x1024', '1024x1792'],
@@ -263,7 +266,7 @@ export function validateNumberOfImages(
263266

264267
export const validateBackground = (options: ImageValidationOptions) => {
265268
if (options.background) {
266-
const supportedModels = ['gpt-image-1', 'gpt-image-1-mini']
269+
const supportedModels = ['gpt-image-2', 'gpt-image-1', 'gpt-image-1-mini']
267270
if (!supportedModels.includes(options.model)) {
268271
throw new Error(
269272
`The model ${options.model} does not support background option.`,
@@ -277,11 +280,13 @@ export const validatePrompt = (options: ImageValidationOptions) => {
277280
throw new Error('Prompt cannot be empty.')
278281
}
279282
if (
280-
(options.model === 'gpt-image-1' || options.model === 'gpt-image-1-mini') &&
283+
(options.model === 'gpt-image-2' ||
284+
options.model === 'gpt-image-1' ||
285+
options.model === 'gpt-image-1-mini') &&
281286
options.prompt.length > 32000
282287
) {
283288
throw new Error(
284-
'For gpt-image-1/gpt-image-1-mini, prompt length must be less than or equal to 32000 characters.',
289+
'For gpt-image-2/gpt-image-1/gpt-image-1-mini, prompt length must be less than or equal to 32000 characters.',
285290
)
286291
}
287292
if (options.model === 'dall-e-2' && options.prompt.length > 1000) {

packages/typescript/ai-openai/src/model-meta.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,28 @@ const GPT_IMAGE_1_MINI = {
572572
OpenAIBaseOptions & OpenAIStreamingOptions & OpenAIMetadataOptions
573573
>
574574

575+
const GPT_IMAGE_2 = {
576+
name: 'gpt-image-2',
577+
knowledge_cutoff: '2026-04-21',
578+
pricing: {
579+
input: {
580+
normal: 5,
581+
cached: 1.25,
582+
},
583+
output: {
584+
normal: 30,
585+
},
586+
},
587+
supports: {
588+
input: ['text', 'image'],
589+
output: ['image'],
590+
endpoints: ['image-generation', 'image-edit'],
591+
features: [],
592+
},
593+
} as const satisfies ModelMeta<
594+
OpenAIBaseOptions & OpenAIStreamingOptions & OpenAIMetadataOptions
595+
>
596+
575597
const O3_DEEP_RESEARCH = {
576598
name: 'o3-deep-research',
577599
context_window: 200_000,
@@ -2217,6 +2239,7 @@ export type OpenAIChatModel = (typeof OPENAI_CHAT_MODELS)[number]
22172239

22182240
// Image generation models (based on endpoints: "image-generation" or "image-edit")
22192241
export const OPENAI_IMAGE_MODELS = [
2242+
GPT_IMAGE_2.name,
22202243
GPT_IMAGE_1.name,
22212244
GPT_IMAGE_1_MINI.name,
22222245
DALL_E_3.name,

packages/typescript/ai-openrouter/src/model-meta.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16379,7 +16379,10 @@ export const OPENROUTER_CHAT_MODELS = [
1637916379
] as const
1638016380

1638116381
export type OpenRouterChatModelToolCapabilitiesByName = {
16382-
[K in (typeof OPENROUTER_CHAT_MODELS)[number]]: readonly ['web_search']
16382+
[K in (typeof OPENROUTER_CHAT_MODELS)[number]]: readonly [
16383+
'web_search',
16384+
'web_fetch',
16385+
]
1638316386
}
1638416387

1638516388
export const OPENROUTER_IMAGE_MODELS = [

packages/typescript/ai/skills/ai-core/media-generation/SKILL.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ function ImageGenerator() {
149149
### 1. Image Generation
150150

151151
Supported adapters: `openaiImage` (dall-e-2, dall-e-3, gpt-image-1,
152-
gpt-image-1-mini) and `geminiImage` (gemini-3.1-flash-image-preview,
152+
gpt-image-1-mini, gpt-image-2) and `geminiImage` (gemini-3.1-flash-image-preview,
153153
imagen-4.0-generate-001, etc.).
154154

155155
```typescript

0 commit comments

Comments
 (0)