pi-agent-browser-native 0.2.48 → 0.2.50

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.
Files changed (189) hide show
  1. package/CHANGELOG.md +27 -1
  2. package/README.md +21 -11
  3. package/dist/extensions/agent-browser/index.js +808 -0
  4. package/dist/extensions/agent-browser/lib/argv-descriptor.js +71 -0
  5. package/dist/extensions/agent-browser/lib/argv-grammar.js +121 -0
  6. package/dist/extensions/agent-browser/lib/bash-guard.js +190 -0
  7. package/dist/extensions/agent-browser/lib/command-policy.js +85 -0
  8. package/dist/extensions/agent-browser/lib/command-taxonomy.js +302 -0
  9. package/dist/extensions/agent-browser/lib/config-policy.js +669 -0
  10. package/dist/extensions/agent-browser/lib/config.js +122 -0
  11. package/dist/extensions/agent-browser/lib/electron/cdp.js +51 -0
  12. package/dist/extensions/agent-browser/lib/electron/cleanup.js +212 -0
  13. package/dist/extensions/agent-browser/lib/electron/discovery.js +633 -0
  14. package/dist/extensions/agent-browser/lib/electron/launch.js +351 -0
  15. package/{extensions/agent-browser/lib/electron/text.ts → dist/extensions/agent-browser/lib/electron/text.js} +5 -5
  16. package/dist/extensions/agent-browser/lib/executable-path.js +20 -0
  17. package/dist/extensions/agent-browser/lib/fs-utils.js +18 -0
  18. package/dist/extensions/agent-browser/lib/input-modes/electron.js +165 -0
  19. package/dist/extensions/agent-browser/lib/input-modes/job.js +519 -0
  20. package/dist/extensions/agent-browser/lib/input-modes/lookups.js +440 -0
  21. package/dist/extensions/agent-browser/lib/input-modes/params.js +164 -0
  22. package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +119 -0
  23. package/dist/extensions/agent-browser/lib/input-modes/shared.js +42 -0
  24. package/dist/extensions/agent-browser/lib/input-modes/types.js +21 -0
  25. package/dist/extensions/agent-browser/lib/input-modes.js +10 -0
  26. package/dist/extensions/agent-browser/lib/json-schema.js +58 -0
  27. package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +59 -0
  28. package/dist/extensions/agent-browser/lib/navigation-policy.js +83 -0
  29. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +62 -0
  30. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +39 -0
  31. package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +276 -0
  32. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +909 -0
  33. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +443 -0
  34. package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +47 -0
  35. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.js +141 -0
  36. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +108 -0
  37. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +112 -0
  38. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +158 -0
  39. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +54 -0
  40. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +762 -0
  41. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +491 -0
  42. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +40 -0
  43. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-artifacts.js +5 -0
  44. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +731 -0
  45. package/dist/extensions/agent-browser/lib/orchestration/browser-run/types.js +1 -0
  46. package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +718 -0
  47. package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +247 -0
  48. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +68 -0
  49. package/{extensions/agent-browser/lib/parsing.ts → dist/extensions/agent-browser/lib/parsing.js} +12 -11
  50. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +241 -0
  51. package/dist/extensions/agent-browser/lib/playbook.js +121 -0
  52. package/dist/extensions/agent-browser/lib/process.js +363 -0
  53. package/dist/extensions/agent-browser/lib/prompt-policy.js +91 -0
  54. package/dist/extensions/agent-browser/lib/results/action-recommendations.js +220 -0
  55. package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +111 -0
  56. package/{extensions/agent-browser/lib/results/artifact-state.ts → dist/extensions/agent-browser/lib/results/artifact-state.js} +4 -8
  57. package/dist/extensions/agent-browser/lib/results/categories.js +76 -0
  58. package/dist/extensions/agent-browser/lib/results/confirmation.js +63 -0
  59. package/dist/extensions/agent-browser/lib/results/contracts.js +8 -0
  60. package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +74 -0
  61. package/dist/extensions/agent-browser/lib/results/envelope.js +166 -0
  62. package/dist/extensions/agent-browser/lib/results/network-routes.js +92 -0
  63. package/dist/extensions/agent-browser/lib/results/network.js +73 -0
  64. package/dist/extensions/agent-browser/lib/results/next-actions.js +72 -0
  65. package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +515 -0
  66. package/dist/extensions/agent-browser/lib/results/presentation/batch.js +397 -0
  67. package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +55 -0
  68. package/dist/extensions/agent-browser/lib/results/presentation/common.js +46 -0
  69. package/dist/extensions/agent-browser/lib/results/presentation/content.js +24 -0
  70. package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +956 -0
  71. package/dist/extensions/agent-browser/lib/results/presentation/errors.js +205 -0
  72. package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +134 -0
  73. package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +159 -0
  74. package/dist/extensions/agent-browser/lib/results/presentation/registry.js +216 -0
  75. package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +104 -0
  76. package/dist/extensions/agent-browser/lib/results/presentation/skills.js +152 -0
  77. package/dist/extensions/agent-browser/lib/results/presentation.js +177 -0
  78. package/dist/extensions/agent-browser/lib/results/recovery-actions.js +107 -0
  79. package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +50 -0
  80. package/dist/extensions/agent-browser/lib/results/selector-recovery.js +225 -0
  81. package/{extensions/agent-browser/lib/results/shared.ts → dist/extensions/agent-browser/lib/results/shared.js} +0 -1
  82. package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +208 -0
  83. package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +78 -0
  84. package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +331 -0
  85. package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +40 -0
  86. package/dist/extensions/agent-browser/lib/results/snapshot.js +264 -0
  87. package/dist/extensions/agent-browser/lib/results/text.js +40 -0
  88. package/{extensions/agent-browser/lib/results.ts → dist/extensions/agent-browser/lib/results.js} +2 -32
  89. package/dist/extensions/agent-browser/lib/runtime.js +855 -0
  90. package/dist/extensions/agent-browser/lib/session-page-state.js +411 -0
  91. package/dist/extensions/agent-browser/lib/string-enum-schema.js +13 -0
  92. package/dist/extensions/agent-browser/lib/temp.js +498 -0
  93. package/dist/extensions/agent-browser/lib/web-search.js +562 -0
  94. package/docs/ARCHITECTURE.md +5 -5
  95. package/docs/COMMAND_REFERENCE.md +4 -4
  96. package/docs/RELEASE.md +22 -11
  97. package/docs/REQUIREMENTS.md +1 -1
  98. package/docs/SUPPORT_MATRIX.md +5 -4
  99. package/docs/TOOL_CONTRACT.md +1 -1
  100. package/package.json +9 -5
  101. package/scripts/config.mjs +14 -20
  102. package/scripts/doctor.mjs +8 -7
  103. package/extensions/agent-browser/index.ts +0 -961
  104. package/extensions/agent-browser/lib/argv-descriptor.ts +0 -90
  105. package/extensions/agent-browser/lib/argv-grammar.ts +0 -128
  106. package/extensions/agent-browser/lib/bash-guard.ts +0 -205
  107. package/extensions/agent-browser/lib/command-policy.ts +0 -71
  108. package/extensions/agent-browser/lib/command-taxonomy.ts +0 -336
  109. package/extensions/agent-browser/lib/config-policy.js +0 -690
  110. package/extensions/agent-browser/lib/config.ts +0 -211
  111. package/extensions/agent-browser/lib/electron/cdp.ts +0 -69
  112. package/extensions/agent-browser/lib/electron/cleanup.ts +0 -235
  113. package/extensions/agent-browser/lib/electron/discovery.ts +0 -710
  114. package/extensions/agent-browser/lib/electron/launch.ts +0 -499
  115. package/extensions/agent-browser/lib/executable-path.ts +0 -19
  116. package/extensions/agent-browser/lib/fs-utils.ts +0 -18
  117. package/extensions/agent-browser/lib/input-modes/electron.ts +0 -170
  118. package/extensions/agent-browser/lib/input-modes/job.ts +0 -527
  119. package/extensions/agent-browser/lib/input-modes/lookups.ts +0 -447
  120. package/extensions/agent-browser/lib/input-modes/params.ts +0 -205
  121. package/extensions/agent-browser/lib/input-modes/semantic-action.ts +0 -127
  122. package/extensions/agent-browser/lib/input-modes/shared.ts +0 -46
  123. package/extensions/agent-browser/lib/input-modes/types.ts +0 -225
  124. package/extensions/agent-browser/lib/input-modes.ts +0 -45
  125. package/extensions/agent-browser/lib/json-schema.ts +0 -73
  126. package/extensions/agent-browser/lib/launch-scoped-flags.ts +0 -67
  127. package/extensions/agent-browser/lib/navigation-policy.ts +0 -95
  128. package/extensions/agent-browser/lib/orchestration/batch-stdin.ts +0 -65
  129. package/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.ts +0 -44
  130. package/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.ts +0 -280
  131. package/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.ts +0 -914
  132. package/extensions/agent-browser/lib/orchestration/browser-run/final-result.ts +0 -521
  133. package/extensions/agent-browser/lib/orchestration/browser-run/index.ts +0 -53
  134. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/direct-anchor-download.ts +0 -158
  135. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.ts +0 -116
  136. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.ts +0 -147
  137. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.ts +0 -183
  138. package/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.ts +0 -58
  139. package/extensions/agent-browser/lib/orchestration/browser-run/prepare.ts +0 -847
  140. package/extensions/agent-browser/lib/orchestration/browser-run/process-output.ts +0 -559
  141. package/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.ts +0 -47
  142. package/extensions/agent-browser/lib/orchestration/browser-run/session-artifacts.ts +0 -8
  143. package/extensions/agent-browser/lib/orchestration/browser-run/session-state.ts +0 -868
  144. package/extensions/agent-browser/lib/orchestration/browser-run/types.ts +0 -565
  145. package/extensions/agent-browser/lib/orchestration/electron-host/index.ts +0 -855
  146. package/extensions/agent-browser/lib/orchestration/input-plan.ts +0 -375
  147. package/extensions/agent-browser/lib/orchestration/output-file.ts +0 -86
  148. package/extensions/agent-browser/lib/pi-tool-rendering.ts +0 -267
  149. package/extensions/agent-browser/lib/playbook.ts +0 -142
  150. package/extensions/agent-browser/lib/process.ts +0 -516
  151. package/extensions/agent-browser/lib/prompt-policy.ts +0 -105
  152. package/extensions/agent-browser/lib/results/action-recommendations.ts +0 -264
  153. package/extensions/agent-browser/lib/results/artifact-manifest.ts +0 -111
  154. package/extensions/agent-browser/lib/results/categories.ts +0 -106
  155. package/extensions/agent-browser/lib/results/confirmation.ts +0 -76
  156. package/extensions/agent-browser/lib/results/contracts.ts +0 -241
  157. package/extensions/agent-browser/lib/results/editable-ref-evidence.ts +0 -72
  158. package/extensions/agent-browser/lib/results/envelope.ts +0 -195
  159. package/extensions/agent-browser/lib/results/network-routes.ts +0 -83
  160. package/extensions/agent-browser/lib/results/network.ts +0 -78
  161. package/extensions/agent-browser/lib/results/next-actions.ts +0 -117
  162. package/extensions/agent-browser/lib/results/presentation/artifacts.ts +0 -588
  163. package/extensions/agent-browser/lib/results/presentation/batch.ts +0 -450
  164. package/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.ts +0 -67
  165. package/extensions/agent-browser/lib/results/presentation/common.ts +0 -53
  166. package/extensions/agent-browser/lib/results/presentation/content.ts +0 -36
  167. package/extensions/agent-browser/lib/results/presentation/diagnostics.ts +0 -923
  168. package/extensions/agent-browser/lib/results/presentation/errors.ts +0 -227
  169. package/extensions/agent-browser/lib/results/presentation/large-output.ts +0 -182
  170. package/extensions/agent-browser/lib/results/presentation/navigation.ts +0 -184
  171. package/extensions/agent-browser/lib/results/presentation/registry.ts +0 -242
  172. package/extensions/agent-browser/lib/results/presentation/semantic-action.ts +0 -131
  173. package/extensions/agent-browser/lib/results/presentation/skills.ts +0 -143
  174. package/extensions/agent-browser/lib/results/presentation.ts +0 -257
  175. package/extensions/agent-browser/lib/results/recovery-actions.ts +0 -139
  176. package/extensions/agent-browser/lib/results/recovery-next-actions.ts +0 -71
  177. package/extensions/agent-browser/lib/results/selector-recovery.ts +0 -320
  178. package/extensions/agent-browser/lib/results/snapshot-high-value-controls.ts +0 -273
  179. package/extensions/agent-browser/lib/results/snapshot-refs.ts +0 -100
  180. package/extensions/agent-browser/lib/results/snapshot-segments.ts +0 -366
  181. package/extensions/agent-browser/lib/results/snapshot-spill.ts +0 -63
  182. package/extensions/agent-browser/lib/results/snapshot.ts +0 -329
  183. package/extensions/agent-browser/lib/results/text.ts +0 -40
  184. package/extensions/agent-browser/lib/runtime.ts +0 -988
  185. package/extensions/agent-browser/lib/session-page-state.ts +0 -512
  186. package/extensions/agent-browser/lib/string-enum-schema.ts +0 -20
  187. package/extensions/agent-browser/lib/temp.ts +0 -577
  188. package/extensions/agent-browser/lib/web-search.ts +0 -728
  189. /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
- }