ai-helper-agent 2.0.0 → 2.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (38) hide show
  1. package/README.md +28 -5
  2. package/README.zh-CN.md +28 -5
  3. package/bin/agent.js +150 -0
  4. package/dist/assets/{agent-store-BFaBECYz.js → agent-store-DOyMdB_7.js} +2 -2
  5. package/dist/assets/{agent-store-BFaBECYz.js.map → agent-store-DOyMdB_7.js.map} +1 -1
  6. package/dist/assets/background.js +86 -87
  7. package/dist/assets/background.js.map +1 -1
  8. package/dist/assets/content.js +84 -80
  9. package/dist/assets/{i18n-CohqPkkN.js → i18n-MmYITlVj.js} +9 -7
  10. package/dist/assets/i18n-MmYITlVj.js.map +1 -0
  11. package/dist/assets/model-profiles-CV_sUuPf.js +25 -0
  12. package/dist/assets/model-profiles-CV_sUuPf.js.map +1 -0
  13. package/dist/assets/options-Df_1Dtn8.css +1 -0
  14. package/dist/assets/options.js +78 -63
  15. package/dist/assets/options.js.map +1 -1
  16. package/dist/assets/page-snapshot-renderer-CE53ibi-.js +4 -0
  17. package/dist/assets/page-snapshot-renderer-CE53ibi-.js.map +1 -0
  18. package/dist/assets/session-store-B0ZPGm7d.js +77 -0
  19. package/dist/assets/session-store-B0ZPGm7d.js.map +1 -0
  20. package/dist/assets/side_panel.css +1 -1
  21. package/dist/assets/side_panel.js +478 -439
  22. package/dist/assets/side_panel.js.map +1 -1
  23. package/dist/icons/badges/version.svg +4 -4
  24. package/dist/manifest.json +6 -3
  25. package/dist/offscreen/offscreen.js +10 -8
  26. package/dist/options.html +3 -12
  27. package/dist/side_panel.html +120 -32
  28. package/package.json +1 -1
  29. package/src/install-mode.js +128 -0
  30. package/src/locales/cli.json +24 -0
  31. package/src/rag/install.js +4 -0
  32. package/src/server.js +3 -1
  33. package/dist/assets/i18n-CohqPkkN.js.map +0 -1
  34. package/dist/assets/model-profiles-BS2LIjxf.js +0 -2
  35. package/dist/assets/model-profiles-BS2LIjxf.js.map +0 -1
  36. package/dist/assets/options-CE9-fjJV.css +0 -1
  37. package/dist/assets/session-store-DwXNnVF5.js +0 -100
  38. package/dist/assets/session-store-DwXNnVF5.js.map +0 -1
