@wenathlan/devthink 2.0.13 → 2.0.15

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 (444) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/accounts.ts +2087 -0
  3. package/agent.ts +2331 -0
  4. package/antigravity.ts +2139 -0
  5. package/apifreeze.ts +4146 -0
  6. package/auth.ts +642 -0
  7. package/background.ts +16837 -0
  8. package/bridge.ts +2080 -0
  9. package/build.ts +54 -0
  10. package/bun.ts +26 -0
  11. package/capture.ts +1614 -0
  12. package/checksecrets.ts +72 -0
  13. package/cjs.ts +9 -0
  14. package/cli.ts +3500 -0
  15. package/commands.ts +1101 -0
  16. package/companion.ts +450 -0
  17. package/compatibility.ts +37 -0
  18. package/config.ts +3137 -0
  19. package/constants.ts +943 -0
  20. package/core.ts +1473 -0
  21. package/crossbrowser.ts +1359 -0
  22. package/dashdone.ts +605 -0
  23. package/data.ts +943 -0
  24. package/database.ts +133 -0
  25. package/debug.ts +850 -0
  26. package/deno.ts +27 -0
  27. package/devthink.ts +707 -0
  28. package/dist/accounts.d.ts +409 -0
  29. package/dist/agent.d.ts +837 -0
  30. package/dist/antigravity.d.ts +380 -0
  31. package/dist/apifreeze.d.ts +113 -0
  32. package/dist/auth.d.ts +224 -0
  33. package/{bridge.d.ts → dist/bridge.d.ts} +1 -1
  34. package/dist/capture.d.ts +595 -0
  35. package/dist/cjs.d.ts +6 -0
  36. package/{cli.js → dist/cli.js} +2 -2
  37. package/dist/commands.d.ts +310 -0
  38. package/dist/compatibility.d.ts +17 -0
  39. package/dist/config.d.ts +1853 -0
  40. package/dist/constants.d.ts +637 -0
  41. package/dist/core.d.ts +361 -0
  42. package/dist/data.d.ts +330 -0
  43. package/dist/database.d.ts +24 -0
  44. package/dist/debug.d.ts +270 -0
  45. package/dist/engine.d.ts +74 -0
  46. package/dist/environments.d.ts +244 -0
  47. package/dist/evidence.d.ts +277 -0
  48. package/dist/export.d.ts +311 -0
  49. package/dist/fingerprint.d.ts +594 -0
  50. package/dist/flow.d.ts +300 -0
  51. package/dist/gates.d.ts +103 -0
  52. package/dist/identity.d.ts +51 -0
  53. package/dist/ids.d.ts +7 -0
  54. package/dist/llm.d.ts +652 -0
  55. package/dist/models.d.ts +1807 -0
  56. package/dist/net.d.ts +325 -0
  57. package/dist/neutral.d.ts +41 -0
  58. package/dist/oauth.d.ts +703 -0
  59. package/dist/page.d.ts +1166 -0
  60. package/dist/perf.d.ts +481 -0
  61. package/dist/plan.d.ts +134 -0
  62. package/dist/project.d.ts +395 -0
  63. package/dist/providers.d.ts +37 -0
  64. package/dist/quota.d.ts +453 -0
  65. package/dist/recovery.d.ts +621 -0
  66. package/dist/request.d.ts +1492 -0
  67. package/dist/run.d.ts +779 -0
  68. package/dist/runtime.d.ts +212 -0
  69. package/dist/search.d.ts +375 -0
  70. package/dist/security.d.ts +534 -0
  71. package/dist/serve.d.ts +136 -0
  72. package/dist/session.d.ts +296 -0
  73. package/dist/storage.d.ts +53 -0
  74. package/dist/streaming.d.ts +1119 -0
  75. package/dist/swarm.d.ts +328 -0
  76. package/dist/tools.d.ts +170 -0
  77. package/dist/types.d.ts +8357 -0
  78. package/dist/utils.d.ts +82 -0
  79. package/dist/version.d.ts +7 -0
  80. package/dist/versionregistry.d.ts +406 -0
  81. package/dist/views.d.ts +579 -0
  82. package/dist/workbenchsession.d.ts +69 -0
  83. package/dist/workflow.d.ts +649 -0
  84. package/docs/readme.md +92 -0
  85. package/docs/schemas/antigravity.json +192 -0
  86. package/engine.ts +1524 -0
  87. package/environments.ts +1005 -0
  88. package/evidence.ts +643 -0
  89. package/export.ts +889 -0
  90. package/fingerprint.ts +1458 -0
  91. package/flow.ts +1190 -0
  92. package/gates.ts +307 -0
  93. package/gateway.ts +34 -0
  94. package/hardening.ts +191 -0
  95. package/headless.ts +369 -0
  96. package/http.ts +2110 -0
  97. package/identity.ts +246 -0
  98. package/ids.ts +26 -0
  99. package/index.ts +369 -0
  100. package/llm.ts +2682 -0
  101. package/mcp.ts +1835 -0
  102. package/{memory.js → memory.ts} +3834 -2310
  103. package/models.ts +3805 -0
  104. package/modes.ts +43 -0
  105. package/net.ts +1214 -0
  106. package/neutral.ts +362 -0
  107. package/node.ts +26 -0
  108. package/oauth.ts +2216 -0
  109. package/offscreen.ts +170 -0
  110. package/pack.ts +956 -0
  111. package/package.json +175 -82
  112. package/page.ts +7824 -0
  113. package/pagebridge.ts +1116 -0
  114. package/perf.ts +957 -0
  115. package/plan.ts +672 -0
  116. package/plugin.ts +76 -0
  117. package/{policy.js → policy.ts} +5073 -4679
  118. package/prisma.config.ts +27 -0
  119. package/progress.ts +1308 -0
  120. package/project.ts +1291 -0
  121. package/protocol.ts +4187 -0
  122. package/providers.ts +246 -0
  123. package/quota.ts +1887 -0
  124. package/recovery.ts +2433 -0
  125. package/request.ts +4482 -0
  126. package/run.ts +2135 -0
  127. package/runtime.ts +526 -0
  128. package/search.ts +1760 -0
  129. package/security.ts +1673 -0
  130. package/serve.ts +419 -0
  131. package/server.ts +5538 -0
  132. package/session.ts +1162 -0
  133. package/storage.ts +182 -0
  134. package/streaming.ts +4101 -0
  135. package/swarm.ts +884 -0
  136. package/sync.ts +56 -0
  137. package/tests/agentcert.test.ts +128 -0
  138. package/tests/agentfleet.test.ts +214 -0
  139. package/tests/agentreview.test.ts +241 -0
  140. package/tests/agentstream.test.ts +335 -0
  141. package/tests/agentwork.test.ts +356 -0
  142. package/tests/apifreeze.test.ts +290 -0
  143. package/tests/apimap.test.ts +112 -0
  144. package/tests/approvalgate.test.ts +175 -0
  145. package/tests/artifactmanifest.test.ts +204 -0
  146. package/tests/attentionfeed.test.ts +163 -0
  147. package/tests/backgroundruns.test.ts +100 -0
  148. package/tests/batchscheduling.test.ts +131 -0
  149. package/tests/blackboard.test.ts +238 -0
  150. package/tests/bridge.test.ts +1088 -0
  151. package/tests/browsercoverage.test.ts +134 -0
  152. package/tests/browserpolyfills.test.ts +124 -0
  153. package/tests/build.mjs +1260 -0
  154. package/tests/clientauth.test.ts +223 -0
  155. package/tests/clitools.test.ts +578 -0
  156. package/tests/confirmgates.test.ts +190 -0
  157. package/tests/containerpack.test.ts +143 -0
  158. package/tests/controlflow.test.ts +2120 -0
  159. package/tests/coordination.test.ts +345 -0
  160. package/tests/copyscreen.test.ts +139 -0
  161. package/tests/core.test.ts +417 -0
  162. package/tests/costcert.test.ts +95 -0
  163. package/tests/crossbrowser.test.ts +115 -0
  164. package/tests/cspaudit.test.ts +79 -0
  165. package/tests/dashdone.test.ts +615 -0
  166. package/tests/datagrid.test.ts +137 -0
  167. package/tests/doccheck.test.ts +107 -0
  168. package/tests/dombatch.test.ts +109 -0
  169. package/tests/emulation.test.ts +282 -0
  170. package/tests/environments.test.ts +259 -0
  171. package/tests/evidenceviews.test.ts +88 -0
  172. package/tests/exporttools.test.ts +185 -0
  173. package/tests/firefoxprep.test.ts +134 -0
  174. package/tests/flowlibrary.test.ts +242 -0
  175. package/tests/flowrun.test.ts +303 -0
  176. package/tests/forensics.test.ts +439 -0
  177. package/tests/gateway.test.ts +939 -0
  178. package/tests/headlesslib.test.ts +171 -0
  179. package/tests/httpstream.test.ts +277 -0
  180. package/tests/immutablelog.test.ts +157 -0
  181. package/tests/inboundguard.test.ts +177 -0
  182. package/tests/lazyload.test.ts +72 -0
  183. package/tests/librarymodes.test.ts +623 -0
  184. package/tests/llm.test.ts +696 -0
  185. package/tests/manifest.test.ts +226 -0
  186. package/tests/maskinputs.test.ts +150 -0
  187. package/tests/matrixverify.test.ts +111 -0
  188. package/tests/mavenpack.test.ts +75 -0
  189. package/tests/mcpserver.test.ts +704 -0
  190. package/tests/memory.test.ts +4155 -0
  191. package/tests/memorycare.test.ts +230 -0
  192. package/tests/migrateplan.test.ts +349 -0
  193. package/tests/minimization.test.ts +414 -0
  194. package/tests/modelroute.test.ts +112 -0
  195. package/tests/multiagent.test.ts +440 -0
  196. package/tests/nativebridge.test.ts +807 -0
  197. package/tests/navigation.test.ts +284 -0
  198. package/tests/nugetpack.test.ts +83 -0
  199. package/tests/orchestration.test.ts +449 -0
  200. package/tests/originpolicy.test.ts +405 -0
  201. package/tests/outputcompare.test.ts +97 -0
  202. package/tests/package.test.ts +91 -0
  203. package/tests/pagebridge.test.ts +5909 -0
  204. package/tests/pentest.test.ts +75 -0
  205. package/tests/perfrecords.test.ts +257 -0
  206. package/tests/permdiff.test.ts +85 -0
  207. package/tests/phishguard.test.ts +128 -0
  208. package/tests/pickerviews.test.ts +155 -0
  209. package/tests/pipelines.test.ts +381 -0
  210. package/tests/planlint.test.ts +240 -0
  211. package/tests/planreview.test.ts +383 -0
  212. package/tests/platformtargets.test.ts +56 -0
  213. package/tests/policy.test.ts +8284 -0
  214. package/tests/portability.test.ts +96 -0
  215. package/tests/progress.test.ts +1036 -0
  216. package/tests/promptlibrary.test.ts +116 -0
  217. package/tests/protocol.test.ts +4793 -0
  218. package/tests/publishingpipeline.test.ts +314 -0
  219. package/tests/quickactions.test.ts +164 -0
  220. package/tests/readiness.test.ts +78 -0
  221. package/tests/recipes.test.ts +163 -0
  222. package/tests/redactshots.test.ts +216 -0
  223. package/tests/registernvidiakeys.ts +51 -0
  224. package/tests/relayserve.test.ts +304 -0
  225. package/tests/releasenotes.test.ts +276 -0
  226. package/tests/resilience.test.ts +467 -0
  227. package/tests/resourceaware.test.ts +187 -0
  228. package/tests/runbudget.test.ts +125 -0
  229. package/tests/runhistory.test.ts +299 -0
  230. package/tests/runreplay.test.ts +113 -0
  231. package/tests/runresume.test.ts +184 -0
  232. package/tests/runstate.test.ts +288 -0
  233. package/tests/runtimeadapters.test.ts +251 -0
  234. package/tests/safariskeleton.test.ts +115 -0
  235. package/tests/sandboxframe.test.ts +196 -0
  236. package/tests/sbom.test.ts +105 -0
  237. package/tests/secretvault.test.ts +188 -0
  238. package/tests/selcache.test.ts +111 -0
  239. package/tests/sessioninterface.test.ts +791 -0
  240. package/tests/sessions.test.ts +591 -0
  241. package/tests/siteprefs.test.ts +228 -0
  242. package/tests/snapshotdelta.test.ts +165 -0
  243. package/tests/statusviews.test.ts +237 -0
  244. package/tests/stepmeter.test.ts +200 -0
  245. package/tests/streamparse.test.ts +163 -0
  246. package/tests/stylepruning.test.ts +90 -0
  247. package/tests/surfaces.test.ts +282 -0
  248. package/tests/sweep.test.ts +78 -0
  249. package/tests/syncbridge.test.ts +164 -0
  250. package/tests/taskqueue.test.ts +206 -0
  251. package/tests/toolcalls.test.ts +336 -0
  252. package/tests/toolcatalog.test.ts +201 -0
  253. package/tests/torture-agent.test.ts +706 -0
  254. package/tests/torture-auth.test.ts +461 -0
  255. package/tests/torture-commands.test.ts +895 -0
  256. package/tests/torture-data.test.ts +923 -0
  257. package/tests/torture-environments.test.ts +285 -0
  258. package/tests/torture-export.test.ts +263 -0
  259. package/tests/torture-http.test.ts +1379 -0
  260. package/tests/torture-llm.test.ts +808 -0
  261. package/tests/torture-memory.test.ts +1084 -0
  262. package/tests/torture-plan.test.ts +829 -0
  263. package/tests/torture-run.test.ts +626 -0
  264. package/tests/torture-session.test.ts +928 -0
  265. package/tests/torture-swarm.test.ts +1245 -0
  266. package/tests/torture-tools.test.ts +964 -0
  267. package/tests/torture-workflow.test.ts +2354 -0
  268. package/tests/tourviews.test.ts +52 -0
  269. package/tests/transparency.test.ts +147 -0
  270. package/tests/trigger.test.ts +941 -0
  271. package/tests/v1sunset.test.ts +428 -0
  272. package/tests/virtlist.test.ts +94 -0
  273. package/tests/vision.test.ts +540 -0
  274. package/tests/vsixpack.test.ts +145 -0
  275. package/tests/webapi.test.ts +523 -0
  276. package/tests/workflow.test.ts +1785 -0
  277. package/tests/workfloweditor.test.ts +759 -0
  278. package/tests/xpipack.test.ts +128 -0
  279. package/tools.ts +734 -0
  280. package/types.ts +9908 -0
  281. package/umd.ts +9 -0
  282. package/utils.ts +249 -0
  283. package/version.ts +8 -0
  284. package/versionregistry.ts +1310 -0
  285. package/views.ts +2153 -0
  286. package/vitest.config.ts +12 -0
  287. package/web/App.tsx +78 -0
  288. package/web/README.md +47 -0
  289. package/web/capacitor.config.ts +46 -0
  290. package/web/const.ts +19 -0
  291. package/web/control.shell.tsx +66 -0
  292. package/web/dashboardpage.ts +554 -0
  293. package/web/db.ts +493 -0
  294. package/web/design.html +541 -0
  295. package/web/gatewayview/Gateway.tsx +345 -0
  296. package/web/gatewayview/config.ts +1042 -0
  297. package/web/gatewayview/definition.ts +174 -0
  298. package/web/icons.ts +15 -0
  299. package/{manifest.json → web/manifest.json} +1 -1
  300. package/web/optionspage.ts +691 -0
  301. package/web/popup.ts +1651 -0
  302. package/web/schema.prisma +176 -0
  303. package/web/sidepanel.ts +7941 -0
  304. package/web/sitemanifest.json +13 -0
  305. package/web/terminal-ui.tsx +622 -0
  306. package/web/transparencypage.ts +541 -0
  307. package/web/vite.config.ts +39 -0
  308. package/web/workspace.ts +23 -0
  309. package/workbenchmemory.ts +104 -0
  310. package/workbenchsession.ts +304 -0
  311. package/workflow.ts +4495 -0
  312. package/bridge.d.ts.map +0 -1
  313. package/bridge.js +0 -1877
  314. package/bun.d.ts.map +0 -1
  315. package/bun.js +0 -52329
  316. package/caps/background.json +0 -712
  317. package/caps/cli.json +0 -360
  318. package/caps/library.json +0 -3611
  319. package/caps/mcp.json +0 -126
  320. package/caps/pagebridge.json +0 -377
  321. package/caps/popup.json +0 -51
  322. package/caps/sidepanel.json +0 -522
  323. package/checksums.txt +0 -142
  324. package/cli.d.ts.map +0 -1
  325. package/companion.d.ts.map +0 -1
  326. package/companion.js +0 -389
  327. package/crossbrowser.d.ts.map +0 -1
  328. package/crossbrowser.js +0 -1191
  329. package/dashdone.d.ts.map +0 -1
  330. package/dashdone.js +0 -368
  331. package/deno.d.ts.map +0 -1
  332. package/deno.js +0 -52325
  333. package/devthink.umd.js +0 -52346
  334. package/fixtures/bun.ts +0 -7
  335. package/fixtures/cjs.js +0 -6
  336. package/fixtures/deno.ts +0 -6
  337. package/fixtures/example-org-pagestate.json +0 -22
  338. package/fixtures/importers/automa-workflow.json +0 -18
  339. package/fixtures/importers/selenium-side.json +0 -20
  340. package/fixtures/importers/tabular-plan.csv +0 -7
  341. package/fixtures/importers/uivision-macro.json +0 -10
  342. package/fixtures/importers/v1-plan.json +0 -13
  343. package/fixtures/mcp-client.mjs +0 -14
  344. package/fixtures/pages/checkout.html +0 -192
  345. package/fixtures/pages/dashboard.html +0 -110
  346. package/fixtures/pages/feed.html +0 -113
  347. package/fixtures/pages/product-grid.html +0 -150
  348. package/fixtures/plans/form-inventory-plan.json +0 -11
  349. package/fixtures/plans/release-notes-plan.json +0 -11
  350. package/fixtures/recipes/agentscompete.json +0 -11
  351. package/fixtures/recipes/agentsforms.json +0 -11
  352. package/fixtures/recipes/agentsmonitor.json +0 -11
  353. package/fixtures/recipes/agentsreview.json +0 -29
  354. package/fixtures/recipes/agentswarm.json +0 -11
  355. package/fixtures/recipes/fillcalendar.json +0 -12
  356. package/fixtures/recipes/fillcheckout.json +0 -13
  357. package/fixtures/recipes/filldependentdropdowns.json +0 -12
  358. package/fixtures/recipes/fillfromcsv.json +0 -13
  359. package/fixtures/recipes/fillloginform.json +0 -12
  360. package/fixtures/recipes/fillmultistepwizard.json +0 -13
  361. package/fixtures/recipes/fillregistration.json +0 -12
  362. package/fixtures/recipes/fillsearchfilters.json +0 -12
  363. package/fixtures/recipes/filltypeahead.json +0 -11
  364. package/fixtures/recipes/monitoralerts.json +0 -12
  365. package/fixtures/recipes/monitoravailability.json +0 -11
  366. package/fixtures/recipes/monitornetworkquiet.json +0 -12
  367. package/fixtures/recipes/monitorpagechanges.json +0 -11
  368. package/fixtures/recipes/monitorpricechange.json +0 -11
  369. package/fixtures/recipes/monitorschedule.json +0 -12
  370. package/fixtures/recipes/scrapedynamicprices.json +0 -13
  371. package/fixtures/recipes/scrapeimagegallery.json +0 -12
  372. package/fixtures/recipes/scrapeinfinitefeed.json +0 -13
  373. package/fixtures/recipes/scrapenestedlists.json +0 -12
  374. package/fixtures/recipes/scrapeproductgrid.json +0 -12
  375. package/fixtures/recipes/scrapereviews.json +0 -12
  376. package/fixtures/recipes/scrapesearchresults.json +0 -12
  377. package/fixtures/recipes/scrapetablepagination.json +0 -12
  378. package/fixtures/recipes/testaccessibility.json +0 -34
  379. package/fixtures/recipes/testconsoleerrors.json +0 -12
  380. package/fixtures/recipes/testdeeplinks.json +0 -12
  381. package/fixtures/recipes/testformvalidation.json +0 -13
  382. package/fixtures/recipes/testlayoutshift.json +0 -12
  383. package/fixtures/recipes/testlinkcheck.json +0 -12
  384. package/fixtures/recipes/testloadtiming.json +0 -12
  385. package/fixtures/recipes/testvisualdiff.json +0 -12
  386. package/fixtures/workflows/changelog-digest-workflow.json +0 -13
  387. package/fixtures/workflows/form-survey-workflow.json +0 -13
  388. package/gallery.json +0 -706
  389. package/hardening.d.ts.map +0 -1
  390. package/hardening.js +0 -188
  391. package/headless.d.ts.map +0 -1
  392. package/headless.js +0 -11522
  393. package/http.d.ts.map +0 -1
  394. package/http.js +0 -2165
  395. package/index.cjs +0 -54682
  396. package/index.d.ts.map +0 -1
  397. package/index.js +0 -52310
  398. package/index.neutral.js +0 -46343
  399. package/mcp.d.ts.map +0 -1
  400. package/mcp.js +0 -20515
  401. package/memory.d.ts.map +0 -1
  402. package/nativehost.template.json +0 -10
  403. package/node.cjs +0 -54686
  404. package/node.d.ts.map +0 -1
  405. package/pack.d.ts.map +0 -1
  406. package/pack.js +0 -805
  407. package/policy.d.ts.map +0 -1
  408. package/progress.d.ts.map +0 -1
  409. package/progress.js +0 -645
  410. package/protocol.d.ts.map +0 -1
  411. package/protocol.js +0 -8334
  412. package/schemas/audit.schema.json +0 -226
  413. package/schemas/capability.schema.json +0 -113
  414. package/schemas/envelope.schema.json +0 -162
  415. package/schemas/memory.schema.json +0 -51
  416. package/schemas/observation.schema.json +0 -113
  417. package/schemas/plan.schema.json +0 -208
  418. package/schemas/progress.schema.json +0 -126
  419. package/schemas/proposal.schema.json +0 -68
  420. package/schemas/session.schema.json +0 -82
  421. package/schemas/tool.schema.json +0 -94
  422. package/server.d.ts.map +0 -1
  423. package/server.js +0 -28877
  424. package/umd-example.html +0 -18
  425. package/umd.d.ts.map +0 -1
  426. /package/{bun.d.ts → dist/bun.d.ts} +0 -0
  427. /package/{cli.d.ts → dist/cli.d.ts} +0 -0
  428. /package/{companion.d.ts → dist/companion.d.ts} +0 -0
  429. /package/{crossbrowser.d.ts → dist/crossbrowser.d.ts} +0 -0
  430. /package/{dashdone.d.ts → dist/dashdone.d.ts} +0 -0
  431. /package/{deno.d.ts → dist/deno.d.ts} +0 -0
  432. /package/{hardening.d.ts → dist/hardening.d.ts} +0 -0
  433. /package/{headless.d.ts → dist/headless.d.ts} +0 -0
  434. /package/{http.d.ts → dist/http.d.ts} +0 -0
  435. /package/{index.d.ts → dist/index.d.ts} +0 -0
  436. /package/{mcp.d.ts → dist/mcp.d.ts} +0 -0
  437. /package/{memory.d.ts → dist/memory.d.ts} +0 -0
  438. /package/{node.d.ts → dist/node.d.ts} +0 -0
  439. /package/{pack.d.ts → dist/pack.d.ts} +0 -0
  440. /package/{policy.d.ts → dist/policy.d.ts} +0 -0
  441. /package/{progress.d.ts → dist/progress.d.ts} +0 -0
  442. /package/{protocol.d.ts → dist/protocol.d.ts} +0 -0
  443. /package/{server.d.ts → dist/server.d.ts} +0 -0
  444. /package/{umd.d.ts → dist/umd.d.ts} +0 -0
