@aiscene/shared 8.0.2 → 8.0.4
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-tools/agent-behavior-init-args.mjs +44 -0
- package/dist/es/agent-tools/base-tools.mjs +163 -0
- package/dist/es/agent-tools/chrome-path.mjs +50 -0
- package/dist/es/agent-tools/cli-report-session.mjs +78 -0
- package/dist/es/agent-tools/error-formatter.mjs +106 -0
- package/dist/es/agent-tools/index.mjs +9 -0
- package/dist/es/agent-tools/init-arg-utils.mjs +38 -0
- package/dist/es/agent-tools/observation-artifact.mjs +5 -0
- package/dist/es/agent-tools/observation-record.mjs +248 -0
- package/dist/es/agent-tools/tool-defaults.mjs +54 -0
- package/dist/es/agent-tools/tool-generator.mjs +529 -0
- package/dist/es/agent-tools/types.mjs +3 -0
- package/dist/es/agent-tools/user-prompt.mjs +66 -0
- package/dist/es/cli/cli-args.mjs +95 -0
- package/dist/es/cli/cli-error.mjs +24 -0
- package/dist/es/cli/cli-runner.mjs +10 -40
- package/dist/es/cli/index.mjs +4 -2
- package/dist/es/cli/interrupt.mjs +116 -0
- package/dist/es/cli/record-command.mjs +130 -0
- package/dist/es/cli/screenshot-file.mjs +24 -0
- package/dist/es/cli/verbose-ai-act.mjs +230 -0
- package/dist/es/cli/verbose-screenshot.mjs +134 -0
- package/dist/es/cli/verbose.mjs +404 -0
- package/dist/es/constants/example-code.mjs +2 -2
- package/dist/es/constants/index.mjs +6 -1
- package/dist/es/env/model-config-manager.mjs +3 -0
- package/dist/es/env/parse-model-config.mjs +6 -1
- package/dist/es/env/types.mjs +4 -1
- package/dist/es/env/utils.mjs +1 -9
- package/dist/es/extractor/index.mjs +2 -2
- package/dist/es/img/index.mjs +2 -2
- package/dist/es/img/info.mjs +58 -17
- package/dist/es/img/photon-loader.mjs +4 -0
- package/dist/es/key-alias-utils.mjs +19 -0
- package/dist/es/mcp/base-server.mjs +10 -9
- package/dist/es/mcp/base-tools.mjs +72 -4
- package/dist/es/mcp/cli-report-session.mjs +78 -0
- package/dist/es/mcp/error-formatter.mjs +19 -0
- package/dist/es/mcp/index.mjs +2 -0
- package/dist/es/mcp/init-arg-utils.mjs +38 -0
- package/dist/es/mcp/inject-report-html-plugin.mjs +1 -1
- package/dist/es/mcp/tool-generator.mjs +65 -17
- package/dist/es/node/fs.mjs +1 -1
- package/dist/es/recorder.mjs +249 -0
- package/dist/lib/agent-tools/agent-behavior-init-args.js +87 -0
- package/dist/lib/agent-tools/base-tools.js +197 -0
- package/dist/lib/agent-tools/chrome-path.js +87 -0
- package/dist/lib/agent-tools/cli-report-session.js +121 -0
- package/dist/lib/agent-tools/error-formatter.js +149 -0
- package/dist/lib/agent-tools/index.js +114 -0
- package/dist/lib/agent-tools/init-arg-utils.js +78 -0
- package/dist/lib/agent-tools/observation-artifact.js +42 -0
- package/dist/lib/agent-tools/observation-record.js +297 -0
- package/dist/lib/agent-tools/tool-defaults.js +97 -0
- package/dist/lib/agent-tools/tool-generator.js +569 -0
- package/dist/lib/agent-tools/types.js +40 -0
- package/dist/lib/agent-tools/user-prompt.js +103 -0
- package/dist/lib/cli/cli-args.js +138 -0
- package/dist/lib/cli/cli-error.js +61 -0
- package/dist/lib/cli/cli-runner.js +19 -46
- package/dist/lib/cli/index.js +8 -3
- package/dist/lib/cli/interrupt.js +156 -0
- package/dist/lib/cli/record-command.js +164 -0
- package/dist/lib/cli/screenshot-file.js +58 -0
- package/dist/lib/cli/verbose-ai-act.js +273 -0
- package/dist/lib/cli/verbose-screenshot.js +177 -0
- package/dist/lib/cli/verbose.js +465 -0
- package/dist/lib/constants/example-code.js +2 -2
- package/dist/lib/constants/index.js +23 -3
- package/dist/lib/env/model-config-manager.js +3 -0
- package/dist/lib/env/parse-model-config.js +6 -1
- package/dist/lib/env/types.js +9 -0
- package/dist/lib/env/utils.js +0 -11
- package/dist/lib/extractor/index.js +3 -0
- package/dist/lib/img/index.js +3 -0
- package/dist/lib/img/info.js +65 -18
- package/dist/lib/img/photon-loader.js +38 -0
- package/dist/lib/key-alias-utils.js +62 -0
- package/dist/lib/mcp/base-server.js +11 -10
- package/dist/lib/mcp/base-tools.js +74 -6
- package/dist/lib/mcp/cli-report-session.js +121 -0
- package/dist/lib/mcp/error-formatter.js +53 -0
- package/dist/lib/mcp/index.js +24 -10
- package/dist/lib/mcp/init-arg-utils.js +78 -0
- package/dist/lib/mcp/inject-report-html-plugin.js +1 -1
- package/dist/lib/mcp/tool-generator.js +74 -26
- package/dist/lib/node/fs.js +1 -1
- package/dist/lib/recorder.js +307 -0
- package/dist/types/agent-tools/agent-behavior-init-args.d.ts +17 -0
- package/dist/types/agent-tools/base-tools.d.ts +158 -0
- package/dist/types/agent-tools/chrome-path.d.ts +2 -0
- package/dist/types/agent-tools/cli-report-session.d.ts +12 -0
- package/dist/types/agent-tools/error-formatter.d.ts +30 -0
- package/dist/types/agent-tools/index.d.ts +9 -0
- package/dist/types/agent-tools/init-arg-utils.d.ts +13 -0
- package/dist/types/agent-tools/observation-artifact.d.ts +10 -0
- package/dist/types/agent-tools/observation-record.d.ts +38 -0
- package/dist/types/agent-tools/tool-defaults.d.ts +63 -0
- package/dist/types/agent-tools/tool-generator.d.ts +13 -0
- package/dist/types/agent-tools/types.d.ts +213 -0
- package/dist/types/agent-tools/user-prompt.d.ts +13 -0
- package/dist/types/cli/cli-args.d.ts +8 -0
- package/dist/types/cli/cli-error.d.ts +5 -0
- package/dist/types/cli/cli-runner.d.ts +4 -7
- package/dist/types/cli/index.d.ts +3 -1
- package/dist/types/cli/interrupt.d.ts +49 -0
- package/dist/types/cli/record-command.d.ts +3 -0
- package/dist/types/cli/screenshot-file.d.ts +10 -0
- package/dist/types/cli/verbose-ai-act.d.ts +44 -0
- package/dist/types/cli/verbose-screenshot.d.ts +10 -0
- package/dist/types/cli/verbose.d.ts +40 -0
- package/dist/types/constants/example-code.d.ts +1 -1
- package/dist/types/constants/index.d.ts +5 -0
- package/dist/types/env/types.d.ts +14 -5
- package/dist/types/env/utils.d.ts +0 -31
- package/dist/types/extractor/index.d.ts +1 -1
- package/dist/types/img/index.d.ts +1 -1
- package/dist/types/img/info.d.ts +7 -0
- package/dist/types/img/photon-loader.d.ts +2 -0
- package/dist/types/key-alias-utils.d.ts +9 -0
- package/dist/types/mcp/base-tools.d.ts +74 -5
- package/dist/types/mcp/cli-report-session.d.ts +12 -0
- package/dist/types/mcp/error-formatter.d.ts +12 -0
- package/dist/types/mcp/index.d.ts +2 -0
- package/dist/types/mcp/init-arg-utils.d.ts +13 -0
- package/dist/types/mcp/inject-report-html-plugin.d.ts +2 -2
- package/dist/types/mcp/launcher-helper.d.ts +3 -3
- package/dist/types/mcp/tool-generator.d.ts +3 -3
- package/dist/types/mcp/types.d.ts +10 -0
- package/dist/types/recorder.d.ts +113 -0
- package/package.json +1 -1
- package/src/agent-tools/agent-behavior-init-args.ts +109 -0
- package/src/agent-tools/base-tools.ts +399 -0
- package/src/agent-tools/chrome-path.ts +74 -0
- package/src/agent-tools/cli-report-session.ts +130 -0
- package/src/agent-tools/error-formatter.ts +177 -0
- package/src/agent-tools/index.ts +9 -0
- package/src/agent-tools/init-arg-utils.ts +105 -0
- package/src/agent-tools/observation-artifact.ts +29 -0
- package/src/agent-tools/observation-record.ts +331 -0
- package/src/agent-tools/tool-defaults.ts +119 -0
- package/src/agent-tools/tool-generator.ts +866 -0
- package/src/agent-tools/types.ts +250 -0
- package/src/agent-tools/user-prompt.ts +102 -0
- package/src/cli/cli-args.ts +173 -0
- package/src/cli/cli-error.ts +24 -0
- package/src/cli/cli-runner.ts +37 -56
- package/src/cli/index.ts +3 -7
- package/src/cli/interrupt.ts +207 -0
- package/src/cli/record-command.ts +177 -0
- package/src/cli/screenshot-file.ts +61 -0
- package/src/cli/verbose-ai-act.ts +387 -0
- package/src/cli/verbose-screenshot.ts +269 -0
- package/src/cli/verbose.ts +753 -0
- package/src/constants/example-code.ts +2 -2
- package/src/constants/index.ts +10 -0
- package/src/env/model-config-manager.ts +3 -0
- package/src/env/parse-model-config.ts +19 -1
- package/src/env/types.ts +13 -2
- package/src/env/utils.ts +0 -50
- package/src/extractor/index.ts +1 -1
- package/src/img/index.ts +14 -0
- package/src/img/info.ts +97 -45
- package/src/img/photon-loader.ts +5 -0
- package/src/img/transform.ts +261 -2
- package/src/key-alias-utils.ts +23 -0
- package/src/mcp/base-server.ts +10 -12
- package/src/mcp/base-tools.ts +218 -11
- package/src/mcp/cli-report-session.ts +130 -0
- package/src/mcp/error-formatter.ts +52 -0
- package/src/mcp/index.ts +2 -0
- package/src/mcp/init-arg-utils.ts +105 -0
- package/src/mcp/inject-report-html-plugin.ts +3 -3
- package/src/mcp/launcher-helper.ts +3 -3
- package/src/mcp/tool-generator.ts +98 -20
- package/src/mcp/types.ts +18 -1
- package/src/recorder.ts +625 -0
|
@@ -0,0 +1,307 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
DEFAULT_MIDSCENE_RECORDER_MARKDOWN_MAX_SCREENSHOTS: ()=>DEFAULT_MIDSCENE_RECORDER_MARKDOWN_MAX_SCREENSHOTS,
|
|
28
|
+
buildMidsceneRecorderActionSummary: ()=>buildMidsceneRecorderActionSummary,
|
|
29
|
+
buildMidsceneRecorderReplayInstruction: ()=>buildMidsceneRecorderReplayInstruction,
|
|
30
|
+
createMidsceneRecorderMarkdownScreenshotAssets: ()=>createMidsceneRecorderMarkdownScreenshotAssets,
|
|
31
|
+
getMidsceneRecorderEventDescription: ()=>getMidsceneRecorderEventDescription,
|
|
32
|
+
getMidsceneRecorderScreenshotsForLLM: ()=>getMidsceneRecorderScreenshotsForLLM,
|
|
33
|
+
getMidsceneRecorderSemantic: ()=>getMidsceneRecorderSemantic,
|
|
34
|
+
sanitizeMidsceneRecorderFileName: ()=>sanitizeMidsceneRecorderFileName,
|
|
35
|
+
stringifyMidsceneRecorderTargetBlock: ()=>stringifyMidsceneRecorderTargetBlock
|
|
36
|
+
});
|
|
37
|
+
const DEFAULT_MIDSCENE_RECORDER_MARKDOWN_MAX_SCREENSHOTS = 20;
|
|
38
|
+
function isMidsceneRecorderPendingDescription(value) {
|
|
39
|
+
return value?.trim() === 'AI is analyzing element...';
|
|
40
|
+
}
|
|
41
|
+
function getMidsceneRecorderSemantic(event) {
|
|
42
|
+
return event.semantic;
|
|
43
|
+
}
|
|
44
|
+
function getRecorderPointerActionVerb(actionType) {
|
|
45
|
+
switch(actionType){
|
|
46
|
+
case 'Tap':
|
|
47
|
+
return 'Tap';
|
|
48
|
+
case 'DoubleClick':
|
|
49
|
+
return 'Double click';
|
|
50
|
+
case 'LongPress':
|
|
51
|
+
return 'Long press';
|
|
52
|
+
case 'RightClick':
|
|
53
|
+
return 'Right click';
|
|
54
|
+
default:
|
|
55
|
+
return 'Click';
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
function getRecorderDragActionVerb(actionType) {
|
|
59
|
+
switch(actionType){
|
|
60
|
+
case 'Swipe':
|
|
61
|
+
return 'Swipe';
|
|
62
|
+
case 'DragAndDrop':
|
|
63
|
+
return 'Drag';
|
|
64
|
+
default:
|
|
65
|
+
return 'Drag';
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
function buildMidsceneRecorderReplayInstruction(event, elementDescription) {
|
|
69
|
+
switch(event.type){
|
|
70
|
+
case 'navigation':
|
|
71
|
+
if ('Stop' === event.actionType) return 'Stop loading the current page.';
|
|
72
|
+
if ('GoBack' === event.actionType) return 'Go back in the browser.';
|
|
73
|
+
if ('GoForward' === event.actionType) return 'Go forward in the browser.';
|
|
74
|
+
if ('Reload' === event.actionType) return 'Reload the current page.';
|
|
75
|
+
if ('NavigationChanged' === event.actionType && event.url) return `Wait for navigation to complete at \`${event.url}\`.`;
|
|
76
|
+
return event.url ? `Navigate to \`${event.url}\`.` : `Navigate using ${elementDescription}.`;
|
|
77
|
+
case 'scroll':
|
|
78
|
+
return event.scrollDestinationDescription ? `Scroll the page/region with description "${elementDescription}" by value "${event.value || 'down'}" until "${event.scrollDestinationDescription}" is visible.` : `Scroll the page/region with description "${elementDescription}" by value "${event.value || 'down'}".`;
|
|
79
|
+
case 'drag':
|
|
80
|
+
{
|
|
81
|
+
const verb = getRecorderDragActionVerb(event.actionType);
|
|
82
|
+
return `${verb} through the area described as "${elementDescription}".`;
|
|
83
|
+
}
|
|
84
|
+
case 'input':
|
|
85
|
+
return `Input "${event.value || ''}" into the element described as "${elementDescription}".`;
|
|
86
|
+
case 'keydown':
|
|
87
|
+
return `Press "${event.value || 'the recorded key'}" on the element described as "${elementDescription}".`;
|
|
88
|
+
default:
|
|
89
|
+
{
|
|
90
|
+
const verb = getRecorderPointerActionVerb(event.actionType);
|
|
91
|
+
if ('Long press' === verb) return `${verb} the element described as "${elementDescription}".`;
|
|
92
|
+
return `${verb} on the element described as "${elementDescription}".`;
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
function buildMidsceneRecorderActionSummary(event, elementDescription) {
|
|
97
|
+
switch(event.type){
|
|
98
|
+
case 'navigation':
|
|
99
|
+
if ('Stop' === event.actionType) return 'Stop page loading';
|
|
100
|
+
if ('GoBack' === event.actionType) return 'Go back';
|
|
101
|
+
if ('GoForward' === event.actionType) return 'Go forward';
|
|
102
|
+
if ('Reload' === event.actionType) return 'Reload page';
|
|
103
|
+
if ('NavigationChanged' === event.actionType && event.url) return `Wait for navigation to complete at ${event.url}`;
|
|
104
|
+
return event.url ? `Navigate to ${event.url}` : 'Navigate';
|
|
105
|
+
case 'scroll':
|
|
106
|
+
return event.scrollDestinationDescription ? `Scroll ${elementDescription} toward ${event.scrollDestinationDescription}` : `Scroll ${elementDescription}`;
|
|
107
|
+
case 'drag':
|
|
108
|
+
return `${getRecorderDragActionVerb(event.actionType)} ${elementDescription}`;
|
|
109
|
+
case 'input':
|
|
110
|
+
return `Input into ${elementDescription}`;
|
|
111
|
+
case 'keydown':
|
|
112
|
+
return `Press ${event.value || 'key'} on ${elementDescription}`;
|
|
113
|
+
default:
|
|
114
|
+
return `${getRecorderPointerActionVerb(event.actionType)} ${elementDescription}`;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
function getMidsceneRecorderEventDescription(event) {
|
|
118
|
+
const semantic = getMidsceneRecorderSemantic(event);
|
|
119
|
+
if (semantic?.actionSummary && !isMidsceneRecorderPendingDescription(semantic.actionSummary)) return semantic.actionSummary;
|
|
120
|
+
if (semantic?.elementDescription && !isMidsceneRecorderPendingDescription(semantic.elementDescription)) return semantic.elementDescription;
|
|
121
|
+
if (semantic?.replayInstruction && !isMidsceneRecorderPendingDescription(semantic.replayInstruction)) return semantic.replayInstruction;
|
|
122
|
+
if ('navigation' === event.type && event.url) return `Navigate to ${event.url}`;
|
|
123
|
+
if (event.value) return event.actionType ? `${event.actionType} ${event.value}` : event.value;
|
|
124
|
+
if (event.elementRect?.x !== void 0 && event.elementRect?.y !== void 0) {
|
|
125
|
+
const prefix = event.actionType || event.type;
|
|
126
|
+
return `${prefix} (${Math.round(event.elementRect.x)}, ${Math.round(event.elementRect.y)})`;
|
|
127
|
+
}
|
|
128
|
+
return event.actionType || event.type;
|
|
129
|
+
}
|
|
130
|
+
function getMidsceneRecorderScreenshotsForLLM(events, maxScreenshots = 1) {
|
|
131
|
+
return selectRecorderScreenshotCandidates(getRecorderScreenshotCandidates(events), maxScreenshots).map((candidate)=>candidate.screenshot);
|
|
132
|
+
}
|
|
133
|
+
function sanitizeMidsceneRecorderFileName(value) {
|
|
134
|
+
return value.trim().replace(/[\\/:*?"<>|]+/g, '-').replace(/\s+/g, '-').replace(/-+/g, '-').replace(/^-|-$/g, '').toLowerCase() || 'midscene-recording';
|
|
135
|
+
}
|
|
136
|
+
function normalizeMarkdownAssetBaseDir(baseDir) {
|
|
137
|
+
const value = (baseDir || './screenshots').replace(/\/+$/g, '');
|
|
138
|
+
if (value.startsWith('./') || value.startsWith('../')) return value;
|
|
139
|
+
return `./${value}`;
|
|
140
|
+
}
|
|
141
|
+
function padEventIndex(index) {
|
|
142
|
+
return String(index + 1).padStart(3, '0');
|
|
143
|
+
}
|
|
144
|
+
function parseScreenshotDataUrl(value) {
|
|
145
|
+
const dataUrlMatch = value.match(/^data:(image\/[a-zA-Z0-9.+-]+);base64,(.+)$/);
|
|
146
|
+
if (dataUrlMatch) {
|
|
147
|
+
const mimeType = dataUrlMatch[1];
|
|
148
|
+
const extension = mimeType.includes('jpeg') ? 'jpg' : mimeType.split('/')[1]?.replace(/[^a-zA-Z0-9]/g, '') || 'png';
|
|
149
|
+
return {
|
|
150
|
+
dataUrl: value,
|
|
151
|
+
base64Data: dataUrlMatch[2],
|
|
152
|
+
mimeType,
|
|
153
|
+
extension
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
if (/^[a-zA-Z0-9+/=\s]+$/.test(value) && value.trim().length > 0) {
|
|
157
|
+
const base64Data = value.replace(/\s+/g, '');
|
|
158
|
+
return {
|
|
159
|
+
dataUrl: `data:image/png;base64,${base64Data}`,
|
|
160
|
+
base64Data,
|
|
161
|
+
mimeType: 'image/png',
|
|
162
|
+
extension: 'png'
|
|
163
|
+
};
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
function getRecorderEventScreenshot(event) {
|
|
167
|
+
return event.screenshotWithBox || event.screenshotAfter || event.screenshotBefore;
|
|
168
|
+
}
|
|
169
|
+
function hasCoordinateFallback(event) {
|
|
170
|
+
const semantic = getMidsceneRecorderSemantic(event);
|
|
171
|
+
return !semantic?.elementDescription && event.elementRect?.x !== void 0 && event.elementRect?.y !== void 0;
|
|
172
|
+
}
|
|
173
|
+
function shouldIncludeMarkdownScreenshot(event, eventIndex, lastEventIndex) {
|
|
174
|
+
const semantic = getMidsceneRecorderSemantic(event);
|
|
175
|
+
return 0 === eventIndex || eventIndex === lastEventIndex || 'navigation' === event.type || 'scroll' === event.type || 'input' === event.type || Boolean(event.screenshotWithBox) || !semantic?.elementDescription || hasCoordinateFallback(event);
|
|
176
|
+
}
|
|
177
|
+
function getRecorderScreenshotCandidatePriority(candidate, firstEventIndex, lastEventIndex) {
|
|
178
|
+
const event = candidate.event;
|
|
179
|
+
let priority = 0;
|
|
180
|
+
if (candidate.eventIndex === firstEventIndex) priority += 100;
|
|
181
|
+
if (candidate.eventIndex === lastEventIndex) priority += 95;
|
|
182
|
+
if ('navigation' === event.type) priority += 80;
|
|
183
|
+
if (event.screenshotWithBox) priority += 70;
|
|
184
|
+
const semantic = getMidsceneRecorderSemantic(event);
|
|
185
|
+
if (semantic?.source === 'heuristic' || semantic?.confidence === 'low' || semantic?.error) priority += 60;
|
|
186
|
+
if ('input' === event.type || 'scroll' === event.type) priority += 40;
|
|
187
|
+
if (!semantic?.elementDescription || hasCoordinateFallback(event)) priority += 30;
|
|
188
|
+
return priority;
|
|
189
|
+
}
|
|
190
|
+
function selectEvenlyDistributedCandidates(candidates, count) {
|
|
191
|
+
if (count <= 0) return [];
|
|
192
|
+
if (candidates.length <= count) return candidates;
|
|
193
|
+
if (1 === count) return [
|
|
194
|
+
candidates[Math.floor((candidates.length - 1) / 2)]
|
|
195
|
+
];
|
|
196
|
+
return Array.from({
|
|
197
|
+
length: count
|
|
198
|
+
}, (_, index)=>{
|
|
199
|
+
const candidateIndex = Math.round(index * (candidates.length - 1) / (count - 1));
|
|
200
|
+
return candidates[candidateIndex];
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function selectRecorderScreenshotCandidates(candidates, maxScreenshots) {
|
|
204
|
+
if (maxScreenshots <= 0 || 0 === candidates.length) return [];
|
|
205
|
+
if (candidates.length <= maxScreenshots) return candidates;
|
|
206
|
+
const selected = new Map();
|
|
207
|
+
const firstEventIndex = candidates[0].eventIndex;
|
|
208
|
+
const lastEventIndex = candidates[candidates.length - 1].eventIndex;
|
|
209
|
+
const addCandidate = (candidate)=>{
|
|
210
|
+
if (!candidate || selected.size >= maxScreenshots) return;
|
|
211
|
+
selected.set(candidate.eventIndex, candidate);
|
|
212
|
+
};
|
|
213
|
+
const addEvenly = (pool)=>{
|
|
214
|
+
const remaining = maxScreenshots - selected.size;
|
|
215
|
+
if (remaining <= 0) return;
|
|
216
|
+
const unselected = pool.filter((candidate)=>!selected.has(candidate.eventIndex));
|
|
217
|
+
for (const candidate of selectEvenlyDistributedCandidates(unselected, remaining))addCandidate(candidate);
|
|
218
|
+
};
|
|
219
|
+
addCandidate(candidates[0]);
|
|
220
|
+
addCandidate(candidates[candidates.length - 1]);
|
|
221
|
+
addEvenly(candidates.filter((candidate)=>getRecorderScreenshotCandidatePriority(candidate, firstEventIndex, lastEventIndex) >= 60));
|
|
222
|
+
addEvenly(candidates.filter((candidate)=>getRecorderScreenshotCandidatePriority(candidate, firstEventIndex, lastEventIndex) >= 40));
|
|
223
|
+
addEvenly(candidates);
|
|
224
|
+
return Array.from(selected.values()).sort((left, right)=>left.eventIndex - right.eventIndex);
|
|
225
|
+
}
|
|
226
|
+
function getRecorderScreenshotCandidates(events) {
|
|
227
|
+
const candidates = [];
|
|
228
|
+
const seenScreenshots = new Set();
|
|
229
|
+
const lastEventIndex = events.length - 1;
|
|
230
|
+
for(let eventIndex = 0; eventIndex < events.length; eventIndex += 1){
|
|
231
|
+
const event = events[eventIndex];
|
|
232
|
+
if (!shouldIncludeMarkdownScreenshot(event, eventIndex, lastEventIndex)) continue;
|
|
233
|
+
const screenshot = getRecorderEventScreenshot(event);
|
|
234
|
+
if (!(!screenshot || seenScreenshots.has(screenshot))) {
|
|
235
|
+
seenScreenshots.add(screenshot);
|
|
236
|
+
candidates.push({
|
|
237
|
+
event,
|
|
238
|
+
eventIndex,
|
|
239
|
+
screenshot
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
return candidates;
|
|
244
|
+
}
|
|
245
|
+
function createMidsceneRecorderMarkdownScreenshotAssets(events, options = {}) {
|
|
246
|
+
const baseDir = normalizeMarkdownAssetBaseDir(options.baseDir);
|
|
247
|
+
const maxScreenshots = options.maxScreenshots ?? DEFAULT_MIDSCENE_RECORDER_MARKDOWN_MAX_SCREENSHOTS;
|
|
248
|
+
const candidates = [];
|
|
249
|
+
for (const candidate of getRecorderScreenshotCandidates(events)){
|
|
250
|
+
const parsedScreenshot = parseScreenshotDataUrl(candidate.screenshot);
|
|
251
|
+
if (parsedScreenshot) candidates.push({
|
|
252
|
+
...candidate,
|
|
253
|
+
parsedScreenshot
|
|
254
|
+
});
|
|
255
|
+
}
|
|
256
|
+
return selectRecorderScreenshotCandidates(candidates, maxScreenshots).map(({ event, eventIndex, parsedScreenshot })=>{
|
|
257
|
+
const safeType = event.type.replace(/[^a-zA-Z0-9-]/g, '-');
|
|
258
|
+
const fileName = `event-${padEventIndex(eventIndex)}-${safeType}.${parsedScreenshot.extension}`;
|
|
259
|
+
return {
|
|
260
|
+
eventIndex,
|
|
261
|
+
eventHashId: event.hashId,
|
|
262
|
+
eventType: event.type,
|
|
263
|
+
relativePath: `${baseDir}/${fileName}`,
|
|
264
|
+
dataUrl: parsedScreenshot.dataUrl,
|
|
265
|
+
base64Data: parsedScreenshot.base64Data,
|
|
266
|
+
mimeType: parsedScreenshot.mimeType
|
|
267
|
+
};
|
|
268
|
+
});
|
|
269
|
+
}
|
|
270
|
+
function scalarToYaml(value) {
|
|
271
|
+
return JSON.stringify(value);
|
|
272
|
+
}
|
|
273
|
+
function stringifyMidsceneRecorderTargetBlock(target) {
|
|
274
|
+
const lines = [
|
|
275
|
+
`${target.platformId}:`
|
|
276
|
+
];
|
|
277
|
+
const values = Object.entries(target.values);
|
|
278
|
+
if (0 === values.length) {
|
|
279
|
+
lines.push(' {}');
|
|
280
|
+
return lines.join('\n');
|
|
281
|
+
}
|
|
282
|
+
for (const [key, value] of values)lines.push(` ${key}: ${scalarToYaml(value)}`);
|
|
283
|
+
return lines.join('\n');
|
|
284
|
+
}
|
|
285
|
+
exports.DEFAULT_MIDSCENE_RECORDER_MARKDOWN_MAX_SCREENSHOTS = __webpack_exports__.DEFAULT_MIDSCENE_RECORDER_MARKDOWN_MAX_SCREENSHOTS;
|
|
286
|
+
exports.buildMidsceneRecorderActionSummary = __webpack_exports__.buildMidsceneRecorderActionSummary;
|
|
287
|
+
exports.buildMidsceneRecorderReplayInstruction = __webpack_exports__.buildMidsceneRecorderReplayInstruction;
|
|
288
|
+
exports.createMidsceneRecorderMarkdownScreenshotAssets = __webpack_exports__.createMidsceneRecorderMarkdownScreenshotAssets;
|
|
289
|
+
exports.getMidsceneRecorderEventDescription = __webpack_exports__.getMidsceneRecorderEventDescription;
|
|
290
|
+
exports.getMidsceneRecorderScreenshotsForLLM = __webpack_exports__.getMidsceneRecorderScreenshotsForLLM;
|
|
291
|
+
exports.getMidsceneRecorderSemantic = __webpack_exports__.getMidsceneRecorderSemantic;
|
|
292
|
+
exports.sanitizeMidsceneRecorderFileName = __webpack_exports__.sanitizeMidsceneRecorderFileName;
|
|
293
|
+
exports.stringifyMidsceneRecorderTargetBlock = __webpack_exports__.stringifyMidsceneRecorderTargetBlock;
|
|
294
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
295
|
+
"DEFAULT_MIDSCENE_RECORDER_MARKDOWN_MAX_SCREENSHOTS",
|
|
296
|
+
"buildMidsceneRecorderActionSummary",
|
|
297
|
+
"buildMidsceneRecorderReplayInstruction",
|
|
298
|
+
"createMidsceneRecorderMarkdownScreenshotAssets",
|
|
299
|
+
"getMidsceneRecorderEventDescription",
|
|
300
|
+
"getMidsceneRecorderScreenshotsForLLM",
|
|
301
|
+
"getMidsceneRecorderSemantic",
|
|
302
|
+
"sanitizeMidsceneRecorderFileName",
|
|
303
|
+
"stringifyMidsceneRecorderTargetBlock"
|
|
304
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
305
|
+
Object.defineProperty(exports, '__esModule', {
|
|
306
|
+
value: true
|
|
307
|
+
});
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
export interface AgentBehaviorInitArgs {
|
|
3
|
+
aiActContext?: string;
|
|
4
|
+
aiActionContext?: string;
|
|
5
|
+
replanningCycleLimit?: number;
|
|
6
|
+
waitAfterAction?: number;
|
|
7
|
+
screenshotShrinkFactor?: number;
|
|
8
|
+
}
|
|
9
|
+
export declare const agentBehaviorInitArgShape: {
|
|
10
|
+
aiActContext: z.ZodOptional<z.ZodString>;
|
|
11
|
+
replanningCycleLimit: z.ZodOptional<z.ZodNumber>;
|
|
12
|
+
waitAfterAction: z.ZodOptional<z.ZodNumber>;
|
|
13
|
+
screenshotShrinkFactor: z.ZodOptional<z.ZodNumber>;
|
|
14
|
+
};
|
|
15
|
+
export declare function extractAgentBehaviorInitArgs(extracted: Partial<AgentBehaviorInitArgs> | undefined): AgentBehaviorInitArgs | undefined;
|
|
16
|
+
export declare function getAgentInitArgsSignature(initArgs: object | undefined): string | undefined;
|
|
17
|
+
export declare function shouldRebuildAgentForInitArgs(currentSignature: string | undefined, nextSignature: string | undefined): boolean;
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import { type CliReportSession } from './cli-report-session';
|
|
3
|
+
import { type ToolDefaults } from './tool-defaults';
|
|
4
|
+
import type { BaseAgent, BaseDevice, IMidsceneTools, ToolCliMetadata, ToolDefinition, ToolSchema } from './types';
|
|
5
|
+
/**
|
|
6
|
+
* Declarative description of a platform's agent init args.
|
|
7
|
+
* Collapses the `extractAgentInitParam` / `sanitizeToolArgs` /
|
|
8
|
+
* `getAgentInitArgSchema` trio into a single data declaration.
|
|
9
|
+
*/
|
|
10
|
+
export interface InitArgSpec<TInitParam> {
|
|
11
|
+
/** Arg namespace, e.g. `android`, `ios`. */
|
|
12
|
+
namespace: string;
|
|
13
|
+
/** Zod shape describing the init args. Field names drive the tool schema. */
|
|
14
|
+
shape: Record<string, z.ZodTypeAny>;
|
|
15
|
+
/**
|
|
16
|
+
* Optional CLI presentation hints. These affect `--help` output for
|
|
17
|
+
* single-platform CLIs but do not alter YAML protocol keys.
|
|
18
|
+
*/
|
|
19
|
+
cli?: {
|
|
20
|
+
/** Prefer bare `--device-id`-style options in platform CLI help output. */
|
|
21
|
+
preferBareKeys?: boolean;
|
|
22
|
+
/** Override the displayed option name for specific init arg fields. */
|
|
23
|
+
preferredNames?: Record<string, string>;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Adapt extracted namespaced args into the concrete `TInitParam` passed to
|
|
27
|
+
* `ensureAgent`. Defaults to returning the raw extracted record.
|
|
28
|
+
*/
|
|
29
|
+
adapt?: (extracted: Record<string, unknown> | undefined) => TInitParam | undefined;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Base class for platform-specific Midscene tools.
|
|
33
|
+
* @typeParam TAgent - Platform-specific agent type.
|
|
34
|
+
* @typeParam TInitParam - Platform-specific init parameter consumed by
|
|
35
|
+
* `ensureAgent`. Defaults to `undefined` for platforms that take no args.
|
|
36
|
+
*/
|
|
37
|
+
export declare abstract class BaseMidsceneTools<TAgent extends BaseAgent = BaseAgent, TInitParam = unknown> implements IMidsceneTools {
|
|
38
|
+
protected agent?: TAgent;
|
|
39
|
+
protected toolDefinitions: ToolDefinition[];
|
|
40
|
+
/**
|
|
41
|
+
* Default options injected into every generated tool call (e.g. forced deep
|
|
42
|
+
* locate / deep think). Set from startup/CLI behavior flags before
|
|
43
|
+
* `initTools()` so they are baked into the generated tool handlers.
|
|
44
|
+
* See https://github.com/web-infra-dev/midscene/issues/2446.
|
|
45
|
+
*/
|
|
46
|
+
protected toolDefaults: ToolDefaults;
|
|
47
|
+
/**
|
|
48
|
+
* Declarative init-arg spec. Subclasses that accept CLI init args should
|
|
49
|
+
* set this once and get `extractAgentInitParam` / `sanitizeToolArgs` /
|
|
50
|
+
* `getAgentInitArgSchema` auto-implemented.
|
|
51
|
+
*
|
|
52
|
+
* Declared with `declare` so that TS doesn't emit an `Object.defineProperty`
|
|
53
|
+
* for this field on the base constructor, which would otherwise overwrite
|
|
54
|
+
* a subclass field initializer under `useDefineForClassFields`.
|
|
55
|
+
*/
|
|
56
|
+
protected readonly initArgSpec?: InitArgSpec<TInitParam>;
|
|
57
|
+
/**
|
|
58
|
+
* Ensure agent is initialized and ready for use.
|
|
59
|
+
* Must be implemented by subclasses to create platform-specific agent.
|
|
60
|
+
* @param initParam Optional initialization parameter (platform-specific, e.g., URL, device ID)
|
|
61
|
+
* @returns Promise resolving to initialized agent instance
|
|
62
|
+
* @throws Error if agent initialization fails
|
|
63
|
+
*/
|
|
64
|
+
protected abstract ensureAgent(initParam?: TInitParam): Promise<TAgent>;
|
|
65
|
+
private getInitArgKeys;
|
|
66
|
+
/**
|
|
67
|
+
* Extract a platform-specific agent init parameter from CLI tool args.
|
|
68
|
+
*/
|
|
69
|
+
protected extractAgentInitParam(args: Record<string, unknown>): TInitParam | undefined;
|
|
70
|
+
/**
|
|
71
|
+
* Remove platform-specific init args before dispatching a tool payload to the action itself.
|
|
72
|
+
*/
|
|
73
|
+
protected sanitizeToolArgs(args: Record<string, unknown>): Record<string, unknown>;
|
|
74
|
+
/**
|
|
75
|
+
* Expose platform-specific init args on action/common tool schemas.
|
|
76
|
+
*/
|
|
77
|
+
protected getAgentInitArgSchema(): ToolSchema;
|
|
78
|
+
/**
|
|
79
|
+
* Expose CLI-only metadata for platform init args so single-platform help can
|
|
80
|
+
* show ergonomic bare flags while the underlying schema stays namespaced.
|
|
81
|
+
* When `preferBareKeys` is enabled, single-platform CLIs only accept the
|
|
82
|
+
* bare spellings; namespaced dotted spellings remain available through the
|
|
83
|
+
* YAML schema instead of the platform CLI surface.
|
|
84
|
+
*/
|
|
85
|
+
protected getAgentInitArgCliMetadata(): ToolCliMetadata | undefined;
|
|
86
|
+
/**
|
|
87
|
+
* Optional: prepare platform-specific tools (e.g., device connection)
|
|
88
|
+
*/
|
|
89
|
+
protected preparePlatformTools(): ToolDefinition[];
|
|
90
|
+
protected getCliReportSessionName(): string | undefined;
|
|
91
|
+
protected createNewCliReportSession(targetIdentity?: string): CliReportSession | undefined;
|
|
92
|
+
protected commitCliReportSession(session?: CliReportSession): void;
|
|
93
|
+
protected readCliReportFileName(): string | undefined;
|
|
94
|
+
protected readCliReportAgentOptions(): {
|
|
95
|
+
reportFileName: string;
|
|
96
|
+
reportAttributes: Record<string, string>;
|
|
97
|
+
} | undefined;
|
|
98
|
+
/**
|
|
99
|
+
* Must be implemented by subclasses to create a temporary device instance
|
|
100
|
+
* This allows getting real actionSpace without connecting to device
|
|
101
|
+
*/
|
|
102
|
+
protected abstract createTemporaryDevice(): BaseDevice;
|
|
103
|
+
/**
|
|
104
|
+
* Initialize all tools by querying actionSpace
|
|
105
|
+
* Uses two-layer fallback strategy:
|
|
106
|
+
* 1. Try to get actionSpace from connected agent (if available)
|
|
107
|
+
* 2. Create temporary device instance to read actionSpace (always succeeds)
|
|
108
|
+
*/
|
|
109
|
+
initTools(): Promise<void>;
|
|
110
|
+
/**
|
|
111
|
+
* Cleanup method - destroy agent and release resources
|
|
112
|
+
*/
|
|
113
|
+
destroy(): Promise<void>;
|
|
114
|
+
/**
|
|
115
|
+
* Get tool definitions
|
|
116
|
+
*/
|
|
117
|
+
getToolDefinitions(): ToolDefinition[];
|
|
118
|
+
/** Commands that exist only on the foreground CLI surface. */
|
|
119
|
+
getCliToolDefinitions(): ToolDefinition[];
|
|
120
|
+
/**
|
|
121
|
+
* Set agent for the tools manager
|
|
122
|
+
*/
|
|
123
|
+
setAgent(agent: TAgent): void;
|
|
124
|
+
/**
|
|
125
|
+
* Set the default options injected into generated tool calls. Must be called
|
|
126
|
+
* before `initTools()` because the values are captured into the generated
|
|
127
|
+
* tool handlers. Merges with any previously set defaults.
|
|
128
|
+
*/
|
|
129
|
+
setToolDefaults(toolDefaults: ToolDefaults): void;
|
|
130
|
+
/**
|
|
131
|
+
* Helper: Convert base64 screenshot to image content array
|
|
132
|
+
*/
|
|
133
|
+
protected buildScreenshotContent(screenshot: string): {
|
|
134
|
+
type: "image";
|
|
135
|
+
data: string;
|
|
136
|
+
mimeType: string;
|
|
137
|
+
}[];
|
|
138
|
+
/**
|
|
139
|
+
* Helper: Build a simple text result for tool responses
|
|
140
|
+
*/
|
|
141
|
+
protected buildTextResult(text: string): {
|
|
142
|
+
content: {
|
|
143
|
+
type: "text";
|
|
144
|
+
text: string;
|
|
145
|
+
}[];
|
|
146
|
+
};
|
|
147
|
+
/**
|
|
148
|
+
* Create a disconnect handler for releasing platform resources
|
|
149
|
+
* @param platformName Human-readable platform name for the response message
|
|
150
|
+
* @returns Handler function that destroys the agent and returns appropriate response
|
|
151
|
+
*/
|
|
152
|
+
protected createDisconnectHandler(platformName: string): () => Promise<{
|
|
153
|
+
content: {
|
|
154
|
+
type: "text";
|
|
155
|
+
text: string;
|
|
156
|
+
}[];
|
|
157
|
+
}>;
|
|
158
|
+
}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
export interface CliReportSession {
|
|
2
|
+
version: 1;
|
|
3
|
+
sessionName: string;
|
|
4
|
+
targetIdentity?: string;
|
|
5
|
+
reportFileName: string;
|
|
6
|
+
reportPath: string;
|
|
7
|
+
createdAt: number;
|
|
8
|
+
}
|
|
9
|
+
export declare function generateCliReportSession(sessionName: string, targetIdentity?: string): CliReportSession;
|
|
10
|
+
export declare function writeCliReportSession(session: CliReportSession): void;
|
|
11
|
+
export declare function createCliReportSession(sessionName: string, targetIdentity?: string): CliReportSession;
|
|
12
|
+
export declare function readCliReportSession(sessionName: string): CliReportSession | undefined;
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/** A compact, transport-safe representation of an unknown thrown value. */
|
|
2
|
+
export interface SerializedError {
|
|
3
|
+
name: string;
|
|
4
|
+
message: string;
|
|
5
|
+
stack?: string;
|
|
6
|
+
code?: string | number;
|
|
7
|
+
status?: string | number;
|
|
8
|
+
requestId?: string | number;
|
|
9
|
+
}
|
|
10
|
+
/** Apply the same string bound used by {@link serializeError}. */
|
|
11
|
+
export declare function truncateSerializedErrorString(value: string): string;
|
|
12
|
+
/**
|
|
13
|
+
* Extract a human-readable message from an unknown thrown value.
|
|
14
|
+
*
|
|
15
|
+
* Many SDK/transport layers reject with structured objects (e.g.
|
|
16
|
+
* `{ code, message }`, `{ error: { message } }`, `{ cause: { message } }`)
|
|
17
|
+
* rather than `Error` instances. This helper returns the bounded message from
|
|
18
|
+
* {@link serializeError}; message-less objects are summarized from the same
|
|
19
|
+
* diagnostic whitelist instead of serializing arbitrary payload fields.
|
|
20
|
+
*/
|
|
21
|
+
export declare function getErrorMessage(error: unknown): string;
|
|
22
|
+
/** Safely read a stack trace from an unknown thrown value when one exists. */
|
|
23
|
+
export declare function getErrorStack(error: unknown): string | undefined;
|
|
24
|
+
/**
|
|
25
|
+
* Extract a small, bounded diagnostic object suitable for JSON and test-runner
|
|
26
|
+
* transports. Only message, stack, and a few common diagnostic fields are
|
|
27
|
+
* retained. Arbitrary payloads are never visited, and nested errors are only
|
|
28
|
+
* inspected one level deep when the outer value has no message of its own.
|
|
29
|
+
*/
|
|
30
|
+
export declare function serializeError(error: unknown): SerializedError;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export * from './base-tools';
|
|
2
|
+
export * from './tool-defaults';
|
|
3
|
+
export * from './agent-behavior-init-args';
|
|
4
|
+
export * from './init-arg-utils';
|
|
5
|
+
export * from './error-formatter';
|
|
6
|
+
export * from './tool-generator';
|
|
7
|
+
export * from './types';
|
|
8
|
+
export * from './chrome-path';
|
|
9
|
+
export * from './observation-record';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { z } from 'zod';
|
|
2
|
+
import type { ToolSchema } from './types';
|
|
3
|
+
export declare function extractNamespacedArgs<TFieldName extends string, TArgs extends Record<string, unknown> = Record<string, unknown>>(args: Record<string, unknown>, namespace: string, keys: readonly TFieldName[]): TArgs | undefined;
|
|
4
|
+
export declare function sanitizeNamespacedArgs(args: Record<string, unknown>, namespace: string, keys: readonly string[]): Record<string, unknown>;
|
|
5
|
+
/**
|
|
6
|
+
* Build a flat tool schema whose keys are dotted `"<namespace>.<field>"`.
|
|
7
|
+
*
|
|
8
|
+
* We intentionally stay flat (rather than `{ namespace: z.object({...}) }`) so
|
|
9
|
+
* that CLI (`--android.device-id`) and `--help` output share the same spelling.
|
|
10
|
+
* `readNamespacedArg` understands all three input shapes:
|
|
11
|
+
* nested namespace object, dotted flat key, and bare key fallback.
|
|
12
|
+
*/
|
|
13
|
+
export declare function createNamespacedInitArgSchema(namespace: string, shape: Record<string, z.ZodTypeAny>): ToolSchema;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { BaseAgent, BaseUIObservation, UIObservationRecord } from './types';
|
|
2
|
+
/** CLI-only bridge between an Agent runtime and observation artifacts. */
|
|
3
|
+
export interface ObservationArtifactAdapter {
|
|
4
|
+
exportRecord(observation: BaseUIObservation): Promise<UIObservationRecord>;
|
|
5
|
+
loadRecord(record: UIObservationRecord): BaseUIObservation;
|
|
6
|
+
}
|
|
7
|
+
/** @internal Property key used by Core and the CLI artifact commands. */
|
|
8
|
+
export declare const observationArtifactAdapterSymbol: unique symbol;
|
|
9
|
+
/** Read the CLI artifact capability attached by the Core Agent. */
|
|
10
|
+
export declare function resolveObservationArtifactAdapter(agent: BaseAgent): ObservationArtifactAdapter | undefined;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import type { UIObservationFrame, UIObservationRecord } from './types';
|
|
2
|
+
export declare function defaultObservationRecordPath(): string;
|
|
3
|
+
export declare function parseUIObservationRecord(input: unknown): UIObservationRecord;
|
|
4
|
+
/** Return a detached record so callers cannot mutate runtime-owned state. */
|
|
5
|
+
export declare function cloneUIObservationRecord(record: UIObservationRecord): UIObservationRecord;
|
|
6
|
+
export declare function readUIObservationRecord(filePath: string): UIObservationRecord;
|
|
7
|
+
export interface UIObservationRecordMetadata {
|
|
8
|
+
startedAt: number;
|
|
9
|
+
endedAt: number;
|
|
10
|
+
shotSize: UIObservationRecord['shotSize'];
|
|
11
|
+
shrunkShotToLogicalRatio: number;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Incrementally persists observation frames and exports a runtime record whose
|
|
15
|
+
* paths resolve to those image files.
|
|
16
|
+
*/
|
|
17
|
+
export declare class UIObservationRecordWriter {
|
|
18
|
+
readonly outputPath: string;
|
|
19
|
+
readonly framesDirectory: string;
|
|
20
|
+
private readonly temporaryFramesDirectory;
|
|
21
|
+
private finalized;
|
|
22
|
+
private disposed;
|
|
23
|
+
private finalizedRecord;
|
|
24
|
+
constructor(filePath?: string);
|
|
25
|
+
persistFrame(dataUrl: string, capturedAt: number): UIObservationFrame;
|
|
26
|
+
/** Resolve a persisted frame before or after the writer is finalized. */
|
|
27
|
+
resolveFramePath(frame: UIObservationFrame): string;
|
|
28
|
+
/** Remove persisted images that are no longer referenced by the frame buffer. */
|
|
29
|
+
pruneFrames(frames: UIObservationFrame[]): void;
|
|
30
|
+
finalize(frames: UIObservationFrame[], metadata: UIObservationRecordMetadata): UIObservationRecord;
|
|
31
|
+
/** Delete writer-owned temporary or finalized frame files. */
|
|
32
|
+
dispose(): void;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Persist a resolved observation record as a portable JSON manifest plus an
|
|
36
|
+
* adjacent image directory. The input record remains usable after writing.
|
|
37
|
+
*/
|
|
38
|
+
export declare function writeUIObservationRecord(record: UIObservationRecord, filePath?: string): string;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Unified, declarative mechanism for "force a default option on every tool
|
|
3
|
+
* call" behaviors exposed by device and Agent Skill CLIs.
|
|
4
|
+
*
|
|
5
|
+
* Adding a new behavior flag (e.g. `--deep-search`) is a one-line change to
|
|
6
|
+
* {@link TOOL_BEHAVIOR_FLAGS}: declare which default-option "bag" it fills.
|
|
7
|
+
* The tool generator, tools managers and CLI parsing are all generic
|
|
8
|
+
* over {@link ToolDefaults} and never need to learn about individual flags.
|
|
9
|
+
*
|
|
10
|
+
* See https://github.com/web-infra-dev/midscene/issues/2446.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Default options injected into generated tool calls. Each field is an
|
|
14
|
+
* injection point; an explicit per-call value always wins over these defaults.
|
|
15
|
+
*/
|
|
16
|
+
export interface ToolDefaults {
|
|
17
|
+
/**
|
|
18
|
+
* Merged into every locate field of action tools (`Tap`, `Input`, ...).
|
|
19
|
+
* e.g. `{ deepLocate: true }`.
|
|
20
|
+
*/
|
|
21
|
+
locate?: Record<string, unknown>;
|
|
22
|
+
/**
|
|
23
|
+
* Merged into the `aiAction` options used by the `act` tool.
|
|
24
|
+
* e.g. `{ deepLocate: true, deepThink: true }`.
|
|
25
|
+
*/
|
|
26
|
+
act?: Record<string, unknown>;
|
|
27
|
+
}
|
|
28
|
+
export interface ToolBehaviorFlag {
|
|
29
|
+
/** Kebab-case CLI flag name, e.g. `deep-locate` (exposed as `--deep-locate`). */
|
|
30
|
+
cli: string;
|
|
31
|
+
/** One-line description for help output. */
|
|
32
|
+
description: string;
|
|
33
|
+
/** Default-option bags this flag turns on when present. */
|
|
34
|
+
defaults: ToolDefaults;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* The single source of truth for behavior flags. Add a row to support a new
|
|
38
|
+
* `--flag`; nothing else in the pipeline needs to change.
|
|
39
|
+
*/
|
|
40
|
+
export declare const TOOL_BEHAVIOR_FLAGS: readonly ToolBehaviorFlag[];
|
|
41
|
+
/** Merge two {@link ToolDefaults}, with `b` taking precedence over `a`. */
|
|
42
|
+
export declare function mergeToolDefaults(a: ToolDefaults, b: ToolDefaults): ToolDefaults;
|
|
43
|
+
/**
|
|
44
|
+
* Resolve the active {@link ToolDefaults} from a predicate that says whether a
|
|
45
|
+
* given flag (by its `cli` name) is enabled.
|
|
46
|
+
*/
|
|
47
|
+
export declare function resolveToolDefaults(isEnabled: (cli: string) => boolean): ToolDefaults;
|
|
48
|
+
/**
|
|
49
|
+
* Split argv into the resolved {@link ToolDefaults} and the remaining args.
|
|
50
|
+
*
|
|
51
|
+
* Behavior flags (e.g. `--deep-locate`) are global: they may appear anywhere
|
|
52
|
+
* in argv and are not tied to a specific sub-command. They are recognized by
|
|
53
|
+
* exact kebab-case match and removed so a strict per-command parser never sees them. Every other
|
|
54
|
+
* token is returned untouched and in order for that per-command parser.
|
|
55
|
+
*
|
|
56
|
+
* This is the single place that knows how a behavior flag looks on the command
|
|
57
|
+
* line; the device / Agent Skill CLI resolves defaults from
|
|
58
|
+
* {@link TOOL_BEHAVIOR_FLAGS} through here / {@link resolveToolDefaults}.
|
|
59
|
+
*/
|
|
60
|
+
export declare function stripBehaviorFlags(argv: readonly string[]): {
|
|
61
|
+
rawArgs: string[];
|
|
62
|
+
toolDefaults: ToolDefaults;
|
|
63
|
+
};
|