@e2edev/e2e 0.9.0 → 0.11.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 +12 -6
- package/dist/agent/act-validation.d.ts +2 -0
- package/dist/agent/act-validation.d.ts.map +1 -1
- package/dist/agent/act-validation.js +2 -2
- package/dist/agent/act-validation.js.map +1 -1
- package/dist/agent/act.d.ts +1 -0
- package/dist/agent/act.d.ts.map +1 -1
- package/dist/agent/act.js +41 -18
- package/dist/agent/act.js.map +1 -1
- package/dist/agent/ai-sdk.d.ts +2 -2
- package/dist/agent/ai-sdk.d.ts.map +1 -1
- package/dist/agent/ai-sdk.js +3 -4
- package/dist/agent/ai-sdk.js.map +1 -1
- package/dist/agent/default-agent.d.ts +17 -2
- package/dist/agent/default-agent.d.ts.map +1 -1
- package/dist/agent/default-agent.js +17 -3
- package/dist/agent/default-agent.js.map +1 -1
- package/dist/agent/error.d.ts.map +1 -1
- package/dist/agent/error.js +1 -0
- package/dist/agent/error.js.map +1 -1
- package/dist/agent/executor.d.ts +13 -0
- package/dist/agent/executor.d.ts.map +1 -1
- package/dist/agent/executor.js.map +1 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +17 -12
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/invocation.d.ts +26 -6
- package/dist/agent/invocation.d.ts.map +1 -1
- package/dist/agent/invocation.js +9 -6
- package/dist/agent/invocation.js.map +1 -1
- package/dist/agent/model/adapter.d.ts +3 -0
- package/dist/agent/model/adapter.d.ts.map +1 -1
- package/dist/agent/model/adapter.js.map +1 -1
- package/dist/agent/model/overflow.d.ts +20 -0
- package/dist/agent/model/overflow.d.ts.map +1 -0
- package/dist/agent/model/overflow.js +82 -0
- package/dist/agent/model/overflow.js.map +1 -0
- package/dist/agent/model/prompt-cache.d.ts +47 -0
- package/dist/agent/model/prompt-cache.d.ts.map +1 -0
- package/dist/agent/model/prompt-cache.js +78 -0
- package/dist/agent/model/prompt-cache.js.map +1 -0
- package/dist/agent/model/sdk.d.ts +41 -24
- package/dist/agent/model/sdk.d.ts.map +1 -1
- package/dist/agent/model/sdk.js +64 -91
- package/dist/agent/model/sdk.js.map +1 -1
- package/dist/agent/primitives.d.ts.map +1 -1
- package/dist/agent/primitives.js +2 -1
- package/dist/agent/primitives.js.map +1 -1
- package/dist/agent/public.d.ts +1 -1
- package/dist/agent/public.d.ts.map +1 -1
- package/dist/agent/public.js.map +1 -1
- package/dist/agent/screen-update.d.ts +8 -3
- package/dist/agent/screen-update.d.ts.map +1 -1
- package/dist/agent/screen-update.js +18 -5
- package/dist/agent/screen-update.js.map +1 -1
- package/dist/agent/tool-loop.d.ts.map +1 -1
- package/dist/agent/tool-loop.js +149 -33
- package/dist/agent/tool-loop.js.map +1 -1
- package/dist/agent/tool-output.d.ts +31 -0
- package/dist/agent/tool-output.d.ts.map +1 -0
- package/dist/agent/tool-output.js +60 -0
- package/dist/agent/tool-output.js.map +1 -0
- package/dist/agent/tool.d.ts +9 -3
- package/dist/agent/tool.d.ts.map +1 -1
- package/dist/agent/tool.js +2 -2
- package/dist/agent/tool.js.map +1 -1
- package/dist/agent/usage.d.ts +7 -0
- package/dist/agent/usage.d.ts.map +1 -1
- package/dist/agent/usage.js +11 -0
- package/dist/agent/usage.js.map +1 -1
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +121 -33
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/init/engine-versions.json +1 -0
- package/dist/cli/init/engines.d.ts +13 -8
- package/dist/cli/init/engines.d.ts.map +1 -1
- package/dist/cli/init/engines.js +26 -7
- package/dist/cli/init/engines.js.map +1 -1
- package/dist/cli/init/gateways.d.ts +22 -0
- package/dist/cli/init/gateways.d.ts.map +1 -0
- package/dist/cli/init/gateways.js +50 -0
- package/dist/cli/init/gateways.js.map +1 -0
- package/dist/cli/init/scaffold.d.ts +7 -1
- package/dist/cli/init/scaffold.d.ts.map +1 -1
- package/dist/cli/init/scaffold.js +26 -13
- package/dist/cli/init/scaffold.js.map +1 -1
- package/dist/cli/init.d.ts.map +1 -1
- package/dist/cli/init.js +51 -13
- package/dist/cli/init.js.map +1 -1
- package/dist/collect/collect.d.ts +7 -0
- package/dist/collect/collect.d.ts.map +1 -1
- package/dist/collect/collect.js +16 -0
- package/dist/collect/collect.js.map +1 -1
- package/dist/collect/registry.d.ts.map +1 -1
- package/dist/collect/registry.js +13 -4
- package/dist/collect/registry.js.map +1 -1
- package/dist/collect/select.d.ts +2 -0
- package/dist/collect/select.d.ts.map +1 -1
- package/dist/collect/select.js +9 -0
- package/dist/collect/select.js.map +1 -1
- package/dist/config/agent.d.ts +16 -33
- package/dist/config/agent.d.ts.map +1 -1
- package/dist/config/agent.js +50 -140
- package/dist/config/agent.js.map +1 -1
- package/dist/config/esm-hooks.d.ts +28 -0
- package/dist/config/esm-hooks.d.ts.map +1 -0
- package/dist/config/esm-hooks.js +35 -0
- package/dist/config/esm-hooks.js.map +1 -0
- package/dist/config/load.d.ts +6 -0
- package/dist/config/load.d.ts.map +1 -1
- package/dist/config/load.js +52 -5
- package/dist/config/load.js.map +1 -1
- package/dist/config/resolve.d.ts +7 -0
- package/dist/config/resolve.d.ts.map +1 -1
- package/dist/config/resolve.js +53 -13
- package/dist/config/resolve.js.map +1 -1
- package/dist/engine/index.d.ts +8 -2
- package/dist/engine/index.d.ts.map +1 -1
- package/dist/engine/index.js.map +1 -1
- package/dist/engine/surface.d.ts +2 -2
- package/dist/engine/surface.d.ts.map +1 -1
- package/dist/explore/body.d.ts +36 -0
- package/dist/explore/body.d.ts.map +1 -0
- package/dist/explore/body.js +168 -0
- package/dist/explore/body.js.map +1 -0
- package/dist/explore/executor.d.ts +25 -0
- package/dist/explore/executor.d.ts.map +1 -0
- package/dist/explore/executor.js +86 -0
- package/dist/explore/executor.js.map +1 -0
- package/dist/explore/index.d.ts +64 -0
- package/dist/explore/index.d.ts.map +1 -0
- package/dist/explore/index.js +183 -0
- package/dist/explore/index.js.map +1 -0
- package/dist/explore/plan.d.ts +74 -0
- package/dist/explore/plan.d.ts.map +1 -0
- package/dist/explore/plan.js +149 -0
- package/dist/explore/plan.js.map +1 -0
- package/dist/explore/reporter.d.ts +11 -0
- package/dist/explore/reporter.d.ts.map +1 -0
- package/dist/explore/reporter.js +54 -0
- package/dist/explore/reporter.js.map +1 -0
- package/dist/explore/state.d.ts +58 -0
- package/dist/explore/state.d.ts.map +1 -0
- package/dist/explore/state.js +147 -0
- package/dist/explore/state.js.map +1 -0
- package/dist/internal/atomic-write.d.ts +1 -1
- package/dist/internal/atomic-write.d.ts.map +1 -1
- package/dist/internal/atomic-write.js.map +1 -1
- package/dist/internal/package-version.d.ts +2 -0
- package/dist/internal/package-version.d.ts.map +1 -1
- package/dist/internal/package-version.js +9 -0
- package/dist/internal/package-version.js.map +1 -1
- package/dist/internal/redact.d.ts +12 -4
- package/dist/internal/redact.d.ts.map +1 -1
- package/dist/internal/redact.js +61 -12
- package/dist/internal/redact.js.map +1 -1
- package/dist/internal/zip.d.ts +32 -0
- package/dist/internal/zip.d.ts.map +1 -0
- package/dist/internal/zip.js +183 -0
- package/dist/internal/zip.js.map +1 -0
- package/dist/report/build.d.ts +55 -0
- package/dist/report/build.d.ts.map +1 -1
- package/dist/report/build.js +10 -1
- package/dist/report/build.js.map +1 -1
- package/dist/report/debug-steps.d.ts.map +1 -1
- package/dist/report/debug-steps.js +15 -0
- package/dist/report/debug-steps.js.map +1 -1
- package/dist/report/format.d.ts +11 -1
- package/dist/report/format.d.ts.map +1 -1
- package/dist/report/format.js +15 -3
- package/dist/report/format.js.map +1 -1
- package/dist/report/list.d.ts.map +1 -1
- package/dist/report/list.js +2 -0
- package/dist/report/list.js.map +1 -1
- package/dist/run/artifacts.d.ts.map +1 -1
- package/dist/run/artifacts.js +8 -6
- package/dist/run/artifacts.js.map +1 -1
- package/dist/run/events.d.ts +4 -2
- package/dist/run/events.d.ts.map +1 -1
- package/dist/run/events.js.map +1 -1
- package/dist/run/execute.d.ts.map +1 -1
- package/dist/run/execute.js +29 -2
- package/dist/run/execute.js.map +1 -1
- package/dist/run/fixtures.d.ts +10 -1
- package/dist/run/fixtures.d.ts.map +1 -1
- package/dist/run/fixtures.js +39 -22
- package/dist/run/fixtures.js.map +1 -1
- package/dist/run/in-process.d.ts +8 -0
- package/dist/run/in-process.d.ts.map +1 -1
- package/dist/run/in-process.js +3 -3
- package/dist/run/in-process.js.map +1 -1
- package/dist/run/records.d.ts +8 -6
- package/dist/run/records.d.ts.map +1 -1
- package/dist/run/runner.d.ts +22 -1
- package/dist/run/runner.d.ts.map +1 -1
- package/dist/run/runner.js +22 -14
- package/dist/run/runner.js.map +1 -1
- package/dist/run/secrecy.d.ts +23 -0
- package/dist/run/secrecy.d.ts.map +1 -0
- package/dist/run/secrecy.js +22 -0
- package/dist/run/secrecy.js.map +1 -0
- package/dist/run/steps.d.ts +11 -0
- package/dist/run/steps.d.ts.map +1 -1
- package/dist/run/steps.js +1 -0
- package/dist/run/steps.js.map +1 -1
- package/dist/run/trace-redaction.d.ts +17 -0
- package/dist/run/trace-redaction.d.ts.map +1 -0
- package/dist/run/trace-redaction.js +148 -0
- package/dist/run/trace-redaction.js.map +1 -0
- package/dist/run/worker-models.d.ts +14 -14
- package/dist/run/worker-models.d.ts.map +1 -1
- package/dist/run/worker-models.js +34 -26
- package/dist/run/worker-models.js.map +1 -1
- package/dist/telemetry/events.d.ts.map +1 -1
- package/dist/telemetry/events.js +17 -2
- package/dist/telemetry/events.js.map +1 -1
- package/dist/types.d.ts +32 -25
- package/dist/types.d.ts.map +1 -1
- package/package.json +6 -4
- package/skills/e2e/SKILL.md +12 -5
- package/skills/e2e/references/agent.md +22 -17
- package/skills/e2e/references/debugging.md +3 -2
- package/skills/e2e/references/explore.md +83 -0
- package/skills/e2e/references/running.md +8 -3
- package/skills/e2e/references/setup.md +17 -13
- package/skills/e2e/references/writing-tests.md +1 -0
- package/dist/config/esm.d.ts +0 -4
- package/dist/config/esm.d.ts.map +0 -1
- package/dist/config/esm.js +0 -35
- package/dist/config/esm.js.map +0 -1
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The exploration body: the test `e2e explore` registers in memory. A loop
|
|
3
|
+
* of ordinary `agent.act` steps, one per charter the planner writes, under
|
|
4
|
+
* the exploration's own budgets. The outcome policy is the one TesterArmy's
|
|
5
|
+
* discovery runs settled on: a step that ends at its budget is a time-boxed
|
|
6
|
+
* charter and not a failure; a failed step is a finding and the run goes on;
|
|
7
|
+
* three failed or blocked steps in a row, the step cap, or the clock end the
|
|
8
|
+
* run with a closing assessment; findings of kind `issue` fail the run; a run
|
|
9
|
+
* that explored nothing and found nothing is blocked, never a pass.
|
|
10
|
+
*/
|
|
11
|
+
import { AgentError, isAgentError } from '../agent/error.js';
|
|
12
|
+
import { credentials } from '../credentials.js';
|
|
13
|
+
import { planNext } from './plan.js';
|
|
14
|
+
/** Failed or blocked steps in a row, none with a finding, that end the run: the approach is not working. */
|
|
15
|
+
export const CONSECUTIVE_FAILURE_LIMIT = 3;
|
|
16
|
+
/** Time kept back for the closing assessment once no step can start. */
|
|
17
|
+
const FINISH_RESERVE_MS = 60_000;
|
|
18
|
+
/** The least time a step is worth starting with. */
|
|
19
|
+
const MIN_STEP_MS = 45_000;
|
|
20
|
+
/** The planner's deadline: one structured call plus a repair round, on a slow provider. */
|
|
21
|
+
const PLAN_TIMEOUT_MS = 90_000;
|
|
22
|
+
/** Below this, not even the closing assessment is asked for. */
|
|
23
|
+
const MIN_PLAN_TIMEOUT_MS = 30_000;
|
|
24
|
+
/** Builds the test body for one exploration. */
|
|
25
|
+
export function createExploreBody(options) {
|
|
26
|
+
const { state } = options;
|
|
27
|
+
const now = options.now ?? Date.now;
|
|
28
|
+
const accounts = options.accounts ?? [];
|
|
29
|
+
return async ({ agent, app }) => {
|
|
30
|
+
const deadline = now() + state.budgets.timeoutMs;
|
|
31
|
+
if (options.openApp)
|
|
32
|
+
await app.open();
|
|
33
|
+
// Resolved here, once the runner has the credential registry up.
|
|
34
|
+
const secrets = accounts.length === 0
|
|
35
|
+
? undefined
|
|
36
|
+
: Object.fromEntries(accounts.map((account) => [account.name, { username: account.username, password: credentials.user(account.name).password }]));
|
|
37
|
+
const ending = await runSteps({ agent, state, accounts, secrets, stepTimeoutMs: options.stepTimeoutMs, remaining: () => deadline - now() });
|
|
38
|
+
state.end(ending.ended, ending.summary);
|
|
39
|
+
conclude(state);
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
/**
|
|
43
|
+
* Plan, act, repeat, until something ends the run; returns why. A cancelled
|
|
44
|
+
* step or a failing provider throws out instead, and the record keeps its
|
|
45
|
+
* `aborted` default.
|
|
46
|
+
*/
|
|
47
|
+
async function runSteps(loop) {
|
|
48
|
+
const { agent, state, remaining } = loop;
|
|
49
|
+
/** Planner answers outside the grammar in a row; one is covered, two end the run. */
|
|
50
|
+
let plannerFailures = 0;
|
|
51
|
+
for (;;) {
|
|
52
|
+
const stop = mustFinish(state, remaining());
|
|
53
|
+
if (stop !== undefined && remaining() < MIN_PLAN_TIMEOUT_MS)
|
|
54
|
+
return { ended: stop.ended };
|
|
55
|
+
let plan;
|
|
56
|
+
try {
|
|
57
|
+
plan = await planNext(agent, state, {
|
|
58
|
+
mustFinish: stop !== undefined,
|
|
59
|
+
reason: stop?.reason,
|
|
60
|
+
accounts: loop.accounts,
|
|
61
|
+
remainingMs: remaining(),
|
|
62
|
+
timeoutMs: Math.max(MIN_PLAN_TIMEOUT_MS, Math.min(PLAN_TIMEOUT_MS, remaining())),
|
|
63
|
+
});
|
|
64
|
+
plannerFailures = 0;
|
|
65
|
+
}
|
|
66
|
+
catch (cause) {
|
|
67
|
+
// A model that cannot produce a plan in the grammar, even after the
|
|
68
|
+
// repair round, is a model shortcoming, not the end of the world: one
|
|
69
|
+
// failure is covered by a built-in charter (a survey first, a
|
|
70
|
+
// continuation later); two in a row end the exploration with the
|
|
71
|
+
// record so far; a failed closing assessment leaves the run to end for
|
|
72
|
+
// the reason it had to, without one. Anything else (the provider, the
|
|
73
|
+
// clock, a cancellation) is the run's error.
|
|
74
|
+
if (!isAgentError(cause) || cause.code !== 'MODEL_OUTPUT_INVALID')
|
|
75
|
+
throw cause;
|
|
76
|
+
if (stop !== undefined)
|
|
77
|
+
return { ended: stop.ended };
|
|
78
|
+
plannerFailures += 1;
|
|
79
|
+
if (plannerFailures > 1)
|
|
80
|
+
return { ended: 'aborted' };
|
|
81
|
+
plan = state.steps.length === 0 ? SURVEY_STEP : CONTINUE_STEP;
|
|
82
|
+
}
|
|
83
|
+
if (plan.kind === 'finish')
|
|
84
|
+
return { ended: stop?.ended ?? 'finished', summary: plan.summary };
|
|
85
|
+
// Asked to finish, the model planned a step anyway: the budget wins.
|
|
86
|
+
if (stop !== undefined)
|
|
87
|
+
return { ended: stop.ended };
|
|
88
|
+
// The plan call took its own time; a step still has to fit before the
|
|
89
|
+
// reserve, or the run is out of time whatever the check above said.
|
|
90
|
+
const room = remaining() - FINISH_RESERVE_MS;
|
|
91
|
+
if (room < MIN_STEP_MS)
|
|
92
|
+
return { ended: 'time' };
|
|
93
|
+
const step = state.beginStep(plan.title, plan.instruction);
|
|
94
|
+
const params = stepParams(state, loop.secrets);
|
|
95
|
+
try {
|
|
96
|
+
const result = await agent.act(step.instruction, {
|
|
97
|
+
timeout: Math.min(loop.stepTimeoutMs, room),
|
|
98
|
+
...(params === undefined ? {} : { params }),
|
|
99
|
+
});
|
|
100
|
+
state.endStep('passed', result.summary);
|
|
101
|
+
}
|
|
102
|
+
catch (cause) {
|
|
103
|
+
if (!isAgentError(cause))
|
|
104
|
+
throw cause;
|
|
105
|
+
state.endStep(stepStatus(cause), cause.explanation, cause.code);
|
|
106
|
+
if (cause.code === 'CANCELLED')
|
|
107
|
+
throw cause;
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Why the loop can no longer start a step, if it cannot. */
|
|
112
|
+
function mustFinish(state, remainingMs) {
|
|
113
|
+
if (state.steps.length >= state.budgets.maxSteps) {
|
|
114
|
+
return { ended: 'step-limit', reason: `the step limit of ${state.budgets.maxSteps} is reached` };
|
|
115
|
+
}
|
|
116
|
+
const streak = state.consecutiveFailures();
|
|
117
|
+
if (streak >= CONSECUTIVE_FAILURE_LIMIT) {
|
|
118
|
+
return { ended: 'stuck', reason: `${streak} steps failed in a row without a finding; exploration is stuck` };
|
|
119
|
+
}
|
|
120
|
+
if (remainingMs < FINISH_RESERVE_MS + MIN_STEP_MS) {
|
|
121
|
+
return { ended: 'time', reason: 'the time budget is nearly spent' };
|
|
122
|
+
}
|
|
123
|
+
return undefined;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* The step parameters a charter carries: the findings so far, so the agent
|
|
127
|
+
* neither reports one twice nor spends the step re-confirming it, and the
|
|
128
|
+
* configured accounts as secrets it can fill by name. Undefined when there
|
|
129
|
+
* is nothing to carry.
|
|
130
|
+
*/
|
|
131
|
+
function stepParams(state, secrets) {
|
|
132
|
+
const reported = state.findings.map((finding) => finding.title);
|
|
133
|
+
const params = {
|
|
134
|
+
...(reported.length === 0 ? {} : { reportedFindings: reported }),
|
|
135
|
+
...(secrets === undefined ? {} : { credentials: secrets }),
|
|
136
|
+
};
|
|
137
|
+
return Object.keys(params).length === 0 ? undefined : params;
|
|
138
|
+
}
|
|
139
|
+
/** How a step that threw ended: a charter that ran out of room ended, it did not fail. */
|
|
140
|
+
function stepStatus(cause) {
|
|
141
|
+
if (cause.code === 'STEP_BUDGET_EXHAUSTED' || cause.code === 'STEP_TIMEOUT')
|
|
142
|
+
return 'exhausted';
|
|
143
|
+
return cause.code === 'CANCELLED' || cause.blocked ? 'blocked' : 'failed';
|
|
144
|
+
}
|
|
145
|
+
/** The first charter when the planner could not write one: look around. */
|
|
146
|
+
const SURVEY_STEP = {
|
|
147
|
+
kind: 'step',
|
|
148
|
+
title: 'Survey the app',
|
|
149
|
+
instruction: 'Survey the app: visit each top-level page or screen the navigation offers once, note what each one is for and which controls it has, and try one obvious action on each. Report any defect you see on the way.',
|
|
150
|
+
};
|
|
151
|
+
/** A later charter when the planner could not write one: carry on with what the goal names and no step covered. */
|
|
152
|
+
const CONTINUE_STEP = {
|
|
153
|
+
kind: 'step',
|
|
154
|
+
title: 'Continue exploring',
|
|
155
|
+
instruction: 'Continue the exploration: from the goal in the project context and the previously completed steps, pick the flow or screen the goal names that no step has covered yet, exercise it end to end with realistic inputs, and report any defect you see on the way.',
|
|
156
|
+
};
|
|
157
|
+
/** Turns the record into the run's verdict. */
|
|
158
|
+
function conclude(state) {
|
|
159
|
+
if (state.steps.length === 0 && state.findings.length === 0) {
|
|
160
|
+
throw new AgentError('AUTOMATION_UNSUPPORTED', 'exploration concluded nothing: no step ran and no finding was recorded', { blocked: true });
|
|
161
|
+
}
|
|
162
|
+
const issues = state.issues;
|
|
163
|
+
if (issues.length > 0) {
|
|
164
|
+
const titles = issues.map((finding) => `[severity ${finding.severity}] ${finding.title}`).join('; ');
|
|
165
|
+
throw new AgentError('ASSERTION_FAILED', `exploration found ${issues.length} issue(s): ${titles}`);
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
//# sourceMappingURL=body.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"body.js","sourceRoot":"","sources":["../../src/explore/body.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The explorer: the built-in agent (`createAgent`) with exploration guidance
|
|
3
|
+
* appended to the project's and one tool added to the project's vocabulary,
|
|
4
|
+
* `report_finding`. Nothing else changes: budgets, loop guards, wind-down,
|
|
5
|
+
* secrets, origin policy, and the transcript are the harness's, and each
|
|
6
|
+
* exploration step runs as one ordinary `agent.act` step.
|
|
7
|
+
*/
|
|
8
|
+
import { type DefaultAgent } from '../agent/default-agent.ts';
|
|
9
|
+
import type { StepExecutor } from '../agent/executor.ts';
|
|
10
|
+
import type { ExploreState } from './state.ts';
|
|
11
|
+
export declare const FINDING_TOOL_NAME = "report_finding";
|
|
12
|
+
export interface ExplorerOptions {
|
|
13
|
+
readonly state: ExploreState;
|
|
14
|
+
/** The executor the agent the exploration runs as resolved to; undefined is the built-in agent. */
|
|
15
|
+
readonly from: StepExecutor | undefined;
|
|
16
|
+
/** Told when a hand-rolled executor is replaced. */
|
|
17
|
+
readonly notice: (message: string) => void;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Builds the explorer. An executor `createAgent` built lends its tools,
|
|
21
|
+
* guidance, model, and provider options; a hand-rolled one has no readable
|
|
22
|
+
* vocabulary and is replaced, with a notice, keeping the model it brought.
|
|
23
|
+
*/
|
|
24
|
+
export declare function createExplorer(options: ExplorerOptions): DefaultAgent;
|
|
25
|
+
//# sourceMappingURL=executor.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.d.ts","sourceRoot":"","sources":["../../src/explore/executor.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,OAAO,EAA+B,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC3F,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAE/C,eAAO,MAAM,iBAAiB,mBAAmB,CAAC;AAYlD,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,KAAK,EAAE,YAAY,CAAC;IAC7B,mGAAmG;IACnG,QAAQ,CAAC,IAAI,EAAE,YAAY,GAAG,SAAS,CAAC;IACxC,oDAAoD;IACpD,QAAQ,CAAC,MAAM,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5C;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,eAAe,GAAG,YAAY,CAgBrE"}
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The explorer: the built-in agent (`createAgent`) with exploration guidance
|
|
3
|
+
* appended to the project's and one tool added to the project's vocabulary,
|
|
4
|
+
* `report_finding`. Nothing else changes: budgets, loop guards, wind-down,
|
|
5
|
+
* secrets, origin policy, and the transcript are the harness's, and each
|
|
6
|
+
* exploration step runs as one ordinary `agent.act` step.
|
|
7
|
+
*/
|
|
8
|
+
import { z } from 'zod';
|
|
9
|
+
import { createAgent, isDefaultAgent } from '../agent/default-agent.js';
|
|
10
|
+
import { defineTool, getToolContext } from '../agent/tool.js';
|
|
11
|
+
import { asSdkLanguageModel } from '../config/agent.js';
|
|
12
|
+
export const FINDING_TOOL_NAME = 'report_finding';
|
|
13
|
+
/** Appended to the project's own guidance; the goal itself travels as agent context. */
|
|
14
|
+
const EXPLORE_RULES = `Exploration mode: this run has no scripted test. Each step is an exploration charter the planner wrote toward the goal given in the project context.
|
|
15
|
+
- Think like a curious first-time user hunting for bugs: exercise the flow the charter names end to end, with realistic inputs and edge cases. Interact, do not just look: fill forms with obviously made-up test data and submit them, save and come back to check what was kept, sign in with made-up credentials when none are configured, and when a list has several items act on one that is not the first and check that the right one changed.
|
|
16
|
+
- On every screen, sanity-check beyond "it renders": totals equal the sum of their parts and quantities multiply; counts match the items listed; nothing is negative that cannot be; dates are plausible and in order, not an epoch default; copy has no template tokens, placeholders, or misspellings; every control does what its name says; what a screen claims happened (saved, added, removed) is true on the next screen; a password is never shown as you type it.
|
|
17
|
+
- Report every defect with ${FINDING_TOOL_NAME} the moment the evidence is on screen, one call per distinct defect: what you expected, what the screen shows, and the actions that reach it. Do not save findings for the conclusion: a defect that appears only in a summary is lost, since the report reads the tool, not the prose. Findings listed under "reportedFindings" in the step parameters are already recorded: never report them again and spend no actions re-confirming them.
|
|
18
|
+
- Accounts listed under "credentials" in the step parameters are yours to sign in with: type the username as text and fill the password with type_secret by the account's name. Never type a password as text, and never ask for one. If no type_secret tool is offered, this engine cannot fill a password securely: skip signing in, note it in the step summary, and explore what is reachable without it.
|
|
19
|
+
- Report defects, not wishes. A defect is something the screen breaks or contradicts: a wrong value, a dead control, a navigation that lands wrong, a claim that turns out false, leaked template text, a misspelling. A missing feature, a design choice, a form the browser refuses to submit while a required field is empty, or something you merely expected is not a defect unless the screen or the goal promised it. A failed tool call, a refused action, or a limit of this harness is not a product defect either.
|
|
20
|
+
- Stay inside the application under test. Do not destroy data that existed before this run (deleting accounts, wiping lists) unless the goal asks for it; creating and editing your own data is fine.
|
|
21
|
+
- When the charter is covered, or nothing new is reachable within it, call complete_step. "passed" means you carried the charter out, however many defects you reported on the way: reported findings never make a step fail. "failed" is only for a charter the application would not let you carry out at all: a flow that cannot be completed, a page that cannot be reached. Keep to the charter: a step is one flow, not the whole app. The summary is read by the planner of the next step: say what was covered, what was found, and what looks worth exploring next.`;
|
|
22
|
+
/**
|
|
23
|
+
* Builds the explorer. An executor `createAgent` built lends its tools,
|
|
24
|
+
* guidance, model, and provider options; a hand-rolled one has no readable
|
|
25
|
+
* vocabulary and is replaced, with a notice, keeping the model it brought.
|
|
26
|
+
*/
|
|
27
|
+
export function createExplorer(options) {
|
|
28
|
+
const { from } = options;
|
|
29
|
+
const base = isDefaultAgent(from) ? from.options : undefined;
|
|
30
|
+
if (from !== undefined && base === undefined) {
|
|
31
|
+
options.notice(`the configured agent "${from.name}" is a custom executor; explore runs the built-in agent instead` +
|
|
32
|
+
(from.model === undefined ? '' : ', with the model that executor brought'));
|
|
33
|
+
}
|
|
34
|
+
const carried = base === undefined && from?.model !== undefined ? { model: asSdkLanguageModel(from.model) } : {};
|
|
35
|
+
return createAgent({
|
|
36
|
+
...base,
|
|
37
|
+
...carried,
|
|
38
|
+
system: [base?.system, EXPLORE_RULES].filter((part) => part !== undefined && part.trim() !== '').join('\n\n'),
|
|
39
|
+
tools: { ...base?.tools, [FINDING_TOOL_NAME]: createFindingTool(options.state) },
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const FINDING_SCHEMA = z.object({
|
|
43
|
+
title: z
|
|
44
|
+
.string()
|
|
45
|
+
.min(4)
|
|
46
|
+
.max(200)
|
|
47
|
+
.describe('A short, specific name for the defect, e.g. "Checkout total shows $0.00 with two items in the cart".'),
|
|
48
|
+
kind: z
|
|
49
|
+
.enum(['issue', 'warning'])
|
|
50
|
+
.describe('issue = a defect a user would hit: a broken flow, wrong data, a dead control, a navigation that lands wrong. warning = cosmetic or polish; blocks no task.'),
|
|
51
|
+
severity: z
|
|
52
|
+
.literal([1, 2, 3, 4, 5])
|
|
53
|
+
.describe('5: a core journey is impossible, data is lost, or money or security is wrong. 4: a core feature is broken but a workaround exists, or wrong money or quantity values are shown. 3: a secondary feature is broken, or wrong non-monetary content. 2: a cosmetic or layout defect that blocks nothing. 1: a trivial polish item (usually a warning).'),
|
|
54
|
+
expected: z.string().min(1).max(2000).describe('What a user would expect here.'),
|
|
55
|
+
actual: z.string().min(1).max(2000).describe('What the screen shows instead, quoted from the observation.'),
|
|
56
|
+
reproduction: z
|
|
57
|
+
.array(z.string().min(1).max(500))
|
|
58
|
+
.min(1)
|
|
59
|
+
.max(20)
|
|
60
|
+
.describe('The actions that reach the defect from the start of the app, one per entry.'),
|
|
61
|
+
});
|
|
62
|
+
/**
|
|
63
|
+
* The finding tool. Read-only: it observes the screen for the location and
|
|
64
|
+
* the evidence pixels, records the finding against the step in progress,
|
|
65
|
+
* keeps the pixels as a screenshot artifact of the step, and answers the
|
|
66
|
+
* model with the finding's number so it is not reported twice.
|
|
67
|
+
*/
|
|
68
|
+
function createFindingTool(state) {
|
|
69
|
+
return defineTool({
|
|
70
|
+
description: 'Report one product defect you have evidence of on the current screen: what you expected, what the screen shows, and how to reach it. Call it the moment the evidence is visible, once per distinct defect. Not for tool errors or refused actions.',
|
|
71
|
+
inputSchema: FINDING_SCHEMA,
|
|
72
|
+
execute: async (input, executionOptions) => {
|
|
73
|
+
const { observe, attachScreenshot } = getToolContext(executionOptions);
|
|
74
|
+
const observation = await observe({ pixels: true }).catch(() => undefined);
|
|
75
|
+
const finding = state.addFinding({ ...input, path: observation?.path, observationRevision: observation?.revision });
|
|
76
|
+
if (observation?.pixels !== undefined) {
|
|
77
|
+
// Evidence is worth keeping, never worth failing the finding for.
|
|
78
|
+
const artifactId = await attachScreenshot(observation.pixels, `finding-${finding.index + 1}`).catch(() => undefined);
|
|
79
|
+
if (artifactId !== undefined)
|
|
80
|
+
state.attachEvidence(finding.id, artifactId);
|
|
81
|
+
}
|
|
82
|
+
return `Finding ${finding.index + 1} recorded (${finding.kind}, severity ${finding.severity}): ${finding.title}. Do not report it again; continue the charter or conclude the step.`;
|
|
83
|
+
},
|
|
84
|
+
}, { mutates: false });
|
|
85
|
+
}
|
|
86
|
+
//# sourceMappingURL=executor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"executor.js","sourceRoot":"","sources":["../../src/explore/executor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `e2e explore`: a run whose one test is a goal. The project config is loaded
|
|
3
|
+
* as `run` loads it, the explorer replaces the executor of the agent the run
|
|
4
|
+
* uses, and the exploration body is registered in memory as the run's only
|
|
5
|
+
* test, so the reporters, `report.json`, artifacts, video, the AI trace, and
|
|
6
|
+
* the exit codes are the runner's own. The record of the exploration rides
|
|
7
|
+
* along as `run.explore`.
|
|
8
|
+
*/
|
|
9
|
+
import type { ReportExplore } from '../report/build.ts';
|
|
10
|
+
import { type RunOutcome } from '../run/runner.ts';
|
|
11
|
+
import type { BuiltinReporter, E2EConfig } from '../types.ts';
|
|
12
|
+
/** Exploration steps per run: breadth first, and diminishing returns come fast. */
|
|
13
|
+
export declare const STEP_BOUNDS: {
|
|
14
|
+
readonly min: 1;
|
|
15
|
+
readonly max: 12;
|
|
16
|
+
readonly default: 8;
|
|
17
|
+
};
|
|
18
|
+
/** The run's wall clock in milliseconds: three to fifteen minutes. */
|
|
19
|
+
export declare const TIMEOUT_BOUNDS: {
|
|
20
|
+
readonly min: 180000;
|
|
21
|
+
readonly max: 900000;
|
|
22
|
+
readonly default: 600000;
|
|
23
|
+
};
|
|
24
|
+
export interface ExploreOptions {
|
|
25
|
+
readonly goal?: string | undefined;
|
|
26
|
+
readonly cwd?: string | undefined;
|
|
27
|
+
readonly configPath?: string | undefined;
|
|
28
|
+
/** The target to explore; with several configured and none named, the first is explored. */
|
|
29
|
+
readonly target?: string | undefined;
|
|
30
|
+
/** The configured agent (`agents.<name>`) the exploration runs as; default: `agents.default`. */
|
|
31
|
+
readonly agent?: string | undefined;
|
|
32
|
+
readonly maxSteps?: number | undefined;
|
|
33
|
+
readonly timeoutMs?: number | undefined;
|
|
34
|
+
readonly headed?: boolean | undefined;
|
|
35
|
+
readonly reporters?: readonly BuiltinReporter[] | undefined;
|
|
36
|
+
readonly artifactsDir?: string | undefined;
|
|
37
|
+
readonly debug?: boolean | undefined;
|
|
38
|
+
readonly aiTrace?: boolean | undefined;
|
|
39
|
+
readonly video?: boolean | undefined;
|
|
40
|
+
readonly interruptSignal?: AbortSignal | undefined;
|
|
41
|
+
readonly forceSignal?: AbortSignal | undefined;
|
|
42
|
+
readonly env?: NodeJS.ProcessEnv | undefined;
|
|
43
|
+
/**
|
|
44
|
+
* A config value instead of a discovered file, for the test harness: it may
|
|
45
|
+
* hold a scripted model, which no config file could. `cwd` is the project
|
|
46
|
+
* root then.
|
|
47
|
+
*/
|
|
48
|
+
readonly rawConfig?: E2EConfig | undefined;
|
|
49
|
+
/** Notices decided before the run starts: the target chosen, a replaced executor. */
|
|
50
|
+
readonly notice?: ((message: string) => void) | undefined;
|
|
51
|
+
}
|
|
52
|
+
export interface ExploreOutcome extends RunOutcome {
|
|
53
|
+
readonly explore: ReportExplore;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Runs one exploration and returns the run's outcome with the exploration
|
|
57
|
+
* record. The config is resolved once here, with the agent `--agent` named,
|
|
58
|
+
* so the target, the agent the explorer is built from, and the credential
|
|
59
|
+
* inventory are what the run resolves too; a config that does not resolve,
|
|
60
|
+
* an unknown agent, or an unknown target is an error before anything starts,
|
|
61
|
+
* as a bad flag is.
|
|
62
|
+
*/
|
|
63
|
+
export declare function explore(options?: ExploreOptions): Promise<ExploreOutcome>;
|
|
64
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/explore/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AASH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AACxD,OAAO,EAAO,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACxD,OAAO,KAAK,EAAe,eAAe,EAAE,SAAS,EAAE,MAAM,aAAa,CAAC;AAQ3E,mFAAmF;AACnF,eAAO,MAAM,WAAW;aAAK,GAAG,EAAE,CAAC;aAAE,GAAG,EAAE,EAAE;aAAE,OAAO,EAAE,CAAC;CAAW,CAAC;AACpE,sEAAsE;AACtE,eAAO,MAAM,cAAc;aAAK,GAAG,EAAE,MAAO;aAAE,GAAG,EAAE,MAAO;aAAE,OAAO,EAAE,MAAO;CAAW,CAAC;AAkBxF,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACnC,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAClC,QAAQ,CAAC,UAAU,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzC,4FAA4F;IAC5F,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,iGAAiG;IACjG,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,QAAQ,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACxC,QAAQ,CAAC,MAAM,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACtC,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,eAAe,EAAE,GAAG,SAAS,CAAC;IAC5D,QAAQ,CAAC,YAAY,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3C,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,OAAO,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;IACrC,QAAQ,CAAC,eAAe,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IACnD,QAAQ,CAAC,WAAW,CAAC,EAAE,WAAW,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,GAAG,SAAS,CAAC;IAC7C;;;;OAIG;IACH,QAAQ,CAAC,SAAS,CAAC,EAAE,SAAS,GAAG,SAAS,CAAC;IAC3C,qFAAqF;IACrF,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC,GAAG,SAAS,CAAC;CAC3D;AAED,MAAM,WAAW,cAAe,SAAQ,UAAU;IAChD,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC;CACjC;AAED;;;;;;;GAOG;AACH,wBAAsB,OAAO,CAAC,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,cAAc,CAAC,CA6CnF"}
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `e2e explore`: a run whose one test is a goal. The project config is loaded
|
|
3
|
+
* as `run` loads it, the explorer replaces the executor of the agent the run
|
|
4
|
+
* uses, and the exploration body is registered in memory as the run's only
|
|
5
|
+
* test, so the reporters, `report.json`, artifacts, video, the AI trace, and
|
|
6
|
+
* the exit codes are the runner's own. The record of the exploration rides
|
|
7
|
+
* along as `run.explore`.
|
|
8
|
+
*/
|
|
9
|
+
import { MAX_PARAMS_BYTES } from '../agent/act-validation.js';
|
|
10
|
+
import { isStepExecutor } from '../agent/executor.js';
|
|
11
|
+
import { selectTargets } from '../collect/select.js';
|
|
12
|
+
import { discoverConfig, loadConfigModule, missingConfigError } from '../config/load.js';
|
|
13
|
+
import { resolveConfig } from '../config/resolve.js';
|
|
14
|
+
import { ConfigurationError } from '../internal/errors.js';
|
|
15
|
+
import { run } from '../run/runner.js';
|
|
16
|
+
import { createExploreBody } from './body.js';
|
|
17
|
+
import { createExplorer } from './executor.js';
|
|
18
|
+
import { exploreReporter } from './reporter.js';
|
|
19
|
+
import { ExploreState } from './state.js';
|
|
20
|
+
const DEFAULT_GOAL = 'Explore the app and find bugs';
|
|
21
|
+
/** Exploration steps per run: breadth first, and diminishing returns come fast. */
|
|
22
|
+
export const STEP_BOUNDS = { min: 1, max: 12, default: 8 };
|
|
23
|
+
/** The run's wall clock in milliseconds: three to fifteen minutes. */
|
|
24
|
+
export const TIMEOUT_BOUNDS = { min: 180_000, max: 900_000, default: 600_000 };
|
|
25
|
+
const MAX_GOAL_CHARS = 2_000;
|
|
26
|
+
/** Each step's action and model-call budget when the config sets none: a charter is longer than a scripted step. */
|
|
27
|
+
const DEFAULT_STEP_BUDGET = 40;
|
|
28
|
+
/** One charter's own deadline; the run's remaining time caps it. */
|
|
29
|
+
const STEP_TIMEOUT_MS = 240_000;
|
|
30
|
+
/** Added to the test timeout so the body's own clock ends the exploration before the attempt's does. */
|
|
31
|
+
const TIMEOUT_GRACE_MS = 60_000;
|
|
32
|
+
/** The virtual file the report and the reporters show for the exploration. */
|
|
33
|
+
const EXPLORE_FILE = 'explore';
|
|
34
|
+
/**
|
|
35
|
+
* Every charter carries every configured account as a step parameter, and
|
|
36
|
+
* step parameters have a size limit. The inventory takes at most a quarter of
|
|
37
|
+
* it, leaving room for the findings that ride along, so an oversized one is a
|
|
38
|
+
* configuration error before anything starts and not a failed first step.
|
|
39
|
+
*/
|
|
40
|
+
const MAX_CREDENTIAL_BYTES = MAX_PARAMS_BYTES / 4;
|
|
41
|
+
/**
|
|
42
|
+
* Runs one exploration and returns the run's outcome with the exploration
|
|
43
|
+
* record. The config is resolved once here, with the agent `--agent` named,
|
|
44
|
+
* so the target, the agent the explorer is built from, and the credential
|
|
45
|
+
* inventory are what the run resolves too; a config that does not resolve,
|
|
46
|
+
* an unknown agent, or an unknown target is an error before anything starts,
|
|
47
|
+
* as a bad flag is.
|
|
48
|
+
*/
|
|
49
|
+
export async function explore(options = {}) {
|
|
50
|
+
const cwd = options.cwd ?? process.cwd();
|
|
51
|
+
const env = options.env ?? process.env;
|
|
52
|
+
const notice = options.notice ?? (() => undefined);
|
|
53
|
+
const goal = resolveGoal(options.goal);
|
|
54
|
+
const budgets = {
|
|
55
|
+
maxSteps: resolveBounded(options.maxSteps, STEP_BOUNDS, 'maxSteps'),
|
|
56
|
+
timeoutMs: resolveBounded(options.timeoutMs, TIMEOUT_BOUNDS, 'timeout'),
|
|
57
|
+
};
|
|
58
|
+
const { raw, projectRoot } = await loadRawConfig(options, cwd);
|
|
59
|
+
// Nothing replays an exploration, and a retry would explore twice.
|
|
60
|
+
const rawConfig = { ...raw, cache: 'off', retries: 0 };
|
|
61
|
+
const resolved = resolveConfig(rawConfig, { projectRoot, env, cli: options.agent === undefined ? {} : { agent: options.agent } });
|
|
62
|
+
const target = pickTarget(resolved.targets, options.target, notice);
|
|
63
|
+
const accounts = credentialAccounts(resolved.credentials);
|
|
64
|
+
if (resolved.agentName !== 'default')
|
|
65
|
+
notice(`exploring with agent "${resolved.agentName}"`);
|
|
66
|
+
const state = new ExploreState(goal, budgets);
|
|
67
|
+
const explorer = createExplorer({ state, from: resolved.agent.executor, notice });
|
|
68
|
+
const outcome = await run({
|
|
69
|
+
cwd: projectRoot,
|
|
70
|
+
rawConfig: {
|
|
71
|
+
...rawConfig,
|
|
72
|
+
agents: { ...rawConfig.agents, [resolved.agentName]: exploreAgentConfig(rawConfig.agents?.[resolved.agentName], explorer) },
|
|
73
|
+
reporters: [...(rawConfig.reporters ?? ['list']), exploreReporter(state)],
|
|
74
|
+
},
|
|
75
|
+
agent: options.agent,
|
|
76
|
+
env,
|
|
77
|
+
tests: {
|
|
78
|
+
file: EXPLORE_FILE,
|
|
79
|
+
registration: exploreRegistration(state, target.app.base !== undefined, accounts),
|
|
80
|
+
explore: () => state.snapshot(),
|
|
81
|
+
},
|
|
82
|
+
targetIds: [target.name],
|
|
83
|
+
headed: options.headed,
|
|
84
|
+
reporters: options.reporters,
|
|
85
|
+
artifactsDir: options.artifactsDir,
|
|
86
|
+
debug: options.debug,
|
|
87
|
+
aiTrace: options.aiTrace,
|
|
88
|
+
video: options.video,
|
|
89
|
+
interruptSignal: options.interruptSignal,
|
|
90
|
+
forceSignal: options.forceSignal,
|
|
91
|
+
});
|
|
92
|
+
return { ...outcome, explore: state.snapshot() };
|
|
93
|
+
}
|
|
94
|
+
async function loadRawConfig(options, cwd) {
|
|
95
|
+
if (options.rawConfig !== undefined)
|
|
96
|
+
return { raw: options.rawConfig, projectRoot: cwd };
|
|
97
|
+
const discovered = discoverConfig(cwd, options.configPath);
|
|
98
|
+
if (discovered.configPath === undefined)
|
|
99
|
+
throw missingConfigError(cwd);
|
|
100
|
+
return { raw: await loadConfigModule(discovered.configPath), projectRoot: discovered.projectRoot };
|
|
101
|
+
}
|
|
102
|
+
function resolveGoal(goal) {
|
|
103
|
+
const trimmed = goal?.trim() ?? '';
|
|
104
|
+
if (trimmed === '')
|
|
105
|
+
return DEFAULT_GOAL;
|
|
106
|
+
if (trimmed.length > MAX_GOAL_CHARS) {
|
|
107
|
+
throw new ConfigurationError('INVALID_CONFIG', `the goal must be at most ${MAX_GOAL_CHARS} characters, got ${trimmed.length}`);
|
|
108
|
+
}
|
|
109
|
+
return trimmed;
|
|
110
|
+
}
|
|
111
|
+
function resolveBounded(value, bounds, label) {
|
|
112
|
+
if (value === undefined)
|
|
113
|
+
return bounds.default;
|
|
114
|
+
if (!Number.isSafeInteger(value) || value < bounds.min || value > bounds.max) {
|
|
115
|
+
throw new ConfigurationError('INVALID_CONFIG', `${label} must be an integer from ${bounds.min} through ${bounds.max}, got ${String(value)}`);
|
|
116
|
+
}
|
|
117
|
+
return value;
|
|
118
|
+
}
|
|
119
|
+
/**
|
|
120
|
+
* The target to explore: the one `--target` names (an unknown one is
|
|
121
|
+
* `UNKNOWN_TARGET`, as for `run`), else the first configured, with a notice
|
|
122
|
+
* when there are several.
|
|
123
|
+
*/
|
|
124
|
+
function pickTarget(targets, requested, notice) {
|
|
125
|
+
const chosen = selectTargets(targets, requested === undefined ? undefined : [requested])[0];
|
|
126
|
+
if (chosen === undefined)
|
|
127
|
+
throw new Error('unreachable: a resolved config declares at least one target');
|
|
128
|
+
if (requested === undefined && targets.length > 1) {
|
|
129
|
+
notice(`exploring target "${chosen.name}"; pass --target to explore another`);
|
|
130
|
+
}
|
|
131
|
+
return chosen;
|
|
132
|
+
}
|
|
133
|
+
/**
|
|
134
|
+
* The agent block the exploration runs as: the project's own options with the
|
|
135
|
+
* explorer as the executor, and per-step budgets that default higher than a
|
|
136
|
+
* scripted step's, a charter being longer. A bare executor has no options to
|
|
137
|
+
* keep; the explorer already lent from it what it could.
|
|
138
|
+
*/
|
|
139
|
+
function exploreAgentConfig(entry, explorer) {
|
|
140
|
+
const block = entry === undefined || isStepExecutor(entry) ? {} : entry;
|
|
141
|
+
return {
|
|
142
|
+
...block,
|
|
143
|
+
executor: explorer,
|
|
144
|
+
maxSteps: block.maxSteps ?? DEFAULT_STEP_BUDGET,
|
|
145
|
+
maxModelCalls: block.maxModelCalls ?? DEFAULT_STEP_BUDGET,
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
/**
|
|
149
|
+
* The accounts every charter carries, bounded to what a step parameter holds.
|
|
150
|
+
* Measured as the step sees them: the usernames and the secret placeholders
|
|
151
|
+
* the passwords become there.
|
|
152
|
+
*/
|
|
153
|
+
function credentialAccounts(credentials) {
|
|
154
|
+
const accounts = [...credentials.values()].map((credential) => ({ name: credential.name, username: credential.username }));
|
|
155
|
+
const carried = Object.fromEntries(accounts.map((account) => [account.name, { username: account.username, password: { kind: 'secret', name: account.name, purpose: 'password' } }]));
|
|
156
|
+
const bytes = Buffer.byteLength(JSON.stringify({ credentials: carried }));
|
|
157
|
+
if (bytes > MAX_CREDENTIAL_BYTES) {
|
|
158
|
+
throw new ConfigurationError('INVALID_CONFIG', `explore carries every configured credential into each step: ${String(accounts.length)} account(s) serialize to ${String(bytes)} bytes, the maximum is ${String(MAX_CREDENTIAL_BYTES)}; explore with a config that declares fewer`);
|
|
159
|
+
}
|
|
160
|
+
return accounts;
|
|
161
|
+
}
|
|
162
|
+
/** The one-test registration: the goal is the title, the body is the exploration loop. */
|
|
163
|
+
function exploreRegistration(state, openApp, accounts) {
|
|
164
|
+
const title = state.goal;
|
|
165
|
+
const test = {
|
|
166
|
+
kind: 'test',
|
|
167
|
+
title,
|
|
168
|
+
titlePath: [title],
|
|
169
|
+
declarationIndex: 0,
|
|
170
|
+
options: {
|
|
171
|
+
timeout: state.budgets.timeoutMs + TIMEOUT_GRACE_MS,
|
|
172
|
+
retries: 0,
|
|
173
|
+
agentContext: `Exploration goal: ${state.goal}`,
|
|
174
|
+
},
|
|
175
|
+
sessions: [],
|
|
176
|
+
fn: createExploreBody({ state, stepTimeoutMs: STEP_TIMEOUT_MS, openApp, accounts }),
|
|
177
|
+
group: undefined,
|
|
178
|
+
mode: 'normal',
|
|
179
|
+
source: undefined,
|
|
180
|
+
};
|
|
181
|
+
return { tests: [test], hooks: [] };
|
|
182
|
+
}
|
|
183
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/explore/index.ts"],"names":[],"mappings":"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"}
|