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
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { ActionResult } from '../action-result.js';
|
|
2
|
+
import type { ExperienceTracker } from '../experience-tracker.js';
|
|
3
|
+
import type Explorer from '../explorer.js';
|
|
4
|
+
import type { KnowledgeTracker } from '../knowledge-tracker.js';
|
|
5
|
+
import { Plan, Test } from '../test-plan.js';
|
|
6
|
+
import { HooksRunner } from '../utils/hooks-runner.js';
|
|
7
|
+
import { WebElement } from '../utils/web-element.js';
|
|
8
|
+
import type { Agent } from './agent.js';
|
|
9
|
+
import type { Navigator } from './navigator.js';
|
|
10
|
+
import type { Provider } from './provider.js';
|
|
11
|
+
import { TaskAgent } from './task-agent.js';
|
|
12
|
+
interface ComponentInfo {
|
|
13
|
+
id: string;
|
|
14
|
+
name: string;
|
|
15
|
+
role: string;
|
|
16
|
+
locator: string;
|
|
17
|
+
preferredCode: string;
|
|
18
|
+
eidx: string;
|
|
19
|
+
description: string;
|
|
20
|
+
html: string;
|
|
21
|
+
text: string;
|
|
22
|
+
tag: string;
|
|
23
|
+
classes: string[];
|
|
24
|
+
attrs: Record<string, string>;
|
|
25
|
+
context: string;
|
|
26
|
+
variant: string;
|
|
27
|
+
placeholder: string;
|
|
28
|
+
disabled: boolean;
|
|
29
|
+
ariaMatches: string[];
|
|
30
|
+
}
|
|
31
|
+
interface InteractionResult {
|
|
32
|
+
componentId: string;
|
|
33
|
+
component: string;
|
|
34
|
+
action: string;
|
|
35
|
+
result: 'success' | 'failed' | 'unknown';
|
|
36
|
+
description: string;
|
|
37
|
+
code?: string;
|
|
38
|
+
}
|
|
39
|
+
interface ComponentTest extends Test {
|
|
40
|
+
component?: ComponentInfo;
|
|
41
|
+
interactions?: InteractionResult[];
|
|
42
|
+
}
|
|
43
|
+
interface DrillOptions {
|
|
44
|
+
knowledgePath?: string;
|
|
45
|
+
maxComponents?: number;
|
|
46
|
+
interactive?: boolean;
|
|
47
|
+
}
|
|
48
|
+
export declare class Driller extends TaskAgent implements Agent {
|
|
49
|
+
readonly ACTION_TOOLS: string[];
|
|
50
|
+
emoji: string;
|
|
51
|
+
explorer: Explorer;
|
|
52
|
+
provider: Provider;
|
|
53
|
+
navigator: Navigator;
|
|
54
|
+
hooksRunner: HooksRunner;
|
|
55
|
+
currentPlan?: Plan;
|
|
56
|
+
allResults: InteractionResult[];
|
|
57
|
+
verifiedAction: {
|
|
58
|
+
componentId: string;
|
|
59
|
+
toolName: string;
|
|
60
|
+
code?: string;
|
|
61
|
+
canonicalCode?: string;
|
|
62
|
+
} | null;
|
|
63
|
+
pendingNestedContext: string | null;
|
|
64
|
+
MAX_COMPONENT_ITERATIONS: number;
|
|
65
|
+
constructor(explorer: Explorer, provider: Provider, navigator: Navigator);
|
|
66
|
+
getNavigator(): Navigator;
|
|
67
|
+
getExperienceTracker(): ExperienceTracker;
|
|
68
|
+
getKnowledgeTracker(): KnowledgeTracker;
|
|
69
|
+
getProvider(): Provider;
|
|
70
|
+
getSystemMessage(component?: ComponentInfo): string;
|
|
71
|
+
drill(opts?: DrillOptions): Promise<Plan>;
|
|
72
|
+
captureAnnotatedState(): Promise<ActionResult>;
|
|
73
|
+
collectComponents(state: ActionResult, maxComponents: number): Promise<ComponentInfo[]>;
|
|
74
|
+
toComponentInfo(element: WebElement, ariaNodes: Array<Record<string, unknown>>): ComponentInfo;
|
|
75
|
+
drillComponent(test: ComponentTest, originalState: ActionResult, interactive: boolean): Promise<void>;
|
|
76
|
+
buildComponentPrompt(originalState: ActionResult, component: ComponentInfo): Promise<string>;
|
|
77
|
+
buildContextUpdate(currentState: ActionResult, component: ComponentInfo): Promise<string>;
|
|
78
|
+
createDrillFlowTools(originalState: ActionResult, test: ComponentTest, interactive: boolean): {
|
|
79
|
+
drill_record: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
80
|
+
action: any;
|
|
81
|
+
result: any;
|
|
82
|
+
code: any;
|
|
83
|
+
}, {
|
|
84
|
+
success: boolean;
|
|
85
|
+
message: string;
|
|
86
|
+
recorded?: undefined;
|
|
87
|
+
} | {
|
|
88
|
+
success: boolean;
|
|
89
|
+
recorded: string;
|
|
90
|
+
message?: undefined;
|
|
91
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
92
|
+
drill_done: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
93
|
+
summary: any;
|
|
94
|
+
}, {
|
|
95
|
+
success: boolean;
|
|
96
|
+
message: string;
|
|
97
|
+
summary?: undefined;
|
|
98
|
+
recorded?: undefined;
|
|
99
|
+
} | {
|
|
100
|
+
success: boolean;
|
|
101
|
+
summary: any;
|
|
102
|
+
recorded: number;
|
|
103
|
+
message?: undefined;
|
|
104
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
105
|
+
drill_skip: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
106
|
+
reason: any;
|
|
107
|
+
}, {
|
|
108
|
+
success: boolean;
|
|
109
|
+
message: string;
|
|
110
|
+
skipped?: undefined;
|
|
111
|
+
} | {
|
|
112
|
+
success: boolean;
|
|
113
|
+
skipped: string;
|
|
114
|
+
message?: undefined;
|
|
115
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
116
|
+
drill_restore: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
117
|
+
reason: any;
|
|
118
|
+
}, {
|
|
119
|
+
success: boolean;
|
|
120
|
+
url: string;
|
|
121
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
122
|
+
drill_ask: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
123
|
+
question: any;
|
|
124
|
+
}, {
|
|
125
|
+
success: boolean;
|
|
126
|
+
message: string;
|
|
127
|
+
skipped?: undefined;
|
|
128
|
+
userSuggestion?: undefined;
|
|
129
|
+
instruction?: undefined;
|
|
130
|
+
} | {
|
|
131
|
+
success: boolean;
|
|
132
|
+
skipped: boolean;
|
|
133
|
+
message?: undefined;
|
|
134
|
+
userSuggestion?: undefined;
|
|
135
|
+
instruction?: undefined;
|
|
136
|
+
} | {
|
|
137
|
+
success: boolean;
|
|
138
|
+
userSuggestion: string;
|
|
139
|
+
instruction: string;
|
|
140
|
+
message?: undefined;
|
|
141
|
+
skipped?: undefined;
|
|
142
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
143
|
+
};
|
|
144
|
+
restoreOriginalState(originalState: ActionResult, reason: string): Promise<void>;
|
|
145
|
+
saveToExperience(state: ActionResult, results: InteractionResult[]): Promise<void>;
|
|
146
|
+
createVerifiedActionTools(baseTools: Record<string, any>, component: ComponentInfo): Record<string, any>;
|
|
147
|
+
hasVerifiedAction(componentId: string): boolean;
|
|
148
|
+
detectNestedOverlayContext(component: ComponentInfo, result: any): Promise<string | null>;
|
|
149
|
+
getVisibleOverlayHtml(): Promise<string>;
|
|
150
|
+
getComponentScopeHtml(component: ComponentInfo, originalState: ActionResult): Promise<string>;
|
|
151
|
+
saveToKnowledge(knowledgePath: string, state: ActionResult, results: InteractionResult[]): Promise<void>;
|
|
152
|
+
generateKnowledgeContent(state: ActionResult, interactions: InteractionResult[]): string;
|
|
153
|
+
logSummary(): void;
|
|
154
|
+
}
|
|
155
|
+
export declare function buildCanonicalClickCode(component: ComponentInfo): string;
|
|
156
|
+
export declare function formatExperienceTitle(interaction: InteractionResult): string;
|
|
157
|
+
export {};
|
package/dist/src/ai/driller.js
CHANGED
|
@@ -11,7 +11,7 @@ import { EXPLORBOT_ATTRS, HTML_COMPOSITE_AREA_HINTS, HTML_COMPOSITE_TARGET_ROLES
|
|
|
11
11
|
import { createDebug, tag } from "../utils/logger.js";
|
|
12
12
|
import { loop, pause } from "../utils/loop.js";
|
|
13
13
|
import { WebElement } from "../utils/web-element.js";
|
|
14
|
-
import {
|
|
14
|
+
import { drillLocatorRule } from "./rules.js";
|
|
15
15
|
import { TaskAgent, isInteractive } from "./task-agent.js";
|
|
16
16
|
import { createCodeceptJSTools } from "./tools.js";
|
|
17
17
|
const debugLog = createDebug('explorbot:driller');
|
|
@@ -23,7 +23,6 @@ export class Driller extends TaskAgent {
|
|
|
23
23
|
navigator;
|
|
24
24
|
hooksRunner;
|
|
25
25
|
currentPlan;
|
|
26
|
-
currentConversation = null;
|
|
27
26
|
allResults = [];
|
|
28
27
|
verifiedAction = null;
|
|
29
28
|
pendingNestedContext = null;
|
|
@@ -245,7 +244,6 @@ export class Driller extends TaskAgent {
|
|
|
245
244
|
this.verifiedAction = null;
|
|
246
245
|
this.pendingNestedContext = null;
|
|
247
246
|
const conversation = this.provider.startConversation(this.getSystemMessage(component), 'driller');
|
|
248
|
-
this.currentConversation = conversation;
|
|
249
247
|
conversation.addUserText(await this.buildComponentPrompt(originalState, component));
|
|
250
248
|
let finished = false;
|
|
251
249
|
const actionTools = this.createVerifiedActionTools(createCodeceptJSTools(this.explorer, test), component);
|
|
@@ -506,10 +504,10 @@ export class Driller extends TaskAgent {
|
|
|
506
504
|
const targetUrl = originalState.fullUrl || originalState.url;
|
|
507
505
|
const action = this.explorer.createAction();
|
|
508
506
|
if (currentState?.url !== originalState.url) {
|
|
509
|
-
await action.attempt(`I.amOnPage(${JSON.stringify(targetUrl)})`, `${reason} (restore URL)
|
|
507
|
+
await action.attempt(`I.amOnPage(${JSON.stringify(targetUrl)})`, `${reason} (restore URL)`);
|
|
510
508
|
return;
|
|
511
509
|
}
|
|
512
|
-
await action.attempt('I.pressKey("Escape")', `${reason} (restore state)
|
|
510
|
+
await action.attempt('I.pressKey("Escape")', `${reason} (restore state)`);
|
|
513
511
|
}
|
|
514
512
|
async saveToExperience(state, results) {
|
|
515
513
|
const experienceTracker = this.getExperienceTracker();
|
|
@@ -667,12 +665,6 @@ export class Driller extends TaskAgent {
|
|
|
667
665
|
tag('step').log(` ${status} ${componentTest.component?.name || test.scenario}`);
|
|
668
666
|
}
|
|
669
667
|
}
|
|
670
|
-
getCurrentPlan() {
|
|
671
|
-
return this.currentPlan;
|
|
672
|
-
}
|
|
673
|
-
getConversation() {
|
|
674
|
-
return this.currentConversation;
|
|
675
|
-
}
|
|
676
668
|
}
|
|
677
669
|
function formatAriaNode(node) {
|
|
678
670
|
const role = typeof node.role === 'string' ? node.role : 'unknown';
|
|
@@ -1105,4 +1097,3 @@ function isInteractiveElement(element) {
|
|
|
1105
1097
|
return true;
|
|
1106
1098
|
return false;
|
|
1107
1099
|
}
|
|
1108
|
-
const drillLocatorRule = locatorRule.replace(/<context_simplification>[\s\S]*?<\/context_simplification>/, '').trim();
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { type ExperienceFile, type ExperienceTracker } from '../experience-tracker.js';
|
|
2
|
+
import type { Agent } from './agent.js';
|
|
3
|
+
import type { Provider } from './provider.js';
|
|
4
|
+
export declare const COMPACT_MAX_LENGTH = 5000;
|
|
5
|
+
interface MergeGroup {
|
|
6
|
+
pattern: string;
|
|
7
|
+
files: ExperienceFile[];
|
|
8
|
+
}
|
|
9
|
+
export declare class ExperienceCompactor implements Agent {
|
|
10
|
+
emoji: string;
|
|
11
|
+
provider: Provider;
|
|
12
|
+
experienceTracker: ExperienceTracker;
|
|
13
|
+
constructor(provider: Provider, experienceTracker: ExperienceTracker);
|
|
14
|
+
compactExperience(experience: string): Promise<string>;
|
|
15
|
+
stripNonUsefulEntries(content: string): string;
|
|
16
|
+
isRecent(file: ExperienceFile): boolean;
|
|
17
|
+
reviewExperienceQuality(content: string, context: {
|
|
18
|
+
url?: string;
|
|
19
|
+
title?: string;
|
|
20
|
+
}): Promise<string>;
|
|
21
|
+
compactAllExperiences(): Promise<{
|
|
22
|
+
merged: number;
|
|
23
|
+
compacted: number;
|
|
24
|
+
}>;
|
|
25
|
+
autocompact(): Promise<{
|
|
26
|
+
merged: number;
|
|
27
|
+
compacted: number;
|
|
28
|
+
}>;
|
|
29
|
+
generalizeDynamicUrls(): number;
|
|
30
|
+
compactFiles(files: ExperienceFile[], options?: {
|
|
31
|
+
skipSmall?: boolean;
|
|
32
|
+
}): Promise<number>;
|
|
33
|
+
mergeSimilarExperiences(options?: {
|
|
34
|
+
onlyDynamic?: boolean;
|
|
35
|
+
}): Promise<number>;
|
|
36
|
+
identifyMergeGroups(files: ExperienceFile[]): Promise<MergeGroup[]>;
|
|
37
|
+
askAiForMergeDecisions(urls: string[]): Promise<{
|
|
38
|
+
urls: string[];
|
|
39
|
+
pattern: string;
|
|
40
|
+
}[]>;
|
|
41
|
+
buildMergePrompt(urls: string[]): string;
|
|
42
|
+
mergeExperienceGroup(group: MergeGroup): Promise<void>;
|
|
43
|
+
getSystemPrompt(): string;
|
|
44
|
+
buildCompactionPrompt(content: string): string;
|
|
45
|
+
buildReviewPrompt(sections: Array<{
|
|
46
|
+
title: string;
|
|
47
|
+
raw: string;
|
|
48
|
+
}>, context: {
|
|
49
|
+
url?: string;
|
|
50
|
+
title?: string;
|
|
51
|
+
}): string;
|
|
52
|
+
}
|
|
53
|
+
export {};
|
|
@@ -1,25 +1,26 @@
|
|
|
1
1
|
import { unlinkSync } from 'node:fs';
|
|
2
|
+
import { basename } from 'node:path';
|
|
2
3
|
import dedent from 'dedent';
|
|
3
|
-
import { marked } from 'marked';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
import { RECENT_WINDOW_DAYS } from '../experience-tracker.js';
|
|
6
6
|
import { Observability } from '../observability.js';
|
|
7
7
|
import { createDebug, log, tag } from '../utils/logger.js';
|
|
8
8
|
import { mdq } from '../utils/markdown-query.js';
|
|
9
|
+
import { isNonReusableCode } from '../utils/step-analyzer.js';
|
|
9
10
|
import { generalizeUrl, hasDynamicUrlSegment } from '../utils/url-matcher.js';
|
|
10
11
|
const debugLog = createDebug('explorbot:experience-compactor');
|
|
12
|
+
export const COMPACT_MAX_LENGTH = 5000;
|
|
11
13
|
export class ExperienceCompactor {
|
|
12
14
|
emoji = '🗜️';
|
|
13
15
|
provider;
|
|
14
16
|
experienceTracker;
|
|
15
|
-
MAX_LENGTH = 5000;
|
|
16
17
|
constructor(provider, experienceTracker) {
|
|
17
18
|
this.provider = provider;
|
|
18
19
|
this.experienceTracker = experienceTracker;
|
|
19
20
|
}
|
|
20
21
|
async compactExperience(experience) {
|
|
21
22
|
const stripped = this.stripNonUsefulEntries(experience);
|
|
22
|
-
if (stripped.length <
|
|
23
|
+
if (stripped.length < COMPACT_MAX_LENGTH) {
|
|
23
24
|
return stripped;
|
|
24
25
|
}
|
|
25
26
|
const prompt = this.buildCompactionPrompt(stripped);
|
|
@@ -101,7 +102,7 @@ export class ExperienceCompactor {
|
|
|
101
102
|
const generalized = generalizeUrl(url);
|
|
102
103
|
if (generalized === url)
|
|
103
104
|
continue;
|
|
104
|
-
const stateHash = file.filePath
|
|
105
|
+
const stateHash = basename(file.filePath, '.md');
|
|
105
106
|
const newData = { ...file.data, url: `~${generalized}~`, mergedFrom: [url] };
|
|
106
107
|
this.experienceTracker.writeExperienceFile(stateHash, file.content, newData);
|
|
107
108
|
tag('substep').log(`Generalized URL: ${url} → ~${generalized}~`);
|
|
@@ -110,7 +111,7 @@ export class ExperienceCompactor {
|
|
|
110
111
|
return count;
|
|
111
112
|
}
|
|
112
113
|
async compactFiles(files, options) {
|
|
113
|
-
const workingSet = options?.skipSmall ? files.filter((f) => f.content.length >=
|
|
114
|
+
const workingSet = options?.skipSmall ? files.filter((f) => f.content.length >= COMPACT_MAX_LENGTH) : files;
|
|
114
115
|
let compactedCount = 0;
|
|
115
116
|
const total = workingSet.length;
|
|
116
117
|
const aiReviewCount = workingSet.filter((f) => this.isRecent(f)).length;
|
|
@@ -119,7 +120,7 @@ export class ExperienceCompactor {
|
|
|
119
120
|
}
|
|
120
121
|
for (let i = 0; i < workingSet.length; i++) {
|
|
121
122
|
const experience = workingSet[i];
|
|
122
|
-
const shortName = experience.filePath
|
|
123
|
+
const shortName = basename(experience.filePath);
|
|
123
124
|
const willReview = this.isRecent(experience);
|
|
124
125
|
if (total > 1 && willReview) {
|
|
125
126
|
tag('substep').log(`[${i + 1}/${total}] reviewing ${shortName}`);
|
|
@@ -128,9 +129,9 @@ export class ExperienceCompactor {
|
|
|
128
129
|
if (willReview) {
|
|
129
130
|
content = await this.reviewExperienceQuality(content, experience.data);
|
|
130
131
|
}
|
|
131
|
-
if (content.length >=
|
|
132
|
+
if (content.length >= COMPACT_MAX_LENGTH) {
|
|
132
133
|
if (total > 1)
|
|
133
|
-
tag('substep').log(`[${i + 1}/${total}] compacting ${shortName} (over ${
|
|
134
|
+
tag('substep').log(`[${i + 1}/${total}] compacting ${shortName} (over ${COMPACT_MAX_LENGTH} chars)`);
|
|
134
135
|
const prompt = this.buildCompactionPrompt(content);
|
|
135
136
|
const model = this.provider.getModelForAgent('experience-compactor');
|
|
136
137
|
const response = await this.provider.chat([
|
|
@@ -141,7 +142,7 @@ export class ExperienceCompactor {
|
|
|
141
142
|
}
|
|
142
143
|
if (content === experience.content)
|
|
143
144
|
continue;
|
|
144
|
-
const stateHash = experience.filePath
|
|
145
|
+
const stateHash = basename(experience.filePath, '.md');
|
|
145
146
|
this.experienceTracker.writeExperienceFile(stateHash, content, experience.data);
|
|
146
147
|
debugLog('Experience file compacted:', experience.filePath);
|
|
147
148
|
compactedCount++;
|
|
@@ -250,7 +251,7 @@ export class ExperienceCompactor {
|
|
|
250
251
|
async mergeExperienceGroup(group) {
|
|
251
252
|
const [targetFile, ...sourceFiles] = group.files;
|
|
252
253
|
const combinedContent = group.files.map((f) => f.content).join('\n\n---\n\n');
|
|
253
|
-
const targetStateHash = targetFile.filePath
|
|
254
|
+
const targetStateHash = basename(targetFile.filePath, '.md');
|
|
254
255
|
const newFrontmatter = {
|
|
255
256
|
...targetFile.data,
|
|
256
257
|
url: group.pattern,
|
|
@@ -283,7 +284,7 @@ export class ExperienceCompactor {
|
|
|
283
284
|
<rules>
|
|
284
285
|
- Use markdown h2 headers only (##) - NO XML tags or wrappers in output
|
|
285
286
|
- Merge similar flows to remove duplicates
|
|
286
|
-
- Keep output under ${
|
|
287
|
+
- Keep output under ${COMPACT_MAX_LENGTH} characters
|
|
287
288
|
- Be explicit and short - no proposals or explanations
|
|
288
289
|
|
|
289
290
|
KEEP only:
|
|
@@ -368,27 +369,9 @@ export class ExperienceCompactor {
|
|
|
368
369
|
}
|
|
369
370
|
}
|
|
370
371
|
function listSections(content) {
|
|
371
|
-
const
|
|
372
|
-
const
|
|
373
|
-
|
|
374
|
-
let currentRaw = '';
|
|
375
|
-
const flush = () => {
|
|
376
|
-
if (currentHeading !== null)
|
|
377
|
-
sections.push({ title: currentHeading, raw: currentRaw });
|
|
378
|
-
};
|
|
379
|
-
for (const token of tokens) {
|
|
380
|
-
const raw = token.raw || '';
|
|
381
|
-
if (token.type === 'heading' && token.depth === 2) {
|
|
382
|
-
flush();
|
|
383
|
-
currentHeading = token.text.trim();
|
|
384
|
-
currentRaw = raw;
|
|
385
|
-
continue;
|
|
386
|
-
}
|
|
387
|
-
if (currentHeading !== null)
|
|
388
|
-
currentRaw += raw;
|
|
389
|
-
}
|
|
390
|
-
flush();
|
|
391
|
-
return sections;
|
|
372
|
+
const sections = mdq(content).query('section2').each();
|
|
373
|
+
const metas = mdq(content).query('section2').meta();
|
|
374
|
+
return sections.map((q, i) => ({ title: metas[i].text.trim(), raw: q.text() }));
|
|
392
375
|
}
|
|
393
376
|
function dropEmptySections(content) {
|
|
394
377
|
let result = content;
|
|
@@ -408,7 +391,7 @@ function dropNonReusableSections(content) {
|
|
|
408
391
|
const sections = [...mdq(result).query('section2(~"FLOW:")').each(), ...mdq(result).query('section2(~"ACTION:")').each()];
|
|
409
392
|
for (const section of sections) {
|
|
410
393
|
const raw = section.text();
|
|
411
|
-
if (
|
|
394
|
+
if (!isNonReusableCode(raw))
|
|
412
395
|
continue;
|
|
413
396
|
result = result.replace(raw, '');
|
|
414
397
|
}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import type { ApiClient } from '../api/api-client.js';
|
|
2
|
+
import type { RequestStore } from '../api/request-store.js';
|
|
3
|
+
export declare function createFishermanTools(apiClient: ApiClient, requestStore: RequestStore, opts: {
|
|
4
|
+
spec?: any;
|
|
5
|
+
baseEndpoint?: string;
|
|
6
|
+
}): {
|
|
7
|
+
tools: {
|
|
8
|
+
getEndpointSpec: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
9
|
+
method: any;
|
|
10
|
+
path: any;
|
|
11
|
+
}, {
|
|
12
|
+
source: string;
|
|
13
|
+
method: string;
|
|
14
|
+
path: string;
|
|
15
|
+
status: number;
|
|
16
|
+
requestBody: any;
|
|
17
|
+
definition?: undefined;
|
|
18
|
+
error?: undefined;
|
|
19
|
+
} | {
|
|
20
|
+
source: string;
|
|
21
|
+
definition: string;
|
|
22
|
+
method?: undefined;
|
|
23
|
+
path?: undefined;
|
|
24
|
+
status?: undefined;
|
|
25
|
+
requestBody?: undefined;
|
|
26
|
+
error?: undefined;
|
|
27
|
+
} | {
|
|
28
|
+
source: string;
|
|
29
|
+
error: any;
|
|
30
|
+
method?: undefined;
|
|
31
|
+
path?: undefined;
|
|
32
|
+
status?: undefined;
|
|
33
|
+
requestBody?: undefined;
|
|
34
|
+
definition?: undefined;
|
|
35
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
36
|
+
request: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<any, {
|
|
37
|
+
success: boolean;
|
|
38
|
+
error: string;
|
|
39
|
+
status?: undefined;
|
|
40
|
+
statusText?: undefined;
|
|
41
|
+
errorPreview?: undefined;
|
|
42
|
+
} | {
|
|
43
|
+
success: boolean;
|
|
44
|
+
status: number;
|
|
45
|
+
statusText: string;
|
|
46
|
+
errorPreview: string;
|
|
47
|
+
error?: undefined;
|
|
48
|
+
} | {
|
|
49
|
+
success: boolean;
|
|
50
|
+
status: number;
|
|
51
|
+
error?: undefined;
|
|
52
|
+
statusText?: undefined;
|
|
53
|
+
errorPreview?: undefined;
|
|
54
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
55
|
+
finish: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
56
|
+
summary: string;
|
|
57
|
+
created: {
|
|
58
|
+
type: string;
|
|
59
|
+
id?: string | number;
|
|
60
|
+
title?: string;
|
|
61
|
+
}[];
|
|
62
|
+
failed?: {
|
|
63
|
+
type: string;
|
|
64
|
+
reason: string;
|
|
65
|
+
}[];
|
|
66
|
+
}, {
|
|
67
|
+
finished: boolean;
|
|
68
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
69
|
+
stop: import("@ai-sdk/provider-utils").ExecutableTool<import("ai").Tool<{
|
|
70
|
+
reason: any;
|
|
71
|
+
}, {
|
|
72
|
+
stopped: boolean;
|
|
73
|
+
}, import("@ai-sdk/provider-utils").Context>>;
|
|
74
|
+
};
|
|
75
|
+
getResult: () => FishermanResult;
|
|
76
|
+
isFinished: () => boolean;
|
|
77
|
+
};
|
|
78
|
+
export interface FishermanResult {
|
|
79
|
+
success: boolean;
|
|
80
|
+
summary: string;
|
|
81
|
+
created: Array<{
|
|
82
|
+
type: string;
|
|
83
|
+
id?: string | number;
|
|
84
|
+
title?: string;
|
|
85
|
+
}>;
|
|
86
|
+
failed: Array<{
|
|
87
|
+
type: string;
|
|
88
|
+
reason: string;
|
|
89
|
+
}>;
|
|
90
|
+
}
|
|
@@ -136,7 +136,7 @@ function extractKeyFields(body, result = {}, depth = 0) {
|
|
|
136
136
|
return result;
|
|
137
137
|
}
|
|
138
138
|
for (const [key, value] of Object.entries(body)) {
|
|
139
|
-
if (value
|
|
139
|
+
if (value == null)
|
|
140
140
|
continue;
|
|
141
141
|
if (typeof value === 'object') {
|
|
142
142
|
extractKeyFields(value, result, depth + 1);
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { ApiClient } from '../api/api-client.js';
|
|
2
|
+
import type { RequestStore } from '../api/request-store.js';
|
|
3
|
+
import type { Agent } from './agent.js';
|
|
4
|
+
import { type FishermanResult } from './fisherman-tools.js';
|
|
5
|
+
import type { Provider } from './provider.js';
|
|
6
|
+
export declare class Fisherman implements Agent {
|
|
7
|
+
emoji: string;
|
|
8
|
+
provider: Provider;
|
|
9
|
+
apiClient: ApiClient;
|
|
10
|
+
requestStore: RequestStore;
|
|
11
|
+
specLoader: () => Promise<any | null>;
|
|
12
|
+
cookieProvider: () => Promise<Record<string, string>>;
|
|
13
|
+
configHeaders: Record<string, string>;
|
|
14
|
+
sessionName?: string;
|
|
15
|
+
baseEndpoint: string;
|
|
16
|
+
spec: any | null;
|
|
17
|
+
mode: 'replicate' | 'achieve' | 'disabled';
|
|
18
|
+
hasApiConfig: boolean;
|
|
19
|
+
constructor(provider: Provider, apiClient: ApiClient, requestStore: RequestStore, specLoader: () => Promise<any | null>, baseEndpoint: string, cookieProvider: () => Promise<Record<string, string>>, configHeaders?: Record<string, string>, hasApiConfig?: boolean);
|
|
20
|
+
isAvailable(): boolean;
|
|
21
|
+
ensureReady(scopeUrl?: string): Promise<void>;
|
|
22
|
+
getEndpointList(scopeUrl?: string): string;
|
|
23
|
+
prepareData(instructions: string, scopeUrl?: string, sessionName?: string): Promise<FishermanResult>;
|
|
24
|
+
detectMode(scopeUrl?: string): Promise<void>;
|
|
25
|
+
refreshAuth(): Promise<void>;
|
|
26
|
+
buildEndpointList(scopeUrl?: string): string;
|
|
27
|
+
buildSystemPrompt(endpointList: string, toolNames: string[], scopeUrl?: string): string;
|
|
28
|
+
buildTaskPrompt(instructions: string): string;
|
|
29
|
+
}
|
package/dist/src/ai/fisherman.js
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { StateManager } from '../../state-manager.js';
|
|
2
|
+
import type { Plan } from '../../test-plan.js';
|
|
3
|
+
import type { Conversation } from '../conversation.js';
|
|
4
|
+
import type { Constructor } from './mixin.js';
|
|
5
|
+
export interface CodeceptJSMethods {
|
|
6
|
+
toCode(conversation: Conversation, scenario: string): string;
|
|
7
|
+
saveCodeceptPlanToFile(plan: Plan): string;
|
|
8
|
+
}
|
|
9
|
+
export declare function WithCodeceptJS<T extends Constructor>(Base: T): {
|
|
10
|
+
new (...args: any[]): {
|
|
11
|
+
savedFiles: Set<string>;
|
|
12
|
+
stateManager?: StateManager;
|
|
13
|
+
toCode(conversation: Conversation, scenario: string): string;
|
|
14
|
+
saveCodeceptPlanToFile(plan: Plan): string;
|
|
15
|
+
getKnowledgeLines(url: string, indent?: string): string[];
|
|
16
|
+
};
|
|
17
|
+
} & T;
|
|
@@ -2,7 +2,6 @@ import { mkdirSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { ActionResult } from "../../action-result.js";
|
|
4
4
|
import { ConfigParser } from "../../config.js";
|
|
5
|
-
import { KnowledgeTracker } from "../../knowledge-tracker.js";
|
|
6
5
|
import { tag } from "../../utils/logger.js";
|
|
7
6
|
import { relativeToCwd } from "../../utils/next-steps.js";
|
|
8
7
|
import { safeFilename } from "../../utils/strings.js";
|
|
@@ -87,7 +86,9 @@ export function WithCodeceptJS(Base) {
|
|
|
87
86
|
return filePath;
|
|
88
87
|
}
|
|
89
88
|
getKnowledgeLines(url, indent = ' ') {
|
|
90
|
-
const knowledgeTracker =
|
|
89
|
+
const knowledgeTracker = this.stateManager?.getKnowledgeTracker();
|
|
90
|
+
if (!knowledgeTracker)
|
|
91
|
+
return [];
|
|
91
92
|
const state = new ActionResult({ url });
|
|
92
93
|
const { wait, waitForElement, code } = knowledgeTracker.getStateParameters(state, ['wait', 'waitForElement', 'code']);
|
|
93
94
|
const lines = [];
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import { ActionResult } from '../../action-result.js';
|
|
2
|
+
import { ExperienceTracker, type SessionStep } from '../../experience-tracker.js';
|
|
3
|
+
import type { Reporter } from '../../reporter.js';
|
|
4
|
+
import type { StateManager } from '../../state-manager.js';
|
|
5
|
+
import { type Task, Test } from '../../test-plan.js';
|
|
6
|
+
import type { Conversation, ToolExecution } from '../conversation.js';
|
|
7
|
+
import type { Provider } from '../provider.js';
|
|
8
|
+
import { type Constructor } from './mixin.js';
|
|
9
|
+
export interface ExperienceMethods {
|
|
10
|
+
saveSession(task: Task, initialState: ActionResult, conversation: Conversation): Promise<void>;
|
|
11
|
+
}
|
|
12
|
+
export declare function WithExperience<T extends Constructor>(Base: T): {
|
|
13
|
+
new (...args: any[]): {
|
|
14
|
+
provider: Provider;
|
|
15
|
+
experienceTracker: ExperienceTracker;
|
|
16
|
+
reporter: Reporter | undefined;
|
|
17
|
+
stateManager: StateManager | undefined;
|
|
18
|
+
isPlaywrightFramework: () => boolean;
|
|
19
|
+
toCode: (conversation: Conversation, scenario: string) => string;
|
|
20
|
+
toPlaywrightCode: (conversation: Conversation, scenario: string) => Promise<string>;
|
|
21
|
+
stopScreencast: () => Promise<void>;
|
|
22
|
+
saveSession(task: Task, initialState: ActionResult, conversation: Conversation): Promise<void>;
|
|
23
|
+
reportSession(test: Test, steps: SessionStep[]): Promise<void>;
|
|
24
|
+
extractSteps(toolExecutions: ToolExecution[]): Promise<SessionStep[]>;
|
|
25
|
+
hasRelevantFlowExperience(state: ActionResult): boolean;
|
|
26
|
+
extractPassedCodeceptSteps(task: Task): SessionStep[];
|
|
27
|
+
curateFlow(steps: SessionStep[], task: Task, initialState: ActionResult): Promise<string>;
|
|
28
|
+
renderFlowFromSuccessfulSteps(steps: SessionStep[], task: Task): string;
|
|
29
|
+
detectRetryPatterns(toolExecutions: ToolExecution[], initialState: ActionResult): Promise<void>;
|
|
30
|
+
analyzeDiscoveries(stepsWithDiffs: Array<{
|
|
31
|
+
step: SessionStep;
|
|
32
|
+
ariaDiff: string | null;
|
|
33
|
+
}>): Promise<void>;
|
|
34
|
+
buildDiscoveryPrompt(stepsWithDiffs: Array<{
|
|
35
|
+
step: SessionStep;
|
|
36
|
+
ariaDiff: string | null;
|
|
37
|
+
}>): string;
|
|
38
|
+
extractVisitedUrls(toolExecutions: ToolExecution[], initialUrl: string): string[];
|
|
39
|
+
};
|
|
40
|
+
} & T;
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { StateManager } from '../../state-manager.js';
|
|
2
|
+
import { type PlaywrightRecorder } from '../../playwright-recorder.js';
|
|
3
|
+
import type { Plan } from '../../test-plan.js';
|
|
4
|
+
import type { Conversation } from '../conversation.js';
|
|
5
|
+
import type { Constructor } from './mixin.js';
|
|
6
|
+
export interface PlaywrightMethods {
|
|
7
|
+
toPlaywrightCode(conversation: Conversation, scenario: string): Promise<string>;
|
|
8
|
+
savePlaywrightPlanToFile(plan: Plan): string;
|
|
9
|
+
}
|
|
10
|
+
export declare function WithPlaywright<T extends Constructor>(Base: T): {
|
|
11
|
+
new (...args: any[]): {
|
|
12
|
+
playwright: {
|
|
13
|
+
recorder: PlaywrightRecorder;
|
|
14
|
+
helper: any;
|
|
15
|
+
} | undefined;
|
|
16
|
+
savedFiles: Set<string>;
|
|
17
|
+
stateManager?: StateManager;
|
|
18
|
+
toPlaywrightCode(conversation: Conversation, scenario: string): Promise<string>;
|
|
19
|
+
savePlaywrightPlanToFile(plan: Plan): string;
|
|
20
|
+
getPlaywrightKnowledgeLines(url: string, indent?: string): string[];
|
|
21
|
+
};
|
|
22
|
+
} & T;
|
|
@@ -2,7 +2,6 @@ import { mkdirSync, writeFileSync } from 'node:fs';
|
|
|
2
2
|
import { join } from 'node:path';
|
|
3
3
|
import { ActionResult } from "../../action-result.js";
|
|
4
4
|
import { ConfigParser } from "../../config.js";
|
|
5
|
-
import { KnowledgeTracker } from "../../knowledge-tracker.js";
|
|
6
5
|
import { renderAssertion, renderCall } from "../../playwright-recorder.js";
|
|
7
6
|
import { tag } from "../../utils/logger.js";
|
|
8
7
|
import { relativeToCwd } from "../../utils/next-steps.js";
|
|
@@ -124,7 +123,9 @@ export function WithPlaywright(Base) {
|
|
|
124
123
|
return filePath;
|
|
125
124
|
}
|
|
126
125
|
getPlaywrightKnowledgeLines(url, indent = ' ') {
|
|
127
|
-
const knowledgeTracker =
|
|
126
|
+
const knowledgeTracker = this.stateManager?.getKnowledgeTracker();
|
|
127
|
+
if (!knowledgeTracker)
|
|
128
|
+
return [];
|
|
128
129
|
const state = new ActionResult({ url });
|
|
129
130
|
const { wait, waitForElement } = knowledgeTracker.getStateParameters(state, ['wait', 'waitForElement']);
|
|
130
131
|
const lines = [];
|