agentpage 0.0.20 → 0.0.21

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
@@ -155,6 +155,7 @@ AI 每一轮不是“凭记忆猜页面”,而是基于最新快照选择可
155
155
  - 元素标签与关键信息
156
156
  - hash selector(如 `#a1b2c`)
157
157
  - 结构化层级关系
158
+ - 布局折叠关联标记:当剪枝把同一容器链路中的多个子节点提升到同层时,会用括号分组(`collapsed-group`)标记它们的来源关联
158
159
 
159
160
  ### 2) 任务增量消费
160
161
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/tool-registry.ts","../src/core/types.ts","../src/core/agent-loop/types.ts","../src/web/ref-store.ts","../src/web/tools/page-info-tool.ts","../src/web/tools/dom-tool.ts","../src/web/tools/navigate-tool.ts","../src/web/tools/wait-tool.ts","../src/web/tools/evaluate-tool.ts","../src/web/messaging.ts","../src/web/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/core/tool-registry.ts","../src/core/types.ts","../src/core/agent-loop/types.ts","../src/web/ref-store.ts","../src/web/tools/page-info-tool.ts","../src/web/tools/dom-tool.ts","../src/web/tools/navigate-tool.ts","../src/web/tools/wait-tool.ts","../src/web/tools/evaluate-tool.ts","../src/web/messaging.ts","../src/web/index.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -90,7 +90,8 @@ function hasToolError(result) {
90
90
  * 压缩/剪枝是怎么做的(中)/ How compression & pruning works in practice (EN):
91
91
  * - `viewportOnly=true` 时:仅保留与视口相交元素(根层容器保留),完全视口外元素跳过。
92
92
  * - `pruneLayout=true` 时:无 id/无语义/无交互/无直接文本的布局容器会被“折叠”,
93
- * 子节点直接提升输出,减少无意义层级。
93
+ * 子节点直接提升输出,减少无意义层级;当同一折叠容器提升出多个相邻节点时,
94
+ * 快照会用括号分组块标记其关联来源(collapsed-group)。
94
95
  * - `maxNodes`:全局节点预算,超限后停止继续遍历并追加 truncation 提示。
95
96
  * - `maxChildren`:每个父节点只保留前 N 个子元素,其余用 `... (n children omitted)` 汇总。
96
97
  * - `maxTextLength`:节点文本按长度截断,避免长段文案占满上下文。
@@ -1368,8 +1369,11 @@ function buildSystemPrompt(params = {}) {
1368
1369
  " Output: new remaining task after removing this-round actions.",
1369
1370
  "- Use only visible targets from snapshot. Use #hashID as selector. Do not guess CSS selectors.",
1370
1371
  "- Batch independent visible actions in one round. Do not split one form into many rounds unnecessarily.",
1371
- "- Strict input order: before every fill/type/select_option, first click or focus the same target in the SAME round.",
1372
- "- Fixed sequence examples: dom.click(#field) -> dom.fill(#field, \"text\"); dom.click(#select) -> dom.select_option(#select, ...).",
1372
+ "- Strict input order (MANDATORY): before every fill/type/select_option, click or focus the SAME target immediately in the SAME round.",
1373
+ "- Multi-field rule (MANDATORY): execute alternating pairs in one batch: focus/click field A -> fill/type A -> focus/click field B -> fill/type B.",
1374
+ "- Do NOT run focus-only batches (e.g., focus A -> focus B). Each focused input/select target must be followed by its input/select action right away.",
1375
+ "- Fixed sequence examples: dom.focus(#name) -> dom.fill(#name, \"new-name\") -> dom.focus(#desc) -> dom.fill(#desc, \"new-desc\"); dom.click(#select) -> dom.select_option(#select, ...).",
1376
+ "- For check/uncheck, target the real input control (checkbox/radio), not nearby text/container nodes.",
1373
1377
  "- Form batch rule: for one visible form, complete all independent fields in one round; do not fill one field then verify repeatedly.",
1374
1378
  "- If an action will change DOM (open modal, navigate), stop after that action batch and continue next round with new snapshot.",
1375
1379
  "- Do NOT call page_info (snapshot/query/get_url/get_title). Snapshot is already provided every round.",
@@ -1603,6 +1607,53 @@ function isEditableElement(el) {
1603
1607
  if (el instanceof HTMLSelectElement) return true;
1604
1608
  return el instanceof HTMLElement && el.isContentEditable;
1605
1609
  }
1610
+ function isCheckableInput(el) {
1611
+ return el instanceof HTMLInputElement && (el.type === "checkbox" || el.type === "radio");
1612
+ }
1613
+ function findCheckableIn(el) {
1614
+ if (!el) return null;
1615
+ const found = el.querySelector("input[type=\"checkbox\"], input[type=\"radio\"]");
1616
+ return isCheckableInput(found) ? found : null;
1617
+ }
1618
+ /**
1619
+ * 归一化 check/uncheck 目标:
1620
+ * 允许模型命中文本容器/label/div,再回溯到关联 checkbox/radio,
1621
+ * 以降低快照剪枝导致的“命中语义节点而非真实控件”失败率。
1622
+ */
1623
+ function resolveCheckableTarget(el) {
1624
+ if (isCheckableInput(el)) return el;
1625
+ if (el instanceof HTMLLabelElement) {
1626
+ const byLabel = findCheckableIn(el);
1627
+ if (byLabel) return byLabel;
1628
+ const htmlFor = el.htmlFor?.trim();
1629
+ if (htmlFor) {
1630
+ const byFor = document.getElementById(htmlFor);
1631
+ if (isCheckableInput(byFor)) return byFor;
1632
+ }
1633
+ }
1634
+ if (el instanceof HTMLElement) {
1635
+ const ownerLabel = el.closest("label");
1636
+ if (ownerLabel) {
1637
+ const byOwnerLabel = findCheckableIn(ownerLabel);
1638
+ if (byOwnerLabel) return byOwnerLabel;
1639
+ const htmlFor = ownerLabel.htmlFor?.trim();
1640
+ if (htmlFor) {
1641
+ const byFor = document.getElementById(htmlFor);
1642
+ if (isCheckableInput(byFor)) return byFor;
1643
+ }
1644
+ }
1645
+ const inSelf = findCheckableIn(el);
1646
+ if (inSelf) return inSelf;
1647
+ const prev = el.previousElementSibling;
1648
+ if (isCheckableInput(prev)) return prev;
1649
+ const next = el.nextElementSibling;
1650
+ if (isCheckableInput(next)) return next;
1651
+ const parent = el.parentElement;
1652
+ const inParent = findCheckableIn(parent);
1653
+ if (inParent) return inParent;
1654
+ }
1655
+ return null;
1656
+ }
1606
1657
  function ensureActionable(el, action, selector) {
1607
1658
  if (!el.isConnected) return {
1608
1659
  content: `"${selector}" 元素已脱离文档,无法执行 ${action}`,
@@ -1680,14 +1731,17 @@ function createDomTool() {
1680
1731
  description: [
1681
1732
  "Perform DOM operations on the current page.",
1682
1733
  "Actions: click, fill, select_option, clear, check, uncheck, type, focus, hover, press, get_text, get_attr, set_attr, add_class, remove_class.",
1734
+ "Input/Select rule: before each fill/type/select_option, click or focus the same target immediately in the same round.",
1735
+ "For multiple fields, use alternating pairs in one batch: focus/click A -> fill/type A -> focus/click B -> fill/type B.",
1736
+ "Do not send focus-only batches for editable fields.",
1683
1737
  "Use the hash ID from DOM snapshot (e.g. #a1b2c) as selector."
1684
1738
  ].join(" "),
1685
1739
  schema: Type.Object({
1686
- action: Type.String({ description: "DOM action: click | fill | select_option | clear | check | uncheck | type | focus | hover | press | get_text | get_attr | set_attr | add_class | remove_class" }),
1740
+ action: Type.String({ description: "DOM action: click | fill | select_option | clear | check | uncheck | type | focus | hover | press | get_text | get_attr | set_attr | add_class | remove_class. For fill/type/select_option, perform click/focus on same target immediately before it." }),
1687
1741
  selector: Type.String({ description: "Element ref ID from snapshot (e.g. #r0, #r5) or CSS selector" }),
1688
- value: Type.Optional(Type.String({ description: "Value for fill/type/set_attr actions" })),
1742
+ value: Type.Optional(Type.String({ description: "Value for fill/type/set_attr actions. For fill/type, run after click/focus on same target in the same round." })),
1689
1743
  key: Type.Optional(Type.String({ description: "Key name for press action (e.g. Enter, Escape, Tab, ArrowDown, ArrowUp, Backspace, Delete, Space)" })),
1690
- label: Type.Optional(Type.String({ description: "Label text for select_option action (fallback when value is not provided)" })),
1744
+ label: Type.Optional(Type.String({ description: "Label text for select_option action (fallback when value is not provided). Run select_option after click/focus on same target in the same round." })),
1691
1745
  index: Type.Optional(Type.Number({ description: "0-based option index for select_option action" })),
1692
1746
  attribute: Type.Optional(Type.String({ description: "Attribute name for get_attr/set_attr actions" })),
1693
1747
  className: Type.Optional(Type.String({ description: "CSS class name for add_class/remove_class" })),
@@ -1738,6 +1792,10 @@ function createDomTool() {
1738
1792
  };
1739
1793
  el = elOrError;
1740
1794
  }
1795
+ if (action === "check" || action === "uncheck") {
1796
+ const resolvedCheckable = resolveCheckableTarget(el);
1797
+ if (resolvedCheckable) el = resolvedCheckable;
1798
+ }
1741
1799
  try {
1742
1800
  if (!force) {
1743
1801
  const checkResult = ensureActionable(el, action, selector);
@@ -2255,13 +2313,18 @@ function generateSnapshot(root = document.body, options = {}) {
2255
2313
  const orderedChildren = [...interactiveChildren, ...nonInteractiveChildren];
2256
2314
  const selectedChildren = orderedChildren.slice(0, maxChildren);
2257
2315
  const omittedChildren = orderedChildren.length - selectedChildren.length;
2258
- const childLines = [];
2316
+ const childBlocks = [];
2259
2317
  for (let i = 0; i < selectedChildren.length; i++) {
2260
2318
  const childResult = walk(selectedChildren[i], depth, currentPath);
2261
- if (childResult) childLines.push(childResult);
2319
+ if (childResult) childBlocks.push(childResult);
2262
2320
  }
2263
- if (omittedChildren > 0) childLines.push(`${" ".repeat(depth)}... (${omittedChildren} children omitted)`);
2264
- return childLines.join("\n");
2321
+ if (childBlocks.length === 0 && omittedChildren <= 0) return "";
2322
+ if (!(childBlocks.length >= 2 || omittedChildren > 0)) return childBlocks.join("\n");
2323
+ const groupLines = [`${" ".repeat(depth)}([${tag}] collapsed-group`];
2324
+ for (const block of childBlocks) groupLines.push(indentMultiline(block, 1));
2325
+ if (omittedChildren > 0) groupLines.push(`${" ".repeat(depth + 1)}... (${omittedChildren} children omitted)`);
2326
+ groupLines.push(`${" ".repeat(depth)})`);
2327
+ return groupLines.join("\n");
2265
2328
  }
2266
2329
  let line = `${indent}[${tag}]`;
2267
2330
  if (directText) line += ` "${directText.slice(0, maxTextLength)}"`;
@@ -2312,6 +2375,13 @@ function queryAllElements(selector, limit = 20) {
2312
2375
  return `选择器语法错误: ${selector}`;
2313
2376
  }
2314
2377
  }
2378
+ /**
2379
+ * 多行文本块缩进(中)/ Indent each line of a multiline block (EN).
2380
+ */
2381
+ function indentMultiline(block, indentLevel) {
2382
+ const prefix = " ".repeat(indentLevel);
2383
+ return block.split("\n").map((line) => `${prefix}${line}`).join("\n");
2384
+ }
2315
2385
  function createPageInfoTool() {
2316
2386
  return {
2317
2387
  name: "page_info",