pi-agent-browser-native 0.2.47 → 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 +63 -19
- package/README.md +52 -19
- 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/ARCHITECTURE.md +10 -10
- package/docs/COMMAND_REFERENCE.md +35 -21
- package/docs/ELECTRON.md +3 -3
- package/docs/RELEASE.md +46 -26
- package/docs/REQUIREMENTS.md +1 -1
- package/docs/SUPPORT_MATRIX.md +35 -106
- package/docs/TOOL_CONTRACT.md +23 -21
- package/package.json +12 -8
- package/scripts/agent-browser-capability-baseline.mjs +6 -3
- package/scripts/config.mjs +8 -2
- package/scripts/doctor.mjs +19 -17
- package/scripts/platform-smoke.mjs +1 -1
- package/extensions/agent-browser/index.ts +0 -952
- 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 -209
- 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 -451
- 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/click-dispatch.ts +0 -257
- package/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts +0 -912
- package/extensions/agent-browser/lib/orchestration/browser-run/final-result.ts +0 -512
- package/extensions/agent-browser/lib/orchestration/browser-run/index.ts +0 -53
- package/extensions/agent-browser/lib/orchestration/browser-run/prepare.ts +0 -1481
- package/extensions/agent-browser/lib/orchestration/browser-run/process-output.ts +0 -564
- package/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.ts +0 -47
- package/extensions/agent-browser/lib/orchestration/browser-run/session-state.ts +0 -868
- package/extensions/agent-browser/lib/orchestration/browser-run/types.ts +0 -564
- 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 -252
- 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 -721
- /package/{extensions/agent-browser/lib/orchestration/browser-run.ts → dist/extensions/agent-browser/lib/orchestration/browser-run.js} +0 -0
|
@@ -1,242 +0,0 @@
|
|
|
1
|
-
import type { CompiledAgentBrowserSemanticAction } from "../../input-modes/types.js";
|
|
2
|
-
import { isRecord } from "../../parsing.js";
|
|
3
|
-
import type { CommandInfo } from "../../runtime.js";
|
|
4
|
-
import { detectConfirmationRequired, type ConfirmationRequiredPresentation } from "../confirmation.js";
|
|
5
|
-
import { formatRawSnapshotText, formatSnapshotSummary } from "../snapshot.js";
|
|
6
|
-
import { redactModelFacingText, stringifyModelFacing } from "./common.js";
|
|
7
|
-
import { formatDiagnosticSummary, formatDiagnosticText, formatProfilesText, getStreamSummary, getTabSummary } from "./diagnostics.js";
|
|
8
|
-
import { getScreenshotSummary } from "./artifacts.js";
|
|
9
|
-
import { formatSkillsText } from "./skills.js";
|
|
10
|
-
import {
|
|
11
|
-
formatExtractionSummary,
|
|
12
|
-
formatExtractionText,
|
|
13
|
-
formatNavigationActionResult,
|
|
14
|
-
formatNavigationSummary,
|
|
15
|
-
getNavigationSummary,
|
|
16
|
-
isNavigationObservableCommand,
|
|
17
|
-
} from "./navigation.js";
|
|
18
|
-
import {
|
|
19
|
-
formatSemanticActionPresentationSummary,
|
|
20
|
-
formatSemanticActionPresentationText,
|
|
21
|
-
resolvePresentationCommandInfo,
|
|
22
|
-
} from "./semantic-action.js";
|
|
23
|
-
|
|
24
|
-
function getPageSummary(data: Record<string, unknown>): string | undefined {
|
|
25
|
-
const title = typeof data.title === "string" ? data.title : undefined;
|
|
26
|
-
const url = typeof data.url === "string" ? data.url : undefined;
|
|
27
|
-
if (!title && !url) return undefined;
|
|
28
|
-
if (title && url) return `${title}\n${url}`;
|
|
29
|
-
return title ?? url;
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function formatConfirmationRequiredSummary(confirmation: ConfirmationRequiredPresentation): string {
|
|
33
|
-
return `Confirmation required: ${confirmation.id}`;
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
const VITALS_METRICS = ["lcp", "fcp", "ttfb", "inp", "cls"] as const;
|
|
37
|
-
|
|
38
|
-
function coerceVitalsMetricValue(value: unknown): number | undefined {
|
|
39
|
-
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
40
|
-
if (isRecord(value)) {
|
|
41
|
-
for (const nestedKey of ["value", "duration", "startTime", "score"] as const) {
|
|
42
|
-
const nestedValue = value[nestedKey];
|
|
43
|
-
if (typeof nestedValue === "number" && Number.isFinite(nestedValue)) return nestedValue;
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
return undefined;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
function getVitalsMetric(data: Record<string, unknown>, key: string): number | undefined {
|
|
50
|
-
const metrics = isRecord(data.metrics) ? data.metrics : undefined;
|
|
51
|
-
return coerceVitalsMetricValue(data[key] ?? data[key.toUpperCase()] ?? metrics?.[key] ?? metrics?.[key.toUpperCase()]);
|
|
52
|
-
}
|
|
53
|
-
|
|
54
|
-
function formatVitalsMetric(key: string, value: number): string {
|
|
55
|
-
return key === "cls" ? `${key.toUpperCase()}: ${value}` : `${key.toUpperCase()}: ${Math.round(value)}ms`;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
function getVitalsMetrics(data: Record<string, unknown>): string[] {
|
|
59
|
-
return VITALS_METRICS.flatMap((key) => {
|
|
60
|
-
const value = getVitalsMetric(data, key);
|
|
61
|
-
return value === undefined ? [] : [formatVitalsMetric(key, value)];
|
|
62
|
-
});
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
function getVitalsUnavailableReason(data: Record<string, unknown>): string {
|
|
66
|
-
for (const key of ["reason", "message", "error", "status"] as const) {
|
|
67
|
-
const value = data[key];
|
|
68
|
-
if (typeof value === "string" && value.trim().length > 0) return redactModelFacingText(value.trim());
|
|
69
|
-
}
|
|
70
|
-
return "No Core Web Vitals metric fields were present in the upstream result.";
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function formatVitalsText(data: Record<string, unknown>): string {
|
|
74
|
-
const url = typeof data.url === "string" && data.url.trim().length > 0 ? redactModelFacingText(data.url.trim()) : undefined;
|
|
75
|
-
const metrics = getVitalsMetrics(data);
|
|
76
|
-
const lines = [url ? `Vitals for ${url}` : "Vitals result"];
|
|
77
|
-
if (metrics.length > 0) lines.push(...metrics.map((metric) => `- ${metric}`));
|
|
78
|
-
else lines.push(`Metrics unavailable: ${getVitalsUnavailableReason(data)}`);
|
|
79
|
-
return lines.join("\n");
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
function formatVitalsSummary(data: Record<string, unknown>): string | undefined {
|
|
83
|
-
const metrics = getVitalsMetrics(data);
|
|
84
|
-
if (metrics.length > 0) return `Vitals: ${metrics.join(", ")}`;
|
|
85
|
-
return "Vitals: metrics unavailable";
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
function formatConfirmationRequiredText(confirmation: ConfirmationRequiredPresentation): string {
|
|
89
|
-
const lines = [
|
|
90
|
-
"Confirmation required.",
|
|
91
|
-
`Pending confirmation id: ${confirmation.id}`,
|
|
92
|
-
];
|
|
93
|
-
if (confirmation.actionText) lines.push(`Action: ${confirmation.actionText}`);
|
|
94
|
-
lines.push(
|
|
95
|
-
"",
|
|
96
|
-
"Next steps:",
|
|
97
|
-
`- Approve: { "args": ["confirm", "${confirmation.id}"] }`,
|
|
98
|
-
`- Deny: { "args": ["deny", "${confirmation.id}"] }`,
|
|
99
|
-
);
|
|
100
|
-
return lines.join("\n");
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
interface CommandPresenter {
|
|
104
|
-
summary?: (commandInfo: CommandInfo, data: unknown) => string | undefined;
|
|
105
|
-
text?: (commandInfo: CommandInfo, data: unknown) => string | undefined;
|
|
106
|
-
}
|
|
107
|
-
|
|
108
|
-
const COMMAND_PRESENTERS: Record<string, CommandPresenter> = {
|
|
109
|
-
profiles: {
|
|
110
|
-
summary: (_commandInfo, data) => Array.isArray(data) ? `Chrome profiles: ${data.length}` : undefined,
|
|
111
|
-
text: (_commandInfo, data) => Array.isArray(data) ? formatProfilesText(data, "Chrome profiles") : undefined,
|
|
112
|
-
},
|
|
113
|
-
screenshot: {
|
|
114
|
-
summary: (_commandInfo, data) => isRecord(data) && typeof data.path === "string" ? `Screenshot saved: ${data.path}` : undefined,
|
|
115
|
-
text: (_commandInfo, data) => isRecord(data) ? getScreenshotSummary(data) : undefined,
|
|
116
|
-
},
|
|
117
|
-
skills: {
|
|
118
|
-
summary: (commandInfo, data) => {
|
|
119
|
-
if (Array.isArray(data) && commandInfo.subcommand === "list") return `agent-browser skills: ${data.length}`;
|
|
120
|
-
if (commandInfo.subcommand === "get") return "agent-browser skill loaded";
|
|
121
|
-
if (commandInfo.subcommand === "path") return "agent-browser skill path";
|
|
122
|
-
return undefined;
|
|
123
|
-
},
|
|
124
|
-
text: formatSkillsText,
|
|
125
|
-
},
|
|
126
|
-
snapshot: {
|
|
127
|
-
summary: (_commandInfo, data) => isRecord(data) ? formatSnapshotSummary(data) : undefined,
|
|
128
|
-
text: (_commandInfo, data) => isRecord(data) ? formatRawSnapshotText(data) : undefined,
|
|
129
|
-
},
|
|
130
|
-
stream: {
|
|
131
|
-
summary: (commandInfo, data) => {
|
|
132
|
-
if (!isRecord(data) || commandInfo.subcommand !== "status") return undefined;
|
|
133
|
-
const port = typeof data.port === "number" ? ` on port ${data.port}` : "";
|
|
134
|
-
return `Stream ${data.enabled === true ? "enabled" : "disabled"}${port}`;
|
|
135
|
-
},
|
|
136
|
-
text: (commandInfo, data) => isRecord(data) && commandInfo.subcommand === "status" ? getStreamSummary(data) : undefined,
|
|
137
|
-
},
|
|
138
|
-
tab: {
|
|
139
|
-
summary: (_commandInfo, data) => isRecord(data) && Array.isArray(data.tabs) ? `Tabs: ${data.tabs.length}` : undefined,
|
|
140
|
-
text: (_commandInfo, data) => isRecord(data) ? getTabSummary(data) : undefined,
|
|
141
|
-
},
|
|
142
|
-
vitals: {
|
|
143
|
-
summary: (_commandInfo, data) => isRecord(data) ? formatVitalsSummary(data) : undefined,
|
|
144
|
-
text: (_commandInfo, data) => isRecord(data) ? formatVitalsText(data) : undefined,
|
|
145
|
-
},
|
|
146
|
-
"web-vitals": {
|
|
147
|
-
summary: (_commandInfo, data) => isRecord(data) ? formatVitalsSummary(data) : undefined,
|
|
148
|
-
text: (_commandInfo, data) => isRecord(data) ? formatVitalsText(data) : undefined,
|
|
149
|
-
},
|
|
150
|
-
};
|
|
151
|
-
|
|
152
|
-
function formatBatchSummary(data: unknown): string | undefined {
|
|
153
|
-
if (!Array.isArray(data)) return undefined;
|
|
154
|
-
const successCount = data.filter((item) => isRecord(item) && item.success !== false).length;
|
|
155
|
-
return successCount === data.length
|
|
156
|
-
? `Batch: ${successCount}/${data.length} succeeded`
|
|
157
|
-
: `Batch failed: ${successCount}/${data.length} succeeded`;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
export function formatPresentationSummary(
|
|
161
|
-
commandInfo: CommandInfo,
|
|
162
|
-
data: unknown,
|
|
163
|
-
compiledSemanticAction?: CompiledAgentBrowserSemanticAction,
|
|
164
|
-
): string {
|
|
165
|
-
const confirmationRequired = detectConfirmationRequired(data);
|
|
166
|
-
if (confirmationRequired) return formatConfirmationRequiredSummary(confirmationRequired);
|
|
167
|
-
|
|
168
|
-
const presentationCommandInfo = resolvePresentationCommandInfo(commandInfo, compiledSemanticAction);
|
|
169
|
-
|
|
170
|
-
if (commandInfo.command === "batch") {
|
|
171
|
-
const batchSummary = formatBatchSummary(data);
|
|
172
|
-
if (batchSummary) return batchSummary;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
if (isRecord(data)) {
|
|
176
|
-
if (compiledSemanticAction) {
|
|
177
|
-
const semanticSummary = formatSemanticActionPresentationSummary(compiledSemanticAction, data);
|
|
178
|
-
if (semanticSummary) return semanticSummary;
|
|
179
|
-
}
|
|
180
|
-
const navigationSummary = getNavigationSummary(data);
|
|
181
|
-
if (navigationSummary && isNavigationObservableCommand(presentationCommandInfo.command)) {
|
|
182
|
-
const navigationText = formatNavigationSummary(navigationSummary);
|
|
183
|
-
if (navigationText) {
|
|
184
|
-
return `${presentationCommandInfo.command ?? "navigation"} → ${navigationText.split("\n", 1)[0] ?? navigationText}`;
|
|
185
|
-
}
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
|
|
189
|
-
const presenterSummary = commandInfo.command ? COMMAND_PRESENTERS[commandInfo.command]?.summary?.(commandInfo, data) : undefined;
|
|
190
|
-
if (presenterSummary) return presenterSummary;
|
|
191
|
-
|
|
192
|
-
if (isRecord(data)) {
|
|
193
|
-
const diagnosticSummary = formatDiagnosticSummary(commandInfo, data);
|
|
194
|
-
if (diagnosticSummary) return diagnosticSummary;
|
|
195
|
-
const extractionSummary = formatExtractionSummary(commandInfo, data);
|
|
196
|
-
if (extractionSummary) return extractionSummary;
|
|
197
|
-
const pageSummary = getPageSummary(data);
|
|
198
|
-
if (pageSummary) return pageSummary.split("\n", 1)[0] ?? "agent-browser result";
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
if (typeof data === "string" && data.length > 0) return data.split("\n", 1)[0] ?? data;
|
|
202
|
-
return `${presentationCommandInfo.command ?? commandInfo.command ?? "agent-browser"} completed`;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
export function formatPresentationContentText(
|
|
206
|
-
commandInfo: CommandInfo,
|
|
207
|
-
data: unknown,
|
|
208
|
-
compiledSemanticAction?: CompiledAgentBrowserSemanticAction,
|
|
209
|
-
): string {
|
|
210
|
-
const confirmationRequired = detectConfirmationRequired(data);
|
|
211
|
-
if (confirmationRequired) return formatConfirmationRequiredText(confirmationRequired);
|
|
212
|
-
|
|
213
|
-
const presenterText = commandInfo.command ? COMMAND_PRESENTERS[commandInfo.command]?.text?.(commandInfo, data) : undefined;
|
|
214
|
-
if (presenterText) return presenterText;
|
|
215
|
-
|
|
216
|
-
if (typeof data === "string") return redactModelFacingText(data);
|
|
217
|
-
if (typeof data === "number" || typeof data === "boolean") return String(data);
|
|
218
|
-
if (!isRecord(data)) return stringifyModelFacing(data);
|
|
219
|
-
|
|
220
|
-
if (compiledSemanticAction) {
|
|
221
|
-
const semanticText = formatSemanticActionPresentationText(compiledSemanticAction, data);
|
|
222
|
-
if (semanticText) return semanticText;
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
const presentationCommandInfo = resolvePresentationCommandInfo(commandInfo, compiledSemanticAction);
|
|
226
|
-
const navigationSummary = getNavigationSummary(data);
|
|
227
|
-
if (navigationSummary && isNavigationObservableCommand(presentationCommandInfo.command)) {
|
|
228
|
-
const navigationText = formatNavigationSummary(navigationSummary);
|
|
229
|
-
if (navigationText) {
|
|
230
|
-
const actionText = formatNavigationActionResult(data);
|
|
231
|
-
return actionText ? `${actionText}\n\nCurrent page:\n${navigationText}` : `Current page:\n${navigationText}`;
|
|
232
|
-
}
|
|
233
|
-
}
|
|
234
|
-
|
|
235
|
-
const extractionText = formatExtractionText(commandInfo, data);
|
|
236
|
-
if (extractionText) return extractionText;
|
|
237
|
-
const diagnosticText = formatDiagnosticText(commandInfo, data);
|
|
238
|
-
if (diagnosticText) return diagnosticText;
|
|
239
|
-
const pageSummary = getPageSummary(data);
|
|
240
|
-
if (pageSummary) return redactModelFacingText(pageSummary);
|
|
241
|
-
return stringifyModelFacing(data);
|
|
242
|
-
}
|
|
@@ -1,131 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Purpose: Map successful semanticAction results to the same presentation signals as direct ref commands.
|
|
3
|
-
* Responsibilities: Resolve presentation command names, compact action prose, and navigation-summary probe gates.
|
|
4
|
-
* Scope: semanticAction success presentation only.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import {
|
|
8
|
-
getCompiledSemanticActionCommandIndex,
|
|
9
|
-
isCompiledSemanticActionFindCommand,
|
|
10
|
-
} from "../../input-modes/semantic-action.js";
|
|
11
|
-
import type { CompiledAgentBrowserSemanticAction } from "../../input-modes/types.js";
|
|
12
|
-
import { isRecord } from "../../parsing.js";
|
|
13
|
-
import type { CommandInfo } from "../../runtime.js";
|
|
14
|
-
import {
|
|
15
|
-
formatNavigationSummary,
|
|
16
|
-
getNavigationSummary,
|
|
17
|
-
isNavigationObservableCommand,
|
|
18
|
-
} from "./navigation.js";
|
|
19
|
-
import { redactModelFacingText } from "./common.js";
|
|
20
|
-
|
|
21
|
-
const SEMANTIC_NAVIGATION_PROBE_ACTIONS = new Set(["check", "click"]);
|
|
22
|
-
|
|
23
|
-
const SEMANTIC_PRESENTATION_ACTIONS = new Set(["check", "click", "fill", "select"]);
|
|
24
|
-
|
|
25
|
-
function getPageSummary(data: Record<string, unknown>): string | undefined {
|
|
26
|
-
const title = typeof data.title === "string" ? data.title : undefined;
|
|
27
|
-
const url = typeof data.url === "string" ? data.url : undefined;
|
|
28
|
-
if (!title && !url) return undefined;
|
|
29
|
-
if (title && url) return `${title}\n${url}`;
|
|
30
|
-
return title ?? url;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function formatSemanticActionTarget(compiled: CompiledAgentBrowserSemanticAction): string {
|
|
34
|
-
if (compiled.action === "select") {
|
|
35
|
-
const selector = compiled.selector ?? "selector";
|
|
36
|
-
const values = compiled.values?.length ? compiled.values.join(", ") : "";
|
|
37
|
-
return values ? `${selector} → ${values}` : selector;
|
|
38
|
-
}
|
|
39
|
-
const commandIndex = getCompiledSemanticActionCommandIndex(compiled);
|
|
40
|
-
const locator = compiled.locator ?? compiled.args[commandIndex + 1] ?? "locator";
|
|
41
|
-
const locatorValue = compiled.args[commandIndex + 2];
|
|
42
|
-
const nameIndex = compiled.args.indexOf("--name");
|
|
43
|
-
const name = nameIndex >= 0 ? compiled.args[nameIndex + 1] : undefined;
|
|
44
|
-
const quotedValue = JSON.stringify(locatorValue ?? "");
|
|
45
|
-
const target = `${locator} ${quotedValue}`;
|
|
46
|
-
return name ? `${target} (name ${JSON.stringify(name)})` : target;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
export function formatSemanticActionCompactLine(compiled: CompiledAgentBrowserSemanticAction): string {
|
|
50
|
-
const target = formatSemanticActionTarget(compiled);
|
|
51
|
-
switch (compiled.action) {
|
|
52
|
-
case "click":
|
|
53
|
-
return `Clicked: ${target}`;
|
|
54
|
-
case "fill":
|
|
55
|
-
return `Filled: ${target}`;
|
|
56
|
-
case "check":
|
|
57
|
-
return `Checked: ${target}`;
|
|
58
|
-
case "select":
|
|
59
|
-
return `Selected: ${target}`;
|
|
60
|
-
default:
|
|
61
|
-
return `${compiled.action}: ${target}`;
|
|
62
|
-
}
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
export function resolveSemanticPresentationCommand(
|
|
66
|
-
compiled: CompiledAgentBrowserSemanticAction | undefined,
|
|
67
|
-
): string | undefined {
|
|
68
|
-
if (!compiled || !SEMANTIC_PRESENTATION_ACTIONS.has(compiled.action)) return undefined;
|
|
69
|
-
if (compiled.action === "select") return "select";
|
|
70
|
-
if (isCompiledSemanticActionFindCommand(compiled)) return compiled.action;
|
|
71
|
-
return undefined;
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export function resolvePresentationCommandInfo(
|
|
75
|
-
commandInfo: CommandInfo,
|
|
76
|
-
compiledSemanticAction?: CompiledAgentBrowserSemanticAction,
|
|
77
|
-
): CommandInfo {
|
|
78
|
-
const presentationCommand = resolveSemanticPresentationCommand(compiledSemanticAction);
|
|
79
|
-
if (!presentationCommand) return commandInfo;
|
|
80
|
-
return { ...commandInfo, command: presentationCommand };
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
export function shouldCaptureSemanticActionNavigationSummary(
|
|
84
|
-
compiled: CompiledAgentBrowserSemanticAction | undefined,
|
|
85
|
-
data: unknown,
|
|
86
|
-
): boolean {
|
|
87
|
-
if (!compiled || !SEMANTIC_NAVIGATION_PROBE_ACTIONS.has(compiled.action)) return false;
|
|
88
|
-
if (!isCompiledSemanticActionFindCommand(compiled)) return false;
|
|
89
|
-
return !isRecord(data) || (typeof data.title !== "string" && typeof data.url !== "string");
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
export function formatSemanticActionPresentationText(
|
|
93
|
-
compiled: CompiledAgentBrowserSemanticAction,
|
|
94
|
-
data: Record<string, unknown>,
|
|
95
|
-
): string | undefined {
|
|
96
|
-
const presentationCommand = resolveSemanticPresentationCommand(compiled);
|
|
97
|
-
if (!presentationCommand) return undefined;
|
|
98
|
-
|
|
99
|
-
const actionLine = formatSemanticActionCompactLine(compiled);
|
|
100
|
-
const navigationSummary = getNavigationSummary(data);
|
|
101
|
-
if (navigationSummary && isNavigationObservableCommand(presentationCommand)) {
|
|
102
|
-
const navigationText = formatNavigationSummary(navigationSummary);
|
|
103
|
-
if (navigationText) return `${actionLine}\n\nCurrent page:\n${navigationText}`;
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
const pageSummary = getPageSummary(data);
|
|
107
|
-
if (pageSummary) return `${actionLine}\n\nCurrent page:\n${redactModelFacingText(pageSummary)}`;
|
|
108
|
-
|
|
109
|
-
return actionLine;
|
|
110
|
-
}
|
|
111
|
-
|
|
112
|
-
export function formatSemanticActionPresentationSummary(
|
|
113
|
-
compiled: CompiledAgentBrowserSemanticAction,
|
|
114
|
-
data: Record<string, unknown>,
|
|
115
|
-
): string | undefined {
|
|
116
|
-
const presentationCommand = resolveSemanticPresentationCommand(compiled);
|
|
117
|
-
if (!presentationCommand) return undefined;
|
|
118
|
-
|
|
119
|
-
const navigationSummary = getNavigationSummary(data);
|
|
120
|
-
if (navigationSummary && isNavigationObservableCommand(presentationCommand)) {
|
|
121
|
-
const navigationText = formatNavigationSummary(navigationSummary);
|
|
122
|
-
if (navigationText) {
|
|
123
|
-
return `${presentationCommand} → ${navigationText.split("\n", 1)[0] ?? navigationText}`;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
|
|
127
|
-
const pageSummary = getPageSummary(data);
|
|
128
|
-
if (pageSummary) return `${presentationCommand} → ${pageSummary.split("\n", 1)[0] ?? pageSummary}`;
|
|
129
|
-
|
|
130
|
-
return `${presentationCommand} → ${formatSemanticActionTarget(compiled)}`;
|
|
131
|
-
}
|
|
@@ -1,143 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Purpose: Render upstream agent-browser skills output as native pi tool guidance.
|
|
3
|
-
* Responsibilities: Format skills list/path/get results and translate agent-browser shell snippets to agent_browser tool calls.
|
|
4
|
-
* Scope: Skills command presentation only.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
import { isRecord } from "../../parsing.js";
|
|
8
|
-
import type { CommandInfo } from "../../runtime.js";
|
|
9
|
-
import { getStringField, redactModelFacingText, stringifyModelFacing } from "./common.js";
|
|
10
|
-
|
|
11
|
-
function formatSkillsListText(skills: unknown[]): string {
|
|
12
|
-
if (skills.length === 0) return "No agent-browser skills found.";
|
|
13
|
-
return skills
|
|
14
|
-
.map((item, index) => {
|
|
15
|
-
if (!isRecord(item)) return `${index + 1}. ${stringifyModelFacing(item)}`;
|
|
16
|
-
const name = redactModelFacingText(getStringField(item, "name") ?? `(skill ${index + 1})`);
|
|
17
|
-
const description = getStringField(item, "description");
|
|
18
|
-
return description ? `${index + 1}. ${name} — ${redactModelFacingText(description)}` : `${index + 1}. ${name}`;
|
|
19
|
-
})
|
|
20
|
-
.join("\n");
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
function getSkillContent(data: unknown): string | undefined {
|
|
24
|
-
if (typeof data === "string") return data;
|
|
25
|
-
if (isRecord(data) && typeof data.content === "string") return data.content;
|
|
26
|
-
if (!Array.isArray(data)) return undefined;
|
|
27
|
-
const content = data.flatMap((item) => (isRecord(item) && typeof item.content === "string" ? [item.content] : []));
|
|
28
|
-
return content.length > 0 ? content.join("\n\n") : undefined;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
function splitShellWords(input: string): string[] | undefined {
|
|
32
|
-
const words: string[] = [];
|
|
33
|
-
let current = "";
|
|
34
|
-
let quote: 'single' | 'double' | undefined;
|
|
35
|
-
for (let index = 0; index < input.length; index += 1) {
|
|
36
|
-
const char = input[index];
|
|
37
|
-
if (quote === "single") {
|
|
38
|
-
if (char === "'") quote = undefined;
|
|
39
|
-
else current += char;
|
|
40
|
-
continue;
|
|
41
|
-
}
|
|
42
|
-
if (quote === "double") {
|
|
43
|
-
if (char === '"') quote = undefined;
|
|
44
|
-
else if (char === "\\" && index + 1 < input.length) {
|
|
45
|
-
index += 1;
|
|
46
|
-
current += input[index];
|
|
47
|
-
} else current += char;
|
|
48
|
-
continue;
|
|
49
|
-
}
|
|
50
|
-
if (char === "'") {
|
|
51
|
-
quote = "single";
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
if (char === '"') {
|
|
55
|
-
quote = "double";
|
|
56
|
-
continue;
|
|
57
|
-
}
|
|
58
|
-
if (char === "\\" && index + 1 < input.length) {
|
|
59
|
-
index += 1;
|
|
60
|
-
current += input[index];
|
|
61
|
-
continue;
|
|
62
|
-
}
|
|
63
|
-
if (char === "#" && current.length === 0) {
|
|
64
|
-
break;
|
|
65
|
-
}
|
|
66
|
-
if (/\s/.test(char)) {
|
|
67
|
-
if (current.length > 0) {
|
|
68
|
-
words.push(current);
|
|
69
|
-
current = "";
|
|
70
|
-
}
|
|
71
|
-
continue;
|
|
72
|
-
}
|
|
73
|
-
current += char;
|
|
74
|
-
}
|
|
75
|
-
if (quote) return undefined;
|
|
76
|
-
if (current.length > 0) words.push(current);
|
|
77
|
-
return words;
|
|
78
|
-
}
|
|
79
|
-
|
|
80
|
-
function formatNativeAgentBrowserCall(args: string[], stdin?: string): string {
|
|
81
|
-
return stdin === undefined
|
|
82
|
-
? `agent_browser { "args": ${JSON.stringify(args)} }`
|
|
83
|
-
: `agent_browser { "args": ${JSON.stringify(args)}, "stdin": ${JSON.stringify(stdin)} }`;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
function formatNativeSkillContent(content: string): string {
|
|
87
|
-
const lines = content.replace(/^allowed-tools:.*agent-browser.*\n?/gim, "").replace(/^```bash\s*$/gim, "```text").split("\n");
|
|
88
|
-
const output: string[] = [];
|
|
89
|
-
for (let index = 0; index < lines.length; index += 1) {
|
|
90
|
-
const line = lines[index];
|
|
91
|
-
const commandMatch = /^(\s*)agent-browser\s+(.+?)\s*$/.exec(line);
|
|
92
|
-
if (!commandMatch) {
|
|
93
|
-
output.push(line);
|
|
94
|
-
continue;
|
|
95
|
-
}
|
|
96
|
-
const indent = commandMatch[1];
|
|
97
|
-
const rawArgsText = commandMatch[2];
|
|
98
|
-
const heredocMatch = /^(.*?)\s+(<<-?)['"]?([A-Za-z_][A-Za-z0-9_]*)['"]?\s*$/.exec(rawArgsText);
|
|
99
|
-
const argsText = heredocMatch?.[1] ?? rawArgsText;
|
|
100
|
-
const args = splitShellWords(argsText);
|
|
101
|
-
if (!args || args.length === 0) {
|
|
102
|
-
output.push(line);
|
|
103
|
-
continue;
|
|
104
|
-
}
|
|
105
|
-
if (!heredocMatch) {
|
|
106
|
-
output.push(`${indent}${formatNativeAgentBrowserCall(args)}`);
|
|
107
|
-
continue;
|
|
108
|
-
}
|
|
109
|
-
const stripsLeadingTabs = heredocMatch[2] === "<<-";
|
|
110
|
-
const delimiter = heredocMatch[3];
|
|
111
|
-
const stdinLines: string[] = [];
|
|
112
|
-
let cursor = index + 1;
|
|
113
|
-
while (cursor < lines.length) {
|
|
114
|
-
const candidate = stripsLeadingTabs ? lines[cursor].replace(/^\t+/, "") : lines[cursor];
|
|
115
|
-
if (candidate === delimiter) break;
|
|
116
|
-
stdinLines.push(candidate);
|
|
117
|
-
cursor += 1;
|
|
118
|
-
}
|
|
119
|
-
if (cursor >= lines.length) {
|
|
120
|
-
output.push(line);
|
|
121
|
-
continue;
|
|
122
|
-
}
|
|
123
|
-
output.push(`${indent}${formatNativeAgentBrowserCall(args, stdinLines.join("\n"))}`);
|
|
124
|
-
index = cursor;
|
|
125
|
-
}
|
|
126
|
-
return output.join("\n");
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
export function formatSkillsText(commandInfo: CommandInfo, data: unknown): string | undefined {
|
|
130
|
-
if (commandInfo.command !== "skills") return undefined;
|
|
131
|
-
if (commandInfo.subcommand === "path") return typeof data === "string" ? redactModelFacingText(data) : undefined;
|
|
132
|
-
if (commandInfo.subcommand === "list" && Array.isArray(data)) return formatSkillsListText(data);
|
|
133
|
-
const content = getSkillContent(data);
|
|
134
|
-
if (content) {
|
|
135
|
-
const note = [
|
|
136
|
-
"Pi native-tool note: upstream skill text was adapted for this native tool.",
|
|
137
|
-
"Use args for CLI tokens and stdin only for batch, eval --stdin, or auth save --password-stdin; do not pipe heredocs through bash unless the user explicitly asks for a bash workflow.",
|
|
138
|
-
].join("\n");
|
|
139
|
-
return `${note}\n\n${redactModelFacingText(formatNativeSkillContent(content))}`;
|
|
140
|
-
}
|
|
141
|
-
if (typeof data === "string") return redactModelFacingText(formatNativeSkillContent(data));
|
|
142
|
-
return undefined;
|
|
143
|
-
}
|