@midscene/core 1.8.10 → 1.9.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 (304) hide show
  1. package/dist/es/agent/agent.mjs +40 -50
  2. package/dist/es/agent/agent.mjs.map +1 -1
  3. package/dist/es/agent/task-builder.mjs +39 -19
  4. package/dist/es/agent/task-builder.mjs.map +1 -1
  5. package/dist/es/agent/tasks.mjs +24 -22
  6. package/dist/es/agent/tasks.mjs.map +1 -1
  7. package/dist/es/agent/utils.mjs +11 -14
  8. package/dist/es/agent/utils.mjs.map +1 -1
  9. package/dist/es/ai-model/connectivity.mjs +7 -3
  10. package/dist/es/ai-model/connectivity.mjs.map +1 -1
  11. package/dist/es/ai-model/errors.mjs +9 -0
  12. package/dist/es/ai-model/errors.mjs.map +1 -0
  13. package/dist/es/ai-model/index.mjs +3 -4
  14. package/dist/es/ai-model/inspect.mjs +132 -144
  15. package/dist/es/ai-model/inspect.mjs.map +1 -1
  16. package/dist/es/ai-model/llm-planning.mjs +46 -28
  17. package/dist/es/ai-model/llm-planning.mjs.map +1 -1
  18. package/dist/es/ai-model/{auto-glm → models/auto-glm}/actions.mjs +22 -44
  19. package/dist/es/ai-model/models/auto-glm/actions.mjs.map +1 -0
  20. package/dist/es/ai-model/models/auto-glm/adapter.mjs +45 -0
  21. package/dist/es/ai-model/models/auto-glm/adapter.mjs.map +1 -0
  22. package/dist/es/ai-model/models/auto-glm/locate.mjs +112 -0
  23. package/dist/es/ai-model/models/auto-glm/locate.mjs.map +1 -0
  24. package/dist/es/ai-model/models/auto-glm/parser.mjs.map +1 -0
  25. package/dist/es/ai-model/{auto-glm → models/auto-glm}/planning.mjs +6 -7
  26. package/dist/es/ai-model/models/auto-glm/planning.mjs.map +1 -0
  27. package/dist/es/ai-model/{auto-glm → models/auto-glm}/prompt.mjs +3 -11
  28. package/dist/es/ai-model/models/auto-glm/prompt.mjs.map +1 -0
  29. package/dist/es/ai-model/models/default.mjs +12 -0
  30. package/dist/es/ai-model/models/default.mjs.map +1 -0
  31. package/dist/es/ai-model/models/doubao.mjs +138 -0
  32. package/dist/es/ai-model/models/doubao.mjs.map +1 -0
  33. package/dist/es/ai-model/models/gemini.mjs +34 -0
  34. package/dist/es/ai-model/models/gemini.mjs.map +1 -0
  35. package/dist/es/ai-model/models/glm.mjs +37 -0
  36. package/dist/es/ai-model/models/glm.mjs.map +1 -0
  37. package/dist/es/ai-model/models/gpt.mjs +31 -0
  38. package/dist/es/ai-model/models/gpt.mjs.map +1 -0
  39. package/dist/es/ai-model/models/index.mjs +2 -0
  40. package/dist/es/ai-model/models/qwen.mjs +113 -0
  41. package/dist/es/ai-model/models/qwen.mjs.map +1 -0
  42. package/dist/es/ai-model/models/registry.mjs +45 -0
  43. package/dist/es/ai-model/models/registry.mjs.map +1 -0
  44. package/dist/es/ai-model/models/resolved.mjs +104 -0
  45. package/dist/es/ai-model/models/resolved.mjs.map +1 -0
  46. package/dist/es/ai-model/models/types.mjs +0 -0
  47. package/dist/es/ai-model/models/ui-tars/adapter.mjs +142 -0
  48. package/dist/es/ai-model/models/ui-tars/adapter.mjs.map +1 -0
  49. package/dist/es/ai-model/{ui-tars-planning.mjs → models/ui-tars/planning.mjs} +44 -62
  50. package/dist/es/ai-model/models/ui-tars/planning.mjs.map +1 -0
  51. package/dist/es/ai-model/prompt/extraction.mjs +3 -3
  52. package/dist/es/ai-model/prompt/extraction.mjs.map +1 -1
  53. package/dist/es/ai-model/prompt/llm-locator.mjs +11 -11
  54. package/dist/es/ai-model/prompt/llm-locator.mjs.map +1 -1
  55. package/dist/es/ai-model/prompt/llm-planning.mjs +25 -60
  56. package/dist/es/ai-model/prompt/llm-planning.mjs.map +1 -1
  57. package/dist/es/ai-model/prompt/llm-section-locator.mjs +15 -10
  58. package/dist/es/ai-model/prompt/llm-section-locator.mjs.map +1 -1
  59. package/dist/es/ai-model/prompt/locate-grounding-rules.mjs +9 -0
  60. package/dist/es/ai-model/prompt/locate-grounding-rules.mjs.map +1 -0
  61. package/dist/es/ai-model/prompt/locate-param-example.mjs +15 -0
  62. package/dist/es/ai-model/prompt/locate-param-example.mjs.map +1 -0
  63. package/dist/es/ai-model/prompt/playwright-generator.mjs +5 -5
  64. package/dist/es/ai-model/prompt/playwright-generator.mjs.map +1 -1
  65. package/dist/es/ai-model/prompt/yaml-generator.mjs +5 -5
  66. package/dist/es/ai-model/prompt/yaml-generator.mjs.map +1 -1
  67. package/dist/es/ai-model/prompts/locate-result-coordinates.mjs +107 -0
  68. package/dist/es/ai-model/prompts/locate-result-coordinates.mjs.map +1 -0
  69. package/dist/es/ai-model/service-caller/index.mjs +59 -190
  70. package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
  71. package/dist/es/ai-model/service-caller/json.mjs +60 -0
  72. package/dist/es/ai-model/service-caller/json.mjs.map +1 -0
  73. package/dist/es/ai-model/shared/model-locate-result/bbox.mjs +68 -0
  74. package/dist/es/ai-model/shared/model-locate-result/bbox.mjs.map +1 -0
  75. package/dist/es/ai-model/shared/model-locate-result/factory.mjs +96 -0
  76. package/dist/es/ai-model/shared/model-locate-result/factory.mjs.map +1 -0
  77. package/dist/es/ai-model/shared/model-locate-result/index.mjs +3 -0
  78. package/dist/es/ai-model/shared/model-locate-result/parse.mjs +41 -0
  79. package/dist/es/ai-model/shared/model-locate-result/parse.mjs.map +1 -0
  80. package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs +64 -0
  81. package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs.map +1 -0
  82. package/dist/es/ai-model/shared/model-locate-result/types.mjs +0 -0
  83. package/dist/es/ai-model/types.mjs +0 -0
  84. package/dist/es/ai-model/workflows/image-preprocess.mjs +27 -0
  85. package/dist/es/ai-model/workflows/image-preprocess.mjs.map +1 -0
  86. package/dist/es/ai-model/workflows/inspect/index.mjs +2 -0
  87. package/dist/es/ai-model/workflows/inspect/locate-result-rect.mjs +23 -0
  88. package/dist/es/ai-model/workflows/inspect/locate-result-rect.mjs.map +1 -0
  89. package/dist/es/ai-model/workflows/inspect/search-area-mapping.mjs +18 -0
  90. package/dist/es/ai-model/workflows/inspect/search-area-mapping.mjs.map +1 -0
  91. package/dist/es/ai-model/workflows/inspect/types.mjs +0 -0
  92. package/dist/es/ai-model/workflows/planning/index.mjs +5 -0
  93. package/dist/es/ai-model/workflows/planning/index.mjs.map +1 -0
  94. package/dist/es/ai-model/workflows/planning/types.mjs +0 -0
  95. package/dist/es/common.mjs +2 -174
  96. package/dist/es/common.mjs.map +1 -1
  97. package/dist/es/device/index.mjs.map +1 -1
  98. package/dist/es/service/index.mjs +96 -69
  99. package/dist/es/service/index.mjs.map +1 -1
  100. package/dist/es/types.mjs.map +1 -1
  101. package/dist/es/utils.mjs +2 -2
  102. package/dist/es/yaml/player.mjs +4 -3
  103. package/dist/es/yaml/player.mjs.map +1 -1
  104. package/dist/lib/agent/agent.js +43 -53
  105. package/dist/lib/agent/agent.js.map +1 -1
  106. package/dist/lib/agent/task-builder.js +38 -18
  107. package/dist/lib/agent/task-builder.js.map +1 -1
  108. package/dist/lib/agent/tasks.js +23 -21
  109. package/dist/lib/agent/tasks.js.map +1 -1
  110. package/dist/lib/agent/utils.js +17 -17
  111. package/dist/lib/agent/utils.js.map +1 -1
  112. package/dist/lib/ai-model/connectivity.js +7 -3
  113. package/dist/lib/ai-model/connectivity.js.map +1 -1
  114. package/dist/lib/ai-model/errors.js +46 -0
  115. package/dist/lib/ai-model/errors.js.map +1 -0
  116. package/dist/lib/ai-model/index.js +7 -14
  117. package/dist/lib/ai-model/inspect.js +141 -144
  118. package/dist/lib/ai-model/inspect.js.map +1 -1
  119. package/dist/lib/ai-model/llm-planning.js +44 -26
  120. package/dist/lib/ai-model/llm-planning.js.map +1 -1
  121. package/dist/lib/ai-model/{auto-glm → models/auto-glm}/actions.js +22 -44
  122. package/dist/lib/ai-model/models/auto-glm/actions.js.map +1 -0
  123. package/dist/lib/ai-model/models/auto-glm/adapter.js +79 -0
  124. package/dist/lib/ai-model/models/auto-glm/adapter.js.map +1 -0
  125. package/dist/lib/ai-model/models/auto-glm/locate.js +146 -0
  126. package/dist/lib/ai-model/models/auto-glm/locate.js.map +1 -0
  127. package/dist/lib/ai-model/models/auto-glm/parser.js.map +1 -0
  128. package/dist/lib/ai-model/{auto-glm → models/auto-glm}/planning.js +8 -9
  129. package/dist/lib/ai-model/models/auto-glm/planning.js.map +1 -0
  130. package/dist/lib/ai-model/{auto-glm → models/auto-glm}/prompt.js +14 -16
  131. package/dist/lib/ai-model/models/auto-glm/prompt.js.map +1 -0
  132. package/dist/lib/ai-model/{auto-glm/util.js → models/default.js} +13 -13
  133. package/dist/lib/ai-model/models/default.js.map +1 -0
  134. package/dist/lib/ai-model/models/doubao.js +184 -0
  135. package/dist/lib/ai-model/models/doubao.js.map +1 -0
  136. package/dist/lib/ai-model/models/gemini.js +68 -0
  137. package/dist/lib/ai-model/models/gemini.js.map +1 -0
  138. package/dist/lib/ai-model/models/glm.js +71 -0
  139. package/dist/lib/ai-model/models/glm.js.map +1 -0
  140. package/dist/lib/ai-model/models/gpt.js +65 -0
  141. package/dist/lib/ai-model/models/gpt.js.map +1 -0
  142. package/dist/lib/ai-model/{service-caller/image-detail.js → models/index.js} +8 -7
  143. package/dist/lib/ai-model/models/index.js.map +1 -0
  144. package/dist/lib/ai-model/models/qwen.js +147 -0
  145. package/dist/lib/ai-model/models/qwen.js.map +1 -0
  146. package/dist/lib/ai-model/models/registry.js +85 -0
  147. package/dist/lib/ai-model/models/registry.js.map +1 -0
  148. package/dist/lib/ai-model/models/resolved.js +138 -0
  149. package/dist/lib/ai-model/models/resolved.js.map +1 -0
  150. package/dist/lib/ai-model/models/types.js +20 -0
  151. package/dist/lib/ai-model/models/types.js.map +1 -0
  152. package/dist/lib/ai-model/models/ui-tars/adapter.js +176 -0
  153. package/dist/lib/ai-model/models/ui-tars/adapter.js.map +1 -0
  154. package/dist/lib/ai-model/{ui-tars-planning.js → models/ui-tars/planning.js} +44 -62
  155. package/dist/lib/ai-model/models/ui-tars/planning.js.map +1 -0
  156. package/dist/lib/ai-model/prompt/extraction.js +3 -3
  157. package/dist/lib/ai-model/prompt/extraction.js.map +1 -1
  158. package/dist/lib/ai-model/prompt/llm-locator.js +11 -11
  159. package/dist/lib/ai-model/prompt/llm-locator.js.map +1 -1
  160. package/dist/lib/ai-model/prompt/llm-planning.js +25 -60
  161. package/dist/lib/ai-model/prompt/llm-planning.js.map +1 -1
  162. package/dist/lib/ai-model/prompt/llm-section-locator.js +15 -10
  163. package/dist/lib/ai-model/prompt/llm-section-locator.js.map +1 -1
  164. package/dist/lib/ai-model/prompt/locate-grounding-rules.js +43 -0
  165. package/dist/lib/ai-model/prompt/locate-grounding-rules.js.map +1 -0
  166. package/dist/lib/ai-model/prompt/locate-param-example.js +52 -0
  167. package/dist/lib/ai-model/prompt/locate-param-example.js.map +1 -0
  168. package/dist/lib/ai-model/prompt/playwright-generator.js +5 -5
  169. package/dist/lib/ai-model/prompt/playwright-generator.js.map +1 -1
  170. package/dist/lib/ai-model/prompt/yaml-generator.js +5 -5
  171. package/dist/lib/ai-model/prompt/yaml-generator.js.map +1 -1
  172. package/dist/lib/ai-model/prompts/locate-result-coordinates.js +150 -0
  173. package/dist/lib/ai-model/prompts/locate-result-coordinates.js.map +1 -0
  174. package/dist/lib/ai-model/service-caller/index.js +68 -199
  175. package/dist/lib/ai-model/service-caller/index.js.map +1 -1
  176. package/dist/lib/ai-model/service-caller/json.js +100 -0
  177. package/dist/lib/ai-model/service-caller/json.js.map +1 -0
  178. package/dist/lib/ai-model/shared/model-locate-result/bbox.js +117 -0
  179. package/dist/lib/ai-model/shared/model-locate-result/bbox.js.map +1 -0
  180. package/dist/lib/ai-model/shared/model-locate-result/factory.js +130 -0
  181. package/dist/lib/ai-model/shared/model-locate-result/factory.js.map +1 -0
  182. package/dist/lib/ai-model/{prompt/common.js → shared/model-locate-result/index.js} +9 -9
  183. package/dist/lib/ai-model/shared/model-locate-result/index.js.map +1 -0
  184. package/dist/lib/ai-model/shared/model-locate-result/parse.js +78 -0
  185. package/dist/lib/ai-model/shared/model-locate-result/parse.js.map +1 -0
  186. package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js +98 -0
  187. package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js.map +1 -0
  188. package/dist/lib/ai-model/shared/model-locate-result/types.js +20 -0
  189. package/dist/lib/ai-model/shared/model-locate-result/types.js.map +1 -0
  190. package/dist/lib/ai-model/types.js +20 -0
  191. package/dist/lib/ai-model/types.js.map +1 -0
  192. package/dist/lib/ai-model/workflows/image-preprocess.js +61 -0
  193. package/dist/lib/ai-model/workflows/image-preprocess.js.map +1 -0
  194. package/dist/lib/ai-model/workflows/inspect/index.js +50 -0
  195. package/dist/lib/ai-model/workflows/inspect/index.js.map +1 -0
  196. package/dist/lib/ai-model/workflows/inspect/locate-result-rect.js +60 -0
  197. package/dist/lib/ai-model/workflows/inspect/locate-result-rect.js.map +1 -0
  198. package/dist/lib/ai-model/workflows/inspect/search-area-mapping.js +52 -0
  199. package/dist/lib/ai-model/workflows/inspect/search-area-mapping.js.map +1 -0
  200. package/dist/lib/ai-model/workflows/inspect/types.js +20 -0
  201. package/dist/lib/ai-model/workflows/inspect/types.js.map +1 -0
  202. package/dist/lib/ai-model/{model-family.js → workflows/planning/index.js} +6 -7
  203. package/dist/lib/ai-model/workflows/planning/index.js.map +1 -0
  204. package/dist/lib/ai-model/workflows/planning/types.js +20 -0
  205. package/dist/lib/ai-model/workflows/planning/types.js.map +1 -0
  206. package/dist/lib/common.js +4 -206
  207. package/dist/lib/common.js.map +1 -1
  208. package/dist/lib/device/index.js.map +1 -1
  209. package/dist/lib/service/index.js +96 -69
  210. package/dist/lib/service/index.js.map +1 -1
  211. package/dist/lib/types.js.map +1 -1
  212. package/dist/lib/utils.js +2 -2
  213. package/dist/lib/yaml/player.js +4 -3
  214. package/dist/lib/yaml/player.js.map +1 -1
  215. package/dist/types/agent/agent.d.ts +14 -6
  216. package/dist/types/agent/task-builder.d.ts +2 -2
  217. package/dist/types/agent/tasks.d.ts +6 -6
  218. package/dist/types/agent/utils.d.ts +8 -5
  219. package/dist/types/ai-model/errors.d.ts +2 -0
  220. package/dist/types/ai-model/index.d.ts +2 -4
  221. package/dist/types/ai-model/inspect.d.ts +13 -33
  222. package/dist/types/ai-model/llm-planning.d.ts +6 -17
  223. package/dist/types/ai-model/{auto-glm → models/auto-glm}/actions.d.ts +2 -2
  224. package/dist/types/ai-model/models/auto-glm/adapter.d.ts +5 -0
  225. package/dist/types/ai-model/models/auto-glm/locate.d.ts +3 -0
  226. package/dist/types/ai-model/models/auto-glm/planning.d.ts +3 -0
  227. package/dist/types/ai-model/models/auto-glm/prompt.d.ts +4 -0
  228. package/dist/types/ai-model/models/default.d.ts +2 -0
  229. package/dist/types/ai-model/models/doubao.d.ts +10 -0
  230. package/dist/types/ai-model/models/gemini.d.ts +18 -0
  231. package/dist/types/ai-model/models/glm.d.ts +18 -0
  232. package/dist/types/ai-model/models/gpt.d.ts +18 -0
  233. package/dist/types/ai-model/models/index.d.ts +2 -0
  234. package/dist/types/ai-model/models/qwen.d.ts +30 -0
  235. package/dist/types/ai-model/models/registry.d.ts +81 -0
  236. package/dist/types/ai-model/models/resolved.d.ts +9 -0
  237. package/dist/types/ai-model/models/types.d.ts +102 -0
  238. package/dist/types/ai-model/models/ui-tars/adapter.d.ts +6 -0
  239. package/dist/types/ai-model/{ui-tars-planning.d.ts → models/ui-tars/planning.d.ts} +7 -11
  240. package/dist/types/ai-model/prompt/llm-locator.d.ts +2 -2
  241. package/dist/types/ai-model/prompt/llm-planning.d.ts +5 -5
  242. package/dist/types/ai-model/prompt/llm-section-locator.d.ts +2 -2
  243. package/dist/types/ai-model/prompt/locate-grounding-rules.d.ts +1 -0
  244. package/dist/types/ai-model/prompt/locate-param-example.d.ts +3 -0
  245. package/dist/types/ai-model/prompt/playwright-generator.d.ts +3 -3
  246. package/dist/types/ai-model/prompt/yaml-generator.d.ts +3 -3
  247. package/dist/types/ai-model/prompts/locate-result-coordinates.d.ts +6 -0
  248. package/dist/types/ai-model/service-caller/index.d.ts +19 -27
  249. package/dist/types/ai-model/service-caller/json.d.ts +9 -0
  250. package/dist/types/ai-model/shared/model-locate-result/bbox.d.ts +7 -0
  251. package/dist/types/ai-model/shared/model-locate-result/factory.d.ts +2 -0
  252. package/dist/types/ai-model/shared/model-locate-result/index.d.ts +3 -0
  253. package/dist/types/ai-model/shared/model-locate-result/parse.d.ts +5 -0
  254. package/dist/types/ai-model/shared/model-locate-result/pixel-bbox-mapper.d.ts +7 -0
  255. package/dist/types/ai-model/shared/model-locate-result/types.d.ts +157 -0
  256. package/dist/types/ai-model/types.d.ts +2 -0
  257. package/dist/types/ai-model/workflows/image-preprocess.d.ts +30 -0
  258. package/dist/types/ai-model/workflows/inspect/index.d.ts +1 -0
  259. package/dist/types/ai-model/workflows/inspect/locate-result-rect.d.ts +4 -0
  260. package/dist/types/ai-model/workflows/inspect/search-area-mapping.d.ts +3 -0
  261. package/dist/types/ai-model/workflows/inspect/types.d.ts +37 -0
  262. package/dist/types/ai-model/workflows/planning/index.d.ts +2 -0
  263. package/dist/types/ai-model/workflows/planning/types.d.ts +15 -0
  264. package/dist/types/common.d.ts +0 -30
  265. package/dist/types/device/index.d.ts +22 -22
  266. package/dist/types/service/index.d.ts +5 -4
  267. package/dist/types/types.d.ts +21 -9
  268. package/dist/types/yaml.d.ts +8 -2
  269. package/package.json +2 -2
  270. package/dist/es/ai-model/auto-glm/actions.mjs.map +0 -1
  271. package/dist/es/ai-model/auto-glm/index.mjs +0 -6
  272. package/dist/es/ai-model/auto-glm/parser.mjs.map +0 -1
  273. package/dist/es/ai-model/auto-glm/planning.mjs.map +0 -1
  274. package/dist/es/ai-model/auto-glm/prompt.mjs.map +0 -1
  275. package/dist/es/ai-model/auto-glm/util.mjs +0 -9
  276. package/dist/es/ai-model/auto-glm/util.mjs.map +0 -1
  277. package/dist/es/ai-model/model-family.mjs +0 -6
  278. package/dist/es/ai-model/model-family.mjs.map +0 -1
  279. package/dist/es/ai-model/prompt/common.mjs +0 -8
  280. package/dist/es/ai-model/prompt/common.mjs.map +0 -1
  281. package/dist/es/ai-model/service-caller/image-detail.mjs +0 -6
  282. package/dist/es/ai-model/service-caller/image-detail.mjs.map +0 -1
  283. package/dist/es/ai-model/ui-tars-planning.mjs.map +0 -1
  284. package/dist/lib/ai-model/auto-glm/actions.js.map +0 -1
  285. package/dist/lib/ai-model/auto-glm/index.js +0 -66
  286. package/dist/lib/ai-model/auto-glm/index.js.map +0 -1
  287. package/dist/lib/ai-model/auto-glm/parser.js.map +0 -1
  288. package/dist/lib/ai-model/auto-glm/planning.js.map +0 -1
  289. package/dist/lib/ai-model/auto-glm/prompt.js.map +0 -1
  290. package/dist/lib/ai-model/auto-glm/util.js.map +0 -1
  291. package/dist/lib/ai-model/model-family.js.map +0 -1
  292. package/dist/lib/ai-model/prompt/common.js.map +0 -1
  293. package/dist/lib/ai-model/service-caller/image-detail.js.map +0 -1
  294. package/dist/lib/ai-model/ui-tars-planning.js.map +0 -1
  295. package/dist/types/ai-model/auto-glm/index.d.ts +0 -6
  296. package/dist/types/ai-model/auto-glm/planning.d.ts +0 -12
  297. package/dist/types/ai-model/auto-glm/prompt.d.ts +0 -27
  298. package/dist/types/ai-model/auto-glm/util.d.ts +0 -13
  299. package/dist/types/ai-model/model-family.d.ts +0 -7
  300. package/dist/types/ai-model/prompt/common.d.ts +0 -2
  301. package/dist/types/ai-model/service-caller/image-detail.d.ts +0 -2
  302. /package/dist/es/ai-model/{auto-glm → models/auto-glm}/parser.mjs +0 -0
  303. /package/dist/lib/ai-model/{auto-glm → models/auto-glm}/parser.js +0 -0
  304. /package/dist/types/ai-model/{auto-glm → models/auto-glm}/parser.d.ts +0 -0
