pi-agent-browser-native 0.2.60 → 0.2.62
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 +30 -0
- package/README.md +11 -11
- package/dist/extensions/agent-browser/index.js +51 -30
- package/dist/extensions/agent-browser/lib/argv-descriptor.js +6 -3
- package/dist/extensions/agent-browser/lib/argv-grammar.js +29 -1
- package/dist/extensions/agent-browser/lib/command-policy.js +10 -1
- package/dist/extensions/agent-browser/lib/command-taxonomy.js +7 -0
- package/dist/extensions/agent-browser/lib/input-modes/job.js +1 -23
- package/dist/extensions/agent-browser/lib/input-modes/lookups.js +5 -2
- package/dist/extensions/agent-browser/lib/input-modes/params.js +2 -1
- package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +25 -1
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +4 -3
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +25 -17
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +14 -11
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +3 -2
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.js +2 -1
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +3 -3
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +5 -4
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +4 -4
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +43 -27
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +66 -54
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +24 -15
- package/dist/extensions/agent-browser/lib/playbook.js +4 -4
- package/dist/extensions/agent-browser/lib/results/next-actions.js +19 -1
- package/dist/extensions/agent-browser/lib/results/presentation/batch.js +8 -7
- package/dist/extensions/agent-browser/lib/results/presentation.js +2 -1
- package/dist/extensions/agent-browser/lib/runtime.js +62 -10
- package/dist/extensions/agent-browser/lib/session-page-state.js +14 -7
- package/docs/ARCHITECTURE.md +5 -5
- package/docs/COMMAND_REFERENCE.md +66 -24
- package/docs/SUPPORT_MATRIX.md +10 -8
- package/docs/TOOL_CONTRACT.md +24 -24
- package/package.json +1 -1
- package/scripts/agent-browser-capability-baseline.mjs +36 -4
|
@@ -75,6 +75,7 @@ export function createAgentBrowserParamsSchema(Type = JsonSchema, StringEnum = l
|
|
|
75
75
|
}, { additionalProperties: false, description: "EXPERIMENTAL: local UI-to-source candidates only (confidence/evidence, not guaranteed mappings). Compiles to batch; mutually exclusive with other input modes." })),
|
|
76
76
|
networkSourceLookup: Type.Optional(Type.Object({
|
|
77
77
|
filter: Type.Optional(Type.String({ description: "Optional upstream network requests filter pattern." })),
|
|
78
|
+
namespace: Type.Optional(Type.String({ description: "Optional upstream namespace; prepends --namespace <name> before the generated batch." })),
|
|
78
79
|
requestId: Type.Optional(Type.String({ description: "Optional network request id to inspect with network request <id>." })),
|
|
79
80
|
session: Type.Optional(Type.String({ description: "Optional upstream session name; prepends --session <name> before the generated batch." })),
|
|
80
81
|
url: Type.Optional(Type.String({ description: "Optional failed request URL or URL fragment to correlate with local source." })),
|
|
@@ -135,7 +136,7 @@ export function createAgentBrowserParamsSchema(Type = JsonSchema, StringEnum = l
|
|
|
135
136
|
outputPath: Type.Optional(Type.String({ description: "Optional workspace-relative or absolute file path that receives the model-facing command data/result after the browser command completes. Useful for eval/get/snapshot captures that should become durable local artifacts.", minLength: 1 })),
|
|
136
137
|
timeoutMs: Type.Optional(Type.Integer({ description: "Optional per-call wrapper subprocess watchdog in milliseconds for browser CLI args/job/qa/source lookup calls. Use for long opens or large output captures; explicit long wait steps are forwarded, so set timeoutMs above the wait duration plus a small grace window when overriding the derived watchdog. Electron actions use electron.timeoutMs instead.", minimum: 1 })),
|
|
137
138
|
sessionMode: Type.Optional(StringEnum(["auto", "fresh"], {
|
|
138
|
-
description: "Session handling mode. `auto` reuses the extension-managed pi-scoped session when possible. `fresh` switches that managed session to a fresh upstream launch so launch-scoped flags like --profile, --executable-path, --session-name, --cdp, --state, --auto-connect, --init-script, --enable, -p/--provider, or iOS --device apply and later auto calls follow the new browser.",
|
|
139
|
+
description: "Session handling mode. `auto` reuses the extension-managed pi-scoped session when possible. `fresh` switches that managed session to a fresh upstream launch so launch-scoped flags like --namespace, --restore, --restore-save, restore check flags, --profile, --executable-path, --session-name, --cdp, --state, --auto-connect, --init-script, --enable, -p/--provider, or iOS --device apply and later auto calls follow the new browser.",
|
|
139
140
|
default: DEFAULT_SESSION_MODE,
|
|
140
141
|
})),
|
|
141
142
|
}, { additionalProperties: false });
|
|
@@ -8,6 +8,10 @@ export const LAUNCH_SCOPED_FLAG_DEFINITIONS = [
|
|
|
8
8
|
flag: "--auto-connect",
|
|
9
9
|
reason: "attaches to an already-running browser at launch time instead of reusing an existing named session",
|
|
10
10
|
},
|
|
11
|
+
{
|
|
12
|
+
flag: "--namespace",
|
|
13
|
+
reason: "selects the upstream daemon/socket and restore-state namespace before session lookup",
|
|
14
|
+
},
|
|
11
15
|
{
|
|
12
16
|
flag: "--cdp",
|
|
13
17
|
reason: "selects the browser/CDP endpoint used when an upstream session is launched",
|
|
@@ -44,6 +48,26 @@ export const LAUNCH_SCOPED_FLAG_DEFINITIONS = [
|
|
|
44
48
|
flag: "--session-name",
|
|
45
49
|
reason: "selects upstream saved auth/session state for the launch",
|
|
46
50
|
},
|
|
51
|
+
{
|
|
52
|
+
flag: "--restore",
|
|
53
|
+
reason: "selects upstream saved auth/session restore state for the launch",
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
flag: "--restore-save",
|
|
57
|
+
reason: "configures upstream restore auto-save policy for the launched session",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
flag: "--restore-check-url",
|
|
61
|
+
reason: "configures restore validation before the launched session can auto-save",
|
|
62
|
+
},
|
|
63
|
+
{
|
|
64
|
+
flag: "--restore-check-text",
|
|
65
|
+
reason: "configures restore validation before the launched session can auto-save",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
flag: "--restore-check-fn",
|
|
69
|
+
reason: "configures restore validation before the launched session can auto-save",
|
|
70
|
+
},
|
|
47
71
|
{
|
|
48
72
|
flag: "--state",
|
|
49
73
|
reason: "loads persisted upstream browser/auth state at launch time",
|
|
@@ -56,4 +80,4 @@ export const LAUNCH_SCOPED_FLAG_LABEL = LAUNCH_SCOPED_FLAGS.join(", ");
|
|
|
56
80
|
* and are plausible wrong-active-tab sources after a fresh launch. These trigger post-open
|
|
57
81
|
* tab-correction (the `tab list` + re-select cycle).
|
|
58
82
|
*/
|
|
59
|
-
export const LAUNCH_SCOPED_TAB_CORRECTION_FLAGS = new Set(["--profile", "--session-name", "--state"]);
|
|
83
|
+
export const LAUNCH_SCOPED_TAB_CORRECTION_FLAGS = new Set(["--profile", "--session-name", "--restore", "--state"]);
|
|
@@ -43,7 +43,7 @@ function getClickDispatchProbeTarget(commandTokens, refSnapshot) {
|
|
|
43
43
|
}
|
|
44
44
|
if (selector.startsWith("xpath="))
|
|
45
45
|
return { kind: "xpath", selector: selector.slice("xpath=".length) };
|
|
46
|
-
return
|
|
46
|
+
return undefined;
|
|
47
47
|
}
|
|
48
48
|
function getEvalResultRecord(data) {
|
|
49
49
|
return isRecord(data) && isRecord(data.result) ? data.result : undefined;
|
|
@@ -219,7 +219,7 @@ export async function prepareClickDispatchProbe(options) {
|
|
|
219
219
|
if (!target)
|
|
220
220
|
return undefined;
|
|
221
221
|
const probe = { marker: `${CLICK_DISPATCH_MARKER_PREFIX}${Date.now().toString(36)}_${Math.random().toString(36).slice(2)}`, target };
|
|
222
|
-
const installData = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, stdin: buildClickDispatchProbeInstallScript(probe) });
|
|
222
|
+
const installData = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, stdin: buildClickDispatchProbeInstallScript(probe) });
|
|
223
223
|
const installResult = getEvalResultRecord(installData);
|
|
224
224
|
return installResult?.status === "installed" ? probe : undefined;
|
|
225
225
|
}
|
|
@@ -241,7 +241,7 @@ function getClickDispatchScrollContainerDiagnostic(result) {
|
|
|
241
241
|
export async function collectClickDispatchDiagnostic(options) {
|
|
242
242
|
if (!options.probe || !options.sessionName)
|
|
243
243
|
return undefined;
|
|
244
|
-
const data = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, stdin: buildClickDispatchProbeCheckScript(options.probe) });
|
|
244
|
+
const data = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, stdin: buildClickDispatchProbeCheckScript(options.probe) });
|
|
245
245
|
const result = getEvalResultRecord(data);
|
|
246
246
|
if (!result)
|
|
247
247
|
return undefined;
|
|
@@ -269,6 +269,7 @@ export async function cleanupClickDispatchProbe(options) {
|
|
|
269
269
|
await runSessionCommandData({
|
|
270
270
|
args: ["eval", "--stdin"],
|
|
271
271
|
cwd: options.cwd,
|
|
272
|
+
namespace: options.namespace,
|
|
272
273
|
sessionName: options.sessionName,
|
|
273
274
|
stdin: buildClickDispatchProbeCleanupScript(options.probe),
|
|
274
275
|
timeoutMs: CLICK_DISPATCH_CLEANUP_TIMEOUT_MS,
|
|
@@ -18,9 +18,14 @@ export function sleepMs(ms) {
|
|
|
18
18
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
19
19
|
}
|
|
20
20
|
export async function collectNavigationSummary(options) {
|
|
21
|
+
const url = extractStringResultField(await runSessionCommandData({ args: ["get", "url"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal }), "url");
|
|
22
|
+
const title = extractStringResultField(await runSessionCommandData({ args: ["get", "title"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal }), "title");
|
|
23
|
+
if (url && /^[a-z][a-z0-9+.-]*:/i.test(url))
|
|
24
|
+
return { title, url };
|
|
21
25
|
return extractNavigationSummaryFromData(await runSessionCommandData({
|
|
22
26
|
args: ["eval", "--stdin"],
|
|
23
27
|
cwd: options.cwd,
|
|
28
|
+
namespace: options.namespace,
|
|
24
29
|
sessionName: options.sessionName,
|
|
25
30
|
signal: options.signal,
|
|
26
31
|
stdin: `({ title: document.title, url: location.href })`,
|
|
@@ -74,7 +79,7 @@ const SCROLL_POSITION_EVAL = `(() => {
|
|
|
74
79
|
return { ...viewport, containerCount: containers.length, containers };
|
|
75
80
|
})()`;
|
|
76
81
|
export async function collectScrollPositionSnapshot(options) {
|
|
77
|
-
return extractScrollPositionSnapshot(await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, stdin: SCROLL_POSITION_EVAL }));
|
|
82
|
+
return extractScrollPositionSnapshot(await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, stdin: SCROLL_POSITION_EVAL }));
|
|
78
83
|
}
|
|
79
84
|
function sameScrollPositionSnapshot(left, right) {
|
|
80
85
|
return left.scrollX === right.scrollX && left.scrollY === right.scrollY && left.scrollHeight === right.scrollHeight && left.scrollWidth === right.scrollWidth && left.containers.length === right.containers.length && left.containers.every((container, index) => {
|
|
@@ -173,7 +178,7 @@ function isComboboxFocusDiagnosticSemanticAction(compiled) {
|
|
|
173
178
|
export async function collectComboboxFocusDiagnostic(options) {
|
|
174
179
|
if (!isComboboxFocusDiagnosticCommand(options.command, options.commandTokens) && !isComboboxFocusDiagnosticSemanticAction(options.semanticAction))
|
|
175
180
|
return undefined;
|
|
176
|
-
return extractComboboxFocusDiagnostic(await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, stdin: COMBOBOX_FOCUS_EVAL }));
|
|
181
|
+
return extractComboboxFocusDiagnostic(await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, stdin: COMBOBOX_FOCUS_EVAL }));
|
|
177
182
|
}
|
|
178
183
|
export function buildComboboxFocusNextActions(sessionName) {
|
|
179
184
|
return [
|
|
@@ -257,11 +262,13 @@ export function collectSnapshotOverlayBlockerDiagnostic(data) {
|
|
|
257
262
|
export async function collectOverlayBlockerDiagnostic(options) {
|
|
258
263
|
if (options.command !== "click" || !isRecord(options.data) || typeof options.data.clicked !== "string")
|
|
259
264
|
return undefined;
|
|
265
|
+
if (!options.data.clicked.startsWith("@") && !options.data.clicked.startsWith("ref="))
|
|
266
|
+
return undefined;
|
|
260
267
|
const priorUrl = normalizeComparableUrl(options.priorTarget?.url);
|
|
261
268
|
const currentUrl = normalizeComparableUrl(options.navigationSummary?.url);
|
|
262
|
-
if (!priorUrl || !currentUrl ||
|
|
269
|
+
if (!priorUrl || !currentUrl || currentUrl !== priorUrl)
|
|
263
270
|
return undefined;
|
|
264
|
-
const snapshotData = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
271
|
+
const snapshotData = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
265
272
|
const diagnostic = collectSnapshotOverlayBlockerDiagnostic(snapshotData);
|
|
266
273
|
if (!diagnostic)
|
|
267
274
|
return undefined;
|
|
@@ -314,9 +321,9 @@ function selectorMayExposeSensitiveLiteral(selector) {
|
|
|
314
321
|
}
|
|
315
322
|
async function collectSelectorTextVisibilityDiagnosticForSelector(options) {
|
|
316
323
|
const { selector } = options;
|
|
317
|
-
if (!selector || /^@e\d+$/.test(selector) || selectorMayExposeSensitiveLiteral(selector))
|
|
324
|
+
if (!selector || /^@e\d+$/.test(selector) || /^#[A-Za-z_][\w-]*$/.test(selector) || selectorMayExposeSensitiveLiteral(selector))
|
|
318
325
|
return undefined;
|
|
319
|
-
const probe = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, stdin: buildVisibleTextProbeScript(selector) });
|
|
326
|
+
const probe = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, stdin: buildVisibleTextProbeScript(selector) });
|
|
320
327
|
const parsed = parseSelectorTextVisibilityProbe(probe, selector);
|
|
321
328
|
if (!parsed || parsed.matchCount <= 1 && parsed.firstMatchVisible !== false)
|
|
322
329
|
return undefined;
|
|
@@ -348,7 +355,7 @@ export async function collectSelectorTextVisibilityDiagnostics(options) {
|
|
|
348
355
|
const selectors = getSuccessfulGetTextSelectors(options);
|
|
349
356
|
const diagnostics = [];
|
|
350
357
|
for (const selector of selectors) {
|
|
351
|
-
const diagnostic = await collectSelectorTextVisibilityDiagnosticForSelector({ cwd: options.cwd, selector, sessionName: options.sessionName, signal: options.signal });
|
|
358
|
+
const diagnostic = await collectSelectorTextVisibilityDiagnosticForSelector({ cwd: options.cwd, namespace: options.namespace, selector, sessionName: options.sessionName, signal: options.signal });
|
|
352
359
|
if (diagnostic)
|
|
353
360
|
diagnostics.push(diagnostic);
|
|
354
361
|
}
|
|
@@ -510,6 +517,7 @@ async function collectElectronManagedSessionUrl(options) {
|
|
|
510
517
|
const urlResult = await collectManagedSessionCommandData({
|
|
511
518
|
args: ["get", "url"],
|
|
512
519
|
cwd: options.cwd,
|
|
520
|
+
namespace: options.namespace,
|
|
513
521
|
sessionName: options.sessionName,
|
|
514
522
|
signal: options.signal,
|
|
515
523
|
timeoutMs: options.timeoutMs,
|
|
@@ -521,8 +529,8 @@ export async function collectElectronManagedSessionTarget(options) {
|
|
|
521
529
|
if (!options.sessionName)
|
|
522
530
|
return undefined;
|
|
523
531
|
const [titleResult, urlResult] = await Promise.all([
|
|
524
|
-
collectManagedSessionCommandData({ args: ["get", "title"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, timeoutMs: options.timeoutMs }),
|
|
525
|
-
collectManagedSessionCommandData({ args: ["get", "url"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, timeoutMs: options.timeoutMs }),
|
|
532
|
+
collectManagedSessionCommandData({ args: ["get", "title"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, timeoutMs: options.timeoutMs }),
|
|
533
|
+
collectManagedSessionCommandData({ args: ["get", "url"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, timeoutMs: options.timeoutMs }),
|
|
526
534
|
]);
|
|
527
535
|
const title = boundElectronProbeString(extractStringResultField(titleResult.data, "result") ?? extractStringResultField(titleResult.data, "title"), 160);
|
|
528
536
|
const url = boundElectronProbeString(extractStringResultField(urlResult.data, "result") ?? extractStringResultField(urlResult.data, "url"), 300);
|
|
@@ -534,7 +542,7 @@ export async function collectQaAttachedTarget(options) {
|
|
|
534
542
|
return undefined;
|
|
535
543
|
if (options.currentTarget?.title || options.currentTarget?.url)
|
|
536
544
|
return { sessionName: options.sessionName, title: options.currentTarget.title, url: options.currentTarget.url };
|
|
537
|
-
return collectElectronManagedSessionTarget({ cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
545
|
+
return collectElectronManagedSessionTarget({ cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
538
546
|
}
|
|
539
547
|
export function formatQaAttachedTargetText(target) {
|
|
540
548
|
if (!target)
|
|
@@ -565,7 +573,7 @@ export async function validateQaAttachedPrecondition(options) {
|
|
|
565
573
|
nextActions: buildQaAttachedRecoveryNextActions(options.sessionName),
|
|
566
574
|
};
|
|
567
575
|
}
|
|
568
|
-
const urlProbe = await collectElectronManagedSessionUrl({ cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
576
|
+
const urlProbe = await collectElectronManagedSessionUrl({ cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
569
577
|
if (urlProbe.error) {
|
|
570
578
|
return {
|
|
571
579
|
error: `qa.attached could not read the attached session URL: ${urlProbe.error}. Run tab list or snapshot -i before retrying qa.attached.`,
|
|
@@ -630,7 +638,7 @@ export async function collectFillVerificationDiagnostic(options) {
|
|
|
630
638
|
const method = contenteditable ? "text" : "value";
|
|
631
639
|
let valueData;
|
|
632
640
|
try {
|
|
633
|
-
valueData = await runSessionCommandData({ args: ["get", method, fill.selector], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, timeoutMs: ELECTRON_FILL_VERIFICATION_TIMEOUT_MS });
|
|
641
|
+
valueData = await runSessionCommandData({ args: ["get", method, fill.selector], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, timeoutMs: ELECTRON_FILL_VERIFICATION_TIMEOUT_MS });
|
|
634
642
|
}
|
|
635
643
|
catch {
|
|
636
644
|
return undefined;
|
|
@@ -659,22 +667,22 @@ export async function collectVisibleRefFallbackDiagnostic(options) {
|
|
|
659
667
|
const target = getVisibleRefFallbackTarget({ commandTokens: options.commandTokens, compiledSemanticAction: options.compiledSemanticAction });
|
|
660
668
|
if (!target)
|
|
661
669
|
return undefined;
|
|
662
|
-
const snapshotData = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
670
|
+
const snapshotData = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
663
671
|
return buildVisibleRefFallbackDiagnosticFromSnapshot({ snapshotData, target });
|
|
664
672
|
}
|
|
665
673
|
export async function collectElectronHandoff(options) {
|
|
666
674
|
if (options.handoff === "connect")
|
|
667
675
|
return { handoff: "connect" };
|
|
668
|
-
const tabs = await runSessionCommandData({ args: ["tab", "list"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
676
|
+
const tabs = await runSessionCommandData({ args: ["tab", "list"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
669
677
|
if (options.handoff === "tabs")
|
|
670
678
|
return { handoff: "tabs", tabs };
|
|
671
|
-
let snapshot = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
679
|
+
let snapshot = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
672
680
|
let refSnapshot = extractRefSnapshotFromData(snapshot);
|
|
673
681
|
let snapshotRetryCount = 0;
|
|
674
682
|
while ((!refSnapshot || refSnapshot.refIds.length === 0) && snapshotRetryCount < 2) {
|
|
675
683
|
snapshotRetryCount += 1;
|
|
676
684
|
await sleepMs(250);
|
|
677
|
-
snapshot = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
685
|
+
snapshot = await runSessionCommandData({ args: ["snapshot", "-i"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
678
686
|
refSnapshot = extractRefSnapshotFromData(snapshot);
|
|
679
687
|
}
|
|
680
688
|
return { handoff: "snapshot", refSnapshot, snapshot, ...(snapshotRetryCount > 0 ? { snapshotRetryCount } : {}), tabs };
|
|
@@ -849,7 +857,7 @@ function buildTimeoutProgressSteps(options) {
|
|
|
849
857
|
export async function collectTimeoutPartialProgress(options) {
|
|
850
858
|
const rawSteps = getTimeoutProgressSteps(options.compiledJob, options.command, options.stdin);
|
|
851
859
|
const artifacts = await collectTimeoutArtifactEvidence(options.cwd, rawSteps);
|
|
852
|
-
const [urlData, titleData] = await Promise.all([runSessionCommandData({ args: ["get", "url"], cwd: options.cwd, sessionName: options.sessionName }), runSessionCommandData({ args: ["get", "title"], cwd: options.cwd, sessionName: options.sessionName })]);
|
|
860
|
+
const [urlData, titleData] = await Promise.all([runSessionCommandData({ args: ["get", "url"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName }), runSessionCommandData({ args: ["get", "title"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName })]);
|
|
853
861
|
const recoveredUrl = extractStringResultField(urlData, "result") ?? extractStringResultField(urlData, "url");
|
|
854
862
|
const title = extractStringResultField(titleData, "result") ?? extractStringResultField(titleData, "title");
|
|
855
863
|
const plannedUrl = recoveredUrl ? undefined : getPlannedCurrentPageUrl(rawSteps);
|
|
@@ -2,7 +2,7 @@ import { cleanupElectronLaunchResources } from "../../electron/cleanup.js";
|
|
|
2
2
|
import { getCompiledSemanticActionCommandIndex, getCompiledSemanticActionSessionPrefix, isCompiledSemanticActionFindCommand, redactNetworkSourceLookupSurface, } from "../../input-modes.js";
|
|
3
3
|
import { buildAgentBrowserNextActions, buildAgentBrowserResultCategoryDetails, } from "../../results.js";
|
|
4
4
|
import { formatSessionArtifactRetentionSummary } from "../../results/artifact-manifest.js";
|
|
5
|
-
import { AgentBrowserNextActionCollector, alignPageChangeSummaryNextActionIds, isStandaloneSnapshotNextAction, withOptionalSessionArgs, } from "../../results/next-actions.js";
|
|
5
|
+
import { AgentBrowserNextActionCollector, alignPageChangeSummaryNextActionIds, applyNamespaceToNextActions, isStandaloneSnapshotNextAction, withOptionalSessionArgs, } from "../../results/next-actions.js";
|
|
6
6
|
import { buildConnectedSessionNextActions, buildNoActivePageNextActions, buildSessionAwareStaleRefNextActions, buildSessionTabRecoveryNextActions, } from "../../results/recovery-next-actions.js";
|
|
7
7
|
import { buildRichInputRecoveryDiagnostic, buildRichInputRecoveryNextActions, buildVisibleRefFallbackNextActions, formatRichInputRecoveryText, formatVisibleRefFallbackText, sanitizeVisibleRefFallbackDiagnostic, } from "../../results/selector-recovery.js";
|
|
8
8
|
import { buildNoActivePageRefSnapshotInvalidation, isNoActivePageSnapshotFailure, } from "../../session-page-state.js";
|
|
@@ -10,7 +10,7 @@ import { extractExplicitSessionName, redactInvocationArgs, redactSensitiveText,
|
|
|
10
10
|
import { isRecord } from "../../parsing.js";
|
|
11
11
|
import { buildClickDispatchNextActions, formatClickDispatchDiagnosticText } from "./click-dispatch.js";
|
|
12
12
|
import { buildComboboxFocusNextActions, buildElectronBroadGetTextScopeNextActions, buildFillVerificationNextActions, buildOverlayBlockerNextActions, buildScrollNoopNextActions, buildSelectorTextVisibilityNextActions, buildSourceLookupElectronNextActions, collectVisibleRefFallbackDiagnostic, formatArtifactCleanupGuidanceText, formatComboboxFocusDiagnosticText, formatElectronBroadGetTextScopeText, formatEvalResultWarningText, formatEvalStdinHintText, formatFillVerificationText, formatOverlayBlockerText, formatRecordingDependencyWarningText, formatScrollNoopDiagnosticText, formatSelectorTextVisibilityText, formatTimeoutPartialProgressText, } from "./diagnostics.js";
|
|
13
|
-
import { buildElectronIdentifiers, buildElectronLifecycleNextActions, buildElectronMismatchNextActions, buildElectronRefFreshnessNextActions, buildManagedSessionFreshFailureNextActions, buildManagedSessionOutcome, buildSessionDetailFields, formatElectronRefFreshnessText, formatManagedSessionOutcomeText, } from "./session-state.js";
|
|
13
|
+
import { buildElectronIdentifiers, buildElectronLifecycleNextActions, buildElectronMismatchNextActions, buildElectronRefFreshnessNextActions, buildManagedSessionFreshFailureNextActions, buildManagedSessionOutcome, buildSessionDetailFields, getSessionContextKey, formatElectronRefFreshnessText, formatManagedSessionOutcomeText, } from "./session-state.js";
|
|
14
14
|
export function buildMissingBinaryMessage() {
|
|
15
15
|
return [
|
|
16
16
|
"agent-browser is required but was not found on PATH.",
|
|
@@ -180,17 +180,19 @@ export async function prepareFinalResultRecoveryState(options) {
|
|
|
180
180
|
const visibleRefFallbackSessionName = options.executionPlan.sessionName ?? extractExplicitSessionName(options.runtimeToolArgs);
|
|
181
181
|
if (categoryDetails.failureCategory === "selector-not-found") {
|
|
182
182
|
const selectorRecoveryCommandTokens = options.presentation.batchFailure?.failedStep.command ?? options.commandTokens;
|
|
183
|
-
visibleRefFallbackDiagnostic = await collectVisibleRefFallbackDiagnostic({ commandTokens: selectorRecoveryCommandTokens, compiledSemanticAction: options.compiledSemanticAction, cwd: options.cwd, sessionName: visibleRefFallbackSessionName, signal: options.signal });
|
|
184
|
-
|
|
185
|
-
|
|
183
|
+
visibleRefFallbackDiagnostic = await collectVisibleRefFallbackDiagnostic({ commandTokens: selectorRecoveryCommandTokens, compiledSemanticAction: options.compiledSemanticAction, cwd: options.cwd, namespace: options.executionPlan.namespace, sessionName: visibleRefFallbackSessionName, signal: options.signal });
|
|
184
|
+
const visibleRefFallbackSessionKey = getSessionContextKey(visibleRefFallbackSessionName, options.executionPlan.namespace);
|
|
185
|
+
if (visibleRefFallbackDiagnostic && visibleRefFallbackSessionKey) {
|
|
186
|
+
const refUpdate = options.sessionPageState.applyRefSnapshot({ fallbackTarget: options.currentSessionTabTarget, sessionName: visibleRefFallbackSessionKey, snapshot: visibleRefFallbackDiagnostic.snapshot, update: options.sessionPageStateUpdate });
|
|
186
187
|
currentRefSnapshot = refUpdate.refSnapshot;
|
|
187
188
|
currentRefSnapshotInvalidation = refUpdate.refSnapshotInvalidation;
|
|
188
189
|
}
|
|
189
190
|
}
|
|
190
191
|
const richInputRecoveryDiagnostic = buildRichInputRecoveryDiagnostic(visibleRefFallbackDiagnostic);
|
|
191
192
|
const noActivePageSnapshotFailure = categoryDetails.resultCategory === "failure" && (isNoActivePageSnapshotFailure(options.executionPlan.commandInfo.command, options.errorText ?? options.presentation.summary) || options.batchRefSnapshotState?.invalidation !== undefined);
|
|
192
|
-
|
|
193
|
-
|
|
193
|
+
const executionSessionKey = getSessionContextKey(options.executionPlan.sessionName, options.executionPlan.namespace);
|
|
194
|
+
if (noActivePageSnapshotFailure && executionSessionKey) {
|
|
195
|
+
const refUpdate = options.sessionPageState.applyRefSnapshotInvalidation({ invalidation: buildNoActivePageRefSnapshotInvalidation(), sessionName: executionSessionKey, update: options.sessionPageStateUpdate });
|
|
194
196
|
currentRefSnapshot = refUpdate.refSnapshot;
|
|
195
197
|
currentRefSnapshotInvalidation = refUpdate.refSnapshotInvalidation;
|
|
196
198
|
}
|
|
@@ -385,6 +387,7 @@ function buildAgentBrowserResultDetails(options, nextActions) {
|
|
|
385
387
|
sessionTabTarget: options.currentSessionTabTarget,
|
|
386
388
|
refSnapshot: options.currentRefSnapshot,
|
|
387
389
|
refSnapshotInvalidation: options.currentRefSnapshotInvalidation,
|
|
390
|
+
namespace: options.executionPlan.namespace,
|
|
388
391
|
...buildSessionDetailFields(options.executionPlan.sessionName, options.executionPlan.usedImplicitSession),
|
|
389
392
|
sessionRecoveryHint: options.redactedRecoveryHint,
|
|
390
393
|
startupScopedFlags: options.executionPlan.startupScopedFlags,
|
|
@@ -396,7 +399,7 @@ function buildAgentBrowserResultDetails(options, nextActions) {
|
|
|
396
399
|
};
|
|
397
400
|
}
|
|
398
401
|
export function buildFinalAgentBrowserToolResult(options) {
|
|
399
|
-
const nextActions = buildResultNextActions(options);
|
|
402
|
+
const nextActions = applyNamespaceToNextActions(buildResultNextActions(options), options.executionPlan.namespace);
|
|
400
403
|
const details = buildAgentBrowserResultDetails(options, nextActions);
|
|
401
404
|
const visibleRefFallbackText = formatVisibleRefFallbackText(options.visibleRefFallbackDiagnostic);
|
|
402
405
|
const richInputRecoveryText = formatRichInputRecoveryText(options.richInputRecoveryDiagnostic);
|
|
@@ -429,9 +432,9 @@ export async function buildMissingBinaryFailureResult(options) {
|
|
|
429
432
|
if (!options.processResult.spawnError?.message.includes("ENOENT"))
|
|
430
433
|
return undefined;
|
|
431
434
|
const errorText = buildMissingBinaryMessage();
|
|
432
|
-
const managedSessionOutcome = buildManagedSessionOutcome({ activeAfter: options.managedSessionActive, activeBefore: options.managedSessionActive, attemptedSessionName: options.executionPlan.managedSessionName, command: options.executionPlan.commandInfo.command, currentSessionName: options.managedSessionName, previousSessionName: options.managedSessionName, sessionMode: options.sessionMode, succeeded: false });
|
|
435
|
+
const managedSessionOutcome = buildManagedSessionOutcome({ activeAfter: options.managedSessionActive, activeBefore: options.managedSessionActive, attemptedSessionName: options.executionPlan.managedSessionName, command: options.executionPlan.commandInfo.command, currentSessionName: options.managedSessionName, currentSessionNamespace: options.managedSessionNamespace, previousSessionName: options.managedSessionName, sessionMode: options.sessionMode, succeeded: false });
|
|
433
436
|
const managedSessionOutcomeText = formatManagedSessionOutcomeText(managedSessionOutcome);
|
|
434
|
-
const managedSessionRecoveryNextActions = buildManagedSessionFreshFailureNextActions(managedSessionOutcome);
|
|
437
|
+
const managedSessionRecoveryNextActions = applyNamespaceToNextActions(buildManagedSessionFreshFailureNextActions(managedSessionOutcome), options.executionPlan.namespace) ?? [];
|
|
435
438
|
let missingBinaryElectronCleanup;
|
|
436
439
|
let missingBinaryElectronRecord;
|
|
437
440
|
if (options.electronLaunch) {
|
|
@@ -439,5 +442,5 @@ export async function buildMissingBinaryFailureResult(options) {
|
|
|
439
442
|
missingBinaryElectronRecord = missingBinaryElectronCleanup.record;
|
|
440
443
|
}
|
|
441
444
|
const textParts = [errorText, managedSessionOutcomeText, missingBinaryElectronCleanup ? `Electron cleanup after failed attach: ${missingBinaryElectronCleanup.summary}` : undefined].filter((part) => part !== undefined && part.length > 0);
|
|
442
|
-
return { content: [{ type: "text", text: textParts.join("\n\n") }], details: { args: options.redactedArgs, compatibilityWorkaround: options.compatibilityWorkaround, effectiveArgs: options.redactedProcessArgs, electron: missingBinaryElectronRecord ? { action: "launch", cleanup: missingBinaryElectronCleanup, launch: missingBinaryElectronRecord, status: "failed", targets: options.electronLaunch?.targets, version: options.electronLaunch?.version } : undefined, managedSessionOutcome, nextActions: managedSessionRecoveryNextActions.length > 0 ? managedSessionRecoveryNextActions : undefined, sessionMode: options.sessionMode, sessionTabCorrection: options.sessionTabCorrection, ...buildAgentBrowserResultCategoryDetails({ args: options.redactedProcessArgs, command: options.executionPlan.commandInfo.command, errorText, failureCategory: "missing-binary", spawnError: options.processResult.spawnError.message, succeeded: false }), spawnError: options.processResult.spawnError.message }, isError: true };
|
|
445
|
+
return { content: [{ type: "text", text: textParts.join("\n\n") }], details: { args: options.redactedArgs, compatibilityWorkaround: options.compatibilityWorkaround, effectiveArgs: options.redactedProcessArgs, electron: missingBinaryElectronRecord ? { action: "launch", cleanup: missingBinaryElectronCleanup, launch: missingBinaryElectronRecord, status: "failed", targets: options.electronLaunch?.targets, version: options.electronLaunch?.version } : undefined, managedSessionOutcome, namespace: options.executionPlan.namespace, nextActions: managedSessionRecoveryNextActions.length > 0 ? managedSessionRecoveryNextActions : undefined, sessionMode: options.sessionMode, sessionTabCorrection: options.sessionTabCorrection, ...buildAgentBrowserResultCategoryDetails({ args: options.redactedProcessArgs, command: options.executionPlan.commandInfo.command, errorText, failureCategory: "missing-binary", spawnError: options.processResult.spawnError.message, succeeded: false }), spawnError: options.processResult.spawnError.message }, isError: true };
|
|
443
446
|
}
|
|
@@ -4,7 +4,7 @@ import { applyBrowserRunStatePatch } from "./session-state.js";
|
|
|
4
4
|
import { buildMissingBinaryFailureResult } from "./final-result.js";
|
|
5
5
|
import { prepareBrowserRun } from "./prepare.js";
|
|
6
6
|
import { processBrowserOutput } from "./process-output.js";
|
|
7
|
-
export { closeManagedSession } from "./session-state.js";
|
|
7
|
+
export { closeManagedSession, getSessionContextKey } from "./session-state.js";
|
|
8
8
|
export async function runAgentBrowserTool(options) {
|
|
9
9
|
const preparedResult = await prepareBrowserRun(options);
|
|
10
10
|
applyBrowserRunStatePatch(options.state, preparedResult.kind === "ready" ? preparedResult.prepared.statePatch : preparedResult.statePatch);
|
|
@@ -28,6 +28,7 @@ export async function runAgentBrowserTool(options) {
|
|
|
28
28
|
implicitSessionCloseTimeoutMs: options.implicitSessionCloseTimeoutMs,
|
|
29
29
|
managedSessionActive: options.state.managedSessionActive,
|
|
30
30
|
managedSessionName: options.state.managedSessionName,
|
|
31
|
+
managedSessionNamespace: options.state.managedSessionNamespace,
|
|
31
32
|
processResult,
|
|
32
33
|
redactedArgs: prepared.redactedArgs,
|
|
33
34
|
redactedProcessArgs: prepared.redactedProcessArgs,
|
|
@@ -42,6 +43,6 @@ export async function runAgentBrowserTool(options) {
|
|
|
42
43
|
return output.result;
|
|
43
44
|
}
|
|
44
45
|
finally {
|
|
45
|
-
await cleanupClickDispatchProbe({ cwd: options.cwd, probe: prepared.clickDispatchProbe, sessionName: prepared.executionPlan.sessionName });
|
|
46
|
+
await cleanupClickDispatchProbe({ cwd: options.cwd, namespace: prepared.executionPlan.namespace, probe: prepared.clickDispatchProbe, sessionName: prepared.executionPlan.sessionName });
|
|
46
47
|
}
|
|
47
48
|
}
|
|
@@ -29,6 +29,7 @@ export async function tryDirectAnchorDownload(options) {
|
|
|
29
29
|
const probeData = await runSessionCommandData({
|
|
30
30
|
args: ["eval", "--stdin"],
|
|
31
31
|
cwd: options.cwd,
|
|
32
|
+
namespace: options.namespace,
|
|
32
33
|
sessionName: options.sessionName,
|
|
33
34
|
signal: options.signal,
|
|
34
35
|
stdin: buildAnchorDownloadProbe(request.selector),
|
|
@@ -128,7 +129,7 @@ export async function tryDirectAnchorDownload(options) {
|
|
|
128
129
|
savedFilePath: absolutePath,
|
|
129
130
|
sessionMode: options.sessionMode,
|
|
130
131
|
...buildAgentBrowserResultCategoryDetails({ artifacts: [artifact], args: options.effectiveArgs, command: "download", savedFile, succeeded: true }),
|
|
131
|
-
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession),
|
|
132
|
+
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession, options.namespace),
|
|
132
133
|
summary: `Download completed: ${absolutePath}`,
|
|
133
134
|
},
|
|
134
135
|
isError: false,
|
package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js
CHANGED
|
@@ -79,10 +79,10 @@ export async function tryNetworkRequestsPageFilter(options) {
|
|
|
79
79
|
const request = parseNetworkRequestsPageFilterRequest(options.commandTokens);
|
|
80
80
|
if (!request || !options.sessionName)
|
|
81
81
|
return undefined;
|
|
82
|
-
const currentUrl = extractCurrentUrl(await runSessionCommandData({ args: ["get", "url"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal }));
|
|
82
|
+
const currentUrl = extractCurrentUrl(await runSessionCommandData({ args: ["get", "url"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal }));
|
|
83
83
|
if (!currentUrl)
|
|
84
84
|
return undefined;
|
|
85
|
-
const networkData = await runSessionCommandData({ args: request.cleanArgs, cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
85
|
+
const networkData = await runSessionCommandData({ args: request.cleanArgs, cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
86
86
|
const filtered = filterNetworkRequestsData(networkData, currentUrl, request);
|
|
87
87
|
if (!filtered)
|
|
88
88
|
return undefined;
|
|
@@ -100,7 +100,7 @@ export async function tryNetworkRequestsPageFilter(options) {
|
|
|
100
100
|
networkRequestsPageFilter: { cleanArgs: request.cleanArgs, currentUrl: redactSensitiveText(currentUrl), matchedRows: filtered.matchedRows, mode: request.mode, totalRows: filtered.totalRows },
|
|
101
101
|
sessionMode: options.sessionMode,
|
|
102
102
|
...buildAgentBrowserResultCategoryDetails({ args: options.effectiveArgs, command: "network", succeeded: true }),
|
|
103
|
-
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession),
|
|
103
|
+
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession, options.namespace),
|
|
104
104
|
summary,
|
|
105
105
|
},
|
|
106
106
|
isError: false,
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { isRecord } from "../../../parsing.js";
|
|
2
2
|
import { buildAgentBrowserResultCategoryDetails } from "../../../results.js";
|
|
3
|
+
import { applyNamespaceToNextActions } from "../../../results/next-actions.js";
|
|
3
4
|
import { buildScrollNoopNextActions } from "../diagnostics.js";
|
|
4
5
|
import { buildSessionDetailFields, runSessionCommandData } from "../session-state.js";
|
|
5
6
|
const SCROLL_CONTAINER_DIRECTIONS = new Set(["down", "left", "right", "up"]);
|
|
@@ -52,11 +53,11 @@ function buildScrollResult(options) {
|
|
|
52
53
|
compatibilityWorkaround: options.compatibilityWorkaround,
|
|
53
54
|
data: options.result,
|
|
54
55
|
effectiveArgs: options.effectiveArgs,
|
|
55
|
-
nextActions: options.succeeded ? undefined : buildScrollNoopNextActions(options.sessionName),
|
|
56
|
+
nextActions: options.succeeded ? undefined : applyNamespaceToNextActions(buildScrollNoopNextActions(options.sessionName), options.namespace),
|
|
56
57
|
[options.scrollField]: options.scrollValue,
|
|
57
58
|
sessionMode: options.sessionMode,
|
|
58
59
|
...buildAgentBrowserResultCategoryDetails({ args: options.effectiveArgs, command: options.command, errorText: options.succeeded ? undefined : options.message, succeeded: options.succeeded, validationError: options.succeeded ? undefined : options.message }),
|
|
59
|
-
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession),
|
|
60
|
+
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession, options.namespace),
|
|
60
61
|
summary: options.message,
|
|
61
62
|
validationError: options.succeeded ? undefined : options.message,
|
|
62
63
|
},
|
|
@@ -67,7 +68,7 @@ export async function tryContainerScroll(options) {
|
|
|
67
68
|
const request = getContainerScrollRequest(options.commandTokens);
|
|
68
69
|
if (!request || !options.sessionName)
|
|
69
70
|
return undefined;
|
|
70
|
-
const data = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, stdin: buildContainerScrollScript(request) });
|
|
71
|
+
const data = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, stdin: buildContainerScrollScript(request) });
|
|
71
72
|
const result = isRecord(data) && isRecord(data.result) ? data.result : data;
|
|
72
73
|
if (!isRecord(result) || typeof result.status !== "string")
|
|
73
74
|
return undefined;
|
|
@@ -102,7 +103,7 @@ export async function tryPageScrollTo(options) {
|
|
|
102
103
|
const request = getPageScrollToRequest(options.commandTokens);
|
|
103
104
|
if (!request || !options.sessionName)
|
|
104
105
|
return undefined;
|
|
105
|
-
const data = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, sessionName: options.sessionName, signal: options.signal, stdin: buildPageScrollToScript(request) });
|
|
106
|
+
const data = await runSessionCommandData({ args: ["eval", "--stdin"], cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal, stdin: buildPageScrollToScript(request) });
|
|
106
107
|
const result = isRecord(data) && isRecord(data.result) ? data.result : data;
|
|
107
108
|
if (!isRecord(result) || typeof result.status !== "string")
|
|
108
109
|
return undefined;
|
package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js
CHANGED
|
@@ -109,15 +109,15 @@ export async function trySnapshotFilter(options) {
|
|
|
109
109
|
const request = parseSnapshotFilterRequest(options.commandTokens);
|
|
110
110
|
if (!request || !options.sessionName)
|
|
111
111
|
return undefined;
|
|
112
|
-
const snapshotData = await runSessionCommandData({ args: request.cleanArgs, cwd: options.cwd, sessionName: options.sessionName, signal: options.signal });
|
|
112
|
+
const snapshotData = await runSessionCommandData({ args: request.cleanArgs, cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal });
|
|
113
113
|
const filtered = request.role || request.search ? filterSnapshotData(snapshotData, request) : isRecord(snapshotData) ? { data: snapshotData, matchedRefs: isRecord(snapshotData.refs) ? Object.keys(snapshotData.refs).length : 0, totalLines: typeof snapshotData.snapshot === "string" ? snapshotData.snapshot.split(/\r?\n/).filter((line) => line.length > 0).length : 0, totalRefs: isRecord(snapshotData.refs) ? Object.keys(snapshotData.refs).length : 0, visibleLines: typeof snapshotData.snapshot === "string" ? snapshotData.snapshot.split(/\r?\n/).filter((line) => line.length > 0).length : 0 } : undefined;
|
|
114
114
|
if (!filtered)
|
|
115
115
|
return undefined;
|
|
116
|
-
const viewport = request.viewport ? await collectScrollPositionSnapshot({ cwd: options.cwd, sessionName: options.sessionName, signal: options.signal }) : undefined;
|
|
116
|
+
const viewport = request.viewport ? await collectScrollPositionSnapshot({ cwd: options.cwd, namespace: options.namespace, sessionName: options.sessionName, signal: options.signal }) : undefined;
|
|
117
117
|
const fullSnapshot = extractRefSnapshotFromData(snapshotData);
|
|
118
118
|
const diff = request.diff ? buildSnapshotDiff(options.previousRefSnapshot, fullSnapshot) : undefined;
|
|
119
119
|
if (fullSnapshot)
|
|
120
|
-
options.sessionPageState.applyRefSnapshot({ sessionName: options.sessionName, snapshot: fullSnapshot, update: options.sessionPageStateUpdate });
|
|
120
|
+
options.sessionPageState.applyRefSnapshot({ sessionName: options.sessionStateKey ?? options.sessionName, snapshot: fullSnapshot, update: options.sessionPageStateUpdate });
|
|
121
121
|
const presentation = await buildSnapshotPresentation(filtered.data, options.persistentArtifactStore, options.artifactManifest);
|
|
122
122
|
const summary = request.role || request.search
|
|
123
123
|
? `Snapshot filter: ${filtered.matchedRefs}/${filtered.totalRefs} direct refs matched${request.role ? ` role=${request.role}` : ""}${request.search ? ` search ${JSON.stringify(request.search)}` : ""}; ${filtered.visibleLines} surrounding snapshot line${filtered.visibleLines === 1 ? "" : "s"} shown.`
|
|
@@ -149,7 +149,7 @@ export async function trySnapshotFilter(options) {
|
|
|
149
149
|
snapshotFilter: request.role || request.search ? { cleanArgs: request.cleanArgs, matchedRefs: filtered.matchedRefs, role: request.role, search: request.search, totalLines: filtered.totalLines, totalRefs: filtered.totalRefs, visibleLines: filtered.visibleLines } : undefined,
|
|
150
150
|
snapshotViewport: viewport,
|
|
151
151
|
...buildAgentBrowserResultCategoryDetails({ args: options.effectiveArgs, command: "snapshot", succeeded: true }),
|
|
152
|
-
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession),
|
|
152
|
+
...buildSessionDetailFields(options.sessionName, options.usedImplicitSession, options.namespace),
|
|
153
153
|
summary,
|
|
154
154
|
},
|
|
155
155
|
isError: false,
|