// ==UserScript== // @name Thpilot AI 划词助手 // @namespace ThpilotAIHelper // @version 2.23.1 // @description 通用网页划词助手:任意网页划词解释、翻译、纠错、总结和聊天、搜索、抓网页、图片、web搜索和工具调用等 // @author Wilsons / Web adaptation // @match http://*/* // @match https://*/* // @match file:///* // @run-at document-idle // @noframes // @grant GM_xmlhttpRequest // @grant GM_getValue // @grant GM_setValue // @grant GM_deleteValue // @grant GM_getResourceText // @grant GM_registerMenuCommand // @grant GM_setClipboard // @grant unsafeWindow // @connect * // @require https://fastly.jsdelivr.net/npm/markdown-it@14.1.0/dist/markdown-it.min.js // @require https://fastly.jsdelivr.net/npm/katex@0.18.1/dist/katex.min.js // @require https://fastly.jsdelivr.net/npm/markdown-it-task-lists@2.1.1/dist/markdown-it-task-lists.min.js // @require https://fastly.jsdelivr.net/npm/markdown-it-footnote@4.0.0/dist/markdown-it-footnote.min.js // @require https://fastly.jsdelivr.net/npm/@highlightjs/cdn-assets@11.11.1/highlight.min.js // @require https://fastly.jsdelivr.net/npm/dompurify@3.2.6/dist/purify.min.js // @require https://fastly.jsdelivr.net/npm/@mozilla/readability@0.6.0/Readability.js // Mermaid 11 等 不能 @require(沙箱挂载失败);用 @resource 扩展内缓存,运行时注入 // @resource katexCss https://fastly.jsdelivr.net/npm/katex@0.18.1/dist/katex.min.css // @resource highlightCss https://fastly.jsdelivr.net/npm/highlight.js@11.11.1/styles/github-dark.min.css // @resource mermaidJs https://fastly.jsdelivr.net/npm/mermaid@11.16.0/dist/mermaid.min.js // @license MIT // ==/UserScript== /* // @require file:///Users/wish/workspace/ThpilotAI/user.js?r=1 */ (async () => { 'use strict'; const SETTINGS_STORAGE_KEY = 'thpilot-web-settings-v2'; function normalizeDomainBlacklist(input) { const domains = Array.isArray(input) ? input : String(input || '').split(/\r?\n/); return [...new Set(domains .map(domain => String(domain || '') .trim() .toLowerCase() .replace(/^\.+|\.+$/g, '')) .filter(Boolean))]; } const storedSettings = GM_getValue(SETTINGS_STORAGE_KEY, {}) || {}; const domainBlacklist = normalizeDomainBlacklist( storedSettings.domainBlacklist, ); const currentHostname = location.hostname .toLowerCase() .replace(/\.+$/, ''); const isDomainBlacklisted = domainBlacklist.some(domain => { return domain && ( currentHostname === domain || currentHostname.endsWith(`.${domain}`) ); }); if (isDomainBlacklisted) return; if (window.top !== window.self) return; if (document.documentElement.dataset.thpilotWebLoaded === '1') return; document.documentElement.dataset.thpilotWebLoaded = '1'; const trustedTypesApi = window.trustedTypes; const trustedHTMLPolicy = (() => { if (!trustedTypesApi) return null; try { return trustedTypesApi.createPolicy( 'thpilot-ai-helper', { createHTML: value => value, }, ); } catch (error) { return trustedTypesApi.getPolicy?.( 'thpilot-ai-helper', ) || null; } })(); function toTrustedHTML(value) { const html = String(value ?? ''); return trustedHTMLPolicy ? trustedHTMLPolicy.createHTML(html) : html; } function setHTML(element, value) { element.innerHTML = toTrustedHTML(value); } function setShadowHTML(shadowRoot, value) { const html = String(value ?? ''); const styleMatch = html.match(/
解析原文
清理结果
聊天

开始与 AI 对话吧!

Enter 提交

Shift+Enter 换行

设置

点击编辑 点击收起
支持 OpenAI 兼容的 /chat/completions; type 为 image 时使用 /images/generations。 API Key 仅保存在 Tampermonkey 存储中。
点击编辑 点击收起
使用严格 JSON 数组格式,model 可指定模型列表中的模型标识, 未配置、无匹配项或对应 API Key 为空时使用全局模型。 支持 icon 和 replaceCallback;网址或系统协议可配置 action 为 "openUrl",Base64 解码可配置 action 为 "decodeBase64", Cambridge 查词可添加 {"id":"cambridgeLookup"}。 url 中用 {{selection}} 代表选中文字。 回调请填写字符串 "genericReplaceCallback"。
点击编辑 点击收起
支持 TavilyBrave Search API。 按数组顺序尝试多个账号;全部不可用后使用 DuckDuckGo。 格式:{"enable":true,"type":"tavily|brave","name":"账号名称","apiKey":"..."}。 name 是本地备注名,可自行填写,只用于区分账号和显示状态,不是登录账号或邮箱;真正识别 API 账号的是 apiKey。
Mac 会自动把 ctrl 转为 meta/cmd。
默认保留 500 条;减少后会删除最早的超额会话。
每行填写一个域名,同时禁用该域名及其所有子域名。 保存后刷新对应网页生效。

配置文件包含模型和搜索服务 API Key,请妥善保管,不要分享给他人。 配置与历史会话使用独立的 JSON 文件。

点击配置 点击收起

实时同步仅上传当前设备的数据,不合并或读取其他设备。 会话按文件增量备份,图片以二进制保存到 WebDAV;连接凭据不写入远程备份。

未同步

导入历史会话

请选择导入方式。合并会按会话 ID 去重并保留较新的记录; 覆盖会替换全部现有历史。超过最大保留条数的最旧记录将被删除。

会话历史

图片预览
`; } function iconBook() { return ` `; } function iconTranslate() { return ` `; } function iconCorrect() { return ` `; } function iconSummary() { return ` `; } function iconChat() { return ` `; } function iconPlus() { return ` `; } function iconMinimize() { return ` `; } function iconRestore() { return ` `; } function iconOutline() { return ` `; } function iconDownload() { return ` `; } function iconHistory() { return ` `; } function iconChevron() { return ` `; } function iconPin() { return ` `; } function iconClose() { return ` `; } function iconSend() { return ` `; } function iconStop() { return ` `; } function iconCopy() { return ` `; } function iconCode() { return ` `; } function iconEdit() { return ` `; } function iconInsert() { return ` `; } function iconRegenerate() { return ` `; } function iconDelete() { return ` `; } })();