pi-agent-browser-native 0.9.3 → 0.9.4

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 (391) hide show
  1. package/CHANGELOG.md +77 -5
  2. package/README.md +103 -81
  3. package/dist/extensions/agent-browser/index.js +43057 -2031
  4. package/dist/extensions/agent-browser/lib/argv-descriptor.js +49 -26
  5. package/dist/extensions/agent-browser/lib/argv-grammar.js +82 -93
  6. package/dist/extensions/agent-browser/lib/bash-guard.js +129 -126
  7. package/dist/extensions/agent-browser/lib/batch-lifecycle.js +112 -51
  8. package/dist/extensions/agent-browser/lib/browser-execution-claim-codec.js +61 -0
  9. package/dist/extensions/agent-browser/lib/browser-execution-claim-storage.js +232 -0
  10. package/dist/extensions/agent-browser/lib/browser-execution-claims.js +202 -0
  11. package/dist/extensions/agent-browser/lib/browser-execution-identity.js +77 -0
  12. package/dist/extensions/agent-browser/lib/browser-journal-branch.js +98 -0
  13. package/dist/extensions/agent-browser/lib/browser-journal-contracts.js +1 -0
  14. package/dist/extensions/agent-browser/lib/browser-journal-projection.js +221 -0
  15. package/dist/extensions/agent-browser/lib/browser-journal-reader.js +89 -0
  16. package/dist/extensions/agent-browser/lib/browser-journal-replay.js +246 -0
  17. package/dist/extensions/agent-browser/lib/browser-journal.js +103 -394
  18. package/dist/extensions/agent-browser/lib/browser-legacy-pages.js +220 -0
  19. package/dist/extensions/agent-browser/lib/browser-legacy-projection.js +282 -0
  20. package/dist/extensions/agent-browser/lib/browser-legacy-types.js +1 -0
  21. package/dist/extensions/agent-browser/lib/browser-session-conversion-stream.js +217 -0
  22. package/dist/extensions/agent-browser/lib/browser-session-conversion.js +80 -335
  23. package/dist/extensions/agent-browser/lib/browser-transcript-contracts.js +35 -0
  24. package/dist/extensions/agent-browser/lib/browser-transcript-validation.js +166 -0
  25. package/dist/extensions/agent-browser/lib/browser-transcript.js +137 -82
  26. package/dist/extensions/agent-browser/lib/browser-value-parsing.js +15 -0
  27. package/dist/extensions/agent-browser/lib/command-capabilities.js +340 -0
  28. package/dist/extensions/agent-browser/lib/command-policy.js +107 -88
  29. package/dist/extensions/agent-browser/lib/command-taxonomy.js +49 -322
  30. package/dist/extensions/agent-browser/lib/config-policy.js +138 -343
  31. package/dist/extensions/agent-browser/lib/config-providers.js +71 -0
  32. package/dist/extensions/agent-browser/lib/config-validation.js +218 -0
  33. package/dist/extensions/agent-browser/lib/config.js +19 -7
  34. package/dist/extensions/agent-browser/lib/electron/cdp.js +15 -7
  35. package/dist/extensions/agent-browser/lib/electron/cleanup.js +134 -55
  36. package/dist/extensions/agent-browser/lib/electron/discovery-darwin.js +109 -0
  37. package/dist/extensions/agent-browser/lib/electron/discovery-desktop.js +136 -0
  38. package/dist/extensions/agent-browser/lib/electron/discovery-evidence.js +89 -0
  39. package/dist/extensions/agent-browser/lib/electron/discovery-linux.js +93 -0
  40. package/dist/extensions/agent-browser/lib/electron/discovery-packages.js +162 -0
  41. package/dist/extensions/agent-browser/lib/electron/discovery-types.js +2 -0
  42. package/dist/extensions/agent-browser/lib/electron/discovery.js +140 -549
  43. package/dist/extensions/agent-browser/lib/electron/launch-monitor.js +102 -0
  44. package/dist/extensions/agent-browser/lib/electron/launch-process.js +209 -0
  45. package/dist/extensions/agent-browser/lib/electron/launch-types.js +2 -0
  46. package/dist/extensions/agent-browser/lib/electron/launch.js +249 -354
  47. package/dist/extensions/agent-browser/lib/executable-path.js +21 -12
  48. package/dist/extensions/agent-browser/lib/execution-cwd.js +35 -18
  49. package/dist/extensions/agent-browser/lib/input-modes/electron.js +162 -121
  50. package/dist/extensions/agent-browser/lib/input-modes/job.js +116 -313
  51. package/dist/extensions/agent-browser/lib/input-modes/lookup-network-evidence.js +104 -0
  52. package/dist/extensions/agent-browser/lib/input-modes/lookup-plan.js +132 -0
  53. package/dist/extensions/agent-browser/lib/input-modes/lookup-redaction.js +57 -0
  54. package/dist/extensions/agent-browser/lib/input-modes/lookup-source-evidence.js +151 -0
  55. package/dist/extensions/agent-browser/lib/input-modes/lookup-workspace.js +142 -0
  56. package/dist/extensions/agent-browser/lib/input-modes/lookups.js +57 -412
  57. package/dist/extensions/agent-browser/lib/input-modes/params.js +63 -17
  58. package/dist/extensions/agent-browser/lib/input-modes/qa-analysis.js +268 -0
  59. package/dist/extensions/agent-browser/lib/input-modes/qa-presentation.js +117 -0
  60. package/dist/extensions/agent-browser/lib/input-modes/script-child.js +396 -0
  61. package/dist/extensions/agent-browser/lib/input-modes/script-protocol.js +86 -0
  62. package/dist/extensions/agent-browser/lib/input-modes/script-types.js +1 -0
  63. package/dist/extensions/agent-browser/lib/input-modes/script-validation.js +60 -0
  64. package/dist/extensions/agent-browser/lib/input-modes/script.js +60 -409
  65. package/dist/extensions/agent-browser/lib/input-modes/semantic-action.js +218 -128
  66. package/dist/extensions/agent-browser/lib/input-modes/shared.js +15 -4
  67. package/dist/extensions/agent-browser/lib/input-modes/types.js +56 -7
  68. package/dist/extensions/agent-browser/lib/json-schema.js +22 -10
  69. package/dist/extensions/agent-browser/lib/launch-scoped-flags.js +17 -5
  70. package/dist/extensions/agent-browser/lib/managed-session-policy-lock.js +92 -425
  71. package/dist/extensions/agent-browser/lib/managed-session-posix-storage.js +58 -0
  72. package/dist/extensions/agent-browser/lib/managed-session-project-identity.js +244 -0
  73. package/dist/extensions/agent-browser/lib/managed-session-restore-context.js +84 -0
  74. package/dist/extensions/agent-browser/lib/managed-session-restore-policy.js +119 -0
  75. package/dist/extensions/agent-browser/lib/managed-session-restore-state.js +83 -0
  76. package/dist/extensions/agent-browser/lib/managed-session-restore.js +168 -300
  77. package/dist/extensions/agent-browser/lib/managed-session-snapshot-records.js +277 -0
  78. package/dist/extensions/agent-browser/lib/managed-session-snapshots.js +128 -305
  79. package/dist/extensions/agent-browser/lib/managed-session-storage.js +56 -253
  80. package/dist/extensions/agent-browser/lib/native-confirmation.js +140 -0
  81. package/dist/extensions/agent-browser/lib/native-output.js +43 -9
  82. package/dist/extensions/agent-browser/lib/orchestration/batch-stdin.js +106 -59
  83. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-merge.js +14 -6
  84. package/dist/extensions/agent-browser/lib/orchestration/browser-run/artifact-paths.js +109 -57
  85. package/dist/extensions/agent-browser/lib/orchestration/browser-run/browser-observation-result.js +82 -0
  86. package/dist/extensions/agent-browser/lib/orchestration/browser-run/click-dispatch.js +164 -60
  87. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostic-values.js +31 -0
  88. package/dist/extensions/agent-browser/lib/orchestration/browser-run/diagnostics.js +152 -781
  89. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-observation.js +202 -0
  90. package/dist/extensions/agent-browser/lib/orchestration/browser-run/electron-text-diagnostics.js +109 -0
  91. package/dist/extensions/agent-browser/lib/orchestration/browser-run/fill-diagnostics.js +119 -0
  92. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-action-recovery.js +147 -0
  93. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-actions.js +144 -0
  94. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-content.js +123 -0
  95. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-contracts.js +1 -0
  96. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-details.js +156 -0
  97. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-electron.js +179 -0
  98. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-evidence.js +39 -0
  99. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-missing-binary.js +89 -0
  100. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-recovery.js +97 -0
  101. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-redaction.js +106 -0
  102. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result-timeout.js +110 -0
  103. package/dist/extensions/agent-browser/lib/orchestration/browser-run/final-result.js +41 -538
  104. package/dist/extensions/agent-browser/lib/orchestration/browser-run/index.js +199 -154
  105. package/dist/extensions/agent-browser/lib/orchestration/browser-run/interaction-diagnostics.js +290 -0
  106. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-close.js +167 -0
  107. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-inspection.js +108 -0
  108. package/dist/extensions/agent-browser/lib/orchestration/browser-run/managed-session-daemon-policy.js +127 -205
  109. package/dist/extensions/agent-browser/lib/orchestration/browser-run/native-helper-observation.js +65 -0
  110. package/dist/extensions/agent-browser/lib/orchestration/browser-run/observation-types.js +1 -0
  111. package/dist/extensions/agent-browser/lib/orchestration/browser-run/overlay-diagnostics.js +120 -0
  112. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/network-page-filter.js +113 -30
  113. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/scroll-shims.js +109 -28
  114. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter-data.js +150 -0
  115. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-filter.js +138 -253
  116. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/snapshot-rendered-text.js +147 -0
  117. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare/wait-timeouts.js +59 -24
  118. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-artifacts.js +159 -0
  119. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-command.js +131 -0
  120. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-contracts.js +1 -0
  121. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-daemon.js +93 -0
  122. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-failure.js +42 -0
  123. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-guards.js +242 -0
  124. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-input.js +75 -0
  125. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-observations.js +92 -0
  126. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-selection.js +254 -0
  127. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-page-state.js +121 -0
  128. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-refs.js +130 -0
  129. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-resources.js +114 -0
  130. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-semantic.js +121 -0
  131. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-session-plan.js +222 -0
  132. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare-timeouts.js +68 -0
  133. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prepare.js +176 -1123
  134. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-analysis.js +191 -0
  135. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-confirmation.js +152 -0
  136. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-diagnostics.js +182 -0
  137. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-electron.js +150 -0
  138. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-contracts.js +1 -0
  139. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase-contracts.js +1 -0
  140. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle-phase.js +115 -0
  141. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-lifecycle.js +256 -0
  142. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed-contracts.js +1 -0
  143. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-managed.js +256 -0
  144. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase-contracts.js +1 -0
  145. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native-phase.js +93 -0
  146. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-native.js +113 -0
  147. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation-contracts.js +1 -0
  148. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-navigation.js +316 -0
  149. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-ownership.js +28 -0
  150. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase-contracts.js +1 -0
  151. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-page-phase.js +142 -0
  152. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation-contracts.js +1 -0
  153. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-presentation.js +333 -0
  154. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase-contracts.js +1 -0
  155. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication-phase.js +71 -0
  156. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-publication.js +201 -0
  157. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-receipts.js +183 -0
  158. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-refs.js +200 -0
  159. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output-tabs.js +142 -0
  160. package/dist/extensions/agent-browser/lib/orchestration/browser-run/process-output.js +18 -968
  161. package/dist/extensions/agent-browser/lib/orchestration/browser-run/prompt-guards.js +23 -13
  162. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-receipt-reconciliation.js +198 -0
  163. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-contracts.js +1 -0
  164. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery-presentation.js +154 -0
  165. package/dist/extensions/agent-browser/lib/orchestration/browser-run/recording-recovery.js +68 -151
  166. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-capture.js +14 -0
  167. package/dist/extensions/agent-browser/lib/orchestration/browser-run/screenshot-observation.js +169 -46
  168. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-commands.js +130 -0
  169. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-electron.js +210 -0
  170. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-observations.js +61 -0
  171. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-outcomes.js +187 -0
  172. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-refs.js +171 -0
  173. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state-tabs.js +228 -0
  174. package/dist/extensions/agent-browser/lib/orchestration/browser-run/session-state.js +77 -765
  175. package/dist/extensions/agent-browser/lib/orchestration/browser-run/text-visibility-diagnostics.js +182 -0
  176. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-diagnostics.js +256 -0
  177. package/dist/extensions/agent-browser/lib/orchestration/browser-run/timeout-progress.js +108 -0
  178. package/dist/extensions/agent-browser/lib/orchestration/code-artifact-observation.js +39 -0
  179. package/dist/extensions/agent-browser/lib/orchestration/code-image-observation.js +119 -0
  180. package/dist/extensions/agent-browser/lib/orchestration/electron-host/branch.js +92 -0
  181. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup-result.js +58 -0
  182. package/dist/extensions/agent-browser/lib/orchestration/electron-host/cleanup.js +78 -0
  183. package/dist/extensions/agent-browser/lib/orchestration/electron-host/contracts.js +1 -0
  184. package/dist/extensions/agent-browser/lib/orchestration/electron-host/discovery.js +106 -0
  185. package/dist/extensions/agent-browser/lib/orchestration/electron-host/index.js +48 -821
  186. package/dist/extensions/agent-browser/lib/orchestration/electron-host/policy.js +86 -0
  187. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-collection.js +69 -0
  188. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-data.js +167 -0
  189. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe-presentation.js +164 -0
  190. package/dist/extensions/agent-browser/lib/orchestration/electron-host/probe.js +161 -0
  191. package/dist/extensions/agent-browser/lib/orchestration/electron-host/status.js +165 -0
  192. package/dist/extensions/agent-browser/lib/orchestration/execution-queue.js +21 -9
  193. package/dist/extensions/agent-browser/lib/orchestration/extension-artifact-preflight.js +211 -0
  194. package/dist/extensions/agent-browser/lib/orchestration/extension-artifacts.js +23 -0
  195. package/dist/extensions/agent-browser/lib/orchestration/extension-attachment-replay.js +99 -0
  196. package/dist/extensions/agent-browser/lib/orchestration/extension-branch-restore.js +275 -0
  197. package/dist/extensions/agent-browser/lib/orchestration/extension-code.js +280 -0
  198. package/dist/extensions/agent-browser/lib/orchestration/extension-command-admission.js +303 -0
  199. package/dist/extensions/agent-browser/lib/orchestration/extension-command-output.js +36 -0
  200. package/dist/extensions/agent-browser/lib/orchestration/extension-command-result.js +335 -0
  201. package/dist/extensions/agent-browser/lib/orchestration/extension-command-run.js +227 -0
  202. package/dist/extensions/agent-browser/lib/orchestration/extension-command-state.js +1 -0
  203. package/dist/extensions/agent-browser/lib/orchestration/extension-electron-ownership.js +204 -0
  204. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-locks.js +139 -0
  205. package/dist/extensions/agent-browser/lib/orchestration/extension-execution-queue.js +24 -0
  206. package/dist/extensions/agent-browser/lib/orchestration/extension-host-coordination.js +98 -0
  207. package/dist/extensions/agent-browser/lib/orchestration/extension-host-run.js +295 -0
  208. package/dist/extensions/agent-browser/lib/orchestration/extension-intent-replay.js +41 -0
  209. package/dist/extensions/agent-browser/lib/orchestration/extension-invocation.js +7 -0
  210. package/dist/extensions/agent-browser/lib/orchestration/extension-lifecycle.js +102 -0
  211. package/dist/extensions/agent-browser/lib/orchestration/extension-managed-ownership.js +133 -0
  212. package/dist/extensions/agent-browser/lib/orchestration/extension-observation.js +120 -0
  213. package/dist/extensions/agent-browser/lib/orchestration/extension-prompt.js +180 -0
  214. package/dist/extensions/agent-browser/lib/orchestration/extension-recording.js +290 -0
  215. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-contracts.js +1 -0
  216. package/dist/extensions/agent-browser/lib/orchestration/extension-resource-replay.js +269 -0
  217. package/dist/extensions/agent-browser/lib/orchestration/extension-result-state.js +113 -0
  218. package/dist/extensions/agent-browser/lib/orchestration/extension-runtime.js +146 -0
  219. package/dist/extensions/agent-browser/lib/orchestration/extension-script-leases.js +58 -0
  220. package/dist/extensions/agent-browser/lib/orchestration/extension-tool-boundary.js +62 -0
  221. package/dist/extensions/agent-browser/lib/orchestration/extension-version-check.js +54 -0
  222. package/dist/extensions/agent-browser/lib/orchestration/input-plan-types.js +1 -0
  223. package/dist/extensions/agent-browser/lib/orchestration/input-plan.js +261 -185
  224. package/dist/extensions/agent-browser/lib/orchestration/input-redaction.js +62 -0
  225. package/dist/extensions/agent-browser/lib/orchestration/native-config.js +144 -0
  226. package/dist/extensions/agent-browser/lib/orchestration/native-root-launch.js +77 -0
  227. package/dist/extensions/agent-browser/lib/orchestration/native-session-defaults.js +210 -157
  228. package/dist/extensions/agent-browser/lib/orchestration/operation-paths.js +124 -58
  229. package/dist/extensions/agent-browser/lib/orchestration/output-file.js +197 -99
  230. package/dist/extensions/agent-browser/lib/orchestration/script-mode.js +199 -96
  231. package/dist/extensions/agent-browser/lib/owned-managed-session-context.js +55 -0
  232. package/dist/extensions/agent-browser/lib/page-target-batch.js +118 -0
  233. package/dist/extensions/agent-browser/lib/page-target-guards.js +50 -0
  234. package/dist/extensions/agent-browser/lib/page-target-navigation.js +104 -0
  235. package/dist/extensions/agent-browser/lib/page-target-validation.js +55 -246
  236. package/dist/extensions/agent-browser/lib/parsing.js +13 -4
  237. package/dist/extensions/agent-browser/lib/pi-tool-rendering.js +133 -68
  238. package/dist/extensions/agent-browser/lib/playbook.js +16 -12
  239. package/dist/extensions/agent-browser/lib/process-child.js +284 -0
  240. package/dist/extensions/agent-browser/lib/process-environment.js +13 -6
  241. package/dist/extensions/agent-browser/lib/process-errors.js +23 -0
  242. package/dist/extensions/agent-browser/lib/process-identity.js +47 -15
  243. package/dist/extensions/agent-browser/lib/process-socket-storage.js +256 -0
  244. package/dist/extensions/agent-browser/lib/process-stdout.js +74 -0
  245. package/dist/extensions/agent-browser/lib/process.js +145 -536
  246. package/dist/extensions/agent-browser/lib/prompt-artifacts.js +287 -0
  247. package/dist/extensions/agent-browser/lib/prompt-policy.js +15 -194
  248. package/dist/extensions/agent-browser/lib/read-command.js +41 -0
  249. package/dist/extensions/agent-browser/lib/read-confirmation.js +131 -68
  250. package/dist/extensions/agent-browser/lib/recording-reservations.js +118 -45
  251. package/dist/extensions/agent-browser/lib/redaction-fields.js +75 -0
  252. package/dist/extensions/agent-browser/lib/redaction-json.js +149 -0
  253. package/dist/extensions/agent-browser/lib/redaction-url.js +88 -0
  254. package/dist/extensions/agent-browser/lib/results/action-contracts.js +1 -0
  255. package/dist/extensions/agent-browser/lib/results/action-recommendations.js +28 -271
  256. package/dist/extensions/agent-browser/lib/results/artifact-contracts.js +1 -0
  257. package/dist/extensions/agent-browser/lib/results/artifact-manifest-validation.js +133 -0
  258. package/dist/extensions/agent-browser/lib/results/artifact-manifest.js +96 -94
  259. package/dist/extensions/agent-browser/lib/results/artifact-recommendations.js +73 -0
  260. package/dist/extensions/agent-browser/lib/results/categories.js +111 -54
  261. package/dist/extensions/agent-browser/lib/results/confirmation.js +29 -13
  262. package/dist/extensions/agent-browser/lib/results/editable-ref-evidence.js +62 -27
  263. package/dist/extensions/agent-browser/lib/results/electron-recommendations.js +83 -0
  264. package/dist/extensions/agent-browser/lib/results/envelope-decoding.js +48 -0
  265. package/dist/extensions/agent-browser/lib/results/envelope.js +90 -67
  266. package/dist/extensions/agent-browser/lib/results/evidence-contracts.js +1 -0
  267. package/dist/extensions/agent-browser/lib/results/failure-recommendations.js +180 -0
  268. package/dist/extensions/agent-browser/lib/results/network-routes.js +86 -45
  269. package/dist/extensions/agent-browser/lib/results/network.js +35 -12
  270. package/dist/extensions/agent-browser/lib/results/next-actions.js +49 -19
  271. package/dist/extensions/agent-browser/lib/results/presentation/artifact-files.js +320 -0
  272. package/dist/extensions/agent-browser/lib/results/presentation/artifact-format.js +138 -0
  273. package/dist/extensions/agent-browser/lib/results/presentation/artifact-images.js +113 -0
  274. package/dist/extensions/agent-browser/lib/results/presentation/artifact-verification.js +145 -0
  275. package/dist/extensions/agent-browser/lib/results/presentation/artifacts.js +99 -555
  276. package/dist/extensions/agent-browser/lib/results/presentation/batch-contracts.js +1 -0
  277. package/dist/extensions/agent-browser/lib/results/presentation/batch-recording.js +118 -0
  278. package/dist/extensions/agent-browser/lib/results/presentation/batch-redaction.js +68 -0
  279. package/dist/extensions/agent-browser/lib/results/presentation/batch-rendering.js +135 -0
  280. package/dist/extensions/agent-browser/lib/results/presentation/batch-step.js +227 -0
  281. package/dist/extensions/agent-browser/lib/results/presentation/batch-summary.js +91 -0
  282. package/dist/extensions/agent-browser/lib/results/presentation/batch.js +91 -460
  283. package/dist/extensions/agent-browser/lib/results/presentation/browser-profile-recovery.js +9 -5
  284. package/dist/extensions/agent-browser/lib/results/presentation/command-presenters.js +216 -0
  285. package/dist/extensions/agent-browser/lib/results/presentation/common.js +26 -9
  286. package/dist/extensions/agent-browser/lib/results/presentation/content.js +86 -29
  287. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-a11y.js +67 -0
  288. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-health.js +79 -0
  289. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-identity.js +199 -0
  290. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-logs.js +75 -0
  291. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network-actions.js +216 -0
  292. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-network.js +124 -0
  293. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-redaction.js +64 -0
  294. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-storage.js +209 -0
  295. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-stream.js +69 -0
  296. package/dist/extensions/agent-browser/lib/results/presentation/diagnostic-summary.js +222 -0
  297. package/dist/extensions/agent-browser/lib/results/presentation/diagnostics.js +103 -1052
  298. package/dist/extensions/agent-browser/lib/results/presentation/early-result.js +70 -0
  299. package/dist/extensions/agent-browser/lib/results/presentation/errors.js +130 -60
  300. package/dist/extensions/agent-browser/lib/results/presentation/input-contracts.js +1 -0
  301. package/dist/extensions/agent-browser/lib/results/presentation/large-output.js +60 -145
  302. package/dist/extensions/agent-browser/lib/results/presentation/navigation.js +147 -88
  303. package/dist/extensions/agent-browser/lib/results/presentation/notices.js +75 -0
  304. package/dist/extensions/agent-browser/lib/results/presentation/observation-contracts.js +1 -0
  305. package/dist/extensions/agent-browser/lib/results/presentation/observation-rendering.js +127 -0
  306. package/dist/extensions/agent-browser/lib/results/presentation/outcomes.js +120 -0
  307. package/dist/extensions/agent-browser/lib/results/presentation/output-completion.js +77 -0
  308. package/dist/extensions/agent-browser/lib/results/presentation/output-spill.js +51 -0
  309. package/dist/extensions/agent-browser/lib/results/presentation/registry.js +116 -240
  310. package/dist/extensions/agent-browser/lib/results/presentation/semantic-action.js +35 -21
  311. package/dist/extensions/agent-browser/lib/results/presentation/skills.js +104 -73
  312. package/dist/extensions/agent-browser/lib/results/presentation/source.js +109 -0
  313. package/dist/extensions/agent-browser/lib/results/presentation.js +17 -261
  314. package/dist/extensions/agent-browser/lib/results/recommendation-contracts.js +1 -0
  315. package/dist/extensions/agent-browser/lib/results/recording.js +52 -14
  316. package/dist/extensions/agent-browser/lib/results/recovery-actions.js +14 -5
  317. package/dist/extensions/agent-browser/lib/results/recovery-next-actions.js +30 -22
  318. package/dist/extensions/agent-browser/lib/results/selector-recovery-target.js +83 -0
  319. package/dist/extensions/agent-browser/lib/results/selector-recovery.js +119 -119
  320. package/dist/extensions/agent-browser/lib/results/snapshot-compact.js +266 -0
  321. package/dist/extensions/agent-browser/lib/results/snapshot-content.js +32 -0
  322. package/dist/extensions/agent-browser/lib/results/snapshot-high-value-controls.js +104 -71
  323. package/dist/extensions/agent-browser/lib/results/snapshot-refs.js +31 -11
  324. package/dist/extensions/agent-browser/lib/results/snapshot-segments.js +125 -66
  325. package/dist/extensions/agent-browser/lib/results/snapshot-spill.js +26 -7
  326. package/dist/extensions/agent-browser/lib/results/snapshot.js +28 -248
  327. package/dist/extensions/agent-browser/lib/results/text.js +16 -5
  328. package/dist/extensions/agent-browser/lib/runtime-args-validation.js +133 -0
  329. package/dist/extensions/agent-browser/lib/runtime-compatibility.js +81 -0
  330. package/dist/extensions/agent-browser/lib/runtime-contracts.js +1 -0
  331. package/dist/extensions/agent-browser/lib/runtime-redaction.js +118 -0
  332. package/dist/extensions/agent-browser/lib/runtime-replay-events.js +144 -0
  333. package/dist/extensions/agent-browser/lib/runtime-session-identity.js +76 -0
  334. package/dist/extensions/agent-browser/lib/runtime-session-plan.js +114 -0
  335. package/dist/extensions/agent-browser/lib/runtime-session-replay.js +123 -0
  336. package/dist/extensions/agent-browser/lib/runtime-tab-correction.js +65 -0
  337. package/dist/extensions/agent-browser/lib/runtime-timeouts.js +28 -0
  338. package/dist/extensions/agent-browser/lib/runtime.js +137 -1041
  339. package/dist/extensions/agent-browser/lib/session-identity.js +51 -0
  340. package/dist/extensions/agent-browser/lib/session-page-observation.js +357 -0
  341. package/dist/extensions/agent-browser/lib/session-page-state.js +178 -333
  342. package/dist/extensions/agent-browser/lib/session-page-types.js +1 -0
  343. package/dist/extensions/agent-browser/lib/temp-artifact-budget.js +78 -0
  344. package/dist/extensions/agent-browser/lib/temp-mutation-queue.js +7 -0
  345. package/dist/extensions/agent-browser/lib/temp-root-ownership.js +234 -0
  346. package/dist/extensions/agent-browser/lib/temp-root.js +207 -0
  347. package/dist/extensions/agent-browser/lib/temp.js +33 -446
  348. package/dist/extensions/agent-browser/lib/tool-surface.js +94 -24
  349. package/dist/extensions/agent-browser/lib/upstream-version.js +3 -2
  350. package/dist/extensions/agent-browser/lib/web-search-providers.js +229 -0
  351. package/dist/extensions/agent-browser/lib/web-search-request.js +108 -0
  352. package/dist/extensions/agent-browser/lib/web-search-results.js +281 -0
  353. package/dist/extensions/agent-browser/lib/web-search-schema.js +82 -0
  354. package/dist/extensions/agent-browser/lib/web-search.js +109 -617
  355. package/dist/extensions/agent-browser/lib/webmcp-observation.js +13 -6
  356. package/dist/extensions/agent-browser/lib/windows-stock-launcher.js +63 -37
  357. package/dist/extensions/agent-browser/script-worker.js +80 -43
  358. package/dist/scripts/agent-browser-target.mjs +4 -2
  359. package/docs/ARCHITECTURE.md +17 -5
  360. package/docs/CODE_QUALITY.md +242 -0
  361. package/docs/COMMAND_REFERENCE.md +251 -220
  362. package/docs/ELECTRON.md +53 -44
  363. package/docs/RELEASE.md +18 -15
  364. package/docs/REQUIREMENTS.md +1 -0
  365. package/docs/SUPPORT_MATRIX.md +76 -75
  366. package/docs/TOOL_CONTRACT.md +145 -116
  367. package/docs/platform-smoke.md +5 -5
  368. package/package.json +143 -120
  369. package/scripts/agent-browser-capability-baseline.mjs +361 -957
  370. package/scripts/agent-browser-target.mjs +6 -2
  371. package/scripts/build.mjs +37 -8
  372. package/scripts/capability-core-commands.mjs +193 -0
  373. package/scripts/capability-options.mjs +283 -0
  374. package/scripts/capability-samples.mjs +133 -0
  375. package/scripts/capability-section.mjs +11 -0
  376. package/scripts/config.mjs +213 -114
  377. package/scripts/convert-browser-session.mjs +30 -9
  378. package/scripts/doctor-sources.mjs +195 -0
  379. package/scripts/doctor.mjs +92 -247
  380. package/scripts/platform-smoke/artifacts.mjs +38 -11
  381. package/scripts/platform-smoke/commands.mjs +104 -0
  382. package/scripts/platform-smoke/crabbox-runner.mjs +167 -80
  383. package/scripts/platform-smoke/doctor-support.mjs +157 -0
  384. package/scripts/platform-smoke/doctor-windows.mjs +230 -0
  385. package/scripts/platform-smoke/doctor.mjs +212 -320
  386. package/scripts/platform-smoke/lease-evidence.mjs +134 -0
  387. package/scripts/platform-smoke/suite-checks.mjs +98 -0
  388. package/scripts/platform-smoke/suite-evidence.mjs +281 -0
  389. package/scripts/platform-smoke/targets.mjs +158 -472
  390. package/scripts/platform-smoke.mjs +55 -40
  391. package/scripts/prepare.mjs +16 -7
