2024-07-15 14:32:42 +02:00
|
|
|
import { ImagePart, TextPart, UserContent } from 'ai'
|
2024-06-11 10:51:02 +02:00
|
|
|
import ky, { HTTPError } from 'ky'
|
|
|
|
|
2024-07-15 14:32:42 +02:00
|
|
|
type Props = {
|
2024-06-11 10:51:02 +02:00
|
|
|
input: string
|
2024-07-15 14:32:42 +02:00
|
|
|
shouldDownloadImages: boolean
|
|
|
|
}
|
|
|
|
export const splitUserTextMessageIntoBlocks = async ({
|
|
|
|
input,
|
|
|
|
shouldDownloadImages,
|
|
|
|
}: Props): Promise<UserContent> => {
|
2024-09-04 14:07:32 +02:00
|
|
|
const splittedInput = input.split('\n\n')
|
2024-07-15 14:32:42 +02:00
|
|
|
let parts: (TextPart | ImagePart)[] = []
|
2024-09-04 14:07:32 +02:00
|
|
|
for (const part of splittedInput) {
|
|
|
|
if (part.startsWith('http') || part.startsWith('["http')) {
|
|
|
|
const urls = part.startsWith('[') ? JSON.parse(part) : [part]
|
|
|
|
for (const url of urls) {
|
|
|
|
const cleanUrl = url.trim()
|
|
|
|
try {
|
|
|
|
const response = await ky.get(cleanUrl)
|
|
|
|
if (
|
|
|
|
!response.ok ||
|
|
|
|
!response.headers.get('content-type')?.startsWith('image/')
|
|
|
|
) {
|
|
|
|
parts.push({ type: 'text', text: cleanUrl })
|
|
|
|
} else {
|
|
|
|
parts.push({
|
|
|
|
type: 'image',
|
|
|
|
image: shouldDownloadImages
|
|
|
|
? await response.arrayBuffer()
|
|
|
|
: url.trim(),
|
|
|
|
})
|
|
|
|
}
|
|
|
|
} catch (err) {
|
|
|
|
if (err instanceof HTTPError) {
|
|
|
|
console.log(err.response.status, await err.response.text())
|
|
|
|
} else {
|
|
|
|
console.error(err)
|
|
|
|
}
|
|
|
|
}
|
2024-06-11 10:51:02 +02:00
|
|
|
}
|
2024-09-04 14:07:32 +02:00
|
|
|
} else {
|
|
|
|
if (parts.at(-1)?.type === 'text') {
|
|
|
|
const lastText = parts.at(-1) as TextPart
|
|
|
|
parts = parts.slice(0, -1)
|
|
|
|
parts.push({ type: 'text', text: lastText.text + '\n\n' + part })
|
2024-06-11 10:51:02 +02:00
|
|
|
} else {
|
2024-09-04 14:07:32 +02:00
|
|
|
parts.push({ type: 'text', text: part })
|
2024-06-11 10:51:02 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return parts
|
|
|
|
}
|