pi-agent-browser-native 0.2.42 → 0.2.44
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/CHANGELOG.md +32 -0
- package/README.md +14 -9
- package/docs/COMMAND_REFERENCE.md +9 -10
- package/docs/RELEASE.md +10 -4
- package/docs/SUPPORT_MATRIX.md +7 -6
- package/docs/TOOL_CONTRACT.md +27 -24
- package/docs/platform-smoke.md +13 -8
- package/extensions/agent-browser/index.ts +71 -2
- package/extensions/agent-browser/lib/input-modes/params.ts +1 -1
- package/extensions/agent-browser/lib/input-modes/types.ts +1 -1
- package/extensions/agent-browser/lib/navigation-policy.ts +95 -0
- package/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts +2 -7
- package/extensions/agent-browser/lib/orchestration/browser-run/final-result.ts +1 -0
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare.ts +2 -2
- package/extensions/agent-browser/lib/orchestration/browser-run/process-output.ts +103 -12
- package/extensions/agent-browser/lib/orchestration/browser-run/session-state.ts +20 -3
- package/extensions/agent-browser/lib/orchestration/browser-run/types.ts +6 -1
- package/extensions/agent-browser/lib/playbook.ts +4 -4
- package/extensions/agent-browser/lib/results/action-recommendations.ts +15 -0
- package/extensions/agent-browser/lib/results/contracts.ts +17 -0
- package/extensions/agent-browser/lib/results/network-routes.ts +80 -0
- package/extensions/agent-browser/lib/results/network.ts +10 -2
- package/extensions/agent-browser/lib/results/presentation/artifacts.ts +14 -0
- package/extensions/agent-browser/lib/results/presentation/batch.ts +36 -13
- package/extensions/agent-browser/lib/results/presentation/diagnostics.ts +154 -16
- package/extensions/agent-browser/lib/results/presentation/errors.ts +62 -2
- package/extensions/agent-browser/lib/results/presentation/semantic-action.ts +2 -4
- package/extensions/agent-browser/lib/results/presentation.ts +31 -1
- package/extensions/agent-browser/lib/results/selector-recovery.ts +11 -3
- package/extensions/agent-browser/lib/results/shared.ts +1 -0
- package/extensions/agent-browser/lib/results.ts +3 -0
- package/extensions/agent-browser/lib/runtime.ts +6 -0
- package/package.json +4 -4
- package/platform-smoke.config.mjs +10 -1
- package/scripts/doctor.mjs +70 -1
- package/scripts/platform-smoke/crabbox-runner.mjs +57 -29
- package/scripts/platform-smoke/doctor.mjs +22 -9
- package/scripts/platform-smoke/targets.mjs +58 -21
- package/scripts/platform-smoke.mjs +1 -0
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
/** Target/suite runner for pi-agent-browser-native platform smoke. */
|
|
2
2
|
|
|
3
|
+
import { execFileSync } from "node:child_process";
|
|
3
4
|
import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
|
|
4
5
|
import { dirname, resolve } from "node:path";
|
|
5
6
|
|
|
@@ -14,7 +15,7 @@ import {
|
|
|
14
15
|
writeManifest,
|
|
15
16
|
writeSummary,
|
|
16
17
|
} from "./artifacts.mjs";
|
|
17
|
-
import { cleanupStaleTargetState, runOnLease, stopLease, warmupLease } from "./crabbox-runner.mjs";
|
|
18
|
+
import { cleanupStaleTargetState, crabboxBin, describeTarget, runOnLease, stopLease, warmupLease } from "./crabbox-runner.mjs";
|
|
18
19
|
|
|
19
20
|
export function platformFor(targetName) {
|
|
20
21
|
return targetName === "windows-native" ? "powershell" : "posix";
|
|
@@ -38,6 +39,45 @@ function authEnvAllowList(config = {}) {
|
|
|
38
39
|
return names.map((name) => String(name).trim()).filter(Boolean);
|
|
39
40
|
}
|
|
40
41
|
|
|
42
|
+
function packageVersion() {
|
|
43
|
+
try {
|
|
44
|
+
return JSON.parse(readFileSync("package.json", "utf8")).version ?? null;
|
|
45
|
+
} catch {
|
|
46
|
+
return null;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
function crabboxVersion() {
|
|
51
|
+
try {
|
|
52
|
+
return execFileSync(crabboxBin(), ["--version"], { encoding: "utf8", stdio: "pipe", timeout: 10_000 }).trim().split(/\r?\n/)[0] ?? null;
|
|
53
|
+
} catch {
|
|
54
|
+
return null;
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
function targetEvidence(config, targetName, runId, slug) {
|
|
59
|
+
const target = describeTarget(targetName, config);
|
|
60
|
+
return {
|
|
61
|
+
targetName,
|
|
62
|
+
platform: platformFor(targetName),
|
|
63
|
+
runId,
|
|
64
|
+
slug,
|
|
65
|
+
packageName: config.packageName,
|
|
66
|
+
packageVersion: packageVersion(),
|
|
67
|
+
crabbox: {
|
|
68
|
+
binary: crabboxBin(),
|
|
69
|
+
version: crabboxVersion(),
|
|
70
|
+
provider: target.provider,
|
|
71
|
+
target: target.crabboxTarget,
|
|
72
|
+
workRoot: target.workRoot,
|
|
73
|
+
image: target.image,
|
|
74
|
+
windowsMode: target.windowsMode,
|
|
75
|
+
sourceVm: target.sourceVm,
|
|
76
|
+
snapshot: target.snapshot,
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
|
|
41
81
|
function writeRedacted(path, text, secretValues) {
|
|
42
82
|
writeFileSync(path, redactSecrets(text ?? "", secretValues));
|
|
43
83
|
}
|
|
@@ -141,12 +181,11 @@ function finalizeSuite(suiteDir, checks, summary, expectedFiles) {
|
|
|
141
181
|
return { assertions: finalAssertions, manifest: writeManifest(suiteDir, [...expectedFiles, "failures.md"]) };
|
|
142
182
|
}
|
|
143
183
|
|
|
144
|
-
export function createLeaseCleanupResult(config, targetName, leaseId, stopResult, staleCleanupResult = null) {
|
|
184
|
+
export function createLeaseCleanupResult(config, targetName, leaseId, stopResult, staleCleanupResult = null, runId = makeRunId()) {
|
|
145
185
|
const suiteName = "lease-cleanup";
|
|
146
|
-
const runId = makeRunId();
|
|
147
186
|
const suiteDir = createSuiteDir(config.artifactRoot, runId, targetName, suiteName);
|
|
148
187
|
const secretValues = collectSecretValues(authEnvAllowList(config));
|
|
149
|
-
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(
|
|
188
|
+
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(targetEvidence(config, targetName, runId, `${config.packageName}-${targetName}`), null, 2));
|
|
150
189
|
writeFileSync(resolve(suiteDir, "suite.json"), JSON.stringify({ suiteName, leaseId, modelCalls: 0 }, null, 2));
|
|
151
190
|
writeCommand(suiteDir, `crabbox stop ${targetName} --id ${leaseId}`);
|
|
152
191
|
writeExitCode(suiteDir, stopResult.code, stopResult.signal);
|
|
@@ -180,16 +219,15 @@ export function createLeaseCleanupResult(config, targetName, leaseId, stopResult
|
|
|
180
219
|
return { ok: assertions.ok, suiteDir, assertions };
|
|
181
220
|
}
|
|
182
221
|
|
|
183
|
-
export function createLeaseCleanupFailureResult(config, targetName, leaseId, stopResult) {
|
|
184
|
-
return createLeaseCleanupResult(config, targetName, leaseId, stopResult);
|
|
222
|
+
export function createLeaseCleanupFailureResult(config, targetName, leaseId, stopResult, runId) {
|
|
223
|
+
return createLeaseCleanupResult(config, targetName, leaseId, stopResult, null, runId);
|
|
185
224
|
}
|
|
186
225
|
|
|
187
|
-
export function createLeaseWarmupFailureResult(config, targetName, warmupResult) {
|
|
226
|
+
export function createLeaseWarmupFailureResult(config, targetName, warmupResult, runId = makeRunId()) {
|
|
188
227
|
const suiteName = "lease-warmup";
|
|
189
|
-
const runId = makeRunId();
|
|
190
228
|
const suiteDir = createSuiteDir(config.artifactRoot, runId, targetName, suiteName);
|
|
191
229
|
const secretValues = collectSecretValues(authEnvAllowList(config));
|
|
192
|
-
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(
|
|
230
|
+
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(targetEvidence(config, targetName, runId, `${config.packageName}-${targetName}`), null, 2));
|
|
193
231
|
writeFileSync(resolve(suiteDir, "suite.json"), JSON.stringify({ suiteName, modelCalls: 0 }, null, 2));
|
|
194
232
|
writeCommand(suiteDir, `crabbox warmup ${targetName}`);
|
|
195
233
|
writeExitCode(suiteDir, warmupResult.code, warmupResult.signal);
|
|
@@ -301,14 +339,13 @@ export function buildBrowserDogfoodCommand(targetName, agentBrowserVersion = "0.
|
|
|
301
339
|
return lines.join("\n");
|
|
302
340
|
}
|
|
303
341
|
|
|
304
|
-
async function runBrowserDogfoodSuite(config, targetName, suiteName, leaseSession) {
|
|
305
|
-
const runId = makeRunId();
|
|
342
|
+
async function runBrowserDogfoodSuite(config, targetName, suiteName, leaseSession, runId = makeRunId()) {
|
|
306
343
|
const suiteDir = createSuiteDir(config.artifactRoot, runId, targetName, suiteName);
|
|
307
344
|
const startedAt = Date.now();
|
|
308
345
|
const platform = platformFor(targetName);
|
|
309
346
|
const slug = `${config.packageName}-${targetName}`;
|
|
310
347
|
const command = buildBrowserDogfoodCommand(targetName, config.agentBrowserVersion);
|
|
311
|
-
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(
|
|
348
|
+
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(targetEvidence(config, targetName, runId, slug), null, 2));
|
|
312
349
|
writeFileSync(resolve(suiteDir, "suite.json"), JSON.stringify({ suiteName, modelCalls: 0, realBrowser: true }, null, 2));
|
|
313
350
|
writeCommand(suiteDir, command);
|
|
314
351
|
|
|
@@ -367,15 +404,14 @@ async function runBrowserDogfoodSuite(config, targetName, suiteName, leaseSessio
|
|
|
367
404
|
return { ok: assertions.ok, suiteDir, assertions };
|
|
368
405
|
}
|
|
369
406
|
|
|
370
|
-
async function runPlatformBuildSuite(config, targetName, suiteName, leaseSession) {
|
|
371
|
-
const runId = makeRunId();
|
|
407
|
+
async function runPlatformBuildSuite(config, targetName, suiteName, leaseSession, runId = makeRunId()) {
|
|
372
408
|
const suiteDir = createSuiteDir(config.artifactRoot, runId, targetName, suiteName);
|
|
373
409
|
const startedAt = Date.now();
|
|
374
410
|
const platform = platformFor(targetName);
|
|
375
411
|
const slug = `${config.packageName}-${targetName}`;
|
|
376
412
|
const command = buildPlatformBuildCommand(targetName, config.packageName, config.nodeValidationMajor);
|
|
377
413
|
mkdirSync(dirname(suiteDir), { recursive: true });
|
|
378
|
-
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(
|
|
414
|
+
writeFileSync(resolve(suiteDir, "target.json"), JSON.stringify(targetEvidence(config, targetName, runId, slug), null, 2));
|
|
379
415
|
writeFileSync(resolve(suiteDir, "suite.json"), JSON.stringify({ suiteName, modelCalls: 0 }, null, 2));
|
|
380
416
|
writeCommand(suiteDir, command);
|
|
381
417
|
|
|
@@ -436,17 +472,18 @@ async function runPlatformBuildSuite(config, targetName, suiteName, leaseSession
|
|
|
436
472
|
return { ok: assertions.ok, suiteDir, assertions };
|
|
437
473
|
}
|
|
438
474
|
|
|
439
|
-
export async function runTargetSuite(config, targetName, suiteName, leaseSession) {
|
|
440
|
-
if (suiteName === "platform-build") return await runPlatformBuildSuite(config, targetName, suiteName, leaseSession);
|
|
441
|
-
if (suiteName === "browser-dogfood-smoke") return await runBrowserDogfoodSuite(config, targetName, suiteName, leaseSession);
|
|
475
|
+
export async function runTargetSuite(config, targetName, suiteName, leaseSession, runId) {
|
|
476
|
+
if (suiteName === "platform-build") return await runPlatformBuildSuite(config, targetName, suiteName, leaseSession, runId);
|
|
477
|
+
if (suiteName === "browser-dogfood-smoke") return await runBrowserDogfoodSuite(config, targetName, suiteName, leaseSession, runId);
|
|
442
478
|
throw new Error(`unknown suite: ${suiteName}`);
|
|
443
479
|
}
|
|
444
480
|
|
|
445
481
|
export async function runTargetSuites(config, targetName, suiteNames) {
|
|
446
482
|
const slug = `${config.packageName}-${targetName}`;
|
|
483
|
+
const runId = makeRunId();
|
|
447
484
|
const lease = await warmupLease(targetName, slug, config);
|
|
448
485
|
if (!lease.ok) {
|
|
449
|
-
const warmupFailure = createLeaseWarmupFailureResult(config, targetName, lease);
|
|
486
|
+
const warmupFailure = createLeaseWarmupFailureResult(config, targetName, lease, runId);
|
|
450
487
|
return { ok: false, results: [warmupFailure] };
|
|
451
488
|
}
|
|
452
489
|
const results = [];
|
|
@@ -455,7 +492,7 @@ export async function runTargetSuites(config, targetName, suiteNames) {
|
|
|
455
492
|
try {
|
|
456
493
|
let sync = true;
|
|
457
494
|
for (const suiteName of suiteNames) {
|
|
458
|
-
const result = await runTargetSuite(config, targetName, suiteName, { ...lease, sync });
|
|
495
|
+
const result = await runTargetSuite(config, targetName, suiteName, { ...lease, sync }, runId);
|
|
459
496
|
results.push(result);
|
|
460
497
|
sync = false;
|
|
461
498
|
if (!result.ok) break;
|
|
@@ -465,7 +502,7 @@ export async function runTargetSuites(config, targetName, suiteNames) {
|
|
|
465
502
|
staleCleanupResult = await cleanupStaleTargetState(targetName, config);
|
|
466
503
|
}
|
|
467
504
|
if (stopResult) {
|
|
468
|
-
results.push(createLeaseCleanupResult(config, targetName, lease.leaseId, stopResult, staleCleanupResult));
|
|
505
|
+
results.push(createLeaseCleanupResult(config, targetName, lease.leaseId, stopResult, staleCleanupResult, runId));
|
|
469
506
|
}
|
|
470
507
|
return { ok: results.every((result) => result.ok), results };
|
|
471
508
|
}
|
|
@@ -61,6 +61,7 @@ Environment:
|
|
|
61
61
|
PLATFORM_SMOKE_MAC_HOST macOS SSH host; default localhost
|
|
62
62
|
PLATFORM_SMOKE_MAC_USER macOS SSH user; default $USER
|
|
63
63
|
PLATFORM_SMOKE_MAC_WORK_ROOT macOS Crabbox work root
|
|
64
|
+
PLATFORM_SMOKE_MAC_PORT macOS SSH port; default 22
|
|
64
65
|
PLATFORM_SMOKE_UBUNTU_IMAGE Ubuntu local-container image; default pi-agent-browser-native-platform:node24-agent-browser0.27.1
|
|
65
66
|
PLATFORM_SMOKE_WINDOWS_VM Parallels Windows template VM
|
|
66
67
|
PLATFORM_SMOKE_WINDOWS_SNAPSHOT Parallels snapshot name
|