🗂️ feat: Send Attachments Directly to Provider (Google) (#9100)

* feat: add validation for google PDFs and add google endpoint as a document supporting endpoint

* feat: add proper pdf formatting for google endpoints (requires PR #14 in agents)

* feat: add multimodal support for google endpoint attachments

* feat: add audio file svg

* fix: refactor attachments logic so multi-attachment messages work properly

* feat: add video file svg

* fix: allows for followup questions of uploaded multimodal attachments

* fix: remove incorrect final message filtering that was breaking Attachment component rendering
This commit is contained in:
Dustin Healy 2025-08-18 05:39:50 -07:00 committed by Dustin Healy
parent b5aadf1302
commit aae47e7b3f
13 changed files with 581 additions and 15 deletions

View file

@ -5,6 +5,16 @@ export interface PDFValidationResult {
error?: string;
}
export interface VideoValidationResult {
isValid: boolean;
error?: string;
}
export interface AudioValidationResult {
isValid: boolean;
error?: string;
}
export async function validatePdf(
pdfBuffer: Buffer,
fileSize: number,
@ -18,6 +28,10 @@ export async function validatePdf(
return validateOpenAIPdf(fileSize);
}
if (endpoint === EModelEndpoint.google) {
return validateGooglePdf(fileSize);
}
return { isValid: true };
}
@ -96,3 +110,76 @@ async function validateOpenAIPdf(fileSize: number): Promise<PDFValidationResult>
return { isValid: true };
}
async function validateGooglePdf(fileSize: number): Promise<PDFValidationResult> {
if (fileSize > 20 * 1024 * 1024) {
return {
isValid: false,
error: "PDF file size exceeds Google's 20MB limit",
};
}
return { isValid: true };
}
/**
* Validates video files for different endpoints
* @param videoBuffer - The video file as a buffer
* @param fileSize - The file size in bytes
* @param endpoint - The endpoint to validate for
* @returns Promise that resolves to validation result
*/
export async function validateVideo(
videoBuffer: Buffer,
fileSize: number,
endpoint: EModelEndpoint,
): Promise<VideoValidationResult> {
if (endpoint === EModelEndpoint.google) {
if (fileSize > 20 * 1024 * 1024) {
return {
isValid: false,
error: `Video file size (${Math.round(fileSize / (1024 * 1024))}MB) exceeds Google's 20MB limit`,
};
}
}
if (!videoBuffer || videoBuffer.length < 10) {
return {
isValid: false,
error: 'Invalid video file: too small or corrupted',
};
}
return { isValid: true };
}
/**
* Validates audio files for different endpoints
* @param audioBuffer - The audio file as a buffer
* @param fileSize - The file size in bytes
* @param endpoint - The endpoint to validate for
* @returns Promise that resolves to validation result
*/
export async function validateAudio(
audioBuffer: Buffer,
fileSize: number,
endpoint: EModelEndpoint,
): Promise<AudioValidationResult> {
if (endpoint === EModelEndpoint.google) {
if (fileSize > 20 * 1024 * 1024) {
return {
isValid: false,
error: `Audio file size (${Math.round(fileSize / (1024 * 1024))}MB) exceeds Google's 20MB limit`,
};
}
}
if (!audioBuffer || audioBuffer.length < 10) {
return {
isValid: false,
error: 'Invalid audio file: too small or corrupted',
};
}
return { isValid: true };
}