zan-browser 2.0.7 → 3.0.0

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.
Files changed (103) hide show
  1. package/dist/agent/agent.d.ts +42 -0
  2. package/dist/agent/agent.d.ts.map +1 -0
  3. package/dist/agent/agent.js +157 -0
  4. package/dist/agent/agent.js.map +1 -0
  5. package/dist/agent/conversation.d.ts +22 -0
  6. package/dist/agent/conversation.d.ts.map +1 -0
  7. package/dist/agent/conversation.js +47 -0
  8. package/dist/agent/conversation.js.map +1 -0
  9. package/dist/agent/prompt.d.ts +3 -0
  10. package/dist/agent/prompt.d.ts.map +1 -0
  11. package/dist/agent/prompt.js +73 -0
  12. package/dist/agent/prompt.js.map +1 -0
  13. package/dist/ai.d.ts +1 -1
  14. package/dist/ai.d.ts.map +1 -1
  15. package/dist/ai.js +26 -1
  16. package/dist/ai.js.map +1 -1
  17. package/dist/browser.d.ts +0 -1
  18. package/dist/browser.d.ts.map +1 -1
  19. package/dist/browser.js +2 -10
  20. package/dist/browser.js.map +1 -1
  21. package/dist/index.d.ts +19 -2
  22. package/dist/index.d.ts.map +1 -1
  23. package/dist/index.js +35 -3
  24. package/dist/index.js.map +1 -1
  25. package/dist/navigator.d.ts +1 -0
  26. package/dist/navigator.d.ts.map +1 -1
  27. package/dist/navigator.js +58 -3
  28. package/dist/navigator.js.map +1 -1
  29. package/dist/observer.d.ts +5 -1
  30. package/dist/observer.d.ts.map +1 -1
  31. package/dist/observer.js +23 -3
  32. package/dist/observer.js.map +1 -1
  33. package/dist/registry.d.ts +20 -0
  34. package/dist/registry.d.ts.map +1 -0
  35. package/dist/registry.js +69 -0
  36. package/dist/registry.js.map +1 -0
  37. package/dist/session.d.ts +12 -27
  38. package/dist/session.d.ts.map +1 -1
  39. package/dist/session.js +74 -194
  40. package/dist/session.js.map +1 -1
  41. package/dist/tools/base.d.ts +37 -0
  42. package/dist/tools/base.d.ts.map +1 -0
  43. package/dist/tools/base.js +6 -0
  44. package/dist/tools/base.js.map +1 -0
  45. package/dist/tools/browser/click.d.ts +8 -0
  46. package/dist/tools/browser/click.d.ts.map +1 -0
  47. package/dist/tools/browser/click.js +42 -0
  48. package/dist/tools/browser/click.js.map +1 -0
  49. package/dist/tools/browser/eval_js.d.ts +8 -0
  50. package/dist/tools/browser/eval_js.d.ts.map +1 -0
  51. package/dist/tools/browser/eval_js.js +46 -0
  52. package/dist/tools/browser/eval_js.js.map +1 -0
  53. package/dist/tools/browser/fill.d.ts +8 -0
  54. package/dist/tools/browser/fill.d.ts.map +1 -0
  55. package/dist/tools/browser/fill.js +48 -0
  56. package/dist/tools/browser/fill.js.map +1 -0
  57. package/dist/tools/browser/navigate.d.ts +8 -0
  58. package/dist/tools/browser/navigate.d.ts.map +1 -0
  59. package/dist/tools/browser/navigate.js +40 -0
  60. package/dist/tools/browser/navigate.js.map +1 -0
  61. package/dist/tools/browser/screenshot.d.ts +8 -0
  62. package/dist/tools/browser/screenshot.d.ts.map +1 -0
  63. package/dist/tools/browser/screenshot.js +27 -0
  64. package/dist/tools/browser/screenshot.js.map +1 -0
  65. package/dist/tools/browser/scroll.d.ts +8 -0
  66. package/dist/tools/browser/scroll.d.ts.map +1 -0
  67. package/dist/tools/browser/scroll.js +36 -0
  68. package/dist/tools/browser/scroll.js.map +1 -0
  69. package/dist/tools/browser/wait.d.ts +8 -0
  70. package/dist/tools/browser/wait.d.ts.map +1 -0
  71. package/dist/tools/browser/wait.js +27 -0
  72. package/dist/tools/browser/wait.js.map +1 -0
  73. package/dist/tools/network/download_file.d.ts +8 -0
  74. package/dist/tools/network/download_file.d.ts.map +1 -0
  75. package/dist/tools/network/download_file.js +68 -0
  76. package/dist/tools/network/download_file.js.map +1 -0
  77. package/dist/tools/network/fetch_url.d.ts +8 -0
  78. package/dist/tools/network/fetch_url.d.ts.map +1 -0
  79. package/dist/tools/network/fetch_url.js +68 -0
  80. package/dist/tools/network/fetch_url.js.map +1 -0
  81. package/dist/tools/network/read_network_logs.d.ts +8 -0
  82. package/dist/tools/network/read_network_logs.d.ts.map +1 -0
  83. package/dist/tools/network/read_network_logs.js +64 -0
  84. package/dist/tools/network/read_network_logs.js.map +1 -0
  85. package/dist/tools/network/web_search.d.ts +8 -0
  86. package/dist/tools/network/web_search.d.ts.map +1 -0
  87. package/dist/tools/network/web_search.js +63 -0
  88. package/dist/tools/network/web_search.js.map +1 -0
  89. package/dist/tools/page/extract_dom.d.ts +8 -0
  90. package/dist/tools/page/extract_dom.d.ts.map +1 -0
  91. package/dist/tools/page/extract_dom.js +37 -0
  92. package/dist/tools/page/extract_dom.js.map +1 -0
  93. package/dist/tools/page/observe.d.ts +8 -0
  94. package/dist/tools/page/observe.d.ts.map +1 -0
  95. package/dist/tools/page/observe.js +37 -0
  96. package/dist/tools/page/observe.js.map +1 -0
  97. package/dist/tools/page/scrape.d.ts +8 -0
  98. package/dist/tools/page/scrape.d.ts.map +1 -0
  99. package/dist/tools/page/scrape.js +75 -0
  100. package/dist/tools/page/scrape.js.map +1 -0
  101. package/dist/types.d.ts +4 -0
  102. package/dist/types.d.ts.map +1 -1
  103. package/package.json +1 -1
