agentpage 0.0.37 → 0.0.39

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
@@ -1161,23 +1161,25 @@ loop 对本轮返回做以下处理:
1161
1161
 
1162
1162
  - 从当前快照直接执行,不复述任务
1163
1163
  - 任务按“剔除模型”推进(current + previous + this-round -> new remaining)
1164
- - 禁止 `page_info` 作为规划手段
1164
+ - 效果检查:规划新动作前先确认上轮操作是否在快照中生效
1165
+ - 禁止 `page_info` 作为规划手段,禁止重复相同工具调用
1165
1166
  - 可见目标尽量同轮批量执行
1166
1167
  - DOM 会变化的动作执行后在下一轮继续
1168
+ - 停机前必须在快照中确认任务已完成
1167
1169
  - 统一输出 `REMAINING` 协议
1168
1170
 
1169
1171
  ### B. Round Messages(轮次状态层)
1170
1172
 
1171
1173
  由 `src/core/agent-loop/messages.ts` 构建,职责是把运行时状态传给模型:
1172
1174
 
1173
- - `Current remaining instruction`
1174
- - `Done steps (do NOT repeat)`
1175
- - `Previous round planned task array`
1176
- - `Effect verification` 要求 AI 对比上轮操作与当前快照,确认每个操作是否生效;未生效时从同区域找其他目标而非重复
1177
- - `Previous round model output (normalized)`
1178
- - `Latest DOM snapshot`
1175
+ - `Remaining: <instruction>` — 当前剩余任务
1176
+ - `Done steps (do NOT repeat)` — 已完成步骤摘要
1177
+ - 关键行为强化(批量执行、禁 page_info、DOM 断轮、Effect check)
1178
+ - `Previous executed` + 效果提示(简短非阻塞)
1179
+ - `Previous model output` — 上轮模型输出摘要
1180
+ - `## Snapshot` — 最新 DOM 快照
1179
1181
 
1180
- 这层是“每轮变化”的动态上下文。
1182
+ 这层是“每轮变化”的动态上下文,已大幅精简避免与 system prompt 规则重复。
1181
1183
 
1182
1184
  ### C. Loop Control(执行控制层)
1183
1185
 
