@midscene/core 1.14.0 → 1.15.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 (96) hide show
  1. package/dist/es/agent/action-readiness.mjs +72 -0
  2. package/dist/es/agent/action-readiness.mjs.map +1 -0
  3. package/dist/es/agent/agent.mjs +14 -6
  4. package/dist/es/agent/agent.mjs.map +1 -1
  5. package/dist/es/agent/task-builder.mjs +45 -33
  6. package/dist/es/agent/task-builder.mjs.map +1 -1
  7. package/dist/es/agent/tasks.mjs +9 -2
  8. package/dist/es/agent/tasks.mjs.map +1 -1
  9. package/dist/es/agent/utils.mjs +1 -1
  10. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs +24 -6
  11. package/dist/es/ai-model/connectivity/run-connectivity-test.mjs.map +1 -1
  12. package/dist/es/ai-model/service-caller/call-ai.mjs +10 -3
  13. package/dist/es/ai-model/service-caller/call-ai.mjs.map +1 -1
  14. package/dist/es/ai-model/service-caller/openai/call-openai.mjs +3 -2
  15. package/dist/es/ai-model/service-caller/openai/call-openai.mjs.map +1 -1
  16. package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs +10 -6
  17. package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs.map +1 -1
  18. package/dist/es/ai-model/service-caller/openai/responses/stream.mjs +8 -1
  19. package/dist/es/ai-model/service-caller/openai/responses/stream.mjs.map +1 -1
  20. package/dist/es/ai-model/service-caller/utils.mjs +3 -2
  21. package/dist/es/ai-model/service-caller/utils.mjs.map +1 -1
  22. package/dist/es/device/index.mjs +11 -4
  23. package/dist/es/device/index.mjs.map +1 -1
  24. package/dist/es/index.mjs.map +1 -1
  25. package/dist/es/report-html-template.mjs +1 -1
  26. package/dist/es/types.mjs.map +1 -1
  27. package/dist/es/utils.mjs +1 -1
  28. package/dist/es/yaml/legacy-yaml-runtime.mjs +6 -0
  29. package/dist/es/yaml/legacy-yaml-runtime.mjs.map +1 -1
  30. package/dist/es/yaml/player.mjs +7 -3
  31. package/dist/es/yaml/player.mjs.map +1 -1
  32. package/dist/lib/agent/action-readiness.js +112 -0
  33. package/dist/lib/agent/action-readiness.js.map +1 -0
  34. package/dist/lib/agent/agent.js +13 -5
  35. package/dist/lib/agent/agent.js.map +1 -1
  36. package/dist/lib/agent/task-builder.js +45 -33
  37. package/dist/lib/agent/task-builder.js.map +1 -1
  38. package/dist/lib/agent/tasks.js +9 -2
  39. package/dist/lib/agent/tasks.js.map +1 -1
  40. package/dist/lib/agent/utils.js +1 -1
  41. package/dist/lib/ai-model/connectivity/run-connectivity-test.js +24 -6
  42. package/dist/lib/ai-model/connectivity/run-connectivity-test.js.map +1 -1
  43. package/dist/lib/ai-model/service-caller/call-ai.js +10 -3
  44. package/dist/lib/ai-model/service-caller/call-ai.js.map +1 -1
  45. package/dist/lib/ai-model/service-caller/openai/call-openai.js +3 -2
  46. package/dist/lib/ai-model/service-caller/openai/call-openai.js.map +1 -1
  47. package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js +10 -6
  48. package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js.map +1 -1
  49. package/dist/lib/ai-model/service-caller/openai/responses/stream.js +8 -1
  50. package/dist/lib/ai-model/service-caller/openai/responses/stream.js.map +1 -1
  51. package/dist/lib/ai-model/service-caller/utils.js +3 -2
  52. package/dist/lib/ai-model/service-caller/utils.js.map +1 -1
  53. package/dist/lib/device/index.js +11 -4
  54. package/dist/lib/device/index.js.map +1 -1
  55. package/dist/lib/index.js.map +1 -1
  56. package/dist/lib/report-html-template.js +1 -1
  57. package/dist/lib/types.js.map +1 -1
  58. package/dist/lib/utils.js +1 -1
  59. package/dist/lib/yaml/legacy-yaml-runtime.js +6 -0
  60. package/dist/lib/yaml/legacy-yaml-runtime.js.map +1 -1
  61. package/dist/lib/yaml/player.js +7 -3
  62. package/dist/lib/yaml/player.js.map +1 -1
  63. package/dist/types/agent/action-readiness.d.ts +14 -0
  64. package/dist/types/agent/action-readiness.d.ts.map +1 -0
  65. package/dist/types/agent/agent.d.ts +6 -2
  66. package/dist/types/agent/agent.d.ts.map +1 -1
  67. package/dist/types/agent/index.d.ts +1 -1
  68. package/dist/types/agent/index.d.ts.map +1 -1
  69. package/dist/types/agent/task-builder.d.ts +4 -1
  70. package/dist/types/agent/task-builder.d.ts.map +1 -1
  71. package/dist/types/agent/tasks.d.ts +3 -0
  72. package/dist/types/agent/tasks.d.ts.map +1 -1
  73. package/dist/types/ai-model/connectivity/index.d.ts +1 -1
  74. package/dist/types/ai-model/connectivity/index.d.ts.map +1 -1
  75. package/dist/types/ai-model/connectivity/run-connectivity-test.d.ts +14 -1
  76. package/dist/types/ai-model/connectivity/run-connectivity-test.d.ts.map +1 -1
  77. package/dist/types/ai-model/index.d.ts +1 -1
  78. package/dist/types/ai-model/index.d.ts.map +1 -1
  79. package/dist/types/ai-model/model-adapter/types.d.ts +2 -0
  80. package/dist/types/ai-model/model-adapter/types.d.ts.map +1 -1
  81. package/dist/types/ai-model/service-caller/call-ai.d.ts.map +1 -1
  82. package/dist/types/ai-model/service-caller/openai/call-openai.d.ts.map +1 -1
  83. package/dist/types/ai-model/service-caller/openai/chat-completion/stream.d.ts.map +1 -1
  84. package/dist/types/ai-model/service-caller/openai/responses/stream.d.ts.map +1 -1
  85. package/dist/types/ai-model/service-caller/utils.d.ts +3 -2
  86. package/dist/types/ai-model/service-caller/utils.d.ts.map +1 -1
  87. package/dist/types/device/index.d.ts +7 -1
  88. package/dist/types/device/index.d.ts.map +1 -1
  89. package/dist/types/index.d.ts +1 -1
  90. package/dist/types/index.d.ts.map +1 -1
  91. package/dist/types/types.d.ts +28 -1
  92. package/dist/types/types.d.ts.map +1 -1
  93. package/dist/types/yaml/legacy-yaml-runtime.d.ts.map +1 -1
  94. package/dist/types/yaml/player.d.ts +2 -1
  95. package/dist/types/yaml/player.d.ts.map +1 -1
  96. package/package.json +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/openai/call-openai.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/service-caller/openai/call-openai.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { getDebug } from '@midscene/shared/logger';\nimport type { ModelCallContext, ModelCallResult } from '../types';\nimport { AIResponseParseError } from '../utils';\nimport {\n callChatCompletion,\n type prepareChatCompletion,\n} from './chat-completion/chat-completion';\nimport { createClient } from './openai-client';\nimport { formatOpenAIAPIErrorDetails } from './openai-request-context';\nimport { callResponses, type prepareResponses } from './responses/responses';\n\nexport type PreparedOpenAIInput =\n | {\n protocol: 'chat-completion';\n input: Awaited<ReturnType<typeof prepareChatCompletion>>;\n }\n | {\n protocol: 'responses';\n input: Awaited<ReturnType<typeof prepareResponses>>;\n };\n\nexport async function callOpenAI(\n {\n modelRuntime,\n options,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n }: ModelCallContext,\n prepared: PreparedOpenAIInput,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const { modelName } = modelConfig;\n const { openai, openAIRequestContext } = await createClient({\n modelConfig,\n proxyAgent: prepared.input.proxyAgent,\n effectiveTimeoutMs,\n executionId,\n recordEvent,\n });\n const isStreaming = options?.stream === true;\n const debugCall = getDebug('ai:call');\n debugCall(\n `sending ${isStreaming ? 'streaming ' : ''}request to ${modelName}`,\n );\n const requestOptions = {\n requestSignal,\n openAIRequestContext,\n onChunk: options?.onChunk,\n recordEvent,\n };\n try {\n const startTime = Date.now();\n const response =\n prepared.protocol === 'responses'\n ? await callResponses(\n {\n ...requestOptions,\n responses: openai.responses,\n requestBodyParams: prepared.input.requestParams,\n },\n isStreaming,\n )\n : await callChatCompletion(\n {\n ...requestOptions,\n completion: openai.chat.completions,\n requestBodyParams: prepared.input.requestParams,\n extractContentAndReasoning:\n prepared.input.extractContentAndReasoning,\n useReasoningAsContentFallback:\n prepared.input.useReasoningAsContentFallback,\n },\n isStreaming,\n );\n const { reasoningContent, ...result } = response;\n requestSignal.throwIfAborted();\n const timeCost = Date.now() - startTime;\n debugCall(`response reasoning content: ${reasoningContent}`);\n debugCall(`response content: ${result.content}`);\n recordEvent?.({\n type: 'response',\n http: openAIRequestContext.httpResponse,\n final: {\n content: result.content,\n reasoningContent,\n usage: result.rawUsage,\n requestId: result.requestId,\n timeCost,\n responseModelName: result.responseModelName,\n },\n });\n return {\n ...result,\n reasoning_content: reasoningContent,\n isStreamed: isStreaming,\n timeCost,\n };\n } catch (error: any) {\n // Fetch already records non-2xx responses. Preserve successful HTTP\n // responses too when SDK parsing or completion validation fails.\n if (openAIRequestContext.httpResponse?.ok) {\n recordEvent?.({\n type: 'error',\n ...openAIRequestContext.httpResponse,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n getDebug('ai:call', { console: true })('call AI error', error);\n if (error instanceof AIResponseParseError) {\n throw error;\n }\n throw new Error(\n `failed to call ${isStreaming ? 'streaming ' : ''}AI model service (${modelName}): ${error.message}${formatOpenAIAPIErrorDetails(error, openAIRequestContext)}\\nTrouble shooting: https://midscenejs.com/model-provider.html`,\n { cause: error },\n );\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","callOpenAI","modelRuntime","options","executionId","recordEvent","requestSignal","effectiveTimeoutMs","prepared","modelConfig","modelName","openai","openAIRequestContext","createClient","isStreaming","debugCall","getDebug","requestOptions","startTime","Date","response","callResponses","callChatCompletion","reasoningContent","result","timeCost","error","Error","String","AIResponseParseError","formatOpenAIAPIErrorDetails"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/service-caller/openai/call-openai.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../src/ai-model/service-caller/openai/call-openai.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import {\n MIDSCENE_MODEL_STREAM_MODE,\n globalConfigManager,\n} from '@midscene/shared/env';\nimport { getDebug } from '@midscene/shared/logger';\nimport type { ModelCallContext, ModelCallResult } from '../types';\nimport { AIResponseParseError } from '../utils';\nimport {\n callChatCompletion,\n type prepareChatCompletion,\n} from './chat-completion/chat-completion';\nimport { createClient } from './openai-client';\nimport { formatOpenAIAPIErrorDetails } from './openai-request-context';\nimport { callResponses, type prepareResponses } from './responses/responses';\n\nexport type PreparedOpenAIInput =\n | {\n protocol: 'chat-completion';\n input: Awaited<ReturnType<typeof prepareChatCompletion>>;\n }\n | {\n protocol: 'responses';\n input: Awaited<ReturnType<typeof prepareResponses>>;\n };\n\nexport async function callOpenAI(\n {\n modelRuntime,\n options,\n executionId,\n recordEvent,\n requestSignal,\n effectiveTimeoutMs,\n }: ModelCallContext,\n prepared: PreparedOpenAIInput,\n): Promise<ModelCallResult> {\n const { config: modelConfig } = modelRuntime;\n const { modelName } = modelConfig;\n const isStreaming =\n options?.stream ??\n globalConfigManager.getEnvConfigValue(MIDSCENE_MODEL_STREAM_MODE) ===\n 'stream';\n const { openai, openAIRequestContext } = await createClient({\n modelConfig,\n proxyAgent: prepared.input.proxyAgent,\n effectiveTimeoutMs,\n executionId,\n recordEvent,\n });\n const debugCall = getDebug('ai:call');\n debugCall(\n `sending ${isStreaming ? 'streaming ' : ''}request to ${modelName}`,\n );\n const requestOptions = {\n requestSignal,\n openAIRequestContext,\n onChunk: options?.onChunk ?? (() => undefined),\n recordEvent,\n };\n try {\n const startTime = Date.now();\n const response =\n prepared.protocol === 'responses'\n ? await callResponses(\n {\n ...requestOptions,\n responses: openai.responses,\n requestBodyParams: prepared.input.requestParams,\n },\n isStreaming,\n )\n : await callChatCompletion(\n {\n ...requestOptions,\n completion: openai.chat.completions,\n requestBodyParams: prepared.input.requestParams,\n extractContentAndReasoning:\n prepared.input.extractContentAndReasoning,\n useReasoningAsContentFallback:\n prepared.input.useReasoningAsContentFallback,\n },\n isStreaming,\n );\n const { reasoningContent, ...result } = response;\n requestSignal.throwIfAborted();\n const timeCost = Date.now() - startTime;\n debugCall(`response reasoning content: ${reasoningContent}`);\n debugCall(`response content: ${result.content}`);\n recordEvent?.({\n type: 'response',\n http: openAIRequestContext.httpResponse,\n final: {\n content: result.content,\n reasoningContent,\n usage: result.rawUsage,\n requestId: result.requestId,\n timeCost,\n responseModelName: result.responseModelName,\n },\n });\n return {\n ...result,\n reasoning_content: reasoningContent,\n isStreamed: isStreaming,\n timeCost,\n };\n } catch (error: any) {\n // Fetch already records non-2xx responses. Preserve successful HTTP\n // responses too when SDK parsing or completion validation fails.\n if (openAIRequestContext.httpResponse?.ok) {\n recordEvent?.({\n type: 'error',\n ...openAIRequestContext.httpResponse,\n error: error instanceof Error ? error.message : String(error),\n });\n }\n getDebug('ai:call', { console: true })('call AI error', error);\n if (error instanceof AIResponseParseError) {\n throw error;\n }\n throw new Error(\n `failed to call ${isStreaming ? 'streaming ' : ''}AI model service (${modelName}): ${error.message}${formatOpenAIAPIErrorDetails(error, openAIRequestContext)}\\nTrouble shooting: https://midscenejs.com/model-provider.html`,\n { cause: error },\n );\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","callOpenAI","modelRuntime","options","executionId","recordEvent","requestSignal","effectiveTimeoutMs","prepared","modelConfig","modelName","isStreaming","globalConfigManager","MIDSCENE_MODEL_STREAM_MODE","openai","openAIRequestContext","createClient","debugCall","getDebug","requestOptions","undefined","startTime","Date","response","callResponses","callChatCompletion","reasoningContent","result","timeCost","error","Error","String","AIResponseParseError","formatOpenAIAPIErrorDetails"],"mappings":"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"}
@@ -35,18 +35,15 @@ const callChatCompletionStream = async ({ completion, openAIRequestContext, extr
35
35
  let usage;
36
36
  let responseModelName;
37
37
  requestSignal.throwIfAborted();
38
- const stream = await completion.create({
38
+ const stream = completion.stream({
39
39
  ...requestBodyParams,
40
- stream: true,
41
40
  stream_options: {
42
41
  ...requestBodyParams.stream_options,
43
42
  include_usage: true
44
43
  }
45
44
  }, {
46
- stream: true,
47
45
  signal: requestSignal
48
46
  });
49
- const requestId = stream._request_id ?? openAIRequestContext.responseRequestId?.requestId;
50
47
  let chunkSequence = 0;
51
48
  for await (const chunk of stream){
52
49
  requestSignal.throwIfAborted();
@@ -56,7 +53,8 @@ const callChatCompletionStream = async ({ completion, openAIRequestContext, extr
56
53
  sequence: chunkSequence,
57
54
  chunk
58
55
  });
59
- const parsedChunk = extractContentAndReasoning(chunk.choices?.[0]?.delta);
56
+ const delta = chunk.choices?.[0]?.delta;
57
+ const parsedChunk = extractContentAndReasoning(delta);
60
58
  const content = parsedChunk.content || '';
61
59
  const reasoning_content = parsedChunk.reasoning_content || '';
62
60
  if (chunk.usage) usage = chunk.usage;
@@ -74,6 +72,9 @@ const callChatCompletionStream = async ({ completion, openAIRequestContext, extr
74
72
  onChunk(chunkData);
75
73
  }
76
74
  }
75
+ const finalCompletion = await stream.finalChatCompletion();
76
+ const assistantMessage = finalCompletion.choices[0].message;
77
+ const requestId = openAIRequestContext.responseRequestId?.requestId;
77
78
  const finalAccumulated = (0, external_utils_js_namespaceObject.resolveContentWithReasoningFallback)({
78
79
  content: accumulated,
79
80
  reasoningContent: accumulatedReasoning,
@@ -91,7 +92,10 @@ const callChatCompletionStream = async ({ completion, openAIRequestContext, extr
91
92
  return {
92
93
  content: accumulated,
93
94
  reasoningContent: accumulatedReasoning,
94
- rawAssistantOutput: void 0,
95
+ rawAssistantOutput: {
96
+ type: 'chat-completion',
97
+ rawValue: assistantMessage
98
+ },
95
99
  rawUsage: usage,
96
100
  requestId,
97
101
  responseModelName
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/openai/chat-completion/stream.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../../src/ai-model/service-caller/openai/chat-completion/stream.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { CodeGenerationChunk } from '@/types';\nimport { assert } from '@midscene/shared/utils';\nimport type OpenAI from 'openai';\nimport type { Stream } from 'openai/streaming';\nimport type { OpenAIProtocolCallResult } from '../../types';\nimport type { ChatCompletionCallOptions } from './types';\nimport { resolveContentWithReasoningFallback } from './utils';\n\nexport const callChatCompletionStream = async ({\n completion,\n openAIRequestContext,\n extractContentAndReasoning,\n useReasoningAsContentFallback,\n requestBodyParams,\n requestSignal,\n onChunk,\n recordEvent,\n}: ChatCompletionCallOptions): Promise<OpenAIProtocolCallResult> => {\n assert(\n typeof onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n let accumulated = '';\n let accumulatedReasoning = '';\n let usage: OpenAI.CompletionUsage | undefined;\n let responseModelName: string | undefined;\n requestSignal.throwIfAborted();\n const stream = (await completion.create(\n {\n ...requestBodyParams,\n stream: true,\n stream_options: {\n ...requestBodyParams.stream_options,\n include_usage: true,\n },\n },\n {\n stream: true,\n signal: requestSignal,\n },\n )) as Stream<OpenAI.Chat.Completions.ChatCompletionChunk> & {\n _request_id?: string | null;\n };\n\n const requestId =\n stream._request_id ?? openAIRequestContext.responseRequestId?.requestId;\n\n let chunkSequence = 0;\n for await (const chunk of stream) {\n requestSignal.throwIfAborted();\n chunkSequence += 1;\n recordEvent?.({\n type: 'chunk',\n sequence: chunkSequence,\n chunk,\n });\n const parsedChunk = extractContentAndReasoning(chunk.choices?.[0]?.delta);\n const content = parsedChunk.content || '';\n const reasoning_content = parsedChunk.reasoning_content || '';\n\n // Check for usage info in any chunk (OpenAI provides usage in separate chunks)\n if (chunk.usage) {\n usage = chunk.usage;\n }\n if (chunk.model) {\n responseModelName = chunk.model;\n }\n\n if (content || reasoning_content) {\n accumulated += content;\n accumulatedReasoning += reasoning_content;\n const chunkData: CodeGenerationChunk = {\n content,\n reasoning_content,\n accumulated,\n isComplete: false,\n usage: undefined,\n };\n onChunk(chunkData);\n }\n }\n\n const finalAccumulated = resolveContentWithReasoningFallback({\n content: accumulated,\n reasoningContent: accumulatedReasoning,\n useReasoningAsContentFallback,\n });\n accumulated = finalAccumulated || '';\n\n // Send final chunk\n const finalChunk: CodeGenerationChunk = {\n content: '',\n accumulated,\n reasoning_content: '',\n isComplete: true,\n usage,\n };\n onChunk(finalChunk);\n return {\n content: accumulated,\n reasoningContent: accumulatedReasoning,\n rawAssistantOutput: undefined,\n rawUsage: usage,\n requestId,\n responseModelName,\n };\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","callChatCompletionStream","completion","openAIRequestContext","extractContentAndReasoning","useReasoningAsContentFallback","requestBodyParams","requestSignal","onChunk","recordEvent","assert","accumulated","accumulatedReasoning","usage","responseModelName","stream","requestId","chunkSequence","chunk","parsedChunk","content","reasoning_content","chunkData","undefined","finalAccumulated","resolveContentWithReasoningFallback","finalChunk"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;ACEO,MAAMI,2BAA2B,OAAO,EAC7CC,UAAU,EACVC,oBAAoB,EACpBC,0BAA0B,EAC1BC,6BAA6B,EAC7BC,iBAAiB,EACjBC,aAAa,EACbC,OAAO,EACPC,WAAW,EACe;IAC1BC,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,AAAmB,cAAnB,OAAOF,SACP;IAEF,IAAIG,cAAc;IAClB,IAAIC,uBAAuB;IAC3B,IAAIC;IACJ,IAAIC;IACJP,cAAc,cAAc;IAC5B,MAAMQ,SAAU,MAAMb,WAAW,MAAM,CACrC;QACE,GAAGI,iBAAiB;QACpB,QAAQ;QACR,gBAAgB;YACd,GAAGA,kBAAkB,cAAc;YACnC,eAAe;QACjB;IACF,GACA;QACE,QAAQ;QACR,QAAQC;IACV;IAKF,MAAMS,YACJD,OAAO,WAAW,IAAIZ,qBAAqB,iBAAiB,EAAE;IAEhE,IAAIc,gBAAgB;IACpB,WAAW,MAAMC,SAASH,OAAQ;QAChCR,cAAc,cAAc;QAC5BU,iBAAiB;QACjBR,cAAc;YACZ,MAAM;YACN,UAAUQ;YACVC;QACF;QACA,MAAMC,cAAcf,2BAA2Bc,MAAM,OAAO,EAAE,CAAC,EAAE,EAAE;QACnE,MAAME,UAAUD,YAAY,OAAO,IAAI;QACvC,MAAME,oBAAoBF,YAAY,iBAAiB,IAAI;QAG3D,IAAID,MAAM,KAAK,EACbL,QAAQK,MAAM,KAAK;QAErB,IAAIA,MAAM,KAAK,EACbJ,oBAAoBI,MAAM,KAAK;QAGjC,IAAIE,WAAWC,mBAAmB;YAChCV,eAAeS;YACfR,wBAAwBS;YACxB,MAAMC,YAAiC;gBACrCF;gBACAC;gBACAV;gBACA,YAAY;gBACZ,OAAOY;YACT;YACAf,QAAQc;QACV;IACF;IAEA,MAAME,mBAAmBC,AAAAA,IAAAA,kCAAAA,mCAAAA,AAAAA,EAAoC;QAC3D,SAASd;QACT,kBAAkBC;QAClBP;IACF;IACAM,cAAca,oBAAoB;IAGlC,MAAME,aAAkC;QACtC,SAAS;QACTf;QACA,mBAAmB;QACnB,YAAY;QACZE;IACF;IACAL,QAAQkB;IACR,OAAO;QACL,SAASf;QACT,kBAAkBC;QAClB,oBAAoBW;QACpB,UAAUV;QACVG;QACAF;IACF;AACF"}
1
+ {"version":3,"file":"ai-model/service-caller/openai/chat-completion/stream.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../../src/ai-model/service-caller/openai/chat-completion/stream.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { CodeGenerationChunk } from '@/types';\nimport { assert } from '@midscene/shared/utils';\nimport type OpenAI from 'openai';\nimport type { OpenAIProtocolCallResult } from '../../types';\nimport type { ChatCompletionCallOptions } from './types';\nimport { resolveContentWithReasoningFallback } from './utils';\n\nexport const callChatCompletionStream = async ({\n completion,\n openAIRequestContext,\n extractContentAndReasoning,\n useReasoningAsContentFallback,\n requestBodyParams,\n requestSignal,\n onChunk,\n recordEvent,\n}: ChatCompletionCallOptions): Promise<OpenAIProtocolCallResult> => {\n assert(\n typeof onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n let accumulated = '';\n let accumulatedReasoning = '';\n let usage: OpenAI.CompletionUsage | undefined;\n let responseModelName: string | undefined;\n requestSignal.throwIfAborted();\n const stream = completion.stream(\n {\n ...requestBodyParams,\n stream_options: {\n ...requestBodyParams.stream_options,\n include_usage: true,\n },\n },\n {\n signal: requestSignal,\n },\n );\n\n let chunkSequence = 0;\n for await (const chunk of stream) {\n requestSignal.throwIfAborted();\n chunkSequence += 1;\n recordEvent?.({\n type: 'chunk',\n sequence: chunkSequence,\n chunk,\n });\n const delta = chunk.choices?.[0]?.delta;\n const parsedChunk = extractContentAndReasoning(delta);\n const content = parsedChunk.content || '';\n const reasoning_content = parsedChunk.reasoning_content || '';\n\n // Check for usage info in any chunk (OpenAI provides usage in separate chunks)\n if (chunk.usage) {\n usage = chunk.usage;\n }\n if (chunk.model) {\n responseModelName = chunk.model;\n }\n\n if (content || reasoning_content) {\n accumulated += content;\n accumulatedReasoning += reasoning_content;\n const chunkData: CodeGenerationChunk = {\n content,\n reasoning_content,\n accumulated,\n isComplete: false,\n usage: undefined,\n };\n onChunk(chunkData);\n }\n }\n\n // TODO: The SDK overwrites non-standard fields such as reasoning_content,\n // so rawAssistantOutput may lose earlier thinking chunks (e.g. Doubao).\n // Add provider-specific handling when full reasoning replay is needed.\n const finalCompletion = await stream.finalChatCompletion();\n const assistantMessage = finalCompletion.choices[0].message;\n const requestId = openAIRequestContext.responseRequestId?.requestId;\n\n const finalAccumulated = resolveContentWithReasoningFallback({\n content: accumulated,\n reasoningContent: accumulatedReasoning,\n useReasoningAsContentFallback,\n });\n accumulated = finalAccumulated || '';\n\n // Send final chunk\n const finalChunk: CodeGenerationChunk = {\n content: '',\n accumulated,\n reasoning_content: '',\n isComplete: true,\n usage,\n };\n onChunk(finalChunk);\n return {\n content: accumulated,\n reasoningContent: accumulatedReasoning,\n rawAssistantOutput: {\n type: 'chat-completion',\n rawValue: assistantMessage,\n },\n rawUsage: usage,\n requestId,\n responseModelName,\n };\n};\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","callChatCompletionStream","completion","openAIRequestContext","extractContentAndReasoning","useReasoningAsContentFallback","requestBodyParams","requestSignal","onChunk","recordEvent","assert","accumulated","accumulatedReasoning","usage","responseModelName","stream","chunkSequence","chunk","delta","parsedChunk","content","reasoning_content","chunkData","undefined","finalCompletion","assistantMessage","requestId","finalAccumulated","resolveContentWithReasoningFallback","finalChunk"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;ACCO,MAAMI,2BAA2B,OAAO,EAC7CC,UAAU,EACVC,oBAAoB,EACpBC,0BAA0B,EAC1BC,6BAA6B,EAC7BC,iBAAiB,EACjBC,aAAa,EACbC,OAAO,EACPC,WAAW,EACe;IAC1BC,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,AAAmB,cAAnB,OAAOF,SACP;IAEF,IAAIG,cAAc;IAClB,IAAIC,uBAAuB;IAC3B,IAAIC;IACJ,IAAIC;IACJP,cAAc,cAAc;IAC5B,MAAMQ,SAASb,WAAW,MAAM,CAC9B;QACE,GAAGI,iBAAiB;QACpB,gBAAgB;YACd,GAAGA,kBAAkB,cAAc;YACnC,eAAe;QACjB;IACF,GACA;QACE,QAAQC;IACV;IAGF,IAAIS,gBAAgB;IACpB,WAAW,MAAMC,SAASF,OAAQ;QAChCR,cAAc,cAAc;QAC5BS,iBAAiB;QACjBP,cAAc;YACZ,MAAM;YACN,UAAUO;YACVC;QACF;QACA,MAAMC,QAAQD,MAAM,OAAO,EAAE,CAAC,EAAE,EAAE;QAClC,MAAME,cAAcf,2BAA2Bc;QAC/C,MAAME,UAAUD,YAAY,OAAO,IAAI;QACvC,MAAME,oBAAoBF,YAAY,iBAAiB,IAAI;QAG3D,IAAIF,MAAM,KAAK,EACbJ,QAAQI,MAAM,KAAK;QAErB,IAAIA,MAAM,KAAK,EACbH,oBAAoBG,MAAM,KAAK;QAGjC,IAAIG,WAAWC,mBAAmB;YAChCV,eAAeS;YACfR,wBAAwBS;YACxB,MAAMC,YAAiC;gBACrCF;gBACAC;gBACAV;gBACA,YAAY;gBACZ,OAAOY;YACT;YACAf,QAAQc;QACV;IACF;IAKA,MAAME,kBAAkB,MAAMT,OAAO,mBAAmB;IACxD,MAAMU,mBAAmBD,gBAAgB,OAAO,CAAC,EAAE,CAAC,OAAO;IAC3D,MAAME,YAAYvB,qBAAqB,iBAAiB,EAAE;IAE1D,MAAMwB,mBAAmBC,AAAAA,IAAAA,kCAAAA,mCAAAA,AAAAA,EAAoC;QAC3D,SAASjB;QACT,kBAAkBC;QAClBP;IACF;IACAM,cAAcgB,oBAAoB;IAGlC,MAAME,aAAkC;QACtC,SAAS;QACTlB;QACA,mBAAmB;QACnB,YAAY;QACZE;IACF;IACAL,QAAQqB;IACR,OAAO;QACL,SAASlB;QACT,kBAAkBC;QAClB,oBAAoB;YAClB,MAAM;YACN,UAAUa;QACZ;QACA,UAAUZ;QACVa;QACAZ;IACF;AACF"}
@@ -40,6 +40,7 @@ async function callResponsesStream({ responses, requestBodyParams, requestSignal
40
40
  }).withResponse();
41
41
  let accumulated = '';
42
42
  let finalResponse;
43
+ const completedItems = new Map();
43
44
  let sequence = 0;
44
45
  for await (const event of stream){
45
46
  requestSignal.throwIfAborted();
@@ -50,6 +51,7 @@ async function callResponsesStream({ responses, requestBodyParams, requestSignal
50
51
  });
51
52
  if ('error' === event.type) throw new Error(event.message);
52
53
  if ('response.failed' === event.type || 'response.incomplete' === event.type) (0, external_utils_js_namespaceObject_1.parseResponse)(event.response);
54
+ if ('response.output_item.done' === event.type) completedItems.set(event.output_index, event.item);
53
55
  if ('response.completed' === event.type) finalResponse = event.response;
54
56
  const content = 'response.output_text.delta' === event.type ? event.delta : '';
55
57
  const reasoningContent = 'response.reasoning_summary_text.delta' === event.type || 'response.reasoning_text.delta' === event.type ? event.delta : '';
@@ -65,7 +67,12 @@ async function callResponsesStream({ responses, requestBodyParams, requestSignal
65
67
  }
66
68
  requestSignal.throwIfAborted();
67
69
  (0, utils_namespaceObject.assert)(finalResponse, 'Responses stream ended without a completed response');
68
- const result = (0, external_utils_js_namespaceObject_1.parseResponse)(finalResponse);
70
+ const result = (0, external_utils_js_namespaceObject_1.parseResponse)(finalResponse.output?.length ? finalResponse : {
71
+ ...finalResponse,
72
+ output: [
73
+ ...completedItems.entries()
74
+ ].sort(([left], [right])=>left - right).map(([, item])=>item)
75
+ });
69
76
  if (!(0, external_utils_js_namespaceObject.hasUsableText)(result.content)) throw new external_utils_js_namespaceObject.AIResponseParseError('empty content from AI model', result.content, void 0, result.rawAssistantOutput);
70
77
  onChunk({
71
78
  content: '',
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/openai/responses/stream.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../../src/ai-model/service-caller/openai/responses/stream.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { assert } from '@midscene/shared/utils';\nimport type { Response } from 'openai/resources/responses/responses';\nimport type { OpenAIProtocolCallResult } from '../../types';\nimport { AIResponseParseError, hasUsableText } from '../../utils';\nimport type { ResponsesCallOptions } from './types';\nimport { parseResponse } from './utils';\n\nexport async function callResponsesStream({\n responses,\n requestBodyParams,\n requestSignal,\n openAIRequestContext,\n onChunk,\n recordEvent,\n}: ResponsesCallOptions): Promise<OpenAIProtocolCallResult> {\n assert(\n typeof onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n requestSignal.throwIfAborted();\n const { data: stream, request_id: requestId } = await responses\n .create({ ...requestBodyParams, stream: true }, { signal: requestSignal })\n .withResponse();\n let accumulated = '';\n let finalResponse: Response | undefined;\n let sequence = 0;\n for await (const event of stream) {\n requestSignal.throwIfAborted();\n recordEvent?.({ type: 'chunk', sequence: ++sequence, chunk: event });\n if (event.type === 'error') {\n throw new Error(event.message);\n }\n if (\n event.type === 'response.failed' ||\n event.type === 'response.incomplete'\n ) {\n parseResponse(event.response);\n }\n if (event.type === 'response.completed') {\n finalResponse = event.response;\n }\n const content =\n event.type === 'response.output_text.delta' ? event.delta : '';\n const reasoningContent =\n event.type === 'response.reasoning_summary_text.delta' ||\n event.type === 'response.reasoning_text.delta'\n ? event.delta\n : '';\n if (content || reasoningContent) {\n accumulated += content;\n onChunk({\n content,\n reasoning_content: reasoningContent,\n accumulated,\n isComplete: false,\n });\n }\n }\n requestSignal.throwIfAborted();\n assert(finalResponse, 'Responses stream ended without a completed response');\n const result = parseResponse(finalResponse);\n if (!hasUsableText(result.content)) {\n throw new AIResponseParseError(\n 'empty content from AI model',\n result.content,\n undefined,\n result.rawAssistantOutput,\n );\n }\n onChunk({\n content: '',\n reasoning_content: '',\n accumulated: result.content,\n isComplete: true,\n usage: result.rawUsage,\n });\n return {\n ...result,\n requestId: requestId ?? openAIRequestContext.responseRequestId?.requestId,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","callResponsesStream","responses","requestBodyParams","requestSignal","openAIRequestContext","onChunk","recordEvent","assert","stream","requestId","accumulated","finalResponse","sequence","event","Error","parseResponse","content","reasoningContent","result","hasUsableText","AIResponseParseError","undefined"],"mappings":";;;IAAAA,oBAAoB,CAAC,GAAG,CAAC,UAASC;QACjC,IAAI,IAAIC,OAAOD,WACR,IAAGD,oBAAoB,CAAC,CAACC,YAAYC,QAAQ,CAACF,oBAAoB,CAAC,CAAC,UAASE,MACzEC,OAAO,cAAc,CAAC,UAASD,KAAK;YAAE,YAAY;YAAM,KAAKD,UAAU,CAACC,IAAI;QAAC;IAGzF;;;ICNAF,oBAAoB,CAAC,GAAG,CAACI,KAAKC,OAAUF,OAAO,SAAS,CAAC,cAAc,CAAC,IAAI,CAACC,KAAKC;;;ICClFL,oBAAoB,CAAC,GAAG,CAAC;QACxB,IAAG,AAAkB,eAAlB,OAAOM,UAA0BA,OAAO,WAAW,EACrDH,OAAO,cAAc,CAAC,UAASG,OAAO,WAAW,EAAE;YAAE,OAAO;QAAS;QAEtEH,OAAO,cAAc,CAAC,UAAS,cAAc;YAAE,OAAO;QAAK;IAC5D;;;;;;;;;;ACCO,eAAeI,oBAAoB,EACxCC,SAAS,EACTC,iBAAiB,EACjBC,aAAa,EACbC,oBAAoB,EACpBC,OAAO,EACPC,WAAW,EACU;IACrBC,IAAAA,sBAAAA,MAAAA,AAAAA,EACE,AAAmB,cAAnB,OAAOF,SACP;IAEFF,cAAc,cAAc;IAC5B,MAAM,EAAE,MAAMK,MAAM,EAAE,YAAYC,SAAS,EAAE,GAAG,MAAMR,UACnD,MAAM,CAAC;QAAE,GAAGC,iBAAiB;QAAE,QAAQ;IAAK,GAAG;QAAE,QAAQC;IAAc,GACvE,YAAY;IACf,IAAIO,cAAc;IAClB,IAAIC;IACJ,IAAIC,WAAW;IACf,WAAW,MAAMC,SAASL,OAAQ;QAChCL,cAAc,cAAc;QAC5BG,cAAc;YAAE,MAAM;YAAS,UAAU,EAAEM;YAAU,OAAOC;QAAM;QAClE,IAAIA,AAAe,YAAfA,MAAM,IAAI,EACZ,MAAM,IAAIC,MAAMD,MAAM,OAAO;QAE/B,IACEA,AAAe,sBAAfA,MAAM,IAAI,IACVA,AAAe,0BAAfA,MAAM,IAAI,EAEVE,AAAAA,IAAAA,oCAAAA,aAAAA,AAAAA,EAAcF,MAAM,QAAQ;QAE9B,IAAIA,AAAe,yBAAfA,MAAM,IAAI,EACZF,gBAAgBE,MAAM,QAAQ;QAEhC,MAAMG,UACJH,AAAe,iCAAfA,MAAM,IAAI,GAAoCA,MAAM,KAAK,GAAG;QAC9D,MAAMI,mBACJJ,AAAe,4CAAfA,MAAM,IAAI,IACVA,AAAe,oCAAfA,MAAM,IAAI,GACNA,MAAM,KAAK,GACX;QACN,IAAIG,WAAWC,kBAAkB;YAC/BP,eAAeM;YACfX,QAAQ;gBACNW;gBACA,mBAAmBC;gBACnBP;gBACA,YAAY;YACd;QACF;IACF;IACAP,cAAc,cAAc;IAC5BI,IAAAA,sBAAAA,MAAAA,AAAAA,EAAOI,eAAe;IACtB,MAAMO,SAASH,AAAAA,IAAAA,oCAAAA,aAAAA,AAAAA,EAAcJ;IAC7B,IAAI,CAACQ,AAAAA,IAAAA,kCAAAA,aAAAA,AAAAA,EAAcD,OAAO,OAAO,GAC/B,MAAM,IAAIE,kCAAAA,oBAAoBA,CAC5B,+BACAF,OAAO,OAAO,EACdG,QACAH,OAAO,kBAAkB;IAG7Bb,QAAQ;QACN,SAAS;QACT,mBAAmB;QACnB,aAAaa,OAAO,OAAO;QAC3B,YAAY;QACZ,OAAOA,OAAO,QAAQ;IACxB;IACA,OAAO;QACL,GAAGA,MAAM;QACT,WAAWT,aAAaL,qBAAqB,iBAAiB,EAAE;IAClE;AACF"}
1
+ {"version":3,"file":"ai-model/service-caller/openai/responses/stream.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../../../src/ai-model/service-caller/openai/responses/stream.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import { assert } from '@midscene/shared/utils';\nimport type { Response } from 'openai/resources/responses/responses';\nimport type { OpenAIProtocolCallResult } from '../../types';\nimport { AIResponseParseError, hasUsableText } from '../../utils';\nimport type { ResponsesCallOptions } from './types';\nimport { parseResponse } from './utils';\n\nexport async function callResponsesStream({\n responses,\n requestBodyParams,\n requestSignal,\n openAIRequestContext,\n onChunk,\n recordEvent,\n}: ResponsesCallOptions): Promise<OpenAIProtocolCallResult> {\n assert(\n typeof onChunk === 'function',\n 'onChunk is required when stream is true',\n );\n requestSignal.throwIfAborted();\n const { data: stream, request_id: requestId } = await responses\n .create({ ...requestBodyParams, stream: true }, { signal: requestSignal })\n .withResponse();\n let accumulated = '';\n let finalResponse: Response | undefined;\n const completedItems = new Map<number, Response['output'][number]>();\n let sequence = 0;\n for await (const event of stream) {\n requestSignal.throwIfAborted();\n recordEvent?.({ type: 'chunk', sequence: ++sequence, chunk: event });\n if (event.type === 'error') {\n throw new Error(event.message);\n }\n if (\n event.type === 'response.failed' ||\n event.type === 'response.incomplete'\n ) {\n parseResponse(event.response);\n }\n if (event.type === 'response.output_item.done') {\n completedItems.set(event.output_index, event.item);\n }\n if (event.type === 'response.completed') {\n finalResponse = event.response;\n }\n const content =\n event.type === 'response.output_text.delta' ? event.delta : '';\n const reasoningContent =\n event.type === 'response.reasoning_summary_text.delta' ||\n event.type === 'response.reasoning_text.delta'\n ? event.delta\n : '';\n if (content || reasoningContent) {\n accumulated += content;\n onChunk({\n content,\n reasoning_content: reasoningContent,\n accumulated,\n isComplete: false,\n });\n }\n }\n requestSignal.throwIfAborted();\n assert(finalResponse, 'Responses stream ended without a completed response');\n // Some ChatGPT plan responses omit output from the completion event even\n // after delivering complete items. Preserve those items, including reasoning\n // and replay metadata, without treating an interrupted stream as complete.\n const result = parseResponse(\n finalResponse.output?.length\n ? finalResponse\n : {\n ...finalResponse,\n output: [...completedItems.entries()]\n .sort(([left], [right]) => left - right)\n .map(([, item]) => item),\n },\n );\n if (!hasUsableText(result.content)) {\n throw new AIResponseParseError(\n 'empty content from AI model',\n result.content,\n undefined,\n result.rawAssistantOutput,\n );\n }\n onChunk({\n content: '',\n reasoning_content: '',\n accumulated: result.content,\n isComplete: true,\n usage: result.rawUsage,\n });\n return {\n ...result,\n requestId: requestId ?? openAIRequestContext.responseRequestId?.requestId,\n };\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","callResponsesStream","responses","requestBodyParams","requestSignal","openAIRequestContext","onChunk","recordEvent","assert","stream","requestId","accumulated","finalResponse","completedItems","Map","sequence","event","Error","parseResponse","content","reasoningContent","result","left","right","item","hasUsableText","AIResponseParseError","undefined"],"mappings":"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"}
@@ -89,12 +89,13 @@ function appendAIRequestFailureSummary(error, attemptErrors, maxAttempts) {
89
89
  error.message = `${error.message}\nPrevious AI call attempt errors:\n${details}`;
90
90
  return error;
91
91
  }
92
- const buildUsageInfo = ({ apiType, usageData, requestId, timeCost, totalTimeCost, retryCount, modelName, modelDescription, responseModelName, slot, internalCallId })=>{
92
+ const buildUsageInfo = ({ apiProtocol, stream, usageData, requestId, timeCost, totalTimeCost, retryCount, modelName, modelDescription, responseModelName, slot, internalCallId })=>{
93
93
  if (!usageData) return;
94
94
  const cachedInputTokens = usageData?.prompt_tokens_details?.cached_tokens;
95
95
  return {
96
96
  ...usageData,
97
- api_type: apiType,
97
+ api_protocol: apiProtocol,
98
+ stream,
98
99
  prompt_tokens: usageData.prompt_tokens ?? 0,
99
100
  completion_tokens: usageData.completion_tokens ?? 0,
100
101
  total_tokens: usageData.total_tokens ?? 0,
@@ -1 +1 @@
1
- {"version":3,"file":"ai-model/service-caller/utils.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/utils.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { RawAssistantOutput } from '@/types';\nimport type { AIUsageInfo } from '@/types';\nimport type OpenAI from 'openai';\nimport type { ModelRuntime } from '../models';\n\n// Error class that preserves usage and rawResponse when AI call parsing fails\nexport class AIResponseParseError extends Error {\n usage?: AIUsageInfo;\n /**\n * Adapter-extracted content used by Midscene for parsing. This is not the\n * full provider response or choices[0].message.\n */\n rawResponse: string;\n rawAssistantOutput?: RawAssistantOutput;\n reasoningContent?: string;\n\n constructor(\n message: string,\n rawResponse: string,\n usage?: AIUsageInfo,\n rawAssistantOutput?: RawAssistantOutput,\n reasoningContent?: string,\n ) {\n super(message);\n this.name = 'AIResponseParseError';\n this.rawResponse = rawResponse;\n this.usage = usage;\n this.rawAssistantOutput = rawAssistantOutput;\n this.reasoningContent = reasoningContent;\n }\n}\n\n/**\n * Internal field name stamped onto every AIUsageInfo shaped by callAI().\n * Used for cross-path dedup when the provider does not return a request_id.\n */\nexport const INTERNAL_CALL_ID_FIELD = '_midscene_call_id';\n\nlet internalCallIdCounter = 0;\nexport function nextInternalCallId(): string {\n internalCallIdCounter += 1;\n return `call_${internalCallIdCounter}`;\n}\n\nexport function stringifyForDebug(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch (_error) {\n return String(value);\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nexport function normalizeRetryCount(retryCount: unknown): number {\n if (typeof retryCount !== 'number' || !Number.isFinite(retryCount)) {\n return 1;\n }\n\n return Math.max(0, Math.floor(retryCount));\n}\n\nexport function appendAIRequestFailureSummary<T extends Error>(\n error: T,\n attemptErrors: Array<{ attempt: number; error: unknown }>,\n maxAttempts: number,\n): T {\n const failedAttempts = attemptErrors.length;\n const retries = Math.max(0, failedAttempts - 1);\n const retryLabel = retries === 1 ? 'retry' : 'retries';\n const originalMessage = error.message;\n const previousAttemptErrors = attemptErrors.slice(0, -1);\n\n error.message = `AI model request failed after ${retries} ${retryLabel} (${failedAttempts}/${maxAttempts} attempts). Last error: ${originalMessage}`;\n\n if (previousAttemptErrors.length === 0) {\n return error;\n }\n\n const details = previousAttemptErrors\n .map(\n ({ attempt, error }) => `Attempt ${attempt}: ${getErrorMessage(error)}`,\n )\n .join('\\n');\n\n error.message = `${error.message}\\nPrevious AI call attempt errors:\\n${details}`;\n return error;\n}\n\nexport const buildUsageInfo = ({\n apiType,\n usageData,\n requestId,\n timeCost,\n totalTimeCost,\n retryCount,\n modelName,\n modelDescription,\n responseModelName,\n slot,\n internalCallId,\n}: {\n apiType: NonNullable<AIUsageInfo['api_type']>;\n usageData?: OpenAI.CompletionUsage;\n requestId?: string | null;\n timeCost?: number;\n totalTimeCost: number;\n retryCount: number;\n modelName: string;\n modelDescription: string;\n responseModelName?: string;\n slot: ModelRuntime['config']['slot'];\n internalCallId: string;\n}): AIUsageInfo | undefined => {\n if (!usageData) return undefined;\n\n const cachedInputTokens = (\n usageData as { prompt_tokens_details?: { cached_tokens?: number } }\n )?.prompt_tokens_details?.cached_tokens;\n\n return {\n ...usageData,\n api_type: apiType,\n prompt_tokens: usageData.prompt_tokens ?? 0,\n completion_tokens: usageData.completion_tokens ?? 0,\n total_tokens: usageData.total_tokens ?? 0,\n cached_input: cachedInputTokens ?? 0,\n time_cost: timeCost ?? 0,\n total_time_cost: totalTimeCost,\n retry_count: retryCount,\n model_name: modelName,\n model_description: modelDescription,\n response_model_name: responseModelName,\n slot,\n // Left undefined at the raw call layer. The agent's onUsage callback\n // fills it from modelConfig.slot for metrics collection, and task\n // layers use withUsageIntent() to stamp a more specific semantic\n // intent (e.g. 'planning', 'insight') when attaching usage to tasks.\n intent: undefined,\n request_id: requestId ?? undefined,\n // Internal stable ID for cross-path dedup when request_id is absent.\n [INTERNAL_CALL_ID_FIELD]: internalCallId,\n } satisfies AIUsageInfo;\n};\n\nexport const hasUsableText = (\n value: string | null | undefined,\n): value is string => typeof value === 'string' && value.trim().length > 0;\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","AIResponseParseError","Error","message","rawResponse","usage","rawAssistantOutput","reasoningContent","INTERNAL_CALL_ID_FIELD","internalCallIdCounter","nextInternalCallId","stringifyForDebug","value","JSON","_error","String","getErrorMessage","error","toError","normalizeRetryCount","retryCount","Number","Math","appendAIRequestFailureSummary","attemptErrors","maxAttempts","failedAttempts","retries","retryLabel","originalMessage","previousAttemptErrors","details","attempt","buildUsageInfo","apiType","usageData","requestId","timeCost","totalTimeCost","modelName","modelDescription","responseModelName","slot","internalCallId","cachedInputTokens","undefined","hasUsableText"],"mappings":"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"}
1
+ {"version":3,"file":"ai-model/service-caller/utils.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../../src/ai-model/service-caller/utils.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { RawAssistantOutput } from '@/types';\nimport type { AIUsageInfo } from '@/types';\nimport type OpenAI from 'openai';\nimport type { ModelRuntime } from '../models';\n\n// Error class that preserves usage and rawResponse when AI call parsing fails\nexport class AIResponseParseError extends Error {\n usage?: AIUsageInfo;\n /**\n * Adapter-extracted content used by Midscene for parsing. This is not the\n * full provider response or choices[0].message.\n */\n rawResponse: string;\n rawAssistantOutput?: RawAssistantOutput;\n reasoningContent?: string;\n\n constructor(\n message: string,\n rawResponse: string,\n usage?: AIUsageInfo,\n rawAssistantOutput?: RawAssistantOutput,\n reasoningContent?: string,\n ) {\n super(message);\n this.name = 'AIResponseParseError';\n this.rawResponse = rawResponse;\n this.usage = usage;\n this.rawAssistantOutput = rawAssistantOutput;\n this.reasoningContent = reasoningContent;\n }\n}\n\n/**\n * Internal field name stamped onto every AIUsageInfo shaped by callAI().\n * Used for cross-path dedup when the provider does not return a request_id.\n */\nexport const INTERNAL_CALL_ID_FIELD = '_midscene_call_id';\n\nlet internalCallIdCounter = 0;\nexport function nextInternalCallId(): string {\n internalCallIdCounter += 1;\n return `call_${internalCallIdCounter}`;\n}\n\nexport function stringifyForDebug(value: unknown): string {\n try {\n return JSON.stringify(value);\n } catch (_error) {\n return String(value);\n }\n}\n\nfunction getErrorMessage(error: unknown): string {\n return error instanceof Error ? error.message : String(error);\n}\n\nexport function toError(error: unknown): Error {\n return error instanceof Error ? error : new Error(String(error));\n}\n\nexport function normalizeRetryCount(retryCount: unknown): number {\n if (typeof retryCount !== 'number' || !Number.isFinite(retryCount)) {\n return 1;\n }\n\n return Math.max(0, Math.floor(retryCount));\n}\n\nexport function appendAIRequestFailureSummary<T extends Error>(\n error: T,\n attemptErrors: Array<{ attempt: number; error: unknown }>,\n maxAttempts: number,\n): T {\n const failedAttempts = attemptErrors.length;\n const retries = Math.max(0, failedAttempts - 1);\n const retryLabel = retries === 1 ? 'retry' : 'retries';\n const originalMessage = error.message;\n const previousAttemptErrors = attemptErrors.slice(0, -1);\n\n error.message = `AI model request failed after ${retries} ${retryLabel} (${failedAttempts}/${maxAttempts} attempts). Last error: ${originalMessage}`;\n\n if (previousAttemptErrors.length === 0) {\n return error;\n }\n\n const details = previousAttemptErrors\n .map(\n ({ attempt, error }) => `Attempt ${attempt}: ${getErrorMessage(error)}`,\n )\n .join('\\n');\n\n error.message = `${error.message}\\nPrevious AI call attempt errors:\\n${details}`;\n return error;\n}\n\nexport const buildUsageInfo = ({\n apiProtocol,\n stream,\n usageData,\n requestId,\n timeCost,\n totalTimeCost,\n retryCount,\n modelName,\n modelDescription,\n responseModelName,\n slot,\n internalCallId,\n}: {\n apiProtocol: NonNullable<AIUsageInfo['api_protocol']>;\n stream: boolean;\n usageData?: OpenAI.CompletionUsage;\n requestId?: string | null;\n timeCost?: number;\n totalTimeCost: number;\n retryCount: number;\n modelName: string;\n modelDescription: string;\n responseModelName?: string;\n slot: ModelRuntime['config']['slot'];\n internalCallId: string;\n}): AIUsageInfo | undefined => {\n if (!usageData) return undefined;\n\n const cachedInputTokens = (\n usageData as { prompt_tokens_details?: { cached_tokens?: number } }\n )?.prompt_tokens_details?.cached_tokens;\n\n return {\n ...usageData,\n api_protocol: apiProtocol,\n stream,\n prompt_tokens: usageData.prompt_tokens ?? 0,\n completion_tokens: usageData.completion_tokens ?? 0,\n total_tokens: usageData.total_tokens ?? 0,\n cached_input: cachedInputTokens ?? 0,\n time_cost: timeCost ?? 0,\n total_time_cost: totalTimeCost,\n retry_count: retryCount,\n model_name: modelName,\n model_description: modelDescription,\n response_model_name: responseModelName,\n slot,\n // Left undefined at the raw call layer. The agent's onUsage callback\n // fills it from modelConfig.slot for metrics collection, and task\n // layers use withUsageIntent() to stamp a more specific semantic\n // intent (e.g. 'planning', 'insight') when attaching usage to tasks.\n intent: undefined,\n request_id: requestId ?? undefined,\n // Internal stable ID for cross-path dedup when request_id is absent.\n [INTERNAL_CALL_ID_FIELD]: internalCallId,\n } satisfies AIUsageInfo;\n};\n\nexport const hasUsableText = (\n value: string | null | undefined,\n): value is string => typeof value === 'string' && value.trim().length > 0;\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","AIResponseParseError","Error","message","rawResponse","usage","rawAssistantOutput","reasoningContent","INTERNAL_CALL_ID_FIELD","internalCallIdCounter","nextInternalCallId","stringifyForDebug","value","JSON","_error","String","getErrorMessage","error","toError","normalizeRetryCount","retryCount","Number","Math","appendAIRequestFailureSummary","attemptErrors","maxAttempts","failedAttempts","retries","retryLabel","originalMessage","previousAttemptErrors","details","attempt","buildUsageInfo","apiProtocol","stream","usageData","requestId","timeCost","totalTimeCost","modelName","modelDescription","responseModelName","slot","internalCallId","cachedInputTokens","undefined","hasUsableText"],"mappings":"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"}
@@ -95,6 +95,7 @@ function resolveSwipeInputPrimitive(input) {
95
95
  };
96
96
  }
97
97
  class AbstractInterface {
98
+ async defaultActionWait(_actionName, _param) {}
98
99
  constructor(){
99
100
  _define_property(this, "mjpegStreamUrl", void 0);
100
101
  _define_property(this, "inputPrimitives", void 0);
@@ -239,7 +240,7 @@ const defineActionInput = (keyboard)=>defineAction({
239
240
  prompt: 'the email input field'
240
241
  }
241
242
  },
242
- call: async (param)=>{
243
+ call: async (param, context)=>{
243
244
  if ('append' === param.mode) param.mode = 'typeOnly';
244
245
  if ('clear' === param.mode) return void await keyboard.clearInput(param.locate);
245
246
  if (!param || !param.value) return;
@@ -248,7 +249,10 @@ const defineActionInput = (keyboard)=>defineAction({
248
249
  replace: 'typeOnly' !== param.mode,
249
250
  autoDismissKeyboard: param.autoDismissKeyboard,
250
251
  keyboardTypeDelay: param.keyboardTypeDelay,
251
- inputStrategy: param.inputStrategy
252
+ inputStrategy: param.inputStrategy,
253
+ ...context?.skipDefaultWait ? {
254
+ skipDefaultWait: true
255
+ } : {}
252
256
  });
253
257
  }
254
258
  });
@@ -299,8 +303,11 @@ const defineActionScroll = (scroll)=>defineAction({
299
303
  prompt: 'the center of the product list area'
300
304
  }
301
305
  },
302
- call: async (param)=>{
303
- await scroll(param);
306
+ call: async (param, context)=>{
307
+ if (context?.skipDefaultWait) await scroll(param, {
308
+ skipDefaultWait: true
309
+ });
310
+ else await scroll(param);
304
311
  }
305
312
  });
306
313
  const actionDragAndDropParamSchema = external_zod_namespaceObject.z.object({