@beeos-ai/device-agent 0.4.0

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 (398) hide show
  1. package/.pi/extensions/android-tools.ts +139 -0
  2. package/.pi/skills/.gitkeep +0 -0
  3. package/.pi/skills/ground-mobile-fallback/SKILL.md +50 -0
  4. package/LICENSE +201 -0
  5. package/dist/action/handler.d.ts +9 -0
  6. package/dist/action/handler.js +124 -0
  7. package/dist/action/handler.js.map +1 -0
  8. package/dist/adapters/agent-gateway-client.d.ts +256 -0
  9. package/dist/adapters/agent-gateway-client.js +332 -0
  10. package/dist/adapters/agent-gateway-client.js.map +1 -0
  11. package/dist/adapters/agentcore-inner-loop.d.ts +29 -0
  12. package/dist/adapters/agentcore-inner-loop.js +72 -0
  13. package/dist/adapters/agentcore-inner-loop.js.map +1 -0
  14. package/dist/adapters/agentcore-pi.d.ts +215 -0
  15. package/dist/adapters/agentcore-pi.js +464 -0
  16. package/dist/adapters/agentcore-pi.js.map +1 -0
  17. package/dist/adapters/agentcore-runner.d.ts +70 -0
  18. package/dist/adapters/agentcore-runner.js +255 -0
  19. package/dist/adapters/agentcore-runner.js.map +1 -0
  20. package/dist/adapters/device-android-adb.d.ts +41 -0
  21. package/dist/adapters/device-android-adb.js +279 -0
  22. package/dist/adapters/device-android-adb.js.map +1 -0
  23. package/dist/adapters/device-desktop.d.ts +37 -0
  24. package/dist/adapters/device-desktop.js +101 -0
  25. package/dist/adapters/device-desktop.js.map +1 -0
  26. package/dist/adapters/identity-file.d.ts +30 -0
  27. package/dist/adapters/identity-file.js +50 -0
  28. package/dist/adapters/identity-file.js.map +1 -0
  29. package/dist/adapters/transport-bridge-ws.d.ts +39 -0
  30. package/dist/adapters/transport-bridge-ws.js +49 -0
  31. package/dist/adapters/transport-bridge-ws.js.map +1 -0
  32. package/dist/adapters/vlm-inner-loop.d.ts +88 -0
  33. package/dist/adapters/vlm-inner-loop.js +199 -0
  34. package/dist/adapters/vlm-inner-loop.js.map +1 -0
  35. package/dist/agent-runtime/adapters/base.d.ts +145 -0
  36. package/dist/agent-runtime/adapters/base.js +29 -0
  37. package/dist/agent-runtime/adapters/base.js.map +1 -0
  38. package/dist/agent-runtime/adapters/index.d.ts +17 -0
  39. package/dist/agent-runtime/adapters/index.js +17 -0
  40. package/dist/agent-runtime/adapters/index.js.map +1 -0
  41. package/dist/agent-runtime/adapters/mock.d.ts +44 -0
  42. package/dist/agent-runtime/adapters/mock.js +54 -0
  43. package/dist/agent-runtime/adapters/mock.js.map +1 -0
  44. package/dist/agent-runtime/adapters/openai.d.ts +63 -0
  45. package/dist/agent-runtime/adapters/openai.js +302 -0
  46. package/dist/agent-runtime/adapters/openai.js.map +1 -0
  47. package/dist/agent-runtime/adapters/registry.d.ts +49 -0
  48. package/dist/agent-runtime/adapters/registry.js +129 -0
  49. package/dist/agent-runtime/adapters/registry.js.map +1 -0
  50. package/dist/agent-runtime/adapters/ui-tars.d.ts +13 -0
  51. package/dist/agent-runtime/adapters/ui-tars.js +22 -0
  52. package/dist/agent-runtime/adapters/ui-tars.js.map +1 -0
  53. package/dist/agent-runtime/agent-runner.d.ts +149 -0
  54. package/dist/agent-runtime/agent-runner.js +356 -0
  55. package/dist/agent-runtime/agent-runner.js.map +1 -0
  56. package/dist/agent-runtime/core.d.ts +170 -0
  57. package/dist/agent-runtime/core.js +624 -0
  58. package/dist/agent-runtime/core.js.map +1 -0
  59. package/dist/agent-runtime/index.d.ts +16 -0
  60. package/dist/agent-runtime/index.js +17 -0
  61. package/dist/agent-runtime/index.js.map +1 -0
  62. package/dist/agent-runtime/plan-executor.d.ts +118 -0
  63. package/dist/agent-runtime/plan-executor.js +501 -0
  64. package/dist/agent-runtime/plan-executor.js.map +1 -0
  65. package/dist/agent-runtime/planner/base.d.ts +128 -0
  66. package/dist/agent-runtime/planner/base.js +157 -0
  67. package/dist/agent-runtime/planner/base.js.map +1 -0
  68. package/dist/agent-runtime/planner/llm-planner.d.ts +58 -0
  69. package/dist/agent-runtime/planner/llm-planner.js +112 -0
  70. package/dist/agent-runtime/planner/llm-planner.js.map +1 -0
  71. package/dist/agent-runtime/planner/noop-planner.d.ts +13 -0
  72. package/dist/agent-runtime/planner/noop-planner.js +30 -0
  73. package/dist/agent-runtime/planner/noop-planner.js.map +1 -0
  74. package/dist/agent-runtime/planner/prompts.d.ts +33 -0
  75. package/dist/agent-runtime/planner/prompts.js +165 -0
  76. package/dist/agent-runtime/planner/prompts.js.map +1 -0
  77. package/dist/agent-runtime/reflection.d.ts +81 -0
  78. package/dist/agent-runtime/reflection.js +189 -0
  79. package/dist/agent-runtime/reflection.js.map +1 -0
  80. package/dist/agent-runtime/reflectors/action-reflector.d.ts +97 -0
  81. package/dist/agent-runtime/reflectors/action-reflector.js +233 -0
  82. package/dist/agent-runtime/reflectors/action-reflector.js.map +1 -0
  83. package/dist/agent-runtime/reflectors/policy.d.ts +53 -0
  84. package/dist/agent-runtime/reflectors/policy.js +106 -0
  85. package/dist/agent-runtime/reflectors/policy.js.map +1 -0
  86. package/dist/agent-runtime/reflectors/trajectory-reflector.d.ts +94 -0
  87. package/dist/agent-runtime/reflectors/trajectory-reflector.js +223 -0
  88. package/dist/agent-runtime/reflectors/trajectory-reflector.js.map +1 -0
  89. package/dist/agent-runtime/skills/embedding.d.ts +53 -0
  90. package/dist/agent-runtime/skills/embedding.js +134 -0
  91. package/dist/agent-runtime/skills/embedding.js.map +1 -0
  92. package/dist/agent-runtime/skills/fs-store.d.ts +88 -0
  93. package/dist/agent-runtime/skills/fs-store.js +483 -0
  94. package/dist/agent-runtime/skills/fs-store.js.map +1 -0
  95. package/dist/agent-runtime/skills/index.d.ts +10 -0
  96. package/dist/agent-runtime/skills/index.js +10 -0
  97. package/dist/agent-runtime/skills/index.js.map +1 -0
  98. package/dist/agent-runtime/skills/matcher-evolver.d.ts +88 -0
  99. package/dist/agent-runtime/skills/matcher-evolver.js +110 -0
  100. package/dist/agent-runtime/skills/matcher-evolver.js.map +1 -0
  101. package/dist/agent-runtime/skills/memory-store.d.ts +23 -0
  102. package/dist/agent-runtime/skills/memory-store.js +94 -0
  103. package/dist/agent-runtime/skills/memory-store.js.map +1 -0
  104. package/dist/agent-runtime/skills/normalise.d.ts +40 -0
  105. package/dist/agent-runtime/skills/normalise.js +152 -0
  106. package/dist/agent-runtime/skills/normalise.js.map +1 -0
  107. package/dist/agent-runtime/skills/replay.d.ts +46 -0
  108. package/dist/agent-runtime/skills/replay.js +106 -0
  109. package/dist/agent-runtime/skills/replay.js.map +1 -0
  110. package/dist/agent-runtime/skills/sqlite-store.d.ts +60 -0
  111. package/dist/agent-runtime/skills/sqlite-store.js +234 -0
  112. package/dist/agent-runtime/skills/sqlite-store.js.map +1 -0
  113. package/dist/agent-runtime/skills/types.d.ts +99 -0
  114. package/dist/agent-runtime/skills/types.js +14 -0
  115. package/dist/agent-runtime/skills/types.js.map +1 -0
  116. package/dist/agent.d.ts +110 -0
  117. package/dist/agent.js +162 -0
  118. package/dist/agent.js.map +1 -0
  119. package/dist/api.d.ts +27 -0
  120. package/dist/api.js +48 -0
  121. package/dist/api.js.map +1 -0
  122. package/dist/app/agent-host.d.ts +59 -0
  123. package/dist/app/agent-host.js +263 -0
  124. package/dist/app/agent-host.js.map +1 -0
  125. package/dist/app/device-manager.d.ts +28 -0
  126. package/dist/app/device-manager.js +64 -0
  127. package/dist/app/device-manager.js.map +1 -0
  128. package/dist/app/message-store.d.ts +55 -0
  129. package/dist/app/message-store.js +99 -0
  130. package/dist/app/message-store.js.map +1 -0
  131. package/dist/app/session-manager.d.ts +132 -0
  132. package/dist/app/session-manager.js +350 -0
  133. package/dist/app/session-manager.js.map +1 -0
  134. package/dist/bootstrap.d.ts +94 -0
  135. package/dist/bootstrap.js +459 -0
  136. package/dist/bootstrap.js.map +1 -0
  137. package/dist/chat.d.ts +16 -0
  138. package/dist/chat.js +175 -0
  139. package/dist/chat.js.map +1 -0
  140. package/dist/config/loader.d.ts +77 -0
  141. package/dist/config/loader.js +292 -0
  142. package/dist/config/loader.js.map +1 -0
  143. package/dist/config/schema.d.ts +162 -0
  144. package/dist/config/schema.js +243 -0
  145. package/dist/config/schema.js.map +1 -0
  146. package/dist/core/actions.d.ts +60 -0
  147. package/dist/core/actions.js +120 -0
  148. package/dist/core/actions.js.map +1 -0
  149. package/dist/core/errors.d.ts +8 -0
  150. package/dist/core/errors.js +9 -0
  151. package/dist/core/errors.js.map +1 -0
  152. package/dist/core/screen.d.ts +7 -0
  153. package/dist/core/screen.js +8 -0
  154. package/dist/core/screen.js.map +1 -0
  155. package/dist/core/session.d.ts +42 -0
  156. package/dist/core/session.js +29 -0
  157. package/dist/core/session.js.map +1 -0
  158. package/dist/debug/dump-system-prompt.d.ts +1 -0
  159. package/dist/debug/dump-system-prompt.js +34 -0
  160. package/dist/debug/dump-system-prompt.js.map +1 -0
  161. package/dist/device/android.d.ts +25 -0
  162. package/dist/device/android.js +231 -0
  163. package/dist/device/android.js.map +1 -0
  164. package/dist/device/apps.d.ts +3 -0
  165. package/dist/device/apps.js +77 -0
  166. package/dist/device/apps.js.map +1 -0
  167. package/dist/device/base.d.ts +20 -0
  168. package/dist/device/base.js +2 -0
  169. package/dist/device/base.js.map +1 -0
  170. package/dist/device/ui-xml.d.ts +29 -0
  171. package/dist/device/ui-xml.js +194 -0
  172. package/dist/device/ui-xml.js.map +1 -0
  173. package/dist/fleet/adapters/process/node-process-manager.d.ts +157 -0
  174. package/dist/fleet/adapters/process/node-process-manager.js +664 -0
  175. package/dist/fleet/adapters/process/node-process-manager.js.map +1 -0
  176. package/dist/fleet/adapters/sources/local-adb.d.ts +105 -0
  177. package/dist/fleet/adapters/sources/local-adb.js +353 -0
  178. package/dist/fleet/adapters/sources/local-adb.js.map +1 -0
  179. package/dist/fleet/adapters/sources/remote-adb.d.ts +97 -0
  180. package/dist/fleet/adapters/sources/remote-adb.js +138 -0
  181. package/dist/fleet/adapters/sources/remote-adb.js.map +1 -0
  182. package/dist/fleet/adapters/state/beeos-cli-store.d.ts +72 -0
  183. package/dist/fleet/adapters/state/beeos-cli-store.js +250 -0
  184. package/dist/fleet/adapters/state/beeos-cli-store.js.map +1 -0
  185. package/dist/fleet/adapters/state/port-allocator.d.ts +43 -0
  186. package/dist/fleet/adapters/state/port-allocator.js +173 -0
  187. package/dist/fleet/adapters/state/port-allocator.js.map +1 -0
  188. package/dist/fleet/domain/device.d.ts +138 -0
  189. package/dist/fleet/domain/device.js +49 -0
  190. package/dist/fleet/domain/device.js.map +1 -0
  191. package/dist/fleet/domain/events.d.ts +102 -0
  192. package/dist/fleet/domain/events.js +15 -0
  193. package/dist/fleet/domain/events.js.map +1 -0
  194. package/dist/fleet/domain/fsm.d.ts +122 -0
  195. package/dist/fleet/domain/fsm.js +475 -0
  196. package/dist/fleet/domain/fsm.js.map +1 -0
  197. package/dist/fleet/http/status-client.d.ts +31 -0
  198. package/dist/fleet/http/status-client.js +115 -0
  199. package/dist/fleet/http/status-client.js.map +1 -0
  200. package/dist/fleet/http/status-server.d.ts +64 -0
  201. package/dist/fleet/http/status-server.js +200 -0
  202. package/dist/fleet/http/status-server.js.map +1 -0
  203. package/dist/fleet/index.d.ts +27 -0
  204. package/dist/fleet/index.js +17 -0
  205. package/dist/fleet/index.js.map +1 -0
  206. package/dist/fleet/installer/index.d.ts +12 -0
  207. package/dist/fleet/installer/index.js +13 -0
  208. package/dist/fleet/installer/index.js.map +1 -0
  209. package/dist/fleet/installer/launchd-mac.d.ts +73 -0
  210. package/dist/fleet/installer/launchd-mac.js +291 -0
  211. package/dist/fleet/installer/launchd-mac.js.map +1 -0
  212. package/dist/fleet/installer/service-spec.d.ts +70 -0
  213. package/dist/fleet/installer/service-spec.js +43 -0
  214. package/dist/fleet/installer/service-spec.js.map +1 -0
  215. package/dist/fleet/installer/spawn-env.d.ts +45 -0
  216. package/dist/fleet/installer/spawn-env.js +224 -0
  217. package/dist/fleet/installer/spawn-env.js.map +1 -0
  218. package/dist/fleet/ports/clock.d.ts +19 -0
  219. package/dist/fleet/ports/clock.js +26 -0
  220. package/dist/fleet/ports/clock.js.map +1 -0
  221. package/dist/fleet/ports/device-source.d.ts +28 -0
  222. package/dist/fleet/ports/device-source.js +18 -0
  223. package/dist/fleet/ports/device-source.js.map +1 -0
  224. package/dist/fleet/ports/process-manager.d.ts +110 -0
  225. package/dist/fleet/ports/process-manager.js +27 -0
  226. package/dist/fleet/ports/process-manager.js.map +1 -0
  227. package/dist/fleet/ports/state-registry.d.ts +49 -0
  228. package/dist/fleet/ports/state-registry.js +12 -0
  229. package/dist/fleet/ports/state-registry.js.map +1 -0
  230. package/dist/fleet/supervisor.d.ts +107 -0
  231. package/dist/fleet/supervisor.js +508 -0
  232. package/dist/fleet/supervisor.js.map +1 -0
  233. package/dist/grounding/grounder.d.ts +46 -0
  234. package/dist/grounding/grounder.js +82 -0
  235. package/dist/grounding/grounder.js.map +1 -0
  236. package/dist/inbound/acp/handlers/device.d.ts +43 -0
  237. package/dist/inbound/acp/handlers/device.js +153 -0
  238. package/dist/inbound/acp/handlers/device.js.map +1 -0
  239. package/dist/inbound/acp/handlers/initialize.d.ts +71 -0
  240. package/dist/inbound/acp/handlers/initialize.js +53 -0
  241. package/dist/inbound/acp/handlers/initialize.js.map +1 -0
  242. package/dist/inbound/acp/handlers/models.d.ts +16 -0
  243. package/dist/inbound/acp/handlers/models.js +23 -0
  244. package/dist/inbound/acp/handlers/models.js.map +1 -0
  245. package/dist/inbound/acp/handlers/session.d.ts +51 -0
  246. package/dist/inbound/acp/handlers/session.js +61 -0
  247. package/dist/inbound/acp/handlers/session.js.map +1 -0
  248. package/dist/inbound/acp/handlers/skills.d.ts +8 -0
  249. package/dist/inbound/acp/handlers/skills.js +9 -0
  250. package/dist/inbound/acp/handlers/skills.js.map +1 -0
  251. package/dist/inbound/acp/notifier.d.ts +35 -0
  252. package/dist/inbound/acp/notifier.js +45 -0
  253. package/dist/inbound/acp/notifier.js.map +1 -0
  254. package/dist/inbound/acp/router.d.ts +67 -0
  255. package/dist/inbound/acp/router.js +179 -0
  256. package/dist/inbound/acp/router.js.map +1 -0
  257. package/dist/inbound/cli/fleet-command.d.ts +34 -0
  258. package/dist/inbound/cli/fleet-command.js +792 -0
  259. package/dist/inbound/cli/fleet-command.js.map +1 -0
  260. package/dist/inbound/cli/main.d.ts +38 -0
  261. package/dist/inbound/cli/main.js +364 -0
  262. package/dist/inbound/cli/main.js.map +1 -0
  263. package/dist/inbound/cli/run-command.d.ts +101 -0
  264. package/dist/inbound/cli/run-command.js +405 -0
  265. package/dist/inbound/cli/run-command.js.map +1 -0
  266. package/dist/inbound/cli/skills-command.d.ts +39 -0
  267. package/dist/inbound/cli/skills-command.js +333 -0
  268. package/dist/inbound/cli/skills-command.js.map +1 -0
  269. package/dist/inbound/http/server.d.ts +7 -0
  270. package/dist/inbound/http/server.js +8 -0
  271. package/dist/inbound/http/server.js.map +1 -0
  272. package/dist/index.d.ts +66 -0
  273. package/dist/index.js +48 -0
  274. package/dist/index.js.map +1 -0
  275. package/dist/logger/index.d.ts +37 -0
  276. package/dist/logger/index.js +84 -0
  277. package/dist/logger/index.js.map +1 -0
  278. package/dist/mcp-client/autospawn.d.ts +67 -0
  279. package/dist/mcp-client/autospawn.js +173 -0
  280. package/dist/mcp-client/autospawn.js.map +1 -0
  281. package/dist/mcp-client/client.d.ts +78 -0
  282. package/dist/mcp-client/client.js +168 -0
  283. package/dist/mcp-client/client.js.map +1 -0
  284. package/dist/mcp-client/index.d.ts +7 -0
  285. package/dist/mcp-client/index.js +4 -0
  286. package/dist/mcp-client/index.js.map +1 -0
  287. package/dist/mcp-client/inproc.d.ts +47 -0
  288. package/dist/mcp-client/inproc.js +229 -0
  289. package/dist/mcp-client/inproc.js.map +1 -0
  290. package/dist/mcp-client/runtime.d.ts +34 -0
  291. package/dist/mcp-client/runtime.js +15 -0
  292. package/dist/mcp-client/runtime.js.map +1 -0
  293. package/dist/model/adapters/autoglm.d.ts +31 -0
  294. package/dist/model/adapters/autoglm.js +409 -0
  295. package/dist/model/adapters/autoglm.js.map +1 -0
  296. package/dist/model/adapters/base.d.ts +13 -0
  297. package/dist/model/adapters/base.js +27 -0
  298. package/dist/model/adapters/base.js.map +1 -0
  299. package/dist/model/adapters/guiowl.d.ts +1 -0
  300. package/dist/model/adapters/guiowl.js +253 -0
  301. package/dist/model/adapters/guiowl.js.map +1 -0
  302. package/dist/model/adapters/index.d.ts +6 -0
  303. package/dist/model/adapters/index.js +8 -0
  304. package/dist/model/adapters/index.js.map +1 -0
  305. package/dist/model/adapters/maiui.d.ts +1 -0
  306. package/dist/model/adapters/maiui.js +117 -0
  307. package/dist/model/adapters/maiui.js.map +1 -0
  308. package/dist/model/adapters/qwenvl.d.ts +1 -0
  309. package/dist/model/adapters/qwenvl.js +108 -0
  310. package/dist/model/adapters/qwenvl.js.map +1 -0
  311. package/dist/model/adapters/showui.d.ts +1 -0
  312. package/dist/model/adapters/showui.js +132 -0
  313. package/dist/model/adapters/showui.js.map +1 -0
  314. package/dist/model/adapters/tool-call.d.ts +6 -0
  315. package/dist/model/adapters/tool-call.js +102 -0
  316. package/dist/model/adapters/tool-call.js.map +1 -0
  317. package/dist/model/adapters/uitars.d.ts +1 -0
  318. package/dist/model/adapters/uitars.js +180 -0
  319. package/dist/model/adapters/uitars.js.map +1 -0
  320. package/dist/model/base.d.ts +32 -0
  321. package/dist/model/base.js +2 -0
  322. package/dist/model/base.js.map +1 -0
  323. package/dist/model/client.d.ts +26 -0
  324. package/dist/model/client.js +300 -0
  325. package/dist/model/client.js.map +1 -0
  326. package/dist/model/image/compress.d.ts +53 -0
  327. package/dist/model/image/compress.js +89 -0
  328. package/dist/model/image/compress.js.map +1 -0
  329. package/dist/model/image/transport.d.ts +134 -0
  330. package/dist/model/image/transport.js +154 -0
  331. package/dist/model/image/transport.js.map +1 -0
  332. package/dist/orchestrator-system-prompt.d.ts +6 -0
  333. package/dist/orchestrator-system-prompt.js +81 -0
  334. package/dist/orchestrator-system-prompt.js.map +1 -0
  335. package/dist/pi-context.d.ts +82 -0
  336. package/dist/pi-context.js +62 -0
  337. package/dist/pi-context.js.map +1 -0
  338. package/dist/pi-local-skills.d.ts +17 -0
  339. package/dist/pi-local-skills.js +24 -0
  340. package/dist/pi-local-skills.js.map +1 -0
  341. package/dist/plugins/acp/index.d.ts +46 -0
  342. package/dist/plugins/acp/index.js +111 -0
  343. package/dist/plugins/acp/index.js.map +1 -0
  344. package/dist/plugins/agent-sync/index.d.ts +40 -0
  345. package/dist/plugins/agent-sync/index.js +98 -0
  346. package/dist/plugins/agent-sync/index.js.map +1 -0
  347. package/dist/plugins/http-debug/index.d.ts +30 -0
  348. package/dist/plugins/http-debug/index.js +64 -0
  349. package/dist/plugins/http-debug/index.js.map +1 -0
  350. package/dist/plugins/http-debug/server.d.ts +92 -0
  351. package/dist/plugins/http-debug/server.js +464 -0
  352. package/dist/plugins/http-debug/server.js.map +1 -0
  353. package/dist/ports/agent-core.d.ts +158 -0
  354. package/dist/ports/agent-core.js +2 -0
  355. package/dist/ports/agent-core.js.map +1 -0
  356. package/dist/ports/agent-host.d.ts +125 -0
  357. package/dist/ports/agent-host.js +23 -0
  358. package/dist/ports/agent-host.js.map +1 -0
  359. package/dist/ports/device.d.ts +53 -0
  360. package/dist/ports/device.js +13 -0
  361. package/dist/ports/device.js.map +1 -0
  362. package/dist/ports/identity.d.ts +22 -0
  363. package/dist/ports/identity.js +9 -0
  364. package/dist/ports/identity.js.map +1 -0
  365. package/dist/ports/plugin.d.ts +62 -0
  366. package/dist/ports/plugin.js +35 -0
  367. package/dist/ports/plugin.js.map +1 -0
  368. package/dist/ports/transport.d.ts +32 -0
  369. package/dist/ports/transport.js +12 -0
  370. package/dist/ports/transport.js.map +1 -0
  371. package/dist/ports/vlm.d.ts +59 -0
  372. package/dist/ports/vlm.js +14 -0
  373. package/dist/ports/vlm.js.map +1 -0
  374. package/dist/test-lan-autoglm.d.ts +7 -0
  375. package/dist/test-lan-autoglm.js +46 -0
  376. package/dist/test-lan-autoglm.js.map +1 -0
  377. package/dist/test-mem-breakdown.d.ts +1 -0
  378. package/dist/test-mem-breakdown.js +103 -0
  379. package/dist/test-mem-breakdown.js.map +1 -0
  380. package/dist/test-mem.d.ts +1 -0
  381. package/dist/test-mem.js +60 -0
  382. package/dist/test-mem.js.map +1 -0
  383. package/dist/test-mobile-use.d.ts +1 -0
  384. package/dist/test-mobile-use.js +18 -0
  385. package/dist/test-mobile-use.js.map +1 -0
  386. package/dist/test-screenshot-loop.d.ts +1 -0
  387. package/dist/test-screenshot-loop.js +43 -0
  388. package/dist/test-screenshot-loop.js.map +1 -0
  389. package/dist/test-screenshot.d.ts +1 -0
  390. package/dist/test-screenshot.js +10 -0
  391. package/dist/test-screenshot.js.map +1 -0
  392. package/dist/test-ui-xml-dump.d.ts +15 -0
  393. package/dist/test-ui-xml-dump.js +49 -0
  394. package/dist/test-ui-xml-dump.js.map +1 -0
  395. package/dist/types.d.ts +69 -0
  396. package/dist/types.js +23 -0
  397. package/dist/types.js.map +1 -0
  398. package/package.json +94 -0