@@ -0,0 +1,335 @@
1
+ import { describe, expect, it } from "vitest";
2
+ import {
3
+ answersampling,
4
+ assemblechunks,
5
+ callprompt,
6
+ cancelframeof,
7
+ canceltool,
8
+ chunkcontent,
9
+ listprompts,
10
+ notifyevent,
11
+ notifyprogress,
12
+ notifyresource,
13
+ readonlyeventkinds,
14
+ protocoleventkinds,
15
+ renderprompt,
16
+ requestsampling,
17
+ streamchunkof,
18
+ subscriberegister,
19
+ unsubscriberegister,
20
+ watchresource,
21
+ unwatchresource,
22
+ } from "../agent.js";
23
+ import type { callcontext, capabilityset, toolresult } from "../types.js";
24
+
25
+ const now = 1_800_000_000_000;
26
+
27
+ /** Builds one client capability set with the sampling flag the callbacks respect. */
28
+ function caps(sampling: boolean): capabilityset {
29
+ return {
30
+ protocolversion: "1.1.56",
31
+ name: "client",
32
+ version: "1",
33
+ toolversion: 1,
34
+ tools: 4,
35
+ namespaces: ["browser"],
36
+ transports: ["stdio"],
37
+ sampling,
38
+ prompts: true,
39
+ streaming: true,
40
+ };
41
+ }
42
+
43
+ describe("agentstream event subscriptions", () => {
44
+ it("registers subscriptions with their kinds and filters and refuses unknown kinds", () => {
45
+ const registered = subscriberegister({
46
+ clientid: "client1",
47
+ kinds: ["callresult", "progress"],
48
+ origin: "https://example.com",
49
+ tool: "browser.readtext",
50
+ now,
51
+ });
52
+ expect(registered.subscription?.kinds).toEqual(["callresult", "progress"]);
53
+ expect(registered.subscription?.origin).toBe("https://example.com");
54
+ expect(registered.subscription?.tool).toBe("browser.readtext");
55
+ expect(registered.subscription?.createdat).toBe(now);
56
+ const defaulted = subscriberegister({ clientid: "client1", now });
57
+ expect(defaulted.subscription?.kinds).toEqual(readonlyeventkinds);
58
+ expect(protocoleventkinds).toContain("callstarted");
59
+ expect(readonlyeventkinds).not.toContain("callstarted");
60
+ expect(subscriberegister({ clientid: "", now }).reason).toMatch(/paired client/i);
61
+ expect(subscriberegister({ clientid: "client1", kinds: ["bogus" as never], now }).reason).toMatch(
62
+ /not a protocol event kind/i,
63
+ );
64
+ expect(subscriberegister({ clientid: "client1", origin: " ", now }).reason).toMatch(/origin filter/i);
65
+ expect(subscriberegister({ clientid: "client1", tool: " ", now }).reason).toMatch(/tool filter/i);
66
+ });
67
+
68
+ it("unsubscribes by id while the record stays for the audit trail", () => {
69
+ const subscription = subscriberegister({ clientid: "client1", now, id: "sub1" }).subscription;
70
+ expect(subscription).toBeDefined();
71
+ const cancelled = unsubscriberegister([subscription as NonNullable<typeof subscription>], "sub1", now + 1);
72
+ expect(cancelled[0]?.canceledat).toBe(now + 1);
73
+ expect(unsubscriberegister(cancelled, "sub1", now + 2)[0]?.canceledat).toBe(now + 1);
74
+ });
75
+
76
+ it("pushes protocol events to the matching subscribers only", () => {
77
+ const one = subscriberegister({ clientid: "client1", kinds: ["callresult"], now, id: "sub1" })
78
+ .subscription as NonNullable<ReturnType<typeof subscriberegister>["subscription"]>;
79
+ const two = subscriberegister({
80
+ clientid: "client2",
81
+ kinds: ["callresult", "progress"],
82
+ origin: "https://example.com",
83
+ now,
84
+ id: "sub2",
85
+ }).subscription as NonNullable<ReturnType<typeof subscriberegister>["subscription"]>;
86
+ const three = subscriberegister({
87
+ clientid: "client3",
88
+ kinds: ["progress"],
89
+ tool: "browser.readtext",
90
+ now,
91
+ id: "sub3",
92
+ }).subscription as NonNullable<ReturnType<typeof subscriberegister>["subscription"]>;
93
+ const cancelled = {
94
+ ...(subscriberegister({ clientid: "client4", kinds: ["callresult"], now, id: "sub4" })
95
+ .subscription as NonNullable<ReturnType<typeof subscriberegister>["subscription"]>),
96
+ canceledat: now,
97
+ };
98
+ const delivered = notifyevent({
99
+ subscriptions: [one, two, three, cancelled],
100
+ kind: "callresult",
101
+ origin: "https://example.com",
102
+ tool: "browser.readtext",
103
+ payload: { ok: true },
104
+ now: now + 5,
105
+ });
106
+ expect(delivered.deliveries.map((delivery) => delivery.subscriptionid)).toEqual(["sub1", "sub2"]);
107
+ expect(delivered.deliveries[0]?.frame.method).toBe("events/notify");
108
+ expect(delivered.deliveries[0]?.frame.params?.kind).toBe("callresult");
109
+ expect(delivered.deliveries[0]?.frame.params?.payload).toEqual({ ok: true });
110
+ expect(delivered.subscriptions.find((subscription) => subscription.id === "sub1")?.lastdeliveredat).toBe(now + 5);
111
+ const filtered = notifyevent({
112
+ subscriptions: [two],
113
+ kind: "callresult",
114
+ origin: "https://other.example",
115
+ now: now + 6,
116
+ });
117
+ expect(filtered.deliveries).toHaveLength(0);
118
+ const toolevent = notifyevent({ subscriptions: [three], kind: "progress", tool: "browser.click", now });
119
+ expect(toolevent.deliveries).toHaveLength(0);
120
+ });
121
+ });
122
+
123
+ describe("agentstream resource watchers", () => {
124
+ it("starts watchers with the page state baseline and refuses empty resources", () => {
125
+ const watched = watchresource({
126
+ clientid: "client1",
127
+ resource: "page",
128
+ state: { url: "https://example.com", title: "Example" },
129
+ now,
130
+ });
131
+ expect(watched.watch?.baseline).toEqual({ url: "https://example.com", title: "Example" });
132
+ expect(watched.watch?.resource).toBe("page");
133
+ expect(watchresource({ clientid: "client1", resource: " ", now }).reason).toMatch(/resource it watches/i);
134
+ expect(watchresource({ clientid: "", resource: "page", now }).reason).toMatch(/paired client/i);
135
+ expect(watchresource({ clientid: "client1", resource: "page", now }).watch?.baseline).toEqual({});
136
+ });
137
+
138
+ it("pushes the page state deltas of changed keys and absorbs the baseline", () => {
139
+ const watch = watchresource({
140
+ clientid: "client1",
141
+ resource: "page",
142
+ state: { url: "https://example.com", title: "Example" },
143
+ now,
144
+ id: "watch1",
145
+ }).watch as NonNullable<ReturnType<typeof watchresource>["watch"]>;
146
+ const unchanged = notifyresource({
147
+ watches: [watch],
148
+ resource: "page",
149
+ state: { url: "https://example.com", title: "Example" },
150
+ now: now + 1,
151
+ });
152
+ expect(unchanged.deliveries).toHaveLength(0);
153
+ const changed = notifyresource({
154
+ watches: [watch],
155
+ resource: "page",
156
+ state: { url: "https://example.com/next", title: "Example" },
157
+ now: now + 2,
158
+ });
159
+ expect(changed.deliveries).toHaveLength(1);
160
+ expect(changed.deliveries[0]?.delta).toEqual({ url: "https://example.com/next" });
161
+ expect(changed.watches[0]?.baseline.url).toBe("https://example.com/next");
162
+ expect(changed.watches[0]?.lastdeliveredat).toBe(now + 2);
163
+ const other = notifyresource({
164
+ watches: changed.watches,
165
+ resource: "other",
166
+ state: { url: "https://elsewhere.example" },
167
+ now: now + 3,
168
+ });
169
+ expect(other.deliveries).toHaveLength(0);
170
+ const unwatched = unwatchresource(changed.watches, "watch1", now + 4);
171
+ expect(unwatched[0]?.canceledat).toBe(now + 4);
172
+ });
173
+ });
174
+
175
+ describe("agentstream sampling callbacks", () => {
176
+ it("sends sampling requests that respect the client capabilities and strip ungranted page content", () => {
177
+ const capable = requestsampling({
178
+ clientid: "client1",
179
+ capabilities: caps(true),
180
+ prompt: "Summarize the run.",
181
+ pagecontent: "the page text",
182
+ pagegrant: false,
183
+ now,
184
+ });
185
+ expect(capable.request?.prompt).toMatch(/page content stays stripped/i);
186
+ expect(capable.request?.pagecontent).toBeUndefined();
187
+ const granted = requestsampling({
188
+ clientid: "client1",
189
+ capabilities: caps(true),
190
+ prompt: "Summarize.",
191
+ pagecontent: "the page text",
192
+ pagegrant: true,
193
+ now,
194
+ });
195
+ expect(granted.request?.pagecontent).toBe("the page text");
196
+ expect(granted.request?.prompt).toBe("Summarize.");
197
+ expect(
198
+ requestsampling({ clientid: "client1", capabilities: caps(false), prompt: "Summarize.", now }).reason,
199
+ ).toMatch(/declared no sampling capability/i);
200
+ expect(requestsampling({ clientid: "client1", capabilities: caps(true), prompt: " ", now }).reason).toMatch(
201
+ /needs its prompt/i,
202
+ );
203
+ expect(
204
+ requestsampling({ clientid: "client1", capabilities: caps(true), prompt: "Summarize.", maxtokens: 0, now })
205
+ .reason,
206
+ ).toMatch(/positive user value/i);
207
+ expect(requestsampling({ clientid: "client1", prompt: "Summarize.", now }).request?.state).toBe("pending");
208
+ });
209
+
210
+ it("completes the sampling round trip with answers and refusals while closed requests stay untouched", () => {
211
+ const request = requestsampling({ clientid: "client1", prompt: "Summarize.", now, id: "sample1" })
212
+ .request as NonNullable<ReturnType<typeof requestsampling>["request"]>;
213
+ const answered = answersampling({ requests: [request], id: "sample1", answer: "the model answer", now: now + 10 });
214
+ expect(answered.request?.state).toBe("answered");
215
+ expect(answered.request?.answer).toBe("the model answer");
216
+ expect(answered.request?.answeredat).toBe(now + 10);
217
+ expect(answered.requests[0]?.answer).toBe("the model answer");
218
+ expect(
219
+ answersampling({ requests: answered.requests, id: "sample1", answer: "again", now: now + 20 }).reason,
220
+ ).toMatch(/already closed/i);
221
+ expect(answersampling({ requests: answered.requests, id: "missing", now }).reason).toMatch(
222
+ /names no stored request/i,
223
+ );
224
+ const refused = requestsampling({ clientid: "client2", prompt: "Summarize.", now, id: "sample2" })
225
+ .request as NonNullable<ReturnType<typeof requestsampling>["request"]>;
226
+ const closed = answersampling({ requests: [refused], id: "sample2", refused: true, now: now + 1 });
227
+ expect(closed.request?.state).toBe("refused");
228
+ expect(closed.request?.answer).toBeUndefined();
229
+ });
230
+ });
231
+
232
+ describe("agentstream prompt tools", () => {
233
+ it("lists the prompt defs exposed as callable tools", () => {
234
+ const prompts = listprompts();
235
+ expect(prompts.map((prompt) => prompt.name)).toEqual(["runreview", "pagesummary", "failuretriage"]);
236
+ for (const prompt of prompts) {
237
+ expect(prompt.template).toMatch(/\{\{/);
238
+ expect(prompt.arguments.length).toBeGreaterThan(0);
239
+ }
240
+ });
241
+
242
+ it("renders the templates and calls the prompts with defaults and required refusals", () => {
243
+ const runreview = listprompts().find((prompt) => prompt.name === "runreview");
244
+ expect(runreview).toBeDefined();
245
+ const rendered = renderprompt(runreview as NonNullable<typeof runreview>, {
246
+ objective: "fill the form",
247
+ steps: "click, type",
248
+ tone: "plain",
249
+ });
250
+ expect(rendered).toContain("fill the form");
251
+ expect(rendered).toContain("click, type");
252
+ expect(rendered.includes("{{")).toBe(false);
253
+ const called = callprompt({ name: "runreview", args: { objective: "fill the form", steps: "click, type" } });
254
+ expect(called.toolcall?.name).toBe("prompts.runreview");
255
+ expect(called.toolcall?.params.arguments).toMatchObject({
256
+ objective: "fill the form",
257
+ steps: "click, type",
258
+ tone: "plain",
259
+ });
260
+ expect(called.rendered).toContain("fill the form");
261
+ expect(callprompt({ name: "runreview", args: { steps: "click, type" } }).reason).toMatch(/objective is required/i);
262
+ expect(callprompt({ name: "bogus" }).reason).toMatch(/no prompt named bogus/i);
263
+ const missing = renderprompt(runreview as NonNullable<typeof runreview>, { objective: "x" });
264
+ expect(missing).toContain("{{steps}}");
265
+ });
266
+ });
267
+
268
+ describe("agentstream streaming, progress and cancellation", () => {
269
+ it("emits ordered stream chunks with the done marker and reassembles them", () => {
270
+ const chunk = streamchunkof({ callid: "call1", seq: 1, content: "hello ", now });
271
+ expect(chunk).toMatchObject({ callid: "call1", seq: 1, content: "hello ", done: false });
272
+ const chunks = chunkcontent({ callid: "call1", content: "abcdefghij", size: 4, now });
273
+ expect(chunks.map((piece) => piece.content)).toEqual(["abcd", "efgh", "ij"]);
274
+ expect(chunks.map((piece) => piece.done)).toEqual([false, false, true]);
275
+ expect(assemblechunks(chunks)).toBe("abcdefghij");
276
+ expect(assemblechunks([chunks[2] as never, chunks[0] as never, chunks[1] as never])).toBe("abcdefghij");
277
+ expect(chunkcontent({ callid: "call2", content: "", now })).toEqual([
278
+ expect.objectContaining({ content: "", done: true }),
279
+ ]);
280
+ });
281
+
282
+ it("emits progress notices with percent, message and cancel hint", () => {
283
+ const notice = notifyprogress({ callid: "call1", percent: 45, message: "Typing the reviewed field.", now });
284
+ expect(notice).toMatchObject({
285
+ callid: "call1",
286
+ percent: 45,
287
+ message: "Typing the reviewed field.",
288
+ cancellable: true,
289
+ });
290
+ const nocancel = notifyprogress({ callid: "call1", message: "Finishing.", cancellable: false, now });
291
+ expect(nocancel.cancellable).toBe(false);
292
+ expect(nocancel.percent).toBeUndefined();
293
+ });
294
+
295
+ it("aborts in flight calls on their cancel frame and preserves the partial result", () => {
296
+ const frame = cancelframeof({ callid: "call1", reason: "the user asked", now });
297
+ expect(frame).toMatchObject({ callid: "call1", reason: "the user asked", at: now });
298
+ expect(cancelframeof({ callid: "call1", now }).reason).toBeUndefined();
299
+ const partial: toolresult = { content: "the first chunks", iserror: false };
300
+ const inflight: callcontext = {
301
+ callid: "call1",
302
+ clientid: "client1",
303
+ tool: "browser.readtext",
304
+ state: "inflight",
305
+ startedat: now,
306
+ chunks: 2,
307
+ };
308
+ const aborted = canceltool({
309
+ contexts: [inflight],
310
+ callid: "call1",
311
+ reason: "the user asked",
312
+ partial,
313
+ now: now + 100,
314
+ });
315
+ expect(aborted.context?.state).toBe("cancelled");
316
+ expect(aborted.context?.partial).toEqual(partial);
317
+ expect(aborted.context?.endedat).toBe(now + 100);
318
+ expect(canceltool({ contexts: aborted.contexts, callid: "call1", now: now + 200 }).reason).toMatch(
319
+ /already left the in flight state/i,
320
+ );
321
+ expect(canceltool({ contexts: aborted.contexts, callid: "missing", now }).reason).toMatch(/names no call context/i);
322
+ const finished: callcontext = {
323
+ callid: "call2",
324
+ clientid: "client1",
325
+ tool: "memory.list",
326
+ state: "done",
327
+ startedat: now,
328
+ endedat: now + 1,
329
+ chunks: 1,
330
+ };
331
+ expect(canceltool({ contexts: [finished], callid: "call2", now }).reason).toMatch(
332
+ /already left the in flight state/i,
333
+ );
334
+ });
335
+ });