@aiscene/core 9.0.6 → 9.0.8

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 (686) hide show
  1. package/dist/es/agent/agent.mjs +24 -11
  2. package/dist/es/agent/agent.mjs.map +1 -1
  3. package/dist/es/agent/cache-config.mjs +19 -0
  4. package/dist/es/agent/cache-config.mjs.map +1 -0
  5. package/dist/es/agent/file-chooser.mjs +82 -0
  6. package/dist/es/agent/file-chooser.mjs.map +1 -0
  7. package/dist/es/agent/insight.mjs +101 -0
  8. package/dist/es/agent/insight.mjs.map +1 -0
  9. package/dist/es/agent/metrics.mjs +81 -0
  10. package/dist/es/agent/metrics.mjs.map +1 -0
  11. package/dist/es/agent/progress/ai-act-progress.mjs +199 -0
  12. package/dist/es/agent/progress/ai-act-progress.mjs.map +1 -0
  13. package/dist/es/agent/progress/index.mjs +2 -0
  14. package/dist/es/agent/progress/progress-bus.mjs +52 -0
  15. package/dist/es/agent/progress/progress-bus.mjs.map +1 -0
  16. package/dist/es/agent/prompt-context.mjs +25 -0
  17. package/dist/es/agent/prompt-context.mjs.map +1 -0
  18. package/dist/es/agent/record-to-report.mjs +14 -0
  19. package/dist/es/agent/record-to-report.mjs.map +1 -0
  20. package/dist/es/agent/run-gherkin-scenario.mjs +114 -0
  21. package/dist/es/agent/run-gherkin-scenario.mjs.map +1 -0
  22. package/dist/es/agent/run-markdown.mjs +62 -0
  23. package/dist/es/agent/run-markdown.mjs.map +1 -0
  24. package/dist/es/agent/screenshot-preparation.mjs +37 -0
  25. package/dist/es/agent/screenshot-preparation.mjs.map +1 -0
  26. package/dist/es/agent/ui-observer.mjs +385 -0
  27. package/dist/es/agent/ui-observer.mjs.map +1 -0
  28. package/dist/es/agent/utils.mjs +42 -4
  29. package/dist/es/agent/utils.mjs.map +1 -1
  30. package/dist/es/ai-model/connectivity/fixture.mjs +8 -0
  31. package/dist/es/ai-model/connectivity/fixture.mjs.map +1 -0
  32. package/dist/es/ai-model/connectivity/index.mjs +2 -0
  33. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs +160 -0
  34. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs.map +1 -0
  35. package/dist/es/ai-model/conversation-history.mjs.map +1 -1
  36. package/dist/es/ai-model/index.mjs +2 -1
  37. package/dist/es/ai-model/inspect.mjs +1 -1
  38. package/dist/es/ai-model/inspect.mjs.map +1 -1
  39. package/dist/es/ai-model/model-adapter/chat-completion.mjs +69 -0
  40. package/dist/es/ai-model/model-adapter/chat-completion.mjs.map +1 -0
  41. package/dist/es/ai-model/model-adapter/custom-planning-action.mjs +6 -0
  42. package/dist/es/ai-model/model-adapter/custom-planning-action.mjs.map +1 -0
  43. package/dist/es/ai-model/model-adapter/custom-planning-types.mjs +0 -0
  44. package/dist/es/ai-model/model-adapter/default-insight-protocol.mjs +28 -0
  45. package/dist/es/ai-model/model-adapter/default-insight-protocol.mjs.map +1 -0
  46. package/dist/es/ai-model/model-adapter/default-locate-protocol.mjs +145 -0
  47. package/dist/es/ai-model/model-adapter/default-locate-protocol.mjs.map +1 -0
  48. package/dist/es/ai-model/model-adapter/default-planning-protocol.mjs +124 -0
  49. package/dist/es/ai-model/model-adapter/default-planning-protocol.mjs.map +1 -0
  50. package/dist/es/ai-model/model-adapter/image-preprocess.mjs +27 -0
  51. package/dist/es/ai-model/model-adapter/image-preprocess.mjs.map +1 -0
  52. package/dist/es/ai-model/model-adapter/index.mjs +2 -0
  53. package/dist/es/ai-model/model-adapter/insight-protocol.mjs +0 -0
  54. package/dist/es/ai-model/model-adapter/insight.mjs +13 -0
  55. package/dist/es/ai-model/model-adapter/insight.mjs.map +1 -0
  56. package/dist/es/ai-model/model-adapter/locate-protocol.mjs +0 -0
  57. package/dist/es/ai-model/model-adapter/locate.mjs +53 -0
  58. package/dist/es/ai-model/model-adapter/locate.mjs.map +1 -0
  59. package/dist/es/ai-model/model-adapter/planning-protocol.mjs +0 -0
  60. package/dist/es/ai-model/model-adapter/planning.mjs +49 -0
  61. package/dist/es/ai-model/model-adapter/planning.mjs.map +1 -0
  62. package/dist/es/ai-model/model-adapter/resolve.mjs +54 -0
  63. package/dist/es/ai-model/model-adapter/resolve.mjs.map +1 -0
  64. package/dist/es/ai-model/model-adapter/types.mjs +0 -0
  65. package/dist/es/ai-model/models/auto-glm/actions.mjs +205 -0
  66. package/dist/es/ai-model/models/auto-glm/actions.mjs.map +1 -0
  67. package/dist/es/ai-model/models/auto-glm/adapter.mjs +45 -0
  68. package/dist/es/ai-model/models/auto-glm/adapter.mjs.map +1 -0
  69. package/dist/es/ai-model/models/auto-glm/locate.mjs +11 -0
  70. package/dist/es/ai-model/models/auto-glm/locate.mjs.map +1 -0
  71. package/dist/es/ai-model/models/auto-glm/parser.mjs +217 -0
  72. package/dist/es/ai-model/models/auto-glm/parser.mjs.map +1 -0
  73. package/dist/es/ai-model/models/auto-glm/planning.mjs +33 -0
  74. package/dist/es/ai-model/models/auto-glm/planning.mjs.map +1 -0
  75. package/dist/es/ai-model/models/auto-glm/prompt.mjs +214 -0
  76. package/dist/es/ai-model/models/auto-glm/prompt.mjs.map +1 -0
  77. package/dist/es/ai-model/models/deepseek/adapter.mjs +79 -0
  78. package/dist/es/ai-model/models/deepseek/adapter.mjs.map +1 -0
  79. package/dist/es/ai-model/models/deepseek/locate-protocol.mjs +89 -0
  80. package/dist/es/ai-model/models/deepseek/locate-protocol.mjs.map +1 -0
  81. package/dist/es/ai-model/models/default.mjs +13 -0
  82. package/dist/es/ai-model/models/default.mjs.map +1 -0
  83. package/dist/es/ai-model/models/doubao.mjs +95 -0
  84. package/dist/es/ai-model/models/doubao.mjs.map +1 -0
  85. package/dist/es/ai-model/models/gemini.mjs +100 -0
  86. package/dist/es/ai-model/models/gemini.mjs.map +1 -0
  87. package/dist/es/ai-model/models/glm.mjs +46 -0
  88. package/dist/es/ai-model/models/glm.mjs.map +1 -0
  89. package/dist/es/ai-model/models/gpt.mjs +43 -0
  90. package/dist/es/ai-model/models/gpt.mjs.map +1 -0
  91. package/dist/es/ai-model/models/index.mjs +2 -0
  92. package/dist/es/ai-model/models/kimi.mjs +102 -0
  93. package/dist/es/ai-model/models/kimi.mjs.map +1 -0
  94. package/dist/es/ai-model/models/mimo.mjs +36 -0
  95. package/dist/es/ai-model/models/mimo.mjs.map +1 -0
  96. package/dist/es/ai-model/models/qwen.mjs +139 -0
  97. package/dist/es/ai-model/models/qwen.mjs.map +1 -0
  98. package/dist/es/ai-model/models/registry.mjs +51 -0
  99. package/dist/es/ai-model/models/registry.mjs.map +1 -0
  100. package/dist/es/ai-model/models/ui-tars/actions.mjs +147 -0
  101. package/dist/es/ai-model/models/ui-tars/actions.mjs.map +1 -0
  102. package/dist/es/ai-model/models/ui-tars/adapter.mjs +102 -0
  103. package/dist/es/ai-model/models/ui-tars/adapter.mjs.map +1 -0
  104. package/dist/es/ai-model/models/ui-tars/parser.mjs +40 -0
  105. package/dist/es/ai-model/models/ui-tars/parser.mjs.map +1 -0
  106. package/dist/es/ai-model/models/ui-tars/planning.mjs +25 -0
  107. package/dist/es/ai-model/models/ui-tars/planning.mjs.map +1 -0
  108. package/dist/es/ai-model/models/ui-tars/prompt.mjs +36 -0
  109. package/dist/es/ai-model/models/ui-tars/prompt.mjs.map +1 -0
  110. package/dist/es/ai-model/models/utils/intent.mjs +6 -0
  111. package/dist/es/ai-model/models/utils/intent.mjs.map +1 -0
  112. package/dist/es/ai-model/prompt/insight/index.mjs +3 -0
  113. package/dist/es/ai-model/prompt/insight/system-prompt.mjs +104 -0
  114. package/dist/es/ai-model/prompt/insight/system-prompt.mjs.map +1 -0
  115. package/dist/es/ai-model/prompt/insight/user-prompt.mjs +23 -0
  116. package/dist/es/ai-model/prompt/insight/user-prompt.mjs.map +1 -0
  117. package/dist/es/ai-model/prompt/locate/element-system-prompt.mjs +12 -0
  118. package/dist/es/ai-model/prompt/locate/element-system-prompt.mjs.map +1 -0
  119. package/dist/es/ai-model/prompt/locate/grounding-rules.mjs +13 -0
  120. package/dist/es/ai-model/prompt/locate/grounding-rules.mjs.map +1 -0
  121. package/dist/es/ai-model/prompt/locate/index.mjs +4 -0
  122. package/dist/es/ai-model/prompt/locate/search-area-system-prompt.mjs +9 -0
  123. package/dist/es/ai-model/prompt/locate/search-area-system-prompt.mjs.map +1 -0
  124. package/dist/es/ai-model/prompt/planning/action-output-example.mjs +52 -0
  125. package/dist/es/ai-model/prompt/planning/action-output-example.mjs.map +1 -0
  126. package/dist/es/ai-model/prompt/planning/action-space-description.mjs +28 -0
  127. package/dist/es/ai-model/prompt/planning/action-space-description.mjs.map +1 -0
  128. package/dist/es/ai-model/prompt/planning/index.mjs +6 -0
  129. package/dist/es/ai-model/prompt/planning/multi-turn-example.mjs +221 -0
  130. package/dist/es/ai-model/prompt/planning/multi-turn-example.mjs.map +1 -0
  131. package/dist/es/ai-model/prompt/planning/planning-response-example.mjs +25 -0
  132. package/dist/es/ai-model/prompt/planning/planning-response-example.mjs.map +1 -0
  133. package/dist/es/ai-model/prompt/planning/sub-goals-text.mjs +17 -0
  134. package/dist/es/ai-model/prompt/planning/sub-goals-text.mjs.map +1 -0
  135. package/dist/es/ai-model/prompt/planning/system-prompt.mjs +293 -0
  136. package/dist/es/ai-model/prompt/planning/system-prompt.mjs.map +1 -0
  137. package/dist/es/ai-model/service-caller/codex-app-server.mjs +1 -0
  138. package/dist/es/ai-model/service-caller/codex-app-server.mjs.map +1 -1
  139. package/dist/es/ai-model/service-caller/index.mjs +35 -16
  140. package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
  141. package/dist/es/ai-model/service-caller/model-call-recorder.mjs +74 -0
  142. package/dist/es/ai-model/service-caller/model-call-recorder.mjs.map +1 -0
  143. package/dist/es/ai-model/service-caller/openai-error.mjs +147 -0
  144. package/dist/es/ai-model/service-caller/openai-error.mjs.map +1 -0
  145. package/dist/es/ai-model/service-caller/proxy-deps.node.mjs +9 -0
  146. package/dist/es/ai-model/service-caller/proxy-deps.node.mjs.map +1 -0
  147. package/dist/es/ai-model/service-caller/proxy-deps.stub.mjs +12 -0
  148. package/dist/es/ai-model/service-caller/proxy-deps.stub.mjs.map +1 -0
  149. package/dist/es/ai-model/service-caller/semantic-retry.mjs +33 -0
  150. package/dist/es/ai-model/service-caller/semantic-retry.mjs.map +1 -0
  151. package/dist/es/ai-model/service-caller/types.mjs +0 -0
  152. package/dist/es/ai-model/shared/action-schema.mjs +15 -0
  153. package/dist/es/ai-model/shared/action-schema.mjs.map +1 -0
  154. package/dist/es/ai-model/shared/json.mjs +63 -0
  155. package/dist/es/ai-model/shared/json.mjs.map +1 -0
  156. package/dist/es/ai-model/shared/model-locate-result/bbox.mjs +60 -0
  157. package/dist/es/ai-model/shared/model-locate-result/bbox.mjs.map +1 -0
  158. package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs +10 -0
  159. package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs.map +1 -0
  160. package/dist/es/ai-model/shared/model-locate-result/errors.mjs +9 -0
  161. package/dist/es/ai-model/shared/model-locate-result/errors.mjs.map +1 -0
  162. package/dist/es/ai-model/shared/model-locate-result/factory.mjs +39 -0
  163. package/dist/es/ai-model/shared/model-locate-result/factory.mjs.map +1 -0
  164. package/dist/es/ai-model/shared/model-locate-result/index.mjs +6 -0
  165. package/dist/es/ai-model/shared/model-locate-result/parse.mjs +45 -0
  166. package/dist/es/ai-model/shared/model-locate-result/parse.mjs.map +1 -0
  167. package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs +67 -0
  168. package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs.map +1 -0
  169. package/dist/es/ai-model/shared/model-locate-result/prompt-spec.mjs +110 -0
  170. package/dist/es/ai-model/shared/model-locate-result/prompt-spec.mjs.map +1 -0
  171. package/dist/es/ai-model/shared/model-locate-result/types.mjs +9 -0
  172. package/dist/es/ai-model/shared/model-locate-result/types.mjs.map +1 -0
  173. package/dist/es/ai-model/shared/multimodal-prompt.mjs +55 -0
  174. package/dist/es/ai-model/shared/multimodal-prompt.mjs.map +1 -0
  175. package/dist/es/ai-model/shared/xml.mjs +42 -0
  176. package/dist/es/ai-model/shared/xml.mjs.map +1 -0
  177. package/dist/es/ai-model/workflows/grounding/index.mjs +4 -0
  178. package/dist/es/ai-model/workflows/grounding/locate-result-rect.mjs +23 -0
  179. package/dist/es/ai-model/workflows/grounding/locate-result-rect.mjs.map +1 -0
  180. package/dist/es/ai-model/workflows/grounding/locate.mjs +168 -0
  181. package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -0
  182. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs +97 -0
  183. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs.map +1 -0
  184. package/dist/es/ai-model/workflows/grounding/search-area-mapping.mjs +18 -0
  185. package/dist/es/ai-model/workflows/grounding/search-area-mapping.mjs.map +1 -0
  186. package/dist/es/ai-model/workflows/grounding/search-area.mjs +55 -0
  187. package/dist/es/ai-model/workflows/grounding/search-area.mjs.map +1 -0
  188. package/dist/es/ai-model/workflows/grounding/section-locate.mjs +146 -0
  189. package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -0
  190. package/dist/es/ai-model/workflows/grounding/types.mjs +0 -0
  191. package/dist/es/ai-model/workflows/grounding/utils.mjs +50 -0
  192. package/dist/es/ai-model/workflows/grounding/utils.mjs.map +1 -0
  193. package/dist/es/ai-model/workflows/insight/extraction.mjs +101 -0
  194. package/dist/es/ai-model/workflows/insight/extraction.mjs.map +1 -0
  195. package/dist/es/ai-model/workflows/insight/index.mjs +3 -0
  196. package/dist/es/ai-model/workflows/insight/insight-response-parser.mjs +26 -0
  197. package/dist/es/ai-model/workflows/insight/insight-response-parser.mjs.map +1 -0
  198. package/dist/es/ai-model/workflows/insight/order-sensitive.mjs +29 -0
  199. package/dist/es/ai-model/workflows/insight/order-sensitive.mjs.map +1 -0
  200. package/dist/es/ai-model/workflows/planning/conversation-history.mjs +185 -0
  201. package/dist/es/ai-model/workflows/planning/conversation-history.mjs.map +1 -0
  202. package/dist/es/ai-model/workflows/planning/custom-planning.mjs +129 -0
  203. package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -0
  204. package/dist/es/ai-model/workflows/planning/index.mjs +4 -0
  205. package/dist/es/ai-model/workflows/planning/locate-normalization.mjs +41 -0
  206. package/dist/es/ai-model/workflows/planning/locate-normalization.mjs.map +1 -0
  207. package/dist/es/ai-model/workflows/planning/planning-action-log.mjs +22 -0
  208. package/dist/es/ai-model/workflows/planning/planning-action-log.mjs.map +1 -0
  209. package/dist/es/ai-model/workflows/planning/standard-planning-parser.mjs +99 -0
  210. package/dist/es/ai-model/workflows/planning/standard-planning-parser.mjs.map +1 -0
  211. package/dist/es/ai-model/workflows/planning/standard-planning.mjs +219 -0
  212. package/dist/es/ai-model/workflows/planning/standard-planning.mjs.map +1 -0
  213. package/dist/es/ai-model/workflows/planning/types.mjs +0 -0
  214. package/dist/es/ai-model/workflows/recorder-generation/common.mjs +171 -0
  215. package/dist/es/ai-model/workflows/recorder-generation/common.mjs.map +1 -0
  216. package/dist/es/ai-model/workflows/recorder-generation/index.mjs +5 -0
  217. package/dist/es/ai-model/workflows/recorder-generation/markdown.mjs +253 -0
  218. package/dist/es/ai-model/workflows/recorder-generation/markdown.mjs.map +1 -0
  219. package/dist/es/ai-model/workflows/recorder-generation/metadata.mjs +83 -0
  220. package/dist/es/ai-model/workflows/recorder-generation/metadata.mjs.map +1 -0
  221. package/dist/es/ai-model/workflows/recorder-generation/playwright.mjs +123 -0
  222. package/dist/es/ai-model/workflows/recorder-generation/playwright.mjs.map +1 -0
  223. package/dist/es/ai-model/workflows/recorder-generation/yaml.mjs +162 -0
  224. package/dist/es/ai-model/workflows/recorder-generation/yaml.mjs.map +1 -0
  225. package/dist/es/common.mjs +12 -1
  226. package/dist/es/common.mjs.map +1 -1
  227. package/dist/es/constants.mjs +4 -0
  228. package/dist/es/constants.mjs.map +1 -0
  229. package/dist/es/device/index.mjs.map +1 -1
  230. package/dist/es/device/input-strategy.mjs +34 -0
  231. package/dist/es/device/input-strategy.mjs.map +1 -0
  232. package/dist/es/dump/html-utils.mjs +16 -1
  233. package/dist/es/dump/html-utils.mjs.map +1 -1
  234. package/dist/es/dump/image-reference.mjs +63 -0
  235. package/dist/es/dump/image-reference.mjs.map +1 -0
  236. package/dist/es/dump/report-action-dump.mjs +244 -0
  237. package/dist/es/dump/report-action-dump.mjs.map +1 -0
  238. package/dist/es/dump/report-dump-compactor.mjs +200 -0
  239. package/dist/es/dump/report-dump-compactor.mjs.map +1 -0
  240. package/dist/es/dump/screenshot-store.mjs +124 -37
  241. package/dist/es/dump/screenshot-store.mjs.map +1 -1
  242. package/dist/es/dump/task-service-dump.mjs +17 -0
  243. package/dist/es/dump/task-service-dump.mjs.map +1 -0
  244. package/dist/es/dump/task-status.mjs +18 -0
  245. package/dist/es/dump/task-status.mjs.map +1 -0
  246. package/dist/es/element-describer.mjs +198 -0
  247. package/dist/es/element-describer.mjs.map +1 -0
  248. package/dist/es/errors.mjs +20 -0
  249. package/dist/es/errors.mjs.map +1 -0
  250. package/dist/es/report-html-template.mjs +4 -0
  251. package/dist/es/report-html-template.mjs.map +1 -0
  252. package/dist/es/report-stats.mjs +113 -0
  253. package/dist/es/report-stats.mjs.map +1 -0
  254. package/dist/es/screenshot-item.mjs +7 -2
  255. package/dist/es/screenshot-item.mjs.map +1 -1
  256. package/dist/es/service/index.mjs +10 -5
  257. package/dist/es/service/index.mjs.map +1 -1
  258. package/dist/es/task-runner.mjs.map +1 -1
  259. package/dist/es/types.mjs.map +1 -1
  260. package/dist/es/utils.mjs +1 -1
  261. package/dist/es/yaml/cleanup.mjs +13 -0
  262. package/dist/es/yaml/cleanup.mjs.map +1 -0
  263. package/dist/lib/agent/agent.js +24 -11
  264. package/dist/lib/agent/agent.js.map +1 -1
  265. package/dist/lib/agent/cache-config.js +53 -0
  266. package/dist/lib/agent/cache-config.js.map +1 -0
  267. package/dist/lib/agent/file-chooser.js +125 -0
  268. package/dist/lib/agent/file-chooser.js.map +1 -0
  269. package/dist/lib/agent/insight.js +135 -0
  270. package/dist/lib/agent/insight.js.map +1 -0
  271. package/dist/lib/agent/metrics.js +115 -0
  272. package/dist/lib/agent/metrics.js.map +1 -0
  273. package/dist/lib/agent/progress/ai-act-progress.js +239 -0
  274. package/dist/lib/agent/progress/ai-act-progress.js.map +1 -0
  275. package/dist/lib/agent/progress/index.js +67 -0
  276. package/dist/lib/agent/progress/index.js.map +1 -0
  277. package/dist/lib/agent/progress/progress-bus.js +86 -0
  278. package/dist/lib/agent/progress/progress-bus.js.map +1 -0
  279. package/dist/lib/agent/prompt-context.js +62 -0
  280. package/dist/lib/agent/prompt-context.js.map +1 -0
  281. package/dist/lib/agent/record-to-report.js +48 -0
  282. package/dist/lib/agent/record-to-report.js.map +1 -0
  283. package/dist/lib/agent/run-gherkin-scenario.js +151 -0
  284. package/dist/lib/agent/run-gherkin-scenario.js.map +1 -0
  285. package/dist/lib/agent/run-markdown.js +96 -0
  286. package/dist/lib/agent/run-markdown.js.map +1 -0
  287. package/dist/lib/agent/screenshot-preparation.js +74 -0
  288. package/dist/lib/agent/screenshot-preparation.js.map +1 -0
  289. package/dist/lib/agent/ui-observer.js +425 -0
  290. package/dist/lib/agent/ui-observer.js.map +1 -0
  291. package/dist/lib/agent/utils.js +46 -2
  292. package/dist/lib/agent/utils.js.map +1 -1
  293. package/dist/lib/ai-model/connectivity/fixture.js +45 -0
  294. package/dist/lib/ai-model/connectivity/fixture.js.map +1 -0
  295. package/dist/lib/ai-model/connectivity/index.js +38 -0
  296. package/dist/lib/ai-model/connectivity/index.js.map +1 -0
  297. package/dist/lib/ai-model/connectivity/run-connectivity-test.js +204 -0
  298. package/dist/lib/ai-model/connectivity/run-connectivity-test.js.map +1 -0
  299. package/dist/lib/ai-model/conversation-history.js.map +1 -1
  300. package/dist/lib/ai-model/index.js +15 -11
  301. package/dist/lib/ai-model/inspect.js +1 -1
  302. package/dist/lib/ai-model/inspect.js.map +1 -1
  303. package/dist/lib/ai-model/model-adapter/chat-completion.js +103 -0
  304. package/dist/lib/ai-model/model-adapter/chat-completion.js.map +1 -0
  305. package/dist/lib/ai-model/model-adapter/custom-planning-action.js +40 -0
  306. package/dist/lib/ai-model/model-adapter/custom-planning-action.js.map +1 -0
  307. package/dist/lib/ai-model/model-adapter/custom-planning-types.js +20 -0
  308. package/dist/lib/ai-model/model-adapter/custom-planning-types.js.map +1 -0
  309. package/dist/lib/ai-model/model-adapter/default-insight-protocol.js +62 -0
  310. package/dist/lib/ai-model/model-adapter/default-insight-protocol.js.map +1 -0
  311. package/dist/lib/ai-model/model-adapter/default-locate-protocol.js +182 -0
  312. package/dist/lib/ai-model/model-adapter/default-locate-protocol.js.map +1 -0
  313. package/dist/lib/ai-model/model-adapter/default-planning-protocol.js +170 -0
  314. package/dist/lib/ai-model/model-adapter/default-planning-protocol.js.map +1 -0
  315. package/dist/lib/ai-model/model-adapter/image-preprocess.js +61 -0
  316. package/dist/lib/ai-model/model-adapter/image-preprocess.js.map +1 -0
  317. package/dist/lib/ai-model/model-adapter/index.js +38 -0
  318. package/dist/lib/ai-model/model-adapter/index.js.map +1 -0
  319. package/dist/lib/ai-model/model-adapter/insight-protocol.js +20 -0
  320. package/dist/lib/ai-model/model-adapter/insight-protocol.js.map +1 -0
  321. package/dist/lib/ai-model/model-adapter/insight.js +50 -0
  322. package/dist/lib/ai-model/model-adapter/insight.js.map +1 -0
  323. package/dist/lib/ai-model/model-adapter/locate-protocol.js +20 -0
  324. package/dist/lib/ai-model/model-adapter/locate-protocol.js.map +1 -0
  325. package/dist/lib/ai-model/model-adapter/locate.js +87 -0
  326. package/dist/lib/ai-model/model-adapter/locate.js.map +1 -0
  327. package/dist/lib/ai-model/model-adapter/planning-protocol.js +20 -0
  328. package/dist/lib/ai-model/model-adapter/planning-protocol.js.map +1 -0
  329. package/dist/lib/ai-model/model-adapter/planning.js +86 -0
  330. package/dist/lib/ai-model/model-adapter/planning.js.map +1 -0
  331. package/dist/lib/ai-model/model-adapter/resolve.js +88 -0
  332. package/dist/lib/ai-model/model-adapter/resolve.js.map +1 -0
  333. package/dist/lib/ai-model/model-adapter/types.js +20 -0
  334. package/dist/lib/ai-model/model-adapter/types.js.map +1 -0
  335. package/dist/lib/ai-model/models/auto-glm/actions.js +239 -0
  336. package/dist/lib/ai-model/models/auto-glm/actions.js.map +1 -0
  337. package/dist/lib/ai-model/models/auto-glm/adapter.js +79 -0
  338. package/dist/lib/ai-model/models/auto-glm/adapter.js.map +1 -0
  339. package/dist/lib/ai-model/models/auto-glm/locate.js +45 -0
  340. package/dist/lib/ai-model/models/auto-glm/locate.js.map +1 -0
  341. package/dist/lib/ai-model/models/auto-glm/parser.js +260 -0
  342. package/dist/lib/ai-model/models/auto-glm/parser.js.map +1 -0
  343. package/dist/lib/ai-model/models/auto-glm/planning.js +67 -0
  344. package/dist/lib/ai-model/models/auto-glm/planning.js.map +1 -0
  345. package/dist/lib/ai-model/models/auto-glm/prompt.js +257 -0
  346. package/dist/lib/ai-model/models/auto-glm/prompt.js.map +1 -0
  347. package/dist/lib/ai-model/models/deepseek/adapter.js +113 -0
  348. package/dist/lib/ai-model/models/deepseek/adapter.js.map +1 -0
  349. package/dist/lib/ai-model/models/deepseek/locate-protocol.js +132 -0
  350. package/dist/lib/ai-model/models/deepseek/locate-protocol.js.map +1 -0
  351. package/dist/lib/ai-model/models/default.js +47 -0
  352. package/dist/lib/ai-model/models/default.js.map +1 -0
  353. package/dist/lib/ai-model/models/doubao.js +132 -0
  354. package/dist/lib/ai-model/models/doubao.js.map +1 -0
  355. package/dist/lib/ai-model/models/gemini.js +137 -0
  356. package/dist/lib/ai-model/models/gemini.js.map +1 -0
  357. package/dist/lib/ai-model/models/glm.js +80 -0
  358. package/dist/lib/ai-model/models/glm.js.map +1 -0
  359. package/dist/lib/ai-model/models/gpt.js +77 -0
  360. package/dist/lib/ai-model/models/gpt.js.map +1 -0
  361. package/dist/lib/ai-model/models/index.js +41 -0
  362. package/dist/lib/ai-model/models/index.js.map +1 -0
  363. package/dist/lib/ai-model/models/kimi.js +136 -0
  364. package/dist/lib/ai-model/models/kimi.js.map +1 -0
  365. package/dist/lib/ai-model/models/mimo.js +70 -0
  366. package/dist/lib/ai-model/models/mimo.js.map +1 -0
  367. package/dist/lib/ai-model/models/qwen.js +173 -0
  368. package/dist/lib/ai-model/models/qwen.js.map +1 -0
  369. package/dist/lib/ai-model/models/registry.js +91 -0
  370. package/dist/lib/ai-model/models/registry.js.map +1 -0
  371. package/dist/lib/ai-model/models/ui-tars/actions.js +181 -0
  372. package/dist/lib/ai-model/models/ui-tars/actions.js.map +1 -0
  373. package/dist/lib/ai-model/models/ui-tars/adapter.js +136 -0
  374. package/dist/lib/ai-model/models/ui-tars/adapter.js.map +1 -0
  375. package/dist/lib/ai-model/models/ui-tars/parser.js +74 -0
  376. package/dist/lib/ai-model/models/ui-tars/parser.js.map +1 -0
  377. package/dist/lib/ai-model/models/ui-tars/planning.js +59 -0
  378. package/dist/lib/ai-model/models/ui-tars/planning.js.map +1 -0
  379. package/dist/lib/ai-model/models/ui-tars/prompt.js +73 -0
  380. package/dist/lib/ai-model/models/ui-tars/prompt.js.map +1 -0
  381. package/dist/lib/ai-model/models/utils/intent.js +40 -0
  382. package/dist/lib/ai-model/models/utils/intent.js.map +1 -0
  383. package/dist/lib/ai-model/prompt/insight/index.js +45 -0
  384. package/dist/lib/ai-model/prompt/insight/index.js.map +1 -0
  385. package/dist/lib/ai-model/prompt/insight/system-prompt.js +138 -0
  386. package/dist/lib/ai-model/prompt/insight/system-prompt.js.map +1 -0
  387. package/dist/lib/ai-model/prompt/insight/user-prompt.js +60 -0
  388. package/dist/lib/ai-model/prompt/insight/user-prompt.js.map +1 -0
  389. package/dist/lib/ai-model/prompt/locate/element-system-prompt.js +46 -0
  390. package/dist/lib/ai-model/prompt/locate/element-system-prompt.js.map +1 -0
  391. package/dist/lib/ai-model/prompt/locate/grounding-rules.js +47 -0
  392. package/dist/lib/ai-model/prompt/locate/grounding-rules.js.map +1 -0
  393. package/dist/lib/ai-model/prompt/locate/index.js +46 -0
  394. package/dist/lib/ai-model/prompt/locate/index.js.map +1 -0
  395. package/dist/lib/ai-model/prompt/locate/search-area-system-prompt.js +43 -0
  396. package/dist/lib/ai-model/prompt/locate/search-area-system-prompt.js.map +1 -0
  397. package/dist/lib/ai-model/prompt/planning/action-output-example.js +92 -0
  398. package/dist/lib/ai-model/prompt/planning/action-output-example.js.map +1 -0
  399. package/dist/lib/ai-model/prompt/planning/action-space-description.js +75 -0
  400. package/dist/lib/ai-model/prompt/planning/action-space-description.js.map +1 -0
  401. package/dist/lib/ai-model/prompt/planning/index.js +63 -0
  402. package/dist/lib/ai-model/prompt/planning/index.js.map +1 -0
  403. package/dist/lib/ai-model/prompt/planning/multi-turn-example.js +255 -0
  404. package/dist/lib/ai-model/prompt/planning/multi-turn-example.js.map +1 -0
  405. package/dist/lib/ai-model/prompt/planning/planning-response-example.js +59 -0
  406. package/dist/lib/ai-model/prompt/planning/planning-response-example.js.map +1 -0
  407. package/dist/lib/ai-model/prompt/planning/sub-goals-text.js +51 -0
  408. package/dist/lib/ai-model/prompt/planning/sub-goals-text.js.map +1 -0
  409. package/dist/lib/ai-model/prompt/planning/system-prompt.js +327 -0
  410. package/dist/lib/ai-model/prompt/planning/system-prompt.js.map +1 -0
  411. package/dist/lib/ai-model/service-caller/codex-app-server.js +1 -0
  412. package/dist/lib/ai-model/service-caller/codex-app-server.js.map +1 -1
  413. package/dist/lib/ai-model/service-caller/index.js +35 -16
  414. package/dist/lib/ai-model/service-caller/index.js.map +1 -1
  415. package/dist/lib/ai-model/service-caller/model-call-recorder.js +124 -0
  416. package/dist/lib/ai-model/service-caller/model-call-recorder.js.map +1 -0
  417. package/dist/lib/ai-model/service-caller/openai-error.js +184 -0
  418. package/dist/lib/ai-model/service-caller/openai-error.js.map +1 -0
  419. package/dist/lib/ai-model/service-caller/proxy-deps.node.js +46 -0
  420. package/dist/lib/ai-model/service-caller/proxy-deps.node.js.map +1 -0
  421. package/dist/lib/ai-model/service-caller/proxy-deps.stub.js +49 -0
  422. package/dist/lib/ai-model/service-caller/proxy-deps.stub.js.map +1 -0
  423. package/dist/lib/ai-model/service-caller/semantic-retry.js +70 -0
  424. package/dist/lib/ai-model/service-caller/semantic-retry.js.map +1 -0
  425. package/dist/lib/ai-model/service-caller/types.js +20 -0
  426. package/dist/lib/ai-model/service-caller/types.js.map +1 -0
  427. package/dist/lib/ai-model/shared/action-schema.js +49 -0
  428. package/dist/lib/ai-model/shared/action-schema.js.map +1 -0
  429. package/dist/lib/ai-model/shared/json.js +103 -0
  430. package/dist/lib/ai-model/shared/json.js.map +1 -0
  431. package/dist/lib/ai-model/shared/model-locate-result/bbox.js +106 -0
  432. package/dist/lib/ai-model/shared/model-locate-result/bbox.js.map +1 -0
  433. package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js +44 -0
  434. package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js.map +1 -0
  435. package/dist/lib/ai-model/shared/model-locate-result/errors.js +46 -0
  436. package/dist/lib/ai-model/shared/model-locate-result/errors.js.map +1 -0
  437. package/dist/lib/ai-model/shared/model-locate-result/factory.js +76 -0
  438. package/dist/lib/ai-model/shared/model-locate-result/factory.js.map +1 -0
  439. package/dist/lib/ai-model/shared/model-locate-result/index.js +66 -0
  440. package/dist/lib/ai-model/shared/model-locate-result/index.js.map +1 -0
  441. package/dist/lib/ai-model/shared/model-locate-result/parse.js +88 -0
  442. package/dist/lib/ai-model/shared/model-locate-result/parse.js.map +1 -0
  443. package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js +101 -0
  444. package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js.map +1 -0
  445. package/dist/lib/ai-model/shared/model-locate-result/prompt-spec.js +156 -0
  446. package/dist/lib/ai-model/shared/model-locate-result/prompt-spec.js.map +1 -0
  447. package/dist/lib/ai-model/shared/model-locate-result/types.js +46 -0
  448. package/dist/lib/ai-model/shared/model-locate-result/types.js.map +1 -0
  449. package/dist/lib/ai-model/shared/multimodal-prompt.js +95 -0
  450. package/dist/lib/ai-model/shared/multimodal-prompt.js.map +1 -0
  451. package/dist/lib/ai-model/shared/xml.js +79 -0
  452. package/dist/lib/ai-model/shared/xml.js.map +1 -0
  453. package/dist/lib/ai-model/workflows/grounding/index.js +46 -0
  454. package/dist/lib/ai-model/workflows/grounding/index.js.map +1 -0
  455. package/dist/lib/ai-model/workflows/grounding/locate-result-rect.js +60 -0
  456. package/dist/lib/ai-model/workflows/grounding/locate-result-rect.js.map +1 -0
  457. package/dist/lib/ai-model/workflows/grounding/locate.js +208 -0
  458. package/dist/lib/ai-model/workflows/grounding/locate.js.map +1 -0
  459. package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js +131 -0
  460. package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js.map +1 -0
  461. package/dist/lib/ai-model/workflows/grounding/search-area-mapping.js +52 -0
  462. package/dist/lib/ai-model/workflows/grounding/search-area-mapping.js.map +1 -0
  463. package/dist/lib/ai-model/workflows/grounding/search-area.js +92 -0
  464. package/dist/lib/ai-model/workflows/grounding/search-area.js.map +1 -0
  465. package/dist/lib/ai-model/workflows/grounding/section-locate.js +180 -0
  466. package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -0
  467. package/dist/lib/ai-model/workflows/grounding/types.js +20 -0
  468. package/dist/lib/ai-model/workflows/grounding/types.js.map +1 -0
  469. package/dist/lib/ai-model/workflows/grounding/utils.js +87 -0
  470. package/dist/lib/ai-model/workflows/grounding/utils.js.map +1 -0
  471. package/dist/lib/ai-model/workflows/insight/extraction.js +135 -0
  472. package/dist/lib/ai-model/workflows/insight/extraction.js.map +1 -0
  473. package/dist/lib/ai-model/workflows/insight/index.js +42 -0
  474. package/dist/lib/ai-model/workflows/insight/index.js.map +1 -0
  475. package/dist/lib/ai-model/workflows/insight/insight-response-parser.js +60 -0
  476. package/dist/lib/ai-model/workflows/insight/insight-response-parser.js.map +1 -0
  477. package/dist/lib/ai-model/workflows/insight/order-sensitive.js +63 -0
  478. package/dist/lib/ai-model/workflows/insight/order-sensitive.js.map +1 -0
  479. package/dist/lib/ai-model/workflows/planning/conversation-history.js +219 -0
  480. package/dist/lib/ai-model/workflows/planning/conversation-history.js.map +1 -0
  481. package/dist/lib/ai-model/workflows/planning/custom-planning.js +166 -0
  482. package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -0
  483. package/dist/lib/ai-model/workflows/planning/index.js +49 -0
  484. package/dist/lib/ai-model/workflows/planning/index.js.map +1 -0
  485. package/dist/lib/ai-model/workflows/planning/locate-normalization.js +75 -0
  486. package/dist/lib/ai-model/workflows/planning/locate-normalization.js.map +1 -0
  487. package/dist/lib/ai-model/workflows/planning/planning-action-log.js +56 -0
  488. package/dist/lib/ai-model/workflows/planning/planning-action-log.js.map +1 -0
  489. package/dist/lib/ai-model/workflows/planning/standard-planning-parser.js +142 -0
  490. package/dist/lib/ai-model/workflows/planning/standard-planning-parser.js.map +1 -0
  491. package/dist/lib/ai-model/workflows/planning/standard-planning.js +253 -0
  492. package/dist/lib/ai-model/workflows/planning/standard-planning.js.map +1 -0
  493. package/dist/lib/ai-model/workflows/planning/types.js +20 -0
  494. package/dist/lib/ai-model/workflows/planning/types.js.map +1 -0
  495. package/dist/lib/ai-model/workflows/recorder-generation/common.js +232 -0
  496. package/dist/lib/ai-model/workflows/recorder-generation/common.js.map +1 -0
  497. package/dist/lib/ai-model/workflows/recorder-generation/index.js +68 -0
  498. package/dist/lib/ai-model/workflows/recorder-generation/index.js.map +1 -0
  499. package/dist/lib/ai-model/workflows/recorder-generation/markdown.js +293 -0
  500. package/dist/lib/ai-model/workflows/recorder-generation/markdown.js.map +1 -0
  501. package/dist/lib/ai-model/workflows/recorder-generation/metadata.js +117 -0
  502. package/dist/lib/ai-model/workflows/recorder-generation/metadata.js.map +1 -0
  503. package/dist/lib/ai-model/workflows/recorder-generation/playwright.js +184 -0
  504. package/dist/lib/ai-model/workflows/recorder-generation/playwright.js.map +1 -0
  505. package/dist/lib/ai-model/workflows/recorder-generation/yaml.js +232 -0
  506. package/dist/lib/ai-model/workflows/recorder-generation/yaml.js.map +1 -0
  507. package/dist/lib/common.js +18 -1
  508. package/dist/lib/common.js.map +1 -1
  509. package/dist/lib/constants.js +38 -0
  510. package/dist/lib/constants.js.map +1 -0
  511. package/dist/lib/device/index.js.map +1 -1
  512. package/dist/lib/device/input-strategy.js +80 -0
  513. package/dist/lib/device/input-strategy.js.map +1 -0
  514. package/dist/lib/dump/html-utils.js +18 -0
  515. package/dist/lib/dump/html-utils.js.map +1 -1
  516. package/dist/lib/dump/image-reference.js +115 -0
  517. package/dist/lib/dump/image-reference.js.map +1 -0
  518. package/dist/lib/dump/report-action-dump.js +284 -0
  519. package/dist/lib/dump/report-action-dump.js.map +1 -0
  520. package/dist/lib/dump/report-dump-compactor.js +234 -0
  521. package/dist/lib/dump/report-dump-compactor.js.map +1 -0
  522. package/dist/lib/dump/screenshot-store.js +146 -38
  523. package/dist/lib/dump/screenshot-store.js.map +1 -1
  524. package/dist/lib/dump/task-service-dump.js +54 -0
  525. package/dist/lib/dump/task-service-dump.js.map +1 -0
  526. package/dist/lib/dump/task-status.js +55 -0
  527. package/dist/lib/dump/task-status.js.map +1 -0
  528. package/dist/lib/element-describer.js +238 -0
  529. package/dist/lib/element-describer.js.map +1 -0
  530. package/dist/lib/errors.js +54 -0
  531. package/dist/lib/errors.js.map +1 -0
  532. package/dist/lib/report-html-template.js +38 -0
  533. package/dist/lib/report-html-template.js.map +1 -0
  534. package/dist/lib/report-stats.js +147 -0
  535. package/dist/lib/report-stats.js.map +1 -0
  536. package/dist/lib/screenshot-item.js +7 -2
  537. package/dist/lib/screenshot-item.js.map +1 -1
  538. package/dist/lib/service/index.js +10 -5
  539. package/dist/lib/service/index.js.map +1 -1
  540. package/dist/lib/task-runner.js.map +1 -1
  541. package/dist/lib/types.js +2 -2
  542. package/dist/lib/types.js.map +1 -1
  543. package/dist/lib/utils.js +1 -1
  544. package/dist/lib/yaml/cleanup.js +47 -0
  545. package/dist/lib/yaml/cleanup.js.map +1 -0
  546. package/dist/types/agent/agent.d.ts +5 -9
  547. package/dist/types/agent/cache-config.d.ts +2 -0
  548. package/dist/types/agent/file-chooser.d.ts +19 -0
  549. package/dist/types/agent/insight.d.ts +21 -0
  550. package/dist/types/agent/metrics.d.ts +48 -0
  551. package/dist/types/agent/progress/ai-act-progress.d.ts +21 -0
  552. package/dist/types/agent/progress/index.d.ts +2 -0
  553. package/dist/types/agent/progress/progress-bus.d.ts +33 -0
  554. package/dist/types/agent/prompt-context.d.ts +3 -0
  555. package/dist/types/agent/record-to-report.d.ts +2 -0
  556. package/dist/types/agent/run-gherkin-scenario.d.ts +26 -0
  557. package/dist/types/agent/run-markdown.d.ts +6 -0
  558. package/dist/types/agent/screenshot-preparation.d.ts +20 -0
  559. package/dist/types/agent/ui-observer.d.ts +103 -0
  560. package/dist/types/agent/utils.d.ts +12 -1
  561. package/dist/types/ai-model/connectivity/fixture.d.ts +5 -0
  562. package/dist/types/ai-model/connectivity/index.d.ts +1 -0
  563. package/dist/types/ai-model/connectivity/run-connectivity-test.d.ts +11 -0
  564. package/dist/types/ai-model/index.d.ts +2 -0
  565. package/dist/types/ai-model/model-adapter/chat-completion.d.ts +2 -0
  566. package/dist/types/ai-model/model-adapter/custom-planning-action.d.ts +25 -0
  567. package/dist/types/ai-model/model-adapter/custom-planning-types.d.ts +31 -0
  568. package/dist/types/ai-model/model-adapter/default-insight-protocol.d.ts +2 -0
  569. package/dist/types/ai-model/model-adapter/default-locate-protocol.d.ts +7 -0
  570. package/dist/types/ai-model/model-adapter/default-planning-protocol.d.ts +25 -0
  571. package/dist/types/ai-model/model-adapter/image-preprocess.d.ts +30 -0
  572. package/dist/types/ai-model/model-adapter/index.d.ts +2 -0
  573. package/dist/types/ai-model/model-adapter/insight-protocol.d.ts +24 -0
  574. package/dist/types/ai-model/model-adapter/insight.d.ts +3 -0
  575. package/dist/types/ai-model/model-adapter/locate-protocol.d.ts +23 -0
  576. package/dist/types/ai-model/model-adapter/locate.d.ts +4 -0
  577. package/dist/types/ai-model/model-adapter/planning-protocol.d.ts +53 -0
  578. package/dist/types/ai-model/model-adapter/planning.d.ts +6 -0
  579. package/dist/types/ai-model/model-adapter/resolve.d.ts +12 -0
  580. package/dist/types/ai-model/model-adapter/types.d.ts +218 -0
  581. package/dist/types/ai-model/models/auto-glm/actions.d.ts +81 -0
  582. package/dist/types/ai-model/models/auto-glm/adapter.d.ts +5 -0
  583. package/dist/types/ai-model/models/auto-glm/locate.d.ts +2 -0
  584. package/dist/types/ai-model/models/auto-glm/parser.d.ts +14 -0
  585. package/dist/types/ai-model/models/auto-glm/planning.d.ts +5 -0
  586. package/dist/types/ai-model/models/auto-glm/prompt.d.ts +4 -0
  587. package/dist/types/ai-model/models/deepseek/adapter.d.ts +39 -0
  588. package/dist/types/ai-model/models/deepseek/locate-protocol.d.ts +5 -0
  589. package/dist/types/ai-model/models/default.d.ts +2 -0
  590. package/dist/types/ai-model/models/doubao.d.ts +7 -0
  591. package/dist/types/ai-model/models/gemini.d.ts +37 -0
  592. package/dist/types/ai-model/models/glm.d.ts +21 -0
  593. package/dist/types/ai-model/models/gpt.d.ts +20 -0
  594. package/dist/types/ai-model/models/index.d.ts +2 -0
  595. package/dist/types/ai-model/models/kimi.d.ts +45 -0
  596. package/dist/types/ai-model/models/mimo.d.ts +10 -0
  597. package/dist/types/ai-model/models/qwen.d.ts +33 -0
  598. package/dist/types/ai-model/models/registry.d.ts +187 -0
  599. package/dist/types/ai-model/models/ui-tars/actions.d.ts +3 -0
  600. package/dist/types/ai-model/models/ui-tars/adapter.d.ts +6 -0
  601. package/dist/types/ai-model/models/ui-tars/parser.d.ts +72 -0
  602. package/dist/types/ai-model/models/ui-tars/planning.d.ts +4 -0
  603. package/dist/types/ai-model/models/ui-tars/prompt.d.ts +2 -0
  604. package/dist/types/ai-model/models/utils/intent.d.ts +2 -0
  605. package/dist/types/ai-model/prompt/insight/index.d.ts +2 -0
  606. package/dist/types/ai-model/prompt/insight/system-prompt.d.ts +6 -0
  607. package/dist/types/ai-model/prompt/insight/user-prompt.d.ts +3 -0
  608. package/dist/types/ai-model/prompt/locate/element-system-prompt.d.ts +4 -0
  609. package/dist/types/ai-model/prompt/locate/grounding-rules.d.ts +1 -0
  610. package/dist/types/ai-model/prompt/locate/index.d.ts +3 -0
  611. package/dist/types/ai-model/prompt/locate/search-area-system-prompt.d.ts +4 -0
  612. package/dist/types/ai-model/prompt/planning/action-output-example.d.ts +17 -0
  613. package/dist/types/ai-model/prompt/planning/action-space-description.d.ts +11 -0
  614. package/dist/types/ai-model/prompt/planning/index.d.ts +6 -0
  615. package/dist/types/ai-model/prompt/planning/multi-turn-example.d.ts +10 -0
  616. package/dist/types/ai-model/prompt/planning/planning-response-example.d.ts +28 -0
  617. package/dist/types/ai-model/prompt/planning/sub-goals-text.d.ts +2 -0
  618. package/dist/types/ai-model/prompt/planning/system-prompt.d.ts +18 -0
  619. package/dist/types/ai-model/service-caller/index.d.ts +21 -6
  620. package/dist/types/ai-model/service-caller/model-call-recorder.d.ts +12 -0
  621. package/dist/types/ai-model/service-caller/openai-error.d.ts +26 -0
  622. package/dist/types/ai-model/service-caller/proxy-deps.node.d.ts +2 -0
  623. package/dist/types/ai-model/service-caller/proxy-deps.stub.d.ts +2 -0
  624. package/dist/types/ai-model/service-caller/semantic-retry.d.ts +30 -0
  625. package/dist/types/ai-model/service-caller/types.d.ts +2 -0
  626. package/dist/types/ai-model/shared/action-schema.d.ts +4 -0
  627. package/dist/types/ai-model/shared/json.d.ts +26 -0
  628. package/dist/types/ai-model/shared/model-locate-result/bbox.d.ts +6 -0
  629. package/dist/types/ai-model/shared/model-locate-result/coordinate-distance.d.ts +4 -0
  630. package/dist/types/ai-model/shared/model-locate-result/errors.d.ts +2 -0
  631. package/dist/types/ai-model/shared/model-locate-result/factory.d.ts +3 -0
  632. package/dist/types/ai-model/shared/model-locate-result/index.d.ts +7 -0
  633. package/dist/types/ai-model/shared/model-locate-result/parse.d.ts +8 -0
  634. package/dist/types/ai-model/shared/model-locate-result/pixel-bbox-mapper.d.ts +7 -0
  635. package/dist/types/ai-model/shared/model-locate-result/prompt-spec.d.ts +6 -0
  636. package/dist/types/ai-model/shared/model-locate-result/types.d.ts +150 -0
  637. package/dist/types/ai-model/shared/multimodal-prompt.d.ts +13 -0
  638. package/dist/types/ai-model/shared/xml.d.ts +15 -0
  639. package/dist/types/ai-model/workflows/grounding/index.d.ts +3 -0
  640. package/dist/types/ai-model/workflows/grounding/locate-result-rect.d.ts +5 -0
  641. package/dist/types/ai-model/workflows/grounding/locate.d.ts +7 -0
  642. package/dist/types/ai-model/workflows/grounding/planning-action-locate.d.ts +4 -0
  643. package/dist/types/ai-model/workflows/grounding/search-area-mapping.d.ts +4 -0
  644. package/dist/types/ai-model/workflows/grounding/search-area.d.ts +18 -0
  645. package/dist/types/ai-model/workflows/grounding/section-locate.d.ts +16 -0
  646. package/dist/types/ai-model/workflows/grounding/types.d.ts +56 -0
  647. package/dist/types/ai-model/workflows/grounding/utils.d.ts +25 -0
  648. package/dist/types/ai-model/workflows/insight/extraction.d.ts +18 -0
  649. package/dist/types/ai-model/workflows/insight/index.d.ts +2 -0
  650. package/dist/types/ai-model/workflows/insight/insight-response-parser.d.ts +4 -0
  651. package/dist/types/ai-model/workflows/insight/order-sensitive.d.ts +6 -0
  652. package/dist/types/ai-model/workflows/planning/conversation-history.d.ts +105 -0
  653. package/dist/types/ai-model/workflows/planning/custom-planning.d.ts +7 -0
  654. package/dist/types/ai-model/workflows/planning/index.d.ts +3 -0
  655. package/dist/types/ai-model/workflows/planning/locate-normalization.d.ts +12 -0
  656. package/dist/types/ai-model/workflows/planning/planning-action-log.d.ts +2 -0
  657. package/dist/types/ai-model/workflows/planning/standard-planning-parser.d.ts +31 -0
  658. package/dist/types/ai-model/workflows/planning/standard-planning.d.ts +4 -0
  659. package/dist/types/ai-model/workflows/planning/types.d.ts +16 -0
  660. package/dist/types/ai-model/workflows/recorder-generation/common.d.ts +89 -0
  661. package/dist/types/ai-model/workflows/recorder-generation/index.d.ts +7 -0
  662. package/dist/types/ai-model/workflows/recorder-generation/markdown.d.ts +7 -0
  663. package/dist/types/ai-model/workflows/recorder-generation/metadata.d.ts +13 -0
  664. package/dist/types/ai-model/workflows/recorder-generation/playwright.d.ts +26 -0
  665. package/dist/types/ai-model/workflows/recorder-generation/yaml.d.ts +17 -0
  666. package/dist/types/common.d.ts +2 -0
  667. package/dist/types/constants.d.ts +1 -0
  668. package/dist/types/device/index.d.ts +15 -4
  669. package/dist/types/device/input-strategy.d.ts +44 -0
  670. package/dist/types/dump/html-utils.d.ts +1 -0
  671. package/dist/types/dump/image-reference.d.ts +36 -0
  672. package/dist/types/dump/report-action-dump.d.ts +127 -0
  673. package/dist/types/dump/report-dump-compactor.d.ts +7 -0
  674. package/dist/types/dump/screenshot-store.d.ts +32 -15
  675. package/dist/types/dump/task-service-dump.d.ts +3 -0
  676. package/dist/types/dump/task-status.d.ts +41 -0
  677. package/dist/types/element-describer.d.ts +43 -0
  678. package/dist/types/errors.d.ts +5 -0
  679. package/dist/types/report-html-template.d.ts +1 -0
  680. package/dist/types/report-stats.d.ts +39 -0
  681. package/dist/types/screenshot-item.d.ts +1 -0
  682. package/dist/types/service/index.d.ts +6 -2
  683. package/dist/types/task-runner.d.ts +6 -0
  684. package/dist/types/types.d.ts +98 -5
  685. package/dist/types/yaml/cleanup.d.ts +2 -0
  686. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/index.mjs","sources":["../../../../src/ai-model/service-caller/index.ts"],"sourcesContent":["import type { AIUsageInfo } from '@/types';\nimport type { CodeGenerationChunk, StreamingCallback } from '@/types';\n\n// Error class that preserves usage and rawResponse when AI call parsing fails\nexport class AIResponseParseError extends Error {\n usage?: AIUsageInfo;\n rawResponse: string;\n\n constructor(message: string, rawResponse: string, usage?: AIUsageInfo) {\n super(message);\n this.name = 'AIResponseParseError';\n this.rawResponse = rawResponse;\n this.usage = usage;\n }\n}\nimport {\n type IModelConfig,\n MIDSCENE_LANGFUSE_DEBUG,\n MIDSCENE_LANGSMITH_DEBUG,\n MIDSCENE_MODEL_MAX_TOKENS,\n OPENAI_MAX_TOKENS,\n type TModelFamily,\n type UITarsModelVersion,\n globalConfigManager,\n} from '@aiscene/shared/env';\n\nimport { getDebug } from '@aiscene/shared/logger';\nimport { assert, ifInBrowser } from '@aiscene/shared/utils';\nimport { jsonrepair } from 'jsonrepair';\nimport OpenAI from 'openai';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { Stream } from 'openai/streaming';\nimport type { AIArgs } from '../../common';\nimport { isAutoGLM, isUITars } from '../auto-glm/util';\nimport {\n callAIWithCodexAppServer,\n isCodexAppServerProvider,\n} from './codex-app-server';\nimport { shouldForceOriginalImageDetail } from './image-detail';\nimport {\n buildRequestAbortSignal,\n isHardTimeoutError,\n resolveEffectiveTimeoutMs,\n} from './request-timeout';\n\nfunction formatAIRequestMessagesForDebug(\n messages: ChatCompletionMessageParam[],\n): string {\n return messages\n .map((message, index) => {\n const role =\n typeof (message as { role?: unknown }).role === 'string'\n ? (message as { role: string }).role\n : 'unknown';\n return `#${index + 1} role=${role}\\n${formatAIMessageContentForDebug(\n (message as { content?: unknown }).content,\n )}`;\n })\n .join('\\n---\\n');\n}\n\nfunction formatAIMessageContentForDebug(content: unknown): string {\n if (typeof content === 'string') {\n return content;\n }\n\n if (!Array.isArray(content)) {\n return safeStringifyForDebug(content);\n }\n\n return content\n .map((part) => {\n if (!part || typeof part !== 'object') {\n return safeStringifyForDebug(part);\n }\n\n const record = part as Record<string, unknown>;\n if (record.type === 'image_url') {\n return '[image omitted]';\n }\n if (typeof record.text === 'string') {\n return record.text;\n }\n if (typeof record.input_text === 'string') {\n return record.input_text;\n }\n return safeStringifyForDebug(redactImagesForDebug(record));\n })\n .join('\\n');\n}\n\nfunction redactImagesForDebug(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => redactImagesForDebug(item));\n }\n if (!value || typeof value !== 'object') {\n return value;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n result[key] =\n key === 'url' || key === 'image_url'\n ? '[image omitted]'\n : redactImagesForDebug(item);\n }\n return result;\n}\n\nfunction safeStringifyForDebug(value: unknown): string {\n if (value === undefined) {\n return '';\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nasync function createChatClient({\n modelConfig,\n}: {\n modelConfig: IModelConfig;\n}): Promise<{\n completion: OpenAI.Chat.Completions;\n modelName: string;\n modelDescription: string;\n uiTarsModelVersion?: UITarsModelVersion;\n modelFamily: TModelFamily | undefined;\n}> {\n const {\n socksProxy,\n httpProxy,\n modelName,\n openaiBaseURL,\n openaiApiKey,\n openaiExtraConfig,\n modelDescription,\n uiTarsModelVersion,\n modelFamily,\n createOpenAIClient,\n timeout,\n } = modelConfig;\n\n let proxyAgent: any = undefined;\n const warnClient = getDebug('ai:call', { console: true });\n const debugProxy = getDebug('ai:call:proxy');\n const warnProxy = getDebug('ai:call:proxy', { console: true });\n\n // Helper function to sanitize proxy URL for logging (remove credentials)\n // Uses URL API instead of regex to avoid ReDoS vulnerabilities\n const sanitizeProxyUrl = (url: string): string => {\n try {\n const parsed = new URL(url);\n if (parsed.username) {\n // Keep username for debugging, hide password for security\n parsed.password = '****';\n return parsed.href;\n }\n return url;\n } catch {\n // If URL parsing fails, return original URL (will be caught later)\n return url;\n }\n };\n\n if (httpProxy) {\n debugProxy('using http proxy', sanitizeProxyUrl(httpProxy));\n if (ifInBrowser) {\n warnProxy(\n 'HTTP proxy is configured but not supported in browser environment',\n );\n } else {\n // Dynamic import with variable to avoid bundler static analysis\n const moduleName = 'undici';\n const { ProxyAgent } = await import(moduleName);\n proxyAgent = new ProxyAgent({\n uri: httpProxy,\n // Note: authentication is handled via the URI (e.g., http://user:pass@proxy.com:8080)\n });\n }\n } else if (socksProxy) {\n debugProxy('using socks proxy', sanitizeProxyUrl(socksProxy));\n if (ifInBrowser) {\n warnProxy(\n 'SOCKS proxy is configured but not supported in browser environment',\n );\n } else {\n try {\n // Dynamic import with variable to avoid bundler static analysis\n const moduleName = 'fetch-socks';\n const { socksDispatcher } = await import(moduleName);\n // Parse SOCKS proxy URL (e.g., socks5://127.0.0.1:1080)\n const proxyUrl = new URL(socksProxy);\n\n // Validate hostname\n if (!proxyUrl.hostname) {\n throw new Error('SOCKS proxy URL must include a valid hostname');\n }\n\n // Validate and parse port\n const port = Number.parseInt(proxyUrl.port, 10);\n if (!proxyUrl.port || Number.isNaN(port)) {\n throw new Error('SOCKS proxy URL must include a valid port');\n }\n\n // Parse SOCKS version from protocol\n const protocol = proxyUrl.protocol.replace(':', '');\n const socksType =\n protocol === 'socks4' ? 4 : protocol === 'socks5' ? 5 : 5;\n\n proxyAgent = socksDispatcher({\n type: socksType,\n host: proxyUrl.hostname,\n port,\n ...(proxyUrl.username\n ? {\n userId: decodeURIComponent(proxyUrl.username),\n password: decodeURIComponent(proxyUrl.password || ''),\n }\n : {}),\n });\n debugProxy('socks proxy configured successfully', {\n type: socksType,\n host: proxyUrl.hostname,\n port: port,\n });\n } catch (error) {\n warnProxy('Failed to configure SOCKS proxy:', error);\n throw new Error(\n `Invalid SOCKS proxy URL: ${socksProxy}. Expected format: socks4://host:port, socks5://host:port, or with authentication: socks5://user:pass@host:port`,\n );\n }\n }\n }\n\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs({ timeout });\n const openAIOptions = {\n baseURL: openaiBaseURL,\n apiKey: openaiApiKey,\n // Use fetchOptions.dispatcher for fetch-based SDK instead of httpAgent\n // Note: Type assertion needed due to undici version mismatch between dependencies\n ...(proxyAgent ? { fetchOptions: { dispatcher: proxyAgent as any } } : {}),\n ...openaiExtraConfig,\n // Midscene already handles retries in callAI(), so disable SDK-level retries\n // to avoid duplicate attempts and duplicated backoff latency.\n maxRetries: 0,\n // When disabled (timeoutMs === null) fall through to the SDK default so\n // only the caller-provided abortSignal can cancel the request.\n ...(effectiveTimeoutMs !== null ? { timeout: effectiveTimeoutMs } : {}),\n dangerouslyAllowBrowser: true,\n };\n\n const baseOpenAI = new OpenAI(openAIOptions);\n\n let openai: OpenAI = baseOpenAI;\n\n // LangSmith wrapper\n if (\n openai &&\n globalConfigManager.getEnvConfigInBoolean(MIDSCENE_LANGSMITH_DEBUG)\n ) {\n if (ifInBrowser) {\n throw new Error('langsmith is not supported in browser');\n }\n warnClient('DEBUGGING MODE: langsmith wrapper enabled');\n // Use variable to prevent static analysis by bundlers\n const langsmithModule = 'langsmith/wrappers';\n const { wrapOpenAI } = await import(langsmithModule);\n openai = wrapOpenAI(openai);\n }\n\n // Langfuse wrapper\n if (\n openai &&\n globalConfigManager.getEnvConfigInBoolean(MIDSCENE_LANGFUSE_DEBUG)\n ) {\n if (ifInBrowser) {\n throw new Error('langfuse is not supported in browser');\n }\n warnClient('DEBUGGING MODE: langfuse wrapper enabled');\n // Use variable to prevent static analysis by bundlers\n const langfuseModule = '@langfuse/openai';\n const { observeOpenAI } = await import(langfuseModule);\n openai = observeOpenAI(openai);\n }\n\n if (createOpenAIClient) {\n const wrappedClient = await createOpenAIClient(baseOpenAI, openAIOptions);\n\n if (wrappedClient) {\n openai = wrappedClient as OpenAI;\n }\n }\n\n return {\n completion: openai.chat.completions,\n modelName,\n modelDescription,\n uiTarsModelVersion,\n modelFamily,\n };\n}\n\nexport async function callAI(\n messages: ChatCompletionMessageParam[],\n modelConfig: IModelConfig,\n options?: {\n stream?: boolean;\n onChunk?: StreamingCallback;\n abortSignal?: AbortSignal;\n },\n): Promise<{\n content: string;\n reasoning_content?: string;\n usage?: AIUsageInfo;\n isStreamed: boolean;\n}> {\n if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) {\n if (\n !modelConfig.modelFamily &&\n hasExplicitReasoningConfig({\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n })\n ) {\n throw new Error(\n 'Reasoning config requires MIDSCENE_MODEL_FAMILY. Set MIDSCENE_MODEL_FAMILY when using MIDSCENE_MODEL_REASONING_ENABLED / MIDSCENE_MODEL_REASONING_EFFORT / MIDSCENE_MODEL_REASONING_BUDGET.',\n );\n }\n\n return callAIWithCodexAppServer(messages, modelConfig, {\n stream: options?.stream,\n onChunk: options?.onChunk,\n reasoningEnabled: modelConfig.reasoningEnabled,\n abortSignal: options?.abortSignal,\n });\n }\n\n const {\n completion,\n modelName,\n modelDescription,\n uiTarsModelVersion,\n modelFamily,\n } = await createChatClient({\n modelConfig,\n });\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig);\n\n const extraBody = modelConfig.extraBody;\n\n const maxTokens =\n globalConfigManager.getEnvConfigValueAsNumber(MIDSCENE_MODEL_MAX_TOKENS) ??\n globalConfigManager.getEnvConfigValueAsNumber(OPENAI_MAX_TOKENS);\n const debugCall = getDebug('ai:call');\n const warnCall = getDebug('ai:call', { console: true });\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n\n const startTime = Date.now();\n\n const temperature = (() => {\n if (modelFamily === 'gpt-5') {\n debugCall('temperature is ignored for gpt-5');\n return undefined;\n }\n return modelConfig.temperature ?? 0;\n })();\n\n const isStreaming = options?.stream && options?.onChunk;\n let content: string | undefined;\n let accumulated = '';\n let accumulatedReasoning = '';\n let usage: OpenAI.CompletionUsage | undefined;\n let timeCost: number | undefined;\n let requestId: string | null | undefined;\n\n const hasUsableText = (value: string | null | undefined): value is string =>\n typeof value === 'string' && value.trim().length > 0;\n\n const buildUsageInfo = (\n usageData?: OpenAI.CompletionUsage,\n requestId?: string | null,\n ) => {\n if (!usageData) return undefined;\n\n const cachedInputTokens = (\n usageData as { prompt_tokens_details?: { cached_tokens?: number } }\n )?.prompt_tokens_details?.cached_tokens;\n\n return {\n prompt_tokens: usageData.prompt_tokens ?? 0,\n completion_tokens: usageData.completion_tokens ?? 0,\n total_tokens: usageData.total_tokens ?? 0,\n cached_input: cachedInputTokens ?? 0,\n time_cost: timeCost ?? 0,\n model_name: modelName,\n model_description: modelDescription,\n slot: modelConfig.slot,\n intent: undefined,\n request_id: requestId ?? undefined,\n } satisfies AIUsageInfo;\n };\n\n const commonConfig = {\n temperature,\n stream: !!isStreaming,\n max_tokens: maxTokens,\n ...(modelFamily === 'qwen2.5-vl' // qwen vl v2 specific config\n ? {\n vl_high_resolution_images: true,\n }\n : {}),\n };\n\n if (isAutoGLM(modelFamily)) {\n (commonConfig as unknown as Record<string, number>).top_p = 0.85;\n (commonConfig as unknown as Record<string, number>).frequency_penalty = 0.2;\n }\n\n const {\n config: reasoningEffortConfig,\n debugMessage: reasoningEffortDebugMessage,\n } = resolveReasoningConfig({\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n modelFamily,\n });\n if (reasoningEffortDebugMessage) {\n debugCall(reasoningEffortDebugMessage);\n }\n\n const shouldUseOriginalImageDetail =\n shouldForceOriginalImageDetail(modelConfig);\n\n // For default-intent GPT-5 calls, request original image detail to preserve\n // screenshot resolution for localization-sensitive tasks.\n const messagesWithImageDetail: ChatCompletionMessageParam[] = (() => {\n if (!shouldUseOriginalImageDetail) {\n return messages;\n }\n\n return messages.map((msg) => {\n if (!Array.isArray(msg.content)) {\n return msg;\n }\n\n const content = msg.content.map((part) => {\n if (part && part.type === 'image_url' && part.image_url?.url) {\n return {\n ...part,\n image_url: {\n ...part.image_url,\n detail: 'original',\n },\n };\n }\n return part;\n });\n\n return {\n ...msg,\n content,\n } as ChatCompletionMessageParam;\n });\n })();\n\n try {\n debugCall(\n `sending ${isStreaming ? 'streaming ' : ''}request to ${modelName}`,\n );\n debugCall(\n `request messages:\\n${formatAIRequestMessagesForDebug(\n messagesWithImageDetail,\n )}`,\n );\n\n if (isStreaming) {\n const { signal: streamSignal, cleanup: cleanupStreamSignal } =\n buildRequestAbortSignal(effectiveTimeoutMs, options?.abortSignal);\n try {\n const stream = (await completion.create(\n {\n model: modelName,\n messages: messagesWithImageDetail,\n ...commonConfig,\n ...reasoningEffortConfig,\n ...extraBody,\n },\n {\n stream: true,\n signal: streamSignal,\n },\n )) as Stream<OpenAI.Chat.Completions.ChatCompletionChunk> & {\n _request_id?: string | null;\n };\n\n requestId = stream._request_id;\n\n for await (const chunk of stream) {\n const content = chunk.choices?.[0]?.delta?.content || '';\n const reasoning_content =\n (chunk.choices?.[0]?.delta as any)?.reasoning_content || '';\n\n // Check for usage info in any chunk (OpenAI provides usage in separate chunks)\n if (chunk.usage) {\n usage = chunk.usage;\n }\n\n if (content || reasoning_content) {\n accumulated += content;\n accumulatedReasoning += reasoning_content;\n const chunkData: CodeGenerationChunk = {\n content,\n reasoning_content,\n accumulated,\n isComplete: false,\n usage: undefined,\n };\n options.onChunk!(chunkData);\n }\n\n // Check if stream is complete\n if (chunk.choices?.[0]?.finish_reason) {\n timeCost = Date.now() - startTime;\n\n // If usage is not available from the stream, provide a basic usage info\n if (!usage) {\n // Estimate token counts based on content length (rough approximation)\n const estimatedTokens = Math.max(\n 1,\n Math.floor(accumulated.length / 4),\n );\n usage = {\n prompt_tokens: estimatedTokens,\n completion_tokens: estimatedTokens,\n total_tokens: estimatedTokens * 2,\n };\n }\n\n // Send final chunk\n const finalChunk: CodeGenerationChunk = {\n content: '',\n accumulated,\n reasoning_content: '',\n isComplete: true,\n usage: buildUsageInfo(usage, requestId),\n };\n options.onChunk!(finalChunk);\n break;\n }\n }\n } finally {\n cleanupStreamSignal();\n }\n content = accumulated;\n debugProfileStats(\n `streaming model, ${modelName}, mode, ${modelFamily || 'default'}, cost-ms, ${timeCost}, temperature, ${temperature ?? ''}`,\n );\n } else {\n // Non-streaming with retry logic\n const retryCount = modelConfig.retryCount ?? 1;\n const retryInterval = modelConfig.retryInterval ?? 2000;\n const maxAttempts = retryCount + 1; // retryCount=1 means 2 total attempts (1 initial + 1 retry)\n\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const { signal: attemptSignal, cleanup: cleanupAttemptSignal } =\n buildRequestAbortSignal(effectiveTimeoutMs, options?.abortSignal);\n try {\n const result = await completion.create(\n {\n model: modelName,\n messages: messagesWithImageDetail,\n ...commonConfig,\n ...reasoningEffortConfig,\n ...extraBody,\n } as any,\n { signal: attemptSignal },\n );\n\n timeCost = Date.now() - startTime;\n\n debugProfileStats(\n `model, ${modelName}, mode, ${modelFamily || 'default'}, ui-tars-version, ${uiTarsModelVersion}, prompt-tokens, ${result.usage?.prompt_tokens || ''}, completion-tokens, ${result.usage?.completion_tokens || ''}, total-tokens, ${result.usage?.total_tokens || ''}, cost-ms, ${timeCost}, requestId, ${result._request_id || ''}, temperature, ${temperature ?? ''}`,\n );\n\n debugProfileDetail(\n `model usage detail: ${JSON.stringify(result.usage)}`,\n );\n\n if (!result.choices) {\n throw new Error(\n `invalid response from LLM service: ${JSON.stringify(result)}`,\n );\n }\n\n content = result.choices[0].message.content!;\n accumulatedReasoning =\n (result.choices[0].message as any)?.reasoning_content || '';\n usage = result.usage;\n requestId = result._request_id;\n\n if (!hasUsableText(content) && hasUsableText(accumulatedReasoning)) {\n warnCall('empty content from AI model, using reasoning content');\n content = accumulatedReasoning;\n }\n\n if (!hasUsableText(content)) {\n throw new AIResponseParseError(\n 'empty content from AI model',\n JSON.stringify(result),\n buildUsageInfo(usage, requestId),\n );\n }\n\n break; // Success, exit retry loop\n } catch (error) {\n lastError = error as Error;\n const wasHardTimeout = isHardTimeoutError(lastError);\n if (wasHardTimeout) {\n warnCall(\n `AI call hit hard timeout (${effectiveTimeoutMs}ms, attempt ${attempt}/${maxAttempts}, model ${modelName}, slot ${modelConfig.slot})`,\n );\n }\n // Do not retry if the request was aborted by the caller\n if (options?.abortSignal?.aborted) {\n break;\n }\n if (attempt < maxAttempts) {\n warnCall(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n await new Promise((resolve) => setTimeout(resolve, retryInterval));\n }\n } finally {\n cleanupAttemptSignal();\n }\n }\n\n if (!content) {\n throw lastError;\n }\n }\n\n debugCall(`response reasoning content: ${accumulatedReasoning}`);\n debugCall(`response content: ${content}`);\n\n // Ensure we always have usage info for streaming responses\n if (isStreaming && !usage) {\n // Estimate token counts based on content length (rough approximation)\n const estimatedTokens = Math.max(\n 1,\n Math.floor((content || '').length / 4),\n );\n usage = {\n prompt_tokens: estimatedTokens,\n completion_tokens: estimatedTokens,\n total_tokens: estimatedTokens * 2,\n } as OpenAI.CompletionUsage;\n }\n\n return {\n content: content || '',\n reasoning_content: accumulatedReasoning || undefined,\n usage: buildUsageInfo(usage, requestId),\n isStreamed: !!isStreaming,\n };\n } catch (e: any) {\n warnCall('call AI error', e);\n\n if (e instanceof AIResponseParseError) {\n throw e;\n }\n\n const newError = new Error(\n `failed to call ${isStreaming ? 'streaming ' : ''}AI model service (${modelName}): ${e.message}\\nTrouble shooting: https://midscenejs.com/model-provider.html`,\n {\n cause: e,\n },\n );\n throw newError;\n }\n}\n\nexport async function callAIWithObjectResponse<T>(\n messages: ChatCompletionMessageParam[],\n modelConfig: IModelConfig,\n options?: {\n abortSignal?: AbortSignal;\n },\n): Promise<{\n content: T;\n contentString: string;\n usage?: AIUsageInfo;\n reasoning_content?: string;\n}> {\n const response = await callAI(messages, modelConfig, {\n abortSignal: options?.abortSignal,\n });\n assert(response, 'empty response');\n const modelFamily = modelConfig.modelFamily;\n const jsonContent = safeParseJson(response.content, modelFamily);\n if (typeof jsonContent !== 'object') {\n throw new AIResponseParseError(\n `failed to parse json response from model (${modelConfig.modelName}): ${response.content}`,\n response.content,\n response.usage,\n );\n }\n return {\n content: jsonContent,\n contentString: response.content,\n usage: response.usage,\n reasoning_content: response.reasoning_content,\n };\n}\n\nexport async function callAIWithStringResponse(\n msgs: AIArgs,\n modelConfig: IModelConfig,\n options?: {\n abortSignal?: AbortSignal;\n },\n): Promise<{ content: string; usage?: AIUsageInfo }> {\n const { content, usage } = await callAI(msgs, modelConfig, {\n abortSignal: options?.abortSignal,\n });\n return { content, usage };\n}\n\nexport function extractJSONFromCodeBlock(response: string) {\n try {\n // First, try to match a JSON object directly in the response\n const jsonMatch = response.match(/^\\s*(\\{[\\s\\S]*\\})\\s*$/);\n if (jsonMatch) {\n return jsonMatch[1];\n }\n\n // If no direct JSON object is found, try to extract JSON from a code block\n const codeBlockMatch = response.match(\n /```(?:json)?\\s*(\\{[\\s\\S]*?\\})\\s*```/,\n );\n if (codeBlockMatch) {\n return codeBlockMatch[1];\n }\n\n // If no code block is found, try to find a JSON-like structure in the text\n const jsonLikeMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonLikeMatch) {\n return jsonLikeMatch[0];\n }\n } catch {}\n // If no JSON-like structure is found, return the original response\n return response;\n}\n\nexport function preprocessDoubaoBboxJson(input: string) {\n if (input.includes('bbox')) {\n // when its values like 940 445 969 490, replace all /\\d+\\s+\\d+/g with /$1,$2/g\n while (/\\d+\\s+\\d+/.test(input)) {\n input = input.replace(/(\\d+)\\s+(\\d+)/g, '$1,$2');\n }\n }\n return input;\n}\n\nfunction hasExplicitReasoningConfig({\n reasoningEnabled,\n reasoningEffort,\n reasoningBudget,\n}: {\n reasoningEnabled?: boolean;\n reasoningEffort?: string;\n reasoningBudget?: number;\n}): boolean {\n return (\n reasoningEnabled !== undefined ||\n !!reasoningEffort ||\n reasoningBudget !== undefined\n );\n}\n\nconst SUPPORTED_REASONING_FAMILIES = [\n 'qwen3-vl',\n 'qwen3.5',\n 'qwen3.6',\n 'doubao-vision',\n 'doubao-seed',\n 'glm-v',\n] as const satisfies readonly TModelFamily[];\n\ntype SupportedReasoningFamily = (typeof SUPPORTED_REASONING_FAMILIES)[number];\n\nfunction isSupportedReasoningFamily(\n family: TModelFamily | undefined,\n): family is SupportedReasoningFamily {\n return (\n !!family &&\n (SUPPORTED_REASONING_FAMILIES as readonly TModelFamily[]).includes(family)\n );\n}\n\nfunction supportedReasoningFamilyNames(): string {\n return SUPPORTED_REASONING_FAMILIES.join(', ');\n}\n\nexport function resolveReasoningConfig({\n reasoningEnabled,\n reasoningEffort,\n reasoningBudget,\n modelFamily,\n}: {\n reasoningEnabled?: boolean;\n reasoningEffort?: string;\n reasoningBudget?: number;\n modelFamily?: TModelFamily;\n}): {\n config: Record<string, unknown>;\n debugMessage?: string;\n} {\n const hasExplicitConfig = hasExplicitReasoningConfig({\n reasoningEnabled,\n reasoningEffort,\n reasoningBudget,\n });\n\n if (hasExplicitConfig) {\n if (!modelFamily) {\n throw new Error(\n `Reasoning config requires MIDSCENE_MODEL_FAMILY. Set MIDSCENE_MODEL_FAMILY to a supported family such as ${supportedReasoningFamilyNames()}, or remove MIDSCENE_MODEL_REASONING_ENABLED / MIDSCENE_MODEL_REASONING_EFFORT / MIDSCENE_MODEL_REASONING_BUDGET.`,\n );\n }\n\n // GPT-5 over Chat Completions is intentionally unsupported here because\n // its reasoning effort compatibility varies by model version.\n if (!isSupportedReasoningFamily(modelFamily)) {\n throw new Error(\n `Reasoning config is not supported for model family \"${modelFamily}\". Use a supported family such as ${supportedReasoningFamilyNames()}, or remove MIDSCENE_MODEL_REASONING_ENABLED / MIDSCENE_MODEL_REASONING_EFFORT / MIDSCENE_MODEL_REASONING_BUDGET.`,\n );\n }\n } else if (!isSupportedReasoningFamily(modelFamily)) {\n return { config: {} };\n }\n\n const effectiveReasoningEnabled = reasoningEnabled ?? false;\n\n const debugMessages: string[] = [];\n const config: Record<string, unknown> = {};\n\n if (\n modelFamily === 'qwen3-vl' ||\n modelFamily === 'qwen3.5' ||\n modelFamily === 'qwen3.6'\n ) {\n // reasoningEnabled → enable_thinking\n config.enable_thinking = effectiveReasoningEnabled;\n debugMessages.push(`enable_thinking=${effectiveReasoningEnabled}`);\n // reasoningBudget → thinking_budget\n if (reasoningBudget !== undefined) {\n config.thinking_budget = reasoningBudget;\n debugMessages.push(`thinking_budget=${reasoningBudget}`);\n }\n // reasoningEffort is ignored for qwen\n } else if (modelFamily === 'doubao-vision' || modelFamily === 'doubao-seed') {\n // reasoningEnabled → thinking.type\n config.thinking = {\n type: effectiveReasoningEnabled ? 'enabled' : 'disabled',\n };\n debugMessages.push(\n `thinking.type=${effectiveReasoningEnabled ? 'enabled' : 'disabled'}`,\n );\n // reasoningEffort → reasoning_effort\n if (reasoningEffort) {\n config.reasoning_effort = reasoningEffort;\n debugMessages.push(`reasoning_effort=\"${reasoningEffort}\"`);\n }\n // reasoningBudget is ignored for doubao\n } else if (modelFamily === 'glm-v') {\n // reasoningEnabled → thinking.type\n config.thinking = {\n type: effectiveReasoningEnabled ? 'enabled' : 'disabled',\n };\n debugMessages.push(\n `thinking.type=${effectiveReasoningEnabled ? 'enabled' : 'disabled'}`,\n );\n // reasoningEffort and reasoningBudget are ignored for glm-v\n }\n\n return {\n config,\n debugMessage: debugMessages.length\n ? `reasoning config for ${modelFamily}: ${debugMessages.join(', ')}`\n : undefined,\n };\n}\n\n/**\n * Normalize a parsed JSON object by trimming whitespace from:\n * 1. All object keys (e.g., \" prompt \" -> \"prompt\")\n * 2. All string values (e.g., \" Tap \" -> \"Tap\")\n * This handles LLM output that may include leading/trailing spaces.\n */\nfunction normalizeJsonObject(obj: any): any {\n // Handle null and undefined\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n // Handle arrays - recursively normalize each element\n if (Array.isArray(obj)) {\n return obj.map((item) => normalizeJsonObject(item));\n }\n\n // Handle objects\n if (typeof obj === 'object') {\n const normalized: any = {};\n\n for (const [key, value] of Object.entries(obj)) {\n // Trim the key to remove leading/trailing spaces\n const trimmedKey = key.trim();\n\n // Recursively normalize the value\n let normalizedValue = normalizeJsonObject(value);\n\n // Trim all string values\n if (typeof normalizedValue === 'string') {\n normalizedValue = normalizedValue.trim();\n }\n\n normalized[trimmedKey] = normalizedValue;\n }\n\n return normalized;\n }\n\n // Handle primitive strings\n if (typeof obj === 'string') {\n return obj.trim();\n }\n\n // Return other primitives as-is\n return obj;\n}\n\nexport function safeParseJson(\n input: string,\n modelFamily: TModelFamily | undefined,\n) {\n const cleanJsonString = extractJSONFromCodeBlock(input);\n // match the point\n if (cleanJsonString?.match(/\\((\\d+),(\\d+)\\)/)) {\n return cleanJsonString\n .match(/\\((\\d+),(\\d+)\\)/)\n ?.slice(1)\n .map(Number);\n }\n\n let parsed: any;\n let lastError: unknown;\n try {\n parsed = JSON.parse(cleanJsonString);\n return normalizeJsonObject(parsed);\n } catch (error) {\n lastError = error;\n }\n try {\n parsed = JSON.parse(jsonrepair(cleanJsonString));\n return normalizeJsonObject(parsed);\n } catch (error) {\n lastError = error;\n }\n\n if (\n modelFamily === 'doubao-vision' ||\n modelFamily === 'doubao-seed' ||\n isUITars(modelFamily)\n ) {\n const jsonString = preprocessDoubaoBboxJson(cleanJsonString);\n try {\n parsed = JSON.parse(jsonrepair(jsonString));\n return normalizeJsonObject(parsed);\n } catch (error) {\n lastError = error;\n }\n }\n throw Error(\n `failed to parse LLM response into JSON. Error - ${String(\n lastError ?? 'unknown error',\n )}. Response - \\n ${input}`,\n );\n}\n"],"names":["AIResponseParseError","Error","message","rawResponse","usage","formatAIRequestMessagesForDebug","messages","index","role","formatAIMessageContentForDebug","content","Array","safeStringifyForDebug","part","record","redactImagesForDebug","value","item","result","key","Object","undefined","JSON","String","createChatClient","modelConfig","socksProxy","httpProxy","modelName","openaiBaseURL","openaiApiKey","openaiExtraConfig","modelDescription","uiTarsModelVersion","modelFamily","createOpenAIClient","timeout","proxyAgent","warnClient","getDebug","debugProxy","warnProxy","sanitizeProxyUrl","url","parsed","URL","ifInBrowser","moduleName","ProxyAgent","socksDispatcher","proxyUrl","port","Number","protocol","socksType","decodeURIComponent","error","effectiveTimeoutMs","resolveEffectiveTimeoutMs","openAIOptions","baseOpenAI","OpenAI","openai","globalConfigManager","MIDSCENE_LANGSMITH_DEBUG","langsmithModule","wrapOpenAI","MIDSCENE_LANGFUSE_DEBUG","langfuseModule","observeOpenAI","wrappedClient","callAI","options","isCodexAppServerProvider","hasExplicitReasoningConfig","callAIWithCodexAppServer","completion","extraBody","maxTokens","MIDSCENE_MODEL_MAX_TOKENS","OPENAI_MAX_TOKENS","debugCall","warnCall","debugProfileStats","debugProfileDetail","startTime","Date","temperature","isStreaming","accumulated","accumulatedReasoning","timeCost","requestId","hasUsableText","buildUsageInfo","usageData","cachedInputTokens","commonConfig","isAutoGLM","reasoningEffortConfig","reasoningEffortDebugMessage","resolveReasoningConfig","shouldUseOriginalImageDetail","shouldForceOriginalImageDetail","messagesWithImageDetail","msg","streamSignal","cleanupStreamSignal","buildRequestAbortSignal","stream","chunk","reasoning_content","chunkData","estimatedTokens","Math","finalChunk","retryCount","retryInterval","maxAttempts","lastError","attempt","attemptSignal","cleanupAttemptSignal","wasHardTimeout","isHardTimeoutError","Promise","resolve","setTimeout","e","newError","callAIWithObjectResponse","response","assert","jsonContent","safeParseJson","callAIWithStringResponse","msgs","extractJSONFromCodeBlock","jsonMatch","codeBlockMatch","jsonLikeMatch","preprocessDoubaoBboxJson","input","reasoningEnabled","reasoningEffort","reasoningBudget","SUPPORTED_REASONING_FAMILIES","isSupportedReasoningFamily","family","supportedReasoningFamilyNames","hasExplicitConfig","effectiveReasoningEnabled","debugMessages","config","normalizeJsonObject","obj","normalized","trimmedKey","normalizedValue","cleanJsonString","jsonrepair","isUITars","jsonString"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/service-caller/index.mjs","sources":["../../../../src/ai-model/service-caller/index.ts"],"sourcesContent":["import type { AIUsageInfo } from '@/types';\nimport type { CodeGenerationChunk, StreamingCallback } from '@/types';\n\n// Error class that preserves usage and rawResponse when AI call parsing fails\nexport class AIResponseParseError extends Error {\n usage?: AIUsageInfo;\n rawResponse: string;\n rawChoiceMessage?: unknown;\n reasoningContent?: string;\n\n constructor(\n message: string,\n rawResponse: string,\n usage?: AIUsageInfo,\n rawChoiceMessage?: unknown,\n reasoningContent?: string,\n ) {\n super(message);\n this.name = 'AIResponseParseError';\n this.rawResponse = rawResponse;\n this.usage = usage;\n this.rawChoiceMessage = rawChoiceMessage;\n this.reasoningContent = reasoningContent;\n }\n}\nimport {\n type IModelConfig,\n MIDSCENE_LANGFUSE_DEBUG,\n MIDSCENE_LANGSMITH_DEBUG,\n MIDSCENE_MODEL_MAX_TOKENS,\n OPENAI_MAX_TOKENS,\n type TModelFamily,\n type TModelReasoningEnabled,\n type UITarsModelVersion,\n globalConfigManager,\n} from '@aiscene/shared/env';\n\nimport { getDebug } from '@aiscene/shared/logger';\nimport { assert, ifInBrowser } from '@aiscene/shared/utils';\nimport { jsonrepair } from 'jsonrepair';\nimport OpenAI from 'openai';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { Stream } from 'openai/streaming';\nimport type { AIArgs } from '../../common';\nimport { isAutoGLM, isUITars } from '../auto-glm/util';\nimport type { ModelRuntime } from '../models';\nimport {\n callAIWithCodexAppServer,\n isCodexAppServerProvider,\n} from './codex-app-server';\nimport { shouldForceOriginalImageDetail } from './image-detail';\nimport {\n buildRequestAbortSignal,\n isHardTimeoutError,\n resolveEffectiveTimeoutMs,\n} from './request-timeout';\n\ntype ModelRuntimeInput = IModelConfig | ModelRuntime;\n\nfunction resolveModelConfig(input: ModelRuntimeInput): IModelConfig {\n return 'config' in input ? input.config : input;\n}\n\nfunction formatAIRequestMessagesForDebug(\n messages: ChatCompletionMessageParam[],\n): string {\n return messages\n .map((message, index) => {\n const role =\n typeof (message as { role?: unknown }).role === 'string'\n ? (message as { role: string }).role\n : 'unknown';\n return `#${index + 1} role=${role}\\n${formatAIMessageContentForDebug(\n (message as { content?: unknown }).content,\n )}`;\n })\n .join('\\n---\\n');\n}\n\nfunction formatAIMessageContentForDebug(content: unknown): string {\n if (typeof content === 'string') {\n return content;\n }\n\n if (!Array.isArray(content)) {\n return safeStringifyForDebug(content);\n }\n\n return content\n .map((part) => {\n if (!part || typeof part !== 'object') {\n return safeStringifyForDebug(part);\n }\n\n const record = part as Record<string, unknown>;\n if (record.type === 'image_url') {\n return '[image omitted]';\n }\n if (typeof record.text === 'string') {\n return record.text;\n }\n if (typeof record.input_text === 'string') {\n return record.input_text;\n }\n return safeStringifyForDebug(redactImagesForDebug(record));\n })\n .join('\\n');\n}\n\nfunction redactImagesForDebug(value: unknown): unknown {\n if (Array.isArray(value)) {\n return value.map((item) => redactImagesForDebug(item));\n }\n if (!value || typeof value !== 'object') {\n return value;\n }\n\n const result: Record<string, unknown> = {};\n for (const [key, item] of Object.entries(value)) {\n result[key] =\n key === 'url' || key === 'image_url'\n ? '[image omitted]'\n : redactImagesForDebug(item);\n }\n return result;\n}\n\nfunction safeStringifyForDebug(value: unknown): string {\n if (value === undefined) {\n return '';\n }\n try {\n return JSON.stringify(value);\n } catch {\n return String(value);\n }\n}\n\nasync function createChatClient({\n modelConfig,\n}: {\n modelConfig: IModelConfig;\n}): Promise<{\n completion: OpenAI.Chat.Completions;\n modelName: string;\n modelDescription: string;\n uiTarsModelVersion?: UITarsModelVersion;\n modelFamily: TModelFamily | undefined;\n}> {\n const {\n socksProxy,\n httpProxy,\n modelName,\n openaiBaseURL,\n openaiApiKey,\n openaiExtraConfig,\n modelDescription,\n uiTarsModelVersion,\n modelFamily,\n createOpenAIClient,\n timeout,\n } = modelConfig;\n\n let proxyAgent: any = undefined;\n const warnClient = getDebug('ai:call', { console: true });\n const debugProxy = getDebug('ai:call:proxy');\n const warnProxy = getDebug('ai:call:proxy', { console: true });\n\n // Helper function to sanitize proxy URL for logging (remove credentials)\n // Uses URL API instead of regex to avoid ReDoS vulnerabilities\n const sanitizeProxyUrl = (url: string): string => {\n try {\n const parsed = new URL(url);\n if (parsed.username) {\n // Keep username for debugging, hide password for security\n parsed.password = '****';\n return parsed.href;\n }\n return url;\n } catch {\n // If URL parsing fails, return original URL (will be caught later)\n return url;\n }\n };\n\n if (httpProxy) {\n debugProxy('using http proxy', sanitizeProxyUrl(httpProxy));\n if (ifInBrowser) {\n warnProxy(\n 'HTTP proxy is configured but not supported in browser environment',\n );\n } else {\n // Dynamic import with variable to avoid bundler static analysis\n const moduleName = 'undici';\n const { ProxyAgent } = await import(moduleName);\n proxyAgent = new ProxyAgent({\n uri: httpProxy,\n // Note: authentication is handled via the URI (e.g., http://user:pass@proxy.com:8080)\n });\n }\n } else if (socksProxy) {\n debugProxy('using socks proxy', sanitizeProxyUrl(socksProxy));\n if (ifInBrowser) {\n warnProxy(\n 'SOCKS proxy is configured but not supported in browser environment',\n );\n } else {\n try {\n // Dynamic import with variable to avoid bundler static analysis\n const moduleName = 'fetch-socks';\n const { socksDispatcher } = await import(moduleName);\n // Parse SOCKS proxy URL (e.g., socks5://127.0.0.1:1080)\n const proxyUrl = new URL(socksProxy);\n\n // Validate hostname\n if (!proxyUrl.hostname) {\n throw new Error('SOCKS proxy URL must include a valid hostname');\n }\n\n // Validate and parse port\n const port = Number.parseInt(proxyUrl.port, 10);\n if (!proxyUrl.port || Number.isNaN(port)) {\n throw new Error('SOCKS proxy URL must include a valid port');\n }\n\n // Parse SOCKS version from protocol\n const protocol = proxyUrl.protocol.replace(':', '');\n const socksType =\n protocol === 'socks4' ? 4 : protocol === 'socks5' ? 5 : 5;\n\n proxyAgent = socksDispatcher({\n type: socksType,\n host: proxyUrl.hostname,\n port,\n ...(proxyUrl.username\n ? {\n userId: decodeURIComponent(proxyUrl.username),\n password: decodeURIComponent(proxyUrl.password || ''),\n }\n : {}),\n });\n debugProxy('socks proxy configured successfully', {\n type: socksType,\n host: proxyUrl.hostname,\n port: port,\n });\n } catch (error) {\n warnProxy('Failed to configure SOCKS proxy:', error);\n throw new Error(\n `Invalid SOCKS proxy URL: ${socksProxy}. Expected format: socks4://host:port, socks5://host:port, or with authentication: socks5://user:pass@host:port`,\n );\n }\n }\n }\n\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs({ timeout });\n const openAIOptions = {\n baseURL: openaiBaseURL,\n apiKey: openaiApiKey,\n // Use fetchOptions.dispatcher for fetch-based SDK instead of httpAgent\n // Note: Type assertion needed due to undici version mismatch between dependencies\n ...(proxyAgent ? { fetchOptions: { dispatcher: proxyAgent as any } } : {}),\n ...openaiExtraConfig,\n // Midscene already handles retries in callAI(), so disable SDK-level retries\n // to avoid duplicate attempts and duplicated backoff latency.\n maxRetries: 0,\n // When disabled (timeoutMs === null) fall through to the SDK default so\n // only the caller-provided abortSignal can cancel the request.\n ...(effectiveTimeoutMs !== null ? { timeout: effectiveTimeoutMs } : {}),\n dangerouslyAllowBrowser: true,\n };\n\n const baseOpenAI = new OpenAI(openAIOptions);\n\n let openai: OpenAI = baseOpenAI;\n\n // LangSmith wrapper\n if (\n openai &&\n globalConfigManager.getEnvConfigInBoolean(MIDSCENE_LANGSMITH_DEBUG)\n ) {\n if (ifInBrowser) {\n throw new Error('langsmith is not supported in browser');\n }\n warnClient('DEBUGGING MODE: langsmith wrapper enabled');\n // Use variable to prevent static analysis by bundlers\n const langsmithModule = 'langsmith/wrappers';\n const { wrapOpenAI } = await import(langsmithModule);\n openai = wrapOpenAI(openai);\n }\n\n // Langfuse wrapper\n if (\n openai &&\n globalConfigManager.getEnvConfigInBoolean(MIDSCENE_LANGFUSE_DEBUG)\n ) {\n if (ifInBrowser) {\n throw new Error('langfuse is not supported in browser');\n }\n warnClient('DEBUGGING MODE: langfuse wrapper enabled');\n // Use variable to prevent static analysis by bundlers\n const langfuseModule = '@langfuse/openai';\n const { observeOpenAI } = await import(langfuseModule);\n openai = observeOpenAI(openai);\n }\n\n if (createOpenAIClient) {\n const wrappedClient = await createOpenAIClient(baseOpenAI, openAIOptions);\n\n if (wrappedClient) {\n openai = wrappedClient as OpenAI;\n }\n }\n\n return {\n completion: openai.chat.completions,\n modelName,\n modelDescription,\n uiTarsModelVersion,\n modelFamily,\n };\n}\n\nexport async function callAI(\n messages: ChatCompletionMessageParam[],\n modelRuntimeOrConfig: ModelRuntimeInput,\n options?: {\n stream?: boolean;\n onChunk?: StreamingCallback;\n abortSignal?: AbortSignal;\n requiresOriginalImageDetail?: boolean;\n expectedJsonObjectResponse?: boolean;\n semanticRetryAttempt?: number;\n },\n): Promise<{\n content: string;\n reasoning_content?: string;\n rawChoiceMessage?: unknown;\n usage?: AIUsageInfo;\n isStreamed: boolean;\n}> {\n const modelConfig = resolveModelConfig(modelRuntimeOrConfig);\n const codexReasoningEnabled =\n modelConfig.reasoningEnabled === 'default'\n ? undefined\n : modelConfig.reasoningEnabled;\n if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) {\n if (\n !modelConfig.modelFamily &&\n hasExplicitReasoningConfig({\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n })\n ) {\n throw new Error(\n 'Reasoning config requires MIDSCENE_MODEL_FAMILY. Set MIDSCENE_MODEL_FAMILY when using MIDSCENE_MODEL_REASONING_ENABLED / MIDSCENE_MODEL_REASONING_EFFORT / MIDSCENE_MODEL_REASONING_BUDGET.',\n );\n }\n\n return callAIWithCodexAppServer(messages, modelConfig, {\n stream: options?.stream,\n onChunk: options?.onChunk,\n reasoningEnabled: codexReasoningEnabled,\n abortSignal: options?.abortSignal,\n });\n }\n\n const {\n completion,\n modelName,\n modelDescription,\n uiTarsModelVersion,\n modelFamily,\n } = await createChatClient({\n modelConfig,\n });\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig);\n\n const extraBody = modelConfig.extraBody;\n\n const maxTokens =\n globalConfigManager.getEnvConfigValueAsNumber(MIDSCENE_MODEL_MAX_TOKENS) ??\n globalConfigManager.getEnvConfigValueAsNumber(OPENAI_MAX_TOKENS);\n const debugCall = getDebug('ai:call');\n const warnCall = getDebug('ai:call', { console: true });\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n\n const startTime = Date.now();\n\n const temperature = (() => {\n if (modelFamily === 'gpt-5') {\n debugCall('temperature is ignored for gpt-5');\n return undefined;\n }\n return modelConfig.temperature ?? 0;\n })();\n\n const isStreaming = options?.stream && options?.onChunk;\n let content: string | undefined;\n let accumulated = '';\n let accumulatedReasoning = '';\n let rawChoiceMessage: unknown;\n let usage: OpenAI.CompletionUsage | undefined;\n let timeCost: number | undefined;\n let requestId: string | null | undefined;\n let responseModelName: string | undefined;\n\n const hasUsableText = (value: string | null | undefined): value is string =>\n typeof value === 'string' && value.trim().length > 0;\n\n const buildUsageInfo = (\n usageData?: OpenAI.CompletionUsage,\n requestId?: string | null,\n ) => {\n if (!usageData) return undefined;\n\n const cachedInputTokens = (\n usageData as { prompt_tokens_details?: { cached_tokens?: number } }\n )?.prompt_tokens_details?.cached_tokens;\n\n return {\n prompt_tokens: usageData.prompt_tokens ?? 0,\n completion_tokens: usageData.completion_tokens ?? 0,\n total_tokens: usageData.total_tokens ?? 0,\n cached_input: cachedInputTokens ?? 0,\n time_cost: timeCost ?? 0,\n model_name: modelName,\n model_description: modelDescription,\n response_model_name: responseModelName,\n slot: modelConfig.slot,\n intent: undefined,\n request_id: requestId ?? undefined,\n } satisfies AIUsageInfo;\n };\n\n const commonConfig = {\n temperature,\n stream: !!isStreaming,\n max_tokens: maxTokens,\n ...(modelFamily === 'qwen2.5-vl' // qwen vl v2 specific config\n ? {\n vl_high_resolution_images: true,\n }\n : {}),\n };\n\n if (isAutoGLM(modelFamily)) {\n (commonConfig as unknown as Record<string, number>).top_p = 0.85;\n (commonConfig as unknown as Record<string, number>).frequency_penalty = 0.2;\n }\n\n const {\n config: reasoningEffortConfig,\n debugMessage: reasoningEffortDebugMessage,\n } = resolveReasoningConfig({\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n modelFamily,\n });\n if (reasoningEffortDebugMessage) {\n debugCall(reasoningEffortDebugMessage);\n }\n\n const shouldUseOriginalImageDetail =\n shouldForceOriginalImageDetail(modelConfig);\n\n // For default-intent GPT-5 calls, request original image detail to preserve\n // screenshot resolution for localization-sensitive tasks.\n const messagesWithImageDetail: ChatCompletionMessageParam[] = (() => {\n if (!shouldUseOriginalImageDetail) {\n return messages;\n }\n\n return messages.map((msg) => {\n if (!Array.isArray(msg.content)) {\n return msg;\n }\n\n const content = msg.content.map((part) => {\n if (part && part.type === 'image_url' && part.image_url?.url) {\n return {\n ...part,\n image_url: {\n ...part.image_url,\n detail: 'original',\n },\n };\n }\n return part;\n });\n\n return {\n ...msg,\n content,\n } as ChatCompletionMessageParam;\n });\n })();\n\n try {\n debugCall(\n `sending ${isStreaming ? 'streaming ' : ''}request to ${modelName}`,\n );\n debugCall(\n `request messages:\\n${formatAIRequestMessagesForDebug(\n messagesWithImageDetail,\n )}`,\n );\n\n if (isStreaming) {\n const { signal: streamSignal, cleanup: cleanupStreamSignal } =\n buildRequestAbortSignal(effectiveTimeoutMs, options?.abortSignal);\n try {\n const stream = (await completion.create(\n {\n model: modelName,\n messages: messagesWithImageDetail,\n ...commonConfig,\n ...reasoningEffortConfig,\n ...extraBody,\n },\n {\n stream: true,\n signal: streamSignal,\n },\n )) as Stream<OpenAI.Chat.Completions.ChatCompletionChunk> & {\n _request_id?: string | null;\n };\n\n requestId = stream._request_id;\n\n for await (const chunk of stream) {\n responseModelName = chunk.model || responseModelName;\n const content = chunk.choices?.[0]?.delta?.content || '';\n const reasoning_content =\n (chunk.choices?.[0]?.delta as any)?.reasoning_content || '';\n\n // Check for usage info in any chunk (OpenAI provides usage in separate chunks)\n if (chunk.usage) {\n usage = chunk.usage;\n }\n\n if (content || reasoning_content) {\n accumulated += content;\n accumulatedReasoning += reasoning_content;\n const chunkData: CodeGenerationChunk = {\n content,\n reasoning_content,\n accumulated,\n isComplete: false,\n usage: undefined,\n };\n options.onChunk!(chunkData);\n }\n\n // Check if stream is complete\n if (chunk.choices?.[0]?.finish_reason) {\n timeCost = Date.now() - startTime;\n\n // If usage is not available from the stream, provide a basic usage info\n if (!usage) {\n // Estimate token counts based on content length (rough approximation)\n const estimatedTokens = Math.max(\n 1,\n Math.floor(accumulated.length / 4),\n );\n usage = {\n prompt_tokens: estimatedTokens,\n completion_tokens: estimatedTokens,\n total_tokens: estimatedTokens * 2,\n };\n }\n\n // Send final chunk\n const finalChunk: CodeGenerationChunk = {\n content: '',\n accumulated,\n reasoning_content: '',\n isComplete: true,\n usage: buildUsageInfo(usage, requestId),\n };\n options.onChunk!(finalChunk);\n break;\n }\n }\n } finally {\n cleanupStreamSignal();\n }\n content = accumulated;\n debugProfileStats(\n `streaming model, ${modelName}, mode, ${modelFamily || 'default'}, cost-ms, ${timeCost}, temperature, ${temperature ?? ''}`,\n );\n } else {\n // Non-streaming with retry logic\n const retryCount = modelConfig.retryCount ?? 1;\n const retryInterval = modelConfig.retryInterval ?? 2000;\n const maxAttempts = retryCount + 1; // retryCount=1 means 2 total attempts (1 initial + 1 retry)\n\n let lastError: Error | undefined;\n\n for (let attempt = 1; attempt <= maxAttempts; attempt++) {\n const { signal: attemptSignal, cleanup: cleanupAttemptSignal } =\n buildRequestAbortSignal(effectiveTimeoutMs, options?.abortSignal);\n try {\n const result = await completion.create(\n {\n model: modelName,\n messages: messagesWithImageDetail,\n ...commonConfig,\n ...reasoningEffortConfig,\n ...extraBody,\n } as any,\n { signal: attemptSignal },\n );\n\n timeCost = Date.now() - startTime;\n responseModelName = result.model || responseModelName;\n\n debugProfileStats(\n `model, ${modelName}, mode, ${modelFamily || 'default'}, ui-tars-version, ${uiTarsModelVersion}, prompt-tokens, ${result.usage?.prompt_tokens || ''}, completion-tokens, ${result.usage?.completion_tokens || ''}, total-tokens, ${result.usage?.total_tokens || ''}, cost-ms, ${timeCost}, requestId, ${result._request_id || ''}, temperature, ${temperature ?? ''}`,\n );\n\n debugProfileDetail(\n `model usage detail: ${JSON.stringify(result.usage)}`,\n );\n\n if (!result.choices) {\n throw new Error(\n `invalid response from LLM service: ${JSON.stringify(result)}`,\n );\n }\n\n rawChoiceMessage = result.choices[0].message;\n content = result.choices[0].message.content!;\n accumulatedReasoning =\n (result.choices[0].message as any)?.reasoning_content || '';\n usage = result.usage;\n requestId = result._request_id;\n\n if (!hasUsableText(content) && hasUsableText(accumulatedReasoning)) {\n warnCall('empty content from AI model, using reasoning content');\n content = accumulatedReasoning;\n }\n\n if (!hasUsableText(content)) {\n throw new AIResponseParseError(\n 'empty content from AI model',\n JSON.stringify(result),\n buildUsageInfo(usage, requestId),\n rawChoiceMessage,\n accumulatedReasoning,\n );\n }\n\n break; // Success, exit retry loop\n } catch (error) {\n lastError = error as Error;\n const wasHardTimeout = isHardTimeoutError(lastError);\n if (wasHardTimeout) {\n warnCall(\n `AI call hit hard timeout (${effectiveTimeoutMs}ms, attempt ${attempt}/${maxAttempts}, model ${modelName}, slot ${modelConfig.slot})`,\n );\n }\n // Do not retry if the request was aborted by the caller\n if (options?.abortSignal?.aborted) {\n break;\n }\n if (attempt < maxAttempts) {\n warnCall(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n await new Promise((resolve) => setTimeout(resolve, retryInterval));\n }\n } finally {\n cleanupAttemptSignal();\n }\n }\n\n if (!content) {\n throw lastError;\n }\n }\n\n debugCall(`response reasoning content: ${accumulatedReasoning}`);\n debugCall(`response content: ${content}`);\n\n // Ensure we always have usage info for streaming responses\n if (isStreaming && !usage) {\n // Estimate token counts based on content length (rough approximation)\n const estimatedTokens = Math.max(\n 1,\n Math.floor((content || '').length / 4),\n );\n usage = {\n prompt_tokens: estimatedTokens,\n completion_tokens: estimatedTokens,\n total_tokens: estimatedTokens * 2,\n } as OpenAI.CompletionUsage;\n }\n\n return {\n content: content || '',\n reasoning_content: accumulatedReasoning || undefined,\n rawChoiceMessage,\n usage: buildUsageInfo(usage, requestId),\n isStreamed: !!isStreaming,\n };\n } catch (e: any) {\n warnCall('call AI error', e);\n\n if (e instanceof AIResponseParseError) {\n throw e;\n }\n\n const newError = new Error(\n `failed to call ${isStreaming ? 'streaming ' : ''}AI model service (${modelName}): ${e.message}\\nTrouble shooting: https://midscenejs.com/model-provider.html`,\n {\n cause: e,\n },\n );\n throw newError;\n }\n}\n\nexport async function callAIWithObjectResponse<T>(\n messages: ChatCompletionMessageParam[],\n modelRuntimeOrConfig: ModelRuntimeInput,\n options?: {\n abortSignal?: AbortSignal;\n jsonParserSource?: unknown;\n retryTimes?: number;\n retryInterval?: number;\n },\n): Promise<{\n content: T;\n contentString: string;\n usage?: AIUsageInfo;\n reasoning_content?: string;\n rawChoiceMessage?: unknown;\n}> {\n const modelConfig = resolveModelConfig(modelRuntimeOrConfig);\n const response = await callAI(messages, modelRuntimeOrConfig, {\n abortSignal: options?.abortSignal,\n expectedJsonObjectResponse: true,\n });\n assert(response, 'empty response');\n const modelFamily = modelConfig.modelFamily;\n const jsonContent = safeParseJson(response.content, modelFamily);\n if (typeof jsonContent !== 'object') {\n throw new AIResponseParseError(\n `failed to parse json response from model (${modelConfig.modelName}): ${response.content}`,\n response.content,\n response.usage,\n response.rawChoiceMessage,\n response.reasoning_content,\n );\n }\n return {\n content: jsonContent,\n contentString: response.content,\n usage: response.usage,\n reasoning_content: response.reasoning_content,\n rawChoiceMessage: response.rawChoiceMessage,\n };\n}\n\nexport async function callAIWithStringResponse(\n msgs: AIArgs,\n modelRuntimeOrConfig: ModelRuntimeInput,\n options?: {\n abortSignal?: AbortSignal;\n requiresOriginalImageDetail?: boolean;\n },\n): Promise<{\n content: string;\n usage?: AIUsageInfo;\n rawChoiceMessage?: unknown;\n}> {\n const { content, usage, rawChoiceMessage } = await callAI(\n msgs,\n modelRuntimeOrConfig,\n {\n abortSignal: options?.abortSignal,\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n },\n );\n return { content, usage, rawChoiceMessage };\n}\n\nexport function extractJSONFromCodeBlock(response: string) {\n try {\n // First, try to match a JSON object directly in the response\n const jsonMatch = response.match(/^\\s*(\\{[\\s\\S]*\\})\\s*$/);\n if (jsonMatch) {\n return jsonMatch[1];\n }\n\n // If no direct JSON object is found, try to extract JSON from a code block\n const codeBlockMatch = response.match(\n /```(?:json)?\\s*(\\{[\\s\\S]*?\\})\\s*```/,\n );\n if (codeBlockMatch) {\n return codeBlockMatch[1];\n }\n\n // If no code block is found, try to find a JSON-like structure in the text\n const jsonLikeMatch = response.match(/\\{[\\s\\S]*\\}/);\n if (jsonLikeMatch) {\n return jsonLikeMatch[0];\n }\n } catch {}\n // If no JSON-like structure is found, return the original response\n return response;\n}\n\nexport function preprocessDoubaoBboxJson(input: string) {\n if (input.includes('bbox')) {\n // when its values like 940 445 969 490, replace all /\\d+\\s+\\d+/g with /$1,$2/g\n while (/\\d+\\s+\\d+/.test(input)) {\n input = input.replace(/(\\d+)\\s+(\\d+)/g, '$1,$2');\n }\n }\n return input;\n}\n\nfunction hasExplicitReasoningConfig({\n reasoningEnabled,\n reasoningEffort,\n reasoningBudget,\n}: {\n reasoningEnabled?: TModelReasoningEnabled;\n reasoningEffort?: string;\n reasoningBudget?: number;\n}): boolean {\n return (\n reasoningEnabled !== undefined ||\n !!reasoningEffort ||\n reasoningBudget !== undefined\n );\n}\n\nconst SUPPORTED_REASONING_FAMILIES = [\n 'qwen3-vl',\n 'qwen3.5',\n 'qwen3.6',\n 'doubao-vision',\n 'doubao-seed',\n 'glm-v',\n] as const satisfies readonly TModelFamily[];\n\ntype SupportedReasoningFamily = (typeof SUPPORTED_REASONING_FAMILIES)[number];\n\nfunction isSupportedReasoningFamily(\n family: TModelFamily | undefined,\n): family is SupportedReasoningFamily {\n return (\n !!family &&\n (SUPPORTED_REASONING_FAMILIES as readonly TModelFamily[]).includes(family)\n );\n}\n\nfunction supportedReasoningFamilyNames(): string {\n return SUPPORTED_REASONING_FAMILIES.join(', ');\n}\n\nexport function resolveReasoningConfig({\n reasoningEnabled,\n reasoningEffort,\n reasoningBudget,\n modelFamily,\n}: {\n reasoningEnabled?: TModelReasoningEnabled;\n reasoningEffort?: string;\n reasoningBudget?: number;\n modelFamily?: TModelFamily;\n}): {\n config: Record<string, unknown>;\n debugMessage?: string;\n} {\n const hasExplicitConfig = hasExplicitReasoningConfig({\n reasoningEnabled,\n reasoningEffort,\n reasoningBudget,\n });\n\n if (hasExplicitConfig) {\n if (!modelFamily) {\n throw new Error(\n `Reasoning config requires MIDSCENE_MODEL_FAMILY. Set MIDSCENE_MODEL_FAMILY to a supported family such as ${supportedReasoningFamilyNames()}, or remove MIDSCENE_MODEL_REASONING_ENABLED / MIDSCENE_MODEL_REASONING_EFFORT / MIDSCENE_MODEL_REASONING_BUDGET.`,\n );\n }\n\n // GPT-5 over Chat Completions is intentionally unsupported here because\n // its reasoning effort compatibility varies by model version.\n if (!isSupportedReasoningFamily(modelFamily)) {\n throw new Error(\n `Reasoning config is not supported for model family \"${modelFamily}\". Use a supported family such as ${supportedReasoningFamilyNames()}, or remove MIDSCENE_MODEL_REASONING_ENABLED / MIDSCENE_MODEL_REASONING_EFFORT / MIDSCENE_MODEL_REASONING_BUDGET.`,\n );\n }\n } else if (!isSupportedReasoningFamily(modelFamily)) {\n return { config: {} };\n }\n\n const effectiveReasoningEnabled =\n reasoningEnabled === 'default' ? undefined : (reasoningEnabled ?? false);\n\n const debugMessages: string[] = [];\n const config: Record<string, unknown> = {};\n\n if (\n modelFamily === 'qwen3-vl' ||\n modelFamily === 'qwen3.5' ||\n modelFamily === 'qwen3.6'\n ) {\n // reasoningEnabled → enable_thinking\n if (effectiveReasoningEnabled !== undefined) {\n config.enable_thinking = effectiveReasoningEnabled;\n }\n debugMessages.push(`enable_thinking=${effectiveReasoningEnabled}`);\n // reasoningBudget → thinking_budget\n if (reasoningBudget !== undefined) {\n config.thinking_budget = reasoningBudget;\n debugMessages.push(`thinking_budget=${reasoningBudget}`);\n }\n // reasoningEffort is ignored for qwen\n } else if (modelFamily === 'doubao-vision' || modelFamily === 'doubao-seed') {\n // reasoningEnabled → thinking.type\n config.thinking = {\n type: effectiveReasoningEnabled ? 'enabled' : 'disabled',\n };\n debugMessages.push(\n `thinking.type=${effectiveReasoningEnabled ? 'enabled' : 'disabled'}`,\n );\n // reasoningEffort → reasoning_effort\n if (reasoningEffort) {\n config.reasoning_effort = reasoningEffort;\n debugMessages.push(`reasoning_effort=\"${reasoningEffort}\"`);\n }\n // reasoningBudget is ignored for doubao\n } else if (modelFamily === 'glm-v') {\n // reasoningEnabled → thinking.type\n config.thinking = {\n type: effectiveReasoningEnabled ? 'enabled' : 'disabled',\n };\n debugMessages.push(\n `thinking.type=${effectiveReasoningEnabled ? 'enabled' : 'disabled'}`,\n );\n // reasoningEffort and reasoningBudget are ignored for glm-v\n }\n\n return {\n config,\n debugMessage: debugMessages.length\n ? `reasoning config for ${modelFamily}: ${debugMessages.join(', ')}`\n : undefined,\n };\n}\n\n/**\n * Normalize a parsed JSON object by trimming whitespace from:\n * 1. All object keys (e.g., \" prompt \" -> \"prompt\")\n * 2. All string values (e.g., \" Tap \" -> \"Tap\")\n * This handles LLM output that may include leading/trailing spaces.\n */\nfunction normalizeJsonObject(obj: any): any {\n // Handle null and undefined\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n // Handle arrays - recursively normalize each element\n if (Array.isArray(obj)) {\n return obj.map((item) => normalizeJsonObject(item));\n }\n\n // Handle objects\n if (typeof obj === 'object') {\n const normalized: any = {};\n\n for (const [key, value] of Object.entries(obj)) {\n // Trim the key to remove leading/trailing spaces\n const trimmedKey = key.trim();\n\n // Recursively normalize the value\n let normalizedValue = normalizeJsonObject(value);\n\n // Trim all string values\n if (typeof normalizedValue === 'string') {\n normalizedValue = normalizedValue.trim();\n }\n\n normalized[trimmedKey] = normalizedValue;\n }\n\n return normalized;\n }\n\n // Handle primitive strings\n if (typeof obj === 'string') {\n return obj.trim();\n }\n\n // Return other primitives as-is\n return obj;\n}\n\nexport function safeParseJson(\n input: string,\n modelFamily: TModelFamily | undefined,\n) {\n const cleanJsonString = extractJSONFromCodeBlock(input);\n // match the point\n if (cleanJsonString?.match(/\\((\\d+),(\\d+)\\)/)) {\n return cleanJsonString\n .match(/\\((\\d+),(\\d+)\\)/)\n ?.slice(1)\n .map(Number);\n }\n\n let parsed: any;\n let lastError: unknown;\n try {\n parsed = JSON.parse(cleanJsonString);\n return normalizeJsonObject(parsed);\n } catch (error) {\n lastError = error;\n }\n try {\n parsed = JSON.parse(jsonrepair(cleanJsonString));\n return normalizeJsonObject(parsed);\n } catch (error) {\n lastError = error;\n }\n\n if (\n modelFamily === 'doubao-vision' ||\n modelFamily === 'doubao-seed' ||\n isUITars(modelFamily)\n ) {\n const jsonString = preprocessDoubaoBboxJson(cleanJsonString);\n try {\n parsed = JSON.parse(jsonrepair(jsonString));\n return normalizeJsonObject(parsed);\n } catch (error) {\n lastError = error;\n }\n }\n throw Error(\n `failed to parse LLM response into JSON. Error - ${String(\n lastError ?? 'unknown error',\n )}. Response - \\n ${input}`,\n );\n}\n"],"names":["AIResponseParseError","Error","message","rawResponse","usage","rawChoiceMessage","reasoningContent","resolveModelConfig","input","formatAIRequestMessagesForDebug","messages","index","role","formatAIMessageContentForDebug","content","Array","safeStringifyForDebug","part","record","redactImagesForDebug","value","item","result","key","Object","undefined","JSON","String","createChatClient","modelConfig","socksProxy","httpProxy","modelName","openaiBaseURL","openaiApiKey","openaiExtraConfig","modelDescription","uiTarsModelVersion","modelFamily","createOpenAIClient","timeout","proxyAgent","warnClient","getDebug","debugProxy","warnProxy","sanitizeProxyUrl","url","parsed","URL","ifInBrowser","moduleName","ProxyAgent","socksDispatcher","proxyUrl","port","Number","protocol","socksType","decodeURIComponent","error","effectiveTimeoutMs","resolveEffectiveTimeoutMs","openAIOptions","baseOpenAI","OpenAI","openai","globalConfigManager","MIDSCENE_LANGSMITH_DEBUG","langsmithModule","wrapOpenAI","MIDSCENE_LANGFUSE_DEBUG","langfuseModule","observeOpenAI","wrappedClient","callAI","modelRuntimeOrConfig","options","codexReasoningEnabled","isCodexAppServerProvider","hasExplicitReasoningConfig","callAIWithCodexAppServer","completion","extraBody","maxTokens","MIDSCENE_MODEL_MAX_TOKENS","OPENAI_MAX_TOKENS","debugCall","warnCall","debugProfileStats","debugProfileDetail","startTime","Date","temperature","isStreaming","accumulated","accumulatedReasoning","timeCost","requestId","responseModelName","hasUsableText","buildUsageInfo","usageData","cachedInputTokens","commonConfig","isAutoGLM","reasoningEffortConfig","reasoningEffortDebugMessage","resolveReasoningConfig","shouldUseOriginalImageDetail","shouldForceOriginalImageDetail","messagesWithImageDetail","msg","streamSignal","cleanupStreamSignal","buildRequestAbortSignal","stream","chunk","reasoning_content","chunkData","estimatedTokens","Math","finalChunk","retryCount","retryInterval","maxAttempts","lastError","attempt","attemptSignal","cleanupAttemptSignal","wasHardTimeout","isHardTimeoutError","Promise","resolve","setTimeout","e","newError","callAIWithObjectResponse","response","assert","jsonContent","safeParseJson","callAIWithStringResponse","msgs","extractJSONFromCodeBlock","jsonMatch","codeBlockMatch","jsonLikeMatch","preprocessDoubaoBboxJson","reasoningEnabled","reasoningEffort","reasoningBudget","SUPPORTED_REASONING_FAMILIES","isSupportedReasoningFamily","family","supportedReasoningFamilyNames","hasExplicitConfig","effectiveReasoningEnabled","debugMessages","config","normalizeJsonObject","obj","normalized","trimmedKey","normalizedValue","cleanJsonString","jsonrepair","isUITars","jsonString"],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { appendFile, mkdir } from "node:fs/promises";
