fix(media): wire tools.media.image.maxBytes config to image processing pipeline

Fixes #2954

The configuration setting tools.media.image.maxBytes was defined but not wired through the image sanitization pipeline. This resulted in hardcoded constants being used instead of the user-configured value.

Changes:
- Modified sanitizeSessionMessagesImages() to accept maxBytes in options
- Modified sanitizeSessionHistory() to accept and pass maxBytes parameter
- Updated attempt.ts to pass config value through the sanitization chain
- All sanitizeContentBlocksImages() calls now receive the configured maxBytes

This ensures that when users configure a custom image size limit, it is actually used throughout the image processing pipeline instead of being ignored.
This commit is contained in:
MD.SHAMSUL ALAM 2026-01-28 03:07:26 +06:00
parent 284b54af42
commit 1bf77f82fe
3 changed files with 10 additions and 1 deletions

View File

@ -38,6 +38,7 @@ export async function sanitizeSessionMessagesImages(
allowBase64Only?: boolean;
includeCamelCase?: boolean;
};
maxBytes?: number;
},
): Promise<AgentMessage[]> {
const sanitizeMode = options?.sanitizeMode ?? "full";
@ -62,6 +63,7 @@ export async function sanitizeSessionMessagesImages(
const nextContent = (await sanitizeContentBlocksImages(
content as ContentBlock[],
label,
{ maxBytes: options?.maxBytes },
)) as unknown as typeof toolMsg.content;
out.push({ ...toolMsg, content: nextContent });
continue;
@ -74,6 +76,7 @@ export async function sanitizeSessionMessagesImages(
const nextContent = (await sanitizeContentBlocksImages(
content as unknown as ContentBlock[],
label,
{ maxBytes: options?.maxBytes },
)) as unknown as typeof userMsg.content;
out.push({ ...userMsg, content: nextContent });
continue;
@ -88,6 +91,7 @@ export async function sanitizeSessionMessagesImages(
const nextContent = (await sanitizeContentBlocksImages(
content as unknown as ContentBlock[],
label,
{ maxBytes: options?.maxBytes },
)) as unknown as typeof assistantMsg.content;
out.push({ ...assistantMsg, content: nextContent });
} else {
@ -101,6 +105,7 @@ export async function sanitizeSessionMessagesImages(
const nextContent = (await sanitizeContentBlocksImages(
content as unknown as ContentBlock[],
label,
{ maxBytes: options?.maxBytes },
)) as unknown as typeof assistantMsg.content;
out.push({ ...assistantMsg, content: nextContent });
continue;
@ -118,6 +123,7 @@ export async function sanitizeSessionMessagesImages(
const finalContent = (await sanitizeContentBlocksImages(
filteredContent as unknown as ContentBlock[],
label,
{ maxBytes: options?.maxBytes },
)) as unknown as typeof assistantMsg.content;
if (finalContent.length === 0) {
continue;

View File

@ -313,6 +313,7 @@ export async function sanitizeSessionHistory(params: {
sessionManager: SessionManager;
sessionId: string;
policy?: TranscriptPolicy;
maxBytes?: number;
}): Promise<AgentMessage[]> {
// Keep docs/reference/transcript-hygiene.md in sync with any logic changes here.
const policy =
@ -328,6 +329,7 @@ export async function sanitizeSessionHistory(params: {
toolCallIdMode: policy.toolCallIdMode,
preserveSignatures: policy.preserveSignatures,
sanitizeThoughtSignatures: policy.sanitizeThoughtSignatures,
maxBytes: params.maxBytes,
});
const sanitizedThinking = policy.normalizeAntigravityThinkingBlocks
? sanitizeAntigravityThinkingBlocks(sanitizedImages)

View File

@ -523,6 +523,7 @@ export async function runEmbeddedAttempt(
sessionManager,
sessionId: params.sessionId,
policy: transcriptPolicy,
maxBytes: params.config?.tools?.media?.image?.maxBytes,
});
cacheTrace?.recordStage("session:sanitized", { messages: prior });
const validatedGemini = transcriptPolicy.validateGeminiTurns
@ -743,7 +744,7 @@ export async function runEmbeddedAttempt(
model: params.model,
existingImages: params.images,
historyMessages: activeSession.messages,
maxBytes: MAX_IMAGE_BYTES,
maxBytes: params.config?.tools?.media?.image?.maxBytes ?? MAX_IMAGE_BYTES,
// Enforce sandbox path restrictions when sandbox is enabled
sandboxRoot: sandbox?.enabled ? sandbox.workspaceDir : undefined,
});