agentpage 0.0.52 → 0.0.54
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/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +210 -13
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
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/ui/panel.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/ui/panel.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":";;;;;;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,KAAA,CAAA;EFzD8C;;;;;AAQhD;;;EE6DE,KAAA,CAAM,GAAA;EF3DN;EAAA,IEmEI,IAAA,CAAA;AAAA;;;;KCtFM,eAAA;EJKc,oBIHxB,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;EHtCA;;;AAMF;;EGsCE,cAAA;EHjCsB;;;;;;;EGyCtB,eAAA;AAAA;;AHnCF;;;;;;;;;;;;AAgBA;;;;;;;iBG6HgB,gBAAA,CACd,IAAA,GAAM,OAAA,EACN,OAAA,GAAS,eAAA;AAAA,iBAilBK,kBAAA,CAAA,GAAsB,cAAA;;;;KCnvB1B,YAAA;kCAEV,SAAA,GAAY,WAAA,ELKY;EKHxB,KAAA,YLOgB;EKLhB,UAAA,YLGkB;EKDlB,WAAA,WLGU;EKDV,QAAA,YLCgB;EKChB,KAAA,WLUwB;EKRxB,WAAA,WLcQ;EKZR,QAAA,WLcsD;EKZtD,SAAA;AAAA;;KAIG,WAAA;;KAGA,WAAA;;;;;;;;;;;;AJ7BL;;;cI6CqB,KAAA;EAAA,QACX,SAAA;EAAA,QACA,UAAA;EAAA,QACA,WAAA;EAAA,QACA,KAAA;EAAA,QACA,WAAA;EAAA,QACA,QAAA;EAAA,QACA,SAAA;EAAA,QAGA,IAAA;EAAA,QACA,GAAA;EAAA,QACA,IAAA;EAAA,QACA,OAAA;EAAA,QACA,UAAA;EAAA,QACA,OAAA;EAAA,QACA,OAAA;EAAA,QACA,SAAA;EAAA,QACA,UAAA;EAAA,QACA,gBAAA;EAAA,QACA,OAAA;EAAA,QAGA,WAAA;EAAA,QACA,WAAA;EAAA,QAEA,OAAA;EAAA,QACA,QAAA;EAAA,QACA,MAAA;EJ9CR;EIiDA,MAAA,IAAU,IAAA,aAAiB,OAAA;EJ/C3B;EIiDA,MAAA;cAEY,OAAA,GAAS,YAAA;EJnDsB;EIsE3C,KAAA,CAAA;EJ5DU;EI2EV,OAAA,CAAA;;EAmBA,IAAA,CAAA;EJ1FU;EIqGV,IAAA,CAAA;EJpGI;EI2GJ,MAAA,CAAA;EJ3GW;EIiHX,UAAA,CAAA;EJpHE;EIyHF,SAAA,CAAA;EJxHY;EI6HZ,UAAA,CAAW,IAAA,EAAM,WAAA,EAAa,IAAA;EJ5HpB;EI4IV,aAAA,CAAA;EJ3II;EIkJJ,SAAA,CAAU,MAAA,EAAQ,WAAA,EAAa,IAAA;EJlJL;EI4K1B,QAAA,CAAA;;EAKA,QAAA,CAAA;;EAKA,UAAA,CAAA;EHvOmC;EGsPnC,YAAA,CAAA;EHtPmC;;;;EAAA,QGiQ3B,YAAA;EAAA,QAYA,YAAA;EAAA,QAOA,SAAA;EAAA,QA6EA,UAAA;EHtVkB;;;;EAAA,QGwYlB,mBAAA;EHrYR;;;;EAAA,QGuaQ,WAAA;EHlaR;;;EAAA,QG0fQ,aAAA;EAAA,QA4BA,UAAA;EAAA,QAiBA,gBAAA;EAAA,QAaA,SAAA;EAAA,QAUA,cAAA;EAAA,QAWA,UAAA;AAAA;;;iBCiLM,aAAA,CAAA,GAAiB,cAAA;;;iBC7vBjB,kBAAA,CAAA,GAAsB,cAAA;;;iBCgMtB,cAAA,CAAA,GAAkB,cAAA;;;iBCxJlB,kBAAA,CAAA,GAAsB,cAAA;;;;;;ATxCtC;;;;;;;;;;AAeA;;;;;;;;;;;;;;KUXY,eAAA;EACV,IAAA;EACA,QAAA;EACA,MAAA,EAAQ,MAAA;EACR,MAAA;AAAA;;KAIU,gBAAA;EACV,IAAA;EACA,MAAA;EACA,MAAA;IACE,OAAA,WAAkB,MAAA;IAClB,OAAA,GAAU,MAAA;EAAA;AAAA;;;;AThBd;;;;;iBS8BgB,mBAAA,CAAA,IAEZ,QAAA,UACA,MAAA,EAAQ,MAAA,sBACP,OAAA;EAAU,OAAA,WAAkB,MAAA;EAAyB,OAAA,GAAU,MAAA;AAAA;;KAgCxD,eAAA,GAAkB,GAAA,UAE3B,MAAA,EAAQ,MAAA,sBAA4B,OAAA;EACnC,OAAA,WAAkB,MAAA;EAClB,OAAA,GAAU,MAAA;AAAA;;;;;;;;;iBAYE,mBAAA,CAAoB,SAAA,EAAW,eAAA;;;;KCrDnC,iBAAA,GAAoB,kBAAA;EVzCpB,kBU2CV,UAAA,IAAc,QAAA;AAAA;AAAA,KAKJ,eAAA;EV9CV;;;;;AAUF;;;;;;EUgDE,MAAA,GAAS,QAAA,EV7CiB;EU+C1B,KAAA,WV7CA;EU+CA,QAAA,WV/CsB;EUiDtB,KAAA,WV3CU;EU6CV,OAAA;EAEA,MAAA,YV7CA;EU+CA,gBAAA,WV7CY;EU+CZ,MAAA;EV7CU;;;;AAUZ;EUyCE,YAAA,YAAwB,MAAA;EAExB,SAAA,WVvCU;EUyCV,MAAA,YVxCI;EU0CJ,YAAA,YV1CW;EU4CX,eAAA,GAAkB,eAAA,EV/ChB;EUiDF,kBAAA,GAAqB,yBAAA;EVhDT;;;;;;EUuDZ,KAAA,aAAkB,YAAA;AAAA;AAAA,cAKP,QAAA;;0BAEa,yBAAA;ET7Gd;EAAA,wBS+Gc,kBAAA;;UAGhB,MAAA;EAAA,QACA,KAAA;EAAA,QACA,QAAA;EAAA,QACA,KAAA;EAAA,QACA,OAAA;EAAA,QACA,MAAA;EAAA,QACA,gBAAA;EAAA,QACA,MAAA;EAAA,QACA,SAAA;;UAEA,oBAAA;EThHR;EAAA,QSkHQ,kBAAA;EThHR;EAAA,QSmHQ,MAAA;ETjHR;EAAA,QSmHQ,OAAA;ETjHR;EAAA,QSmHQ,YAAA;ETjHR;EAAA,QSmHQ,eAAA;ETjHR;EAAA,QSmHQ,kBAAA;ETjHR;EAAA,QSoHQ,QAAA;ETpHI;ESuHZ,KAAA,EAAO,KAAA;ETjHqB;ESoH5B,SAAA,EAAW,iBAAA;cAEC,OAAA,EAAS,eAAA;ETpHrB;ESoJA,aAAA,CAAA;ETlJA;ES+JA,YAAA,CAAa,IAAA,EAAM,cAAA;ET/JS;;;;;ESwK5B,UAAA,CAAW,IAAA;ETpKA;ES0KX,OAAA,CAAQ,IAAA;ETjKoB;ESsK5B,YAAA,CAAA;ETpKsB;;;;ES4KtB,gBAAA,CAAA;EThJyB;ES4JzB,QAAA,CAAA,GAAY,cAAA;ETxJ6C;ES+JzD,QAAA,CAAS,KAAA;ET7JC;;;;;;ESuKV,SAAA,CAAU,MAAA,EAAQ,QAAA;ETzKC;ES8KnB,WAAA,CAAY,QAAA;ET9KqC;ESmLjD,QAAA,CAAS,KAAA;ETjLT;ESsLA,SAAA,CAAU,OAAA;ETpLV;ESyLA,SAAA,CAAA;ETzLyB;ES8LzB,mBAAA,CAAoB,SAAA;;EAKpB,mBAAA,CAAA;;EAKA,SAAA,CAAU,OAAA;ER9PS;;;;;EQuQnB,eAAA,CAAgB,MAAA;EAChB,eAAA,CAAgB,GAAA,UAAa,MAAA;ERpP7B;EQmQA,gBAAA,CAAiB,OAAA,EAAS,MAAA;ERnQtB;EQ0QJ,kBAAA,CAAmB,GAAA;ER1PnB;EQ+PA,oBAAA,CAAqB,GAAA;ER/PJ;EQwQjB,gBAAA,CAAA,GAAoB,MAAA;ERnQhB;EQwQJ,kBAAA,CAAA;ERvPA;EQ4PA,SAAA,CAAU,OAAA;ERpPN;EQ0PJ,SAAA,CAAA;ER1PQ;EQ+PR,eAAA,CAAgB,OAAA;;EAKhB,eAAA,CAAA;EP1VU;EO+VV,kBAAA,CAAmB,OAAA,EAAS,eAAA;;EAK5B,kBAAA,CAAA,GAAsB,eAAA;EPlWtB;EOuWA,YAAA,CAAA;EP3VA;;;;EOqWA,WAAA,CAAY,OAAA,GAAS,YAAA,GAAoB,KAAA;EPzVzC;;;EOmWA,YAAA,CAAA;EPjVA;;;;AAkHF;;EAlHE,QO6VQ,SAAA;EPzOgB;;;;;;;AAilB1B;;EO9SQ,IAAA,CAAK,OAAA,WAAkB,OAAA,CAAQ,eAAA;EP8SD;;;;;EAAA,QOvN5B,mBAAA;AAAA"}
|
package/dist/index.mjs
CHANGED
|
@@ -111,6 +111,75 @@ function _djb2(str) {
|
|
|
111
111
|
return (hash >>> 0).toString(36);
|
|
112
112
|
}
|
|
113
113
|
/**
|
|
114
|
+
* 从快照文本中查找指定 selector 附近的可点击元素。
|
|
115
|
+
*
|
|
116
|
+
* 当点击某个元素无效果时,框架需要推荐具体的替代目标而非泛泛的建议。
|
|
117
|
+
* 此函数在快照中定位目标 selector 所在行,然后在上下 windowSize 行内
|
|
118
|
+
* 扫描带有点击信号的元素,返回按距离排序的推荐列表。
|
|
119
|
+
*
|
|
120
|
+
* 点击信号判定:
|
|
121
|
+
* - listeners 属性含 clk / pdn / mdn
|
|
122
|
+
* - 有 onclick 属性
|
|
123
|
+
* - 标签为 [a] 或 [button]
|
|
124
|
+
* - role="button" 或 role="link"
|
|
125
|
+
*
|
|
126
|
+
* 返回:描述字符串数组(`#hashID ([tag] "text" listeners="...")`),最多 5 个。
|
|
127
|
+
*
|
|
128
|
+
* 用途:
|
|
129
|
+
* - `INEFFECTIVE_CLICK_BLOCKED` 拦截消息中附带推荐
|
|
130
|
+
* - "Snapshot unchanged" 提示中附带推荐
|
|
131
|
+
* - 交替循环检测提示中附带推荐
|
|
132
|
+
*/
|
|
133
|
+
function findNearbyClickTargets(snapshot, selector, excludeSelectors, windowSize = 15) {
|
|
134
|
+
if (!snapshot || !selector) return [];
|
|
135
|
+
const lines = snapshot.split("\n");
|
|
136
|
+
const selectorRef = selector.startsWith("#") ? selector : `#${selector}`;
|
|
137
|
+
let targetLineIdx = -1;
|
|
138
|
+
for (let i = 0; i < lines.length; i++) if (lines[i].includes(selectorRef)) {
|
|
139
|
+
targetLineIdx = i;
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
if (targetLineIdx === -1) return [];
|
|
143
|
+
const start = Math.max(0, targetLineIdx - windowSize);
|
|
144
|
+
const end = Math.min(lines.length - 1, targetLineIdx + windowSize);
|
|
145
|
+
const CLICK_SIGNAL_RE = /(?:listeners="[^"]*\b(?:clk|pdn|mdn)\b[^"]*")|(?:\bonclick\b)|(?:\[a\])|(?:\[button\])|(?:role="(?:button|link)")/i;
|
|
146
|
+
const HASH_RE = /#([a-z0-9]{4,})\b/gi;
|
|
147
|
+
const TAG_RE = /\[([a-z0-9-]+)\]/i;
|
|
148
|
+
const TEXT_RE = /"([^"]{1,40})"/;
|
|
149
|
+
const candidates = [];
|
|
150
|
+
for (let i = start; i <= end; i++) {
|
|
151
|
+
if (i === targetLineIdx) continue;
|
|
152
|
+
const line = lines[i];
|
|
153
|
+
if (!CLICK_SIGNAL_RE.test(line)) continue;
|
|
154
|
+
HASH_RE.lastIndex = 0;
|
|
155
|
+
let match;
|
|
156
|
+
while ((match = HASH_RE.exec(line)) !== null) {
|
|
157
|
+
const ref = `#${match[1]}`;
|
|
158
|
+
if (ref === selectorRef) continue;
|
|
159
|
+
if (excludeSelectors?.has(ref)) continue;
|
|
160
|
+
const tag = TAG_RE.exec(line)?.[1] ?? "?";
|
|
161
|
+
const text = TEXT_RE.exec(line)?.[1] ?? "";
|
|
162
|
+
const listeners = line.match(/listeners="([^"]*)"/)?.[1] ?? "";
|
|
163
|
+
const brief = text ? `[${tag}] "${text}" listeners="${listeners}"` : `[${tag}] listeners="${listeners}"`;
|
|
164
|
+
candidates.push({
|
|
165
|
+
ref,
|
|
166
|
+
distance: Math.abs(i - targetLineIdx),
|
|
167
|
+
brief
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
candidates.sort((a, b) => a.distance - b.distance);
|
|
172
|
+
const seen = /* @__PURE__ */ new Set();
|
|
173
|
+
const result = [];
|
|
174
|
+
for (const c of candidates) {
|
|
175
|
+
if (seen.has(c.ref)) continue;
|
|
176
|
+
seen.add(c.ref);
|
|
177
|
+
result.push(`${c.ref} (${c.brief})`);
|
|
178
|
+
if (result.length >= 5) break;
|
|
179
|
+
}
|
|
180
|
+
return result;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
114
183
|
* 构建任务数组。
|
|
115
184
|
*
|
|
116
185
|
* 作用:把一轮工具调用规整成稳定字符串数组,
|
|
@@ -753,23 +822,27 @@ function detectIdleLoop(toolCalls, consecutiveReadOnlyRounds) {
|
|
|
753
822
|
*
|
|
754
823
|
* 集合的维护由 index.ts 负责:
|
|
755
824
|
* - 轮次结束且快照未变:将本轮 click 的 selector 加入集合
|
|
756
|
-
* -
|
|
825
|
+
* - 快照变化:仅移除本轮点击的 selector,保留其他无效记录
|
|
826
|
+
*
|
|
827
|
+
* 增强:当拦截时,自动从快照中查找附近可点击元素并作为具体推荐注入响应,
|
|
828
|
+
* 让模型有明确的替代目标而非盲猜。
|
|
757
829
|
*/
|
|
758
|
-
function checkIneffectiveClickRepeat(toolName, toolInput, ineffectiveClickSelectors) {
|
|
830
|
+
function checkIneffectiveClickRepeat(toolName, toolInput, ineffectiveClickSelectors, latestSnapshot) {
|
|
759
831
|
if (toolName !== "dom") return null;
|
|
760
832
|
if (getToolAction(toolInput) !== "click") return null;
|
|
761
833
|
const selector = toolInput && typeof toolInput === "object" ? toolInput.selector : void 0;
|
|
762
834
|
if (typeof selector !== "string" || !selector) return null;
|
|
763
835
|
if (!ineffectiveClickSelectors.has(selector)) return null;
|
|
836
|
+
const nearby = latestSnapshot ? findNearbyClickTargets(latestSnapshot, selector, ineffectiveClickSelectors) : [];
|
|
837
|
+
const lines = [`Click on ${selector} was BLOCKED — this target was already clicked in a previous round with NO visible effect on the page.`, "You MUST try a DIFFERENT element."];
|
|
838
|
+
if (nearby.length > 0) {
|
|
839
|
+
lines.push("", "Nearby clickable alternatives (try these first, sorted by proximity):");
|
|
840
|
+
for (const item of nearby) lines.push(` → ${item}`);
|
|
841
|
+
lines.push("");
|
|
842
|
+
}
|
|
843
|
+
lines.push("Other suggestions:", "1) Look INSIDE the clicked container for an <a>, <button>, or child with clk/pdn/mdn listener", "2) Try a parent or sibling element with stronger click signal", "3) Use evaluate to inspect or trigger navigation programmatically", "4) Try a completely different approach (search, sidebar, direct URL navigation)");
|
|
764
844
|
return {
|
|
765
|
-
content:
|
|
766
|
-
`Click on ${selector} was BLOCKED — this target was already clicked in a previous round with NO visible effect on the page.`,
|
|
767
|
-
"You MUST try a DIFFERENT element. Suggestions:",
|
|
768
|
-
"1) Look INSIDE the clicked container for an <a>, <button>, or child with clk/pdn/mdn listener",
|
|
769
|
-
"2) Try a parent or sibling element with stronger click signal",
|
|
770
|
-
"3) Use evaluate to inspect or trigger navigation programmatically",
|
|
771
|
-
"4) Try a completely different approach (search, sidebar, direct URL navigation)"
|
|
772
|
-
].join("\n"),
|
|
845
|
+
content: lines.join("\n"),
|
|
773
846
|
details: {
|
|
774
847
|
error: true,
|
|
775
848
|
code: "INEFFECTIVE_CLICK_BLOCKED",
|
|
@@ -881,6 +954,7 @@ async function executeAgentLoop(params) {
|
|
|
881
954
|
let recoveryCount = 0;
|
|
882
955
|
let redundantInterceptCount = 0;
|
|
883
956
|
const ineffectiveClickSelectors = /* @__PURE__ */ new Set();
|
|
957
|
+
const recentRoundClickTargets = [];
|
|
884
958
|
let pendingNotFoundRetry;
|
|
885
959
|
let snapshotReadCount = 0;
|
|
886
960
|
let snapshotSizeTotal = 0;
|
|
@@ -1078,7 +1152,7 @@ async function executeAgentLoop(params) {
|
|
|
1078
1152
|
callbacks?.onToolResult?.(tc.name, redundant);
|
|
1079
1153
|
continue;
|
|
1080
1154
|
}
|
|
1081
|
-
const ineffective = checkIneffectiveClickRepeat(tc.name, tc.input, ineffectiveClickSelectors);
|
|
1155
|
+
const ineffective = checkIneffectiveClickRepeat(tc.name, tc.input, ineffectiveClickSelectors, pageContext.latestSnapshot);
|
|
1082
1156
|
if (ineffective) {
|
|
1083
1157
|
appendToolTrace(round, tc.name, tc.input, ineffective);
|
|
1084
1158
|
redundantInterceptCount += 1;
|
|
@@ -1155,17 +1229,69 @@ async function executeAgentLoop(params) {
|
|
|
1155
1229
|
if (roundHasPotentialDomMutation) {
|
|
1156
1230
|
const roundEndFingerprint = computeSnapshotFingerprint(pageContext.latestSnapshot || "");
|
|
1157
1231
|
if (roundEndFingerprint === roundStartFingerprint && roundStartFingerprint !== "") {
|
|
1232
|
+
const nearbyHintLines = [];
|
|
1233
|
+
for (const sel of roundClickSelectors) {
|
|
1234
|
+
const nearby = findNearbyClickTargets(pageContext.latestSnapshot || "", sel, ineffectiveClickSelectors);
|
|
1235
|
+
if (nearby.length > 0) {
|
|
1236
|
+
nearbyHintLines.push(`Nearby clickable alternatives for ${sel}:`);
|
|
1237
|
+
for (const item of nearby) nearbyHintLines.push(` → ${item}`);
|
|
1238
|
+
}
|
|
1239
|
+
}
|
|
1158
1240
|
const unchangedHint = [
|
|
1159
1241
|
"Snapshot unchanged after action:",
|
|
1160
1242
|
"- The page snapshot is IDENTICAL before and after your action(s) this round.",
|
|
1161
1243
|
"- Your click/action had NO visible effect on the page. Do NOT repeat it.",
|
|
1162
|
-
|
|
1244
|
+
...nearbyHintLines.length > 0 ? [
|
|
1245
|
+
"",
|
|
1246
|
+
"Try these nearby elements instead (sorted by proximity):",
|
|
1247
|
+
...nearbyHintLines,
|
|
1248
|
+
""
|
|
1249
|
+
] : [],
|
|
1250
|
+
"- If no suggestion above fits, look INSIDE the target for <a>/<button>/child with clk listener, or try a parent/sibling with stronger signal, or use a completely different approach."
|
|
1163
1251
|
].join("\n");
|
|
1164
1252
|
protocolViolationHint = protocolViolationHint ? protocolViolationHint + "\n\n" + unchangedHint : unchangedHint;
|
|
1165
1253
|
for (const sel of roundClickSelectors) ineffectiveClickSelectors.add(sel);
|
|
1166
1254
|
} else if (roundEndFingerprint !== roundStartFingerprint) {
|
|
1167
1255
|
consecutiveNoProtocolRounds = 0;
|
|
1168
|
-
ineffectiveClickSelectors.
|
|
1256
|
+
for (const sel of roundClickSelectors) ineffectiveClickSelectors.delete(sel);
|
|
1257
|
+
}
|
|
1258
|
+
}
|
|
1259
|
+
if (roundClickSelectors.length > 0) {
|
|
1260
|
+
recentRoundClickTargets.push([...roundClickSelectors]);
|
|
1261
|
+
while (recentRoundClickTargets.length > 6) recentRoundClickTargets.shift();
|
|
1262
|
+
}
|
|
1263
|
+
if (recentRoundClickTargets.length >= 4) {
|
|
1264
|
+
const recentWindow = recentRoundClickTargets.slice(-4);
|
|
1265
|
+
const allTargets = recentWindow.flat();
|
|
1266
|
+
const uniqueTargets = new Set(allTargets);
|
|
1267
|
+
if (uniqueTargets.size <= 2 && allTargets.length >= 4) {
|
|
1268
|
+
const cycleNearbyLines = [];
|
|
1269
|
+
for (const sel of uniqueTargets) {
|
|
1270
|
+
const nearby = findNearbyClickTargets(pageContext.latestSnapshot || "", sel, new Set([...ineffectiveClickSelectors, ...uniqueTargets]));
|
|
1271
|
+
if (nearby.length > 0) {
|
|
1272
|
+
cycleNearbyLines.push(`Alternatives near ${sel}:`);
|
|
1273
|
+
for (const item of nearby) cycleNearbyLines.push(` → ${item}`);
|
|
1274
|
+
}
|
|
1275
|
+
}
|
|
1276
|
+
const cycleHint = [
|
|
1277
|
+
"Click target cycling detected:",
|
|
1278
|
+
`- You have been alternating between the same ${uniqueTargets.size} target(s) for ${recentWindow.length}+ rounds: ${[...uniqueTargets].join(", ")}`,
|
|
1279
|
+
"- NONE of these clicks achieved navigation or meaningful page change.",
|
|
1280
|
+
...cycleNearbyLines.length > 0 ? [
|
|
1281
|
+
"",
|
|
1282
|
+
"Try these nearby clickable alternatives instead:",
|
|
1283
|
+
...cycleNearbyLines,
|
|
1284
|
+
""
|
|
1285
|
+
] : [],
|
|
1286
|
+
"You MUST abandon ALL these targets. If no suggestion above fits, try:",
|
|
1287
|
+
" 1) Look INSIDE the clicked container for <a>, <button>, or child with clk/pdn/mdn listener",
|
|
1288
|
+
" 2) Navigate via URL: use navigate.goto to go to the target page directly",
|
|
1289
|
+
" 3) Use evaluate to inspect the page and find the real navigation link",
|
|
1290
|
+
" 4) Use a search/filter/sidebar navigation approach instead"
|
|
1291
|
+
].join("\n");
|
|
1292
|
+
protocolViolationHint = protocolViolationHint ? protocolViolationHint + "\n\n" + cycleHint : cycleHint;
|
|
1293
|
+
for (const sel of uniqueTargets) ineffectiveClickSelectors.add(sel);
|
|
1294
|
+
recentRoundClickTargets.length = 0;
|
|
1169
1295
|
}
|
|
1170
1296
|
}
|
|
1171
1297
|
if (consecutiveNoProtocolRounds >= 5) {
|
|
@@ -2537,6 +2663,35 @@ const FILL_RELEVANT_EVENTS = new Set([
|
|
|
2537
2663
|
"mousedown",
|
|
2538
2664
|
"pointerdown"
|
|
2539
2665
|
]);
|
|
2666
|
+
/** 仅含焦点类事件的集合——只绑定这些事件的元素不应作为 click 目标 */
|
|
2667
|
+
const FOCUS_ONLY_EVENTS = new Set([
|
|
2668
|
+
"blur",
|
|
2669
|
+
"focus",
|
|
2670
|
+
"focusin",
|
|
2671
|
+
"focusout"
|
|
2672
|
+
]);
|
|
2673
|
+
/** 点击信号事件集合 */
|
|
2674
|
+
const CLICK_SIGNAL_EVENTS = new Set([
|
|
2675
|
+
"click",
|
|
2676
|
+
"mousedown",
|
|
2677
|
+
"pointerdown",
|
|
2678
|
+
"mouseup",
|
|
2679
|
+
"pointerup"
|
|
2680
|
+
]);
|
|
2681
|
+
/** 原生可被点击的 ARIA role */
|
|
2682
|
+
const CLICKABLE_ROLES = new Set([
|
|
2683
|
+
"button",
|
|
2684
|
+
"link",
|
|
2685
|
+
"tab",
|
|
2686
|
+
"menuitem",
|
|
2687
|
+
"menuitemcheckbox",
|
|
2688
|
+
"menuitemradio",
|
|
2689
|
+
"option",
|
|
2690
|
+
"checkbox",
|
|
2691
|
+
"radio",
|
|
2692
|
+
"switch",
|
|
2693
|
+
"treeitem"
|
|
2694
|
+
]);
|
|
2540
2695
|
let activeRefStore;
|
|
2541
2696
|
function setActiveRefStore(store) {
|
|
2542
2697
|
activeRefStore = store;
|
|
@@ -3108,6 +3263,44 @@ function executePress(el, key) {
|
|
|
3108
3263
|
...modState
|
|
3109
3264
|
}));
|
|
3110
3265
|
}
|
|
3266
|
+
/**
|
|
3267
|
+
* 点击信号校验:检查目标元素是否具备可点击信号。
|
|
3268
|
+
*
|
|
3269
|
+
* 判定逻辑(仅在有正向证据时拦截):
|
|
3270
|
+
* - 原生可点击元素(a/button/summary/input[submit|button|reset])→ 放行
|
|
3271
|
+
* - 有 CLICKABLE_ROLES 中的 ARIA role → 放行
|
|
3272
|
+
* - 有 onclick 属性 → 放行
|
|
3273
|
+
* - 有 click/mousedown/pointerdown 等事件监听 → 放行
|
|
3274
|
+
* - 无任何事件监听 → 放行(可能有事件委托)
|
|
3275
|
+
* - 有事件监听但全部为 focus/blur 类 → 拦截
|
|
3276
|
+
*/
|
|
3277
|
+
function validateClickSignal(el, selector, action) {
|
|
3278
|
+
if (el instanceof HTMLAnchorElement || el instanceof HTMLButtonElement || el instanceof HTMLOptionElement || el.tagName === "SUMMARY" || el instanceof HTMLInputElement && [
|
|
3279
|
+
"submit",
|
|
3280
|
+
"button",
|
|
3281
|
+
"reset"
|
|
3282
|
+
].includes(el.type)) return null;
|
|
3283
|
+
const role = el.getAttribute("role");
|
|
3284
|
+
if (role && CLICKABLE_ROLES.has(role)) return null;
|
|
3285
|
+
if (el.hasAttribute("onclick")) return null;
|
|
3286
|
+
const trackedEvents = getTrackedElementEvents(el);
|
|
3287
|
+
if (trackedEvents.length === 0) return null;
|
|
3288
|
+
if (trackedEvents.some((e) => CLICK_SIGNAL_EVENTS.has(e))) return null;
|
|
3289
|
+
if (trackedEvents.every((e) => FOCUS_ONLY_EVENTS.has(e))) return {
|
|
3290
|
+
content: [
|
|
3291
|
+
`Element ${describeElement(el)} has NO click handler (listeners: ${trackedEvents.join(",")}).`,
|
|
3292
|
+
`This element only has focus/blur listeners — it is NOT a valid click target.`,
|
|
3293
|
+
`Look for a nearby <a>, <button>, or sibling/parent with clk/pdn/mdn listener instead.`
|
|
3294
|
+
].join(" "),
|
|
3295
|
+
details: {
|
|
3296
|
+
error: true,
|
|
3297
|
+
code: "NO_CLICK_SIGNAL",
|
|
3298
|
+
action,
|
|
3299
|
+
selector
|
|
3300
|
+
}
|
|
3301
|
+
};
|
|
3302
|
+
return null;
|
|
3303
|
+
}
|
|
3111
3304
|
function describeElement(el) {
|
|
3112
3305
|
const tag = el.tagName.toLowerCase();
|
|
3113
3306
|
const id = el.id ? `#${el.id}` : "";
|
|
@@ -3300,6 +3493,10 @@ function createDomTool() {
|
|
|
3300
3493
|
case "click": {
|
|
3301
3494
|
const target = resolvePointerActionTarget(resolveFormItemControlTarget(retarget(el, force ? "none" : "button-link")));
|
|
3302
3495
|
const clickCount = typeof params.clickCount === "number" ? params.clickCount : 1;
|
|
3496
|
+
if (!force) {
|
|
3497
|
+
const noSignal = validateClickSignal(target, selector, action);
|
|
3498
|
+
if (noSignal) return noSignal;
|
|
3499
|
+
}
|
|
3303
3500
|
if (target instanceof HTMLOptionElement) {
|
|
3304
3501
|
const parent = target.parentElement;
|
|
3305
3502
|
if (parent instanceof HTMLSelectElement) {
|