From 6c7ecd8b75d044d0c7c5724218c03960fcf1095b Mon Sep 17 00:00:00 2001 From: Ayush7614 Date: Sun, 12 Jul 2026 20:03:05 +0530 Subject: [PATCH 1/6] feat(chrome): image budget controls for screenshot quality + per-turn capture (issue #311) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an 'Image budget' section under Settings → Multimodal with three persisted controls applied to screenshot capture and vision request formatting: - imageDetail (high/low/auto): sent as the OpenAI-style image_url 'detail' field; 'auto' (default) is a no-op so providers keep their default. - maxScreenshotsPerTurn (0-5, 0=unlimited): caps auto-screenshots per turn via a per-turn counter reset at the start of each turn. - maxImageDimension (512-2048px): caps every vision image's largest side and the token budget derived from it. Defaults preserve pre-#311 behavior: auto detail, unlimited screenshots, and a 1568px cap that maps to the legacy IMAGE_BUDGET byte-for-byte (near-square viewports still downscale to ~1109px). Budget is applied to all vision capture paths (auto-screenshot, /screenshot, full_page_screenshot, verify_form, crop, user attachments). UI shows a cost/latency explanation. --- src/chrome/src/agent/agent.js | 109 ++++++++++++++++++++++++++------ src/chrome/src/background.js | 20 ++++++ src/chrome/src/ui/locales/ar.js | 13 ++++ src/chrome/src/ui/locales/en.js | 17 +++++ src/chrome/src/ui/locales/es.js | 13 ++++ src/chrome/src/ui/locales/fr.js | 13 ++++ src/chrome/src/ui/locales/he.js | 13 ++++ src/chrome/src/ui/locales/id.js | 13 ++++ src/chrome/src/ui/locales/ja.js | 13 ++++ src/chrome/src/ui/locales/ko.js | 13 ++++ src/chrome/src/ui/locales/ms.js | 13 ++++ src/chrome/src/ui/locales/pl.js | 13 ++++ src/chrome/src/ui/locales/ru.js | 13 ++++ src/chrome/src/ui/locales/th.js | 13 ++++ src/chrome/src/ui/locales/tl.js | 13 ++++ src/chrome/src/ui/locales/tr.js | 13 ++++ src/chrome/src/ui/locales/uk.js | 13 ++++ src/chrome/src/ui/locales/zh.js | 13 ++++ src/chrome/src/ui/settings.html | 43 +++++++++++++ src/chrome/src/ui/settings.js | 22 ++++++- 20 files changed, 385 insertions(+), 21 deletions(-) diff --git a/src/chrome/src/agent/agent.js b/src/chrome/src/agent/agent.js index 39dd13715..7d2ec9fba 100644 --- a/src/chrome/src/agent/agent.js +++ b/src/chrome/src/agent/agent.js @@ -128,6 +128,17 @@ export class Agent { // (form fields + email/phone text) BEFORE leaving the extension. Off by // default — loaded from chrome.storage.local in background.js. this.screenshotRedaction = false; + // Image budget (issue #311): screenshot quality + capture limits. All + // loaded from chrome.storage.local in background.js. Defaults preserve the + // previous behavior: no explicit `detail` was ever sent (so the provider + // uses its own default — OpenAI's is 'auto'), auto-screenshots were + // unlimited per turn, and images were capped at 1568px per side. + this.imageDetail = 'auto'; // 'high' | 'low' | 'auto' (provider-dependent) + this.maxScreenshotsPerTurn = 0; // 0 = unlimited + this.maxImageDimension = 1568; // max width/height in px for any vision image + // tabId -> auto-screenshot count within the current turn/run. Enforces + // `maxScreenshotsPerTurn`. Reset when a run starts and on tab cleanup. + this.autoScreenshotCount = new Map(); this.costAllowanceSessionUsd = DEFAULT_CLOUD_COST_ALLOWANCE_USD; this.costAllowanceTotalUsd = DEFAULT_CLOUD_COST_ALLOWANCE_USD; this.cloudCostSpentUsd = 0; @@ -1795,7 +1806,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: contextLine + screenshotNote + userMessage }, - { type: 'image_url', image_url: { url: shot.dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: shot.dataUrl }) }, ], }; } @@ -2486,7 +2497,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: noteText }, - { type: 'image_url', image_url: { url: attachedImage } }, + { type: 'image_url', image_url: this._withImageDetail({ url: attachedImage }) }, ], }); const _runIdForShot = this.currentRunId.get(tabId); @@ -2593,9 +2604,13 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d if (didStateChange && (provider.supportsVision || visionProvider)) { const lastTs = this.lastAutoScreenshotTs.get(tabId) || 0; if (Date.now() - lastTs >= 500) { + // Enforce maxScreenshotsPerTurn (issue #311). 0 means unlimited. + const _screenshotCap = Number(this.maxScreenshotsPerTurn) || 0; + const _overBudget = _screenshotCap > 0 && (this.autoScreenshotCount.get(tabId) || 0) >= _screenshotCap; await new Promise(r => setTimeout(r, 250)); - const shot = await this._captureAutoScreenshot(tabId); + const shot = _overBudget ? null : await this._captureAutoScreenshot(tabId); if (shot) { + if (_screenshotCap > 0) this.autoScreenshotCount.set(tabId, (this.autoScreenshotCount.get(tabId) || 0) + 1); this.lastAutoScreenshotTs.set(tabId, Date.now()); // Pair the image with a textual list of visible clickables so // the model can ground "the Publish button" by name instead of @@ -2638,7 +2653,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: textBlock }, - { type: 'image_url', image_url: { url: shot.dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: shot.dataUrl }) }, ], }); pushed = true; @@ -3171,13 +3186,14 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // binary-search, then ask CDP to capture + scale in one pass. This // avoids ever materializing a multi-MB native-DPR JPEG that we'd // then have to decode and resize in the service worker. - const [targetW, targetH] = Agent._fitImageDimensions(cssW, cssH); + const budget = this._budgetForCapture(); + const [targetW, targetH] = Agent._fitImageDimensions(cssW, cssH, budget); const scale = targetW < cssW ? targetW / cssW : 1; const captureOnce = async () => { const shot = await this._withIndicatorsHidden(tabId, () => cdpClient.sendCommand(tabId, 'Page.captureScreenshot', { format: 'jpeg', - quality: Math.round(Agent.IMAGE_BUDGET.initialJpegQuality * 100), + quality: Math.round(budget.initialJpegQuality * 100), fromSurface: true, clip: { x: 0, y: 0, width: cssW, height: cssH, scale }, }) @@ -3340,7 +3356,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: 'Describe this screenshot of the current browser viewport for a web-automation agent. Follow the format in the system prompt.' }, - { type: 'image_url', image_url: { url: dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: dataUrl }) }, ], }, ]; @@ -3496,7 +3512,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: prompt }, - { type: 'image_url', image_url: { url: screenshot.dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: screenshot.dataUrl }) }, ], }, ], { @@ -3890,7 +3906,53 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d } /** - * Draw a red outline rectangle over a base64 PNG/JPEG screenshot, at the + * Build a snapshot of the active image budget for a single capture. Starts + * from the static defaults and applies the user's `maxImageDimension` cap + * (issue #311) so the per-side pixel limit AND the total-token budget both + * track the setting. When the cap is the limiting factor, the token budget + * is widened to exactly fit a square image at the cap so the dimension cap + * (not the legacy 1568px token budget) governs sizing. + */ + _budgetForCapture() { + const base = Agent.IMAGE_BUDGET; + const cap = Math.max(1, Math.min(2048, Number(this.maxImageDimension) || 1568)); + const tokensForCap = Math.ceil((cap / base.pxPerToken) * (cap / base.pxPerToken)); + // Defaults must preserve the pre-#311 behavior. The default cap (1568) + // maps to the legacy budget byte-for-byte — same per-side limit AND same + // total-token limit — so a square viewport is still downscaled to ~1109px + // exactly as before. A LOWER cap shrinks both limits; a HIGHER cap widens + // them so the larger dimension is actually honored ("keep fidelity"). + if (cap === base.maxTargetPx) { + return { ...base }; + } + return { + ...base, + maxTargetPx: cap, + maxTargetTokens: tokensForCap, + }; + } + + /** + * The `detail` value to attach to an OpenAI-style image_url block, driven by + * the `imageDetail` setting (issue #311). Returns null when the setting is + * 'auto' so the provider uses its own default (OpenAI's is 'auto'); 'high' + * and 'low' are passed through. Anthropic ignores unknown `detail`, so this + * is harmless there. + */ + _imageDetailField() { + return this.imageDetail === 'auto' ? null : this.imageDetail; + } + + /** + * Return a copy of `imageUrl` with a `detail` field merged in when the user + * has chosen a non-auto image detail (issue #311). No-op for 'auto'. + */ + _withImageDetail(imageUrl) { + const detail = this._imageDetailField(); + return detail ? { ...imageUrl, detail } : imageUrl; + } + + /** * given CSS-pixel rect. Scales the rect by the ratio between the image's * actual pixel dimensions and the CSS viewport so it lines up regardless * of whether the capture was taken at scale=1 or native DPR. @@ -5471,6 +5533,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d this.progressSessions.delete(tabId); this.mastodonStates.delete(tabId); this.lastAutoScreenshotTs.delete(tabId); + this.autoScreenshotCount.delete(tabId); this.lastSeenAdapter.delete(tabId); this._lastInteractionRect.delete(tabId); this._doneBlockCount.delete(tabId); @@ -8343,7 +8406,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d if (!screenshot?.data) return null; const rawUrl = `data:image/png;base64,${screenshot.data}`; return { - dataUrl: await this._compressJpegToByteCeiling(rawUrl), + dataUrl: await this._compressJpegToByteCeiling(rawUrl, this._budgetForCapture()), description: `Screenshot captured via CDP (${screenshot.data.length} bytes, CSS-pixel aligned for pixel clicks)`, }; } @@ -8351,12 +8414,13 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // Budget-aware mode (default): pick target dims via binary // search, ask CDP to capture + scale in one pass, then run // the iterative-quality fallback if bytes are still over. - const [targetW, targetH] = Agent._fitImageDimensions(cssW, cssH); + const budget = this._budgetForCapture(); + const [targetW, targetH] = Agent._fitImageDimensions(cssW, cssH, budget); const scale = targetW < cssW ? targetW / cssW : 1; const screenshot = await this._withIndicatorsHidden(tabId, () => cdpClient.sendCommand(tabId, 'Page.captureScreenshot', { format: 'jpeg', - quality: Math.round(Agent.IMAGE_BUDGET.initialJpegQuality * 100), + quality: Math.round(budget.initialJpegQuality * 100), fromSurface: true, clip: { x: 0, y: 0, width: cssW, height: cssH, scale }, }) @@ -8365,7 +8429,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const rawUrl = `data:image/jpeg;base64,${screenshot.data}`; const resized = scale < 1 ? ` (resized ${cssW}×${cssH} → ${targetW}×${targetH} for vision-token budget)` : ''; return { - dataUrl: await this._compressJpegToByteCeiling(rawUrl), + dataUrl: await this._compressJpegToByteCeiling(rawUrl, budget), description: `Screenshot captured via CDP (${screenshot.data.length} bytes, JPEG)${resized}`, }; }; @@ -8389,7 +8453,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d if (!coordAligned) { const cssW = Math.max(1, Math.round(probe?.innerWidth || 1024)); const cssH = Math.max(1, Math.round(probe?.innerHeight || 768)); - const shrunk = await this._shrinkImageForBudget(rawUrl, cssW, cssH); + const shrunk = await this._shrinkImageForBudget(rawUrl, cssW, cssH, this._budgetForCapture()); return { dataUrl: shrunk.dataUrl, description: `Screenshot captured via tabs API (${shrunk.dataUrl.length} bytes base64, resized to ${shrunk.width}×${shrunk.height})`, @@ -8901,10 +8965,11 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // Full-page captures are the worst case for size — a 1920×8000 // document at native DPR easily blows past any provider's image - // budget. Always shrink to the token/byte budget. Dimensions come + // budget. Always shrink to the token/byte budget (which honors the + // user's `maxImageDimension` cap, issue #311). Dimensions come // from decoding the bitmap (we don't know the real doc size up // front the way we do for viewport captures). - const shrunk = await this._shrinkImageForBudget(rawUrl, 0, 0); + const shrunk = await this._shrinkImageForBudget(rawUrl, 0, 0, this._budgetForCapture()); // Local screenshot redaction (issue #312): pixelate form fields + // email/phone text on the image BEFORE it is sent to any vision @@ -9012,8 +9077,10 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // blows past the tool-result char cap and gets truncated to garbage // that the vision model can never read. let verifyShotUrl = `data:image/png;base64,${shot.data}`; - // Local screenshot redaction (issue #312): pixelate form fields + - // email/phone text BEFORE the image reaches the model. + // Apply the user's image budget (issue #311) before the image + // reaches the model, then run local redaction (issue #312) on the + // budget-fit copy so PII is pixelated at the size the model sees. + verifyShotUrl = (await this._shrinkImageForBudget(verifyShotUrl, 0, 0, this._budgetForCapture())).dataUrl; if (this.screenshotRedaction) { verifyShotUrl = await this._redactScreenshotDataUrl(tabId, verifyShotUrl, { coordinateSpace: 'viewport' }); } @@ -11628,7 +11695,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d error: `The active provider (${provider?.name || 'unknown'}) does not support image attachments. Switch to a vision-capable model (e.g. Claude 3+, GPT-4o) or remove the attached image and try again.`, }; } - blocks.push({ type: 'image_url', image_url: { url: att.dataUrl } }); + blocks.push({ type: 'image_url', image_url: this._withImageDetail({ url: att.dataUrl }) }); } else if (att.kind === 'document') { if (!provider?.supportsDocuments) { return { @@ -11662,6 +11729,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d async _processMessageInner(tabId, userMessage, onUpdate, mode, attachments = [], runOptions = {}) { await this._hydrate(tabId); + // Reset the per-turn auto-screenshot budget (issue #311) for a fresh turn. + this.autoScreenshotCount.delete(tabId); const messages = this.getConversation(tabId, mode); // Scheduled resumes get the live ledger appended at fire time, so the // model's first turn sees current row state even if it never calls @@ -12069,6 +12138,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d async _processMessageStreamInner(tabId, userMessage, onUpdate, mode, runOptions = {}) { await this._hydrate(tabId); + // Reset the per-turn auto-screenshot budget (issue #311) for a fresh turn. + this.autoScreenshotCount.delete(tabId); const messages = this.getConversation(tabId, mode); const costState = this._newCostRunState(); this.currentCostState.set(tabId, costState); diff --git a/src/chrome/src/background.js b/src/chrome/src/background.js index 1a55658ee..fff80785d 100644 --- a/src/chrome/src/background.js +++ b/src/chrome/src/background.js @@ -152,6 +152,17 @@ async function loadScreenshotRedaction() { } const screenshotRedactionReady = loadScreenshotRedaction().catch(() => {}); +// Image budget (issue #311): screenshot quality + how many screenshots the +// agent may capture per turn, and the max image dimension. Defaults preserve +// the previous behavior (auto detail, unlimited screenshots, 1568px cap). +async function loadImageBudget() { + const stored = await chrome.storage.local.get(['imageDetail', 'maxScreenshotsPerTurn', 'maxImageDimension']); + if (stored.imageDetail != null) agent.imageDetail = stored.imageDetail; + if (stored.maxScreenshotsPerTurn != null) agent.maxScreenshotsPerTurn = stored.maxScreenshotsPerTurn; + if (stored.maxImageDimension != null) agent.maxImageDimension = stored.maxImageDimension; +} +loadImageBudget(); + async function loadStrictSecretMode() { const stored = await chrome.storage.local.get('strictSecretMode'); if (stored.strictSecretMode != null) agent.strictSecretMode = !!stored.strictSecretMode; @@ -683,6 +694,15 @@ chrome.storage.onChanged.addListener((changes) => { if (changes.screenshotRedaction) { agent.screenshotRedaction = !!changes.screenshotRedaction.newValue; } + if (changes.imageDetail) { + agent.imageDetail = changes.imageDetail.newValue; + } + if (changes.maxScreenshotsPerTurn) { + agent.maxScreenshotsPerTurn = changes.maxScreenshotsPerTurn.newValue; + } + if (changes.maxImageDimension) { + agent.maxImageDimension = changes.maxImageDimension.newValue; + } if (changes[API_MUTATION_OBSERVER_KEY]) { setApiMutationObserverEnabled(changes[API_MUTATION_OBSERVER_KEY].newValue === true); } diff --git a/src/chrome/src/ui/locales/ar.js b/src/chrome/src/ui/locales/ar.js index b6ad49c0d..8a4cda878 100644 --- a/src/chrome/src/ui/locales/ar.js +++ b/src/chrome/src/ui/locales/ar.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "إخفاء المحتوى الحساس في لقطات الشاشة", "st.redaction.toggle.desc": "قبل إرسال لقطة الشاشة إلى نموذج رؤية، يقوم بتغبيش حقول النماذج والنص الذي يبدو كبريد إلكتروني أو رقم هاتف. يعمل الكشف بالكامل على جهازك — لا يُنقل أي شيء إضافي.", "st.redaction.warning": "⚠️ هذا تعتيم بأفضل جهد ومن نوع fail-open: إذا تعذّر تشغيل التعتيم على صفحة ما (مثلًا مباشرة بعد التنقل، أو في عارضات PDF، أو على صفحات المتصفح المقيّدة)، فستُرسل لقطة الشاشة كما هي دون تعتيم. يعتمد الكشف فقط على استدلالات DOM — النص المرسوم على عنصر canvas، أو البيانات الشخصية داخل الصور، أو أي شيء لا يُعرف كحقل نموذج أو نص بريد/هاتف قد يفلت من الكشف، كما أن نص الصفحة المُرسل إلى النموذج لا يُعتَّم بهذا الإعداد. هذا ليس ضمانًا أمنيًا. للخصوصية الكاملة، استخدم نموذجًا محليًا/دون اتصال (llama.cpp أو Ollama): عندها لن تغادر لقطات الشاشة جهازك إطلاقًا ولن تعود هناك حاجة للتعتيم.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/en.js b/src/chrome/src/ui/locales/en.js index 2fea1e9f6..d3308ea25 100644 --- a/src/chrome/src/ui/locales/en.js +++ b/src/chrome/src/ui/locales/en.js @@ -538,6 +538,23 @@ export default { 'st.transcription.failed': 'Failed: {error}', 'st.transcription.fill_required': 'Fill in Base URL and Model first.', + // Image budget (issue #311): tune screenshot quality + how many + // screenshots the agent may capture/send per turn, and how large each + // image may be. All controls live on the Multimodal tab. + 'st.imageBudget.heading': 'Image budget', + 'st.imageBudget.desc': 'Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.', + 'st.imageBudget.detail.label': 'Image detail', + 'st.imageBudget.detail.desc': 'Vision image detail sent to the model. "high" keeps more detail (more tokens, higher cost); "low" sends a smaller, cheaper image; "auto" lets the provider decide. Provider-dependent.', + 'st.imageBudget.detail.high': 'High (more detail, more cost)', + 'st.imageBudget.detail.low': 'Low (cheaper, less detail)', + 'st.imageBudget.detail.auto': 'Auto (provider default)', + 'st.imageBudget.maxPerTurn.label': 'Max screenshots per turn', + 'st.imageBudget.maxPerTurn.desc': 'How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.', + 'st.imageBudget.maxPerTurn.unlimited': 'Unlimited', + 'st.imageBudget.maxDimension.label': 'Max image dimension', + 'st.imageBudget.maxDimension.desc': 'Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.', + 'st.imageBudget.warning': '⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. "Image detail" is honored by OpenAI-style endpoints; other providers may ignore it.', + // Screenshot redaction (issue #312): local, best-effort PII blurring that // runs in-browser before any screenshot reaches a vision model. 'st.redaction.heading': 'Screenshot redaction', diff --git a/src/chrome/src/ui/locales/es.js b/src/chrome/src/ui/locales/es.js index 817539c20..294f21a19 100644 --- a/src/chrome/src/ui/locales/es.js +++ b/src/chrome/src/ui/locales/es.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "Redactar contenido sensible en las capturas de pantalla", "st.redaction.toggle.desc": "Antes de enviar una captura de pantalla a un modelo de visión, difumina los campos de formulario y el texto que parezca un correo electrónico o un número de teléfono. La detección se ejecuta enteramente en tu dispositivo — no se transmite nada adicional.", "st.redaction.warning": "⚠️ Es una redacción best-effort y fail-open: si no se puede aplicar en una página (por ejemplo justo después de una navegación, en visores de PDF o en páginas restringidas del navegador), la captura se envía igualmente sin redactar. La detección usa solo heurísticas del DOM — texto dibujado en un canvas, datos personales dentro de imágenes, o cualquier cosa no reconocida como campo de formulario o texto de correo/teléfono puede pasar desapercibida, y el texto de la página enviado al modelo no se redacta con este ajuste. No es una garantía de seguridad. Para privacidad total, usa un modelo local/sin conexión (llama.cpp, Ollama): las capturas nunca saldrán de tu equipo y la redacción deja de ser necesaria.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/fr.js b/src/chrome/src/ui/locales/fr.js index abc093ef4..1362ed678 100644 --- a/src/chrome/src/ui/locales/fr.js +++ b/src/chrome/src/ui/locales/fr.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "Flouter le contenu sensible dans les captures d'écran", "st.redaction.toggle.desc": "Avant qu'une capture d'écran soit envoyée à un modèle de vision, floute les champs de formulaire et le texte qui ressemble à un e-mail ou un numéro de téléphone. La détection s'exécute entièrement sur votre appareil — rien de plus n'est transmis.", "st.redaction.warning": "⚠️ Meilleur effort et fail-open : si le floutage ne peut pas s'exécuter sur une page (par exemple juste après une navigation, dans les visionneuses PDF, ou sur des pages restreintes du navigateur), la capture est quand même envoyée non floutée. La détection utilise uniquement des heuristiques DOM — texte dessiné sur un canvas, données personnelles dans des images, ou tout ce qui n'est pas reconnu comme champ de formulaire ou texte e-mail/téléphone peut passer inaperçu, et le texte de la page envoyé au modèle n'est pas flouté par ce réglage. Ce n'est PAS une garantie de sécurité. Pour une confidentialité totale, utilisez un modèle local/hors ligne (llama.cpp, Ollama) : les captures ne quittent alors jamais votre machine et le floutage devient inutile.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/he.js b/src/chrome/src/ui/locales/he.js index 7a3aea043..fde02731d 100644 --- a/src/chrome/src/ui/locales/he.js +++ b/src/chrome/src/ui/locales/he.js @@ -655,4 +655,17 @@ export default { "st.redaction.toggle.label": "טשטש תוכן רגיש בצילומי מסך", "st.redaction.toggle.desc": "לפני שצילום מסך נשלח למודל ראייה, מטשטש שדות טופס וטקסט שנראה כמו אימייל או מספר טלפון. הזיהוי פועל כולו במכשיר שלך — שום דבר נוסף לא מועבר.", "st.redaction.warning": "⚠️ זהו טשטוש במאמץ סביר (best-effort) מסוג fail-open: אם הטשטוש לא יכול לפעול בדף מסוים (למשל מיד אחרי ניווט, בצפייה בקבצי PDF, או בדפי דפדפן מוגבלים), צילום המסך עדיין יישלח ללא טשטוש. הזיהוי מסתמך רק על היוריסטיקות DOM — טקסט המצויר על canvas, מידע אישי בתוך תמונות, או כל דבר שלא מזוהה כשדה טופס או כטקסט אימייל/טלפון עלול לחמוק, וטקסט הדף הנשלח למודל אינו מטושטש על ידי הגדרה זו. זו אינה ערבות אבטחה. לפרטיות מלאה, השתמש במודל מקומי/לא מקוון (llama.cpp, Ollama): כך צילומי מסך לעולם לא יעזבו את המכשיר שלך והטשטוש כבר לא יידרש.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/id.js b/src/chrome/src/ui/locales/id.js index 5f9ffe8e9..21ff47508 100644 --- a/src/chrome/src/ui/locales/id.js +++ b/src/chrome/src/ui/locales/id.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "Samarkan konten sensitif pada tangkapan layar", "st.redaction.toggle.desc": "Sebelum tangkapan layar dikirim ke model visi, WebBrain mengaburkan kolom formulir dan teks yang terlihat seperti email atau nomor telepon. Pendeteksian berjalan sepenuhnya di perangkat Anda — tidak ada yang dikirim ekstra.", "st.redaction.warning": "⚠️ Ini bersifat best-effort dan fail-open: jika penyamaran tidak bisa berjalan di suatu halaman (misalnya tepat setelah navigasi, di penampil PDF, atau di halaman browser yang dibatasi), tangkapan layar tetap dikirim tanpa disamarkan. Pendeteksian hanya menggunakan heuristik DOM — teks yang digambar di canvas, informasi pribadi di dalam gambar, atau apa pun yang tidak dikenali sebagai kolom formulir atau teks email/telepon bisa saja lolos, dan teks halaman yang dikirim ke model tidak disamarkan oleh pengaturan ini. Ini BUKAN jaminan keamanan. Untuk privasi penuh, gunakan model lokal/offline (llama.cpp, Ollama): tangkapan layar tidak akan pernah meninggalkan perangkat Anda dan penyamaran pun jadi tidak diperlukan.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/ja.js b/src/chrome/src/ui/locales/ja.js index 5bf20ba3f..24a31320b 100644 --- a/src/chrome/src/ui/locales/ja.js +++ b/src/chrome/src/ui/locales/ja.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "スクリーンショット内の機密情報を黒塗りする", "st.redaction.toggle.desc": "スクリーンショットをビジョンモデルに送信する前に、フォーム項目やメールアドレス・電話番号らしきテキストにモザイクをかけます。検出はすべて端末内で行われ、追加で送信されるデータはありません。", "st.redaction.warning": "⚠️ これはベストエフォートかつフェイルオープンな処理です。ページ上で黒塗り処理が実行できない場合(ナビゲーション直後、PDFビューア、制限されたブラウザページなど)、スクリーンショットは黒塗りされないまま送信されます。検出はDOMヒューリスティックのみに基づいており、canvasに描画されたテキスト、画像内の個人情報、フォーム項目やメール/電話のテキストと認識されないものは見逃される可能性があります。またモデルに送られるページの本文テキストはこの設定では黒塗りされません。これはセキュリティ上の保証ではありません。完全なプライバシーが必要な場合は、ローカル/オフラインモデル(llama.cpp、Ollamaなど)を使用してください。その場合スクリーンショットは端末から一切出ないため、黒塗りは不要になります。", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/ko.js b/src/chrome/src/ui/locales/ko.js index 1d9e4f1f9..a583f72c4 100644 --- a/src/chrome/src/ui/locales/ko.js +++ b/src/chrome/src/ui/locales/ko.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "스크린샷의 민감한 콘텐츠 마스킹", "st.redaction.toggle.desc": "스크린샷을 비전 모델로 보내기 전에 양식 필드와 이메일이나 전화번호처럼 보이는 텍스트를 흐리게 처리합니다. 감지는 전적으로 사용자 기기에서 실행되며, 추가로 전송되는 데이터는 없습니다.", "st.redaction.warning": "⚠️ 이 기능은 최선을 다하는(best-effort) 방식이며 fail-open입니다. 마스킹이 페이지에서 실행될 수 없는 경우(예: 탐색 직후, PDF 뷰어, 제한된 브라우저 페이지 등) 스크린샷은 마스킹되지 않은 채로 그대로 전송됩니다. 감지는 DOM 휴리스틱만 사용하므로 캔버스에 그려진 텍스트, 이미지 안의 개인정보, 양식 필드나 이메일/전화번호 텍스트로 인식되지 않는 항목은 놓칠 수 있으며, 모델로 전송되는 페이지 텍스트는 이 설정으로 마스킹되지 않습니다. 이는 보안을 보장하는 기능이 아닙니다. 완전한 프라이버시가 필요하다면 로컬/오프라인 모델(llama.cpp, Ollama)을 사용하세요. 이 경우 스크린샷이 기기를 벗어나지 않으므로 마스킹 자체가 필요하지 않습니다.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/ms.js b/src/chrome/src/ui/locales/ms.js index 003a164ce..be5437a61 100644 --- a/src/chrome/src/ui/locales/ms.js +++ b/src/chrome/src/ui/locales/ms.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "Samarkan kandungan sensitif dalam tangkapan skrin", "st.redaction.toggle.desc": "Sebelum tangkapan skrin dihantar ke model visi, medan borang dan teks yang kelihatan seperti e-mel atau nombor telefon akan dikaburkan. Pengesanan berjalan sepenuhnya pada peranti anda — tiada apa-apa tambahan dihantar.", "st.redaction.warning": "⚠️ Ini bersifat usaha terbaik (best-effort) dan fail-open: jika penyamaran tidak dapat berjalan pada sesuatu halaman (contohnya sejurus selepas navigasi, dalam pemapar PDF, atau pada halaman pelayar yang dihadkan), tangkapan skrin tetap dihantar tanpa disamarkan. Pengesanan hanya menggunakan heuristik DOM — teks yang dilukis pada canvas, maklumat peribadi dalam imej, atau apa-apa yang tidak dikenali sebagai medan borang atau teks e-mel/telefon mungkin terlepas, dan teks halaman yang dihantar kepada model tidak disamarkan oleh tetapan ini. Ini BUKAN jaminan keselamatan. Untuk privasi sepenuhnya, gunakan model tempatan/luar talian (llama.cpp, Ollama): tangkapan skrin tidak akan meninggalkan peranti anda dan penyamaran menjadi tidak diperlukan.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/pl.js b/src/chrome/src/ui/locales/pl.js index 32676fea7..ab88d08a6 100644 --- a/src/chrome/src/ui/locales/pl.js +++ b/src/chrome/src/ui/locales/pl.js @@ -662,4 +662,17 @@ export default { "st.redaction.toggle.label": "Redaguj poufną treść na zrzutach ekranu", "st.redaction.toggle.desc": "Zanim zrzut ekranu zostanie wysłany do modelu wizyjnego, rozmywa pola formularzy oraz tekst wyglądający jak e-mail lub numer telefonu. Wykrywanie działa całkowicie na Twoim urządzeniu — nic dodatkowego nie jest przesyłane.", "st.redaction.warning": "⚠️ To redakcja typu best-effort i fail-open: jeśli redakcja nie może zadziałać na danej stronie (np. tuż po nawigacji, w przeglądarkach PDF lub na ograniczonych stronach przeglądarki), zrzut ekranu i tak zostanie wysłany bez redakcji. Wykrywanie opiera się wyłącznie na heurystykach DOM — tekst narysowany na canvasie, dane osobowe wewnątrz obrazów lub cokolwiek nierozpoznanego jako pole formularza czy tekst e-mail/telefon może zostać pominięte, a tekst strony wysyłany do modelu nie jest redagowany przez to ustawienie. To NIE jest gwarancja bezpieczeństwa. Dla pełnej prywatności użyj lokalnego/offline'owego modelu (llama.cpp, Ollama): wtedy zrzuty ekranu nigdy nie opuszczają Twojego urządzenia, a redakcja przestaje być potrzebna.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/ru.js b/src/chrome/src/ui/locales/ru.js index fc1f9c4e7..8afeb203b 100644 --- a/src/chrome/src/ui/locales/ru.js +++ b/src/chrome/src/ui/locales/ru.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "Скрывать чувствительный контент на скриншотах", "st.redaction.toggle.desc": "Перед отправкой скриншота модели зрения размывает поля форм и текст, похожий на email или номер телефона. Обнаружение выполняется полностью на вашем устройстве — ничего лишнего не передаётся.", "st.redaction.warning": "⚠️ Работает по принципу «максимум усилий» и fail-open: если редактирование не может выполниться на странице (например, сразу после перехода, в просмотрщиках PDF или на ограниченных страницах браузера), скриншот всё равно отправляется неотредактированным. Обнаружение использует только эвристики DOM — текст, нарисованный на canvas, персональные данные внутри изображений или что-либо, не распознанное как поле формы или текст email/телефона, может остаться незамеченным, а текст страницы, отправляемый модели, этой настройкой не редактируется. Это НЕ гарантия безопасности. Для полной приватности используйте локальную/офлайн-модель (llama.cpp, Ollama): тогда скриншоты вообще не покидают ваше устройство и редактирование не требуется.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/th.js b/src/chrome/src/ui/locales/th.js index 8351564fd..084675dea 100644 --- a/src/chrome/src/ui/locales/th.js +++ b/src/chrome/src/ui/locales/th.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "เบลอเนื้อหาที่ละเอียดอ่อนในภาพหน้าจอ", "st.redaction.toggle.desc": "ก่อนส่งภาพหน้าจอไปยังโมเดลวิชั่น ระบบจะเบลอช่องฟอร์มและข้อความที่ดูเหมือนอีเมลหรือหมายเลขโทรศัพท์ การตรวจจับทำงานทั้งหมดบนอุปกรณ์ของคุณ — ไม่มีการส่งข้อมูลเพิ่มเติมใดๆ", "st.redaction.warning": "⚠️ ฟีเจอร์นี้เป็นแบบ best-effort และ fail-open: หากการเบลอไม่สามารถทำงานบนหน้าใดหน้าหนึ่งได้ (เช่น ทันทีหลังการนำทาง ในตัวแสดง PDF หรือบนหน้าเบราว์เซอร์ที่ถูกจำกัด) ภาพหน้าจอจะยังคงถูกส่งไปโดยไม่ถูกเบลอ การตรวจจับใช้เพียงหลักการ DOM heuristics เท่านั้น — ข้อความที่วาดบน canvas ข้อมูลส่วนบุคคลในรูปภาพ หรือสิ่งใดก็ตามที่ไม่ถูกจดจำว่าเป็นช่องฟอร์มหรือข้อความอีเมล/โทรศัพท์ อาจหลุดรอดไปได้ และข้อความในหน้าเว็บที่ส่งไปยังโมเดลก็ไม่ถูกเบลอโดยการตั้งค่านี้ นี่ไม่ใช่การรับประกันด้านความปลอดภัย หากต้องการความเป็นส่วนตัวอย่างเต็มที่ ให้ใช้โมเดลภายในเครื่อง/ออฟไลน์ (llama.cpp, Ollama) เพราะภาพหน้าจอจะไม่ออกจากเครื่องของคุณเลย และไม่จำเป็นต้องเบลออีกต่อไป", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/tl.js b/src/chrome/src/ui/locales/tl.js index f0473c5d3..a27ce1582 100644 --- a/src/chrome/src/ui/locales/tl.js +++ b/src/chrome/src/ui/locales/tl.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "Burahin ang sensitibong nilalaman sa mga screenshot", "st.redaction.toggle.desc": "Bago ipadala ang isang screenshot sa isang vision model, binuburahin nito ang mga form field at tekstong mukhang email o numero ng telepono. Tumatakbo ang detection nang buo sa iyong device — walang karagdagang ipinapadala.", "st.redaction.warning": "⚠️ Best-effort at fail-open ito: kung hindi matakbo ang pagbura sa isang page (halimbawa, agad pagkatapos mag-navigate, sa mga PDF viewer, o sa mga restricted browser page), ipapadala pa rin ang screenshot nang hindi nabura. Gumagamit lang ang detection ng DOM heuristics — puwedeng makalusot ang tekstong iginuhit sa canvas, personal na impormasyon sa loob ng mga larawan, o anumang hindi nakikilalang form field o email/phone text, at hindi binubura ng setting na ito ang text ng page na ipinapadala sa model. Hindi ito garantiya ng seguridad. Para sa ganap na privacy, gumamit ng local/offline model (llama.cpp, Ollama): hindi na aalis sa iyong device ang mga screenshot at hindi na kailangan ang pagbura.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/tr.js b/src/chrome/src/ui/locales/tr.js index e038c72a0..4bf1e29fd 100644 --- a/src/chrome/src/ui/locales/tr.js +++ b/src/chrome/src/ui/locales/tr.js @@ -701,4 +701,17 @@ export default { "st.redaction.toggle.label": "Ekran görüntülerindeki hassas içeriği sansürle", "st.redaction.toggle.desc": "Bir ekran görüntüsü bir görüntü modeline gönderilmeden önce, form alanlarını ve e-posta ya da telefon numarasına benzeyen metni bulanıklaştırır. Algılama tamamen cihazınızda çalışır — fazladan hiçbir şey iletilmez.", "st.redaction.warning": "⚠️ En iyi çaba ilkesiyle çalışır ve fail-open'dır: sansürleme bir sayfada çalışamazsa (örneğin bir gezinmeden hemen sonra, PDF görüntüleyicilerde veya kısıtlı tarayıcı sayfalarında), ekran görüntüsü yine de sansürlenmeden gönderilir. Algılama yalnızca DOM sezgisel yöntemlerini kullanır — bir canvas üzerine çizilmiş metin, görsellerin içindeki kişisel veriler veya form alanı ya da e-posta/telefon metni olarak tanınmayan herhangi bir şey gözden kaçabilir; modele gönderilen sayfa metni de bu ayarla sansürlenmez. Bu bir güvenlik garantisi DEĞİLDİR. Tam gizlilik için yerel/çevrimdışı bir model kullanın (llama.cpp, Ollama): bu durumda ekran görüntüleri makinenizden hiç çıkmaz ve sansürleme gereksiz hale gelir.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/uk.js b/src/chrome/src/ui/locales/uk.js index 2f076fb48..0704f3bb3 100644 --- a/src/chrome/src/ui/locales/uk.js +++ b/src/chrome/src/ui/locales/uk.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "Приховувати чутливий вміст на знімках екрана", "st.redaction.toggle.desc": "Перед надсиланням знімка екрана моделі зору розмиває поля форм і текст, схожий на email чи номер телефону. Виявлення виконується повністю на вашому пристрої — нічого зайвого не передається.", "st.redaction.warning": "⚠️ Працює за принципом «найкращих зусиль» і fail-open: якщо редагування не може виконатися на сторінці (наприклад, одразу після переходу, у переглядачах PDF або на обмежених сторінках браузера), знімок екрана все одно надсилається невідредагованим. Виявлення використовує лише евристики DOM — текст, намальований на canvas, персональні дані всередині зображень або будь-що, не розпізнане як поле форми чи текст email/телефону, може залишитися непоміченим, а текст сторінки, що надсилається моделі, цим налаштуванням не редагується. Це НЕ гарантія безпеки. Для повної приватності використовуйте локальну/офлайн-модель (llama.cpp, Ollama): тоді знімки екрана взагалі не покидають ваш пристрій і редагування стає непотрібним.", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/locales/zh.js b/src/chrome/src/ui/locales/zh.js index d3e81d0a9..2ae892f5c 100644 --- a/src/chrome/src/ui/locales/zh.js +++ b/src/chrome/src/ui/locales/zh.js @@ -702,4 +702,17 @@ export default { "st.redaction.toggle.label": "对截图中的敏感内容进行打码", "st.redaction.toggle.desc": "在截图发送给视觉模型之前,对表单字段以及看起来像邮箱或电话号码的文本进行打码模糊处理。检测完全在你的设备上运行——不会额外传输任何内容。", "st.redaction.warning": "⚠️ 这是尽力而为且失败开放(fail-open)的处理:如果打码功能在某个页面上无法运行(例如刚导航完成之后、在 PDF 查看器中,或在受限的浏览器页面上),截图仍会以未打码的原样发送。检测仅使用 DOM 启发式方法——canvas 上绘制的文字、图片中的个人信息,或任何未被识别为表单字段或邮箱/电话文本的内容都可能被遗漏,发送给模型的页面文本也不会被此设置打码。这不是安全保证。若需要完全的隐私保护,请使用本地/离线模型(llama.cpp、Ollama):这样截图将永远不会离开你的设备,也就不再需要打码。", + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", }; diff --git a/src/chrome/src/ui/settings.html b/src/chrome/src/ui/settings.html index d71f4a0a3..09a5be655 100644 --- a/src/chrome/src/ui/settings.html +++ b/src/chrome/src/ui/settings.html @@ -1036,6 +1036,49 @@

+

+
+
+ +
+ + +
+
+ +
+ + +
+
+ +
+ + +
+
+ +
+
+

diff --git a/src/chrome/src/ui/settings.js b/src/chrome/src/ui/settings.js index 8f4251d81..6e6ca3500 100644 --- a/src/chrome/src/ui/settings.js +++ b/src/chrome/src/ui/settings.js @@ -44,7 +44,10 @@ const costSessionLimitInput = document.getElementById('input-cost-session-limit' const costTotalLimitInput = document.getElementById('input-cost-total-limit'); const costSpentValueLabel = document.getElementById('cost-spent-value'); const btnResetCostSpend = document.getElementById('btn-reset-cost-spend'); -const autoScreenshotSelect = document.getElementById('select-auto-screenshot'); + const autoScreenshotSelect = document.getElementById('select-auto-screenshot'); + const imageDetailSelect = document.getElementById('select-image-detail'); + const maxScreenshotsSelect = document.getElementById('select-max-screenshots'); + const maxImageDimensionSelect = document.getElementById('select-max-image-dimension'); const siteAdaptersToggle = document.getElementById('toggle-site-adapters'); const voiceInputToggle = document.getElementById('toggle-voice-input'); const apiMutationObserverToggle = document.getElementById('toggle-api-mutation-observer'); @@ -354,7 +357,7 @@ async function init() { chrome.storage.local.remove(['authToken', 'authEmail', 'authDefaultModel']).catch(() => {}); // Load display settings - const stored = await chrome.storage.local.get(['verboseMode', 'screenshotFallback', 'maxAgentSteps', 'autoScreenshot', 'useSiteAdapters', 'voiceInputEnabled', 'apiMutationObserverEnabled', 'planBeforeActMode', 'planBeforeAct', 'planReviewMode', 'planReviewConfidenceThreshold', 'notifySound', 'completionConfetti', 'tracingEnabled', 'strictSecretMode', 'agentAllowLocalNetwork', 'scheduledTasksEnabled', 'scheduledRequireConsequentialConfirmation', 'providerFilter', 'requestTimeoutMs', 'costAllowanceSessionUsd', 'costAllowanceTotalUsd', 'cloudCostSpentUsd', 'screenshotRedaction']); + const stored = await chrome.storage.local.get(['verboseMode', 'screenshotFallback', 'maxAgentSteps', 'autoScreenshot', 'useSiteAdapters', 'voiceInputEnabled', 'apiMutationObserverEnabled', 'planBeforeActMode', 'planBeforeAct', 'planReviewMode', 'planReviewConfidenceThreshold', 'notifySound', 'completionConfetti', 'tracingEnabled', 'strictSecretMode', 'agentAllowLocalNetwork', 'scheduledTasksEnabled', 'scheduledRequireConsequentialConfirmation', 'providerFilter', 'requestTimeoutMs', 'costAllowanceSessionUsd', 'costAllowanceTotalUsd', 'cloudCostSpentUsd', 'screenshotRedaction', 'imageDetail', 'maxScreenshotsPerTurn', 'maxImageDimension']); if (typeof stored.providerFilter === 'string' && ['all','local','cloud','router'].includes(stored.providerFilter)) { providerFilter = stored.providerFilter; } @@ -378,6 +381,9 @@ async function init() { requestTimeoutValueLabel.textContent = tSec + 's'; } autoScreenshotSelect.value = stored.autoScreenshot || 'state_change'; + imageDetailSelect.value = stored.imageDetail || 'auto'; + maxScreenshotsSelect.value = String(stored.maxScreenshotsPerTurn != null ? stored.maxScreenshotsPerTurn : 0); + maxImageDimensionSelect.value = String(stored.maxImageDimension || 1568); siteAdaptersToggle.checked = stored.useSiteAdapters ?? true; if (voiceInputToggle) voiceInputToggle.checked = stored.voiceInputEnabled ?? true; apiMutationObserverToggle.checked = stored.apiMutationObserverEnabled === true; @@ -808,6 +814,18 @@ autoScreenshotSelect.addEventListener('change', async () => { await chrome.storage.local.set({ autoScreenshot: autoScreenshotSelect.value }).catch(() => {}); }); +imageDetailSelect.addEventListener('change', async () => { + await chrome.storage.local.set({ imageDetail: imageDetailSelect.value }).catch(() => {}); +}); + +maxScreenshotsSelect.addEventListener('change', async () => { + await chrome.storage.local.set({ maxScreenshotsPerTurn: parseInt(maxScreenshotsSelect.value, 10) || 0 }).catch(() => {}); +}); + +maxImageDimensionSelect.addEventListener('change', async () => { + await chrome.storage.local.set({ maxImageDimension: parseInt(maxImageDimensionSelect.value, 10) || 1568 }).catch(() => {}); +}); + siteAdaptersToggle.addEventListener('change', async () => { await chrome.storage.local.set({ useSiteAdapters: siteAdaptersToggle.checked }).catch(() => {}); }); From bf0d0cfe4fb3a023c458db392be3c226f8db23b7 Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Mon, 13 Jul 2026 04:04:30 +0300 Subject: [PATCH 2/6] feat(firefox): port image budget controls and close review items 1/4/5 Mirror Chrome image-budget (#311) to Firefox (agent helpers, settings, storage hydration, locales), skip re-shrink when vision dims are already set, and add unit tests for budget mapping, detail, and per-turn counters. --- src/chrome/src/agent/agent.js | 27 +++-- src/firefox/src/agent/agent.js | 184 +++++++++++++++++++++++++++---- src/firefox/src/background.js | 21 ++++ src/firefox/src/ui/locales/ar.js | 15 +++ src/firefox/src/ui/locales/en.js | 15 +++ src/firefox/src/ui/locales/es.js | 15 +++ src/firefox/src/ui/locales/fr.js | 15 +++ src/firefox/src/ui/locales/he.js | 15 +++ src/firefox/src/ui/locales/id.js | 15 +++ src/firefox/src/ui/locales/ja.js | 15 +++ src/firefox/src/ui/locales/ko.js | 15 +++ src/firefox/src/ui/locales/ms.js | 15 +++ src/firefox/src/ui/locales/pl.js | 15 +++ src/firefox/src/ui/locales/ru.js | 15 +++ src/firefox/src/ui/locales/th.js | 15 +++ src/firefox/src/ui/locales/tl.js | 15 +++ src/firefox/src/ui/locales/tr.js | 15 +++ src/firefox/src/ui/locales/uk.js | 15 +++ src/firefox/src/ui/locales/zh.js | 15 +++ src/firefox/src/ui/settings.html | 43 ++++++++ src/firefox/src/ui/settings.js | 20 +++- test/run.js | 90 ++++++++++++++- 22 files changed, 590 insertions(+), 35 deletions(-) diff --git a/src/chrome/src/agent/agent.js b/src/chrome/src/agent/agent.js index 3a7739827..e7fa635ee 100644 --- a/src/chrome/src/agent/agent.js +++ b/src/chrome/src/agent/agent.js @@ -3557,14 +3557,23 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // Original crop/CSS space (used to map the vision box back for cropping). const origW = Math.max(1, Math.round(screenshot.width || 0)); const origH = Math.max(1, Math.round(screenshot.height || 0)); - // Model-facing image may already be budget-resized by the capture path; - // re-apply the budget here so localization never bypasses maxImageDimension - // even if the caller handed us an unshrunk dataUrl (issue #311). - const shrunk = await this._shrinkImageForBudget( - screenshot.dataUrl, origW, origH, this._budgetForCapture(), - ); - const visionW = Math.max(1, Math.round(shrunk.width || origW)); - const visionH = Math.max(1, Math.round(shrunk.height || origH)); + // Prefer already-budgeted vision dims from capture — re-shrinking with CSS + // dims double-encodes JPEG and can desync scale (issue #311 review). + let visionDataUrl; + let visionW; + let visionH; + if (screenshot.visionWidth && screenshot.visionHeight) { + visionDataUrl = screenshot.dataUrl; + visionW = Math.max(1, Math.round(screenshot.visionWidth)); + visionH = Math.max(1, Math.round(screenshot.visionHeight)); + } else { + const shrunk = await this._shrinkImageForBudget( + screenshot.dataUrl, origW, origH, this._budgetForCapture(), + ); + visionDataUrl = shrunk.dataUrl; + visionW = Math.max(1, Math.round(shrunk.width || origW)); + visionH = Math.max(1, Math.round(shrunk.height || origH)); + } const started = Date.now(); const runId = this.currentRunId.get(tabId); const costState = opts.costState || this.currentCostState.get(tabId) || null; @@ -3583,7 +3592,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: prompt }, - { type: 'image_url', image_url: this._withImageDetail({ url: shrunk.dataUrl }) }, + { type: 'image_url', image_url: this._withImageDetail({ url: visionDataUrl }) }, ], }, ], { diff --git a/src/firefox/src/agent/agent.js b/src/firefox/src/agent/agent.js index a85c6f0f8..b897e1d9c 100644 --- a/src/firefox/src/agent/agent.js +++ b/src/firefox/src/agent/agent.js @@ -109,6 +109,17 @@ export class Agent { this._compactCooldown = new Map(); this.autoScreenshot = 'state_change'; this.useSiteAdapters = true; + // Image budget (issue #311): screenshot quality + capture limits. All + // loaded from browser.storage.local in background.js. Defaults preserve + // previous behavior: no explicit `detail`, unlimited auto-screenshots + // per turn, and images capped at 1568px per side. + this.imageDetail = 'auto'; // 'high' | 'low' | 'auto' (provider-dependent) + this.maxScreenshotsPerTurn = 0; // 0 = unlimited + this.maxImageDimension = 1568; // max width/height in px for any vision image + // tabId -> auto-screenshot count within the current turn/run. Enforces + // `maxScreenshotsPerTurn` for every automatic capture (initial viewport + // AND post-action). Reset when a run starts and on tab cleanup. + this.autoScreenshotCount = new Map(); this.costAllowanceSessionUsd = DEFAULT_CLOUD_COST_ALLOWANCE_USD; this.costAllowanceTotalUsd = DEFAULT_CLOUD_COST_ALLOWANCE_USD; this.cloudCostSpentUsd = 0; @@ -2093,7 +2104,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: noteText }, - { type: 'image_url', image_url: { url: attachedImage } }, + { type: 'image_url', image_url: this._withImageDetail({ url: attachedImage }) }, ], }); } @@ -2186,7 +2197,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const lastTs = this.lastAutoScreenshotTs.get(tabId) || 0; if (Date.now() - lastTs >= 500) { await new Promise(r => setTimeout(r, 250)); - const shot = await this._captureAutoScreenshot(tabId); + const shot = await this._captureBudgetedAutoScreenshot(tabId); if (shot) { this.lastAutoScreenshotTs.set(tabId, Date.now()); const visible = await this._getVisibleInteractiveElements(tabId); @@ -2226,7 +2237,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: textBlock }, - { type: 'image_url', image_url: { url: shot.dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: shot.dataUrl }) }, ], }); pushed = true; @@ -2396,6 +2407,49 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d } } + /** + * Build a snapshot of the active image budget for a single capture. Starts + * from the static defaults and applies the user's `maxImageDimension` cap + * (issue #311) so the per-side pixel limit AND the total-token budget both + * track the setting. When the cap is the limiting factor, the token budget + * is widened to exactly fit a square image at the cap so the dimension cap + * (not the legacy 1568px token budget) governs sizing. + */ + _budgetForCapture() { + const base = Agent.IMAGE_BUDGET; + const cap = Math.max(1, Math.min(2048, Number(this.maxImageDimension) || 1568)); + const tokensForCap = Math.ceil((cap / base.pxPerToken) * (cap / base.pxPerToken)); + // Defaults must preserve the pre-#311 behavior. The default cap (1568) + // maps to the legacy budget byte-for-byte — same per-side limit AND same + // total-token limit. + if (cap === base.maxTargetPx) { + return { ...base }; + } + return { + ...base, + maxTargetPx: cap, + maxTargetTokens: tokensForCap, + }; + } + + /** + * The `detail` value to attach to an OpenAI-style image_url block, driven by + * the `imageDetail` setting (issue #311). Returns null when the setting is + * 'auto' so the provider uses its own default; 'high' and 'low' pass through. + */ + _imageDetailField() { + return this.imageDetail === 'auto' ? null : this.imageDetail; + } + + /** + * Return a copy of `imageUrl` with a `detail` field merged in when the user + * has chosen a non-auto image detail (issue #311). No-op for 'auto'. + */ + _withImageDetail(imageUrl) { + const detail = this._imageDetailField(); + return detail ? { ...imageUrl, detail } : imageUrl; + } + /** * Byte-ceiling-only re-encode: preserves dimensions, just drops JPEG * quality until bytes fit. Useful when you've already decided the @@ -2833,14 +2887,47 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d return { ...shot, blankFrameRetry: meta }; } + /** + * Whether another automatic screenshot is allowed under maxScreenshotsPerTurn + * (issue #311). 0 means unlimited. Does not mutate the counter. + */ + _canTakeAutoScreenshot(tabId) { + const cap = Number(this.maxScreenshotsPerTurn) || 0; + if (cap <= 0) return true; + return (this.autoScreenshotCount.get(tabId) || 0) < cap; + } + + /** + * Record a successful automatic screenshot against the per-turn budget. + * No-op when the budget is unlimited. + */ + _recordAutoScreenshot(tabId) { + const cap = Number(this.maxScreenshotsPerTurn) || 0; + if (cap <= 0) return; + this.autoScreenshotCount.set(tabId, (this.autoScreenshotCount.get(tabId) || 0) + 1); + } + + /** + * Capture an automatic screenshot only when the per-turn budget allows it. + * Check-then-capture-then-increment so a failed capture does not burn a slot, + * and both the initial viewport shot and post-action shots share one counter. + */ + async _captureBudgetedAutoScreenshot(tabId, opts = {}) { + if (!this._canTakeAutoScreenshot(tabId)) return null; + const shot = await this._captureAutoScreenshot(tabId, opts); + if (shot) this._recordAutoScreenshot(tabId); + return shot; + } + /** * Capture a viewport screenshot via the WebExtension tabs API. Firefox * supports `scale: 1` on captureVisibleTab to force a CSS-pixel-aligned * image (otherwise it captures at devicePixelRatio, causing the same * coordinate-mismatch loop chrome had pre-1.5.1). Returns - * { dataUrl, width, height } in CSS pixels, or null on failure. + * { dataUrl, width, height } in (possibly budget-resized) pixels, or null. + * `opts` accepted for Chrome call-site parity; capture is always CSS-locked. */ - async _captureAutoScreenshot(tabId) { + async _captureAutoScreenshot(tabId, _opts = {}) { try { const tab = await browser.tabs.get(tabId); if (!tab) return null; @@ -2853,6 +2940,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const probe = await this._captureViewportProbe(tabId); const w = Math.max(1, Math.round(probe?.innerWidth || 1024)); const h = Math.max(1, Math.round(probe?.innerHeight || 768)); + const budget = this._budgetForCapture(); const captureOnce = async () => { // scale: 1 forces 1 image pixel per CSS pixel (Firefox-specific option, // ignored by Chrome but Chrome path uses CDP anyway). @@ -2869,7 +2957,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // lets us downsize during capture (scale:1 is viewport-lock, not a // factor). So we capture at CSS size and shrink via DOM canvas to // the token budget. On small viewports this is a no-op fast-exit. - const shrunk = await this._shrinkImageForBudget(rawDataUrl, w, h); + const shrunk = await this._shrinkImageForBudget(rawDataUrl, w, h, budget); let dataUrl = shrunk.dataUrl; if (this.screenshotRedaction) { dataUrl = await this._redactScreenshotDataUrl(tabId, dataUrl, { coordinateSpace: 'viewport' }); @@ -2910,7 +2998,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: 'Describe this screenshot of the current browser viewport for a web-automation agent. Follow the format in the system prompt.' }, - { type: 'image_url', image_url: { url: dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: dataUrl }) }, ], }, ]; @@ -3020,11 +3108,23 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d }) ); if (!cropDataUrl) return null; - let dataUrl = await this._compressJpegToByteCeiling(cropDataUrl); + // Model-facing path honors maxImageDimension (issue #311). Keep the raw + // `cropDataUrl` at full CSS resolution for the local download crop; + // `_locateVisibleMediaWithVision` maps vision boxes back to that space. + const shrunk = await this._shrinkImageForBudget(cropDataUrl, width, height, this._budgetForCapture()); + let dataUrl = shrunk.dataUrl; if (this.screenshotRedaction) { dataUrl = await this._redactScreenshotDataUrl(tabId, dataUrl, { coordinateSpace: 'viewport' }); } - return { dataUrl, cropDataUrl, width, height, coordAligned: true }; + return { + dataUrl, + cropDataUrl, + width, + height, + visionWidth: shrunk.width, + visionHeight: shrunk.height, + coordAligned: true, + }; } catch (_) { const fallback = await this._captureAutoScreenshot(tabId); return fallback ? { ...fallback, cropDataUrl: fallback.dataUrl } : null; @@ -3047,13 +3147,31 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d } const target = ['image', 'video', 'media'].includes(opts.target) ? opts.target : 'media'; - const width = Math.max(1, Math.round(screenshot.width || 0)); - const height = Math.max(1, Math.round(screenshot.height || 0)); + // Original crop/CSS space (used to map the vision box back for cropping). + const origW = Math.max(1, Math.round(screenshot.width || 0)); + const origH = Math.max(1, Math.round(screenshot.height || 0)); + // Prefer already-budgeted vision dims from capture — re-shrinking with CSS + // dims double-encodes JPEG and can desync scale (issue #311 review). + let visionDataUrl; + let visionW; + let visionH; + if (screenshot.visionWidth && screenshot.visionHeight) { + visionDataUrl = screenshot.dataUrl; + visionW = Math.max(1, Math.round(screenshot.visionWidth)); + visionH = Math.max(1, Math.round(screenshot.visionHeight)); + } else { + const shrunk = await this._shrinkImageForBudget( + screenshot.dataUrl, origW, origH, this._budgetForCapture(), + ); + visionDataUrl = shrunk.dataUrl; + visionW = Math.max(1, Math.round(shrunk.width || origW)); + visionH = Math.max(1, Math.round(shrunk.height || origH)); + } const started = Date.now(); const runId = this.currentRunId.get(tabId); const costState = opts.costState || this.currentCostState.get(tabId) || null; const prompt = [ - `Image size: ${width}x${height} pixels.`, + `Image size: ${visionW}x${visionH} pixels.`, `Task: locate the single visible ${target} the user most likely means by "this image", "this video", or "this media" on the current page.`, 'Return JSON only with this exact shape:', '{"found":true,"x":0,"y":0,"width":100,"height":100,"confidence":0.9,"mediaType":"image","reason":"largest central visible media"}', @@ -3067,7 +3185,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: prompt }, - { type: 'image_url', image_url: { url: screenshot.dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: visionDataUrl }) }, ], }, ], { @@ -3077,9 +3195,19 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d }, costState); const raw = res?.content || ''; - const rect = Agent._normalizeVisibleMediaLocation(raw, { width, height }); - if (!rect) throw new Error('vision model did not return a usable media box'); - if (rect.confidence < 0.45) throw new Error(`vision confidence too low (${rect.confidence})`); + const visionRect = Agent._normalizeVisibleMediaLocation(raw, { width: visionW, height: visionH }); + if (!visionRect) throw new Error('vision model did not return a usable media box'); + if (visionRect.confidence < 0.45) throw new Error(`vision confidence too low (${visionRect.confidence})`); + // Map vision-image pixels back to the original cropDataUrl coordinate space. + const scaleX = origW / visionW; + const scaleY = origH / visionH; + const rect = { + ...visionRect, + x: Math.round(visionRect.x * scaleX), + y: Math.round(visionRect.y * scaleY), + width: Math.round(visionRect.width * scaleX), + height: Math.round(visionRect.height * scaleY), + }; const latencyMs = Date.now() - started; trace.recordVisionSubCall(runId, { context: 'download_social_media_visible_media', @@ -3232,7 +3360,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d return { role: 'user', content: contextLine + userMessage }; } - const shot = await this._captureAutoScreenshot(tabId); + const shot = await this._captureBudgetedAutoScreenshot(tabId); if (!shot) return { role: 'user', content: contextLine + userMessage }; // Vision-model path: sub-call the dedicated vision model, drop a text @@ -3261,7 +3389,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d role: 'user', content: [ { type: 'text', text: contextLine + screenshotNote + userMessage }, - { type: 'image_url', image_url: { url: shot.dataUrl } }, + { type: 'image_url', image_url: this._withImageDetail({ url: shot.dataUrl }) }, ], }; } @@ -4608,6 +4736,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d this.progressSessions.delete(tabId); this.mastodonStates.delete(tabId); this.lastAutoScreenshotTs.delete(tabId); + this.autoScreenshotCount.delete(tabId); this.lastSeenAdapter.delete(tabId); this._doneBlockCount.delete(tabId); this._recentSubmitClicks.delete(tabId); @@ -7383,7 +7512,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // Shrink to the vision budget before handing the image to the // model. Same two-stage dance as Chrome: decode → pick target dims // → draw at target → iterative JPEG quality until bytes fit. - const shrunk = await this._shrinkImageForBudget(rawUrl, 0, 0); + // Honors user maxImageDimension (issue #311). + const shrunk = await this._shrinkImageForBudget(rawUrl, 0, 0, this._budgetForCapture()); return { dataUrl: shrunk.dataUrl, description: `Screenshot captured (${shrunk.dataUrl.length} base64 chars, ${shrunk.width}×${shrunk.height})`, @@ -8002,6 +8132,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d let verifyShotUrl = await this._withIndicatorsHidden(tabId, () => browser.tabs.captureVisibleTab(tab.windowId, { format: 'png', quality: 80 }) ); + // Budget-resize for the model (issue #311 maxImageDimension). + verifyShotUrl = (await this._shrinkImageForBudget(verifyShotUrl, 0, 0, this._budgetForCapture())).dataUrl; // Local screenshot redaction (issue #312): pixelate form fields + // email/phone text BEFORE the image reaches the model. if (this.screenshotRedaction) { @@ -8489,7 +8621,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d * provider — the caller surfaces `error` as the turn's plain-text response, * without ever pushing the message to the conversation. */ - _applyAttachments(enriched, attachments, provider, options = {}) { + async _applyAttachments(enriched, attachments, provider, options = {}) { const blocks = []; const textAttachmentCount = (attachments || []).filter(att => att?.kind === 'text').length; let textBudgetRemaining = this._textAttachmentContentBudget(provider, { ...options, enriched }); @@ -8502,7 +8634,11 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d error: `The active provider (${provider?.name || 'unknown'}) does not support image attachments. Switch to a vision-capable model (e.g. Claude 3+, GPT-4o) or remove the attached image and try again.`, }; } - blocks.push({ type: 'image_url', image_url: { url: att.dataUrl } }); + // Budget-resize a model-facing copy; leave the original attachment + // untouched so the UI/history still has the user-picked full image + // (issue #311 maxImageDimension). + const shrunk = await this._shrinkImageForBudget(att.dataUrl, 0, 0, this._budgetForCapture()); + blocks.push({ type: 'image_url', image_url: this._withImageDetail({ url: shrunk.dataUrl }) }); } else if (att.kind === 'document') { if (!provider?.supportsDocuments) { return { @@ -8536,6 +8672,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d async _processMessageInner(tabId, userMessage, onUpdate, mode, attachments = [], runOptions = {}) { await this._hydrate(tabId); + // Reset the per-turn auto-screenshot budget (issue #311) for a fresh turn. + this.autoScreenshotCount.delete(tabId); const messages = this.getConversation(tabId, mode); // Scheduled resumes get the live ledger appended at fire time, so the // model's first turn sees current row state even if it never calls @@ -8576,7 +8714,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // agent run, and the message must never be pushed to history this way. if (attachments && attachments.length) { const canUseScratchpadTool = this._isActionMode(mode); - const attachResult = this._applyAttachments(enriched, attachments, provider, { + const attachResult = await this._applyAttachments(enriched, attachments, provider, { canUseScratchpadTool, tabId, messages, @@ -8942,6 +9080,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d async _processMessageStreamInner(tabId, userMessage, onUpdate, mode, runOptions = {}) { await this._hydrate(tabId); + // Reset the per-turn auto-screenshot budget (issue #311) for a fresh turn. + this.autoScreenshotCount.delete(tabId); const messages = this.getConversation(tabId, mode); const costState = this._newCostRunState(); this.currentCostState.set(tabId, costState); diff --git a/src/firefox/src/background.js b/src/firefox/src/background.js index 05584e786..88db06fb9 100644 --- a/src/firefox/src/background.js +++ b/src/firefox/src/background.js @@ -198,6 +198,17 @@ async function loadScreenshotRedaction() { } const screenshotRedactionReady = loadScreenshotRedaction().catch(() => {}); +// Image budget (issue #311): screenshot quality + how many screenshots the +// agent may capture per turn, and the max image dimension. Defaults preserve +// the previous behavior (auto detail, unlimited screenshots, 1568px cap). +async function loadImageBudget() { + const stored = await browser.storage.local.get(['imageDetail', 'maxScreenshotsPerTurn', 'maxImageDimension']); + if (stored.imageDetail != null) agent.imageDetail = stored.imageDetail; + if (stored.maxScreenshotsPerTurn != null) agent.maxScreenshotsPerTurn = stored.maxScreenshotsPerTurn; + if (stored.maxImageDimension != null) agent.maxImageDimension = stored.maxImageDimension; +} +const imageBudgetReady = loadImageBudget().catch(() => {}); + async function syncAgentUserMemoryFromStorage() { const [store, settings] = await Promise.all([ userMemoryStore.load(), @@ -717,6 +728,15 @@ browser.storage.onChanged.addListener((changes) => { if (changes.screenshotRedaction) { agent.screenshotRedaction = !!changes.screenshotRedaction.newValue; } + if (changes.imageDetail) { + agent.imageDetail = changes.imageDetail.newValue; + } + if (changes.maxScreenshotsPerTurn) { + agent.maxScreenshotsPerTurn = changes.maxScreenshotsPerTurn.newValue; + } + if (changes.maxImageDimension) { + agent.maxImageDimension = changes.maxImageDimension.newValue; + } if (changes.profileText) { agent.profileText = changes.profileText.newValue || ''; refreshPrompts = true; @@ -1341,6 +1361,7 @@ async function handleMessage(msg, sender) { // onChanged keeps them in sync afterward. await Promise.all([planBeforeActReady, planReviewReady, customSkillsReady, userMemoryReady]); await screenshotRedactionReady; + await imageBudgetReady; switch (msg.action) { case 'profile_sync_state': return { ok: true, ...(await profileSync.state()) }; diff --git a/src/firefox/src/ui/locales/ar.js b/src/firefox/src/ui/locales/ar.js index 55bb5cad4..b154e48a0 100644 --- a/src/firefox/src/ui/locales/ar.js +++ b/src/firefox/src/ui/locales/ar.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "لا توجد ذاكرة محفوظة بهذا المعرّف.", "st.memory.security_html": "الخصوصية: تُخزَّن ذاكرة المستخدم كنص عادي في ملف تعريف المتصفح هذا. عند تمكينها، تُرسل سجلات الذاكرة النشطة إلى موفّر LLM الذي تضبطه كجزء من مطالبة النظام. لا تخزّن هنا كلمات المرور أو مفاتيح API أو الرموز المميزة أو رموز الاسترداد أو الأسرار الحساسة.", "hist.filter.clear": "مسح عامل التصفية وعرض كل المحادثات", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "تعتيم لقطات الشاشة", "st.redaction.toggle.label": "إخفاء المحتوى الحساس في لقطات الشاشة", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/en.js b/src/firefox/src/ui/locales/en.js index ad097450c..02993cf4d 100644 --- a/src/firefox/src/ui/locales/en.js +++ b/src/firefox/src/ui/locales/en.js @@ -527,6 +527,21 @@ export default { 'st.transcription.failed': 'Failed: {error}', 'st.transcription.fill_required': 'Fill in Base URL and Model first.', + // Image budget (issue #311): screenshot quality + capture limits. + 'st.imageBudget.heading': 'Image budget', + 'st.imageBudget.desc': 'Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.', + 'st.imageBudget.detail.label': 'Image detail', + 'st.imageBudget.detail.desc': 'Vision image detail sent to the model. "high" keeps more detail (more tokens, higher cost); "low" sends a smaller, cheaper image; "auto" lets the provider decide. Provider-dependent.', + 'st.imageBudget.detail.high': 'High (more detail, more cost)', + 'st.imageBudget.detail.low': 'Low (cheaper, less detail)', + 'st.imageBudget.detail.auto': 'Auto (provider default)', + 'st.imageBudget.maxPerTurn.label': 'Max screenshots per turn', + 'st.imageBudget.maxPerTurn.desc': 'How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.', + 'st.imageBudget.maxPerTurn.unlimited': 'Unlimited', + 'st.imageBudget.maxDimension.label': 'Max image dimension', + 'st.imageBudget.maxDimension.desc': 'Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.', + 'st.imageBudget.warning': '⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. "Image detail" is honored by OpenAI-style endpoints; other providers may ignore it.', + // Screenshot redaction (issue #312): local, best-effort PII blurring that // runs in-browser before any screenshot reaches a vision model. 'st.redaction.heading': 'Screenshot redaction', diff --git a/src/firefox/src/ui/locales/es.js b/src/firefox/src/ui/locales/es.js index 91dbbb691..c00fcdd85 100644 --- a/src/firefox/src/ui/locales/es.js +++ b/src/firefox/src/ui/locales/es.js @@ -699,6 +699,21 @@ export default { "st.memory.reason.not_found": "Ninguna memoria guardada tiene ese ID.", "st.memory.security_html": "Privacidad: la memoria del usuario se almacena como texto sin formato en este perfil del navegador. Cuando está activada, los registros de memoria activos se envían al proveedor de LLM que configures como parte de las instrucciones del sistema. No guardes aquí contraseñas, claves de API, tokens, códigos de recuperación ni secretos sensibles.", "hist.filter.clear": "Borrar el filtro y mostrar todas las conversaciones", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Redacción de capturas de pantalla", "st.redaction.toggle.label": "Redactar contenido sensible en las capturas de pantalla", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/fr.js b/src/firefox/src/ui/locales/fr.js index 4b4b517e9..493c2b7d3 100644 --- a/src/firefox/src/ui/locales/fr.js +++ b/src/firefox/src/ui/locales/fr.js @@ -699,6 +699,21 @@ export default { "st.memory.reason.not_found": "Aucune mémoire enregistrée ne possède cet identifiant.", "st.memory.security_html": "Confidentialité : la mémoire utilisateur est stockée en texte brut dans ce profil de navigateur. Lorsqu’elle est activée, les enregistrements de mémoire actifs sont envoyés au fournisseur LLM configuré dans l’invite système. N’y enregistrez pas de mots de passe, clés API, jetons, codes de récupération ou secrets sensibles.", "hist.filter.clear": "Effacer le filtre et afficher toutes les conversations", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Floutage des captures d'écran", "st.redaction.toggle.label": "Flouter le contenu sensible dans les captures d'écran", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/he.js b/src/firefox/src/ui/locales/he.js index 8587e28e1..64010f13a 100644 --- a/src/firefox/src/ui/locales/he.js +++ b/src/firefox/src/ui/locales/he.js @@ -653,6 +653,21 @@ export default { "tr.event.result": "תוֹצָאָה", "tr.event.step": "שָׁלָב {step}", "sp.perm.verb.record": "להקליט את הכרטיסייה (ואת המיקרופון) באתר", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "טשטוש צילומי מסך", "st.redaction.toggle.label": "טשטש תוכן רגיש בצילומי מסך", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/id.js b/src/firefox/src/ui/locales/id.js index 7d7f97335..4251c27a9 100644 --- a/src/firefox/src/ui/locales/id.js +++ b/src/firefox/src/ui/locales/id.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "Tidak ada memori tersimpan dengan ID tersebut.", "st.memory.security_html": "Privasi: memori pengguna disimpan sebagai teks biasa di profil peramban ini. Saat diaktifkan, catatan memori aktif dikirim ke penyedia LLM yang Anda konfigurasikan sebagai bagian dari prompt sistem. Jangan simpan kata sandi, kunci API, token, kode pemulihan, atau rahasia sensitif di sini.", "hist.filter.clear": "Bersihkan filter dan tampilkan semua percakapan", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Penyamaran tangkapan layar", "st.redaction.toggle.label": "Samarkan konten sensitif pada tangkapan layar", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/ja.js b/src/firefox/src/ui/locales/ja.js index c3b137181..e1135fd4a 100644 --- a/src/firefox/src/ui/locales/ja.js +++ b/src/firefox/src/ui/locales/ja.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "その ID の保存済みメモリはありません。", "st.memory.security_html": "プライバシー: ユーザーメモリは、このブラウザープロフィールにプレーンテキストで保存されます。有効にすると、有効なメモリ記録がシステムプロンプトの一部として、設定した LLM プロバイダーに送信されます。パスワード、API キー、トークン、復旧コード、機密情報は保存しないでください。", "hist.filter.clear": "フィルターを消去してすべての会話を表示", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "スクリーンショットの黒塗り", "st.redaction.toggle.label": "スクリーンショット内の機密情報を黒塗りする", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/ko.js b/src/firefox/src/ui/locales/ko.js index 49774062b..45af36646 100644 --- a/src/firefox/src/ui/locales/ko.js +++ b/src/firefox/src/ui/locales/ko.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "해당 ID의 저장된 메모리가 없습니다.", "st.memory.security_html": "개인정보 보호: 사용자 메모리는 이 브라우저 프로필에 일반 텍스트로 저장됩니다. 사용하면 활성 메모리 기록이 시스템 프롬프트의 일부로 설정한 LLM 공급자에게 전송됩니다. 비밀번호, API 키, 토큰, 복구 코드 또는 민감한 비밀 정보는 저장하지 마세요.", "hist.filter.clear": "필터를 지우고 모든 대화 표시", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "스크린샷 마스킹", "st.redaction.toggle.label": "스크린샷의 민감한 콘텐츠 마스킹", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/ms.js b/src/firefox/src/ui/locales/ms.js index 924272893..da4231a16 100644 --- a/src/firefox/src/ui/locales/ms.js +++ b/src/firefox/src/ui/locales/ms.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "Tiada memori yang disimpan dengan ID tersebut.", "st.memory.security_html": "Privasi: memori pengguna disimpan sebagai teks biasa dalam profil pelayar ini. Apabila diaktifkan, rekod memori aktif dihantar kepada pembekal LLM yang anda konfigurasikan sebagai sebahagian daripada system prompt. Jangan simpan kata laluan, kunci API, token, kod pemulihan atau rahsia sensitif di sini.", "hist.filter.clear": "Kosongkan penapis dan tunjukkan semua perbualan", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Penyamaran tangkapan skrin", "st.redaction.toggle.label": "Samarkan kandungan sensitif dalam tangkapan skrin", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/pl.js b/src/firefox/src/ui/locales/pl.js index 2183e7ac4..a9ac9c080 100644 --- a/src/firefox/src/ui/locales/pl.js +++ b/src/firefox/src/ui/locales/pl.js @@ -657,6 +657,21 @@ export default { "st.memory.reason.not_found": "Nie ma zapisanego wpisu o tym ID.", "st.memory.security_html": "Prywatność: pamięć użytkownika jest przechowywana jako zwykły tekst w tym profilu przeglądarki. Po włączeniu aktywne wpisy pamięci są wysyłane do skonfigurowanego dostawcy LLM jako część promptu systemowego. Nie zapisuj tutaj haseł, kluczy API, tokenów, kodów odzyskiwania ani poufnych sekretów.", "hist.filter.clear": "Wyczyść filtr i pokaż wszystkie rozmowy", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Redakcja zrzutów ekranu", "st.redaction.toggle.label": "Redaguj poufną treść na zrzutach ekranu", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/ru.js b/src/firefox/src/ui/locales/ru.js index c6938992d..692f8cc2f 100644 --- a/src/firefox/src/ui/locales/ru.js +++ b/src/firefox/src/ui/locales/ru.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "Сохранённой записи с таким ID нет.", "st.memory.security_html": "Конфиденциальность: память пользователя хранится открытым текстом в этом профиле браузера. Когда она включена, активные записи памяти отправляются выбранному провайдеру LLM как часть системного промпта. Не храните здесь пароли, API-ключи, токены, коды восстановления или другие конфиденциальные секреты.", "hist.filter.clear": "Очистить фильтр и показать все разговоры", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Редактирование скриншотов", "st.redaction.toggle.label": "Скрывать чувствительный контент на скриншотах", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/th.js b/src/firefox/src/ui/locales/th.js index 2ea3e4945..a260b1170 100644 --- a/src/firefox/src/ui/locales/th.js +++ b/src/firefox/src/ui/locales/th.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "ไม่มีหน่วยความจำที่บันทึกไว้ด้วย ID นี้", "st.memory.security_html": "ความเป็นส่วนตัว: หน่วยความจำผู้ใช้ถูกเก็บเป็นข้อความธรรมดาในโปรไฟล์เบราว์เซอร์นี้ เมื่อเปิดใช้งาน บันทึกหน่วยความจำที่ใช้งานอยู่จะถูกส่งไปยังผู้ให้บริการ LLM ที่คุณตั้งค่าไว้โดยเป็นส่วนหนึ่งของ system prompt อย่าเก็บรหัสผ่าน คีย์ API โทเค็น รหัสกู้คืน หรือข้อมูลลับที่ละเอียดอ่อนไว้ที่นี่", "hist.filter.clear": "ล้างตัวกรองและแสดงการสนทนาทั้งหมด", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "การเบลอภาพหน้าจอ", "st.redaction.toggle.label": "เบลอเนื้อหาที่ละเอียดอ่อนในภาพหน้าจอ", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/tl.js b/src/firefox/src/ui/locales/tl.js index cc01d9eb6..ff476e8ca 100644 --- a/src/firefox/src/ui/locales/tl.js +++ b/src/firefox/src/ui/locales/tl.js @@ -697,6 +697,21 @@ export default { "st.memory.reason.not_found": "Walang naka-save na memory na may ganoong ID.", "st.memory.security_html": "Privacy: naka-store bilang plain text ang memory ng user sa browser profile na ito. Kapag naka-enable, ipinapadala ang mga aktibong memory record sa naka-configure mong LLM provider bilang bahagi ng system prompt. Huwag mag-store dito ng mga password, API key, token, recovery code, o sensitibong lihim.", "hist.filter.clear": "I-clear ang filter at ipakita ang lahat ng pag-uusap", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Pagbura sa mga screenshot", "st.redaction.toggle.label": "Burahin ang sensitibong nilalaman sa mga screenshot", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/tr.js b/src/firefox/src/ui/locales/tr.js index 2d6e0bd93..3fae84086 100644 --- a/src/firefox/src/ui/locales/tr.js +++ b/src/firefox/src/ui/locales/tr.js @@ -696,6 +696,21 @@ export default { "st.memory.reason.not_found": "Bu kimliğe sahip kaydedilmiş bellek yok.", "st.memory.security_html": "Gizlilik: kullanıcı belleği bu tarayıcı profilinde düz metin olarak saklanır. Etkinleştirildiğinde aktif bellek kayıtları, sistem isteminin bir parçası olarak yapılandırdığınız LLM sağlayıcısına gönderilir. Burada parola, API anahtarı, token, kurtarma kodu veya hassas gizli bilgi saklamayın.", "hist.filter.clear": "Filtreyi temizle ve tüm konuşmaları göster", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Ekran görüntüsü sansürleme", "st.redaction.toggle.label": "Ekran görüntülerindeki hassas içeriği sansürle", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/uk.js b/src/firefox/src/ui/locales/uk.js index f9eb7fb8b..700a621d4 100644 --- a/src/firefox/src/ui/locales/uk.js +++ b/src/firefox/src/ui/locales/uk.js @@ -698,6 +698,21 @@ export default { "st.memory.reason.not_found": "Збереженого запису з таким ID немає.", "st.memory.security_html": "Конфіденційність: пам’ять користувача зберігається відкритим текстом у цьому профілі браузера. Коли її ввімкнено, активні записи пам’яті надсилаються вибраному провайдеру LLM як частина системного промпту. Не зберігайте тут паролі, ключі API, токени, коди відновлення чи інші конфіденційні секрети.", "hist.filter.clear": "Очистити фільтр і показати всі розмови", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "Редагування знімків екрана", "st.redaction.toggle.label": "Приховувати чутливий вміст на знімках екрана", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/locales/zh.js b/src/firefox/src/ui/locales/zh.js index cd323c3a1..421a4de07 100644 --- a/src/firefox/src/ui/locales/zh.js +++ b/src/firefox/src/ui/locales/zh.js @@ -699,6 +699,21 @@ export default { "st.memory.reason.not_found": "没有使用该 ID 的已保存记忆。", "st.memory.security_html": "隐私:用户记忆以明文形式存储在此浏览器配置文件中。启用后,活动记忆记录会作为系统提示词的一部分发送给您配置的 LLM 提供商。请勿在此存储密码、API 密钥、令牌、恢复代码或敏感机密信息。", "hist.filter.clear": "清除筛选并显示所有对话", + // Image budget (issue #311): screenshot quality + capture limits. + "st.imageBudget.heading": "Image budget", + "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", + "st.imageBudget.detail.label": "Image detail", + "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", + "st.imageBudget.detail.high": "High (more detail, more cost)", + "st.imageBudget.detail.low": "Low (cheaper, less detail)", + "st.imageBudget.detail.auto": "Auto (provider default)", + "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", + "st.imageBudget.maxPerTurn.unlimited": "Unlimited", + "st.imageBudget.maxDimension.label": "Max image dimension", + "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", + "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.redaction.heading": "截图打码", "st.redaction.toggle.label": "对截图中的敏感内容进行打码", "st.redaction.toggle.desc": "Before a screenshot is sent to a vision model, blur form fields and text that looks like an email or phone number. Detection runs entirely on your device \u2014 nothing extra is transmitted.", diff --git a/src/firefox/src/ui/settings.html b/src/firefox/src/ui/settings.html index ff316efcf..1579a2f9f 100644 --- a/src/firefox/src/ui/settings.html +++ b/src/firefox/src/ui/settings.html @@ -1037,6 +1037,49 @@

+

+
+
+ +
+ + +
+
+ +
+ + +
+
+ +
+ + +
+
+ +
+
+

diff --git a/src/firefox/src/ui/settings.js b/src/firefox/src/ui/settings.js index e817ee48a..d2f2e4fcb 100644 --- a/src/firefox/src/ui/settings.js +++ b/src/firefox/src/ui/settings.js @@ -46,6 +46,9 @@ const costTotalLimitInput = document.getElementById('input-cost-total-limit'); const costSpentValueLabel = document.getElementById('cost-spent-value'); const btnResetCostSpend = document.getElementById('btn-reset-cost-spend'); const autoScreenshotSelect = document.getElementById('select-auto-screenshot'); +const imageDetailSelect = document.getElementById('select-image-detail'); +const maxScreenshotsSelect = document.getElementById('select-max-screenshots'); +const maxImageDimensionSelect = document.getElementById('select-max-image-dimension'); const siteAdaptersToggle = document.getElementById('toggle-site-adapters'); const voiceInputToggle = document.getElementById('toggle-voice-input'); const apiMutationObserverToggle = document.getElementById('toggle-api-mutation-observer'); @@ -352,7 +355,7 @@ async function init() { browser.storage.local.remove(['authToken', 'authEmail', 'authDefaultModel']).catch(() => {}); // Load display settings - const stored = await browser.storage.local.get(['verboseMode', 'selectionShortcutEnabled', 'screenshotFallback', 'maxAgentSteps', 'autoScreenshot', 'useSiteAdapters', 'voiceInputEnabled', 'apiMutationObserverEnabled', 'planBeforeActMode', 'planBeforeAct', 'planReviewMode', 'planReviewConfidenceThreshold', 'notifySound', 'completionConfetti', 'tracingEnabled', 'strictSecretMode', 'agentAllowLocalNetwork', 'scheduledTasksEnabled', 'scheduledRequireConsequentialConfirmation', 'providerFilter', 'requestTimeoutMs', 'costAllowanceSessionUsd', 'costAllowanceTotalUsd', 'cloudCostSpentUsd', 'screenshotRedaction']); + const stored = await browser.storage.local.get(['verboseMode', 'selectionShortcutEnabled', 'screenshotFallback', 'maxAgentSteps', 'autoScreenshot', 'useSiteAdapters', 'voiceInputEnabled', 'apiMutationObserverEnabled', 'planBeforeActMode', 'planBeforeAct', 'planReviewMode', 'planReviewConfidenceThreshold', 'notifySound', 'completionConfetti', 'tracingEnabled', 'strictSecretMode', 'agentAllowLocalNetwork', 'scheduledTasksEnabled', 'scheduledRequireConsequentialConfirmation', 'providerFilter', 'requestTimeoutMs', 'costAllowanceSessionUsd', 'costAllowanceTotalUsd', 'cloudCostSpentUsd', 'screenshotRedaction', 'imageDetail', 'maxScreenshotsPerTurn', 'maxImageDimension']); if (typeof stored.providerFilter === 'string' && ['all','local','cloud','router'].includes(stored.providerFilter)) { providerFilter = stored.providerFilter; } @@ -376,6 +379,9 @@ async function init() { requestTimeoutValueLabel.textContent = tSec + 's'; } if (autoScreenshotSelect) autoScreenshotSelect.value = stored.autoScreenshot || 'state_change'; + if (imageDetailSelect) imageDetailSelect.value = stored.imageDetail || 'auto'; + if (maxScreenshotsSelect) maxScreenshotsSelect.value = String(stored.maxScreenshotsPerTurn != null ? stored.maxScreenshotsPerTurn : 0); + if (maxImageDimensionSelect) maxImageDimensionSelect.value = String(stored.maxImageDimension || 1568); if (siteAdaptersToggle) siteAdaptersToggle.checked = stored.useSiteAdapters ?? true; if (voiceInputToggle) voiceInputToggle.checked = stored.voiceInputEnabled ?? true; if (apiMutationObserverToggle) apiMutationObserverToggle.checked = stored.apiMutationObserverEnabled === true; @@ -797,6 +803,18 @@ autoScreenshotSelect?.addEventListener('change', async () => { await browser.storage.local.set({ autoScreenshot: autoScreenshotSelect.value }).catch(() => {}); }); +imageDetailSelect?.addEventListener('change', async () => { + await browser.storage.local.set({ imageDetail: imageDetailSelect.value }).catch(() => {}); +}); + +maxScreenshotsSelect?.addEventListener('change', async () => { + await browser.storage.local.set({ maxScreenshotsPerTurn: parseInt(maxScreenshotsSelect.value, 10) || 0 }).catch(() => {}); +}); + +maxImageDimensionSelect?.addEventListener('change', async () => { + await browser.storage.local.set({ maxImageDimension: parseInt(maxImageDimensionSelect.value, 10) || 1568 }).catch(() => {}); +}); + siteAdaptersToggle?.addEventListener('change', async () => { await browser.storage.local.set({ useSiteAdapters: siteAdaptersToggle.checked }).catch(() => {}); }); diff --git a/test/run.js b/test/run.js index 654aa819d..e7fc3b3d0 100644 --- a/test/run.js +++ b/test/run.js @@ -901,8 +901,10 @@ test('remaining model-facing screenshot fallbacks apply redaction', () => { test('firefox auto and media screenshot helpers redact model-facing data URLs', () => { const source = fs.readFileSync(path.join(ROOT, 'src/firefox/src/agent/agent.js'), 'utf8'); - const autoStart = source.indexOf('async _captureAutoScreenshot(tabId)'); + // Signature may include optional opts for Chrome call-site parity. + const autoStart = source.indexOf('async _captureAutoScreenshot(tabId'); const autoEnd = source.indexOf('async _describeScreenshot', autoStart); + assert.ok(autoStart >= 0 && autoEnd > autoStart, 'firefox auto capture method not found'); const autoBody = source.slice(autoStart, autoEnd); assert.match( autoBody, @@ -912,11 +914,12 @@ test('firefox auto and media screenshot helpers redact model-facing data URLs', const mediaStart = source.indexOf('async _captureVisibleMediaScreenshot(tabId)'); const mediaEnd = source.indexOf('async _locateVisibleMediaWithVision', mediaStart); + assert.ok(mediaStart >= 0 && mediaEnd > mediaStart, 'firefox media capture method not found'); const mediaBody = source.slice(mediaStart, mediaEnd); assert.match( mediaBody, - /let dataUrl = await this\._compressJpegToByteCeiling\(cropDataUrl\);[\s\S]*?if \(this\.screenshotRedaction\) \{[\s\S]*?dataUrl = await this\._redactScreenshotDataUrl\(tabId, dataUrl, \{ coordinateSpace: 'viewport' \}\);[\s\S]*?return \{ dataUrl, cropDataUrl, width, height, coordAligned: true \};/, - 'firefox visible-media localization should redact the model-facing screenshot while keeping the raw crop source local' + /const shrunk = await this\._shrinkImageForBudget\(cropDataUrl, width, height, this\._budgetForCapture\(\)\);[\s\S]*?let dataUrl = shrunk\.dataUrl;[\s\S]*?if \(this\.screenshotRedaction\) \{[\s\S]*?dataUrl = await this\._redactScreenshotDataUrl\(tabId, dataUrl, \{ coordinateSpace: 'viewport' \}\);[\s\S]*?return \{[\s\S]*?dataUrl,[\s\S]*?cropDataUrl,[\s\S]*?width,[\s\S]*?height,[\s\S]*?visionWidth: shrunk\.width,[\s\S]*?visionHeight: shrunk\.height,/, + 'firefox visible-media localization should budget+redact the model-facing screenshot while keeping the raw crop source local' ); }); @@ -2581,6 +2584,87 @@ test('custom budget is honored', () => { assert.ok(estimateImageTokens(w, h, 28) <= 400); }); +test('image budget helpers: default budget equals IMAGE_BUDGET', () => { + for (const AgentClass of [AgentCh, AgentFx]) { + const agent = new AgentClass({}); + assert.equal(agent.imageDetail, 'auto', `${AgentClass.name}: default imageDetail`); + assert.equal(agent.maxScreenshotsPerTurn, 0, `${AgentClass.name}: unlimited default`); + assert.equal(agent.maxImageDimension, 1568, `${AgentClass.name}: default maxImageDimension`); + const budget = agent._budgetForCapture(); + assert.equal(budget.maxTargetPx, AgentClass.IMAGE_BUDGET.maxTargetPx); + assert.equal(budget.maxTargetTokens, AgentClass.IMAGE_BUDGET.maxTargetTokens); + assert.equal(budget.pxPerToken, AgentClass.IMAGE_BUDGET.pxPerToken); + } +}); + +test('image budget helpers: lower/higher maxImageDimension remaps token cap', () => { + for (const AgentClass of [AgentCh, AgentFx]) { + const agent = new AgentClass({}); + agent.maxImageDimension = 512; + const low = agent._budgetForCapture(); + assert.equal(low.maxTargetPx, 512); + assert.equal(low.maxTargetTokens, Math.ceil((512 / 28) * (512 / 28))); + + agent.maxImageDimension = 2048; + const high = agent._budgetForCapture(); + assert.equal(high.maxTargetPx, 2048); + assert.equal(high.maxTargetTokens, Math.ceil((2048 / 28) * (2048 / 28))); + + agent.maxImageDimension = 0; // coerce to default + const coerced = agent._budgetForCapture(); + assert.equal(coerced.maxTargetPx, AgentClass.IMAGE_BUDGET.maxTargetPx); + } +}); + +test('image budget helpers: _withImageDetail only when non-auto', () => { + for (const AgentClass of [AgentCh, AgentFx]) { + const agent = new AgentClass({}); + const base = { url: 'data:image/jpeg;base64,xx' }; + assert.deepEqual(agent._withImageDetail(base), base, `${AgentClass.name}: auto omits detail`); + assert.equal(agent._imageDetailField(), null); + + agent.imageDetail = 'high'; + assert.deepEqual(agent._withImageDetail(base), { ...base, detail: 'high' }); + assert.equal(agent._imageDetailField(), 'high'); + + agent.imageDetail = 'low'; + assert.deepEqual(agent._withImageDetail(base), { ...base, detail: 'low' }); + } +}); + +test('image budget helpers: auto-screenshot counter + failed capture does not burn slot', async () => { + for (const AgentClass of [AgentCh, AgentFx]) { + const agent = new AgentClass({}); + const tabId = 42; + agent.maxScreenshotsPerTurn = 1; + + assert.equal(agent._canTakeAutoScreenshot(tabId), true); + agent._recordAutoScreenshot(tabId); + assert.equal(agent._canTakeAutoScreenshot(tabId), false); + assert.equal(agent.autoScreenshotCount.get(tabId), 1); + + // Failed capture must not increment (budgeted wrapper checks then captures). + agent.autoScreenshotCount.delete(tabId); + agent._captureAutoScreenshot = async () => null; + const missed = await agent._captureBudgetedAutoScreenshot(tabId); + assert.equal(missed, null); + assert.equal(agent.autoScreenshotCount.has(tabId), false, `${AgentClass.name}: failed capture must not burn slot`); + assert.equal(agent._canTakeAutoScreenshot(tabId), true); + + agent._captureAutoScreenshot = async () => ({ dataUrl: 'data:image/jpeg;base64,ok', width: 10, height: 10 }); + const first = await agent._captureBudgetedAutoScreenshot(tabId); + assert.ok(first); + assert.equal(agent.autoScreenshotCount.get(tabId), 1); + const second = await agent._captureBudgetedAutoScreenshot(tabId); + assert.equal(second, null, `${AgentClass.name}: limit 1 blocks second auto shot`); + + // Unlimited (0) never blocks. + agent.maxScreenshotsPerTurn = 0; + agent.autoScreenshotCount.set(tabId, 99); + assert.equal(agent._canTakeAutoScreenshot(tabId), true); + } +}); + test('existing dims under caps stay within the monotonic bound', () => { // Fuzz a range of common viewport sizes; invariant: output ≤ input on // every dimension, and output token count ≤ maxTargetTokens. From 8135c4da0683616c6882df3c01c8523b12a1c9a9 Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Mon, 13 Jul 2026 04:22:04 +0300 Subject: [PATCH 3/6] fix(agent): coord-aligned side-only budget + maxScreenshotsPerTurn skip signal Coord-aligned captures honor maxImageDimension per side without the vision token budget so common viewports stay 1:1 when under the cap. Exhausted per-turn auto-screenshot limits emit a warning, trusted note, and trace; settings copy no longer promises state-change captures after the budget. --- src/chrome/src/agent/agent.js | 82 +++++++++++++++++++++++++-------- src/chrome/src/ui/locales/ar.js | 2 +- src/chrome/src/ui/locales/en.js | 2 +- src/chrome/src/ui/locales/es.js | 2 +- src/chrome/src/ui/locales/fr.js | 2 +- src/chrome/src/ui/locales/he.js | 2 +- src/chrome/src/ui/locales/id.js | 2 +- src/chrome/src/ui/locales/ja.js | 2 +- src/chrome/src/ui/locales/ko.js | 2 +- src/chrome/src/ui/locales/ms.js | 2 +- src/chrome/src/ui/locales/pl.js | 2 +- src/chrome/src/ui/locales/ru.js | 2 +- src/chrome/src/ui/locales/th.js | 2 +- src/chrome/src/ui/locales/tl.js | 2 +- src/chrome/src/ui/locales/tr.js | 2 +- src/chrome/src/ui/locales/uk.js | 2 +- src/chrome/src/ui/locales/zh.js | 2 +- src/firefox/src/agent/agent.js | 54 ++++++++++++++++++++-- test/run.js | 49 ++++++++++++++++++++ 19 files changed, 176 insertions(+), 41 deletions(-) diff --git a/src/chrome/src/agent/agent.js b/src/chrome/src/agent/agent.js index e7fa635ee..716a33864 100644 --- a/src/chrome/src/agent/agent.js +++ b/src/chrome/src/agent/agent.js @@ -1780,6 +1780,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // Count toward maxScreenshotsPerTurn so a limit of 1 is a true per-turn // maximum (initial + post-action share the same budget). Issue #311. + // onUpdate may be null here (enrich runs before some callers wire UI); + // budget skips still try trace when a runId exists. const shot = await this._captureBudgetedAutoScreenshot(tabId); if (!shot) { return { role: 'user', content: contextLine + userMessage }; @@ -2612,7 +2614,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d await new Promise(r => setTimeout(r, 250)); // Shared budget check+increment (issue #311) — same helper as the // initial viewport capture so the configured value is a true max. - const shot = await this._captureBudgetedAutoScreenshot(tabId); + // Pass onUpdate + messages so a budget skip is not silent. + const shot = await this._captureBudgetedAutoScreenshot(tabId, { onUpdate, messages }); if (shot) { this.lastAutoScreenshotTs.set(tabId, Date.now()); // Pair the image with a textual list of visible clickables so @@ -3167,13 +3170,40 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d this.autoScreenshotCount.set(tabId, (this.autoScreenshotCount.get(tabId) || 0) + 1); } + /** + * Surface a maxScreenshotsPerTurn skip so the agent/user are not silently + * "blind" mid-turn (issue #311 review). Trusted note only — not page content. + */ + _notifyAutoScreenshotBudgetSkipped(tabId, { onUpdate = null, messages = null } = {}) { + const message = 'auto-screenshot skipped: maxScreenshotsPerTurn reached'; + try { + if (typeof onUpdate === 'function') onUpdate('warning', { message }); + } catch { /* ignore UI delivery failures */ } + try { + if (Array.isArray(messages)) { + messages.push({ role: 'user', content: `[${message}]` }); + } + } catch { /* ignore */ } + try { + const runId = this.currentRunId.get(tabId); + if (runId) { + trace.recordNote(runId, null, 'auto_screenshot_budget_skipped', { message }); + } + } catch { /* ignore */ } + } + /** * Capture an automatic screenshot only when the per-turn budget allows it. * Check-then-capture-then-increment so a failed capture does not burn a slot, * and both the initial viewport shot and post-action shots share one counter. + * When the budget blocks a capture, emits a warning/trace/trusted note so the + * skip is not silent (opts.onUpdate / opts.messages). */ async _captureBudgetedAutoScreenshot(tabId, opts = {}) { - if (!this._canTakeAutoScreenshot(tabId)) return null; + if (!this._canTakeAutoScreenshot(tabId)) { + this._notifyAutoScreenshotBudgetSkipped(tabId, opts); + return null; + } const shot = await this._captureAutoScreenshot(tabId, opts); if (shot) this._recordAutoScreenshot(tabId); return shot; @@ -3193,11 +3223,11 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const cssH = Math.max(1, Math.round(probe?.innerHeight || 768)); if (coordAligned) { - // Prefer 1:1 CSS↔image pixels so click({x,y}) lands correctly. When - // the CSS viewport exceeds maxImageDimension we must still honor the - // budget: resize for the model and report a scale transform so - // callers can map image coords back to CSS (issue #311). - const budget = this._budgetForCapture(); + // Prefer 1:1 CSS↔image pixels so click({x,y}) lands correctly. Cap only + // by maxImageDimension (per side), not the vision token budget — so a + // normal 1080p viewport stays 1:1 under the default 1568px cap (issue + // #311 review). When a side exceeds the cap, resize and report scale. + const budget = this._budgetForCoordAlignedCapture(); const captureOnce = async () => { const shot = await this._withIndicatorsHidden(tabId, () => cdpClient.sendCommand(tabId, 'Page.captureScreenshot', { @@ -3208,8 +3238,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d ); if (!shot?.data) return null; const rawDataUrl = `data:image/jpeg;base64,${shot.data}`; - const needsResize = cssW > budget.maxTargetPx || cssH > budget.maxTargetPx - || Agent._estimateImageTokens(cssW, cssH, budget.pxPerToken) > budget.maxTargetTokens; + const needsResize = cssW > budget.maxTargetPx || cssH > budget.maxTargetPx; if (needsResize) { const shrunk = await this._shrinkImageForBudget(rawDataUrl, cssW, cssH, budget); const redacted = await this._redactScreenshotDataUrl(tabId, shrunk.dataUrl, { coordinateSpace: 'viewport' }); @@ -4022,6 +4051,21 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d }; } + /** + * Budget for coord-aligned (1:1 CSS↔image) captures. Only the per-side + * `maxImageDimension` cap applies — the vision token budget does NOT force + * a downscale. So 1920×1080 stays 1:1 under the default 1568px cap; resize + * only when a side exceeds the cap (issue #311 review option a). + */ + _budgetForCoordAlignedCapture() { + const base = this._budgetForCapture(); + return { + ...base, + // Large enough that `_fitImageDimensions` is gated only by maxTargetPx. + maxTargetTokens: Number.MAX_SAFE_INTEGER, + }; + } + /** * The `detail` value to attach to an OpenAI-style image_url block, driven by * the `imageDetail` setting (issue #311). Returns null when the setting is @@ -8491,11 +8535,10 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const captureOnce = async () => { if (coordAligned) { - // Prefer CSS-pixel fidelity for click({x,y}). When the viewport - // exceeds maxImageDimension, resize for the budget and tell the - // model how to map image pixels back to CSS (issue #311). + // Prefer CSS-pixel fidelity for click({x,y}). Cap only by + // maxImageDimension (sides), not the token budget (issue #311). // PNG capture (lossless) so glyph edges stay sharp before re-encode. - const budget = this._budgetForCapture(); + const budget = this._budgetForCoordAlignedCapture(); const screenshot = await this._withIndicatorsHidden(tabId, () => cdpClient.sendCommand(tabId, 'Page.captureScreenshot', { format: 'png', @@ -8505,8 +8548,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d ); if (!screenshot?.data) return null; const rawUrl = `data:image/png;base64,${screenshot.data}`; - const needsResize = cssW > budget.maxTargetPx || cssH > budget.maxTargetPx - || Agent._estimateImageTokens(cssW, cssH, budget.pxPerToken) > budget.maxTargetTokens; + const needsResize = cssW > budget.maxTargetPx || cssH > budget.maxTargetPx; if (needsResize) { const shrunk = await this._shrinkImageForBudget(rawUrl, cssW, cssH, budget); const scaleX = (cssW / Math.max(1, shrunk.width)).toFixed(4); @@ -8571,11 +8613,11 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d description: `Screenshot captured via tabs API (${shrunk.dataUrl.length} bytes base64, resized to ${shrunk.width}×${shrunk.height})`, }; } - // coord_aligned tabs-API fallback: still honor maxImageDimension. - const needsResize = cssW > budget.maxTargetPx || cssH > budget.maxTargetPx - || Agent._estimateImageTokens(cssW, cssH, budget.pxPerToken) > budget.maxTargetTokens; + // coord_aligned tabs-API fallback: side cap only (not token budget). + const coordBudget = this._budgetForCoordAlignedCapture(); + const needsResize = cssW > coordBudget.maxTargetPx || cssH > coordBudget.maxTargetPx; if (needsResize) { - const shrunk = await this._shrinkImageForBudget(rawUrl, cssW, cssH, budget); + const shrunk = await this._shrinkImageForBudget(rawUrl, cssW, cssH, coordBudget); const scaleX = (cssW / Math.max(1, shrunk.width)).toFixed(4); const scaleY = (cssH / Math.max(1, shrunk.height)).toFixed(4); return { @@ -8583,7 +8625,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d description: `Screenshot captured via tabs API (${shrunk.dataUrl.length} bytes base64). CSS viewport ${cssW}×${cssH} downscaled to ${shrunk.width}×${shrunk.height} for maxImageDimension — multiply image-pixel coords by (${scaleX}, ${scaleY}) to get CSS click coords.`, }; } - const compressed = await this._compressJpegToByteCeiling(rawUrl, budget); + const compressed = await this._compressJpegToByteCeiling(rawUrl, coordBudget); return { dataUrl: compressed, description: `Screenshot captured via tabs API (${compressed.length} bytes base64, CSS-pixel aligned)`, diff --git a/src/chrome/src/ui/locales/ar.js b/src/chrome/src/ui/locales/ar.js index 15740759e..4fe5dbdae 100644 --- a/src/chrome/src/ui/locales/ar.js +++ b/src/chrome/src/ui/locales/ar.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/en.js b/src/chrome/src/ui/locales/en.js index 3670f4454..ebfbdcacf 100644 --- a/src/chrome/src/ui/locales/en.js +++ b/src/chrome/src/ui/locales/en.js @@ -551,7 +551,7 @@ export default { 'st.imageBudget.detail.low': 'Low (cheaper, less detail)', 'st.imageBudget.detail.auto': 'Auto (provider default)', 'st.imageBudget.maxPerTurn.label': 'Max screenshots per turn', - 'st.imageBudget.maxPerTurn.desc': 'How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.', + 'st.imageBudget.maxPerTurn.desc': 'How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.', 'st.imageBudget.maxPerTurn.unlimited': 'Unlimited', 'st.imageBudget.maxDimension.label': 'Max image dimension', 'st.imageBudget.maxDimension.desc': 'Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.', diff --git a/src/chrome/src/ui/locales/es.js b/src/chrome/src/ui/locales/es.js index acb69d232..5fd70c1fe 100644 --- a/src/chrome/src/ui/locales/es.js +++ b/src/chrome/src/ui/locales/es.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/fr.js b/src/chrome/src/ui/locales/fr.js index 1ce76fc1c..ec7a4eb9b 100644 --- a/src/chrome/src/ui/locales/fr.js +++ b/src/chrome/src/ui/locales/fr.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/he.js b/src/chrome/src/ui/locales/he.js index 303e6c84c..f0ba8e96c 100644 --- a/src/chrome/src/ui/locales/he.js +++ b/src/chrome/src/ui/locales/he.js @@ -665,7 +665,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/id.js b/src/chrome/src/ui/locales/id.js index f9bd6d25c..6eeb35c95 100644 --- a/src/chrome/src/ui/locales/id.js +++ b/src/chrome/src/ui/locales/id.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/ja.js b/src/chrome/src/ui/locales/ja.js index 09fe13b61..1101558d1 100644 --- a/src/chrome/src/ui/locales/ja.js +++ b/src/chrome/src/ui/locales/ja.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/ko.js b/src/chrome/src/ui/locales/ko.js index 1335835d2..595552e47 100644 --- a/src/chrome/src/ui/locales/ko.js +++ b/src/chrome/src/ui/locales/ko.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/ms.js b/src/chrome/src/ui/locales/ms.js index fa90ab941..335e401ad 100644 --- a/src/chrome/src/ui/locales/ms.js +++ b/src/chrome/src/ui/locales/ms.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/pl.js b/src/chrome/src/ui/locales/pl.js index 5e53d1911..0edb1a30c 100644 --- a/src/chrome/src/ui/locales/pl.js +++ b/src/chrome/src/ui/locales/pl.js @@ -672,7 +672,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/ru.js b/src/chrome/src/ui/locales/ru.js index d14683356..474f59c53 100644 --- a/src/chrome/src/ui/locales/ru.js +++ b/src/chrome/src/ui/locales/ru.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/th.js b/src/chrome/src/ui/locales/th.js index d743a81bb..7c20e6f72 100644 --- a/src/chrome/src/ui/locales/th.js +++ b/src/chrome/src/ui/locales/th.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/tl.js b/src/chrome/src/ui/locales/tl.js index 7ed7ff2a2..d9187e817 100644 --- a/src/chrome/src/ui/locales/tl.js +++ b/src/chrome/src/ui/locales/tl.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/tr.js b/src/chrome/src/ui/locales/tr.js index 5bcb3ee84..e0f3104f6 100644 --- a/src/chrome/src/ui/locales/tr.js +++ b/src/chrome/src/ui/locales/tr.js @@ -711,7 +711,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/uk.js b/src/chrome/src/ui/locales/uk.js index 98b89038f..62817cdf0 100644 --- a/src/chrome/src/ui/locales/uk.js +++ b/src/chrome/src/ui/locales/uk.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/chrome/src/ui/locales/zh.js b/src/chrome/src/ui/locales/zh.js index cd055fc65..1e1b7cdad 100644 --- a/src/chrome/src/ui/locales/zh.js +++ b/src/chrome/src/ui/locales/zh.js @@ -712,7 +712,7 @@ export default { "st.imageBudget.detail.low": "Low (cheaper, less detail)", "st.imageBudget.detail.auto": "Auto (provider default)", "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; the agent still captures at least when state changes.", + "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", "st.imageBudget.maxPerTurn.unlimited": "Unlimited", "st.imageBudget.maxDimension.label": "Max image dimension", "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", diff --git a/src/firefox/src/agent/agent.js b/src/firefox/src/agent/agent.js index b897e1d9c..f3af88c51 100644 --- a/src/firefox/src/agent/agent.js +++ b/src/firefox/src/agent/agent.js @@ -2197,7 +2197,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const lastTs = this.lastAutoScreenshotTs.get(tabId) || 0; if (Date.now() - lastTs >= 500) { await new Promise(r => setTimeout(r, 250)); - const shot = await this._captureBudgetedAutoScreenshot(tabId); + // Pass onUpdate + messages so a maxScreenshotsPerTurn skip is not silent. + const shot = await this._captureBudgetedAutoScreenshot(tabId, { onUpdate, messages }); if (shot) { this.lastAutoScreenshotTs.set(tabId, Date.now()); const visible = await this._getVisibleInteractiveElements(tabId); @@ -2432,6 +2433,20 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d }; } + /** + * Budget for CSS-pixel-aligned captures (Firefox always captures at scale:1). + * Only the per-side `maxImageDimension` cap applies — the vision token budget + * does NOT force a downscale. So 1920×1080 stays 1:1 under the default 1568px + * cap (issue #311 review option a). + */ + _budgetForCoordAlignedCapture() { + const base = this._budgetForCapture(); + return { + ...base, + maxTargetTokens: Number.MAX_SAFE_INTEGER, + }; + } + /** * The `detail` value to attach to an OpenAI-style image_url block, driven by * the `imageDetail` setting (issue #311). Returns null when the setting is @@ -2907,13 +2922,40 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d this.autoScreenshotCount.set(tabId, (this.autoScreenshotCount.get(tabId) || 0) + 1); } + /** + * Surface a maxScreenshotsPerTurn skip so the agent/user are not silently + * "blind" mid-turn (issue #311 review). Trusted note only — not page content. + */ + _notifyAutoScreenshotBudgetSkipped(tabId, { onUpdate = null, messages = null } = {}) { + const message = 'auto-screenshot skipped: maxScreenshotsPerTurn reached'; + try { + if (typeof onUpdate === 'function') onUpdate('warning', { message }); + } catch { /* ignore UI delivery failures */ } + try { + if (Array.isArray(messages)) { + messages.push({ role: 'user', content: `[${message}]` }); + } + } catch { /* ignore */ } + try { + const runId = this.currentRunId.get(tabId); + if (runId) { + trace.recordNote(runId, null, 'auto_screenshot_budget_skipped', { message }); + } + } catch { /* ignore */ } + } + /** * Capture an automatic screenshot only when the per-turn budget allows it. * Check-then-capture-then-increment so a failed capture does not burn a slot, * and both the initial viewport shot and post-action shots share one counter. + * When the budget blocks a capture, emits a warning/trace/trusted note so the + * skip is not silent (opts.onUpdate / opts.messages). */ async _captureBudgetedAutoScreenshot(tabId, opts = {}) { - if (!this._canTakeAutoScreenshot(tabId)) return null; + if (!this._canTakeAutoScreenshot(tabId)) { + this._notifyAutoScreenshotBudgetSkipped(tabId, opts); + return null; + } const shot = await this._captureAutoScreenshot(tabId, opts); if (shot) this._recordAutoScreenshot(tabId); return shot; @@ -2940,7 +2982,9 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const probe = await this._captureViewportProbe(tabId); const w = Math.max(1, Math.round(probe?.innerWidth || 1024)); const h = Math.max(1, Math.round(probe?.innerHeight || 768)); - const budget = this._budgetForCapture(); + // CSS-pixel aligned (scale:1): side cap only so 1080p stays 1:1 under the + // default 1568px maxImageDimension (issue #311 review option a). + const budget = this._budgetForCoordAlignedCapture(); const captureOnce = async () => { // scale: 1 forces 1 image pixel per CSS pixel (Firefox-specific option, // ignored by Chrome but Chrome path uses CDP anyway). @@ -2955,8 +2999,8 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // Firefox's captureVisibleTab doesn't take a clip/scale in a way that // lets us downsize during capture (scale:1 is viewport-lock, not a - // factor). So we capture at CSS size and shrink via DOM canvas to - // the token budget. On small viewports this is a no-op fast-exit. + // factor). Capture at CSS size; shrink only when a side exceeds + // maxImageDimension (coord-aligned budget). const shrunk = await this._shrinkImageForBudget(rawDataUrl, w, h, budget); let dataUrl = shrunk.dataUrl; if (this.screenshotRedaction) { diff --git a/test/run.js b/test/run.js index e7fc3b3d0..568af3e15 100644 --- a/test/run.js +++ b/test/run.js @@ -2665,6 +2665,55 @@ test('image budget helpers: auto-screenshot counter + failed capture does not bu } }); +test('image budget helpers: coord-aligned budget ignores token cap (side cap only)', () => { + for (const AgentClass of [AgentCh, AgentFx]) { + const agent = new AgentClass({}); + const full = agent._budgetForCapture(); + const coord = agent._budgetForCoordAlignedCapture(); + assert.equal(coord.maxTargetPx, full.maxTargetPx, `${AgentClass.name}: side cap matches`); + assert.ok(coord.maxTargetTokens > full.maxTargetTokens, `${AgentClass.name}: token cap disabled for coord`); + + // 1440×900: both sides under 1568, but tokens (~1653) exceed full budget. + const w = 1440, h = 900; + const tokens = AgentClass._estimateImageTokens(w, h, full.pxPerToken); + assert.ok(tokens > full.maxTargetTokens, 'fixture must exceed full token budget'); + assert.ok(w <= coord.maxTargetPx && h <= coord.maxTargetPx, 'fixture must fit side cap'); + const fullFit = AgentClass._fitImageDimensions(w, h, full); + const coordFit = AgentClass._fitImageDimensions(w, h, coord); + assert.ok(fullFit[0] < w || fullFit[1] < h, `${AgentClass.name}: full budget should shrink 1440×900`); + assert.deepEqual(coordFit, [w, h], `${AgentClass.name}: coord budget keeps 1440×900 1:1`); + + // 1920×1080: width exceeds 1568 — still downscales under side cap. + const big = AgentClass._fitImageDimensions(1920, 1080, coord); + assert.ok(big[0] <= coord.maxTargetPx && big[1] <= coord.maxTargetPx); + assert.ok(big[0] < 1920, `${AgentClass.name}: 1080p still side-capped when width > maxImageDimension`); + } +}); + +test('image budget helpers: budget skip notifies warning + trusted message', async () => { + for (const AgentClass of [AgentCh, AgentFx]) { + const agent = new AgentClass({}); + const tabId = 7; + agent.maxScreenshotsPerTurn = 1; + agent.autoScreenshotCount.set(tabId, 1); + + const warnings = []; + const messages = []; + const onUpdate = (type, payload) => { + if (type === 'warning') warnings.push(payload); + }; + agent._captureAutoScreenshot = async () => ({ dataUrl: 'x', width: 1, height: 1 }); + const shot = await agent._captureBudgetedAutoScreenshot(tabId, { onUpdate, messages }); + assert.equal(shot, null); + assert.equal(warnings.length, 1, `${AgentClass.name}: warning emitted`); + assert.match(warnings[0].message, /maxScreenshotsPerTurn reached/); + assert.equal(messages.length, 1, `${AgentClass.name}: trusted note pushed`); + assert.match(messages[0].content, /maxScreenshotsPerTurn reached/); + // Capture must not have been attempted when budget was already spent. + assert.equal(agent.autoScreenshotCount.get(tabId), 1); + } +}); + test('existing dims under caps stay within the monotonic bound', () => { // Fuzz a range of common viewport sizes; invariant: output ≤ input on // every dimension, and output token count ≤ maxTargetTokens. From 62769d074ab40bffc9614d9b22f8578845f0a79c Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Mon, 13 Jul 2026 04:25:00 +0300 Subject: [PATCH 4/6] fix(chrome): image-budget review nits (indent, default select, compress budget) Align settings const indentation, mark 1568px as the selected default, and pass the active capture budget into non-coord JPEG byte-ceiling compress. --- src/chrome/src/agent/agent.js | 2 +- src/chrome/src/ui/settings.html | 2 +- src/chrome/src/ui/settings.js | 8 ++++---- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/chrome/src/agent/agent.js b/src/chrome/src/agent/agent.js index 716a33864..60dc96f86 100644 --- a/src/chrome/src/agent/agent.js +++ b/src/chrome/src/agent/agent.js @@ -3283,7 +3283,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // CDP-side resize + JPEG q=75 usually fits. Iterative quality // downgrade is the safety net for high-DPR screens where the // captured image can still exceed the base64 ceiling. - const shrunk = await this._compressJpegToByteCeiling(rawDataUrl); + const shrunk = await this._compressJpegToByteCeiling(rawDataUrl, budget); const redacted = await this._redactScreenshotDataUrl(tabId, shrunk, { coordinateSpace: 'viewport' }); return { dataUrl: redacted, diff --git a/src/chrome/src/ui/settings.html b/src/chrome/src/ui/settings.html index 1ac87106a..3d0cad62a 100644 --- a/src/chrome/src/ui/settings.html +++ b/src/chrome/src/ui/settings.html @@ -1080,7 +1080,7 @@

768px - +
diff --git a/src/chrome/src/ui/settings.js b/src/chrome/src/ui/settings.js index bd96a16f8..494d52a27 100644 --- a/src/chrome/src/ui/settings.js +++ b/src/chrome/src/ui/settings.js @@ -45,10 +45,10 @@ const costSessionLimitInput = document.getElementById('input-cost-session-limit' const costTotalLimitInput = document.getElementById('input-cost-total-limit'); const costSpentValueLabel = document.getElementById('cost-spent-value'); const btnResetCostSpend = document.getElementById('btn-reset-cost-spend'); - const autoScreenshotSelect = document.getElementById('select-auto-screenshot'); - const imageDetailSelect = document.getElementById('select-image-detail'); - const maxScreenshotsSelect = document.getElementById('select-max-screenshots'); - const maxImageDimensionSelect = document.getElementById('select-max-image-dimension'); +const autoScreenshotSelect = document.getElementById('select-auto-screenshot'); +const imageDetailSelect = document.getElementById('select-image-detail'); +const maxScreenshotsSelect = document.getElementById('select-max-screenshots'); +const maxImageDimensionSelect = document.getElementById('select-max-image-dimension'); const siteAdaptersToggle = document.getElementById('toggle-site-adapters'); const voiceInputToggle = document.getElementById('toggle-voice-input'); const apiMutationObserverToggle = document.getElementById('toggle-api-mutation-observer'); From 3342b0c421dd0e59f3fd380693dbf114025ad658 Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Mon, 13 Jul 2026 04:27:22 +0300 Subject: [PATCH 5/6] fix(agent): validate image-budget storage and save full-res screenshots Normalize imageDetail / maxScreenshotsPerTurn / maxImageDimension on load and settings change so corrupt storage cannot reach providers. Viewport screenshot save:true keeps a pre-budget CSS-resolution data URL for Downloads (matching full_page_screenshot) while the model still gets the budgeted, optionally redacted copy. --- src/chrome/src/agent/agent.js | 114 +++++++++++++++++++++++++++------ src/chrome/src/background.js | 18 ++---- src/chrome/src/ui/settings.js | 17 ++++- src/firefox/src/agent/agent.js | 43 +++++++++++++ src/firefox/src/background.js | 18 ++---- src/firefox/src/ui/settings.js | 17 ++++- test/run.js | 57 ++++++++++++++++- 7 files changed, 236 insertions(+), 48 deletions(-) diff --git a/src/chrome/src/agent/agent.js b/src/chrome/src/agent/agent.js index 60dc96f86..38e21d542 100644 --- a/src/chrome/src/agent/agent.js +++ b/src/chrome/src/agent/agent.js @@ -4066,6 +4066,49 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d }; } + /** + * Coerce storage / settings values for image budget (issue #311). Rejects + * corrupted or out-of-range values so provider payloads never see e.g. + * `detail: "medium"` and counters stay within the UI set (0–5). + */ + static normalizeImageDetail(value, fallback = 'auto') { + return (value === 'high' || value === 'low' || value === 'auto') ? value : fallback; + } + + static normalizeMaxScreenshotsPerTurn(value, fallback = 0) { + const n = Number(value); + if (!Number.isFinite(n)) return fallback; + const i = Math.trunc(n); + if (i <= 0) return 0; + return Math.min(5, i); + } + + static normalizeMaxImageDimension(value, fallback = 1568) { + const n = Number(value); + if (!Number.isFinite(n) || n <= 0) return fallback; + return Math.max(1, Math.min(2048, Math.round(n))); + } + + /** + * Apply validated image-budget fields from storage. Only keys present on + * `stored` are updated; missing keys leave current agent defaults alone. + */ + applyImageBudgetFromStorage(stored = {}) { + if (stored.imageDetail != null) { + this.imageDetail = Agent.normalizeImageDetail(stored.imageDetail, this.imageDetail); + } + if (stored.maxScreenshotsPerTurn != null) { + this.maxScreenshotsPerTurn = Agent.normalizeMaxScreenshotsPerTurn( + stored.maxScreenshotsPerTurn, this.maxScreenshotsPerTurn, + ); + } + if (stored.maxImageDimension != null) { + this.maxImageDimension = Agent.normalizeMaxImageDimension( + stored.maxImageDimension, this.maxImageDimension, + ); + } + } + /** * The `detail` value to attach to an OpenAI-style image_url block, driven by * the `imageDetail` setting (issue #311). Returns null when the setting is @@ -8520,10 +8563,14 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d // user message, not a base64 string embedded in a tool-result's JSON // text. Either way the model never sees the picture. let dataUrl = null; + // Pre-budget capture for Downloads when save:true (issue #311 review). + // Model path uses the budgeted `dataUrl`; disk gets full CSS when available. + let saveDataUrl = null; let description = ''; let probe = null; let coordAligned = false; let blankFrameRetry = null; + const wantSave = !!(args && args.save); try { await cdpClient.attach(tabId); await cdpClient.sendCommand(tabId, 'Page.enable'); @@ -8555,19 +8602,44 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const scaleY = (cssH / Math.max(1, shrunk.height)).toFixed(4); return { dataUrl: shrunk.dataUrl, + saveDataUrl: rawUrl, description: `Screenshot captured via CDP (${screenshot.data.length} bytes). CSS viewport ${cssW}×${cssH} downscaled to ${shrunk.width}×${shrunk.height} for maxImageDimension — multiply image-pixel coords by (${scaleX}, ${scaleY}) to get CSS click coords.`, }; } return { dataUrl: await this._compressJpegToByteCeiling(rawUrl, budget), + saveDataUrl: rawUrl, description: `Screenshot captured via CDP (${screenshot.data.length} bytes, CSS-pixel aligned for pixel clicks)`, }; } - // Budget-aware mode (default): pick target dims via binary - // search, ask CDP to capture + scale in one pass, then run - // the iterative-quality fallback if bytes are still over. + // Budget-aware mode (default). When the user also asked to save, + // capture full CSS first so Downloads gets full resolution, then + // shrink a model-facing copy (mirrors full_page_screenshot). const budget = this._budgetForCapture(); + if (wantSave) { + const screenshot = await this._withIndicatorsHidden(tabId, () => + cdpClient.sendCommand(tabId, 'Page.captureScreenshot', { + format: 'png', + fromSurface: true, + clip: { x: 0, y: 0, width: cssW, height: cssH, scale: 1 }, + }) + ); + if (!screenshot?.data) return null; + const rawUrl = `data:image/png;base64,${screenshot.data}`; + const shrunk = await this._shrinkImageForBudget(rawUrl, cssW, cssH, budget); + const resized = (shrunk.width < cssW || shrunk.height < cssH) + ? ` (model copy resized ${cssW}×${cssH} → ${shrunk.width}×${shrunk.height} for vision budget; Downloads keeps full CSS)` + : ''; + return { + dataUrl: shrunk.dataUrl, + saveDataUrl: rawUrl, + description: `Screenshot captured via CDP (${screenshot.data.length} bytes, PNG)${resized}`, + }; + } + + // No save: pick target dims via binary search, ask CDP to capture + // + scale in one pass, then iterative-quality fallback if needed. const [targetW, targetH] = Agent._fitImageDimensions(cssW, cssH, budget); const scale = targetW < cssW ? targetW / cssW : 1; const screenshot = await this._withIndicatorsHidden(tabId, () => @@ -8589,6 +8661,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const captured = await this._retryBlankScreenshotCapture(await captureOnce(), captureOnce, { probe }); if (!captured?.dataUrl) throw new Error('CDP returned an empty screenshot'); dataUrl = captured.dataUrl; + saveDataUrl = captured.saveDataUrl || null; description = captured.description || ''; blankFrameRetry = captured.blankFrameRetry || null; } catch { @@ -8601,6 +8674,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d } // Tabs API fallback: no clip/scale available. Capture full, then // decode + resize + recompress via OffscreenCanvas to fit budget. + // Keep the raw capture for Downloads when save:true. const captureOnce = async () => { const rawUrl = await chrome.tabs.captureVisibleTab(tab.windowId, { format: 'png', quality: 80 }); const cssW = Math.max(1, Math.round(probe?.innerWidth || 1024)); @@ -8610,6 +8684,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const shrunk = await this._shrinkImageForBudget(rawUrl, cssW, cssH, budget); return { dataUrl: shrunk.dataUrl, + saveDataUrl: rawUrl, description: `Screenshot captured via tabs API (${shrunk.dataUrl.length} bytes base64, resized to ${shrunk.width}×${shrunk.height})`, }; } @@ -8622,17 +8697,20 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d const scaleY = (cssH / Math.max(1, shrunk.height)).toFixed(4); return { dataUrl: shrunk.dataUrl, + saveDataUrl: rawUrl, description: `Screenshot captured via tabs API (${shrunk.dataUrl.length} bytes base64). CSS viewport ${cssW}×${cssH} downscaled to ${shrunk.width}×${shrunk.height} for maxImageDimension — multiply image-pixel coords by (${scaleX}, ${scaleY}) to get CSS click coords.`, }; } const compressed = await this._compressJpegToByteCeiling(rawUrl, coordBudget); return { dataUrl: compressed, + saveDataUrl: rawUrl, description: `Screenshot captured via tabs API (${compressed.length} bytes base64, CSS-pixel aligned)`, }; }; const captured = await this._retryBlankScreenshotCapture(await captureOnce(), captureOnce, { probe }); dataUrl = captured?.dataUrl || null; + saveDataUrl = captured?.saveDataUrl || null; description = captured?.description || ''; blankFrameRetry = captured?.blankFrameRetry || null; } @@ -8643,23 +8721,14 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d }; } - // Apply redaction after both capture branches converge so the tabs-API - // fallback cannot bypass the privacy setting when CDP is unavailable. - if (this.screenshotRedaction) { - dataUrl = await this._redactScreenshotDataUrl(tabId, dataUrl, { coordinateSpace: 'viewport' }); - } - - // If the user asked to save this screenshot to Downloads, do it - // here — directly from the service worker via chrome.downloads. - // This runs BEFORE the vision-presentation branch because saving - // is independent of whether the agent can see the image. The - // screenshot data URLs are clean (image/png or image/jpeg with - // no parameters) so they pass through downloads.download safely - // — unlike the recorder's video/webm;codecs=... edge case. + // Save first from the pre-budget capture (full CSS when available), + // matching full_page_screenshot: Downloads keep full resolution; + // only the model-facing copy is budget-resized / redacted. let savedFile = null; - if (args && args.save) { + if (wantSave) { try { - const mimeMatch = /^data:([^;]+);/.exec(dataUrl); + const urlForSave = saveDataUrl || dataUrl; + const mimeMatch = /^data:([^;]+);/.exec(urlForSave); const mime = mimeMatch ? mimeMatch[1] : 'image/png'; const ext = mime === 'image/jpeg' ? 'jpg' : 'png'; const stamp = new Date().toISOString().replace(/[:.]/g, '-').slice(0, 19).replace('T', '_'); @@ -8669,7 +8738,7 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d filename = filename.split('/').pop().split('\\').pop(); if (!/\.(png|jpg|jpeg)$/i.test(filename)) filename += `.${ext}`; const downloadId = await chrome.downloads.download({ - url: dataUrl, filename, saveAs: false, + url: urlForSave, filename, saveAs: false, }); savedFile = { downloadId, filename, mimeType: mime }; } catch (e) { @@ -8677,6 +8746,13 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d } } + // Apply redaction after save so the local download is untouched + // (same pattern as full_page_screenshot). Tabs-API fallback cannot + // bypass the privacy setting for the model-facing path. + if (this.screenshotRedaction) { + dataUrl = await this._redactScreenshotDataUrl(tabId, dataUrl, { coordinateSpace: 'viewport' }); + } + // Pick the presentation path based on what the active providers can // actually do with an image. Order matters: a dedicated vision model // (cheaper, summary-only) wins over the main provider's own vision. diff --git a/src/chrome/src/background.js b/src/chrome/src/background.js index 5c03a71ef..8a4b0bd7e 100644 --- a/src/chrome/src/background.js +++ b/src/chrome/src/background.js @@ -195,9 +195,7 @@ const screenshotRedactionReady = loadScreenshotRedaction().catch(() => {}); // the previous behavior (auto detail, unlimited screenshots, 1568px cap). async function loadImageBudget() { const stored = await chrome.storage.local.get(['imageDetail', 'maxScreenshotsPerTurn', 'maxImageDimension']); - if (stored.imageDetail != null) agent.imageDetail = stored.imageDetail; - if (stored.maxScreenshotsPerTurn != null) agent.maxScreenshotsPerTurn = stored.maxScreenshotsPerTurn; - if (stored.maxImageDimension != null) agent.maxImageDimension = stored.maxImageDimension; + agent.applyImageBudgetFromStorage(stored); } // Retained so handleMessage can await hydration on a cold SW start — the first // chat must not race ahead of the persisted image-budget settings (issue #311). @@ -739,14 +737,12 @@ chrome.storage.onChanged.addListener((changes) => { if (changes.screenshotRedaction) { agent.screenshotRedaction = !!changes.screenshotRedaction.newValue; } - if (changes.imageDetail) { - agent.imageDetail = changes.imageDetail.newValue; - } - if (changes.maxScreenshotsPerTurn) { - agent.maxScreenshotsPerTurn = changes.maxScreenshotsPerTurn.newValue; - } - if (changes.maxImageDimension) { - agent.maxImageDimension = changes.maxImageDimension.newValue; + if (changes.imageDetail || changes.maxScreenshotsPerTurn || changes.maxImageDimension) { + agent.applyImageBudgetFromStorage({ + imageDetail: changes.imageDetail ? changes.imageDetail.newValue : undefined, + maxScreenshotsPerTurn: changes.maxScreenshotsPerTurn ? changes.maxScreenshotsPerTurn.newValue : undefined, + maxImageDimension: changes.maxImageDimension ? changes.maxImageDimension.newValue : undefined, + }); } if (changes[API_MUTATION_OBSERVER_KEY]) { setApiMutationObserverEnabled(changes[API_MUTATION_OBSERVER_KEY].newValue === true); diff --git a/src/chrome/src/ui/settings.js b/src/chrome/src/ui/settings.js index 494d52a27..3aae04850 100644 --- a/src/chrome/src/ui/settings.js +++ b/src/chrome/src/ui/settings.js @@ -821,15 +821,26 @@ autoScreenshotSelect.addEventListener('change', async () => { }); imageDetailSelect.addEventListener('change', async () => { - await chrome.storage.local.set({ imageDetail: imageDetailSelect.value }).catch(() => {}); + const v = imageDetailSelect.value; + const imageDetail = (v === 'high' || v === 'low' || v === 'auto') ? v : 'auto'; + imageDetailSelect.value = imageDetail; + await chrome.storage.local.set({ imageDetail }).catch(() => {}); }); maxScreenshotsSelect.addEventListener('change', async () => { - await chrome.storage.local.set({ maxScreenshotsPerTurn: parseInt(maxScreenshotsSelect.value, 10) || 0 }).catch(() => {}); + let n = parseInt(maxScreenshotsSelect.value, 10); + if (!Number.isFinite(n) || n < 0) n = 0; + if (n > 5) n = 5; + maxScreenshotsSelect.value = String(n); + await chrome.storage.local.set({ maxScreenshotsPerTurn: n }).catch(() => {}); }); maxImageDimensionSelect.addEventListener('change', async () => { - await chrome.storage.local.set({ maxImageDimension: parseInt(maxImageDimensionSelect.value, 10) || 1568 }).catch(() => {}); + let n = parseInt(maxImageDimensionSelect.value, 10); + if (!Number.isFinite(n) || n <= 0) n = 1568; + n = Math.max(1, Math.min(2048, n)); + maxImageDimensionSelect.value = String(n); + await chrome.storage.local.set({ maxImageDimension: n }).catch(() => {}); }); siteAdaptersToggle.addEventListener('change', async () => { diff --git a/src/firefox/src/agent/agent.js b/src/firefox/src/agent/agent.js index f3af88c51..d68121e43 100644 --- a/src/firefox/src/agent/agent.js +++ b/src/firefox/src/agent/agent.js @@ -2447,6 +2447,49 @@ Rules: no prose intro, no conclusion, no "this screenshot shows...", no layout d }; } + /** + * Coerce storage / settings values for image budget (issue #311). Rejects + * corrupted or out-of-range values so provider payloads never see e.g. + * `detail: "medium"` and counters stay within the UI set (0–5). + */ + static normalizeImageDetail(value, fallback = 'auto') { + return (value === 'high' || value === 'low' || value === 'auto') ? value : fallback; + } + + static normalizeMaxScreenshotsPerTurn(value, fallback = 0) { + const n = Number(value); + if (!Number.isFinite(n)) return fallback; + const i = Math.trunc(n); + if (i <= 0) return 0; + return Math.min(5, i); + } + + static normalizeMaxImageDimension(value, fallback = 1568) { + const n = Number(value); + if (!Number.isFinite(n) || n <= 0) return fallback; + return Math.max(1, Math.min(2048, Math.round(n))); + } + + /** + * Apply validated image-budget fields from storage. Only keys present on + * `stored` are updated; missing keys leave current agent defaults alone. + */ + applyImageBudgetFromStorage(stored = {}) { + if (stored.imageDetail != null) { + this.imageDetail = Agent.normalizeImageDetail(stored.imageDetail, this.imageDetail); + } + if (stored.maxScreenshotsPerTurn != null) { + this.maxScreenshotsPerTurn = Agent.normalizeMaxScreenshotsPerTurn( + stored.maxScreenshotsPerTurn, this.maxScreenshotsPerTurn, + ); + } + if (stored.maxImageDimension != null) { + this.maxImageDimension = Agent.normalizeMaxImageDimension( + stored.maxImageDimension, this.maxImageDimension, + ); + } + } + /** * The `detail` value to attach to an OpenAI-style image_url block, driven by * the `imageDetail` setting (issue #311). Returns null when the setting is diff --git a/src/firefox/src/background.js b/src/firefox/src/background.js index 88db06fb9..5ff32a708 100644 --- a/src/firefox/src/background.js +++ b/src/firefox/src/background.js @@ -203,9 +203,7 @@ const screenshotRedactionReady = loadScreenshotRedaction().catch(() => {}); // the previous behavior (auto detail, unlimited screenshots, 1568px cap). async function loadImageBudget() { const stored = await browser.storage.local.get(['imageDetail', 'maxScreenshotsPerTurn', 'maxImageDimension']); - if (stored.imageDetail != null) agent.imageDetail = stored.imageDetail; - if (stored.maxScreenshotsPerTurn != null) agent.maxScreenshotsPerTurn = stored.maxScreenshotsPerTurn; - if (stored.maxImageDimension != null) agent.maxImageDimension = stored.maxImageDimension; + agent.applyImageBudgetFromStorage(stored); } const imageBudgetReady = loadImageBudget().catch(() => {}); @@ -728,14 +726,12 @@ browser.storage.onChanged.addListener((changes) => { if (changes.screenshotRedaction) { agent.screenshotRedaction = !!changes.screenshotRedaction.newValue; } - if (changes.imageDetail) { - agent.imageDetail = changes.imageDetail.newValue; - } - if (changes.maxScreenshotsPerTurn) { - agent.maxScreenshotsPerTurn = changes.maxScreenshotsPerTurn.newValue; - } - if (changes.maxImageDimension) { - agent.maxImageDimension = changes.maxImageDimension.newValue; + if (changes.imageDetail || changes.maxScreenshotsPerTurn || changes.maxImageDimension) { + agent.applyImageBudgetFromStorage({ + imageDetail: changes.imageDetail ? changes.imageDetail.newValue : undefined, + maxScreenshotsPerTurn: changes.maxScreenshotsPerTurn ? changes.maxScreenshotsPerTurn.newValue : undefined, + maxImageDimension: changes.maxImageDimension ? changes.maxImageDimension.newValue : undefined, + }); } if (changes.profileText) { agent.profileText = changes.profileText.newValue || ''; diff --git a/src/firefox/src/ui/settings.js b/src/firefox/src/ui/settings.js index d2f2e4fcb..b2bd63906 100644 --- a/src/firefox/src/ui/settings.js +++ b/src/firefox/src/ui/settings.js @@ -804,15 +804,26 @@ autoScreenshotSelect?.addEventListener('change', async () => { }); imageDetailSelect?.addEventListener('change', async () => { - await browser.storage.local.set({ imageDetail: imageDetailSelect.value }).catch(() => {}); + const v = imageDetailSelect.value; + const imageDetail = (v === 'high' || v === 'low' || v === 'auto') ? v : 'auto'; + imageDetailSelect.value = imageDetail; + await browser.storage.local.set({ imageDetail }).catch(() => {}); }); maxScreenshotsSelect?.addEventListener('change', async () => { - await browser.storage.local.set({ maxScreenshotsPerTurn: parseInt(maxScreenshotsSelect.value, 10) || 0 }).catch(() => {}); + let n = parseInt(maxScreenshotsSelect.value, 10); + if (!Number.isFinite(n) || n < 0) n = 0; + if (n > 5) n = 5; + maxScreenshotsSelect.value = String(n); + await browser.storage.local.set({ maxScreenshotsPerTurn: n }).catch(() => {}); }); maxImageDimensionSelect?.addEventListener('change', async () => { - await browser.storage.local.set({ maxImageDimension: parseInt(maxImageDimensionSelect.value, 10) || 1568 }).catch(() => {}); + let n = parseInt(maxImageDimensionSelect.value, 10); + if (!Number.isFinite(n) || n <= 0) n = 1568; + n = Math.max(1, Math.min(2048, n)); + maxImageDimensionSelect.value = String(n); + await browser.storage.local.set({ maxImageDimension: n }).catch(() => {}); }); siteAdaptersToggle?.addEventListener('change', async () => { diff --git a/test/run.js b/test/run.js index 568af3e15..6669723ea 100644 --- a/test/run.js +++ b/test/run.js @@ -886,7 +886,10 @@ test('remaining model-facing screenshot fallbacks apply redaction', () => { const chromeEnd = chromeSource.indexOf("if (name === 'done')", chromeStart); const chromeBody = chromeSource.slice(chromeStart, chromeEnd); const fallbackIndex = chromeBody.indexOf('chrome.tabs.captureVisibleTab'); - const convergedRedactionIndex = chromeBody.indexOf('// Apply redaction after both capture branches converge'); + // Save runs first (full-res); model-facing redaction is after both capture branches. + const convergedRedactionIndex = chromeBody.indexOf( + "if (this.screenshotRedaction) {\n dataUrl = await this._redactScreenshotDataUrl(tabId, dataUrl, { coordinateSpace: 'viewport' });", + ); assert.ok(fallbackIndex >= 0 && convergedRedactionIndex > fallbackIndex, 'Chrome tabs-API fallback should converge into redaction before presentation'); @@ -2714,6 +2717,58 @@ test('image budget helpers: budget skip notifies warning + trusted message', asy } }); +test('image budget helpers: storage normalization rejects corrupt values', () => { + for (const AgentClass of [AgentCh, AgentFx]) { + assert.equal(AgentClass.normalizeImageDetail('high'), 'high'); + assert.equal(AgentClass.normalizeImageDetail('medium'), 'auto'); + assert.equal(AgentClass.normalizeImageDetail(null, 'low'), 'low'); + assert.equal(AgentClass.normalizeMaxScreenshotsPerTurn(3), 3); + assert.equal(AgentClass.normalizeMaxScreenshotsPerTurn(99), 5); + assert.equal(AgentClass.normalizeMaxScreenshotsPerTurn(-1), 0); + assert.equal(AgentClass.normalizeMaxScreenshotsPerTurn('nope', 2), 2); + assert.equal(AgentClass.normalizeMaxImageDimension(512), 512); + assert.equal(AgentClass.normalizeMaxImageDimension(9999), 2048); + assert.equal(AgentClass.normalizeMaxImageDimension(0), 1568); + assert.equal(AgentClass.normalizeMaxImageDimension('x', 1024), 1024); + + const agent = new AgentClass({}); + agent.applyImageBudgetFromStorage({ + imageDetail: 'bogus', + maxScreenshotsPerTurn: 100, + maxImageDimension: -5, + }); + assert.equal(agent.imageDetail, 'auto', `${AgentClass.name}: bad detail falls back to current/default`); + assert.equal(agent.maxScreenshotsPerTurn, 5); + // -5 is non-finite-positive → fallback to current default 1568 + assert.equal(agent.maxImageDimension, 1568); + + agent.applyImageBudgetFromStorage({ imageDetail: 'low', maxImageDimension: 768 }); + assert.equal(agent.imageDetail, 'low'); + assert.equal(agent.maxImageDimension, 768); + assert.equal(agent.maxScreenshotsPerTurn, 5, 'unspecified keys leave prior value'); + } +}); + +test('chrome screenshot tool saves pre-budget data URL when save:true', () => { + // Structural: save path must prefer saveDataUrl (full CSS) over budgeted dataUrl. + const source = fs.readFileSync(path.join(ROOT, 'src/chrome/src/agent/agent.js'), 'utf8'); + const start = source.indexOf("if (name === 'screenshot')"); + const end = source.indexOf("if (name === 'done')", start); + assert.ok(start >= 0 && end > start, 'screenshot tool block not found'); + const body = source.slice(start, end); + assert.match(body, /saveDataUrl/, 'screenshot tool should track pre-budget saveDataUrl'); + assert.match( + body, + /const urlForSave = saveDataUrl \|\| dataUrl/, + 'Downloads must use saveDataUrl when present', + ); + assert.match( + body, + /wantSave[\s\S]*captureScreenshot[\s\S]*scale: 1[\s\S]*_shrinkImageForBudget/, + 'save:true non-coord path should full-capture then shrink for the model', + ); +}); + test('existing dims under caps stay within the monotonic bound', () => { // Fuzz a range of common viewport sizes; invariant: output ≤ input on // every dimension, and output token count ≤ maxTargetTokens. From a13006778215f397f06d299ea83bbb7371afa997 Mon Sep 17 00:00:00 2001 From: Emre Sokullu Date: Mon, 13 Jul 2026 04:30:20 +0300 Subject: [PATCH 6/6] i18n: translate image-budget settings strings in all non-en locales Replace English stubs for st.imageBudget.* with real translations in Chrome and Firefox locale files (review nit #10). --- src/chrome/src/ui/locales/ar.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/es.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/fr.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/he.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/id.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/ja.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/ko.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/ms.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/pl.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/ru.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/th.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/tl.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/tr.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/uk.js | 26 +++++++++++++------------- src/chrome/src/ui/locales/zh.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/ar.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/es.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/fr.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/he.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/id.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/ja.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/ko.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/ms.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/pl.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/ru.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/th.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/tl.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/tr.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/uk.js | 26 +++++++++++++------------- src/firefox/src/ui/locales/zh.js | 26 +++++++++++++------------- 30 files changed, 390 insertions(+), 390 deletions(-) diff --git a/src/chrome/src/ui/locales/ar.js b/src/chrome/src/ui/locales/ar.js index 4fe5dbdae..f837a4e22 100644 --- a/src/chrome/src/ui/locales/ar.js +++ b/src/chrome/src/ui/locales/ar.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "إخفاء المحتوى الحساس في لقطات الشاشة", "st.redaction.toggle.desc": "قبل إرسال لقطة الشاشة إلى نموذج رؤية، يقوم بتغبيش حقول النماذج والنص الذي يبدو كبريد إلكتروني أو رقم هاتف. يعمل الكشف بالكامل على جهازك — لا يُنقل أي شيء إضافي.", "st.redaction.warning": "⚠️ هذا تعتيم بأفضل جهد ومن نوع fail-open: إذا تعذّر تشغيل التعتيم على صفحة ما (مثلًا مباشرة بعد التنقل، أو في عارضات PDF، أو على صفحات المتصفح المقيّدة)، فستُرسل لقطة الشاشة كما هي دون تعتيم. يعتمد الكشف فقط على استدلالات DOM — النص المرسوم على عنصر canvas، أو البيانات الشخصية داخل الصور، أو أي شيء لا يُعرف كحقل نموذج أو نص بريد/هاتف قد يفلت من الكشف، كما أن نص الصفحة المُرسل إلى النموذج لا يُعتَّم بهذا الإعداد. هذا ليس ضمانًا أمنيًا. للخصوصية الكاملة، استخدم نموذجًا محليًا/دون اتصال (llama.cpp أو Ollama): عندها لن تغادر لقطات الشاشة جهازك إطلاقًا ولن تعود هناك حاجة للتعتيم.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "ميزانية الصور", + "st.imageBudget.desc": "يتحكم في حجم لقطات الشاشة وعدد ما يلتقطه الوكيل لكل جولة للرؤية. تقليل التفاصيل والأبعاد يخفض التكلفة والكمون على النقاط الطرفية الصغيرة؛ زيادتها تحافظ على الدقة. القيم الافتراضية تطابق السلوك السابق.", + "st.imageBudget.detail.label": "تفاصيل الصورة", + "st.imageBudget.detail.desc": "تفاصيل صورة الرؤية المُرسلة إلى النموذج. «high» يحافظ على مزيد من التفاصيل (مزيد من الرموز والتكلفة)؛ «low» يرسل صورة أصغر وأرخص؛ «auto» يترك القرار للمزوّد. يعتمد على المزوّد.", + "st.imageBudget.detail.high": "عالية (مزيد من التفاصيل والتكلفة)", + "st.imageBudget.detail.low": "منخفضة (أرخص وأقل تفاصيل)", + "st.imageBudget.detail.auto": "تلقائي (افتراضي المزوّد)", + "st.imageBudget.maxPerTurn.label": "أقصى لقطات لكل جولة", + "st.imageBudget.maxPerTurn.desc": "كم لقطة تلقائية يمكن للوكيل التقاطها للرؤية في جولة واحدة (0 = بلا حد). القيم الأقل تخفض التكلفة؛ عند استنفاد الميزانية تُتخطى اللقطات التلقائية اللاحقة في تلك الجولة.", + "st.imageBudget.maxPerTurn.unlimited": "بلا حد", + "st.imageBudget.maxDimension.label": "أقصى بُعد للصورة", + "st.imageBudget.maxDimension.desc": "أطول ضلع (العرض أو الارتفاع) بالبكسل لأي لقطة تُرسل إلى الرؤية. حد أصغر يصغّر الصور قبل الإرسال فيخفض الرموز والتكلفة. حد أكبر يحافظ على الدقة.", + "st.imageBudget.warning": "⚠️ تنطبق هذه الإعدادات على اللقطات المخصصة للرؤية (لقطة تلقائية، /screenshot، صفحة كاملة، verify_form). الصور المحفوظة يدويًا بدقة كاملة لا تتأثر. «Image detail» تحترمه نقاط النهاية بأسلوب OpenAI؛ قد يتجاهلها مزوّدون آخرون.", }; diff --git a/src/chrome/src/ui/locales/es.js b/src/chrome/src/ui/locales/es.js index 5fd70c1fe..e7ae4e229 100644 --- a/src/chrome/src/ui/locales/es.js +++ b/src/chrome/src/ui/locales/es.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "Redactar contenido sensible en las capturas de pantalla", "st.redaction.toggle.desc": "Antes de enviar una captura de pantalla a un modelo de visión, difumina los campos de formulario y el texto que parezca un correo electrónico o un número de teléfono. La detección se ejecuta enteramente en tu dispositivo — no se transmite nada adicional.", "st.redaction.warning": "⚠️ Es una redacción best-effort y fail-open: si no se puede aplicar en una página (por ejemplo justo después de una navegación, en visores de PDF o en páginas restringidas del navegador), la captura se envía igualmente sin redactar. La detección usa solo heurísticas del DOM — texto dibujado en un canvas, datos personales dentro de imágenes, o cualquier cosa no reconocida como campo de formulario o texto de correo/teléfono puede pasar desapercibida, y el texto de la página enviado al modelo no se redacta con este ajuste. No es una garantía de seguridad. Para privacidad total, usa un modelo local/sin conexión (llama.cpp, Ollama): las capturas nunca saldrán de tu equipo y la redacción deja de ser necesaria.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Presupuesto de imágenes", + "st.imageBudget.desc": "Controla el tamaño de las capturas y cuántas toma el agente por turno para visión. Menor detalle y dimensión reducen coste y latencia en endpoints pequeños; mayor valor mantiene la fidelidad. Los valores predeterminados coinciden con el comportamiento anterior.", + "st.imageBudget.detail.label": "Detalle de imagen", + "st.imageBudget.detail.desc": "Detalle de la imagen de visión enviada al modelo. «high» conserva más detalle (más tokens y coste); «low» envía una imagen más pequeña y barata; «auto» deja decidir al proveedor. Depende del proveedor.", + "st.imageBudget.detail.high": "Alto (más detalle, más coste)", + "st.imageBudget.detail.low": "Bajo (más barato, menos detalle)", + "st.imageBudget.detail.auto": "Automático (predeterminado del proveedor)", + "st.imageBudget.maxPerTurn.label": "Máx. capturas por turno", + "st.imageBudget.maxPerTurn.desc": "Cuántas capturas automáticas puede tomar el agente para visión en un solo turno (0 = ilimitado). Valores más bajos reducen el coste; cuando se agota el presupuesto, no se toman más capturas automáticas en ese turno.", + "st.imageBudget.maxPerTurn.unlimited": "Ilimitado", + "st.imageBudget.maxDimension.label": "Dimensión máxima de imagen", + "st.imageBudget.maxDimension.desc": "Lado mayor (ancho o alto) en píxeles de cualquier captura enviada a visión. Un tope más bajo reduce las imágenes antes de enviarlas, cortando tokens y coste. Un tope más alto mantiene la fidelidad.", + "st.imageBudget.warning": "⚠️ Estos ajustes se aplican a capturas para visión (auto-captura, /screenshot, página completa, verify_form). Las imágenes guardadas manualmente a resolución completa no se ven afectadas. «Image detail» lo respetan endpoints estilo OpenAI; otros proveedores pueden ignorarlo.", }; diff --git a/src/chrome/src/ui/locales/fr.js b/src/chrome/src/ui/locales/fr.js index ec7a4eb9b..99ecf3338 100644 --- a/src/chrome/src/ui/locales/fr.js +++ b/src/chrome/src/ui/locales/fr.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "Flouter le contenu sensible dans les captures d'écran", "st.redaction.toggle.desc": "Avant qu'une capture d'écran soit envoyée à un modèle de vision, floute les champs de formulaire et le texte qui ressemble à un e-mail ou un numéro de téléphone. La détection s'exécute entièrement sur votre appareil — rien de plus n'est transmis.", "st.redaction.warning": "⚠️ Meilleur effort et fail-open : si le floutage ne peut pas s'exécuter sur une page (par exemple juste après une navigation, dans les visionneuses PDF, ou sur des pages restreintes du navigateur), la capture est quand même envoyée non floutée. La détection utilise uniquement des heuristiques DOM — texte dessiné sur un canvas, données personnelles dans des images, ou tout ce qui n'est pas reconnu comme champ de formulaire ou texte e-mail/téléphone peut passer inaperçu, et le texte de la page envoyé au modèle n'est pas flouté par ce réglage. Ce n'est PAS une garantie de sécurité. Pour une confidentialité totale, utilisez un modèle local/hors ligne (llama.cpp, Ollama) : les captures ne quittent alors jamais votre machine et le floutage devient inutile.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Budget d’images", + "st.imageBudget.desc": "Contrôle la taille des captures et le nombre que l’agent prend pour la vision par tour. Moins de détail et une dimension plus petite réduisent le coût et la latence sur les petits endpoints ; plus élevé conserve la fidélité. Les valeurs par défaut reprennent le comportement précédent.", + "st.imageBudget.detail.label": "Détail d’image", + "st.imageBudget.detail.desc": "Détail d’image vision envoyé au modèle. « high » garde plus de détail (plus de tokens et de coût) ; « low » envoie une image plus petite et moins chère ; « auto » laisse le fournisseur décider. Dépend du fournisseur.", + "st.imageBudget.detail.high": "Élevé (plus de détail, plus de coût)", + "st.imageBudget.detail.low": "Faible (moins cher, moins de détail)", + "st.imageBudget.detail.auto": "Auto (défaut du fournisseur)", + "st.imageBudget.maxPerTurn.label": "Captures max. par tour", + "st.imageBudget.maxPerTurn.desc": "Nombre de captures auto que l’agent peut prendre pour la vision dans un tour (0 = illimité). Une valeur plus basse réduit le coût ; une fois le budget épuisé, les captures auto suivantes sont ignorées pour ce tour.", + "st.imageBudget.maxPerTurn.unlimited": "Illimité", + "st.imageBudget.maxDimension.label": "Dimension max. d’image", + "st.imageBudget.maxDimension.desc": "Plus grand côté (largeur ou hauteur) en pixels pour toute capture envoyée à la vision. Un plafond plus bas réduit les images avant envoi, ce qui coupe tokens et coût. Un plafond plus haut conserve la fidélité.", + "st.imageBudget.warning": "⚠️ Ces réglages s’appliquent aux captures pour la vision (auto-capture, /screenshot, page entière, verify_form). Les images enregistrées manuellement en pleine résolution ne sont pas affectées. « Image detail » est respecté par les endpoints de type OpenAI ; d’autres fournisseurs peuvent l’ignorer.", }; diff --git a/src/chrome/src/ui/locales/he.js b/src/chrome/src/ui/locales/he.js index f0ba8e96c..10c1910d7 100644 --- a/src/chrome/src/ui/locales/he.js +++ b/src/chrome/src/ui/locales/he.js @@ -657,17 +657,17 @@ export default { "st.redaction.toggle.label": "טשטש תוכן רגיש בצילומי מסך", "st.redaction.toggle.desc": "לפני שצילום מסך נשלח למודל ראייה, מטשטש שדות טופס וטקסט שנראה כמו אימייל או מספר טלפון. הזיהוי פועל כולו במכשיר שלך — שום דבר נוסף לא מועבר.", "st.redaction.warning": "⚠️ זהו טשטוש במאמץ סביר (best-effort) מסוג fail-open: אם הטשטוש לא יכול לפעול בדף מסוים (למשל מיד אחרי ניווט, בצפייה בקבצי PDF, או בדפי דפדפן מוגבלים), צילום המסך עדיין יישלח ללא טשטוש. הזיהוי מסתמך רק על היוריסטיקות DOM — טקסט המצויר על canvas, מידע אישי בתוך תמונות, או כל דבר שלא מזוהה כשדה טופס או כטקסט אימייל/טלפון עלול לחמוק, וטקסט הדף הנשלח למודל אינו מטושטש על ידי הגדרה זו. זו אינה ערבות אבטחה. לפרטיות מלאה, השתמש במודל מקומי/לא מקוון (llama.cpp, Ollama): כך צילומי מסך לעולם לא יעזבו את המכשיר שלך והטשטוש כבר לא יידרש.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "תקציב תמונות", + "st.imageBudget.desc": "שולט בגודל צילומי המסך ובכמה פעמים הסוכן מצלם לצורכי ראייה בכל תור. פרט ומימד נמוכים יותר מפחיתים עלות והשהיה בקצוות קטנים; גבוהים יותר שומרים על נאמנות. ברירות המחדל תואמות להתנהגות הקודמת.", + "st.imageBudget.detail.label": "רמת פירוט תמונה", + "st.imageBudget.detail.desc": "רמת פירוט תמונת הראייה שנשלחת למודל. «high» שומר יותר פרטים (יותר טוקנים ועלות); «low» שולח תמונה קטנה וזולה יותר; «auto» משאיר לספק להחליט. תלוי בספק.", + "st.imageBudget.detail.high": "גבוה (יותר פרטים, יותר עלות)", + "st.imageBudget.detail.low": "נמוך (זול יותר, פחות פרטים)", + "st.imageBudget.detail.auto": "אוטומטי (ברירת מחדל של הספק)", + "st.imageBudget.maxPerTurn.label": "מקס׳ צילומים לתור", + "st.imageBudget.maxPerTurn.desc": "כמה צילומי מסך אוטומטיים הסוכן רשאי לצלם לראייה בתור אחד (0 = ללא הגבלה). ערכים נמוכים מפחיתים עלות; כשהתקציב נגמר, צילומים אוטומטיים נוספים בתור הזה מדולגים.", + "st.imageBudget.maxPerTurn.unlimited": "ללא הגבלה", + "st.imageBudget.maxDimension.label": "ממד תמונה מרבי", + "st.imageBudget.maxDimension.desc": "הצלע הארוכה (רוחב או גובה) בפיקסלים לכל צילום שנשלח לראייה. תקרה נמוכה יותר מקטינה תמונות לפני השליחה ומורידה טוקנים ועלות. תקרה גבוהה יותר שומרת נאמנות.", + "st.imageBudget.warning": "⚠️ ההגדרות האלה חלות על צילומים לראייה (צילום אוטומטי, /screenshot, עמוד מלא, verify_form). תמונות שנשמרו ידנית ברזולוציה מלאה אינן מושפעות. «Image detail» מכובד על ידי נקודות קצה בסגנון OpenAI; ספקים אחרים עשויים להתעלם.", }; diff --git a/src/chrome/src/ui/locales/id.js b/src/chrome/src/ui/locales/id.js index 6eeb35c95..46203d4a2 100644 --- a/src/chrome/src/ui/locales/id.js +++ b/src/chrome/src/ui/locales/id.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "Samarkan konten sensitif pada tangkapan layar", "st.redaction.toggle.desc": "Sebelum tangkapan layar dikirim ke model visi, WebBrain mengaburkan kolom formulir dan teks yang terlihat seperti email atau nomor telepon. Pendeteksian berjalan sepenuhnya di perangkat Anda — tidak ada yang dikirim ekstra.", "st.redaction.warning": "⚠️ Ini bersifat best-effort dan fail-open: jika penyamaran tidak bisa berjalan di suatu halaman (misalnya tepat setelah navigasi, di penampil PDF, atau di halaman browser yang dibatasi), tangkapan layar tetap dikirim tanpa disamarkan. Pendeteksian hanya menggunakan heuristik DOM — teks yang digambar di canvas, informasi pribadi di dalam gambar, atau apa pun yang tidak dikenali sebagai kolom formulir atau teks email/telepon bisa saja lolos, dan teks halaman yang dikirim ke model tidak disamarkan oleh pengaturan ini. Ini BUKAN jaminan keamanan. Untuk privasi penuh, gunakan model lokal/offline (llama.cpp, Ollama): tangkapan layar tidak akan pernah meninggalkan perangkat Anda dan penyamaran pun jadi tidak diperlukan.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Anggaran gambar", + "st.imageBudget.desc": "Mengontrol ukuran tangkapan layar dan berapa kali agen menangkap untuk visi per giliran. Detail dan dimensi lebih rendah mengurangi biaya dan latensi di endpoint kecil; lebih tinggi menjaga fidelitas. Default cocok dengan perilaku sebelumnya.", + "st.imageBudget.detail.label": "Detail gambar", + "st.imageBudget.detail.desc": "Detail gambar visi yang dikirim ke model. «high» mempertahankan lebih banyak detail (lebih banyak token dan biaya); «low» mengirim gambar lebih kecil dan murah; «auto» membiarkan penyedia memutuskan. Bergantung pada penyedia.", + "st.imageBudget.detail.high": "Tinggi (lebih detail, lebih mahal)", + "st.imageBudget.detail.low": "Rendah (lebih murah, lebih sedikit detail)", + "st.imageBudget.detail.auto": "Otomatis (default penyedia)", + "st.imageBudget.maxPerTurn.label": "Maks. tangkapan per giliran", + "st.imageBudget.maxPerTurn.desc": "Berapa banyak tangkapan otomatis yang boleh diambil agen untuk visi dalam satu giliran (0 = tanpa batas). Nilai lebih rendah mengurangi biaya; setelah anggaran habis, tangkapan otomatis berikutnya di giliran itu dilewati.", + "st.imageBudget.maxPerTurn.unlimited": "Tanpa batas", + "st.imageBudget.maxDimension.label": "Dimensi gambar maksimum", + "st.imageBudget.maxDimension.desc": "Sisi terpanjang (lebar atau tinggi) dalam piksel untuk setiap tangkapan yang dikirim ke visi. Batas lebih kecil mengecilkan gambar sebelum dikirim, mengurangi token dan biaya. Batas lebih besar menjaga fidelitas.", + "st.imageBudget.warning": "⚠️ Pengaturan ini berlaku untuk tangkapan untuk visi (tangkapan otomatis, /screenshot, halaman penuh, verify_form). Gambar resolusi penuh yang disimpan manual tidak terpengaruh. «Image detail» dihormati endpoint bergaya OpenAI; penyedia lain mungkin mengabaikannya.", }; diff --git a/src/chrome/src/ui/locales/ja.js b/src/chrome/src/ui/locales/ja.js index 1101558d1..9fd70cff5 100644 --- a/src/chrome/src/ui/locales/ja.js +++ b/src/chrome/src/ui/locales/ja.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "スクリーンショット内の機密情報を黒塗りする", "st.redaction.toggle.desc": "スクリーンショットをビジョンモデルに送信する前に、フォーム項目やメールアドレス・電話番号らしきテキストにモザイクをかけます。検出はすべて端末内で行われ、追加で送信されるデータはありません。", "st.redaction.warning": "⚠️ これはベストエフォートかつフェイルオープンな処理です。ページ上で黒塗り処理が実行できない場合(ナビゲーション直後、PDFビューア、制限されたブラウザページなど)、スクリーンショットは黒塗りされないまま送信されます。検出はDOMヒューリスティックのみに基づいており、canvasに描画されたテキスト、画像内の個人情報、フォーム項目やメール/電話のテキストと認識されないものは見逃される可能性があります。またモデルに送られるページの本文テキストはこの設定では黒塗りされません。これはセキュリティ上の保証ではありません。完全なプライバシーが必要な場合は、ローカル/オフラインモデル(llama.cpp、Ollamaなど)を使用してください。その場合スクリーンショットは端末から一切出ないため、黒塗りは不要になります。", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "画像予算", + "st.imageBudget.desc": "スクリーンショットのサイズと、エージェントが 1 ターンあたりビジョン用に撮影する回数を制御します。詳細度と寸法を下げると小型エンドポイントでのコストと遅延が減り、上げると忠実度が保たれます。既定値は以前の動作と同じです。", + "st.imageBudget.detail.label": "画像の詳細度", + "st.imageBudget.detail.desc": "モデルに送るビジョン画像の詳細度。「high」はより多くの詳細を保持(トークンとコスト増);「low」は小さく安価な画像;「auto」はプロバイダ任せ。プロバイダ依存です。", + "st.imageBudget.detail.high": "高(詳細多・コスト高)", + "st.imageBudget.detail.low": "低(安価・詳細少)", + "st.imageBudget.detail.auto": "自動(プロバイダ既定)", + "st.imageBudget.maxPerTurn.label": "1 ターンあたりの最大スクリーンショット数", + "st.imageBudget.maxPerTurn.desc": "エージェントが 1 ターンでビジョン用に自動撮影できる回数(0 = 無制限)。低い値はコストを下げます。予算を使い切ると、そのターンの以降の自動撮影はスキップされます。", + "st.imageBudget.maxPerTurn.unlimited": "無制限", + "st.imageBudget.maxDimension.label": "最大画像寸法", + "st.imageBudget.maxDimension.desc": "ビジョンに送るスクリーンショットの長辺(幅または高さ)のピクセル上限。上限を下げると送信前に縮小しトークンとコストを削減。上げると忠実度を保ちます。", + "st.imageBudget.warning": "⚠️ これらの設定はビジョン用のスクリーンショット(自動撮影、/screenshot、全ページ、verify_form)に適用されます。手動で保存したフル解像度画像には影響しません。「Image detail」は OpenAI 系エンドポイントで尊重され、他のプロバイダでは無視されることがあります。", }; diff --git a/src/chrome/src/ui/locales/ko.js b/src/chrome/src/ui/locales/ko.js index 595552e47..f0c1776f7 100644 --- a/src/chrome/src/ui/locales/ko.js +++ b/src/chrome/src/ui/locales/ko.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "스크린샷의 민감한 콘텐츠 마스킹", "st.redaction.toggle.desc": "스크린샷을 비전 모델로 보내기 전에 양식 필드와 이메일이나 전화번호처럼 보이는 텍스트를 흐리게 처리합니다. 감지는 전적으로 사용자 기기에서 실행되며, 추가로 전송되는 데이터는 없습니다.", "st.redaction.warning": "⚠️ 이 기능은 최선을 다하는(best-effort) 방식이며 fail-open입니다. 마스킹이 페이지에서 실행될 수 없는 경우(예: 탐색 직후, PDF 뷰어, 제한된 브라우저 페이지 등) 스크린샷은 마스킹되지 않은 채로 그대로 전송됩니다. 감지는 DOM 휴리스틱만 사용하므로 캔버스에 그려진 텍스트, 이미지 안의 개인정보, 양식 필드나 이메일/전화번호 텍스트로 인식되지 않는 항목은 놓칠 수 있으며, 모델로 전송되는 페이지 텍스트는 이 설정으로 마스킹되지 않습니다. 이는 보안을 보장하는 기능이 아닙니다. 완전한 프라이버시가 필요하다면 로컬/오프라인 모델(llama.cpp, Ollama)을 사용하세요. 이 경우 스크린샷이 기기를 벗어나지 않으므로 마스킹 자체가 필요하지 않습니다.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "이미지 예산", + "st.imageBudget.desc": "스크린샷 크기와 에이전트가 턴마다 비전용으로 캡처하는 횟수를 제어합니다. 세부도와 크기를 낮추면 작은 엔드포인트에서 비용과 지연이 줄고, 높이면 충실도가 유지됩니다. 기본값은 이전 동작과 같습니다.", + "st.imageBudget.detail.label": "이미지 세부도", + "st.imageBudget.detail.desc": "모델에 보내는 비전 이미지 세부도입니다. «high»는 더 많은 세부 유지(토큰·비용 증가); «low»는 더 작고 저렴한 이미지; «auto»는 제공자가 결정. 제공자에 따라 다릅니다.", + "st.imageBudget.detail.high": "높음 (세부 많음, 비용 높음)", + "st.imageBudget.detail.low": "낮음 (저렴, 세부 적음)", + "st.imageBudget.detail.auto": "자동 (제공자 기본값)", + "st.imageBudget.maxPerTurn.label": "턴당 최대 스크린샷", + "st.imageBudget.maxPerTurn.desc": "에이전트가 한 턴에 비전용으로 자동 캡처할 수 있는 횟수(0 = 무제한). 낮을수록 비용이 줄고, 예산을 다 쓰면 해당 턴의 추가 자동 캡처는 건너뜁니다.", + "st.imageBudget.maxPerTurn.unlimited": "무제한", + "st.imageBudget.maxDimension.label": "최대 이미지 치수", + "st.imageBudget.maxDimension.desc": "비전으로 보내는 스크린샷의 긴 변(너비 또는 높이) 픽셀 상한. 낮은 상한은 전송 전 축소로 토큰·비용을 줄이고, 높은 상한은 충실도를 유지합니다.", + "st.imageBudget.warning": "⚠️ 이 설정은 비전용 스크린샷(자동 캡처, /screenshot, 전체 페이지, verify_form)에 적용됩니다. 수동으로 저장한 전체 해상도 이미지는 영향을 받지 않습니다. «Image detail»은 OpenAI 스타일 엔드포인트에서 적용되며 다른 제공자는 무시할 수 있습니다.", }; diff --git a/src/chrome/src/ui/locales/ms.js b/src/chrome/src/ui/locales/ms.js index 335e401ad..998825913 100644 --- a/src/chrome/src/ui/locales/ms.js +++ b/src/chrome/src/ui/locales/ms.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "Samarkan kandungan sensitif dalam tangkapan skrin", "st.redaction.toggle.desc": "Sebelum tangkapan skrin dihantar ke model visi, medan borang dan teks yang kelihatan seperti e-mel atau nombor telefon akan dikaburkan. Pengesanan berjalan sepenuhnya pada peranti anda — tiada apa-apa tambahan dihantar.", "st.redaction.warning": "⚠️ Ini bersifat usaha terbaik (best-effort) dan fail-open: jika penyamaran tidak dapat berjalan pada sesuatu halaman (contohnya sejurus selepas navigasi, dalam pemapar PDF, atau pada halaman pelayar yang dihadkan), tangkapan skrin tetap dihantar tanpa disamarkan. Pengesanan hanya menggunakan heuristik DOM — teks yang dilukis pada canvas, maklumat peribadi dalam imej, atau apa-apa yang tidak dikenali sebagai medan borang atau teks e-mel/telefon mungkin terlepas, dan teks halaman yang dihantar kepada model tidak disamarkan oleh tetapan ini. Ini BUKAN jaminan keselamatan. Untuk privasi sepenuhnya, gunakan model tempatan/luar talian (llama.cpp, Ollama): tangkapan skrin tidak akan meninggalkan peranti anda dan penyamaran menjadi tidak diperlukan.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Bajet imej", + "st.imageBudget.desc": "Mengawal saiz tangkapan skrin dan berapa kali ejen menangkap untuk visi setiap pusingan. Perincian dan dimensi lebih rendah mengurangkan kos dan latensi pada endpoint kecil; lebih tinggi mengekalkan ketepatan. Lalai sepadan dengan tingkah laku sebelumnya.", + "st.imageBudget.detail.label": "Perincian imej", + "st.imageBudget.detail.desc": "Perincian imej visi yang dihantar kepada model. «high» mengekalkan lebih banyak perincian (lebih banyak token dan kos); «low» menghantar imej lebih kecil dan murah; «auto» membiarkan pembekal memutuskan. Bergantung kepada pembekal.", + "st.imageBudget.detail.high": "Tinggi (lebih perincian, lebih kos)", + "st.imageBudget.detail.low": "Rendah (lebih murah, kurang perincian)", + "st.imageBudget.detail.auto": "Auto (lalai pembekal)", + "st.imageBudget.maxPerTurn.label": "Maks. tangkapan setiap pusingan", + "st.imageBudget.maxPerTurn.desc": "Berapa banyak tangkapan automatik yang boleh diambil ejen untuk visi dalam satu pusingan (0 = tanpa had). Nilai lebih rendah mengurangkan kos; selepas bajet habis, tangkapan automatik seterusnya dalam pusingan itu dilangkau.", + "st.imageBudget.maxPerTurn.unlimited": "Tanpa had", + "st.imageBudget.maxDimension.label": "Dimensi imej maksimum", + "st.imageBudget.maxDimension.desc": "Sisi terpanjang (lebar atau tinggi) dalam piksel untuk mana-mana tangkapan yang dihantar ke visi. Had lebih kecil mengecilkan imej sebelum dihantar, mengurangkan token dan kos. Had lebih besar mengekalkan ketepatan.", + "st.imageBudget.warning": "⚠️ Tetapan ini digunakan pada tangkapan untuk visi (tangkapan auto, /screenshot, halaman penuh, verify_form). Imej resolusi penuh yang disimpan secara manual tidak terjejas. «Image detail» dihormati oleh endpoint gaya OpenAI; pembekal lain mungkin mengabaikannya.", }; diff --git a/src/chrome/src/ui/locales/pl.js b/src/chrome/src/ui/locales/pl.js index 0edb1a30c..d28e1bd6d 100644 --- a/src/chrome/src/ui/locales/pl.js +++ b/src/chrome/src/ui/locales/pl.js @@ -664,17 +664,17 @@ export default { "st.redaction.toggle.label": "Redaguj poufną treść na zrzutach ekranu", "st.redaction.toggle.desc": "Zanim zrzut ekranu zostanie wysłany do modelu wizyjnego, rozmywa pola formularzy oraz tekst wyglądający jak e-mail lub numer telefonu. Wykrywanie działa całkowicie na Twoim urządzeniu — nic dodatkowego nie jest przesyłane.", "st.redaction.warning": "⚠️ To redakcja typu best-effort i fail-open: jeśli redakcja nie może zadziałać na danej stronie (np. tuż po nawigacji, w przeglądarkach PDF lub na ograniczonych stronach przeglądarki), zrzut ekranu i tak zostanie wysłany bez redakcji. Wykrywanie opiera się wyłącznie na heurystykach DOM — tekst narysowany na canvasie, dane osobowe wewnątrz obrazów lub cokolwiek nierozpoznanego jako pole formularza czy tekst e-mail/telefon może zostać pominięte, a tekst strony wysyłany do modelu nie jest redagowany przez to ustawienie. To NIE jest gwarancja bezpieczeństwa. Dla pełnej prywatności użyj lokalnego/offline'owego modelu (llama.cpp, Ollama): wtedy zrzuty ekranu nigdy nie opuszczają Twojego urządzenia, a redakcja przestaje być potrzebna.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Budżet obrazów", + "st.imageBudget.desc": "Kontroluje rozmiar zrzutów i ile razy agent robi zrzut na turę na potrzeby vision. Niższy detal i wymiar obniżają koszt i opóźnienie na małych endpointach; wyższe wartości zachowują wierność. Domyślne wartości odpowiadają wcześniejszemu zachowaniu.", + "st.imageBudget.detail.label": "Szczegółowość obrazu", + "st.imageBudget.detail.desc": "Szczegółowość obrazu vision wysyłanego do modelu. «high» zachowuje więcej szczegółów (więcej tokenów i koszt); «low» wysyła mniejszy, tańszy obraz; «auto» zostawia decyzję dostawcy. Zależy od dostawcy.", + "st.imageBudget.detail.high": "Wysoka (więcej szczegółów, wyższy koszt)", + "st.imageBudget.detail.low": "Niska (taniej, mniej szczegółów)", + "st.imageBudget.detail.auto": "Auto (domyślne dostawcy)", + "st.imageBudget.maxPerTurn.label": "Maks. zrzutów na turę", + "st.imageBudget.maxPerTurn.desc": "Ile automatycznych zrzutów agent może wykonać na vision w jednej turze (0 = bez limitu). Niższe wartości obniżają koszt; po wyczerpaniu budżetu kolejne auto-zrzuty w tej turze są pomijane.", + "st.imageBudget.maxPerTurn.unlimited": "Bez limitu", + "st.imageBudget.maxDimension.label": "Maks. wymiar obrazu", + "st.imageBudget.maxDimension.desc": "Najdłuższy bok (szerokość lub wysokość) w pikselach dla każdego zrzutu wysyłanego do vision. Niższy limit zmniejsza obrazy przed wysłaniem, tnąc tokeny i koszt. Wyższy limit zachowuje wierność.", + "st.imageBudget.warning": "⚠️ Te ustawienia dotyczą zrzutów na vision (auto-zrzut, /screenshot, cała strona, verify_form). Ręcznie zapisane obrazy w pełnej rozdzielczości nie są objęte. «Image detail» honorują endpointy w stylu OpenAI; inni dostawcy mogą to ignorować.", }; diff --git a/src/chrome/src/ui/locales/ru.js b/src/chrome/src/ui/locales/ru.js index 474f59c53..daad53bc0 100644 --- a/src/chrome/src/ui/locales/ru.js +++ b/src/chrome/src/ui/locales/ru.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "Скрывать чувствительный контент на скриншотах", "st.redaction.toggle.desc": "Перед отправкой скриншота модели зрения размывает поля форм и текст, похожий на email или номер телефона. Обнаружение выполняется полностью на вашем устройстве — ничего лишнего не передаётся.", "st.redaction.warning": "⚠️ Работает по принципу «максимум усилий» и fail-open: если редактирование не может выполниться на странице (например, сразу после перехода, в просмотрщиках PDF или на ограниченных страницах браузера), скриншот всё равно отправляется неотредактированным. Обнаружение использует только эвристики DOM — текст, нарисованный на canvas, персональные данные внутри изображений или что-либо, не распознанное как поле формы или текст email/телефона, может остаться незамеченным, а текст страницы, отправляемый модели, этой настройкой не редактируется. Это НЕ гарантия безопасности. Для полной приватности используйте локальную/офлайн-модель (llama.cpp, Ollama): тогда скриншоты вообще не покидают ваше устройство и редактирование не требуется.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Бюджет изображений", + "st.imageBudget.desc": "Управляет размером скриншотов и тем, сколько раз агент снимает экран за ход для vision. Меньше детализация и размер — ниже стоимость и задержка на слабых endpoint’ах; больше — выше точность. Значения по умолчанию совпадают с прежним поведением.", + "st.imageBudget.detail.label": "Детализация изображения", + "st.imageBudget.detail.desc": "Детализация vision-изображения, отправляемого модели. «high» сохраняет больше деталей (больше токенов и стоимость); «low» — меньшее и дешевле изображение; «auto» — решение провайдера. Зависит от провайдера.", + "st.imageBudget.detail.high": "Высокая (больше деталей, дороже)", + "st.imageBudget.detail.low": "Низкая (дешевле, меньше деталей)", + "st.imageBudget.detail.auto": "Авто (по умолчанию провайдера)", + "st.imageBudget.maxPerTurn.label": "Макс. скриншотов за ход", + "st.imageBudget.maxPerTurn.desc": "Сколько авто-скриншотов агент может сделать для vision за один ход (0 = без лимита). Меньшие значения снижают стоимость; после исчерпания бюджета дальнейшие авто-скриншоты в этом ходе пропускаются.", + "st.imageBudget.maxPerTurn.unlimited": "Без ограничений", + "st.imageBudget.maxDimension.label": "Макс. размер изображения", + "st.imageBudget.maxDimension.desc": "Наибольшая сторона (ширина или высота) в пикселях для любого скриншота, отправляемого в vision. Меньший предел сжимает изображения до отправки, снижая токены и стоимость. Больший предел сохраняет точность.", + "st.imageBudget.warning": "⚠️ Эти настройки применяются к скриншотам для vision (авто-скриншот, /screenshot, вся страница, verify_form). Вручную сохранённые изображения в полном разрешении не затрагиваются. «Image detail» учитывается endpoint’ами в стиле OpenAI; другие провайдеры могут игнорировать.", }; diff --git a/src/chrome/src/ui/locales/th.js b/src/chrome/src/ui/locales/th.js index 7c20e6f72..43eacd63d 100644 --- a/src/chrome/src/ui/locales/th.js +++ b/src/chrome/src/ui/locales/th.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "เบลอเนื้อหาที่ละเอียดอ่อนในภาพหน้าจอ", "st.redaction.toggle.desc": "ก่อนส่งภาพหน้าจอไปยังโมเดลวิชั่น ระบบจะเบลอช่องฟอร์มและข้อความที่ดูเหมือนอีเมลหรือหมายเลขโทรศัพท์ การตรวจจับทำงานทั้งหมดบนอุปกรณ์ของคุณ — ไม่มีการส่งข้อมูลเพิ่มเติมใดๆ", "st.redaction.warning": "⚠️ ฟีเจอร์นี้เป็นแบบ best-effort และ fail-open: หากการเบลอไม่สามารถทำงานบนหน้าใดหน้าหนึ่งได้ (เช่น ทันทีหลังการนำทาง ในตัวแสดง PDF หรือบนหน้าเบราว์เซอร์ที่ถูกจำกัด) ภาพหน้าจอจะยังคงถูกส่งไปโดยไม่ถูกเบลอ การตรวจจับใช้เพียงหลักการ DOM heuristics เท่านั้น — ข้อความที่วาดบน canvas ข้อมูลส่วนบุคคลในรูปภาพ หรือสิ่งใดก็ตามที่ไม่ถูกจดจำว่าเป็นช่องฟอร์มหรือข้อความอีเมล/โทรศัพท์ อาจหลุดรอดไปได้ และข้อความในหน้าเว็บที่ส่งไปยังโมเดลก็ไม่ถูกเบลอโดยการตั้งค่านี้ นี่ไม่ใช่การรับประกันด้านความปลอดภัย หากต้องการความเป็นส่วนตัวอย่างเต็มที่ ให้ใช้โมเดลภายในเครื่อง/ออฟไลน์ (llama.cpp, Ollama) เพราะภาพหน้าจอจะไม่ออกจากเครื่องของคุณเลย และไม่จำเป็นต้องเบลออีกต่อไป", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "งบประมาณรูปภาพ", + "st.imageBudget.desc": "ควบคุมขนาดภาพหน้าจอและจำนวนครั้งที่เอเจนต์จับภาพเพื่อวิชันต่อเทิร์น รายละเอียดและมิติที่ต่ำกว่าช่วยลดต้นทุนและความหน่วงบน endpoint ขนาดเล็ก ค่าที่สูงกว่าคงความคมชัด ค่าเริ่มต้นตรงกับพฤติกรรมเดิม", + "st.imageBudget.detail.label": "รายละเอียดรูปภาพ", + "st.imageBudget.detail.desc": "รายละเอียดรูปวิชันที่ส่งไปยังโมเดล «high» คงรายละเอียดมากขึ้น (โทเคนและต้นทุนสูงขึ้น) «low» ส่งรูปเล็กและถูกกว่า «auto» ให้ผู้ให้บริการตัดสินใจ ขึ้นกับผู้ให้บริการ", + "st.imageBudget.detail.high": "สูง (รายละเอียดมาก ต้นทุนสูง)", + "st.imageBudget.detail.low": "ต่ำ (ถูกกว่า รายละเอียดน้อย)", + "st.imageBudget.detail.auto": "อัตโนมัติ (ค่าเริ่มต้นของผู้ให้บริการ)", + "st.imageBudget.maxPerTurn.label": "ภาพหน้าจอสูงสุดต่อเทิร์น", + "st.imageBudget.maxPerTurn.desc": "จำนวนภาพอัตโนมัติที่เอเจนต์จับเพื่อวิชันในหนึ่งเทิร์น (0 = ไม่จำกัด) ค่าที่ต่ำกว่าช่วยลดต้นทุน เมื่องบหมดแล้ว ภาพอัตโนมัติถัดไปในเทิร์นนั้นจะถูกข้าม", + "st.imageBudget.maxPerTurn.unlimited": "ไม่จำกัด", + "st.imageBudget.maxDimension.label": "มิติรูปสูงสุด", + "st.imageBudget.maxDimension.desc": "ด้านที่ยาวที่สุด (กว้างหรือสูง) เป็นพิกเซลของภาพที่ส่งไปวิชัน เพดานต่ำกว่าจะย่อภาพก่อนส่ง ลดโทเคนและต้นทุน เพดานสูงกว่าคงความคมชัด", + "st.imageBudget.warning": "⚠️ การตั้งค่าเหล่านี้ใช้กับภาพสำหรับวิชัน (จับอัตโนมัติ, /screenshot, ทั้งหน้า, verify_form) รูปความละเอียดเต็มที่บันทึกด้วยตนเองไม่ได้รับผลกระทบ «Image detail» เคารพโดย endpoint แบบ OpenAI ผู้ให้บริการอื่นอาจละเว้น", }; diff --git a/src/chrome/src/ui/locales/tl.js b/src/chrome/src/ui/locales/tl.js index d9187e817..d0267d551 100644 --- a/src/chrome/src/ui/locales/tl.js +++ b/src/chrome/src/ui/locales/tl.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "Burahin ang sensitibong nilalaman sa mga screenshot", "st.redaction.toggle.desc": "Bago ipadala ang isang screenshot sa isang vision model, binuburahin nito ang mga form field at tekstong mukhang email o numero ng telepono. Tumatakbo ang detection nang buo sa iyong device — walang karagdagang ipinapadala.", "st.redaction.warning": "⚠️ Best-effort at fail-open ito: kung hindi matakbo ang pagbura sa isang page (halimbawa, agad pagkatapos mag-navigate, sa mga PDF viewer, o sa mga restricted browser page), ipapadala pa rin ang screenshot nang hindi nabura. Gumagamit lang ang detection ng DOM heuristics — puwedeng makalusot ang tekstong iginuhit sa canvas, personal na impormasyon sa loob ng mga larawan, o anumang hindi nakikilalang form field o email/phone text, at hindi binubura ng setting na ito ang text ng page na ipinapadala sa model. Hindi ito garantiya ng seguridad. Para sa ganap na privacy, gumamit ng local/offline model (llama.cpp, Ollama): hindi na aalis sa iyong device ang mga screenshot at hindi na kailangan ang pagbura.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Badyet ng imahe", + "st.imageBudget.desc": "Kontrolin ang laki ng screenshot at kung ilang beses kumuha ang agent para sa vision bawat turn. Mas mababang detalye at sukat ay nagpapababa ng gastos at latency sa maliliit na endpoint; mas mataas ay nagpapanatili ng fidelity. Ang default ay tumutugma sa dating gawi.", + "st.imageBudget.detail.label": "Detalye ng imahe", + "st.imageBudget.detail.desc": "Detalye ng vision image na ipinapadala sa modelo. «high» ay mas maraming detalye (mas maraming token at gastos); «low» ay mas maliit at murang imahe; «auto» ay desisyon ng provider. Depende sa provider.", + "st.imageBudget.detail.high": "Mataas (mas detalye, mas gastos)", + "st.imageBudget.detail.low": "Mababa (mas mura, mas kaunting detalye)", + "st.imageBudget.detail.auto": "Auto (default ng provider)", + "st.imageBudget.maxPerTurn.label": "Max na screenshot bawat turn", + "st.imageBudget.maxPerTurn.desc": "Ilang auto-screenshot ang maaaring kunin ng agent para sa vision sa isang turn (0 = walang limit). Mas mababang halaga ay nagpapababa ng gastos; kapag naubos ang badyet, lalaktawan ang susunod na auto-screenshot sa turn na iyon.", + "st.imageBudget.maxPerTurn.unlimited": "Walang limit", + "st.imageBudget.maxDimension.label": "Max na sukat ng imahe", + "st.imageBudget.maxDimension.desc": "Pinakamahabang gilid (lapad o taas) sa pixels para sa anumang screenshot na ipinapadala sa vision. Mas mababang cap ay nagpapaliit ng imahe bago ipadala, binabawasan ang token at gastos. Mas mataas na cap ay nagpapanatili ng fidelity.", + "st.imageBudget.warning": "⚠️ Naaangkop ang mga setting na ito sa screenshot para sa vision (auto-screenshot, /screenshot, buong page, verify_form). Hindi apektado ang manu-manong naka-save na full-resolution na imahe. Iginagalang ang «Image detail» ng OpenAI-style endpoints; maaaring balewalain ng ibang provider.", }; diff --git a/src/chrome/src/ui/locales/tr.js b/src/chrome/src/ui/locales/tr.js index e0f3104f6..9417519b5 100644 --- a/src/chrome/src/ui/locales/tr.js +++ b/src/chrome/src/ui/locales/tr.js @@ -703,17 +703,17 @@ export default { "st.redaction.toggle.label": "Ekran görüntülerindeki hassas içeriği sansürle", "st.redaction.toggle.desc": "Bir ekran görüntüsü bir görüntü modeline gönderilmeden önce, form alanlarını ve e-posta ya da telefon numarasına benzeyen metni bulanıklaştırır. Algılama tamamen cihazınızda çalışır — fazladan hiçbir şey iletilmez.", "st.redaction.warning": "⚠️ En iyi çaba ilkesiyle çalışır ve fail-open'dır: sansürleme bir sayfada çalışamazsa (örneğin bir gezinmeden hemen sonra, PDF görüntüleyicilerde veya kısıtlı tarayıcı sayfalarında), ekran görüntüsü yine de sansürlenmeden gönderilir. Algılama yalnızca DOM sezgisel yöntemlerini kullanır — bir canvas üzerine çizilmiş metin, görsellerin içindeki kişisel veriler veya form alanı ya da e-posta/telefon metni olarak tanınmayan herhangi bir şey gözden kaçabilir; modele gönderilen sayfa metni de bu ayarla sansürlenmez. Bu bir güvenlik garantisi DEĞİLDİR. Tam gizlilik için yerel/çevrimdışı bir model kullanın (llama.cpp, Ollama): bu durumda ekran görüntüleri makinenizden hiç çıkmaz ve sansürleme gereksiz hale gelir.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Görüntü bütçesi", + "st.imageBudget.desc": "Ekran görüntüsü boyutunu ve ajanın tur başına görüş için kaç kez yakalayacağını kontrol eder. Daha düşük ayrıntı ve boyut küçük uçlarda maliyet ve gecikmeyi azaltır; daha yüksek değer sadakati korur. Varsayılanlar önceki davranışla uyumludur.", + "st.imageBudget.detail.label": "Görüntü ayrıntısı", + "st.imageBudget.detail.desc": "Modele gönderilen görüş görüntüsü ayrıntısı. «high» daha fazla ayrıntı tutar (daha fazla token ve maliyet); «low» daha küçük ve ucuz bir görüntü gönderir; «auto» sağlayıcının karar vermesine bırakır. Sağlayıcıya bağlıdır.", + "st.imageBudget.detail.high": "Yüksek (daha fazla ayrıntı, daha fazla maliyet)", + "st.imageBudget.detail.low": "Düşük (daha ucuz, daha az ayrıntı)", + "st.imageBudget.detail.auto": "Otomatik (sağlayıcı varsayılanı)", + "st.imageBudget.maxPerTurn.label": "Tur başına en fazla ekran görüntüsü", + "st.imageBudget.maxPerTurn.desc": "Ajanın bir turda görüş için alabileceği otomatik ekran görüntüsü sayısı (0 = sınırsız). Daha düşük değerler maliyeti azaltır; bütçe dolunca o tur için başka otomatik görüntü alınmaz.", + "st.imageBudget.maxPerTurn.unlimited": "Sınırsız", + "st.imageBudget.maxDimension.label": "En büyük görüntü boyutu", + "st.imageBudget.maxDimension.desc": "Görüşe gönderilen herhangi bir ekran görüntüsünün en uzun kenarı (genişlik veya yükseklik) piksel cinsinden. Daha küçük üst sınır görüntüleri göndermeden önce küçültür, token ve maliyeti düşürür. Daha büyük üst sınır sadakati korur.", + "st.imageBudget.warning": "⚠️ Bu ayarlar görüş için yakalanan ekran görüntülerine uygulanır (otomatik görüntü, /screenshot, tam sayfa, verify_form). Elle kaydedilen tam çözünürlüklü görüntüler etkilenmez. «Image detail» OpenAI tarzı uçlar tarafından uygulanır; diğer sağlayıcılar yok sayabilir.", }; diff --git a/src/chrome/src/ui/locales/uk.js b/src/chrome/src/ui/locales/uk.js index 62817cdf0..67861a792 100644 --- a/src/chrome/src/ui/locales/uk.js +++ b/src/chrome/src/ui/locales/uk.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "Приховувати чутливий вміст на знімках екрана", "st.redaction.toggle.desc": "Перед надсиланням знімка екрана моделі зору розмиває поля форм і текст, схожий на email чи номер телефону. Виявлення виконується повністю на вашому пристрої — нічого зайвого не передається.", "st.redaction.warning": "⚠️ Працює за принципом «найкращих зусиль» і fail-open: якщо редагування не може виконатися на сторінці (наприклад, одразу після переходу, у переглядачах PDF або на обмежених сторінках браузера), знімок екрана все одно надсилається невідредагованим. Виявлення використовує лише евристики DOM — текст, намальований на canvas, персональні дані всередині зображень або будь-що, не розпізнане як поле форми чи текст email/телефону, може залишитися непоміченим, а текст сторінки, що надсилається моделі, цим налаштуванням не редагується. Це НЕ гарантія безпеки. Для повної приватності використовуйте локальну/офлайн-модель (llama.cpp, Ollama): тоді знімки екрана взагалі не покидають ваш пристрій і редагування стає непотрібним.", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Бюджет зображень", + "st.imageBudget.desc": "Керує розміром знімків і тим, скільки разів агент знімає екран за хід для vision. Менша деталізація й розмір — нижча вартість і затримка на слабких endpoint’ах; більші значення зберігають точність. Типові значення збігаються з попередньою поведінкою.", + "st.imageBudget.detail.label": "Деталізація зображення", + "st.imageBudget.detail.desc": "Деталізація vision-зображення, що надсилається моделі. «high» зберігає більше деталей (більше токенів і вартість); «low» — менше й дешевше зображення; «auto» — рішення провайдера. Залежить від провайдера.", + "st.imageBudget.detail.high": "Висока (більше деталей, дорожче)", + "st.imageBudget.detail.low": "Низька (дешевше, менше деталей)", + "st.imageBudget.detail.auto": "Авто (типово для провайдера)", + "st.imageBudget.maxPerTurn.label": "Макс. знімків за хід", + "st.imageBudget.maxPerTurn.desc": "Скільки авто-знімків агент може зробити для vision за один хід (0 = без обмежень). Менші значення знижують вартість; після вичерпання бюджету подальші авто-знімки в цьому ході пропускаються.", + "st.imageBudget.maxPerTurn.unlimited": "Без обмежень", + "st.imageBudget.maxDimension.label": "Макс. розмір зображення", + "st.imageBudget.maxDimension.desc": "Найбільша сторона (ширина або висота) у пікселях для будь-якого знімка, надісланого у vision. Менша межа стискає зображення до надсилання, зменшуючи токени й вартість. Більша межа зберігає точність.", + "st.imageBudget.warning": "⚠️ Ці налаштування застосовуються до знімків для vision (авто-знімок, /screenshot, вся сторінка, verify_form). Вручну збережені зображення в повній роздільності не зачіпаються. «Image detail» враховують endpoint’и в стилі OpenAI; інші провайдери можуть ігнорувати.", }; diff --git a/src/chrome/src/ui/locales/zh.js b/src/chrome/src/ui/locales/zh.js index 1e1b7cdad..86a52254d 100644 --- a/src/chrome/src/ui/locales/zh.js +++ b/src/chrome/src/ui/locales/zh.js @@ -704,17 +704,17 @@ export default { "st.redaction.toggle.label": "对截图中的敏感内容进行打码", "st.redaction.toggle.desc": "在截图发送给视觉模型之前,对表单字段以及看起来像邮箱或电话号码的文本进行打码模糊处理。检测完全在你的设备上运行——不会额外传输任何内容。", "st.redaction.warning": "⚠️ 这是尽力而为且失败开放(fail-open)的处理:如果打码功能在某个页面上无法运行(例如刚导航完成之后、在 PDF 查看器中,或在受限的浏览器页面上),截图仍会以未打码的原样发送。检测仅使用 DOM 启发式方法——canvas 上绘制的文字、图片中的个人信息,或任何未被识别为表单字段或邮箱/电话文本的内容都可能被遗漏,发送给模型的页面文本也不会被此设置打码。这不是安全保证。若需要完全的隐私保护,请使用本地/离线模型(llama.cpp、Ollama):这样截图将永远不会离开你的设备,也就不再需要打码。", - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "图像预算", + "st.imageBudget.desc": "控制截图大小以及代理每轮为视觉模型捕获的次数。更低的细节与尺寸可降低小端点的成本与延迟;更高则保留保真度。默认值与先前行为一致。", + "st.imageBudget.detail.label": "图像细节", + "st.imageBudget.detail.desc": "发送给模型的视觉图像细节。「high」保留更多细节(更多 token 与成本);「low」发送更小、更便宜的图像;「auto」由提供商决定。取决于提供商。", + "st.imageBudget.detail.high": "高(更多细节,更高成本)", + "st.imageBudget.detail.low": "低(更便宜,更少细节)", + "st.imageBudget.detail.auto": "自动(提供商默认)", + "st.imageBudget.maxPerTurn.label": "每轮最大截图数", + "st.imageBudget.maxPerTurn.desc": "代理在单轮中可为视觉捕获的自动截图数量(0 = 无限制)。较低值可降低成本;预算用尽后,该轮将不再进行自动截图。", + "st.imageBudget.maxPerTurn.unlimited": "无限制", + "st.imageBudget.maxDimension.label": "最大图像尺寸", + "st.imageBudget.maxDimension.desc": "发送给视觉的任何截图的最长边(宽或高),单位为像素。更小的上限会在发送前缩小图像,降低 token 与成本;更大的上限保留保真度。", + "st.imageBudget.warning": "⚠️ 这些设置适用于为视觉捕获的截图(自动截图、/screenshot、整页、verify_form)。手动保存的全分辨率图像不受影响。「Image detail」由 OpenAI 风格端点遵循;其他提供商可能忽略。", }; diff --git a/src/firefox/src/ui/locales/ar.js b/src/firefox/src/ui/locales/ar.js index b154e48a0..e8670fd32 100644 --- a/src/firefox/src/ui/locales/ar.js +++ b/src/firefox/src/ui/locales/ar.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "الخصوصية: تُخزَّن ذاكرة المستخدم كنص عادي في ملف تعريف المتصفح هذا. عند تمكينها، تُرسل سجلات الذاكرة النشطة إلى موفّر LLM الذي تضبطه كجزء من مطالبة النظام. لا تخزّن هنا كلمات المرور أو مفاتيح API أو الرموز المميزة أو رموز الاسترداد أو الأسرار الحساسة.", "hist.filter.clear": "مسح عامل التصفية وعرض كل المحادثات", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "ميزانية الصور", + "st.imageBudget.desc": "يتحكم في حجم لقطات الشاشة وعدد ما يلتقطه الوكيل لكل جولة للرؤية. تقليل التفاصيل والأبعاد يخفض التكلفة والكمون على النقاط الطرفية الصغيرة؛ زيادتها تحافظ على الدقة. القيم الافتراضية تطابق السلوك السابق.", + "st.imageBudget.detail.label": "تفاصيل الصورة", + "st.imageBudget.detail.desc": "تفاصيل صورة الرؤية المُرسلة إلى النموذج. «high» يحافظ على مزيد من التفاصيل (مزيد من الرموز والتكلفة)؛ «low» يرسل صورة أصغر وأرخص؛ «auto» يترك القرار للمزوّد. يعتمد على المزوّد.", + "st.imageBudget.detail.high": "عالية (مزيد من التفاصيل والتكلفة)", + "st.imageBudget.detail.low": "منخفضة (أرخص وأقل تفاصيل)", + "st.imageBudget.detail.auto": "تلقائي (افتراضي المزوّد)", + "st.imageBudget.maxPerTurn.label": "أقصى لقطات لكل جولة", + "st.imageBudget.maxPerTurn.desc": "كم لقطة تلقائية يمكن للوكيل التقاطها للرؤية في جولة واحدة (0 = بلا حد). القيم الأقل تخفض التكلفة؛ عند استنفاد الميزانية تُتخطى اللقطات التلقائية اللاحقة في تلك الجولة.", + "st.imageBudget.maxPerTurn.unlimited": "بلا حد", + "st.imageBudget.maxDimension.label": "أقصى بُعد للصورة", + "st.imageBudget.maxDimension.desc": "أطول ضلع (العرض أو الارتفاع) بالبكسل لأي لقطة تُرسل إلى الرؤية. حد أصغر يصغّر الصور قبل الإرسال فيخفض الرموز والتكلفة. حد أكبر يحافظ على الدقة.", + "st.imageBudget.warning": "⚠️ تنطبق هذه الإعدادات على اللقطات المخصصة للرؤية (لقطة تلقائية، /screenshot، صفحة كاملة، verify_form). الصور المحفوظة يدويًا بدقة كاملة لا تتأثر. «Image detail» تحترمه نقاط النهاية بأسلوب OpenAI؛ قد يتجاهلها مزوّدون آخرون.", "st.redaction.heading": "تعتيم لقطات الشاشة", "st.redaction.toggle.label": "إخفاء المحتوى الحساس في لقطات الشاشة", diff --git a/src/firefox/src/ui/locales/es.js b/src/firefox/src/ui/locales/es.js index c00fcdd85..d1aabca14 100644 --- a/src/firefox/src/ui/locales/es.js +++ b/src/firefox/src/ui/locales/es.js @@ -700,19 +700,19 @@ export default { "st.memory.security_html": "Privacidad: la memoria del usuario se almacena como texto sin formato en este perfil del navegador. Cuando está activada, los registros de memoria activos se envían al proveedor de LLM que configures como parte de las instrucciones del sistema. No guardes aquí contraseñas, claves de API, tokens, códigos de recuperación ni secretos sensibles.", "hist.filter.clear": "Borrar el filtro y mostrar todas las conversaciones", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Presupuesto de imágenes", + "st.imageBudget.desc": "Controla el tamaño de las capturas y cuántas toma el agente por turno para visión. Menor detalle y dimensión reducen coste y latencia en endpoints pequeños; mayor valor mantiene la fidelidad. Los valores predeterminados coinciden con el comportamiento anterior.", + "st.imageBudget.detail.label": "Detalle de imagen", + "st.imageBudget.detail.desc": "Detalle de la imagen de visión enviada al modelo. «high» conserva más detalle (más tokens y coste); «low» envía una imagen más pequeña y barata; «auto» deja decidir al proveedor. Depende del proveedor.", + "st.imageBudget.detail.high": "Alto (más detalle, más coste)", + "st.imageBudget.detail.low": "Bajo (más barato, menos detalle)", + "st.imageBudget.detail.auto": "Automático (predeterminado del proveedor)", + "st.imageBudget.maxPerTurn.label": "Máx. capturas por turno", + "st.imageBudget.maxPerTurn.desc": "Cuántas capturas automáticas puede tomar el agente para visión en un solo turno (0 = ilimitado). Valores más bajos reducen el coste; cuando se agota el presupuesto, no se toman más capturas automáticas en ese turno.", + "st.imageBudget.maxPerTurn.unlimited": "Ilimitado", + "st.imageBudget.maxDimension.label": "Dimensión máxima de imagen", + "st.imageBudget.maxDimension.desc": "Lado mayor (ancho o alto) en píxeles de cualquier captura enviada a visión. Un tope más bajo reduce las imágenes antes de enviarlas, cortando tokens y coste. Un tope más alto mantiene la fidelidad.", + "st.imageBudget.warning": "⚠️ Estos ajustes se aplican a capturas para visión (auto-captura, /screenshot, página completa, verify_form). Las imágenes guardadas manualmente a resolución completa no se ven afectadas. «Image detail» lo respetan endpoints estilo OpenAI; otros proveedores pueden ignorarlo.", "st.redaction.heading": "Redacción de capturas de pantalla", "st.redaction.toggle.label": "Redactar contenido sensible en las capturas de pantalla", diff --git a/src/firefox/src/ui/locales/fr.js b/src/firefox/src/ui/locales/fr.js index 493c2b7d3..e970f94ee 100644 --- a/src/firefox/src/ui/locales/fr.js +++ b/src/firefox/src/ui/locales/fr.js @@ -700,19 +700,19 @@ export default { "st.memory.security_html": "Confidentialité : la mémoire utilisateur est stockée en texte brut dans ce profil de navigateur. Lorsqu’elle est activée, les enregistrements de mémoire actifs sont envoyés au fournisseur LLM configuré dans l’invite système. N’y enregistrez pas de mots de passe, clés API, jetons, codes de récupération ou secrets sensibles.", "hist.filter.clear": "Effacer le filtre et afficher toutes les conversations", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Budget d’images", + "st.imageBudget.desc": "Contrôle la taille des captures et le nombre que l’agent prend pour la vision par tour. Moins de détail et une dimension plus petite réduisent le coût et la latence sur les petits endpoints ; plus élevé conserve la fidélité. Les valeurs par défaut reprennent le comportement précédent.", + "st.imageBudget.detail.label": "Détail d’image", + "st.imageBudget.detail.desc": "Détail d’image vision envoyé au modèle. « high » garde plus de détail (plus de tokens et de coût) ; « low » envoie une image plus petite et moins chère ; « auto » laisse le fournisseur décider. Dépend du fournisseur.", + "st.imageBudget.detail.high": "Élevé (plus de détail, plus de coût)", + "st.imageBudget.detail.low": "Faible (moins cher, moins de détail)", + "st.imageBudget.detail.auto": "Auto (défaut du fournisseur)", + "st.imageBudget.maxPerTurn.label": "Captures max. par tour", + "st.imageBudget.maxPerTurn.desc": "Nombre de captures auto que l’agent peut prendre pour la vision dans un tour (0 = illimité). Une valeur plus basse réduit le coût ; une fois le budget épuisé, les captures auto suivantes sont ignorées pour ce tour.", + "st.imageBudget.maxPerTurn.unlimited": "Illimité", + "st.imageBudget.maxDimension.label": "Dimension max. d’image", + "st.imageBudget.maxDimension.desc": "Plus grand côté (largeur ou hauteur) en pixels pour toute capture envoyée à la vision. Un plafond plus bas réduit les images avant envoi, ce qui coupe tokens et coût. Un plafond plus haut conserve la fidélité.", + "st.imageBudget.warning": "⚠️ Ces réglages s’appliquent aux captures pour la vision (auto-capture, /screenshot, page entière, verify_form). Les images enregistrées manuellement en pleine résolution ne sont pas affectées. « Image detail » est respecté par les endpoints de type OpenAI ; d’autres fournisseurs peuvent l’ignorer.", "st.redaction.heading": "Floutage des captures d'écran", "st.redaction.toggle.label": "Flouter le contenu sensible dans les captures d'écran", diff --git a/src/firefox/src/ui/locales/he.js b/src/firefox/src/ui/locales/he.js index 64010f13a..b21f30e49 100644 --- a/src/firefox/src/ui/locales/he.js +++ b/src/firefox/src/ui/locales/he.js @@ -654,19 +654,19 @@ export default { "tr.event.step": "שָׁלָב {step}", "sp.perm.verb.record": "להקליט את הכרטיסייה (ואת המיקרופון) באתר", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "תקציב תמונות", + "st.imageBudget.desc": "שולט בגודל צילומי המסך ובכמה פעמים הסוכן מצלם לצורכי ראייה בכל תור. פרט ומימד נמוכים יותר מפחיתים עלות והשהיה בקצוות קטנים; גבוהים יותר שומרים על נאמנות. ברירות המחדל תואמות להתנהגות הקודמת.", + "st.imageBudget.detail.label": "רמת פירוט תמונה", + "st.imageBudget.detail.desc": "רמת פירוט תמונת הראייה שנשלחת למודל. «high» שומר יותר פרטים (יותר טוקנים ועלות); «low» שולח תמונה קטנה וזולה יותר; «auto» משאיר לספק להחליט. תלוי בספק.", + "st.imageBudget.detail.high": "גבוה (יותר פרטים, יותר עלות)", + "st.imageBudget.detail.low": "נמוך (זול יותר, פחות פרטים)", + "st.imageBudget.detail.auto": "אוטומטי (ברירת מחדל של הספק)", + "st.imageBudget.maxPerTurn.label": "מקס׳ צילומים לתור", + "st.imageBudget.maxPerTurn.desc": "כמה צילומי מסך אוטומטיים הסוכן רשאי לצלם לראייה בתור אחד (0 = ללא הגבלה). ערכים נמוכים מפחיתים עלות; כשהתקציב נגמר, צילומים אוטומטיים נוספים בתור הזה מדולגים.", + "st.imageBudget.maxPerTurn.unlimited": "ללא הגבלה", + "st.imageBudget.maxDimension.label": "ממד תמונה מרבי", + "st.imageBudget.maxDimension.desc": "הצלע הארוכה (רוחב או גובה) בפיקסלים לכל צילום שנשלח לראייה. תקרה נמוכה יותר מקטינה תמונות לפני השליחה ומורידה טוקנים ועלות. תקרה גבוהה יותר שומרת נאמנות.", + "st.imageBudget.warning": "⚠️ ההגדרות האלה חלות על צילומים לראייה (צילום אוטומטי, /screenshot, עמוד מלא, verify_form). תמונות שנשמרו ידנית ברזולוציה מלאה אינן מושפעות. «Image detail» מכובד על ידי נקודות קצה בסגנון OpenAI; ספקים אחרים עשויים להתעלם.", "st.redaction.heading": "טשטוש צילומי מסך", "st.redaction.toggle.label": "טשטש תוכן רגיש בצילומי מסך", diff --git a/src/firefox/src/ui/locales/id.js b/src/firefox/src/ui/locales/id.js index 4251c27a9..3afafabb9 100644 --- a/src/firefox/src/ui/locales/id.js +++ b/src/firefox/src/ui/locales/id.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "Privasi: memori pengguna disimpan sebagai teks biasa di profil peramban ini. Saat diaktifkan, catatan memori aktif dikirim ke penyedia LLM yang Anda konfigurasikan sebagai bagian dari prompt sistem. Jangan simpan kata sandi, kunci API, token, kode pemulihan, atau rahasia sensitif di sini.", "hist.filter.clear": "Bersihkan filter dan tampilkan semua percakapan", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Anggaran gambar", + "st.imageBudget.desc": "Mengontrol ukuran tangkapan layar dan berapa kali agen menangkap untuk visi per giliran. Detail dan dimensi lebih rendah mengurangi biaya dan latensi di endpoint kecil; lebih tinggi menjaga fidelitas. Default cocok dengan perilaku sebelumnya.", + "st.imageBudget.detail.label": "Detail gambar", + "st.imageBudget.detail.desc": "Detail gambar visi yang dikirim ke model. «high» mempertahankan lebih banyak detail (lebih banyak token dan biaya); «low» mengirim gambar lebih kecil dan murah; «auto» membiarkan penyedia memutuskan. Bergantung pada penyedia.", + "st.imageBudget.detail.high": "Tinggi (lebih detail, lebih mahal)", + "st.imageBudget.detail.low": "Rendah (lebih murah, lebih sedikit detail)", + "st.imageBudget.detail.auto": "Otomatis (default penyedia)", + "st.imageBudget.maxPerTurn.label": "Maks. tangkapan per giliran", + "st.imageBudget.maxPerTurn.desc": "Berapa banyak tangkapan otomatis yang boleh diambil agen untuk visi dalam satu giliran (0 = tanpa batas). Nilai lebih rendah mengurangi biaya; setelah anggaran habis, tangkapan otomatis berikutnya di giliran itu dilewati.", + "st.imageBudget.maxPerTurn.unlimited": "Tanpa batas", + "st.imageBudget.maxDimension.label": "Dimensi gambar maksimum", + "st.imageBudget.maxDimension.desc": "Sisi terpanjang (lebar atau tinggi) dalam piksel untuk setiap tangkapan yang dikirim ke visi. Batas lebih kecil mengecilkan gambar sebelum dikirim, mengurangi token dan biaya. Batas lebih besar menjaga fidelitas.", + "st.imageBudget.warning": "⚠️ Pengaturan ini berlaku untuk tangkapan untuk visi (tangkapan otomatis, /screenshot, halaman penuh, verify_form). Gambar resolusi penuh yang disimpan manual tidak terpengaruh. «Image detail» dihormati endpoint bergaya OpenAI; penyedia lain mungkin mengabaikannya.", "st.redaction.heading": "Penyamaran tangkapan layar", "st.redaction.toggle.label": "Samarkan konten sensitif pada tangkapan layar", diff --git a/src/firefox/src/ui/locales/ja.js b/src/firefox/src/ui/locales/ja.js index e1135fd4a..b7b1634f7 100644 --- a/src/firefox/src/ui/locales/ja.js +++ b/src/firefox/src/ui/locales/ja.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "プライバシー: ユーザーメモリは、このブラウザープロフィールにプレーンテキストで保存されます。有効にすると、有効なメモリ記録がシステムプロンプトの一部として、設定した LLM プロバイダーに送信されます。パスワード、API キー、トークン、復旧コード、機密情報は保存しないでください。", "hist.filter.clear": "フィルターを消去してすべての会話を表示", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "画像予算", + "st.imageBudget.desc": "スクリーンショットのサイズと、エージェントが 1 ターンあたりビジョン用に撮影する回数を制御します。詳細度と寸法を下げると小型エンドポイントでのコストと遅延が減り、上げると忠実度が保たれます。既定値は以前の動作と同じです。", + "st.imageBudget.detail.label": "画像の詳細度", + "st.imageBudget.detail.desc": "モデルに送るビジョン画像の詳細度。「high」はより多くの詳細を保持(トークンとコスト増);「low」は小さく安価な画像;「auto」はプロバイダ任せ。プロバイダ依存です。", + "st.imageBudget.detail.high": "高(詳細多・コスト高)", + "st.imageBudget.detail.low": "低(安価・詳細少)", + "st.imageBudget.detail.auto": "自動(プロバイダ既定)", + "st.imageBudget.maxPerTurn.label": "1 ターンあたりの最大スクリーンショット数", + "st.imageBudget.maxPerTurn.desc": "エージェントが 1 ターンでビジョン用に自動撮影できる回数(0 = 無制限)。低い値はコストを下げます。予算を使い切ると、そのターンの以降の自動撮影はスキップされます。", + "st.imageBudget.maxPerTurn.unlimited": "無制限", + "st.imageBudget.maxDimension.label": "最大画像寸法", + "st.imageBudget.maxDimension.desc": "ビジョンに送るスクリーンショットの長辺(幅または高さ)のピクセル上限。上限を下げると送信前に縮小しトークンとコストを削減。上げると忠実度を保ちます。", + "st.imageBudget.warning": "⚠️ これらの設定はビジョン用のスクリーンショット(自動撮影、/screenshot、全ページ、verify_form)に適用されます。手動で保存したフル解像度画像には影響しません。「Image detail」は OpenAI 系エンドポイントで尊重され、他のプロバイダでは無視されることがあります。", "st.redaction.heading": "スクリーンショットの黒塗り", "st.redaction.toggle.label": "スクリーンショット内の機密情報を黒塗りする", diff --git a/src/firefox/src/ui/locales/ko.js b/src/firefox/src/ui/locales/ko.js index 45af36646..451cf9d56 100644 --- a/src/firefox/src/ui/locales/ko.js +++ b/src/firefox/src/ui/locales/ko.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "개인정보 보호: 사용자 메모리는 이 브라우저 프로필에 일반 텍스트로 저장됩니다. 사용하면 활성 메모리 기록이 시스템 프롬프트의 일부로 설정한 LLM 공급자에게 전송됩니다. 비밀번호, API 키, 토큰, 복구 코드 또는 민감한 비밀 정보는 저장하지 마세요.", "hist.filter.clear": "필터를 지우고 모든 대화 표시", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "이미지 예산", + "st.imageBudget.desc": "스크린샷 크기와 에이전트가 턴마다 비전용으로 캡처하는 횟수를 제어합니다. 세부도와 크기를 낮추면 작은 엔드포인트에서 비용과 지연이 줄고, 높이면 충실도가 유지됩니다. 기본값은 이전 동작과 같습니다.", + "st.imageBudget.detail.label": "이미지 세부도", + "st.imageBudget.detail.desc": "모델에 보내는 비전 이미지 세부도입니다. «high»는 더 많은 세부 유지(토큰·비용 증가); «low»는 더 작고 저렴한 이미지; «auto»는 제공자가 결정. 제공자에 따라 다릅니다.", + "st.imageBudget.detail.high": "높음 (세부 많음, 비용 높음)", + "st.imageBudget.detail.low": "낮음 (저렴, 세부 적음)", + "st.imageBudget.detail.auto": "자동 (제공자 기본값)", + "st.imageBudget.maxPerTurn.label": "턴당 최대 스크린샷", + "st.imageBudget.maxPerTurn.desc": "에이전트가 한 턴에 비전용으로 자동 캡처할 수 있는 횟수(0 = 무제한). 낮을수록 비용이 줄고, 예산을 다 쓰면 해당 턴의 추가 자동 캡처는 건너뜁니다.", + "st.imageBudget.maxPerTurn.unlimited": "무제한", + "st.imageBudget.maxDimension.label": "최대 이미지 치수", + "st.imageBudget.maxDimension.desc": "비전으로 보내는 스크린샷의 긴 변(너비 또는 높이) 픽셀 상한. 낮은 상한은 전송 전 축소로 토큰·비용을 줄이고, 높은 상한은 충실도를 유지합니다.", + "st.imageBudget.warning": "⚠️ 이 설정은 비전용 스크린샷(자동 캡처, /screenshot, 전체 페이지, verify_form)에 적용됩니다. 수동으로 저장한 전체 해상도 이미지는 영향을 받지 않습니다. «Image detail»은 OpenAI 스타일 엔드포인트에서 적용되며 다른 제공자는 무시할 수 있습니다.", "st.redaction.heading": "스크린샷 마스킹", "st.redaction.toggle.label": "스크린샷의 민감한 콘텐츠 마스킹", diff --git a/src/firefox/src/ui/locales/ms.js b/src/firefox/src/ui/locales/ms.js index da4231a16..9910fede4 100644 --- a/src/firefox/src/ui/locales/ms.js +++ b/src/firefox/src/ui/locales/ms.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "Privasi: memori pengguna disimpan sebagai teks biasa dalam profil pelayar ini. Apabila diaktifkan, rekod memori aktif dihantar kepada pembekal LLM yang anda konfigurasikan sebagai sebahagian daripada system prompt. Jangan simpan kata laluan, kunci API, token, kod pemulihan atau rahsia sensitif di sini.", "hist.filter.clear": "Kosongkan penapis dan tunjukkan semua perbualan", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Bajet imej", + "st.imageBudget.desc": "Mengawal saiz tangkapan skrin dan berapa kali ejen menangkap untuk visi setiap pusingan. Perincian dan dimensi lebih rendah mengurangkan kos dan latensi pada endpoint kecil; lebih tinggi mengekalkan ketepatan. Lalai sepadan dengan tingkah laku sebelumnya.", + "st.imageBudget.detail.label": "Perincian imej", + "st.imageBudget.detail.desc": "Perincian imej visi yang dihantar kepada model. «high» mengekalkan lebih banyak perincian (lebih banyak token dan kos); «low» menghantar imej lebih kecil dan murah; «auto» membiarkan pembekal memutuskan. Bergantung kepada pembekal.", + "st.imageBudget.detail.high": "Tinggi (lebih perincian, lebih kos)", + "st.imageBudget.detail.low": "Rendah (lebih murah, kurang perincian)", + "st.imageBudget.detail.auto": "Auto (lalai pembekal)", + "st.imageBudget.maxPerTurn.label": "Maks. tangkapan setiap pusingan", + "st.imageBudget.maxPerTurn.desc": "Berapa banyak tangkapan automatik yang boleh diambil ejen untuk visi dalam satu pusingan (0 = tanpa had). Nilai lebih rendah mengurangkan kos; selepas bajet habis, tangkapan automatik seterusnya dalam pusingan itu dilangkau.", + "st.imageBudget.maxPerTurn.unlimited": "Tanpa had", + "st.imageBudget.maxDimension.label": "Dimensi imej maksimum", + "st.imageBudget.maxDimension.desc": "Sisi terpanjang (lebar atau tinggi) dalam piksel untuk mana-mana tangkapan yang dihantar ke visi. Had lebih kecil mengecilkan imej sebelum dihantar, mengurangkan token dan kos. Had lebih besar mengekalkan ketepatan.", + "st.imageBudget.warning": "⚠️ Tetapan ini digunakan pada tangkapan untuk visi (tangkapan auto, /screenshot, halaman penuh, verify_form). Imej resolusi penuh yang disimpan secara manual tidak terjejas. «Image detail» dihormati oleh endpoint gaya OpenAI; pembekal lain mungkin mengabaikannya.", "st.redaction.heading": "Penyamaran tangkapan skrin", "st.redaction.toggle.label": "Samarkan kandungan sensitif dalam tangkapan skrin", diff --git a/src/firefox/src/ui/locales/pl.js b/src/firefox/src/ui/locales/pl.js index a9ac9c080..68472e290 100644 --- a/src/firefox/src/ui/locales/pl.js +++ b/src/firefox/src/ui/locales/pl.js @@ -658,19 +658,19 @@ export default { "st.memory.security_html": "Prywatność: pamięć użytkownika jest przechowywana jako zwykły tekst w tym profilu przeglądarki. Po włączeniu aktywne wpisy pamięci są wysyłane do skonfigurowanego dostawcy LLM jako część promptu systemowego. Nie zapisuj tutaj haseł, kluczy API, tokenów, kodów odzyskiwania ani poufnych sekretów.", "hist.filter.clear": "Wyczyść filtr i pokaż wszystkie rozmowy", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Budżet obrazów", + "st.imageBudget.desc": "Kontroluje rozmiar zrzutów i ile razy agent robi zrzut na turę na potrzeby vision. Niższy detal i wymiar obniżają koszt i opóźnienie na małych endpointach; wyższe wartości zachowują wierność. Domyślne wartości odpowiadają wcześniejszemu zachowaniu.", + "st.imageBudget.detail.label": "Szczegółowość obrazu", + "st.imageBudget.detail.desc": "Szczegółowość obrazu vision wysyłanego do modelu. «high» zachowuje więcej szczegółów (więcej tokenów i koszt); «low» wysyła mniejszy, tańszy obraz; «auto» zostawia decyzję dostawcy. Zależy od dostawcy.", + "st.imageBudget.detail.high": "Wysoka (więcej szczegółów, wyższy koszt)", + "st.imageBudget.detail.low": "Niska (taniej, mniej szczegółów)", + "st.imageBudget.detail.auto": "Auto (domyślne dostawcy)", + "st.imageBudget.maxPerTurn.label": "Maks. zrzutów na turę", + "st.imageBudget.maxPerTurn.desc": "Ile automatycznych zrzutów agent może wykonać na vision w jednej turze (0 = bez limitu). Niższe wartości obniżają koszt; po wyczerpaniu budżetu kolejne auto-zrzuty w tej turze są pomijane.", + "st.imageBudget.maxPerTurn.unlimited": "Bez limitu", + "st.imageBudget.maxDimension.label": "Maks. wymiar obrazu", + "st.imageBudget.maxDimension.desc": "Najdłuższy bok (szerokość lub wysokość) w pikselach dla każdego zrzutu wysyłanego do vision. Niższy limit zmniejsza obrazy przed wysłaniem, tnąc tokeny i koszt. Wyższy limit zachowuje wierność.", + "st.imageBudget.warning": "⚠️ Te ustawienia dotyczą zrzutów na vision (auto-zrzut, /screenshot, cała strona, verify_form). Ręcznie zapisane obrazy w pełnej rozdzielczości nie są objęte. «Image detail» honorują endpointy w stylu OpenAI; inni dostawcy mogą to ignorować.", "st.redaction.heading": "Redakcja zrzutów ekranu", "st.redaction.toggle.label": "Redaguj poufną treść na zrzutach ekranu", diff --git a/src/firefox/src/ui/locales/ru.js b/src/firefox/src/ui/locales/ru.js index 692f8cc2f..1c23d8cb5 100644 --- a/src/firefox/src/ui/locales/ru.js +++ b/src/firefox/src/ui/locales/ru.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "Конфиденциальность: память пользователя хранится открытым текстом в этом профиле браузера. Когда она включена, активные записи памяти отправляются выбранному провайдеру LLM как часть системного промпта. Не храните здесь пароли, API-ключи, токены, коды восстановления или другие конфиденциальные секреты.", "hist.filter.clear": "Очистить фильтр и показать все разговоры", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Бюджет изображений", + "st.imageBudget.desc": "Управляет размером скриншотов и тем, сколько раз агент снимает экран за ход для vision. Меньше детализация и размер — ниже стоимость и задержка на слабых endpoint’ах; больше — выше точность. Значения по умолчанию совпадают с прежним поведением.", + "st.imageBudget.detail.label": "Детализация изображения", + "st.imageBudget.detail.desc": "Детализация vision-изображения, отправляемого модели. «high» сохраняет больше деталей (больше токенов и стоимость); «low» — меньшее и дешевле изображение; «auto» — решение провайдера. Зависит от провайдера.", + "st.imageBudget.detail.high": "Высокая (больше деталей, дороже)", + "st.imageBudget.detail.low": "Низкая (дешевле, меньше деталей)", + "st.imageBudget.detail.auto": "Авто (по умолчанию провайдера)", + "st.imageBudget.maxPerTurn.label": "Макс. скриншотов за ход", + "st.imageBudget.maxPerTurn.desc": "Сколько авто-скриншотов агент может сделать для vision за один ход (0 = без лимита). Меньшие значения снижают стоимость; после исчерпания бюджета дальнейшие авто-скриншоты в этом ходе пропускаются.", + "st.imageBudget.maxPerTurn.unlimited": "Без ограничений", + "st.imageBudget.maxDimension.label": "Макс. размер изображения", + "st.imageBudget.maxDimension.desc": "Наибольшая сторона (ширина или высота) в пикселях для любого скриншота, отправляемого в vision. Меньший предел сжимает изображения до отправки, снижая токены и стоимость. Больший предел сохраняет точность.", + "st.imageBudget.warning": "⚠️ Эти настройки применяются к скриншотам для vision (авто-скриншот, /screenshot, вся страница, verify_form). Вручную сохранённые изображения в полном разрешении не затрагиваются. «Image detail» учитывается endpoint’ами в стиле OpenAI; другие провайдеры могут игнорировать.", "st.redaction.heading": "Редактирование скриншотов", "st.redaction.toggle.label": "Скрывать чувствительный контент на скриншотах", diff --git a/src/firefox/src/ui/locales/th.js b/src/firefox/src/ui/locales/th.js index a260b1170..48b2f5fc9 100644 --- a/src/firefox/src/ui/locales/th.js +++ b/src/firefox/src/ui/locales/th.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "ความเป็นส่วนตัว: หน่วยความจำผู้ใช้ถูกเก็บเป็นข้อความธรรมดาในโปรไฟล์เบราว์เซอร์นี้ เมื่อเปิดใช้งาน บันทึกหน่วยความจำที่ใช้งานอยู่จะถูกส่งไปยังผู้ให้บริการ LLM ที่คุณตั้งค่าไว้โดยเป็นส่วนหนึ่งของ system prompt อย่าเก็บรหัสผ่าน คีย์ API โทเค็น รหัสกู้คืน หรือข้อมูลลับที่ละเอียดอ่อนไว้ที่นี่", "hist.filter.clear": "ล้างตัวกรองและแสดงการสนทนาทั้งหมด", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "งบประมาณรูปภาพ", + "st.imageBudget.desc": "ควบคุมขนาดภาพหน้าจอและจำนวนครั้งที่เอเจนต์จับภาพเพื่อวิชันต่อเทิร์น รายละเอียดและมิติที่ต่ำกว่าช่วยลดต้นทุนและความหน่วงบน endpoint ขนาดเล็ก ค่าที่สูงกว่าคงความคมชัด ค่าเริ่มต้นตรงกับพฤติกรรมเดิม", + "st.imageBudget.detail.label": "รายละเอียดรูปภาพ", + "st.imageBudget.detail.desc": "รายละเอียดรูปวิชันที่ส่งไปยังโมเดล «high» คงรายละเอียดมากขึ้น (โทเคนและต้นทุนสูงขึ้น) «low» ส่งรูปเล็กและถูกกว่า «auto» ให้ผู้ให้บริการตัดสินใจ ขึ้นกับผู้ให้บริการ", + "st.imageBudget.detail.high": "สูง (รายละเอียดมาก ต้นทุนสูง)", + "st.imageBudget.detail.low": "ต่ำ (ถูกกว่า รายละเอียดน้อย)", + "st.imageBudget.detail.auto": "อัตโนมัติ (ค่าเริ่มต้นของผู้ให้บริการ)", + "st.imageBudget.maxPerTurn.label": "ภาพหน้าจอสูงสุดต่อเทิร์น", + "st.imageBudget.maxPerTurn.desc": "จำนวนภาพอัตโนมัติที่เอเจนต์จับเพื่อวิชันในหนึ่งเทิร์น (0 = ไม่จำกัด) ค่าที่ต่ำกว่าช่วยลดต้นทุน เมื่องบหมดแล้ว ภาพอัตโนมัติถัดไปในเทิร์นนั้นจะถูกข้าม", + "st.imageBudget.maxPerTurn.unlimited": "ไม่จำกัด", + "st.imageBudget.maxDimension.label": "มิติรูปสูงสุด", + "st.imageBudget.maxDimension.desc": "ด้านที่ยาวที่สุด (กว้างหรือสูง) เป็นพิกเซลของภาพที่ส่งไปวิชัน เพดานต่ำกว่าจะย่อภาพก่อนส่ง ลดโทเคนและต้นทุน เพดานสูงกว่าคงความคมชัด", + "st.imageBudget.warning": "⚠️ การตั้งค่าเหล่านี้ใช้กับภาพสำหรับวิชัน (จับอัตโนมัติ, /screenshot, ทั้งหน้า, verify_form) รูปความละเอียดเต็มที่บันทึกด้วยตนเองไม่ได้รับผลกระทบ «Image detail» เคารพโดย endpoint แบบ OpenAI ผู้ให้บริการอื่นอาจละเว้น", "st.redaction.heading": "การเบลอภาพหน้าจอ", "st.redaction.toggle.label": "เบลอเนื้อหาที่ละเอียดอ่อนในภาพหน้าจอ", diff --git a/src/firefox/src/ui/locales/tl.js b/src/firefox/src/ui/locales/tl.js index ff476e8ca..f0a8059e5 100644 --- a/src/firefox/src/ui/locales/tl.js +++ b/src/firefox/src/ui/locales/tl.js @@ -698,19 +698,19 @@ export default { "st.memory.security_html": "Privacy: naka-store bilang plain text ang memory ng user sa browser profile na ito. Kapag naka-enable, ipinapadala ang mga aktibong memory record sa naka-configure mong LLM provider bilang bahagi ng system prompt. Huwag mag-store dito ng mga password, API key, token, recovery code, o sensitibong lihim.", "hist.filter.clear": "I-clear ang filter at ipakita ang lahat ng pag-uusap", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Badyet ng imahe", + "st.imageBudget.desc": "Kontrolin ang laki ng screenshot at kung ilang beses kumuha ang agent para sa vision bawat turn. Mas mababang detalye at sukat ay nagpapababa ng gastos at latency sa maliliit na endpoint; mas mataas ay nagpapanatili ng fidelity. Ang default ay tumutugma sa dating gawi.", + "st.imageBudget.detail.label": "Detalye ng imahe", + "st.imageBudget.detail.desc": "Detalye ng vision image na ipinapadala sa modelo. «high» ay mas maraming detalye (mas maraming token at gastos); «low» ay mas maliit at murang imahe; «auto» ay desisyon ng provider. Depende sa provider.", + "st.imageBudget.detail.high": "Mataas (mas detalye, mas gastos)", + "st.imageBudget.detail.low": "Mababa (mas mura, mas kaunting detalye)", + "st.imageBudget.detail.auto": "Auto (default ng provider)", + "st.imageBudget.maxPerTurn.label": "Max na screenshot bawat turn", + "st.imageBudget.maxPerTurn.desc": "Ilang auto-screenshot ang maaaring kunin ng agent para sa vision sa isang turn (0 = walang limit). Mas mababang halaga ay nagpapababa ng gastos; kapag naubos ang badyet, lalaktawan ang susunod na auto-screenshot sa turn na iyon.", + "st.imageBudget.maxPerTurn.unlimited": "Walang limit", + "st.imageBudget.maxDimension.label": "Max na sukat ng imahe", + "st.imageBudget.maxDimension.desc": "Pinakamahabang gilid (lapad o taas) sa pixels para sa anumang screenshot na ipinapadala sa vision. Mas mababang cap ay nagpapaliit ng imahe bago ipadala, binabawasan ang token at gastos. Mas mataas na cap ay nagpapanatili ng fidelity.", + "st.imageBudget.warning": "⚠️ Naaangkop ang mga setting na ito sa screenshot para sa vision (auto-screenshot, /screenshot, buong page, verify_form). Hindi apektado ang manu-manong naka-save na full-resolution na imahe. Iginagalang ang «Image detail» ng OpenAI-style endpoints; maaaring balewalain ng ibang provider.", "st.redaction.heading": "Pagbura sa mga screenshot", "st.redaction.toggle.label": "Burahin ang sensitibong nilalaman sa mga screenshot", diff --git a/src/firefox/src/ui/locales/tr.js b/src/firefox/src/ui/locales/tr.js index 3fae84086..952b9b0a7 100644 --- a/src/firefox/src/ui/locales/tr.js +++ b/src/firefox/src/ui/locales/tr.js @@ -697,19 +697,19 @@ export default { "st.memory.security_html": "Gizlilik: kullanıcı belleği bu tarayıcı profilinde düz metin olarak saklanır. Etkinleştirildiğinde aktif bellek kayıtları, sistem isteminin bir parçası olarak yapılandırdığınız LLM sağlayıcısına gönderilir. Burada parola, API anahtarı, token, kurtarma kodu veya hassas gizli bilgi saklamayın.", "hist.filter.clear": "Filtreyi temizle ve tüm konuşmaları göster", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Görüntü bütçesi", + "st.imageBudget.desc": "Ekran görüntüsü boyutunu ve ajanın tur başına görüş için kaç kez yakalayacağını kontrol eder. Daha düşük ayrıntı ve boyut küçük uçlarda maliyet ve gecikmeyi azaltır; daha yüksek değer sadakati korur. Varsayılanlar önceki davranışla uyumludur.", + "st.imageBudget.detail.label": "Görüntü ayrıntısı", + "st.imageBudget.detail.desc": "Modele gönderilen görüş görüntüsü ayrıntısı. «high» daha fazla ayrıntı tutar (daha fazla token ve maliyet); «low» daha küçük ve ucuz bir görüntü gönderir; «auto» sağlayıcının karar vermesine bırakır. Sağlayıcıya bağlıdır.", + "st.imageBudget.detail.high": "Yüksek (daha fazla ayrıntı, daha fazla maliyet)", + "st.imageBudget.detail.low": "Düşük (daha ucuz, daha az ayrıntı)", + "st.imageBudget.detail.auto": "Otomatik (sağlayıcı varsayılanı)", + "st.imageBudget.maxPerTurn.label": "Tur başına en fazla ekran görüntüsü", + "st.imageBudget.maxPerTurn.desc": "Ajanın bir turda görüş için alabileceği otomatik ekran görüntüsü sayısı (0 = sınırsız). Daha düşük değerler maliyeti azaltır; bütçe dolunca o tur için başka otomatik görüntü alınmaz.", + "st.imageBudget.maxPerTurn.unlimited": "Sınırsız", + "st.imageBudget.maxDimension.label": "En büyük görüntü boyutu", + "st.imageBudget.maxDimension.desc": "Görüşe gönderilen herhangi bir ekran görüntüsünün en uzun kenarı (genişlik veya yükseklik) piksel cinsinden. Daha küçük üst sınır görüntüleri göndermeden önce küçültür, token ve maliyeti düşürür. Daha büyük üst sınır sadakati korur.", + "st.imageBudget.warning": "⚠️ Bu ayarlar görüş için yakalanan ekran görüntülerine uygulanır (otomatik görüntü, /screenshot, tam sayfa, verify_form). Elle kaydedilen tam çözünürlüklü görüntüler etkilenmez. «Image detail» OpenAI tarzı uçlar tarafından uygulanır; diğer sağlayıcılar yok sayabilir.", "st.redaction.heading": "Ekran görüntüsü sansürleme", "st.redaction.toggle.label": "Ekran görüntülerindeki hassas içeriği sansürle", diff --git a/src/firefox/src/ui/locales/uk.js b/src/firefox/src/ui/locales/uk.js index 700a621d4..4eeed47fb 100644 --- a/src/firefox/src/ui/locales/uk.js +++ b/src/firefox/src/ui/locales/uk.js @@ -699,19 +699,19 @@ export default { "st.memory.security_html": "Конфіденційність: пам’ять користувача зберігається відкритим текстом у цьому профілі браузера. Коли її ввімкнено, активні записи пам’яті надсилаються вибраному провайдеру LLM як частина системного промпту. Не зберігайте тут паролі, ключі API, токени, коди відновлення чи інші конфіденційні секрети.", "hist.filter.clear": "Очистити фільтр і показати всі розмови", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "Бюджет зображень", + "st.imageBudget.desc": "Керує розміром знімків і тим, скільки разів агент знімає екран за хід для vision. Менша деталізація й розмір — нижча вартість і затримка на слабких endpoint’ах; більші значення зберігають точність. Типові значення збігаються з попередньою поведінкою.", + "st.imageBudget.detail.label": "Деталізація зображення", + "st.imageBudget.detail.desc": "Деталізація vision-зображення, що надсилається моделі. «high» зберігає більше деталей (більше токенів і вартість); «low» — менше й дешевше зображення; «auto» — рішення провайдера. Залежить від провайдера.", + "st.imageBudget.detail.high": "Висока (більше деталей, дорожче)", + "st.imageBudget.detail.low": "Низька (дешевше, менше деталей)", + "st.imageBudget.detail.auto": "Авто (типово для провайдера)", + "st.imageBudget.maxPerTurn.label": "Макс. знімків за хід", + "st.imageBudget.maxPerTurn.desc": "Скільки авто-знімків агент може зробити для vision за один хід (0 = без обмежень). Менші значення знижують вартість; після вичерпання бюджету подальші авто-знімки в цьому ході пропускаються.", + "st.imageBudget.maxPerTurn.unlimited": "Без обмежень", + "st.imageBudget.maxDimension.label": "Макс. розмір зображення", + "st.imageBudget.maxDimension.desc": "Найбільша сторона (ширина або висота) у пікселях для будь-якого знімка, надісланого у vision. Менша межа стискає зображення до надсилання, зменшуючи токени й вартість. Більша межа зберігає точність.", + "st.imageBudget.warning": "⚠️ Ці налаштування застосовуються до знімків для vision (авто-знімок, /screenshot, вся сторінка, verify_form). Вручну збережені зображення в повній роздільності не зачіпаються. «Image detail» враховують endpoint’и в стилі OpenAI; інші провайдери можуть ігнорувати.", "st.redaction.heading": "Редагування знімків екрана", "st.redaction.toggle.label": "Приховувати чутливий вміст на знімках екрана", diff --git a/src/firefox/src/ui/locales/zh.js b/src/firefox/src/ui/locales/zh.js index 421a4de07..3dfe22f1e 100644 --- a/src/firefox/src/ui/locales/zh.js +++ b/src/firefox/src/ui/locales/zh.js @@ -700,19 +700,19 @@ export default { "st.memory.security_html": "隐私:用户记忆以明文形式存储在此浏览器配置文件中。启用后,活动记忆记录会作为系统提示词的一部分发送给您配置的 LLM 提供商。请勿在此存储密码、API 密钥、令牌、恢复代码或敏感机密信息。", "hist.filter.clear": "清除筛选并显示所有对话", // Image budget (issue #311): screenshot quality + capture limits. - "st.imageBudget.heading": "Image budget", - "st.imageBudget.desc": "Control screenshot size and how many the agent captures for vision per turn. Lower detail and dimension cuts cost and latency for smaller endpoints; higher keeps fidelity. Defaults match the previous behavior.", - "st.imageBudget.detail.label": "Image detail", - "st.imageBudget.detail.desc": "Vision image detail sent to the model. \"high\" keeps more detail (more tokens, higher cost); \"low\" sends a smaller, cheaper image; \"auto\" lets the provider decide. Provider-dependent.", - "st.imageBudget.detail.high": "High (more detail, more cost)", - "st.imageBudget.detail.low": "Low (cheaper, less detail)", - "st.imageBudget.detail.auto": "Auto (provider default)", - "st.imageBudget.maxPerTurn.label": "Max screenshots per turn", - "st.imageBudget.maxPerTurn.desc": "How many auto-screenshots the agent may capture for vision within a single turn (0 = unlimited). Lower values reduce cost; once the budget is spent further auto-screenshots are skipped for that turn.", - "st.imageBudget.maxPerTurn.unlimited": "Unlimited", - "st.imageBudget.maxDimension.label": "Max image dimension", - "st.imageBudget.maxDimension.desc": "Largest side (width or height) in pixels for any screenshot sent to vision. Smaller caps shrink images before they are sent, cutting tokens and cost. Larger caps keep fidelity.", - "st.imageBudget.warning": "⚠️ These settings apply to screenshots captured for vision (auto-screenshot, /screenshot, full-page, verify_form). Manually saved full-resolution images are unaffected. \"Image detail\" is honored by OpenAI-style endpoints; other providers may ignore it.", + "st.imageBudget.heading": "图像预算", + "st.imageBudget.desc": "控制截图大小以及代理每轮为视觉模型捕获的次数。更低的细节与尺寸可降低小端点的成本与延迟;更高则保留保真度。默认值与先前行为一致。", + "st.imageBudget.detail.label": "图像细节", + "st.imageBudget.detail.desc": "发送给模型的视觉图像细节。「high」保留更多细节(更多 token 与成本);「low」发送更小、更便宜的图像;「auto」由提供商决定。取决于提供商。", + "st.imageBudget.detail.high": "高(更多细节,更高成本)", + "st.imageBudget.detail.low": "低(更便宜,更少细节)", + "st.imageBudget.detail.auto": "自动(提供商默认)", + "st.imageBudget.maxPerTurn.label": "每轮最大截图数", + "st.imageBudget.maxPerTurn.desc": "代理在单轮中可为视觉捕获的自动截图数量(0 = 无限制)。较低值可降低成本;预算用尽后,该轮将不再进行自动截图。", + "st.imageBudget.maxPerTurn.unlimited": "无限制", + "st.imageBudget.maxDimension.label": "最大图像尺寸", + "st.imageBudget.maxDimension.desc": "发送给视觉的任何截图的最长边(宽或高),单位为像素。更小的上限会在发送前缩小图像,降低 token 与成本;更大的上限保留保真度。", + "st.imageBudget.warning": "⚠️ 这些设置适用于为视觉捕获的截图(自动截图、/screenshot、整页、verify_form)。手动保存的全分辨率图像不受影响。「Image detail」由 OpenAI 风格端点遵循;其他提供商可能忽略。", "st.redaction.heading": "截图打码", "st.redaction.toggle.label": "对截图中的敏感内容进行打码",