@midscene/shared 1.7.5-beta-20260420031920.0 → 1.7.5-beta-20260420032657.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/cli/cli-runner.mjs +4 -41
- package/dist/es/mcp/base-tools.mjs +2 -43
- package/dist/es/mcp/index.mjs +0 -1
- package/dist/es/mcp/tool-generator.mjs +11 -29
- package/dist/lib/cli/cli-runner.js +4 -41
- package/dist/lib/mcp/base-tools.js +2 -43
- package/dist/lib/mcp/index.js +12 -19
- package/dist/lib/mcp/tool-generator.js +11 -29
- package/dist/types/cli/cli-runner.d.ts +1 -3
- package/dist/types/mcp/base-tools.d.ts +5 -62
- package/dist/types/mcp/index.d.ts +0 -1
- package/dist/types/mcp/tool-generator.d.ts +3 -3
- package/dist/types/mcp/types.d.ts +0 -8
- package/package.json +1 -1
- package/src/cli/cli-runner.ts +5 -74
- package/src/mcp/base-tools.ts +9 -162
- package/src/mcp/index.ts +0 -1
- package/src/mcp/tool-generator.ts +10 -47
- package/src/mcp/types.ts +0 -10
- package/dist/es/key-alias-utils.mjs +0 -19
- package/dist/es/mcp/init-arg-utils.mjs +0 -38
- package/dist/lib/key-alias-utils.js +0 -62
- package/dist/lib/mcp/init-arg-utils.js +0 -78
- package/dist/types/key-alias-utils.d.ts +0 -9
- package/dist/types/mcp/init-arg-utils.d.ts +0 -13
- package/src/key-alias-utils.ts +0 -23
- package/src/mcp/init-arg-utils.ts +0 -105
|
@@ -2,7 +2,6 @@ import { existsSync, writeFileSync } from "node:fs";
|
|
|
2
2
|
import { tmpdir } from "node:os";
|
|
3
3
|
import { join } from "node:path";
|
|
4
4
|
import dotenv from "dotenv";
|
|
5
|
-
import { getKeyAliases, isRecord } from "../key-alias-utils.mjs";
|
|
6
5
|
import { getDebug } from "../logger.mjs";
|
|
7
6
|
function _define_property(obj, key, value) {
|
|
8
7
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -29,36 +28,16 @@ function parseValue(raw) {
|
|
|
29
28
|
}
|
|
30
29
|
function parseCliArgs(args) {
|
|
31
30
|
const result = {};
|
|
32
|
-
const setArgValue = (key, value)=>{
|
|
33
|
-
if (!key.includes('.')) {
|
|
34
|
-
result[key] = value;
|
|
35
|
-
return;
|
|
36
|
-
}
|
|
37
|
-
const segments = key.split('.');
|
|
38
|
-
let current = result;
|
|
39
|
-
for (const segment of segments.slice(0, -1)){
|
|
40
|
-
const aliases = getKeyAliases(segment);
|
|
41
|
-
const existing = aliases.map((alias)=>current[alias]);
|
|
42
|
-
const nestedRecord = existing.find(isRecord);
|
|
43
|
-
const conflictingScalar = existing.find((entry)=>void 0 !== entry && !isRecord(entry));
|
|
44
|
-
if (void 0 !== conflictingScalar) throw new CLIError(`Conflicting CLI args: "${segment}" is used both as a value and as a namespace`);
|
|
45
|
-
const target = nestedRecord ?? {};
|
|
46
|
-
for (const alias of aliases)current[alias] = target;
|
|
47
|
-
current = target;
|
|
48
|
-
}
|
|
49
|
-
const leafSegment = segments[segments.length - 1];
|
|
50
|
-
for (const alias of getKeyAliases(leafSegment))current[alias] = value;
|
|
51
|
-
};
|
|
52
31
|
for(let i = 0; i < args.length; i++){
|
|
53
32
|
const arg = args[i];
|
|
54
33
|
if (!arg.startsWith('--')) continue;
|
|
55
34
|
const body = arg.slice(2);
|
|
56
35
|
const eqIdx = body.indexOf('=');
|
|
57
|
-
if (eqIdx >= 0)
|
|
36
|
+
if (eqIdx >= 0) result[body.slice(0, eqIdx)] = parseValue(body.slice(eqIdx + 1));
|
|
58
37
|
else if (args[i + 1] && !args[i + 1].startsWith('--')) {
|
|
59
38
|
i++;
|
|
60
|
-
|
|
61
|
-
} else
|
|
39
|
+
result[body] = parseValue(args[i]);
|
|
40
|
+
} else result[body] = true;
|
|
62
41
|
}
|
|
63
42
|
return result;
|
|
64
43
|
}
|
|
@@ -87,32 +66,16 @@ function removePrefix(name, prefix) {
|
|
|
87
66
|
if (prefix && name.startsWith(prefix)) return name.slice(prefix.length);
|
|
88
67
|
return name;
|
|
89
68
|
}
|
|
90
|
-
function formatCliOptionName(name) {
|
|
91
|
-
return `--${name}`;
|
|
92
|
-
}
|
|
93
|
-
function getCliOptionDisplay(key, cliOption) {
|
|
94
|
-
const label = formatCliOptionName(cliOption?.preferredName ?? key);
|
|
95
|
-
const aliases = [
|
|
96
|
-
...new Set(cliOption?.aliases ?? [])
|
|
97
|
-
].map((alias)=>formatCliOptionName(alias)).filter((alias)=>alias !== label);
|
|
98
|
-
return {
|
|
99
|
-
label,
|
|
100
|
-
aliases
|
|
101
|
-
};
|
|
102
|
-
}
|
|
103
69
|
function printCommandHelp(scriptName, cmd) {
|
|
104
70
|
const { def } = cmd;
|
|
105
71
|
console.log(`\nUsage: ${scriptName} ${cmd.name} [options]\n`);
|
|
106
72
|
console.log(def.description);
|
|
107
73
|
const schemaEntries = Object.entries(def.schema);
|
|
108
74
|
if (schemaEntries.length > 0) {
|
|
109
|
-
const optionWidth = Math.max(22, ...schemaEntries.map(([key])=>getCliOptionDisplay(key, def.cli?.options?.[key]).label.length));
|
|
110
75
|
console.log('\nOptions:');
|
|
111
76
|
for (const [key, zodType] of schemaEntries){
|
|
112
|
-
const { label, aliases } = getCliOptionDisplay(key, def.cli?.options?.[key]);
|
|
113
77
|
const desc = zodType.description ?? '';
|
|
114
|
-
|
|
115
|
-
console.log(` ${label.padEnd(optionWidth)} ${desc}${aliasText}`);
|
|
78
|
+
console.log(` --${key.padEnd(20)} ${desc}`);
|
|
116
79
|
}
|
|
117
80
|
}
|
|
118
81
|
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
import { parseBase64 } from "@midscene/shared/img";
|
|
2
2
|
import { getDebug } from "@midscene/shared/logger";
|
|
3
|
-
import { camelToKebab, getKeyAliases } from "../key-alias-utils.mjs";
|
|
4
|
-
import { createNamespacedInitArgSchema, extractNamespacedArgs, sanitizeNamespacedArgs } from "./init-arg-utils.mjs";
|
|
5
3
|
import { generateCommonTools, generateToolsFromActionSpace } from "./tool-generator.mjs";
|
|
6
4
|
function _define_property(obj, key, value) {
|
|
7
5
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -15,45 +13,6 @@ function _define_property(obj, key, value) {
|
|
|
15
13
|
}
|
|
16
14
|
const debug = getDebug('mcp:base-tools');
|
|
17
15
|
class BaseMidsceneTools {
|
|
18
|
-
getInitArgKeys() {
|
|
19
|
-
return this.initArgSpec ? Object.keys(this.initArgSpec.shape) : [];
|
|
20
|
-
}
|
|
21
|
-
extractAgentInitParam(args) {
|
|
22
|
-
if (!this.initArgSpec) return;
|
|
23
|
-
const extracted = extractNamespacedArgs(args, this.initArgSpec.namespace, this.getInitArgKeys());
|
|
24
|
-
if (this.initArgSpec.adapt) return this.initArgSpec.adapt(extracted);
|
|
25
|
-
return extracted;
|
|
26
|
-
}
|
|
27
|
-
sanitizeToolArgs(args) {
|
|
28
|
-
if (!this.initArgSpec) return args;
|
|
29
|
-
return sanitizeNamespacedArgs(args, this.initArgSpec.namespace, this.getInitArgKeys());
|
|
30
|
-
}
|
|
31
|
-
getAgentInitArgSchema() {
|
|
32
|
-
if (!this.initArgSpec) return {};
|
|
33
|
-
return createNamespacedInitArgSchema(this.initArgSpec.namespace, this.initArgSpec.shape);
|
|
34
|
-
}
|
|
35
|
-
getAgentInitArgCliMetadata() {
|
|
36
|
-
if (!this.initArgSpec?.cli) return;
|
|
37
|
-
const options = Object.fromEntries(this.getInitArgKeys().map((key)=>{
|
|
38
|
-
const canonicalKey = `${this.initArgSpec.namespace}.${key}`;
|
|
39
|
-
const preferredName = this.initArgSpec.cli?.preferredNames?.[key] ?? (this.initArgSpec.cli?.preferBareKeys ? camelToKebab(key) : canonicalKey);
|
|
40
|
-
const aliases = new Set(getKeyAliases(canonicalKey));
|
|
41
|
-
if (this.initArgSpec.cli?.preferBareKeys) for (const alias of getKeyAliases(key))aliases.add(alias);
|
|
42
|
-
aliases.delete(preferredName);
|
|
43
|
-
return [
|
|
44
|
-
canonicalKey,
|
|
45
|
-
{
|
|
46
|
-
preferredName,
|
|
47
|
-
aliases: [
|
|
48
|
-
...aliases
|
|
49
|
-
]
|
|
50
|
-
}
|
|
51
|
-
];
|
|
52
|
-
}));
|
|
53
|
-
return {
|
|
54
|
-
options
|
|
55
|
-
};
|
|
56
|
-
}
|
|
57
16
|
preparePlatformTools() {
|
|
58
17
|
return [];
|
|
59
18
|
}
|
|
@@ -71,8 +30,8 @@ class BaseMidsceneTools {
|
|
|
71
30
|
await tempDevice.destroy?.();
|
|
72
31
|
debug('Action space from temporary device:', actionSpace.map((a)=>a.name).join(', '));
|
|
73
32
|
}
|
|
74
|
-
const actionTools = generateToolsFromActionSpace(actionSpace, (
|
|
75
|
-
const commonTools = generateCommonTools((
|
|
33
|
+
const actionTools = generateToolsFromActionSpace(actionSpace, ()=>this.ensureAgent());
|
|
34
|
+
const commonTools = generateCommonTools(()=>this.ensureAgent());
|
|
76
35
|
this.toolDefinitions.push(...actionTools, ...commonTools);
|
|
77
36
|
debug('Total tools prepared:', this.toolDefinitions.length);
|
|
78
37
|
}
|
package/dist/es/mcp/index.mjs
CHANGED
|
@@ -277,30 +277,17 @@ async function captureFailureResult(agent, actionName, errorMessage) {
|
|
|
277
277
|
};
|
|
278
278
|
}
|
|
279
279
|
}
|
|
280
|
-
function
|
|
281
|
-
const options = {
|
|
282
|
-
...base?.options ?? {},
|
|
283
|
-
...extra?.options ?? {}
|
|
284
|
-
};
|
|
285
|
-
return Object.keys(options).length > 0 ? {
|
|
286
|
-
options
|
|
287
|
-
} : void 0;
|
|
288
|
-
}
|
|
289
|
-
function generateToolsFromActionSpace(actionSpace, getAgent, sanitizeArgs = (args)=>args, initArgSchema = {}, initArgCliMetadata) {
|
|
280
|
+
function generateToolsFromActionSpace(actionSpace, getAgent) {
|
|
290
281
|
return actionSpace.map((action)=>{
|
|
291
|
-
const schema =
|
|
292
|
-
...extractActionSchema(action.paramSchema),
|
|
293
|
-
...initArgSchema
|
|
294
|
-
};
|
|
282
|
+
const schema = extractActionSchema(action.paramSchema);
|
|
295
283
|
return {
|
|
296
284
|
name: action.name,
|
|
297
285
|
description: describeActionForMCP(action),
|
|
298
286
|
schema,
|
|
299
|
-
cli: initArgCliMetadata,
|
|
300
287
|
handler: async (args)=>{
|
|
301
288
|
try {
|
|
302
|
-
const agent = await getAgent(
|
|
303
|
-
const normalizedArgs = normalizeActionArgs(
|
|
289
|
+
const agent = await getAgent();
|
|
290
|
+
const normalizedArgs = normalizeActionArgs(args, action.paramSchema);
|
|
304
291
|
let actionResult;
|
|
305
292
|
try {
|
|
306
293
|
actionResult = await executeAction(agent, action.name, normalizedArgs);
|
|
@@ -319,18 +306,15 @@ function generateToolsFromActionSpace(actionSpace, getAgent, sanitizeArgs = (arg
|
|
|
319
306
|
};
|
|
320
307
|
});
|
|
321
308
|
}
|
|
322
|
-
function generateCommonTools(getAgent
|
|
309
|
+
function generateCommonTools(getAgent) {
|
|
323
310
|
return [
|
|
324
311
|
{
|
|
325
312
|
name: 'take_screenshot',
|
|
326
313
|
description: 'Capture screenshot of current page/screen',
|
|
327
|
-
schema: {
|
|
328
|
-
|
|
329
|
-
},
|
|
330
|
-
cli: initArgCliMetadata,
|
|
331
|
-
handler: async (args = {})=>{
|
|
314
|
+
schema: {},
|
|
315
|
+
handler: async ()=>{
|
|
332
316
|
try {
|
|
333
|
-
const agent = await getAgent(
|
|
317
|
+
const agent = await getAgent();
|
|
334
318
|
const screenshot = await agent.page?.screenshotBase64();
|
|
335
319
|
if (!screenshot) return createErrorResult('Screenshot not available');
|
|
336
320
|
const { mimeType, body } = parseBase64(screenshot);
|
|
@@ -354,14 +338,12 @@ function generateCommonTools(getAgent, initArgSchema = {}, initArgCliMetadata) {
|
|
|
354
338
|
name: 'act',
|
|
355
339
|
description: 'Execute a natural language action. The AI will plan and perform multi-step operations in a single invocation, useful for transient UI interactions (e.g., Spotlight, dropdown menus) that disappear between separate commands.',
|
|
356
340
|
schema: {
|
|
357
|
-
prompt: z.string().describe('Natural language description of the action to perform, e.g. "press Command+Space, type Safari, press Enter"')
|
|
358
|
-
...initArgSchema
|
|
341
|
+
prompt: z.string().describe('Natural language description of the action to perform, e.g. "press Command+Space, type Safari, press Enter"')
|
|
359
342
|
},
|
|
360
|
-
|
|
361
|
-
handler: async (args = {})=>{
|
|
343
|
+
handler: async (args)=>{
|
|
362
344
|
const prompt = args.prompt;
|
|
363
345
|
try {
|
|
364
|
-
const agent = await getAgent(
|
|
346
|
+
const agent = await getAgent();
|
|
365
347
|
if (!agent.aiAction) return createErrorResult('act is not supported by this agent');
|
|
366
348
|
const result = await agent.aiAction(prompt, {
|
|
367
349
|
deepThink: false
|
|
@@ -44,7 +44,6 @@ const external_node_os_namespaceObject = require("node:os");
|
|
|
44
44
|
const external_node_path_namespaceObject = require("node:path");
|
|
45
45
|
const external_dotenv_namespaceObject = require("dotenv");
|
|
46
46
|
var external_dotenv_default = /*#__PURE__*/ __webpack_require__.n(external_dotenv_namespaceObject);
|
|
47
|
-
const external_key_alias_utils_js_namespaceObject = require("../key-alias-utils.js");
|
|
48
47
|
const external_logger_js_namespaceObject = require("../logger.js");
|
|
49
48
|
function _define_property(obj, key, value) {
|
|
50
49
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -71,36 +70,16 @@ function parseValue(raw) {
|
|
|
71
70
|
}
|
|
72
71
|
function parseCliArgs(args) {
|
|
73
72
|
const result = {};
|
|
74
|
-
const setArgValue = (key, value)=>{
|
|
75
|
-
if (!key.includes('.')) {
|
|
76
|
-
result[key] = value;
|
|
77
|
-
return;
|
|
78
|
-
}
|
|
79
|
-
const segments = key.split('.');
|
|
80
|
-
let current = result;
|
|
81
|
-
for (const segment of segments.slice(0, -1)){
|
|
82
|
-
const aliases = (0, external_key_alias_utils_js_namespaceObject.getKeyAliases)(segment);
|
|
83
|
-
const existing = aliases.map((alias)=>current[alias]);
|
|
84
|
-
const nestedRecord = existing.find(external_key_alias_utils_js_namespaceObject.isRecord);
|
|
85
|
-
const conflictingScalar = existing.find((entry)=>void 0 !== entry && !(0, external_key_alias_utils_js_namespaceObject.isRecord)(entry));
|
|
86
|
-
if (void 0 !== conflictingScalar) throw new CLIError(`Conflicting CLI args: "${segment}" is used both as a value and as a namespace`);
|
|
87
|
-
const target = nestedRecord ?? {};
|
|
88
|
-
for (const alias of aliases)current[alias] = target;
|
|
89
|
-
current = target;
|
|
90
|
-
}
|
|
91
|
-
const leafSegment = segments[segments.length - 1];
|
|
92
|
-
for (const alias of (0, external_key_alias_utils_js_namespaceObject.getKeyAliases)(leafSegment))current[alias] = value;
|
|
93
|
-
};
|
|
94
73
|
for(let i = 0; i < args.length; i++){
|
|
95
74
|
const arg = args[i];
|
|
96
75
|
if (!arg.startsWith('--')) continue;
|
|
97
76
|
const body = arg.slice(2);
|
|
98
77
|
const eqIdx = body.indexOf('=');
|
|
99
|
-
if (eqIdx >= 0)
|
|
78
|
+
if (eqIdx >= 0) result[body.slice(0, eqIdx)] = parseValue(body.slice(eqIdx + 1));
|
|
100
79
|
else if (args[i + 1] && !args[i + 1].startsWith('--')) {
|
|
101
80
|
i++;
|
|
102
|
-
|
|
103
|
-
} else
|
|
81
|
+
result[body] = parseValue(args[i]);
|
|
82
|
+
} else result[body] = true;
|
|
104
83
|
}
|
|
105
84
|
return result;
|
|
106
85
|
}
|
|
@@ -129,32 +108,16 @@ function removePrefix(name, prefix) {
|
|
|
129
108
|
if (prefix && name.startsWith(prefix)) return name.slice(prefix.length);
|
|
130
109
|
return name;
|
|
131
110
|
}
|
|
132
|
-
function formatCliOptionName(name) {
|
|
133
|
-
return `--${name}`;
|
|
134
|
-
}
|
|
135
|
-
function getCliOptionDisplay(key, cliOption) {
|
|
136
|
-
const label = formatCliOptionName(cliOption?.preferredName ?? key);
|
|
137
|
-
const aliases = [
|
|
138
|
-
...new Set(cliOption?.aliases ?? [])
|
|
139
|
-
].map((alias)=>formatCliOptionName(alias)).filter((alias)=>alias !== label);
|
|
140
|
-
return {
|
|
141
|
-
label,
|
|
142
|
-
aliases
|
|
143
|
-
};
|
|
144
|
-
}
|
|
145
111
|
function printCommandHelp(scriptName, cmd) {
|
|
146
112
|
const { def } = cmd;
|
|
147
113
|
console.log(`\nUsage: ${scriptName} ${cmd.name} [options]\n`);
|
|
148
114
|
console.log(def.description);
|
|
149
115
|
const schemaEntries = Object.entries(def.schema);
|
|
150
116
|
if (schemaEntries.length > 0) {
|
|
151
|
-
const optionWidth = Math.max(22, ...schemaEntries.map(([key])=>getCliOptionDisplay(key, def.cli?.options?.[key]).label.length));
|
|
152
117
|
console.log('\nOptions:');
|
|
153
118
|
for (const [key, zodType] of schemaEntries){
|
|
154
|
-
const { label, aliases } = getCliOptionDisplay(key, def.cli?.options?.[key]);
|
|
155
119
|
const desc = zodType.description ?? '';
|
|
156
|
-
|
|
157
|
-
console.log(` ${label.padEnd(optionWidth)} ${desc}${aliasText}`);
|
|
120
|
+
console.log(` --${key.padEnd(20)} ${desc}`);
|
|
158
121
|
}
|
|
159
122
|
}
|
|
160
123
|
}
|
|
@@ -28,8 +28,6 @@ __webpack_require__.d(__webpack_exports__, {
|
|
|
28
28
|
});
|
|
29
29
|
const img_namespaceObject = require("@midscene/shared/img");
|
|
30
30
|
const logger_namespaceObject = require("@midscene/shared/logger");
|
|
31
|
-
const external_key_alias_utils_js_namespaceObject = require("../key-alias-utils.js");
|
|
32
|
-
const external_init_arg_utils_js_namespaceObject = require("./init-arg-utils.js");
|
|
33
31
|
const external_tool_generator_js_namespaceObject = require("./tool-generator.js");
|
|
34
32
|
function _define_property(obj, key, value) {
|
|
35
33
|
if (key in obj) Object.defineProperty(obj, key, {
|
|
@@ -43,45 +41,6 @@ function _define_property(obj, key, value) {
|
|
|
43
41
|
}
|
|
44
42
|
const debug = (0, logger_namespaceObject.getDebug)('mcp:base-tools');
|
|
45
43
|
class BaseMidsceneTools {
|
|
46
|
-
getInitArgKeys() {
|
|
47
|
-
return this.initArgSpec ? Object.keys(this.initArgSpec.shape) : [];
|
|
48
|
-
}
|
|
49
|
-
extractAgentInitParam(args) {
|
|
50
|
-
if (!this.initArgSpec) return;
|
|
51
|
-
const extracted = (0, external_init_arg_utils_js_namespaceObject.extractNamespacedArgs)(args, this.initArgSpec.namespace, this.getInitArgKeys());
|
|
52
|
-
if (this.initArgSpec.adapt) return this.initArgSpec.adapt(extracted);
|
|
53
|
-
return extracted;
|
|
54
|
-
}
|
|
55
|
-
sanitizeToolArgs(args) {
|
|
56
|
-
if (!this.initArgSpec) return args;
|
|
57
|
-
return (0, external_init_arg_utils_js_namespaceObject.sanitizeNamespacedArgs)(args, this.initArgSpec.namespace, this.getInitArgKeys());
|
|
58
|
-
}
|
|
59
|
-
getAgentInitArgSchema() {
|
|
60
|
-
if (!this.initArgSpec) return {};
|
|
61
|
-
return (0, external_init_arg_utils_js_namespaceObject.createNamespacedInitArgSchema)(this.initArgSpec.namespace, this.initArgSpec.shape);
|
|
62
|
-
}
|
|
63
|
-
getAgentInitArgCliMetadata() {
|
|
64
|
-
if (!this.initArgSpec?.cli) return;
|
|
65
|
-
const options = Object.fromEntries(this.getInitArgKeys().map((key)=>{
|
|
66
|
-
const canonicalKey = `${this.initArgSpec.namespace}.${key}`;
|
|
67
|
-
const preferredName = this.initArgSpec.cli?.preferredNames?.[key] ?? (this.initArgSpec.cli?.preferBareKeys ? (0, external_key_alias_utils_js_namespaceObject.camelToKebab)(key) : canonicalKey);
|
|
68
|
-
const aliases = new Set((0, external_key_alias_utils_js_namespaceObject.getKeyAliases)(canonicalKey));
|
|
69
|
-
if (this.initArgSpec.cli?.preferBareKeys) for (const alias of (0, external_key_alias_utils_js_namespaceObject.getKeyAliases)(key))aliases.add(alias);
|
|
70
|
-
aliases.delete(preferredName);
|
|
71
|
-
return [
|
|
72
|
-
canonicalKey,
|
|
73
|
-
{
|
|
74
|
-
preferredName,
|
|
75
|
-
aliases: [
|
|
76
|
-
...aliases
|
|
77
|
-
]
|
|
78
|
-
}
|
|
79
|
-
];
|
|
80
|
-
}));
|
|
81
|
-
return {
|
|
82
|
-
options
|
|
83
|
-
};
|
|
84
|
-
}
|
|
85
44
|
preparePlatformTools() {
|
|
86
45
|
return [];
|
|
87
46
|
}
|
|
@@ -99,8 +58,8 @@ class BaseMidsceneTools {
|
|
|
99
58
|
await tempDevice.destroy?.();
|
|
100
59
|
debug('Action space from temporary device:', actionSpace.map((a)=>a.name).join(', '));
|
|
101
60
|
}
|
|
102
|
-
const actionTools = (0, external_tool_generator_js_namespaceObject.generateToolsFromActionSpace)(actionSpace, (
|
|
103
|
-
const commonTools = (0, external_tool_generator_js_namespaceObject.generateCommonTools)((
|
|
61
|
+
const actionTools = (0, external_tool_generator_js_namespaceObject.generateToolsFromActionSpace)(actionSpace, ()=>this.ensureAgent());
|
|
62
|
+
const commonTools = (0, external_tool_generator_js_namespaceObject.generateCommonTools)(()=>this.ensureAgent());
|
|
104
63
|
this.toolDefinitions.push(...actionTools, ...commonTools);
|
|
105
64
|
debug('Total tools prepared:', this.toolDefinitions.length);
|
|
106
65
|
}
|
package/dist/lib/mcp/index.js
CHANGED
|
@@ -12,9 +12,6 @@ var __webpack_modules__ = {
|
|
|
12
12
|
"./error-formatter" (module) {
|
|
13
13
|
module.exports = require("./error-formatter.js");
|
|
14
14
|
},
|
|
15
|
-
"./init-arg-utils" (module) {
|
|
16
|
-
module.exports = require("./init-arg-utils.js");
|
|
17
|
-
},
|
|
18
15
|
"./inject-report-html-plugin" (module) {
|
|
19
16
|
module.exports = require("./inject-report-html-plugin.js");
|
|
20
17
|
},
|
|
@@ -79,33 +76,29 @@ var __webpack_exports__ = {};
|
|
|
79
76
|
var __rspack_reexport = {};
|
|
80
77
|
for(const __rspack_import_key in _base_tools__rspack_import_1)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_base_tools__rspack_import_1[__rspack_import_key];
|
|
81
78
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
82
|
-
var
|
|
83
|
-
var __rspack_reexport = {};
|
|
84
|
-
for(const __rspack_import_key in _init_arg_utils__rspack_import_2)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_init_arg_utils__rspack_import_2[__rspack_import_key];
|
|
85
|
-
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
86
|
-
var _error_formatter__rspack_import_3 = __webpack_require__("./error-formatter");
|
|
79
|
+
var _error_formatter__rspack_import_2 = __webpack_require__("./error-formatter");
|
|
87
80
|
var __rspack_reexport = {};
|
|
88
|
-
for(const __rspack_import_key in
|
|
81
|
+
for(const __rspack_import_key in _error_formatter__rspack_import_2)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_error_formatter__rspack_import_2[__rspack_import_key];
|
|
89
82
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
90
|
-
var
|
|
83
|
+
var _tool_generator__rspack_import_3 = __webpack_require__("./tool-generator");
|
|
91
84
|
var __rspack_reexport = {};
|
|
92
|
-
for(const __rspack_import_key in
|
|
85
|
+
for(const __rspack_import_key in _tool_generator__rspack_import_3)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_tool_generator__rspack_import_3[__rspack_import_key];
|
|
93
86
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
94
|
-
var
|
|
87
|
+
var _types__rspack_import_4 = __webpack_require__("./types");
|
|
95
88
|
var __rspack_reexport = {};
|
|
96
|
-
for(const __rspack_import_key in
|
|
89
|
+
for(const __rspack_import_key in _types__rspack_import_4)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_types__rspack_import_4[__rspack_import_key];
|
|
97
90
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
98
|
-
var
|
|
91
|
+
var _inject_report_html_plugin__rspack_import_5 = __webpack_require__("./inject-report-html-plugin");
|
|
99
92
|
var __rspack_reexport = {};
|
|
100
|
-
for(const __rspack_import_key in
|
|
93
|
+
for(const __rspack_import_key in _inject_report_html_plugin__rspack_import_5)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_inject_report_html_plugin__rspack_import_5[__rspack_import_key];
|
|
101
94
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
102
|
-
var
|
|
95
|
+
var _launcher_helper__rspack_import_6 = __webpack_require__("./launcher-helper");
|
|
103
96
|
var __rspack_reexport = {};
|
|
104
|
-
for(const __rspack_import_key in
|
|
97
|
+
for(const __rspack_import_key in _launcher_helper__rspack_import_6)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_launcher_helper__rspack_import_6[__rspack_import_key];
|
|
105
98
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
106
|
-
var
|
|
99
|
+
var _chrome_path__rspack_import_7 = __webpack_require__("./chrome-path");
|
|
107
100
|
var __rspack_reexport = {};
|
|
108
|
-
for(const __rspack_import_key in
|
|
101
|
+
for(const __rspack_import_key in _chrome_path__rspack_import_7)if ("default" !== __rspack_import_key) __rspack_reexport[__rspack_import_key] = ()=>_chrome_path__rspack_import_7[__rspack_import_key];
|
|
109
102
|
__webpack_require__.d(__webpack_exports__, __rspack_reexport);
|
|
110
103
|
})();
|
|
111
104
|
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
@@ -306,30 +306,17 @@ async function captureFailureResult(agent, actionName, errorMessage) {
|
|
|
306
306
|
};
|
|
307
307
|
}
|
|
308
308
|
}
|
|
309
|
-
function
|
|
310
|
-
const options = {
|
|
311
|
-
...base?.options ?? {},
|
|
312
|
-
...extra?.options ?? {}
|
|
313
|
-
};
|
|
314
|
-
return Object.keys(options).length > 0 ? {
|
|
315
|
-
options
|
|
316
|
-
} : void 0;
|
|
317
|
-
}
|
|
318
|
-
function generateToolsFromActionSpace(actionSpace, getAgent, sanitizeArgs = (args)=>args, initArgSchema = {}, initArgCliMetadata) {
|
|
309
|
+
function generateToolsFromActionSpace(actionSpace, getAgent) {
|
|
319
310
|
return actionSpace.map((action)=>{
|
|
320
|
-
const schema =
|
|
321
|
-
...extractActionSchema(action.paramSchema),
|
|
322
|
-
...initArgSchema
|
|
323
|
-
};
|
|
311
|
+
const schema = extractActionSchema(action.paramSchema);
|
|
324
312
|
return {
|
|
325
313
|
name: action.name,
|
|
326
314
|
description: describeActionForMCP(action),
|
|
327
315
|
schema,
|
|
328
|
-
cli: initArgCliMetadata,
|
|
329
316
|
handler: async (args)=>{
|
|
330
317
|
try {
|
|
331
|
-
const agent = await getAgent(
|
|
332
|
-
const normalizedArgs = normalizeActionArgs(
|
|
318
|
+
const agent = await getAgent();
|
|
319
|
+
const normalizedArgs = normalizeActionArgs(args, action.paramSchema);
|
|
333
320
|
let actionResult;
|
|
334
321
|
try {
|
|
335
322
|
actionResult = await executeAction(agent, action.name, normalizedArgs);
|
|
@@ -348,18 +335,15 @@ function generateToolsFromActionSpace(actionSpace, getAgent, sanitizeArgs = (arg
|
|
|
348
335
|
};
|
|
349
336
|
});
|
|
350
337
|
}
|
|
351
|
-
function generateCommonTools(getAgent
|
|
338
|
+
function generateCommonTools(getAgent) {
|
|
352
339
|
return [
|
|
353
340
|
{
|
|
354
341
|
name: 'take_screenshot',
|
|
355
342
|
description: 'Capture screenshot of current page/screen',
|
|
356
|
-
schema: {
|
|
357
|
-
|
|
358
|
-
},
|
|
359
|
-
cli: initArgCliMetadata,
|
|
360
|
-
handler: async (args = {})=>{
|
|
343
|
+
schema: {},
|
|
344
|
+
handler: async ()=>{
|
|
361
345
|
try {
|
|
362
|
-
const agent = await getAgent(
|
|
346
|
+
const agent = await getAgent();
|
|
363
347
|
const screenshot = await agent.page?.screenshotBase64();
|
|
364
348
|
if (!screenshot) return createErrorResult('Screenshot not available');
|
|
365
349
|
const { mimeType, body } = (0, img_namespaceObject.parseBase64)(screenshot);
|
|
@@ -383,14 +367,12 @@ function generateCommonTools(getAgent, initArgSchema = {}, initArgCliMetadata) {
|
|
|
383
367
|
name: 'act',
|
|
384
368
|
description: 'Execute a natural language action. The AI will plan and perform multi-step operations in a single invocation, useful for transient UI interactions (e.g., Spotlight, dropdown menus) that disappear between separate commands.',
|
|
385
369
|
schema: {
|
|
386
|
-
prompt: external_zod_namespaceObject.z.string().describe('Natural language description of the action to perform, e.g. "press Command+Space, type Safari, press Enter"')
|
|
387
|
-
...initArgSchema
|
|
370
|
+
prompt: external_zod_namespaceObject.z.string().describe('Natural language description of the action to perform, e.g. "press Command+Space, type Safari, press Enter"')
|
|
388
371
|
},
|
|
389
|
-
|
|
390
|
-
handler: async (args = {})=>{
|
|
372
|
+
handler: async (args)=>{
|
|
391
373
|
const prompt = args.prompt;
|
|
392
374
|
try {
|
|
393
|
-
const agent = await getAgent(
|
|
375
|
+
const agent = await getAgent();
|
|
394
376
|
if (!agent.aiAction) return createErrorResult('act is not supported by this agent');
|
|
395
377
|
const result = await agent.aiAction(prompt, {
|
|
396
378
|
deepThink: false
|
|
@@ -19,6 +19,4 @@ export declare class CLIError extends Error {
|
|
|
19
19
|
export declare function parseValue(raw: string): unknown;
|
|
20
20
|
export declare function parseCliArgs(args: string[]): Record<string, unknown>;
|
|
21
21
|
export declare function removePrefix(name: string, prefix?: string): string;
|
|
22
|
-
|
|
23
|
-
export declare function runToolsCLI(tools: AnyMidsceneTools, scriptName: string, options?: CLIRunnerOptions): Promise<void>;
|
|
24
|
-
export {};
|
|
22
|
+
export declare function runToolsCLI(tools: BaseMidsceneTools, scriptName: string, options?: CLIRunnerOptions): Promise<void>;
|
|
@@ -1,52 +1,13 @@
|
|
|
1
1
|
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
2
|
-
import type {
|
|
3
|
-
import type { BaseAgent, BaseDevice, IMidsceneTools, ToolCliMetadata, ToolDefinition, ToolSchema } from './types';
|
|
2
|
+
import type { BaseAgent, BaseDevice, IMidsceneTools, ToolDefinition } from './types';
|
|
4
3
|
/**
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
* `getAgentInitArgSchema` trio into a single data declaration.
|
|
4
|
+
* Base class for platform-specific MCP tools
|
|
5
|
+
* Generic type TAgent allows subclasses to use their specific agent types
|
|
8
6
|
*/
|
|
9
|
-
export
|
|
10
|
-
/** Arg namespace, e.g. `android`, `ios`. */
|
|
11
|
-
namespace: string;
|
|
12
|
-
/** Zod shape describing the init args. Field names drive the MCP schema. */
|
|
13
|
-
shape: Record<string, z.ZodTypeAny>;
|
|
14
|
-
/**
|
|
15
|
-
* Optional CLI presentation hints. These affect `--help` output for
|
|
16
|
-
* single-platform CLIs but do not alter MCP/YAML protocol keys.
|
|
17
|
-
*/
|
|
18
|
-
cli?: {
|
|
19
|
-
/** Prefer bare `--device-id`-style options in platform CLI help output. */
|
|
20
|
-
preferBareKeys?: boolean;
|
|
21
|
-
/** Override the displayed option name for specific init arg fields. */
|
|
22
|
-
preferredNames?: Record<string, string>;
|
|
23
|
-
};
|
|
24
|
-
/**
|
|
25
|
-
* Adapt extracted namespaced args into the concrete `TInitParam` passed to
|
|
26
|
-
* `ensureAgent`. Defaults to returning the raw extracted record.
|
|
27
|
-
*/
|
|
28
|
-
adapt?: (extracted: Record<string, unknown> | undefined) => TInitParam | undefined;
|
|
29
|
-
}
|
|
30
|
-
/**
|
|
31
|
-
* Base class for platform-specific MCP tools.
|
|
32
|
-
* @typeParam TAgent - Platform-specific agent type.
|
|
33
|
-
* @typeParam TInitParam - Platform-specific init parameter consumed by
|
|
34
|
-
* `ensureAgent`. Defaults to `undefined` for platforms that take no args.
|
|
35
|
-
*/
|
|
36
|
-
export declare abstract class BaseMidsceneTools<TAgent extends BaseAgent = BaseAgent, TInitParam = unknown> implements IMidsceneTools {
|
|
7
|
+
export declare abstract class BaseMidsceneTools<TAgent extends BaseAgent = BaseAgent> implements IMidsceneTools {
|
|
37
8
|
protected mcpServer?: McpServer;
|
|
38
9
|
protected agent?: TAgent;
|
|
39
10
|
protected toolDefinitions: ToolDefinition[];
|
|
40
|
-
/**
|
|
41
|
-
* Declarative init-arg spec. Subclasses that accept CLI/MCP init args should
|
|
42
|
-
* set this once and get `extractAgentInitParam` / `sanitizeToolArgs` /
|
|
43
|
-
* `getAgentInitArgSchema` auto-implemented.
|
|
44
|
-
*
|
|
45
|
-
* Declared with `declare` so that TS doesn't emit an `Object.defineProperty`
|
|
46
|
-
* for this field on the base constructor, which would otherwise overwrite
|
|
47
|
-
* a subclass field initializer under `useDefineForClassFields`.
|
|
48
|
-
*/
|
|
49
|
-
protected readonly initArgSpec?: InitArgSpec<TInitParam>;
|
|
50
11
|
/**
|
|
51
12
|
* Ensure agent is initialized and ready for use.
|
|
52
13
|
* Must be implemented by subclasses to create platform-specific agent.
|
|
@@ -54,25 +15,7 @@ export declare abstract class BaseMidsceneTools<TAgent extends BaseAgent = BaseA
|
|
|
54
15
|
* @returns Promise resolving to initialized agent instance
|
|
55
16
|
* @throws Error if agent initialization fails
|
|
56
17
|
*/
|
|
57
|
-
protected abstract ensureAgent(initParam?:
|
|
58
|
-
private getInitArgKeys;
|
|
59
|
-
/**
|
|
60
|
-
* Extract a platform-specific agent init parameter from CLI/MCP tool args.
|
|
61
|
-
*/
|
|
62
|
-
protected extractAgentInitParam(args: Record<string, unknown>): TInitParam | undefined;
|
|
63
|
-
/**
|
|
64
|
-
* Remove platform-specific init args before dispatching a tool payload to the action itself.
|
|
65
|
-
*/
|
|
66
|
-
protected sanitizeToolArgs(args: Record<string, unknown>): Record<string, unknown>;
|
|
67
|
-
/**
|
|
68
|
-
* Expose platform-specific init args on action/common tool schemas.
|
|
69
|
-
*/
|
|
70
|
-
protected getAgentInitArgSchema(): ToolSchema;
|
|
71
|
-
/**
|
|
72
|
-
* Expose CLI-only metadata for platform init args so single-platform help can
|
|
73
|
-
* show ergonomic bare flags while the underlying schema stays namespaced.
|
|
74
|
-
*/
|
|
75
|
-
protected getAgentInitArgCliMetadata(): ToolCliMetadata | undefined;
|
|
18
|
+
protected abstract ensureAgent(initParam?: string): Promise<TAgent>;
|
|
76
19
|
/**
|
|
77
20
|
* Optional: prepare platform-specific tools (e.g., device connection)
|
|
78
21
|
*/
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import type { ActionSpaceItem, BaseAgent,
|
|
1
|
+
import type { ActionSpaceItem, BaseAgent, ToolDefinition } from './types';
|
|
2
2
|
/**
|
|
3
3
|
* Converts DeviceAction from actionSpace into MCP ToolDefinition
|
|
4
4
|
* This is the core logic that removes need for hardcoded tool definitions
|
|
5
5
|
*/
|
|
6
|
-
export declare function generateToolsFromActionSpace(actionSpace: ActionSpaceItem[], getAgent: (
|
|
6
|
+
export declare function generateToolsFromActionSpace(actionSpace: ActionSpaceItem[], getAgent: () => Promise<BaseAgent>): ToolDefinition[];
|
|
7
7
|
/**
|
|
8
8
|
* Generate common tools (screenshot, act)
|
|
9
9
|
*/
|
|
10
|
-
export declare function generateCommonTools(getAgent: (
|
|
10
|
+
export declare function generateCommonTools(getAgent: () => Promise<BaseAgent>): ToolDefinition[];
|
|
@@ -49,13 +49,6 @@ export type ToolHandler<T = Record<string, unknown>> = (args: T) => Promise<Tool
|
|
|
49
49
|
* Tool schema type using Zod
|
|
50
50
|
*/
|
|
51
51
|
export type ToolSchema = Record<string, z.ZodTypeAny>;
|
|
52
|
-
export interface ToolCliOption {
|
|
53
|
-
preferredName?: string;
|
|
54
|
-
aliases?: string[];
|
|
55
|
-
}
|
|
56
|
-
export interface ToolCliMetadata {
|
|
57
|
-
options?: Record<string, ToolCliOption>;
|
|
58
|
-
}
|
|
59
52
|
/**
|
|
60
53
|
* Tool definition for MCP server
|
|
61
54
|
*/
|
|
@@ -64,7 +57,6 @@ export interface ToolDefinition<T = Record<string, unknown>> {
|
|
|
64
57
|
description: string;
|
|
65
58
|
schema: ToolSchema;
|
|
66
59
|
handler: ToolHandler<T>;
|
|
67
|
-
cli?: ToolCliMetadata;
|
|
68
60
|
}
|
|
69
61
|
/**
|
|
70
62
|
* Tool type for mcpKitForAgent return value
|