explorbot 0.1.32-beta.1 → 0.2.1

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 (222) hide show
  1. package/README.md +35 -19
  2. package/bin/explorbot-cli.ts +33 -10
  3. package/boat/api-tester/src/config.ts +45 -3
  4. package/boat/doc-collector/src/ai/documentarian.ts +26 -28
  5. package/boat/doc-collector/src/ai/tools.ts +74 -16
  6. package/boat/doc-collector/src/cli.ts +1 -6
  7. package/boat/doc-collector/src/docbot.ts +30 -9
  8. package/boat/doc-collector/src/docs-renderer.ts +19 -24
  9. package/boat/doc-collector/src/screenshots.ts +34 -2
  10. package/boat/doc-collector/src/state-diagram.ts +281 -0
  11. package/dist/bin/explorbot-cli.js +29 -9
  12. package/dist/boat/api-tester/src/config.js +43 -4
  13. package/dist/boat/doc-collector/src/ai/documentarian.js +19 -7
  14. package/dist/boat/doc-collector/src/ai/tools.js +53 -16
  15. package/dist/boat/doc-collector/src/cli.js +1 -5
  16. package/dist/boat/doc-collector/src/docbot.js +27 -8
  17. package/dist/boat/doc-collector/src/docs-renderer.js +18 -3
  18. package/dist/boat/doc-collector/src/screenshots.js +30 -1
  19. package/dist/boat/doc-collector/src/state-diagram.js +200 -0
  20. package/dist/models.json +30 -0
  21. package/dist/package.json +23 -3
  22. package/dist/src/action-result.d.ts +8 -10
  23. package/dist/src/action-result.js +72 -164
  24. package/dist/src/action.d.ts +13 -12
  25. package/dist/src/action.js +37 -113
  26. package/dist/src/ai/agent.d.ts +17 -0
  27. package/dist/src/ai/captain/idle-mode.js +1 -1
  28. package/dist/src/ai/captain/test-mode.js +1 -1
  29. package/dist/src/ai/captain/web-mode.js +18 -29
  30. package/dist/src/ai/captain.d.ts +1 -3
  31. package/dist/src/ai/captain.js +17 -45
  32. package/dist/src/ai/conversation.d.ts +2 -5
  33. package/dist/src/ai/conversation.js +9 -28
  34. package/dist/src/ai/driller.d.ts +2 -17
  35. package/dist/src/ai/driller.js +26 -50
  36. package/dist/src/ai/experience-compactor.d.ts +2 -2
  37. package/dist/src/ai/experience-compactor.js +16 -33
  38. package/dist/src/ai/fisherman-tools.js +1 -1
  39. package/dist/src/ai/fisherman.d.ts +0 -1
  40. package/dist/src/ai/fisherman.js +0 -3
  41. package/dist/src/ai/historian/codeceptjs.d.ts +2 -0
  42. package/dist/src/ai/historian/codeceptjs.js +4 -3
  43. package/dist/src/ai/historian/playwright.d.ts +4 -1
  44. package/dist/src/ai/historian/playwright.js +4 -3
  45. package/dist/src/ai/historian/screencast.d.ts +2 -1
  46. package/dist/src/ai/historian/screencast.js +2 -2
  47. package/dist/src/ai/historian/utils.d.ts +0 -1
  48. package/dist/src/ai/historian/utils.js +0 -1
  49. package/dist/src/ai/historian.d.ts +10 -8
  50. package/dist/src/ai/historian.js +1 -5
  51. package/dist/src/ai/navigator.d.ts +8 -6
  52. package/dist/src/ai/navigator.js +34 -65
  53. package/dist/src/ai/pilot.d.ts +13 -8
  54. package/dist/src/ai/pilot.js +53 -59
  55. package/dist/src/ai/planner.d.ts +5 -4
  56. package/dist/src/ai/planner.js +66 -52
  57. package/dist/src/ai/provider.d.ts +4 -1
  58. package/dist/src/ai/provider.js +77 -137
  59. package/dist/src/ai/quartermaster.d.ts +22 -22
  60. package/dist/src/ai/quartermaster.js +8 -14
  61. package/dist/src/ai/rerunner.d.ts +3 -13
  62. package/dist/src/ai/rerunner.js +23 -44
  63. package/dist/src/ai/researcher/cache.js +11 -18
  64. package/dist/src/ai/researcher/coordinates.js +4 -3
  65. package/dist/src/ai/researcher/deep-analysis.d.ts +2 -0
  66. package/dist/src/ai/researcher/deep-analysis.js +8 -11
  67. package/dist/src/ai/researcher/locators.d.ts +9 -2
  68. package/dist/src/ai/researcher/locators.js +65 -8
  69. package/dist/src/ai/researcher/parser.js +1 -1
  70. package/dist/src/ai/researcher/research-result.d.ts +0 -1
  71. package/dist/src/ai/researcher/research-result.js +0 -19
  72. package/dist/src/ai/researcher/sections.d.ts +2 -0
  73. package/dist/src/ai/researcher/sections.js +7 -3
  74. package/dist/src/ai/researcher.js +40 -106
  75. package/dist/src/ai/rules.d.ts +1 -0
  76. package/dist/src/ai/rules.js +22 -15
  77. package/dist/src/ai/session-analyst.js +8 -5
  78. package/dist/src/ai/task-agent.d.ts +19 -6
  79. package/dist/src/ai/task-agent.js +37 -33
  80. package/dist/src/ai/tester.d.ts +6 -14
  81. package/dist/src/ai/tester.js +46 -111
  82. package/dist/src/ai/tools.d.ts +26 -14
  83. package/dist/src/ai/tools.js +138 -132
  84. package/dist/src/command-handler.js +1 -1
  85. package/dist/src/commands/compact-command.d.ts +1 -1
  86. package/dist/src/commands/compact-command.js +6 -6
  87. package/dist/src/commands/context-aria-command.js +1 -1
  88. package/dist/src/commands/context-command.js +8 -6
  89. package/dist/src/commands/context-data-command.js +2 -2
  90. package/dist/src/commands/context-experience-command.js +2 -2
  91. package/dist/src/commands/context-html-command.js +2 -2
  92. package/dist/src/commands/context-knowledge-command.js +2 -2
  93. package/dist/src/commands/drill-command.js +1 -1
  94. package/dist/src/commands/experience-command.js +1 -1
  95. package/dist/src/commands/explore-command.js +4 -3
  96. package/dist/src/commands/freesail-command.js +2 -2
  97. package/dist/src/commands/knows-command.js +1 -1
  98. package/dist/src/commands/learn-command.js +5 -3
  99. package/dist/src/commands/path-command.js +1 -1
  100. package/dist/src/commands/research-command.js +1 -1
  101. package/dist/src/commands/test-command.js +1 -1
  102. package/dist/src/components/AddKnowledge.d.ts +2 -0
  103. package/dist/src/components/AddKnowledge.js +3 -7
  104. package/dist/src/components/App.js +3 -3
  105. package/dist/src/config.d.ts +19 -0
  106. package/dist/src/config.js +156 -10
  107. package/dist/src/experience-tracker.d.ts +11 -6
  108. package/dist/src/experience-tracker.js +82 -155
  109. package/dist/src/explorbot.d.ts +21 -13
  110. package/dist/src/explorbot.js +84 -80
  111. package/dist/src/explorer.d.ts +66 -102
  112. package/dist/src/explorer.js +332 -623
  113. package/dist/src/knowledge-tracker.d.ts +2 -2
  114. package/dist/src/knowledge-tracker.js +38 -45
  115. package/dist/src/state-manager.d.ts +10 -30
  116. package/dist/src/state-manager.js +11 -129
  117. package/dist/src/utils/aria.d.ts +6 -1
  118. package/dist/src/utils/aria.js +4 -1
  119. package/dist/src/utils/cache.d.ts +15 -0
  120. package/dist/src/utils/cache.js +34 -0
  121. package/dist/src/utils/context-formatter.d.ts +6 -0
  122. package/dist/src/utils/context-formatter.js +15 -27
  123. package/dist/src/utils/hooks-runner.js +2 -4
  124. package/dist/src/utils/html.d.ts +5 -0
  125. package/dist/src/utils/html.js +71 -0
  126. package/dist/src/utils/markdown-files.d.ts +10 -0
  127. package/dist/src/utils/markdown-files.js +21 -0
  128. package/dist/src/utils/markdown-query.d.ts +6 -0
  129. package/dist/src/utils/markdown-query.js +14 -1
  130. package/dist/src/utils/page-readiness.d.ts +1 -0
  131. package/dist/src/utils/page-readiness.js +1 -1
  132. package/dist/src/utils/secrets.js +2 -2
  133. package/dist/src/utils/strings.d.ts +2 -0
  134. package/dist/src/utils/strings.js +10 -0
  135. package/dist/src/utils/test-files.js +1 -1
  136. package/dist/src/utils/web-annotate.d.ts +5 -0
  137. package/dist/src/utils/web-annotate.js +58 -0
  138. package/dist/src/utils/web-eidx.d.ts +2 -0
  139. package/dist/src/utils/web-eidx.js +20 -0
  140. package/dist/src/utils/web-element.d.ts +3 -1
  141. package/dist/src/utils/web-element.js +32 -0
  142. package/dist/src/utils/web-sandbox.d.ts +4 -0
  143. package/dist/src/utils/web-sandbox.js +37 -0
  144. package/models.json +30 -0
  145. package/package.json +23 -3
  146. package/src/action-result.ts +70 -173
  147. package/src/action.ts +38 -132
  148. package/src/ai/agent.ts +20 -0
  149. package/src/ai/captain/idle-mode.ts +1 -1
  150. package/src/ai/captain/test-mode.ts +1 -1
  151. package/src/ai/captain/web-mode.ts +18 -30
  152. package/src/ai/captain.ts +17 -42
  153. package/src/ai/conversation.ts +9 -32
  154. package/src/ai/driller.ts +53 -83
  155. package/src/ai/experience-compactor.ts +16 -35
  156. package/src/ai/fisherman-tools.ts +1 -1
  157. package/src/ai/fisherman.ts +0 -4
  158. package/src/ai/historian/codeceptjs.ts +5 -3
  159. package/src/ai/historian/playwright.ts +7 -4
  160. package/src/ai/historian/screencast.ts +4 -3
  161. package/src/ai/historian/utils.ts +0 -1
  162. package/src/ai/historian.ts +6 -8
  163. package/src/ai/navigator.ts +39 -70
  164. package/src/ai/pilot.ts +59 -61
  165. package/src/ai/planner.ts +76 -62
  166. package/src/ai/provider.ts +85 -146
  167. package/src/ai/quartermaster.ts +39 -45
  168. package/src/ai/rerunner.ts +27 -50
  169. package/src/ai/researcher/cache.ts +10 -16
  170. package/src/ai/researcher/coordinates.ts +4 -3
  171. package/src/ai/researcher/deep-analysis.ts +10 -11
  172. package/src/ai/researcher/locators.ts +66 -9
  173. package/src/ai/researcher/parser.ts +1 -1
  174. package/src/ai/researcher/research-result.ts +0 -18
  175. package/src/ai/researcher/sections.ts +9 -3
  176. package/src/ai/researcher.ts +42 -119
  177. package/src/ai/rules.ts +24 -13
  178. package/src/ai/session-analyst.ts +8 -5
  179. package/src/ai/task-agent.ts +45 -38
  180. package/src/ai/tester.ts +51 -129
  181. package/src/ai/tools.ts +145 -153
  182. package/src/command-handler.ts +1 -1
  183. package/src/commands/compact-command.ts +7 -8
  184. package/src/commands/context-aria-command.ts +1 -1
  185. package/src/commands/context-command.ts +8 -6
  186. package/src/commands/context-data-command.ts +2 -2
  187. package/src/commands/context-experience-command.ts +2 -2
  188. package/src/commands/context-html-command.ts +2 -2
  189. package/src/commands/context-knowledge-command.ts +2 -2
  190. package/src/commands/drill-command.ts +1 -1
  191. package/src/commands/experience-command.ts +1 -1
  192. package/src/commands/explore-command.ts +4 -3
  193. package/src/commands/freesail-command.ts +2 -2
  194. package/src/commands/knows-command.ts +1 -1
  195. package/src/commands/learn-command.ts +5 -3
  196. package/src/commands/path-command.ts +1 -1
  197. package/src/commands/research-command.ts +1 -1
  198. package/src/commands/test-command.ts +1 -1
  199. package/src/components/AddKnowledge.tsx +5 -7
  200. package/src/components/App.tsx +3 -3
  201. package/src/config.ts +185 -11
  202. package/src/experience-tracker.ts +89 -152
  203. package/src/explorbot.ts +88 -83
  204. package/src/explorer.ts +402 -693
  205. package/src/knowledge-tracker.ts +42 -49
  206. package/src/state-manager.ts +20 -155
  207. package/src/utils/aria.ts +11 -2
  208. package/src/utils/cache.ts +40 -0
  209. package/src/utils/context-formatter.ts +12 -15
  210. package/src/utils/hooks-runner.ts +2 -4
  211. package/src/utils/html.ts +79 -0
  212. package/src/utils/markdown-files.ts +30 -0
  213. package/src/utils/markdown-query.ts +15 -1
  214. package/src/utils/page-readiness.ts +1 -1
  215. package/src/utils/secrets.ts +2 -3
  216. package/src/utils/strings.ts +12 -0
  217. package/src/utils/test-files.ts +1 -1
  218. package/src/utils/web-annotate.ts +64 -0
  219. package/src/utils/web-eidx.ts +21 -0
  220. package/src/utils/web-element.ts +34 -0
  221. package/src/utils/web-sandbox.ts +43 -0
  222. package/dist/boat/api-tester/example/apibot.config.js +0 -30
