@midscene/core 1.12.4-beta-20260904041024.0 → 1.12.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/agent.mjs +72 -25
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/index.mjs +2 -1
- package/dist/es/agent/insight.mjs +26 -10
- package/dist/es/agent/insight.mjs.map +1 -1
- package/dist/es/agent/prompt-context.mjs +12 -7
- package/dist/es/agent/prompt-context.mjs.map +1 -1
- package/dist/es/agent/run-gherkin-scenario.mjs +1 -1
- package/dist/es/agent/run-gherkin-scenario.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +2 -1
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/test-runner-nodes.mjs +274 -0
- package/dist/es/agent/test-runner-nodes.mjs.map +1 -0
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/ai-model/prompt/insight/user-prompt.mjs +1 -1
- package/dist/es/ai-model/prompt/insight/user-prompt.mjs.map +1 -1
- package/dist/es/ai-model/workflows/insight/extraction.mjs +3 -1
- package/dist/es/ai-model/workflows/insight/extraction.mjs.map +1 -1
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs +3 -3
- package/dist/es/ai-model/workflows/planning/custom-planning.mjs.map +1 -1
- package/dist/es/ai-model/workflows/planning/standard-planning.mjs +1 -1
- package/dist/es/ai-model/workflows/planning/standard-planning.mjs.map +1 -1
- package/dist/es/report-html-template.mjs +1 -1
- package/dist/es/types.mjs.map +1 -1
- package/dist/es/utils.mjs +1 -1
- package/dist/es/yaml/player.mjs +0 -5
- package/dist/es/yaml/player.mjs.map +1 -1
- package/dist/es/yaml.mjs.map +1 -1
- package/dist/lib/agent/agent.js +72 -25
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/index.js +57 -8
- package/dist/lib/agent/insight.js +26 -10
- package/dist/lib/agent/insight.js.map +1 -1
- package/dist/lib/agent/prompt-context.js +16 -8
- package/dist/lib/agent/prompt-context.js.map +1 -1
- package/dist/lib/agent/run-gherkin-scenario.js +1 -1
- package/dist/lib/agent/run-gherkin-scenario.js.map +1 -1
- package/dist/lib/agent/tasks.js +2 -1
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/test-runner-nodes.js +353 -0
- package/dist/lib/agent/test-runner-nodes.js.map +1 -0
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/ai-model/prompt/insight/user-prompt.js +1 -1
- package/dist/lib/ai-model/prompt/insight/user-prompt.js.map +1 -1
- package/dist/lib/ai-model/workflows/insight/extraction.js +3 -1
- package/dist/lib/ai-model/workflows/insight/extraction.js.map +1 -1
- package/dist/lib/ai-model/workflows/planning/custom-planning.js +3 -3
- package/dist/lib/ai-model/workflows/planning/custom-planning.js.map +1 -1
- package/dist/lib/ai-model/workflows/planning/standard-planning.js +1 -1
- package/dist/lib/ai-model/workflows/planning/standard-planning.js.map +1 -1
- package/dist/lib/report-html-template.js +1 -1
- package/dist/lib/types.js.map +1 -1
- package/dist/lib/utils.js +1 -1
- package/dist/lib/yaml/player.js +0 -5
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/lib/yaml.js.map +1 -1
- package/dist/types/agent/agent.d.ts +26 -3
- package/dist/types/agent/index.d.ts +3 -1
- package/dist/types/agent/insight.d.ts +5 -1
- package/dist/types/agent/prompt-context.d.ts +2 -0
- package/dist/types/agent/run-gherkin-scenario.d.ts +1 -0
- package/dist/types/agent/test-runner-nodes.d.ts +192 -0
- package/dist/types/types.d.ts +28 -0
- package/dist/types/yaml.d.ts +12 -4
- package/package.json +10 -2
package/dist/es/agent/agent.mjs
CHANGED
|
@@ -10,6 +10,7 @@ import { getVersion, processCacheConfig, reportHTMLContent } from "../utils.mjs"
|
|
|
10
10
|
import { ScriptPlayer, buildDetailedLocateParam, buildDetailedLocateParamAndRestParams, parseYamlScript } from "../yaml/index.mjs";
|
|
11
11
|
import { readFile } from "node:fs/promises";
|
|
12
12
|
import { basename, resolve as external_node_path_resolve } from "node:path";
|
|
13
|
+
import { isAgentAIContextKey } from "@midscene/shared/agent-tools/agent-context";
|
|
13
14
|
import { serializeError } from "@midscene/shared/agent-tools/error-formatter";
|
|
14
15
|
import { observationArtifactAdapterSymbol } from "@midscene/shared/agent-tools/observation-artifact";
|
|
15
16
|
import { MIDSCENE_REPLANNING_CYCLE_LIMIT, ModelConfigManager, globalConfigManager, globalModelConfigManager } from "@midscene/shared/env";
|
|
@@ -27,6 +28,7 @@ import { runGherkinScenario } from "./run-gherkin-scenario.mjs";
|
|
|
27
28
|
import { markdownToAiActPrompt } from "./run-markdown.mjs";
|
|
28
29
|
import { TaskCache } from "./task-cache.mjs";
|
|
29
30
|
import { TaskExecutor, locatePlanForLocate, withFileChooser } from "./tasks.mjs";
|
|
31
|
+
import { commonAgentTestRunnerNodeDefinitions } from "./test-runner-nodes.mjs";
|
|
30
32
|
import { UIObservationImpl, UIObserverImpl, uiContextFromObservationRecord } from "./ui-observer.mjs";
|
|
31
33
|
import { locateParamStr, paramStr, taskTitleStr, typeStr } from "./ui-utils.mjs";
|
|
32
34
|
import { commonContextParser, getReportFileName, normalizeFilePaths, normalizeScrollType } from "./utils.mjs";
|
|
@@ -45,6 +47,9 @@ const warn = getDebug('agent', {
|
|
|
45
47
|
console: true
|
|
46
48
|
});
|
|
47
49
|
class Agent {
|
|
50
|
+
static getTestRunnerNodeDefinitions() {
|
|
51
|
+
return commonAgentTestRunnerNodeDefinitions;
|
|
52
|
+
}
|
|
48
53
|
get onDumpUpdate() {
|
|
49
54
|
return this.dumpUpdateListeners[0];
|
|
50
55
|
}
|
|
@@ -52,8 +57,24 @@ class Agent {
|
|
|
52
57
|
this.dumpUpdateListeners = [];
|
|
53
58
|
if (callback) this.dumpUpdateListeners.push(callback);
|
|
54
59
|
}
|
|
55
|
-
get
|
|
56
|
-
|
|
60
|
+
get aiContexts() {
|
|
61
|
+
if (!this.opts.aiContexts) this.opts.aiContexts = {};
|
|
62
|
+
return this.opts.aiContexts;
|
|
63
|
+
}
|
|
64
|
+
resolveUserContext(apiName, callContext) {
|
|
65
|
+
if (void 0 !== callContext) return callContext;
|
|
66
|
+
const apiContext = this.opts.aiContexts?.[apiName];
|
|
67
|
+
if (void 0 !== apiContext) return apiContext;
|
|
68
|
+
const defaultContext = this.opts.aiContexts?.default;
|
|
69
|
+
if (void 0 !== defaultContext) return defaultContext;
|
|
70
|
+
}
|
|
71
|
+
withContext(apiName, options) {
|
|
72
|
+
const resolvedContext = this.resolveUserContext(apiName, options?.context);
|
|
73
|
+
if (void 0 === resolvedContext) return options;
|
|
74
|
+
return {
|
|
75
|
+
...options ?? {},
|
|
76
|
+
context: resolvedContext
|
|
77
|
+
};
|
|
57
78
|
}
|
|
58
79
|
get page() {
|
|
59
80
|
return this.interface;
|
|
@@ -79,7 +100,7 @@ class Agent {
|
|
|
79
100
|
};
|
|
80
101
|
}
|
|
81
102
|
createInsight(getUIContext) {
|
|
82
|
-
return new Insight(this.taskExecutor, ()=>this.resolveModelRuntime('insight'), getUIContext);
|
|
103
|
+
return new Insight(this.taskExecutor, ()=>this.resolveModelRuntime('insight'), (apiName, callContext)=>this.resolveUserContext(apiName, callContext), getUIContext);
|
|
83
104
|
}
|
|
84
105
|
async getActionSpace() {
|
|
85
106
|
return this.fullActionSpace;
|
|
@@ -140,12 +161,24 @@ class Agent {
|
|
|
140
161
|
return observer;
|
|
141
162
|
}
|
|
142
163
|
async setAIActionContext(prompt) {
|
|
143
|
-
|
|
164
|
+
warn('setAIActionContext() is deprecated; use setAIContext("aiAct", context) instead.');
|
|
165
|
+
this.setAIContext('aiAct', prompt);
|
|
144
166
|
}
|
|
145
167
|
async setAIActContext(prompt) {
|
|
146
|
-
|
|
147
|
-
this.
|
|
148
|
-
|
|
168
|
+
warn('setAIActContext() is deprecated; use setAIContext("aiAct", context) instead.');
|
|
169
|
+
this.setAIContext('aiAct', prompt);
|
|
170
|
+
}
|
|
171
|
+
setAIContext(target, context) {
|
|
172
|
+
if (!isAgentAIContextKey(target)) throw new TypeError(`Unknown Agent context key: ${String(target)}`);
|
|
173
|
+
if (void 0 !== context && 'string' != typeof context) throw new TypeError('Agent context must be a string or undefined');
|
|
174
|
+
this.aiContexts[target] = context;
|
|
175
|
+
if ('aiAct' === target) if (void 0 === context) {
|
|
176
|
+
this.opts.aiActContext = void 0;
|
|
177
|
+
this.opts.aiActionContext = void 0;
|
|
178
|
+
} else {
|
|
179
|
+
this.opts.aiActContext = context;
|
|
180
|
+
this.opts.aiActionContext = context;
|
|
181
|
+
}
|
|
149
182
|
}
|
|
150
183
|
resetDump() {
|
|
151
184
|
this.dump = new ReportActionDump({
|
|
@@ -249,7 +282,7 @@ class Agent {
|
|
|
249
282
|
}
|
|
250
283
|
async aiTap(locatePrompt, opt) {
|
|
251
284
|
assert(locatePrompt, 'missing locate prompt for tap');
|
|
252
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
285
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiTap', opt));
|
|
253
286
|
const fileChooserAccept = opt?.fileChooserAccept ? this.normalizeFileInput(opt.fileChooserAccept) : void 0;
|
|
254
287
|
await withFileChooser(this.interface, fileChooserAccept, async ()=>{
|
|
255
288
|
await this.callActionInActionSpace('Tap', {
|
|
@@ -259,21 +292,21 @@ class Agent {
|
|
|
259
292
|
}
|
|
260
293
|
async aiRightClick(locatePrompt, opt) {
|
|
261
294
|
assert(locatePrompt, 'missing locate prompt for right click');
|
|
262
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
295
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiRightClick', opt));
|
|
263
296
|
await this.callActionInActionSpace('RightClick', {
|
|
264
297
|
locate: detailedLocateParam
|
|
265
298
|
});
|
|
266
299
|
}
|
|
267
300
|
async aiDoubleClick(locatePrompt, opt) {
|
|
268
301
|
assert(locatePrompt, 'missing locate prompt for double click');
|
|
269
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
302
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiDoubleClick', opt));
|
|
270
303
|
await this.callActionInActionSpace('DoubleClick', {
|
|
271
304
|
locate: detailedLocateParam
|
|
272
305
|
});
|
|
273
306
|
}
|
|
274
307
|
async aiHover(locatePrompt, opt) {
|
|
275
308
|
assert(locatePrompt, 'missing locate prompt for hover');
|
|
276
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
309
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiHover', opt));
|
|
277
310
|
await this.callActionInActionSpace('Hover', {
|
|
278
311
|
locate: detailedLocateParam
|
|
279
312
|
});
|
|
@@ -297,7 +330,7 @@ class Agent {
|
|
|
297
330
|
}
|
|
298
331
|
assert('string' == typeof value || 'number' == typeof value, 'input value must be a string or number, use empty string if you want to clear the input');
|
|
299
332
|
assert(locatePrompt, 'missing locate prompt for input');
|
|
300
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, opt);
|
|
333
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, this.withContext('aiInput', opt));
|
|
301
334
|
const stringValue = 'number' == typeof value ? String(value) : value;
|
|
302
335
|
const mode = opt?.mode === 'append' ? 'typeOnly' : opt?.mode;
|
|
303
336
|
await this.callActionInActionSpace('Input', {
|
|
@@ -323,7 +356,7 @@ class Agent {
|
|
|
323
356
|
};
|
|
324
357
|
}
|
|
325
358
|
assert(opt?.keyName, 'missing keyName for keyboard press');
|
|
326
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', opt);
|
|
359
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', this.withContext('aiKeyboardPress', opt));
|
|
327
360
|
await this.callActionInActionSpace('KeyboardPress', {
|
|
328
361
|
...restParams,
|
|
329
362
|
locate: locateParam
|
|
@@ -355,14 +388,14 @@ class Agent {
|
|
|
355
388
|
scrollType: normalizedScrollType
|
|
356
389
|
};
|
|
357
390
|
}
|
|
358
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', opt);
|
|
391
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', this.withContext('aiScroll', opt));
|
|
359
392
|
await this.callActionInActionSpace('Scroll', {
|
|
360
393
|
...restParams,
|
|
361
394
|
locate: locateParam
|
|
362
395
|
});
|
|
363
396
|
}
|
|
364
397
|
async aiPinch(locatePrompt, opt) {
|
|
365
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', opt);
|
|
398
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', this.withContext('aiPinch', opt));
|
|
366
399
|
await this.callActionInActionSpace('Pinch', {
|
|
367
400
|
...restParams,
|
|
368
401
|
locate: locateParam
|
|
@@ -370,7 +403,7 @@ class Agent {
|
|
|
370
403
|
}
|
|
371
404
|
async aiLongPress(locatePrompt, opt) {
|
|
372
405
|
assert(locatePrompt, 'missing locate prompt for long press');
|
|
373
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, opt);
|
|
406
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, this.withContext('aiLongPress', opt));
|
|
374
407
|
await this.callActionInActionSpace('LongPress', {
|
|
375
408
|
...restParams,
|
|
376
409
|
locate: locateParam
|
|
@@ -378,13 +411,14 @@ class Agent {
|
|
|
378
411
|
}
|
|
379
412
|
async aiClearInput(locatePrompt, opt) {
|
|
380
413
|
assert(locatePrompt, 'missing locate prompt for clear input');
|
|
381
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
414
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiClearInput', opt));
|
|
382
415
|
await this.callActionInActionSpace('ClearInput', {
|
|
383
416
|
locate: detailedLocateParam
|
|
384
417
|
});
|
|
385
418
|
}
|
|
386
419
|
async aiAct(taskPrompt, opt) {
|
|
387
|
-
const
|
|
420
|
+
const internalOptions = opt;
|
|
421
|
+
const internalReportDisplay = internalOptions?._internalReportDisplay;
|
|
388
422
|
const taskPromptText = 'string' == typeof taskPrompt ? taskPrompt : taskPrompt.prompt;
|
|
389
423
|
const reportPrompt = internalReportDisplay?.prompt || taskPromptText;
|
|
390
424
|
const fileChooserAccept = opt?.fileChooserAccept ? this.normalizeFileInput(opt.fileChooserAccept) : void 0;
|
|
@@ -393,7 +427,7 @@ class Agent {
|
|
|
393
427
|
const runAiAct = async ()=>{
|
|
394
428
|
const planningModel = this.resolveModelRuntime('planning');
|
|
395
429
|
const defaultModel = this.resolveModelRuntime('default');
|
|
396
|
-
const aiActContext = opt?.context
|
|
430
|
+
const aiActContext = this.resolveUserContext('aiAct', opt?.context);
|
|
397
431
|
const cachePrompt = buildPromptWithContext(taskPrompt, aiActContext);
|
|
398
432
|
const effort = (()=>{
|
|
399
433
|
const resolvedEffort = opt?.effort ?? (opt?.deepThink === true ? 'deepThink' : 'balance');
|
|
@@ -511,7 +545,7 @@ class Agent {
|
|
|
511
545
|
return this.createInsight().aiAsk(prompt, opt);
|
|
512
546
|
}
|
|
513
547
|
async aiLocate(prompt, opt) {
|
|
514
|
-
const locateParam = buildDetailedLocateParam(prompt, opt);
|
|
548
|
+
const locateParam = buildDetailedLocateParam(prompt, this.withContext('aiLocate', opt));
|
|
515
549
|
assert(locateParam, 'cannot get locate param for aiLocate');
|
|
516
550
|
const locatePlan = locatePlanForLocate(locateParam);
|
|
517
551
|
const plans = [
|
|
@@ -534,10 +568,11 @@ class Agent {
|
|
|
534
568
|
}
|
|
535
569
|
async aiWaitFor(assertion, opt) {
|
|
536
570
|
const modelRuntime = this.resolveModelRuntime('insight');
|
|
571
|
+
const options = this.withContext('aiWaitFor', opt);
|
|
537
572
|
await this.taskExecutor.waitFor(assertion, {
|
|
538
|
-
...
|
|
539
|
-
timeoutMs:
|
|
540
|
-
checkIntervalMs:
|
|
573
|
+
...options,
|
|
574
|
+
timeoutMs: options?.timeoutMs || 15000,
|
|
575
|
+
checkIntervalMs: options?.checkIntervalMs || 3000
|
|
541
576
|
}, modelRuntime);
|
|
542
577
|
}
|
|
543
578
|
async ai(...args) {
|
|
@@ -806,11 +841,23 @@ class Agent {
|
|
|
806
841
|
groupDescription: ''
|
|
807
842
|
}, opts || {});
|
|
808
843
|
assertReportGenerationOptions(this.opts);
|
|
809
|
-
|
|
844
|
+
if (void 0 !== this.opts.aiContexts && ('object' != typeof this.opts.aiContexts || null === this.opts.aiContexts || Array.isArray(this.opts.aiContexts))) throw new TypeError('opts.aiContexts must be a plain object');
|
|
845
|
+
for (const [key, value] of Object.entries(this.opts.aiContexts ?? {})){
|
|
846
|
+
if (!isAgentAIContextKey(key)) throw new TypeError(`Unknown Agent context key: ${key}`);
|
|
847
|
+
if (void 0 !== value && 'string' != typeof value) throw new TypeError(`Agent context "${key}" must be a string`);
|
|
848
|
+
}
|
|
849
|
+
const deprecatedAiActContextOption = void 0 !== this.opts.aiActContext ? 'aiActContext' : void 0 !== this.opts.aiActionContext ? 'aiActionContext' : void 0;
|
|
850
|
+
if (deprecatedAiActContextOption) warn(`Agent option "${deprecatedAiActContextOption}" is deprecated; use "aiContexts.aiAct" instead. When both are provided, "aiContexts.aiAct" takes precedence.`);
|
|
851
|
+
const normalizedAIContexts = {
|
|
852
|
+
...this.opts.aiContexts
|
|
853
|
+
};
|
|
854
|
+
const resolvedAiActContext = normalizedAIContexts.aiAct ?? this.opts.aiActContext ?? this.opts.aiActionContext;
|
|
810
855
|
if (void 0 !== resolvedAiActContext) {
|
|
856
|
+
normalizedAIContexts.aiAct = resolvedAiActContext;
|
|
811
857
|
this.opts.aiActContext = resolvedAiActContext;
|
|
812
|
-
this.opts.aiActionContext
|
|
858
|
+
this.opts.aiActionContext = resolvedAiActContext;
|
|
813
859
|
}
|
|
860
|
+
this.opts.aiContexts = normalizedAIContexts;
|
|
814
861
|
if (opts?.modelConfig && ('object' != typeof opts?.modelConfig || Array.isArray(opts.modelConfig))) throw new Error(`opts.modelConfig must be a plain object map of env keys to values, but got ${typeof opts?.modelConfig}`);
|
|
815
862
|
const hasCustomConfig = opts?.modelConfig || opts?.createOpenAIClient;
|
|
816
863
|
this.modelConfigManager = hasCustomConfig ? new ModelConfigManager(opts?.modelConfig, opts?.createOpenAIClient) : globalModelConfigManager;
|