2
+ import node_path from "node:path";
3
+ import { getMidsceneRunBaseDir } from "@aiscene/shared/common";
4
+ import { getBasicEnvValue } from "@aiscene/shared/env/basic";
5
+ import { MIDSCENE_RECORD_MODEL_CALL } from "@aiscene/shared/env/types";
6
+ import { getDebug } from "@aiscene/shared/logger";
7
+ import { ifInBrowser, ifInWorker } from "@aiscene/shared/utils";
8
+ function _define_property(obj, key, value) {
9
+ if (key in obj) Object.defineProperty(obj, key, {
10
+ value: value,
11
+ enumerable: true,
12
+ configurable: true,
13
+ writable: true
14
+ });
15
+ else obj[key] = value;
16
+ return obj;
17
+ }
18
+ const warnRecorder = getDebug('ai:model-record', {
19
+ console: true
20
+ });
21
+ function isModelCallRecordingEnabled() {
22
+ if (ifInBrowser || ifInWorker) return false;
23
+ const value = getBasicEnvValue(MIDSCENE_RECORD_MODEL_CALL);
24
+ return 'true' === value || '1' === value;
25
+ }
26
+ class ModelCallRecorder {
27
+ async initializeFilePath() {
28
+ try {
29
+ const dir = node_path.join(getMidsceneRunBaseDir(), 'model-requests');
30
+ await mkdir(dir, {
31
+ recursive: true
32
+ });
33
+ this.filePath = node_path.join(dir, `${this.processStartTime}-${process.pid}.jsonl`);
34
+ } catch (error) {
35
+ warnRecorder('Failed to initialize model call recorder', error);
36
+ }
37
+ return this.filePath;
38
+ }
39
+ getFilePath() {
40
+ if (this.filePath || !isModelCallRecordingEnabled()) return Promise.resolve(this.filePath);
41
+ if (!this.filePathPromise) this.filePathPromise = this.initializeFilePath().finally(()=>{
42
+ this.filePathPromise = void 0;
43
+ });
44
+ return this.filePathPromise;
45
+ }
46
+ async writeEvent(event) {
47
+ const filePath = await this.getFilePath();
48
+ if (!filePath) return;
49
+ await appendFile(filePath, `${JSON.stringify({
50
+ timestamp: new Date().toISOString(),
51
+ ...event
52
+ })}\n`);
53
+ }
54
+ record(event) {
55
+ const nextWrite = this.writeQueue.then(()=>this.writeEvent(event));
56
+ this.writeQueue = nextWrite.catch((error)=>{
57
+ warnRecorder('Failed to write model call record', error);
58
+ });
59
+ return this.writeQueue;
60
+ }
61
+ constructor(){
62
+ _define_property(this, "processStartTime", new Date().toISOString().replace(/[:.]/g, '-'));
63
+ _define_property(this, "filePath", void 0);
64
+ _define_property(this, "filePathPromise", void 0);
65
+ _define_property(this, "writeQueue", Promise.resolve());
66
+ }
67
+ }
68
+ const modelCallRecorder = new ModelCallRecorder();
69
+ function recordModelCallEvent(event) {
70
+ return modelCallRecorder.record(event);
71
+ }
72
+ export { ModelCallRecorder, isModelCallRecordingEnabled, recordModelCallEvent };
73
+
74
+ //# sourceMappingURL=model-call-recorder.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/service-caller/model-call-recorder.mjs","sources":["../../../../src/ai-model/service-caller/model-call-recorder.ts"],"sourcesContent":["import { appendFile, mkdir } from 'node:fs/promises';\nimport path from 'node:path';\n\nimport { getMidsceneRunBaseDir } from '@aiscene/shared/common';\nimport { getBasicEnvValue } from '@aiscene/shared/env/basic';\nimport { MIDSCENE_RECORD_MODEL_CALL } from '@aiscene/shared/env/types';\nimport { getDebug } from '@aiscene/shared/logger';\nimport { ifInBrowser, ifInWorker } from '@aiscene/shared/utils';\n\nconst warnRecorder = getDebug('ai:model-record', { console: true });\n\nexport function isModelCallRecordingEnabled() {\n if (ifInBrowser || ifInWorker) return false;\n const value = getBasicEnvValue(MIDSCENE_RECORD_MODEL_CALL);\n return value === 'true' || value === '1';\n}\n\nexport class ModelCallRecorder {\n private readonly processStartTime = new Date()\n .toISOString()\n .replace(/[:.]/g, '-');\n private filePath: string | undefined;\n private filePathPromise: Promise<string | undefined> | undefined;\n private writeQueue: Promise<void> = Promise.resolve();\n\n private async initializeFilePath() {\n try {\n const dir = path.join(getMidsceneRunBaseDir(), 'model-requests');\n await mkdir(dir, { recursive: true });\n this.filePath = path.join(\n dir,\n `${this.processStartTime}-${process.pid}.jsonl`,\n );\n } catch (error) {\n warnRecorder('Failed to initialize model call recorder', error);\n }\n return this.filePath;\n }\n\n private getFilePath(): Promise<string | undefined> {\n if (this.filePath || !isModelCallRecordingEnabled()) {\n return Promise.resolve(this.filePath);\n }\n\n if (!this.filePathPromise) {\n this.filePathPromise = this.initializeFilePath().finally(() => {\n this.filePathPromise = undefined;\n });\n }\n return this.filePathPromise;\n }\n\n private async writeEvent(event: Record<string, unknown>) {\n const filePath = await this.getFilePath();\n if (!filePath) return;\n await appendFile(\n filePath,\n `${JSON.stringify({ timestamp: new Date().toISOString(), ...event })}\\n`,\n );\n }\n\n record(event: Record<string, unknown>) {\n const nextWrite = this.writeQueue.then(() => this.writeEvent(event));\n this.writeQueue = nextWrite.catch((error) => {\n warnRecorder('Failed to write model call record', error);\n });\n return this.writeQueue;\n }\n}\n\nconst modelCallRecorder = new ModelCallRecorder();\n\nexport function recordModelCallEvent(event: Record<string, unknown>) {\n return modelCallRecorder.record(event);\n}\n"],"names":["warnRecorder","getDebug","isModelCallRecordingEnabled","ifInBrowser","ifInWorker","value","getBasicEnvValue","MIDSCENE_RECORD_MODEL_CALL","ModelCallRecorder","dir","path","getMidsceneRunBaseDir","mkdir","process","error","Promise","undefined","event","filePath","appendFile","JSON","Date","nextWrite","modelCallRecorder","recordModelCallEvent"],"mappings":";;;;;;;;;;;;;;;;;AASA,MAAMA,eAAeC,SAAS,mBAAmB;IAAE,SAAS;AAAK;AAE1D,SAASC;IACd,IAAIC,eAAeC,YAAY,OAAO;IACtC,MAAMC,QAAQC,iBAAiBC;IAC/B,OAAOF,AAAU,WAAVA,SAAoBA,AAAU,QAAVA;AAC7B;AAEO,MAAMG;IAQX,MAAc,qBAAqB;QACjC,IAAI;YACF,MAAMC,MAAMC,UAAAA,IAAS,CAACC,yBAAyB;YAC/C,MAAMC,MAAMH,KAAK;gBAAE,WAAW;YAAK;YACnC,IAAI,CAAC,QAAQ,GAAGC,UAAAA,IAAS,CACvBD,KACA,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,EAAEI,QAAQ,GAAG,CAAC,MAAM,CAAC;QAEnD,EAAE,OAAOC,OAAO;YACdd,aAAa,4CAA4Cc;QAC3D;QACA,OAAO,IAAI,CAAC,QAAQ;IACtB;IAEQ,cAA2C;QACjD,IAAI,IAAI,CAAC,QAAQ,IAAI,CAACZ,+BACpB,OAAOa,QAAQ,OAAO,CAAC,IAAI,CAAC,QAAQ;QAGtC,IAAI,CAAC,IAAI,CAAC,eAAe,EACvB,IAAI,CAAC,eAAe,GAAG,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC;YACvD,IAAI,CAAC,eAAe,GAAGC;QACzB;QAEF,OAAO,IAAI,CAAC,eAAe;IAC7B;IAEA,MAAc,WAAWC,KAA8B,EAAE;QACvD,MAAMC,WAAW,MAAM,IAAI,CAAC,WAAW;QACvC,IAAI,CAACA,UAAU;QACf,MAAMC,WACJD,UACA,GAAGE,KAAK,SAAS,CAAC;YAAE,WAAW,IAAIC,OAAO,WAAW;YAAI,GAAGJ,KAAK;QAAC,GAAG,EAAE,CAAC;IAE5E;IAEA,OAAOA,KAA8B,EAAE;QACrC,MAAMK,YAAY,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,IAAM,IAAI,CAAC,UAAU,CAACL;QAC7D,IAAI,CAAC,UAAU,GAAGK,UAAU,KAAK,CAAC,CAACR;YACjCd,aAAa,qCAAqCc;QACpD;QACA,OAAO,IAAI,CAAC,UAAU;IACxB;;QAjDA,uBAAiB,oBAAmB,IAAIO,OACrC,WAAW,GACX,OAAO,CAAC,SAAS;QACpB,uBAAQ,YAAR;QACA,uBAAQ,mBAAR;QACA,uBAAQ,cAA4BN,QAAQ,OAAO;;AA6CrD;AAEA,MAAMQ,oBAAoB,IAAIf;AAEvB,SAASgB,qBAAqBP,KAA8B;IACjE,OAAOM,kBAAkB,MAAM,CAACN;AAClC"}
@@ -0,0 +1,147 @@
1
+ import { getDebug } from "@aiscene/shared/logger";
2
+ const MAX_ERROR_RESPONSE_BODY_LENGTH = 4000;
3
+ const MAX_FETCH_ERROR_LENGTH = 4000;
4
+ const debugOpenAIFetch = getDebug('ai:call');
5
+ function headersToEntries(headers) {
6
+ const entries = [];
7
+ new Headers(headers).forEach((value, key)=>entries.push([
8
+ key,
9
+ value
10
+ ]));
11
+ return entries;
12
+ }
13
+ function truncateText(text, maxLength) {
14
+ if (text.length <= maxLength) return text;
15
+ return `${text.slice(0, maxLength)}... [truncated, ${text.length} chars total]`;
16
+ }
17
+ function truncateErrorResponseBody(body) {
18
+ return truncateText(body, MAX_ERROR_RESPONSE_BODY_LENGTH);
19
+ }
20
+ function getErrorCode(error) {
21
+ if (!error || 'object' != typeof error) return;
22
+ const code = error.code;
23
+ return 'string' == typeof code ? code : void 0;
24
+ }
25
+ function formatErrorSummary(error) {
26
+ if (error instanceof Error) {
27
+ const code = getErrorCode(error);
28
+ const codeText = code ? ` [${code}]` : '';
29
+ return `${error.name}${codeText}: ${error.message}`;
30
+ }
31
+ return String(error);
32
+ }
33
+ function formatFetchErrorForReport(error) {
34
+ const details = [
35
+ formatErrorSummary(error)
36
+ ];
37
+ const cause = error && 'object' == typeof error ? error.cause : void 0;
38
+ if (void 0 !== cause) details.push(`Cause: ${formatErrorSummary(cause)}`);
39
+ return truncateText(details.join('\n'), MAX_FETCH_ERROR_LENGTH);
40
+ }
41
+ function getDefaultFetch() {
42
+ if ('function' == typeof globalThis.fetch) return globalThis.fetch;
43
+ throw new Error('`fetch` is not defined as a global; check that the runtime provides globalThis.fetch or polyfill it before creating the OpenAI client');
44
+ }
45
+ function wrapOpenAICompatibleFetch(context) {
46
+ const baseFetch = getDefaultFetch();
47
+ let attempt = 0;
48
+ return async (input, init)=>{
49
+ attempt += 1;
50
+ if (context.recordEvent) {
51
+ const request = new Request(input, init);
52
+ context.recordEvent({
53
+ type: 'request',
54
+ attempt,
55
+ request: {
56
+ url: request.url,
57
+ method: request.method,
58
+ body: await request.clone().text().catch(()=>void 0)
59
+ }
60
+ });
61
+ }
62
+ let response;
63
+ try {
64
+ response = await baseFetch(input, init);
65
+ } catch (error) {
66
+ const fetchErrorSummary = formatFetchErrorForReport(error);
67
+ debugOpenAIFetch('OpenAI-compatible fetch failed', fetchErrorSummary);
68
+ context.fetchErrors ??= [];
69
+ context.fetchErrors.push({
70
+ attempt,
71
+ error: fetchErrorSummary
72
+ });
73
+ context.recordEvent?.({
74
+ type: 'error',
75
+ attempt,
76
+ error: fetchErrorSummary
77
+ });
78
+ throw error;
79
+ }
80
+ const requestId = response.headers.get('x-request-id') ?? response.headers.get('x-model-request-id');
81
+ if (requestId) {
82
+ context.responseRequestIds ??= [];
83
+ context.responseRequestIds.push({
84
+ attempt,
85
+ requestId,
86
+ status: response.status,
87
+ ok: response.ok
88
+ });
89
+ }
90
+ if (!response.ok) {
91
+ const rawResponseBody = await response.clone().text().catch(()=>void 0);
92
+ if (void 0 !== rawResponseBody) {
93
+ context.rawResponseBodies ??= [];
94
+ context.rawResponseBodies.push({
95
+ attempt,
96
+ body: rawResponseBody
97
+ });
98
+ }
99
+ }
100
+ if (context.recordEvent) {
101
+ const isStream = response.headers.get('content-type')?.includes('text/event-stream');
102
+ const body = isStream ? void 0 : await response.clone().text().catch(()=>void 0);
103
+ const httpResponse = {
104
+ attempt,
105
+ status: response.status,
106
+ ok: response.ok,
107
+ headers: headersToEntries(response.headers),
108
+ ...void 0 === body ? {} : {
109
+ body
110
+ }
111
+ };
112
+ context.httpResponses ??= [];
113
+ context.httpResponses.push(httpResponse);
114
+ if (!response.ok) context.recordEvent({
115
+ type: 'error',
116
+ ...httpResponse
117
+ });
118
+ }
119
+ return response;
120
+ };
121
+ }
122
+ function formatOpenAIAPIErrorDetails(_error, context) {
123
+ const details = [];
124
+ if (context.rawResponseBodies?.length === 1) details.push(`OpenAI raw error response body: ${truncateErrorResponseBody(context.rawResponseBodies[0].body)}`);
125
+ else if (context.rawResponseBodies?.length) {
126
+ const rawResponseBodyDetails = context.rawResponseBodies.map(({ attempt, body })=>`Attempt ${attempt}: ${truncateErrorResponseBody(body)}`).join('\n');
127
+ details.push(`OpenAI raw error response bodies:\n${rawResponseBodyDetails}`);
128
+ }
129
+ const errorResponseRequestIds = context.responseRequestIds?.filter(({ ok })=>!ok);
130
+ if (errorResponseRequestIds?.length === 1) {
131
+ const { attempt, requestId, status } = errorResponseRequestIds[0];
132
+ details.push(`OpenAI error response request ID (attempt ${attempt}, status ${status}): ${requestId}`);
133
+ } else if (errorResponseRequestIds?.length) {
134
+ const requestIdDetails = errorResponseRequestIds.map(({ attempt, requestId, status })=>`Attempt ${attempt} (status ${status}): ${requestId}`).join('\n');
135
+ details.push(`OpenAI error response request IDs:\n${requestIdDetails}`);
136
+ }
137
+ if (context.fetchErrors?.length === 1) details.push(`OpenAI fetch error (attempt ${context.fetchErrors[0].attempt}): ${context.fetchErrors[0].error}`);
138
+ else if (context.fetchErrors?.length) {
139
+ const fetchErrorDetails = context.fetchErrors.map(({ attempt, error })=>`Attempt ${attempt}: ${error}`).join('\n');
140
+ details.push(`OpenAI fetch errors:\n${fetchErrorDetails}`);
141
+ }
142
+ if (!details.length) return '';
143
+ return `\n${details.join('\n')}`;
144
+ }
145
+ export { formatOpenAIAPIErrorDetails, wrapOpenAICompatibleFetch };
146
+
147
+ //# sourceMappingURL=openai-error.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/service-caller/openai-error.mjs","sources":["../../../../src/ai-model/service-caller/openai-error.ts"],"sourcesContent":["import { getDebug } from '@aiscene/shared/logger';\n\nconst MAX_ERROR_RESPONSE_BODY_LENGTH = 4000;\nconst MAX_FETCH_ERROR_LENGTH = 4000;\n\nconst debugOpenAIFetch = getDebug('ai:call');\n\nexport interface OpenAIErrorResponseContext {\n recordEvent?: (event: Record<string, unknown>) => void;\n responseRequestIds?: Array<{\n attempt: number;\n requestId: string;\n status: number;\n ok: boolean;\n }>;\n rawResponseBodies?: Array<{\n attempt: number;\n body: string;\n }>;\n fetchErrors?: Array<{\n attempt: number;\n error: string;\n }>;\n httpResponses?: Array<{\n attempt: number;\n status: number;\n ok: boolean;\n headers: Array<[string, string]>;\n body?: string;\n }>;\n}\n\nfunction headersToEntries(\n headers: HeadersInit | undefined,\n): Array<[string, string]> {\n const entries: Array<[string, string]> = [];\n new Headers(headers).forEach((value, key) => entries.push([key, value]));\n return entries;\n}\n\nfunction truncateText(text: string, maxLength: number): string {\n if (text.length <= maxLength) {\n return text;\n }\n\n return `${text.slice(0, maxLength)}... [truncated, ${text.length} chars total]`;\n}\n\nfunction truncateErrorResponseBody(body: string): string {\n return truncateText(body, MAX_ERROR_RESPONSE_BODY_LENGTH);\n}\n\nfunction getErrorCode(error: unknown): string | undefined {\n if (!error || typeof error !== 'object') {\n return undefined;\n }\n\n const code = (error as { code?: unknown }).code;\n return typeof code === 'string' ? code : undefined;\n}\n\nfunction formatErrorSummary(error: unknown): string {\n if (error instanceof Error) {\n const code = getErrorCode(error);\n const codeText = code ? ` [${code}]` : '';\n return `${error.name}${codeText}: ${error.message}`;\n }\n\n return String(error);\n}\n\nfunction formatFetchErrorForReport(error: unknown): string {\n const details = [formatErrorSummary(error)];\n const cause =\n error && typeof error === 'object'\n ? (error as { cause?: unknown }).cause\n : undefined;\n\n if (cause !== undefined) {\n details.push(`Cause: ${formatErrorSummary(cause)}`);\n }\n\n return truncateText(details.join('\\n'), MAX_FETCH_ERROR_LENGTH);\n}\n\n// Mirrors OpenAI SDK's default fetch selection:\n// openai@6.3.0 src/client.ts sets `this.fetch = options.fetch ?? Shims.getDefaultFetch()`,\n// and src/internal/shims.ts resolves that default to global `fetch`.\nfunction getDefaultFetch(): typeof fetch {\n if (typeof globalThis.fetch === 'function') {\n return globalThis.fetch;\n }\n\n throw new Error(\n '`fetch` is not defined as a global; check that the runtime provides globalThis.fetch or polyfill it before creating the OpenAI client',\n );\n}\n\nexport function wrapOpenAICompatibleFetch(\n context: OpenAIErrorResponseContext,\n): typeof fetch {\n const baseFetch = getDefaultFetch();\n let attempt = 0;\n\n return async (input, init) => {\n attempt += 1;\n if (context.recordEvent) {\n // Midscene does not expose a custom fetch hook. The OpenAI SDK therefore\n // always invokes this wrapper with standard Fetch API input and init.\n const request = new Request(input, init);\n context.recordEvent({\n type: 'request',\n attempt,\n request: {\n url: request.url,\n method: request.method,\n body: await request\n .clone()\n .text()\n .catch(() => undefined),\n },\n });\n }\n let response: Response;\n try {\n response = await baseFetch(input, init);\n } catch (error) {\n const fetchErrorSummary = formatFetchErrorForReport(error);\n debugOpenAIFetch('OpenAI-compatible fetch failed', fetchErrorSummary);\n context.fetchErrors ??= [];\n context.fetchErrors.push({\n attempt,\n error: fetchErrorSummary,\n });\n context.recordEvent?.({\n type: 'error',\n attempt,\n error: fetchErrorSummary,\n });\n throw error;\n }\n\n const requestId =\n response.headers.get('x-request-id') ??\n response.headers.get('x-model-request-id');\n\n if (requestId) {\n context.responseRequestIds ??= [];\n context.responseRequestIds.push({\n attempt,\n requestId,\n status: response.status,\n ok: response.ok,\n });\n }\n\n if (!response.ok) {\n // OpenAI SDK only exposes the `error` field for JSON error responses.\n // Non-standard provider bodies like `{ err: 'xxx' }` would otherwise be\n // hidden from Midscene's final error message.\n const rawResponseBody = await response\n .clone()\n .text()\n .catch(() => undefined);\n\n if (rawResponseBody !== undefined) {\n context.rawResponseBodies ??= [];\n context.rawResponseBodies.push({\n attempt,\n body: rawResponseBody,\n });\n }\n }\n\n if (context.recordEvent) {\n const isStream = response.headers\n .get('content-type')\n ?.includes('text/event-stream');\n const body = isStream\n ? undefined\n : await response\n .clone()\n .text()\n .catch(() => undefined);\n const httpResponse = {\n attempt,\n status: response.status,\n ok: response.ok,\n headers: headersToEntries(response.headers),\n ...(body === undefined ? {} : { body }),\n };\n context.httpResponses ??= [];\n context.httpResponses.push(httpResponse);\n if (!response.ok) {\n context.recordEvent({ type: 'error', ...httpResponse });\n }\n }\n\n return response;\n };\n}\n\nexport function formatOpenAIAPIErrorDetails(\n _error: unknown,\n context: OpenAIErrorResponseContext,\n): string {\n const details: string[] = [];\n\n if (context.rawResponseBodies?.length === 1) {\n details.push(\n `OpenAI raw error response body: ${truncateErrorResponseBody(\n context.rawResponseBodies[0].body,\n )}`,\n );\n } else if (context.rawResponseBodies?.length) {\n const rawResponseBodyDetails = context.rawResponseBodies\n .map(\n ({ attempt, body }) =>\n `Attempt ${attempt}: ${truncateErrorResponseBody(body)}`,\n )\n .join('\\n');\n\n details.push(\n `OpenAI raw error response bodies:\\n${rawResponseBodyDetails}`,\n );\n }\n\n const errorResponseRequestIds = context.responseRequestIds?.filter(\n ({ ok }) => !ok,\n );\n if (errorResponseRequestIds?.length === 1) {\n const { attempt, requestId, status } = errorResponseRequestIds[0];\n details.push(\n `OpenAI error response request ID (attempt ${attempt}, status ${status}): ${requestId}`,\n );\n } else if (errorResponseRequestIds?.length) {\n const requestIdDetails = errorResponseRequestIds\n .map(\n ({ attempt, requestId, status }) =>\n `Attempt ${attempt} (status ${status}): ${requestId}`,\n )\n .join('\\n');\n details.push(`OpenAI error response request IDs:\\n${requestIdDetails}`);\n }\n\n if (context.fetchErrors?.length === 1) {\n details.push(\n `OpenAI fetch error (attempt ${context.fetchErrors[0].attempt}): ${context.fetchErrors[0].error}`,\n );\n } else if (context.fetchErrors?.length) {\n const fetchErrorDetails = context.fetchErrors\n .map(({ attempt, error }) => `Attempt ${attempt}: ${error}`)\n .join('\\n');\n\n details.push(`OpenAI fetch errors:\\n${fetchErrorDetails}`);\n }\n\n if (!details.length) {\n return '';\n }\n\n return `\\n${details.join('\\n')}`;\n}\n"],"names":["MAX_ERROR_RESPONSE_BODY_LENGTH","MAX_FETCH_ERROR_LENGTH","debugOpenAIFetch","getDebug","headersToEntries","headers","entries","Headers","value","key","truncateText","text","maxLength","truncateErrorResponseBody","body","getErrorCode","error","code","undefined","formatErrorSummary","Error","codeText","String","formatFetchErrorForReport","details","cause","getDefaultFetch","globalThis","wrapOpenAICompatibleFetch","context","baseFetch","attempt","input","init","request","Request","response","fetchErrorSummary","requestId","rawResponseBody","isStream","httpResponse","formatOpenAIAPIErrorDetails","_error","rawResponseBodyDetails","errorResponseRequestIds","ok","status","requestIdDetails","fetchErrorDetails"],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ function loadUndici() {
2
+ return import("undici");
3
+ }
4
+ function loadFetchSocks() {
5
+ return import("fetch-socks");
6
+ }
7
+ export { loadFetchSocks, loadUndici };
8
+
9
+ //# sourceMappingURL=proxy-deps.node.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/service-caller/proxy-deps.node.mjs","sources":["../../../../src/ai-model/service-caller/proxy-deps.node.ts"],"sourcesContent":["export function loadUndici(): Promise<typeof import('undici')> {\n return import('undici');\n}\n\nexport function loadFetchSocks(): Promise<typeof import('fetch-socks')> {\n return import('fetch-socks');\n}\n"],"names":["loadUndici","loadFetchSocks"],"mappings":"AAAO,SAASA;IACd,OAAO,MAAM,CAAC;AAChB;AAEO,SAASC;IACd,OAAO,MAAM,CAAC;AAChB"}
@@ -0,0 +1,12 @@
1
+ function unavailable() {
2
+ throw new Error('proxy dependencies are unavailable in browser builds');
3
+ }
4
+ function loadUndici() {
5
+ return unavailable();
6
+ }
7
+ function loadFetchSocks() {
8
+ return unavailable();
9
+ }
10
+ export { loadFetchSocks, loadUndici };
11
+
12
+ //# sourceMappingURL=proxy-deps.stub.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/service-caller/proxy-deps.stub.mjs","sources":["../../../../src/ai-model/service-caller/proxy-deps.stub.ts"],"sourcesContent":["function unavailable(): never {\n throw new Error('proxy dependencies are unavailable in browser builds');\n}\n\nexport function loadUndici(): Promise<typeof import('undici')> {\n return unavailable();\n}\n\nexport function loadFetchSocks(): Promise<typeof import('fetch-socks')> {\n return unavailable();\n}\n"],"names":["unavailable","Error","loadUndici","loadFetchSocks"],"mappings":"AAAA,SAASA;IACP,MAAM,IAAIC,MAAM;AAClB;AAEO,SAASC;IACd,OAAOF;AACT;AAEO,SAASG;IACd,OAAOH;AACT"}
@@ -0,0 +1,33 @@
1
+ function withSemanticRetryFeedback(messages, previousParseError) {
2
+ if (!previousParseError) return messages;
3
+ const errorMessage = previousParseError instanceof Error ? previousParseError.message : String(previousParseError);
4
+ return [
5
+ ...messages,
6
+ {
7
+ role: 'user',
8
+ content: `The previous response was invalid:\n${errorMessage}\n\nPlease avoid the validation error above in this response.`
9
+ }
10
+ ];
11
+ }
12
+ async function callAiAndParseWithRetry({ callAi, parseResponse, toParseError, parseRetryTimes = 0, parseRetryInterval = 0, abortSignal, onParseRetry }) {
13
+ const normalizedRetryTimes = Number.isFinite(parseRetryTimes) ? Math.max(0, Math.floor(parseRetryTimes)) : 0;
14
+ const normalizedRetryInterval = Number.isFinite(parseRetryInterval) ? Math.max(0, parseRetryInterval) : 0;
15
+ const callAndParseOnce = async (remainingRetries, retryAttempt, previousParseError)=>{
16
+ const response = await callAi(retryAttempt, previousParseError);
17
+ try {
18
+ return await parseResponse(response);
19
+ } catch (error) {
20
+ if (remainingRetries > 0 && !abortSignal?.aborted) {
21
+ onParseRetry?.(error, response);
22
+ if (normalizedRetryInterval > 0) await new Promise((resolve)=>setTimeout(resolve, normalizedRetryInterval));
23
+ if (abortSignal?.aborted) throw toParseError(error, response);
24
+ return callAndParseOnce(remainingRetries - 1, retryAttempt + 1, error);
25
+ }
26
+ throw toParseError(error, response);
27
+ }
28
+ };
29
+ return callAndParseOnce(normalizedRetryTimes, 0);
30
+ }
31
+ export { callAiAndParseWithRetry, withSemanticRetryFeedback };
32
+
33
+ //# sourceMappingURL=semantic-retry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/service-caller/semantic-retry.mjs","sources":["../../../../src/ai-model/service-caller/semantic-retry.ts"],"sourcesContent":["import type { ChatCompletionMessageParam } from 'openai/resources/index';\n\nexport function withSemanticRetryFeedback(\n messages: ChatCompletionMessageParam[],\n previousParseError?: unknown,\n): ChatCompletionMessageParam[] {\n if (!previousParseError) return messages;\n\n const errorMessage =\n previousParseError instanceof Error\n ? previousParseError.message\n : String(previousParseError);\n\n return [\n ...messages,\n {\n role: 'user',\n content: `The previous response was invalid:\\n${errorMessage}\\n\\nPlease avoid the validation error above in this response.`,\n },\n ];\n}\n\nexport type CallAiAndParseWithRetryOptions<Response, Parsed> = {\n /** Sends a single model request. Request errors are always propagated as-is. */\n /**\n * `retryAttempt` is local to this retry loop: 0 for the initial request,\n * then incremented after each parsing failure.\n */\n callAi: (\n retryAttempt: number,\n previousParseError?: unknown,\n ) => Promise<Response>;\n /** Parses a successful model response. Only failures from this callback retry. */\n parseResponse: (response: Response) => Parsed | Promise<Parsed>;\n /** Converts the final parsing failure into the caller's domain error. */\n toParseError: (error: unknown, response: Response) => Error;\n /** Number of additional model requests after a parsing failure. Defaults to 0. */\n parseRetryTimes?: number;\n /** Delay in milliseconds before retrying a parsing failure. Defaults to 0. */\n parseRetryInterval?: number;\n abortSignal?: AbortSignal;\n /** Runs immediately before a parsing failure triggers another model request. */\n onParseRetry?: (error: unknown, response: Response) => void;\n};\n\n/**\n * Calls AI and parses its response, retrying only when the response cannot be\n * structurally parsed.\n *\n * Errors thrown by callAi() intentionally bypass this retry mechanism and are\n * propagated as-is. Only a successful callAi() response that fails the\n * parseResponse() callback triggers another model request.\n */\nexport async function callAiAndParseWithRetry<Response, Parsed>({\n callAi,\n parseResponse,\n toParseError,\n parseRetryTimes = 0,\n parseRetryInterval = 0,\n abortSignal,\n onParseRetry,\n}: CallAiAndParseWithRetryOptions<Response, Parsed>): Promise<Parsed> {\n const normalizedRetryTimes = Number.isFinite(parseRetryTimes)\n ? Math.max(0, Math.floor(parseRetryTimes))\n : 0;\n const normalizedRetryInterval = Number.isFinite(parseRetryInterval)\n ? Math.max(0, parseRetryInterval)\n : 0;\n\n const callAndParseOnce = async (\n remainingRetries: number,\n retryAttempt: number,\n previousParseError?: unknown,\n ): Promise<Parsed> => {\n const response = await callAi(retryAttempt, previousParseError);\n\n try {\n return await parseResponse(response);\n } catch (error) {\n if (remainingRetries > 0 && !abortSignal?.aborted) {\n onParseRetry?.(error, response);\n if (normalizedRetryInterval > 0) {\n await new Promise((resolve) =>\n setTimeout(resolve, normalizedRetryInterval),\n );\n }\n if (abortSignal?.aborted) {\n throw toParseError(error, response);\n }\n return callAndParseOnce(remainingRetries - 1, retryAttempt + 1, error);\n }\n throw toParseError(error, response);\n }\n };\n\n return callAndParseOnce(normalizedRetryTimes, 0);\n}\n"],"names":["withSemanticRetryFeedback","messages","previousParseError","errorMessage","Error","String","callAiAndParseWithRetry","callAi","parseResponse","toParseError","parseRetryTimes","parseRetryInterval","abortSignal","onParseRetry","normalizedRetryTimes","Number","Math","normalizedRetryInterval","callAndParseOnce","remainingRetries","retryAttempt","response","error","Promise","resolve","setTimeout"],"mappings":"AAEO,SAASA,0BACdC,QAAsC,EACtCC,kBAA4B;IAE5B,IAAI,CAACA,oBAAoB,OAAOD;IAEhC,MAAME,eACJD,8BAA8BE,QAC1BF,mBAAmB,OAAO,GAC1BG,OAAOH;IAEb,OAAO;WACFD;QACH;YACE,MAAM;YACN,SAAS,CAAC,oCAAoC,EAAEE,aAAa,6DAA6D,CAAC;QAC7H;KACD;AACH;AAiCO,eAAeG,wBAA0C,EAC9DC,MAAM,EACNC,aAAa,EACbC,YAAY,EACZC,kBAAkB,CAAC,EACnBC,qBAAqB,CAAC,EACtBC,WAAW,EACXC,YAAY,EACqC;IACjD,MAAMC,uBAAuBC,OAAO,QAAQ,CAACL,mBACzCM,KAAK,GAAG,CAAC,GAAGA,KAAK,KAAK,CAACN,oBACvB;IACJ,MAAMO,0BAA0BF,OAAO,QAAQ,CAACJ,sBAC5CK,KAAK,GAAG,CAAC,GAAGL,sBACZ;IAEJ,MAAMO,mBAAmB,OACvBC,kBACAC,cACAlB;QAEA,MAAMmB,WAAW,MAAMd,OAAOa,cAAclB;QAE5C,IAAI;YACF,OAAO,MAAMM,cAAca;QAC7B,EAAE,OAAOC,OAAO;YACd,IAAIH,mBAAmB,KAAK,CAACP,aAAa,SAAS;gBACjDC,eAAeS,OAAOD;gBACtB,IAAIJ,0BAA0B,GAC5B,MAAM,IAAIM,QAAQ,CAACC,UACjBC,WAAWD,SAASP;gBAGxB,IAAIL,aAAa,SACf,MAAMH,aAAaa,OAAOD;gBAE5B,OAAOH,iBAAiBC,mBAAmB,GAAGC,eAAe,GAAGE;YAClE;YACA,MAAMb,aAAaa,OAAOD;QAC5B;IACF;IAEA,OAAOH,iBAAiBJ,sBAAsB;AAChD"}
File without changes
@@ -0,0 +1,15 @@
1
+ const getZodDefaultValue = (field)=>{
2
+ let current = field;
3
+ const visited = new Set();
4
+ while(current && !visited.has(current)){
5
+ visited.add(current);
6
+ const currentWithDef = current;
7
+ if (!currentWithDef._def?.typeName) break;
8
+ if ('ZodDefault' === currentWithDef._def.typeName) return currentWithDef._def.defaultValue?.();
9
+ if ('ZodOptional' === currentWithDef._def.typeName || 'ZodNullable' === currentWithDef._def.typeName) current = currentWithDef._def.innerType;
10
+ else break;
11
+ }
12
+ };
13
+ export { getZodDefaultValue };
14
+
15
+ //# sourceMappingURL=action-schema.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/shared/action-schema.mjs","sources":["../../../../src/ai-model/shared/action-schema.ts"],"sourcesContent":["/**\n * Find ZodDefault in the wrapper chain and return its default value.\n */\nexport const getZodDefaultValue = (field: unknown): unknown | undefined => {\n let current = field;\n const visited = new Set<unknown>();\n\n while (current && !visited.has(current)) {\n visited.add(current);\n const currentWithDef = current as {\n _def?: {\n typeName?: string;\n defaultValue?: () => unknown;\n innerType?: unknown;\n };\n };\n\n if (!currentWithDef._def?.typeName) break;\n\n if (currentWithDef._def.typeName === 'ZodDefault') {\n return currentWithDef._def.defaultValue?.();\n }\n\n if (\n currentWithDef._def.typeName === 'ZodOptional' ||\n currentWithDef._def.typeName === 'ZodNullable'\n ) {\n current = currentWithDef._def.innerType;\n } else {\n break;\n }\n }\n\n return undefined;\n};\n"],"names":["getZodDefaultValue","field","current","visited","Set","currentWithDef"],"mappings":"AAGO,MAAMA,qBAAqB,CAACC;IACjC,IAAIC,UAAUD;IACd,MAAME,UAAU,IAAIC;IAEpB,MAAOF,WAAW,CAACC,QAAQ,GAAG,CAACD,SAAU;QACvCC,QAAQ,GAAG,CAACD;QACZ,MAAMG,iBAAiBH;QAQvB,IAAI,CAACG,eAAe,IAAI,EAAE,UAAU;QAEpC,IAAIA,AAAiC,iBAAjCA,eAAe,IAAI,CAAC,QAAQ,EAC9B,OAAOA,eAAe,IAAI,CAAC,YAAY;QAGzC,IACEA,AAAiC,kBAAjCA,eAAe,IAAI,CAAC,QAAQ,IAC5BA,AAAiC,kBAAjCA,eAAe,IAAI,CAAC,QAAQ,EAE5BH,UAAUG,eAAe,IAAI,CAAC,SAAS;aAEvC;IAEJ;AAGF"}