@@ -0,0 +1,48 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FillTool = void 0;
4
+ class FillTool {
5
+ name = "fill";
6
+ description = "Clear and type text into an input or textarea by its ActionSpace ID";
7
+ inputSchema = {
8
+ type: "object",
9
+ properties: {
10
+ elementId: { type: "string", description: "Input element ID from the current ActionSpace (e.g. I1, T1)" },
11
+ value: { type: "string", description: "Text to type into the field" },
12
+ },
13
+ required: ["elementId", "value"],
14
+ };
15
+ async execute(params, ctx) {
16
+ const { page, observer, interceptor } = ctx;
17
+ if (!page || !observer) {
18
+ return { success: false, summary: "fill failed: no browser context", error: "missing page/observer" };
19
+ }
20
+ const elementId = String(params.elementId);
21
+ const value = String(params.value);
22
+ interceptor?.markActionTimestamp();
23
+ // Try cached CSS selector first
24
+ const selector = observer.getSelector(elementId);
25
+ if (selector) {
26
+ try {
27
+ await page.click(selector, { clickCount: 3 }); // select all
28
+ await page.keyboard.press("Backspace");
29
+ await page.type(selector, value, { delay: 80 });
30
+ return { success: true, summary: `Filled ${elementId} with "${value}"` };
31
+ }
32
+ catch {
33
+ // Fall through to coordinate-based fill
34
+ }
35
+ }
36
+ // Fallback: resolve to coordinates
37
+ const coords = await observer.resolveElementId(elementId);
38
+ if (!coords) {
39
+ return { success: false, summary: `fill failed: element ${elementId} not found`, error: `Element ${elementId} not found in DOM` };
40
+ }
41
+ await page.mouse.click(coords.x, coords.y);
42
+ await page.keyboard.press("Control+a");
43
+ await page.keyboard.type(value, { delay: 80 });
44
+ return { success: true, summary: `Filled ${elementId} with "${value}" at (${coords.x}, ${coords.y})` };
45
+ }
46
+ }
47
+ exports.FillTool = FillTool;
48
+ //# sourceMappingURL=fill.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fill.js","sourceRoot":"","sources":["../../../src/tools/browser/fill.ts"],"names":[],"mappings":";;;AAEA,MAAa,QAAQ;IACnB,IAAI,GAAG,MAAM,CAAC;IACd,WAAW,GAAG,qEAAqE,CAAC;IAEpF,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6DAA6D,EAAE;YACzG,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;SACtE;QACD,QAAQ,EAAE,CAAC,WAAW,EAAE,OAAO,CAAC;KACjC,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;QAC5C,IAAI,CAAC,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YACvB,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,iCAAiC,EAAE,KAAK,EAAE,uBAAuB,EAAE,CAAC;QACxG,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QACnC,WAAW,EAAE,mBAAmB,EAAE,CAAC;QAEnC,gCAAgC;QAChC,MAAM,QAAQ,GAAG,QAAQ,CAAC,WAAW,CAAC,SAAS,CAAC,CAAC;QACjD,IAAI,QAAQ,EAAE,CAAC;YACb,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,UAAU,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,aAAa;gBAC5D,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;gBACvC,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;gBAChD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,SAAS,UAAU,KAAK,GAAG,EAAE,CAAC;YAC3E,CAAC;YAAC,MAAM,CAAC;gBACP,wCAAwC;YAC1C,CAAC;QACH,CAAC;QAED,mCAAmC;QACnC,MAAM,MAAM,GAAG,MAAM,QAAQ,CAAC,gBAAgB,CAAC,SAAS,CAAC,CAAC;QAC1D,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,wBAAwB,SAAS,YAAY,EAAE,KAAK,EAAE,WAAW,SAAS,mBAAmB,EAAE,CAAC;QACpI,CAAC;QAED,MAAM,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;QAC3C,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,WAAW,CAAC,CAAC;QACvC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC,CAAC;QAC/C,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,SAAS,UAAU,KAAK,SAAS,MAAM,CAAC,CAAC,KAAK,MAAM,CAAC,CAAC,GAAG,EAAE,CAAC;IACzG,CAAC;CACF;AA/CD,4BA+CC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class NavigateTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=navigate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigate.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/navigate.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzE,qBAAa,YAAa,YAAW,IAAI;IACvC,IAAI,SAAc;IAClB,WAAW,SAAiE;IAE5E,WAAW,EAAE,UAAU,CAMrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAwBtF"}
@@ -0,0 +1,40 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.NavigateTool = void 0;
4
+ class NavigateTool {
5
+ name = "navigate";
6
+ description = "Navigate the browser to a URL and wait for the page to load";
7
+ inputSchema = {
8
+ type: "object",
9
+ properties: {
10
+ url: { type: "string", description: "The URL to navigate to" },
11
+ },
12
+ required: ["url"],
13
+ };
14
+ async execute(params, ctx) {
15
+ const { page, interceptor } = ctx;
16
+ if (!page) {
17
+ return { success: false, summary: "navigate failed: no browser context", error: "missing page" };
18
+ }
19
+ const url = String(params.url);
20
+ interceptor?.markActionTimestamp();
21
+ try {
22
+ await page.goto(url, { waitUntil: "domcontentloaded", timeout: 15_000 });
23
+ // Wait for network to settle — catches XHR that SPAs fire after DOM is parsed
24
+ try {
25
+ await page.waitForNetworkIdle({ timeout: 8_000 });
26
+ }
27
+ catch {
28
+ // Background polling — continue
29
+ }
30
+ await page.waitForTimeout(800);
31
+ return { success: true, summary: `Navigated to ${url}` };
32
+ }
33
+ catch (err) {
34
+ const msg = err.message;
35
+ return { success: false, summary: `navigate failed: ${msg}`, error: msg };
36
+ }
37
+ }
38
+ }
39
+ exports.NavigateTool = NavigateTool;
40
+ //# sourceMappingURL=navigate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"navigate.js","sourceRoot":"","sources":["../../../src/tools/browser/navigate.ts"],"names":[],"mappings":";;;AAEA,MAAa,YAAY;IACvB,IAAI,GAAG,UAAU,CAAC;IAClB,WAAW,GAAG,6DAA6D,CAAC;IAE5E,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,wBAAwB,EAAE;SAC/D;QACD,QAAQ,EAAE,CAAC,KAAK,CAAC;KAClB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,qCAAqC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;QACnG,CAAC;QAED,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,WAAW,EAAE,mBAAmB,EAAE,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,kBAAkB,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;YACzE,8EAA8E;YAC9E,IAAI,CAAC;gBACH,MAAM,IAAI,CAAC,kBAAkB,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC;YACpD,CAAC;YAAC,MAAM,CAAC;gBACP,gCAAgC;YAClC,CAAC;YACD,MAAM,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC;YAC/B,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,gBAAgB,GAAG,EAAE,EAAE,CAAC;QAC3D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,oBAAoB,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC5E,CAAC;IACH,CAAC;CACF;AApCD,oCAoCC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class ScreenshotTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(_params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=screenshot.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/screenshot.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzE,qBAAa,cAAe,YAAW,IAAI;IACzC,IAAI,SAAgB;IACpB,WAAW,SAAwG;IAEnH,WAAW,EAAE,UAAU,CAIrB;IAEI,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAevF"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScreenshotTool = void 0;
4
+ class ScreenshotTool {
5
+ name = "screenshot";
6
+ description = "Take a JPEG screenshot of the current page. Use only when ActionSpace observation is insufficient.";
7
+ inputSchema = {
8
+ type: "object",
9
+ properties: {},
10
+ required: [],
11
+ };
12
+ async execute(_params, ctx) {
13
+ const { page } = ctx;
14
+ if (!page) {
15
+ return { success: false, summary: "screenshot failed: no browser context", error: "missing page" };
16
+ }
17
+ const result = await page.screenshot({ type: "jpeg", quality: 80, encoding: "base64" });
18
+ const base64 = typeof result === "string" ? result : result.toString("base64");
19
+ return {
20
+ success: true,
21
+ summary: "Screenshot captured",
22
+ data: { base64, mimeType: "image/jpeg", timestamp: Date.now() },
23
+ };
24
+ }
25
+ }
26
+ exports.ScreenshotTool = ScreenshotTool;
27
+ //# sourceMappingURL=screenshot.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"screenshot.js","sourceRoot":"","sources":["../../../src/tools/browser/screenshot.ts"],"names":[],"mappings":";;;AAEA,MAAa,cAAc;IACzB,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAAG,oGAAoG,CAAC;IAEnH,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,OAAgC,EAAE,GAAgB;QAC9D,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;QACrB,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,uCAAuC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;QACrG,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxF,MAAM,MAAM,GAAG,OAAO,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QAE/E,OAAO;YACL,OAAO,EAAE,IAAI;YACb,OAAO,EAAE,qBAAqB;YAC9B,IAAI,EAAE,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAE;SAChE,CAAC;IACJ,CAAC;CACF;AAzBD,wCAyBC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class ScrollTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=scroll.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/scroll.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzE,qBAAa,UAAW,YAAW,IAAI;IACrC,IAAI,SAAY;IAChB,WAAW,SAA4D;IAEvE,WAAW,EAAE,UAAU,CAOrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAuBtF"}
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ScrollTool = void 0;
4
+ class ScrollTool {
5
+ name = "scroll";
6
+ description = "Scroll the page up or down by a given number of pixels";
7
+ inputSchema = {
8
+ type: "object",
9
+ properties: {
10
+ direction: { type: "string", description: "Scroll direction", enum: ["up", "down"] },
11
+ amount: { type: "number", description: "Pixels to scroll (default 300)", default: 300 },
12
+ },
13
+ required: ["direction"],
14
+ };
15
+ async execute(params, ctx) {
16
+ const { page, interceptor } = ctx;
17
+ if (!page) {
18
+ return { success: false, summary: "scroll failed: no browser context", error: "missing page" };
19
+ }
20
+ const direction = String(params.direction);
21
+ const amount = Number(params.amount) || 300;
22
+ interceptor?.markActionTimestamp();
23
+ try {
24
+ await page.evaluate(({ direction, amount }) => {
25
+ window.scrollBy(0, direction === "down" ? amount : -amount);
26
+ }, { direction, amount });
27
+ return { success: true, summary: `Scrolled ${direction} ${amount}px` };
28
+ }
29
+ catch {
30
+ // Execution context destroyed = page navigated mid-scroll
31
+ return { success: true, summary: `Scrolled ${direction} ${amount}px (page may have navigated)` };
32
+ }
33
+ }
34
+ }
35
+ exports.ScrollTool = ScrollTool;
36
+ //# sourceMappingURL=scroll.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scroll.js","sourceRoot":"","sources":["../../../src/tools/browser/scroll.ts"],"names":[],"mappings":";;;AAEA,MAAa,UAAU;IACrB,IAAI,GAAG,QAAQ,CAAC;IAChB,WAAW,GAAG,wDAAwD,CAAC;IAEvE,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,SAAS,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,kBAAkB,EAAE,IAAI,EAAE,CAAC,IAAI,EAAE,MAAM,CAAC,EAAE;YACpF,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,gCAAgC,EAAE,OAAO,EAAE,GAAG,EAAE;SACxF;QACD,QAAQ,EAAE,CAAC,WAAW,CAAC;KACxB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,EAAE,IAAI,EAAE,WAAW,EAAE,GAAG,GAAG,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,mCAAmC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC;QACjG,CAAC;QAED,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,SAAS,CAAkB,CAAC;QAC5D,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,CAAC;QAC5C,WAAW,EAAE,mBAAmB,EAAE,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CACjB,CAAC,EAAE,SAAS,EAAE,MAAM,EAAyC,EAAE,EAAE;gBAC/D,MAAM,CAAC,QAAQ,CAAC,CAAC,EAAE,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;YAC9D,CAAC,EACD,EAAE,SAAS,EAAE,MAAM,EAAE,CACtB,CAAC;YACF,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,SAAS,IAAI,MAAM,IAAI,EAAE,CAAC;QACzE,CAAC;QAAC,MAAM,CAAC;YACP,0DAA0D;YAC1D,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,YAAY,SAAS,IAAI,MAAM,8BAA8B,EAAE,CAAC;QACnG,CAAC;IACH,CAAC;CACF;AApCD,gCAoCC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class WaitTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=wait.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.d.ts","sourceRoot":"","sources":["../../../src/tools/browser/wait.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzE,qBAAa,QAAS,YAAW,IAAI;IACnC,IAAI,SAAU;IACd,WAAW,SAAmF;IAE9F,WAAW,EAAE,UAAU,CAMrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAYtF"}
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.WaitTool = void 0;
4
+ class WaitTool {
5
+ name = "wait";
6
+ description = "Wait for a specified number of milliseconds (useful when the page is loading)";
7
+ inputSchema = {
8
+ type: "object",
9
+ properties: {
10
+ ms: { type: "number", description: "Milliseconds to wait (default 1500)", default: 1500 },
11
+ },
12
+ required: [],
13
+ };
14
+ async execute(params, ctx) {
15
+ const { page } = ctx;
16
+ const ms = Math.min(Number(params.ms) || 1500, 10_000); // cap at 10s
17
+ if (page) {
18
+ await page.waitForTimeout(ms);
19
+ }
20
+ else {
21
+ await new Promise((r) => setTimeout(r, ms));
22
+ }
23
+ return { success: true, summary: `Waited ${ms}ms` };
24
+ }
25
+ }
26
+ exports.WaitTool = WaitTool;
27
+ //# sourceMappingURL=wait.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"wait.js","sourceRoot":"","sources":["../../../src/tools/browser/wait.ts"],"names":[],"mappings":";;;AAEA,MAAa,QAAQ;IACnB,IAAI,GAAG,MAAM,CAAC;IACd,WAAW,GAAG,+EAA+E,CAAC;IAE9F,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,EAAE,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,qCAAqC,EAAE,OAAO,EAAE,IAAI,EAAE;SAC1F;QACD,QAAQ,EAAE,EAAE;KACb,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,EAAE,IAAI,EAAE,GAAG,GAAG,CAAC;QACrB,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC,aAAa;QAErE,IAAI,IAAI,EAAE,CAAC;YACT,MAAM,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,MAAM,IAAI,OAAO,CAAO,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC;QACpD,CAAC;QAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC;IACtD,CAAC;CACF;AAxBD,4BAwBC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class DownloadFileTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=download_file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download_file.d.ts","sourceRoot":"","sources":["../../../src/tools/network/download_file.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKzE,qBAAa,gBAAiB,YAAW,IAAI;IAC3C,IAAI,SAAmB;IACvB,WAAW,SAA2G;IAEtH,WAAW,EAAE,UAAU,CAOrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAuDtF"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DownloadFileTool = void 0;
4
+ const MAX_CONTENT_LENGTH = 10_000;
5
+ const DOWNLOAD_TIMEOUT_MS = 30_000;
6
+ class DownloadFileTool {
7
+ name = "download_file";
8
+ description = "Download an external file (CSV, JSON, XML) and return its parsed content. Does NOT require a browser.";
9
+ inputSchema = {
10
+ type: "object",
11
+ properties: {
12
+ url: { type: "string", description: "URL of the file to download" },
13
+ format: { type: "string", description: "Expected file format", enum: ["json", "csv", "xml", "text"], default: "text" },
14
+ },
15
+ required: ["url"],
16
+ };
17
+ async execute(params, ctx) {
18
+ const url = String(params.url);
19
+ const format = String(params.format || "text");
20
+ try {
21
+ const response = await fetch(url, {
22
+ signal: AbortSignal.timeout(DOWNLOAD_TIMEOUT_MS),
23
+ });
24
+ if (!response.ok) {
25
+ return {
26
+ success: false,
27
+ summary: `download_file failed: HTTP ${response.status} ${response.statusText}`,
28
+ error: `HTTP ${response.status}`,
29
+ };
30
+ }
31
+ const raw = await response.text();
32
+ let parsed = raw;
33
+ let summary;
34
+ switch (format) {
35
+ case "json":
36
+ try {
37
+ parsed = JSON.parse(raw);
38
+ const jsonStr = JSON.stringify(parsed, null, 2).slice(0, MAX_CONTENT_LENGTH);
39
+ summary = `Downloaded JSON (${raw.length} chars):\n${jsonStr}`;
40
+ }
41
+ catch {
42
+ summary = `Downloaded file (not valid JSON, ${raw.length} chars):\n${raw.slice(0, MAX_CONTENT_LENGTH)}`;
43
+ }
44
+ break;
45
+ case "csv": {
46
+ const lines = raw.split("\n").filter((l) => l.trim());
47
+ const preview = lines.slice(0, 20).join("\n");
48
+ summary = `Downloaded CSV (${lines.length} rows):\n${preview}`;
49
+ parsed = { totalRows: lines.length, preview: lines.slice(0, 20) };
50
+ break;
51
+ }
52
+ case "xml":
53
+ summary = `Downloaded XML (${raw.length} chars):\n${raw.slice(0, MAX_CONTENT_LENGTH)}`;
54
+ break;
55
+ default:
56
+ summary = `Downloaded file (${raw.length} chars):\n${raw.slice(0, MAX_CONTENT_LENGTH)}`;
57
+ break;
58
+ }
59
+ return { success: true, summary, data: parsed };
60
+ }
61
+ catch (err) {
62
+ const msg = err.message;
63
+ return { success: false, summary: `download_file failed: ${msg}`, error: msg };
64
+ }
65
+ }
66
+ }
67
+ exports.DownloadFileTool = DownloadFileTool;
68
+ //# sourceMappingURL=download_file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"download_file.js","sourceRoot":"","sources":["../../../src/tools/network/download_file.ts"],"names":[],"mappings":";;;AAEA,MAAM,kBAAkB,GAAG,MAAM,CAAC;AAClC,MAAM,mBAAmB,GAAG,MAAM,CAAC;AAEnC,MAAa,gBAAgB;IAC3B,IAAI,GAAG,eAAe,CAAC;IACvB,WAAW,GAAG,uGAAuG,CAAC;IAEtH,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,6BAA6B,EAAE;YACnE,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sBAAsB,EAAE,IAAI,EAAE,CAAC,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,MAAM,EAAE;SACvH;QACD,QAAQ,EAAE,CAAC,KAAK,CAAC;KAClB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,MAAM,CAAC,CAAC;QAE/C,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,mBAAmB,CAAC;aACjD,CAAC,CAAC;YAEH,IAAI,CAAC,QAAQ,CAAC,EAAE,EAAE,CAAC;gBACjB,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,8BAA8B,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE;oBAC/E,KAAK,EAAE,QAAQ,QAAQ,CAAC,MAAM,EAAE;iBACjC,CAAC;YACJ,CAAC;YAED,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAClC,IAAI,MAAM,GAAY,GAAG,CAAC;YAC1B,IAAI,OAAe,CAAC;YAEpB,QAAQ,MAAM,EAAE,CAAC;gBACf,KAAK,MAAM;oBACT,IAAI,CAAC;wBACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;wBACzB,MAAM,OAAO,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,CAAC;wBAC7E,OAAO,GAAG,oBAAoB,GAAG,CAAC,MAAM,aAAa,OAAO,EAAE,CAAC;oBACjE,CAAC;oBAAC,MAAM,CAAC;wBACP,OAAO,GAAG,oCAAoC,GAAG,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC;oBAC1G,CAAC;oBACD,MAAM;gBAER,KAAK,KAAK,CAAC,CAAC,CAAC;oBACX,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC;oBACtD,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;oBAC9C,OAAO,GAAG,mBAAmB,KAAK,CAAC,MAAM,YAAY,OAAO,EAAE,CAAC;oBAC/D,MAAM,GAAG,EAAE,SAAS,EAAE,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC;oBAClE,MAAM;gBACR,CAAC;gBAED,KAAK,KAAK;oBACR,OAAO,GAAG,mBAAmB,GAAG,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC;oBACvF,MAAM;gBAER;oBACE,OAAO,GAAG,oBAAoB,GAAG,CAAC,MAAM,aAAa,GAAG,CAAC,KAAK,CAAC,CAAC,EAAE,kBAAkB,CAAC,EAAE,CAAC;oBACxF,MAAM;YACV,CAAC;YAED,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC;QAClD,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,yBAAyB,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QACjF,CAAC;IACH,CAAC;CACF;AApED,4CAoEC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class FetchUrlTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=fetch_url.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch_url.d.ts","sourceRoot":"","sources":["../../../src/tools/network/fetch_url.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKzE,qBAAa,YAAa,YAAW,IAAI;IACvC,IAAI,SAAe;IACnB,WAAW,SAAyI;IAEpJ,WAAW,EAAE,UAAU,CASrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAkDtF"}
@@ -0,0 +1,68 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.FetchUrlTool = void 0;
4
+ const MAX_BODY_LENGTH = 8_000;
5
+ const FETCH_TIMEOUT_MS = 15_000;
6
+ class FetchUrlTool {
7
+ name = "fetch_url";
8
+ description = "Make a direct HTTP request (GET/POST) with custom headers. Does NOT require a browser. Useful for calling discovered APIs directly.";
9
+ inputSchema = {
10
+ type: "object",
11
+ properties: {
12
+ url: { type: "string", description: "URL to fetch" },
13
+ method: { type: "string", description: "HTTP method", enum: ["GET", "POST", "PUT", "PATCH", "DELETE"], default: "GET" },
14
+ headers: { type: "string", description: "JSON string of headers, e.g. '{\"Authorization\": \"Bearer token\"}'" },
15
+ body: { type: "string", description: "Request body (for POST/PUT/PATCH)" },
16
+ },
17
+ required: ["url"],
18
+ };
19
+ async execute(params, ctx) {
20
+ const url = String(params.url);
21
+ const method = String(params.method || "GET");
22
+ let headers = {};
23
+ if (params.headers) {
24
+ try {
25
+ headers = JSON.parse(String(params.headers));
26
+ }
27
+ catch {
28
+ return { success: false, summary: "fetch_url failed: invalid headers JSON", error: "invalid headers JSON" };
29
+ }
30
+ }
31
+ try {
32
+ const response = await fetch(url, {
33
+ method,
34
+ headers,
35
+ body: params.body ? String(params.body) : undefined,
36
+ signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),
37
+ });
38
+ const contentType = response.headers.get("content-type") ?? "";
39
+ let body;
40
+ try {
41
+ body = await response.text();
42
+ }
43
+ catch {
44
+ body = "(could not read response body)";
45
+ }
46
+ const trimmed = body.slice(0, MAX_BODY_LENGTH);
47
+ const overflow = body.length > MAX_BODY_LENGTH ? `\n... truncated (${body.length} total chars)` : "";
48
+ return {
49
+ success: response.ok,
50
+ summary: `${method} ${url} → ${response.status} ${response.statusText} (${contentType})\n${trimmed}${overflow}`,
51
+ data: {
52
+ status: response.status,
53
+ statusText: response.statusText,
54
+ contentType,
55
+ body: trimmed,
56
+ headers: Object.fromEntries(response.headers.entries()),
57
+ },
58
+ error: response.ok ? undefined : `HTTP ${response.status} ${response.statusText}`,
59
+ };
60
+ }
61
+ catch (err) {
62
+ const msg = err.message;
63
+ return { success: false, summary: `fetch_url failed: ${msg}`, error: msg };
64
+ }
65
+ }
66
+ }
67
+ exports.FetchUrlTool = FetchUrlTool;
68
+ //# sourceMappingURL=fetch_url.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"fetch_url.js","sourceRoot":"","sources":["../../../src/tools/network/fetch_url.ts"],"names":[],"mappings":";;;AAEA,MAAM,eAAe,GAAG,KAAK,CAAC;AAC9B,MAAM,gBAAgB,GAAG,MAAM,CAAC;AAEhC,MAAa,YAAY;IACvB,IAAI,GAAG,WAAW,CAAC;IACnB,WAAW,GAAG,qIAAqI,CAAC;IAEpJ,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,GAAG,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;YACpD,MAAM,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,CAAC,EAAE,OAAO,EAAE,KAAK,EAAE;YACvH,OAAO,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,sEAAsE,EAAE;YAChH,IAAI,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,mCAAmC,EAAE;SAC3E;QACD,QAAQ,EAAE,CAAC,KAAK,CAAC;KAClB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC/B,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;QAE9C,IAAI,OAAO,GAA2B,EAAE,CAAC;QACzC,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,CAAC;gBACH,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC;YAC/C,CAAC;YAAC,MAAM,CAAC;gBACP,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,wCAAwC,EAAE,KAAK,EAAE,sBAAsB,EAAE,CAAC;YAC9G,CAAC;QACH,CAAC;QAED,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,MAAM,KAAK,CAAC,GAAG,EAAE;gBAChC,MAAM;gBACN,OAAO;gBACP,IAAI,EAAE,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,SAAS;gBACnD,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,gBAAgB,CAAC;aAC9C,CAAC,CAAC;YAEH,MAAM,WAAW,GAAG,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;YAC/D,IAAI,IAAY,CAAC;YAEjB,IAAI,CAAC;gBACH,IAAI,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,CAAC;YAC/B,CAAC;YAAC,MAAM,CAAC;gBACP,IAAI,GAAG,gCAAgC,CAAC;YAC1C,CAAC;YAED,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC;YAC/C,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,GAAG,eAAe,CAAC,CAAC,CAAC,oBAAoB,IAAI,CAAC,MAAM,eAAe,CAAC,CAAC,CAAC,EAAE,CAAC;YAErG,OAAO;gBACL,OAAO,EAAE,QAAQ,CAAC,EAAE;gBACpB,OAAO,EAAE,GAAG,MAAM,IAAI,GAAG,MAAM,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,KAAK,WAAW,MAAM,OAAO,GAAG,QAAQ,EAAE;gBAC/G,IAAI,EAAE;oBACJ,MAAM,EAAE,QAAQ,CAAC,MAAM;oBACvB,UAAU,EAAE,QAAQ,CAAC,UAAU;oBAC/B,WAAW;oBACX,IAAI,EAAE,OAAO;oBACb,OAAO,EAAE,MAAM,CAAC,WAAW,CAAE,QAAQ,CAAC,OAAe,CAAC,OAAO,EAAE,CAAC;iBACjE;gBACD,KAAK,EAAE,QAAQ,CAAC,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,QAAQ,QAAQ,CAAC,MAAM,IAAI,QAAQ,CAAC,UAAU,EAAE;aAClF,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,qBAAqB,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC7E,CAAC;IACH,CAAC;CACF;AAjED,oCAiEC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class ReadNetworkLogsTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=read_network_logs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read_network_logs.d.ts","sourceRoot":"","sources":["../../../src/tools/network/read_network_logs.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAEzE,qBAAa,mBAAoB,YAAW,IAAI;IAC9C,IAAI,SAAuB;IAC3B,WAAW,SAAkH;IAE7H,WAAW,EAAE,UAAU,CAQrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAsDtF"}
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ReadNetworkLogsTool = void 0;
4
+ class ReadNetworkLogsTool {
5
+ name = "read_network_logs";
6
+ description = "Read captured XHR/fetch requests sorted by relevance score. Use to inspect what API calls the page has made.";
7
+ inputSchema = {
8
+ type: "object",
9
+ properties: {
10
+ minScore: { type: "number", description: "Minimum relevance score filter (default 1)", default: 1 },
11
+ limit: { type: "number", description: "Max number of requests to return (default 15)", default: 15 },
12
+ showBodies: { type: "string", description: "Include response bodies in output", enum: ["true", "false"], default: "false" },
13
+ },
14
+ required: [],
15
+ };
16
+ async execute(params, ctx) {
17
+ const { interceptor } = ctx;
18
+ if (!interceptor) {
19
+ return { success: false, summary: "read_network_logs failed: no interceptor", error: "missing interceptor" };
20
+ }
21
+ const minScore = Number(params.minScore) || 1;
22
+ const limit = Math.min(Number(params.limit) || 15, 30);
23
+ const showBodies = String(params.showBodies) === "true";
24
+ const requests = interceptor.getUseful(minScore).slice(0, limit);
25
+ if (requests.length === 0) {
26
+ return {
27
+ success: true,
28
+ summary: `No XHR requests captured with score >= ${minScore}`,
29
+ data: [],
30
+ };
31
+ }
32
+ const lines = requests.map((r) => {
33
+ const marker = r.triggeredByAction ? " ↑" : " ";
34
+ const kb = r.responseBody
35
+ ? ` ${(r.responseBody.length / 1024).toFixed(1)}KB`
36
+ : "";
37
+ const ct = r.contentType ? ` ${r.contentType.split(";")[0]}` : "";
38
+ let line = `[${r.score}]${marker} ${r.method} ${r.url}${ct}${kb}`;
39
+ if (showBodies && r.responseBody) {
40
+ const bodyPreview = r.responseBody.slice(0, 500);
41
+ line += `\n Body: ${bodyPreview}${r.responseBody.length > 500 ? "..." : ""}`;
42
+ }
43
+ return line;
44
+ });
45
+ const total = interceptor.getAll().length;
46
+ const summary = `Captured XHR requests (${requests.length} shown, ${total} total):\n${lines.join("\n")}`;
47
+ return {
48
+ success: true,
49
+ summary,
50
+ data: requests.map((r) => ({
51
+ id: r.id,
52
+ method: r.method,
53
+ url: r.url,
54
+ status: r.status,
55
+ score: r.score,
56
+ contentType: r.contentType,
57
+ bodyLength: r.responseBody?.length ?? 0,
58
+ triggeredByAction: r.triggeredByAction,
59
+ })),
60
+ };
61
+ }
62
+ }
63
+ exports.ReadNetworkLogsTool = ReadNetworkLogsTool;
64
+ //# sourceMappingURL=read_network_logs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read_network_logs.js","sourceRoot":"","sources":["../../../src/tools/network/read_network_logs.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class WebSearchTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=web_search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web_search.d.ts","sourceRoot":"","sources":["../../../src/tools/network/web_search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAKzE,qBAAa,aAAc,YAAW,IAAI;IACxC,IAAI,SAAgB;IACpB,WAAW,SAAoJ;IAE/J,WAAW,EAAE,UAAU,CAMrB;IAEI,OAAO,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CA8CtF"}
@@ -0,0 +1,63 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.WebSearchTool = void 0;
7
+ const sdk_1 = __importDefault(require("@anthropic-ai/sdk"));
8
+ const FALLBACK_MODEL = "claude-haiku-4-5-20251001";
9
+ class WebSearchTool {
10
+ name = "web_search";
11
+ description = "Search the web for information before navigating. Useful when the goal is vague or the target site/URL is unknown. Does NOT require a browser.";
12
+ inputSchema = {
13
+ type: "object",
14
+ properties: {
15
+ query: { type: "string", description: "Search query" },
16
+ },
17
+ required: ["query"],
18
+ };
19
+ async execute(params, ctx) {
20
+ const query = String(params.query);
21
+ try {
22
+ const client = new sdk_1.default({ apiKey: ctx.anthropicApiKey });
23
+ // The web_search tool type is supported by the API but may not be
24
+ // in older SDK type definitions — cast through unknown.
25
+ const response = await client.messages.create({
26
+ model: ctx.aiModel ?? FALLBACK_MODEL,
27
+ max_tokens: 1024,
28
+ tools: [{ type: "web_search_20250305" }],
29
+ messages: [
30
+ { role: "user", content: `Search the web for: ${query}\n\nReturn the most relevant URLs and snippets.` },
31
+ ],
32
+ });
33
+ // Extract text and search result blocks from the response
34
+ const parts = [];
35
+ const urls = [];
36
+ for (const block of response.content) {
37
+ if (block.type === "text") {
38
+ parts.push(block.text);
39
+ }
40
+ else if (block.type === "web_search_tool_result") {
41
+ for (const item of block.content ?? []) {
42
+ if (item.type === "web_search_result") {
43
+ urls.push(item.url);
44
+ parts.push(`- ${item.title}: ${item.url}\n ${(item.page_content ?? item.encrypted_content ?? "").slice(0, 200)}`);
45
+ }
46
+ }
47
+ }
48
+ }
49
+ const summary = parts.join("\n\n").slice(0, 4000);
50
+ return {
51
+ success: true,
52
+ summary: `Web search results for "${query}":\n${summary}`,
53
+ data: { query, urls, resultCount: urls.length },
54
+ };
55
+ }
56
+ catch (err) {
57
+ const msg = err.message;
58
+ return { success: false, summary: `web_search failed: ${msg}`, error: msg };
59
+ }
60
+ }
61
+ }
62
+ exports.WebSearchTool = WebSearchTool;
63
+ //# sourceMappingURL=web_search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"web_search.js","sourceRoot":"","sources":["../../../src/tools/network/web_search.ts"],"names":[],"mappings":";;;;;;AACA,4DAA0C;AAE1C,MAAM,cAAc,GAAG,2BAA2B,CAAC;AAEnD,MAAa,aAAa;IACxB,IAAI,GAAG,YAAY,CAAC;IACpB,WAAW,GAAG,gJAAgJ,CAAC;IAE/J,WAAW,GAAe;QACxB,IAAI,EAAE,QAAQ;QACd,UAAU,EAAE;YACV,KAAK,EAAE,EAAE,IAAI,EAAE,QAAQ,EAAE,WAAW,EAAE,cAAc,EAAE;SACvD;QACD,QAAQ,EAAE,CAAC,OAAO,CAAC;KACpB,CAAC;IAEF,KAAK,CAAC,OAAO,CAAC,MAA+B,EAAE,GAAgB;QAC7D,MAAM,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;QAEnC,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,IAAI,aAAS,CAAC,EAAE,MAAM,EAAE,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC;YAE9D,kEAAkE;YAClE,wDAAwD;YACxD,MAAM,QAAQ,GAAG,MAAM,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC;gBAC5C,KAAK,EAAE,GAAG,CAAC,OAAO,IAAI,cAAc;gBACpC,UAAU,EAAE,IAAI;gBAChB,KAAK,EAAE,CAAC,EAAE,IAAI,EAAE,qBAAqB,EAAS,CAAC;gBAC/C,QAAQ,EAAE;oBACR,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,uBAAuB,KAAK,iDAAiD,EAAE;iBACzG;aACF,CAAC,CAAC;YAEH,0DAA0D;YAC1D,MAAM,KAAK,GAAa,EAAE,CAAC;YAC3B,MAAM,IAAI,GAAa,EAAE,CAAC;YAE1B,KAAK,MAAM,KAAK,IAAI,QAAQ,CAAC,OAAO,EAAE,CAAC;gBACrC,IAAI,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;oBAC1B,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;gBACzB,CAAC;qBAAM,IAAK,KAAa,CAAC,IAAI,KAAK,wBAAwB,EAAE,CAAC;oBAC5D,KAAK,MAAM,IAAI,IAAK,KAAa,CAAC,OAAO,IAAI,EAAE,EAAE,CAAC;wBAChD,IAAI,IAAI,CAAC,IAAI,KAAK,mBAAmB,EAAE,CAAC;4BACtC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;4BACpB,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,KAAK,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,YAAY,IAAI,IAAI,CAAC,iBAAiB,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;wBACrH,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YAED,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,IAAI,CAAC,CAAC;YAElD,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,2BAA2B,KAAK,OAAO,OAAO,EAAE;gBACzD,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,MAAM,EAAE;aAChD,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,GAAG,GAAI,GAAa,CAAC,OAAO,CAAC;YACnC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,sBAAsB,GAAG,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC;QAC9E,CAAC;IACH,CAAC;CACF;AA1DD,sCA0DC"}
@@ -0,0 +1,8 @@
1
+ import type { Tool, ToolContext, ToolResult, JSONSchema } from "../base";
2
+ export declare class ExtractDomTool implements Tool {
3
+ name: string;
4
+ description: string;
5
+ inputSchema: JSONSchema;
6
+ execute(_params: Record<string, unknown>, ctx: ToolContext): Promise<ToolResult>;
7
+ }
8
+ //# sourceMappingURL=extract_dom.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extract_dom.d.ts","sourceRoot":"","sources":["../../../src/tools/page/extract_dom.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,WAAW,EAAE,UAAU,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AAIzE,qBAAa,cAAe,YAAW,IAAI;IACzC,IAAI,SAAiB;IACrB,WAAW,SAAoJ;IAE/J,WAAW,EAAE,UAAU,CAIrB;IAEI,OAAO,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,EAAE,WAAW,GAAG,OAAO,CAAC,UAAU,CAAC;CAyBvF"}