@midscene/core 1.9.8 → 1.10.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/agent.mjs +26 -94
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/prompt-context.mjs +14 -0
- package/dist/es/agent/prompt-context.mjs.map +1 -0
- package/dist/es/agent/run-gherkin-scenario.mjs +114 -0
- package/dist/es/agent/run-gherkin-scenario.mjs.map +1 -0
- package/dist/es/agent/task-builder.mjs +4 -4
- package/dist/es/agent/task-builder.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +4 -8
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +15 -3
- package/dist/es/agent/utils.mjs.map +1 -1
- package/dist/es/ai-model/index.mjs +1 -2
- package/dist/es/ai-model/inspect.mjs +77 -50
- package/dist/es/ai-model/inspect.mjs.map +1 -1
- package/dist/es/ai-model/llm-planning.mjs +10 -26
- package/dist/es/ai-model/llm-planning.mjs.map +1 -1
- package/dist/es/ai-model/model-adapter/chat-completion.mjs +46 -0
- package/dist/es/ai-model/model-adapter/chat-completion.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/index.mjs +2 -0
- package/dist/es/ai-model/model-adapter/locate.mjs +33 -0
- package/dist/es/ai-model/model-adapter/locate.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/planning.mjs +44 -0
- package/dist/es/ai-model/model-adapter/planning.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/resolve.mjs +43 -0
- package/dist/es/ai-model/model-adapter/resolve.mjs.map +1 -0
- package/dist/es/ai-model/model-adapter/types.mjs +0 -0
- package/dist/es/ai-model/models/auto-glm/actions.mjs +19 -31
- package/dist/es/ai-model/models/auto-glm/actions.mjs.map +1 -1
- package/dist/es/ai-model/models/auto-glm/adapter.mjs +8 -16
- package/dist/es/ai-model/models/auto-glm/adapter.mjs.map +1 -1
- package/dist/es/ai-model/models/auto-glm/locate.mjs +6 -108
- package/dist/es/ai-model/models/auto-glm/locate.mjs.map +1 -1
- package/dist/es/ai-model/models/auto-glm/parser.mjs +19 -41
- package/dist/es/ai-model/models/auto-glm/parser.mjs.map +1 -1
- package/dist/es/ai-model/models/auto-glm/planning.mjs +27 -70
- package/dist/es/ai-model/models/auto-glm/planning.mjs.map +1 -1
- package/dist/es/ai-model/models/default.mjs.map +1 -1
- package/dist/es/ai-model/models/doubao.mjs.map +1 -1
- package/dist/es/ai-model/models/gemini.mjs +1 -1
- package/dist/es/ai-model/models/gemini.mjs.map +1 -1
- package/dist/es/ai-model/models/glm.mjs.map +1 -1
- package/dist/es/ai-model/models/gpt.mjs.map +1 -1
- package/dist/es/ai-model/models/kimi.mjs.map +1 -1
- package/dist/es/ai-model/models/mimo.mjs.map +1 -1
- package/dist/es/ai-model/models/qwen.mjs.map +1 -1
- package/dist/es/ai-model/models/registry.mjs +1 -1
- package/dist/es/ai-model/models/registry.mjs.map +1 -1
- package/dist/es/ai-model/models/ui-tars/actions.mjs +147 -0
- package/dist/es/ai-model/models/ui-tars/actions.mjs.map +1 -0
- package/dist/es/ai-model/models/ui-tars/adapter.mjs +2 -2
- package/dist/es/ai-model/models/ui-tars/adapter.mjs.map +1 -1
- package/dist/es/ai-model/models/ui-tars/parser.mjs +40 -0
- package/dist/es/ai-model/models/ui-tars/parser.mjs.map +1 -0
- package/dist/es/ai-model/models/ui-tars/planning.mjs +19 -230
- package/dist/es/ai-model/models/ui-tars/planning.mjs.map +1 -1
- package/dist/es/ai-model/{prompt/ui-tars-planning.mjs → models/ui-tars/prompt.mjs} +1 -1
- package/dist/es/ai-model/models/ui-tars/prompt.mjs.map +1 -0
- package/dist/es/ai-model/service-caller/index.mjs +1 -3
- package/dist/es/ai-model/service-caller/index.mjs.map +1 -1
- package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs +10 -0
- package/dist/es/ai-model/shared/model-locate-result/coordinate-distance.mjs.map +1 -0
- package/dist/es/ai-model/shared/model-locate-result/factory.mjs +1 -3
- package/dist/es/ai-model/shared/model-locate-result/factory.mjs.map +1 -1
- package/dist/es/ai-model/shared/model-locate-result/index.mjs +3 -2
- package/dist/es/ai-model/shared/planning-action.mjs +6 -0
- package/dist/es/ai-model/shared/planning-action.mjs.map +1 -0
- package/dist/es/ai-model/workflows/inspect/planning-action-locate.mjs +95 -0
- package/dist/es/ai-model/workflows/inspect/planning-action-locate.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs +126 -0
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -0
- package/dist/es/ai-model/workflows/planning/locate-normalization.mjs +31 -0
- package/dist/es/ai-model/workflows/planning/locate-normalization.mjs.map +1 -0
- package/dist/es/common.mjs +10 -6
- package/dist/es/common.mjs.map +1 -1
- package/dist/es/element-describer.mjs +180 -0
- package/dist/es/element-describer.mjs.map +1 -0
- package/dist/es/index.mjs +2 -1
- package/dist/es/index.mjs.map +1 -1
- package/dist/es/report-generator.mjs +3 -5
- package/dist/es/report-generator.mjs.map +1 -1
- package/dist/es/service/index.mjs +3 -2
- package/dist/es/service/index.mjs.map +1 -1
- package/dist/es/skill/index.mjs +1 -1
- package/dist/es/skill/index.mjs.map +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +2 -2
- package/dist/es/yaml/player.mjs +7 -0
- package/dist/es/yaml/player.mjs.map +1 -1
- package/dist/lib/agent/agent.js +25 -93
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/{ai-model/models/chat-content.js → agent/prompt-context.js} +13 -13
- package/dist/lib/agent/prompt-context.js.map +1 -0
- package/dist/lib/agent/run-gherkin-scenario.js +151 -0
- package/dist/lib/agent/run-gherkin-scenario.js.map +1 -0
- package/dist/lib/agent/task-builder.js +4 -4
- package/dist/lib/agent/task-builder.js.map +1 -1
- package/dist/lib/agent/tasks.js +4 -8
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/utils.js +14 -2
- package/dist/lib/agent/utils.js.map +1 -1
- package/dist/lib/ai-model/index.js +0 -10
- package/dist/lib/ai-model/inspect.js +77 -50
- package/dist/lib/ai-model/inspect.js.map +1 -1
- package/dist/lib/ai-model/llm-planning.js +9 -25
- package/dist/lib/ai-model/llm-planning.js.map +1 -1
- package/dist/lib/ai-model/model-adapter/chat-completion.js +83 -0
- package/dist/lib/ai-model/model-adapter/chat-completion.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/custom-planning-types.js +20 -0
- package/dist/lib/ai-model/model-adapter/custom-planning-types.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/index.js +38 -0
- package/dist/lib/ai-model/model-adapter/index.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/locate.js +67 -0
- package/dist/lib/ai-model/model-adapter/locate.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/planning.js +81 -0
- package/dist/lib/ai-model/model-adapter/planning.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/resolve.js +77 -0
- package/dist/lib/ai-model/model-adapter/resolve.js.map +1 -0
- package/dist/lib/ai-model/model-adapter/types.js.map +1 -0
- package/dist/lib/ai-model/models/auto-glm/actions.js +19 -31
- package/dist/lib/ai-model/models/auto-glm/actions.js.map +1 -1
- package/dist/lib/ai-model/models/auto-glm/adapter.js +6 -14
- package/dist/lib/ai-model/models/auto-glm/adapter.js.map +1 -1
- package/dist/lib/ai-model/models/auto-glm/locate.js +8 -110
- package/dist/lib/ai-model/models/auto-glm/locate.js.map +1 -1
- package/dist/lib/ai-model/models/auto-glm/parser.js +24 -46
- package/dist/lib/ai-model/models/auto-glm/parser.js.map +1 -1
- package/dist/lib/ai-model/models/auto-glm/planning.js +28 -71
- package/dist/lib/ai-model/models/auto-glm/planning.js.map +1 -1
- package/dist/lib/ai-model/models/default.js.map +1 -1
- package/dist/lib/ai-model/models/doubao.js.map +1 -1
- package/dist/lib/ai-model/models/gemini.js +2 -2
- package/dist/lib/ai-model/models/gemini.js.map +1 -1
- package/dist/lib/ai-model/models/glm.js.map +1 -1
- package/dist/lib/ai-model/models/gpt.js.map +1 -1
- package/dist/lib/ai-model/models/kimi.js.map +1 -1
- package/dist/lib/ai-model/models/mimo.js.map +1 -1
- 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/models/ui-tars/actions.js +181 -0
- package/dist/lib/ai-model/models/ui-tars/actions.js.map +1 -0
- package/dist/lib/ai-model/models/ui-tars/adapter.js +1 -1
- package/dist/lib/ai-model/models/ui-tars/adapter.js.map +1 -1
- package/dist/lib/ai-model/models/ui-tars/parser.js +74 -0
- package/dist/lib/ai-model/models/ui-tars/parser.js.map +1 -0
- package/dist/lib/ai-model/models/ui-tars/planning.js +21 -232
- package/dist/lib/ai-model/models/ui-tars/planning.js.map +1 -1
- package/dist/lib/ai-model/{prompt/ui-tars-planning.js → models/ui-tars/prompt.js} +1 -1
- package/dist/lib/ai-model/models/ui-tars/prompt.js.map +1 -0
- package/dist/lib/ai-model/service-caller/index.js +1 -3
- package/dist/lib/ai-model/service-caller/index.js.map +1 -1
- package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js +44 -0
- package/dist/lib/ai-model/shared/model-locate-result/coordinate-distance.js.map +1 -0
- package/dist/lib/ai-model/shared/model-locate-result/factory.js +5 -4
- package/dist/lib/ai-model/shared/model-locate-result/factory.js.map +1 -1
- package/dist/lib/ai-model/shared/model-locate-result/index.js +7 -0
- package/dist/lib/ai-model/shared/planning-action.js +40 -0
- package/dist/lib/ai-model/shared/planning-action.js.map +1 -0
- package/dist/lib/ai-model/workflows/inspect/planning-action-locate.js +129 -0
- package/dist/lib/ai-model/workflows/inspect/planning-action-locate.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/custom-planning.js +163 -0
- package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -0
- package/dist/lib/ai-model/workflows/planning/locate-normalization.js +65 -0
- package/dist/lib/ai-model/workflows/planning/locate-normalization.js.map +1 -0
- package/dist/lib/common.js +13 -6
- package/dist/lib/common.js.map +1 -1
- package/dist/lib/element-describer.js +223 -0
- package/dist/lib/element-describer.js.map +1 -0
- package/dist/lib/index.js +14 -1
- package/dist/lib/index.js.map +1 -1
- package/dist/lib/report-generator.js +4 -6
- package/dist/lib/report-generator.js.map +1 -1
- package/dist/lib/service/index.js +3 -2
- package/dist/lib/service/index.js.map +1 -1
- package/dist/lib/skill/index.js +1 -1
- package/dist/lib/skill/index.js.map +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +2 -2
- package/dist/lib/yaml/player.js +7 -0
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/types/agent/agent.d.ts +4 -18
- package/dist/types/agent/index.d.ts +3 -2
- package/dist/types/agent/prompt-context.d.ts +2 -0
- package/dist/types/agent/run-gherkin-scenario.d.ts +26 -0
- package/dist/types/agent/tasks.d.ts +3 -1
- package/dist/types/ai-model/index.d.ts +0 -2
- package/dist/types/ai-model/inspect.d.ts +3 -2
- package/dist/types/ai-model/model-adapter/chat-completion.d.ts +3 -0
- package/dist/types/ai-model/model-adapter/custom-planning-types.d.ts +32 -0
- package/dist/types/ai-model/model-adapter/index.d.ts +2 -0
- package/dist/types/ai-model/model-adapter/locate.d.ts +3 -0
- package/dist/types/ai-model/model-adapter/planning.d.ts +4 -0
- package/dist/types/ai-model/{models → model-adapter}/types.d.ts +39 -4
- package/dist/types/ai-model/models/auto-glm/actions.d.ts +8 -5
- package/dist/types/ai-model/models/auto-glm/adapter.d.ts +1 -1
- package/dist/types/ai-model/models/auto-glm/locate.d.ts +2 -3
- package/dist/types/ai-model/models/auto-glm/parser.d.ts +6 -10
- package/dist/types/ai-model/models/auto-glm/planning.d.ts +5 -4
- package/dist/types/ai-model/models/default.d.ts +1 -1
- package/dist/types/ai-model/models/doubao.d.ts +1 -1
- package/dist/types/ai-model/models/gemini.d.ts +1 -1
- package/dist/types/ai-model/models/glm.d.ts +1 -1
- package/dist/types/ai-model/models/gpt.d.ts +1 -1
- package/dist/types/ai-model/models/index.d.ts +1 -1
- package/dist/types/ai-model/models/kimi.d.ts +1 -1
- package/dist/types/ai-model/models/mimo.d.ts +1 -1
- package/dist/types/ai-model/models/qwen.d.ts +1 -1
- package/dist/types/ai-model/models/registry.d.ts +10 -10
- package/dist/types/ai-model/models/ui-tars/actions.d.ts +3 -0
- package/dist/types/ai-model/models/ui-tars/adapter.d.ts +1 -1
- package/dist/types/ai-model/models/ui-tars/parser.d.ts +72 -0
- package/dist/types/ai-model/models/ui-tars/planning.d.ts +3 -68
- package/dist/types/ai-model/service-caller/index.d.ts +4 -5
- package/dist/types/ai-model/shared/model-locate-result/coordinate-distance.d.ts +4 -0
- package/dist/types/ai-model/shared/model-locate-result/factory.d.ts +2 -1
- package/dist/types/ai-model/shared/model-locate-result/index.d.ts +4 -2
- package/dist/types/ai-model/shared/model-locate-result/types.d.ts +0 -1
- package/dist/types/ai-model/shared/planning-action.d.ts +20 -0
- package/dist/types/ai-model/workflows/inspect/planning-action-locate.d.ts +4 -0
- package/dist/types/ai-model/workflows/inspect/types.d.ts +21 -2
- package/dist/types/ai-model/workflows/planning/custom-planning.d.ts +7 -0
- package/dist/types/ai-model/workflows/planning/locate-normalization.d.ts +9 -0
- package/dist/types/common.d.ts +1 -0
- package/dist/types/device/index.d.ts +17 -17
- package/dist/types/element-describer.d.ts +46 -0
- package/dist/types/index.d.ts +2 -1
- package/dist/types/service/index.d.ts +3 -1
- package/dist/types/types.d.ts +5 -0
- package/dist/types/yaml.d.ts +4 -1
- package/package.json +3 -3
- package/dist/es/ai-model/models/chat-content.mjs +0 -14
- package/dist/es/ai-model/models/chat-content.mjs.map +0 -1
- package/dist/es/ai-model/models/resolved.mjs +0 -107
- package/dist/es/ai-model/models/resolved.mjs.map +0 -1
- package/dist/es/ai-model/prompt/recorder-ui-describer.mjs +0 -56
- package/dist/es/ai-model/prompt/recorder-ui-describer.mjs.map +0 -1
- package/dist/es/ai-model/prompt/ui-tars-planning.mjs.map +0 -1
- package/dist/es/recorder-ui-describer.mjs +0 -379
- package/dist/es/recorder-ui-describer.mjs.map +0 -1
- package/dist/lib/ai-model/models/chat-content.js.map +0 -1
- package/dist/lib/ai-model/models/resolved.js +0 -141
- package/dist/lib/ai-model/models/resolved.js.map +0 -1
- package/dist/lib/ai-model/models/types.js.map +0 -1
- package/dist/lib/ai-model/prompt/recorder-ui-describer.js +0 -90
- package/dist/lib/ai-model/prompt/recorder-ui-describer.js.map +0 -1
- package/dist/lib/ai-model/prompt/ui-tars-planning.js.map +0 -1
- package/dist/lib/recorder-ui-describer.js +0 -419
- package/dist/lib/recorder-ui-describer.js.map +0 -1
- package/dist/types/ai-model/models/chat-content.d.ts +0 -2
- package/dist/types/ai-model/prompt/recorder-ui-describer.d.ts +0 -1
- package/dist/types/recorder-ui-describer.d.ts +0 -20
- /package/dist/es/ai-model/{models/types.mjs → model-adapter/custom-planning-types.mjs} +0 -0
- /package/dist/lib/ai-model/{models → model-adapter}/types.js +0 -0
- /package/dist/types/ai-model/{models/resolved.d.ts → model-adapter/resolve.d.ts} +0 -0
- /package/dist/types/ai-model/{prompt/ui-tars-planning.d.ts → models/ui-tars/prompt.d.ts} +0 -0
|
@@ -1,113 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
import { extraTextFromUserPrompt, promptsToChatParam } from "../../inspect.mjs";
|
|
5
|
-
import { findElementPrompt } from "../../prompt/llm-locator.mjs";
|
|
6
|
-
import { callAIWithStringResponse } from "../../service-caller/index.mjs";
|
|
7
|
-
import { finalizePixelBbox } from "../../shared/model-locate-result/bbox.mjs";
|
|
8
|
-
import { mapLocateResultToPixelBboxByCoordinates } from "../../shared/model-locate-result/pixel-bbox-mapper.mjs";
|
|
9
|
-
import { pixelBboxToRect } from "../../workflows/inspect/locate-result-rect.mjs";
|
|
10
|
-
import { mapSearchAreaPixelBboxToOriginalPixelBbox } from "../../workflows/inspect/search-area-mapping.mjs";
|
|
11
|
-
import { parseAutoGLMLocateResponse } from "./parser.mjs";
|
|
12
|
-
const debugInspect = getDebug('ai:inspect');
|
|
13
|
-
async function autoGlmLocate(elementDescription, options, getSystemPrompt) {
|
|
14
|
-
const { context, modelRuntime } = options;
|
|
15
|
-
const screenshotBase64 = context.screenshot.base64;
|
|
16
|
-
assert(elementDescription, "cannot find the target element description");
|
|
17
|
-
const elementDescriptionText = extraTextFromUserPrompt(elementDescription);
|
|
18
|
-
const userInstructionPrompt = findElementPrompt(elementDescriptionText);
|
|
19
|
-
const locateImage = options.searchConfig?.image ?? {
|
|
20
|
-
imageBase64: screenshotBase64,
|
|
21
|
-
width: context.shotSize.width,
|
|
22
|
-
height: context.shotSize.height
|
|
23
|
-
};
|
|
24
|
-
const imagePayload = locateImage.imageBase64;
|
|
25
|
-
const imageWidth = locateImage.width;
|
|
26
|
-
const imageHeight = locateImage.height;
|
|
27
|
-
const msgs = [
|
|
28
|
-
{
|
|
29
|
-
role: 'system',
|
|
30
|
-
content: getSystemPrompt()
|
|
31
|
-
},
|
|
32
|
-
{
|
|
33
|
-
role: 'user',
|
|
34
|
-
content: [
|
|
35
|
-
{
|
|
36
|
-
type: 'image_url',
|
|
37
|
-
image_url: {
|
|
38
|
-
url: imagePayload,
|
|
39
|
-
detail: 'high'
|
|
40
|
-
}
|
|
41
|
-
},
|
|
42
|
-
{
|
|
43
|
-
type: 'text',
|
|
44
|
-
text: `Tap: ${userInstructionPrompt}`
|
|
45
|
-
}
|
|
46
|
-
]
|
|
47
|
-
}
|
|
48
|
-
];
|
|
49
|
-
if ('string' != typeof elementDescription) {
|
|
50
|
-
const addOns = await promptsToChatParam({
|
|
51
|
-
images: elementDescription.images,
|
|
52
|
-
convertHttpImage2Base64: elementDescription.convertHttpImage2Base64
|
|
53
|
-
});
|
|
54
|
-
msgs.push(...addOns);
|
|
55
|
-
}
|
|
56
|
-
const { content: rawResponseContent, usage, rawChoiceMessage } = await callAIWithStringResponse(msgs, modelRuntime, {
|
|
57
|
-
abortSignal: options.abortSignal
|
|
58
|
-
});
|
|
59
|
-
debugInspect('auto-glm rawResponse:', rawResponseContent);
|
|
60
|
-
const parsed = parseAutoGLMLocateResponse(rawResponseContent);
|
|
61
|
-
debugInspect('auto-glm thinking:', parsed.think);
|
|
62
|
-
debugInspect('auto-glm coordinates:', parsed.coordinates);
|
|
63
|
-
let resRect;
|
|
64
|
-
let matchedElement;
|
|
65
|
-
let errors = [];
|
|
66
|
-
if (parsed.error || !parsed.coordinates) {
|
|
67
|
-
errors = [
|
|
68
|
-
parsed.error || 'Failed to parse auto-glm response'
|
|
69
|
-
];
|
|
70
|
-
debugInspect('auto-glm parse error:', errors[0]);
|
|
71
|
-
} else {
|
|
72
|
-
const { x, y } = parsed.coordinates;
|
|
73
|
-
debugInspect('auto-glm coordinates [0-999]:', {
|
|
74
|
-
x,
|
|
75
|
-
y
|
|
76
|
-
});
|
|
77
|
-
const ctx = {
|
|
78
|
-
preparedSize: {
|
|
79
|
-
width: imageWidth,
|
|
80
|
-
height: imageHeight
|
|
81
|
-
}
|
|
82
|
-
};
|
|
83
|
-
const targetPixelBbox = finalizePixelBbox(mapLocateResultToPixelBboxByCoordinates({
|
|
84
|
-
type: 'point',
|
|
85
|
-
coordinates: [
|
|
86
|
-
x,
|
|
87
|
-
y
|
|
88
|
-
]
|
|
89
|
-
}, ctx, {
|
|
90
|
-
shape: 'point',
|
|
91
|
-
order: 'xy',
|
|
92
|
-
normalizedBy: 1000
|
|
93
|
-
}), parsed.coordinates, ctx);
|
|
94
|
-
resRect = pixelBboxToRect(mapSearchAreaPixelBboxToOriginalPixelBbox(targetPixelBbox, options.searchConfig?.mapping));
|
|
95
|
-
debugInspect('auto-glm resRect:', resRect);
|
|
96
|
-
const element = generateElementByRect(resRect, elementDescriptionText);
|
|
97
|
-
if (element) matchedElement = element;
|
|
98
|
-
}
|
|
1
|
+
import { getTapLocatedPixelBbox } from "../../shared/planning-action.mjs";
|
|
2
|
+
import { getAutoGLMChineseLocatePrompt, getAutoGLMMultilingualLocatePrompt } from "./prompt.mjs";
|
|
3
|
+
function createAutoGlmPlanningTapLocator(isMultilingual) {
|
|
99
4
|
return {
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
element: matchedElement,
|
|
103
|
-
errors
|
|
104
|
-
},
|
|
105
|
-
rawResponse: rawResponseContent,
|
|
106
|
-
rawChoiceMessage,
|
|
107
|
-
usage,
|
|
108
|
-
reasoning_content: parsed.think
|
|
5
|
+
buildSystemPrompt: ()=>isMultilingual ? getAutoGLMMultilingualLocatePrompt() : getAutoGLMChineseLocatePrompt(),
|
|
6
|
+
getLocatedPixelBbox: getTapLocatedPixelBbox
|
|
109
7
|
};
|
|
110
8
|
}
|
|
111
|
-
export {
|
|
9
|
+
export { createAutoGlmPlanningTapLocator };
|
|
112
10
|
|
|
113
11
|
//# sourceMappingURL=locate.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/auto-glm/locate.mjs","sources":["../../../../../src/ai-model/models/auto-glm/locate.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"ai-model/models/auto-glm/locate.mjs","sources":["../../../../../src/ai-model/models/auto-glm/locate.ts"],"sourcesContent":["import type { PlanningTapLocatorDefinition } from '../../model-adapter/types';\nimport { getTapLocatedPixelBbox } from '../../shared/planning-action';\nimport {\n getAutoGLMChineseLocatePrompt,\n getAutoGLMMultilingualLocatePrompt,\n} from './prompt';\n\nexport function createAutoGlmPlanningTapLocator(\n isMultilingual: boolean,\n): PlanningTapLocatorDefinition {\n return {\n buildSystemPrompt: () =>\n isMultilingual\n ? getAutoGLMMultilingualLocatePrompt()\n : getAutoGLMChineseLocatePrompt(),\n getLocatedPixelBbox: getTapLocatedPixelBbox,\n };\n}\n"],"names":["createAutoGlmPlanningTapLocator","isMultilingual","getAutoGLMMultilingualLocatePrompt","getAutoGLMChineseLocatePrompt","getTapLocatedPixelBbox"],"mappings":";;AAOO,SAASA,gCACdC,cAAuB;IAEvB,OAAO;QACL,mBAAmB,IACjBA,iBACIC,uCACAC;QACN,qBAAqBC;IACvB;AACF"}
|
|
@@ -7,7 +7,7 @@ const extractValueAfter = (src, key)=>{
|
|
|
7
7
|
if (rest.endsWith('")')) rest = rest.slice(0, -2);
|
|
8
8
|
return rest;
|
|
9
9
|
};
|
|
10
|
-
function
|
|
10
|
+
function parseAutoGLMPlanningAction(response) {
|
|
11
11
|
debug('Parsing action:', response);
|
|
12
12
|
let trimmedResponse = '';
|
|
13
13
|
try {
|
|
@@ -170,70 +170,48 @@ function parseAction(response) {
|
|
|
170
170
|
}
|
|
171
171
|
}
|
|
172
172
|
function parseAutoGLMResponse(content) {
|
|
173
|
+
let parsedResponse;
|
|
173
174
|
if (content.includes('finish(message=')) {
|
|
174
175
|
const parts = content.split('finish(message=');
|
|
175
176
|
const think = parts[0].trim();
|
|
176
177
|
const actionContent = `finish(message=${parts[1]}`;
|
|
177
|
-
|
|
178
|
+
parsedResponse = {
|
|
178
179
|
think,
|
|
179
180
|
content: actionContent
|
|
180
181
|
};
|
|
181
|
-
}
|
|
182
|
-
if (content.includes('do(action=')) {
|
|
182
|
+
} else if (content.includes('do(action=')) {
|
|
183
183
|
const parts = content.split('do(action=');
|
|
184
184
|
const think = parts[0].trim();
|
|
185
185
|
const actionContent = `do(action=${parts[1]}`;
|
|
186
|
-
|
|
186
|
+
parsedResponse = {
|
|
187
187
|
think,
|
|
188
188
|
content: actionContent
|
|
189
189
|
};
|
|
190
|
-
}
|
|
191
|
-
if (content.includes('<answer>')) {
|
|
190
|
+
} else if (content.includes('<answer>')) {
|
|
192
191
|
const parts = content.split('<answer>');
|
|
193
192
|
const think = parts[0].replace(/<think>/g, '').replace(/<\/think>/g, '').trim();
|
|
194
193
|
const actionContent = parts[1].replace(/<\/answer>/g, '').trim();
|
|
195
|
-
|
|
194
|
+
parsedResponse = {
|
|
196
195
|
think,
|
|
197
196
|
content: actionContent
|
|
198
197
|
};
|
|
199
|
-
}
|
|
200
|
-
return {
|
|
198
|
+
} else parsedResponse = {
|
|
201
199
|
think: '',
|
|
202
200
|
content
|
|
203
201
|
};
|
|
202
|
+
debug('autoGLM rawResponse:', content);
|
|
203
|
+
debug('thinking in response:', parsedResponse.think);
|
|
204
|
+
debug('action in response:', parsedResponse.content);
|
|
205
|
+
return parsedResponse;
|
|
204
206
|
}
|
|
205
|
-
function
|
|
206
|
-
const
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
207
|
+
function parseAutoGLMPlanningResponse(content) {
|
|
208
|
+
const response = parseAutoGLMResponse(content);
|
|
209
|
+
const action = parseAutoGLMPlanningAction(response);
|
|
210
|
+
return {
|
|
211
|
+
response,
|
|
212
|
+
action
|
|
211
213
|
};
|
|
212
|
-
try {
|
|
213
|
-
const elementMatch = actionContent.match(/element=\[(\d+),(\d+)\]/);
|
|
214
|
-
if (!elementMatch) return {
|
|
215
|
-
think,
|
|
216
|
-
coordinates: null,
|
|
217
|
-
error: `Failed to extract element coordinates from auto-glm response: ${actionContent}`
|
|
218
|
-
};
|
|
219
|
-
const x = Number(elementMatch[1]);
|
|
220
|
-
const y = Number(elementMatch[2]);
|
|
221
|
-
return {
|
|
222
|
-
think,
|
|
223
|
-
coordinates: {
|
|
224
|
-
x,
|
|
225
|
-
y
|
|
226
|
-
}
|
|
227
|
-
};
|
|
228
|
-
} catch (e) {
|
|
229
|
-
const errorMessage = e instanceof Error ? e.message : String(e);
|
|
230
|
-
return {
|
|
231
|
-
think,
|
|
232
|
-
coordinates: null,
|
|
233
|
-
error: `Failed to parse coordinates "${actionContent}" with errorMessage: ${errorMessage}`
|
|
234
|
-
};
|
|
235
|
-
}
|
|
236
214
|
}
|
|
237
|
-
export { extractValueAfter,
|
|
215
|
+
export { extractValueAfter, parseAutoGLMPlanningAction, parseAutoGLMPlanningResponse, parseAutoGLMResponse };
|
|
238
216
|
|
|
239
217
|
//# sourceMappingURL=parser.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/auto-glm/parser.mjs","sources":["../../../../../src/ai-model/models/auto-glm/parser.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport type { ParsedAction } from './actions';\n\nconst debug = getDebug('auto-glm-parser');\n\n// Do not rely on regex extraction here; regex can fail on malformed input.\n// Bad Case: finish(message=\"Finished! Now There is a contact whose name is \\\"Tom\\\" in the list.\")\nexport const extractValueAfter = (src: string, key: string): string => {\n const idx = src.indexOf(key);\n if (idx === -1) {\n throw new Error(`Missing key ${key} in action payload ${src}`);\n }\n let rest = src.slice(idx + key.length).trim();\n if (rest.endsWith('\")')) {\n rest = rest.slice(0, -2);\n }\n return rest;\n};\n\nexport function parseAction(response: {\n think: string;\n content: string;\n}): ParsedAction {\n debug('Parsing action:', response);\n let trimmedResponse = '';\n try {\n trimmedResponse = response.content.trim();\n\n if (\n trimmedResponse.startsWith('do(action=\"Type\"') ||\n trimmedResponse.startsWith('do(action=\"Type_Name\"')\n ) {\n const text = extractValueAfter(trimmedResponse, 'text=\"');\n return {\n _metadata: 'do',\n action: 'Type',\n text,\n think: response.think,\n } as ParsedAction;\n }\n\n if (trimmedResponse.startsWith('finish(message=')) {\n let message = extractValueAfter(trimmedResponse, 'finish(message=\"');\n if (message.endsWith(')')) message = message.slice(0, -1);\n return {\n _metadata: 'finish',\n message,\n think: response.think,\n } as ParsedAction;\n }\n\n if (trimmedResponse.startsWith('do(')) {\n const actionMatch = trimmedResponse.match(/do\\(action=\"([^\"]+)\"/);\n if (!actionMatch)\n throw new Error(\n `Failed to extract action type from do() call; raw=\"${trimmedResponse}\"`,\n );\n const actionType = actionMatch[1];\n\n const baseAction = { _metadata: 'do' as const, think: response.think };\n switch (actionType) {\n case 'Tap': {\n const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n if (!elementMatch)\n throw new Error(\n `Failed to extract element coordinates for Tap; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Tap',\n element: [Number(elementMatch[1]), Number(elementMatch[2])],\n } as ParsedAction;\n }\n case 'Double Tap': {\n const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n if (!elementMatch)\n throw new Error(\n `Failed to extract element coordinates for Double Tap; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Double Tap',\n element: [Number(elementMatch[1]), Number(elementMatch[2])],\n } as ParsedAction;\n }\n case 'Swipe': {\n const startMatch = trimmedResponse.match(/start=\\[(\\d+),(\\d+)\\]/);\n const endMatch = trimmedResponse.match(/end=\\[(\\d+),(\\d+)\\]/);\n if (!startMatch || !endMatch)\n throw new Error(\n `Failed to extract start/end coordinates for Swipe; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Swipe',\n start: [Number(startMatch[1]), Number(startMatch[2])],\n end: [Number(endMatch[1]), Number(endMatch[2])],\n } as ParsedAction;\n }\n case 'Long Press': {\n const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n if (!elementMatch)\n throw new Error(\n `Failed to extract element coordinates for Long Press; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Long Press',\n element: [Number(elementMatch[1]), Number(elementMatch[2])],\n } as ParsedAction;\n }\n case 'Launch': {\n const app = extractValueAfter(trimmedResponse, 'app=\"');\n return { ...baseAction, action: 'Launch', app } as ParsedAction;\n }\n case 'Back': {\n return { ...baseAction, action: 'Back' } as ParsedAction;\n }\n case 'Home': {\n return { ...baseAction, action: 'Home' } as ParsedAction;\n }\n case 'Wait': {\n const durationMatch = trimmedResponse.match(\n /duration=(?:[\"\\[])?(\\d+)/,\n );\n if (!durationMatch) {\n throw new Error(\n `Failed to extract duration for Wait; raw=\"${trimmedResponse}\"`,\n );\n }\n const seconds = Number.parseInt(durationMatch[1], 10);\n const durationMs = seconds * 1000;\n return {\n ...baseAction,\n action: 'Wait',\n durationMs,\n } as ParsedAction;\n }\n case 'Interact': {\n return { ...baseAction, action: 'Interact' } as ParsedAction;\n }\n case 'Call_API': {\n const instruction = extractValueAfter(\n trimmedResponse,\n 'instruction=\"',\n );\n return {\n ...baseAction,\n action: 'Call_API',\n instruction,\n } as ParsedAction;\n }\n case 'Take_over': {\n const message = extractValueAfter(trimmedResponse, 'message=\"');\n return {\n ...baseAction,\n action: 'Take_over',\n message,\n } as ParsedAction;\n }\n case 'Note': {\n const message = extractValueAfter(trimmedResponse, 'message=\"');\n return {\n ...baseAction,\n action: 'Note',\n message,\n } as ParsedAction;\n }\n default:\n throw new Error(\n `Unknown action type: ${actionType}; raw=\"${trimmedResponse}\"`,\n );\n }\n }\n throw new Error(`Failed to parse action: ${trimmedResponse}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Failed to parse action: ${errorMessage}; raw=\"${trimmedResponse}\"`,\n );\n }\n}\n\nexport function parseAutoGLMResponse(content: string): {\n think: string;\n content: string;\n} {\n if (content.includes('finish(message=')) {\n const parts = content.split('finish(message=');\n const think = parts[0].trim();\n const actionContent = `finish(message=${parts[1]}`;\n return { think, content: actionContent };\n }\n if (content.includes('do(action=')) {\n const parts = content.split('do(action=');\n const think = parts[0].trim();\n const actionContent = `do(action=${parts[1]}`;\n return { think, content: actionContent };\n }\n if (content.includes('<answer>')) {\n const parts = content.split('<answer>');\n const think = parts[0]\n .replace(/<think>/g, '')\n .replace(/<\\/think>/g, '')\n .trim();\n const actionContent = parts[1].replace(/<\\/answer>/g, '').trim();\n return { think, content: actionContent };\n }\n return { think: '', content };\n}\n\nexport function parseAutoGLMLocateResponse(rawResponse: string): {\n think: string;\n coordinates: { x: number; y: number } | null;\n error?: string;\n} {\n const { think, content: actionContent } = parseAutoGLMResponse(rawResponse);\n if (!actionContent.startsWith('do(action=\"Tap\"')) {\n return {\n think,\n coordinates: null,\n error: `Unexpected action type in auto-glm locate response: ${actionContent}`,\n };\n }\n try {\n const elementMatch = actionContent.match(/element=\\[(\\d+),(\\d+)\\]/);\n if (!elementMatch) {\n return {\n think,\n coordinates: null,\n error: `Failed to extract element coordinates from auto-glm response: ${actionContent}`,\n };\n }\n const x = Number(elementMatch[1]);\n const y = Number(elementMatch[2]);\n return { think, coordinates: { x, y } };\n } catch (e) {\n const errorMessage = e instanceof Error ? e.message : String(e);\n return {\n think,\n coordinates: null,\n error: `Failed to parse coordinates \"${actionContent}\" with errorMessage: ${errorMessage}`,\n };\n }\n}\n"],"names":["debug","getDebug","extractValueAfter","src","key","idx","Error","rest","parseAction","response","trimmedResponse","text","message","actionMatch","actionType","baseAction","elementMatch","Number","startMatch","endMatch","app","durationMatch","seconds","durationMs","instruction","error","errorMessage","String","parseAutoGLMResponse","content","parts","think","actionContent","parseAutoGLMLocateResponse","rawResponse","x","y","e"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/models/auto-glm/parser.mjs","sources":["../../../../../src/ai-model/models/auto-glm/parser.ts"],"sourcesContent":["import { getDebug } from '@midscene/shared/logger';\nimport type { AutoGLMParsedAction } from './actions';\n\nconst debug = getDebug('auto-glm-parser');\n\n// Do not rely on regex extraction here; regex can fail on malformed input.\n// Bad Case: finish(message=\"Finished! Now There is a contact whose name is \\\"Tom\\\" in the list.\")\nexport const extractValueAfter = (src: string, key: string): string => {\n const idx = src.indexOf(key);\n if (idx === -1) {\n throw new Error(`Missing key ${key} in action payload ${src}`);\n }\n let rest = src.slice(idx + key.length).trim();\n if (rest.endsWith('\")')) {\n rest = rest.slice(0, -2);\n }\n return rest;\n};\n\nexport function parseAutoGLMPlanningAction(response: {\n think: string;\n content: string;\n}): AutoGLMParsedAction {\n debug('Parsing action:', response);\n let trimmedResponse = '';\n try {\n trimmedResponse = response.content.trim();\n\n if (\n trimmedResponse.startsWith('do(action=\"Type\"') ||\n trimmedResponse.startsWith('do(action=\"Type_Name\"')\n ) {\n const text = extractValueAfter(trimmedResponse, 'text=\"');\n return {\n _metadata: 'do',\n action: 'Type',\n text,\n think: response.think,\n } as AutoGLMParsedAction;\n }\n\n if (trimmedResponse.startsWith('finish(message=')) {\n let message = extractValueAfter(trimmedResponse, 'finish(message=\"');\n if (message.endsWith(')')) message = message.slice(0, -1);\n return {\n _metadata: 'finish',\n message,\n think: response.think,\n } as AutoGLMParsedAction;\n }\n\n if (trimmedResponse.startsWith('do(')) {\n const actionMatch = trimmedResponse.match(/do\\(action=\"([^\"]+)\"/);\n if (!actionMatch)\n throw new Error(\n `Failed to extract action type from do() call; raw=\"${trimmedResponse}\"`,\n );\n const actionType = actionMatch[1];\n\n const baseAction = { _metadata: 'do' as const, think: response.think };\n switch (actionType) {\n case 'Tap': {\n const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n if (!elementMatch)\n throw new Error(\n `Failed to extract element coordinates for Tap; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Tap',\n element: [Number(elementMatch[1]), Number(elementMatch[2])],\n } as AutoGLMParsedAction;\n }\n case 'Double Tap': {\n const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n if (!elementMatch)\n throw new Error(\n `Failed to extract element coordinates for Double Tap; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Double Tap',\n element: [Number(elementMatch[1]), Number(elementMatch[2])],\n } as AutoGLMParsedAction;\n }\n case 'Swipe': {\n const startMatch = trimmedResponse.match(/start=\\[(\\d+),(\\d+)\\]/);\n const endMatch = trimmedResponse.match(/end=\\[(\\d+),(\\d+)\\]/);\n if (!startMatch || !endMatch)\n throw new Error(\n `Failed to extract start/end coordinates for Swipe; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Swipe',\n start: [Number(startMatch[1]), Number(startMatch[2])],\n end: [Number(endMatch[1]), Number(endMatch[2])],\n } as AutoGLMParsedAction;\n }\n case 'Long Press': {\n const elementMatch = trimmedResponse.match(/element=\\[(\\d+),(\\d+)\\]/);\n if (!elementMatch)\n throw new Error(\n `Failed to extract element coordinates for Long Press; raw=\"${trimmedResponse}\"`,\n );\n return {\n ...baseAction,\n action: 'Long Press',\n element: [Number(elementMatch[1]), Number(elementMatch[2])],\n } as AutoGLMParsedAction;\n }\n case 'Launch': {\n const app = extractValueAfter(trimmedResponse, 'app=\"');\n return {\n ...baseAction,\n action: 'Launch',\n app,\n } as AutoGLMParsedAction;\n }\n case 'Back': {\n return { ...baseAction, action: 'Back' } as AutoGLMParsedAction;\n }\n case 'Home': {\n return { ...baseAction, action: 'Home' } as AutoGLMParsedAction;\n }\n case 'Wait': {\n const durationMatch = trimmedResponse.match(\n /duration=(?:[\"\\[])?(\\d+)/,\n );\n if (!durationMatch) {\n throw new Error(\n `Failed to extract duration for Wait; raw=\"${trimmedResponse}\"`,\n );\n }\n const seconds = Number.parseInt(durationMatch[1], 10);\n const durationMs = seconds * 1000;\n return {\n ...baseAction,\n action: 'Wait',\n durationMs,\n } as AutoGLMParsedAction;\n }\n case 'Interact': {\n return { ...baseAction, action: 'Interact' } as AutoGLMParsedAction;\n }\n case 'Call_API': {\n const instruction = extractValueAfter(\n trimmedResponse,\n 'instruction=\"',\n );\n return {\n ...baseAction,\n action: 'Call_API',\n instruction,\n } as AutoGLMParsedAction;\n }\n case 'Take_over': {\n const message = extractValueAfter(trimmedResponse, 'message=\"');\n return {\n ...baseAction,\n action: 'Take_over',\n message,\n } as AutoGLMParsedAction;\n }\n case 'Note': {\n const message = extractValueAfter(trimmedResponse, 'message=\"');\n return {\n ...baseAction,\n action: 'Note',\n message,\n } as AutoGLMParsedAction;\n }\n default:\n throw new Error(\n `Unknown action type: ${actionType}; raw=\"${trimmedResponse}\"`,\n );\n }\n }\n throw new Error(`Failed to parse action: ${trimmedResponse}`);\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n throw new Error(\n `Failed to parse action: ${errorMessage}; raw=\"${trimmedResponse}\"`,\n );\n }\n}\n\nexport function parseAutoGLMResponse(content: string): {\n think: string;\n content: string;\n} {\n let parsedResponse: { think: string; content: string };\n\n if (content.includes('finish(message=')) {\n const parts = content.split('finish(message=');\n const think = parts[0].trim();\n const actionContent = `finish(message=${parts[1]}`;\n parsedResponse = { think, content: actionContent };\n } else if (content.includes('do(action=')) {\n const parts = content.split('do(action=');\n const think = parts[0].trim();\n const actionContent = `do(action=${parts[1]}`;\n parsedResponse = { think, content: actionContent };\n } else if (content.includes('<answer>')) {\n const parts = content.split('<answer>');\n const think = parts[0]\n .replace(/<think>/g, '')\n .replace(/<\\/think>/g, '')\n .trim();\n const actionContent = parts[1].replace(/<\\/answer>/g, '').trim();\n parsedResponse = { think, content: actionContent };\n } else {\n parsedResponse = { think: '', content };\n }\n\n debug('autoGLM rawResponse:', content);\n debug('thinking in response:', parsedResponse.think);\n debug('action in response:', parsedResponse.content);\n return parsedResponse;\n}\n\nexport function parseAutoGLMPlanningResponse(content: string): {\n response: ReturnType<typeof parseAutoGLMResponse>;\n action: AutoGLMParsedAction;\n} {\n const response = parseAutoGLMResponse(content);\n const action = parseAutoGLMPlanningAction(response);\n return { response, action };\n}\n"],"names":["debug","getDebug","extractValueAfter","src","key","idx","Error","rest","parseAutoGLMPlanningAction","response","trimmedResponse","text","message","actionMatch","actionType","baseAction","elementMatch","Number","startMatch","endMatch","app","durationMatch","seconds","durationMs","instruction","error","errorMessage","String","parseAutoGLMResponse","content","parsedResponse","parts","think","actionContent","parseAutoGLMPlanningResponse","action"],"mappings":"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"}
|
|
@@ -1,76 +1,33 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { AIResponseParseError, callAIWithStringResponse } from "../../service-caller/index.mjs";
|
|
1
|
+
import { assert } from "@midscene/shared/utils";
|
|
2
|
+
import { createCoordinateDistanceToPixels } from "../../shared/model-locate-result/index.mjs";
|
|
4
3
|
import { transformAutoGLMAction } from "./actions.mjs";
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
const { conversationHistory, context, actionContext } = options;
|
|
9
|
-
const systemPrompt = getSystemPrompt() + (actionContext ? `<high_priority_knowledge>${actionContext}</high_priority_knowledge>` : '');
|
|
10
|
-
const imagePayloadBase64 = context.screenshot.base64;
|
|
11
|
-
const userInstructionText = userPromptToString(userInstruction);
|
|
12
|
-
const referenceImageMessages = options.referenceImageMessages ?? [];
|
|
13
|
-
const userInstructionMessage = {
|
|
14
|
-
role: 'user',
|
|
15
|
-
content: [
|
|
16
|
-
{
|
|
17
|
-
type: 'text',
|
|
18
|
-
text: userInstructionText
|
|
19
|
-
}
|
|
20
|
-
]
|
|
21
|
-
};
|
|
22
|
-
conversationHistory.append({
|
|
23
|
-
role: 'user',
|
|
24
|
-
content: [
|
|
25
|
-
{
|
|
26
|
-
type: 'image_url',
|
|
27
|
-
image_url: {
|
|
28
|
-
url: imagePayloadBase64
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
]
|
|
32
|
-
});
|
|
33
|
-
const msgs = [
|
|
34
|
-
{
|
|
35
|
-
role: 'system',
|
|
36
|
-
content: systemPrompt
|
|
37
|
-
},
|
|
38
|
-
userInstructionMessage,
|
|
39
|
-
...referenceImageMessages,
|
|
40
|
-
...conversationHistory.snapshot(1)
|
|
41
|
-
];
|
|
42
|
-
const { content: rawResponse, usage, rawChoiceMessage } = await callAIWithStringResponse(msgs, options.modelRuntime, {
|
|
43
|
-
abortSignal: options.abortSignal
|
|
44
|
-
});
|
|
45
|
-
debug('autoGLMPlanning rawResponse:', rawResponse);
|
|
46
|
-
let parsedResponse;
|
|
47
|
-
let transformedActions;
|
|
48
|
-
try {
|
|
49
|
-
parsedResponse = parseAutoGLMResponse(rawResponse);
|
|
50
|
-
debug('thinking in response:', parsedResponse.think);
|
|
51
|
-
debug('action in response:', parsedResponse.content);
|
|
52
|
-
const parsedAction = parseAction(parsedResponse);
|
|
53
|
-
debug('Parsed action object:', parsedAction);
|
|
54
|
-
transformedActions = transformAutoGLMAction(parsedAction, context.shotSize, options.actionSpace);
|
|
55
|
-
debug('Transformed actions:', transformedActions);
|
|
56
|
-
} catch (parseError) {
|
|
57
|
-
const errorMessage = parseError instanceof Error ? parseError.message : String(parseError);
|
|
58
|
-
throw new AIResponseParseError(`Parse error: ${errorMessage}`, JSON.stringify(rawResponse, void 0, 2), usage, rawChoiceMessage);
|
|
59
|
-
}
|
|
60
|
-
conversationHistory.append({
|
|
61
|
-
role: 'assistant',
|
|
62
|
-
content: `<think>${parsedResponse.think}</think><answer>${parsedResponse.content}</answer>`
|
|
63
|
-
});
|
|
64
|
-
const shouldContinuePlanning = !parsedResponse.content.startsWith('finish(');
|
|
4
|
+
import { parseAutoGLMPlanningResponse } from "./parser.mjs";
|
|
5
|
+
import { getAutoGLMChinesePlanPrompt, getAutoGLMMultilingualPlanPrompt } from "./prompt.mjs";
|
|
6
|
+
function createAutoGlmPlanner(isMultilingual) {
|
|
65
7
|
return {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
8
|
+
messages: {
|
|
9
|
+
systemPromptPlacement: 'system-message',
|
|
10
|
+
buildSystemPrompt: ()=>isMultilingual ? getAutoGLMMultilingualPlanPrompt() : getAutoGLMChinesePlanPrompt(),
|
|
11
|
+
historyImageLimit: 1,
|
|
12
|
+
buildAssistantContent: (parsedResponse)=>`<think>${parsedResponse.response.think}</think><answer>${parsedResponse.response.content}</answer>`
|
|
13
|
+
},
|
|
14
|
+
coordinates: {
|
|
15
|
+
shape: 'point',
|
|
16
|
+
order: 'xy',
|
|
17
|
+
normalizedBy: 1000
|
|
18
|
+
},
|
|
19
|
+
parseResponse: (rawResponse)=>parseAutoGLMPlanningResponse(rawResponse),
|
|
20
|
+
transformActions: (parsedResponse, { options, coordinateSystem })=>{
|
|
21
|
+
assert(coordinateSystem, 'Auto-GLM planning requires coordinate system');
|
|
22
|
+
return transformAutoGLMAction(parsedResponse.action, {
|
|
23
|
+
actionSpace: options.actionSpace,
|
|
24
|
+
coordinateDistanceToPixels: createCoordinateDistanceToPixels(options.context.shotSize, coordinateSystem)
|
|
25
|
+
});
|
|
26
|
+
},
|
|
27
|
+
shouldContinuePlanning: (parsedResponse)=>'finish' !== parsedResponse.action._metadata,
|
|
28
|
+
buildResponseLog: (_parsedResponse, rawResponse)=>rawResponse
|
|
72
29
|
};
|
|
73
30
|
}
|
|
74
|
-
export {
|
|
31
|
+
export { createAutoGlmPlanner };
|
|
75
32
|
|
|
76
33
|
//# sourceMappingURL=planning.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/auto-glm/planning.mjs","sources":["../../../../../src/ai-model/models/auto-glm/planning.ts"],"sourcesContent":["import {
|
|
1
|
+
{"version":3,"file":"ai-model/models/auto-glm/planning.mjs","sources":["../../../../../src/ai-model/models/auto-glm/planning.ts"],"sourcesContent":["import { assert } from '@midscene/shared/utils';\nimport type { CustomPlanningDefinition } from '../../model-adapter/custom-planning-types';\nimport { createCoordinateDistanceToPixels } from '../../shared/model-locate-result';\nimport { transformAutoGLMAction } from './actions';\nimport { parseAutoGLMPlanningResponse } from './parser';\nimport {\n getAutoGLMChinesePlanPrompt,\n getAutoGLMMultilingualPlanPrompt,\n} from './prompt';\n\ntype AutoGLMParsedResponse = ReturnType<typeof parseAutoGLMPlanningResponse>;\n\nexport function createAutoGlmPlanner(\n isMultilingual: boolean,\n): CustomPlanningDefinition<AutoGLMParsedResponse> {\n return {\n messages: {\n systemPromptPlacement: 'system-message',\n buildSystemPrompt: () =>\n isMultilingual\n ? getAutoGLMMultilingualPlanPrompt()\n : getAutoGLMChinesePlanPrompt(),\n historyImageLimit: 1,\n buildAssistantContent: (parsedResponse) =>\n `<think>${parsedResponse.response.think}</think><answer>${parsedResponse.response.content}</answer>`,\n },\n coordinates: {\n shape: 'point',\n order: 'xy',\n normalizedBy: 1000,\n },\n parseResponse: (rawResponse) => {\n return parseAutoGLMPlanningResponse(rawResponse);\n },\n transformActions: (parsedResponse, { options, coordinateSystem }) => {\n assert(coordinateSystem, 'Auto-GLM planning requires coordinate system');\n return transformAutoGLMAction(parsedResponse.action, {\n actionSpace: options.actionSpace,\n coordinateDistanceToPixels: createCoordinateDistanceToPixels(\n options.context.shotSize,\n coordinateSystem,\n ),\n });\n },\n shouldContinuePlanning: (parsedResponse) =>\n parsedResponse.action._metadata !== 'finish',\n buildResponseLog: (_parsedResponse, rawResponse) => rawResponse,\n };\n}\n"],"names":["createAutoGlmPlanner","isMultilingual","getAutoGLMMultilingualPlanPrompt","getAutoGLMChinesePlanPrompt","parsedResponse","rawResponse","parseAutoGLMPlanningResponse","options","coordinateSystem","assert","transformAutoGLMAction","createCoordinateDistanceToPixels","_parsedResponse"],"mappings":";;;;;AAYO,SAASA,qBACdC,cAAuB;IAEvB,OAAO;QACL,UAAU;YACR,uBAAuB;YACvB,mBAAmB,IACjBA,iBACIC,qCACAC;YACN,mBAAmB;YACnB,uBAAuB,CAACC,iBACtB,CAAC,OAAO,EAAEA,eAAe,QAAQ,CAAC,KAAK,CAAC,gBAAgB,EAAEA,eAAe,QAAQ,CAAC,OAAO,CAAC,SAAS,CAAC;QACxG;QACA,aAAa;YACX,OAAO;YACP,OAAO;YACP,cAAc;QAChB;QACA,eAAe,CAACC,cACPC,6BAA6BD;QAEtC,kBAAkB,CAACD,gBAAgB,EAAEG,OAAO,EAAEC,gBAAgB,EAAE;YAC9DC,OAAOD,kBAAkB;YACzB,OAAOE,uBAAuBN,eAAe,MAAM,EAAE;gBACnD,aAAaG,QAAQ,WAAW;gBAChC,4BAA4BI,iCAC1BJ,QAAQ,OAAO,CAAC,QAAQ,EACxBC;YAEJ;QACF;QACA,wBAAwB,CAACJ,iBACvBA,AAAoC,aAApCA,eAAe,MAAM,CAAC,SAAS;QACjC,kBAAkB,CAACQ,iBAAiBP,cAAgBA;IACtD;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/default.mjs","sources":["../../../../src/ai-model/models/default.ts"],"sourcesContent":["import type { ModelAdapterDefinition } from '
|
|
1
|
+
{"version":3,"file":"ai-model/models/default.mjs","sources":["../../../../src/ai-model/models/default.ts"],"sourcesContent":["import type { ModelAdapterDefinition } from '../model-adapter/types';\n\nexport const defaultOpenAICompatibleAdapterConfig: ModelAdapterDefinition = {\n chatCompletion: {\n unsupportedUserConfig: [\n 'reasoningEnabled',\n 'reasoningEffort',\n 'reasoningBudget',\n ],\n },\n};\n"],"names":["defaultOpenAICompatibleAdapterConfig"],"mappings":"AAEO,MAAMA,uCAA+D;IAC1E,gBAAgB;QACd,uBAAuB;YACrB;YACA;YACA;SACD;IACH;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/doubao.mjs","sources":["../../../../src/ai-model/models/doubao.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport { assert } from '@midscene/shared/utils';\nimport { jsonrepair } from 'jsonrepair';\nimport {\n extractJSONFromCodeBlock,\n safeParseJson,\n} from '../service-caller/json';\nimport {\n type LocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../shared/model-locate-result';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n JsonParserContext,\n JsonParserSource,\n ModelAdapterDefinition,\n} from './types';\n\nexport function normalizeDoubaoJsonObject(\n obj: any,\n context: Pick<JsonParserContext, 'preserveStringValueKeys'> = {},\n): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => normalizeDoubaoJsonObject(item, context));\n }\n\n if (typeof obj === 'object') {\n const normalized: any = {};\n for (const [key, value] of Object.entries(obj)) {\n const trimmedKey = key.trim();\n const preserveStringValue =\n context.preserveStringValueKeys?.includes(trimmedKey) ?? false;\n const normalizedValue =\n typeof value === 'string'\n ? preserveStringValue\n ? value\n : value.trim()\n : normalizeDoubaoJsonObject(value, context);\n normalized[trimmedKey] = normalizedValue;\n }\n return normalized;\n }\n\n return typeof obj === 'string' ? obj.trim() : obj;\n}\n\nexport function shouldRepairDoubaoLocateJson(source: JsonParserSource) {\n return (\n source === 'locate' ||\n source === 'section-locator' ||\n source === 'planning-action-param'\n );\n}\n\nexport function preprocessDoubaoLocateJson(input: string) {\n if (input.includes('bbox')) {\n while (/\\d+\\s+\\d+/.test(input)) {\n input = input.replace(/(\\d+)\\s+(\\d+)/g, '$1,$2');\n }\n }\n return input;\n}\n\nconst doubaoJsonParser: ModelAdapterDefinition['jsonParser'] = (\n raw,\n context = { source: 'generic-object' },\n) => {\n const { source } = context;\n try {\n return safeParseJson(raw, context);\n } catch (firstError) {\n if (!shouldRepairDoubaoLocateJson(source)) {\n throw firstError;\n }\n\n const jsonString = preprocessDoubaoLocateJson(\n extractJSONFromCodeBlock(raw),\n );\n try {\n return normalizeDoubaoJsonObject(\n JSON.parse(jsonrepair(jsonString)),\n context,\n );\n } catch (error) {\n throw Error(\n `failed to parse LLM response into JSON. Error - ${String(\n error ?? firstError ?? 'unknown error',\n )}. Response - \\n ${raw}`,\n );\n }\n }\n};\n\nexport function parseDoubaoRawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any);\n if (typeof bbox === 'string') {\n assert(\n /^(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)$/.test(bbox.trim()),\n `invalid bbox data string for doubao-vision mode: ${bbox}`,\n );\n const splitted = bbox.split(' ');\n if (splitted.length === 4) {\n return {\n type: 'bbox',\n coordinates: [\n Number(splitted[0]),\n Number(splitted[1]),\n Number(splitted[2]),\n Number(splitted[3]),\n ],\n };\n }\n throw new Error(`invalid bbox data string for doubao-vision mode: ${bbox}`);\n }\n\n let bboxList: number[] = [];\n if (Array.isArray(bbox) && typeof bbox[0] === 'string') {\n bbox.forEach((item) => {\n if (typeof item === 'string' && item.includes(',')) {\n const [x, y] = item.split(',');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else if (typeof item === 'string' && item.includes(' ')) {\n const [x, y] = item.split(' ');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else {\n bboxList.push(Number(item));\n }\n });\n } else {\n bboxList = bbox as number[];\n }\n\n if (bboxList.length === 4 || bboxList.length === 5) {\n return {\n type: 'bbox',\n coordinates: [bboxList[0], bboxList[1], bboxList[2], bboxList[3]],\n };\n }\n\n if (\n bboxList.length === 6 ||\n bboxList.length === 2 ||\n bboxList.length === 3 ||\n bboxList.length === 7\n ) {\n return { type: 'point', coordinates: [bboxList[0], bboxList[1]] };\n }\n\n if (bbox.length === 8) {\n return {\n type: 'bbox',\n coordinates: [bboxList[0], bboxList[1], bboxList[4], bboxList[5]],\n };\n }\n\n const msg = `invalid bbox data for doubao-vision mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n}\n\nconst buildDoubaoChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.thinking = {\n type: (reasoningEnabled ?? false) ? 'enabled' : 'disabled',\n };\n if (reasoningEffort) {\n modelSpecificConfig.reasoning_effort = reasoningEffort;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst doubaoVisionAdapter: ModelAdapterDefinition = {\n jsonParser: doubaoJsonParser,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildDoubaoChatCompletionParams,\n },\n locate: {\n resultAdapter: {\n coordinates: { shape: 'bbox', order: 'xy', normalizedBy: 1000 },\n parseRawLocateValue: parseDoubaoRawLocateValue,\n },\n },\n};\n\nexport const doubaoAdapters = {\n 'doubao-vision': doubaoVisionAdapter,\n 'doubao-seed': doubaoVisionAdapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'doubao-vision' | 'doubao-seed'\n>;\n"],"names":["normalizeDoubaoJsonObject","obj","context","Array","item","normalized","key","value","Object","trimmedKey","preserveStringValue","normalizedValue","shouldRepairDoubaoLocateJson","source","preprocessDoubaoLocateJson","input","doubaoJsonParser","raw","safeParseJson","firstError","jsonString","extractJSONFromCodeBlock","JSON","jsonrepair","error","Error","String","parseDoubaoRawLocateValue","bbox","unwrapCoordinateListLikeInput","assert","splitted","Number","bboxList","x","y","msg","buildDoubaoChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","undefined","modelSpecificConfig","doubaoVisionAdapter","doubaoAdapters"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"ai-model/models/doubao.mjs","sources":["../../../../src/ai-model/models/doubao.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport { assert } from '@midscene/shared/utils';\nimport { jsonrepair } from 'jsonrepair';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n JsonParserContext,\n JsonParserSource,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\nimport {\n extractJSONFromCodeBlock,\n safeParseJson,\n} from '../service-caller/json';\nimport {\n type LocateResultValue,\n unwrapCoordinateListLikeInput,\n} from '../shared/model-locate-result';\n\nexport function normalizeDoubaoJsonObject(\n obj: any,\n context: Pick<JsonParserContext, 'preserveStringValueKeys'> = {},\n): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (Array.isArray(obj)) {\n return obj.map((item) => normalizeDoubaoJsonObject(item, context));\n }\n\n if (typeof obj === 'object') {\n const normalized: any = {};\n for (const [key, value] of Object.entries(obj)) {\n const trimmedKey = key.trim();\n const preserveStringValue =\n context.preserveStringValueKeys?.includes(trimmedKey) ?? false;\n const normalizedValue =\n typeof value === 'string'\n ? preserveStringValue\n ? value\n : value.trim()\n : normalizeDoubaoJsonObject(value, context);\n normalized[trimmedKey] = normalizedValue;\n }\n return normalized;\n }\n\n return typeof obj === 'string' ? obj.trim() : obj;\n}\n\nexport function shouldRepairDoubaoLocateJson(source: JsonParserSource) {\n return (\n source === 'locate' ||\n source === 'section-locator' ||\n source === 'planning-action-param'\n );\n}\n\nexport function preprocessDoubaoLocateJson(input: string) {\n if (input.includes('bbox')) {\n while (/\\d+\\s+\\d+/.test(input)) {\n input = input.replace(/(\\d+)\\s+(\\d+)/g, '$1,$2');\n }\n }\n return input;\n}\n\nconst doubaoJsonParser: ModelAdapterDefinition['jsonParser'] = (\n raw,\n context = { source: 'generic-object' },\n) => {\n const { source } = context;\n try {\n return safeParseJson(raw, context);\n } catch (firstError) {\n if (!shouldRepairDoubaoLocateJson(source)) {\n throw firstError;\n }\n\n const jsonString = preprocessDoubaoLocateJson(\n extractJSONFromCodeBlock(raw),\n );\n try {\n return normalizeDoubaoJsonObject(\n JSON.parse(jsonrepair(jsonString)),\n context,\n );\n } catch (error) {\n throw Error(\n `failed to parse LLM response into JSON. Error - ${String(\n error ?? firstError ?? 'unknown error',\n )}. Response - \\n ${raw}`,\n );\n }\n }\n};\n\nexport function parseDoubaoRawLocateValue(input: unknown): LocateResultValue {\n const bbox = unwrapCoordinateListLikeInput(input as any);\n if (typeof bbox === 'string') {\n assert(\n /^(\\d+)\\s(\\d+)\\s(\\d+)\\s(\\d+)$/.test(bbox.trim()),\n `invalid bbox data string for doubao-vision mode: ${bbox}`,\n );\n const splitted = bbox.split(' ');\n if (splitted.length === 4) {\n return {\n type: 'bbox',\n coordinates: [\n Number(splitted[0]),\n Number(splitted[1]),\n Number(splitted[2]),\n Number(splitted[3]),\n ],\n };\n }\n throw new Error(`invalid bbox data string for doubao-vision mode: ${bbox}`);\n }\n\n let bboxList: number[] = [];\n if (Array.isArray(bbox) && typeof bbox[0] === 'string') {\n bbox.forEach((item) => {\n if (typeof item === 'string' && item.includes(',')) {\n const [x, y] = item.split(',');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else if (typeof item === 'string' && item.includes(' ')) {\n const [x, y] = item.split(' ');\n bboxList.push(Number(x.trim()), Number(y.trim()));\n } else {\n bboxList.push(Number(item));\n }\n });\n } else {\n bboxList = bbox as number[];\n }\n\n if (bboxList.length === 4 || bboxList.length === 5) {\n return {\n type: 'bbox',\n coordinates: [bboxList[0], bboxList[1], bboxList[2], bboxList[3]],\n };\n }\n\n if (\n bboxList.length === 6 ||\n bboxList.length === 2 ||\n bboxList.length === 3 ||\n bboxList.length === 7\n ) {\n return { type: 'point', coordinates: [bboxList[0], bboxList[1]] };\n }\n\n if (bbox.length === 8) {\n return {\n type: 'bbox',\n coordinates: [bboxList[0], bboxList[1], bboxList[4], bboxList[5]],\n };\n }\n\n const msg = `invalid bbox data for doubao-vision mode: ${JSON.stringify(bbox)} `;\n throw new Error(msg);\n}\n\nconst buildDoubaoChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.thinking = {\n type: (reasoningEnabled ?? false) ? 'enabled' : 'disabled',\n };\n if (reasoningEffort) {\n modelSpecificConfig.reasoning_effort = reasoningEffort;\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst doubaoVisionAdapter: ModelAdapterDefinition = {\n jsonParser: doubaoJsonParser,\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildDoubaoChatCompletionParams,\n },\n locate: {\n resultAdapter: {\n coordinates: { shape: 'bbox', order: 'xy', normalizedBy: 1000 },\n parseRawLocateValue: parseDoubaoRawLocateValue,\n },\n },\n};\n\nexport const doubaoAdapters = {\n 'doubao-vision': doubaoVisionAdapter,\n 'doubao-seed': doubaoVisionAdapter,\n} satisfies Pick<\n Record<TModelFamily, ModelAdapterDefinition>,\n 'doubao-vision' | 'doubao-seed'\n>;\n"],"names":["normalizeDoubaoJsonObject","obj","context","Array","item","normalized","key","value","Object","trimmedKey","preserveStringValue","normalizedValue","shouldRepairDoubaoLocateJson","source","preprocessDoubaoLocateJson","input","doubaoJsonParser","raw","safeParseJson","firstError","jsonString","extractJSONFromCodeBlock","JSON","jsonrepair","error","Error","String","parseDoubaoRawLocateValue","bbox","unwrapCoordinateListLikeInput","assert","splitted","Number","bboxList","x","y","msg","buildDoubaoChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","undefined","modelSpecificConfig","doubaoVisionAdapter","doubaoAdapters"],"mappings":"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"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defaultExtractContentAndReasoning } from "
|
|
1
|
+
import { defaultExtractContentAndReasoning } from "../model-adapter/chat-completion.mjs";
|
|
2
2
|
const buildGeminiChatCompletionParams = (input)=>{
|
|
3
3
|
const { midsceneDefaults, userConfig, intent } = input;
|
|
4
4
|
const { reasoningEnabled, reasoningEffort } = userConfig;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/gemini.mjs","sources":["../../../../src/ai-model/models/gemini.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type OpenAI from 'openai';\nimport { defaultExtractContentAndReasoning } from '
|
|
1
|
+
{"version":3,"file":"ai-model/models/gemini.mjs","sources":["../../../../src/ai-model/models/gemini.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type OpenAI from 'openai';\nimport { defaultExtractContentAndReasoning } from '../model-adapter/chat-completion';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionContentSource,\n ChatCompletionParamsResult,\n ContentAndReasoning,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\n\ntype GeminiContentPart = Record<string, unknown> & {\n text?: string;\n thought?: boolean;\n};\n\ntype GeminiContentExtension = {\n content: string | null | GeminiContentPart[];\n reasoning_content?: string;\n extra_content?: unknown;\n};\n\ntype GeminiContentSource =\n | ChatCompletionContentSource\n | (Omit<OpenAI.Chat.Completions.ChatCompletionMessage, 'content'> &\n GeminiContentExtension)\n | (Omit<OpenAI.Chat.Completions.ChatCompletionChunk.Choice.Delta, 'content'> &\n GeminiContentExtension);\n\nconst buildGeminiChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig, intent } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n const modelSpecificConfig: {\n extra_body?: {\n google?: {\n thinking_config: Record<string, unknown>;\n };\n };\n reasoning_effort?: unknown;\n } = {};\n\n if (reasoningEnabled !== 'default') {\n if (reasoningEffort) {\n modelSpecificConfig.extra_body = {\n google: {\n thinking_config: {\n thinking_level: reasoningEffort,\n include_thoughts: true,\n },\n },\n };\n } else {\n if (intent === 'insight') {\n modelSpecificConfig.extra_body = {\n google: {\n thinking_config: {\n // In real Gemini tests, insight calls need `include_thoughts` to get\n // the model's thinking, and Gemini puts that thinking into `content`.\n include_thoughts: true,\n },\n },\n };\n }\n\n // Gemini 3.x cannot fully disable native thinking, so use the lowest\n // supported effort unless the user explicitly requests another level.\n modelSpecificConfig.reasoning_effort = 'minimal';\n }\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nconst extractInlineThought = (content: string): string | undefined => {\n const match = content.match(/<thought>([\\s\\S]*?)<\\/thought>/i);\n return match?.[1]?.trim() || undefined;\n};\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return !!value && typeof value === 'object' && !Array.isArray(value);\n}\n\ntype GeminiExtractedContent = {\n content: string;\n geminiReasoningContent: string;\n};\n\nconst formatReasoningContent = ({\n geminiReasoningContent,\n providerReasoningContent,\n}: {\n geminiReasoningContent: string;\n providerReasoningContent: string;\n}): string => {\n if (geminiReasoningContent && providerReasoningContent) {\n return `thoughtParts:${geminiReasoningContent}; reasoning_content:${providerReasoningContent}`;\n }\n\n return geminiReasoningContent || providerReasoningContent || '';\n};\n\nconst extractGeminiThoughtParts = (\n content: GeminiContentPart[],\n): GeminiExtractedContent => {\n const contentParts: string[] = [];\n const reasoningParts: string[] = [];\n\n for (const part of content) {\n if (!isRecord(part)) {\n continue;\n }\n\n const text = typeof part.text === 'string' ? part.text : undefined;\n if (!text) {\n continue;\n }\n\n if (part.thought === true) {\n reasoningParts.push(text);\n } else {\n contentParts.push(text);\n }\n }\n\n return {\n content: contentParts.join(''),\n geminiReasoningContent: reasoningParts.join(''),\n };\n};\n\nexport const extractGeminiContentAndReasoning = (\n message: GeminiContentSource | undefined,\n): ContentAndReasoning => {\n // Gemini native API exposes thought summaries in\n // `response.candidates[0].content.parts`, where each text part can carry\n // `thought: true`. Some OpenAI-compatible adapters may pass through a\n // native-like content-parts shape, even though the Gemini OpenAI\n // compatibility docs do not guarantee it.\n // Docs: https://ai.google.dev/gemini-api/docs/thinking#thought-summaries\n\n if (!message) {\n return {\n content: '',\n reasoning_content: '',\n };\n }\n\n if (Array.isArray(message.content)) {\n const extracted = extractGeminiThoughtParts(message.content);\n\n return {\n content: extracted.content,\n reasoning_content: formatReasoningContent({\n geminiReasoningContent: extracted.geminiReasoningContent,\n providerReasoningContent:\n typeof message.reasoning_content === 'string'\n ? message.reasoning_content\n : '',\n }),\n };\n }\n\n const result = defaultExtractContentAndReasoning(\n message as ChatCompletionContentSource,\n );\n // In real Gemini OpenAI-compatible responses we observed that\n // `include_thoughts` can still return a plain string `message.content`,\n // with the thought summary prepended as `<thought>...</thought>` before the\n // visible answer. Keep content unchanged, but extract that leading thought\n // text for report display.\n const geminiReasoningContent = extractInlineThought(result.content) || '';\n\n return {\n content: result.content,\n reasoning_content: formatReasoningContent({\n geminiReasoningContent,\n providerReasoningContent: result.reasoning_content,\n }),\n };\n};\n\nexport const geminiAdapters = {\n gemini: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEnabled', 'reasoningBudget'],\n buildChatCompletionParams: buildGeminiChatCompletionParams,\n extractContentAndReasoning: extractGeminiContentAndReasoning,\n },\n locate: {\n resultAdapter: {\n coordinates: { shape: 'bbox', order: 'yx', normalizedBy: 1000 },\n },\n },\n },\n} satisfies Pick<Record<TModelFamily, ModelAdapterDefinition>, 'gemini'>;\n"],"names":["buildGeminiChatCompletionParams","input","midsceneDefaults","userConfig","intent","reasoningEnabled","reasoningEffort","commonOverrideConfig","undefined","modelSpecificConfig","extractInlineThought","content","match","isRecord","value","Array","formatReasoningContent","geminiReasoningContent","providerReasoningContent","extractGeminiThoughtParts","contentParts","reasoningParts","part","text","extractGeminiContentAndReasoning","message","extracted","result","defaultExtractContentAndReasoning","geminiAdapters"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/glm.mjs","sources":["../../../../src/ai-model/models/glm.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '
|
|
1
|
+
{"version":3,"file":"ai-model/models/glm.mjs","sources":["../../../../src/ai-model/models/glm.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\n\nconst buildGlmChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n const modelSpecificConfig: Record<string, unknown> = {};\n\n if (reasoningEnabled !== 'default') {\n modelSpecificConfig.thinking = {\n type: (reasoningEnabled ?? false) ? 'enabled' : 'disabled',\n };\n }\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nexport const glmAdapters = {\n 'glm-v': {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEffort', 'reasoningBudget'],\n buildChatCompletionParams: buildGlmChatCompletionParams,\n },\n locate: {\n resultAdapter: {\n coordinates: { shape: 'bbox', order: 'xy', normalizedBy: 1000 },\n },\n },\n },\n} satisfies Pick<Record<TModelFamily, ModelAdapterDefinition>, 'glm-v'>;\n"],"names":["buildGlmChatCompletionParams","input","midsceneDefaults","userConfig","reasoningEnabled","commonOverrideConfig","undefined","modelSpecificConfig","glmAdapters"],"mappings":"AAOA,MAAMA,+BAA+B,CACnCC;IAEA,MAAM,EAAEC,gBAAgB,EAAEC,UAAU,EAAE,GAAGF;IACzC,MAAM,EAAEG,gBAAgB,EAAE,GAAGD;IAC7B,MAAME,uBAAgD,CAAC;IAEvD,IAAIF,AAA2BG,WAA3BH,WAAW,WAAW,EACxBE,qBAAqB,WAAW,GAAGF,WAAW,WAAW;IAG3D,MAAMI,sBAA+C,CAAC;IAEtD,IAAIH,AAAqB,cAArBA,kBACFG,oBAAoB,QAAQ,GAAG;QAC7B,MAAOH,oBAAoB,QAAS,YAAY;IAClD;IAGF,OAAO;QACL,QAAQ;YACN,GAAGF,gBAAgB;YACnB,GAAGG,oBAAoB;YACvB,GAAGE,mBAAmB;QACxB;IACF;AACF;AAEO,MAAMC,cAAc;IACzB,SAAS;QACP,gBAAgB;YACd,uBAAuB;gBAAC;gBAAmB;aAAkB;YAC7D,2BAA2BR;QAC7B;QACA,QAAQ;YACN,eAAe;gBACb,aAAa;oBAAE,OAAO;oBAAQ,OAAO;oBAAM,cAAc;gBAAK;YAChE;QACF;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/gpt.mjs","sources":["../../../../src/ai-model/models/gpt.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ImageDetail,\n ModelAdapterDefinition,\n} from '
|
|
1
|
+
{"version":3,"file":"ai-model/models/gpt.mjs","sources":["../../../../src/ai-model/models/gpt.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ImageDetail,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\n\nconst originalImageDetailForDefaultIntent = (\n input: ChatCompletionCallContext,\n): ImageDetail | undefined =>\n input.intent === 'default' || input.requiresOriginalImageDetail\n ? 'original'\n : undefined;\n\nconst buildGpt5ChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled, reasoningEffort } = userConfig;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n if (userConfig.temperature !== undefined) {\n commonOverrideConfig.temperature = userConfig.temperature;\n }\n\n const effectiveReasoningEffort =\n reasoningEnabled === true ? (reasoningEffort ?? 'medium') : 'none';\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n reasoning_effort: effectiveReasoningEffort,\n },\n };\n};\n\nexport const gptAdapters = {\n 'gpt-5': {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningBudget'],\n buildChatCompletionParams: buildGpt5ChatCompletionParams,\n resolveImageDetail: originalImageDetailForDefaultIntent,\n },\n locate: {\n resultAdapter: {\n coordinates: { shape: 'bbox', order: 'xy' },\n },\n },\n },\n} satisfies Pick<Record<TModelFamily, ModelAdapterDefinition>, 'gpt-5'>;\n"],"names":["originalImageDetailForDefaultIntent","input","undefined","buildGpt5ChatCompletionParams","midsceneDefaults","userConfig","reasoningEnabled","reasoningEffort","commonOverrideConfig","effectiveReasoningEffort","gptAdapters"],"mappings":"AAQA,MAAMA,sCAAsC,CAC1CC,QAEAA,AAAiB,cAAjBA,MAAM,MAAM,IAAkBA,MAAM,2BAA2B,GAC3D,aACAC;AAEN,MAAMC,gCAAgC,CACpCF;IAEA,MAAM,EAAEG,gBAAgB,EAAEC,UAAU,EAAE,GAAGJ;IACzC,MAAM,EAAEK,gBAAgB,EAAEC,eAAe,EAAE,GAAGF;IAC9C,MAAMG,uBAAgD,CAAC;IAEvD,IAAIH,AAA2BH,WAA3BG,WAAW,WAAW,EACxBG,qBAAqB,WAAW,GAAGH,WAAW,WAAW;IAG3D,MAAMI,2BACJH,AAAqB,SAArBA,mBAA6BC,mBAAmB,WAAY;IAE9D,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,kBAAkBC;QACpB;IACF;AACF;AAEO,MAAMC,cAAc;IACzB,SAAS;QACP,gBAAgB;YACd,uBAAuB;gBAAC;aAAkB;YAC1C,2BAA2BP;YAC3B,oBAAoBH;QACtB;QACA,QAAQ;YACN,eAAe;gBACb,aAAa;oBAAE,OAAO;oBAAQ,OAAO;gBAAK;YAC5C;QACF;IACF;AACF"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ai-model/models/kimi.mjs","sources":["../../../../src/ai-model/models/kimi.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '
|
|
1
|
+
{"version":3,"file":"ai-model/models/kimi.mjs","sources":["../../../../src/ai-model/models/kimi.ts"],"sourcesContent":["import type { TModelFamily } from '@midscene/shared/env';\nimport type {\n ChatCompletionCallContext,\n ChatCompletionParamsResult,\n ModelAdapterDefinition,\n} from '../model-adapter/types';\n\nconst buildKimiChatCompletionParams = (\n input: ChatCompletionCallContext,\n): ChatCompletionParamsResult => {\n const { midsceneDefaults, userConfig } = input;\n const { reasoningEnabled } = userConfig;\n const effectiveReasoningEnabled = reasoningEnabled ?? false;\n const commonOverrideConfig: Record<string, unknown> = {};\n\n // kimi disallow custom temperature\n commonOverrideConfig.temperature = undefined;\n\n const modelSpecificConfig: Record<string, unknown> = {\n thinking: {\n type: effectiveReasoningEnabled ? 'enabled' : 'disabled',\n },\n };\n\n return {\n config: {\n ...midsceneDefaults,\n ...commonOverrideConfig,\n ...modelSpecificConfig,\n },\n };\n};\n\nexport const kimiAdapters = {\n kimi: {\n chatCompletion: {\n unsupportedUserConfig: ['reasoningEffort', 'reasoningBudget'],\n buildChatCompletionParams: buildKimiChatCompletionParams,\n },\n locate: {\n resultAdapter: {\n coordinates: { shape: 'point', order: 'xy', normalizedBy: 1 },\n },\n },\n },\n} satisfies Pick<Record<TModelFamily, ModelAdapterDefinition>, 'kimi'>;\n"],"names":["buildKimiChatCompletionParams","input","midsceneDefaults","userConfig","reasoningEnabled","effectiveReasoningEnabled","commonOverrideConfig","undefined","modelSpecificConfig","kimiAdapters"],"mappings":"AAOA,MAAMA,gCAAgC,CACpCC;IAEA,MAAM,EAAEC,gBAAgB,EAAEC,UAAU,EAAE,GAAGF;IACzC,MAAM,EAAEG,gBAAgB,EAAE,GAAGD;IAC7B,MAAME,4BAA4BD,oBAAoB;IACtD,MAAME,uBAAgD,CAAC;IAGvDA,qBAAqB,WAAW,GAAGC;IAEnC,MAAMC,sBAA+C;QACnD,UAAU;YACR,MAAMH,4BAA4B,YAAY;QAChD;IACF;IAEA,OAAO;QACL,QAAQ;YACN,GAAGH,gBAAgB;YACnB,GAAGI,oBAAoB;YACvB,GAAGE,mBAAmB;QACxB;IACF;AACF;AAEO,MAAMC,eAAe;IAC1B,MAAM;QACJ,gBAAgB;YACd,uBAAuB;gBAAC;gBAAmB;aAAkB;YAC7D,2BAA2BT;QAC7B;QACA,QAAQ;YACN,eAAe;gBACb,aAAa;oBAAE,OAAO;oBAAS,OAAO;oBAAM,cAAc;gBAAE;YAC9D;QACF;IACF;AACF"}
|