feat: add initial Perplexity extension support#370
Conversation
There was a problem hiding this comment.
Pull request overview
为 Ophel 增加对 perplexity.ai 的首版站点适配,并补齐在真实站点验证中发现的若干兼容性问题,使注入、会话识别、标题同步、大纲/导出与 usage monitor 能在 Perplexity 上正常工作。
Changes:
- 新增 Perplexity 站点适配器并接入适配器注册/站点常量/默认配置
- 扩展注入范围与后台目标 URL 覆盖
perplexity.ai/www.perplexity.ai - 修复 usage monitor 统计逻辑(合并 selector 以覆盖用户消息与 AI 输出)并优化会话标题更新策略
Reviewed changes
Copilot reviewed 14 out of 14 changed files in this pull request and generated 6 comments.
Show a summary per file
| File | Description |
|---|---|
| src/utils/storage.ts | 为新站点补齐默认站点设置(主题/宽度/模式等) |
| src/tabs/options/pages/FeaturesPage.tsx | 历史统计曲线增加 Perplexity 站点筛选项 |
| src/core/usage-counter-manager.ts | 支持适配器提供 usage monitor 挂载锚点;修复“已加载输出”统计选择器合并 |
| src/core/conversation/manager.ts | 增加标题更新策略,避免 Perplexity slug 覆盖真实标题 |
| src/contents/ui-entry.tsx | 内容脚本注入匹配新增 Perplexity 域名,并纳入 shadow host 挂载判断 |
| src/contents/scroll-lock-main.ts | scroll-lock 内容脚本注入匹配新增 Perplexity 域名 |
| src/contents/monitor-entry.ts | monitor 内容脚本注入匹配新增 Perplexity 域名 |
| src/contents/main.ts | 主内容脚本注入匹配新增 Perplexity 域名;移除 adapter 加载时的 console.warn |
| src/constants/defaults.ts | 增加 SITE_IDS.PERPLEXITY 与平台列表项 |
| src/background.ts | 后台目标 URL 覆盖新增 Perplexity;通知 API 可用性判定改为可选 |
| src/adapters/perplexity.ts | 新增 Perplexity 适配器:会话识别、列表抓取、导出标记、大纲提取、宽度与 usage monitor 挂载等 |
| src/adapters/index.ts | 注册 PerplexityAdapter |
| src/adapters/base.ts | 为适配器新增 getUsageCounterMountAnchor 扩展点 |
| package.json | host_permissions / matches 新增 Perplexity 域名 |
代码审查总结一、Copilot Review 问题修复情况(6/6)
二、功能完整性审计大纲抽取,实测扫描不全 对比 🔴 必须补齐(核心功能缺失)
|
| 方法 | 功能 | 当前状态 | 影响 |
|---|---|---|---|
getCleanModeConfig() |
净化模式(隐藏广告/免责声明) | ❌ 返回 null → 无效果 | 页面冗余元素无法清理 |
getLatestReplyText() |
复制最新回复(Ctrl+Shift+C) | ❌ 返回 null → DOM 嗅探降级 | 快捷键复制可能失败或内容不完整 |
deleteConversationOnSite() |
删除会话 | ❌ 返回 {success: false} |
无法从 Ophel 侧边栏删除会话 |
三、代码质量问题
- base.ts:错位的中文注释("精准查找提交按钮")应完全删除,只保留新的英文 JSDoc
fetchThreadsViaApi:JSON.parse(await response.text())缺少 try-catch,API 返回异常时会崩溃fetchThreadsViaApi:fetch 调用缺少 AbortController 超时机制,可能无限挂起loadAllConversations():缺少并发保护标志,快速多次调用可能产生重复 API 请求
四、对现有功能的影响
零回归风险 — 所有对共享文件(background.ts、manager.ts、usage-counter-manager.ts、storage.ts 等)的改动都是纯扩展式的,不修改现有逻辑。Gemini/ChatGPT/Claude 等站点不受影响。
五、总结
作为「首版适配」仍有 6 个 SiteAdapter 关键方法未实现,导致禅模式、净化模式、模型锁定、主题同步、复制最新回复、会话删除等功能不可用。更关键的最核心功能大纲扫描不全,无法合并。
|
禅模式 / 净化模式 / 模型锁定 等这些功能平时我没有用到过,所以没想过测试这些。 |
OK,优先解决 大纲抽取缺失、主题模式切换未同步到宿主页面、禅模式这三个问题 下面这些为次优先级问题
|
|
辛苦🫶
完成后麻烦测试一下,包括 Chrome 之外的其他浏览器和油猴脚本 有问题随时与我联系~ |
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
Co-authored-by: LainElaina <1796137367@qq.com>
|
@urzeye 但模型锁定似乎在左侧会话栏快速切换会话的时候可能无法及时找到模型切换器的状态(尤其是perplexity可能在显示“深度研究”的时候并不显示模型切换器的组件。 其他的都已在chrome和edge测试,目前看起来扩展程序没有什么严重问题。 麻烦测试看看你的环境下有没有问题~ |
好的,等我晚会或明天看一下❤️ |
Co-authored-by: LainElaina <1796137367@qq.com>
urzeye
left a comment
There was a problem hiding this comment.
谢谢这次 Perplexity 支持的工作,能看出来你在真实站点上做了不少验证,也补了很多边界。但我现在不能接受这个 PR 直接合并,需要 request changes。
我这里最重要的合并标准是:不能为了新增某一个站点,把站点特有逻辑加进公共路径;不能为了一个功能引入不可控的 bug 风险;在这个基础上,性能和包体积也是硬约束。Ophel 同时有扩展版和油猴脚本版,油猴脚本有字符数/体积/解析成本限制,新增站点适配必须非常克制。这个 PR 当前新增 5000+ 行,其中 Perplexity adapter 单文件 4000+ 行,并且通过 adapter registry 进入公共 content/userscript bundle。你这里说的是“首版适配”,但实际包含了基础适配、远程删除/重命名、线程 API 预拉、模型持续锁定、主题、禅模式校准、Mermaid debug、通用大纲状态修复、通用会话同步改造等很多东西。这个范围太大,也很难安全 review。
几个主要阻塞点:
-
公共逻辑被 Perplexity 需求污染。
ConversationManager里硬编码SITE_IDS.PERPLEXITY,并新增当前会话轮询、URL 变化多次同步、远程 snapshot、sidebar mutation prune 等逻辑。站点适配应该封装在 adapter 内,公共 manager 不应该知道某个站点的特殊同步策略。 -
删除语义被全局改变。远程删除失败时本地也不删,这会影响所有支持远程删除的站点,也改变了用户对“从 Ophel 面板删除/清理”的预期。Perplexity 的远程删除可以做,但失败处理应限制在 Perplexity 适配层或 toast 中,不能改公共删除语义。
-
模型锁定方向不接受。这里的“模型锁定”更准确应该是“默认模型初始化”:进入页面后尝试设置一次默认模型即可。如果用户后面自己改了,或者站点自己改了,不需要持续抢回来。当前 PR 引入 persistent monitor、MutationObserver、多轮 relock watch 等复杂机制,我不接受为了 Perplexity 的模型选择引入这种复杂度。如果未来真要做严格锁定,那应该是另一个明确方案,比如请求层 hook,而不是通用 UI 操作链路里堆状态机。
-
包体积和性能风险过高。你这次新增的 Perplexity adapter 体量很大,并且不是按需加载。用户不访问 Perplexity,也会在公共脚本里承担下载、解析和初始化成本。油猴脚本尤其敏感,我已经看到整体包体积相比之前明显增大(约 +300KB、到 4.1MB 量级),这个趋势我不能接受。新增站点支持必须有体积控制方案,至少要考虑按 hostname 懒加载/拆 chunk,或者先做最小能力集。
-
远程线程列表不能被当作 authoritative。当前 API 最多拉有限页数,并不能证明完整,侧栏 DOM 也可能虚拟滚动/卸载。用它来 prune 本地会话有误删风险。首版适配应优先做可见 DOM 的新增/更新同步,不要默认做远端全量预拉和本地删除。
-
这个 PR 夹带了不少与 Perplexity 基础适配不直接相关的通用改动,例如 outline tree key、assistant mermaid selector fallback、storage adapter 兜底、模型 relock 节奏等。这些即使有价值,也应该独立 PR,单独说明问题、影响范围和验证结果。
我建议不要在当前 PR 上继续堆修修补补,而是拆分:
- PR 1:最小 Perplexity 支持,只包含站点识别、matches/permissions、输入框、当前会话 ID、基础会话标题、大纲提取、导出、必要的 usage counter 窄扩展点。
- PR 2:如果确实需要,单独做 Perplexity 远程删除/重命名,但逻辑必须限制在 Perplexity adapter 内,不能改变公共 manager 的删除语义。
- PR 3:如果要做默认模型,只做一次性默认模型尝试;不要 persistent lock。更复杂的真锁定另开设计讨论。
- PR 4:outline、Mermaid、storage、统计等通用修复分别拆小,按各自影响范围 review。
- 同时需要给出包体积变化说明,尤其是油猴脚本体积/字符数和是否能按需加载。
所以这次我先 request changes。不是否定 Perplexity 支持本身,而是当前 PR 的范围、性能成本、公共逻辑改动和维护风险都超过了我能接受的合并标准。
| new DeepSeekAdapter(), | ||
| new DoubaoAdapter(), | ||
| new ImaAdapter(), | ||
| new PerplexityAdapter(), |
There was a problem hiding this comment.
这里把 PerplexityAdapter 和其它 adapter 一样 eager import 并实例化,会让 4000+ 行 Perplexity 适配代码进入所有站点的 content/userscript 主包。这个 PR 的包体积已经有明显增长,而Greasy Fork 对油猴脚本本身有字符数限制,之前加“高级模型用量监控”已达上限,强行拆除了一部分代码出去。对我来说,新增单站点支持不能让所有用户都支付这部分体积和运行时成本。
建议先拆成最小可合并版本,或者把站点适配改成按 hostname 懒加载/按需动态导入;至少不能在没有体积控制方案的情况下直接把这么大的 adapter 放进公共入口。
| @@ -137,6 +142,8 @@ export class ConversationManager { | |||
| } | |||
There was a problem hiding this comment.
这里开始在所有站点初始化当前会话轮询同步,不应该放进通用逻辑。Perplexity 可能需要额外同步当前线程标题/URL,但这个行为会影响所有适配器:每个站点都会持续读取宿主页状态并写回 store,可能覆盖用户在 Ophel 面板里的手动标题、导入数据或其它本地编辑。
单站点适配需要 opt-in,不能为了 Perplexity 改变所有站点的会话同步模型。建议增加明确的 adapter capability,默认关闭,只在 Perplexity 内部启用,并且最好限制同步窗口而不是长期轮询。
| } | ||
|
|
||
| const scheduleConversationSync = () => { | ||
| clearPendingTimers() |
There was a problem hiding this comment.
这里每次 gh-url-change 都排 5 个定时器去同步当前会话,同样是 Perplexity 需求溢出到公共 UI 层。URL 变化是所有站点都会触发的高频路径,这会增加额外 store 写入、UI 刷新和标题覆盖风险。
如果 Perplexity 需要路由切换后补同步,应该由 Perplexity adapter 或专用 capability 驱动,不能在 App 里对所有站点加固定节奏的重试。
| const remoteAttempted = remoteEnabled && remoteResultMap.has(id) && remoteMethod !== "none" | ||
| const remoteSuccess = remoteAttempted && (remoteItem?.success || false) | ||
| const shouldDeleteLocal = exists && (!remoteAttempted || remoteSuccess) | ||
|
|
There was a problem hiding this comment.
这里改变了所有站点的删除语义:只要远程删除尝试过但失败,本地就不删除。这个行为不是 Perplexity 适配的必要条件,而且会让原本的“从 Ophel 面板本地清理”被远程失败阻塞。
远程删除的失败处理应该限制在具体站点能力里,不能反向改变公共 ConversationManager 的本地删除语义。建议恢复原语义,Perplexity 如需特殊提示或保护,放在 Perplexity adapter 返回结果和 UI toast 中处理。
| return this.mergeConversationInfos(cachedList, domList, currentList) | ||
| } | ||
|
|
||
| hasAuthoritativeConversationList(): boolean { |
There was a problem hiding this comment.
这里把缓存有效期内的线程列表标记为 authoritative 有误删风险。下面的 API 拉取最多 5 页、每页 100 条,并不能证明拿到了完整远端列表;Perplexity 侧边栏也可能虚拟滚动/卸载 DOM 节点。如果后续公共 manager 依据这个 authoritative list 删除本地记录,会把“没加载到/没拉全”的会话误判成已删除。
建议不要用这个标记驱动本地删除,除非能确认远端返回完整列表;否则最多只做新增/更新同步,不做 prune。
| @@ -746,7 +746,17 @@ export class OutlineManager { | |||
| "|" + | |||
There was a problem hiding this comment.
这个 tree key / state key 的调整不像 Perplexity 适配的必要改动,更像通用大纲状态稳定性修复。它可能是对的,但放在这个 PR 里会扩大审查面:既要审 Perplexity,又要审所有站点的大纲折叠/书签/状态恢复行为。
建议拆成独立 PR,单独说明要修复的问题和验证范围。Perplexity 首版适配不应该夹带这类通用行为变更。
| @@ -492,7 +492,25 @@ export class AssistantMermaidRenderer { | |||
| } | |||
There was a problem hiding this comment.
这里从 export selector 回退到 chat content selector 的思路可以理解,因为 Perplexity 的导出 selector 是临时标记型 selector。不过这也是通用 Mermaid 渲染路径的行为变化,会影响所有使用 data-gh-* 导出标记的站点。
建议把这个变更拆成独立修复,或让 adapter 显式提供 assistant mermaid selector,而不是在 renderer 里根据 selector 字符串包含 data-gh- 做隐式判断。
| if (result.localDeletedCount === 0) { | ||
| showToast(t("deleteError") || "删除失败") | ||
| const firstReason = | ||
| result.results.find((item) => item.reason)?.reason || undefined |
There was a problem hiding this comment.
把远程删除失败 reason 展示出来是有帮助的,可以保留。
但这里的 UI 提示不能掩盖更大的行为变化:公共 manager 已经变成远程失败时本地也不删除。这个策略我不接受作为通用行为。建议 UI 只负责展示结果,删除语义恢复到原来的本地清理逻辑;Perplexity 的远程删除失败可作为附加提示。
| @@ -96,6 +96,11 @@ const userscriptStorageAdapter: StateStorage = { | |||
| const extensionStorageAdapter: StateStorage = { | |||
There was a problem hiding this comment.
这个兜底和 Perplexity 适配无关,建议从 PR 移除。更重要的是,extension 构建里如果 chrome.storage.local 不存在,静默返回 null/resolve 会掩盖平台选择或运行环境错误,可能导致用户数据看起来像“空数据”。
这类平台存储行为必须单独讨论和验证,不能夹在站点适配 PR 里。
| @@ -681,7 +681,7 @@ export function initUrlChangeObserver(ctx: ModulesContext): void { | |||
| modules.usageCounterManager?.handleUrlChange() | |||
There was a problem hiding this comment.
这里把所有站点的模型 relock 延迟从 300ms 改成 80ms,并配合 ModelLocker 里的多轮 watcher,会增加路由切换时的 DOM 查询和 UI 操作频率。这个改动不是 Perplexity 基础适配的必要条件,也会影响现有站点。
建议恢复原行为;Perplexity 的默认模型问题不要通过改变全站 relock 节奏解决。
|
我目前只看了代码,没有实际做各种测试,先补充一个整体判断。 感谢做 Perplexity 适配,也能看出来在真实站点上花了不少时间验证。但我现在很难接受这个 PR 以当前形态合并。原因不是“不想支持 Perplexity”,而是这个 PR 的范围、性能成本和架构影响都已经超过了我对这个项目的合并标准。 Ophel 同时要支持浏览器扩展和油猴脚本。油猴脚本不是普通 Web app,Greasy Fork 对它有字符数/体积等现实限制;扩展版也同样要考虑 content script 的下载、解析、注入和运行时成本。现在引入任何东西都必须非常慎重。如果某个功能会明显影响稳定性、性能或可维护性,我宁可先不要这个功能,也不会为了“功能完整”接受不可控的实现。 这次 PR 有几个全局问题:
我建议这个 PR 不要继续按当前结构修到可合并,而是拆分:
所以我这次已经 request changes。再次感谢你做这个适配,但我对功能、性能、包体积、bug 可控性、架构边界和可维护性的要求会比较严格。Perplexity 可以支持,但必须用更小、更可控、更不会影响其它站点的方式合进来。 明天我会先进行一些必要的测试,在这个 PR 的基础上进行拆分,再次感谢 PR 🫶 |
|
收到,有一部分目前做的过头了。我再拉一个新分支只做对perplexity的最小支持,后续其他内容看需求补其他PR。 |
也是我上面第一次的评论里没和你讲清楚,项目也缺少一些必要的开发文档,导致出现了一些偏差。 周末我有时间也会一起做这个PR 的改造 |
|
最近这段时间在忙别的。 |
我的账号也已经用不了了🥲 根据我的观察,貌似现在用perplexity网页版的人并不多了,还在用perplexity的人也就用它的api进行搜索或者使用perplexity computer客户端,所以适配网页的工作暂停了。 其实不只是perplexity ,其他新AI站点的适配我也都停了,相关issue已经关闭。 近期Gemini, ChatGPT , AI Studio等网页集体改版,最近的重心都在新dom结构适配、bug修复和已有功能优化上,已经很多个版本没有加入新功能了。 这个PR暂时保留,我们根据后续情况再看是否要继续进行合并与新站点的适配吧。 这个pr里之前还包含高级模型使用统计相关的问题修复吧,也许可以拆出来只做一个影响范围小的fix。 无比感谢你的贡献和付出❤️❤️❤️ |





描述 Description
为 Ophel 增加 Perplexity 首版适配,并补齐在真实站点验证中发现的若干兼容性问题,使核心功能可以在
perplexity.ai上正常工作。本 PR 主要包含:
本次修改已经过人工自查,并在真实登录状态下完成了手动验证。
变更类型 Type of change
关联 Issue Related Issues
Closes #33
Closes #337
测试情况 Testing
已执行:
corepack pnpm installcorepack pnpm typechecknode scripts/prepare-mermaid-assets.mjscorepack pnpm exec plasmo buildcorepack pnpm exec plasmo package手动实测内容:
已加载输出统计正常测试环境 Test Environment:
视觉变化 Visual Changes
已附截图,展示以下内容:


检查清单 Checklist