explorbot 0.1.31 → 0.2.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.
- package/README.md +14 -14
- package/bin/explorbot-cli.ts +4 -3
- package/boat/doc-collector/src/ai/documentarian.ts +22 -27
- package/boat/doc-collector/src/ai/tools.ts +67 -10
- package/boat/doc-collector/src/docbot.ts +28 -7
- package/boat/doc-collector/src/docs-renderer.ts +19 -24
- package/boat/doc-collector/src/screenshots.ts +33 -1
- package/boat/doc-collector/src/state-diagram.ts +281 -0
- package/dist/bin/explorbot-cli.js +3 -3
- package/dist/boat/doc-collector/src/ai/documentarian.js +16 -6
- package/dist/boat/doc-collector/src/ai/tools.js +47 -10
- package/dist/boat/doc-collector/src/docbot.js +25 -6
- package/dist/boat/doc-collector/src/docs-renderer.js +18 -3
- package/dist/boat/doc-collector/src/screenshots.js +29 -0
- package/dist/boat/doc-collector/src/state-diagram.js +200 -0
- package/dist/package.json +8 -6
- package/dist/src/action-result.d.ts +131 -0
- package/dist/src/action-result.js +82 -159
- package/dist/src/action.d.ts +43 -0
- package/dist/src/action.js +18 -106
- package/dist/src/activity.d.ts +26 -0
- package/dist/src/ai/agent.d.ts +3 -0
- package/dist/src/ai/captain/file-tools.d.ts +28 -0
- package/dist/src/ai/captain/idle-mode.d.ts +11 -0
- package/dist/src/ai/captain/mixin.d.ts +10 -0
- package/dist/src/ai/captain/test-mode.d.ts +13 -0
- package/dist/src/ai/captain/web-mode.d.ts +13 -0
- package/dist/src/ai/captain/web-mode.js +0 -7
- package/dist/src/ai/captain.d.ts +141 -0
- package/dist/src/ai/captain.js +4 -19
- package/dist/src/ai/conversation.d.ts +28 -0
- package/dist/src/ai/conversation.js +9 -28
- package/dist/src/ai/driller.d.ts +157 -0
- package/dist/src/ai/driller.js +3 -12
- package/dist/src/ai/experience-compactor.d.ts +53 -0
- package/dist/src/ai/experience-compactor.js +16 -33
- package/dist/src/ai/fisherman-tools.d.ts +90 -0
- package/dist/src/ai/fisherman-tools.js +1 -1
- package/dist/src/ai/fisherman.d.ts +29 -0
- package/dist/src/ai/fisherman.js +0 -3
- package/dist/src/ai/historian/codeceptjs.d.ts +17 -0
- package/dist/src/ai/historian/codeceptjs.js +3 -2
- package/dist/src/ai/historian/experience.d.ts +40 -0
- package/dist/src/ai/historian/mixin.d.ts +2 -0
- package/dist/src/ai/historian/playwright.d.ts +22 -0
- package/dist/src/ai/historian/playwright.js +3 -2
- package/dist/src/ai/historian/screencast.d.ts +32 -0
- package/dist/src/ai/historian/utils.d.ts +3 -0
- package/dist/src/ai/historian/utils.js +0 -1
- package/dist/src/ai/historian.d.ts +109 -0
- package/dist/src/ai/historian.js +1 -5
- package/dist/src/ai/navigator.d.ts +54 -0
- package/dist/src/ai/navigator.js +11 -46
- package/dist/src/ai/pilot.d.ts +81 -0
- package/dist/src/ai/pilot.js +6 -17
- package/dist/src/ai/planner/session-dedup.d.ts +12 -0
- package/dist/src/ai/planner/styles.d.ts +6 -0
- package/dist/src/ai/planner/subpages.d.ts +35 -0
- package/dist/src/ai/planner.d.ts +79 -0
- package/dist/src/ai/planner.js +49 -37
- package/dist/src/ai/provider.d.ts +53 -0
- package/dist/src/ai/provider.js +78 -130
- package/dist/src/ai/quartermaster.d.ts +56 -0
- package/dist/src/ai/quartermaster.js +4 -10
- package/dist/src/ai/rerunner.d.ts +48 -0
- package/dist/src/ai/rerunner.js +14 -22
- package/dist/src/ai/researcher/cache.d.ts +6 -0
- package/dist/src/ai/researcher/cache.js +11 -18
- package/dist/src/ai/researcher/coordinates.d.ts +56 -0
- package/dist/src/ai/researcher/deep-analysis.d.ts +74 -0
- package/dist/src/ai/researcher/deep-analysis.js +3 -6
- package/dist/src/ai/researcher/fingerprint-worker.d.ts +1 -0
- package/dist/src/ai/researcher/focus.d.ts +8 -0
- package/dist/src/ai/researcher/locators.d.ts +36 -0
- package/dist/src/ai/researcher/mixin.d.ts +2 -0
- package/dist/src/ai/researcher/parser.d.ts +35 -0
- package/dist/src/ai/researcher/parser.js +1 -1
- package/dist/src/ai/researcher/research-result.d.ts +15 -0
- package/dist/src/ai/researcher/research-result.js +0 -19
- package/dist/src/ai/researcher/sections.d.ts +19 -0
- package/dist/src/ai/researcher/sections.js +5 -1
- package/dist/src/ai/researcher.js +12 -53
- package/dist/src/ai/rules.d.ts +16 -0
- package/dist/src/ai/rules.js +22 -15
- package/dist/src/ai/session-analyst.d.ts +11 -0
- package/dist/src/ai/session-analyst.js +8 -5
- package/dist/src/ai/task-agent.d.ts +28 -0
- package/dist/src/ai/task-agent.js +2 -27
- package/dist/src/ai/tester.d.ts +101 -0
- package/dist/src/ai/tester.js +10 -61
- package/dist/src/ai/tools.d.ts +52 -0
- package/dist/src/ai/tools.js +119 -101
- package/dist/src/api/api-client.d.ts +17 -0
- package/dist/src/api/request-result.d.ts +44 -0
- package/dist/src/api/request-store.d.ts +29 -0
- package/dist/src/api/spec-reader.d.ts +5 -0
- package/dist/src/api/xhr-capture.d.ts +10 -0
- package/dist/src/browser-server.d.ts +10 -0
- package/dist/src/command-handler.d.ts +68 -0
- package/dist/src/commands/add-rule-command.d.ts +11 -0
- package/dist/src/commands/base-command.d.ts +26 -0
- package/dist/src/commands/clean-command.d.ts +12 -0
- package/dist/src/commands/compact-command.d.ts +20 -0
- package/dist/src/commands/compact-command.js +6 -6
- package/dist/src/commands/context-aria-command.d.ts +6 -0
- package/dist/src/commands/context-command.d.ts +11 -0
- package/dist/src/commands/context-command.js +1 -1
- package/dist/src/commands/context-data-command.d.ts +6 -0
- package/dist/src/commands/context-experience-command.d.ts +6 -0
- package/dist/src/commands/context-html-command.d.ts +6 -0
- package/dist/src/commands/context-knowledge-command.d.ts +6 -0
- package/dist/src/commands/context-knowledge-command.js +1 -1
- package/dist/src/commands/debug-command.d.ts +6 -0
- package/dist/src/commands/drill-command.d.ts +10 -0
- package/dist/src/commands/exit-command.d.ts +7 -0
- package/dist/src/commands/experience-command.d.ts +15 -0
- package/dist/src/commands/experience-command.js +1 -1
- package/dist/src/commands/explore-command.d.ts +51 -0
- package/dist/src/commands/freesail-command.d.ts +12 -0
- package/dist/src/commands/help-command.d.ts +6 -0
- package/dist/src/commands/index.d.ts +4 -0
- package/dist/src/commands/init-command.d.ts +7 -0
- package/dist/src/commands/knows-command.d.ts +10 -0
- package/dist/src/commands/knows-command.js +1 -1
- package/dist/src/commands/learn-command.d.ts +7 -0
- package/dist/src/commands/learn-command.js +3 -1
- package/dist/src/commands/navigate-command.d.ts +7 -0
- package/dist/src/commands/path-command.d.ts +10 -0
- package/dist/src/commands/plan-clear-command.d.ts +7 -0
- package/dist/src/commands/plan-command.d.ts +14 -0
- package/dist/src/commands/plan-edit-command.d.ts +7 -0
- package/dist/src/commands/plan-load-command.d.ts +7 -0
- package/dist/src/commands/plan-reload-command.d.ts +7 -0
- package/dist/src/commands/plan-save-command.d.ts +7 -0
- package/dist/src/commands/plans-command.d.ts +21 -0
- package/dist/src/commands/rerun-command.d.ts +7 -0
- package/dist/src/commands/research-command.d.ts +11 -0
- package/dist/src/commands/runs-command.d.ts +7 -0
- package/dist/src/commands/start-command.d.ts +7 -0
- package/dist/src/commands/status-command.d.ts +6 -0
- package/dist/src/commands/test-command.d.ts +11 -0
- package/dist/src/components/ActivityPane.d.ts +6 -0
- package/dist/src/components/AddKnowledge.d.ts +10 -0
- package/dist/src/components/AddKnowledge.js +3 -7
- package/dist/src/components/AddRule.d.ts +9 -0
- package/dist/src/components/App.d.ts +9 -0
- package/dist/src/components/App.js +2 -2
- package/dist/src/components/Autocomplete.d.ts +3 -0
- package/dist/src/components/InputPane.d.ts +13 -0
- package/dist/src/components/InputReadline.d.ts +17 -0
- package/dist/src/components/LogPane.d.ts +6 -0
- package/dist/src/components/PlanEditor.d.ts +9 -0
- package/dist/src/components/PlanPane.d.ts +13 -0
- package/dist/src/components/SessionTimer.d.ts +6 -0
- package/dist/src/components/StateTransitionPane.d.ts +8 -0
- package/dist/src/components/StatusPane.d.ts +4 -0
- package/dist/src/components/TaskPane.d.ts +9 -0
- package/dist/src/components/Welcome.d.ts +3 -0
- package/dist/src/components/WelcomeChecklist.d.ts +9 -0
- package/dist/src/components/WelcomeCommands.d.ts +6 -0
- package/dist/src/components/autocomplete-store.d.ts +10 -0
- package/dist/src/components/parse-keypress.d.ts +12 -0
- package/dist/src/config.d.ts +253 -0
- package/dist/src/config.js +12 -0
- package/dist/src/execution-controller.d.ts +25 -0
- package/dist/src/experience-tracker.d.ts +112 -0
- package/dist/src/experience-tracker.js +83 -155
- package/dist/src/explorbot.d.ts +106 -0
- package/dist/src/explorbot.js +17 -51
- package/dist/src/explorer.d.ts +129 -0
- package/dist/src/explorer.js +31 -77
- package/dist/src/index.d.ts +6 -0
- package/dist/src/index.js +2 -55
- package/dist/src/knowledge-tracker.d.ts +33 -0
- package/dist/src/knowledge-tracker.js +47 -47
- package/dist/src/observability.d.ts +13 -0
- package/dist/src/observability.js +2 -1
- package/dist/src/playwright-recorder.d.ts +31 -0
- package/dist/src/reporter.d.ts +34 -0
- package/dist/src/state-manager.d.ts +160 -0
- package/dist/src/state-manager.js +10 -136
- package/dist/src/stats.d.ts +24 -0
- package/dist/src/suite.d.ts +24 -0
- package/dist/src/test-plan.d.ts +166 -0
- package/dist/src/utils/aria.d.ts +25 -0
- package/dist/src/utils/aria.js +4 -1
- package/dist/src/utils/browser-errors.d.ts +8 -0
- package/dist/src/utils/cache.d.ts +15 -0
- package/dist/src/utils/cache.js +34 -0
- package/dist/src/utils/cli-name.d.ts +1 -0
- package/dist/src/utils/code-extractor.d.ts +1 -0
- package/dist/src/utils/context-formatter.d.ts +31 -0
- package/dist/src/utils/context-formatter.js +15 -27
- package/dist/src/utils/error-page.d.ts +12 -0
- package/dist/src/utils/expandable.d.ts +4 -0
- package/dist/src/utils/hooks-runner.d.ts +15 -0
- package/dist/src/utils/html-diff.d.ts +19 -0
- package/dist/src/utils/html.d.ts +129 -0
- package/dist/src/utils/html.js +71 -0
- package/dist/src/utils/log-filters.d.ts +6 -0
- package/dist/src/utils/logger.d.ts +35 -0
- package/dist/src/utils/loop.d.ts +35 -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-parser.d.ts +17 -0
- package/dist/src/utils/markdown-query.d.ts +46 -0
- package/dist/src/utils/markdown-query.js +14 -1
- package/dist/src/utils/markdown-terminal.d.ts +1 -0
- package/dist/src/utils/next-steps.d.ts +11 -0
- package/dist/src/utils/page-readiness.d.ts +7 -0
- package/dist/src/utils/page-readiness.js +1 -1
- package/dist/src/utils/research-parser.d.ts +1 -0
- package/dist/src/utils/retry.d.ts +8 -0
- package/dist/src/utils/rules-loader.d.ts +12 -0
- package/dist/src/utils/secrets.d.ts +4 -0
- package/dist/src/utils/secrets.js +28 -0
- package/dist/src/utils/step-analyzer.d.ts +11 -0
- package/dist/src/utils/strings.d.ts +5 -0
- package/dist/src/utils/strings.js +10 -0
- package/dist/src/utils/test-files.d.ts +3 -0
- package/dist/src/utils/test-plan-markdown.d.ts +9 -0
- package/dist/src/utils/throttle.d.ts +2 -0
- package/dist/src/utils/unique-names.d.ts +2 -0
- package/dist/src/utils/url-matcher.d.ts +6 -0
- package/dist/src/utils/web-element.d.ts +45 -0
- package/dist/src/utils/web-element.js +3 -0
- package/dist/src/utils/web-sandbox.d.ts +4 -0
- package/dist/src/utils/web-sandbox.js +37 -0
- package/dist/src/utils/xpath.d.ts +17 -0
- package/package.json +8 -6
- package/src/action-result.ts +80 -168
- package/src/action.ts +16 -123
- package/src/ai/captain/web-mode.ts +0 -7
- package/src/ai/captain.ts +5 -17
- package/src/ai/conversation.ts +9 -32
- package/src/ai/driller.ts +3 -16
- 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 +4 -2
- package/src/ai/historian/playwright.ts +4 -2
- package/src/ai/historian/utils.ts +0 -1
- package/src/ai/historian.ts +4 -7
- package/src/ai/navigator.ts +13 -49
- package/src/ai/pilot.ts +6 -16
- package/src/ai/planner.ts +56 -44
- package/src/ai/provider.ts +86 -139
- package/src/ai/quartermaster.ts +34 -41
- package/src/ai/rerunner.ts +17 -21
- package/src/ai/researcher/cache.ts +10 -16
- package/src/ai/researcher/deep-analysis.ts +3 -6
- package/src/ai/researcher/parser.ts +1 -1
- package/src/ai/researcher/research-result.ts +0 -18
- package/src/ai/researcher/sections.ts +5 -1
- package/src/ai/researcher.ts +11 -59
- package/src/ai/rules.ts +24 -13
- package/src/ai/session-analyst.ts +8 -5
- package/src/ai/task-agent.ts +3 -30
- package/src/ai/tester.ts +12 -73
- package/src/ai/tools.ts +119 -106
- package/src/commands/compact-command.ts +7 -8
- package/src/commands/context-command.ts +1 -1
- package/src/commands/context-knowledge-command.ts +1 -1
- package/src/commands/experience-command.ts +1 -1
- package/src/commands/knows-command.ts +1 -1
- package/src/commands/learn-command.ts +3 -1
- package/src/components/AddKnowledge.tsx +5 -7
- package/src/components/App.tsx +2 -2
- package/src/config.ts +12 -0
- package/src/experience-tracker.ts +90 -152
- package/src/explorbot.ts +17 -51
- package/src/explorer.ts +34 -81
- package/src/index.ts +9 -0
- package/src/knowledge-tracker.ts +49 -50
- package/src/observability.ts +2 -1
- package/src/state-manager.ts +15 -164
- 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/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 +28 -0
- package/src/utils/strings.ts +12 -0
- package/src/utils/web-element.ts +4 -0
- package/src/utils/web-sandbox.ts +43 -0
- package/src/index.tsx +0 -62
|
@@ -1,11 +1,11 @@
|
|
|
1
|
-
import { existsSync, mkdirSync, readFileSync,
|
|
2
|
-
import { basename,
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { basename, join } from 'node:path';
|
|
3
3
|
import matter from 'gray-matter';
|
|
4
|
-
import { marked } from 'marked';
|
|
5
4
|
import { ConfigParser } from './config.js';
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
5
|
+
import { createDebug, pluralize, tag } from './utils/logger.js';
|
|
6
|
+
import { loadMarkdownFiles } from './utils/markdown-files.js';
|
|
8
7
|
import { mdq } from './utils/markdown-query.js';
|
|
8
|
+
import { redactSecrets } from './utils/secrets.js';
|
|
9
9
|
import { isNonReusableCode } from "./utils/step-analyzer.js";
|
|
10
10
|
import { extractStatePath } from './utils/url-matcher.js';
|
|
11
11
|
const debugLog = createDebug('explorbot:experience');
|
|
@@ -32,20 +32,13 @@ export class ExperienceTracker {
|
|
|
32
32
|
experienceDir;
|
|
33
33
|
disabled;
|
|
34
34
|
knowledgeTracker;
|
|
35
|
-
constructor(options = {}) {
|
|
35
|
+
constructor(knowledgeTracker, options = {}) {
|
|
36
36
|
const configParser = ConfigParser.getInstance();
|
|
37
37
|
const config = configParser.getConfig();
|
|
38
|
-
const configPath = configParser.getConfigPath();
|
|
39
38
|
this.disabled = options.disabled ?? false;
|
|
40
|
-
this.knowledgeTracker =
|
|
39
|
+
this.knowledgeTracker = knowledgeTracker;
|
|
41
40
|
// Resolve experience directory relative to the config file location (project root)
|
|
42
|
-
|
|
43
|
-
const projectRoot = dirname(configPath);
|
|
44
|
-
this.experienceDir = join(projectRoot, config.dirs?.experience || 'experience');
|
|
45
|
-
}
|
|
46
|
-
else {
|
|
47
|
-
this.experienceDir = config.dirs?.experience || 'experience';
|
|
48
|
-
}
|
|
41
|
+
this.experienceDir = configParser.resolveProjectDir(config.dirs?.experience || 'experience');
|
|
49
42
|
if (!this.disabled) {
|
|
50
43
|
this.ensureDirectory(this.experienceDir);
|
|
51
44
|
}
|
|
@@ -83,7 +76,9 @@ export class ExperienceTracker {
|
|
|
83
76
|
}
|
|
84
77
|
}
|
|
85
78
|
readExperienceFile(stateHash) {
|
|
86
|
-
|
|
79
|
+
return this.readExperienceFileAt(this.getExperienceFilePath(stateHash));
|
|
80
|
+
}
|
|
81
|
+
readExperienceFileAt(filePath) {
|
|
87
82
|
const fileContent = readFileSync(filePath, 'utf8');
|
|
88
83
|
const { content, data } = matter(fileContent);
|
|
89
84
|
return { content, data };
|
|
@@ -93,23 +88,9 @@ export class ExperienceTracker {
|
|
|
93
88
|
return;
|
|
94
89
|
}
|
|
95
90
|
const filePath = this.getExperienceFilePath(stateHash);
|
|
96
|
-
const fileContent = matter.stringify(content, frontmatter || {});
|
|
91
|
+
const fileContent = matter.stringify(redactSecrets(content), frontmatter || {});
|
|
97
92
|
writeFileSync(filePath, fileContent, 'utf8');
|
|
98
93
|
}
|
|
99
|
-
hasRecentExperience(stateHash, prefix = '') {
|
|
100
|
-
if (this.disabled) {
|
|
101
|
-
return false;
|
|
102
|
-
}
|
|
103
|
-
if (prefix) {
|
|
104
|
-
stateHash = `${prefix}_${stateHash}`;
|
|
105
|
-
}
|
|
106
|
-
const filePath = this.getExperienceFilePath(stateHash);
|
|
107
|
-
if (!existsSync(filePath)) {
|
|
108
|
-
return false;
|
|
109
|
-
}
|
|
110
|
-
const stats = statSync(filePath);
|
|
111
|
-
return stats.mtime.getTime() > Date.now() - 1000 * 60 * 60 * 24;
|
|
112
|
-
}
|
|
113
94
|
getExperienceFilePath(stateHash) {
|
|
114
95
|
return join(this.experienceDir, `${stateHash}.md`);
|
|
115
96
|
}
|
|
@@ -153,7 +134,10 @@ export class ExperienceTracker {
|
|
|
153
134
|
this.ensureExperienceFile(state);
|
|
154
135
|
const stateHash = state.getStateHash();
|
|
155
136
|
const { content, data } = this.readExperienceFile(stateHash);
|
|
156
|
-
if (content
|
|
137
|
+
if (mdq(content)
|
|
138
|
+
.query('code')
|
|
139
|
+
.meta()
|
|
140
|
+
.some((m) => m.text.trim() === action.code.trim())) {
|
|
157
141
|
debugLog('Skipping duplicate action', action.code);
|
|
158
142
|
return;
|
|
159
143
|
}
|
|
@@ -178,7 +162,10 @@ export class ExperienceTracker {
|
|
|
178
162
|
this.ensureExperienceFile(state);
|
|
179
163
|
const stateHash = state.getStateHash();
|
|
180
164
|
const { content, data } = this.readExperienceFile(stateHash);
|
|
181
|
-
if (content
|
|
165
|
+
if (mdq(content)
|
|
166
|
+
.query('section2')
|
|
167
|
+
.each()
|
|
168
|
+
.some((s) => s.text().trim() === body.trim())) {
|
|
182
169
|
debugLog('Skipping duplicate flow body');
|
|
183
170
|
return;
|
|
184
171
|
}
|
|
@@ -199,25 +186,9 @@ export class ExperienceTracker {
|
|
|
199
186
|
continue;
|
|
200
187
|
}
|
|
201
188
|
try {
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
for (const file of files) {
|
|
206
|
-
try {
|
|
207
|
-
const content = readFileSync(file, 'utf8');
|
|
208
|
-
const parsed = matter(content);
|
|
209
|
-
const mtime = statSync(file).mtime;
|
|
210
|
-
allFiles.push({
|
|
211
|
-
filePath: file,
|
|
212
|
-
data: parsed.data,
|
|
213
|
-
content: parsed.content,
|
|
214
|
-
mtime,
|
|
215
|
-
});
|
|
216
|
-
}
|
|
217
|
-
catch (error) {
|
|
218
|
-
debugLog(`Failed to read experience file ${file}:`, error);
|
|
219
|
-
}
|
|
220
|
-
}
|
|
189
|
+
allFiles.push(...loadMarkdownFiles(experienceDir, {
|
|
190
|
+
onError: (filePath, error) => debugLog(`Failed to read experience file ${filePath}:`, error),
|
|
191
|
+
}));
|
|
221
192
|
}
|
|
222
193
|
catch (error) {
|
|
223
194
|
debugLog(`Failed to read experience directory ${experienceDir}:`, error);
|
|
@@ -241,19 +212,18 @@ export class ExperienceTracker {
|
|
|
241
212
|
});
|
|
242
213
|
})
|
|
243
214
|
.map((experience) => {
|
|
244
|
-
|
|
245
|
-
if (lines.length <= maxLines)
|
|
215
|
+
if (experience.content.split('\n').length <= maxLines)
|
|
246
216
|
return experience;
|
|
247
|
-
|
|
217
|
+
let content = experience.content;
|
|
218
|
+
while (content.split('\n').length > maxLines) {
|
|
219
|
+
const sections = mdq(content).query('section2').each();
|
|
220
|
+
if (sections.length <= 1)
|
|
221
|
+
break;
|
|
222
|
+
content = sections[sections.length - 1].replace('');
|
|
223
|
+
}
|
|
224
|
+
return { ...experience, content };
|
|
248
225
|
});
|
|
249
226
|
}
|
|
250
|
-
/**
|
|
251
|
-
* Clean up experience tracker (for testing)
|
|
252
|
-
*/
|
|
253
|
-
cleanup() {
|
|
254
|
-
// Clear any in-memory state if needed
|
|
255
|
-
// The actual files will be cleaned up by test cleanup
|
|
256
|
-
}
|
|
257
227
|
getSuccessfulExperience(state, options) {
|
|
258
228
|
const records = this.getRelevantExperience(state, {
|
|
259
229
|
includeDescendantExperience: options?.includeDescendants,
|
|
@@ -285,36 +255,48 @@ export class ExperienceTracker {
|
|
|
285
255
|
const bHash = basename(b.filePath, '.md');
|
|
286
256
|
return aHash.localeCompare(bHash);
|
|
287
257
|
});
|
|
258
|
+
return this.buildToc(sorted);
|
|
259
|
+
}
|
|
260
|
+
renderExperienceTocFor(state) {
|
|
261
|
+
const toc = this.getExperienceTableOfContents(state);
|
|
262
|
+
if (toc.length === 0)
|
|
263
|
+
return '';
|
|
264
|
+
const totalSections = toc.reduce((sum, entry) => sum + entry.sections.length, 0);
|
|
265
|
+
debugLog(`injecting experience TOC (${toc.length} files, ${totalSections} sections)`);
|
|
266
|
+
tag('operation').log(`Found ${toc.length} experience ${pluralize(toc.length, 'file')} (${totalSections} sections)`);
|
|
267
|
+
return renderExperienceToc(toc);
|
|
268
|
+
}
|
|
269
|
+
getExperienceSection(fileTag, sectionIndex, state, options) {
|
|
270
|
+
const toc = this.getExperienceTableOfContents(state, options);
|
|
271
|
+
const entry = toc.find((e) => e.fileTag === fileTag);
|
|
272
|
+
if (!entry)
|
|
273
|
+
return null;
|
|
274
|
+
const extracted = this.readSectionByHash(entry.fileHash, sectionIndex);
|
|
275
|
+
if (!extracted)
|
|
276
|
+
return null;
|
|
277
|
+
return { title: extracted.title, url: entry.url, content: extracted.body };
|
|
278
|
+
}
|
|
279
|
+
buildToc(records) {
|
|
288
280
|
const toc = [];
|
|
289
|
-
for (
|
|
290
|
-
const record = sorted[i];
|
|
291
|
-
const fileHash = basename(record.filePath, '.md');
|
|
292
|
-
const url = record.data?.url || '';
|
|
281
|
+
for (const record of records) {
|
|
293
282
|
const sections = listTocHeadings(record.content);
|
|
294
283
|
if (sections.length === 0)
|
|
295
284
|
continue;
|
|
296
285
|
toc.push({
|
|
297
|
-
fileTag: indexToLetters(
|
|
298
|
-
fileHash,
|
|
299
|
-
url,
|
|
286
|
+
fileTag: indexToLetters(toc.length),
|
|
287
|
+
fileHash: basename(record.filePath, '.md'),
|
|
288
|
+
url: record.data?.url || '',
|
|
300
289
|
sections,
|
|
301
290
|
});
|
|
302
291
|
}
|
|
303
292
|
return toc;
|
|
304
293
|
}
|
|
305
|
-
|
|
306
|
-
const
|
|
307
|
-
const entry = toc.find((e) => e.fileTag === fileTag);
|
|
308
|
-
if (!entry)
|
|
309
|
-
return null;
|
|
310
|
-
const filePath = this.findExperienceFileByHash(entry.fileHash);
|
|
294
|
+
readSectionByHash(fileHash, sectionIndex) {
|
|
295
|
+
const filePath = this.findExperienceFileByHash(fileHash);
|
|
311
296
|
if (!filePath)
|
|
312
297
|
return null;
|
|
313
|
-
const { content } = this.
|
|
314
|
-
|
|
315
|
-
if (!extracted)
|
|
316
|
-
return null;
|
|
317
|
-
return { title: extracted.title, url: entry.url, content: extracted.body };
|
|
298
|
+
const { content } = this.readExperienceFileAt(filePath);
|
|
299
|
+
return extractHeadingSection(content, sectionIndex);
|
|
318
300
|
}
|
|
319
301
|
findExperienceFileByHash(fileHash) {
|
|
320
302
|
for (const dir of this.getExperienceDirectories()) {
|
|
@@ -358,81 +340,34 @@ export class ExperienceTracker {
|
|
|
358
340
|
const bUrl = b.data?.url || '';
|
|
359
341
|
return aUrl.localeCompare(bUrl);
|
|
360
342
|
});
|
|
361
|
-
|
|
362
|
-
for (let i = 0; i < sorted.length; i++) {
|
|
363
|
-
const record = sorted[i];
|
|
364
|
-
const sections = listTocHeadings(record.content);
|
|
365
|
-
if (sections.length === 0)
|
|
366
|
-
continue;
|
|
367
|
-
toc.push({
|
|
368
|
-
fileTag: indexToLetters(toc.length),
|
|
369
|
-
fileHash: basename(record.filePath, '.md'),
|
|
370
|
-
url: record.data?.url || '',
|
|
371
|
-
sections,
|
|
372
|
-
});
|
|
373
|
-
}
|
|
374
|
-
return toc;
|
|
343
|
+
return this.buildToc(sorted);
|
|
375
344
|
}
|
|
376
345
|
getExperienceSectionByTag(fileTag, sectionIndex, filter) {
|
|
377
346
|
const toc = this.listAllExperienceToc(filter);
|
|
378
347
|
const entry = toc.find((e) => e.fileTag === fileTag);
|
|
379
348
|
if (!entry)
|
|
380
349
|
return null;
|
|
381
|
-
const
|
|
382
|
-
if (!filePath)
|
|
383
|
-
return null;
|
|
384
|
-
const { content } = this.readExperienceFile(entry.fileHash);
|
|
385
|
-
const extracted = extractHeadingSection(content, sectionIndex);
|
|
350
|
+
const extracted = this.readSectionByHash(entry.fileHash, sectionIndex);
|
|
386
351
|
if (!extracted)
|
|
387
352
|
return null;
|
|
388
353
|
return { title: extracted.title, url: entry.url, content: extracted.body, fileHash: entry.fileHash };
|
|
389
354
|
}
|
|
390
355
|
}
|
|
391
356
|
function listTocHeadings(content) {
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
continue;
|
|
398
|
-
const heading = token;
|
|
399
|
-
if (heading.depth !== 2 && heading.depth !== 3)
|
|
400
|
-
continue;
|
|
401
|
-
index++;
|
|
402
|
-
result.push({ index, level: heading.depth, title: heading.text });
|
|
403
|
-
}
|
|
404
|
-
return result;
|
|
357
|
+
return mdq(content)
|
|
358
|
+
.query('heading')
|
|
359
|
+
.meta()
|
|
360
|
+
.filter((m) => m.depth === 2 || m.depth === 3)
|
|
361
|
+
.map((m, i) => ({ index: i + 1, level: m.depth, title: m.text }));
|
|
405
362
|
}
|
|
406
363
|
function extractHeadingSection(content, sectionIndex) {
|
|
407
|
-
const
|
|
408
|
-
const
|
|
409
|
-
|
|
410
|
-
const token = tokens[i];
|
|
411
|
-
if (token.type !== 'heading')
|
|
412
|
-
continue;
|
|
413
|
-
const heading = token;
|
|
414
|
-
if (heading.depth !== 2 && heading.depth !== 3)
|
|
415
|
-
continue;
|
|
416
|
-
matching.push({ tokenIdx: i, depth: heading.depth, text: heading.text });
|
|
417
|
-
}
|
|
364
|
+
const sections = mdq(content).query('section').each();
|
|
365
|
+
const metas = mdq(content).query('section').meta();
|
|
366
|
+
const matching = metas.map((meta, i) => ({ meta, section: sections[i] })).filter((entry) => entry.meta.depth === 2 || entry.meta.depth === 3);
|
|
418
367
|
if (sectionIndex < 1 || sectionIndex > matching.length)
|
|
419
368
|
return null;
|
|
420
369
|
const target = matching[sectionIndex - 1];
|
|
421
|
-
|
|
422
|
-
for (let j = target.tokenIdx + 1; j < tokens.length; j++) {
|
|
423
|
-
const token = tokens[j];
|
|
424
|
-
if (token.type !== 'heading')
|
|
425
|
-
continue;
|
|
426
|
-
if (token.depth <= target.depth) {
|
|
427
|
-
endTokenIdx = j;
|
|
428
|
-
break;
|
|
429
|
-
}
|
|
430
|
-
}
|
|
431
|
-
const body = tokens
|
|
432
|
-
.slice(target.tokenIdx, endTokenIdx)
|
|
433
|
-
.map((t) => t.raw || '')
|
|
434
|
-
.join('');
|
|
435
|
-
return { title: target.text, body };
|
|
370
|
+
return { title: target.meta.text, body: target.section.text() };
|
|
436
371
|
}
|
|
437
372
|
function indexToLetters(index) {
|
|
438
373
|
let n = index;
|
|
@@ -498,21 +433,14 @@ function generateActionContent(title, code, explanation) {
|
|
|
498
433
|
return lines.join('\n');
|
|
499
434
|
}
|
|
500
435
|
function renderAsHowTo(content) {
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
result += `## HOW to ${text.slice(7).trim()} (single-step)\n\n`;
|
|
512
|
-
continue;
|
|
513
|
-
}
|
|
514
|
-
}
|
|
515
|
-
result += token.raw || '';
|
|
516
|
-
}
|
|
517
|
-
return result;
|
|
436
|
+
return mdq(content)
|
|
437
|
+
.query('h2')
|
|
438
|
+
.replaceEach((heading) => {
|
|
439
|
+
const text = heading.meta()[0]?.text.trim() || '';
|
|
440
|
+
if (text.startsWith('FLOW:'))
|
|
441
|
+
return `## HOW to ${text.slice(5).trim()} (multi-step)\n\n`;
|
|
442
|
+
if (text.startsWith('ACTION:'))
|
|
443
|
+
return `## HOW to ${text.slice(7).trim()} (single-step)\n\n`;
|
|
444
|
+
return heading.text();
|
|
445
|
+
});
|
|
518
446
|
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { Captain } from './ai/captain.js';
|
|
2
|
+
import { Driller } from './ai/driller.js';
|
|
3
|
+
import { ExperienceCompactor } from './ai/experience-compactor.js';
|
|
4
|
+
import { Fisherman } from './ai/fisherman.js';
|
|
5
|
+
import { Historian } from './ai/historian.js';
|
|
6
|
+
import { Navigator } from './ai/navigator.js';
|
|
7
|
+
import { Pilot } from './ai/pilot.js';
|
|
8
|
+
import { Planner } from './ai/planner.js';
|
|
9
|
+
import { AIProvider } from './ai/provider.js';
|
|
10
|
+
import { Quartermaster } from './ai/quartermaster.js';
|
|
11
|
+
import { Rerunner } from './ai/rerunner.js';
|
|
12
|
+
import { Researcher } from './ai/researcher.js';
|
|
13
|
+
import { SessionAnalyst } from './ai/session-analyst.js';
|
|
14
|
+
import { Tester } from './ai/tester.js';
|
|
15
|
+
import type { ExplorbotConfig } from './config.js';
|
|
16
|
+
import { ConfigParser } from './config.js';
|
|
17
|
+
import { ExperienceTracker } from './experience-tracker.js';
|
|
18
|
+
import Explorer from './explorer.js';
|
|
19
|
+
import { KnowledgeTracker } from './knowledge-tracker.js';
|
|
20
|
+
import { WebPageState } from './state-manager.js';
|
|
21
|
+
import type { Suite } from './suite.js';
|
|
22
|
+
import { Plan, type Test } from './test-plan.js';
|
|
23
|
+
export interface ExplorBotOptions {
|
|
24
|
+
from?: string;
|
|
25
|
+
baseUrl?: string;
|
|
26
|
+
verbose?: boolean;
|
|
27
|
+
config?: string;
|
|
28
|
+
path?: string;
|
|
29
|
+
show?: boolean;
|
|
30
|
+
headless?: boolean;
|
|
31
|
+
incognito?: boolean;
|
|
32
|
+
session?: string;
|
|
33
|
+
}
|
|
34
|
+
export type UserResolveFunction = (error?: Error, showWelcome?: boolean) => Promise<string | null>;
|
|
35
|
+
export declare class ExplorBot {
|
|
36
|
+
configParser: ConfigParser;
|
|
37
|
+
explorer: Explorer;
|
|
38
|
+
provider: AIProvider;
|
|
39
|
+
config: ExplorbotConfig;
|
|
40
|
+
options: ExplorBotOptions;
|
|
41
|
+
userResolveFn: UserResolveFunction | null;
|
|
42
|
+
currentPlan?: Plan;
|
|
43
|
+
planFeature?: string;
|
|
44
|
+
lastPlanError: Error | null;
|
|
45
|
+
lastSavedPlanPath: string | null;
|
|
46
|
+
agents: Record<string, any>;
|
|
47
|
+
sessionPlans: Plan[];
|
|
48
|
+
lastReportedTestCount: number;
|
|
49
|
+
_experienceTracker?: ExperienceTracker;
|
|
50
|
+
_knowledgeTracker?: KnowledgeTracker;
|
|
51
|
+
constructor(options?: ExplorBotOptions);
|
|
52
|
+
get isExploring(): boolean;
|
|
53
|
+
setUserResolve(fn: UserResolveFunction): void;
|
|
54
|
+
start(): Promise<void>;
|
|
55
|
+
startProviderOnly(): Promise<void>;
|
|
56
|
+
stop(): Promise<void>;
|
|
57
|
+
visitInitialState(): Promise<void>;
|
|
58
|
+
visit(url: string): Promise<void>;
|
|
59
|
+
openFreshTab(): Promise<void>;
|
|
60
|
+
getCurrentState(): WebPageState | null;
|
|
61
|
+
getExplorer(): Explorer;
|
|
62
|
+
knowledgeTracker(): KnowledgeTracker;
|
|
63
|
+
experienceTracker(): ExperienceTracker;
|
|
64
|
+
getConfig(): ExplorbotConfig;
|
|
65
|
+
getOptions(): ExplorBotOptions;
|
|
66
|
+
getProvider(): AIProvider;
|
|
67
|
+
createAgent<T>(factory: (deps: {
|
|
68
|
+
explorer: Explorer;
|
|
69
|
+
ai: AIProvider;
|
|
70
|
+
config: ExplorbotConfig;
|
|
71
|
+
}) => T): T;
|
|
72
|
+
agentResearcher(): Researcher;
|
|
73
|
+
agentNavigator(): Navigator;
|
|
74
|
+
agentPlanner(): Planner;
|
|
75
|
+
agentPilot(): Pilot;
|
|
76
|
+
agentTester(): Tester;
|
|
77
|
+
agentCaptain(): Captain;
|
|
78
|
+
agentExperienceCompactor(): ExperienceCompactor;
|
|
79
|
+
agentQuartermaster(): Quartermaster | null;
|
|
80
|
+
agentHistorian(): Historian;
|
|
81
|
+
agentRerunner(): Rerunner;
|
|
82
|
+
agentDriller(): Driller;
|
|
83
|
+
agentSessionAnalyst(): SessionAnalyst;
|
|
84
|
+
agentFisherman(): Fisherman | null;
|
|
85
|
+
getCurrentPlan(): Plan | undefined;
|
|
86
|
+
getSuite(): Suite | null;
|
|
87
|
+
getPlanFeature(): string | undefined;
|
|
88
|
+
clearPlan(): void;
|
|
89
|
+
plan(feature?: string, opts?: {
|
|
90
|
+
fresh?: boolean;
|
|
91
|
+
style?: string;
|
|
92
|
+
extend?: Plan;
|
|
93
|
+
completedPlans?: Plan[];
|
|
94
|
+
noSave?: boolean;
|
|
95
|
+
}): Promise<Plan>;
|
|
96
|
+
getPlansDir(): string;
|
|
97
|
+
savePlan(filename?: string): string | null;
|
|
98
|
+
savePlans(plans: Plan[], filename?: string): string | null;
|
|
99
|
+
generatePlanFilename(feature?: string): string;
|
|
100
|
+
resolvePlanPath(filename: string): string;
|
|
101
|
+
loadPlan(filename: string): Plan;
|
|
102
|
+
loadPlans(filename: string): Plan[];
|
|
103
|
+
setCurrentPlan(plan?: Plan): void;
|
|
104
|
+
getSessionTests(): Test[];
|
|
105
|
+
printSessionAnalysis(): Promise<void>;
|
|
106
|
+
}
|
package/dist/src/explorbot.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { existsSync, mkdirSync } from 'node:fs';
|
|
2
2
|
import path from 'node:path';
|
|
3
|
-
import { ActionResult } from "./action-result.js";
|
|
4
3
|
import { Captain } from "./ai/captain.js";
|
|
5
4
|
import { Driller } from "./ai/driller.js";
|
|
6
5
|
import { ExperienceCompactor } from "./ai/experience-compactor.js";
|
|
@@ -25,6 +24,7 @@ import Explorer from "./explorer.js";
|
|
|
25
24
|
import { KnowledgeTracker } from "./knowledge-tracker.js";
|
|
26
25
|
import { Stats } from "./stats.js";
|
|
27
26
|
import { Plan } from "./test-plan.js";
|
|
27
|
+
import { browserErrorMessage } from "./utils/browser-errors.js";
|
|
28
28
|
import { setVerboseMode, tag } from "./utils/logger.js";
|
|
29
29
|
import { relativeToCwd } from "./utils/next-steps.js";
|
|
30
30
|
import { sanitizeFilename } from "./utils/strings.js";
|
|
@@ -36,7 +36,6 @@ export class ExplorBot {
|
|
|
36
36
|
config;
|
|
37
37
|
options;
|
|
38
38
|
userResolveFn = null;
|
|
39
|
-
needsInput = false;
|
|
40
39
|
currentPlan;
|
|
41
40
|
planFeature;
|
|
42
41
|
lastPlanError = null;
|
|
@@ -44,6 +43,8 @@ export class ExplorBot {
|
|
|
44
43
|
agents = {};
|
|
45
44
|
sessionPlans = [];
|
|
46
45
|
lastReportedTestCount = 0;
|
|
46
|
+
_experienceTracker;
|
|
47
|
+
_knowledgeTracker;
|
|
47
48
|
constructor(options = {}) {
|
|
48
49
|
this.options = options;
|
|
49
50
|
this.configParser = ConfigParser.getInstance();
|
|
@@ -64,16 +65,14 @@ export class ExplorBot {
|
|
|
64
65
|
}
|
|
65
66
|
try {
|
|
66
67
|
await this.startProviderOnly();
|
|
67
|
-
this.explorer = new Explorer(this.config, this.provider, this.options);
|
|
68
|
+
this.explorer = new Explorer(this.config, this.provider, this.options, this.experienceTracker(), this.knowledgeTracker());
|
|
68
69
|
await this.explorer.start();
|
|
69
70
|
if (!this.options.incognito) {
|
|
70
71
|
await this.agentExperienceCompactor().autocompact();
|
|
71
72
|
}
|
|
72
|
-
if (this.userResolveFn)
|
|
73
|
-
this.explorer.setUserResolve(this.userResolveFn);
|
|
74
73
|
}
|
|
75
74
|
catch (error) {
|
|
76
|
-
const message =
|
|
75
|
+
const message = browserErrorMessage(error);
|
|
77
76
|
console.error('\nFailed to start:', message);
|
|
78
77
|
process.exit(1);
|
|
79
78
|
}
|
|
@@ -105,17 +104,11 @@ export class ExplorBot {
|
|
|
105
104
|
getExplorer() {
|
|
106
105
|
return this.explorer;
|
|
107
106
|
}
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
return this.explorer.getKnowledgeTracker();
|
|
111
|
-
}
|
|
112
|
-
return new KnowledgeTracker();
|
|
107
|
+
knowledgeTracker() {
|
|
108
|
+
return (this._knowledgeTracker ||= new KnowledgeTracker());
|
|
113
109
|
}
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
return this.explorer.getStateManager().getExperienceTracker();
|
|
117
|
-
}
|
|
118
|
-
return new ExperienceTracker();
|
|
110
|
+
experienceTracker() {
|
|
111
|
+
return (this._experienceTracker ||= new ExperienceTracker(this.knowledgeTracker()));
|
|
119
112
|
}
|
|
120
113
|
getConfig() {
|
|
121
114
|
return this.config;
|
|
@@ -123,12 +116,6 @@ export class ExplorBot {
|
|
|
123
116
|
getOptions() {
|
|
124
117
|
return this.options;
|
|
125
118
|
}
|
|
126
|
-
isReady() {
|
|
127
|
-
return this.explorer?.isStarted;
|
|
128
|
-
}
|
|
129
|
-
getConfigParser() {
|
|
130
|
-
return this.configParser;
|
|
131
|
-
}
|
|
132
119
|
getProvider() {
|
|
133
120
|
return this.provider;
|
|
134
121
|
}
|
|
@@ -138,10 +125,8 @@ export class ExplorBot {
|
|
|
138
125
|
ai: this.provider,
|
|
139
126
|
config: this.config,
|
|
140
127
|
});
|
|
141
|
-
const agentEmoji = agent.emoji || '';
|
|
142
128
|
const agentName = agent.constructor.name.toLowerCase();
|
|
143
129
|
tag('debug').log(`Created ${agentName} agent`);
|
|
144
|
-
// Agent is stored by the calling method using a string key
|
|
145
130
|
return agent;
|
|
146
131
|
}
|
|
147
132
|
agentResearcher() {
|
|
@@ -149,12 +134,12 @@ export class ExplorBot {
|
|
|
149
134
|
}
|
|
150
135
|
agentNavigator() {
|
|
151
136
|
return (this.agents.navigator ||= this.createAgent(({ ai, explorer }) => {
|
|
152
|
-
return new Navigator(explorer, ai
|
|
137
|
+
return new Navigator(explorer, ai);
|
|
153
138
|
}));
|
|
154
139
|
}
|
|
155
140
|
agentPlanner() {
|
|
156
141
|
if (!this.agents.planner) {
|
|
157
|
-
this.agents.planner = this.createAgent(({ ai, explorer }) => new Planner(explorer, ai));
|
|
142
|
+
this.agents.planner = this.createAgent(({ ai, explorer }) => new Planner(explorer, ai, this.agentResearcher()));
|
|
158
143
|
const fisherman = this.agentFisherman();
|
|
159
144
|
if (fisherman)
|
|
160
145
|
this.agents.planner.setFisherman(fisherman);
|
|
@@ -165,14 +150,8 @@ export class ExplorBot {
|
|
|
165
150
|
return (this.agents.pilot ||= this.createAgent(({ ai, explorer }) => {
|
|
166
151
|
const researcher = this.agentResearcher();
|
|
167
152
|
const navigator = this.agentNavigator();
|
|
168
|
-
const
|
|
169
|
-
|
|
170
|
-
const getState = () => {
|
|
171
|
-
const state = stateManager.getCurrentState();
|
|
172
|
-
return state ? ActionResult.fromState(state) : null;
|
|
173
|
-
};
|
|
174
|
-
const tools = createAgentTools({ explorer, researcher, navigator, experienceTracker, getState, supervisor: true });
|
|
175
|
-
return new Pilot(ai, tools, researcher, explorer, experienceTracker);
|
|
153
|
+
const tools = createAgentTools({ explorer, researcher, navigator, supervisor: true });
|
|
154
|
+
return new Pilot(ai, tools, researcher, explorer);
|
|
176
155
|
}));
|
|
177
156
|
}
|
|
178
157
|
agentTester() {
|
|
@@ -180,13 +159,7 @@ export class ExplorBot {
|
|
|
180
159
|
this.agents.tester = this.createAgent(({ ai, explorer }) => {
|
|
181
160
|
const researcher = this.agentResearcher();
|
|
182
161
|
const navigator = this.agentNavigator();
|
|
183
|
-
const
|
|
184
|
-
const experienceTracker = stateManager.getExperienceTracker();
|
|
185
|
-
const getState = () => {
|
|
186
|
-
const state = stateManager.getCurrentState();
|
|
187
|
-
return state ? ActionResult.fromState(state) : null;
|
|
188
|
-
};
|
|
189
|
-
const tools = createAgentTools({ explorer, researcher, navigator, experienceTracker, getState });
|
|
162
|
+
const tools = createAgentTools({ explorer, researcher, navigator });
|
|
190
163
|
return new Tester(explorer, ai, researcher, navigator, tools);
|
|
191
164
|
});
|
|
192
165
|
const qm = this.agentQuartermaster();
|
|
@@ -204,15 +177,11 @@ export class ExplorBot {
|
|
|
204
177
|
agentCaptain() {
|
|
205
178
|
if (!this.agents.captain) {
|
|
206
179
|
this.agents.captain = new Captain(this);
|
|
207
|
-
const qm = this.agentQuartermaster();
|
|
208
|
-
if (qm)
|
|
209
|
-
this.agents.captain.setQuartermaster(qm);
|
|
210
|
-
this.agents.captain.setHistorian(this.agentHistorian());
|
|
211
180
|
}
|
|
212
181
|
return this.agents.captain;
|
|
213
182
|
}
|
|
214
183
|
agentExperienceCompactor() {
|
|
215
|
-
return (this.agents.experienceCompactor ||= new ExperienceCompactor(this.provider, this.
|
|
184
|
+
return (this.agents.experienceCompactor ||= new ExperienceCompactor(this.provider, this.experienceTracker()));
|
|
216
185
|
}
|
|
217
186
|
agentQuartermaster() {
|
|
218
187
|
const config = this.config.ai?.agents?.quartermaster;
|
|
@@ -241,12 +210,9 @@ export class ExplorBot {
|
|
|
241
210
|
this.agents.rerunner = this.createAgent(({ ai, explorer }) => {
|
|
242
211
|
const researcher = this.agentResearcher();
|
|
243
212
|
const navigator = this.agentNavigator();
|
|
244
|
-
const tools = createAgentTools({ explorer, researcher, navigator });
|
|
213
|
+
const tools = createAgentTools({ explorer, researcher, navigator, withExperience: false });
|
|
245
214
|
return new Rerunner(explorer, ai, tools);
|
|
246
215
|
});
|
|
247
|
-
const qm = this.agentQuartermaster();
|
|
248
|
-
if (qm)
|
|
249
|
-
this.agents.rerunner.setQuartermaster(qm);
|
|
250
216
|
this.agents.rerunner.setHistorian(this.agentHistorian());
|
|
251
217
|
}
|
|
252
218
|
return this.agents.rerunner;
|
|
@@ -443,7 +409,7 @@ export class ExplorBot {
|
|
|
443
409
|
this.lastReportedTestCount = tests.length;
|
|
444
410
|
}
|
|
445
411
|
catch (error) {
|
|
446
|
-
const message =
|
|
412
|
+
const message = browserErrorMessage(error);
|
|
447
413
|
tag('warning').log(`Session analysis failed: ${message}`);
|
|
448
414
|
}
|
|
449
415
|
}
|