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