From 5338bdfc0fe07935c97ac143273e91daf11ba569 Mon Sep 17 00:00:00 2001 From: hailin Date: Sat, 7 Feb 2026 04:55:54 -0800 Subject: [PATCH] fix(agents): correct Claude API file size limits (image 5MB, PDF 25MB) Claude API enforces a hard 5MB limit per image (not 20MB as previously set). PDFs have a 32MB total request limit; set individual PDF cap to 25MB to leave room for prompt/messages. The downloadAsBase64 method now accepts a per-type maxSize parameter. Co-Authored-By: Claude Opus 4.6 --- .../coordinator/coordinator-agent.service.ts | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/services/conversation-service/src/infrastructure/agents/coordinator/coordinator-agent.service.ts b/packages/services/conversation-service/src/infrastructure/agents/coordinator/coordinator-agent.service.ts index 507ff16..428dbf4 100644 --- a/packages/services/conversation-service/src/infrastructure/agents/coordinator/coordinator-agent.service.ts +++ b/packages/services/conversation-service/src/infrastructure/agents/coordinator/coordinator-agent.service.ts @@ -330,8 +330,10 @@ export class CoordinatorAgentService implements OnModuleInit { /** 文本类文件最大嵌入大小 (超过则截断) */ private readonly MAX_TEXT_EMBED_SIZE = 50_000; - /** 二进制文件最大 base64 大小 (20MB,Claude API 限制) */ - private readonly MAX_BINARY_SIZE = 20 * 1024 * 1024; + /** 图片最大 5MB(Claude API 硬限制) */ + private readonly MAX_IMAGE_SIZE = 5 * 1024 * 1024; + /** PDF 最大 25MB(Claude API 整个请求 32MB 限制,留 7MB 给 prompt/messages) */ + private readonly MAX_PDF_SIZE = 25 * 1024 * 1024; /** * 获取 file-service 内部地址 @@ -364,13 +366,13 @@ export class CoordinatorAgentService implements OnModuleInit { try { if (att.type === 'image') { - const { base64, mediaType } = await this.downloadAsBase64(contentUrl, att.mimeType); + const { base64, mediaType } = await this.downloadAsBase64(contentUrl, att.mimeType, this.MAX_IMAGE_SIZE); blocks.push({ type: 'image', source: { type: 'base64', media_type: mediaType, data: base64 }, }); } else if (att.mimeType === 'application/pdf') { - const { base64 } = await this.downloadAsBase64(contentUrl, att.mimeType); + const { base64 } = await this.downloadAsBase64(contentUrl, att.mimeType, this.MAX_PDF_SIZE); blocks.push({ type: 'document', source: { type: 'base64', media_type: 'application/pdf', data: base64 }, @@ -405,14 +407,14 @@ export class CoordinatorAgentService implements OnModuleInit { * 从内部 URL 下载文件并转为 base64 * conversation-service 与 file-service 同在 Docker 网络内 */ - private async downloadAsBase64(url: string, mimeType: string): Promise<{ base64: string; mediaType: string }> { + private async downloadAsBase64(url: string, mimeType: string, maxSize: number): Promise<{ base64: string; mediaType: string }> { const response = await fetch(url); if (!response.ok) { throw new Error(`HTTP ${response.status} from ${url}`); } const arrayBuffer = await response.arrayBuffer(); - if (arrayBuffer.byteLength > this.MAX_BINARY_SIZE) { - throw new Error(`文件过大 (${(arrayBuffer.byteLength / 1024 / 1024).toFixed(1)}MB),超过 ${this.MAX_BINARY_SIZE / 1024 / 1024}MB 限制`); + if (arrayBuffer.byteLength > maxSize) { + throw new Error(`文件过大 (${(arrayBuffer.byteLength / 1024 / 1024).toFixed(1)}MB),超过 ${(maxSize / 1024 / 1024).toFixed(0)}MB 限制`); } const base64 = Buffer.from(arrayBuffer).toString('base64'); return { base64, mediaType: mimeType };