From 33f617a6cc5dd6f5db54c59da881241715f23b33 Mon Sep 17 00:00:00 2001 From: Ivan Vasilov Date: Thu, 30 Nov 2023 10:01:51 +0100 Subject: [PATCH] Migrate all apps and packages to use OpenAI v4 lib (#19270) * Migrate all apps and packages to use OpenAI v4 lib. * Minor fix. * refactor: improve types for completion chunks --------- Co-authored-by: Greg Richardson --- apps/studio/package.json | 3 +- apps/studio/pages/api/ai/sql/debug.ts | 40 ++---- apps/studio/pages/api/ai/sql/edit.ts | 44 ++---- apps/studio/pages/api/ai/sql/generate.ts | 44 ++---- apps/studio/pages/api/ai/sql/title.ts | 37 ++--- package-lock.json | 132 ++++-------------- packages/ui/package.json | 2 +- .../ui/src/components/Command/AiCommand.tsx | 25 +--- 8 files changed, 90 insertions(+), 237 deletions(-) diff --git a/apps/studio/package.json b/apps/studio/package.json index d44d8116898..48981cc7d3a 100644 --- a/apps/studio/package.json +++ b/apps/studio/package.json @@ -63,8 +63,7 @@ "monaco-editor": "0.33.0", "next": "^13.5.6", "next-themes": "^0.2.1", - "openai-old": "npm:openai@^3.3.0", - "openai": "^4.0.0", + "openai": "^4.20.1", "openapi-fetch": "^0.6.1", "p-queue": "^6.6.2", "papaparse": "^5.3.1", diff --git a/apps/studio/pages/api/ai/sql/debug.ts b/apps/studio/pages/api/ai/sql/debug.ts index 7f517157d1f..c1f78d6430c 100644 --- a/apps/studio/pages/api/ai/sql/debug.ts +++ b/apps/studio/pages/api/ai/sql/debug.ts @@ -4,12 +4,7 @@ import { isError } from 'data/utils/error-check' import { jsonrepair } from 'jsonrepair' import apiWrapper from 'lib/api/apiWrapper' import { NextApiRequest, NextApiResponse } from 'next' -import type { - ChatCompletionRequestMessage, - CreateChatCompletionRequest, - CreateChatCompletionResponse, - ErrorResponse, -} from 'openai-old' +import { OpenAI } from 'openai' const openAiKey = process.env.OPENAI_KEY @@ -23,7 +18,10 @@ const debugSqlSchema = SchemaBuilder.emptySchema() type DebugSqlResult = typeof debugSqlSchema.T -const completionFunctions = { +const completionFunctions: Record< + string, + OpenAI.Chat.Completions.ChatCompletionCreateParams.Function +> = { debugSql: { name: 'debugSql', description: stripIndent` @@ -38,7 +36,7 @@ const completionFunctions = { - Use vector(384) data type for any embedding/vector related query - Always use double apostrophe in SQL strings (eg. 'Night''s watch') `, - parameters: debugSqlSchema.schema, + parameters: debugSqlSchema.schema as Record, }, } @@ -61,6 +59,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { } export async function handlePost(req: NextApiRequest, res: NextApiResponse) { + const openAI = new OpenAI({ apiKey: openAiKey }) const { body: { errorMessage, sql, entityDefinitions }, } = req @@ -69,7 +68,7 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { const maxCompletionTokenCount = 2048 const hasEntityDefinitions = entityDefinitions !== undefined && entityDefinitions.length > 0 - const completionMessages: ChatCompletionRequestMessage[] = [] + const completionMessages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [] if (hasEntityDefinitions) { completionMessages.push({ @@ -98,7 +97,7 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { } ) - const completionOptions: CreateChatCompletionRequest = { + const completionOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = { model, messages: completionMessages, max_tokens: maxCompletionTokenCount, @@ -110,20 +109,13 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { stream: false, } - const response = await fetch('https://api.openai.com/v1/chat/completions', { - headers: { - Authorization: `Bearer ${openAiKey}`, - 'Content-Type': 'application/json', - }, - method: 'POST', - body: JSON.stringify(completionOptions), - }) + let completionResponse: OpenAI.Chat.Completions.ChatCompletion + try { + completionResponse = await openAI.chat.completions.create(completionOptions) + } catch (error: any) { + console.error(`AI SQL debugging failed: ${error.message}`) - if (!response.ok) { - const errorResponse: ErrorResponse = await response.json() - console.error(`AI SQL debugging failed: ${errorResponse.error.message}`) - - if ('code' in errorResponse.error && errorResponse.error.code === 'context_length_exceeded') { + if ('code' in error && error.code === 'context_length_exceeded') { if (hasEntityDefinitions) { const definitionsLength = entityDefinitions.reduce( (sum: number, def: string) => sum + def.length, @@ -149,8 +141,6 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { }) } - const completionResponse: CreateChatCompletionResponse = await response.json() - const [firstChoice] = completionResponse.choices const sqlResponseString = firstChoice.message?.function_call?.arguments diff --git a/apps/studio/pages/api/ai/sql/edit.ts b/apps/studio/pages/api/ai/sql/edit.ts index e4d3373df2a..869ac6211d6 100644 --- a/apps/studio/pages/api/ai/sql/edit.ts +++ b/apps/studio/pages/api/ai/sql/edit.ts @@ -4,12 +4,7 @@ import { isError } from 'data/utils/error-check' import { jsonrepair } from 'jsonrepair' import apiWrapper from 'lib/api/apiWrapper' import { NextApiRequest, NextApiResponse } from 'next' -import type { - ChatCompletionRequestMessage, - CreateChatCompletionRequest, - CreateChatCompletionResponse, - ErrorResponse, -} from 'openai-old' +import { OpenAI } from 'openai' const openAiKey = process.env.OPENAI_KEY @@ -29,11 +24,14 @@ const editSqlSchema = SchemaBuilder.emptySchema().addString('sql', { type EditSqlResult = typeof editSqlSchema.T -const completionFunctions = { +const completionFunctions: Record< + string, + OpenAI.Chat.Completions.ChatCompletionCreateParams.Function +> = { editSql: { name: 'editSql', description: "Edits a Postgres SQL query based on the user's instructions", - parameters: editSqlSchema.schema, + parameters: editSqlSchema.schema as Record, }, } @@ -60,11 +58,12 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { body: { prompt, sql, entityDefinitions }, } = req + const openAI = new OpenAI({ apiKey: openAiKey }) const model = 'gpt-3.5-turbo-0613' const maxCompletionTokenCount = 2048 const hasEntityDefinitions = entityDefinitions !== undefined && entityDefinitions.length > 0 - const completionMessages: ChatCompletionRequestMessage[] = [] + const completionMessages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [] if (hasEntityDefinitions) { completionMessages.push({ @@ -90,7 +89,7 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { } ) - const completionOptions: CreateChatCompletionRequest = { + const completionOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = { model, messages: completionMessages, max_tokens: maxCompletionTokenCount, @@ -102,26 +101,17 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { stream: false, } - const response = await fetch('https://api.openai.com/v1/chat/completions', { - headers: { - Authorization: `Bearer ${openAiKey}`, - 'Content-Type': 'application/json', - }, - method: 'POST', - body: JSON.stringify(completionOptions), - }) - - if (!response.ok) { - const errorResponse: ErrorResponse = await response.json() - console.error(`AI SQL editing failed: ${errorResponse.error.message}`) - - if ('code' in errorResponse.error && errorResponse.error.code === 'context_length_exceeded') { + let completionResponse: OpenAI.Chat.Completions.ChatCompletion + try { + completionResponse = await openAI.chat.completions.create(completionOptions) + } catch (error: any) { + console.error(`AI SQL editing failed: ${error.message}`) + if ('code' in error && error.code === 'context_length_exceeded') { if (hasEntityDefinitions) { const definitionsLength = entityDefinitions.reduce( (sum: number, def: string) => sum + def.length, 0 ) - if (definitionsLength > sql.length) { return res.status(400).json({ error: @@ -129,20 +119,16 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { }) } } - return res.status(400).json({ error: 'Your SQL query is too large for Supabase AI to ingest. Try splitting it into smaller queries.', }) } - return res.status(500).json({ error: 'There was an unknown error editing the SQL snippet. Please try again.', }) } - const completionResponse: CreateChatCompletionResponse = await response.json() - const [firstChoice] = completionResponse.choices const sqlResponseString = firstChoice.message?.function_call?.arguments diff --git a/apps/studio/pages/api/ai/sql/generate.ts b/apps/studio/pages/api/ai/sql/generate.ts index 0b1214558ef..71642983ea5 100644 --- a/apps/studio/pages/api/ai/sql/generate.ts +++ b/apps/studio/pages/api/ai/sql/generate.ts @@ -4,12 +4,7 @@ import { isError } from 'data/utils/error-check' import { jsonrepair } from 'jsonrepair' import apiWrapper from 'lib/api/apiWrapper' import { NextApiRequest, NextApiResponse } from 'next' -import type { - ChatCompletionRequestMessage, - CreateChatCompletionRequest, - CreateChatCompletionResponse, - ErrorResponse, -} from 'openai-old' +import { OpenAI } from 'openai' const openAiKey = process.env.OPENAI_KEY @@ -34,11 +29,14 @@ const generateSqlSchema = SchemaBuilder.emptySchema() type GenerateSqlResult = typeof generateSqlSchema.T -const completionFunctions = { +const completionFunctions: Record< + string, + OpenAI.Chat.Completions.ChatCompletionCreateParams.Function +> = { generateSql: { name: 'generateSql', description: 'Generates Postgres SQL based on a natural language prompt', - parameters: generateSqlSchema.schema, + parameters: generateSqlSchema.schema as Record, }, } @@ -61,6 +59,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { } export async function handlePost(req: NextApiRequest, res: NextApiResponse) { + const openAI = new OpenAI({ apiKey: openAiKey }) const { body: { prompt, entityDefinitions }, } = req @@ -69,7 +68,7 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { const maxCompletionTokenCount = 1024 const hasEntityDefinitions = entityDefinitions !== undefined && entityDefinitions.length > 0 - const completionMessages: ChatCompletionRequestMessage[] = [] + const completionMessages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [] if (hasEntityDefinitions) { completionMessages.push({ @@ -86,7 +85,7 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { content: prompt, }) - const completionOptions: CreateChatCompletionRequest = { + const completionOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = { model, messages: completionMessages, max_tokens: maxCompletionTokenCount, @@ -98,24 +97,13 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { stream: false, } - const response = await fetch('https://api.openai.com/v1/chat/completions', { - headers: { - Authorization: `Bearer ${openAiKey}`, - 'Content-Type': 'application/json', - }, - method: 'POST', - body: JSON.stringify(completionOptions), - }) + let completionResponse: OpenAI.Chat.Completions.ChatCompletion + try { + completionResponse = await openAI.chat.completions.create(completionOptions) + } catch (error: any) { + console.error(`AI SQL generation failed: ${error.message}`) - if (!response.ok) { - const errorResponse: ErrorResponse = await response.json() - console.error(`AI SQL generation failed: ${errorResponse.error.message}`) - - if ( - 'code' in errorResponse.error && - errorResponse.error.code === 'context_length_exceeded' && - hasEntityDefinitions - ) { + if ('code' in error && error.code === 'context_length_exceeded' && hasEntityDefinitions) { return res.status(400).json({ error: 'Your database metadata is too large for Supabase AI to ingest. Try disabling database metadata in AI settings.', @@ -127,8 +115,6 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { }) } - const completionResponse: CreateChatCompletionResponse = await response.json() - const [firstChoice] = completionResponse.choices const sqlResponseString = firstChoice.message?.function_call?.arguments diff --git a/apps/studio/pages/api/ai/sql/title.ts b/apps/studio/pages/api/ai/sql/title.ts index 9a04a1d8a9d..b53170f9004 100644 --- a/apps/studio/pages/api/ai/sql/title.ts +++ b/apps/studio/pages/api/ai/sql/title.ts @@ -4,12 +4,7 @@ import { isError } from 'data/utils/error-check' import { jsonrepair } from 'jsonrepair' import apiWrapper from 'lib/api/apiWrapper' import { NextApiRequest, NextApiResponse } from 'next' -import type { - ChatCompletionRequestMessage, - CreateChatCompletionRequest, - CreateChatCompletionResponse, - ErrorResponse, -} from 'openai-old' +import { OpenAI } from 'openai' const openAiKey = process.env.OPENAI_KEY @@ -29,11 +24,11 @@ const generateTitleSchema = SchemaBuilder.emptySchema() type GenerateTitleResult = typeof generateTitleSchema.T -const completionFunctions = { +const completionFunctions: Record = { generateTitle: { name: 'generateTitle', description: 'Generates a short title and detailed description for a Postgres SQL snippet', - parameters: generateTitleSchema.schema, + parameters: generateTitleSchema.schema as Record, }, } @@ -56,6 +51,7 @@ async function handler(req: NextApiRequest, res: NextApiResponse) { } export async function handlePost(req: NextApiRequest, res: NextApiResponse) { + const openAI = new OpenAI({ apiKey: openAiKey }) const { body: { sql }, } = req @@ -63,14 +59,14 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { const model = 'gpt-3.5-turbo-0613' const maxCompletionTokenCount = 1024 - const completionMessages: ChatCompletionRequestMessage[] = [ + const completionMessages: OpenAI.Chat.Completions.ChatCompletionMessageParam[] = [ { role: 'user', content: sql, }, ] - const completionOptions: CreateChatCompletionRequest = { + const completionOptions: OpenAI.Chat.Completions.ChatCompletionCreateParamsNonStreaming = { model, messages: completionMessages, max_tokens: maxCompletionTokenCount, @@ -82,20 +78,13 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { stream: false, } - const response = await fetch('https://api.openai.com/v1/chat/completions', { - headers: { - Authorization: `Bearer ${openAiKey}`, - 'Content-Type': 'application/json', - }, - method: 'POST', - body: JSON.stringify(completionOptions), - }) + let completionResponse: OpenAI.Chat.Completions.ChatCompletion + try { + completionResponse = await openAI.chat.completions.create(completionOptions) + } catch (error: any) { + console.error(`AI title generation failed: ${error.message}`) - if (!response.ok) { - const errorResponse: ErrorResponse = await response.json() - console.error(`AI title generation failed: ${errorResponse.error.message}`) - - if ('code' in errorResponse.error && errorResponse.error.code === 'context_length_exceeded') { + if ('code' in error && error.code === 'context_length_exceeded') { return res.status(400).json({ error: 'Your SQL query is too large for Supabase AI to ingest. Try splitting it into smaller queries.', @@ -107,8 +96,6 @@ export async function handlePost(req: NextApiRequest, res: NextApiResponse) { }) } - const completionResponse: CreateChatCompletionResponse = await response.json() - const [firstChoice] = completionResponse.choices const titleResponseString = firstChoice.message?.function_call?.arguments diff --git a/package-lock.json b/package-lock.json index 9c7ec309da1..ad48bd37731 100644 --- a/package-lock.json +++ b/package-lock.json @@ -248,6 +248,7 @@ "version": "18.18.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", "integrity": "sha512-vXYZGRrSCreZmq1rEjMRLXJhiy8MrIeVasx+PCVlP414N7CJLHnMf+juVvjdprHyH+XRy3zKZLHeNueOpJCn0g==", + "dev": true, "dependencies": { "undici-types": "~5.26.4" } @@ -451,25 +452,6 @@ } } }, - "apps/database-new/node_modules/openai": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.20.0.tgz", - "integrity": "sha512-VbAYerNZFfIIeESS+OL9vgDkK8Mnri55n+jN0UN/HZeuM0ghGh6nDN6UGRZxslNgyJ7XmY/Ca9DO4YYyvrszGA==", - "dependencies": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "digest-fetch": "^1.3.0", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "web-streams-polyfill": "^3.2.1" - }, - "bin": { - "openai": "bin/cli" - } - }, "apps/database-new/node_modules/resolve": { "version": "2.0.0-next.5", "resolved": "https://registry.npmjs.org/resolve/-/resolve-2.0.0-next.5.tgz", @@ -580,6 +562,7 @@ }, "apps/docs/node_modules/@types/node": { "version": "18.18.8", + "dev": true, "license": "MIT", "dependencies": { "undici-types": "~5.26.4" @@ -662,25 +645,6 @@ ], "license": "MIT" }, - "apps/docs/node_modules/openai": { - "version": "4.20.0", - "resolved": "https://registry.npmjs.org/openai/-/openai-4.20.0.tgz", - "integrity": "sha512-VbAYerNZFfIIeESS+OL9vgDkK8Mnri55n+jN0UN/HZeuM0ghGh6nDN6UGRZxslNgyJ7XmY/Ca9DO4YYyvrszGA==", - "dependencies": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "digest-fetch": "^1.3.0", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "web-streams-polyfill": "^3.2.1" - }, - "bin": { - "openai": "bin/cli" - } - }, "apps/docs/node_modules/puppeteer": { "version": "16.2.0", "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-16.2.0.tgz", @@ -786,8 +750,7 @@ "monaco-editor": "0.33.0", "next": "^13.5.6", "next-themes": "^0.2.1", - "openai": "^4.0.0", - "openai-old": "npm:openai@^3.3.0", + "openai": "^4.20.1", "openapi-fetch": "^0.6.1", "p-queue": "^6.6.2", "papaparse": "^5.3.1", @@ -886,13 +849,6 @@ "glob": "7.1.7" } }, - "apps/studio/node_modules/@types/node": { - "version": "18.18.10", - "license": "MIT", - "dependencies": { - "undici-types": "~5.26.4" - } - }, "apps/studio/node_modules/ajv": { "version": "8.12.0", "license": "MIT", @@ -1023,24 +979,6 @@ "version": "1.0.0", "license": "MIT" }, - "apps/studio/node_modules/openai": { - "version": "4.19.0", - "license": "Apache-2.0", - "dependencies": { - "@types/node": "^18.11.18", - "@types/node-fetch": "^2.6.4", - "abort-controller": "^3.0.0", - "agentkeepalive": "^4.2.1", - "digest-fetch": "^1.3.0", - "form-data-encoder": "1.7.2", - "formdata-node": "^4.3.2", - "node-fetch": "^2.6.7", - "web-streams-polyfill": "^3.2.1" - }, - "bin": { - "openai": "bin/cli" - } - }, "apps/studio/node_modules/resolve": { "version": "2.0.0-next.5", "dev": true, @@ -17664,24 +17602,6 @@ "node": ">=0.4.0" } }, - "node_modules/follow-redirects": { - "version": "1.15.3", - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, "node_modules/for-each": { "version": "0.3.3", "license": "MIT", @@ -26415,34 +26335,30 @@ } }, "node_modules/openai": { - "version": "3.3.0", - "license": "MIT", + "version": "4.20.1", + "resolved": "https://registry.npmjs.org/openai/-/openai-4.20.1.tgz", + "integrity": "sha512-Dd3q8EvINfganZFtg6V36HjrMaihqRgIcKiHua4Nq9aw/PxOP48dhbsk8x5klrxajt5Lpnc1KTOG5i1S6BKAJA==", "dependencies": { - "axios": "^0.26.0", - "form-data": "^4.0.0" + "@types/node": "^18.11.18", + "@types/node-fetch": "^2.6.4", + "abort-controller": "^3.0.0", + "agentkeepalive": "^4.2.1", + "digest-fetch": "^1.3.0", + "form-data-encoder": "1.7.2", + "formdata-node": "^4.3.2", + "node-fetch": "^2.6.7", + "web-streams-polyfill": "^3.2.1" + }, + "bin": { + "openai": "bin/cli" } }, - "node_modules/openai-old": { - "name": "openai", - "version": "3.3.0", - "license": "MIT", + "node_modules/openai/node_modules/@types/node": { + "version": "18.18.13", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.13.tgz", + "integrity": "sha512-vXYZGRrSCreZmq1rEjMRLXJhiy8MrIeVasx+PCVlP414N7CJLHnMf+juVvjdprHyH+XRy3zKZLHeNueOpJCn0g==", "dependencies": { - "axios": "^0.26.0", - "form-data": "^4.0.0" - } - }, - "node_modules/openai-old/node_modules/axios": { - "version": "0.26.1", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.8" - } - }, - "node_modules/openai/node_modules/axios": { - "version": "0.26.1", - "license": "MIT", - "dependencies": { - "follow-redirects": "^1.14.8" + "undici-types": "~5.26.4" } }, "node_modules/openapi-fetch": { @@ -34939,7 +34855,7 @@ "lottie-light-react": "^2.4.0", "lucide-react": "^0.167.0", "next-themes": "^0.2.1", - "openai": "^3.3.0", + "openai": "^4.17.0", "postcss": "^8.4.31", "prop-types": "^15.7.2", "react-copy-to-clipboard": "^5.1.0", diff --git a/packages/ui/package.json b/packages/ui/package.json index 17df900e5f9..a709c2b789d 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -64,7 +64,7 @@ "lottie-light-react": "^2.4.0", "lucide-react": "^0.167.0", "next-themes": "^0.2.1", - "openai": "^3.3.0", + "openai": "^4.17.0", "postcss": "^8.4.31", "prop-types": "^15.7.2", "react-copy-to-clipboard": "^5.1.0", diff --git a/packages/ui/src/components/Command/AiCommand.tsx b/packages/ui/src/components/Command/AiCommand.tsx index 34b0ccd0127..565ae26ebe1 100644 --- a/packages/ui/src/components/Command/AiCommand.tsx +++ b/packages/ui/src/components/Command/AiCommand.tsx @@ -1,8 +1,4 @@ -import type { - ChatCompletionResponseMessage, - CreateChatCompletionResponse, - CreateChatCompletionResponseChoicesInner, -} from 'openai' +import type OpenAI from 'openai' import { Dispatch, SetStateAction, @@ -24,15 +20,15 @@ import { Input, markdownComponents, } from 'ui' -import { AiIcon, AiIconChat } from './Command.icons' +import { AiIconChat } from './Command.icons' import { CommandGroup, CommandItem, useAutoInputFocus, useHistoryKeys } from './Command.utils' import { AiWarning } from './Command.alerts' import { useCommandMenu } from './CommandMenuProvider' import ReactMarkdown from 'react-markdown' -import { cn } from './../../lib/utils' import remarkGfm from 'remark-gfm' +import { cn } from './../../lib/utils' const questions = [ 'How do I get started with Supabase?', @@ -43,13 +39,6 @@ const questions = [ 'How do I set up authentication?', ] -type CreateChatCompletionResponseChoicesInnerDelta = Omit< - CreateChatCompletionResponseChoicesInner, - 'message' -> & { - delta: Partial -} - function getEdgeFunctionUrl() { const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL?.replace(/\/$/, '') @@ -236,12 +225,12 @@ export function useAiChat({ setIsResponding(true) - const completionResponse: CreateChatCompletionResponse = JSON.parse(e.data) + const completionChunk: OpenAI.Chat.Completions.ChatCompletionChunk = JSON.parse(e.data) const [ { delta: { content }, }, - ] = completionResponse.choices as CreateChatCompletionResponseChoicesInnerDelta[] + ] = completionChunk.choices if (content) { dispatchMessage({ @@ -328,12 +317,12 @@ export function queryAi(messages: Message[], timeout = 0) { return } - const completionResponse: CreateChatCompletionResponse = JSON.parse(e.data) + const completionChunk: OpenAI.Chat.Completions.ChatCompletionChunk = JSON.parse(e.data) const [ { delta: { content }, }, - ] = completionResponse.choices as CreateChatCompletionResponseChoicesInnerDelta[] + ] = completionChunk.choices if (content) { answer += content