@midscene/core 0.8.16 → 0.8.17-beta-20250103010342.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/README.md +1 -1
- package/dist/lib/ai-model.js +387 -342
- package/dist/lib/env.js +3 -0
- package/dist/lib/index.js +388 -343
- package/dist/lib/types/ai-model.d.ts +3 -3
- package/dist/lib/types/{index-43fd19f4.d.ts → automation-1fa20bde.d.ts} +21 -44
- package/dist/lib/types/env.d.ts +2 -1
- package/dist/lib/types/index.d.ts +4 -4
- package/dist/lib/types/{types-55182ae1.d.ts → types-7702c41a.d.ts} +5 -16
- package/dist/lib/types/utils.d.ts +1 -1
- package/dist/lib/utils.js +1 -1
- package/package.json +6 -3
- package/report/index.html +2 -2
package/dist/lib/ai-model.js
CHANGED
|
@@ -1033,10 +1033,10 @@ var require_dist = __commonJS({
|
|
|
1033
1033
|
}
|
|
1034
1034
|
});
|
|
1035
1035
|
|
|
1036
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
1036
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/async_caller.js
|
|
1037
1037
|
var import_p_retry, import_p_queue, STATUS_NO_RETRY, STATUS_IGNORE, AsyncCaller;
|
|
1038
1038
|
var init_async_caller = __esm({
|
|
1039
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
1039
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/async_caller.js"() {
|
|
1040
1040
|
"use strict";
|
|
1041
1041
|
import_p_retry = __toESM(require_p_retry());
|
|
1042
1042
|
import_p_queue = __toESM(require_dist());
|
|
@@ -1158,7 +1158,7 @@ var init_async_caller = __esm({
|
|
|
1158
1158
|
}
|
|
1159
1159
|
});
|
|
1160
1160
|
|
|
1161
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
1161
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/messages.js
|
|
1162
1162
|
function isLangChainMessage(message) {
|
|
1163
1163
|
return typeof (message == null ? void 0 : message._getType) === "function";
|
|
1164
1164
|
}
|
|
@@ -1173,25 +1173,25 @@ function convertLangChainMessageToExample(message) {
|
|
|
1173
1173
|
return converted;
|
|
1174
1174
|
}
|
|
1175
1175
|
var init_messages = __esm({
|
|
1176
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
1176
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/messages.js"() {
|
|
1177
1177
|
"use strict";
|
|
1178
1178
|
}
|
|
1179
1179
|
});
|
|
1180
1180
|
|
|
1181
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
1181
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/_uuid.js
|
|
1182
1182
|
function assertUuid(str) {
|
|
1183
1183
|
if (!validate_default(str)) {
|
|
1184
1184
|
throw new Error(`Invalid UUID: ${str}`);
|
|
1185
1185
|
}
|
|
1186
1186
|
}
|
|
1187
1187
|
var init_uuid = __esm({
|
|
1188
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
1188
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/_uuid.js"() {
|
|
1189
1189
|
"use strict";
|
|
1190
1190
|
init_esm_node();
|
|
1191
1191
|
}
|
|
1192
1192
|
});
|
|
1193
1193
|
|
|
1194
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
1194
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/warn.js
|
|
1195
1195
|
function warnOnce(message) {
|
|
1196
1196
|
if (!warnedMessages[message]) {
|
|
1197
1197
|
console.warn(message);
|
|
@@ -1200,13 +1200,13 @@ function warnOnce(message) {
|
|
|
1200
1200
|
}
|
|
1201
1201
|
var warnedMessages;
|
|
1202
1202
|
var init_warn = __esm({
|
|
1203
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
1203
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/warn.js"() {
|
|
1204
1204
|
"use strict";
|
|
1205
1205
|
warnedMessages = {};
|
|
1206
1206
|
}
|
|
1207
1207
|
});
|
|
1208
1208
|
|
|
1209
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
1209
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/client.js
|
|
1210
1210
|
async function mergeRuntimeEnvIntoRunCreates(runs) {
|
|
1211
1211
|
const runtimeEnv = await getRuntimeEnvironment();
|
|
1212
1212
|
const envVars = getLangChainEnvVarsMetadata();
|
|
@@ -1244,7 +1244,7 @@ function trimQuotes(str) {
|
|
|
1244
1244
|
}
|
|
1245
1245
|
var getTracingSamplingRate, isLocalhost, raiseForStatus, handle429, Queue, DEFAULT_BATCH_SIZE_LIMIT_BYTES, Client;
|
|
1246
1246
|
var init_client = __esm({
|
|
1247
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
1247
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/client.js"() {
|
|
1248
1248
|
"use strict";
|
|
1249
1249
|
init_esm_node();
|
|
1250
1250
|
init_async_caller();
|
|
@@ -3005,10 +3005,10 @@ var init_client = __esm({
|
|
|
3005
3005
|
}
|
|
3006
3006
|
});
|
|
3007
3007
|
|
|
3008
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
3008
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/index.js
|
|
3009
3009
|
var __version__;
|
|
3010
3010
|
var init_dist = __esm({
|
|
3011
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
3011
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/index.js"() {
|
|
3012
3012
|
"use strict";
|
|
3013
3013
|
init_client();
|
|
3014
3014
|
init_run_trees();
|
|
@@ -3016,7 +3016,7 @@ var init_dist = __esm({
|
|
|
3016
3016
|
}
|
|
3017
3017
|
});
|
|
3018
3018
|
|
|
3019
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
3019
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/env.js
|
|
3020
3020
|
async function getRuntimeEnvironment() {
|
|
3021
3021
|
if (runtimeEnvironment === void 0) {
|
|
3022
3022
|
const env = getEnv();
|
|
@@ -3113,7 +3113,7 @@ function getShas() {
|
|
|
3113
3113
|
}
|
|
3114
3114
|
var globalEnv, isBrowser, isWebWorker, isJsDom, isDeno, isNode, getEnv, runtimeEnvironment, cachedCommitSHAs;
|
|
3115
3115
|
var init_env = __esm({
|
|
3116
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
3116
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/env.js"() {
|
|
3117
3117
|
"use strict";
|
|
3118
3118
|
init_dist();
|
|
3119
3119
|
isBrowser = () => typeof window !== "undefined" && typeof window.document !== "undefined";
|
|
@@ -3143,10 +3143,10 @@ var init_env = __esm({
|
|
|
3143
3143
|
}
|
|
3144
3144
|
});
|
|
3145
3145
|
|
|
3146
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
3146
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/env.js
|
|
3147
3147
|
var isTracingEnabled;
|
|
3148
3148
|
var init_env2 = __esm({
|
|
3149
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
3149
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/env.js"() {
|
|
3150
3150
|
"use strict";
|
|
3151
3151
|
init_env();
|
|
3152
3152
|
isTracingEnabled = (tracingEnabled) => {
|
|
@@ -3164,7 +3164,7 @@ var init_env2 = __esm({
|
|
|
3164
3164
|
}
|
|
3165
3165
|
});
|
|
3166
3166
|
|
|
3167
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
3167
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/run_trees.js
|
|
3168
3168
|
function stripNonAlphanumeric(input) {
|
|
3169
3169
|
return input.replace(/[-:.]/g, "");
|
|
3170
3170
|
}
|
|
@@ -3188,7 +3188,7 @@ function isRunnableConfigLike(x) {
|
|
|
3188
3188
|
}
|
|
3189
3189
|
var Baggage, RunTree;
|
|
3190
3190
|
var init_run_trees = __esm({
|
|
3191
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
3191
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/run_trees.js"() {
|
|
3192
3192
|
"use strict";
|
|
3193
3193
|
init_esm_node();
|
|
3194
3194
|
init_env();
|
|
@@ -3612,13 +3612,13 @@ var init_run_trees = __esm({
|
|
|
3612
3612
|
}
|
|
3613
3613
|
});
|
|
3614
3614
|
|
|
3615
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
3615
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/singletons/traceable.js
|
|
3616
3616
|
function isTraceableFunction(x) {
|
|
3617
3617
|
return typeof x === "function" && "langsmith:traceable" in x;
|
|
3618
3618
|
}
|
|
3619
3619
|
var MockAsyncLocalStorage, AsyncLocalStorageProvider, AsyncLocalStorageProviderSingleton, ROOT;
|
|
3620
3620
|
var init_traceable = __esm({
|
|
3621
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
3621
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/singletons/traceable.js"() {
|
|
3622
3622
|
"use strict";
|
|
3623
3623
|
MockAsyncLocalStorage = class {
|
|
3624
3624
|
getStore() {
|
|
@@ -3658,7 +3658,7 @@ var init_traceable = __esm({
|
|
|
3658
3658
|
}
|
|
3659
3659
|
});
|
|
3660
3660
|
|
|
3661
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
3661
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/asserts.js
|
|
3662
3662
|
function isPromiseMethod(x) {
|
|
3663
3663
|
if (x === "then" || x === "catch" || x === "finally") {
|
|
3664
3664
|
return true;
|
|
@@ -3674,7 +3674,7 @@ function isKVMap(x) {
|
|
|
3674
3674
|
}
|
|
3675
3675
|
var isAsyncIterable, isIteratorLike, GeneratorFunction, isGenerator, isThenable, isReadableStream;
|
|
3676
3676
|
var init_asserts = __esm({
|
|
3677
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
3677
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/utils/asserts.js"() {
|
|
3678
3678
|
"use strict";
|
|
3679
3679
|
isAsyncIterable = (x) => x != null && typeof x === "object" && // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
3680
3680
|
typeof x[Symbol.asyncIterator] === "function";
|
|
@@ -3690,7 +3690,7 @@ var init_asserts = __esm({
|
|
|
3690
3690
|
}
|
|
3691
3691
|
});
|
|
3692
3692
|
|
|
3693
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
3693
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/traceable.js
|
|
3694
3694
|
function traceable(wrappedFunc, config) {
|
|
3695
3695
|
const { aggregator, argsConfigPath, ...runTreeConfig } = config != null ? config : {};
|
|
3696
3696
|
const traceableFunc = (...args) => {
|
|
@@ -3888,7 +3888,7 @@ function traceable(wrappedFunc, config) {
|
|
|
3888
3888
|
}
|
|
3889
3889
|
var import_node_async_hooks, handleRunInputs, handleRunOutputs, getTracingRunTree, getSerializablePromise, convertSerializableArg;
|
|
3890
3890
|
var init_traceable2 = __esm({
|
|
3891
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
3891
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/traceable.js"() {
|
|
3892
3892
|
"use strict";
|
|
3893
3893
|
import_node_async_hooks = require("async_hooks");
|
|
3894
3894
|
init_run_trees();
|
|
@@ -4068,7 +4068,7 @@ var init_traceable2 = __esm({
|
|
|
4068
4068
|
}
|
|
4069
4069
|
});
|
|
4070
4070
|
|
|
4071
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
4071
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/wrappers/openai.js
|
|
4072
4072
|
function _combineChatCompletionChoices(choices) {
|
|
4073
4073
|
var _a, _b;
|
|
4074
4074
|
const reversedChoices = choices.slice().reverse();
|
|
@@ -4142,7 +4142,7 @@ function _combineChatCompletionChoices(choices) {
|
|
|
4142
4142
|
}
|
|
4143
4143
|
var chatAggregator, textAggregator, wrapOpenAI, _wrapClient, wrapSDK;
|
|
4144
4144
|
var init_openai = __esm({
|
|
4145
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
4145
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/wrappers/openai.js"() {
|
|
4146
4146
|
"use strict";
|
|
4147
4147
|
init_traceable2();
|
|
4148
4148
|
chatAggregator = (chunks) => {
|
|
@@ -4254,22 +4254,22 @@ var init_openai = __esm({
|
|
|
4254
4254
|
}
|
|
4255
4255
|
});
|
|
4256
4256
|
|
|
4257
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
4257
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/wrappers/index.js
|
|
4258
4258
|
var init_wrappers = __esm({
|
|
4259
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
4259
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/dist/wrappers/index.js"() {
|
|
4260
4260
|
"use strict";
|
|
4261
4261
|
init_openai();
|
|
4262
4262
|
}
|
|
4263
4263
|
});
|
|
4264
4264
|
|
|
4265
|
-
// ../../node_modules/.pnpm/langsmith@0.1.
|
|
4265
|
+
// ../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/wrappers.js
|
|
4266
4266
|
var wrappers_exports = {};
|
|
4267
4267
|
__export(wrappers_exports, {
|
|
4268
4268
|
wrapOpenAI: () => wrapOpenAI,
|
|
4269
4269
|
wrapSDK: () => wrapSDK
|
|
4270
4270
|
});
|
|
4271
4271
|
var init_wrappers2 = __esm({
|
|
4272
|
-
"../../node_modules/.pnpm/langsmith@0.1.
|
|
4272
|
+
"../../node_modules/.pnpm/langsmith@0.1.36_@langchain+core@0.3.26_openai@4.57.1_zod@3.23.8___langchain@0.3.8_@langchain_pnf6d76o2t3a6oyjkhgz2xqm4a/node_modules/langsmith/wrappers.js"() {
|
|
4273
4273
|
"use strict";
|
|
4274
4274
|
init_wrappers();
|
|
4275
4275
|
}
|
|
@@ -4313,6 +4313,7 @@ var OPENAI_MAX_TOKENS = "OPENAI_MAX_TOKENS";
|
|
|
4313
4313
|
var MIDSCENE_MODEL_TEXT_ONLY = "MIDSCENE_MODEL_TEXT_ONLY";
|
|
4314
4314
|
var MIDSCENE_CACHE = "MIDSCENE_CACHE";
|
|
4315
4315
|
var MATCH_BY_POSITION = "MATCH_BY_POSITION";
|
|
4316
|
+
var MIDSCENE_API_TYPE = "MIDSCENE_API_TYPE";
|
|
4316
4317
|
var MIDSCENE_REPORT_TAG_NAME = "MIDSCENE_REPORT_TAG_NAME";
|
|
4317
4318
|
var MIDSCENE_USE_AZURE_OPENAI = "MIDSCENE_USE_AZURE_OPENAI";
|
|
4318
4319
|
var MIDSCENE_AZURE_OPENAI_SCOPE = "MIDSCENE_AZURE_OPENAI_SCOPE";
|
|
@@ -4375,8 +4376,7 @@ var getAIConfigInJson = (configKey) => {
|
|
|
4375
4376
|
|
|
4376
4377
|
// src/ai-model/common.ts
|
|
4377
4378
|
var import_node_assert = __toESM(require("assert"));
|
|
4378
|
-
async function callAiFn(
|
|
4379
|
-
const { msgs, AIActionType: AIActionTypeValue } = options;
|
|
4379
|
+
async function callAiFn(msgs, AIActionTypeValue) {
|
|
4380
4380
|
(0, import_node_assert.default)(
|
|
4381
4381
|
checkAIConfig(),
|
|
4382
4382
|
"Cannot find config for AI model service. You should set it before using. https://midscenejs.com/model-provider.html"
|
|
@@ -4387,19 +4387,9 @@ async function callAiFn(options) {
|
|
|
4387
4387
|
);
|
|
4388
4388
|
return { content, usage };
|
|
4389
4389
|
}
|
|
4390
|
-
function transformUserMessages(msgs) {
|
|
4391
|
-
const textOnly = Boolean(getAIConfig(MIDSCENE_MODEL_TEXT_ONLY));
|
|
4392
|
-
if (!textOnly)
|
|
4393
|
-
return msgs;
|
|
4394
|
-
return msgs.reduce((res, msg) => {
|
|
4395
|
-
if (msg.type === "text") {
|
|
4396
|
-
res += msg.text;
|
|
4397
|
-
}
|
|
4398
|
-
return res;
|
|
4399
|
-
}, "");
|
|
4400
|
-
}
|
|
4401
4390
|
|
|
4402
4391
|
// src/ai-model/prompt/element_inspector.ts
|
|
4392
|
+
var import_prompts = require("@langchain/core/prompts");
|
|
4403
4393
|
function systemPromptToFindElement() {
|
|
4404
4394
|
if (getAIConfig(MATCH_BY_POSITION)) {
|
|
4405
4395
|
return systemPromptToFindElementPosition();
|
|
@@ -4542,36 +4532,31 @@ Output Example:
|
|
|
4542
4532
|
}
|
|
4543
4533
|
function systemPromptToFindElementPosition() {
|
|
4544
4534
|
return `
|
|
4545
|
-
|
|
4546
|
-
You are an expert in software page image (2D) and page element text analysis.
|
|
4535
|
+
You are a GUI agent. You are given a task and your action history, with screenshots. You need to perform the next action to complete the task.
|
|
4547
4536
|
|
|
4548
|
-
|
|
4549
|
-
|
|
4537
|
+
## Output Format
|
|
4538
|
+
\`\`\`
|
|
4539
|
+
Action_Summary: ...
|
|
4540
|
+
Action: ...
|
|
4541
|
+
\`\`\`
|
|
4550
4542
|
|
|
4551
|
-
|
|
4543
|
+
## Action Space
|
|
4544
|
+
click(start_box='[x1, y1, x2, y2]')
|
|
4545
|
+
long_press(start_box='[x1, y1, x2, y2]', time='')
|
|
4546
|
+
type(content='')
|
|
4547
|
+
scroll(direction='down or up or right or left')
|
|
4548
|
+
open_app(app_name='')
|
|
4549
|
+
navigate_back()
|
|
4550
|
+
navigate_home()
|
|
4551
|
+
WAIT()
|
|
4552
|
+
finished() # Submit the task regardless of whether it succeeds or fails.
|
|
4552
4553
|
|
|
4553
|
-
|
|
4554
|
+
## Note
|
|
4555
|
+
- Use Chinese in \`Action_Summary\` part.
|
|
4554
4556
|
|
|
4555
|
-
|
|
4556
|
-
{
|
|
4557
|
-
"elements": [
|
|
4558
|
-
{
|
|
4559
|
-
// Describe the reason for finding this element, replace with actual value in practice
|
|
4560
|
-
"reason": "Reason for finding element 4: It is located in the upper right corner, is an image type, and according to the screenshot, it is a shopping cart icon button",
|
|
4561
|
-
// If the target element includes text information, extract the text information; if it does not, do not extract it
|
|
4562
|
-
"text": "",
|
|
4563
|
-
// position of this element
|
|
4564
|
-
"position": { x: number, y: number }
|
|
4565
|
-
}
|
|
4566
|
-
],
|
|
4567
|
-
"errors": []// Return an error if there is no target element on the picture
|
|
4568
|
-
}
|
|
4569
|
-
\`\`\`
|
|
4557
|
+
## User Instruction
|
|
4570
4558
|
`;
|
|
4571
4559
|
}
|
|
4572
|
-
function multiDescription(multi) {
|
|
4573
|
-
return multi ? "multiple elements matching the description (two or more)" : "The element closest to the description (only one)";
|
|
4574
|
-
}
|
|
4575
4560
|
var findElementSchema = {
|
|
4576
4561
|
type: "json_schema",
|
|
4577
4562
|
json_schema: {
|
|
@@ -4616,6 +4601,23 @@ var findElementSchema = {
|
|
|
4616
4601
|
}
|
|
4617
4602
|
}
|
|
4618
4603
|
};
|
|
4604
|
+
var findElementPrompt = new import_prompts.PromptTemplate({
|
|
4605
|
+
template: `
|
|
4606
|
+
Here is the item user want to find. Just go ahead:
|
|
4607
|
+
=====================================
|
|
4608
|
+
{{
|
|
4609
|
+
"description": "{targetElementDescription}",
|
|
4610
|
+
"multi": {multi}
|
|
4611
|
+
}}
|
|
4612
|
+
=====================================
|
|
4613
|
+
|
|
4614
|
+
pageDescription: {pageDescription}
|
|
4615
|
+
`,
|
|
4616
|
+
inputVariables: ["pageDescription", "targetElementDescription", "multi"]
|
|
4617
|
+
});
|
|
4618
|
+
|
|
4619
|
+
// src/ai-model/prompt/planning.ts
|
|
4620
|
+
var import_prompts3 = require("@langchain/core/prompts");
|
|
4619
4621
|
|
|
4620
4622
|
// src/ai-model/prompt/util.ts
|
|
4621
4623
|
var import_node_assert2 = __toESM(require("assert"));
|
|
@@ -4624,6 +4626,7 @@ var import_node_assert2 = __toESM(require("assert"));
|
|
|
4624
4626
|
var import_img = require("@midscene/shared/img");
|
|
4625
4627
|
|
|
4626
4628
|
// src/ai-model/prompt/util.ts
|
|
4629
|
+
var import_prompts2 = require("@langchain/core/prompts");
|
|
4627
4630
|
var characteristic = "You are a versatile professional in software UI design and testing. Your outstanding contributions will impact the user experience of billions of users.";
|
|
4628
4631
|
var contextFormatIntro = `
|
|
4629
4632
|
The user will give you a screenshot and some of the texts on it. There may be some none-English characters (like Chinese) on it, indicating it's an non-English app. If some text is shown on screenshot but not introduced by the JSON description, use the information you see on screenshot.`;
|
|
@@ -4652,6 +4655,22 @@ Return in the following JSON format:
|
|
|
4652
4655
|
}
|
|
4653
4656
|
`;
|
|
4654
4657
|
}
|
|
4658
|
+
var extractDataPrompt = new import_prompts2.PromptTemplate({
|
|
4659
|
+
template: `
|
|
4660
|
+
pageDescription: {pageDescription}
|
|
4661
|
+
|
|
4662
|
+
Use your extract_data_from_UI skill to find the following data, placing it in the \`data\` field
|
|
4663
|
+
DATA_DEMAND start:
|
|
4664
|
+
=====================================
|
|
4665
|
+
{dataKeys}
|
|
4666
|
+
|
|
4667
|
+
{dataQuery}
|
|
4668
|
+
|
|
4669
|
+
=====================================
|
|
4670
|
+
DATA_DEMAND ends.
|
|
4671
|
+
`,
|
|
4672
|
+
inputVariables: ["pageDescription", "dataKeys", "dataQuery"]
|
|
4673
|
+
});
|
|
4655
4674
|
function systemPromptToAssert() {
|
|
4656
4675
|
return `
|
|
4657
4676
|
${characteristic}
|
|
@@ -4700,7 +4719,7 @@ function truncateText(text, maxLength = 100) {
|
|
|
4700
4719
|
}
|
|
4701
4720
|
return "";
|
|
4702
4721
|
}
|
|
4703
|
-
function
|
|
4722
|
+
function elementByPositionWithElementInfo(elementsInfo, position) {
|
|
4704
4723
|
(0, import_node_assert2.default)(typeof position !== "undefined", "position is required for query");
|
|
4705
4724
|
const item = elementsInfo.find((item2) => {
|
|
4706
4725
|
return item2.rect.left <= position.x && position.x <= item2.rect.left + item2.rect.width && item2.rect.top <= position.y && position.y <= item2.rect.top + item2.rect.height;
|
|
@@ -4754,23 +4773,26 @@ async function describeUserPage(context, opt) {
|
|
|
4754
4773
|
const { id, ...rest } = item;
|
|
4755
4774
|
return `id=${id}: ${JSON.stringify(rest)}`;
|
|
4756
4775
|
}).join("\n\n");
|
|
4776
|
+
const pageJSONDescription = getAIConfig(MATCH_BY_POSITION) ? "" : `Some of the elements are marked with a rectangle in the screenshot, some are not.
|
|
4777
|
+
Json description of all the page elements:
|
|
4778
|
+
${contentList}`;
|
|
4779
|
+
const sizeDescription = describeSize({ width, height });
|
|
4757
4780
|
return {
|
|
4758
4781
|
description: `
|
|
4759
|
-
The size of the page: ${
|
|
4760
|
-
Some of the elements are marked with a rectangle in the screenshot, some are not.
|
|
4782
|
+
The size of the page: ${sizeDescription}
|
|
4761
4783
|
|
|
4762
|
-
${
|
|
4763
|
-
getAIConfig(MATCH_BY_POSITION) ? "" : `Json description of all the page elements:
|
|
4764
|
-
${contentList}`}
|
|
4784
|
+
${pageJSONDescription}
|
|
4765
4785
|
`,
|
|
4766
4786
|
elementById(id) {
|
|
4767
4787
|
(0, import_node_assert2.default)(typeof id !== "undefined", "id is required for query");
|
|
4768
4788
|
const item = idElementMap[`${id}`];
|
|
4769
4789
|
return item;
|
|
4770
4790
|
},
|
|
4771
|
-
elementByPosition(position) {
|
|
4772
|
-
|
|
4773
|
-
|
|
4791
|
+
elementByPosition(position, size) {
|
|
4792
|
+
console.log("elementByPosition", { position, size });
|
|
4793
|
+
return elementByPositionWithElementInfo(elementsInfo, position);
|
|
4794
|
+
},
|
|
4795
|
+
size: { width, height }
|
|
4774
4796
|
};
|
|
4775
4797
|
}
|
|
4776
4798
|
function cropFieldInformation(elementsInfo, truncateTextLength, filterNonTextContent = false) {
|
|
@@ -4824,19 +4846,35 @@ function cropFieldInformation(elementsInfo, truncateTextLength, filterNonTextCon
|
|
|
4824
4846
|
// src/ai-model/prompt/planning.ts
|
|
4825
4847
|
var quickAnswerFormat = () => {
|
|
4826
4848
|
const matchByPosition = getAIConfig(MATCH_BY_POSITION);
|
|
4827
|
-
const
|
|
4828
|
-
|
|
4829
|
-
|
|
4830
|
-
|
|
4831
|
-
|
|
4849
|
+
const locationFormat = {
|
|
4850
|
+
position: {
|
|
4851
|
+
description: `"position": { x: number; y: number } // Represents the position of the element; replace with actual values in practice (ensure it reflects the element's position)`,
|
|
4852
|
+
format: '"position": { x: number; y: number }',
|
|
4853
|
+
sample: '{"prompt": "the search bar"}',
|
|
4854
|
+
locateParam: `{
|
|
4855
|
+
"prompt"?: string // the description of the element to find. It can only be omitted when locate is null.
|
|
4856
|
+
} | null // If it's not on the page, the LocateParam should be null`
|
|
4857
|
+
},
|
|
4858
|
+
id: {
|
|
4859
|
+
description: '"id": string // Represents the ID of the element; replace with actual values in practice',
|
|
4860
|
+
format: '"id": string',
|
|
4861
|
+
sample: `{"id": "c81c4e9a33", "prompt": "the search bar"}`,
|
|
4862
|
+
locateParam: `{
|
|
4863
|
+
"id": string, // the id of the element found. It should either be the id marked with a rectangle in the screenshot or the id described in the description.
|
|
4864
|
+
"prompt"?: string // the description of the element to find. It can only be omitted when locate is null.
|
|
4865
|
+
} | null // If it's not on the page, the LocateParam should be null`
|
|
4866
|
+
}
|
|
4867
|
+
};
|
|
4868
|
+
const type = matchByPosition ? "position" : "id";
|
|
4869
|
+
const format = locationFormat[type];
|
|
4832
4870
|
return {
|
|
4833
|
-
description,
|
|
4834
|
-
format,
|
|
4835
|
-
sample
|
|
4871
|
+
description: format.description,
|
|
4872
|
+
format: format.format,
|
|
4873
|
+
sample: format.sample,
|
|
4874
|
+
locateParam: format.locateParam
|
|
4836
4875
|
};
|
|
4837
4876
|
};
|
|
4838
|
-
|
|
4839
|
-
return `
|
|
4877
|
+
var systemTemplate = `
|
|
4840
4878
|
## Role
|
|
4841
4879
|
|
|
4842
4880
|
You are a versatile professional in software UI automation. Your outstanding contributions will impact the user experience of billions of users.
|
|
@@ -4870,76 +4908,70 @@ You are a versatile professional in software UI automation. Your outstanding con
|
|
|
4870
4908
|
|
|
4871
4909
|
The \`locate\` param is commonly used in the \`param\` field of the action, means to locate the target element to perform the action, it follows the following scheme:
|
|
4872
4910
|
|
|
4873
|
-
type LocateParam = {
|
|
4874
|
-
"id": string, // the id of the element found. It should either be the id marked with a rectangle in the screenshot or the id described in the description.
|
|
4875
|
-
prompt?: string // the description of the element to find. It can only be omitted when locate is null.
|
|
4876
|
-
} | null // If it's not on the page, the LocateParam should be null
|
|
4911
|
+
type LocateParam = {locateParam}
|
|
4877
4912
|
|
|
4878
4913
|
### Supported actions
|
|
4879
4914
|
|
|
4880
4915
|
Each action has a \`type\` and corresponding \`param\`. To be detailed:
|
|
4881
4916
|
- type: 'Tap', tap the located element
|
|
4882
|
-
* { locate:
|
|
4917
|
+
* {{ locate: {sample}, param: null }}
|
|
4883
4918
|
- type: 'Hover', move mouse over to the located element
|
|
4884
|
-
* { locate: LocateParam, param: null }
|
|
4919
|
+
* {{ locate: LocateParam, param: null }}
|
|
4885
4920
|
- type: 'Input', replace the value in the input field
|
|
4886
|
-
* { locate: LocateParam, param: { value: string } }
|
|
4921
|
+
* {{ locate: LocateParam, param: {{ value: string }} }}
|
|
4887
4922
|
* \`value\` is the final required input value based on the existing input. No matter what modifications are required, just provide the final value to replace the existing input value.
|
|
4888
4923
|
- type: 'KeyboardPress', press a key
|
|
4889
|
-
* { param: { value: string } }
|
|
4924
|
+
* {{ param: {{ value: string }} }}
|
|
4890
4925
|
- type: 'Scroll', scroll up or down.
|
|
4891
|
-
* {
|
|
4926
|
+
* {{
|
|
4892
4927
|
locate: LocateParam | null,
|
|
4893
|
-
param: {
|
|
4928
|
+
param: {{
|
|
4894
4929
|
direction: 'down'(default) | 'up' | 'right' | 'left',
|
|
4895
4930
|
scrollType: 'once' (default) | 'untilBottom' | 'untilTop' | 'untilRight' | 'untilLeft',
|
|
4896
4931
|
distance: null | number
|
|
4897
|
-
}
|
|
4898
|
-
}
|
|
4932
|
+
}}
|
|
4933
|
+
}}
|
|
4899
4934
|
* To scroll some specific element, put the element at the center of the region in the \`locate\` field. If it's a page scroll, put \`null\` in the \`locate\` field.
|
|
4900
4935
|
* \`param\` is required in this action. If some fields are not specified, use direction \`down\`, \`once\` scroll type, and \`null\` distance.
|
|
4901
4936
|
- type: 'FalsyConditionStatement'
|
|
4902
|
-
* { param: null }
|
|
4937
|
+
* {{ param: null }}
|
|
4903
4938
|
* use this action when the instruction is an "if" statement and the condition is falsy.
|
|
4904
4939
|
- type: 'Sleep'
|
|
4905
|
-
* { param: { timeMs: number } }
|
|
4940
|
+
* {{ param: {{ timeMs: number }} }}
|
|
4906
4941
|
|
|
4907
4942
|
## How to compose the \`taskWillBeAccomplished\` and \`furtherPlan\` fields ?
|
|
4908
4943
|
|
|
4909
4944
|
\`taskWillBeAccomplished\` is a boolean field, means whether the task will be accomplished after all the actions.
|
|
4910
4945
|
|
|
4911
|
-
\`furtherPlan\` is used when the task cannot be accomplished. It follows the scheme { whatHaveDone: string, whatToDoNext: string }:
|
|
4946
|
+
\`furtherPlan\` is used when the task cannot be accomplished. It follows the scheme {{ whatHaveDone: string, whatToDoNext: string }}:
|
|
4912
4947
|
- \`whatHaveDone\`: a string, describe what have been done after the previous actions.
|
|
4913
4948
|
- \`whatToDoNext\`: a string, describe what should be done next after the previous actions has finished. It should be a concise and clear description of the actions to be performed. Make sure you don't lose any necessary steps user asked.
|
|
4914
|
-
|
|
4949
|
+
`;
|
|
4950
|
+
var outputTemplate = `
|
|
4915
4951
|
## Output JSON Format:
|
|
4916
4952
|
|
|
4917
4953
|
The JSON format is as follows:
|
|
4918
4954
|
|
|
4919
|
-
{
|
|
4955
|
+
{{
|
|
4920
4956
|
"actions": [
|
|
4921
|
-
{
|
|
4957
|
+
{{
|
|
4922
4958
|
"thought": "Reasons for generating this task, and why this task is feasible on this page",
|
|
4923
4959
|
"type": "Tap",
|
|
4924
4960
|
"param": null,
|
|
4925
|
-
"locate": {
|
|
4926
|
-
|
|
4927
|
-
prompt: "the search bar"
|
|
4928
|
-
} | null,
|
|
4929
|
-
},
|
|
4961
|
+
"locate": {sample} | null,
|
|
4962
|
+
}},
|
|
4930
4963
|
// ... more actions
|
|
4931
4964
|
],
|
|
4932
4965
|
"taskWillBeAccomplished": boolean,
|
|
4933
|
-
"furtherPlan": { "whatHaveDone": string, "whatToDoNext": string } | null,
|
|
4966
|
+
"furtherPlan": {{ "whatHaveDone": string, "whatToDoNext": string }} | null,
|
|
4934
4967
|
"error"?: string
|
|
4935
|
-
}
|
|
4936
|
-
|
|
4937
|
-
## Example #1 : How to decompose a task
|
|
4968
|
+
}}
|
|
4969
|
+
Here is an example of how to decompose a task:
|
|
4938
4970
|
|
|
4939
4971
|
When a user says 'Click the language switch button, wait 1s, click "English"', the user will give you the description like this:
|
|
4940
4972
|
|
|
4941
4973
|
====================
|
|
4942
|
-
|
|
4974
|
+
{pageDescription}
|
|
4943
4975
|
====================
|
|
4944
4976
|
|
|
4945
4977
|
By viewing the page screenshot and description, you should consider this and output the JSON:
|
|
@@ -4949,110 +4981,119 @@ By viewing the page screenshot and description, you should consider this and out
|
|
|
4949
4981
|
* The "English" option button is not shown in the screenshot now, it means it may only show after the previous actions are finished. So the last action will have a \`null\` value in the \`locate\` field.
|
|
4950
4982
|
* The task cannot be accomplished (because we cannot see the "English" option now), so a \`furtherPlan\` field is needed.
|
|
4951
4983
|
|
|
4952
|
-
{
|
|
4984
|
+
{{
|
|
4953
4985
|
"actions":[
|
|
4954
|
-
{
|
|
4986
|
+
{{
|
|
4987
|
+
"type": "Tap",
|
|
4955
4988
|
"thought": "Click the language switch button to open the language options.",
|
|
4956
|
-
"type": "Tap",
|
|
4957
4989
|
"param": null,
|
|
4958
|
-
"locate": {
|
|
4959
|
-
|
|
4960
|
-
|
|
4961
|
-
}
|
|
4962
|
-
},
|
|
4963
|
-
{
|
|
4964
|
-
"thought": "Wait for 1 second to ensure the language options are displayed.",
|
|
4990
|
+
"locate": {sample},
|
|
4991
|
+
}},
|
|
4992
|
+
{{
|
|
4965
4993
|
"type": "Sleep",
|
|
4966
|
-
"
|
|
4967
|
-
|
|
4968
|
-
|
|
4969
|
-
|
|
4994
|
+
"thought": "Wait for 1 second to ensure the language options are displayed.",
|
|
4995
|
+
"param": {{ "timeMs": 1000 }},
|
|
4996
|
+
}},
|
|
4997
|
+
{{
|
|
4970
4998
|
"type": "Tap",
|
|
4971
|
-
"
|
|
4999
|
+
"thought": "Locate the 'English' option in the language menu.",
|
|
5000
|
+
"param": null,
|
|
4972
5001
|
"locate": null
|
|
4973
|
-
},
|
|
5002
|
+
}},
|
|
4974
5003
|
],
|
|
4975
5004
|
"error": null,
|
|
4976
5005
|
"taskWillBeAccomplished": false,
|
|
4977
|
-
"furtherPlan": {
|
|
4978
|
-
"whatToDoNext": "find the 'English' option and click on it",
|
|
4979
|
-
"whatHaveDone": "Click the language switch button and wait 1s"
|
|
4980
|
-
}
|
|
4981
|
-
}
|
|
5006
|
+
"furtherPlan": {{
|
|
5007
|
+
"whatToDoNext": "find the 'English' option and click on it",
|
|
5008
|
+
"whatHaveDone": "Click the language switch button and wait 1s"
|
|
5009
|
+
}}
|
|
5010
|
+
}}
|
|
4982
5011
|
|
|
4983
|
-
|
|
5012
|
+
Here is another example of how to tolerate error situations only when the instruction is an "if" statement:
|
|
4984
5013
|
|
|
4985
5014
|
If the user says "If there is a popup, close it", you should consider this and output the JSON:
|
|
4986
5015
|
|
|
4987
5016
|
* By viewing the page screenshot and description, you cannot find the popup, so the condition is falsy.
|
|
4988
5017
|
* The instruction itself is an "if" statement, it means the user can tolerate this situation, so you should leave a \`FalsyConditionStatement\` action.
|
|
4989
5018
|
|
|
4990
|
-
{
|
|
4991
|
-
"actions": [{
|
|
4992
|
-
"thought": "There is no popup on the page",
|
|
5019
|
+
{{
|
|
5020
|
+
"actions": [{{
|
|
4993
5021
|
"type": "FalsyConditionStatement",
|
|
5022
|
+
"thought": "There is no popup on the page",
|
|
4994
5023
|
"param": null
|
|
4995
|
-
}
|
|
5024
|
+
}}
|
|
4996
5025
|
],
|
|
4997
5026
|
"taskWillBeAccomplished": true,
|
|
4998
5027
|
"furtherPlan": null
|
|
4999
|
-
}
|
|
5028
|
+
}}
|
|
5000
5029
|
|
|
5001
5030
|
For contrast, if the user says "Close the popup" in this situation, you should consider this and output the JSON:
|
|
5002
5031
|
|
|
5003
|
-
{
|
|
5032
|
+
{{
|
|
5004
5033
|
"actions": [],
|
|
5005
5034
|
"error": "The instruction and page context are irrelevant, there is no popup on the page",
|
|
5006
5035
|
"taskWillBeAccomplished": true,
|
|
5007
5036
|
"furtherPlan": null
|
|
5008
|
-
}
|
|
5037
|
+
}}
|
|
5009
5038
|
|
|
5010
|
-
|
|
5039
|
+
Here is an example of when task is accomplished, don't plan more actions:
|
|
5011
5040
|
|
|
5012
5041
|
When the user ask to "Wait 4s", you should consider this:
|
|
5013
5042
|
|
|
5014
|
-
{
|
|
5043
|
+
{{
|
|
5015
5044
|
"actions": [
|
|
5016
|
-
{
|
|
5017
|
-
"thought": "Wait for 4 seconds",
|
|
5045
|
+
{{
|
|
5018
5046
|
"type": "Sleep",
|
|
5019
|
-
"
|
|
5020
|
-
|
|
5047
|
+
"thought": "Wait for 4 seconds",
|
|
5048
|
+
"param": {{ "timeMs": 4000 }},
|
|
5049
|
+
}},
|
|
5021
5050
|
],
|
|
5022
5051
|
"taskWillBeAccomplished": true,
|
|
5023
5052
|
"furtherPlan": null // All steps have been included in the actions, so no further plan is needed
|
|
5024
|
-
}
|
|
5053
|
+
}}
|
|
5025
5054
|
|
|
5026
|
-
|
|
5055
|
+
Here is an example of what NOT to do:
|
|
5027
5056
|
|
|
5028
5057
|
Wrong output:
|
|
5029
5058
|
|
|
5030
|
-
{
|
|
5059
|
+
{{
|
|
5031
5060
|
"actions":[
|
|
5032
|
-
{
|
|
5033
|
-
"thought": "Click the language switch button to open the language options.",
|
|
5061
|
+
{{
|
|
5034
5062
|
"type": "Tap",
|
|
5063
|
+
"thought": "Click the language switch button to open the language options.",
|
|
5035
5064
|
"param": null,
|
|
5036
|
-
"locate": {
|
|
5037
|
-
|
|
5038
|
-
}
|
|
5039
|
-
},
|
|
5040
|
-
{
|
|
5065
|
+
"locate": {{
|
|
5066
|
+
{sample}, // WRONG:prompt is missing
|
|
5067
|
+
}}
|
|
5068
|
+
}},
|
|
5069
|
+
{{
|
|
5070
|
+
"type": "Tap",
|
|
5041
5071
|
"thought": "Click the English option",
|
|
5042
|
-
"type": "Tap",
|
|
5043
5072
|
"param": null,
|
|
5044
5073
|
"locate": null, // This means the 'English' option is not shown in the screenshot, the task cannot be accomplished
|
|
5045
|
-
}
|
|
5074
|
+
}}
|
|
5046
5075
|
],
|
|
5047
5076
|
"taskWillBeAccomplished": false,
|
|
5048
5077
|
// WRONG: should not be null
|
|
5049
5078
|
"furtherPlan": null,
|
|
5050
|
-
}
|
|
5079
|
+
}}
|
|
5051
5080
|
|
|
5052
|
-
Reason:
|
|
5081
|
+
Reason:
|
|
5053
5082
|
* The \`prompt\` is missing in the first 'Locate' action
|
|
5054
5083
|
* Since the option button is not shown in the screenshot, the task cannot be accomplished, so a \`furtherPlan\` field is needed.
|
|
5055
5084
|
`;
|
|
5085
|
+
async function systemPromptToTaskPlanning() {
|
|
5086
|
+
const promptTemplate = new import_prompts3.PromptTemplate({
|
|
5087
|
+
template: `${systemTemplate}
|
|
5088
|
+
|
|
5089
|
+
${outputTemplate}`,
|
|
5090
|
+
inputVariables: ["pageDescription", "sample", "locateParam"]
|
|
5091
|
+
});
|
|
5092
|
+
return await promptTemplate.format({
|
|
5093
|
+
pageDescription: samplePageDescription,
|
|
5094
|
+
sample: quickAnswerFormat().sample,
|
|
5095
|
+
locateParam: quickAnswerFormat().locateParam
|
|
5096
|
+
});
|
|
5056
5097
|
}
|
|
5057
5098
|
var planSchema = {
|
|
5058
5099
|
type: "json_schema",
|
|
@@ -5136,6 +5177,34 @@ var planSchema = {
|
|
|
5136
5177
|
}
|
|
5137
5178
|
}
|
|
5138
5179
|
};
|
|
5180
|
+
var taskBackgroundContext = async (originalPrompt, whatHaveDone) => {
|
|
5181
|
+
if (!originalPrompt || !whatHaveDone) {
|
|
5182
|
+
return "";
|
|
5183
|
+
}
|
|
5184
|
+
return `
|
|
5185
|
+
For your information, this is a task that some important person handed to you. Here is the original task description and what have been done after the previous actions:
|
|
5186
|
+
=====================================
|
|
5187
|
+
Original task description:
|
|
5188
|
+
${originalPrompt}
|
|
5189
|
+
=====================================
|
|
5190
|
+
What have been done:
|
|
5191
|
+
${whatHaveDone}
|
|
5192
|
+
=====================================
|
|
5193
|
+
`;
|
|
5194
|
+
};
|
|
5195
|
+
var automationUserPrompt = new import_prompts3.PromptTemplate({
|
|
5196
|
+
template: `
|
|
5197
|
+
Here is the instruction:
|
|
5198
|
+
=====================================
|
|
5199
|
+
{userPrompt}
|
|
5200
|
+
=====================================
|
|
5201
|
+
|
|
5202
|
+
{taskBackgroundContext}
|
|
5203
|
+
|
|
5204
|
+
pageDescription: {pageDescription}
|
|
5205
|
+
`,
|
|
5206
|
+
inputVariables: ["pageDescription", "userPrompt", "taskBackgroundContext"]
|
|
5207
|
+
});
|
|
5139
5208
|
|
|
5140
5209
|
// src/ai-model/openai/index.ts
|
|
5141
5210
|
function checkAIConfig(preferVendor) {
|
|
@@ -5158,7 +5227,9 @@ function getModelName() {
|
|
|
5158
5227
|
}
|
|
5159
5228
|
return modelName;
|
|
5160
5229
|
}
|
|
5161
|
-
async function createChatClient(
|
|
5230
|
+
async function createChatClient({
|
|
5231
|
+
AIActionTypeValue
|
|
5232
|
+
}) {
|
|
5162
5233
|
let openai;
|
|
5163
5234
|
const extraConfig = getAIConfigInJson(MIDSCENE_OPENAI_INIT_CONFIG_JSON);
|
|
5164
5235
|
const socksProxy = getAIConfig(MIDSCENE_OPENAI_SOCKS_PROXY);
|
|
@@ -5209,6 +5280,10 @@ async function createChatClient() {
|
|
|
5209
5280
|
apiKey: getAIConfig(OPENAI_API_KEY),
|
|
5210
5281
|
httpAgent: socksAgent,
|
|
5211
5282
|
...extraConfig,
|
|
5283
|
+
defaultHeaders: {
|
|
5284
|
+
...(extraConfig == null ? void 0 : extraConfig.defaultHeaders) || {},
|
|
5285
|
+
[MIDSCENE_API_TYPE]: AIActionTypeValue.toString()
|
|
5286
|
+
},
|
|
5212
5287
|
dangerouslyAllowBrowser: true
|
|
5213
5288
|
});
|
|
5214
5289
|
}
|
|
@@ -5241,8 +5316,10 @@ async function createChatClient() {
|
|
|
5241
5316
|
}
|
|
5242
5317
|
throw new Error("Openai SDK or Anthropic SDK is not initialized");
|
|
5243
5318
|
}
|
|
5244
|
-
async function call(messages, responseFormat) {
|
|
5245
|
-
const { completion, style } = await createChatClient(
|
|
5319
|
+
async function call(messages, AIActionTypeValue, responseFormat) {
|
|
5320
|
+
const { completion, style } = await createChatClient({
|
|
5321
|
+
AIActionTypeValue
|
|
5322
|
+
});
|
|
5246
5323
|
const shouldPrintTiming = typeof getAIConfig(MIDSCENE_DEBUG_AI_PROFILE) === "string";
|
|
5247
5324
|
const maxTokens = getAIConfig(OPENAI_MAX_TOKENS);
|
|
5248
5325
|
const startTime = Date.now();
|
|
@@ -5325,47 +5402,47 @@ async function callToGetJSONObject(messages, AIActionTypeValue) {
|
|
|
5325
5402
|
responseFormat = { type: "json_object" /* JSON */ };
|
|
5326
5403
|
}
|
|
5327
5404
|
}
|
|
5328
|
-
const
|
|
5329
|
-
try {
|
|
5330
|
-
return JSON.parse(input);
|
|
5331
|
-
} catch (e) {
|
|
5332
|
-
return null;
|
|
5333
|
-
}
|
|
5334
|
-
};
|
|
5335
|
-
const response = await call(messages, responseFormat);
|
|
5405
|
+
const response = await call(messages, AIActionTypeValue, responseFormat);
|
|
5336
5406
|
(0, import_node_assert3.default)(response, "empty response");
|
|
5337
|
-
|
|
5338
|
-
|
|
5339
|
-
|
|
5340
|
-
|
|
5341
|
-
try {
|
|
5342
|
-
jsonContent = JSON.parse(cleanJsonString);
|
|
5343
|
-
} catch (e) {
|
|
5344
|
-
}
|
|
5345
|
-
if (jsonContent)
|
|
5346
|
-
return { content: jsonContent, usage: response.usage };
|
|
5407
|
+
const jsonContent = safeParseJson(response.content);
|
|
5408
|
+
return { content: jsonContent, usage: response.usage };
|
|
5409
|
+
}
|
|
5410
|
+
function extractJSONFromCodeBlock(response) {
|
|
5347
5411
|
try {
|
|
5348
|
-
|
|
5412
|
+
const jsonMatch = response.match(/^\s*(\{[\s\S]*\})\s*$/);
|
|
5413
|
+
if (jsonMatch) {
|
|
5414
|
+
return jsonMatch[1];
|
|
5415
|
+
}
|
|
5416
|
+
const codeBlockMatch = response.match(
|
|
5417
|
+
/```(?:json)?\s*(\{[\s\S]*?\})\s*```/
|
|
5418
|
+
);
|
|
5419
|
+
if (codeBlockMatch) {
|
|
5420
|
+
return codeBlockMatch[1];
|
|
5421
|
+
}
|
|
5422
|
+
const jsonLikeMatch = response.match(/\{[\s\S]*\}/);
|
|
5423
|
+
if (jsonLikeMatch) {
|
|
5424
|
+
return jsonLikeMatch[0];
|
|
5425
|
+
}
|
|
5349
5426
|
} catch (e) {
|
|
5350
5427
|
}
|
|
5351
|
-
|
|
5352
|
-
return { content: jsonContent, usage: response.usage };
|
|
5353
|
-
throw Error(`failed to parse json response: ${response.content}`);
|
|
5428
|
+
return response;
|
|
5354
5429
|
}
|
|
5355
|
-
function
|
|
5356
|
-
|
|
5357
|
-
|
|
5358
|
-
|
|
5430
|
+
function safeParseJson(input) {
|
|
5431
|
+
var _a;
|
|
5432
|
+
const cleanJsonString = extractJSONFromCodeBlock(input);
|
|
5433
|
+
if (cleanJsonString.match(/\((\d+),(\d+)\)/)) {
|
|
5434
|
+
return (_a = cleanJsonString.match(/\((\d+),(\d+)\)/)) == null ? void 0 : _a.slice(1).map(Number);
|
|
5359
5435
|
}
|
|
5360
|
-
|
|
5361
|
-
|
|
5362
|
-
|
|
5436
|
+
try {
|
|
5437
|
+
return JSON.parse(cleanJsonString);
|
|
5438
|
+
} catch (e) {
|
|
5363
5439
|
}
|
|
5364
|
-
|
|
5365
|
-
|
|
5366
|
-
|
|
5440
|
+
try {
|
|
5441
|
+
return import_dirty_json.default.parse(cleanJsonString);
|
|
5442
|
+
} catch (e) {
|
|
5443
|
+
console.log("e:", e);
|
|
5367
5444
|
}
|
|
5368
|
-
|
|
5445
|
+
throw Error(`failed to parse json response: ${input}`);
|
|
5369
5446
|
}
|
|
5370
5447
|
|
|
5371
5448
|
// src/ai-model/inspect.ts
|
|
@@ -5374,76 +5451,82 @@ var liteContextConfig = {
|
|
|
5374
5451
|
filterNonTextContent: true,
|
|
5375
5452
|
truncateTextLength: 200
|
|
5376
5453
|
};
|
|
5377
|
-
function
|
|
5454
|
+
function transformToAbsoluteCoords(relativePosition, size) {
|
|
5455
|
+
return {
|
|
5456
|
+
x: Number((relativePosition.x / 1e3 * size.width).toFixed(3)),
|
|
5457
|
+
y: Number((relativePosition.y / 1e3 * size.height).toFixed(3))
|
|
5458
|
+
};
|
|
5459
|
+
}
|
|
5460
|
+
async function transformElementPositionToId(aiResult, elementsInfo, size, screenshotBase64) {
|
|
5461
|
+
if (Array.isArray(aiResult)) {
|
|
5462
|
+
const relativePosition = aiResult;
|
|
5463
|
+
const absolutePosition = transformToAbsoluteCoords(
|
|
5464
|
+
{
|
|
5465
|
+
x: relativePosition[0],
|
|
5466
|
+
y: relativePosition[1]
|
|
5467
|
+
},
|
|
5468
|
+
size
|
|
5469
|
+
);
|
|
5470
|
+
const element = elementByPositionWithElementInfo(
|
|
5471
|
+
elementsInfo,
|
|
5472
|
+
absolutePosition
|
|
5473
|
+
);
|
|
5474
|
+
(0, import_node_assert4.default)(
|
|
5475
|
+
element,
|
|
5476
|
+
`inspect: no id found with position: ${JSON.stringify({ absolutePosition })}`
|
|
5477
|
+
);
|
|
5478
|
+
return {
|
|
5479
|
+
errors: [],
|
|
5480
|
+
elements: [
|
|
5481
|
+
{
|
|
5482
|
+
id: element.id
|
|
5483
|
+
}
|
|
5484
|
+
]
|
|
5485
|
+
};
|
|
5486
|
+
}
|
|
5378
5487
|
return {
|
|
5379
5488
|
errors: aiResult.errors,
|
|
5380
|
-
elements: aiResult.elements
|
|
5381
|
-
var _a;
|
|
5382
|
-
if ("id" in item) {
|
|
5383
|
-
return item;
|
|
5384
|
-
}
|
|
5385
|
-
const { position } = item;
|
|
5386
|
-
const id = (_a = elementByPosition(elementsInfo, position)) == null ? void 0 : _a.id;
|
|
5387
|
-
(0, import_node_assert4.default)(
|
|
5388
|
-
id,
|
|
5389
|
-
`inspect: no id found with position: ${JSON.stringify({ position })}`
|
|
5390
|
-
);
|
|
5391
|
-
return {
|
|
5392
|
-
...item,
|
|
5393
|
-
id
|
|
5394
|
-
};
|
|
5395
|
-
})
|
|
5489
|
+
elements: aiResult.elements
|
|
5396
5490
|
};
|
|
5397
5491
|
}
|
|
5492
|
+
function getQuickAnswer(quickAnswer, elementById) {
|
|
5493
|
+
if (!quickAnswer) {
|
|
5494
|
+
return void 0;
|
|
5495
|
+
}
|
|
5496
|
+
if ("id" in quickAnswer && quickAnswer.id && elementById(quickAnswer.id)) {
|
|
5497
|
+
return {
|
|
5498
|
+
parseResult: {
|
|
5499
|
+
elements: [quickAnswer],
|
|
5500
|
+
errors: []
|
|
5501
|
+
},
|
|
5502
|
+
rawResponse: quickAnswer,
|
|
5503
|
+
elementById
|
|
5504
|
+
};
|
|
5505
|
+
}
|
|
5506
|
+
}
|
|
5398
5507
|
async function AiInspectElement(options) {
|
|
5399
5508
|
const { context, multi, targetElementDescription, callAI } = options;
|
|
5400
5509
|
const { screenshotBase64, screenshotBase64WithElementMarker } = context;
|
|
5401
|
-
const { description, elementById, elementByPosition
|
|
5402
|
-
|
|
5403
|
-
|
|
5404
|
-
|
|
5405
|
-
return {
|
|
5406
|
-
parseResult: {
|
|
5407
|
-
elements: [options.quickAnswer],
|
|
5408
|
-
errors: []
|
|
5409
|
-
},
|
|
5410
|
-
elementById
|
|
5411
|
-
};
|
|
5412
|
-
}
|
|
5413
|
-
if (!targetElementDescription) {
|
|
5414
|
-
return {
|
|
5415
|
-
parseResult: {
|
|
5416
|
-
elements: [],
|
|
5417
|
-
errors: [
|
|
5418
|
-
`inspect: cannot find the target by id: ${options.quickAnswer.id}, and no target element description is provided`
|
|
5419
|
-
]
|
|
5420
|
-
},
|
|
5421
|
-
elementById
|
|
5422
|
-
};
|
|
5423
|
-
}
|
|
5424
|
-
}
|
|
5425
|
-
if ("position" in options.quickAnswer && elementByPosition2(options.quickAnswer.position)) {
|
|
5426
|
-
return {
|
|
5427
|
-
parseResult: transformElementPositionToId(
|
|
5428
|
-
{
|
|
5429
|
-
elements: [options.quickAnswer]
|
|
5430
|
-
},
|
|
5431
|
-
context.content
|
|
5432
|
-
),
|
|
5433
|
-
elementById
|
|
5434
|
-
};
|
|
5435
|
-
}
|
|
5510
|
+
const { description, elementById, elementByPosition, size } = await describeUserPage(context);
|
|
5511
|
+
const quickAnswer = getQuickAnswer(options.quickAnswer, elementById);
|
|
5512
|
+
if (quickAnswer) {
|
|
5513
|
+
return quickAnswer;
|
|
5436
5514
|
}
|
|
5437
5515
|
(0, import_node_assert4.default)(
|
|
5438
5516
|
targetElementDescription,
|
|
5439
5517
|
"cannot find the target element description"
|
|
5440
5518
|
);
|
|
5519
|
+
const userInstructionPrompt = await findElementPrompt.format({
|
|
5520
|
+
pageDescription: description,
|
|
5521
|
+
targetElementDescription,
|
|
5522
|
+
multi
|
|
5523
|
+
});
|
|
5441
5524
|
const systemPrompt = systemPromptToFindElement();
|
|
5442
5525
|
const msgs = [
|
|
5443
5526
|
{ role: "system", content: systemPrompt },
|
|
5444
5527
|
{
|
|
5445
5528
|
role: "user",
|
|
5446
|
-
content:
|
|
5529
|
+
content: [
|
|
5447
5530
|
{
|
|
5448
5531
|
type: "image_url",
|
|
5449
5532
|
image_url: {
|
|
@@ -5452,46 +5535,23 @@ async function AiInspectElement(options) {
|
|
|
5452
5535
|
},
|
|
5453
5536
|
{
|
|
5454
5537
|
type: "text",
|
|
5455
|
-
text:
|
|
5456
|
-
pageDescription:
|
|
5457
|
-
|
|
5458
|
-
${description}
|
|
5459
|
-
|
|
5460
|
-
Here is the item user want to find. Just go ahead:
|
|
5461
|
-
=====================================
|
|
5462
|
-
${JSON.stringify({
|
|
5463
|
-
description: targetElementDescription,
|
|
5464
|
-
multi: multiDescription(multi)
|
|
5465
|
-
})}
|
|
5466
|
-
=====================================`
|
|
5538
|
+
text: userInstructionPrompt
|
|
5467
5539
|
}
|
|
5468
|
-
]
|
|
5540
|
+
]
|
|
5469
5541
|
}
|
|
5470
5542
|
];
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
msgs,
|
|
5474
|
-
AIActionType: 1 /* INSPECT_ELEMENT */
|
|
5475
|
-
});
|
|
5476
|
-
return {
|
|
5477
|
-
parseResult: transformElementPositionToId(res.content, context.content),
|
|
5478
|
-
rawResponse: res,
|
|
5479
|
-
elementById,
|
|
5480
|
-
usage: res.usage
|
|
5481
|
-
};
|
|
5482
|
-
}
|
|
5483
|
-
const inspectElement = await callAiFn({
|
|
5484
|
-
msgs,
|
|
5485
|
-
AIActionType: 1 /* INSPECT_ELEMENT */
|
|
5486
|
-
});
|
|
5543
|
+
const callAIFn = callAI || callToGetJSONObject;
|
|
5544
|
+
const res = await callAIFn(msgs, 1 /* INSPECT_ELEMENT */);
|
|
5487
5545
|
return {
|
|
5488
|
-
parseResult: transformElementPositionToId(
|
|
5489
|
-
|
|
5490
|
-
context.content
|
|
5546
|
+
parseResult: await transformElementPositionToId(
|
|
5547
|
+
res.content,
|
|
5548
|
+
context.content,
|
|
5549
|
+
size,
|
|
5550
|
+
screenshotBase64
|
|
5491
5551
|
),
|
|
5492
|
-
rawResponse:
|
|
5552
|
+
rawResponse: res.content,
|
|
5493
5553
|
elementById,
|
|
5494
|
-
usage:
|
|
5554
|
+
usage: res.usage
|
|
5495
5555
|
};
|
|
5496
5556
|
}
|
|
5497
5557
|
async function AiExtractElementInfo(options) {
|
|
@@ -5502,11 +5562,25 @@ async function AiExtractElementInfo(options) {
|
|
|
5502
5562
|
context,
|
|
5503
5563
|
liteContextConfig
|
|
5504
5564
|
);
|
|
5565
|
+
let dataKeys = "";
|
|
5566
|
+
let dataQueryText = "";
|
|
5567
|
+
if (typeof dataQuery === "string") {
|
|
5568
|
+
dataKeys = "";
|
|
5569
|
+
dataQueryText = dataQuery;
|
|
5570
|
+
} else {
|
|
5571
|
+
dataKeys = `return in key-value style object, keys are ${Object.keys(dataQuery).join(",")}`;
|
|
5572
|
+
dataQueryText = JSON.stringify(dataQuery, null, 2);
|
|
5573
|
+
}
|
|
5574
|
+
const extractDataPromptText = await extractDataPrompt.format({
|
|
5575
|
+
pageDescription: description,
|
|
5576
|
+
dataKeys,
|
|
5577
|
+
dataQuery: dataQueryText
|
|
5578
|
+
});
|
|
5505
5579
|
const msgs = [
|
|
5506
5580
|
{ role: "system", content: systemPrompt },
|
|
5507
5581
|
{
|
|
5508
5582
|
role: "user",
|
|
5509
|
-
content:
|
|
5583
|
+
content: [
|
|
5510
5584
|
{
|
|
5511
5585
|
type: "image_url",
|
|
5512
5586
|
image_url: {
|
|
@@ -5515,25 +5589,15 @@ async function AiExtractElementInfo(options) {
|
|
|
5515
5589
|
},
|
|
5516
5590
|
{
|
|
5517
5591
|
type: "text",
|
|
5518
|
-
text:
|
|
5519
|
-
pageDescription: ${description}
|
|
5520
|
-
|
|
5521
|
-
Use your extract_data_from_UI skill to find the following data, placing it in the \`data\` field
|
|
5522
|
-
DATA_DEMAND start:
|
|
5523
|
-
=====================================
|
|
5524
|
-
${typeof dataQuery === "object" ? `return in key-value style object, keys are ${Object.keys(dataQuery).join(",")}` : ""}
|
|
5525
|
-
${typeof dataQuery === "string" ? dataQuery : JSON.stringify(dataQuery, null, 2)}
|
|
5526
|
-
=====================================
|
|
5527
|
-
DATA_DEMAND ends.
|
|
5528
|
-
`
|
|
5592
|
+
text: extractDataPromptText
|
|
5529
5593
|
}
|
|
5530
|
-
]
|
|
5594
|
+
]
|
|
5531
5595
|
}
|
|
5532
5596
|
];
|
|
5533
|
-
const result = await callAiFn(
|
|
5597
|
+
const result = await callAiFn(
|
|
5534
5598
|
msgs,
|
|
5535
|
-
|
|
5536
|
-
|
|
5599
|
+
2 /* EXTRACT_DATA */
|
|
5600
|
+
);
|
|
5537
5601
|
return {
|
|
5538
5602
|
parseResult: result.content,
|
|
5539
5603
|
elementById,
|
|
@@ -5550,7 +5614,7 @@ async function AiAssert(options) {
|
|
|
5550
5614
|
{ role: "system", content: systemPrompt },
|
|
5551
5615
|
{
|
|
5552
5616
|
role: "user",
|
|
5553
|
-
content:
|
|
5617
|
+
content: [
|
|
5554
5618
|
{
|
|
5555
5619
|
type: "image_url",
|
|
5556
5620
|
image_url: {
|
|
@@ -5569,43 +5633,39 @@ async function AiAssert(options) {
|
|
|
5569
5633
|
=====================================
|
|
5570
5634
|
`
|
|
5571
5635
|
}
|
|
5572
|
-
]
|
|
5636
|
+
]
|
|
5573
5637
|
}
|
|
5574
5638
|
];
|
|
5575
|
-
const { content: assertResult, usage } = await callAiFn(
|
|
5639
|
+
const { content: assertResult, usage } = await callAiFn(
|
|
5576
5640
|
msgs,
|
|
5577
|
-
|
|
5578
|
-
|
|
5641
|
+
0 /* ASSERT */
|
|
5642
|
+
);
|
|
5579
5643
|
return {
|
|
5580
5644
|
content: assertResult,
|
|
5581
5645
|
usage
|
|
5582
5646
|
};
|
|
5583
5647
|
}
|
|
5584
5648
|
|
|
5585
|
-
// src/ai-model/automation
|
|
5649
|
+
// src/ai-model/automation.ts
|
|
5586
5650
|
var import_node_assert5 = __toESM(require("assert"));
|
|
5587
5651
|
async function plan(userPrompt, opts) {
|
|
5588
5652
|
const { callAI, context } = opts || {};
|
|
5589
5653
|
const { screenshotBase64, screenshotBase64WithElementMarker } = context;
|
|
5590
|
-
const { description: pageDescription, elementByPosition
|
|
5591
|
-
const systemPrompt = systemPromptToTaskPlanning();
|
|
5592
|
-
|
|
5593
|
-
|
|
5594
|
-
|
|
5595
|
-
|
|
5596
|
-
|
|
5597
|
-
|
|
5598
|
-
|
|
5599
|
-
|
|
5600
|
-
${opts.whatHaveDone}
|
|
5601
|
-
=====================================
|
|
5602
|
-
`;
|
|
5603
|
-
}
|
|
5654
|
+
const { description: pageDescription, elementByPosition } = await describeUserPage(context);
|
|
5655
|
+
const systemPrompt = await systemPromptToTaskPlanning();
|
|
5656
|
+
const userInstructionPrompt = await automationUserPrompt.format({
|
|
5657
|
+
pageDescription,
|
|
5658
|
+
userPrompt,
|
|
5659
|
+
taskBackgroundContext: taskBackgroundContext(
|
|
5660
|
+
opts.originalPrompt,
|
|
5661
|
+
opts.whatHaveDone
|
|
5662
|
+
)
|
|
5663
|
+
});
|
|
5604
5664
|
const msgs = [
|
|
5605
5665
|
{ role: "system", content: systemPrompt },
|
|
5606
5666
|
{
|
|
5607
5667
|
role: "user",
|
|
5608
|
-
content:
|
|
5668
|
+
content: [
|
|
5609
5669
|
{
|
|
5610
5670
|
type: "image_url",
|
|
5611
5671
|
image_url: {
|
|
@@ -5615,28 +5675,13 @@ ${opts.whatHaveDone}
|
|
|
5615
5675
|
},
|
|
5616
5676
|
{
|
|
5617
5677
|
type: "text",
|
|
5618
|
-
text:
|
|
5619
|
-
pageDescription:
|
|
5620
|
-
|
|
5621
|
-
${pageDescription}
|
|
5622
|
-
|
|
5623
|
-
|
|
5624
|
-
Here is the instruction:
|
|
5625
|
-
=====================================
|
|
5626
|
-
${userPrompt}
|
|
5627
|
-
=====================================
|
|
5628
|
-
|
|
5629
|
-
${taskBackgroundContext}
|
|
5630
|
-
`.trim()
|
|
5678
|
+
text: userInstructionPrompt
|
|
5631
5679
|
}
|
|
5632
|
-
]
|
|
5680
|
+
]
|
|
5633
5681
|
}
|
|
5634
5682
|
];
|
|
5635
|
-
const
|
|
5636
|
-
const { content, usage } = await
|
|
5637
|
-
msgs,
|
|
5638
|
-
AIActionType: 3 /* PLAN */
|
|
5639
|
-
});
|
|
5683
|
+
const call3 = callAI || callAiFn;
|
|
5684
|
+
const { content, usage } = await call3(msgs, 3 /* PLAN */);
|
|
5640
5685
|
const planFromAI = content;
|
|
5641
5686
|
const actions = (planFromAI == null ? void 0 : planFromAI.actions) || [];
|
|
5642
5687
|
(0, import_node_assert5.default)(planFromAI, "can't get plans from AI");
|