agent-browser 0.3.0 → 0.3.2

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 (220) hide show
  1. package/bin/agent-browser +0 -0
  2. package/bin/agent-browser-darwin-arm64 +0 -0
  3. package/bin/agent-browser-darwin-x64 +0 -0
  4. package/bin/agent-browser-linux-arm64 +0 -0
  5. package/bin/agent-browser-linux-x64 +0 -0
  6. package/bin/agent-browser.cmd +35 -0
  7. package/dist/cli-light.d.ts +1 -1
  8. package/dist/cli-light.js +1 -1
  9. package/package.json +10 -4
  10. package/scripts/build-all-platforms.sh +68 -0
  11. package/scripts/copy-native.js +35 -0
  12. package/scripts/postinstall.js +113 -15
  13. package/.prettierrc +0 -7
  14. package/AGENTS.md +0 -26
  15. package/benchmark/benchmark.ts +0 -521
  16. package/benchmark/run.ts +0 -322
  17. package/cli/Cargo.lock +0 -114
  18. package/cli/Cargo.toml +0 -17
  19. package/cli/src/main.rs +0 -332
  20. package/cli/target/.rustc_info.json +0 -1
  21. package/cli/target/CACHEDIR.TAG +0 -3
  22. package/cli/target/release/.cargo-lock +0 -0
  23. package/cli/target/release/.fingerprint/agent-browser-5894536b887e2ce7/bin-agent-browser +0 -1
  24. package/cli/target/release/.fingerprint/agent-browser-5894536b887e2ce7/bin-agent-browser.json +0 -1
  25. package/cli/target/release/.fingerprint/agent-browser-5894536b887e2ce7/dep-bin-agent-browser +0 -0
  26. package/cli/target/release/.fingerprint/agent-browser-5894536b887e2ce7/invoked.timestamp +0 -1
  27. package/cli/target/release/.fingerprint/agent-browser-5894536b887e2ce7/output-bin-agent-browser +0 -2
  28. package/cli/target/release/.fingerprint/itoa-653b9192107a1caa/dep-lib-itoa +0 -0
  29. package/cli/target/release/.fingerprint/itoa-653b9192107a1caa/invoked.timestamp +0 -1
  30. package/cli/target/release/.fingerprint/itoa-653b9192107a1caa/lib-itoa +0 -1
  31. package/cli/target/release/.fingerprint/itoa-653b9192107a1caa/lib-itoa.json +0 -1
  32. package/cli/target/release/.fingerprint/libc-0303d277881093f4/build-script-build-script-build +0 -1
  33. package/cli/target/release/.fingerprint/libc-0303d277881093f4/build-script-build-script-build.json +0 -1
  34. package/cli/target/release/.fingerprint/libc-0303d277881093f4/dep-build-script-build-script-build +0 -0
  35. package/cli/target/release/.fingerprint/libc-0303d277881093f4/invoked.timestamp +0 -1
  36. package/cli/target/release/.fingerprint/libc-b8c0d8e35a1980d3/run-build-script-build-script-build +0 -1
  37. package/cli/target/release/.fingerprint/libc-b8c0d8e35a1980d3/run-build-script-build-script-build.json +0 -1
  38. package/cli/target/release/.fingerprint/libc-d843359d3dd4757b/dep-lib-libc +0 -0
  39. package/cli/target/release/.fingerprint/libc-d843359d3dd4757b/invoked.timestamp +0 -1
  40. package/cli/target/release/.fingerprint/libc-d843359d3dd4757b/lib-libc +0 -1
  41. package/cli/target/release/.fingerprint/libc-d843359d3dd4757b/lib-libc.json +0 -1
  42. package/cli/target/release/.fingerprint/memchr-dcaf8011940d18dd/dep-lib-memchr +0 -0
  43. package/cli/target/release/.fingerprint/memchr-dcaf8011940d18dd/invoked.timestamp +0 -1
  44. package/cli/target/release/.fingerprint/memchr-dcaf8011940d18dd/lib-memchr +0 -1
  45. package/cli/target/release/.fingerprint/memchr-dcaf8011940d18dd/lib-memchr.json +0 -1
  46. package/cli/target/release/.fingerprint/proc-macro2-291b57751730d5b3/build-script-build-script-build +0 -1
  47. package/cli/target/release/.fingerprint/proc-macro2-291b57751730d5b3/build-script-build-script-build.json +0 -1
  48. package/cli/target/release/.fingerprint/proc-macro2-291b57751730d5b3/dep-build-script-build-script-build +0 -0
  49. package/cli/target/release/.fingerprint/proc-macro2-291b57751730d5b3/invoked.timestamp +0 -1
  50. package/cli/target/release/.fingerprint/proc-macro2-a753b344a6b4aa98/dep-lib-proc_macro2 +0 -0
  51. package/cli/target/release/.fingerprint/proc-macro2-a753b344a6b4aa98/invoked.timestamp +0 -1
  52. package/cli/target/release/.fingerprint/proc-macro2-a753b344a6b4aa98/lib-proc_macro2 +0 -1
  53. package/cli/target/release/.fingerprint/proc-macro2-a753b344a6b4aa98/lib-proc_macro2.json +0 -1
  54. package/cli/target/release/.fingerprint/proc-macro2-fc2999f6676f03db/run-build-script-build-script-build +0 -1
  55. package/cli/target/release/.fingerprint/proc-macro2-fc2999f6676f03db/run-build-script-build-script-build.json +0 -1
  56. package/cli/target/release/.fingerprint/quote-352ae41707d371c9/run-build-script-build-script-build +0 -1
  57. package/cli/target/release/.fingerprint/quote-352ae41707d371c9/run-build-script-build-script-build.json +0 -1
  58. package/cli/target/release/.fingerprint/quote-7d13be3cbe4f9de4/build-script-build-script-build +0 -1
  59. package/cli/target/release/.fingerprint/quote-7d13be3cbe4f9de4/build-script-build-script-build.json +0 -1
  60. package/cli/target/release/.fingerprint/quote-7d13be3cbe4f9de4/dep-build-script-build-script-build +0 -0
  61. package/cli/target/release/.fingerprint/quote-7d13be3cbe4f9de4/invoked.timestamp +0 -1
  62. package/cli/target/release/.fingerprint/quote-833e6725e0f7d298/dep-lib-quote +0 -0
  63. package/cli/target/release/.fingerprint/quote-833e6725e0f7d298/invoked.timestamp +0 -1
  64. package/cli/target/release/.fingerprint/quote-833e6725e0f7d298/lib-quote +0 -1
  65. package/cli/target/release/.fingerprint/quote-833e6725e0f7d298/lib-quote.json +0 -1
  66. package/cli/target/release/.fingerprint/serde-b8c046c16de48f41/run-build-script-build-script-build +0 -1
  67. package/cli/target/release/.fingerprint/serde-b8c046c16de48f41/run-build-script-build-script-build.json +0 -1
  68. package/cli/target/release/.fingerprint/serde-d35d32ab52b82a81/build-script-build-script-build +0 -1
  69. package/cli/target/release/.fingerprint/serde-d35d32ab52b82a81/build-script-build-script-build.json +0 -1
  70. package/cli/target/release/.fingerprint/serde-d35d32ab52b82a81/dep-build-script-build-script-build +0 -0
  71. package/cli/target/release/.fingerprint/serde-d35d32ab52b82a81/invoked.timestamp +0 -1
  72. package/cli/target/release/.fingerprint/serde-d6fb44202dad3efd/dep-lib-serde +0 -0
  73. package/cli/target/release/.fingerprint/serde-d6fb44202dad3efd/invoked.timestamp +0 -1
  74. package/cli/target/release/.fingerprint/serde-d6fb44202dad3efd/lib-serde +0 -1
  75. package/cli/target/release/.fingerprint/serde-d6fb44202dad3efd/lib-serde.json +0 -1
  76. package/cli/target/release/.fingerprint/serde_core-0f7ba2581c8c0423/dep-lib-serde_core +0 -0
  77. package/cli/target/release/.fingerprint/serde_core-0f7ba2581c8c0423/invoked.timestamp +0 -1
  78. package/cli/target/release/.fingerprint/serde_core-0f7ba2581c8c0423/lib-serde_core +0 -1
  79. package/cli/target/release/.fingerprint/serde_core-0f7ba2581c8c0423/lib-serde_core.json +0 -1
  80. package/cli/target/release/.fingerprint/serde_core-74db491143173930/run-build-script-build-script-build +0 -1
  81. package/cli/target/release/.fingerprint/serde_core-74db491143173930/run-build-script-build-script-build.json +0 -1
  82. package/cli/target/release/.fingerprint/serde_core-f043ae3f4b601577/build-script-build-script-build +0 -1
  83. package/cli/target/release/.fingerprint/serde_core-f043ae3f4b601577/build-script-build-script-build.json +0 -1
  84. package/cli/target/release/.fingerprint/serde_core-f043ae3f4b601577/dep-build-script-build-script-build +0 -0
  85. package/cli/target/release/.fingerprint/serde_core-f043ae3f4b601577/invoked.timestamp +0 -1
  86. package/cli/target/release/.fingerprint/serde_derive-a5d13e0e658ceae3/dep-lib-serde_derive +0 -0
  87. package/cli/target/release/.fingerprint/serde_derive-a5d13e0e658ceae3/invoked.timestamp +0 -1
  88. package/cli/target/release/.fingerprint/serde_derive-a5d13e0e658ceae3/lib-serde_derive +0 -1
  89. package/cli/target/release/.fingerprint/serde_derive-a5d13e0e658ceae3/lib-serde_derive.json +0 -1
  90. package/cli/target/release/.fingerprint/serde_json-a8467019a959068f/run-build-script-build-script-build +0 -1
  91. package/cli/target/release/.fingerprint/serde_json-a8467019a959068f/run-build-script-build-script-build.json +0 -1
  92. package/cli/target/release/.fingerprint/serde_json-bfa3f43b57842d41/build-script-build-script-build +0 -1
  93. package/cli/target/release/.fingerprint/serde_json-bfa3f43b57842d41/build-script-build-script-build.json +0 -1
  94. package/cli/target/release/.fingerprint/serde_json-bfa3f43b57842d41/dep-build-script-build-script-build +0 -0
  95. package/cli/target/release/.fingerprint/serde_json-bfa3f43b57842d41/invoked.timestamp +0 -1
  96. package/cli/target/release/.fingerprint/serde_json-f61651a65bf0eb31/dep-lib-serde_json +0 -0
  97. package/cli/target/release/.fingerprint/serde_json-f61651a65bf0eb31/invoked.timestamp +0 -1
  98. package/cli/target/release/.fingerprint/serde_json-f61651a65bf0eb31/lib-serde_json +0 -1
  99. package/cli/target/release/.fingerprint/serde_json-f61651a65bf0eb31/lib-serde_json.json +0 -1
  100. package/cli/target/release/.fingerprint/syn-6f9a22f8c7f909b0/dep-lib-syn +0 -0
  101. package/cli/target/release/.fingerprint/syn-6f9a22f8c7f909b0/invoked.timestamp +0 -1
  102. package/cli/target/release/.fingerprint/syn-6f9a22f8c7f909b0/lib-syn +0 -1
  103. package/cli/target/release/.fingerprint/syn-6f9a22f8c7f909b0/lib-syn.json +0 -1
  104. package/cli/target/release/.fingerprint/unicode-ident-60c57228d30a23d0/dep-lib-unicode_ident +0 -0
  105. package/cli/target/release/.fingerprint/unicode-ident-60c57228d30a23d0/invoked.timestamp +0 -1
  106. package/cli/target/release/.fingerprint/unicode-ident-60c57228d30a23d0/lib-unicode_ident +0 -1
  107. package/cli/target/release/.fingerprint/unicode-ident-60c57228d30a23d0/lib-unicode_ident.json +0 -1
  108. package/cli/target/release/.fingerprint/zmij-60b0e0e9d7c08f71/run-build-script-build-script-build +0 -1
  109. package/cli/target/release/.fingerprint/zmij-60b0e0e9d7c08f71/run-build-script-build-script-build.json +0 -1
  110. package/cli/target/release/.fingerprint/zmij-9501bcbd6d8b933c/dep-lib-zmij +0 -0
  111. package/cli/target/release/.fingerprint/zmij-9501bcbd6d8b933c/invoked.timestamp +0 -1
  112. package/cli/target/release/.fingerprint/zmij-9501bcbd6d8b933c/lib-zmij +0 -1
  113. package/cli/target/release/.fingerprint/zmij-9501bcbd6d8b933c/lib-zmij.json +0 -1
  114. package/cli/target/release/.fingerprint/zmij-aa602f885104061e/build-script-build-script-build +0 -1
  115. package/cli/target/release/.fingerprint/zmij-aa602f885104061e/build-script-build-script-build.json +0 -1
  116. package/cli/target/release/.fingerprint/zmij-aa602f885104061e/dep-build-script-build-script-build +0 -0
  117. package/cli/target/release/.fingerprint/zmij-aa602f885104061e/invoked.timestamp +0 -1
  118. package/cli/target/release/agent-browser +0 -0
  119. package/cli/target/release/agent-browser.d +0 -1
  120. package/cli/target/release/build/libc-0303d277881093f4/build-script-build +0 -0
  121. package/cli/target/release/build/libc-0303d277881093f4/build_script_build-0303d277881093f4 +0 -0
  122. package/cli/target/release/build/libc-0303d277881093f4/build_script_build-0303d277881093f4.d +0 -5
  123. package/cli/target/release/build/libc-b8c0d8e35a1980d3/invoked.timestamp +0 -1
  124. package/cli/target/release/build/libc-b8c0d8e35a1980d3/output +0 -25
  125. package/cli/target/release/build/libc-b8c0d8e35a1980d3/root-output +0 -1
  126. package/cli/target/release/build/libc-b8c0d8e35a1980d3/stderr +0 -0
  127. package/cli/target/release/build/proc-macro2-291b57751730d5b3/build-script-build +0 -0
  128. package/cli/target/release/build/proc-macro2-291b57751730d5b3/build_script_build-291b57751730d5b3 +0 -0
  129. package/cli/target/release/build/proc-macro2-291b57751730d5b3/build_script_build-291b57751730d5b3.d +0 -5
  130. package/cli/target/release/build/proc-macro2-fc2999f6676f03db/invoked.timestamp +0 -1
  131. package/cli/target/release/build/proc-macro2-fc2999f6676f03db/output +0 -23
  132. package/cli/target/release/build/proc-macro2-fc2999f6676f03db/root-output +0 -1
  133. package/cli/target/release/build/proc-macro2-fc2999f6676f03db/stderr +0 -0
  134. package/cli/target/release/build/quote-352ae41707d371c9/invoked.timestamp +0 -1
  135. package/cli/target/release/build/quote-352ae41707d371c9/output +0 -2
  136. package/cli/target/release/build/quote-352ae41707d371c9/root-output +0 -1
  137. package/cli/target/release/build/quote-352ae41707d371c9/stderr +0 -0
  138. package/cli/target/release/build/quote-7d13be3cbe4f9de4/build-script-build +0 -0
  139. package/cli/target/release/build/quote-7d13be3cbe4f9de4/build_script_build-7d13be3cbe4f9de4 +0 -0
  140. package/cli/target/release/build/quote-7d13be3cbe4f9de4/build_script_build-7d13be3cbe4f9de4.d +0 -5
  141. package/cli/target/release/build/serde-b8c046c16de48f41/invoked.timestamp +0 -1
  142. package/cli/target/release/build/serde-b8c046c16de48f41/out/private.rs +0 -6
  143. package/cli/target/release/build/serde-b8c046c16de48f41/output +0 -13
  144. package/cli/target/release/build/serde-b8c046c16de48f41/root-output +0 -1
  145. package/cli/target/release/build/serde-b8c046c16de48f41/stderr +0 -0
  146. package/cli/target/release/build/serde-d35d32ab52b82a81/build-script-build +0 -0
  147. package/cli/target/release/build/serde-d35d32ab52b82a81/build_script_build-d35d32ab52b82a81 +0 -0
  148. package/cli/target/release/build/serde-d35d32ab52b82a81/build_script_build-d35d32ab52b82a81.d +0 -5
  149. package/cli/target/release/build/serde_core-74db491143173930/invoked.timestamp +0 -1
  150. package/cli/target/release/build/serde_core-74db491143173930/out/private.rs +0 -5
  151. package/cli/target/release/build/serde_core-74db491143173930/output +0 -11
  152. package/cli/target/release/build/serde_core-74db491143173930/root-output +0 -1
  153. package/cli/target/release/build/serde_core-74db491143173930/stderr +0 -0
  154. package/cli/target/release/build/serde_core-f043ae3f4b601577/build-script-build +0 -0
  155. package/cli/target/release/build/serde_core-f043ae3f4b601577/build_script_build-f043ae3f4b601577 +0 -0
  156. package/cli/target/release/build/serde_core-f043ae3f4b601577/build_script_build-f043ae3f4b601577.d +0 -5
  157. package/cli/target/release/build/serde_json-a8467019a959068f/invoked.timestamp +0 -1
  158. package/cli/target/release/build/serde_json-a8467019a959068f/output +0 -3
  159. package/cli/target/release/build/serde_json-a8467019a959068f/root-output +0 -1
  160. package/cli/target/release/build/serde_json-a8467019a959068f/stderr +0 -0
  161. package/cli/target/release/build/serde_json-bfa3f43b57842d41/build-script-build +0 -0
  162. package/cli/target/release/build/serde_json-bfa3f43b57842d41/build_script_build-bfa3f43b57842d41 +0 -0
  163. package/cli/target/release/build/serde_json-bfa3f43b57842d41/build_script_build-bfa3f43b57842d41.d +0 -5
  164. package/cli/target/release/build/zmij-60b0e0e9d7c08f71/invoked.timestamp +0 -1
  165. package/cli/target/release/build/zmij-60b0e0e9d7c08f71/output +0 -3
  166. package/cli/target/release/build/zmij-60b0e0e9d7c08f71/root-output +0 -1
  167. package/cli/target/release/build/zmij-60b0e0e9d7c08f71/stderr +0 -0
  168. package/cli/target/release/build/zmij-aa602f885104061e/build-script-build +0 -0
  169. package/cli/target/release/build/zmij-aa602f885104061e/build_script_build-aa602f885104061e +0 -0
  170. package/cli/target/release/build/zmij-aa602f885104061e/build_script_build-aa602f885104061e.d +0 -5
  171. package/cli/target/release/deps/agent_browser-5894536b887e2ce7 +0 -0
  172. package/cli/target/release/deps/agent_browser-5894536b887e2ce7.d +0 -5
  173. package/cli/target/release/deps/itoa-653b9192107a1caa.d +0 -8
  174. package/cli/target/release/deps/libc-d843359d3dd4757b.d +0 -45
  175. package/cli/target/release/deps/libitoa-653b9192107a1caa.rlib +0 -0
  176. package/cli/target/release/deps/libitoa-653b9192107a1caa.rmeta +0 -0
  177. package/cli/target/release/deps/liblibc-d843359d3dd4757b.rlib +0 -0
  178. package/cli/target/release/deps/liblibc-d843359d3dd4757b.rmeta +0 -0
  179. package/cli/target/release/deps/libmemchr-dcaf8011940d18dd.rlib +0 -0
  180. package/cli/target/release/deps/libmemchr-dcaf8011940d18dd.rmeta +0 -0
  181. package/cli/target/release/deps/libproc_macro2-a753b344a6b4aa98.rlib +0 -0
  182. package/cli/target/release/deps/libproc_macro2-a753b344a6b4aa98.rmeta +0 -0
  183. package/cli/target/release/deps/libquote-833e6725e0f7d298.rlib +0 -0
  184. package/cli/target/release/deps/libquote-833e6725e0f7d298.rmeta +0 -0
  185. package/cli/target/release/deps/libserde-d6fb44202dad3efd.rlib +0 -0
  186. package/cli/target/release/deps/libserde-d6fb44202dad3efd.rmeta +0 -0
  187. package/cli/target/release/deps/libserde_core-0f7ba2581c8c0423.rlib +0 -0
  188. package/cli/target/release/deps/libserde_core-0f7ba2581c8c0423.rmeta +0 -0
  189. package/cli/target/release/deps/libserde_derive-a5d13e0e658ceae3.dylib +0 -0
  190. package/cli/target/release/deps/libserde_json-f61651a65bf0eb31.rlib +0 -0
  191. package/cli/target/release/deps/libserde_json-f61651a65bf0eb31.rmeta +0 -0
  192. package/cli/target/release/deps/libsyn-6f9a22f8c7f909b0.rlib +0 -0
  193. package/cli/target/release/deps/libsyn-6f9a22f8c7f909b0.rmeta +0 -0
  194. package/cli/target/release/deps/libunicode_ident-60c57228d30a23d0.rlib +0 -0
  195. package/cli/target/release/deps/libunicode_ident-60c57228d30a23d0.rmeta +0 -0
  196. package/cli/target/release/deps/libzmij-9501bcbd6d8b933c.rlib +0 -0
  197. package/cli/target/release/deps/libzmij-9501bcbd6d8b933c.rmeta +0 -0
  198. package/cli/target/release/deps/memchr-dcaf8011940d18dd.d +0 -30
  199. package/cli/target/release/deps/proc_macro2-a753b344a6b4aa98.d +0 -17
  200. package/cli/target/release/deps/quote-833e6725e0f7d298.d +0 -13
  201. package/cli/target/release/deps/serde-d6fb44202dad3efd.d +0 -14
  202. package/cli/target/release/deps/serde_core-0f7ba2581c8c0423.d +0 -27
  203. package/cli/target/release/deps/serde_derive-a5d13e0e658ceae3.d +0 -34
  204. package/cli/target/release/deps/serde_json-f61651a65bf0eb31.d +0 -22
  205. package/cli/target/release/deps/syn-6f9a22f8c7f909b0.d +0 -49
  206. package/cli/target/release/deps/unicode_ident-60c57228d30a23d0.d +0 -8
  207. package/cli/target/release/deps/zmij-9501bcbd6d8b933c.d +0 -8
  208. package/src/actions.ts +0 -1670
  209. package/src/browser.test.ts +0 -157
  210. package/src/browser.ts +0 -686
  211. package/src/cli-light.ts +0 -457
  212. package/src/client.ts +0 -150
  213. package/src/daemon.ts +0 -187
  214. package/src/index.ts +0 -1185
  215. package/src/protocol.test.ts +0 -216
  216. package/src/protocol.ts +0 -852
  217. package/src/snapshot.ts +0 -380
  218. package/src/types.ts +0 -913
  219. package/tsconfig.json +0 -28
  220. package/vitest.config.ts +0 -9
