explorbot 0.2.3 → 0.2.5
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 +1 -1
- package/bin/explorbot-cli.ts +26 -8
- package/boat/api-tester/src/cli.ts +17 -0
- package/boat/api-tester/src/config.ts +4 -2
- package/boat/doc-collector/bin/doc-collector-cli.ts +2 -0
- package/boat/doc-collector/src/ai/documentarian.ts +61 -31
- package/boat/doc-collector/src/cli.ts +14 -1
- package/boat/doc-collector/src/config.ts +4 -2
- package/boat/prima/bin/prima-cli.ts +0 -0
- package/boat/prima/src/activity-line.ts +33 -0
- package/boat/prima/src/cli.ts +127 -86
- package/boat/prima/src/envelope.ts +102 -52
- package/boat/prima/src/prima.ts +567 -128
- package/boat/prima/src/pw-parser.ts +11 -1
- package/boat/prima/src/pw-registry.ts +4 -5
- package/boat/prima/src/session-log.ts +126 -0
- package/dist/bin/explorbot-cli.js +26 -8
- package/dist/boat/api-tester/bin/apibot-cli.js +2 -0
- package/dist/boat/api-tester/src/cli.js +17 -0
- package/dist/boat/api-tester/src/config.js +4 -2
- package/dist/boat/doc-collector/bin/doc-collector-cli.js +2 -0
- package/dist/boat/doc-collector/src/ai/documentarian.js +44 -19
- package/dist/boat/doc-collector/src/cli.js +14 -1
- package/dist/boat/doc-collector/src/config.js +4 -2
- package/dist/boat/prima/src/activity-line.js +30 -0
- package/dist/boat/prima/src/cli.js +109 -77
- package/dist/boat/prima/src/envelope.js +94 -44
- package/dist/boat/prima/src/prima.js +533 -119
- package/dist/boat/prima/src/pw-parser.js +13 -1
- package/dist/boat/prima/src/pw-registry.js +4 -5
- package/dist/boat/prima/src/session-log.js +108 -0
- package/dist/package.json +3 -2
- package/dist/rules/navigator/verification-actions.md +20 -0
- package/dist/src/action-result.d.ts +7 -0
- package/dist/src/action-result.js +4 -0
- package/dist/src/action.d.ts +2 -0
- package/dist/src/action.js +41 -2
- package/dist/src/ai/captain/web-mode.js +6 -3
- package/dist/src/ai/captain.js +2 -0
- package/dist/src/ai/navigator.d.ts +34 -0
- package/dist/src/ai/navigator.js +237 -181
- package/dist/src/ai/pilot.d.ts +7 -0
- package/dist/src/ai/pilot.js +90 -2
- package/dist/src/ai/provider.d.ts +2 -2
- package/dist/src/ai/provider.js +14 -23
- package/dist/src/ai/rerunner.js +2 -1
- package/dist/src/ai/researcher/cache.d.ts +2 -0
- package/dist/src/ai/researcher/cache.js +10 -2
- package/dist/src/ai/researcher.js +3 -2
- package/dist/src/ai/rules.js +17 -10
- package/dist/src/ai/session-analyst.js +2 -0
- package/dist/src/ai/task-agent.js +4 -1
- package/dist/src/ai/tester.d.ts +6 -3
- package/dist/src/ai/tester.js +50 -46
- package/dist/src/ai/tools.d.ts +14 -0
- package/dist/src/ai/tools.js +117 -37
- package/dist/src/commands/config-command.d.ts +51 -0
- package/dist/src/commands/config-command.js +117 -0
- package/dist/src/commands/index.js +2 -0
- package/dist/src/config.d.ts +9 -1
- package/dist/src/config.js +53 -4
- package/dist/src/execution-controller.d.ts +2 -0
- package/dist/src/execution-controller.js +6 -0
- package/dist/src/explorbot.d.ts +2 -1
- package/dist/src/explorbot.js +7 -2
- package/dist/src/explorer.js +2 -3
- package/dist/src/playwright-recorder.js +30 -0
- package/dist/src/remote.d.ts +55 -0
- package/dist/src/remote.js +235 -0
- package/dist/src/reporter.d.ts +1 -0
- package/dist/src/reporter.js +7 -1
- package/dist/src/state-manager.d.ts +2 -1
- package/dist/src/state-manager.js +3 -1
- package/dist/src/stats.d.ts +1 -0
- package/dist/src/stats.js +1 -0
- package/dist/src/test-plan.d.ts +3 -0
- package/dist/src/test-plan.js +26 -0
- package/dist/src/utils/aria.d.ts +2 -8
- package/dist/src/utils/aria.js +69 -40
- package/dist/src/utils/html.js +1 -0
- package/dist/src/utils/logger.d.ts +7 -1
- package/dist/src/utils/logger.js +32 -0
- package/dist/src/utils/page-readiness.js +18 -1
- package/dist/src/utils/url-matcher.js +3 -0
- package/dist/src/utils/web-element.d.ts +2 -0
- package/dist/src/utils/web-element.js +8 -0
- package/dist/src/utils/web-sandbox.d.ts +1 -1
- package/dist/src/utils/web-sandbox.js +2 -3
- package/docs/api-testing/basics.md +90 -0
- package/docs/api-testing/planning.md +57 -0
- package/docs/api-testing/running-tests.md +55 -0
- package/docs/assets/cloud-report.png +0 -0
- package/docs/assets/html-report.png +0 -0
- package/docs/assets/langfuse-trace.png +0 -0
- package/docs/assets/successful-explore-run.png +0 -0
- package/docs/basics/getting-started.md +140 -0
- package/docs/basics/prerequisites.md +63 -0
- package/docs/basics/providers.md +362 -0
- package/docs/basics/running.md +78 -0
- package/docs/contributing/ai-integration-tests.md +57 -0
- package/docs/contributing/contributing.md +90 -0
- package/docs/contributing/demo-videos.md +36 -0
- package/docs/contributing/npm-package.md +138 -0
- package/docs/contributing/observability.md +227 -0
- package/docs/contributing/regression-tests.md +103 -0
- package/docs/contributing/testing.md +95 -0
- package/docs/doc-collection/basics.md +128 -0
- package/docs/doc-collection/crawling.md +67 -0
- package/docs/doc-collection/interactive-mode.md +99 -0
- package/docs/index.json +87 -0
- package/docs/reference/commands.md +997 -0
- package/docs/reference/configuration.md +569 -0
- package/docs/reference/scripting.md +303 -0
- package/docs/reference/websocket.md +50 -0
- package/docs/superpowers/plans/2026-08-01-actor-boat.md +925 -0
- package/docs/superpowers/plans/2026-08-01-prima-boat.md +1120 -0
- package/docs/superpowers/reviews/2026-08-06-prima-vs-playwright-cli.md +268 -0
- package/docs/superpowers/specs/2026-08-01-actor-boat-design.md +204 -0
- package/docs/superpowers/specs/2026-08-01-prima-boat-design.md +242 -0
- package/docs/superpowers/specs/2026-08-03-global-config-design.md +138 -0
- package/docs/superpowers/specs/2026-08-07-prima-fixes-design.md +394 -0
- package/docs/superpowers/specs/2026-08-18-prima-false-verdicts.md +159 -0
- package/docs/web-testing/agents.md +158 -0
- package/docs/web-testing/automated-tests.md +134 -0
- package/docs/web-testing/basics.md +91 -0
- package/docs/web-testing/customization.md +131 -0
- package/docs/web-testing/hooks.md +238 -0
- package/docs/web-testing/page-interaction.md +84 -0
- package/docs/web-testing/planner.md +122 -0
- package/docs/web-testing/rerun.md +164 -0
- package/docs/web-testing/researcher.md +380 -0
- package/docs/workflow/agentic-usage.md +233 -0
- package/docs/workflow/application-spec.md +73 -0
- package/docs/workflow/ci.md +202 -0
- package/docs/workflow/knowledge.md +310 -0
- package/docs/workflow/planning-styles.md +67 -0
- package/docs/workflow/reporting.md +133 -0
- package/docs/workflow/test-plans.md +90 -0
- package/package.json +3 -2
- package/rules/navigator/verification-actions.md +20 -0
- package/src/action-result.ts +11 -0
- package/src/action.ts +43 -3
- package/src/ai/captain/web-mode.ts +6 -3
- package/src/ai/captain.ts +3 -0
- package/src/ai/navigator.ts +255 -186
- package/src/ai/pilot.ts +104 -2
- package/src/ai/provider.ts +14 -24
- package/src/ai/rerunner.ts +2 -1
- package/src/ai/researcher/cache.ts +12 -2
- package/src/ai/researcher.ts +3 -2
- package/src/ai/rules.ts +17 -10
- package/src/ai/session-analyst.ts +2 -0
- package/src/ai/task-agent.ts +3 -1
- package/src/ai/tester.ts +52 -45
- package/src/ai/tools.ts +136 -37
- package/src/commands/config-command.ts +146 -0
- package/src/commands/index.ts +2 -0
- package/src/config.ts +60 -5
- package/src/execution-controller.ts +8 -0
- package/src/explorbot.ts +7 -3
- package/src/explorer.ts +2 -2
- package/src/playwright-recorder.ts +23 -0
- package/src/remote.ts +244 -0
- package/src/reporter.ts +7 -1
- package/src/state-manager.ts +6 -2
- package/src/stats.ts +1 -0
- package/src/test-plan.ts +29 -0
- package/src/utils/aria.ts +65 -45
- package/src/utils/html.ts +1 -0
- package/src/utils/logger.ts +33 -2
- package/src/utils/page-readiness.ts +24 -1
- package/src/utils/url-matcher.ts +3 -0
- package/src/utils/web-element.ts +9 -0
- package/src/utils/web-sandbox.ts +3 -4
|
@@ -0,0 +1,362 @@
|
|
|
1
|
+
# AI Provider Configuration
|
|
2
|
+
|
|
3
|
+
Explorbot connects to AI providers through the [Vercel AI SDK](https://sdk.vercel.ai/). Use any supported provider, and mix providers across different models.
|
|
4
|
+
|
|
5
|
+
> The `export default` config block inside each `<!-- START/END provider -->` marker is generated from [`models.json`](../../models.json). After editing that file, run `bunosh docs:sync`. Everything else — including the import blocks — is hand-written.
|
|
6
|
+
|
|
7
|
+
## Requirements
|
|
8
|
+
|
|
9
|
+
Your model must support:
|
|
10
|
+
- Structured output (JSON mode)
|
|
11
|
+
- Tool use (function calling)
|
|
12
|
+
|
|
13
|
+
To analyze screenshots, you also need a vision-capable model.
|
|
14
|
+
|
|
15
|
+
Explorbot uses three roles:
|
|
16
|
+
|
|
17
|
+
- `model` for token-heavy page reading of ARIA & HTMLs (cheap & fast).
|
|
18
|
+
- `visionModel` for screenshot analysis
|
|
19
|
+
- `agenticModel` as advisor and planner.
|
|
20
|
+
|
|
21
|
+
Pick a fast, cheap model for the first two and a stronger one for the third. When a provider has no recommended model for one of these roles, combine it with another provider for that role.
|
|
22
|
+
|
|
23
|
+
### OpenRouter
|
|
24
|
+
|
|
25
|
+
Start with OpenRouter. One key reaches [many providers and models](https://openrouter.ai/models).
|
|
26
|
+
Openrouter is an optimal solution as you can balance the models and provider for best price and speed.
|
|
27
|
+
So if your goal is to optimize costs, choose Openrouter.
|
|
28
|
+
|
|
29
|
+
> Openrouter is recommended to start as it serves best models
|
|
30
|
+
|
|
31
|
+
Install the provider package:
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
npm i @openrouter/ai-sdk-provider
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
Import it inside `explorbot.config.ts` and create the client from your API key:
|
|
38
|
+
|
|
39
|
+
```javascript
|
|
40
|
+
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
|
|
41
|
+
|
|
42
|
+
const openrouter = createOpenRouter({
|
|
43
|
+
apiKey: process.env.OPENROUTER_API_KEY,
|
|
44
|
+
});
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Set the recommended models in the exported config:
|
|
48
|
+
|
|
49
|
+
<!-- START provider:openrouter -->
|
|
50
|
+
```javascript
|
|
51
|
+
export default {
|
|
52
|
+
ai: {
|
|
53
|
+
model: openrouter('openai/gpt-oss-20b:nitro'),
|
|
54
|
+
visionModel: openrouter('google/gemma-4-31b-it:nitro'),
|
|
55
|
+
agenticModel: openrouter('google/gemma-4-31b-it:nitro'),
|
|
56
|
+
},
|
|
57
|
+
};
|
|
58
|
+
```
|
|
59
|
+
<!-- END provider:openrouter -->
|
|
60
|
+
|
|
61
|
+
Pick model IDs from [OpenRouter](https://openrouter.ai/) that support structured output and tools. The `:nitro` variants route to the fastest available host.
|
|
62
|
+
|
|
63
|
+
### Groq
|
|
64
|
+
|
|
65
|
+
Install the provider package:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
npm i @ai-sdk/groq
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Import it inside `explorbot.config.ts` and create the client from your API key:
|
|
72
|
+
|
|
73
|
+
```javascript
|
|
74
|
+
import { createGroq } from '@ai-sdk/groq';
|
|
75
|
+
|
|
76
|
+
const groq = createGroq({
|
|
77
|
+
apiKey: process.env.GROQ_API_KEY,
|
|
78
|
+
});
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
Set the recommended models in the exported config:
|
|
82
|
+
|
|
83
|
+
<!-- START provider:groq -->
|
|
84
|
+
```javascript
|
|
85
|
+
export default {
|
|
86
|
+
ai: {
|
|
87
|
+
model: groq('openai/gpt-oss-20b'),
|
|
88
|
+
visionModel: groq('qwen/qwen3.6-27b'),
|
|
89
|
+
agenticModel: groq('qwen/qwen3.6-27b'),
|
|
90
|
+
},
|
|
91
|
+
};
|
|
92
|
+
```
|
|
93
|
+
<!-- END provider:groq -->
|
|
94
|
+
|
|
95
|
+
The gpt-oss models are fast and cheap; the larger 120B handles the agenticModel role.
|
|
96
|
+
|
|
97
|
+
### OpenAI
|
|
98
|
+
|
|
99
|
+
Install the provider package:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
npm i @ai-sdk/openai
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Import it inside `explorbot.config.ts` and create the client from your API key:
|
|
106
|
+
|
|
107
|
+
```javascript
|
|
108
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
109
|
+
|
|
110
|
+
const openai = createOpenAI({
|
|
111
|
+
apiKey: process.env.OPENAI_API_KEY,
|
|
112
|
+
});
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Set the recommended models in the exported config:
|
|
116
|
+
|
|
117
|
+
<!-- START provider:openai -->
|
|
118
|
+
```javascript
|
|
119
|
+
export default {
|
|
120
|
+
ai: {
|
|
121
|
+
model: openai('gpt-5.4-nano'),
|
|
122
|
+
visionModel: openai('gpt-5.4-nano'),
|
|
123
|
+
agenticModel: openai('gpt-5.6-luna'),
|
|
124
|
+
},
|
|
125
|
+
};
|
|
126
|
+
```
|
|
127
|
+
<!-- END provider:openai -->
|
|
128
|
+
|
|
129
|
+
### Anthropic
|
|
130
|
+
|
|
131
|
+
Claude Haiku is the only Anthropic model suited to Explorbot, and even it is too costly per token for the token-heavy roles, so we recommend it only for the low-volume agenticModel. Use a cheaper provider for `model` and `visionModel` (see [Multi-Provider Configuration](#multi-provider-configuration)).
|
|
132
|
+
|
|
133
|
+
Install the provider package:
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
npm i @ai-sdk/anthropic
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
Import it inside `explorbot.config.ts` and create the client from your API key:
|
|
140
|
+
|
|
141
|
+
```javascript
|
|
142
|
+
import { createAnthropic } from '@ai-sdk/anthropic';
|
|
143
|
+
|
|
144
|
+
const anthropic = createAnthropic({
|
|
145
|
+
apiKey: process.env.ANTHROPIC_API_KEY,
|
|
146
|
+
});
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
Set the recommended model in the exported config:
|
|
150
|
+
|
|
151
|
+
<!-- START provider:anthropic -->
|
|
152
|
+
```javascript
|
|
153
|
+
export default {
|
|
154
|
+
ai: {
|
|
155
|
+
agenticModel: anthropic('claude-haiku-4-5-20251001'),
|
|
156
|
+
},
|
|
157
|
+
};
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
> [!NOTE]
|
|
161
|
+
> This provider currently doesn't serve `model` and `visionModel`, which is required for Explorbot to run at optimal cost and speed.
|
|
162
|
+
> It is recommended to pair it with another AI provider.
|
|
163
|
+
<!-- END provider:anthropic -->
|
|
164
|
+
|
|
165
|
+
### Azure OpenAI
|
|
166
|
+
|
|
167
|
+
Install the provider package:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
npm i @ai-sdk/azure
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
Import it inside `explorbot.config.ts` and create the client from your resource name and API key:
|
|
174
|
+
|
|
175
|
+
```javascript
|
|
176
|
+
import { createAzure } from '@ai-sdk/azure';
|
|
177
|
+
|
|
178
|
+
const azure = createAzure({
|
|
179
|
+
resourceName: process.env.AZURE_RESOURCE_NAME,
|
|
180
|
+
apiKey: process.env.AZURE_API_KEY,
|
|
181
|
+
});
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Set the models in the exported config, using the deployment names you created in your resource:
|
|
185
|
+
|
|
186
|
+
```javascript
|
|
187
|
+
export default {
|
|
188
|
+
ai: {
|
|
189
|
+
model: azure('your-deployment-name'),
|
|
190
|
+
visionModel: azure('your-deployment-name'),
|
|
191
|
+
agenticModel: azure('your-deployment-name'),
|
|
192
|
+
},
|
|
193
|
+
};
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
Azure addresses models by the deployment names you create in your resource, not by public model IDs. Use separate deployments if chat and vision run on different endpoints.
|
|
197
|
+
|
|
198
|
+
### Google (Gemini)
|
|
199
|
+
|
|
200
|
+
An API key from [Google AI Studio](https://aistudio.google.com/apikey) already has the Gemini API enabled. A key from the Google Cloud console may need the API enabled first, and service-account (Vertex Express) keys use a different API surface than the one this provider targets.
|
|
201
|
+
|
|
202
|
+
Install the provider package:
|
|
203
|
+
|
|
204
|
+
```bash
|
|
205
|
+
npm i @ai-sdk/google
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
Import it inside `explorbot.config.ts` and create the client from your API key:
|
|
209
|
+
|
|
210
|
+
```javascript
|
|
211
|
+
import { createGoogleGenerativeAI } from '@ai-sdk/google';
|
|
212
|
+
|
|
213
|
+
const google = createGoogleGenerativeAI({
|
|
214
|
+
apiKey: process.env.GOOGLE_API_KEY,
|
|
215
|
+
});
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
Set the recommended models in the exported config:
|
|
219
|
+
|
|
220
|
+
<!-- START provider:google -->
|
|
221
|
+
```javascript
|
|
222
|
+
export default {
|
|
223
|
+
ai: {
|
|
224
|
+
model: google('gemini-3.1-flash-lite'),
|
|
225
|
+
visionModel: google('gemini-3.1-flash-lite'),
|
|
226
|
+
agenticModel: google('gemini-3.5-flash'),
|
|
227
|
+
},
|
|
228
|
+
};
|
|
229
|
+
```
|
|
230
|
+
<!-- END provider:google -->
|
|
231
|
+
|
|
232
|
+
The flash-lite tier is the cheapest current option for the token-heavy `model` and `visionModel` roles; the full flash is stronger for the low-volume `agenticModel`.
|
|
233
|
+
|
|
234
|
+
On a free (no-billing) key the `agenticModel` is heavily rate-limited and will fail with quota errors mid-session — keep every role on the flash-lite model or enable billing. Google also retires older models for new accounts: `gemini-2.5-flash` and `gemini-2.5-flash-lite` return a 404 for keys created after their cutoff, and enabling billing does not bring them back.
|
|
235
|
+
|
|
236
|
+
Note: Gemini models are slower than hosted OSS models on Groq or Cerebras. Everything works, sessions just take more wall-clock time.
|
|
237
|
+
|
|
238
|
+
### Mistral
|
|
239
|
+
|
|
240
|
+
Install the provider package:
|
|
241
|
+
|
|
242
|
+
```bash
|
|
243
|
+
npm i @ai-sdk/mistral
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
Import it inside `explorbot.config.ts` and create the client from your API key:
|
|
247
|
+
|
|
248
|
+
```javascript
|
|
249
|
+
import { createMistral } from '@ai-sdk/mistral';
|
|
250
|
+
|
|
251
|
+
const mistral = createMistral({
|
|
252
|
+
apiKey: process.env.MISTRAL_API_KEY,
|
|
253
|
+
});
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
Set the recommended models in the exported config:
|
|
257
|
+
|
|
258
|
+
<!-- START provider:mistral -->
|
|
259
|
+
```javascript
|
|
260
|
+
export default {
|
|
261
|
+
ai: {
|
|
262
|
+
model: mistral('mistral-small-latest'),
|
|
263
|
+
visionModel: mistral('mistral-small-latest'),
|
|
264
|
+
agenticModel: mistral('mistral-large-latest'),
|
|
265
|
+
},
|
|
266
|
+
};
|
|
267
|
+
```
|
|
268
|
+
<!-- END provider:mistral -->
|
|
269
|
+
|
|
270
|
+
Mistral Small covers the token-heavy `model` and `visionModel` roles — it accepts image input, so it can read screenshots. Mistral Large, the larger multimodal flagship, handles the low-volume `agenticModel`. The `-latest` aliases track Mistral's newest release of each, so recommendations keep up as models ship.
|
|
271
|
+
|
|
272
|
+
### Poolside
|
|
273
|
+
|
|
274
|
+
Poolside serves an OpenAI-compatible endpoint, so it uses the OpenAI provider package with a custom `baseURL`:
|
|
275
|
+
|
|
276
|
+
```bash
|
|
277
|
+
npm i @ai-sdk/openai
|
|
278
|
+
```
|
|
279
|
+
|
|
280
|
+
Import it inside `explorbot.config.ts` and point the client at the poolside endpoint:
|
|
281
|
+
|
|
282
|
+
```javascript
|
|
283
|
+
import { createOpenAI } from '@ai-sdk/openai';
|
|
284
|
+
|
|
285
|
+
const poolside = createOpenAI({
|
|
286
|
+
apiKey: process.env.POOLSIDE_API_KEY,
|
|
287
|
+
baseURL: 'https://inference.poolside.ai/v1',
|
|
288
|
+
});
|
|
289
|
+
```
|
|
290
|
+
|
|
291
|
+
Set the recommended models in the exported config:
|
|
292
|
+
|
|
293
|
+
<!-- START provider:poolside -->
|
|
294
|
+
```javascript
|
|
295
|
+
export default {
|
|
296
|
+
ai: {
|
|
297
|
+
model: poolside('poolside/laguna-xs-2.1'),
|
|
298
|
+
},
|
|
299
|
+
};
|
|
300
|
+
```
|
|
301
|
+
|
|
302
|
+
> [!NOTE]
|
|
303
|
+
> This provider currently doesn't serve `visionModel` and `agenticModel`, which is required for Explorbot to run at optimal cost and speed.
|
|
304
|
+
> It is recommended to pair it with another AI provider.
|
|
305
|
+
<!-- END provider:poolside -->
|
|
306
|
+
|
|
307
|
+
Laguna XS is an agentic coding model — fast, cheap, and reliable at tool calling, which makes it a good fit for the token-heavy `model` role that reads page HTML and drives the browser.
|
|
308
|
+
|
|
309
|
+
Keep `agenticModel` on another provider. Poolside's endpoint accepts `response_format: json_schema` but does not enforce it, so structured-output calls depend on the model volunteering valid JSON. Laguna XS usually does; Laguna S answers in prose instead, which makes it unusable for the Planner, Pilot, and Captain. Laguna S is also slow enough under page-sized prompts to hit Explorbot's request timeouts, so it is not a substitute for Laguna XS in the `model` role either.
|
|
310
|
+
|
|
311
|
+
## Multi-Provider Configuration
|
|
312
|
+
|
|
313
|
+
Mix clients the same way you assign `model`, `visionModel`, and `agenticModel`. Each field can use a different provider instance — a fast provider does the token-heavy reading while a stronger one makes the decisions:
|
|
314
|
+
|
|
315
|
+
```javascript
|
|
316
|
+
import { createGroq } from '@ai-sdk/groq';
|
|
317
|
+
import { createOpenRouter } from '@openrouter/ai-sdk-provider';
|
|
318
|
+
|
|
319
|
+
const groq = createGroq({ apiKey: process.env.GROQ_API_KEY });
|
|
320
|
+
const openrouter = createOpenRouter({ apiKey: process.env.OPENROUTER_API_KEY });
|
|
321
|
+
|
|
322
|
+
export default {
|
|
323
|
+
ai: {
|
|
324
|
+
model: groq('openai/gpt-oss-20b'),
|
|
325
|
+
visionModel: groq('meta-llama/llama-4-scout-17b-16e-instruct'),
|
|
326
|
+
agenticModel: openrouter('minimax/minimax-m2.5:nitro'),
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
```
|
|
330
|
+
|
|
331
|
+
## Per-Agent Model Configuration
|
|
332
|
+
|
|
333
|
+
Any agent can override the defaults. Add an `agents` block and set per-agent options — a different `model` (using any client shown above) or a `reasoning` level:
|
|
334
|
+
|
|
335
|
+
```javascript
|
|
336
|
+
export default {
|
|
337
|
+
ai: {
|
|
338
|
+
// ...your model, visionModel, agenticModel...
|
|
339
|
+
agents: {
|
|
340
|
+
researcher: { reasoning: 'low' },
|
|
341
|
+
planner: { reasoning: 'none' },
|
|
342
|
+
tester: { reasoning: 'none' },
|
|
343
|
+
},
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
See [Configuration](../reference/configuration.md) for every per-agent option.
|
|
349
|
+
|
|
350
|
+
## Environment Variables
|
|
351
|
+
|
|
352
|
+
Set your API key as an environment variable, or use a `.env` file in your project root:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
export OPENROUTER_API_KEY=your-key-here
|
|
356
|
+
export GROQ_API_KEY=your-key-here
|
|
357
|
+
export CEREBRAS_API_KEY=your-key-here
|
|
358
|
+
export OPENAI_API_KEY=your-key-here
|
|
359
|
+
export ANTHROPIC_API_KEY=your-key-here
|
|
360
|
+
export GOOGLE_API_KEY=your-key-here
|
|
361
|
+
export MISTRAL_API_KEY=your-key-here
|
|
362
|
+
```
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# Running Explorbot: TUI and CLI
|
|
2
|
+
|
|
3
|
+
There are two ways to run Explorbot: an interactive terminal UI where you watch and steer, and plain CLI commands that do one job and exit. Same engine, same config, same artifacts — the difference is whether you are in the loop.
|
|
4
|
+
|
|
5
|
+
| Use | Choose it when | Start with |
|
|
6
|
+
|-----|----------------|------------|
|
|
7
|
+
| **TUI** | You are learning, steering, or debugging interactively | `npx explorbot start /path` |
|
|
8
|
+
| **CLI** | You want one repeatable task that prints a result and exits | `npx explorbot explore /path` |
|
|
9
|
+
| **Persistent browser** | You run several local commands and want to avoid starting a new browser process each time | `npx explorbot browser start --show` |
|
|
10
|
+
| **CI** | You need unattended, scheduled, or pipeline runs with saved reports | `npx explorbot explore /path --max-tests 10` |
|
|
11
|
+
|
|
12
|
+
Persistent browser is an optimization for local TUI or CLI work, while CI uses CLI commands. Each command still creates a fresh browser context; use `--session` when cookies and login state must carry over. See [Persistent Browser](../reference/commands.md#persistent-browser) and [Continuous Integration](../workflow/ci.md) for setup details.
|
|
13
|
+
|
|
14
|
+
## TUI mode
|
|
15
|
+
|
|
16
|
+
`npx explorbot start` opens the interactive terminal UI. Pass a path to start on a specific page:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
npx explorbot start /admin/projects
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
The screen splits into a log pane, where everything Explorbot does is printed as it happens, and an input line at the bottom. Type slash-commands to drive it:
|
|
23
|
+
|
|
24
|
+
```
|
|
25
|
+
/explore # full loop: research, plan, test, repeat
|
|
26
|
+
/research # analyze the current page
|
|
27
|
+
/plan # propose test scenarios
|
|
28
|
+
/test # run the next test
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
You can also type raw CodeceptJS commands — `I.click('Save')`, `I.amOnPage('/login')` — and they execute in the browser immediately. In interactive mode the bot asks you for help when it gets stuck, instead of giving up.
|
|
32
|
+
|
|
33
|
+
Use the TUI for:
|
|
34
|
+
|
|
35
|
+
- **First runs.** You see every step and every mistake as it happens.
|
|
36
|
+
- **Teaching Explorbot your app.** Watch it fail, add a knowledge file, retry — the tight loop is what the TUI is for.
|
|
37
|
+
- **Debugging a failing scenario.** Replay it step by step with slash-commands and raw `I.*` commands.
|
|
38
|
+
|
|
39
|
+
The TUI needs a modern terminal — iTerm2, WARP, Kitty, Ghostty, or Windows Terminal with WSL; see [Prerequisites](./prerequisites.md) for the compatibility notes.
|
|
40
|
+
|
|
41
|
+
## CLI mode
|
|
42
|
+
|
|
43
|
+
Every other command runs without the TUI: it launches a browser (headless by default), does its job, prints the result, and exits.
|
|
44
|
+
|
|
45
|
+
| Command | What it does | Docs |
|
|
46
|
+
|---------|--------------|------|
|
|
47
|
+
| `explore <path>` | Research a page, plan tests, run them, move to sub-pages | [Web Testing Basics](../web-testing/basics.md) |
|
|
48
|
+
| `plan <path>` | Generate a test plan as markdown and exit | [Test Plans](../workflow/test-plans.md) |
|
|
49
|
+
| `test <planfile> [index]` | Run tests from a saved plan | [Test Plans](../workflow/test-plans.md) |
|
|
50
|
+
| `rerun <file>` | Re-run generated tests with AI healing | [Rerun](../web-testing/rerun.md) |
|
|
51
|
+
| `docs collect <url>` | Crawl pages and generate documentation | [Doc Collection](../doc-collection/basics.md) |
|
|
52
|
+
| `api plan` / `api test` / `api explore` | Plan and run API tests | [API Testing](../api-testing/basics.md) |
|
|
53
|
+
|
|
54
|
+
The full list, with every option, is in the [Commands reference](../reference/commands.md).
|
|
55
|
+
|
|
56
|
+
### Exit codes
|
|
57
|
+
|
|
58
|
+
CLI commands follow one rule: exit `0` when the run completed, `1` when the run itself failed — a config error, an unreachable start page, a provider that won't respond. Before exiting, the CLI shows a short session summary if anything happened during the run.
|
|
59
|
+
|
|
60
|
+
For `explore` and `test`, a failing test does **not** change the exit code. The run completed; the failure is a result, printed in the console summary and recorded in the reports. So `npx explorbot explore / || echo broken` catches crashes, not bugs. To gate a pipeline on test results, read the reports — see [Continuous Integration](../workflow/ci.md).
|
|
61
|
+
|
|
62
|
+
A few commands have sharper semantics you can script against:
|
|
63
|
+
|
|
64
|
+
- `plan` exits `1` when no test scenarios could be generated.
|
|
65
|
+
- `navigate <url>` exits `0` when the page was reached, `1` when not — a cheap "is the app up and can we log in" probe.
|
|
66
|
+
- `api test` and `api explore` exit `1` when any test failed.
|
|
67
|
+
|
|
68
|
+
## Flags that matter in both modes
|
|
69
|
+
|
|
70
|
+
The browser runs headless by default; `--show` opens a visible window and `--headless` forces it hidden. `--session [file]` saves and restores the browser session (cookies, localStorage) — the default file is `output/session.json` — so login happens once and later runs skip it. `--incognito` runs without recording experience, useful for throwaway runs. `--verbose` prints debug logs. See the [Commands reference](../reference/commands.md) for the rest.
|
|
71
|
+
|
|
72
|
+
## Driving Explorbot from other tools
|
|
73
|
+
|
|
74
|
+
CLI mode makes Explorbot scriptable by anything that can run a shell command — including coding agents like Claude Code. Every input and output is plain markdown: plans land in `output/plans/`, reports in `output/reports/`, and hints live in `knowledge/`. An agent can run `explorbot plan /checkout`, read the generated plan, edit or extend it, run `explorbot test` on it, read the report, then write a knowledge file to fix what confused the bot — and iterate. No API or SDK needed; the files are the interface.
|
|
75
|
+
|
|
76
|
+
## Running in CI
|
|
77
|
+
|
|
78
|
+
Because CLI commands exit cleanly and keep their learning in cacheable directories, Explorbot fits scheduled pipelines: run `explore` nightly with a test budget, cache `experience/` and `output/` between runs, and upload the reports. See [Continuous Integration](../workflow/ci.md) for worked examples.
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
# AI Agent Integration Tests
|
|
2
|
+
|
|
3
|
+
We test AI agents with [`@copilotkit/aimock`](https://github.com/CopilotKit/aimock), an HTTP mock server that speaks LLM provider protocols. Unlike in-process model stubs, it runs the real `Provider` class and lets you inspect the HTTP requests through its Journal.
|
|
4
|
+
|
|
5
|
+
Reference implementation: `tests/integration/planner.test.ts`.
|
|
6
|
+
|
|
7
|
+
## Principles
|
|
8
|
+
|
|
9
|
+
### What we mock
|
|
10
|
+
|
|
11
|
+
- **The AI provider** — via the aimock HTTP server. Point the Vercel AI SDK at `mock.url/v1` with `createOpenAI({ compatibility: 'compatible' })` and `openai.chat('model-name')`. The `compatibility: 'compatible'` option keeps the mock on the Chat Completions API; without it, the SDK defaults to the Responses API, which aimock does not fully implement.
|
|
12
|
+
- **Explorer, StateManager, Researcher, ExperienceTracker** — duck-typed mocks with only the methods the agent under test calls. Each agent runs in isolation; downstream agents (such as Researcher when testing Planner) return canned output.
|
|
13
|
+
- **`withPage`** — resolves with a fake page object for agents that validate locators, since no browser runs in these tests.
|
|
14
|
+
|
|
15
|
+
### What we don't mock
|
|
16
|
+
|
|
17
|
+
- The real `Provider` class, so tests exercise serialization, retry, and telemetry paths.
|
|
18
|
+
- Parsers, result objects, and markdown processing — the real pipeline runs.
|
|
19
|
+
- `ActionResult.fromState()`, which works without the filesystem when `state.html` is inline.
|
|
20
|
+
|
|
21
|
+
### What we test
|
|
22
|
+
|
|
23
|
+
- **Output correctness**: the plan or research markdown the agent returns matches the canned AI response.
|
|
24
|
+
- **Prompt construction** (via Journal): `mock.getLastRequest()` returns the messages sent to the AI, so you assert on what the agent prompted, not just what it returned. This is the main reason to use aimock.
|
|
25
|
+
- **Control flow**: cache hits, dedup, retries, error paths, and style or feature injection. Inspect the request count and prompt content.
|
|
26
|
+
|
|
27
|
+
### Fixture types
|
|
28
|
+
|
|
29
|
+
- Text response (for `chat()` / `invokeConversation()`): `mock.on({}, { content: 'text' })`
|
|
30
|
+
- Structured output (for `generateObject()`): `mock.on({}, { content: JSON.stringify(obj) })` — the SDK parses it back via `response_format: json_schema`
|
|
31
|
+
- Sequential responses: `mock.on({ sequenceIndex: 0 }, ...)`, `sequenceIndex: 1`, ...
|
|
32
|
+
- Errors: `mock.on({}, { error: {...}, status: 500 })`
|
|
33
|
+
- See aimock docs for matching by user message, tool name, regex, or predicate.
|
|
34
|
+
|
|
35
|
+
### Test data
|
|
36
|
+
|
|
37
|
+
- Canned UI maps live in `test-data/ui-maps/`.
|
|
38
|
+
- Use fictional applications (Task Tracker, and so on). Never use real product data or user names.
|
|
39
|
+
- Two formats exist, depending on the agent under test:
|
|
40
|
+
- **Planner-input** (`task-board.md`): Element and Type columns only — what the Planner sees after its own table-column filtering.
|
|
41
|
+
- **Researcher-output** (`task-board-research.md`): full Element, Type, ARIA, CSS, and Coordinates columns — the raw Researcher AI output format.
|
|
42
|
+
|
|
43
|
+
### Module-level caches
|
|
44
|
+
|
|
45
|
+
Many agents hold module-level state: plan registry, session dedup, style cache, research cache. Each module that caches across calls must export a `clearXxx()` function for use in `beforeEach`. See the existing exports:
|
|
46
|
+
|
|
47
|
+
- `src/ai/planner/subpages.ts` — `clearPlanRegistry()`
|
|
48
|
+
- `src/ai/planner/session-dedup.ts` — `clearSessionDedup()`
|
|
49
|
+
- `src/ai/planner/styles.ts` — `clearStyleCache()`
|
|
50
|
+
- `src/ai/researcher/cache.ts` — `clearResearchCache()`
|
|
51
|
+
|
|
52
|
+
## Running
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
bun test tests/integration/planner.test.ts
|
|
56
|
+
bun test tests/integration/
|
|
57
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
# Contributing to Explorbot
|
|
2
|
+
|
|
3
|
+
## Project Philosophy
|
|
4
|
+
|
|
5
|
+
Explorbot is general-purpose. It works with any web application, with no site-specific code. Keep this in mind when you contribute:
|
|
6
|
+
|
|
7
|
+
- Solutions must work across different websites.
|
|
8
|
+
- Don't hardcode locators or site-specific selectors.
|
|
9
|
+
- Prefer universal patterns: ARIA, semantic HTML, common UI conventions.
|
|
10
|
+
- A fix that only helps one site is probably the wrong approach.
|
|
11
|
+
|
|
12
|
+
## Before You Start
|
|
13
|
+
|
|
14
|
+
Discuss first, code second. Open an issue to propose your idea before you send a PR. This saves wasted effort and aligns on the approach.
|
|
15
|
+
|
|
16
|
+
If Explorbot struggles on your site, try the built-in extension points first:
|
|
17
|
+
|
|
18
|
+
- Knowledge files teach Explorbot about your pages (credentials, wait conditions, hints).
|
|
19
|
+
- Rules add agent-specific guidance for navigation, research, and planning.
|
|
20
|
+
- Hooks run custom logic before and after actions.
|
|
21
|
+
- Configuration adjusts models, timeouts, and browser settings.
|
|
22
|
+
|
|
23
|
+
See the [knowledge](../workflow/knowledge.md), [hooks](../web-testing/hooks.md), and [configuration](../reference/configuration.md) docs.
|
|
24
|
+
|
|
25
|
+
## Pull Requests
|
|
26
|
+
|
|
27
|
+
We accept PRs that help a variety of users. Here is what gets merged.
|
|
28
|
+
|
|
29
|
+
### Tiny PRs get merged first
|
|
30
|
+
|
|
31
|
+
Small, focused changes are reviewed and merged quickly. Examples:
|
|
32
|
+
|
|
33
|
+
- Fix a typo in a prompt.
|
|
34
|
+
- Add a missing ARIA selector pattern.
|
|
35
|
+
- Improve an error message.
|
|
36
|
+
- Fix a bug with a clear reproduction.
|
|
37
|
+
|
|
38
|
+
### PRs that change agent logic require manual testing
|
|
39
|
+
|
|
40
|
+
Changes to agents (tester, navigator, researcher, pilot, and others) affect how Explorbot interacts with every website. These PRs must be:
|
|
41
|
+
|
|
42
|
+
- Polished — clean code, no leftover debug artifacts.
|
|
43
|
+
- Tested by a person on real websites.
|
|
44
|
+
- Described clearly: what changed and why.
|
|
45
|
+
|
|
46
|
+
### PRs that change prompts require execution traces
|
|
47
|
+
|
|
48
|
+
If you change internal AI prompts or rules, you must provide a [Langfuse](https://langfuse.com) execution trace that shows the change improved behavior. "It should work better" is not evidence. Show the before and after.
|
|
49
|
+
|
|
50
|
+
### We accept agentic PRs
|
|
51
|
+
|
|
52
|
+
AI-generated contributions are welcome if they follow the rules above: small, focused, tested, with clear explanations.
|
|
53
|
+
|
|
54
|
+
### What NOT to send
|
|
55
|
+
|
|
56
|
+
- PRs that reformat code differently. We use [Biome](https://biomejs.dev/) for formatting. Run `bun run format` before submitting.
|
|
57
|
+
- Large refactoring PRs without prior discussion.
|
|
58
|
+
- Site-specific fixes that only help one website.
|
|
59
|
+
- Changes that break existing tests.
|
|
60
|
+
|
|
61
|
+
## Development Setup
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
bun install
|
|
65
|
+
bunx playwright install
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Code Style
|
|
69
|
+
|
|
70
|
+
- Biome for formatting and linting. Run `bun run format` after every change.
|
|
71
|
+
- No comments unless explicitly needed.
|
|
72
|
+
- Early returns instead of nested if/else.
|
|
73
|
+
- KISS/YAGNI — make the smallest change possible.
|
|
74
|
+
- No code duplication. Check if it already exists.
|
|
75
|
+
- Use dedent for formatting prompts.
|
|
76
|
+
- No ternary operators.
|
|
77
|
+
|
|
78
|
+
See `CLAUDE.md` for the full guidelines.
|
|
79
|
+
|
|
80
|
+
## Testing
|
|
81
|
+
|
|
82
|
+
Run `bun run format`, `bun run lint`, `bun run test:unit`, and `bun run test:node` before you submit a PR — all checks must pass. See the [testing guide](testing.md) for details, [AI integration tests](ai-integration-tests.md) for mocked-LLM agent tests, and [regression tests](regression-tests.md) for the real-AI end-to-end harness.
|
|
83
|
+
|
|
84
|
+
## Using Claude Code
|
|
85
|
+
|
|
86
|
+
This project includes Claude Code skills to help with development. See the `.claude/skills/` directory: changelog, demo-video, explorbot-debug, explorbot-fix-session, image-processing, prompt-audit, xpath-testing.
|
|
87
|
+
|
|
88
|
+
## Questions?
|
|
89
|
+
|
|
90
|
+
Open an issue on GitHub for questions or discussion.
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# Demo Videos
|
|
2
|
+
|
|
3
|
+
Explorbot sessions can be turned into demo videos for social media and presentations. The generator composites the browser screencast of a test with a simulated terminal that replays the session's real log lines at their original pace, over an abstract background with window chrome and shadows. Everything shown is real recorded data: no more than 1.25x speedup, successful runs only.
|
|
4
|
+
|
|
5
|
+
Implementation lives in `.claude/skills/demo-video/` (`demo-video.ts` exports `analyzeDemoCandidates` and `createDemoVideo`; the Bunoshfile wraps them as commands).
|
|
6
|
+
|
|
7
|
+
## Prerequisites
|
|
8
|
+
|
|
9
|
+
- `vhs` and `ttyd` — render the terminal simulation (`go install github.com/charmbracelet/vhs@latest`)
|
|
10
|
+
- `ffmpeg` and ImageMagick
|
|
11
|
+
- IBM Plex Mono font (optional — VHS falls back to its default mono font)
|
|
12
|
+
- A session recorded with screencasts: enable `ai.agents.historian.screencast` in `explorbot.config.js` so `output/screencasts/*.webm` exist alongside `output/explorbot.log`
|
|
13
|
+
|
|
14
|
+
## Usage
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
bunx bunosh demo:analyze output/explorbot.log --screencasts output/screencasts
|
|
18
|
+
bunx bunosh demo:video --size landscape --app-title "My App"
|
|
19
|
+
bunx bunosh demo:video "upload a file" --size vertical --terminal-theme light
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
`demo:analyze` lists candidate segments ranked by how well they will read on video. `demo:video` renders the best one, or the test whose scenario name matches the first argument. Key options: `--duration` (target seconds, default 30), `--size` (`landscape`, `square`, `vertical`, or `WxH`), `--app-title` (browser window title, defaults to the tested app's host), `--terminal-theme` (`dark` or `light`), `--bg-image` (`auto` fetches a random abstract photo from Unsplash, `gradient` generates one offline, or pass a file/URL). Run `bunx bunosh demo:video --help` for the full list.
|
|
23
|
+
|
|
24
|
+
The renderer verifies its output and writes three check frames (`*-frame-first/mid/last.png`) next to the video — review them before publishing.
|
|
25
|
+
|
|
26
|
+
## How segments are picked
|
|
27
|
+
|
|
28
|
+
Only successful tests with an existing screencast qualify. Within a test, the scorer prefers windows that:
|
|
29
|
+
|
|
30
|
+
- are dense in visible actions (click, fill, type, navigate) rather than thinking or verification steps
|
|
31
|
+
- have no dead air — inter-step gaps stay under 10 seconds
|
|
32
|
+
- show forward progress — windows dominated by repeated retry steps are rejected
|
|
33
|
+
- were executed live — batch-logged step bursts cannot sync with the video and are rejected
|
|
34
|
+
- do not end on a failure note or mid-navigation on a blank page
|
|
35
|
+
|
|
36
|
+
The log's `Saved screencast:` line joins a test to its `.webm`; video time is calibrated from that timestamp minus the video duration. If a screencast file was overwritten by a run outside the log, it is skipped.
|