@@ -1,4 +1,4 @@
1
- import { isAutoGLM, isUITars } from "../ai-model/auto-glm/util.mjs";
1
+ import { getModelRuntime } from "../ai-model/models/index.mjs";
2
2
  import js_yaml from "js-yaml";
3
3
  import { ScreenshotItem } from "../screenshot-item.mjs";
4
4
  import service from "../service/index.mjs";
@@ -54,9 +54,6 @@ const normalizeScrollType = (scrollType)=>{
54
54
  if (scrollType in legacyScrollTypeMap) return legacyScrollTypeMap[scrollType];
55
55
  return scrollType;
56
56
  };
57
- const defaultReplanningCycleLimit = 20;
58
- const defaultVlmUiTarsReplanningCycleLimit = 40;
59
- const defaultAutoGlmReplanningCycleLimit = 100;
60
57
  class Agent {
61
58
  get onDumpUpdate() {
62
59
  return this.dumpUpdateListeners[0];
@@ -71,15 +68,14 @@ class Agent {
71
68
  get page() {
72
69
  return this.interface;
73
70
  }
74
- ensureVLModelWarning() {
75
- if (!this.hasWarnedNonVLModel && 'puppeteer' !== this.interface.interfaceType && 'playwright' !== this.interface.interfaceType && 'static' !== this.interface.interfaceType && 'chrome-extension-proxy' !== this.interface.interfaceType && 'page-over-chrome-extension-bridge' !== this.interface.interfaceType) {
76
- this.modelConfigManager.throwErrorIfNonVLModel();
77
- this.hasWarnedNonVLModel = true;
78
- }
71
+ assertModelFamilyForNonWebContext() {
72
+ if ('puppeteer' !== this.interface.interfaceType && 'playwright' !== this.interface.interfaceType && 'static' !== this.interface.interfaceType && 'chrome-extension-proxy' !== this.interface.interfaceType && 'page-over-chrome-extension-bridge' !== this.interface.interfaceType) this.modelConfigManager.throwErrorIfNonVLModel();
73
+ }
74
+ resolveReplanningCycleLimit(planningModel) {
75
+ return this.opts.replanningCycleLimit ?? globalConfigManager.getEnvConfigValueAsNumber(MIDSCENE_REPLANNING_CYCLE_LIMIT) ?? planningModel.adapter.planning.defaultReplanningCycleLimit;
79
76
  }
80
- resolveReplanningCycleLimit(modelConfigForPlanning) {
81
- if (void 0 !== this.opts.replanningCycleLimit) return this.opts.replanningCycleLimit;
82
- return isUITars(modelConfigForPlanning.modelFamily) ? defaultVlmUiTarsReplanningCycleLimit : isAutoGLM(modelConfigForPlanning.modelFamily) ? defaultAutoGlmReplanningCycleLimit : defaultReplanningCycleLimit;
77
+ resolveModelRuntime(intent) {
78
+ return getModelRuntime(this.modelConfigManager.getModelConfig(intent));
83
79
  }
84
80
  async getActionSpace() {
85
81
  return this.fullActionSpace;
@@ -88,18 +84,16 @@ class Agent {
88
84
  return false;
89
85
  }
90
86
  async getUIContext(action) {
91
- this.ensureVLModelWarning();
87
+ this.assertModelFamilyForNonWebContext();
92
88
  if (this.frozenUIContext) {
93
89
  debug('Using frozen page context for action:', action);
94
90
  return this.frozenUIContext;
95
91
  }
96
- const { modelFamily } = this.modelConfigManager.getModelConfig('default');
97
92
  const maxRetries = Agent.CONTEXT_RETRY_MAX;
98
93
  for(let attempt = 0;; attempt++)try {
99
94
  return await commonContextParser(this.interface, {
100
95
  uploadServerUrl: this.modelConfigManager.getUploadTestServerUrl(),
101
- screenshotShrinkFactor: this.opts.screenshotShrinkFactor,
102
- modelFamily
96
+ screenshotShrinkFactor: this.opts.screenshotShrinkFactor
103
97
  });
104
98
  } catch (error) {
105
99
  if (attempt < maxRetries && this.isRetryableContextError(error)) {
@@ -193,9 +187,9 @@ class Agent {
193
187
  actionPlan
194
188
  ].filter(Boolean);
195
189
  const title = taskTitleStr(type, locateParamStr(opt?.locate || {}));
196
- const defaultIntentModelConfig = this.modelConfigManager.getModelConfig('default');
197
- const modelConfigForPlanning = this.modelConfigManager.getModelConfig('planning');
198
- const { output } = await this.taskExecutor.runPlans(title, plans, modelConfigForPlanning, defaultIntentModelConfig);
190
+ const defaultModel = this.resolveModelRuntime('default');
191
+ const planningModel = this.resolveModelRuntime('planning');
192
+ const { output } = await this.taskExecutor.runPlans(title, plans, planningModel, defaultModel);
199
193
  return output;
200
194
  }
201
195
  async aiTap(locatePrompt, opt) {
@@ -339,20 +333,20 @@ class Agent {
339
333
  const abortSignal = opt?.abortSignal;
340
334
  if (abortSignal?.aborted) throw new Error(`aiAct aborted: ${abortSignal.reason || 'signal already aborted'}`);
341
335
  const runAiAct = async ()=>{
342
- const modelConfigForPlanning = this.modelConfigManager.getModelConfig('planning');
336
+ const planningModel = this.resolveModelRuntime('planning');
337
+ const defaultModel = this.resolveModelRuntime('default');
343
338
  const deepThink = opt?.deepThink === true;
344
339
  const deepLocate = opt?.deepLocate;
345
- const noIndividualLocateModel = 'default' === modelConfigForPlanning.slot;
346
- const includeBboxInPlanning = !deepThink && noIndividualLocateModel;
347
- debug('setting includeBboxInPlanning to', includeBboxInPlanning, {
340
+ const noIndividualLocateModel = 'default' === planningModel.config.slot;
341
+ const includeLocateInPlanning = !deepThink && noIndividualLocateModel;
342
+ debug('setting includeLocateInPlanning to', includeLocateInPlanning, {
348
343
  deepThink,
349
344
  noIndividualLocateModel
350
345
  });
351
346
  const cacheable = opt?.cacheable;
352
- const replanningCycleLimit = this.resolveReplanningCycleLimit(modelConfigForPlanning);
353
- const isVlmUiTars = isUITars(modelConfigForPlanning.modelFamily);
354
- const isAutoGlm = isAutoGLM(modelConfigForPlanning.modelFamily);
355
- const matchedCache = isVlmUiTars || isAutoGlm || false === cacheable ? void 0 : this.taskCache?.matchPlanCache(taskPrompt);
347
+ const replanningCycleLimit = this.resolveReplanningCycleLimit(planningModel);
348
+ const planCacheEnabled = planningModel.adapter.planning.cacheEnabled;
349
+ const matchedCache = planCacheEnabled && false !== cacheable ? this.taskCache?.matchPlanCache(taskPrompt) : void 0;
356
350
  if (matchedCache?.cacheUsable && this.taskCache?.isCacheResultUsed && matchedCache.cacheContent?.yamlWorkflow?.trim()) {
357
351
  await this.taskExecutor.loadYamlFlowAsPlanning(taskPrompt, matchedCache.cacheContent.yamlWorkflow);
358
352
  debug('matched cache, will call .runYaml to run the action');
@@ -361,7 +355,7 @@ class Agent {
361
355
  return;
362
356
  }
363
357
  const imagesIncludeCount = deepThink ? 2 : 1;
364
- const { output: actionOutput } = await this.taskExecutor.action(taskPrompt, modelConfigForPlanning, this.modelConfigManager.getModelConfig('default'), includeBboxInPlanning, this.aiActContext, cacheable, replanningCycleLimit, imagesIncludeCount, deepThink, fileChooserAccept, deepLocate, abortSignal);
358
+ const { output: actionOutput } = await this.taskExecutor.action(taskPrompt, planningModel, defaultModel, includeLocateInPlanning, this.aiActContext, cacheable, replanningCycleLimit, imagesIncludeCount, deepThink, fileChooserAccept, deepLocate, abortSignal);
365
359
  if (this.taskCache && actionOutput?.yamlFlow?.length && false !== cacheable) {
366
360
  const yamlContent = {
367
361
  tasks: [
@@ -386,26 +380,26 @@ class Agent {
386
380
  return this.aiAct(taskPrompt, opt);
387
381
  }
388
382
  async aiQuery(demand, opt = defaultServiceExtractOption) {
389
- const modelConfig = this.modelConfigManager.getModelConfig('insight');
390
- const { output } = await this.taskExecutor.createTypeQueryExecution('Query', demand, modelConfig, opt);
383
+ const modelRuntime = this.resolveModelRuntime('insight');
384
+ const { output } = await this.taskExecutor.createTypeQueryExecution('Query', demand, modelRuntime, opt);
391
385
  return output;
392
386
  }
393
387
  async aiBoolean(prompt, opt = defaultServiceExtractOption) {
394
- const modelConfig = this.modelConfigManager.getModelConfig('insight');
388
+ const modelRuntime = this.resolveModelRuntime('insight');
395
389
  const { textPrompt, multimodalPrompt } = parsePrompt(prompt);
396
- const { output } = await this.taskExecutor.createTypeQueryExecution('Boolean', textPrompt, modelConfig, opt, multimodalPrompt);
390
+ const { output } = await this.taskExecutor.createTypeQueryExecution('Boolean', textPrompt, modelRuntime, opt, multimodalPrompt);
397
391
  return output;
398
392
  }
399
393
  async aiNumber(prompt, opt = defaultServiceExtractOption) {
400
- const modelConfig = this.modelConfigManager.getModelConfig('insight');
394
+ const modelRuntime = this.resolveModelRuntime('insight');
401
395
  const { textPrompt, multimodalPrompt } = parsePrompt(prompt);
402
- const { output } = await this.taskExecutor.createTypeQueryExecution('Number', textPrompt, modelConfig, opt, multimodalPrompt);
396
+ const { output } = await this.taskExecutor.createTypeQueryExecution('Number', textPrompt, modelRuntime, opt, multimodalPrompt);
403
397
  return output;
404
398
  }
405
399
  async aiString(prompt, opt = defaultServiceExtractOption) {
406
- const modelConfig = this.modelConfigManager.getModelConfig('insight');
400
+ const modelRuntime = this.resolveModelRuntime('insight');
407
401
  const { textPrompt, multimodalPrompt } = parsePrompt(prompt);
408
- const { output } = await this.taskExecutor.createTypeQueryExecution('String', textPrompt, modelConfig, opt, multimodalPrompt);
402
+ const { output } = await this.taskExecutor.createTypeQueryExecution('String', textPrompt, modelRuntime, opt, multimodalPrompt);
409
403
  return output;
410
404
  }
411
405
  async aiAsk(prompt, opt = defaultServiceExtractOption) {
@@ -421,8 +415,8 @@ class Agent {
421
415
  while(!success && retryCount < retryLimit){
422
416
  if (retryCount >= 2) deepLocate = true;
423
417
  debug('aiDescribe', center, 'verifyPrompt', verifyPrompt, 'retryCount', retryCount, 'deepLocate', deepLocate);
424
- const modelConfig = this.modelConfigManager.getModelConfig('insight');
425
- const text = await this.service.describe(center, modelConfig, {
418
+ const modelRuntime = this.resolveModelRuntime('insight');
419
+ const text = await this.service.describe(center, modelRuntime, {
426
420
  deepLocate
427
421
  });
428
422
  debug('aiDescribe text', text);
@@ -464,9 +458,9 @@ class Agent {
464
458
  const plans = [
465
459
  locatePlan
466
460
  ];
467
- const defaultIntentModelConfig = this.modelConfigManager.getModelConfig('default');
468
- const modelConfigForPlanning = this.modelConfigManager.getModelConfig('planning');
469
- const { output } = await this.taskExecutor.runPlans(taskTitleStr('Locate', locateParamStr(locateParam)), plans, modelConfigForPlanning, defaultIntentModelConfig);
461
+ const defaultModel = this.resolveModelRuntime('default');
462
+ const planningModel = this.resolveModelRuntime('planning');
463
+ const { output } = await this.taskExecutor.runPlans(taskTitleStr('Locate', locateParamStr(locateParam)), plans, planningModel, defaultModel);
470
464
  const { element } = output;
471
465
  return {
472
466
  rect: element?.rect,
@@ -475,7 +469,7 @@ class Agent {
475
469
  };
476
470
  }
477
471
  async aiAssert(assertion, msg, opt) {
478
- const modelConfig = this.modelConfigManager.getModelConfig('insight');
472
+ const modelRuntime = this.resolveModelRuntime('insight');
479
473
  const serviceOpt = {
480
474
  domIncluded: opt?.domIncluded ?? defaultServiceExtractOption.domIncluded,
481
475
  screenshotIncluded: opt?.screenshotIncluded ?? defaultServiceExtractOption.screenshotIncluded
@@ -483,7 +477,7 @@ class Agent {
483
477
  const { textPrompt, multimodalPrompt } = parsePrompt(assertion);
484
478
  const assertionText = 'string' == typeof assertion ? assertion : assertion.prompt;
485
479
  try {
486
- const { output, thought } = await this.taskExecutor.createTypeQueryExecution('Assert', textPrompt, modelConfig, serviceOpt, multimodalPrompt);
480
+ const { output, thought } = await this.taskExecutor.createTypeQueryExecution('Assert', textPrompt, modelRuntime, serviceOpt, multimodalPrompt);
487
481
  const pass = Boolean(output);
488
482
  const message = pass ? void 0 : `Assertion failed: ${msg || assertionText}\nReason: ${thought || '(no_reason)'}`;
489
483
  if (opt?.keepRawResponse) return {
@@ -513,12 +507,12 @@ class Agent {
513
507
  }
514
508
  }
515
509
  async aiWaitFor(assertion, opt) {
516
- const modelConfig = this.modelConfigManager.getModelConfig('insight');
510
+ const modelRuntime = this.resolveModelRuntime('insight');
517
511
  await this.taskExecutor.waitFor(assertion, {
518
512
  ...opt,
519
513
  timeoutMs: opt?.timeoutMs || 15000,
520
514
  checkIntervalMs: opt?.checkIntervalMs || 3000
521
- }, modelConfig);
515
+ }, modelRuntime);
522
516
  }
523
517
  async ai(...args) {
524
518
  return this.aiAct(...args);
@@ -691,22 +685,18 @@ class Agent {
691
685
  _define_property(this, "destroyed", false);
692
686
  _define_property(this, "modelConfigManager", void 0);
693
687
  _define_property(this, "frozenUIContext", void 0);
694
- _define_property(this, "hasWarnedNonVLModel", false);
695
688
  _define_property(this, "executionDumpIndexByRunner", new WeakMap());
696
689
  _define_property(this, "fullActionSpace", void 0);
697
690
  _define_property(this, "reportGenerator", void 0);
698
691
  _define_property(this, "lastExecutionDump", void 0);
699
692
  this.interface = interfaceInstance;
700
- const envReplanningCycleLimit = globalConfigManager.getEnvConfigValueAsNumber(MIDSCENE_REPLANNING_CYCLE_LIMIT);
701
693
  this.opts = Object.assign({
702
694
  generateReport: true,
703
695
  persistExecutionDump: false,
704
696
  autoPrintReportMsg: true,
705
697
  groupName: 'Midscene Report',
706
698
  groupDescription: ''
707
- }, opts || {}, opts?.replanningCycleLimit !== void 0 || void 0 === envReplanningCycleLimit || Number.isNaN(envReplanningCycleLimit) ? {} : {
708
- replanningCycleLimit: envReplanningCycleLimit
709
- });
699
+ }, opts || {});
710
700
  assertReportGenerationOptions(this.opts);
711
701
  const resolvedAiActContext = this.opts.aiActContext ?? this.opts.aiActionContext;
712
702
  if (void 0 !== resolvedAiActContext) {
@@ -1 +1 @@
1
- {"version":3,"file":"agent/agent.mjs","sources":["../../../src/agent/agent.ts"],"sourcesContent":["import { isAutoGLM, isUITars } from '@/ai-model/auto-glm/util';\nimport yaml from 'js-yaml';\nimport type { TUserPrompt } from '../ai-model/index';\nimport { ScreenshotItem } from '../screenshot-item';\nimport Service from '../service/index';\n// Import types and values directly from their source files to avoid circular dependency\n// DO NOT import from '../index' as it creates a circular dependency:\n// index.ts -> agent/index.ts -> agent/agent.ts -> index.ts\nimport {\n type ActionParam,\n type ActionReturn,\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentOpt,\n type AgentWaitForOpt,\n type DeepThinkOption,\n type DeviceAction,\n ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskLog,\n type LocateOption,\n type LocateResultElement,\n type LocateValidatorResult,\n type LocatorValidatorOption,\n type OnTaskStartTip,\n type PlanningAction,\n type Rect,\n ReportActionDump,\n type ReportMeta,\n type ScrollParam,\n type ServiceAction,\n type ServiceExtractOption,\n type ServiceExtractParam,\n type TestStatus,\n type UIContext,\n} from '../types';\nimport type { MidsceneYamlScript } from '../yaml';\n\nimport type { IReportGenerator } from '@/report-generator';\nimport {\n ReportGenerator,\n assertReportGenerationOptions,\n} from '@/report-generator';\nimport { getVersion, processCacheConfig, reportHTMLContent } from '@/utils';\nimport {\n ScriptPlayer,\n buildDetailedLocateParam,\n parseYamlScript,\n} from '../yaml/index';\n\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { AbstractInterface } from '@/device';\nimport type { TaskRunner } from '@/task-runner';\nimport {\n type IModelConfig,\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n ModelConfigManager,\n globalConfigManager,\n globalModelConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert, ifInBrowser, uuid } from '@midscene/shared/utils';\nimport { defineActionSleep } from '../device';\nimport { validateAgentCacheInput } from './cache-config';\nimport { TaskCache } from './task-cache';\nimport {\n TaskExecutionError,\n TaskExecutor,\n locatePlanForLocate,\n withFileChooser,\n} from './tasks';\nimport { locateParamStr, paramStr, taskTitleStr, typeStr } from './ui-utils';\nimport { commonContextParser, getReportFileName, parsePrompt } from './utils';\n\nconst debug = getDebug('agent');\n\nconst distanceOfTwoPoints = (p1: [number, number], p2: [number, number]) => {\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n return Math.round(Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2));\n};\n\nconst includedInRect = (point: [number, number], rect: Rect) => {\n const [x, y] = point;\n const { left, top, width, height } = rect;\n return x >= left && x <= left + width && y >= top && y <= top + height;\n};\n\nconst defaultServiceExtractOption: ServiceExtractOption = {\n domIncluded: false,\n screenshotIncluded: true,\n};\n\nconst legacyScrollTypeMap = {\n once: 'singleAction',\n untilBottom: 'scrollToBottom',\n untilTop: 'scrollToTop',\n untilRight: 'scrollToRight',\n untilLeft: 'scrollToLeft',\n} as const;\n\ntype LegacyScrollType = keyof typeof legacyScrollTypeMap;\n\nconst normalizeScrollType = (\n scrollType: ScrollParam['scrollType'] | LegacyScrollType | undefined,\n): ScrollParam['scrollType'] | undefined => {\n if (!scrollType) {\n return scrollType;\n }\n\n if (scrollType in legacyScrollTypeMap) {\n return legacyScrollTypeMap[scrollType as LegacyScrollType];\n }\n\n return scrollType as ScrollParam['scrollType'];\n};\n\nconst defaultReplanningCycleLimit = 20;\nconst defaultVlmUiTarsReplanningCycleLimit = 40;\nconst defaultAutoGlmReplanningCycleLimit = 100;\n\nexport type AiActOptions = {\n cacheable?: boolean;\n fileChooserAccept?: string | string[];\n deepThink?: DeepThinkOption;\n deepLocate?: boolean;\n abortSignal?: AbortSignal;\n};\n\nexport class Agent<\n InterfaceType extends AbstractInterface = AbstractInterface,\n> {\n interface: InterfaceType;\n\n service: Service;\n\n dump: ReportActionDump;\n\n reportFile?: string | null;\n\n reportFileName?: string;\n\n taskExecutor: TaskExecutor;\n\n opts: AgentOpt;\n\n /**\n * If true, the agent will not perform any actions\n */\n dryMode = false;\n\n onTaskStartTip?: OnTaskStartTip;\n\n taskCache?: TaskCache;\n\n private dumpUpdateListeners: Array<\n (dump: string, executionDump?: ExecutionDump) => void\n > = [];\n\n get onDumpUpdate():\n | ((dump: string, executionDump?: ExecutionDump) => void)\n | undefined {\n return this.dumpUpdateListeners[0];\n }\n\n set onDumpUpdate(callback:\n | ((dump: string, executionDump?: ExecutionDump) => void)\n | undefined) {\n // Clear existing listeners\n this.dumpUpdateListeners = [];\n // Add callback to array if provided\n if (callback) {\n this.dumpUpdateListeners.push(callback);\n }\n }\n\n destroyed = false;\n\n modelConfigManager: ModelConfigManager;\n\n /**\n * Frozen page context for consistent AI operations\n */\n private frozenUIContext?: UIContext;\n\n private get aiActContext(): string | undefined {\n return this.opts.aiActContext ?? this.opts.aiActionContext;\n }\n\n /**\n * Flag to track if VL model warning has been shown\n */\n private hasWarnedNonVLModel = false;\n\n private executionDumpIndexByRunner = new WeakMap<TaskRunner, number>();\n\n private fullActionSpace: DeviceAction[];\n\n private reportGenerator: IReportGenerator;\n\n // @deprecated use .interface instead\n get page() {\n return this.interface;\n }\n\n /**\n * Ensures VL model warning is shown once when needed\n */\n private ensureVLModelWarning() {\n if (\n !this.hasWarnedNonVLModel &&\n this.interface.interfaceType !== 'puppeteer' &&\n this.interface.interfaceType !== 'playwright' &&\n this.interface.interfaceType !== 'static' &&\n this.interface.interfaceType !== 'chrome-extension-proxy' &&\n this.interface.interfaceType !== 'page-over-chrome-extension-bridge'\n ) {\n this.modelConfigManager.throwErrorIfNonVLModel();\n this.hasWarnedNonVLModel = true;\n }\n }\n\n private resolveReplanningCycleLimit(\n modelConfigForPlanning: IModelConfig,\n ): number {\n if (this.opts.replanningCycleLimit !== undefined) {\n return this.opts.replanningCycleLimit;\n }\n\n return isUITars(modelConfigForPlanning.modelFamily)\n ? defaultVlmUiTarsReplanningCycleLimit\n : isAutoGLM(modelConfigForPlanning.modelFamily)\n ? defaultAutoGlmReplanningCycleLimit\n : defaultReplanningCycleLimit;\n }\n\n constructor(interfaceInstance: InterfaceType, opts?: AgentOpt) {\n this.interface = interfaceInstance;\n\n const envReplanningCycleLimit =\n globalConfigManager.getEnvConfigValueAsNumber(\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n );\n\n this.opts = Object.assign(\n {\n generateReport: true,\n persistExecutionDump: false,\n autoPrintReportMsg: true,\n groupName: 'Midscene Report',\n groupDescription: '',\n },\n opts || {},\n opts?.replanningCycleLimit === undefined &&\n envReplanningCycleLimit !== undefined &&\n !Number.isNaN(envReplanningCycleLimit)\n ? { replanningCycleLimit: envReplanningCycleLimit }\n : {},\n );\n assertReportGenerationOptions(this.opts);\n\n const resolvedAiActContext =\n this.opts.aiActContext ?? this.opts.aiActionContext;\n if (resolvedAiActContext !== undefined) {\n this.opts.aiActContext = resolvedAiActContext;\n this.opts.aiActionContext ??= resolvedAiActContext;\n }\n\n if (\n opts?.modelConfig &&\n (typeof opts?.modelConfig !== 'object' || Array.isArray(opts.modelConfig))\n ) {\n throw new Error(\n `opts.modelConfig must be a plain object map of env keys to values, but got ${typeof opts?.modelConfig}`,\n );\n }\n // Create ModelConfigManager if modelConfig or createOpenAIClient is provided\n // Otherwise, use the global config manager\n const hasCustomConfig = opts?.modelConfig || opts?.createOpenAIClient;\n this.modelConfigManager = hasCustomConfig\n ? new ModelConfigManager(opts?.modelConfig, opts?.createOpenAIClient)\n : globalModelConfigManager;\n\n this.onTaskStartTip = this.opts.onTaskStartTip;\n\n this.service = new Service(async () => {\n return this.getUIContext();\n });\n\n // Process cache configuration\n const cacheConfigObj = this.processCacheConfig(opts || {});\n if (cacheConfigObj) {\n this.taskCache = new TaskCache(\n cacheConfigObj.id,\n cacheConfigObj.enabled,\n undefined, // cacheFilePath\n {\n readOnly: cacheConfigObj.readOnly,\n writeOnly: cacheConfigObj.writeOnly,\n cacheDir: cacheConfigObj.cacheDir,\n },\n );\n }\n\n const baseActionSpace = this.interface.actionSpace();\n this.fullActionSpace = [...baseActionSpace, defineActionSleep()];\n\n this.taskExecutor = new TaskExecutor(this.interface, this.service, {\n taskCache: this.taskCache,\n onTaskStart: this.callbackOnTaskStartTip.bind(this),\n replanningCycleLimit: this.opts.replanningCycleLimit,\n waitAfterAction: this.opts.waitAfterAction,\n useDeviceTime: this.opts.useDeviceTime,\n actionSpace: this.fullActionSpace,\n hooks: {\n onTaskUpdate: async (runner) => {\n const executionDump = runner.dump();\n this.appendExecutionDump(executionDump, runner);\n\n // Persist report updates before notifying listeners so screenshot\n // payloads can be released from memory and serialized as references.\n this.writeOutActionDumps(executionDump);\n await this.reportGenerator.flush();\n\n // Call all registered dump update listeners\n const dumpString = this.dumpDataString();\n for (const listener of this.dumpUpdateListeners) {\n try {\n listener(dumpString, executionDump);\n } catch (error) {\n console.error('Error in onDumpUpdate listener', error);\n }\n }\n },\n },\n });\n this.dump = this.resetDump();\n this.reportFileName =\n opts?.reportFileName ||\n // Keep deprecated testId behavior for generated report names until it is\n // fully removed from the public API.\n getReportFileName(opts?.testId || this.interface.interfaceType || 'web');\n\n this.reportGenerator = ReportGenerator.create(this.reportFileName!, {\n generateReport: this.opts.generateReport,\n persistExecutionDump: this.opts.persistExecutionDump,\n outputFormat: this.opts.outputFormat,\n autoPrintReportMsg: this.opts.autoPrintReportMsg,\n reuseExistingReport:\n this.opts.reportAttributes?.['data-group-id'] === this.reportFileName,\n });\n }\n\n async getActionSpace(): Promise<DeviceAction[]> {\n return this.fullActionSpace;\n }\n\n private static readonly CONTEXT_RETRY_MAX = 3;\n private static readonly CONTEXT_RETRY_DELAY_MS = 1500;\n\n /**\n * Override in subclasses to indicate which errors are transient and should\n * trigger an automatic retry when building the UI context.\n * Returns `false` by default (no retry).\n */\n protected isRetryableContextError(_error: unknown): boolean {\n return false;\n }\n\n async getUIContext(action?: ServiceAction): Promise<UIContext> {\n // Check VL model configuration when UI context is first needed\n this.ensureVLModelWarning();\n\n // If page context is frozen, return the frozen context for all actions\n if (this.frozenUIContext) {\n debug('Using frozen page context for action:', action);\n return this.frozenUIContext;\n }\n\n const { modelFamily } = this.modelConfigManager.getModelConfig('default');\n\n const maxRetries = Agent.CONTEXT_RETRY_MAX;\n for (let attempt = 0; ; attempt++) {\n try {\n return await commonContextParser(this.interface, {\n uploadServerUrl: this.modelConfigManager.getUploadTestServerUrl(),\n screenshotShrinkFactor: this.opts.screenshotShrinkFactor,\n modelFamily,\n });\n } catch (error) {\n if (attempt < maxRetries && this.isRetryableContextError(error)) {\n debug(\n `retryable context error (attempt ${attempt + 1}/${maxRetries}), retrying in ${Agent.CONTEXT_RETRY_DELAY_MS}ms: ${error}`,\n );\n await new Promise((resolve) =>\n setTimeout(resolve, Agent.CONTEXT_RETRY_DELAY_MS),\n );\n continue;\n }\n throw error;\n }\n }\n }\n\n async _snapshotContext(): Promise<UIContext> {\n return await this.getUIContext('locate');\n }\n\n /**\n * @deprecated Use {@link setAIActContext} instead.\n */\n async setAIActionContext(prompt: string) {\n await this.setAIActContext(prompt);\n }\n\n async setAIActContext(prompt: string) {\n if (this.aiActContext) {\n console.warn(\n 'aiActContext is already set, and it is called again, will override the previous setting',\n );\n }\n this.opts.aiActContext = prompt;\n this.opts.aiActionContext = prompt;\n }\n\n resetDump() {\n this.dump = new ReportActionDump({\n sdkVersion: getVersion(),\n groupName: this.opts.groupName!,\n groupDescription: this.opts.groupDescription,\n executions: [],\n modelBriefs: [],\n deviceType: this.interface.interfaceType,\n });\n this.executionDumpIndexByRunner = new WeakMap<TaskRunner, number>();\n\n return this.dump;\n }\n\n appendExecutionDump(execution: ExecutionDump, runner?: TaskRunner) {\n const currentDump = this.dump;\n if (runner) {\n const existingIndex = this.executionDumpIndexByRunner.get(runner);\n if (existingIndex !== undefined) {\n currentDump.executions[existingIndex] = execution;\n return;\n }\n currentDump.executions.push(execution);\n this.executionDumpIndexByRunner.set(\n runner,\n currentDump.executions.length - 1,\n );\n return;\n }\n currentDump.executions.push(execution);\n }\n\n dumpDataString(opt?: { inlineScreenshots?: boolean }) {\n // update dump info\n this.dump.groupName = this.opts.groupName!;\n this.dump.groupDescription = this.opts.groupDescription;\n // In browser environment, use inline screenshots since file system is not available\n if (ifInBrowser || opt?.inlineScreenshots) {\n return this.dump.serializeWithInlineScreenshots();\n }\n return this.dump.serialize();\n }\n\n reportHTMLString(opt?: { inlineScreenshots?: boolean }) {\n // dumpDataString() handles browser environment with inline screenshots\n return reportHTMLContent(this.dumpDataString(opt));\n }\n\n private lastExecutionDump?: ExecutionDump;\n\n writeOutActionDumps(executionDump?: ExecutionDump) {\n const exec = executionDump || this.lastExecutionDump;\n if (exec) {\n this.lastExecutionDump = exec;\n this.reportGenerator.onExecutionUpdate(\n exec,\n this.getReportMeta(),\n this.opts.reportAttributes,\n );\n }\n this.reportFile = this.reportGenerator.getReportPath();\n }\n\n private getReportMeta(): ReportMeta {\n return {\n groupName: this.dump.groupName,\n groupDescription: this.dump.groupDescription,\n sdkVersion: this.dump.sdkVersion,\n modelBriefs: this.dump.modelBriefs,\n deviceType: this.dump.deviceType,\n };\n }\n\n private async callbackOnTaskStartTip(task: ExecutionTask) {\n const param = paramStr(task);\n const tip = param ? `${typeStr(task)} - ${param}` : typeStr(task);\n\n if (this.onTaskStartTip) {\n await this.onTaskStartTip(tip);\n }\n }\n\n wrapActionInActionSpace<T extends DeviceAction>(\n name: string,\n ): (param: ActionParam<T>) => Promise<ActionReturn<T>> {\n return async (param: ActionParam<T>) => {\n return await this.callActionInActionSpace<ActionReturn<T>>(name, param);\n };\n }\n\n async callActionInActionSpace<T = any>(\n type: string,\n opt?: T, // and all other action params\n ) {\n debug('callActionInActionSpace', type, ',', opt);\n\n const actionPlan: PlanningAction<T> = {\n type: type as any,\n param: (opt as any) || {},\n thought: '',\n };\n debug('actionPlan', actionPlan); // , ', in which the locateParam is', locateParam);\n\n const plans: PlanningAction[] = [actionPlan].filter(\n Boolean,\n ) as PlanningAction[];\n\n const title = taskTitleStr(\n type as any,\n locateParamStr((opt as any)?.locate || {}),\n );\n\n // assume all operation in action space is related to locating\n const defaultIntentModelConfig =\n this.modelConfigManager.getModelConfig('default');\n const modelConfigForPlanning =\n this.modelConfigManager.getModelConfig('planning');\n\n const { output } = await this.taskExecutor.runPlans(\n title,\n plans,\n modelConfigForPlanning,\n defaultIntentModelConfig,\n );\n return output;\n }\n\n async aiTap(\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { fileChooserAccept?: string | string[] },\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for tap');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n const fileChooserAccept = opt?.fileChooserAccept\n ? this.normalizeFileInput(opt.fileChooserAccept)\n : undefined;\n\n await withFileChooser(this.interface, fileChooserAccept, async () => {\n await this.callActionInActionSpace('Tap', {\n locate: detailedLocateParam,\n });\n });\n }\n\n async aiRightClick(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for right click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('RightClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiDoubleClick(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for double click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('DoubleClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiHover(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for hover');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('Hover', {\n locate: detailedLocateParam,\n });\n }\n\n // New signature, always use locatePrompt as the first param\n async aiInput(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'typeOnly' | 'append' },\n ): Promise<void>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value\n */\n async aiInput(\n value: string | number,\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { autoDismissKeyboard?: boolean } & {\n mode?: 'replace' | 'clear' | 'typeOnly' | 'append';\n }, // AndroidDeviceInputOpt &\n ): Promise<void>;\n\n // Implementation\n async aiInput(\n locatePromptOrValue: TUserPrompt | string | number,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'typeOnly' | 'append' }) // AndroidDeviceInputOpt &\n | undefined,\n optOrUndefined?: LocateOption, // AndroidDeviceInputOpt &\n ) {\n let value: string | number;\n let locatePrompt: TUserPrompt;\n let opt:\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'typeOnly' | 'append' }) // AndroidDeviceInputOpt &\n | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has value)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'value' in locatePromptOrOpt\n ) {\n // New signature: aiInput(locatePrompt, opt)\n locatePrompt = locatePromptOrValue as TUserPrompt;\n const optWithValue = locatePromptOrOpt as LocateOption & {\n // AndroidDeviceInputOpt &\n value: string | number;\n autoDismissKeyboard?: boolean;\n };\n value = optWithValue.value;\n opt = optWithValue;\n } else {\n // Legacy signature: aiInput(value, locatePrompt, opt)\n value = locatePromptOrValue as string | number;\n locatePrompt = locatePromptOrOpt as TUserPrompt;\n opt = {\n ...optOrUndefined,\n value,\n };\n }\n\n assert(\n typeof value === 'string' || typeof value === 'number',\n 'input value must be a string or number, use empty string if you want to clear the input',\n );\n assert(locatePrompt, 'missing locate prompt for input');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n // Convert value to string to ensure consistency\n const stringValue = typeof value === 'number' ? String(value) : value;\n\n // backward compat: convert deprecated 'append' to 'typeOnly'\n const mode = opt?.mode === 'append' ? 'typeOnly' : opt?.mode;\n\n await this.callActionInActionSpace('Input', {\n ...(opt || {}),\n value: stringValue,\n locate: detailedLocateParam,\n mode,\n });\n }\n\n // New signature\n async aiKeyboardPress(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { keyName: string },\n ): Promise<void>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName\n */\n async aiKeyboardPress(\n keyName: string,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void>;\n\n // Implementation\n async aiKeyboardPress(\n locatePromptOrKeyName: TUserPrompt | string,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { keyName: string })\n | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let keyName: string;\n let locatePrompt: TUserPrompt | undefined;\n let opt: (LocateOption & { keyName: string }) | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has keyName)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'keyName' in locatePromptOrOpt\n ) {\n // New signature: aiKeyboardPress(locatePrompt, opt)\n locatePrompt = locatePromptOrKeyName as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & {\n keyName: string;\n };\n } else {\n // Legacy signature: aiKeyboardPress(keyName, locatePrompt, opt)\n keyName = locatePromptOrKeyName as string;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n keyName,\n };\n }\n\n assert(opt?.keyName, 'missing keyName for keyboard press');\n\n const detailedLocateParam = locatePrompt\n ? buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n\n await this.callActionInActionSpace('KeyboardPress', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n // New signature\n async aiScroll(\n locatePrompt: TUserPrompt | undefined,\n opt: LocateOption & ScrollParam,\n ): Promise<void>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters\n */\n async aiScroll(\n scrollParam: ScrollParam,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void>;\n\n // Implementation\n async aiScroll(\n locatePromptOrScrollParam: TUserPrompt | ScrollParam | undefined,\n locatePromptOrOpt: TUserPrompt | (LocateOption & ScrollParam) | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let scrollParam: ScrollParam;\n let locatePrompt: TUserPrompt | undefined;\n let opt: LocateOption | undefined;\n\n const isLocatePromptLike = (value: unknown): value is TUserPrompt => {\n if (\n typeof value === 'string' ||\n typeof value === 'undefined' ||\n value === null\n ) {\n return true;\n }\n\n return typeof value === 'object' && value !== null && 'prompt' in value;\n };\n\n // Check if using new signature (first param is locatePrompt, second is options)\n if (\n isLocatePromptLike(locatePromptOrScrollParam) &&\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null\n ) {\n // New signature: aiScroll(locatePrompt, opt)\n locatePrompt = locatePromptOrScrollParam as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & ScrollParam;\n } else {\n // Legacy signature: aiScroll(scrollParam, locatePrompt, opt)\n scrollParam = locatePromptOrScrollParam as ScrollParam;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n ...(scrollParam || {}),\n };\n }\n\n if (opt) {\n const normalizedScrollType = normalizeScrollType(\n (opt as ScrollParam).scrollType as\n | ScrollParam['scrollType']\n | LegacyScrollType\n | undefined,\n );\n\n if (normalizedScrollType !== (opt as ScrollParam).scrollType) {\n (opt as ScrollParam) = {\n ...(opt || {}),\n scrollType: normalizedScrollType as ScrollParam['scrollType'],\n };\n }\n }\n\n const detailedLocateParam = buildDetailedLocateParam(\n locatePrompt || '',\n opt,\n );\n\n await this.callActionInActionSpace('Scroll', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n async aiPinch(\n locatePrompt: TUserPrompt | undefined,\n opt: LocateOption & {\n direction: 'in' | 'out';\n distance?: number;\n duration?: number;\n },\n ): Promise<void> {\n const detailedLocateParam = buildDetailedLocateParam(\n locatePrompt || '',\n opt,\n );\n\n await this.callActionInActionSpace('Pinch', {\n ...opt,\n locate: detailedLocateParam,\n });\n }\n\n async aiLongPress(\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { duration?: number },\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for long press');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('LongPress', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n async aiClearInput(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for clear input');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('ClearInput', {\n locate: detailedLocateParam,\n });\n }\n\n async aiAct(\n taskPrompt: string,\n opt?: AiActOptions,\n ): Promise<string | undefined> {\n const fileChooserAccept = opt?.fileChooserAccept\n ? this.normalizeFileInput(opt.fileChooserAccept)\n : undefined;\n\n const abortSignal = opt?.abortSignal;\n if (abortSignal?.aborted) {\n throw new Error(\n `aiAct aborted: ${abortSignal.reason || 'signal already aborted'}`,\n );\n }\n\n const runAiAct = async () => {\n const modelConfigForPlanning =\n this.modelConfigManager.getModelConfig('planning');\n // Controls the aiAct planning mode, such as sub-goal prompts and bbox strategy.\n const deepThink = opt?.deepThink === true;\n\n const deepLocate = opt?.deepLocate;\n\n const noIndividualLocateModel = modelConfigForPlanning.slot === 'default';\n\n const includeBboxInPlanning = !deepThink && noIndividualLocateModel;\n\n debug('setting includeBboxInPlanning to', includeBboxInPlanning, {\n deepThink,\n noIndividualLocateModel,\n });\n\n const cacheable = opt?.cacheable;\n const replanningCycleLimit = this.resolveReplanningCycleLimit(\n modelConfigForPlanning,\n );\n // if vlm-ui-tars or auto-glm, plan cache is not used\n const isVlmUiTars = isUITars(modelConfigForPlanning.modelFamily);\n const isAutoGlm = isAutoGLM(modelConfigForPlanning.modelFamily);\n const matchedCache =\n isVlmUiTars || isAutoGlm || cacheable === false\n ? undefined\n : this.taskCache?.matchPlanCache(taskPrompt);\n if (\n matchedCache?.cacheUsable &&\n this.taskCache?.isCacheResultUsed &&\n matchedCache.cacheContent?.yamlWorkflow?.trim()\n ) {\n // log into report file\n await this.taskExecutor.loadYamlFlowAsPlanning(\n taskPrompt,\n matchedCache.cacheContent.yamlWorkflow,\n );\n\n debug('matched cache, will call .runYaml to run the action');\n const yaml = matchedCache.cacheContent.yamlWorkflow;\n await this.runYaml(yaml);\n return;\n }\n\n // If cache matched but is not executable, fall through to normal execution\n const imagesIncludeCount: number = deepThink ? 2 : 1;\n const { output: actionOutput } = await this.taskExecutor.action(\n taskPrompt,\n modelConfigForPlanning,\n this.modelConfigManager.getModelConfig('default'),\n includeBboxInPlanning,\n this.aiActContext,\n cacheable,\n replanningCycleLimit,\n imagesIncludeCount,\n deepThink,\n fileChooserAccept,\n deepLocate,\n abortSignal,\n );\n\n // update cache\n if (\n this.taskCache &&\n actionOutput?.yamlFlow?.length &&\n cacheable !== false\n ) {\n const yamlContent: MidsceneYamlScript = {\n tasks: [\n {\n name: taskPrompt,\n flow: actionOutput.yamlFlow,\n },\n ],\n };\n const yamlFlowStr = yaml.dump(yamlContent);\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'plan',\n prompt: taskPrompt,\n yamlWorkflow: yamlFlowStr,\n },\n matchedCache,\n );\n }\n\n return actionOutput?.output;\n };\n\n return await runAiAct();\n }\n\n /**\n * @deprecated Use {@link Agent.aiAct} instead.\n */\n async aiAction(taskPrompt: string, opt?: AiActOptions) {\n return this.aiAct(taskPrompt, opt);\n }\n\n async aiQuery<ReturnType = any>(\n demand: ServiceExtractParam,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<ReturnType> {\n const modelConfig = this.modelConfigManager.getModelConfig('insight');\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'Query',\n demand,\n modelConfig,\n opt,\n );\n return output as ReturnType;\n }\n\n async aiBoolean(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<boolean> {\n const modelConfig = this.modelConfigManager.getModelConfig('insight');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'Boolean',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n return output as boolean;\n }\n\n async aiNumber(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<number> {\n const modelConfig = this.modelConfigManager.getModelConfig('insight');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'Number',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n return output as number;\n }\n\n async aiString(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<string> {\n const modelConfig = this.modelConfigManager.getModelConfig('insight');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'String',\n textPrompt,\n modelConfig,\n opt,\n multimodalPrompt,\n );\n return output as string;\n }\n\n async aiAsk(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<string> {\n return this.aiString(prompt, opt);\n }\n\n async describeElementAtPoint(\n center: [number, number],\n opt?: {\n verifyPrompt?: boolean;\n retryLimit?: number;\n deepLocate?: boolean;\n } & LocatorValidatorOption,\n ): Promise<AgentDescribeElementAtPointResult> {\n const { verifyPrompt = true, retryLimit = 3 } = opt || {};\n\n let success = false;\n let retryCount = 0;\n let resultPrompt = '';\n let deepLocate = opt?.deepLocate || false;\n let verifyResult: LocateValidatorResult | undefined;\n\n while (!success && retryCount < retryLimit) {\n if (retryCount >= 2) {\n deepLocate = true;\n }\n debug(\n 'aiDescribe',\n center,\n 'verifyPrompt',\n verifyPrompt,\n 'retryCount',\n retryCount,\n 'deepLocate',\n deepLocate,\n );\n // use same intent as aiLocate\n const modelConfig = this.modelConfigManager.getModelConfig('insight');\n\n const text = await this.service.describe(center, modelConfig, {\n deepLocate,\n });\n debug('aiDescribe text', text);\n assert(text.description, `failed to describe element at [${center}]`);\n resultPrompt = text.description;\n\n if (!verifyPrompt) {\n success = true;\n break;\n }\n\n // Don't pass deepLocate to verification locate — the description was generated\n // from a cropped view (deepLocate describe), but verification should use regular\n // locate on the full screenshot to confirm the description works universally.\n // Passing deepLocate here would trigger AiLocateSection with an element-level\n // description as a section prompt, which is semantically incorrect.\n verifyResult = await this.verifyLocator(\n resultPrompt,\n undefined,\n center,\n opt,\n );\n if (verifyResult.pass) {\n success = true;\n } else {\n retryCount++;\n }\n }\n\n return {\n prompt: resultPrompt,\n deepLocate,\n verifyResult,\n };\n }\n\n async verifyLocator(\n prompt: string,\n locateOpt: LocateOption | undefined,\n expectCenter: [number, number],\n verifyLocateOption?: LocatorValidatorOption,\n ): Promise<LocateValidatorResult> {\n debug('verifyLocator', prompt, locateOpt, expectCenter, verifyLocateOption);\n\n const { center: verifyCenter, rect: verifyRect } = await this.aiLocate(\n prompt,\n locateOpt,\n );\n const distance = distanceOfTwoPoints(expectCenter, verifyCenter);\n const included = includedInRect(expectCenter, verifyRect);\n const pass =\n distance <= (verifyLocateOption?.centerDistanceThreshold || 20) ||\n included;\n const verifyResult = {\n pass,\n rect: verifyRect,\n center: verifyCenter,\n centerDistance: distance,\n };\n debug('aiDescribe verifyResult', verifyResult);\n return verifyResult;\n }\n\n /**\n * Locate an element and return both its center point and an approximate rect.\n *\n * - In most locate flows, `rect` represents the matched element boundary.\n * - Some models only support point grounding instead of boundary grounding.\n * In those cases (for example, AutoGLM), `rect` falls back to a small 8x8\n * box centered on the located point.\n *\n * Because `rect` may vary with the underlying model capability, avoid relying\n * on it too heavily for strict boundary semantics. If you need a stable click\n * target, prefer `center`.\n */\n async aiLocate(prompt: TUserPrompt, opt?: LocateOption) {\n const locateParam = buildDetailedLocateParam(prompt, opt);\n assert(locateParam, 'cannot get locate param for aiLocate');\n const locatePlan = locatePlanForLocate(locateParam);\n const plans = [locatePlan];\n const defaultIntentModelConfig =\n this.modelConfigManager.getModelConfig('default');\n const modelConfigForPlanning =\n this.modelConfigManager.getModelConfig('planning');\n\n const { output } = await this.taskExecutor.runPlans(\n taskTitleStr('Locate', locateParamStr(locateParam)),\n plans,\n modelConfigForPlanning,\n defaultIntentModelConfig,\n );\n\n const { element } = output;\n\n return {\n rect: element?.rect,\n center: element?.center,\n dpr: element?.dpr,\n } as Pick<LocateResultElement, 'rect' | 'center'>;\n }\n\n async aiAssert(\n assertion: TUserPrompt,\n msg?: string,\n opt?: AgentAssertOpt & ServiceExtractOption,\n ) {\n const modelConfig = this.modelConfigManager.getModelConfig('insight');\n\n const serviceOpt: ServiceExtractOption = {\n domIncluded: opt?.domIncluded ?? defaultServiceExtractOption.domIncluded,\n screenshotIncluded:\n opt?.screenshotIncluded ??\n defaultServiceExtractOption.screenshotIncluded,\n };\n\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n const assertionText =\n typeof assertion === 'string' ? assertion : assertion.prompt;\n\n try {\n const { output, thought } =\n await this.taskExecutor.createTypeQueryExecution<boolean>(\n 'Assert',\n textPrompt,\n modelConfig,\n serviceOpt,\n multimodalPrompt,\n );\n\n const pass = Boolean(output);\n const message = pass\n ? undefined\n : `Assertion failed: ${msg || assertionText}\\nReason: ${thought || '(no_reason)'}`;\n\n if (opt?.keepRawResponse) {\n return {\n pass,\n thought,\n message,\n };\n }\n\n if (!pass) {\n throw new Error(message);\n }\n } catch (error) {\n if (error instanceof TaskExecutionError) {\n const errorTask = error.errorTask;\n const thought = errorTask?.thought;\n const rawError = errorTask?.error;\n const rawMessage =\n errorTask?.errorMessage ||\n (rawError instanceof Error\n ? rawError.message\n : rawError\n ? String(rawError)\n : undefined);\n const reason = thought || rawMessage || '(no_reason)';\n const message = `Assertion failed: ${msg || assertionText}\\nReason: ${reason}`;\n\n if (opt?.keepRawResponse) {\n return {\n pass: false,\n thought,\n message,\n };\n }\n\n throw new Error(message, {\n cause: rawError ?? error,\n });\n }\n\n throw error;\n }\n }\n\n async aiWaitFor(assertion: TUserPrompt, opt?: AgentWaitForOpt) {\n const modelConfig = this.modelConfigManager.getModelConfig('insight');\n await this.taskExecutor.waitFor(\n assertion,\n {\n ...opt,\n timeoutMs: opt?.timeoutMs || 15 * 1000,\n checkIntervalMs: opt?.checkIntervalMs || 3 * 1000,\n },\n modelConfig,\n );\n }\n\n async ai(...args: Parameters<typeof this.aiAct>) {\n return this.aiAct(...args);\n }\n\n async runYaml(yamlScriptContent: string): Promise<{\n result: Record<string, any>;\n }> {\n const script = parseYamlScript(yamlScriptContent, 'yaml');\n const player = new ScriptPlayer(script, async () => {\n return { agent: this, freeFn: [] };\n });\n await player.run();\n\n if (player.status === 'error') {\n const errors = player.taskStatusList\n .filter((task) => task.status === 'error')\n .map((task) => {\n return `task - ${task.name}: ${task.error?.message}`;\n })\n .join('\\n');\n throw new Error(`Error(s) occurred in running yaml script:\\n${errors}`);\n }\n\n return {\n result: player.result,\n };\n }\n\n async evaluateJavaScript(script: string) {\n assert(\n this.interface.evaluateJavaScript,\n 'evaluateJavaScript is not supported in current agent',\n );\n return this.interface.evaluateJavaScript(script);\n }\n\n /**\n * Add a dump update listener\n * @param listener Listener function\n * @returns A remove function that can be called to remove this listener\n */\n addDumpUpdateListener(\n listener: (dump: string, executionDump?: ExecutionDump) => void,\n ): () => void {\n this.dumpUpdateListeners.push(listener);\n\n // Return remove function\n return () => {\n this.removeDumpUpdateListener(listener);\n };\n }\n\n /**\n * Remove a dump update listener\n * @param listener The listener function to remove\n */\n removeDumpUpdateListener(\n listener: (dump: string, executionDump?: ExecutionDump) => void,\n ): void {\n const index = this.dumpUpdateListeners.indexOf(listener);\n if (index > -1) {\n this.dumpUpdateListeners.splice(index, 1);\n }\n }\n\n /**\n * Clear all dump update listeners\n */\n clearDumpUpdateListeners(): void {\n this.dumpUpdateListeners = [];\n }\n\n async destroy() {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n this.destroyed = true;\n let interfaceDestroyError: unknown;\n try {\n await this.interface.destroy?.();\n } catch (error) {\n interfaceDestroyError = error;\n }\n\n // Wait for all queued write operations to complete\n await this.reportGenerator.flush();\n\n const finalPath = await this.reportGenerator.finalize();\n this.reportFile = finalPath;\n\n this.resetDump(); // reset dump to release memory\n\n if (interfaceDestroyError) {\n throw interfaceDestroyError;\n }\n }\n\n async recordToReport(\n title?: string,\n opt?: {\n content?: string;\n screenshotBase64?: string;\n },\n ) {\n // 1. screenshot\n const base64 =\n opt?.screenshotBase64 ?? (await this.interface.screenshotBase64());\n const now = Date.now();\n const screenshot = ScreenshotItem.create(base64, now);\n // 2. build recorder\n const recorder: ExecutionRecorderItem[] = [\n {\n type: 'screenshot',\n ts: now,\n screenshot,\n },\n ];\n // 3. build ExecutionTaskLog\n const task: ExecutionTaskLog = {\n taskId: uuid(),\n type: 'Log',\n subType: 'Screenshot',\n status: 'finished',\n recorder,\n timing: {\n start: now,\n end: now,\n cost: 0,\n },\n param: {\n content: opt?.content || '',\n },\n executor: async () => {},\n };\n // 4. build ExecutionDump\n const executionDump = new ExecutionDump({\n id: uuid(),\n logTime: now,\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n });\n // 5. append to execution dump\n this.appendExecutionDump(executionDump);\n\n this.writeOutActionDumps(executionDump);\n await this.reportGenerator.flush();\n\n // Call all registered dump update listeners\n const dumpString = this.dumpDataString();\n for (const listener of this.dumpUpdateListeners) {\n try {\n listener(dumpString);\n } catch (error) {\n console.error('Error in onDumpUpdate listener', error);\n }\n }\n }\n\n /**\n * @deprecated Use {@link Agent.recordToReport} instead.\n */\n async logScreenshot(\n title?: string,\n opt?: {\n content: string;\n },\n ) {\n await this.recordToReport(title, opt);\n }\n\n _unstableLogContent() {\n const { groupName, groupDescription, executions } = this.dump;\n return {\n groupName,\n groupDescription,\n executions: executions || [],\n };\n }\n\n /**\n * Freezes the current page context to be reused in subsequent AI operations\n * This avoids recalculating page context for each operation\n */\n async freezePageContext(): Promise<void> {\n debug('Freezing page context');\n const context = await this._snapshotContext();\n // Mark the context as frozen\n context._isFrozen = true;\n this.frozenUIContext = context;\n debug('Page context frozen successfully');\n }\n\n /**\n * Unfreezes the page context, allowing AI operations to calculate context dynamically\n */\n async unfreezePageContext(): Promise<void> {\n debug('Unfreezing page context');\n this.frozenUIContext = undefined;\n debug('Page context unfrozen successfully');\n }\n\n /**\n * Process cache configuration and return normalized cache settings\n */\n private processCacheConfig(opts: AgentOpt): {\n id: string;\n enabled: boolean;\n readOnly: boolean;\n writeOnly: boolean;\n cacheDir?: string;\n } | null {\n validateAgentCacheInput(opts.cache);\n\n // Use the unified utils function to process cache configuration\n const cacheConfig = processCacheConfig(\n opts.cache,\n opts.cacheId || 'default',\n );\n\n if (!cacheConfig) {\n return null;\n }\n\n // Handle cache configuration object\n if (typeof cacheConfig === 'object' && cacheConfig !== null) {\n const id = cacheConfig.id;\n const strategyValue = cacheConfig.strategy ?? 'read-write';\n const isReadOnly = strategyValue === 'read-only';\n const isWriteOnly = strategyValue === 'write-only';\n\n return {\n id,\n enabled: !isWriteOnly,\n readOnly: isReadOnly,\n writeOnly: isWriteOnly,\n cacheDir: cacheConfig.cacheDir?.trim(),\n };\n }\n\n return null;\n }\n\n private normalizeFilePaths(files: string[]): string[] {\n if (ifInBrowser) {\n throw new Error('File chooser is not supported in browser environment');\n }\n\n return files.map((file) => {\n const absolutePath = resolve(file);\n if (!existsSync(absolutePath)) {\n throw new Error(\n `File not found: ${file}. Resolved to: ${absolutePath}. Current working directory: ${process.cwd()}`,\n );\n }\n return absolutePath;\n });\n }\n\n private normalizeFileInput(files: string | string[]): string[] {\n const filesArray = Array.isArray(files) ? files : [files];\n return this.normalizeFilePaths(filesArray);\n }\n\n /**\n * Manually flush cache to file\n * @param options - Optional configuration\n * @param options.cleanUnused - If true, removes unused cache records before flushing\n */\n async flushCache(options?: { cleanUnused?: boolean }): Promise<void> {\n if (!this.taskCache) {\n throw new Error('Cache is not configured');\n }\n\n this.taskCache.flushCacheToFile(options);\n }\n}\n\nexport const createAgent = (\n interfaceInstance: AbstractInterface,\n opts?: AgentOpt,\n) => {\n return new Agent(interfaceInstance, opts);\n};\n"],"names":["debug","getDebug","distanceOfTwoPoints","p1","p2","x1","y1","x2","y2","Math","includedInRect","point","rect","x","y","left","top","width","height","defaultServiceExtractOption","legacyScrollTypeMap","normalizeScrollType","scrollType","defaultReplanningCycleLimit","defaultVlmUiTarsReplanningCycleLimit","defaultAutoGlmReplanningCycleLimit","Agent","callback","modelConfigForPlanning","undefined","isUITars","isAutoGLM","_error","action","modelFamily","maxRetries","attempt","commonContextParser","error","Promise","resolve","setTimeout","prompt","console","ReportActionDump","getVersion","WeakMap","execution","runner","currentDump","existingIndex","opt","ifInBrowser","reportHTMLContent","executionDump","exec","task","param","paramStr","tip","typeStr","name","type","actionPlan","plans","Boolean","title","taskTitleStr","locateParamStr","defaultIntentModelConfig","output","locatePrompt","assert","detailedLocateParam","buildDetailedLocateParam","fileChooserAccept","withFileChooser","locatePromptOrValue","locatePromptOrOpt","optOrUndefined","value","optWithValue","stringValue","String","mode","locatePromptOrKeyName","keyName","locatePromptOrScrollParam","scrollParam","isLocatePromptLike","normalizedScrollType","taskPrompt","abortSignal","Error","runAiAct","deepThink","deepLocate","noIndividualLocateModel","includeBboxInPlanning","cacheable","replanningCycleLimit","isVlmUiTars","isAutoGlm","matchedCache","yaml","imagesIncludeCount","actionOutput","yamlContent","yamlFlowStr","demand","modelConfig","textPrompt","multimodalPrompt","parsePrompt","center","verifyPrompt","retryLimit","success","retryCount","resultPrompt","verifyResult","text","locateOpt","expectCenter","verifyLocateOption","verifyCenter","verifyRect","distance","included","pass","locateParam","locatePlan","locatePlanForLocate","element","assertion","msg","serviceOpt","assertionText","thought","message","TaskExecutionError","errorTask","rawError","rawMessage","reason","args","yamlScriptContent","script","parseYamlScript","player","ScriptPlayer","errors","listener","index","interfaceDestroyError","finalPath","base64","now","Date","screenshot","ScreenshotItem","recorder","uuid","ExecutionDump","dumpString","groupName","groupDescription","executions","context","opts","validateAgentCacheInput","cacheConfig","processCacheConfig","id","strategyValue","isReadOnly","isWriteOnly","files","file","absolutePath","existsSync","process","filesArray","Array","options","interfaceInstance","envReplanningCycleLimit","globalConfigManager","MIDSCENE_REPLANNING_CYCLE_LIMIT","Object","Number","assertReportGenerationOptions","resolvedAiActContext","hasCustomConfig","ModelConfigManager","globalModelConfigManager","Service","cacheConfigObj","TaskCache","baseActionSpace","defineActionSleep","TaskExecutor","getReportFileName","ReportGenerator","createAgent"],"mappings":"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"}
1
+ {"version":3,"file":"agent/agent.mjs","sources":["../../../src/agent/agent.ts"],"sourcesContent":["import { type ModelRuntime, getModelRuntime } from '@/ai-model/models';\nimport yaml from 'js-yaml';\nimport type { TUserPrompt } from '../ai-model/index';\nimport { ScreenshotItem } from '../screenshot-item';\nimport Service from '../service/index';\n// Import types and values directly from their source files to avoid circular dependency\n// DO NOT import from '../index' as it creates a circular dependency:\n// index.ts -> agent/index.ts -> agent/agent.ts -> index.ts\nimport {\n type ActionParam,\n type ActionReturn,\n type AgentAssertOpt,\n type AgentDescribeElementAtPointResult,\n type AgentOpt,\n type AgentWaitForOpt,\n type DeepThinkOption,\n type DeviceAction,\n ExecutionDump,\n type ExecutionRecorderItem,\n type ExecutionTask,\n type ExecutionTaskLog,\n type LocateOption,\n type LocateResultElement,\n type LocateValidatorResult,\n type LocatorValidatorOption,\n type OnTaskStartTip,\n type PlanningAction,\n type Rect,\n ReportActionDump,\n type ReportMeta,\n type ScrollParam,\n type ServiceAction,\n type ServiceExtractOption,\n type ServiceExtractParam,\n type TestStatus,\n type UIContext,\n} from '../types';\nimport type { MidsceneYamlScript } from '../yaml';\n\nimport type { IReportGenerator } from '@/report-generator';\nimport {\n ReportGenerator,\n assertReportGenerationOptions,\n} from '@/report-generator';\nimport { getVersion, processCacheConfig, reportHTMLContent } from '@/utils';\nimport {\n ScriptPlayer,\n buildDetailedLocateParam,\n parseYamlScript,\n} from '../yaml/index';\n\nimport { existsSync } from 'node:fs';\nimport { resolve } from 'node:path';\nimport type { AbstractInterface } from '@/device';\nimport type { TaskRunner } from '@/task-runner';\nimport {\n type IModelConfig,\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n ModelConfigManager,\n type TIntent,\n globalConfigManager,\n globalModelConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { assert, ifInBrowser, uuid } from '@midscene/shared/utils';\nimport { defineActionSleep } from '../device';\nimport { validateAgentCacheInput } from './cache-config';\nimport { TaskCache } from './task-cache';\nimport {\n TaskExecutionError,\n TaskExecutor,\n locatePlanForLocate,\n withFileChooser,\n} from './tasks';\nimport { locateParamStr, paramStr, taskTitleStr, typeStr } from './ui-utils';\nimport { commonContextParser, getReportFileName, parsePrompt } from './utils';\n\nconst debug = getDebug('agent');\n\nconst distanceOfTwoPoints = (p1: [number, number], p2: [number, number]) => {\n const [x1, y1] = p1;\n const [x2, y2] = p2;\n return Math.round(Math.sqrt((x1 - x2) ** 2 + (y1 - y2) ** 2));\n};\n\nconst includedInRect = (point: [number, number], rect: Rect) => {\n const [x, y] = point;\n const { left, top, width, height } = rect;\n return x >= left && x <= left + width && y >= top && y <= top + height;\n};\n\nconst defaultServiceExtractOption: ServiceExtractOption = {\n domIncluded: false,\n screenshotIncluded: true,\n};\n\nconst legacyScrollTypeMap = {\n once: 'singleAction',\n untilBottom: 'scrollToBottom',\n untilTop: 'scrollToTop',\n untilRight: 'scrollToRight',\n untilLeft: 'scrollToLeft',\n} as const;\n\ntype LegacyScrollType = keyof typeof legacyScrollTypeMap;\n\nconst normalizeScrollType = (\n scrollType: ScrollParam['scrollType'] | LegacyScrollType | undefined,\n): ScrollParam['scrollType'] | undefined => {\n if (!scrollType) {\n return scrollType;\n }\n\n if (scrollType in legacyScrollTypeMap) {\n return legacyScrollTypeMap[scrollType as LegacyScrollType];\n }\n\n return scrollType as ScrollParam['scrollType'];\n};\n\nexport type AiActOptions = {\n cacheable?: boolean;\n fileChooserAccept?: string | string[];\n deepThink?: DeepThinkOption;\n deepLocate?: boolean;\n abortSignal?: AbortSignal;\n};\n\nexport class Agent<\n InterfaceType extends AbstractInterface = AbstractInterface,\n> {\n interface: InterfaceType;\n\n service: Service;\n\n dump: ReportActionDump;\n\n reportFile?: string | null;\n\n reportFileName?: string;\n\n taskExecutor: TaskExecutor;\n\n opts: AgentOpt;\n\n /**\n * If true, the agent will not perform any actions\n */\n dryMode = false;\n\n onTaskStartTip?: OnTaskStartTip;\n\n taskCache?: TaskCache;\n\n private dumpUpdateListeners: Array<\n (dump: string, executionDump?: ExecutionDump) => void\n > = [];\n\n get onDumpUpdate():\n | ((dump: string, executionDump?: ExecutionDump) => void)\n | undefined {\n return this.dumpUpdateListeners[0];\n }\n\n set onDumpUpdate(callback:\n | ((dump: string, executionDump?: ExecutionDump) => void)\n | undefined) {\n // Clear existing listeners\n this.dumpUpdateListeners = [];\n // Add callback to array if provided\n if (callback) {\n this.dumpUpdateListeners.push(callback);\n }\n }\n\n destroyed = false;\n\n modelConfigManager: ModelConfigManager;\n\n /**\n * Frozen page context for consistent AI operations\n */\n private frozenUIContext?: UIContext;\n\n private get aiActContext(): string | undefined {\n return this.opts.aiActContext ?? this.opts.aiActionContext;\n }\n\n private executionDumpIndexByRunner = new WeakMap<TaskRunner, number>();\n\n private fullActionSpace: DeviceAction[];\n\n private reportGenerator: IReportGenerator;\n\n // @deprecated use .interface instead\n get page() {\n return this.interface;\n }\n\n /**\n * Fails fast for non-web interfaces when the model family is missing.\n *\n * Early Midscene web usage allowed running without `modelFamily` and falling\n * back to a default bbox parser. Non-web users do not have that compatibility\n * path, so this check helps surface configuration problems before spending a\n * model call.\n *\n * Web flows validate missing locate model family at workflow boundaries:\n * `Service.locate` throws when aiTap/aiType fallback to the default model for\n * direct locate, and generic planning throws when aiAct asks a planning model\n * to return inline locate coordinates. Those checks are intentionally placed\n * where Midscene knows which model role should provide coordinate parsing.\n */\n private assertModelFamilyForNonWebContext() {\n if (\n this.interface.interfaceType !== 'puppeteer' &&\n this.interface.interfaceType !== 'playwright' &&\n this.interface.interfaceType !== 'static' &&\n this.interface.interfaceType !== 'chrome-extension-proxy' &&\n this.interface.interfaceType !== 'page-over-chrome-extension-bridge'\n ) {\n this.modelConfigManager.throwErrorIfNonVLModel();\n }\n }\n\n private resolveReplanningCycleLimit(planningModel: ModelRuntime): number {\n return (\n this.opts.replanningCycleLimit ??\n globalConfigManager.getEnvConfigValueAsNumber(\n MIDSCENE_REPLANNING_CYCLE_LIMIT,\n ) ??\n planningModel.adapter.planning.defaultReplanningCycleLimit\n );\n }\n\n private resolveModelRuntime(intent: TIntent): ModelRuntime {\n return getModelRuntime(this.modelConfigManager.getModelConfig(intent));\n }\n\n constructor(interfaceInstance: InterfaceType, opts?: AgentOpt) {\n this.interface = interfaceInstance;\n\n this.opts = Object.assign(\n {\n generateReport: true,\n persistExecutionDump: false,\n autoPrintReportMsg: true,\n groupName: 'Midscene Report',\n groupDescription: '',\n },\n opts || {},\n );\n assertReportGenerationOptions(this.opts);\n\n const resolvedAiActContext =\n this.opts.aiActContext ?? this.opts.aiActionContext;\n if (resolvedAiActContext !== undefined) {\n this.opts.aiActContext = resolvedAiActContext;\n this.opts.aiActionContext ??= resolvedAiActContext;\n }\n\n if (\n opts?.modelConfig &&\n (typeof opts?.modelConfig !== 'object' || Array.isArray(opts.modelConfig))\n ) {\n throw new Error(\n `opts.modelConfig must be a plain object map of env keys to values, but got ${typeof opts?.modelConfig}`,\n );\n }\n // Create ModelConfigManager if modelConfig or createOpenAIClient is provided\n // Otherwise, use the global config manager\n const hasCustomConfig = opts?.modelConfig || opts?.createOpenAIClient;\n this.modelConfigManager = hasCustomConfig\n ? new ModelConfigManager(opts?.modelConfig, opts?.createOpenAIClient)\n : globalModelConfigManager;\n\n this.onTaskStartTip = this.opts.onTaskStartTip;\n\n this.service = new Service(async () => {\n return this.getUIContext();\n });\n\n // Process cache configuration\n const cacheConfigObj = this.processCacheConfig(opts || {});\n if (cacheConfigObj) {\n this.taskCache = new TaskCache(\n cacheConfigObj.id,\n cacheConfigObj.enabled,\n undefined, // cacheFilePath\n {\n readOnly: cacheConfigObj.readOnly,\n writeOnly: cacheConfigObj.writeOnly,\n cacheDir: cacheConfigObj.cacheDir,\n },\n );\n }\n\n const baseActionSpace = this.interface.actionSpace();\n this.fullActionSpace = [...baseActionSpace, defineActionSleep()];\n\n this.taskExecutor = new TaskExecutor(this.interface, this.service, {\n taskCache: this.taskCache,\n onTaskStart: this.callbackOnTaskStartTip.bind(this),\n replanningCycleLimit: this.opts.replanningCycleLimit,\n waitAfterAction: this.opts.waitAfterAction,\n useDeviceTime: this.opts.useDeviceTime,\n actionSpace: this.fullActionSpace,\n hooks: {\n onTaskUpdate: async (runner) => {\n const executionDump = runner.dump();\n this.appendExecutionDump(executionDump, runner);\n\n // Persist report updates before notifying listeners so screenshot\n // payloads can be released from memory and serialized as references.\n this.writeOutActionDumps(executionDump);\n await this.reportGenerator.flush();\n\n // Call all registered dump update listeners\n const dumpString = this.dumpDataString();\n for (const listener of this.dumpUpdateListeners) {\n try {\n listener(dumpString, executionDump);\n } catch (error) {\n console.error('Error in onDumpUpdate listener', error);\n }\n }\n },\n },\n });\n this.dump = this.resetDump();\n this.reportFileName =\n opts?.reportFileName ||\n // Keep deprecated testId behavior for generated report names until it is\n // fully removed from the public API.\n getReportFileName(opts?.testId || this.interface.interfaceType || 'web');\n\n this.reportGenerator = ReportGenerator.create(this.reportFileName!, {\n generateReport: this.opts.generateReport,\n persistExecutionDump: this.opts.persistExecutionDump,\n outputFormat: this.opts.outputFormat,\n autoPrintReportMsg: this.opts.autoPrintReportMsg,\n reuseExistingReport:\n this.opts.reportAttributes?.['data-group-id'] === this.reportFileName,\n });\n }\n\n async getActionSpace(): Promise<DeviceAction[]> {\n return this.fullActionSpace;\n }\n\n private static readonly CONTEXT_RETRY_MAX = 3;\n private static readonly CONTEXT_RETRY_DELAY_MS = 1500;\n\n /**\n * Override in subclasses to indicate which errors are transient and should\n * trigger an automatic retry when building the UI context.\n * Returns `false` by default (no retry).\n */\n protected isRetryableContextError(_error: unknown): boolean {\n return false;\n }\n\n async getUIContext(action?: ServiceAction): Promise<UIContext> {\n // Some non-web flows, such as Android, need an Agent instance before they\n // can call device methods via ADB, so defer missing modelFamily errors\n // until UI context is actually requested.\n this.assertModelFamilyForNonWebContext();\n\n // If page context is frozen, return the frozen context for all actions\n if (this.frozenUIContext) {\n debug('Using frozen page context for action:', action);\n return this.frozenUIContext;\n }\n\n const maxRetries = Agent.CONTEXT_RETRY_MAX;\n for (let attempt = 0; ; attempt++) {\n try {\n return await commonContextParser(this.interface, {\n uploadServerUrl: this.modelConfigManager.getUploadTestServerUrl(),\n screenshotShrinkFactor: this.opts.screenshotShrinkFactor,\n });\n } catch (error) {\n if (attempt < maxRetries && this.isRetryableContextError(error)) {\n debug(\n `retryable context error (attempt ${attempt + 1}/${maxRetries}), retrying in ${Agent.CONTEXT_RETRY_DELAY_MS}ms: ${error}`,\n );\n await new Promise((resolve) =>\n setTimeout(resolve, Agent.CONTEXT_RETRY_DELAY_MS),\n );\n continue;\n }\n throw error;\n }\n }\n }\n\n async _snapshotContext(): Promise<UIContext> {\n return await this.getUIContext('locate');\n }\n\n /**\n * @deprecated Use {@link setAIActContext} instead.\n */\n async setAIActionContext(prompt: string) {\n await this.setAIActContext(prompt);\n }\n\n async setAIActContext(prompt: string) {\n if (this.aiActContext) {\n console.warn(\n 'aiActContext is already set, and it is called again, will override the previous setting',\n );\n }\n this.opts.aiActContext = prompt;\n this.opts.aiActionContext = prompt;\n }\n\n resetDump() {\n this.dump = new ReportActionDump({\n sdkVersion: getVersion(),\n groupName: this.opts.groupName!,\n groupDescription: this.opts.groupDescription,\n executions: [],\n modelBriefs: [],\n deviceType: this.interface.interfaceType,\n });\n this.executionDumpIndexByRunner = new WeakMap<TaskRunner, number>();\n\n return this.dump;\n }\n\n appendExecutionDump(execution: ExecutionDump, runner?: TaskRunner) {\n const currentDump = this.dump;\n if (runner) {\n const existingIndex = this.executionDumpIndexByRunner.get(runner);\n if (existingIndex !== undefined) {\n currentDump.executions[existingIndex] = execution;\n return;\n }\n currentDump.executions.push(execution);\n this.executionDumpIndexByRunner.set(\n runner,\n currentDump.executions.length - 1,\n );\n return;\n }\n currentDump.executions.push(execution);\n }\n\n dumpDataString(opt?: { inlineScreenshots?: boolean }) {\n // update dump info\n this.dump.groupName = this.opts.groupName!;\n this.dump.groupDescription = this.opts.groupDescription;\n // In browser environment, use inline screenshots since file system is not available\n if (ifInBrowser || opt?.inlineScreenshots) {\n return this.dump.serializeWithInlineScreenshots();\n }\n return this.dump.serialize();\n }\n\n reportHTMLString(opt?: { inlineScreenshots?: boolean }) {\n // dumpDataString() handles browser environment with inline screenshots\n return reportHTMLContent(this.dumpDataString(opt));\n }\n\n private lastExecutionDump?: ExecutionDump;\n\n writeOutActionDumps(executionDump?: ExecutionDump) {\n const exec = executionDump || this.lastExecutionDump;\n if (exec) {\n this.lastExecutionDump = exec;\n this.reportGenerator.onExecutionUpdate(\n exec,\n this.getReportMeta(),\n this.opts.reportAttributes,\n );\n }\n this.reportFile = this.reportGenerator.getReportPath();\n }\n\n private getReportMeta(): ReportMeta {\n return {\n groupName: this.dump.groupName,\n groupDescription: this.dump.groupDescription,\n sdkVersion: this.dump.sdkVersion,\n modelBriefs: this.dump.modelBriefs,\n deviceType: this.dump.deviceType,\n };\n }\n\n private async callbackOnTaskStartTip(task: ExecutionTask) {\n const param = paramStr(task);\n const tip = param ? `${typeStr(task)} - ${param}` : typeStr(task);\n\n if (this.onTaskStartTip) {\n await this.onTaskStartTip(tip);\n }\n }\n\n wrapActionInActionSpace<T extends DeviceAction>(\n name: string,\n ): (param: ActionParam<T>) => Promise<ActionReturn<T>> {\n return async (param: ActionParam<T>) => {\n return await this.callActionInActionSpace<ActionReturn<T>>(name, param);\n };\n }\n\n async callActionInActionSpace<T = any>(\n type: string,\n opt?: T, // and all other action params\n ) {\n debug('callActionInActionSpace', type, ',', opt);\n\n const actionPlan: PlanningAction<T> = {\n type: type as any,\n param: (opt as any) || {},\n thought: '',\n };\n debug('actionPlan', actionPlan); // , ', in which the locateParam is', locateParam);\n\n const plans: PlanningAction[] = [actionPlan].filter(\n Boolean,\n ) as PlanningAction[];\n\n const title = taskTitleStr(\n type as any,\n locateParamStr((opt as any)?.locate || {}),\n );\n\n // assume all operation in action space is related to locating\n const defaultModel = this.resolveModelRuntime('default');\n const planningModel = this.resolveModelRuntime('planning');\n\n const { output } = await this.taskExecutor.runPlans(\n title,\n plans,\n planningModel,\n defaultModel,\n );\n return output;\n }\n\n async aiTap(\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { fileChooserAccept?: string | string[] },\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for tap');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n const fileChooserAccept = opt?.fileChooserAccept\n ? this.normalizeFileInput(opt.fileChooserAccept)\n : undefined;\n\n await withFileChooser(this.interface, fileChooserAccept, async () => {\n await this.callActionInActionSpace('Tap', {\n locate: detailedLocateParam,\n });\n });\n }\n\n async aiRightClick(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for right click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('RightClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiDoubleClick(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for double click');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('DoubleClick', {\n locate: detailedLocateParam,\n });\n }\n\n async aiHover(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for hover');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('Hover', {\n locate: detailedLocateParam,\n });\n }\n\n // New signature, always use locatePrompt as the first param\n async aiInput(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'typeOnly' | 'append' },\n ): Promise<void>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value\n */\n async aiInput(\n value: string | number,\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { autoDismissKeyboard?: boolean } & {\n mode?: 'replace' | 'clear' | 'typeOnly' | 'append';\n }, // AndroidDeviceInputOpt &\n ): Promise<void>;\n\n // Implementation\n async aiInput(\n locatePromptOrValue: TUserPrompt | string | number,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'typeOnly' | 'append' }) // AndroidDeviceInputOpt &\n | undefined,\n optOrUndefined?: LocateOption, // AndroidDeviceInputOpt &\n ) {\n let value: string | number;\n let locatePrompt: TUserPrompt;\n let opt:\n | (LocateOption & { value: string | number } & {\n autoDismissKeyboard?: boolean;\n } & { mode?: 'replace' | 'clear' | 'typeOnly' | 'append' }) // AndroidDeviceInputOpt &\n | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has value)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'value' in locatePromptOrOpt\n ) {\n // New signature: aiInput(locatePrompt, opt)\n locatePrompt = locatePromptOrValue as TUserPrompt;\n const optWithValue = locatePromptOrOpt as LocateOption & {\n // AndroidDeviceInputOpt &\n value: string | number;\n autoDismissKeyboard?: boolean;\n };\n value = optWithValue.value;\n opt = optWithValue;\n } else {\n // Legacy signature: aiInput(value, locatePrompt, opt)\n value = locatePromptOrValue as string | number;\n locatePrompt = locatePromptOrOpt as TUserPrompt;\n opt = {\n ...optOrUndefined,\n value,\n };\n }\n\n assert(\n typeof value === 'string' || typeof value === 'number',\n 'input value must be a string or number, use empty string if you want to clear the input',\n );\n assert(locatePrompt, 'missing locate prompt for input');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n // Convert value to string to ensure consistency\n const stringValue = typeof value === 'number' ? String(value) : value;\n\n // backward compat: convert deprecated 'append' to 'typeOnly'\n const mode = opt?.mode === 'append' ? 'typeOnly' : opt?.mode;\n\n await this.callActionInActionSpace('Input', {\n ...(opt || {}),\n value: stringValue,\n locate: detailedLocateParam,\n mode,\n });\n }\n\n // New signature\n async aiKeyboardPress(\n locatePrompt: TUserPrompt,\n opt: LocateOption & { keyName: string },\n ): Promise<void>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName\n */\n async aiKeyboardPress(\n keyName: string,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void>;\n\n // Implementation\n async aiKeyboardPress(\n locatePromptOrKeyName: TUserPrompt | string,\n locatePromptOrOpt:\n | TUserPrompt\n | (LocateOption & { keyName: string })\n | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let keyName: string;\n let locatePrompt: TUserPrompt | undefined;\n let opt: (LocateOption & { keyName: string }) | undefined;\n\n // Check if using new signature (first param is locatePrompt, second has keyName)\n if (\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null &&\n 'keyName' in locatePromptOrOpt\n ) {\n // New signature: aiKeyboardPress(locatePrompt, opt)\n locatePrompt = locatePromptOrKeyName as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & {\n keyName: string;\n };\n } else {\n // Legacy signature: aiKeyboardPress(keyName, locatePrompt, opt)\n keyName = locatePromptOrKeyName as string;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n keyName,\n };\n }\n\n assert(opt?.keyName, 'missing keyName for keyboard press');\n\n const detailedLocateParam = locatePrompt\n ? buildDetailedLocateParam(locatePrompt, opt)\n : undefined;\n\n await this.callActionInActionSpace('KeyboardPress', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n // New signature\n async aiScroll(\n locatePrompt: TUserPrompt | undefined,\n opt: LocateOption & ScrollParam,\n ): Promise<void>;\n\n // Legacy signature - deprecated\n /**\n * @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters\n */\n async aiScroll(\n scrollParam: ScrollParam,\n locatePrompt?: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void>;\n\n // Implementation\n async aiScroll(\n locatePromptOrScrollParam: TUserPrompt | ScrollParam | undefined,\n locatePromptOrOpt: TUserPrompt | (LocateOption & ScrollParam) | undefined,\n optOrUndefined?: LocateOption,\n ) {\n let scrollParam: ScrollParam;\n let locatePrompt: TUserPrompt | undefined;\n let opt: LocateOption | undefined;\n\n const isLocatePromptLike = (value: unknown): value is TUserPrompt => {\n if (\n typeof value === 'string' ||\n typeof value === 'undefined' ||\n value === null\n ) {\n return true;\n }\n\n return typeof value === 'object' && value !== null && 'prompt' in value;\n };\n\n // Check if using new signature (first param is locatePrompt, second is options)\n if (\n isLocatePromptLike(locatePromptOrScrollParam) &&\n typeof locatePromptOrOpt === 'object' &&\n locatePromptOrOpt !== null\n ) {\n // New signature: aiScroll(locatePrompt, opt)\n locatePrompt = locatePromptOrScrollParam as TUserPrompt;\n opt = locatePromptOrOpt as LocateOption & ScrollParam;\n } else {\n // Legacy signature: aiScroll(scrollParam, locatePrompt, opt)\n scrollParam = locatePromptOrScrollParam as ScrollParam;\n locatePrompt = locatePromptOrOpt as TUserPrompt | undefined;\n opt = {\n ...(optOrUndefined || {}),\n ...(scrollParam || {}),\n };\n }\n\n if (opt) {\n const normalizedScrollType = normalizeScrollType(\n (opt as ScrollParam).scrollType as\n | ScrollParam['scrollType']\n | LegacyScrollType\n | undefined,\n );\n\n if (normalizedScrollType !== (opt as ScrollParam).scrollType) {\n (opt as ScrollParam) = {\n ...(opt || {}),\n scrollType: normalizedScrollType as ScrollParam['scrollType'],\n };\n }\n }\n\n const detailedLocateParam = buildDetailedLocateParam(\n locatePrompt || '',\n opt,\n );\n\n await this.callActionInActionSpace('Scroll', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n async aiPinch(\n locatePrompt: TUserPrompt | undefined,\n opt: LocateOption & {\n direction: 'in' | 'out';\n distance?: number;\n duration?: number;\n },\n ): Promise<void> {\n const detailedLocateParam = buildDetailedLocateParam(\n locatePrompt || '',\n opt,\n );\n\n await this.callActionInActionSpace('Pinch', {\n ...opt,\n locate: detailedLocateParam,\n });\n }\n\n async aiLongPress(\n locatePrompt: TUserPrompt,\n opt?: LocateOption & { duration?: number },\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for long press');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('LongPress', {\n ...(opt || {}),\n locate: detailedLocateParam,\n });\n }\n\n async aiClearInput(\n locatePrompt: TUserPrompt,\n opt?: LocateOption,\n ): Promise<void> {\n assert(locatePrompt, 'missing locate prompt for clear input');\n\n const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);\n\n await this.callActionInActionSpace('ClearInput', {\n locate: detailedLocateParam,\n });\n }\n\n async aiAct(\n taskPrompt: string,\n opt?: AiActOptions,\n ): Promise<string | undefined> {\n const fileChooserAccept = opt?.fileChooserAccept\n ? this.normalizeFileInput(opt.fileChooserAccept)\n : undefined;\n\n const abortSignal = opt?.abortSignal;\n if (abortSignal?.aborted) {\n throw new Error(\n `aiAct aborted: ${abortSignal.reason || 'signal already aborted'}`,\n );\n }\n\n const runAiAct = async () => {\n const planningModel = this.resolveModelRuntime('planning');\n const defaultModel = this.resolveModelRuntime('default');\n // Controls the aiAct planning mode, such as sub-goal prompts and locate result strategy.\n const deepThink = opt?.deepThink === true;\n\n const deepLocate = opt?.deepLocate;\n\n const noIndividualLocateModel = planningModel.config.slot === 'default';\n\n const includeLocateInPlanning = !deepThink && noIndividualLocateModel;\n\n debug('setting includeLocateInPlanning to', includeLocateInPlanning, {\n deepThink,\n noIndividualLocateModel,\n });\n\n const cacheable = opt?.cacheable;\n const replanningCycleLimit =\n this.resolveReplanningCycleLimit(planningModel);\n const planCacheEnabled = planningModel.adapter.planning.cacheEnabled;\n const matchedCache =\n !planCacheEnabled || cacheable === false\n ? undefined\n : this.taskCache?.matchPlanCache(taskPrompt);\n if (\n matchedCache?.cacheUsable &&\n this.taskCache?.isCacheResultUsed &&\n matchedCache.cacheContent?.yamlWorkflow?.trim()\n ) {\n // log into report file\n await this.taskExecutor.loadYamlFlowAsPlanning(\n taskPrompt,\n matchedCache.cacheContent.yamlWorkflow,\n );\n\n debug('matched cache, will call .runYaml to run the action');\n const yaml = matchedCache.cacheContent.yamlWorkflow;\n await this.runYaml(yaml);\n return;\n }\n\n // If cache matched but is not executable, fall through to normal execution\n const imagesIncludeCount: number = deepThink ? 2 : 1;\n const { output: actionOutput } = await this.taskExecutor.action(\n taskPrompt,\n planningModel,\n defaultModel,\n includeLocateInPlanning,\n this.aiActContext,\n cacheable,\n replanningCycleLimit,\n imagesIncludeCount,\n deepThink,\n fileChooserAccept,\n deepLocate,\n abortSignal,\n );\n\n // update cache\n if (\n this.taskCache &&\n actionOutput?.yamlFlow?.length &&\n cacheable !== false\n ) {\n const yamlContent: MidsceneYamlScript = {\n tasks: [\n {\n name: taskPrompt,\n flow: actionOutput.yamlFlow,\n },\n ],\n };\n const yamlFlowStr = yaml.dump(yamlContent);\n this.taskCache.updateOrAppendCacheRecord(\n {\n type: 'plan',\n prompt: taskPrompt,\n yamlWorkflow: yamlFlowStr,\n },\n matchedCache,\n );\n }\n\n return actionOutput?.output;\n };\n\n return await runAiAct();\n }\n\n /**\n * @deprecated Use {@link Agent.aiAct} instead.\n */\n async aiAction(taskPrompt: string, opt?: AiActOptions) {\n return this.aiAct(taskPrompt, opt);\n }\n\n async aiQuery<ReturnType = any>(\n demand: ServiceExtractParam,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<ReturnType> {\n const modelRuntime = this.resolveModelRuntime('insight');\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'Query',\n demand,\n modelRuntime,\n opt,\n );\n return output as ReturnType;\n }\n\n async aiBoolean(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<boolean> {\n const modelRuntime = this.resolveModelRuntime('insight');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'Boolean',\n textPrompt,\n modelRuntime,\n opt,\n multimodalPrompt,\n );\n return output as boolean;\n }\n\n async aiNumber(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<number> {\n const modelRuntime = this.resolveModelRuntime('insight');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'Number',\n textPrompt,\n modelRuntime,\n opt,\n multimodalPrompt,\n );\n return output as number;\n }\n\n async aiString(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<string> {\n const modelRuntime = this.resolveModelRuntime('insight');\n\n const { textPrompt, multimodalPrompt } = parsePrompt(prompt);\n const { output } = await this.taskExecutor.createTypeQueryExecution(\n 'String',\n textPrompt,\n modelRuntime,\n opt,\n multimodalPrompt,\n );\n return output as string;\n }\n\n async aiAsk(\n prompt: TUserPrompt,\n opt: ServiceExtractOption = defaultServiceExtractOption,\n ): Promise<string> {\n return this.aiString(prompt, opt);\n }\n\n async describeElementAtPoint(\n center: [number, number],\n opt?: {\n verifyPrompt?: boolean;\n retryLimit?: number;\n deepLocate?: boolean;\n } & LocatorValidatorOption,\n ): Promise<AgentDescribeElementAtPointResult> {\n const { verifyPrompt = true, retryLimit = 3 } = opt || {};\n\n let success = false;\n let retryCount = 0;\n let resultPrompt = '';\n let deepLocate = opt?.deepLocate || false;\n let verifyResult: LocateValidatorResult | undefined;\n\n while (!success && retryCount < retryLimit) {\n if (retryCount >= 2) {\n deepLocate = true;\n }\n debug(\n 'aiDescribe',\n center,\n 'verifyPrompt',\n verifyPrompt,\n 'retryCount',\n retryCount,\n 'deepLocate',\n deepLocate,\n );\n // use same intent as aiLocate\n const modelRuntime = this.resolveModelRuntime('insight');\n\n const text = await this.service.describe(center, modelRuntime, {\n deepLocate,\n });\n debug('aiDescribe text', text);\n assert(text.description, `failed to describe element at [${center}]`);\n resultPrompt = text.description;\n\n if (!verifyPrompt) {\n success = true;\n break;\n }\n\n // Don't pass deepLocate to verification locate — the description was generated\n // from a cropped view (deepLocate describe), but verification should use regular\n // locate on the full screenshot to confirm the description works universally.\n // Passing deepLocate here would add another first-pass locate and search-area\n // crop around an already element-level description, which is not the intent of\n // verification.\n verifyResult = await this.verifyLocator(\n resultPrompt,\n undefined,\n center,\n opt,\n );\n if (verifyResult.pass) {\n success = true;\n } else {\n retryCount++;\n }\n }\n\n return {\n prompt: resultPrompt,\n deepLocate,\n verifyResult,\n };\n }\n\n async verifyLocator(\n prompt: string,\n locateOpt: LocateOption | undefined,\n expectCenter: [number, number],\n verifyLocateOption?: LocatorValidatorOption,\n ): Promise<LocateValidatorResult> {\n debug('verifyLocator', prompt, locateOpt, expectCenter, verifyLocateOption);\n\n const { center: verifyCenter, rect: verifyRect } = await this.aiLocate(\n prompt,\n locateOpt,\n );\n const distance = distanceOfTwoPoints(expectCenter, verifyCenter);\n const included = includedInRect(expectCenter, verifyRect);\n const pass =\n distance <= (verifyLocateOption?.centerDistanceThreshold || 20) ||\n included;\n const verifyResult = {\n pass,\n rect: verifyRect,\n center: verifyCenter,\n centerDistance: distance,\n };\n debug('aiDescribe verifyResult', verifyResult);\n return verifyResult;\n }\n\n /**\n * Locate an element and return both its center point and an approximate rect.\n *\n * - In most locate flows, `rect` represents the matched element boundary.\n * - Some models only support point grounding instead of boundary grounding.\n * In those cases (for example, AutoGLM), `rect` falls back to a small 8x8\n * box centered on the located point.\n *\n * Because `rect` may vary with the underlying model capability, avoid relying\n * on it too heavily for strict boundary semantics. If you need a stable click\n * target, prefer `center`.\n */\n async aiLocate(prompt: TUserPrompt, opt?: LocateOption) {\n const locateParam = buildDetailedLocateParam(prompt, opt);\n assert(locateParam, 'cannot get locate param for aiLocate');\n const locatePlan = locatePlanForLocate(locateParam);\n const plans = [locatePlan];\n const defaultModel = this.resolveModelRuntime('default');\n const planningModel = this.resolveModelRuntime('planning');\n\n const { output } = await this.taskExecutor.runPlans(\n taskTitleStr('Locate', locateParamStr(locateParam)),\n plans,\n planningModel,\n defaultModel,\n );\n\n const { element } = output;\n\n return {\n rect: element?.rect,\n center: element?.center,\n dpr: element?.dpr,\n } as Pick<LocateResultElement, 'rect' | 'center'>;\n }\n\n async aiAssert(\n assertion: TUserPrompt,\n msg?: string,\n opt?: AgentAssertOpt & ServiceExtractOption,\n ) {\n const modelRuntime = this.resolveModelRuntime('insight');\n\n const serviceOpt: ServiceExtractOption = {\n domIncluded: opt?.domIncluded ?? defaultServiceExtractOption.domIncluded,\n screenshotIncluded:\n opt?.screenshotIncluded ??\n defaultServiceExtractOption.screenshotIncluded,\n };\n\n const { textPrompt, multimodalPrompt } = parsePrompt(assertion);\n const assertionText =\n typeof assertion === 'string' ? assertion : assertion.prompt;\n\n try {\n const { output, thought } =\n await this.taskExecutor.createTypeQueryExecution<boolean>(\n 'Assert',\n textPrompt,\n modelRuntime,\n serviceOpt,\n multimodalPrompt,\n );\n\n const pass = Boolean(output);\n const message = pass\n ? undefined\n : `Assertion failed: ${msg || assertionText}\\nReason: ${thought || '(no_reason)'}`;\n\n if (opt?.keepRawResponse) {\n return {\n pass,\n thought,\n message,\n };\n }\n\n if (!pass) {\n throw new Error(message);\n }\n } catch (error) {\n if (error instanceof TaskExecutionError) {\n const errorTask = error.errorTask;\n const thought = errorTask?.thought;\n const rawError = errorTask?.error;\n const rawMessage =\n errorTask?.errorMessage ||\n (rawError instanceof Error\n ? rawError.message\n : rawError\n ? String(rawError)\n : undefined);\n const reason = thought || rawMessage || '(no_reason)';\n const message = `Assertion failed: ${msg || assertionText}\\nReason: ${reason}`;\n\n if (opt?.keepRawResponse) {\n return {\n pass: false,\n thought,\n message,\n };\n }\n\n throw new Error(message, {\n cause: rawError ?? error,\n });\n }\n\n throw error;\n }\n }\n\n async aiWaitFor(assertion: TUserPrompt, opt?: AgentWaitForOpt) {\n const modelRuntime = this.resolveModelRuntime('insight');\n await this.taskExecutor.waitFor(\n assertion,\n {\n ...opt,\n timeoutMs: opt?.timeoutMs || 15 * 1000,\n checkIntervalMs: opt?.checkIntervalMs || 3 * 1000,\n },\n modelRuntime,\n );\n }\n\n async ai(...args: Parameters<typeof this.aiAct>) {\n return this.aiAct(...args);\n }\n\n async runYaml(yamlScriptContent: string): Promise<{\n result: Record<string, any>;\n }> {\n const script = parseYamlScript(yamlScriptContent, 'yaml');\n const player = new ScriptPlayer(script, async () => {\n return { agent: this, freeFn: [] };\n });\n await player.run();\n\n if (player.status === 'error') {\n const errors = player.taskStatusList\n .filter((task) => task.status === 'error')\n .map((task) => {\n return `task - ${task.name}: ${task.error?.message}`;\n })\n .join('\\n');\n throw new Error(`Error(s) occurred in running yaml script:\\n${errors}`);\n }\n\n return {\n result: player.result,\n };\n }\n\n async evaluateJavaScript(script: string) {\n assert(\n this.interface.evaluateJavaScript,\n 'evaluateJavaScript is not supported in current agent',\n );\n return this.interface.evaluateJavaScript(script);\n }\n\n /**\n * Add a dump update listener\n * @param listener Listener function\n * @returns A remove function that can be called to remove this listener\n */\n addDumpUpdateListener(\n listener: (dump: string, executionDump?: ExecutionDump) => void,\n ): () => void {\n this.dumpUpdateListeners.push(listener);\n\n // Return remove function\n return () => {\n this.removeDumpUpdateListener(listener);\n };\n }\n\n /**\n * Remove a dump update listener\n * @param listener The listener function to remove\n */\n removeDumpUpdateListener(\n listener: (dump: string, executionDump?: ExecutionDump) => void,\n ): void {\n const index = this.dumpUpdateListeners.indexOf(listener);\n if (index > -1) {\n this.dumpUpdateListeners.splice(index, 1);\n }\n }\n\n /**\n * Clear all dump update listeners\n */\n clearDumpUpdateListeners(): void {\n this.dumpUpdateListeners = [];\n }\n\n async destroy() {\n // Early return if already destroyed\n if (this.destroyed) {\n return;\n }\n\n this.destroyed = true;\n let interfaceDestroyError: unknown;\n try {\n await this.interface.destroy?.();\n } catch (error) {\n interfaceDestroyError = error;\n }\n\n // Wait for all queued write operations to complete\n await this.reportGenerator.flush();\n\n const finalPath = await this.reportGenerator.finalize();\n this.reportFile = finalPath;\n\n this.resetDump(); // reset dump to release memory\n\n if (interfaceDestroyError) {\n throw interfaceDestroyError;\n }\n }\n\n async recordToReport(\n title?: string,\n opt?: {\n content?: string;\n screenshotBase64?: string;\n },\n ) {\n // 1. screenshot\n const base64 =\n opt?.screenshotBase64 ?? (await this.interface.screenshotBase64());\n const now = Date.now();\n const screenshot = ScreenshotItem.create(base64, now);\n // 2. build recorder\n const recorder: ExecutionRecorderItem[] = [\n {\n type: 'screenshot',\n ts: now,\n screenshot,\n },\n ];\n // 3. build ExecutionTaskLog\n const task: ExecutionTaskLog = {\n taskId: uuid(),\n type: 'Log',\n subType: 'Screenshot',\n status: 'finished',\n recorder,\n timing: {\n start: now,\n end: now,\n cost: 0,\n },\n param: {\n content: opt?.content || '',\n },\n executor: async () => {},\n };\n // 4. build ExecutionDump\n const executionDump = new ExecutionDump({\n id: uuid(),\n logTime: now,\n name: `Log - ${title || 'untitled'}`,\n description: opt?.content || '',\n tasks: [task],\n });\n // 5. append to execution dump\n this.appendExecutionDump(executionDump);\n\n this.writeOutActionDumps(executionDump);\n await this.reportGenerator.flush();\n\n // Call all registered dump update listeners\n const dumpString = this.dumpDataString();\n for (const listener of this.dumpUpdateListeners) {\n try {\n listener(dumpString);\n } catch (error) {\n console.error('Error in onDumpUpdate listener', error);\n }\n }\n }\n\n /**\n * @deprecated Use {@link Agent.recordToReport} instead.\n */\n async logScreenshot(\n title?: string,\n opt?: {\n content: string;\n },\n ) {\n await this.recordToReport(title, opt);\n }\n\n _unstableLogContent() {\n const { groupName, groupDescription, executions } = this.dump;\n return {\n groupName,\n groupDescription,\n executions: executions || [],\n };\n }\n\n /**\n * Freezes the current page context to be reused in subsequent AI operations\n * This avoids recalculating page context for each operation\n */\n async freezePageContext(): Promise<void> {\n debug('Freezing page context');\n const context = await this._snapshotContext();\n // Mark the context as frozen\n context._isFrozen = true;\n this.frozenUIContext = context;\n debug('Page context frozen successfully');\n }\n\n /**\n * Unfreezes the page context, allowing AI operations to calculate context dynamically\n */\n async unfreezePageContext(): Promise<void> {\n debug('Unfreezing page context');\n this.frozenUIContext = undefined;\n debug('Page context unfrozen successfully');\n }\n\n /**\n * Process cache configuration and return normalized cache settings\n */\n private processCacheConfig(opts: AgentOpt): {\n id: string;\n enabled: boolean;\n readOnly: boolean;\n writeOnly: boolean;\n cacheDir?: string;\n } | null {\n validateAgentCacheInput(opts.cache);\n\n // Use the unified utils function to process cache configuration\n const cacheConfig = processCacheConfig(\n opts.cache,\n opts.cacheId || 'default',\n );\n\n if (!cacheConfig) {\n return null;\n }\n\n // Handle cache configuration object\n if (typeof cacheConfig === 'object' && cacheConfig !== null) {\n const id = cacheConfig.id;\n const strategyValue = cacheConfig.strategy ?? 'read-write';\n const isReadOnly = strategyValue === 'read-only';\n const isWriteOnly = strategyValue === 'write-only';\n\n return {\n id,\n enabled: !isWriteOnly,\n readOnly: isReadOnly,\n writeOnly: isWriteOnly,\n cacheDir: cacheConfig.cacheDir?.trim(),\n };\n }\n\n return null;\n }\n\n private normalizeFilePaths(files: string[]): string[] {\n if (ifInBrowser) {\n throw new Error('File chooser is not supported in browser environment');\n }\n\n return files.map((file) => {\n const absolutePath = resolve(file);\n if (!existsSync(absolutePath)) {\n throw new Error(\n `File not found: ${file}. Resolved to: ${absolutePath}. Current working directory: ${process.cwd()}`,\n );\n }\n return absolutePath;\n });\n }\n\n private normalizeFileInput(files: string | string[]): string[] {\n const filesArray = Array.isArray(files) ? files : [files];\n return this.normalizeFilePaths(filesArray);\n }\n\n /**\n * Manually flush cache to file\n * @param options - Optional configuration\n * @param options.cleanUnused - If true, removes unused cache records before flushing\n */\n async flushCache(options?: { cleanUnused?: boolean }): Promise<void> {\n if (!this.taskCache) {\n throw new Error('Cache is not configured');\n }\n\n this.taskCache.flushCacheToFile(options);\n }\n}\n\nexport const createAgent = (\n interfaceInstance: AbstractInterface,\n opts?: AgentOpt,\n) => {\n return new Agent(interfaceInstance, opts);\n};\n"],"names":["debug","getDebug","distanceOfTwoPoints","p1","p2","x1","y1","x2","y2","Math","includedInRect","point","rect","x","y","left","top","width","height","defaultServiceExtractOption","legacyScrollTypeMap","normalizeScrollType","scrollType","Agent","callback","planningModel","globalConfigManager","MIDSCENE_REPLANNING_CYCLE_LIMIT","intent","getModelRuntime","_error","action","maxRetries","attempt","commonContextParser","error","Promise","resolve","setTimeout","prompt","console","ReportActionDump","getVersion","WeakMap","execution","runner","currentDump","existingIndex","undefined","opt","ifInBrowser","reportHTMLContent","executionDump","exec","task","param","paramStr","tip","typeStr","name","type","actionPlan","plans","Boolean","title","taskTitleStr","locateParamStr","defaultModel","output","locatePrompt","assert","detailedLocateParam","buildDetailedLocateParam","fileChooserAccept","withFileChooser","locatePromptOrValue","locatePromptOrOpt","optOrUndefined","value","optWithValue","stringValue","String","mode","locatePromptOrKeyName","keyName","locatePromptOrScrollParam","scrollParam","isLocatePromptLike","normalizedScrollType","taskPrompt","abortSignal","Error","runAiAct","deepThink","deepLocate","noIndividualLocateModel","includeLocateInPlanning","cacheable","replanningCycleLimit","planCacheEnabled","matchedCache","yaml","imagesIncludeCount","actionOutput","yamlContent","yamlFlowStr","demand","modelRuntime","textPrompt","multimodalPrompt","parsePrompt","center","verifyPrompt","retryLimit","success","retryCount","resultPrompt","verifyResult","text","locateOpt","expectCenter","verifyLocateOption","verifyCenter","verifyRect","distance","included","pass","locateParam","locatePlan","locatePlanForLocate","element","assertion","msg","serviceOpt","assertionText","thought","message","TaskExecutionError","errorTask","rawError","rawMessage","reason","args","yamlScriptContent","script","parseYamlScript","player","ScriptPlayer","errors","listener","index","interfaceDestroyError","finalPath","base64","now","Date","screenshot","ScreenshotItem","recorder","uuid","ExecutionDump","dumpString","groupName","groupDescription","executions","context","opts","validateAgentCacheInput","cacheConfig","processCacheConfig","id","strategyValue","isReadOnly","isWriteOnly","files","file","absolutePath","existsSync","process","filesArray","Array","options","interfaceInstance","Object","assertReportGenerationOptions","resolvedAiActContext","hasCustomConfig","ModelConfigManager","globalModelConfigManager","Service","cacheConfigObj","TaskCache","baseActionSpace","defineActionSleep","TaskExecutor","getReportFileName","ReportGenerator","createAgent"],"mappings":"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"}