@@ -1,521 +0,0 @@
1
- #!/usr/bin/env npx tsx
2
- /**
3
- * Benchmark: agent-browser vs playwright-mcp
4
- *
5
- * Measures:
6
- * - Speed: cold start, navigation, click, snapshot operations
7
- * - Context usage: output/response size in bytes and estimated tokens
8
- */
9
-
10
- import { spawn, execSync, ChildProcess } from 'child_process';
11
- import * as readline from 'readline';
12
-
13
- // ============================================================================
14
- // Configuration
15
- // ============================================================================
16
-
17
- const TEST_URL = 'https://example.com';
18
- const ITERATIONS = 3;
19
-
20
- interface BenchmarkResult {
21
- operation: string;
22
- tool: string;
23
- timeMs: number;
24
- outputBytes: number;
25
- estimatedTokens: number;
26
- }
27
-
28
- const results: BenchmarkResult[] = [];
29
-
30
- // Estimate tokens (~4 chars per token for English text)
31
- function estimateTokens(text: string): number {
32
- return Math.ceil(text.length / 4);
33
- }
34
-
35
- function formatBytes(bytes: number): string {
36
- if (bytes < 1024) return `${bytes} B`;
37
- if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
38
- return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
39
- }
40
-
41
- // ============================================================================
42
- // Agent-Browser Benchmarks
43
- // ============================================================================
44
-
45
- async function runAgentBrowser(args: string[]): Promise<{ timeMs: number; output: string }> {
46
- const start = performance.now();
47
-
48
- return new Promise((resolve, reject) => {
49
- const proc = spawn('node', ['./dist/index.js', '--session', 'benchmark', '--json', ...args], {
50
- cwd: process.cwd(),
51
- env: { ...process.env },
52
- });
53
-
54
- let output = '';
55
- let stderr = '';
56
-
57
- proc.stdout.on('data', (data) => { output += data.toString(); });
58
- proc.stderr.on('data', (data) => { stderr += data.toString(); });
59
-
60
- proc.on('close', (code) => {
61
- const timeMs = performance.now() - start;
62
- if (code !== 0 && !output.includes('"success"')) {
63
- reject(new Error(`agent-browser failed: ${stderr || output}`));
64
- } else {
65
- resolve({ timeMs, output: output.trim() });
66
- }
67
- });
68
-
69
- proc.on('error', reject);
70
- });
71
- }
72
-
73
- async function benchmarkAgentBrowser(): Promise<void> {
74
- console.log('\n📦 Benchmarking agent-browser...\n');
75
-
76
- // Clean up any existing session
77
- try {
78
- await runAgentBrowser(['close']);
79
- } catch {
80
- // Ignore - session might not exist
81
- }
82
-
83
- // Wait a bit for cleanup
84
- await new Promise(r => setTimeout(r, 500));
85
-
86
- // Cold start (includes daemon startup + browser launch + navigation)
87
- console.log(' ⏱️ Cold start (navigate)...');
88
- const coldStart = await runAgentBrowser(['open', TEST_URL]);
89
- results.push({
90
- operation: 'cold_start_navigate',
91
- tool: 'agent-browser',
92
- timeMs: coldStart.timeMs,
93
- outputBytes: coldStart.output.length,
94
- estimatedTokens: estimateTokens(coldStart.output),
95
- });
96
- console.log(` ${coldStart.timeMs.toFixed(0)}ms, ${formatBytes(coldStart.output.length)}`);
97
-
98
- // Warm operations
99
- for (let i = 0; i < ITERATIONS; i++) {
100
- // Navigate (warm)
101
- console.log(` ⏱️ Navigate (warm, iter ${i + 1})...`);
102
- const nav = await runAgentBrowser(['open', TEST_URL]);
103
- results.push({
104
- operation: 'navigate_warm',
105
- tool: 'agent-browser',
106
- timeMs: nav.timeMs,
107
- outputBytes: nav.output.length,
108
- estimatedTokens: estimateTokens(nav.output),
109
- });
110
- console.log(` ${nav.timeMs.toFixed(0)}ms, ${formatBytes(nav.output.length)}`);
111
-
112
- // Snapshot
113
- console.log(` ⏱️ Snapshot (iter ${i + 1})...`);
114
- const snapshot = await runAgentBrowser(['snapshot']);
115
- results.push({
116
- operation: 'snapshot',
117
- tool: 'agent-browser',
118
- timeMs: snapshot.timeMs,
119
- outputBytes: snapshot.output.length,
120
- estimatedTokens: estimateTokens(snapshot.output),
121
- });
122
- console.log(` ${snapshot.timeMs.toFixed(0)}ms, ${formatBytes(snapshot.output.length)}`);
123
-
124
- // Get title
125
- console.log(` ⏱️ Get title (iter ${i + 1})...`);
126
- const title = await runAgentBrowser(['get', 'title']);
127
- results.push({
128
- operation: 'get_title',
129
- tool: 'agent-browser',
130
- timeMs: title.timeMs,
131
- outputBytes: title.output.length,
132
- estimatedTokens: estimateTokens(title.output),
133
- });
134
- console.log(` ${title.timeMs.toFixed(0)}ms, ${formatBytes(title.output.length)}`);
135
-
136
- // Get URL
137
- console.log(` ⏱️ Get URL (iter ${i + 1})...`);
138
- const url = await runAgentBrowser(['get', 'url']);
139
- results.push({
140
- operation: 'get_url',
141
- tool: 'agent-browser',
142
- timeMs: url.timeMs,
143
- outputBytes: url.output.length,
144
- estimatedTokens: estimateTokens(url.output),
145
- });
146
- console.log(` ${url.timeMs.toFixed(0)}ms, ${formatBytes(url.output.length)}`);
147
-
148
- // Click (on a link that exists on example.com)
149
- console.log(` ⏱️ Click link (iter ${i + 1})...`);
150
- const click = await runAgentBrowser(['click', 'a']);
151
- results.push({
152
- operation: 'click',
153
- tool: 'agent-browser',
154
- timeMs: click.timeMs,
155
- outputBytes: click.output.length,
156
- estimatedTokens: estimateTokens(click.output),
157
- });
158
- console.log(` ${click.timeMs.toFixed(0)}ms, ${formatBytes(click.output.length)}`);
159
-
160
- // Navigate back for next iteration
161
- await runAgentBrowser(['open', TEST_URL]);
162
- }
163
-
164
- // Screenshot
165
- console.log(' ⏱️ Screenshot...');
166
- const screenshot = await runAgentBrowser(['screenshot']);
167
- results.push({
168
- operation: 'screenshot',
169
- tool: 'agent-browser',
170
- timeMs: screenshot.timeMs,
171
- outputBytes: screenshot.output.length,
172
- estimatedTokens: estimateTokens(screenshot.output),
173
- });
174
- console.log(` ${screenshot.timeMs.toFixed(0)}ms, ${formatBytes(screenshot.output.length)}`);
175
-
176
- // Close
177
- console.log(' ⏱️ Close...');
178
- const close = await runAgentBrowser(['close']);
179
- results.push({
180
- operation: 'close',
181
- tool: 'agent-browser',
182
- timeMs: close.timeMs,
183
- outputBytes: close.output.length,
184
- estimatedTokens: estimateTokens(close.output),
185
- });
186
- console.log(` ${close.timeMs.toFixed(0)}ms`);
187
- }
188
-
189
- // ============================================================================
190
- // Playwright-MCP Benchmarks
191
- // ============================================================================
192
-
193
- class MCPClient {
194
- private proc: ChildProcess;
195
- private rl: readline.Interface;
196
- private responseBuffer: Map<number, { resolve: (v: any) => void; reject: (e: Error) => void }> = new Map();
197
- private requestId = 0;
198
- private ready = false;
199
-
200
- constructor() {
201
- this.proc = spawn('node', ['./opensrc/repos/github.com/microsoft/playwright-mcp/cli.js', '--headless'], {
202
- cwd: process.cwd(),
203
- stdio: ['pipe', 'pipe', 'pipe'],
204
- });
205
-
206
- this.rl = readline.createInterface({ input: this.proc.stdout! });
207
-
208
- this.rl.on('line', (line) => {
209
- try {
210
- const msg = JSON.parse(line);
211
- if (msg.id !== undefined && this.responseBuffer.has(msg.id)) {
212
- const handler = this.responseBuffer.get(msg.id)!;
213
- this.responseBuffer.delete(msg.id);
214
- handler.resolve(msg);
215
- }
216
- } catch {
217
- // Non-JSON output, ignore
218
- }
219
- });
220
-
221
- this.proc.stderr?.on('data', (data) => {
222
- // Debug output, ignore in benchmarks
223
- });
224
- }
225
-
226
- async initialize(): Promise<{ timeMs: number; output: string }> {
227
- const start = performance.now();
228
-
229
- // Send initialize request
230
- const initResult = await this.sendRequest('initialize', {
231
- protocolVersion: '2024-11-05',
232
- capabilities: {},
233
- clientInfo: { name: 'benchmark', version: '1.0.0' },
234
- });
235
-
236
- // Send initialized notification
237
- this.sendNotification('notifications/initialized', {});
238
-
239
- const timeMs = performance.now() - start;
240
- const output = JSON.stringify(initResult);
241
-
242
- this.ready = true;
243
- return { timeMs, output };
244
- }
245
-
246
- async callTool(name: string, args: Record<string, unknown>): Promise<{ timeMs: number; output: string }> {
247
- const start = performance.now();
248
- const result = await this.sendRequest('tools/call', { name, arguments: args });
249
- const timeMs = performance.now() - start;
250
- const output = JSON.stringify(result);
251
- return { timeMs, output };
252
- }
253
-
254
- private sendRequest(method: string, params: Record<string, unknown>): Promise<any> {
255
- const id = ++this.requestId;
256
- const request = { jsonrpc: '2.0', id, method, params };
257
-
258
- return new Promise((resolve, reject) => {
259
- this.responseBuffer.set(id, { resolve, reject });
260
- this.proc.stdin!.write(JSON.stringify(request) + '\n');
261
-
262
- // Timeout after 30s
263
- setTimeout(() => {
264
- if (this.responseBuffer.has(id)) {
265
- this.responseBuffer.delete(id);
266
- reject(new Error(`Request timeout: ${method}`));
267
- }
268
- }, 30000);
269
- });
270
- }
271
-
272
- private sendNotification(method: string, params: Record<string, unknown>): void {
273
- const notification = { jsonrpc: '2.0', method, params };
274
- this.proc.stdin!.write(JSON.stringify(notification) + '\n');
275
- }
276
-
277
- async close(): Promise<void> {
278
- this.proc.kill();
279
- this.rl.close();
280
- }
281
- }
282
-
283
- async function benchmarkPlaywrightMCP(): Promise<void> {
284
- console.log('\n📦 Benchmarking playwright-mcp...\n');
285
-
286
- let client: MCPClient | null = null;
287
-
288
- try {
289
- // Cold start (includes server startup + initialization)
290
- console.log(' ⏱️ Cold start (initialize + navigate)...');
291
- const coldStartBegin = performance.now();
292
-
293
- client = new MCPClient();
294
- const init = await client.initialize();
295
-
296
- // Navigate
297
- const nav = await client.callTool('browser_navigate', { url: TEST_URL });
298
-
299
- const coldStartTime = performance.now() - coldStartBegin;
300
- const coldStartOutput = init.output + nav.output;
301
-
302
- results.push({
303
- operation: 'cold_start_navigate',
304
- tool: 'playwright-mcp',
305
- timeMs: coldStartTime,
306
- outputBytes: coldStartOutput.length,
307
- estimatedTokens: estimateTokens(coldStartOutput),
308
- });
309
- console.log(` ${coldStartTime.toFixed(0)}ms, ${formatBytes(coldStartOutput.length)}`);
310
-
311
- // Warm operations
312
- for (let i = 0; i < ITERATIONS; i++) {
313
- // Navigate (warm)
314
- console.log(` ⏱️ Navigate (warm, iter ${i + 1})...`);
315
- const navWarm = await client.callTool('browser_navigate', { url: TEST_URL });
316
- results.push({
317
- operation: 'navigate_warm',
318
- tool: 'playwright-mcp',
319
- timeMs: navWarm.timeMs,
320
- outputBytes: navWarm.output.length,
321
- estimatedTokens: estimateTokens(navWarm.output),
322
- });
323
- console.log(` ${navWarm.timeMs.toFixed(0)}ms, ${formatBytes(navWarm.output.length)}`);
324
-
325
- // Snapshot
326
- console.log(` ⏱️ Snapshot (iter ${i + 1})...`);
327
- const snapshot = await client.callTool('browser_snapshot', {});
328
- results.push({
329
- operation: 'snapshot',
330
- tool: 'playwright-mcp',
331
- timeMs: snapshot.timeMs,
332
- outputBytes: snapshot.output.length,
333
- estimatedTokens: estimateTokens(snapshot.output),
334
- });
335
- console.log(` ${snapshot.timeMs.toFixed(0)}ms, ${formatBytes(snapshot.output.length)}`);
336
-
337
- // Note: playwright-mcp doesn't have separate get_title/get_url tools
338
- // Title and URL are included in snapshot, so we'll skip those
339
-
340
- // Click
341
- console.log(` ⏱️ Click link (iter ${i + 1})...`);
342
- // playwright-mcp uses ref from snapshot - we'll use a generic approach
343
- const click = await client.callTool('browser_click', {
344
- element: 'More information link',
345
- ref: 'a' // This might not work exactly the same way
346
- });
347
- results.push({
348
- operation: 'click',
349
- tool: 'playwright-mcp',
350
- timeMs: click.timeMs,
351
- outputBytes: click.output.length,
352
- estimatedTokens: estimateTokens(click.output),
353
- });
354
- console.log(` ${click.timeMs.toFixed(0)}ms, ${formatBytes(click.output.length)}`);
355
-
356
- // Navigate back
357
- await client.callTool('browser_navigate', { url: TEST_URL });
358
- }
359
-
360
- // Screenshot
361
- console.log(' ⏱️ Screenshot...');
362
- const screenshot = await client.callTool('browser_take_screenshot', {});
363
- results.push({
364
- operation: 'screenshot',
365
- tool: 'playwright-mcp',
366
- timeMs: screenshot.timeMs,
367
- outputBytes: screenshot.output.length,
368
- estimatedTokens: estimateTokens(screenshot.output),
369
- });
370
- console.log(` ${screenshot.timeMs.toFixed(0)}ms, ${formatBytes(screenshot.output.length)}`);
371
-
372
- // Close
373
- console.log(' ⏱️ Close...');
374
- const closeStart = performance.now();
375
- const closeResult = await client.callTool('browser_close', {});
376
- results.push({
377
- operation: 'close',
378
- tool: 'playwright-mcp',
379
- timeMs: closeResult.timeMs,
380
- outputBytes: closeResult.output.length,
381
- estimatedTokens: estimateTokens(closeResult.output),
382
- });
383
- console.log(` ${closeResult.timeMs.toFixed(0)}ms`);
384
-
385
- } catch (error) {
386
- console.error(' ❌ playwright-mcp benchmark failed:', error);
387
- } finally {
388
- if (client) {
389
- await client.close();
390
- }
391
- }
392
- }
393
-
394
- // ============================================================================
395
- // Results Summary
396
- // ============================================================================
397
-
398
- function printResults(): void {
399
- console.log('\n' + '='.repeat(80));
400
- console.log('📊 BENCHMARK RESULTS');
401
- console.log('='.repeat(80));
402
-
403
- // Group by operation
404
- const operations = [...new Set(results.map(r => r.operation))];
405
-
406
- console.log('\n📈 Speed Comparison (average across iterations):\n');
407
- console.log('| Operation | agent-browser | playwright-mcp | Difference |');
408
- console.log('|---------------------|---------------|----------------|------------|');
409
-
410
- for (const op of operations) {
411
- const agentResults = results.filter(r => r.operation === op && r.tool === 'agent-browser');
412
- const mcpResults = results.filter(r => r.operation === op && r.tool === 'playwright-mcp');
413
-
414
- const agentAvg = agentResults.length > 0
415
- ? agentResults.reduce((sum, r) => sum + r.timeMs, 0) / agentResults.length
416
- : null;
417
- const mcpAvg = mcpResults.length > 0
418
- ? mcpResults.reduce((sum, r) => sum + r.timeMs, 0) / mcpResults.length
419
- : null;
420
-
421
- const agentStr = agentAvg !== null ? `${agentAvg.toFixed(0)}ms`.padEnd(13) : 'N/A'.padEnd(13);
422
- const mcpStr = mcpAvg !== null ? `${mcpAvg.toFixed(0)}ms`.padEnd(14) : 'N/A'.padEnd(14);
423
-
424
- let diff = '';
425
- if (agentAvg !== null && mcpAvg !== null) {
426
- const ratio = agentAvg / mcpAvg;
427
- if (ratio < 1) {
428
- diff = `${((1 - ratio) * 100).toFixed(0)}% faster`;
429
- } else if (ratio > 1) {
430
- diff = `${((ratio - 1) * 100).toFixed(0)}% slower`;
431
- } else {
432
- diff = 'same';
433
- }
434
- }
435
-
436
- console.log(`| ${op.padEnd(19)} | ${agentStr} | ${mcpStr} | ${diff.padEnd(10)} |`);
437
- }
438
-
439
- console.log('\n📦 Context Usage (output size for AI consumption):\n');
440
- console.log('| Operation | agent-browser | playwright-mcp |');
441
- console.log('|---------------------|--------------------|--------------------|');
442
-
443
- for (const op of operations) {
444
- const agentResults = results.filter(r => r.operation === op && r.tool === 'agent-browser');
445
- const mcpResults = results.filter(r => r.operation === op && r.tool === 'playwright-mcp');
446
-
447
- const agentAvgBytes = agentResults.length > 0
448
- ? agentResults.reduce((sum, r) => sum + r.outputBytes, 0) / agentResults.length
449
- : null;
450
- const agentAvgTokens = agentResults.length > 0
451
- ? agentResults.reduce((sum, r) => sum + r.estimatedTokens, 0) / agentResults.length
452
- : null;
453
-
454
- const mcpAvgBytes = mcpResults.length > 0
455
- ? mcpResults.reduce((sum, r) => sum + r.outputBytes, 0) / mcpResults.length
456
- : null;
457
- const mcpAvgTokens = mcpResults.length > 0
458
- ? mcpResults.reduce((sum, r) => sum + r.estimatedTokens, 0) / mcpResults.length
459
- : null;
460
-
461
- const agentStr = agentAvgBytes !== null
462
- ? `${formatBytes(agentAvgBytes)} (~${Math.round(agentAvgTokens!)} tok)`.padEnd(18)
463
- : 'N/A'.padEnd(18);
464
- const mcpStr = mcpAvgBytes !== null
465
- ? `${formatBytes(mcpAvgBytes)} (~${Math.round(mcpAvgTokens!)} tok)`.padEnd(18)
466
- : 'N/A'.padEnd(18);
467
-
468
- console.log(`| ${op.padEnd(19)} | ${agentStr} | ${mcpStr} |`);
469
- }
470
-
471
- // Total context usage
472
- const agentTotal = results.filter(r => r.tool === 'agent-browser');
473
- const mcpTotal = results.filter(r => r.tool === 'playwright-mcp');
474
-
475
- const agentTotalBytes = agentTotal.reduce((sum, r) => sum + r.outputBytes, 0);
476
- const agentTotalTokens = agentTotal.reduce((sum, r) => sum + r.estimatedTokens, 0);
477
- const mcpTotalBytes = mcpTotal.reduce((sum, r) => sum + r.outputBytes, 0);
478
- const mcpTotalTokens = mcpTotal.reduce((sum, r) => sum + r.estimatedTokens, 0);
479
-
480
- console.log('\n📊 Total Context Usage (all operations combined):');
481
- console.log(` agent-browser: ${formatBytes(agentTotalBytes)} (~${agentTotalTokens} tokens)`);
482
- console.log(` playwright-mcp: ${formatBytes(mcpTotalBytes)} (~${mcpTotalTokens} tokens)`);
483
-
484
- if (agentTotalBytes > 0 && mcpTotalBytes > 0) {
485
- const ratio = agentTotalBytes / mcpTotalBytes;
486
- if (ratio < 1) {
487
- console.log(` → agent-browser uses ${((1 - ratio) * 100).toFixed(0)}% less context`);
488
- } else {
489
- console.log(` → playwright-mcp uses ${((1 - 1/ratio) * 100).toFixed(0)}% less context`);
490
- }
491
- }
492
-
493
- console.log('\n' + '='.repeat(80));
494
- }
495
-
496
- // ============================================================================
497
- // Main
498
- // ============================================================================
499
-
500
- async function main(): Promise<void> {
501
- console.log('🚀 Browser Automation Benchmark');
502
- console.log(` Testing against: ${TEST_URL}`);
503
- console.log(` Iterations: ${ITERATIONS}`);
504
- console.log('='.repeat(80));
505
-
506
- try {
507
- // Build first
508
- console.log('\n🔨 Building agent-browser...');
509
- execSync('pnpm build', { cwd: process.cwd(), stdio: 'inherit' });
510
-
511
- await benchmarkAgentBrowser();
512
- await benchmarkPlaywrightMCP();
513
-
514
- printResults();
515
- } catch (error) {
516
- console.error('\n❌ Benchmark failed:', error);
517
- process.exit(1);
518
- }
519
- }
520
-
521
- main();