@coolkiller007/my-page-agent 0.2.5 → 0.2.6

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 CHANGED
@@ -1,7 +1,6 @@
1
1
  # My Page Agent
2
2
 
3
- 面向中台的页面内嵌 GUI Agent。项目将自然语言任务转换为受控的页面读取与操作,并以
4
- 单一 npm 包交付。
3
+ 面向中台的页面内嵌 GUI Agent。项目将自然语言任务转换为受控的页面读取与操作,并以单一 npm 包交付。
5
4
 
6
5
  ## Installation
7
6
 
@@ -33,23 +32,19 @@ writeResult(result.data)
33
32
  agent.dispose()
34
33
  ```
35
34
 
36
- 生产环境必须通过公司后端代理或 AI 网关访问模型,不得把生产 API Key 打进浏览器产
37
- 物。页面内容在发送给模型前也应通过 `transformPageContent` 完成业务所需的脱敏。
35
+ 生产环境必须通过公司后端代理或 AI 网关访问模型,不得把生产 API Key 打进浏览器产物。页面内容在发送给模型前也应通过 `transformPageContent` 完成业务所需的脱敏。
38
36
 
39
37
  ## Public API
40
38
 
41
39
  包根入口是唯一公共入口:
42
40
 
43
41
  - `createAgent(config)`:创建并组装 `MyPageAgent`。
44
- - `MyPageAgent`:Agent 门面;提供 `execute(task)`、`stop()`、`dispose()` 和只读
45
- `status`。
42
+ - `MyPageAgent`:Agent 门面;提供 `execute(task)`、`stop()`、`dispose()` 和只读`status`。
46
43
  - `agent.ui`:提供 `show()`、`hide()`、`expand()` 和 `collapse()`。
47
44
  - `tool(options)`:定义自定义 Agent 工具。
48
- - 类型:`MyPageAgentConfig`、`AgentActivity`、`AgentStatus`、`ExecutionResult`
49
- 和 `HistoricalEvent`。
45
+ - 类型:`MyPageAgentConfig`、`AgentActivity`、`AgentStatus`、`ExecutionResult`和 `HistoricalEvent`。
50
46
 
51
- `AgentRuntime`、`BrowserController`、`OpenAICompatibleClient`、UI 内部组件、DOM
52
- Tree、Prompt 和自动修复器属于内部实现,不从包根入口导出。
47
+ `AgentRuntime`、`BrowserController`、`OpenAICompatibleClient`、UI 内部组件、DOM Tree、Prompt 和自动修复器属于内部实现,不从包根入口导出。
53
48
 
54
49
  ## Architecture
55
50
 
@@ -60,5 +55,4 @@ Tree、Prompt 和自动修复器属于内部实现,不从包根入口导出。
60
55
  - `src/shared`:跨能力共享的无状态工具。
61
56
  - `src/index.ts`:限定公共 API 的唯一包入口。
62
57
 
63
- 项目只发布 `@coolkiller007/my-page-agent`,不使用 npm workspaces。Browser、Runti
64
- me 和 UI 只在 `MyPageAgent` 中组装,内部模块使用相对 import。
58
+ 项目只发布 `@coolkiller007/my-page-agent`,不使用 npm workspaces。Browser、Runtime 和 UI 只在 `MyPageAgent` 中组装,内部模块使用相对 import。
package/dist/index.js CHANGED
@@ -235,7 +235,8 @@ async function selectOptionElement(selectElement, optionText) {
235
235
  if (!isSelectElement(selectElement)) throw new Error("Element is not a select element");
236
236
  const option = Array.from(selectElement.options).find((opt) => opt.textContent?.trim() === optionText.trim());
237
237
  if (!option) throw new Error(`Option with text "${optionText}" not found in select element`);
238
- selectElement.value = option.value;
238
+ if (selectElement.multiple) option.selected = true;
239
+ else selectElement.value = option.value;
239
240
  selectElement.dispatchEvent(new Event("change", { bubbles: true }));
240
241
  await waitFor$1(.05);
241
242
  }
@@ -1365,10 +1366,27 @@ var dom_tree_default = (args = {
1365
1366
  * 若不同步,选择后重新快照时 LLM 看不到变化,会误判操作未生效而反复执行 select 操作。
1366
1367
  */
1367
1368
  if (node.tagName.toLowerCase() === "select") {
1368
- const selectedOption = node.options[node.selectedIndex];
1369
- nodeData.attributes.value = selectedOption ? selectedOption.text : node.value;
1369
+ if (node.multiple) nodeData.attributes.value = Array.from(node.options).filter((opt) => opt.selected).map((opt) => opt.text).join(", ");
1370
+ else {
1371
+ const selectedOption = node.options[node.selectedIndex];
1372
+ nodeData.attributes.value = selectedOption ? selectedOption.text : node.value;
1373
+ }
1370
1374
  }
1371
1375
  /**
1376
+ * @edit @workaround input/textarea.value
1377
+ * 文本类输入框(含日期选择器底层常见的 <input type="text">)当前内容同样是 DOM 属性,
1378
+ * 不会反映到 HTML attribute 上,若不同步,输入后重新快照时 LLM 看不到变化,
1379
+ * 会误判输入未生效而反复重试。password/file/hidden 等类型不同步,避免泄露敏感值或无意义路径。
1380
+ */
1381
+ const NO_VALUE_SYNC_INPUT_TYPES = /* @__PURE__ */ new Set([
1382
+ "password",
1383
+ "file",
1384
+ "hidden",
1385
+ "checkbox",
1386
+ "radio"
1387
+ ]);
1388
+ if (node.tagName.toLowerCase() === "input" && !NO_VALUE_SYNC_INPUT_TYPES.has(node.type) || node.tagName.toLowerCase() === "textarea") nodeData.attributes.value = node.value;
1389
+ /**
1372
1390
  * @edit @workaround label-wrapped checkbox/radio checked
1373
1391
  * 常见组件库(如 antd)把 checkbox/radio 包在 <label> 里,视觉上的选中框覆盖在原生
1374
1392
  * input 上面,导致 input 不是 isTopElement,不会被收进可交互树、也就打印不出 checked
@@ -1586,7 +1604,11 @@ function flatTreeToString(flatTree, includeAttributes = [], keepSemanticTags = f
1586
1604
  "aria-haspopup",
1587
1605
  "aria-controls",
1588
1606
  "aria-owns",
1589
- "contenteditable"
1607
+ "contenteditable",
1608
+ "aria-valuenow",
1609
+ "aria-valuetext",
1610
+ "aria-valuemin",
1611
+ "aria-valuemax"
1590
1612
  ];
1591
1613
  const includeAttrs = [...includeAttributes, ...DEFAULT_INCLUDE_ATTRIBUTES];
1592
1614
  const capTextLength = (text, maxLength) => {