@@ -1,24 +1,40 @@
1
1
  import { Text } from "@earendil-works/pi-tui";
2
2
  import { formatAgentBrowserRenderCall } from "./pi-tool-rendering.js";
3
3
  import { JsonSchema } from "./json-schema.js";
4
- import { AGENT_BROWSER_NAMESPACE, AGENT_BROWSER_OUTPUT_SCHEMA, finalizeAgentBrowserNativeResult } from "./native-output.js";
4
+ import { AGENT_BROWSER_NAMESPACE, AGENT_BROWSER_OUTPUT_SCHEMA, finalizeAgentBrowserNativeResult, } from "./native-output.js";
5
5
  import { AGENT_BROWSER_PARAMS, AGENT_BROWSER_CODE_PARAMS, AGENT_BROWSER_ACTION_PARAMS, AGENT_BROWSER_QA_PARAMS, AGENT_BROWSER_ELECTRON_PARAMS, AGENT_BROWSER_SOURCE_PARAMS, AGENT_BROWSER_NETWORK_SOURCE_PARAMS, AGENT_BROWSER_TOOLS_PARAMS, } from "./input-modes/params.js";
6
6
  export const AGENT_BROWSER_TOOL_INVENTORY = {
7
- action: { name: "agent_browser_action", description: "Click, check, fill, or select a unique accessible target using stable locators or current refs." },
8
- qa: { name: "agent_browser_qa", description: "Check a URL or attached page with visible assertions and a diagnostic pass/fail verdict." },
9
- electron: { name: "agent_browser_electron", description: "Discover, launch, probe, and clean up owned Electron desktop applications." },
10
- source: { name: "agent_browser_source", description: "Find experimental DOM/React/local-source candidates with a bounded workspace scan." },
11
- network: { name: "agent_browser_network_source", description: "Correlate failed requests with initiator and local-source candidates." },
7
+ action: {
8
+ name: "agent_browser_action",
9
+ description: "Click, check, fill, or select a unique accessible target using stable locators or current refs.",
10
+ },
11
+ qa: {
12
+ name: "agent_browser_qa",
13
+ description: "Check a URL or attached page with visible assertions and a diagnostic pass/fail verdict.",
14
+ },
15
+ electron: {
16
+ name: "agent_browser_electron",
17
+ description: "Discover, launch, probe, and clean up owned Electron desktop applications.",
18
+ },
19
+ source: {
20
+ name: "agent_browser_source",
21
+ description: "Find experimental DOM/React/local-source candidates with a bounded workspace scan.",
22
+ },
23
+ network: {
24
+ name: "agent_browser_network_source",
25
+ description: "Correlate failed requests with initiator and local-source candidates.",
26
+ },
12
27
  };
