@midscene/core 1.12.5-beta-20260908034641.0 → 1.12.5

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 (165) hide show
  1. package/dist/es/agent/agent.mjs +6 -1
  2. package/dist/es/agent/agent.mjs.map +1 -1
  3. package/dist/es/agent/progress/ai-act-progress.mjs +2 -23
  4. package/dist/es/agent/progress/ai-act-progress.mjs.map +1 -1
  5. package/dist/es/agent/task-builder.mjs +21 -24
  6. package/dist/es/agent/task-builder.mjs.map +1 -1
  7. package/dist/es/agent/utils.mjs +24 -23
  8. package/dist/es/agent/utils.mjs.map +1 -1
  9. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs +1 -8
  10. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs.map +1 -1
  11. package/dist/es/ai-model/model-adapter/codex-app-server.mjs +23 -0
  12. package/dist/es/ai-model/model-adapter/codex-app-server.mjs.map +1 -0
  13. package/dist/es/ai-model/model-adapter/custom-planning-action.mjs +3 -3
  14. package/dist/es/ai-model/model-adapter/custom-planning-action.mjs.map +1 -1
  15. package/dist/es/ai-model/model-adapter/resolve.mjs +3 -0
  16. package/dist/es/ai-model/model-adapter/resolve.mjs.map +1 -1
  17. package/dist/es/ai-model/models/auto-glm/locate.mjs +2 -2
  18. package/dist/es/ai-model/models/auto-glm/locate.mjs.map +1 -1
  19. package/dist/es/ai-model/models/deepseek/adapter.mjs +4 -2
  20. package/dist/es/ai-model/models/deepseek/adapter.mjs.map +1 -1
  21. package/dist/es/ai-model/models/doubao.mjs +4 -2
  22. package/dist/es/ai-model/models/doubao.mjs.map +1 -1
  23. package/dist/es/ai-model/models/gpt.mjs +60 -2
  24. package/dist/es/ai-model/models/gpt.mjs.map +1 -1
  25. package/dist/es/ai-model/models/kimi.mjs +4 -2
  26. package/dist/es/ai-model/models/kimi.mjs.map +1 -1
  27. package/dist/es/ai-model/models/qwen.mjs +8 -28
  28. package/dist/es/ai-model/models/qwen.mjs.map +1 -1
  29. package/dist/es/ai-model/models/ui-tars/adapter.mjs +4 -2
  30. package/dist/es/ai-model/models/ui-tars/adapter.mjs.map +1 -1
  31. package/dist/es/ai-model/service-caller/codex-app-server.mjs +7 -17
  32. package/dist/es/ai-model/service-caller/codex-app-server.mjs.map +1 -1
  33. package/dist/es/ai-model/service-caller/index.mjs +5 -4
  34. package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
  35. package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs +2 -1
  36. package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs.map +1 -1
  37. package/dist/es/ai-model/shared/model-locate-result/factory.mjs +21 -21
  38. package/dist/es/ai-model/shared/model-locate-result/factory.mjs.map +1 -1
  39. package/dist/es/ai-model/shared/model-locate-result/pixel-mapper.mjs +87 -0
  40. package/dist/es/ai-model/shared/model-locate-result/pixel-mapper.mjs.map +1 -0
  41. package/dist/es/ai-model/shared/model-locate-result/types.mjs.map +1 -1
  42. package/dist/es/ai-model/shared/model-locate-result/validation.mjs +55 -0
  43. package/dist/es/ai-model/shared/model-locate-result/validation.mjs.map +1 -0
  44. package/dist/es/ai-model/workflows/grounding/locate.mjs +11 -13
  45. package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -1
  46. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs +3 -3
  47. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs.map +1 -1
  48. package/dist/es/ai-model/workflows/grounding/search-area-mapping.mjs +27 -11
  49. package/dist/es/ai-model/workflows/grounding/search-area-mapping.mjs.map +1 -1
  50. package/dist/es/ai-model/workflows/grounding/search-area.mjs +26 -1
  51. package/dist/es/ai-model/workflows/grounding/search-area.mjs.map +1 -1
  52. package/dist/es/ai-model/workflows/grounding/section-locate.mjs +4 -8
  53. package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -1
  54. package/dist/es/ai-model/workflows/planning/locate-normalization.mjs +2 -1
  55. package/dist/es/ai-model/workflows/planning/locate-normalization.mjs.map +1 -1
  56. package/dist/es/ai-model/workflows/planning/standard-planning.mjs.map +1 -1
  57. package/dist/es/common.mjs +2 -9
  58. package/dist/es/common.mjs.map +1 -1
  59. package/dist/es/element-describer.mjs +2 -2
  60. package/dist/es/element-describer.mjs.map +1 -1
  61. package/dist/es/report-html-template.mjs +1 -1
  62. package/dist/es/service/index.mjs +13 -11
  63. package/dist/es/service/index.mjs.map +1 -1
  64. package/dist/es/types.mjs.map +1 -1
  65. package/dist/es/utils.mjs +1 -1
  66. package/dist/lib/agent/agent.js +6 -1
  67. package/dist/lib/agent/agent.js.map +1 -1
  68. package/dist/lib/agent/progress/ai-act-progress.js +2 -23
  69. package/dist/lib/agent/progress/ai-act-progress.js.map +1 -1
  70. package/dist/lib/agent/task-builder.js +20 -23
  71. package/dist/lib/agent/task-builder.js.map +1 -1
  72. package/dist/lib/agent/utils.js +26 -28
  73. package/dist/lib/agent/utils.js.map +1 -1
  74. package/dist/lib/ai-model/connectivity/run-connectivity-test.js +1 -8
  75. package/dist/lib/ai-model/connectivity/run-connectivity-test.js.map +1 -1
  76. package/dist/lib/ai-model/{workflows/grounding/locate-result-rect.js → model-adapter/codex-app-server.js} +22 -25
  77. package/dist/lib/ai-model/model-adapter/codex-app-server.js.map +1 -0
  78. package/dist/lib/ai-model/model-adapter/custom-planning-action.js +5 -5
  79. package/dist/lib/ai-model/model-adapter/custom-planning-action.js.map +1 -1
  80. package/dist/lib/ai-model/model-adapter/resolve.js +3 -0
  81. package/dist/lib/ai-model/model-adapter/resolve.js.map +1 -1
  82. package/dist/lib/ai-model/models/auto-glm/locate.js +1 -1
  83. package/dist/lib/ai-model/models/auto-glm/locate.js.map +1 -1
  84. package/dist/lib/ai-model/models/deepseek/adapter.js +4 -2
  85. package/dist/lib/ai-model/models/deepseek/adapter.js.map +1 -1
  86. package/dist/lib/ai-model/models/doubao.js +4 -2
  87. package/dist/lib/ai-model/models/doubao.js.map +1 -1
  88. package/dist/lib/ai-model/models/gpt.js +60 -2
  89. package/dist/lib/ai-model/models/gpt.js.map +1 -1
  90. package/dist/lib/ai-model/models/kimi.js +4 -2
  91. package/dist/lib/ai-model/models/kimi.js.map +1 -1
  92. package/dist/lib/ai-model/models/qwen.js +7 -27
  93. package/dist/lib/ai-model/models/qwen.js.map +1 -1
  94. package/dist/lib/ai-model/models/ui-tars/adapter.js +4 -2
  95. package/dist/lib/ai-model/models/ui-tars/adapter.js.map +1 -1
  96. package/dist/lib/ai-model/service-caller/codex-app-server.js +7 -20
  97. package/dist/lib/ai-model/service-caller/codex-app-server.js.map +1 -1
  98. package/dist/lib/ai-model/service-caller/index.js +5 -4
  99. package/dist/lib/ai-model/service-caller/index.js.map +1 -1
  100. package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js +2 -1
  101. package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js.map +1 -1
  102. package/dist/lib/ai-model/shared/model-locate-result/factory.js +21 -21
  103. package/dist/lib/ai-model/shared/model-locate-result/factory.js.map +1 -1
  104. package/dist/lib/ai-model/shared/model-locate-result/pixel-mapper.js +139 -0
  105. package/dist/lib/ai-model/shared/model-locate-result/pixel-mapper.js.map +1 -0
  106. package/dist/lib/ai-model/shared/model-locate-result/types.js.map +1 -1
  107. package/dist/lib/ai-model/shared/model-locate-result/validation.js +92 -0
  108. package/dist/lib/ai-model/shared/model-locate-result/validation.js.map +1 -0
  109. package/dist/lib/ai-model/workflows/grounding/locate.js +10 -12
  110. package/dist/lib/ai-model/workflows/grounding/locate.js.map +1 -1
  111. package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js +3 -3
  112. package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js.map +1 -1
  113. package/dist/lib/ai-model/workflows/grounding/search-area-mapping.js +35 -13
  114. package/dist/lib/ai-model/workflows/grounding/search-area-mapping.js.map +1 -1
  115. package/dist/lib/ai-model/workflows/grounding/search-area.js +30 -2
  116. package/dist/lib/ai-model/workflows/grounding/search-area.js.map +1 -1
  117. package/dist/lib/ai-model/workflows/grounding/section-locate.js +3 -7
  118. package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -1
  119. package/dist/lib/ai-model/workflows/planning/locate-normalization.js +2 -1
  120. package/dist/lib/ai-model/workflows/planning/locate-normalization.js.map +1 -1
  121. package/dist/lib/ai-model/workflows/planning/standard-planning.js.map +1 -1
  122. package/dist/lib/common.js +2 -9
  123. package/dist/lib/common.js.map +1 -1
  124. package/dist/lib/element-describer.js +2 -2
  125. package/dist/lib/element-describer.js.map +1 -1
  126. package/dist/lib/report-html-template.js +1 -1
  127. package/dist/lib/service/index.js +13 -11
  128. package/dist/lib/service/index.js.map +1 -1
  129. package/dist/lib/types.js.map +1 -1
  130. package/dist/lib/utils.js +1 -1
  131. package/dist/types/agent/agent.d.ts +7 -12
  132. package/dist/types/agent/utils.d.ts +8 -9
  133. package/dist/types/ai-model/model-adapter/codex-app-server.d.ts +2 -0
  134. package/dist/types/ai-model/model-adapter/custom-planning-action.d.ts +3 -2
  135. package/dist/types/ai-model/model-adapter/resolve.d.ts +2 -1
  136. package/dist/types/ai-model/model-adapter/types.d.ts +18 -3
  137. package/dist/types/ai-model/models/deepseek/adapter.d.ts +2 -0
  138. package/dist/types/ai-model/models/gpt.d.ts +21 -2
  139. package/dist/types/ai-model/models/kimi.d.ts +2 -0
  140. package/dist/types/ai-model/models/qwen.d.ts +2 -3
  141. package/dist/types/ai-model/models/registry.d.ts +25 -2
  142. package/dist/types/ai-model/service-caller/codex-app-server.d.ts +3 -7
  143. package/dist/types/ai-model/shared/model-locate-result/index.d.ts +1 -1
  144. package/dist/types/ai-model/shared/model-locate-result/pixel-mapper.d.ts +24 -0
  145. package/dist/types/ai-model/shared/model-locate-result/types.d.ts +33 -71
  146. package/dist/types/ai-model/shared/model-locate-result/validation.d.ts +3 -0
  147. package/dist/types/ai-model/workflows/grounding/search-area-mapping.d.ts +8 -3
  148. package/dist/types/ai-model/workflows/grounding/search-area.d.ts +6 -3
  149. package/dist/types/ai-model/workflows/grounding/types.d.ts +4 -3
  150. package/dist/types/types.d.ts +2 -3
  151. package/package.json +2 -2
  152. package/dist/es/ai-model/shared/model-locate-result/bbox.mjs +0 -60
  153. package/dist/es/ai-model/shared/model-locate-result/bbox.mjs.map +0 -1
  154. package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs +0 -67
  155. package/dist/es/ai-model/shared/model-locate-result/pixel-bbox-mapper.mjs.map +0 -1
  156. package/dist/es/ai-model/workflows/grounding/locate-result-rect.mjs +0 -23
  157. package/dist/es/ai-model/workflows/grounding/locate-result-rect.mjs.map +0 -1
  158. package/dist/lib/ai-model/shared/model-locate-result/bbox.js +0 -106
  159. package/dist/lib/ai-model/shared/model-locate-result/bbox.js.map +0 -1
  160. package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js +0 -101
  161. package/dist/lib/ai-model/shared/model-locate-result/pixel-bbox-mapper.js.map +0 -1
  162. package/dist/lib/ai-model/workflows/grounding/locate-result-rect.js.map +0 -1
  163. package/dist/types/ai-model/shared/model-locate-result/bbox.d.ts +0 -6
  164. package/dist/types/ai-model/shared/model-locate-result/pixel-bbox-mapper.d.ts +0 -7
  165. package/dist/types/ai-model/workflows/grounding/locate-result-rect.d.ts +0 -5
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/model-adapter/custom-planning-action.mjs","sources":["../../../../src/ai-model/model-adapter/custom-planning-action.ts"],"sourcesContent":["import type { LocateResultPoint, PixelBbox, PlanningAction } from '@/types';\n\n// AutoGLM and UI-TARS both produce point coordinates before normalization.\ntype PreNormalizedPlanningLocateParam = {\n prompt: string;\n point: LocateResultPoint;\n};\n\nexport type LocateActionParam = {\n locate: PreNormalizedPlanningLocateParam;\n};\n\nexport type LocatePlanningAction<TType extends string> =\n PlanningAction<LocateActionParam> & {\n type: TType;\n };\n\nexport type ScrollPlanningAction = PlanningAction<\n LocateActionParam & {\n distance: number;\n direction: 'up' | 'down' | 'left' | 'right';\n }\n> & {\n type: 'Scroll';\n};\n\nexport type DragAndDropPlanningAction = PlanningAction<{\n from: PreNormalizedPlanningLocateParam;\n to: PreNormalizedPlanningLocateParam;\n}> & {\n type: 'DragAndDrop';\n};\n\ntype TapPlanningActionWithLocatedPixelBbox = PlanningAction<{\n locate: {\n locatedPixelBbox: PixelBbox;\n };\n}>;\n\nexport function getTapLocatedPixelBbox(\n actions: PlanningAction[],\n): PixelBbox | undefined {\n for (const action of actions) {\n if (action.type !== 'Tap') {\n continue;\n }\n\n return (action as TapPlanningActionWithLocatedPixelBbox).param.locate\n .locatedPixelBbox;\n }\n\n return undefined;\n}\n"],"names":["getTapLocatedPixelBbox","actions","action"],"mappings":"AAuCO,SAASA,uBACdC,OAAyB;IAEzB,KAAK,MAAMC,UAAUD,QACnB,IAAIC,AAAgB,UAAhBA,OAAO,IAAI,EAIf,OAAQA,OAAiD,KAAK,CAAC,MAAM,CAClE,gBAAgB;AAIvB"}
1
+ {"version":3,"file":"ai-model/model-adapter/custom-planning-action.mjs","sources":["../../../../src/ai-model/model-adapter/custom-planning-action.ts"],"sourcesContent":["import type { LocateResultPoint, PlanningAction } from '@/types';\nimport type { PixelLocateResult } from '../shared/model-locate-result';\n\n// AutoGLM and UI-TARS both produce point coordinates before normalization.\ntype PreNormalizedPlanningLocateParam = {\n prompt: string;\n point: LocateResultPoint;\n};\n\nexport type LocateActionParam = {\n locate: PreNormalizedPlanningLocateParam;\n};\n\nexport type LocatePlanningAction<TType extends string> =\n PlanningAction<LocateActionParam> & {\n type: TType;\n };\n\nexport type ScrollPlanningAction = PlanningAction<\n LocateActionParam & {\n distance: number;\n direction: 'up' | 'down' | 'left' | 'right';\n }\n> & {\n type: 'Scroll';\n};\n\nexport type DragAndDropPlanningAction = PlanningAction<{\n from: PreNormalizedPlanningLocateParam;\n to: PreNormalizedPlanningLocateParam;\n}> & {\n type: 'DragAndDrop';\n};\n\ntype TapPlanningActionWithLocatedPixelResult = PlanningAction<{\n locate: {\n locatedPixelResult: PixelLocateResult;\n };\n}>;\n\nexport function getTapLocatedPixelResult(\n actions: PlanningAction[],\n): PixelLocateResult | undefined {\n for (const action of actions) {\n if (action.type !== 'Tap') {\n continue;\n }\n\n return (action as TapPlanningActionWithLocatedPixelResult).param.locate\n .locatedPixelResult;\n }\n\n return undefined;\n}\n"],"names":["getTapLocatedPixelResult","actions","action"],"mappings":"AAwCO,SAASA,yBACdC,OAAyB;IAEzB,KAAK,MAAMC,UAAUD,QACnB,IAAIC,AAAgB,UAAhBA,OAAO,IAAI,EAIf,OAAQA,OAAmD,KAAK,CAAC,MAAM,CACpE,kBAAkB;AAIzB"}
@@ -1,5 +1,6 @@
1
1
  import { parseModelResponseJson } from "../shared/json.mjs";
