Spaces:
Running
Running
import { OpenAIStream, StreamingTextResponse } from 'ai'; | |
import OpenAI from 'openai'; | |
import { auth } from '@/auth'; | |
import { nanoid } from '@/lib/utils'; | |
import { | |
ChatCompletionContentPart, | |
ChatCompletionContentPartImage, | |
ChatCompletionMessageParam, | |
} from 'openai/resources'; | |
export const runtime = 'edge'; | |
const openai = new OpenAI({ | |
apiKey: process.env.OPENAI_API_KEY, | |
}); | |
export async function POST(req: Request) { | |
const json = await req.json(); | |
const { messages, dataset } = json as { | |
messages: ChatCompletionMessageParam[]; | |
dataset: string[]; | |
}; | |
const userId = (await auth())?.user.id; | |
if (!userId) { | |
return new Response('Unauthorized', { | |
status: 401, | |
}); | |
} | |
const messagesWithImage: ChatCompletionMessageParam[] = messages.map( | |
message => { | |
if (message.role !== 'user') return message; | |
const contentWithImage: ChatCompletionContentPart[] = [ | |
{ | |
type: 'text', | |
text: message.content as string, | |
}, | |
...dataset.map( | |
image => | |
({ | |
type: 'image_url', | |
image_url: { url: image }, | |
}) satisfies ChatCompletionContentPartImage, | |
), | |
]; | |
return { | |
role: 'user', | |
content: contentWithImage, | |
}; | |
}, | |
); | |
const res = await openai.chat.completions.create({ | |
model: 'gpt-4-vision-preview', | |
messages: messagesWithImage, | |
temperature: 0.7, | |
stream: true, | |
max_tokens: 300, | |
}); | |
const stream = OpenAIStream(res, { | |
async onCompletion(completion) { | |
const title = json.messages[0].content.substring(0, 100); | |
const id = json.id ?? nanoid(); | |
const createdAt = Date.now(); | |
const payload = { | |
id, | |
title, | |
userId, | |
createdAt, | |
messages: [ | |
...messages, | |
{ | |
content: completion, | |
role: 'assistant', | |
}, | |
], | |
}; | |
}, | |
}); | |
return new StreamingTextResponse(stream); | |
} | |