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.
- package/README.md +35 -19
- package/bin/explorbot-cli.ts +33 -10
- package/boat/api-tester/src/config.ts +45 -3
- package/boat/doc-collector/src/ai/documentarian.ts +26 -28
- package/boat/doc-collector/src/ai/tools.ts +74 -16
- package/boat/doc-collector/src/cli.ts +1 -6
- package/boat/doc-collector/src/docbot.ts +30 -9
- package/boat/doc-collector/src/docs-renderer.ts +19 -24
- package/boat/doc-collector/src/screenshots.ts +34 -2
- package/boat/doc-collector/src/state-diagram.ts +281 -0
- package/dist/bin/explorbot-cli.js +29 -9
- package/dist/boat/api-tester/src/config.js +43 -4
- package/dist/boat/doc-collector/src/ai/documentarian.js +19 -7
- package/dist/boat/doc-collector/src/ai/tools.js +53 -16
- package/dist/boat/doc-collector/src/cli.js +1 -5
- package/dist/boat/doc-collector/src/docbot.js +27 -8
- package/dist/boat/doc-collector/src/docs-renderer.js +18 -3
- package/dist/boat/doc-collector/src/screenshots.js +30 -1
- package/dist/boat/doc-collector/src/state-diagram.js +200 -0
- package/dist/models.json +30 -0
- package/dist/package.json +23 -3
- package/dist/src/action-result.d.ts +8 -10
- package/dist/src/action-result.js +72 -164
- package/dist/src/action.d.ts +13 -12
- package/dist/src/action.js +37 -113
- package/dist/src/ai/agent.d.ts +17 -0
- package/dist/src/ai/captain/idle-mode.js +1 -1
- package/dist/src/ai/captain/test-mode.js +1 -1
- package/dist/src/ai/captain/web-mode.js +18 -29
- package/dist/src/ai/captain.d.ts +1 -3
- package/dist/src/ai/captain.js +17 -45
- package/dist/src/ai/conversation.d.ts +2 -5
- package/dist/src/ai/conversation.js +9 -28
- package/dist/src/ai/driller.d.ts +2 -17
- package/dist/src/ai/driller.js +26 -50
- package/dist/src/ai/experience-compactor.d.ts +2 -2
- package/dist/src/ai/experience-compactor.js +16 -33
- package/dist/src/ai/fisherman-tools.js +1 -1
- package/dist/src/ai/fisherman.d.ts +0 -1
- package/dist/src/ai/fisherman.js +0 -3
- package/dist/src/ai/historian/codeceptjs.d.ts +2 -0
- package/dist/src/ai/historian/codeceptjs.js +4 -3
- package/dist/src/ai/historian/playwright.d.ts +4 -1
- package/dist/src/ai/historian/playwright.js +4 -3
- package/dist/src/ai/historian/screencast.d.ts +2 -1
- package/dist/src/ai/historian/screencast.js +2 -2
- package/dist/src/ai/historian/utils.d.ts +0 -1
- package/dist/src/ai/historian/utils.js +0 -1
- package/dist/src/ai/historian.d.ts +10 -8
- package/dist/src/ai/historian.js +1 -5
- package/dist/src/ai/navigator.d.ts +8 -6
- package/dist/src/ai/navigator.js +34 -65
- package/dist/src/ai/pilot.d.ts +13 -8
- package/dist/src/ai/pilot.js +53 -59
- package/dist/src/ai/planner.d.ts +5 -4
- package/dist/src/ai/planner.js +66 -52
- package/dist/src/ai/provider.d.ts +4 -1
- package/dist/src/ai/provider.js +77 -137
- package/dist/src/ai/quartermaster.d.ts +22 -22
- package/dist/src/ai/quartermaster.js +8 -14
- package/dist/src/ai/rerunner.d.ts +3 -13
- package/dist/src/ai/rerunner.js +23 -44
- package/dist/src/ai/researcher/cache.js +11 -18
- package/dist/src/ai/researcher/coordinates.js +4 -3
- package/dist/src/ai/researcher/deep-analysis.d.ts +2 -0
- package/dist/src/ai/researcher/deep-analysis.js +8 -11
- package/dist/src/ai/researcher/locators.d.ts +9 -2
- package/dist/src/ai/researcher/locators.js +65 -8
- package/dist/src/ai/researcher/parser.js +1 -1
- package/dist/src/ai/researcher/research-result.d.ts +0 -1
- package/dist/src/ai/researcher/research-result.js +0 -19
- package/dist/src/ai/researcher/sections.d.ts +2 -0
- package/dist/src/ai/researcher/sections.js +7 -3
- package/dist/src/ai/researcher.js +40 -106
- package/dist/src/ai/rules.d.ts +1 -0
- package/dist/src/ai/rules.js +22 -15
- package/dist/src/ai/session-analyst.js +8 -5
- package/dist/src/ai/task-agent.d.ts +19 -6
- package/dist/src/ai/task-agent.js +37 -33
- package/dist/src/ai/tester.d.ts +6 -14
- package/dist/src/ai/tester.js +46 -111
- package/dist/src/ai/tools.d.ts +26 -14
- package/dist/src/ai/tools.js +138 -132
- package/dist/src/command-handler.js +1 -1
- package/dist/src/commands/compact-command.d.ts +1 -1
- package/dist/src/commands/compact-command.js +6 -6
- package/dist/src/commands/context-aria-command.js +1 -1
- package/dist/src/commands/context-command.js +8 -6
- package/dist/src/commands/context-data-command.js +2 -2
- package/dist/src/commands/context-experience-command.js +2 -2
- package/dist/src/commands/context-html-command.js +2 -2
- package/dist/src/commands/context-knowledge-command.js +2 -2
- package/dist/src/commands/drill-command.js +1 -1
- package/dist/src/commands/experience-command.js +1 -1
- package/dist/src/commands/explore-command.js +4 -3
- package/dist/src/commands/freesail-command.js +2 -2
- package/dist/src/commands/knows-command.js +1 -1
- package/dist/src/commands/learn-command.js +5 -3
- package/dist/src/commands/path-command.js +1 -1
- package/dist/src/commands/research-command.js +1 -1
- package/dist/src/commands/test-command.js +1 -1
- package/dist/src/components/AddKnowledge.d.ts +2 -0
- package/dist/src/components/AddKnowledge.js +3 -7
- package/dist/src/components/App.js +3 -3
- package/dist/src/config.d.ts +19 -0
- package/dist/src/config.js +156 -10
- package/dist/src/experience-tracker.d.ts +11 -6
- package/dist/src/experience-tracker.js +82 -155
- package/dist/src/explorbot.d.ts +21 -13
- package/dist/src/explorbot.js +84 -80
- package/dist/src/explorer.d.ts +66 -102
- package/dist/src/explorer.js +332 -623
- package/dist/src/knowledge-tracker.d.ts +2 -2
- package/dist/src/knowledge-tracker.js +38 -45
- package/dist/src/state-manager.d.ts +10 -30
- package/dist/src/state-manager.js +11 -129
- package/dist/src/utils/aria.d.ts +6 -1
- package/dist/src/utils/aria.js +4 -1
- package/dist/src/utils/cache.d.ts +15 -0
- package/dist/src/utils/cache.js +34 -0
- package/dist/src/utils/context-formatter.d.ts +6 -0
- package/dist/src/utils/context-formatter.js +15 -27
- package/dist/src/utils/hooks-runner.js +2 -4
- package/dist/src/utils/html.d.ts +5 -0
- package/dist/src/utils/html.js +71 -0
- package/dist/src/utils/markdown-files.d.ts +10 -0
- package/dist/src/utils/markdown-files.js +21 -0
- package/dist/src/utils/markdown-query.d.ts +6 -0
- package/dist/src/utils/markdown-query.js +14 -1
- package/dist/src/utils/page-readiness.d.ts +1 -0
- package/dist/src/utils/page-readiness.js +1 -1
- package/dist/src/utils/secrets.js +2 -2
- package/dist/src/utils/strings.d.ts +2 -0
- package/dist/src/utils/strings.js +10 -0
- package/dist/src/utils/test-files.js +1 -1
- package/dist/src/utils/web-annotate.d.ts +5 -0
- package/dist/src/utils/web-annotate.js +58 -0
- package/dist/src/utils/web-eidx.d.ts +2 -0
- package/dist/src/utils/web-eidx.js +20 -0
- package/dist/src/utils/web-element.d.ts +3 -1
- package/dist/src/utils/web-element.js +32 -0
- package/dist/src/utils/web-sandbox.d.ts +4 -0
- package/dist/src/utils/web-sandbox.js +37 -0
- package/models.json +30 -0
- package/package.json +23 -3
- package/src/action-result.ts +70 -173
- package/src/action.ts +38 -132
- package/src/ai/agent.ts +20 -0
- package/src/ai/captain/idle-mode.ts +1 -1
- package/src/ai/captain/test-mode.ts +1 -1
- package/src/ai/captain/web-mode.ts +18 -30
- package/src/ai/captain.ts +17 -42
- package/src/ai/conversation.ts +9 -32
- package/src/ai/driller.ts +53 -83
- package/src/ai/experience-compactor.ts +16 -35
- package/src/ai/fisherman-tools.ts +1 -1
- package/src/ai/fisherman.ts +0 -4
- package/src/ai/historian/codeceptjs.ts +5 -3
- package/src/ai/historian/playwright.ts +7 -4
- package/src/ai/historian/screencast.ts +4 -3
- package/src/ai/historian/utils.ts +0 -1
- package/src/ai/historian.ts +6 -8
- package/src/ai/navigator.ts +39 -70
- package/src/ai/pilot.ts +59 -61
- package/src/ai/planner.ts +76 -62
- package/src/ai/provider.ts +85 -146
- package/src/ai/quartermaster.ts +39 -45
- package/src/ai/rerunner.ts +27 -50
- package/src/ai/researcher/cache.ts +10 -16
- package/src/ai/researcher/coordinates.ts +4 -3
- package/src/ai/researcher/deep-analysis.ts +10 -11
- package/src/ai/researcher/locators.ts +66 -9
- package/src/ai/researcher/parser.ts +1 -1
- package/src/ai/researcher/research-result.ts +0 -18
- package/src/ai/researcher/sections.ts +9 -3
- package/src/ai/researcher.ts +42 -119
- package/src/ai/rules.ts +24 -13
- package/src/ai/session-analyst.ts +8 -5
- package/src/ai/task-agent.ts +45 -38
- package/src/ai/tester.ts +51 -129
- package/src/ai/tools.ts +145 -153
- package/src/command-handler.ts +1 -1
- package/src/commands/compact-command.ts +7 -8
- package/src/commands/context-aria-command.ts +1 -1
- package/src/commands/context-command.ts +8 -6
- package/src/commands/context-data-command.ts +2 -2
- package/src/commands/context-experience-command.ts +2 -2
- package/src/commands/context-html-command.ts +2 -2
- package/src/commands/context-knowledge-command.ts +2 -2
- package/src/commands/drill-command.ts +1 -1
- package/src/commands/experience-command.ts +1 -1
- package/src/commands/explore-command.ts +4 -3
- package/src/commands/freesail-command.ts +2 -2
- package/src/commands/knows-command.ts +1 -1
- package/src/commands/learn-command.ts +5 -3
- package/src/commands/path-command.ts +1 -1
- package/src/commands/research-command.ts +1 -1
- package/src/commands/test-command.ts +1 -1
- package/src/components/AddKnowledge.tsx +5 -7
- package/src/components/App.tsx +3 -3
- package/src/config.ts +185 -11
- package/src/experience-tracker.ts +89 -152
- package/src/explorbot.ts +88 -83
- package/src/explorer.ts +402 -693
- package/src/knowledge-tracker.ts +42 -49
- package/src/state-manager.ts +20 -155
- package/src/utils/aria.ts +11 -2
- package/src/utils/cache.ts +40 -0
- package/src/utils/context-formatter.ts +12 -15
- package/src/utils/hooks-runner.ts +2 -4
- package/src/utils/html.ts +79 -0
- package/src/utils/markdown-files.ts +30 -0
- package/src/utils/markdown-query.ts +15 -1
- package/src/utils/page-readiness.ts +1 -1
- package/src/utils/secrets.ts +2 -3
- package/src/utils/strings.ts +12 -0
- package/src/utils/test-files.ts +1 -1
- package/src/utils/web-annotate.ts +64 -0
- package/src/utils/web-eidx.ts +21 -0
- package/src/utils/web-element.ts +34 -0
- package/src/utils/web-sandbox.ts +43 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
95
|
+
explorer: Explorer;
|
|
94
96
|
} | undefined;
|
|
95
97
|
savedFiles: Set<string>;
|
|
96
|
-
constructor(provider: Provider, experienceTracker
|
|
98
|
+
constructor(provider: Provider, experienceTracker: ExperienceTracker, reporter?: Reporter, stateManager?: StateManager, config?: ExplorbotConfig, playwright?: {
|
|
97
99
|
recorder: PlaywrightRecorder;
|
|
98
|
-
|
|
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 {};
|
package/dist/src/ai/historian.js
CHANGED
|
@@ -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
|
|
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 {
|
|
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
|
-
|
|
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;
|
package/dist/src/ai/navigator.js
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
this.
|
|
69
|
-
this.
|
|
70
|
-
this.
|
|
71
|
-
this.
|
|
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.
|
|
74
|
+
return this.config.ai?.agents?.navigator?.verifyAttempts ?? 3;
|
|
75
75
|
}
|
|
76
76
|
get verifyTimeout() {
|
|
77
|
-
return this.
|
|
77
|
+
return this.config.ai?.agents?.navigator?.verifyTimeout ?? 1500;
|
|
78
78
|
}
|
|
79
79
|
getBaseOrigin() {
|
|
80
|
-
const baseUrl = this.
|
|
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.
|
|
124
|
+
return this.visitOnce(url);
|
|
125
125
|
}
|
|
126
126
|
async visitOnce(url) {
|
|
127
127
|
try {
|
|
128
|
-
const action = this.explorer.
|
|
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.
|
|
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.
|
|
172
|
+
const action = opts?.action ?? this.explorer.action();
|
|
173
173
|
const expectedUrl = opts?.expectedUrl;
|
|
174
|
-
|
|
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
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
|
|
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.
|
|
627
|
+
const action = this.explorer.action();
|
|
659
628
|
let failures = 0;
|
|
660
|
-
const page = this.explorer.
|
|
661
|
-
const originalTimeout = this.
|
|
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
|
|
688
|
-
const verified = await action.attempt(codeBlock, message
|
|
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.
|
|
690
|
+
this.stateManager.updateState(actionResult);
|
|
722
691
|
return { verified, successfulCodes, assertionSteps, totalAttempted };
|
|
723
692
|
}
|
|
724
693
|
checkAlreadyVerified(aiResponse, actionResult) {
|
package/dist/src/ai/pilot.d.ts
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { ActionResult } from '../action-result.js';
|
|
2
|
-
import {
|
|
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
|
-
|
|
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(
|
|
36
|
+
buildSharedEvidenceRules(): string;
|
|
37
|
+
buildTaskContext(task: Test): string;
|
|
33
38
|
buildResetSystemPrompt(task: Test): string;
|
|
34
|
-
buildVerdictSystemPrompt(
|
|
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
|
|
47
|
+
task: Test;
|
|
43
48
|
}): Promise<string>;
|
|
44
49
|
getExperienceToc(): string;
|
|
45
50
|
pickPlanningTools(): Record<string, unknown>;
|