@@ -1 +0,0 @@
1
- {"version":3,"file":"model-profiles-BS2LIjxf.js","names":["DEFAULT_API_BASE"],"sources":["../../src/background/tools/browser-tools.js","../../src/background/tools/tab-tools.js","../../src/background/tools/storage-tools.js","../../src/background/tools/media-tools.js","../../src/background/tools/ai-tools.js","../../src/background/tools/agent-tools.js","../../src/background/tools/memory-tools.js","../../src/background/tools/debugger-tools.js","../../src/background/constants.js","../../src/shared/model-profiles.js"],"sourcesContent":["// browser-tools - page interaction + form operation + content extraction tool definitions\n\nexport const BROWSER_TOOLS = [\n {\n id: 'interact_element',\n category: 'page_interaction',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'interact_element',\n description: 'Click or hover on a page element. Locate via ref (recommended, from query_elements), text, or CSS selector',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['click', 'hover'] },\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n ref: { type: 'integer', description: 'Index returned by query_elements (recommended); valid only on current page, re-query after navigation' },\n text: { type: 'string', description: 'Match element by text (e.g. \"Login\"), click on first match' },\n tag: { type: 'string', description: 'Restrict tag with text, e.g. button/a' },\n selector: { type: 'string', description: 'CSS selector (used when neither ref nor text provided); avoid long nth-child chains, prefer selector returned by query_elements' },\n waitTime: { type: 'integer' },\n timeout: { type: 'integer' }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'scroll_to',\n category: 'page_interaction',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'scroll_to',\n description: 'Scroll page to a target. Use scroll_collect for infinite scroll collection',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n target: { type: 'string', enum: ['selector', 'top', 'bottom', 'coordinates', 'text'], description: 'Scroll target type; selector→requires selector, coordinates→requires x/y, text→requires text' },\n selector: { type: 'string' },\n text: { type: 'string', description: 'When target=text, scroll to element containing this text' },\n x: { type: 'integer' },\n y: { type: 'integer' },\n align: { type: 'string', enum: ['start', 'center', 'end', 'nearest'] },\n behavior: { type: 'string', enum: ['smooth', 'auto'] },\n maxScrolls: { type: 'integer', description: 'When target=text, max scroll attempts (default 20)' },\n pauseMs: { type: 'integer', description: 'When target=text, wait ms after each scroll (default 500)' }\n },\n required: []\n }\n }\n },\n {\n id: 'wait_element',\n category: 'page_interaction',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'wait_element',\n description: 'Wait for an element to appear/disappear/become visible/hidden. For page navigation, use wait_navigation',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n selector: { type: 'string' },\n state: { type: 'string', enum: ['appeared', 'disappeared', 'visible', 'hidden'] },\n timeout: { type: 'integer' }\n },\n required: ['selector']\n }\n }\n },\n {\n id: 'drag_drop',\n category: 'page_interaction',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'drag_drop',\n description: 'Drag element (⚠️ experimental, may not work on most pages; use click instead if needed)',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n sourceSelector: { type: 'string' },\n targetSelector: { type: 'string' }\n },\n required: ['sourceSelector', 'targetSelector']\n }\n }\n },\n {\n id: 'wait_navigation',\n category: 'page_interaction',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'wait_navigation',\n description: 'Wait for navigation',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n timeout: { type: 'integer' },\n waitUntil: { type: 'string', enum: ['load', 'domcontentloaded', 'networkidle'] }\n },\n required: []\n }\n }\n },\n {\n id: 'handle_dialog',\n category: 'page_interaction',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'handle_dialog',\n description: 'Handle page dialogs (alert/confirm/prompt). Use BEFORE an action that triggers a dialog. accept=auto-confirm, dismiss=auto-cancel, restore=revert to native behavior',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n action: { type: 'string', enum: ['accept', 'dismiss', 'restore'], description: 'accept: auto-OK/Allow; dismiss: auto-Cancel/Block; restore: revert to native dialogs' }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'fill_form',\n category: 'form_operation',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'fill_form',\n description: 'Fill multiple form fields at once. For single-field input on React/Vue apps (controlled components), prefer keyboard_input',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n fields: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n selector: { type: 'string' },\n value: { type: 'string' },\n fieldType: { type: 'string', enum: ['text', 'select', 'checkbox', 'radio', 'contenteditable'] }\n },\n required: ['selector', 'value']\n }\n },\n waitTime: { type: 'integer' }\n },\n required: ['fields']\n }\n }\n },\n {\n id: 'keyboard_input',\n category: 'form_operation',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'keyboard_input',\n description: 'Type text or dispatch a key event into the focused element. Bypasses React/Vue controlled components. text=type into field, key=single key like Enter/Escape',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n key: { type: 'string' },\n text: { type: 'string' },\n ctrlKey: { type: 'boolean' },\n shiftKey: { type: 'boolean' },\n altKey: { type: 'boolean' }\n },\n required: []\n }\n }\n },\n {\n id: 'file_upload',\n category: 'form_operation',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'file_upload',\n description: 'Upload file',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n selector: { type: 'string' },\n fileName: { type: 'string' },\n fileContent: { type: 'string', description: 'File content (base64)' },\n fileType: { type: 'string', description: 'MIME type, e.g. image/png' }\n },\n required: ['selector', 'fileName', 'fileContent']\n }\n }\n },\n {\n id: 'select_dropdown',\n category: 'form_operation',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'select_dropdown',\n description: 'Dropdown selection (also supports custom components; trigger can use ref instead of triggerSelector)',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n ref: { type: 'integer', description: 'Index returned by query_elements (takes precedence over triggerSelector)' },\n triggerSelector: { type: 'string' },\n optionText: { type: 'string' },\n optionSelector: { type: 'string' },\n timeout: { type: 'integer' }\n },\n required: ['optionText']\n }\n }\n },\n {\n id: 'page_content',\n category: 'content_extraction',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'page_content',\n description: 'Get page text or HTML content. For structured data (tables/links/images), use extract_data. For interactive elements, use query_elements',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n format: { type: 'string', enum: ['text', 'html'] },\n selector: { type: 'string' },\n maxLength: { type: 'integer' }\n },\n required: []\n }\n }\n },\n {\n id: 'extract_data',\n category: 'content_extraction',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'extract_data',\n description: 'Extract structured data from page',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n dataType: { type: 'string', enum: ['table', 'metadata', 'links', 'forms', 'images'], description: 'table→HTML tables, metadata→meta/SEO tags, links→hyperlinks, forms→form elements, images→image elements' },\n selector: { type: 'string' },\n filterType: { type: 'string', enum: ['all', 'internal', 'external'], description: 'links only: filter by link target' },\n includeHeaders: { type: 'boolean', description: 'table only: include header row' },\n format: { type: 'string', enum: ['json', 'markdown'], description: 'table only: output format' },\n includeImages: { type: 'boolean', description: 'links only: include images as links' },\n minWidth: { type: 'integer', description: 'images only: min width filter' },\n minHeight: { type: 'integer', description: 'images only: min height filter' },\n maxResults: { type: 'integer' }\n },\n required: ['dataType']\n }\n }\n },\n {\n id: 'query_elements',\n category: 'content_extraction',\n execution: 'content_script',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'query_elements',\n description: 'Query interactive elements (buttons, inputs, links, etc). Returns ref numbers for use in interact_element/fill_form. Recommended as the primary element locating method',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n filterByText: { type: 'string' },\n elementTypes: {\n type: 'array',\n items: { type: 'string', enum: ['button', 'input', 'select', 'textarea', 'a', 'checkbox', 'radio', 'menuitem'] }\n },\n maxResults: { type: 'integer' },\n countOnly: { type: 'boolean' }\n },\n required: []\n }\n }\n },\n {\n id: 'search_in_page',\n category: 'content_extraction',\n execution: 'content_script',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'search_in_page',\n description: 'Find text in current page content',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n query: { type: 'string' },\n mode: { type: 'string', enum: ['plain', 'regex'] },\n caseSensitive: { type: 'boolean' },\n contextLength: { type: 'integer' },\n maxResults: { type: 'integer' },\n highlight: { type: 'boolean' }\n },\n required: ['query']\n }\n }\n },\n {\n id: 'iframe_content',\n category: 'content_extraction',\n execution: 'content_script',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'iframe_content',\n description: 'Get content of an iframe embedded in the page',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n selector: { type: 'string' },\n includeNested: { type: 'boolean' },\n maxLength: { type: 'integer' }\n },\n required: []\n }\n }\n },\n {\n id: 'scroll_collect',\n category: 'content_extraction',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'scroll_collect',\n description: 'Scroll page and collect content incrementally. Use for infinite scroll or lazy-loaded pages',\n parameters: {\n type: 'object',\n properties: {\n tabId: { type: 'integer', description: 'Omit to use active tab' },\n scrollPixels: { type: 'integer' },\n maxScrolls: { type: 'integer' },\n pauseMs: { type: 'integer' },\n selector: { type: 'string' }\n },\n required: []\n }\n }\n },\n];\n","// tab-tools - tab management + bookmark history tool definitions\n\nexport const TAB_TOOLS = [\n {\n id: 'manage_tab',\n category: 'tab_management',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n confirmationActions: ['close'],\n type: 'function',\n function: {\n name: 'manage_tab',\n description: 'Manage browser tabs. open=navigate to URL (requires url), switch=change active tab (requires tabId), close=close tab, reload=refresh page, navigate=history back/forward (requires direction)',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['open', 'switch', 'close', 'reload', 'navigate'], description: 'open: new URL; switch: change tab; close: close tab; reload: refresh; navigate: history back/forward' },\n url: { type: 'string', description: 'Required when action=open' },\n tabId: { type: 'integer', description: 'Required for switch/close/reload; omit for open' },\n active: { type: 'boolean' },\n waitForLoad: { type: 'boolean' },\n loadTimeout: { type: 'integer' },\n bypassCache: { type: 'boolean' },\n direction: { type: 'string', enum: ['back', 'forward'], description: 'Required when action=navigate' }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'list_tabs',\n category: 'tab_management',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'list_tabs',\n description: 'Get list of open tabs. Use mode=active to get current tab tabId when unsure which tab to operate on',\n parameters: {\n type: 'object',\n properties: {\n mode: { type: 'string', enum: ['all', 'active'] },\n includeUrl: { type: 'boolean' },\n includeTitle: { type: 'boolean' }\n }\n }\n }\n },\n {\n id: 'search_browser_data',\n category: 'bookmark_history',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'search_browser_data',\n description: 'Search browser bookmarks or history',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['bookmark', 'history'], description: 'bookmark: search bookmarks; history: search browsing history' },\n query: { type: 'string' },\n maxResults: { type: 'integer' },\n startTime: { type: 'integer', description: 'history only: start timestamp (ms)' },\n endTime: { type: 'integer', description: 'history only: end timestamp (ms)' }\n },\n required: ['action', 'query']\n }\n }\n },\n];\n","// storage-tools - storage management + network request tool definitions\n\nexport const STORAGE_TOOLS = [\n{\n id: 'manage_storage',\n category: 'storage_management',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'manage_storage',\n description: 'Read/write browser localStorage or sessionStorage',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['get', 'set', 'remove', 'clear'], description: 'get: read key; set: write key+value (requires value); remove: delete key; clear: wipe all' },\n storage: { type: 'string', enum: ['local', 'session'] },\n key: { type: 'string', description: 'Required for get/set/remove' },\n value: { type: 'string', description: 'Required for set' }\n },\n required: ['action', 'storage']\n }\n }\n },\n{\n id: 'manage_cookies',\n category: 'storage_management',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: true,\n type: 'function',\n function: {\n name: 'manage_cookies',\n description: 'Get/set/remove/list browser cookies',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['get', 'set', 'remove', 'list'], description: 'get: read by name; set: write (requires name+value+domain); remove: delete by name; list: list all' },\n name: { type: 'string' },\n value: { type: 'string', description: 'Required for set' },\n domain: { type: 'string', description: 'Required for set' },\n path: { type: 'string' },\n secure: { type: 'boolean' },\n httpOnly: { type: 'boolean' },\n expirationDate: { type: 'number' }\n },\n required: ['action']\n }\n }\n },\n{\n id: 'clear_data',\n category: 'storage_management',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: true,\n type: 'function',\n function: {\n name: 'clear_data',\n description: 'Clear localStorage/sessionStorage for a site or current page',\n parameters: {\n type: 'object',\n properties: {\n site: { type: 'string' }\n }\n }\n }\n },\n {\n id: 'fetch_url',\n category: 'network_request',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'fetch_url',\n description: 'Send HTTP GET/POST request to a URL. Returns response body as text. For JavaScript-rendered pages, use manage_tab(open)+page_content instead',\n parameters: {\n type: 'object',\n properties: {\n url: { type: 'string' },\n method: { type: 'string', enum: ['GET', 'POST'] },\n headers: { type: 'object' },\n body: { type: 'string' },\n timeout: { type: 'integer' }\n },\n required: ['url']\n }\n }\n },\n];\n","// media-tools - media output + debug dev tool definitions\n\nexport const MEDIA_TOOLS = [\n {\n id: 'notify',\n category: 'media_output',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'notify',\n description: 'Show notification',\n parameters: {\n type: 'object',\n properties: {\n title: { type: 'string' },\n message: { type: 'string' },\n icon: { type: 'string' },\n silent: { type: 'boolean' },\n requireInteraction: { type: 'boolean' },\n playSound: { type: 'boolean' },\n soundType: { type: 'string', enum: ['default', 'success', 'warning', 'error'] }\n },\n required: ['title', 'message']\n }\n }\n },\n {\n id: 'clipboard',\n category: 'media_output',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'clipboard',\n description: 'Clipboard operations. copy: write text to clipboard (requires text); paste: paste from clipboard; get_selected: get currently selected text on page',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['copy', 'paste', 'get_selected'], description: 'copy: write text; paste: paste clipboard; get_selected: get page selection' },\n text: { type: 'string', description: 'Required for copy' },\n format: { type: 'string', enum: ['text', 'html'], description: 'for get_selected' }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'download_file',\n category: 'media_output',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: true,\n type: 'function',\n function: {\n name: 'download_file',\n description: 'Download file',\n parameters: {\n type: 'object',\n properties: {\n url: { type: 'string' },\n filename: { type: 'string' }\n },\n required: ['url']\n }\n }\n },\n {\n id: 'qrcode',\n category: 'media_output',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'qrcode',\n description: 'Generate QR code',\n parameters: {\n type: 'object',\n properties: {\n content: { type: 'string' },\n size: { type: 'integer' },\n errorCorrection: { type: 'string', enum: ['L', 'M', 'Q', 'H'] },\n showImage: { type: 'boolean' }\n }\n }\n }\n },\n {\n id: 'capture_page',\n category: 'media_output',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'capture_page',\n description: 'Capture page screenshot. download: save image locally; analyze: send to vision model for analysis (requires vision API configured); both: download + analyze',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['download', 'analyze', 'both'], description: 'download: save locally; analyze: vision model analysis; both: download + analyze' },\n tabId: { type: 'integer', description: 'Required for analyze/both' },\n format: { type: 'string', enum: ['jpeg', 'png'] },\n quality: { type: 'integer' },\n visionMaxDim: { type: 'integer', minimum: 512, maximum: 2048, description: 'Max dimension (px) of image for vision analysis' },\n visionQuality: { type: 'integer', minimum: 30, maximum: 95, description: 'JPEG quality of image for vision analysis' }\n }\n }\n }\n },\n {\n id: 'browser_info',\n category: 'debug_dev',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'browser_info',\n description: 'Get browser version, platform, and environment info',\n parameters: {\n type: 'object',\n properties: {}\n }\n }\n },\n {\n id: 'inject_css',\n category: 'debug_dev',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'inject_css',\n description: 'Inject custom CSS into the page. style: insert stylesheet; inline: apply inline style to matched elements',\n parameters: {\n type: 'object',\n properties: {\n css: { type: 'string' },\n targetSelector: { type: 'string' },\n injectMode: { type: 'string', enum: ['style', 'inline'], description: 'style: insert <style> tag; inline: apply to elements matching targetSelector' }\n },\n required: ['css']\n }\n }\n },\n];\n","// ai-tools - ai collaboration tool definitions\n\nexport const AI_TOOLS = [\n {\n id: 'clarify_question',\n category: 'ai_collaboration',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'clarify_question',\n description: 'Ask the user a clarifying question with options when the task is ambiguous. Pauses execution until user responds',\n parameters: {\n type: 'object',\n properties: {\n question: { type: 'string' },\n options: { type: 'array', items: { type: 'string' } },\n recommendedOption: { type: 'integer' },\n allowCustomInput: { type: 'boolean' },\n allowAdditionalInfo: { type: 'boolean' }\n },\n required: ['question', 'options', 'recommendedOption']\n }\n }\n },\n {\n id: 'highlight_text',\n category: 'debug_dev',\n execution: 'content_script',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'highlight_text',\n description: 'Highlight text on the page for visual emphasis',\n parameters: {\n type: 'object',\n properties: {\n text: { type: 'string' },\n color: { type: 'string' }\n },\n required: ['text']\n }\n }\n },\n{\n id: 'plan_task',\n category: 'ai_collaboration',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'plan_task',\n description: 'Plan and decompose a complex task into subtasks for structured execution',\n parameters: {\n type: 'object',\n properties: {\n taskDescription: { type: 'string' },\n subtasks: {\n type: 'array',\n items: {\n type: 'object',\n properties: {\n id: { type: 'string' },\n name: { type: 'string' },\n description: { type: 'string' },\n dependencies: { type: 'array', items: { type: 'string' } },\n estimatedSteps: { type: 'integer' }\n },\n required: ['id', 'name', 'description']\n }\n },\n isComplex: { type: 'boolean' },\n strategy: { type: 'string', enum: ['sequential', 'parallel', 'conditional'] }\n },\n required: ['taskDescription', 'subtasks']\n }\n }\n },\n{\n id: 'search_chats',\n category: 'ai_collaboration',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'search_chats',\n description: 'Search past conversation history for context or previous answers',\n parameters: {\n type: 'object',\n properties: {\n query: { type: 'string', description: 'Search keyword; empty returns all' },\n maxResults: { type: 'integer' },\n searchScope: { type: 'string', enum: ['current_session', 'all_sessions'] }\n }\n }\n }\n },\n {\n id: 'preview_ui',\n category: 'ai_collaboration',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'preview_ui',\n description: 'Preview or retrieve a UI prototype. preview: render HTML in side panel (requires html+title); get: load a previously saved prototype (requires prototypeId)',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['preview', 'get'], description: 'preview: render HTML (requires html+title); get: load saved prototype (requires prototypeId)' },\n html: { type: 'string', description: 'Required for preview: HTML content to render' },\n title: { type: 'string', description: 'Required for preview: title of the prototype' },\n description: { type: 'string' },\n prototypeId: { type: 'string', description: 'Required for get: ID of saved prototype' }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'dispatch_task',\n category: 'ai_collaboration',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'dispatch_task',\n description: 'Dispatch a task to a sub-agent for parallel or specialized execution',\n parameters: {\n type: 'object',\n properties: {\n subAgentId: { type: 'string' },\n task: { type: 'string' }\n },\n required: ['subAgentId', 'task']\n }\n }\n },\n];\n","// agent-tools - local agent tool definitions\n\nexport const AGENT_TOOLS = [\n {\n id: 'agent_file',\n category: 'local_agent',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n confirmationActions: ['delete'],\n type: 'function',\n function: {\n name: 'agent_file',\n description: 'File operations on the agent local filesystem. read: get file content; write: create/overwrite file (requires content); list: list directory; delete: move to trash; download: download file to browser',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['read', 'write', 'list', 'delete', 'download'], description: 'read: get content; write: create/overwrite; list: directory listing; delete: trash; download: save to browser' },\n path: { type: 'string', description: 'File/directory path; optional for list (defaults to workdir)' },\n content: { type: 'string', description: 'Required for write: file content' }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'agent_trash',\n category: 'local_agent',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'agent_trash',\n description: 'Manage agent trash bin. list: view deleted items; restore: recover from trash (requires trashId)',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['list', 'restore'], description: 'list: view trash; restore: recover item (requires trashId)' },\n trashId: { type: 'string', description: 'Required for restore' },\n hours: { type: 'integer' },\n type: { type: 'string', enum: ['file', 'directory'] }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'agent_exec',\n category: 'local_agent',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'agent_exec',\n description: 'Execute a shell command on the agent machine. Returns stdout/stderr and exit code',\n parameters: {\n type: 'object',\n properties: {\n command: { type: 'string' },\n cwd: { type: 'string' },\n force: { type: 'boolean', description: 'Force execute confirmed command' },\n timeoutMs: { type: 'integer' }\n },\n required: ['command']\n }\n }\n },\n {\n id: 'agent_search',\n category: 'local_agent',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'agent_search',\n description: 'Search files or file content on the agent machine. file: find files by name pattern; content: search text/regex inside files',\n parameters: {\n type: 'object',\n properties: {\n searchType: { type: 'string', enum: ['file', 'content'], description: 'file: find files by name; content: search inside files' },\n path: { type: 'string' },\n pattern: { type: 'string' },\n recursive: { type: 'boolean' },\n filePattern: { type: 'string' },\n caseSensitive: { type: 'boolean' },\n maxResults: { type: 'integer' },\n contextLines: { type: 'integer' }\n },\n required: ['searchType', 'path']\n }\n }\n },\n {\n id: 'agent_skill',\n category: 'local_agent',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'agent_skill',\n description: 'Load or run a Skill. run: execute a Workflow Skill (requires params); load: load an Agent Skill instruction into context',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['load', 'run'], description: 'run: execute Workflow Skill (requires params); load: load Agent Skill instructions' },\n name: { type: 'string' },\n params: { type: 'object', description: 'Required for run: Workflow Skill parameters' }\n },\n required: ['action', 'name']\n }\n }\n },\n {\n id: 'manage_agent',\n category: 'ai_collaboration',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'manage_agent',\n description: 'List or switch paired AI agents',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['list', 'switch'], description: 'list: show all paired agents; switch: change active agent (requires agentId)' },\n agentId: { type: 'string', description: 'Required for switch' },\n agentName: { type: 'string' }\n },\n required: ['action']\n }\n }\n },\n {\n id: 'exec_log',\n category: 'ai_collaboration',\n execution: 'background',\n parallelizable: true,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'exec_log',\n description: 'Extract historical execution logs to analyze successful paths and failure lessons.',\n parameters: {\n type: 'object',\n properties: {\n scope: { type: 'string', enum: ['last_n_rounds', 'full_session'], description: 'Scope' },\n rounds: { type: 'integer', description: 'Number of rounds (default 3)' },\n sessionId: { type: 'string', description: 'Session ID' }\n },\n required: ['scope']\n }\n }\n },\n];\n","// memory-tools - long-term memory tool definitions (3-in-1)\n// Memory file path: ~/.ai-helper-agent/memory/global-memory.json (Agent system config directory)\n// Actually stored on the Agent local file system, read/written via agent_file\n\nexport const MEMORY_TOOLS = [\n {\n id: 'agent_memory',\n category: 'local_agent',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n type: 'function',\n function: {\n name: 'agent_memory',\n description: 'Long-term memory management. store: save memories (subAction: add/update/delete); recall: search memories; manage: review/compact memory store',\n parameters: {\n type: 'object',\n properties: {\n action: { type: 'string', enum: ['store', 'recall', 'manage'], description: 'store: save a memory (requires subAction); recall: search memories (requires query); manage: maintenance (requires subAction)' },\n subAction: { type: 'string', description: 'When action=store: add (create new), update (modify existing, requires memoryId), delete (remove, requires memoryId). When action=manage: review (list all), compact (merge/reduce)' },\n type: { type: 'string', enum: ['fact', 'summary'], description: 'Memory type' },\n category: { type: 'string', enum: ['preference', 'knowledge', 'decision', 'custom'], description: 'optional for store: memory category' },\n content: { type: 'string', description: 'Required for store: memory content to save' },\n title: { type: 'string', description: 'optional for store: title for summary type' },\n tags: { type: 'array', items: { type: 'string' }, description: 'optional for store/recall: tag filter' },\n importance: { type: 'integer', description: 'optional for store: importance 1-10' },\n memoryId: { type: 'string', description: 'Required for store subAction=update/delete: target memory ID' },\n sourceSessionId: { type: 'string', description: 'optional for store: source session ID' },\n query: { type: 'string', description: 'Required for recall: search keyword to find memories' },\n memoryType: { type: 'string', enum: ['fact', 'summary', 'all'], description: 'optional for recall: memory type filter, default all' },\n limit: { type: 'integer', description: 'optional for recall: max number of results, default 10' }\n },\n required: ['action']\n }\n }\n }\n];\n","// debugger-tools - 基于 Chrome DevTools Protocol 的高级页面调试工具\n//\n// 单工具 + action 枚举设计:\n// attach/detach/evaluate/input/network/screenshot/emulate\n// 普通点击/输入/内容提取应优先使用 interact_element、page_content 等常规工具,\n// 本工具仅覆盖 content script 无法实现的场景(原生输入、网络抓包、最早时机执行 JS 等)。\n\nexport const DEBUGGER_TOOLS = [\n {\n id: 'debug_page',\n category: 'debug_dev',\n execution: 'background',\n parallelizable: false,\n requiresConfirmation: false,\n confirmationActions: ['attach'],\n type: 'function',\n function: {\n name: 'debug_page',\n description: [\n 'Advanced page debugging via Chrome DevTools Protocol (stronger than content scripts).',\n 'Usage flow: MUST call action=attach first (user confirmation required; a yellow debugger infobar shows on the tab until detach), then call other actions, and finally call action=detach.',\n 'Only use this when normal tools are insufficient: native-level mouse/keyboard events (canvas, file inputs, widgets that ignore synthetic events), capturing XHR/fetch request and response bodies, evaluating JS at page context, full-page screenshots beyond the viewport, or device/UA emulation.',\n 'For ordinary clicking, typing, scrolling and content extraction, prefer interact_element / page_content (no debugger bar).',\n 'Actions:',\n 'attach: open a debugger session on the target tab (requires user confirmation).',\n 'detach: close the session and remove the debugger infobar. Call it when debugging work is done.',\n 'evaluate: execute JavaScript in the page main world and get its return value (async/await supported).',\n 'input: dispatch native input events — click (by selector or x/y), type text into a focused element, press a key (Enter/Tab/Escape/arrows...), mouse-wheel scroll.',\n 'network: passive network recording — start (optionally filterUrl), collect (drain recorded requests incl. response bodies), stop.',\n 'screenshot: capture viewport, full page, or a single element (by selector); the image is downloaded locally.',\n 'emulate: override userAgent, viewport/device metrics, geolocation, timezone, or prefers-color-scheme; use target=reset to clear all overrides.',\n ].join(' '),\n parameters: {\n type: 'object',\n properties: {\n action: {\n type: 'string',\n enum: ['attach', 'detach', 'evaluate', 'input', 'network', 'screenshot', 'emulate'],\n description: 'Debugger action to perform. attach is required before any other action.',\n },\n tabId: { type: 'integer', description: 'Target tab ID. Omit to use the active tab.' },\n\n // ── evaluate ──\n expression: {\n type: 'string',\n description: 'action=evaluate: JavaScript source to run in page context. May return a Promise (it is awaited). Return value is JSON-serialized.',\n },\n\n // ── input ──\n inputType: {\n type: 'string',\n enum: ['click', 'type', 'press', 'scroll'],\n description: 'action=input: event type. click=mouse click; type=insert text; press=keyboard shortcut; scroll=mouse wheel.',\n },\n selector: {\n type: 'string',\n description: 'CSS selector. action=input click/type: target element (click uses its center point; type focuses it first). action=screenshot: capture only this element box.',\n },\n x: { type: 'integer', description: 'action=input click/scroll: viewport X coordinate in CSS pixels (used when selector omitted).' },\n y: { type: 'integer', description: 'action=input click/scroll: viewport Y coordinate in CSS pixels (used when selector omitted).' },\n text: { type: 'string', description: 'action=input type: text to insert into the focused/target element.' },\n key: {\n type: 'string',\n description: 'action=input press: key name, e.g. \"Enter\", \"Tab\", \"Escape\", \"Backspace\", \"Delete\", \"Space\", \"ArrowLeft/Up/Right/Down\", \"Home\", \"End\", \"PageUp\", \"PageDown\", \"F5\", or a single character like \"a\" (prefix with \"Control+\"/\"Shift+\"/\"Alt+\" for modifiers). Single printable characters are typed as text (Shift-aware); Ctrl/Alt/Meta combos are treated as shortcuts and do not insert characters. For multi-character input use inputType=type.',\n },\n deltaX: { type: 'number', description: 'action=input scroll: horizontal wheel delta (positive scrolls left). Default 0.' },\n deltaY: { type: 'number', description: 'action=input scroll: vertical wheel delta (positive scrolls down). Default 300.' },\n\n // ── network ──\n networkMode: {\n type: 'string',\n enum: ['start', 'collect', 'stop'],\n description: 'action=network: start=begin recording; collect=return and clear buffered entries; stop=stop recording and return remaining entries.',\n },\n filterUrl: { type: 'string', description: 'action=network start: only record requests whose URL contains this substring (e.g. \"/api/\"). Omit to record all.' },\n\n // ── screenshot ──\n fullPage: { type: 'boolean', description: 'action=screenshot: capture the full scrollable page, not only the viewport. Ignored when selector is provided.' },\n imageFormat: { type: 'string', enum: ['png', 'jpeg'], description: 'action=screenshot: image format (default png).' },\n quality: { type: 'integer', description: 'action=screenshot: JPEG quality 1-100 (jpeg only).' },\n\n // ── emulate ──\n emulateTarget: {\n type: 'string',\n enum: ['ua', 'viewport', 'geolocation', 'timezone', 'colorScheme', 'reset'],\n description: 'action=emulate: what to override. reset clears ALL emulation overrides.',\n },\n userAgent: { type: 'string', description: 'action=emulate target=ua: custom User-Agent string.' },\n viewportWidth: { type: 'integer', description: 'action=emulate target=viewport: viewport width in CSS pixels.' },\n viewportHeight: { type: 'integer', description: 'action=emulate target=viewport: viewport height in CSS pixels.' },\n deviceScaleFactor: { type: 'number', description: 'action=emulate target=viewport: DPR (default 1).' },\n mobile: { type: 'boolean', description: 'action=emulate target=viewport: enable mobile metrics (touch, fixed viewport).' },\n latitude: { type: 'number', description: 'action=emulate target=geolocation: latitude.' },\n longitude: { type: 'number', description: 'action=emulate target=geolocation: longitude.' },\n timezoneId: { type: 'string', description: 'action=emulate target=timezone: IANA timezone id, e.g. \"Asia/Shanghai\" or \"America/New_York\".' },\n colorScheme: { type: 'string', enum: ['dark', 'light'], description: 'action=emulate target=colorScheme: emulate prefers-color-scheme.' },\n },\n required: ['action'],\n },\n },\n },\n];\n","// background/constants.js - 默认配置和内置工具定义\n\n// 默认配置\nexport const DEFAULT_API_BASE = 'https://api.deepseek.com';\nexport const DEFAULT_MODEL = 'deepseek-v4-pro';\n\n// ReAct 循环配置默认值\nexport const DEFAULT_REACT_CONFIG = {\n maxIterations: 100, // 最大循环次数 (1-1000)\n apiTimeout: 300000, // API 请求超时 (ms) (10000-600000)\n loopTimeout: 7200000, // 整体循环超时 (ms) (60000-7200000)\n toolTimeout: 600000, // 工具执行超时 (ms) (5000-600000)\n clarifyTimeout: 300000, // 澄清工具超时 (ms) (60000-600000),默认5分钟\n apiRetryCount: 3, // API 调用失败重试次数 (0-10)\n apiRetryBaseDelay: 1000, // API 重试基础延迟 (ms) (500-30000),指数退避\n enableToolPreselect: false, // 是否启用工具预筛选(默认关闭)\n preselectMinToolCount: 10, // 工具预筛选最小触发数量(工具数超过此值才启动预筛选)\n toolConfirmationEnabled: true // 是否启用敏感操作确认(关闭后敏感操作直接放行)\n};\n\n// 反思配置默认值\nexport const DEFAULT_REFLECTION_CONFIG = {\n enabled: false, // 是否启用反思(可整体关闭)\n postReflection: {\n enabled: true, // 主循环后置反思\n maxRounds: 1, // 最大反思轮数(0=不反思)\n qualityThreshold: 7, // 质量评分阈值(1-10),低于此值重新执行\n refineThreshold: 5, // 修订阈值(1-10),低于此值直接修订而非重新执行\n model: null, // 反思用模型,null=使用当前模型\n temperature: 0.3, // 反思时 temperature\n maxTokens: 2048 // 反思响应最大 token\n },\n subtaskReflection: {\n enabled: false, // 子任务反思(默认关闭)\n onlyForComplexSubtasks: true, // 仅标记为 complex 的子任务\n maxRounds: 1,\n dimensions: ['completeness', 'relevance'], // 简化维度\n model: null,\n temperature: 0.3,\n maxTokens: 1024\n },\n toolReflection: {\n enabled: true, // 工具级反思\n triggerOnError: true, // 工具返回错误时触发\n triggerOnEmpty: true, // 工具返回空结果时触发\n triggerOnOversized: true, // 工具返回结果过大时触发\n oversizeThreshold: 50000, // 结果大小阈值(字符)\n triggerOnConsecutiveFails: 3, // 连续 N 次工具失败触发\n maxPerIteration: 2 // 每轮迭代最多触发工具反思次数\n }\n};\n\n// 流式输出配置默认值\nexport const DEFAULT_STREAM_CONFIG = {\n streamEnabled: true, // LLM 流式输出默认开启\n streamChunkDelay: 30, // Side Panel 渲染字符间延迟 (ms),0=瞬间渲染\n agentStreamEnabled: true // Agent 命令流式输出默认开启\n};\n\n// 对话配置默认值\nexport const DEFAULT_CHAT_CONFIG = {\n maxMemoryMessages: 20, // 记忆历史限制条数,默认20条\n enableExecutionLog: true // 执行日志默认开启\n};\n\n// ==================== 工具定义(按类别拆分到 tools/ 目录) ====================\n\nimport { BROWSER_TOOLS } from './tools/browser-tools.js';\nimport { TAB_TOOLS } from './tools/tab-tools.js';\nimport { STORAGE_TOOLS } from './tools/storage-tools.js';\nimport { MEDIA_TOOLS } from './tools/media-tools.js';\nimport { AI_TOOLS } from './tools/ai-tools.js';\nimport { AGENT_TOOLS } from './tools/agent-tools.js';\nimport { MEMORY_TOOLS } from './tools/memory-tools.js';\nimport { DEBUGGER_TOOLS } from './tools/debugger-tools.js';\n\nexport const RAW_TOOLS = [\n ...BROWSER_TOOLS,\n ...TAB_TOOLS,\n ...STORAGE_TOOLS,\n ...MEDIA_TOOLS,\n ...AI_TOOLS,\n ...AGENT_TOOLS,\n ...MEMORY_TOOLS,\n ...DEBUGGER_TOOLS,\n];\n\n// ==================== 工具类别映射(单一数据源) ====================\n\n// 类别权重:用于确定分类显示顺序(数字越小越靠前)\nexport const CATEGORY_WEIGHT = {\n page_interaction: 1,\n form_operation: 2,\n content_extraction: 3,\n tab_management: 4,\n bookmark_history: 5,\n storage_management: 6,\n network_request: 7,\n media_output: 8,\n debug_dev: 9,\n ai_collaboration: 10,\n local_agent: 11,\n mcp: 12,\n knowledge: 13,\n};\n\n// 从 RAW_TOOLS 动态派生分类顺序列表(单一数据源,无需手动维护)\nexport const CATEGORY_ORDER = [...new Set(RAW_TOOLS.map(t => t.category))]\n .sort((a, b) => (CATEGORY_WEIGHT[a] || 99) - (CATEGORY_WEIGHT[b] || 99));\n\n// 从 RAW_TOOLS 自动派生所有映射表\nexport const BUILTIN_TOOLS = RAW_TOOLS.map(t => ({ id: t.id, type: t.type, function: t.function }));\nexport const TOOL_CATEGORY_MAP = Object.fromEntries(RAW_TOOLS.map(t => [t.id, t.category]));\nexport const TOOL_EXECUTION_MAP = Object.fromEntries(RAW_TOOLS.map(t => [t.id, t.execution]));\nexport const PARALLELIZABLE_TOOLS = new Set(RAW_TOOLS.filter(t => t.parallelizable).map(t => t.id));\nexport const CONFIRMATION_REQUIRED_TOOLS = new Set(RAW_TOOLS.filter(t => t.requiresConfirmation).map(t => t.id));\n// 合并工具的 action 级别确认映射(如 manage_tab 的 close action 需要确认)\n// 派生结果示例:{ manage_tab: ['close'] }\nexport const CONFIRMATION_ACTION_MAP = Object.fromEntries(\n RAW_TOOLS.filter(t => Array.isArray(t.confirmationActions) && t.confirmationActions.length > 0)\n .map(t => [t.id, t.confirmationActions])\n);\nexport const BUILTIN_TOOLS_UI = RAW_TOOLS.map(t => ({\n id: t.id, name: t.function.name, description: t.function.description,\n category: t.category, execution: t.execution,\n parallelizable: t.parallelizable, requiresConfirmation: t.requiresConfirmation,\n enabled: true\n}));\n\n// ==================== 工具自定义超时配置 ====================\n// 各工具的超时时间(ms),未配置的工具默认使用 toolTimeout(600000ms = 10分钟)\n// 格式:{ 工具id: 超时毫秒数 }\n// 示例:将快速工具设为较短超时以减少卡死等待时间:\n// list_tabs: 15000, // 获取标签页列表,15s\n// manage_tab: 10000, // 标签页操作,10s\n// download_file: 600000, // 下载文件,10分钟(覆盖默认值)\n// 注意:当前所有工具沿用全局 toolTimeout,此配置仅提供扩展能力\nexport const TOOL_TIMEOUT_MS = {\n // 预留扩展:按需为各工具配置独立超时\n};\n","// shared/model-profiles.js - 模型厂商配置(多配置记忆与切换)\n//\n// 设计:modelProfiles 保存多套厂商配置(地址/Key/模型列表/选中模型),\n// activeProfileId 标记当前激活项。扁平键(apiBase/apiKey/modelName/customModels)\n// 保留为\"激活配置的运行时投影\"——所有既有调用链(background/会话/Agent)零改动。\n// 切换配置时由本模块统一把配置字段写回扁平键,避免数据分叉。\n\nconst PROFILES_KEY = 'modelProfiles';\nconst ACTIVE_PROFILE_KEY = 'activeProfileId';\n\n// 迁移初始配置的固定 id(两端并发迁移时幂等,不会产生重复条目)\nconst LEGACY_PROFILE_ID = 'profile-legacy-default';\n\n// 历史硬编码预设模型(迁移时快照进配置的完整模型列表)\nconst LEGACY_PRESET_MODELS = ['deepseek-v4-pro', 'deepseek-v4-flash'];\n\nexport const DEFAULT_API_BASE = 'https://api.deepseek.com';\nexport const DEFAULT_MODEL_NAME = 'deepseek-v4-pro';\n\n// 预设厂商域名 → 配置默认名映射\nconst VENDOR_NAME_RULES = [\n [/api\\.deepseek\\.com/i, 'DeepSeek'],\n [/hunyuan\\.cloud\\.tencent\\.com/i, '腾讯混元'],\n [/dashscope\\.aliyuncs\\.com/i, '阿里云百炼'],\n [/qianfan\\.baidubce\\.com/i, '百度千帆'],\n [/ark\\.cn-beijing\\.volces\\.com/i, '火山方舟'],\n [/open\\.bigmodel\\.cn/i, '智谱 GLM'],\n [/api\\.moonshot\\.cn/i, 'Moonshot'],\n [/api\\.stepfun\\.com/i, '阶跃星辰'],\n [/api\\.minimaxi\\.com/i, 'MiniMax'],\n [/spark-api-open\\.xf-yun\\.com/i, '讯飞星火'],\n [/api\\.baichuan-ai\\.com/i, '百川智能'],\n [/api\\.siliconflow\\.cn/i, '硅基流动'],\n [/api\\.openai\\.com/i, 'OpenAI'],\n [/api\\.anthropic\\.com/i, 'Anthropic'],\n [/generativelanguage\\.googleapis\\.com/i, 'Google Gemini'],\n [/openrouter\\.ai/i, 'OpenRouter'],\n [/api\\.groq\\.com/i, 'Groq'],\n [/api\\.mistral\\.ai/i, 'Mistral'],\n];\n\n/**\n * 生成配置 id(优先 crypto.randomUUID,兜底时间戳+随机串)\n */\nfunction generateId() {\n if (typeof crypto !== 'undefined' && typeof crypto.randomUUID === 'function') {\n return crypto.randomUUID();\n }\n return `p-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;\n}\n\n/**\n * 从 apiBase 提取主机名(用于列表右侧提示)\n * @param {string} apiBase\n * @returns {string}\n */\nexport function getHostFromApiBase(apiBase) {\n const raw = String(apiBase || '').trim();\n if (!raw) return '';\n try {\n return new URL(raw).hostname;\n } catch {\n return raw.replace(/^https?:\\/\\//i, '').split('/')[0];\n }\n}\n\n/**\n * 从 apiBase 推导配置默认名(预设厂商映射,未知域名回退主机名)\n * @param {string} apiBase\n * @returns {string}\n */\nexport function deriveProfileName(apiBase) {\n const raw = String(apiBase || '').trim();\n if (!raw) return '';\n for (const [re, name] of VENDOR_NAME_RULES) {\n if (re.test(raw)) return name;\n }\n return getHostFromApiBase(raw);\n}\n\n/**\n * 模型列表归一化:兼容旧格式(字符串)与新格式({name, contextWindow})\n * @param {Array} list\n * @returns {Array<{name: string, contextWindow: number}>}\n */\nexport function normalizeModels(list) {\n const out = [];\n if (!Array.isArray(list)) return out;\n for (const item of list) {\n if (typeof item === 'string' && item) {\n out.push({ name: item, contextWindow: 0 });\n } else if (item && typeof item === 'object' && item.name) {\n out.push({ name: item.name, contextWindow: item.contextWindow || 0 });\n }\n }\n return out;\n}\n\n/**\n * 名称排序比较器:不区分大小写(固定 zh 排序规则,Node 与 Chrome 的 ICU 行为一致);\n * 汉字组整体排在拉丁字母前、组内按拼音,拉丁字母按字母序。\n * 用于厂商 / 模型下拉列表的展示排序,仅影响渲染顺序,不改变配置存储顺序\n * @param {string} a\n * @param {string} b\n * @returns {number}\n */\nexport function compareByName(a, b) {\n return String(a || '').toLowerCase().localeCompare(String(b || '').toLowerCase(), 'zh');\n}\n\n/**\n * 读取完整配置状态\n * @returns {Promise<{profiles: Array, activeProfileId: string}>}\n */\nexport async function getState() {\n const result = await chrome.storage.local.get([PROFILES_KEY, ACTIVE_PROFILE_KEY]);\n const profiles = Array.isArray(result[PROFILES_KEY]) ? result[PROFILES_KEY] : [];\n return { profiles, activeProfileId: result[ACTIVE_PROFILE_KEY] || '' };\n}\n\n/**\n * 获取当前激活配置对象(无则返回 null)\n * @param {{profiles: Array, activeProfileId: string}} [state]\n * @returns {Promise<object|null>}\n */\nexport async function getActiveProfile(state) {\n const s = state || await getState();\n return s.profiles.find(p => p.id === s.activeProfileId) || null;\n}\n\n/**\n * 校验模型名是否属于指定配置的可用模型(选中的模型名或模型列表内)\n * 用于「历史模型名 + 当前厂商连接」错配场景的运行时一致性校验(如定时任务\n * 执行时宿主会话/Agent 携带的可能仍是旧厂商的模型名)。\n * @param {string} modelName\n * @param {object|null} profile\n * @returns {boolean}\n */\nexport function isModelInProfile(modelName, profile) {\n if (!modelName || !profile) return false;\n if (modelName === profile.modelName) return true;\n return normalizeModels(profile.models).some((m) => m.name === modelName);\n}\n\n/**\n * 迁移旧数据并确保配置状态就绪(幂等,可在多个页面并发调用)\n * @param {{fallbackName?: string}} [opts]\n * @returns {Promise<{profiles: Array, activeProfileId: string, migrated: boolean}>}\n */\nexport async function ensureProfilesMigrated(opts = {}) {\n let state = await getState();\n\n if (state.profiles.length === 0) {\n // 用当前扁平键 + 预设模型快照构造初始配置\n const flat = await chrome.storage.local.get([\n 'apiBase', 'apiKey', 'modelName', 'customModels', 'deletedPresetModels',\n ]);\n const deletedPresets = Array.isArray(flat.deletedPresetModels) ? flat.deletedPresetModels : [];\n const models = [];\n const indexOf = new Map();\n for (const name of LEGACY_PRESET_MODELS) {\n if (!deletedPresets.includes(name)) {\n indexOf.set(name, models.length);\n models.push({ name, contextWindow: 0 });\n }\n }\n for (const item of normalizeModels(flat.customModels)) {\n if (indexOf.has(item.name)) {\n if (item.contextWindow > 0) models[indexOf.get(item.name)].contextWindow = item.contextWindow;\n } else {\n indexOf.set(item.name, models.length);\n models.push(item);\n }\n }\n\n const apiBase = flat.apiBase || DEFAULT_API_BASE;\n const now = Date.now();\n const profile = {\n id: LEGACY_PROFILE_ID,\n name: deriveProfileName(apiBase) || opts.fallbackName || 'AI',\n apiBase,\n apiKey: flat.apiKey || '',\n modelName: flat.modelName || DEFAULT_MODEL_NAME,\n models,\n createdAt: now,\n updatedAt: now,\n };\n\n // 二次读取防并发双写:另一端已写入则直接采用\n const recheck = await getState();\n if (recheck.profiles.length > 0) {\n return repairActiveId(recheck);\n }\n\n await chrome.storage.local.set({\n [PROFILES_KEY]: [profile],\n [ACTIVE_PROFILE_KEY]: profile.id,\n // 同步扁平键:迁移后 customModels 即配置的完整模型列表(投影保持一致)\n customModels: models,\n });\n return { profiles: [profile], activeProfileId: profile.id, migrated: true };\n }\n\n return repairActiveId(state);\n}\n\n/**\n * 修复 activeProfileId 缺失/失效的情况\n */\nasync function repairActiveId(state) {\n const valid = state.profiles.some(p => p.id === state.activeProfileId);\n if (valid) return { ...state, migrated: false };\n const activeProfileId = state.profiles[0].id;\n await chrome.storage.local.set({ [ACTIVE_PROFILE_KEY]: activeProfileId });\n return { profiles: state.profiles, activeProfileId, migrated: false };\n}\n\n/**\n * 切换激活配置:把配置字段同步回扁平键(立即生效)\n * @param {string} id\n * @returns {Promise<object|null>} 切换后的配置对象\n */\nexport async function applyProfile(id) {\n const state = await getState();\n const profile = state.profiles.find(p => p.id === id);\n if (!profile) return null;\n\n await chrome.storage.local.set({\n apiBase: profile.apiBase || DEFAULT_API_BASE,\n apiKey: profile.apiKey || '',\n modelName: profile.modelName || DEFAULT_MODEL_NAME,\n customModels: normalizeModels(profile.models),\n [ACTIVE_PROFILE_KEY]: profile.id,\n });\n return profile;\n}\n\n/**\n * 更新激活配置的字段(如保存配置时同步地址/Key/模型名/模型列表)\n * @param {object} patch - 允许的字段:name/apiBase/apiKey/modelName/models\n * @returns {Promise<object|null>} 更新后的配置对象\n */\nexport async function updateActiveProfile(patch) {\n const state = await getState();\n const profile = state.profiles.find(p => p.id === state.activeProfileId);\n if (!profile) return null;\n\n const next = {\n ...profile,\n updatedAt: Date.now(),\n };\n if (patch.name !== undefined) next.name = String(patch.name).trim() || profile.name;\n if (patch.apiBase !== undefined) next.apiBase = patch.apiBase;\n if (patch.apiKey !== undefined) next.apiKey = patch.apiKey;\n if (patch.modelName !== undefined) next.modelName = patch.modelName;\n if (patch.models !== undefined) next.models = normalizeModels(patch.models);\n\n const profiles = state.profiles.map(p => (p.id === profile.id ? next : p));\n await chrome.storage.local.set({ [PROFILES_KEY]: profiles });\n return next;\n}\n\n/**\n * 同步激活配置的模型列表(模型增删改后调用)\n * @param {Array} models\n */\nexport function syncActiveProfileModels(models) {\n return updateActiveProfile({ models });\n}\n\n/**\n * 同步激活配置的选中模型(切换模型时调用)\n * @param {string} modelName\n */\nexport function updateActiveProfileModelName(modelName) {\n return updateActiveProfile({ modelName });\n}\n\n/**\n * 新建配置\n * @param {object} data - {name, apiBase, apiKey, modelName, models}\n * @param {{activate?: boolean}} [opts]\n * @returns {Promise<object>} 新配置对象\n */\nexport async function createProfile(data = {}, opts = {}) {\n const state = await getState();\n const now = Date.now();\n const profile = {\n id: generateId(),\n name: String(data.name || '').trim() || deriveProfileName(data.apiBase) || 'AI',\n apiBase: data.apiBase !== undefined ? data.apiBase : DEFAULT_API_BASE,\n apiKey: data.apiKey || '',\n modelName: data.modelName || DEFAULT_MODEL_NAME,\n models: normalizeModels(data.models),\n createdAt: now,\n updatedAt: now,\n };\n\n const profiles = [...state.profiles, profile];\n const payload = { [PROFILES_KEY]: profiles };\n if (opts.activate !== false) {\n payload[ACTIVE_PROFILE_KEY] = profile.id;\n payload.apiBase = profile.apiBase || DEFAULT_API_BASE;\n payload.apiKey = profile.apiKey;\n payload.modelName = profile.modelName;\n payload.customModels = profile.models;\n }\n await chrome.storage.local.set(payload);\n return profile;\n}\n\n/**\n * 重命名配置\n * @param {string} id\n * @param {string} name\n * @returns {Promise<boolean>} 是否重命名成功\n */\nexport async function renameProfile(id, name) {\n const newName = String(name || '').trim();\n if (!newName) return false;\n const state = await getState();\n const target = state.profiles.find(p => p.id === id);\n if (!target) return false;\n\n const profiles = state.profiles.map(p => (\n p.id === id ? { ...p, name: newName, updatedAt: Date.now() } : p\n ));\n await chrome.storage.local.set({ [PROFILES_KEY]: profiles });\n return true;\n}\n\n/**\n * 删除配置(至少保留一个;删除激活项时自动激活剩余第一个并同步扁平键)\n * @param {string} id\n * @returns {Promise<{deleted: boolean, reason?: string, activeProfileId: string, nextActive?: object|null}>}\n */\nexport async function deleteProfile(id) {\n const state = await getState();\n if (state.profiles.length <= 1) {\n return { deleted: false, reason: 'last', activeProfileId: state.activeProfileId };\n }\n const target = state.profiles.find(p => p.id === id);\n if (!target) {\n return { deleted: false, reason: 'not-found', activeProfileId: state.activeProfileId };\n }\n\n const profiles = state.profiles.filter(p => p.id !== id);\n let activeProfileId = state.activeProfileId;\n let nextActive = null;\n if (activeProfileId === id) {\n activeProfileId = profiles[0].id;\n nextActive = profiles[0];\n }\n\n const payload = { [PROFILES_KEY]: profiles, [ACTIVE_PROFILE_KEY]: activeProfileId };\n if (nextActive) {\n payload.apiBase = nextActive.apiBase || DEFAULT_API_BASE;\n payload.apiKey = nextActive.apiKey || '';\n payload.modelName = nextActive.modelName || DEFAULT_MODEL_NAME;\n payload.customModels = normalizeModels(nextActive.models);\n }\n await chrome.storage.local.set(payload);\n return { deleted: true, activeProfileId, nextActive };\n}\n\n/**\n * 判断是否为“空白默认配置”(自动迁移生成、从未被用户配置过)\n */\nfunction isPristineDefault(p) {\n return !!p\n && !p.apiKey\n && (!p.apiBase || p.apiBase === DEFAULT_API_BASE)\n && (!p.modelName || p.modelName === DEFAULT_MODEL_NAME);\n}\n\n/**\n * 导入合并用:按 id 对齐合并厂商配置\n * - 新 id:追加\n * - 同 id:文件条目 updatedAt 较新则覆盖,否则忽略(保留本机);\n * 例外:本机条目为空白默认配置时不阻挡同 id 导入(新环境迁移场景)\n * - 无 id 的条目:无法对齐,跳过\n * @param {Array} localProfiles - 本机现有配置\n * @param {Array} incomingProfiles - 导入文件中的配置\n * @returns {Array} 合并后的配置列表(不修改原数组)\n */\nexport function mergeProfiles(localProfiles, incomingProfiles) {\n const merged = Array.isArray(localProfiles) ? localProfiles.map(p => ({ ...p })) : [];\n if (!Array.isArray(incomingProfiles)) return merged;\n\n for (const inc of incomingProfiles) {\n if (!inc || !inc.id) continue;\n const idx = merged.findIndex(p => p.id === inc.id);\n if (idx === -1) {\n merged.push({ ...inc });\n continue;\n }\n const fileTs = Number(inc.updatedAt) || 0;\n const localTs = Number(merged[idx].updatedAt) || 0;\n if (fileTs > localTs || isPristineDefault(merged[idx])) {\n const next = { ...inc };\n // 不含密钥导出时文件 apiKey 为空:继承本机密钥,避免误清\n if (!next.apiKey && merged[idx].apiKey) next.apiKey = merged[idx].apiKey;\n merged[idx] = next;\n }\n // 文件条目不更新(老文件):忽略,保留本机\n }\n return merged;\n}\n\n/**\n * 导出用:剥离配置中的密钥\n * @param {Array} profiles\n * @returns {Array}\n */\nexport function stripProfileSecrets(profiles) {\n if (!Array.isArray(profiles)) return [];\n return profiles.map(p => ({ ...p, apiKey: '' }));\n}\n"],"mappings":"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"}
@@ -1 +0,0 @@
1
- *{box-sizing:border-box;margin:0;padding:0}body{color:#333;background:#f5f7fa;padding:30px;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Helvetica Neue,Arial,sans-serif}.container{background:#fff;border-radius:12px;max-width:600px;margin:0 auto;padding:30px;box-shadow:0 2px 12px #0000001a}.page-header{justify-content:space-between;align-items:flex-start;margin-bottom:24px;display:flex}.header-left h1{color:#667eea;text-align:left;margin-top:0;margin-bottom:6px;font-size:24px}.header-left .subtitle{color:#888;text-align:left;margin-bottom:0;font-size:14px}.header-actions{flex-shrink:0;gap:8px;padding-top:6px;display:flex}.icon-btn{cursor:pointer;color:#666;background:#fff;border:1px solid #ddd;border-radius:8px;justify-content:center;align-items:center;width:38px;height:38px;padding:0;transition:all .2s;display:flex;position:relative}.icon-btn:hover{color:#667eea;background:#f0f0f0;border-color:#667eea}.icon-btn svg{pointer-events:none;width:18px;height:18px}.form-group{margin-bottom:20px}label{color:#555;margin-bottom:8px;font-weight:500;display:block}label .hint{color:#999;font-size:12px;font-weight:400}label .info-icon{text-align:center;color:#fff;cursor:help;vertical-align:middle;background:#667eea;border-radius:50%;width:16px;height:16px;margin-left:4px;font-size:11px;line-height:16px;display:inline-block}input[type=text],input[type=url],input[type=password],input[type=number],textarea{border:1px solid #e0e0e0;border-radius:8px;width:100%;padding:12px;font-family:Consolas,Monaco,monospace;font-size:14px;transition:border-color .2s,box-shadow .2s}input[type=text]:focus,input[type=url]:focus,input[type=password]:focus,input[type=number]:focus,textarea:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 3px #667eea26}select{color:#333;cursor:pointer;appearance:none;background-color:#fff;background-image:url("data:image/svg+xml;utf8,<svg xmlns='http://www.w3.org/2000/svg' width='10' height='10' viewBox='0 0 10 10'><polygon points='0,2 10,2 5,8' fill='%23999'/></svg>");background-position:right 12px center;background-repeat:no-repeat;border:1px solid #e0e0e0;border-radius:8px;width:100%;padding:12px 40px 12px 12px;font-family:inherit;font-size:14px;transition:border-color .2s,box-shadow .2s}select:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 3px #667eea26}textarea{resize:vertical;height:120px;min-height:80px}.btn{cursor:pointer;border:none;border-radius:8px;padding:12px 30px;font-size:14px;font-weight:500;transition:all .2s}.btn-primary{color:#fff;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);width:100%}.btn-primary:hover{transform:translateY(-1px);box-shadow:0 4px 12px #667eea66}.btn-primary:active{transform:translateY(0)}.btn-save{cursor:pointer;color:#fff;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);border:none;border-radius:12px;justify-content:center;align-items:center;gap:10px;width:100%;padding:14px 0;font-size:15px;font-weight:600;transition:all .25s cubic-bezier(.4,0,.2,1);display:flex;position:relative;overflow:hidden;box-shadow:0 4px 15px #667eea4d}.btn-save .save-icon{flex-shrink:0;width:20px;height:20px;transition:transform .3s}.btn-save:hover{transform:translateY(-2px);box-shadow:0 8px 25px #667eea80}.btn-save:hover .save-icon{transform:scale(1.1)}.btn-save:active{transition:transform .1s;transform:scale(.98)}.btn-save .save-shine{pointer-events:none;background:linear-gradient(90deg,#0000,#ffffff26,#0000);width:60%;height:100%;position:absolute;top:0;left:-100%;transform:skew(-20deg)}.btn-save:hover .save-shine{animation:.6s ease-out saveShine}@keyframes saveShine{0%{left:-100%}to{left:150%}}.btn-save.saved{pointer-events:none;background:linear-gradient(135deg,#48bb78 0%,#38a169 100%);box-shadow:0 4px 20px #48bb7866}.btn-save.saved .save-icon{animation:.5s ease-out savePulse}@keyframes savePulse{0%{transform:scale(1)}30%{transform:scale(1.3)}to{transform:scale(1)}}.save-bar{z-index:50;background:#fff;margin-top:8px;padding:12px 24px 24px;transition:box-shadow .2s;position:sticky;bottom:0}.save-bar.floating{box-shadow:0 -6px 16px #0000000f}.status{border-radius:8px;margin-top:20px;padding:12px 16px;font-size:14px;display:none}.status.success{color:#38a169;background:#f0fff4;border:1px solid #c6f6d5;display:block}.status.error{color:#e53e3e;background:#fff5f5;border:1px solid #fed7d7;display:block}.info-box{background:#ebf8ff;border:1px solid #bee3f8;border-radius:8px;margin-bottom:20px;padding:16px}.info-box h3{color:#2b6cb0;margin-bottom:10px;font-size:14px}.info-box p{color:#4a5568;font-size:13px;line-height:1.6}.info-box code{background:#e2e8f0;border-radius:4px;padding:2px 6px;font-family:Consolas,Monaco,monospace;font-size:12px}.warning-box{background:#fefcbf;border:1px solid #faf089;border-radius:8px;margin-bottom:20px;padding:16px}.warning-box h3{color:#975a16;margin-bottom:8px;font-size:14px}.warning-box p{color:#744210;font-size:13px;line-height:1.6}.collapsible-header{cursor:pointer;-webkit-user-select:none;user-select:none;justify-content:space-between;align-items:center;display:flex}.collapsible-header:hover{opacity:.85}.collapsible-arrow{color:inherit;font-size:10px;transition:transform .2s}.collapsible-header.open .collapsible-arrow,.collapsible.open .collapsible-arrow{transform:rotate(90deg)}.toast-container{z-index:100000;pointer-events:none;flex-direction:column;gap:8px;display:flex;position:fixed;top:20px;left:50%;transform:translate(-50%)}.toast{color:#fff;opacity:0;pointer-events:auto;background:#333;border-radius:8px;justify-content:center;align-items:center;gap:8px;min-width:200px;padding:12px 24px;font-size:13px;transition:opacity .3s,transform .3s;display:flex;transform:translateY(-20px);box-shadow:0 4px 12px #0000004d}.toast.toast-show{opacity:1;transform:translateY(0)}.toast.success{background:#2d8a4e}.toast.error{background:#d9534f}.toast.warning{color:#333;background:#f0ad4e}.toast.info{background:#5bc0de}@keyframes toastFadeIn{0%{opacity:0;transform:translateY(-20px)}to{opacity:1;transform:translateY(0)}}.model-selector{position:relative}.model-selector input{background:#fff;border:1px solid #e0e0e0;border-radius:8px;width:100%;padding:12px 40px 12px 12px;font-family:Consolas,Monaco,monospace;font-size:14px;transition:border-color .2s,box-shadow .2s}.model-selector input:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 3px #667eea26}.model-selector:after{content:"▼";color:#999;pointer-events:none;font-size:10px;position:absolute;top:50%;right:12px;transform:translateY(-50%)}.model-dropdown{z-index:1000;background:#fff;border:1px solid #e0e0e0;border-radius:8px;max-height:240px;display:none;position:absolute;top:calc(100% + 5px);left:0;right:0;overflow:hidden auto;box-shadow:0 4px 12px #00000026}.model-dropdown.show{display:block}.model-dropdown-empty{color:#999;text-align:center;padding:10px 12px;font-size:13px}.model-option{color:#333;cursor:pointer;border-bottom:1px solid #f0f0f0;justify-content:space-between;align-items:center;padding:10px 12px;font-family:Consolas,Monaco,monospace;font-size:14px;transition:background .2s;display:flex}.model-option:last-child{border-bottom:none}.model-option:hover{background:#f5f7fa}.model-option.selected{color:#667eea;background:#f0f4ff;font-weight:500}.model-option .delete-model-btn{color:#e53e3e;cursor:pointer;opacity:.6;background:0 0;border:none;padding:0 4px;font-size:14px;line-height:1;transition:opacity .2s;display:none}.model-option:hover .delete-model-btn{opacity:1;display:inline-block}.model-option .delete-model-btn:hover{opacity:1;color:#c53030}.model-option .model-ctx-badge{color:#667eea;white-space:nowrap;background:#e8f0fe;border-radius:4px;flex-shrink:0;margin-left:8px;padding:1px 6px;font-family:Consolas,Monaco,monospace;font-size:11px}.model-option-right{flex-shrink:0;align-items:center;gap:8px;display:flex}.model-option-right .model-ctx-badge{margin-left:0}.model-option-left{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.api-base-url-hint{color:#999;white-space:nowrap;flex-shrink:0;font-family:Consolas,Monaco,monospace;font-size:11px}.profile-switcher-row{align-items:center;gap:8px;display:flex}.profile-switcher-row .profile-selector{flex:1;min-width:0}.profile-actions{flex-shrink:0;gap:6px;display:flex}.profile-action-btn{color:#555;cursor:pointer;white-space:nowrap;background:0 0;border:1px solid #e0e0e0;border-radius:6px;padding:8px 10px;font-family:inherit;font-size:12px;transition:all .2s}.profile-action-btn:hover{color:#667eea;background:#f0f4ff;border-color:#667eea}.profile-action-danger:hover{color:#e53e3e;background:#fff5f5;border-color:#e53e3e}.profile-option{color:#333;cursor:pointer;border-bottom:1px solid #f0f0f0;justify-content:space-between;align-items:center;gap:12px;padding:10px 12px;font-size:14px;transition:background .2s;display:flex}.profile-option:last-child{border-bottom:none}.profile-option:hover{background:#f5f7fa}.profile-option.selected{color:#667eea;background:#f0f4ff;font-weight:500}.profile-option-left{text-overflow:ellipsis;white-space:nowrap;flex:1;min-width:0;overflow:hidden}.profile-option-right{color:#999;white-space:nowrap;text-overflow:ellipsis;flex-shrink:0;max-width:55%;font-family:Consolas,Monaco,monospace;font-size:11px;overflow:hidden}#profileGroup{margin-bottom:12px}.profile-scope{background:#f8f9fe;border-radius:0 10px 10px 0;margin:0 0 20px;padding:12px 14px 0 18px;position:relative}.profile-scope:before{content:"";background:linear-gradient(#667eea,#764ba2);border-radius:3px;width:3px;position:absolute;top:0;bottom:0;left:0}.profile-scope-hint{color:#88a;-webkit-user-select:none;user-select:none;margin-bottom:12px;font-size:12px}.profile-scope>.form-group{margin-bottom:16px}.profile-scope>.form-group:last-child{margin-bottom:14px}.selected-ctx-badge{color:#667eea;white-space:nowrap;z-index:1;pointer-events:none;background:#e8f0fe;border-radius:4px;padding:2px 6px;font-family:Consolas,Monaco,monospace;font-size:11px;position:absolute;top:50%;right:36px;transform:translateY(-50%)}.add-model-section{flex-wrap:wrap;gap:6px;margin-top:4px;display:flex}.add-model-section>.add-model-toggle-btn{flex:auto;width:auto;min-width:0}.add-model-section>.add-model-form{flex:1 0 100%}.fetch-models-btn{white-space:nowrap}.add-model-toggle-btn{color:#667eea;cursor:pointer;text-align:center;background:0 0;border:1px dashed #667eea;border-radius:6px;width:100%;padding:6px 12px;font-size:13px;transition:all .2s}.add-model-toggle-btn:hover{background:#f0f4ff;border-style:solid}.add-model-form{background:#f8f9fc;border:1px solid #e8ecf4;border-radius:8px;flex-direction:column;gap:8px;margin-top:8px;padding:12px;display:flex}.add-model-form input{border:1px solid #e0e0e0;border-radius:6px;padding:8px 12px;font-family:Consolas,Monaco,monospace;font-size:13px}.add-model-form input:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 2px #667eea26}.add-model-form-actions{justify-content:flex-end;gap:8px;display:flex}.add-model-form-actions .btn-primary{color:#fff;cursor:pointer;background:#667eea;border:none;border-radius:6px;padding:6px 16px;font-size:13px;transition:background .2s}.add-model-form-actions .btn-primary:hover{background:#5a6fd6}.add-model-form-actions .btn-cancel{color:#666;cursor:pointer;white-space:nowrap;background:#f0f0f0;border:none;border-radius:6px;min-width:56px;padding:6px 16px;font-size:13px;transition:background .2s}.add-model-form-actions .btn-cancel:hover{background:#e0e0e0}.token-input-wrapper{align-items:center;display:flex;position:relative}.token-input-wrapper input{border:1px solid #e0e0e0;border-radius:8px;width:100%;padding:12px 45px 12px 12px;font-family:Consolas,Monaco,monospace;font-size:14px;transition:border-color .2s,box-shadow .2s}.token-input-wrapper input:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 3px #667eea26}.toggle-token-btn{cursor:pointer;color:#999;background:0 0;border:none;justify-content:center;align-items:center;padding:4px 8px;transition:color .2s;display:flex;position:absolute;right:8px}.toggle-token-btn:hover{color:#667eea}.tools-config{border-top:2px solid #e0e0e0;margin-top:30px;padding-top:20px}.tools-config h2{color:#667eea;margin-bottom:10px;font-size:18px}.tools-config .subtitle{margin-bottom:20px}.tool-item{border:1px solid #e0e0e0;border-radius:8px;align-items:flex-start;gap:12px;margin-bottom:10px;padding:12px;transition:border-color .2s;display:flex}.tool-item:hover{border-color:#667eea}.tool-item input[type=checkbox]{cursor:pointer;accent-color:#667eea;width:18px;height:18px;margin-top:3px}.tool-item-content{flex:1}.tool-item-name{color:#333;margin-bottom:4px;font-weight:500}.tool-item-desc{color:#888;font-size:12px;line-height:1.4}.tool-item-name code{color:#667eea;background:#f0f0f0;border-radius:4px;padding:2px 6px;font-family:Consolas,Monaco,monospace;font-size:12px}.system-prompt-wrapper{position:relative}.reset-system-prompt-btn{cursor:pointer;color:#667eea;z-index:10;background:#667eea1a;border:none;border-radius:4px;justify-content:center;align-items:center;padding:6px 8px;transition:all .2s;display:flex;position:absolute;top:8px;right:8px}.reset-system-prompt-btn:hover{background:#667eea33}.react-config{margin-top:0}.react-config h2{color:#667eea;margin-bottom:10px;font-size:18px}.react-config .subtitle{margin-bottom:20px}.react-config-item{margin-bottom:15px}.react-config-item label{align-items:center;gap:8px;margin-bottom:5px;display:flex}.react-config-item .hint-text{color:#999;font-size:12px;font-weight:400}.react-config-item input[type=number]{border:1px solid #e0e0e0;border-radius:8px;width:100%;padding:10px;font-family:Consolas,Monaco,monospace;font-size:14px;transition:border-color .2s,box-shadow .2s}.react-config-item input[type=number]:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 3px #667eea26}.react-config-item .range-labels{color:#999;justify-content:space-between;margin-top:3px;font-size:11px;display:flex}.react-config-item .unit{color:#888;margin-left:4px;font-size:12px}.chat-config{border-top:2px solid #e0e0e0;margin-top:30px;padding-top:20px}.chat-config h2{color:#667eea;margin-bottom:10px;font-size:18px}.chat-config .subtitle{margin-bottom:20px}.chat-config-item{margin-bottom:15px}.chat-config-item label{align-items:center;gap:8px;margin-bottom:5px;display:flex}.chat-config-item .hint-text{color:#999;font-size:12px;font-weight:400}.chat-config-item input[type=number]{border:1px solid #e0e0e0;border-radius:8px;width:100%;padding:10px;font-family:Consolas,Monaco,monospace;font-size:14px;transition:border-color .2s,box-shadow .2s}.chat-config-item input[type=number]:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 3px #667eea26}.chat-config-item .range-labels{color:#999;justify-content:space-between;margin-top:3px;font-size:11px;display:flex}.chat-config-item .unit{color:#888;margin-left:4px;font-size:12px}.toggle-label{cursor:pointer;align-items:center;gap:10px;display:flex}.toggle-label input[type=checkbox]{appearance:none;cursor:pointer;background:#e0e0e0;border-radius:11px;width:40px;height:22px;transition:background .3s;position:relative}.toggle-label input[type=checkbox]:before{content:"";background:#fff;border-radius:50%;width:18px;height:18px;transition:transform .3s;position:absolute;top:2px;left:2px;box-shadow:0 2px 4px #0003}.toggle-label input[type=checkbox]:checked{background:#667eea}.toggle-label input[type=checkbox]:checked:before{transform:translate(18px)}.toggle-label .toggle-text{color:#333;font-weight:500}.toggle-label:has(input:disabled){cursor:not-allowed;opacity:.5}.toggle-label input[type=checkbox]:disabled{cursor:not-allowed}.toolbar-config{margin-top:0}.toolbar-config h2{color:#667eea;margin-bottom:10px;font-size:18px}.toolbar-config .subtitle{margin-bottom:20px}.toolbar-tools-list{margin-top:15px}.tool-item{background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;align-items:center;gap:10px;margin-bottom:8px;padding:10px 12px;transition:border-color .2s,background .2s;display:flex}.tool-item:hover{background:#f5f7ff;border-color:#667eea}.tool-item .tool-drag-handle{cursor:grab;color:#bbb;letter-spacing:-2px;-webkit-user-select:none;user-select:none;flex-shrink:0;align-items:center;padding:2px 4px;font-size:14px;display:flex}.tool-item .tool-drag-handle:active{cursor:grabbing}.tool-item.dragging{opacity:.4}.tool-item.drag-over{background:#edf0ff;border-color:#667eea}.tool-item .tool-order-btns{flex-direction:column;flex-shrink:0;gap:2px;display:flex}.tool-item .tool-order-btn{color:#999;cursor:pointer;background:0 0;border:none;border-radius:3px;justify-content:center;align-items:center;width:20px;height:16px;padding:0;font-size:10px;line-height:1;display:flex}.tool-item .tool-order-btn:hover{color:#333;background:#e0e0e0}.tool-item .tool-order-btn:disabled{opacity:.3;cursor:not-allowed}.tool-item .tool-info{flex:1;min-width:0}.tool-item .tool-name{color:#333;font-size:14px;font-weight:500}.tool-item .tool-badge{border-radius:4px;margin-left:6px;padding:1px 6px;font-size:11px;font-weight:400;display:inline-block}.tool-item .tool-badge.builtin{color:#667eea;background:#e8f0fe}.tool-item .tool-badge.custom{color:#92400e;background:#fef3c7}.tool-item .tool-prompt-preview{color:#888;white-space:nowrap;text-overflow:ellipsis;max-width:300px;margin-top:2px;font-size:12px;overflow:hidden}.tool-item .tool-actions{flex-shrink:0;gap:4px;display:flex}.tool-item .tool-action-btn{cursor:pointer;color:#888;background:0 0;border:none;border-radius:4px;padding:4px 8px;font-size:12px;transition:background .15s}.tool-item .tool-action-btn:hover{color:#333;background:#e0e0e0}.tool-item .tool-action-btn.danger:hover{color:#dc2626;background:#fee2e2}.btn-secondary{color:#555;cursor:pointer;background:#f0f0f0;border:1px dashed #ccc;border-radius:8px;padding:10px 20px;font-family:inherit;font-size:13px;transition:all .2s}.btn-secondary:hover{color:#667eea;background:#e8e8e8;border-color:#667eea}.btn-cancel{color:#555;cursor:pointer;background:#f0f0f0;border:none;border-radius:8px;padding:10px 20px;font-family:inherit;font-size:13px}.btn-cancel:hover{background:#e0e0e0}.domain-blocklist-section{border-top:2px solid #e0e0e0;margin-top:20px;padding-top:16px}.domain-blocklist-title{color:#667eea;margin-bottom:4px;font-size:15px}.domain-add-row{gap:8px;margin-top:12px;margin-bottom:12px;display:flex}.domain-add-input{border:1px solid #ccc;border-radius:8px;outline:none;flex:1;padding:8px 12px;font-family:inherit;font-size:13px;transition:border-color .2s}.domain-add-input:focus{border-color:#667eea}.domain-blocklist-list{max-height:200px;overflow-y:auto}.domain-blocklist-empty{text-align:center;color:#bbb;padding:16px;font-size:13px}.domain-blocklist-item{color:#333;background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;justify-content:space-between;align-items:center;margin-bottom:6px;padding:8px 12px;font-size:13px;transition:border-color .2s,background .2s;display:flex}.domain-blocklist-item:hover{background:#f5f7ff;border-color:#667eea}.domain-blocklist-item-name{text-overflow:ellipsis;white-space:nowrap;flex:1;margin-right:8px;overflow:hidden}.domain-blocklist-item-remove{color:#bbb;cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;padding:4px 8px;font-size:12px;transition:all .15s;display:flex}.domain-blocklist-item-remove:hover{color:#e53e3e;background:#fff5f5}.modal-overlay{z-index:10000;background:#00000080;justify-content:center;align-items:center;width:100%;height:100%;display:flex;position:fixed;top:0;left:0}.modal-content{background:#fff;border-radius:12px;width:90%;max-width:500px;padding:24px;box-shadow:0 8px 30px #0003}.modal-content h3{color:#333;margin-bottom:16px;font-size:16px}.modal-header{justify-content:space-between;align-items:center;margin-bottom:16px;display:flex}.modal-header h3{color:#333;margin-bottom:0;font-size:16px}.modal-close-btn{color:#999;cursor:pointer;background:0 0;border:none;border-radius:6px;justify-content:center;align-items:center;width:28px;height:28px;padding:0;font-size:16px;line-height:1;transition:all .15s;display:flex}.modal-close-btn:hover{color:#333;background:#f0f0f0}.modal-actions{justify-content:flex-end;gap:8px;margin-top:16px;display:flex}.modal-actions .btn{width:auto;padding:8px 24px}.modal-actions .btn-primary{color:#fff;background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);width:auto;padding:8px 24px}.modal-actions .btn-secondary{width:auto;padding:8px 24px}.import-tabs{border-bottom:2px solid #e8eaed;gap:4px;margin-bottom:20px;padding:0 2px;display:flex}.import-tab{color:#999;cursor:pointer;background:0 0;border:none;border-bottom:2px solid #0000;border-radius:6px 6px 0 0;margin-bottom:-2px;padding:8px 16px;font-family:inherit;font-size:13px;transition:all .2s}.import-tab:hover{color:#555;background:#f5f7fa}.import-tab.active{color:#667eea;background:#f5f7ff;border-bottom-color:#667eea;font-weight:600}.import-panel{display:none}.import-panel.active{display:block}.import-panel-desc{color:#999;margin-bottom:16px;font-size:13px;line-height:1.5}.upload-drop-zone{text-align:center;cursor:pointer;background:#fafbfc;border:2px dashed #d0d5dd;border-radius:10px;padding:28px 20px;transition:all .2s}.upload-drop-zone:hover{background:#f5f7ff;border-color:#667eea}.upload-drop-zone.has-file{background:#f0fff4;border-style:solid;border-color:#38a169}.upload-drop-zone .upload-icon{margin-bottom:8px;font-size:32px;display:block}.upload-drop-zone .upload-text{color:#666;font-size:13px}.upload-drop-zone .upload-hint{color:#aaa;margin-top:4px;font-size:11px}.upload-drop-zone .file-name{color:#38a169;margin-top:4px;font-size:13px;font-weight:500}.upload-drop-zone input[type=file]{display:none}.url-input-wrapper{align-items:center;display:flex;position:relative}.url-input-wrapper .url-input-icon{z-index:1;pointer-events:none;font-size:14px;position:absolute;left:12px}.url-input-wrapper input[type=url]{padding-left:34px}.agent-skill-editor-container{flex-direction:column;max-height:85vh;display:flex;overflow:hidden}.agent-skill-editor-container .modal-body{flex:1;margin-bottom:16px;padding-right:4px;overflow-y:auto}.agent-skill-editor-container .modal-header{justify-content:center;position:relative}.agent-skill-editor-container .modal-header .modal-close-btn{position:absolute;top:-4px;right:-4px}.skill-resource-list{flex-wrap:wrap;gap:6px;display:flex}.skill-resource-tag{color:#555;background:#f0f4ff;border:1px solid #d4dafc;border-radius:4px;padding:4px 10px;font-family:monospace;font-size:12px;display:inline-block}.skill-section-title{color:#999;text-transform:uppercase;letter-spacing:.5px;padding:16px 0 8px;font-size:13px;font-weight:600}.skill-section-title:first-child{padding-top:0}.skill-card-badge{border-radius:3px;padding:1px 6px;font-size:11px;font-weight:500;display:inline-block}.badge-workflow{color:#667eea;background:#f0f4ff}.badge-agent{color:#38a169;background:#f0fff4}.badge-disabled{color:#d97706;background:#fef3c7}.badge-builtin{color:#7c3aed;background:#ede9fe}.skill-card-workflow{border-left:3px solid #667eea}.skill-card-agent{border-left:3px solid #38a169}.skill-card.skill-disabled{opacity:.6;background:#fafafa;border-left-color:#999}.skill-card-body.disabled{opacity:.6}.skill-card-body.disabled .skill-card-desc,.skill-card-body.disabled .skill-card-params{display:none}.skill-card.skill-disabled .skill-card-name{color:#999}.param-required{color:#e53e3e;font-size:11px;font-weight:500}.param-optional{color:#999;font-size:11px}.skill-run-summary{color:#666;background:#f8f9fa;border-radius:6px;margin-bottom:12px;padding:10px 14px;font-size:13px}.skill-run-step{border:1px solid #e0e0e0;border-radius:6px;margin-bottom:8px;overflow:hidden}.skill-run-step.step-success{border-left:3px solid #38a169}.skill-run-step.step-error{border-left:3px solid #e53e3e}.skill-run-step.step-skipped{opacity:.7;border-left:3px solid #ccc}.skill-run-step .step-header{background:#fafafa;border-bottom:1px solid #eee;align-items:center;gap:8px;padding:8px 12px;display:flex}.skill-run-step .step-status-icon{text-align:center;width:20px;font-size:14px;font-weight:700}.step-success .step-status-icon{color:#38a169}.step-error .step-status-icon{color:#e53e3e}.step-skipped .step-status-icon{color:#999}.skill-run-step .step-title{flex:1;font-size:13px;font-weight:500}.skill-run-step .step-tool-tag{color:#4a5568;background:#edf2f7;border-radius:3px;padding:1px 6px;font-family:Consolas,Monaco,monospace;font-size:11px}.skill-run-step .step-output{white-space:pre-wrap;word-break:break-all;color:#333;background:#fff;max-height:200px;margin:0;padding:10px 12px;font-family:Consolas,Monaco,monospace;font-size:12px;line-height:1.5;overflow-y:auto}#toolbarMaxVisible{border:1px solid #e0e0e0;border-radius:8px;width:100%;padding:10px;font-family:Consolas,Monaco,monospace;font-size:14px;transition:border-color .2s,box-shadow .2s}#toolbarMaxVisible:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 3px #667eea26}.tab-nav{border-bottom:2px solid #e0e0e0;gap:2px;margin-bottom:24px;padding-bottom:0;display:flex}.tab-nav-btn{color:#888;cursor:pointer;white-space:nowrap;text-overflow:ellipsis;background:0 0;border:none;border-bottom:2px solid #0000;border-radius:8px 8px 0 0;flex:auto;min-width:0;margin-bottom:-2px;padding:10px 6px;font-family:inherit;font-size:14px;transition:all .2s;overflow:hidden}.tab-nav-btn:hover{color:#555;background:#f5f5f5}.tab-nav-btn.active{color:#667eea;border-bottom-color:#667eea;font-weight:500}.tab-panel{display:none}.tab-panel.active{display:block}@media (width<=640px){.tab-nav-btn{padding:10px 3px;font-size:13px}}.reflection-config{margin-top:0}.reflection-config h2{color:#667eea;margin-bottom:10px;font-size:18px}.reflection-config .subtitle{margin-bottom:20px}.reflection-section{background:#fafafa;border:1px solid #e0e0e0;border-radius:10px;margin-bottom:16px;padding:16px}.reflection-toggles{background:#fafafa;border:1px solid #e0e0e0;border-radius:10px;overflow:hidden}.reflection-toggle-row{align-items:center;gap:10px;padding:12px 16px;transition:background .15s;display:flex}.reflection-toggle-row+.reflection-toggle-row{border-top:1px solid #eee}.reflection-toggle-row:hover{background:#f5f5f5}.reflection-row-icon{flex-shrink:0;font-size:16px}.reflection-row-text{color:#333;flex:1;font-size:14px;font-weight:500}.reflection-row-hint{color:#999;margin-left:6px;font-size:12px;font-weight:400}.reflection-toggle-row.disabled{opacity:.45}.reflection-toggle-row.disabled .reflection-row-text{color:#999}.reflection-section-header{justify-content:space-between;align-items:center;padding-bottom:8px;display:flex}.reflection-section-title{color:#333;align-items:center;gap:6px;font-size:14px;font-weight:600;display:flex}.reflection-section-toggle{align-items:center;gap:6px;display:flex}.reflection-section-toggle label{margin-bottom:0}.reflection-config-item{margin-bottom:12px}.reflection-config-item:last-child{margin-bottom:0}.reflection-config-item label{color:#555;align-items:center;gap:8px;margin-bottom:4px;font-size:13px;font-weight:500;display:flex}.reflection-config-item .hint-text{color:#999;font-size:11px;font-weight:400}.reflection-config-item input[type=number],.reflection-config-item input[type=text]{border:1px solid #e0e0e0;border-radius:6px;width:100%;padding:8px 10px;font-family:Consolas,Monaco,monospace;font-size:13px;transition:border-color .2s}.reflection-config-item input[type=number]:focus,.reflection-config-item input[type=text]:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 2px #667eea1a}.reflection-config-item .unit{color:#888;margin-left:4px;font-size:11px}.reflection-config-item .range-labels{color:#999;justify-content:space-between;margin-top:2px;font-size:10px;display:flex}.reflection-section.collapsible{cursor:pointer}.reflection-section.collapsible .reflection-section-header:hover{background:#667eea0d;border-radius:6px}.reflection-section.collapsed .reflection-section-content{display:none}.reflection-section-icon{margin-right:4px;font-size:12px;transition:transform .2s;display:inline-block}.reflection-section.collapsed .reflection-section-icon{transform:rotate(-90deg)}.reflection-section.disabled{opacity:.5}.reflection-section.disabled .reflection-section-content{display:none}.reflection-title-row{justify-content:space-between;align-items:center;margin-bottom:4px;display:flex}.reflection-title-row h2{color:#667eea;margin:0;font-size:18px}.toolbar-title-row{justify-content:space-between;align-items:center;margin-bottom:4px;display:flex}.toolbar-title-row h2{color:#667eea;margin:0;font-size:18px}.reflection-config.disabled{opacity:.6}.reflection-config.disabled .reflection-section,.reflection-config.disabled .reflection-toggles,.toolbar-config.disabled .toolbar-config-body{display:none}.toolbar-config.disabled .subtitle,.toolbar-config.disabled .hint{opacity:.4}.reflection-toggle-switch{width:36px;height:20px;display:inline-block;position:relative}.reflection-toggle-switch input{opacity:0;width:0;height:0}.reflection-toggle-slider{cursor:pointer;background-color:#ccc;border-radius:20px;transition:all .3s;position:absolute;inset:0}.reflection-toggle-slider:before{content:"";background-color:#fff;border-radius:50%;width:16px;height:16px;transition:all .3s;position:absolute;bottom:2px;left:2px}.reflection-toggle-switch input:checked+.reflection-toggle-slider{background-color:#667eea}.reflection-toggle-switch input:focus+.reflection-toggle-slider{box-shadow:0 0 1px #667eea}.reflection-toggle-switch input:checked+.reflection-toggle-slider:before{transform:translate(16px)}.reflection-toggle-text{color:#666;font-size:12px;font-weight:500}.reflection-main-toggle{background:linear-gradient(135deg,#f0f4ff 0%,#e8eefd 100%);border:1px solid #d0d9f0;border-radius:10px;justify-content:space-between;align-items:center;margin-bottom:16px;padding:12px 16px;display:flex}.reflection-main-toggle label{color:#333;cursor:pointer;align-items:center;gap:8px;margin-bottom:0;font-weight:600;display:flex}.agent-config{margin-top:0}.agent-config h2{color:#667eea;margin-bottom:10px;font-size:18px}.agent-config .subtitle{margin-bottom:20px}.agent-status{border-radius:8px;align-items:center;gap:8px;margin-bottom:20px;padding:12px 16px;font-size:14px;font-weight:500;display:flex}.agent-status-row{align-items:center;gap:12px;margin-bottom:20px;display:flex}.agent-status-row .agent-status{flex:1;margin-bottom:0}.agent-status-row #disconnectGroup{flex-shrink:0;margin-bottom:0}.agent-status.connected{color:#38a169;background:#f0fff4;border:1px solid #c6f6d5}.agent-status.disconnected{color:#e53e3e;background:#fff5f5;border:1px solid #fed7d7}.agent-status.checking{color:#d69e2e;background:#fffbeb;border:1px solid #fef3c7}.agent-status-dot{background:currentColor;border-radius:50%;flex-shrink:0;width:10px;height:10px}.agent-info{color:#4a5568;background:#f0f4ff;border:1px solid #d0d9f0;border-radius:8px;margin-bottom:16px;padding:10px 14px;font-size:13px}.agent-detail-toggle{color:#718096;cursor:pointer;text-align:left;background:0 0;border:1px dashed #cbd5e0;border-radius:6px;width:100%;margin-bottom:8px;padding:8px 14px;font-size:13px;transition:all .2s}.agent-detail-toggle:hover{color:#4a5568;background:#f7fafc;border-color:#a0aec0}.agent-detail-toggle.open{border-bottom:none;border-bottom-right-radius:0;border-bottom-left-radius:0;margin-bottom:0}.agent-detail-panel{color:#4a5568;background:#fafafa;border:1px dashed #cbd5e0;border-top:none;border-radius:0 0 6px 6px;margin-bottom:16px;padding:12px 14px;font-size:13px;display:none}.detail-row{border-bottom:1px solid #f0f0f0;padding:5px 0;display:flex}.detail-row:last-child{border-bottom:none}.detail-label{color:#a0aec0;flex:0 0 120px;font-weight:500}.detail-value{word-break:break-all;flex:1;line-height:1.6}.detail-value code{background:#edf2f7;border-radius:3px;padding:1px 6px;font-size:12px}.paired-agents-section{margin-bottom:20px}.paired-agents-section h3{color:#667eea;margin-bottom:10px;font-size:14px}.paired-agents-list{flex-direction:column;gap:8px;display:flex}.paired-agent-item{background:#fafafa;border:1px solid #e8e8e8;border-radius:8px;align-items:center;gap:10px;padding:10px 14px;transition:all .2s;display:flex}.paired-agent-item:hover{background:#f5f6ff;border-color:#667eea}.paired-agent-item.active{background:#f0f4ff;border-color:#667eea;flex-wrap:wrap}.paired-agent-item.active>#agentDetailArea{border-top:1px dashed #cbd5e0;flex-basis:100%;width:100%;margin-top:6px;padding-top:8px}.paired-agent-item.active>#agentDetailArea .agent-status-row{margin-bottom:8px}.paired-agent-item.active>#agentDetailArea .agent-status{margin-bottom:0;padding:8px 12px;font-size:13px}.paired-agent-item.active>#agentDetailArea .agent-info{margin-bottom:8px;padding:6px 10px;font-size:12px}.paired-agent-item.active>#agentDetailArea .agent-detail-toggle{margin-bottom:6px;padding:6px 10px;font-size:12px}.paired-agent-item.active>#agentDetailArea .agent-detail-panel{margin-bottom:0;font-size:12px}.paired-agent-dot{border-radius:50%;flex-shrink:0;width:12px;height:12px;transition:all .2s}.paired-agent-dot.online{background:0 0;border:2.5px solid #48bb78}.paired-agent-dot.offline{background:0 0;border:2.5px solid #cbd5e0}.paired-agent-dot.checking{background:0 0;border:2.5px solid #ecc94b}.paired-agent-dot.active-online{background:#48bb78;box-shadow:0 0 0 3px #48bb7833}.paired-agent-dot.active-offline{background:#cbd5e0;box-shadow:0 0 0 3px #cbd5e04d}.paired-agent-dot.active-checking{background:#ecc94b;box-shadow:0 0 0 3px #ecc94b33}.paired-agent-name{color:#2d3748;white-space:nowrap;text-overflow:ellipsis;cursor:text;border-radius:4px;flex:1;padding:2px 4px;font-size:14px;font-weight:500;transition:background .15s;overflow:hidden}.paired-agent-name:hover{background:#667eea14}.paired-agent-url{color:#a0aec0;white-space:nowrap;text-overflow:ellipsis;max-width:200px;font-size:11px;overflow:hidden}.paired-agent-actions{flex-shrink:0;gap:6px;display:flex}.paired-agent-btn{color:#4a5568;cursor:pointer;background:#fff;border:1px solid #e2e8f0;border-radius:4px;padding:4px 12px;font-size:12px;transition:all .15s}.paired-agent-btn:hover{color:#fff;background:#667eea;border-color:#667eea}.paired-agent-btn.delete-btn{color:#e53e3e;background:#fff5f5;border-color:#fed7d7}.paired-agent-btn.delete-btn:hover{color:#fff;background:#e53e3e;border-color:#e53e3e}.paired-agent-btn.disconnect-btn{color:#e53e3e;background:#fff5f5;border-color:#fed7d7}.paired-agent-btn.disconnect-btn:hover{color:#fff;background:#e53e3e;border-color:#e53e3e}.paired-agent-status-text{flex-shrink:0;font-size:11px}.paired-agent-status-text.online{color:#48bb78}.paired-agent-status-text.connected{color:#48bb78;font-weight:600}.paired-agent-status-text.offline{color:#a0aec0}.paired-agent-status-text.disabled{color:#a0aec0;font-style:italic}.paired-agent-item.disabled{opacity:.6}.paired-agent-item.disabled .paired-agent-name{text-decoration:line-through}.paired-agent-dot.disabled{background:0 0;border:2.5px solid #a0aec0}.paired-agent-dot.active-disabled{background:#a0aec0;box-shadow:0 0 0 3px #a0aec033}.paired-agent-btn.disable-btn{color:#718096;background:#f7fafc;border-color:#e2e8f0}.paired-agent-btn.disable-btn:hover{color:#4a5568;background:#edf2f7;border-color:#cbd5e0}.paired-agent-btn.enable-btn{color:#2b6cb0;background:#ebf8ff;border-color:#bee3f8}.paired-agent-btn.enable-btn:hover{color:#fff;background:#3182ce;border-color:#3182ce}.add-agent-section{border-top:1px solid #e8e8e8;margin-top:4px;padding-top:16px}.add-agent-section h3{color:#667eea;margin-bottom:12px;font-size:14px}.toolbox-agent-status{border-radius:8px;align-items:center;gap:8px;margin-bottom:20px;padding:10px 14px;font-size:13px;font-weight:500;display:flex}.toolbox-agent-status.connected{color:#38a169;background:#f0fff4;border:1px solid #c6f6d5}.toolbox-agent-status.disconnected{color:#e53e3e;background:#fff5f5;border:1px solid #fed7d7}.toolbox-status-dot{border-radius:50%;flex-shrink:0;width:8px;height:8px}.toolbox-status-dot.connected{background:#38a169}.toolbox-status-dot.disconnected{background:#e53e3e}.toolbox-section{margin-bottom:24px}.toolbox-section-header{margin-bottom:12px}.toolbox-section-title-row{justify-content:space-between;align-items:center;margin-bottom:4px;display:flex}.toolbox-section-title{color:#667eea;margin:0;font-size:16px}.toolbox-tool-count{color:#888;white-space:nowrap;background:#f0f4ff;border-radius:10px;margin-left:10px;padding:2px 8px;font-size:12px}.toolbox-section-desc{color:#999;font-size:12px}.global-toggle{cursor:pointer;-webkit-user-select:none;user-select:none;flex-shrink:0;align-items:center;gap:8px;display:flex}.global-toggle input{display:none}.global-toggle-slider{background:#ccc;border-radius:11px;width:40px;height:22px;transition:background .2s;position:relative}.global-toggle-slider:after{content:"";background:#fff;border-radius:50%;width:18px;height:18px;transition:transform .2s;position:absolute;top:2px;left:2px}.global-toggle input:checked+.global-toggle-slider{background:#667eea}.global-toggle input:checked+.global-toggle-slider:after{transform:translate(18px)}.global-toggle-label{color:#666;min-width:48px;font-size:13px}.toolbox-section-content{opacity:0;max-height:0;transition:max-height .3s ease-out,opacity .3s ease-out;overflow:hidden}.toolbox-filter-bar{align-items:center;gap:8px;margin-bottom:8px;display:flex}.toolbox-search-input{border:1px solid #d0d5dd;border-radius:6px;outline:none;flex:1;width:100%;padding:6px 28px 6px 10px;font-size:13px;transition:border-color .2s}.toolbox-search-input:focus{border-color:#667eea}.toolbox-search-wrapper{flex:1;position:relative}.toolbox-search-clear{cursor:pointer;color:#999;background:0 0;border:none;border-radius:3px;padding:2px 4px;font-size:12px;line-height:1;display:none;position:absolute;top:50%;right:6px;transform:translateY(-50%)}.toolbox-search-clear:hover{color:#e53e3e;background:#e53e3e14}.toolbox-search-wrapper:has(.toolbox-search-input:not(:placeholder-shown)) .toolbox-search-clear{display:block}.toolbox-filter-tabs{flex-shrink:0;gap:4px;display:flex}.toolbox-filter-tab{color:#666;cursor:pointer;background:#fff;border:1px solid #d0d5dd;border-radius:6px;padding:4px 10px;font-size:12px;transition:all .2s}.toolbox-filter-tab:hover{color:#667eea;border-color:#667eea}.toolbox-filter-tab.active{color:#fff;background:#667eea;border-color:#667eea}.toolbox-list{max-height:400px;padding-right:4px;overflow-y:auto}.toolbox-list::-webkit-scrollbar{width:6px}.toolbox-list::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.toolbox-list::-webkit-scrollbar-thumb{background:#ccc;border-radius:3px}.toolbox-list::-webkit-scrollbar-thumb:hover{background:#999}.toolbox-section:not(.disabled-section) .toolbox-section-content{opacity:1;max-height:2000px}.toolbox-section.disabled-section .toolbox-section-content{opacity:0;pointer-events:none;max-height:0}.toolbox-empty{text-align:center;color:#999;padding:32px 16px}.toolbox-empty-icon{margin-bottom:10px;font-size:36px}.toolbox-empty-title{color:#666;margin-bottom:6px;font-size:14px;font-weight:500}.toolbox-empty-desc{color:#aaa;font-size:12px}.mcp-server-card{background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;margin-bottom:8px;padding:12px 14px;transition:border-color .2s,background .2s}.mcp-server-card:hover{background:#f5f7ff;border-color:#667eea}.mcp-server-card.disabled{opacity:.55}.mcp-card-body.disabled{display:none}.mcp-server-card.editing{background:#f8f9fc;border-color:#667eea}.mcp-server-card.editing .mcp-add-form{background:0 0;border:none;margin-top:0;padding:0}.mcp-server-header{justify-content:space-between;align-items:center;margin-bottom:6px;display:flex}.mcp-server-info{align-items:center;gap:8px;font-size:14px;font-weight:500;display:flex}.mcp-server-header-right{align-items:center;gap:12px;display:flex}.mcp-server-status{font-size:12px}.mcp-server-name{color:#333}.mcp-server-badge{color:#667eea;background:#e8f0fe;border-radius:4px;padding:1px 8px;font-size:11px;font-weight:400}.mcp-server-tools-count{color:#888;font-size:12px}.mcp-server-command{margin-bottom:4px}.mcp-server-command code{color:#555;word-break:break-all;background:#edf2f7;border-radius:4px;padding:2px 8px;font-size:12px}.mcp-server-meta{color:#999;margin-bottom:6px;font-size:11px}.mcp-tools-section{margin-bottom:10px}.mcp-tools-toggle{color:#667eea;cursor:pointer;background:0 0;border:none;padding:2px 0;font-family:inherit;font-size:12px}.mcp-tools-toggle:hover{color:#5a6fd6;text-decoration:underline}.mcp-tools-list{border-top:1px solid #eee;margin-top:6px;padding-top:6px}.mcp-tool-item{border-left:2px solid #e8ecf4;margin-bottom:4px;padding:4px 0 4px 14px}.mcp-tool-name{color:#333;font-family:Consolas,Monaco,monospace;font-size:13px;font-weight:500}.mcp-tool-desc{color:#999;margin-top:2px;font-size:11px}.mcp-server-actions{align-items:center;gap:6px;display:flex}.skill-card{background:#fafafa;border:1px solid #e0e0e0;border-radius:8px;margin-bottom:8px;padding:12px 14px;transition:border-color .2s,background .2s}.skill-card:hover{background:#f5f7ff;border-color:#667eea}.skill-card-header{justify-content:space-between;align-items:center;margin-bottom:6px;display:flex}.skill-card-info{align-items:center;gap:8px;font-size:14px;display:flex}.skill-card-icon{font-size:16px}.skill-card-name{color:#333;font-weight:500}.skill-card-version{color:#888;background:#f0f0f0;border-radius:4px;padding:1px 6px;font-size:11px}.skill-card-step-count{color:#667eea;background:#e8f0fe;border-radius:4px;padding:1px 6px;font-size:11px}.skill-card-desc{color:#666;margin-bottom:8px;font-size:13px;line-height:1.5}.skill-card-params{flex-wrap:wrap;gap:4px;margin-bottom:10px;display:flex}.skill-param-tag{color:#92400e;background:#fef3c7;border-radius:4px;padding:1px 8px;font-family:Consolas,Monaco,monospace;font-size:11px}.skill-param-tag.required{color:#b91c1c;background:#fee2e2}.skill-param-tag.skill-more-tag{color:#64748b;background:#e2e8f0;font-style:italic}.skill-expand-btn{color:#667eea;cursor:pointer;background:0 0;border:none;margin-bottom:8px;padding:2px 0;font-family:inherit;font-size:12px;transition:color .2s}.skill-expand-btn:hover{color:#5a6fd6;text-decoration:underline}.skill-expand-btn.skill-expand-resources{color:#64748b;background:#e2e8f0;border-radius:4px;margin-bottom:0;padding:1px 8px;font-family:Consolas,Monaco,monospace;display:inline-block}.skill-expand-btn.skill-expand-resources:hover{color:#475569;background:#cbd5e1;text-decoration:none}.skill-card-actions{gap:6px;display:flex}.toolbox-btn{cursor:pointer;border:none;border-radius:4px;padding:4px 12px;font-family:inherit;font-size:12px;transition:all .2s}.toolbox-btn:disabled{opacity:.5;cursor:not-allowed}.toolbox-btn-primary{color:#fff;background:#667eea}.toolbox-btn-primary:hover:not(:disabled){background:#5a6fd6}.toolbox-btn-warn{color:#fff;background:#ed8936}.toolbox-btn-warn:hover:not(:disabled){background:#dd6b20}.toolbox-btn-danger{color:#e53e3e;background:0 0;border:1px solid #0000}.toolbox-btn-danger:hover:not(:disabled){background:#fff5f5;border-color:#fed7d7}.toolbox-btn-edit{color:#667eea;background:#f0f4ff;border:1px solid #d4dafc}.toolbox-btn-edit:hover:not(:disabled){background:#e0e7ff}.toolbox-btn-cancel{color:#666;background:#f0f0f0}.toolbox-btn-cancel:hover{background:#e0e0e0}.toolbox-add-btn{color:#888;cursor:pointer;background:0 0;border:1px dashed #ccc;border-radius:8px;width:100%;margin-top:8px;padding:10px 16px;font-family:inherit;font-size:13px;transition:all .2s}.toolbox-add-btn:hover:not(:disabled){color:#667eea;background:#f0f4ff;border-color:#667eea}.toolbox-add-btn:disabled{opacity:.4;cursor:not-allowed}.toolbox-section-actions{gap:8px;margin-top:8px;display:flex}.toolbox-section-actions .toolbox-add-btn{flex:1;margin-top:0}.toolbox-toggle{cursor:pointer;width:36px;height:20px;margin-right:auto;display:inline-block;position:relative}.toolbox-toggle input{opacity:0;width:0;height:0}.toolbox-toggle-slider{background:#ccc;border-radius:20px;transition:background .3s;position:absolute;inset:0}.toolbox-toggle-slider:before{content:"";background:#fff;border-radius:50%;width:16px;height:16px;transition:transform .3s;position:absolute;bottom:2px;left:2px;box-shadow:0 1px 3px #0003}.toolbox-toggle input:checked+.toolbox-toggle-slider{background:#667eea}.toolbox-toggle input:checked+.toolbox-toggle-slider:before{transform:translate(16px)}.mcp-add-form{background:#f8f9fc;border:1px solid #e8ecf4;border-radius:8px;margin-top:8px;padding:12px}.mcp-add-form-row{gap:8px;margin-bottom:8px;display:flex}.mcp-transport-group{background:#f0f2f5;border-radius:8px;gap:0;margin-bottom:8px;padding:3px;display:flex}.mcp-transport-btn{color:#666;cursor:pointer;white-space:nowrap;background:0 0;border:none;border-radius:6px;flex:1;padding:7px 12px;font-family:inherit;font-size:13px;transition:all .2s}.mcp-transport-btn:hover{color:#333;background:#667eea14}.mcp-transport-btn.active{color:#667eea;background:#fff;font-weight:500;box-shadow:0 1px 3px #0000001a}.mcp-add-form-actions{justify-content:flex-end;gap:8px;display:flex}.mcp-env-section{margin-bottom:8px}.mcp-env-header{align-items:baseline;gap:6px;margin-bottom:6px;display:flex}.mcp-env-title{color:#333;font-size:13px;font-weight:500}.mcp-env-hint{color:#999;font-size:11px}.mcp-env-rows{flex-direction:column;gap:4px;margin-bottom:4px;display:flex}.mcp-env-row{align-items:center;gap:4px;display:flex}.mcp-env-row .mcp-env-key{border-radius:6px;padding:8px 10px;font-size:13px}.mcp-env-row .mcp-env-value{border-radius:6px;padding:8px 40px 8px 10px;font-family:inherit;font-size:13px}.mcp-env-value-wrap.token-input-wrapper{flex:2}.mcp-env-add-row{color:#667eea!important;background:0 0!important;border:1px dashed #667eea!important;padding:2px 10px!important;font-size:12px!important}.mcp-env-add-row:hover{background:#667eea0d!important}.toolbox-input{border:1px solid #e0e0e0;border-radius:6px;flex:1;min-width:0;padding:8px 10px;font-family:inherit;font-size:13px;transition:border-color .2s}.toolbox-input:focus{border-color:#667eea;outline:none;box-shadow:0 0 0 2px #667eea1a}.knowledge-header{justify-content:space-between;align-items:center;gap:12px;margin-bottom:16px;display:flex}.knowledge-title-row{align-items:center;gap:10px;min-width:0;display:flex}.knowledge-title{color:#333;margin:0;font-size:18px}.knowledge-list{grid-template-columns:repeat(auto-fill,minmax(280px,1fr));gap:14px;display:grid}.kb-card{background:#fff;border:1px solid #e5e7eb;border-radius:10px;flex-direction:column;gap:8px;padding:16px;transition:box-shadow .15s,border-color .15s;display:flex}.kb-card:hover{border-color:#d5d9f0;box-shadow:0 2px 12px #667eea14}.kb-card-title{color:#333;align-items:center;gap:8px;min-width:0;font-size:15px;font-weight:600;display:flex}.kb-card-name{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.kb-card-desc{color:#888;-webkit-line-clamp:2;-webkit-box-orient:vertical;font-size:12px;line-height:1.5;display:-webkit-box;overflow:hidden}.kb-card-meta{color:#667eea;font-size:12px;font-weight:500}.kb-card-model{color:#aaa;text-overflow:ellipsis;white-space:nowrap;font-size:11px;overflow:hidden}.kb-card.kb-card-disabled{opacity:.6;background:#fafafa}.kb-card-disabled .kb-card-name{color:#999}.kb-card-badge{border-radius:3px;flex-shrink:0;padding:1px 6px;font-size:10px;font-weight:500}.kb-card-actions{flex-wrap:wrap;gap:6px;margin-top:auto;padding-top:6px;display:flex}.kb-action-btn{color:#555;cursor:pointer;background:#fff;border:1px solid #e0e0e0;border-radius:6px;padding:5px 12px;font-family:inherit;font-size:12px;transition:all .15s}.kb-action-btn:hover{color:#667eea;background:#f5f7ff;border-color:#667eea}.kb-action-danger{color:#c0392b}.kb-action-danger:hover{color:#e74c3c;background:#fdf1f0;border-color:#e74c3c}.kb-modal{max-width:560px}.kb-modal-wide{max-width:680px}.kb-modal-body{max-height:62vh;overflow-y:auto}.kb-chunk-row{border-top:1px solid #f0f0f0;flex-wrap:wrap;align-items:center;gap:14px;margin-top:16px;padding-top:12px;display:flex}.kb-chunk-title{color:#555;font-size:13px;font-weight:600}.kb-chunk-inline{color:#666;align-items:center;gap:6px;margin-bottom:0;font-size:12px;font-weight:400;display:inline-flex}.kb-chunk-inline input[type=number]{border:1px solid #e0e0e0;border-radius:6px;width:76px;padding:5px 8px;font-family:inherit;font-size:12px}.kb-chunk-inline input[type=number]:focus{border-color:#667eea;outline:none}.kb-radio-row{flex-wrap:wrap;gap:16px;margin-top:6px;display:flex}.kb-radio-inline{color:#555;cursor:pointer;align-items:center;gap:6px;font-size:13px;display:inline-flex}.kb-radio-inline input[type=radio]{cursor:pointer;margin:0}.kb-vec-hint{color:#999;margin-top:6px;font-size:12px;line-height:1.6}.kb-vec-test-row{flex-wrap:wrap;align-items:center;gap:10px;margin-top:6px;display:flex}.kb-vec-test-row input[type=number]{border:1px solid #e0e0e0;border-radius:6px;width:110px;padding:5px 8px;font-family:inherit;font-size:12px}.kb-vec-test-row input[type=number]:focus{border-color:#667eea;outline:none}.kb-vec-test-result{color:#38a169;word-break:break-all;flex:100%;font-size:12px}.kb-status{color:#667eea;background:#f5f7ff;border:1px solid #dfe5fb;border-radius:8px;margin-top:12px;padding:10px 12px;font-size:12px;line-height:1.6}.kb-doc-list{flex-direction:column;gap:6px;display:flex}.kb-doc-row{background:#fafbfc;border:1px solid #f0f0f0;border-radius:8px;align-items:center;gap:10px;padding:10px 12px;display:flex}.kb-doc-row:hover{background:#f8f9ff;border-color:#e0e4f5}.kb-doc-info{flex:1;min-width:0}.kb-doc-name{color:#333;text-overflow:ellipsis;white-space:nowrap;font-size:13px;font-weight:500;overflow:hidden}.kb-doc-meta{color:#999;margin-top:2px;font-size:11px}.kb-doc-del{color:#bbb;cursor:pointer;background:0 0;border:none;border-radius:6px;flex:none;width:26px;height:26px;font-size:13px;line-height:1;transition:all .15s}.kb-doc-del:hover{color:#e74c3c;background:#fdf1f0}.kb-search-scope{color:#888;margin-bottom:10px;font-size:12px}.kb-search-bar{gap:8px;display:flex}.kb-search-bar input{flex:1;min-width:0}.kb-search-opts{flex-wrap:wrap;gap:14px;margin-top:10px;display:flex}.kb-hit-count{color:#666;margin-top:14px;font-size:12px;font-weight:600}.kb-fallback-hint{color:#b7791f;background:#fdf6ec;border:1px solid #f5e1c0;border-radius:8px;margin-top:12px;padding:8px 12px;font-size:12px;line-height:1.6}.kb-hit-list{flex-direction:column;gap:10px;margin-top:10px;display:flex}.kb-hit{background:#fafbfc;border:1px solid #f0f0f0;border-radius:8px;padding:12px}.kb-hit-head{align-items:center;gap:8px;min-width:0;margin-bottom:6px;display:flex}.kb-hit-score{color:#667eea;font-variant-numeric:tabular-nums;background:#eef1ff;border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:600}.kb-hit-doc{color:#888;text-overflow:ellipsis;white-space:nowrap;font-size:12px;overflow:hidden}.kb-hit-text{color:#444;word-break:break-word;font-size:13px;line-height:1.7}.kb-hit-collapsed{-webkit-line-clamp:4;cursor:pointer;-webkit-box-orient:vertical;display:-webkit-box;overflow:hidden}
@@ -1,100 +0,0 @@
1
- const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/agent-store-BFaBECYz.js","assets/rolldown-runtime-C0FnF6B9.js","assets/i18n-CohqPkkN.js"])))=>i.map(i=>d[i]);
2
- import{a as e,c as t,l as n}from"./i18n-CohqPkkN.js";e(`zh`,{tokenCounter:{truncatedMiddle:`
3
-
4
- ... [中间 {tokens} tokens 已截断] ...
5
-
6
- `,omittedTokens:`
7
-
8
- ... [省略 {tokens} tokens] ...
9
-
10
- `,omittedMiddleHtml:`
11
- <!-- 省略中间内容 -->
12
- `,truncated:`[截断]`,omittedKey:`...[省略]`,moreFields:`还有 {count} 个字段`,unknownTool:`未知工具`,userQuestion:`- 用户问题:{question}`,usedTools:`- 使用的工具:{tools}`,historySummary:`[历史摘要]`}}),e(`en`,{tokenCounter:{truncatedMiddle:`
13
-
14
- ... [middle {tokens} tokens truncated] ...
15
-
16
- `,omittedTokens:`
17
-
18
- ... [{tokens} tokens omitted] ...
19
-
20
- `,omittedMiddleHtml:`
21
- <!-- middle content omitted -->
22
- `,truncated:`[truncated]`,omittedKey:`...[omitted]`,moreFields:`{count} more fields`,unknownTool:`Unknown tool`,userQuestion:`- User question: {question}`,usedTools:`- Tools used: {tools}`,historySummary:`[History Summary]`}});var r=/[\u4e00-\u9fff\u3400-\u4dbf\uf900-\ufaff]/g,i=1.5,a=4,o=4,s=85,c=170,l=512;function u(e){if(!e)return s;let t=Number(e.width),n=Number(e.height);if(t>0&&n>0)return s+c*(Math.ceil(t/l)*Math.ceil(n/l));let r=e.url||``,i=(r.split(`,`)[1]||r).length*3/4;return Math.max(s,Math.ceil(i/65))}var d=1,f=0,p=3,ee=.3,te=3;function ne(e,t){if(!t||t<=0||!e||e<=0)return;let r=t/e;if(r<ee||r>te){n.warn(`[TokenCounter] calibration ratioexception,ignore: estimated=${e}, actual=${t}, ratio=${r.toFixed(3)}`);return}f++;let i=Math.min(.3,1/f),a=d;d=d*(1-i)+r*i,n.debug(`[TokenCounter] Tokencalibration update: ratio=${r.toFixed(3)}, alpha=${i.toFixed(3)}, old=${a.toFixed(3)} → new=${d.toFixed(3)}, samples=${f}`)}function re(e){return f<p||d<=0?e:Math.ceil(e*d)}function ie(){return{factor:d,samples:f,active:f>=p}}function m(e){if(!e||typeof e!=`string`)return 0;let t=e.match(r),n=t?t.length:0,o=e.length-n;return Math.ceil(n/i+o/a)}function h(e){return!e||e.length===0?0:e.reduce((e,t)=>{let n=0;if(typeof t.content==`string`)n=m(t.content);else if(Array.isArray(t.content))for(let e of t.content)e&&(e.type===`text`?n+=m(e.text||``):e.type===`image_url`&&e.image_url?n+=u(e.image_url):n+=m(JSON.stringify(e)));else t.content&&(n=m(JSON.stringify(t.content)));let r=``;return t.tool_calls&&(r+=JSON.stringify(t.tool_calls)),t.tool_call_id&&(r+=t.tool_call_id),t.reasoning_content&&(r+=t.reasoning_content),r&&(n+=m(r)),e+n+o},0)}function g(e,n){if(!e||typeof e!=`string`)return e;let r=m(e);if(r<=n)return e;let i=Math.floor(n*.7),o=n-i,s=Math.floor(i*a),c=Math.floor(o*a),l=e.slice(0,s),u=e.slice(-c),d=r-n;return l+t(`tokenCounter.truncatedMiddle`,{tokens:d})+u}function ae(e,n,r){if(!e||typeof e!=`string`||m(e)<=n)return e;if(!r){let t=e.trim();r=t.startsWith(`{`)||t.startsWith(`[`)?`json`:/<(!DOCTYPE|html|head|body)[\s>]/i.test(t.substring(0,200))?`html`:`text`}if(r===`html`)return oe(e,n);if(r===`json`)return se(e,n);let i=Math.floor(n*.6*a),o=Math.floor(n*.2*a),s=e.slice(0,i),c=e.slice(-o);return s+t(`tokenCounter.omittedTokens`,{tokens:m(e)-n})+c}function oe(e,n){let r=e.match(/<body[\s>][\s\S]*<\/body>/i);if(r){let i=r[0];e.substring(0,e.indexOf(i));let o=Math.floor(n*.8),s=n-o,c=Math.floor(s*a),l=Math.floor(o*a);return e.slice(0,c)+i.slice(0,l)+t(`tokenCounter.omittedMiddleHtml`)+i.slice(-Math.floor(l*.3))+e.slice(-Math.floor(c*.3))}return g(e,n)}function se(e,n){try{let r=JSON.parse(e);if(typeof r!=`object`||!r)return g(e,n);let i={},o=Object.keys(r),s=Math.min(o.length,30);for(let e=0;e<s;e++){let n=o[e],a=r[n];i[n]=typeof a==`string`&&a.length>200?a.substring(0,200)+`...`+t(`tokenCounter.truncated`):typeof a==`object`&&a?`[${Array.isArray(a)?`Array(${a.length})`:`Object(${Object.keys(a).length} keys)`}]`:a}o.length>s&&(i[`...[省略]`]=`还有 ${o.length-s} 个字段`);let c=JSON.stringify(i,null,2);return m(c)>n&&(c=c.substring(0,Math.floor(n*a))),c}catch{return g(e,n)}}var _={"deepseek-v4-pro":128e3,"deepseek-v3":128e3,"deepseek-chat":64e3,"deepseek-reasoner":64e3,"gpt-4o":128e3,"gpt-4o-mini":128e3,"gpt-4-turbo":128e3,"gpt-4":8192,"gpt-3.5-turbo":16385,"claude-3.5-sonnet":2e5,"claude-3-opus":2e5,"claude-3-haiku":2e5,"claude-3-sonnet":2e5,default:256e3};function ce(e){let t=new Map;if(!e||!Array.isArray(e))return t;for(let n of e)typeof n!=`string`&&n&&typeof n==`object`&&n.name&&t.set(n.name,n.contextWindow||0);return t}function v(e,t,n){if(n&&n.has(e)){let t=n.get(e);if(t&&t>0)return t}return t&&t>0?t:_[e]||_.default}var le=2e3;function ue(e){return e*200}var de=4096;function fe(e,t=0,n,r){return v(e,n,r)-le-ue(t)-de}function pe(e,t){let n=e/t;return n<.7?{level:`safe`,ratio:n}:n<.9?{level:`warning`,ratio:n}:{level:`critical`,ratio:n}}function me(e,t,n={}){let{preserveSystem:r=!0,generateSummary:i=!0}=n,a=e.length;if(h(e)<=t)return{messages:[...e],trimmedCount:0,summary:null};let o=r&&e[0]?.role===`system`?[e[0]]:[],s=o.length?[...e.slice(1)]:[...e],c=[];for(;s.length>0&&!(h([...o,...s])<=t);){let e=s.shift();if(c.push(e),e?.role===`assistant`&&e.tool_calls)for(;s.length>0&&s[0]?.role===`tool`;)c.push(s.shift())}let l=[...o,...s],u=i?he(c):null;return{messages:l,trimmedCount:a-l.length,summary:u}}function he(e){if(!e||e.length===0)return null;let n=[],r=[],i=[];for(let n of e)if(n.role===`user`){let e=typeof n.content==`string`?n.content:Array.isArray(n.content)?n.content.filter(e=>e.type===`text`).map(e=>e.text).join(``):``;if(e&&e.trim()){let t=e.replace(/\[选中内容\]\u000a[\s\S]*?\u000a\u000a\[用户问题\]\u000a/,``).replace(/\[引用内容\]\u000a[\s\S]*?\u000a\u000a\[用户问题\]\u000a/,``).replace(/\[选中内容摘要\]\u000a[\s\S]*?\u000a\u000a\[用户问题\]\u000a/,``).replace(/\[引用内容摘要\]\u000a[\s\S]*?\u000a\u000a\[用户问题\]\u000a/,``).trim().substring(0,80);t&&r.push(t)}}else if(n.role===`assistant`&&n.tool_calls)for(let e of n.tool_calls){let n=e.function?.name||e.name||t(`tokenCounter.unknownTool`);i.push(n)}if(r.length>0&&n.push(t(`tokenCounter.userQuestion`,{question:r[r.length-1]})),i.length>0){let e=[...new Set(i)].slice(0,10);n.push(t(`tokenCounter.usedTools`,{tools:e.join(`, `)}))}return n.length===0?null:t(`tokenCounter.historySummary`)+`
23
- `+n.join(`
24
- `)}function ge(e){return typeof e==`string`?e.replace(/[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g,`�`):e}var _e=new Set([`role`,`content`,`tool_calls`,`tool_call_id`,`name`,`reasoning_content`,`prefix`]);function ve(e){let t=e.map((e,t)=>{let r={};for(let t of _e)t in e&&(r[t]=e[t]);return Array.isArray(r.content)&&(r.content=r.content.map(e=>{if(e&&e.type===`image_url`&&e.image_url){let t={url:e.image_url.url};return e.image_url.width!=null&&(t.width=e.image_url.width),e.image_url.height!=null&&(t.height=e.image_url.height),{...e,image_url:t}}return e&&e.type===`text`&&typeof e.text==`string`?{...e,text:ge(e.text)}:e})),typeof r.content==`string`&&(r.content=ge(r.content)),r.role===`tool`?r.tool_call_id?r:(n.warn(`[Background] foundmessage ${t} missing tool_call_id,skipped`,e),null):(r.role===`assistant`&&Array.isArray(r.tool_calls)?r.tool_calls=r.tool_calls.map(e=>({id:e.id,type:e.type,function:e.function})):r.role===`assistant`&&r.tool_calls!==void 0&&(n.warn(`[Background] foundmessage ${t} tool_calls non-group (type: ${typeof r.tool_calls}),cleared`),delete r.tool_calls),r.role===`assistant`&&r.content===null&&(r.content=``),r)}).filter(e=>e!==null);for(let e=0;e<t.length;e++){let r=t[e];if(r?.role===`assistant`&&r.tool_calls){let i=new Set;for(let n=e+1;n<t.length&&t[n].role===`tool`;n++)i.add(t[n].tool_call_id);let a=r.tool_calls.filter(e=>i.has(e.id));if(a.length===0)n.warn(`[Background] filterApiMessages: `,e,` assistant message tool_calls no matchconfig tool response,cleared`),delete r.tool_calls,r.content||(t.splice(e,1),e--);else if(a.length<r.tool_calls.length){let t=r.tool_calls.filter(e=>!i.has(e.id));n.warn(`[Background] filterApiMessages: `,e,` assistant message`,t.length,` tool_call no corresponding response,removed,keep`,a.length,``),r.tool_calls=a}}}return t}function ye(e){return!e||e.length===0?e:e.map(e=>{if(!e||!Array.isArray(e.content))return e;let t=!1,n=e.content.map(e=>e&&e.type===`image_url`&&e.image_url?(t=!0,{type:`image_url`,image_url:{url:e.image_url.url}}):e);return t?{...e,content:n}:e})}function be(e){if(typeof e==`string`)return e;if(Array.isArray(e)){let t=e.filter(e=>e.type===`text`);return t.length===1?t[0].text:t}return e}function xe(e){return e==null?``:typeof e==`string`?e:Array.isArray(e)?e.filter(e=>e&&e.type===`text`&&e.text).map(e=>e.text).join(`
25
- `):JSON.stringify(e)}var y=2e3;function Se(e){if(!e)return{compressed:e,wasCompressed:!1};let t=m(e);if(t<=y)return{compressed:e,wasCompressed:!1};let r=g(e,y);return n.debug(`[TokenCounter] referenced contentcompress: ${t} → ${m(r)} tokens`),{compressed:r,wasCompressed:!0}}e(`zh`,{db:{sessionLabel:`会话 {id}`,archivedLabel:`[归档] {label}`}}),e(`en`,{db:{sessionLabel:`Session {id}`,archivedLabel:`[Archived] {label}`}});var Ce=`ai-helper-db`,we=6,Te=6048e5,b=`react_checkpoint_`;function Ee(){return new Promise((e,t)=>{let r=indexedDB.open(Ce,we);r.onupgradeneeded=e=>{let t=e.target.result;if(t.objectStoreNames.contains(`sessions`)||t.createObjectStore(`sessions`,{keyPath:`id`}).createIndex(`updatedAt`,`updatedAt`,{unique:!1}),t.objectStoreNames.contains(`activeSession`)||t.createObjectStore(`activeSession`,{keyPath:`key`}),t.objectStoreNames.contains(`archivedSessions`)||t.createObjectStore(`archivedSessions`,{keyPath:`id`}).createIndex(`createdAt`,`createdAt`,{unique:!1}),!t.objectStoreNames.contains(`uiPrototypes`)){let e=t.createObjectStore(`uiPrototypes`,{keyPath:`id`});e.createIndex(`createdAt`,`createdAt`,{unique:!1}),e.createIndex(`sessionId`,`sessionId`,{unique:!1})}if(!t.objectStoreNames.contains(`tokenStats`)){let e=t.createObjectStore(`tokenStats`,{keyPath:`id`});e.createIndex(`sessionId`,`sessionId`,{unique:!1}),e.createIndex(`timestamp`,`timestamp`,{unique:!1})}if(t.objectStoreNames.contains(`reactCheckpoints`)||t.createObjectStore(`reactCheckpoints`,{keyPath:`sessionId`}).createIndex(`updatedAt`,`updatedAt`,{unique:!1}),!t.objectStoreNames.contains(`bookmarks`)){let e=t.createObjectStore(`bookmarks`,{keyPath:`id`});e.createIndex(`sessionId`,`sessionId`,{unique:!1}),e.createIndex(`createdAt`,`createdAt`,{unique:!1})}if(!t.objectStoreNames.contains(`scheduledTasks`)){let e=t.createObjectStore(`scheduledTasks`,{keyPath:`id`});e.createIndex(`nextRunAt`,`nextRunAt`,{unique:!1}),e.createIndex(`enabled`,`enabled`,{unique:!1})}},r.onsuccess=t=>{let r=t.target.result;r.onversionchange=e=>{n.debug(`[IDB] detected versionchange event,maindynamicclosecurrent connection as allows upgrade`);try{e.target.close()}catch{}x=null},e(r)},r.onerror=e=>{n.error(`[IDB] opendatabase failed:`,e.target.error),t(e.target.error)},r.onblocked=()=>{n.warn(`[IDB] databaseupgrade blocked (other connections notclose),waitingretry...`)}})}var x=null;function S(){x&&(x=null,n.debug(`[IDB] databaseconnectionreset`))}function C(){return x||=Ee(),x}function w(e,t,r,i=!1){return C().then(a=>new Promise((o,s)=>{let c=null,l=!1;if(!a.objectStoreNames.contains(e)){if(n.error(`[IDB] store "${e}" not found!current DB version: ${a.version}, store column table: [${Array.from(a.objectStoreNames).join(`, `)}]`),i){l=!0,s(Error(`Store "${e}" does not exist in database (version ${a.version})`));return}l=!0;try{a.close()}catch{}S(),setTimeout(()=>{w(e,t,r,!0).then(o).catch(s)},50);return}let u;try{u=a.transaction(e,t)}catch(a){if(n.error(`[IDB] create transaction failed (${e}):`,a.message),i){l=!0,s(a);return}l=!0,S(),setTimeout(()=>{w(e,t,r,!0).then(o).catch(s)},50);return}r(u.objectStore(e),e=>{c=e}),u.oncomplete=()=>{l||(l=!0,o(c))},u.onerror=a=>{if(l)return;l=!0;let c=a.target.error||Error(`Transaction error on ${e}`);n.error(`[IDB] transaction error (${e}):`,c),i?s(c):(S(),w(e,t,r,!0).then(o).catch(s))},u.onabort=()=>{l||(l=!0,i?s(Error(`Transaction aborted on ${e}`)):(S(),w(e,t,r,!0).then(o).catch(s)))}}))}function T(){return w(`sessions`,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>t(n.result||[]),n.onerror=()=>t([])})}function E(e){return w(`sessions`,`readonly`,(t,n)=>{let r=t.get(e);r.onsuccess=()=>n(r.result||null),r.onerror=()=>n(null)})}async function De(e,t){if(!e||!t)return!1;try{let n=await E(e);if(!n||!n.messageHistory)return!1;let r=n.messageHistory.findIndex(e=>(e.messageId||e.id)===t);return r!==-1&&(n.messageHistory.splice(r,1),await D(n))}catch(e){return n.error(`[DB] deleteMessageFromSession failed:`,e),!1}}function D(e){return w(`sessions`,`readwrite`,(t,n)=>{let r=t.put(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function Oe(e){return w(`sessions`,`readwrite`,(t,n)=>{let r=t.delete(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function ke(e){return C().then(t=>new Promise(n=>{let r=t.transaction(`sessions`,`readwrite`),i=r.objectStore(`sessions`);e.forEach(e=>i.put(e)),r.oncomplete=()=>n(!0),r.onerror=()=>n(!1)}))}function O(){return w(`activeSession`,`readonly`,(e,t)=>{let n=e.get(`active`);n.onsuccess=()=>t(n.result?.sessionId||null),n.onerror=()=>t(null)})}function k(e){return w(`activeSession`,`readwrite`,(t,n)=>{let r=t.put({key:`active`,sessionId:e});r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function A(){return w(`archivedSessions`,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>t(n.result||[]),n.onerror=()=>t([])})}function j(e){return C().then(t=>new Promise(n=>{let r=t.transaction(`archivedSessions`,`readwrite`),i=r.objectStore(`archivedSessions`),a=i.clear();a.onsuccess=()=>{e.forEach(e=>i.put(e))},r.oncomplete=()=>n(!0),r.onerror=()=>n(!1)}))}function Ae(e){let t=Date.now(),n={...e,createdAt:e.createdAt||t,updatedAt:t};return w(`uiPrototypes`,`readwrite`,(e,t)=>{let r=e.put(n);r.onsuccess=()=>t(n),r.onerror=()=>t(null)})}function je(e){return w(`uiPrototypes`,`readonly`,(t,n)=>{let r=t.get(e);r.onsuccess=()=>n(r.result||null),r.onerror=()=>n(null)})}function Me(e=null){return w(`uiPrototypes`,`readonly`,(t,n)=>{let r=t.getAll();r.onsuccess=()=>{let t=r.result||[];e&&(t=t.filter(t=>t.sessionId===e)),t.sort((e,t)=>(t.createdAt||0)-(e.createdAt||0)),n(t)},r.onerror=()=>n([])})}function Ne(e){return w(`uiPrototypes`,`readwrite`,(t,n)=>{let r=t.delete(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function Pe(e){return e?E(e).then(e=>{if(!e)return[];let n=e.title||t(`db.sessionLabel`,{id:e.id?.slice(0,8)});return(e.messageHistory||[]).filter(e=>e.content).map((t,r)=>({session:e.id,sessionLabel:n,index:r,role:t.role,content:t.content}))}):T().then(e=>{let n=e,r=[];return n.forEach(e=>{let n=e.title||t(`db.sessionLabel`,{id:e.id?.slice(0,8)});(e.messageHistory||[]).forEach((t,i)=>{t.content&&r.push({session:e.id,sessionLabel:n,index:i,role:t.role,content:t.content})})}),r})}function Fe(){return A().then(e=>{let n=[];return e.forEach(e=>{let r=t(`db.archivedLabel`,{label:e.title||t(`db.sessionLabel`,{id:e.id?.slice(0,8)})});(e.messages||[]).forEach((t,i)=>{t.content&&n.push({session:e.id,sessionLabel:r,index:i,role:t.role,content:t.content})})}),n})}function Ie(){return new Promise(e=>{chrome.storage.local.get([`sessions`,`conversationSessions`],async t=>{let r=!1;if(t.sessions?.list?.length>0){let{list:e,activeSessionId:i}=t.sessions;await ke(e),i&&await k(i),r=!0,n.debug(`[IDB] migrated activesession:`,e.length,``)}t.conversationSessions?.sessions?.length>0&&(await j(t.conversationSessions.sessions),r=!0,n.debug(`[IDB] migrated archivesession:`,t.conversationSessions.sessions.length,``)),r&&chrome.storage.local.remove([`sessions`,`conversationSessions`,`chatHistory`],()=>{n.debug(`[IDB] cleaned chrome.storage.local olddata`)}),e(r)})})}async function M(){(await T()).length>0||await O()||await Ie()}async function Le(e){if(!e?.sessionId)return!1;let t=Date.now(),r={...e,updatedAt:t,createdAt:e.createdAt||t},i=b+e.sessionId,a=!1;try{await chrome.storage.local.set({[i]:r}),a=!0}catch(e){n.warn(`[Storage] chrome.storage.local save checkpoint failed:`,e.message)}let o=!1;try{o=await w(`reactCheckpoints`,`readwrite`,(e,t)=>{let n=e.put(r);n.onsuccess=()=>t(!0),n.onerror=()=>t(!1)})}catch(e){n.warn(`[Storage] IndexedDB save checkpoint failed (downgraded to chrome.storage.local):`,e.message)}return!a&&!o?(n.error(`[Storage] checkpoint save complete failed:chrome.storage.local and IndexedDB averagenon- with `),!1):!0}async function Re(e){if(!e)return null;try{let t=await w(`reactCheckpoints`,`readonly`,(t,n)=>{let r=t.get(e);r.onsuccess=()=>n(r.result||null),r.onerror=()=>n(null)});if(t)return t}catch{}try{let t=b+e;return(await chrome.storage.local.get(t))[t]||null}catch(e){return n.warn(`[Storage] chrome.storage.local read checkpoint failed:`,e.message),null}}async function N(e){if(!e)return!1;let t=!1;try{let n=b+e;await chrome.storage.local.remove(n),t=!0}catch(e){n.warn(`[Storage] chrome.storage.local delete checkpoint failed:`,e.message)}try{await w(`reactCheckpoints`,`readwrite`,(t,n)=>{let r=t.delete(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)}),t=!0}catch{}return t}async function P(){let e=[];try{let t=await chrome.storage.local.get(null);for(let[n,r]of Object.entries(t))n.startsWith(b)&&r?.sessionId&&e.push(r)}catch(e){n.warn(`[Storage] chrome.storage.local get all checkpoint failed:`,e.message)}let t=[];try{t=await w(`reactCheckpoints`,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>t(n.result||[]),n.onerror=()=>t([])})}catch{}let r=new Map;for(let t of e)r.set(t.sessionId,t);for(let e of t)r.set(e.sessionId,e);return Array.from(r.values())}async function ze(){let e=await P(),t=Date.now(),r=e.filter(e=>(e.updatedAt||0)<t-Te);if(r.length===0)return 0;let i=0;for(let e of r)await N(e.sessionId)&&i++;return n.debug(`[IDB] cleanup ${i} expired ReAct checkpoint`),i}function F(){return w(`bookmarks`,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>t(n.result||[]),n.onerror=()=>t([])})}function Be(e){return w(`bookmarks`,`readwrite`,(t,n)=>{let r=t.put(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function I(e){return w(`bookmarks`,`readwrite`,(t,n)=>{let r=t.delete(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function Ve(e,t){return w(`bookmarks`,`readwrite`,(n,r)=>{let i=n.get(e);i.onsuccess=()=>{let e=i.result;if(!e){r(!1);return}e.pinned=t;let a=n.put(e);a.onsuccess=()=>r(!0),a.onerror=()=>r(!1)},i.onerror=()=>r(!1)})}function He(e){return w(`scheduledTasks`,`readonly`,(t,n)=>{let r=t.get(e);r.onsuccess=()=>n(r.result||null),r.onerror=()=>n(null)})}function Ue(){return w(`scheduledTasks`,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>t(n.result||[]),n.onerror=()=>t([])})}function We(e){return w(`scheduledTasks`,`readwrite`,(t,n)=>{let r=t.put(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function Ge(e){return w(`scheduledTasks`,`readwrite`,(t,n)=>{let r=t.delete(e);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}var L=`tokenStats`,R=new Set([`selection_toolbar`]);function Ke(e){let t={id:`tcr_${Date.now()}_${Math.random().toString(36).slice(2,8)}`,sessionId:e.sessionId,timestamp:new Date().toISOString(),model:e.model||`unknown`,promptTokens:e.promptTokens||0,completionTokens:e.completionTokens||0,totalTokens:e.totalTokens||0,contextWindow:e.contextWindow||256e3,contextUsageRate:e.contextWindow>0?(e.promptTokens||0)/e.contextWindow:0,callType:e.callType||`unknown`};return w(L,`readwrite`,(e,n)=>{let r=e.put(t);r.onsuccess=()=>n(!0),r.onerror=()=>n(!1)})}function qe(e){return w(L,`readonly`,(t,n)=>{let r=t.index(`sessionId`),i=e?r.getAll(IDBKeyRange.bound(e,e+`￿`)):t.getAll();i.onsuccess=()=>{let t=(i.result||[]).filter(t=>t.sessionId===e||e&&t.sessionId?.startsWith(e+`_`));if(t.length===0){n({sessionId:e,totalPromptTokens:0,totalCompletionTokens:0,totalTokens:0,apiCallCount:0,avgContextUsageRate:0,maxContextUsageRate:0,minContextUsageRate:0,records:[]});return}let r=t.map(e=>e.contextUsageRate||0).filter(e=>e>0);n({sessionId:e,totalPromptTokens:t.reduce((e,t)=>e+(t.promptTokens||0),0),totalCompletionTokens:t.reduce((e,t)=>e+(t.completionTokens||0),0),totalTokens:t.reduce((e,t)=>e+(t.totalTokens||0),0),apiCallCount:t.length,avgContextUsageRate:r.length>0?r.reduce((e,t)=>e+t,0)/r.length:0,maxContextUsageRate:r.length>0?Math.max(...r):0,minContextUsageRate:r.length>0?Math.min(...r):0,records:t.sort((e,t)=>new Date(t.timestamp)-new Date(e.timestamp)).slice(0,20)})},i.onerror=()=>n(null)})}function Je(){return w(L,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>{let e=n.result||[];if(e.length===0){t({totalPromptTokens:0,totalCompletionTokens:0,totalTokens:0,totalApiCalls:0,totalSessions:0,lastUpdated:null});return}let r=new Set(e.map(e=>e.sessionId).filter(e=>e&&!R.has(e)));t({totalPromptTokens:e.reduce((e,t)=>e+(t.promptTokens||0),0),totalCompletionTokens:e.reduce((e,t)=>e+(t.completionTokens||0),0),totalTokens:e.reduce((e,t)=>e+(t.totalTokens||0),0),totalApiCalls:e.length,totalSessions:r.size,lastUpdated:e.reduce((e,t)=>t.timestamp>e?t.timestamp:e,``)})},n.onerror=()=>t(null)})}function Ye(){return w(L,`readwrite`,(e,t)=>{let n=e.clear();n.onsuccess=()=>t(!0),n.onerror=()=>t(!1)})}function Xe(e=30){return w(L,`readonly`,(t,n)=>{let r=new Date(new Date().getTime()-e*24*60*60*1e3),i=t.index(`timestamp`).getAll(IDBKeyRange.lowerBound(r.toISOString()));i.onsuccess=()=>{let e=i.result||[],t=new Map;e.forEach(e=>{let n=new Date(e.timestamp);if(n<r)return;let i=n.toISOString().split(`T`)[0];t.has(i)||t.set(i,{date:i,totalTokens:0,apiCalls:0});let a=t.get(i);a.totalTokens+=e.totalTokens||0,a.apiCalls+=1}),n(Array.from(t.values()).sort((e,t)=>e.date.localeCompare(t.date)))},i.onerror=()=>n([])})}function Ze(e,t){return w(L,`readonly`,(n,r)=>{let i=n.index(`timestamp`).getAll(IDBKeyRange.bound(e,t));i.onsuccess=()=>{let n=i.result||[],a=new Date(e),o=new Date(t),s=n.filter(e=>{let t=new Date(e.timestamp);return t>=a&&t<=o});if(s.length===0){r({totalPromptTokens:0,totalCompletionTokens:0,totalTokens:0,totalApiCalls:0,totalSessions:0,lastUpdated:null});return}let c=new Set(s.map(e=>e.sessionId).filter(e=>e&&!R.has(e)));r({totalPromptTokens:s.reduce((e,t)=>e+(t.promptTokens||0),0),totalCompletionTokens:s.reduce((e,t)=>e+(t.completionTokens||0),0),totalTokens:s.reduce((e,t)=>e+(t.totalTokens||0),0),totalApiCalls:s.length,totalSessions:c.size,lastUpdated:s.reduce((e,t)=>t.timestamp>e?t.timestamp:e,``)})},i.onerror=()=>r(null)})}function Qe(){return w(L,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>{let e=n.result||[],r=new Map;e.forEach(e=>{let t=e.model||`unknown`;r.has(t)||r.set(t,0),r.set(t,r.get(t)+(e.totalTokens||0))});let i=Array.from(r.values()).reduce((e,t)=>e+t,0);t(Array.from(r.entries()).map(([e,t])=>({model:e,totalTokens:t,percentage:i>0?t/i*100:0})).sort((e,t)=>t.totalTokens-e.totalTokens))},n.onerror=()=>t([])})}function $e(){return w(L,`readonly`,(e,t)=>{let n=e.getAll();n.onsuccess=()=>{let e=n.result||[],r=new Map;e.forEach(e=>{let t=e.callType||`unknown`;r.has(t)||r.set(t,0),r.set(t,r.get(t)+(e.totalTokens||0))});let i=Array.from(r.values()).reduce((e,t)=>e+t,0);t(Array.from(r.entries()).map(([e,t])=>({callType:e,totalTokens:t,percentage:i>0?t/i*100:0})).sort((e,t)=>t.totalTokens-e.totalTokens))},n.onerror=()=>t([])})}var et=[{id:`default`,name:`Default Assistant`,description:`All-purpose AI assistant with all tool capabilities`,icon:`🤖`,systemPrompt:null,toolIds:null,skillIds:null,isBuiltin:!0,allowSubDispatch:!1,model:null,temperature:null,topP:null}],tt=[{name:`Code Review Expert`,icon:`🔍`,description:`Focused on code review and quality assurance`,systemPrompt:`You are a senior Code Review Expert. Your responsibilities:
26
- 1. Review code for logical correctness, performance, and security
27
- 2. Check code style, naming conventions, and best practices
28
- 3. Identify potential bugs, memory leaks, and concurrency issues
29
- 4. Provide actionable improvement suggestions with example code
30
-
31
- Response principles:
32
- - Always indicate severity (critical/moderate/suggestion)
33
- - Provide specific code modification suggestions, avoid vague comments
34
- - Focus on maintainability, not just functional correctness`,systemPromptZh:`你是一位资深代码审查专家。你的职责:
35
- 1. 审查代码的逻辑正确性、性能和安全性
36
- 2. 检查代码风格、命名规范和最佳实践
37
- 3. 识别潜在的 Bug、内存泄漏和并发问题
38
- 4. 提供可操作的改进建议,并附带示例代码
39
-
40
- 回复原则:
41
- - 始终标注严重程度(严重/中等/建议)
42
- - 提供具体的代码修改建议,避免模糊评论
43
- - 关注可维护性,而非仅关注功能正确性`,toolIds:[`page_content`,`search_browser_data`,`agent_file`,`agent_search`,`search_chats`,`fetch_url`,`plan_task`],allowSubDispatch:!1},{name:`Web Automation Assistant`,icon:`🌐`,description:`Focused on web interaction and automation`,systemPrompt:`You are a web automation expert. Your strengths:
44
- 1. Automate web page interactions based on user needs (clicking, form filling, scrolling, etc.)
45
- 2. Extract and analyze web page content
46
- 3. Handle multi-step web interaction flows
47
-
48
- Operating principles:
49
- - Understand page structure before acting; prefer query_elements first
50
- - Verify results after actions to ensure they take effect
51
- - Analyze errors and try alternative approaches
52
- - Never assume elements exist; fetch page info first when uncertain
53
- - For dialogs (alert/confirm/prompt), call handle_dialog BEFORE the action that triggers them, then use interact_element to proceed`,systemPromptZh:`你是一位网页自动化专家。你的优势:
54
- 1. 根据用户需求自动化网页交互(点击、表单填写、滚动等)
55
- 2. 提取和分析网页内容
56
- 3. 处理多步骤的网页交互流程
57
-
58
- 操作原则:
59
- - 行动前先理解页面结构,优先使用 query_elements
60
- - 操作后验证结果,确保生效
61
- - 分析错误并尝试替代方案
62
- - 不要假设元素存在,不确定时先获取页面信息
63
- - 涉及 alert/confirm/prompt 弹窗时,先在触发弹窗的操作前调用 handle_dialog,再通过 interact_element 继续`,toolIds:[`page_content`,`query_elements`,`interact_element`,`fill_form`,`scroll_to`,`wait_element`,`keyboard_input`,`select_dropdown`,`capture_page`,`extract_data`,`search_in_page`,`wait_navigation`,`scroll_collect`,`drag_drop`,`file_upload`,`iframe_content`,`manage_tab`,`handle_dialog`],allowSubDispatch:!1},{name:`Data Analyst`,icon:`📊`,description:`Focused on data extraction, analysis, and visualization`,systemPrompt:`You are a data analyst. Your strengths:
64
- 1. Extract structured data from web pages (tables, lists, JSON)
65
- 2. Analyze and summarize data patterns
66
- 3. Present analysis results in clear formats
67
-
68
- Analysis principles:
69
- - Understand data structure before starting analysis
70
- - Use the most appropriate extraction method (tables → extract_data with dataType=table; links/images/forms → extract_data with dataType=links/images/forms; text/HTML → page_content with format=text/html)
71
- - Support analysis results with data; avoid subjective assumptions
72
- - Present conclusions using tables or charts`,systemPromptZh:`你是一位数据分析师。你的优势:
73
- 1. 从网页中提取结构化数据(表格、列表、JSON)
74
- 2. 分析和总结数据模式
75
- 3. 以清晰格式呈现分析结果
76
-
77
- 分析原则:
78
- - 开始分析前先理解数据结构
79
- - 使用最合适的提取方法(表格使用 extract_data 配合 dataType=table;链接/图片/表单等结构化数据使用 extract_data 配合 dataType=links/images/forms;纯文本/HTML 使用 page_content 配合 format=text/html)
80
- - 用数据支撑分析结果,避免主观臆断
81
- - 使用表格或图表呈现结论`,toolIds:[`page_content`,`extract_data`,`query_elements`,`search_in_page`,`scroll_collect`,`fetch_url`,`iframe_content`,`clipboard`],allowSubDispatch:!1},{name:`Documentation Assistant`,icon:`📝`,description:`Focused on technical documentation and content organization`,systemPrompt:`You are a technical documentation expert. Your strengths:
82
- 1. Write clear technical documentation (API docs, READMEs, user guides)
83
- 2. Distill and summarize technical information
84
- 3. Transform complex concepts into easy-to-understand documentation
85
-
86
- Writing principles:
87
- - Clear structure: Use headings, lists, and tables to organize content
88
- - Examples first: Key concepts must include code or configuration examples
89
- - Reader-oriented: Adjust technical depth based on target audience
90
- - Stay concise: Avoid redundancy; every paragraph should carry information`,systemPromptZh:`你是一位技术文档专家。你的优势:
91
- 1. 编写清晰的技术文档(API 文档、README、用户指南)
92
- 2. 提炼和总结技术信息
93
- 3. 将复杂概念转化为易于理解的文档
94
-
95
- 编写原则:
96
- - 结构清晰:使用标题、列表和表格组织内容
97
- - 示例先行:关键概念必须附带代码或配置示例
98
- - 面向读者:根据目标受众调整技术深度
99
- - 保持简洁:避免冗余,每段文字都应承载信息`,toolIds:[`page_content`,`clipboard`,`search_browser_data`,`search_chats`,`fetch_url`,`agent_file`,`agent_search`,`extract_data`,`capture_page`,`search_in_page`],allowSubDispatch:!1}];function nt(){return`agent_`+Date.now().toString(36)+`_`+Math.random().toString(36).substring(2,6)}var z=new Set,B=new Set,V=[],H=`deepseek-v4-pro`,U=null,W=[],G=!0,K=!0,rt=null,it=!1,at=null,ot=``,st=``,ct=[],lt=-1,ut=-1,dt=[],ft=[],pt=-1,mt=null,ht=-1,gt=[],_t=-1,vt=`prompts`,yt=`prompts`,q=!1,bt=-1,xt=-1,St=-1,Ct=null,wt=``,Tt=[],Et=-1,Dt=null,Ot=null,kt=null,At=null,jt=[],Mt={platformName:`Unknown`,platform:`unknown`,arch:`unknown`,shell:`/bin/sh`,homeDir:`/home/user`,workdir:``,connected:!1},Nt={maxMemoryMessages:20,enableExecutionLog:!1,showMessageTimestamp:!0},Pt=.2,Ft=1,It=0,Lt=`all`,Rt=``,zt=[],Bt=[],Vt={},J=new Map,Ht=null,Y=new Map,Ut=new Set,Wt=new Map,Gt=null,Kt=null,qt=null,Jt=null,Yt=null,Xt=3e5,Zt=null,Qt=!1,$t=null,en=[],tn=``,nn=null,rn=0,an=0,on=-1,sn=!1,cn=``,ln=``,un=``,dn=[],fn=!0,pn=[],mn=new Map,hn=new Map,gn=new Map,_n=new Map,vn=!1,yn=!1,bn=new Map,X={get isGenerating(){return z.has(U)},set isGenerating(e){e?z.add(U):z.delete(U),document.dispatchEvent(new CustomEvent(`generating-state-changed`))},get generatingSessionIds(){return z},get completedSessionIds(){return B},set completedSessionIds(e){B=e},get messageHistory(){return V},set messageHistory(e){V=e},get currentModel(){return H},set currentModel(e){H=e},get activeSessionId(){return U},set activeSessionId(e){U=e},get sessions(){return W},set sessions(e){W=e},get useTools(){return G},set useTools(e){G=e},get isolateChat(){return K},set isolateChat(e){K=e},get activeCompaction(){return rt},set activeCompaction(e){rt=e},get enableSelectionQuery(){return it},set enableSelectionQuery(e){it=e},get currentTabId(){return at},set currentTabId(e){at=e},get selectedContextText(){return ot},set selectedContextText(e){ot=e},get quotedContextText(){return st},set quotedContextText(e){st=e},get customPrompts(){return ct},set customPrompts(e){ct=e},get selectedPromptIndex(){return lt},set selectedPromptIndex(e){lt=e},get selectedSkillIndex(){return ut},set selectedSkillIndex(e){ut=e},get selectedSkills(){return dt},set selectedSkills(e){dt=e},get selectedMcpServices(){return ft},set selectedMcpServices(e){ft=e},get selectedMcpServiceIndex(){return pt},set selectedMcpServiceIndex(e){pt=e},get selectedPage(){return mt},set selectedPage(e){mt=e},get selectedPageIndex(){return ht},set selectedPageIndex(e){ht=e},get knowledgeRefs(){return gt},set knowledgeRefs(e){gt=e},get selectedKnowledgeAtIndex(){return _t},set selectedKnowledgeAtIndex(e){_t=e},get activeDropdownTab(){return vt},set activeDropdownTab(e){vt=e},get lastActiveDropdownTab(){return yt},set lastActiveDropdownTab(e){yt=e},get showMergedList(){return q},set showMergedList(e){q=e},get selectedAgentAtIndex(){return bt},set selectedAgentAtIndex(e){bt=e},get selectedProxyAtIndex(){return xt},set selectedProxyAtIndex(e){xt=e},get selectedFileAtIndex(){return St},set selectedFileAtIndex(e){St=e},get draggedItemIndex(){return Ct},set draggedItemIndex(e){Ct=e},get systemPrompt(){return wt},set systemPrompt(e){wt=e},get activeAgentId(){return Dt},set activeAgentId(e){Dt=e},get activeAgentToolIds(){return Ot},set activeAgentToolIds(e){Ot=e},get activeAgentMcpExcludedServerIds(){return kt},set activeAgentMcpExcludedServerIds(e){kt=e},get activeAgentSkillIds(){return At},set activeAgentSkillIds(e){At=e},get customAgents(){return jt},set customAgents(e){jt=e},get agentPlatform(){return Mt},set agentPlatform(e){Object.assign(Mt,e)},get inputHistory(){return Tt},set inputHistory(e){Tt=e},get inputHistoryIndex(){return Et},set inputHistoryIndex(e){Et=e},get chatConfig(){return Nt},set chatConfig(e){Nt=e},get temperature(){return Pt},set temperature(e){Pt=e},get topP(){return Ft},set topP(e){Ft=e},get selectedTempIndex(){return It},set selectedTempIndex(e){It=e},get currentCategory(){return Lt},set currentCategory(e){Lt=e},get currentSearch(){return Rt},set currentSearch(e){Rt=e},get enabledTools(){return zt},set enabledTools(e){zt=e},get mcpClosedServers(){return Bt},set mcpClosedServers(e){Bt=e},get collapsedCategories(){return Vt},get sessionExecutionStatus(){return J},set sessionExecutionStatus(e){J=e},get currentExecutionStatus(){return J.get(U)||null},set currentExecutionStatus(e){e===null?J.delete(U):J.set(U,e)},get executionLogListener(){return Ht},set executionLogListener(e){Ht=e},get pendingCancelApi(){return Y.get(U)||null},set pendingCancelApi(e){e===null?Y.delete(U):Y.set(U,e)},get pendingCancelApiMap(){return Y},get pendingCallApiSessionIds(){return Ut},set pendingCallApiSessionIds(e){Ut=e},get substituteLoadingIds(){return Wt},set substituteLoadingIds(e){Wt=e},get currentClarifyToolCallId(){return Gt},set currentClarifyToolCallId(e){Gt=e},get currentClarifySessionId(){return Kt},set currentClarifySessionId(e){Kt=e},get currentConfirmToolCallId(){return qt},set currentConfirmToolCallId(e){qt=e},get currentConfirmSessionId(){return Jt},set currentConfirmSessionId(e){Jt=e},get clarifyTimerInterval(){return Yt},set clarifyTimerInterval(e){Yt=e},get clarifyTimeoutValue(){return Xt},set clarifyTimeoutValue(e){Xt=e},get messageTocContainer(){return Zt},set messageTocContainer(e){Zt=e},get isMouseOverToc(){return Qt},set isMouseOverToc(e){Qt=e},get tocHideTimer(){return $t},set tocHideTimer(e){$t=e},get bookmarks(){return en},set bookmarks(e){en=e},get lastSelectedText(){return tn},set lastSelectedText(e){tn=e},get currentSelectionRange(){return nn},set currentSelectionRange(e){nn=e},get lastMouseX(){return rn},set lastMouseX(e){rn=e},get lastMouseY(){return an},set lastMouseY(e){an=e},get pendingDeleteIndex(){return on},set pendingDeleteIndex(e){on=e},get enableImageInput(){return sn},set enableImageInput(e){sn=e},get imageModelName(){return cn},set imageModelName(e){cn=e},get imageApiBase(){return ln},set imageApiBase(e){ln=e},get imageApiKey(){return un},set imageApiKey(e){un=e},get attachedImages(){return dn},set attachedImages(e){dn=e},get enableFileInput(){return fn},set enableFileInput(e){fn=e},get attachedFiles(){return pn},set attachedFiles(e){pn=e},get agentVersions(){return mn},set agentVersions(e){mn=e},get agentWorkdirs(){return hn},set agentWorkdirs(e){hn=e},get agentHomeDirs(){return gn},set agentHomeDirs(e){gn=e},get agentSystemInfos(){return _n},set agentSystemInfos(e){_n=e},get isScrolling(){return vn},set isScrolling(e){vn=e},get isComposing(){return yn},set isComposing(e){yn=e},get customModelMap(){return bn},set customModelMap(e){bn=e}},xn=`modulepreload`,Sn=function(e){return`/`+e},Cn={},wn=function(e,t,n){let r=Promise.resolve();if(t&&t.length>0){let e=document.getElementsByTagName(`link`),i=document.querySelector(`meta[property=csp-nonce]`),a=i?.nonce||i?.getAttribute(`nonce`);function o(e){return Promise.all(e.map(e=>Promise.resolve(e).then(e=>({status:`fulfilled`,value:e}),e=>({status:`rejected`,reason:e}))))}function s(e){return import.meta.resolve?import.meta.resolve(e):new URL(e,import.meta.url).href}r=o(t.map(t=>{if(t=Sn(t,n),t=s(t),t in Cn)return;Cn[t]=!0;let r=t.endsWith(`.css`);for(let n=e.length-1;n>=0;n--){let i=e[n];if(i.href===t&&(!r||i.rel===`stylesheet`))return}let i=document.createElement(`link`);if(i.rel=r?`stylesheet`:xn,r||(i.as=`script`),i.crossOrigin=``,i.href=t,a&&i.setAttribute(`nonce`,a),document.head.appendChild(i),r)return new Promise((e,n)=>{i.addEventListener(`load`,e),i.addEventListener(`error`,()=>n(Error(`Unable to preload CSS for ${t}`)))})}))}function i(e){let t=new Event(`vite:preloadError`,{cancelable:!0});if(t.payload=e,window.dispatchEvent(t),!t.defaultPrevented)throw e}return r.then(t=>{for(let e of t||[])e.status===`rejected`&&i(e.reason);return e().catch(i)})};e(`zh`,{session:{newSession:`新会话`,importedSession:`导入的会话`,unnamedSession:`未命名会话`,restoredSession:`恢复的会话`,forkSuffix:`分叉`,sourceNotFound:`源会话不存在`,scheduledSession:`定时任务`}}),e(`en`,{session:{newSession:`New session`,importedSession:`Imported session`,unnamedSession:`Unnamed session`,restoredSession:`Restored session`,forkSuffix:`Fork`,sourceNotFound:`Source session not found`,scheduledSession:`Scheduled task`}});async function Tn(e){try{await N(e)}catch(e){n.warn(`[session-store] cleanup ReAct checkpoint failed:`,e)}}var En=!1;async function Z(){En||(await M(),En=!0,Dn())}async function Dn(){try{let e=await T(),t=new Set(e.map(e=>e.id));t.add(`default`);let r=await chrome.storage.local.get(null),i=Object.keys(r).filter(e=>e.startsWith(`scrollPosition_`)&&!t.has(e.slice(15)));i.length>0&&(await chrome.storage.local.remove(i),n.debug(`[session-store] cleanup ${i.length} orphan scrollPosition key:`,i))}catch(e){n.warn(`[session-store] cleanup orphaned scrollPosition failed:`,e)}}async function On(){await Z();let[e,t]=await Promise.all([T(),O()]);return e.sort((e,t)=>e.order!==void 0&&t.order!==void 0?e.order-t.order:e.order===void 0?t.order===void 0?new Date(e.createdAt)-new Date(t.createdAt):1:-1),{activeSessionId:t,list:e}}function kn(e){return typeof e==`string`?e:Array.isArray(e)?e.filter(e=>e.type===`text`).map(e=>e.text).join(``):``}async function An(){if(!X.activeSessionId)return!1;let e=await E(X.activeSessionId);if(!e)return n.warn(`[SessionStore] saveCurrentSession cannot find currentsession:`,X.activeSessionId),!1;if(e.model=X.currentModel,e.useTools=X.useTools,e.enabledTools=[...X.enabledTools],e.agentId=X.activeAgentId||null,e.temperature=X.temperature,e.topP=X.topP,e.contextCompaction=X.activeCompaction||void 0,e.messageHistory=X.messageHistory.map(e=>({role:e.role,content:e.content||``,executionLog:e.executionLog||[],reflectionScore:e.reflectionScore,wasRevised:e.wasRevised||!1,htmlContent:e.htmlContent||void 0,messageId:e.messageId||void 0,timestamp:e.timestamp||void 0,contextBubbles:e.contextBubbles||void 0,resumable:e.resumable||!1})),e.updatedAt=new Date().toISOString(),!e.forkMetadata){let t=X.messageHistory.find(e=>e.role===`user`);t&&(e.title=kn(t.content).substring(0,50).replace(/\n/g,` `))}return await D(e)?!0:(n.error(`[SessionStore] putSession failed, sessionId:`,X.activeSessionId),!1)}async function jn(){await Z();let e=Q(),n={id:e,title:t(`session.newSession`),model:X.currentModel,useTools:X.useTools,enabledTools:[...X.enabledTools],agentId:X.activeAgentId||null,temperature:X.temperature,topP:X.topP,messageHistory:[],scrollPosition:0,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),order:Date.now(),isGenerating:!1,lastExecutionLog:[]};return await D(n),await k(e),n}async function Mn(e){await Z();let n=[];for(let r of e){let e={id:Q(),title:r.title||t(`session.importedSession`),model:r.model||X.currentModel,useTools:r.useTools===void 0||r.useTools,enabledTools:r.enabledTools||[...X.enabledTools],temperature:r.temperature===void 0?X.temperature:r.temperature,topP:r.topP===void 0?X.topP:r.topP,agentId:r.agentId||null,messageHistory:(r.messageHistory||[]).map(e=>({role:e.role,content:e.content||``,executionLog:e.executionLog||[],reflectionScore:e.reflectionScore,wasRevised:e.wasRevised||!1,htmlContent:e.htmlContent||void 0,messageId:e.messageId||void 0,timestamp:e.timestamp||void 0})),scrollPosition:0,createdAt:r.createdAt||new Date().toISOString(),updatedAt:new Date().toISOString(),order:Date.now()+n.length,isGenerating:!1,lastExecutionLog:[]};await D(e),n.push(e)}return!await O()&&n.length>0&&await k(n[0].id),n}async function Nn(e,t){let n=await E(e);return n?(n.messageHistory=n.messageHistory||[],n.messageHistory.push({role:t.role,content:t.content||``,executionLog:t.executionLog||[],reflectionScore:t.reflectionScore,wasRevised:t.wasRevised||!1,htmlContent:t.htmlContent||void 0,messageId:t.messageId||void 0,timestamp:t.timestamp||void 0,contextBubbles:t.contextBubbles||void 0}),n.updatedAt=new Date().toISOString(),n.isGenerating=!1,await D(n),!0):!1}function Q(){return`sess_`+Date.now().toString(36)+`_`+Math.random().toString(36).substring(2,8)}async function Pn(e){if(e===X.activeSessionId)return;let t=An(),r=chrome.storage.local.get([`modelName`,`temperature`,`topP`]).catch(()=>({})),[i]=await Promise.all([E(e),t]);if(!i)return n.error(`[SessionStore] find not to session:`,e),!1;if(await k(e),X.activeSessionId=e,X.messageHistory=i.messageHistory||[],X.activeCompaction=i.contextCompaction||null,X.currentModel=i.model||X.currentModel,X.temperature=i.temperature===void 0?X.temperature:i.temperature,X.topP=i.topP===void 0?X.topP:i.topP,X.useTools=i.useTools===void 0?X.useTools:i.useTools,X.activeAgentId=i.agentId||null,i.agentId?chrome.storage.local.set({activeAssistantId:i.agentId}):chrome.storage.local.remove(`activeAssistantId`),i.agentId&&i.agentId!=="default")try{let{getAgent:e}=await wn(async()=>{let{getAgent:e}=await import(`./agent-store-BFaBECYz.js`).then(e=>e.t);return{getAgent:e}},__vite__mapDeps([0,1,2])),t=await e(i.agentId);t&&(t.model&&(X.currentModel=t.model),t.temperature!==null&&t.temperature!==void 0&&(X.temperature=t.temperature,X.topP=t.topP!==null&&t.topP!==void 0?t.topP:1),document.dispatchEvent(new CustomEvent(`agent-model-changed`)))}catch{}else{let e=await r;e.modelName&&(X.currentModel=e.modelName),e.temperature!==void 0&&(X.temperature=e.temperature),e.topP!==void 0&&(X.topP=e.topP),document.dispatchEvent(new CustomEvent(`agent-model-changed`))}return i.isGenerating&&X.pendingCallApiSessionIds.has(e)?X.generatingSessionIds.add(e):i.isGenerating&&(n.debug(`[SessionStore] detected expiredperiod isGenerating mark,async cleanup:`,e),(async()=>{try{let t=await E(e);t&&(t.isGenerating=!1,await D(t))}catch(e){n.warn(`[SessionStore] cleanup expired isGenerating mark failed:`,e)}})()),i}async function $(e){let t=await T(),r=await O();await Oe(e),chrome.storage.local.remove(`scrollPosition_`+e),await Tn(e);try{let t=(await F()).filter(t=>t.sessionId===e);for(let e of t)await I(e.id);t.length>0&&n.info(`[SessionStore] cleaned ${t.length} bookmark (session ${e} deleted)`)}catch(e){n.warn(`[SessionStore] cleanup bookmarks failed:`,e)}if(r===e){let n=[...t].sort((e,t)=>e.order!==void 0&&t.order!==void 0?e.order-t.order:e.order===void 0?t.order===void 0?new Date(e.createdAt)-new Date(t.createdAt):1:-1),r=n.findIndex(t=>t.id===e),i=n.filter(t=>t.id!==e);i.length>0?await k(i[Math.min(r,i.length-1)].id):await k(null)}return!0}async function Fn(e,t){let n=await E(e);return n?(n.title=t,n.updatedAt=new Date().toISOString(),await D(n),!0):!1}async function In(e){let t=await T(),n=new Map(t.map(e=>[e.id,e])),r=[];return e.forEach((e,t)=>{let i=n.get(e);i&&(i.order=t,r.push(D(i)))}),await Promise.all(r),!0}async function Ln(){if(!X.messageHistory||X.messageHistory.length===0)return;let e=await E(X.activeSessionId);if(!e)return;let n=X.messageHistory.find(e=>e.role===`user`),r=n?kn(n.content).substring(0,50).replace(/\n/g,` `):e.title||t(`session.unnamedSession`),i=Date.now().toString(36)+Math.random().toString(36).substring(2,8),a=X.messageHistory.map(e=>({role:e.role,content:e.content||``,executionLog:e.executionLog||[],reflectionScore:e.reflectionScore,wasRevised:e.wasRevised||!1,htmlContent:e.htmlContent||void 0})),o=await A();o.push({id:i,title:r,createdAt:new Date().toISOString(),messages:a}),o.length>20&&o.splice(0,o.length-20),await j(o);let s=await jn();return await $(e.id),await Pn(s.id),!0}async function Rn(e,n=null){await Z();let r=await E(e);if(!r)throw Error(t(`session.sourceNotFound`));let i=Q(),a=new Date().toISOString(),o=r.messageHistory||[],s=!1;if(n){let e=o.findIndex(e=>e.messageId===n);e>=0&&(o=o.slice(0,e+1),s=!0)}let c=o.map(e=>({...e,executionLog:Array.isArray(e.executionLog)?[...e.executionLog]:[],contextBubbles:Array.isArray(e.contextBubbles)?[...e.contextBubbles]:void 0,messageId:`msg_`+Date.now().toString(36)+`_`+Math.random().toString(36).substring(2,8)})),l={...r,id:i,title:`${r.title||t(`session.newSession`)} - ${t(`session.forkSuffix`)}`,messageHistory:c,isGenerating:!1,lastExecutionLog:[],scrollPosition:0,createdAt:a,updatedAt:a,order:Date.now(),forkMetadata:{sourceSessionId:e,forkedAt:a,...s?{upToMessageId:n}:{}}};return await D(l),await k(i),l}async function zn(e){await Z();let n={id:Q(),title:e.name||t(`session.scheduledSession`),model:e.model||null,useTools:e.useTools==null?null:e.useTools,enabledTools:null,agentId:e.agentId||null,temperature:e.temperature==null?null:e.temperature,topP:e.topP==null?null:e.topP,messageHistory:[],scrollPosition:0,createdAt:new Date().toISOString(),updatedAt:new Date().toISOString(),order:Date.now(),isGenerating:!1,lastExecutionLog:[],scheduledTaskId:e.id};return await D(n),n}export{h as $,Ge as A,He as B,$e as C,I as D,ze as E,P as F,We as G,je as H,Ue as I,Pe as J,Le as K,T as L,M,O as N,De as O,F as P,Se as Q,Fe as R,qe as S,Ke as T,Me as U,E as V,Be as W,de as X,Ve as Y,pe as Z,nt as _,$ as a,ie as at,Je as b,On as c,ce as ct,An as d,me as dt,m as et,Pn as f,g as ft,et as g,tt as h,jn as i,re as it,Ne as j,N as k,Fn as l,ye as lt,X as m,ne as mt,Ln as n,ve as nt,Rn as o,v as ot,wn as p,ae as pt,Ae as q,zn as r,he as rt,Mn as s,fe as st,Nn as t,xe as tt,In as u,be as ut,Ye as v,Qe as w,Ze as x,Xe as y,Re as z};
100
- //# sourceMappingURL=session-store-DwXNnVF5.js.map