feat(tools): add image support to read_file tool (#5172)

Co-authored-by: Daniel <57051444+daniel-lxs@users.noreply.github.com>
Co-authored-by: Daniel Riccio <ricciodaniel98@gmail.com>
This commit is contained in:
Sam Hoang Van 2025-07-29 10:23:33 +07:00 committed by GitHub
parent 93930643c6
commit 017622d3e3
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
49 changed files with 1847 additions and 90 deletions

View file

@ -101,6 +101,8 @@ export const globalSettingsSchema = z.object({
maxWorkspaceFiles: z.number().optional(),
showRooIgnoredFiles: z.boolean().optional(),
maxReadFileLine: z.number().optional(),
maxImageFileSize: z.number().optional(),
maxTotalImageSize: z.number().optional(),
terminalOutputLineLimit: z.number().optional(),
terminalOutputCharacterLimit: z.number().optional(),

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,192 @@
import path from "path"
import * as fs from "fs/promises"
import { t } from "../../../i18n"
import prettyBytes from "pretty-bytes"
/**
* Default maximum allowed image file size in bytes (5MB)
*/
export const DEFAULT_MAX_IMAGE_FILE_SIZE_MB = 5
/**
* Default maximum total memory usage for all images in a single read operation (20MB)
* This is a cumulative limit - as each image is processed, its size is added to the total.
* If including another image would exceed this limit, it will be skipped with a notice.
* Example: With a 20MB limit, reading 3 images of 8MB, 7MB, and 10MB would process
* the first two (15MB total) but skip the third to stay under the limit.
*/
export const DEFAULT_MAX_TOTAL_IMAGE_SIZE_MB = 20
/**
* Supported image formats that can be displayed
*/
export const SUPPORTED_IMAGE_FORMATS = [
".png",
".jpg",
".jpeg",
".gif",
".webp",
".svg",
".bmp",
".ico",
".tiff",
".tif",
".avif",
] as const
export const IMAGE_MIME_TYPES: Record<string, string> = {
".png": "image/png",
".jpg": "image/jpeg",
".jpeg": "image/jpeg",
".gif": "image/gif",
".webp": "image/webp",
".svg": "image/svg+xml",
".bmp": "image/bmp",
".ico": "image/x-icon",
".tiff": "image/tiff",
".tif": "image/tiff",
".avif": "image/avif",
}
/**
* Result of image validation
*/
export interface ImageValidationResult {
isValid: boolean
reason?: "size_limit" | "memory_limit" | "unsupported_model"
notice?: string
sizeInMB?: number
}
/**
* Result of image processing
*/
export interface ImageProcessingResult {
dataUrl: string
buffer: Buffer
sizeInKB: number
sizeInMB: number
notice: string
}
/**
* Reads an image file and returns both the data URL and buffer
*/
export async function readImageAsDataUrlWithBuffer(filePath: string): Promise<{ dataUrl: string; buffer: Buffer }> {
const fileBuffer = await fs.readFile(filePath)
const base64 = fileBuffer.toString("base64")
const ext = path.extname(filePath).toLowerCase()
const mimeType = IMAGE_MIME_TYPES[ext] || "image/png"
const dataUrl = `data:${mimeType};base64,${base64}`
return { dataUrl, buffer: fileBuffer }
}
/**
* Checks if a file extension is a supported image format
*/
export function isSupportedImageFormat(extension: string): boolean {
return SUPPORTED_IMAGE_FORMATS.includes(extension.toLowerCase() as (typeof SUPPORTED_IMAGE_FORMATS)[number])
}
/**
* Validates if an image can be processed based on size limits and model support
*/
export async function validateImageForProcessing(
fullPath: string,
supportsImages: boolean,
maxImageFileSize: number,
maxTotalImageSize: number,
currentTotalMemoryUsed: number,
): Promise<ImageValidationResult> {
// Check if model supports images
if (!supportsImages) {
return {
isValid: false,
reason: "unsupported_model",
notice: "Image file detected but current model does not support images. Skipping image processing.",
}
}
const imageStats = await fs.stat(fullPath)
const imageSizeInMB = imageStats.size / (1024 * 1024)
// Check individual file size limit
if (imageStats.size > maxImageFileSize * 1024 * 1024) {
const imageSizeFormatted = prettyBytes(imageStats.size)
return {
isValid: false,
reason: "size_limit",
notice: t("tools:readFile.imageTooLarge", {
size: imageSizeFormatted,
max: maxImageFileSize,
}),
sizeInMB: imageSizeInMB,
}
}
// Check total memory limit
if (currentTotalMemoryUsed + imageSizeInMB > maxTotalImageSize) {
const currentMemoryFormatted = prettyBytes(currentTotalMemoryUsed * 1024 * 1024)
const fileMemoryFormatted = prettyBytes(imageStats.size)
return {
isValid: false,
reason: "memory_limit",
notice: `Image skipped to avoid size limit (${maxTotalImageSize}MB). Current: ${currentMemoryFormatted} + this file: ${fileMemoryFormatted}. Try fewer or smaller images.`,
sizeInMB: imageSizeInMB,
}
}
return {
isValid: true,
sizeInMB: imageSizeInMB,
}
}
/**
* Processes an image file and returns the result
*/
export async function processImageFile(fullPath: string): Promise<ImageProcessingResult> {
const imageStats = await fs.stat(fullPath)
const { dataUrl, buffer } = await readImageAsDataUrlWithBuffer(fullPath)
const imageSizeInKB = Math.round(imageStats.size / 1024)
const imageSizeInMB = imageStats.size / (1024 * 1024)
const noticeText = t("tools:readFile.imageWithSize", { size: imageSizeInKB })
return {
dataUrl,
buffer,
sizeInKB: imageSizeInKB,
sizeInMB: imageSizeInMB,
notice: noticeText,
}
}
/**
* Memory tracker for image processing
*/
export class ImageMemoryTracker {
private totalMemoryUsed: number = 0
/**
* Gets the current total memory used in MB
*/
getTotalMemoryUsed(): number {
return this.totalMemoryUsed
}
/**
* Adds to the total memory used
*/
addMemoryUsage(sizeInMB: number): void {
this.totalMemoryUsed += sizeInMB
}
/**
* Resets the memory tracker
*/
reset(): void {
this.totalMemoryUsed = 0
}
}

View file

@ -14,6 +14,14 @@ import { readLines } from "../../integrations/misc/read-lines"
import { extractTextFromFile, addLineNumbers, getSupportedBinaryFormats } from "../../integrations/misc/extract-text"
import { parseSourceCodeDefinitionsForFile } from "../../services/tree-sitter"
import { parseXml } from "../../utils/xml"
import {
DEFAULT_MAX_IMAGE_FILE_SIZE_MB,
DEFAULT_MAX_TOTAL_IMAGE_SIZE_MB,
isSupportedImageFormat,
validateImageForProcessing,
processImageFile,
ImageMemoryTracker,
} from "./helpers/imageHelpers"
export function getReadFileToolDescription(blockName: string, blockParams: any): string {
// Handle both single path and multiple files via args
@ -66,6 +74,7 @@ interface FileResult {
notice?: string
lineRanges?: LineRange[]
xmlContent?: string // Final XML content for this file
imageDataUrl?: string // Image data URL for image files
feedbackText?: string // User feedback text from approval/denial
feedbackImages?: any[] // User feedback images from approval/denial
}
@ -83,6 +92,10 @@ export async function readFileTool(
const legacyStartLineStr: string | undefined = block.params.start_line
const legacyEndLineStr: string | undefined = block.params.end_line
// Check if the current model supports images at the beginning
const modelInfo = cline.api.getModel().info
const supportsImages = modelInfo.supportsImages ?? false
// Handle partial message first
if (block.partial) {
let filePath = ""
@ -420,6 +433,15 @@ export async function readFileTool(
}
}
// Track total image memory usage across all files
const imageMemoryTracker = new ImageMemoryTracker()
const state = await cline.providerRef.deref()?.getState()
const {
maxReadFileLine = -1,
maxImageFileSize = DEFAULT_MAX_IMAGE_FILE_SIZE_MB,
maxTotalImageSize = DEFAULT_MAX_TOTAL_IMAGE_SIZE_MB,
} = state ?? {}
// Then process only approved files
for (const fileResult of fileResults) {
// Skip files that weren't approved
@ -429,7 +451,6 @@ export async function readFileTool(
const relPath = fileResult.path
const fullPath = path.resolve(cline.cwd, relPath)
const { maxReadFileLine = -1 } = (await cline.providerRef.deref()?.getState()) ?? {}
// Process approved files
try {
@ -440,14 +461,71 @@ export async function readFileTool(
const fileExtension = path.extname(relPath).toLowerCase()
const supportedBinaryFormats = getSupportedBinaryFormats()
if (!supportedBinaryFormats.includes(fileExtension)) {
// Check if it's a supported image format
if (isSupportedImageFormat(fileExtension)) {
try {
// Validate image for processing
const validationResult = await validateImageForProcessing(
fullPath,
supportsImages,
maxImageFileSize,
maxTotalImageSize,
imageMemoryTracker.getTotalMemoryUsed(),
)
if (!validationResult.isValid) {
// Track file read
await cline.fileContextTracker.trackFileContext(relPath, "read_tool" as RecordSource)
updateFileResult(relPath, {
xmlContent: `<file><path>${relPath}</path>\n<notice>${validationResult.notice}</notice>\n</file>`,
})
continue
}
// Process the image
const imageResult = await processImageFile(fullPath)
// Track memory usage for this image
imageMemoryTracker.addMemoryUsage(imageResult.sizeInMB)
// Track file read
await cline.fileContextTracker.trackFileContext(relPath, "read_tool" as RecordSource)
// Store image data URL separately - NOT in XML
updateFileResult(relPath, {
xmlContent: `<file><path>${relPath}</path>\n<notice>${imageResult.notice}</notice>\n</file>`,
imageDataUrl: imageResult.dataUrl,
})
continue
} catch (error) {
const errorMsg = error instanceof Error ? error.message : String(error)
updateFileResult(relPath, {
status: "error",
error: `Error reading image file: ${errorMsg}`,
xmlContent: `<file><path>${relPath}</path><error>Error reading image file: ${errorMsg}</error></file>`,
})
await handleError(
`reading image file ${relPath}`,
error instanceof Error ? error : new Error(errorMsg),
)
continue
}
}
// Check if it's a supported binary format that can be processed
if (supportedBinaryFormats && supportedBinaryFormats.includes(fileExtension)) {
// For supported binary formats (.pdf, .docx, .ipynb), continue to extractTextFromFile
// Fall through to the normal extractTextFromFile processing below
} else {
// Handle unknown binary format
const fileFormat = fileExtension.slice(1) || "bin" // Remove the dot, fallback to "bin"
updateFileResult(relPath, {
notice: "Binary file",
xmlContent: `<file><path>${relPath}</path>\n<notice>Binary file</notice>\n</file>`,
notice: `Binary file format: ${fileFormat}`,
xmlContent: `<file><path>${relPath}</path>\n<binary_file format="${fileFormat}">Binary file - content not displayed</binary_file>\n</file>`,
})
continue
}
// For supported binary formats (.pdf, .docx, .ipynb), continue to extractTextFromFile
}
// Handle range reads (bypass maxReadFileLine)
@ -546,6 +624,11 @@ export async function readFileTool(
const xmlResults = fileResults.filter((result) => result.xmlContent).map((result) => result.xmlContent)
const filesXml = `<files>\n${xmlResults.join("\n")}\n</files>`
// Collect all image data URLs from file results
const fileImageUrls = fileResults
.filter((result) => result.imageDataUrl)
.map((result) => result.imageDataUrl as string)
// Process all feedback in a unified way without branching
let statusMessage = ""
let feedbackImages: any[] = []
@ -573,20 +656,39 @@ export async function readFileTool(
}
}
// Combine all images: feedback images first, then file images
const allImages = [...feedbackImages, ...fileImageUrls]
// Re-check if the model supports images before including them, in case it changed during execution.
const finalModelSupportsImages = cline.api.getModel().info.supportsImages ?? false
const imagesToInclude = finalModelSupportsImages ? allImages : []
// Push the result with appropriate formatting
if (statusMessage) {
const result = formatResponse.toolResult(statusMessage, feedbackImages)
if (statusMessage || imagesToInclude.length > 0) {
// Always use formatResponse.toolResult when we have a status message or images
const result = formatResponse.toolResult(
statusMessage || filesXml,
imagesToInclude.length > 0 ? imagesToInclude : undefined,
)
// Handle different return types from toolResult
if (typeof result === "string") {
pushToolResult(`${result}\n${filesXml}`)
if (statusMessage) {
pushToolResult(`${result}\n${filesXml}`)
} else {
pushToolResult(result)
}
} else {
// For block-based results, we need to convert the filesXml to a text block and append it
const textBlock = { type: "text" as const, text: filesXml }
pushToolResult([...result, textBlock])
// For block-based results, append the files XML as a text block if not already included
if (statusMessage) {
const textBlock = { type: "text" as const, text: filesXml }
pushToolResult([...result, textBlock])
} else {
pushToolResult(result)
}
}
} else {
// No status message, just push the files XML
// No images or status message, just push the files XML
pushToolResult(filesXml)
}
} catch (error) {

View file

@ -1493,6 +1493,8 @@ export class ClineProvider
showRooIgnoredFiles,
language,
maxReadFileLine,
maxImageFileSize,
maxTotalImageSize,
terminalCompressProgressBar,
historyPreviewCollapsed,
cloudUserInfo,
@ -1600,6 +1602,8 @@ export class ClineProvider
language: language ?? formatLanguage(vscode.env.language),
renderContext: this.renderContext,
maxReadFileLine: maxReadFileLine ?? -1,
maxImageFileSize: maxImageFileSize ?? 5,
maxTotalImageSize: maxTotalImageSize ?? 20,
maxConcurrentFileReads: maxConcurrentFileReads ?? 5,
settingsImportedAt: this.settingsImportedAt,
terminalCompressProgressBar: terminalCompressProgressBar ?? true,
@ -1770,6 +1774,8 @@ export class ClineProvider
telemetrySetting: stateValues.telemetrySetting || "unset",
showRooIgnoredFiles: stateValues.showRooIgnoredFiles ?? true,
maxReadFileLine: stateValues.maxReadFileLine ?? -1,
maxImageFileSize: stateValues.maxImageFileSize ?? 5,
maxTotalImageSize: stateValues.maxTotalImageSize ?? 20,
maxConcurrentFileReads: stateValues.maxConcurrentFileReads ?? 5,
historyPreviewCollapsed: stateValues.historyPreviewCollapsed ?? false,
cloudUserInfo,

View file

@ -533,6 +533,8 @@ describe("ClineProvider", () => {
showRooIgnoredFiles: true,
renderContext: "sidebar",
maxReadFileLine: 500,
maxImageFileSize: 5,
maxTotalImageSize: 20,
cloudUserInfo: null,
organizationAllowList: ORGANIZATION_ALLOW_ALL,
autoCondenseContext: true,

View file

@ -1265,6 +1265,14 @@ export const webviewMessageHandler = async (
await updateGlobalState("maxReadFileLine", message.value)
await provider.postStateToWebview()
break
case "maxImageFileSize":
await updateGlobalState("maxImageFileSize", message.value)
await provider.postStateToWebview()
break
case "maxTotalImageSize":
await updateGlobalState("maxTotalImageSize", message.value)
await provider.postStateToWebview()
break
case "maxConcurrentFileReads":
const valueToSave = message.value // Capture the value intended for saving
await updateGlobalState("maxConcurrentFileReads", valueToSave)

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (línies {{start}}-{{end}})",
"definitionsOnly": " (només definicions)",
"maxLines": " (màxim {{max}} línies)"
"maxLines": " (màxim {{max}} línies)",
"imageTooLarge": "El fitxer d'imatge és massa gran ({{size}} MB). La mida màxima permesa és {{max}} MB.",
"imageWithSize": "Fitxer d'imatge ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo sembla estar atrapat en un bucle, intentant la mateixa acció ({{toolName}}) repetidament. Això podria indicar un problema amb la seva estratègia actual. Considera reformular la tasca, proporcionar instruccions més específiques o guiar-lo cap a un enfocament diferent.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (Zeilen {{start}}-{{end}})",
"definitionsOnly": " (nur Definitionen)",
"maxLines": " (maximal {{max}} Zeilen)"
"maxLines": " (maximal {{max}} Zeilen)",
"imageTooLarge": "Die Bilddatei ist zu groß ({{size}} MB). Die maximal erlaubte Größe beträgt {{max}} MB.",
"imageWithSize": "Bilddatei ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo scheint in einer Schleife festzustecken und versucht wiederholt dieselbe Aktion ({{toolName}}). Dies könnte auf ein Problem mit der aktuellen Strategie hindeuten. Überlege dir, die Aufgabe umzuformulieren, genauere Anweisungen zu geben oder Roo zu einem anderen Ansatz zu führen.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (lines {{start}}-{{end}})",
"definitionsOnly": " (definitions only)",
"maxLines": " (max {{max}} lines)"
"maxLines": " (max {{max}} lines)",
"imageTooLarge": "Image file is too large ({{size}} MB). The maximum allowed size is {{max}} MB.",
"imageWithSize": "Image file ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo appears to be stuck in a loop, attempting the same action ({{toolName}}) repeatedly. This might indicate a problem with its current strategy. Consider rephrasing the task, providing more specific instructions, or guiding it towards a different approach.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (líneas {{start}}-{{end}})",
"definitionsOnly": " (solo definiciones)",
"maxLines": " (máximo {{max}} líneas)"
"maxLines": " (máximo {{max}} líneas)",
"imageTooLarge": "El archivo de imagen es demasiado grande ({{size}} MB). El tamaño máximo permitido es {{max}} MB.",
"imageWithSize": "Archivo de imagen ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo parece estar atrapado en un bucle, intentando la misma acción ({{toolName}}) repetidamente. Esto podría indicar un problema con su estrategia actual. Considera reformular la tarea, proporcionar instrucciones más específicas o guiarlo hacia un enfoque diferente.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (lignes {{start}}-{{end}})",
"definitionsOnly": " (définitions uniquement)",
"maxLines": " (max {{max}} lignes)"
"maxLines": " (max {{max}} lignes)",
"imageTooLarge": "Le fichier image est trop volumineux ({{size}} MB). La taille maximale autorisée est {{max}} MB.",
"imageWithSize": "Fichier image ({{size}} Ko)"
},
"toolRepetitionLimitReached": "Roo semble être bloqué dans une boucle, tentant la même action ({{toolName}}) de façon répétée. Cela pourrait indiquer un problème avec sa stratégie actuelle. Envisage de reformuler la tâche, de fournir des instructions plus spécifiques ou de le guider vers une approche différente.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (पंक्तियाँ {{start}}-{{end}})",
"definitionsOnly": " (केवल परिभाषाएँ)",
"maxLines": " (अधिकतम {{max}} पंक्तियाँ)"
"maxLines": " (अधिकतम {{max}} पंक्तियाँ)",
"imageTooLarge": "छवि फ़ाइल बहुत बड़ी है ({{size}} MB)। अधिकतम अनुमतित आकार {{max}} MB है।",
"imageWithSize": "छवि फ़ाइल ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo एक लूप में फंसा हुआ लगता है, बार-बार एक ही क्रिया ({{toolName}}) को दोहरा रहा है। यह उसकी वर्तमान रणनीति में किसी समस्या का संकेत हो सकता है। कार्य को पुनः परिभाषित करने, अधिक विशिष्ट निर्देश देने, या उसे एक अलग दृष्टिकोण की ओर मार्गदर्शित करने पर विचार करें।",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (baris {{start}}-{{end}})",
"definitionsOnly": " (hanya definisi)",
"maxLines": " (maks {{max}} baris)"
"maxLines": " (maks {{max}} baris)",
"imageTooLarge": "File gambar terlalu besar ({{size}} MB). Ukuran maksimum yang diizinkan adalah {{max}} MB.",
"imageWithSize": "File gambar ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo tampaknya terjebak dalam loop, mencoba aksi yang sama ({{toolName}}) berulang kali. Ini mungkin menunjukkan masalah dengan strategi saat ini. Pertimbangkan untuk mengubah frasa tugas, memberikan instruksi yang lebih spesifik, atau mengarahkannya ke pendekatan yang berbeda.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (righe {{start}}-{{end}})",
"definitionsOnly": " (solo definizioni)",
"maxLines": " (max {{max}} righe)"
"maxLines": " (max {{max}} righe)",
"imageTooLarge": "Il file immagine è troppo grande ({{size}} MB). La dimensione massima consentita è {{max}} MB.",
"imageWithSize": "File immagine ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo sembra essere bloccato in un ciclo, tentando ripetutamente la stessa azione ({{toolName}}). Questo potrebbe indicare un problema con la sua strategia attuale. Considera di riformulare l'attività, fornire istruzioni più specifiche o guidarlo verso un approccio diverso.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " ({{start}}-{{end}}行目)",
"definitionsOnly": " (定義のみ)",
"maxLines": " (最大{{max}}行)"
"maxLines": " (最大{{max}}行)",
"imageTooLarge": "画像ファイルが大きすぎます({{size}} MB。最大許可サイズは {{max}} MB です。",
"imageWithSize": "画像ファイル({{size}} KB"
},
"toolRepetitionLimitReached": "Rooが同じ操作{{toolName}})を繰り返し試みるループに陥っているようです。これは現在の方法に問題がある可能性を示しています。タスクの言い換え、より具体的な指示の提供、または別のアプローチへの誘導を検討してください。",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " ({{start}}-{{end}}행)",
"definitionsOnly": " (정의만)",
"maxLines": " (최대 {{max}}행)"
"maxLines": " (최대 {{max}}행)",
"imageTooLarge": "이미지 파일이 너무 큽니다 ({{size}} MB). 최대 허용 크기는 {{max}} MB입니다.",
"imageWithSize": "이미지 파일 ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo가 같은 동작({{toolName}})을 반복적으로 시도하면서 루프에 갇힌 것 같습니다. 이는 현재 전략에 문제가 있을 수 있음을 나타냅니다. 작업을 다시 표현하거나, 더 구체적인 지침을 제공하거나, 다른 접근 방식으로 안내해 보세요.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (regels {{start}}-{{end}})",
"definitionsOnly": " (alleen definities)",
"maxLines": " (max {{max}} regels)"
"maxLines": " (max {{max}} regels)",
"imageTooLarge": "Afbeeldingsbestand is te groot ({{size}} MB). De maximaal toegestane grootte is {{max}} MB.",
"imageWithSize": "Afbeeldingsbestand ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo lijkt vast te zitten in een lus, waarbij hij herhaaldelijk dezelfde actie ({{toolName}}) probeert. Dit kan duiden op een probleem met de huidige strategie. Overweeg de taak te herformuleren, specifiekere instructies te geven of Roo naar een andere aanpak te leiden.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (linie {{start}}-{{end}})",
"definitionsOnly": " (tylko definicje)",
"maxLines": " (maks. {{max}} linii)"
"maxLines": " (maks. {{max}} linii)",
"imageTooLarge": "Plik obrazu jest zbyt duży ({{size}} MB). Maksymalny dozwolony rozmiar to {{max}} MB.",
"imageWithSize": "Plik obrazu ({{size}} KB)"
},
"toolRepetitionLimitReached": "Wygląda na to, że Roo utknął w pętli, wielokrotnie próbując wykonać tę samą akcję ({{toolName}}). Może to wskazywać na problem z jego obecną strategią. Rozważ przeformułowanie zadania, podanie bardziej szczegółowych instrukcji lub nakierowanie go na inne podejście.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (linhas {{start}}-{{end}})",
"definitionsOnly": " (apenas definições)",
"maxLines": " (máx. {{max}} linhas)"
"maxLines": " (máx. {{max}} linhas)",
"imageTooLarge": "Arquivo de imagem é muito grande ({{size}} MB). O tamanho máximo permitido é {{max}} MB.",
"imageWithSize": "Arquivo de imagem ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo parece estar preso em um loop, tentando a mesma ação ({{toolName}}) repetidamente. Isso pode indicar um problema com sua estratégia atual. Considere reformular a tarefa, fornecer instruções mais específicas ou guiá-lo para uma abordagem diferente.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (строки {{start}}-{{end}})",
"definitionsOnly": " (только определения)",
"maxLines": " (макс. {{max}} строк)"
"maxLines": " (макс. {{max}} строк)",
"imageTooLarge": "Файл изображения слишком большой ({{size}} МБ). Максимально допустимый размер {{max}} МБ.",
"imageWithSize": "Файл изображения ({{size}} КБ)"
},
"toolRepetitionLimitReached": "Похоже, что Roo застрял в цикле, многократно пытаясь выполнить одно и то же действие ({{toolName}}). Это может указывать на проблему с его текущей стратегией. Попробуйте переформулировать задачу, предоставить более конкретные инструкции или направить его к другому подходу.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (satır {{start}}-{{end}})",
"definitionsOnly": " (sadece tanımlar)",
"maxLines": " (maks. {{max}} satır)"
"maxLines": " (maks. {{max}} satır)",
"imageTooLarge": "Görüntü dosyası çok büyük ({{size}} MB). İzin verilen maksimum boyut {{max}} MB.",
"imageWithSize": "Görüntü dosyası ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo bir döngüye takılmış gibi görünüyor, aynı eylemi ({{toolName}}) tekrar tekrar deniyor. Bu, mevcut stratejisinde bir sorun olduğunu gösterebilir. Görevi yeniden ifade etmeyi, daha spesifik talimatlar vermeyi veya onu farklı bir yaklaşıma yönlendirmeyi düşünün.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (dòng {{start}}-{{end}})",
"definitionsOnly": " (chỉ định nghĩa)",
"maxLines": " (tối đa {{max}} dòng)"
"maxLines": " (tối đa {{max}} dòng)",
"imageTooLarge": "Tệp hình ảnh quá lớn ({{size}} MB). Kích thước tối đa cho phép là {{max}} MB.",
"imageWithSize": "Tệp hình ảnh ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo dường như đang bị mắc kẹt trong một vòng lặp, liên tục cố gắng thực hiện cùng một hành động ({{toolName}}). Điều này có thể cho thấy vấn đề với chiến lược hiện tại. Hãy cân nhắc việc diễn đạt lại nhiệm vụ, cung cấp hướng dẫn cụ thể hơn, hoặc hướng Roo theo một cách tiếp cận khác.",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (第 {{start}}-{{end}} 行)",
"definitionsOnly": " (仅定义)",
"maxLines": " (最多 {{max}} 行)"
"maxLines": " (最多 {{max}} 行)",
"imageTooLarge": "图片文件过大 ({{size}} MB)。允许的最大大小为 {{max}} MB。",
"imageWithSize": "图片文件 ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo 似乎陷入循环,反复尝试同一操作 ({{toolName}})。这可能表明当前策略存在问题。请考虑重新描述任务、提供更具体的指示或引导其尝试不同的方法。",
"codebaseSearch": {

View file

@ -2,7 +2,9 @@
"readFile": {
"linesRange": " (第 {{start}}-{{end}} 行)",
"definitionsOnly": " (僅定義)",
"maxLines": " (最多 {{max}} 行)"
"maxLines": " (最多 {{max}} 行)",
"imageTooLarge": "圖片檔案過大 ({{size}} MB)。允許的最大大小為 {{max}} MB。",
"imageWithSize": "圖片檔案 ({{size}} KB)"
},
"toolRepetitionLimitReached": "Roo 似乎陷入循環,反覆嘗試同一操作 ({{toolName}})。這可能表明目前策略存在問題。請考慮重新描述工作、提供更具體的指示或引導其嘗試不同的方法。",
"codebaseSearch": {

View file

@ -284,6 +284,8 @@ export type ExtensionState = Pick<
maxWorkspaceFiles: number // Maximum number of files to include in current working directory details (0-500)
showRooIgnoredFiles: boolean // Whether to show .rooignore'd files in listings
maxReadFileLine: number // Maximum number of lines to read from a file before truncating
maxImageFileSize: number // Maximum size of image files to process in MB
maxTotalImageSize: number // Maximum total size for all images in a single read operation in MB
experiments: Experiments // Map of experiment IDs to their enabled state

View file

@ -162,6 +162,8 @@ export interface WebviewMessage {
| "remoteBrowserEnabled"
| "language"
| "maxReadFileLine"
| "maxImageFileSize"
| "maxTotalImageSize"
| "maxConcurrentFileReads"
| "includeDiagnosticMessages"
| "maxDiagnosticMessages"

View file

@ -20,6 +20,8 @@ type ContextManagementSettingsProps = HTMLAttributes<HTMLDivElement> & {
maxWorkspaceFiles: number
showRooIgnoredFiles?: boolean
maxReadFileLine?: number
maxImageFileSize?: number
maxTotalImageSize?: number
maxConcurrentFileReads?: number
profileThresholds?: Record<string, number>
includeDiagnosticMessages?: boolean
@ -32,6 +34,8 @@ type ContextManagementSettingsProps = HTMLAttributes<HTMLDivElement> & {
| "maxWorkspaceFiles"
| "showRooIgnoredFiles"
| "maxReadFileLine"
| "maxImageFileSize"
| "maxTotalImageSize"
| "maxConcurrentFileReads"
| "profileThresholds"
| "includeDiagnosticMessages"
@ -49,6 +53,8 @@ export const ContextManagementSettings = ({
showRooIgnoredFiles,
setCachedStateField,
maxReadFileLine,
maxImageFileSize,
maxTotalImageSize,
maxConcurrentFileReads,
profileThresholds = {},
includeDiagnosticMessages,
@ -206,6 +212,62 @@ export const ContextManagementSettings = ({
</div>
</div>
<div>
<div className="flex flex-col gap-2">
<span className="font-medium">{t("settings:contextManagement.maxImageFileSize.label")}</span>
<div className="flex items-center gap-4">
<Input
type="number"
pattern="[0-9]*"
className="w-24 bg-vscode-input-background text-vscode-input-foreground border border-vscode-input-border px-2 py-1 rounded text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={maxImageFileSize ?? 5}
min={1}
max={100}
onChange={(e) => {
const newValue = parseInt(e.target.value, 10)
if (!isNaN(newValue) && newValue >= 1 && newValue <= 100) {
setCachedStateField("maxImageFileSize", newValue)
}
}}
onClick={(e) => e.currentTarget.select()}
data-testid="max-image-file-size-input"
/>
<span>{t("settings:contextManagement.maxImageFileSize.mb")}</span>
</div>
</div>
<div className="text-vscode-descriptionForeground text-sm mt-2">
{t("settings:contextManagement.maxImageFileSize.description")}
</div>
</div>
<div>
<div className="flex flex-col gap-2">
<span className="font-medium">{t("settings:contextManagement.maxTotalImageSize.label")}</span>
<div className="flex items-center gap-4">
<Input
type="number"
pattern="[0-9]*"
className="w-24 bg-vscode-input-background text-vscode-input-foreground border border-vscode-input-border px-2 py-1 rounded text-right [appearance:textfield] [&::-webkit-outer-spin-button]:appearance-none [&::-webkit-inner-spin-button]:appearance-none"
value={maxTotalImageSize ?? 20}
min={1}
max={500}
onChange={(e) => {
const newValue = parseInt(e.target.value, 10)
if (!isNaN(newValue) && newValue >= 1 && newValue <= 500) {
setCachedStateField("maxTotalImageSize", newValue)
}
}}
onClick={(e) => e.currentTarget.select()}
data-testid="max-total-image-size-input"
/>
<span>{t("settings:contextManagement.maxTotalImageSize.mb")}</span>
</div>
</div>
<div className="text-vscode-descriptionForeground text-sm mt-2">
{t("settings:contextManagement.maxTotalImageSize.description")}
</div>
</div>
<div>
<VSCodeCheckbox
checked={includeDiagnosticMessages}

View file

@ -168,6 +168,8 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
showRooIgnoredFiles,
remoteBrowserEnabled,
maxReadFileLine,
maxImageFileSize,
maxTotalImageSize,
terminalCompressProgressBar,
maxConcurrentFileReads,
condensingApiConfigId,
@ -321,6 +323,8 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
vscode.postMessage({ type: "maxWorkspaceFiles", value: maxWorkspaceFiles ?? 200 })
vscode.postMessage({ type: "showRooIgnoredFiles", bool: showRooIgnoredFiles })
vscode.postMessage({ type: "maxReadFileLine", value: maxReadFileLine ?? -1 })
vscode.postMessage({ type: "maxImageFileSize", value: maxImageFileSize ?? 5 })
vscode.postMessage({ type: "maxTotalImageSize", value: maxTotalImageSize ?? 20 })
vscode.postMessage({ type: "maxConcurrentFileReads", value: cachedState.maxConcurrentFileReads ?? 5 })
vscode.postMessage({ type: "includeDiagnosticMessages", bool: includeDiagnosticMessages })
vscode.postMessage({ type: "maxDiagnosticMessages", value: maxDiagnosticMessages ?? 50 })
@ -667,6 +671,8 @@ const SettingsView = forwardRef<SettingsViewRef, SettingsViewProps>(({ onDone, t
maxWorkspaceFiles={maxWorkspaceFiles ?? 200}
showRooIgnoredFiles={showRooIgnoredFiles}
maxReadFileLine={maxReadFileLine}
maxImageFileSize={maxImageFileSize}
maxTotalImageSize={maxTotalImageSize}
maxConcurrentFileReads={maxConcurrentFileReads}
profileThresholds={profileThresholds}
includeDiagnosticMessages={includeDiagnosticMessages}

View file

@ -121,6 +121,10 @@ export interface ExtensionStateContextType extends ExtensionState {
setAwsUsePromptCache: (value: boolean) => void
maxReadFileLine: number
setMaxReadFileLine: (value: number) => void
maxImageFileSize: number
setMaxImageFileSize: (value: number) => void
maxTotalImageSize: number
setMaxTotalImageSize: (value: number) => void
machineId?: string
pinnedApiConfigs?: Record<string, boolean>
setPinnedApiConfigs: (value: Record<string, boolean>) => void
@ -209,6 +213,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
showRooIgnoredFiles: true, // Default to showing .rooignore'd files with lock symbol (current behavior).
renderContext: "sidebar",
maxReadFileLine: -1, // Default max read file line limit
maxImageFileSize: 5, // Default max image file size in MB
maxTotalImageSize: 20, // Default max total image size in MB
pinnedApiConfigs: {}, // Empty object for pinned API configs
terminalZshOhMy: false, // Default Oh My Zsh integration setting
maxConcurrentFileReads: 5, // Default concurrent file reads
@ -455,6 +461,8 @@ export const ExtensionStateContextProvider: React.FC<{ children: React.ReactNode
setRemoteBrowserEnabled: (value) => setState((prevState) => ({ ...prevState, remoteBrowserEnabled: value })),
setAwsUsePromptCache: (value) => setState((prevState) => ({ ...prevState, awsUsePromptCache: value })),
setMaxReadFileLine: (value) => setState((prevState) => ({ ...prevState, maxReadFileLine: value })),
setMaxImageFileSize: (value) => setState((prevState) => ({ ...prevState, maxImageFileSize: value })),
setMaxTotalImageSize: (value) => setState((prevState) => ({ ...prevState, maxTotalImageSize: value })),
setPinnedApiConfigs: (value) => setState((prevState) => ({ ...prevState, pinnedApiConfigs: value })),
setTerminalCompressProgressBar: (value) =>
setState((prevState) => ({ ...prevState, terminalCompressProgressBar: value })),

View file

@ -209,6 +209,8 @@ describe("mergeExtensionState", () => {
sharingEnabled: false,
profileThresholds: {},
hasOpenedModeSelector: false, // Add the new required property
maxImageFileSize: 5,
maxTotalImageSize: 20,
}
const prevState: ExtensionState = {

View file

@ -537,6 +537,16 @@
"profileDescription": "Llindar personalitzat només per a aquest perfil (substitueix el per defecte global)",
"inheritDescription": "Aquest perfil hereta el llindar per defecte global ({{threshold}}%)",
"usesGlobal": "(utilitza global {{threshold}}%)"
},
"maxImageFileSize": {
"label": "Mida màxima d'arxiu d'imatge",
"mb": "MB",
"description": "Mida màxima (en MB) per a arxius d'imatge que poden ser processats per l'eina de lectura d'arxius."
},
"maxTotalImageSize": {
"label": "Mida total màxima d'imatges",
"mb": "MB",
"description": "Límit de mida acumulativa màxima (en MB) per a totes les imatges processades en una sola operació read_file. Quan es llegeixen múltiples imatges, la mida de cada imatge s'afegeix al total. Si incloure una altra imatge excediria aquest límit, serà omesa."
}
},
"terminal": {

View file

@ -537,6 +537,16 @@
"profileDescription": "Benutzerdefinierter Schwellenwert nur für dieses Profil (überschreibt globalen Standard)",
"inheritDescription": "Dieses Profil erbt den globalen Standard-Schwellenwert ({{threshold}}%)",
"usesGlobal": "(verwendet global {{threshold}}%)"
},
"maxImageFileSize": {
"label": "Maximale Bilddateigröße",
"mb": "MB",
"description": "Maximale Größe (in MB) für Bilddateien, die vom read file Tool verarbeitet werden können."
},
"maxTotalImageSize": {
"label": "Maximale Gesamtbildgröße",
"mb": "MB",
"description": "Maximales kumulatives Größenlimit (in MB) für alle Bilder, die in einer einzelnen read_file-Operation verarbeitet werden. Beim Lesen mehrerer Bilder wird die Größe jedes Bildes zur Gesamtsumme addiert. Wenn das Einbeziehen eines weiteren Bildes dieses Limit überschreiten würde, wird es übersprungen."
}
},
"terminal": {

View file

@ -512,6 +512,16 @@
"lines": "lines",
"always_full_read": "Always read entire file"
},
"maxImageFileSize": {
"label": "Max image file size",
"mb": "MB",
"description": "Maximum size (in MB) for image files that can be processed by the read file tool."
},
"maxTotalImageSize": {
"label": "Max total image size",
"mb": "MB",
"description": "Maximum cumulative size limit (in MB) for all images processed in a single read_file operation. When reading multiple images, each image's size is added to the total. If including another image would exceed this limit, it will be skipped."
},
"diagnostics": {
"includeMessages": {
"label": "Automatically include diagnostics in context",

View file

@ -513,6 +513,16 @@
"label": "Límite de lecturas simultáneas",
"description": "Número máximo de archivos que la herramienta 'read_file' puede procesar simultáneamente. Valores más altos pueden acelerar la lectura de múltiples archivos pequeños pero aumentan el uso de memoria."
},
"maxImageFileSize": {
"label": "Tamaño máximo de archivo de imagen",
"mb": "MB",
"description": "Tamaño máximo (en MB) para archivos de imagen que pueden ser procesados por la herramienta de lectura de archivos."
},
"maxTotalImageSize": {
"label": "Tamaño total máximo de imágenes",
"mb": "MB",
"description": "Límite de tamaño acumulativo máximo (en MB) para todas las imágenes procesadas en una sola operación read_file. Al leer múltiples imágenes, el tamaño de cada imagen se suma al total. Si incluir otra imagen excedería este límite, será omitida."
},
"diagnostics": {
"includeMessages": {
"label": "Incluir automáticamente diagnósticos en el contexto",

View file

@ -513,6 +513,16 @@
"label": "Limite de lectures simultanées",
"description": "Nombre maximum de fichiers que l'outil 'read_file' peut traiter simultanément. Des valeurs plus élevées peuvent accélérer la lecture de plusieurs petits fichiers mais augmentent l'utilisation de la mémoire."
},
"maxImageFileSize": {
"label": "Taille maximale des fichiers d'image",
"mb": "MB",
"description": "Taille maximale (en MB) pour les fichiers d'image qui peuvent être traités par l'outil de lecture de fichier."
},
"maxTotalImageSize": {
"label": "Taille totale maximale des images",
"mb": "MB",
"description": "Limite de taille cumulée maximale (en MB) pour toutes les images traitées dans une seule opération read_file. Lors de la lecture de plusieurs images, la taille de chaque image est ajoutée au total. Si l'inclusion d'une autre image dépasserait cette limite, elle sera ignorée."
},
"diagnostics": {
"includeMessages": {
"label": "Inclure automatiquement les diagnostics dans le contexte",

View file

@ -538,6 +538,16 @@
"profileDescription": "केवल इस प्रोफ़ाइल के लिए कस्टम सीमा (वैश्विक डिफ़ॉल्ट को ओवरराइड करता है)",
"inheritDescription": "यह प्रोफ़ाइल वैश्विक डिफ़ॉल्ट सीमा को इनहेरिट करता है ({{threshold}}%)",
"usesGlobal": "(वैश्विक {{threshold}}% का उपयोग करता है)"
},
"maxImageFileSize": {
"label": "अधिकतम छवि फ़ाइल आकार",
"mb": "MB",
"description": "छवि फ़ाइलों के लिए अधिकतम आकार (MB में) जो read file tool द्वारा प्रसंस्कृत किया जा सकता है।"
},
"maxTotalImageSize": {
"label": "अधिकतम कुल छवि आकार",
"mb": "MB",
"description": "एकल read_file ऑपरेशन में संसाधित सभी छवियों के लिए अधिकतम संचयी आकार सीमा (MB में)। कई छवियों को पढ़ते समय, प्रत्येक छवि का आकार कुल में जोड़ा जाता है। यदि किसी अन्य छवि को शामिल करने से यह सीमा पार हो जाएगी, तो उसे छोड़ दिया जाएगा।"
}
},
"terminal": {

View file

@ -542,6 +542,16 @@
"description": "Roo membaca sejumlah baris ini ketika model menghilangkan nilai start/end. Jika angka ini kurang dari total file, Roo menghasilkan indeks nomor baris dari definisi kode. Kasus khusus: -1 menginstruksikan Roo untuk membaca seluruh file (tanpa indexing), dan 0 menginstruksikannya untuk tidak membaca baris dan hanya menyediakan indeks baris untuk konteks minimal. Nilai yang lebih rendah meminimalkan penggunaan konteks awal, memungkinkan pembacaan rentang baris yang tepat selanjutnya. Permintaan start/end eksplisit tidak dibatasi oleh pengaturan ini.",
"lines": "baris",
"always_full_read": "Selalu baca seluruh file"
},
"maxImageFileSize": {
"label": "Ukuran file gambar maksimum",
"mb": "MB",
"description": "Ukuran maksimum (dalam MB) untuk file gambar yang dapat diproses oleh alat baca file."
},
"maxTotalImageSize": {
"label": "Ukuran total gambar maksimum",
"mb": "MB",
"description": "Batas ukuran kumulatif maksimum (dalam MB) untuk semua gambar yang diproses dalam satu operasi read_file. Saat membaca beberapa gambar, ukuran setiap gambar ditambahkan ke total. Jika menyertakan gambar lain akan melebihi batas ini, gambar tersebut akan dilewati."
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "Soglia personalizzata solo per questo profilo (sovrascrive il predefinito globale)",
"inheritDescription": "Questo profilo eredita la soglia predefinita globale ({{threshold}}%)",
"usesGlobal": "(usa globale {{threshold}}%)"
},
"maxImageFileSize": {
"label": "Dimensione massima file immagine",
"mb": "MB",
"description": "Dimensione massima (in MB) per i file immagine che possono essere elaborati dallo strumento di lettura file."
},
"maxTotalImageSize": {
"label": "Dimensione totale massima immagini",
"mb": "MB",
"description": "Limite di dimensione cumulativa massima (in MB) per tutte le immagini elaborate in una singola operazione read_file. Durante la lettura di più immagini, la dimensione di ogni immagine viene aggiunta al totale. Se l'inclusione di un'altra immagine supererebbe questo limite, verrà saltata."
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "このプロファイルのみのカスタムしきい値(グローバルデフォルトを上書き)",
"inheritDescription": "このプロファイルはグローバルデフォルトしきい値を継承します({{threshold}}%",
"usesGlobal": "(グローバル {{threshold}}% を使用)"
},
"maxImageFileSize": {
"label": "最大画像ファイルサイズ",
"mb": "MB",
"description": "read fileツールで処理できる画像ファイルの最大サイズMB単位。"
},
"maxTotalImageSize": {
"label": "最大合計画像サイズ",
"mb": "MB",
"description": "単一のread_file操作で処理されるすべての画像の累積サイズ制限MB単位。複数の画像を読み取る際、各画像のサイズが合計に加算されます。別の画像を含めるとこの制限を超える場合、その画像はスキップされます。"
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "이 프로필만을 위한 사용자 정의 임계값 (글로벌 기본값 재정의)",
"inheritDescription": "이 프로필은 글로벌 기본 임계값을 상속합니다 ({{threshold}}%)",
"usesGlobal": "(글로벌 {{threshold}}% 사용)"
},
"maxImageFileSize": {
"label": "최대 이미지 파일 크기",
"mb": "MB",
"description": "read file 도구로 처리할 수 있는 이미지 파일의 최대 크기(MB 단위)입니다."
},
"maxTotalImageSize": {
"label": "최대 총 이미지 크기",
"mb": "MB",
"description": "단일 read_file 작업에서 처리되는 모든 이미지의 최대 누적 크기 제한(MB 단위)입니다. 여러 이미지를 읽을 때 각 이미지의 크기가 총계에 추가됩니다. 다른 이미지를 포함하면 이 제한을 초과하는 경우 해당 이미지는 건너뜁니다."
}
},
"terminal": {

View file

@ -513,6 +513,16 @@
"label": "Limiet gelijktijdige bestandslezingen",
"description": "Maximum aantal bestanden dat de 'read_file' tool tegelijkertijd kan verwerken. Hogere waarden kunnen het lezen van meerdere kleine bestanden versnellen maar verhogen het geheugengebruik."
},
"maxImageFileSize": {
"label": "Maximum afbeeldingsbestandsgrootte",
"mb": "MB",
"description": "Maximale grootte (in MB) voor afbeeldingsbestanden die kunnen worden verwerkt door de read file tool."
},
"maxTotalImageSize": {
"label": "Maximale totale afbeeldingsgrootte",
"mb": "MB",
"description": "Maximale cumulatieve groottelimiet (in MB) voor alle afbeeldingen die in één read_file-bewerking worden verwerkt. Bij het lezen van meerdere afbeeldingen wordt de grootte van elke afbeelding bij het totaal opgeteld. Als het toevoegen van een andere afbeelding deze limiet zou overschrijden, wordt deze overgeslagen."
},
"diagnostics": {
"includeMessages": {
"label": "Automatisch diagnostiek opnemen in context",

View file

@ -538,6 +538,16 @@
"profileDescription": "Niestandardowy próg tylko dla tego profilu (zastępuje globalny domyślny)",
"inheritDescription": "Ten profil dziedziczy globalny domyślny próg ({{threshold}}%)",
"usesGlobal": "(używa globalnego {{threshold}}%)"
},
"maxImageFileSize": {
"label": "Maksymalny rozmiar pliku obrazu",
"mb": "MB",
"description": "Maksymalny rozmiar (w MB) plików obrazów, które mogą być przetwarzane przez narzędzie do czytania plików."
},
"maxTotalImageSize": {
"label": "Maksymalny całkowity rozmiar obrazów",
"mb": "MB",
"description": "Maksymalny skumulowany limit rozmiaru (w MB) dla wszystkich obrazów przetwarzanych w jednej operacji read_file. Podczas odczytu wielu obrazów rozmiar każdego obrazu jest dodawany do sumy. Jeśli dołączenie kolejnego obrazu przekroczyłoby ten limit, zostanie on pominięty."
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "Limite personalizado apenas para este perfil (substitui o padrão global)",
"inheritDescription": "Este perfil herda o limite padrão global ({{threshold}}%)",
"usesGlobal": "(usa global {{threshold}}%)"
},
"maxImageFileSize": {
"label": "Tamanho máximo do arquivo de imagem",
"mb": "MB",
"description": "Tamanho máximo (em MB) para arquivos de imagem que podem ser processados pela ferramenta de leitura de arquivos."
},
"maxTotalImageSize": {
"label": "Tamanho total máximo da imagem",
"mb": "MB",
"description": "Limite máximo de tamanho cumulativo (em MB) para todas as imagens processadas em uma única operação read_file. Ao ler várias imagens, o tamanho de cada imagem é adicionado ao total. Se incluir outra imagem exceder esse limite, ela será ignorada."
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "Пользовательский порог только для этого профиля (переопределяет глобальный по умолчанию)",
"inheritDescription": "Этот профиль наследует глобальный порог по умолчанию ({{threshold}}%)",
"usesGlobal": "(использует глобальный {{threshold}}%)"
},
"maxImageFileSize": {
"label": "Максимальный размер файла изображения",
"mb": "MB",
"description": "Максимальный размер (в МБ) для файлов изображений, которые могут быть обработаны инструментом чтения файлов."
},
"maxTotalImageSize": {
"label": "Максимальный общий размер изображений",
"mb": "МБ",
"description": "Максимальный совокупный лимит размера (в МБ) для всех изображений, обрабатываемых в одной операции read_file. При чтении нескольких изображений размер каждого изображения добавляется к общему. Если включение другого изображения превысит этот лимит, оно будет пропущено."
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "Sadece bu profil için özel eşik (küresel varsayılanı geçersiz kılar)",
"inheritDescription": "Bu profil küresel varsayılan eşiği miras alır ({{threshold}}%)",
"usesGlobal": "(küresel {{threshold}}% kullanır)"
},
"maxImageFileSize": {
"label": "Maksimum görüntü dosyası boyutu",
"mb": "MB",
"description": "Dosya okuma aracı tarafından işlenebilecek görüntü dosyaları için maksimum boyut (MB cinsinden)."
},
"maxTotalImageSize": {
"label": "Maksimum toplam görüntü boyutu",
"mb": "MB",
"description": "Tek bir read_file işleminde işlenen tüm görüntüler için maksimum kümülatif boyut sınırı (MB cinsinden). Birden çok görüntü okurken, her görüntünün boyutu toplama eklenir. Başka bir görüntü eklemek bu sınırı aşacaksa, atlanacaktır."
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "Ngưỡng tùy chỉnh chỉ cho hồ sơ này (ghi đè mặc định toàn cục)",
"inheritDescription": "Hồ sơ này kế thừa ngưỡng mặc định toàn cục ({{threshold}}%)",
"usesGlobal": "(sử dụng toàn cục {{threshold}}%)"
},
"maxImageFileSize": {
"label": "Kích thước tối đa của tệp hình ảnh",
"mb": "MB",
"description": "Kích thước tối đa (tính bằng MB) cho các tệp hình ảnh có thể được xử lý bởi công cụ đọc tệp."
},
"maxTotalImageSize": {
"label": "Kích thước tổng tối đa của hình ảnh",
"mb": "MB",
"description": "Giới hạn kích thước tích lũy tối đa (tính bằng MB) cho tất cả hình ảnh được xử lý trong một thao tác read_file duy nhất. Khi đọc nhiều hình ảnh, kích thước của mỗi hình ảnh được cộng vào tổng. Nếu việc thêm một hình ảnh khác sẽ vượt quá giới hạn này, nó sẽ bị bỏ qua."
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "仅此配置文件的自定义阈值(覆盖全局默认)",
"inheritDescription": "此配置文件继承全局默认阈值({{threshold}}%",
"usesGlobal": "(使用全局 {{threshold}}%"
},
"maxImageFileSize": {
"label": "最大图像文件大小",
"mb": "MB",
"description": "read file工具可以处理的图像文件的最大大小以MB为单位。"
},
"maxTotalImageSize": {
"label": "图片总大小上限",
"mb": "MB",
"description": "单次 read_file 操作中处理的所有图片的最大累计大小限制MB。读取多张图片时每张图片的大小会累加到总大小中。如果包含另一张图片会超过此限制则会跳过该图片。"
}
},
"terminal": {

View file

@ -538,6 +538,16 @@
"profileDescription": "僅此檔案的自訂閾值(覆蓋全域預設)",
"inheritDescription": "此檔案繼承全域預設閾值({{threshold}}%",
"usesGlobal": "(使用全域 {{threshold}}%"
},
"maxImageFileSize": {
"label": "最大圖像檔案大小",
"mb": "MB",
"description": "read file工具可以處理的圖像檔案的最大大小以MB為單位。"
},
"maxTotalImageSize": {
"label": "圖片總大小上限",
"mb": "MB",
"description": "單次 read_file 操作中處理的所有圖片的最大累計大小限制MB。讀取多張圖片時每張圖片的大小會累加到總大小中。如果包含另一張圖片會超過此限制則會跳過該圖片。"
}
},
"terminal": {