agentpage 0.0.40 → 0.0.41
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.
- package/README.md +17 -1
- package/dist/index.d.mts +11 -1
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +42 -10
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["sleep","sleep","sleep","convertMessages"],"sources":["../src/core/agent-loop/constants.ts","../src/core/agent-loop/helpers.ts","../src/core/agent-loop/snapshot.ts","../src/core/agent-loop/messages.ts","../src/core/agent-loop/recovery.ts","../src/core/agent-loop/index.ts","../src/core/ai-client/constants.ts","../src/core/ai-client/sse.ts","../src/core/ai-client/custom.ts","../src/core/ai-client/openai.ts","../src/core/ai-client/anthropic.ts","../src/core/ai-client/deepseek.ts","../src/core/ai-client/doubao.ts","../src/core/ai-client/qwen.ts","../src/core/ai-client/index.ts","../src/core/tool-registry.ts","../src/core/system-prompt.ts","../src/web/event-listener-tracker.ts","../src/web/tools/dom-tool.ts","../src/web/tools/page-info-tool.ts","../src/web/tools/navigate-tool.ts","../src/web/tools/wait-tool.ts","../src/web/tools/evaluate-tool.ts","../src/web/ref-store.ts","../src/web/ui/styles.ts","../src/web/ui/logo-data.ts","../src/web/ui/icons.ts","../src/web/ui/panel.ts","../src/web/messaging.ts","../src/web/index.ts"],"sourcesContent":["/**\n * Agent Loop 默认配置常量。\n *\n * 统一集中在该文件,避免在主循环中散落“魔法数字”。\n */\nexport const DEFAULT_MAX_ROUNDS = 40;\nexport const DEFAULT_RECOVERY_WAIT_MS = 100;\nexport const DEFAULT_ACTION_RECOVERY_ROUNDS = 2;\nexport const DEFAULT_NOT_FOUND_RETRY_ROUNDS = 2;\nexport const DEFAULT_NOT_FOUND_RETRY_WAIT_MS = 1000;\nexport const DEFAULT_ROUND_STABILITY_WAIT_TIMEOUT_MS = 4000;\nexport const DEFAULT_ROUND_STABILITY_WAIT_QUIET_MS = 200;\nexport const DEFAULT_ROUND_STABILITY_WAIT_LOADING_SELECTORS = [\n\t\".ant-spin\",\n\t\".ant-spin-spinning\",\n\t\".ant-skeleton\",\n\t\".el-loading-mask\",\n\t\".bk-loading\",\n\t\".bk-spin-loading\",\n\t\".bk-skeleton\",\n\t\".bk-sideslider-loading\",\n\t\".t-loading\",\n\t\".t-skeleton\",\n\t\".t-skeleton__row\",\n\t\"[aria-busy=\\\"true\\\"]\",\n\t\".skeleton\",\n\t\".loading\",\n];\n// ─── DOM 快照去重标记 ───\n\n/** 快照起始标记 — 用于在消息中识别快照边界 */\nexport const SNAPSHOT_START = \"<!-- SNAPSHOT_START -->\";\n/** 快照结束标记 */\nexport const SNAPSHOT_END = \"<!-- SNAPSHOT_END -->\";\n/** 旧快照被替换后的占位文本 */\nexport const SNAPSHOT_OUTDATED = \"[此快照已过期,请参考对话中最新的快照]\";","/**\n * Agent Loop 辅助函数。\n *\n * 这个文件只放“纯函数”:\n * - 不访问外部可变状态\n * - 不做网络/DOM/I/O\n * - 输入相同,输出稳定\n *\n * 目的:把 index.ts 里的协议解析、文本规整、判定逻辑拆出来,\n * 让主循环只负责编排流程,方便阅读、测试和后续扩展。\n *\n * 函数能力速览:\n * - 基础工具:\n * - `sleep`:异步等待\n * - `toContentString`:统一工具结果内容为字符串\n * - 快照相关:\n * - `parseSnapshotExpandHints`:解析 `SNAPSHOT_HINT: EXPAND_CHILDREN`\n * - `extractHashSelectorRef`:从 `#ref` 选择器提取 ref id\n * - 任务推进与协议:\n * - `buildTaskArray`:将工具调用规整成稳定任务数组\n * - `normalizeModelOutput`:压缩模型输出供下一轮上下文使用\n * - `parseRemainingInstruction`:解析 `REMAINING` 协议\n * - `deriveNextInstruction`:推导下一轮 remaining(有协议优先)\n * - `reduceRemainingHeuristically`:协议缺失时做启发式推进\n * - 执行控制:\n * - `shouldForceRoundBreak`:判断动作后是否应断轮\n * - `collectMissingTask`:提取“元素未找到”任务用于重试流\n * - 错误与参数判定:\n * - `isElementNotFoundResult`:识别元素未找到错误\n * - `buildToolCallKey`:生成稳定调用键\n * - `resolveRecoveryWaitMs`:解析恢复等待时长\n * - `getToolAction`:读取工具输入里的 action\n * - `hasToolError`:判断结果是否标记为错误\n */\nimport type { ToolCallResult } from \"../tool-registry.js\";\nimport { DEFAULT_RECOVERY_WAIT_MS } from \"./constants.js\";\n\n/**\n * 异步睡眠。\n *\n * 用于重试等待、节流等待等场景。\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * 统一内容为字符串。\n *\n * 工具返回 content 可能是 string 或 object;这里统一转成 string,\n * 便于日志、错误判定、摘要拼接。\n */\nexport function toContentString(content: ToolCallResult[\"content\"]): string {\n return typeof content === \"string\" ? content : JSON.stringify(content, null, 2);\n}\n\n/**\n * 解析快照放宽提示。\n *\n * 约定格式:`SNAPSHOT_HINT: EXPAND_CHILDREN #ref1 #ref2`\n *\n * 返回:去掉 `#` 前缀后的 ref id 列表。\n */\nexport function parseSnapshotExpandHints(text: string | undefined): string[] {\n if (!text) return [];\n const refs: string[] = [];\n const regex = /^\\s*SNAPSHOT_HINT\\s*:\\s*EXPAND_CHILDREN\\s+(.+)$/gim;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n const tail = match[1] ?? \"\";\n const tokens = tail.match(/#[A-Za-z0-9_-]+/g) ?? [];\n for (const token of tokens) refs.push(token.replace(/^#/, \"\"));\n }\n return refs;\n}\n\n/**\n * 提取 hash selector 的 ref。\n *\n * 仅处理“纯 hash 选择器”,例如 `#1rv01x`。\n * 如果是复杂 CSS(如 `.x #id`)会返回 null,避免误判。\n */\nexport function extractHashSelectorRef(toolInput: unknown): string | null {\n if (!toolInput || typeof toolInput !== \"object\") return null;\n const selector = (toolInput as { selector?: unknown }).selector;\n if (typeof selector !== \"string\") return null;\n const m = selector.trim().match(/^#([A-Za-z0-9_-]+)$/);\n return m ? m[1] : null;\n}\n\n/**\n * 构建任务数组。\n *\n * 作用:把一轮工具调用规整成稳定字符串数组,\n * 用于“上一轮任务回显”和“重复批次检测”。\n */\nexport function buildTaskArray(toolCalls: Array<{ name: string; input: unknown }>): string[] {\n return toolCalls.map(tc => `${tc.name}:${JSON.stringify(tc.input)}`);\n}\n\n/**\n * 规范化模型输出。\n *\n * 优先保留 REMAINING;否则保留首段摘要,避免长文本污染上下文。\n *\n * 返回字符串会被注入下一轮消息,作为“上一轮模型输出摘要”。\n */\nexport function normalizeModelOutput(text: string | undefined): string {\n if (!text) return \"\";\n const trimmed = text.trim();\n if (!trimmed) return \"\";\n const remainingMatch = trimmed.match(/REMAINING\\s*:\\s*([\\s\\S]*)$/i);\n if (remainingMatch) return `REMAINING: ${remainingMatch[1].trim()}`;\n const firstBlock = trimmed.split(/\\n\\s*\\n/)[0]?.trim() ?? trimmed;\n return firstBlock.slice(0, 220);\n}\n\n/**\n * 解析 REMAINING。\n *\n * 返回值:\n * - `\"\"` 表示 DONE\n * - 非空字符串表示新的 remaining\n * - `null` 表示协议缺失\n *\n * 注意:这里只负责解析,不负责 fallback 策略。\n *\n * 解析策略:\n * - 匹配最后一个 `REMAINING:` 后到行尾的内容(单行匹配,不跨行)\n * - `REMAINING: DONE` → 返回 `\"\"`(任务完成)\n * - `REMAINING: <text>` → 返回 `<text>`\n * - DONE 后面尾随的摘要文本会被忽略(模型常在 DONE 后附加总结)\n */\nexport function parseRemainingInstruction(text: string | undefined): string | null {\n if (!text) return null;\n // 按行从后往前找最后一个 REMAINING: 行(模型可能在 DONE 后输出总结文本)\n const lines = text.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const lineMatch = lines[i].match(/REMAINING\\s*:\\s*(.*)$/i);\n if (lineMatch) {\n const value = lineMatch[1].trim();\n // 兼容 `REMAINING: DONE - xxx` / `REMAINING: DONE: xxx` 等写法\n if (/^done(?:\\s*(?:[-—::]|\\b).*)?$/i.test(value)) return \"\";\n return value;\n }\n }\n return null;\n}\n\n/**\n * 推导下一轮 remaining。\n *\n * 策略:\n * - 有 REMAINING 协议 -> 使用模型给出的 nextInstruction\n * - 无协议 -> 保持 currentInstruction 不变(由上层决定是否启发式推进)\n */\nexport function deriveNextInstruction(\n text: string | undefined,\n currentInstruction: string,\n): { nextInstruction: string; hasRemainingProtocol: boolean } {\n const parsed = parseRemainingInstruction(text);\n if (parsed !== null) {\n return { nextInstruction: parsed, hasRemainingProtocol: true };\n }\n return { nextInstruction: currentInstruction, hasRemainingProtocol: false };\n}\n\n/**\n * 启发式剔除 remaining。\n *\n * 用于协议缺失但本轮有执行动作时,按线性步骤剔除已执行数量。\n *\n * 这是“保守推进”策略,不保证语义完美,但能避免 remaining 长期不变。\n */\nexport function reduceRemainingHeuristically(\n currentInstruction: string,\n executedCount: number,\n): string {\n if (!currentInstruction.trim() || executedCount <= 0) return currentInstruction;\n\n const normalized = currentInstruction\n .replace(/\\s+/g, \" \")\n .replace(/(->|=>|→)/g, \" 然后 \")\n .replace(/[,,。;;]/g, \" 然后 \");\n\n const parts = normalized\n .split(/\\s*(?:然后|再|并且|并|接着|随后|之后)\\s*/g)\n .map(part => part.trim())\n .filter(Boolean);\n\n if (parts.length <= 1) return currentInstruction;\n\n const nextParts = parts.slice(Math.min(executedCount, parts.length));\n if (nextParts.length === 0) return \"\";\n return nextParts.join(\" -> \");\n}\n\n/**\n * 判定是否强制断轮。\n *\n * 语义:潜在 DOM 结构变化动作后,等待下一轮新快照。\n *\n * 当前规则:\n * - `navigate.*` 一律断轮\n * - `dom.press` 仅 Enter 断轮\n * - `evaluate` 断轮\n * - 其他动作默认不断轮\n */\nexport function shouldForceRoundBreak(toolName: string, toolInput: unknown): boolean {\n const action = getToolAction(toolInput);\n\n if (toolName === \"navigate\") {\n return action === \"goto\" || action === \"back\" || action === \"forward\" || action === \"reload\";\n }\n\n if (toolName === \"dom\") {\n if (action === \"click\") return true;\n if (action === \"press\") {\n const key = typeof toolInput === \"object\" && toolInput !== null\n ? String((toolInput as { key?: unknown; value?: unknown }).key ?? (toolInput as { value?: unknown }).value ?? \"\")\n : \"\";\n return key === \"Enter\";\n }\n return false;\n }\n\n return toolName === \"evaluate\";\n}\n\n/**\n * 判定动作是否可能引发页面结构或状态变化。\n *\n * 用于“轮次后稳定等待”触发条件:\n * - 命中 true:本轮结束后执行加载态 + DOM 静默双重等待\n * - 命中 false:跳过等待,直接进入下一轮\n */\nexport function isPotentialDomMutation(toolName: string, toolInput: unknown): boolean {\n const action = getToolAction(toolInput);\n\n if (toolName === \"navigate\") return true;\n if (toolName === \"evaluate\") return true;\n if (toolName !== \"dom\") return false;\n\n if (!action) return false;\n return [\n \"click\",\n \"fill\",\n \"select_option\",\n \"clear\",\n \"check\",\n \"uncheck\",\n \"type\",\n \"focus\",\n \"hover\",\n \"scroll\",\n \"press\",\n \"set_attr\",\n \"add_class\",\n \"remove_class\",\n ].includes(action);\n}\n\n/**\n * 采集找不到元素任务。\n *\n * 返回 null 表示当前结果不属于“元素未找到”,\n * 返回对象表示可进入 not-found retry 对话流。\n */\nexport function collectMissingTask(\n name: string,\n input: unknown,\n result: ToolCallResult,\n): { name: string; input: unknown; reason: string } | null {\n if (!isElementNotFoundResult(result)) return null;\n return {\n name,\n input,\n reason: toContentString(result.content).slice(0, 240),\n };\n}\n\n/**\n * 元素不存在判定。\n *\n * 判定顺序:\n * 1) 优先看结构化错误码 `ELEMENT_NOT_FOUND`\n * 2) 回退看中文错误文本关键词(兼容历史结果格式)\n */\nexport function isElementNotFoundResult(result: ToolCallResult): boolean {\n const details = result.details;\n if (details && typeof details === \"object\") {\n const code = (details as { code?: unknown }).code;\n if (code === \"ELEMENT_NOT_FOUND\") return true;\n }\n\n const content = toContentString(result.content);\n return content.includes(\"未找到\") && content.includes(\"元素\");\n}\n\n/**\n * 生成稳定调用键。\n *\n * 用于 recoveryAttempts 的 map key(同名 + 同参数视为同一调用)。\n */\nexport function buildToolCallKey(name: string, input: unknown): string {\n return `${name}:${JSON.stringify(input)}`;\n}\n\n/**\n * 解析恢复等待时长。\n * 优先级:waitMs > waitSeconds > 默认值。\n *\n * 统一返回毫秒整数,且最小为 0。\n */\nexport function resolveRecoveryWaitMs(input: unknown): number {\n if (!input || typeof input !== \"object\") return DEFAULT_RECOVERY_WAIT_MS;\n\n const params = input as Record<string, unknown>;\n const waitMs = params.waitMs;\n if (typeof waitMs === \"number\" && Number.isFinite(waitMs)) {\n return Math.max(0, Math.floor(waitMs));\n }\n\n const waitSeconds = params.waitSeconds;\n if (typeof waitSeconds === \"number\" && Number.isFinite(waitSeconds)) {\n return Math.max(0, Math.floor(waitSeconds * 1000));\n }\n\n return DEFAULT_RECOVERY_WAIT_MS;\n}\n\n/**\n * 读取工具 action。\n *\n * 仅在 input 是对象且 action 为字符串时返回值,否则返回 undefined。\n */\nexport function getToolAction(input: unknown): string | undefined {\n if (!input || typeof input !== \"object\") return undefined;\n const action = (input as Record<string, unknown>).action;\n return typeof action === \"string\" ? action : undefined;\n}\n\n/**\n * 判定错误标记。\n *\n * 约定:`result.details.error === true` 视为错误结果。\n */\nexport function hasToolError(result: ToolCallResult): boolean {\n return result.details && typeof result.details === \"object\"\n ? Boolean((result.details as { error?: unknown }).error)\n : false;\n}\n","/**\n * DOM 快照生命周期管理。\n *\n * 负责 4 类能力:读取、包裹、去重、剥离。\n *\n * 快照读取主流程:\n * 1) 组装快照参数(默认偏完整性)\n * 2) 调用 `page_info.snapshot`\n * 3) 将工具返回内容统一成字符串\n * 4) 由消息层进行包裹与注入\n * 5) 在多轮对话中去重旧快照\n *\n * 调用链:\n * - `agent-loop/index.ts` 在“无快照、每轮结束、导航后、恢复后”触发读取。\n * - `messages.ts` 负责把最新快照注入到本轮上下文。\n * - 本文件只处理快照文本本身,不负责业务决策与停机判定。\n *\n * 压缩/剪枝实现位置:\n * - 具体算法在 `src/web/tools/page-info-tool.ts` 的 `generateSnapshot()`。\n * - 本文件通过 `readPageSnapshot()` 传参触发这些策略,不在 core 层直接操作 DOM。\n * - 这样保持分层:core 只声明策略参数,web 负责真实遍历与裁剪。\n */\nimport { ToolRegistry } from \"../tool-registry.js\";\nimport type { AIMessage } from \"../types.js\";\nimport {\n SNAPSHOT_END,\n SNAPSHOT_OUTDATED,\n SNAPSHOT_START,\n} from \"./constants.js\";\nimport { toContentString } from \"./helpers.js\";\n\n// ─── 快照读取 ───\n\n/**\n * 读取页面 URL。\n *\n * 步骤:\n * 1) 通过 registry 分发 `page_info.get_url`。\n * 2) 若 content 为字符串则直接返回。\n * 3) 否则返回 undefined,交由上层容错。\n *\n * 输入/输出:\n * - 输入:`ToolRegistry`\n * - 输出:`string | undefined`\n * - 副作用:无本地状态写入(仅发起一次工具调用)\n */\nexport async function readPageUrl(\n registry: ToolRegistry,\n): Promise<string | undefined> {\n const result = await registry.dispatch(\"page_info\", { action: \"get_url\" });\n return typeof result.content === \"string\" ? result.content : undefined;\n}\n\n/**\n * 读取页面快照。\n *\n * 默认关闭 viewportOnly,优先完整性。\n *\n * 步骤:\n * 1) 合并调用方 options 与默认值(深度/裁剪/剪枝/节点上限等)。\n * 2) 分发 `page_info.snapshot` 获取当前 DOM 文本快照。\n * 3) 使用 `toContentString` 归一化输出,避免 provider 差异导致结构不一致。\n * 4) 返回稳定字符串给 loop,供后续注入消息与统计。\n *\n * 默认参数意图:\n * - `maxDepth=12`: 保留更深层级,减少深层组件控件被截断。\n * - `viewportOnly=false`: 优先完整性,避免误判“元素不存在”。\n * - `pruneLayout=true`: 抑制纯布局噪声,降低 token 压力。\n * - `maxNodes=500` / `maxChildren=30`: 控制体积上限,兼顾可读性。\n * - `maxTextLength=40`: 防止长文本淹没结构信息。\n *\n * 压缩/剪枝是怎么做的:\n * - `viewportOnly=true` 时:仅保留与视口相交元素(根层容器保留),完全视口外元素跳过。\n * - `pruneLayout=true` 时:无 id/无语义/无交互/无直接文本的布局容器会被“折叠”,\n * 子节点直接提升输出,减少无意义层级;当同一折叠容器提升出多个相邻节点时,\n * 快照会用括号分组块标记其关联来源(collapsed-group)。\n * - `maxNodes`:全局节点预算,超限后停止继续遍历并追加 truncation 提示。\n * - `maxChildren`:每个父节点只保留前 N 个子元素,其余用 `... (n children omitted)` 汇总。\n * - `maxTextLength`:节点文本按长度截断,避免长段文案占满上下文。\n * - 交互优先排序:优先输出按钮/输入框/链接等交互元素,再输出普通元素。\n * - 属性压缩:仅保留关键属性(如 id、关键 class、交互属性、布尔状态、val),减少冗余 token。\n *\n * 输入/输出:\n * - 输入:`ToolRegistry` + 可选快照参数\n * - 输出:归一化后的快照字符串(始终 string)\n * - 副作用:无本地状态写入;仅依赖工具调用结果\n */\nexport async function readPageSnapshot(\n registry: ToolRegistry,\n options?: {\n maxDepth?: number;\n viewportOnly?: boolean;\n pruneLayout?: boolean;\n maxNodes?: number;\n maxChildren?: number;\n maxTextLength?: number;\n expandOptionLists?: boolean;\n expandChildrenRefs?: string[];\n expandedChildrenLimit?: number;\n },\n): Promise<string> {\n const result = await registry.dispatch(\"page_info\", {\n action: \"snapshot\",\n maxDepth: options?.maxDepth ?? 12,\n viewportOnly: options?.viewportOnly ?? false,\n pruneLayout: options?.pruneLayout ?? true,\n maxNodes: options?.maxNodes ?? 500,\n maxChildren: options?.maxChildren ?? 30,\n maxTextLength: options?.maxTextLength ?? 40,\n expandOptionLists: options?.expandOptionLists,\n expandChildrenRefs: options?.expandChildrenRefs,\n expandedChildrenLimit: options?.expandedChildrenLimit,\n });\n return toContentString(result.content);\n}\n\n// ─── 快照标记 ───\n\n/**\n * 包裹快照。\n *\n * 作用:\n * - 为快照加 `SNAPSHOT_START/END` 边界,便于后续正则定位。\n * - 支持去重与旧快照剥离,防止多轮 token 累积。\n * - 仅做纯字符串变换,不访问外部状态。\n */\nexport function wrapSnapshot(snapshot: string): string {\n return `${SNAPSHOT_START}\\n${snapshot}\\n${SNAPSHOT_END}`;\n}\n\n// ─── 快照去重 ───\n\n/** 转义正则字符。 */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** 快照块匹配正则。 */\nconst SNAPSHOT_REGEX = new RegExp(\n `${escapeRegex(SNAPSHOT_START)}[\\\\s\\\\S]*?${escapeRegex(SNAPSHOT_END)}`,\n \"g\",\n);\n\n/** 是否包含快照标记。 */\nfunction containsSnapshot(text: string): boolean {\n return text.includes(SNAPSHOT_START) && text.includes(SNAPSHOT_END);\n}\n\n/**\n * 去重消息快照。\n * 仅保留最后一份快照,旧快照替换为过期提示。\n *\n * 步骤:\n * 1) 扫描 tool 消息中的快照块引用。\n * 2) 保留最后一次快照,视为当前事实来源。\n * 3) 将更早快照替换为 `SNAPSHOT_OUTDATED`,避免模型引用旧状态。\n *\n * 返回语义:\n * - `true`: 至少发现了 1 份快照(可能发生替换,也可能只有一份无需替换)。\n * - `false`: 未发现任何快照标记。\n */\nexport function deduplicateSnapshots(messages: AIMessage[]): boolean {\n type SnapshotRef = {\n items: Array<{ toolCallId: string; result: string }>;\n index: number;\n };\n const refs: SnapshotRef[] = [];\n\n for (const msg of messages) {\n if (msg.role !== \"tool\" || !Array.isArray(msg.content)) continue;\n const items = msg.content as Array<{ toolCallId: string; result: string }>;\n for (let j = 0; j < items.length; j++) {\n if (typeof items[j].result === \"string\" && containsSnapshot(items[j].result)) {\n refs.push({ items, index: j });\n }\n }\n }\n\n if (refs.length <= 1) return refs.length > 0;\n\n // 保留最后一份快照,将更早的快照替换为过期提示\n for (let i = 0; i < refs.length - 1; i++) {\n const ref = refs[i];\n ref.items[ref.index].result = ref.items[ref.index].result.replace(\n SNAPSHOT_REGEX,\n SNAPSHOT_OUTDATED,\n );\n }\n\n return true;\n}\n\n/**\n * 剥离旧快照。\n *\n * 说明:\n * - 当 prompt 中已有历史快照时,将其替换为过期占位文本。\n * - 让每轮真正生效的只有“最新注入快照”,减少冲突上下文。\n * - 这是 prompt 级清理;不会触碰 tool trace 中的原始结果对象。\n */\nexport function stripSnapshotFromPrompt(prompt: string): string {\n if (!containsSnapshot(prompt)) return prompt;\n return prompt.replace(SNAPSHOT_REGEX, SNAPSHOT_OUTDATED);\n}\n\n/** 导出快照正则,供消息层做错误摘要清理等用途。 */\nexport { SNAPSHOT_REGEX };\n","/**\n * 紧凑消息构建。\n *\n * 这个文件专门负责“给模型喂什么消息”。\n *\n * 它把 Agent Loop 的运行状态压缩成模型可直接消费的消息内容,核心输入包括:\n * - 用户原始目标(userMessage)\n * - 当前剩余任务(remainingInstruction)\n * - 已执行轨迹(trace / previousRoundTasks)\n * - 上一轮模型输出摘要(previousRoundModelOutput)\n * - 最新页面快照(latestSnapshot)\n * - 协议修复提示(protocolViolationHint)\n *\n * 设计目标:\n * 1) 减少上下文噪音,避免模型复述与空转\n * 2) 强化“基于当前快照做增量决策”的行为\n * 3) 让 REMAINING 协议在每轮都可持续推进\n *\n * 这个文件主要做了 4 件事:\n * 1) UI 意图识别:\n * - `isExplicitAgentUiRequest` 判断用户是否“明确要求操作 AutoPilot 聊天 UI”。\n * - 默认情况下会在提示词里禁止模型点击聊天输入框/发送按钮等。\n *\n * 2) 轨迹可读化:\n * - `formatToolInputBrief`、`formatToolResultBrief`、`buildToolTrace`\n * 把工具输入/结果压成短文本,便于注入上下文和调试展示。\n * - 直观效果示例(最终会长这样):\n * 1. [round 2] dom (action=\"click\", selector=\"#a1b2c\") [ELEMENT_NOT_FOUND]\n * 2. [round 2] wait (action=\"wait_for_selector\", selector=\"#a1b2c\")\n * 3. [round 3] dom (action=\"fill\", selector=\"#x9k3d\")\n *\n * 3) Round 0 消息构建:\n * - 首轮注入“任务 + remaining + 最新快照 + 执行约束”。\n * - 明确要求模型输出 `REMAINING: ...` 或 `REMAINING: DONE`。\n *\n * 4) Round 1+ 消息构建:\n * - 不再重复整段原始任务,改为注入“已完成步骤 + 当前 remaining + 最新快照”。\n * - 追加错误摘要、上轮计划数组、协议修复提示,帮助模型持续收敛。\n *\n * 边界说明(这个文件不做的事):\n * - 不调用模型、不执行工具\n * - 不维护循环状态(状态维护在 index.ts)\n * - 不读取页面快照(快照读取在 snapshot.ts)\n *\n * 一句话:这里是 Agent Loop 的“消息编排层”,负责把运行态翻译成稳定、高信息密度的提示上下文。\n */\nimport type { ToolCallResult } from \"../tool-registry.js\";\nimport type { AIMessage } from \"../types.js\";\nimport { toContentString, hasToolError } from \"./helpers.js\";\nimport { wrapSnapshot, SNAPSHOT_REGEX } from \"./snapshot.js\";\nimport type { ToolTraceEntry } from \"./types.js\";\n\n/**\n * 显式 UI 意图判定。\n *\n * 用途:默认禁止模型操作 AutoPilot 自己的聊天 UI(输入框/发送按钮等),\n * 只有当用户文本里“同时出现 UI 关键词 + 操作动词”时才放行。\n *\n * 判定逻辑:\n * - `hasAgentUiKeyword`:是否提到聊天面板/输入框/发送按钮等\n * - `hasActionVerb`:是否包含点击/输入/发送等动作意图\n * - 二者都满足才返回 true\n */\nexport function isExplicitAgentUiRequest(userMessage: string): boolean {\n const lower = userMessage.toLowerCase();\n const compact = lower.replace(/[\\s\\p{P}\\p{S}]+/gu, \"\");\n\n const hasAgentUiKeyword =\n /(chat|dock|chatinput|sendbutton|shortcut|quicktest)/i.test(lower) ||\n /(聊天|对话|指令输入框|消息输入框|输入框|发送按钮|发送|快捷测试|测试按钮|聊天面板)/.test(compact);\n\n const hasActionVerb =\n /(press|click|type|fill|send|input|submit|enter)/i.test(lower) ||\n /(输入|点击|发送|填写|填入|操作|提交|回车|按下)/.test(compact);\n return hasAgentUiKeyword && hasActionVerb;\n}\n\n// ─── 格式化辅助 ───\n\n/**\n * 输入摘要。\n *\n * 把工具输入压缩成一段短文本(用于轨迹展示),\n * 只保留高价值字段,避免日志过长。\n */\nexport function formatToolInputBrief(input: unknown): string {\n if (!input || typeof input !== \"object\") return \"\";\n\n const params = input as Record<string, unknown>;\n const parts: string[] = [];\n\n for (const key of [\"action\", \"selector\", \"waitMs\", \"waitSeconds\", \"url\", \"text\"]) {\n const value = params[key];\n if (value === undefined || value === null) continue;\n if (typeof value === \"string\") {\n parts.push(`${key}=${JSON.stringify(value).slice(0, 80)}`);\n } else if (typeof value === \"number\" || typeof value === \"boolean\") {\n parts.push(`${key}=${String(value)}`);\n }\n }\n\n if (parts.length === 0) return \"\";\n return ` (${parts.join(\", \")})`;\n}\n\n/**\n * 结果摘要。\n *\n * 读取工具结果首行,拼接错误码,生成一行可读结论:\n * - 成功:`✓ ...`\n * - 失败:`✗ ... [CODE]`\n */\nfunction formatToolResultBrief(result: ToolCallResult): string {\n const content = toContentString(result.content);\n const firstLine = content.split(\"\\n\").find(l => l.trim())?.trim().slice(0, 80) ?? \"\";\n\n if (hasToolError(result)) {\n const code = result.details && typeof result.details === \"object\"\n ? (result.details as { code?: string }).code\n : undefined;\n return `✗ ${firstLine}${code ? ` [${code}]` : \"\"}`;\n }\n return `✓ ${firstLine}`;\n}\n\n// ─── 轨迹格式化 ───\n\n/**\n * 轨迹格式化。\n *\n * 将完整工具轨迹转为可读文本列表,供提示词注入或调试展示。\n * 支持附加 current 条目(未入库前的临时展示)。\n *\n * 输出样式示例:\n * 1. [round 1] dom (action=\"click\", selector=\"#btnCreate\")\n * 2. [round 1] dom (action=\"fill\", selector=\"#title\") [FILL_NOT_APPLIED]\n * 3. [round 2] wait (action=\"wait_for_selector\", selector=\"#dialog\")\n */\nexport function buildToolTrace(\n trace: ToolTraceEntry[],\n current?: {\n round: number;\n name: string;\n input: unknown;\n result?: ToolCallResult;\n marker?: string;\n },\n): string {\n const lines = trace.map((entry, index) => {\n const code =\n entry.result.details && typeof entry.result.details === \"object\"\n ? (entry.result.details as { code?: unknown }).code\n : undefined;\n const codeText = typeof code === \"string\" ? ` [${code}]` : \"\";\n const marker = entry.marker ? ` ${entry.marker}` : \"\";\n return `${index + 1}. [round ${entry.round}] ${entry.name}${formatToolInputBrief(entry.input)}${codeText}${marker}`;\n });\n\n if (current) {\n const code =\n current.result?.details && typeof current.result.details === \"object\"\n ? (current.result.details as { code?: unknown }).code\n : undefined;\n const codeText = typeof code === \"string\" ? ` [${code}]` : \"\";\n const marker = current.marker ? ` ${current.marker}` : \"\";\n lines.push(\n `${lines.length + 1}. [round ${current.round}] ${current.name}${formatToolInputBrief(current.input)}${codeText}${marker}`,\n );\n }\n\n return lines.length > 0 ? lines.join(\"\\n\") : \"(暂无工具执行记录)\";\n}\n\n// ─── 紧凑消息构建 ───\n\n/**\n * 构建紧凑消息数组。\n *\n * 两种轮次语义:\n * - Round 0:发送“初始任务 + 当前快照 + 执行约束”\n * - Round 1+:发送“已完成步骤 + 当前 remaining + 最新快照”\n *\n * 渐进式语义:\n * - `remainingInstruction`:当前轮次仍待执行的文本。\n * - `previousRoundTasks`:上一轮已执行的任务数组,避免重复计划。\n * - `previousRoundModelOutput`:上一轮模型输出摘要,用于 task-reduction 输入。\n * - `previousRoundPlannedTasks`:上一轮计划数组,用于对齐“计划 vs 实际执行”。\n * - `protocolViolationHint`:协议修复提示(当 remaining 未完成但模型无动作时)。\n *\n * 输出:符合 AIMessage 结构的消息数组,可直接传给 AIClient.chat。\n */\nexport function buildCompactMessages(\n userMessage: string,\n trace: ToolTraceEntry[],\n latestSnapshot: string | undefined,\n currentUrl: string | undefined,\n history?: AIMessage[],\n remainingInstruction?: string,\n previousRoundTasks?: string[],\n previousRoundModelOutput?: string,\n previousRoundPlannedTasks?: string[],\n protocolViolationHint?: string,\n): AIMessage[] {\n const messages: AIMessage[] = history ? [...history] : [];\n const allowAgentUiInteraction = isExplicitAgentUiRequest(userMessage);\n const activeInstruction = (remainingInstruction && remainingInstruction.trim())\n ? remainingInstruction.trim()\n : userMessage;\n\n // ─── Round 0:任务描述 + 快照,一条 user 消息完成注入 ───\n if (trace.length === 0) {\n // 结构说明:\n // 1) 用户目标\n // 2) 当前 remaining\n // 3) URL(可选)\n // 4) 快照 + 行为约束(禁 page_info、禁误触 Agent UI、要求 REMAINING 输出)\n const parts: string[] = [\n userMessage,\n \"\",\n `Remaining: ${activeInstruction}`,\n ];\n if (currentUrl) {\n parts.push(`URL: ${currentUrl}`);\n }\n if (latestSnapshot) {\n parts.push(\n \"\",\n \"Use #hashID from snapshot. Do NOT call page_info (snapshot is auto-refreshed). Batch fills freely; at most ONE click (last) per round.\",\n \"Semantic completion: keep all unresolved user constraints in Remaining until they are visibly satisfied in the snapshot.\",\n \"Do NOT compress Remaining into a vague shell action that drops required entities, values, counts, filters, destinations, selections, or final outcomes from the user goal.\",\n \"Before any advance/finalize action, verify the prerequisite constraints are already satisfied in snapshot; otherwise continue the unsatisfied parts first.\",\n \"Effect check: confirm previous actions' expected effects in current snapshot before planning new actions.\",\n \"Click ends the round — actions after a click are discarded. Dropdown: open(click) → next round → pick(click).\",\n \"If a list shows `... (N children omitted)`, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>` and wait for next snapshot.\",\n allowAgentUiInteraction\n ? \"User explicitly asked to operate AutoPilot UI. You may interact with chat input/send/dock only as requested.\"\n : \"Do NOT interact with any AI chat UI elements (chat input, send button, dock). Only operate on the actual page content.\",\n \"Output: REMAINING: <new remaining> or REMAINING: DONE\",\n \"\",\n \"## Snapshot\",\n wrapSnapshot(latestSnapshot),\n );\n }\n if (protocolViolationHint) {\n parts.push(\"\", protocolViolationHint);\n }\n messages.push({ role: \"user\", content: parts.join(\"\\n\") });\n return messages;\n }\n\n // ─── Round 1+:注入“已完成步骤 + 执行上下文 + 最新快照” ───\n // 不再重复原始 userMessage,避免模型每轮回到起点重做。\n\n // 第 1 条 assistant 消息:已完成步骤摘要(从 trace 重建)\n const traceParts: string[] = [];\n for (let i = 0; i < trace.length; i++) {\n const entry = trace[i];\n const isError = hasToolError(entry.result);\n const brief = formatToolResultBrief(entry.result);\n const status = isError ? \"❌\" : \"✅\";\n const marker = entry.marker ? ` ${entry.marker}` : \"\";\n traceParts.push(\n `${status} ${i + 1}. ${entry.name}${formatToolInputBrief(entry.input)} → ${brief}${marker}`,\n );\n }\n messages.push({\n role: \"assistant\",\n content: `Done steps (do NOT repeat):\\n${traceParts.join(\"\\n\")}`,\n });\n\n // 第 2 条 user 消息:执行上下文 + 协议约束 + 最新快照\n const hasErrors = trace.some(e => hasToolError(e.result));\n const contextParts: string[] = [\n // 当前剩余任务(唯一待消费目标)\n `Remaining: ${activeInstruction}`,\n \"\",\n // ── 关键行为强化(system prompt 已有完整规则,此处补强模型易违反的关键条) ──\n \"Batch fills per round; clicks end the round — at most ONE click (last). Do NOT call page_info (snapshot is auto-refreshed).\",\n \"Semantic completion: preserve all unresolved user constraints in Remaining until they are visibly satisfied in the snapshot.\",\n \"Do NOT narrow Remaining into only a shell action if that would drop required entities, values, counts, filters, destinations, selections, or final outcomes.\",\n \"Before any advance/finalize action, check that all prerequisite constraints are already visible in the snapshot.\",\n \"Effect check: confirm previous actions' expected effects in snapshot before planning new actions.\",\n \"Never repeat the same tool call on the same target. If no effect, try a different element.\",\n \"Click ends the round — actions after a click are discarded. Dropdown: open(click) → next round → pick(click).\",\n \"If a list shows `... (N children omitted)`, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>` and wait.\",\n allowAgentUiInteraction\n ? \"User explicitly asked to operate AutoPilot UI.\"\n : \"Do NOT interact with AI chat UI elements.\",\n \"Output: REMAINING: <new remaining> or REMAINING: DONE\",\n ];\n\n if (hasErrors) {\n contextParts.push(\"\", \"Last step failed. Retry differently or skip to other targets.\");\n } else {\n contextParts.push(\"\", \"If fully done, reply summary only (no tools).\");\n }\n\n if (previousRoundTasks && previousRoundTasks.length > 0) {\n // 上轮已执行 + 简短效果提示(非阻塞,避免分析瘧痪)\n contextParts.push(\n \"\",\n \"Previous executed:\",\n ...previousRoundTasks.map((task, index) => `${index + 1}. ${task}`),\n \"If any had no visible effect, try a different nearby element instead of repeating.\",\n );\n }\n\n if (previousRoundPlannedTasks && previousRoundPlannedTasks.length > 0) {\n contextParts.push(\n \"\",\n \"Previous planned:\",\n ...previousRoundPlannedTasks.map((task, index) => `${index + 1}. ${task}`),\n );\n }\n\n if (previousRoundModelOutput) {\n contextParts.push(\n \"\",\n \"Previous model output:\",\n previousRoundModelOutput,\n );\n }\n\n // 最近失败摘要\n const lastEntry = trace[trace.length - 1];\n if (hasToolError(lastEntry.result)) {\n const detail = toContentString(lastEntry.result.content);\n const stripped = detail.replace(SNAPSHOT_REGEX, \"\").trim();\n if (stripped && stripped.length < 300) {\n contextParts.push(\"\", \"Error: \" + stripped);\n }\n }\n\n if (currentUrl) {\n contextParts.push(\"\", `URL: ${currentUrl}`);\n }\n\n if (protocolViolationHint) {\n contextParts.push(\"\", protocolViolationHint);\n }\n\n if (latestSnapshot) {\n // 注入最新快照\n contextParts.push(\n \"\",\n \"## Snapshot\",\n wrapSnapshot(latestSnapshot),\n );\n }\n\n messages.push({ role: \"user\", content: contextParts.join(\"\\n\") });\n\n return messages;\n}\n","/**\n * 保护与恢复机制。\n *\n * 这个文件负责给 Agent Loop 提供“防失败、防空转、防重复”的保护链。\n * 目标是:即使某一步失败,也尽量让循环继续推进,而不是直接崩掉。\n *\n * 主要能力:\n * 1) 冗余拦截:拦住无意义的 `page_info.*` 调用\n * 2) 快照防抖:连续 snapshot 触发时给出警告并限制空转\n * 3) 找不到元素恢复:自动等待 + 刷新快照 + 重试上限\n * 4) 导航后刷新:导航成功后立刻更新快照上下文\n * 5) 空转检测:连续只读轮次触发停机信号\n *\n * 一句话:这里是主循环的“保险丝层”。\n */\nimport type { ToolCallResult } from \"../tool-registry.js\";\nimport type { AgentLoopCallbacks } from \"./types.js\";\nimport { DEFAULT_ACTION_RECOVERY_ROUNDS } from \"./constants.js\";\nimport { readPageSnapshot } from \"./snapshot.js\";\nimport {\n getToolAction,\n hasToolError,\n isElementNotFoundResult,\n resolveRecoveryWaitMs,\n buildToolCallKey,\n sleep,\n toContentString,\n} from \"./helpers.js\";\nimport { ToolRegistry } from \"../tool-registry.js\";\nimport type { PageContextState } from \"./types.js\";\n\n// ─── 冗余 page_info 拦截 ───\n\n/** 冗余 page_info 动作集合。 */\nconst REDUNDANT_PAGE_INFO_ACTIONS = new Set([\"snapshot\", \"query_all\", \"get_url\", \"get_title\", \"get_viewport\"]);\n\n/**\n * 冗余 page_info 检查。\n *\n * 场景:模型在 loop 中频繁请求 page_info,导致“只看不做”。\n * 处理:命中白名单动作时直接返回拦截结果,不真正执行工具。\n *\n * 示例:\n * - 输入:`page_info.snapshot`\n * - 输出:`REDUNDANT_PAGE_INFO_SKIPPED`\n */\nexport function checkRedundantSnapshot(\n toolName: string,\n toolInput: unknown,\n _latestSnapshot: string | undefined,\n round: number,\n): ToolCallResult | null {\n if (toolName !== \"page_info\") return null;\n\n const action = getToolAction(toolInput);\n if (action && REDUNDANT_PAGE_INFO_ACTIONS.has(action)) {\n return {\n content:\n `page_info.${action} is blocked in loop execution. A snapshot is provided by the framework; continue with actionable tools directly.`,\n details: {\n code: \"REDUNDANT_PAGE_INFO_SKIPPED\",\n action,\n round,\n },\n };\n }\n return null;\n}\n\n/**\n * 快照防抖。\n *\n * 规则:连续触发 `page_info.snapshot` 时,第 2 次起标记为冗余,\n * 返回 `REDUNDANT_SNAPSHOT`,提醒模型直接使用已有快照继续执行。\n *\n * 返回值:\n * - `result`:可能被替换成防抖后的结果\n * - `consecutiveCount`:更新后的连续 snapshot 计数\n */\nexport function applySnapshotDebounce(\n toolName: string,\n toolInput: unknown,\n result: ToolCallResult,\n consecutiveCount: number,\n): { result: ToolCallResult; consecutiveCount: number } {\n if (toolName === \"page_info\" && getToolAction(toolInput) === \"snapshot\") {\n const newCount = consecutiveCount + 1;\n if (newCount >= 2) {\n return {\n consecutiveCount: newCount,\n result: {\n content: [\n toContentString(result.content),\n \"Redundant snapshot detected. Continue with remaining actionable steps using the latest snapshot; avoid additional snapshot unless navigation or uncertainty changes.\",\n ].join(\"\\n\"),\n details: {\n error: true,\n code: \"REDUNDANT_SNAPSHOT\",\n consecutiveSnapshotCalls: newCount,\n },\n },\n };\n }\n return { result, consecutiveCount: newCount };\n }\n // 非 snapshot 调用,重置计数\n return { result, consecutiveCount: 0 };\n}\n\n// ─── 元素未找到自动恢复 ───\n\n/**\n * 元素未找到恢复。\n *\n * 触发条件:\n * - 工具是 `dom`\n * - 结果被识别为“元素未找到”\n *\n * 处理流程:\n * 1) 按调用键统计恢复次数(同 name + input 视为同一调用)\n * 2) 在上限内:等待 -> 刷新快照 -> 返回 `ELEMENT_NOT_FOUND_RECOVERY`\n * 3) 超过上限:返回 `ELEMENT_NOT_FOUND_MAX_RECOVERY_REACHED`\n *\n * 说明:函数只返回“恢复后的结果描述”,是否继续下一轮由主循环决定。\n */\nexport async function handleElementRecovery(\n toolName: string,\n toolInput: unknown,\n result: ToolCallResult,\n recoveryAttempts: Map<string, number>,\n registry: ToolRegistry,\n pageContext: PageContextState,\n callbacks?: AgentLoopCallbacks,\n): Promise<ToolCallResult | null> {\n if (toolName !== \"dom\" || !isElementNotFoundResult(result)) {\n return null;\n }\n\n const key = buildToolCallKey(toolName, toolInput);\n const attempts = (recoveryAttempts.get(key) ?? 0) + 1;\n recoveryAttempts.set(key, attempts);\n const recoveryWaitMs = resolveRecoveryWaitMs(toolInput);\n\n if (attempts <= DEFAULT_ACTION_RECOVERY_ROUNDS) {\n await sleep(recoveryWaitMs);\n callbacks?.onBeforeRecoverySnapshot?.();\n pageContext.latestSnapshot = await readPageSnapshot(registry);\n\n return {\n content: [\n toContentString(result.content),\n `Recovery ${attempts}/${DEFAULT_ACTION_RECOVERY_ROUNDS}: snapshot refreshed, re-locate target.`,\n ].join(\"\\n\"),\n details: {\n error: true,\n code: \"ELEMENT_NOT_FOUND_RECOVERY\",\n recoveryAttempt: attempts,\n recoveryMaxRounds: DEFAULT_ACTION_RECOVERY_ROUNDS,\n },\n };\n }\n\n return {\n content: [\n toContentString(result.content),\n `Max recovery attempts (${DEFAULT_ACTION_RECOVERY_ROUNDS}) reached. Try a different target.`,\n ].join(\"\\n\"),\n details: {\n error: true,\n code: \"ELEMENT_NOT_FOUND_MAX_RECOVERY_REACHED\",\n recoveryAttempt: attempts,\n recoveryMaxRounds: DEFAULT_ACTION_RECOVERY_ROUNDS,\n },\n };\n}\n\n// ─── 导航后 URL 变化检测 ───\n\n/**\n * 导航后快照刷新。\n *\n * 当 `navigate.goto/back/forward/reload` 成功后,立即刷新快照,\n * 防止后续动作还在旧页面上下文里决策。\n */\nexport async function handleNavigationUrlChange(\n toolName: string,\n toolInput: unknown,\n result: ToolCallResult,\n registry: ToolRegistry,\n pageContext: PageContextState,\n callbacks?: AgentLoopCallbacks,\n): Promise<void> {\n if (toolName !== \"navigate\") return;\n\n const action = getToolAction(toolInput);\n if (\n (action === \"goto\" || action === \"back\" || action === \"forward\" || action === \"reload\") &&\n !hasToolError(result)\n ) {\n callbacks?.onBeforeRecoverySnapshot?.();\n pageContext.latestSnapshot = await readPageSnapshot(registry);\n }\n}\n\n// ─── 空转检测 ───\n\n/** 只读工具集合。 */\nconst READ_ONLY_TOOLS = new Set([\"page_info\"]);\n\n/** DOM 只读动作集合。 */\nconst READ_ONLY_DOM_ACTIONS = new Set([\"get_text\", \"get_attr\"]);\n\n/**\n * 空转检测:识别连续只读轮次并终止。\n *\n * 判定口径:\n * - `page_info.*` 视为只读\n * - `dom.get_text/get_attr` 视为只读\n *\n * 返回值语义:\n * - `-1`:触发停机(连续 2 轮纯只读)\n * - `0`:本轮有实质操作,计数清零\n * - `>0`:当前连续只读轮次\n */\nexport function detectIdleLoop(\n toolCalls: Array<{ name: string; input: unknown }>,\n consecutiveReadOnlyRounds: number,\n): number {\n const allReadOnly = toolCalls.length > 0 && toolCalls.every(({ name, input }) => {\n if (READ_ONLY_TOOLS.has(name)) return true;\n if (name !== \"dom\") return false;\n const action = getToolAction(input);\n return Boolean(action && READ_ONLY_DOM_ACTIONS.has(action));\n });\n if (allReadOnly) {\n const newCount = consecutiveReadOnlyRounds + 1;\n // 连续 2 轮纯只读 → 返回 -1 表示强制终止\n return newCount >= 2 ? -1 : newCount;\n }\n return 0; // 有实际操作,重置\n}\n","/**\n * Agent Loop 主流程(口语版)\n *\n * 流程图(文本):\n *\n * 轮次开始\n * │\n * ├─ 先看有没有最新快照\n * │ └─ 没有就先拍一张(可带 expandChildrenRefs)\n * │\n * ├─ 组装本轮上下文消息\n * │ └─ remaining + 上轮任务 + 最新快照 +(必要时)重试提示\n * │\n * ├─ 调用模型拿决策\n * │ └─ 同时解析 `REMAINING` 和 `SNAPSHOT_HINT`\n * │\n * ├─ 有 toolCalls 吗?\n * │ ├─ 没有:走收敛/协议修复判断(必要时等待后重试)\n * │ └─ 有:逐个执行工具\n * │ ├─ 冗余拦截(例如 page_info 空转)\n * │ ├─ 失败恢复(元素未找到重试)\n * │ ├─ 导航后更新快照\n * │ └─ 命中断轮条件则提前结束本轮\n * │\n * ├─ 更新 remaining(优先协议,缺失时启发式剔除)\n * │\n * ├─ 防空转 / 防自转 / 防协议缺失检查\n * │ └─ 连续只读、重复批次、连续无协议均会触发停机\n * │\n * ├─ 刷新快照\n * ▼\n * 下一轮或停机\n *\n * 停机条件(任一命中):\n * - `REMAINING: DONE`(或 remaining 为空)\n * - 协议修复后仍无推进\n * - 连续只读(空转)\n * - 重复批次(自转)\n * - 达到 maxRounds\n */\nimport {\n DEFAULT_MAX_ROUNDS,\n DEFAULT_NOT_FOUND_RETRY_ROUNDS,\n DEFAULT_NOT_FOUND_RETRY_WAIT_MS,\n DEFAULT_ROUND_STABILITY_WAIT_LOADING_SELECTORS,\n DEFAULT_ROUND_STABILITY_WAIT_QUIET_MS,\n DEFAULT_ROUND_STABILITY_WAIT_TIMEOUT_MS,\n} from \"./constants.js\";\nimport {\n buildTaskArray,\n collectMissingTask,\n deriveNextInstruction,\n extractHashSelectorRef,\n getToolAction,\n normalizeModelOutput,\n parseSnapshotExpandHints,\n reduceRemainingHeuristically,\n shouldForceRoundBreak,\n isPotentialDomMutation,\n sleep,\n toContentString,\n hasToolError,\n} from \"./helpers.js\";\nimport { readPageSnapshot, stripSnapshotFromPrompt } from \"./snapshot.js\";\nimport { buildCompactMessages } from \"./messages.js\";\nimport {\n checkRedundantSnapshot,\n applySnapshotDebounce,\n handleElementRecovery,\n handleNavigationUrlChange,\n detectIdleLoop,\n} from \"./recovery.js\";\nimport type {\n AgentLoopParams,\n AgentLoopResult,\n AgentLoopMetrics,\n PageContextState,\n ToolTraceEntry,\n} from \"./types.js\";\nimport type { AIMessage } from \"../types.js\";\n\n/**\n * 执行 Agent 循环。\n *\n * 你可以把这个函数理解成“任务执行调度器”:\n * - 输入:用户任务、系统提示词、工具注册表、历史消息、初始快照\n * - 过程:按轮次持续执行“看页面 -> 让模型决策 -> 跑工具 -> 更新上下文”\n * - 输出:最终回复、完整工具调用记录、可复用消息、结构化指标\n *\n * 每轮主流程(固定顺序):\n * 1) Ensure Snapshot:确保当前有最新快照(必要时读取)\n * 2) Build Messages:构建紧凑上下文(remaining + 上轮轨迹 + 最新快照)\n * 3) Call AI:请求模型并解析协议字段(`REMAINING` / `SNAPSHOT_HINT`)\n * 4) Execute Tools:执行工具调用并应用保护机制(冗余拦截、恢复、导航刷新)\n * 5) Reduce Remaining:推进剩余任务(优先协议,缺失时启发式剔除)\n * 6) Guard & Refresh:防空转/防自转判定,并刷新快照进入下一轮\n *\n * 核心状态语义:\n * - `remainingInstruction`:当前轮还未消费完的任务文本\n * - `previousRoundTasks`:上一轮已执行动作,防止模型原样重复\n * - `previousRoundPlannedTasks`:上一轮模型计划,用于重复批次检测\n * - `protocolViolationHint`:协议修复提示(remaining 未完成却无工具调用时注入)\n *\n * 停机条件(命中任意一条即结束):\n * - 模型无工具调用且 remaining 已收敛(`REMAINING: DONE` 或空)\n * - 协议修复后仍无推进\n * - 连续只读轮次(防空转)\n * - 连续重复计划批次(防自转)\n * - 达到 `maxRounds`\n */\nexport async function executeAgentLoop(\n params: AgentLoopParams,\n): Promise<AgentLoopResult> {\n const {\n client,\n registry,\n systemPrompt,\n message,\n initialSnapshot,\n history,\n dryRun = false,\n maxRounds = DEFAULT_MAX_ROUNDS,\n roundStabilityWait,\n callbacks,\n } = params;\n\n // 固定依赖与运行态容器\n const tools = registry.getDefinitions();\n const allToolCalls: AgentLoopResult[\"toolCalls\"] = [];\n const fullToolTrace: ToolTraceEntry[] = [];\n const actionRecoveryAttempts = new Map<string, number>();\n const pageContext: PageContextState = {\n latestSnapshot: initialSnapshot,\n };\n\n // 最终输出\n let finalReply = \"\";\n\n // 循环控制状态\n let consecutiveSnapshotCalls = 0;\n let consecutiveReadOnlyRounds = 0;\n let consecutiveNoProtocolRounds = 0;\n let usedRounds = 0;\n\n // token 统计\n let inputTokens = 0;\n let outputTokens = 0;\n // 渐进式任务状态\n // remainingInstruction: 当前轮次要继续消费的剩余文本。\n // previousRoundTasks: 上一轮已经执行过的任务数组,用于提醒 AI 不要原样重复。\n // lastPlannedBatchKey + consecutiveSamePlannedBatch: 防止 AI 连续给出相同任务批次导致自转。\n // lastRoundHadError: 如果上一轮有错误,不触发“重复批次即停机”,避免误停。\n let remainingInstruction = message.trim();\n let previousRoundTasks: string[] = [];\n let previousRoundPlannedTasks: string[] = [];\n let previousRoundModelOutput = \"\";\n let lastPlannedBatchKey = \"\";\n let consecutiveSamePlannedBatch = 0;\n let lastRoundHadError = false;\n let protocolViolationHint: string | undefined;\n const snapshotExpandRefIds = new Set<string>();\n const effectiveRoundStabilityWait = {\n enabled: roundStabilityWait?.enabled ?? true,\n timeoutMs: Math.max(200, Math.floor(roundStabilityWait?.timeoutMs ?? DEFAULT_ROUND_STABILITY_WAIT_TIMEOUT_MS)),\n quietMs: Math.max(50, Math.floor(roundStabilityWait?.quietMs ?? DEFAULT_ROUND_STABILITY_WAIT_QUIET_MS)),\n loadingSelectors: [\n ...new Set(\n [\n ...DEFAULT_ROUND_STABILITY_WAIT_LOADING_SELECTORS,\n ...(roundStabilityWait?.loadingSelectors ?? []),\n ]\n .map(selector => selector.trim())\n .filter(Boolean),\n ),\n ],\n };\n // 恢复与拦截统计\n let recoveryCount = 0;\n let redundantInterceptCount = 0;\n\n type MissingToolTask = {\n name: string;\n input: unknown;\n reason: string;\n };\n\n let pendingNotFoundRetry:\n | {\n attempt: number;\n tasks: MissingToolTask[];\n }\n | undefined;\n\n // 快照体积统计\n let snapshotReadCount = 0;\n let snapshotSizeTotal = 0;\n let snapshotSizeMax = 0;\n\n /**\n * 记录快照统计。\n *\n * 用于输出可观测指标:读取次数、平均长度、最大长度。\n * Used for observability metrics: read count, avg size, max size.\n */\n const recordSnapshotStats = (snapshot: string | undefined): void => {\n if (typeof snapshot !== \"string\") return;\n snapshotReadCount += 1;\n snapshotSizeTotal += snapshot.length;\n if (snapshot.length > snapshotSizeMax) snapshotSizeMax = snapshot.length;\n };\n\n /**\n * 刷新页面快照。\n *\n * 只做两件事:读取最新快照 + 更新快照统计。\n * Does exactly two things: read latest snapshot + update metrics.\n */\n const refreshSnapshot = async (): Promise<void> => {\n pageContext.latestSnapshot = await readPageSnapshot(\n registry,\n snapshotExpandRefIds.size > 0\n ? { expandChildrenRefs: Array.from(snapshotExpandRefIds), expandedChildrenLimit: 120 }\n : undefined,\n );\n recordSnapshotStats(pageContext.latestSnapshot);\n };\n\n /**\n * 轮次后稳定等待(双重等待)。\n *\n * 顺序固定为:\n * 1) 等待 loading 指示器隐藏\n * 2) 等待 DOM quiet window\n */\n const runRoundStabilityBarrier = async (): Promise<void> => {\n if (!effectiveRoundStabilityWait.enabled) return;\n if (!registry.has(\"wait\")) return;\n\n const timeout = effectiveRoundStabilityWait.timeoutMs;\n const loadingSelector = effectiveRoundStabilityWait.loadingSelectors.join(\", \");\n\n if (loadingSelector) {\n await registry.dispatch(\"wait\", {\n action: \"wait_for_selector\",\n selector: loadingSelector,\n state: \"hidden\",\n timeout,\n });\n }\n\n await registry.dispatch(\"wait\", {\n action: \"wait_for_stable\",\n timeout,\n quietMs: effectiveRoundStabilityWait.quietMs,\n });\n };\n\n\n if (pageContext.latestSnapshot) {\n recordSnapshotStats(pageContext.latestSnapshot);\n }\n\n /**\n * 追加工具轨迹。\n *\n * 同时写入:\n * - allToolCalls:对外返回结果\n * - fullToolTrace:下一轮消息上下文\n */\n const appendToolTrace = (\n round: number,\n name: string,\n input: unknown,\n result: AgentLoopResult[\"toolCalls\"][number][\"result\"],\n ): void => {\n allToolCalls.push({ name, input, result });\n fullToolTrace.push({ round, name, input, result });\n };\n\n // 主循环\n for (let round = 0; round < maxRounds; round++) {\n callbacks?.onRound?.(round);\n usedRounds = round + 1;\n\n // ═══ 阶段 1:确保快照 ═══\n if (!pageContext.latestSnapshot) {\n await refreshSnapshot();\n }\n\n // ═══ 阶段 2:构建紧凑消息 ═══\n // 每轮消息都自带快照(buildCompactMessages 注入),因此始终剥离\n // system prompt 中的旧快照,避免重复。\n const effectivePrompt = stripSnapshotFromPrompt(systemPrompt);\n\n const chatMessages = buildCompactMessages(\n message,\n fullToolTrace,\n pageContext.latestSnapshot,\n pageContext.currentUrl,\n history,\n remainingInstruction,\n previousRoundTasks,\n previousRoundModelOutput,\n previousRoundPlannedTasks,\n protocolViolationHint,\n );\n\n if (pendingNotFoundRetry && pendingNotFoundRetry.tasks.length > 0) {\n chatMessages.push({\n role: \"user\",\n content: [\n \"## Not-found retry context\",\n `Retry attempt: ${pendingNotFoundRetry.attempt}/${DEFAULT_NOT_FOUND_RETRY_ROUNDS}`,\n \"These tool targets were not found in previous execution:\",\n ...pendingNotFoundRetry.tasks.map((task, i) =>\n `${i + 1}. ${task.name}(${JSON.stringify(task.input)}) -> ${task.reason}`,\n ),\n \"Only retry unresolved targets that are now visible in the latest snapshot.\",\n \"If still not found, return no tool calls and include REMAINING with the unresolved part.\",\n ].join(\"\\n\"),\n });\n }\n\n // ═══ 阶段 3:调用 AI ═══\n const response = await client.chat({\n systemPrompt: effectivePrompt,\n messages: chatMessages,\n tools,\n });\n\n // 计费/观测数据累计\n inputTokens += response.usage?.inputTokens ?? 0;\n outputTokens += response.usage?.outputTokens ?? 0;\n\n // 先解析协议,最终推进在本轮执行后统一决定。\n const parsedInstructionState = deriveNextInstruction(response.text, remainingInstruction);\n const snapshotHintRefs = parseSnapshotExpandHints(response.text);\n for (const ref of snapshotHintRefs.slice(0, 8)) {\n snapshotExpandRefIds.add(ref);\n }\n\n // 没有工具调用:若处于找不到重试流程,先等待再重试;否则正常结束\n if (!response.toolCalls || response.toolCalls.length === 0) {\n consecutiveNoProtocolRounds = 0; // 非工具轮打断协议缺失计数\n if (pendingNotFoundRetry) {\n const unresolvedHint = response.text?.toLowerCase() ?? \"\";\n const stillUnresolved =\n unresolvedHint.includes(\"找不到\") ||\n unresolvedHint.includes(\"未找到\") ||\n unresolvedHint.includes(\"not found\") ||\n unresolvedHint.includes(\"cannot find\") ||\n unresolvedHint.includes(\"unable to locate\");\n\n if (stillUnresolved && pendingNotFoundRetry.attempt < DEFAULT_NOT_FOUND_RETRY_ROUNDS) {\n pendingNotFoundRetry = {\n ...pendingNotFoundRetry,\n attempt: pendingNotFoundRetry.attempt + 1,\n };\n callbacks?.onText?.(\n `未命中目标,准备第 ${pendingNotFoundRetry.attempt} 次重试(等待 ${DEFAULT_NOT_FOUND_RETRY_WAIT_MS}ms)...`,\n );\n await sleep(DEFAULT_NOT_FOUND_RETRY_WAIT_MS);\n await refreshSnapshot();\n continue;\n }\n pendingNotFoundRetry = undefined;\n }\n\n if (parsedInstructionState.hasRemainingProtocol) {\n remainingInstruction = parsedInstructionState.nextInstruction;\n }\n\n const unresolvedRemaining = remainingInstruction.trim().length > 0;\n if (unresolvedRemaining && round < maxRounds - 1) {\n protocolViolationHint = [\n \"Protocol violation in previous round:\",\n \"- Remaining task is not DONE, but no tool calls were returned.\",\n \"This round MUST do one of:\",\n \"1) Return actionable tool calls for visible targets; or\",\n \"2) If truly complete, return a short summary and EXACTLY `REMAINING: DONE`.\",\n \"Do NOT output planning/explaining text.\",\n ].join(\"\\n\");\n lastRoundHadError = true;\n await refreshSnapshot();\n continue;\n }\n\n finalReply = response.text ?? \"\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n\n protocolViolationHint = undefined;\n const plannedTasksCurrentRound = buildTaskArray(\n response.toolCalls.map(tc => ({ name: tc.name, input: tc.input })),\n );\n\n const plannedBatchKey = JSON.stringify(\n response.toolCalls.map(tc => ({ name: tc.name, input: tc.input })),\n );\n // 比较“本轮计划”与“上一轮计划”是否完全一致。\n if (plannedBatchKey === lastPlannedBatchKey) {\n consecutiveSamePlannedBatch += 1;\n } else {\n consecutiveSamePlannedBatch = 1;\n lastPlannedBatchKey = plannedBatchKey;\n }\n\n // 防自转:连续两轮给出相同计划且上一轮无错误,判定任务已完成或模型卡住,直接结束。\n if (consecutiveSamePlannedBatch >= 2 && !lastRoundHadError) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n\n // ─── Dry-run 模式 ───\n if (dryRun) {\n finalReply = response.text ? response.text + \"\\n\\n\" : \"\";\n finalReply += \"🔧 AI 请求调用以下工具(dry-run 模式,未执行):\\n\";\n for (const tc of response.toolCalls) {\n callbacks?.onToolCall?.(tc.name, tc.input);\n finalReply += `\\n┌─ 工具: ${tc.name}\\n`;\n finalReply += `│ ID: ${tc.id}\\n`;\n finalReply += `│ 参数:\\n`;\n const inputStr = JSON.stringify(tc.input, null, 2);\n for (const line of inputStr.split(\"\\n\")) {\n finalReply += `│ ${line}\\n`;\n }\n finalReply += `└────────────────────\\n`;\n }\n break;\n }\n\n // ═══ 阶段 4:执行工具调用(带保护机制)═══\n\n // 批量执行所有工具调用\n // roundHasError 用于控制“重复批次停机”:上一轮有错误时,不应武断终止。\n let roundHasError = false;\n let roundHasPotentialDomMutation = false;\n const executedTaskCalls: Array<{ name: string; input: unknown }> = [];\n const roundMissingTasks: MissingToolTask[] = [];\n for (const tc of response.toolCalls) {\n\n // 自动策略:当 AI 对 hash 列表执行 scroll 时,默认下一轮对该节点放宽 children 截断。\n // 这样即使模型未显式输出 SNAPSHOT_HINT,也能尽快拿到完整列表选项。\n if (tc.name === \"dom\" && getToolAction(tc.input) === \"scroll\") {\n const ref = extractHashSelectorRef(tc.input);\n if (ref) snapshotExpandRefIds.add(ref);\n }\n\n // 保护 1:冗余快照拦截\n const redundant = checkRedundantSnapshot(\n tc.name, tc.input, pageContext.latestSnapshot, round,\n );\n if (redundant) {\n appendToolTrace(round, tc.name, tc.input, redundant);\n redundantInterceptCount += 1;\n callbacks?.onToolResult?.(tc.name, redundant);\n continue;\n }\n\n callbacks?.onToolCall?.(tc.name, tc.input);\n\n // 执行工具\n let result = await registry.dispatch(tc.name, tc.input);\n\n // 保护 2:连续快照防抖\n const debounced = applySnapshotDebounce(\n tc.name, tc.input, result, consecutiveSnapshotCalls,\n );\n result = debounced.result;\n consecutiveSnapshotCalls = debounced.consecutiveCount;\n\n // 保护 3:元素未找到自动恢复\n const recovered = await handleElementRecovery(\n tc.name, tc.input, result,\n actionRecoveryAttempts, registry, pageContext, callbacks,\n );\n if (recovered) result = recovered;\n if (\n recovered?.details &&\n typeof recovered.details === \"object\" &&\n (recovered.details as { code?: unknown }).code === \"ELEMENT_NOT_FOUND_RECOVERY\"\n ) {\n recoveryCount += 1;\n }\n\n appendToolTrace(round, tc.name, tc.input, result);\n executedTaskCalls.push({ name: tc.name, input: tc.input });\n\n const missingTask = collectMissingTask(tc.name, tc.input, result);\n if (missingTask) {\n roundMissingTasks.push(missingTask);\n }\n\n if (result.details && typeof result.details === \"object\") {\n roundHasError = roundHasError || Boolean((result.details as { error?: unknown }).error);\n }\n if (!hasToolError(result) && isPotentialDomMutation(tc.name, tc.input)) {\n roundHasPotentialDomMutation = true;\n }\n\n // 捕获显式 snapshot 结果\n if (tc.name === \"page_info\" && getToolAction(tc.input) === \"snapshot\") {\n pageContext.latestSnapshot = toContentString(result.content);\n recordSnapshotStats(pageContext.latestSnapshot);\n }\n\n // 保护 4:导航后 URL 变化检测\n await handleNavigationUrlChange(\n tc.name, tc.input, result, registry, pageContext, callbacks,\n );\n\n callbacks?.onToolResult?.(tc.name, result);\n\n if (shouldForceRoundBreak(tc.name, tc.input)) {\n break;\n }\n }\n\n if (roundMissingTasks.length > 0) {\n pendingNotFoundRetry = {\n attempt: 1,\n tasks: roundMissingTasks,\n };\n } else {\n pendingNotFoundRetry = undefined;\n }\n\n // 将本轮执行状态传给下一轮上下文。\n if (parsedInstructionState.hasRemainingProtocol) {\n remainingInstruction = parsedInstructionState.nextInstruction;\n consecutiveNoProtocolRounds = 0;\n } else {\n const nextByHeuristic = reduceRemainingHeuristically(remainingInstruction, executedTaskCalls.length);\n if (nextByHeuristic !== remainingInstruction) {\n remainingInstruction = nextByHeuristic;\n consecutiveNoProtocolRounds = 0;\n } else if (executedTaskCalls.length > 0) {\n // 模型执行了工具但未遵循 REMAINING 协议且启发式无法推进。\n // 若本轮有成功的 DOM 变更(click/fill 等),说明任务在实质推进,\n // 不累计协议缺失计数,避免因模型不遵循 REMAINING 协议而过早停机。\n // 仅在本轮全部失败或无 DOM 变更时才累计,防止真正的空转。\n if (!roundHasPotentialDomMutation || roundHasError) {\n consecutiveNoProtocolRounds += 1;\n }\n }\n }\n\n previousRoundModelOutput = parsedInstructionState.hasRemainingProtocol\n ? normalizeModelOutput(response.text)\n : `REMAINING: ${remainingInstruction || \"DONE\"}`;\n\n lastRoundHadError = roundHasError;\n previousRoundTasks = buildTaskArray(executedTaskCalls);\n previousRoundPlannedTasks = plannedTasksCurrentRound;\n\n // 协议显式 DONE 且本轮已完成执行且无错误:直接收敛,避免后续重复动作。\n if (\n parsedInstructionState.hasRemainingProtocol &&\n remainingInstruction.trim().length === 0 &&\n !roundHasError\n ) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n\n // 保护 5:防协议缺失空转 — 连续多轮有工具调用但无 REMAINING 协议且启发式无法推进\n if (consecutiveNoProtocolRounds >= 3) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n if (consecutiveNoProtocolRounds >= 2) {\n protocolViolationHint = [\n \"Protocol reminder: REMAINING protocol missing for 2+ rounds with tool calls.\",\n \"You MUST include REMAINING: <text> or REMAINING: DONE in every response.\",\n \"If the task is fully complete, return REMAINING: DONE with no tool calls.\",\n ].join(\"\\n\");\n }\n\n // 保护 6:空转检测\n const attemptedTaskCalls = response.toolCalls.map(tc => ({ name: tc.name, input: tc.input }));\n const idleResult = detectIdleLoop(attemptedTaskCalls, consecutiveReadOnlyRounds);\n if (idleResult === -1) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n consecutiveReadOnlyRounds = idleResult;\n\n if (roundHasPotentialDomMutation) {\n await runRoundStabilityBarrier();\n }\n\n // ═══ 阶段 5:刷新快照(供下一轮使用)═══\n await refreshSnapshot();\n }\n\n // 构建紧凑的 result.messages 供多轮记忆使用\n // Build compact result.messages for optional multi-turn memory reuse.\n const resultMessages: AIMessage[] = [...(history ?? []), { role: \"user\", content: message }];\n if (finalReply) {\n resultMessages.push({ role: \"assistant\", content: finalReply });\n }\n\n // 结果统计\n const successfulToolCalls = allToolCalls.filter(tc => {\n const details = tc.result.details;\n return !(details && typeof details === \"object\" && Boolean((details as { error?: unknown }).error));\n }).length;\n const failedToolCalls = allToolCalls.length - successfulToolCalls;\n\n const metrics: AgentLoopMetrics = {\n roundCount: usedRounds,\n totalToolCalls: allToolCalls.length,\n successfulToolCalls,\n failedToolCalls,\n toolSuccessRate: allToolCalls.length > 0\n ? Number((successfulToolCalls / allToolCalls.length).toFixed(4))\n : 1,\n recoveryCount,\n redundantInterceptCount,\n snapshotReadCount,\n latestSnapshotSize: pageContext.latestSnapshot?.length ?? 0,\n avgSnapshotSize: snapshotReadCount > 0 ? Math.round(snapshotSizeTotal / snapshotReadCount) : 0,\n maxSnapshotSize: snapshotSizeMax,\n inputTokens,\n outputTokens,\n };\n\n // 统一发出指标回调\n callbacks?.onMetrics?.(metrics);\n\n return { reply: finalReply, toolCalls: allToolCalls, messages: resultMessages, metrics };\n}\n\n// ─── Re-exports(维持外部 API 不变)───\nexport { wrapSnapshot } from \"./snapshot.js\";\nexport type {\n AgentLoopParams,\n AgentLoopResult,\n AgentLoopCallbacks,\n AgentLoopMetrics,\n RoundStabilityWaitOptions,\n} from \"./types.js\";\n","/**\n * AI Client 共享常量(中)/ Shared constants and helpers for AI clients (EN).\n */\nimport type { AIClientConfig } from \"./index.js\";\n\n// ─── Provider 端点映射 ───\n\n/** 默认端点映射(中)/ Default API endpoints by provider (EN). */\nexport const PROVIDER_ENDPOINTS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n copilot: \"https://models.inference.ai.azure.com\",\n anthropic: \"https://api.anthropic.com\",\n deepseek: \"https://api.deepseek.com\",\n doubao: \"https://ark.cn-beijing.volces.com/api/v3\",\n qwen: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n};\n\n// ─── 共享工具函数 ───\n\n/** 校验 provider(中)/ Validate provider support (EN). */\nexport function validateProvider(provider: string): void {\n if (!PROVIDER_ENDPOINTS[provider]) {\n const supported = Object.keys(PROVIDER_ENDPOINTS).join(\", \");\n throw new Error(\n `Unknown AI provider: ${provider}. Supported: ${supported}`,\n );\n }\n}\n\n/** 解析 baseURL(中)/ Resolve API base URL (EN). */\nexport function resolveBaseURL(config: AIClientConfig): string {\n return config.baseURL ?? PROVIDER_ENDPOINTS[config.provider] ?? \"\";\n}\n\n/**\n * 清理 schema(中)/ Clean non-serializable fields from schema (EN).\n */\nexport function cleanSchema(schema: unknown): unknown {\n return JSON.parse(JSON.stringify(schema));\n}\n","/** SSE 事件处理器(中)/ SSE JSON event handler (EN). Return false to stop early. */\nexport type SSEJSONHandler = (\n event: Record<string, unknown>,\n meta: { event?: string; rawData: string },\n) => void | boolean | Promise<void | boolean>;\n\n/** SSE 配置(中)/ SSE consume options (EN). */\nexport type SSEConsumeOptions = {\n /** 单次读取超时(毫秒)。不传则不超时。 */\n readTimeoutMs?: number;\n /** 是否在遇到 [DONE] 时提前结束(默认 true)。 */\n stopOnDone?: boolean;\n};\n\n/**\n * 通用 SSE(JSON) 消费器(中)/ Generic SSE(JSON) consumer (EN).\n *\n * 读取 response.body,按 SSE 规则拼装并分发 JSON data 事件。\n * Reads response body, assembles SSE frames, and dispatches JSON data events.\n */\nexport async function consumeSSEJSON(\n response: Response,\n onEvent: SSEJSONHandler,\n options: SSEConsumeOptions = {},\n): Promise<void> {\n if (!response.body) return;\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n const stopOnDone = options.stopOnDone ?? true;\n\n let buffer = \"\";\n let currentEvent: string | undefined;\n let dataLines: string[] = [];\n let stoppedByDone = false;\n\n async function readChunk() {\n const readTimeoutMs = options.readTimeoutMs;\n if (!readTimeoutMs || readTimeoutMs <= 0) {\n return reader.read();\n }\n\n return new Promise<ReadableStreamReadResult<Uint8Array>>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error(`SSE read timeout (${readTimeoutMs}ms)`));\n }, readTimeoutMs);\n\n reader.read().then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n }\n\n async function flushEvent(): Promise<boolean> {\n if (dataLines.length === 0) {\n currentEvent = undefined;\n return true;\n }\n\n const rawData = dataLines.join(\"\\n\").trim();\n const event = currentEvent;\n dataLines = [];\n currentEvent = undefined;\n\n if (!rawData) return true;\n if (stopOnDone && rawData === \"[DONE]\") {\n stoppedByDone = true;\n return false;\n }\n\n try {\n const parsed = JSON.parse(rawData) as Record<string, unknown>;\n const shouldContinue = await onEvent(parsed, { event, rawData });\n if (shouldContinue === false) return false;\n } catch {\n // 非 JSON data 事件忽略\n }\n\n return true;\n }\n\n while (true) {\n const { done, value } = await readChunk();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n const trimmed = line.trim();\n\n if (!trimmed) {\n const shouldContinue = await flushEvent();\n if (!shouldContinue) break;\n continue;\n }\n if (trimmed.startsWith(\":\")) continue;\n if (trimmed.startsWith(\"event:\")) {\n currentEvent = trimmed.slice(6).trim() || undefined;\n continue;\n }\n if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(5).trimStart());\n }\n }\n\n if (stoppedByDone) break;\n }\n\n if (!stoppedByDone) {\n await flushEvent();\n } else {\n await reader.cancel().catch(() => undefined);\n }\n}\n","/**\n * 可继承 AI 客户端基类(中)/ Extensible base AI client class (EN).\n *\n * 支持注入 chatHandler 或子类覆写 chat。\n * Supports injected chatHandler or subclass override.\n */\nimport type { AIChatResponse, AIClient, AIMessage } from \"../types.js\";\nimport type { ToolDefinition } from \"../tool-registry.js\";\nimport {\n consumeSSEJSON,\n type SSEConsumeOptions,\n type SSEJSONHandler,\n} from \"./sse.js\";\n\n// ─── 类型定义 ───\n\n/** chat 入参(中)/ Chat handler params aligned with AIClient.chat (EN). */\nexport type ChatHandlerParams = {\n /** 系统提示词 */\n systemPrompt: string;\n /** 对话消息列表 */\n messages: AIMessage[];\n /** 可用工具定义列表 */\n tools?: ToolDefinition[];\n};\n\n/** BaseAIClient 选项(中)/ BaseAIClient constructor options (EN). */\nexport type BaseAIClientOptions = {\n /** 对话处理函数 — 接收 ChatHandlerParams,返回 AIChatResponse */\n chatHandler: (params: ChatHandlerParams) => Promise<AIChatResponse>;\n};\n\nexport {\n consumeSSEJSON,\n type SSEConsumeOptions,\n type SSEJSONHandler,\n} from \"./sse.js\";\n\n// ─── BaseAIClient 类 ───\n\n/**\n * BaseAIClient 实现(中)/ BaseAIClient implementation of AIClient (EN).\n */\nexport class BaseAIClient implements AIClient {\n /** 用户提供的对话处理函数 */\n protected chatHandler: (params: ChatHandlerParams) => Promise<AIChatResponse>;\n\n constructor(options: BaseAIClientOptions) {\n this.chatHandler = options.chatHandler;\n }\n\n /**\n * 发送对话请求(中)/ Dispatch chat request via handler (EN).\n */\n async chat(params: ChatHandlerParams): Promise<AIChatResponse> {\n return this.chatHandler(params);\n }\n\n /** SSE 消费复用入口(中)/ Reusable SSE(JSON) consumer for subclasses (EN). */\n protected async consumeSSEJSON(\n response: Response,\n onEvent: SSEJSONHandler,\n options?: SSEConsumeOptions,\n ): Promise<void> {\n return consumeSSEJSON(response, onEvent, options);\n }\n}\n","/**\n * OpenAI/Copilot 客户端(中)/ OpenAI-compatible client implementation (EN).\n */\nimport type { AIChatResponse, AIMessage, AIToolCall } from \"../types.js\";\nimport type { AIClientConfig, ChatParams, ChatRequestInit } from \"./index.js\";\nimport { BaseAIClient } from \"./custom.js\";\nimport type { ChatHandlerParams } from \"./custom.js\";\nimport { consumeSSEJSON } from \"./sse.js\";\nimport { resolveBaseURL, cleanSchema } from \"./constants.js\";\n\n// ─── OpenAI 原始 API 响应类型 ───\n\n/** OpenAI 工具调用原始类型(中)/ Raw OpenAI tool_call shape (EN). */\ntype OpenAIRawToolCall = {\n id: string;\n type: \"function\";\n function: { name: string; arguments: string };\n};\n\n/** OpenAI 原始响应类型(中)/ Raw OpenAI chat completion response (EN). */\ntype OpenAIRawResponse = {\n choices?: Array<{\n message: {\n content: string | null;\n tool_calls?: OpenAIRawToolCall[];\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n};\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 45000;\nconst JSON_TIMEOUT_RETRY_COUNT = 1;\n\nfunction isRequestTimeoutError(error: unknown): boolean {\n return error instanceof Error && /^AI request timeout \\(\\d+ms\\)$/.test(error.message);\n}\n\nasync function fetchWithTimeout(\n input: RequestInfo | URL,\n init: RequestInit,\n timeoutMs: number,\n): Promise<Response> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n return fetch(input, init);\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n return await fetch(input, {\n ...init,\n signal: controller.signal,\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new Error(`AI request timeout (${timeoutMs}ms)`);\n }\n throw error;\n } finally {\n clearTimeout(timer);\n }\n}\n\n// ─── OpenAIClient 类 ───\n\n/**\n * OpenAIClient 类(中)/ OpenAIClient class for OpenAI & Copilot (EN).\n */\nexport class OpenAIClient extends BaseAIClient {\n /** AI 客户端配置(provider / model / apiKey / baseURL) */\n protected config: AIClientConfig;\n\n constructor(config: AIClientConfig) {\n // 注入 chatHandler — 根据 config.stream 选择流式或 JSON(默认流式)\n super({\n chatHandler: async (params: ChatHandlerParams): Promise<AIChatResponse> => {\n const req = buildOpenAIRequest(this.config, params);\n const useStream = this.config.stream ?? true;\n const requestTimeoutMs = this.config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n if (!useStream) {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= JSON_TIMEOUT_RETRY_COUNT; attempt++) {\n try {\n const res = await fetchWithTimeout(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n }, requestTimeoutMs);\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`AI API ${res.status}: ${errText.slice(0, 500)}`);\n }\n\n const data = await res.json();\n return parseOpenAIResponse(data);\n } catch (error) {\n lastError = error;\n const shouldRetry = attempt < JSON_TIMEOUT_RETRY_COUNT && isRequestTimeoutError(error);\n if (!shouldRetry) throw error;\n }\n }\n\n throw lastError instanceof Error ? lastError : new Error(\"AI request failed\");\n }\n\n // 流式模式:请求体已在 buildOpenAIRequest 中包含 stream 字段\n const streamRes = await fetchWithTimeout(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n }, requestTimeoutMs);\n\n if (!streamRes.ok) {\n const errText = await streamRes.text();\n throw new Error(`AI API ${streamRes.status}: ${errText.slice(0, 500)}`);\n }\n\n const contentType = streamRes.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n const data = await streamRes.json();\n return parseOpenAIResponse(data);\n }\n\n return parseOpenAIStream(streamRes, 20000);\n },\n });\n this.config = config;\n }\n}\n\n// ─── 底层 API:请求构建 ───\n\n/**\n * 构建 OpenAI 请求(中)/ Build OpenAI chat request payload (EN).\n */\nexport function buildOpenAIRequest(\n config: AIClientConfig,\n params: ChatParams,\n): ChatRequestInit {\n const baseURL = resolveBaseURL(config);\n const { systemPrompt, messages, tools } = params;\n\n // 转换工具定义为 OpenAI function calling 格式\n const openaiTools = tools?.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: cleanSchema(t.schema),\n },\n }));\n\n // 转换消息为 OpenAI 格式\n const openaiMessages = convertMessages(systemPrompt, messages);\n\n // 构建请求体\n const body: Record<string, unknown> = {\n model: config.model,\n messages: openaiMessages,\n temperature: 0.3,\n max_tokens: 4096,\n };\n\n if (config.stream ?? true) {\n body.stream = true;\n body.stream_options = { include_usage: true };\n }\n\n if (openaiTools && openaiTools.length > 0) {\n body.tools = openaiTools;\n body.tool_choice = \"auto\";\n body.parallel_tool_calls = config.parallelToolCalls ?? true;\n }\n\n return {\n url: `${baseURL}/chat/completions`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n };\n}\n\n// ─── 响应解析 ───\n\n/**\n * 解析 OpenAI 响应(中)/ Parse raw OpenAI response into AIChatResponse (EN).\n */\nexport function parseOpenAIResponse(data: unknown): AIChatResponse {\n const d = data as OpenAIRawResponse;\n const choice = d.choices?.[0];\n if (!choice) throw new Error(\"AI 未返回有效响应\");\n\n const msg = choice.message;\n\n // 解析工具调用:arguments 是 JSON 字符串,需要 parse 为对象\n const toolCalls: AIToolCall[] | undefined = msg.tool_calls?.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n input: JSON.parse(tc.function.arguments),\n }));\n\n return {\n text: msg.content || undefined,\n toolCalls: toolCalls?.length ? toolCalls : undefined,\n usage: d.usage\n ? {\n inputTokens: d.usage.prompt_tokens ?? 0,\n outputTokens: d.usage.completion_tokens ?? 0,\n }\n : undefined,\n };\n}\n\n// ─── 内部辅助函数 ───\n\n/**\n * 消息转换(中)/ Convert unified messages to OpenAI format (EN).\n */\nfunction convertMessages(\n systemPrompt: string,\n messages: AIMessage[],\n): Record<string, unknown>[] {\n const result: Record<string, unknown>[] = [\n { role: \"system\", content: systemPrompt },\n ];\n\n for (const m of messages) {\n if (m.role === \"tool\" && Array.isArray(m.content)) {\n // 工具结果 → 每个结果单独一条 tool 消息(OpenAI 要求按 tool_call_id 对应)\n for (const tc of m.content) {\n result.push({\n role: \"tool\",\n content: tc.result,\n tool_call_id: tc.toolCallId,\n });\n }\n } else if (m.role === \"assistant\" && m.toolCalls?.length) {\n // AI 回复含工具调用 → 带 tool_calls 字段\n result.push({\n role: \"assistant\",\n content: typeof m.content === \"string\" ? m.content : null,\n tool_calls: m.toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\",\n function: {\n name: tc.name,\n arguments: JSON.stringify(tc.input),\n },\n })),\n });\n } else {\n // 普通消息(user / assistant 纯文本)\n result.push({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : JSON.stringify(m.content),\n });\n }\n }\n\n return result;\n}\n\n// ─── 流式响应解析 ───\n\n/** 流式 tool_call 增量类型(中)/ Tool-call delta type in SSE stream (EN). */\ntype OpenAIStreamToolCallDelta = {\n index: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n};\n\n/** 流式 chunk 类型(中)/ SSE chunk type (EN). */\ntype OpenAIStreamChunk = {\n choices?: Array<{\n delta: {\n content?: string;\n tool_calls?: OpenAIStreamToolCallDelta[];\n };\n }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n};\n\n/**\n * 解析 OpenAI SSE(中)/ Parse OpenAI SSE stream into unified response (EN).\n */\nexport async function parseOpenAIStream(\n response: Response,\n readTimeoutMs = 20000,\n): Promise<AIChatResponse> {\n // 回退:无 ReadableStream 支持\n if (!response.body) {\n const data = await response.json();\n return parseOpenAIResponse(data);\n }\n\n let text = \"\";\n const toolCallMap = new Map<number, { id: string; name: string; arguments: string }>();\n let usage: AIChatResponse[\"usage\"];\n await consumeSSEJSON(\n response,\n (event) => {\n const chunk = event as OpenAIStreamChunk;\n const delta = chunk.choices?.[0]?.delta;\n\n if (delta?.content) text += delta.content;\n\n if (delta?.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index ?? 0;\n const existing = toolCallMap.get(idx);\n if (existing) {\n if (tc.function?.arguments) existing.arguments += tc.function.arguments;\n } else {\n toolCallMap.set(idx, {\n id: tc.id ?? \"\",\n name: tc.function?.name ?? \"\",\n arguments: tc.function?.arguments ?? \"\",\n });\n }\n }\n }\n\n if (chunk.usage) {\n usage = {\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n };\n }\n },\n { readTimeoutMs, stopOnDone: true },\n );\n\n // 组装工具调用\n const toolCalls: AIToolCall[] = [];\n for (const [, tc] of [...toolCallMap.entries()].sort((a, b) => a[0] - b[0])) {\n try {\n toolCalls.push({ id: tc.id, name: tc.name, input: JSON.parse(tc.arguments) });\n } catch {\n // 工具参数 JSON 解析失败,跳过\n }\n }\n\n return {\n text: text || undefined,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage,\n };\n}\n","/**\n * Anthropic 客户端实现(中)/ Anthropic Messages API client implementation (EN).\n */\nimport type { AIChatResponse, AIMessage, AIToolCall } from \"../types.js\";\nimport type { AIClientConfig, ChatParams, ChatRequestInit } from \"./index.js\";\nimport { BaseAIClient } from \"./custom.js\";\nimport type { ChatHandlerParams } from \"./custom.js\";\nimport { consumeSSEJSON } from \"./sse.js\";\nimport { resolveBaseURL, cleanSchema } from \"./constants.js\";\n\n// ─── Anthropic 原始 API 响应类型 ───\n\n/** Anthropic 文本块(中)/ Anthropic text block (EN). */\ntype AnthropicTextBlock = {\n type: \"text\";\n text: string;\n};\n\n/** Anthropic 工具调用块(中)/ Anthropic tool_use block (EN). */\ntype AnthropicToolUseBlock = {\n type: \"tool_use\";\n id: string;\n name: string;\n input: unknown;\n};\n\n/** Anthropic 内容块联合类型(中)/ Anthropic content block union (EN). */\ntype AnthropicContentBlock = AnthropicTextBlock | AnthropicToolUseBlock;\n\n/** Anthropic 原始响应类型(中)/ Raw Anthropic response type (EN). */\ntype AnthropicRawResponse = {\n content?: AnthropicContentBlock[];\n usage?: {\n input_tokens: number;\n output_tokens: number;\n };\n};\n\n// ─── AnthropicClient 类 ───\n\n/**\n * AnthropicClient 类(中)/ AnthropicClient class (EN).\n */\nexport class AnthropicClient extends BaseAIClient {\n /** AI 客户端配置(provider / model / apiKey / baseURL) */\n protected config: AIClientConfig;\n\n constructor(config: AIClientConfig) {\n // 注入 chatHandler — 根据 config.stream 选择流式或 JSON(默认流式)\n super({\n chatHandler: async (params: ChatHandlerParams): Promise<AIChatResponse> => {\n const req = buildAnthropicRequest(this.config, params);\n const useStream = this.config.stream ?? true;\n\n if (!useStream) {\n const res = await fetch(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`AI API ${res.status}: ${errText.slice(0, 500)}`);\n }\n\n const data = await res.json();\n return parseAnthropicResponse(data);\n }\n\n // 流式模式:请求体已在 buildAnthropicRequest 中包含 stream 字段\n const res = await fetch(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`AI API ${res.status}: ${errText.slice(0, 500)}`);\n }\n\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n const data = await res.json();\n return parseAnthropicResponse(data);\n }\n\n return parseAnthropicStream(res);\n },\n });\n this.config = config;\n }\n}\n\n// ─── 底层 API:请求构建 ───\n\n/**\n * 构建 Anthropic 请求(中)/ Build Anthropic Messages API request (EN).\n */\nexport function buildAnthropicRequest(\n config: AIClientConfig,\n params: ChatParams,\n): ChatRequestInit {\n const baseURL = resolveBaseURL(config);\n const { systemPrompt, messages, tools } = params;\n\n // 转换工具定义为 Anthropic 格式(input_schema 而非 parameters)\n const anthropicTools = tools?.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: cleanSchema(t.schema),\n }));\n\n // 转换消息为 Anthropic 格式(过滤掉 system 角色消息)\n const anthropicMessages = convertMessages(messages);\n\n // 构建请求体 — system 作为顶层字段\n const body: Record<string, unknown> = {\n model: config.model,\n max_tokens: config.model.includes(\"opus\") ? 16384 : 8192,\n system: systemPrompt,\n messages: anthropicMessages,\n };\n\n if (config.stream ?? true) {\n body.stream = true;\n }\n\n if (anthropicTools && anthropicTools.length > 0) {\n body.tools = anthropicTools;\n }\n\n return {\n url: `${baseURL}/v1/messages`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": config.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n };\n}\n\n// ─── 响应解析 ───\n\n/**\n * 解析 Anthropic 响应(中)/ Parse raw Anthropic response (EN).\n */\nexport function parseAnthropicResponse(data: unknown): AIChatResponse {\n const d = data as AnthropicRawResponse;\n\n // 提取所有文本块,合并为单个字符串\n const text = d.content\n ?.filter((b): b is AnthropicTextBlock => b.type === \"text\")\n .map((b) => b.text)\n .join(\"\");\n\n // 提取所有工具调用块\n const toolCalls: AIToolCall[] | undefined = d.content\n ?.filter((b): b is AnthropicToolUseBlock => b.type === \"tool_use\")\n .map((b) => ({\n id: b.id,\n name: b.name,\n input: b.input,\n }));\n\n return {\n text: text || undefined,\n toolCalls: toolCalls?.length ? toolCalls : undefined,\n usage: d.usage\n ? {\n inputTokens: d.usage.input_tokens,\n outputTokens: d.usage.output_tokens,\n }\n : undefined,\n };\n}\n\n// ─── 内部辅助函数 ───\n\n/**\n * 消息格式转换(中)/ Convert unified messages to Anthropic format (EN).\n */\nfunction convertMessages(\n messages: AIMessage[],\n): Record<string, unknown>[] {\n return messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n if (m.role === \"tool\" && Array.isArray(m.content)) {\n // 工具结果 → Anthropic 用 user 角色 + tool_result content block\n return {\n role: \"user\" as const,\n content: m.content.map((tc) => ({\n type: \"tool_result\" as const,\n tool_use_id: tc.toolCallId,\n content: tc.result,\n })),\n };\n }\n if (m.role === \"assistant\" && m.toolCalls?.length) {\n // AI 回复含工具调用 → text block + tool_use blocks\n const content: Record<string, unknown>[] = [];\n if (m.content && typeof m.content === \"string\") {\n content.push({ type: \"text\", text: m.content });\n }\n for (const tc of m.toolCalls) {\n content.push({\n type: \"tool_use\",\n id: tc.id,\n name: tc.name,\n input: tc.input,\n });\n }\n return { role: \"assistant\" as const, content };\n }\n // 普通消息(user / assistant 纯文本)\n return {\n role: m.role as \"user\" | \"assistant\",\n content:\n typeof m.content === \"string\"\n ? m.content\n : JSON.stringify(m.content),\n };\n });\n}\n\n// ─── 流式响应解析 ───\n\n/**\n * 解析 Anthropic SSE(中)/ Parse Anthropic SSE stream (EN).\n */\nexport async function parseAnthropicStream(response: Response): Promise<AIChatResponse> {\n // 回退:无 ReadableStream 支持\n if (!response.body) {\n const data = await response.json();\n return parseAnthropicResponse(data);\n }\n\n let text = \"\";\n const toolCalls: AIToolCall[] = [];\n let currentToolUse: { id: string; name: string; inputJson: string } | null = null;\n let inputTokens = 0;\n let outputTokens = 0;\n await consumeSSEJSON(\n response,\n (event) => {\n switch (event.type) {\n case \"message_start\": {\n const msg = event.message as { usage?: { input_tokens?: number } } | undefined;\n inputTokens = msg?.usage?.input_tokens ?? 0;\n break;\n }\n\n case \"content_block_start\": {\n const block = event.content_block as { type: string; id?: string; name?: string } | undefined;\n if (block?.type === \"tool_use\") {\n currentToolUse = { id: block.id ?? \"\", name: block.name ?? \"\", inputJson: \"\" };\n }\n break;\n }\n\n case \"content_block_delta\": {\n const delta = event.delta as { type: string; text?: string; partial_json?: string } | undefined;\n if (delta?.type === \"text_delta\") {\n text += delta.text ?? \"\";\n } else if (delta?.type === \"input_json_delta\" && currentToolUse) {\n currentToolUse.inputJson += delta.partial_json ?? \"\";\n }\n break;\n }\n\n case \"content_block_stop\":\n if (currentToolUse) {\n try {\n toolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n input: JSON.parse(currentToolUse.inputJson || \"{}\"),\n });\n } catch {\n // 工具参数 JSON 解析失败,跳过\n }\n currentToolUse = null;\n }\n break;\n\n case \"message_delta\": {\n const deltaUsage = (event as { usage?: { output_tokens?: number } }).usage;\n outputTokens = deltaUsage?.output_tokens ?? 0;\n break;\n }\n }\n },\n { stopOnDone: false },\n );\n\n return {\n text: text || undefined,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: inputTokens > 0 || outputTokens > 0 ? { inputTokens, outputTokens } : undefined,\n };\n}\n","/**\n * DeepSeek 客户端封装(中)/ DeepSeek client wrapper (EN).\n *\n * DeepSeek 与 OpenAI Chat Completions 兼容,直接复用 OpenAIClient。\n * DeepSeek is OpenAI-compatible, so it reuses OpenAIClient behavior.\n */\nimport { OpenAIClient } from \"./openai.js\";\n\n/**\n * DeepSeek 客户端类(中)/ DeepSeek client class extending OpenAIClient (EN).\n */\nexport class DeepSeekClient extends OpenAIClient {}\n","/**\n * Doubao 客户端封装(中)/ Doubao client wrapper (EN).\n *\n * Doubao(火山引擎 Ark)与 OpenAI Chat Completions 兼容,直接复用 OpenAIClient。\n * Doubao (Volcengine Ark) is OpenAI-compatible, so it reuses OpenAIClient behavior.\n */\nimport { OpenAIClient } from \"./openai.js\";\n\n/**\n * Doubao 客户端类(中)/ Doubao client class extending OpenAIClient (EN).\n */\nexport class DoubaoClient extends OpenAIClient {}\n","/**\n * Qwen 客户端封装(中)/ Qwen client wrapper (EN).\n *\n * Qwen(阿里云百炼兼容模式)与 OpenAI Chat Completions 兼容,直接复用 OpenAIClient。\n * Qwen (DashScope compatible mode) is OpenAI-compatible, so it reuses OpenAIClient behavior.\n */\nimport { OpenAIClient } from \"./openai.js\";\n\n/**\n * Qwen 客户端类(中)/ Qwen client class extending OpenAIClient (EN).\n */\nexport class QwenClient extends OpenAIClient {}\n","/**\n * AI 客户端主入口(中)/ AI client entrypoint based on fetch (EN).\n *\n * 提供 provider 路由与统一类型导出。\n * Provides provider routing and unified type exports.\n */\nimport type { AIClient, AIChatResponse, AIMessage } from \"../types.js\";\nimport type { ToolDefinition } from \"../tool-registry.js\";\nimport { validateProvider } from \"./constants.js\";\nimport { OpenAIClient } from \"./openai.js\";\nimport { AnthropicClient } from \"./anthropic.js\";\nimport { DeepSeekClient } from \"./deepseek.js\";\nimport { DoubaoClient } from \"./doubao.js\";\nimport { QwenClient } from \"./qwen.js\";\n\n// Re-export 类型,方便外部统一从 ai-client 导入\nexport type { AIClient, AIChatResponse, AIMessage, AIToolCall } from \"../types.js\";\n\n// Re-export 客户端类(基类 + OpenAI + Anthropic)\nexport { BaseAIClient, type BaseAIClientOptions, type ChatHandlerParams } from \"./custom.js\";\nexport { OpenAIClient, parseOpenAIStream } from \"./openai.js\";\nexport { AnthropicClient, parseAnthropicStream } from \"./anthropic.js\";\nexport { DeepSeekClient } from \"./deepseek.js\";\nexport { DoubaoClient } from \"./doubao.js\";\nexport { QwenClient } from \"./qwen.js\";\n\n// ─── 公共类型定义 ───\n\n/** AI 客户端配置(中)/ AI client configuration (EN). */\nexport type AIClientConfig = {\n /** AI 提供商: \"openai\" | \"copilot\" | \"anthropic\" | \"deepseek\" | \"doubao\" | \"qwen\" */\n provider: string;\n /** 模型名称,如 \"gpt-4o\"、\"claude-sonnet-4-20250514\" */\n model: string;\n /** API Key / Token */\n apiKey: string;\n /** 自定义 API 基础 URL(可选,如本地 Ollama: http://localhost:11434/v1) */\n baseURL?: string;\n /** 是否启用流式输出(SSE)。默认 true;传 false 时使用 JSON 非流式响应。 */\n stream?: boolean;\n /** 单次请求超时(毫秒,默认 45000;<=0 表示不设置超时)。 */\n requestTimeoutMs?: number;\n /** 是否允许模型并行返回多个工具调用(默认 true)。 */\n parallelToolCalls?: boolean;\n};\n\n/** 统一 chat 入参(中)/ Unified chat parameters (EN). */\nexport type ChatParams = {\n /** 系统提示词 */\n systemPrompt: string;\n /** 对话消息列表 */\n messages: AIMessage[];\n /** 可用工具定义列表 */\n tools?: ToolDefinition[];\n};\n\n/**\n * HTTP 请求对象(中)/ Built HTTP request init payload (EN).\n */\nexport type ChatRequestInit = {\n /** 请求 URL */\n url: string;\n /** HTTP 方法 */\n method: \"POST\";\n /** 请求头 */\n headers: Record<string, string>;\n /** 请求体(JSON 字符串) */\n body: string;\n};\n\n// ─── 高层 API ───\n\n/**\n * 创建 AI 客户端(中)/ Create AI client by provider (EN).\n */\nexport function createAIClient(config: AIClientConfig): AIClient {\n validateProvider(config.provider);\n\n switch (config.provider) {\n case \"openai\":\n case \"copilot\":\n return new OpenAIClient(config);\n case \"doubao\":\n return new DoubaoClient(config);\n case \"qwen\":\n return new QwenClient(config);\n case \"anthropic\":\n return new AnthropicClient(config);\n case \"deepseek\":\n return new DeepSeekClient(config);\n default:\n throw new Error(\n `Unknown AI provider: ${config.provider}. Supported: openai, copilot, anthropic, deepseek, doubao, qwen`,\n );\n }\n}\n","/**\n * Tool Registry — 工具注册表,负责工具的注册、查询和分发。\n *\n * 实例化设计 — 每个 Agent 创建独立的 ToolRegistry,避免全局状态污染:\n *\n * // Node 端\n * const registry = new ToolRegistry();\n * registerBuiltinTools(registry); // 注册 exec, file, browser...\n * await executeAgentLoop({ registry, ... });\n *\n * // Web 端\n * const registry = new ToolRegistry();\n * registerWebTools(registry); // 注册 dom, navigate...\n * await executeAgentLoop({ registry, ... });\n *\n * 优点:\n * - 多实例安全:Node Agent 和 Web Agent 可并行运行,工具列表互不干扰\n * - 测试隔离:每个 test case 创建独立 registry,无需清理全局状态\n * - 可组合:可按需注册不同工具子集\n */\nimport type { TObject } from \"@sinclair/typebox\";\nexport { jsonResult, readNumberParam, readStringParam } from \"./tool-params.js\";\n\n/**\n * 工具执行结果 — 每个工具的 execute() 必须返回此类型。\n */\nexport type ToolCallResult = {\n /** 返回内容(字符串文本或结构化对象,最终会序列化后发给 AI) */\n content: string | Record<string, unknown>;\n /** 可选的额外细节(用于日志记录、调试等,不直接发给 AI) */\n details?: Record<string, unknown>;\n};\n\n/**\n * 工具定义 — 注册工具时需要提供的完整描述。\n *\n * 这四个字段分别告诉 AI「叫什么名字」「能做什么」「需要什么参数」「怎么执行」:\n * - name + description → AI 根据用户意图选择合适的工具\n * - schema → AI 生成符合格式的参数 JSON\n * - execute → 实际执行逻辑\n */\nexport type ToolDefinition = {\n /** 工具名称(AI 通过此名称调用,如 \"exec\"、\"file_read\") */\n name: string;\n /** 工具描述(AI 据此判断何时使用这个工具) */\n description: string;\n /** 参数的 JSON Schema(TypeBox 定义,描述工具接受哪些参数及其类型) */\n schema: TObject;\n /** 执行函数 — 接收 AI 传入的参数,返回执行结果 */\n execute: (params: Record<string, unknown>) => Promise<ToolCallResult>;\n};\n\n/**\n * 工具注册表实例 — 管理一组工具的注册、查询和分发。\n *\n * 每个 Agent 拥有独立的 ToolRegistry 实例,从而:\n * - Node Agent 的 exec/file 工具不会泄漏到 Web Agent\n * - Web Agent 的 dom/navigate 工具不会泄漏到 Node Agent\n * - 测试中不同 case 互不影响\n */\nexport class ToolRegistry {\n private tools = new Map<string, ToolDefinition>();\n\n /** 注册一个工具 */\n register(tool: ToolDefinition): void {\n this.tools.set(tool.name, tool);\n }\n\n /** 获取所有已注册的工具定义列表(发给 AI,告知可用工具) */\n getDefinitions(): ToolDefinition[] {\n return Array.from(this.tools.values());\n }\n\n /** 按名称检查工具是否已注册。 */\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n /** 按名称注销工具,返回是否删除成功。 */\n unregister(name: string): boolean {\n return this.tools.delete(name);\n }\n\n /**\n * 根据工具名分发并执行工具调用。\n * - 找到工具 → 执行 execute() → 返回结果\n * - 找不到 → 返回错误信息(不抛异常,让 AI 知道工具不存在)\n * - 执行出错 → 捕获异常,返回错误信息(不中断 Agent 循环)\n */\n async dispatch(name: string, input: unknown): Promise<ToolCallResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n return {\n content: `Unknown tool: ${name}`,\n details: { error: true, toolName: name },\n };\n }\n\n try {\n const params = (input ?? {}) as Record<string, unknown>;\n return await tool.execute(params);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: `Tool \"${name}\" failed: ${message}`,\n details: { error: true, toolName: name, message },\n };\n }\n }\n}\n","/**\n * 极简系统提示词构建器。\n *\n * 纯函数,不依赖运行时环境;调用方只需传入工具定义和可选扩展指令。\n *\n * 职责:\n * - 组装发送给 AI 的 system prompt(英文正文)\n * - 包含核心规则、工具列表、事件简写表、输出协议\n * - 支持额外自定义指令注入\n *\n * 约束(来自 AGENTS.md §11):\n * - 发送给模型的 prompt 正文统一英文\n * - 中文仅用于源码注释\n *\n * 调用方:\n * - `agent-loop/index.ts` 在循环启动时调用 `buildSystemPrompt()` 构建系统消息\n * - `web/index.ts` 的 WebAgent 通过 systemPrompt 配置传入额外指令\n */\n/**\n * 系统提示词构建参数。\n *\n * 所有字段可选:\n * - thinkingLevel:AI 思考深度标签(如 \"high\"/\"medium\"),影响推理行为\n * - listenerEvents:快照中实际会输出的 listener 事件集合,用于同步缩写说明\n * - extraInstructions:额外英文指令,追加到 \"## Extra Instructions\" 章节\n */\nexport type SystemPromptParams = {\n /** AI 思考深度标签。 */\n thinkingLevel?: string;\n /** 允许在 Listener Abbrevs 中输出的事件白名单。 */\n listenerEvents?: string[];\n /** 额外英文指令(字符串或字符串数组)。 */\n extraInstructions?: string | string[];\n};\n\nconst LISTENER_ABBREV_MAP: Record<string, string> = {\n click: \"clk\",\n dblclick: \"dbl\",\n mousedown: \"mdn\",\n mouseup: \"mup\",\n mousemove: \"mmv\",\n mouseover: \"mov\",\n mouseout: \"mot\",\n mouseenter: \"men\",\n mouseleave: \"mlv\",\n pointerdown: \"pdn\",\n pointerup: \"pup\",\n pointermove: \"pmv\",\n touchstart: \"tst\",\n touchend: \"ted\",\n keydown: \"kdn\",\n keyup: \"kup\",\n input: \"inp\",\n change: \"chg\",\n submit: \"sub\",\n focus: \"fcs\",\n blur: \"blr\",\n scroll: \"scl\",\n wheel: \"whl\",\n drag: \"drg\",\n dragstart: \"drs\",\n dragend: \"dre\",\n drop: \"drp\",\n contextmenu: \"ctx\",\n};\n\nconst DEFAULT_SYSTEM_PROMPT_LISTENER_EVENTS = [\n \"click\",\n \"input\",\n \"change\",\n \"mousedown\",\n \"pointerdown\",\n \"keydown\",\n \"submit\",\n \"focus\",\n \"blur\",\n];\n\nfunction buildListenerAbbrevLine(listenerEvents?: string[]): string {\n const allowed = (listenerEvents && listenerEvents.length > 0)\n ? listenerEvents\n : DEFAULT_SYSTEM_PROMPT_LISTENER_EVENTS;\n\n const normalized = allowed\n .map(event => event.trim().toLowerCase())\n .filter(Boolean);\n\n const unique = [...new Set(normalized)];\n const pairs = unique\n .map(event => {\n const abbrev = LISTENER_ABBREV_MAP[event];\n return abbrev ? `${abbrev}=${event}` : null;\n })\n .filter((pair): pair is string => !!pair);\n\n return pairs.join(\" \");\n}\n\n/**\n * 规范化额外指令:统一转为非空字符串数组。\n *\n * - 单字符串 → 单元素数组\n * - 字符串数组 → 过滤空值\n * - undefined → 空数组\n */\nfunction normalizeExtraInstructions(input?: string | string[]): string[] {\n if (!input) return [];\n const rawList = Array.isArray(input) ? input : [input];\n return rawList.map(s => s.trim()).filter(Boolean);\n}\n\n/**\n * 构建系统提示词。\n *\n * 输出结构(按章节顺序):\n * 1. **Core Rules** — Agent 核心行为规则\n * - 快照驱动决策:仅基于当前快照 + 剩余任务工作\n * - 增量消费模型:每轮执行后输出 REMAINING 推进任务\n * - hash ID 定位:仅交互元素携带 #hashID,非交互元素为上下文\n * - 事件信号:listeners=\"...\" 标注运行时事件绑定\n * - 批量执行:同轮完成所有独立可见操作\n * - 输入顺序:fill/type 前必须先 focus/click 同一目标\n * - DOM 变化断轮:会改变 DOM 的动作执行后等待下一轮新快照\n * - 停机规则:任务完成后输出 REMAINING: DONE\n *\n * 2. **Listener Abbrevs** — 事件简写对照表\n * - 快照中 listeners=\"clk,inp,chg\" 的简写含义\n * - 与 page-info-tool.ts 的 EVENT_ABBREV 映射一致\n *\n * 3. **Output Contract** — 输出协议\n * - 每轮返回工具调用 + REMAINING 文本行\n *\n * 4. **Reasoning Profile**(可选) — 思考深度配置\n *\n * 5. **Extra Instructions**(可选) — 用户自定义额外指令\n *\n * @param params - 构建参数(工具列表、思考深度、额外指令)\n * @returns 完整的系统提示词字符串(英文)\n */\nexport function buildSystemPrompt(params: SystemPromptParams = {}): string {\n const sections: string[] = [];\n\n // ─── 章节 1:角色定义 + 核心规则 ───\n // 这是 prompt 最核心的部分,定义了 Agent 的行为模式和约束。\n // 规则按重要性排列,每条规则对应一个具体的行为约束。\n sections.push(\n [\n \"You are AutoPilot, an AI agent controlling the current web page via tools.\",\n \"\",\n \"## Core Rules\",\n\n \"- Work from CURRENT snapshot + remaining task. Do not restate.\",\n \"- Task reduction: (remaining, prev actions, this-round) → new remaining.\",\n \"- Use #hashID from snapshot as selector. Do not guess CSS selectors.\",\n \"- Only interactive elements carry #hashID; others are context-only and cannot be targeted.\",\n\n \"- Bracket tag may show ARIA role ([combobox], [slider]) as primary interaction hint.\",\n \"- listeners=\\\"...\\\" = bound event handlers (abbrevs below). Prefer targets with matching listeners.\",\n \"- Click priority: clk/pdn/mdn, onclick, native link/button, role=button/link. Avoid focus-only or hover-only signals.\",\n \"- No-effect fallback: try nearest actionable sibling/ancestor in same semantic group instead of repeating.\",\n\n \"- Batch fill/type/check/select_option freely within one round. A click always ends the round — send at most ONE click as the LAST action in a batch.\",\n \"- Input order (MANDATORY): focus/click → fill/type/select_option per target. Multi-field: focus A→fill A→focus B→fill B.\",\n \"- Search/filter inputs: after fill, press Enter (or click search button) to trigger the search. Do not assume fill alone submits.\",\n \"- Do NOT run focus-only batches. Each focus must be immediately followed by its fill/type/select_option.\",\n\n \"- Steppers: compute delta from visible value, click exactly |delta| times. Check/uncheck: target real input control.\",\n \"- DOM-changing action (click/modal/navigate): ends the round, next snapshot follows. Actions sent after a click in the same batch are discarded.\",\n \"- Intermediate progress is NOT completion: if an action only opens, expands, reveals, filters, paginates, switches context, or loads the next step, keep REMAINING on the final user goal until the requested end state/value/content is visible in the snapshot.\",\n \"- Effect check: before planning new actions, confirm previous actions' expected effects are visible in current snapshot. If not, the action failed — try a different target instead of repeating.\",\n \"- Do NOT call page_info — snapshot is auto-refreshed and provided every round. Do NOT use get_text/get_attr to read what is already visible in the snapshot.\",\n \"- Never repeat the same tool call (same name + same args) on the same target. If it didn't work, try a different approach.\",\n \"- Dropdown/select: prefer dom.select_option (works in one round). For custom dropdowns requiring click-to-open: click → wait for next snapshot → click option (two rounds).\",\n \"- Omitted children: output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>`, wait for next snapshot.\",\n \"- Do NOT verify values unless user explicitly asks.\",\n \"- Stop: when remaining task is fully achieved (confirmed in snapshot), output REMAINING: DONE with a summary.\",\n \"- Do NOT interact with AutoPilot UI unless user asks.\",\n \"\",\n\n // ─── 事件简写对照表 ───\n \"## Listener Abbrevs\",\n buildListenerAbbrevLine(params.listenerEvents),\n \"\",\n // ─── 输出协议 + 极简示例 ───\n \"## Output\",\n \"Tool calls + one text line: REMAINING: <new remaining> or REMAINING: DONE\",\n \"Example: Task A→B→C. Round1 do A → REMAINING: B→C. Round2 do B → REMAINING: C. Round3 do C → REMAINING: DONE\",\n ].join(\"\\n\"),\n );\n\n // ─── 章节 4(可选):思考深度配置 ───\n // 影响模型的推理深度(如 \"high\" 表示复杂任务需深度思考)。\n if (params.thinkingLevel) {\n sections.push(\n [\n \"## Reasoning Profile\",\n `- Thinking level: ${params.thinkingLevel}`,\n ].join(\"\\n\"),\n );\n }\n\n // ─── 章节 5(可选):额外自定义指令 ───\n // 由 WebAgent 使用方通过 extraInstructions 配置传入。\n // 典型用途:业务特定规则、UI 框架提示、测试场景约束等。\n const extraInstructions = normalizeExtraInstructions(params.extraInstructions);\n if (extraInstructions.length > 0) {\n sections.push(\n [\n \"## Extra Instructions\",\n ...extraInstructions.map(line => `- ${line}`),\n ].join(\"\\n\"),\n );\n }\n\n return sections.join(\"\\n\\n\");\n}\n","/**\n * 全局事件监听追踪器(浏览器端)。\n *\n * 设计目标:\n * 1. 从 EventTarget.prototype 统一拦截 add/removeEventListener\n * 2. 仅记录 Element 实例,避免污染 document/window 等\n * 3. 不改变原调用语义:先执行原方法,再做追踪记录\n * 4. 追踪失败时静默兜底,不影响业务代码执行\n */\n\ntype AddEventListenerFn = EventTarget[\"addEventListener\"];\ntype RemoveEventListenerFn = EventTarget[\"removeEventListener\"];\n\nconst elementEventMap = new WeakMap<Element, Set<string>>();\n\nlet installed = false;\nlet originalAddEventListener: AddEventListenerFn | undefined;\nlet originalRemoveEventListener: RemoveEventListenerFn | undefined;\n\nfunction normalizeEventType(type: unknown): string | null {\n if (typeof type !== \"string\") return null;\n const normalized = type.trim().toLowerCase();\n return normalized || null;\n}\n\nfunction canTrackElementTarget(target: EventTarget): target is Element {\n if (typeof Element === \"undefined\") return false;\n return target instanceof Element;\n}\n\nfunction trackElementEvent(target: EventTarget, type: string): void {\n if (!canTrackElementTarget(target)) return;\n const prev = elementEventMap.get(target);\n if (prev) {\n prev.add(type);\n return;\n }\n elementEventMap.set(target, new Set([type]));\n}\n\nfunction untrackElementEvent(target: EventTarget, type: string): void {\n if (!canTrackElementTarget(target)) return;\n const prev = elementEventMap.get(target);\n if (!prev) return;\n prev.delete(type);\n if (prev.size === 0) {\n elementEventMap.delete(target);\n }\n}\n\n/**\n * 安装全局监听追踪补丁(幂等)。\n */\nexport function installEventListenerTracking(): void {\n if (installed) return;\n if (typeof EventTarget === \"undefined\") return;\n\n const proto = EventTarget.prototype;\n const nativeAdd = proto.addEventListener;\n const nativeRemove = proto.removeEventListener;\n\n if (typeof nativeAdd !== \"function\" || typeof nativeRemove !== \"function\") return;\n\n originalAddEventListener = nativeAdd;\n originalRemoveEventListener = nativeRemove;\n\n proto.addEventListener = function patchedAddEventListener(\n this: EventTarget,\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions,\n ): void {\n originalAddEventListener?.call(this, type, listener, options);\n try {\n const normalizedType = normalizeEventType(type);\n if (!normalizedType || listener == null) return;\n trackElementEvent(this, normalizedType);\n } catch {\n // 追踪失败不应影响业务逻辑\n }\n };\n\n proto.removeEventListener = function patchedRemoveEventListener(\n this: EventTarget,\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions,\n ): void {\n originalRemoveEventListener?.call(this, type, listener, options);\n try {\n const normalizedType = normalizeEventType(type);\n if (!normalizedType || listener == null) return;\n untrackElementEvent(this, normalizedType);\n } catch {\n // 追踪失败不应影响业务逻辑\n }\n };\n\n installed = true;\n}\n\n/**\n * 读取元素已记录的事件名(排序后返回,便于稳定输出)。\n */\nexport function getTrackedElementEvents(el: Element): string[] {\n const set = elementEventMap.get(el);\n if (!set || set.size === 0) return [];\n return Array.from(set).sort();\n}\n\n/**\n * 判断元素是否存在至少一个被追踪到的事件绑定。\n */\nexport function hasTrackedElementEvents(el: Element): boolean {\n return (elementEventMap.get(el)?.size ?? 0) > 0;\n}\n","/**\n * DOM Tool — 浏览器 DOM 操作工具(结合 Playwright 核心交互模式增强)。\n *\n * 关键改进(参考 Playwright):\n * 1. retarget — 点击时自动重定向到 button/link/label.control\n * 2. scrollIntoView 多策略 — 4 种 block 对齐轮换,解决 sticky 遮挡\n * 3. stable 检查 — rAF 逐帧检测元素位置稳定后再操作\n * 4. hit-target 验证 — elementsFromPoint 检查是否被遮挡\n * 5. 完整点击事件链 — pointermove→pointerdown→mousedown→pointerup→mouseup→click\n * 6. check/uncheck 通过 click — 先检查→click 切换→验证状态\n * 7. press 组合键 — 支持 Control+a, Shift+Enter 等修饰键\n * 8. fill 分类型 — date/color/range 走 setValue,text 类走 selectAll+原生写入\n * 9. 自定义下拉增强 — 更广泛的 option 选择器 + 等待弹出\n * 10. ARIA disabled — 检查祖先链 aria-disabled\n *\n * 运行环境:浏览器 Content Script(直接访问 DOM,无 CDP)。\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport type { RefStore } from \"../ref-store.js\";\nimport { getTrackedElementEvents } from \"../event-listener-tracker.js\";\n\n// ─── 常量 ───\n\nconst DEFAULT_WAIT_MS = 1200;\n\n/** scrollIntoView 轮换策略(参考 Playwright dom.ts) */\nconst SCROLL_OPTIONS: (ScrollIntoViewOptions | undefined)[] = [\n undefined,\n { block: \"end\", inline: \"end\" },\n { block: \"center\", inline: \"center\" },\n { block: \"start\", inline: \"start\" },\n];\n\n/** fill 时直接 setValue 的 input 类型(参考 Playwright kInputTypesToSetValue) */\nconst INPUT_SET_VALUE_TYPES = new Set([\n \"color\", \"date\", \"time\", \"datetime-local\", \"month\", \"range\", \"week\",\n]);\n\n/** fill 时走 selectText+写入 的 input 类型 */\nconst INPUT_TYPE_INTO_TYPES = new Set([\n \"\", \"email\", \"number\", \"password\", \"search\", \"tel\", \"text\", \"url\",\n]);\n\n/** 不可 fill 的 input 类型 */\nconst INPUT_BLOCKED_TYPES = new Set([\n \"checkbox\", \"radio\", \"file\", \"button\", \"submit\", \"reset\", \"image\",\n]);\n\n/** 修饰键集合 */\nconst MODIFIER_KEYS = new Set([\"Control\", \"Shift\", \"Alt\", \"Meta\"]);\n\n/** 键名→code 映射 */\nconst KEY_CODE_MAP: Record<string, string> = {\n Enter: \"Enter\", Escape: \"Escape\", Esc: \"Escape\",\n Tab: \"Tab\", Space: \"Space\", \" \": \"Space\",\n Backspace: \"Backspace\", Delete: \"Delete\",\n ArrowUp: \"ArrowUp\", ArrowDown: \"ArrowDown\",\n ArrowLeft: \"ArrowLeft\", ArrowRight: \"ArrowRight\",\n Home: \"Home\", End: \"End\", PageUp: \"PageUp\", PageDown: \"PageDown\",\n Control: \"ControlLeft\", Shift: \"ShiftLeft\", Alt: \"AltLeft\", Meta: \"MetaLeft\",\n};\n\nconst FILL_RELEVANT_EVENTS = new Set([\n \"input\", \"change\", \"focus\", \"blur\", \"keydown\",\n \"click\", \"mousedown\", \"pointerdown\",\n]);\n\n// ─── 模块状态 ───\n\nlet activeRefStore: RefStore | undefined;\n\nexport function setActiveRefStore(store: RefStore | undefined): void {\n activeRefStore = store;\n}\n\nexport function getActiveRefStore(): RefStore | undefined {\n return activeRefStore;\n}\n\n// ─── 基础工具 ───\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\n/** 查询元素:优先 RefStore hash,回退 CSS 选择器 */\nfunction queryElement(selector: string): Element | string {\n try {\n if (selector.startsWith(\"#\") && activeRefStore) {\n const id = selector.slice(1);\n if (activeRefStore.has(id)) {\n const el = activeRefStore.get(id);\n if (!el) return `未找到 ref \"${selector}\" 对应的元素(可能已被移除或快照已过期)`;\n return el;\n }\n }\n const el = document.querySelector(selector);\n if (!el) return `未找到匹配 \"${selector}\" 的元素`;\n return el;\n } catch {\n return `选择器语法错误: ${selector}`;\n }\n}\n\n/** 轮询等待元素出现 */\nasync function waitForElement(selector: string, timeoutMs: number): Promise<Element | string | null> {\n const start = Date.now();\n while (Date.now() - start <= timeoutMs) {\n const r = queryElement(selector);\n if (typeof r !== \"string\") return r;\n if (r.startsWith(\"选择器语法错误\")) return r;\n await sleep(100);\n }\n return null;\n}\n\nfunction resolveWaitMs(params: Record<string, unknown>): number {\n const waitMs = params.waitMs;\n if (typeof waitMs === \"number\" && Number.isFinite(waitMs)) return Math.max(0, Math.floor(waitMs));\n const waitSeconds = params.waitSeconds;\n if (typeof waitSeconds === \"number\" && Number.isFinite(waitSeconds)) return Math.max(0, Math.floor(waitSeconds * 1000));\n return DEFAULT_WAIT_MS;\n}\n\n// ─── 可见性判定(参考 Playwright domUtils.ts) ───\n\n/** 检查元素样式可见性(处理 checkVisibility / details 折叠 / visibility) */\nfunction isStyleVisible(el: Element, style?: CSSStyleDeclaration): boolean {\n style = style ?? window.getComputedStyle(el);\n if (typeof el.checkVisibility === \"function\") {\n if (!el.checkVisibility()) return false;\n } else {\n const det = el.closest(\"details,summary\");\n if (det !== el && det?.nodeName === \"DETAILS\" && !(det as HTMLDetailsElement).open) return false;\n }\n return style.visibility === \"visible\";\n}\n\n/**\n * 元素可见性检查(参考 Playwright isElementVisible+computeBox)。\n * 处理 display:contents / display:none / visibility / opacity / 尺寸为 0。\n */\nfunction isElementVisible(el: Element): boolean {\n if (!(el instanceof HTMLElement || el instanceof SVGElement)) return false;\n if (!el.isConnected) return false;\n const style = window.getComputedStyle(el);\n\n if (style.display === \"contents\") {\n for (let child = el.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === Node.ELEMENT_NODE && isElementVisible(child as Element)) return true;\n if (child.nodeType === Node.TEXT_NODE) {\n const range = document.createRange();\n range.selectNodeContents(child);\n const rects = range.getClientRects();\n for (let i = 0; i < rects.length; i++) {\n if (rects[i].width > 0 && rects[i].height > 0) return true;\n }\n }\n }\n return false;\n }\n if (style.display === \"none\") return false;\n if (!isStyleVisible(el, style)) return false;\n if (style.opacity === \"0\") return false;\n const rect = el.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n}\n\n// ─── disabled / editable 检查(参考 Playwright) ───\n\n/** ARIA disabled:检查元素自身 + 祖先链 aria-disabled(参考 Playwright getAriaDisabled) */\nfunction isElementDisabled(el: Element): boolean {\n if (el instanceof HTMLButtonElement || el instanceof HTMLInputElement ||\n el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {\n if ((el as HTMLButtonElement).disabled) return true;\n }\n let cursor: Element | null = el;\n while (cursor) {\n if (cursor.getAttribute(\"aria-disabled\") === \"true\") return true;\n cursor = cursor.parentElement;\n }\n return false;\n}\n\nfunction isEditableElement(el: Element): boolean {\n if (el instanceof HTMLTextAreaElement) return !el.readOnly;\n if (el instanceof HTMLInputElement) {\n return !INPUT_BLOCKED_TYPES.has(el.type) && !el.readOnly;\n }\n if (el instanceof HTMLSelectElement) return true;\n return el instanceof HTMLElement && el.isContentEditable;\n}\n\n// ─── 稳定性检查(参考 Playwright _checkElementIsStable) ───\n\n/** rAF 逐帧检查元素位置是否连续 3 帧不变 */\nfunction checkElementStable(el: Element, timeoutMs = 800): Promise<boolean> {\n return new Promise((resolve) => {\n let lastRect: DOMRect | undefined;\n let stableCount = 0;\n const start = performance.now();\n function check() {\n if (performance.now() - start > timeoutMs || !el.isConnected) { resolve(false); return; }\n const rect = el.getBoundingClientRect();\n if (lastRect) {\n const same = rect.x === lastRect.x && rect.y === lastRect.y &&\n rect.width === lastRect.width && rect.height === lastRect.height;\n if (!same) { stableCount = 0; } else if (++stableCount >= 3) { resolve(true); return; }\n }\n lastRect = rect;\n requestAnimationFrame(check);\n }\n requestAnimationFrame(check);\n });\n}\n\n// ─── retarget(参考 Playwright injectedScript.retarget) ───\n\ntype RetargetMode = \"none\" | \"follow-label\" | \"button-link\";\n\n/**\n * 将目标重定向到关联的交互控件。\n * - button-link:非交互元素→最近 button/[role=button]/a/[role=link]\n * - follow-label:label→control + 非交互→button/[role=button]/[role=checkbox]/[role=radio]\n */\nfunction retarget(el: Element, mode: RetargetMode): Element {\n if (mode === \"none\") return el;\n if (!el.matches(\"input, textarea, select\") && !(el as HTMLElement).isContentEditable) {\n if (mode === \"button-link\") {\n el = el.closest(\"button, [role=button], a, [role=link]\") || el;\n } else {\n el = el.closest(\"button, [role=button], [role=checkbox], [role=radio]\") || el;\n }\n }\n if (mode === \"follow-label\") {\n if (!el.matches(\"a, input, textarea, button, select, [role=link], [role=button], [role=checkbox], [role=radio]\") &&\n !(el as HTMLElement).isContentEditable) {\n const label = el.closest(\"label\") as HTMLLabelElement | null;\n if (label?.control) el = label.control;\n }\n }\n return el;\n}\n\n// ─── scrollIntoView(参考 Playwright 4 种策略轮换) ───\n\nfunction scrollIntoViewIfNeeded(el: Element, retry = 0): void {\n if (retry === 0 && \"scrollIntoViewIfNeeded\" in el) {\n (el as HTMLElement & { scrollIntoViewIfNeeded: (c?: boolean) => void }).scrollIntoViewIfNeeded(true);\n return;\n }\n const opts = SCROLL_OPTIONS[retry % SCROLL_OPTIONS.length];\n el.scrollIntoView(opts ?? { block: \"center\", inline: \"nearest\" });\n}\n\n// ─── hit-target 检查 ───\n\n/** 检查元素中心点是否被遮挡,返回遮挡元素描述或 null */\nfunction checkHitTarget(el: Element): string | null {\n const rect = el.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n const topEl = document.elementFromPoint(x, y);\n if (!topEl) return null;\n if (topEl === el || el.contains(topEl) || topEl.contains(el)) return null;\n const sharedLabel = topEl.closest(\"label\");\n if (sharedLabel && sharedLabel.contains(el)) return null;\n return describeElement(topEl);\n}\n\n// ─── actionability 综合检查 ───\n\nfunction ensureActionable(el: Element, action: string, selector: string, force: boolean): ToolCallResult | null {\n if (force) return null;\n if (!el.isConnected) {\n return { content: `\"${selector}\" 元素已脱离文档,无法执行 ${action}`, details: { error: true, code: \"ELEMENT_DETACHED\", action, selector } };\n }\n const readOnlyActions = new Set([\"get_text\", \"get_attr\"]);\n if (!readOnlyActions.has(action) && !isElementVisible(el)) {\n return { content: `\"${selector}\" 元素不可见,无法执行 ${action}`, details: { error: true, code: \"ELEMENT_NOT_VISIBLE\", action, selector } };\n }\n const mutationActions = new Set([\"click\", \"fill\", \"type\", \"press\", \"select_option\", \"clear\", \"check\", \"uncheck\"]);\n if (mutationActions.has(action) && isElementDisabled(el)) {\n return { content: `\"${selector}\" 元素已禁用(disabled/aria-disabled),无法执行 ${action}`, details: { error: true, code: \"ELEMENT_DISABLED\", action, selector } };\n }\n if ([\"fill\", \"type\", \"clear\"].includes(action) && !isEditableElement(el)) {\n // 允许 fill 作用于 role=slider(后续在 fill 分支做专门处理)\n if (action === \"fill\" && el.getAttribute(\"role\") === \"slider\") {\n return null;\n }\n return { content: `\"${selector}\" 不是可编辑元素,无法执行 ${action}`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n return null;\n}\n\n/**\n * 为 role=slider 查找关联的数值输入框。\n * 典型场景:Element Plus slider + input-number 同属一个 form-item。\n */\nfunction findAssociatedSliderInput(slider: Element): HTMLInputElement | null {\n const candidates: Element[] = [];\n\n const formItem = slider.closest(\".el-form-item\");\n if (formItem) candidates.push(formItem);\n\n let cursor: Element | null = slider.parentElement;\n for (let depth = 0; cursor && depth < 4; depth++, cursor = cursor.parentElement) {\n candidates.push(cursor);\n }\n\n for (const scope of candidates) {\n const input = scope.querySelector(\n 'input[type=\"number\"], input[role=\"spinbutton\"], .el-input-number input:not([type=\"hidden\"])',\n );\n if (input instanceof HTMLInputElement && isEditableElement(input) && isElementVisible(input)) {\n return input;\n }\n }\n return null;\n}\n\n// ─── 事件派发(参考 Playwright input.ts 事件链) ───\n\nfunction getClickPoint(el: Element): { x: number; y: number } {\n const r = el.getBoundingClientRect();\n return { x: r.left + r.width / 2, y: r.top + r.height / 2 };\n}\n\n/**\n * 完整点击事件链(参考 Playwright Mouse.click):\n * pointermove → mousemove → (per clickCount) pointerdown → mousedown → focus → pointerup → mouseup → click\n */\nfunction dispatchClickEvents(el: HTMLElement, clickCount = 1): void {\n const { x, y } = getClickPoint(el);\n const base: MouseEventInit = { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y, button: 0 };\n\n el.dispatchEvent(new PointerEvent(\"pointermove\", { ...base, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mousemove\", base));\n\n for (let cc = 1; cc <= clickCount; cc++) {\n el.dispatchEvent(new PointerEvent(\"pointerdown\", { ...base, detail: cc, buttons: 1, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mousedown\", { ...base, detail: cc, buttons: 1 }));\n if (cc === 1 && el !== document.activeElement) el.focus({ preventScroll: true });\n el.dispatchEvent(new PointerEvent(\"pointerup\", { ...base, detail: cc, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mouseup\", { ...base, detail: cc }));\n el.dispatchEvent(new MouseEvent(\"click\", { ...base, detail: cc }));\n }\n}\n\n/** hover 事件链 */\nfunction dispatchHoverEvents(el: HTMLElement): void {\n const { x, y } = getClickPoint(el);\n const base: MouseEventInit = { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y };\n el.dispatchEvent(new PointerEvent(\"pointerenter\", { ...base, bubbles: false }));\n el.dispatchEvent(new MouseEvent(\"mouseenter\", { ...base, bubbles: false }));\n el.dispatchEvent(new PointerEvent(\"pointermove\", { ...base, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mousemove\", base));\n el.dispatchEvent(new MouseEvent(\"mouseover\", base));\n}\n\n/** 派发 input + change 事件(兼容 React/Vue 受控组件) */\nfunction dispatchInputEvents(el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement): void {\n el.dispatchEvent(new Event(\"input\", { bubbles: true, composed: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\n/** 原生 setter 写入表单值(绕过 React/Vue getter/setter 拦截) */\nfunction setNativeValue(el: HTMLInputElement | HTMLTextAreaElement, value: string): void {\n const proto = el instanceof HTMLInputElement ? HTMLInputElement.prototype : HTMLTextAreaElement.prototype;\n const desc = Object.getOwnPropertyDescriptor(proto, \"value\");\n if (desc?.set) desc.set.call(el, value);\n else el.value = value;\n}\n\nfunction getFillEventSupportScore(el: Element): number {\n let score = 0;\n\n if (el.hasAttribute(\"oninput\") || el.hasAttribute(\"onchange\")) score += 80;\n if (el.hasAttribute(\"onfocus\") || el.hasAttribute(\"onblur\")) score += 60;\n if (el.hasAttribute(\"onclick\")) score += 40;\n\n const tracked = getTrackedElementEvents(el);\n for (const eventName of tracked) {\n if (!FILL_RELEVANT_EVENTS.has(eventName)) continue;\n if (eventName === \"input\") score += 40;\n else if (eventName === \"change\") score += 35;\n else if (eventName === \"focus\" || eventName === \"blur\") score += 28;\n else if (eventName === \"keydown\") score += 24;\n else score += 14;\n }\n\n return score;\n}\n\nfunction isCandidateFillTarget(el: Element): boolean {\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {\n return !isElementDisabled(el);\n }\n if (el instanceof HTMLElement && el.isContentEditable) return true;\n return false;\n}\n\nfunction executeFillOnResolvedTarget(\n target: Element,\n value: string,\n selector: string,\n action: string,\n sourceHint?: string,\n): ToolCallResult | null {\n if (target instanceof HTMLInputElement) {\n const type = target.type.toLowerCase();\n if (INPUT_BLOCKED_TYPES.has(type)) {\n return { content: `\"${selector}\" 为 input[type=${type}],不支持 fill;请使用 click/check 等动作。`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n if (INPUT_SET_VALUE_TYPES.has(type)) {\n const finalVal = type === \"color\" ? value.toLowerCase().trim() : value.trim();\n target.focus();\n target.value = finalVal;\n if (target.value !== finalVal) {\n return { content: `\"${selector}\" 填写格式不匹配(type=${type})`, details: { error: true, code: \"MALFORMED_VALUE\", action, selector } };\n }\n dispatchInputEvents(target);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${finalVal}\"${suffix}` };\n }\n if (type === \"number\" && Number.isNaN(Number(value.trim()))) {\n return { content: `\"${selector}\" 为 input[type=number],无法填写非数字 \"${value}\"`, details: { error: true, code: \"INVALID_NUMBER\", action, selector } };\n }\n scrollIntoViewIfNeeded(target);\n target.focus();\n selectText(target);\n setNativeValue(target, value);\n dispatchInputEvents(target);\n if (target.value !== value) {\n return { content: `\"${selector}\" 填写后值不一致:期望 \"${value}\",实际 \"${target.value}\"`, details: { error: true, code: \"FILL_NOT_APPLIED\", action, selector } };\n }\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n if (target instanceof HTMLTextAreaElement) {\n scrollIntoViewIfNeeded(target);\n target.focus();\n selectText(target);\n setNativeValue(target, value);\n dispatchInputEvents(target);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n if (target instanceof HTMLSelectElement) {\n target.focus();\n const options = Array.from(target.options);\n let matched = options.find(o => o.value === value);\n if (!matched) {\n const normalized = value.trim().toLowerCase();\n matched = options.find(o => o.text.trim().toLowerCase() === normalized);\n }\n if (!matched) return { content: `\"${selector}\" 下拉框中不存在选项 \"${value}\"` };\n target.value = matched.value;\n dispatchInputEvents(target);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n if (target instanceof HTMLElement && target.isContentEditable) {\n target.focus();\n selectText(target);\n if (value) document.execCommand(\"insertText\", false, value);\n else document.execCommand(\"delete\", false, undefined);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n return null;\n}\n\nfunction guessNearbyFillTarget(anchor: Element, value: string): Element | null {\n const preferNumeric = Number.isFinite(Number(value));\n const scopeEntries: Array<{ scope: Element; level: number }> = [];\n\n const formItem = anchor.closest(\".el-form-item\");\n if (formItem) scopeEntries.push({ scope: formItem, level: 0 });\n\n let cursor: Element | null = anchor.parentElement;\n for (let level = 1; cursor && level <= 4; level++, cursor = cursor.parentElement) {\n scopeEntries.push({ scope: cursor, level });\n }\n\n const visited = new Set<Element>();\n let best: { el: Element; score: number } | null = null;\n\n for (const { scope, level } of scopeEntries) {\n const candidates = Array.from(scope.querySelectorAll(\n 'input:not([type=\"hidden\"]), textarea, select, [contenteditable=\"true\"], [role=\"spinbutton\"]',\n ));\n\n for (const candidate of candidates) {\n if (!(candidate instanceof Element)) continue;\n if (visited.has(candidate)) continue;\n visited.add(candidate);\n\n if (!isCandidateFillTarget(candidate)) continue;\n if (!isElementVisible(candidate)) continue;\n\n let score = 100 - level * 18;\n score += getFillEventSupportScore(candidate);\n\n if (candidate instanceof HTMLInputElement) {\n const type = candidate.type.toLowerCase();\n if (preferNumeric && (type === \"number\" || candidate.getAttribute(\"role\") === \"spinbutton\")) score += 80;\n if (!preferNumeric && [\"text\", \"\", \"search\", \"email\", \"tel\", \"url\", \"password\"].includes(type)) score += 36;\n }\n\n if (candidate.getAttribute(\"placeholder\")) score += 8;\n if (candidate.getAttribute(\"aria-label\")) score += 8;\n\n if (!best || score > best.score) {\n best = { el: candidate, score };\n }\n }\n }\n\n return best?.el ?? null;\n}\n\n// ─── selectText(参考 Playwright:input/textarea/contenteditable 三种策略) ───\n\nfunction selectText(el: Element): void {\n if (el instanceof HTMLInputElement) { el.select(); el.focus(); return; }\n if (el instanceof HTMLTextAreaElement) { el.selectionStart = 0; el.selectionEnd = el.value.length; el.focus(); return; }\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n if (sel) { sel.removeAllRanges(); sel.addRange(range); }\n if (el instanceof HTMLElement) el.focus();\n}\n\n// ─── 键盘:组合键支持(参考 Playwright Keyboard.press) ───\n\nfunction splitKeyCombo(key: string): string[] {\n const tokens = key.split(\"+\");\n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i] === \"\" && i + 1 < tokens.length) { tokens[i + 1] = \"+\" + tokens[i + 1]; tokens.splice(i, 1); }\n }\n return tokens.filter(Boolean);\n}\n\nfunction resolveKeyCode(key: string): string {\n return KEY_CODE_MAP[key] ?? (key.length === 1 ? `Key${key.toUpperCase()}` : key);\n}\n\n/**\n * 执行 press:修饰键按正序 down → 主键 down/up → 修饰键逆序 up(参考 Playwright)。\n * 修饰键按下时抑制文本输入(只发 keydown/keyup,不发 keypress)。\n */\nfunction executePress(el: Element, key: string): void {\n const tokens = splitKeyCombo(key);\n const mainKey = tokens[tokens.length - 1];\n const mods = tokens.slice(0, -1);\n const modState = {\n ctrlKey: mods.includes(\"Control\"),\n shiftKey: mods.includes(\"Shift\"),\n altKey: mods.includes(\"Alt\"),\n metaKey: mods.includes(\"Meta\"),\n };\n const hasNonShiftMod = modState.ctrlKey || modState.altKey || modState.metaKey;\n\n for (const m of mods) {\n el.dispatchEvent(new KeyboardEvent(\"keydown\", { key: m, code: resolveKeyCode(m), bubbles: true, cancelable: true, ...modState }));\n }\n const allowed = el.dispatchEvent(new KeyboardEvent(\"keydown\", { key: mainKey, code: resolveKeyCode(mainKey), bubbles: true, cancelable: true, ...modState }));\n // 只有无非 Shift 修饰键且是单字符时才发 keypress(参考 Playwright 文本抑制逻辑)\n if (allowed && mainKey.length === 1 && !hasNonShiftMod) {\n el.dispatchEvent(new KeyboardEvent(\"keypress\", { key: mainKey, code: resolveKeyCode(mainKey), bubbles: true, cancelable: true, ...modState }));\n }\n el.dispatchEvent(new KeyboardEvent(\"keyup\", { key: mainKey, code: resolveKeyCode(mainKey), bubbles: true, cancelable: true, ...modState }));\n for (let i = mods.length - 1; i >= 0; i--) {\n el.dispatchEvent(new KeyboardEvent(\"keyup\", { key: mods[i], code: resolveKeyCode(mods[i]), bubbles: true, cancelable: true, ...modState }));\n }\n}\n\n// ─── 元素描述 ───\n\nfunction describeElement(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const id = el.id ? `#${el.id}` : \"\";\n const cls = el.className && typeof el.className === \"string\"\n ? el.className.trim().split(/\\s+/).filter(Boolean).slice(0, 3).map(c => `.${c}`).join(\"\") : \"\";\n const text = el instanceof HTMLSelectElement\n ? el.selectedOptions[0]?.textContent?.trim().slice(0, 40) ?? \"\"\n : el.textContent?.trim().slice(0, 40) ?? \"\";\n const textHint = text ? ` \"${text}\"` : \"\";\n const hints: string[] = [];\n for (const attr of [\"type\", \"name\", \"placeholder\", \"href\", \"role\"]) {\n const v = el.getAttribute(attr);\n if (v) hints.push(`${attr}=${v}`);\n }\n if (el instanceof HTMLSelectElement && el.value) hints.push(`val=${el.value}`);\n const attrHint = hints.length > 0 ? ` [${hints.join(\", \")}]` : \"\";\n return `<${tag}${id}${cls}>${textHint}${attrHint}`;\n}\n\n// ─── checkable 目标归一化 ───\n\nfunction isCheckableInput(el: Element | null): el is HTMLInputElement {\n return el instanceof HTMLInputElement && (el.type === \"checkbox\" || el.type === \"radio\");\n}\n\nfunction getChecked(el: Element): boolean | \"error\" {\n if (el instanceof HTMLInputElement && (el.type === \"checkbox\" || el.type === \"radio\")) return el.checked;\n const role = el.getAttribute(\"role\");\n if (role === \"checkbox\" || role === \"radio\" || role === \"switch\") return el.getAttribute(\"aria-checked\") === \"true\";\n return \"error\";\n}\n\n/**\n * 归一化 check/uncheck 目标:允许命中文本容器/label/div,回溯到关联 checkbox/radio。\n */\nfunction resolveCheckableTarget(el: Element): Element {\n if (getChecked(el) !== \"error\") return el;\n if (el instanceof HTMLLabelElement && el.control && getChecked(el.control) !== \"error\") return el.control;\n const ownerLabel = el.closest(\"label\") as HTMLLabelElement | null;\n if (ownerLabel?.control && getChecked(ownerLabel.control) !== \"error\") return ownerLabel.control;\n const inner = el.querySelector('input[type=\"checkbox\"], input[type=\"radio\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"]');\n if (inner && getChecked(inner) !== \"error\") return inner;\n const prev = el.previousElementSibling;\n if (prev && getChecked(prev) !== \"error\") return prev;\n const next = el.nextElementSibling;\n if (next && getChecked(next) !== \"error\") return next;\n const parent = el.parentElement;\n if (parent) {\n const inP = parent.querySelector('input[type=\"checkbox\"], input[type=\"radio\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"]');\n if (inP && getChecked(inP) !== \"error\") return inP;\n }\n return el;\n}\n\n/**\n * 为 pointer 类动作(click/check/uncheck)解析可点击代理目标:\n * 当命中隐藏的原生 checkbox/radio/switch input 时,优先改点其可见 label/容器。\n */\nfunction resolvePointerActionTarget(el: Element): Element {\n if (!(el instanceof HTMLInputElement)) return el;\n\n const inputType = el.type?.toLowerCase() ?? \"\";\n const isCheckable = inputType === \"checkbox\" || inputType === \"radio\";\n if (!isCheckable && el.getAttribute(\"role\") !== \"switch\") return el;\n if (isElementVisible(el)) return el;\n\n const label = el.labels?.[0] ?? (el.closest(\"label\") as HTMLLabelElement | null);\n if (label && isElementVisible(label)) return label;\n\n const proxy = el.closest(\".el-switch, .el-checkbox, .el-radio, [role='switch'], [role='checkbox'], [role='radio']\");\n if (proxy && isElementVisible(proxy)) return proxy;\n\n const siblingProxy = el.parentElement?.querySelector(\n \".el-switch__core, .el-checkbox__inner, .el-radio__inner, [role='switch'], [role='checkbox'], [role='radio']\",\n );\n if (siblingProxy && isElementVisible(siblingProxy)) return siblingProxy;\n\n return el;\n}\n\n/**\n * 当命中表单项说明 label(如 Element Plus el-form-item__label)时,\n * 自动重定向到同一表单项中的首个可交互控件。\n */\nfunction resolveFormItemControlTarget(el: Element): Element {\n if (!(el instanceof HTMLElement)) return el;\n const isLabelLike = el.tagName === \"LABEL\" || el.classList.contains(\"el-form-item__label\");\n if (!isLabelLike) return el;\n\n const htmlLabel = el as HTMLLabelElement;\n if (htmlLabel.control && isElementVisible(htmlLabel.control)) return htmlLabel.control;\n\n const formItem = el.closest(\".el-form-item\");\n if (!formItem) return el;\n const content = formItem.querySelector(\".el-form-item__content\") ?? formItem;\n const control = content.querySelector(\n \"input:not([type='hidden']), textarea, select, button, [role='switch'], [role='checkbox'], [role='radio'], [role='button'], .el-switch, .el-checkbox, .el-radio, [tabindex]:not([tabindex='-1'])\",\n );\n if (control && isElementVisible(control)) return control;\n return el;\n}\n\n// ─── 自定义下拉增强 ───\n\nfunction findVisibleOptionByText(text: string): HTMLElement | null {\n const target = text.trim().toLowerCase();\n if (!target) return null;\n const selectors = [\n '[role=\"option\"]', '[role=\"listbox\"] li',\n \".el-select-dropdown__item\", \".el-option\", // Element Plus\n \".ant-select-item-option\", // Ant Design\n \".el-cascader-node\", \".el-dropdown-menu__item\",\n '[class*=\"option\"]', \"li[data-value]\", \"option\",\n ].join(\", \");\n const nodes = Array.from(document.querySelectorAll(selectors));\n const visible = nodes.filter(n => n instanceof HTMLElement && isElementVisible(n));\n for (const n of visible) { if (n.textContent?.trim().toLowerCase() === target) return n as HTMLElement; }\n for (const n of visible) { if (n.textContent?.trim().toLowerCase().includes(target)) return n as HTMLElement; }\n return null;\n}\n\nasync function waitForDropdownPopup(maxWait = 500): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < maxWait) {\n const popup = document.querySelector('[role=\"listbox\"], .el-select-dropdown, .el-popper, .ant-select-dropdown, [class*=\"dropdown\"]');\n if (popup && isElementVisible(popup)) return;\n await sleep(50);\n }\n}\n\n// ─── 工具定义 ───\n\nexport function createDomTool(): ToolDefinition {\n return {\n name: \"dom\",\n description: [\n \"DOM actions on the current page.\",\n \"Actions: click, fill, select_option, clear, check, uncheck, type, focus, hover, scroll, press, get_text, get_attr, set_attr, add_class, remove_class.\",\n \"Prefer #hashID from snapshot as selector; use CSS only as compatibility fallback, not as the default strategy.\",\n \"Before fill/type/select_option, click or focus the same target in the same round.\",\n \"For multi-field forms, pair focus/click and fill/type per field in one batch.\",\n \"press supports combos like Enter or Control+a.\",\n \"Visual ordinal instructions use 1-based order.\",\n \"check/uncheck toggles via click and verifies the final state.\",\n \"Do not click nearby descriptive text, labels, or help text when a separate actionable control is visible; target the real interactive option that changes state.\",\n \"For custom widgets such as rating, slider, or composite pickers, prefer visible actionable child items; use fill for slider-like controls when appropriate.\",\n \"For virtualized lists, wheel pickers, or not-yet-visible options, scroll first and then click or select the newly visible target.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"DOM action name.\",\n }),\n selector: Type.String({ description: \"Prefer #hashID from snapshot; CSS selector is fallback only\" }),\n value: Type.Optional(Type.String({ description: \"Value for fill/type/set_attr\" })),\n key: Type.Optional(Type.String({ description: \"Key for press, supports combos\" })),\n label: Type.Optional(Type.String({ description: \"Label for select_option\" })),\n index: Type.Optional(Type.Number({ description: \"0-based option index\" })),\n attribute: Type.Optional(Type.String({ description: \"Attribute name\" })),\n className: Type.Optional(Type.String({ description: \"CSS class name\" })),\n clickCount: Type.Optional(Type.Number({ description: \"Click count\" })),\n deltaY: Type.Optional(Type.Number({ description: \"Vertical scroll delta\" })),\n deltaX: Type.Optional(Type.Number({ description: \"Horizontal scroll delta\" })),\n steps: Type.Optional(Type.Number({ description: \"Scroll repeat count\" })),\n waitMs: Type.Optional(Type.Number({ description: \"Wait timeout in ms\" })),\n waitSeconds: Type.Optional(Type.Number({ description: \"Wait timeout in seconds\" })),\n force: Type.Optional(Type.Boolean({ description: \"Skip actionability checks\" })),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n const selector = params.selector as string;\n const waitMs = resolveWaitMs(params);\n const force = params.force === true;\n\n if (!selector) return { content: \"缺少 selector 参数\" };\n\n // ── 元素查找 ──\n let el: Element;\n if (waitMs > 0) {\n const found = await waitForElement(selector, waitMs);\n if (typeof found === \"string\") return { content: found, details: { error: true, code: \"INVALID_SELECTOR\", action, selector } };\n if (!found) return { content: `未找到匹配 \"${selector}\" 的元素`, details: { error: true, code: \"ELEMENT_NOT_FOUND\", action, selector, waitMs } };\n el = found;\n } else {\n const r = queryElement(selector);\n if (typeof r === \"string\") return { content: r, details: { error: true, code: r.startsWith(\"未找到\") ? \"ELEMENT_NOT_FOUND\" : \"INVALID_SELECTOR\", action, selector, waitMs } };\n el = r;\n }\n\n // check/uncheck 归一化\n if (action === \"check\" || action === \"uncheck\") {\n el = resolveCheckableTarget(el);\n }\n\n const actionabilityTarget =\n action === \"click\" || action === \"check\" || action === \"uncheck\"\n ? resolvePointerActionTarget(resolveFormItemControlTarget(el))\n : el;\n\n try {\n // actionability(skip for force / read-only actions)\n const checkResult = ensureActionable(actionabilityTarget, action, selector, force);\n if (checkResult) return checkResult;\n\n switch (action) {\n // ─── click ───\n case \"click\": {\n const target = resolvePointerActionTarget(resolveFormItemControlTarget(retarget(el, force ? \"none\" : \"button-link\")));\n const clickCount = typeof params.clickCount === \"number\" ? params.clickCount : 1;\n\n // option 元素自动写回 select\n if (target instanceof HTMLOptionElement) {\n const parent = target.parentElement;\n if (parent instanceof HTMLSelectElement) {\n parent.focus(); parent.value = target.value;\n dispatchInputEvents(parent);\n return { content: `已选择 ${describeElement(parent)} 的选项 \"${target.value}\"` };\n }\n }\n\n if (target instanceof HTMLElement) {\n scrollIntoViewIfNeeded(target);\n // stable 检查(参考 Playwright)\n if (!force) await checkElementStable(target, 500);\n // hit-target 检查\n if (!force) {\n const blocker = checkHitTarget(target);\n if (blocker) {\n scrollIntoViewIfNeeded(target, 1);\n await sleep(100);\n // 第二次检查仍被遮挡时 warn 但不阻断\n }\n }\n dispatchClickEvents(target, clickCount);\n } else {\n target.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n }\n return { content: `已点击 ${describeElement(target)}` };\n }\n\n // ─── fill(参考 Playwright 分类型策略) ───\n case \"fill\": {\n const value = params.value as string;\n if (value === undefined) return { content: \"缺少 value 参数\" };\n const target = retarget(el, \"follow-label\");\n\n // role=slider 特化:优先写关联数字输入框,其次点击离散子项(评分星级)\n if (target instanceof HTMLElement && target.getAttribute(\"role\") === \"slider\") {\n const numericValue = Number(value);\n if (!Number.isFinite(numericValue)) {\n const guessed = guessNearbyFillTarget(target, value);\n if (guessed) {\n const guessedResult = executeFillOnResolvedTarget(guessed, value, selector, action, \"heuristic-nearby-target\");\n if (guessedResult) return guessedResult;\n }\n return { content: `\"${selector}\" 为 role=slider,未找到可推断填写目标`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n\n const linkedInput = findAssociatedSliderInput(target);\n if (linkedInput) {\n const filled = executeFillOnResolvedTarget(linkedInput, String(numericValue), selector, action, `from ${describeElement(target)}`);\n if (filled) return filled;\n }\n\n const min = Number(target.getAttribute(\"aria-valuemin\") ?? \"1\");\n const max = Number(target.getAttribute(\"aria-valuemax\") ?? String(target.children.length || 5));\n const discreteCount = Number.isFinite(max - min + 1) ? Math.max(1, Math.round(max - min + 1)) : target.children.length;\n const desiredIndex = Math.round(numericValue - min);\n const children = Array.from(target.children).filter((node): node is HTMLElement => node instanceof HTMLElement);\n\n if (children.length >= discreteCount && desiredIndex >= 0 && desiredIndex < children.length) {\n const item = children[desiredIndex];\n scrollIntoViewIfNeeded(item);\n dispatchClickEvents(item);\n return { content: `已点击 ${describeElement(item)},设置 ${describeElement(target)} 值为 ${numericValue}` };\n }\n\n const guessed = guessNearbyFillTarget(target, String(numericValue));\n if (guessed) {\n const guessedResult = executeFillOnResolvedTarget(guessed, String(numericValue), selector, action, \"heuristic-nearby-target\");\n if (guessedResult) return guessedResult;\n }\n\n return { content: `\"${selector}\" 为 role=slider,但未找到可写入输入框或可点击离散子项`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n\n const directFilled = executeFillOnResolvedTarget(target, value, selector, action);\n if (directFilled) return directFilled;\n\n const guessed = guessNearbyFillTarget(target, value);\n if (guessed) {\n const guessedResult = executeFillOnResolvedTarget(guessed, value, selector, action, \"heuristic-nearby-target\");\n if (guessedResult) return guessedResult;\n }\n\n return { content: `\"${selector}\" 不是可编辑元素,且未在附近找到可推断填写目标`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n\n // ─── select_option(参考 Playwright selectOptions 多策略匹配) ───\n case \"select_option\": {\n const value = params.value as string | undefined;\n const label = params.label as string | undefined;\n const index = typeof params.index === \"number\" ? Math.floor(params.index) : undefined;\n if (value === undefined && label === undefined && index === undefined) {\n return { content: \"缺少可选参数:value 或 label 或 index\" };\n }\n\n const target = retarget(el, \"follow-label\");\n\n // 非原生 <select>:自定义下拉\n if (!(target instanceof HTMLSelectElement)) {\n if (!(target instanceof HTMLElement)) return { content: `\"${selector}\" 不是下拉框元素` };\n scrollIntoViewIfNeeded(target);\n const wanted = (label ?? value ?? \"\").trim();\n if (!wanted) return { content: `\"${selector}\" 为自定义下拉时,需提供 value 或 label` };\n dispatchClickEvents(target); // 点击触发器打开\n await waitForDropdownPopup(800);\n const option = findVisibleOptionByText(wanted);\n if (!option) return { content: `未找到与 \"${wanted}\" 匹配的可见下拉选项(自定义下拉)`, details: { error: true, code: \"OPTION_NOT_FOUND\", action, selector, wanted } };\n dispatchClickEvents(option);\n return { content: `已在自定义下拉中选择 \"${wanted}\"` };\n }\n\n // 原生 <select>\n target.focus();\n const options = Array.from(target.options);\n let selected: HTMLOptionElement | undefined;\n if (value !== undefined) selected = options.find(o => o.value === value);\n if (!selected && label !== undefined) { const nl = label.trim().toLowerCase(); selected = options.find(o => o.text.trim().toLowerCase() === nl); }\n if (!selected && value !== undefined) { const nv = value.trim().toLowerCase(); selected = options.find(o => o.text.trim().toLowerCase() === nv); }\n if (!selected && index !== undefined) {\n if (index < 0 || index >= options.length) return { content: `\"${selector}\" 下拉框不存在 index=${index} 的选项` };\n selected = options[index];\n }\n if (!selected) return { content: `\"${selector}\" 下拉框中不存在选项 \"${value ?? label ?? `index=${index}`}\"` };\n // option disabled 检查(参考 Playwright)\n if (selected.disabled) return { content: `\"${selector}\" 目标选项已禁用:${selected.value}`, details: { error: true, code: \"OPTION_DISABLED\", action, selector } };\n if (!target.multiple) { for (const o of options) o.selected = false; }\n selected.selected = true;\n target.value = selected.value;\n dispatchInputEvents(target);\n return { content: `已选择 ${describeElement(target)}: value=\"${selected.value}\", label=\"${selected.text.trim()}\"` };\n }\n\n // ─── clear ───\n case \"clear\": {\n const target = retarget(el, \"follow-label\");\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n scrollIntoViewIfNeeded(target);\n target.focus(); selectText(target);\n setNativeValue(target as HTMLInputElement, \"\");\n dispatchInputEvents(target);\n return { content: `已清空 ${describeElement(target)}` };\n }\n if (target instanceof HTMLSelectElement) {\n target.focus(); target.value = \"\";\n dispatchInputEvents(target);\n return { content: `已清空 ${describeElement(target)}` };\n }\n if (target instanceof HTMLElement && target.isContentEditable) {\n target.focus(); selectText(target);\n document.execCommand(\"delete\", false, undefined);\n return { content: `已清空 ${describeElement(target)}` };\n }\n return { content: `\"${selector}\" 不是可清空元素` };\n }\n\n // ─── check / uncheck(参考 Playwright:通过 click 切换 + 验证状态) ───\n case \"check\":\n case \"uncheck\": {\n const wantChecked = action === \"check\";\n const current = getChecked(el);\n if (current === \"error\") {\n return { content: `\"${selector}\" 不是 checkbox/radio/[role=checkbox]/[role=radio],无法 ${action}`, details: { error: true, code: \"NOT_CHECKABLE\", action, selector } };\n }\n // 已是目标状态(幂等,参考 Playwright)\n if (current === wantChecked) return { content: `${describeElement(el)} 已经是${wantChecked ? \"选中\" : \"未选中\"}状态` };\n // radio 不能 uncheck\n if (!wantChecked && el instanceof HTMLInputElement && el.type === \"radio\") {\n return { content: `无法取消 radio 按钮的选中状态`, details: { error: true, code: \"CANNOT_UNCHECK_RADIO\", action, selector } };\n }\n // 通过 click 切换(参考 Playwright _setChecked)\n const pointerTarget = resolvePointerActionTarget(el);\n scrollIntoViewIfNeeded(pointerTarget);\n if (pointerTarget instanceof HTMLElement) dispatchClickEvents(pointerTarget);\n else pointerTarget.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n // 验证状态变更\n await sleep(50);\n const finalState = getChecked(el);\n if (finalState !== wantChecked && el instanceof HTMLInputElement) {\n el.checked = wantChecked;\n dispatchInputEvents(el);\n }\n return { content: `已${wantChecked ? \"勾选\" : \"取消勾选\"} ${describeElement(el)}` };\n }\n\n // ─── type(逐字符键入) ───\n case \"type\": {\n const value = params.value as string;\n if (value === undefined) return { content: \"缺少 value 参数\" };\n const target = retarget(el, \"follow-label\");\n scrollIntoViewIfNeeded(target);\n if (target instanceof HTMLElement) target.focus();\n\n for (const char of value) {\n const init: KeyboardEventInit = { key: char, code: resolveKeyCode(char), bubbles: true, cancelable: true };\n target.dispatchEvent(new KeyboardEvent(\"keydown\", init));\n target.dispatchEvent(new KeyboardEvent(\"keypress\", init));\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n const proto = target instanceof HTMLInputElement ? HTMLInputElement.prototype : HTMLTextAreaElement.prototype;\n const nativeSet = Object.getOwnPropertyDescriptor(proto, \"value\")?.set;\n if (nativeSet) nativeSet.call(target, target.value + char); else target.value += char;\n } else if (target instanceof HTMLElement && target.isContentEditable) {\n document.execCommand(\"insertText\", false, char);\n }\n target.dispatchEvent(new Event(\"input\", { bubbles: true, composed: true }));\n target.dispatchEvent(new KeyboardEvent(\"keyup\", init));\n }\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n return { content: `已逐字输入到 ${describeElement(target)}: \"${value}\"` };\n }\n\n // ─── focus(参考 Playwright:双次 focus) ───\n case \"focus\": {\n const target = retarget(el, \"follow-label\");\n if (target instanceof HTMLElement || target instanceof SVGElement) {\n target.focus(); target.focus(); // Playwright workaround: 双次 focus\n }\n return { content: `已聚焦 ${describeElement(target)}` };\n }\n\n // ─── hover ───\n case \"hover\": {\n const target = retarget(el, \"none\");\n scrollIntoViewIfNeeded(target);\n if (!force) await checkElementStable(target, 500);\n if (target instanceof HTMLElement) dispatchHoverEvents(target);\n return { content: `已悬停 ${describeElement(target)}` };\n }\n\n // ─── scroll(组件内滚动,适配时间滚轮/虚拟列表) ───\n case \"scroll\": {\n const target = retarget(el, \"none\");\n const deltaY = typeof params.deltaY === \"number\"\n ? params.deltaY\n : (typeof params.value === \"string\" && !Number.isNaN(Number(params.value)) ? Number(params.value) : 180);\n const deltaX = typeof params.deltaX === \"number\" ? params.deltaX : 0;\n const rawSteps = typeof params.steps === \"number\" ? Math.floor(params.steps) : 1;\n const steps = Math.min(20, Math.max(1, rawSteps));\n\n if (target instanceof HTMLElement) {\n scrollIntoViewIfNeeded(target);\n for (let i = 0; i < steps; i++) {\n target.scrollBy({ top: deltaY, left: deltaX, behavior: \"auto\" });\n target.dispatchEvent(new WheelEvent(\"wheel\", {\n bubbles: true,\n cancelable: true,\n deltaY,\n deltaX,\n }));\n }\n return { content: `已滚动 ${describeElement(target)}: deltaY=${deltaY}, deltaX=${deltaX}, steps=${steps}` };\n }\n\n for (let i = 0; i < steps; i++) {\n target.dispatchEvent(new WheelEvent(\"wheel\", {\n bubbles: true,\n cancelable: true,\n deltaY,\n deltaX,\n }));\n }\n return { content: `已滚动 ${describeElement(target)}: deltaY=${deltaY}, deltaX=${deltaX}, steps=${steps}` };\n }\n\n // ─── press(支持组合键) ───\n case \"press\": {\n const key = (params.key as string) || (params.value as string);\n if (!key) return { content: \"缺少 key 参数(如 Enter, Escape, Tab, Control+a)\" };\n const target = retarget(el, \"none\");\n scrollIntoViewIfNeeded(target);\n if (target instanceof HTMLElement) target.focus();\n executePress(target, key);\n // Enter 特殊:触发 form submit\n const mainKey = splitKeyCombo(key).pop();\n if (mainKey === \"Enter\") {\n const form = (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) ? (target.form ?? target.closest(\"form\")) : target.closest(\"form\");\n form?.dispatchEvent(new Event(\"submit\", { bubbles: true, cancelable: true }));\n }\n return { content: `已在 ${describeElement(target)} 上按下 ${key}` };\n }\n\n // ─── 读取类 ───\n case \"get_text\": {\n const text = el.textContent?.trim() ?? \"\";\n return { content: `${describeElement(el)} 的文本内容:${text || \"(空)\"}` };\n }\n case \"get_attr\": {\n const attribute = params.attribute as string;\n if (!attribute) return { content: \"缺少 attribute 参数\" };\n const attrName = attribute.toLowerCase();\n if (attrName === \"checked\") {\n if (el instanceof HTMLInputElement) return { content: `${describeElement(el)} 的 checked = ${String(el.checked)}` };\n return { content: `${describeElement(el)} 的 checked = ${el.getAttribute(\"aria-checked\") ?? \"(不存在)\"}` };\n }\n if (attrName === \"selected\") {\n if (el instanceof HTMLOptionElement) return { content: `${describeElement(el)} 的 selected = ${String(el.selected)}` };\n return { content: `${describeElement(el)} 的 selected = ${el.getAttribute(\"aria-selected\") ?? \"(不存在)\"}` };\n }\n if (attrName === \"disabled\") {\n if (el instanceof HTMLButtonElement || el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {\n return { content: `${describeElement(el)} 的 disabled = ${String(el.disabled)}` };\n }\n }\n if (attrName === \"readonly\" && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {\n return { content: `${describeElement(el)} 的 readonly = ${String(el.readOnly)}` };\n }\n if (attrName === \"value\" && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement)) {\n return { content: `${describeElement(el)} 的 value = ${el.value || \"(空)\"}` };\n }\n return { content: `${describeElement(el)} 的 ${attribute} = ${el.getAttribute(attribute) ?? \"(不存在)\"}` };\n }\n\n // ─── 修改类 ───\n case \"set_attr\": {\n const attribute = params.attribute as string;\n const value = params.value as string;\n if (!attribute || value === undefined) return { content: \"缺少 attribute 或 value 参数\" };\n el.setAttribute(attribute, value);\n return { content: `已设置 ${describeElement(el)} 的 ${attribute}=\"${value}\"` };\n }\n case \"add_class\": {\n const className = params.className as string;\n if (!className) return { content: \"缺少 className 参数\" };\n el.classList.add(className);\n return { content: `已添加 class \"${className}\" 到 ${describeElement(el)}` };\n }\n case \"remove_class\": {\n const className = params.className as string;\n if (!className) return { content: \"缺少 className 参数\" };\n el.classList.remove(className);\n return { content: `已移除 ${describeElement(el)} 的 class \"${className}\"` };\n }\n\n default:\n return { content: `未知的 DOM 动作: ${action}` };\n }\n } catch (err) {\n return { content: `DOM 操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`, details: { error: true, action, selector } };\n }\n },\n };\n}","/**\n * Page Info Tool — 基于 Web API 的页面信息获取工具。\n *\n * 替代 Playwright 的 getTitle/getUrl/snapshot 等。\n * 运行环境:浏览器 Content Script。\n *\n * 支持 6 种动作:\n * get_url — 获取当前页面 URL\n * get_title — 获取页面标题\n * get_selection — 获取用户选中的文本\n * get_viewport — 获取视口尺寸和滚动位置\n * snapshot — 获取页面 DOM 结构快照(AI 可读的文本描述)\n * query_all — 查询所有匹配选择器的元素,返回摘要信息\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport type { RefStore } from \"../ref-store.js\";\nimport { getTrackedElementEvents, hasTrackedElementEvents } from \"../event-listener-tracker.js\";\nimport { getActiveRefStore } from \"./dom-tool.js\";\n\n/** 快照配置选项 */\nexport type SnapshotOptions = {\n /** 最大遍历深度(默认 12) */\n maxDepth?: number;\n /**\n * 视口裁剪:只保留与视口相交的元素(默认 true)。\n * 开启后,完全在视口外的元素会被跳过,大幅减少 token 消耗。\n * 注意:祖先容器即使自身不在视口内,只要有子元素在视口内就会保留。\n */\n viewportOnly?: boolean;\n /**\n * 智能剪枝:折叠无意义的纯布局容器(默认 true)。\n * 开启后,没有文本、没有 id、没有交互属性的纯布局元素(div/span/section 等)\n * 如果自身无意义,会被折叠——子元素直接提升到父级输出,减少嵌套噪音。\n */\n pruneLayout?: boolean;\n /**\n * hash ID 映射表(可选)。\n * 传入 RefStore 实例后,每个元素使用确定性 hash ID 替代完整 XPath,\n * 大幅减少 token 消耗。dom-tool 通过 RefStore.get(id) 解析回 DOM 元素。\n */\n refStore?: RefStore;\n /** 最大输出节点数(默认 220),超过后停止继续遍历。 */\n maxNodes?: number;\n /** 每个父节点最多输出的子元素数(默认 25),超出部分会折叠。 */\n maxChildren?: number;\n /** 文本截断长度(默认 40)。 */\n maxTextLength?: number;\n /**\n * 是否对“选项列表”容器放宽子节点截断(默认 false)。\n * 典型场景:时间选择器/下拉选项列表,避免关键选项被 `...children omitted` 折叠。\n */\n expandOptionLists?: boolean;\n /**\n * 仅对指定 hash ref 节点放宽子节点截断(优先级高于默认 maxChildren)。\n * 例如:[#abc123, #def456],用于 AI 在看到 children omitted 后定向请求放宽。\n */\n expandChildrenRefs?: string[];\n /** 对 expandChildrenRefs 节点生效的子节点上限(默认 120)。 */\n expandedChildrenLimit?: number;\n /**\n * 快照中允许输出的 listener 事件白名单(默认仅输出常用事件)。\n * 例如:['click', 'input', 'change', 'mousedown']。\n * 仅影响 `listeners=\"...\"` 文本输出,不影响内部交互判定与 hash 分配。\n */\n listenerEvents?: string[];\n};\n\n/** 快照属性值最大保留长度(超出截断)。 */\nconst MAX_SNAPSHOT_ATTR_VALUE_LENGTH = 120;\n/** 选项列表放宽时的子节点上限(仍保留硬上限,避免快照无限膨胀)。 */\nconst MAX_EXPANDED_LIST_CHILDREN = 120;\n/** 定向放宽 children 的硬上限。 */\nconst MAX_EXPANDED_CHILDREN_LIMIT = 300;\n/** 快照默认保留的高价值 listener 事件(控制 token 体积)。 */\nconst DEFAULT_SNAPSHOT_LISTENER_EVENTS = [\n \"click\",\n \"input\",\n \"change\",\n \"mousedown\",\n \"pointerdown\",\n \"keydown\",\n \"submit\",\n \"focus\",\n \"blur\",\n];\n\n/** 事件名 → 快照简写映射(压缩 token)。 */\nconst EVENT_ABBREV: Record<string, string> = {\n click: \"clk\", dblclick: \"dbl\",\n mousedown: \"mdn\", mouseup: \"mup\", mousemove: \"mmv\",\n mouseover: \"mov\", mouseout: \"mot\", mouseenter: \"men\", mouseleave: \"mlv\",\n pointerdown: \"pdn\", pointerup: \"pup\", pointermove: \"pmv\",\n touchstart: \"tst\", touchend: \"ted\",\n keydown: \"kdn\", keyup: \"kup\",\n input: \"inp\", change: \"chg\", submit: \"sub\",\n focus: \"fcs\", blur: \"blr\",\n scroll: \"scl\", wheel: \"whl\",\n drag: \"drg\", dragstart: \"drs\", dragend: \"dre\", drop: \"drp\",\n contextmenu: \"ctx\",\n};\n\nfunction abbrevEvent(name: string): string {\n return EVENT_ABBREV[name] ?? name.slice(0, 3);\n}\n\nfunction normalizeSnapshotListenerEvent(name: string): string {\n return name.trim().toLowerCase();\n}\n\n/**\n * 规整快照属性值,避免把长 base64/data URL 原样注入快照。\n */\nfunction sanitizeSnapshotAttrValue(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n\n const dataUrlMatch = trimmed.match(/^data:([^,]*?),(.*)$/i);\n if (dataUrlMatch) {\n const meta = dataUrlMatch[1] || \"\";\n const payload = dataUrlMatch[2] || \"\";\n const isBase64 = /;base64/i.test(meta);\n const payloadLength = payload.length;\n const previewMeta = meta.slice(0, 48);\n if (isBase64 || payloadLength > 64) {\n return `data:${previewMeta},<omitted:${payloadLength}>`;\n }\n }\n\n const base64ChunkMatch = trimmed.match(/^[A-Za-z0-9+/]{80,}={0,2}$/);\n if (base64ChunkMatch) {\n return `<base64:${trimmed.length}>`;\n }\n\n if (trimmed.length > MAX_SNAPSHOT_ATTR_VALUE_LENGTH) {\n return `${trimmed.slice(0, MAX_SNAPSHOT_ATTR_VALUE_LENGTH)}...`;\n }\n return trimmed;\n}\n\n/**\n * 生成页面 DOM 快照 — 将 DOM 树转为 AI 可理解的文本描述。\n *\n * 基于 Web API 实现,只遍历可见元素,跳过 script/style/svg 等无意义节点。\n * 传入 RefStore 时,每个元素生成确定性 hash ID(如 #a1b2c),\n * AI 通过 hash ID 精确定位元素,无需猜测 CSS 选择器。\n *\n * 输出格式示例:\n * [header] #k9f2a\n * [nav] #m3d7e\n * [a] \"首页\" href=\"/\" #p1c4b\n * [a] \"关于\" href=\"/about\" #q8e5f\n * [main] #r2a6d\n * [h1] \"欢迎\" #s7g3h\n * [input] type=\"text\" placeholder=\"搜索...\" #t4j8k\n * [button] \"搜索\" id=\"search-btn\" onclick #u5n2m\n *\n * @param root - 快照根元素(默认 document.body)\n * @param options - 快照选项对象,或传入数字作为 maxDepth(向后兼容)\n */\nexport function generateSnapshot(\n root: Element = document.body,\n options: SnapshotOptions | number = {},\n): string {\n // 向后兼容:数字参数视为 maxDepth\n const opts: SnapshotOptions = typeof options === \"number\"\n ? { maxDepth: options }\n : options;\n\n const maxDepth = opts.maxDepth ?? 12;\n const viewportOnly = opts.viewportOnly ?? true;\n const pruneLayout = opts.pruneLayout ?? true;\n const maxNodes = opts.maxNodes ?? 220;\n const maxChildren = opts.maxChildren ?? 25;\n const maxTextLength = opts.maxTextLength ?? 40;\n const expandOptionLists = opts.expandOptionLists ?? false;\n const expandedChildrenLimit = Math.min(\n MAX_EXPANDED_CHILDREN_LIMIT,\n Math.max(1, opts.expandedChildrenLimit ?? MAX_EXPANDED_LIST_CHILDREN),\n );\n const expandChildrenRefSet = new Set(\n (opts.expandChildrenRefs ?? [])\n .map(ref => ref.trim().replace(/^#/, \"\"))\n .filter(Boolean),\n );\n const allowedListenerEvents = new Set(\n (opts.listenerEvents && opts.listenerEvents.length > 0\n ? opts.listenerEvents\n : DEFAULT_SNAPSHOT_LISTENER_EVENTS)\n .map(normalizeSnapshotListenerEvent)\n .filter(Boolean),\n );\n\n let emittedNodes = 0;\n let truncatedByNodeBudget = false;\n\n const refStore = opts.refStore;\n\n const SKIP_TAGS = new Set([\n \"SCRIPT\", \"STYLE\", \"SVG\", \"NOSCRIPT\", \"LINK\", \"META\", \"BR\", \"HR\",\n \"COLGROUP\", \"COL\",\n ]);\n\n /** 纯布局容器标签 — 智能剪枝时可能被折叠 */\n const LAYOUT_TAGS = new Set([\n \"DIV\", \"SPAN\", \"SECTION\", \"ARTICLE\", \"ASIDE\", \"MAIN\",\n \"HEADER\", \"FOOTER\", \"NAV\", \"FIGURE\", \"FIGCAPTION\",\n ]);\n\n /** 视口尺寸(viewportOnly 开启时使用) */\n const vpWidth = viewportOnly ? window.innerWidth : 0;\n const vpHeight = viewportOnly ? window.innerHeight : 0;\n\n const INTERACTIVE_ATTRS = [\n \"href\", \"type\", \"placeholder\", \"value\", \"name\", \"role\", \"aria-label\",\n \"src\", \"alt\", \"title\", \"for\", \"action\", \"method\",\n ];\n\n const INTERACTIVE_TAGS = new Set([\n \"A\", \"BUTTON\", \"INPUT\", \"TEXTAREA\", \"SELECT\", \"OPTION\", \"LABEL\", \"SUMMARY\",\n ]);\n\n const INTERACTIVE_EVENTS = new Set([\n \"click\", \"dblclick\", \"mousedown\", \"mouseup\", \"pointerdown\", \"pointerup\",\n \"touchstart\", \"touchend\", \"input\", \"change\", \"keydown\", \"keyup\",\n \"submit\", \"focus\", \"blur\",\n ]);\n\n /** 交互性 ARIA role — 需要分配 hash ID 的角色集合 */\n const INTERACTIVE_ROLES = new Set([\n \"button\", \"link\", \"tab\", \"switch\", \"slider\", \"checkbox\", \"radio\",\n \"combobox\", \"listbox\", \"option\", \"menuitem\", \"textbox\", \"spinbutton\",\n \"searchbox\", \"treeitem\", \"gridcell\", \"scrollbar\",\n ]);\n\n /**\n * 事件优先级(值越大越优先):\n * 输入链路(input/change/focus/blur) > 点击链路(click/pointer) > 其他事件。\n */\n const EVENT_PRIORITY: Record<string, number> = {\n input: 140,\n change: 130,\n focus: 120,\n blur: 110,\n keydown: 100,\n keyup: 90,\n click: 80,\n dblclick: 70,\n pointerdown: 60,\n pointerup: 55,\n mousedown: 50,\n mouseup: 45,\n touchstart: 40,\n touchend: 35,\n submit: 30,\n };\n\n /** 布尔状态属性 — 只在存在时输出(无值),如 disabled、checked */\n const BOOLEAN_ATTRS = [\n \"disabled\", \"checked\", \"readonly\", \"required\", \"selected\",\n \"hidden\",\n ];\n\n /**\n * 计算元素在父节点中同标签兄弟里的序号(1-based,XPath 规范)。\n * 如果同标签兄弟只有一个,返回空字符串(无需索引消歧)。\n */\n function getSiblingIndex(el: Element): string {\n const parent = el.parentElement;\n if (!parent) return \"\";\n const tag = el.tagName;\n const siblings = Array.from(parent.children).filter((c) => c.tagName === tag);\n if (siblings.length <= 1) return \"\";\n return `[${siblings.indexOf(el) + 1}]`;\n }\n\n /**\n * 判断元素是否与视口相交(部分可见也算)。\n * 对根级容器(depth <= 1)始终返回 true,确保不丢失顶层结构。\n */\n function isInViewport(el: Element, depth: number): boolean {\n if (!viewportOnly) return true;\n // 根级容器始终保留(body/html 等),否则整棵树会被跳过\n if (depth <= 1) return true;\n const rect = el.getBoundingClientRect();\n // 元素完全在视口外则跳过\n if (rect.bottom < 0 || rect.top > vpHeight) return false;\n if (rect.right < 0 || rect.left > vpWidth) return false;\n // 零尺寸元素(如隐藏的 position:absolute 元素)也跳过\n if (rect.width === 0 && rect.height === 0) return false;\n return true;\n }\n\n /**\n * 判断元素是否为「无意义布局容器」(智能剪枝候选)。\n * 满足所有条件时返回 true:\n * 1. 标签是常见布局容器(div/span/section 等)\n * 2. 没有 id\n * 3. 没有交互属性(href/role/aria-label/onclick 等)\n * 4. 没有直接文本内容\n */\n function isEmptyLayoutContainer(el: Element, directText: string): boolean {\n if (!pruneLayout) return false;\n if (!LAYOUT_TAGS.has(el.tagName)) return false;\n // 有 id 的元素可能是重要锚点\n if (el.getAttribute(\"id\")) return false;\n // 有 role/aria-label 的元素有语义\n if (el.getAttribute(\"role\") || el.getAttribute(\"aria-label\")) return false;\n // 有内联事件(onclick 等)的元素有交互\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) return false;\n }\n // 运行时追踪到事件绑定的元素有交互语义\n if (hasTrackedElementEvents(el)) return false;\n // 有直接文本内容的元素有意义\n if (directText) return false;\n return true;\n }\n\n function hasInteractiveTrackedEvents(el: Element): boolean {\n const tracked = getTrackedElementEvents(el);\n if (tracked.length === 0) return false;\n return tracked.some(name => INTERACTIVE_EVENTS.has(name));\n }\n\n function getSnapshotListenerEvents(el: Element): string[] {\n const tracked = getTrackedElementEvents(el);\n if (tracked.length === 0) return [];\n return tracked.filter(name => allowedListenerEvents.has(normalizeSnapshotListenerEvent(name)));\n }\n\n function getTrackedEventPriorityScore(el: Element): number {\n const tracked = getTrackedElementEvents(el);\n if (tracked.length === 0) return 0;\n\n let score = 0;\n for (const name of tracked) {\n score += EVENT_PRIORITY[name] ?? 8;\n }\n return score;\n }\n\n /**\n * 元素优先级:\n * 1) 输入控件/按钮等语义控件\n * 2) 事件追踪优先级(输入、点击、失焦等)\n * 3) inline 事件与可聚焦能力补充加分\n */\n function getElementPriorityScore(el: Element): number {\n let score = 0;\n\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {\n score += 200;\n } else if (el instanceof HTMLButtonElement || el instanceof HTMLAnchorElement) {\n score += 180;\n } else if (el.getAttribute(\"role\") === \"button\" || el.getAttribute(\"role\") === \"switch\" || el.getAttribute(\"role\") === \"slider\") {\n score += 160;\n }\n\n score += getTrackedEventPriorityScore(el);\n\n if (el.hasAttribute(\"onclick\")) score += 60;\n if (el.hasAttribute(\"oninput\") || el.hasAttribute(\"onchange\")) score += 80;\n if (el.hasAttribute(\"onfocus\") || el.hasAttribute(\"onblur\")) score += 70;\n if (el.hasAttribute(\"tabindex\")) score += 20;\n\n return score;\n }\n\n function orderChildrenByPriority(children: Element[]): Element[] {\n return children\n .map((child, index) => ({\n child,\n index,\n interactive: isInteractiveElement(child),\n score: getElementPriorityScore(child),\n }))\n .sort((a, b) => {\n if (a.interactive !== b.interactive) return a.interactive ? -1 : 1;\n if (b.score !== a.score) return b.score - a.score;\n return a.index - b.index;\n })\n .map(entry => entry.child);\n }\n\n function isInteractiveElement(el: Element): boolean {\n if (INTERACTIVE_TAGS.has(el.tagName)) return true;\n if (el.hasAttribute(\"onclick\")) return true;\n if (el.hasAttribute(\"role\")) return true;\n if (el.hasAttribute(\"tabindex\")) return true;\n if (el.hasAttribute(\"aria-label\")) return true;\n if (hasInteractiveTrackedEvents(el)) return true;\n return false;\n }\n\n /**\n * 判断元素是否需要分配 hash ID(仅交互节点分配,节省 token)。\n *\n * 核心依据:元素是否绑定了交互事件(INTERACTIVE_EVENTS 集合)。\n * 辅助依据:语义交互标签、内联事件、ARIA role、tabindex 等兜底。\n */\n function needsHashId(el: Element): boolean {\n // 核心判定:有追踪到的交互事件(click/input/change/focus/blur 等)\n if (hasInteractiveTrackedEvents(el)) return true;\n // 内联事件处理器(onclick/oninput 等)\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) return true;\n }\n // 语义交互标签兜底(即使没有事件追踪也应可操作)\n if (INTERACTIVE_TAGS.has(el.tagName)) return true;\n // 交互性 ARIA role 兜底\n const role = el.getAttribute(\"role\");\n if (role && INTERACTIVE_ROLES.has(role)) return true;\n // tabindex → 可聚焦\n if (el.hasAttribute(\"tabindex\")) return true;\n // contenteditable → 可编辑\n if ((el as HTMLElement).isContentEditable && el.getAttribute(\"contenteditable\") !== \"inherit\") return true;\n return false;\n }\n\n /** 判断是否为“选项列表”容器(时间/下拉/listbox 等)。 */\n function isOptionListContainer(el: Element): boolean {\n if (el.getAttribute(\"role\") === \"listbox\") return true;\n const cls = (el.getAttribute(\"class\") || \"\").toLowerCase();\n if (\n cls.includes(\"time-spinner__list\") ||\n cls.includes(\"select-dropdown\") ||\n cls.includes(\"virtual-list\") ||\n cls.includes(\"option\")\n ) {\n return true;\n }\n\n if (el.tagName === \"UL\") {\n const children = Array.from(el.children);\n if (children.length >= 20) {\n const liCount = children.filter(child => child.tagName === \"LI\").length;\n if (liCount / children.length >= 0.8) return true;\n }\n }\n return false;\n }\n\n /** 针对子节点截断计算动态上限。 */\n function resolveChildLimit(el: Element, defaultLimit: number, hashId?: string): number {\n let nextLimit = defaultLimit;\n if (expandOptionLists && isOptionListContainer(el)) {\n nextLimit = Math.max(nextLimit, MAX_EXPANDED_LIST_CHILDREN);\n }\n if (hashId && expandChildrenRefSet.has(hashId)) {\n nextLimit = Math.max(nextLimit, expandedChildrenLimit);\n }\n return nextLimit;\n }\n\n /**\n * 判断元素或其任何后代是否为交互节点(需要 hash ID)。\n * 用于文本聚合判定:子树无交互后代时可安全合并叶文本。\n */\n function hasInteractiveDescendant(el: Element): boolean {\n if (needsHashId(el)) return true;\n for (const child of Array.from(el.children)) {\n if (hasInteractiveDescendant(child)) return true;\n }\n return false;\n }\n\n /**\n * 深度收集元素子树中所有叶子文本节点的内容。\n * 跳过 SKIP_TAGS 和不可见元素,用于透明容器的文本聚合。\n */\n function collectLeafTexts(el: Element, maxLen: number): string[] {\n const texts: string[] = [];\n for (const node of Array.from(el.childNodes)) {\n if (node.nodeType === Node.TEXT_NODE) {\n const t = node.textContent?.trim();\n if (t) texts.push(t.slice(0, maxLen));\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const child = node as Element;\n if (SKIP_TAGS.has(child.tagName.toUpperCase())) continue;\n try {\n const s = window.getComputedStyle(child);\n if (s.display === \"none\" || s.visibility === \"hidden\") continue;\n } catch { continue; }\n texts.push(...collectLeafTexts(child, maxLen));\n }\n }\n return texts;\n }\n\n function walk(el: Element, depth: number, parentPath: string): string {\n if (emittedNodes >= maxNodes) {\n truncatedByNodeBudget = true;\n return \"\";\n }\n\n if (depth > maxDepth) return \"\";\n if (SKIP_TAGS.has(el.tagName.toUpperCase())) return \"\";\n\n // 跳过标记为 autopilot 内部 UI 的元素(避免 AI 操作自身界面)\n if (el.hasAttribute(\"data-autopilot-ignore\")) return \"\";\n\n // 跳过不可见元素\n const style = window.getComputedStyle(el);\n if (style.display === \"none\" || style.visibility === \"hidden\") return \"\";\n\n // ─── 视口裁剪 ───\n // 检查元素是否在视口内(viewportOnly 关闭时始终通过)\n if (!isInViewport(el, depth)) return \"\";\n\n const indent = \" \".repeat(depth);\n const tag = el.tagName.toLowerCase();\n\n // ─── 角色优先标签 ───\n // 当元素有 INTERACTIVE_ROLES 内的 role 且与 tag 不等价时,\n // 用 role 替代 tag 作为显示标签(如 [combobox] 替代 [input] role=\"combobox\")。\n // 这让 AI 直接从标签判断交互模式,同时省去冗余的 role=\"...\" 属性。\n const rawRole = el.getAttribute(\"role\");\n const useRoleAsTag = !!(rawRole && INTERACTIVE_ROLES.has(rawRole) && rawRole !== tag);\n const displayTag = useRoleAsTag ? rawRole : tag;\n\n // 构建当前元素的内部路径(始终计算,子元素路径依赖它)\n // 注意:路径使用原始 tag 而非 displayTag,保证 hash 计算一致性\n const index = getSiblingIndex(el);\n const currentPath = `${parentPath}/${tag}${index}`;\n // 仅交互节点分配 hash ID 并注册到 RefStore,非交互节点不占 token\n const shouldAssignHash = refStore && needsHashId(el);\n const hashId = shouldAssignHash ? refStore.set(el, currentPath) : undefined;\n\n // 收集有意义的属性(精简版:只保留对 AI 操作有用的信息)\n const attrs: string[] = [];\n\n // 1. id — 最重要的标识信息\n const elId = el.getAttribute(\"id\");\n if (elId) attrs.push(`id=\"${elId}\"`);\n\n // 2. class — 保留第 1 个有语义的类名(不论交互与否,class 对 AI 识别元素语义有价值)\n const className = el.getAttribute(\"class\")?.trim();\n if (className) {\n const cls = className.split(/\\s+/)\n .find(c => c && !c.startsWith(\"data-v-\") && c.length < 25 && !/^[a-z]{1,2}\\d|^_|^css-/.test(c));\n if (cls) attrs.push(`class=\"${cls}\"`);\n }\n\n // 3. 交互属性(href, type, placeholder 等)\n for (const attr of INTERACTIVE_ATTRS) {\n // 若 role 已提升为显示标签,跳过 role 属性避免重复输出\n if (attr === \"role\" && useRoleAsTag) continue;\n const val = el.getAttribute(attr);\n if (val) {\n const safeVal = sanitizeSnapshotAttrValue(val);\n if (safeVal) attrs.push(`${attr}=\"${safeVal}\"`);\n }\n }\n\n // 4. 布尔状态属性(disabled, checked 等)\n for (const attr of BOOLEAN_ATTRS) {\n if (el.hasAttribute(attr)) attrs.push(attr);\n }\n\n // 4.1 运行时布尔状态(property 级别),避免仅靠 attribute 导致状态丢失\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement || el instanceof HTMLButtonElement) {\n if (el.disabled && !attrs.includes(\"disabled\")) attrs.push(\"disabled\");\n }\n if ((el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) && el.readOnly) {\n if (!attrs.includes(\"readonly\")) attrs.push(\"readonly\");\n }\n\n // 5. 事件绑定 — 只标记有 onclick(最重要的交互信号)\n if (el.hasAttribute(\"onclick\")) attrs.push(\"onclick\");\n\n // 5.1 运行时事件绑定(addEventListener 追踪)\n const trackedEvents = getSnapshotListenerEvents(el);\n if (trackedEvents.length > 0) {\n const preview = trackedEvents.slice(0, 6).map(abbrevEvent).join(\",\");\n const suffix = trackedEvents.length > 6 ? \",...\" : \"\";\n attrs.push(`listeners=\"${preview}${suffix}\"`);\n }\n\n // 6. data-* 属性 — 只保留 data-testid(自动化测试定位用)\n const testId = el.getAttribute(\"data-testid\") || el.getAttribute(\"data-test-id\");\n if (testId) {\n const safeTestId = sanitizeSnapshotAttrValue(testId).slice(0, 25);\n if (safeTestId) attrs.push(`data-testid=\"${safeTestId}\"`);\n }\n\n // 7. 对于 input/textarea,补充当前实际 value(截短到 40 字符)\n if ((el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) && el.value) {\n const currentVal = sanitizeSnapshotAttrValue(el.value).slice(0, 40);\n const attrVal = el.getAttribute(\"value\");\n if (attrVal !== currentVal) {\n attrs.push(`val=\"${currentVal}\"`);\n }\n }\n\n // 7.1 对于 checkbox/radio,补充运行时 checked 状态(property 级别)\n if (el instanceof HTMLInputElement && (el.type === \"checkbox\" || el.type === \"radio\") && el.checked) {\n if (!attrs.includes(\"checked\")) attrs.push(\"checked\");\n }\n\n // 8. 对于 select,补充当前选中 value;对于 option,按运行时 selected 状态输出\n if (el instanceof HTMLSelectElement && el.value) {\n attrs.push(`val=\"${sanitizeSnapshotAttrValue(el.value).slice(0, 40)}\"`);\n }\n if (el instanceof HTMLOptionElement && el.selected) {\n if (!attrs.includes(\"selected\")) attrs.push(\"selected\");\n }\n\n // 获取直接文本(不含子元素文本)\n let directText = \"\";\n for (let i = 0; i < el.childNodes.length; i++) {\n const node = el.childNodes[i];\n if (node.nodeType === Node.TEXT_NODE) {\n const t = node.textContent?.trim();\n if (t) directText += t + \" \";\n }\n }\n directText = directText.trim();\n\n // ─── 智能剪枝(链式坍塌) ───\n // 无意义布局容器不输出自身行,子内容直接提升到当前层级。\n // 若子树无任何交互后代,则合并所有叶文本为一行(文本聚合)。\n if (isEmptyLayoutContainer(el, directText)) {\n const allChildren = Array.from(el.children);\n\n // 文本聚合:子树无交互后代时,合并所有叶子文本为一行\n if (!allChildren.some(c => hasInteractiveDescendant(c))) {\n const texts = collectLeafTexts(el, maxTextLength);\n if (texts.length > 0) {\n emittedNodes++;\n return `${indent}\"${texts.join(\" · \").slice(0, maxTextLength * 3)}\"`;\n }\n return \"\";\n }\n\n // 链式穿透:有交互后代时,子内容直接提升(不输出 collapsed-group)\n const orderedChildren = orderChildrenByPriority(allChildren);\n const childLimit = resolveChildLimit(el, maxChildren, hashId);\n const selectedChildren = orderedChildren.slice(0, childLimit);\n const omittedChildren = orderedChildren.length - selectedChildren.length;\n\n const childBlocks: string[] = [];\n for (let i = 0; i < selectedChildren.length; i++) {\n // 子元素继承当前路径(保证 hash 计算正确),但不增加缩进\n const childResult = walk(selectedChildren[i], depth, currentPath);\n if (childResult) childBlocks.push(childResult);\n }\n\n // 如果子树也全部为空,整个容器就被剪掉\n if (childBlocks.length === 0 && omittedChildren <= 0) {\n return \"\";\n }\n\n let result = childBlocks.join(\"\\n\");\n if (omittedChildren > 0) {\n result += `\\n${indent}... (${omittedChildren} children omitted)`;\n }\n return result;\n }\n\n // 构建当前元素描述:[显示标签] \"文本\" 属性 #hashID(仅交互节点)\n // displayTag 在有交互性 role 时为 role 值,否则为原始 HTML tag\n let line = `${indent}[${displayTag}]`;\n if (directText) line += ` \"${directText.slice(0, maxTextLength)}\"`;\n if (attrs.length) line += ` ${attrs.join(\" \")}`;\n // 仅交互节点输出 hash ID,非交互节点不附加标识(省 token)\n if (hashId) {\n line += ` #${hashId}`;\n }\n\n const lines: string[] = [line];\n emittedNodes++;\n\n // 递归子元素(优先保留可交互元素,再保留普通元素)\n const allChildren = Array.from(el.children);\n const orderedChildren = orderChildrenByPriority(allChildren);\n const childLimit = resolveChildLimit(el, maxChildren, hashId);\n const selectedChildren = orderedChildren.slice(0, childLimit);\n const omittedChildren = orderedChildren.length - selectedChildren.length;\n\n for (let i = 0; i < selectedChildren.length; i++) {\n const childResult = walk(selectedChildren[i], depth + 1, currentPath);\n if (childResult) lines.push(childResult);\n }\n\n if (omittedChildren > 0) {\n lines.push(`${indent} ... (${omittedChildren} children omitted)`);\n }\n\n // 纯文本布局标签简化:无 hashId、无子输出的布局标签只输出文本\n // 例如 [div] \"租户\" → \"租户\",去掉无意义的标签外壳\n if (!hashId && LAYOUT_TAGS.has(el.tagName) && directText && lines.length === 1) {\n return `${indent}\"${directText.slice(0, maxTextLength)}\"`;\n }\n\n return lines.join(\"\\n\");\n }\n\n // 根元素自身的标签作为路径起点,walk 内部不再重复追加\n // 例如 root=body 时,parentPath=\"\",walk 中 currentPath=\"/body\"\n const output = walk(root, 0, \"\") || \"(空页面)\";\n if (!truncatedByNodeBudget) return output;\n return `${output}\\n... (snapshot truncated: maxNodes=${maxNodes})`;\n}\n\n/**\n * 查询所有匹配元素并返回摘要信息(标签、文本、关键属性)。\n */\nfunction queryAllElements(selector: string, limit = 20): string {\n try {\n const elements = document.querySelectorAll(selector);\n if (elements.length === 0) return `未找到匹配 \"${selector}\" 的元素`;\n\n const results: string[] = [`找到 ${elements.length} 个元素:`];\n const count = Math.min(elements.length, limit);\n\n for (let i = 0; i < count; i++) {\n const el = elements[i];\n const tag = el.tagName.toLowerCase();\n const text = el.textContent?.trim().slice(0, 60) ?? \"\";\n const id = el.id ? `#${el.id}` : \"\";\n const cls = el.className && typeof el.className === \"string\"\n ? `.${el.className.split(\" \").filter(Boolean).join(\".\")}`\n : \"\";\n results.push(` ${i + 1}. <${tag}${id}${cls}> \"${text}\"`);\n }\n\n if (elements.length > limit) {\n results.push(` ...还有 ${elements.length - limit} 个元素`);\n }\n\n return results.join(\"\\n\");\n } catch {\n return `选择器语法错误: ${selector}`;\n }\n}\n\n/**\n * 多行文本块缩进(中)/ Indent each line of a multiline block (EN).\n */\nfunction indentMultiline(block: string, indentLevel: number): string {\n const prefix = \" \".repeat(indentLevel);\n return block\n .split(\"\\n\")\n .map(line => `${prefix}${line}`)\n .join(\"\\n\");\n}\n\nexport function createPageInfoTool(): ToolDefinition {\n return {\n name: \"page_info\",\n description: [\n \"Page information tool.\",\n \"Actions: get_url, get_title, get_selection, get_viewport, snapshot, query_all.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"Page info action name\",\n }),\n selector: Type.Optional(\n Type.String({ description: \"CSS selector for query_all\" }),\n ),\n maxDepth: Type.Optional(\n Type.Number({ description: \"Snapshot max depth\" }),\n ),\n viewportOnly: Type.Optional(\n Type.Boolean({ description: \"Snapshot only visible elements\" }),\n ),\n pruneLayout: Type.Optional(\n Type.Boolean({ description: \"Collapse empty layout containers\" }),\n ),\n maxNodes: Type.Optional(\n Type.Number({ description: \"Snapshot max nodes\" }),\n ),\n maxChildren: Type.Optional(\n Type.Number({ description: \"Snapshot max children per node\" }),\n ),\n maxTextLength: Type.Optional(\n Type.Number({ description: \"Snapshot max text length\" }),\n ),\n expandOptionLists: Type.Optional(\n Type.Boolean({ description: \"Expand option/list containers\" }),\n ),\n expandChildrenRefs: Type.Optional(\n Type.Array(Type.String({ description: \"#hashIDs to expand children for\" })),\n ),\n expandedChildrenLimit: Type.Optional(\n Type.Number({ description: \"Expanded child limit\" }),\n ),\n listenerEvents: Type.Optional(\n Type.Array(Type.String({ description: \"Snapshot listener event whitelist\" })),\n ),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n\n try {\n switch (action) {\n case \"get_url\":\n return { content: window.location.href };\n\n case \"get_title\":\n return { content: document.title || \"(无标题)\" };\n\n case \"get_selection\": {\n // 获取用户当前选中的文本\n const selection = window.getSelection();\n const text = selection?.toString().trim() ?? \"\";\n return { content: text || \"(未选中任何文本)\" };\n }\n\n case \"get_viewport\": {\n // 获取视口和滚动信息\n const info = {\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n pageWidth: document.documentElement.scrollWidth,\n pageHeight: document.documentElement.scrollHeight,\n };\n return { content: JSON.stringify(info, null, 2) };\n }\n\n case \"snapshot\": {\n // 生成 DOM 快照 — AI 理解当前页面结构的主要方式\n const maxDepth = (params.maxDepth as number) ?? 12;\n const viewportOnly = (params.viewportOnly as boolean) ?? true;\n const pruneLayout = (params.pruneLayout as boolean) ?? true;\n const maxNodes = (params.maxNodes as number) ?? 220;\n const maxChildren = (params.maxChildren as number) ?? 25;\n const maxTextLength = (params.maxTextLength as number) ?? 40;\n const expandOptionLists = (params.expandOptionLists as boolean) ?? false;\n const expandChildrenRefs = Array.isArray(params.expandChildrenRefs)\n ? (params.expandChildrenRefs as unknown[]).filter((ref): ref is string => typeof ref === \"string\")\n : undefined;\n const expandedChildrenLimit = typeof params.expandedChildrenLimit === \"number\"\n ? params.expandedChildrenLimit as number\n : undefined;\n const listenerEvents = Array.isArray(params.listenerEvents)\n ? (params.listenerEvents as unknown[]).filter((event): event is string => typeof event === \"string\")\n : undefined;\n const snapshot = generateSnapshot(document.body, {\n maxDepth,\n viewportOnly,\n pruneLayout,\n maxNodes,\n maxChildren,\n maxTextLength,\n expandOptionLists,\n expandChildrenRefs,\n expandedChildrenLimit,\n listenerEvents,\n refStore: getActiveRefStore(),\n });\n return { content: snapshot };\n }\n\n case \"query_all\": {\n // 查询所有匹配元素\n const selector = params.selector as string;\n if (!selector) return { content: \"缺少 selector 参数\" };\n return { content: queryAllElements(selector) };\n }\n\n default:\n return { content: `未知的页面信息动作: ${action}` };\n }\n } catch (err) {\n return {\n content: `页面信息操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, action },\n };\n }\n },\n };\n}\n","/**\n * Navigate Tool — 页面导航工具(增强版)。\n *\n * 支持 5 种动作:\n * goto — 跳转到指定 URL\n * back — 浏览器后退\n * forward — 浏览器前进\n * reload — 刷新当前页面\n * scroll — 滚动页面到指定位置或元素(支持 RefStore hash ID + 多策略对齐)\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport { getActiveRefStore } from \"./dom-tool.js\";\n\n/** 解析 selector(支持 RefStore hash ID 和 CSS 选择器) */\nfunction resolveElement(selector: string): Element | null {\n if (selector.startsWith(\"#\")) {\n const store = getActiveRefStore();\n if (store) {\n const id = selector.slice(1);\n if (store.has(id)) return store.get(id) ?? null;\n }\n }\n try { return document.querySelector(selector); } catch { return null; }\n}\n\nexport function createNavigateTool(): ToolDefinition {\n return {\n name: \"navigate\",\n description: [\n \"Page navigation tool.\",\n \"Actions: goto, back, forward, reload, scroll.\",\n \"scroll supports #hashID from snapshot or CSS selector.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"Navigation action name\",\n }),\n url: Type.Optional(Type.String({ description: \"URL for goto\" })),\n selector: Type.Optional(\n Type.String({ description: \"#hashID or CSS selector for scroll\" }),\n ),\n x: Type.Optional(Type.Number({ description: \"Horizontal scroll position\" })),\n y: Type.Optional(Type.Number({ description: \"Vertical scroll position\" })),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n\n try {\n switch (action) {\n case \"goto\": {\n const url = params.url as string;\n if (!url) return { content: \"缺少 url 参数\" };\n window.location.href = url;\n return { content: `正在导航到 ${url}` };\n }\n\n case \"back\": {\n window.history.back();\n return { content: \"已后退\" };\n }\n\n case \"forward\": {\n window.history.forward();\n return { content: \"已前进\" };\n }\n\n case \"reload\": {\n window.location.reload();\n return { content: \"正在刷新页面\" };\n }\n\n case \"scroll\": {\n const selector = params.selector as string | undefined;\n\n if (selector) {\n const el = resolveElement(selector);\n if (!el) return { content: `未找到元素 \"${selector}\"` };\n // 尝试 scrollIntoViewIfNeeded(Chrome),回退 scrollIntoView center\n if (\"scrollIntoViewIfNeeded\" in el) {\n (el as HTMLElement & { scrollIntoViewIfNeeded: (c?: boolean) => void }).scrollIntoViewIfNeeded(true);\n } else {\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n return { content: `已滚动到元素 \"${selector}\"` };\n }\n\n const x = (params.x as number) ?? 0;\n const y = (params.y as number) ?? 0;\n window.scrollTo({ left: x, top: y, behavior: \"smooth\" });\n return { content: `已滚动到 (${x}, ${y})` };\n }\n\n default:\n return { content: `未知的导航动作: ${action}` };\n }\n } catch (err) {\n return {\n content: `导航操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, action },\n };\n }\n },\n };\n}\n","/**\n * Wait Tool 等待工具 / Wait utility for DOM conditions.\n *\n * 支持动作 / Supported actions:\n * - wait_for_selector: 等待选择器达到状态 / wait selector state\n * - wait_for_hidden: 等待元素隐藏或移除 / wait element hidden or detached\n * - wait_for_text: 等待页面出现文本 / wait text appears in page\n * - wait_for_stable: 等待 DOM 进入静默窗口 / wait DOM quiet window\n *\n * 说明 / Notes:\n * - hash selector(如 #abc123)优先通过 RefStore 解析。\n * - 可见性语义与 dom-tool 保持一致(参考 Playwright 风格)。\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport { getActiveRefStore } from \"./dom-tool.js\";\n\nconst DEFAULT_TIMEOUT = 6_000;\nconst POLL_INTERVAL_MS = 80;\nconst STABLE_TICK_MS = 50;\nconst OBSERVER_OPTIONS: MutationObserverInit = {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n};\nconst TEXT_OBSERVER_OPTIONS: MutationObserverInit = {\n childList: true,\n subtree: true,\n characterData: true,\n};\n\ntype SelectorState = \"attached\" | \"visible\" | \"hidden\" | \"detached\";\n\n/**\n * 可见性判定 / Visibility check.\n *\n * 与 dom-tool 保持一致,处理 display:contents、visibility、opacity、零尺寸等场景。\n */\nfunction isVisible(el: Element): boolean {\n if (!(el instanceof HTMLElement || el instanceof SVGElement)) return false;\n if (!el.isConnected) return false;\n const style = window.getComputedStyle(el);\n\n if (style.display === \"contents\") {\n for (let child = el.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === Node.ELEMENT_NODE && isVisible(child as Element)) return true;\n if (child.nodeType === Node.TEXT_NODE) {\n const range = document.createRange();\n range.selectNodeContents(child);\n const rects = range.getClientRects();\n for (let i = 0; i < rects.length; i++) {\n if (rects[i].width > 0 && rects[i].height > 0) return true;\n }\n }\n }\n return false;\n }\n if (style.display === \"none\") return false;\n if (typeof el.checkVisibility === \"function\") {\n if (!el.checkVisibility()) return false;\n }\n if (style.visibility !== \"visible\") return false;\n if (style.opacity === \"0\") return false;\n const rect = el.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n}\n\n/**\n * 解析选择器 / Resolve selector.\n *\n * 先尝试 RefStore hash,再回退到 document.querySelector。\n */\nfunction resolveSelector(selector: string): Element | null {\n if (selector.startsWith(\"#\")) {\n const store = getActiveRefStore();\n if (store) {\n const id = selector.slice(1);\n if (store.has(id)) return store.get(id) ?? null;\n }\n }\n try { return document.querySelector(selector); } catch { return null; }\n}\n\n/**\n * 计算选择器状态 / Evaluate selector state.\n *\n * @returns matched 表示是否达到目标状态;element 为当前命中的元素(如果存在)。\n */\nfunction evaluateSelectorState(selector: string, state: SelectorState): { matched: boolean; element?: Element } {\n const el = resolveSelector(selector) ?? undefined;\n switch (state) {\n case \"attached\":\n return { matched: Boolean(el), element: el };\n case \"visible\":\n return { matched: Boolean(el && isVisible(el)), element: el };\n case \"hidden\":\n return { matched: !el || !isVisible(el), element: el };\n case \"detached\":\n return { matched: !el, element: el };\n default:\n return { matched: false };\n }\n}\n\n/**\n * 等待选择器达到指定状态 / Wait selector reaches state.\n *\n * 策略:轮询 + MutationObserver 双通道,既保证及时性也降低漏检概率。\n */\nfunction waitForSelectorState(\n selector: string,\n state: SelectorState,\n timeoutMs: number,\n): Promise<{ element?: Element }> {\n return new Promise((resolve, reject) => {\n let finished = false;\n\n const finish = (handler: () => void): void => {\n if (finished) return;\n finished = true;\n clearTimeout(timer);\n clearInterval(interval);\n observer.disconnect();\n handler();\n };\n\n const check = (): void => {\n let result: { matched: boolean; element?: Element };\n try {\n result = evaluateSelectorState(selector, state);\n } catch {\n finish(() => reject(new Error(`选择器语法错误: ${selector}`)));\n return;\n }\n if (result.matched) {\n finish(() => resolve({ element: result.element }));\n }\n };\n\n const timer = setTimeout(() => {\n finish(() => reject(new Error(`等待 \"${selector}\" 达到状态 \"${state}\" 超时 (${timeoutMs}ms)`)));\n }, timeoutMs);\n\n const interval = setInterval(check, POLL_INTERVAL_MS);\n const observer = new MutationObserver(check);\n observer.observe(document.body, OBSERVER_OPTIONS);\n\n check();\n });\n}\n\n/**\n * 等待文本出现 / Wait text appears.\n *\n * 先做一次即时检查,再监听 DOM 变化。\n */\nfunction waitForText(text: string, timeoutMs: number): Promise<void> {\n return new Promise((resolve, reject) => {\n // 先检查是否已包含\n if (document.body.textContent?.includes(text)) {\n resolve();\n return;\n }\n\n const timer = setTimeout(() => {\n observer.disconnect();\n reject(new Error(`等待文本 \"${text}\" 出现超时 (${timeoutMs}ms)`));\n }, timeoutMs);\n\n const observer = new MutationObserver(() => {\n if (document.body.textContent?.includes(text)) {\n clearTimeout(timer);\n observer.disconnect();\n resolve();\n }\n });\n\n observer.observe(document.body, TEXT_OBSERVER_OPTIONS);\n });\n}\n\n/**\n * 等待 DOM 稳定 / Wait DOM stable.\n *\n * 定义:quietMs 窗口内没有任何 MutationObserver 事件。\n */\nfunction waitForDomStable(timeoutMs: number, quietMs: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const startedAt = Date.now();\n let lastMutationAt = Date.now();\n\n const finish = (ok: boolean, err?: Error): void => {\n clearInterval(tick);\n observer.disconnect();\n if (ok) resolve();\n else reject(err ?? new Error(\"等待页面稳定失败\"));\n };\n\n const observer = new MutationObserver(() => {\n lastMutationAt = Date.now();\n });\n\n observer.observe(document.body, OBSERVER_OPTIONS);\n\n const tick = setInterval(() => {\n const now = Date.now();\n if (now - startedAt > timeoutMs) {\n finish(false, new Error(`等待页面稳定超时 (${timeoutMs}ms)`));\n return;\n }\n if (now - lastMutationAt >= quietMs) {\n finish(true);\n }\n }, STABLE_TICK_MS);\n });\n}\n\nexport function createWaitTool(): ToolDefinition {\n return {\n name: \"wait\",\n description: [\n \"Wait for page conditions.\",\n \"Actions: wait_for_selector, wait_for_hidden, wait_for_text, wait_for_stable.\",\n \"wait_for_selector supports attached, visible, hidden, detached.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"Wait action name\",\n }),\n selector: Type.Optional(\n Type.String({ description: \"Selector for wait_for_selector/wait_for_hidden\" }),\n ),\n state: Type.Optional(\n Type.String({ description: \"Selector state: attached | visible | hidden | detached\" }),\n ),\n text: Type.Optional(\n Type.String({ description: \"Text to wait for\" }),\n ),\n timeout: Type.Optional(\n Type.Number({ description: \"Timeout in ms\" }),\n ),\n quietMs: Type.Optional(\n Type.Number({ description: \"Quiet window in ms\" }),\n ),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n const timeoutMs = (params.timeout as number) ?? DEFAULT_TIMEOUT;\n\n try {\n switch (action) {\n case \"wait_for_selector\": {\n const selector = params.selector as string;\n if (!selector) return { content: \"缺少 selector 参数\" };\n const state = (params.state as SelectorState | undefined) ?? \"attached\";\n if (![\"attached\", \"visible\", \"hidden\", \"detached\"].includes(state)) {\n return { content: `无效 state: ${state}` };\n }\n const result = await waitForSelectorState(selector, state, timeoutMs);\n if (state === \"attached\" || state === \"visible\") {\n const tag = result.element?.tagName?.toLowerCase();\n return { content: `元素 \"${selector}\" 已达到状态 \"${state}\"${tag ? ` (${tag})` : \"\"}` };\n }\n return { content: `元素 \"${selector}\" 已达到状态 \"${state}\"` };\n }\n\n case \"wait_for_hidden\": {\n const selector = params.selector as string;\n if (!selector) return { content: \"缺少 selector 参数\" };\n await waitForSelectorState(selector, \"hidden\", timeoutMs);\n return { content: `元素 \"${selector}\" 已隐藏或消失` };\n }\n\n case \"wait_for_text\": {\n const text = params.text as string;\n if (!text) return { content: \"缺少 text 参数\" };\n await waitForText(text, timeoutMs);\n return { content: `文本 \"${text}\" 已出现` };\n }\n\n case \"wait_for_stable\": {\n const quietMs = Math.max(50, Math.floor((params.quietMs as number) ?? 300));\n await waitForDomStable(timeoutMs, quietMs);\n return { content: `页面已稳定(静默窗口 ${quietMs}ms)` };\n }\n\n default:\n return { content: `未知的等待动作: ${action}` };\n }\n } catch (err) {\n return {\n content: `等待操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, action },\n };\n }\n },\n };\n}\n","/**\n * Evaluate Tool — 在页面上下文中执行任意 JavaScript 表达式。\n *\n * 替代 Playwright 的 page.evaluate()。\n * 运行环境:浏览器 Content Script。\n *\n * 这是最灵活的工具 — 当其他 tools 无法满足需求时,\n * AI 可以直接编写 JS 代码来操作页面。\n *\n * 支持 2 种动作:\n * evaluate — 执行 JS 表达式并返回结果\n * evaluate_handle — 执行 JS 并返回序列化的 DOM 信息\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\n\n/**\n * 安全执行 JS 表达式,捕获错误并序列化结果。\n */\nfunction safeEvaluate(expression: string): { result?: unknown; error?: string } {\n try {\n // 使用 Function 构造器代替 eval,避免污染当前作用域\n const fn = new Function(`\"use strict\"; return (${expression});`);\n const result = fn();\n return { result };\n } catch {\n // 如果作为表达式失败,尝试作为语句块执行\n try {\n const fn = new Function(`\"use strict\"; ${expression}`);\n const result = fn();\n return { result };\n } catch (err2) {\n return { error: err2 instanceof Error ? err2.message : String(err2) };\n }\n }\n}\n\n/**\n * 将执行结果序列化为字符串(处理 DOM 元素、循环引用等)。\n */\nfunction serializeResult(value: unknown): string {\n if (value === undefined) return \"undefined\";\n if (value === null) return \"null\";\n\n // DOM 元素 → 返回 outerHTML 片段\n if (value instanceof Element) {\n const tag = value.tagName.toLowerCase();\n const id = value.id ? `#${value.id}` : \"\";\n const text = value.textContent?.trim().slice(0, 100) ?? \"\";\n return `<${tag}${id}> \"${text}\"`;\n }\n\n // NodeList / HTMLCollection → 逐个序列化\n if (value instanceof NodeList || value instanceof HTMLCollection) {\n const items = Array.from(value).map((el, i) => ` ${i}: ${serializeResult(el)}`);\n return `[${value.length} elements]\\n${items.join(\"\\n\")}`;\n }\n\n // 普通值 → JSON 序列化\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nexport function createEvaluateTool(): ToolDefinition {\n return {\n name: \"evaluate\",\n description: [\n \"Execute JavaScript in page context.\",\n \"Use when other tools are insufficient; can access document and window.\",\n ].join(\" \"),\n\n schema: Type.Object({\n expression: Type.String({\n description: \"JavaScript expression or code block to execute.\",\n }),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const expression = params.expression as string;\n if (!expression) return { content: \"缺少 expression 参数\" };\n\n const { result, error } = safeEvaluate(expression);\n\n if (error) {\n return {\n content: `JS 执行错误: ${error}`,\n details: { error: true, expression },\n };\n }\n\n return { content: serializeResult(result) };\n },\n };\n}\n","/**\n * RefStore — 快照 hash ID 与 DOM 元素的映射表。\n *\n * 快照生成时,根据元素的 DOM 路径 + 页面 URL 生成确定性 hash ID,\n * 同时保存 ID → Element 的映射。AI 使用 hash ID 作为 selector 定位元素,\n * 免去超长 XPath 路径,大幅减少 token 消耗。\n *\n * 优势:\n * - **确定性**:同一元素无论快照顺序,始终得到相同 ID\n * - **并发安全**:多次快照不会产生 ID 冲突\n * - **跨页面隔离**:URL hash 作为命名空间,不同页面元素 ID 互不碰撞\n *\n * 生命周期:每次 WebAgent.chat() 调用时创建,对话结束后清空。\n *\n * 使用方:\n * page-info-tool.ts — generateSnapshot() 写入映射\n * dom-tool.ts — queryElement() 读取映射\n * index.ts — WebAgent 持有实例,管理生命周期\n */\n\n/**\n * FNV-1a 32-bit hash — 简单高效的字符串散列。\n * 分布均匀,碰撞率低,适合生成短 ID。\n */\nfunction fnv1a(str: string): number {\n let h = 0x811c9dc5; // FNV offset basis\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 0x01000193); // FNV prime\n }\n return h >>> 0; // 转为无符号 32-bit\n}\n\n/**\n * hash ID → DOM 元素的映射存储。\n *\n * - `set(el, path)` 由快照生成时调用,返回确定性 hash ID\n * - `get(id)` 由 dom-tool 查询时调用,根据 hash ID 取回元素\n * - `has(id)` 检查 ID 是否存在(用于 selector 类型判断)\n * - `clear()` 每次对话结束后清空\n */\nexport class RefStore {\n private map = new Map<string, Element>();\n /** 页面 URL 的 hash 前缀,用于跨页面命名空间隔离 */\n private urlKey: string;\n\n /**\n * @param url 当前页面 URL(可选)。传入后作为 hash 命名空间,\n * 使不同页面的相同 DOM 路径产生不同 ID。\n */\n constructor(url?: string) {\n this.urlKey = url ?? \"\";\n }\n\n /**\n * 注册一个元素,返回确定性 hash ID。\n * 相同 URL + path 始终产生相同 ID(并发安全)。\n *\n * @param el DOM 元素引用\n * @param path 元素的 XPath-like 路径(如 \"/body/div[1]/main/button\")\n */\n set(el: Element, path: string): string {\n const baseId = fnv1a(this.urlKey + path).toString(36);\n let id = baseId;\n // 极小概率碰撞处理:不同 path 映射到相同 hash 时追加后缀\n let suffix = 2;\n while (this.map.has(id) && this.map.get(id) !== el) {\n id = baseId + suffix++;\n }\n this.map.set(id, el);\n return id;\n }\n\n /**\n * 根据 hash ID 获取 DOM 元素。\n * 返回 Element 或 undefined(ID 不存在或元素已被移除)。\n */\n get(id: string): Element | undefined {\n return this.map.get(id);\n }\n\n /** 检查 hash ID 是否存在 */\n has(id: string): boolean {\n return this.map.has(id);\n }\n\n /** 清空所有映射 */\n clear(): void {\n this.map.clear();\n }\n\n /**\n * 重置映射表:清空所有映射,并可选更新 URL 命名空间。\n *\n * 用于页面导航后刷新 RefStore:旧的 hash ID → Element 映射已失效,\n * 需要用新 URL 重新生成确定性 hash。\n *\n * @param url 新的页面 URL(不传则保持原 URL 命名空间)\n */\n reset(url?: string): void {\n this.map.clear();\n if (url !== undefined) {\n this.urlKey = url;\n }\n }\n\n /** 当前映射数量 */\n get size(): number {\n return this.map.size;\n }\n}\n","/**\n * AutoPilot UI 面板样式。\n *\n * 全部使用 CSS-in-JS(字符串注入),零外部依赖。\n * 所有选择器在 #autopilot-panel 作用域下,避免污染宿主样式。\n *\n * 风格:白色基调 — 轻量现代风,微妙阴影与品牌色点缀。\n */\n\nexport const PANEL_STYLES = /* css */ `\n/* ─── CSS Variables ─── */\n#autopilot-panel {\n --ap-bg: #ffffff;\n --ap-bg-secondary: #f8f9fb;\n --ap-bg-tertiary: #f0f2f5;\n --ap-border: #e8eaed;\n --ap-border-hover: #d0d3d9;\n --ap-text: #1a1a2e;\n --ap-text-secondary: #6b7280;\n --ap-text-tertiary: #b0b7c3;\n --ap-primary: #6366f1;\n --ap-primary-hover: #4f46e5;\n --ap-primary-light: rgba(99, 102, 241, 0.08);\n --ap-primary-glow: rgba(99, 102, 241, 0.18);\n --ap-success: #22c55e;\n --ap-error: #ef4444;\n --ap-warning: #f59e0b;\n --ap-shadow: 0 0 12px rgba(0, 0, 0, 0.06);\n --ap-shadow-lg: 0 0 16px rgba(0, 0, 0, 0.08);\n --ap-radius: 16px;\n --ap-radius-sm: 10px;\n --ap-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n --ap-transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ─── 操作遮罩 ─── */\n#autopilot-mask {\n position: fixed;\n inset: 0;\n z-index: 99998;\n background: rgba(255, 255, 255, 0.5);\n backdrop-filter: blur(2px);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--ap-transition);\n}\n#autopilot-mask.active {\n opacity: 1;\n pointer-events: auto;\n cursor: not-allowed;\n}\n#autopilot-mask .ap-mask-label {\n position: absolute;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n background: #ffffff;\n border: 1px solid var(--ap-border);\n color: var(--ap-primary);\n font-family: var(--ap-font);\n font-size: 13px;\n font-weight: 500;\n padding: 10px 24px;\n border-radius: 24px;\n letter-spacing: 0.2px;\n display: flex;\n align-items: center;\n gap: 10px;\n user-select: none;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n}\n#autopilot-mask .ap-mask-spinner {\n width: 14px;\n height: 14px;\n border: 2px solid rgba(99, 102, 241, 0.2);\n border-top-color: var(--ap-primary);\n border-radius: 50%;\n animation: ap-spin 0.8s linear infinite;\n}\n@keyframes ap-spin {\n to { transform: rotate(360deg); }\n}\n\n/* ─── 面板容器 ─── */\n#autopilot-panel {\n position: fixed;\n z-index: 99999;\n width: 520px;\n max-height: 680px;\n display: flex;\n flex-direction: column;\n background: var(--ap-bg);\n border-radius: var(--ap-radius);\n box-shadow: var(--ap-shadow);\n border: 1px solid var(--ap-border);\n font-family: var(--ap-font);\n font-size: 14px;\n color: var(--ap-text);\n overflow: hidden;\n opacity: 1;\n transition: opacity var(--ap-transition), transform var(--ap-transition);\n user-select: none;\n}\n#autopilot-panel.collapsed {\n opacity: 0;\n pointer-events: none;\n transform: scale(0.92);\n}\n\n/* ─── 触发按钮 (FAB) ─── */\n#autopilot-fab {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 99998;\n width: 40px;\n height: 40px;\n border-radius: 12px;\n background: #ffffff;\n color: var(--ap-primary);\n border: 1px solid var(--ap-border);\n cursor: pointer;\n box-shadow: 0 0 8px rgba(0, 0, 0, 0.06);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s, box-shadow 0.2s, opacity var(--ap-transition);\n font-family: var(--ap-font);\n padding: 6px;\n overflow: hidden;\n touch-action: none;\n}\n#autopilot-fab:active {\n cursor: pointer;\n}\n/* FAB 拖拽态:长按激活拖拽时切换为 grabbing 光标 */\n#autopilot-fab.dragging {\n cursor: grabbing;\n}\n/* FAB 激活态:面板展开时 FAB 显示品牌色边框 */\n#autopilot-fab.active {\n border-color: var(--ap-primary);\n box-shadow: 0 0 0 3px var(--ap-primary-light), 0 0 8px rgba(0, 0, 0, 0.06);\n}\n#autopilot-fab img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n pointer-events: none;\n}\n\n/* ─── 头部 ─── */\n.ap-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--ap-border);\n background: var(--ap-bg);\n flex-shrink: 0;\n}\n.ap-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.ap-header-logo {\n width: 30px;\n height: 30px;\n border-radius: 8px;\n background: var(--ap-bg-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: hidden;\n padding: 3px;\n}\n.ap-header-logo img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.ap-header-title {\n font-weight: 600;\n font-size: 15px;\n color: var(--ap-text);\n letter-spacing: -0.01em;\n}\n.ap-header-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n.ap-header-btn {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--ap-text-tertiary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, color 0.15s;\n font-family: var(--ap-font);\n}\n.ap-header-btn:hover {\n background: var(--ap-bg-tertiary);\n color: var(--ap-text-secondary);\n}\n.ap-header-btn svg {\n width: 16px;\n height: 16px;\n}\n\n/* ─── 状态条 ─── */\n.ap-status {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n font-size: 12px;\n color: var(--ap-text-secondary);\n background: var(--ap-bg-secondary);\n border-bottom: 1px solid var(--ap-border);\n flex-shrink: 0;\n}\n.ap-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--ap-text-tertiary);\n flex-shrink: 0;\n transition: background 0.2s;\n}\n.ap-status-dot.idle {\n background: var(--ap-success);\n box-shadow: 0 0 6px rgba(34, 197, 94, 0.4);\n}\n.ap-status-dot.running {\n background: var(--ap-primary);\n box-shadow: 0 0 8px var(--ap-primary-glow);\n animation: ap-pulse 1.5s ease-in-out infinite;\n}\n.ap-status-dot.error {\n background: var(--ap-error);\n box-shadow: 0 0 6px rgba(239, 68, 68, 0.4);\n}\n@keyframes ap-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n/* ─── 消息区 ─── */\n.ap-messages {\n flex: 1;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-height: 200px;\n max-height: 420px;\n scroll-behavior: smooth;\n}\n.ap-messages::-webkit-scrollbar { width: 4px; }\n.ap-messages::-webkit-scrollbar-track { background: transparent; }\n.ap-messages::-webkit-scrollbar-thumb {\n background: var(--ap-text-tertiary);\n border-radius: 4px;\n}\n\n/* 消息气泡 */\n.ap-msg {\n max-width: 88%;\n padding: 10px 14px;\n border-radius: var(--ap-radius-sm);\n line-height: 1.6;\n font-size: 13.5px;\n word-break: break-word;\n animation: ap-msg-in 0.25s ease-out;\n}\n@keyframes ap-msg-in {\n from { opacity: 0; transform: translateY(6px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ap-msg.user {\n align-self: flex-end;\n background: var(--ap-primary);\n color: #fff;\n border-bottom-right-radius: 4px;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.2);\n}\n.ap-msg.assistant {\n align-self: flex-start;\n background: var(--ap-bg-tertiary);\n color: var(--ap-text);\n border: 1px solid var(--ap-border);\n border-bottom-left-radius: 4px;\n}\n.ap-msg.tool {\n align-self: flex-start;\n background: var(--ap-bg-secondary);\n color: var(--ap-text-secondary);\n font-size: 12px;\n font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;\n padding: 8px 12px;\n border-left: 3px solid var(--ap-primary);\n border-radius: 0 var(--ap-radius-sm) var(--ap-radius-sm) 0;\n}\n.ap-msg.error {\n align-self: flex-start;\n background: rgba(239, 68, 68, 0.05);\n color: var(--ap-error);\n border-left: 3px solid var(--ap-error);\n font-size: 12.5px;\n border-radius: 0 var(--ap-radius-sm) var(--ap-radius-sm) 0;\n}\n\n/* ─── 空状态 ─── */\n.ap-empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--ap-text-tertiary);\n padding: 40px 20px;\n text-align: center;\n}\n.ap-empty-icon {\n width: 48px;\n height: 48px;\n opacity: 0.5;\n}\n.ap-empty-icon img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.ap-empty-text {\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* ─── 停止按钮 ─── */\n.ap-stop-container {\n flex-shrink: 0;\n padding: 0 16px 8px;\n}\n.ap-stop-btn {\n width: 100%;\n height: 36px;\n border: 1px solid rgba(239, 68, 68, 0.2);\n border-radius: var(--ap-radius-sm);\n background: rgba(239, 68, 68, 0.04);\n color: var(--ap-error);\n cursor: pointer;\n font-family: var(--ap-font);\n font-size: 12.5px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: background 0.15s, border-color 0.15s;\n}\n.ap-stop-btn:hover {\n background: rgba(239, 68, 68, 0.08);\n border-color: rgba(239, 68, 68, 0.35);\n}\n.ap-stop-btn svg {\n width: 13px;\n height: 13px;\n}\n\n/* ─── 输入区 ─── */\n.ap-input-area {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid var(--ap-border);\n background: var(--ap-bg);\n flex-shrink: 0;\n}\n.ap-input-wrapper {\n flex: 1;\n position: relative;\n}\n.ap-input {\n width: 100%;\n min-height: 40px;\n max-height: 120px;\n padding: 10px 14px;\n border: 1px solid var(--ap-border);\n border-radius: var(--ap-radius-sm);\n background: var(--ap-bg);\n color: var(--ap-text);\n font-family: var(--ap-font);\n font-size: 13.5px;\n line-height: 1.5;\n resize: none;\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n box-sizing: border-box;\n}\n.ap-input:focus {\n border-color: var(--ap-primary);\n box-shadow: 0 0 0 3px var(--ap-primary-light);\n}\n.ap-input::placeholder {\n color: var(--ap-text-tertiary);\n}\n.ap-input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.ap-send-btn {\n width: 40px;\n height: 40px;\n border-radius: var(--ap-radius-sm);\n border: none;\n background: var(--ap-primary);\n color: #fff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, transform 0.1s, box-shadow 0.15s;\n flex-shrink: 0;\n font-family: var(--ap-font);\n}\n.ap-send-btn:hover {\n background: var(--ap-primary-hover);\n box-shadow: 0 2px 10px rgba(99, 102, 241, 0.25);\n}\n.ap-send-btn:active {\n transform: scale(0.95);\n}\n.ap-send-btn:disabled {\n background: var(--ap-text-tertiary);\n cursor: not-allowed;\n box-shadow: none;\n}\n.ap-send-btn svg {\n width: 18px;\n height: 18px;\n}\n\n/* ─── 进度指示器 ─── */\n.ap-typing {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 10px 14px;\n align-self: flex-start;\n}\n.ap-typing-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--ap-primary);\n animation: ap-typing 1.4s ease-in-out infinite;\n}\n.ap-typing-dot:nth-child(2) { animation-delay: 0.2s; }\n.ap-typing-dot:nth-child(3) { animation-delay: 0.4s; }\n@keyframes ap-typing {\n 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }\n 30% { transform: translateY(-4px); opacity: 1; }\n}\n`;\n","/**\n * AutoPilot Logo — 螃蟹图标的 PNG data URI。\n * 从 assets/logo/contours (2).svg 中提取的嵌入式 PNG。\n */\nexport const LOGO_DATA_URL = \"data:image/png;base64,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\";\n","/**\n * AutoPilot SVG 图标集合(内联 SVG 字符串)。\n * 使用微型图标风格,线宽一致,视觉协调。\n */\nimport { LOGO_DATA_URL } from \"./logo-data.js\";\n\nexport const ICONS = {\n /** AutoPilot logo — 螃蟹图标(PNG data URI,用 <img> 渲染) */\n logo: `<img src=\"${LOGO_DATA_URL}\" alt=\"AutoPilot\" style=\"width:100%;height:100%;object-fit:contain;\" />`,\n\n /** 发送 */\n send: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/><polygon points=\"22 2 15 22 11 13 2 9 22 2\"/></svg>`,\n\n /** 最小化 */\n minimize: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`,\n\n /** 清空 */\n trash: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`,\n\n /** 关闭 */\n close: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`,\n\n /** 停止(方块) */\n stop: `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\"/></svg>`,\n};\n","/**\n * AutoPilot UI Panel — 开箱即用的聊天面板 + 操作遮罩。\n *\n * 纯 DOM 实现,零框架依赖。通过 `agent.panel.show()` 一行代码启用。\n *\n * 功能:\n * - 浮动聊天面板(FAB 按钮展开/收起)\n * - 操作遮罩(自动化执行期间阻止用户操作页面)\n * - 实时消息流(用户消息、AI 回复、工具调用、错误)\n * - 输入框 + 发送/停止控制\n *\n * 架构位置:web/ui/ 层,仅依赖 DOM API,不依赖 core。\n * 通过 WebAgent 的 callbacks 接口接收 Agent 事件。\n */\nimport { PANEL_STYLES } from \"./styles.js\";\nimport { ICONS } from \"./icons.js\";\nimport { computePosition, flip, shift, offset } from \"@floating-ui/dom\";\n\n/** 面板配置选项 */\nexport type PanelOptions = {\n /** 面板容器挂载点(默认 document.body) */\n container?: HTMLElement;\n /** 构造时是否自动挂载到 DOM(默认 true)。设为 false 时需手动调用 mount() */\n mount?: boolean;\n /** 是否在 Agent 运行时自动显示操作遮罩(默认 true) */\n enableMask?: boolean;\n /** 面板默认展开状态(默认 false,即收起状态,只显示 FAB) */\n expanded?: boolean;\n /** 面板标题(默认 \"AutoPilot\") */\n title?: string;\n /** 输入框占位文本 */\n placeholder?: string;\n /** 遮罩提示文本 */\n maskText?: string;\n /** 空状态提示文本 */\n emptyText?: string;\n};\n\n/** 消息类型 */\ntype MessageType = \"user\" | \"assistant\" | \"tool\" | \"error\";\n\n/** 面板状态 */\ntype PanelStatus = \"idle\" | \"running\" | \"error\";\n\n/**\n * AutoPilot UI 面板。\n *\n * 使用方式:\n * ```ts\n * // 默认自动挂载\n * const panel = new Panel({ enableMask: true });\n * panel.onSend = async (text) => { await agent.chat(text); };\n *\n * // 延迟挂载\n * const panel = new Panel({ mount: false });\n * panel.mount(); // 手动挂载\n * ```\n */\nexport default class Panel {\n private container: HTMLElement;\n private enableMask: boolean;\n private title: string;\n private placeholder: string;\n private maskText: string;\n private emptyText: string;\n\n // ─── DOM 引用 ───\n private root: HTMLDivElement | null = null;\n private fab: HTMLButtonElement | null = null;\n private mask: HTMLDivElement | null = null;\n private panelEl: HTMLDivElement | null = null;\n private messagesEl: HTMLDivElement | null = null;\n private inputEl: HTMLTextAreaElement | null = null;\n private sendBtn: HTMLButtonElement | null = null;\n private statusDot: HTMLDivElement | null = null;\n private statusText: HTMLSpanElement | null = null;\n private stopBtnContainer: HTMLDivElement | null = null;\n private styleEl: HTMLStyleElement | null = null;\n\n // ─── FAB 拖拽状态 ───\n private fabDragging = false;\n private fabHasMoved = false;\n\n private mounted = false;\n private expanded: boolean;\n private status: PanelStatus = \"idle\";\n\n /** 用户发送消息回调 — 由 WebAgent 绑定 */\n onSend: ((text: string) => Promise<void>) | null = null;\n /** 用户点击停止按钮回调 */\n onStop: (() => void) | null = null;\n\n constructor(options: PanelOptions = {}) {\n this.container = options.container ?? document.body;\n this.enableMask = options.enableMask ?? true;\n this.expanded = options.expanded ?? false;\n this.title = options.title ?? \"AutoPilot\";\n this.placeholder = options.placeholder ?? \"输入要执行的网页操作...\";\n this.maskText = options.maskText ?? \"AutoPilot 正在操作页面\";\n this.emptyText = options.emptyText ?? \"发送一条消息,AI 将帮你操作页面\";\n\n // 默认自动挂载,传 mount: false 时需手动调用 mount()\n if (options.mount !== false) {\n this.mount();\n }\n }\n\n // ─── 公共 API ───\n\n /** 挂载面板到 DOM(全局单例:先清理残留再创建,防止 HMR/多实例\"分身\") */\n mount(): void {\n if (this.mounted) return;\n // 清理 DOM 中可能残留的旧实例(HMR 热更新、重复 new Panel())\n this.cleanupStale();\n this.injectStyles();\n this.createDOM();\n this.bindEvents();\n this.mounted = true;\n // 根据初始状态显示\n if (this.expanded) {\n this.show();\n }\n }\n\n /** 卸载面板 */\n unmount(): void {\n if (!this.mounted) return;\n this.root?.remove();\n this.styleEl?.remove();\n this.root = null;\n this.fab = null;\n this.mask = null;\n this.panelEl = null;\n this.messagesEl = null;\n this.inputEl = null;\n this.sendBtn = null;\n this.statusDot = null;\n this.statusText = null;\n this.stopBtnContainer = null;\n this.styleEl = null;\n this.mounted = false;\n }\n\n /** 展开面板(tooltip 风格定位到 FAB 旁边,FAB 保持可见) */\n show(): void {\n if (!this.mounted) this.mount();\n this.expanded = true;\n this.fab?.classList.add(\"active\");\n // 先定位再显示,避免初始位置闪烁\n this.updatePanelPosition();\n this.panelEl?.classList.remove(\"collapsed\");\n this.inputEl?.focus();\n }\n\n /** 收起面板 */\n hide(): void {\n this.expanded = false;\n this.panelEl?.classList.add(\"collapsed\");\n this.fab?.classList.remove(\"active\");\n }\n\n /** 切换展开/收起 */\n toggle(): void {\n if (this.expanded) this.hide();\n else this.show();\n }\n\n /** 是否已展开 */\n isExpanded(): boolean {\n return this.expanded;\n }\n\n /** 是否已挂载 */\n isMounted(): boolean {\n return this.mounted;\n }\n\n /** 添加消息到面板 */\n addMessage(type: MessageType, text: string): void {\n if (!this.messagesEl) return;\n // 移除空状态\n const empty = this.messagesEl.querySelector(\".ap-empty\");\n if (empty) empty.remove();\n // 移除 typing 指示器\n this.removeTyping();\n\n const msg = document.createElement(\"div\");\n msg.className = `ap-msg ${type}`;\n msg.textContent = text;\n this.messagesEl.appendChild(msg);\n this.scrollToBottom();\n }\n\n /** 清空所有消息 */\n clearMessages(): void {\n if (!this.messagesEl) return;\n this.messagesEl.innerHTML = \"\";\n this.showEmpty();\n }\n\n /** 设置面板状态 */\n setStatus(status: PanelStatus, text?: string): void {\n this.status = status;\n if (this.statusDot) {\n this.statusDot.className = `ap-status-dot ${status}`;\n }\n if (this.statusText) {\n const defaultTexts: Record<PanelStatus, string> = {\n idle: \"就绪\",\n running: \"执行中...\",\n error: \"出错\",\n };\n this.statusText.textContent = text ?? defaultTexts[status];\n }\n // 控制输入区 & 停止按钮\n this.updateInputState();\n // 控制遮罩\n if (this.enableMask) {\n if (status === \"running\") {\n this.showMask();\n } else {\n this.hideMask();\n }\n }\n }\n\n /** 显示操作遮罩 */\n showMask(): void {\n this.mask?.classList.add(\"active\");\n }\n\n /** 隐藏操作遮罩 */\n hideMask(): void {\n this.mask?.classList.remove(\"active\");\n }\n\n /** 显示 typing 指示器 */\n showTyping(): void {\n if (!this.messagesEl) return;\n this.removeTyping();\n const typing = document.createElement(\"div\");\n typing.className = \"ap-typing\";\n typing.innerHTML = `\n <div class=\"ap-typing-dot\"></div>\n <div class=\"ap-typing-dot\"></div>\n <div class=\"ap-typing-dot\"></div>\n `;\n this.messagesEl.appendChild(typing);\n this.scrollToBottom();\n }\n\n /** 移除 typing 指示器 */\n removeTyping(): void {\n const typing = this.messagesEl?.querySelector(\".ap-typing\");\n if (typing) typing.remove();\n }\n\n // ─── 内部方法 ───\n\n /**\n * 清理 DOM 中残留的旧 Panel 元素。\n * 防止 HMR 热更新或多次 new Panel() 导致多个 FAB/面板\"分身\"。\n */\n private cleanupStale(): void {\n // 清除所有旧的 autopilot root 容器(含 FAB + 面板 + 遮罩)\n document.querySelectorAll(\"[data-autopilot-ignore]\").forEach((el) => {\n // 只清理顶层 root(不清理 root 内部的子元素)\n if (el.parentElement === this.container || el.parentElement === document.body) {\n el.remove();\n }\n });\n // 清除残留样式\n document.querySelectorAll(\"style[data-autopilot-panel]\").forEach((el) => el.remove());\n }\n\n private injectStyles(): void {\n this.styleEl = document.createElement(\"style\");\n this.styleEl.setAttribute(\"data-autopilot-panel\", \"\");\n this.styleEl.textContent = PANEL_STYLES;\n document.head.appendChild(this.styleEl);\n }\n\n private createDOM(): void {\n this.root = document.createElement(\"div\");\n this.root.setAttribute(\"data-autopilot-ignore\", \"\");\n\n // ─── 操作遮罩 ───\n this.mask = document.createElement(\"div\");\n this.mask.id = \"autopilot-mask\";\n this.mask.innerHTML = `\n <div class=\"ap-mask-label\">\n <div class=\"ap-mask-spinner\"></div>\n <span>${this.escapeHtml(this.maskText)}</span>\n </div>\n `;\n this.root.appendChild(this.mask);\n\n // ─── FAB 按钮 ───\n this.fab = document.createElement(\"button\");\n this.fab.id = \"autopilot-fab\";\n this.fab.setAttribute(\"data-autopilot-ignore\", \"\");\n this.fab.innerHTML = ICONS.logo;\n this.fab.title = this.title;\n if (this.expanded) this.fab.classList.add(\"active\");\n this.root.appendChild(this.fab);\n\n // ─── 面板 ───\n this.panelEl = document.createElement(\"div\");\n this.panelEl.id = \"autopilot-panel\";\n this.panelEl.setAttribute(\"data-autopilot-ignore\", \"\");\n if (!this.expanded) this.panelEl.classList.add(\"collapsed\");\n\n this.panelEl.innerHTML = `\n <div class=\"ap-header\">\n <div class=\"ap-header-left\">\n <div class=\"ap-header-logo\">${ICONS.logo}</div>\n <span class=\"ap-header-title\">${this.escapeHtml(this.title)}</span>\n </div>\n <div class=\"ap-header-actions\">\n <button class=\"ap-header-btn\" data-action=\"clear\" title=\"清空消息\">${ICONS.trash}</button>\n <button class=\"ap-header-btn\" data-action=\"minimize\" title=\"收起面板\">${ICONS.minimize}</button>\n </div>\n </div>\n <div class=\"ap-status\">\n <div class=\"ap-status-dot idle\"></div>\n <span class=\"ap-status-text\">就绪</span>\n </div>\n <div class=\"ap-messages\">\n <div class=\"ap-empty\">\n <div class=\"ap-empty-icon\">${ICONS.logo}</div>\n <div class=\"ap-empty-text\">${this.escapeHtml(this.emptyText)}</div>\n </div>\n </div>\n <div class=\"ap-stop-container\" style=\"display:none\">\n <button class=\"ap-stop-btn\">${ICONS.stop}<span>停止执行</span></button>\n </div>\n <div class=\"ap-input-area\">\n <div class=\"ap-input-wrapper\">\n <textarea class=\"ap-input\" rows=\"1\" placeholder=\"${this.escapeHtml(this.placeholder)}\"></textarea>\n </div>\n <button class=\"ap-send-btn\" title=\"发送\">${ICONS.send}</button>\n </div>\n `;\n\n this.root.appendChild(this.panelEl);\n\n // 缓存 DOM 引用\n this.messagesEl = this.panelEl.querySelector(\".ap-messages\");\n this.inputEl = this.panelEl.querySelector(\".ap-input\");\n this.sendBtn = this.panelEl.querySelector(\".ap-send-btn\");\n this.statusDot = this.panelEl.querySelector(\".ap-status-dot\");\n this.statusText = this.panelEl.querySelector(\".ap-status-text\");\n this.stopBtnContainer = this.panelEl.querySelector(\".ap-stop-container\");\n\n // 挂载到容器\n this.container.appendChild(this.root);\n }\n\n private bindEvents(): void {\n // FAB 点击 → 切换面板(拖拽过的不触发)\n this.fab?.addEventListener(\"click\", () => {\n if (this.fabHasMoved) {\n this.fabHasMoved = false;\n return;\n }\n this.toggle();\n });\n\n // 头部按钮\n this.panelEl?.addEventListener(\"click\", (e) => {\n const target = (e.target as HTMLElement).closest(\"[data-action]\");\n if (!target) return;\n const action = target.getAttribute(\"data-action\");\n if (action === \"minimize\") this.hide();\n if (action === \"clear\") this.clearMessages();\n });\n\n // 发送按钮\n this.sendBtn?.addEventListener(\"click\", () => this.handleSend());\n\n // 输入框回车发送(Shift+Enter 换行)\n this.inputEl?.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n this.handleSend();\n }\n });\n\n // 输入框自动调整高度\n this.inputEl?.addEventListener(\"input\", () => {\n if (!this.inputEl) return;\n this.inputEl.style.height = \"auto\";\n this.inputEl.style.height = Math.min(this.inputEl.scrollHeight, 120) + \"px\";\n });\n\n // 停止按钮\n this.stopBtnContainer?.addEventListener(\"click\", () => {\n this.onStop?.();\n });\n\n // ─── 拖拽绑定 ───\n this.initFabDrag();\n }\n\n /**\n * 使用 @floating-ui/dom 计算面板相对于 FAB 的 tooltip 位置。\n * 根据 FAB 贴边方向自动翻转,并设置对应的 transform-origin 确保动画自然。\n */\n private updatePanelPosition(): void {\n if (!this.fab || !this.panelEl || !this.expanded) return;\n computePosition(this.fab, this.panelEl, {\n placement: \"top-end\",\n middleware: [\n offset(8),\n flip({ fallbackPlacements: [\"top-start\", \"bottom-end\", \"bottom-start\", \"left\", \"right\"] }),\n shift({ padding: 12 }),\n ],\n }).then(({ x, y, placement }) => {\n if (!this.panelEl) return;\n // 根据实际弹出方向设置 transform-origin,保证 tooltip 展开/收起动画自然\n const origins: Record<string, string> = {\n \"top-end\": \"bottom right\",\n \"top-start\": \"bottom left\",\n \"bottom-end\": \"top right\",\n \"bottom-start\": \"top left\",\n left: \"center right\",\n right: \"center left\",\n };\n Object.assign(this.panelEl.style, {\n left: `${x}px`,\n top: `${y}px`,\n right: \"auto\",\n bottom: \"auto\",\n transformOrigin: origins[placement] ?? \"bottom right\",\n });\n });\n }\n\n /**\n * 初始化 FAB 按钮拖拽:长按 300ms 后进入拖拽模式,松手后自动贴边。\n * 短按(未触发长按)或移动距离不超过阈值的走正常 click toggle 逻辑。\n */\n private initFabDrag(): void {\n if (!this.fab) return;\n const fab = this.fab;\n const LONG_PRESS_MS = 300;\n let startX = 0;\n let startY = 0;\n let fabStartX = 0;\n let fabStartY = 0;\n let moved = false;\n let longPressTimer: ReturnType<typeof setTimeout> | null = null;\n let dragActivated = false;\n let pointerId = -1;\n\n const onDown = (e: PointerEvent) => {\n moved = false;\n dragActivated = false;\n startX = e.clientX;\n startY = e.clientY;\n pointerId = e.pointerId;\n const rect = fab.getBoundingClientRect();\n fabStartX = rect.left;\n fabStartY = rect.top;\n\n // 长按计时器\n longPressTimer = setTimeout(() => {\n dragActivated = true;\n this.fabDragging = true;\n fab.setPointerCapture(pointerId);\n fab.style.transition = \"none\";\n fab.classList.add(\"dragging\");\n }, LONG_PRESS_MS);\n\n e.preventDefault();\n };\n\n const onMove = (e: PointerEvent) => {\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n\n // 如果还没激活拖拽,移动超过 4px 则取消长按(算作普通滑动)\n if (!dragActivated) {\n if (Math.abs(dx) > 4 || Math.abs(dy) > 4) {\n if (longPressTimer) { clearTimeout(longPressTimer); longPressTimer = null; }\n }\n return;\n }\n\n if (!moved && Math.abs(dx) < 4 && Math.abs(dy) < 4) return;\n moved = true;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const fw = fab.offsetWidth;\n const fh = fab.offsetHeight;\n const newLeft = Math.max(0, Math.min(vw - fw, fabStartX + dx));\n const newTop = Math.max(0, Math.min(vh - fh, fabStartY + dy));\n fab.style.left = newLeft + \"px\";\n fab.style.top = newTop + \"px\";\n fab.style.right = \"auto\";\n fab.style.bottom = \"auto\";\n\n // 拖拽过程中实时更新 tooltip 面板位置\n if (this.expanded) this.updatePanelPosition();\n };\n\n const onUp = () => {\n if (longPressTimer) { clearTimeout(longPressTimer); longPressTimer = null; }\n if (!dragActivated) {\n // 短按 → 不拦截,让 click 正常触发 toggle\n return;\n }\n this.fabDragging = false;\n this.fabHasMoved = dragActivated; // 拦截后续 click\n dragActivated = false;\n fab.classList.remove(\"dragging\");\n if (moved) {\n this.snapFabToEdge();\n }\n };\n\n fab.addEventListener(\"pointerdown\", onDown);\n fab.addEventListener(\"pointermove\", onMove);\n fab.addEventListener(\"pointerup\", onUp);\n fab.addEventListener(\"pointercancel\", onUp);\n }\n\n /**\n * FAB 吸附到最近屏幕边缘(左/右贴边,上下保持位置)。\n */\n private snapFabToEdge(): void {\n if (!this.fab) return;\n const rect = this.fab.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const fw = this.fab.offsetWidth;\n const fh = this.fab.offsetHeight;\n const gap = 12;\n const centerX = rect.left + fw / 2;\n const snapLeft = centerX < vw / 2;\n const targetX = snapLeft ? gap : vw - fw - gap;\n const targetY = Math.max(gap, Math.min(vh - fh - gap, rect.top));\n\n this.fab.style.transition = \"left 0.3s cubic-bezier(0.22, 1, 0.36, 1), top 0.3s cubic-bezier(0.22, 1, 0.36, 1)\";\n this.fab.style.left = targetX + \"px\";\n this.fab.style.top = targetY + \"px\";\n this.fab.style.right = \"auto\";\n this.fab.style.bottom = \"auto\";\n\n const cleanup = () => {\n if (this.fab) this.fab.style.transition = \"\";\n // 贴边后更新 tooltip 面板位置\n if (this.expanded) this.updatePanelPosition();\n };\n this.fab.addEventListener(\"transitionend\", cleanup, { once: true });\n setTimeout(cleanup, 350);\n }\n\n private handleSend(): void {\n if (!this.inputEl || this.status === \"running\") return;\n const text = this.inputEl.value.trim();\n if (!text) return;\n\n this.inputEl.value = \"\";\n this.inputEl.style.height = \"auto\";\n this.addMessage(\"user\", text);\n\n if (this.onSend) {\n this.onSend(text).catch((err) => {\n this.addMessage(\"error\", `执行失败: ${err instanceof Error ? err.message : String(err)}`);\n this.setStatus(\"error\");\n });\n }\n }\n\n private updateInputState(): void {\n const isRunning = this.status === \"running\";\n if (this.inputEl) {\n this.inputEl.disabled = isRunning;\n }\n if (this.sendBtn) {\n this.sendBtn.disabled = isRunning;\n }\n if (this.stopBtnContainer) {\n this.stopBtnContainer.style.display = isRunning ? \"block\" : \"none\";\n }\n }\n\n private showEmpty(): void {\n if (!this.messagesEl) return;\n this.messagesEl.innerHTML = `\n <div class=\"ap-empty\">\n <div class=\"ap-empty-icon\">${ICONS.logo}</div>\n <div class=\"ap-empty-text\">${this.escapeHtml(this.emptyText)}</div>\n </div>\n `;\n }\n\n private scrollToBottom(): void {\n if (!this.messagesEl) return;\n requestAnimationFrame(() => {\n this.messagesEl!.scrollTop = this.messagesEl!.scrollHeight;\n });\n }\n\n private escapeHtml(str: string): string {\n const div = document.createElement(\"div\");\n div.textContent = str;\n return div.innerHTML;\n }\n}\n","/**\n * Web Tools 消息通信桥接层。\n *\n * 解决 Chrome Extension 的作用域隔离问题:\n *\n * Service Worker (后台) Content Script (页面)\n * ┌──────────────────┐ ┌──────────────────────┐\n * │ agent-core │ │ document / window │\n * │ tool-registry │ chrome.tabs │ │\n * │ │ .sendMessage() │ DOM 操作实际执行 │\n * │ tool.execute() │ ─────────────────► │ handleToolMessage() │\n * │ ↓ │ │ ↓ │\n * │ sendToContent() │ ◄───────────────── │ 返回执行结果 │\n * └──────────────────┘ response └──────────────────────┘\n *\n * 使用方式:\n * Service Worker 端:\n * import { createProxyExecutor } from \"./messaging.js\";\n * const execute = createProxyExecutor();\n * // execute 会把调用转发到 content script\n *\n * Content Script 端:\n * import { registerToolHandler } from \"./messaging.js\";\n * registerToolHandler(actualExecutors);\n * // 监听来自 service worker 的工具调用请求\n */\n\n// ─── 消息类型定义 ───\n\n/** Service Worker → Content Script 的工具调用请求 */\nexport type ToolCallMessage = {\n type: \"AUTOPILOT_TOOL_CALL\";\n toolName: string;\n params: Record<string, unknown>;\n callId: string;\n};\n\n/** Content Script → Service Worker 的工具调用结果 */\nexport type ToolCallResponse = {\n type: \"AUTOPILOT_TOOL_RESULT\";\n callId: string;\n result: {\n content: string | Record<string, unknown>;\n details?: Record<string, unknown>;\n };\n};\n\n// ─── Service Worker 端(发送方) ───\n\n/**\n * 创建代理执行器 — 在 Service Worker 端使用。\n *\n * 它不直接执行 DOM 操作,而是通过 chrome.tabs.sendMessage\n * 把调用请求发给当前活动 tab 的 content script 执行。\n *\n * @returns execute 函数,签名与 ToolDefinition.execute 相同\n */\nexport function createProxyExecutor() {\n return async (\n toolName: string,\n params: Record<string, unknown>,\n ): Promise<{ content: string | Record<string, unknown>; details?: Record<string, unknown> }> => {\n const callId = `${toolName}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n // 获取当前活动 tab\n const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });\n if (!tab?.id) {\n return { content: \"错误:没有活动的浏览器标签页\" };\n }\n\n // 发送消息到 content script 并等待结果\n const message: ToolCallMessage = {\n type: \"AUTOPILOT_TOOL_CALL\",\n toolName,\n params,\n callId,\n };\n\n try {\n const response = await chrome.tabs.sendMessage(tab.id, message) as ToolCallResponse;\n return response.result;\n } catch (err) {\n return {\n content: `工具调用失败(content script 可能未加载): ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, toolName },\n };\n }\n };\n}\n\n// ─── Content Script 端(接收方) ───\n\n/** 工具执行器映射:toolName → execute 函数 */\nexport type ToolExecutorMap = Map<\n string,\n (params: Record<string, unknown>) => Promise<{\n content: string | Record<string, unknown>;\n details?: Record<string, unknown>;\n }>\n>;\n\n/**\n * 在 Content Script 端注册工具执行处理器。\n *\n * 监听来自 Service Worker 的 AUTOPILOT_TOOL_CALL 消息,\n * 根据 toolName 找到对应的执行函数,执行后返回结果。\n *\n * @param executors 工具名称 → 执行函数的映射\n */\nexport function registerToolHandler(executors: ToolExecutorMap): void {\n chrome.runtime.onMessage.addListener(\n (message: unknown, _sender: chrome.runtime.MessageSender, sendResponse: (response: ToolCallResponse) => void) => {\n // 只处理我们的消息类型\n const msg = message as ToolCallMessage;\n if (msg?.type !== \"AUTOPILOT_TOOL_CALL\") return false;\n\n const executor = executors.get(msg.toolName);\n if (!executor) {\n sendResponse({\n type: \"AUTOPILOT_TOOL_RESULT\",\n callId: msg.callId,\n result: { content: `未知工具: ${msg.toolName}` },\n });\n return true; // 同步返回 true 表示我们会异步 sendResponse\n }\n\n // 异步执行工具并返回结果\n executor(msg.params)\n .then((result) => {\n sendResponse({\n type: \"AUTOPILOT_TOOL_RESULT\",\n callId: msg.callId,\n result,\n });\n })\n .catch((err) => {\n sendResponse({\n type: \"AUTOPILOT_TOOL_RESULT\",\n callId: msg.callId,\n result: {\n content: `工具 ${msg.toolName} 执行异常: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true },\n },\n });\n });\n\n return true; // 告诉 Chrome 我们会异步调用 sendResponse\n },\n );\n}\n","/**\n * WebAgent — 浏览器端 AI Agent 类。\n *\n * 封装了完整的 Agent 能力,可在浏览器中独立运行:\n * - 对话(chat) → 发消息、获取 AI 回复\n * - 工具注册 → 注册内置 Web 工具或自定义工具\n * - 决策循环 → 复用 core/agent-loop.ts 的通用逻辑\n * - AI 连接 → 复用 core/ai-client.ts(基于 fetch,跨平台)\n *\n * 使用示例:\n * ```ts\n * const agent = new WebAgent({ token: \"ghp_xxx\", provider: \"copilot\" });\n * agent.registerTools(); // 注册内置 Web 工具\n * agent.callbacks.onText = (text) => console.log(text);\n *\n * const result = await agent.chat(\"获取页面标题\");\n * console.log(result.reply);\n * ```\n *\n * 架构位置:\n * ┌──────────────────────────────────────────────────┐\n * │ WebAgent(浏览器端入口) │\n * │ ┌──────────┐ ┌────────────┐ ┌──────────────┐ │\n * │ │ core/ │ │ core/ │ │ web/ │ │\n * │ │ ai-client│ │ agent-loop │ │ (DOM/导航等)│ │\n * │ │ (fetch) │ │ (通用循环) │ │ │ │\n * │ └──────────┘ └────────────┘ └──────────────┘ │\n * └──────────────────────────────────────────────────┘\n */\nimport {\n executeAgentLoop,\n type AgentLoopCallbacks,\n type AgentLoopResult,\n type RoundStabilityWaitOptions,\n} from \"../core/agent-loop/index.js\";\nimport type { AIMessage } from \"../core/types.js\";\nimport { createAIClient } from \"../core/ai-client/index.js\";\nimport type { AIClient } from \"../core/types.js\";\nimport { ToolRegistry, type ToolDefinition, type ToolCallResult } from \"../core/tool-registry.js\";\nimport { buildSystemPrompt } from \"../core/system-prompt.js\";\nimport { generateSnapshot, type SnapshotOptions } from \"./tools/page-info-tool.js\";\nimport { createDomTool, setActiveRefStore } from \"./tools/dom-tool.js\";\nimport { createNavigateTool } from \"./tools/navigate-tool.js\";\nimport { createPageInfoTool } from \"./tools/page-info-tool.js\";\nimport { createWaitTool } from \"./tools/wait-tool.js\";\nimport { createEvaluateTool } from \"./tools/evaluate-tool.js\";\nimport { RefStore } from \"./ref-store.js\";\nimport { installEventListenerTracking } from \"./event-listener-tracker.js\";\nimport Panel, { type PanelOptions } from \"./ui/index.js\";\n\n// 默认安装全局事件监听追踪(幂等),用于快照输出 listeners 信号。\ninstallEventListenerTracking();\n\n// ─── 回调类型 ───\n\n/** WebAgent 事件回调(扩展 AgentLoopCallbacks,增加快照事件) */\nexport type WebAgentCallbacks = AgentLoopCallbacks & {\n /** 自动快照生成完成时触发 */\n onSnapshot?: (snapshot: string) => void;\n};\n\n// ─── 配置 ───\n\nexport type WebAgentOptions = {\n /**\n * 自定义 AI 客户端实例(可选)。\n *\n * 传入后将直接使用该实例进行对话,忽略 token / provider / model / baseURL。\n * 支持 BaseAIClient 或任何实现 AIClient 接口的对象。\n *\n * ```ts\n * const client = new BaseAIClient({ chatHandler: async (params) => { ... } });\n * const agent = new WebAgent({ client });\n * ```\n */\n client?: AIClient;\n /** API 认证 Token (GitHub PAT / OpenAI key / Anthropic key) */\n token?: string;\n /** AI 提供商: \"copilot\" | \"openai\" | \"anthropic\" | \"deepseek\" | \"doubao\" | \"qwen\"(默认 \"copilot\") */\n provider?: string;\n /** 模型名称(默认 \"gpt-4o\") */\n model?: string;\n /** 自定义 API 基础 URL(可选,覆盖 provider 默认值) */\n baseURL?: string;\n /** 是否启用流式输出(SSE)。默认 true;false 时使用 JSON 非流式响应。 */\n stream?: boolean;\n /** 单次 AI 请求超时(毫秒,默认 45000;<=0 表示不设置超时)。 */\n requestTimeoutMs?: number;\n /** 是否启用干运行模式 */\n dryRun?: boolean;\n /**\n * 系统提示词注册项。\n * - string:按默认 key 注册一条\n * - Record<string, string>:按 key 批量注册多条\n */\n systemPrompt?: string | Record<string, string>;\n /** 最大工具调用轮次(默认 10) */\n maxRounds?: number;\n /** 是否启用多轮对话记忆(默认 false) */\n memory?: boolean;\n /** 是否在每次对话前自动生成页面快照(默认 true) */\n autoSnapshot?: boolean;\n /** 快照选项(视口裁剪、智能剪枝等,autoSnapshot 开启时生效) */\n snapshotOptions?: SnapshotOptions;\n /** 轮次后稳定等待(加载态 + DOM 静默)配置 */\n roundStabilityWait?: RoundStabilityWaitOptions;\n /**\n * UI 面板配置。\n * - true:使用默认配置创建面板\n * - PanelOptions:使用自定义配置创建面板\n * - false / undefined:不创建面板\n */\n panel?: boolean | PanelOptions;\n};\n\n// ─── WebAgent 类 ───\n\nexport class WebAgent {\n /** 默认系统提示词 key(兼容旧版 setSystemPrompt(prompt))。 */\n private static readonly DEFAULT_SYSTEM_PROMPT_KEY = \"default\";\n /** 默认内置工具名(注册后受保护,不允许删除)。 */\n private static readonly DEFAULT_TOOL_NAMES = [\"dom\", \"navigate\", \"page_info\", \"wait\", \"evaluate\"] as const;\n\n /** 用户传入的自定义 AI 客户端实例(优先级高于 token/provider) */\n private client?: AIClient;\n private token: string;\n private provider: string;\n private model: string;\n private baseURL?: string;\n private stream: boolean;\n private requestTimeoutMs: number;\n private dryRun: boolean;\n private maxRounds: number;\n /** system prompt 注册表(key -> prompt 文本)。 */\n private systemPromptRegistry = new Map<string, string>();\n /** 受保护工具集合(默认工具)。 */\n private protectedToolNames = new Set<string>();\n\n /** 多轮对话记忆开关 */\n private memory: boolean;\n /** 对话历史(memory 开启时自动累积) */\n private history: AIMessage[] = [];\n /** 自动快照开关 */\n private autoSnapshot: boolean;\n /** 快照选项 */\n private snapshotOptions: SnapshotOptions;\n /** 轮次后稳定等待配置 */\n private roundStabilityWait?: RoundStabilityWaitOptions;\n\n /** 工具注册表实例 — 每个 WebAgent 拥有独立的工具集 */\n private registry = new ToolRegistry();\n\n /** 内置 UI 面板(通过 options.panel 配置启用) */\n panel: Panel | null = null;\n\n /** 事件回调 — 绑定后可实时获取 Agent 进度,用于 UI 展示 */\n callbacks: WebAgentCallbacks = {};\n\n constructor(options: WebAgentOptions) {\n this.client = options.client;\n this.token = options.token || \"\";\n this.provider = options.provider ?? \"copilot\";\n this.model = options.model ?? \"gpt-4o\";\n this.baseURL = options.baseURL;\n this.stream = options.stream ?? true;\n this.requestTimeoutMs = options.requestTimeoutMs ?? 45000;\n this.dryRun = options.dryRun ?? false;\n this.maxRounds = options.maxRounds ?? 40;\n this.memory = options.memory ?? false;\n this.autoSnapshot = options.autoSnapshot ?? true;\n this.snapshotOptions = options.snapshotOptions ?? {};\n this.roundStabilityWait = options.roundStabilityWait;\n\n if (typeof options.systemPrompt === \"string\") {\n this.setSystemPrompt(options.systemPrompt);\n } else if (options.systemPrompt && typeof options.systemPrompt === \"object\") {\n this.setSystemPrompts(options.systemPrompt);\n }\n\n // ─── UI 面板 ───\n if (options.panel) {\n const panelOpts = typeof options.panel === \"object\" ? options.panel : {};\n this.panel = new Panel(panelOpts);\n this.wirePanel();\n }\n }\n\n // ─── 工具管理 ───\n\n /** 注册所有内置 Web 工具(dom, navigate, page_info, wait, evaluate) */\n registerTools(): void {\n this.registry.register(createDomTool());\n this.registry.register(createNavigateTool());\n this.registry.register(createPageInfoTool());\n this.registry.register(createWaitTool());\n this.registry.register(createEvaluateTool());\n\n for (const name of WebAgent.DEFAULT_TOOL_NAMES) {\n this.protectedToolNames.add(name);\n }\n }\n\n /** 注册一个自定义工具 */\n registerTool(tool: ToolDefinition): void {\n this.registry.register(tool);\n }\n\n /**\n * 删除一个已注册工具。\n * - 默认内置工具(registerTools 注册)不允许删除\n * - 返回 true 表示删除成功,false 表示不存在或受保护\n */\n removeTool(name: string): boolean {\n if (this.protectedToolNames.has(name)) return false;\n return this.registry.unregister(name);\n }\n\n /** 检查工具是否已注册。 */\n hasTool(name: string): boolean {\n return this.registry.has(name);\n }\n\n /** 获取当前所有已注册工具名。 */\n getToolNames(): string[] {\n return this.registry.getDefinitions().map(tool => tool.name);\n }\n\n /**\n * 删除所有“非默认”工具。\n * 返回值为本次被删除的工具名数组。\n */\n clearCustomTools(): string[] {\n const removed: string[] = [];\n for (const tool of this.registry.getDefinitions()) {\n if (this.protectedToolNames.has(tool.name)) continue;\n if (this.registry.unregister(tool.name)) {\n removed.push(tool.name);\n }\n }\n return removed;\n }\n\n /** 获取所有已注册的工具定义列表 */\n getTools(): ToolDefinition[] {\n return this.registry.getDefinitions();\n }\n\n // ─── 配置修改 ───\n\n /** 设置 API Token */\n setToken(token: string): void {\n this.token = token;\n }\n\n /**\n * 设置自定义 AI 客户端实例。\n *\n * 传入后将优先使用该实例进行对话,忽略 token / provider / model / baseURL。\n * 传入 undefined 可恢复使用内置客户端。\n */\n setClient(client: AIClient | undefined): void {\n this.client = client;\n }\n\n /** 设置 AI 提供商 */\n setProvider(provider: string): void {\n this.provider = provider;\n }\n\n /** 设置模型 */\n setModel(model: string): void {\n this.model = model;\n }\n\n /** 设置是否启用流式输出(SSE) */\n setStream(enabled: boolean): void {\n this.stream = enabled;\n }\n\n /** 获取当前流式输出开关状态 */\n getStream(): boolean {\n return this.stream;\n }\n\n /** 设置单次 AI 请求超时(毫秒) */\n setRequestTimeoutMs(timeoutMs: number): void {\n this.requestTimeoutMs = Math.floor(timeoutMs);\n }\n\n /** 获取当前 AI 请求超时(毫秒) */\n getRequestTimeoutMs(): number {\n return this.requestTimeoutMs;\n }\n\n /** 切换干运行模式 */\n setDryRun(enabled: boolean): void {\n this.dryRun = enabled;\n }\n\n /**\n * 注册系统提示词。\n * - setSystemPrompt(prompt):使用默认 key 注册\n * - setSystemPrompt(key, prompt):按指定 key 注册\n */\n setSystemPrompt(prompt: string): void;\n setSystemPrompt(key: string, prompt: string): void;\n setSystemPrompt(keyOrPrompt: string, maybePrompt?: string): void {\n const key = maybePrompt === undefined\n ? WebAgent.DEFAULT_SYSTEM_PROMPT_KEY\n : keyOrPrompt.trim();\n const prompt = maybePrompt === undefined ? keyOrPrompt : maybePrompt;\n\n if (!key) throw new Error(\"system prompt 的 key 不能为空\");\n const value = prompt.trim();\n if (!value) throw new Error(\"system prompt 不能为空\");\n\n this.systemPromptRegistry.set(key, value);\n }\n\n /** 批量注册系统提示词(key -> prompt)。 */\n setSystemPrompts(prompts: Record<string, string>): void {\n for (const [key, prompt] of Object.entries(prompts)) {\n this.setSystemPrompt(key, prompt);\n }\n }\n\n /** 注销指定 key 的系统提示词。 */\n removeSystemPrompt(key: string): boolean {\n return this.systemPromptRegistry.delete(key);\n }\n\n /** 只保留指定 key 的系统提示词,其余全部删除。 */\n keepOnlySystemPrompt(key: string): boolean {\n if (!this.systemPromptRegistry.has(key)) return false;\n const value = this.systemPromptRegistry.get(key)!;\n this.systemPromptRegistry.clear();\n this.systemPromptRegistry.set(key, value);\n return true;\n }\n\n /** 获取当前已注册的全部系统提示词(浅拷贝)。 */\n getSystemPrompts(): Record<string, string> {\n return Object.fromEntries(this.systemPromptRegistry.entries());\n }\n\n /** 删除全部系统提示词。 */\n clearSystemPrompts(): void {\n this.systemPromptRegistry.clear();\n }\n\n /** 开启或关闭多轮对话记忆 */\n setMemory(enabled: boolean): void {\n this.memory = enabled;\n if (!enabled) this.history = [];\n }\n\n /** 获取当前记忆开关状态 */\n getMemory(): boolean {\n return this.memory;\n }\n\n /** 开启或关闭自动快照 */\n setAutoSnapshot(enabled: boolean): void {\n this.autoSnapshot = enabled;\n }\n\n /** 获取当前自动快照开关状态 */\n getAutoSnapshot(): boolean {\n return this.autoSnapshot;\n }\n\n /** 设置快照选项(视口裁剪、智能剪枝等) */\n setSnapshotOptions(options: SnapshotOptions): void {\n this.snapshotOptions = options;\n }\n\n /** 获取当前快照选项 */\n getSnapshotOptions(): SnapshotOptions {\n return { ...this.snapshotOptions };\n }\n\n /** 清空对话历史(不影响记忆开关) */\n clearHistory(): void {\n this.history = [];\n }\n\n // ─── UI 面板 ───\n\n /**\n * 手动创建并挂载 UI 面板(构造时未传 panel 选项时可后续调用)。\n * 若面板已存在则跳过。\n */\n createPanel(options: PanelOptions = {}): Panel {\n if (this.panel) return this.panel;\n this.panel = new Panel(options);\n this.wirePanel();\n return this.panel;\n }\n\n /**\n * 销毁 UI 面板。\n */\n destroyPanel(): void {\n if (!this.panel) return;\n this.panel.unmount();\n this.panel = null;\n }\n\n /**\n * 建立面板到 WebAgent 的双向绑定。\n *\n * - panel.onSend → agent.chat()\n * - agent.callbacks → panel 消息流 & 状态\n */\n private wirePanel(): void {\n if (!this.panel) return;\n const panel = this.panel;\n\n // 用户消息 → agent.chat\n panel.onSend = async (text: string) => {\n panel.setStatus(\"running\");\n panel.showTyping();\n try {\n const result = await this.chat(text);\n panel.removeTyping();\n if (result.reply) {\n panel.addMessage(\"assistant\", result.reply);\n }\n panel.setStatus(\"idle\");\n } catch (err) {\n panel.removeTyping();\n panel.addMessage(\"error\", `执行失败: ${err instanceof Error ? err.message : String(err)}`);\n panel.setStatus(\"error\");\n }\n };\n\n // 包裹 callbacks:转发到面板\n const originalOnText = this.callbacks.onText;\n const originalOnToolCall = this.callbacks.onToolCall;\n const originalOnToolResult = this.callbacks.onToolResult;\n\n this.callbacks.onText = (text: string) => {\n originalOnText?.(text);\n // 实时文本由 wirePanel.onSend 的 result.reply 处理,此处不重复添加\n };\n\n this.callbacks.onToolCall = (name: string, input: unknown) => {\n originalOnToolCall?.(name, input);\n const inputStr = typeof input === \"string\" ? input : JSON.stringify(input, null, 0);\n const summary = inputStr.length > 80 ? inputStr.slice(0, 80) + \"…\" : inputStr;\n panel.addMessage(\"tool\", `🔧 ${name}(${summary})`);\n };\n\n this.callbacks.onToolResult = (name: string, result: ToolCallResult) => {\n originalOnToolResult?.(name, result);\n const resultStr = typeof result.content === \"string\" ? result.content : JSON.stringify(result.content, null, 0);\n const summary = resultStr.length > 100 ? resultStr.slice(0, 100) + \"…\" : resultStr;\n panel.addMessage(\"tool\", `✅ ${name} → ${summary}`);\n };\n }\n\n // ─── 核心能力 ───\n\n /**\n * 发送消息并获取 AI 回复(含完整工具调用循环)。\n *\n * 内部流程(全部复用 core):\n * 1. createAIClient() → 创建 fetch AI 客户端\n * 2. buildSystemPrompt() → 构建系统提示词\n * 3. executeAgentLoop() → 执行决策循环\n * 4. callbacks → 实时通知 UI\n */\n async chat(message: string): Promise<AgentLoopResult> {\n // 优先使用自定义 client,否则使用内置 createAIClient\n const client = this.client ?? this.createBuiltinClient();\n\n // 先构建基础系统提示词,再追加已注册的 system prompt 扩展。\n let systemPrompt = buildSystemPrompt({\n listenerEvents: this.snapshotOptions.listenerEvents,\n });\n if (this.systemPromptRegistry.size > 0) {\n const extensionText = Array.from(this.systemPromptRegistry.entries())\n .map(([key, prompt]) => `- [${key}]\\n${prompt}`)\n .join(\"\\n\\n\");\n systemPrompt += `\\n\\n## Registered System Prompt Extensions\\n${extensionText}`;\n }\n\n // ─── 自动快照:注入 system prompt,不污染对话历史 ───\n // 创建本次对话的 RefStore,快照结束后保持活跃,对话结束后清空\n const refStore = new RefStore(globalThis.location?.href);\n setActiveRefStore(refStore);\n let initialSnapshot: string | undefined;\n\n try {\n const snapshot = generateSnapshot(document.body, {\n maxDepth: 12,\n viewportOnly: false,\n maxNodes: 500,\n maxChildren: 30,\n ...this.snapshotOptions,\n refStore,\n });\n initialSnapshot = snapshot;\n if (this.autoSnapshot) {\n this.callbacks.onSnapshot?.(snapshot);\n }\n } catch {\n // 快照失败不阻塞正常流程\n }\n\n // 包装回调:在恢复快照前重置 RefStore,确保新快照的 hash ID 有效\n const wrappedCallbacks: WebAgentCallbacks = {\n ...this.callbacks,\n onBeforeRecoverySnapshot: (newUrl?: string) => {\n // URL 变化 → 清空映射 + 更新 URL 命名空间\n // 元素定位失败 → 仅清空可能失效的映射(URL 不变)\n if (newUrl !== undefined) {\n refStore.reset(newUrl);\n } else {\n refStore.clear();\n }\n // 转发到用户回调(如有设置)\n this.callbacks.onBeforeRecoverySnapshot?.(newUrl);\n },\n };\n\n // 复用 core/agent-loop — 同一份决策循环\n const result = await executeAgentLoop({\n client,\n registry: this.registry,\n systemPrompt,\n message,\n initialSnapshot,\n history: this.memory ? this.history : undefined,\n dryRun: this.dryRun,\n maxRounds: this.maxRounds,\n roundStabilityWait: this.roundStabilityWait,\n callbacks: wrappedCallbacks,\n });\n\n // 记忆模式:累积对话历史供下次 chat() 使用\n if (this.memory) {\n this.history = result.messages;\n }\n\n // 对话结束,清空 RefStore\n refStore.clear();\n setActiveRefStore(undefined);\n\n return result;\n }\n\n // ─── 内部方法 ───\n\n /**\n * 创建内置 AI 客户端(基于 token / provider / model 配置)。\n *\n * @throws 未设置 token 时抛出 Error\n */\n private createBuiltinClient(): AIClient {\n if (!this.token) {\n throw new Error(\"未设置 Token,请先调用 setToken() 或传入自定义 client\");\n }\n return createAIClient({\n provider: this.provider,\n model: this.model,\n apiKey: this.token,\n baseURL: this.baseURL,\n stream: this.stream,\n requestTimeoutMs: this.requestTimeoutMs,\n });\n }\n}\n\n// ─── Re-exports ───\n// 从入口文件统一导出所有公共 API,消费方只需 import from \"agentpage\"\n\nexport {\n generateSnapshot,\n type SnapshotOptions,\n} from \"./tools/page-info-tool.js\";\nexport { createDomTool } from \"./tools/dom-tool.js\";\nexport { createNavigateTool } from \"./tools/navigate-tool.js\";\nexport { createPageInfoTool } from \"./tools/page-info-tool.js\";\nexport { createWaitTool } from \"./tools/wait-tool.js\";\nexport { createEvaluateTool } from \"./tools/evaluate-tool.js\";\nexport {\n createProxyExecutor,\n registerToolHandler,\n type ToolCallMessage,\n type ToolCallResponse,\n type ToolExecutorMap,\n} from \"./messaging.js\";\nexport { default as Panel, type PanelOptions } from \"./ui/index.js\";\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["sleep","sleep","sleep","convertMessages"],"sources":["../src/core/agent-loop/constants.ts","../src/core/agent-loop/helpers.ts","../src/core/agent-loop/snapshot.ts","../src/core/agent-loop/messages.ts","../src/core/agent-loop/recovery.ts","../src/core/agent-loop/index.ts","../src/core/ai-client/constants.ts","../src/core/ai-client/sse.ts","../src/core/ai-client/custom.ts","../src/core/ai-client/openai.ts","../src/core/ai-client/anthropic.ts","../src/core/ai-client/deepseek.ts","../src/core/ai-client/doubao.ts","../src/core/ai-client/qwen.ts","../src/core/ai-client/minimax.ts","../src/core/ai-client/index.ts","../src/core/tool-registry.ts","../src/core/system-prompt.ts","../src/web/event-listener-tracker.ts","../src/web/tools/dom-tool.ts","../src/web/tools/page-info-tool.ts","../src/web/tools/navigate-tool.ts","../src/web/tools/wait-tool.ts","../src/web/tools/evaluate-tool.ts","../src/web/ref-store.ts","../src/web/ui/styles.ts","../src/web/ui/logo-data.ts","../src/web/ui/icons.ts","../src/web/ui/panel.ts","../src/web/messaging.ts","../src/web/index.ts"],"sourcesContent":["/**\n * Agent Loop 默认配置常量。\n *\n * 统一集中在该文件,避免在主循环中散落“魔法数字”。\n */\nexport const DEFAULT_MAX_ROUNDS = 40;\nexport const DEFAULT_RECOVERY_WAIT_MS = 100;\nexport const DEFAULT_ACTION_RECOVERY_ROUNDS = 2;\nexport const DEFAULT_NOT_FOUND_RETRY_ROUNDS = 2;\nexport const DEFAULT_NOT_FOUND_RETRY_WAIT_MS = 1000;\nexport const DEFAULT_ROUND_STABILITY_WAIT_TIMEOUT_MS = 4000;\nexport const DEFAULT_ROUND_STABILITY_WAIT_QUIET_MS = 200;\nexport const DEFAULT_ROUND_STABILITY_WAIT_LOADING_SELECTORS = [\n\t\".ant-spin\",\n\t\".ant-spin-spinning\",\n\t\".ant-skeleton\",\n\t\".el-loading-mask\",\n\t\".bk-loading\",\n\t\".bk-spin-loading\",\n\t\".bk-skeleton\",\n\t\".bk-sideslider-loading\",\n\t\".t-loading\",\n\t\".t-skeleton\",\n\t\".t-skeleton__row\",\n\t\"[aria-busy=\\\"true\\\"]\",\n\t\".skeleton\",\n\t\".loading\",\n];\n// ─── DOM 快照去重标记 ───\n\n/** 快照起始标记 — 用于在消息中识别快照边界 */\nexport const SNAPSHOT_START = \"<!-- SNAPSHOT_START -->\";\n/** 快照结束标记 */\nexport const SNAPSHOT_END = \"<!-- SNAPSHOT_END -->\";\n/** 旧快照被替换后的占位文本 */\nexport const SNAPSHOT_OUTDATED = \"[此快照已过期,请参考对话中最新的快照]\";","/**\n * Agent Loop 辅助函数。\n *\n * 这个文件只放“纯函数”:\n * - 不访问外部可变状态\n * - 不做网络/DOM/I/O\n * - 输入相同,输出稳定\n *\n * 目的:把 index.ts 里的协议解析、文本规整、判定逻辑拆出来,\n * 让主循环只负责编排流程,方便阅读、测试和后续扩展。\n *\n * 函数能力速览:\n * - 基础工具:\n * - `sleep`:异步等待\n * - `toContentString`:统一工具结果内容为字符串\n * - 快照相关:\n * - `parseSnapshotExpandHints`:解析 `SNAPSHOT_HINT: EXPAND_CHILDREN`\n * - `extractHashSelectorRef`:从 `#ref` 选择器提取 ref id\n * - 任务推进与协议:\n * - `buildTaskArray`:将工具调用规整成稳定任务数组\n * - `normalizeModelOutput`:压缩模型输出供下一轮上下文使用\n * - `parseRemainingInstruction`:解析 `REMAINING` 协议\n * - `deriveNextInstruction`:推导下一轮 remaining(有协议优先)\n * - `reduceRemainingHeuristically`:协议缺失时做启发式推进\n * - 执行控制:\n * - `shouldForceRoundBreak`:判断动作后是否应断轮\n * - `collectMissingTask`:提取“元素未找到”任务用于重试流\n * - 错误与参数判定:\n * - `isElementNotFoundResult`:识别元素未找到错误\n * - `buildToolCallKey`:生成稳定调用键\n * - `resolveRecoveryWaitMs`:解析恢复等待时长\n * - `getToolAction`:读取工具输入里的 action\n * - `hasToolError`:判断结果是否标记为错误\n */\nimport type { ToolCallResult } from \"../tool-registry.js\";\nimport { DEFAULT_RECOVERY_WAIT_MS } from \"./constants.js\";\n\n/**\n * 异步睡眠。\n *\n * 用于重试等待、节流等待等场景。\n */\nexport function sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n}\n\n/**\n * 统一内容为字符串。\n *\n * 工具返回 content 可能是 string 或 object;这里统一转成 string,\n * 便于日志、错误判定、摘要拼接。\n */\nexport function toContentString(content: ToolCallResult[\"content\"]): string {\n return typeof content === \"string\" ? content : JSON.stringify(content, null, 2);\n}\n\n/**\n * 解析快照放宽提示。\n *\n * 约定格式:`SNAPSHOT_HINT: EXPAND_CHILDREN #ref1 #ref2`\n *\n * 返回:去掉 `#` 前缀后的 ref id 列表。\n */\nexport function parseSnapshotExpandHints(text: string | undefined): string[] {\n if (!text) return [];\n const refs: string[] = [];\n const regex = /^\\s*SNAPSHOT_HINT\\s*:\\s*EXPAND_CHILDREN\\s+(.+)$/gim;\n let match: RegExpExecArray | null;\n while ((match = regex.exec(text)) !== null) {\n const tail = match[1] ?? \"\";\n const tokens = tail.match(/#[A-Za-z0-9_-]+/g) ?? [];\n for (const token of tokens) refs.push(token.replace(/^#/, \"\"));\n }\n return refs;\n}\n\n/**\n * 提取 hash selector 的 ref。\n *\n * 仅处理“纯 hash 选择器”,例如 `#1rv01x`。\n * 如果是复杂 CSS(如 `.x #id`)会返回 null,避免误判。\n */\nexport function extractHashSelectorRef(toolInput: unknown): string | null {\n if (!toolInput || typeof toolInput !== \"object\") return null;\n const selector = (toolInput as { selector?: unknown }).selector;\n if (typeof selector !== \"string\") return null;\n const m = selector.trim().match(/^#([A-Za-z0-9_-]+)$/);\n return m ? m[1] : null;\n}\n\n/**\n * 构建任务数组。\n *\n * 作用:把一轮工具调用规整成稳定字符串数组,\n * 用于“上一轮任务回显”和“重复批次检测”。\n */\nexport function buildTaskArray(toolCalls: Array<{ name: string; input: unknown }>): string[] {\n return toolCalls.map(tc => `${tc.name}:${JSON.stringify(tc.input)}`);\n}\n\n/**\n * 规范化模型输出。\n *\n * 优先保留 REMAINING;否则保留首段摘要,避免长文本污染上下文。\n *\n * 返回字符串会被注入下一轮消息,作为“上一轮模型输出摘要”。\n */\nexport function normalizeModelOutput(text: string | undefined): string {\n if (!text) return \"\";\n const trimmed = text.trim();\n if (!trimmed) return \"\";\n const remainingMatch = trimmed.match(/REMAINING\\s*:\\s*([\\s\\S]*)$/i);\n if (remainingMatch) return `REMAINING: ${remainingMatch[1].trim()}`;\n const firstBlock = trimmed.split(/\\n\\s*\\n/)[0]?.trim() ?? trimmed;\n return firstBlock.slice(0, 220);\n}\n\n/**\n * 解析 REMAINING。\n *\n * 返回值:\n * - `\"\"` 表示 DONE\n * - 非空字符串表示新的 remaining\n * - `null` 表示协议缺失\n *\n * 注意:这里只负责解析,不负责 fallback 策略。\n *\n * 解析策略:\n * - 匹配最后一个 `REMAINING:` 后到行尾的内容(单行匹配,不跨行)\n * - `REMAINING: DONE` → 返回 `\"\"`(任务完成)\n * - `REMAINING: <text>` → 返回 `<text>`\n * - DONE 后面尾随的摘要文本会被忽略(模型常在 DONE 后附加总结)\n */\nexport function parseRemainingInstruction(text: string | undefined): string | null {\n if (!text) return null;\n // 按行从后往前找最后一个 REMAINING: 行(模型可能在 DONE 后输出总结文本)\n const lines = text.split(\"\\n\");\n for (let i = lines.length - 1; i >= 0; i--) {\n const lineMatch = lines[i].match(/REMAINING\\s*:\\s*(.*)$/i);\n if (lineMatch) {\n const value = lineMatch[1].trim();\n // 兼容 `REMAINING: DONE - xxx` / `REMAINING: DONE: xxx` 等写法\n if (/^done(?:\\s*(?:[-—::]|\\b).*)?$/i.test(value)) return \"\";\n return value;\n }\n }\n return null;\n}\n\n/**\n * 推导下一轮 remaining。\n *\n * 策略:\n * - 有 REMAINING 协议 -> 使用模型给出的 nextInstruction\n * - 无协议 -> 保持 currentInstruction 不变(由上层决定是否启发式推进)\n */\nexport function deriveNextInstruction(\n text: string | undefined,\n currentInstruction: string,\n): { nextInstruction: string; hasRemainingProtocol: boolean } {\n const parsed = parseRemainingInstruction(text);\n if (parsed !== null) {\n return { nextInstruction: parsed, hasRemainingProtocol: true };\n }\n return { nextInstruction: currentInstruction, hasRemainingProtocol: false };\n}\n\n/**\n * 启发式剔除 remaining。\n *\n * 用于协议缺失但本轮有执行动作时,按线性步骤剔除已执行数量。\n *\n * 这是“保守推进”策略,不保证语义完美,但能避免 remaining 长期不变。\n */\nexport function reduceRemainingHeuristically(\n currentInstruction: string,\n executedCount: number,\n): string {\n if (!currentInstruction.trim() || executedCount <= 0) return currentInstruction;\n\n const normalized = currentInstruction\n .replace(/\\s+/g, \" \")\n .replace(/(->|=>|→)/g, \" 然后 \")\n .replace(/[,,。;;]/g, \" 然后 \");\n\n const parts = normalized\n .split(/\\s*(?:然后|再|并且|并|接着|随后|之后)\\s*/g)\n .map(part => part.trim())\n .filter(Boolean);\n\n if (parts.length <= 1) return currentInstruction;\n\n const nextParts = parts.slice(Math.min(executedCount, parts.length));\n if (nextParts.length === 0) return \"\";\n return nextParts.join(\" -> \");\n}\n\n/**\n * 判定是否强制断轮。\n *\n * 语义:潜在 DOM 结构变化动作后,等待下一轮新快照。\n *\n * 当前规则:\n * - `navigate.*` 一律断轮\n * - `dom.press` 仅 Enter 断轮\n * - `evaluate` 断轮\n * - 其他动作默认不断轮\n */\nexport function shouldForceRoundBreak(toolName: string, toolInput: unknown): boolean {\n const action = getToolAction(toolInput);\n\n if (toolName === \"navigate\") {\n return action === \"goto\" || action === \"back\" || action === \"forward\" || action === \"reload\";\n }\n\n if (toolName === \"dom\") {\n if (action === \"click\") return true;\n if (action === \"press\") {\n const key = typeof toolInput === \"object\" && toolInput !== null\n ? String((toolInput as { key?: unknown; value?: unknown }).key ?? (toolInput as { value?: unknown }).value ?? \"\")\n : \"\";\n return key === \"Enter\";\n }\n return false;\n }\n\n return toolName === \"evaluate\";\n}\n\n/**\n * 判定动作是否可能引发页面结构或状态变化。\n *\n * 用于“轮次后稳定等待”触发条件:\n * - 命中 true:本轮结束后执行加载态 + DOM 静默双重等待\n * - 命中 false:跳过等待,直接进入下一轮\n */\nexport function isPotentialDomMutation(toolName: string, toolInput: unknown): boolean {\n const action = getToolAction(toolInput);\n\n if (toolName === \"navigate\") return true;\n if (toolName === \"evaluate\") return true;\n if (toolName !== \"dom\") return false;\n\n if (!action) return false;\n return [\n \"click\",\n \"fill\",\n \"select_option\",\n \"clear\",\n \"check\",\n \"uncheck\",\n \"type\",\n \"focus\",\n \"hover\",\n \"scroll\",\n \"press\",\n \"set_attr\",\n \"add_class\",\n \"remove_class\",\n ].includes(action);\n}\n\n/**\n * 采集找不到元素任务。\n *\n * 返回 null 表示当前结果不属于“元素未找到”,\n * 返回对象表示可进入 not-found retry 对话流。\n */\nexport function collectMissingTask(\n name: string,\n input: unknown,\n result: ToolCallResult,\n): { name: string; input: unknown; reason: string } | null {\n if (!isElementNotFoundResult(result)) return null;\n return {\n name,\n input,\n reason: toContentString(result.content).slice(0, 240),\n };\n}\n\n/**\n * 元素不存在判定。\n *\n * 判定顺序:\n * 1) 优先看结构化错误码 `ELEMENT_NOT_FOUND`\n * 2) 回退看中文错误文本关键词(兼容历史结果格式)\n */\nexport function isElementNotFoundResult(result: ToolCallResult): boolean {\n const details = result.details;\n if (details && typeof details === \"object\") {\n const code = (details as { code?: unknown }).code;\n if (code === \"ELEMENT_NOT_FOUND\") return true;\n }\n\n const content = toContentString(result.content);\n return content.includes(\"未找到\") && content.includes(\"元素\");\n}\n\n/**\n * 生成稳定调用键。\n *\n * 用于 recoveryAttempts 的 map key(同名 + 同参数视为同一调用)。\n */\nexport function buildToolCallKey(name: string, input: unknown): string {\n return `${name}:${JSON.stringify(input)}`;\n}\n\n/**\n * 解析恢复等待时长。\n * 优先级:waitMs > waitSeconds > 默认值。\n *\n * 统一返回毫秒整数,且最小为 0。\n */\nexport function resolveRecoveryWaitMs(input: unknown): number {\n if (!input || typeof input !== \"object\") return DEFAULT_RECOVERY_WAIT_MS;\n\n const params = input as Record<string, unknown>;\n const waitMs = params.waitMs;\n if (typeof waitMs === \"number\" && Number.isFinite(waitMs)) {\n return Math.max(0, Math.floor(waitMs));\n }\n\n const waitSeconds = params.waitSeconds;\n if (typeof waitSeconds === \"number\" && Number.isFinite(waitSeconds)) {\n return Math.max(0, Math.floor(waitSeconds * 1000));\n }\n\n return DEFAULT_RECOVERY_WAIT_MS;\n}\n\n/**\n * 读取工具 action。\n *\n * 仅在 input 是对象且 action 为字符串时返回值,否则返回 undefined。\n */\nexport function getToolAction(input: unknown): string | undefined {\n if (!input || typeof input !== \"object\") return undefined;\n const action = (input as Record<string, unknown>).action;\n return typeof action === \"string\" ? action : undefined;\n}\n\n/**\n * 判定错误标记。\n *\n * 约定:`result.details.error === true` 视为错误结果。\n */\nexport function hasToolError(result: ToolCallResult): boolean {\n return result.details && typeof result.details === \"object\"\n ? Boolean((result.details as { error?: unknown }).error)\n : false;\n}\n","/**\n * DOM 快照生命周期管理。\n *\n * 负责 4 类能力:读取、包裹、去重、剥离。\n *\n * 快照读取主流程:\n * 1) 组装快照参数(默认偏完整性)\n * 2) 调用 `page_info.snapshot`\n * 3) 将工具返回内容统一成字符串\n * 4) 由消息层进行包裹与注入\n * 5) 在多轮对话中去重旧快照\n *\n * 调用链:\n * - `agent-loop/index.ts` 在“无快照、每轮结束、导航后、恢复后”触发读取。\n * - `messages.ts` 负责把最新快照注入到本轮上下文。\n * - 本文件只处理快照文本本身,不负责业务决策与停机判定。\n *\n * 压缩/剪枝实现位置:\n * - 具体算法在 `src/web/tools/page-info-tool.ts` 的 `generateSnapshot()`。\n * - 本文件通过 `readPageSnapshot()` 传参触发这些策略,不在 core 层直接操作 DOM。\n * - 这样保持分层:core 只声明策略参数,web 负责真实遍历与裁剪。\n */\nimport { ToolRegistry } from \"../tool-registry.js\";\nimport type { AIMessage } from \"../types.js\";\nimport {\n SNAPSHOT_END,\n SNAPSHOT_OUTDATED,\n SNAPSHOT_START,\n} from \"./constants.js\";\nimport { toContentString } from \"./helpers.js\";\n\n// ─── 快照读取 ───\n\n/**\n * 读取页面 URL。\n *\n * 步骤:\n * 1) 通过 registry 分发 `page_info.get_url`。\n * 2) 若 content 为字符串则直接返回。\n * 3) 否则返回 undefined,交由上层容错。\n *\n * 输入/输出:\n * - 输入:`ToolRegistry`\n * - 输出:`string | undefined`\n * - 副作用:无本地状态写入(仅发起一次工具调用)\n */\nexport async function readPageUrl(\n registry: ToolRegistry,\n): Promise<string | undefined> {\n const result = await registry.dispatch(\"page_info\", { action: \"get_url\" });\n return typeof result.content === \"string\" ? result.content : undefined;\n}\n\n/**\n * 读取页面快照。\n *\n * 默认关闭 viewportOnly,优先完整性。\n *\n * 步骤:\n * 1) 合并调用方 options 与默认值(深度/裁剪/剪枝/节点上限等)。\n * 2) 分发 `page_info.snapshot` 获取当前 DOM 文本快照。\n * 3) 使用 `toContentString` 归一化输出,避免 provider 差异导致结构不一致。\n * 4) 返回稳定字符串给 loop,供后续注入消息与统计。\n *\n * 默认参数意图:\n * - `maxDepth=12`: 保留更深层级,减少深层组件控件被截断。\n * - `viewportOnly=false`: 优先完整性,避免误判“元素不存在”。\n * - `pruneLayout=true`: 抑制纯布局噪声,降低 token 压力。\n * - `maxNodes=500` / `maxChildren=30`: 控制体积上限,兼顾可读性。\n * - `maxTextLength=40`: 防止长文本淹没结构信息。\n *\n * 压缩/剪枝是怎么做的:\n * - `viewportOnly=true` 时:仅保留与视口相交元素(根层容器保留),完全视口外元素跳过。\n * - `pruneLayout=true` 时:无 id/无语义/无交互/无直接文本的布局容器会被“折叠”,\n * 子节点直接提升输出,减少无意义层级;当同一折叠容器提升出多个相邻节点时,\n * 快照会用括号分组块标记其关联来源(collapsed-group)。\n * - `maxNodes`:全局节点预算,超限后停止继续遍历并追加 truncation 提示。\n * - `maxChildren`:每个父节点只保留前 N 个子元素,其余用 `... (n children omitted)` 汇总。\n * - `maxTextLength`:节点文本按长度截断,避免长段文案占满上下文。\n * - 交互优先排序:优先输出按钮/输入框/链接等交互元素,再输出普通元素。\n * - 属性压缩:仅保留关键属性(如 id、关键 class、交互属性、布尔状态、val),减少冗余 token。\n *\n * 输入/输出:\n * - 输入:`ToolRegistry` + 可选快照参数\n * - 输出:归一化后的快照字符串(始终 string)\n * - 副作用:无本地状态写入;仅依赖工具调用结果\n */\nexport async function readPageSnapshot(\n registry: ToolRegistry,\n options?: {\n maxDepth?: number;\n viewportOnly?: boolean;\n pruneLayout?: boolean;\n maxNodes?: number;\n maxChildren?: number;\n maxTextLength?: number;\n expandOptionLists?: boolean;\n expandChildrenRefs?: string[];\n expandedChildrenLimit?: number;\n },\n): Promise<string> {\n const result = await registry.dispatch(\"page_info\", {\n action: \"snapshot\",\n maxDepth: options?.maxDepth ?? 12,\n viewportOnly: options?.viewportOnly ?? false,\n pruneLayout: options?.pruneLayout ?? true,\n maxNodes: options?.maxNodes ?? 500,\n maxChildren: options?.maxChildren ?? 30,\n maxTextLength: options?.maxTextLength ?? 40,\n expandOptionLists: options?.expandOptionLists,\n expandChildrenRefs: options?.expandChildrenRefs,\n expandedChildrenLimit: options?.expandedChildrenLimit,\n });\n return toContentString(result.content);\n}\n\n// ─── 快照标记 ───\n\n/**\n * 包裹快照。\n *\n * 作用:\n * - 为快照加 `SNAPSHOT_START/END` 边界,便于后续正则定位。\n * - 支持去重与旧快照剥离,防止多轮 token 累积。\n * - 仅做纯字符串变换,不访问外部状态。\n */\nexport function wrapSnapshot(snapshot: string): string {\n return `${SNAPSHOT_START}\\n${snapshot}\\n${SNAPSHOT_END}`;\n}\n\n// ─── 快照去重 ───\n\n/** 转义正则字符。 */\nfunction escapeRegex(str: string): string {\n return str.replace(/[.*+?^${}()|[\\]\\\\]/g, \"\\\\$&\");\n}\n\n/** 快照块匹配正则。 */\nconst SNAPSHOT_REGEX = new RegExp(\n `${escapeRegex(SNAPSHOT_START)}[\\\\s\\\\S]*?${escapeRegex(SNAPSHOT_END)}`,\n \"g\",\n);\n\n/** 是否包含快照标记。 */\nfunction containsSnapshot(text: string): boolean {\n return text.includes(SNAPSHOT_START) && text.includes(SNAPSHOT_END);\n}\n\n/**\n * 去重消息快照。\n * 仅保留最后一份快照,旧快照替换为过期提示。\n *\n * 步骤:\n * 1) 扫描 tool 消息中的快照块引用。\n * 2) 保留最后一次快照,视为当前事实来源。\n * 3) 将更早快照替换为 `SNAPSHOT_OUTDATED`,避免模型引用旧状态。\n *\n * 返回语义:\n * - `true`: 至少发现了 1 份快照(可能发生替换,也可能只有一份无需替换)。\n * - `false`: 未发现任何快照标记。\n */\nexport function deduplicateSnapshots(messages: AIMessage[]): boolean {\n type SnapshotRef = {\n items: Array<{ toolCallId: string; result: string }>;\n index: number;\n };\n const refs: SnapshotRef[] = [];\n\n for (const msg of messages) {\n if (msg.role !== \"tool\" || !Array.isArray(msg.content)) continue;\n const items = msg.content as Array<{ toolCallId: string; result: string }>;\n for (let j = 0; j < items.length; j++) {\n if (typeof items[j].result === \"string\" && containsSnapshot(items[j].result)) {\n refs.push({ items, index: j });\n }\n }\n }\n\n if (refs.length <= 1) return refs.length > 0;\n\n // 保留最后一份快照,将更早的快照替换为过期提示\n for (let i = 0; i < refs.length - 1; i++) {\n const ref = refs[i];\n ref.items[ref.index].result = ref.items[ref.index].result.replace(\n SNAPSHOT_REGEX,\n SNAPSHOT_OUTDATED,\n );\n }\n\n return true;\n}\n\n/**\n * 剥离旧快照。\n *\n * 说明:\n * - 当 prompt 中已有历史快照时,将其替换为过期占位文本。\n * - 让每轮真正生效的只有“最新注入快照”,减少冲突上下文。\n * - 这是 prompt 级清理;不会触碰 tool trace 中的原始结果对象。\n */\nexport function stripSnapshotFromPrompt(prompt: string): string {\n if (!containsSnapshot(prompt)) return prompt;\n return prompt.replace(SNAPSHOT_REGEX, SNAPSHOT_OUTDATED);\n}\n\n/** 导出快照正则,供消息层做错误摘要清理等用途。 */\nexport { SNAPSHOT_REGEX };\n","/**\n * 紧凑消息构建。\n *\n * 这个文件专门负责“给模型喂什么消息”。\n *\n * 它把 Agent Loop 的运行状态压缩成模型可直接消费的消息内容,核心输入包括:\n * - 用户原始目标(userMessage)\n * - 当前剩余任务(remainingInstruction)\n * - 已执行轨迹(trace / previousRoundTasks)\n * - 上一轮模型输出摘要(previousRoundModelOutput)\n * - 最新页面快照(latestSnapshot)\n * - 协议修复提示(protocolViolationHint)\n *\n * 设计目标:\n * 1) 减少上下文噪音,避免模型复述与空转\n * 2) 强化“基于当前快照做增量决策”的行为\n * 3) 让 REMAINING 协议在每轮都可持续推进\n *\n * 这个文件主要做了 4 件事:\n * 1) UI 意图识别:\n * - `isExplicitAgentUiRequest` 判断用户是否“明确要求操作 AutoPilot 聊天 UI”。\n * - 默认情况下会在提示词里禁止模型点击聊天输入框/发送按钮等。\n *\n * 2) 轨迹可读化:\n * - `formatToolInputBrief`、`formatToolResultBrief`、`buildToolTrace`\n * 把工具输入/结果压成短文本,便于注入上下文和调试展示。\n * - 直观效果示例(最终会长这样):\n * 1. [round 2] dom (action=\"click\", selector=\"#a1b2c\") [ELEMENT_NOT_FOUND]\n * 2. [round 2] wait (action=\"wait_for_selector\", selector=\"#a1b2c\")\n * 3. [round 3] dom (action=\"fill\", selector=\"#x9k3d\")\n *\n * 3) Round 0 消息构建:\n * - 首轮注入“任务 + remaining + 最新快照 + 执行约束”。\n * - 明确要求模型输出 `REMAINING: ...` 或 `REMAINING: DONE`。\n *\n * 4) Round 1+ 消息构建:\n * - 不再重复整段原始任务,改为注入“已完成步骤 + 当前 remaining + 最新快照”。\n * - 追加错误摘要、上轮计划数组、协议修复提示,帮助模型持续收敛。\n *\n * 边界说明(这个文件不做的事):\n * - 不调用模型、不执行工具\n * - 不维护循环状态(状态维护在 index.ts)\n * - 不读取页面快照(快照读取在 snapshot.ts)\n *\n * 一句话:这里是 Agent Loop 的“消息编排层”,负责把运行态翻译成稳定、高信息密度的提示上下文。\n */\nimport type { ToolCallResult } from \"../tool-registry.js\";\nimport type { AIMessage } from \"../types.js\";\nimport { toContentString, hasToolError } from \"./helpers.js\";\nimport { wrapSnapshot, SNAPSHOT_REGEX } from \"./snapshot.js\";\nimport type { ToolTraceEntry } from \"./types.js\";\n\n/**\n * 显式 UI 意图判定。\n *\n * 用途:默认禁止模型操作 AutoPilot 自己的聊天 UI(输入框/发送按钮等),\n * 只有当用户文本里“同时出现 UI 关键词 + 操作动词”时才放行。\n *\n * 判定逻辑:\n * - `hasAgentUiKeyword`:是否提到聊天面板/输入框/发送按钮等\n * - `hasActionVerb`:是否包含点击/输入/发送等动作意图\n * - 二者都满足才返回 true\n */\nexport function isExplicitAgentUiRequest(userMessage: string): boolean {\n const lower = userMessage.toLowerCase();\n const compact = lower.replace(/[\\s\\p{P}\\p{S}]+/gu, \"\");\n\n const hasAgentUiKeyword =\n /(chat|dock|chatinput|sendbutton|shortcut|quicktest)/i.test(lower) ||\n /(聊天|对话|指令输入框|消息输入框|输入框|发送按钮|发送|快捷测试|测试按钮|聊天面板)/.test(compact);\n\n const hasActionVerb =\n /(press|click|type|fill|send|input|submit|enter)/i.test(lower) ||\n /(输入|点击|发送|填写|填入|操作|提交|回车|按下)/.test(compact);\n return hasAgentUiKeyword && hasActionVerb;\n}\n\n// ─── 格式化辅助 ───\n\n/**\n * 输入摘要。\n *\n * 把工具输入压缩成一段短文本(用于轨迹展示),\n * 只保留高价值字段,避免日志过长。\n */\nexport function formatToolInputBrief(input: unknown): string {\n if (!input || typeof input !== \"object\") return \"\";\n\n const params = input as Record<string, unknown>;\n const parts: string[] = [];\n\n for (const key of [\"action\", \"selector\", \"waitMs\", \"waitSeconds\", \"url\", \"text\"]) {\n const value = params[key];\n if (value === undefined || value === null) continue;\n if (typeof value === \"string\") {\n parts.push(`${key}=${JSON.stringify(value).slice(0, 80)}`);\n } else if (typeof value === \"number\" || typeof value === \"boolean\") {\n parts.push(`${key}=${String(value)}`);\n }\n }\n\n if (parts.length === 0) return \"\";\n return ` (${parts.join(\", \")})`;\n}\n\n/**\n * 结果摘要。\n *\n * 读取工具结果首行,拼接错误码,生成一行可读结论:\n * - 成功:`✓ ...`\n * - 失败:`✗ ... [CODE]`\n */\nfunction formatToolResultBrief(result: ToolCallResult): string {\n const content = toContentString(result.content);\n const firstLine = content.split(\"\\n\").find(l => l.trim())?.trim().slice(0, 80) ?? \"\";\n\n if (hasToolError(result)) {\n const code = result.details && typeof result.details === \"object\"\n ? (result.details as { code?: string }).code\n : undefined;\n return `✗ ${firstLine}${code ? ` [${code}]` : \"\"}`;\n }\n return `✓ ${firstLine}`;\n}\n\n// ─── 轨迹格式化 ───\n\n/**\n * 轨迹格式化。\n *\n * 将完整工具轨迹转为可读文本列表,供提示词注入或调试展示。\n * 支持附加 current 条目(未入库前的临时展示)。\n *\n * 输出样式示例:\n * 1. [round 1] dom (action=\"click\", selector=\"#btnCreate\")\n * 2. [round 1] dom (action=\"fill\", selector=\"#title\") [FILL_NOT_APPLIED]\n * 3. [round 2] wait (action=\"wait_for_selector\", selector=\"#dialog\")\n */\nexport function buildToolTrace(\n trace: ToolTraceEntry[],\n current?: {\n round: number;\n name: string;\n input: unknown;\n result?: ToolCallResult;\n marker?: string;\n },\n): string {\n const lines = trace.map((entry, index) => {\n const code =\n entry.result.details && typeof entry.result.details === \"object\"\n ? (entry.result.details as { code?: unknown }).code\n : undefined;\n const codeText = typeof code === \"string\" ? ` [${code}]` : \"\";\n const marker = entry.marker ? ` ${entry.marker}` : \"\";\n return `${index + 1}. [round ${entry.round}] ${entry.name}${formatToolInputBrief(entry.input)}${codeText}${marker}`;\n });\n\n if (current) {\n const code =\n current.result?.details && typeof current.result.details === \"object\"\n ? (current.result.details as { code?: unknown }).code\n : undefined;\n const codeText = typeof code === \"string\" ? ` [${code}]` : \"\";\n const marker = current.marker ? ` ${current.marker}` : \"\";\n lines.push(\n `${lines.length + 1}. [round ${current.round}] ${current.name}${formatToolInputBrief(current.input)}${codeText}${marker}`,\n );\n }\n\n return lines.length > 0 ? lines.join(\"\\n\") : \"(暂无工具执行记录)\";\n}\n\n// ─── 紧凑消息构建 ───\n\n/**\n * 构建紧凑消息数组。\n *\n * 两种轮次语义:\n * - Round 0:发送“初始任务 + 当前快照 + 执行约束”\n * - Round 1+:发送“已完成步骤 + 当前 remaining + 最新快照”\n *\n * 渐进式语义:\n * - `remainingInstruction`:当前轮次仍待执行的文本。\n * - `previousRoundTasks`:上一轮已执行的任务数组,避免重复计划。\n * - `previousRoundModelOutput`:上一轮模型输出摘要,用于 task-reduction 输入。\n * - `previousRoundPlannedTasks`:上一轮计划数组,用于对齐“计划 vs 实际执行”。\n * - `protocolViolationHint`:协议修复提示(当 remaining 未完成但模型无动作时)。\n *\n * 输出:符合 AIMessage 结构的消息数组,可直接传给 AIClient.chat。\n */\nexport function buildCompactMessages(\n userMessage: string,\n trace: ToolTraceEntry[],\n latestSnapshot: string | undefined,\n currentUrl: string | undefined,\n history?: AIMessage[],\n remainingInstruction?: string,\n previousRoundTasks?: string[],\n previousRoundModelOutput?: string,\n previousRoundPlannedTasks?: string[],\n protocolViolationHint?: string,\n): AIMessage[] {\n const messages: AIMessage[] = history ? [...history] : [];\n const allowAgentUiInteraction = isExplicitAgentUiRequest(userMessage);\n const activeInstruction = (remainingInstruction && remainingInstruction.trim())\n ? remainingInstruction.trim()\n : userMessage;\n\n // ─── Round 0:任务描述 + 快照,一条 user 消息完成注入 ───\n if (trace.length === 0) {\n // 结构说明:\n // 1) 用户目标\n // 2) 当前 remaining\n // 3) URL(可选)\n // 4) 快照 + 行为约束(禁 page_info、禁误触 Agent UI、要求 REMAINING 输出)\n const parts: string[] = [\n userMessage,\n \"\",\n `Remaining: ${activeInstruction}`,\n ];\n if (currentUrl) {\n parts.push(`URL: ${currentUrl}`);\n }\n if (latestSnapshot) {\n parts.push(\n \"\",\n \"Use #hashID from snapshot. Do NOT call page_info (snapshot is auto-refreshed). Batch fills freely; at most ONE click (last) per round.\",\n \"Semantic completion: keep all unresolved user constraints in Remaining until they are visibly satisfied in the snapshot.\",\n \"Do NOT compress Remaining into a vague shell action that drops required entities, values, counts, filters, destinations, selections, or final outcomes from the user goal.\",\n \"Before any advance/finalize action, verify the prerequisite constraints are already satisfied in snapshot; otherwise continue the unsatisfied parts first.\",\n \"Effect check: confirm previous actions' expected effects in current snapshot before planning new actions.\",\n \"Click ends the round — actions after a click are discarded. Dropdown: open(click) → next round → pick(click).\",\n \"If a list shows `... (N children omitted)`, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>` and wait for next snapshot.\",\n allowAgentUiInteraction\n ? \"User explicitly asked to operate AutoPilot UI. You may interact with chat input/send/dock only as requested.\"\n : \"Do NOT interact with any AI chat UI elements (chat input, send button, dock). Only operate on the actual page content.\",\n \"Output: REMAINING: <new remaining> or REMAINING: DONE\",\n \"\",\n \"## Snapshot\",\n wrapSnapshot(latestSnapshot),\n );\n }\n if (protocolViolationHint) {\n parts.push(\"\", protocolViolationHint);\n }\n messages.push({ role: \"user\", content: parts.join(\"\\n\") });\n return messages;\n }\n\n // ─── Round 1+:注入“已完成步骤 + 执行上下文 + 最新快照” ───\n // 不再重复原始 userMessage,避免模型每轮回到起点重做。\n\n // 第 1 条 assistant 消息:已完成步骤摘要(从 trace 重建)\n const traceParts: string[] = [];\n for (let i = 0; i < trace.length; i++) {\n const entry = trace[i];\n const isError = hasToolError(entry.result);\n const brief = formatToolResultBrief(entry.result);\n const status = isError ? \"❌\" : \"✅\";\n const marker = entry.marker ? ` ${entry.marker}` : \"\";\n traceParts.push(\n `${status} ${i + 1}. ${entry.name}${formatToolInputBrief(entry.input)} → ${brief}${marker}`,\n );\n }\n messages.push({\n role: \"assistant\",\n content: `Done steps (do NOT repeat):\\n${traceParts.join(\"\\n\")}`,\n });\n\n // 第 2 条 user 消息:执行上下文 + 协议约束 + 最新快照\n const hasErrors = trace.some(e => hasToolError(e.result));\n const contextParts: string[] = [\n // 当前剩余任务(唯一待消费目标)\n `Remaining: ${activeInstruction}`,\n \"\",\n // ── 关键行为强化(system prompt 已有完整规则,此处补强模型易违反的关键条) ──\n \"Batch fills per round; clicks end the round — at most ONE click (last). Do NOT call page_info (snapshot is auto-refreshed).\",\n \"Semantic completion: preserve all unresolved user constraints in Remaining until they are visibly satisfied in the snapshot.\",\n \"Do NOT narrow Remaining into only a shell action if that would drop required entities, values, counts, filters, destinations, selections, or final outcomes.\",\n \"Before any advance/finalize action, check that all prerequisite constraints are already visible in the snapshot.\",\n \"Effect check: confirm previous actions' expected effects in snapshot before planning new actions.\",\n \"Never repeat the same tool call on the same target. If no effect, try a different element.\",\n \"Click ends the round — actions after a click are discarded. Dropdown: open(click) → next round → pick(click).\",\n \"If a list shows `... (N children omitted)`, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>` and wait.\",\n allowAgentUiInteraction\n ? \"User explicitly asked to operate AutoPilot UI.\"\n : \"Do NOT interact with AI chat UI elements.\",\n \"Output: REMAINING: <new remaining> or REMAINING: DONE\",\n ];\n\n if (hasErrors) {\n contextParts.push(\"\", \"Last step failed. Retry differently or skip to other targets.\");\n } else {\n contextParts.push(\"\", \"If fully done, reply summary only (no tools).\");\n }\n\n if (previousRoundTasks && previousRoundTasks.length > 0) {\n // 上轮已执行 + 简短效果提示(非阻塞,避免分析瘧痪)\n contextParts.push(\n \"\",\n \"Previous executed:\",\n ...previousRoundTasks.map((task, index) => `${index + 1}. ${task}`),\n \"If any had no visible effect, try a different nearby element instead of repeating.\",\n );\n }\n\n if (previousRoundPlannedTasks && previousRoundPlannedTasks.length > 0) {\n contextParts.push(\n \"\",\n \"Previous planned:\",\n ...previousRoundPlannedTasks.map((task, index) => `${index + 1}. ${task}`),\n );\n }\n\n if (previousRoundModelOutput) {\n contextParts.push(\n \"\",\n \"Previous model output:\",\n previousRoundModelOutput,\n );\n }\n\n // 最近失败摘要\n const lastEntry = trace[trace.length - 1];\n if (hasToolError(lastEntry.result)) {\n const detail = toContentString(lastEntry.result.content);\n const stripped = detail.replace(SNAPSHOT_REGEX, \"\").trim();\n if (stripped && stripped.length < 300) {\n contextParts.push(\"\", \"Error: \" + stripped);\n }\n }\n\n if (currentUrl) {\n contextParts.push(\"\", `URL: ${currentUrl}`);\n }\n\n if (protocolViolationHint) {\n contextParts.push(\"\", protocolViolationHint);\n }\n\n if (latestSnapshot) {\n // 注入最新快照\n contextParts.push(\n \"\",\n \"## Snapshot\",\n wrapSnapshot(latestSnapshot),\n );\n }\n\n messages.push({ role: \"user\", content: contextParts.join(\"\\n\") });\n\n return messages;\n}\n","/**\n * 保护与恢复机制。\n *\n * 这个文件负责给 Agent Loop 提供“防失败、防空转、防重复”的保护链。\n * 目标是:即使某一步失败,也尽量让循环继续推进,而不是直接崩掉。\n *\n * 主要能力:\n * 1) 冗余拦截:拦住无意义的 `page_info.*` 调用\n * 2) 快照防抖:连续 snapshot 触发时给出警告并限制空转\n * 3) 找不到元素恢复:自动等待 + 刷新快照 + 重试上限\n * 4) 导航后刷新:导航成功后立刻更新快照上下文\n * 5) 空转检测:连续只读轮次触发停机信号\n *\n * 一句话:这里是主循环的“保险丝层”。\n */\nimport type { ToolCallResult } from \"../tool-registry.js\";\nimport type { AgentLoopCallbacks } from \"./types.js\";\nimport { DEFAULT_ACTION_RECOVERY_ROUNDS } from \"./constants.js\";\nimport { readPageSnapshot } from \"./snapshot.js\";\nimport {\n getToolAction,\n hasToolError,\n isElementNotFoundResult,\n resolveRecoveryWaitMs,\n buildToolCallKey,\n sleep,\n toContentString,\n} from \"./helpers.js\";\nimport { ToolRegistry } from \"../tool-registry.js\";\nimport type { PageContextState } from \"./types.js\";\n\n// ─── 冗余 page_info 拦截 ───\n\n/** 冗余 page_info 动作集合。 */\nconst REDUNDANT_PAGE_INFO_ACTIONS = new Set([\"snapshot\", \"query_all\", \"get_url\", \"get_title\", \"get_viewport\"]);\n\n/**\n * 冗余 page_info 检查。\n *\n * 场景:模型在 loop 中频繁请求 page_info,导致“只看不做”。\n * 处理:命中白名单动作时直接返回拦截结果,不真正执行工具。\n *\n * 示例:\n * - 输入:`page_info.snapshot`\n * - 输出:`REDUNDANT_PAGE_INFO_SKIPPED`\n */\nexport function checkRedundantSnapshot(\n toolName: string,\n toolInput: unknown,\n _latestSnapshot: string | undefined,\n round: number,\n): ToolCallResult | null {\n if (toolName !== \"page_info\") return null;\n\n const action = getToolAction(toolInput);\n if (action && REDUNDANT_PAGE_INFO_ACTIONS.has(action)) {\n return {\n content:\n `page_info.${action} is blocked in loop execution. A snapshot is provided by the framework; continue with actionable tools directly.`,\n details: {\n code: \"REDUNDANT_PAGE_INFO_SKIPPED\",\n action,\n round,\n },\n };\n }\n return null;\n}\n\n/**\n * 快照防抖。\n *\n * 规则:连续触发 `page_info.snapshot` 时,第 2 次起标记为冗余,\n * 返回 `REDUNDANT_SNAPSHOT`,提醒模型直接使用已有快照继续执行。\n *\n * 返回值:\n * - `result`:可能被替换成防抖后的结果\n * - `consecutiveCount`:更新后的连续 snapshot 计数\n */\nexport function applySnapshotDebounce(\n toolName: string,\n toolInput: unknown,\n result: ToolCallResult,\n consecutiveCount: number,\n): { result: ToolCallResult; consecutiveCount: number } {\n if (toolName === \"page_info\" && getToolAction(toolInput) === \"snapshot\") {\n const newCount = consecutiveCount + 1;\n if (newCount >= 2) {\n return {\n consecutiveCount: newCount,\n result: {\n content: [\n toContentString(result.content),\n \"Redundant snapshot detected. Continue with remaining actionable steps using the latest snapshot; avoid additional snapshot unless navigation or uncertainty changes.\",\n ].join(\"\\n\"),\n details: {\n error: true,\n code: \"REDUNDANT_SNAPSHOT\",\n consecutiveSnapshotCalls: newCount,\n },\n },\n };\n }\n return { result, consecutiveCount: newCount };\n }\n // 非 snapshot 调用,重置计数\n return { result, consecutiveCount: 0 };\n}\n\n// ─── 元素未找到自动恢复 ───\n\n/**\n * 元素未找到恢复。\n *\n * 触发条件:\n * - 工具是 `dom`\n * - 结果被识别为“元素未找到”\n *\n * 处理流程:\n * 1) 按调用键统计恢复次数(同 name + input 视为同一调用)\n * 2) 在上限内:等待 -> 刷新快照 -> 返回 `ELEMENT_NOT_FOUND_RECOVERY`\n * 3) 超过上限:返回 `ELEMENT_NOT_FOUND_MAX_RECOVERY_REACHED`\n *\n * 说明:函数只返回“恢复后的结果描述”,是否继续下一轮由主循环决定。\n */\nexport async function handleElementRecovery(\n toolName: string,\n toolInput: unknown,\n result: ToolCallResult,\n recoveryAttempts: Map<string, number>,\n registry: ToolRegistry,\n pageContext: PageContextState,\n callbacks?: AgentLoopCallbacks,\n): Promise<ToolCallResult | null> {\n if (toolName !== \"dom\" || !isElementNotFoundResult(result)) {\n return null;\n }\n\n const key = buildToolCallKey(toolName, toolInput);\n const attempts = (recoveryAttempts.get(key) ?? 0) + 1;\n recoveryAttempts.set(key, attempts);\n const recoveryWaitMs = resolveRecoveryWaitMs(toolInput);\n\n if (attempts <= DEFAULT_ACTION_RECOVERY_ROUNDS) {\n await sleep(recoveryWaitMs);\n callbacks?.onBeforeRecoverySnapshot?.();\n pageContext.latestSnapshot = await readPageSnapshot(registry);\n\n return {\n content: [\n toContentString(result.content),\n `Recovery ${attempts}/${DEFAULT_ACTION_RECOVERY_ROUNDS}: snapshot refreshed, re-locate target.`,\n ].join(\"\\n\"),\n details: {\n error: true,\n code: \"ELEMENT_NOT_FOUND_RECOVERY\",\n recoveryAttempt: attempts,\n recoveryMaxRounds: DEFAULT_ACTION_RECOVERY_ROUNDS,\n },\n };\n }\n\n return {\n content: [\n toContentString(result.content),\n `Max recovery attempts (${DEFAULT_ACTION_RECOVERY_ROUNDS}) reached. Try a different target.`,\n ].join(\"\\n\"),\n details: {\n error: true,\n code: \"ELEMENT_NOT_FOUND_MAX_RECOVERY_REACHED\",\n recoveryAttempt: attempts,\n recoveryMaxRounds: DEFAULT_ACTION_RECOVERY_ROUNDS,\n },\n };\n}\n\n// ─── 导航后 URL 变化检测 ───\n\n/**\n * 导航后快照刷新。\n *\n * 当 `navigate.goto/back/forward/reload` 成功后,立即刷新快照,\n * 防止后续动作还在旧页面上下文里决策。\n */\nexport async function handleNavigationUrlChange(\n toolName: string,\n toolInput: unknown,\n result: ToolCallResult,\n registry: ToolRegistry,\n pageContext: PageContextState,\n callbacks?: AgentLoopCallbacks,\n): Promise<void> {\n if (toolName !== \"navigate\") return;\n\n const action = getToolAction(toolInput);\n if (\n (action === \"goto\" || action === \"back\" || action === \"forward\" || action === \"reload\") &&\n !hasToolError(result)\n ) {\n callbacks?.onBeforeRecoverySnapshot?.();\n pageContext.latestSnapshot = await readPageSnapshot(registry);\n }\n}\n\n// ─── 空转检测 ───\n\n/** 只读工具集合。 */\nconst READ_ONLY_TOOLS = new Set([\"page_info\"]);\n\n/** DOM 只读动作集合。 */\nconst READ_ONLY_DOM_ACTIONS = new Set([\"get_text\", \"get_attr\"]);\n\n/**\n * 空转检测:识别连续只读轮次并终止。\n *\n * 判定口径:\n * - `page_info.*` 视为只读\n * - `dom.get_text/get_attr` 视为只读\n *\n * 返回值语义:\n * - `-1`:触发停机(连续 2 轮纯只读)\n * - `0`:本轮有实质操作,计数清零\n * - `>0`:当前连续只读轮次\n */\nexport function detectIdleLoop(\n toolCalls: Array<{ name: string; input: unknown }>,\n consecutiveReadOnlyRounds: number,\n): number {\n const allReadOnly = toolCalls.length > 0 && toolCalls.every(({ name, input }) => {\n if (READ_ONLY_TOOLS.has(name)) return true;\n if (name !== \"dom\") return false;\n const action = getToolAction(input);\n return Boolean(action && READ_ONLY_DOM_ACTIONS.has(action));\n });\n if (allReadOnly) {\n const newCount = consecutiveReadOnlyRounds + 1;\n // 连续 2 轮纯只读 → 返回 -1 表示强制终止\n return newCount >= 2 ? -1 : newCount;\n }\n return 0; // 有实际操作,重置\n}\n","/**\n * Agent Loop 主流程(口语版)\n *\n * 流程图(文本):\n *\n * 轮次开始\n * │\n * ├─ 先看有没有最新快照\n * │ └─ 没有就先拍一张(可带 expandChildrenRefs)\n * │\n * ├─ 组装本轮上下文消息\n * │ └─ remaining + 上轮任务 + 最新快照 +(必要时)重试提示\n * │\n * ├─ 调用模型拿决策\n * │ └─ 同时解析 `REMAINING` 和 `SNAPSHOT_HINT`\n * │\n * ├─ 有 toolCalls 吗?\n * │ ├─ 没有:走收敛/协议修复判断(必要时等待后重试)\n * │ └─ 有:逐个执行工具\n * │ ├─ 冗余拦截(例如 page_info 空转)\n * │ ├─ 失败恢复(元素未找到重试)\n * │ ├─ 导航后更新快照\n * │ └─ 命中断轮条件则提前结束本轮\n * │\n * ├─ 更新 remaining(优先协议,缺失时启发式剔除)\n * │\n * ├─ 防空转 / 防自转 / 防协议缺失检查\n * │ └─ 连续只读、重复批次、连续无协议均会触发停机\n * │\n * ├─ 刷新快照\n * ▼\n * 下一轮或停机\n *\n * 停机条件(任一命中):\n * - `REMAINING: DONE`(或 remaining 为空)\n * - 协议修复后仍无推进\n * - 连续只读(空转)\n * - 重复批次(自转)\n * - 达到 maxRounds\n */\nimport {\n DEFAULT_MAX_ROUNDS,\n DEFAULT_NOT_FOUND_RETRY_ROUNDS,\n DEFAULT_NOT_FOUND_RETRY_WAIT_MS,\n DEFAULT_ROUND_STABILITY_WAIT_LOADING_SELECTORS,\n DEFAULT_ROUND_STABILITY_WAIT_QUIET_MS,\n DEFAULT_ROUND_STABILITY_WAIT_TIMEOUT_MS,\n} from \"./constants.js\";\nimport {\n buildTaskArray,\n collectMissingTask,\n deriveNextInstruction,\n extractHashSelectorRef,\n getToolAction,\n normalizeModelOutput,\n parseSnapshotExpandHints,\n reduceRemainingHeuristically,\n shouldForceRoundBreak,\n isPotentialDomMutation,\n sleep,\n toContentString,\n hasToolError,\n} from \"./helpers.js\";\nimport { readPageSnapshot, stripSnapshotFromPrompt } from \"./snapshot.js\";\nimport { buildCompactMessages } from \"./messages.js\";\nimport {\n checkRedundantSnapshot,\n applySnapshotDebounce,\n handleElementRecovery,\n handleNavigationUrlChange,\n detectIdleLoop,\n} from \"./recovery.js\";\nimport type {\n AgentLoopParams,\n AgentLoopResult,\n AgentLoopMetrics,\n PageContextState,\n ToolTraceEntry,\n} from \"./types.js\";\nimport type { AIMessage } from \"../types.js\";\n\n/**\n * 执行 Agent 循环。\n *\n * 你可以把这个函数理解成“任务执行调度器”:\n * - 输入:用户任务、系统提示词、工具注册表、历史消息、初始快照\n * - 过程:按轮次持续执行“看页面 -> 让模型决策 -> 跑工具 -> 更新上下文”\n * - 输出:最终回复、完整工具调用记录、可复用消息、结构化指标\n *\n * 每轮主流程(固定顺序):\n * 1) Ensure Snapshot:确保当前有最新快照(必要时读取)\n * 2) Build Messages:构建紧凑上下文(remaining + 上轮轨迹 + 最新快照)\n * 3) Call AI:请求模型并解析协议字段(`REMAINING` / `SNAPSHOT_HINT`)\n * 4) Execute Tools:执行工具调用并应用保护机制(冗余拦截、恢复、导航刷新)\n * 5) Reduce Remaining:推进剩余任务(优先协议,缺失时启发式剔除)\n * 6) Guard & Refresh:防空转/防自转判定,并刷新快照进入下一轮\n *\n * 核心状态语义:\n * - `remainingInstruction`:当前轮还未消费完的任务文本\n * - `previousRoundTasks`:上一轮已执行动作,防止模型原样重复\n * - `previousRoundPlannedTasks`:上一轮模型计划,用于重复批次检测\n * - `protocolViolationHint`:协议修复提示(remaining 未完成却无工具调用时注入)\n *\n * 停机条件(命中任意一条即结束):\n * - 模型无工具调用且 remaining 已收敛(`REMAINING: DONE` 或空)\n * - 协议修复后仍无推进\n * - 连续只读轮次(防空转)\n * - 连续重复计划批次(防自转)\n * - 达到 `maxRounds`\n */\nexport async function executeAgentLoop(\n params: AgentLoopParams,\n): Promise<AgentLoopResult> {\n const {\n client,\n registry,\n systemPrompt,\n message,\n initialSnapshot,\n history,\n dryRun = false,\n maxRounds = DEFAULT_MAX_ROUNDS,\n roundStabilityWait,\n callbacks,\n } = params;\n\n // 固定依赖与运行态容器\n const tools = registry.getDefinitions();\n const allToolCalls: AgentLoopResult[\"toolCalls\"] = [];\n const fullToolTrace: ToolTraceEntry[] = [];\n const actionRecoveryAttempts = new Map<string, number>();\n const pageContext: PageContextState = {\n latestSnapshot: initialSnapshot,\n };\n\n // 最终输出\n let finalReply = \"\";\n\n // 循环控制状态\n let consecutiveSnapshotCalls = 0;\n let consecutiveReadOnlyRounds = 0;\n let consecutiveNoProtocolRounds = 0;\n let usedRounds = 0;\n\n // token 统计\n let inputTokens = 0;\n let outputTokens = 0;\n // 渐进式任务状态\n // remainingInstruction: 当前轮次要继续消费的剩余文本。\n // previousRoundTasks: 上一轮已经执行过的任务数组,用于提醒 AI 不要原样重复。\n // lastPlannedBatchKey + consecutiveSamePlannedBatch: 防止 AI 连续给出相同任务批次导致自转。\n // lastRoundHadError: 如果上一轮有错误,不触发“重复批次即停机”,避免误停。\n let remainingInstruction = message.trim();\n let previousRoundTasks: string[] = [];\n let previousRoundPlannedTasks: string[] = [];\n let previousRoundModelOutput = \"\";\n let lastPlannedBatchKey = \"\";\n let consecutiveSamePlannedBatch = 0;\n let lastRoundHadError = false;\n let protocolViolationHint: string | undefined;\n const snapshotExpandRefIds = new Set<string>();\n const effectiveRoundStabilityWait = {\n enabled: roundStabilityWait?.enabled ?? true,\n timeoutMs: Math.max(200, Math.floor(roundStabilityWait?.timeoutMs ?? DEFAULT_ROUND_STABILITY_WAIT_TIMEOUT_MS)),\n quietMs: Math.max(50, Math.floor(roundStabilityWait?.quietMs ?? DEFAULT_ROUND_STABILITY_WAIT_QUIET_MS)),\n loadingSelectors: [\n ...new Set(\n [\n ...DEFAULT_ROUND_STABILITY_WAIT_LOADING_SELECTORS,\n ...(roundStabilityWait?.loadingSelectors ?? []),\n ]\n .map(selector => selector.trim())\n .filter(Boolean),\n ),\n ],\n };\n // 恢复与拦截统计\n let recoveryCount = 0;\n let redundantInterceptCount = 0;\n\n type MissingToolTask = {\n name: string;\n input: unknown;\n reason: string;\n };\n\n let pendingNotFoundRetry:\n | {\n attempt: number;\n tasks: MissingToolTask[];\n }\n | undefined;\n\n // 快照体积统计\n let snapshotReadCount = 0;\n let snapshotSizeTotal = 0;\n let snapshotSizeMax = 0;\n\n /**\n * 记录快照统计。\n *\n * 用于输出可观测指标:读取次数、平均长度、最大长度。\n * Used for observability metrics: read count, avg size, max size.\n */\n const recordSnapshotStats = (snapshot: string | undefined): void => {\n if (typeof snapshot !== \"string\") return;\n snapshotReadCount += 1;\n snapshotSizeTotal += snapshot.length;\n if (snapshot.length > snapshotSizeMax) snapshotSizeMax = snapshot.length;\n };\n\n /**\n * 刷新页面快照。\n *\n * 只做两件事:读取最新快照 + 更新快照统计。\n * Does exactly two things: read latest snapshot + update metrics.\n */\n const refreshSnapshot = async (): Promise<void> => {\n pageContext.latestSnapshot = await readPageSnapshot(\n registry,\n snapshotExpandRefIds.size > 0\n ? { expandChildrenRefs: Array.from(snapshotExpandRefIds), expandedChildrenLimit: 120 }\n : undefined,\n );\n recordSnapshotStats(pageContext.latestSnapshot);\n };\n\n /**\n * 轮次后稳定等待(双重等待)。\n *\n * 顺序固定为:\n * 1) 等待 loading 指示器隐藏\n * 2) 等待 DOM quiet window\n */\n const runRoundStabilityBarrier = async (): Promise<void> => {\n if (!effectiveRoundStabilityWait.enabled) return;\n if (!registry.has(\"wait\")) return;\n\n const timeout = effectiveRoundStabilityWait.timeoutMs;\n const loadingSelector = effectiveRoundStabilityWait.loadingSelectors.join(\", \");\n\n if (loadingSelector) {\n await registry.dispatch(\"wait\", {\n action: \"wait_for_selector\",\n selector: loadingSelector,\n state: \"hidden\",\n timeout,\n });\n }\n\n await registry.dispatch(\"wait\", {\n action: \"wait_for_stable\",\n timeout,\n quietMs: effectiveRoundStabilityWait.quietMs,\n });\n };\n\n\n if (pageContext.latestSnapshot) {\n recordSnapshotStats(pageContext.latestSnapshot);\n }\n\n /**\n * 追加工具轨迹。\n *\n * 同时写入:\n * - allToolCalls:对外返回结果\n * - fullToolTrace:下一轮消息上下文\n */\n const appendToolTrace = (\n round: number,\n name: string,\n input: unknown,\n result: AgentLoopResult[\"toolCalls\"][number][\"result\"],\n ): void => {\n allToolCalls.push({ name, input, result });\n fullToolTrace.push({ round, name, input, result });\n };\n\n // 主循环\n for (let round = 0; round < maxRounds; round++) {\n callbacks?.onRound?.(round);\n usedRounds = round + 1;\n\n // ═══ 阶段 1:确保快照 ═══\n if (!pageContext.latestSnapshot) {\n await refreshSnapshot();\n }\n\n // ═══ 阶段 2:构建紧凑消息 ═══\n // 每轮消息都自带快照(buildCompactMessages 注入),因此始终剥离\n // system prompt 中的旧快照,避免重复。\n const effectivePrompt = stripSnapshotFromPrompt(systemPrompt);\n\n const chatMessages = buildCompactMessages(\n message,\n fullToolTrace,\n pageContext.latestSnapshot,\n pageContext.currentUrl,\n history,\n remainingInstruction,\n previousRoundTasks,\n previousRoundModelOutput,\n previousRoundPlannedTasks,\n protocolViolationHint,\n );\n\n if (pendingNotFoundRetry && pendingNotFoundRetry.tasks.length > 0) {\n chatMessages.push({\n role: \"user\",\n content: [\n \"## Not-found retry context\",\n `Retry attempt: ${pendingNotFoundRetry.attempt}/${DEFAULT_NOT_FOUND_RETRY_ROUNDS}`,\n \"These tool targets were not found in previous execution:\",\n ...pendingNotFoundRetry.tasks.map((task, i) =>\n `${i + 1}. ${task.name}(${JSON.stringify(task.input)}) -> ${task.reason}`,\n ),\n \"Only retry unresolved targets that are now visible in the latest snapshot.\",\n \"If still not found, return no tool calls and include REMAINING with the unresolved part.\",\n ].join(\"\\n\"),\n });\n }\n\n // ═══ 阶段 3:调用 AI ═══\n const response = await client.chat({\n systemPrompt: effectivePrompt,\n messages: chatMessages,\n tools,\n });\n\n // 计费/观测数据累计\n inputTokens += response.usage?.inputTokens ?? 0;\n outputTokens += response.usage?.outputTokens ?? 0;\n\n // 先解析协议,最终推进在本轮执行后统一决定。\n const parsedInstructionState = deriveNextInstruction(response.text, remainingInstruction);\n const snapshotHintRefs = parseSnapshotExpandHints(response.text);\n for (const ref of snapshotHintRefs.slice(0, 8)) {\n snapshotExpandRefIds.add(ref);\n }\n\n // 没有工具调用:若处于找不到重试流程,先等待再重试;否则正常结束\n if (!response.toolCalls || response.toolCalls.length === 0) {\n consecutiveNoProtocolRounds = 0; // 非工具轮打断协议缺失计数\n if (pendingNotFoundRetry) {\n const unresolvedHint = response.text?.toLowerCase() ?? \"\";\n const stillUnresolved =\n unresolvedHint.includes(\"找不到\") ||\n unresolvedHint.includes(\"未找到\") ||\n unresolvedHint.includes(\"not found\") ||\n unresolvedHint.includes(\"cannot find\") ||\n unresolvedHint.includes(\"unable to locate\");\n\n if (stillUnresolved && pendingNotFoundRetry.attempt < DEFAULT_NOT_FOUND_RETRY_ROUNDS) {\n pendingNotFoundRetry = {\n ...pendingNotFoundRetry,\n attempt: pendingNotFoundRetry.attempt + 1,\n };\n callbacks?.onText?.(\n `未命中目标,准备第 ${pendingNotFoundRetry.attempt} 次重试(等待 ${DEFAULT_NOT_FOUND_RETRY_WAIT_MS}ms)...`,\n );\n await sleep(DEFAULT_NOT_FOUND_RETRY_WAIT_MS);\n await refreshSnapshot();\n continue;\n }\n pendingNotFoundRetry = undefined;\n }\n\n if (parsedInstructionState.hasRemainingProtocol) {\n remainingInstruction = parsedInstructionState.nextInstruction;\n }\n\n const unresolvedRemaining = remainingInstruction.trim().length > 0;\n if (unresolvedRemaining && round < maxRounds - 1) {\n protocolViolationHint = [\n \"Protocol violation in previous round:\",\n \"- Remaining task is not DONE, but no tool calls were returned.\",\n \"This round MUST do one of:\",\n \"1) Return actionable tool calls for visible targets; or\",\n \"2) If truly complete, return a short summary and EXACTLY `REMAINING: DONE`.\",\n \"Do NOT output planning/explaining text.\",\n ].join(\"\\n\");\n lastRoundHadError = true;\n await refreshSnapshot();\n continue;\n }\n\n finalReply = response.text ?? \"\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n\n protocolViolationHint = undefined;\n const plannedTasksCurrentRound = buildTaskArray(\n response.toolCalls.map(tc => ({ name: tc.name, input: tc.input })),\n );\n\n const plannedBatchKey = JSON.stringify(\n response.toolCalls.map(tc => ({ name: tc.name, input: tc.input })),\n );\n // 比较“本轮计划”与“上一轮计划”是否完全一致。\n if (plannedBatchKey === lastPlannedBatchKey) {\n consecutiveSamePlannedBatch += 1;\n } else {\n consecutiveSamePlannedBatch = 1;\n lastPlannedBatchKey = plannedBatchKey;\n }\n\n // 防自转:连续两轮给出相同计划且上一轮无错误,判定任务已完成或模型卡住,直接结束。\n if (consecutiveSamePlannedBatch >= 2 && !lastRoundHadError) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n\n // ─── Dry-run 模式 ───\n if (dryRun) {\n finalReply = response.text ? response.text + \"\\n\\n\" : \"\";\n finalReply += \"🔧 AI 请求调用以下工具(dry-run 模式,未执行):\\n\";\n for (const tc of response.toolCalls) {\n callbacks?.onToolCall?.(tc.name, tc.input);\n finalReply += `\\n┌─ 工具: ${tc.name}\\n`;\n finalReply += `│ ID: ${tc.id}\\n`;\n finalReply += `│ 参数:\\n`;\n const inputStr = JSON.stringify(tc.input, null, 2);\n for (const line of inputStr.split(\"\\n\")) {\n finalReply += `│ ${line}\\n`;\n }\n finalReply += `└────────────────────\\n`;\n }\n break;\n }\n\n // ═══ 阶段 4:执行工具调用(带保护机制)═══\n\n // 批量执行所有工具调用\n // roundHasError 用于控制“重复批次停机”:上一轮有错误时,不应武断终止。\n let roundHasError = false;\n let roundHasPotentialDomMutation = false;\n const executedTaskCalls: Array<{ name: string; input: unknown }> = [];\n const roundMissingTasks: MissingToolTask[] = [];\n for (const tc of response.toolCalls) {\n\n // 自动策略:当 AI 对 hash 列表执行 scroll 时,默认下一轮对该节点放宽 children 截断。\n // 这样即使模型未显式输出 SNAPSHOT_HINT,也能尽快拿到完整列表选项。\n if (tc.name === \"dom\" && getToolAction(tc.input) === \"scroll\") {\n const ref = extractHashSelectorRef(tc.input);\n if (ref) snapshotExpandRefIds.add(ref);\n }\n\n // 保护 1:冗余快照拦截\n const redundant = checkRedundantSnapshot(\n tc.name, tc.input, pageContext.latestSnapshot, round,\n );\n if (redundant) {\n appendToolTrace(round, tc.name, tc.input, redundant);\n redundantInterceptCount += 1;\n callbacks?.onToolResult?.(tc.name, redundant);\n continue;\n }\n\n callbacks?.onToolCall?.(tc.name, tc.input);\n\n // 执行工具\n let result = await registry.dispatch(tc.name, tc.input);\n\n // 保护 2:连续快照防抖\n const debounced = applySnapshotDebounce(\n tc.name, tc.input, result, consecutiveSnapshotCalls,\n );\n result = debounced.result;\n consecutiveSnapshotCalls = debounced.consecutiveCount;\n\n // 保护 3:元素未找到自动恢复\n const recovered = await handleElementRecovery(\n tc.name, tc.input, result,\n actionRecoveryAttempts, registry, pageContext, callbacks,\n );\n if (recovered) result = recovered;\n if (\n recovered?.details &&\n typeof recovered.details === \"object\" &&\n (recovered.details as { code?: unknown }).code === \"ELEMENT_NOT_FOUND_RECOVERY\"\n ) {\n recoveryCount += 1;\n }\n\n appendToolTrace(round, tc.name, tc.input, result);\n executedTaskCalls.push({ name: tc.name, input: tc.input });\n\n const missingTask = collectMissingTask(tc.name, tc.input, result);\n if (missingTask) {\n roundMissingTasks.push(missingTask);\n }\n\n if (result.details && typeof result.details === \"object\") {\n roundHasError = roundHasError || Boolean((result.details as { error?: unknown }).error);\n }\n if (!hasToolError(result) && isPotentialDomMutation(tc.name, tc.input)) {\n roundHasPotentialDomMutation = true;\n }\n\n // 捕获显式 snapshot 结果\n if (tc.name === \"page_info\" && getToolAction(tc.input) === \"snapshot\") {\n pageContext.latestSnapshot = toContentString(result.content);\n recordSnapshotStats(pageContext.latestSnapshot);\n }\n\n // 保护 4:导航后 URL 变化检测\n await handleNavigationUrlChange(\n tc.name, tc.input, result, registry, pageContext, callbacks,\n );\n\n callbacks?.onToolResult?.(tc.name, result);\n\n if (shouldForceRoundBreak(tc.name, tc.input)) {\n break;\n }\n }\n\n if (roundMissingTasks.length > 0) {\n pendingNotFoundRetry = {\n attempt: 1,\n tasks: roundMissingTasks,\n };\n } else {\n pendingNotFoundRetry = undefined;\n }\n\n // 将本轮执行状态传给下一轮上下文。\n if (parsedInstructionState.hasRemainingProtocol) {\n remainingInstruction = parsedInstructionState.nextInstruction;\n consecutiveNoProtocolRounds = 0;\n } else {\n const nextByHeuristic = reduceRemainingHeuristically(remainingInstruction, executedTaskCalls.length);\n if (nextByHeuristic !== remainingInstruction) {\n remainingInstruction = nextByHeuristic;\n consecutiveNoProtocolRounds = 0;\n } else if (executedTaskCalls.length > 0) {\n // 模型执行了工具但未遵循 REMAINING 协议且启发式无法推进。\n // 若本轮有成功的 DOM 变更(click/fill 等),说明任务在实质推进,\n // 不累计协议缺失计数,避免因模型不遵循 REMAINING 协议而过早停机。\n // 仅在本轮全部失败或无 DOM 变更时才累计,防止真正的空转。\n if (!roundHasPotentialDomMutation || roundHasError) {\n consecutiveNoProtocolRounds += 1;\n }\n }\n }\n\n previousRoundModelOutput = parsedInstructionState.hasRemainingProtocol\n ? normalizeModelOutput(response.text)\n : `REMAINING: ${remainingInstruction || \"DONE\"}`;\n\n lastRoundHadError = roundHasError;\n previousRoundTasks = buildTaskArray(executedTaskCalls);\n previousRoundPlannedTasks = plannedTasksCurrentRound;\n\n // 协议显式 DONE 且本轮已完成执行且无错误:直接收敛,避免后续重复动作。\n if (\n parsedInstructionState.hasRemainingProtocol &&\n remainingInstruction.trim().length === 0 &&\n !roundHasError\n ) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n\n // 保护 5:防协议缺失空转 — 连续多轮有工具调用但无 REMAINING 协议且启发式无法推进\n if (consecutiveNoProtocolRounds >= 3) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n if (consecutiveNoProtocolRounds >= 2) {\n protocolViolationHint = [\n \"Protocol reminder: REMAINING protocol missing for 2+ rounds with tool calls.\",\n \"You MUST include REMAINING: <text> or REMAINING: DONE in every response.\",\n \"If the task is fully complete, return REMAINING: DONE with no tool calls.\",\n ].join(\"\\n\");\n }\n\n // 保护 6:空转检测\n const attemptedTaskCalls = response.toolCalls.map(tc => ({ name: tc.name, input: tc.input }));\n const idleResult = detectIdleLoop(attemptedTaskCalls, consecutiveReadOnlyRounds);\n if (idleResult === -1) {\n finalReply = response.text?.trim() || \"任务已完成。\";\n if (finalReply) callbacks?.onText?.(finalReply);\n break;\n }\n consecutiveReadOnlyRounds = idleResult;\n\n if (roundHasPotentialDomMutation) {\n await runRoundStabilityBarrier();\n }\n\n // ═══ 阶段 5:刷新快照(供下一轮使用)═══\n await refreshSnapshot();\n }\n\n // 构建紧凑的 result.messages 供多轮记忆使用\n // Build compact result.messages for optional multi-turn memory reuse.\n const resultMessages: AIMessage[] = [...(history ?? []), { role: \"user\", content: message }];\n if (finalReply) {\n resultMessages.push({ role: \"assistant\", content: finalReply });\n }\n\n // 结果统计\n const successfulToolCalls = allToolCalls.filter(tc => {\n const details = tc.result.details;\n return !(details && typeof details === \"object\" && Boolean((details as { error?: unknown }).error));\n }).length;\n const failedToolCalls = allToolCalls.length - successfulToolCalls;\n\n const metrics: AgentLoopMetrics = {\n roundCount: usedRounds,\n totalToolCalls: allToolCalls.length,\n successfulToolCalls,\n failedToolCalls,\n toolSuccessRate: allToolCalls.length > 0\n ? Number((successfulToolCalls / allToolCalls.length).toFixed(4))\n : 1,\n recoveryCount,\n redundantInterceptCount,\n snapshotReadCount,\n latestSnapshotSize: pageContext.latestSnapshot?.length ?? 0,\n avgSnapshotSize: snapshotReadCount > 0 ? Math.round(snapshotSizeTotal / snapshotReadCount) : 0,\n maxSnapshotSize: snapshotSizeMax,\n inputTokens,\n outputTokens,\n };\n\n // 统一发出指标回调\n callbacks?.onMetrics?.(metrics);\n\n return { reply: finalReply, toolCalls: allToolCalls, messages: resultMessages, metrics };\n}\n\n// ─── Re-exports(维持外部 API 不变)───\nexport { wrapSnapshot } from \"./snapshot.js\";\nexport type {\n AgentLoopParams,\n AgentLoopResult,\n AgentLoopCallbacks,\n AgentLoopMetrics,\n RoundStabilityWaitOptions,\n} from \"./types.js\";\n","/**\n * AI Client 共享常量(中)/ Shared constants and helpers for AI clients (EN).\n */\nimport type { AIClientConfig } from \"./index.js\";\n\n// ─── Provider 端点映射 ───\n\n/** 默认端点映射(中)/ Default API endpoints by provider (EN). */\nexport const PROVIDER_ENDPOINTS: Record<string, string> = {\n openai: \"https://api.openai.com/v1\",\n copilot: \"https://models.inference.ai.azure.com\",\n anthropic: \"https://api.anthropic.com\",\n deepseek: \"https://api.deepseek.com\",\n doubao: \"https://ark.cn-beijing.volces.com/api/v3\",\n qwen: \"https://dashscope.aliyuncs.com/compatible-mode/v1\",\n minimax: \"https://api.minimaxi.com/v1\",\n};\n\n// ─── 共享工具函数 ───\n\n/** 校验 provider(中)/ Validate provider support (EN). */\nexport function validateProvider(provider: string): void {\n if (!PROVIDER_ENDPOINTS[provider]) {\n const supported = Object.keys(PROVIDER_ENDPOINTS).join(\", \");\n throw new Error(\n `Unknown AI provider: ${provider}. Supported: ${supported}`,\n );\n }\n}\n\n/** 解析 baseURL(中)/ Resolve API base URL (EN). */\nexport function resolveBaseURL(config: AIClientConfig): string {\n return config.baseURL ?? PROVIDER_ENDPOINTS[config.provider] ?? \"\";\n}\n\n/**\n * 清理 schema(中)/ Clean non-serializable fields from schema (EN).\n */\nexport function cleanSchema(schema: unknown): unknown {\n return JSON.parse(JSON.stringify(schema));\n}\n","/** SSE 事件处理器(中)/ SSE JSON event handler (EN). Return false to stop early. */\nexport type SSEJSONHandler = (\n event: Record<string, unknown>,\n meta: { event?: string; rawData: string },\n) => void | boolean | Promise<void | boolean>;\n\n/** SSE 配置(中)/ SSE consume options (EN). */\nexport type SSEConsumeOptions = {\n /** 单次读取超时(毫秒)。不传则不超时。 */\n readTimeoutMs?: number;\n /** 是否在遇到 [DONE] 时提前结束(默认 true)。 */\n stopOnDone?: boolean;\n};\n\n/**\n * 通用 SSE(JSON) 消费器(中)/ Generic SSE(JSON) consumer (EN).\n *\n * 读取 response.body,按 SSE 规则拼装并分发 JSON data 事件。\n * Reads response body, assembles SSE frames, and dispatches JSON data events.\n */\nexport async function consumeSSEJSON(\n response: Response,\n onEvent: SSEJSONHandler,\n options: SSEConsumeOptions = {},\n): Promise<void> {\n if (!response.body) return;\n\n const reader = response.body.getReader();\n const decoder = new TextDecoder();\n const stopOnDone = options.stopOnDone ?? true;\n\n let buffer = \"\";\n let currentEvent: string | undefined;\n let dataLines: string[] = [];\n let stoppedByDone = false;\n\n async function readChunk() {\n const readTimeoutMs = options.readTimeoutMs;\n if (!readTimeoutMs || readTimeoutMs <= 0) {\n return reader.read();\n }\n\n return new Promise<ReadableStreamReadResult<Uint8Array>>((resolve, reject) => {\n const timer = setTimeout(() => {\n reject(new Error(`SSE read timeout (${readTimeoutMs}ms)`));\n }, readTimeoutMs);\n\n reader.read().then(\n (value) => {\n clearTimeout(timer);\n resolve(value);\n },\n (error) => {\n clearTimeout(timer);\n reject(error);\n },\n );\n });\n }\n\n async function flushEvent(): Promise<boolean> {\n if (dataLines.length === 0) {\n currentEvent = undefined;\n return true;\n }\n\n const rawData = dataLines.join(\"\\n\").trim();\n const event = currentEvent;\n dataLines = [];\n currentEvent = undefined;\n\n if (!rawData) return true;\n if (stopOnDone && rawData === \"[DONE]\") {\n stoppedByDone = true;\n return false;\n }\n\n try {\n const parsed = JSON.parse(rawData) as Record<string, unknown>;\n const shouldContinue = await onEvent(parsed, { event, rawData });\n if (shouldContinue === false) return false;\n } catch {\n // 非 JSON data 事件忽略\n }\n\n return true;\n }\n\n while (true) {\n const { done, value } = await readChunk();\n if (done) break;\n\n buffer += decoder.decode(value, { stream: true });\n\n const lines = buffer.split(\"\\n\");\n buffer = lines.pop() ?? \"\";\n\n for (const rawLine of lines) {\n const line = rawLine.endsWith(\"\\r\") ? rawLine.slice(0, -1) : rawLine;\n const trimmed = line.trim();\n\n if (!trimmed) {\n const shouldContinue = await flushEvent();\n if (!shouldContinue) break;\n continue;\n }\n if (trimmed.startsWith(\":\")) continue;\n if (trimmed.startsWith(\"event:\")) {\n currentEvent = trimmed.slice(6).trim() || undefined;\n continue;\n }\n if (trimmed.startsWith(\"data:\")) {\n dataLines.push(trimmed.slice(5).trimStart());\n }\n }\n\n if (stoppedByDone) break;\n }\n\n if (!stoppedByDone) {\n await flushEvent();\n } else {\n await reader.cancel().catch(() => undefined);\n }\n}\n","/**\n * 可继承 AI 客户端基类(中)/ Extensible base AI client class (EN).\n *\n * 支持注入 chatHandler 或子类覆写 chat。\n * Supports injected chatHandler or subclass override.\n */\nimport type { AIChatResponse, AIClient, AIMessage } from \"../types.js\";\nimport type { ToolDefinition } from \"../tool-registry.js\";\nimport {\n consumeSSEJSON,\n type SSEConsumeOptions,\n type SSEJSONHandler,\n} from \"./sse.js\";\n\n// ─── 类型定义 ───\n\n/** chat 入参(中)/ Chat handler params aligned with AIClient.chat (EN). */\nexport type ChatHandlerParams = {\n /** 系统提示词 */\n systemPrompt: string;\n /** 对话消息列表 */\n messages: AIMessage[];\n /** 可用工具定义列表 */\n tools?: ToolDefinition[];\n};\n\n/** BaseAIClient 选项(中)/ BaseAIClient constructor options (EN). */\nexport type BaseAIClientOptions = {\n /** 对话处理函数 — 接收 ChatHandlerParams,返回 AIChatResponse */\n chatHandler: (params: ChatHandlerParams) => Promise<AIChatResponse>;\n};\n\nexport {\n consumeSSEJSON,\n type SSEConsumeOptions,\n type SSEJSONHandler,\n} from \"./sse.js\";\n\n// ─── BaseAIClient 类 ───\n\n/**\n * BaseAIClient 实现(中)/ BaseAIClient implementation of AIClient (EN).\n */\nexport class BaseAIClient implements AIClient {\n /** 用户提供的对话处理函数 */\n protected chatHandler: (params: ChatHandlerParams) => Promise<AIChatResponse>;\n\n constructor(options: BaseAIClientOptions) {\n this.chatHandler = options.chatHandler;\n }\n\n /**\n * 发送对话请求(中)/ Dispatch chat request via handler (EN).\n */\n async chat(params: ChatHandlerParams): Promise<AIChatResponse> {\n return this.chatHandler(params);\n }\n\n /** SSE 消费复用入口(中)/ Reusable SSE(JSON) consumer for subclasses (EN). */\n protected async consumeSSEJSON(\n response: Response,\n onEvent: SSEJSONHandler,\n options?: SSEConsumeOptions,\n ): Promise<void> {\n return consumeSSEJSON(response, onEvent, options);\n }\n}\n","/**\n * OpenAI/Copilot 客户端(中)/ OpenAI-compatible client implementation (EN).\n */\nimport type { AIChatResponse, AIMessage, AIToolCall } from \"../types.js\";\nimport type { AIClientConfig, ChatParams, ChatRequestInit } from \"./index.js\";\nimport { BaseAIClient } from \"./custom.js\";\nimport type { ChatHandlerParams } from \"./custom.js\";\nimport { consumeSSEJSON } from \"./sse.js\";\nimport { resolveBaseURL, cleanSchema } from \"./constants.js\";\n\n// ─── OpenAI 原始 API 响应类型 ───\n\n/** OpenAI 工具调用原始类型(中)/ Raw OpenAI tool_call shape (EN). */\ntype OpenAIRawToolCall = {\n id: string;\n type: \"function\";\n function: { name: string; arguments: string };\n};\n\n/** OpenAI 原始响应类型(中)/ Raw OpenAI chat completion response (EN). */\ntype OpenAIRawResponse = {\n choices?: Array<{\n message: {\n content: string | null;\n tool_calls?: OpenAIRawToolCall[];\n };\n }>;\n usage?: {\n prompt_tokens?: number;\n completion_tokens?: number;\n };\n};\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 45000;\nconst JSON_TIMEOUT_RETRY_COUNT = 1;\n\nfunction isRequestTimeoutError(error: unknown): boolean {\n return error instanceof Error && /^AI request timeout \\(\\d+ms\\)$/.test(error.message);\n}\n\nasync function fetchWithTimeout(\n input: RequestInfo | URL,\n init: RequestInit,\n timeoutMs: number,\n): Promise<Response> {\n if (!Number.isFinite(timeoutMs) || timeoutMs <= 0) {\n return fetch(input, init);\n }\n\n const controller = new AbortController();\n const timer = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n return await fetch(input, {\n ...init,\n signal: controller.signal,\n });\n } catch (error) {\n if (error instanceof Error && error.name === \"AbortError\") {\n throw new Error(`AI request timeout (${timeoutMs}ms)`);\n }\n throw error;\n } finally {\n clearTimeout(timer);\n }\n}\n\n// ─── OpenAIClient 类 ───\n\n/**\n * OpenAIClient 类(中)/ OpenAIClient class for OpenAI & Copilot (EN).\n */\nexport class OpenAIClient extends BaseAIClient {\n /** AI 客户端配置(provider / model / apiKey / baseURL) */\n protected config: AIClientConfig;\n\n constructor(config: AIClientConfig) {\n // 注入 chatHandler — 根据 config.stream 选择流式或 JSON(默认流式)\n super({\n chatHandler: async (params: ChatHandlerParams): Promise<AIChatResponse> => {\n const req = buildOpenAIRequest(this.config, params);\n const useStream = this.config.stream ?? true;\n const requestTimeoutMs = this.config.requestTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n if (!useStream) {\n let lastError: unknown;\n\n for (let attempt = 0; attempt <= JSON_TIMEOUT_RETRY_COUNT; attempt++) {\n try {\n const res = await fetchWithTimeout(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n }, requestTimeoutMs);\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`AI API ${res.status}: ${errText.slice(0, 500)}`);\n }\n\n const data = await res.json();\n return parseOpenAIResponse(data);\n } catch (error) {\n lastError = error;\n const shouldRetry = attempt < JSON_TIMEOUT_RETRY_COUNT && isRequestTimeoutError(error);\n if (!shouldRetry) throw error;\n }\n }\n\n throw lastError instanceof Error ? lastError : new Error(\"AI request failed\");\n }\n\n // 流式模式:请求体已在 buildOpenAIRequest 中包含 stream 字段\n const streamRes = await fetchWithTimeout(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n }, requestTimeoutMs);\n\n if (!streamRes.ok) {\n const errText = await streamRes.text();\n throw new Error(`AI API ${streamRes.status}: ${errText.slice(0, 500)}`);\n }\n\n const contentType = streamRes.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n const data = await streamRes.json();\n return parseOpenAIResponse(data);\n }\n\n return parseOpenAIStream(streamRes, 20000);\n },\n });\n this.config = config;\n }\n}\n\n// ─── 底层 API:请求构建 ───\n\n/**\n * 构建 OpenAI 请求(中)/ Build OpenAI chat request payload (EN).\n */\nexport function buildOpenAIRequest(\n config: AIClientConfig,\n params: ChatParams,\n): ChatRequestInit {\n const baseURL = resolveBaseURL(config);\n const { systemPrompt, messages, tools } = params;\n\n // 转换工具定义为 OpenAI function calling 格式\n const openaiTools = tools?.map((t) => ({\n type: \"function\" as const,\n function: {\n name: t.name,\n description: t.description,\n parameters: cleanSchema(t.schema),\n },\n }));\n\n // 转换消息为 OpenAI 格式\n const openaiMessages = convertMessages(systemPrompt, messages);\n\n // 构建请求体\n const body: Record<string, unknown> = {\n model: config.model,\n messages: openaiMessages,\n temperature: 0.3,\n max_tokens: 4096,\n };\n\n if (config.stream ?? true) {\n body.stream = true;\n body.stream_options = { include_usage: true };\n }\n\n if (openaiTools && openaiTools.length > 0) {\n body.tools = openaiTools;\n body.tool_choice = \"auto\";\n body.parallel_tool_calls = config.parallelToolCalls ?? true;\n }\n\n return {\n url: `${baseURL}/chat/completions`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n Authorization: `Bearer ${config.apiKey}`,\n },\n body: JSON.stringify(body),\n };\n}\n\n// ─── 响应解析 ───\n\n/**\n * 解析 OpenAI 响应(中)/ Parse raw OpenAI response into AIChatResponse (EN).\n */\nexport function parseOpenAIResponse(data: unknown): AIChatResponse {\n const d = data as OpenAIRawResponse;\n const choice = d.choices?.[0];\n if (!choice) throw new Error(\"AI 未返回有效响应\");\n\n const msg = choice.message;\n\n // 解析工具调用:arguments 是 JSON 字符串,需要 parse 为对象\n const toolCalls: AIToolCall[] | undefined = msg.tool_calls?.map((tc) => ({\n id: tc.id,\n name: tc.function.name,\n input: JSON.parse(tc.function.arguments),\n }));\n\n return {\n text: msg.content || undefined,\n toolCalls: toolCalls?.length ? toolCalls : undefined,\n usage: d.usage\n ? {\n inputTokens: d.usage.prompt_tokens ?? 0,\n outputTokens: d.usage.completion_tokens ?? 0,\n }\n : undefined,\n };\n}\n\n// ─── 内部辅助函数 ───\n\n/**\n * 消息转换(中)/ Convert unified messages to OpenAI format (EN).\n */\nfunction convertMessages(\n systemPrompt: string,\n messages: AIMessage[],\n): Record<string, unknown>[] {\n const result: Record<string, unknown>[] = [\n { role: \"system\", content: systemPrompt },\n ];\n\n for (const m of messages) {\n if (m.role === \"tool\" && Array.isArray(m.content)) {\n // 工具结果 → 每个结果单独一条 tool 消息(OpenAI 要求按 tool_call_id 对应)\n for (const tc of m.content) {\n result.push({\n role: \"tool\",\n content: tc.result,\n tool_call_id: tc.toolCallId,\n });\n }\n } else if (m.role === \"assistant\" && m.toolCalls?.length) {\n // AI 回复含工具调用 → 带 tool_calls 字段\n result.push({\n role: \"assistant\",\n content: typeof m.content === \"string\" ? m.content : null,\n tool_calls: m.toolCalls.map((tc) => ({\n id: tc.id,\n type: \"function\",\n function: {\n name: tc.name,\n arguments: JSON.stringify(tc.input),\n },\n })),\n });\n } else {\n // 普通消息(user / assistant 纯文本)\n result.push({\n role: m.role,\n content:\n typeof m.content === \"string\"\n ? m.content\n : JSON.stringify(m.content),\n });\n }\n }\n\n return result;\n}\n\n// ─── 流式响应解析 ───\n\n/** 流式 tool_call 增量类型(中)/ Tool-call delta type in SSE stream (EN). */\ntype OpenAIStreamToolCallDelta = {\n index: number;\n id?: string;\n function?: { name?: string; arguments?: string };\n};\n\n/** 流式 chunk 类型(中)/ SSE chunk type (EN). */\ntype OpenAIStreamChunk = {\n choices?: Array<{\n delta: {\n content?: string;\n tool_calls?: OpenAIStreamToolCallDelta[];\n };\n }>;\n usage?: { prompt_tokens?: number; completion_tokens?: number };\n};\n\n/**\n * 解析 OpenAI SSE(中)/ Parse OpenAI SSE stream into unified response (EN).\n */\nexport async function parseOpenAIStream(\n response: Response,\n readTimeoutMs = 20000,\n): Promise<AIChatResponse> {\n // 回退:无 ReadableStream 支持\n if (!response.body) {\n const data = await response.json();\n return parseOpenAIResponse(data);\n }\n\n let text = \"\";\n const toolCallMap = new Map<number, { id: string; name: string; arguments: string }>();\n let usage: AIChatResponse[\"usage\"];\n await consumeSSEJSON(\n response,\n (event) => {\n const chunk = event as OpenAIStreamChunk;\n const delta = chunk.choices?.[0]?.delta;\n\n if (delta?.content) text += delta.content;\n\n if (delta?.tool_calls) {\n for (const tc of delta.tool_calls) {\n const idx = tc.index ?? 0;\n const existing = toolCallMap.get(idx);\n if (existing) {\n if (tc.function?.arguments) existing.arguments += tc.function.arguments;\n } else {\n toolCallMap.set(idx, {\n id: tc.id ?? \"\",\n name: tc.function?.name ?? \"\",\n arguments: tc.function?.arguments ?? \"\",\n });\n }\n }\n }\n\n if (chunk.usage) {\n usage = {\n inputTokens: chunk.usage.prompt_tokens ?? 0,\n outputTokens: chunk.usage.completion_tokens ?? 0,\n };\n }\n },\n { readTimeoutMs, stopOnDone: true },\n );\n\n // 组装工具调用\n const toolCalls: AIToolCall[] = [];\n for (const [, tc] of [...toolCallMap.entries()].sort((a, b) => a[0] - b[0])) {\n try {\n toolCalls.push({ id: tc.id, name: tc.name, input: JSON.parse(tc.arguments) });\n } catch {\n // 工具参数 JSON 解析失败,跳过\n }\n }\n\n return {\n text: text || undefined,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage,\n };\n}\n","/**\n * Anthropic 客户端实现(中)/ Anthropic Messages API client implementation (EN).\n */\nimport type { AIChatResponse, AIMessage, AIToolCall } from \"../types.js\";\nimport type { AIClientConfig, ChatParams, ChatRequestInit } from \"./index.js\";\nimport { BaseAIClient } from \"./custom.js\";\nimport type { ChatHandlerParams } from \"./custom.js\";\nimport { consumeSSEJSON } from \"./sse.js\";\nimport { resolveBaseURL, cleanSchema } from \"./constants.js\";\n\n// ─── Anthropic 原始 API 响应类型 ───\n\n/** Anthropic 文本块(中)/ Anthropic text block (EN). */\ntype AnthropicTextBlock = {\n type: \"text\";\n text: string;\n};\n\n/** Anthropic 工具调用块(中)/ Anthropic tool_use block (EN). */\ntype AnthropicToolUseBlock = {\n type: \"tool_use\";\n id: string;\n name: string;\n input: unknown;\n};\n\n/** Anthropic 内容块联合类型(中)/ Anthropic content block union (EN). */\ntype AnthropicContentBlock = AnthropicTextBlock | AnthropicToolUseBlock;\n\n/** Anthropic 原始响应类型(中)/ Raw Anthropic response type (EN). */\ntype AnthropicRawResponse = {\n content?: AnthropicContentBlock[];\n usage?: {\n input_tokens: number;\n output_tokens: number;\n };\n};\n\n// ─── AnthropicClient 类 ───\n\n/**\n * AnthropicClient 类(中)/ AnthropicClient class (EN).\n */\nexport class AnthropicClient extends BaseAIClient {\n /** AI 客户端配置(provider / model / apiKey / baseURL) */\n protected config: AIClientConfig;\n\n constructor(config: AIClientConfig) {\n // 注入 chatHandler — 根据 config.stream 选择流式或 JSON(默认流式)\n super({\n chatHandler: async (params: ChatHandlerParams): Promise<AIChatResponse> => {\n const req = buildAnthropicRequest(this.config, params);\n const useStream = this.config.stream ?? true;\n\n if (!useStream) {\n const res = await fetch(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`AI API ${res.status}: ${errText.slice(0, 500)}`);\n }\n\n const data = await res.json();\n return parseAnthropicResponse(data);\n }\n\n // 流式模式:请求体已在 buildAnthropicRequest 中包含 stream 字段\n const res = await fetch(req.url, {\n method: req.method,\n headers: req.headers,\n body: req.body,\n });\n\n if (!res.ok) {\n const errText = await res.text();\n throw new Error(`AI API ${res.status}: ${errText.slice(0, 500)}`);\n }\n\n const contentType = res.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n const data = await res.json();\n return parseAnthropicResponse(data);\n }\n\n return parseAnthropicStream(res);\n },\n });\n this.config = config;\n }\n}\n\n// ─── 底层 API:请求构建 ───\n\n/**\n * 构建 Anthropic 请求(中)/ Build Anthropic Messages API request (EN).\n */\nexport function buildAnthropicRequest(\n config: AIClientConfig,\n params: ChatParams,\n): ChatRequestInit {\n const baseURL = resolveBaseURL(config);\n const { systemPrompt, messages, tools } = params;\n\n // 转换工具定义为 Anthropic 格式(input_schema 而非 parameters)\n const anthropicTools = tools?.map((t) => ({\n name: t.name,\n description: t.description,\n input_schema: cleanSchema(t.schema),\n }));\n\n // 转换消息为 Anthropic 格式(过滤掉 system 角色消息)\n const anthropicMessages = convertMessages(messages);\n\n // 构建请求体 — system 作为顶层字段\n const body: Record<string, unknown> = {\n model: config.model,\n max_tokens: config.model.includes(\"opus\") ? 16384 : 8192,\n system: systemPrompt,\n messages: anthropicMessages,\n };\n\n if (config.stream ?? true) {\n body.stream = true;\n }\n\n if (anthropicTools && anthropicTools.length > 0) {\n body.tools = anthropicTools;\n }\n\n return {\n url: `${baseURL}/v1/messages`,\n method: \"POST\",\n headers: {\n \"Content-Type\": \"application/json\",\n \"x-api-key\": config.apiKey,\n \"anthropic-version\": \"2023-06-01\",\n },\n body: JSON.stringify(body),\n };\n}\n\n// ─── 响应解析 ───\n\n/**\n * 解析 Anthropic 响应(中)/ Parse raw Anthropic response (EN).\n */\nexport function parseAnthropicResponse(data: unknown): AIChatResponse {\n const d = data as AnthropicRawResponse;\n\n // 提取所有文本块,合并为单个字符串\n const text = d.content\n ?.filter((b): b is AnthropicTextBlock => b.type === \"text\")\n .map((b) => b.text)\n .join(\"\");\n\n // 提取所有工具调用块\n const toolCalls: AIToolCall[] | undefined = d.content\n ?.filter((b): b is AnthropicToolUseBlock => b.type === \"tool_use\")\n .map((b) => ({\n id: b.id,\n name: b.name,\n input: b.input,\n }));\n\n return {\n text: text || undefined,\n toolCalls: toolCalls?.length ? toolCalls : undefined,\n usage: d.usage\n ? {\n inputTokens: d.usage.input_tokens,\n outputTokens: d.usage.output_tokens,\n }\n : undefined,\n };\n}\n\n// ─── 内部辅助函数 ───\n\n/**\n * 消息格式转换(中)/ Convert unified messages to Anthropic format (EN).\n */\nfunction convertMessages(\n messages: AIMessage[],\n): Record<string, unknown>[] {\n return messages\n .filter((m) => m.role !== \"system\")\n .map((m) => {\n if (m.role === \"tool\" && Array.isArray(m.content)) {\n // 工具结果 → Anthropic 用 user 角色 + tool_result content block\n return {\n role: \"user\" as const,\n content: m.content.map((tc) => ({\n type: \"tool_result\" as const,\n tool_use_id: tc.toolCallId,\n content: tc.result,\n })),\n };\n }\n if (m.role === \"assistant\" && m.toolCalls?.length) {\n // AI 回复含工具调用 → text block + tool_use blocks\n const content: Record<string, unknown>[] = [];\n if (m.content && typeof m.content === \"string\") {\n content.push({ type: \"text\", text: m.content });\n }\n for (const tc of m.toolCalls) {\n content.push({\n type: \"tool_use\",\n id: tc.id,\n name: tc.name,\n input: tc.input,\n });\n }\n return { role: \"assistant\" as const, content };\n }\n // 普通消息(user / assistant 纯文本)\n return {\n role: m.role as \"user\" | \"assistant\",\n content:\n typeof m.content === \"string\"\n ? m.content\n : JSON.stringify(m.content),\n };\n });\n}\n\n// ─── 流式响应解析 ───\n\n/**\n * 解析 Anthropic SSE(中)/ Parse Anthropic SSE stream (EN).\n */\nexport async function parseAnthropicStream(response: Response): Promise<AIChatResponse> {\n // 回退:无 ReadableStream 支持\n if (!response.body) {\n const data = await response.json();\n return parseAnthropicResponse(data);\n }\n\n let text = \"\";\n const toolCalls: AIToolCall[] = [];\n let currentToolUse: { id: string; name: string; inputJson: string } | null = null;\n let inputTokens = 0;\n let outputTokens = 0;\n await consumeSSEJSON(\n response,\n (event) => {\n switch (event.type) {\n case \"message_start\": {\n const msg = event.message as { usage?: { input_tokens?: number } } | undefined;\n inputTokens = msg?.usage?.input_tokens ?? 0;\n break;\n }\n\n case \"content_block_start\": {\n const block = event.content_block as { type: string; id?: string; name?: string } | undefined;\n if (block?.type === \"tool_use\") {\n currentToolUse = { id: block.id ?? \"\", name: block.name ?? \"\", inputJson: \"\" };\n }\n break;\n }\n\n case \"content_block_delta\": {\n const delta = event.delta as { type: string; text?: string; partial_json?: string } | undefined;\n if (delta?.type === \"text_delta\") {\n text += delta.text ?? \"\";\n } else if (delta?.type === \"input_json_delta\" && currentToolUse) {\n currentToolUse.inputJson += delta.partial_json ?? \"\";\n }\n break;\n }\n\n case \"content_block_stop\":\n if (currentToolUse) {\n try {\n toolCalls.push({\n id: currentToolUse.id,\n name: currentToolUse.name,\n input: JSON.parse(currentToolUse.inputJson || \"{}\"),\n });\n } catch {\n // 工具参数 JSON 解析失败,跳过\n }\n currentToolUse = null;\n }\n break;\n\n case \"message_delta\": {\n const deltaUsage = (event as { usage?: { output_tokens?: number } }).usage;\n outputTokens = deltaUsage?.output_tokens ?? 0;\n break;\n }\n }\n },\n { stopOnDone: false },\n );\n\n return {\n text: text || undefined,\n toolCalls: toolCalls.length > 0 ? toolCalls : undefined,\n usage: inputTokens > 0 || outputTokens > 0 ? { inputTokens, outputTokens } : undefined,\n };\n}\n","/**\n * DeepSeek 客户端封装(中)/ DeepSeek client wrapper (EN).\n *\n * DeepSeek 与 OpenAI Chat Completions 兼容,直接复用 OpenAIClient。\n * DeepSeek is OpenAI-compatible, so it reuses OpenAIClient behavior.\n */\nimport { OpenAIClient } from \"./openai.js\";\n\n/**\n * DeepSeek 客户端类(中)/ DeepSeek client class extending OpenAIClient (EN).\n */\nexport class DeepSeekClient extends OpenAIClient {}\n","/**\n * Doubao 客户端封装(中)/ Doubao client wrapper (EN).\n *\n * Doubao(火山引擎 Ark)与 OpenAI Chat Completions 兼容,直接复用 OpenAIClient。\n * Doubao (Volcengine Ark) is OpenAI-compatible, so it reuses OpenAIClient behavior.\n */\nimport { OpenAIClient } from \"./openai.js\";\n\n/**\n * Doubao 客户端类(中)/ Doubao client class extending OpenAIClient (EN).\n */\nexport class DoubaoClient extends OpenAIClient {}\n","/**\n * Qwen 客户端封装(中)/ Qwen client wrapper (EN).\n *\n * Qwen(阿里云百炼兼容模式)与 OpenAI Chat Completions 兼容,直接复用 OpenAIClient。\n * Qwen (DashScope compatible mode) is OpenAI-compatible, so it reuses OpenAIClient behavior.\n */\nimport { OpenAIClient } from \"./openai.js\";\n\n/**\n * Qwen 客户端类(中)/ Qwen client class extending OpenAIClient (EN).\n */\nexport class QwenClient extends OpenAIClient {}\n","/**\n * MiniMax 客户端封装(中)/ MiniMax client wrapper (EN).\n *\n * MiniMax 与 OpenAI Chat Completions 兼容,直接复用 OpenAIClient。\n * MiniMax is OpenAI-compatible, so it reuses OpenAIClient behavior.\n *\n * 默认端点:https://api.minimaxi.com/v1\n * 推荐模型:MiniMax-M2.5 / MiniMax-M2.5-highspeed\n */\nimport { OpenAIClient } from \"./openai.js\";\n\n/**\n * MiniMax 客户端类(中)/ MiniMax client class extending OpenAIClient (EN).\n */\nexport class MiniMaxClient extends OpenAIClient {}\n","/**\n * AI 客户端主入口(中)/ AI client entrypoint based on fetch (EN).\n *\n * 提供 provider 路由与统一类型导出。\n * Provides provider routing and unified type exports.\n */\nimport type { AIClient, AIChatResponse, AIMessage } from \"../types.js\";\nimport type { ToolDefinition } from \"../tool-registry.js\";\nimport { validateProvider } from \"./constants.js\";\nimport { OpenAIClient } from \"./openai.js\";\nimport { AnthropicClient } from \"./anthropic.js\";\nimport { DeepSeekClient } from \"./deepseek.js\";\nimport { DoubaoClient } from \"./doubao.js\";\nimport { QwenClient } from \"./qwen.js\";\nimport { MiniMaxClient } from \"./minimax.js\";\n\n// Re-export 类型,方便外部统一从 ai-client 导入\nexport type { AIClient, AIChatResponse, AIMessage, AIToolCall } from \"../types.js\";\n\n// Re-export 客户端类(基类 + OpenAI + Anthropic)\nexport { BaseAIClient, type BaseAIClientOptions, type ChatHandlerParams } from \"./custom.js\";\nexport { OpenAIClient, parseOpenAIStream } from \"./openai.js\";\nexport { AnthropicClient, parseAnthropicStream } from \"./anthropic.js\";\nexport { DeepSeekClient } from \"./deepseek.js\";\nexport { DoubaoClient } from \"./doubao.js\";\nexport { QwenClient } from \"./qwen.js\";\nexport { MiniMaxClient } from \"./minimax.js\";\n\n// ─── 公共类型定义 ───\n\n/** AI 客户端配置(中)/ AI client configuration (EN). */\nexport type AIClientConfig = {\n /** AI 提供商: \"openai\" | \"copilot\" | \"anthropic\" | \"deepseek\" | \"doubao\" | \"qwen\" | \"minimax\" */\n provider: string;\n /** 模型名称,如 \"gpt-4o\"、\"claude-sonnet-4-20250514\" */\n model: string;\n /** API Key / Token */\n apiKey: string;\n /** 自定义 API 基础 URL(可选,如本地 Ollama: http://localhost:11434/v1) */\n baseURL?: string;\n /** 是否启用流式输出(SSE)。默认 true;传 false 时使用 JSON 非流式响应。 */\n stream?: boolean;\n /** 单次请求超时(毫秒,默认 45000;<=0 表示不设置超时)。 */\n requestTimeoutMs?: number;\n /** 是否允许模型并行返回多个工具调用(默认 true)。 */\n parallelToolCalls?: boolean;\n};\n\n/** 统一 chat 入参(中)/ Unified chat parameters (EN). */\nexport type ChatParams = {\n /** 系统提示词 */\n systemPrompt: string;\n /** 对话消息列表 */\n messages: AIMessage[];\n /** 可用工具定义列表 */\n tools?: ToolDefinition[];\n};\n\n/**\n * HTTP 请求对象(中)/ Built HTTP request init payload (EN).\n */\nexport type ChatRequestInit = {\n /** 请求 URL */\n url: string;\n /** HTTP 方法 */\n method: \"POST\";\n /** 请求头 */\n headers: Record<string, string>;\n /** 请求体(JSON 字符串) */\n body: string;\n};\n\n// ─── 高层 API ───\n\n/**\n * 创建 AI 客户端(中)/ Create AI client by provider (EN).\n */\nexport function createAIClient(config: AIClientConfig): AIClient {\n validateProvider(config.provider);\n\n switch (config.provider) {\n case \"openai\":\n case \"copilot\":\n return new OpenAIClient(config);\n case \"doubao\":\n return new DoubaoClient(config);\n case \"qwen\":\n return new QwenClient(config);\n case \"anthropic\":\n return new AnthropicClient(config);\n case \"deepseek\":\n return new DeepSeekClient(config);\n case \"minimax\":\n return new MiniMaxClient(config);\n default:\n throw new Error(\n `Unknown AI provider: ${config.provider}. Supported: openai, copilot, anthropic, deepseek, doubao, qwen, minimax`,\n );\n }\n}\n","/**\n * Tool Registry — 工具注册表,负责工具的注册、查询和分发。\n *\n * 实例化设计 — 每个 Agent 创建独立的 ToolRegistry,避免全局状态污染:\n *\n * // Node 端\n * const registry = new ToolRegistry();\n * registerBuiltinTools(registry); // 注册 exec, file, browser...\n * await executeAgentLoop({ registry, ... });\n *\n * // Web 端\n * const registry = new ToolRegistry();\n * registerWebTools(registry); // 注册 dom, navigate...\n * await executeAgentLoop({ registry, ... });\n *\n * 优点:\n * - 多实例安全:Node Agent 和 Web Agent 可并行运行,工具列表互不干扰\n * - 测试隔离:每个 test case 创建独立 registry,无需清理全局状态\n * - 可组合:可按需注册不同工具子集\n */\nimport type { TObject } from \"@sinclair/typebox\";\nexport { jsonResult, readNumberParam, readStringParam } from \"./tool-params.js\";\n\n/**\n * 工具执行结果 — 每个工具的 execute() 必须返回此类型。\n */\nexport type ToolCallResult = {\n /** 返回内容(字符串文本或结构化对象,最终会序列化后发给 AI) */\n content: string | Record<string, unknown>;\n /** 可选的额外细节(用于日志记录、调试等,不直接发给 AI) */\n details?: Record<string, unknown>;\n};\n\n/**\n * 工具定义 — 注册工具时需要提供的完整描述。\n *\n * 这四个字段分别告诉 AI「叫什么名字」「能做什么」「需要什么参数」「怎么执行」:\n * - name + description → AI 根据用户意图选择合适的工具\n * - schema → AI 生成符合格式的参数 JSON\n * - execute → 实际执行逻辑\n */\nexport type ToolDefinition = {\n /** 工具名称(AI 通过此名称调用,如 \"exec\"、\"file_read\") */\n name: string;\n /** 工具描述(AI 据此判断何时使用这个工具) */\n description: string;\n /** 参数的 JSON Schema(TypeBox 定义,描述工具接受哪些参数及其类型) */\n schema: TObject;\n /** 执行函数 — 接收 AI 传入的参数,返回执行结果 */\n execute: (params: Record<string, unknown>) => Promise<ToolCallResult>;\n};\n\n/**\n * 工具注册表实例 — 管理一组工具的注册、查询和分发。\n *\n * 每个 Agent 拥有独立的 ToolRegistry 实例,从而:\n * - Node Agent 的 exec/file 工具不会泄漏到 Web Agent\n * - Web Agent 的 dom/navigate 工具不会泄漏到 Node Agent\n * - 测试中不同 case 互不影响\n */\nexport class ToolRegistry {\n private tools = new Map<string, ToolDefinition>();\n\n /** 注册一个工具 */\n register(tool: ToolDefinition): void {\n this.tools.set(tool.name, tool);\n }\n\n /** 获取所有已注册的工具定义列表(发给 AI,告知可用工具) */\n getDefinitions(): ToolDefinition[] {\n return Array.from(this.tools.values());\n }\n\n /** 按名称检查工具是否已注册。 */\n has(name: string): boolean {\n return this.tools.has(name);\n }\n\n /** 按名称注销工具,返回是否删除成功。 */\n unregister(name: string): boolean {\n return this.tools.delete(name);\n }\n\n /**\n * 根据工具名分发并执行工具调用。\n * - 找到工具 → 执行 execute() → 返回结果\n * - 找不到 → 返回错误信息(不抛异常,让 AI 知道工具不存在)\n * - 执行出错 → 捕获异常,返回错误信息(不中断 Agent 循环)\n */\n async dispatch(name: string, input: unknown): Promise<ToolCallResult> {\n const tool = this.tools.get(name);\n if (!tool) {\n return {\n content: `Unknown tool: ${name}`,\n details: { error: true, toolName: name },\n };\n }\n\n try {\n const params = (input ?? {}) as Record<string, unknown>;\n return await tool.execute(params);\n } catch (err) {\n const message = err instanceof Error ? err.message : String(err);\n return {\n content: `Tool \"${name}\" failed: ${message}`,\n details: { error: true, toolName: name, message },\n };\n }\n }\n}\n","/**\n * 极简系统提示词构建器。\n *\n * 纯函数,不依赖运行时环境;调用方只需传入工具定义和可选扩展指令。\n *\n * 职责:\n * - 组装发送给 AI 的 system prompt(英文正文)\n * - 包含核心规则、工具列表、事件简写表、输出协议\n * - 支持额外自定义指令注入\n *\n * 约束(来自 AGENTS.md §11):\n * - 发送给模型的 prompt 正文统一英文\n * - 中文仅用于源码注释\n *\n * 调用方:\n * - `agent-loop/index.ts` 在循环启动时调用 `buildSystemPrompt()` 构建系统消息\n * - `web/index.ts` 的 WebAgent 通过 systemPrompt 配置传入额外指令\n */\n/**\n * 系统提示词构建参数。\n *\n * 所有字段可选:\n * - thinkingLevel:AI 思考深度标签(如 \"high\"/\"medium\"),影响推理行为\n * - listenerEvents:快照中实际会输出的 listener 事件集合,用于同步缩写说明\n * - extraInstructions:额外英文指令,追加到 \"## Extra Instructions\" 章节\n */\nexport type SystemPromptParams = {\n /** AI 思考深度标签。 */\n thinkingLevel?: string;\n /** 允许在 Listener Abbrevs 中输出的事件白名单。 */\n listenerEvents?: string[];\n /** 额外英文指令(字符串或字符串数组)。 */\n extraInstructions?: string | string[];\n};\n\nconst LISTENER_ABBREV_MAP: Record<string, string> = {\n click: \"clk\",\n dblclick: \"dbl\",\n mousedown: \"mdn\",\n mouseup: \"mup\",\n mousemove: \"mmv\",\n mouseover: \"mov\",\n mouseout: \"mot\",\n mouseenter: \"men\",\n mouseleave: \"mlv\",\n pointerdown: \"pdn\",\n pointerup: \"pup\",\n pointermove: \"pmv\",\n touchstart: \"tst\",\n touchend: \"ted\",\n keydown: \"kdn\",\n keyup: \"kup\",\n input: \"inp\",\n change: \"chg\",\n submit: \"sub\",\n focus: \"fcs\",\n blur: \"blr\",\n scroll: \"scl\",\n wheel: \"whl\",\n drag: \"drg\",\n dragstart: \"drs\",\n dragend: \"dre\",\n drop: \"drp\",\n contextmenu: \"ctx\",\n};\n\nconst DEFAULT_SYSTEM_PROMPT_LISTENER_EVENTS = [\n \"click\",\n \"input\",\n \"change\",\n \"mousedown\",\n \"pointerdown\",\n \"keydown\",\n \"submit\",\n \"focus\",\n \"blur\",\n];\n\nfunction buildListenerAbbrevLine(listenerEvents?: string[]): string {\n const allowed = (listenerEvents && listenerEvents.length > 0)\n ? listenerEvents\n : DEFAULT_SYSTEM_PROMPT_LISTENER_EVENTS;\n\n const normalized = allowed\n .map(event => event.trim().toLowerCase())\n .filter(Boolean);\n\n const unique = [...new Set(normalized)];\n const pairs = unique\n .map(event => {\n const abbrev = LISTENER_ABBREV_MAP[event];\n return abbrev ? `${abbrev}=${event}` : null;\n })\n .filter((pair): pair is string => !!pair);\n\n return pairs.join(\" \");\n}\n\n/**\n * 规范化额外指令:统一转为非空字符串数组。\n *\n * - 单字符串 → 单元素数组\n * - 字符串数组 → 过滤空值\n * - undefined → 空数组\n */\nfunction normalizeExtraInstructions(input?: string | string[]): string[] {\n if (!input) return [];\n const rawList = Array.isArray(input) ? input : [input];\n return rawList.map(s => s.trim()).filter(Boolean);\n}\n\n/**\n * 构建系统提示词。\n *\n * 输出结构(按章节顺序):\n * 1. **Core Rules** — Agent 核心行为规则\n * - 快照驱动决策:仅基于当前快照 + 剩余任务工作\n * - 增量消费模型:每轮执行后输出 REMAINING 推进任务\n * - hash ID 定位:仅交互元素携带 #hashID,非交互元素为上下文\n * - 事件信号:listeners=\"...\" 标注运行时事件绑定\n * - 批量执行:同轮完成所有独立可见操作\n * - 输入顺序:fill/type 前必须先 focus/click 同一目标\n * - DOM 变化断轮:会改变 DOM 的动作执行后等待下一轮新快照\n * - 停机规则:任务完成后输出 REMAINING: DONE\n *\n * 2. **Listener Abbrevs** — 事件简写对照表\n * - 快照中 listeners=\"clk,inp,chg\" 的简写含义\n * - 与 page-info-tool.ts 的 EVENT_ABBREV 映射一致\n *\n * 3. **Output Contract** — 输出协议\n * - 每轮返回工具调用 + REMAINING 文本行\n *\n * 4. **Reasoning Profile**(可选) — 思考深度配置\n *\n * 5. **Extra Instructions**(可选) — 用户自定义额外指令\n *\n * @param params - 构建参数(工具列表、思考深度、额外指令)\n * @returns 完整的系统提示词字符串(英文)\n */\nexport function buildSystemPrompt(params: SystemPromptParams = {}): string {\n const sections: string[] = [];\n\n // ─── 章节 1:角色定义 + 核心规则 ───\n // 这是 prompt 最核心的部分,定义了 Agent 的行为模式和约束。\n // 规则按重要性排列,每条规则对应一个具体的行为约束。\n sections.push(\n [\n \"You are AutoPilot, an AI agent controlling the current web page via tools.\",\n \"\",\n \"## Core Rules\",\n\n \"- Work from CURRENT snapshot + remaining task. Do not restate.\",\n \"- Task reduction: (remaining, prev actions, this-round) → new remaining.\",\n \"- Use #hashID from snapshot as selector. Do not guess CSS selectors.\",\n \"- Only interactive elements carry #hashID; others are context-only and cannot be targeted.\",\n\n \"- Bracket tag may show ARIA role ([combobox], [slider]) as primary interaction hint.\",\n \"- listeners=\\\"...\\\" = bound event handlers (abbrevs below). Prefer targets with matching listeners.\",\n \"- Click priority: clk/pdn/mdn, onclick, native link/button, role=button/link. Avoid focus-only or hover-only signals.\",\n \"- No-effect fallback: try nearest actionable sibling/ancestor in same semantic group instead of repeating.\",\n\n \"- Batch fill/type/check/select_option freely within one round. A click always ends the round — send at most ONE click as the LAST action in a batch.\",\n \"- Input order (MANDATORY): focus/click → fill/type/select_option per target. Multi-field: focus A→fill A→focus B→fill B.\",\n \"- Search/filter inputs: after fill, press Enter (or click search button) to trigger the search. Do not assume fill alone submits.\",\n \"- Do NOT run focus-only batches. Each focus must be immediately followed by its fill/type/select_option.\",\n\n \"- Steppers: compute delta from visible value, click exactly |delta| times. Check/uncheck: target real input control.\",\n \"- DOM-changing action (click/modal/navigate): ends the round, next snapshot follows. Actions sent after a click in the same batch are discarded.\",\n \"- Intermediate progress is NOT completion: if an action only opens, expands, reveals, filters, paginates, switches context, or loads the next step, keep REMAINING on the final user goal until the requested end state/value/content is visible in the snapshot.\",\n \"- Effect check: before planning new actions, confirm previous actions' expected effects are visible in current snapshot. If not, the action failed — try a different target instead of repeating.\",\n \"- Do NOT call page_info — snapshot is auto-refreshed and provided every round. Do NOT use get_text/get_attr to read what is already visible in the snapshot.\",\n \"- Never repeat the same tool call (same name + same args) on the same target. If it didn't work, try a different approach.\",\n \"- Dropdown/select: prefer dom.select_option (works in one round). For custom dropdowns requiring click-to-open: click → wait for next snapshot → click option (two rounds).\",\n \"- Omitted children: output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>`, wait for next snapshot.\",\n \"- Do NOT verify values unless user explicitly asks.\",\n \"- Stop: when remaining task is fully achieved (confirmed in snapshot), output REMAINING: DONE with a summary.\",\n \"- Do NOT interact with AutoPilot UI unless user asks.\",\n \"\",\n\n // ─── 事件简写对照表 ───\n \"## Listener Abbrevs\",\n buildListenerAbbrevLine(params.listenerEvents),\n \"\",\n // ─── 输出协议 + 极简示例 ───\n \"## Output\",\n \"Tool calls + one text line: REMAINING: <new remaining> or REMAINING: DONE\",\n \"Example: Task A→B→C. Round1 do A → REMAINING: B→C. Round2 do B → REMAINING: C. Round3 do C → REMAINING: DONE\",\n ].join(\"\\n\"),\n );\n\n // ─── 章节 4(可选):思考深度配置 ───\n // 影响模型的推理深度(如 \"high\" 表示复杂任务需深度思考)。\n if (params.thinkingLevel) {\n sections.push(\n [\n \"## Reasoning Profile\",\n `- Thinking level: ${params.thinkingLevel}`,\n ].join(\"\\n\"),\n );\n }\n\n // ─── 章节 5(可选):额外自定义指令 ───\n // 由 WebAgent 使用方通过 extraInstructions 配置传入。\n // 典型用途:业务特定规则、UI 框架提示、测试场景约束等。\n const extraInstructions = normalizeExtraInstructions(params.extraInstructions);\n if (extraInstructions.length > 0) {\n sections.push(\n [\n \"## Extra Instructions\",\n ...extraInstructions.map(line => `- ${line}`),\n ].join(\"\\n\"),\n );\n }\n\n return sections.join(\"\\n\\n\");\n}\n","/**\n * 全局事件监听追踪器(浏览器端)。\n *\n * 设计目标:\n * 1. 从 EventTarget.prototype 统一拦截 add/removeEventListener\n * 2. 仅记录 Element 实例,避免污染 document/window 等\n * 3. 不改变原调用语义:先执行原方法,再做追踪记录\n * 4. 追踪失败时静默兜底,不影响业务代码执行\n */\n\ntype AddEventListenerFn = EventTarget[\"addEventListener\"];\ntype RemoveEventListenerFn = EventTarget[\"removeEventListener\"];\n\nconst elementEventMap = new WeakMap<Element, Set<string>>();\n\nlet installed = false;\nlet originalAddEventListener: AddEventListenerFn | undefined;\nlet originalRemoveEventListener: RemoveEventListenerFn | undefined;\n\nfunction normalizeEventType(type: unknown): string | null {\n if (typeof type !== \"string\") return null;\n const normalized = type.trim().toLowerCase();\n return normalized || null;\n}\n\nfunction canTrackElementTarget(target: EventTarget): target is Element {\n if (typeof Element === \"undefined\") return false;\n return target instanceof Element;\n}\n\nfunction trackElementEvent(target: EventTarget, type: string): void {\n if (!canTrackElementTarget(target)) return;\n const prev = elementEventMap.get(target);\n if (prev) {\n prev.add(type);\n return;\n }\n elementEventMap.set(target, new Set([type]));\n}\n\nfunction untrackElementEvent(target: EventTarget, type: string): void {\n if (!canTrackElementTarget(target)) return;\n const prev = elementEventMap.get(target);\n if (!prev) return;\n prev.delete(type);\n if (prev.size === 0) {\n elementEventMap.delete(target);\n }\n}\n\n/**\n * 安装全局监听追踪补丁(幂等)。\n */\nexport function installEventListenerTracking(): void {\n if (installed) return;\n if (typeof EventTarget === \"undefined\") return;\n\n const proto = EventTarget.prototype;\n const nativeAdd = proto.addEventListener;\n const nativeRemove = proto.removeEventListener;\n\n if (typeof nativeAdd !== \"function\" || typeof nativeRemove !== \"function\") return;\n\n originalAddEventListener = nativeAdd;\n originalRemoveEventListener = nativeRemove;\n\n proto.addEventListener = function patchedAddEventListener(\n this: EventTarget,\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | AddEventListenerOptions,\n ): void {\n originalAddEventListener?.call(this, type, listener, options);\n try {\n const normalizedType = normalizeEventType(type);\n if (!normalizedType || listener == null) return;\n trackElementEvent(this, normalizedType);\n } catch {\n // 追踪失败不应影响业务逻辑\n }\n };\n\n proto.removeEventListener = function patchedRemoveEventListener(\n this: EventTarget,\n type: string,\n listener: EventListenerOrEventListenerObject | null,\n options?: boolean | EventListenerOptions,\n ): void {\n originalRemoveEventListener?.call(this, type, listener, options);\n try {\n const normalizedType = normalizeEventType(type);\n if (!normalizedType || listener == null) return;\n untrackElementEvent(this, normalizedType);\n } catch {\n // 追踪失败不应影响业务逻辑\n }\n };\n\n installed = true;\n}\n\n/**\n * 读取元素已记录的事件名(排序后返回,便于稳定输出)。\n */\nexport function getTrackedElementEvents(el: Element): string[] {\n const set = elementEventMap.get(el);\n if (!set || set.size === 0) return [];\n return Array.from(set).sort();\n}\n\n/**\n * 判断元素是否存在至少一个被追踪到的事件绑定。\n */\nexport function hasTrackedElementEvents(el: Element): boolean {\n return (elementEventMap.get(el)?.size ?? 0) > 0;\n}\n","/**\n * DOM Tool — 浏览器 DOM 操作工具(结合 Playwright 核心交互模式增强)。\n *\n * 关键改进(参考 Playwright):\n * 1. retarget — 点击时自动重定向到 button/link/label.control\n * 2. scrollIntoView 多策略 — 4 种 block 对齐轮换,解决 sticky 遮挡\n * 3. stable 检查 — rAF 逐帧检测元素位置稳定后再操作\n * 4. hit-target 验证 — elementsFromPoint 检查是否被遮挡\n * 5. 完整点击事件链 — pointermove→pointerdown→mousedown→pointerup→mouseup→click\n * 6. check/uncheck 通过 click — 先检查→click 切换→验证状态\n * 7. press 组合键 — 支持 Control+a, Shift+Enter 等修饰键\n * 8. fill 分类型 — date/color/range 走 setValue,text 类走 selectAll+原生写入\n * 9. 自定义下拉增强 — 更广泛的 option 选择器 + 等待弹出\n * 10. ARIA disabled — 检查祖先链 aria-disabled\n *\n * 运行环境:浏览器 Content Script(直接访问 DOM,无 CDP)。\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport type { RefStore } from \"../ref-store.js\";\nimport { getTrackedElementEvents } from \"../event-listener-tracker.js\";\n\n// ─── 常量 ───\n\nconst DEFAULT_WAIT_MS = 1200;\n\n/** scrollIntoView 轮换策略(参考 Playwright dom.ts) */\nconst SCROLL_OPTIONS: (ScrollIntoViewOptions | undefined)[] = [\n undefined,\n { block: \"end\", inline: \"end\" },\n { block: \"center\", inline: \"center\" },\n { block: \"start\", inline: \"start\" },\n];\n\n/** fill 时直接 setValue 的 input 类型(参考 Playwright kInputTypesToSetValue) */\nconst INPUT_SET_VALUE_TYPES = new Set([\n \"color\", \"date\", \"time\", \"datetime-local\", \"month\", \"range\", \"week\",\n]);\n\n/** fill 时走 selectText+写入 的 input 类型 */\nconst INPUT_TYPE_INTO_TYPES = new Set([\n \"\", \"email\", \"number\", \"password\", \"search\", \"tel\", \"text\", \"url\",\n]);\n\n/** 不可 fill 的 input 类型 */\nconst INPUT_BLOCKED_TYPES = new Set([\n \"checkbox\", \"radio\", \"file\", \"button\", \"submit\", \"reset\", \"image\",\n]);\n\n/** 修饰键集合 */\nconst MODIFIER_KEYS = new Set([\"Control\", \"Shift\", \"Alt\", \"Meta\"]);\n\n/** 键名→code 映射 */\nconst KEY_CODE_MAP: Record<string, string> = {\n Enter: \"Enter\", Escape: \"Escape\", Esc: \"Escape\",\n Tab: \"Tab\", Space: \"Space\", \" \": \"Space\",\n Backspace: \"Backspace\", Delete: \"Delete\",\n ArrowUp: \"ArrowUp\", ArrowDown: \"ArrowDown\",\n ArrowLeft: \"ArrowLeft\", ArrowRight: \"ArrowRight\",\n Home: \"Home\", End: \"End\", PageUp: \"PageUp\", PageDown: \"PageDown\",\n Control: \"ControlLeft\", Shift: \"ShiftLeft\", Alt: \"AltLeft\", Meta: \"MetaLeft\",\n};\n\nconst FILL_RELEVANT_EVENTS = new Set([\n \"input\", \"change\", \"focus\", \"blur\", \"keydown\",\n \"click\", \"mousedown\", \"pointerdown\",\n]);\n\n// ─── 模块状态 ───\n\nlet activeRefStore: RefStore | undefined;\n\nexport function setActiveRefStore(store: RefStore | undefined): void {\n activeRefStore = store;\n}\n\nexport function getActiveRefStore(): RefStore | undefined {\n return activeRefStore;\n}\n\n// ─── 基础工具 ───\n\nfunction sleep(ms: number): Promise<void> {\n return new Promise((r) => setTimeout(r, ms));\n}\n\n/** 查询元素:优先 RefStore hash,回退 CSS 选择器 */\nfunction queryElement(selector: string): Element | string {\n try {\n if (selector.startsWith(\"#\") && activeRefStore) {\n const id = selector.slice(1);\n if (activeRefStore.has(id)) {\n const el = activeRefStore.get(id);\n if (!el) return `未找到 ref \"${selector}\" 对应的元素(可能已被移除或快照已过期)`;\n return el;\n }\n }\n const el = document.querySelector(selector);\n if (!el) return `未找到匹配 \"${selector}\" 的元素`;\n return el;\n } catch {\n return `选择器语法错误: ${selector}`;\n }\n}\n\n/** 轮询等待元素出现 */\nasync function waitForElement(selector: string, timeoutMs: number): Promise<Element | string | null> {\n const start = Date.now();\n while (Date.now() - start <= timeoutMs) {\n const r = queryElement(selector);\n if (typeof r !== \"string\") return r;\n if (r.startsWith(\"选择器语法错误\")) return r;\n await sleep(100);\n }\n return null;\n}\n\nfunction resolveWaitMs(params: Record<string, unknown>): number {\n const waitMs = params.waitMs;\n if (typeof waitMs === \"number\" && Number.isFinite(waitMs)) return Math.max(0, Math.floor(waitMs));\n const waitSeconds = params.waitSeconds;\n if (typeof waitSeconds === \"number\" && Number.isFinite(waitSeconds)) return Math.max(0, Math.floor(waitSeconds * 1000));\n return DEFAULT_WAIT_MS;\n}\n\n// ─── 可见性判定(参考 Playwright domUtils.ts) ───\n\n/** 检查元素样式可见性(处理 checkVisibility / details 折叠 / visibility) */\nfunction isStyleVisible(el: Element, style?: CSSStyleDeclaration): boolean {\n style = style ?? window.getComputedStyle(el);\n if (typeof el.checkVisibility === \"function\") {\n if (!el.checkVisibility()) return false;\n } else {\n const det = el.closest(\"details,summary\");\n if (det !== el && det?.nodeName === \"DETAILS\" && !(det as HTMLDetailsElement).open) return false;\n }\n return style.visibility === \"visible\";\n}\n\n/**\n * 元素可见性检查(参考 Playwright isElementVisible+computeBox)。\n * 处理 display:contents / display:none / visibility / opacity / 尺寸为 0。\n */\nfunction isElementVisible(el: Element): boolean {\n if (!(el instanceof HTMLElement || el instanceof SVGElement)) return false;\n if (!el.isConnected) return false;\n const style = window.getComputedStyle(el);\n\n if (style.display === \"contents\") {\n for (let child = el.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === Node.ELEMENT_NODE && isElementVisible(child as Element)) return true;\n if (child.nodeType === Node.TEXT_NODE) {\n const range = document.createRange();\n range.selectNodeContents(child);\n const rects = range.getClientRects();\n for (let i = 0; i < rects.length; i++) {\n if (rects[i].width > 0 && rects[i].height > 0) return true;\n }\n }\n }\n return false;\n }\n if (style.display === \"none\") return false;\n if (!isStyleVisible(el, style)) return false;\n if (style.opacity === \"0\") return false;\n const rect = el.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n}\n\n// ─── disabled / editable 检查(参考 Playwright) ───\n\n/** ARIA disabled:检查元素自身 + 祖先链 aria-disabled(参考 Playwright getAriaDisabled) */\nfunction isElementDisabled(el: Element): boolean {\n if (el instanceof HTMLButtonElement || el instanceof HTMLInputElement ||\n el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {\n if ((el as HTMLButtonElement).disabled) return true;\n }\n let cursor: Element | null = el;\n while (cursor) {\n if (cursor.getAttribute(\"aria-disabled\") === \"true\") return true;\n cursor = cursor.parentElement;\n }\n return false;\n}\n\nfunction isEditableElement(el: Element): boolean {\n if (el instanceof HTMLTextAreaElement) return !el.readOnly;\n if (el instanceof HTMLInputElement) {\n return !INPUT_BLOCKED_TYPES.has(el.type) && !el.readOnly;\n }\n if (el instanceof HTMLSelectElement) return true;\n return el instanceof HTMLElement && el.isContentEditable;\n}\n\n// ─── 稳定性检查(参考 Playwright _checkElementIsStable) ───\n\n/** rAF 逐帧检查元素位置是否连续 3 帧不变 */\nfunction checkElementStable(el: Element, timeoutMs = 800): Promise<boolean> {\n return new Promise((resolve) => {\n let lastRect: DOMRect | undefined;\n let stableCount = 0;\n const start = performance.now();\n function check() {\n if (performance.now() - start > timeoutMs || !el.isConnected) { resolve(false); return; }\n const rect = el.getBoundingClientRect();\n if (lastRect) {\n const same = rect.x === lastRect.x && rect.y === lastRect.y &&\n rect.width === lastRect.width && rect.height === lastRect.height;\n if (!same) { stableCount = 0; } else if (++stableCount >= 3) { resolve(true); return; }\n }\n lastRect = rect;\n requestAnimationFrame(check);\n }\n requestAnimationFrame(check);\n });\n}\n\n// ─── retarget(参考 Playwright injectedScript.retarget) ───\n\ntype RetargetMode = \"none\" | \"follow-label\" | \"button-link\";\n\n/**\n * 将目标重定向到关联的交互控件。\n * - button-link:非交互元素→最近 button/[role=button]/a/[role=link]\n * - follow-label:label→control + 非交互→button/[role=button]/[role=checkbox]/[role=radio]\n */\nfunction retarget(el: Element, mode: RetargetMode): Element {\n if (mode === \"none\") return el;\n if (!el.matches(\"input, textarea, select\") && !(el as HTMLElement).isContentEditable) {\n if (mode === \"button-link\") {\n el = el.closest(\"button, [role=button], a, [role=link]\") || el;\n } else {\n el = el.closest(\"button, [role=button], [role=checkbox], [role=radio]\") || el;\n }\n }\n if (mode === \"follow-label\") {\n if (!el.matches(\"a, input, textarea, button, select, [role=link], [role=button], [role=checkbox], [role=radio]\") &&\n !(el as HTMLElement).isContentEditable) {\n const label = el.closest(\"label\") as HTMLLabelElement | null;\n if (label?.control) el = label.control;\n }\n }\n return el;\n}\n\n// ─── scrollIntoView(参考 Playwright 4 种策略轮换) ───\n\nfunction scrollIntoViewIfNeeded(el: Element, retry = 0): void {\n if (retry === 0 && \"scrollIntoViewIfNeeded\" in el) {\n (el as HTMLElement & { scrollIntoViewIfNeeded: (c?: boolean) => void }).scrollIntoViewIfNeeded(true);\n return;\n }\n const opts = SCROLL_OPTIONS[retry % SCROLL_OPTIONS.length];\n el.scrollIntoView(opts ?? { block: \"center\", inline: \"nearest\" });\n}\n\n// ─── hit-target 检查 ───\n\n/** 检查元素中心点是否被遮挡,返回遮挡元素描述或 null */\nfunction checkHitTarget(el: Element): string | null {\n const rect = el.getBoundingClientRect();\n const x = rect.left + rect.width / 2;\n const y = rect.top + rect.height / 2;\n const topEl = document.elementFromPoint(x, y);\n if (!topEl) return null;\n if (topEl === el || el.contains(topEl) || topEl.contains(el)) return null;\n const sharedLabel = topEl.closest(\"label\");\n if (sharedLabel && sharedLabel.contains(el)) return null;\n return describeElement(topEl);\n}\n\n// ─── actionability 综合检查 ───\n\nfunction ensureActionable(el: Element, action: string, selector: string, force: boolean): ToolCallResult | null {\n if (force) return null;\n if (!el.isConnected) {\n return { content: `\"${selector}\" 元素已脱离文档,无法执行 ${action}`, details: { error: true, code: \"ELEMENT_DETACHED\", action, selector } };\n }\n const readOnlyActions = new Set([\"get_text\", \"get_attr\"]);\n if (!readOnlyActions.has(action) && !isElementVisible(el)) {\n return { content: `\"${selector}\" 元素不可见,无法执行 ${action}`, details: { error: true, code: \"ELEMENT_NOT_VISIBLE\", action, selector } };\n }\n const mutationActions = new Set([\"click\", \"fill\", \"type\", \"press\", \"select_option\", \"clear\", \"check\", \"uncheck\"]);\n if (mutationActions.has(action) && isElementDisabled(el)) {\n return { content: `\"${selector}\" 元素已禁用(disabled/aria-disabled),无法执行 ${action}`, details: { error: true, code: \"ELEMENT_DISABLED\", action, selector } };\n }\n if ([\"fill\", \"type\", \"clear\"].includes(action) && !isEditableElement(el)) {\n // 允许 fill 作用于 role=slider(后续在 fill 分支做专门处理)\n if (action === \"fill\" && el.getAttribute(\"role\") === \"slider\") {\n return null;\n }\n return { content: `\"${selector}\" 不是可编辑元素,无法执行 ${action}`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n return null;\n}\n\n/**\n * 为 role=slider 查找关联的数值输入框。\n * 典型场景:Element Plus slider + input-number 同属一个 form-item。\n */\nfunction findAssociatedSliderInput(slider: Element): HTMLInputElement | null {\n const candidates: Element[] = [];\n\n const formItem = slider.closest(\".el-form-item\");\n if (formItem) candidates.push(formItem);\n\n let cursor: Element | null = slider.parentElement;\n for (let depth = 0; cursor && depth < 4; depth++, cursor = cursor.parentElement) {\n candidates.push(cursor);\n }\n\n for (const scope of candidates) {\n const input = scope.querySelector(\n 'input[type=\"number\"], input[role=\"spinbutton\"], .el-input-number input:not([type=\"hidden\"])',\n );\n if (input instanceof HTMLInputElement && isEditableElement(input) && isElementVisible(input)) {\n return input;\n }\n }\n return null;\n}\n\n// ─── 事件派发(参考 Playwright input.ts 事件链) ───\n\nfunction getClickPoint(el: Element): { x: number; y: number } {\n const r = el.getBoundingClientRect();\n return { x: r.left + r.width / 2, y: r.top + r.height / 2 };\n}\n\n/**\n * 完整点击事件链(参考 Playwright Mouse.click):\n * pointermove → mousemove → (per clickCount) pointerdown → mousedown → focus → pointerup → mouseup → click\n */\nfunction dispatchClickEvents(el: HTMLElement, clickCount = 1): void {\n const { x, y } = getClickPoint(el);\n const base: MouseEventInit = { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y, button: 0 };\n\n el.dispatchEvent(new PointerEvent(\"pointermove\", { ...base, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mousemove\", base));\n\n for (let cc = 1; cc <= clickCount; cc++) {\n el.dispatchEvent(new PointerEvent(\"pointerdown\", { ...base, detail: cc, buttons: 1, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mousedown\", { ...base, detail: cc, buttons: 1 }));\n if (cc === 1 && el !== document.activeElement) el.focus({ preventScroll: true });\n el.dispatchEvent(new PointerEvent(\"pointerup\", { ...base, detail: cc, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mouseup\", { ...base, detail: cc }));\n el.dispatchEvent(new MouseEvent(\"click\", { ...base, detail: cc }));\n }\n}\n\n/** hover 事件链 */\nfunction dispatchHoverEvents(el: HTMLElement): void {\n const { x, y } = getClickPoint(el);\n const base: MouseEventInit = { bubbles: true, cancelable: true, view: window, clientX: x, clientY: y };\n el.dispatchEvent(new PointerEvent(\"pointerenter\", { ...base, bubbles: false }));\n el.dispatchEvent(new MouseEvent(\"mouseenter\", { ...base, bubbles: false }));\n el.dispatchEvent(new PointerEvent(\"pointermove\", { ...base, pointerId: 1 }));\n el.dispatchEvent(new MouseEvent(\"mousemove\", base));\n el.dispatchEvent(new MouseEvent(\"mouseover\", base));\n}\n\n/** 派发 input + change 事件(兼容 React/Vue 受控组件) */\nfunction dispatchInputEvents(el: HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement): void {\n el.dispatchEvent(new Event(\"input\", { bubbles: true, composed: true }));\n el.dispatchEvent(new Event(\"change\", { bubbles: true }));\n}\n\n/** 原生 setter 写入表单值(绕过 React/Vue getter/setter 拦截) */\nfunction setNativeValue(el: HTMLInputElement | HTMLTextAreaElement, value: string): void {\n const proto = el instanceof HTMLInputElement ? HTMLInputElement.prototype : HTMLTextAreaElement.prototype;\n const desc = Object.getOwnPropertyDescriptor(proto, \"value\");\n if (desc?.set) desc.set.call(el, value);\n else el.value = value;\n}\n\nfunction getFillEventSupportScore(el: Element): number {\n let score = 0;\n\n if (el.hasAttribute(\"oninput\") || el.hasAttribute(\"onchange\")) score += 80;\n if (el.hasAttribute(\"onfocus\") || el.hasAttribute(\"onblur\")) score += 60;\n if (el.hasAttribute(\"onclick\")) score += 40;\n\n const tracked = getTrackedElementEvents(el);\n for (const eventName of tracked) {\n if (!FILL_RELEVANT_EVENTS.has(eventName)) continue;\n if (eventName === \"input\") score += 40;\n else if (eventName === \"change\") score += 35;\n else if (eventName === \"focus\" || eventName === \"blur\") score += 28;\n else if (eventName === \"keydown\") score += 24;\n else score += 14;\n }\n\n return score;\n}\n\nfunction isCandidateFillTarget(el: Element): boolean {\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {\n return !isElementDisabled(el);\n }\n if (el instanceof HTMLElement && el.isContentEditable) return true;\n return false;\n}\n\nfunction executeFillOnResolvedTarget(\n target: Element,\n value: string,\n selector: string,\n action: string,\n sourceHint?: string,\n): ToolCallResult | null {\n if (target instanceof HTMLInputElement) {\n const type = target.type.toLowerCase();\n if (INPUT_BLOCKED_TYPES.has(type)) {\n return { content: `\"${selector}\" 为 input[type=${type}],不支持 fill;请使用 click/check 等动作。`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n if (INPUT_SET_VALUE_TYPES.has(type)) {\n const finalVal = type === \"color\" ? value.toLowerCase().trim() : value.trim();\n target.focus();\n target.value = finalVal;\n if (target.value !== finalVal) {\n return { content: `\"${selector}\" 填写格式不匹配(type=${type})`, details: { error: true, code: \"MALFORMED_VALUE\", action, selector } };\n }\n dispatchInputEvents(target);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${finalVal}\"${suffix}` };\n }\n if (type === \"number\" && Number.isNaN(Number(value.trim()))) {\n return { content: `\"${selector}\" 为 input[type=number],无法填写非数字 \"${value}\"`, details: { error: true, code: \"INVALID_NUMBER\", action, selector } };\n }\n scrollIntoViewIfNeeded(target);\n target.focus();\n selectText(target);\n setNativeValue(target, value);\n dispatchInputEvents(target);\n if (target.value !== value) {\n return { content: `\"${selector}\" 填写后值不一致:期望 \"${value}\",实际 \"${target.value}\"`, details: { error: true, code: \"FILL_NOT_APPLIED\", action, selector } };\n }\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n if (target instanceof HTMLTextAreaElement) {\n scrollIntoViewIfNeeded(target);\n target.focus();\n selectText(target);\n setNativeValue(target, value);\n dispatchInputEvents(target);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n if (target instanceof HTMLSelectElement) {\n target.focus();\n const options = Array.from(target.options);\n let matched = options.find(o => o.value === value);\n if (!matched) {\n const normalized = value.trim().toLowerCase();\n matched = options.find(o => o.text.trim().toLowerCase() === normalized);\n }\n if (!matched) return { content: `\"${selector}\" 下拉框中不存在选项 \"${value}\"` };\n target.value = matched.value;\n dispatchInputEvents(target);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n if (target instanceof HTMLElement && target.isContentEditable) {\n target.focus();\n selectText(target);\n if (value) document.execCommand(\"insertText\", false, value);\n else document.execCommand(\"delete\", false, undefined);\n const suffix = sourceHint ? `(${sourceHint})` : \"\";\n return { content: `已填写 ${describeElement(target)}: \"${value}\"${suffix}` };\n }\n\n return null;\n}\n\nfunction guessNearbyFillTarget(anchor: Element, value: string): Element | null {\n const preferNumeric = Number.isFinite(Number(value));\n const scopeEntries: Array<{ scope: Element; level: number }> = [];\n\n const formItem = anchor.closest(\".el-form-item\");\n if (formItem) scopeEntries.push({ scope: formItem, level: 0 });\n\n let cursor: Element | null = anchor.parentElement;\n for (let level = 1; cursor && level <= 4; level++, cursor = cursor.parentElement) {\n scopeEntries.push({ scope: cursor, level });\n }\n\n const visited = new Set<Element>();\n let best: { el: Element; score: number } | null = null;\n\n for (const { scope, level } of scopeEntries) {\n const candidates = Array.from(scope.querySelectorAll(\n 'input:not([type=\"hidden\"]), textarea, select, [contenteditable=\"true\"], [role=\"spinbutton\"]',\n ));\n\n for (const candidate of candidates) {\n if (!(candidate instanceof Element)) continue;\n if (visited.has(candidate)) continue;\n visited.add(candidate);\n\n if (!isCandidateFillTarget(candidate)) continue;\n if (!isElementVisible(candidate)) continue;\n\n let score = 100 - level * 18;\n score += getFillEventSupportScore(candidate);\n\n if (candidate instanceof HTMLInputElement) {\n const type = candidate.type.toLowerCase();\n if (preferNumeric && (type === \"number\" || candidate.getAttribute(\"role\") === \"spinbutton\")) score += 80;\n if (!preferNumeric && [\"text\", \"\", \"search\", \"email\", \"tel\", \"url\", \"password\"].includes(type)) score += 36;\n }\n\n if (candidate.getAttribute(\"placeholder\")) score += 8;\n if (candidate.getAttribute(\"aria-label\")) score += 8;\n\n if (!best || score > best.score) {\n best = { el: candidate, score };\n }\n }\n }\n\n return best?.el ?? null;\n}\n\n// ─── selectText(参考 Playwright:input/textarea/contenteditable 三种策略) ───\n\nfunction selectText(el: Element): void {\n if (el instanceof HTMLInputElement) { el.select(); el.focus(); return; }\n if (el instanceof HTMLTextAreaElement) { el.selectionStart = 0; el.selectionEnd = el.value.length; el.focus(); return; }\n const range = document.createRange();\n range.selectNodeContents(el);\n const sel = window.getSelection();\n if (sel) { sel.removeAllRanges(); sel.addRange(range); }\n if (el instanceof HTMLElement) el.focus();\n}\n\n// ─── 键盘:组合键支持(参考 Playwright Keyboard.press) ───\n\nfunction splitKeyCombo(key: string): string[] {\n const tokens = key.split(\"+\");\n for (let i = 0; i < tokens.length; i++) {\n if (tokens[i] === \"\" && i + 1 < tokens.length) { tokens[i + 1] = \"+\" + tokens[i + 1]; tokens.splice(i, 1); }\n }\n return tokens.filter(Boolean);\n}\n\nfunction resolveKeyCode(key: string): string {\n return KEY_CODE_MAP[key] ?? (key.length === 1 ? `Key${key.toUpperCase()}` : key);\n}\n\n/**\n * 执行 press:修饰键按正序 down → 主键 down/up → 修饰键逆序 up(参考 Playwright)。\n * 修饰键按下时抑制文本输入(只发 keydown/keyup,不发 keypress)。\n */\nfunction executePress(el: Element, key: string): void {\n const tokens = splitKeyCombo(key);\n const mainKey = tokens[tokens.length - 1];\n const mods = tokens.slice(0, -1);\n const modState = {\n ctrlKey: mods.includes(\"Control\"),\n shiftKey: mods.includes(\"Shift\"),\n altKey: mods.includes(\"Alt\"),\n metaKey: mods.includes(\"Meta\"),\n };\n const hasNonShiftMod = modState.ctrlKey || modState.altKey || modState.metaKey;\n\n for (const m of mods) {\n el.dispatchEvent(new KeyboardEvent(\"keydown\", { key: m, code: resolveKeyCode(m), bubbles: true, cancelable: true, ...modState }));\n }\n const allowed = el.dispatchEvent(new KeyboardEvent(\"keydown\", { key: mainKey, code: resolveKeyCode(mainKey), bubbles: true, cancelable: true, ...modState }));\n // 只有无非 Shift 修饰键且是单字符时才发 keypress(参考 Playwright 文本抑制逻辑)\n if (allowed && mainKey.length === 1 && !hasNonShiftMod) {\n el.dispatchEvent(new KeyboardEvent(\"keypress\", { key: mainKey, code: resolveKeyCode(mainKey), bubbles: true, cancelable: true, ...modState }));\n }\n el.dispatchEvent(new KeyboardEvent(\"keyup\", { key: mainKey, code: resolveKeyCode(mainKey), bubbles: true, cancelable: true, ...modState }));\n for (let i = mods.length - 1; i >= 0; i--) {\n el.dispatchEvent(new KeyboardEvent(\"keyup\", { key: mods[i], code: resolveKeyCode(mods[i]), bubbles: true, cancelable: true, ...modState }));\n }\n}\n\n// ─── 元素描述 ───\n\nfunction describeElement(el: Element): string {\n const tag = el.tagName.toLowerCase();\n const id = el.id ? `#${el.id}` : \"\";\n const cls = el.className && typeof el.className === \"string\"\n ? el.className.trim().split(/\\s+/).filter(Boolean).slice(0, 3).map(c => `.${c}`).join(\"\") : \"\";\n const text = el instanceof HTMLSelectElement\n ? el.selectedOptions[0]?.textContent?.trim().slice(0, 40) ?? \"\"\n : el.textContent?.trim().slice(0, 40) ?? \"\";\n const textHint = text ? ` \"${text}\"` : \"\";\n const hints: string[] = [];\n for (const attr of [\"type\", \"name\", \"placeholder\", \"href\", \"role\"]) {\n const v = el.getAttribute(attr);\n if (v) hints.push(`${attr}=${v}`);\n }\n if (el instanceof HTMLSelectElement && el.value) hints.push(`val=${el.value}`);\n const attrHint = hints.length > 0 ? ` [${hints.join(\", \")}]` : \"\";\n return `<${tag}${id}${cls}>${textHint}${attrHint}`;\n}\n\n// ─── checkable 目标归一化 ───\n\nfunction isCheckableInput(el: Element | null): el is HTMLInputElement {\n return el instanceof HTMLInputElement && (el.type === \"checkbox\" || el.type === \"radio\");\n}\n\nfunction getChecked(el: Element): boolean | \"error\" {\n if (el instanceof HTMLInputElement && (el.type === \"checkbox\" || el.type === \"radio\")) return el.checked;\n const role = el.getAttribute(\"role\");\n if (role === \"checkbox\" || role === \"radio\" || role === \"switch\") return el.getAttribute(\"aria-checked\") === \"true\";\n return \"error\";\n}\n\n/**\n * 归一化 check/uncheck 目标:允许命中文本容器/label/div,回溯到关联 checkbox/radio。\n */\nfunction resolveCheckableTarget(el: Element): Element {\n if (getChecked(el) !== \"error\") return el;\n if (el instanceof HTMLLabelElement && el.control && getChecked(el.control) !== \"error\") return el.control;\n const ownerLabel = el.closest(\"label\") as HTMLLabelElement | null;\n if (ownerLabel?.control && getChecked(ownerLabel.control) !== \"error\") return ownerLabel.control;\n const inner = el.querySelector('input[type=\"checkbox\"], input[type=\"radio\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"]');\n if (inner && getChecked(inner) !== \"error\") return inner;\n const prev = el.previousElementSibling;\n if (prev && getChecked(prev) !== \"error\") return prev;\n const next = el.nextElementSibling;\n if (next && getChecked(next) !== \"error\") return next;\n const parent = el.parentElement;\n if (parent) {\n const inP = parent.querySelector('input[type=\"checkbox\"], input[type=\"radio\"], [role=\"checkbox\"], [role=\"radio\"], [role=\"switch\"]');\n if (inP && getChecked(inP) !== \"error\") return inP;\n }\n return el;\n}\n\n/**\n * 为 pointer 类动作(click/check/uncheck)解析可点击代理目标:\n * 当命中隐藏的原生 checkbox/radio/switch input 时,优先改点其可见 label/容器。\n */\nfunction resolvePointerActionTarget(el: Element): Element {\n if (!(el instanceof HTMLInputElement)) return el;\n\n const inputType = el.type?.toLowerCase() ?? \"\";\n const isCheckable = inputType === \"checkbox\" || inputType === \"radio\";\n if (!isCheckable && el.getAttribute(\"role\") !== \"switch\") return el;\n if (isElementVisible(el)) return el;\n\n const label = el.labels?.[0] ?? (el.closest(\"label\") as HTMLLabelElement | null);\n if (label && isElementVisible(label)) return label;\n\n const proxy = el.closest(\".el-switch, .el-checkbox, .el-radio, [role='switch'], [role='checkbox'], [role='radio']\");\n if (proxy && isElementVisible(proxy)) return proxy;\n\n const siblingProxy = el.parentElement?.querySelector(\n \".el-switch__core, .el-checkbox__inner, .el-radio__inner, [role='switch'], [role='checkbox'], [role='radio']\",\n );\n if (siblingProxy && isElementVisible(siblingProxy)) return siblingProxy;\n\n return el;\n}\n\n/**\n * 当命中表单项说明 label(如 Element Plus el-form-item__label)时,\n * 自动重定向到同一表单项中的首个可交互控件。\n */\nfunction resolveFormItemControlTarget(el: Element): Element {\n if (!(el instanceof HTMLElement)) return el;\n const isLabelLike = el.tagName === \"LABEL\" || el.classList.contains(\"el-form-item__label\");\n if (!isLabelLike) return el;\n\n const htmlLabel = el as HTMLLabelElement;\n if (htmlLabel.control && isElementVisible(htmlLabel.control)) return htmlLabel.control;\n\n const formItem = el.closest(\".el-form-item\");\n if (!formItem) return el;\n const content = formItem.querySelector(\".el-form-item__content\") ?? formItem;\n const control = content.querySelector(\n \"input:not([type='hidden']), textarea, select, button, [role='switch'], [role='checkbox'], [role='radio'], [role='button'], .el-switch, .el-checkbox, .el-radio, [tabindex]:not([tabindex='-1'])\",\n );\n if (control && isElementVisible(control)) return control;\n return el;\n}\n\n// ─── 自定义下拉增强 ───\n\nfunction findVisibleOptionByText(text: string): HTMLElement | null {\n const target = text.trim().toLowerCase();\n if (!target) return null;\n const selectors = [\n '[role=\"option\"]', '[role=\"listbox\"] li',\n \".el-select-dropdown__item\", \".el-option\", // Element Plus\n \".ant-select-item-option\", // Ant Design\n \".el-cascader-node\", \".el-dropdown-menu__item\",\n '[class*=\"option\"]', \"li[data-value]\", \"option\",\n ].join(\", \");\n const nodes = Array.from(document.querySelectorAll(selectors));\n const visible = nodes.filter(n => n instanceof HTMLElement && isElementVisible(n));\n for (const n of visible) { if (n.textContent?.trim().toLowerCase() === target) return n as HTMLElement; }\n for (const n of visible) { if (n.textContent?.trim().toLowerCase().includes(target)) return n as HTMLElement; }\n return null;\n}\n\nasync function waitForDropdownPopup(maxWait = 500): Promise<void> {\n const start = Date.now();\n while (Date.now() - start < maxWait) {\n const popup = document.querySelector('[role=\"listbox\"], .el-select-dropdown, .el-popper, .ant-select-dropdown, [class*=\"dropdown\"]');\n if (popup && isElementVisible(popup)) return;\n await sleep(50);\n }\n}\n\n// ─── 工具定义 ───\n\nexport function createDomTool(): ToolDefinition {\n return {\n name: \"dom\",\n description: [\n \"DOM actions on the current page.\",\n \"Actions: click, fill, select_option, clear, check, uncheck, type, focus, hover, scroll, press, get_text, get_attr, set_attr, add_class, remove_class.\",\n \"Prefer #hashID from snapshot as selector; use CSS only as compatibility fallback, not as the default strategy.\",\n \"Before fill/type/select_option, click or focus the same target in the same round.\",\n \"For multi-field forms, pair focus/click and fill/type per field in one batch.\",\n \"press supports combos like Enter or Control+a.\",\n \"Visual ordinal instructions use 1-based order.\",\n \"check/uncheck toggles via click and verifies the final state.\",\n \"Do not click nearby descriptive text, labels, or help text when a separate actionable control is visible; target the real interactive option that changes state.\",\n \"For custom widgets such as rating, slider, or composite pickers, prefer visible actionable child items; use fill for slider-like controls when appropriate.\",\n \"For virtualized lists, wheel pickers, or not-yet-visible options, scroll first and then click or select the newly visible target.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"DOM action name.\",\n }),\n selector: Type.String({ description: \"Prefer #hashID from snapshot; CSS selector is fallback only\" }),\n value: Type.Optional(Type.String({ description: \"Value for fill/type/set_attr\" })),\n key: Type.Optional(Type.String({ description: \"Key for press, supports combos\" })),\n label: Type.Optional(Type.String({ description: \"Label for select_option\" })),\n index: Type.Optional(Type.Number({ description: \"0-based option index\" })),\n attribute: Type.Optional(Type.String({ description: \"Attribute name\" })),\n className: Type.Optional(Type.String({ description: \"CSS class name\" })),\n clickCount: Type.Optional(Type.Number({ description: \"Click count\" })),\n deltaY: Type.Optional(Type.Number({ description: \"Vertical scroll delta\" })),\n deltaX: Type.Optional(Type.Number({ description: \"Horizontal scroll delta\" })),\n steps: Type.Optional(Type.Number({ description: \"Scroll repeat count\" })),\n waitMs: Type.Optional(Type.Number({ description: \"Wait timeout in ms\" })),\n waitSeconds: Type.Optional(Type.Number({ description: \"Wait timeout in seconds\" })),\n force: Type.Optional(Type.Boolean({ description: \"Skip actionability checks\" })),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n const selector = params.selector as string;\n const waitMs = resolveWaitMs(params);\n const force = params.force === true;\n\n if (!selector) return { content: \"缺少 selector 参数\" };\n\n // ── 元素查找 ──\n let el: Element;\n if (waitMs > 0) {\n const found = await waitForElement(selector, waitMs);\n if (typeof found === \"string\") return { content: found, details: { error: true, code: \"INVALID_SELECTOR\", action, selector } };\n if (!found) return { content: `未找到匹配 \"${selector}\" 的元素`, details: { error: true, code: \"ELEMENT_NOT_FOUND\", action, selector, waitMs } };\n el = found;\n } else {\n const r = queryElement(selector);\n if (typeof r === \"string\") return { content: r, details: { error: true, code: r.startsWith(\"未找到\") ? \"ELEMENT_NOT_FOUND\" : \"INVALID_SELECTOR\", action, selector, waitMs } };\n el = r;\n }\n\n // check/uncheck 归一化\n if (action === \"check\" || action === \"uncheck\") {\n el = resolveCheckableTarget(el);\n }\n\n const actionabilityTarget =\n action === \"click\" || action === \"check\" || action === \"uncheck\"\n ? resolvePointerActionTarget(resolveFormItemControlTarget(el))\n : el;\n\n try {\n // actionability(skip for force / read-only actions)\n const checkResult = ensureActionable(actionabilityTarget, action, selector, force);\n if (checkResult) return checkResult;\n\n switch (action) {\n // ─── click ───\n case \"click\": {\n const target = resolvePointerActionTarget(resolveFormItemControlTarget(retarget(el, force ? \"none\" : \"button-link\")));\n const clickCount = typeof params.clickCount === \"number\" ? params.clickCount : 1;\n\n // option 元素自动写回 select\n if (target instanceof HTMLOptionElement) {\n const parent = target.parentElement;\n if (parent instanceof HTMLSelectElement) {\n parent.focus(); parent.value = target.value;\n dispatchInputEvents(parent);\n return { content: `已选择 ${describeElement(parent)} 的选项 \"${target.value}\"` };\n }\n }\n\n if (target instanceof HTMLElement) {\n scrollIntoViewIfNeeded(target);\n // stable 检查(参考 Playwright)\n if (!force) await checkElementStable(target, 500);\n // hit-target 检查\n if (!force) {\n const blocker = checkHitTarget(target);\n if (blocker) {\n scrollIntoViewIfNeeded(target, 1);\n await sleep(100);\n // 第二次检查仍被遮挡时 warn 但不阻断\n }\n }\n dispatchClickEvents(target, clickCount);\n } else {\n target.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n }\n return { content: `已点击 ${describeElement(target)}` };\n }\n\n // ─── fill(参考 Playwright 分类型策略) ───\n case \"fill\": {\n const value = params.value as string;\n if (value === undefined) return { content: \"缺少 value 参数\" };\n const target = retarget(el, \"follow-label\");\n\n // role=slider 特化:优先写关联数字输入框,其次点击离散子项(评分星级)\n if (target instanceof HTMLElement && target.getAttribute(\"role\") === \"slider\") {\n const numericValue = Number(value);\n if (!Number.isFinite(numericValue)) {\n const guessed = guessNearbyFillTarget(target, value);\n if (guessed) {\n const guessedResult = executeFillOnResolvedTarget(guessed, value, selector, action, \"heuristic-nearby-target\");\n if (guessedResult) return guessedResult;\n }\n return { content: `\"${selector}\" 为 role=slider,未找到可推断填写目标`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n\n const linkedInput = findAssociatedSliderInput(target);\n if (linkedInput) {\n const filled = executeFillOnResolvedTarget(linkedInput, String(numericValue), selector, action, `from ${describeElement(target)}`);\n if (filled) return filled;\n }\n\n const min = Number(target.getAttribute(\"aria-valuemin\") ?? \"1\");\n const max = Number(target.getAttribute(\"aria-valuemax\") ?? String(target.children.length || 5));\n const discreteCount = Number.isFinite(max - min + 1) ? Math.max(1, Math.round(max - min + 1)) : target.children.length;\n const desiredIndex = Math.round(numericValue - min);\n const children = Array.from(target.children).filter((node): node is HTMLElement => node instanceof HTMLElement);\n\n if (children.length >= discreteCount && desiredIndex >= 0 && desiredIndex < children.length) {\n const item = children[desiredIndex];\n scrollIntoViewIfNeeded(item);\n dispatchClickEvents(item);\n return { content: `已点击 ${describeElement(item)},设置 ${describeElement(target)} 值为 ${numericValue}` };\n }\n\n const guessed = guessNearbyFillTarget(target, String(numericValue));\n if (guessed) {\n const guessedResult = executeFillOnResolvedTarget(guessed, String(numericValue), selector, action, \"heuristic-nearby-target\");\n if (guessedResult) return guessedResult;\n }\n\n return { content: `\"${selector}\" 为 role=slider,但未找到可写入输入框或可点击离散子项`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n\n const directFilled = executeFillOnResolvedTarget(target, value, selector, action);\n if (directFilled) return directFilled;\n\n const guessed = guessNearbyFillTarget(target, value);\n if (guessed) {\n const guessedResult = executeFillOnResolvedTarget(guessed, value, selector, action, \"heuristic-nearby-target\");\n if (guessedResult) return guessedResult;\n }\n\n return { content: `\"${selector}\" 不是可编辑元素,且未在附近找到可推断填写目标`, details: { error: true, code: \"UNSUPPORTED_FILL_TARGET\", action, selector } };\n }\n\n // ─── select_option(参考 Playwright selectOptions 多策略匹配) ───\n case \"select_option\": {\n const value = params.value as string | undefined;\n const label = params.label as string | undefined;\n const index = typeof params.index === \"number\" ? Math.floor(params.index) : undefined;\n if (value === undefined && label === undefined && index === undefined) {\n return { content: \"缺少可选参数:value 或 label 或 index\" };\n }\n\n const target = retarget(el, \"follow-label\");\n\n // 非原生 <select>:自定义下拉\n if (!(target instanceof HTMLSelectElement)) {\n if (!(target instanceof HTMLElement)) return { content: `\"${selector}\" 不是下拉框元素` };\n scrollIntoViewIfNeeded(target);\n const wanted = (label ?? value ?? \"\").trim();\n if (!wanted) return { content: `\"${selector}\" 为自定义下拉时,需提供 value 或 label` };\n dispatchClickEvents(target); // 点击触发器打开\n await waitForDropdownPopup(800);\n const option = findVisibleOptionByText(wanted);\n if (!option) return { content: `未找到与 \"${wanted}\" 匹配的可见下拉选项(自定义下拉)`, details: { error: true, code: \"OPTION_NOT_FOUND\", action, selector, wanted } };\n dispatchClickEvents(option);\n return { content: `已在自定义下拉中选择 \"${wanted}\"` };\n }\n\n // 原生 <select>\n target.focus();\n const options = Array.from(target.options);\n let selected: HTMLOptionElement | undefined;\n if (value !== undefined) selected = options.find(o => o.value === value);\n if (!selected && label !== undefined) { const nl = label.trim().toLowerCase(); selected = options.find(o => o.text.trim().toLowerCase() === nl); }\n if (!selected && value !== undefined) { const nv = value.trim().toLowerCase(); selected = options.find(o => o.text.trim().toLowerCase() === nv); }\n if (!selected && index !== undefined) {\n if (index < 0 || index >= options.length) return { content: `\"${selector}\" 下拉框不存在 index=${index} 的选项` };\n selected = options[index];\n }\n if (!selected) return { content: `\"${selector}\" 下拉框中不存在选项 \"${value ?? label ?? `index=${index}`}\"` };\n // option disabled 检查(参考 Playwright)\n if (selected.disabled) return { content: `\"${selector}\" 目标选项已禁用:${selected.value}`, details: { error: true, code: \"OPTION_DISABLED\", action, selector } };\n if (!target.multiple) { for (const o of options) o.selected = false; }\n selected.selected = true;\n target.value = selected.value;\n dispatchInputEvents(target);\n return { content: `已选择 ${describeElement(target)}: value=\"${selected.value}\", label=\"${selected.text.trim()}\"` };\n }\n\n // ─── clear ───\n case \"clear\": {\n const target = retarget(el, \"follow-label\");\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n scrollIntoViewIfNeeded(target);\n target.focus(); selectText(target);\n setNativeValue(target as HTMLInputElement, \"\");\n dispatchInputEvents(target);\n return { content: `已清空 ${describeElement(target)}` };\n }\n if (target instanceof HTMLSelectElement) {\n target.focus(); target.value = \"\";\n dispatchInputEvents(target);\n return { content: `已清空 ${describeElement(target)}` };\n }\n if (target instanceof HTMLElement && target.isContentEditable) {\n target.focus(); selectText(target);\n document.execCommand(\"delete\", false, undefined);\n return { content: `已清空 ${describeElement(target)}` };\n }\n return { content: `\"${selector}\" 不是可清空元素` };\n }\n\n // ─── check / uncheck(参考 Playwright:通过 click 切换 + 验证状态) ───\n case \"check\":\n case \"uncheck\": {\n const wantChecked = action === \"check\";\n const current = getChecked(el);\n if (current === \"error\") {\n return { content: `\"${selector}\" 不是 checkbox/radio/[role=checkbox]/[role=radio],无法 ${action}`, details: { error: true, code: \"NOT_CHECKABLE\", action, selector } };\n }\n // 已是目标状态(幂等,参考 Playwright)\n if (current === wantChecked) return { content: `${describeElement(el)} 已经是${wantChecked ? \"选中\" : \"未选中\"}状态` };\n // radio 不能 uncheck\n if (!wantChecked && el instanceof HTMLInputElement && el.type === \"radio\") {\n return { content: `无法取消 radio 按钮的选中状态`, details: { error: true, code: \"CANNOT_UNCHECK_RADIO\", action, selector } };\n }\n // 通过 click 切换(参考 Playwright _setChecked)\n const pointerTarget = resolvePointerActionTarget(el);\n scrollIntoViewIfNeeded(pointerTarget);\n if (pointerTarget instanceof HTMLElement) dispatchClickEvents(pointerTarget);\n else pointerTarget.dispatchEvent(new MouseEvent(\"click\", { bubbles: true }));\n // 验证状态变更\n await sleep(50);\n const finalState = getChecked(el);\n if (finalState !== wantChecked && el instanceof HTMLInputElement) {\n el.checked = wantChecked;\n dispatchInputEvents(el);\n }\n return { content: `已${wantChecked ? \"勾选\" : \"取消勾选\"} ${describeElement(el)}` };\n }\n\n // ─── type(逐字符键入) ───\n case \"type\": {\n const value = params.value as string;\n if (value === undefined) return { content: \"缺少 value 参数\" };\n const target = retarget(el, \"follow-label\");\n scrollIntoViewIfNeeded(target);\n if (target instanceof HTMLElement) target.focus();\n\n for (const char of value) {\n const init: KeyboardEventInit = { key: char, code: resolveKeyCode(char), bubbles: true, cancelable: true };\n target.dispatchEvent(new KeyboardEvent(\"keydown\", init));\n target.dispatchEvent(new KeyboardEvent(\"keypress\", init));\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n const proto = target instanceof HTMLInputElement ? HTMLInputElement.prototype : HTMLTextAreaElement.prototype;\n const nativeSet = Object.getOwnPropertyDescriptor(proto, \"value\")?.set;\n if (nativeSet) nativeSet.call(target, target.value + char); else target.value += char;\n } else if (target instanceof HTMLElement && target.isContentEditable) {\n document.execCommand(\"insertText\", false, char);\n }\n target.dispatchEvent(new Event(\"input\", { bubbles: true, composed: true }));\n target.dispatchEvent(new KeyboardEvent(\"keyup\", init));\n }\n if (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) {\n target.dispatchEvent(new Event(\"change\", { bubbles: true }));\n }\n return { content: `已逐字输入到 ${describeElement(target)}: \"${value}\"` };\n }\n\n // ─── focus(参考 Playwright:双次 focus) ───\n case \"focus\": {\n const target = retarget(el, \"follow-label\");\n if (target instanceof HTMLElement || target instanceof SVGElement) {\n target.focus(); target.focus(); // Playwright workaround: 双次 focus\n }\n return { content: `已聚焦 ${describeElement(target)}` };\n }\n\n // ─── hover ───\n case \"hover\": {\n const target = retarget(el, \"none\");\n scrollIntoViewIfNeeded(target);\n if (!force) await checkElementStable(target, 500);\n if (target instanceof HTMLElement) dispatchHoverEvents(target);\n return { content: `已悬停 ${describeElement(target)}` };\n }\n\n // ─── scroll(组件内滚动,适配时间滚轮/虚拟列表) ───\n case \"scroll\": {\n const target = retarget(el, \"none\");\n const deltaY = typeof params.deltaY === \"number\"\n ? params.deltaY\n : (typeof params.value === \"string\" && !Number.isNaN(Number(params.value)) ? Number(params.value) : 180);\n const deltaX = typeof params.deltaX === \"number\" ? params.deltaX : 0;\n const rawSteps = typeof params.steps === \"number\" ? Math.floor(params.steps) : 1;\n const steps = Math.min(20, Math.max(1, rawSteps));\n\n if (target instanceof HTMLElement) {\n scrollIntoViewIfNeeded(target);\n for (let i = 0; i < steps; i++) {\n target.scrollBy({ top: deltaY, left: deltaX, behavior: \"auto\" });\n target.dispatchEvent(new WheelEvent(\"wheel\", {\n bubbles: true,\n cancelable: true,\n deltaY,\n deltaX,\n }));\n }\n return { content: `已滚动 ${describeElement(target)}: deltaY=${deltaY}, deltaX=${deltaX}, steps=${steps}` };\n }\n\n for (let i = 0; i < steps; i++) {\n target.dispatchEvent(new WheelEvent(\"wheel\", {\n bubbles: true,\n cancelable: true,\n deltaY,\n deltaX,\n }));\n }\n return { content: `已滚动 ${describeElement(target)}: deltaY=${deltaY}, deltaX=${deltaX}, steps=${steps}` };\n }\n\n // ─── press(支持组合键) ───\n case \"press\": {\n const key = (params.key as string) || (params.value as string);\n if (!key) return { content: \"缺少 key 参数(如 Enter, Escape, Tab, Control+a)\" };\n const target = retarget(el, \"none\");\n scrollIntoViewIfNeeded(target);\n if (target instanceof HTMLElement) target.focus();\n executePress(target, key);\n // Enter 特殊:触发 form submit\n const mainKey = splitKeyCombo(key).pop();\n if (mainKey === \"Enter\") {\n const form = (target instanceof HTMLInputElement || target instanceof HTMLTextAreaElement) ? (target.form ?? target.closest(\"form\")) : target.closest(\"form\");\n form?.dispatchEvent(new Event(\"submit\", { bubbles: true, cancelable: true }));\n }\n return { content: `已在 ${describeElement(target)} 上按下 ${key}` };\n }\n\n // ─── 读取类 ───\n case \"get_text\": {\n const text = el.textContent?.trim() ?? \"\";\n return { content: `${describeElement(el)} 的文本内容:${text || \"(空)\"}` };\n }\n case \"get_attr\": {\n const attribute = params.attribute as string;\n if (!attribute) return { content: \"缺少 attribute 参数\" };\n const attrName = attribute.toLowerCase();\n if (attrName === \"checked\") {\n if (el instanceof HTMLInputElement) return { content: `${describeElement(el)} 的 checked = ${String(el.checked)}` };\n return { content: `${describeElement(el)} 的 checked = ${el.getAttribute(\"aria-checked\") ?? \"(不存在)\"}` };\n }\n if (attrName === \"selected\") {\n if (el instanceof HTMLOptionElement) return { content: `${describeElement(el)} 的 selected = ${String(el.selected)}` };\n return { content: `${describeElement(el)} 的 selected = ${el.getAttribute(\"aria-selected\") ?? \"(不存在)\"}` };\n }\n if (attrName === \"disabled\") {\n if (el instanceof HTMLButtonElement || el instanceof HTMLInputElement || el instanceof HTMLSelectElement || el instanceof HTMLTextAreaElement) {\n return { content: `${describeElement(el)} 的 disabled = ${String(el.disabled)}` };\n }\n }\n if (attrName === \"readonly\" && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement)) {\n return { content: `${describeElement(el)} 的 readonly = ${String(el.readOnly)}` };\n }\n if (attrName === \"value\" && (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement)) {\n return { content: `${describeElement(el)} 的 value = ${el.value || \"(空)\"}` };\n }\n return { content: `${describeElement(el)} 的 ${attribute} = ${el.getAttribute(attribute) ?? \"(不存在)\"}` };\n }\n\n // ─── 修改类 ───\n case \"set_attr\": {\n const attribute = params.attribute as string;\n const value = params.value as string;\n if (!attribute || value === undefined) return { content: \"缺少 attribute 或 value 参数\" };\n el.setAttribute(attribute, value);\n return { content: `已设置 ${describeElement(el)} 的 ${attribute}=\"${value}\"` };\n }\n case \"add_class\": {\n const className = params.className as string;\n if (!className) return { content: \"缺少 className 参数\" };\n el.classList.add(className);\n return { content: `已添加 class \"${className}\" 到 ${describeElement(el)}` };\n }\n case \"remove_class\": {\n const className = params.className as string;\n if (!className) return { content: \"缺少 className 参数\" };\n el.classList.remove(className);\n return { content: `已移除 ${describeElement(el)} 的 class \"${className}\"` };\n }\n\n default:\n return { content: `未知的 DOM 动作: ${action}` };\n }\n } catch (err) {\n return { content: `DOM 操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`, details: { error: true, action, selector } };\n }\n },\n };\n}","/**\n * Page Info Tool — 基于 Web API 的页面信息获取工具。\n *\n * 替代 Playwright 的 getTitle/getUrl/snapshot 等。\n * 运行环境:浏览器 Content Script。\n *\n * 支持 6 种动作:\n * get_url — 获取当前页面 URL\n * get_title — 获取页面标题\n * get_selection — 获取用户选中的文本\n * get_viewport — 获取视口尺寸和滚动位置\n * snapshot — 获取页面 DOM 结构快照(AI 可读的文本描述)\n * query_all — 查询所有匹配选择器的元素,返回摘要信息\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport type { RefStore } from \"../ref-store.js\";\nimport { getTrackedElementEvents, hasTrackedElementEvents } from \"../event-listener-tracker.js\";\nimport { getActiveRefStore } from \"./dom-tool.js\";\n\n/** 快照配置选项 */\nexport type SnapshotOptions = {\n /** 最大遍历深度(默认 12) */\n maxDepth?: number;\n /**\n * 视口裁剪:只保留与视口相交的元素(默认 true)。\n * 开启后,完全在视口外的元素会被跳过,大幅减少 token 消耗。\n * 注意:祖先容器即使自身不在视口内,只要有子元素在视口内就会保留。\n */\n viewportOnly?: boolean;\n /**\n * 智能剪枝:折叠无意义的纯布局容器(默认 true)。\n * 开启后,没有文本、没有 id、没有交互属性的纯布局元素(div/span/section 等)\n * 如果自身无意义,会被折叠——子元素直接提升到父级输出,减少嵌套噪音。\n */\n pruneLayout?: boolean;\n /**\n * hash ID 映射表(可选)。\n * 传入 RefStore 实例后,每个元素使用确定性 hash ID 替代完整 XPath,\n * 大幅减少 token 消耗。dom-tool 通过 RefStore.get(id) 解析回 DOM 元素。\n */\n refStore?: RefStore;\n /** 最大输出节点数(默认 220),超过后停止继续遍历。 */\n maxNodes?: number;\n /** 每个父节点最多输出的子元素数(默认 25),超出部分会折叠。 */\n maxChildren?: number;\n /** 文本截断长度(默认 40)。 */\n maxTextLength?: number;\n /**\n * 是否对“选项列表”容器放宽子节点截断(默认 false)。\n * 典型场景:时间选择器/下拉选项列表,避免关键选项被 `...children omitted` 折叠。\n */\n expandOptionLists?: boolean;\n /**\n * 仅对指定 hash ref 节点放宽子节点截断(优先级高于默认 maxChildren)。\n * 例如:[#abc123, #def456],用于 AI 在看到 children omitted 后定向请求放宽。\n */\n expandChildrenRefs?: string[];\n /** 对 expandChildrenRefs 节点生效的子节点上限(默认 120)。 */\n expandedChildrenLimit?: number;\n /**\n * 快照中允许输出的 listener 事件白名单(默认仅输出常用事件)。\n * 例如:['click', 'input', 'change', 'mousedown']。\n * 仅影响 `listeners=\"...\"` 文本输出,不影响内部交互判定与 hash 分配。\n */\n listenerEvents?: string[];\n /**\n * class 名过滤正则列表(默认开启常用 UI 框架过滤)。\n * 每项为正则字符串,class 名匹配任一正则即从快照中剔除。\n * - 默认(undefined):启用内置规则,剔除 Element Plus / AntD / BK / TDesign / Arco / Vant / Naive 等。\n * - 自定义 string[]:替换默认规则,使用自定义正则。\n * - false:禁用过滤,保留所有 class。\n */\n classNameFilter?: string[] | false;\n};\n\n/**\n * 内置 class 名过滤正则(剔除常见 UI 框架噪音类名)。\n * 通过匹配组件关键词(如 -button、-input、-dialog)统一覆盖所有框架,\n * 无需逐一枚举框架前缀。\n */\nconst DEFAULT_CLASSNAME_FILTERS: string[] = [\n // 通用组件关键词:匹配 class 中含 -button / -input 等的类名\n // 保留悬浮层相关类名(dialog/modal/drawer/popover/tooltip/popper/overlay/popup/dropdown)以便 AI 识别弹层结构\n \"-(?:button|btn|input|select|option|tag|badge|menu|menuitem|tab|tabs|table|thead|tbody|tfoot|th|td|form|form-item|field|label|checkbox|radio|switch|slider|rate|upload|tree|collapse|breadcrumb|pagination|pager|step|steps|progress|cascader|transfer|picker|date-picker|time-picker|color-picker|auto-complete|autocomplete|card|alert|message|notification|notify|toast|spin|spinner|loading|skeleton|empty|result|avatar|icon|image|divider|space|scrollbar|affix|anchor|back-top|backtop|watermark|segmented|descriptions|statistic|countdown|row|col|grid|layout|container|header|footer|aside|main|sidebar|wrapper|inner|content|prefix|suffix|append|prepend|cell|column|group|panel|item|list|body|close|arrow|placeholder|trigger|reference|transition)\",\n];\n\n/** 快照属性值最大保留长度(超出截断)。 */\nconst MAX_SNAPSHOT_ATTR_VALUE_LENGTH = 120;\n/** 选项列表放宽时的子节点上限(仍保留硬上限,避免快照无限膨胀)。 */\nconst MAX_EXPANDED_LIST_CHILDREN = 120;\n/** 定向放宽 children 的硬上限。 */\nconst MAX_EXPANDED_CHILDREN_LIMIT = 300;\n/** 快照默认保留的高价值 listener 事件(控制 token 体积)。 */\nconst DEFAULT_SNAPSHOT_LISTENER_EVENTS = [\n \"click\",\n \"input\",\n \"change\",\n \"mousedown\",\n \"pointerdown\",\n \"keydown\",\n \"submit\",\n \"focus\",\n \"blur\",\n];\n\n/** 事件名 → 快照简写映射(压缩 token)。 */\nconst EVENT_ABBREV: Record<string, string> = {\n click: \"clk\", dblclick: \"dbl\",\n mousedown: \"mdn\", mouseup: \"mup\", mousemove: \"mmv\",\n mouseover: \"mov\", mouseout: \"mot\", mouseenter: \"men\", mouseleave: \"mlv\",\n pointerdown: \"pdn\", pointerup: \"pup\", pointermove: \"pmv\",\n touchstart: \"tst\", touchend: \"ted\",\n keydown: \"kdn\", keyup: \"kup\",\n input: \"inp\", change: \"chg\", submit: \"sub\",\n focus: \"fcs\", blur: \"blr\",\n scroll: \"scl\", wheel: \"whl\",\n drag: \"drg\", dragstart: \"drs\", dragend: \"dre\", drop: \"drp\",\n contextmenu: \"ctx\",\n};\n\nfunction abbrevEvent(name: string): string {\n return EVENT_ABBREV[name] ?? name.slice(0, 3);\n}\n\nfunction normalizeSnapshotListenerEvent(name: string): string {\n return name.trim().toLowerCase();\n}\n\n/**\n * 规整快照属性值,避免把长 base64/data URL 原样注入快照。\n */\nfunction sanitizeSnapshotAttrValue(value: string): string {\n const trimmed = value.trim();\n if (!trimmed) return \"\";\n\n const dataUrlMatch = trimmed.match(/^data:([^,]*?),(.*)$/i);\n if (dataUrlMatch) {\n const meta = dataUrlMatch[1] || \"\";\n const payload = dataUrlMatch[2] || \"\";\n const isBase64 = /;base64/i.test(meta);\n const payloadLength = payload.length;\n const previewMeta = meta.slice(0, 48);\n if (isBase64 || payloadLength > 64) {\n return `data:${previewMeta},<omitted:${payloadLength}>`;\n }\n }\n\n const base64ChunkMatch = trimmed.match(/^[A-Za-z0-9+/]{80,}={0,2}$/);\n if (base64ChunkMatch) {\n return `<base64:${trimmed.length}>`;\n }\n\n if (trimmed.length > MAX_SNAPSHOT_ATTR_VALUE_LENGTH) {\n return `${trimmed.slice(0, MAX_SNAPSHOT_ATTR_VALUE_LENGTH)}...`;\n }\n return trimmed;\n}\n\n/**\n * 生成页面 DOM 快照 — 将 DOM 树转为 AI 可理解的文本描述。\n *\n * 基于 Web API 实现,只遍历可见元素,跳过 script/style/svg 等无意义节点。\n * 传入 RefStore 时,每个元素生成确定性 hash ID(如 #a1b2c),\n * AI 通过 hash ID 精确定位元素,无需猜测 CSS 选择器。\n *\n * 输出格式示例:\n * [header] #k9f2a\n * [nav] #m3d7e\n * [a] \"首页\" href=\"/\" #p1c4b\n * [a] \"关于\" href=\"/about\" #q8e5f\n * [main] #r2a6d\n * [h1] \"欢迎\" #s7g3h\n * [input] type=\"text\" placeholder=\"搜索...\" #t4j8k\n * [button] \"搜索\" id=\"search-btn\" onclick #u5n2m\n *\n * @param root - 快照根元素(默认 document.body)\n * @param options - 快照选项对象,或传入数字作为 maxDepth(向后兼容)\n */\nexport function generateSnapshot(\n root: Element = document.body,\n options: SnapshotOptions | number = {},\n): string {\n // 向后兼容:数字参数视为 maxDepth\n const opts: SnapshotOptions = typeof options === \"number\"\n ? { maxDepth: options }\n : options;\n\n const maxDepth = opts.maxDepth ?? 12;\n const viewportOnly = opts.viewportOnly ?? true;\n const pruneLayout = opts.pruneLayout ?? true;\n const maxNodes = opts.maxNodes ?? 220;\n const maxChildren = opts.maxChildren ?? 25;\n const maxTextLength = opts.maxTextLength ?? 40;\n const expandOptionLists = opts.expandOptionLists ?? false;\n const expandedChildrenLimit = Math.min(\n MAX_EXPANDED_CHILDREN_LIMIT,\n Math.max(1, opts.expandedChildrenLimit ?? MAX_EXPANDED_LIST_CHILDREN),\n );\n const expandChildrenRefSet = new Set(\n (opts.expandChildrenRefs ?? [])\n .map(ref => ref.trim().replace(/^#/, \"\"))\n .filter(Boolean),\n );\n const allowedListenerEvents = new Set(\n (opts.listenerEvents && opts.listenerEvents.length > 0\n ? opts.listenerEvents\n : DEFAULT_SNAPSHOT_LISTENER_EVENTS)\n .map(normalizeSnapshotListenerEvent)\n .filter(Boolean),\n );\n const classNameFilterRegexps: RegExp[] | null = opts.classNameFilter === false\n ? null\n : (opts.classNameFilter && opts.classNameFilter.length > 0\n ? opts.classNameFilter\n : DEFAULT_CLASSNAME_FILTERS\n ).map(p => new RegExp(p));\n\n let emittedNodes = 0;\n let truncatedByNodeBudget = false;\n\n const refStore = opts.refStore;\n\n const SKIP_TAGS = new Set([\n \"SCRIPT\", \"STYLE\", \"SVG\", \"NOSCRIPT\", \"LINK\", \"META\", \"BR\", \"HR\",\n \"COLGROUP\", \"COL\",\n ]);\n\n /** 纯布局容器标签 — 智能剪枝时可能被折叠 */\n const LAYOUT_TAGS = new Set([\n \"DIV\", \"SPAN\", \"SECTION\", \"ARTICLE\", \"ASIDE\", \"MAIN\",\n \"HEADER\", \"FOOTER\", \"NAV\", \"FIGURE\", \"FIGCAPTION\",\n ]);\n\n /** 视口尺寸(viewportOnly 开启时使用) */\n const vpWidth = viewportOnly ? window.innerWidth : 0;\n const vpHeight = viewportOnly ? window.innerHeight : 0;\n\n const INTERACTIVE_ATTRS = [\n \"href\", \"type\", \"placeholder\", \"value\", \"name\", \"role\", \"aria-label\",\n \"src\", \"alt\", \"title\", \"for\", \"action\", \"method\",\n ];\n\n const INTERACTIVE_TAGS = new Set([\n \"A\", \"BUTTON\", \"INPUT\", \"TEXTAREA\", \"SELECT\", \"OPTION\", \"LABEL\", \"SUMMARY\",\n ]);\n\n const INTERACTIVE_EVENTS = new Set([\n \"click\", \"dblclick\", \"mousedown\", \"mouseup\", \"pointerdown\", \"pointerup\",\n \"touchstart\", \"touchend\", \"input\", \"change\", \"keydown\", \"keyup\",\n \"submit\", \"focus\", \"blur\",\n ]);\n\n /** 交互性 ARIA role — 需要分配 hash ID 的角色集合 */\n const INTERACTIVE_ROLES = new Set([\n \"button\", \"link\", \"tab\", \"switch\", \"slider\", \"checkbox\", \"radio\",\n \"combobox\", \"listbox\", \"option\", \"menuitem\", \"textbox\", \"spinbutton\",\n \"searchbox\", \"treeitem\", \"gridcell\", \"scrollbar\",\n ]);\n\n /**\n * 事件优先级(值越大越优先):\n * 输入链路(input/change/focus/blur) > 点击链路(click/pointer) > 其他事件。\n */\n const EVENT_PRIORITY: Record<string, number> = {\n input: 140,\n change: 130,\n focus: 120,\n blur: 110,\n keydown: 100,\n keyup: 90,\n click: 80,\n dblclick: 70,\n pointerdown: 60,\n pointerup: 55,\n mousedown: 50,\n mouseup: 45,\n touchstart: 40,\n touchend: 35,\n submit: 30,\n };\n\n /** 布尔状态属性 — 只在存在时输出(无值),如 disabled、checked */\n const BOOLEAN_ATTRS = [\n \"disabled\", \"checked\", \"readonly\", \"required\", \"selected\",\n \"hidden\",\n ];\n\n /**\n * 计算元素在父节点中同标签兄弟里的序号(1-based,XPath 规范)。\n * 如果同标签兄弟只有一个,返回空字符串(无需索引消歧)。\n */\n function getSiblingIndex(el: Element): string {\n const parent = el.parentElement;\n if (!parent) return \"\";\n const tag = el.tagName;\n const siblings = Array.from(parent.children).filter((c) => c.tagName === tag);\n if (siblings.length <= 1) return \"\";\n return `[${siblings.indexOf(el) + 1}]`;\n }\n\n /**\n * 判断元素是否与视口相交(部分可见也算)。\n * 对根级容器(depth <= 1)始终返回 true,确保不丢失顶层结构。\n */\n function isInViewport(el: Element, depth: number): boolean {\n if (!viewportOnly) return true;\n // 根级容器始终保留(body/html 等),否则整棵树会被跳过\n if (depth <= 1) return true;\n const rect = el.getBoundingClientRect();\n // 元素完全在视口外则跳过\n if (rect.bottom < 0 || rect.top > vpHeight) return false;\n if (rect.right < 0 || rect.left > vpWidth) return false;\n // 零尺寸元素(如隐藏的 position:absolute 元素)也跳过\n if (rect.width === 0 && rect.height === 0) return false;\n return true;\n }\n\n /**\n * 判断元素是否为「无意义布局容器」(智能剪枝候选)。\n * 满足所有条件时返回 true:\n * 1. 标签是常见布局容器(div/span/section 等)\n * 2. 没有 id\n * 3. 没有交互属性(href/role/aria-label/onclick 等)\n * 4. 没有直接文本内容\n */\n function isEmptyLayoutContainer(el: Element, directText: string): boolean {\n if (!pruneLayout) return false;\n if (!LAYOUT_TAGS.has(el.tagName)) return false;\n // 有 id 的元素可能是重要锚点\n if (el.getAttribute(\"id\")) return false;\n // 有 role/aria-label 的元素有语义\n if (el.getAttribute(\"role\") || el.getAttribute(\"aria-label\")) return false;\n // 有内联事件(onclick 等)的元素有交互\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) return false;\n }\n // 运行时追踪到事件绑定的元素有交互语义\n if (hasTrackedElementEvents(el)) return false;\n // 有直接文本内容的元素有意义\n if (directText) return false;\n return true;\n }\n\n function hasInteractiveTrackedEvents(el: Element): boolean {\n const tracked = getTrackedElementEvents(el);\n if (tracked.length === 0) return false;\n return tracked.some(name => INTERACTIVE_EVENTS.has(name));\n }\n\n function getSnapshotListenerEvents(el: Element): string[] {\n const tracked = getTrackedElementEvents(el);\n if (tracked.length === 0) return [];\n return tracked.filter(name => allowedListenerEvents.has(normalizeSnapshotListenerEvent(name)));\n }\n\n function getTrackedEventPriorityScore(el: Element): number {\n const tracked = getTrackedElementEvents(el);\n if (tracked.length === 0) return 0;\n\n let score = 0;\n for (const name of tracked) {\n score += EVENT_PRIORITY[name] ?? 8;\n }\n return score;\n }\n\n /**\n * 元素优先级:\n * 1) 输入控件/按钮等语义控件\n * 2) 事件追踪优先级(输入、点击、失焦等)\n * 3) inline 事件与可聚焦能力补充加分\n */\n function getElementPriorityScore(el: Element): number {\n let score = 0;\n\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement) {\n score += 200;\n } else if (el instanceof HTMLButtonElement || el instanceof HTMLAnchorElement) {\n score += 180;\n } else if (el.getAttribute(\"role\") === \"button\" || el.getAttribute(\"role\") === \"switch\" || el.getAttribute(\"role\") === \"slider\") {\n score += 160;\n }\n\n score += getTrackedEventPriorityScore(el);\n\n if (el.hasAttribute(\"onclick\")) score += 60;\n if (el.hasAttribute(\"oninput\") || el.hasAttribute(\"onchange\")) score += 80;\n if (el.hasAttribute(\"onfocus\") || el.hasAttribute(\"onblur\")) score += 70;\n if (el.hasAttribute(\"tabindex\")) score += 20;\n\n return score;\n }\n\n function orderChildrenByPriority(children: Element[]): Element[] {\n return children\n .map((child, index) => ({\n child,\n index,\n interactive: isInteractiveElement(child),\n score: getElementPriorityScore(child),\n }))\n .sort((a, b) => {\n if (a.interactive !== b.interactive) return a.interactive ? -1 : 1;\n if (b.score !== a.score) return b.score - a.score;\n return a.index - b.index;\n })\n .map(entry => entry.child);\n }\n\n function isInteractiveElement(el: Element): boolean {\n if (INTERACTIVE_TAGS.has(el.tagName)) return true;\n if (el.hasAttribute(\"onclick\")) return true;\n if (el.hasAttribute(\"role\")) return true;\n if (el.hasAttribute(\"tabindex\")) return true;\n if (el.hasAttribute(\"aria-label\")) return true;\n if (hasInteractiveTrackedEvents(el)) return true;\n return false;\n }\n\n /**\n * 判断元素是否需要分配 hash ID(仅交互节点分配,节省 token)。\n *\n * 核心依据:元素是否绑定了交互事件(INTERACTIVE_EVENTS 集合)。\n * 辅助依据:语义交互标签、内联事件、ARIA role、tabindex 等兜底。\n */\n function needsHashId(el: Element): boolean {\n // 核心判定:有追踪到的交互事件(click/input/change/focus/blur 等)\n if (hasInteractiveTrackedEvents(el)) return true;\n // 内联事件处理器(onclick/oninput 等)\n for (const attr of Array.from(el.attributes)) {\n if (attr.name.startsWith(\"on\")) return true;\n }\n // 语义交互标签兜底(即使没有事件追踪也应可操作)\n if (INTERACTIVE_TAGS.has(el.tagName)) return true;\n // 交互性 ARIA role 兜底\n const role = el.getAttribute(\"role\");\n if (role && INTERACTIVE_ROLES.has(role)) return true;\n // tabindex → 可聚焦\n if (el.hasAttribute(\"tabindex\")) return true;\n // contenteditable → 可编辑\n if ((el as HTMLElement).isContentEditable && el.getAttribute(\"contenteditable\") !== \"inherit\") return true;\n return false;\n }\n\n /** 判断是否为“选项列表”容器(时间/下拉/listbox 等)。 */\n function isOptionListContainer(el: Element): boolean {\n if (el.getAttribute(\"role\") === \"listbox\") return true;\n const cls = (el.getAttribute(\"class\") || \"\").toLowerCase();\n if (\n cls.includes(\"time-spinner__list\") ||\n cls.includes(\"select-dropdown\") ||\n cls.includes(\"virtual-list\") ||\n cls.includes(\"option\")\n ) {\n return true;\n }\n\n if (el.tagName === \"UL\") {\n const children = Array.from(el.children);\n if (children.length >= 20) {\n const liCount = children.filter(child => child.tagName === \"LI\").length;\n if (liCount / children.length >= 0.8) return true;\n }\n }\n return false;\n }\n\n /** 针对子节点截断计算动态上限。 */\n function resolveChildLimit(el: Element, defaultLimit: number, hashId?: string): number {\n let nextLimit = defaultLimit;\n if (expandOptionLists && isOptionListContainer(el)) {\n nextLimit = Math.max(nextLimit, MAX_EXPANDED_LIST_CHILDREN);\n }\n if (hashId && expandChildrenRefSet.has(hashId)) {\n nextLimit = Math.max(nextLimit, expandedChildrenLimit);\n }\n return nextLimit;\n }\n\n /**\n * 判断元素或其任何后代是否为交互节点(需要 hash ID)。\n * 用于文本聚合判定:子树无交互后代时可安全合并叶文本。\n */\n function hasInteractiveDescendant(el: Element): boolean {\n if (needsHashId(el)) return true;\n for (const child of Array.from(el.children)) {\n if (hasInteractiveDescendant(child)) return true;\n }\n return false;\n }\n\n /**\n * 深度收集元素子树中所有叶子文本节点的内容。\n * 跳过 SKIP_TAGS 和不可见元素,用于透明容器的文本聚合。\n */\n function collectLeafTexts(el: Element, maxLen: number): string[] {\n const texts: string[] = [];\n for (const node of Array.from(el.childNodes)) {\n if (node.nodeType === Node.TEXT_NODE) {\n const t = node.textContent?.trim();\n if (t) texts.push(t.slice(0, maxLen));\n } else if (node.nodeType === Node.ELEMENT_NODE) {\n const child = node as Element;\n if (SKIP_TAGS.has(child.tagName.toUpperCase())) continue;\n try {\n const s = window.getComputedStyle(child);\n if (s.display === \"none\" || s.visibility === \"hidden\") continue;\n } catch { continue; }\n texts.push(...collectLeafTexts(child, maxLen));\n }\n }\n return texts;\n }\n\n function walk(el: Element, depth: number, parentPath: string): string {\n if (emittedNodes >= maxNodes) {\n truncatedByNodeBudget = true;\n return \"\";\n }\n\n if (depth > maxDepth) return \"\";\n if (SKIP_TAGS.has(el.tagName.toUpperCase())) return \"\";\n\n // 跳过标记为 autopilot 内部 UI 的元素(避免 AI 操作自身界面)\n if (el.hasAttribute(\"data-autopilot-ignore\")) return \"\";\n\n // 跳过不可见元素\n const style = window.getComputedStyle(el);\n if (style.display === \"none\" || style.visibility === \"hidden\") return \"\";\n\n // ─── 视口裁剪 ───\n // 检查元素是否在视口内(viewportOnly 关闭时始终通过)\n if (!isInViewport(el, depth)) return \"\";\n\n const indent = \" \".repeat(depth);\n const tag = el.tagName.toLowerCase();\n\n // ─── 角色优先标签 ───\n // 当元素有 INTERACTIVE_ROLES 内的 role 且与 tag 不等价时,\n // 用 role 替代 tag 作为显示标签(如 [combobox] 替代 [input] role=\"combobox\")。\n // 这让 AI 直接从标签判断交互模式,同时省去冗余的 role=\"...\" 属性。\n const rawRole = el.getAttribute(\"role\");\n const useRoleAsTag = !!(rawRole && INTERACTIVE_ROLES.has(rawRole) && rawRole !== tag);\n const displayTag = useRoleAsTag ? rawRole : tag;\n\n // 构建当前元素的内部路径(始终计算,子元素路径依赖它)\n // 注意:路径使用原始 tag 而非 displayTag,保证 hash 计算一致性\n const index = getSiblingIndex(el);\n const currentPath = `${parentPath}/${tag}${index}`;\n // 仅交互节点分配 hash ID 并注册到 RefStore,非交互节点不占 token\n const shouldAssignHash = refStore && needsHashId(el);\n const hashId = shouldAssignHash ? refStore.set(el, currentPath) : undefined;\n\n // 收集有意义的属性(精简版:只保留对 AI 操作有用的信息)\n const attrs: string[] = [];\n\n // 1. id — 最重要的标识信息\n const elId = el.getAttribute(\"id\");\n if (elId) attrs.push(`id=\"${elId}\"`);\n\n // 2. class — 保留第 1 个有语义的类名(不论交互与否,class 对 AI 识别元素语义有价值)\n const className = el.getAttribute(\"class\")?.trim();\n if (className) {\n const cls = className.split(/\\s+/)\n .find(c => c && !c.startsWith(\"data-v-\") && c.length < 25 && !/^[a-z]{1,2}\\d|^_|^css-/.test(c)\n && !(classNameFilterRegexps && classNameFilterRegexps.some(r => r.test(c))));\n if (cls) attrs.push(`class=\"${cls}\"`);\n }\n\n // 3. 交互属性(href, type, placeholder 等)\n for (const attr of INTERACTIVE_ATTRS) {\n // 若 role 已提升为显示标签,跳过 role 属性避免重复输出\n if (attr === \"role\" && useRoleAsTag) continue;\n const val = el.getAttribute(attr);\n if (val) {\n const safeVal = sanitizeSnapshotAttrValue(val);\n if (safeVal) attrs.push(`${attr}=\"${safeVal}\"`);\n }\n }\n\n // 4. 布尔状态属性(disabled, checked 等)\n for (const attr of BOOLEAN_ATTRS) {\n if (el.hasAttribute(attr)) attrs.push(attr);\n }\n\n // 4.1 运行时布尔状态(property 级别),避免仅靠 attribute 导致状态丢失\n if (el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement || el instanceof HTMLSelectElement || el instanceof HTMLButtonElement) {\n if (el.disabled && !attrs.includes(\"disabled\")) attrs.push(\"disabled\");\n }\n if ((el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) && el.readOnly) {\n if (!attrs.includes(\"readonly\")) attrs.push(\"readonly\");\n }\n\n // 5. 事件绑定 — 只标记有 onclick(最重要的交互信号)\n if (el.hasAttribute(\"onclick\")) attrs.push(\"onclick\");\n\n // 5.1 运行时事件绑定(addEventListener 追踪)\n const trackedEvents = getSnapshotListenerEvents(el);\n if (trackedEvents.length > 0) {\n const preview = trackedEvents.slice(0, 6).map(abbrevEvent).join(\",\");\n const suffix = trackedEvents.length > 6 ? \",...\" : \"\";\n attrs.push(`listeners=\"${preview}${suffix}\"`);\n }\n\n // 6. data-* 属性 — 只保留 data-testid(自动化测试定位用)\n const testId = el.getAttribute(\"data-testid\") || el.getAttribute(\"data-test-id\");\n if (testId) {\n const safeTestId = sanitizeSnapshotAttrValue(testId).slice(0, 25);\n if (safeTestId) attrs.push(`data-testid=\"${safeTestId}\"`);\n }\n\n // 7. 对于 input/textarea,补充当前实际 value(截短到 40 字符)\n if ((el instanceof HTMLInputElement || el instanceof HTMLTextAreaElement) && el.value) {\n const currentVal = sanitizeSnapshotAttrValue(el.value).slice(0, 40);\n const attrVal = el.getAttribute(\"value\");\n if (attrVal !== currentVal) {\n attrs.push(`val=\"${currentVal}\"`);\n }\n }\n\n // 7.1 对于 checkbox/radio,补充运行时 checked 状态(property 级别)\n if (el instanceof HTMLInputElement && (el.type === \"checkbox\" || el.type === \"radio\") && el.checked) {\n if (!attrs.includes(\"checked\")) attrs.push(\"checked\");\n }\n\n // 8. 对于 select,补充当前选中 value;对于 option,按运行时 selected 状态输出\n if (el instanceof HTMLSelectElement && el.value) {\n attrs.push(`val=\"${sanitizeSnapshotAttrValue(el.value).slice(0, 40)}\"`);\n }\n if (el instanceof HTMLOptionElement && el.selected) {\n if (!attrs.includes(\"selected\")) attrs.push(\"selected\");\n }\n\n // 获取直接文本(不含子元素文本)\n let directText = \"\";\n for (let i = 0; i < el.childNodes.length; i++) {\n const node = el.childNodes[i];\n if (node.nodeType === Node.TEXT_NODE) {\n const t = node.textContent?.trim();\n if (t) directText += t + \" \";\n }\n }\n directText = directText.trim();\n\n // ─── 智能剪枝(链式坍塌) ───\n // 无意义布局容器不输出自身行,子内容直接提升到当前层级。\n // 若子树无任何交互后代,则合并所有叶文本为一行(文本聚合)。\n if (isEmptyLayoutContainer(el, directText)) {\n const allChildren = Array.from(el.children);\n\n // 文本聚合:子树无交互后代时,合并所有叶子文本为一行\n if (!allChildren.some(c => hasInteractiveDescendant(c))) {\n const texts = collectLeafTexts(el, maxTextLength);\n if (texts.length > 0) {\n emittedNodes++;\n return `${indent}\"${texts.join(\" · \").slice(0, maxTextLength * 3)}\"`;\n }\n return \"\";\n }\n\n // 链式穿透:有交互后代时,子内容直接提升(不输出 collapsed-group)\n const orderedChildren = orderChildrenByPriority(allChildren);\n const childLimit = resolveChildLimit(el, maxChildren, hashId);\n const selectedChildren = orderedChildren.slice(0, childLimit);\n const omittedChildren = orderedChildren.length - selectedChildren.length;\n\n const childBlocks: string[] = [];\n for (let i = 0; i < selectedChildren.length; i++) {\n // 子元素继承当前路径(保证 hash 计算正确),但不增加缩进\n const childResult = walk(selectedChildren[i], depth, currentPath);\n if (childResult) childBlocks.push(childResult);\n }\n\n // 如果子树也全部为空,整个容器就被剪掉\n if (childBlocks.length === 0 && omittedChildren <= 0) {\n return \"\";\n }\n\n let result = childBlocks.join(\"\\n\");\n if (omittedChildren > 0) {\n result += `\\n${indent}... (${omittedChildren} children omitted)`;\n }\n return result;\n }\n\n // 构建当前元素描述:[显示标签] \"文本\" 属性 #hashID(仅交互节点)\n // displayTag 在有交互性 role 时为 role 值,否则为原始 HTML tag\n let line = `${indent}[${displayTag}]`;\n if (directText) line += ` \"${directText.slice(0, maxTextLength)}\"`;\n if (attrs.length) line += ` ${attrs.join(\" \")}`;\n // 仅交互节点输出 hash ID,非交互节点不附加标识(省 token)\n if (hashId) {\n line += ` #${hashId}`;\n }\n\n const lines: string[] = [line];\n emittedNodes++;\n\n // 递归子元素(优先保留可交互元素,再保留普通元素)\n const allChildren = Array.from(el.children);\n const orderedChildren = orderChildrenByPriority(allChildren);\n const childLimit = resolveChildLimit(el, maxChildren, hashId);\n const selectedChildren = orderedChildren.slice(0, childLimit);\n const omittedChildren = orderedChildren.length - selectedChildren.length;\n\n for (let i = 0; i < selectedChildren.length; i++) {\n const childResult = walk(selectedChildren[i], depth + 1, currentPath);\n if (childResult) lines.push(childResult);\n }\n\n if (omittedChildren > 0) {\n lines.push(`${indent} ... (${omittedChildren} children omitted)`);\n }\n\n // 纯文本布局标签简化:无 hashId、无子输出的布局标签只输出文本\n // 例如 [div] \"租户\" → \"租户\",去掉无意义的标签外壳\n if (!hashId && LAYOUT_TAGS.has(el.tagName) && directText && lines.length === 1) {\n return `${indent}\"${directText.slice(0, maxTextLength)}\"`;\n }\n\n return lines.join(\"\\n\");\n }\n\n // 根元素自身的标签作为路径起点,walk 内部不再重复追加\n // 例如 root=body 时,parentPath=\"\",walk 中 currentPath=\"/body\"\n const output = walk(root, 0, \"\") || \"(空页面)\";\n if (!truncatedByNodeBudget) return output;\n return `${output}\\n... (snapshot truncated: maxNodes=${maxNodes})`;\n}\n\n/**\n * 查询所有匹配元素并返回摘要信息(标签、文本、关键属性)。\n */\nfunction queryAllElements(selector: string, limit = 20): string {\n try {\n const elements = document.querySelectorAll(selector);\n if (elements.length === 0) return `未找到匹配 \"${selector}\" 的元素`;\n\n const results: string[] = [`找到 ${elements.length} 个元素:`];\n const count = Math.min(elements.length, limit);\n\n for (let i = 0; i < count; i++) {\n const el = elements[i];\n const tag = el.tagName.toLowerCase();\n const text = el.textContent?.trim().slice(0, 60) ?? \"\";\n const id = el.id ? `#${el.id}` : \"\";\n const cls = el.className && typeof el.className === \"string\"\n ? `.${el.className.split(\" \").filter(Boolean).join(\".\")}`\n : \"\";\n results.push(` ${i + 1}. <${tag}${id}${cls}> \"${text}\"`);\n }\n\n if (elements.length > limit) {\n results.push(` ...还有 ${elements.length - limit} 个元素`);\n }\n\n return results.join(\"\\n\");\n } catch {\n return `选择器语法错误: ${selector}`;\n }\n}\n\n/**\n * 多行文本块缩进(中)/ Indent each line of a multiline block (EN).\n */\nfunction indentMultiline(block: string, indentLevel: number): string {\n const prefix = \" \".repeat(indentLevel);\n return block\n .split(\"\\n\")\n .map(line => `${prefix}${line}`)\n .join(\"\\n\");\n}\n\nexport function createPageInfoTool(): ToolDefinition {\n return {\n name: \"page_info\",\n description: [\n \"Page information tool.\",\n \"Actions: get_url, get_title, get_selection, get_viewport, snapshot, query_all.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"Page info action name\",\n }),\n selector: Type.Optional(\n Type.String({ description: \"CSS selector for query_all\" }),\n ),\n maxDepth: Type.Optional(\n Type.Number({ description: \"Snapshot max depth\" }),\n ),\n viewportOnly: Type.Optional(\n Type.Boolean({ description: \"Snapshot only visible elements\" }),\n ),\n pruneLayout: Type.Optional(\n Type.Boolean({ description: \"Collapse empty layout containers\" }),\n ),\n maxNodes: Type.Optional(\n Type.Number({ description: \"Snapshot max nodes\" }),\n ),\n maxChildren: Type.Optional(\n Type.Number({ description: \"Snapshot max children per node\" }),\n ),\n maxTextLength: Type.Optional(\n Type.Number({ description: \"Snapshot max text length\" }),\n ),\n expandOptionLists: Type.Optional(\n Type.Boolean({ description: \"Expand option/list containers\" }),\n ),\n expandChildrenRefs: Type.Optional(\n Type.Array(Type.String({ description: \"#hashIDs to expand children for\" })),\n ),\n expandedChildrenLimit: Type.Optional(\n Type.Number({ description: \"Expanded child limit\" }),\n ),\n listenerEvents: Type.Optional(\n Type.Array(Type.String({ description: \"Snapshot listener event whitelist\" })),\n ),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n\n try {\n switch (action) {\n case \"get_url\":\n return { content: window.location.href };\n\n case \"get_title\":\n return { content: document.title || \"(无标题)\" };\n\n case \"get_selection\": {\n // 获取用户当前选中的文本\n const selection = window.getSelection();\n const text = selection?.toString().trim() ?? \"\";\n return { content: text || \"(未选中任何文本)\" };\n }\n\n case \"get_viewport\": {\n // 获取视口和滚动信息\n const info = {\n viewportWidth: window.innerWidth,\n viewportHeight: window.innerHeight,\n scrollX: window.scrollX,\n scrollY: window.scrollY,\n pageWidth: document.documentElement.scrollWidth,\n pageHeight: document.documentElement.scrollHeight,\n };\n return { content: JSON.stringify(info, null, 2) };\n }\n\n case \"snapshot\": {\n // 生成 DOM 快照 — AI 理解当前页面结构的主要方式\n const maxDepth = (params.maxDepth as number) ?? 12;\n const viewportOnly = (params.viewportOnly as boolean) ?? true;\n const pruneLayout = (params.pruneLayout as boolean) ?? true;\n const maxNodes = (params.maxNodes as number) ?? 220;\n const maxChildren = (params.maxChildren as number) ?? 25;\n const maxTextLength = (params.maxTextLength as number) ?? 40;\n const expandOptionLists = (params.expandOptionLists as boolean) ?? false;\n const expandChildrenRefs = Array.isArray(params.expandChildrenRefs)\n ? (params.expandChildrenRefs as unknown[]).filter((ref): ref is string => typeof ref === \"string\")\n : undefined;\n const expandedChildrenLimit = typeof params.expandedChildrenLimit === \"number\"\n ? params.expandedChildrenLimit as number\n : undefined;\n const listenerEvents = Array.isArray(params.listenerEvents)\n ? (params.listenerEvents as unknown[]).filter((event): event is string => typeof event === \"string\")\n : undefined;\n const snapshot = generateSnapshot(document.body, {\n maxDepth,\n viewportOnly,\n pruneLayout,\n maxNodes,\n maxChildren,\n maxTextLength,\n expandOptionLists,\n expandChildrenRefs,\n expandedChildrenLimit,\n listenerEvents,\n refStore: getActiveRefStore(),\n });\n return { content: snapshot };\n }\n\n case \"query_all\": {\n // 查询所有匹配元素\n const selector = params.selector as string;\n if (!selector) return { content: \"缺少 selector 参数\" };\n return { content: queryAllElements(selector) };\n }\n\n default:\n return { content: `未知的页面信息动作: ${action}` };\n }\n } catch (err) {\n return {\n content: `页面信息操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, action },\n };\n }\n },\n };\n}\n","/**\n * Navigate Tool — 页面导航工具(增强版)。\n *\n * 支持 5 种动作:\n * goto — 跳转到指定 URL\n * back — 浏览器后退\n * forward — 浏览器前进\n * reload — 刷新当前页面\n * scroll — 滚动页面到指定位置或元素(支持 RefStore hash ID + 多策略对齐)\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport { getActiveRefStore } from \"./dom-tool.js\";\n\n/** 解析 selector(支持 RefStore hash ID 和 CSS 选择器) */\nfunction resolveElement(selector: string): Element | null {\n if (selector.startsWith(\"#\")) {\n const store = getActiveRefStore();\n if (store) {\n const id = selector.slice(1);\n if (store.has(id)) return store.get(id) ?? null;\n }\n }\n try { return document.querySelector(selector); } catch { return null; }\n}\n\nexport function createNavigateTool(): ToolDefinition {\n return {\n name: \"navigate\",\n description: [\n \"Page navigation tool.\",\n \"Actions: goto, back, forward, reload, scroll.\",\n \"scroll supports #hashID from snapshot or CSS selector.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"Navigation action name\",\n }),\n url: Type.Optional(Type.String({ description: \"URL for goto\" })),\n selector: Type.Optional(\n Type.String({ description: \"#hashID or CSS selector for scroll\" }),\n ),\n x: Type.Optional(Type.Number({ description: \"Horizontal scroll position\" })),\n y: Type.Optional(Type.Number({ description: \"Vertical scroll position\" })),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n\n try {\n switch (action) {\n case \"goto\": {\n const url = params.url as string;\n if (!url) return { content: \"缺少 url 参数\" };\n window.location.href = url;\n return { content: `正在导航到 ${url}` };\n }\n\n case \"back\": {\n window.history.back();\n return { content: \"已后退\" };\n }\n\n case \"forward\": {\n window.history.forward();\n return { content: \"已前进\" };\n }\n\n case \"reload\": {\n window.location.reload();\n return { content: \"正在刷新页面\" };\n }\n\n case \"scroll\": {\n const selector = params.selector as string | undefined;\n\n if (selector) {\n const el = resolveElement(selector);\n if (!el) return { content: `未找到元素 \"${selector}\"` };\n // 尝试 scrollIntoViewIfNeeded(Chrome),回退 scrollIntoView center\n if (\"scrollIntoViewIfNeeded\" in el) {\n (el as HTMLElement & { scrollIntoViewIfNeeded: (c?: boolean) => void }).scrollIntoViewIfNeeded(true);\n } else {\n el.scrollIntoView({ behavior: \"smooth\", block: \"center\" });\n }\n return { content: `已滚动到元素 \"${selector}\"` };\n }\n\n const x = (params.x as number) ?? 0;\n const y = (params.y as number) ?? 0;\n window.scrollTo({ left: x, top: y, behavior: \"smooth\" });\n return { content: `已滚动到 (${x}, ${y})` };\n }\n\n default:\n return { content: `未知的导航动作: ${action}` };\n }\n } catch (err) {\n return {\n content: `导航操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, action },\n };\n }\n },\n };\n}\n","/**\n * Wait Tool 等待工具 / Wait utility for DOM conditions.\n *\n * 支持动作 / Supported actions:\n * - wait_for_selector: 等待选择器达到状态 / wait selector state\n * - wait_for_hidden: 等待元素隐藏或移除 / wait element hidden or detached\n * - wait_for_text: 等待页面出现文本 / wait text appears in page\n * - wait_for_stable: 等待 DOM 进入静默窗口 / wait DOM quiet window\n *\n * 说明 / Notes:\n * - hash selector(如 #abc123)优先通过 RefStore 解析。\n * - 可见性语义与 dom-tool 保持一致(参考 Playwright 风格)。\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\nimport { getActiveRefStore } from \"./dom-tool.js\";\n\nconst DEFAULT_TIMEOUT = 6_000;\nconst POLL_INTERVAL_MS = 80;\nconst STABLE_TICK_MS = 50;\nconst OBSERVER_OPTIONS: MutationObserverInit = {\n childList: true,\n subtree: true,\n attributes: true,\n characterData: true,\n};\nconst TEXT_OBSERVER_OPTIONS: MutationObserverInit = {\n childList: true,\n subtree: true,\n characterData: true,\n};\n\ntype SelectorState = \"attached\" | \"visible\" | \"hidden\" | \"detached\";\n\n/**\n * 可见性判定 / Visibility check.\n *\n * 与 dom-tool 保持一致,处理 display:contents、visibility、opacity、零尺寸等场景。\n */\nfunction isVisible(el: Element): boolean {\n if (!(el instanceof HTMLElement || el instanceof SVGElement)) return false;\n if (!el.isConnected) return false;\n const style = window.getComputedStyle(el);\n\n if (style.display === \"contents\") {\n for (let child = el.firstChild; child; child = child.nextSibling) {\n if (child.nodeType === Node.ELEMENT_NODE && isVisible(child as Element)) return true;\n if (child.nodeType === Node.TEXT_NODE) {\n const range = document.createRange();\n range.selectNodeContents(child);\n const rects = range.getClientRects();\n for (let i = 0; i < rects.length; i++) {\n if (rects[i].width > 0 && rects[i].height > 0) return true;\n }\n }\n }\n return false;\n }\n if (style.display === \"none\") return false;\n if (typeof el.checkVisibility === \"function\") {\n if (!el.checkVisibility()) return false;\n }\n if (style.visibility !== \"visible\") return false;\n if (style.opacity === \"0\") return false;\n const rect = el.getBoundingClientRect();\n return rect.width > 0 && rect.height > 0;\n}\n\n/**\n * 解析选择器 / Resolve selector.\n *\n * 先尝试 RefStore hash,再回退到 document.querySelector。\n */\nfunction resolveSelector(selector: string): Element | null {\n if (selector.startsWith(\"#\")) {\n const store = getActiveRefStore();\n if (store) {\n const id = selector.slice(1);\n if (store.has(id)) return store.get(id) ?? null;\n }\n }\n try { return document.querySelector(selector); } catch { return null; }\n}\n\n/**\n * 计算选择器状态 / Evaluate selector state.\n *\n * @returns matched 表示是否达到目标状态;element 为当前命中的元素(如果存在)。\n */\nfunction evaluateSelectorState(selector: string, state: SelectorState): { matched: boolean; element?: Element } {\n const el = resolveSelector(selector) ?? undefined;\n switch (state) {\n case \"attached\":\n return { matched: Boolean(el), element: el };\n case \"visible\":\n return { matched: Boolean(el && isVisible(el)), element: el };\n case \"hidden\":\n return { matched: !el || !isVisible(el), element: el };\n case \"detached\":\n return { matched: !el, element: el };\n default:\n return { matched: false };\n }\n}\n\n/**\n * 等待选择器达到指定状态 / Wait selector reaches state.\n *\n * 策略:轮询 + MutationObserver 双通道,既保证及时性也降低漏检概率。\n */\nfunction waitForSelectorState(\n selector: string,\n state: SelectorState,\n timeoutMs: number,\n): Promise<{ element?: Element }> {\n return new Promise((resolve, reject) => {\n let finished = false;\n\n const finish = (handler: () => void): void => {\n if (finished) return;\n finished = true;\n clearTimeout(timer);\n clearInterval(interval);\n observer.disconnect();\n handler();\n };\n\n const check = (): void => {\n let result: { matched: boolean; element?: Element };\n try {\n result = evaluateSelectorState(selector, state);\n } catch {\n finish(() => reject(new Error(`选择器语法错误: ${selector}`)));\n return;\n }\n if (result.matched) {\n finish(() => resolve({ element: result.element }));\n }\n };\n\n const timer = setTimeout(() => {\n finish(() => reject(new Error(`等待 \"${selector}\" 达到状态 \"${state}\" 超时 (${timeoutMs}ms)`)));\n }, timeoutMs);\n\n const interval = setInterval(check, POLL_INTERVAL_MS);\n const observer = new MutationObserver(check);\n observer.observe(document.body, OBSERVER_OPTIONS);\n\n check();\n });\n}\n\n/**\n * 等待文本出现 / Wait text appears.\n *\n * 先做一次即时检查,再监听 DOM 变化。\n */\nfunction waitForText(text: string, timeoutMs: number): Promise<void> {\n return new Promise((resolve, reject) => {\n // 先检查是否已包含\n if (document.body.textContent?.includes(text)) {\n resolve();\n return;\n }\n\n const timer = setTimeout(() => {\n observer.disconnect();\n reject(new Error(`等待文本 \"${text}\" 出现超时 (${timeoutMs}ms)`));\n }, timeoutMs);\n\n const observer = new MutationObserver(() => {\n if (document.body.textContent?.includes(text)) {\n clearTimeout(timer);\n observer.disconnect();\n resolve();\n }\n });\n\n observer.observe(document.body, TEXT_OBSERVER_OPTIONS);\n });\n}\n\n/**\n * 等待 DOM 稳定 / Wait DOM stable.\n *\n * 定义:quietMs 窗口内没有任何 MutationObserver 事件。\n */\nfunction waitForDomStable(timeoutMs: number, quietMs: number): Promise<void> {\n return new Promise((resolve, reject) => {\n const startedAt = Date.now();\n let lastMutationAt = Date.now();\n\n const finish = (ok: boolean, err?: Error): void => {\n clearInterval(tick);\n observer.disconnect();\n if (ok) resolve();\n else reject(err ?? new Error(\"等待页面稳定失败\"));\n };\n\n const observer = new MutationObserver(() => {\n lastMutationAt = Date.now();\n });\n\n observer.observe(document.body, OBSERVER_OPTIONS);\n\n const tick = setInterval(() => {\n const now = Date.now();\n if (now - startedAt > timeoutMs) {\n finish(false, new Error(`等待页面稳定超时 (${timeoutMs}ms)`));\n return;\n }\n if (now - lastMutationAt >= quietMs) {\n finish(true);\n }\n }, STABLE_TICK_MS);\n });\n}\n\nexport function createWaitTool(): ToolDefinition {\n return {\n name: \"wait\",\n description: [\n \"Wait for page conditions.\",\n \"Actions: wait_for_selector, wait_for_hidden, wait_for_text, wait_for_stable.\",\n \"wait_for_selector supports attached, visible, hidden, detached.\",\n ].join(\" \"),\n\n schema: Type.Object({\n action: Type.String({\n description: \"Wait action name\",\n }),\n selector: Type.Optional(\n Type.String({ description: \"Selector for wait_for_selector/wait_for_hidden\" }),\n ),\n state: Type.Optional(\n Type.String({ description: \"Selector state: attached | visible | hidden | detached\" }),\n ),\n text: Type.Optional(\n Type.String({ description: \"Text to wait for\" }),\n ),\n timeout: Type.Optional(\n Type.Number({ description: \"Timeout in ms\" }),\n ),\n quietMs: Type.Optional(\n Type.Number({ description: \"Quiet window in ms\" }),\n ),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const action = params.action as string;\n const timeoutMs = (params.timeout as number) ?? DEFAULT_TIMEOUT;\n\n try {\n switch (action) {\n case \"wait_for_selector\": {\n const selector = params.selector as string;\n if (!selector) return { content: \"缺少 selector 参数\" };\n const state = (params.state as SelectorState | undefined) ?? \"attached\";\n if (![\"attached\", \"visible\", \"hidden\", \"detached\"].includes(state)) {\n return { content: `无效 state: ${state}` };\n }\n const result = await waitForSelectorState(selector, state, timeoutMs);\n if (state === \"attached\" || state === \"visible\") {\n const tag = result.element?.tagName?.toLowerCase();\n return { content: `元素 \"${selector}\" 已达到状态 \"${state}\"${tag ? ` (${tag})` : \"\"}` };\n }\n return { content: `元素 \"${selector}\" 已达到状态 \"${state}\"` };\n }\n\n case \"wait_for_hidden\": {\n const selector = params.selector as string;\n if (!selector) return { content: \"缺少 selector 参数\" };\n await waitForSelectorState(selector, \"hidden\", timeoutMs);\n return { content: `元素 \"${selector}\" 已隐藏或消失` };\n }\n\n case \"wait_for_text\": {\n const text = params.text as string;\n if (!text) return { content: \"缺少 text 参数\" };\n await waitForText(text, timeoutMs);\n return { content: `文本 \"${text}\" 已出现` };\n }\n\n case \"wait_for_stable\": {\n const quietMs = Math.max(50, Math.floor((params.quietMs as number) ?? 300));\n await waitForDomStable(timeoutMs, quietMs);\n return { content: `页面已稳定(静默窗口 ${quietMs}ms)` };\n }\n\n default:\n return { content: `未知的等待动作: ${action}` };\n }\n } catch (err) {\n return {\n content: `等待操作 \"${action}\" 失败: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, action },\n };\n }\n },\n };\n}\n","/**\n * Evaluate Tool — 在页面上下文中执行任意 JavaScript 表达式。\n *\n * 替代 Playwright 的 page.evaluate()。\n * 运行环境:浏览器 Content Script。\n *\n * 这是最灵活的工具 — 当其他 tools 无法满足需求时,\n * AI 可以直接编写 JS 代码来操作页面。\n *\n * 支持 2 种动作:\n * evaluate — 执行 JS 表达式并返回结果\n * evaluate_handle — 执行 JS 并返回序列化的 DOM 信息\n */\nimport { Type } from \"@sinclair/typebox\";\nimport type { ToolDefinition, ToolCallResult } from \"../../core/tool-registry.js\";\n\n/**\n * 安全执行 JS 表达式,捕获错误并序列化结果。\n */\nfunction safeEvaluate(expression: string): { result?: unknown; error?: string } {\n try {\n // 使用 Function 构造器代替 eval,避免污染当前作用域\n const fn = new Function(`\"use strict\"; return (${expression});`);\n const result = fn();\n return { result };\n } catch {\n // 如果作为表达式失败,尝试作为语句块执行\n try {\n const fn = new Function(`\"use strict\"; ${expression}`);\n const result = fn();\n return { result };\n } catch (err2) {\n return { error: err2 instanceof Error ? err2.message : String(err2) };\n }\n }\n}\n\n/**\n * 将执行结果序列化为字符串(处理 DOM 元素、循环引用等)。\n */\nfunction serializeResult(value: unknown): string {\n if (value === undefined) return \"undefined\";\n if (value === null) return \"null\";\n\n // DOM 元素 → 返回 outerHTML 片段\n if (value instanceof Element) {\n const tag = value.tagName.toLowerCase();\n const id = value.id ? `#${value.id}` : \"\";\n const text = value.textContent?.trim().slice(0, 100) ?? \"\";\n return `<${tag}${id}> \"${text}\"`;\n }\n\n // NodeList / HTMLCollection → 逐个序列化\n if (value instanceof NodeList || value instanceof HTMLCollection) {\n const items = Array.from(value).map((el, i) => ` ${i}: ${serializeResult(el)}`);\n return `[${value.length} elements]\\n${items.join(\"\\n\")}`;\n }\n\n // 普通值 → JSON 序列化\n try {\n return JSON.stringify(value, null, 2);\n } catch {\n return String(value);\n }\n}\n\nexport function createEvaluateTool(): ToolDefinition {\n return {\n name: \"evaluate\",\n description: [\n \"Execute JavaScript in page context.\",\n \"Use when other tools are insufficient; can access document and window.\",\n ].join(\" \"),\n\n schema: Type.Object({\n expression: Type.String({\n description: \"JavaScript expression or code block to execute.\",\n }),\n }),\n\n execute: async (params): Promise<ToolCallResult> => {\n const expression = params.expression as string;\n if (!expression) return { content: \"缺少 expression 参数\" };\n\n const { result, error } = safeEvaluate(expression);\n\n if (error) {\n return {\n content: `JS 执行错误: ${error}`,\n details: { error: true, expression },\n };\n }\n\n return { content: serializeResult(result) };\n },\n };\n}\n","/**\n * RefStore — 快照 hash ID 与 DOM 元素的映射表。\n *\n * 快照生成时,根据元素的 DOM 路径 + 页面 URL 生成确定性 hash ID,\n * 同时保存 ID → Element 的映射。AI 使用 hash ID 作为 selector 定位元素,\n * 免去超长 XPath 路径,大幅减少 token 消耗。\n *\n * 优势:\n * - **确定性**:同一元素无论快照顺序,始终得到相同 ID\n * - **并发安全**:多次快照不会产生 ID 冲突\n * - **跨页面隔离**:URL hash 作为命名空间,不同页面元素 ID 互不碰撞\n *\n * 生命周期:每次 WebAgent.chat() 调用时创建,对话结束后清空。\n *\n * 使用方:\n * page-info-tool.ts — generateSnapshot() 写入映射\n * dom-tool.ts — queryElement() 读取映射\n * index.ts — WebAgent 持有实例,管理生命周期\n */\n\n/**\n * FNV-1a 32-bit hash — 简单高效的字符串散列。\n * 分布均匀,碰撞率低,适合生成短 ID。\n */\nfunction fnv1a(str: string): number {\n let h = 0x811c9dc5; // FNV offset basis\n for (let i = 0; i < str.length; i++) {\n h ^= str.charCodeAt(i);\n h = Math.imul(h, 0x01000193); // FNV prime\n }\n return h >>> 0; // 转为无符号 32-bit\n}\n\n/**\n * hash ID → DOM 元素的映射存储。\n *\n * - `set(el, path)` 由快照生成时调用,返回确定性 hash ID\n * - `get(id)` 由 dom-tool 查询时调用,根据 hash ID 取回元素\n * - `has(id)` 检查 ID 是否存在(用于 selector 类型判断)\n * - `clear()` 每次对话结束后清空\n */\nexport class RefStore {\n private map = new Map<string, Element>();\n /** 页面 URL 的 hash 前缀,用于跨页面命名空间隔离 */\n private urlKey: string;\n\n /**\n * @param url 当前页面 URL(可选)。传入后作为 hash 命名空间,\n * 使不同页面的相同 DOM 路径产生不同 ID。\n */\n constructor(url?: string) {\n this.urlKey = url ?? \"\";\n }\n\n /**\n * 注册一个元素,返回确定性 hash ID。\n * 相同 URL + path 始终产生相同 ID(并发安全)。\n *\n * @param el DOM 元素引用\n * @param path 元素的 XPath-like 路径(如 \"/body/div[1]/main/button\")\n */\n set(el: Element, path: string): string {\n const baseId = fnv1a(this.urlKey + path).toString(36);\n let id = baseId;\n // 极小概率碰撞处理:不同 path 映射到相同 hash 时追加后缀\n let suffix = 2;\n while (this.map.has(id) && this.map.get(id) !== el) {\n id = baseId + suffix++;\n }\n this.map.set(id, el);\n return id;\n }\n\n /**\n * 根据 hash ID 获取 DOM 元素。\n * 返回 Element 或 undefined(ID 不存在或元素已被移除)。\n */\n get(id: string): Element | undefined {\n return this.map.get(id);\n }\n\n /** 检查 hash ID 是否存在 */\n has(id: string): boolean {\n return this.map.has(id);\n }\n\n /** 清空所有映射 */\n clear(): void {\n this.map.clear();\n }\n\n /**\n * 重置映射表:清空所有映射,并可选更新 URL 命名空间。\n *\n * 用于页面导航后刷新 RefStore:旧的 hash ID → Element 映射已失效,\n * 需要用新 URL 重新生成确定性 hash。\n *\n * @param url 新的页面 URL(不传则保持原 URL 命名空间)\n */\n reset(url?: string): void {\n this.map.clear();\n if (url !== undefined) {\n this.urlKey = url;\n }\n }\n\n /** 当前映射数量 */\n get size(): number {\n return this.map.size;\n }\n}\n","/**\n * AutoPilot UI 面板样式。\n *\n * 全部使用 CSS-in-JS(字符串注入),零外部依赖。\n * 所有选择器在 #autopilot-panel 作用域下,避免污染宿主样式。\n *\n * 风格:白色基调 — 轻量现代风,微妙阴影与品牌色点缀。\n */\n\nexport const PANEL_STYLES = /* css */ `\n/* ─── CSS Variables ─── */\n#autopilot-panel {\n --ap-bg: #ffffff;\n --ap-bg-secondary: #f8f9fb;\n --ap-bg-tertiary: #f0f2f5;\n --ap-border: #e8eaed;\n --ap-border-hover: #d0d3d9;\n --ap-text: #1a1a2e;\n --ap-text-secondary: #6b7280;\n --ap-text-tertiary: #b0b7c3;\n --ap-primary: #6366f1;\n --ap-primary-hover: #4f46e5;\n --ap-primary-light: rgba(99, 102, 241, 0.08);\n --ap-primary-glow: rgba(99, 102, 241, 0.18);\n --ap-success: #22c55e;\n --ap-error: #ef4444;\n --ap-warning: #f59e0b;\n --ap-shadow: 0 0 12px rgba(0, 0, 0, 0.06);\n --ap-shadow-lg: 0 0 16px rgba(0, 0, 0, 0.08);\n --ap-radius: 16px;\n --ap-radius-sm: 10px;\n --ap-font: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, 'Helvetica Neue', Arial, sans-serif;\n --ap-transition: 0.25s cubic-bezier(0.4, 0, 0.2, 1);\n}\n\n/* ─── 操作遮罩 ─── */\n#autopilot-mask {\n --ap-mask-opacity: 0.15;\n position: fixed;\n inset: 0;\n z-index: 99998;\n background: rgba(255, 255, 255, var(--ap-mask-opacity));\n backdrop-filter: blur(1px);\n opacity: 0;\n pointer-events: none;\n transition: opacity var(--ap-transition);\n}\n#autopilot-mask.active {\n opacity: 1;\n pointer-events: auto;\n cursor: not-allowed;\n}\n#autopilot-mask .ap-mask-label {\n position: absolute;\n top: 20px;\n left: 50%;\n transform: translateX(-50%);\n background: #ffffff;\n border: 1px solid var(--ap-border);\n color: var(--ap-primary);\n font-family: var(--ap-font);\n font-size: 13px;\n font-weight: 500;\n padding: 10px 24px;\n border-radius: 24px;\n letter-spacing: 0.2px;\n display: flex;\n align-items: center;\n gap: 10px;\n user-select: none;\n box-shadow: 0 4px 16px rgba(0, 0, 0, 0.08);\n}\n#autopilot-mask .ap-mask-spinner {\n width: 14px;\n height: 14px;\n border: 2px solid rgba(99, 102, 241, 0.2);\n border-top-color: var(--ap-primary);\n border-radius: 50%;\n animation: ap-spin 0.8s linear infinite;\n}\n@keyframes ap-spin {\n to { transform: rotate(360deg); }\n}\n\n/* ─── 面板容器 ─── */\n#autopilot-panel {\n position: fixed;\n z-index: 99999;\n width: 520px;\n height: min(75vh, 820px);\n max-height: min(75vh, 820px);\n display: flex;\n flex-direction: column;\n background: var(--ap-bg);\n border-radius: var(--ap-radius);\n box-shadow: var(--ap-shadow);\n border: 1px solid var(--ap-border);\n font-family: var(--ap-font);\n font-size: 14px;\n color: var(--ap-text);\n overflow: hidden;\n opacity: 1;\n transition: opacity var(--ap-transition), transform var(--ap-transition);\n user-select: none;\n}\n#autopilot-panel.collapsed {\n opacity: 0;\n pointer-events: none;\n transform: scale(0.92);\n}\n\n/* ─── 触发按钮 (FAB) ─── */\n#autopilot-fab {\n position: fixed;\n bottom: 20px;\n right: 20px;\n z-index: 99998;\n width: 40px;\n height: 40px;\n border-radius: 12px;\n background: #ffffff;\n color: var(--ap-primary);\n border: 1px solid var(--ap-border);\n cursor: pointer;\n box-shadow: 0 0 8px rgba(0, 0, 0, 0.06);\n display: flex;\n align-items: center;\n justify-content: center;\n transition: transform 0.2s, box-shadow 0.2s, opacity var(--ap-transition);\n font-family: var(--ap-font);\n padding: 6px;\n overflow: hidden;\n touch-action: none;\n}\n#autopilot-fab:active {\n cursor: pointer;\n}\n/* FAB 拖拽态:长按激活拖拽时切换为 grabbing 光标 */\n#autopilot-fab.dragging {\n cursor: grabbing;\n}\n/* FAB 激活态:面板展开时 FAB 显示品牌色边框 */\n#autopilot-fab.active {\n border-color: var(--ap-primary);\n box-shadow: 0 0 0 3px var(--ap-primary-light), 0 0 8px rgba(0, 0, 0, 0.06);\n}\n#autopilot-fab img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n pointer-events: none;\n}\n\n/* ─── 头部 ─── */\n.ap-header {\n display: flex;\n align-items: center;\n justify-content: space-between;\n padding: 12px 16px;\n border-bottom: 1px solid var(--ap-border);\n background: var(--ap-bg);\n flex-shrink: 0;\n}\n.ap-header-left {\n display: flex;\n align-items: center;\n gap: 10px;\n}\n.ap-header-logo {\n width: 30px;\n height: 30px;\n border-radius: 8px;\n background: var(--ap-bg-secondary);\n display: flex;\n align-items: center;\n justify-content: center;\n flex-shrink: 0;\n overflow: hidden;\n padding: 3px;\n}\n.ap-header-logo img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.ap-header-title {\n font-weight: 600;\n font-size: 15px;\n color: var(--ap-text);\n letter-spacing: -0.01em;\n}\n.ap-header-actions {\n display: flex;\n align-items: center;\n gap: 2px;\n}\n.ap-header-btn {\n width: 32px;\n height: 32px;\n border-radius: 8px;\n border: none;\n background: transparent;\n color: var(--ap-text-tertiary);\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, color 0.15s;\n font-family: var(--ap-font);\n}\n.ap-header-btn:hover {\n background: var(--ap-bg-tertiary);\n color: var(--ap-text-secondary);\n}\n.ap-header-btn svg {\n width: 16px;\n height: 16px;\n}\n\n/* ─── 状态条 ─── */\n.ap-status {\n display: flex;\n align-items: center;\n gap: 8px;\n padding: 8px 16px;\n font-size: 12px;\n color: var(--ap-text-secondary);\n background: var(--ap-bg-secondary);\n border-bottom: 1px solid var(--ap-border);\n flex-shrink: 0;\n}\n.ap-status-dot {\n width: 7px;\n height: 7px;\n border-radius: 50%;\n background: var(--ap-text-tertiary);\n flex-shrink: 0;\n transition: background 0.2s;\n}\n.ap-status-dot.idle {\n background: var(--ap-success);\n box-shadow: 0 0 6px rgba(34, 197, 94, 0.4);\n}\n.ap-status-dot.running {\n background: var(--ap-primary);\n box-shadow: 0 0 8px var(--ap-primary-glow);\n animation: ap-pulse 1.5s ease-in-out infinite;\n}\n.ap-status-dot.error {\n background: var(--ap-error);\n box-shadow: 0 0 6px rgba(239, 68, 68, 0.4);\n}\n@keyframes ap-pulse {\n 0%, 100% { opacity: 1; }\n 50% { opacity: 0.4; }\n}\n\n/* ─── 消息区 ─── */\n.ap-messages {\n flex: 1 1 0;\n overflow-y: auto;\n padding: 16px;\n display: flex;\n flex-direction: column;\n gap: 12px;\n min-height: 0;\n scroll-behavior: smooth;\n}\n.ap-messages::-webkit-scrollbar { width: 4px; }\n.ap-messages::-webkit-scrollbar-track { background: transparent; }\n.ap-messages::-webkit-scrollbar-thumb {\n background: var(--ap-text-tertiary);\n border-radius: 4px;\n}\n\n/* 消息气泡 */\n.ap-msg {\n max-width: 88%;\n padding: 10px 14px;\n border-radius: var(--ap-radius-sm);\n line-height: 1.6;\n font-size: 13.5px;\n word-break: break-word;\n animation: ap-msg-in 0.25s ease-out;\n}\n@keyframes ap-msg-in {\n from { opacity: 0; transform: translateY(6px); }\n to { opacity: 1; transform: translateY(0); }\n}\n.ap-msg.user {\n align-self: flex-end;\n background: var(--ap-primary);\n color: #fff;\n border-bottom-right-radius: 4px;\n box-shadow: 0 2px 8px rgba(99, 102, 241, 0.2);\n}\n.ap-msg.assistant {\n align-self: flex-start;\n background: var(--ap-bg-tertiary);\n color: var(--ap-text);\n border: 1px solid var(--ap-border);\n border-bottom-left-radius: 4px;\n}\n.ap-msg.tool {\n align-self: flex-start;\n background: var(--ap-bg-secondary);\n color: var(--ap-text-secondary);\n font-size: 12px;\n font-family: 'SF Mono', 'Fira Code', 'Consolas', monospace;\n padding: 8px 12px;\n border-left: 3px solid var(--ap-primary);\n border-radius: 0 var(--ap-radius-sm) var(--ap-radius-sm) 0;\n}\n.ap-msg.error {\n align-self: flex-start;\n background: rgba(239, 68, 68, 0.05);\n color: var(--ap-error);\n border-left: 3px solid var(--ap-error);\n font-size: 12.5px;\n border-radius: 0 var(--ap-radius-sm) var(--ap-radius-sm) 0;\n}\n\n/* ─── 空状态 ─── */\n.ap-empty {\n flex: 1;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n gap: 10px;\n color: var(--ap-text-tertiary);\n padding: 40px 20px;\n text-align: center;\n}\n.ap-empty-icon {\n width: 48px;\n height: 48px;\n opacity: 0.5;\n}\n.ap-empty-icon img {\n width: 100%;\n height: 100%;\n object-fit: contain;\n}\n.ap-empty-text {\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* ─── 停止按钮 ─── */\n.ap-stop-container {\n flex-shrink: 0;\n padding: 0 16px 8px;\n}\n.ap-stop-btn {\n width: 100%;\n height: 36px;\n border: 1px solid rgba(239, 68, 68, 0.2);\n border-radius: var(--ap-radius-sm);\n background: rgba(239, 68, 68, 0.04);\n color: var(--ap-error);\n cursor: pointer;\n font-family: var(--ap-font);\n font-size: 12.5px;\n display: flex;\n align-items: center;\n justify-content: center;\n gap: 6px;\n transition: background 0.15s, border-color 0.15s;\n}\n.ap-stop-btn:hover {\n background: rgba(239, 68, 68, 0.08);\n border-color: rgba(239, 68, 68, 0.35);\n}\n.ap-stop-btn svg {\n width: 13px;\n height: 13px;\n}\n\n/* ─── 输入区 ─── */\n.ap-input-area {\n display: flex;\n align-items: flex-end;\n gap: 8px;\n padding: 12px 16px;\n border-top: 1px solid var(--ap-border);\n background: var(--ap-bg);\n flex-shrink: 0;\n}\n.ap-input-wrapper {\n flex: 1;\n position: relative;\n}\n.ap-input {\n width: 100%;\n min-height: 40px;\n max-height: 120px;\n padding: 10px 14px;\n border: 1px solid var(--ap-border);\n border-radius: var(--ap-radius-sm);\n background: var(--ap-bg);\n color: var(--ap-text);\n font-family: var(--ap-font);\n font-size: 13.5px;\n line-height: 1.5;\n resize: none;\n outline: none;\n transition: border-color 0.15s, box-shadow 0.15s;\n box-sizing: border-box;\n}\n.ap-input:focus {\n border-color: var(--ap-primary);\n box-shadow: 0 0 0 3px var(--ap-primary-light);\n}\n.ap-input::placeholder {\n color: var(--ap-text-tertiary);\n}\n.ap-input:disabled {\n opacity: 0.5;\n cursor: not-allowed;\n}\n.ap-send-btn {\n width: 40px;\n height: 40px;\n border-radius: var(--ap-radius-sm);\n border: none;\n background: var(--ap-primary);\n color: #fff;\n cursor: pointer;\n display: flex;\n align-items: center;\n justify-content: center;\n transition: background 0.15s, transform 0.1s, box-shadow 0.15s;\n flex-shrink: 0;\n font-family: var(--ap-font);\n}\n.ap-send-btn:hover {\n background: var(--ap-primary-hover);\n box-shadow: 0 2px 10px rgba(99, 102, 241, 0.25);\n}\n.ap-send-btn:active {\n transform: scale(0.95);\n}\n.ap-send-btn:disabled {\n background: var(--ap-text-tertiary);\n cursor: not-allowed;\n box-shadow: none;\n}\n.ap-send-btn svg {\n width: 18px;\n height: 18px;\n}\n\n/* ─── 进度指示器 ─── */\n.ap-typing {\n display: flex;\n align-items: center;\n gap: 4px;\n padding: 10px 14px;\n align-self: flex-start;\n}\n.ap-typing-dot {\n width: 6px;\n height: 6px;\n border-radius: 50%;\n background: var(--ap-primary);\n animation: ap-typing 1.4s ease-in-out infinite;\n}\n.ap-typing-dot:nth-child(2) { animation-delay: 0.2s; }\n.ap-typing-dot:nth-child(3) { animation-delay: 0.4s; }\n@keyframes ap-typing {\n 0%, 60%, 100% { transform: translateY(0); opacity: 0.4; }\n 30% { transform: translateY(-4px); opacity: 1; }\n}\n`;\n","/**\n * AutoPilot Logo — 螃蟹图标的 PNG data URI。\n * 从 assets/logo/contours (2).svg 中提取的嵌入式 PNG。\n */\nexport const LOGO_DATA_URL = \"data:image/png;base64,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\";\n","/**\n * AutoPilot SVG 图标集合(内联 SVG 字符串)。\n * 使用微型图标风格,线宽一致,视觉协调。\n */\nimport { LOGO_DATA_URL } from \"./logo-data.js\";\n\nexport const ICONS = {\n /** AutoPilot logo — 螃蟹图标(PNG data URI,用 <img> 渲染) */\n logo: `<img src=\"${LOGO_DATA_URL}\" alt=\"AutoPilot\" style=\"width:100%;height:100%;object-fit:contain;\" />`,\n\n /** 发送 */\n send: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"22\" y1=\"2\" x2=\"11\" y2=\"13\"/><polygon points=\"22 2 15 22 11 13 2 9 22 2\"/></svg>`,\n\n /** 最小化 */\n minimize: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"5\" y1=\"12\" x2=\"19\" y2=\"12\"/></svg>`,\n\n /** 清空 */\n trash: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><polyline points=\"3 6 5 6 21 6\"/><path d=\"M19 6v14a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2V6m3 0V4a2 2 0 0 1 2-2h4a2 2 0 0 1 2 2v2\"/></svg>`,\n\n /** 关闭 */\n close: `<svg viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"><line x1=\"18\" y1=\"6\" x2=\"6\" y2=\"18\"/><line x1=\"6\" y1=\"6\" x2=\"18\" y2=\"18\"/></svg>`,\n\n /** 停止(方块) */\n stop: `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><rect x=\"6\" y=\"6\" width=\"12\" height=\"12\" rx=\"2\"/></svg>`,\n};\n","/**\n * AutoPilot UI Panel — 开箱即用的聊天面板 + 操作遮罩。\n *\n * 纯 DOM 实现,零框架依赖。通过 `agent.panel.show()` 一行代码启用。\n *\n * 功能:\n * - 浮动聊天面板(FAB 按钮展开/收起)\n * - 操作遮罩(自动化执行期间阻止用户操作页面)\n * - 实时消息流(用户消息、AI 回复、工具调用、错误)\n * - 输入框 + 发送/停止控制\n *\n * 架构位置:web/ui/ 层,仅依赖 DOM API,不依赖 core。\n * 通过 WebAgent 的 callbacks 接口接收 Agent 事件。\n */\nimport { PANEL_STYLES } from \"./styles.js\";\nimport { ICONS } from \"./icons.js\";\nimport { computePosition, flip, shift, offset } from \"@floating-ui/dom\";\n\n/** 面板配置选项 */\nexport type PanelOptions = {\n /** 面板容器挂载点(默认 document.body) */\n container?: HTMLElement;\n /** 构造时是否自动挂载到 DOM(默认 true)。设为 false 时需手动调用 mount() */\n mount?: boolean;\n /** 是否在 Agent 运行时自动显示操作遮罩(默认 true) */\n enableMask?: boolean;\n /** 遮罩背景透明度(0–1,默认 0.15)。0 = 全透明,1 = 纯白不透明 */\n maskOpacity?: number;\n /** 面板默认展开状态(默认 false,即收起状态,只显示 FAB) */\n expanded?: boolean;\n /** 面板标题(默认 \"AutoPilot\") */\n title?: string;\n /** 输入框占位文本 */\n placeholder?: string;\n /** 遮罩提示文本 */\n maskText?: string;\n /** 空状态提示文本 */\n emptyText?: string;\n};\n\n/** 消息类型 */\ntype MessageType = \"user\" | \"assistant\" | \"tool\" | \"error\";\n\n/** 面板状态 */\ntype PanelStatus = \"idle\" | \"running\" | \"error\";\n\n/**\n * AutoPilot UI 面板。\n *\n * 使用方式:\n * ```ts\n * // 默认自动挂载\n * const panel = new Panel({ enableMask: true });\n * panel.onSend = async (text) => { await agent.chat(text); };\n *\n * // 延迟挂载\n * const panel = new Panel({ mount: false });\n * panel.mount(); // 手动挂载\n * ```\n */\nexport default class Panel {\n private container: HTMLElement;\n private enableMask: boolean;\n private maskOpacity: number;\n private title: string;\n private placeholder: string;\n private maskText: string;\n private emptyText: string;\n\n // ─── DOM 引用 ───\n private root: HTMLDivElement | null = null;\n private fab: HTMLButtonElement | null = null;\n private mask: HTMLDivElement | null = null;\n private panelEl: HTMLDivElement | null = null;\n private messagesEl: HTMLDivElement | null = null;\n private inputEl: HTMLTextAreaElement | null = null;\n private sendBtn: HTMLButtonElement | null = null;\n private statusDot: HTMLDivElement | null = null;\n private statusText: HTMLSpanElement | null = null;\n private stopBtnContainer: HTMLDivElement | null = null;\n private styleEl: HTMLStyleElement | null = null;\n\n // ─── FAB 拖拽状态 ───\n private fabDragging = false;\n private fabHasMoved = false;\n\n private mounted = false;\n private expanded: boolean;\n private status: PanelStatus = \"idle\";\n\n /** 用户发送消息回调 — 由 WebAgent 绑定 */\n onSend: ((text: string) => Promise<void>) | null = null;\n /** 用户点击停止按钮回调 */\n onStop: (() => void) | null = null;\n\n constructor(options: PanelOptions = {}) {\n this.container = options.container ?? document.body;\n this.enableMask = options.enableMask ?? true;\n this.maskOpacity = Math.max(0, Math.min(1, options.maskOpacity ?? 0.15));\n this.expanded = options.expanded ?? false;\n this.title = options.title ?? \"AutoPilot\";\n this.placeholder = options.placeholder ?? \"输入要执行的网页操作...\";\n this.maskText = options.maskText ?? \"AutoPilot 正在操作页面\";\n this.emptyText = options.emptyText ?? \"发送一条消息,AI 将帮你操作页面\";\n\n // 默认自动挂载,传 mount: false 时需手动调用 mount()\n if (options.mount !== false) {\n this.mount();\n }\n }\n\n // ─── 公共 API ───\n\n /** 挂载面板到 DOM(全局单例:先清理残留再创建,防止 HMR/多实例\"分身\") */\n mount(): void {\n if (this.mounted) return;\n // 清理 DOM 中可能残留的旧实例(HMR 热更新、重复 new Panel())\n this.cleanupStale();\n this.injectStyles();\n this.createDOM();\n this.bindEvents();\n this.mounted = true;\n // 根据初始状态显示\n if (this.expanded) {\n this.show();\n }\n }\n\n /** 卸载面板 */\n unmount(): void {\n if (!this.mounted) return;\n this.root?.remove();\n this.styleEl?.remove();\n this.root = null;\n this.fab = null;\n this.mask = null;\n this.panelEl = null;\n this.messagesEl = null;\n this.inputEl = null;\n this.sendBtn = null;\n this.statusDot = null;\n this.statusText = null;\n this.stopBtnContainer = null;\n this.styleEl = null;\n this.mounted = false;\n }\n\n /** 展开面板(tooltip 风格定位到 FAB 旁边,FAB 保持可见) */\n show(): void {\n if (!this.mounted) this.mount();\n this.expanded = true;\n this.fab?.classList.add(\"active\");\n // 先定位再显示,避免初始位置闪烁\n this.updatePanelPosition();\n this.panelEl?.classList.remove(\"collapsed\");\n this.inputEl?.focus();\n }\n\n /** 收起面板 */\n hide(): void {\n this.expanded = false;\n this.panelEl?.classList.add(\"collapsed\");\n this.fab?.classList.remove(\"active\");\n }\n\n /** 切换展开/收起 */\n toggle(): void {\n if (this.expanded) this.hide();\n else this.show();\n }\n\n /** 是否已展开 */\n isExpanded(): boolean {\n return this.expanded;\n }\n\n /** 是否已挂载 */\n isMounted(): boolean {\n return this.mounted;\n }\n\n /** 添加消息到面板 */\n addMessage(type: MessageType, text: string): void {\n if (!this.messagesEl) return;\n // 移除空状态\n const empty = this.messagesEl.querySelector(\".ap-empty\");\n if (empty) empty.remove();\n // 移除 typing 指示器\n this.removeTyping();\n\n const msg = document.createElement(\"div\");\n msg.className = `ap-msg ${type}`;\n msg.textContent = text;\n this.messagesEl.appendChild(msg);\n this.scrollToBottom();\n }\n\n /** 清空所有消息 */\n clearMessages(): void {\n if (!this.messagesEl) return;\n this.messagesEl.innerHTML = \"\";\n this.showEmpty();\n }\n\n /** 设置面板状态 */\n setStatus(status: PanelStatus, text?: string): void {\n this.status = status;\n if (this.statusDot) {\n this.statusDot.className = `ap-status-dot ${status}`;\n }\n if (this.statusText) {\n const defaultTexts: Record<PanelStatus, string> = {\n idle: \"就绪\",\n running: \"执行中...\",\n error: \"出错\",\n };\n this.statusText.textContent = text ?? defaultTexts[status];\n }\n // 控制输入区 & 停止按钮\n this.updateInputState();\n // 控制遮罩\n if (this.enableMask) {\n if (status === \"running\") {\n this.showMask();\n } else {\n this.hideMask();\n }\n }\n }\n\n /** 显示操作遮罩 */\n showMask(): void {\n this.mask?.classList.add(\"active\");\n }\n\n /** 隐藏操作遮罩 */\n hideMask(): void {\n this.mask?.classList.remove(\"active\");\n }\n\n /** 显示 typing 指示器 */\n showTyping(): void {\n if (!this.messagesEl) return;\n this.removeTyping();\n const typing = document.createElement(\"div\");\n typing.className = \"ap-typing\";\n typing.innerHTML = `\n <div class=\"ap-typing-dot\"></div>\n <div class=\"ap-typing-dot\"></div>\n <div class=\"ap-typing-dot\"></div>\n `;\n this.messagesEl.appendChild(typing);\n this.scrollToBottom();\n }\n\n /** 移除 typing 指示器 */\n removeTyping(): void {\n const typing = this.messagesEl?.querySelector(\".ap-typing\");\n if (typing) typing.remove();\n }\n\n // ─── 内部方法 ───\n\n /**\n * 清理 DOM 中残留的旧 Panel 元素。\n * 防止 HMR 热更新或多次 new Panel() 导致多个 FAB/面板\"分身\"。\n */\n private cleanupStale(): void {\n // 清除所有旧的 autopilot root 容器(含 FAB + 面板 + 遮罩)\n document.querySelectorAll(\"[data-autopilot-ignore]\").forEach((el) => {\n // 只清理顶层 root(不清理 root 内部的子元素)\n if (el.parentElement === this.container || el.parentElement === document.body) {\n el.remove();\n }\n });\n // 清除残留样式\n document.querySelectorAll(\"style[data-autopilot-panel]\").forEach((el) => el.remove());\n }\n\n private injectStyles(): void {\n this.styleEl = document.createElement(\"style\");\n this.styleEl.setAttribute(\"data-autopilot-panel\", \"\");\n this.styleEl.textContent = PANEL_STYLES;\n document.head.appendChild(this.styleEl);\n }\n\n private createDOM(): void {\n this.root = document.createElement(\"div\");\n this.root.setAttribute(\"data-autopilot-ignore\", \"\");\n\n // ─── 操作遮罩 ───\n this.mask = document.createElement(\"div\");\n this.mask.id = \"autopilot-mask\";\n this.mask.style.setProperty(\"--ap-mask-opacity\", String(this.maskOpacity));\n this.mask.innerHTML = `\n <div class=\"ap-mask-label\">\n <div class=\"ap-mask-spinner\"></div>\n <span>${this.escapeHtml(this.maskText)}</span>\n </div>\n `;\n this.root.appendChild(this.mask);\n\n // ─── FAB 按钮 ───\n this.fab = document.createElement(\"button\");\n this.fab.id = \"autopilot-fab\";\n this.fab.setAttribute(\"data-autopilot-ignore\", \"\");\n this.fab.innerHTML = ICONS.logo;\n this.fab.title = this.title;\n if (this.expanded) this.fab.classList.add(\"active\");\n this.root.appendChild(this.fab);\n\n // ─── 面板 ───\n this.panelEl = document.createElement(\"div\");\n this.panelEl.id = \"autopilot-panel\";\n this.panelEl.setAttribute(\"data-autopilot-ignore\", \"\");\n if (!this.expanded) this.panelEl.classList.add(\"collapsed\");\n\n this.panelEl.innerHTML = `\n <div class=\"ap-header\">\n <div class=\"ap-header-left\">\n <div class=\"ap-header-logo\">${ICONS.logo}</div>\n <span class=\"ap-header-title\">${this.escapeHtml(this.title)}</span>\n </div>\n <div class=\"ap-header-actions\">\n <button class=\"ap-header-btn\" data-action=\"clear\" title=\"清空消息\">${ICONS.trash}</button>\n <button class=\"ap-header-btn\" data-action=\"minimize\" title=\"收起面板\">${ICONS.minimize}</button>\n </div>\n </div>\n <div class=\"ap-status\">\n <div class=\"ap-status-dot idle\"></div>\n <span class=\"ap-status-text\">就绪</span>\n </div>\n <div class=\"ap-messages\">\n <div class=\"ap-empty\">\n <div class=\"ap-empty-icon\">${ICONS.logo}</div>\n <div class=\"ap-empty-text\">${this.escapeHtml(this.emptyText)}</div>\n </div>\n </div>\n <div class=\"ap-stop-container\" style=\"display:none\">\n <button class=\"ap-stop-btn\">${ICONS.stop}<span>停止执行</span></button>\n </div>\n <div class=\"ap-input-area\">\n <div class=\"ap-input-wrapper\">\n <textarea class=\"ap-input\" rows=\"1\" placeholder=\"${this.escapeHtml(this.placeholder)}\"></textarea>\n </div>\n <button class=\"ap-send-btn\" title=\"发送\">${ICONS.send}</button>\n </div>\n `;\n\n this.root.appendChild(this.panelEl);\n\n // 缓存 DOM 引用\n this.messagesEl = this.panelEl.querySelector(\".ap-messages\");\n this.inputEl = this.panelEl.querySelector(\".ap-input\");\n this.sendBtn = this.panelEl.querySelector(\".ap-send-btn\");\n this.statusDot = this.panelEl.querySelector(\".ap-status-dot\");\n this.statusText = this.panelEl.querySelector(\".ap-status-text\");\n this.stopBtnContainer = this.panelEl.querySelector(\".ap-stop-container\");\n\n // 挂载到容器\n this.container.appendChild(this.root);\n }\n\n private bindEvents(): void {\n // FAB 点击 → 切换面板(拖拽过的不触发)\n this.fab?.addEventListener(\"click\", () => {\n if (this.fabHasMoved) {\n this.fabHasMoved = false;\n return;\n }\n this.toggle();\n });\n\n // 头部按钮\n this.panelEl?.addEventListener(\"click\", (e) => {\n const target = (e.target as HTMLElement).closest(\"[data-action]\");\n if (!target) return;\n const action = target.getAttribute(\"data-action\");\n if (action === \"minimize\") this.hide();\n if (action === \"clear\") this.clearMessages();\n });\n\n // 发送按钮\n this.sendBtn?.addEventListener(\"click\", () => this.handleSend());\n\n // 输入框回车发送(Shift+Enter 换行)\n this.inputEl?.addEventListener(\"keydown\", (e) => {\n if (e.key === \"Enter\" && !e.shiftKey) {\n e.preventDefault();\n this.handleSend();\n }\n });\n\n // 输入框自动调整高度\n this.inputEl?.addEventListener(\"input\", () => {\n if (!this.inputEl) return;\n this.inputEl.style.height = \"auto\";\n this.inputEl.style.height = Math.min(this.inputEl.scrollHeight, 120) + \"px\";\n });\n\n // 停止按钮\n this.stopBtnContainer?.addEventListener(\"click\", () => {\n this.onStop?.();\n });\n\n // ─── 拖拽绑定 ───\n this.initFabDrag();\n }\n\n /**\n * 使用 @floating-ui/dom 计算面板相对于 FAB 的 tooltip 位置。\n * 根据 FAB 贴边方向自动翻转,并设置对应的 transform-origin 确保动画自然。\n */\n private updatePanelPosition(): void {\n if (!this.fab || !this.panelEl || !this.expanded) return;\n computePosition(this.fab, this.panelEl, {\n placement: \"top-end\",\n middleware: [\n offset(8),\n flip({ fallbackPlacements: [\"top-start\", \"bottom-end\", \"bottom-start\", \"left\", \"right\"] }),\n shift({ padding: 12 }),\n ],\n }).then(({ x, y, placement }) => {\n if (!this.panelEl) return;\n // 根据实际弹出方向设置 transform-origin,保证 tooltip 展开/收起动画自然\n const origins: Record<string, string> = {\n \"top-end\": \"bottom right\",\n \"top-start\": \"bottom left\",\n \"bottom-end\": \"top right\",\n \"bottom-start\": \"top left\",\n left: \"center right\",\n right: \"center left\",\n };\n Object.assign(this.panelEl.style, {\n left: `${x}px`,\n top: `${y}px`,\n right: \"auto\",\n bottom: \"auto\",\n transformOrigin: origins[placement] ?? \"bottom right\",\n });\n });\n }\n\n /**\n * 初始化 FAB 按钮拖拽:长按 300ms 后进入拖拽模式,松手后自动贴边。\n * 短按(未触发长按)或移动距离不超过阈值的走正常 click toggle 逻辑。\n */\n private initFabDrag(): void {\n if (!this.fab) return;\n const fab = this.fab;\n const LONG_PRESS_MS = 300;\n let startX = 0;\n let startY = 0;\n let fabStartX = 0;\n let fabStartY = 0;\n let moved = false;\n let longPressTimer: ReturnType<typeof setTimeout> | null = null;\n let dragActivated = false;\n let pointerId = -1;\n\n const onDown = (e: PointerEvent) => {\n moved = false;\n dragActivated = false;\n startX = e.clientX;\n startY = e.clientY;\n pointerId = e.pointerId;\n const rect = fab.getBoundingClientRect();\n fabStartX = rect.left;\n fabStartY = rect.top;\n\n // 长按计时器\n longPressTimer = setTimeout(() => {\n dragActivated = true;\n this.fabDragging = true;\n fab.setPointerCapture(pointerId);\n fab.style.transition = \"none\";\n fab.classList.add(\"dragging\");\n }, LONG_PRESS_MS);\n\n e.preventDefault();\n };\n\n const onMove = (e: PointerEvent) => {\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n\n // 如果还没激活拖拽,移动超过 4px 则取消长按(算作普通滑动)\n if (!dragActivated) {\n if (Math.abs(dx) > 4 || Math.abs(dy) > 4) {\n if (longPressTimer) { clearTimeout(longPressTimer); longPressTimer = null; }\n }\n return;\n }\n\n if (!moved && Math.abs(dx) < 4 && Math.abs(dy) < 4) return;\n moved = true;\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const fw = fab.offsetWidth;\n const fh = fab.offsetHeight;\n const newLeft = Math.max(0, Math.min(vw - fw, fabStartX + dx));\n const newTop = Math.max(0, Math.min(vh - fh, fabStartY + dy));\n fab.style.left = newLeft + \"px\";\n fab.style.top = newTop + \"px\";\n fab.style.right = \"auto\";\n fab.style.bottom = \"auto\";\n\n // 拖拽过程中实时更新 tooltip 面板位置\n if (this.expanded) this.updatePanelPosition();\n };\n\n const onUp = () => {\n if (longPressTimer) { clearTimeout(longPressTimer); longPressTimer = null; }\n if (!dragActivated) {\n // 短按 → 不拦截,让 click 正常触发 toggle\n return;\n }\n this.fabDragging = false;\n this.fabHasMoved = dragActivated; // 拦截后续 click\n dragActivated = false;\n fab.classList.remove(\"dragging\");\n if (moved) {\n this.snapFabToEdge();\n }\n };\n\n fab.addEventListener(\"pointerdown\", onDown);\n fab.addEventListener(\"pointermove\", onMove);\n fab.addEventListener(\"pointerup\", onUp);\n fab.addEventListener(\"pointercancel\", onUp);\n }\n\n /**\n * FAB 吸附到最近屏幕边缘(左/右贴边,上下保持位置)。\n */\n private snapFabToEdge(): void {\n if (!this.fab) return;\n const rect = this.fab.getBoundingClientRect();\n const vw = window.innerWidth;\n const vh = window.innerHeight;\n const fw = this.fab.offsetWidth;\n const fh = this.fab.offsetHeight;\n const gap = 12;\n const centerX = rect.left + fw / 2;\n const snapLeft = centerX < vw / 2;\n const targetX = snapLeft ? gap : vw - fw - gap;\n const targetY = Math.max(gap, Math.min(vh - fh - gap, rect.top));\n\n this.fab.style.transition = \"left 0.3s cubic-bezier(0.22, 1, 0.36, 1), top 0.3s cubic-bezier(0.22, 1, 0.36, 1)\";\n this.fab.style.left = targetX + \"px\";\n this.fab.style.top = targetY + \"px\";\n this.fab.style.right = \"auto\";\n this.fab.style.bottom = \"auto\";\n\n const cleanup = () => {\n if (this.fab) this.fab.style.transition = \"\";\n // 贴边后更新 tooltip 面板位置\n if (this.expanded) this.updatePanelPosition();\n };\n this.fab.addEventListener(\"transitionend\", cleanup, { once: true });\n setTimeout(cleanup, 350);\n }\n\n private handleSend(): void {\n if (!this.inputEl || this.status === \"running\") return;\n const text = this.inputEl.value.trim();\n if (!text) return;\n\n this.inputEl.value = \"\";\n this.inputEl.style.height = \"auto\";\n this.addMessage(\"user\", text);\n\n if (this.onSend) {\n this.onSend(text).catch((err) => {\n this.addMessage(\"error\", `执行失败: ${err instanceof Error ? err.message : String(err)}`);\n this.setStatus(\"error\");\n });\n }\n }\n\n private updateInputState(): void {\n const isRunning = this.status === \"running\";\n if (this.inputEl) {\n this.inputEl.disabled = isRunning;\n }\n if (this.sendBtn) {\n this.sendBtn.disabled = isRunning;\n }\n if (this.stopBtnContainer) {\n this.stopBtnContainer.style.display = isRunning ? \"block\" : \"none\";\n }\n }\n\n private showEmpty(): void {\n if (!this.messagesEl) return;\n this.messagesEl.innerHTML = `\n <div class=\"ap-empty\">\n <div class=\"ap-empty-icon\">${ICONS.logo}</div>\n <div class=\"ap-empty-text\">${this.escapeHtml(this.emptyText)}</div>\n </div>\n `;\n }\n\n private scrollToBottom(): void {\n if (!this.messagesEl) return;\n // 双帧滚动:确保 DOM 渲染完毕后再滚到底部,避免新消息追加后高度未更新\n requestAnimationFrame(() => {\n requestAnimationFrame(() => {\n if (!this.messagesEl) return;\n this.messagesEl.scrollTop = this.messagesEl.scrollHeight;\n });\n });\n }\n\n private escapeHtml(str: string): string {\n const div = document.createElement(\"div\");\n div.textContent = str;\n return div.innerHTML;\n }\n}\n","/**\n * Web Tools 消息通信桥接层。\n *\n * 解决 Chrome Extension 的作用域隔离问题:\n *\n * Service Worker (后台) Content Script (页面)\n * ┌──────────────────┐ ┌──────────────────────┐\n * │ agent-core │ │ document / window │\n * │ tool-registry │ chrome.tabs │ │\n * │ │ .sendMessage() │ DOM 操作实际执行 │\n * │ tool.execute() │ ─────────────────► │ handleToolMessage() │\n * │ ↓ │ │ ↓ │\n * │ sendToContent() │ ◄───────────────── │ 返回执行结果 │\n * └──────────────────┘ response └──────────────────────┘\n *\n * 使用方式:\n * Service Worker 端:\n * import { createProxyExecutor } from \"./messaging.js\";\n * const execute = createProxyExecutor();\n * // execute 会把调用转发到 content script\n *\n * Content Script 端:\n * import { registerToolHandler } from \"./messaging.js\";\n * registerToolHandler(actualExecutors);\n * // 监听来自 service worker 的工具调用请求\n */\n\n// ─── 消息类型定义 ───\n\n/** Service Worker → Content Script 的工具调用请求 */\nexport type ToolCallMessage = {\n type: \"AUTOPILOT_TOOL_CALL\";\n toolName: string;\n params: Record<string, unknown>;\n callId: string;\n};\n\n/** Content Script → Service Worker 的工具调用结果 */\nexport type ToolCallResponse = {\n type: \"AUTOPILOT_TOOL_RESULT\";\n callId: string;\n result: {\n content: string | Record<string, unknown>;\n details?: Record<string, unknown>;\n };\n};\n\n// ─── Service Worker 端(发送方) ───\n\n/**\n * 创建代理执行器 — 在 Service Worker 端使用。\n *\n * 它不直接执行 DOM 操作,而是通过 chrome.tabs.sendMessage\n * 把调用请求发给当前活动 tab 的 content script 执行。\n *\n * @returns execute 函数,签名与 ToolDefinition.execute 相同\n */\nexport function createProxyExecutor() {\n return async (\n toolName: string,\n params: Record<string, unknown>,\n ): Promise<{ content: string | Record<string, unknown>; details?: Record<string, unknown> }> => {\n const callId = `${toolName}_${Date.now()}_${Math.random().toString(36).slice(2, 8)}`;\n\n // 获取当前活动 tab\n const [tab] = await chrome.tabs.query({ active: true, currentWindow: true });\n if (!tab?.id) {\n return { content: \"错误:没有活动的浏览器标签页\" };\n }\n\n // 发送消息到 content script 并等待结果\n const message: ToolCallMessage = {\n type: \"AUTOPILOT_TOOL_CALL\",\n toolName,\n params,\n callId,\n };\n\n try {\n const response = await chrome.tabs.sendMessage(tab.id, message) as ToolCallResponse;\n return response.result;\n } catch (err) {\n return {\n content: `工具调用失败(content script 可能未加载): ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true, toolName },\n };\n }\n };\n}\n\n// ─── Content Script 端(接收方) ───\n\n/** 工具执行器映射:toolName → execute 函数 */\nexport type ToolExecutorMap = Map<\n string,\n (params: Record<string, unknown>) => Promise<{\n content: string | Record<string, unknown>;\n details?: Record<string, unknown>;\n }>\n>;\n\n/**\n * 在 Content Script 端注册工具执行处理器。\n *\n * 监听来自 Service Worker 的 AUTOPILOT_TOOL_CALL 消息,\n * 根据 toolName 找到对应的执行函数,执行后返回结果。\n *\n * @param executors 工具名称 → 执行函数的映射\n */\nexport function registerToolHandler(executors: ToolExecutorMap): void {\n chrome.runtime.onMessage.addListener(\n (message: unknown, _sender: chrome.runtime.MessageSender, sendResponse: (response: ToolCallResponse) => void) => {\n // 只处理我们的消息类型\n const msg = message as ToolCallMessage;\n if (msg?.type !== \"AUTOPILOT_TOOL_CALL\") return false;\n\n const executor = executors.get(msg.toolName);\n if (!executor) {\n sendResponse({\n type: \"AUTOPILOT_TOOL_RESULT\",\n callId: msg.callId,\n result: { content: `未知工具: ${msg.toolName}` },\n });\n return true; // 同步返回 true 表示我们会异步 sendResponse\n }\n\n // 异步执行工具并返回结果\n executor(msg.params)\n .then((result) => {\n sendResponse({\n type: \"AUTOPILOT_TOOL_RESULT\",\n callId: msg.callId,\n result,\n });\n })\n .catch((err) => {\n sendResponse({\n type: \"AUTOPILOT_TOOL_RESULT\",\n callId: msg.callId,\n result: {\n content: `工具 ${msg.toolName} 执行异常: ${err instanceof Error ? err.message : String(err)}`,\n details: { error: true },\n },\n });\n });\n\n return true; // 告诉 Chrome 我们会异步调用 sendResponse\n },\n );\n}\n","/**\n * WebAgent — 浏览器端 AI Agent 类。\n *\n * 封装了完整的 Agent 能力,可在浏览器中独立运行:\n * - 对话(chat) → 发消息、获取 AI 回复\n * - 工具注册 → 注册内置 Web 工具或自定义工具\n * - 决策循环 → 复用 core/agent-loop.ts 的通用逻辑\n * - AI 连接 → 复用 core/ai-client.ts(基于 fetch,跨平台)\n *\n * 使用示例:\n * ```ts\n * const agent = new WebAgent({ token: \"ghp_xxx\", provider: \"copilot\" });\n * agent.registerTools(); // 注册内置 Web 工具\n * agent.callbacks.onText = (text) => console.log(text);\n *\n * const result = await agent.chat(\"获取页面标题\");\n * console.log(result.reply);\n * ```\n *\n * 架构位置:\n * ┌──────────────────────────────────────────────────┐\n * │ WebAgent(浏览器端入口) │\n * │ ┌──────────┐ ┌────────────┐ ┌──────────────┐ │\n * │ │ core/ │ │ core/ │ │ web/ │ │\n * │ │ ai-client│ │ agent-loop │ │ (DOM/导航等)│ │\n * │ │ (fetch) │ │ (通用循环) │ │ │ │\n * │ └──────────┘ └────────────┘ └──────────────┘ │\n * └──────────────────────────────────────────────────┘\n */\nimport {\n executeAgentLoop,\n type AgentLoopCallbacks,\n type AgentLoopResult,\n type RoundStabilityWaitOptions,\n} from \"../core/agent-loop/index.js\";\nimport type { AIMessage } from \"../core/types.js\";\nimport { createAIClient } from \"../core/ai-client/index.js\";\nimport type { AIClient } from \"../core/types.js\";\nimport { ToolRegistry, type ToolDefinition, type ToolCallResult } from \"../core/tool-registry.js\";\nimport { buildSystemPrompt } from \"../core/system-prompt.js\";\nimport { generateSnapshot, type SnapshotOptions } from \"./tools/page-info-tool.js\";\nimport { createDomTool, setActiveRefStore } from \"./tools/dom-tool.js\";\nimport { createNavigateTool } from \"./tools/navigate-tool.js\";\nimport { createPageInfoTool } from \"./tools/page-info-tool.js\";\nimport { createWaitTool } from \"./tools/wait-tool.js\";\nimport { createEvaluateTool } from \"./tools/evaluate-tool.js\";\nimport { RefStore } from \"./ref-store.js\";\nimport { installEventListenerTracking } from \"./event-listener-tracker.js\";\nimport Panel, { type PanelOptions } from \"./ui/index.js\";\n\n// 默认安装全局事件监听追踪(幂等),用于快照输出 listeners 信号。\ninstallEventListenerTracking();\n\n// ─── 回调类型 ───\n\n/** WebAgent 事件回调(扩展 AgentLoopCallbacks,增加快照事件) */\nexport type WebAgentCallbacks = AgentLoopCallbacks & {\n /** 自动快照生成完成时触发 */\n onSnapshot?: (snapshot: string) => void;\n};\n\n// ─── 配置 ───\n\nexport type WebAgentOptions = {\n /**\n * 自定义 AI 客户端实例(可选)。\n *\n * 传入后将直接使用该实例进行对话,忽略 token / provider / model / baseURL。\n * 支持 BaseAIClient 或任何实现 AIClient 接口的对象。\n *\n * ```ts\n * const client = new BaseAIClient({ chatHandler: async (params) => { ... } });\n * const agent = new WebAgent({ client });\n * ```\n */\n client?: AIClient;\n /** API 认证 Token (GitHub PAT / OpenAI key / Anthropic key) */\n token?: string;\n /** AI 提供商: \"copilot\" | \"openai\" | \"anthropic\" | \"deepseek\" | \"doubao\" | \"qwen\"(默认 \"copilot\") */\n provider?: string;\n /** 模型名称(默认 \"gpt-4o\") */\n model?: string;\n /** 自定义 API 基础 URL(可选,覆盖 provider 默认值) */\n baseURL?: string;\n /** 是否启用流式输出(SSE)。默认 true;false 时使用 JSON 非流式响应。 */\n stream?: boolean;\n /** 单次 AI 请求超时(毫秒,默认 45000;<=0 表示不设置超时)。 */\n requestTimeoutMs?: number;\n /** 是否启用干运行模式 */\n dryRun?: boolean;\n /**\n * 系统提示词注册项。\n * - string:按默认 key 注册一条\n * - Record<string, string>:按 key 批量注册多条\n */\n systemPrompt?: string | Record<string, string>;\n /** 最大工具调用轮次(默认 10) */\n maxRounds?: number;\n /** 是否启用多轮对话记忆(默认 false) */\n memory?: boolean;\n /** 是否在每次对话前自动生成页面快照(默认 true) */\n autoSnapshot?: boolean;\n /** 快照选项(视口裁剪、智能剪枝等,autoSnapshot 开启时生效) */\n snapshotOptions?: SnapshotOptions;\n /** 轮次后稳定等待(加载态 + DOM 静默)配置 */\n roundStabilityWait?: RoundStabilityWaitOptions;\n /**\n * UI 面板配置。\n * - true:使用默认配置创建面板\n * - PanelOptions:使用自定义配置创建面板\n * - false / undefined:不创建面板\n */\n panel?: boolean | PanelOptions;\n};\n\n// ─── WebAgent 类 ───\n\nexport class WebAgent {\n /** 默认系统提示词 key(兼容旧版 setSystemPrompt(prompt))。 */\n private static readonly DEFAULT_SYSTEM_PROMPT_KEY = \"default\";\n /** 默认内置工具名(注册后受保护,不允许删除)。 */\n private static readonly DEFAULT_TOOL_NAMES = [\"dom\", \"navigate\", \"page_info\", \"wait\", \"evaluate\"] as const;\n\n /** 用户传入的自定义 AI 客户端实例(优先级高于 token/provider) */\n private client?: AIClient;\n private token: string;\n private provider: string;\n private model: string;\n private baseURL?: string;\n private stream: boolean;\n private requestTimeoutMs: number;\n private dryRun: boolean;\n private maxRounds: number;\n /** system prompt 注册表(key -> prompt 文本)。 */\n private systemPromptRegistry = new Map<string, string>();\n /** 受保护工具集合(默认工具)。 */\n private protectedToolNames = new Set<string>();\n\n /** 多轮对话记忆开关 */\n private memory: boolean;\n /** 对话历史(memory 开启时自动累积) */\n private history: AIMessage[] = [];\n /** 自动快照开关 */\n private autoSnapshot: boolean;\n /** 快照选项 */\n private snapshotOptions: SnapshotOptions;\n /** 轮次后稳定等待配置 */\n private roundStabilityWait?: RoundStabilityWaitOptions;\n\n /** 工具注册表实例 — 每个 WebAgent 拥有独立的工具集 */\n private registry = new ToolRegistry();\n\n /** 内置 UI 面板(通过 options.panel 配置启用) */\n panel: Panel | null = null;\n\n /** 事件回调 — 绑定后可实时获取 Agent 进度,用于 UI 展示 */\n callbacks: WebAgentCallbacks = {};\n\n constructor(options: WebAgentOptions) {\n this.client = options.client;\n this.token = options.token || \"\";\n this.provider = options.provider ?? \"copilot\";\n this.model = options.model ?? \"gpt-4o\";\n this.baseURL = options.baseURL;\n this.stream = options.stream ?? true;\n this.requestTimeoutMs = options.requestTimeoutMs ?? 45000;\n this.dryRun = options.dryRun ?? false;\n this.maxRounds = options.maxRounds ?? 40;\n this.memory = options.memory ?? false;\n this.autoSnapshot = options.autoSnapshot ?? true;\n this.snapshotOptions = options.snapshotOptions ?? {};\n this.roundStabilityWait = options.roundStabilityWait;\n\n if (typeof options.systemPrompt === \"string\") {\n this.setSystemPrompt(options.systemPrompt);\n } else if (options.systemPrompt && typeof options.systemPrompt === \"object\") {\n this.setSystemPrompts(options.systemPrompt);\n }\n\n // ─── UI 面板 ───\n if (options.panel) {\n const panelOpts = typeof options.panel === \"object\" ? options.panel : {};\n this.panel = new Panel(panelOpts);\n this.wirePanel();\n }\n }\n\n // ─── 工具管理 ───\n\n /** 注册所有内置 Web 工具(dom, navigate, page_info, wait, evaluate) */\n registerTools(): void {\n this.registry.register(createDomTool());\n this.registry.register(createNavigateTool());\n this.registry.register(createPageInfoTool());\n this.registry.register(createWaitTool());\n this.registry.register(createEvaluateTool());\n\n for (const name of WebAgent.DEFAULT_TOOL_NAMES) {\n this.protectedToolNames.add(name);\n }\n }\n\n /** 注册一个自定义工具 */\n registerTool(tool: ToolDefinition): void {\n this.registry.register(tool);\n }\n\n /**\n * 删除一个已注册工具。\n * - 默认内置工具(registerTools 注册)不允许删除\n * - 返回 true 表示删除成功,false 表示不存在或受保护\n */\n removeTool(name: string): boolean {\n if (this.protectedToolNames.has(name)) return false;\n return this.registry.unregister(name);\n }\n\n /** 检查工具是否已注册。 */\n hasTool(name: string): boolean {\n return this.registry.has(name);\n }\n\n /** 获取当前所有已注册工具名。 */\n getToolNames(): string[] {\n return this.registry.getDefinitions().map(tool => tool.name);\n }\n\n /**\n * 删除所有“非默认”工具。\n * 返回值为本次被删除的工具名数组。\n */\n clearCustomTools(): string[] {\n const removed: string[] = [];\n for (const tool of this.registry.getDefinitions()) {\n if (this.protectedToolNames.has(tool.name)) continue;\n if (this.registry.unregister(tool.name)) {\n removed.push(tool.name);\n }\n }\n return removed;\n }\n\n /** 获取所有已注册的工具定义列表 */\n getTools(): ToolDefinition[] {\n return this.registry.getDefinitions();\n }\n\n // ─── 配置修改 ───\n\n /** 设置 API Token */\n setToken(token: string): void {\n this.token = token;\n }\n\n /**\n * 设置自定义 AI 客户端实例。\n *\n * 传入后将优先使用该实例进行对话,忽略 token / provider / model / baseURL。\n * 传入 undefined 可恢复使用内置客户端。\n */\n setClient(client: AIClient | undefined): void {\n this.client = client;\n }\n\n /** 设置 AI 提供商 */\n setProvider(provider: string): void {\n this.provider = provider;\n }\n\n /** 设置模型 */\n setModel(model: string): void {\n this.model = model;\n }\n\n /** 设置是否启用流式输出(SSE) */\n setStream(enabled: boolean): void {\n this.stream = enabled;\n }\n\n /** 获取当前流式输出开关状态 */\n getStream(): boolean {\n return this.stream;\n }\n\n /** 设置单次 AI 请求超时(毫秒) */\n setRequestTimeoutMs(timeoutMs: number): void {\n this.requestTimeoutMs = Math.floor(timeoutMs);\n }\n\n /** 获取当前 AI 请求超时(毫秒) */\n getRequestTimeoutMs(): number {\n return this.requestTimeoutMs;\n }\n\n /** 切换干运行模式 */\n setDryRun(enabled: boolean): void {\n this.dryRun = enabled;\n }\n\n /**\n * 注册系统提示词。\n * - setSystemPrompt(prompt):使用默认 key 注册\n * - setSystemPrompt(key, prompt):按指定 key 注册\n */\n setSystemPrompt(prompt: string): void;\n setSystemPrompt(key: string, prompt: string): void;\n setSystemPrompt(keyOrPrompt: string, maybePrompt?: string): void {\n const key = maybePrompt === undefined\n ? WebAgent.DEFAULT_SYSTEM_PROMPT_KEY\n : keyOrPrompt.trim();\n const prompt = maybePrompt === undefined ? keyOrPrompt : maybePrompt;\n\n if (!key) throw new Error(\"system prompt 的 key 不能为空\");\n const value = prompt.trim();\n if (!value) throw new Error(\"system prompt 不能为空\");\n\n this.systemPromptRegistry.set(key, value);\n }\n\n /** 批量注册系统提示词(key -> prompt)。 */\n setSystemPrompts(prompts: Record<string, string>): void {\n for (const [key, prompt] of Object.entries(prompts)) {\n this.setSystemPrompt(key, prompt);\n }\n }\n\n /** 注销指定 key 的系统提示词。 */\n removeSystemPrompt(key: string): boolean {\n return this.systemPromptRegistry.delete(key);\n }\n\n /** 只保留指定 key 的系统提示词,其余全部删除。 */\n keepOnlySystemPrompt(key: string): boolean {\n if (!this.systemPromptRegistry.has(key)) return false;\n const value = this.systemPromptRegistry.get(key)!;\n this.systemPromptRegistry.clear();\n this.systemPromptRegistry.set(key, value);\n return true;\n }\n\n /** 获取当前已注册的全部系统提示词(浅拷贝)。 */\n getSystemPrompts(): Record<string, string> {\n return Object.fromEntries(this.systemPromptRegistry.entries());\n }\n\n /** 删除全部系统提示词。 */\n clearSystemPrompts(): void {\n this.systemPromptRegistry.clear();\n }\n\n /** 开启或关闭多轮对话记忆 */\n setMemory(enabled: boolean): void {\n this.memory = enabled;\n if (!enabled) this.history = [];\n }\n\n /** 获取当前记忆开关状态 */\n getMemory(): boolean {\n return this.memory;\n }\n\n /** 开启或关闭自动快照 */\n setAutoSnapshot(enabled: boolean): void {\n this.autoSnapshot = enabled;\n }\n\n /** 获取当前自动快照开关状态 */\n getAutoSnapshot(): boolean {\n return this.autoSnapshot;\n }\n\n /** 设置快照选项(视口裁剪、智能剪枝等) */\n setSnapshotOptions(options: SnapshotOptions): void {\n this.snapshotOptions = options;\n }\n\n /** 获取当前快照选项 */\n getSnapshotOptions(): SnapshotOptions {\n return { ...this.snapshotOptions };\n }\n\n /** 清空对话历史(不影响记忆开关) */\n clearHistory(): void {\n this.history = [];\n }\n\n // ─── UI 面板 ───\n\n /**\n * 手动创建并挂载 UI 面板(构造时未传 panel 选项时可后续调用)。\n * 若面板已存在则跳过。\n */\n createPanel(options: PanelOptions = {}): Panel {\n if (this.panel) return this.panel;\n this.panel = new Panel(options);\n this.wirePanel();\n return this.panel;\n }\n\n /**\n * 销毁 UI 面板。\n */\n destroyPanel(): void {\n if (!this.panel) return;\n this.panel.unmount();\n this.panel = null;\n }\n\n /**\n * 建立面板到 WebAgent 的双向绑定。\n *\n * - panel.onSend → agent.chat()\n * - agent.callbacks → panel 消息流 & 状态\n */\n private wirePanel(): void {\n if (!this.panel) return;\n const panel = this.panel;\n\n // 用户消息 → agent.chat\n panel.onSend = async (text: string) => {\n panel.setStatus(\"running\");\n panel.showTyping();\n try {\n const result = await this.chat(text);\n panel.removeTyping();\n if (result.reply) {\n panel.addMessage(\"assistant\", result.reply);\n }\n panel.setStatus(\"idle\");\n } catch (err) {\n panel.removeTyping();\n panel.addMessage(\"error\", `执行失败: ${err instanceof Error ? err.message : String(err)}`);\n panel.setStatus(\"error\");\n }\n };\n\n // 包裹 callbacks:转发到面板\n const originalOnText = this.callbacks.onText;\n const originalOnToolCall = this.callbacks.onToolCall;\n const originalOnToolResult = this.callbacks.onToolResult;\n\n this.callbacks.onText = (text: string) => {\n originalOnText?.(text);\n // 实时文本由 wirePanel.onSend 的 result.reply 处理,此处不重复添加\n };\n\n this.callbacks.onToolCall = (name: string, input: unknown) => {\n originalOnToolCall?.(name, input);\n const inputStr = typeof input === \"string\" ? input : JSON.stringify(input, null, 0);\n const summary = inputStr.length > 80 ? inputStr.slice(0, 80) + \"…\" : inputStr;\n panel.addMessage(\"tool\", `🔧 ${name}(${summary})`);\n };\n\n this.callbacks.onToolResult = (name: string, result: ToolCallResult) => {\n originalOnToolResult?.(name, result);\n const resultStr = typeof result.content === \"string\" ? result.content : JSON.stringify(result.content, null, 0);\n const summary = resultStr.length > 100 ? resultStr.slice(0, 100) + \"…\" : resultStr;\n panel.addMessage(\"tool\", `✅ ${name} → ${summary}`);\n };\n }\n\n // ─── 核心能力 ───\n\n /**\n * 发送消息并获取 AI 回复(含完整工具调用循环)。\n *\n * 内部流程(全部复用 core):\n * 1. createAIClient() → 创建 fetch AI 客户端\n * 2. buildSystemPrompt() → 构建系统提示词\n * 3. executeAgentLoop() → 执行决策循环\n * 4. callbacks → 实时通知 UI\n */\n async chat(message: string): Promise<AgentLoopResult> {\n // 优先使用自定义 client,否则使用内置 createAIClient\n const client = this.client ?? this.createBuiltinClient();\n\n // 先构建基础系统提示词,再追加已注册的 system prompt 扩展。\n let systemPrompt = buildSystemPrompt({\n listenerEvents: this.snapshotOptions.listenerEvents,\n });\n if (this.systemPromptRegistry.size > 0) {\n const extensionText = Array.from(this.systemPromptRegistry.entries())\n .map(([key, prompt]) => `- [${key}]\\n${prompt}`)\n .join(\"\\n\\n\");\n systemPrompt += `\\n\\n## Registered System Prompt Extensions\\n${extensionText}`;\n }\n\n // ─── 自动快照:注入 system prompt,不污染对话历史 ───\n // 创建本次对话的 RefStore,快照结束后保持活跃,对话结束后清空\n const refStore = new RefStore(globalThis.location?.href);\n setActiveRefStore(refStore);\n let initialSnapshot: string | undefined;\n\n try {\n const snapshot = generateSnapshot(document.body, {\n maxDepth: 12,\n viewportOnly: false,\n maxNodes: 500,\n maxChildren: 30,\n ...this.snapshotOptions,\n refStore,\n });\n initialSnapshot = snapshot;\n if (this.autoSnapshot) {\n this.callbacks.onSnapshot?.(snapshot);\n }\n } catch {\n // 快照失败不阻塞正常流程\n }\n\n // 包装回调:在恢复快照前重置 RefStore,确保新快照的 hash ID 有效\n const wrappedCallbacks: WebAgentCallbacks = {\n ...this.callbacks,\n onBeforeRecoverySnapshot: (newUrl?: string) => {\n // URL 变化 → 清空映射 + 更新 URL 命名空间\n // 元素定位失败 → 仅清空可能失效的映射(URL 不变)\n if (newUrl !== undefined) {\n refStore.reset(newUrl);\n } else {\n refStore.clear();\n }\n // 转发到用户回调(如有设置)\n this.callbacks.onBeforeRecoverySnapshot?.(newUrl);\n },\n };\n\n // 复用 core/agent-loop — 同一份决策循环\n const result = await executeAgentLoop({\n client,\n registry: this.registry,\n systemPrompt,\n message,\n initialSnapshot,\n history: this.memory ? this.history : undefined,\n dryRun: this.dryRun,\n maxRounds: this.maxRounds,\n roundStabilityWait: this.roundStabilityWait,\n callbacks: wrappedCallbacks,\n });\n\n // 记忆模式:累积对话历史供下次 chat() 使用\n if (this.memory) {\n this.history = result.messages;\n }\n\n // 对话结束,清空 RefStore\n refStore.clear();\n setActiveRefStore(undefined);\n\n return result;\n }\n\n // ─── 内部方法 ───\n\n /**\n * 创建内置 AI 客户端(基于 token / provider / model 配置)。\n *\n * @throws 未设置 token 时抛出 Error\n */\n private createBuiltinClient(): AIClient {\n if (!this.token) {\n throw new Error(\"未设置 Token,请先调用 setToken() 或传入自定义 client\");\n }\n return createAIClient({\n provider: this.provider,\n model: this.model,\n apiKey: this.token,\n baseURL: this.baseURL,\n stream: this.stream,\n requestTimeoutMs: this.requestTimeoutMs,\n });\n }\n}\n\n// ─── Re-exports ───\n// 从入口文件统一导出所有公共 API,消费方只需 import from \"agentpage\"\n\nexport {\n generateSnapshot,\n type SnapshotOptions,\n} from \"./tools/page-info-tool.js\";\nexport { createDomTool } from \"./tools/dom-tool.js\";\nexport { createNavigateTool } from \"./tools/navigate-tool.js\";\nexport { createPageInfoTool } from \"./tools/page-info-tool.js\";\nexport { createWaitTool } from \"./tools/wait-tool.js\";\nexport { createEvaluateTool } from \"./tools/evaluate-tool.js\";\nexport {\n createProxyExecutor,\n registerToolHandler,\n type ToolCallMessage,\n type ToolCallResponse,\n type ToolExecutorMap,\n} from \"./messaging.js\";\nexport { default as Panel, type PanelOptions } from \"./ui/index.js\";\n"],"mappings":"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"}
|