@midscene/core 1.12.3 → 1.12.4-beta-20260902093735.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/agent/agent.mjs +88 -25
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/index.mjs +2 -1
- package/dist/es/agent/insight.mjs +40 -10
- package/dist/es/agent/insight.mjs.map +1 -1
- package/dist/es/agent/prompt-context.mjs +42 -6
- package/dist/es/agent/prompt-context.mjs.map +1 -1
- package/dist/es/agent/run-gherkin-scenario.mjs.map +1 -1
- 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 +4 -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/index.mjs +2 -2
- package/dist/es/index.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/utils.mjs +4 -3
- package/dist/es/yaml/utils.mjs.map +1 -1
- package/dist/lib/agent/agent.js +87 -24
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/index.js +5 -1
- package/dist/lib/agent/insight.js +40 -10
- package/dist/lib/agent/insight.js.map +1 -1
- package/dist/lib/agent/prompt-context.js +55 -7
- package/dist/lib/agent/prompt-context.js.map +1 -1
- package/dist/lib/agent/run-gherkin-scenario.js.map +1 -1
- 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 +4 -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/index.js +4 -1
- package/dist/lib/index.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/utils.js +3 -2
- package/dist/lib/yaml/utils.js.map +1 -1
- package/dist/types/agent/agent.d.ts +22 -3
- package/dist/types/agent/index.d.ts +2 -1
- package/dist/types/agent/insight.d.ts +6 -1
- package/dist/types/agent/prompt-context.d.ts +27 -1
- package/dist/types/agent/run-gherkin-scenario.d.ts +1 -0
- package/dist/types/index.d.ts +1 -1
- package/dist/types/types.d.ts +26 -0
- package/dist/types/yaml.d.ts +12 -4
- package/package.json +2 -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 { isAgentContextKey } 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";
|
|
@@ -21,7 +22,7 @@ import { FileChooserAccepter } from "./file-chooser.mjs";
|
|
|
21
22
|
import { Insight } from "./insight.mjs";
|
|
22
23
|
import { MetricsCollector } from "./metrics.mjs";
|
|
23
24
|
import { AgentProgressBus } from "./progress/index.mjs";
|
|
24
|
-
import { buildPromptWithContext } from "./prompt-context.mjs";
|
|
25
|
+
import { INTERNAL_AI_CONTEXT_METADATA_KEY, buildPromptWithContext, renderAIContext } from "./prompt-context.mjs";
|
|
25
26
|
import { normalizeRecordToReportScreenshot } from "./record-to-report.mjs";
|
|
26
27
|
import { runGherkinScenario } from "./run-gherkin-scenario.mjs";
|
|
27
28
|
import { markdownToAiActPrompt } from "./run-markdown.mjs";
|
|
@@ -52,8 +53,44 @@ class Agent {
|
|
|
52
53
|
this.dumpUpdateListeners = [];
|
|
53
54
|
if (callback) this.dumpUpdateListeners.push(callback);
|
|
54
55
|
}
|
|
55
|
-
get
|
|
56
|
-
|
|
56
|
+
get contexts() {
|
|
57
|
+
if (!this.opts.contexts) this.opts.contexts = {};
|
|
58
|
+
return this.opts.contexts;
|
|
59
|
+
}
|
|
60
|
+
resolveUserContext(apiName, callContext) {
|
|
61
|
+
if (void 0 !== callContext) return {
|
|
62
|
+
value: callContext,
|
|
63
|
+
metadata: {
|
|
64
|
+
source: 'call'
|
|
65
|
+
}
|
|
66
|
+
};
|
|
67
|
+
const apiContext = this.opts.contexts?.[apiName];
|
|
68
|
+
if (void 0 !== apiContext) return {
|
|
69
|
+
value: apiContext,
|
|
70
|
+
metadata: {
|
|
71
|
+
source: 'api',
|
|
72
|
+
apiName
|
|
73
|
+
}
|
|
74
|
+
};
|
|
75
|
+
const defaultContext = this.opts.contexts?.default;
|
|
76
|
+
if (void 0 !== defaultContext) return {
|
|
77
|
+
value: defaultContext,
|
|
78
|
+
metadata: {
|
|
79
|
+
source: 'default'
|
|
80
|
+
}
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
resolveContext(apiName, callContext, additionalContext) {
|
|
84
|
+
return renderAIContext(this.resolveUserContext(apiName, callContext), additionalContext);
|
|
85
|
+
}
|
|
86
|
+
withContext(apiName, options) {
|
|
87
|
+
const resolvedContext = this.resolveUserContext(apiName, options?.context);
|
|
88
|
+
if (void 0 === resolvedContext) return options;
|
|
89
|
+
return {
|
|
90
|
+
...options ?? {},
|
|
91
|
+
context: resolvedContext.value,
|
|
92
|
+
[INTERNAL_AI_CONTEXT_METADATA_KEY]: resolvedContext.metadata
|
|
93
|
+
};
|
|
57
94
|
}
|
|
58
95
|
get page() {
|
|
59
96
|
return this.interface;
|
|
@@ -79,7 +116,7 @@ class Agent {
|
|
|
79
116
|
};
|
|
80
117
|
}
|
|
81
118
|
createInsight(getUIContext) {
|
|
82
|
-
return new Insight(this.taskExecutor, ()=>this.resolveModelRuntime('insight'), getUIContext);
|
|
119
|
+
return new Insight(this.taskExecutor, ()=>this.resolveModelRuntime('insight'), getUIContext, (apiName, callContext)=>this.resolveUserContext(apiName, callContext));
|
|
83
120
|
}
|
|
84
121
|
async getActionSpace() {
|
|
85
122
|
return this.fullActionSpace;
|
|
@@ -140,12 +177,24 @@ class Agent {
|
|
|
140
177
|
return observer;
|
|
141
178
|
}
|
|
142
179
|
async setAIActionContext(prompt) {
|
|
143
|
-
|
|
180
|
+
warn('setAIActionContext() is deprecated; use setContext("aiAct", context) instead.');
|
|
181
|
+
this.setContext('aiAct', prompt);
|
|
144
182
|
}
|
|
145
183
|
async setAIActContext(prompt) {
|
|
146
|
-
|
|
147
|
-
this.
|
|
148
|
-
|
|
184
|
+
warn('setAIActContext() is deprecated; use setContext("aiAct", context) instead.');
|
|
185
|
+
this.setContext('aiAct', prompt);
|
|
186
|
+
}
|
|
187
|
+
setContext(target, context) {
|
|
188
|
+
if (!isAgentContextKey(target)) throw new TypeError(`Unknown Agent context key: ${String(target)}`);
|
|
189
|
+
if (void 0 !== context && 'string' != typeof context) throw new TypeError('Agent context must be a string or undefined');
|
|
190
|
+
this.contexts[target] = context;
|
|
191
|
+
if ('aiAct' === target) if (void 0 === context) {
|
|
192
|
+
this.opts.aiActContext = void 0;
|
|
193
|
+
this.opts.aiActionContext = void 0;
|
|
194
|
+
} else {
|
|
195
|
+
this.opts.aiActContext = context;
|
|
196
|
+
this.opts.aiActionContext = context;
|
|
197
|
+
}
|
|
149
198
|
}
|
|
150
199
|
resetDump() {
|
|
151
200
|
this.dump = new ReportActionDump({
|
|
@@ -249,7 +298,7 @@ class Agent {
|
|
|
249
298
|
}
|
|
250
299
|
async aiTap(locatePrompt, opt) {
|
|
251
300
|
assert(locatePrompt, 'missing locate prompt for tap');
|
|
252
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
301
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiTap', opt));
|
|
253
302
|
const fileChooserAccept = opt?.fileChooserAccept ? this.normalizeFileInput(opt.fileChooserAccept) : void 0;
|
|
254
303
|
await withFileChooser(this.interface, fileChooserAccept, async ()=>{
|
|
255
304
|
await this.callActionInActionSpace('Tap', {
|
|
@@ -259,21 +308,21 @@ class Agent {
|
|
|
259
308
|
}
|
|
260
309
|
async aiRightClick(locatePrompt, opt) {
|
|
261
310
|
assert(locatePrompt, 'missing locate prompt for right click');
|
|
262
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
311
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiRightClick', opt));
|
|
263
312
|
await this.callActionInActionSpace('RightClick', {
|
|
264
313
|
locate: detailedLocateParam
|
|
265
314
|
});
|
|
266
315
|
}
|
|
267
316
|
async aiDoubleClick(locatePrompt, opt) {
|
|
268
317
|
assert(locatePrompt, 'missing locate prompt for double click');
|
|
269
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
318
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiDoubleClick', opt));
|
|
270
319
|
await this.callActionInActionSpace('DoubleClick', {
|
|
271
320
|
locate: detailedLocateParam
|
|
272
321
|
});
|
|
273
322
|
}
|
|
274
323
|
async aiHover(locatePrompt, opt) {
|
|
275
324
|
assert(locatePrompt, 'missing locate prompt for hover');
|
|
276
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
325
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiHover', opt));
|
|
277
326
|
await this.callActionInActionSpace('Hover', {
|
|
278
327
|
locate: detailedLocateParam
|
|
279
328
|
});
|
|
@@ -297,7 +346,7 @@ class Agent {
|
|
|
297
346
|
}
|
|
298
347
|
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
348
|
assert(locatePrompt, 'missing locate prompt for input');
|
|
300
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, opt);
|
|
349
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, this.withContext('aiInput', opt));
|
|
301
350
|
const stringValue = 'number' == typeof value ? String(value) : value;
|
|
302
351
|
const mode = opt?.mode === 'append' ? 'typeOnly' : opt?.mode;
|
|
303
352
|
await this.callActionInActionSpace('Input', {
|
|
@@ -323,7 +372,7 @@ class Agent {
|
|
|
323
372
|
};
|
|
324
373
|
}
|
|
325
374
|
assert(opt?.keyName, 'missing keyName for keyboard press');
|
|
326
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', opt);
|
|
375
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', this.withContext('aiKeyboardPress', opt));
|
|
327
376
|
await this.callActionInActionSpace('KeyboardPress', {
|
|
328
377
|
...restParams,
|
|
329
378
|
locate: locateParam
|
|
@@ -355,14 +404,14 @@ class Agent {
|
|
|
355
404
|
scrollType: normalizedScrollType
|
|
356
405
|
};
|
|
357
406
|
}
|
|
358
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', opt);
|
|
407
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', this.withContext('aiScroll', opt));
|
|
359
408
|
await this.callActionInActionSpace('Scroll', {
|
|
360
409
|
...restParams,
|
|
361
410
|
locate: locateParam
|
|
362
411
|
});
|
|
363
412
|
}
|
|
364
413
|
async aiPinch(locatePrompt, opt) {
|
|
365
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', opt);
|
|
414
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt || '', this.withContext('aiPinch', opt));
|
|
366
415
|
await this.callActionInActionSpace('Pinch', {
|
|
367
416
|
...restParams,
|
|
368
417
|
locate: locateParam
|
|
@@ -370,7 +419,7 @@ class Agent {
|
|
|
370
419
|
}
|
|
371
420
|
async aiLongPress(locatePrompt, opt) {
|
|
372
421
|
assert(locatePrompt, 'missing locate prompt for long press');
|
|
373
|
-
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, opt);
|
|
422
|
+
const { locateParam, restParams } = buildDetailedLocateParamAndRestParams(locatePrompt, this.withContext('aiLongPress', opt));
|
|
374
423
|
await this.callActionInActionSpace('LongPress', {
|
|
375
424
|
...restParams,
|
|
376
425
|
locate: locateParam
|
|
@@ -378,13 +427,14 @@ class Agent {
|
|
|
378
427
|
}
|
|
379
428
|
async aiClearInput(locatePrompt, opt) {
|
|
380
429
|
assert(locatePrompt, 'missing locate prompt for clear input');
|
|
381
|
-
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, opt);
|
|
430
|
+
const detailedLocateParam = buildDetailedLocateParam(locatePrompt, this.withContext('aiClearInput', opt));
|
|
382
431
|
await this.callActionInActionSpace('ClearInput', {
|
|
383
432
|
locate: detailedLocateParam
|
|
384
433
|
});
|
|
385
434
|
}
|
|
386
435
|
async aiAct(taskPrompt, opt) {
|
|
387
|
-
const
|
|
436
|
+
const internalOptions = opt;
|
|
437
|
+
const internalReportDisplay = internalOptions?._internalReportDisplay;
|
|
388
438
|
const taskPromptText = 'string' == typeof taskPrompt ? taskPrompt : taskPrompt.prompt;
|
|
389
439
|
const reportPrompt = internalReportDisplay?.prompt || taskPromptText;
|
|
390
440
|
const fileChooserAccept = opt?.fileChooserAccept ? this.normalizeFileInput(opt.fileChooserAccept) : void 0;
|
|
@@ -393,7 +443,7 @@ class Agent {
|
|
|
393
443
|
const runAiAct = async ()=>{
|
|
394
444
|
const planningModel = this.resolveModelRuntime('planning');
|
|
395
445
|
const defaultModel = this.resolveModelRuntime('default');
|
|
396
|
-
const aiActContext = opt?.context
|
|
446
|
+
const aiActContext = this.resolveContext('aiAct', opt?.context, internalOptions?._internalAdditionalContext);
|
|
397
447
|
const cachePrompt = buildPromptWithContext(taskPrompt, aiActContext);
|
|
398
448
|
const effort = (()=>{
|
|
399
449
|
const resolvedEffort = opt?.effort ?? (opt?.deepThink === true ? 'deepThink' : 'balance');
|
|
@@ -511,7 +561,7 @@ class Agent {
|
|
|
511
561
|
return this.createInsight().aiAsk(prompt, opt);
|
|
512
562
|
}
|
|
513
563
|
async aiLocate(prompt, opt) {
|
|
514
|
-
const locateParam = buildDetailedLocateParam(prompt, opt);
|
|
564
|
+
const locateParam = buildDetailedLocateParam(prompt, this.withContext('aiLocate', opt));
|
|
515
565
|
assert(locateParam, 'cannot get locate param for aiLocate');
|
|
516
566
|
const locatePlan = locatePlanForLocate(locateParam);
|
|
517
567
|
const plans = [
|
|
@@ -534,10 +584,11 @@ class Agent {
|
|
|
534
584
|
}
|
|
535
585
|
async aiWaitFor(assertion, opt) {
|
|
536
586
|
const modelRuntime = this.resolveModelRuntime('insight');
|
|
587
|
+
const options = this.withContext('aiWaitFor', opt);
|
|
537
588
|
await this.taskExecutor.waitFor(assertion, {
|
|
538
|
-
...
|
|
539
|
-
timeoutMs:
|
|
540
|
-
checkIntervalMs:
|
|
589
|
+
...options,
|
|
590
|
+
timeoutMs: options?.timeoutMs || 15000,
|
|
591
|
+
checkIntervalMs: options?.checkIntervalMs || 3000
|
|
541
592
|
}, modelRuntime);
|
|
542
593
|
}
|
|
543
594
|
async ai(...args) {
|
|
@@ -806,11 +857,23 @@ class Agent {
|
|
|
806
857
|
groupDescription: ''
|
|
807
858
|
}, opts || {});
|
|
808
859
|
assertReportGenerationOptions(this.opts);
|
|
809
|
-
|
|
860
|
+
if (void 0 !== this.opts.contexts && ('object' != typeof this.opts.contexts || null === this.opts.contexts || Array.isArray(this.opts.contexts))) throw new TypeError('opts.contexts must be a plain object');
|
|
861
|
+
for (const [key, value] of Object.entries(this.opts.contexts ?? {})){
|
|
862
|
+
if (!isAgentContextKey(key)) throw new TypeError(`Unknown Agent context key: ${key}`);
|
|
863
|
+
if (void 0 !== value && 'string' != typeof value) throw new TypeError(`Agent context "${key}" must be a string`);
|
|
864
|
+
}
|
|
865
|
+
const deprecatedAiActContextOption = void 0 !== this.opts.aiActContext ? 'aiActContext' : void 0 !== this.opts.aiActionContext ? 'aiActionContext' : void 0;
|
|
866
|
+
if (deprecatedAiActContextOption) warn(`Agent option "${deprecatedAiActContextOption}" is deprecated; use "contexts.aiAct" instead. When both are provided, "contexts.aiAct" takes precedence.`);
|
|
867
|
+
const normalizedContexts = {
|
|
868
|
+
...this.opts.contexts
|
|
869
|
+
};
|
|
870
|
+
const resolvedAiActContext = normalizedContexts.aiAct ?? this.opts.aiActContext ?? this.opts.aiActionContext;
|
|
810
871
|
if (void 0 !== resolvedAiActContext) {
|
|
872
|
+
normalizedContexts.aiAct = resolvedAiActContext;
|
|
811
873
|
this.opts.aiActContext = resolvedAiActContext;
|
|
812
874
|
this.opts.aiActionContext ??= resolvedAiActContext;
|
|
813
875
|
}
|
|
876
|
+
this.opts.contexts = normalizedContexts;
|
|
814
877
|
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
878
|
const hasCustomConfig = opts?.modelConfig || opts?.createOpenAIClient;
|
|
816
879
|
this.modelConfigManager = hasCustomConfig ? new ModelConfigManager(opts?.modelConfig, opts?.createOpenAIClient) : globalModelConfigManager;
|