mirror of
https://github.com/toeverything/AFFiNE.git
synced 2026-08-09 05:05:52 +08:00
chore: drop old client support (#14369)
This commit is contained in:
@@ -24,7 +24,9 @@ import {
|
||||
CopilotPromptInvalid,
|
||||
CopilotProviderNotSupported,
|
||||
CopilotProviderSideError,
|
||||
fetchBuffer,
|
||||
metrics,
|
||||
OneMB,
|
||||
UserFriendlyError,
|
||||
} from '../../../base';
|
||||
import { CopilotProvider } from './provider';
|
||||
@@ -673,14 +675,12 @@ export class OpenAIProvider extends CopilotProvider<OpenAIConfig> {
|
||||
|
||||
for (const [idx, entry] of attachments.entries()) {
|
||||
const url = typeof entry === 'string' ? entry : entry.attachment;
|
||||
const resp = await fetch(url);
|
||||
if (resp.ok) {
|
||||
const type = resp.headers.get('content-type');
|
||||
if (type && type.startsWith('image/')) {
|
||||
const buffer = new Uint8Array(await resp.arrayBuffer());
|
||||
const file = new File([buffer], `${idx}.png`, { type });
|
||||
form.append('image[]', file);
|
||||
}
|
||||
try {
|
||||
const { buffer, type } = await fetchBuffer(url, 10 * OneMB, 'image/');
|
||||
const file = new File([buffer], `${idx}.png`, { type });
|
||||
form.append('image[]', file);
|
||||
} catch {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,11 +12,22 @@ import {
|
||||
import { GoogleAuth, GoogleAuthOptions } from 'google-auth-library';
|
||||
import z, { ZodType } from 'zod';
|
||||
|
||||
import {
|
||||
bufferToArrayBuffer,
|
||||
fetchBuffer,
|
||||
OneMinute,
|
||||
ResponseTooLargeError,
|
||||
safeFetch,
|
||||
SsrfBlockedError,
|
||||
} from '../../../base';
|
||||
import { CustomAITools } from '../tools';
|
||||
import { PromptMessage, StreamObject } from './types';
|
||||
|
||||
type ChatMessage = CoreUserMessage | CoreAssistantMessage;
|
||||
|
||||
const ATTACHMENT_MAX_BYTES = 20 * 1024 * 1024;
|
||||
const ATTACH_HEAD_PARAMS = { timeoutMs: OneMinute / 12, maxRedirects: 3 };
|
||||
|
||||
const SIMPLE_IMAGE_URL_REGEX = /^(https?:\/\/|data:image\/)/;
|
||||
const FORMAT_INFER_MAP: Record<string, string> = {
|
||||
pdf: 'application/pdf',
|
||||
@@ -42,6 +53,11 @@ const FORMAT_INFER_MAP: Record<string, string> = {
|
||||
flv: 'video/flv',
|
||||
};
|
||||
|
||||
async function fetchArrayBuffer(url: string): Promise<ArrayBuffer> {
|
||||
const { buffer } = await fetchBuffer(url, ATTACHMENT_MAX_BYTES);
|
||||
return bufferToArrayBuffer(buffer);
|
||||
}
|
||||
|
||||
export async function inferMimeType(url: string) {
|
||||
if (url.startsWith('data:')) {
|
||||
return url.split(';')[0].split(':')[1];
|
||||
@@ -53,12 +69,15 @@ export async function inferMimeType(url: string) {
|
||||
if (ext) {
|
||||
return ext;
|
||||
}
|
||||
const mimeType = await fetch(url, {
|
||||
method: 'HEAD',
|
||||
redirect: 'follow',
|
||||
}).then(res => res.headers.get('Content-Type'));
|
||||
if (mimeType) {
|
||||
return mimeType;
|
||||
try {
|
||||
const mimeType = await safeFetch(
|
||||
url,
|
||||
{ method: 'HEAD' },
|
||||
ATTACH_HEAD_PARAMS
|
||||
).then(res => res.headers.get('content-type'));
|
||||
if (mimeType) return mimeType;
|
||||
} catch {
|
||||
// ignore and fallback to default
|
||||
}
|
||||
}
|
||||
return 'application/octet-stream';
|
||||
@@ -106,7 +125,16 @@ export async function chatToGPTMessage(
|
||||
if (SIMPLE_IMAGE_URL_REGEX.test(attachment)) {
|
||||
const data =
|
||||
attachment.startsWith('data:') || useBase64Attachment
|
||||
? await fetch(attachment).then(r => r.arrayBuffer())
|
||||
? await fetchArrayBuffer(attachment).catch(error => {
|
||||
// Avoid leaking internal details for blocked URLs.
|
||||
if (
|
||||
error instanceof SsrfBlockedError ||
|
||||
error instanceof ResponseTooLargeError
|
||||
) {
|
||||
throw new Error('Attachment URL is not allowed');
|
||||
}
|
||||
throw error;
|
||||
})
|
||||
: new URL(attachment);
|
||||
if (mediaType.startsWith('image/')) {
|
||||
contents.push({ type: 'image', image: data, mediaType });
|
||||
|
||||
Reference in New Issue
Block a user