主题
输入交互系统
本文引用的源码文件
本文引用的文件
目录
引言
本文件面向“输入交互系统”,聚焦侧边栏输入框及其周边能力:文本输入、富文本支持、智能补全、菜单面板系统、交互门控机制、提示词管理、输入历史、键盘快捷键、无障碍与移动端适配,以及输入验证与安全过滤。该系统由 Chrome 扩展端(Manifest V3)与独立本地 Agent 组成,用户输入在侧边栏完成,经后台进程调度后调用 Agent 的文件读写、命令执行、长期记忆与 RAG 等能力。
项目结构
输入交互系统主要位于 side_panel 模块,并与 background、content、agent 三处协同:
- side_panel:负责 UI 输入、提示词选择、菜单面板、交互门控、历史记录等。
- background:负责工具确认、会话状态、消息路由与保活。
- content:负责页面级表单与富文本输入模拟。
- agent:负责命令安全分级与执行策略。
graph TB subgraph "侧边栏" SP_Index["side_panel/index.js"] PM["prompt-manager.js"] IAP["input-add-menu-panel.js"] IH["input-history.js"] IG["interaction-gate.js"] end subgraph "后台进程" BG["background/react-loop.js"] end subgraph "内容脚本" CT["content/interaction-tools.js"] end subgraph "本地代理" AG["agent/src/security.js"] end SP_Index --> PM SP_Index --> IAP SP_Index --> IH SP_Index --> IG PM --> BG IAP --> PM IG --> BG BG --> AG SP_Index --> CT
图表来源
- src/side_panel/index.js#L700-L900
- src/side_panel/prompt-manager.js#L18-L52
- src/side_panel/input-add-menu-panel.js#L1-L46
- src/side_panel/input-history.js#L1-L44
- src/side_panel/interaction-gate.js#L1-L30
- src/background/react-loop.js#L262-L285
- src/content/interaction-tools.js#L468-L476
- agent/src/security.js#L257-L283
章节来源
核心组件
- 输入框与划词浮层:提供基础文本输入、选中上下文注入、浮动快捷菜单。
- 提示词管理器:提示词模板库、搜索合并视图、变量替换与上下文注入、发送链路。
- “+”二级菜单面板:分类数据加载、搜索过滤、多选/单选、动态管理入口。
- 交互门控:确认/澄清弹窗单模态排队、呈现回执、超时计时起点控制。
- 输入历史:去重、容量限制、持久化。
- 页面输入工具:键盘事件模拟、富文本编辑器写入、结果反馈。
- 命令安全:Agent 端命令替换特征检测与白名单纠偏。
章节来源
- src/side_panel/index.js#L700-L900
- src/side_panel/prompt-manager.js#L18-L52
- src/side_panel/input-add-menu-panel.js#L1-L46
- src/side_panel/interaction-gate.js#L1-L30
- src/side_panel/input-history.js#L1-L44
- src/content/interaction-tools.js#L468-L476
- agent/src/security.js#L257-L283
架构总览
输入交互从用户键入或点击触发开始,经过提示词/技能/MCP/知识库/网页/工作目录等上下文组装,最终进入后台工具执行与 Agent 安全校验。
sequenceDiagram participant U as "用户" participant SP as "侧边栏(index.js)" participant PM as "提示词(ppt-manager.js)" participant IAP as "二级菜单(input-add-menu-panel.js)" participant BG as "后台(react-loop.js)" participant CT as "内容脚本(interaction-tools.js)" participant AG as "代理(security.js)" U->>SP : 输入/选择提示词/打开菜单 SP->>PM : 渲染/搜索/插入提示词 SP->>IAP : 打开分类面板并加载数据 PM->>SP : 组装上下文(技能/MCP/知识/网页/文件) SP->>BG : 发送请求/发起工具调用 BG->>AG : 命令安全检查 AG-->>BG : 允许/确认/拒绝 BG->>CT : 页面输入/富文本写入 CT-->>BG : 执行结果 BG-->>SP : 流式响应/完成
图表来源
- src/side_panel/index.js#L700-L900
- src/side_panel/prompt-manager.js#L620-L800
- src/side_panel/input-add-menu-panel.js#L173-L231
- src/background/react-loop.js#L262-L285
- src/content/interaction-tools.js#L468-L476
- agent/src/security.js#L257-L283
详细组件分析
输入框与划词浮层
- 功能要点
- 基础文本输入与自动高度调整。
- 基于选中文本的浮动菜单,展示已启用“在菜单中显示”的提示词项。
- 点击浮层项后,将选中内容作为上下文注入,再发送提示词。
- 关键流程
- 计算浮层位置,避免溢出视口。
- 过滤出 enabledInMenu=true 的提示词,渲染为可点击项。
- 点击后隐藏浮层、压缩上下文、追加气泡、记录历史并发送。
flowchart TD
Start(["打开浮层"]) --> Filter["过滤启用菜单的提示词"]
Filter --> Render["渲染菜单项"]
Render --> Position["计算位置与边界"]
Position --> Show["显示浮层"]
Show --> Click{"用户点击某项?"}
Click --> |否| Hide["保持显示"]
Click --> |是| Inject["注入选中上下文"]
Inject --> Send["发送提示词"]
Send --> End(["结束"])
图表来源
章节来源
提示词管理系统
- 功能要点
- 提示词模板库:编码+内容,拖拽排序,管理按钮。
- 下拉选择器:Tab 模式(提示词/技能/MCP)与合并搜索模式。
- 变量替换与上下文注入:技能、MCP、知识库、网页、文件、引用/选中内容。
- 发送链路:半自动压缩、消息构建、历史保存、输入历史追加。
- 关键实现
- showPromptSelector/hidePromptSelector 控制下拉可见性。
- renderMergedList 聚合搜索,统一导航与选择行为。
- insertPromptToInputByCode 支持 skipTriggerStrip,用于菜单面板 Ctrl+点击场景。
- sendPromptByCode 组装上下文、构建 userContent、调用 callApi。
classDiagram
class PromptManager {
+showPromptSelector(filterText, targetTab)
+hidePromptSelector()
+renderMergedList(filterText)
+insertPromptToInputByCode(code, options)
+sendPromptByCode(code)
}
class State {
+customPrompts
+selectedSkills
+selectedMcpServices
+knowledgeRefs
+selectedPage
+attachedFiles
}
class ChatManager {
+callApi()
+addMessage()
+buildUserContent()
}
PromptManager --> State : "读取/更新"
PromptManager --> ChatManager : "发送消息"
图表来源
- src/side_panel/prompt-manager.js#L18-L52
- src/side_panel/prompt-manager.js#L195-L244
- src/side_panel/prompt-manager.js#L370-L518
- src/side_panel/prompt-manager.js#L570-L619
- src/side_panel/prompt-manager.js#L620-L800
章节来源
- src/side_panel/prompt-manager.js#L18-L52
- src/side_panel/prompt-manager.js#L195-L244
- src/side_panel/prompt-manager.js#L370-L518
- src/side_panel/prompt-manager.js#L570-L619
- src/side_panel/prompt-manager.js#L620-L800
菜单面板系统(“+”二级面板)
- 功能要点
- 分类:提示词、技能、MCP、网页、知识库、助手、代理、工作目录、截图动作。
- 搜索过滤:按类别字段进行本地即时过滤;截图类隐藏搜索框。
- 管理入口:不同类别对应不同管理动作(提示词管理、设置页、新建/编辑、工作目录面板等)。
- 选择行为:普通点击与 Ctrl/Cmd+点击语义区分;多选类别保持展开。
- 关键实现
- openCategoryPanel/closeCategoryPanel 控制面板生命周期与数据加载。
- fetchCategoryData 根据类别拉取数据;workspace 仅加载根一层。
- filterDataset/renderList 处理搜索与渲染;handleItemClick 分发选择动作。
flowchart TD
Open["openCategoryPanel(category)"] --> Load["fetchCategoryData(category)"]
Load --> Data["dataset = 数据数组"]
Data --> Search["filterDataset(query)"]
Search --> Render["renderList()"]
Render --> Click{"handleItemClick"}
Click --> Action["按类别执行选择/发送/打开管理"]
Action --> Close["onRequestClose()"]
图表来源
- src/side_panel/input-add-menu-panel.js#L173-L231
- src/side_panel/input-add-menu-panel.js#L233-L322
- src/side_panel/input-add-menu-panel.js#L412-L480
章节来源
- src/side_panel/input-add-menu-panel.js#L1-L46
- src/side_panel/input-add-menu-panel.js#L173-L231
- src/side_panel/input-add-menu-panel.js#L233-L322
- src/side_panel/input-add-menu-panel.js#L412-L480
交互门控机制(意图识别、预筛选、安全检查)
- 用户意图识别
- 通过提示词/技能/MCP/知识库/网页/工作目录等上下文组合表达意图。
- 合并搜索模式下,提示词、技能、MCP 统一检索,便于快速定位目标。
- 工具预筛选
- 调用主力模型前使用轻量 API 预筛选工具集合,减少后续开销。
- 安全检查
- Agent 端对命令替换特征进行白名单纠偏,避免误报导致绝对禁止。
- 敏感操作需用户确认,确认倒计时仅在交互真正呈现后启动。
sequenceDiagram participant UI as "UI(提示词/技能/MCP)" participant Gate as "交互门控(interaction-gate.js)" participant BG as "后台(react-loop.js)" participant AG as "代理(security.js)" UI->>Gate : requestDisplay(kind) alt 闸门空闲 Gate->>Gate : presentKind(kind) Gate->>BG : reportInteractionDisplayed(kind,item) else 闸门被占用 Gate->>Gate : waitingKinds.push(kind) end BG->>AG : 命令安全检查 AG-->>BG : allow/confirm/deny
图表来源
- src/side_panel/interaction-gate.js#L30-L93
- src/side_panel/interaction-gate.js#L132-L152
- src/background/react-loop.js#L262-L285
- agent/src/security.js#L257-L283
章节来源
- src/side_panel/interaction-gate.js#L1-L30
- src/side_panel/interaction-gate.js#L30-L93
- src/side_panel/interaction-gate.js#L132-L152
- src/background/react-loop.js#L262-L285
- agent/src/security.js#L257-L283
输入历史记录
- 功能要点
- 去重:相同文本只保留最新一条。
- 容量限制:最多 20 条,超出移除最旧条目。
- 持久化:保存到 chrome.storage.local。
- 使用场景
- 提示词发送后、划词问答发送后,将提示词正文加入历史,便于快速复用。
flowchart TD
Add["addToInputHistory(text)"] --> Trim["trim 与空值检查"]
Trim --> Exists{"是否重复?"}
Exists --> |是| Remove["移除旧条目"]
Exists --> |否| Keep["保留"]
Remove --> Push["push 到末尾"]
Keep --> Push
Push --> Limit{"超过20条?"}
Limit --> |是| Shift["shift 移除最旧"]
Limit --> |否| Save["saveInputHistory()"]
Shift --> Save
图表来源
章节来源
页面输入与富文本支持
- 功能要点
- 键盘事件模拟:focus → keydown → keypress → input → keyup → blur,兼容 React/Vue 受控组件。
- 富文本编辑器:contenteditable 元素通过 execCommand 或 dispatch InputEvent 写入。
- 结果反馈:成功时返回包含变化提示的消息。
- 测试覆盖
- checkbox 拒绝文本输入、value 为空报错、contenteditable 走富文本路径。
flowchart TD
Target["定位目标元素"] --> Type{"是否 contenteditable?"}
Type --> |是| Rich["execCommand/Dispatch InputEvent"]
Type --> |否| Keys["模拟完整键盘事件链"]
Rich --> Wait["等待 DOM/URL 变化"]
Keys --> Wait
Wait --> Result["返回 success 与变化提示"]
图表来源
章节来源
自定义输入组件示例(代码片段路径)
- 在侧边栏中插入自定义输入组件并接入提示词发送链路:
- 在二级菜单面板中接入自定义分类数据与选择动作:
- 在内容脚本中实现复杂表单输入(含富文本):
章节来源
- src/side_panel/prompt-manager.js#L570-L619
- src/side_panel/input-add-menu-panel.js#L217-L231
- src/content/interaction-tools.js#L468-L476
依赖关系分析
- 组件耦合
- index.js 作为侧边栏入口,协调提示词、菜单面板、历史记录、交互门控等。
- prompt-manager.js 依赖 skill-selector、page-selector、agent-at-selector、chat-manager 等模块。
- input-add-menu-panel.js 复用 skill-selector、agent-at-selector、workspace-panel、image-helpers 等。
- interaction-gate.js 与 background/react-loop.js 通过消息协议协作。
- 外部依赖
- chrome.runtime.sendMessage 用于跨进程通信。
- chrome.storage.local 用于持久化输入历史。
- Agent 端 security.js 提供命令安全策略。
graph LR Index["index.js"] --> PM["prompt-manager.js"] Index --> IAP["input-add-menu-panel.js"] Index --> IH["input-history.js"] Index --> IG["interaction-gate.js"] PM --> Skill["skill-selector.js"] PM --> Page["page-selector.js"] PM --> AtSel["agent-at-selector.js"] PM --> Chat["chat-manager.js"] IAP --> Skill IAP --> AtSel IAP --> WS["workspace-panel.js"] IG --> BG["background/react-loop.js"] BG --> Sec["agent/security.js"]
图表来源
- src/side_panel/index.js#L1-L34
- src/side_panel/prompt-manager.js#L1-L16
- src/side_panel/input-add-menu-panel.js#L24-L45
- src/side_panel/interaction-gate.js#L15-L30
- src/background/react-loop.js#L262-L285
- agent/src/security.js#L257-L283
章节来源
- src/side_panel/index.js#L1-L34
- src/side_panel/prompt-manager.js#L1-L16
- src/side_panel/input-add-menu-panel.js#L24-L45
- src/side_panel/interaction-gate.js#L15-L30
性能与体验考量
- Token 预算与上下文压缩
- 发送前阈值驱动的半自动压缩,失败不阻塞本次发送。
- 共享函数 selectHistoryForSend 与 applyCompactionInjection 统一裁剪与摘要注入。
- 长对话质量保障
- 三级上下文压力监测、任务状态锚点,避免长对话质量下滑。
- 用户体验优化
- 输入框自动高度调整、浮动菜单自适应位置、快捷键提示。
- 二级菜单面板搜索即时过滤、无搜索类别隐藏搜索框。
- 交互门控确保用户有真实机会看到并响应确认/澄清弹窗。
章节来源
- src/side_panel/prompt-manager.js#L620-L800
- src/side_panel/index.js#L811-L900
- src/side_panel/input-add-menu-panel.js#L116-L120
- src/side_panel/interaction-gate.js#L132-L152
故障排查指南
- 确认弹窗无法拒绝
- 现象:未弹出确认即被判拒。
- 原因:确认与澄清弹窗同层级且澄清遮挡确认,导致用户不可见。
- 解决:使用交互门控排队,仅在真正呈现后上报 INTERACTION_DISPLAYED,后台据此启动超时。
- 命令被误报为危险
- 现象:只读/打印类命令被绝对禁止。
- 原因:命令替换特征黑名单过于严格。
- 解决:Agent 端采用白名单纠偏,仅对可疑子段送检,避免整串一票否决。
- 表单输入无效
- 现象:React/Vue 受控组件 value 不变。
- 原因:直接赋值未触发 onChange。
- 解决:使用键盘事件模拟完整事件链,或富文本路径写入。
章节来源
- src/side_panel/interaction-gate.js#L1-L30
- src/side_panel/interaction-gate.js#L132-L152
- agent/src/security.js#L257-L283
- src/content/interaction-tools.js#L468-L476
结论
输入交互系统以侧边栏为核心,围绕提示词管理、二级菜单面板、交互门控、输入历史与页面输入工具形成闭环。通过 Token 预算驱动压缩、上下文注入与 Agent 安全策略,系统在易用性与安全性之间取得平衡。建议在实际扩展中遵循现有接口契约,优先复用提示词与菜单面板能力,并在新增输入组件时对齐快捷键、无障碍与移动端适配规范。