@midscene/core 1.14.0 → 1.15.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/action-readiness.mjs +72 -0
- package/dist/es/agent/action-readiness.mjs.map +1 -0
- package/dist/es/agent/agent.mjs +14 -6
- package/dist/es/agent/agent.mjs.map +1 -1
- package/dist/es/agent/task-builder.mjs +45 -33
- package/dist/es/agent/task-builder.mjs.map +1 -1
- package/dist/es/agent/tasks.mjs +9 -2
- package/dist/es/agent/tasks.mjs.map +1 -1
- package/dist/es/agent/utils.mjs +1 -1
- package/dist/es/ai-model/connectivity/run-connectivity-test.mjs +24 -6
- package/dist/es/ai-model/connectivity/run-connectivity-test.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/call-ai.mjs +10 -3
- package/dist/es/ai-model/service-caller/call-ai.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/call-openai.mjs +3 -2
- package/dist/es/ai-model/service-caller/openai/call-openai.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs +10 -6
- package/dist/es/ai-model/service-caller/openai/chat-completion/stream.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/openai/responses/stream.mjs +8 -1
- package/dist/es/ai-model/service-caller/openai/responses/stream.mjs.map +1 -1
- package/dist/es/ai-model/service-caller/utils.mjs +3 -2
- package/dist/es/ai-model/service-caller/utils.mjs.map +1 -1
- package/dist/es/device/index.mjs +11 -4
- package/dist/es/device/index.mjs.map +1 -1
- 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/legacy-yaml-runtime.mjs +6 -0
- package/dist/es/yaml/legacy-yaml-runtime.mjs.map +1 -1
- package/dist/es/yaml/player.mjs +7 -3
- package/dist/es/yaml/player.mjs.map +1 -1
- package/dist/lib/agent/action-readiness.js +112 -0
- package/dist/lib/agent/action-readiness.js.map +1 -0
- package/dist/lib/agent/agent.js +13 -5
- package/dist/lib/agent/agent.js.map +1 -1
- package/dist/lib/agent/task-builder.js +45 -33
- package/dist/lib/agent/task-builder.js.map +1 -1
- package/dist/lib/agent/tasks.js +9 -2
- package/dist/lib/agent/tasks.js.map +1 -1
- package/dist/lib/agent/utils.js +1 -1
- package/dist/lib/ai-model/connectivity/run-connectivity-test.js +24 -6
- package/dist/lib/ai-model/connectivity/run-connectivity-test.js.map +1 -1
- package/dist/lib/ai-model/service-caller/call-ai.js +10 -3
- package/dist/lib/ai-model/service-caller/call-ai.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/call-openai.js +3 -2
- package/dist/lib/ai-model/service-caller/openai/call-openai.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js +10 -6
- package/dist/lib/ai-model/service-caller/openai/chat-completion/stream.js.map +1 -1
- package/dist/lib/ai-model/service-caller/openai/responses/stream.js +8 -1
- package/dist/lib/ai-model/service-caller/openai/responses/stream.js.map +1 -1
- package/dist/lib/ai-model/service-caller/utils.js +3 -2
- package/dist/lib/ai-model/service-caller/utils.js.map +1 -1
- package/dist/lib/device/index.js +11 -4
- package/dist/lib/device/index.js.map +1 -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/legacy-yaml-runtime.js +6 -0
- package/dist/lib/yaml/legacy-yaml-runtime.js.map +1 -1
- package/dist/lib/yaml/player.js +7 -3
- package/dist/lib/yaml/player.js.map +1 -1
- package/dist/types/agent/action-readiness.d.ts +14 -0
- package/dist/types/agent/action-readiness.d.ts.map +1 -0
- package/dist/types/agent/agent.d.ts +6 -2
- package/dist/types/agent/agent.d.ts.map +1 -1
- package/dist/types/agent/index.d.ts +1 -1
- package/dist/types/agent/index.d.ts.map +1 -1
- package/dist/types/agent/task-builder.d.ts +4 -1
- package/dist/types/agent/task-builder.d.ts.map +1 -1
- package/dist/types/agent/tasks.d.ts +3 -0
- package/dist/types/agent/tasks.d.ts.map +1 -1
- package/dist/types/ai-model/connectivity/index.d.ts +1 -1
- package/dist/types/ai-model/connectivity/index.d.ts.map +1 -1
- package/dist/types/ai-model/connectivity/run-connectivity-test.d.ts +14 -1
- package/dist/types/ai-model/connectivity/run-connectivity-test.d.ts.map +1 -1
- package/dist/types/ai-model/index.d.ts +1 -1
- package/dist/types/ai-model/index.d.ts.map +1 -1
- package/dist/types/ai-model/model-adapter/types.d.ts +2 -0
- package/dist/types/ai-model/model-adapter/types.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/call-ai.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/openai/call-openai.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/openai/chat-completion/stream.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/openai/responses/stream.d.ts.map +1 -1
- package/dist/types/ai-model/service-caller/utils.d.ts +3 -2
- package/dist/types/ai-model/service-caller/utils.d.ts.map +1 -1
- package/dist/types/device/index.d.ts +7 -1
- package/dist/types/device/index.d.ts.map +1 -1
- package/dist/types/index.d.ts +1 -1
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/types.d.ts +28 -1
- package/dist/types/types.d.ts.map +1 -1
- package/dist/types/yaml/legacy-yaml-runtime.d.ts.map +1 -1
- package/dist/types/yaml/player.d.ts +2 -1
- package/dist/types/yaml/player.d.ts.map +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
import { getErrorMessage } from "@midscene/shared/agent-tools/error-formatter";
|
|
2
|
+
import { getDebug } from "@midscene/shared/logger";
|
|
3
|
+
function _define_property(obj, key, value) {
|
|
4
|
+
if (key in obj) Object.defineProperty(obj, key, {
|
|
5
|
+
value: value,
|
|
6
|
+
enumerable: true,
|
|
7
|
+
configurable: true,
|
|
8
|
+
writable: true
|
|
9
|
+
});
|
|
10
|
+
else obj[key] = value;
|
|
11
|
+
return obj;
|
|
12
|
+
}
|
|
13
|
+
const warn = getDebug('agent:action-readiness', {
|
|
14
|
+
console: true
|
|
15
|
+
});
|
|
16
|
+
const errorCode = 'ACTION_READINESS_FAILED';
|
|
17
|
+
class ActionReadinessError extends Error {
|
|
18
|
+
constructor(phase, actionName, cause){
|
|
19
|
+
super(`waitForActionReady ${phase} failed for ${actionName}: ${getErrorMessage(cause)}`, {
|
|
20
|
+
cause
|
|
21
|
+
}), _define_property(this, "code", errorCode);
|
|
22
|
+
this.name = 'ActionReadinessError';
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
function isActionReadinessError(error) {
|
|
26
|
+
const seen = new Set();
|
|
27
|
+
while(error && 'object' == typeof error && !seen.has(error)){
|
|
28
|
+
seen.add(error);
|
|
29
|
+
const value = error;
|
|
30
|
+
if (value.code === errorCode) return true;
|
|
31
|
+
error = value.cause;
|
|
32
|
+
}
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
class ActionReadiness {
|
|
36
|
+
async wait(action, signal) {
|
|
37
|
+
signal?.throwIfAborted();
|
|
38
|
+
let onAbort;
|
|
39
|
+
const timer = setTimeout(()=>{
|
|
40
|
+
warn(`waitForActionReady for ${action.name} (${action.id}) is still pending after 5000ms; continuing to wait.`);
|
|
41
|
+
}, 5000);
|
|
42
|
+
try {
|
|
43
|
+
await new Promise((resolve, reject)=>{
|
|
44
|
+
if (signal) {
|
|
45
|
+
onAbort = ()=>reject(signal.reason);
|
|
46
|
+
signal.addEventListener('abort', onAbort, {
|
|
47
|
+
once: true
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
Promise.resolve(this.callback({
|
|
51
|
+
action,
|
|
52
|
+
signal
|
|
53
|
+
})).then(resolve, reject);
|
|
54
|
+
});
|
|
55
|
+
signal?.throwIfAborted();
|
|
56
|
+
} catch (cause) {
|
|
57
|
+
signal?.throwIfAborted();
|
|
58
|
+
throw new ActionReadinessError('wait', action.name, cause);
|
|
59
|
+
} finally{
|
|
60
|
+
clearTimeout(timer);
|
|
61
|
+
if (signal && onAbort) signal.removeEventListener('abort', onAbort);
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
constructor(callback){
|
|
65
|
+
_define_property(this, "callback", void 0);
|
|
66
|
+
this.callback = callback;
|
|
67
|
+
if ('function' != typeof callback) throw new Error('waitForActionReady must be a function');
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
export { ActionReadiness, ActionReadinessError, isActionReadinessError };
|
|
71
|
+
|
|
72
|
+
//# sourceMappingURL=action-readiness.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"agent/action-readiness.mjs","sources":["../../../src/agent/action-readiness.ts"],"sourcesContent":["import type { ActionReadyContext, WaitForActionReady } from '@/types';\nimport { getErrorMessage } from '@midscene/shared/agent-tools/error-formatter';\nimport { getDebug } from '@midscene/shared/logger';\n\nconst warn = getDebug('agent:action-readiness', { console: true });\nconst errorCode = 'ACTION_READINESS_FAILED';\n\nexport class ActionReadinessError extends Error {\n readonly code = errorCode;\n\n constructor(phase: string, actionName: string, cause: unknown) {\n super(\n `waitForActionReady ${phase} failed for ${actionName}: ${getErrorMessage(cause)}`,\n { cause },\n );\n this.name = 'ActionReadinessError';\n }\n}\n\n/** Also recognizes the bounded cause retained by TaskExecutionError. */\nexport function isActionReadinessError(error: unknown): boolean {\n const seen = new Set<unknown>();\n while (error && typeof error === 'object' && !seen.has(error)) {\n seen.add(error);\n const value = error as { code?: unknown; cause?: unknown };\n if (value.code === errorCode) return true;\n error = value.cause;\n }\n return false;\n}\n\n/** Await application readiness after a successful action; slow waits only warn. */\nexport class ActionReadiness {\n constructor(private readonly callback: WaitForActionReady) {\n if (typeof callback !== 'function') {\n throw new Error('waitForActionReady must be a function');\n }\n }\n\n async wait(\n action: ActionReadyContext['action'],\n signal?: AbortSignal,\n ): Promise<void> {\n signal?.throwIfAborted();\n let onAbort: (() => void) | undefined;\n const timer = setTimeout(() => {\n warn(\n `waitForActionReady for ${action.name} (${action.id}) is still pending after 5000ms; continuing to wait.`,\n );\n }, 5000);\n try {\n await new Promise<void>((resolve, reject) => {\n // Listen before invoking user code, including callbacks that abort\n // synchronously or never settle. Both late outcomes stay handled.\n if (signal) {\n onAbort = () => reject(signal.reason);\n signal.addEventListener('abort', onAbort, { once: true });\n }\n Promise.resolve(this.callback({ action, signal })).then(\n resolve,\n reject,\n );\n });\n signal?.throwIfAborted();\n } catch (cause) {\n // Preserve the cancellation reason instead of reporting a readiness failure.\n signal?.throwIfAborted();\n throw new ActionReadinessError('wait', action.name, cause);\n } finally {\n clearTimeout(timer);\n if (signal && onAbort) signal.removeEventListener('abort', onAbort);\n }\n }\n}\n"],"names":["warn","getDebug","errorCode","ActionReadinessError","Error","phase","actionName","cause","getErrorMessage","isActionReadinessError","error","seen","Set","value","ActionReadiness","action","signal","onAbort","timer","setTimeout","Promise","resolve","reject","clearTimeout","callback"],"mappings":";;;;;;;;;;;;AAIA,MAAMA,OAAOC,SAAS,0BAA0B;IAAE,SAAS;AAAK;AAChE,MAAMC,YAAY;AAEX,MAAMC,6BAA6BC;IAGxC,YAAYC,KAAa,EAAEC,UAAkB,EAAEC,KAAc,CAAE;QAC7D,KAAK,CACH,CAAC,mBAAmB,EAAEF,MAAM,YAAY,EAAEC,WAAW,EAAE,EAAEE,gBAAgBD,QAAQ,EACjF;YAAEA;QAAM,IALZ,uBAAS,QAAOL;QAOd,IAAI,CAAC,IAAI,GAAG;IACd;AACF;AAGO,SAASO,uBAAuBC,KAAc;IACnD,MAAMC,OAAO,IAAIC;IACjB,MAAOF,SAAS,AAAiB,YAAjB,OAAOA,SAAsB,CAACC,KAAK,GAAG,CAACD,OAAQ;QAC7DC,KAAK,GAAG,CAACD;QACT,MAAMG,QAAQH;QACd,IAAIG,MAAM,IAAI,KAAKX,WAAW,OAAO;QACrCQ,QAAQG,MAAM,KAAK;IACrB;IACA,OAAO;AACT;AAGO,MAAMC;IAOX,MAAM,KACJC,MAAoC,EACpCC,MAAoB,EACL;QACfA,QAAQ;QACR,IAAIC;QACJ,MAAMC,QAAQC,WAAW;YACvBnB,KACE,CAAC,uBAAuB,EAAEe,OAAO,IAAI,CAAC,EAAE,EAAEA,OAAO,EAAE,CAAC,oDAAoD,CAAC;QAE7G,GAAG;QACH,IAAI;YACF,MAAM,IAAIK,QAAc,CAACC,SAASC;gBAGhC,IAAIN,QAAQ;oBACVC,UAAU,IAAMK,OAAON,OAAO,MAAM;oBACpCA,OAAO,gBAAgB,CAAC,SAASC,SAAS;wBAAE,MAAM;oBAAK;gBACzD;gBACAG,QAAQ,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC;oBAAEL;oBAAQC;gBAAO,IAAI,IAAI,CACrDK,SACAC;YAEJ;YACAN,QAAQ;QACV,EAAE,OAAOT,OAAO;YAEdS,QAAQ;YACR,MAAM,IAAIb,qBAAqB,QAAQY,OAAO,IAAI,EAAER;QACtD,SAAU;YACRgB,aAAaL;YACb,IAAIF,UAAUC,SAASD,OAAO,mBAAmB,CAAC,SAASC;QAC7D;IACF;IAvCA,YAA6BO,QAA4B,CAAE;;aAA9BA,QAAQ,GAARA;QAC3B,IAAI,AAAoB,cAApB,OAAOA,UACT,MAAM,IAAIpB,MAAM;IAEpB;AAoCF"}
|
package/dist/es/agent/agent.mjs
CHANGED
|
@@ -9,7 +9,7 @@ import { waitForResourceIdle } from "../test-runner/engine/resource-operations.m
|
|
|
9
9
|
import { buildAgentTestRunReportDump } from "../test-runner/reporting/agent-report.mjs";
|
|
10
10
|
import { executionRecordsToReportInput } from "../test-runner/reporting/execution-record.mjs";
|
|
11
11
|
import { ExecutionDump, ReportActionDump } from "../types.mjs";
|
|
12
|
-
import { YamlExecutionOwnershipError, enterYamlAction, enterYamlExecution, runInYamlExecutionContext } from "../yaml/execution-session.mjs";
|
|
12
|
+
import { YamlExecutionOwnershipError, currentYamlSignal, enterYamlAction, enterYamlExecution, runInYamlExecutionContext } from "../yaml/execution-session.mjs";
|
|
13
13
|
import { ReportGenerator, assertReportGenerationOptions } from "../report-generator.mjs";
|
|
14
14
|
import { getVersion, processCacheConfig, reportHTMLContent } from "../utils.mjs";
|
|
15
15
|
import { ScriptPlayer, buildDetailedLocateParam, buildDetailedLocateParamAndRestParams, parseYamlScript } from "../yaml/index.mjs";
|
|
@@ -22,6 +22,7 @@ import { MIDSCENE_REPLANNING_CYCLE_LIMIT, ModelConfigManager, globalConfigManage
|
|
|
22
22
|
import { getDebug } from "@midscene/shared/logger";
|
|
23
23
|
import { assert, ifInBrowser, uuid } from "@midscene/shared/utils";
|
|
24
24
|
import { defineActionRegisterFileChooserAccept, defineActionSleep } from "../device/index.mjs";
|
|
25
|
+
import { ActionReadiness, isActionReadinessError } from "./action-readiness.mjs";
|
|
25
26
|
import { validateAgentCacheInput } from "./cache-config.mjs";
|
|
26
27
|
import { FileChooserAccepter } from "./file-chooser.mjs";
|
|
27
28
|
import { Insight } from "./insight.mjs";
|
|
@@ -352,7 +353,7 @@ class Agent {
|
|
|
352
353
|
wrapActionInActionSpace(name) {
|
|
353
354
|
return async (param)=>await this.callActionInActionSpace(name, param);
|
|
354
355
|
}
|
|
355
|
-
async callActionInActionSpace(type, opt) {
|
|
356
|
+
async callActionInActionSpace(type, opt, abortSignal) {
|
|
356
357
|
debug('callActionInActionSpace', type, ',', opt);
|
|
357
358
|
const clonedActionParam = opt && 'object' == typeof opt && !Array.isArray(opt) ? {
|
|
358
359
|
...opt
|
|
@@ -369,7 +370,9 @@ class Agent {
|
|
|
369
370
|
const title = taskTitleStr(type, locateParamStr(opt?.locate || {}));
|
|
370
371
|
const defaultModel = this.resolveModelRuntime('default');
|
|
371
372
|
const planningModel = this.resolveModelRuntime('planning');
|
|
372
|
-
const { output } = await this.taskExecutor.runPlans(title, plans, planningModel, defaultModel
|
|
373
|
+
const { output } = await this.taskExecutor.runPlans(title, plans, planningModel, defaultModel, {
|
|
374
|
+
abortSignal: abortSignal ?? currentYamlSignal(this)
|
|
375
|
+
});
|
|
373
376
|
return output;
|
|
374
377
|
}
|
|
375
378
|
async aiTap(locatePrompt, opt) {
|
|
@@ -558,7 +561,7 @@ class Agent {
|
|
|
558
561
|
});
|
|
559
562
|
return;
|
|
560
563
|
} catch (error) {
|
|
561
|
-
if (error instanceof YamlExecutionOwnershipError) throw error;
|
|
564
|
+
if (error instanceof YamlExecutionOwnershipError || isActionReadinessError(error)) throw error;
|
|
562
565
|
abortSignal?.throwIfAborted();
|
|
563
566
|
cachedYamlFailed = true;
|
|
564
567
|
warn(`cached aiAct plan failed, will replan and disable the stale cache: ${error instanceof Error ? error.message : String(error)}`);
|
|
@@ -686,15 +689,17 @@ class Agent {
|
|
|
686
689
|
async ai(...args) {
|
|
687
690
|
return this.aiAct(...args);
|
|
688
691
|
}
|
|
689
|
-
async runYaml(yamlScriptContent) {
|
|
692
|
+
async runYaml(yamlScriptContent, options) {
|
|
690
693
|
if (this.destroyed) throw new Error('Cannot run YAML using a destroyed Agent.');
|
|
691
694
|
const script = parseYamlScript(yamlScriptContent, 'yaml');
|
|
692
695
|
const player = new ScriptPlayer(script, async ()=>({
|
|
693
696
|
agent: this,
|
|
694
697
|
freeFn: []
|
|
695
|
-
}));
|
|
698
|
+
}), void 0, void 0, options?.abortSignal);
|
|
696
699
|
await player.run();
|
|
697
700
|
if ('error' === player.status) {
|
|
701
|
+
const readinessFailure = player.taskStatusList.find((task)=>isActionReadinessError(task.error));
|
|
702
|
+
if (readinessFailure) throw readinessFailure.error;
|
|
698
703
|
const errors = player.taskStatusList.filter((task)=>'error' === task.status).map((task)=>`task - ${task.name}: ${task.error?.message}`).join('\n');
|
|
699
704
|
throw new Error(`Error(s) occurred in running yaml script:\n${errors}`);
|
|
700
705
|
}
|
|
@@ -938,6 +943,7 @@ class Agent {
|
|
|
938
943
|
_define_property(this, "dumpUpdateListeners", []);
|
|
939
944
|
_define_property(this, "progressBus", new AgentProgressBus());
|
|
940
945
|
_define_property(this, "destroyed", false);
|
|
946
|
+
_define_property(this, "actionReadiness", void 0);
|
|
941
947
|
_define_property(this, "modelConfigManager", void 0);
|
|
942
948
|
_define_property(this, "frozenUIContext", void 0);
|
|
943
949
|
_define_property(this, "activeObserver", null);
|
|
@@ -957,6 +963,7 @@ class Agent {
|
|
|
957
963
|
groupDescription: ''
|
|
958
964
|
}, opts || {});
|
|
959
965
|
assertReportGenerationOptions(this.opts);
|
|
966
|
+
if (void 0 !== this.opts.waitForActionReady) this.actionReadiness = new ActionReadiness(this.opts.waitForActionReady);
|
|
960
967
|
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');
|
|
961
968
|
for (const [key, value] of Object.entries(this.opts.aiContexts ?? {})){
|
|
962
969
|
if (!isAgentAIContextKey(key)) throw new TypeError(`Unknown Agent context key: ${key}`);
|
|
@@ -1002,6 +1009,7 @@ class Agent {
|
|
|
1002
1009
|
onTaskStart: this.callbackOnTaskStartTip.bind(this),
|
|
1003
1010
|
replanningCycleLimit: this.opts.replanningCycleLimit,
|
|
1004
1011
|
waitAfterAction: this.opts.waitAfterAction,
|
|
1012
|
+
actionReadiness: this.actionReadiness,
|
|
1005
1013
|
useDeviceTime: this.opts.useDeviceTime,
|
|
1006
1014
|
actionSpace: this.fullActionSpace,
|
|
1007
1015
|
hooks: {
|