package/dist/index.mjs CHANGED
@@ -450,12 +450,10 @@ function buildCompactMessages(userMessage, trace, latestSnapshot, currentUrl, hi
450
450
  const parts = [
451
451
  userMessage,
452
452
  "",
453
- "## Progressive execution state",
454
- "Current remaining instruction to execute this round:",
455
- activeInstruction
453
+ `Remaining: ${activeInstruction}`
456
454
  ];
457
- if (currentUrl) parts.push("", `URL: ${currentUrl}`);
458
- if (latestSnapshot) parts.push("", "## Current page snapshot", "Apply task-reduction model directly from this snapshot. Do NOT restate the task.", "Use hash IDs (e.g. #a1b2c) from the snapshot as selector params.", "Do NOT call page_info (get_url/get_title/query_all/snapshot).", "Batch independent visible actions in one round.", "Build the minimal action array from current snapshot to finish this remaining instruction in one round whenever possible.", "For deterministic increase/decrease controls, compute delta from current visible value and issue exactly that many clicks in one round (e.g., +2 => two increase clicks). Do not overshoot then undo.", "If action changes DOM (open modal/navigate), stop that batch and continue next round.", "For dropdown/select fields, use dom with action=select_option (or fill on a select).", "If a needed list shows `... (N children omitted)` under a specific container, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<containerRef>` and wait for next round snapshot.", "Stop rule: once requested state is reached, stop tool calls. If verification is needed, verify once and then output REMAINING: DONE.", allowAgentUiInteraction ? "User explicitly asked to operate AutoPilot UI. You may interact with chat input/send/dock only as requested." : "Do NOT interact with any AI chat UI elements (chat input, send button, dock). Only operate on the actual page content.", "Output one line: REMAINING: <new remaining task after this round> or REMAINING: DONE", wrapSnapshot(latestSnapshot));
455
+ if (currentUrl) parts.push(`URL: ${currentUrl}`);
456
+ if (latestSnapshot) parts.push("", "Use #hashID from snapshot. Do NOT call page_info (snapshot is auto-refreshed). Batch all visible actions in one round.", "Effect check: confirm previous actions' expected effects in current snapshot before planning new actions.", "If action changes DOM (modal/navigate), stop batch and continue next round.", "If a list shows `... (N children omitted)`, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>` and wait for next snapshot.", allowAgentUiInteraction ? "User explicitly asked to operate AutoPilot UI. You may interact with chat input/send/dock only as requested." : "Do NOT interact with any AI chat UI elements (chat input, send button, dock). Only operate on the actual page content.", "Output: REMAINING: <new remaining> or REMAINING: DONE", "", "## Snapshot", wrapSnapshot(latestSnapshot));
459
457
  if (protocolViolationHint) parts.push("", protocolViolationHint);
460
458
  messages.push({
461
459
  role: "user",
@@ -478,42 +476,29 @@ function buildCompactMessages(userMessage, trace, latestSnapshot, currentUrl, hi
478
476
  });
479
477
  const hasErrors = trace.some((e) => hasToolError(e.result));
480
478
  const contextParts = [
481
- "## Execution context",
482
- "Current remaining instruction:",
483
- activeInstruction,
479
+ `Remaining: ${activeInstruction}`,
484
480
  "",
485
- "Task-reduction model:",
486
- "Input: current remaining instruction + previous round executed actions + this-round actions.",
487
- "Output: new remaining instruction after removing this-round actions.",
488
- "Start from visible page state directly. Do NOT restate task. Do NOT output planning text.",
489
- "Execute all independent visible sub-tasks in one round.",
490
- "Do NOT act on elements not present in this snapshot yet.",
491
- "If action changes DOM (open modal/navigate), stop after that batch and continue next round.",
492
- "Do NOT call page_info (get_url/get_title/query_all/snapshot).",
493
- "For dropdown/select fields, use dom with action=select_option (or fill on a select).",
494
- "If a needed list shows `... (N children omitted)` under a specific container, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<containerRef>` and wait for next round snapshot.",
495
- "Build the minimal action array from current snapshot to finish this remaining instruction in one round whenever possible.",
496
- "For deterministic increase/decrease controls, compute delta from current visible value and issue exactly that many clicks in one round (e.g., +2 => two increase clicks). Do not overshoot then undo.",
497
- "Stop rule: once requested state is reached, stop tool calls. If verification is needed, verify once and then output REMAINING: DONE.",
498
- allowAgentUiInteraction ? "User explicitly asked to operate AutoPilot UI. You may interact with chat input/send/dock only as requested." : "Do NOT interact with any AI chat UI elements (chat input, send button, dock). Only operate on the actual page content."
481
+ "Execute all independent visible sub-tasks in one round. Do NOT call page_info (snapshot is auto-refreshed).",
482
+ "Effect check: confirm previous actions' expected effects in snapshot before planning new actions.",
483
+ "Never repeat the same tool call on the same target. If no effect, try a different element.",
484
+ "If action changes DOM (modal/navigate), stop batch and continue next round.",
485
+ "If a list shows `... (N children omitted)`, output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>` and wait.",
486
+ allowAgentUiInteraction ? "User explicitly asked to operate AutoPilot UI." : "Do NOT interact with AI chat UI elements.",
487
+ "Output: REMAINING: <new remaining> or REMAINING: DONE"
499
488
  ];
500
- if (hasErrors) contextParts.push("", "The last step failed. Retry with a different approach, or skip and continue with other visible targets.");
501
- else contextParts.push("", "If the goal is fully done, reply with a short summary (no tool calls).");
502
- if (previousRoundTasks && previousRoundTasks.length > 0) {
503
- contextParts.push("", "Previous round planned task array (already executed):", ...previousRoundTasks.map((task, index) => `${index + 1}. ${task}`));
504
- contextParts.push("", "## Effect verification (MANDATORY before planning new actions)", "Compare the above executed actions against the CURRENT snapshot below:", "- Did each action produce the expected result? (e.g., click opened a dialog/navigated; fill changed the input value; select_option updated the selected item)", "- If an action had NO visible effect (page unchanged near the target area), do NOT repeat the same target.", " Instead, look for a different actionable element nearby (sibling/ancestor in the same row/card/group) that has stronger interaction signals (click listeners, button/link semantics).", "- Only after confirming which previous actions succeeded, plan this round's new actions on the remaining unfinished parts.");
505
- }
506
- if (previousRoundPlannedTasks && previousRoundPlannedTasks.length > 0) contextParts.push("", "Previous round model planned task array (before execution):", ...previousRoundPlannedTasks.map((task, index) => `${index + 1}. ${task}`));
507
- if (previousRoundModelOutput) contextParts.push("", "Previous round model output (normalized, for task reduction input):", previousRoundModelOutput);
508
- contextParts.push("", "After this round, include one plain text line:", "REMAINING: <new remaining instruction after this-round actions>", "or REMAINING: DONE");
489
+ if (hasErrors) contextParts.push("", "Last step failed. Retry differently or skip to other targets.");
490
+ else contextParts.push("", "If fully done, reply summary only (no tools).");
491
+ if (previousRoundTasks && previousRoundTasks.length > 0) contextParts.push("", "Previous executed:", ...previousRoundTasks.map((task, index) => `${index + 1}. ${task}`), "If any had no visible effect, try a different nearby element instead of repeating.");
492
+ if (previousRoundPlannedTasks && previousRoundPlannedTasks.length > 0) contextParts.push("", "Previous planned:", ...previousRoundPlannedTasks.map((task, index) => `${index + 1}. ${task}`));
493
+ if (previousRoundModelOutput) contextParts.push("", "Previous model output:", previousRoundModelOutput);
509
494
  const lastEntry = trace[trace.length - 1];
510
495
  if (hasToolError(lastEntry.result)) {
511
496
  const stripped = toContentString(lastEntry.result.content).replace(SNAPSHOT_REGEX, "").trim();
512
- if (stripped && stripped.length < 300) contextParts.push("", "Last error: " + stripped);
497
+ if (stripped && stripped.length < 300) contextParts.push("", "Error: " + stripped);
513
498
  }
514
499
  if (currentUrl) contextParts.push("", `URL: ${currentUrl}`);
515
500
  if (protocolViolationHint) contextParts.push("", protocolViolationHint);
516
- if (latestSnapshot) contextParts.push("", "## Latest DOM snapshot", "Use hash IDs from this snapshot. Do NOT call page_info — this is already the latest.", wrapSnapshot(latestSnapshot));
501
+ if (latestSnapshot) contextParts.push("", "## Snapshot", wrapSnapshot(latestSnapshot));
517
502
  messages.push({
518
503
  role: "user",
519
504
  content: contextParts.join("\n")
@@ -1711,52 +1696,34 @@ function buildSystemPrompt(params = {}) {
1711
1696
  "You are AutoPilot, an AI agent controlling the current web page via tools.",
1712
1697
  "",
1713
1698
  "## Core Rules",
1714
- "- Work from CURRENT snapshot + CURRENT remaining task directly. Do not restate the request.",
1715
- "- Treat each round as task reduction:",
1716
- " Input: (1) current remaining task, (2) previous round executed actions, (3) actions you execute this round.",
1717
- " Output: new remaining task after removing this-round actions.",
1718
- "- Use only visible targets from snapshot. Use #hashID as selector. Do not guess CSS selectors.",
1719
- "- Only interactive elements (with events, inputs, buttons, links, etc.) carry #hashID. Elements without #hashID are context-only (labels, headings, text) and cannot be targeted.",
1720
- "- Snapshot tag in brackets may show ARIA role instead of HTML tag when it better describes the interaction pattern (e.g. [combobox] for input with role=\"combobox\", [slider] for div with role=\"slider\"). Treat the bracket tag as the primary interaction hint.",
1721
- "- listeners=\"...\" on snapshot indicates bound event handlers (see Listener Abbrevs below). Prefer targets with relevant listeners when multiple candidates look similar.",
1722
- "- Click targeting rule (MANDATORY): for click/navigation actions, prioritize elements with explicit click signals (listeners containing clk/pdn/mdn, onclick, native link/button semantics, or role=button/link).",
1723
- "- Do NOT click focus/hover-only nodes for navigation (e.g. listeners only like fcs/blr/men/mlv without click-related signals). Treat those as context labels unless no better actionable target exists.",
1724
- "- Correlation fallback: if a click produced no progress, in the next round choose the nearest actionable sibling/ancestor within the same semantic group (same row/card/form), such as adjacent repo path/link/button, instead of repeating the same ineffective target.",
1725
- "- Batch independent visible actions in one round. Do not split one form into many rounds unnecessarily.",
1726
- "- Strict input order (MANDATORY): before every fill/type/select_option, click or focus the SAME target immediately in the SAME round.",
1727
- "- Multi-field rule (MANDATORY): execute alternating pairs in one batch: focus/click field A -> fill/type A -> focus/click field B -> fill/type B.",
1728
- "- Build the minimal action array from CURRENT snapshot to satisfy the target in one round whenever possible.",
1729
- "- 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.",
1730
- "- 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, ...).",
1731
- "- Deterministic delta rule: for increase/decrease steppers, compute target delta from visible current value and emit exactly |delta| clicks in one round (e.g., +2 => click increase twice). Never overshoot then undo.",
1732
- "- For check/uncheck, target the real input control (checkbox/radio), not nearby text/container nodes.",
1733
- "- Form batch rule: for one visible form, complete all independent fields in one round; do not fill one field then verify repeatedly.",
1734
- "- If an action will change DOM (open modal, navigate), stop after that action batch and continue next round with new snapshot.",
1735
- "- Do NOT call page_info (snapshot/query/get_url/get_title). Snapshot is already provided every round.",
1736
- "- For dropdown/select, use dom action=select_option (or fill on select).",
1737
- "- If a required list shows `... (N children omitted)` under a specific container, request focused expansion by outputting `SNAPSHOT_HINT: EXPAND_CHILDREN #<containerRef>`.",
1738
- "- After outputting snapshot expansion hint, wait for the next refreshed snapshot before further scrolling/clicking on that list.",
1739
- "- Verification whitelist: do NOT use get_text/get_attr to verify input/select values unless the user explicitly asks for verification.",
1740
- "- Stop rule: when the requested state is achieved, stop calling tools. If verification is requested, verify once and then return REMAINING: DONE (no repeated get_text/get_attr on the same target).",
1741
- "- Do NOT interact with AutoPilot UI unless user explicitly asks.",
1699
+ "- Work from CURRENT snapshot + remaining task. Do not restate.",
1700
+ "- Task reduction: (remaining, prev actions, this-round) new remaining.",
1701
+ "- Use #hashID from snapshot as selector. Do not guess CSS selectors.",
1702
+ "- Only interactive elements carry #hashID; others are context-only and cannot be targeted.",
1703
+ "- Bracket tag may show ARIA role ([combobox], [slider]) as primary interaction hint.",
1704
+ "- listeners=\"...\" = bound event handlers (abbrevs below). Prefer targets with matching listeners.",
1705
+ "- Click priority: clk/pdn/mdn, onclick, native link/button, role=button/link. Avoid focus/hover-only (fcs/blr/men/mlv only).",
1706
+ "- No-effect fallback: try nearest actionable sibling/ancestor in same semantic group instead of repeating.",
1707
+ "- Batch all independent visible actions per round. Build minimal action array. Complete all form fields together.",
1708
+ "- Input order (MANDATORY): focus/click fill/type/select_option per target. Multi-field: focus A→fill A→focus B→fill B.",
1709
+ "- Do NOT run focus-only batches. Each focus must be immediately followed by its fill/type/select_option.",
1710
+ "- Steppers: compute delta from visible value, click exactly |delta| times. Check/uncheck: target real input control.",
1711
+ "- DOM-changing action (modal/navigate): stop batch, continue next round with new snapshot.",
1712
+ "- 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.",
1713
+ "- 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.",
1714
+ "- Never repeat the same tool call (same name + same args) on the same target. If it didn't work, try a different approach.",
1715
+ "- Dropdown/select: use dom.select_option or fill.",
1716
+ "- Omitted children: output `SNAPSHOT_HINT: EXPAND_CHILDREN #<ref>`, wait for next snapshot.",
1717
+ "- Do NOT verify values unless user explicitly asks.",
1718
+ "- Stop: when remaining task is fully achieved (confirmed in snapshot), output REMAINING: DONE with a summary.",
1719
+ "- Do NOT interact with AutoPilot UI unless user asks.",
1742
1720
  "",
1743
1721
  "## Listener Abbrevs",
1744
1722
  "clk=click dbl=dblclick mdn=mousedown mup=mouseup mmv=mousemove mov=mouseover mot=mouseout men=mouseenter mlv=mouseleave pdn=pointerdown pup=pointerup pmv=pointermove tst=touchstart ted=touchend kdn=keydown kup=keyup inp=input chg=change sub=submit fcs=focus blr=blur scl=scroll whl=wheel drg=drag drs=dragstart dre=dragend drp=drop ctx=contextmenu",
1745
1723
  "",
1746
- "## Output Contract",
1747
- "- Return tool calls for this round.",
1748
- "- Also include one plain text line:",
1749
- " REMAINING: <new remaining task after this round>",
1750
- " or REMAINING: DONE",
1751
- "",
1752
- "## Minimal Example",
1753
- "Task: click button -> type \"abc\" in input -> send",
1754
- "Round1 execute: click button",
1755
- "Remaining: type \"abc\" in input -> send",
1756
- "Round2 execute: type \"abc\" in input",
1757
- "Remaining: send",
1758
- "Round3 execute: send",
1759
- "Remaining: DONE"
1724
+ "## Output",
1725
+ "Tool calls + one text line: REMAINING: <new remaining> or REMAINING: DONE",
1726
+ "Example: Task A→B→C. Round1 do A → REMAINING: B→C. Round2 do B → REMAINING: C. Round3 do C → REMAINING: DONE"
1760
1727
  ].join("\n"));
1761
1728
  const tools = params.tools ?? [];
1762
1729
  if (tools.length > 0) {