13
28
  export const AGENT_BROWSER_INSTRUCTION_GROUP = {
14
29
  name: "browser",
15
30
  description: "Search the web, browse and interact with pages, verify browser UI, and inspect Electron apps.",
16
31
  };
17
32
  const advancedNames = new Set(Object.values(AGENT_BROWSER_TOOL_INVENTORY).map(({ name }) => name));
18
- /** Register once; advanced calls adapt only their input shape and reuse the ordinary executor. */
19
- export function registerAgentBrowserToolSurface(pi, options) {
20
- const execute = async (id, params, signal, onUpdate, ctx) => finalizeAgentBrowserNativeResult(await options.execute(id, params, signal, onUpdate, ctx), params);
21
- const nativeOutput = { namespace: AGENT_BROWSER_NAMESPACE, outputSchema: AGENT_BROWSER_OUTPUT_SCHEMA };
33
+ const nativeOutput = {
34
+ namespace: AGENT_BROWSER_NAMESPACE,
35
+ outputSchema: AGENT_BROWSER_OUTPUT_SCHEMA,
36
+ };
37
+ function registerCoreTools(pi, options, execute) {
22
38
  pi.registerTool({
23
39
  name: "agent_browser",
24
40
  ...nativeOutput,
@@ -47,6 +63,8 @@ export function registerAgentBrowserToolSurface(pi, options) {
47
63
  },
48
64
  renderResult: options.renderResult,
49
65
  });
66
+ }
67
+ function registerActionTool(pi, options, execute) {
50
68
  pi.registerTool({
51
69
  ...AGENT_BROWSER_TOOL_INVENTORY.action,
52
70
  ...nativeOutput,
@@ -59,6 +77,8 @@ export function registerAgentBrowserToolSurface(pi, options) {
59
77
  return execute(id, { semanticAction, outputPath, timeoutMs }, signal, onUpdate, ctx);
60
78
  },
61
79
  });
80
+ }
81
+ function registerQaTool(pi, options, execute) {
62
82
  pi.registerTool({
63
83
  ...AGENT_BROWSER_TOOL_INVENTORY.qa,
64
84
  ...nativeOutput,
@@ -71,6 +91,8 @@ export function registerAgentBrowserToolSurface(pi, options) {
71
91
  return execute(id, { qa, outputPath, timeoutMs, sessionMode }, signal, onUpdate, ctx);
72
92
  },
73
93
  });
94
+ }
95
+ function registerElectronTool(pi, options, execute) {
74
96
  pi.registerTool({
75
97
  ...AGENT_BROWSER_TOOL_INVENTORY.electron,
76
98
  ...nativeOutput,
@@ -83,6 +105,8 @@ export function registerAgentBrowserToolSurface(pi, options) {
83
105
  return execute(id, { electron, outputPath }, signal, onUpdate, ctx);
84
106
  },
85
107
  });
108
+ }
109
+ function registerSourceTools(pi, options, execute) {
86
110
  pi.registerTool({
87
111
  ...AGENT_BROWSER_TOOL_INVENTORY.source,
88
112
  ...nativeOutput,
@@ -107,13 +131,24 @@ export function registerAgentBrowserToolSurface(pi, options) {
107
131
  return execute(id, { networkSourceLookup, outputPath, timeoutMs, sessionMode }, signal, onUpdate, ctx);
108
132
  },
109
133
  });
134
+ }
135
+ function toolStatus(available, active) {
136
+ if (!available) {
137
+ return "unavailable in this Pi tool selection";
138
+ }
139
+ return active ? "active" : "inactive";
140
+ }
141
+ function registerToolLoader(pi) {
110
142
  pi.registerTool({
111
143
  name: "agent_browser_tools",
112
144
  namespace: AGENT_BROWSER_NAMESPACE,
113
145
  outputSchema: JsonSchema.Object({
114
146
  inventory: JsonSchema.Array(JsonSchema.Object({
115
- key: JsonSchema.String(), name: JsonSchema.String(), description: JsonSchema.String(),
116
- available: JsonSchema.Boolean(), active: JsonSchema.Boolean(),
147
+ key: JsonSchema.String(),
148
+ name: JsonSchema.String(),
149
+ description: JsonSchema.String(),
150
+ available: JsonSchema.Boolean(),
151
+ active: JsonSchema.Boolean(),
117
152
  })),
118
153
  added: JsonSchema.Array(JsonSchema.String()),
119
154
  }),
@@ -124,46 +159,81 @@ export function registerAgentBrowserToolSurface(pi, options) {
124
159
  async execute(_id, params) {
125
160
  const available = new Set(pi.getAllTools().map(({ name }) => name));
126
161
  const active = new Set(pi.getActiveTools());
127
- const added = (params.enable ?? []).map((key) => AGENT_BROWSER_TOOL_INVENTORY[key].name)
162
+ const added = (params.enable ?? [])
163
+ .map((key) => AGENT_BROWSER_TOOL_INVENTORY[key].name)
128
164
  .filter((name) => available.has(name) && !active.has(name));
129
- if (added.length > 0)
165
+ if (added.length > 0) {
130
166
  pi.setActiveTools([...new Set([...active, ...added])]);
167
+ }
131
168
  const current = new Set(pi.getActiveTools());
132
169
  const inventory = Object.entries(AGENT_BROWSER_TOOL_INVENTORY).map(([key, tool]) => ({
133
- key, ...tool, available: available.has(tool.name), active: current.has(tool.name),
170
+ key,
171
+ name: tool.name,
172
+ description: tool.description,
173
+ available: available.has(tool.name),
174
+ active: current.has(tool.name),
134
175
  }));
135
176
  return {
136
- content: [{ type: "text", text: inventory.map((tool) => `${tool.key}: ${tool.name} (${!tool.available ? "unavailable in this Pi tool selection" : tool.active ? "active" : "inactive"}) — ${tool.description}`).join("\n") }],
177
+ content: [
178
+ {
179
+ type: "text",
180
+ text: inventory
181
+ .map((tool) => `${tool.key}: ${tool.name} (${toolStatus(tool.available, tool.active)}) — ${tool.description}`)
182
+ .join("\n"),
183
+ },
184
+ ],
137
185
  details: { inventory, added: [...new Set(added)] },
138
186
  structuredContent: { inventory, added: [...new Set(added)] },
139
187
  };
140
188
  },
141
189
  });
190
+ }
191
+ function hasExplicitToolSelection() {
192
+ const argv = process.argv.slice(2);
193
+ const delimiter = argv.indexOf("--");
194
+ return (delimiter < 0 ? argv : argv.slice(0, delimiter)).some((arg) => arg === "--tools" || arg === "-t");
195
+ }
196
+ function registerAdvancedToolReplay(pi) {
142
197
  pi.on("session_start", async (_event, ctx) => {
143
198
  // ponytail: official 1.0 SDK supplies initialActiveToolNames on resume, bypassing
144
199
  // native transcript restoration. Remove this additive fallback once the supported SDK restores it.
145
- const argv = process.argv.slice(2);
146
- const delimiter = argv.indexOf("--");
147
- if ((delimiter < 0 ? argv : argv.slice(0, delimiter)).some((arg) => arg === "--tools" || arg === "-t"))
200
+ if (hasExplicitToolSelection()) {
148
201
  return;
202
+ }
149
203
  // A host-filtered catalog is an explicit selection, not our default surface.
150
204
  const available = new Set(pi.getAllTools().map(({ name }) => name));
151
- if (!["agent_browser", "agent_browser_code", "agent_browser_tools", ...advancedNames].every(name => available.has(name)))
205
+ if (!["agent_browser", "agent_browser_code", "agent_browser_tools", ...advancedNames].every((name) => available.has(name))) {
152
206
  return;
207
+ }
153
208
  // Native dynamic imports bypass Pi's host-package aliases in consumer installs.
154
209
  // Only tool names are needed; replay native deltas without requiring the optional pi-ai peer.
155
210
  const restored = new Set();
156
211
  for (const message of ctx.sessionManager.buildSessionProjection().messages) {
157
- if (message.role !== "system")
212
+ if (message.role !== "system") {
158
213
  continue;
159
- for (const removed of message.toolsRemoved ?? [])
214
+ }
215
+ for (const removed of message.toolsRemoved ?? []) {
160
216
  restored.delete(removed.name);
161
- for (const added of message.toolsAdded ?? [])
217
+ }
218
+ for (const added of message.toolsAdded ?? []) {
162
219
  restored.add(added.name);
220
+ }
163
221
  }
164
222
  const active = new Set(pi.getActiveTools());
165
223
  const added = [...restored].filter((name) => advancedNames.has(name) && available.has(name) && !active.has(name));
166
- if (added.length > 0)
224
+ if (added.length > 0) {
167
225
  pi.setActiveTools([...active, ...added]);
226
+ }
168
227
  });
169
228
  }
229
+ /** Register once; adapters retain native execution, output, activation, and replay contracts. */
230
+ export function registerAgentBrowserToolSurface(pi, options) {
231
+ const execute = async (id, params, signal, onUpdate, ctx) => finalizeAgentBrowserNativeResult(await options.execute(id, params, signal, onUpdate, ctx), params);
232
+ registerCoreTools(pi, options, execute);
233
+ registerActionTool(pi, options, execute);
234
+ registerQaTool(pi, options, execute);
235
+ registerElectronTool(pi, options, execute);
236
+ registerSourceTools(pi, options, execute);
237
+ registerToolLoader(pi);
238
+ registerAdvancedToolReplay(pi);
239
+ }
@@ -6,9 +6,10 @@ export function parseAgentBrowserVersionOutput(stdout) {
6
6
  }
7
7
  export function getAgentBrowserVersionValidationError(stdout) {
8
8
  const observed = parseAgentBrowserVersionOutput(stdout);
9
- if (observed && isSupportedAgentBrowserVersion(observed))
9
+ if (observed !== undefined && isSupportedAgentBrowserVersion(observed)) {
10
10
  return undefined;
11
- return observed
11
+ }
12
+ return observed !== undefined
12
13
  ? `Installed agent-browser ${observed} is unsupported; stable versions must be at least ${MINIMUM_AGENT_BROWSER_VERSION_LABEL}. Install ${TARGET_AGENT_BROWSER_VERSION_LABEL} (recommended), run pi-agent-browser-doctor, then reload Pi.`
13
14
  : `agent-browser --version returned an unrecognized value; expected ${SUPPORTED_AGENT_BROWSER_VERSION_LABEL}. Run pi-agent-browser-doctor and install a supported upstream version.`;
14
15
  }
@@ -0,0 +1,229 @@
1
+ import { isRecord } from "./parsing.js";
2
+ import { fetchSearchJson, SEARCH_REQUEST_TIMEOUT_MS } from "./web-search-request.js";
3
+ import { cleanSearchText, normalizeBraveSearchResult, normalizeExaSearchResult, parseBraveSearchResponse, parseExaSearchResponse, } from "./web-search-results.js";
4
+ const BRAVE_SEARCH_ENDPOINT = "https://api.search.brave.com/res/v1/web/search";
5
+ const EXA_SEARCH_ENDPOINT = "https://api.exa.ai/search";
6
+ const EXA_DYNAMIC_HIGHLIGHTS_BETA = "dynamic-highlights-2026-08-28";
7
+ export const EXA_SEARCH_SYSTEM_PROMPT = "Prefer primary, official sources. Respect any requested version or date. Avoid duplicate or equivalent results.";
8
+ /** Local validation/config failures, not provider outages; reported as `validation-error`. */
9
+ export class WebSearchLocalError extends Error {
10
+ }
11
+ export function buildBraveSearchUrl(params) {
12
+ const url = new URL(BRAVE_SEARCH_ENDPOINT);
13
+ url.searchParams.set("q", params.query);
14
+ url.searchParams.set("count", String(params.count));
15
+ url.searchParams.set("offset", String(params.offset));
16
+ if (params.country !== undefined && params.country.length > 0) {
17
+ url.searchParams.set("country", params.country.toUpperCase());
18
+ }
19
+ if (params.searchLang !== undefined && params.searchLang.length > 0) {
20
+ url.searchParams.set("search_lang", params.searchLang);
21
+ }
22
+ if (params.safesearch !== undefined) {
23
+ url.searchParams.set("safesearch", params.safesearch);
24
+ }
25
+ if (params.freshness !== undefined) {
26
+ url.searchParams.set("freshness", params.freshness);
27
+ }
28
+ return url;
29
+ }
30
+ const FRESHNESS_DAYS = { pd: 1, pw: 7, pm: 31, py: 365 };
31
+ function getStartPublishedDate(freshness, now) {
32
+ if (freshness === undefined) {
33
+ return;
34
+ }
35
+ return new Date(now().getTime() - FRESHNESS_DAYS[freshness] * 24 * 60 * 60 * 1000).toISOString();
36
+ }
37
+ function hasEntries(values) {
38
+ return values !== undefined && values.length > 0;
39
+ }
40
+ function validateExaFilters(params, searchType) {
41
+ if (hasEntries(params.additionalQueries) && !searchType.startsWith("deep")) {
42
+ throw new WebSearchLocalError(`additionalQueries requires deep-lite, deep, or deep-reasoning; received ${searchType}.`);
43
+ }
44
+ if ((params.category === "company" || params.category === "people") &&
45
+ (params.freshness !== undefined || hasEntries(params.excludeDomains))) {
46
+ throw new WebSearchLocalError(`category ${params.category} cannot be combined with freshness or excludeDomains.`);
47
+ }
48
+ }
49
+ function exaContentFilters(params) {
50
+ return {
51
+ ...(hasEntries(params.includeDomains) ? { includeDomains: params.includeDomains } : {}),
52
+ ...(hasEntries(params.excludeDomains) ? { excludeDomains: params.excludeDomains } : {}),
53
+ ...(hasEntries(params.additionalQueries)
54
+ ? { additionalQueries: params.additionalQueries }
55
+ : {}),
56
+ ...(params.safesearch !== undefined && params.safesearch !== "off" ? { moderation: true } : {}),
57
+ };
58
+ }
59
+ export function buildExaSearchRequestBody(params, now = () => new Date()) {
60
+ const searchType = params.searchType ?? "auto";
61
+ validateExaFilters(params, searchType);
62
+ const startPublishedDate = getStartPublishedDate(params.freshness, now);
63
+ return {
64
+ query: params.query,
65
+ type: searchType,
66
+ numResults: Math.min(params.count + params.offset, 100),
67
+ contents: { highlights: params.highlightsDynamic === true ? { dynamic: true } : true },
68
+ systemPrompt: EXA_SEARCH_SYSTEM_PROMPT,
69
+ ...(params.category !== undefined ? { category: params.category } : {}),
70
+ ...(params.country !== undefined && params.country.length > 0
71
+ ? { userLocation: params.country.toUpperCase() }
72
+ : {}),
73
+ ...exaContentFilters(params),
74
+ ...(startPublishedDate !== undefined ? { startPublishedDate } : {}),
75
+ };
76
+ }
77
+ export async function fetchBraveSearchJson(url, apiKey, signal) {
78
+ const data = await fetchSearchJson({
79
+ apiKey,
80
+ cancelMessage: "Brave search cancelled",
81
+ init: { headers: { Accept: "application/json", "X-Subscription-Token": apiKey } },
82
+ invalidJsonMessage: "Brave search returned invalid JSON",
83
+ provider: "brave",
84
+ request: url,
85
+ signal,
86
+ timeoutMessage: "Brave search timed out",
87
+ timeoutMs: SEARCH_REQUEST_TIMEOUT_MS,
88
+ });
89
+ return parseBraveSearchResponse(data);
90
+ }
91
+ function getExaRequestTimeoutMs(searchType) {
92
+ switch (searchType) {
93
+ case "deep-lite":
94
+ return 45_000;
95
+ case "deep":
96
+ return 60_000;
97
+ case "deep-reasoning":
98
+ return 90_000;
99
+ case "auto":
100
+ case "fast":
101
+ case "instant":
102
+ case undefined:
103
+ return SEARCH_REQUEST_TIMEOUT_MS;
104
+ }
105
+ }
106
+ function usesDynamicHighlights(body) {
107
+ const contents = body.contents;
108
+ return (isRecord(contents) &&
109
+ !Array.isArray(contents) &&
110
+ isRecord(contents.highlights) &&
111
+ !Array.isArray(contents.highlights) &&
112
+ contents.highlights.dynamic === true);
113
+ }
114
+ export async function fetchExaSearchJson(body, apiKey, signal, timeoutMs = SEARCH_REQUEST_TIMEOUT_MS) {
115
+ const data = await fetchSearchJson({
116
+ apiKey,
117
+ cancelMessage: "Exa search cancelled",
118
+ init: {
119
+ body: JSON.stringify(body),
120
+ headers: {
121
+ Accept: "application/json",
122
+ "Content-Type": "application/json",
123
+ "x-api-key": apiKey,
124
+ ...(usesDynamicHighlights(body) ? { "Exa-Beta": EXA_DYNAMIC_HIGHLIGHTS_BETA } : {}),
125
+ },
126
+ method: "POST",
127
+ },
128
+ invalidJsonMessage: "Exa search returned invalid JSON",
129
+ provider: "exa",
130
+ request: EXA_SEARCH_ENDPOINT,
131
+ signal,
132
+ timeoutMessage: "Exa search timed out",
133
+ timeoutMs,
134
+ });
135
+ return parseExaSearchResponse(data);
136
+ }
137
+ const BRAVE_WEB_SEARCH_ADAPTER = {
138
+ provider: "brave",
139
+ buildRequest(params) {
140
+ // Brave offsets count pages; fetch the prefix and slice by result like Exa.
141
+ return buildBraveSearchUrl({ ...params, count: params.count + params.offset, offset: 0 });
142
+ },
143
+ fetchJson: fetchBraveSearchJson,
144
+ normalizeResponse(response, params) {
145
+ return {
146
+ results: (response.web?.results ?? [])
147
+ .map(normalizeBraveSearchResult)
148
+ .filter((result) => result !== undefined)
149
+ .slice(params.offset, params.offset + params.count),
150
+ returnedQuery: cleanSearchText(response.query?.altered, 300) ??
151
+ cleanSearchText(response.query?.original, 300) ??
152
+ params.query,
153
+ };
154
+ },
155
+ };
156
+ const EXA_WEB_SEARCH_ADAPTER = {
157
+ provider: "exa",
158
+ buildRequest(params) {
159
+ return {
160
+ body: buildExaSearchRequestBody(params),
161
+ timeoutMs: getExaRequestTimeoutMs(params.searchType ?? "auto"),
162
+ };
163
+ },
164
+ fetchJson(request, apiKey, signal) {
165
+ return fetchExaSearchJson(request.body, apiKey, signal, request.timeoutMs);
166
+ },
167
+ normalizeResponse(response, params) {
168
+ return {
169
+ extraDetails: {
170
+ requestId: cleanSearchText(response.requestId, 120),
171
+ searchType: params.searchType ?? "auto",
172
+ },
173
+ results: (response.results ?? [])
174
+ .map(normalizeExaSearchResult)
175
+ .filter((result) => result !== undefined)
176
+ .slice(params.offset, params.offset + params.count),
177
+ returnedQuery: params.query,
178
+ };
179
+ },
180
+ };
181
+ // Dynamic public callers supply unknown inputs; validate them before entering typed providers.
182
+ const WEB_SEARCH_PROVIDER_ADAPTERS = {
183
+ brave: {
184
+ provider: "brave",
185
+ buildRequest: BRAVE_WEB_SEARCH_ADAPTER.buildRequest,
186
+ fetchJson(request, apiKey, signal) {
187
+ if (!(request instanceof URL)) {
188
+ throw new Error("Brave search request must be a URL");
189
+ }
190
+ return BRAVE_WEB_SEARCH_ADAPTER.fetchJson(request, apiKey, signal);
191
+ },
192
+ normalizeResponse(response, params) {
193
+ return BRAVE_WEB_SEARCH_ADAPTER.normalizeResponse(parseBraveSearchResponse(response), params);
194
+ },
195
+ },
196
+ exa: {
197
+ provider: "exa",
198
+ buildRequest: EXA_WEB_SEARCH_ADAPTER.buildRequest,
199
+ fetchJson(request, apiKey, signal) {
200
+ if (!isRecord(request) ||
201
+ !isRecord(request.body) ||
202
+ typeof request.timeoutMs !== "number") {
203
+ throw new Error("Exa search request must contain a body and timeout");
204
+ }
205
+ return fetchExaSearchJson(request.body, apiKey, signal, request.timeoutMs);
206
+ },
207
+ normalizeResponse(response, params) {
208
+ return EXA_WEB_SEARCH_ADAPTER.normalizeResponse(parseExaSearchResponse(response), params);
209
+ },
210
+ },
211
+ };
212
+ export function getWebSearchProviderAdapter(provider) {
213
+ return WEB_SEARCH_PROVIDER_ADAPTERS[provider];
214
+ }
215
+ /** Build before queueing so local validation fails without consuming a request slot. */
216
+ export function prepareWebSearchRequest(provider, params, apiKey, signal) {
217
+ if (provider === "exa") {
218
+ const request = EXA_WEB_SEARCH_ADAPTER.buildRequest(params);
219
+ return async () => {
220
+ const response = await EXA_WEB_SEARCH_ADAPTER.fetchJson(request, apiKey, signal);
221
+ return EXA_WEB_SEARCH_ADAPTER.normalizeResponse(response, params);
222
+ };
223
+ }
224
+ const request = BRAVE_WEB_SEARCH_ADAPTER.buildRequest(params);
225
+ return async () => {
226
+ const response = await BRAVE_WEB_SEARCH_ADAPTER.fetchJson(request, apiKey, signal);
227
+ return BRAVE_WEB_SEARCH_ADAPTER.normalizeResponse(response, params);
228
+ };
229
+ }
@@ -0,0 +1,108 @@
1
+ import { cleanSearchText, getProviderLabel } from "./web-search-results.js";
2
+ export const SEARCH_REQUEST_TIMEOUT_MS = 15_000;
3
+ export const WEB_SEARCH_MIN_REQUEST_INTERVAL_MS = 1_100;
4
+ function sleepWithAbort(ms, signal) {
5
+ if (ms <= 0) {
6
+ return Promise.resolve();
7
+ }
8
+ if (signal?.aborted === true) {
9
+ const reason = signal.reason;
10
+ // A caller-owned abort reason may be non-Error; preserve the original reason.
11
+ // oxlint-disable-next-line typescript/prefer-promise-reject-errors
12
+ return Promise.reject(reason ?? new Error("Web search cancelled"));
13
+ }
14
+ return new Promise((resolve, reject) => {
15
+ const cleanup = () => signal?.removeEventListener("abort", abort);
16
+ const timeout = setTimeout(() => {
17
+ cleanup();
18
+ resolve();
19
+ }, ms);
20
+ const abort = () => {
21
+ clearTimeout(timeout);
22
+ cleanup();
23
+ const reason = signal?.reason;
24
+ // A caller-owned abort reason may be non-Error; preserve the original reason.
25
+ // oxlint-disable-next-line typescript/prefer-promise-reject-errors
26
+ reject(reason ?? new Error("Web search cancelled"));
27
+ };
28
+ signal?.addEventListener("abort", abort, { once: true });
29
+ });
30
+ }
31
+ export class WebSearchRequestGate {
32
+ now;
33
+ sleep;
34
+ lastRequestStartedAt = 0;
35
+ tail = Promise.resolve();
36
+ constructor(now = Date.now, sleep = sleepWithAbort) {
37
+ this.now = now;
38
+ this.sleep = sleep;
39
+ }
40
+ run(signal, task) {
41
+ const runTask = async () => {
42
+ const elapsedMs = this.lastRequestStartedAt === 0
43
+ ? WEB_SEARCH_MIN_REQUEST_INTERVAL_MS
44
+ : this.now() - this.lastRequestStartedAt;
45
+ const waitMs = Math.max(0, WEB_SEARCH_MIN_REQUEST_INTERVAL_MS - elapsedMs);
46
+ if (waitMs > 0) {
47
+ await this.sleep(waitMs, signal);
48
+ }
49
+ if (signal?.aborted === true) {
50
+ signal.throwIfAborted();
51
+ }
52
+ this.lastRequestStartedAt = this.now();
53
+ return task();
54
+ };
55
+ const result = this.tail.then(runTask, runTask);
56
+ this.tail = result.catch(() => {
57
+ /* Failed requests release the queue; callers retain the original rejection. */
58
+ });
59
+ return result;
60
+ }
61
+ }
62
+ function redactSearchSecret(text, apiKey) {
63
+ return apiKey.length > 0 ? text.split(apiKey).join("[REDACTED]") : text;
64
+ }
65
+ function formatSearchHttpError(options) {
66
+ const { provider, status, statusText, body, apiKey } = options;
67
+ const providerLabel = getProviderLabel(provider);
68
+ const errorPreview = cleanSearchText(redactSearchSecret(body, apiKey), 300);
69
+ if (status === 429) {
70
+ const preview = errorPreview !== undefined
71
+ ? ` Upstream details: ${redactSearchSecret(errorPreview, apiKey)}`
72
+ : "";
73
+ return `${providerLabel} search rate limit exceeded (HTTP 429). Do not issue parallel or repeated agent_browser_web_search calls; use one high-signal query, inspect those results, then wait before retrying or ask the user to adjust their ${providerLabel} API plan/limits.${preview}`;
74
+ }
75
+ return `${providerLabel} search failed with HTTP ${status}: ${errorPreview !== undefined ? redactSearchSecret(errorPreview, apiKey) : statusText}`;
76
+ }
77
+ export async function fetchSearchJson(options) {
78
+ if (options.signal?.aborted === true) {
79
+ options.signal.throwIfAborted();
80
+ }
81
+ const controller = new AbortController();
82
+ const timeout = setTimeout(() => controller.abort(new Error(options.timeoutMessage)), options.timeoutMs);
83
+ const abort = () => controller.abort(options.signal?.reason ?? new Error(options.cancelMessage));
84
+ options.signal?.addEventListener("abort", abort, { once: true });
85
+ try {
86
+ const response = await fetch(options.request, { ...options.init, signal: controller.signal });
87
+ const text = await response.text();
88
+ if (!response.ok) {
89
+ throw new Error(formatSearchHttpError({
90
+ provider: options.provider,
91
+ status: response.status,
92
+ statusText: response.statusText,
93
+ body: text,
94
+ apiKey: options.apiKey,
95
+ }));
96
+ }
97
+ try {
98
+ return JSON.parse(text);
99
+ }
100
+ catch (error) {
101
+ throw new Error(`${options.invalidJsonMessage}: ${error instanceof Error ? error.message : "Unknown JSON parse failure"}`, { cause: error });
102
+ }
103
+ }
104
+ finally {
105
+ clearTimeout(timeout);
106
+ options.signal?.removeEventListener("abort", abort);
107
+ }
108
+ }