@midscene/core 1.12.9 → 1.12.10-beta-20260918061340.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (151) hide show
  1. package/dist/es/agent/task-builder.mjs +1 -1
  2. package/dist/es/agent/task-builder.mjs.map +1 -1
  3. package/dist/es/agent/tasks.mjs +4 -4
  4. package/dist/es/agent/tasks.mjs.map +1 -1
  5. package/dist/es/agent/utils.mjs +1 -1
  6. package/dist/es/ai-model/model-adapter/chat-completion.mjs +8 -11
  7. package/dist/es/ai-model/model-adapter/chat-completion.mjs.map +1 -1
  8. package/dist/es/ai-model/model-adapter/resolve.mjs +10 -0
  9. package/dist/es/ai-model/model-adapter/resolve.mjs.map +1 -1
  10. package/dist/es/ai-model/model-adapter/responses.mjs +37 -0
  11. package/dist/es/ai-model/model-adapter/responses.mjs.map +1 -0
  12. package/dist/es/ai-model/model-adapter/temperature-with-semantic-retry.mjs +7 -0
  13. package/dist/es/ai-model/model-adapter/temperature-with-semantic-retry.mjs.map +1 -0
  14. package/dist/es/ai-model/models/gpt.mjs +68 -8
  15. package/dist/es/ai-model/models/gpt.mjs.map +1 -1
  16. package/dist/es/ai-model/models/registry.mjs +2 -2
  17. package/dist/es/ai-model/models/registry.mjs.map +1 -1
  18. package/dist/es/ai-model/service-caller/call-ai.mjs +22 -13
  19. package/dist/es/ai-model/service-caller/call-ai.mjs.map +1 -1
  20. package/dist/es/ai-model/service-caller/codex/call-codex.mjs +5 -1
  21. package/dist/es/ai-model/service-caller/codex/call-codex.mjs.map +1 -1
  22. package/dist/es/ai-model/service-caller/index.mjs +1 -2
  23. package/dist/es/ai-model/service-caller/model-call.mjs +4 -4
  24. package/dist/es/ai-model/service-caller/model-call.mjs.map +1 -1
  25. package/dist/es/ai-model/service-caller/openai/call-openai.mjs +13 -8
  26. package/dist/es/ai-model/service-caller/openai/call-openai.mjs.map +1 -1
  27. package/dist/es/ai-model/service-caller/openai/chat-completion/chat-completion.mjs +12 -6
  28. package/dist/es/ai-model/service-caller/openai/chat-completion/chat-completion.mjs.map +1 -1
  29. package/dist/es/ai-model/service-caller/openai/chat-completion/non-stream.mjs +9 -9
  30. package/dist/es/ai-model/service-caller/openai/chat-completion/non-stream.mjs.map +1 -1
  31. package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs +4 -8
  32. package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs.map +1 -1
  33. package/dist/es/ai-model/service-caller/openai/openai-client.mjs +3 -3
  34. package/dist/es/ai-model/service-caller/openai/openai-client.mjs.map +1 -1
  35. package/dist/es/ai-model/service-caller/openai/responses/non-stream.mjs +21 -0
  36. package/dist/es/ai-model/service-caller/openai/responses/non-stream.mjs.map +1 -0
  37. package/dist/es/ai-model/service-caller/openai/responses/responses.mjs +60 -0
  38. package/dist/es/ai-model/service-caller/openai/responses/responses.mjs.map +1 -0
  39. package/dist/es/ai-model/service-caller/openai/responses/stream.mjs +56 -0
  40. package/dist/es/ai-model/service-caller/openai/responses/stream.mjs.map +1 -0
  41. package/dist/es/ai-model/service-caller/openai/responses/types.mjs +0 -0
  42. package/dist/es/ai-model/service-caller/openai/responses/utils.mjs +60 -0
  43. package/dist/es/ai-model/service-caller/openai/responses/utils.mjs.map +1 -0
  44. package/dist/es/ai-model/service-caller/utils.mjs +5 -4
  45. package/dist/es/ai-model/service-caller/utils.mjs.map +1 -1
  46. package/dist/es/ai-model/workflows/grounding/locate.mjs +6 -6
  47. package/dist/es/ai-model/workflows/grounding/locate.mjs.map +1 -1
  48. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs +5 -5
  49. package/dist/es/ai-model/workflows/grounding/planning-action-locate.mjs.map +1 -1
  50. package/dist/es/ai-model/workflows/grounding/section-locate.mjs +5 -5
  51. package/dist/es/ai-model/workflows/grounding/section-locate.mjs.map +1 -1
  52. package/dist/es/ai-model/workflows/insight/extraction.mjs +3 -3
  53. package/dist/es/ai-model/workflows/insight/extraction.mjs.map +1 -1
  54. package/dist/es/ai-model/workflows/planning/custom-planning.mjs +3 -3
  55. package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -1
  56. package/dist/es/ai-model/workflows/planning/standard-planning.mjs +4 -4
  57. package/dist/es/ai-model/workflows/planning/standard-planning.mjs.map +1 -1
  58. package/dist/es/report-html-template.mjs +1 -1
  59. package/dist/es/service/index.mjs +11 -11
  60. package/dist/es/service/index.mjs.map +1 -1
  61. package/dist/es/types.mjs.map +1 -1
  62. package/dist/es/utils.mjs +1 -1
  63. package/dist/lib/agent/task-builder.js +1 -1
  64. package/dist/lib/agent/task-builder.js.map +1 -1
  65. package/dist/lib/agent/tasks.js +4 -4
  66. package/dist/lib/agent/tasks.js.map +1 -1
  67. package/dist/lib/agent/utils.js +1 -1
  68. package/dist/lib/ai-model/model-adapter/chat-completion.js +8 -11
  69. package/dist/lib/ai-model/model-adapter/chat-completion.js.map +1 -1
  70. package/dist/lib/ai-model/model-adapter/resolve.js +10 -0
  71. package/dist/lib/ai-model/model-adapter/resolve.js.map +1 -1
  72. package/dist/lib/ai-model/model-adapter/responses.js +74 -0
  73. package/dist/lib/ai-model/model-adapter/responses.js.map +1 -0
  74. package/dist/lib/ai-model/model-adapter/temperature-with-semantic-retry.js +41 -0
  75. package/dist/lib/ai-model/model-adapter/temperature-with-semantic-retry.js.map +1 -0
  76. package/dist/lib/ai-model/models/gpt.js +68 -8
  77. package/dist/lib/ai-model/models/gpt.js.map +1 -1
  78. package/dist/lib/ai-model/models/registry.js +2 -2
  79. package/dist/lib/ai-model/models/registry.js.map +1 -1
  80. package/dist/lib/ai-model/service-caller/call-ai.js +22 -13
  81. package/dist/lib/ai-model/service-caller/call-ai.js.map +1 -1
  82. package/dist/lib/ai-model/service-caller/codex/call-codex.js +5 -1
  83. package/dist/lib/ai-model/service-caller/codex/call-codex.js.map +1 -1
  84. package/dist/lib/ai-model/service-caller/index.js +0 -4
  85. package/dist/lib/ai-model/service-caller/model-call.js +4 -4
  86. package/dist/lib/ai-model/service-caller/model-call.js.map +1 -1
  87. package/dist/lib/ai-model/service-caller/openai/call-openai.js +12 -7
  88. package/dist/lib/ai-model/service-caller/openai/call-openai.js.map +1 -1
  89. package/dist/lib/ai-model/service-caller/openai/chat-completion/chat-completion.js +12 -6
  90. package/dist/lib/ai-model/service-caller/openai/chat-completion/chat-completion.js.map +1 -1
  91. package/dist/lib/ai-model/service-caller/openai/chat-completion/non-stream.js +9 -9
  92. package/dist/lib/ai-model/service-caller/openai/chat-completion/non-stream.js.map +1 -1
  93. package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js +4 -8
  94. package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js.map +1 -1
  95. package/dist/lib/ai-model/service-caller/openai/openai-client.js +5 -5
  96. package/dist/lib/ai-model/service-caller/openai/openai-client.js.map +1 -1
  97. package/dist/lib/ai-model/service-caller/openai/responses/non-stream.js +55 -0
  98. package/dist/lib/ai-model/service-caller/openai/responses/non-stream.js.map +1 -0
  99. package/dist/lib/ai-model/service-caller/openai/responses/responses.js +97 -0
  100. package/dist/lib/ai-model/service-caller/openai/responses/responses.js.map +1 -0
  101. package/dist/lib/ai-model/service-caller/openai/responses/stream.js +90 -0
  102. package/dist/lib/ai-model/service-caller/openai/responses/stream.js.map +1 -0
  103. package/dist/lib/ai-model/service-caller/openai/responses/types.js +20 -0
  104. package/dist/lib/ai-model/service-caller/openai/responses/types.js.map +1 -0
  105. package/dist/lib/ai-model/service-caller/openai/responses/utils.js +100 -0
  106. package/dist/lib/ai-model/service-caller/openai/responses/utils.js.map +1 -0
  107. package/dist/lib/ai-model/service-caller/utils.js +5 -4
  108. package/dist/lib/ai-model/service-caller/utils.js.map +1 -1
  109. package/dist/lib/ai-model/workflows/grounding/locate.js +6 -6
  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 +5 -5
  112. package/dist/lib/ai-model/workflows/grounding/planning-action-locate.js.map +1 -1
  113. package/dist/lib/ai-model/workflows/grounding/section-locate.js +5 -5
  114. package/dist/lib/ai-model/workflows/grounding/section-locate.js.map +1 -1
  115. package/dist/lib/ai-model/workflows/insight/extraction.js +3 -3
  116. package/dist/lib/ai-model/workflows/insight/extraction.js.map +1 -1
  117. package/dist/lib/ai-model/workflows/planning/custom-planning.js +3 -3
  118. package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -1
  119. package/dist/lib/ai-model/workflows/planning/standard-planning.js +4 -4
  120. package/dist/lib/ai-model/workflows/planning/standard-planning.js.map +1 -1
  121. package/dist/lib/report-html-template.js +1 -1
  122. package/dist/lib/service/index.js +11 -11
  123. package/dist/lib/service/index.js.map +1 -1
  124. package/dist/lib/types.js.map +1 -1
  125. package/dist/lib/utils.js +1 -1
  126. package/dist/types/ai-model/model-adapter/resolve.d.ts +4 -1
  127. package/dist/types/ai-model/model-adapter/responses.d.ts +3 -0
  128. package/dist/types/ai-model/model-adapter/temperature-with-semantic-retry.d.ts +5 -0
  129. package/dist/types/ai-model/model-adapter/types.d.ts +38 -13
  130. package/dist/types/ai-model/models/gpt.d.ts +13 -3
  131. package/dist/types/ai-model/models/registry.d.ts +12 -2
  132. package/dist/types/ai-model/service-caller/index.d.ts +0 -1
  133. package/dist/types/ai-model/service-caller/model-call.d.ts +3 -2
  134. package/dist/types/ai-model/service-caller/openai/call-openai.d.ts +9 -1
  135. package/dist/types/ai-model/service-caller/openai/chat-completion/chat-completion.d.ts +3 -4
  136. package/dist/types/ai-model/service-caller/openai/chat-completion/non-stream.d.ts +1 -1
  137. package/dist/types/ai-model/service-caller/openai/chat-completion/stream.d.ts +1 -1
  138. package/dist/types/ai-model/service-caller/openai/chat-completion/types.d.ts +5 -5
  139. package/dist/types/ai-model/service-caller/openai/openai-client.d.ts +2 -2
  140. package/dist/types/ai-model/service-caller/openai/responses/non-stream.d.ts +3 -0
  141. package/dist/types/ai-model/service-caller/openai/responses/responses.d.ts +7 -0
  142. package/dist/types/ai-model/service-caller/openai/responses/stream.d.ts +3 -0
  143. package/dist/types/ai-model/service-caller/openai/responses/types.d.ts +7 -0
  144. package/dist/types/ai-model/service-caller/openai/responses/utils.d.ts +7 -0
  145. package/dist/types/ai-model/service-caller/types.d.ts +3 -2
  146. package/dist/types/ai-model/service-caller/utils.d.ts +5 -3
  147. package/dist/types/ai-model/workflows/grounding/section-locate.d.ts +2 -1
  148. package/dist/types/ai-model/workflows/grounding/types.d.ts +3 -2
  149. package/dist/types/ai-model/workflows/insight/extraction.d.ts +1 -1
  150. package/dist/types/types.d.ts +11 -2
  151. package/package.json +2 -2
