mirror of
https://github.com/luckyyzh/pi-agent-integrated.git
synced 2026-10-03 02:59:35 +00:00
feat: integrate Pi backend and Pi Web
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
export const MAX_ATTACHED_IMAGE_BYTES = 10 * 1024 * 1024;
|
||||
export const MAX_ATTACHED_IMAGES = 10;
|
||||
|
||||
export interface Base64ImageAttachment {
|
||||
data: string;
|
||||
mimeType: string;
|
||||
}
|
||||
|
||||
function isBase64DataChar(code: number): boolean {
|
||||
return (code >= 0x41 && code <= 0x5a)
|
||||
|| (code >= 0x61 && code <= 0x7a)
|
||||
|| (code >= 0x30 && code <= 0x39)
|
||||
|| code === 0x2b
|
||||
|| code === 0x2f;
|
||||
}
|
||||
|
||||
export function getBase64DecodedByteLength(data: string): number | null {
|
||||
if (!data || data.length % 4 !== 0) return null;
|
||||
const padding = data.endsWith("==") ? 2 : data.endsWith("=") ? 1 : 0;
|
||||
const dataEnd = data.length - padding;
|
||||
for (let index = 0; index < dataEnd; index += 1) {
|
||||
if (!isBase64DataChar(data.charCodeAt(index))) return null;
|
||||
}
|
||||
for (let index = dataEnd; index < data.length; index += 1) {
|
||||
if (data[index] !== "=") return null;
|
||||
}
|
||||
return (data.length / 4) * 3 - padding;
|
||||
}
|
||||
|
||||
export function isBase64ImageWithinLimits(value: unknown): value is Base64ImageAttachment {
|
||||
if (!value || typeof value !== "object") return false;
|
||||
const image = value as Partial<Base64ImageAttachment>;
|
||||
if (typeof image.data !== "string" || typeof image.mimeType !== "string" || !image.mimeType.startsWith("image/")) {
|
||||
return false;
|
||||
}
|
||||
const bytes = getBase64DecodedByteLength(image.data);
|
||||
return bytes !== null && bytes <= MAX_ATTACHED_IMAGE_BYTES;
|
||||
}
|
||||
|
||||
/** Return an API-safe error for prompt, steering, and follow-up image arrays. */
|
||||
export function validateAgentImages(value: unknown): string | null {
|
||||
if (value === undefined) return null;
|
||||
if (!Array.isArray(value)) return "images must be an array";
|
||||
if (value.length > MAX_ATTACHED_IMAGES) {
|
||||
return `A message can include at most ${MAX_ATTACHED_IMAGES} images`;
|
||||
}
|
||||
for (const image of value) {
|
||||
if (!image || typeof image !== "object" || (image as { type?: unknown }).type !== "image") {
|
||||
return "Each attachment must be an image";
|
||||
}
|
||||
if (!isBase64ImageWithinLimits(image)) {
|
||||
return `Each image must be valid base64 image data of ${MAX_ATTACHED_IMAGE_BYTES / (1024 * 1024)}MB or smaller`;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
Reference in New Issue
Block a user