pi-agent-browser-native 0.2.48 → 0.2.49
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 +17 -0
- package/README.md +16 -6
- package/dist/extensions/agent-browser/index.js +785 -0
- package/dist/extensions/agent-browser/lib/argv-descriptor.js +71 -0
- package/dist/extensions/agent-browser/lib/argv-grammar.js +121 -0
- package/dist/extensions/agent-browser/lib/bash-guard.js +190 -0
- package/dist/extensions/agent-browser/lib/command-policy.js +85 -0
- package/dist/extensions/agent-browser/lib/command-taxonomy.js +302 -0
- package/dist/extensions/agent-browser/lib/config-policy.js +686 -0
- package/dist/extensions/agent-browser/lib/config.js +122 -0
- package/dist/extensions/agent-browser/lib/electron/cdp.js +51 -0
- package/dist/extensions/agent-browser/lib/electron/cleanup.js +212 -0
- package/dist/extensions/agent-browser/lib/electron/discovery.js +633 -0
- package/dist/extensions/agent-browser/lib/electron/launch.js +351 -0
- package/{extensions/agent-browser/lib/electron/text.ts → dist/extensions/agent-browser/lib/electron/text.js} +5 -5
- package/dist/extensions/agent-browser/lib/executable-path.js +20 -0
- package/dist/extensions/agent-browser/lib/fs-utils.js +18 -0
- package/dist/extensions/agent-browser/lib/input-modes/electron.js +165 -0
- package/dist/extensions/agent-browser/lib/input-modes/job.js +519 -0
- package/dist/extensions/agent-browser/lib/input-modes/lookups.js +440 -0
- package/dist/extensions/agent-browser/lib/input-modes/params.js +164 -0
- package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +119 -0
- package/dist/extensions/agent-browser/lib/input-modes/shared.js +42 -0
- package/dist/extensions/agent-browser/lib/input-modes/types.js +21 -0
- package/dist/extensions/agent-browser/lib/input-modes.js +10 -0
- package/dist/extensions/agent-browser/lib/json-schema.js +58 -0
- package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +59 -0
- package/dist/extensions/agent-browser/lib/navigation-policy.js +83 -0
- package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +62 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +39 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +276 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +909 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +443 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +47 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.js +141 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +108 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +112 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +158 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +54 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +762 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +491 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +40 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-artifacts.js +5 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +731 -0
- package/dist/extensions/agent-browser/lib/orchestration/browser-run/types.js +1 -0
- package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +718 -0
- package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +247 -0
- package/dist/extensions/agent-browser/lib/orchestration/output-file.js +68 -0
- package/{extensions/agent-browser/lib/parsing.ts → dist/extensions/agent-browser/lib/parsing.js} +12 -11
- package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +241 -0
- package/dist/extensions/agent-browser/lib/playbook.js +121 -0
- package/dist/extensions/agent-browser/lib/process.js +448 -0
- package/dist/extensions/agent-browser/lib/prompt-policy.js +91 -0
- package/dist/extensions/agent-browser/lib/results/action-recommendations.js +220 -0
- package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +111 -0
- package/{extensions/agent-browser/lib/results/artifact-state.ts → dist/extensions/agent-browser/lib/results/artifact-state.js} +4 -8
- package/dist/extensions/agent-browser/lib/results/categories.js +76 -0
- package/dist/extensions/agent-browser/lib/results/confirmation.js +63 -0
- package/dist/extensions/agent-browser/lib/results/contracts.js +8 -0
- package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +74 -0
- package/dist/extensions/agent-browser/lib/results/envelope.js +166 -0
- package/dist/extensions/agent-browser/lib/results/network-routes.js +92 -0
- package/dist/extensions/agent-browser/lib/results/network.js +73 -0
- package/dist/extensions/agent-browser/lib/results/next-actions.js +72 -0
- package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +515 -0
- package/dist/extensions/agent-browser/lib/results/presentation/batch.js +397 -0
- package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +55 -0
- package/dist/extensions/agent-browser/lib/results/presentation/common.js +46 -0
- package/dist/extensions/agent-browser/lib/results/presentation/content.js +24 -0
- package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +960 -0
- package/dist/extensions/agent-browser/lib/results/presentation/errors.js +205 -0
- package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +134 -0
- package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +159 -0
- package/dist/extensions/agent-browser/lib/results/presentation/registry.js +216 -0
- package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +104 -0
- package/dist/extensions/agent-browser/lib/results/presentation/skills.js +152 -0
- package/dist/extensions/agent-browser/lib/results/presentation.js +177 -0
- package/dist/extensions/agent-browser/lib/results/recovery-actions.js +107 -0
- package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +50 -0
- package/dist/extensions/agent-browser/lib/results/selector-recovery.js +225 -0
- package/{extensions/agent-browser/lib/results/shared.ts → dist/extensions/agent-browser/lib/results/shared.js} +0 -1
- package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +208 -0
- package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +78 -0
- package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +331 -0
- package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +40 -0
- package/dist/extensions/agent-browser/lib/results/snapshot.js +264 -0
- package/dist/extensions/agent-browser/lib/results/text.js +40 -0
- package/{extensions/agent-browser/lib/results.ts → dist/extensions/agent-browser/lib/results.js} +2 -32
- package/dist/extensions/agent-browser/lib/runtime.js +816 -0
- package/dist/extensions/agent-browser/lib/session-page-state.js +411 -0
- package/dist/extensions/agent-browser/lib/string-enum-schema.js +13 -0
- package/dist/extensions/agent-browser/lib/temp.js +498 -0
- package/dist/extensions/agent-browser/lib/web-search.js +562 -0
- package/docs/RELEASE.md +22 -11
- package/docs/SUPPORT_MATRIX.md +4 -3
- package/package.json +9 -5
- package/scripts/config.mjs +8 -2
- package/scripts/doctor.mjs +8 -7
- package/extensions/agent-browser/index.ts +0 -961
- package/extensions/agent-browser/lib/argv-descriptor.ts +0 -90
- package/extensions/agent-browser/lib/argv-grammar.ts +0 -128
- package/extensions/agent-browser/lib/bash-guard.ts +0 -205
- package/extensions/agent-browser/lib/command-policy.ts +0 -71
- package/extensions/agent-browser/lib/command-taxonomy.ts +0 -336
- package/extensions/agent-browser/lib/config-policy.js +0 -690
- package/extensions/agent-browser/lib/config.ts +0 -211
- package/extensions/agent-browser/lib/electron/cdp.ts +0 -69
- package/extensions/agent-browser/lib/electron/cleanup.ts +0 -235
- package/extensions/agent-browser/lib/electron/discovery.ts +0 -710
- package/extensions/agent-browser/lib/electron/launch.ts +0 -499
- package/extensions/agent-browser/lib/executable-path.ts +0 -19
- package/extensions/agent-browser/lib/fs-utils.ts +0 -18
- package/extensions/agent-browser/lib/input-modes/electron.ts +0 -170
- package/extensions/agent-browser/lib/input-modes/job.ts +0 -527
- package/extensions/agent-browser/lib/input-modes/lookups.ts +0 -447
- package/extensions/agent-browser/lib/input-modes/params.ts +0 -205
- package/extensions/agent-browser/lib/input-modes/semantic-action.ts +0 -127
- package/extensions/agent-browser/lib/input-modes/shared.ts +0 -46
- package/extensions/agent-browser/lib/input-modes/types.ts +0 -225
- package/extensions/agent-browser/lib/input-modes.ts +0 -45
- package/extensions/agent-browser/lib/json-schema.ts +0 -73
- package/extensions/agent-browser/lib/launch-scoped-flags.ts +0 -67
- package/extensions/agent-browser/lib/navigation-policy.ts +0 -95
- package/extensions/agent-browser/lib/orchestration/batch-stdin.ts +0 -65
- package/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.ts +0 -44
- package/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.ts +0 -280
- package/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts +0 -914
- package/extensions/agent-browser/lib/orchestration/browser-run/final-result.ts +0 -521
- package/extensions/agent-browser/lib/orchestration/browser-run/index.ts +0 -53
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.ts +0 -158
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.ts +0 -116
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.ts +0 -147
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.ts +0 -183
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.ts +0 -58
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare.ts +0 -847
- package/extensions/agent-browser/lib/orchestration/browser-run/process-output.ts +0 -559
- package/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.ts +0 -47
- package/extensions/agent-browser/lib/orchestration/browser-run/session-artifacts.ts +0 -8
- package/extensions/agent-browser/lib/orchestration/browser-run/session-state.ts +0 -868
- package/extensions/agent-browser/lib/orchestration/browser-run/types.ts +0 -565
- package/extensions/agent-browser/lib/orchestration/electron-host/index.ts +0 -855
- package/extensions/agent-browser/lib/orchestration/input-plan.ts +0 -375
- package/extensions/agent-browser/lib/orchestration/output-file.ts +0 -86
- package/extensions/agent-browser/lib/pi-tool-rendering.ts +0 -267
- package/extensions/agent-browser/lib/playbook.ts +0 -142
- package/extensions/agent-browser/lib/process.ts +0 -516
- package/extensions/agent-browser/lib/prompt-policy.ts +0 -105
- package/extensions/agent-browser/lib/results/action-recommendations.ts +0 -264
- package/extensions/agent-browser/lib/results/artifact-manifest.ts +0 -111
- package/extensions/agent-browser/lib/results/categories.ts +0 -106
- package/extensions/agent-browser/lib/results/confirmation.ts +0 -76
- package/extensions/agent-browser/lib/results/contracts.ts +0 -241
- package/extensions/agent-browser/lib/results/editable-ref-evidence.ts +0 -72
- package/extensions/agent-browser/lib/results/envelope.ts +0 -195
- package/extensions/agent-browser/lib/results/network-routes.ts +0 -83
- package/extensions/agent-browser/lib/results/network.ts +0 -78
- package/extensions/agent-browser/lib/results/next-actions.ts +0 -117
- package/extensions/agent-browser/lib/results/presentation/artifacts.ts +0 -588
- package/extensions/agent-browser/lib/results/presentation/batch.ts +0 -450
- package/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.ts +0 -67
- package/extensions/agent-browser/lib/results/presentation/common.ts +0 -53
- package/extensions/agent-browser/lib/results/presentation/content.ts +0 -36
- package/extensions/agent-browser/lib/results/presentation/diagnostics.ts +0 -923
- package/extensions/agent-browser/lib/results/presentation/errors.ts +0 -227
- package/extensions/agent-browser/lib/results/presentation/large-output.ts +0 -182
- package/extensions/agent-browser/lib/results/presentation/navigation.ts +0 -184
- package/extensions/agent-browser/lib/results/presentation/registry.ts +0 -242
- package/extensions/agent-browser/lib/results/presentation/semantic-action.ts +0 -131
- package/extensions/agent-browser/lib/results/presentation/skills.ts +0 -143
- package/extensions/agent-browser/lib/results/presentation.ts +0 -257
- package/extensions/agent-browser/lib/results/recovery-actions.ts +0 -139
- package/extensions/agent-browser/lib/results/recovery-next-actions.ts +0 -71
- package/extensions/agent-browser/lib/results/selector-recovery.ts +0 -320
- package/extensions/agent-browser/lib/results/snapshot-high-value-controls.ts +0 -273
- package/extensions/agent-browser/lib/results/snapshot-refs.ts +0 -100
- package/extensions/agent-browser/lib/results/snapshot-segments.ts +0 -366
- package/extensions/agent-browser/lib/results/snapshot-spill.ts +0 -63
- package/extensions/agent-browser/lib/results/snapshot.ts +0 -329
- package/extensions/agent-browser/lib/results/text.ts +0 -40
- package/extensions/agent-browser/lib/runtime.ts +0 -988
- package/extensions/agent-browser/lib/session-page-state.ts +0 -512
- package/extensions/agent-browser/lib/string-enum-schema.ts +0 -20
- package/extensions/agent-browser/lib/temp.ts +0 -577
- package/extensions/agent-browser/lib/web-search.ts +0 -728
- /package/{extensions/agent-browser/lib/orchestration/browser-run.ts → dist/extensions/agent-browser/lib/orchestration/browser-run.js} +0 -0
|
@@ -1,366 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Purpose: Parse raw agent-browser snapshot text into previewable sections.
|
|
3
|
-
* Responsibilities: Identify signal lines, rank content segments, build structured previews, and provide raw-outline fallback previews.
|
|
4
|
-
* Scope: Snapshot text/section planning only; ref enrichment, high-value control ranking, spill files, and final presentation live elsewhere.
|
|
5
|
-
* Usage: Snapshot presentation uses this module before selecting displayed refs.
|
|
6
|
-
* Invariants/Assumptions: Parsing is best-effort and must stay resilient to upstream snapshot text format changes.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { SnapshotLineRefInfo, SnapshotRefEntry } from "./snapshot-refs.js";
|
|
10
|
-
import { normalizeWhitespace, truncateText } from "./text.js";
|
|
11
|
-
|
|
12
|
-
const SNAPSHOT_MAX_ADDITIONAL_SECTIONS = 2;
|
|
13
|
-
const SNAPSHOT_FALLBACK_PREVIEW_MAX_LINES = 12;
|
|
14
|
-
const SNAPSHOT_LINE_MAX_CHARS = 140;
|
|
15
|
-
|
|
16
|
-
const SNAPSHOT_SIGNAL_ROLES = new Set([
|
|
17
|
-
"article",
|
|
18
|
-
"banner",
|
|
19
|
-
"button",
|
|
20
|
-
"checkbox",
|
|
21
|
-
"combobox",
|
|
22
|
-
"dialog",
|
|
23
|
-
"gridcell",
|
|
24
|
-
"heading",
|
|
25
|
-
"link",
|
|
26
|
-
"listitem",
|
|
27
|
-
"main",
|
|
28
|
-
"menu",
|
|
29
|
-
"menuitem",
|
|
30
|
-
"navigation",
|
|
31
|
-
"option",
|
|
32
|
-
"radio",
|
|
33
|
-
"region",
|
|
34
|
-
"row",
|
|
35
|
-
"searchbox",
|
|
36
|
-
"tab",
|
|
37
|
-
"textbox",
|
|
38
|
-
]);
|
|
39
|
-
|
|
40
|
-
const SNAPSHOT_SEGMENT_ROOT_ROLES = new Set(["article", "dialog", "heading", "main", "menu", "region"]);
|
|
41
|
-
|
|
42
|
-
const SNAPSHOT_ROLE_PRIORITY: Record<string, number> = {
|
|
43
|
-
article: 0,
|
|
44
|
-
main: 1,
|
|
45
|
-
dialog: 2,
|
|
46
|
-
menu: 3,
|
|
47
|
-
region: 4,
|
|
48
|
-
heading: 5,
|
|
49
|
-
searchbox: 6,
|
|
50
|
-
textbox: 7,
|
|
51
|
-
combobox: 8,
|
|
52
|
-
button: 9,
|
|
53
|
-
checkbox: 10,
|
|
54
|
-
radio: 11,
|
|
55
|
-
tab: 12,
|
|
56
|
-
option: 13,
|
|
57
|
-
link: 14,
|
|
58
|
-
listitem: 14,
|
|
59
|
-
row: 15,
|
|
60
|
-
gridcell: 16,
|
|
61
|
-
navigation: 17,
|
|
62
|
-
generic: 99,
|
|
63
|
-
unknown: 100,
|
|
64
|
-
};
|
|
65
|
-
|
|
66
|
-
const SNAPSHOT_NOISE_NAME_PATTERNS = [
|
|
67
|
-
/^skip to /i,
|
|
68
|
-
/^ad$/i,
|
|
69
|
-
/^don't want to see ads\??$/i,
|
|
70
|
-
/keyboard shortcuts/i,
|
|
71
|
-
/\bpromoted\b/i,
|
|
72
|
-
/\bsponsored\b/i,
|
|
73
|
-
];
|
|
74
|
-
|
|
75
|
-
const SNAPSHOT_CHROME_SECTION_PATTERNS = [
|
|
76
|
-
/^primary$/i,
|
|
77
|
-
/^footer$/i,
|
|
78
|
-
/^navigation$/i,
|
|
79
|
-
/\bwhat['’]?s happening\b/i,
|
|
80
|
-
/\brelevant people\b/i,
|
|
81
|
-
/\btrending\b/i,
|
|
82
|
-
/\brelated\b/i,
|
|
83
|
-
/\brecommended\b/i,
|
|
84
|
-
/\bsuggested\b/i,
|
|
85
|
-
];
|
|
86
|
-
|
|
87
|
-
export interface SnapshotLine extends SnapshotLineRefInfo {
|
|
88
|
-
depth: number;
|
|
89
|
-
headingLevel?: number;
|
|
90
|
-
index: number;
|
|
91
|
-
name: string;
|
|
92
|
-
raw: string;
|
|
93
|
-
ref?: string;
|
|
94
|
-
role: string;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
export interface SnapshotSegment {
|
|
98
|
-
endIndexExclusive: number;
|
|
99
|
-
lines: SnapshotLine[];
|
|
100
|
-
root: SnapshotLine;
|
|
101
|
-
score: number;
|
|
102
|
-
startIndex: number;
|
|
103
|
-
}
|
|
104
|
-
|
|
105
|
-
export interface SnapshotPreview {
|
|
106
|
-
omittedCount: number;
|
|
107
|
-
refIds: string[];
|
|
108
|
-
lines: string[];
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
export function getSnapshotRolePriority(role: string): number {
|
|
112
|
-
return SNAPSHOT_ROLE_PRIORITY[role] ?? 50;
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
export function parseSnapshotLines(snapshot: string): SnapshotLine[] {
|
|
116
|
-
return snapshot
|
|
117
|
-
.split("\n")
|
|
118
|
-
.filter((line) => line.length > 0)
|
|
119
|
-
.map((raw, index) => {
|
|
120
|
-
const trimmed = raw.trimStart();
|
|
121
|
-
const depth = Math.floor(((raw.match(/^\s*/) ?? [""])[0].length ?? 0) / 2);
|
|
122
|
-
const role = trimmed.match(/^[-*]\s+([^\s"]+)/)?.[1] ?? "unknown";
|
|
123
|
-
const name = normalizeWhitespace(trimmed.match(/"([^"]*)"/)?.[1] ?? "");
|
|
124
|
-
const ref = trimmed.match(/\bref=([^,\]\s]+)/)?.[1];
|
|
125
|
-
const headingLevel = trimmed.match(/\blevel=(\d+)/)?.[1];
|
|
126
|
-
return {
|
|
127
|
-
depth,
|
|
128
|
-
headingLevel: headingLevel ? Number(headingLevel) : undefined,
|
|
129
|
-
index,
|
|
130
|
-
name,
|
|
131
|
-
raw,
|
|
132
|
-
ref,
|
|
133
|
-
role,
|
|
134
|
-
} satisfies SnapshotLine;
|
|
135
|
-
});
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
export function isNoiseName(name: string): boolean {
|
|
139
|
-
return SNAPSHOT_NOISE_NAME_PATTERNS.some((pattern) => pattern.test(name));
|
|
140
|
-
}
|
|
141
|
-
|
|
142
|
-
export function isChromeSectionName(name: string): boolean {
|
|
143
|
-
return SNAPSHOT_CHROME_SECTION_PATTERNS.some((pattern) => pattern.test(name));
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
function isNoiseSnapshotLine(line: SnapshotLine): boolean {
|
|
147
|
-
if (line.name.length > 0 && isNoiseName(line.name)) return true;
|
|
148
|
-
const loweredRaw = line.raw.toLowerCase();
|
|
149
|
-
return loweredRaw.includes("promoted") || loweredRaw.includes("sponsored");
|
|
150
|
-
}
|
|
151
|
-
|
|
152
|
-
function isPotentialSegmentRootLine(line: SnapshotLine): boolean {
|
|
153
|
-
if (!SNAPSHOT_SEGMENT_ROOT_ROLES.has(line.role)) return false;
|
|
154
|
-
if (isNoiseSnapshotLine(line)) return false;
|
|
155
|
-
if (line.role === "heading") {
|
|
156
|
-
return line.name.length > 0 && (line.headingLevel ?? 99) <= 3;
|
|
157
|
-
}
|
|
158
|
-
if (line.role === "region") {
|
|
159
|
-
return line.name.length > 0;
|
|
160
|
-
}
|
|
161
|
-
return true;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
function scoreSegment(segment: SnapshotSegment): number {
|
|
165
|
-
const { root } = segment;
|
|
166
|
-
const distinctRefs = new Set(segment.lines.flatMap((line) => (line.ref ? [line.ref] : []))).size;
|
|
167
|
-
let score = 0;
|
|
168
|
-
|
|
169
|
-
score += 120 - getSnapshotRolePriority(root.role) * 8;
|
|
170
|
-
score += Math.min(distinctRefs, 16);
|
|
171
|
-
score += Math.min(segment.lines.length, 12);
|
|
172
|
-
score -= Math.min(root.index, 60) / 3;
|
|
173
|
-
score -= root.depth * 6;
|
|
174
|
-
|
|
175
|
-
if (root.role === "heading") {
|
|
176
|
-
if (root.headingLevel === 1) score += 40;
|
|
177
|
-
else if (root.headingLevel === 2) score += 22;
|
|
178
|
-
else if (root.headingLevel === 3) score += 12;
|
|
179
|
-
}
|
|
180
|
-
if (root.name.length > 0) score += 10;
|
|
181
|
-
if (root.name.length <= 2) score -= 18;
|
|
182
|
-
if (isChromeSectionName(root.name)) score -= 45;
|
|
183
|
-
if (isNoiseName(root.name)) score -= 1000;
|
|
184
|
-
return score;
|
|
185
|
-
}
|
|
186
|
-
|
|
187
|
-
export function buildSnapshotSegments(snapshotLines: SnapshotLine[]): SnapshotSegment[] {
|
|
188
|
-
const roots: SnapshotLine[] = [];
|
|
189
|
-
const stack: SnapshotLine[] = [];
|
|
190
|
-
|
|
191
|
-
for (const line of snapshotLines) {
|
|
192
|
-
stack.length = line.depth;
|
|
193
|
-
if (isPotentialSegmentRootLine(line)) {
|
|
194
|
-
const normalizedName = normalizeWhitespace(line.name.toLowerCase());
|
|
195
|
-
let duplicateAncestor: SnapshotLine | undefined;
|
|
196
|
-
for (let index = stack.length - 1; index >= 0; index -= 1) {
|
|
197
|
-
const ancestor = stack[index];
|
|
198
|
-
if (
|
|
199
|
-
normalizedName.length > 0 &&
|
|
200
|
-
normalizeWhitespace(ancestor.name.toLowerCase()) === normalizedName &&
|
|
201
|
-
SNAPSHOT_SEGMENT_ROOT_ROLES.has(ancestor.role)
|
|
202
|
-
) {
|
|
203
|
-
duplicateAncestor = ancestor;
|
|
204
|
-
break;
|
|
205
|
-
}
|
|
206
|
-
}
|
|
207
|
-
if (!duplicateAncestor) {
|
|
208
|
-
roots.push(line);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
stack[line.depth] = line;
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
return roots.map((root, index) => {
|
|
215
|
-
let endIndexExclusive = snapshotLines.length;
|
|
216
|
-
for (let nextIndex = index + 1; nextIndex < roots.length; nextIndex += 1) {
|
|
217
|
-
const candidate = roots[nextIndex];
|
|
218
|
-
if (candidate.depth <= root.depth) {
|
|
219
|
-
endIndexExclusive = candidate.index;
|
|
220
|
-
break;
|
|
221
|
-
}
|
|
222
|
-
}
|
|
223
|
-
const lines = snapshotLines.slice(root.index, endIndexExclusive);
|
|
224
|
-
const segment: SnapshotSegment = {
|
|
225
|
-
endIndexExclusive,
|
|
226
|
-
lines,
|
|
227
|
-
root,
|
|
228
|
-
score: 0,
|
|
229
|
-
startIndex: root.index,
|
|
230
|
-
};
|
|
231
|
-
segment.score = scoreSegment(segment);
|
|
232
|
-
return segment;
|
|
233
|
-
});
|
|
234
|
-
}
|
|
235
|
-
|
|
236
|
-
export function choosePrimarySegment(segments: SnapshotSegment[]): SnapshotSegment | undefined {
|
|
237
|
-
if (segments.length === 0) return undefined;
|
|
238
|
-
return (
|
|
239
|
-
segments.find((segment) => segment.root.role === "main" || segment.root.role === "article") ??
|
|
240
|
-
segments.find((segment) => segment.root.role === "heading" && segment.root.headingLevel === 1) ??
|
|
241
|
-
segments.find((segment) => segment.score >= 90) ??
|
|
242
|
-
[...segments].sort((left, right) => right.score - left.score || left.startIndex - right.startIndex)[0]
|
|
243
|
-
);
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
export function chooseAdditionalSegments(segments: SnapshotSegment[], primary: SnapshotSegment | undefined): SnapshotSegment[] {
|
|
247
|
-
if (!primary) return [];
|
|
248
|
-
|
|
249
|
-
const seenNames = new Set<string>([normalizeWhitespace(primary.root.name.toLowerCase())]);
|
|
250
|
-
const rankedCandidates = segments
|
|
251
|
-
.filter((segment) => segment !== primary && segment.score >= 45)
|
|
252
|
-
.sort((left, right) => {
|
|
253
|
-
const leftDistance = Math.abs(left.startIndex - primary.startIndex);
|
|
254
|
-
const rightDistance = Math.abs(right.startIndex - primary.startIndex);
|
|
255
|
-
if (leftDistance !== rightDistance) return leftDistance - rightDistance;
|
|
256
|
-
if (right.score !== left.score) return right.score - left.score;
|
|
257
|
-
return left.startIndex - right.startIndex;
|
|
258
|
-
});
|
|
259
|
-
|
|
260
|
-
const chosen: SnapshotSegment[] = [];
|
|
261
|
-
for (const segment of rankedCandidates) {
|
|
262
|
-
if (chosen.length >= SNAPSHOT_MAX_ADDITIONAL_SECTIONS) break;
|
|
263
|
-
if (isChromeSectionName(segment.root.name)) continue;
|
|
264
|
-
if (segment.root.role === "heading" && segment.root.name.length <= 2) continue;
|
|
265
|
-
const nameKey = normalizeWhitespace(segment.root.name.toLowerCase());
|
|
266
|
-
if (nameKey && seenNames.has(nameKey)) continue;
|
|
267
|
-
chosen.push(segment);
|
|
268
|
-
if (nameKey) seenNames.add(nameKey);
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
return chosen.sort((left, right) => left.startIndex - right.startIndex);
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
export function getMeaningfulSegmentLines(segment: SnapshotSegment): SnapshotLine[] {
|
|
275
|
-
return segment.lines.filter((line) => {
|
|
276
|
-
if (isNoiseSnapshotLine(line)) return false;
|
|
277
|
-
if (line.role === "generic" && !line.ref && line.name.length === 0) return false;
|
|
278
|
-
if (line.role === "link" && line.name.length === 0) return false;
|
|
279
|
-
return true;
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
|
|
283
|
-
function formatPreviewLine(line: SnapshotLine, baseDepth: number): string {
|
|
284
|
-
const leadingWhitespace = (line.raw.match(/^\s*/) ?? [""])[0].length;
|
|
285
|
-
const stripChars = Math.min(leadingWhitespace, Math.max(0, baseDepth) * 2);
|
|
286
|
-
return truncateText(line.raw.slice(stripChars), SNAPSHOT_LINE_MAX_CHARS);
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
export function buildSegmentPreview(segment: SnapshotSegment, maxLines: number): SnapshotPreview {
|
|
290
|
-
const meaningfulLines = getMeaningfulSegmentLines(segment);
|
|
291
|
-
if (meaningfulLines.length === 0) {
|
|
292
|
-
return { omittedCount: 0, refIds: [], lines: [] };
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const previewLines: SnapshotLine[] = [];
|
|
296
|
-
const previewRefIds = new Set<string>();
|
|
297
|
-
const seenPreviewKeys = new Set<string>();
|
|
298
|
-
const rootDepth = segment.root.depth;
|
|
299
|
-
|
|
300
|
-
for (const line of meaningfulLines) {
|
|
301
|
-
if (previewLines.length >= maxLines) break;
|
|
302
|
-
if (line !== segment.root) {
|
|
303
|
-
const relativeDepth = line.depth - rootDepth;
|
|
304
|
-
if (segment.root.role !== "heading" && relativeDepth > 2) continue;
|
|
305
|
-
if (segment.root.name.length > 0 && line.name === segment.root.name && (line.role === "heading" || line.role === "link")) {
|
|
306
|
-
continue;
|
|
307
|
-
}
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
const key = `${line.role}:${line.name}:${line.ref ?? ""}:${line.depth}`;
|
|
311
|
-
if (seenPreviewKeys.has(key)) continue;
|
|
312
|
-
seenPreviewKeys.add(key);
|
|
313
|
-
previewLines.push(line);
|
|
314
|
-
if (line.ref) previewRefIds.add(line.ref);
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
return {
|
|
318
|
-
omittedCount: Math.max(0, meaningfulLines.length - previewLines.length),
|
|
319
|
-
refIds: [...previewRefIds],
|
|
320
|
-
lines: previewLines.map((line) => formatPreviewLine(line, rootDepth)),
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
|
|
324
|
-
export function buildFallbackSnapshotOutline(snapshotLines: SnapshotLine[]): SnapshotPreview {
|
|
325
|
-
const selected = new Set<number>();
|
|
326
|
-
for (let index = 0; index < snapshotLines.length && selected.size < 4; index += 1) {
|
|
327
|
-
if (!isNoiseSnapshotLine(snapshotLines[index])) selected.add(index);
|
|
328
|
-
}
|
|
329
|
-
for (let index = 0; index < snapshotLines.length && selected.size < SNAPSHOT_FALLBACK_PREVIEW_MAX_LINES; index += 1) {
|
|
330
|
-
const line = snapshotLines[index];
|
|
331
|
-
if (isNoiseSnapshotLine(line)) continue;
|
|
332
|
-
if (SNAPSHOT_SIGNAL_ROLES.has(line.role) || line.ref || line.name.length > 0) {
|
|
333
|
-
selected.add(index);
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
const chosenLines = [...selected]
|
|
337
|
-
.sort((left, right) => left - right)
|
|
338
|
-
.slice(0, SNAPSHOT_FALLBACK_PREVIEW_MAX_LINES)
|
|
339
|
-
.map((index) => snapshotLines[index]);
|
|
340
|
-
return {
|
|
341
|
-
omittedCount: Math.max(0, snapshotLines.length - chosenLines.length),
|
|
342
|
-
refIds: chosenLines.flatMap((line) => (line.ref ? [line.ref] : [])),
|
|
343
|
-
lines: chosenLines.map((line) => truncateText(line.raw, SNAPSHOT_LINE_MAX_CHARS)),
|
|
344
|
-
};
|
|
345
|
-
}
|
|
346
|
-
|
|
347
|
-
export function buildRefLineOrderMap(snapshotLines: SnapshotLine[]): Map<string, number> {
|
|
348
|
-
const map = new Map<string, number>();
|
|
349
|
-
for (const line of snapshotLines) {
|
|
350
|
-
if (!line.ref || map.has(line.ref)) continue;
|
|
351
|
-
map.set(line.ref, line.index);
|
|
352
|
-
}
|
|
353
|
-
return map;
|
|
354
|
-
}
|
|
355
|
-
|
|
356
|
-
export function canUseStructuredSnapshotPreview(snapshotLines: SnapshotLine[], refEntries: SnapshotRefEntry[]): boolean {
|
|
357
|
-
if (snapshotLines.length === 0) return false;
|
|
358
|
-
const linesWithRecognizedRoles = snapshotLines.filter((line) => line.role !== "unknown").length;
|
|
359
|
-
const linesWithNames = snapshotLines.filter((line) => line.name.length > 0).length;
|
|
360
|
-
const parsedRefIds = new Set(snapshotLines.flatMap((line) => (line.ref ? [line.ref] : [])));
|
|
361
|
-
return (
|
|
362
|
-
linesWithRecognizedRoles >= Math.min(snapshotLines.length, 3) ||
|
|
363
|
-
linesWithNames >= Math.min(snapshotLines.length, 3) ||
|
|
364
|
-
parsedRefIds.size >= Math.min(refEntries.length, 3)
|
|
365
|
-
);
|
|
366
|
-
}
|
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Purpose: Persist full compacted snapshot payloads when model-facing output is shortened.
|
|
3
|
-
* Responsibilities: Write persistent or secure-temp snapshot spill files and merge spill retention metadata into the session artifact manifest.
|
|
4
|
-
* Scope: Snapshot spill artifact lifecycle only; preview planning and presentation text live in snapshot.ts and sibling modules.
|
|
5
|
-
* Usage: Snapshot presentation calls these helpers after deciding a snapshot is too large for inline output.
|
|
6
|
-
* Invariants/Assumptions: Explicit full-output paths are reported but not deleted here; retention state mirrors the backing storage scope.
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
import type { PersistentSessionArtifactEviction, PersistentSessionArtifactStore } from "../temp.js";
|
|
10
|
-
import { writePersistentSessionArtifactFile, writeSecureTempFile } from "../temp.js";
|
|
11
|
-
import {
|
|
12
|
-
buildEvictedSessionArtifactEntries,
|
|
13
|
-
formatSessionArtifactRetentionSummary,
|
|
14
|
-
mergeSessionArtifactManifest,
|
|
15
|
-
} from "./artifact-manifest.js";
|
|
16
|
-
import type { SessionArtifactManifest, SessionArtifactManifestEntry } from "./contracts.js";
|
|
17
|
-
|
|
18
|
-
const SNAPSHOT_SPILL_FILE_PREFIX = "pi-agent-browser-snapshot";
|
|
19
|
-
|
|
20
|
-
export interface SnapshotSpillWriteResult {
|
|
21
|
-
evictedArtifacts: PersistentSessionArtifactEviction[];
|
|
22
|
-
path: string;
|
|
23
|
-
storageScope: "persistent-session" | "process-temp";
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
export async function writeSnapshotSpillFile(
|
|
27
|
-
data: Record<string, unknown>,
|
|
28
|
-
persistentArtifactStore: PersistentSessionArtifactStore | undefined,
|
|
29
|
-
): Promise<SnapshotSpillWriteResult> {
|
|
30
|
-
const options = {
|
|
31
|
-
content: JSON.stringify(data, null, 2),
|
|
32
|
-
prefix: SNAPSHOT_SPILL_FILE_PREFIX,
|
|
33
|
-
suffix: ".json",
|
|
34
|
-
};
|
|
35
|
-
if (persistentArtifactStore) {
|
|
36
|
-
const result = await writePersistentSessionArtifactFile({ ...options, store: persistentArtifactStore });
|
|
37
|
-
return { ...result, storageScope: "persistent-session" };
|
|
38
|
-
}
|
|
39
|
-
return { evictedArtifacts: [], path: await writeSecureTempFile(options), storageScope: "process-temp" };
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
export function applySnapshotArtifactManifest(options: {
|
|
43
|
-
baseManifest?: SessionArtifactManifest;
|
|
44
|
-
command?: string;
|
|
45
|
-
fullOutputPath?: string;
|
|
46
|
-
spill?: SnapshotSpillWriteResult;
|
|
47
|
-
}): { artifactManifest?: SessionArtifactManifest; artifactRetentionSummary?: string } {
|
|
48
|
-
if (!options.fullOutputPath || !options.spill) return {};
|
|
49
|
-
const nowMs = Date.now();
|
|
50
|
-
const entries: SessionArtifactManifestEntry[] = [
|
|
51
|
-
{
|
|
52
|
-
command: options.command,
|
|
53
|
-
createdAtMs: nowMs,
|
|
54
|
-
kind: "spill",
|
|
55
|
-
path: options.fullOutputPath,
|
|
56
|
-
retentionState: options.spill.storageScope === "persistent-session" ? "live" : "ephemeral",
|
|
57
|
-
storageScope: options.spill.storageScope,
|
|
58
|
-
},
|
|
59
|
-
...buildEvictedSessionArtifactEntries(options.spill.evictedArtifacts, nowMs),
|
|
60
|
-
];
|
|
61
|
-
const artifactManifest = mergeSessionArtifactManifest({ base: options.baseManifest, entries, nowMs });
|
|
62
|
-
return artifactManifest ? { artifactManifest, artifactRetentionSummary: formatSessionArtifactRetentionSummary(artifactManifest) } : {};
|
|
63
|
-
}
|