@midscene/core 1.13.4-beta-20260928072823.0 → 1.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (300) hide show
  1. package/dist/es/agent/task-builder.mjs +1 -1
  2. package/dist/es/agent/task-builder.mjs.map +1 -1
  3. package/dist/es/agent/tasks.mjs +4 -4
  4. package/dist/es/agent/tasks.mjs.map +1 -1
  5. package/dist/es/agent/utils.mjs +1 -1
  6. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs +2 -5
  7. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs.map +1 -1
  8. package/dist/es/ai-model/model-adapter/chat-completion.mjs +8 -11
  9. package/dist/es/ai-model/model-adapter/chat-completion.mjs.map +1 -1
  10. package/dist/es/ai-model/model-adapter/default-locate-protocol.mjs +7 -8
  11. package/dist/es/ai-model/model-adapter/default-locate-protocol.mjs.map +1 -1
  12. package/dist/es/ai-model/model-adapter/locate.mjs +3 -7
  13. package/dist/es/ai-model/model-adapter/locate.mjs.map +1 -1
  14. package/dist/es/ai-model/model-adapter/resolve.mjs +11 -3
  15. package/dist/es/ai-model/model-adapter/resolve.mjs.map +1 -1
  16. package/dist/es/ai-model/model-adapter/responses.mjs +38 -0
  17. package/dist/es/ai-model/model-adapter/responses.mjs.map +1 -0
  18. package/dist/es/ai-model/model-adapter/temperature-with-semantic-retry.mjs +7 -0
  19. package/dist/es/ai-model/model-adapter/temperature-with-semantic-retry.mjs.map +1 -0
  20. package/dist/es/ai-model/models/gpt.mjs +73 -9
  21. package/dist/es/ai-model/models/gpt.mjs.map +1 -1
  22. package/dist/es/ai-model/models/qwen.mjs +8 -2
  23. package/dist/es/ai-model/models/qwen.mjs.map +1 -1
  24. package/dist/es/ai-model/models/registry.mjs +2 -2
  25. package/dist/es/ai-model/models/registry.mjs.map +1 -1
  26. package/dist/es/ai-model/service-caller/call-ai.mjs +22 -13
  27. package/dist/es/ai-model/service-caller/call-ai.mjs.map +1 -1
  28. package/dist/es/ai-model/service-caller/codex/call-codex.mjs +10 -8
  29. package/dist/es/ai-model/service-caller/codex/call-codex.mjs.map +1 -1
  30. package/dist/es/ai-model/service-caller/codex/codex-app-server.mjs +29 -28
  31. package/dist/es/ai-model/service-caller/codex/codex-app-server.mjs.map +1 -1
  32. package/dist/es/ai-model/service-caller/index.mjs +1 -2
  33. package/dist/es/ai-model/service-caller/model-call.mjs +4 -4
  34. package/dist/es/ai-model/service-caller/model-call.mjs.map +1 -1
  35. package/dist/es/ai-model/service-caller/openai/call-openai.mjs +18 -8
  36. package/dist/es/ai-model/service-caller/openai/call-openai.mjs.map +1 -1
  37. package/dist/es/ai-model/service-caller/openai/chat-completion/chat-completion.mjs +11 -7
  38. package/dist/es/ai-model/service-caller/openai/chat-completion/chat-completion.mjs.map +1 -1
  39. package/dist/es/ai-model/service-caller/openai/chat-completion/non-stream.mjs +9 -9
  40. package/dist/es/ai-model/service-caller/openai/chat-completion/non-stream.mjs.map +1 -1
  41. package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs +4 -8
  42. package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs.map +1 -1
  43. package/dist/es/ai-model/service-caller/openai/chat-completion/utils.mjs +28 -1
  44. package/dist/es/ai-model/service-caller/openai/chat-completion/utils.mjs.map +1 -1
  45. package/dist/es/ai-model/service-caller/openai/openai-client.mjs +3 -3
  46. package/dist/es/ai-model/service-caller/openai/openai-client.mjs.map +1 -1
  47. package/dist/es/ai-model/service-caller/openai/responses/non-stream.mjs +21 -0
  48. package/dist/es/ai-model/service-caller/openai/responses/non-stream.mjs.map +1 -0
  49. package/dist/es/ai-model/service-caller/openai/responses/responses.mjs +57 -0
  50. package/dist/es/ai-model/service-caller/openai/responses/responses.mjs.map +1 -0
  51. package/dist/es/ai-model/service-caller/openai/responses/stream.mjs +56 -0
  52. package/dist/es/ai-model/service-caller/openai/responses/stream.mjs.map +1 -0
  53. package/dist/es/ai-model/service-caller/openai/responses/types.mjs +0 -0
  54. package/dist/es/ai-model/service-caller/openai/responses/utils.mjs +72 -0
  55. package/dist/es/ai-model/service-caller/openai/responses/utils.mjs.map +1 -0
  56. package/dist/es/ai-model/service-caller/semantic-retry.mjs.map +1 -1
  57. package/dist/es/ai-model/service-caller/utils.mjs +6 -25
  58. package/dist/es/ai-model/service-caller/utils.mjs.map +1 -1
  59. package/dist/es/ai-model/shared/model-locate-result/factory.mjs +4 -1
  60. package/dist/es/ai-model/shared/model-locate-result/factory.mjs.map +1 -1
  61. package/dist/es/ai-model/shared/model-locate-result/prompt-spec.mjs +3 -2
  62. package/dist/es/ai-model/shared/model-locate-result/prompt-spec.mjs.map +1 -1
  63. package/dist/es/ai-model/shared/model-locate-result/result-field.mjs +13 -0
  64. package/dist/es/ai-model/shared/model-locate-result/result-field.mjs.map +1 -0
  65. package/dist/es/ai-model/shared/model-locate-result/types.mjs.map +1 -1
  66. package/dist/es/ai-model/shared/multimodal-prompt.mjs +5 -8
  67. package/dist/es/ai-model/shared/multimodal-prompt.mjs.map +1 -1
  68. package/dist/es/ai-model/workflows/grounding/locate.mjs +6 -6
  69. package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -1
  70. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs +5 -5
  71. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs.map +1 -1
  72. package/dist/es/ai-model/workflows/grounding/section-locate.mjs +5 -5
  73. package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -1
  74. package/dist/es/ai-model/workflows/grounding/utils.mjs +4 -7
  75. package/dist/es/ai-model/workflows/grounding/utils.mjs.map +1 -1
  76. package/dist/es/ai-model/workflows/insight/extraction.mjs +9 -15
  77. package/dist/es/ai-model/workflows/insight/extraction.mjs.map +1 -1
  78. package/dist/es/ai-model/workflows/insight/order-sensitive.mjs.map +1 -1
  79. package/dist/es/ai-model/workflows/planning/conversation-history.mjs +17 -9
  80. package/dist/es/ai-model/workflows/planning/conversation-history.mjs.map +1 -1
  81. package/dist/es/ai-model/workflows/planning/custom-planning.mjs +12 -14
  82. package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -1
  83. package/dist/es/ai-model/workflows/planning/locate-normalization.mjs +5 -9
  84. package/dist/es/ai-model/workflows/planning/locate-normalization.mjs.map +1 -1
  85. package/dist/es/ai-model/workflows/planning/standard-planning.mjs +25 -28
  86. package/dist/es/ai-model/workflows/planning/standard-planning.mjs.map +1 -1
  87. package/dist/es/ai-model/workflows/recorder-generation/common.mjs +2 -4
  88. package/dist/es/ai-model/workflows/recorder-generation/common.mjs.map +1 -1
  89. package/dist/es/ai-model/workflows/recorder-generation/markdown.mjs +3 -5
  90. package/dist/es/ai-model/workflows/recorder-generation/markdown.mjs.map +1 -1
  91. package/dist/es/ai-model/workflows/recorder-generation/metadata.mjs +2 -4
  92. package/dist/es/ai-model/workflows/recorder-generation/metadata.mjs.map +1 -1
  93. package/dist/es/ai-model/workflows/recorder-generation/playwright.mjs.map +1 -1
  94. package/dist/es/ai-model/workflows/recorder-generation/yaml.mjs +2 -4
  95. package/dist/es/ai-model/workflows/recorder-generation/yaml.mjs.map +1 -1
  96. package/dist/es/report-html-template.mjs +1 -1
  97. package/dist/es/service/index.mjs +17 -26
  98. package/dist/es/service/index.mjs.map +1 -1
  99. package/dist/es/types.mjs.map +1 -1
  100. package/dist/es/utils.mjs +1 -1
  101. package/dist/lib/agent/task-builder.js +1 -1
  102. package/dist/lib/agent/task-builder.js.map +1 -1
  103. package/dist/lib/agent/tasks.js +4 -4
  104. package/dist/lib/agent/tasks.js.map +1 -1
  105. package/dist/lib/agent/utils.js +1 -1
  106. package/dist/lib/ai-model/connectivity/run-connectivity-test.js +2 -5
  107. package/dist/lib/ai-model/connectivity/run-connectivity-test.js.map +1 -1
  108. package/dist/lib/ai-model/model-adapter/chat-completion.js +8 -11
  109. package/dist/lib/ai-model/model-adapter/chat-completion.js.map +1 -1
  110. package/dist/lib/ai-model/model-adapter/default-locate-protocol.js +7 -8
  111. package/dist/lib/ai-model/model-adapter/default-locate-protocol.js.map +1 -1
  112. package/dist/lib/ai-model/model-adapter/locate.js +3 -7
  113. package/dist/lib/ai-model/model-adapter/locate.js.map +1 -1
  114. package/dist/lib/ai-model/model-adapter/resolve.js +11 -3
  115. package/dist/lib/ai-model/model-adapter/resolve.js.map +1 -1
  116. package/dist/lib/ai-model/model-adapter/responses.js +75 -0
  117. package/dist/lib/ai-model/model-adapter/responses.js.map +1 -0
  118. package/dist/lib/ai-model/model-adapter/temperature-with-semantic-retry.js +41 -0
  119. package/dist/lib/ai-model/model-adapter/temperature-with-semantic-retry.js.map +1 -0
  120. package/dist/lib/ai-model/models/gpt.js +73 -9
  121. package/dist/lib/ai-model/models/gpt.js.map +1 -1
  122. package/dist/lib/ai-model/models/qwen.js +8 -2
  123. package/dist/lib/ai-model/models/qwen.js.map +1 -1
  124. package/dist/lib/ai-model/models/registry.js +2 -2
  125. package/dist/lib/ai-model/models/registry.js.map +1 -1
  126. package/dist/lib/ai-model/service-caller/call-ai.js +22 -13
  127. package/dist/lib/ai-model/service-caller/call-ai.js.map +1 -1
  128. package/dist/lib/ai-model/service-caller/codex/call-codex.js +10 -8
  129. package/dist/lib/ai-model/service-caller/codex/call-codex.js.map +1 -1
  130. package/dist/lib/ai-model/service-caller/codex/codex-app-server.js +29 -28
  131. package/dist/lib/ai-model/service-caller/codex/codex-app-server.js.map +1 -1
  132. package/dist/lib/ai-model/service-caller/index.js +0 -4
  133. package/dist/lib/ai-model/service-caller/model-call.js +4 -4
  134. package/dist/lib/ai-model/service-caller/model-call.js.map +1 -1
  135. package/dist/lib/ai-model/service-caller/openai/call-openai.js +17 -7
  136. package/dist/lib/ai-model/service-caller/openai/call-openai.js.map +1 -1
  137. package/dist/lib/ai-model/service-caller/openai/chat-completion/chat-completion.js +10 -6
  138. package/dist/lib/ai-model/service-caller/openai/chat-completion/chat-completion.js.map +1 -1
  139. package/dist/lib/ai-model/service-caller/openai/chat-completion/non-stream.js +9 -9
  140. package/dist/lib/ai-model/service-caller/openai/chat-completion/non-stream.js.map +1 -1
  141. package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js +4 -8
  142. package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js.map +1 -1
  143. package/dist/lib/ai-model/service-caller/openai/chat-completion/utils.js +32 -2
  144. package/dist/lib/ai-model/service-caller/openai/chat-completion/utils.js.map +1 -1
  145. package/dist/lib/ai-model/service-caller/openai/openai-client.js +5 -5
  146. package/dist/lib/ai-model/service-caller/openai/openai-client.js.map +1 -1
  147. package/dist/lib/ai-model/service-caller/openai/responses/non-stream.js +55 -0
  148. package/dist/lib/ai-model/service-caller/openai/responses/non-stream.js.map +1 -0
  149. package/dist/lib/ai-model/service-caller/openai/responses/responses.js +94 -0
  150. package/dist/lib/ai-model/service-caller/openai/responses/responses.js.map +1 -0
  151. package/dist/lib/ai-model/service-caller/openai/responses/stream.js +90 -0
  152. package/dist/lib/ai-model/service-caller/openai/responses/stream.js.map +1 -0
  153. package/dist/lib/ai-model/service-caller/openai/responses/types.js +20 -0
  154. package/dist/lib/ai-model/service-caller/openai/responses/types.js.map +1 -0
  155. package/dist/lib/ai-model/service-caller/openai/responses/utils.js +112 -0
  156. package/dist/lib/ai-model/service-caller/openai/responses/utils.js.map +1 -0
  157. package/dist/lib/ai-model/service-caller/semantic-retry.js.map +1 -1
  158. package/dist/lib/ai-model/service-caller/utils.js +5 -27
  159. package/dist/lib/ai-model/service-caller/utils.js.map +1 -1
  160. package/dist/lib/ai-model/shared/model-locate-result/factory.js +4 -1
  161. package/dist/lib/ai-model/shared/model-locate-result/factory.js.map +1 -1
  162. package/dist/lib/ai-model/shared/model-locate-result/prompt-spec.js +3 -2
  163. package/dist/lib/ai-model/shared/model-locate-result/prompt-spec.js.map +1 -1
  164. package/dist/lib/ai-model/shared/model-locate-result/result-field.js +50 -0
  165. package/dist/lib/ai-model/shared/model-locate-result/result-field.js.map +1 -0
  166. package/dist/lib/ai-model/shared/model-locate-result/types.js.map +1 -1
  167. package/dist/lib/ai-model/shared/multimodal-prompt.js +11 -14
  168. package/dist/lib/ai-model/shared/multimodal-prompt.js.map +1 -1
  169. package/dist/lib/ai-model/workflows/grounding/locate.js +6 -6
  170. package/dist/lib/ai-model/workflows/grounding/locate.js.map +1 -1
  171. package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js +5 -5
  172. package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js.map +1 -1
  173. package/dist/lib/ai-model/workflows/grounding/section-locate.js +5 -5
  174. package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -1
  175. package/dist/lib/ai-model/workflows/grounding/utils.js +3 -6
  176. package/dist/lib/ai-model/workflows/grounding/utils.js.map +1 -1
  177. package/dist/lib/ai-model/workflows/insight/extraction.js +8 -14
  178. package/dist/lib/ai-model/workflows/insight/extraction.js.map +1 -1
  179. package/dist/lib/ai-model/workflows/insight/order-sensitive.js.map +1 -1
  180. package/dist/lib/ai-model/workflows/planning/conversation-history.js +17 -9
  181. package/dist/lib/ai-model/workflows/planning/conversation-history.js.map +1 -1
  182. package/dist/lib/ai-model/workflows/planning/custom-planning.js +11 -13
  183. package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -1
  184. package/dist/lib/ai-model/workflows/planning/locate-normalization.js +5 -9
  185. package/dist/lib/ai-model/workflows/planning/locate-normalization.js.map +1 -1
  186. package/dist/lib/ai-model/workflows/planning/standard-planning.js +24 -27
  187. package/dist/lib/ai-model/workflows/planning/standard-planning.js.map +1 -1
  188. package/dist/lib/ai-model/workflows/recorder-generation/common.js +2 -4
  189. package/dist/lib/ai-model/workflows/recorder-generation/common.js.map +1 -1
  190. package/dist/lib/ai-model/workflows/recorder-generation/markdown.js +3 -5
  191. package/dist/lib/ai-model/workflows/recorder-generation/markdown.js.map +1 -1
  192. package/dist/lib/ai-model/workflows/recorder-generation/metadata.js +2 -4
  193. package/dist/lib/ai-model/workflows/recorder-generation/metadata.js.map +1 -1
  194. package/dist/lib/ai-model/workflows/recorder-generation/playwright.js.map +1 -1
  195. package/dist/lib/ai-model/workflows/recorder-generation/yaml.js +2 -4
  196. package/dist/lib/ai-model/workflows/recorder-generation/yaml.js.map +1 -1
  197. package/dist/lib/report-html-template.js +1 -1
  198. package/dist/lib/service/index.js +17 -26
  199. package/dist/lib/service/index.js.map +1 -1
  200. package/dist/lib/types.js.map +1 -1
  201. package/dist/lib/utils.js +1 -1
  202. package/dist/types/ai-model/connectivity/run-connectivity-test.d.ts.map +1 -1
  203. package/dist/types/ai-model/index.d.ts +1 -1
  204. package/dist/types/ai-model/index.d.ts.map +1 -1
  205. package/dist/types/ai-model/model-adapter/chat-completion.d.ts.map +1 -1
  206. package/dist/types/ai-model/model-adapter/default-locate-protocol.d.ts +2 -6
  207. package/dist/types/ai-model/model-adapter/default-locate-protocol.d.ts.map +1 -1
  208. package/dist/types/ai-model/model-adapter/locate.d.ts +1 -1
  209. package/dist/types/ai-model/model-adapter/locate.d.ts.map +1 -1
  210. package/dist/types/ai-model/model-adapter/resolve.d.ts +4 -2
  211. package/dist/types/ai-model/model-adapter/resolve.d.ts.map +1 -1
  212. package/dist/types/ai-model/model-adapter/responses.d.ts +4 -0
  213. package/dist/types/ai-model/model-adapter/responses.d.ts.map +1 -0
  214. package/dist/types/ai-model/model-adapter/temperature-with-semantic-retry.d.ts +6 -0
  215. package/dist/types/ai-model/model-adapter/temperature-with-semantic-retry.d.ts.map +1 -0
  216. package/dist/types/ai-model/model-adapter/types.d.ts +42 -20
  217. package/dist/types/ai-model/model-adapter/types.d.ts.map +1 -1
  218. package/dist/types/ai-model/models/gpt.d.ts +15 -3
  219. package/dist/types/ai-model/models/gpt.d.ts.map +1 -1
  220. package/dist/types/ai-model/models/qwen.d.ts +2 -1
  221. package/dist/types/ai-model/models/qwen.d.ts.map +1 -1
  222. package/dist/types/ai-model/models/registry.d.ts +16 -3
  223. package/dist/types/ai-model/models/registry.d.ts.map +1 -1
  224. package/dist/types/ai-model/service-caller/call-ai.d.ts +2 -2
  225. package/dist/types/ai-model/service-caller/call-ai.d.ts.map +1 -1
  226. package/dist/types/ai-model/service-caller/codex/call-codex.d.ts +4 -2
  227. package/dist/types/ai-model/service-caller/codex/call-codex.d.ts.map +1 -1
  228. package/dist/types/ai-model/service-caller/codex/codex-app-server.d.ts +5 -4
  229. package/dist/types/ai-model/service-caller/codex/codex-app-server.d.ts.map +1 -1
  230. package/dist/types/ai-model/service-caller/index.d.ts +0 -1
  231. package/dist/types/ai-model/service-caller/index.d.ts.map +1 -1
  232. package/dist/types/ai-model/service-caller/model-call.d.ts +6 -6
  233. package/dist/types/ai-model/service-caller/model-call.d.ts.map +1 -1
  234. package/dist/types/ai-model/service-caller/openai/call-openai.d.ts +9 -1
  235. package/dist/types/ai-model/service-caller/openai/call-openai.d.ts.map +1 -1
  236. package/dist/types/ai-model/service-caller/openai/chat-completion/chat-completion.d.ts +3 -4
  237. package/dist/types/ai-model/service-caller/openai/chat-completion/chat-completion.d.ts.map +1 -1
  238. package/dist/types/ai-model/service-caller/openai/chat-completion/non-stream.d.ts +1 -1
  239. package/dist/types/ai-model/service-caller/openai/chat-completion/non-stream.d.ts.map +1 -1
  240. package/dist/types/ai-model/service-caller/openai/chat-completion/stream.d.ts +1 -1
  241. package/dist/types/ai-model/service-caller/openai/chat-completion/stream.d.ts.map +1 -1
  242. package/dist/types/ai-model/service-caller/openai/chat-completion/types.d.ts +5 -5
  243. package/dist/types/ai-model/service-caller/openai/chat-completion/types.d.ts.map +1 -1
  244. package/dist/types/ai-model/service-caller/openai/chat-completion/utils.d.ts +5 -0
  245. package/dist/types/ai-model/service-caller/openai/chat-completion/utils.d.ts.map +1 -1
  246. package/dist/types/ai-model/service-caller/openai/openai-client.d.ts +2 -2
  247. package/dist/types/ai-model/service-caller/openai/openai-client.d.ts.map +1 -1
  248. package/dist/types/ai-model/service-caller/openai/responses/non-stream.d.ts +4 -0
  249. package/dist/types/ai-model/service-caller/openai/responses/non-stream.d.ts.map +1 -0
  250. package/dist/types/ai-model/service-caller/openai/responses/responses.d.ts +8 -0
  251. package/dist/types/ai-model/service-caller/openai/responses/responses.d.ts.map +1 -0
  252. package/dist/types/ai-model/service-caller/openai/responses/stream.d.ts +4 -0
  253. package/dist/types/ai-model/service-caller/openai/responses/stream.d.ts.map +1 -0
  254. package/dist/types/ai-model/service-caller/openai/responses/types.d.ts +8 -0
  255. package/dist/types/ai-model/service-caller/openai/responses/types.d.ts.map +1 -0
  256. package/dist/types/ai-model/service-caller/openai/responses/utils.d.ts +8 -0
  257. package/dist/types/ai-model/service-caller/openai/responses/utils.d.ts.map +1 -0
  258. package/dist/types/ai-model/service-caller/semantic-retry.d.ts +2 -2
  259. package/dist/types/ai-model/service-caller/semantic-retry.d.ts.map +1 -1
  260. package/dist/types/ai-model/service-caller/types.d.ts +35 -5
  261. package/dist/types/ai-model/service-caller/types.d.ts.map +1 -1
  262. package/dist/types/ai-model/service-caller/utils.d.ts +5 -9
  263. package/dist/types/ai-model/service-caller/utils.d.ts.map +1 -1
  264. package/dist/types/ai-model/shared/model-locate-result/factory.d.ts.map +1 -1
  265. package/dist/types/ai-model/shared/model-locate-result/prompt-spec.d.ts +4 -1
  266. package/dist/types/ai-model/shared/model-locate-result/prompt-spec.d.ts.map +1 -1
  267. package/dist/types/ai-model/shared/model-locate-result/result-field.d.ts +5 -0
  268. package/dist/types/ai-model/shared/model-locate-result/result-field.d.ts.map +1 -0
  269. package/dist/types/ai-model/shared/model-locate-result/types.d.ts +6 -0
  270. package/dist/types/ai-model/shared/model-locate-result/types.d.ts.map +1 -1
  271. package/dist/types/ai-model/shared/multimodal-prompt.d.ts +3 -3
  272. package/dist/types/ai-model/shared/multimodal-prompt.d.ts.map +1 -1
  273. package/dist/types/ai-model/workflows/grounding/planning-action-locate.d.ts.map +1 -1
  274. package/dist/types/ai-model/workflows/grounding/section-locate.d.ts +2 -1
  275. package/dist/types/ai-model/workflows/grounding/section-locate.d.ts.map +1 -1
  276. package/dist/types/ai-model/workflows/grounding/types.d.ts +3 -2
  277. package/dist/types/ai-model/workflows/grounding/types.d.ts.map +1 -1
  278. package/dist/types/ai-model/workflows/grounding/utils.d.ts +3 -3
  279. package/dist/types/ai-model/workflows/grounding/utils.d.ts.map +1 -1
  280. package/dist/types/ai-model/workflows/insight/extraction.d.ts +1 -1
  281. package/dist/types/ai-model/workflows/insight/extraction.d.ts.map +1 -1
  282. package/dist/types/ai-model/workflows/insight/order-sensitive.d.ts.map +1 -1
  283. package/dist/types/ai-model/workflows/planning/conversation-history.d.ts +10 -8
  284. package/dist/types/ai-model/workflows/planning/conversation-history.d.ts.map +1 -1
  285. package/dist/types/ai-model/workflows/planning/custom-planning.d.ts +2 -2
  286. package/dist/types/ai-model/workflows/planning/custom-planning.d.ts.map +1 -1
  287. package/dist/types/ai-model/workflows/planning/locate-normalization.d.ts +1 -2
  288. package/dist/types/ai-model/workflows/planning/locate-normalization.d.ts.map +1 -1
  289. package/dist/types/ai-model/workflows/planning/standard-planning.d.ts.map +1 -1
  290. package/dist/types/ai-model/workflows/recorder-generation/common.d.ts +2 -1
  291. package/dist/types/ai-model/workflows/recorder-generation/common.d.ts.map +1 -1
  292. package/dist/types/ai-model/workflows/recorder-generation/markdown.d.ts +2 -2
  293. package/dist/types/ai-model/workflows/recorder-generation/markdown.d.ts.map +1 -1
  294. package/dist/types/ai-model/workflows/recorder-generation/metadata.d.ts.map +1 -1
  295. package/dist/types/ai-model/workflows/recorder-generation/playwright.d.ts.map +1 -1
  296. package/dist/types/ai-model/workflows/recorder-generation/yaml.d.ts.map +1 -1
  297. package/dist/types/service/index.d.ts.map +1 -1
  298. package/dist/types/types.d.ts +11 -2
  299. package/dist/types/types.d.ts.map +1 -1
  300. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/qwen.mjs","sources":["../../../../src/ai-model/models/qwen.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\nimport {\n type LocateResultValue,\n createLocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../shared/model-locate-result';\n\nconst qwen25BboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n rounding: 'round',\n} as const;\nconst qwen25PointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n rounding: 'round',\n} as const;\nconst qwen3BboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\n\nfunction parseQwen25RawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any) as number[];\n if (bbox.length < 2) {\n const msg = `invalid bbox data for qwen-vl mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n }\n\n if (typeof bbox[2] === 'number' && typeof bbox[3] === 'number') {\n return createLocateResultValue(qwen25BboxCoordinatesMeta, [\n bbox[0],\n bbox[1],\n bbox[2],\n bbox[3],\n ]);\n }\n\n return createLocateResultValue(qwen25PointCoordinatesMeta, [\n bbox[0],\n bbox[1],\n ]);\n}\n\nconst buildQwenChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningBudget } = userConfig;\n\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n // Alibaba Cloud Model Studio JSON mode:\n // https://help.aliyun.com/zh/model-studio/json-mode\n // Observed in qwen3.6 grounding runs: enabling this can make the model\n // return only [\"bbox_2d\"] without coordinates.\n // if (isLocateIntent(input.intent)) {\n // commonOverrideConfig.response_format = { type: 'json_object' };\n // }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.enable_thinking = reasoningEnabled ?? false;\n if (reasoningBudget !== undefined) {\n modelSpecificConfig.thinking_budget = reasoningBudget;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst buildQwen25ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n vl_high_resolution_images: true,\n },\n };\n};\n\nconst qwen3Adapter: ModelAdapterDefinition = {\n acceptBbox2dAlias: true,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEffort'],\n buildChatCompletionParams: buildQwenChatCompletionParams,\n messageExtraction: {\n kind: 'default',\n // DashScope returns Qwen thinking as `reasoning_content`. vLLM's\n // OpenAI-compatible server is migrating the recommended field to\n // `reasoning`, so Qwen adapters accept both serving conventions:\n // https://github.com/vllm-project/vllm/issues/27755\n reasoningContentKeys: ['reasoning_content', 'reasoning'],\n },\n useReasoningAsContentFallback: true,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: qwen3BboxCoordinatesMeta,\n },\n },\n },\n};\n\nexport const qwenAdapters = {\n 'qwen2.5-vl': {\n acceptBbox2dAlias: true,\n chatCompletion: {\n unsupportedUserConfig: [\n 'reasoningEnabled',\n 'reasoningEffort',\n 'reasoningBudget',\n ],\n buildChatCompletionParams: buildQwen25ChatCompletionParams,\n },\n imagePreprocess: {\n padBlockSize: 28,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: qwen25BboxCoordinatesMeta,\n parseRawLocateValue: parseQwen25RawLocateValue,\n },\n },\n },\n },\n 'qwen3-vl': qwen3Adapter,\n qwen3: qwen3Adapter,\n 'qwen3.5': qwen3Adapter,\n 'qwen3.6': qwen3Adapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'qwen2.5-vl' | 'qwen3-vl' | 'qwen3' | 'qwen3.5' | 'qwen3.6'\n>;\n"],"names":["qwen25BboxCoordinatesMeta","qwen25PointCoordinatesMeta","qwen3BboxCoordinatesMeta","parseQwen25RawLocateValue","input","bbox","unwrapCoordinateListLikeInput","msg","JSON","Error","createLocateResultValue","buildQwenChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningBudget","commonOverrideConfig","undefined","modelSpecificConfig","buildQwen25ChatCompletionParams","qwen3Adapter","qwenAdapters"],"mappings":";AAYA,MAAMA,4BAA4B;IAChC,OAAO;IACP,OAAO;IACP,UAAU;AACZ;AACA,MAAMC,6BAA6B;IACjC,OAAO;IACP,OAAO;IACP,UAAU;AACZ;AACA,MAAMC,2BAA2B;IAC/B,OAAO;IACP,OAAO;IACP,cAAc;IACd,UAAU;AACZ;AAEA,SAASC,0BAA0BC,KAAc;IAC/C,MAAMC,OAAOC,8BAA8BF;IAC3C,IAAIC,KAAK,MAAM,GAAG,GAAG;QACnB,MAAME,MAAM,CAAC,oCAAoC,EAAEC,KAAK,SAAS,CAACH,MAAM,CAAC,CAAC;QAC1E,MAAM,IAAII,MAAMF;IAClB;IAEA,IAAI,AAAmB,YAAnB,OAAOF,IAAI,CAAC,EAAE,IAAiB,AAAmB,YAAnB,OAAOA,IAAI,CAAC,EAAE,EAC/C,OAAOK,wBAAwBV,2BAA2B;QACxDK,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;KACR;IAGH,OAAOK,wBAAwBT,4BAA4B;QACzDI,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;KACR;AACH;AAEA,MAAMM,gCAAgC,CACpCP;IAEA,MAAM,EAAEQ,gBAAgB,EAAEC,UAAU,EAAE,GAAGT;IACzC,MAAM,EAAEU,gBAAgB,EAAEC,eAAe,EAAE,GAAGF;IAE9C,MAAMG,uBAAgD,CAAC;IAEvD,IAAIH,AAA2BI,WAA3BJ,WAAW,WAAW,EACxBG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAW3D,MAAMK,sBAA+C,CAAC;IAEtD,IAAIJ,AAAqB,cAArBA,kBAAgC;QAClCI,oBAAoB,eAAe,GAAGJ,oBAAoB;QAC1D,IAAIC,AAAoBE,WAApBF,iBACFG,oBAAoB,eAAe,GAAGH;IAE1C;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGE,mBAAmB;QACxB;IACF;AACF;AAEA,MAAMC,kCAAkC,CACtCf;IAEA,MAAM,EAAEQ,gBAAgB,EAAEC,UAAU,EAAE,GAAGT;IACzC,MAAMY,uBAAgD,CAAC;IAEvD,IAAIH,AAA2BI,WAA3BJ,WAAW,WAAW,EACxBG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAG3D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,2BAA2B;QAC7B;IACF;AACF;AAEA,MAAMI,eAAuC;IAC3C,mBAAmB;IACnB,gBAAgB;QACd,uBAAuB;YAAC;SAAkB;QAC1C,2BAA2BT;QAC3B,mBAAmB;YACjB,MAAM;YAKN,sBAAsB;gBAAC;gBAAqB;aAAY;QAC1D;QACA,+BAA+B;IACjC;IACA,QAAQ;QACN,SAAS;YACP,cAAc;gBACZ,aAAaT;YACf;QACF;IACF;AACF;AAEO,MAAMmB,eAAe;IAC1B,cAAc;QACZ,mBAAmB;QACnB,gBAAgB;YACd,uBAAuB;gBACrB;gBACA;gBACA;aACD;YACD,2BAA2BF;QAC7B;QACA,iBAAiB;YACf,cAAc;QAChB;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAanB;oBACb,qBAAqBG;gBACvB;YACF;QACF;IACF;IACA,YAAYiB;IACZ,OAAOA;IACP,WAAWA;IACX,WAAWA;AACb"}
1
+ {"version":3,"file":"ai-model/models/qwen.mjs","sources":["../../../../src/ai-model/models/qwen.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\nimport {\n type LocateResultValue,\n createLocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../shared/model-locate-result';\n\nconst qwen25BboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n rounding: 'round',\n} as const;\nconst qwen25PointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n rounding: 'round',\n} as const;\nconst qwen3BboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\n\nfunction parseQwen25RawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any) as number[];\n if (bbox.length < 2) {\n const msg = `invalid bbox data for qwen-vl mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n }\n\n if (typeof bbox[2] === 'number' && typeof bbox[3] === 'number') {\n return createLocateResultValue(qwen25BboxCoordinatesMeta, [\n bbox[0],\n bbox[1],\n bbox[2],\n bbox[3],\n ]);\n }\n\n return createLocateResultValue(qwen25PointCoordinatesMeta, [\n bbox[0],\n bbox[1],\n ]);\n}\n\nconst buildQwenChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningBudget } = userConfig;\n\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n // Alibaba Cloud Model Studio JSON mode:\n // https://help.aliyun.com/zh/model-studio/json-mode\n // Observed in qwen3.6 grounding runs: enabling this can make the model\n // return only [\"bbox_2d\"] without coordinates.\n // if (isLocateIntent(input.intent)) {\n // commonOverrideConfig.response_format = { type: 'json_object' };\n // }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.enable_thinking = reasoningEnabled ?? false;\n if (reasoningBudget !== undefined) {\n modelSpecificConfig.thinking_budget = reasoningBudget;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst buildQwen25ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n vl_high_resolution_images: true,\n },\n };\n};\n\nconst qwen3Adapter: ModelAdapterDefinition = {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEffort'],\n buildChatCompletionParams: buildQwenChatCompletionParams,\n messageExtraction: {\n kind: 'default',\n // DashScope returns Qwen thinking as `reasoning_content`. vLLM's\n // OpenAI-compatible server is migrating the recommended field to\n // `reasoning`, so Qwen adapters accept both serving conventions:\n // https://github.com/vllm-project/vllm/issues/27755\n reasoningContentKeys: ['reasoning_content', 'reasoning'],\n },\n useReasoningAsContentFallback: true,\n },\n locate: {\n element: {\n resultFormat: {\n resultKey: 'bbox_2d',\n resultKeyAliases: ['bbox'],\n coordinates: qwen3BboxCoordinatesMeta,\n },\n },\n },\n};\n\nexport const qwenAdapters = {\n 'qwen2.5-vl': {\n chatCompletion: {\n unsupportedUserConfig: [\n 'reasoningEnabled',\n 'reasoningEffort',\n 'reasoningBudget',\n ],\n buildChatCompletionParams: buildQwen25ChatCompletionParams,\n },\n imagePreprocess: {\n padBlockSize: 28,\n },\n locate: {\n element: {\n resultFormat: {\n resultKey: 'bbox_2d',\n resultKeyAliases: ['bbox'],\n coordinates: qwen25BboxCoordinatesMeta,\n parseRawLocateValue: parseQwen25RawLocateValue,\n },\n },\n },\n },\n 'qwen3-vl': qwen3Adapter,\n qwen3: qwen3Adapter,\n 'qwen3.5': qwen3Adapter,\n 'qwen3.6': qwen3Adapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'qwen2.5-vl' | 'qwen3-vl' | 'qwen3' | 'qwen3.5' | 'qwen3.6'\n>;\n"],"names":["qwen25BboxCoordinatesMeta","qwen25PointCoordinatesMeta","qwen3BboxCoordinatesMeta","parseQwen25RawLocateValue","input","bbox","unwrapCoordinateListLikeInput","msg","JSON","Error","createLocateResultValue","buildQwenChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningBudget","commonOverrideConfig","undefined","modelSpecificConfig","buildQwen25ChatCompletionParams","qwen3Adapter","qwenAdapters"],"mappings":";AAYA,MAAMA,4BAA4B;IAChC,OAAO;IACP,OAAO;IACP,UAAU;AACZ;AACA,MAAMC,6BAA6B;IACjC,OAAO;IACP,OAAO;IACP,UAAU;AACZ;AACA,MAAMC,2BAA2B;IAC/B,OAAO;IACP,OAAO;IACP,cAAc;IACd,UAAU;AACZ;AAEA,SAASC,0BAA0BC,KAAc;IAC/C,MAAMC,OAAOC,8BAA8BF;IAC3C,IAAIC,KAAK,MAAM,GAAG,GAAG;QACnB,MAAME,MAAM,CAAC,oCAAoC,EAAEC,KAAK,SAAS,CAACH,MAAM,CAAC,CAAC;QAC1E,MAAM,IAAII,MAAMF;IAClB;IAEA,IAAI,AAAmB,YAAnB,OAAOF,IAAI,CAAC,EAAE,IAAiB,AAAmB,YAAnB,OAAOA,IAAI,CAAC,EAAE,EAC/C,OAAOK,wBAAwBV,2BAA2B;QACxDK,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;KACR;IAGH,OAAOK,wBAAwBT,4BAA4B;QACzDI,IAAI,CAAC,EAAE;QACPA,IAAI,CAAC,EAAE;KACR;AACH;AAEA,MAAMM,gCAAgC,CACpCP;IAEA,MAAM,EAAEQ,gBAAgB,EAAEC,UAAU,EAAE,GAAGT;IACzC,MAAM,EAAEU,gBAAgB,EAAEC,eAAe,EAAE,GAAGF;IAE9C,MAAMG,uBAAgD,CAAC;IAEvD,IAAIH,AAA2BI,WAA3BJ,WAAW,WAAW,EACxBG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAW3D,MAAMK,sBAA+C,CAAC;IAEtD,IAAIJ,AAAqB,cAArBA,kBAAgC;QAClCI,oBAAoB,eAAe,GAAGJ,oBAAoB;QAC1D,IAAIC,AAAoBE,WAApBF,iBACFG,oBAAoB,eAAe,GAAGH;IAE1C;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGE,mBAAmB;QACxB;IACF;AACF;AAEA,MAAMC,kCAAkC,CACtCf;IAEA,MAAM,EAAEQ,gBAAgB,EAAEC,UAAU,EAAE,GAAGT;IACzC,MAAMY,uBAAgD,CAAC;IAEvD,IAAIH,AAA2BI,WAA3BJ,WAAW,WAAW,EACxBG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAG3D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,2BAA2B;QAC7B;IACF;AACF;AAEA,MAAMI,eAAuC;IAC3C,gBAAgB;QACd,uBAAuB;YAAC;SAAkB;QAC1C,2BAA2BT;QAC3B,mBAAmB;YACjB,MAAM;YAKN,sBAAsB;gBAAC;gBAAqB;aAAY;QAC1D;QACA,+BAA+B;IACjC;IACA,QAAQ;QACN,SAAS;YACP,cAAc;gBACZ,WAAW;gBACX,kBAAkB;oBAAC;iBAAO;gBAC1B,aAAaT;YACf;QACF;IACF;AACF;AAEO,MAAMmB,eAAe;IAC1B,cAAc;QACZ,gBAAgB;YACd,uBAAuB;gBACrB;gBACA;gBACA;aACD;YACD,2BAA2BF;QAC7B;QACA,iBAAiB;YACf,cAAc;QAChB;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,WAAW;oBACX,kBAAkB;wBAAC;qBAAO;oBAC1B,aAAanB;oBACb,qBAAqBG;gBACvB;YACF;QACF;IACF;IACA,YAAYiB;IACZ,OAAOA;IACP,WAAWA;IACX,WAAWA;AACb"}
@@ -26,8 +26,8 @@ const MODEL_ADAPTER_CONFIGS = {
26
26
  const modelAdapterCache = new Map();
27
27
  const debugModelAdapter = getDebug('ai:model-adapter');
28
28
  function debugAdapterUnsupportedUserConfig(modelFamily, adapter) {
29
- if (0 === adapter.chatCompletion.unsupportedUserConfig.length) return;
30
- debugModelAdapter(`model adapter "${modelFamily}" unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`);
29
+ if (adapter.chatCompletion.unsupportedUserConfig.length > 0) debugModelAdapter(`model adapter "${modelFamily}" (chat-completion) unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`);
30
+ if (adapter.responses.unsupportedUserConfig.length > 0) debugModelAdapter(`model adapter "${modelFamily}" (responses) unsupportedUserConfig: ${JSON.stringify(adapter.responses.unsupportedUserConfig)}`);
31
31
  }
32
32
  function getModelAdapter(modelFamily) {
33
33
  const cacheKey = modelFamily ?? 'default';
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/registry.mjs","sources":["../../../../src/ai-model/models/registry.ts"],"sourcesContent":["import type { IModelConfig, TModelFamily } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ResolvedModelAdapter } from '../model-adapter/resolve';\nimport type {\n ModelAdapter,\n ModelAdapterDefinition,\n ModelRuntime,\n} from '../model-adapter/types';\nimport { autoGlmAdapters } from './auto-glm/adapter';\nimport { deepSeekAdapters } from './deepseek/adapter';\nimport { defaultOpenAICompatibleAdapterConfig } from './default';\nimport { doubaoAdapters } from './doubao';\nimport { geminiAdapters } from './gemini';\nimport { glmAdapters } from './glm';\nimport { gptAdapters } from './gpt';\nimport { kimiAdapters } from './kimi';\nimport { mimoAdapters } from './mimo';\nimport { qwenAdapters } from './qwen';\nimport { uiTarsAdapters } from './ui-tars/adapter';\n\nexport const MODEL_ADAPTER_CONFIGS = {\n ...qwenAdapters,\n ...deepSeekAdapters,\n ...doubaoAdapters,\n ...geminiAdapters,\n ...uiTarsAdapters,\n ...glmAdapters,\n ...autoGlmAdapters,\n ...gptAdapters,\n ...kimiAdapters,\n ...mimoAdapters,\n} satisfies Record<TModelFamily, ModelAdapterDefinition>;\n\ntype ModelAdapterCacheKey = TModelFamily | 'default';\n\nconst modelAdapterCache = new Map<ModelAdapterCacheKey, ModelAdapter>();\nconst debugModelAdapter = getDebug('ai:model-adapter');\n\nfunction debugAdapterUnsupportedUserConfig(\n modelFamily: ModelAdapterCacheKey,\n adapter: ModelAdapter,\n): void {\n if (adapter.chatCompletion.unsupportedUserConfig.length === 0) {\n return;\n }\n\n debugModelAdapter(\n `model adapter \"${modelFamily}\" unsupportedUserConfig: ${JSON.stringify(\n adapter.chatCompletion.unsupportedUserConfig,\n )}`,\n );\n}\n\nexport function getModelAdapter(modelFamily?: TModelFamily): ModelAdapter {\n const cacheKey: ModelAdapterCacheKey = modelFamily ?? 'default';\n let adapter = modelAdapterCache.get(cacheKey);\n if (adapter) {\n return adapter;\n }\n\n const config = modelFamily\n ? MODEL_ADAPTER_CONFIGS[modelFamily]\n : defaultOpenAICompatibleAdapterConfig;\n if (!config) {\n throw new Error(\n `No model adapter registered for modelFamily: ${modelFamily}`,\n );\n }\n\n adapter = new ResolvedModelAdapter(config, cacheKey);\n modelAdapterCache.set(cacheKey, adapter);\n debugAdapterUnsupportedUserConfig(cacheKey, adapter);\n\n return adapter;\n}\n\nexport function getModelRuntime(config: IModelConfig): ModelRuntime {\n return {\n config,\n adapter: getModelAdapter(config.modelFamily),\n };\n}\n"],"names":["MODEL_ADAPTER_CONFIGS","qwenAdapters","deepSeekAdapters","doubaoAdapters","geminiAdapters","uiTarsAdapters","glmAdapters","autoGlmAdapters","gptAdapters","kimiAdapters","mimoAdapters","modelAdapterCache","Map","debugModelAdapter","getDebug","debugAdapterUnsupportedUserConfig","modelFamily","adapter","JSON","getModelAdapter","cacheKey","config","defaultOpenAICompatibleAdapterConfig","Error","ResolvedModelAdapter","getModelRuntime"],"mappings":";;;;;;;;;;;;;AAoBO,MAAMA,wBAAwB;IACnC,GAAGC,YAAY;IACf,GAAGC,gBAAgB;IACnB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,WAAW;IACd,GAAGC,eAAe;IAClB,GAAGC,WAAW;IACd,GAAGC,YAAY;IACf,GAAGC,YAAY;AACjB;AAIA,MAAMC,oBAAoB,IAAIC;AAC9B,MAAMC,oBAAoBC,SAAS;AAEnC,SAASC,kCACPC,WAAiC,EACjCC,OAAqB;IAErB,IAAIA,AAAwD,MAAxDA,QAAQ,cAAc,CAAC,qBAAqB,CAAC,MAAM,EACrD;IAGFJ,kBACE,CAAC,eAAe,EAAEG,YAAY,yBAAyB,EAAEE,KAAK,SAAS,CACrED,QAAQ,cAAc,CAAC,qBAAqB,GAC3C;AAEP;AAEO,SAASE,gBAAgBH,WAA0B;IACxD,MAAMI,WAAiCJ,eAAe;IACtD,IAAIC,UAAUN,kBAAkB,GAAG,CAACS;IACpC,IAAIH,SACF,OAAOA;IAGT,MAAMI,SAASL,cACXhB,qBAAqB,CAACgB,YAAY,GAClCM;IACJ,IAAI,CAACD,QACH,MAAM,IAAIE,MACR,CAAC,6CAA6C,EAAEP,aAAa;IAIjEC,UAAU,IAAIO,qBAAqBH,QAAQD;IAC3CT,kBAAkB,GAAG,CAACS,UAAUH;IAChCF,kCAAkCK,UAAUH;IAE5C,OAAOA;AACT;AAEO,SAASQ,gBAAgBJ,MAAoB;IAClD,OAAO;QACLA;QACA,SAASF,gBAAgBE,OAAO,WAAW;IAC7C;AACF"}
1
+ {"version":3,"file":"ai-model/models/registry.mjs","sources":["../../../../src/ai-model/models/registry.ts"],"sourcesContent":["import type { IModelConfig, TModelFamily } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ResolvedModelAdapter } from '../model-adapter/resolve';\nimport type {\n ModelAdapter,\n ModelAdapterDefinition,\n ModelRuntime,\n} from '../model-adapter/types';\nimport { autoGlmAdapters } from './auto-glm/adapter';\nimport { deepSeekAdapters } from './deepseek/adapter';\nimport { defaultOpenAICompatibleAdapterConfig } from './default';\nimport { doubaoAdapters } from './doubao';\nimport { geminiAdapters } from './gemini';\nimport { glmAdapters } from './glm';\nimport { gptAdapters } from './gpt';\nimport { kimiAdapters } from './kimi';\nimport { mimoAdapters } from './mimo';\nimport { qwenAdapters } from './qwen';\nimport { uiTarsAdapters } from './ui-tars/adapter';\n\nexport const MODEL_ADAPTER_CONFIGS = {\n ...qwenAdapters,\n ...deepSeekAdapters,\n ...doubaoAdapters,\n ...geminiAdapters,\n ...uiTarsAdapters,\n ...glmAdapters,\n ...autoGlmAdapters,\n ...gptAdapters,\n ...kimiAdapters,\n ...mimoAdapters,\n} satisfies Record<TModelFamily, ModelAdapterDefinition>;\n\ntype ModelAdapterCacheKey = TModelFamily | 'default';\n\nconst modelAdapterCache = new Map<ModelAdapterCacheKey, ModelAdapter>();\nconst debugModelAdapter = getDebug('ai:model-adapter');\n\nfunction debugAdapterUnsupportedUserConfig(\n modelFamily: ModelAdapterCacheKey,\n adapter: ModelAdapter,\n): void {\n if (adapter.chatCompletion.unsupportedUserConfig.length > 0) {\n debugModelAdapter(\n `model adapter \"${modelFamily}\" (chat-completion) unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`,\n );\n }\n if (adapter.responses.unsupportedUserConfig.length > 0) {\n debugModelAdapter(\n `model adapter \"${modelFamily}\" (responses) unsupportedUserConfig: ${JSON.stringify(adapter.responses.unsupportedUserConfig)}`,\n );\n }\n}\n\nexport function getModelAdapter(modelFamily?: TModelFamily): ModelAdapter {\n const cacheKey: ModelAdapterCacheKey = modelFamily ?? 'default';\n let adapter = modelAdapterCache.get(cacheKey);\n if (adapter) {\n return adapter;\n }\n\n const config = modelFamily\n ? MODEL_ADAPTER_CONFIGS[modelFamily]\n : defaultOpenAICompatibleAdapterConfig;\n if (!config) {\n throw new Error(\n `No model adapter registered for modelFamily: ${modelFamily}`,\n );\n }\n\n adapter = new ResolvedModelAdapter(config, cacheKey);\n modelAdapterCache.set(cacheKey, adapter);\n debugAdapterUnsupportedUserConfig(cacheKey, adapter);\n\n return adapter;\n}\n\nexport function getModelRuntime(config: IModelConfig): ModelRuntime {\n return {\n config,\n adapter: getModelAdapter(config.modelFamily),\n };\n}\n"],"names":["MODEL_ADAPTER_CONFIGS","qwenAdapters","deepSeekAdapters","doubaoAdapters","geminiAdapters","uiTarsAdapters","glmAdapters","autoGlmAdapters","gptAdapters","kimiAdapters","mimoAdapters","modelAdapterCache","Map","debugModelAdapter","getDebug","debugAdapterUnsupportedUserConfig","modelFamily","adapter","JSON","getModelAdapter","cacheKey","config","defaultOpenAICompatibleAdapterConfig","Error","ResolvedModelAdapter","getModelRuntime"],"mappings":";;;;;;;;;;;;;AAoBO,MAAMA,wBAAwB;IACnC,GAAGC,YAAY;IACf,GAAGC,gBAAgB;IACnB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,WAAW;IACd,GAAGC,eAAe;IAClB,GAAGC,WAAW;IACd,GAAGC,YAAY;IACf,GAAGC,YAAY;AACjB;AAIA,MAAMC,oBAAoB,IAAIC;AAC9B,MAAMC,oBAAoBC,SAAS;AAEnC,SAASC,kCACPC,WAAiC,EACjCC,OAAqB;IAErB,IAAIA,QAAQ,cAAc,CAAC,qBAAqB,CAAC,MAAM,GAAG,GACxDJ,kBACE,CAAC,eAAe,EAAEG,YAAY,2CAA2C,EAAEE,KAAK,SAAS,CAACD,QAAQ,cAAc,CAAC,qBAAqB,GAAG;IAG7I,IAAIA,QAAQ,SAAS,CAAC,qBAAqB,CAAC,MAAM,GAAG,GACnDJ,kBACE,CAAC,eAAe,EAAEG,YAAY,qCAAqC,EAAEE,KAAK,SAAS,CAACD,QAAQ,SAAS,CAAC,qBAAqB,GAAG;AAGpI;AAEO,SAASE,gBAAgBH,WAA0B;IACxD,MAAMI,WAAiCJ,eAAe;IACtD,IAAIC,UAAUN,kBAAkB,GAAG,CAACS;IACpC,IAAIH,SACF,OAAOA;IAGT,MAAMI,SAASL,cACXhB,qBAAqB,CAACgB,YAAY,GAClCM;IACJ,IAAI,CAACD,QACH,MAAM,IAAIE,MACR,CAAC,6CAA6C,EAAEP,aAAa;IAIjEC,UAAU,IAAIO,qBAAqBH,QAAQD;IAC3CT,kBAAkB,GAAG,CAACS,UAAUH;IAChCF,kCAAkCK,UAAUH;IAE5C,OAAOA;AACT;AAEO,SAASQ,gBAAgBJ,MAAoB;IAClD,OAAO;QACLA;QACA,SAASF,gBAAgBE,OAAO,WAAW;IAC7C;AACF"}
@@ -5,6 +5,7 @@ import { isCodexAppServerProvider } from "./codex/codex-app-server.mjs";
5
5
  import { isModelCallRecordingEnabled, recordModelCallEvent } from "./model-call-recorder.mjs";
6
6
  import { callOpenAI } from "./openai/call-openai.mjs";
7
7
  import { prepareChatCompletion } from "./openai/chat-completion/chat-completion.mjs";
8
+ import { prepareResponses } from "./openai/responses/responses.mjs";
8
9
  import { buildRequestAbortSignal, resolveEffectiveTimeoutMs, runWithAbortSignal, waitForRetry } from "./request-timeout.mjs";
9
10
  import { appendAIRequestFailureSummary, buildUsageInfo, nextInternalCallId, normalizeRetryCount, toError } from "./utils.mjs";
10
11
  function _define_property(obj, key, value) {
@@ -17,6 +18,7 @@ function _define_property(obj, key, value) {
17
18
  else obj[key] = value;
18
19
  return obj;
19
20
  }
21
+ const DEFAULT_MODEL_PROTOCOL = 'openai-chat';
20
22
  async function callAI(messages, modelRuntime, options) {
21
23
  options?.abortSignal?.throwIfAborted();
22
24
  const isStreaming = options?.stream === true;
@@ -24,21 +26,27 @@ async function callAI(messages, modelRuntime, options) {
24
26
  const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;
25
27
  const internalCallId = nextInternalCallId();
26
28
  const { config: modelConfig } = modelRuntime;
27
- const prepare = async ()=>isCodexAppServerProvider(modelConfig.openaiBaseURL) ? {
29
+ const prepare = async ()=>{
30
+ const input = {
31
+ messages,
32
+ modelRuntime,
33
+ options
34
+ };
35
+ if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) return {
28
36
  protocol: 'codex',
29
- input: prepareCodexCall({
30
- messages,
31
- modelRuntime,
32
- options
33
- })
34
- } : {
37
+ input: prepareCodexCall(input)
38
+ };
39
+ const protocol = modelConfig.protocol ?? DEFAULT_MODEL_PROTOCOL;
40
+ assert(modelRuntime.adapter.supportedProtocols.includes(protocol), `Model adapter "${modelConfig.modelFamily ?? 'default'}" does not support protocol "${protocol}"`);
41
+ if ('openai-responses' === protocol) return {
42
+ protocol: 'responses',
43
+ input: await prepareResponses(input)
44
+ };
45
+ return {
35
46
  protocol: 'chat-completion',
36
- input: await prepareChatCompletion({
37
- messages,
38
- modelRuntime,
39
- options
40
- })
47
+ input: await prepareChatCompletion(input)
41
48
  };
49
+ };
42
50
  const prepared = options?.abortSignal ? await runWithAbortSignal(options.abortSignal, prepare) : await prepare();
43
51
  const result = await callModelWithRetry({
44
52
  messages,
@@ -50,6 +58,7 @@ async function callAI(messages, modelRuntime, options) {
50
58
  });
51
59
  const { rawUsage, timeCost, totalTimeCost, retryCount, requestId, responseModelName, ...response } = result;
52
60
  const usage = buildUsageInfo({
61
+ apiType: prepared.protocol,
53
62
  usageData: rawUsage,
54
63
  timeCost,
55
64
  totalTimeCost,
@@ -145,7 +154,7 @@ async function callModelOnce({ messages, modelRuntime, options, executionId, int
145
154
  } : options
146
155
  };
147
156
  try {
148
- return await runWithAbortSignal(requestSignal, ()=>'codex' === prepared.protocol ? callCodex(context, prepared.input) : callOpenAI(context, prepared.input));
157
+ return await runWithAbortSignal(requestSignal, ()=>'codex' === prepared.protocol ? callCodex(context, prepared.input) : callOpenAI(context, prepared));
149
158
  } catch (error) {
150
159
  options?.abortSignal?.throwIfAborted();
151
160
  const lastError = toError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/call-ai.mjs","sources":["../../../../src/ai-model/service-caller/call-ai.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nexport async function callAI(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n const isStreaming = options?.stream === true;\n if (isStreaming) {\n assert(\n typeof options?.onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n }\n\n // Low-level callers without a TaskRunner still need a stable ID for the\n // lifetime of this model call (including its network retries).\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n\n // Stable internal ID for this call, used by the agent to deduplicate usage\n // across the onUsage callback and the task-dump-based collectUsageMetrics()\n // path when the provider does not return a request_id.\n const internalCallId = nextInternalCallId();\n\n const { config: modelConfig } = modelRuntime;\n\n const prepare = async (): Promise<PreparedModelInput> =>\n isCodexAppServerProvider(modelConfig.openaiBaseURL)\n ? {\n protocol: 'codex',\n input: prepareCodexCall({ messages, modelRuntime, options }),\n }\n : {\n protocol: 'chat-completion',\n input: await prepareChatCompletion({\n messages,\n modelRuntime,\n options,\n }),\n };\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const usage = buildUsageInfo({\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | { protocol: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | {\n protocol: 'chat-completion';\n input: Awaited<ReturnType<typeof prepareChatCompletion>>;\n };\n\ntype ModelCallInput = {\n messages: ChatCompletionMessageParam[];\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', { console: true })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordEvent = isModelCallRecordingEnabled()\n ? (event: Record<string, unknown>) => {\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n messages,\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.protocol === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared.input),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["callAI","messages","modelRuntime","options","isStreaming","assert","executionId","uuid","internalCallId","nextInternalCallId","modelConfig","prepare","isCodexAppServerProvider","prepareCodexCall","prepareChatCompletion","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","usage","buildUsageInfo","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","input","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordEvent","isModelCallRecordingEnabled","event","recordModelCallEvent","undefined","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","callCodex","callOpenAI"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/service-caller/call-ai.mjs","sources":["../../../../src/ai-model/service-caller/call-ai.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { type PreparedOpenAIInput, callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport { prepareResponses } from './openai/responses/responses';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport type { ModelCallMessages } from './types';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nconst DEFAULT_MODEL_PROTOCOL = 'openai-chat';\n\nexport async function callAI(\n messages: ModelCallMessages,\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n const isStreaming = options?.stream === true;\n if (isStreaming) {\n assert(\n typeof options?.onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n }\n\n // Low-level callers without a TaskRunner still need a stable ID for the\n // lifetime of this model call (including its network retries).\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n\n // Stable internal ID for this call, used by the agent to deduplicate usage\n // across the onUsage callback and the task-dump-based collectUsageMetrics()\n // path when the provider does not return a request_id.\n const internalCallId = nextInternalCallId();\n\n const { config: modelConfig } = modelRuntime;\n\n const prepare = async (): Promise<PreparedModelInput> => {\n const input = { messages, modelRuntime, options };\n if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) {\n return { protocol: 'codex', input: prepareCodexCall(input) };\n }\n const protocol = modelConfig.protocol ?? DEFAULT_MODEL_PROTOCOL;\n\n assert(\n modelRuntime.adapter.supportedProtocols.includes(protocol),\n `Model adapter \"${modelConfig.modelFamily ?? 'default'}\" does not support protocol \"${protocol}\"`,\n );\n if (protocol === 'openai-responses') {\n return { protocol: 'responses', input: await prepareResponses(input) };\n }\n return {\n protocol: 'chat-completion',\n input: await prepareChatCompletion(input),\n };\n };\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const usage = buildUsageInfo({\n apiType: prepared.protocol,\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | { protocol: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | PreparedOpenAIInput;\n\ntype ModelCallInput = {\n messages: ModelCallMessages;\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', { console: true })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordEvent = isModelCallRecordingEnabled()\n ? (event: Record<string, unknown>) => {\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n messages,\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.protocol === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["DEFAULT_MODEL_PROTOCOL","callAI","messages","modelRuntime","options","isStreaming","assert","executionId","uuid","internalCallId","nextInternalCallId","modelConfig","prepare","input","isCodexAppServerProvider","prepareCodexCall","protocol","prepareResponses","prepareChatCompletion","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","usage","buildUsageInfo","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordEvent","isModelCallRecordingEnabled","event","recordModelCallEvent","undefined","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","callCodex","callOpenAI"],"mappings":"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"}
@@ -1,8 +1,7 @@
1
- import { applyImageDetail } from "../utils.mjs";
2
1
  import { callAIWithCodexAppServer } from "./codex-app-server.mjs";
3
2
  const prepareCodexCall = ({ messages, modelRuntime, options })=>{
4
3
  const { config: modelConfig, adapter } = modelRuntime;
5
- const { config, imageDetail } = adapter.buildCodexAppServerParams({
4
+ const { config } = adapter.buildCodexAppServerParams({
6
5
  intent: modelConfig.intent,
7
6
  userConfig: {
8
7
  reasoningEnabled: modelConfig.reasoningEnabled,
@@ -11,16 +10,18 @@ const prepareCodexCall = ({ messages, modelRuntime, options })=>{
11
10
  },
12
11
  requiresOriginalImageDetail: options?.requiresOriginalImageDetail
13
12
  });
14
- const messagesWithImageDetail = applyImageDetail({
15
- imageDetail,
16
- messages
17
- });
13
+ const resolveImageDetail = ({ imageDetail })=>adapter.resolveImageDetail({
14
+ imageDetail,
15
+ intent: modelConfig.intent,
16
+ requiresOriginalImageDetail: options?.requiresOriginalImageDetail
17
+ });
18
18
  return {
19
- messages: messagesWithImageDetail,
19
+ messages,
20
+ resolveImageDetail,
20
21
  requestParams: config
21
22
  };
22
23
  };
23
- const callCodex = async ({ modelRuntime, options, recordEvent, requestSignal }, { messages, requestParams })=>{
24
+ const callCodex = async ({ modelRuntime, options, recordEvent, requestSignal }, { messages, resolveImageDetail, requestParams })=>{
24
25
  const { config: modelConfig } = modelRuntime;
25
26
  let protocolChunkSequence = 0;
26
27
  const codexStartTime = Date.now();
@@ -46,6 +47,7 @@ const callCodex = async ({ modelRuntime, options, recordEvent, requestSignal },
46
47
  stream: options?.stream,
47
48
  onChunk: options?.onChunk,
48
49
  params: requestParams,
50
+ resolveImageDetail,
49
51
  abortSignal: requestSignal,
50
52
  onRecordEvent: recordCodexEvent
51
53
  });
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/codex/call-codex.mjs","sources":["../../../../../src/ai-model/service-caller/codex/call-codex.ts"],"sourcesContent":["import type { ModelCallContext, ModelCallResult } from '../types';\nimport { applyImageDetail } from '../utils';\nimport {\n type CodexAppServerRecordEvent,\n callAIWithCodexAppServer,\n} from './codex-app-server';\n\nexport const prepareCodexCall = ({\n messages,\n modelRuntime,\n options,\n}: Pick<ModelCallContext, 'messages' | 'modelRuntime' | 'options'>) => {\n const { config: modelConfig, adapter } = modelRuntime;\n const { config, imageDetail } = adapter.buildCodexAppServerParams({\n intent: modelConfig.intent,\n userConfig: {\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n },\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n const messagesWithImageDetail = applyImageDetail({ imageDetail, messages });\n return { messages: messagesWithImageDetail, requestParams: config };\n};\n\nexport const callCodex = async (\n { modelRuntime, options, recordEvent, requestSignal }: ModelCallContext,\n { messages, requestParams }: ReturnType<typeof prepareCodexCall>,\n): Promise<ModelCallResult> => {\n const { config: modelConfig } = modelRuntime;\n let protocolChunkSequence = 0;\n const codexStartTime = Date.now();\n const recordCodexEvent = recordEvent\n ? (event: CodexAppServerRecordEvent) => {\n if (event.type === 'chunk') {\n protocolChunkSequence += 1;\n recordEvent({\n ...event,\n attempt: 1,\n sequence: protocolChunkSequence,\n provider: 'codex-app-server',\n });\n return;\n }\n\n recordEvent({\n ...event,\n attempt: 1,\n provider: 'codex-app-server',\n });\n }\n : undefined;\n\n try {\n const codexResult = await callAIWithCodexAppServer(messages, modelConfig, {\n stream: options?.stream,\n onChunk: options?.onChunk,\n params: requestParams,\n abortSignal: requestSignal,\n onRecordEvent: recordCodexEvent,\n });\n requestSignal.throwIfAborted();\n const { protocolMetadata, usage: rawUsage, ...response } = codexResult;\n const timeCost = Date.now() - codexStartTime;\n recordEvent?.({\n type: 'response',\n attempt: 1,\n provider: 'codex-app-server',\n final: {\n content: response.content,\n reasoningContent: response.reasoning_content,\n usage: rawUsage,\n timeCost,\n protocol: protocolMetadata,\n },\n });\n return {\n ...response,\n rawUsage,\n timeCost,\n requestId: protocolMetadata.turnId,\n };\n } catch (error) {\n recordEvent?.({\n type: 'error',\n attempt: 1,\n provider: 'codex-app-server',\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : String(error),\n });\n throw error;\n }\n};\n"],"names":["prepareCodexCall","messages","modelRuntime","options","modelConfig","adapter","config","imageDetail","messagesWithImageDetail","applyImageDetail","callCodex","recordEvent","requestSignal","requestParams","protocolChunkSequence","codexStartTime","Date","recordCodexEvent","event","undefined","codexResult","callAIWithCodexAppServer","protocolMetadata","rawUsage","response","timeCost","error","Error","String"],"mappings":";;AAOO,MAAMA,mBAAmB,CAAC,EAC/BC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACyD;IAChE,MAAM,EAAE,QAAQC,WAAW,EAAEC,OAAO,EAAE,GAAGH;IACzC,MAAM,EAAEI,MAAM,EAAEC,WAAW,EAAE,GAAGF,QAAQ,yBAAyB,CAAC;QAChE,QAAQD,YAAY,MAAM;QAC1B,YAAY;YACV,kBAAkBA,YAAY,gBAAgB;YAC9C,iBAAiBA,YAAY,eAAe;YAC5C,iBAAiBA,YAAY,eAAe;QAC9C;QACA,6BAA6BD,SAAS;IACxC;IACA,MAAMK,0BAA0BC,iBAAiB;QAAEF;QAAaN;IAAS;IACzE,OAAO;QAAE,UAAUO;QAAyB,eAAeF;IAAO;AACpE;AAEO,MAAMI,YAAY,OACvB,EAAER,YAAY,EAAEC,OAAO,EAAEQ,WAAW,EAAEC,aAAa,EAAoB,EACvE,EAAEX,QAAQ,EAAEY,aAAa,EAAuC;IAEhE,MAAM,EAAE,QAAQT,WAAW,EAAE,GAAGF;IAChC,IAAIY,wBAAwB;IAC5B,MAAMC,iBAAiBC,KAAK,GAAG;IAC/B,MAAMC,mBAAmBN,cACrB,CAACO;QACC,IAAIA,AAAe,YAAfA,MAAM,IAAI,EAAc;YAC1BJ,yBAAyB;YACzBH,YAAY;gBACV,GAAGO,KAAK;gBACR,SAAS;gBACT,UAAUJ;gBACV,UAAU;YACZ;YACA;QACF;QAEAH,YAAY;YACV,GAAGO,KAAK;YACR,SAAS;YACT,UAAU;QACZ;IACF,IACAC;IAEJ,IAAI;QACF,MAAMC,cAAc,MAAMC,yBAAyBpB,UAAUG,aAAa;YACxE,QAAQD,SAAS;YACjB,SAASA,SAAS;YAClB,QAAQU;YACR,aAAaD;YACb,eAAeK;QACjB;QACAL,cAAc,cAAc;QAC5B,MAAM,EAAEU,gBAAgB,EAAE,OAAOC,QAAQ,EAAE,GAAGC,UAAU,GAAGJ;QAC3D,MAAMK,WAAWT,KAAK,GAAG,KAAKD;QAC9BJ,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OAAO;gBACL,SAASa,SAAS,OAAO;gBACzB,kBAAkBA,SAAS,iBAAiB;gBAC5C,OAAOD;gBACPE;gBACA,UAAUH;YACZ;QACF;QACA,OAAO;YACL,GAAGE,QAAQ;YACXD;YACAE;YACA,WAAWH,iBAAiB,MAAM;QACpC;IACF,EAAE,OAAOI,OAAO;QACdf,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OACEe,iBAAiBC,QACb;gBACE,MAAMD,MAAM,IAAI;gBAChB,SAASA,MAAM,OAAO;gBACtB,OAAOA,MAAM,KAAK;YACpB,IACAE,OAAOF;QACf;QACA,MAAMA;IACR;AACF"}
1
+ {"version":3,"file":"ai-model/service-caller/codex/call-codex.mjs","sources":["../../../../../src/ai-model/service-caller/codex/call-codex.ts"],"sourcesContent":["import type { ResolveImageDetail } from '../../model-adapter/types';\nimport type { ModelCallContext, ModelCallResult } from '../types';\nimport {\n type CodexAppServerRecordEvent,\n callAIWithCodexAppServer,\n} from './codex-app-server';\n\nexport const prepareCodexCall = ({\n messages,\n modelRuntime,\n options,\n}: Pick<ModelCallContext, 'messages' | 'modelRuntime' | 'options'>) => {\n const { config: modelConfig, adapter } = modelRuntime;\n const { config } = adapter.buildCodexAppServerParams({\n intent: modelConfig.intent,\n userConfig: {\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n },\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n const resolveImageDetail: ResolveImageDetail = ({ imageDetail }) =>\n adapter.resolveImageDetail({\n imageDetail,\n intent: modelConfig.intent,\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n return { messages, resolveImageDetail, requestParams: config };\n};\n\nexport const callCodex = async (\n { modelRuntime, options, recordEvent, requestSignal }: ModelCallContext,\n {\n messages,\n resolveImageDetail,\n requestParams,\n }: ReturnType<typeof prepareCodexCall>,\n): Promise<ModelCallResult> => {\n const { config: modelConfig } = modelRuntime;\n let protocolChunkSequence = 0;\n const codexStartTime = Date.now();\n const recordCodexEvent = recordEvent\n ? (event: CodexAppServerRecordEvent) => {\n if (event.type === 'chunk') {\n protocolChunkSequence += 1;\n recordEvent({\n ...event,\n attempt: 1,\n sequence: protocolChunkSequence,\n provider: 'codex-app-server',\n });\n return;\n }\n\n recordEvent({\n ...event,\n attempt: 1,\n provider: 'codex-app-server',\n });\n }\n : undefined;\n\n try {\n const codexResult = await callAIWithCodexAppServer(messages, modelConfig, {\n stream: options?.stream,\n onChunk: options?.onChunk,\n params: requestParams,\n resolveImageDetail,\n abortSignal: requestSignal,\n onRecordEvent: recordCodexEvent,\n });\n requestSignal.throwIfAborted();\n const { protocolMetadata, usage: rawUsage, ...response } = codexResult;\n const timeCost = Date.now() - codexStartTime;\n recordEvent?.({\n type: 'response',\n attempt: 1,\n provider: 'codex-app-server',\n final: {\n content: response.content,\n reasoningContent: response.reasoning_content,\n usage: rawUsage,\n timeCost,\n protocol: protocolMetadata,\n },\n });\n return {\n ...response,\n rawUsage,\n timeCost,\n requestId: protocolMetadata.turnId,\n };\n } catch (error) {\n recordEvent?.({\n type: 'error',\n attempt: 1,\n provider: 'codex-app-server',\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : String(error),\n });\n throw error;\n }\n};\n"],"names":["prepareCodexCall","messages","modelRuntime","options","modelConfig","adapter","config","resolveImageDetail","imageDetail","callCodex","recordEvent","requestSignal","requestParams","protocolChunkSequence","codexStartTime","Date","recordCodexEvent","event","undefined","codexResult","callAIWithCodexAppServer","protocolMetadata","rawUsage","response","timeCost","error","Error","String"],"mappings":";AAOO,MAAMA,mBAAmB,CAAC,EAC/BC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACyD;IAChE,MAAM,EAAE,QAAQC,WAAW,EAAEC,OAAO,EAAE,GAAGH;IACzC,MAAM,EAAEI,MAAM,EAAE,GAAGD,QAAQ,yBAAyB,CAAC;QACnD,QAAQD,YAAY,MAAM;QAC1B,YAAY;YACV,kBAAkBA,YAAY,gBAAgB;YAC9C,iBAAiBA,YAAY,eAAe;YAC5C,iBAAiBA,YAAY,eAAe;QAC9C;QACA,6BAA6BD,SAAS;IACxC;IACA,MAAMI,qBAAyC,CAAC,EAAEC,WAAW,EAAE,GAC7DH,QAAQ,kBAAkB,CAAC;YACzBG;YACA,QAAQJ,YAAY,MAAM;YAC1B,6BAA6BD,SAAS;QACxC;IACF,OAAO;QAAEF;QAAUM;QAAoB,eAAeD;IAAO;AAC/D;AAEO,MAAMG,YAAY,OACvB,EAAEP,YAAY,EAAEC,OAAO,EAAEO,WAAW,EAAEC,aAAa,EAAoB,EACvE,EACEV,QAAQ,EACRM,kBAAkB,EAClBK,aAAa,EACuB;IAEtC,MAAM,EAAE,QAAQR,WAAW,EAAE,GAAGF;IAChC,IAAIW,wBAAwB;IAC5B,MAAMC,iBAAiBC,KAAK,GAAG;IAC/B,MAAMC,mBAAmBN,cACrB,CAACO;QACC,IAAIA,AAAe,YAAfA,MAAM,IAAI,EAAc;YAC1BJ,yBAAyB;YACzBH,YAAY;gBACV,GAAGO,KAAK;gBACR,SAAS;gBACT,UAAUJ;gBACV,UAAU;YACZ;YACA;QACF;QAEAH,YAAY;YACV,GAAGO,KAAK;YACR,SAAS;YACT,UAAU;QACZ;IACF,IACAC;IAEJ,IAAI;QACF,MAAMC,cAAc,MAAMC,yBAAyBnB,UAAUG,aAAa;YACxE,QAAQD,SAAS;YACjB,SAASA,SAAS;YAClB,QAAQS;YACRL;YACA,aAAaI;YACb,eAAeK;QACjB;QACAL,cAAc,cAAc;QAC5B,MAAM,EAAEU,gBAAgB,EAAE,OAAOC,QAAQ,EAAE,GAAGC,UAAU,GAAGJ;QAC3D,MAAMK,WAAWT,KAAK,GAAG,KAAKD;QAC9BJ,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OAAO;gBACL,SAASa,SAAS,OAAO;gBACzB,kBAAkBA,SAAS,iBAAiB;gBAC5C,OAAOD;gBACPE;gBACA,UAAUH;YACZ;QACF;QACA,OAAO;YACL,GAAGE,QAAQ;YACXD;YACAE;YACA,WAAWH,iBAAiB,MAAM;QACpC;IACF,EAAE,OAAOI,OAAO;QACdf,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OACEe,iBAAiBC,QACb;gBACE,MAAMD,MAAM,IAAI;gBAChB,SAASA,MAAM,OAAO;gBACtB,OAAOA,MAAM,KAAK;YACpB,IACAE,OAAOF;QACf;QACA,MAAMA;IACR;AACF"}
@@ -52,7 +52,6 @@ const toNonEmptyString = (value)=>{
52
52
  const trimmed = value.trim();
53
53
  return trimmed || void 0;
54
54
  };
55
- const toCodexImageDetail = (value)=>'auto' === value || 'low' === value || 'high' === value || 'original' === value ? value : void 0;
56
55
  const normalizeCodexLocalImagePath = (imageUrl, platform = process.platform)=>{
57
56
  if (!imageUrl.startsWith('file://')) return imageUrl;
58
57
  try {
@@ -71,54 +70,54 @@ const normalizeCodexLocalImagePath = (imageUrl, platform = process.platform)=>{
71
70
  }
72
71
  };
73
72
  const extractTextFromMessage = (message)=>{
74
- const content = message.content;
73
+ const { content } = message;
75
74
  if ('string' == typeof content) return content;
76
- if (Array.isArray(content)) return content.map((part)=>{
77
- if (!part || 'object' != typeof part) return '';
78
- if ('text' === part.type && 'string' == typeof part.text) return part.text;
79
- if ('input_text' === part.type && 'string' == typeof part.text) return part.text;
80
- return '';
81
- }).filter(Boolean).join('\n');
82
- return '';
75
+ return content.map((part)=>'text' === part.type ? part.text : '').filter(Boolean).join('\n');
83
76
  };
84
- const extractImageInputs = (message)=>{
85
- const content = message.content;
77
+ const extractImageInputs = (message, resolveImageDetail)=>{
78
+ const { content } = message;
86
79
  if (!Array.isArray(content)) return [];
87
80
  const inputs = [];
88
81
  for (const part of content){
89
- if (!part || 'object' != typeof part) continue;
90
- const partType = String(part.type || '');
91
- const imageUrl = 'image_url' === partType ? toNonEmptyString(part.image_url?.url) : 'input_image' === partType ? toNonEmptyString(part.image_url || part.url) : void 0;
92
- const imageDetail = toCodexImageDetail('image_url' === partType ? part.image_url?.detail : part.detail);
82
+ if ('image' !== part.type) continue;
83
+ const imageUrl = toNonEmptyString(part.url);
84
+ const detail = resolveImageDetail({
85
+ imageDetail: part.detail
86
+ });
93
87
  if (imageUrl) {
94
88
  if (imageUrl.startsWith('/') || imageUrl.startsWith('./') || imageUrl.startsWith('../') || imageUrl.startsWith('file://')) {
95
89
  const path = imageUrl.startsWith('file://') ? normalizeCodexLocalImagePath(imageUrl) : imageUrl;
96
90
  inputs.push({
97
91
  type: 'localImage',
98
92
  path,
99
- ...imageDetail ? {
100
- detail: imageDetail
101
- } : {}
93
+ detail
102
94
  });
103
95
  continue;
104
96
  }
105
97
  inputs.push({
106
98
  type: 'image',
107
99
  url: imageUrl,
108
- ...imageDetail ? {
109
- detail: imageDetail
110
- } : {}
100
+ detail
111
101
  });
112
102
  }
113
103
  }
114
104
  return inputs;
115
105
  };
116
- const buildCodexTurnPayloadFromMessages = (messages)=>{
106
+ const buildCodexTurnPayloadFromMessages = (messages, resolveImageDetail)=>{
117
107
  const developerInstructionParts = [];
118
108
  const transcriptParts = [];
119
109
  const imageInputs = [];
120
- for (const message of messages){
121
- const role = String(message.role || 'user');
110
+ for (const entry of messages){
111
+ const message = (()=>{
112
+ if ('role' in entry) return entry;
113
+ if ('input-message' === entry.type) return entry.message;
114
+ if ('chat-completion' !== entry.output.type) throw new Error('Cannot replay Responses output in a Codex conversation');
115
+ return {
116
+ role: 'assistant',
117
+ content: entry.output.rawValue.content ?? ''
118
+ };
119
+ })();
120
+ const { role } = message;
122
121
  const text = extractTextFromMessage(message);
123
122
  if ('system' === role) {
124
123
  if (text.trim()) developerInstructionParts.push(text.trim());
@@ -127,7 +126,7 @@ const buildCodexTurnPayloadFromMessages = (messages)=>{
127
126
  const roleTag = role.toUpperCase();
128
127
  if (text.trim()) transcriptParts.push(`[${roleTag}]\n${text.trim()}`);
129
128
  else transcriptParts.push(`[${roleTag}]\n(no text content)`);
130
- if ('user' === role) imageInputs.push(...extractImageInputs(message));
129
+ if ('user' === role) imageInputs.push(...extractImageInputs(message, resolveImageDetail));
131
130
  }
132
131
  const fullTranscript = transcriptParts.join('\n\n');
133
132
  const transcriptText = (fullTranscript.length > CODEX_TEXT_INPUT_MAX_LENGTH ? fullTranscript.slice(-CODEX_TEXT_INPUT_MAX_LENGTH) : fullTranscript) || 'Please answer the latest user request.';
@@ -175,9 +174,9 @@ class CodexAppServerConnection {
175
174
  isClosed() {
176
175
  return this.closed;
177
176
  }
178
- async runTurn({ messages, modelConfig, stream, onChunk, params, abortSignal, onRecordEvent }) {
177
+ async runTurn({ messages, resolveImageDetail, modelConfig, stream, onChunk, params, abortSignal, onRecordEvent }) {
179
178
  const isStreaming = !!(stream && onChunk);
180
- const { developerInstructions, input } = buildCodexTurnPayloadFromMessages(messages);
179
+ const { developerInstructions, input } = buildCodexTurnPayloadFromMessages(messages, resolveImageDetail);
181
180
  let threadId;
182
181
  let turnId;
183
182
  let latestErrorMessage;
@@ -550,7 +549,7 @@ class CodexAppServerConnection {
550
549
  }
551
550
  }
552
551
  class CodexAppServerConnectionManager {
553
- async runTurn({ messages, modelConfig, stream, onChunk, params, abortSignal, onRecordEvent }) {
552
+ async runTurn({ messages, resolveImageDetail, modelConfig, stream, onChunk, params, abortSignal, onRecordEvent }) {
554
553
  return this.runner.run(async ()=>{
555
554
  abortSignal?.throwIfAborted();
556
555
  const connection = await this.getConnection();
@@ -558,6 +557,7 @@ class CodexAppServerConnectionManager {
558
557
  try {
559
558
  return await connection.runTurn({
560
559
  messages,
560
+ resolveImageDetail,
561
561
  modelConfig,
562
562
  stream,
563
563
  onChunk,
@@ -599,6 +599,7 @@ async function callAIWithCodexAppServer(messages, modelConfig, options) {
599
599
  return codexConnectionManager.runTurn({
600
600
  messages,
601
601
  modelConfig,
602
+ resolveImageDetail: options.resolveImageDetail,
602
603
  stream: options?.stream,
603
604
  onChunk: options?.onChunk,
604
605
  params: options?.params,