2
2
  import { resolveChatCompletion } from "./chat-completion.mjs";
3
+ import { buildDefaultCodexAppServerParams } from "./codex-app-server.mjs";
3
4
  import { resolveInsight } from "./insight.mjs";
4
5
  import { resolveLocate } from "./locate.mjs";
5
6
  import { resolveCustomPlanningDefinition, resolvePlanning } from "./planning.mjs";
@@ -27,6 +28,7 @@ class ResolvedModelAdapter {
27
28
  constructor(config, modelFamily){
28
29
  _define_property(this, "jsonParser", void 0);
29
30
  _define_property(this, "chatCompletion", void 0);
31
+ _define_property(this, "buildCodexAppServerParams", void 0);
30
32
  _define_property(this, "acceptBbox2dAlias", void 0);
31
33
  _define_property(this, "imagePreprocess", void 0);
32
34
  _define_property(this, "insight", void 0);
@@ -34,6 +36,7 @@ class ResolvedModelAdapter {
34
36
  _define_property(this, "locate", void 0);
35
37
  this.jsonParser = resolveJsonParser(config.jsonParser);
36
38
  this.chatCompletion = resolveChatCompletion(config.chatCompletion);
39
+ this.buildCodexAppServerParams = config.buildCodexAppServerParams ?? buildDefaultCodexAppServerParams;
37
40
  this.acceptBbox2dAlias = config.acceptBbox2dAlias ?? false;
38
41
  this.imagePreprocess = resolveImagePreprocess(config.imagePreprocess);
39
42
  this.insight = resolveInsight(config.insight, {
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/model-adapter/resolve.mjs","sources":["../../../../src/ai-model/model-adapter/resolve.ts"],"sourcesContent":["import { parseModelResponseJson } from '../shared/json';\nimport { resolveChatCompletion } from './chat-completion';\nimport { resolveInsight } from './insight';\nimport type { InsightAdapter } from './insight-protocol';\nimport { resolveLocate } from './locate';\nimport { resolveCustomPlanningDefinition, resolvePlanning } from './planning';\nimport type {\n ChatCompletionAdapter,\n ImagePreprocessPolicy,\n JsonParser,\n LocateAdapter,\n ModelAdapter,\n ModelAdapterDefinition,\n PlanningAdapter,\n} from './types';\n\nfunction resolveJsonParser(\n jsonParser: ModelAdapterDefinition['jsonParser'],\n): JsonParser {\n if (!jsonParser || jsonParser === 'lenient-json') {\n return parseModelResponseJson;\n }\n\n if (typeof jsonParser === 'function') {\n return jsonParser;\n }\n\n throw new Error(`Unknown json parser preset: ${jsonParser}`);\n}\n\nfunction resolveImagePreprocess(\n imagePreprocess: ModelAdapterDefinition['imagePreprocess'],\n): ImagePreprocessPolicy {\n return {\n padBlockSize: imagePreprocess?.padBlockSize,\n };\n}\n\nexport class ResolvedModelAdapter implements ModelAdapter {\n readonly jsonParser: JsonParser;\n readonly chatCompletion: ChatCompletionAdapter;\n readonly acceptBbox2dAlias: boolean;\n readonly imagePreprocess: ImagePreprocessPolicy;\n readonly insight: InsightAdapter;\n readonly planning: PlanningAdapter;\n readonly locate: LocateAdapter;\n\n constructor(config: ModelAdapterDefinition, modelFamily: string) {\n this.jsonParser = resolveJsonParser(config.jsonParser);\n this.chatCompletion = resolveChatCompletion(config.chatCompletion);\n this.acceptBbox2dAlias = config.acceptBbox2dAlias ?? false;\n this.imagePreprocess = resolveImagePreprocess(config.imagePreprocess);\n this.insight = resolveInsight(config.insight, {\n jsonParser: this.jsonParser,\n });\n const customPlanner =\n config.planning?.kind === 'custom' ? config.planning.planner : undefined;\n const resolvedCustomPlanner = customPlanner\n ? resolveCustomPlanningDefinition(customPlanner)\n : undefined;\n this.locate = resolveLocate(\n config.locate,\n resolvedCustomPlanner,\n {\n jsonParser: this.jsonParser,\n },\n this.acceptBbox2dAlias,\n );\n this.planning = resolvePlanning(\n config.planning,\n resolvedCustomPlanner,\n { jsonParser: this.jsonParser },\n this.locate.kind === 'standard'\n ? this.locate.element.resultCodec\n : undefined,\n );\n }\n}\n"],"names":["resolveJsonParser","jsonParser","parseModelResponseJson","Error","resolveImagePreprocess","imagePreprocess","ResolvedModelAdapter","config","modelFamily","resolveChatCompletion","resolveInsight","customPlanner","undefined","resolvedCustomPlanner","resolveCustomPlanningDefinition","resolveLocate","resolvePlanning"],"mappings":";;;;;;;;;;;;;;;AAgBA,SAASA,kBACPC,UAAgD;IAEhD,IAAI,CAACA,cAAcA,AAAe,mBAAfA,YACjB,OAAOC;IAGT,IAAI,AAAsB,cAAtB,OAAOD,YACT,OAAOA;IAGT,MAAM,IAAIE,MAAM,CAAC,4BAA4B,EAAEF,YAAY;AAC7D;AAEA,SAASG,uBACPC,eAA0D;IAE1D,OAAO;QACL,cAAcA,iBAAiB;IACjC;AACF;AAEO,MAAMC;IASX,YAAYC,MAA8B,EAAEC,WAAmB,CAAE;QARjE,uBAAS,cAAT;QACA,uBAAS,kBAAT;QACA,uBAAS,qBAAT;QACA,uBAAS,mBAAT;QACA,uBAAS,WAAT;QACA,uBAAS,YAAT;QACA,uBAAS,UAAT;QAGE,IAAI,CAAC,UAAU,GAAGR,kBAAkBO,OAAO,UAAU;QACrD,IAAI,CAAC,cAAc,GAAGE,sBAAsBF,OAAO,cAAc;QACjE,IAAI,CAAC,iBAAiB,GAAGA,OAAO,iBAAiB,IAAI;QACrD,IAAI,CAAC,eAAe,GAAGH,uBAAuBG,OAAO,eAAe;QACpE,IAAI,CAAC,OAAO,GAAGG,eAAeH,OAAO,OAAO,EAAE;YAC5C,YAAY,IAAI,CAAC,UAAU;QAC7B;QACA,MAAMI,gBACJJ,OAAO,QAAQ,EAAE,SAAS,WAAWA,OAAO,QAAQ,CAAC,OAAO,GAAGK;QACjE,MAAMC,wBAAwBF,gBAC1BG,gCAAgCH,iBAChCC;QACJ,IAAI,CAAC,MAAM,GAAGG,cACZR,OAAO,MAAM,EACbM,uBACA;YACE,YAAY,IAAI,CAAC,UAAU;QAC7B,GACA,IAAI,CAAC,iBAAiB;QAExB,IAAI,CAAC,QAAQ,GAAGG,gBACdT,OAAO,QAAQ,EACfM,uBACA;YAAE,YAAY,IAAI,CAAC,UAAU;QAAC,GAC9B,AAAqB,eAArB,IAAI,CAAC,MAAM,CAAC,IAAI,GACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,GAC/BD;IAER;AACF"}
1
+ {"version":3,"file":"ai-model/model-adapter/resolve.mjs","sources":["../../../../src/ai-model/model-adapter/resolve.ts"],"sourcesContent":["import { parseModelResponseJson } from '../shared/json';\nimport { resolveChatCompletion } from './chat-completion';\nimport { buildDefaultCodexAppServerParams } from './codex-app-server';\nimport { resolveInsight } from './insight';\nimport type { InsightAdapter } from './insight-protocol';\nimport { resolveLocate } from './locate';\nimport { resolveCustomPlanningDefinition, resolvePlanning } from './planning';\nimport type {\n BuildCodexAppServerParams,\n ChatCompletionAdapter,\n ImagePreprocessPolicy,\n JsonParser,\n LocateAdapter,\n ModelAdapter,\n ModelAdapterDefinition,\n PlanningAdapter,\n} from './types';\n\nfunction resolveJsonParser(\n jsonParser: ModelAdapterDefinition['jsonParser'],\n): JsonParser {\n if (!jsonParser || jsonParser === 'lenient-json') {\n return parseModelResponseJson;\n }\n\n if (typeof jsonParser === 'function') {\n return jsonParser;\n }\n\n throw new Error(`Unknown json parser preset: ${jsonParser}`);\n}\n\nfunction resolveImagePreprocess(\n imagePreprocess: ModelAdapterDefinition['imagePreprocess'],\n): ImagePreprocessPolicy {\n return {\n padBlockSize: imagePreprocess?.padBlockSize,\n };\n}\n\nexport class ResolvedModelAdapter implements ModelAdapter {\n readonly jsonParser: JsonParser;\n readonly chatCompletion: ChatCompletionAdapter;\n readonly buildCodexAppServerParams: BuildCodexAppServerParams;\n readonly acceptBbox2dAlias: boolean;\n readonly imagePreprocess: ImagePreprocessPolicy;\n readonly insight: InsightAdapter;\n readonly planning: PlanningAdapter;\n readonly locate: LocateAdapter;\n\n constructor(config: ModelAdapterDefinition, modelFamily: string) {\n this.jsonParser = resolveJsonParser(config.jsonParser);\n this.chatCompletion = resolveChatCompletion(config.chatCompletion);\n this.buildCodexAppServerParams =\n config.buildCodexAppServerParams ?? buildDefaultCodexAppServerParams;\n this.acceptBbox2dAlias = config.acceptBbox2dAlias ?? false;\n this.imagePreprocess = resolveImagePreprocess(config.imagePreprocess);\n this.insight = resolveInsight(config.insight, {\n jsonParser: this.jsonParser,\n });\n const customPlanner =\n config.planning?.kind === 'custom' ? config.planning.planner : undefined;\n const resolvedCustomPlanner = customPlanner\n ? resolveCustomPlanningDefinition(customPlanner)\n : undefined;\n this.locate = resolveLocate(\n config.locate,\n resolvedCustomPlanner,\n {\n jsonParser: this.jsonParser,\n },\n this.acceptBbox2dAlias,\n );\n this.planning = resolvePlanning(\n config.planning,\n resolvedCustomPlanner,\n { jsonParser: this.jsonParser },\n this.locate.kind === 'standard'\n ? this.locate.element.resultCodec\n : undefined,\n );\n }\n}\n"],"names":["resolveJsonParser","jsonParser","parseModelResponseJson","Error","resolveImagePreprocess","imagePreprocess","ResolvedModelAdapter","config","modelFamily","resolveChatCompletion","buildDefaultCodexAppServerParams","resolveInsight","customPlanner","undefined","resolvedCustomPlanner","resolveCustomPlanningDefinition","resolveLocate","resolvePlanning"],"mappings":";;;;;;;;;;;;;;;;AAkBA,SAASA,kBACPC,UAAgD;IAEhD,IAAI,CAACA,cAAcA,AAAe,mBAAfA,YACjB,OAAOC;IAGT,IAAI,AAAsB,cAAtB,OAAOD,YACT,OAAOA;IAGT,MAAM,IAAIE,MAAM,CAAC,4BAA4B,EAAEF,YAAY;AAC7D;AAEA,SAASG,uBACPC,eAA0D;IAE1D,OAAO;QACL,cAAcA,iBAAiB;IACjC;AACF;AAEO,MAAMC;IAUX,YAAYC,MAA8B,EAAEC,WAAmB,CAAE;QATjE,uBAAS,cAAT;QACA,uBAAS,kBAAT;QACA,uBAAS,6BAAT;QACA,uBAAS,qBAAT;QACA,uBAAS,mBAAT;QACA,uBAAS,WAAT;QACA,uBAAS,YAAT;QACA,uBAAS,UAAT;QAGE,IAAI,CAAC,UAAU,GAAGR,kBAAkBO,OAAO,UAAU;QACrD,IAAI,CAAC,cAAc,GAAGE,sBAAsBF,OAAO,cAAc;QACjE,IAAI,CAAC,yBAAyB,GAC5BA,OAAO,yBAAyB,IAAIG;QACtC,IAAI,CAAC,iBAAiB,GAAGH,OAAO,iBAAiB,IAAI;QACrD,IAAI,CAAC,eAAe,GAAGH,uBAAuBG,OAAO,eAAe;QACpE,IAAI,CAAC,OAAO,GAAGI,eAAeJ,OAAO,OAAO,EAAE;YAC5C,YAAY,IAAI,CAAC,UAAU;QAC7B;QACA,MAAMK,gBACJL,OAAO,QAAQ,EAAE,SAAS,WAAWA,OAAO,QAAQ,CAAC,OAAO,GAAGM;QACjE,MAAMC,wBAAwBF,gBAC1BG,gCAAgCH,iBAChCC;QACJ,IAAI,CAAC,MAAM,GAAGG,cACZT,OAAO,MAAM,EACbO,uBACA;YACE,YAAY,IAAI,CAAC,UAAU;QAC7B,GACA,IAAI,CAAC,iBAAiB;QAExB,IAAI,CAAC,QAAQ,GAAGG,gBACdV,OAAO,QAAQ,EACfO,uBACA;YAAE,YAAY,IAAI,CAAC,UAAU;QAAC,GAC9B,AAAqB,eAArB,IAAI,CAAC,MAAM,CAAC,IAAI,GACZ,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,WAAW,GAC/BD;IAER;AACF"}
@@ -1,9 +1,9 @@
1
- import { getTapLocatedPixelBbox } from "../../model-adapter/custom-planning-action.mjs";
1
+ import { getTapLocatedPixelResult } from "../../model-adapter/custom-planning-action.mjs";
2
2
  import { getAutoGLMChineseLocatePrompt, getAutoGLMMultilingualLocatePrompt } from "./prompt.mjs";
3
3
  function createAutoGlmPlanningTapLocator(isMultilingual) {
4
4
  return {
5
5
  buildSystemPrompt: ()=>isMultilingual ? getAutoGLMMultilingualLocatePrompt() : getAutoGLMChineseLocatePrompt(),
6
- getLocatedPixelBbox: getTapLocatedPixelBbox
6
+ getLocatedPixelResult: getTapLocatedPixelResult
7
7
  };
8
8
  }
9
9
  export { createAutoGlmPlanningTapLocator };
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/auto-glm/locate.mjs","sources":["../../../../../src/ai-model/models/auto-glm/locate.ts"],"sourcesContent":["import { getTapLocatedPixelBbox } from '../../model-adapter/custom-planning-action';\nimport type { PlanningTapLocatorDefinition } from '../../model-adapter/types';\nimport {\n getAutoGLMChineseLocatePrompt,\n getAutoGLMMultilingualLocatePrompt,\n} from './prompt';\n\nexport function createAutoGlmPlanningTapLocator(\n isMultilingual: boolean,\n): PlanningTapLocatorDefinition {\n return {\n buildSystemPrompt: () =>\n isMultilingual\n ? getAutoGLMMultilingualLocatePrompt()\n : getAutoGLMChineseLocatePrompt(),\n getLocatedPixelBbox: getTapLocatedPixelBbox,\n };\n}\n"],"names":["createAutoGlmPlanningTapLocator","isMultilingual","getAutoGLMMultilingualLocatePrompt","getAutoGLMChineseLocatePrompt","getTapLocatedPixelBbox"],"mappings":";;AAOO,SAASA,gCACdC,cAAuB;IAEvB,OAAO;QACL,mBAAmB,IACjBA,iBACIC,uCACAC;QACN,qBAAqBC;IACvB;AACF"}
1
+ {"version":3,"file":"ai-model/models/auto-glm/locate.mjs","sources":["../../../../../src/ai-model/models/auto-glm/locate.ts"],"sourcesContent":["import { getTapLocatedPixelResult } from '../../model-adapter/custom-planning-action';\nimport type { PlanningTapLocatorDefinition } from '../../model-adapter/types';\nimport {\n getAutoGLMChineseLocatePrompt,\n getAutoGLMMultilingualLocatePrompt,\n} from './prompt';\n\nexport function createAutoGlmPlanningTapLocator(\n isMultilingual: boolean,\n): PlanningTapLocatorDefinition {\n return {\n buildSystemPrompt: () =>\n isMultilingual\n ? getAutoGLMMultilingualLocatePrompt()\n : getAutoGLMChineseLocatePrompt(),\n getLocatedPixelResult: getTapLocatedPixelResult,\n };\n}\n"],"names":["createAutoGlmPlanningTapLocator","isMultilingual","getAutoGLMMultilingualLocatePrompt","getAutoGLMChineseLocatePrompt","getTapLocatedPixelResult"],"mappings":";;AAOO,SAASA,gCACdC,cAAuB;IAEvB,OAAO;QACL,mBAAmB,IACjBA,iBACIC,uCACAC;QACN,uBAAuBC;IACzB;AACF"}
@@ -3,12 +3,14 @@ import { deepSeekElementLocateProtocol, deepSeekSearchAreaProtocol } from "./loc
3
3
  const deepSeekPointCoordinates = {
4
4
  shape: 'point',
5
5
  order: 'xy',
6
- normalizedBy: 1000
6
+ normalizedBy: 1000,
7
+ rounding: 'round'
7
8
  };
8
9
  const deepSeekBboxCoordinates = {
9
10
  shape: 'bbox',
10
11
  order: 'xy',
11
- normalizedBy: 1000
12
+ normalizedBy: 1000,
13
+ rounding: 'round'
12
14
  };
13
15
  function parseDeepSeekCoordinateValues(input, expectedLength, label) {
14
16
  const coordinateTexts = String(input).match(/\d+/g);
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/deepseek/adapter.mjs","sources":["../../../../../src/ai-model/models/deepseek/adapter.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} from '../../shared/model-locate-result';\nimport {\n deepSeekElementLocateProtocol,\n deepSeekSearchAreaProtocol,\n} from './locate-protocol';\n\nconst deepSeekPointCoordinates = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1000,\n} as const;\n\nconst deepSeekBboxCoordinates = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n} as const;\n\nfunction parseDeepSeekCoordinateValues(\n input: unknown,\n expectedLength: number,\n label: string,\n): number[] {\n const coordinateTexts = String(input).match(/\\d+/g);\n if (coordinateTexts?.length !== expectedLength) {\n throw new Error(\n `DeepSeek ${label} locate result must contain exactly ${expectedLength} positive integers, got ${coordinateTexts?.length ?? 0}`,\n );\n }\n\n return coordinateTexts.map(Number);\n}\n\nfunction parseDeepSeekPointLocateValue(input: unknown): LocateResultValue {\n return createLocateResultValue(\n deepSeekPointCoordinates,\n parseDeepSeekCoordinateValues(input, 2, 'point'),\n );\n}\n\nfunction parseDeepSeekBboxLocateValue(input: unknown): LocateResultValue {\n return createLocateResultValue(\n deepSeekBboxCoordinates,\n parseDeepSeekCoordinateValues(input, 4, 'bbox'),\n );\n}\n\nconst buildDeepSeekChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n const isThinkingMode =\n reasoningEnabled === true || reasoningEnabled === 'default';\n\n // DeepSeek thinking mode does not support temperature. For compatibility,\n // DeepSeek ignores this parameter instead of rejecting the request, so omit\n // the ineffective setting. `default` also uses thinking mode because\n // DeepSeek enables it by default.\n // https://api-docs.deepseek.com/zh-cn/guides/thinking_mode\n if (isThinkingMode) {\n commonOverrideConfig.temperature = undefined;\n } else if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.thinking = {\n type: (reasoningEnabled ?? false) ? 'enabled' : 'disabled',\n };\n if (reasoningEffort) {\n modelSpecificConfig.reasoning_effort = reasoningEffort;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nexport const deepSeekAdapters = {\n deepseek: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildDeepSeekChatCompletionParams,\n useReasoningAsContentFallback: true,\n // DeepSeek only requires reasoning_content to be replayed after tool\n // calls. Midscene planning does not use tool calls, so it is unnecessary.\n replayRawAssistantMessage: false,\n },\n locate: {\n element: {\n protocol: deepSeekElementLocateProtocol,\n resultFormat: {\n coordinates: deepSeekPointCoordinates,\n parseRawLocateValue: parseDeepSeekPointLocateValue,\n },\n },\n searchArea: {\n protocol: deepSeekSearchAreaProtocol,\n resultFormat: {\n coordinates: deepSeekBboxCoordinates,\n parseRawLocateValue: parseDeepSeekBboxLocateValue,\n },\n },\n },\n },\n} satisfies Pick<Record<TModelFamily, ModelAdapterDefinition>, 'deepseek'>;\n"],"names":["deepSeekPointCoordinates","deepSeekBboxCoordinates","parseDeepSeekCoordinateValues","input","expectedLength","label","coordinateTexts","String","Error","Number","parseDeepSeekPointLocateValue","createLocateResultValue","parseDeepSeekBboxLocateValue","buildDeepSeekChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","isThinkingMode","undefined","modelSpecificConfig","deepSeekAdapters","deepSeekElementLocateProtocol","deepSeekSearchAreaProtocol"],"mappings":";;AAeA,MAAMA,2BAA2B;IAC/B,OAAO;IACP,OAAO;IACP,cAAc;AAChB;AAEA,MAAMC,0BAA0B;IAC9B,OAAO;IACP,OAAO;IACP,cAAc;AAChB;AAEA,SAASC,8BACPC,KAAc,EACdC,cAAsB,EACtBC,KAAa;IAEb,MAAMC,kBAAkBC,OAAOJ,OAAO,KAAK,CAAC;IAC5C,IAAIG,iBAAiB,WAAWF,gBAC9B,MAAM,IAAII,MACR,CAAC,SAAS,EAAEH,MAAM,oCAAoC,EAAED,eAAe,wBAAwB,EAAEE,iBAAiB,UAAU,GAAG;IAInI,OAAOA,gBAAgB,GAAG,CAACG;AAC7B;AAEA,SAASC,8BAA8BP,KAAc;IACnD,OAAOQ,wBACLX,0BACAE,8BAA8BC,OAAO,GAAG;AAE5C;AAEA,SAASS,6BAA6BT,KAAc;IAClD,OAAOQ,wBACLV,yBACAC,8BAA8BC,OAAO,GAAG;AAE5C;AAEA,MAAMU,oCAAoC,CACxCV;IAEA,MAAM,EAAEW,gBAAgB,EAAEC,UAAU,EAAE,GAAGZ;IACzC,MAAM,EAAEa,gBAAgB,EAAEC,eAAe,EAAE,GAAGF;IAC9C,MAAMG,uBAAgD,CAAC;IACvD,MAAMC,iBACJH,AAAqB,SAArBA,oBAA6BA,AAAqB,cAArBA;IAO/B,IAAIG,gBACFD,qBAAqB,WAAW,GAAGE;SAC9B,IAAIL,AAA2BK,WAA3BL,WAAW,WAAW,EAC/BG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAG3D,IACEA,AAA8B,WAA9BA,WAAW,cAAc,IACzBZ,MAAM,0BAA0B,EAEhCe,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAMG,sBAA+C,CAAC;IACtD,IAAIL,AAAqB,cAArBA,kBAAgC;QAClCK,oBAAoB,QAAQ,GAAG;YAC7B,MAAOL,oBAAoB,QAAS,YAAY;QAClD;QACA,IAAIC,iBACFI,oBAAoB,gBAAgB,GAAGJ;IAE3C;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGG,mBAAmB;QACxB;IACF;AACF;AAEO,MAAMC,mBAAmB;IAC9B,UAAU;QACR,gBAAgB;YACd,uBAAuB;gBAAC;aAAkB;YAC1C,2BAA2BT;YAC3B,+BAA+B;YAG/B,2BAA2B;QAC7B;QACA,QAAQ;YACN,SAAS;gBACP,UAAUU;gBACV,cAAc;oBACZ,aAAavB;oBACb,qBAAqBU;gBACvB;YACF;YACA,YAAY;gBACV,UAAUc;gBACV,cAAc;oBACZ,aAAavB;oBACb,qBAAqBW;gBACvB;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"file":"ai-model/models/deepseek/adapter.mjs","sources":["../../../../../src/ai-model/models/deepseek/adapter.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} from '../../shared/model-locate-result';\nimport {\n deepSeekElementLocateProtocol,\n deepSeekSearchAreaProtocol,\n} from './locate-protocol';\n\nconst deepSeekPointCoordinates = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\n\nconst deepSeekBboxCoordinates = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\n\nfunction parseDeepSeekCoordinateValues(\n input: unknown,\n expectedLength: number,\n label: string,\n): number[] {\n const coordinateTexts = String(input).match(/\\d+/g);\n if (coordinateTexts?.length !== expectedLength) {\n throw new Error(\n `DeepSeek ${label} locate result must contain exactly ${expectedLength} positive integers, got ${coordinateTexts?.length ?? 0}`,\n );\n }\n\n return coordinateTexts.map(Number);\n}\n\nfunction parseDeepSeekPointLocateValue(input: unknown): LocateResultValue {\n return createLocateResultValue(\n deepSeekPointCoordinates,\n parseDeepSeekCoordinateValues(input, 2, 'point'),\n );\n}\n\nfunction parseDeepSeekBboxLocateValue(input: unknown): LocateResultValue {\n return createLocateResultValue(\n deepSeekBboxCoordinates,\n parseDeepSeekCoordinateValues(input, 4, 'bbox'),\n );\n}\n\nconst buildDeepSeekChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n const isThinkingMode =\n reasoningEnabled === true || reasoningEnabled === 'default';\n\n // DeepSeek thinking mode does not support temperature. For compatibility,\n // DeepSeek ignores this parameter instead of rejecting the request, so omit\n // the ineffective setting. `default` also uses thinking mode because\n // DeepSeek enables it by default.\n // https://api-docs.deepseek.com/zh-cn/guides/thinking_mode\n if (isThinkingMode) {\n commonOverrideConfig.temperature = undefined;\n } else if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.thinking = {\n type: (reasoningEnabled ?? false) ? 'enabled' : 'disabled',\n };\n if (reasoningEffort) {\n modelSpecificConfig.reasoning_effort = reasoningEffort;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nexport const deepSeekAdapters = {\n deepseek: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildDeepSeekChatCompletionParams,\n useReasoningAsContentFallback: true,\n // DeepSeek only requires reasoning_content to be replayed after tool\n // calls. Midscene planning does not use tool calls, so it is unnecessary.\n replayRawAssistantMessage: false,\n },\n locate: {\n element: {\n protocol: deepSeekElementLocateProtocol,\n resultFormat: {\n coordinates: deepSeekPointCoordinates,\n parseRawLocateValue: parseDeepSeekPointLocateValue,\n },\n },\n searchArea: {\n protocol: deepSeekSearchAreaProtocol,\n resultFormat: {\n coordinates: deepSeekBboxCoordinates,\n parseRawLocateValue: parseDeepSeekBboxLocateValue,\n },\n },\n },\n },\n} satisfies Pick<Record<TModelFamily, ModelAdapterDefinition>, 'deepseek'>;\n"],"names":["deepSeekPointCoordinates","deepSeekBboxCoordinates","parseDeepSeekCoordinateValues","input","expectedLength","label","coordinateTexts","String","Error","Number","parseDeepSeekPointLocateValue","createLocateResultValue","parseDeepSeekBboxLocateValue","buildDeepSeekChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","isThinkingMode","undefined","modelSpecificConfig","deepSeekAdapters","deepSeekElementLocateProtocol","deepSeekSearchAreaProtocol"],"mappings":";;AAeA,MAAMA,2BAA2B;IAC/B,OAAO;IACP,OAAO;IACP,cAAc;IACd,UAAU;AACZ;AAEA,MAAMC,0BAA0B;IAC9B,OAAO;IACP,OAAO;IACP,cAAc;IACd,UAAU;AACZ;AAEA,SAASC,8BACPC,KAAc,EACdC,cAAsB,EACtBC,KAAa;IAEb,MAAMC,kBAAkBC,OAAOJ,OAAO,KAAK,CAAC;IAC5C,IAAIG,iBAAiB,WAAWF,gBAC9B,MAAM,IAAII,MACR,CAAC,SAAS,EAAEH,MAAM,oCAAoC,EAAED,eAAe,wBAAwB,EAAEE,iBAAiB,UAAU,GAAG;IAInI,OAAOA,gBAAgB,GAAG,CAACG;AAC7B;AAEA,SAASC,8BAA8BP,KAAc;IACnD,OAAOQ,wBACLX,0BACAE,8BAA8BC,OAAO,GAAG;AAE5C;AAEA,SAASS,6BAA6BT,KAAc;IAClD,OAAOQ,wBACLV,yBACAC,8BAA8BC,OAAO,GAAG;AAE5C;AAEA,MAAMU,oCAAoC,CACxCV;IAEA,MAAM,EAAEW,gBAAgB,EAAEC,UAAU,EAAE,GAAGZ;IACzC,MAAM,EAAEa,gBAAgB,EAAEC,eAAe,EAAE,GAAGF;IAC9C,MAAMG,uBAAgD,CAAC;IACvD,MAAMC,iBACJH,AAAqB,SAArBA,oBAA6BA,AAAqB,cAArBA;IAO/B,IAAIG,gBACFD,qBAAqB,WAAW,GAAGE;SAC9B,IAAIL,AAA2BK,WAA3BL,WAAW,WAAW,EAC/BG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAG3D,IACEA,AAA8B,WAA9BA,WAAW,cAAc,IACzBZ,MAAM,0BAA0B,EAEhCe,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAMG,sBAA+C,CAAC;IACtD,IAAIL,AAAqB,cAArBA,kBAAgC;QAClCK,oBAAoB,QAAQ,GAAG;YAC7B,MAAOL,oBAAoB,QAAS,YAAY;QAClD;QACA,IAAIC,iBACFI,oBAAoB,gBAAgB,GAAGJ;IAE3C;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGG,mBAAmB;QACxB;IACF;AACF;AAEO,MAAMC,mBAAmB;IAC9B,UAAU;QACR,gBAAgB;YACd,uBAAuB;gBAAC;aAAkB;YAC1C,2BAA2BT;YAC3B,+BAA+B;YAG/B,2BAA2B;QAC7B;QACA,QAAQ;YACN,SAAS;gBACP,UAAUU;gBACV,cAAc;oBACZ,aAAavB;oBACb,qBAAqBU;gBACvB;YACF;YACA,YAAY;gBACV,UAAUc;gBACV,cAAc;oBACZ,aAAavB;oBACb,qBAAqBW;gBACvB;YACF;QACF;IACF;AACF"}
@@ -3,12 +3,14 @@ import { createLocateResultValue, unwrapCoordinateListLikeInput } from "../share
3
3
  const doubaoBboxCoordinatesMeta = {
4
4
  shape: 'bbox',
5
5
  order: 'xy',
6
- normalizedBy: 1000
6
+ normalizedBy: 1000,
7
+ rounding: 'round'
7
8
  };
8
9
  const doubaoPointCoordinatesMeta = {
9
10
  shape: 'point',
10
11
  order: 'xy',
11
- normalizedBy: 1000
12
+ normalizedBy: 1000,
13
+ rounding: 'round'
12
14
  };
13
15
  const coordinateSequencePattern = /(?:^|[^a-zA-Z0-9])(\d+(?:[^a-zA-Z0-9]+\d+)+)(?=$|[^a-zA-Z0-9])/g;
14
16
  function isFourFiniteNumberArray(input) {
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/doubao.mjs","sources":["../../../../src/ai-model/models/doubao.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\nimport { parseModelResponseJson } from '../shared/json';\nimport {\n type LocateResultValue,\n createLocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../shared/model-locate-result';\n\nconst doubaoBboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n} as const;\nconst doubaoPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1000,\n} as const;\n\n/**\n * Finds a sequence of numbers separated by punctuation or whitespace in a\n * string. Separators cannot be letters, which prevents extracting the `2` in\n * a mixed alphanumeric token such as `bbox_2d` as a coordinate.\n */\nconst coordinateSequencePattern =\n /(?:^|[^a-zA-Z0-9])(\\d+(?:[^a-zA-Z0-9]+\\d+)+)(?=$|[^a-zA-Z0-9])/g;\n\nfunction isFourFiniteNumberArray(input: unknown): input is number[] {\n return (\n Array.isArray(input) &&\n input.length === 4 &&\n input.every((value) => typeof value === 'number' && Number.isFinite(value))\n );\n}\n\nfunction parseNumbersFromUnexpectedBboxStructure(input: unknown): number[] {\n const serialized = JSON.stringify(input);\n if (!serialized) {\n return [];\n }\n\n const sequences = Array.from(\n serialized.matchAll(coordinateSequencePattern),\n (match) => match[1].match(/\\d+/g)?.map(Number) ?? [],\n );\n const longestLength = Math.max(\n 0,\n ...sequences.map((sequence) => sequence.length),\n );\n const longestSequences = sequences.filter(\n (sequence) => sequence.length === longestLength,\n );\n\n if (longestSequences.length !== 1) {\n return [];\n }\n\n return longestSequences[0];\n}\n\nexport function parseDoubaoRawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any);\n const bboxList = isFourFiniteNumberArray(bbox)\n ? bbox\n : parseNumbersFromUnexpectedBboxStructure(bbox);\n\n if (bboxList.length === 4 || bboxList.length === 5) {\n return createLocateResultValue(doubaoBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[2],\n bboxList[3],\n ]);\n }\n\n if (\n bboxList.length === 6 ||\n bboxList.length === 2 ||\n bboxList.length === 3 ||\n bboxList.length === 7\n ) {\n return createLocateResultValue(doubaoPointCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n ]);\n }\n\n if (bboxList.length === 8) {\n return createLocateResultValue(doubaoBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[4],\n bboxList[5],\n ]);\n }\n\n const msg = `invalid bbox data for doubao-vision mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n}\n\nconst buildDoubaoChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n // Doubao Chat Completions JSON mode:\n // https://docs.volcengine.com/docs/82379/1568221?lang=zh\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.thinking = {\n type: (reasoningEnabled ?? false) ? 'enabled' : 'disabled',\n };\n if (reasoningEffort) {\n modelSpecificConfig.reasoning_effort = reasoningEffort;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst doubaoVisionAdapter: ModelAdapterDefinition = {\n jsonParser: parseModelResponseJson,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildDoubaoChatCompletionParams,\n useReasoningAsContentFallback: true,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: doubaoBboxCoordinatesMeta,\n parseRawLocateValue: parseDoubaoRawLocateValue,\n },\n },\n },\n};\n\nexport const doubaoAdapters = {\n 'doubao-vision': doubaoVisionAdapter,\n 'doubao-seed': doubaoVisionAdapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'doubao-vision' | 'doubao-seed'\n>;\n"],"names":["doubaoBboxCoordinatesMeta","doubaoPointCoordinatesMeta","coordinateSequencePattern","isFourFiniteNumberArray","input","Array","value","Number","parseNumbersFromUnexpectedBboxStructure","serialized","JSON","sequences","match","longestLength","Math","sequence","longestSequences","parseDoubaoRawLocateValue","bbox","unwrapCoordinateListLikeInput","bboxList","createLocateResultValue","msg","Error","buildDoubaoChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","undefined","modelSpecificConfig","doubaoVisionAdapter","parseModelResponseJson","doubaoAdapters"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/models/doubao.mjs","sources":["../../../../src/ai-model/models/doubao.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\nimport { parseModelResponseJson } from '../shared/json';\nimport {\n type LocateResultValue,\n createLocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../shared/model-locate-result';\n\nconst doubaoBboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\nconst doubaoPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\n\n/**\n * Finds a sequence of numbers separated by punctuation or whitespace in a\n * string. Separators cannot be letters, which prevents extracting the `2` in\n * a mixed alphanumeric token such as `bbox_2d` as a coordinate.\n */\nconst coordinateSequencePattern =\n /(?:^|[^a-zA-Z0-9])(\\d+(?:[^a-zA-Z0-9]+\\d+)+)(?=$|[^a-zA-Z0-9])/g;\n\nfunction isFourFiniteNumberArray(input: unknown): input is number[] {\n return (\n Array.isArray(input) &&\n input.length === 4 &&\n input.every((value) => typeof value === 'number' && Number.isFinite(value))\n );\n}\n\nfunction parseNumbersFromUnexpectedBboxStructure(input: unknown): number[] {\n const serialized = JSON.stringify(input);\n if (!serialized) {\n return [];\n }\n\n const sequences = Array.from(\n serialized.matchAll(coordinateSequencePattern),\n (match) => match[1].match(/\\d+/g)?.map(Number) ?? [],\n );\n const longestLength = Math.max(\n 0,\n ...sequences.map((sequence) => sequence.length),\n );\n const longestSequences = sequences.filter(\n (sequence) => sequence.length === longestLength,\n );\n\n if (longestSequences.length !== 1) {\n return [];\n }\n\n return longestSequences[0];\n}\n\nexport function parseDoubaoRawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any);\n const bboxList = isFourFiniteNumberArray(bbox)\n ? bbox\n : parseNumbersFromUnexpectedBboxStructure(bbox);\n\n if (bboxList.length === 4 || bboxList.length === 5) {\n return createLocateResultValue(doubaoBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[2],\n bboxList[3],\n ]);\n }\n\n if (\n bboxList.length === 6 ||\n bboxList.length === 2 ||\n bboxList.length === 3 ||\n bboxList.length === 7\n ) {\n return createLocateResultValue(doubaoPointCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n ]);\n }\n\n if (bboxList.length === 8) {\n return createLocateResultValue(doubaoBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[4],\n bboxList[5],\n ]);\n }\n\n const msg = `invalid bbox data for doubao-vision mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n}\n\nconst buildDoubaoChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n // Doubao Chat Completions JSON mode:\n // https://docs.volcengine.com/docs/82379/1568221?lang=zh\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.thinking = {\n type: (reasoningEnabled ?? false) ? 'enabled' : 'disabled',\n };\n if (reasoningEffort) {\n modelSpecificConfig.reasoning_effort = reasoningEffort;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst doubaoVisionAdapter: ModelAdapterDefinition = {\n jsonParser: parseModelResponseJson,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildDoubaoChatCompletionParams,\n useReasoningAsContentFallback: true,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: doubaoBboxCoordinatesMeta,\n parseRawLocateValue: parseDoubaoRawLocateValue,\n },\n },\n },\n};\n\nexport const doubaoAdapters = {\n 'doubao-vision': doubaoVisionAdapter,\n 'doubao-seed': doubaoVisionAdapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'doubao-vision' | 'doubao-seed'\n>;\n"],"names":["doubaoBboxCoordinatesMeta","doubaoPointCoordinatesMeta","coordinateSequencePattern","isFourFiniteNumberArray","input","Array","value","Number","parseNumbersFromUnexpectedBboxStructure","serialized","JSON","sequences","match","longestLength","Math","sequence","longestSequences","parseDoubaoRawLocateValue","bbox","unwrapCoordinateListLikeInput","bboxList","createLocateResultValue","msg","Error","buildDoubaoChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","undefined","modelSpecificConfig","doubaoVisionAdapter","parseModelResponseJson","doubaoAdapters"],"mappings":";;AAaA,MAAMA,4BAA4B;IAChC,OAAO;IACP,OAAO;IACP,cAAc;IACd,UAAU;AACZ;AACA,MAAMC,6BAA6B;IACjC,OAAO;IACP,OAAO;IACP,cAAc;IACd,UAAU;AACZ;AAOA,MAAMC,4BACJ;AAEF,SAASC,wBAAwBC,KAAc;IAC7C,OACEC,MAAM,OAAO,CAACD,UACdA,AAAiB,MAAjBA,MAAM,MAAM,IACZA,MAAM,KAAK,CAAC,CAACE,QAAU,AAAiB,YAAjB,OAAOA,SAAsBC,OAAO,QAAQ,CAACD;AAExE;AAEA,SAASE,wCAAwCJ,KAAc;IAC7D,MAAMK,aAAaC,KAAK,SAAS,CAACN;IAClC,IAAI,CAACK,YACH,OAAO,EAAE;IAGX,MAAME,YAAYN,MAAM,IAAI,CAC1BI,WAAW,QAAQ,CAACP,4BACpB,CAACU,QAAUA,KAAK,CAAC,EAAE,CAAC,KAAK,CAAC,SAAS,IAAIL,WAAW,EAAE;IAEtD,MAAMM,gBAAgBC,KAAK,GAAG,CAC5B,MACGH,UAAU,GAAG,CAAC,CAACI,WAAaA,SAAS,MAAM;IAEhD,MAAMC,mBAAmBL,UAAU,MAAM,CACvC,CAACI,WAAaA,SAAS,MAAM,KAAKF;IAGpC,IAAIG,AAA4B,MAA5BA,iBAAiB,MAAM,EACzB,OAAO,EAAE;IAGX,OAAOA,gBAAgB,CAAC,EAAE;AAC5B;AAEO,SAASC,0BAA0Bb,KAAc;IACtD,MAAMc,OAAOC,8BAA8Bf;IAC3C,MAAMgB,WAAWjB,wBAAwBe,QACrCA,OACAV,wCAAwCU;IAE5C,IAAIE,AAAoB,MAApBA,SAAS,MAAM,IAAUA,AAAoB,MAApBA,SAAS,MAAM,EAC1C,OAAOC,wBAAwBrB,2BAA2B;QACxDoB,QAAQ,CAAC,EAAE;QACXA,QAAQ,CAAC,EAAE;QACXA,QAAQ,CAAC,EAAE;QACXA,QAAQ,CAAC,EAAE;KACZ;IAGH,IACEA,AAAoB,MAApBA,SAAS,MAAM,IACfA,AAAoB,MAApBA,SAAS,MAAM,IACfA,AAAoB,MAApBA,SAAS,MAAM,IACfA,AAAoB,MAApBA,SAAS,MAAM,EAEf,OAAOC,wBAAwBpB,4BAA4B;QACzDmB,QAAQ,CAAC,EAAE;QACXA,QAAQ,CAAC,EAAE;KACZ;IAGH,IAAIA,AAAoB,MAApBA,SAAS,MAAM,EACjB,OAAOC,wBAAwBrB,2BAA2B;QACxDoB,QAAQ,CAAC,EAAE;QACXA,QAAQ,CAAC,EAAE;QACXA,QAAQ,CAAC,EAAE;QACXA,QAAQ,CAAC,EAAE;KACZ;IAGH,MAAME,MAAM,CAAC,0CAA0C,EAAEZ,KAAK,SAAS,CAACQ,MAAM,CAAC,CAAC;IAChF,MAAM,IAAIK,MAAMD;AAClB;AAEA,MAAME,kCAAkC,CACtCpB;IAEA,MAAM,EAAEqB,gBAAgB,EAAEC,UAAU,EAAE,GAAGtB;IACzC,MAAM,EAAEuB,gBAAgB,EAAEC,eAAe,EAAE,GAAGF;IAC9C,MAAMG,uBAAgD,CAAC;IAEvD,IAAIH,AAA2BI,WAA3BJ,WAAW,WAAW,EACxBG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAK3D,IACEA,AAA8B,WAA9BA,WAAW,cAAc,IACzBtB,MAAM,0BAA0B,EAEhCyB,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAME,sBAA+C,CAAC;IAEtD,IAAIJ,AAAqB,cAArBA,kBAAgC;QAClCI,oBAAoB,QAAQ,GAAG;YAC7B,MAAOJ,oBAAoB,QAAS,YAAY;QAClD;QACA,IAAIC,iBACFG,oBAAoB,gBAAgB,GAAGH;IAE3C;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGE,mBAAmB;QACxB;IACF;AACF;AAEA,MAAMC,sBAA8C;IAClD,YAAYC;IACZ,gBAAgB;QACd,uBAAuB;YAAC;SAAkB;QAC1C,2BAA2BT;QAC3B,+BAA+B;IACjC;IACA,QAAQ;QACN,SAAS;YACP,cAAc;gBACZ,aAAaxB;gBACb,qBAAqBiB;YACvB;QACF;IACF;AACF;AAEO,MAAMiB,iBAAiB;IAC5B,iBAAiBF;IACjB,eAAeA;AACjB"}
@@ -1,14 +1,50 @@
1
1
  import { isLocateIntent } from "./utils/intent.mjs";
2
2
  const originalImageDetailForDefaultIntent = (input)=>isLocateIntent(input.intent) || input.requiresOriginalImageDetail ? 'original' : void 0;
3
+ const resolveGpt5ReasoningEffort = ({ reasoningEnabled, reasoningEffort })=>{
4
+ if ('default' === reasoningEnabled) return;
5
+ return true === reasoningEnabled ? reasoningEffort ?? 'medium' : 'none';
6
+ };
7
+ const resolveGpt6ReasoningEffort = ({ reasoningEnabled, reasoningEffort })=>{
8
+ if ('default' === reasoningEnabled) return;
9
+ return true === reasoningEnabled ? reasoningEffort ?? 'medium' : 'low';
10
+ };
11
+ const buildGpt5CodexAppServerParams = (input)=>({
12
+ config: {
13
+ effort: resolveGpt5ReasoningEffort(input.userConfig ?? {})
14
+ },
15
+ imageDetail: originalImageDetailForDefaultIntent(input)
16
+ });
17
+ const buildGpt6CodexAppServerParams = (input)=>({
18
+ config: {
19
+ effort: resolveGpt6ReasoningEffort(input.userConfig ?? {})
20
+ },
21
+ imageDetail: originalImageDetailForDefaultIntent(input)
22
+ });
3
23
  const buildGpt5ChatCompletionParams = (input)=>{
4
24
  const { midsceneDefaults, userConfig } = input;
5
- const { reasoningEnabled, reasoningEffort } = userConfig;
6
25
  const commonOverrideConfig = {};
7
26
  if (void 0 !== userConfig.temperature) commonOverrideConfig.temperature = userConfig.temperature;
8
27
  if ('none' !== input.userConfig.responseFormat && input.expectedJsonObjectResponse) commonOverrideConfig.response_format = {
9
28
  type: 'json_object'
10
29
  };
11
- const effectiveReasoningEffort = true === reasoningEnabled ? reasoningEffort ?? 'medium' : 'none';
30
+ const effectiveReasoningEffort = resolveGpt5ReasoningEffort(userConfig);
31
+ return {
32
+ config: {
33
+ ...midsceneDefaults,
34
+ ...commonOverrideConfig,
35
+ reasoning_effort: effectiveReasoningEffort
36
+ }
37
+ };
38
+ };
39
+ const buildGpt6ChatCompletionParams = (input)=>{
40
+ const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;
41
+ const { responseFormat } = userConfig;
42
+ const commonOverrideConfig = {};
43
+ commonOverrideConfig.temperature = void 0;
44
+ if ('none' !== responseFormat && expectedJsonObjectResponse) commonOverrideConfig.response_format = {
45
+ type: 'json_object'
46
+ };
47
+ const effectiveReasoningEffort = resolveGpt6ReasoningEffort(userConfig);
12
48
  return {
13
49
  config: {
14
50
  ...midsceneDefaults,
@@ -19,6 +55,7 @@ const buildGpt5ChatCompletionParams = (input)=>{
19
55
  };
20
56
  const gptAdapters = {
21
57
  'gpt-5': {
58
+ buildCodexAppServerParams: buildGpt5CodexAppServerParams,
22
59
  chatCompletion: {
23
60
  unsupportedUserConfig: [
24
61
  'reasoningBudget'
@@ -36,6 +73,27 @@ const gptAdapters = {
36
73
  }
37
74
  }
38
75
  }
76
+ },
77
+ 'gpt-6': {
78
+ buildCodexAppServerParams: buildGpt6CodexAppServerParams,
79
+ chatCompletion: {
80
+ unsupportedUserConfig: [
81
+ 'temperature',
82
+ 'reasoningBudget'
83
+ ],
84
+ buildChatCompletionParams: buildGpt6ChatCompletionParams,
85
+ resolveImageDetail: originalImageDetailForDefaultIntent
86
+ },
87
+ locate: {
88
+ element: {
89
+ resultFormat: {
90
+ coordinates: {
91
+ shape: 'bbox',
92
+ order: 'xy'
93
+ }
94
+ }
95
+ }
96
+ }
39
97
  }
40
98
  };
41
99
  export { gptAdapters };
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/gpt.mjs","sources":["../../../../src/ai-model/models/gpt.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ImageDetail,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\nimport { isLocateIntent } from './utils/intent';\n\nconst originalImageDetailForDefaultIntent = (\n input: ChatCompletionCallContext,\n): ImageDetail | undefined =>\n isLocateIntent(input.intent) || input.requiresOriginalImageDetail\n ? 'original'\n : undefined;\n\nconst buildGpt5ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n // OpenAI Chat Completions JSON mode:\n // https://platform.openai.com/docs/guides/structured-outputs?api-mode=chat#json-mode\n if (\n input.userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const effectiveReasoningEffort =\n reasoningEnabled === true ? (reasoningEffort ?? 'medium') : 'none';\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning_effort: effectiveReasoningEffort,\n },\n };\n};\n\nexport const gptAdapters = {\n 'gpt-5': {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildGpt5ChatCompletionParams,\n resolveImageDetail: originalImageDetailForDefaultIntent,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: { shape: 'bbox', order: 'xy' },\n },\n },\n },\n },\n} satisfies Pick<Record<TModelFamily, ModelAdapterDefinition>, 'gpt-5'>;\n"],"names":["originalImageDetailForDefaultIntent","input","isLocateIntent","undefined","buildGpt5ChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","effectiveReasoningEffort","gptAdapters"],"mappings":";AASA,MAAMA,sCAAsC,CAC1CC,QAEAC,eAAeD,MAAM,MAAM,KAAKA,MAAM,2BAA2B,GAC7D,aACAE;AAEN,MAAMC,gCAAgC,CACpCH;IAEA,MAAM,EAAEI,gBAAgB,EAAEC,UAAU,EAAE,GAAGL;IACzC,MAAM,EAAEM,gBAAgB,EAAEC,eAAe,EAAE,GAAGF;IAC9C,MAAMG,uBAAgD,CAAC;IAEvD,IAAIH,AAA2BH,WAA3BG,WAAW,WAAW,EACxBG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAK3D,IACEL,AAAoC,WAApCA,MAAM,UAAU,CAAC,cAAc,IAC/BA,MAAM,0BAA0B,EAEhCQ,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAMC,2BACJH,AAAqB,SAArBA,mBAA6BC,mBAAmB,WAAY;IAE9D,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,kBAAkBC;QACpB;IACF;AACF;AAEO,MAAMC,cAAc;IACzB,SAAS;QACP,gBAAgB;YACd,uBAAuB;gBAAC;aAAkB;YAC1C,2BAA2BP;YAC3B,oBAAoBJ;QACtB;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAa;wBAAE,OAAO;wBAAQ,OAAO;oBAAK;gBAC5C;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"file":"ai-model/models/gpt.mjs","sources":["../../../../src/ai-model/models/gpt.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n CodexAppServerCallInput,\n CodexAppServerParamsResult,\n ImageDetail,\n ModelAdapterDefinition,\n ReasoningInput,\n} from '../model-adapter/types';\nimport { isLocateIntent } from './utils/intent';\n\nconst originalImageDetailForDefaultIntent = (\n input: Pick<\n CodexAppServerCallInput,\n 'intent' | 'requiresOriginalImageDetail'\n >,\n): ImageDetail | undefined =>\n isLocateIntent(input.intent) || input.requiresOriginalImageDetail\n ? 'original'\n : undefined;\n\nconst resolveGpt5ReasoningEffort = ({\n reasoningEnabled,\n reasoningEffort,\n}: ReasoningInput): string | undefined => {\n if (reasoningEnabled === 'default') return undefined;\n return reasoningEnabled === true ? (reasoningEffort ?? 'medium') : 'none';\n};\n\n// Astra cannot disable reasoning; use its lowest effort when disabled.\nconst resolveGpt6ReasoningEffort = ({\n reasoningEnabled,\n reasoningEffort,\n}: ReasoningInput): string | undefined => {\n if (reasoningEnabled === 'default') return undefined;\n return reasoningEnabled === true ? (reasoningEffort ?? 'medium') : 'low';\n};\n\nconst buildGpt5CodexAppServerParams = (\n input: CodexAppServerCallInput,\n): CodexAppServerParamsResult => ({\n config: { effort: resolveGpt5ReasoningEffort(input.userConfig ?? {}) },\n imageDetail: originalImageDetailForDefaultIntent(input),\n});\n\nconst buildGpt6CodexAppServerParams = (\n input: CodexAppServerCallInput,\n): CodexAppServerParamsResult => ({\n config: { effort: resolveGpt6ReasoningEffort(input.userConfig ?? {}) },\n imageDetail: originalImageDetailForDefaultIntent(input),\n});\n\nconst buildGpt5ChatCompletionParams = (\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 // OpenAI Chat Completions JSON mode:\n // https://platform.openai.com/docs/guides/structured-outputs?api-mode=chat#json-mode\n if (\n input.userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const effectiveReasoningEffort = resolveGpt5ReasoningEffort(userConfig);\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning_effort: effectiveReasoningEffort,\n },\n };\n};\n\nconst buildGpt6ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;\n const { responseFormat } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n // GPT-6 does not support temperature; omit it from the serialized request.\n commonOverrideConfig.temperature = undefined;\n if (responseFormat !== 'none' && expectedJsonObjectResponse) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const effectiveReasoningEffort = resolveGpt6ReasoningEffort(userConfig);\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning_effort: effectiveReasoningEffort,\n },\n };\n};\n\nexport const gptAdapters = {\n 'gpt-5': {\n buildCodexAppServerParams: buildGpt5CodexAppServerParams,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildGpt5ChatCompletionParams,\n resolveImageDetail: originalImageDetailForDefaultIntent,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: { shape: 'bbox', order: 'xy' },\n },\n },\n },\n },\n 'gpt-6': {\n buildCodexAppServerParams: buildGpt6CodexAppServerParams,\n chatCompletion: {\n unsupportedUserConfig: ['temperature', 'reasoningBudget'],\n buildChatCompletionParams: buildGpt6ChatCompletionParams,\n resolveImageDetail: originalImageDetailForDefaultIntent,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: { shape: 'bbox', order: 'xy' },\n },\n },\n },\n },\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'gpt-5' | 'gpt-6'\n>;\n"],"names":["originalImageDetailForDefaultIntent","input","isLocateIntent","undefined","resolveGpt5ReasoningEffort","reasoningEnabled","reasoningEffort","resolveGpt6ReasoningEffort","buildGpt5CodexAppServerParams","buildGpt6CodexAppServerParams","buildGpt5ChatCompletionParams","midsceneDefaults","userConfig","commonOverrideConfig","effectiveReasoningEffort","buildGpt6ChatCompletionParams","expectedJsonObjectResponse","responseFormat","gptAdapters"],"mappings":";AAYA,MAAMA,sCAAsC,CAC1CC,QAKAC,eAAeD,MAAM,MAAM,KAAKA,MAAM,2BAA2B,GAC7D,aACAE;AAEN,MAAMC,6BAA6B,CAAC,EAClCC,gBAAgB,EAChBC,eAAe,EACA;IACf,IAAID,AAAqB,cAArBA,kBAAgC;IACpC,OAAOA,AAAqB,SAArBA,mBAA6BC,mBAAmB,WAAY;AACrE;AAGA,MAAMC,6BAA6B,CAAC,EAClCF,gBAAgB,EAChBC,eAAe,EACA;IACf,IAAID,AAAqB,cAArBA,kBAAgC;IACpC,OAAOA,AAAqB,SAArBA,mBAA6BC,mBAAmB,WAAY;AACrE;AAEA,MAAME,gCAAgC,CACpCP,QACgC;QAChC,QAAQ;YAAE,QAAQG,2BAA2BH,MAAM,UAAU,IAAI,CAAC;QAAG;QACrE,aAAaD,oCAAoCC;IACnD;AAEA,MAAMQ,gCAAgC,CACpCR,QACgC;QAChC,QAAQ;YAAE,QAAQM,2BAA2BN,MAAM,UAAU,IAAI,CAAC;QAAG;QACrE,aAAaD,oCAAoCC;IACnD;AAEA,MAAMS,gCAAgC,CACpCT;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAE,GAAGX;IACzC,MAAMY,uBAAgD,CAAC;IAEvD,IAAID,AAA2BT,WAA3BS,WAAW,WAAW,EACxBC,qBAAqB,WAAW,GAAGD,WAAW,WAAW;IAK3D,IACEX,AAAoC,WAApCA,MAAM,UAAU,CAAC,cAAc,IAC/BA,MAAM,0BAA0B,EAEhCY,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAMC,2BAA2BV,2BAA2BQ;IAE5D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGE,oBAAoB;YACvB,kBAAkBC;QACpB;IACF;AACF;AAEA,MAAMC,gCAAgC,CACpCd;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAEI,0BAA0B,EAAE,GAAGf;IACrE,MAAM,EAAEgB,cAAc,EAAE,GAAGL;IAC3B,MAAMC,uBAAgD,CAAC;IAEvDA,qBAAqB,WAAW,GAAGV;IACnC,IAAIc,AAAmB,WAAnBA,kBAA6BD,4BAC/BH,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAMC,2BAA2BP,2BAA2BK;IAE5D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGE,oBAAoB;YACvB,kBAAkBC;QACpB;IACF;AACF;AAEO,MAAMI,cAAc;IACzB,SAAS;QACP,2BAA2BV;QAC3B,gBAAgB;YACd,uBAAuB;gBAAC;aAAkB;YAC1C,2BAA2BE;YAC3B,oBAAoBV;QACtB;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAa;wBAAE,OAAO;wBAAQ,OAAO;oBAAK;gBAC5C;YACF;QACF;IACF;IACA,SAAS;QACP,2BAA2BS;QAC3B,gBAAgB;YACd,uBAAuB;gBAAC;gBAAe;aAAkB;YACzD,2BAA2BM;YAC3B,oBAAoBf;QACtB;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAa;wBAAE,OAAO;wBAAQ,OAAO;oBAAK;gBAC5C;YACF;QACF;IACF;AACF"}
@@ -2,11 +2,13 @@ import { createLocateResultValue, parseCoordinateList } from "../shared/model-lo
2
2
  const kimiNormalizedPointCoordinatesMeta = {
3
3
  shape: 'point',
4
4
  order: 'xy',
5
- normalizedBy: 1
5
+ normalizedBy: 1,
6
+ rounding: 'round'
6
7
  };
7
8
  const kimiPixelPointCoordinatesMeta = {
8
9
  shape: 'point',
9
- order: 'xy'
10
+ order: 'xy',
11
+ rounding: 'round'
10
12
  };
11
13
  function parseKimiRawLocateValue(input) {
12
14
  const point = parseCoordinateList(input, 'point');
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/kimi.mjs","sources":["../../../../src/ai-model/models/kimi.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 parseCoordinateList,\n} from '../shared/model-locate-result';\n\nconst kimiNormalizedPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1,\n} as const;\nconst kimiPixelPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n} as const;\n\nfunction parseKimiRawLocateValue(input: unknown): LocateResultValue {\n const point = parseCoordinateList(input, 'point');\n if (point.length < 2) {\n throw new Error(`invalid point data: ${JSON.stringify(input)} `);\n }\n const [x, y] = point;\n // Keep this compatible with OSWorld's Kimi adapter: values <= 1 are\n // normalized coordinates, otherwise they are treated as screenshot pixels.\n const coordinatesMeta =\n x <= 1 && y <= 1\n ? kimiNormalizedPointCoordinatesMeta\n : kimiPixelPointCoordinatesMeta;\n return createLocateResultValue(coordinatesMeta, [x, y]);\n}\n\nconst buildKimiChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled } = userConfig;\n const effectiveReasoningEnabled = reasoningEnabled ?? false;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n // kimi disallow custom temperature\n commonOverrideConfig.temperature = undefined;\n\n // Kimi Chat Completions response_format:\n // https://platform.kimi.com/docs/api/chat\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const modelSpecificConfig: Record<string, unknown> = {\n thinking: {\n type: effectiveReasoningEnabled ? 'enabled' : 'disabled',\n },\n };\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst buildKimi3ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n // Kimi disallows custom temperature.\n commonOverrideConfig.temperature = undefined;\n\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n // Kimi K3 currently only supports reasoning_effort=\"max\"; its docs say\n // additional effort levels will be available later.\n const reasoningEffort = userConfig.reasoningEffort;\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...(reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),\n },\n };\n};\n\nexport const kimiAdapters = {\n kimi: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEffort', 'reasoningBudget'],\n buildChatCompletionParams: buildKimiChatCompletionParams,\n useReasoningAsContentFallback: true,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: kimiNormalizedPointCoordinatesMeta,\n parseRawLocateValue: parseKimiRawLocateValue,\n },\n },\n },\n },\n kimi3: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEnabled', 'reasoningBudget'],\n buildChatCompletionParams: buildKimi3ChatCompletionParams,\n useReasoningAsContentFallback: true,\n // Kimi K3 multi-turn and tool calls must replay the complete assistant\n // message, including reasoning_content and tool_calls.\n // https://platform.kimi.com/docs/guide/use-thinking-effort\n replayRawAssistantMessage: true,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: kimiNormalizedPointCoordinatesMeta,\n parseRawLocateValue: parseKimiRawLocateValue,\n },\n },\n },\n },\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'kimi' | 'kimi3'\n>;\n"],"names":["kimiNormalizedPointCoordinatesMeta","kimiPixelPointCoordinatesMeta","parseKimiRawLocateValue","input","point","parseCoordinateList","Error","JSON","x","y","coordinatesMeta","createLocateResultValue","buildKimiChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","effectiveReasoningEnabled","commonOverrideConfig","undefined","modelSpecificConfig","buildKimi3ChatCompletionParams","reasoningEffort","kimiAdapters"],"mappings":";AAYA,MAAMA,qCAAqC;IACzC,OAAO;IACP,OAAO;IACP,cAAc;AAChB;AACA,MAAMC,gCAAgC;IACpC,OAAO;IACP,OAAO;AACT;AAEA,SAASC,wBAAwBC,KAAc;IAC7C,MAAMC,QAAQC,oBAAoBF,OAAO;IACzC,IAAIC,MAAM,MAAM,GAAG,GACjB,MAAM,IAAIE,MAAM,CAAC,oBAAoB,EAAEC,KAAK,SAAS,CAACJ,OAAO,CAAC,CAAC;IAEjE,MAAM,CAACK,GAAGC,EAAE,GAAGL;IAGf,MAAMM,kBACJF,KAAK,KAAKC,KAAK,IACXT,qCACAC;IACN,OAAOU,wBAAwBD,iBAAiB;QAACF;QAAGC;KAAE;AACxD;AAEA,MAAMG,gCAAgC,CACpCT;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAE,GAAGX;IACzC,MAAM,EAAEY,gBAAgB,EAAE,GAAGD;IAC7B,MAAME,4BAA4BD,oBAAoB;IACtD,MAAME,uBAAgD,CAAC;IAGvDA,qBAAqB,WAAW,GAAGC;IAInC,IACEJ,AAA8B,WAA9BA,WAAW,cAAc,IACzBX,MAAM,0BAA0B,EAEhCc,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAME,sBAA+C;QACnD,UAAU;YACR,MAAMH,4BAA4B,YAAY;QAChD;IACF;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGE,mBAAmB;QACxB;IACF;AACF;AAEA,MAAMC,iCAAiC,CACrCjB;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAE,GAAGX;IACzC,MAAMc,uBAAgD,CAAC;IAGvDA,qBAAqB,WAAW,GAAGC;IAEnC,IACEJ,AAA8B,WAA9BA,WAAW,cAAc,IACzBX,MAAM,0BAA0B,EAEhCc,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAK/D,MAAMI,kBAAkBP,WAAW,eAAe;IAElD,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAII,kBAAkB;gBAAE,kBAAkBA;YAAgB,IAAI,CAAC,CAAC;QAClE;IACF;AACF;AAEO,MAAMC,eAAe;IAC1B,MAAM;QACJ,gBAAgB;YACd,uBAAuB;gBAAC;gBAAmB;aAAkB;YAC7D,2BAA2BV;YAC3B,+BAA+B;QACjC;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAaZ;oBACb,qBAAqBE;gBACvB;YACF;QACF;IACF;IACA,OAAO;QACL,gBAAgB;YACd,uBAAuB;gBAAC;gBAAoB;aAAkB;YAC9D,2BAA2BkB;YAC3B,+BAA+B;YAI/B,2BAA2B;QAC7B;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAapB;oBACb,qBAAqBE;gBACvB;YACF;QACF;IACF;AACF"}
1
+ {"version":3,"file":"ai-model/models/kimi.mjs","sources":["../../../../src/ai-model/models/kimi.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 parseCoordinateList,\n} from '../shared/model-locate-result';\n\nconst kimiNormalizedPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1,\n rounding: 'round',\n} as const;\nconst kimiPixelPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n rounding: 'round',\n} as const;\n\nfunction parseKimiRawLocateValue(input: unknown): LocateResultValue {\n const point = parseCoordinateList(input, 'point');\n if (point.length < 2) {\n throw new Error(`invalid point data: ${JSON.stringify(input)} `);\n }\n const [x, y] = point;\n // Keep this compatible with OSWorld's Kimi adapter: values <= 1 are\n // normalized coordinates, otherwise they are treated as screenshot pixels.\n const coordinatesMeta =\n x <= 1 && y <= 1\n ? kimiNormalizedPointCoordinatesMeta\n : kimiPixelPointCoordinatesMeta;\n return createLocateResultValue(coordinatesMeta, [x, y]);\n}\n\nconst buildKimiChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled } = userConfig;\n const effectiveReasoningEnabled = reasoningEnabled ?? false;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n // kimi disallow custom temperature\n commonOverrideConfig.temperature = undefined;\n\n // Kimi Chat Completions response_format:\n // https://platform.kimi.com/docs/api/chat\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n const modelSpecificConfig: Record<string, unknown> = {\n thinking: {\n type: effectiveReasoningEnabled ? 'enabled' : 'disabled',\n },\n };\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst buildKimi3ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n // Kimi disallows custom temperature.\n commonOverrideConfig.temperature = undefined;\n\n if (\n userConfig.responseFormat !== 'none' &&\n input.expectedJsonObjectResponse\n ) {\n commonOverrideConfig.response_format = { type: 'json_object' };\n }\n\n // Kimi K3 currently only supports reasoning_effort=\"max\"; its docs say\n // additional effort levels will be available later.\n const reasoningEffort = userConfig.reasoningEffort;\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...(reasoningEffort ? { reasoning_effort: reasoningEffort } : {}),\n },\n };\n};\n\nexport const kimiAdapters = {\n kimi: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEffort', 'reasoningBudget'],\n buildChatCompletionParams: buildKimiChatCompletionParams,\n useReasoningAsContentFallback: true,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: kimiNormalizedPointCoordinatesMeta,\n parseRawLocateValue: parseKimiRawLocateValue,\n },\n },\n },\n },\n kimi3: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEnabled', 'reasoningBudget'],\n buildChatCompletionParams: buildKimi3ChatCompletionParams,\n useReasoningAsContentFallback: true,\n // Kimi K3 multi-turn and tool calls must replay the complete assistant\n // message, including reasoning_content and tool_calls.\n // https://platform.kimi.com/docs/guide/use-thinking-effort\n replayRawAssistantMessage: true,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: kimiNormalizedPointCoordinatesMeta,\n parseRawLocateValue: parseKimiRawLocateValue,\n },\n },\n },\n },\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'kimi' | 'kimi3'\n>;\n"],"names":["kimiNormalizedPointCoordinatesMeta","kimiPixelPointCoordinatesMeta","parseKimiRawLocateValue","input","point","parseCoordinateList","Error","JSON","x","y","coordinatesMeta","createLocateResultValue","buildKimiChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","effectiveReasoningEnabled","commonOverrideConfig","undefined","modelSpecificConfig","buildKimi3ChatCompletionParams","reasoningEffort","kimiAdapters"],"mappings":";AAYA,MAAMA,qCAAqC;IACzC,OAAO;IACP,OAAO;IACP,cAAc;IACd,UAAU;AACZ;AACA,MAAMC,gCAAgC;IACpC,OAAO;IACP,OAAO;IACP,UAAU;AACZ;AAEA,SAASC,wBAAwBC,KAAc;IAC7C,MAAMC,QAAQC,oBAAoBF,OAAO;IACzC,IAAIC,MAAM,MAAM,GAAG,GACjB,MAAM,IAAIE,MAAM,CAAC,oBAAoB,EAAEC,KAAK,SAAS,CAACJ,OAAO,CAAC,CAAC;IAEjE,MAAM,CAACK,GAAGC,EAAE,GAAGL;IAGf,MAAMM,kBACJF,KAAK,KAAKC,KAAK,IACXT,qCACAC;IACN,OAAOU,wBAAwBD,iBAAiB;QAACF;QAAGC;KAAE;AACxD;AAEA,MAAMG,gCAAgC,CACpCT;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAE,GAAGX;IACzC,MAAM,EAAEY,gBAAgB,EAAE,GAAGD;IAC7B,MAAME,4BAA4BD,oBAAoB;IACtD,MAAME,uBAAgD,CAAC;IAGvDA,qBAAqB,WAAW,GAAGC;IAInC,IACEJ,AAA8B,WAA9BA,WAAW,cAAc,IACzBX,MAAM,0BAA0B,EAEhCc,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAME,sBAA+C;QACnD,UAAU;YACR,MAAMH,4BAA4B,YAAY;QAChD;IACF;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGE,mBAAmB;QACxB;IACF;AACF;AAEA,MAAMC,iCAAiC,CACrCjB;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAE,GAAGX;IACzC,MAAMc,uBAAgD,CAAC;IAGvDA,qBAAqB,WAAW,GAAGC;IAEnC,IACEJ,AAA8B,WAA9BA,WAAW,cAAc,IACzBX,MAAM,0BAA0B,EAEhCc,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAK/D,MAAMI,kBAAkBP,WAAW,eAAe;IAElD,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAII,kBAAkB;gBAAE,kBAAkBA;YAAgB,IAAI,CAAC,CAAC;QAClE;IACF;AACF;AAEO,MAAMC,eAAe;IAC1B,MAAM;QACJ,gBAAgB;YACd,uBAAuB;gBAAC;gBAAmB;aAAkB;YAC7D,2BAA2BV;YAC3B,+BAA+B;QACjC;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAaZ;oBACb,qBAAqBE;gBACvB;YACF;QACF;IACF;IACA,OAAO;QACL,gBAAgB;YACd,uBAAuB;gBAAC;gBAAoB;aAAkB;YAC9D,2BAA2BkB;YAC3B,+BAA+B;YAI/B,2BAA2B;QAC7B;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAapB;oBACb,qBAAqBE;gBACvB;YACF;QACF;IACF;AACF"}
@@ -1,26 +1,20 @@
1
- import { createLocateResultValue, isBboxLocateResultValue, unwrapCoordinateListLikeInput } from "../shared/model-locate-result/index.mjs";
2
- const defaultBboxSize = 20;
1
+ import { createLocateResultValue, unwrapCoordinateListLikeInput } from "../shared/model-locate-result/index.mjs";
3
2
  const qwen25BboxCoordinatesMeta = {
4
3
  shape: 'bbox',
5
- order: 'xy'
4
+ order: 'xy',
5
+ rounding: 'round'
6
6
  };
7
7
  const qwen25PointCoordinatesMeta = {
8
8
  shape: 'point',
9
- order: 'xy'
9
+ order: 'xy',
10
+ rounding: 'round'
10
11
  };
11
12
  const qwen3BboxCoordinatesMeta = {
12
13
  shape: 'bbox',
13
14
  order: 'xy',
14
- normalizedBy: 1000
15
+ normalizedBy: 1000,
16
+ rounding: 'round'
15
17
  };
16
- function topLeftPointToPixelBbox(x, y) {
17
- return [
18
- Math.round(x),
19
- Math.round(y),
20
- Math.round(x + defaultBboxSize),
21
- Math.round(y + defaultBboxSize)
22
- ];
23
- }
24
18
  function parseQwen25RawLocateValue(input) {
25
19
  const bbox = unwrapCoordinateListLikeInput(input);
26
20
  if (bbox.length < 2) {
@@ -38,19 +32,6 @@ function parseQwen25RawLocateValue(input) {
38
32
  bbox[1]
39
33
  ]);
40
34
  }
41
- function normalizeQwen25ResultToPixelBbox(result) {
42
- if (isBboxLocateResultValue(result)) {
43
- const { coordinates } = result;
44
- return [
45
- Math.round(coordinates[0]),
46
- Math.round(coordinates[1]),
47
- Math.round(coordinates[2]),
48
- Math.round(coordinates[3])
49
- ];
50
- }
51
- const { coordinates } = result;
52
- return topLeftPointToPixelBbox(coordinates[0], coordinates[1]);
53
- }
54
35
  const buildQwenChatCompletionParams = (input)=>{
55
36
  const { midsceneDefaults, userConfig } = input;
56
37
  const { reasoningEnabled, reasoningBudget } = userConfig;
@@ -123,8 +104,7 @@ const qwenAdapters = {
123
104
  element: {
124
105
  resultFormat: {
125
106
  coordinates: qwen25BboxCoordinatesMeta,
126
- parseRawLocateValue: parseQwen25RawLocateValue,
127
- mapLocateResultToPixelBbox: normalizeQwen25ResultToPixelBbox
107
+ parseRawLocateValue: parseQwen25RawLocateValue
128
108
  }
129
109
  }
130
110
  }
@@ -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 type PixelBbox,\n createLocateResultValue,\n isBboxLocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../shared/model-locate-result';\n\nconst defaultBboxSize = 20;\nconst qwen25BboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n} as const;\nconst qwen25PointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n} as const;\nconst qwen3BboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n} as const;\n\nfunction topLeftPointToPixelBbox(x: number, y: number): PixelBbox {\n return [\n Math.round(x),\n Math.round(y),\n Math.round(x + defaultBboxSize),\n Math.round(y + defaultBboxSize),\n ];\n}\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\nfunction normalizeQwen25ResultToPixelBbox(\n result: LocateResultValue,\n): PixelBbox {\n if (isBboxLocateResultValue(result)) {\n const { coordinates } = result;\n return [\n Math.round(coordinates[0]),\n Math.round(coordinates[1]),\n Math.round(coordinates[2]),\n Math.round(coordinates[3]),\n ];\n }\n\n const { coordinates } = result;\n return topLeftPointToPixelBbox(coordinates[0], coordinates[1]);\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 mapLocateResultToPixelBbox: normalizeQwen25ResultToPixelBbox,\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":["defaultBboxSize","qwen25BboxCoordinatesMeta","qwen25PointCoordinatesMeta","qwen3BboxCoordinatesMeta","topLeftPointToPixelBbox","x","y","Math","parseQwen25RawLocateValue","input","bbox","unwrapCoordinateListLikeInput","msg","JSON","Error","createLocateResultValue","normalizeQwen25ResultToPixelBbox","result","isBboxLocateResultValue","coordinates","buildQwenChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningBudget","commonOverrideConfig","undefined","modelSpecificConfig","buildQwen25ChatCompletionParams","qwen3Adapter","qwenAdapters"],"mappings":"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"}
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"}
@@ -6,12 +6,14 @@ const defaultVlmUiTarsReplanningCycleLimit = 40;
6
6
  const uiTarsBboxCoordinatesMeta = {
7
7
  shape: 'bbox',
8
8
  order: 'xy',
9
- normalizedBy: 1000
9
+ normalizedBy: 1000,
10
+ rounding: 'round'
10
11
  };
11
12
  const uiTarsPointCoordinatesMeta = {
12
13
  shape: 'point',
13
14
  order: 'xy',
14
- normalizedBy: 1000
15
+ normalizedBy: 1000,
16
+ rounding: 'round'
15
17
  };
16
18
  function parseUiTarsRawLocateValue(input) {
17
19
  const bbox = unwrapCoordinateListLikeInput(input);
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/ui-tars/adapter.mjs","sources":["../../../../../src/ai-model/models/ui-tars/adapter.ts"],"sourcesContent":["import { type TModelFamily, UITarsModelVersion } from '@midscene/shared/env';\nimport { assert } from '@midscene/shared/utils';\nimport type { ModelAdapterDefinition } from '../../model-adapter/types';\nimport {\n type LocateResultValue,\n createLocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../../shared/model-locate-result';\nimport { createUiTarsPlanner } from './planning';\n\nconst defaultVlmUiTarsReplanningCycleLimit = 40;\nconst uiTarsBboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n} as const;\nconst uiTarsPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1000,\n} as const;\n\n// UI-TARS has not received active updates for a long time, so this parser is\n// intentionally kept separate from Doubao even though the current logic is the\n// same. This avoids coupling UI-TARS behavior to future Doubao adapter changes.\nfunction parseUiTarsRawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any);\n if (typeof bbox === 'string') {\n assert(\n /^(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)$/.test(bbox.trim()),\n `invalid bbox data string for ui-tars mode: ${bbox}`,\n );\n const splitted = bbox.split(' ');\n if (splitted.length === 4) {\n return createLocateResultValue(uiTarsBboxCoordinatesMeta, [\n Number(splitted[0]),\n Number(splitted[1]),\n Number(splitted[2]),\n Number(splitted[3]),\n ]);\n }\n throw new Error(`invalid bbox data string for ui-tars mode: ${bbox}`);\n }\n\n let bboxList: number[] = [];\n if (Array.isArray(bbox) && typeof bbox[0] === 'string') {\n bbox.forEach((item) => {\n if (typeof item === 'string' && item.includes(',')) {\n const [x, y] = item.split(',');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else if (typeof item === 'string' && item.includes(' ')) {\n const [x, y] = item.split(' ');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else {\n bboxList.push(Number(item));\n }\n });\n } else {\n bboxList = bbox as number[];\n }\n\n if (bboxList.length === 4 || bboxList.length === 5) {\n return createLocateResultValue(uiTarsBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[2],\n bboxList[3],\n ]);\n }\n\n if (\n bboxList.length === 6 ||\n bboxList.length === 2 ||\n bboxList.length === 3 ||\n bboxList.length === 7\n ) {\n return createLocateResultValue(uiTarsPointCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n ]);\n }\n\n if (bbox.length === 8) {\n return createLocateResultValue(uiTarsBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[4],\n bboxList[5],\n ]);\n }\n\n const msg = `invalid bbox data for ui-tars mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n}\n\nfunction createUiTarsAdapter(\n uiTarsModelVersion: UITarsModelVersion,\n): ModelAdapterDefinition {\n return {\n chatCompletion: {\n unsupportedUserConfig: [\n 'reasoningEnabled',\n 'reasoningEffort',\n 'reasoningBudget',\n ],\n buildChatCompletionParams: ({ midsceneDefaults, userConfig }) => {\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 },\n };\n },\n },\n planning: {\n kind: 'custom',\n cacheEnabled: false,\n defaultReplanningCycleLimit: defaultVlmUiTarsReplanningCycleLimit,\n planner: createUiTarsPlanner(uiTarsModelVersion),\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: uiTarsBboxCoordinatesMeta,\n parseRawLocateValue: parseUiTarsRawLocateValue,\n },\n },\n },\n };\n}\n\nconst uiTarsDoubao15Adapter = createUiTarsAdapter(\n UITarsModelVersion.DOUBAO_1_5_20B,\n);\n\nexport const uiTarsAdapters = {\n 'vlm-ui-tars': createUiTarsAdapter(UITarsModelVersion.V1_0),\n 'vlm-ui-tars-doubao': uiTarsDoubao15Adapter,\n 'vlm-ui-tars-doubao-1.5': uiTarsDoubao15Adapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'vlm-ui-tars' | 'vlm-ui-tars-doubao' | 'vlm-ui-tars-doubao-1.5'\n>;\n"],"names":["defaultVlmUiTarsReplanningCycleLimit","uiTarsBboxCoordinatesMeta","uiTarsPointCoordinatesMeta","parseUiTarsRawLocateValue","input","bbox","unwrapCoordinateListLikeInput","assert","splitted","createLocateResultValue","Number","Error","bboxList","Array","item","x","y","msg","JSON","createUiTarsAdapter","uiTarsModelVersion","midsceneDefaults","userConfig","commonOverrideConfig","undefined","createUiTarsPlanner","uiTarsDoubao15Adapter","UITarsModelVersion","uiTarsAdapters"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/models/ui-tars/adapter.mjs","sources":["../../../../../src/ai-model/models/ui-tars/adapter.ts"],"sourcesContent":["import { type TModelFamily, UITarsModelVersion } from '@midscene/shared/env';\nimport { assert } from '@midscene/shared/utils';\nimport type { ModelAdapterDefinition } from '../../model-adapter/types';\nimport {\n type LocateResultValue,\n createLocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../../shared/model-locate-result';\nimport { createUiTarsPlanner } from './planning';\n\nconst defaultVlmUiTarsReplanningCycleLimit = 40;\nconst uiTarsBboxCoordinatesMeta = {\n shape: 'bbox',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\nconst uiTarsPointCoordinatesMeta = {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1000,\n rounding: 'round',\n} as const;\n\n// UI-TARS has not received active updates for a long time, so this parser is\n// intentionally kept separate from Doubao even though the current logic is the\n// same. This avoids coupling UI-TARS behavior to future Doubao adapter changes.\nfunction parseUiTarsRawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any);\n if (typeof bbox === 'string') {\n assert(\n /^(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)$/.test(bbox.trim()),\n `invalid bbox data string for ui-tars mode: ${bbox}`,\n );\n const splitted = bbox.split(' ');\n if (splitted.length === 4) {\n return createLocateResultValue(uiTarsBboxCoordinatesMeta, [\n Number(splitted[0]),\n Number(splitted[1]),\n Number(splitted[2]),\n Number(splitted[3]),\n ]);\n }\n throw new Error(`invalid bbox data string for ui-tars mode: ${bbox}`);\n }\n\n let bboxList: number[] = [];\n if (Array.isArray(bbox) && typeof bbox[0] === 'string') {\n bbox.forEach((item) => {\n if (typeof item === 'string' && item.includes(',')) {\n const [x, y] = item.split(',');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else if (typeof item === 'string' && item.includes(' ')) {\n const [x, y] = item.split(' ');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else {\n bboxList.push(Number(item));\n }\n });\n } else {\n bboxList = bbox as number[];\n }\n\n if (bboxList.length === 4 || bboxList.length === 5) {\n return createLocateResultValue(uiTarsBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[2],\n bboxList[3],\n ]);\n }\n\n if (\n bboxList.length === 6 ||\n bboxList.length === 2 ||\n bboxList.length === 3 ||\n bboxList.length === 7\n ) {\n return createLocateResultValue(uiTarsPointCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n ]);\n }\n\n if (bbox.length === 8) {\n return createLocateResultValue(uiTarsBboxCoordinatesMeta, [\n bboxList[0],\n bboxList[1],\n bboxList[4],\n bboxList[5],\n ]);\n }\n\n const msg = `invalid bbox data for ui-tars mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n}\n\nfunction createUiTarsAdapter(\n uiTarsModelVersion: UITarsModelVersion,\n): ModelAdapterDefinition {\n return {\n chatCompletion: {\n unsupportedUserConfig: [\n 'reasoningEnabled',\n 'reasoningEffort',\n 'reasoningBudget',\n ],\n buildChatCompletionParams: ({ midsceneDefaults, userConfig }) => {\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 },\n };\n },\n },\n planning: {\n kind: 'custom',\n cacheEnabled: false,\n defaultReplanningCycleLimit: defaultVlmUiTarsReplanningCycleLimit,\n planner: createUiTarsPlanner(uiTarsModelVersion),\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: uiTarsBboxCoordinatesMeta,\n parseRawLocateValue: parseUiTarsRawLocateValue,\n },\n },\n },\n };\n}\n\nconst uiTarsDoubao15Adapter = createUiTarsAdapter(\n UITarsModelVersion.DOUBAO_1_5_20B,\n);\n\nexport const uiTarsAdapters = {\n 'vlm-ui-tars': createUiTarsAdapter(UITarsModelVersion.V1_0),\n 'vlm-ui-tars-doubao': uiTarsDoubao15Adapter,\n 'vlm-ui-tars-doubao-1.5': uiTarsDoubao15Adapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'vlm-ui-tars' | 'vlm-ui-tars-doubao' | 'vlm-ui-tars-doubao-1.5'\n>;\n"],"names":["defaultVlmUiTarsReplanningCycleLimit","uiTarsBboxCoordinatesMeta","uiTarsPointCoordinatesMeta","parseUiTarsRawLocateValue","input","bbox","unwrapCoordinateListLikeInput","assert","splitted","createLocateResultValue","Number","Error","bboxList","Array","item","x","y","msg","JSON","createUiTarsAdapter","uiTarsModelVersion","midsceneDefaults","userConfig","commonOverrideConfig","undefined","createUiTarsPlanner","uiTarsDoubao15Adapter","UITarsModelVersion","uiTarsAdapters"],"mappings":"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"}
@@ -113,12 +113,6 @@ const extractImageInputs = (message, imageDetailOverride)=>{
113
113
  }
