|
import { OpenAIStream, StreamingTextResponse } from 'ai'; |
|
import OpenAI from 'openai'; |
|
|
|
import { auth } from '@/auth'; |
|
import { nanoid } from '@/lib/utils'; |
|
import { |
|
ChatCompletionContentPart, |
|
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, image } = json as { |
|
messages: ChatCompletionMessageParam[]; |
|
image: 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, |
|
}, |
|
{ |
|
type: 'image_url', |
|
image_url: { url: image }, |
|
}, |
|
]; |
|
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); |
|
} |
|
|