@@ -4,6 +4,7 @@ import { buildDefaultCodexAppServerParams } from "./codex-app-server.mjs";
4
4
  import { resolveInsight } from "./insight.mjs";
5
5
  import { resolveLocate } from "./locate.mjs";
6
6
  import { resolveCustomPlanningDefinition, resolvePlanning } from "./planning.mjs";
7
+ import { resolveResponses } from "./responses.mjs";
7
8
  function _define_property(obj, key, value) {
8
9
  if (key in obj) Object.defineProperty(obj, key, {
9
10
  value: value,
@@ -14,6 +15,7 @@ function _define_property(obj, key, value) {
14
15
  else obj[key] = value;
15
16
  return obj;
16
17
  }
18
+ const defaultImageDetail = (_input)=>void 0;
17
19
  function resolveJsonParser(jsonParser) {
18
20
  if (!jsonParser || 'lenient-json' === jsonParser) return parseModelResponseJson;
19
21
  if ('function' == typeof jsonParser) return jsonParser;
@@ -26,16 +28,24 @@ function resolveImagePreprocess(imagePreprocess) {
26
28
  }
27
29
  class ResolvedModelAdapter {
28
30
  constructor(config, modelFamily){
31
+ _define_property(this, "supportedApiTypes", void 0);
29
32
  _define_property(this, "jsonParser", void 0);
30
33
  _define_property(this, "chatCompletion", void 0);
34
+ _define_property(this, "resolveImageDetail", void 0);
35
+ _define_property(this, "responses", void 0);
31
36
  _define_property(this, "buildCodexAppServerParams", void 0);
32
37
  _define_property(this, "acceptBbox2dAlias", void 0);
33
38
  _define_property(this, "imagePreprocess", void 0);
34
39
  _define_property(this, "insight", void 0);
35
40
  _define_property(this, "planning", void 0);
36
41
  _define_property(this, "locate", void 0);
42
+ this.supportedApiTypes = config.supportedApiTypes ?? [
43
+ 'chat-completion'
44
+ ];
37
45
  this.jsonParser = resolveJsonParser(config.jsonParser);
38
46
  this.chatCompletion = resolveChatCompletion(config.chatCompletion);
47
+ this.resolveImageDetail = config.resolveImageDetail ?? defaultImageDetail;
48
+ this.responses = resolveResponses(config.responses);
39
49
  this.buildCodexAppServerParams = config.buildCodexAppServerParams ?? buildDefaultCodexAppServerParams;
40
50
  this.acceptBbox2dAlias = config.acceptBbox2dAlias ?? false;
41
51
  this.imagePreprocess = resolveImagePreprocess(config.imagePreprocess);
@@ -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 { 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
+ {"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 { resolveResponses } from './responses';\nimport type {\n BuildCodexAppServerParams,\n ChatCompletionAdapter,\n ImagePreprocessPolicy,\n JsonParser,\n LocateAdapter,\n ModelAdapter,\n ModelAdapterDefinition,\n PlanningAdapter,\n ResolveImageDetail,\n ResponsesAdapter,\n} from './types';\n\nconst defaultImageDetail = (_input: unknown) => undefined;\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 supportedApiTypes: ModelAdapter['supportedApiTypes'];\n readonly jsonParser: JsonParser;\n readonly chatCompletion: ChatCompletionAdapter;\n readonly resolveImageDetail: ResolveImageDetail;\n readonly responses: ResponsesAdapter;\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.supportedApiTypes = config.supportedApiTypes ?? ['chat-completion'];\n this.jsonParser = resolveJsonParser(config.jsonParser);\n this.chatCompletion = resolveChatCompletion(config.chatCompletion);\n this.resolveImageDetail = config.resolveImageDetail ?? defaultImageDetail;\n this.responses = resolveResponses(config.responses);\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":["defaultImageDetail","_input","undefined","resolveJsonParser","jsonParser","parseModelResponseJson","Error","resolveImagePreprocess","imagePreprocess","ResolvedModelAdapter","config","modelFamily","resolveChatCompletion","resolveResponses","buildDefaultCodexAppServerParams","resolveInsight","customPlanner","resolvedCustomPlanner","resolveCustomPlanningDefinition","resolveLocate","resolvePlanning"],"mappings":";;;;;;;;;;;;;;;;;AAqBA,MAAMA,qBAAqB,CAACC,SAAoBC;AAEhD,SAASC,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;IAaX,YAAYC,MAA8B,EAAEC,WAAmB,CAAE;QAZjE,uBAAS,qBAAT;QACA,uBAAS,cAAT;QACA,uBAAS,kBAAT;QACA,uBAAS,sBAAT;QACA,uBAAS,aAAT;QACA,uBAAS,6BAAT;QACA,uBAAS,qBAAT;QACA,uBAAS,mBAAT;QACA,uBAAS,WAAT;QACA,uBAAS,YAAT;QACA,uBAAS,UAAT;QAGE,IAAI,CAAC,iBAAiB,GAAGD,OAAO,iBAAiB,IAAI;YAAC;SAAkB;QACxE,IAAI,CAAC,UAAU,GAAGP,kBAAkBO,OAAO,UAAU;QACrD,IAAI,CAAC,cAAc,GAAGE,sBAAsBF,OAAO,cAAc;QACjE,IAAI,CAAC,kBAAkB,GAAGA,OAAO,kBAAkB,IAAIV;QACvD,IAAI,CAAC,SAAS,GAAGa,iBAAiBH,OAAO,SAAS;QAClD,IAAI,CAAC,yBAAyB,GAC5BA,OAAO,yBAAyB,IAAII;QACtC,IAAI,CAAC,iBAAiB,GAAGJ,OAAO,iBAAiB,IAAI;QACrD,IAAI,CAAC,eAAe,GAAGH,uBAAuBG,OAAO,eAAe;QACpE,IAAI,CAAC,OAAO,GAAGK,eAAeL,OAAO,OAAO,EAAE;YAC5C,YAAY,IAAI,CAAC,UAAU;QAC7B;QACA,MAAMM,gBACJN,OAAO,QAAQ,EAAE,SAAS,WAAWA,OAAO,QAAQ,CAAC,OAAO,GAAGR;QACjE,MAAMe,wBAAwBD,gBAC1BE,gCAAgCF,iBAChCd;QACJ,IAAI,CAAC,MAAM,GAAGiB,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/Bf;IAER;AACF"}
@@ -0,0 +1,37 @@
1
+ import { getTemperatureWithSemanticRetry } from "./temperature-with-semantic-retry.mjs";
2
+ const midsceneResponsesDefaults = {
3
+ temperature: 0
4
+ };
5
+ const buildDefaultResponsesParams = ({ midsceneDefaults, userConfig })=>({
6
+ config: {
7
+ temperature: userConfig.temperature ?? midsceneDefaults.temperature
8
+ }
9
+ });
10
+ function resolveResponses(responses) {
11
+ const buildResponsesParams = responses?.buildResponsesParams ?? buildDefaultResponsesParams;
12
+ return {
13
+ unsupportedUserConfig: responses?.unsupportedUserConfig ?? [],
14
+ buildResponsesParams: (input)=>{
15
+ const context = {
16
+ ...input,
17
+ userConfig: input.userConfig ?? {},
18
+ midsceneDefaults: midsceneResponsesDefaults
19
+ };
20
+ const params = buildResponsesParams(context);
21
+ return {
22
+ ...params,
23
+ config: {
24
+ ...params.config,
25
+ temperature: getTemperatureWithSemanticRetry({
26
+ temperature: params.config.temperature,
27
+ userTemperature: input.userConfig?.temperature,
28
+ semanticRetryAttempt: input.semanticRetryAttempt
29
+ })
30
+ }
31
+ };
32
+ }
33
+ };
34
+ }
35
+ export { buildDefaultResponsesParams, resolveResponses };
36
+
37
+ //# sourceMappingURL=responses.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/model-adapter/responses.mjs","sources":["../../../../src/ai-model/model-adapter/responses.ts"],"sourcesContent":["import { getTemperatureWithSemanticRetry } from './temperature-with-semantic-retry';\nimport type {\n BuildResponsesParams,\n MidsceneResponsesDefaults,\n ModelAdapterDefinition,\n ResponsesAdapter,\n} from './types';\n\nconst midsceneResponsesDefaults: MidsceneResponsesDefaults = {\n temperature: 0,\n};\n\nexport const buildDefaultResponsesParams: BuildResponsesParams = ({\n midsceneDefaults,\n userConfig,\n}) => ({\n config: {\n temperature: userConfig.temperature ?? midsceneDefaults.temperature,\n },\n});\n\nexport function resolveResponses(\n responses: ModelAdapterDefinition['responses'],\n): ResponsesAdapter {\n const buildResponsesParams =\n responses?.buildResponsesParams ?? buildDefaultResponsesParams;\n return {\n unsupportedUserConfig: responses?.unsupportedUserConfig ?? [],\n buildResponsesParams: (input) => {\n const context = {\n ...input,\n userConfig: input.userConfig ?? {},\n midsceneDefaults: midsceneResponsesDefaults,\n };\n const params = buildResponsesParams(context);\n return {\n ...params,\n config: {\n ...params.config,\n temperature: getTemperatureWithSemanticRetry({\n temperature: params.config.temperature,\n userTemperature: input.userConfig?.temperature,\n semanticRetryAttempt: input.semanticRetryAttempt,\n }),\n },\n };\n },\n };\n}\n"],"names":["midsceneResponsesDefaults","buildDefaultResponsesParams","midsceneDefaults","userConfig","resolveResponses","responses","buildResponsesParams","input","context","params","getTemperatureWithSemanticRetry"],"mappings":";AAQA,MAAMA,4BAAuD;IAC3D,aAAa;AACf;AAEO,MAAMC,8BAAoD,CAAC,EAChEC,gBAAgB,EAChBC,UAAU,EACX,GAAM;QACL,QAAQ;YACN,aAAaA,WAAW,WAAW,IAAID,iBAAiB,WAAW;QACrE;IACF;AAEO,SAASE,iBACdC,SAA8C;IAE9C,MAAMC,uBACJD,WAAW,wBAAwBJ;IACrC,OAAO;QACL,uBAAuBI,WAAW,yBAAyB,EAAE;QAC7D,sBAAsB,CAACE;YACrB,MAAMC,UAAU;gBACd,GAAGD,KAAK;gBACR,YAAYA,MAAM,UAAU,IAAI,CAAC;gBACjC,kBAAkBP;YACpB;YACA,MAAMS,SAASH,qBAAqBE;YACpC,OAAO;gBACL,GAAGC,MAAM;gBACT,QAAQ;oBACN,GAAGA,OAAO,MAAM;oBAChB,aAAaC,gCAAgC;wBAC3C,aAAaD,OAAO,MAAM,CAAC,WAAW;wBACtC,iBAAiBF,MAAM,UAAU,EAAE;wBACnC,sBAAsBA,MAAM,oBAAoB;oBAClD;gBACF;YACF;QACF;IACF;AACF"}
@@ -0,0 +1,7 @@
1
+ function getTemperatureWithSemanticRetry({ temperature, userTemperature, semanticRetryAttempt = 0 }) {
2
+ if (semanticRetryAttempt > 0 && void 0 === userTemperature && 0 === temperature) return 0.2;
3
+ return temperature;
4
+ }
5
+ export { getTemperatureWithSemanticRetry };
6
+
7
+ //# sourceMappingURL=temperature-with-semantic-retry.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-model/model-adapter/temperature-with-semantic-retry.mjs","sources":["../../../../src/ai-model/model-adapter/temperature-with-semantic-retry.ts"],"sourcesContent":["export function getTemperatureWithSemanticRetry<T>({\n temperature,\n userTemperature,\n semanticRetryAttempt = 0,\n}: {\n temperature: T;\n userTemperature?: number;\n semanticRetryAttempt?: number;\n}): T | number {\n // Only perturb the default deterministic request after a semantic parse\n // failure: preserve an explicit user temperature, and avoid adding a\n // temperature to adapters whose normal parameters do not include one.\n if (\n semanticRetryAttempt > 0 &&\n userTemperature === undefined &&\n temperature === 0\n ) {\n return 0.2;\n }\n return temperature;\n}\n"],"names":["getTemperatureWithSemanticRetry","temperature","userTemperature","semanticRetryAttempt","undefined"],"mappings":"AAAO,SAASA,gCAAmC,EACjDC,WAAW,EACXC,eAAe,EACfC,uBAAuB,CAAC,EAKzB;IAIC,IACEA,uBAAuB,KACvBD,AAAoBE,WAApBF,mBACAD,AAAgB,MAAhBA,aAEA,OAAO;IAET,OAAOA;AACT"}
@@ -11,15 +11,54 @@ const resolveGpt6ReasoningEffort = ({ reasoningEnabled, reasoningEffort })=>{
11
11
  const buildGpt5CodexAppServerParams = (input)=>({
12
12
  config: {
13
13
  effort: resolveGpt5ReasoningEffort(input.userConfig ?? {})
14
- },
15
- imageDetail: originalImageDetailForDefaultIntent(input)
14
+ }
16
15
  });
17
16
  const buildGpt6CodexAppServerParams = (input)=>({
18
17
  config: {
19
18
  effort: resolveGpt6ReasoningEffort(input.userConfig ?? {})
20
- },
21
- imageDetail: originalImageDetailForDefaultIntent(input)
19
+ }
22
20
  });
21
+ const buildGpt5ResponsesParams = (input)=>{
22
+ const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;
23
+ const commonOverrideConfig = {};
24
+ if (void 0 !== userConfig.temperature) commonOverrideConfig.temperature = userConfig.temperature;
25
+ if ('none' !== userConfig.responseFormat && expectedJsonObjectResponse) commonOverrideConfig.text = {
26
+ format: {
27
+ type: 'json_object'
28
+ }
29
+ };
30
+ const effectiveReasoningEffort = resolveGpt5ReasoningEffort(userConfig);
31
+ return {
32
+ config: {
33
+ ...midsceneDefaults,
34
+ ...commonOverrideConfig,
35
+ reasoning: {
36
+ effort: effectiveReasoningEffort
37
+ }
38
+ }
39
+ };
40
+ };
41
+ const buildGpt6ResponsesParams = (input)=>{
42
+ const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;
43
+ const { responseFormat } = userConfig;
44
+ const commonOverrideConfig = {};
45
+ commonOverrideConfig.temperature = void 0;
46
+ if ('none' !== responseFormat && expectedJsonObjectResponse) commonOverrideConfig.text = {
47
+ format: {
48
+ type: 'json_object'
49
+ }
50
+ };
51
+ const effectiveReasoningEffort = resolveGpt6ReasoningEffort(userConfig);
52
+ return {
53
+ config: {
54
+ ...midsceneDefaults,
55
+ ...commonOverrideConfig,
56
+ reasoning: {
57
+ effort: effectiveReasoningEffort
58
+ }
59
+ }
60
+ };
61
+ };
23
62
  const buildGpt5ChatCompletionParams = (input)=>{
24
63
  const { midsceneDefaults, userConfig } = input;
25
64
  const commonOverrideConfig = {};
@@ -55,13 +94,23 @@ const buildGpt6ChatCompletionParams = (input)=>{
55
94
  };
56
95
  const gptAdapters = {
57
96
  'gpt-5': {
97
+ supportedApiTypes: [
98
+ 'chat-completion',
99
+ 'responses'
100
+ ],
101
+ resolveImageDetail: originalImageDetailForDefaultIntent,
102
+ responses: {
103
+ unsupportedUserConfig: [
104
+ 'reasoningBudget'
105
+ ],
106
+ buildResponsesParams: buildGpt5ResponsesParams
107
+ },
58
108
  buildCodexAppServerParams: buildGpt5CodexAppServerParams,
59
109
  chatCompletion: {
60
110
  unsupportedUserConfig: [
61
111
  'reasoningBudget'
62
112
  ],
63
- buildChatCompletionParams: buildGpt5ChatCompletionParams,
64
- resolveImageDetail: originalImageDetailForDefaultIntent
113
+ buildChatCompletionParams: buildGpt5ChatCompletionParams
65
114
  },
66
115
  locate: {
67
116
  element: {
@@ -75,14 +124,25 @@ const gptAdapters = {
75
124
  }
76
125
  },
77
126
  'gpt-6': {
127
+ supportedApiTypes: [
128
+ 'chat-completion',
129
+ 'responses'
130
+ ],
131
+ resolveImageDetail: originalImageDetailForDefaultIntent,
132
+ responses: {
133
+ unsupportedUserConfig: [
134
+ 'temperature',
135
+ 'reasoningBudget'
136
+ ],
137
+ buildResponsesParams: buildGpt6ResponsesParams
138
+ },
78
139
  buildCodexAppServerParams: buildGpt6CodexAppServerParams,
79
140
  chatCompletion: {
80
141
  unsupportedUserConfig: [
81
142
  'temperature',
82
143
  'reasoningBudget'
83
144
  ],
84
- buildChatCompletionParams: buildGpt6ChatCompletionParams,
85
- resolveImageDetail: originalImageDetailForDefaultIntent
145
+ buildChatCompletionParams: buildGpt6ChatCompletionParams
86
146
  },
87
147
  locate: {
88
148
  element: {
@@ -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 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"}
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 BuildResponsesParams,\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n CodexAppServerCallInput,\n CodexAppServerParamsResult,\n ModelAdapterDefinition,\n ReasoningInput,\n ResolveImageDetail,\n} from '../model-adapter/types';\nimport { isLocateIntent } from './utils/intent';\n\nconst originalImageDetailForDefaultIntent: ResolveImageDetail = (input) =>\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});\n\nconst buildGpt6CodexAppServerParams = (\n input: CodexAppServerCallInput,\n): CodexAppServerParamsResult => ({\n config: { effort: resolveGpt6ReasoningEffort(input.userConfig ?? {}) },\n});\n\nconst buildGpt5ResponsesParams: BuildResponsesParams = (input) => {\n const { midsceneDefaults, userConfig, expectedJsonObjectResponse } = input;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n if (userConfig.responseFormat !== 'none' && expectedJsonObjectResponse) {\n commonOverrideConfig.text = { 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 buildGpt6ResponsesParams: BuildResponsesParams = (input) => {\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.text = { 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\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 supportedApiTypes: ['chat-completion', 'responses'],\n resolveImageDetail: originalImageDetailForDefaultIntent,\n responses: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildResponsesParams: buildGpt5ResponsesParams,\n },\n buildCodexAppServerParams: buildGpt5CodexAppServerParams,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildGpt5ChatCompletionParams,\n },\n locate: {\n element: {\n resultFormat: {\n coordinates: { shape: 'bbox', order: 'xy' },\n },\n },\n },\n },\n 'gpt-6': {\n supportedApiTypes: ['chat-completion', 'responses'],\n resolveImageDetail: originalImageDetailForDefaultIntent,\n responses: {\n unsupportedUserConfig: ['temperature', 'reasoningBudget'],\n buildResponsesParams: buildGpt6ResponsesParams,\n },\n buildCodexAppServerParams: buildGpt6CodexAppServerParams,\n chatCompletion: {\n unsupportedUserConfig: ['temperature', 'reasoningBudget'],\n buildChatCompletionParams: buildGpt6ChatCompletionParams,\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","buildGpt5ResponsesParams","midsceneDefaults","userConfig","expectedJsonObjectResponse","commonOverrideConfig","effectiveReasoningEffort","buildGpt6ResponsesParams","responseFormat","buildGpt5ChatCompletionParams","buildGpt6ChatCompletionParams","gptAdapters"],"mappings":";AAaA,MAAMA,sCAA0D,CAACC,QAC/DC,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;IACvE;AAEA,MAAMQ,gCAAgC,CACpCR,QACgC;QAChC,QAAQ;YAAE,QAAQM,2BAA2BN,MAAM,UAAU,IAAI,CAAC;QAAG;IACvE;AAEA,MAAMS,2BAAiD,CAACT;IACtD,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAEC,0BAA0B,EAAE,GAAGZ;IACrE,MAAMa,uBAAgD,CAAC;IAEvD,IAAIF,AAA2BT,WAA3BS,WAAW,WAAW,EACxBE,qBAAqB,WAAW,GAAGF,WAAW,WAAW;IAG3D,IAAIA,AAA8B,WAA9BA,WAAW,cAAc,IAAeC,4BAC1CC,qBAAqB,IAAI,GAAG;QAAE,QAAQ;YAAE,MAAM;QAAc;IAAE;IAGhE,MAAMC,2BAA2BX,2BAA2BQ;IAE5D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGG,oBAAoB;YACvB,WAAW;gBAAE,QAAQC;YAAyB;QAChD;IACF;AACF;AAEA,MAAMC,2BAAiD,CAACf;IACtD,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAEC,0BAA0B,EAAE,GAAGZ;IACrE,MAAM,EAAEgB,cAAc,EAAE,GAAGL;IAC3B,MAAME,uBAAgD,CAAC;IAEvDA,qBAAqB,WAAW,GAAGX;IACnC,IAAIc,AAAmB,WAAnBA,kBAA6BJ,4BAC/BC,qBAAqB,IAAI,GAAG;QAAE,QAAQ;YAAE,MAAM;QAAc;IAAE;IAGhE,MAAMC,2BAA2BR,2BAA2BK;IAE5D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGG,oBAAoB;YACvB,WAAW;gBAAE,QAAQC;YAAyB;QAChD;IACF;AACF;AAEA,MAAMG,gCAAgC,CACpCjB;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAE,GAAGX;IACzC,MAAMa,uBAAgD,CAAC;IAEvD,IAAIF,AAA2BT,WAA3BS,WAAW,WAAW,EACxBE,qBAAqB,WAAW,GAAGF,WAAW,WAAW;IAK3D,IACEX,AAAoC,WAApCA,MAAM,UAAU,CAAC,cAAc,IAC/BA,MAAM,0BAA0B,EAEhCa,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAMC,2BAA2BX,2BAA2BQ;IAE5D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGG,oBAAoB;YACvB,kBAAkBC;QACpB;IACF;AACF;AAEA,MAAMI,gCAAgC,CACpClB;IAEA,MAAM,EAAEU,gBAAgB,EAAEC,UAAU,EAAEC,0BAA0B,EAAE,GAAGZ;IACrE,MAAM,EAAEgB,cAAc,EAAE,GAAGL;IAC3B,MAAME,uBAAgD,CAAC;IAEvDA,qBAAqB,WAAW,GAAGX;IACnC,IAAIc,AAAmB,WAAnBA,kBAA6BJ,4BAC/BC,qBAAqB,eAAe,GAAG;QAAE,MAAM;IAAc;IAG/D,MAAMC,2BAA2BR,2BAA2BK;IAE5D,OAAO;QACL,QAAQ;YACN,GAAGD,gBAAgB;YACnB,GAAGG,oBAAoB;YACvB,kBAAkBC;QACpB;IACF;AACF;AAEO,MAAMK,cAAc;IACzB,SAAS;QACP,mBAAmB;YAAC;YAAmB;SAAY;QACnD,oBAAoBpB;QACpB,WAAW;YACT,uBAAuB;gBAAC;aAAkB;YAC1C,sBAAsBU;QACxB;QACA,2BAA2BF;QAC3B,gBAAgB;YACd,uBAAuB;gBAAC;aAAkB;YAC1C,2BAA2BU;QAC7B;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAa;wBAAE,OAAO;wBAAQ,OAAO;oBAAK;gBAC5C;YACF;QACF;IACF;IACA,SAAS;QACP,mBAAmB;YAAC;YAAmB;SAAY;QACnD,oBAAoBlB;QACpB,WAAW;YACT,uBAAuB;gBAAC;gBAAe;aAAkB;YACzD,sBAAsBgB;QACxB;QACA,2BAA2BP;QAC3B,gBAAgB;YACd,uBAAuB;gBAAC;gBAAe;aAAkB;YACzD,2BAA2BU;QAC7B;QACA,QAAQ;YACN,SAAS;gBACP,cAAc;oBACZ,aAAa;wBAAE,OAAO;wBAAQ,OAAO;oBAAK;gBAC5C;YACF;QACF;IACF;AACF"}
@@ -26,8 +26,8 @@ const MODEL_ADAPTER_CONFIGS = {
26
26
  const modelAdapterCache = new Map();
27
27
  const debugModelAdapter = getDebug('ai:model-adapter');
28
28
  function debugAdapterUnsupportedUserConfig(modelFamily, adapter) {
29
- if (0 === adapter.chatCompletion.unsupportedUserConfig.length) return;
30
- debugModelAdapter(`model adapter "${modelFamily}" unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`);
29
+ if (adapter.chatCompletion.unsupportedUserConfig.length > 0) debugModelAdapter(`model adapter "${modelFamily}" (chat-completion) unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`);
30
+ if (adapter.responses.unsupportedUserConfig.length > 0) debugModelAdapter(`model adapter "${modelFamily}" (responses) unsupportedUserConfig: ${JSON.stringify(adapter.responses.unsupportedUserConfig)}`);
31
31
  }
32
32
  function getModelAdapter(modelFamily) {
33
33
  const cacheKey = modelFamily ?? 'default';
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/models/registry.mjs","sources":["../../../../src/ai-model/models/registry.ts"],"sourcesContent":["import type { IModelConfig, TModelFamily } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ResolvedModelAdapter } from '../model-adapter/resolve';\nimport type {\n ModelAdapter,\n ModelAdapterDefinition,\n ModelRuntime,\n} from '../model-adapter/types';\nimport { autoGlmAdapters } from './auto-glm/adapter';\nimport { deepSeekAdapters } from './deepseek/adapter';\nimport { defaultOpenAICompatibleAdapterConfig } from './default';\nimport { doubaoAdapters } from './doubao';\nimport { geminiAdapters } from './gemini';\nimport { glmAdapters } from './glm';\nimport { gptAdapters } from './gpt';\nimport { kimiAdapters } from './kimi';\nimport { mimoAdapters } from './mimo';\nimport { qwenAdapters } from './qwen';\nimport { uiTarsAdapters } from './ui-tars/adapter';\n\nexport const MODEL_ADAPTER_CONFIGS = {\n ...qwenAdapters,\n ...deepSeekAdapters,\n ...doubaoAdapters,\n ...geminiAdapters,\n ...uiTarsAdapters,\n ...glmAdapters,\n ...autoGlmAdapters,\n ...gptAdapters,\n ...kimiAdapters,\n ...mimoAdapters,\n} satisfies Record<TModelFamily, ModelAdapterDefinition>;\n\ntype ModelAdapterCacheKey = TModelFamily | 'default';\n\nconst modelAdapterCache = new Map<ModelAdapterCacheKey, ModelAdapter>();\nconst debugModelAdapter = getDebug('ai:model-adapter');\n\nfunction debugAdapterUnsupportedUserConfig(\n modelFamily: ModelAdapterCacheKey,\n adapter: ModelAdapter,\n): void {\n if (adapter.chatCompletion.unsupportedUserConfig.length === 0) {\n return;\n }\n\n debugModelAdapter(\n `model adapter \"${modelFamily}\" unsupportedUserConfig: ${JSON.stringify(\n adapter.chatCompletion.unsupportedUserConfig,\n )}`,\n );\n}\n\nexport function getModelAdapter(modelFamily?: TModelFamily): ModelAdapter {\n const cacheKey: ModelAdapterCacheKey = modelFamily ?? 'default';\n let adapter = modelAdapterCache.get(cacheKey);\n if (adapter) {\n return adapter;\n }\n\n const config = modelFamily\n ? MODEL_ADAPTER_CONFIGS[modelFamily]\n : defaultOpenAICompatibleAdapterConfig;\n if (!config) {\n throw new Error(\n `No model adapter registered for modelFamily: ${modelFamily}`,\n );\n }\n\n adapter = new ResolvedModelAdapter(config, cacheKey);\n modelAdapterCache.set(cacheKey, adapter);\n debugAdapterUnsupportedUserConfig(cacheKey, adapter);\n\n return adapter;\n}\n\nexport function getModelRuntime(config: IModelConfig): ModelRuntime {\n return {\n config,\n adapter: getModelAdapter(config.modelFamily),\n };\n}\n"],"names":["MODEL_ADAPTER_CONFIGS","qwenAdapters","deepSeekAdapters","doubaoAdapters","geminiAdapters","uiTarsAdapters","glmAdapters","autoGlmAdapters","gptAdapters","kimiAdapters","mimoAdapters","modelAdapterCache","Map","debugModelAdapter","getDebug","debugAdapterUnsupportedUserConfig","modelFamily","adapter","JSON","getModelAdapter","cacheKey","config","defaultOpenAICompatibleAdapterConfig","Error","ResolvedModelAdapter","getModelRuntime"],"mappings":";;;;;;;;;;;;;AAoBO,MAAMA,wBAAwB;IACnC,GAAGC,YAAY;IACf,GAAGC,gBAAgB;IACnB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,WAAW;IACd,GAAGC,eAAe;IAClB,GAAGC,WAAW;IACd,GAAGC,YAAY;IACf,GAAGC,YAAY;AACjB;AAIA,MAAMC,oBAAoB,IAAIC;AAC9B,MAAMC,oBAAoBC,SAAS;AAEnC,SAASC,kCACPC,WAAiC,EACjCC,OAAqB;IAErB,IAAIA,AAAwD,MAAxDA,QAAQ,cAAc,CAAC,qBAAqB,CAAC,MAAM,EACrD;IAGFJ,kBACE,CAAC,eAAe,EAAEG,YAAY,yBAAyB,EAAEE,KAAK,SAAS,CACrED,QAAQ,cAAc,CAAC,qBAAqB,GAC3C;AAEP;AAEO,SAASE,gBAAgBH,WAA0B;IACxD,MAAMI,WAAiCJ,eAAe;IACtD,IAAIC,UAAUN,kBAAkB,GAAG,CAACS;IACpC,IAAIH,SACF,OAAOA;IAGT,MAAMI,SAASL,cACXhB,qBAAqB,CAACgB,YAAY,GAClCM;IACJ,IAAI,CAACD,QACH,MAAM,IAAIE,MACR,CAAC,6CAA6C,EAAEP,aAAa;IAIjEC,UAAU,IAAIO,qBAAqBH,QAAQD;IAC3CT,kBAAkB,GAAG,CAACS,UAAUH;IAChCF,kCAAkCK,UAAUH;IAE5C,OAAOA;AACT;AAEO,SAASQ,gBAAgBJ,MAAoB;IAClD,OAAO;QACLA;QACA,SAASF,gBAAgBE,OAAO,WAAW;IAC7C;AACF"}
1
+ {"version":3,"file":"ai-model/models/registry.mjs","sources":["../../../../src/ai-model/models/registry.ts"],"sourcesContent":["import type { IModelConfig, TModelFamily } from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport { ResolvedModelAdapter } from '../model-adapter/resolve';\nimport type {\n ModelAdapter,\n ModelAdapterDefinition,\n ModelRuntime,\n} from '../model-adapter/types';\nimport { autoGlmAdapters } from './auto-glm/adapter';\nimport { deepSeekAdapters } from './deepseek/adapter';\nimport { defaultOpenAICompatibleAdapterConfig } from './default';\nimport { doubaoAdapters } from './doubao';\nimport { geminiAdapters } from './gemini';\nimport { glmAdapters } from './glm';\nimport { gptAdapters } from './gpt';\nimport { kimiAdapters } from './kimi';\nimport { mimoAdapters } from './mimo';\nimport { qwenAdapters } from './qwen';\nimport { uiTarsAdapters } from './ui-tars/adapter';\n\nexport const MODEL_ADAPTER_CONFIGS = {\n ...qwenAdapters,\n ...deepSeekAdapters,\n ...doubaoAdapters,\n ...geminiAdapters,\n ...uiTarsAdapters,\n ...glmAdapters,\n ...autoGlmAdapters,\n ...gptAdapters,\n ...kimiAdapters,\n ...mimoAdapters,\n} satisfies Record<TModelFamily, ModelAdapterDefinition>;\n\ntype ModelAdapterCacheKey = TModelFamily | 'default';\n\nconst modelAdapterCache = new Map<ModelAdapterCacheKey, ModelAdapter>();\nconst debugModelAdapter = getDebug('ai:model-adapter');\n\nfunction debugAdapterUnsupportedUserConfig(\n modelFamily: ModelAdapterCacheKey,\n adapter: ModelAdapter,\n): void {\n if (adapter.chatCompletion.unsupportedUserConfig.length > 0) {\n debugModelAdapter(\n `model adapter \"${modelFamily}\" (chat-completion) unsupportedUserConfig: ${JSON.stringify(adapter.chatCompletion.unsupportedUserConfig)}`,\n );\n }\n if (adapter.responses.unsupportedUserConfig.length > 0) {\n debugModelAdapter(\n `model adapter \"${modelFamily}\" (responses) unsupportedUserConfig: ${JSON.stringify(adapter.responses.unsupportedUserConfig)}`,\n );\n }\n}\n\nexport function getModelAdapter(modelFamily?: TModelFamily): ModelAdapter {\n const cacheKey: ModelAdapterCacheKey = modelFamily ?? 'default';\n let adapter = modelAdapterCache.get(cacheKey);\n if (adapter) {\n return adapter;\n }\n\n const config = modelFamily\n ? MODEL_ADAPTER_CONFIGS[modelFamily]\n : defaultOpenAICompatibleAdapterConfig;\n if (!config) {\n throw new Error(\n `No model adapter registered for modelFamily: ${modelFamily}`,\n );\n }\n\n adapter = new ResolvedModelAdapter(config, cacheKey);\n modelAdapterCache.set(cacheKey, adapter);\n debugAdapterUnsupportedUserConfig(cacheKey, adapter);\n\n return adapter;\n}\n\nexport function getModelRuntime(config: IModelConfig): ModelRuntime {\n return {\n config,\n adapter: getModelAdapter(config.modelFamily),\n };\n}\n"],"names":["MODEL_ADAPTER_CONFIGS","qwenAdapters","deepSeekAdapters","doubaoAdapters","geminiAdapters","uiTarsAdapters","glmAdapters","autoGlmAdapters","gptAdapters","kimiAdapters","mimoAdapters","modelAdapterCache","Map","debugModelAdapter","getDebug","debugAdapterUnsupportedUserConfig","modelFamily","adapter","JSON","getModelAdapter","cacheKey","config","defaultOpenAICompatibleAdapterConfig","Error","ResolvedModelAdapter","getModelRuntime"],"mappings":";;;;;;;;;;;;;AAoBO,MAAMA,wBAAwB;IACnC,GAAGC,YAAY;IACf,GAAGC,gBAAgB;IACnB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,cAAc;IACjB,GAAGC,WAAW;IACd,GAAGC,eAAe;IAClB,GAAGC,WAAW;IACd,GAAGC,YAAY;IACf,GAAGC,YAAY;AACjB;AAIA,MAAMC,oBAAoB,IAAIC;AAC9B,MAAMC,oBAAoBC,SAAS;AAEnC,SAASC,kCACPC,WAAiC,EACjCC,OAAqB;IAErB,IAAIA,QAAQ,cAAc,CAAC,qBAAqB,CAAC,MAAM,GAAG,GACxDJ,kBACE,CAAC,eAAe,EAAEG,YAAY,2CAA2C,EAAEE,KAAK,SAAS,CAACD,QAAQ,cAAc,CAAC,qBAAqB,GAAG;IAG7I,IAAIA,QAAQ,SAAS,CAAC,qBAAqB,CAAC,MAAM,GAAG,GACnDJ,kBACE,CAAC,eAAe,EAAEG,YAAY,qCAAqC,EAAEE,KAAK,SAAS,CAACD,QAAQ,SAAS,CAAC,qBAAqB,GAAG;AAGpI;AAEO,SAASE,gBAAgBH,WAA0B;IACxD,MAAMI,WAAiCJ,eAAe;IACtD,IAAIC,UAAUN,kBAAkB,GAAG,CAACS;IACpC,IAAIH,SACF,OAAOA;IAGT,MAAMI,SAASL,cACXhB,qBAAqB,CAACgB,YAAY,GAClCM;IACJ,IAAI,CAACD,QACH,MAAM,IAAIE,MACR,CAAC,6CAA6C,EAAEP,aAAa;IAIjEC,UAAU,IAAIO,qBAAqBH,QAAQD;IAC3CT,kBAAkB,GAAG,CAACS,UAAUH;IAChCF,kCAAkCK,UAAUH;IAE5C,OAAOA;AACT;AAEO,SAASQ,gBAAgBJ,MAAoB;IAClD,OAAO;QACLA;QACA,SAASF,gBAAgBE,OAAO,WAAW;IAC7C;AACF"}
@@ -5,6 +5,7 @@ import { isCodexAppServerProvider } from "./codex/codex-app-server.mjs";
5
5
  import { isModelCallRecordingEnabled, recordModelCallEvent } from "./model-call-recorder.mjs";
6
6
  import { callOpenAI } from "./openai/call-openai.mjs";
7
7
  import { prepareChatCompletion } from "./openai/chat-completion/chat-completion.mjs";
8
+ import { prepareResponses } from "./openai/responses/responses.mjs";
8
9
  import { buildRequestAbortSignal, resolveEffectiveTimeoutMs, runWithAbortSignal, waitForRetry } from "./request-timeout.mjs";
9
10
  import { appendAIRequestFailureSummary, buildUsageInfo, nextInternalCallId, normalizeRetryCount, toError } from "./utils.mjs";
10
11
  function _define_property(obj, key, value) {
@@ -17,6 +18,7 @@ function _define_property(obj, key, value) {
17
18
  else obj[key] = value;
18
19
  return obj;
19
20
  }
21
+ const DEFAULT_MODEL_API_TYPE = 'chat-completion';
20
22
  async function callAI(messages, modelRuntime, options) {
21
23
  options?.abortSignal?.throwIfAborted();
22
24
  const isStreaming = options?.stream === true;
@@ -24,21 +26,27 @@ async function callAI(messages, modelRuntime, options) {
24
26
  const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;
25
27
  const internalCallId = nextInternalCallId();
26
28
  const { config: modelConfig } = modelRuntime;
27
- const prepare = async ()=>isCodexAppServerProvider(modelConfig.openaiBaseURL) ? {
29
+ const prepare = async ()=>{
30
+ const input = {
31
+ messages,
32
+ modelRuntime,
33
+ options
34
+ };
35
+ if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) return {
28
36
  protocol: 'codex',
29
- input: prepareCodexCall({
30
- messages,
31
- modelRuntime,
32
- options
33
- })
34
- } : {
37
+ input: prepareCodexCall(input)
38
+ };
39
+ const apiType = modelConfig.apiType ?? DEFAULT_MODEL_API_TYPE;
40
+ assert(modelRuntime.adapter.supportedApiTypes.includes(apiType), `Model adapter "${modelConfig.modelFamily ?? 'default'}" does not support API type "${apiType}"`);
41
+ if ('responses' === apiType) return {
42
+ protocol: 'responses',
43
+ input: await prepareResponses(input)
44
+ };
45
+ return {
35
46
  protocol: 'chat-completion',
36
- input: await prepareChatCompletion({
37
- messages,
38
- modelRuntime,
39
- options
40
- })
47
+ input: await prepareChatCompletion(input)
41
48
  };
49
+ };
42
50
  const prepared = options?.abortSignal ? await runWithAbortSignal(options.abortSignal, prepare) : await prepare();
43
51
  const result = await callModelWithRetry({
44
52
  messages,
@@ -50,6 +58,7 @@ async function callAI(messages, modelRuntime, options) {
50
58
  });
51
59
  const { rawUsage, timeCost, totalTimeCost, retryCount, requestId, responseModelName, ...response } = result;
52
60
  const usage = buildUsageInfo({
61
+ apiType: prepared.protocol,
53
62
  usageData: rawUsage,
54
63
  timeCost,
55
64
  totalTimeCost,
@@ -145,7 +154,7 @@ async function callModelOnce({ messages, modelRuntime, options, executionId, int
145
154
  } : options
146
155
  };
147
156
  try {
148
- return await runWithAbortSignal(requestSignal, ()=>'codex' === prepared.protocol ? callCodex(context, prepared.input) : callOpenAI(context, prepared.input));
157
+ return await runWithAbortSignal(requestSignal, ()=>'codex' === prepared.protocol ? callCodex(context, prepared.input) : callOpenAI(context, prepared));
149
158
  } catch (error) {
150
159
  options?.abortSignal?.throwIfAborted();
151
160
  const lastError = toError(error);
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/call-ai.mjs","sources":["../../../../src/ai-model/service-caller/call-ai.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nexport async function callAI(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n const isStreaming = options?.stream === true;\n if (isStreaming) {\n assert(\n typeof options?.onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n }\n\n // Low-level callers without a TaskRunner still need a stable ID for the\n // lifetime of this model call (including its network retries).\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n\n // Stable internal ID for this call, used by the agent to deduplicate usage\n // across the onUsage callback and the task-dump-based collectUsageMetrics()\n // path when the provider does not return a request_id.\n const internalCallId = nextInternalCallId();\n\n const { config: modelConfig } = modelRuntime;\n\n const prepare = async (): Promise<PreparedModelInput> =>\n isCodexAppServerProvider(modelConfig.openaiBaseURL)\n ? {\n protocol: 'codex',\n input: prepareCodexCall({ messages, modelRuntime, options }),\n }\n : {\n protocol: 'chat-completion',\n input: await prepareChatCompletion({\n messages,\n modelRuntime,\n options,\n }),\n };\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const usage = buildUsageInfo({\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | { protocol: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | {\n protocol: 'chat-completion';\n input: Awaited<ReturnType<typeof prepareChatCompletion>>;\n };\n\ntype ModelCallInput = {\n messages: ChatCompletionMessageParam[];\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', { console: true })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordEvent = isModelCallRecordingEnabled()\n ? (event: Record<string, unknown>) => {\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n messages,\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.protocol === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared.input),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["callAI","messages","modelRuntime","options","isStreaming","assert","executionId","uuid","internalCallId","nextInternalCallId","modelConfig","prepare","isCodexAppServerProvider","prepareCodexCall","prepareChatCompletion","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","usage","buildUsageInfo","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","input","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordEvent","isModelCallRecordingEnabled","event","recordModelCallEvent","undefined","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","callCodex","callOpenAI"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/service-caller/call-ai.mjs","sources":["../../../../src/ai-model/service-caller/call-ai.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport { assert, uuid } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { callCodex, prepareCodexCall } from './codex/call-codex';\nimport { isCodexAppServerProvider } from './codex/codex-app-server';\nimport {\n isModelCallRecordingEnabled,\n recordModelCallEvent,\n} from './model-call-recorder';\nimport { type PreparedOpenAIInput, callOpenAI } from './openai/call-openai';\nimport { prepareChatCompletion } from './openai/chat-completion/chat-completion';\nimport { prepareResponses } from './openai/responses/responses';\nimport {\n buildRequestAbortSignal,\n resolveEffectiveTimeoutMs,\n runWithAbortSignal,\n waitForRetry,\n} from './request-timeout';\nimport type {\n AICallResult,\n CallAIOptions,\n ModelCallContext,\n ModelCallResult,\n} from './types';\nimport {\n appendAIRequestFailureSummary,\n buildUsageInfo,\n nextInternalCallId,\n normalizeRetryCount,\n toError,\n} from './utils';\n\nconst DEFAULT_MODEL_API_TYPE = 'chat-completion';\n\nexport async function callAI(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: CallAIOptions,\n): Promise<AICallResult> {\n options?.abortSignal?.throwIfAborted();\n const isStreaming = options?.stream === true;\n if (isStreaming) {\n assert(\n typeof options?.onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n }\n\n // Low-level callers without a TaskRunner still need a stable ID for the\n // lifetime of this model call (including its network retries).\n const executionId = modelRuntime.executionId ?? `unscoped-${uuid()}`;\n\n // Stable internal ID for this call, used by the agent to deduplicate usage\n // across the onUsage callback and the task-dump-based collectUsageMetrics()\n // path when the provider does not return a request_id.\n const internalCallId = nextInternalCallId();\n\n const { config: modelConfig } = modelRuntime;\n\n const prepare = async (): Promise<PreparedModelInput> => {\n const input = { messages, modelRuntime, options };\n if (isCodexAppServerProvider(modelConfig.openaiBaseURL)) {\n return { protocol: 'codex', input: prepareCodexCall(input) };\n }\n const apiType = modelConfig.apiType ?? DEFAULT_MODEL_API_TYPE;\n\n assert(\n modelRuntime.adapter.supportedApiTypes.includes(apiType),\n `Model adapter \"${modelConfig.modelFamily ?? 'default'}\" does not support API type \"${apiType}\"`,\n );\n if (apiType === 'responses') {\n return { protocol: 'responses', input: await prepareResponses(input) };\n }\n return {\n protocol: 'chat-completion',\n input: await prepareChatCompletion(input),\n };\n };\n\n const prepared = options?.abortSignal\n ? await runWithAbortSignal(options.abortSignal, prepare)\n : await prepare();\n\n const result = await callModelWithRetry({\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n });\n\n const {\n rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n ...response\n } = result;\n\n const usage = buildUsageInfo({\n apiType: prepared.protocol,\n usageData: rawUsage,\n timeCost,\n totalTimeCost,\n retryCount,\n requestId,\n responseModelName,\n modelName: modelConfig.modelName,\n modelDescription: modelConfig.modelDescription,\n slot: modelConfig.slot,\n internalCallId,\n });\n\n const debugProfileStats = getDebug('ai:profile:stats');\n const debugProfileDetail = getDebug('ai:profile:detail');\n debugProfileStats(\n `model, ${modelConfig.modelName}, mode, ${modelConfig.modelFamily || 'default'}, streaming, ${response.isStreamed}, prompt-tokens, ${usage?.prompt_tokens ?? ''}, completion-tokens, ${usage?.completion_tokens ?? ''}, total-tokens, ${usage?.total_tokens ?? ''}, cached-input, ${usage?.cached_input ?? ''}, cost-ms, ${timeCost ?? ''}, requestId, ${requestId ?? ''}, slot, ${modelConfig.slot}, configured-temperature, ${modelConfig.temperature ?? ''}`,\n );\n debugProfileDetail(`model usage detail: ${JSON.stringify(usage)}`);\n\n if (usage && modelRuntime.onUsage) {\n modelRuntime.onUsage(usage);\n }\n return { ...response, usage };\n}\n\ntype PreparedModelInput =\n | { protocol: 'codex'; input: ReturnType<typeof prepareCodexCall> }\n | PreparedOpenAIInput;\n\ntype ModelCallInput = {\n messages: ChatCompletionMessageParam[];\n modelRuntime: ModelRuntime;\n options?: CallAIOptions;\n executionId: string;\n internalCallId: string;\n prepared: PreparedModelInput;\n};\n\n/** Carries the original failure across the retry boundary without replaying output. */\nclass NonRetryableModelCallError extends Error {\n readonly cause: Error;\n\n constructor(cause: Error) {\n super(cause.message, { cause });\n this.cause = cause;\n }\n}\n\nasync function callModelWithRetry(\n input: ModelCallInput,\n): Promise<ModelCallResult & { totalTimeCost: number; retryCount: number }> {\n const startTime = Date.now();\n const {\n modelRuntime: { config },\n options,\n } = input;\n const maxAttempts = normalizeRetryCount(config.retryCount) + 1;\n const retryInterval = config.retryInterval ?? 2000;\n const attemptErrors: Array<{ attempt: number; error: unknown }> = [];\n\n for (let attempt = 1; ; attempt++) {\n options?.abortSignal?.throwIfAborted();\n try {\n const result = await callModelOnce(input, attempt);\n return {\n ...result,\n totalTimeCost: Date.now() - startTime,\n retryCount: attempt - 1,\n };\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n if (error instanceof NonRetryableModelCallError) {\n throw error.cause;\n }\n const lastError = toError(error);\n attemptErrors.push({ attempt, error: lastError });\n if (attempt === maxAttempts) {\n throw appendAIRequestFailureSummary(\n lastError,\n attemptErrors,\n maxAttempts,\n );\n }\n getDebug('ai:call', { console: true })(\n `AI call failed (attempt ${attempt}/${maxAttempts}), retrying in ${retryInterval}ms... Error: ${lastError.message}`,\n );\n }\n await waitForRetry(retryInterval, options?.abortSignal);\n }\n}\n\nasync function callModelOnce(\n {\n messages,\n modelRuntime,\n options,\n executionId,\n internalCallId,\n prepared,\n }: ModelCallInput,\n attempt: number,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const recordEvent = isModelCallRecordingEnabled()\n ? (event: Record<string, unknown>) => {\n void recordModelCallEvent({\n executionId,\n callId: internalCallId,\n semanticRetryAttempt: options?.semanticRetryAttempt,\n slot: modelConfig.slot,\n intent: modelConfig.intent,\n modelFamily: modelConfig.modelFamily,\n ...event,\n attempt,\n });\n }\n : undefined;\n const effectiveTimeoutMs = resolveEffectiveTimeoutMs(modelConfig.timeout);\n const { signal: requestSignal, cleanup } = buildRequestAbortSignal(\n effectiveTimeoutMs,\n options?.abortSignal,\n );\n let deliveredChunk = false;\n const onChunk = options?.onChunk;\n const context: ModelCallContext = {\n messages,\n modelRuntime,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n options: onChunk\n ? {\n ...options,\n onChunk: (chunk) => {\n requestSignal.throwIfAborted();\n deliveredChunk = true;\n onChunk(chunk);\n },\n }\n : options,\n };\n try {\n return await runWithAbortSignal(requestSignal, () =>\n prepared.protocol === 'codex'\n ? callCodex(context, prepared.input)\n : callOpenAI(context, prepared),\n );\n } catch (error) {\n options?.abortSignal?.throwIfAborted();\n const lastError = toError(error);\n if (deliveredChunk) {\n throw new NonRetryableModelCallError(lastError);\n }\n throw lastError;\n } finally {\n cleanup();\n }\n}\n"],"names":["DEFAULT_MODEL_API_TYPE","callAI","messages","modelRuntime","options","isStreaming","assert","executionId","uuid","internalCallId","nextInternalCallId","modelConfig","prepare","input","isCodexAppServerProvider","prepareCodexCall","apiType","prepareResponses","prepareChatCompletion","prepared","runWithAbortSignal","result","callModelWithRetry","rawUsage","timeCost","totalTimeCost","retryCount","requestId","responseModelName","response","usage","buildUsageInfo","debugProfileStats","getDebug","debugProfileDetail","JSON","NonRetryableModelCallError","Error","cause","startTime","Date","config","maxAttempts","normalizeRetryCount","retryInterval","attemptErrors","attempt","callModelOnce","error","lastError","toError","appendAIRequestFailureSummary","waitForRetry","recordEvent","isModelCallRecordingEnabled","event","recordModelCallEvent","undefined","effectiveTimeoutMs","resolveEffectiveTimeoutMs","requestSignal","cleanup","buildRequestAbortSignal","deliveredChunk","onChunk","context","chunk","callCodex","callOpenAI"],"mappings":"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"}
@@ -2,7 +2,7 @@ import { applyImageDetail } from "../utils.mjs";
2
2
  import { callAIWithCodexAppServer } from "./codex-app-server.mjs";
3
3
  const prepareCodexCall = ({ messages, modelRuntime, options })=>{
4
4
  const { config: modelConfig, adapter } = modelRuntime;
5
- const { config, imageDetail } = adapter.buildCodexAppServerParams({
5
+ const { config } = adapter.buildCodexAppServerParams({
6
6
  intent: modelConfig.intent,
7
7
  userConfig: {
8
8
  reasoningEnabled: modelConfig.reasoningEnabled,
@@ -11,6 +11,10 @@ const prepareCodexCall = ({ messages, modelRuntime, options })=>{
11
11
  },
12
12
  requiresOriginalImageDetail: options?.requiresOriginalImageDetail
13
13
  });
14
+ const imageDetail = adapter.resolveImageDetail({
15
+ intent: modelConfig.intent,
16
+ requiresOriginalImageDetail: options?.requiresOriginalImageDetail
17
+ });
14
18
  const messagesWithImageDetail = applyImageDetail({
15
19
  imageDetail,
16
20
  messages
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/codex/call-codex.mjs","sources":["../../../../../src/ai-model/service-caller/codex/call-codex.ts"],"sourcesContent":["import type { ModelCallContext, ModelCallResult } from '../types';\nimport { applyImageDetail } from '../utils';\nimport {\n type CodexAppServerRecordEvent,\n callAIWithCodexAppServer,\n} from './codex-app-server';\n\nexport const prepareCodexCall = ({\n messages,\n modelRuntime,\n options,\n}: Pick<ModelCallContext, 'messages' | 'modelRuntime' | 'options'>) => {\n const { config: modelConfig, adapter } = modelRuntime;\n const { config, imageDetail } = adapter.buildCodexAppServerParams({\n intent: modelConfig.intent,\n userConfig: {\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n },\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n const messagesWithImageDetail = applyImageDetail({ imageDetail, messages });\n return { messages: messagesWithImageDetail, requestParams: config };\n};\n\nexport const callCodex = async (\n { modelRuntime, options, recordEvent, requestSignal }: ModelCallContext,\n { messages, requestParams }: ReturnType<typeof prepareCodexCall>,\n): Promise<ModelCallResult> => {\n const { config: modelConfig } = modelRuntime;\n let protocolChunkSequence = 0;\n const codexStartTime = Date.now();\n const recordCodexEvent = recordEvent\n ? (event: CodexAppServerRecordEvent) => {\n if (event.type === 'chunk') {\n protocolChunkSequence += 1;\n recordEvent({\n ...event,\n attempt: 1,\n sequence: protocolChunkSequence,\n provider: 'codex-app-server',\n });\n return;\n }\n\n recordEvent({\n ...event,\n attempt: 1,\n provider: 'codex-app-server',\n });\n }\n : undefined;\n\n try {\n const codexResult = await callAIWithCodexAppServer(messages, modelConfig, {\n stream: options?.stream,\n onChunk: options?.onChunk,\n params: requestParams,\n abortSignal: requestSignal,\n onRecordEvent: recordCodexEvent,\n });\n requestSignal.throwIfAborted();\n const { protocolMetadata, usage: rawUsage, ...response } = codexResult;\n const timeCost = Date.now() - codexStartTime;\n recordEvent?.({\n type: 'response',\n attempt: 1,\n provider: 'codex-app-server',\n final: {\n content: response.content,\n reasoningContent: response.reasoning_content,\n usage: rawUsage,\n timeCost,\n protocol: protocolMetadata,\n },\n });\n return {\n ...response,\n rawUsage,\n timeCost,\n requestId: protocolMetadata.turnId,\n };\n } catch (error) {\n recordEvent?.({\n type: 'error',\n attempt: 1,\n provider: 'codex-app-server',\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : String(error),\n });\n throw error;\n }\n};\n"],"names":["prepareCodexCall","messages","modelRuntime","options","modelConfig","adapter","config","imageDetail","messagesWithImageDetail","applyImageDetail","callCodex","recordEvent","requestSignal","requestParams","protocolChunkSequence","codexStartTime","Date","recordCodexEvent","event","undefined","codexResult","callAIWithCodexAppServer","protocolMetadata","rawUsage","response","timeCost","error","Error","String"],"mappings":";;AAOO,MAAMA,mBAAmB,CAAC,EAC/BC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACyD;IAChE,MAAM,EAAE,QAAQC,WAAW,EAAEC,OAAO,EAAE,GAAGH;IACzC,MAAM,EAAEI,MAAM,EAAEC,WAAW,EAAE,GAAGF,QAAQ,yBAAyB,CAAC;QAChE,QAAQD,YAAY,MAAM;QAC1B,YAAY;YACV,kBAAkBA,YAAY,gBAAgB;YAC9C,iBAAiBA,YAAY,eAAe;YAC5C,iBAAiBA,YAAY,eAAe;QAC9C;QACA,6BAA6BD,SAAS;IACxC;IACA,MAAMK,0BAA0BC,iBAAiB;QAAEF;QAAaN;IAAS;IACzE,OAAO;QAAE,UAAUO;QAAyB,eAAeF;IAAO;AACpE;AAEO,MAAMI,YAAY,OACvB,EAAER,YAAY,EAAEC,OAAO,EAAEQ,WAAW,EAAEC,aAAa,EAAoB,EACvE,EAAEX,QAAQ,EAAEY,aAAa,EAAuC;IAEhE,MAAM,EAAE,QAAQT,WAAW,EAAE,GAAGF;IAChC,IAAIY,wBAAwB;IAC5B,MAAMC,iBAAiBC,KAAK,GAAG;IAC/B,MAAMC,mBAAmBN,cACrB,CAACO;QACC,IAAIA,AAAe,YAAfA,MAAM,IAAI,EAAc;YAC1BJ,yBAAyB;YACzBH,YAAY;gBACV,GAAGO,KAAK;gBACR,SAAS;gBACT,UAAUJ;gBACV,UAAU;YACZ;YACA;QACF;QAEAH,YAAY;YACV,GAAGO,KAAK;YACR,SAAS;YACT,UAAU;QACZ;IACF,IACAC;IAEJ,IAAI;QACF,MAAMC,cAAc,MAAMC,yBAAyBpB,UAAUG,aAAa;YACxE,QAAQD,SAAS;YACjB,SAASA,SAAS;YAClB,QAAQU;YACR,aAAaD;YACb,eAAeK;QACjB;QACAL,cAAc,cAAc;QAC5B,MAAM,EAAEU,gBAAgB,EAAE,OAAOC,QAAQ,EAAE,GAAGC,UAAU,GAAGJ;QAC3D,MAAMK,WAAWT,KAAK,GAAG,KAAKD;QAC9BJ,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OAAO;gBACL,SAASa,SAAS,OAAO;gBACzB,kBAAkBA,SAAS,iBAAiB;gBAC5C,OAAOD;gBACPE;gBACA,UAAUH;YACZ;QACF;QACA,OAAO;YACL,GAAGE,QAAQ;YACXD;YACAE;YACA,WAAWH,iBAAiB,MAAM;QACpC;IACF,EAAE,OAAOI,OAAO;QACdf,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OACEe,iBAAiBC,QACb;gBACE,MAAMD,MAAM,IAAI;gBAChB,SAASA,MAAM,OAAO;gBACtB,OAAOA,MAAM,KAAK;YACpB,IACAE,OAAOF;QACf;QACA,MAAMA;IACR;AACF"}
1
+ {"version":3,"file":"ai-model/service-caller/codex/call-codex.mjs","sources":["../../../../../src/ai-model/service-caller/codex/call-codex.ts"],"sourcesContent":["import type { ModelCallContext, ModelCallResult } from '../types';\nimport { applyImageDetail } from '../utils';\nimport {\n type CodexAppServerRecordEvent,\n callAIWithCodexAppServer,\n} from './codex-app-server';\n\nexport const prepareCodexCall = ({\n messages,\n modelRuntime,\n options,\n}: Pick<ModelCallContext, 'messages' | 'modelRuntime' | 'options'>) => {\n const { config: modelConfig, adapter } = modelRuntime;\n const { config } = adapter.buildCodexAppServerParams({\n intent: modelConfig.intent,\n userConfig: {\n reasoningEnabled: modelConfig.reasoningEnabled,\n reasoningEffort: modelConfig.reasoningEffort,\n reasoningBudget: modelConfig.reasoningBudget,\n },\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n const imageDetail = adapter.resolveImageDetail({\n intent: modelConfig.intent,\n requiresOriginalImageDetail: options?.requiresOriginalImageDetail,\n });\n const messagesWithImageDetail = applyImageDetail({ imageDetail, messages });\n return { messages: messagesWithImageDetail, requestParams: config };\n};\n\nexport const callCodex = async (\n { modelRuntime, options, recordEvent, requestSignal }: ModelCallContext,\n { messages, requestParams }: ReturnType<typeof prepareCodexCall>,\n): Promise<ModelCallResult> => {\n const { config: modelConfig } = modelRuntime;\n let protocolChunkSequence = 0;\n const codexStartTime = Date.now();\n const recordCodexEvent = recordEvent\n ? (event: CodexAppServerRecordEvent) => {\n if (event.type === 'chunk') {\n protocolChunkSequence += 1;\n recordEvent({\n ...event,\n attempt: 1,\n sequence: protocolChunkSequence,\n provider: 'codex-app-server',\n });\n return;\n }\n\n recordEvent({\n ...event,\n attempt: 1,\n provider: 'codex-app-server',\n });\n }\n : undefined;\n\n try {\n const codexResult = await callAIWithCodexAppServer(messages, modelConfig, {\n stream: options?.stream,\n onChunk: options?.onChunk,\n params: requestParams,\n abortSignal: requestSignal,\n onRecordEvent: recordCodexEvent,\n });\n requestSignal.throwIfAborted();\n const { protocolMetadata, usage: rawUsage, ...response } = codexResult;\n const timeCost = Date.now() - codexStartTime;\n recordEvent?.({\n type: 'response',\n attempt: 1,\n provider: 'codex-app-server',\n final: {\n content: response.content,\n reasoningContent: response.reasoning_content,\n usage: rawUsage,\n timeCost,\n protocol: protocolMetadata,\n },\n });\n return {\n ...response,\n rawUsage,\n timeCost,\n requestId: protocolMetadata.turnId,\n };\n } catch (error) {\n recordEvent?.({\n type: 'error',\n attempt: 1,\n provider: 'codex-app-server',\n error:\n error instanceof Error\n ? {\n name: error.name,\n message: error.message,\n stack: error.stack,\n }\n : String(error),\n });\n throw error;\n }\n};\n"],"names":["prepareCodexCall","messages","modelRuntime","options","modelConfig","adapter","config","imageDetail","messagesWithImageDetail","applyImageDetail","callCodex","recordEvent","requestSignal","requestParams","protocolChunkSequence","codexStartTime","Date","recordCodexEvent","event","undefined","codexResult","callAIWithCodexAppServer","protocolMetadata","rawUsage","response","timeCost","error","Error","String"],"mappings":";;AAOO,MAAMA,mBAAmB,CAAC,EAC/BC,QAAQ,EACRC,YAAY,EACZC,OAAO,EACyD;IAChE,MAAM,EAAE,QAAQC,WAAW,EAAEC,OAAO,EAAE,GAAGH;IACzC,MAAM,EAAEI,MAAM,EAAE,GAAGD,QAAQ,yBAAyB,CAAC;QACnD,QAAQD,YAAY,MAAM;QAC1B,YAAY;YACV,kBAAkBA,YAAY,gBAAgB;YAC9C,iBAAiBA,YAAY,eAAe;YAC5C,iBAAiBA,YAAY,eAAe;QAC9C;QACA,6BAA6BD,SAAS;IACxC;IACA,MAAMI,cAAcF,QAAQ,kBAAkB,CAAC;QAC7C,QAAQD,YAAY,MAAM;QAC1B,6BAA6BD,SAAS;IACxC;IACA,MAAMK,0BAA0BC,iBAAiB;QAAEF;QAAaN;IAAS;IACzE,OAAO;QAAE,UAAUO;QAAyB,eAAeF;IAAO;AACpE;AAEO,MAAMI,YAAY,OACvB,EAAER,YAAY,EAAEC,OAAO,EAAEQ,WAAW,EAAEC,aAAa,EAAoB,EACvE,EAAEX,QAAQ,EAAEY,aAAa,EAAuC;IAEhE,MAAM,EAAE,QAAQT,WAAW,EAAE,GAAGF;IAChC,IAAIY,wBAAwB;IAC5B,MAAMC,iBAAiBC,KAAK,GAAG;IAC/B,MAAMC,mBAAmBN,cACrB,CAACO;QACC,IAAIA,AAAe,YAAfA,MAAM,IAAI,EAAc;YAC1BJ,yBAAyB;YACzBH,YAAY;gBACV,GAAGO,KAAK;gBACR,SAAS;gBACT,UAAUJ;gBACV,UAAU;YACZ;YACA;QACF;QAEAH,YAAY;YACV,GAAGO,KAAK;YACR,SAAS;YACT,UAAU;QACZ;IACF,IACAC;IAEJ,IAAI;QACF,MAAMC,cAAc,MAAMC,yBAAyBpB,UAAUG,aAAa;YACxE,QAAQD,SAAS;YACjB,SAASA,SAAS;YAClB,QAAQU;YACR,aAAaD;YACb,eAAeK;QACjB;QACAL,cAAc,cAAc;QAC5B,MAAM,EAAEU,gBAAgB,EAAE,OAAOC,QAAQ,EAAE,GAAGC,UAAU,GAAGJ;QAC3D,MAAMK,WAAWT,KAAK,GAAG,KAAKD;QAC9BJ,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OAAO;gBACL,SAASa,SAAS,OAAO;gBACzB,kBAAkBA,SAAS,iBAAiB;gBAC5C,OAAOD;gBACPE;gBACA,UAAUH;YACZ;QACF;QACA,OAAO;YACL,GAAGE,QAAQ;YACXD;YACAE;YACA,WAAWH,iBAAiB,MAAM;QACpC;IACF,EAAE,OAAOI,OAAO;QACdf,cAAc;YACZ,MAAM;YACN,SAAS;YACT,UAAU;YACV,OACEe,iBAAiBC,QACb;gBACE,MAAMD,MAAM,IAAI;gBAChB,SAASA,MAAM,OAAO;gBACtB,OAAOA,MAAM,KAAK;YACpB,IACAE,OAAOF;QACf;QACA,MAAMA;IACR;AACF"}
@@ -1,6 +1,5 @@
1
1
  import { callAIWithObjectResponse, callAIWithStringResponse, parseAIObjectResponse } from "./model-call.mjs";
2
2
  import { callAI } from "./call-ai.mjs";
3
- import { createChatClient } from "./openai/openai-client.mjs";
4
3
  import { AIResponseParseError, INTERNAL_CALL_ID_FIELD } from "./utils.mjs";
5
4
  import { extractJSONFromCodeBlock, parseModelResponseJson } from "../shared/json.mjs";
6
- export { AIResponseParseError, INTERNAL_CALL_ID_FIELD, callAI, callAIWithObjectResponse, callAIWithStringResponse, createChatClient, extractJSONFromCodeBlock, parseAIObjectResponse, parseModelResponseJson };
5
+ export { AIResponseParseError, INTERNAL_CALL_ID_FIELD, callAI, callAIWithObjectResponse, callAIWithStringResponse, extractJSONFromCodeBlock, parseAIObjectResponse, parseModelResponseJson };
@@ -15,7 +15,7 @@ function parseAIObjectResponse(response, modelRuntime, jsonParserSource = 'gener
15
15
  contentString: response.content,
16
16
  usage: response.usage,
17
17
  reasoning_content: response.reasoning_content,
18
- rawChoiceMessage: response.rawChoiceMessage
18
+ rawAssistantOutput: response.rawAssistantOutput
19
19
  };
20
20
  }
21
21
  async function callAIWithObjectResponse(messages, modelRuntime, options) {
@@ -29,7 +29,7 @@ async function callAIWithObjectResponse(messages, modelRuntime, options) {
29
29
  parseResponse: (response)=>parseAIObjectResponse(response, modelRuntime, options?.jsonParserSource),
30
30
  toParseError: (error, response)=>{
31
31
  const errorMessage = error instanceof Error ? error.message : String(error);
32
- return new AIResponseParseError(errorMessage, response.content, response.usage, response.rawChoiceMessage, response.reasoning_content);
32
+ return new AIResponseParseError(errorMessage, response.content, response.usage, response.rawAssistantOutput, response.reasoning_content);
33
33
  },
34
34
  parseRetryTimes: options?.retryTimes ?? modelConfig.retryCount,
35
35
  parseRetryInterval: options?.retryInterval ?? modelConfig.retryInterval,
@@ -37,11 +37,11 @@ async function callAIWithObjectResponse(messages, modelRuntime, options) {
37
37
  });
38
38
  }
39
39
  async function callAIWithStringResponse(msgs, modelRuntime, options) {
40
- const { content, usage, rawChoiceMessage } = await callAI(msgs, modelRuntime, options);
40
+ const { content, usage, rawAssistantOutput } = await callAI(msgs, modelRuntime, options);
41
41
  return {
42
42
  content,
43
43
  usage,
44
- rawChoiceMessage
44
+ rawAssistantOutput
45
45
  };
46
46
  }
47
47
  export { callAIWithObjectResponse, callAIWithStringResponse, parseAIObjectResponse };
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/model-call.mjs","sources":["../../../../src/ai-model/service-caller/model-call.ts"],"sourcesContent":["import type { AIUsageInfo } from '@/types';\nimport { assert } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { type JsonParserSource, assertJsonObject } from '../shared/json';\nimport { callAI } from './call-ai';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from './semantic-retry';\nimport type { CallAIOptions } from './types';\nimport type { AIArgs } from './types';\nimport { AIResponseParseError } from './utils';\n\nexport type AIObjectResponse<T> = {\n // TODO: `content` is a misleading name here because this is already the parsed object response. Consider renaming it to `object` or `data`.\n content: T;\n contentString: string;\n usage?: AIUsageInfo;\n reasoning_content?: string;\n rawChoiceMessage?: unknown;\n};\n\nexport function parseAIObjectResponse<T>(\n response: Awaited<ReturnType<typeof callAI>>,\n modelRuntime: ModelRuntime,\n jsonParserSource: JsonParserSource = 'generic-object',\n): AIObjectResponse<T> {\n const { adapter } = modelRuntime;\n assert(response, 'empty response');\n const jsonContent = adapter.jsonParser(response.content, {\n source: jsonParserSource,\n });\n assertJsonObject(jsonContent);\n return {\n content: jsonContent as T,\n contentString: response.content,\n usage: response.usage,\n reasoning_content: response.reasoning_content,\n rawChoiceMessage: response.rawChoiceMessage,\n };\n}\n\nexport async function callAIWithObjectResponse<T>(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: {\n abortSignal?: AbortSignal;\n jsonParserSource?: JsonParserSource;\n retryTimes?: number;\n retryInterval?: number;\n },\n): Promise<AIObjectResponse<T>> {\n const { config: modelConfig } = modelRuntime;\n return callAiAndParseWithRetry({\n callAi: (retryAttempt, previousParseError) =>\n callAI(\n withSemanticRetryFeedback(messages, previousParseError),\n modelRuntime,\n {\n abortSignal: options?.abortSignal,\n expectedJsonObjectResponse: true,\n semanticRetryAttempt: retryAttempt,\n },\n ),\n parseResponse: (response) =>\n parseAIObjectResponse<T>(\n response,\n modelRuntime,\n options?.jsonParserSource,\n ),\n toParseError: (error, response) => {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return new AIResponseParseError(\n errorMessage,\n response.content,\n response.usage,\n response.rawChoiceMessage,\n response.reasoning_content,\n );\n },\n parseRetryTimes: options?.retryTimes ?? modelConfig.retryCount,\n parseRetryInterval: options?.retryInterval ?? modelConfig.retryInterval,\n abortSignal: options?.abortSignal,\n });\n}\n\nexport async function callAIWithStringResponse(\n msgs: AIArgs,\n modelRuntime: ModelRuntime,\n options?: Pick<CallAIOptions, 'abortSignal' | 'requiresOriginalImageDetail'>,\n): Promise<{\n content: string;\n usage?: AIUsageInfo;\n rawChoiceMessage?: unknown;\n}> {\n const { content, usage, rawChoiceMessage } = await callAI(\n msgs,\n modelRuntime,\n options,\n );\n return { content, usage, rawChoiceMessage };\n}\n"],"names":["parseAIObjectResponse","response","modelRuntime","jsonParserSource","adapter","assert","jsonContent","assertJsonObject","callAIWithObjectResponse","messages","options","modelConfig","callAiAndParseWithRetry","retryAttempt","previousParseError","callAI","withSemanticRetryFeedback","error","errorMessage","Error","String","AIResponseParseError","callAIWithStringResponse","msgs","content","usage","rawChoiceMessage"],"mappings":";;;;;AAuBO,SAASA,sBACdC,QAA4C,EAC5CC,YAA0B,EAC1BC,mBAAqC,gBAAgB;IAErD,MAAM,EAAEC,OAAO,EAAE,GAAGF;IACpBG,OAAOJ,UAAU;IACjB,MAAMK,cAAcF,QAAQ,UAAU,CAACH,SAAS,OAAO,EAAE;QACvD,QAAQE;IACV;IACAI,iBAAiBD;IACjB,OAAO;QACL,SAASA;QACT,eAAeL,SAAS,OAAO;QAC/B,OAAOA,SAAS,KAAK;QACrB,mBAAmBA,SAAS,iBAAiB;QAC7C,kBAAkBA,SAAS,gBAAgB;IAC7C;AACF;AAEO,eAAeO,yBACpBC,QAAsC,EACtCP,YAA0B,EAC1BQ,OAKC;IAED,MAAM,EAAE,QAAQC,WAAW,EAAE,GAAGT;IAChC,OAAOU,wBAAwB;QAC7B,QAAQ,CAACC,cAAcC,qBACrBC,OACEC,0BAA0BP,UAAUK,qBACpCZ,cACA;gBACE,aAAaQ,SAAS;gBACtB,4BAA4B;gBAC5B,sBAAsBG;YACxB;QAEJ,eAAe,CAACZ,WACdD,sBACEC,UACAC,cACAQ,SAAS;QAEb,cAAc,CAACO,OAAOhB;YACpB,MAAMiB,eACJD,iBAAiBE,QAAQF,MAAM,OAAO,GAAGG,OAAOH;YAClD,OAAO,IAAII,qBACTH,cACAjB,SAAS,OAAO,EAChBA,SAAS,KAAK,EACdA,SAAS,gBAAgB,EACzBA,SAAS,iBAAiB;QAE9B;QACA,iBAAiBS,SAAS,cAAcC,YAAY,UAAU;QAC9D,oBAAoBD,SAAS,iBAAiBC,YAAY,aAAa;QACvE,aAAaD,SAAS;IACxB;AACF;AAEO,eAAeY,yBACpBC,IAAY,EACZrB,YAA0B,EAC1BQ,OAA4E;IAM5E,MAAM,EAAEc,OAAO,EAAEC,KAAK,EAAEC,gBAAgB,EAAE,GAAG,MAAMX,OACjDQ,MACArB,cACAQ;IAEF,OAAO;QAAEc;QAASC;QAAOC;IAAiB;AAC5C"}
1
+ {"version":3,"file":"ai-model/service-caller/model-call.mjs","sources":["../../../../src/ai-model/service-caller/model-call.ts"],"sourcesContent":["import type { RawAssistantOutput } from '@/types';\nimport type { AIUsageInfo } from '@/types';\nimport { assert } from '@midscene/shared/utils';\nimport type { ChatCompletionMessageParam } from 'openai/resources/index';\nimport type { ModelRuntime } from '../models';\nimport { type JsonParserSource, assertJsonObject } from '../shared/json';\nimport { callAI } from './call-ai';\nimport {\n callAiAndParseWithRetry,\n withSemanticRetryFeedback,\n} from './semantic-retry';\nimport type { CallAIOptions } from './types';\nimport type { AIArgs } from './types';\nimport { AIResponseParseError } from './utils';\n\nexport type AIObjectResponse<T> = {\n // TODO: `content` is a misleading name here because this is already the parsed object response. Consider renaming it to `object` or `data`.\n content: T;\n contentString: string;\n usage?: AIUsageInfo;\n reasoning_content?: string;\n rawAssistantOutput?: RawAssistantOutput;\n};\n\nexport function parseAIObjectResponse<T>(\n response: Awaited<ReturnType<typeof callAI>>,\n modelRuntime: ModelRuntime,\n jsonParserSource: JsonParserSource = 'generic-object',\n): AIObjectResponse<T> {\n const { adapter } = modelRuntime;\n assert(response, 'empty response');\n const jsonContent = adapter.jsonParser(response.content, {\n source: jsonParserSource,\n });\n assertJsonObject(jsonContent);\n return {\n content: jsonContent as T,\n contentString: response.content,\n usage: response.usage,\n reasoning_content: response.reasoning_content,\n rawAssistantOutput: response.rawAssistantOutput,\n };\n}\n\nexport async function callAIWithObjectResponse<T>(\n messages: ChatCompletionMessageParam[],\n modelRuntime: ModelRuntime,\n options?: {\n abortSignal?: AbortSignal;\n jsonParserSource?: JsonParserSource;\n retryTimes?: number;\n retryInterval?: number;\n },\n): Promise<AIObjectResponse<T>> {\n const { config: modelConfig } = modelRuntime;\n return callAiAndParseWithRetry({\n callAi: (retryAttempt, previousParseError) =>\n callAI(\n withSemanticRetryFeedback(messages, previousParseError),\n modelRuntime,\n {\n abortSignal: options?.abortSignal,\n expectedJsonObjectResponse: true,\n semanticRetryAttempt: retryAttempt,\n },\n ),\n parseResponse: (response) =>\n parseAIObjectResponse<T>(\n response,\n modelRuntime,\n options?.jsonParserSource,\n ),\n toParseError: (error, response) => {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n return new AIResponseParseError(\n errorMessage,\n response.content,\n response.usage,\n response.rawAssistantOutput,\n response.reasoning_content,\n );\n },\n parseRetryTimes: options?.retryTimes ?? modelConfig.retryCount,\n parseRetryInterval: options?.retryInterval ?? modelConfig.retryInterval,\n abortSignal: options?.abortSignal,\n });\n}\n\nexport async function callAIWithStringResponse(\n msgs: AIArgs,\n modelRuntime: ModelRuntime,\n options?: Pick<CallAIOptions, 'abortSignal' | 'requiresOriginalImageDetail'>,\n): Promise<{\n content: string;\n usage?: AIUsageInfo;\n rawAssistantOutput?: RawAssistantOutput;\n}> {\n const { content, usage, rawAssistantOutput } = await callAI(\n msgs,\n modelRuntime,\n options,\n );\n return { content, usage, rawAssistantOutput };\n}\n"],"names":["parseAIObjectResponse","response","modelRuntime","jsonParserSource","adapter","assert","jsonContent","assertJsonObject","callAIWithObjectResponse","messages","options","modelConfig","callAiAndParseWithRetry","retryAttempt","previousParseError","callAI","withSemanticRetryFeedback","error","errorMessage","Error","String","AIResponseParseError","callAIWithStringResponse","msgs","content","usage","rawAssistantOutput"],"mappings":";;;;;AAwBO,SAASA,sBACdC,QAA4C,EAC5CC,YAA0B,EAC1BC,mBAAqC,gBAAgB;IAErD,MAAM,EAAEC,OAAO,EAAE,GAAGF;IACpBG,OAAOJ,UAAU;IACjB,MAAMK,cAAcF,QAAQ,UAAU,CAACH,SAAS,OAAO,EAAE;QACvD,QAAQE;IACV;IACAI,iBAAiBD;IACjB,OAAO;QACL,SAASA;QACT,eAAeL,SAAS,OAAO;QAC/B,OAAOA,SAAS,KAAK;QACrB,mBAAmBA,SAAS,iBAAiB;QAC7C,oBAAoBA,SAAS,kBAAkB;IACjD;AACF;AAEO,eAAeO,yBACpBC,QAAsC,EACtCP,YAA0B,EAC1BQ,OAKC;IAED,MAAM,EAAE,QAAQC,WAAW,EAAE,GAAGT;IAChC,OAAOU,wBAAwB;QAC7B,QAAQ,CAACC,cAAcC,qBACrBC,OACEC,0BAA0BP,UAAUK,qBACpCZ,cACA;gBACE,aAAaQ,SAAS;gBACtB,4BAA4B;gBAC5B,sBAAsBG;YACxB;QAEJ,eAAe,CAACZ,WACdD,sBACEC,UACAC,cACAQ,SAAS;QAEb,cAAc,CAACO,OAAOhB;YACpB,MAAMiB,eACJD,iBAAiBE,QAAQF,MAAM,OAAO,GAAGG,OAAOH;YAClD,OAAO,IAAII,qBACTH,cACAjB,SAAS,OAAO,EAChBA,SAAS,KAAK,EACdA,SAAS,kBAAkB,EAC3BA,SAAS,iBAAiB;QAE9B;QACA,iBAAiBS,SAAS,cAAcC,YAAY,UAAU;QAC9D,oBAAoBD,SAAS,iBAAiBC,YAAY,aAAa;QACvE,aAAaD,SAAS;IACxB;AACF;AAEO,eAAeY,yBACpBC,IAAY,EACZrB,YAA0B,EAC1BQ,OAA4E;IAM5E,MAAM,EAAEc,OAAO,EAAEC,KAAK,EAAEC,kBAAkB,EAAE,GAAG,MAAMX,OACnDQ,MACArB,cACAQ;IAEF,OAAO;QAAEc;QAASC;QAAOC;IAAmB;AAC9C"}