114
114
  return inputs;
115
115
  };
116
- const resolveCodexReasoningEffort = ({ reasoningEnabled, modelConfig })=>{
117
- if (true !== reasoningEnabled) return 'none';
118
- const normalized = modelConfig.reasoningEffort?.trim().toLowerCase();
119
- if ('none' === normalized || 'minimal' === normalized || 'low' === normalized || 'medium' === normalized || 'high' === normalized || 'xhigh' === normalized) return normalized;
120
- return 'medium';
121
- };
122
116
  const buildCodexTurnPayloadFromMessages = (messages, imageDetailOverride)=>{
123
117
  const developerInstructionParts = [];
124
118
  const transcriptParts = [];
@@ -181,16 +175,12 @@ class CodexAppServerConnection {
181
175
  isClosed() {
182
176
  return this.closed;
183
177
  }
184
- async runTurn({ messages, modelConfig, stream, onChunk, reasoningEnabled, abortSignal, imageDetail, onRecordEvent }) {
178
+ async runTurn({ messages, modelConfig, stream, onChunk, params, abortSignal, imageDetail, onRecordEvent }) {
185
179
  const startTime = Date.now();
186
180
  const timeoutMs = modelConfig.timeout || CODEX_DEFAULT_TIMEOUT_MS;
187
181
  const deadlineAt = Date.now() + timeoutMs;
188
182
  const isStreaming = !!(stream && onChunk);
189
183
  const { developerInstructions, input } = buildCodexTurnPayloadFromMessages(messages, imageDetail);
190
- const effort = resolveCodexReasoningEffort({
191
- reasoningEnabled,
192
- modelConfig
193
- });
194
184
  let threadId;
195
185
  let turnId;
196
186
  let latestErrorMessage;
@@ -244,9 +234,9 @@ class CodexAppServerConnection {
244
234
  threadId = threadStartResponse?.thread?.id;
245
235
  if (!threadId) throw new Error('thread/start did not return a thread id');
246
236
  const turnStartParams = {
237
+ ...params,
247
238
  threadId,
248
- input,
249
- effort
239
+ input
250
240
  };
251
241
  onRecordEvent?.({
252
242
  type: 'request',
@@ -573,7 +563,7 @@ class CodexAppServerConnection {
573
563
  }
574
564
  }
575
565
  class CodexAppServerConnectionManager {
576
- async runTurn({ messages, modelConfig, stream, onChunk, reasoningEnabled, abortSignal, imageDetail, onRecordEvent }) {
566
+ async runTurn({ messages, modelConfig, stream, onChunk, params, abortSignal, imageDetail, onRecordEvent }) {
577
567
  return this.runner.run(async ()=>{
578
568
  const connection = await this.getConnection();
579
569
  try {
@@ -582,7 +572,7 @@ class CodexAppServerConnectionManager {
582
572
  modelConfig,
583
573
  stream,
584
574
  onChunk,
585
- reasoningEnabled,
575
+ params,
586
576
  abortSignal,
587
577
  imageDetail,
588
578
  onRecordEvent
@@ -623,7 +613,7 @@ async function callAIWithCodexAppServer(messages, modelConfig, options) {
623
613
  modelConfig,
624
614
  stream: options?.stream,
625
615
  onChunk: options?.onChunk,
626
- reasoningEnabled: options?.reasoningEnabled,
616
+ params: options?.params,
627
617
  abortSignal: options?.abortSignal,
628
618
  imageDetail: options?.imageDetail,
629
619
  onRecordEvent: options?.onRecordEvent
@@ -632,6 +622,6 @@ async function callAIWithCodexAppServer(messages, modelConfig, options) {
632
622
  async function __shutdownCodexAppServerForTests() {
633
623
  await codexConnectionManager.shutdownForTests();
634
624
  }
635
- export { __shutdownCodexAppServerForTests, buildCodexTurnPayloadFromMessages, callAIWithCodexAppServer, isCodexAppServerProvider, normalizeCodexLocalImagePath, resolveCodexReasoningEffort };
625
+ export { __shutdownCodexAppServerForTests, buildCodexTurnPayloadFromMessages, callAIWithCodexAppServer, isCodexAppServerProvider, normalizeCodexLocalImagePath };
636
626
 
637
627
  //# sourceMappingURL=codex-app-server.mjs.map