agentpage 0.0.29 → 0.0.31
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 +9 -5
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +65 -7
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -380,11 +380,11 @@ agent.clearHistory(); // 手动清空历史
|
|
|
380
380
|
|
|
381
381
|
| 参数 | 类型 | 默认值 | 说明 |
|
|
382
382
|
| --- | --- | --- | --- |
|
|
383
|
-
| `maxDepth` | `number` | `8`(chat 首轮)/ `
|
|
383
|
+
| `maxDepth` | `number` | `8`(chat 首轮)/ `7`(page_info.snapshot) | DOM 最大遍历深度,超过该深度的子树不会输出 |
|
|
384
384
|
| `viewportOnly` | `boolean` | `false`(chat 首轮)/ `true`(page_info.snapshot) | 是否仅保留与视口相交的元素 |
|
|
385
385
|
| `pruneLayout` | `boolean` | `true` | 是否折叠无意义纯布局容器(div/span/section 等) |
|
|
386
|
-
| `maxNodes` | `number` | `500`(chat 首轮)/ `
|
|
387
|
-
| `maxChildren` | `number` | `30`(chat 首轮)/ `
|
|
386
|
+
| `maxNodes` | `number` | `500`(chat 首轮)/ `280`(page_info.snapshot) | 快照最大节点输出数量,超出后停止遍历并追加截断提示 |
|
|
387
|
+
| `maxChildren` | `number` | `30`(chat 首轮)/ `32`(page_info.snapshot) | 每个父节点最多保留的子元素数量 |
|
|
388
388
|
| `maxTextLength` | `number` | `40` | 单节点文本截断长度(字符数) |
|
|
389
389
|
| `refStore` | `RefStore` | 自动创建 | hash ID 映射表(一般无需手动传入,WebAgent 自动管理) |
|
|
390
390
|
|
|
@@ -400,7 +400,7 @@ agent.clearHistory(); // 手动清空历史
|
|
|
400
400
|
|
|
401
401
|
- `page_info.snapshot` 会为命中事件追踪的元素输出 `listeners="click,input,..."`
|
|
402
402
|
- 交互优先级识别会把运行时监听事件纳入判断(不仅依赖 `onclick/role` 等静态属性)
|
|
403
|
-
-
|
|
403
|
+
- 智能剪枝会优先保留“自身有事件绑定”的容器,并在中浅层对子树事件做受预算探测,尽量保留可操作链路
|
|
404
404
|
|
|
405
405
|
边界说明:
|
|
406
406
|
|
|
@@ -442,6 +442,10 @@ agent.clearHistory(); // 手动清空历史
|
|
|
442
442
|
|
|
443
443
|
折叠规则:
|
|
444
444
|
- 没有 `id`、没有语义标签(如 `main`/`nav`)、没有交互属性、没有直接文本的纯布局div/span
|
|
445
|
+
- 浅层布局主干默认保留(避免页面主结构被过早折叠)
|
|
446
|
+
- 自身有事件绑定(`on*` 或追踪到 listeners)的容器优先保留
|
|
447
|
+
- 中浅层子树出现事件绑定时,在预算范围内尽量保留相关容器
|
|
448
|
+
- `svg` 装饰节点与 `__SVG_SPRITE_NODE__` sprite 容器会被过滤,避免噪音吞掉节点预算
|
|
445
449
|
- 子节点直接**提升**输出到父级位置
|
|
446
450
|
- 当同一折叠容器提升出多个相邻节点时,用 `collapsed-group` 括号块标记它们的来源关联
|
|
447
451
|
|
|
@@ -465,7 +469,7 @@ agent.clearHistory(); // 手动清空历史
|
|
|
465
469
|
| --- | --- | --- | --- | --- | --- |
|
|
466
470
|
| `chat()` 首轮 | 8 | false | 500 | 30 | 优先完整性,提供充足的页面上下文 |
|
|
467
471
|
| `page_info.snapshot`(loop 内) | 8 | false | 500 | 30 | 与首轮对齐,保证一致性 |
|
|
468
|
-
| `page_info.snapshot`(手动调用) |
|
|
472
|
+
| `page_info.snapshot`(手动调用) | 7 | true | 280 | 32 | 略放宽额度,兼顾结构完整与可操作性 |
|
|
469
473
|
|
|
470
474
|
---
|
|
471
475
|
|
package/dist/index.d.mts.map
CHANGED
|
@@ -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/index.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":";;;;;;KA0BY,cAAA;EAuBV,qCArBA,OAAA,WAAkB,MAAA,mBAqBR;EAnBV,OAAA,GAAU,MAAA;AAAA;;;;;;ACfZ;;;KD0BY,cAAA;ECxBV,4CD0BA,IAAA,UCtBA;EDwBA,WAAA,UCxBK;ED0BL,MAAA,EAAQ,OAAA,ECpBW;EDsBnB,OAAA,GAAU,MAAA,EAAQ,MAAA,sBAA4B,OAAA,CAAQ,cAAA;AAAA;;;;KClC5C,UAAA;ED0BA,0BCxBV,EAAA;EAEA,IAAA,UD8BkB;EC5BlB,KAAA;AAAA;;KAMU,SAAA;EACV,IAAA,4CDiBA;ECfA,OAAA,WAAkB,KAAA;IAAQ,UAAA;IAAoB,MAAA;EAAA,IDmBpC;ECjBV,SAAA,GAAY,UAAA;AAAA;;KAMF,cAAA;iBAEV,IAAA;EAEA,SAAA,GAAY,UAAA,IA3BQ;EA6BpB,KAAA;IAAU,WAAA;IAAqB,YAAA;EAAA;AAAA;;;AAjBjC;;;KA2BY,QAAA;EACV,IAAA,CAAK,MAAA;IACH,YAAA;IACA,QAAA,EAAU,SAAA;IACV,KAAA,GAAQ,cAAA;EAAA,IACN,OAAA,CAAQ,cAAA;AAAA;;;;KCjDF,yBAAA;EFoBA,2BElBV,OAAA,YFkBgB;EEhBhB,SAAA,WF2BwB;EEzBxB,OAAA,WF+BQ;EE7BR,gBAAA;AAAA;AAAA,KAGU,gBAAA;EACV,UAAA;EACA,cAAA;EACA,mBAAA;EACA,eAAA;EACA,eAAA;EACA,aAAA;EACA,uBAAA;EACA,iBAAA;EACA,kBAAA;EACA,eAAA;EACA,eAAA;EACA,WAAA;EACA,YAAA;AAAA;;KAMU,kBAAA;EDzBA,mBC2BV,MAAA,IAAU,IAAA;EAEV,UAAA,IAAc,IAAA,UAAc,KAAA,oBD3B5B;EC6BA,YAAA,IAAgB,IAAA,UAAc,MAAA,EAAQ,cAAA,WDzBtC;EC2BA,OAAA,IAAW,KAAA;ED3BN;AAMP;;;;;;;EC8BE,wBAAA,IAA4B,MAAA,oBD3BkB;EC6B9C,SAAA,IAAa,OAAA,EAAS,gBAAA;AAAA;AAAA,KA4BZ,eAAA;EDhCV,iBCkCA,KAAA,UDhCE;ECkCF,SAAA,EAAW,KAAA;IAAQ,IAAA;IAAc,KAAA;IAAgB,MAAA,EAAQ,cAAA;EAAA,IDhC7C;ECkCZ,QAAA,EAAU,SAAA,IDlCgB;ECoC1B,OAAA,EAAS,gBAAA;AAAA;;;;;;AFrEX;;;;;;;;;;AAeA;;;;;;;;;;;;;;cGAa,QAAA;EAAA,QACH,GAAA;EHOsC;EAAA,QGLtC,MAAA;EHK4D;;;;cGCxD,GAAA;EFnCF;;;;;;;EE8CV,GAAA,CAAI,EAAA,EAAI,OAAA,EAAS,IAAA;EFxCZ;AAMP;;;EEkDE,GAAA,CAAI,EAAA,WAAa,OAAA;EFjDjB;EEsDA,GAAA,CAAI,EAAA;EFpDc;EEyDlB,MAAA,CAAO,EAAA;EFzDuC;;;;;AAQhD;;EE4DE,KAAA,CAAM,OAAA,GAAU,WAAA;EFxDM;EEsEtB,KAAA,CAAA;EFtEA;;;;;;;AAYF;EEsEE,KAAA,CAAM,GAAA;;MAQF,IAAA,CAAA;AAAA;;;;KC/GM,eAAA;EJKc,mBIHxB,QAAA;EJOgB;;;;;EIDhB,YAAA;EJCgB;AAWlB;;;;EINE,WAAA;EJcsD;;;;;EIRtD,QAAA,GAAW,QAAA,EJMX;EIJA,QAAA,WJMA;EIJA,WAAA,WJIU;EIFV,aAAA;EJEsD;;;;EIGtD,iBAAA;;AHrCF;;;EG0CE,kBAAA,aHxCA;EG0CA,qBAAA;AAAA;;;AHhCF;;;;;;;;;;;;;AAWA;;;;;iBG0GgB,gBAAA,CACd,IAAA,GAAM,OAAA,EACN,OAAA,GAAS,eAAA;AAAA,
|
|
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/index.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
|
@@ -2353,6 +2353,30 @@ function resolvePointerActionTarget(el) {
|
|
|
2353
2353
|
return el;
|
|
2354
2354
|
}
|
|
2355
2355
|
/**
|
|
2356
|
+
* 点击目标上卷:当命中文本/装饰子节点时,优先上卷到最近可点击祖先。
|
|
2357
|
+
*
|
|
2358
|
+
* 典型场景:
|
|
2359
|
+
* - 列表项文本本身无 click,但父级容器(如 .g-pointer)有点击语义
|
|
2360
|
+
* - 事件委托绑定在祖先,子节点点击命中不稳定
|
|
2361
|
+
*/
|
|
2362
|
+
function resolveClickableAncestorTarget(el) {
|
|
2363
|
+
const isSelfClickable = (node) => {
|
|
2364
|
+
if (node.matches("a, button, input, textarea, select, summary, [role=button], [role=link], [role=menuitem]")) return true;
|
|
2365
|
+
if (node.hasAttribute("onclick")) return true;
|
|
2366
|
+
const tabIndexAttr = node.getAttribute("tabindex");
|
|
2367
|
+
if (tabIndexAttr !== null && tabIndexAttr !== "-1") return true;
|
|
2368
|
+
if (getTrackedElementEvents(node).some((name) => name === "click" || name === "pointerdown" || name === "mousedown")) return true;
|
|
2369
|
+
return false;
|
|
2370
|
+
};
|
|
2371
|
+
if (isSelfClickable(el)) return el;
|
|
2372
|
+
let ancestor = el.parentElement;
|
|
2373
|
+
for (let depth = 0; ancestor && depth < 6; depth++, ancestor = ancestor.parentElement) {
|
|
2374
|
+
if (!isElementVisible(ancestor)) continue;
|
|
2375
|
+
if (isSelfClickable(ancestor)) return ancestor;
|
|
2376
|
+
}
|
|
2377
|
+
return el;
|
|
2378
|
+
}
|
|
2379
|
+
/**
|
|
2356
2380
|
* 当命中表单项说明 label(如 Element Plus el-form-item__label)时,
|
|
2357
2381
|
* 自动重定向到同一表单项中的首个可交互控件。
|
|
2358
2382
|
*/
|
|
@@ -2519,13 +2543,13 @@ function createDomTool() {
|
|
|
2519
2543
|
"type",
|
|
2520
2544
|
"clear"
|
|
2521
2545
|
].includes(action)) el = resolveEditableTarget(retarget(el, "follow-label"));
|
|
2522
|
-
const actionabilityTarget = action === "click" || action === "check" || action === "uncheck" ? resolvePointerActionTarget(resolveFormItemControlTarget(el)) : el;
|
|
2546
|
+
const actionabilityTarget = action === "click" || action === "check" || action === "uncheck" ? resolvePointerActionTarget(resolveClickableAncestorTarget(resolveFormItemControlTarget(el))) : el;
|
|
2523
2547
|
try {
|
|
2524
2548
|
const checkResult = ensureActionable(actionabilityTarget, action, selector, force);
|
|
2525
2549
|
if (checkResult) return checkResult;
|
|
2526
2550
|
switch (action) {
|
|
2527
2551
|
case "click": {
|
|
2528
|
-
const target = resolvePointerActionTarget(resolveFormItemControlTarget(retarget(el, force ? "none" : "button-link")));
|
|
2552
|
+
const target = resolvePointerActionTarget(resolveClickableAncestorTarget(resolveFormItemControlTarget(retarget(el, force ? "none" : "button-link"))));
|
|
2529
2553
|
const clickCount = typeof params.clickCount === "number" ? params.clickCount : 1;
|
|
2530
2554
|
if (target instanceof HTMLOptionElement) {
|
|
2531
2555
|
const parent = target.parentElement;
|
|
@@ -3053,6 +3077,7 @@ function generateSnapshot(root = document.body, options = {}) {
|
|
|
3053
3077
|
"value",
|
|
3054
3078
|
"name",
|
|
3055
3079
|
"role",
|
|
3080
|
+
"tabindex",
|
|
3056
3081
|
"aria-label",
|
|
3057
3082
|
"aria-valuenow",
|
|
3058
3083
|
"aria-valuemin",
|
|
@@ -3127,6 +3152,37 @@ function generateSnapshot(root = document.body, options = {}) {
|
|
|
3127
3152
|
if (rect.width === 0 && rect.height === 0) return false;
|
|
3128
3153
|
return true;
|
|
3129
3154
|
}
|
|
3155
|
+
/** 统一标签名键值(HTML/SVG 在不同环境可能大小写不一致)。 */
|
|
3156
|
+
function getTagKey(el) {
|
|
3157
|
+
return (el.tagName || "").toUpperCase();
|
|
3158
|
+
}
|
|
3159
|
+
/** 判断元素是否存在绑定事件(inline 或 addEventListener 追踪)。 */
|
|
3160
|
+
function hasBoundEvents(el) {
|
|
3161
|
+
if (hasTrackedElementEvents(el)) return true;
|
|
3162
|
+
for (const attr of Array.from(el.attributes)) if (attr.name.startsWith("on")) return true;
|
|
3163
|
+
return false;
|
|
3164
|
+
}
|
|
3165
|
+
/**
|
|
3166
|
+
* 判断子树内是否存在绑定事件元素。
|
|
3167
|
+
*
|
|
3168
|
+
* 说明:
|
|
3169
|
+
* - 该判定只用于“是否允许剪枝布局容器”。
|
|
3170
|
+
* - 命中扫描预算上限时保守返回 true,避免误剪导致交互目标丢失。
|
|
3171
|
+
*/
|
|
3172
|
+
function hasBoundEventsInSubtree(el, scanBudget = 180) {
|
|
3173
|
+
const stack = Array.from(el.children);
|
|
3174
|
+
let scanned = 0;
|
|
3175
|
+
while (stack.length > 0) {
|
|
3176
|
+
const current = stack.pop();
|
|
3177
|
+
if (!current) continue;
|
|
3178
|
+
if (hasBoundEvents(current)) return true;
|
|
3179
|
+
scanned += 1;
|
|
3180
|
+
if (scanned >= scanBudget) return true;
|
|
3181
|
+
const children = Array.from(current.children);
|
|
3182
|
+
for (let i = children.length - 1; i >= 0; i--) stack.push(children[i]);
|
|
3183
|
+
}
|
|
3184
|
+
return false;
|
|
3185
|
+
}
|
|
3130
3186
|
/**
|
|
3131
3187
|
* 判断元素是否为「无意义布局容器」(智能剪枝候选)。
|
|
3132
3188
|
* 满足所有条件时返回 true:
|
|
@@ -3137,12 +3193,12 @@ function generateSnapshot(root = document.body, options = {}) {
|
|
|
3137
3193
|
*/
|
|
3138
3194
|
function isEmptyLayoutContainer(el, directText) {
|
|
3139
3195
|
if (!pruneLayout) return false;
|
|
3140
|
-
if (!LAYOUT_TAGS.has(el
|
|
3196
|
+
if (!LAYOUT_TAGS.has(getTagKey(el))) return false;
|
|
3141
3197
|
if (el.getAttribute("id")) return false;
|
|
3142
3198
|
if (el.getAttribute("role") || el.getAttribute("aria-label")) return false;
|
|
3143
|
-
|
|
3144
|
-
if (hasTrackedElementEvents(el)) return false;
|
|
3199
|
+
if (hasBoundEvents(el)) return false;
|
|
3145
3200
|
if (directText) return false;
|
|
3201
|
+
if (hasBoundEventsInSubtree(el)) return false;
|
|
3146
3202
|
return true;
|
|
3147
3203
|
}
|
|
3148
3204
|
function hasInteractiveTrackedEvents(el) {
|
|
@@ -3151,7 +3207,7 @@ function generateSnapshot(root = document.body, options = {}) {
|
|
|
3151
3207
|
return trackedEvents.some((eventName) => INTERACTIVE_EVENTS.has(eventName));
|
|
3152
3208
|
}
|
|
3153
3209
|
function isInteractiveElement(el) {
|
|
3154
|
-
if (INTERACTIVE_TAGS.has(el
|
|
3210
|
+
if (INTERACTIVE_TAGS.has(getTagKey(el))) return true;
|
|
3155
3211
|
if (el.hasAttribute("onclick")) return true;
|
|
3156
3212
|
if (el.hasAttribute("role")) return true;
|
|
3157
3213
|
if (el.hasAttribute("tabindex")) return true;
|
|
@@ -3185,7 +3241,9 @@ function generateSnapshot(root = document.body, options = {}) {
|
|
|
3185
3241
|
return "";
|
|
3186
3242
|
}
|
|
3187
3243
|
if (depth > maxDepth) return "";
|
|
3188
|
-
|
|
3244
|
+
const tagKey = getTagKey(el);
|
|
3245
|
+
if (SKIP_TAGS.has(tagKey)) return "";
|
|
3246
|
+
if (el.getAttribute("id") === "__SVG_SPRITE_NODE__") return "";
|
|
3189
3247
|
if (el.hasAttribute("data-autopilot-ignore")) return "";
|
|
3190
3248
|
const style = window.getComputedStyle(el);
|
|
3191
3249
|
if (style.display === "none" || style.visibility === "hidden") return "";
|