Migrate to new OpenAI SDK (Responses API) and upgrade dependencies#86
Migrate to new OpenAI SDK (Responses API) and upgrade dependencies#86yisding wants to merge 1 commit into
Conversation
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 28eeb59b9c
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| }); | ||
|
|
||
| res.status(200).json({ url: response.data.data[0].url }); | ||
| res.status(200).json({ url: response.data?.[0]?.url }); |
There was a problem hiding this comment.
Return image bytes for gpt-image-1 instead of URL
Switching this endpoint to model: "gpt-image-1" but still reading response.data?.[0]?.url breaks image delivery, because GPT image models return base64 image data (b64_json) rather than a hosted URL. In practice this causes successful generations to come back with url: undefined, so clients that expect a usable image URL will fail for every request to this route.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Pull request overview
Migrates the app’s Next.js API routes from the legacy OpenAI SDK (OpenAIApi / Chat Completions) to the newer openai client using the Responses API (structured JSON outputs) and updates image generation to openai.images.generate, alongside a broad dependency upgrade.
Changes:
- Refactors
/api/words,/api/wordpieces, and/api/wordgradeto useopenai.responses.createwith JSON schema formatting andoutput_text. - Updates
/api/imageto useopenai.images.generatewith thegpt-image-1model. - Upgrades Next/React/OpenAI SDK and related tooling dependencies.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 4 comments.
Show a summary per file
| File | Description |
|---|---|
| pages/api/words.ts | Switches to Responses API with JSON schema formatted text output and parsing into word lists. |
| pages/api/wordpieces.ts | Switches to Responses API with JSON schema formatted output for phoneme/character segmentation. |
| pages/api/wordgrade.ts | Switches to Responses API with JSON schema formatted output for grade classification. |
| pages/api/image.ts | Migrates image generation to openai.images.generate and updates response extraction. |
| package.json | Upgrades major dependencies (Next/React/OpenAI SDK) and moves some tooling packages to devDependencies. |
Comments suppressed due to low confidence (3)
pages/api/words.ts:114
JSON.parse(responseJson)can throw if the model returns non-JSON (or JSON with leading/trailing text). Right now that exception will bubble up and produce a 500 without a controlled error response. Wrap the parse (and ideally the OpenAI call) in try/catch and return a 502/503 with a helpful error message.
const responseJson = response.output_text;
if (!responseJson) {
res.status(503).json({ error: "No response" });
return;
}
const responseData: string[] = JSON.parse(responseJson);
pages/api/wordpieces.ts:115
JSON.parse(responseJson)is not guarded; if the model ever emits invalid JSON, this handler will throw and fail the request with an unhandled 500. Consider wrapping parsing (and the OpenAI call) in try/catch and returning a structured error response.
const responseJson = response.output_text;
if (!responseJson) {
res.status(503).json({ error: "No response" });
return;
}
const responseData: { characters: string; phonemes: string }[] =
JSON.parse(responseJson);
pages/api/wordgrade.ts:68
JSON.parse(responseJson)is unguarded; any non-JSON output will throw and cause an unhandled 500. Wrap parsing (and/or the OpenAI request) in try/catch and return a controlled error response so the client can handle it.
const responseJson = response.output_text;
if (!responseJson) {
res.status(503).json({ error: "No response" });
return;
}
const responseData: { grade: string } = JSON.parse(responseJson);
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| Word: pig | ||
| Output: [ { "phonemes": "p", "characters": "p" }, { "phonemes": "ɪ", characters: "i" }, { "phonemes": "g", "characters": "g" } ] | ||
|
|
| Word: blue | ||
| Output: [ { "phonemes": "b", "characters": "b" }, { "phonemes": "l", characters: "l" }, { "phonemes": "u:", "characters": "ue" } ] | ||
|
|
| Word: happy | ||
| Output: [ { "phonemes": "h", "characters": "h" }, { "phonemes": "æ", characters: "a" }, { "phonemes": "p", "characters": "pp" },{ "phonemes": "i", "characters": "y" } ]`, | ||
| }, | ||
| { | ||
| role: "user", | ||
| content: `Word: ${word} | ||
| Output:`, | ||
| }, | ||
| ]; | ||
| Output: [ { "phonemes": "h", "characters": "h" }, { "phonemes": "æ", characters: "a" }, { "phonemes": "p", "characters": "pp" },{ "phonemes": "i", "characters": "y" } ]`; |
| const response = await openai.images.generate({ | ||
| model: "gpt-image-1", | ||
| prompt: `clip art of ${word}`, | ||
| n: 1, | ||
| size: "256x256", | ||
| }); | ||
|
|
||
| res.status(200).json({ url: response.data.data[0].url }); | ||
| res.status(200).json({ url: response.data?.[0]?.url }); | ||
| } |
There was a problem hiding this comment.
Blocking feedback
gpt-image-1request/response handling here will break image delivery — .../api/image.ts#L24-L30
If you want me to push fixes, reply with item numbers (for example: please fix 1).
| model: "gpt-image-1", | ||
| prompt: `clip art of ${word}`, | ||
| n: 1, | ||
| size: "256x256", |
There was a problem hiding this comment.
gpt-image-1 does not support size: "256x256", and this model returns b64_json image bytes rather than url. With the current call shape, /api/image can fail validation or return { url: undefined }, so generated images will not render in the UI.
Suggested fix: use a GPT-image-supported size (for example 1024x1024 or auto) and return an image derived from b64_json (for example a data:image/png;base64,... URL or a stored asset URL). If this endpoint must keep hosted URL output at 256x256, use a DALL·E model instead.
Motivation
openaiSDK and the Responses API model for image generation and chat-style endpoints.Description
OpenAIApiusage with the newOpenAIclient and instantiated it vianew OpenAI({ apiKey: process.env.OPENAI_API_KEY })across API handlers.openai.images.generatewithmodel: "gpt-image-1"and updated response extraction toresponse.data?.[0]?.urlinpages/api/image.ts.pages/api/wordgrade.ts,pages/api/wordpieces.ts,pages/api/words.ts) to callopenai.responses.createusinginstructions+inputand JSON schema formatting via thetext.formatblock, then readresponse.output_textandJSON.parseit.package.jsonandpackage-lock.jsonwith numerous dependency bumps (e.g.next,react,react-dom,openai,eslint,prettier,tailwindcss,@sentry/nextjs, etc.) and moved some previously top-level packages intodevDependenciesor updated their versions.Testing
Codex Task