@@ -1,5 +1,6 @@
1
1
  import type { ExplorbotConfig } from '../config.js';
2
- import { ExperienceTracker } from '../experience-tracker.js';
2
+ import type { ExperienceTracker } from '../experience-tracker.js';
3
+ import type Explorer from '../explorer.js';
3
4
  import type { PlaywrightRecorder } from '../playwright-recorder.js';
4
5
  import type { Reporter } from '../reporter.js';
5
6
  import type { StateManager } from '../state-manager.js';
@@ -9,14 +10,13 @@ import { type ExperienceMethods } from './historian/experience.js';
9
10
  import { type PlaywrightMethods } from './historian/playwright.js';
10
11
  import { type ScreencastMethods } from './historian/screencast.js';
11
12
  import type { Provider } from './provider.js';
12
- export { isNonReusableCode } from '../utils/step-analyzer.js';
13
13
  declare const HistorianBase: {
14
14
  new (...args: any[]): {
15
15
  config: ExplorbotConfig | undefined;
16
16
  savedFiles: Set<string>;
17
17
  playwright: {
18
18
  recorder: PlaywrightRecorder;
19
- helper: any;
19
+ explorer: Explorer;
20
20
  };
21
21
  screencastPage: any;
22
22
  screencastActive: boolean;
@@ -37,9 +37,10 @@ declare const HistorianBase: {
37
37
  new (...args: any[]): {
38
38
  playwright: {
39
39
  recorder: PlaywrightRecorder;
40
- helper: any;
40
+ explorer: Explorer;
41
41
  };
42
42
  savedFiles: Set<string>;
43
+ stateManager?: StateManager;
43
44
  toPlaywrightCode(conversation: import("./conversation.js").Conversation, scenario: string): Promise<string>;
44
45
  savePlaywrightPlanToFile(plan: Plan): string;
45
46
  getPlaywrightKnowledgeLines(url: string, indent?: string): string[];
@@ -47,6 +48,7 @@ declare const HistorianBase: {
47
48
  } & {
48
49
  new (...args: any[]): {
49
50
  savedFiles: Set<string>;
51
+ stateManager?: StateManager;
50
52
  toCode(conversation: import("./conversation.js").Conversation, scenario: string): string;
51
53
  saveCodeceptPlanToFile(plan: Plan): string;
52
54
  getKnowledgeLines(url: string, indent?: string): string[];
@@ -90,19 +92,19 @@ export declare class Historian extends HistorianBase {
90
92
  config: ExplorbotConfig | undefined;
91
93
  playwright: {
92
94
  recorder: PlaywrightRecorder;
93
- helper: any;
95
+ explorer: Explorer;
94
96
  } | undefined;
95
97
  savedFiles: Set<string>;
96
- constructor(provider: Provider, experienceTracker?: ExperienceTracker, reporter?: Reporter, stateManager?: StateManager, config?: ExplorbotConfig, playwright?: {
98
+ constructor(provider: Provider, experienceTracker: ExperienceTracker, reporter?: Reporter, stateManager?: StateManager, config?: ExplorbotConfig, playwright?: {
97
99
  recorder: PlaywrightRecorder;
98
- helper: any;
100
+ explorer: Explorer;
99
101
  });
100
102
  isPlaywrightFramework(): boolean;
101
103
  getSavedFiles(): string[];
102
104
  savePlanToFile(plan: Plan): string;
103
105
  rewriteScenarioInFile(filePath: string, healedSteps: Array<{
104
- test: string;
105
106
  original: string;
106
107
  healed: string;
107
108
  }>): void;
108
109
  }
110
+ export {};
@@ -1,18 +1,16 @@
1
1
  import { readFileSync, writeFileSync } from 'node:fs';
2
- import { ExperienceTracker } from "../experience-tracker.js";
3
2
  import { tag } from "../utils/logger.js";
4
3
  import { relativeToCwd } from "../utils/next-steps.js";
5
4
  import { WithCodeceptJS } from "./historian/codeceptjs.js";
6
5
  import { WithExperience } from "./historian/experience.js";
7
6
  import { WithPlaywright } from "./historian/playwright.js";
8
7
  import { WithScreencast } from "./historian/screencast.js";
9
- export { isNonReusableCode } from "../utils/step-analyzer.js";
10
8
  const HistorianBase = WithScreencast(WithPlaywright(WithCodeceptJS(WithExperience(Object))));
11
9
  export class Historian extends HistorianBase {
12
10
  constructor(provider, experienceTracker, reporter, stateManager, config, playwright) {
13
11
  super();
14
12
  this.provider = provider;
15
- this.experienceTracker = experienceTracker || new ExperienceTracker();
13
+ this.experienceTracker = experienceTracker;
16
14
  this.reporter = reporter;
17
15
  this.stateManager = stateManager;
18
16
  this.config = config;
@@ -32,8 +30,6 @@ export class Historian extends HistorianBase {
32
30
  rewriteScenarioInFile(filePath, healedSteps) {
33
31
  let content = readFileSync(filePath, 'utf-8');
34
32
  for (const step of healedSteps) {
35
- if (!content.includes(step.original))
36
- continue;
37
33
  content = content.replace(step.original, step.healed);
38
34
  }
39
35
  writeFileSync(filePath, content);
@@ -1,16 +1,16 @@
1
1
  import { ActionResult } from '../action-result.js';
2
2
  import type Action from '../action.js';
3
- import { ExperienceTracker } from '../experience-tracker.js';
3
+ import type { ExplorbotConfig } from '../config.js';
4
+ import type { ExperienceTracker } from '../experience-tracker.js';
4
5
  import Explorer from '../explorer.js';
5
- import { KnowledgeTracker } from '../knowledge-tracker.js';
6
+ import type { KnowledgeTracker } from '../knowledge-tracker.js';
7
+ import { type StateManager } from '../state-manager.js';
6
8
  import { HooksRunner } from '../utils/hooks-runner.js';
7
- import type { Agent } from './agent.js';
8
- import { ExperienceCompactor } from './experience-compactor.js';
9
+ import type { Agent, AgentDeps } from './agent.js';
9
10
  import type { Provider } from './provider.js';
10
11
  declare class Navigator implements Agent {
11
12
  emoji: string;
12
13
  provider: Provider;
13
- experienceCompactor: ExperienceCompactor;
14
14
  knowledgeTracker: KnowledgeTracker;
15
15
  experienceTracker: ExperienceTracker;
16
16
  hooksRunner: HooksRunner;
@@ -18,7 +18,9 @@ declare class Navigator implements Agent {
18
18
  systemPrompt: string;
19
19
  freeSailSystemPrompt: string;
20
20
  explorer: Explorer;
21
- constructor(explorer: Explorer, provider: Provider, experienceCompactor: ExperienceCompactor, experienceTracker?: ExperienceTracker);
21
+ config: ExplorbotConfig;
22
+ stateManager: StateManager;
23
+ constructor(deps: AgentDeps);
22
24
  get verifyAttempts(): number;
23
25
  get verifyTimeout(): number;
24
26
  getBaseOrigin(): string | null;
@@ -2,8 +2,6 @@ import { tool } from 'ai';
2
2
  import dedent from 'dedent';
3
3
  import { z } from 'zod';
4
4
  import { ActionResult } from '../action-result.js';
5
- import { ExperienceTracker, renderExperienceToc } from '../experience-tracker.js';
6
- import { KnowledgeTracker } from '../knowledge-tracker.js';
7
5
  import { normalizeUrl } from '../state-manager.js';
8
6
  import { extractCodeBlocks } from '../utils/code-extractor.js';
9
7
  import { HooksRunner } from "../utils/hooks-runner.js";
@@ -14,12 +12,11 @@ import { extractStatePath } from '../utils/url-matcher.js';
14
12
  import { Researcher } from "./researcher.js";
15
13
  import { actionRule, locatorRule, unexpectedPopupRule } from './rules.js';
16
14
  import { isInteractive } from './task-agent.js';
17
- import { createAgentTools } from "./tools.js";
15
+ import { createLearnExperienceTool } from "./tools.js";
18
16
  const debugLog = createDebug('explorbot:navigator');
19
17
  class Navigator {
20
18
  emoji = '🧭';
21
19
  provider;
22
- experienceCompactor;
23
20
  knowledgeTracker;
24
21
  experienceTracker;
25
22
  hooksRunner;
@@ -62,22 +59,25 @@ class Navigator {
62
59
  </rules>
63
60
  `;
64
61
  explorer;
65
- constructor(explorer, provider, experienceCompactor, experienceTracker) {
66
- this.provider = provider;
67
- this.explorer = explorer;
68
- this.experienceCompactor = experienceCompactor;
69
- this.knowledgeTracker = new KnowledgeTracker();
70
- this.experienceTracker = experienceTracker || new ExperienceTracker();
71
- this.hooksRunner = new HooksRunner(explorer, explorer.getConfig());
62
+ config;
63
+ stateManager;
64
+ constructor(deps) {
65
+ this.provider = deps.ai;
66
+ this.explorer = deps.explorer;
67
+ this.config = deps.config;
68
+ this.stateManager = deps.stateManager;
69
+ this.knowledgeTracker = deps.knowledgeTracker;
70
+ this.experienceTracker = deps.stateManager.getExperienceTracker();
71
+ this.hooksRunner = new HooksRunner(deps.explorer, deps.config);
72
72
  }
73
73
  get verifyAttempts() {
74
- return this.explorer.getConfig().ai?.agents?.navigator?.verifyAttempts ?? 3;
74
+ return this.config.ai?.agents?.navigator?.verifyAttempts ?? 3;
75
75
  }
76
76
  get verifyTimeout() {
77
- return this.explorer.getConfig().ai?.agents?.navigator?.verifyTimeout ?? 1500;
77
+ return this.config.ai?.agents?.navigator?.verifyTimeout ?? 1500;
78
78
  }
79
79
  getBaseOrigin() {
80
- const baseUrl = this.explorer.getConfig().playwright.url;
80
+ const baseUrl = this.config.playwright.url;
81
81
  try {
82
82
  return new URL(baseUrl).origin;
83
83
  }
@@ -121,11 +121,11 @@ class Navigator {
121
121
  return normalizeUrl(currentUrl) === normalizeUrl(expectedUrl);
122
122
  }
123
123
  async visit(url) {
124
- return this.explorer.runWithBrowserRecovery('navigator.visit', () => this.visitOnce(url));
124
+ return this.visitOnce(url);
125
125
  }
126
126
  async visitOnce(url) {
127
127
  try {
128
- const action = this.explorer.createAction();
128
+ const action = this.explorer.action();
129
129
  await action.execute(`I.amOnPage('${url}')`);
130
130
  const currentUrl = action.stateManager.getCurrentState()?.url || '';
131
131
  if (currentUrl === 'about:blank' || currentUrl === '') {
@@ -153,7 +153,7 @@ class Navigator {
153
153
  throw new Error(`Navigation to ${url} failed: ${action.lastError?.message}`);
154
154
  }
155
155
  }
156
- await this.explorer.capturePageWithScreenshot();
156
+ await this.explorer.capture({ screenshot: true });
157
157
  await this.hooksRunner.runAfterHook('navigator', url);
158
158
  }
159
159
  catch (error) {
@@ -169,19 +169,10 @@ class Navigator {
169
169
  async resolveState(message, actionResult, opts) {
170
170
  tag('info').log('AI Navigator resolving state at', actionResult.url);
171
171
  debugLog('Resolution message:', message);
172
- const action = opts?.action ?? this.explorer.createAction();
172
+ const action = opts?.action ?? this.explorer.action();
173
173
  const expectedUrl = opts?.expectedUrl;
174
- let knowledge = '';
174
+ const knowledge = this.knowledgeTracker.renderRelevantKnowledge(actionResult);
175
175
  let experience = '';
176
- const relevantKnowledge = this.knowledgeTracker.getRelevantKnowledge(actionResult);
177
- if (relevantKnowledge.length > 0) {
178
- const knowledgeContent = relevantKnowledge.map((k) => k.content).join('\n\n');
179
- knowledge = `
180
- <hint>
181
- Here is relevant knowledge for this page:
182
- ${knowledgeContent}
183
- </hint>`;
184
- }
185
176
  if (!actionResult.isInsideIframe) {
186
177
  const successful = this.experienceTracker.getSuccessfulExperience(actionResult);
187
178
  if (successful.length > 0) {
@@ -323,7 +314,7 @@ class Navigator {
323
314
  }
324
315
  codeBlockIndex++;
325
316
  totalAttempts++;
326
- await this.explorer.switchToMainFrame();
317
+ await action.exitIframe();
327
318
  const prevActionResult = action.actionResult ?? actionResult;
328
319
  const prevHash = prevActionResult.getStateHash();
329
320
  debugLog(`Attempting resolution: ${codeBlock}`);
@@ -352,7 +343,7 @@ class Navigator {
352
343
  // URL did not transition to expectedUrl within timeout
353
344
  }
354
345
  }
355
- const freshState = await this.explorer.capturePageState();
346
+ const freshState = await this.explorer.capture();
356
347
  const currentUrl = /^https?:\/\//i.test(expectedUrl) ? freshState.fullUrl || freshState.url || '' : freshState.url || '';
357
348
  const urlMatches = this.isSameExpectedOrigin(expectedUrl, action.stateManager) && normalizeUrl(currentUrl) === normalizeUrl(expectedUrl);
358
349
  const stateChanged = freshState.getStateHash() !== actionResult.getStateHash();
@@ -362,7 +353,6 @@ class Navigator {
362
353
  if (freshState.getStateHash() !== prevHash) {
363
354
  try {
364
355
  const diff = await freshState.diff(prevActionResult);
365
- await diff.calculate();
366
356
  ariaChanges = diff.ariaChanged;
367
357
  }
368
358
  catch (err) {
@@ -446,24 +436,17 @@ class Navigator {
446
436
  return resolved;
447
437
  }
448
438
  buildExperienceTools() {
449
- const stateManager = this.explorer.getStateManager();
439
+ if (!this.experienceTracker)
440
+ return undefined;
441
+ const stateManager = this.stateManager;
450
442
  const getState = () => {
451
443
  const s = stateManager.getCurrentState();
452
444
  return s ? ActionResult.fromState(s) : null;
453
445
  };
454
- const { learnExperience } = createAgentTools({
455
- explorer: this.explorer,
456
- researcher: null,
457
- navigator: this,
458
- experienceTracker: this.experienceTracker,
459
- getState,
460
- });
461
- if (!learnExperience)
462
- return undefined;
463
- return { learnExperience };
446
+ return { learnExperience: createLearnExperienceTool({ getExperienceTracker: () => this.experienceTracker, getState }) };
464
447
  }
465
448
  async freeSail(opts, actionResult) {
466
- const stateManager = this.explorer.getStateManager();
449
+ const stateManager = this.stateManager;
467
450
  const state = stateManager.getCurrentState();
468
451
  if (!state) {
469
452
  return null;
@@ -579,24 +562,10 @@ class Navigator {
579
562
  tag('operation').log(`Reusing cached verification: ${cachedVerification ? 'PASS' : 'FAIL'}`);
580
563
  return { verified: cachedVerification, successfulCodes: [], assertionSteps: [], totalAttempted: 0 };
581
564
  }
582
- let knowledge = '';
565
+ const knowledge = this.knowledgeTracker.renderRelevantKnowledge(actionResult);
583
566
  let experience = '';
584
- const relevantKnowledge = this.knowledgeTracker.getRelevantKnowledge(actionResult);
585
- if (relevantKnowledge.length > 0) {
586
- const knowledgeContent = relevantKnowledge.map((k) => k.content).join('\n\n');
587
- knowledge = `
588
- <hint>
589
- Here is relevant knowledge for this page:
590
- ${knowledgeContent}
591
- </hint>`;
592
- }
593
567
  if (!actionResult.isInsideIframe) {
594
- const toc = this.experienceTracker.getExperienceTableOfContents(actionResult);
595
- if (toc.length > 0) {
596
- const totalSections = toc.reduce((sum, entry) => sum + entry.sections.length, 0);
597
- tag('operation').log(`Found ${toc.length} experience ${pluralize(toc.length, 'file')} (${totalSections} sections) for: ${actionResult.url}`);
598
- experience = renderExperienceToc(toc);
599
- }
568
+ experience = this.experienceTracker.renderExperienceTocFor(actionResult);
600
569
  }
601
570
  const priorVerifications = Object.entries(actionResult.verifications ?? {});
602
571
  let verificationContext = '';
@@ -655,10 +624,10 @@ class Navigator {
655
624
  let codeBlocks = [];
656
625
  const successfulCodes = [];
657
626
  const assertionSteps = [];
658
- const action = this.explorer.createAction();
627
+ const action = this.explorer.action();
659
628
  let failures = 0;
660
- const page = this.explorer.playwrightHelper?.page;
661
- const originalTimeout = this.explorer.playwrightHelper?.options?.timeout ?? 3000;
629
+ const page = this.explorer.page;
630
+ const originalTimeout = this.config.playwright.timeout ?? 3000;
662
631
  page?.setDefaultTimeout(this.verifyTimeout);
663
632
  try {
664
633
  await loop(async ({ stop, iteration }) => {
@@ -684,8 +653,8 @@ class Navigator {
684
653
  stop();
685
654
  return;
686
655
  }
687
- await this.explorer.switchToMainFrame();
688
- const verified = await action.attempt(codeBlock, message, false);
656
+ await action.exitIframe();
657
+ const verified = await action.attempt(codeBlock, message);
689
658
  if (verified) {
690
659
  tag('success').log('Verification passed');
691
660
  successfulCodes.push(codeBlock);
@@ -718,7 +687,7 @@ class Navigator {
718
687
  if (alreadyVerified)
719
688
  verified = true;
720
689
  actionResult.addVerification(message, verified);
721
- this.explorer.getStateManager().updateState(actionResult);
690
+ this.stateManager.updateState(actionResult);
722
691
  return { verified, successfulCodes, assertionSteps, totalAttempted };
723
692
  }
724
693
  checkAlreadyVerified(aiResponse, actionResult) {
@@ -1,8 +1,10 @@
1
1
  import { ActionResult } from '../action-result.js';
2
- import { type ExperienceTracker } from '../experience-tracker.js';
2
+ import type { RequestStore } from '../api/request-store.js';
3
3
  import type Explorer from '../explorer.js';
4
+ import type { PlaywrightRecorder } from '../playwright-recorder.js';
5
+ import type { StateManager } from '../state-manager.js';
4
6
  import { type Test } from '../test-plan.js';
5
- import type { Agent } from './agent.js';
7
+ import type { Agent, AgentDeps } from './agent.js';
6
8
  import type { Conversation } from './conversation.js';
7
9
  import type { Fisherman } from './fisherman.js';
8
10
  import type { Navigator } from './navigator.js';
@@ -15,9 +17,11 @@ export declare class Pilot implements Agent {
15
17
  conversation: Conversation | null;
16
18
  researcher: Researcher;
17
19
  explorer: Explorer;
20
+ stateManager: StateManager;
21
+ requestStore: RequestStore;
22
+ playwrightRecorder: PlaywrightRecorder;
18
23
  fisherman: Fisherman | null;
19
- experienceTracker: ExperienceTracker | null;
20
- constructor(provider: Provider, agentTools: any, researcher: Researcher, explorer: Explorer, experienceTracker?: ExperienceTracker);
24
+ constructor(deps: AgentDeps, agentTools: any, researcher: Researcher);
21
25
  setFisherman(fisherman: Fisherman): void;
22
26
  get stepsToReview(): number;
23
27
  reset(): void;
@@ -29,17 +33,18 @@ export declare class Pilot implements Agent {
29
33
  reviewReset(task: Test, currentState: ActionResult, reason: string, testerConversation: Conversation): Promise<boolean>;
30
34
  reviewDecision(type: 'finish' | 'stop', task: Test, currentState: ActionResult, testerConversation: Conversation, navigator?: Navigator): Promise<boolean>;
31
35
  reviewResetDecision(task: Test, currentState: ActionResult, reason: string, testerConversation: Conversation): Promise<boolean>;
32
- buildSharedEvidenceRules(task: Test): string;
36
+ buildSharedEvidenceRules(): string;
37
+ buildTaskContext(task: Test): string;
33
38
  buildResetSystemPrompt(task: Test): string;
34
- buildVerdictSystemPrompt(type: string, task: Test): string;
39
+ buildVerdictSystemPrompt(task: Test): string;
35
40
  planTest(task: Test, currentState: ActionResult): Promise<string>;
36
41
  reviewNewPage(task: Test, currentState: ActionResult, testerConversation: Conversation): Promise<string>;
37
42
  analyzeProgress(task: Test, currentState: ActionResult, testerConversation: Conversation): Promise<string>;
38
43
  formatExpectations(task: Test): string;
39
- sendToPilot(userText: string, functionId: string, opts?: {
44
+ sendToPilot(userText: string, functionId: string, opts: {
40
45
  tools?: boolean;
41
46
  maxToolRoundtrips?: number;
42
- task?: Test;
47
+ task: Test;
43
48
  }): Promise<string>;
44
49
  getExperienceToc(): string;
45
50
  pickPlanningTools(): Record<string, unknown>;