@@ -0,0 +1,508 @@
1
+ /**
2
+ * Fleet supervisor — orchestrator that translates the pure FSM (`domain/fsm.ts`)
3
+ * effects into real side effects against the adapter ports.
4
+ *
5
+ * Responsibilities:
6
+ *
7
+ * 1. Wire `IDeviceSource` (ADB events), `IStateRegistry` (devices.json),
8
+ * `IProcessManager` (mcp + daemon spawn/kill) and `IClock` (timers).
9
+ * 2. Maintain one `DeviceRecord` per serial discovered from EITHER source
10
+ * (a device with a binding but no ADB → `adb_offline`; a device with
11
+ * ADB but no binding → `awaiting_bind`).
12
+ * 3. For every event, call `step()` to compute `(record', effects)` and
13
+ * enact each effect (spawn / kill / timer / port allocation / log).
14
+ * 4. Track `mcpAlive` / `daemonAlive` outside the FSM and call
15
+ * `markHealthy()` when both are observed in `spawning`.
16
+ * 5. Expose a read-only `snapshot()` for the HTTP `/fleet/devices` endpoint
17
+ * in M4.
18
+ *
19
+ * Concurrency model: single async serializer. All inbound events queue through
20
+ * `dispatch()` which pulls one at a time. This guarantees a coherent view of
21
+ * the FSM during multi-effect transitions and removes any need for locks.
22
+ */
23
+ import { newDeviceRecord, stateExpectsDaemon, stateExpectsMcp } from "./domain/device.js";
24
+ import { backoffMs, markHealthy, step, } from "./domain/fsm.js";
25
+ import { SystemClock } from "./ports/clock.js";
26
+ const noopLogger = {
27
+ debug: () => { },
28
+ info: () => { },
29
+ warn: () => { },
30
+ error: () => { },
31
+ };
32
+ // ── FleetSupervisor ─────────────────────────────────────────────────────────
33
+ export class FleetSupervisor {
34
+ source;
35
+ registry;
36
+ allocator;
37
+ processManager;
38
+ clock;
39
+ graceMs;
40
+ keepMs;
41
+ logger;
42
+ defaultAgentGatewayUrl;
43
+ slots = new Map();
44
+ queue = [];
45
+ dispatching = false;
46
+ started = false;
47
+ unsubAdb = null;
48
+ unsubBinding = null;
49
+ unsubProcess = null;
50
+ constructor(opts) {
51
+ this.source = opts.source;
52
+ this.registry = opts.registry;
53
+ this.allocator = opts.allocator;
54
+ this.processManager = opts.processManager;
55
+ this.clock = opts.clock ?? new SystemClock();
56
+ this.graceMs = opts.graceMs ?? readEnvMs("FLEET_ADB_GRACE_MS", 5_000);
57
+ this.keepMs = opts.keepMs ?? readEnvMs("FLEET_DAEMON_KEEP_MS", 300_000);
58
+ this.logger = opts.logger ?? noopLogger;
59
+ this.defaultAgentGatewayUrl = opts.defaultAgentGatewayUrl;
60
+ }
61
+ async start() {
62
+ if (this.started)
63
+ return;
64
+ this.started = true;
65
+ await this.allocator.start();
66
+ await this.registry.start();
67
+ await this.processManager.start();
68
+ // Seed in-memory slots from currently-known bindings (devices that have
69
+ // been attached but ADB hasn't connected yet → `adb_offline`).
70
+ for (const binding of this.registry.list()) {
71
+ this.ensureSlot(binding.serial, binding);
72
+ }
73
+ // Subscribe to events BEFORE starting the source so the initial-sync
74
+ // snapshot is observed.
75
+ this.unsubAdb = this.source.on((ev) => this.enqueue(ev));
76
+ this.unsubBinding = this.registry.on((ev) => this.enqueue(ev));
77
+ this.unsubProcess = this.processManager.on((ev) => this.enqueue(ev));
78
+ await this.source.start();
79
+ }
80
+ async stop() {
81
+ if (!this.started)
82
+ return;
83
+ this.started = false;
84
+ this.unsubAdb?.();
85
+ this.unsubBinding?.();
86
+ this.unsubProcess?.();
87
+ this.unsubAdb = null;
88
+ this.unsubBinding = null;
89
+ this.unsubProcess = null;
90
+ for (const slot of this.slots.values()) {
91
+ slot.graceTimer?.();
92
+ slot.keepTimer?.();
93
+ slot.backoffTimer?.();
94
+ slot.graceTimer = undefined;
95
+ slot.keepTimer = undefined;
96
+ slot.backoffTimer = undefined;
97
+ }
98
+ await this.source.stop();
99
+ await this.processManager.stop();
100
+ await this.registry.stop();
101
+ await this.allocator.stop();
102
+ }
103
+ /** Read-only snapshot for `/fleet/devices`. */
104
+ snapshot() {
105
+ const now = this.clock.now();
106
+ const out = [];
107
+ for (const slot of this.slots.values()) {
108
+ const r = slot.record;
109
+ const mcpPid = this.processManager.pid(r.serial, "mcp");
110
+ const daemonPid = this.processManager.pid(r.serial, "daemon");
111
+ const mcpUrl = r.mcpPort > 0 ? `http://127.0.0.1:${r.mcpPort}` : null;
112
+ const scrcpy = {
113
+ enabled: scrcpyEnabled(r.binding),
114
+ running: slot.scrcpyAlive,
115
+ pid: this.processManager.pid(r.serial, "scrcpy"),
116
+ lastError: slot.scrcpyLastError,
117
+ };
118
+ out.push({
119
+ serial: r.serial,
120
+ name: r.name,
121
+ instanceId: r.binding?.instanceId ?? null,
122
+ state: r.state,
123
+ mcpUrl,
124
+ mcpPid,
125
+ daemonPid,
126
+ scrcpy,
127
+ enteredAt: r.enteredAt,
128
+ sinceMs: Math.max(0, now - r.enteredAt),
129
+ restartCount: r.restartCount,
130
+ });
131
+ }
132
+ return out.sort((a, b) => a.serial.localeCompare(b.serial));
133
+ }
134
+ /**
135
+ * Force the registry to re-read `devices.json` (e.g. after `beeos device
136
+ * attach` finished). Returns once the diff has been queued; the per-slot
137
+ * effects fire asynchronously.
138
+ */
139
+ async reload() {
140
+ await this.registry.reload();
141
+ }
142
+ /**
143
+ * User-initiated full restart of one device's mcp + daemon pair.
144
+ *
145
+ * Flow: kill both children → reset slot to `adb_offline` (cancels timers,
146
+ * releases port, clears restartCount) → if ADB is currently online and
147
+ * the device is still bound, synthesise an `adb_online` event so the FSM
148
+ * walks the normal spawn path. The result mirrors what would happen if
149
+ * the user yanked the cable and plugged it back in immediately, except
150
+ * that grace/keep windows are skipped.
151
+ *
152
+ * Returns `false` if `serial` is unknown, `true` otherwise.
153
+ */
154
+ async restartDevice(serial) {
155
+ const slot = this.slots.get(serial);
156
+ if (!slot)
157
+ return false;
158
+ // Tear down children (expected=true so the FSM won't penalise).
159
+ await this.processManager.killMcp(serial, { expected: true });
160
+ await this.processManager.killDaemon(serial, { expected: true });
161
+ await this.processManager.killScrcpy(serial, { expected: true });
162
+ // Cancel any timers.
163
+ slot.graceTimer?.();
164
+ slot.keepTimer?.();
165
+ slot.backoffTimer?.();
166
+ slot.graceTimer = undefined;
167
+ slot.keepTimer = undefined;
168
+ slot.backoffTimer = undefined;
169
+ // Reset record to adb_offline + restartCount=0.
170
+ slot.record = {
171
+ ...slot.record,
172
+ state: "adb_offline",
173
+ restartCount: 0,
174
+ mcpPort: 0,
175
+ enteredAt: this.clock.now(),
176
+ };
177
+ slot.mcpAlive = false;
178
+ slot.daemonAlive = false;
179
+ slot.scrcpyAlive = false;
180
+ slot.scrcpyLastError = null;
181
+ slot.scrcpyRequested = false;
182
+ await this.allocator.release(serial);
183
+ // Re-enter the spawn path if ADB is still online.
184
+ const onlineSerials = this.source.snapshot();
185
+ if (onlineSerials.includes(serial)) {
186
+ this.enqueue({ kind: "adb_online", serial });
187
+ }
188
+ return true;
189
+ }
190
+ // ── Event ingestion ──────────────────────────────────────────────────────
191
+ enqueue(ev) {
192
+ this.queue.push(ev);
193
+ if (!this.dispatching) {
194
+ void this.drain();
195
+ }
196
+ }
197
+ async drain() {
198
+ if (this.dispatching)
199
+ return;
200
+ this.dispatching = true;
201
+ try {
202
+ while (this.queue.length > 0) {
203
+ const ev = this.queue.shift();
204
+ await this.dispatch(ev);
205
+ }
206
+ }
207
+ finally {
208
+ this.dispatching = false;
209
+ }
210
+ }
211
+ async dispatch(event) {
212
+ const serial = event.serial;
213
+ const binding = this.bindingFor(serial, event);
214
+ const slot = this.ensureSlot(serial, binding);
215
+ // Refresh binding before stepping (FSM consults it).
216
+ if (binding !== undefined) {
217
+ slot.record = { ...slot.record, binding };
218
+ // Keep the friendly name in sync with the registry's `name`.
219
+ if (binding && binding.name) {
220
+ slot.record = { ...slot.record, name: binding.name };
221
+ }
222
+ else if (!binding) {
223
+ // binding removed → keep last known name
224
+ }
225
+ }
226
+ // Track child-alive flags BEFORE stepping so `markHealthy` can fire.
227
+ if (event.kind === "mcp_started") {
228
+ slot.mcpAlive = true;
229
+ slot.record = { ...slot.record, mcpPort: event.port };
230
+ }
231
+ if (event.kind === "daemon_started")
232
+ slot.daemonAlive = true;
233
+ if (event.kind === "mcp_exited")
234
+ slot.mcpAlive = false;
235
+ if (event.kind === "daemon_exited")
236
+ slot.daemonAlive = false;
237
+ // scrcpy is OPTIONAL — track liveness for the snapshot only; never gate
238
+ // `healthy`. Errors are surfaced through `lastError` so operators can see
239
+ // why video is degraded without scraping logs.
240
+ if (event.kind === "scrcpy_started") {
241
+ slot.scrcpyAlive = true;
242
+ slot.scrcpyLastError = null;
243
+ }
244
+ if (event.kind === "scrcpy_exited") {
245
+ slot.scrcpyAlive = false;
246
+ slot.scrcpyLastError = event.reason ?? null;
247
+ }
248
+ const ctx = { now: this.clock.now() };
249
+ const result = step(slot.record, event, ctx);
250
+ slot.record = result.record;
251
+ for (const effect of result.effects) {
252
+ await this.applyEffect(slot, effect);
253
+ }
254
+ // Promote `spawning → healthy` when both children are observed alive.
255
+ if (slot.record.state === "spawning" &&
256
+ slot.mcpAlive &&
257
+ slot.daemonAlive) {
258
+ const promote = markHealthy(slot.record, { now: this.clock.now() });
259
+ slot.record = promote.record;
260
+ for (const effect of promote.effects) {
261
+ await this.applyEffect(slot, effect);
262
+ }
263
+ }
264
+ // Reset alive flags when entering a state that no longer expects either
265
+ // child (so a future spawn cycle starts from a clean slate).
266
+ if (!stateExpectsMcp(slot.record.state))
267
+ slot.mcpAlive = false;
268
+ if (!stateExpectsDaemon(slot.record.state))
269
+ slot.daemonAlive = false;
270
+ }
271
+ bindingFor(serial, event) {
272
+ if (event.kind === "binding_added" ||
273
+ event.kind === "binding_changed") {
274
+ return this.registry.get(serial);
275
+ }
276
+ if (event.kind === "binding_removed") {
277
+ return null;
278
+ }
279
+ return undefined; // no change; keep existing
280
+ }
281
+ ensureSlot(serial, binding) {
282
+ let slot = this.slots.get(serial);
283
+ if (!slot) {
284
+ const resolvedBinding = binding === undefined ? this.registry.get(serial) : binding;
285
+ slot = {
286
+ record: newDeviceRecord({
287
+ serial,
288
+ binding: resolvedBinding ?? null,
289
+ now: this.clock.now(),
290
+ }),
291
+ mcpAlive: false,
292
+ daemonAlive: false,
293
+ scrcpyAlive: false,
294
+ scrcpyLastError: null,
295
+ scrcpyRequested: false,
296
+ };
297
+ this.slots.set(serial, slot);
298
+ }
299
+ return slot;
300
+ }
301
+ // ── Effect application ──────────────────────────────────────────────────
302
+ async applyEffect(slot, effect) {
303
+ switch (effect.kind) {
304
+ case "allocate_port": {
305
+ const port = await this.allocator.acquire(slot.record.serial);
306
+ slot.record = { ...slot.record, mcpPort: port };
307
+ return;
308
+ }
309
+ case "release_port": {
310
+ await this.allocator.release(slot.record.serial);
311
+ slot.record = { ...slot.record, mcpPort: 0 };
312
+ return;
313
+ }
314
+ case "spawn_mcp": {
315
+ const port = slot.record.mcpPort > 0
316
+ ? slot.record.mcpPort
317
+ : await this.allocator.acquire(slot.record.serial);
318
+ slot.record = { ...slot.record, mcpPort: port };
319
+ const opts = this.spawnOptionsFor(slot, port);
320
+ // Fire-and-forget: the spawnMcp side will emit `mcp_started` /
321
+ // `mcp_exited` events that re-enter `dispatch`.
322
+ void this.processManager.spawnMcp(opts).catch((e) => {
323
+ this.logger.error("spawn_mcp failed", {
324
+ serial: slot.record.serial,
325
+ error: String(e),
326
+ });
327
+ });
328
+ return;
329
+ }
330
+ case "spawn_daemon": {
331
+ const port = slot.record.mcpPort > 0
332
+ ? slot.record.mcpPort
333
+ : await this.allocator.acquire(slot.record.serial);
334
+ slot.record = { ...slot.record, mcpPort: port };
335
+ const opts = this.spawnOptionsFor(slot, port);
336
+ void this.processManager.spawnDaemon(opts).catch((e) => {
337
+ this.logger.error("spawn_daemon failed", {
338
+ serial: slot.record.serial,
339
+ error: String(e),
340
+ });
341
+ });
342
+ // Co-spawn scrcpy-bridge alongside the daemon when the binding asks
343
+ // for it. We piggyback on `spawn_daemon` (instead of introducing a
344
+ // new FSM effect) because scrcpy is OPTIONAL — its lifecycle is
345
+ // strictly bounded by the daemon's, and the pure FSM should remain
346
+ // unaware of it. The `scrcpyRequested` flag debounces a same-cycle
347
+ // re-spawn (e.g. degraded → healthy → degraded transitions).
348
+ const scrcpyOpts = this.scrcpySpawnOptionsFor(slot);
349
+ if (scrcpyOpts && !slot.scrcpyRequested) {
350
+ slot.scrcpyRequested = true;
351
+ slot.scrcpyLastError = null;
352
+ void this.processManager.spawnScrcpy(scrcpyOpts).catch((e) => {
353
+ this.logger.error("spawn_scrcpy failed", {
354
+ serial: slot.record.serial,
355
+ error: String(e),
356
+ });
357
+ });
358
+ }
359
+ return;
360
+ }
361
+ case "kill_mcp": {
362
+ slot.mcpAlive = false;
363
+ // Fire-and-forget: the actual SIGTERM→SIGKILL grace must not block
364
+ // the dispatcher (the FSM has already moved on; the trailing
365
+ // mcp_exited event will be a no-op in the new state).
366
+ void this.processManager.killMcp(slot.record.serial, {
367
+ expected: effect.expected,
368
+ }).catch((e) => {
369
+ this.logger.error("kill_mcp failed", {
370
+ serial: slot.record.serial,
371
+ error: String(e),
372
+ });
373
+ });
374
+ return;
375
+ }
376
+ case "kill_daemon": {
377
+ slot.daemonAlive = false;
378
+ void this.processManager.killDaemon(slot.record.serial, {
379
+ expected: effect.expected,
380
+ }).catch((e) => {
381
+ this.logger.error("kill_daemon failed", {
382
+ serial: slot.record.serial,
383
+ error: String(e),
384
+ });
385
+ });
386
+ // scrcpy is bounded by the daemon's lifecycle: once the FSM tears
387
+ // the daemon down (decay → degraded/gone, or binding removal), kill
388
+ // scrcpy too. `expected = effect.expected` mirrors the daemon kill.
389
+ slot.scrcpyAlive = false;
390
+ slot.scrcpyRequested = false;
391
+ void this.processManager.killScrcpy(slot.record.serial, {
392
+ expected: effect.expected,
393
+ }).catch((e) => {
394
+ this.logger.error("kill_scrcpy failed", {
395
+ serial: slot.record.serial,
396
+ error: String(e),
397
+ });
398
+ });
399
+ return;
400
+ }
401
+ case "start_grace_timer": {
402
+ slot.graceTimer?.();
403
+ const ms = slot.record.binding?.graceMs ?? this.graceMs;
404
+ slot.graceTimer = this.clock.schedule(ms, () => this.enqueue({ kind: "grace_expired", serial: slot.record.serial }));
405
+ return;
406
+ }
407
+ case "cancel_grace_timer": {
408
+ slot.graceTimer?.();
409
+ slot.graceTimer = undefined;
410
+ return;
411
+ }
412
+ case "start_keep_timer": {
413
+ slot.keepTimer?.();
414
+ const ms = slot.record.binding?.keepMs ?? this.keepMs;
415
+ slot.keepTimer = this.clock.schedule(ms, () => this.enqueue({ kind: "keep_expired", serial: slot.record.serial }));
416
+ return;
417
+ }
418
+ case "cancel_keep_timer": {
419
+ slot.keepTimer?.();
420
+ slot.keepTimer = undefined;
421
+ return;
422
+ }
423
+ case "start_backoff_timer": {
424
+ slot.backoffTimer?.();
425
+ const ms = backoffMs(effect.attempt);
426
+ slot.backoffTimer = this.clock.schedule(ms, () => this.enqueue({ kind: "backoff_elapsed", serial: slot.record.serial }));
427
+ return;
428
+ }
429
+ case "cancel_backoff_timer": {
430
+ slot.backoffTimer?.();
431
+ slot.backoffTimer = undefined;
432
+ return;
433
+ }
434
+ case "log": {
435
+ const fn = this.logger[effect.level] ?? this.logger.info;
436
+ fn.call(this.logger, effect.msg, {
437
+ serial: effect.serial,
438
+ ...(effect.data ?? {}),
439
+ });
440
+ return;
441
+ }
442
+ }
443
+ }
444
+ spawnOptionsFor(slot, mcpPort) {
445
+ const binding = slot.record.binding;
446
+ return {
447
+ serial: slot.record.serial,
448
+ mcpPort,
449
+ keyFile: binding?.keyFile ?? "",
450
+ agentGatewayUrl: this.defaultAgentGatewayUrl,
451
+ daemonHttpPort: binding?.httpPort,
452
+ name: slot.record.name,
453
+ instanceId: binding?.instanceId ?? undefined,
454
+ // `devices.json#backend` flows through here verbatim. When the
455
+ // binding lacks a backend (older entries from before §3.4 of the
456
+ // self-hosted plan), the process manager falls back to its
457
+ // constructor-time default (`adb`).
458
+ backend: binding?.backend,
459
+ };
460
+ }
461
+ /**
462
+ * Build `SpawnScrcpyOptions` for a slot, returning `null` when scrcpy is
463
+ * not requested (`videoMode !== "scrcpy"`) or the binding lacks the
464
+ * mandatory fields (`instanceId` / `keyFile` / Agent Gateway URL).
465
+ *
466
+ * We deliberately pass `bridgePrivateKeyFile === bridgePublicKeyFile`
467
+ * (both pointing at the same `.key.json` file written by `beeos device
468
+ * attach`). The Rust side accepts that layout (see scrcpy-bridge's
469
+ * `bootstrap/mod.rs`).
470
+ */
471
+ scrcpySpawnOptionsFor(slot) {
472
+ const binding = slot.record.binding;
473
+ if (!scrcpyEnabled(binding))
474
+ return null;
475
+ if (!binding)
476
+ return null;
477
+ if (!binding.instanceId)
478
+ return null;
479
+ if (!binding.keyFile)
480
+ return null;
481
+ const agw = this.defaultAgentGatewayUrl ?? process.env.AGENT_GATEWAY_URL;
482
+ if (!agw) {
483
+ this.logger.warn("scrcpy enabled but AGENT_GATEWAY_URL not configured — skipping", { serial: slot.record.serial });
484
+ return null;
485
+ }
486
+ return {
487
+ serial: slot.record.serial,
488
+ instanceId: binding.instanceId,
489
+ agentGatewayUrl: agw,
490
+ bridgePrivateKeyFile: binding.keyFile,
491
+ bridgePublicKeyFile: binding.keyFile,
492
+ };
493
+ }
494
+ }
495
+ function scrcpyEnabled(binding) {
496
+ return binding?.videoMode === "scrcpy";
497
+ }
498
+ // ── Helpers ────────────────────────────────────────────────────────────────
499
+ function readEnvMs(name, fallback) {
500
+ const raw = process.env[name];
501
+ if (!raw)
502
+ return fallback;
503
+ const n = Number(raw);
504
+ if (!Number.isFinite(n) || n < 0)
505
+ return fallback;
506
+ return Math.floor(n);
507
+ }
508
+ //# sourceMappingURL=supervisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"supervisor.js","sourceRoot":"","sources":["../../src/fleet/supervisor.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAQH,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAE1F,OAAO,EACL,SAAS,EACT,WAAW,EACX,IAAI,GAEL,MAAM,iBAAiB,CAAC;AAEzB,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAqB/C,MAAM,UAAU,GAAqB;IACnC,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;IACf,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,IAAI,EAAE,GAAG,EAAE,GAAE,CAAC;IACd,KAAK,EAAE,GAAG,EAAE,GAAE,CAAC;CAChB,CAAC;AA8CF,+EAA+E;AAE/E,MAAM,OAAO,eAAe;IACT,MAAM,CAAgB;IACtB,QAAQ,CAAiB;IACzB,SAAS,CAAiB;IAC1B,cAAc,CAAkB;IAChC,KAAK,CAAS;IACd,OAAO,CAAS;IAChB,MAAM,CAAS;IACf,MAAM,CAAmB;IACzB,sBAAsB,CAAU;IAEhC,KAAK,GAAG,IAAI,GAAG,EAAsB,CAAC;IACtC,KAAK,GAAiB,EAAE,CAAC;IAClC,WAAW,GAAG,KAAK,CAAC;IACpB,OAAO,GAAG,KAAK,CAAC;IAChB,QAAQ,GAAwB,IAAI,CAAC;IACrC,YAAY,GAAwB,IAAI,CAAC;IACzC,YAAY,GAAwB,IAAI,CAAC;IAEjD,YAAY,IAA4B;QACtC,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC;QAC1B,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QAC9B,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,CAAC;QAChC,IAAI,CAAC,cAAc,GAAG,IAAI,CAAC,cAAc,CAAC;QAC1C,IAAI,CAAC,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,IAAI,WAAW,EAAE,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,SAAS,CAAC,oBAAoB,EAAE,KAAK,CAAC,CAAC;QACtE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,SAAS,CAAC,sBAAsB,EAAE,OAAO,CAAC,CAAC;QACxE,IAAI,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,IAAI,UAAU,CAAC;QACxC,IAAI,CAAC,sBAAsB,GAAG,IAAI,CAAC,sBAAsB,CAAC;IAC5D,CAAC;IAED,KAAK,CAAC,KAAK;QACT,IAAI,IAAI,CAAC,OAAO;YAAE,OAAO;QACzB,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;QAEpB,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,CAAC;QAC7B,MAAM,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC;QAC5B,MAAM,IAAI,CAAC,cAAc,CAAC,KAAK,EAAE,CAAC;QAElC,wEAAwE;QACxE,+DAA+D;QAC/D,KAAK,MAAM,OAAO,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,EAAE,CAAC;YAC3C,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC3C,CAAC;QAED,qEAAqE;QACrE,wBAAwB;QACxB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QACzD,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC/D,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,cAAc,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAErE,MAAM,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IAC5B,CAAC;IAED,KAAK,CAAC,IAAI;QACR,IAAI,CAAC,IAAI,CAAC,OAAO;YAAE,OAAO;QAC1B,IAAI,CAAC,OAAO,GAAG,KAAK,CAAC;QAErB,IAAI,CAAC,QAAQ,EAAE,EAAE,CAAC;QAClB,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;QACrB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QACzB,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC;QAEzB,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;YACpB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;YACnB,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;YACtB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;YAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;YAC3B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAChC,CAAC;QAED,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAAC;QACzB,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QACjC,MAAM,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC;QAC3B,MAAM,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;IAC9B,CAAC;IAED,+CAA+C;IAC/C,QAAQ;QACN,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAqB,EAAE,CAAC;QACjC,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;YACvC,MAAM,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC;YACtB,MAAM,MAAM,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;YACxD,MAAM,SAAS,GAAG,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;YAC9D,MAAM,MAAM,GAAG,CAAC,CAAC,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,oBAAoB,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACtE,MAAM,MAAM,GAAiB;gBAC3B,OAAO,EAAE,aAAa,CAAC,CAAC,CAAC,OAAO,CAAC;gBACjC,OAAO,EAAE,IAAI,CAAC,WAAW;gBACzB,GAAG,EAAE,IAAI,CAAC,cAAc,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,EAAE,QAAQ,CAAC;gBAChD,SAAS,EAAE,IAAI,CAAC,eAAe;aAChC,CAAC;YACF,GAAG,CAAC,IAAI,CAAC;gBACP,MAAM,EAAE,CAAC,CAAC,MAAM;gBAChB,IAAI,EAAE,CAAC,CAAC,IAAI;gBACZ,UAAU,EAAE,CAAC,CAAC,OAAO,EAAE,UAAU,IAAI,IAAI;gBACzC,KAAK,EAAE,CAAC,CAAC,KAAK;gBACd,MAAM;gBACN,MAAM;gBACN,SAAS;gBACT,MAAM;gBACN,SAAS,EAAE,CAAC,CAAC,SAAS;gBACtB,OAAO,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,SAAS,CAAC;gBACvC,YAAY,EAAE,CAAC,CAAC,YAAY;aAC7B,CAAC,CAAC;QACL,CAAC;QACD,OAAO,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC;IAC9D,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,MAAM;QACV,MAAM,IAAI,CAAC,QAAQ,CAAC,MAAM,EAAE,CAAC;IAC/B,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,aAAa,CAAC,MAAc;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACpC,IAAI,CAAC,IAAI;YAAE,OAAO,KAAK,CAAC;QAExB,gEAAgE;QAChE,MAAM,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QACjE,MAAM,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,MAAM,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC;QAEjE,qBAAqB;QACrB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;QACpB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;QACnB,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;QACtB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;QAC5B,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;QAE9B,gDAAgD;QAChD,IAAI,CAAC,MAAM,GAAG;YACZ,GAAG,IAAI,CAAC,MAAM;YACd,KAAK,EAAE,aAAa;YACpB,YAAY,EAAE,CAAC;YACf,OAAO,EAAE,CAAC;YACV,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;SAC5B,CAAC;QACF,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QACzB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC5B,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;QAC7B,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC;QAErC,kDAAkD;QAClD,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,QAAQ,EAAE,CAAC;QAC7C,IAAI,aAAa,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACnC,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,MAAM,EAAE,CAAC,CAAC;QAC/C,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,4EAA4E;IAEpE,OAAO,CAAC,EAAc;QAC5B,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACpB,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,CAAC;YACtB,KAAK,IAAI,CAAC,KAAK,EAAE,CAAC;QACpB,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK;QACjB,IAAI,IAAI,CAAC,WAAW;YAAE,OAAO;QAC7B,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QACxB,IAAI,CAAC;YACH,OAAO,IAAI,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;gBAC7B,MAAM,EAAE,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,EAAG,CAAC;gBAC/B,MAAM,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YAC1B,CAAC;QACH,CAAC;gBAAS,CAAC;YACT,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAC3B,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,QAAQ,CAAC,KAAiB;QACtC,MAAM,MAAM,GAAG,KAAK,CAAC,MAAM,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC;QAC/C,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAE9C,qDAAqD;QACrD,IAAI,OAAO,KAAK,SAAS,EAAE,CAAC;YAC1B,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;YAC1C,6DAA6D;YAC7D,IAAI,OAAO,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;gBAC5B,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC;YACvD,CAAC;iBAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACpB,yCAAyC;YAC3C,CAAC;QACH,CAAC;QAED,qEAAqE;QACrE,IAAI,KAAK,CAAC,IAAI,KAAK,aAAa,EAAE,CAAC;YACjC,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;YACrB,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,IAAI,EAAE,CAAC;QACxD,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;YAAE,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;QAC7D,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY;YAAE,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QACvD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe;YAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;QAC7D,wEAAwE;QACxE,0EAA0E;QAC1E,+CAA+C;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB,EAAE,CAAC;YACpC,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC;YACxB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;QAC9B,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,eAAe,EAAE,CAAC;YACnC,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;YACzB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC,MAAM,IAAI,IAAI,CAAC;QAC9C,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC;QACtC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,CAAC,CAAC;QAC7C,IAAI,CAAC,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE5B,KAAK,MAAM,MAAM,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACpC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACvC,CAAC;QAED,sEAAsE;QACtE,IACE,IAAI,CAAC,MAAM,CAAC,KAAK,KAAK,UAAU;YAChC,IAAI,CAAC,QAAQ;YACb,IAAI,CAAC,WAAW,EAChB,CAAC;YACD,MAAM,OAAO,GAAG,WAAW,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;YACpE,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;YAC7B,KAAK,MAAM,MAAM,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;gBACrC,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;YACvC,CAAC;QACH,CAAC;QAED,wEAAwE;QACxE,6DAA6D;QAC7D,IAAI,CAAC,eAAe,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;QAC/D,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;YAAE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;IACvE,CAAC;IAEO,UAAU,CAAC,MAAc,EAAE,KAAiB;QAClD,IACE,KAAK,CAAC,IAAI,KAAK,eAAe;YAC9B,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAChC,CAAC;YACD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QACnC,CAAC;QACD,IAAI,KAAK,CAAC,IAAI,KAAK,iBAAiB,EAAE,CAAC;YACrC,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO,SAAS,CAAC,CAAC,2BAA2B;IAC/C,CAAC;IAEO,UAAU,CAAC,MAAc,EAAE,OAAyC;QAC1E,IAAI,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,EAAE,CAAC;YACV,MAAM,eAAe,GACnB,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC;YAC9D,IAAI,GAAG;gBACL,MAAM,EAAE,eAAe,CAAC;oBACtB,MAAM;oBACN,OAAO,EAAE,eAAe,IAAI,IAAI;oBAChC,GAAG,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,EAAE;iBACtB,CAAC;gBACF,QAAQ,EAAE,KAAK;gBACf,WAAW,EAAE,KAAK;gBAClB,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,IAAI;gBACrB,eAAe,EAAE,KAAK;aACvB,CAAC;YACF,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;QAC/B,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,2EAA2E;IAEnE,KAAK,CAAC,WAAW,CAAC,IAAgB,EAAE,MAAmB;QAC7D,QAAQ,MAAM,CAAC,IAAI,EAAE,CAAC;YACpB,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBAC9D,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAChD,OAAO;YACT,CAAC;YACD,KAAK,cAAc,CAAC,CAAC,CAAC;gBACpB,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACjD,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;gBAC7C,OAAO;YACT,CAAC;YACD,KAAK,WAAW,CAAC,CAAC,CAAC;gBACjB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC;oBAClC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;oBACrB,CAAC,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACrD,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAChD,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC9C,+DAA+D;gBAC/D,gDAAgD;gBAChD,KAAK,IAAI,CAAC,cAAc,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBAClD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,kBAAkB,EAAE;wBACpC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;wBAC1B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;qBACjB,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,KAAK,cAAc,CAAC,CAAC,CAAC;gBACpB,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,GAAG,CAAC;oBAClC,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO;oBACrB,CAAC,CAAC,MAAM,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;gBACrD,IAAI,CAAC,MAAM,GAAG,EAAE,GAAG,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC;gBAChD,MAAM,IAAI,GAAG,IAAI,CAAC,eAAe,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;gBAC9C,KAAK,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBACrD,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE;wBACvC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;wBAC1B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;qBACjB,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,oEAAoE;gBACpE,mEAAmE;gBACnE,gEAAgE;gBAChE,mEAAmE;gBACnE,mEAAmE;gBACnE,6DAA6D;gBAC7D,MAAM,UAAU,GAAG,IAAI,CAAC,qBAAqB,CAAC,IAAI,CAAC,CAAC;gBACpD,IAAI,UAAU,IAAI,CAAC,IAAI,CAAC,eAAe,EAAE,CAAC;oBACxC,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC5B,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC;oBAC5B,KAAK,IAAI,CAAC,cAAc,CAAC,WAAW,CAAC,UAAU,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;wBAC3D,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,qBAAqB,EAAE;4BACvC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;4BAC1B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;yBACjB,CAAC,CAAC;oBACL,CAAC,CAAC,CAAC;gBACL,CAAC;gBACD,OAAO;YACT,CAAC;YACD,KAAK,UAAU,CAAC,CAAC,CAAC;gBAChB,IAAI,CAAC,QAAQ,GAAG,KAAK,CAAC;gBACtB,mEAAmE;gBACnE,6DAA6D;gBAC7D,sDAAsD;gBACtD,KAAK,IAAI,CAAC,cAAc,CAAC,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBACnD,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE;wBACnC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;wBAC1B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;qBACjB,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,KAAK,aAAa,CAAC,CAAC,CAAC;gBACnB,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,KAAK,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBACtD,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE;wBACtC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;wBAC1B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;qBACjB,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,kEAAkE;gBAClE,oEAAoE;gBACpE,oEAAoE;gBACpE,IAAI,CAAC,WAAW,GAAG,KAAK,CAAC;gBACzB,IAAI,CAAC,eAAe,GAAG,KAAK,CAAC;gBAC7B,KAAK,IAAI,CAAC,cAAc,CAAC,UAAU,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE;oBACtD,QAAQ,EAAE,MAAM,CAAC,QAAQ;iBAC1B,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE;oBACb,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,oBAAoB,EAAE;wBACtC,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;wBAC1B,KAAK,EAAE,MAAM,CAAC,CAAC,CAAC;qBACjB,CAAC,CAAC;gBACL,CAAC,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;YACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;gBACpB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC,OAAO,CAAC;gBACxD,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAC7C,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,eAAe,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CACpE,CAAC;gBACF,OAAO;YACT,CAAC;YACD,KAAK,oBAAoB,CAAC,CAAC,CAAC;gBAC1B,IAAI,CAAC,UAAU,EAAE,EAAE,CAAC;gBACpB,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;gBAC5B,OAAO;YACT,CAAC;YACD,KAAK,kBAAkB,CAAC,CAAC,CAAC;gBACxB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBACnB,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,IAAI,IAAI,CAAC,MAAM,CAAC;gBACtD,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAC5C,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CACnE,CAAC;gBACF,OAAO;YACT,CAAC;YACD,KAAK,mBAAmB,CAAC,CAAC,CAAC;gBACzB,IAAI,CAAC,SAAS,EAAE,EAAE,CAAC;gBACnB,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;gBAC3B,OAAO;YACT,CAAC;YACD,KAAK,qBAAqB,CAAC,CAAC,CAAC;gBAC3B,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;gBACtB,MAAM,EAAE,GAAG,SAAS,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;gBACrC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,EAAE,EAAE,GAAG,EAAE,CAC/C,IAAI,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,iBAAiB,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,CACtE,CAAC;gBACF,OAAO;YACT,CAAC;YACD,KAAK,sBAAsB,CAAC,CAAC,CAAC;gBAC5B,IAAI,CAAC,YAAY,EAAE,EAAE,CAAC;gBACtB,IAAI,CAAC,YAAY,GAAG,SAAS,CAAC;gBAC9B,OAAO;YACT,CAAC;YACD,KAAK,KAAK,CAAC,CAAC,CAAC;gBACX,MAAM,EAAE,GAAG,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC;gBACzD,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,EAAE;oBAC/B,MAAM,EAAE,MAAM,CAAC,MAAM;oBACrB,GAAG,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;iBACvB,CAAC,CAAC;gBACH,OAAO;YACT,CAAC;QACH,CAAC;IACH,CAAC;IAEO,eAAe,CAAC,IAAgB,EAAE,OAAe;QACvD,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QACpC,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,OAAO;YACP,OAAO,EAAE,OAAO,EAAE,OAAO,IAAI,EAAE;YAC/B,eAAe,EAAE,IAAI,CAAC,sBAAsB;YAC5C,cAAc,EAAE,OAAO,EAAE,QAAQ;YACjC,IAAI,EAAE,IAAI,CAAC,MAAM,CAAC,IAAI;YACtB,UAAU,EAAE,OAAO,EAAE,UAAU,IAAI,SAAS;YAC5C,+DAA+D;YAC/D,iEAAiE;YACjE,2DAA2D;YAC3D,oCAAoC;YACpC,OAAO,EAAE,OAAO,EAAE,OAAO;SAC1B,CAAC;IACJ,CAAC;IAED;;;;;;;;;OASG;IACK,qBAAqB,CAAC,IAAgB;QAC5C,MAAM,OAAO,GAAG,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC;QACpC,IAAI,CAAC,aAAa,CAAC,OAAO,CAAC;YAAE,OAAO,IAAI,CAAC;QACzC,IAAI,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAC1B,IAAI,CAAC,OAAO,CAAC,UAAU;YAAE,OAAO,IAAI,CAAC;QACrC,IAAI,CAAC,OAAO,CAAC,OAAO;YAAE,OAAO,IAAI,CAAC;QAClC,MAAM,GAAG,GAAG,IAAI,CAAC,sBAAsB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC;QACzE,IAAI,CAAC,GAAG,EAAE,CAAC;YACT,IAAI,CAAC,MAAM,CAAC,IAAI,CACd,gEAAgE,EAChE,EAAE,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM,EAAE,CAC/B,CAAC;YACF,OAAO,IAAI,CAAC;QACd,CAAC;QACD,OAAO;YACL,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,MAAM;YAC1B,UAAU,EAAE,OAAO,CAAC,UAAU;YAC9B,eAAe,EAAE,GAAG;YACpB,oBAAoB,EAAE,OAAO,CAAC,OAAO;YACrC,mBAAmB,EAAE,OAAO,CAAC,OAAO;SACrC,CAAC;IACJ,CAAC;CACF;AAED,SAAS,aAAa,CAAC,OAA6B;IAClD,OAAO,OAAO,EAAE,SAAS,KAAK,QAAQ,CAAC;AACzC,CAAC;AAED,8EAA8E;AAE9E,SAAS,SAAS,CAAC,IAAY,EAAE,QAAgB;IAC/C,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC9B,IAAI,CAAC,GAAG;QAAE,OAAO,QAAQ,CAAC;IAC1B,MAAM,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;IACtB,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;QAAE,OAAO,QAAQ,CAAC;IAClD,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;AACvB,CAAC"}
@@ -0,0 +1,46 @@
1
+ import { type ImageTransport } from "../model/image/transport.js";
2
+ export interface GrounderConfig {
3
+ baseUrl?: string;
4
+ apiKey?: string;
5
+ model?: string;
6
+ /**
7
+ * Strategy for delivering the screenshot to the grounding model.
8
+ * Defaults to `DataUrlTransport` (inline base64). Pass a
9
+ * `FallbackTransport(http -> data)` here to enjoy the body-size win
10
+ * while keeping a hard correctness floor.
11
+ */
12
+ imageTransport?: ImageTransport;
13
+ }
14
+ /**
15
+ * Visual grounder port. Given a screenshot and a description, return the
16
+ * raw model response (typically `[x, y]`). Returning `null` signals
17
+ * "model declined / network error" to the caller.
18
+ *
19
+ * Extracted as an interface so `pi-context` and tests can swap in fake
20
+ * implementations without depending on the OpenAI SDK.
21
+ */
22
+ export interface IGrounder {
23
+ ground(screenshotB64: string, query: string): Promise<string | null>;
24
+ }
25
+ /**
26
+ * HTTP-based visual grounder: sends a screenshot + text query to a VLM endpoint
27
+ * and returns the raw model response as a string.
28
+ *
29
+ * Configuration precedence (high → low):
30
+ * 1. Explicit `GrounderConfig` passed to the constructor (preferred —
31
+ * `loadConfig()` resolves `config.grounder` from CLI flags + JSON).
32
+ * 2. `process.env.GROUNDER_*` (back-compat, harness scripts).
33
+ * 3. `process.env.GUI_AGENT_*` (legacy, deprecated alias).
34
+ * 4. Hard defaults (`gpt-4o`, OpenAI default base URL).
35
+ *
36
+ * The screenshot input is compressed and routed through an
37
+ * `ImageTransport` so grounding traffic stays under ARouter's body-size
38
+ * cap on the same code path as the main VLM loop.
39
+ */
40
+ export declare class HTTPGrounder implements IGrounder {
41
+ private readonly client;
42
+ private readonly model;
43
+ private readonly imageTransport;
44
+ constructor(config?: GrounderConfig);
45
+ ground(screenshotB64: string, query: string): Promise<string | null>;
46
+ }
@@ -0,0 +1,82 @@
1
+ import OpenAI from "openai";
2
+ import { compressForVlm } from "../model/image/compress.js";
3
+ import { DataUrlTransport } from "../model/image/transport.js";
4
+ import { getLogger } from "../logger/index.js";
5
+ const SYSTEM_PROMPT = `\
6
+ You are a visual grounding model. Given a screenshot and a natural-language description of a UI element, output the pixel coordinate of that element.
7
+
8
+ Output format (one line only):
9
+ [x, y]
10
+
11
+ Where x and y are pixel coordinates in the original image. Output nothing else.`;
12
+ /**
13
+ * HTTP-based visual grounder: sends a screenshot + text query to a VLM endpoint
14
+ * and returns the raw model response as a string.
15
+ *
16
+ * Configuration precedence (high → low):
17
+ * 1. Explicit `GrounderConfig` passed to the constructor (preferred —
18
+ * `loadConfig()` resolves `config.grounder` from CLI flags + JSON).
19
+ * 2. `process.env.GROUNDER_*` (back-compat, harness scripts).
20
+ * 3. `process.env.GUI_AGENT_*` (legacy, deprecated alias).
21
+ * 4. Hard defaults (`gpt-4o`, OpenAI default base URL).
22
+ *
23
+ * The screenshot input is compressed and routed through an
24
+ * `ImageTransport` so grounding traffic stays under ARouter's body-size
25
+ * cap on the same code path as the main VLM loop.
26
+ */
27
+ export class HTTPGrounder {
28
+ client;
29
+ model;
30
+ imageTransport;
31
+ constructor(config = {}) {
32
+ this.client = new OpenAI({
33
+ baseURL: config.baseUrl ?? process.env.GROUNDER_BASE_URL ?? process.env.GUI_AGENT_BASE_URL,
34
+ apiKey: config.apiKey ?? process.env.GROUNDER_API_KEY ?? process.env.GUI_AGENT_API_KEY ?? "nokey",
35
+ });
36
+ this.model = config.model ?? process.env.GROUNDER_MODEL ?? process.env.GUI_AGENT_MODEL ?? "gpt-4o";
37
+ this.imageTransport = config.imageTransport ?? new DataUrlTransport();
38
+ }
39
+ async ground(screenshotB64, query) {
40
+ // Same observability contract as agent-runtime/adapters/openai.ts —
41
+ // a single `vlm.image.prepared` line per call so dashboards can
42
+ // attribute traffic to either the predict-loop or the grounder
43
+ // (stage label) without forking the metric schema.
44
+ const t0 = Date.now();
45
+ const raw = Buffer.from(screenshotB64, "base64");
46
+ const compressed = await compressForVlm(raw);
47
+ const t1 = Date.now();
48
+ const imageRef = await this.imageTransport.send(compressed.bytes, compressed.mime);
49
+ const t2 = Date.now();
50
+ getLogger().info({
51
+ component: "vlm-image",
52
+ stage: "grounder",
53
+ inputBytes: raw.length,
54
+ outputBytes: compressed.bytes.length,
55
+ width: compressed.width,
56
+ height: compressed.height,
57
+ mime: compressed.mime,
58
+ compressMs: t1 - t0,
59
+ transport: this.imageTransport.name,
60
+ transportMs: t2 - t1,
61
+ refKind: imageRef.kind,
62
+ }, "vlm.image.prepared");
63
+ const messages = [
64
+ { role: "system", content: SYSTEM_PROMPT },
65
+ {
66
+ role: "user",
67
+ content: [
68
+ { type: "image_url", image_url: { url: imageRef.url } },
69
+ { type: "text", text: `Find the element: ${query}` },
70
+ ],
71
+ },
72
+ ];
73
+ try {
74
+ const resp = await this.client.chat.completions.create({ model: this.model, messages, max_tokens: 64 });
75
+ return resp.choices[0]?.message?.content ?? null;
76
+ }
77
+ catch {
78
+ return null;
79
+ }
80
+ }
81
+ }
82
+ //# sourceMappingURL=grounder.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grounder.js","sourceRoot":"","sources":["../../src/grounding/grounder.ts"],"names":[],"mappings":"AAAA,OAAO,MAAM,MAAM,QAAQ,CAAC;AAE5B,OAAO,EAAE,cAAc,EAAE,MAAM,4BAA4B,CAAC;AAC5D,OAAO,EAAE,gBAAgB,EAAuB,MAAM,6BAA6B,CAAC;AACpF,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AA2B/C,MAAM,aAAa,GAAG;;;;;;gFAM0D,CAAC;AAEjF;;;;;;;;;;;;;;GAcG;AACH,MAAM,OAAO,YAAY;IACN,MAAM,CAAS;IACf,KAAK,CAAS;IACd,cAAc,CAAiB;IAEhD,YAAY,SAAyB,EAAE;QACrC,IAAI,CAAC,MAAM,GAAG,IAAI,MAAM,CAAC;YACvB,OAAO,EAAE,MAAM,CAAC,OAAO,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO,CAAC,GAAG,CAAC,kBAAkB;YAC1F,MAAM,EAAE,MAAM,CAAC,MAAM,IAAI,OAAO,CAAC,GAAG,CAAC,gBAAgB,IAAI,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,OAAO;SAClG,CAAC,CAAC;QACH,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,QAAQ,CAAC;QACnG,IAAI,CAAC,cAAc,GAAG,MAAM,CAAC,cAAc,IAAI,IAAI,gBAAgB,EAAE,CAAC;IACxE,CAAC;IAED,KAAK,CAAC,MAAM,CAAC,aAAqB,EAAE,KAAa;QAC/C,oEAAoE;QACpE,gEAAgE;QAChE,+DAA+D;QAC/D,mDAAmD;QACnD,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC;QACjD,MAAM,UAAU,GAAG,MAAM,cAAc,CAAC,GAAG,CAAC,CAAC;QAC7C,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,UAAU,CAAC,IAAI,CAAC,CAAC;QACnF,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;QACtB,SAAS,EAAE,CAAC,IAAI,CACd;YACE,SAAS,EAAE,WAAW;YACtB,KAAK,EAAE,UAAU;YACjB,UAAU,EAAE,GAAG,CAAC,MAAM;YACtB,WAAW,EAAE,UAAU,CAAC,KAAK,CAAC,MAAM;YACpC,KAAK,EAAE,UAAU,CAAC,KAAK;YACvB,MAAM,EAAE,UAAU,CAAC,MAAM;YACzB,IAAI,EAAE,UAAU,CAAC,IAAI;YACrB,UAAU,EAAE,EAAE,GAAG,EAAE;YACnB,SAAS,EAAE,IAAI,CAAC,cAAc,CAAC,IAAI;YACnC,WAAW,EAAE,EAAE,GAAG,EAAE;YACpB,OAAO,EAAE,QAAQ,CAAC,IAAI;SACvB,EACD,oBAAoB,CACrB,CAAC;QAEF,MAAM,QAAQ,GAAwC;YACpD,EAAE,IAAI,EAAE,QAAQ,EAAE,OAAO,EAAE,aAAa,EAAE;YAC1C;gBACE,IAAI,EAAE,MAAM;gBACZ,OAAO,EAAE;oBACP,EAAE,IAAI,EAAE,WAAW,EAAE,SAAS,EAAE,EAAE,GAAG,EAAE,QAAQ,CAAC,GAAG,EAAE,EAAE;oBACvD,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,qBAAqB,KAAK,EAAE,EAAE;iBACrD;aACF;SACF,CAAC;QAEF,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,MAAM,CAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,QAAQ,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC,CAAC;YACxG,OAAO,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,IAAI,IAAI,CAAC;QACnD,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,IAAI,CAAC;QACd,CAAC;IACH,CAAC;CACF"}