### Canned LLM Response for wiki-edo-lead-slot-dup Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md Example of a canned LLM response for the 'wiki-edo-lead-slot-dup' test case, preserving slot 11 duplication. This response is derived from console logs or manual reproduction, not a live LLM call. ```text ⟦0⟧江戶⟦/0⟧(⟦1⟧日語⟦/1⟧:⟦2⟧...⟦/2⟧...)是⟦11⟧現今日本首都⟦/11⟧⟦12⟧東京⟦/12⟧的⟦11⟧舊稱⟦/11⟧。⟦*13⟧ ``` -------------------------------- ### Get Shinkansen Settings Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Reads user-customized settings combined with defaults. API Key is fetched from local storage. ```javascript import { getSettings } from './lib/storage.js'; const settings = await getSettings(); ``` -------------------------------- ### Example HTML Structure for gmail-button-nested-a Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md Simplified and sanitized HTML structure for the 'gmail-button-nested-a' test case. Note the specific styling on the TD and A elements, and the lack of styling on the SPAN. ```html Learn more ``` -------------------------------- ### Preset Shortcuts (v1.4.12) Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Information about preset shortcuts for translation, including manifest commands, storage schema, and behavior. ```APIDOC ## Preset Shortcuts (v1.4.12) ### Description Provides functionality for setting and managing translation presets using keyboard shortcuts. ### Manifest Commands - `translate-preset-1` (Alt+A): Preset Flash - `translate-preset-2` (Alt+S): Preset Flash Lite - `translate-preset-3` (Alt+D): Preset Google MT ### Storage Schema `translatePresets: [{ slot, engine, model, label }]` Three default presets are built into `lib/storage.js` `DEFAULT_SETTINGS`. ### Behavior - **Idle State**: Pressing any preset key initiates translation using the `engine` + `model` of the corresponding slot. - **Translating**: Pressing any preset key aborts the current translation. - **Translation Complete**: Pressing any preset key restores the page (`restorePage`), regardless of the slot. ### Model Override `content.js` `SK.translateUnits` passes the slot's model to `TRANSLATE_BATCH` payload.modelOverride. `background.js` `handleTranslate` uses `geminiOverrides.model` to override `geminiConfig.model`, differentiating cache partitions with the `cacheTag` parameter. ### Future Options UI (v1.4.13) Planned UI for editing engine, model, and label. For v1.4.12, users can temporarily modify presets directly via `chrome.storage.sync.translatePresets`. ``` -------------------------------- ### Get State Function for Debug API Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Returns a snapshot of the current translation state. This is a read-only method provided by the debug API. ```javascript getState(): Object ``` -------------------------------- ### Set Shinkansen Settings Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Writes settings, with API Key automatically saved to local storage and other settings to sync storage. Allows partial updates. ```javascript import { setSettings } from './lib/storage.js'; // 更新部分設定 await setSettings({ apiKey: 'NEW_API_KEY', geminiConfig: { model: 'gemini-3.1-flash-lite-preview', temperature: 0.8 }, ytSubtitle: { autoTranslate: false } }); ``` -------------------------------- ### Importing ES Modules with fetch Mock for Google Translate Batch Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This test demonstrates importing ES modules directly using `await import()` and mocking `globalThis.fetch`. It's used to test the Google Translate batch functionality, including URL chunking and handling of multiple result batches. ```javascript mock `globalThis.fetch` 直接 import ES module;驗證 SEP 串接、URL 長度分塊、空陣列、多批次 result 依 idx 寫回 ``` -------------------------------- ### Get Cache Statistics Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Retrieve statistics about the current cache status using cache.stats. This includes the number of entries and total size in bytes for both translation cache and glossary cache. ```javascript import * as cache from './lib/cache.js'; const stats = await cache.stats(); // { // count: 1250, // 翻譯快取條目數 // bytes: 2500000, // 翻譯快取大小(bytes) // glossaryCount: 15, // 術語表快取條目數 // glossaryBytes: 50000 // 術語表快取大小(bytes) // } ``` -------------------------------- ### Popup/Options Script to Background Script Message: QUERY_USAGE Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Retrieves detailed usage records for display in a table on the options page. The response includes an array of usage records. ```javascript QUERY_USAGE { ok, records } ``` -------------------------------- ### Start YouTube Subtitle Translation Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Automatically intercepts YouTube subtitle data, translates it in batches based on time windows, and replaces the displayed subtitles in real-time. Also provides access to translation status via SK.YT. ```javascript const SK = window.__SK; // 啟動 YouTube 字幕翻譯 await SK.translateYouTubeSubtitles(); ``` ```javascript // 存取字幕翻譯狀態 const YT = SK.YT; console.log({ active: YT.active, rawSegments: YT.rawSegments, captionMap: YT.captionMap, translatedUpToMs: YT.translatedUpToMs }); ``` -------------------------------- ### Popup/Options Script to Background Script Message: QUERY_USAGE_CHART Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Requests data formatted for a usage statistics chart in the options page. The response provides the chart data. ```javascript QUERY_USAGE_CHART { ok, data } ``` -------------------------------- ### Popup/Options Script to Background Script Message: USAGE_STATS Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Requests cumulative usage statistics, including total input tokens, output tokens, cost in USD, and the time period since the last reset. Used for display in the popup. ```javascript USAGE_STATS { ok, totalInputTokens, totalOutputTokens, totalCostUSD, since } ``` -------------------------------- ### Popup/Options Script to Background Script Message: QUERY_USAGE_STATS Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Queries aggregated usage statistics for display in the options page. The response contains the statistics object. ```javascript QUERY_USAGE_STATS { ok, stats } ``` -------------------------------- ### Default System Prompt Structure for Gemini Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md The default system prompt is defined in lib/storage.js. It uses XML tags to define the translator's role, critical rules, linguistic guidelines, and formatting preferences. This prompt is dynamically augmented based on the content being translated. ```JavaScript const DEFAULT_SYSTEM_PROMPT = ` 定位為「精通英美流行文化與台灣在地文學的首席翻譯專家」,追求出版級台灣當代語感 禁止輸出思考過程、忠實保留不雅詞彙(不做道德審查)、專有名詞保留英文原文(地理位置例外,須翻為台灣標準譯名) 台灣道地語感(拒絕翻譯腔)、禁用中國大陸用語(附具體對照表)、台灣通行譯名、特殊詞彙首次出現加註原文 全形標點、破折號改寫、中英夾雜半形空格、數字格式(1–99 中文數字、100 以上阿拉伯數字)、年份格式 `; ``` -------------------------------- ### Add testInject Helper to Shinkansen Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md This helper function is to be added to the window.__shinkansen object in content.js. It serializes an element, injects a translation, and returns source text and slot count. Use this for testing the serialize -> inject path without network latency. ```javascript testInject(el, translation) { const { text, slots } = serializeWithPlaceholders(el); const unit = { kind: 'element', el }; injectTranslation(unit, translation, slots); return { sourceText: text, slotCount: slots.length }; } ``` -------------------------------- ### Popup/Options Script to Background Script Message: CLEAR_USAGE Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Instructs the background script to clear all recorded usage data. The background script confirms the operation. ```javascript CLEAR_USAGE { ok } ``` -------------------------------- ### Popup/Options Script to Background Script Message: RESET_USAGE Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Resets the cumulative usage statistics. The response includes the reset statistics. ```javascript RESET_USAGE { ok, totalInputTokens, totalOutputTokens, totalCostUSD, since } ``` -------------------------------- ### Rate Limiter Implementation Details Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md The rate limiter uses a three-dimensional sliding window for RPM, TPM, and RPD. It persists RPD data in chrome.storage.local and applies a safety margin to limits. Error handling for 429 responses includes respecting the Retry-After header and exponential backoff. ```JavaScript // RPM: 60-second sliding window using a circular buffer of timestamps // TPM: 60-second sliding window using token estimation (Math.ceil(text.length / 3.5)) // RPD: Resets at Pacific midnight, persisted in chrome.storage.local (key rateLimit_rpd_) // Safety Margin: Each limit multiplied by (1 - safetyMargin), default 10% // 429 Handling: Respect Retry-After header, otherwise exponential backoff (2^n * 500ms, max 8s). RPD exceeded means no retry. ``` -------------------------------- ### Settings Management API Source: https://context7.com/jimmysu0309/shinkansen/llms.txt APIs for reading and writing user settings, including API keys and translation configurations. ```APIDOC ## GET /settings ### Description Reads the complete settings by merging default and user-customized settings. The API Key is read from local storage and is not synced via Google accounts. ### Method GET ### Endpoint /settings ### Response #### Success Response (200) - **apiKey** (string) - The API key. - **geminiConfig** (object) - Configuration for Gemini models. - **model** (string) - The Gemini model to use. - **serviceTier** (string) - The service tier for the model. - **temperature** (number) - The temperature setting for the model. - **maxOutputTokens** (number) - Maximum output tokens. - **systemInstruction** (string) - System instructions for the model. - **pricing** (object) - Pricing information. - **inputPerMTok** (number) - Cost per million input tokens. - **outputPerMTok** (number) - Cost per million output tokens. - **tier** (string) - The service tier. - **ytSubtitle** (object) - YouTube subtitle settings. - **autoTranslate** (boolean) - Whether to auto-translate subtitles. - **engine** (string) - The translation engine for subtitles. - **windowSizeS** (number) - The time window size in seconds for subtitle processing. - **lookaheadS** (number) - The lookahead time in seconds for subtitle processing. - **translatePresets** (array) - Presets for translation. - **slot** (number) - The slot number for the preset. - **engine** (string) - The translation engine for the preset. - **model** (string) - The model used in the preset. - **label** (string) - A label for the preset. - **glossary** (object) - Glossary settings. - **enabled** (boolean) - Whether the glossary is enabled. - **skipThreshold** (number) - Threshold for skipping glossary entries. - **blockingThreshold** (number) - Threshold for blocking glossary entries. - **fixedGlossary** (object) - Fixed glossary settings. - **global** (array) - Global glossary entries. - **byDomain** (object) - Domain-specific glossary entries. ### Response Example ```json { "apiKey": "AIza...", "geminiConfig": { "model": "gemini-3-flash-preview", "serviceTier": "DEFAULT", "temperature": 1.0, "maxOutputTokens": 8192, "systemInstruction": "你是一位精通..." }, "pricing": { "inputPerMTok": 0.50, "outputPerMTok": 3.00 }, "tier": "tier1", "ytSubtitle": { "autoTranslate": true, "engine": "gemini", "windowSizeS": 30, "lookaheadS": 10 }, "translatePresets": [ { "slot": 1, "engine": "gemini", "model": "gemini-3.1-flash-lite-preview", "label": "Flash Lite" }, { "slot": 2, "engine": "gemini", "model": "gemini-3-flash-preview", "label": "Flash" }, { "slot": 3, "engine": "google", "model": null, "label": "Google MT" } ], "glossary": { "enabled": false, "skipThreshold": 1, "blockingThreshold": 5 }, "fixedGlossary": { "global": [], "byDomain": {} } } ``` ## POST /settings ### Description Writes settings. The API Key is automatically written to local storage, and other settings are written to sync storage. ### Method POST ### Endpoint /settings ### Request Body - **apiKey** (string) - Optional - The API key to set. - **geminiConfig** (object) - Optional - Configuration for Gemini models. - **model** (string) - Optional - The Gemini model to use. - **temperature** (number) - Optional - The temperature setting for the model. - **ytSubtitle** (object) - Optional - YouTube subtitle settings. - **autoTranslate** (boolean) - Optional - Whether to auto-translate subtitles. ### Request Example ```json { "apiKey": "NEW_API_KEY", "geminiConfig": { "model": "gemini-3.1-flash-lite-preview", "temperature": 0.8 }, "ytSubtitle": { "autoTranslate": false } } ``` ``` -------------------------------- ### Popup/Options Script to Background Script Message: EXPORT_USAGE_CSV Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Requests the export of usage statistics in CSV format from the options page. The background script returns the CSV data. ```javascript EXPORT_USAGE_CSV { ok, csv } ``` -------------------------------- ### Core Message API - TRANSLATE_BATCH_GOOGLE Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Translates text segments in batches using the free, unofficial Google Translate endpoint. This method does not require an API key, bypasses rate limits, and incurs no cost, making it suitable for understanding content where perfect translation is not critical. ```APIDOC ## POST /api/translate/batch/google ### Description Translates text segments in batches using the free, unofficial Google Translate endpoint. This method does not require an API key, bypasses rate limits, and incurs no cost, making it suitable for understanding content where perfect translation is not critical. ### Method POST ### Endpoint /api/translate/batch/google ### Parameters #### Request Body - **type** (string) - Required - Message type, should be 'TRANSLATE_BATCH_GOOGLE' - **payload** (object) - Required - Payload for the translation request - **texts** (array of strings) - Required - The text segments to translate ### Request Example ```json { "type": "TRANSLATE_BATCH_GOOGLE", "payload": { "texts": ["Breaking news today", "Weather forecast for tomorrow"] } } ``` ### Response #### Success Response (200) - **ok** (boolean) - Indicates if the operation was successful - **result** (array of strings) - The translated text segments - **usage** (object) - Statistics about the API usage - **engine** (string) - The translation engine used ('google') - **chars** (integer) - The number of characters translated - **cacheHits** (integer) - Number of local cache hits #### Response Example ```json { "ok": true, "result": ["今日重大新聞", "明天天氣預報"], "usage": { "engine": "google", "chars": 42, "cacheHits": 0 } } ``` ``` -------------------------------- ### Popup Panel Specification Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Details the layout and functionality of the main popup panel. ```APIDOC ## 13. Popup Panel Specification ### 13.1 Layout - Header: emoji 🚄 + Name "Shinkansen" + Version (dynamic) - Main Button: "Translate Page" / "Show Original" (toggles based on `GET_STATE`) - Edit Translation Button: (hidden by default, shown after translation; toggles `TOGGLE_EDIT_MODE`) - Whitelist Auto-Translate Toggle - Glossary Consistency Toggle - YouTube Subtitle Translation Toggle (only on YouTube video pages) - Cache Statistics (count / size) + Clear Cache Button - Cumulative Cost / Token Display (read via `USAGE_STATS` message; reset function in options page) - Status Bar: ("Status: Ready" / "Status: Translating..." / error messages, etc.) - Footer: Settings Button (opens options page) + Shortcut Hint (dynamic, reads `chrome.commands`) ### 13.2 Version Display **Must** be dynamically read via `chrome.runtime.getManifest().version`, not hardcoded. ``` -------------------------------- ### Implement Pure Google Docs URL Parsing Test Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This test case focuses on the URL parsing logic for pure Google Docs links. It notes that cross-tab redirection flows are not covered and will require future end-to-end testing. ```javascript test/regression/pure-gdoc-url.spec.js ``` -------------------------------- ### Implement Detect Navigation Anchor Threshold Test Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This test case is designed to verify the detection of navigation anchors based on a specific threshold. It ensures that navigation elements are correctly identified under defined conditions. ```javascript test/regression/detect-nav-anchor-threshold.spec.js ``` -------------------------------- ### Access Debugging Interface via window.__shinkansen Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Utilize the global `window.__shinkansen` object in the browser console for debugging purposes. It provides methods to inspect version, state, collect data, and test specific functionalities. ```javascript // 在瀏覽器 console 中使用 const api = window.__shinkansen; ``` ```javascript // 查看版本 api.version; // '1.4.22' ``` ```javascript // 查看翻譯狀態 api.getState(); // { translated: true, translating: false, stickyTranslate: true, // replacedCount: 45, cacheSize: 100, guardCacheSize: 45 } ``` ```javascript // 收集段落(除錯用) api.collectParagraphs(); ``` ```javascript // 帶統計資訊 api.collectParagraphsWithStats(); // { units: [...], skipStats: { notBlockTag: 5, ... } } ``` ```javascript // 測試序列化 const el = document.querySelector('p'); api.serialize(el); // { text: '...', slots: [...] } ``` ```javascript // 測試注入 api.testInject(el, '測試翻譯'); ``` ```javascript // 測試 Google Docs URL 判斷 api.testGoogleDocsUrl('https://docs.google.com/document/d/xxx/edit'); // { isEditor: true, isMobileBasic: false, mobileBasicUrl: '...mobilebasic' } ``` -------------------------------- ### JavaScript for Dynamic Version Display Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Demonstrates how to dynamically read the extension's version number using the chrome.runtime.getManifest().version API. This ensures the version displayed is always up-to-date. ```javascript chrome.runtime.getManifest().version ``` -------------------------------- ### Default Settings Structure for Shinkansen Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md This JSON object defines the default configuration settings for the Shinkansen extension, including API parameters, glossary settings, domain rules, and UI preferences. These settings are managed via chrome.storage.sync. ```json { "geminiConfig": { "model": "gemini-3-flash-preview", "serviceTier": "DEFAULT", "temperature": 1.0, "topP": 0.95, "topK": 40, "maxOutputTokens": 8192, "systemInstruction": "(見 §3.3 DEFAULT_SYSTEM_PROMPT)" }, "pricing": { "inputPerMTok": 0.50, "outputPerMTok": 3.00 }, "glossary": { "enabled": false, "prompt": "(見 DEFAULT_GLOSSARY_PROMPT)", "temperature": 0.1, "skipThreshold": 1, "blockingThreshold": 5, "timeoutMs": 60000, "maxTerms": 200 }, "domainRules": { "whitelist": [] }, "autoTranslate": false, "debugLog": false, "tier": "tier1", "safetyMargin": 0.1, "maxRetries": 3, "rpmOverride": null, "tpmOverride": null, "rpdOverride": null, "maxConcurrentBatches": 10, "maxUnitsPerBatch": 12, "maxCharsPerBatch": 3500, "maxTranslateUnits": 1000, "toastOpacity": 0.7, "toastAutoHide": true, "skipTraditionalChinesePage": true, "ytSubtitle": { "autoTranslate": true, "temperature": 0.1, "systemPrompt": "(見 DEFAULT_SUBTITLE_SYSTEM_PROMPT)", "windowSizeS": 30, "lookaheadS": 10, "debugToast": false, "onTheFly": false, "model": "", "pricing": null } } ``` -------------------------------- ### Expose testInject API in content.js Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md Adds a `testInject` function to the `window.__shinkansen` object for testing purposes. This function performs a full 'serialize + mock LLM response + inject' flow on a specified element without network calls. It requires the element to be a valid DOM Element. ```javascript // 測試專用:對指定 element 跑一次完整的「serialize + 假 LLM 回應 + inject」 // 流程,回傳統計資訊。測試斷言對象是注入後的 DOM(element 本身)。 // 不觸發任何網路呼叫。 testInject(el, translation) { if (!el || el.nodeType !== Node.ELEMENT_NODE) { throw new Error('testInject: el must be an Element'); } const { text, slots } = serializeWithPlaceholders(el); const unit = { kind: 'element', el }; injectTranslation(unit, translation, slots); return { sourceText: text, slotCount: slots.length }; } ``` -------------------------------- ### Background/Popup Script to Content Script Message: TRANSLATE_PRESET Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Triggers translation using a specific preset slot (1, 2, or 3) in the content script. Handles restoring the page or aborting translation based on the current state. ```javascript TRANSLATE_PRESET v1.4.12:依 payload.slot(1/2/3)觸發對應 preset 翻譯;已翻譯時任一 slot 皆 restorePage;翻譯中任一 slot 皆 abort ``` -------------------------------- ### Expose selectBestSlotOccurrences API in content.js Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/REGRESSION_PLAN.md Exposes the `selectBestSlotOccurrences` function for pure function testing within Category C. This allows testing the slot selection logic in isolation. ```javascript // 測試專用:暴露 selectBestSlotOccurrences 給 Category C 純函式測試。 selectBestSlotOccurrences(text) { return selectBestSlotOccurrences(text); } ``` -------------------------------- ### Content Script to Background Script Message: LOG_USAGE Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Logs usage statistics, such as input and output tokens, from the content script to the background script. The background script confirms receipt with an 'ok' status. ```javascript LOG_USAGE { inputTokens, outputTokens, … } { ok } ``` -------------------------------- ### Content Script to Background Script Message: STICKY_QUERY Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Queries the background script about the sticky translation status of the current tab. The response indicates whether translation should occur and the associated slot. ```javascript STICKY_QUERY — { ok, shouldTranslate, slot } ``` -------------------------------- ### Content Script to Background Script Message: STICKY_SET Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Sets the current tab as sticky with a specific slot number after a successful translation. The background script confirms the operation. ```javascript STICKY_SET { slot: number } { ok } ``` -------------------------------- ### Test Preset Hotkey Behavior Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This regression test suite covers the behavior of preset hotkeys in the application, ensuring correct functionality across different states (idle, translated, translating) and slots. It uses direct function calls and stubbed methods for testing. ```javascript test/regression/preset-hotkey-behavior.spec.js ``` -------------------------------- ### Background/Popup Script to Content Script Message: GET_STATE Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Requests the current translation state from the content script. Used to determine the appropriate action for UI elements like buttons. ```javascript GET_STATE 查詢翻譯狀態 ``` -------------------------------- ### Core Message API - TRANSLATE_SUBTITLE_BATCH Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Dedicated endpoint for translating YouTube subtitles. It utilizes a separate system prompt optimized for conversational language and specific temperature settings, supporting independent model and pricing configurations. ```APIDOC ## POST /api/translate/subtitle/batch ### Description Dedicated endpoint for translating YouTube subtitles. It utilizes a separate system prompt optimized for conversational language and specific temperature settings, supporting independent model and pricing configurations. ### Method POST ### Endpoint /api/translate/subtitle/batch ### Parameters #### Request Body - **type** (string) - Required - Message type, should be 'TRANSLATE_SUBTITLE_BATCH' - **payload** (object) - Required - Payload for the translation request - **texts** (array of strings) - Required - The subtitle text segments to translate ### Request Example ```json { "type": "TRANSLATE_SUBTITLE_BATCH", "payload": { "texts": [ "Welcome back to the channel", "Today we are going to talk about AI" ] } } ``` ### Response #### Success Response (200) - **ok** (boolean) - Indicates if the operation was successful - **result** (array of strings) - The translated subtitle text segments - **usage** (object) - Statistics about the API usage (structure similar to TRANSLATE_BATCH) - **rpdExceeded** (boolean) - Flag indicating if the daily quota was exceeded - **hadMismatch** (boolean) - Flag indicating if there was a mismatch in segment alignment #### Response Example ```json { "ok": true, "result": ["歡迎回到頻道", "今天我們要談論人工智能"], "usage": { "inputTokens": 150, "outputTokens": 80, "cachedTokens": 50, "costUSD": 0.0012, "billedInputTokens": 112, "billedCostUSD": 0.0009, "cacheHits": 0 }, "rpdExceeded": false, "hadMismatch": false } ``` ``` -------------------------------- ### Content Script to Background Script Message: EXTRACT_GLOSSARY Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Requests the extraction of glossary terms from a given input. The background script processes the input and returns the identified terms and diagnostic information. ```javascript EXTRACT_GLOSSARY { input } { ok, terms, _diag } ``` -------------------------------- ### Testing Parallel Batch Translation for YouTube Subtitles Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This test focuses on the parallel processing of subtitle translation batches for YouTube. It mocks `chrome.runtime.sendMessage` to introduce a fixed delay and records timestamps to assert that subsequent batches are processed in parallel within a short time frame. ```javascript mock `chrome.runtime.sendMessage` 固定 100ms 延遲 + 記錄呼叫時間戳;17 條 rawSegments 切成 [1,8,8],呼叫 `translateYouTubeSubtitles`,斷言 batch 2 呼叫時間 - batch 1 呼叫時間 < 50ms ``` -------------------------------- ### Implement Whitelist Auto Translate Jest Unit Test Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This Jest unit test suite covers the integration of domain whitelisting and automatic translation features. It tests various scenarios including exact matches, wildcards, root domain hits, and cases where auto-translate is disabled or the whitelist is empty. ```javascript test/jest-unit/whitelist-auto-translate.test.cjs ``` -------------------------------- ### Log and Query Usage Data Source: https://context7.com/jimmysu0309/shinkansen/llms.txt Record translation token counts and costs, with support for IndexedDB persistence and statistical queries. Use LOG_USAGE to record, and QUERY_USAGE to retrieve records or stats. ```javascript // 記錄翻譯用量(由 translatePage 內部呼叫) browser.runtime.sendMessage({ type: 'LOG_USAGE', payload: { url: location.href, title: document.title, inputTokens: 500, outputTokens: 250, cachedTokens: 100, billedInputTokens: 425, billedCostUSD: 0.0015, segments: 20, cacheHits: 5, durationMs: 3500, timestamp: Date.now() } }); ``` ```javascript // 查詢用量紀錄 const { records } = await browser.runtime.sendMessage({ type: 'QUERY_USAGE', payload: { startDate: '2025-01-01', endDate: '2025-01-31', limit: 100 } }); ``` ```javascript // 查詢統計摘要 const { stats } = await browser.runtime.sendMessage({ type: 'QUERY_USAGE_STATS', payload: { startDate: '2025-01-01' } }); // { totalTokens: 125000, totalCost: 0.45, recordCount: 50 } ``` ```javascript // 匯出 CSV const { csv } = await browser.runtime.sendMessage({ type: 'EXPORT_USAGE_CSV', payload: {} }); ``` -------------------------------- ### Shinkansen Batch Translation Protocol Source: https://github.com/jimmysu0309/shinkansen/blob/main/SPEC.md Describes how Shinkansen handles batching and segmenting text for translation requests. ```APIDOC ## Batch Translation Protocol ### Description Shinkansen sends multiple text segments concatenated with a specific separator for batch translation. The response is split using the same separator to align segments. ### Method POST (via Google Gemini API) ### Endpoint `https://generativelanguage.googleapis.com/v1beta/models/{model}:generateContent` ### Parameters #### Request Body (Batching) - **Text Segmentation**: Segments are joined by `\n<<>>\n`. - **Batching Strategy**: Uses a greedy approach with two thresholds: `maxCharsPerBatch` (default 3500) and `maxUnitsPerBatch` (default 12). Either threshold triggers batch finalization. - **Large Segments**: Segments exceeding batch limits are processed individually. ### Response Handling #### Alignment Failure Fallback If the number of returned segments does not match the number of sent segments, the system reverts to processing each segment individually. ### Implementation Details - **Primary Packing Layer**: `packBatches()` in `content.js`. - **Secondary Insurance Layer**: `packChunks()` in `lib/gemini.js`. ``` -------------------------------- ### Mocking TRANSLATE_BATCH for YouTube Subtitle Translation Test Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This snippet illustrates how to mock the `TRANSLATE_BATCH` message in a testing environment. It specifies the expected return value for a subtitle translation request, ensuring that the translated text is correctly returned. ```javascript mock `TRANSLATE_BATCH` 回傳 `['你好,世界!']` ``` -------------------------------- ### Mock YouTube Player Response for Subtitle Translation Source: https://github.com/jimmysu0309/shinkansen/blob/main/test/PENDING_REGRESSION.md This HTML snippet demonstrates the structure for mocking the `ytInitialPlayerResponse` and the caption display element for testing YouTube subtitle translation. It's used to simulate the YouTube player's state and the initial display of captions. ```html
Hello, world!
```