mirror of
https://github.com/danny-avila/LibreChat.git
synced 2026-04-02 22:07:19 +02:00
📄 feat: Model-Aware Bedrock Document Size Validation (#12467)
* 📄 fix: Model-Aware Bedrock Document Size Validation
Remove the hard 4.5MB clamp on Bedrock document uploads so that
Claude 4+ (PDF) and Nova (PDF/DOCX) models can accept larger files
per AWS documentation. The default 4.5MB limit is preserved for
other models/formats, and fileConfig can now override it in either
direction—consistent with every other provider.
* address review: restore Math.min for non-exempt docs, tighten regexes, add tests
- Restore Math.min clamp for non-exempt Bedrock documents (fileConfig can
only lower the hard 4.5 MB API limit, not raise it); only exempt models
(Claude 4+ PDF, Nova PDF/DOCX) use ?? to allow fileConfig override
- Replace copied isBedrockClaude4Plus regex with cleaner anchored pattern
that correctly handles multi-digit version numbers (e.g. sonnet-40)
and removes dead Alt 1 branch matching no real Bedrock model IDs
- Tighten isBedrockNova from includes() to startsWith() to prevent
substring matching in unexpected positions
- Add integration test verifying model is threaded to validateBedrockDocument
- Add boundary tests for exempt + low configuredFileSizeLimit, non-exempt
+ high configuredFileSizeLimit, and exempt model accepting files up to 32 MB
- Revert two tests that were incorrectly inverted to prove wrong behavior
- Fix inaccurate JSDoc and misleading test name
* simplify: allow fileConfig to override Bedrock limit in either direction
Make Bedrock consistent with all other providers — fileConfig sets the
effective limit unconditionally via ?? rather than clamping with Math.min.
The model-aware defaults (4.5 MB for non-exempt, 32 MB for exempt) remain
as sensible fallbacks when no fileConfig is set.
* fix: handle cross-region inference profile IDs in Bedrock model matchers
Bedrock cross-region inference profiles prepend a region code to the
model ID (e.g. "us.amazon.nova-pro-v1:0", "eu.anthropic.claude-sonnet-4-...").
Both isBedrockNova and isBedrockClaude4Plus would miss these prefixed IDs,
silently falling back to the 4.5 MB default for eligible models.
Switch both matchers to use (?:^|\.) to anchor the vendor segment so the
pattern matches with or without a leading region prefix.
This commit is contained in:
parent
fda72ac621
commit
1455f15b7b
5 changed files with 254 additions and 26 deletions
|
|
@ -1085,6 +1085,7 @@ class BaseClient {
|
|||
provider: this.options.agent?.provider ?? this.options.endpoint,
|
||||
endpoint: this.options.agent?.endpoint ?? this.options.endpoint,
|
||||
useResponsesApi: this.options.agent?.model_parameters?.useResponsesApi,
|
||||
model: this.modelOptions?.model ?? this.model,
|
||||
},
|
||||
getStrategyFunctions,
|
||||
);
|
||||
|
|
|
|||
|
|
@ -88,11 +88,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
updatedAt: new Date(),
|
||||
}) as unknown as IMongoFile;
|
||||
|
||||
const createMockDocFile = (
|
||||
sizeInMB: number,
|
||||
mimeType: string,
|
||||
filename: string,
|
||||
): IMongoFile =>
|
||||
const createMockDocFile = (sizeInMB: number, mimeType: string, filename: string): IMongoFile =>
|
||||
({
|
||||
_id: new Types.ObjectId(),
|
||||
user: new Types.ObjectId(),
|
||||
|
|
@ -135,6 +131,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
configuredLimit,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -163,6 +160,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -196,6 +194,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -235,6 +234,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.ANTHROPIC,
|
||||
configuredLimit,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -274,6 +274,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.GOOGLE,
|
||||
configuredLimit,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -314,6 +315,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
undefined,
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -407,6 +409,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
mbToBytes(5),
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -441,6 +444,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
mbToBytes(50),
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
|
||||
|
|
@ -480,6 +484,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
mbToBytes(10),
|
||||
undefined,
|
||||
);
|
||||
expect(mockedValidatePdf).toHaveBeenNthCalledWith(
|
||||
2,
|
||||
|
|
@ -487,6 +492,7 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
expect.any(Number),
|
||||
Providers.OPENAI,
|
||||
mbToBytes(10),
|
||||
undefined,
|
||||
);
|
||||
});
|
||||
});
|
||||
|
|
@ -657,6 +663,36 @@ describe('encodeAndFormatDocuments - fileConfig integration', () => {
|
|||
});
|
||||
});
|
||||
|
||||
it('should thread model to validateBedrockDocument when model is provided', async () => {
|
||||
const req = createMockRequest() as ServerRequest;
|
||||
const model = 'anthropic.claude-sonnet-4-20250514-v1:0';
|
||||
const file = createMockDocFile(1, 'text/csv', 'data.csv');
|
||||
|
||||
const mockContent = Buffer.from('col1,col2\nval1,val2').toString('base64');
|
||||
mockedGetFileStream.mockResolvedValue({
|
||||
file,
|
||||
content: mockContent,
|
||||
metadata: file,
|
||||
});
|
||||
|
||||
mockedValidateBedrockDocument.mockResolvedValue({ isValid: true });
|
||||
|
||||
await encodeAndFormatDocuments(
|
||||
req,
|
||||
[file],
|
||||
{ provider: Providers.BEDROCK, model },
|
||||
mockStrategyFunctions,
|
||||
);
|
||||
|
||||
expect(mockedValidateBedrockDocument).toHaveBeenCalledWith(
|
||||
expect.any(Number),
|
||||
'text/csv',
|
||||
expect.any(Buffer),
|
||||
undefined,
|
||||
model,
|
||||
);
|
||||
});
|
||||
|
||||
it('should reject Bedrock document when validation fails', async () => {
|
||||
const req = createMockRequest() as ServerRequest;
|
||||
const file = createMockDocFile(5, 'text/csv', 'big.csv');
|
||||
|
|
|
|||
|
|
@ -29,10 +29,10 @@ import { getFileStream, getConfiguredFileSizeLimit } from './utils';
|
|||
export async function encodeAndFormatDocuments(
|
||||
req: ServerRequest,
|
||||
files: IMongoFile[],
|
||||
params: { provider: Providers; endpoint?: string; useResponsesApi?: boolean },
|
||||
params: { provider: Providers; endpoint?: string; useResponsesApi?: boolean; model?: string },
|
||||
getStrategyFunctions: (source: string) => StrategyFunctions,
|
||||
): Promise<DocumentResult> {
|
||||
const { provider, endpoint, useResponsesApi } = params;
|
||||
const { provider, endpoint, useResponsesApi, model } = params;
|
||||
if (!files?.length) {
|
||||
return { documents: [], files: [] };
|
||||
}
|
||||
|
|
@ -94,6 +94,7 @@ export async function encodeAndFormatDocuments(
|
|||
mimeType,
|
||||
fileBuffer,
|
||||
configuredFileSizeLimit,
|
||||
model,
|
||||
);
|
||||
|
||||
if (!validation.isValid) {
|
||||
|
|
@ -122,6 +123,7 @@ export async function encodeAndFormatDocuments(
|
|||
pdfBuffer.length,
|
||||
provider,
|
||||
configuredFileSizeLimit,
|
||||
model,
|
||||
);
|
||||
|
||||
if (!validation.isValid) {
|
||||
|
|
|
|||
|
|
@ -173,13 +173,13 @@ describe('PDF Validation with fileConfig.endpoints.*.fileSizeLimit', () => {
|
|||
expect(result.error).toContain('2.0MB');
|
||||
});
|
||||
|
||||
it('should clamp to 4.5MB hard limit even when config is higher', async () => {
|
||||
it('should allow configured limit higher than 4.5MB default', async () => {
|
||||
const configuredLimit = mbToBytes(512);
|
||||
const pdfBuffer = createMockPdfBuffer(5);
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, configuredLimit);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('4.5MB');
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should reject PDFs with invalid header', async () => {
|
||||
|
|
@ -200,6 +200,120 @@ describe('PDF Validation with fileConfig.endpoints.*.fileSizeLimit', () => {
|
|||
});
|
||||
});
|
||||
|
||||
describe('validatePdf - Bedrock with model-specific exemptions', () => {
|
||||
const provider = Providers.BEDROCK;
|
||||
|
||||
it('should exempt Claude 4+ PDFs from the 4.5MB limit', async () => {
|
||||
const pdfBuffer = createMockPdfBuffer(10);
|
||||
const model = 'anthropic.claude-sonnet-4-20250514-v1:0';
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should exempt Claude 4+ PDFs via cross-region inference profile ID', async () => {
|
||||
const pdfBuffer = createMockPdfBuffer(10);
|
||||
const model = 'us.anthropic.claude-sonnet-4-20250514-v1:0';
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should exempt Nova PDFs from the 4.5MB limit', async () => {
|
||||
const pdfBuffer = createMockPdfBuffer(10);
|
||||
const model = 'amazon.nova-pro-v1:0';
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should exempt Nova PDFs via cross-region inference profile ID', async () => {
|
||||
const pdfBuffer = createMockPdfBuffer(10);
|
||||
const model = 'us.amazon.nova-pro-v1:0';
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should still enforce 4.5MB for non-exempt models without config override', async () => {
|
||||
const pdfBuffer = createMockPdfBuffer(5);
|
||||
const model = 'anthropic.claude-3-5-sonnet-20241022-v2:0';
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('4.5MB');
|
||||
});
|
||||
|
||||
it('should accept PDFs below 32MB for exempt Claude 4+ models', async () => {
|
||||
const pdfBuffer = createMockPdfBuffer(30);
|
||||
const model = 'anthropic.claude-opus-4-20250514-v1:0';
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
});
|
||||
|
||||
it('should reject exempt model PDFs exceeding 32MB', async () => {
|
||||
const pdfBuffer = createMockPdfBuffer(35);
|
||||
const model = 'anthropic.claude-sonnet-4-20250514-v1:0';
|
||||
const result = await validatePdf(pdfBuffer, pdfBuffer.length, provider, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('32.0MB');
|
||||
});
|
||||
|
||||
it('should respect configuredFileSizeLimit when lower than 32MB for exempt models', async () => {
|
||||
const configuredLimit = mbToBytes(10);
|
||||
const pdfBuffer = createMockPdfBuffer(15);
|
||||
const model = 'anthropic.claude-sonnet-4-20250514-v1:0';
|
||||
const result = await validatePdf(
|
||||
pdfBuffer,
|
||||
pdfBuffer.length,
|
||||
provider,
|
||||
configuredLimit,
|
||||
model,
|
||||
);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('10.0MB');
|
||||
});
|
||||
|
||||
it('should allow configuredFileSizeLimit higher than 32MB for exempt models', async () => {
|
||||
const configuredLimit = mbToBytes(50);
|
||||
const pdfBuffer = createMockPdfBuffer(35);
|
||||
const model = 'amazon.nova-pro-v1:0';
|
||||
const result = await validatePdf(
|
||||
pdfBuffer,
|
||||
pdfBuffer.length,
|
||||
provider,
|
||||
configuredLimit,
|
||||
model,
|
||||
);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should allow configuredFileSizeLimit higher than 4.5MB for non-exempt models', async () => {
|
||||
const configuredLimit = mbToBytes(100);
|
||||
const pdfBuffer = createMockPdfBuffer(5);
|
||||
const model = 'anthropic.claude-3-5-sonnet-20241022-v2:0';
|
||||
const result = await validatePdf(
|
||||
pdfBuffer,
|
||||
pdfBuffer.length,
|
||||
provider,
|
||||
configuredLimit,
|
||||
model,
|
||||
);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
});
|
||||
|
||||
describe('validateBedrockDocument - non-PDF types', () => {
|
||||
it('should accept CSV within 4.5MB limit', async () => {
|
||||
const fileSize = 2 * 1024 * 1024;
|
||||
|
|
@ -218,7 +332,7 @@ describe('PDF Validation with fileConfig.endpoints.*.fileSizeLimit', () => {
|
|||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should reject non-PDF document exceeding 4.5MB hard limit', async () => {
|
||||
it('should reject non-PDF document exceeding 4.5MB default limit', async () => {
|
||||
const fileSize = 5 * 1024 * 1024;
|
||||
const result = await validateBedrockDocument(fileSize, 'text/plain');
|
||||
|
||||
|
|
@ -226,24 +340,54 @@ describe('PDF Validation with fileConfig.endpoints.*.fileSizeLimit', () => {
|
|||
expect(result.error).toContain('4.5MB');
|
||||
});
|
||||
|
||||
it('should clamp to 4.5MB even when config is higher for non-PDF', async () => {
|
||||
it('should allow configured limit higher than 4.5MB for non-PDF', async () => {
|
||||
const fileSize = 5 * 1024 * 1024;
|
||||
const configuredLimit = mbToBytes(512);
|
||||
const result = await validateBedrockDocument(fileSize, 'text/html', undefined, configuredLimit);
|
||||
const result = await validateBedrockDocument(
|
||||
fileSize,
|
||||
'text/html',
|
||||
undefined,
|
||||
configuredLimit,
|
||||
);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('4.5MB');
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should use configured limit when lower than provider limit for non-PDF', async () => {
|
||||
const fileSize = 3 * 1024 * 1024;
|
||||
const configuredLimit = mbToBytes(2);
|
||||
const result = await validateBedrockDocument(fileSize, 'text/markdown', undefined, configuredLimit);
|
||||
const result = await validateBedrockDocument(
|
||||
fileSize,
|
||||
'text/markdown',
|
||||
undefined,
|
||||
configuredLimit,
|
||||
);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('2.0MB');
|
||||
});
|
||||
|
||||
it('should exempt Nova DOCX from 4.5MB limit', async () => {
|
||||
const fileSize = 10 * 1024 * 1024;
|
||||
const mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
||||
const model = 'amazon.nova-pro-v1:0';
|
||||
const result = await validateBedrockDocument(fileSize, mimeType, undefined, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(true);
|
||||
expect(result.error).toBeUndefined();
|
||||
});
|
||||
|
||||
it('should NOT exempt Claude 4+ DOCX from 4.5MB limit (only PDF exempt)', async () => {
|
||||
const fileSize = 5 * 1024 * 1024;
|
||||
const mimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
||||
const model = 'anthropic.claude-sonnet-4-20250514-v1:0';
|
||||
const result = await validateBedrockDocument(fileSize, mimeType, undefined, undefined, model);
|
||||
|
||||
expect(result.isValid).toBe(false);
|
||||
expect(result.error).toContain('4.5MB');
|
||||
});
|
||||
|
||||
it('should not run PDF header check on non-PDF types', async () => {
|
||||
const buffer = Buffer.from('NOT-A-PDF-HEADER-but-valid-csv-content');
|
||||
const result = await validateBedrockDocument(buffer.length, 'text/csv', buffer);
|
||||
|
|
|
|||
|
|
@ -31,13 +31,20 @@ export async function validatePdf(
|
|||
fileSize: number,
|
||||
provider: Providers,
|
||||
configuredFileSizeLimit?: number,
|
||||
model?: string,
|
||||
): Promise<PDFValidationResult> {
|
||||
if (provider === Providers.ANTHROPIC) {
|
||||
return validateAnthropicPdf(pdfBuffer, fileSize, configuredFileSizeLimit);
|
||||
}
|
||||
|
||||
if (provider === Providers.BEDROCK) {
|
||||
return validateBedrockDocument(fileSize, 'application/pdf', pdfBuffer, configuredFileSizeLimit);
|
||||
return validateBedrockDocument(
|
||||
fileSize,
|
||||
'application/pdf',
|
||||
pdfBuffer,
|
||||
configuredFileSizeLimit,
|
||||
model,
|
||||
);
|
||||
}
|
||||
|
||||
if (isOpenAILikeProvider(provider)) {
|
||||
|
|
@ -123,12 +130,51 @@ async function validateAnthropicPdf(
|
|||
}
|
||||
|
||||
/**
|
||||
* Validates a document against Bedrock's 4.5MB hard limit. PDF-specific header
|
||||
* checks run only when the MIME type is `application/pdf`.
|
||||
* Matches Bedrock Claude 4+ model identifiers, including cross-region inference profile IDs.
|
||||
* Pattern: [region.]anthropic.claude-{family}-{version≥4}-{date}-v{n}:{rev}
|
||||
* e.g. "anthropic.claude-sonnet-4-20250514-v1:0" or "us.anthropic.claude-sonnet-4-20250514-v1:0"
|
||||
*/
|
||||
const BEDROCK_CLAUDE_4_PLUS_RE = /(?:^|\.)anthropic\.claude-(?:sonnet|opus|haiku)-[4-9]\d*-/;
|
||||
const isBedrockClaude4Plus = (model?: string): boolean =>
|
||||
model != null && BEDROCK_CLAUDE_4_PLUS_RE.test(model);
|
||||
|
||||
/**
|
||||
* Matches Bedrock Nova model identifiers, including cross-region inference profile IDs.
|
||||
* e.g. "amazon.nova-pro-v1:0" or "us.amazon.nova-pro-v1:0"
|
||||
*/
|
||||
const isBedrockNova = (model?: string): boolean =>
|
||||
model != null && /(?:^|\.)amazon\.nova-/.test(model);
|
||||
|
||||
const pdfMimeType = 'application/pdf';
|
||||
const docxMimeType = 'application/vnd.openxmlformats-officedocument.wordprocessingml.document';
|
||||
|
||||
/**
|
||||
* Returns true when the given model + MIME type combination is exempt from
|
||||
* Bedrock's default 4.5 MB per-document limit.
|
||||
*
|
||||
* Per AWS docs (https://docs.aws.amazon.com/bedrock/latest/userguide/inference-api-restrictions.html):
|
||||
* - Claude 4+: PDFs are exempt from the 4.5 MB limit
|
||||
* - Nova: PDFs and DOCX are exempt from the 4.5 MB limit
|
||||
*/
|
||||
const isExemptFromBedrockDocLimit = (model?: string, mimeType?: string): boolean => {
|
||||
if (mimeType === pdfMimeType) {
|
||||
return isBedrockClaude4Plus(model) || isBedrockNova(model);
|
||||
}
|
||||
if (mimeType === docxMimeType) {
|
||||
return isBedrockNova(model);
|
||||
}
|
||||
return false;
|
||||
};
|
||||
|
||||
/**
|
||||
* Validates a document against Bedrock size limits. The default limit is 4.5 MB,
|
||||
* but Claude 4+ (PDF) and Nova (PDF/DOCX) models are exempt per AWS docs.
|
||||
* When exempt, falls back to a 32 MB request-level limit as a reasonable upper bound.
|
||||
* @param fileSize - The file size in bytes
|
||||
* @param mimeType - The MIME type of the document
|
||||
* @param fileBuffer - The file buffer (used for PDF header validation)
|
||||
* @param configuredFileSizeLimit - Optional configured file size limit from fileConfig (in bytes)
|
||||
* @param model - Optional Bedrock model identifier for model-specific limit exceptions
|
||||
* @returns Promise that resolves to validation result
|
||||
*/
|
||||
export async function validateBedrockDocument(
|
||||
|
|
@ -136,14 +182,13 @@ export async function validateBedrockDocument(
|
|||
mimeType: string,
|
||||
fileBuffer?: Buffer,
|
||||
configuredFileSizeLimit?: number,
|
||||
model?: string,
|
||||
): Promise<ValidationResult> {
|
||||
try {
|
||||
/** Bedrock enforces a hard 4.5MB per-document limit at the API level; config can only lower it */
|
||||
const providerLimit = mbToBytes(4.5);
|
||||
const effectiveLimit =
|
||||
configuredFileSizeLimit != null
|
||||
? Math.min(configuredFileSizeLimit, providerLimit)
|
||||
: providerLimit;
|
||||
const exempt = isExemptFromBedrockDocLimit(model, mimeType);
|
||||
/** Default 4.5 MB; exempt models (Claude 4+ PDF, Nova PDF/DOCX) default to 32 MB when unconfigured */
|
||||
const providerLimit = exempt ? mbToBytes(32) : mbToBytes(4.5);
|
||||
const effectiveLimit = configuredFileSizeLimit ?? providerLimit;
|
||||
|
||||
if (fileSize > effectiveLimit) {
|
||||
const limitMB = (effectiveLimit / (1024 * 1024)).toFixed(1);
|
||||
|
|
@ -153,7 +198,7 @@ export async function validateBedrockDocument(
|
|||
};
|
||||
}
|
||||
|
||||
if (mimeType === 'application/pdf' && fileBuffer) {
|
||||
if (mimeType === pdfMimeType && fileBuffer) {
|
||||
if (fileBuffer.length < 5) {
|
||||
return {
|
||||
isValid: false,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue