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
package/src/explorbot.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import {
|
|
3
|
+
import type { AgentDeps } from './ai/agent.ts';
|
|
4
4
|
import { Captain } from './ai/captain.ts';
|
|
5
5
|
import { Driller } from './ai/driller.ts';
|
|
6
6
|
import { ExperienceCompactor } from './ai/experience-compactor.ts';
|
|
@@ -24,10 +24,13 @@ import { ConfigParser } from './config.ts';
|
|
|
24
24
|
import { ExperienceTracker } from './experience-tracker.ts';
|
|
25
25
|
import Explorer from './explorer.ts';
|
|
26
26
|
import { KnowledgeTracker } from './knowledge-tracker.ts';
|
|
27
|
-
import {
|
|
27
|
+
import { PlaywrightRecorder } from './playwright-recorder.ts';
|
|
28
|
+
import { Reporter } from './reporter.ts';
|
|
29
|
+
import { StateManager, WebPageState } from './state-manager.ts';
|
|
28
30
|
import { Stats } from './stats.ts';
|
|
29
31
|
import type { Suite } from './suite.ts';
|
|
30
32
|
import { Plan, type Test } from './test-plan.ts';
|
|
33
|
+
import { browserErrorMessage } from './utils/browser-errors.ts';
|
|
31
34
|
import { setVerboseMode, tag } from './utils/logger.ts';
|
|
32
35
|
import { relativeToCwd } from './utils/next-steps.ts';
|
|
33
36
|
import { sanitizeFilename } from './utils/strings.ts';
|
|
@@ -42,7 +45,7 @@ export interface ExplorBotOptions {
|
|
|
42
45
|
show?: boolean;
|
|
43
46
|
headless?: boolean;
|
|
44
47
|
incognito?: boolean;
|
|
45
|
-
session?: string;
|
|
48
|
+
session?: string | boolean;
|
|
46
49
|
}
|
|
47
50
|
|
|
48
51
|
export type UserResolveFunction = (error?: Error, showWelcome?: boolean) => Promise<string | null>;
|
|
@@ -54,7 +57,6 @@ export class ExplorBot {
|
|
|
54
57
|
private config!: ExplorbotConfig;
|
|
55
58
|
private options: ExplorBotOptions;
|
|
56
59
|
private userResolveFn: UserResolveFunction | null = null;
|
|
57
|
-
public needsInput = false;
|
|
58
60
|
private currentPlan?: Plan;
|
|
59
61
|
private planFeature?: string;
|
|
60
62
|
lastPlanError: Error | null = null;
|
|
@@ -62,6 +64,12 @@ export class ExplorBot {
|
|
|
62
64
|
private agents: Record<string, any> = {};
|
|
63
65
|
private sessionPlans: Plan[] = [];
|
|
64
66
|
private lastReportedTestCount = 0;
|
|
67
|
+
private _experienceTracker?: ExperienceTracker;
|
|
68
|
+
private _knowledgeTracker?: KnowledgeTracker;
|
|
69
|
+
private _stateManager?: StateManager;
|
|
70
|
+
private _reporter?: Reporter;
|
|
71
|
+
private _requestStore?: RequestStore;
|
|
72
|
+
private _playwrightRecorder?: PlaywrightRecorder;
|
|
65
73
|
|
|
66
74
|
constructor(options: ExplorBotOptions = {}) {
|
|
67
75
|
this.options = options;
|
|
@@ -73,7 +81,7 @@ export class ExplorBot {
|
|
|
73
81
|
}
|
|
74
82
|
|
|
75
83
|
get isExploring(): boolean {
|
|
76
|
-
return this.explorer
|
|
84
|
+
return !!this.explorer;
|
|
77
85
|
}
|
|
78
86
|
|
|
79
87
|
setUserResolve(fn: UserResolveFunction): void {
|
|
@@ -81,20 +89,26 @@ export class ExplorBot {
|
|
|
81
89
|
}
|
|
82
90
|
|
|
83
91
|
async start(): Promise<void> {
|
|
84
|
-
if (this.explorer
|
|
92
|
+
if (this.explorer) {
|
|
85
93
|
return;
|
|
86
94
|
}
|
|
87
95
|
|
|
88
96
|
try {
|
|
89
97
|
await this.startProviderOnly();
|
|
90
|
-
|
|
98
|
+
const explorerOptions = { ...this.options, session: typeof this.options.session === 'string' ? this.options.session : undefined };
|
|
99
|
+
this.explorer = new Explorer(this.config, explorerOptions, {
|
|
100
|
+
stateManager: this.stateManager(),
|
|
101
|
+
knowledgeTracker: this.knowledgeTracker(),
|
|
102
|
+
reporter: this.reporter(),
|
|
103
|
+
requestStore: this.requestStore(),
|
|
104
|
+
playwrightRecorder: this.playwrightRecorder(),
|
|
105
|
+
});
|
|
91
106
|
await this.explorer.start();
|
|
92
107
|
if (!this.options.incognito) {
|
|
93
108
|
await this.agentExperienceCompactor().autocompact();
|
|
94
109
|
}
|
|
95
|
-
if (this.userResolveFn) this.explorer.setUserResolve(this.userResolveFn);
|
|
96
110
|
} catch (error) {
|
|
97
|
-
const message =
|
|
111
|
+
const message = browserErrorMessage(error);
|
|
98
112
|
console.error('\nFailed to start:', message);
|
|
99
113
|
process.exit(1);
|
|
100
114
|
}
|
|
@@ -103,6 +117,7 @@ export class ExplorBot {
|
|
|
103
117
|
async startProviderOnly(): Promise<void> {
|
|
104
118
|
if (this.provider) return;
|
|
105
119
|
this.config = await this.configParser.loadConfig(this.options);
|
|
120
|
+
if (this.options.session === true) this.options.session = path.join(this.configParser.getOutputDir(), 'session.json');
|
|
106
121
|
this.provider = new AIProvider(this.config.ai);
|
|
107
122
|
await this.provider.validateConnection();
|
|
108
123
|
}
|
|
@@ -121,30 +136,40 @@ export class ExplorBot {
|
|
|
121
136
|
return this.agentNavigator().visit(url);
|
|
122
137
|
}
|
|
123
138
|
|
|
124
|
-
async
|
|
125
|
-
await this.explorer.
|
|
139
|
+
async openTab(): Promise<void> {
|
|
140
|
+
await this.explorer.openTab();
|
|
126
141
|
}
|
|
127
142
|
|
|
128
143
|
getCurrentState(): WebPageState | null {
|
|
129
|
-
return this.
|
|
144
|
+
return this._stateManager?.getCurrentState() ?? null;
|
|
130
145
|
}
|
|
131
146
|
|
|
132
147
|
getExplorer(): Explorer {
|
|
133
148
|
return this.explorer;
|
|
134
149
|
}
|
|
135
150
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
return this.explorer.getKnowledgeTracker();
|
|
139
|
-
}
|
|
140
|
-
return new KnowledgeTracker();
|
|
151
|
+
knowledgeTracker(): KnowledgeTracker {
|
|
152
|
+
return (this._knowledgeTracker ||= new KnowledgeTracker());
|
|
141
153
|
}
|
|
142
154
|
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
155
|
+
experienceTracker(): ExperienceTracker {
|
|
156
|
+
return (this._experienceTracker ||= new ExperienceTracker(this.knowledgeTracker()));
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
stateManager(): StateManager {
|
|
160
|
+
return (this._stateManager ||= new StateManager(this.experienceTracker(), this.knowledgeTracker()));
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
reporter(): Reporter {
|
|
164
|
+
return (this._reporter ||= new Reporter(this.config.reporter, this.stateManager()));
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
requestStore(): RequestStore {
|
|
168
|
+
return (this._requestStore ||= new RequestStore(this.configParser.getOutputDir()));
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
playwrightRecorder(): PlaywrightRecorder {
|
|
172
|
+
return (this._playwrightRecorder ||= new PlaywrightRecorder());
|
|
148
173
|
}
|
|
149
174
|
|
|
150
175
|
getConfig(): ExplorbotConfig {
|
|
@@ -154,47 +179,39 @@ export class ExplorBot {
|
|
|
154
179
|
getOptions(): ExplorBotOptions {
|
|
155
180
|
return this.options;
|
|
156
181
|
}
|
|
157
|
-
isReady(): boolean {
|
|
158
|
-
return this.explorer?.isStarted;
|
|
159
|
-
}
|
|
160
|
-
|
|
161
|
-
getConfigParser(): ConfigParser {
|
|
162
|
-
return this.configParser;
|
|
163
|
-
}
|
|
164
182
|
|
|
165
183
|
getProvider(): AIProvider {
|
|
166
184
|
return this.provider;
|
|
167
185
|
}
|
|
168
186
|
|
|
169
|
-
createAgent<T>(factory: (deps:
|
|
187
|
+
createAgent<T>(factory: (deps: AgentDeps) => T): T {
|
|
170
188
|
const agent = factory({
|
|
171
189
|
explorer: this.explorer,
|
|
172
190
|
ai: this.provider,
|
|
173
191
|
config: this.config,
|
|
192
|
+
stateManager: this.stateManager(),
|
|
193
|
+
knowledgeTracker: this.knowledgeTracker(),
|
|
194
|
+
requestStore: this.requestStore(),
|
|
195
|
+
playwrightRecorder: this.playwrightRecorder(),
|
|
174
196
|
});
|
|
175
197
|
|
|
176
|
-
const agentEmoji = (agent as any).emoji || '';
|
|
177
198
|
const agentName = (agent as any).constructor.name.toLowerCase();
|
|
178
199
|
tag('debug').log(`Created ${agentName} agent`);
|
|
179
200
|
|
|
180
|
-
// Agent is stored by the calling method using a string key
|
|
181
|
-
|
|
182
201
|
return agent;
|
|
183
202
|
}
|
|
184
203
|
|
|
185
204
|
agentResearcher(): Researcher {
|
|
186
|
-
return (this.agents.researcher ||= this.createAgent((
|
|
205
|
+
return (this.agents.researcher ||= this.createAgent((deps) => new Researcher(deps)));
|
|
187
206
|
}
|
|
188
207
|
|
|
189
208
|
agentNavigator(): Navigator {
|
|
190
|
-
return (this.agents.navigator ||= this.createAgent((
|
|
191
|
-
return new Navigator(explorer, ai, this.agentExperienceCompactor(), explorer.getStateManager().getExperienceTracker());
|
|
192
|
-
}));
|
|
209
|
+
return (this.agents.navigator ||= this.createAgent((deps) => new Navigator(deps)));
|
|
193
210
|
}
|
|
194
211
|
|
|
195
212
|
agentPlanner(): Planner {
|
|
196
213
|
if (!this.agents.planner) {
|
|
197
|
-
this.agents.planner = this.createAgent((
|
|
214
|
+
this.agents.planner = this.createAgent((deps) => new Planner(deps, this.agentResearcher()));
|
|
198
215
|
const fisherman = this.agentFisherman();
|
|
199
216
|
if (fisherman) this.agents.planner.setFisherman(fisherman);
|
|
200
217
|
}
|
|
@@ -202,38 +219,26 @@ export class ExplorBot {
|
|
|
202
219
|
}
|
|
203
220
|
|
|
204
221
|
agentPilot(): Pilot {
|
|
205
|
-
return (this.agents.pilot ||= this.createAgent((
|
|
222
|
+
return (this.agents.pilot ||= this.createAgent((deps) => {
|
|
206
223
|
const researcher = this.agentResearcher();
|
|
207
224
|
const navigator = this.agentNavigator();
|
|
208
|
-
const
|
|
209
|
-
|
|
210
|
-
const getState = () => {
|
|
211
|
-
const state = stateManager.getCurrentState();
|
|
212
|
-
return state ? ActionResult.fromState(state) : null;
|
|
213
|
-
};
|
|
214
|
-
const tools = createAgentTools({ explorer, researcher, navigator, experienceTracker, getState, supervisor: true });
|
|
215
|
-
return new Pilot(ai, tools, researcher, explorer, experienceTracker);
|
|
225
|
+
const tools = createAgentTools({ ...deps, researcher, navigator, supervisor: true });
|
|
226
|
+
return new Pilot(deps, tools, researcher);
|
|
216
227
|
}));
|
|
217
228
|
}
|
|
218
229
|
|
|
219
230
|
agentTester(): Tester {
|
|
220
231
|
if (!this.agents.tester) {
|
|
221
|
-
this.agents.tester = this.createAgent((
|
|
232
|
+
this.agents.tester = this.createAgent((deps) => {
|
|
222
233
|
const researcher = this.agentResearcher();
|
|
223
234
|
const navigator = this.agentNavigator();
|
|
224
|
-
const
|
|
225
|
-
|
|
226
|
-
const getState = () => {
|
|
227
|
-
const state = stateManager.getCurrentState();
|
|
228
|
-
return state ? ActionResult.fromState(state) : null;
|
|
229
|
-
};
|
|
230
|
-
const tools = createAgentTools({ explorer, researcher, navigator, experienceTracker, getState });
|
|
231
|
-
return new Tester(explorer, ai, researcher, navigator, tools);
|
|
235
|
+
const tools = createAgentTools({ ...deps, researcher, navigator });
|
|
236
|
+
return new Tester(deps, researcher, navigator, tools);
|
|
232
237
|
});
|
|
233
238
|
|
|
234
239
|
const qm = this.agentQuartermaster();
|
|
235
240
|
if (qm) this.agents.tester.setQuartermaster(qm);
|
|
236
|
-
this.agents.tester.setHistorian(this.agentHistorian());
|
|
241
|
+
if (this.isHistorianEnabled()) this.agents.tester.setHistorian(this.agentHistorian());
|
|
237
242
|
this.agents.tester.setPilot(this.agentPilot());
|
|
238
243
|
this.agents.tester.setCaptain(this.agentCaptain());
|
|
239
244
|
|
|
@@ -246,16 +251,12 @@ export class ExplorBot {
|
|
|
246
251
|
agentCaptain(): Captain {
|
|
247
252
|
if (!this.agents.captain) {
|
|
248
253
|
this.agents.captain = new Captain(this);
|
|
249
|
-
|
|
250
|
-
const qm = this.agentQuartermaster();
|
|
251
|
-
if (qm) this.agents.captain.setQuartermaster(qm);
|
|
252
|
-
this.agents.captain.setHistorian(this.agentHistorian());
|
|
253
254
|
}
|
|
254
255
|
return this.agents.captain;
|
|
255
256
|
}
|
|
256
257
|
|
|
257
258
|
agentExperienceCompactor(): ExperienceCompactor {
|
|
258
|
-
return (this.agents.experienceCompactor ||= new ExperienceCompactor(this.provider, this.
|
|
259
|
+
return (this.agents.experienceCompactor ||= new ExperienceCompactor(this.provider, this.experienceTracker()));
|
|
259
260
|
}
|
|
260
261
|
|
|
261
262
|
agentQuartermaster(): Quartermaster | null {
|
|
@@ -266,41 +267,37 @@ export class ExplorBot {
|
|
|
266
267
|
this.agents.quartermaster = new Quartermaster(this.provider, {
|
|
267
268
|
model: config?.model,
|
|
268
269
|
});
|
|
269
|
-
this.agents.quartermaster.start(this.explorer
|
|
270
|
+
this.agents.quartermaster.start(this.explorer, this.stateManager());
|
|
270
271
|
}
|
|
271
272
|
return this.agents.quartermaster;
|
|
272
273
|
}
|
|
273
274
|
|
|
274
275
|
agentHistorian(): Historian {
|
|
275
|
-
return (this.agents.historian ||= this.createAgent(({ ai, explorer, config }) => {
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
recorder: explorer.getPlaywrightRecorder(),
|
|
280
|
-
helper: explorer.playwrightHelper,
|
|
276
|
+
return (this.agents.historian ||= this.createAgent(({ ai, explorer, config, stateManager, playwrightRecorder }) => {
|
|
277
|
+
return new Historian(ai, this.experienceTracker(), this.reporter(), stateManager, config, {
|
|
278
|
+
recorder: playwrightRecorder,
|
|
279
|
+
explorer,
|
|
281
280
|
});
|
|
282
281
|
}));
|
|
283
282
|
}
|
|
284
283
|
|
|
285
284
|
agentRerunner(): Rerunner {
|
|
286
285
|
if (!this.agents.rerunner) {
|
|
287
|
-
this.agents.rerunner = this.createAgent((
|
|
286
|
+
this.agents.rerunner = this.createAgent((deps) => {
|
|
288
287
|
const researcher = this.agentResearcher();
|
|
289
288
|
const navigator = this.agentNavigator();
|
|
290
|
-
const tools = createAgentTools({
|
|
291
|
-
return new Rerunner(
|
|
289
|
+
const tools = createAgentTools({ ...deps, researcher, navigator, withExperience: false });
|
|
290
|
+
return new Rerunner(deps, tools);
|
|
292
291
|
});
|
|
293
|
-
|
|
294
|
-
if (qm) this.agents.rerunner.setQuartermaster(qm);
|
|
295
|
-
this.agents.rerunner.setHistorian(this.agentHistorian());
|
|
292
|
+
if (this.isHistorianEnabled()) this.agents.rerunner.setHistorian(this.agentHistorian());
|
|
296
293
|
}
|
|
297
294
|
return this.agents.rerunner;
|
|
298
295
|
}
|
|
299
296
|
|
|
300
297
|
agentDriller(): Driller {
|
|
301
|
-
return (this.agents.driller ||= this.createAgent((
|
|
298
|
+
return (this.agents.driller ||= this.createAgent((deps) => {
|
|
302
299
|
const navigator = this.agentNavigator();
|
|
303
|
-
return new Driller(
|
|
300
|
+
return new Driller(deps, navigator);
|
|
304
301
|
}));
|
|
305
302
|
}
|
|
306
303
|
|
|
@@ -317,7 +314,7 @@ export class ExplorBot {
|
|
|
317
314
|
if (!this.agents.fisherman) {
|
|
318
315
|
const apiConfig = this.config.api;
|
|
319
316
|
const outputDir = this.configParser.getOutputDir();
|
|
320
|
-
const requestStore = this.
|
|
317
|
+
const requestStore = this.requestStore();
|
|
321
318
|
const baseEndpoint = apiConfig?.baseEndpoint || this.config.playwright.url;
|
|
322
319
|
const configHeaders = apiConfig?.headers || {};
|
|
323
320
|
const apiClient = new ApiClient(baseEndpoint);
|
|
@@ -332,7 +329,11 @@ export class ExplorBot {
|
|
|
332
329
|
}
|
|
333
330
|
};
|
|
334
331
|
|
|
335
|
-
const cookieProvider = () =>
|
|
332
|
+
const cookieProvider = async (): Promise<Record<string, string>> => {
|
|
333
|
+
const cookies = await this.explorer.withPage((page) => page.context().cookies()).catch(() => []);
|
|
334
|
+
if (!cookies.length) return {};
|
|
335
|
+
return { Cookie: cookies.map((c: any) => `${c.name}=${c.value}`).join('; ') };
|
|
336
|
+
};
|
|
336
337
|
|
|
337
338
|
this.agents.fisherman = this.createAgent(({ ai }) => {
|
|
338
339
|
return new Fisherman(ai, apiClient, requestStore, specLoader, baseEndpoint, cookieProvider, configHeaders, hasApiConfig);
|
|
@@ -366,7 +367,7 @@ export class ExplorBot {
|
|
|
366
367
|
}
|
|
367
368
|
|
|
368
369
|
if (!opts.extend && this.currentPlan?.url) {
|
|
369
|
-
const currentUrl = this.
|
|
370
|
+
const currentUrl = this._stateManager?.getCurrentState()?.url;
|
|
370
371
|
if (currentUrl && currentUrl !== this.currentPlan.url) {
|
|
371
372
|
tag('info').log('Different page detected, clearing previous plan');
|
|
372
373
|
this.clearPlan();
|
|
@@ -419,7 +420,7 @@ export class ExplorBot {
|
|
|
419
420
|
}
|
|
420
421
|
|
|
421
422
|
generatePlanFilename(feature?: string): string {
|
|
422
|
-
const state = this.
|
|
423
|
+
const state = this._stateManager?.getCurrentState();
|
|
423
424
|
const urlPath = state?.url || '/';
|
|
424
425
|
const urlPart = sanitizeFilename(urlPath) || 'root';
|
|
425
426
|
const suffix = '.md';
|
|
@@ -499,7 +500,7 @@ export class ExplorBot {
|
|
|
499
500
|
const filePath = this.agentSessionAnalyst().writeReport(markdown);
|
|
500
501
|
tag('info').log(`Session report saved: ${relativeToCwd(filePath)}`);
|
|
501
502
|
|
|
502
|
-
const reporter = this.
|
|
503
|
+
const reporter = this._reporter;
|
|
503
504
|
if (reporter?.isEnabled()) {
|
|
504
505
|
let description = markdown;
|
|
505
506
|
const modelsTable = Stats.modelsTable(this.provider.getConfiguredModels());
|
|
@@ -509,8 +510,12 @@ export class ExplorBot {
|
|
|
509
510
|
|
|
510
511
|
this.lastReportedTestCount = tests.length;
|
|
511
512
|
} catch (error) {
|
|
512
|
-
const message =
|
|
513
|
+
const message = browserErrorMessage(error);
|
|
513
514
|
tag('warning').log(`Session analysis failed: ${message}`);
|
|
514
515
|
}
|
|
515
516
|
}
|
|
517
|
+
|
|
518
|
+
private isHistorianEnabled(): boolean {
|
|
519
|
+
return this.config.ai?.agents?.historian?.enabled !== false;
|
|
520
|
+
}
|
|
516
521
|
}
|