wuying-agentbay-sdk 0.11.0 → 0.12.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/{chunk-E7QC5S76.mjs → chunk-BVWUCG4J.mjs} +264 -5
- package/dist/chunk-BVWUCG4J.mjs.map +1 -0
- package/dist/{chunk-ZUB35HKV.cjs → chunk-SL5GCAQE.cjs} +265 -6
- package/dist/chunk-SL5GCAQE.cjs.map +1 -0
- package/dist/index.cjs +1295 -317
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +1694 -1125
- package/dist/index.d.ts +1694 -1125
- package/dist/index.mjs +1228 -250
- package/dist/index.mjs.map +1 -1
- package/dist/model-CNCGFWJH.cjs +200 -0
- package/dist/{model-2G37RFQQ.cjs.map → model-CNCGFWJH.cjs.map} +1 -1
- package/dist/{model-ZFTLKEMC.mjs → model-LGWQJWKQ.mjs} +14 -2
- package/docs/api/common-features/basics/agentbay.md +96 -0
- package/docs/api/common-features/basics/context-manager.md +21 -2
- package/docs/api/common-features/basics/session.md +130 -0
- package/docs/examples/browser-use/extension-example/extension-example.ts +2 -1
- package/docs/examples/common-features/basics/session-pause-resume/README.md +53 -0
- package/docs/examples/common-features/basics/session-pause-resume/session-pause-resume.ts +237 -0
- package/docs/examples/mobile-use/mobile-simulate-basic-usage.ts +202 -0
- package/docs/examples/mobile-use/mobile-simulate-with-ctx.ts +170 -0
- package/package.json +2 -2
- package/dist/chunk-E7QC5S76.mjs.map +0 -1
- package/dist/chunk-ZUB35HKV.cjs.map +0 -1
- package/dist/model-2G37RFQQ.cjs +0 -188
- /package/dist/{model-ZFTLKEMC.mjs.map → model-LGWQJWKQ.mjs.map} +0 -0
package/dist/index.mjs
CHANGED
|
@@ -94,16 +94,22 @@ import {
|
|
|
94
94
|
ModifyContextRequest,
|
|
95
95
|
ModifyContextResponse,
|
|
96
96
|
ModifyContextResponseBody,
|
|
97
|
+
PauseSessionAsyncRequest,
|
|
98
|
+
PauseSessionAsyncResponse,
|
|
99
|
+
PauseSessionAsyncResponseBody,
|
|
97
100
|
ReleaseMcpSessionRequest,
|
|
98
101
|
ReleaseMcpSessionResponse,
|
|
99
102
|
ReleaseMcpSessionResponseBody,
|
|
103
|
+
ResumeSessionAsyncRequest,
|
|
104
|
+
ResumeSessionAsyncResponse,
|
|
105
|
+
ResumeSessionAsyncResponseBody,
|
|
100
106
|
SetLabelRequest,
|
|
101
107
|
SetLabelResponse,
|
|
102
108
|
SetLabelResponseBody,
|
|
103
109
|
SyncContextRequest,
|
|
104
110
|
SyncContextResponse,
|
|
105
111
|
SyncContextResponseBody
|
|
106
|
-
} from "./chunk-
|
|
112
|
+
} from "./chunk-BVWUCG4J.mjs";
|
|
107
113
|
import {
|
|
108
114
|
__commonJS,
|
|
109
115
|
__dirname,
|
|
@@ -186,14 +192,14 @@ var require_main = __commonJS({
|
|
|
186
192
|
"node_modules/dotenv/lib/main.js"(exports, module) {
|
|
187
193
|
"use strict";
|
|
188
194
|
init_esm_shims();
|
|
189
|
-
var
|
|
190
|
-
var
|
|
195
|
+
var fs7 = __require("fs");
|
|
196
|
+
var path7 = __require("path");
|
|
191
197
|
var os = __require("os");
|
|
192
198
|
var crypto2 = __require("crypto");
|
|
193
199
|
var packageJson = require_package();
|
|
194
200
|
var version = packageJson.version;
|
|
195
201
|
var LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/mg;
|
|
196
|
-
function
|
|
202
|
+
function parse3(src) {
|
|
197
203
|
const obj = {};
|
|
198
204
|
let lines = src.toString();
|
|
199
205
|
lines = lines.replace(/\r\n?/mg, "\n");
|
|
@@ -212,7 +218,7 @@ var require_main = __commonJS({
|
|
|
212
218
|
}
|
|
213
219
|
return obj;
|
|
214
220
|
}
|
|
215
|
-
__name(
|
|
221
|
+
__name(parse3, "parse");
|
|
216
222
|
function _parseVault(options) {
|
|
217
223
|
options = options || {};
|
|
218
224
|
const vaultPath = _vaultPath(options);
|
|
@@ -302,7 +308,7 @@ var require_main = __commonJS({
|
|
|
302
308
|
if (options && options.path && options.path.length > 0) {
|
|
303
309
|
if (Array.isArray(options.path)) {
|
|
304
310
|
for (const filepath of options.path) {
|
|
305
|
-
if (
|
|
311
|
+
if (fs7.existsSync(filepath)) {
|
|
306
312
|
possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
307
313
|
}
|
|
308
314
|
}
|
|
@@ -310,16 +316,16 @@ var require_main = __commonJS({
|
|
|
310
316
|
possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
311
317
|
}
|
|
312
318
|
} else {
|
|
313
|
-
possibleVaultPath =
|
|
319
|
+
possibleVaultPath = path7.resolve(process.cwd(), ".env.vault");
|
|
314
320
|
}
|
|
315
|
-
if (
|
|
321
|
+
if (fs7.existsSync(possibleVaultPath)) {
|
|
316
322
|
return possibleVaultPath;
|
|
317
323
|
}
|
|
318
324
|
return null;
|
|
319
325
|
}
|
|
320
326
|
__name(_vaultPath, "_vaultPath");
|
|
321
327
|
function _resolveHome(envPath) {
|
|
322
|
-
return envPath[0] === "~" ?
|
|
328
|
+
return envPath[0] === "~" ? path7.join(os.homedir(), envPath.slice(1)) : envPath;
|
|
323
329
|
}
|
|
324
330
|
__name(_resolveHome, "_resolveHome");
|
|
325
331
|
function _configVault(options) {
|
|
@@ -338,7 +344,7 @@ var require_main = __commonJS({
|
|
|
338
344
|
}
|
|
339
345
|
__name(_configVault, "_configVault");
|
|
340
346
|
function configDotenv(options) {
|
|
341
|
-
const dotenvPath =
|
|
347
|
+
const dotenvPath = path7.resolve(process.cwd(), ".env");
|
|
342
348
|
let encoding = "utf8";
|
|
343
349
|
const debug = Boolean(options && options.debug);
|
|
344
350
|
const quiet = options && "quiet" in options ? options.quiet : true;
|
|
@@ -362,13 +368,13 @@ var require_main = __commonJS({
|
|
|
362
368
|
}
|
|
363
369
|
let lastError;
|
|
364
370
|
const parsedAll = {};
|
|
365
|
-
for (const
|
|
371
|
+
for (const path8 of optionPaths) {
|
|
366
372
|
try {
|
|
367
|
-
const parsed = DotenvModule.parse(
|
|
373
|
+
const parsed = DotenvModule.parse(fs7.readFileSync(path8, { encoding }));
|
|
368
374
|
DotenvModule.populate(parsedAll, parsed, options);
|
|
369
375
|
} catch (e) {
|
|
370
376
|
if (debug) {
|
|
371
|
-
_debug(`Failed to load ${
|
|
377
|
+
_debug(`Failed to load ${path8} ${e.message}`);
|
|
372
378
|
}
|
|
373
379
|
lastError = e;
|
|
374
380
|
}
|
|
@@ -383,7 +389,7 @@ var require_main = __commonJS({
|
|
|
383
389
|
const shortPaths = [];
|
|
384
390
|
for (const filePath of optionPaths) {
|
|
385
391
|
try {
|
|
386
|
-
const relative =
|
|
392
|
+
const relative = path7.relative(process.cwd(), filePath);
|
|
387
393
|
shortPaths.push(relative);
|
|
388
394
|
} catch (e) {
|
|
389
395
|
if (debug) {
|
|
@@ -473,7 +479,7 @@ var require_main = __commonJS({
|
|
|
473
479
|
_parseVault,
|
|
474
480
|
config,
|
|
475
481
|
decrypt,
|
|
476
|
-
parse:
|
|
482
|
+
parse: parse3,
|
|
477
483
|
populate
|
|
478
484
|
};
|
|
479
485
|
module.exports.configDotenv = DotenvModule.configDotenv;
|
|
@@ -553,7 +559,7 @@ function getVersionFromPackageJson() {
|
|
|
553
559
|
}
|
|
554
560
|
} catch (error) {
|
|
555
561
|
}
|
|
556
|
-
return "0.
|
|
562
|
+
return "0.12.0";
|
|
557
563
|
}
|
|
558
564
|
__name(getVersionFromPackageJson, "getVersionFromPackageJson");
|
|
559
565
|
function isReleaseBuild() {
|
|
@@ -581,9 +587,9 @@ init_esm_shims();
|
|
|
581
587
|
})();
|
|
582
588
|
|
|
583
589
|
// src/agent-bay.ts
|
|
584
|
-
var
|
|
585
|
-
import * as
|
|
586
|
-
import * as
|
|
590
|
+
var dotenv2 = __toESM(require_main());
|
|
591
|
+
import * as fs5 from "fs";
|
|
592
|
+
import * as path5 from "path";
|
|
587
593
|
|
|
588
594
|
// src/api/index.ts
|
|
589
595
|
init_esm_shims();
|
|
@@ -1059,6 +1065,96 @@ var _Client = class _Client extends (OpenApi.default || OpenApi) {
|
|
|
1059
1065
|
const runtime = new $dara.RuntimeOptions({});
|
|
1060
1066
|
return await this.getSessionWithOptions(request, runtime);
|
|
1061
1067
|
}
|
|
1068
|
+
/**
|
|
1069
|
+
* Pause session async
|
|
1070
|
+
*
|
|
1071
|
+
* @param request - PauseSessionAsyncRequest
|
|
1072
|
+
* @param runtime - runtime options for this request RuntimeOptions
|
|
1073
|
+
* @returns PauseSessionAsyncResponse
|
|
1074
|
+
*/
|
|
1075
|
+
async pauseSessionAsyncWithOptions(request, runtime) {
|
|
1076
|
+
request.validate();
|
|
1077
|
+
const body = {};
|
|
1078
|
+
if (!$dara.isNull(request.authorization)) {
|
|
1079
|
+
body["Authorization"] = request.authorization;
|
|
1080
|
+
}
|
|
1081
|
+
if (!$dara.isNull(request.sessionId)) {
|
|
1082
|
+
body["SessionId"] = request.sessionId;
|
|
1083
|
+
}
|
|
1084
|
+
const req = new $OpenApiUtil.OpenApiRequest({
|
|
1085
|
+
body: OpenApiUtil.parseToMap(body)
|
|
1086
|
+
});
|
|
1087
|
+
const params = new $OpenApiUtil.Params({
|
|
1088
|
+
action: "PauseSessionAsync",
|
|
1089
|
+
version: "2025-05-06",
|
|
1090
|
+
protocol: "HTTPS",
|
|
1091
|
+
pathname: "/",
|
|
1092
|
+
method: "POST",
|
|
1093
|
+
authType: "Anonymous",
|
|
1094
|
+
style: "RPC",
|
|
1095
|
+
reqBodyType: "formData",
|
|
1096
|
+
bodyType: "json"
|
|
1097
|
+
});
|
|
1098
|
+
return $dara.cast(
|
|
1099
|
+
await this.callApi(params, req, runtime),
|
|
1100
|
+
new PauseSessionAsyncResponse({})
|
|
1101
|
+
);
|
|
1102
|
+
}
|
|
1103
|
+
/**
|
|
1104
|
+
* Pause session async
|
|
1105
|
+
*
|
|
1106
|
+
* @param request - PauseSessionAsyncRequest
|
|
1107
|
+
* @returns PauseSessionAsyncResponse
|
|
1108
|
+
*/
|
|
1109
|
+
async pauseSessionAsync(request) {
|
|
1110
|
+
const runtime = new $dara.RuntimeOptions({});
|
|
1111
|
+
return await this.pauseSessionAsyncWithOptions(request, runtime);
|
|
1112
|
+
}
|
|
1113
|
+
/**
|
|
1114
|
+
* Resume session async
|
|
1115
|
+
*
|
|
1116
|
+
* @param request - ResumeSessionAsyncRequest
|
|
1117
|
+
* @param runtime - runtime options for this request RuntimeOptions
|
|
1118
|
+
* @returns ResumeSessionAsyncResponse
|
|
1119
|
+
*/
|
|
1120
|
+
async resumeSessionAsyncWithOptions(request, runtime) {
|
|
1121
|
+
request.validate();
|
|
1122
|
+
const body = {};
|
|
1123
|
+
if (!$dara.isNull(request.authorization)) {
|
|
1124
|
+
body["Authorization"] = request.authorization;
|
|
1125
|
+
}
|
|
1126
|
+
if (!$dara.isNull(request.sessionId)) {
|
|
1127
|
+
body["SessionId"] = request.sessionId;
|
|
1128
|
+
}
|
|
1129
|
+
const req = new $OpenApiUtil.OpenApiRequest({
|
|
1130
|
+
body: OpenApiUtil.parseToMap(body)
|
|
1131
|
+
});
|
|
1132
|
+
const params = new $OpenApiUtil.Params({
|
|
1133
|
+
action: "ResumeSessionAsync",
|
|
1134
|
+
version: "2025-05-06",
|
|
1135
|
+
protocol: "HTTPS",
|
|
1136
|
+
pathname: "/",
|
|
1137
|
+
method: "POST",
|
|
1138
|
+
authType: "Anonymous",
|
|
1139
|
+
style: "RPC",
|
|
1140
|
+
reqBodyType: "formData",
|
|
1141
|
+
bodyType: "json"
|
|
1142
|
+
});
|
|
1143
|
+
return $dara.cast(
|
|
1144
|
+
await this.callApi(params, req, runtime),
|
|
1145
|
+
new ResumeSessionAsyncResponse({})
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
/**
|
|
1149
|
+
* Resume session async
|
|
1150
|
+
*
|
|
1151
|
+
* @param request - ResumeSessionAsyncRequest
|
|
1152
|
+
* @returns ResumeSessionAsyncResponse
|
|
1153
|
+
*/
|
|
1154
|
+
async resumeSessionAsync(request) {
|
|
1155
|
+
const runtime = new $dara.RuntimeOptions({});
|
|
1156
|
+
return await this.resumeSessionAsyncWithOptions(request, runtime);
|
|
1157
|
+
}
|
|
1062
1158
|
/**
|
|
1063
1159
|
* Get forwarding link for specific port
|
|
1064
1160
|
*
|
|
@@ -1904,6 +2000,70 @@ var _Client = class _Client extends (OpenApi.default || OpenApi) {
|
|
|
1904
2000
|
__name(_Client, "Client");
|
|
1905
2001
|
var Client = _Client;
|
|
1906
2002
|
|
|
2003
|
+
// src/config.ts
|
|
2004
|
+
init_esm_shims();
|
|
2005
|
+
var dotenv = __toESM(require_main());
|
|
2006
|
+
import * as fs2 from "fs";
|
|
2007
|
+
import * as path2 from "path";
|
|
2008
|
+
var BROWSER_RECORD_PATH = "/home/guest/record";
|
|
2009
|
+
function findDotEnvFile(startPath) {
|
|
2010
|
+
const currentPath = startPath ? path2.resolve(startPath) : process.cwd();
|
|
2011
|
+
let searchPath = currentPath;
|
|
2012
|
+
while (searchPath !== path2.dirname(searchPath)) {
|
|
2013
|
+
const envFile = path2.join(searchPath, ".env");
|
|
2014
|
+
if (fs2.existsSync(envFile)) {
|
|
2015
|
+
return envFile;
|
|
2016
|
+
}
|
|
2017
|
+
const gitDir = path2.join(searchPath, ".git");
|
|
2018
|
+
if (fs2.existsSync(gitDir)) {
|
|
2019
|
+
}
|
|
2020
|
+
searchPath = path2.dirname(searchPath);
|
|
2021
|
+
}
|
|
2022
|
+
const rootEnv = path2.join(searchPath, ".env");
|
|
2023
|
+
if (fs2.existsSync(rootEnv)) {
|
|
2024
|
+
return rootEnv;
|
|
2025
|
+
}
|
|
2026
|
+
return null;
|
|
2027
|
+
}
|
|
2028
|
+
__name(findDotEnvFile, "findDotEnvFile");
|
|
2029
|
+
function loadDotEnvWithFallback(customEnvPath) {
|
|
2030
|
+
if (customEnvPath) {
|
|
2031
|
+
if (fs2.existsSync(customEnvPath)) {
|
|
2032
|
+
try {
|
|
2033
|
+
const envConfig = dotenv.parse(fs2.readFileSync(customEnvPath));
|
|
2034
|
+
for (const k in envConfig) {
|
|
2035
|
+
if (!process.env.hasOwnProperty(k)) {
|
|
2036
|
+
process.env[k] = envConfig[k];
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
return;
|
|
2040
|
+
} catch (error) {
|
|
2041
|
+
}
|
|
2042
|
+
}
|
|
2043
|
+
}
|
|
2044
|
+
const envFile = findDotEnvFile();
|
|
2045
|
+
if (envFile) {
|
|
2046
|
+
try {
|
|
2047
|
+
const envConfig = dotenv.parse(fs2.readFileSync(envFile));
|
|
2048
|
+
for (const k in envConfig) {
|
|
2049
|
+
if (!process.env.hasOwnProperty(k)) {
|
|
2050
|
+
process.env[k] = envConfig[k];
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
} catch (error) {
|
|
2054
|
+
}
|
|
2055
|
+
}
|
|
2056
|
+
}
|
|
2057
|
+
__name(loadDotEnvWithFallback, "loadDotEnvWithFallback");
|
|
2058
|
+
var dotEnvLoaded = false;
|
|
2059
|
+
if (!dotEnvLoaded) {
|
|
2060
|
+
try {
|
|
2061
|
+
loadDotEnvWithFallback();
|
|
2062
|
+
dotEnvLoaded = true;
|
|
2063
|
+
} catch (error) {
|
|
2064
|
+
}
|
|
2065
|
+
}
|
|
2066
|
+
|
|
1907
2067
|
// src/context.ts
|
|
1908
2068
|
init_esm_shims();
|
|
1909
2069
|
|
|
@@ -1978,8 +2138,8 @@ var BrowserError = _BrowserError;
|
|
|
1978
2138
|
|
|
1979
2139
|
// src/utils/logger.ts
|
|
1980
2140
|
init_esm_shims();
|
|
1981
|
-
import * as
|
|
1982
|
-
import * as
|
|
2141
|
+
import * as fs3 from "fs";
|
|
2142
|
+
import * as path3 from "path";
|
|
1983
2143
|
var LOG_LEVEL_VALUES = {
|
|
1984
2144
|
DEBUG: 0,
|
|
1985
2145
|
INFO: 1,
|
|
@@ -2158,17 +2318,17 @@ function writeToFile(message) {
|
|
|
2158
2318
|
return;
|
|
2159
2319
|
}
|
|
2160
2320
|
try {
|
|
2161
|
-
if (
|
|
2162
|
-
const stats =
|
|
2321
|
+
if (fs3.existsSync(logFilePath)) {
|
|
2322
|
+
const stats = fs3.statSync(logFilePath);
|
|
2163
2323
|
if (stats.size >= logFileMaxSize) {
|
|
2164
2324
|
const rotatedPath = `${logFilePath}.1`;
|
|
2165
|
-
if (
|
|
2166
|
-
|
|
2325
|
+
if (fs3.existsSync(rotatedPath)) {
|
|
2326
|
+
fs3.unlinkSync(rotatedPath);
|
|
2167
2327
|
}
|
|
2168
|
-
|
|
2328
|
+
fs3.renameSync(logFilePath, rotatedPath);
|
|
2169
2329
|
}
|
|
2170
2330
|
}
|
|
2171
|
-
|
|
2331
|
+
fs3.appendFileSync(logFilePath, message + "\n", "utf8");
|
|
2172
2332
|
} catch (error) {
|
|
2173
2333
|
if (consoleLoggingEnabled) {
|
|
2174
2334
|
process.stderr.write(`Failed to write to log file: ${error}
|
|
@@ -2185,9 +2345,9 @@ function setupLogger(config) {
|
|
|
2185
2345
|
if (config.logFile) {
|
|
2186
2346
|
logFilePath = config.logFile;
|
|
2187
2347
|
fileLoggingEnabled = true;
|
|
2188
|
-
const dir =
|
|
2189
|
-
if (!
|
|
2190
|
-
|
|
2348
|
+
const dir = path3.dirname(logFilePath);
|
|
2349
|
+
if (!fs3.existsSync(dir)) {
|
|
2350
|
+
fs3.mkdirSync(dir, { recursive: true });
|
|
2191
2351
|
}
|
|
2192
2352
|
if (config.maxFileSize) {
|
|
2193
2353
|
logFileMaxSize = parseFileSize(config.maxFileSize);
|
|
@@ -3223,7 +3383,7 @@ var _ContextService = class _ContextService {
|
|
|
3223
3383
|
const maxAttempts = Math.floor(timeout / pollInterval);
|
|
3224
3384
|
let attempt = 0;
|
|
3225
3385
|
while (attempt < maxAttempts) {
|
|
3226
|
-
await new Promise((
|
|
3386
|
+
await new Promise((resolve3) => setTimeout(resolve3, pollInterval * 1e3));
|
|
3227
3387
|
attempt++;
|
|
3228
3388
|
const statusResult = await this.getClearStatus(contextId);
|
|
3229
3389
|
if (!statusResult.success) {
|
|
@@ -3313,8 +3473,8 @@ var _ExtractPolicyClass = class _ExtractPolicyClass {
|
|
|
3313
3473
|
__name(_ExtractPolicyClass, "ExtractPolicyClass");
|
|
3314
3474
|
var ExtractPolicyClass = _ExtractPolicyClass;
|
|
3315
3475
|
var _WhiteListValidator = class _WhiteListValidator {
|
|
3316
|
-
static containsWildcard(
|
|
3317
|
-
return /[*?\[\]]/.test(
|
|
3476
|
+
static containsWildcard(path7) {
|
|
3477
|
+
return /[*?\[\]]/.test(path7);
|
|
3318
3478
|
}
|
|
3319
3479
|
static validate(whitelist) {
|
|
3320
3480
|
if (this.containsWildcard(whitelist.path)) {
|
|
@@ -3389,12 +3549,12 @@ var _SyncPolicyImpl = class _SyncPolicyImpl {
|
|
|
3389
3549
|
__name(_SyncPolicyImpl, "SyncPolicyImpl");
|
|
3390
3550
|
var SyncPolicyImpl = _SyncPolicyImpl;
|
|
3391
3551
|
var _ContextSync = class _ContextSync {
|
|
3392
|
-
constructor(contextId,
|
|
3552
|
+
constructor(contextId, path7, policy) {
|
|
3393
3553
|
if (policy) {
|
|
3394
3554
|
validateSyncPolicy(policy);
|
|
3395
3555
|
}
|
|
3396
3556
|
this.contextId = contextId;
|
|
3397
|
-
this.path =
|
|
3557
|
+
this.path = path7;
|
|
3398
3558
|
this.policy = policy;
|
|
3399
3559
|
}
|
|
3400
3560
|
// WithPolicy sets the policy and returns the context sync for chaining
|
|
@@ -3495,9 +3655,9 @@ function validateSyncPolicy(policy) {
|
|
|
3495
3655
|
);
|
|
3496
3656
|
}
|
|
3497
3657
|
if (policy.recyclePolicy.paths) {
|
|
3498
|
-
for (const
|
|
3499
|
-
if (
|
|
3500
|
-
const tempWhiteList = { path:
|
|
3658
|
+
for (const path7 of policy.recyclePolicy.paths) {
|
|
3659
|
+
if (path7 && path7.trim() !== "") {
|
|
3660
|
+
const tempWhiteList = { path: path7 };
|
|
3501
3661
|
WhiteListValidator.validate(tempWhiteList);
|
|
3502
3662
|
}
|
|
3503
3663
|
}
|
|
@@ -3509,11 +3669,11 @@ function newSyncPolicyWithDefaults(policy) {
|
|
|
3509
3669
|
return new SyncPolicyImpl(policy).toJSON();
|
|
3510
3670
|
}
|
|
3511
3671
|
__name(newSyncPolicyWithDefaults, "newSyncPolicyWithDefaults");
|
|
3512
|
-
function newContextSync(contextId,
|
|
3672
|
+
function newContextSync(contextId, path7, policy) {
|
|
3513
3673
|
if (policy) {
|
|
3514
3674
|
validateSyncPolicy(policy);
|
|
3515
3675
|
}
|
|
3516
|
-
return new ContextSync(contextId,
|
|
3676
|
+
return new ContextSync(contextId, path7, policy);
|
|
3517
3677
|
}
|
|
3518
3678
|
__name(newContextSync, "newContextSync");
|
|
3519
3679
|
|
|
@@ -3645,7 +3805,7 @@ var _Agent = class _Agent {
|
|
|
3645
3805
|
};
|
|
3646
3806
|
}
|
|
3647
3807
|
logDebug(`Task ${taskId} is still running, please wait for a while.`);
|
|
3648
|
-
await new Promise((
|
|
3808
|
+
await new Promise((resolve3) => setTimeout(resolve3, 3e3));
|
|
3649
3809
|
triedTime++;
|
|
3650
3810
|
}
|
|
3651
3811
|
return {
|
|
@@ -4582,8 +4742,8 @@ var _BrowserFingerprintGenerator = class _BrowserFingerprintGenerator {
|
|
|
4582
4742
|
async saveToFile(jsonData, filename) {
|
|
4583
4743
|
try {
|
|
4584
4744
|
if (typeof __require !== "undefined") {
|
|
4585
|
-
const
|
|
4586
|
-
|
|
4745
|
+
const fs7 = __require("fs");
|
|
4746
|
+
fs7.writeFileSync(filename, jsonData, "utf8");
|
|
4587
4747
|
console.log(`Fingerprint data saved to ${filename}`);
|
|
4588
4748
|
return true;
|
|
4589
4749
|
} else {
|
|
@@ -5032,7 +5192,7 @@ var _Browser = class _Browser {
|
|
|
5032
5192
|
logDebug(`VPC mode, endpoint_router_port: ${this.session.httpPort}`);
|
|
5033
5193
|
this._endpointUrl = `ws://${this.session.networkInterfaceIp}:${this.session.httpPort}`;
|
|
5034
5194
|
} else {
|
|
5035
|
-
const { GetCdpLinkRequest: GetCdpLinkRequest2 } = await import("./model-
|
|
5195
|
+
const { GetCdpLinkRequest: GetCdpLinkRequest2 } = await import("./model-LGWQJWKQ.mjs");
|
|
5036
5196
|
const request = new GetCdpLinkRequest2({
|
|
5037
5197
|
authorization: `Bearer ${this.session.getAPIKey()}`,
|
|
5038
5198
|
sessionId: this.session.sessionId
|
|
@@ -6544,7 +6704,7 @@ var _ContextManager = class _ContextManager {
|
|
|
6544
6704
|
* }
|
|
6545
6705
|
* ```
|
|
6546
6706
|
*/
|
|
6547
|
-
async infoWithParams(contextId,
|
|
6707
|
+
async infoWithParams(contextId, path7, taskType) {
|
|
6548
6708
|
const request = new GetContextInfoRequest({
|
|
6549
6709
|
authorization: `Bearer ${this.session.getAPIKey()}`,
|
|
6550
6710
|
sessionId: this.session.getSessionId()
|
|
@@ -6552,8 +6712,8 @@ var _ContextManager = class _ContextManager {
|
|
|
6552
6712
|
if (contextId) {
|
|
6553
6713
|
request.contextId = contextId;
|
|
6554
6714
|
}
|
|
6555
|
-
if (
|
|
6556
|
-
request.path =
|
|
6715
|
+
if (path7) {
|
|
6716
|
+
request.path = path7;
|
|
6557
6717
|
}
|
|
6558
6718
|
if (taskType) {
|
|
6559
6719
|
request.taskType = taskType;
|
|
@@ -6628,16 +6788,31 @@ var _ContextManager = class _ContextManager {
|
|
|
6628
6788
|
/**
|
|
6629
6789
|
* Synchronizes a context with the session. Supports both async and callback modes.
|
|
6630
6790
|
*
|
|
6631
|
-
* @param contextId - Optional context ID to synchronize
|
|
6632
|
-
* @param path - Optional path where the context should be mounted
|
|
6791
|
+
* @param contextId - Optional context ID to synchronize. If provided, `path` must also be provided.
|
|
6792
|
+
* @param path - Optional path where the context should be mounted. If provided, `contextId` must also be provided.
|
|
6633
6793
|
* @param mode - Optional synchronization mode (e.g., "upload", "download")
|
|
6634
6794
|
* @param callback - Optional callback function. If provided, runs in background and calls callback when complete
|
|
6635
6795
|
* @param maxRetries - Maximum number of retries for polling completion status (default: 150)
|
|
6636
6796
|
* @param retryInterval - Milliseconds to wait between retries (default: 1500)
|
|
6637
6797
|
* @returns Promise resolving to ContextSyncResult with success status and request ID
|
|
6638
6798
|
* @throws Error if the API call fails
|
|
6799
|
+
* @throws Error if `contextId` or `path` is provided without the other parameter.
|
|
6800
|
+
* Both must be provided together, or both must be omitted.
|
|
6801
|
+
*
|
|
6802
|
+
* @example
|
|
6803
|
+
* Sync all contexts (no parameters):
|
|
6804
|
+
* ```typescript
|
|
6805
|
+
* const agentBay = new AgentBay({ apiKey: 'your_api_key' });
|
|
6806
|
+
* const result = await agentBay.create();
|
|
6807
|
+
* if (result.success) {
|
|
6808
|
+
* const syncResult = await result.session.context.sync();
|
|
6809
|
+
* console.log(`Sync: ${syncResult.success}`);
|
|
6810
|
+
* await result.session.delete();
|
|
6811
|
+
* }
|
|
6812
|
+
* ```
|
|
6639
6813
|
*
|
|
6640
6814
|
* @example
|
|
6815
|
+
* Sync specific context with path:
|
|
6641
6816
|
* ```typescript
|
|
6642
6817
|
* const agentBay = new AgentBay({ apiKey: 'your_api_key' });
|
|
6643
6818
|
* const result = await agentBay.create();
|
|
@@ -6649,7 +6824,14 @@ var _ContextManager = class _ContextManager {
|
|
|
6649
6824
|
* }
|
|
6650
6825
|
* ```
|
|
6651
6826
|
*/
|
|
6652
|
-
async sync(contextId,
|
|
6827
|
+
async sync(contextId, path7, mode, callback, maxRetries = 150, retryInterval = 1500) {
|
|
6828
|
+
const hasContextId = contextId !== void 0 && contextId.trim() !== "";
|
|
6829
|
+
const hasPath = path7 !== void 0 && path7.trim() !== "";
|
|
6830
|
+
if (hasContextId !== hasPath) {
|
|
6831
|
+
throw new Error(
|
|
6832
|
+
"contextId and path must be provided together or both omitted. If you want to sync a specific context, both contextId and path are required. If you want to sync all contexts, omit both parameters."
|
|
6833
|
+
);
|
|
6834
|
+
}
|
|
6653
6835
|
const request = new SyncContextRequest({
|
|
6654
6836
|
authorization: `Bearer ${this.session.getAPIKey()}`,
|
|
6655
6837
|
sessionId: this.session.getSessionId()
|
|
@@ -6657,8 +6839,8 @@ var _ContextManager = class _ContextManager {
|
|
|
6657
6839
|
if (contextId) {
|
|
6658
6840
|
request.contextId = contextId;
|
|
6659
6841
|
}
|
|
6660
|
-
if (
|
|
6661
|
-
request.path =
|
|
6842
|
+
if (path7) {
|
|
6843
|
+
request.path = path7;
|
|
6662
6844
|
}
|
|
6663
6845
|
if (mode) {
|
|
6664
6846
|
request.mode = mode;
|
|
@@ -6708,7 +6890,7 @@ var _ContextManager = class _ContextManager {
|
|
|
6708
6890
|
const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : "";
|
|
6709
6891
|
logAPIResponseWithDetails("SyncContext", requestId, success, keyFields, fullResponse);
|
|
6710
6892
|
if (callback && success) {
|
|
6711
|
-
this.pollForCompletion(callback, contextId,
|
|
6893
|
+
this.pollForCompletion(callback, contextId, path7, maxRetries, retryInterval).catch((error) => {
|
|
6712
6894
|
logError("Error in background polling:", error);
|
|
6713
6895
|
callback(false);
|
|
6714
6896
|
});
|
|
@@ -6720,7 +6902,7 @@ var _ContextManager = class _ContextManager {
|
|
|
6720
6902
|
if (success) {
|
|
6721
6903
|
const finalSuccess = await this.pollForCompletionAsync(
|
|
6722
6904
|
contextId,
|
|
6723
|
-
|
|
6905
|
+
path7,
|
|
6724
6906
|
maxRetries,
|
|
6725
6907
|
retryInterval
|
|
6726
6908
|
);
|
|
@@ -6741,10 +6923,10 @@ var _ContextManager = class _ContextManager {
|
|
|
6741
6923
|
/**
|
|
6742
6924
|
* Polls the info interface to check if sync is completed and calls callback.
|
|
6743
6925
|
*/
|
|
6744
|
-
async pollForCompletion(callback, contextId,
|
|
6926
|
+
async pollForCompletion(callback, contextId, path7, maxRetries = 150, retryInterval = 1500) {
|
|
6745
6927
|
for (let retry = 0; retry < maxRetries; retry++) {
|
|
6746
6928
|
try {
|
|
6747
|
-
const infoResult = await this.infoWithParams(contextId,
|
|
6929
|
+
const infoResult = await this.infoWithParams(contextId, path7);
|
|
6748
6930
|
let allCompleted = true;
|
|
6749
6931
|
let hasFailure = false;
|
|
6750
6932
|
let hasSyncTasks = false;
|
|
@@ -6789,10 +6971,10 @@ var _ContextManager = class _ContextManager {
|
|
|
6789
6971
|
/**
|
|
6790
6972
|
* Async version of polling for sync completion.
|
|
6791
6973
|
*/
|
|
6792
|
-
async pollForCompletionAsync(contextId,
|
|
6974
|
+
async pollForCompletionAsync(contextId, path7, maxRetries = 150, retryInterval = 1500) {
|
|
6793
6975
|
for (let retry = 0; retry < maxRetries; retry++) {
|
|
6794
6976
|
try {
|
|
6795
|
-
const infoResult = await this.infoWithParams(contextId,
|
|
6977
|
+
const infoResult = await this.infoWithParams(contextId, path7);
|
|
6796
6978
|
let allCompleted = true;
|
|
6797
6979
|
let hasFailure = false;
|
|
6798
6980
|
let hasSyncTasks = false;
|
|
@@ -6837,7 +7019,7 @@ var _ContextManager = class _ContextManager {
|
|
|
6837
7019
|
* Sleep utility function for TypeScript
|
|
6838
7020
|
*/
|
|
6839
7021
|
sleep(ms) {
|
|
6840
|
-
return new Promise((
|
|
7022
|
+
return new Promise((resolve3) => setTimeout(resolve3, ms));
|
|
6841
7023
|
}
|
|
6842
7024
|
};
|
|
6843
7025
|
__name(_ContextManager, "ContextManager");
|
|
@@ -6852,8 +7034,8 @@ init_esm_shims();
|
|
|
6852
7034
|
|
|
6853
7035
|
// src/filesystem/file-transfer.ts
|
|
6854
7036
|
init_esm_shims();
|
|
6855
|
-
import * as
|
|
6856
|
-
import * as
|
|
7037
|
+
import * as fs4 from "fs";
|
|
7038
|
+
import * as path4 from "path";
|
|
6857
7039
|
import fetch2 from "node-fetch";
|
|
6858
7040
|
var _FileTransfer = class _FileTransfer {
|
|
6859
7041
|
/**
|
|
@@ -6892,7 +7074,7 @@ var _FileTransfer = class _FileTransfer {
|
|
|
6892
7074
|
progressCb = void 0
|
|
6893
7075
|
} = options || {};
|
|
6894
7076
|
try {
|
|
6895
|
-
if (!
|
|
7077
|
+
if (!fs4.existsSync(localPath)) {
|
|
6896
7078
|
return {
|
|
6897
7079
|
success: false,
|
|
6898
7080
|
bytesSent: 0,
|
|
@@ -6962,7 +7144,7 @@ var _FileTransfer = class _FileTransfer {
|
|
|
6962
7144
|
// Assuming previous step succeeded
|
|
6963
7145
|
etag: "",
|
|
6964
7146
|
// Assuming previous step succeeded
|
|
6965
|
-
bytesSent:
|
|
7147
|
+
bytesSent: fs4.statSync(localPath).size,
|
|
6966
7148
|
// Assuming previous step succeeded
|
|
6967
7149
|
path: remotePath,
|
|
6968
7150
|
error: `session.context.sync(upload) failed: ${e.message || e}`
|
|
@@ -6986,7 +7168,7 @@ var _FileTransfer = class _FileTransfer {
|
|
|
6986
7168
|
// Assuming previous step succeeded
|
|
6987
7169
|
etag: "",
|
|
6988
7170
|
// Assuming previous step succeeded
|
|
6989
|
-
bytesSent:
|
|
7171
|
+
bytesSent: fs4.statSync(localPath).size,
|
|
6990
7172
|
// Assuming previous step succeeded
|
|
6991
7173
|
path: remotePath,
|
|
6992
7174
|
error: `Upload sync not finished: ${error || "timeout or unknown"}`
|
|
@@ -6999,7 +7181,7 @@ var _FileTransfer = class _FileTransfer {
|
|
|
6999
7181
|
requestIdSync: reqIdSync,
|
|
7000
7182
|
httpStatus: 200,
|
|
7001
7183
|
etag: "",
|
|
7002
|
-
bytesSent:
|
|
7184
|
+
bytesSent: fs4.statSync(localPath).size,
|
|
7003
7185
|
path: remotePath
|
|
7004
7186
|
};
|
|
7005
7187
|
} catch (e) {
|
|
@@ -7086,11 +7268,11 @@ var _FileTransfer = class _FileTransfer {
|
|
|
7086
7268
|
const downloadUrl = urlRes.url;
|
|
7087
7269
|
const reqIdDownload = urlRes.requestId;
|
|
7088
7270
|
try {
|
|
7089
|
-
const dir =
|
|
7090
|
-
if (!
|
|
7091
|
-
|
|
7271
|
+
const dir = path4.dirname(localPath);
|
|
7272
|
+
if (!fs4.existsSync(dir)) {
|
|
7273
|
+
fs4.mkdirSync(dir, { recursive: true });
|
|
7092
7274
|
}
|
|
7093
|
-
if (
|
|
7275
|
+
if (fs4.existsSync(localPath) && !overwrite) {
|
|
7094
7276
|
return {
|
|
7095
7277
|
success: false,
|
|
7096
7278
|
requestIdDownloadUrl: reqIdDownload,
|
|
@@ -7106,13 +7288,13 @@ var _FileTransfer = class _FileTransfer {
|
|
|
7106
7288
|
localPath,
|
|
7107
7289
|
progressCb
|
|
7108
7290
|
);
|
|
7109
|
-
if (
|
|
7291
|
+
if (fs4.existsSync(localPath)) {
|
|
7110
7292
|
return {
|
|
7111
7293
|
success: true,
|
|
7112
7294
|
requestIdDownloadUrl: reqIdDownload,
|
|
7113
7295
|
requestIdSync: reqIdSync,
|
|
7114
7296
|
httpStatus: 200,
|
|
7115
|
-
bytesReceived:
|
|
7297
|
+
bytesReceived: fs4.statSync(localPath).size,
|
|
7116
7298
|
path: remotePath,
|
|
7117
7299
|
localPath
|
|
7118
7300
|
};
|
|
@@ -7211,11 +7393,11 @@ var _FileTransfer = class _FileTransfer {
|
|
|
7211
7393
|
const statusList = res.contextStatusData || [];
|
|
7212
7394
|
for (const item of statusList) {
|
|
7213
7395
|
const cid = item.contextId;
|
|
7214
|
-
const
|
|
7396
|
+
const path7 = item.path;
|
|
7215
7397
|
const ttype = item.taskType;
|
|
7216
7398
|
const status = item.status;
|
|
7217
7399
|
const err = item.errorMessage;
|
|
7218
|
-
if (cid === contextId &&
|
|
7400
|
+
if (cid === contextId && path7 === remotePath && (taskType === void 0 || ttype === taskType)) {
|
|
7219
7401
|
if (err) {
|
|
7220
7402
|
return { success: false, error: `Task error: ${err}` };
|
|
7221
7403
|
}
|
|
@@ -7228,7 +7410,7 @@ var _FileTransfer = class _FileTransfer {
|
|
|
7228
7410
|
} catch (e) {
|
|
7229
7411
|
lastErr = `info error: ${e.message || e}`;
|
|
7230
7412
|
}
|
|
7231
|
-
await new Promise((
|
|
7413
|
+
await new Promise((resolve3) => setTimeout(resolve3, interval * 1e3));
|
|
7232
7414
|
}
|
|
7233
7415
|
return { success: false, error: lastErr || "timeout" };
|
|
7234
7416
|
}
|
|
@@ -7241,7 +7423,7 @@ var _FileTransfer = class _FileTransfer {
|
|
|
7241
7423
|
if (contentType) {
|
|
7242
7424
|
headers["Content-Type"] = contentType;
|
|
7243
7425
|
}
|
|
7244
|
-
const fileBuffer =
|
|
7426
|
+
const fileBuffer = fs4.readFileSync(filePath);
|
|
7245
7427
|
const response = await fetch2(url, {
|
|
7246
7428
|
method: "PUT",
|
|
7247
7429
|
body: fileBuffer,
|
|
@@ -7268,7 +7450,7 @@ var _FileTransfer = class _FileTransfer {
|
|
|
7268
7450
|
}
|
|
7269
7451
|
const buffer = await response.buffer();
|
|
7270
7452
|
bytesReceived = buffer.length;
|
|
7271
|
-
|
|
7453
|
+
fs4.writeFileSync(destPath, buffer);
|
|
7272
7454
|
if (progressCb) {
|
|
7273
7455
|
progressCb(bytesReceived);
|
|
7274
7456
|
}
|
|
@@ -7427,10 +7609,10 @@ var _FileSystem = class _FileSystem {
|
|
|
7427
7609
|
* }
|
|
7428
7610
|
* ```
|
|
7429
7611
|
*/
|
|
7430
|
-
async createDirectory(
|
|
7612
|
+
async createDirectory(path7) {
|
|
7431
7613
|
try {
|
|
7432
7614
|
const args = {
|
|
7433
|
-
path:
|
|
7615
|
+
path: path7
|
|
7434
7616
|
};
|
|
7435
7617
|
const result = await this.session.callMcpTool(
|
|
7436
7618
|
"create_directory",
|
|
@@ -7478,10 +7660,10 @@ var _FileSystem = class _FileSystem {
|
|
|
7478
7660
|
* }
|
|
7479
7661
|
* ```
|
|
7480
7662
|
*/
|
|
7481
|
-
async editFile(
|
|
7663
|
+
async editFile(path7, edits, dryRun = false) {
|
|
7482
7664
|
try {
|
|
7483
7665
|
const args = {
|
|
7484
|
-
path:
|
|
7666
|
+
path: path7,
|
|
7485
7667
|
edits,
|
|
7486
7668
|
dryRun
|
|
7487
7669
|
};
|
|
@@ -7528,10 +7710,10 @@ var _FileSystem = class _FileSystem {
|
|
|
7528
7710
|
* }
|
|
7529
7711
|
* ```
|
|
7530
7712
|
*/
|
|
7531
|
-
async getFileInfo(
|
|
7713
|
+
async getFileInfo(path7) {
|
|
7532
7714
|
try {
|
|
7533
7715
|
const args = {
|
|
7534
|
-
path:
|
|
7716
|
+
path: path7
|
|
7535
7717
|
};
|
|
7536
7718
|
const result = await this.session.callMcpTool(
|
|
7537
7719
|
"get_file_info",
|
|
@@ -7606,10 +7788,10 @@ var _FileSystem = class _FileSystem {
|
|
|
7606
7788
|
*
|
|
7607
7789
|
* @see {@link readFile}, {@link writeFile}
|
|
7608
7790
|
*/
|
|
7609
|
-
async listDirectory(
|
|
7791
|
+
async listDirectory(path7) {
|
|
7610
7792
|
try {
|
|
7611
7793
|
const args = {
|
|
7612
|
-
path:
|
|
7794
|
+
path: path7
|
|
7613
7795
|
};
|
|
7614
7796
|
const result = await this.session.callMcpTool(
|
|
7615
7797
|
"list_directory",
|
|
@@ -7696,10 +7878,10 @@ var _FileSystem = class _FileSystem {
|
|
|
7696
7878
|
* @param length - Optional: Number of bytes to read. If 0, reads the entire file from offset.
|
|
7697
7879
|
* @returns FileContentResult with file content and requestId
|
|
7698
7880
|
*/
|
|
7699
|
-
async readFileChunk(
|
|
7881
|
+
async readFileChunk(path7, offset = 0, length = 0) {
|
|
7700
7882
|
try {
|
|
7701
7883
|
const args = {
|
|
7702
|
-
path:
|
|
7884
|
+
path: path7
|
|
7703
7885
|
};
|
|
7704
7886
|
if (offset > 0) {
|
|
7705
7887
|
args.offset = offset;
|
|
@@ -7778,8 +7960,8 @@ var _FileSystem = class _FileSystem {
|
|
|
7778
7960
|
for (const line of lines) {
|
|
7779
7961
|
const colonIndex = line.indexOf(":");
|
|
7780
7962
|
if (colonIndex > 0 && currentPath === "" && !line.substring(0, colonIndex).includes(" ")) {
|
|
7781
|
-
const
|
|
7782
|
-
currentPath =
|
|
7963
|
+
const path7 = line.substring(0, colonIndex).trim();
|
|
7964
|
+
currentPath = path7;
|
|
7783
7965
|
if (line.length > colonIndex + 1) {
|
|
7784
7966
|
const contentStart = line.substring(colonIndex + 1).trim();
|
|
7785
7967
|
if (contentStart) {
|
|
@@ -7799,8 +7981,8 @@ var _FileSystem = class _FileSystem {
|
|
|
7799
7981
|
if (currentPath) {
|
|
7800
7982
|
fileContents[currentPath] = currentContent.join("\n");
|
|
7801
7983
|
}
|
|
7802
|
-
for (const
|
|
7803
|
-
fileContents[
|
|
7984
|
+
for (const path7 in fileContents) {
|
|
7985
|
+
fileContents[path7] = fileContents[path7].replace(/\n+$/, "");
|
|
7804
7986
|
}
|
|
7805
7987
|
}
|
|
7806
7988
|
return {
|
|
@@ -7840,10 +8022,10 @@ var _FileSystem = class _FileSystem {
|
|
|
7840
8022
|
* }
|
|
7841
8023
|
* ```
|
|
7842
8024
|
*/
|
|
7843
|
-
async searchFiles(
|
|
8025
|
+
async searchFiles(path7, pattern, excludePatterns = []) {
|
|
7844
8026
|
try {
|
|
7845
8027
|
const args = {
|
|
7846
|
-
path:
|
|
8028
|
+
path: path7,
|
|
7847
8029
|
pattern
|
|
7848
8030
|
};
|
|
7849
8031
|
if (excludePatterns.length > 0) {
|
|
@@ -7887,7 +8069,7 @@ var _FileSystem = class _FileSystem {
|
|
|
7887
8069
|
* @param mode - Optional: Write mode. One of "overwrite", "append", or "create_new". Default is "overwrite".
|
|
7888
8070
|
* @returns BoolResult with write result and requestId
|
|
7889
8071
|
*/
|
|
7890
|
-
async writeFileChunk(
|
|
8072
|
+
async writeFileChunk(path7, content, mode = "overwrite") {
|
|
7891
8073
|
try {
|
|
7892
8074
|
const validModes = ["overwrite", "append", "create_new"];
|
|
7893
8075
|
if (!validModes.includes(mode)) {
|
|
@@ -7900,7 +8082,7 @@ var _FileSystem = class _FileSystem {
|
|
|
7900
8082
|
};
|
|
7901
8083
|
}
|
|
7902
8084
|
const args = {
|
|
7903
|
-
path:
|
|
8085
|
+
path: path7,
|
|
7904
8086
|
content,
|
|
7905
8087
|
mode
|
|
7906
8088
|
};
|
|
@@ -7977,10 +8159,10 @@ var _FileSystem = class _FileSystem {
|
|
|
7977
8159
|
*
|
|
7978
8160
|
* @see {@link writeFile}, {@link listDirectory}
|
|
7979
8161
|
*/
|
|
7980
|
-
async readFile(
|
|
8162
|
+
async readFile(path7) {
|
|
7981
8163
|
const chunkSize = DEFAULT_CHUNK_SIZE;
|
|
7982
8164
|
try {
|
|
7983
|
-
const fileInfoResult = await this.getFileInfo(
|
|
8165
|
+
const fileInfoResult = await this.getFileInfo(path7);
|
|
7984
8166
|
if (!fileInfoResult.success) {
|
|
7985
8167
|
return {
|
|
7986
8168
|
requestId: fileInfoResult.requestId,
|
|
@@ -7994,7 +8176,7 @@ var _FileSystem = class _FileSystem {
|
|
|
7994
8176
|
requestId: fileInfoResult.requestId,
|
|
7995
8177
|
success: false,
|
|
7996
8178
|
content: "",
|
|
7997
|
-
errorMessage: `Path does not exist or is a directory: ${
|
|
8179
|
+
errorMessage: `Path does not exist or is a directory: ${path7}`
|
|
7998
8180
|
};
|
|
7999
8181
|
}
|
|
8000
8182
|
const fileSize = fileInfoResult.fileInfo.size || 0;
|
|
@@ -8014,7 +8196,7 @@ var _FileSystem = class _FileSystem {
|
|
|
8014
8196
|
length = fileSize - offset;
|
|
8015
8197
|
}
|
|
8016
8198
|
try {
|
|
8017
|
-
const chunkResult = await this.readFileChunk(
|
|
8199
|
+
const chunkResult = await this.readFileChunk(path7, offset, length);
|
|
8018
8200
|
if (!chunkResult.success) {
|
|
8019
8201
|
return chunkResult;
|
|
8020
8202
|
}
|
|
@@ -8100,16 +8282,16 @@ var _FileSystem = class _FileSystem {
|
|
|
8100
8282
|
*
|
|
8101
8283
|
* @see {@link readFile}, {@link listDirectory}
|
|
8102
8284
|
*/
|
|
8103
|
-
async writeFile(
|
|
8285
|
+
async writeFile(path7, content, mode = "overwrite") {
|
|
8104
8286
|
const chunkSize = DEFAULT_CHUNK_SIZE;
|
|
8105
8287
|
try {
|
|
8106
8288
|
const contentLen = content.length;
|
|
8107
8289
|
if (contentLen <= chunkSize) {
|
|
8108
|
-
return await this.writeFileChunk(
|
|
8290
|
+
return await this.writeFileChunk(path7, content, mode);
|
|
8109
8291
|
}
|
|
8110
8292
|
const firstChunkEnd = Math.min(chunkSize, contentLen);
|
|
8111
8293
|
const firstResult = await this.writeFileChunk(
|
|
8112
|
-
|
|
8294
|
+
path7,
|
|
8113
8295
|
content.substring(0, firstChunkEnd),
|
|
8114
8296
|
mode
|
|
8115
8297
|
);
|
|
@@ -8120,7 +8302,7 @@ var _FileSystem = class _FileSystem {
|
|
|
8120
8302
|
for (let offset = firstChunkEnd; offset < contentLen; ) {
|
|
8121
8303
|
const end = Math.min(offset + chunkSize, contentLen);
|
|
8122
8304
|
const chunkResult = await this.writeFileChunk(
|
|
8123
|
-
|
|
8305
|
+
path7,
|
|
8124
8306
|
content.substring(offset, end),
|
|
8125
8307
|
"append"
|
|
8126
8308
|
);
|
|
@@ -8161,9 +8343,9 @@ var _FileSystem = class _FileSystem {
|
|
|
8161
8343
|
* }
|
|
8162
8344
|
* ```
|
|
8163
8345
|
*/
|
|
8164
|
-
async getFileChange(
|
|
8346
|
+
async getFileChange(path7) {
|
|
8165
8347
|
try {
|
|
8166
|
-
const args = { path:
|
|
8348
|
+
const args = { path: path7 };
|
|
8167
8349
|
const result = await this.session.callMcpTool("get_file_change", args);
|
|
8168
8350
|
if (!result.success) {
|
|
8169
8351
|
return {
|
|
@@ -8234,17 +8416,17 @@ var _FileSystem = class _FileSystem {
|
|
|
8234
8416
|
* }
|
|
8235
8417
|
* ```
|
|
8236
8418
|
*/
|
|
8237
|
-
async watchDirectory(
|
|
8238
|
-
console.log(`Starting directory monitoring for: ${
|
|
8419
|
+
async watchDirectory(path7, callback, interval = 500, signal) {
|
|
8420
|
+
console.log(`Starting directory monitoring for: ${path7}`);
|
|
8239
8421
|
console.log(`Polling interval: ${interval} ms`);
|
|
8240
8422
|
const monitor = /* @__PURE__ */ __name(async () => {
|
|
8241
8423
|
while (!signal?.aborted) {
|
|
8242
8424
|
try {
|
|
8243
8425
|
if (this.session._isExpired && this.session._isExpired()) {
|
|
8244
|
-
console.log(`Session expired, stopping directory monitoring for: ${
|
|
8426
|
+
console.log(`Session expired, stopping directory monitoring for: ${path7}`);
|
|
8245
8427
|
break;
|
|
8246
8428
|
}
|
|
8247
|
-
const result = await this.getFileChange(
|
|
8429
|
+
const result = await this.getFileChange(path7);
|
|
8248
8430
|
if (result.success && result.events.length > 0) {
|
|
8249
8431
|
console.log(`Detected ${result.events.length} file changes:`);
|
|
8250
8432
|
for (const event of result.events) {
|
|
@@ -8258,29 +8440,29 @@ var _FileSystem = class _FileSystem {
|
|
|
8258
8440
|
} else if (!result.success) {
|
|
8259
8441
|
const errorMsg = (result.errorMessage || "").toLowerCase();
|
|
8260
8442
|
if (errorMsg.includes("session") && (errorMsg.includes("expired") || errorMsg.includes("invalid"))) {
|
|
8261
|
-
console.log(`Session expired, stopping directory monitoring for: ${
|
|
8443
|
+
console.log(`Session expired, stopping directory monitoring for: ${path7}`);
|
|
8262
8444
|
break;
|
|
8263
8445
|
}
|
|
8264
8446
|
console.error(`Error monitoring directory: ${result.errorMessage}`);
|
|
8265
8447
|
}
|
|
8266
|
-
await new Promise((
|
|
8267
|
-
const timeoutId = setTimeout(
|
|
8448
|
+
await new Promise((resolve3) => {
|
|
8449
|
+
const timeoutId = setTimeout(resolve3, interval);
|
|
8268
8450
|
signal?.addEventListener("abort", () => {
|
|
8269
8451
|
clearTimeout(timeoutId);
|
|
8270
|
-
|
|
8452
|
+
resolve3(void 0);
|
|
8271
8453
|
});
|
|
8272
8454
|
});
|
|
8273
8455
|
} catch (error) {
|
|
8274
8456
|
console.error(`Unexpected error in directory monitoring: ${error}`);
|
|
8275
8457
|
const errorStr = String(error).toLowerCase();
|
|
8276
8458
|
if (errorStr.includes("session") && (errorStr.includes("expired") || errorStr.includes("invalid"))) {
|
|
8277
|
-
console.log(`Session expired, stopping directory monitoring for: ${
|
|
8459
|
+
console.log(`Session expired, stopping directory monitoring for: ${path7}`);
|
|
8278
8460
|
break;
|
|
8279
8461
|
}
|
|
8280
|
-
await new Promise((
|
|
8462
|
+
await new Promise((resolve3) => setTimeout(resolve3, interval));
|
|
8281
8463
|
}
|
|
8282
8464
|
}
|
|
8283
|
-
console.log(`Stopped monitoring directory: ${
|
|
8465
|
+
console.log(`Stopped monitoring directory: ${path7}`);
|
|
8284
8466
|
}, "monitor");
|
|
8285
8467
|
return monitor();
|
|
8286
8468
|
}
|
|
@@ -8868,7 +9050,7 @@ var _Mobile = class _Mobile {
|
|
|
8868
9050
|
async getAdbUrl(adbkeyPub) {
|
|
8869
9051
|
try {
|
|
8870
9052
|
const optionsJson = JSON.stringify({ adbkey_pub: adbkeyPub });
|
|
8871
|
-
const { GetAdbLinkRequest: GetAdbLinkRequest2 } = await import("./model-
|
|
9053
|
+
const { GetAdbLinkRequest: GetAdbLinkRequest2 } = await import("./model-LGWQJWKQ.mjs");
|
|
8872
9054
|
const request = new GetAdbLinkRequest2({
|
|
8873
9055
|
authorization: `Bearer ${this.session.getAPIKey()}`,
|
|
8874
9056
|
sessionId: this.session.sessionId,
|
|
@@ -9298,12 +9480,12 @@ var _Oss = class _Oss {
|
|
|
9298
9480
|
* }
|
|
9299
9481
|
* ```
|
|
9300
9482
|
*/
|
|
9301
|
-
async upload(bucket, object,
|
|
9483
|
+
async upload(bucket, object, path7) {
|
|
9302
9484
|
try {
|
|
9303
9485
|
const args = {
|
|
9304
9486
|
bucket,
|
|
9305
9487
|
object,
|
|
9306
|
-
path:
|
|
9488
|
+
path: path7
|
|
9307
9489
|
};
|
|
9308
9490
|
const result = await this.session.callMcpTool("oss_upload", args);
|
|
9309
9491
|
return {
|
|
@@ -9341,11 +9523,11 @@ var _Oss = class _Oss {
|
|
|
9341
9523
|
* }
|
|
9342
9524
|
* ```
|
|
9343
9525
|
*/
|
|
9344
|
-
async uploadAnonymous(url,
|
|
9526
|
+
async uploadAnonymous(url, path7) {
|
|
9345
9527
|
try {
|
|
9346
9528
|
const args = {
|
|
9347
9529
|
url,
|
|
9348
|
-
path:
|
|
9530
|
+
path: path7
|
|
9349
9531
|
};
|
|
9350
9532
|
const result = await this.session.callMcpTool("oss_upload_annon", args);
|
|
9351
9533
|
return {
|
|
@@ -9385,12 +9567,12 @@ var _Oss = class _Oss {
|
|
|
9385
9567
|
* }
|
|
9386
9568
|
* ```
|
|
9387
9569
|
*/
|
|
9388
|
-
async download(bucket, object,
|
|
9570
|
+
async download(bucket, object, path7) {
|
|
9389
9571
|
try {
|
|
9390
9572
|
const args = {
|
|
9391
9573
|
bucket,
|
|
9392
9574
|
object,
|
|
9393
|
-
path:
|
|
9575
|
+
path: path7
|
|
9394
9576
|
};
|
|
9395
9577
|
const result = await this.session.callMcpTool("oss_download", args);
|
|
9396
9578
|
return {
|
|
@@ -9428,11 +9610,11 @@ var _Oss = class _Oss {
|
|
|
9428
9610
|
* }
|
|
9429
9611
|
* ```
|
|
9430
9612
|
*/
|
|
9431
|
-
async downloadAnonymous(url,
|
|
9613
|
+
async downloadAnonymous(url, path7) {
|
|
9432
9614
|
try {
|
|
9433
9615
|
const args = {
|
|
9434
9616
|
url,
|
|
9435
|
-
path:
|
|
9617
|
+
path: path7
|
|
9436
9618
|
};
|
|
9437
9619
|
const result = await this.session.callMcpTool("oss_download_annon", args);
|
|
9438
9620
|
return {
|
|
@@ -9667,7 +9849,7 @@ var _Session = class _Session {
|
|
|
9667
9849
|
try {
|
|
9668
9850
|
let syncResult;
|
|
9669
9851
|
if (syncContextId) {
|
|
9670
|
-
syncResult = await this.context.sync(syncContextId);
|
|
9852
|
+
syncResult = await this.context.sync(syncContextId, BROWSER_RECORD_PATH);
|
|
9671
9853
|
logInfo(`\u{1F3A5} Synced browser recording context: ${syncContextId}`);
|
|
9672
9854
|
} else {
|
|
9673
9855
|
syncResult = await this.context.sync();
|
|
@@ -10427,80 +10609,374 @@ var _Session = class _Session {
|
|
|
10427
10609
|
};
|
|
10428
10610
|
}
|
|
10429
10611
|
}
|
|
10430
|
-
|
|
10431
|
-
|
|
10432
|
-
|
|
10433
|
-
|
|
10434
|
-
|
|
10435
|
-
|
|
10436
|
-
|
|
10437
|
-
|
|
10438
|
-
|
|
10439
|
-
|
|
10440
|
-
|
|
10441
|
-
|
|
10442
|
-
|
|
10443
|
-
|
|
10444
|
-
|
|
10445
|
-
|
|
10446
|
-
|
|
10447
|
-
|
|
10448
|
-
|
|
10449
|
-
|
|
10450
|
-
|
|
10451
|
-
|
|
10452
|
-
|
|
10453
|
-
|
|
10454
|
-
|
|
10455
|
-
|
|
10456
|
-
|
|
10457
|
-
|
|
10458
|
-
|
|
10459
|
-
|
|
10460
|
-
|
|
10461
|
-
|
|
10462
|
-
|
|
10463
|
-
|
|
10464
|
-
|
|
10465
|
-
|
|
10466
|
-
|
|
10467
|
-
|
|
10468
|
-
|
|
10469
|
-
|
|
10470
|
-
|
|
10612
|
+
/**
|
|
10613
|
+
* Asynchronously pause this session, putting it into a dormant state.
|
|
10614
|
+
*
|
|
10615
|
+
* This method calls the PauseSessionAsync API to initiate the pause operation and then polls
|
|
10616
|
+
* the GetSession API to check the session status until it becomes PAUSED or until timeout is reached.
|
|
10617
|
+
* During the paused state, resource usage and costs are reduced while session state is preserved.
|
|
10618
|
+
*
|
|
10619
|
+
* @param timeout - Timeout in seconds to wait for the session to pause. Defaults to 600 seconds.
|
|
10620
|
+
* @param pollInterval - Interval in seconds between status polls. Defaults to 2.0 seconds.
|
|
10621
|
+
*
|
|
10622
|
+
* @returns Promise resolving to SessionPauseResult containing:
|
|
10623
|
+
* - success: Whether the pause operation succeeded
|
|
10624
|
+
* - requestId: Unique identifier for this API request
|
|
10625
|
+
* - status: Final session status (should be "PAUSED" if successful)
|
|
10626
|
+
* - errorMessage: Error description if pause failed
|
|
10627
|
+
*
|
|
10628
|
+
* @throws Error if the API call fails or network issues occur.
|
|
10629
|
+
*
|
|
10630
|
+
* @example
|
|
10631
|
+
* ```typescript
|
|
10632
|
+
* const agentBay = new AgentBay({ apiKey: 'your_api_key' });
|
|
10633
|
+
* const result = await agentBay.create();
|
|
10634
|
+
* if (result.success) {
|
|
10635
|
+
* const pauseResult = await result.session.pauseAsync();
|
|
10636
|
+
* if (pauseResult.success) {
|
|
10637
|
+
* console.log('Session paused successfully');
|
|
10638
|
+
* }
|
|
10639
|
+
* }
|
|
10640
|
+
* ```
|
|
10641
|
+
*
|
|
10642
|
+
* @remarks
|
|
10643
|
+
* **Behavior:**
|
|
10644
|
+
* - Initiates pause operation through PauseSessionAsync API
|
|
10645
|
+
* - Polls session status until PAUSED state or timeout
|
|
10646
|
+
* - Session state transitions: RUNNING -> PAUSING -> PAUSED
|
|
10647
|
+
* - All session state is preserved during pause
|
|
10648
|
+
*
|
|
10649
|
+
* **Important Notes:**
|
|
10650
|
+
* - Paused sessions cannot perform operations (deletion, task execution, etc.)
|
|
10651
|
+
* - Use {@link resumeAsync} to restore the session to RUNNING state
|
|
10652
|
+
* - During pause, both resource usage and costs are lower
|
|
10653
|
+
* - If timeout is exceeded, returns with success=false
|
|
10654
|
+
*
|
|
10655
|
+
* @see {@link resumeAsync}
|
|
10656
|
+
*/
|
|
10657
|
+
async pauseAsync(timeout = 600, pollInterval = 2) {
|
|
10658
|
+
try {
|
|
10659
|
+
const request = new PauseSessionAsyncRequest({
|
|
10660
|
+
authorization: `Bearer ${this.getAPIKey()}`,
|
|
10661
|
+
sessionId: this.sessionId
|
|
10662
|
+
});
|
|
10663
|
+
logAPICall("PauseSessionAsync", `SessionId=${this.sessionId}`);
|
|
10664
|
+
const response = await this.getClient().pauseSessionAsync(request);
|
|
10665
|
+
const requestId = extractRequestId(response) || "";
|
|
10666
|
+
setRequestId(requestId);
|
|
10667
|
+
const responseMap = response.to_map ? response.to_map() : response;
|
|
10668
|
+
if (!responseMap) {
|
|
10669
|
+
return {
|
|
10670
|
+
requestId: requestId || "",
|
|
10671
|
+
success: false,
|
|
10672
|
+
errorMessage: "Invalid response format"
|
|
10673
|
+
};
|
|
10674
|
+
}
|
|
10675
|
+
const body = responseMap.body;
|
|
10676
|
+
if (!body) {
|
|
10677
|
+
return {
|
|
10678
|
+
requestId: requestId || "",
|
|
10679
|
+
success: false,
|
|
10680
|
+
errorMessage: "Invalid response body"
|
|
10681
|
+
};
|
|
10682
|
+
}
|
|
10683
|
+
const success = body.success !== false;
|
|
10684
|
+
const code = body.code || "";
|
|
10685
|
+
const message = body.message || "";
|
|
10686
|
+
const httpStatusCode = body.httpStatusCode || 0;
|
|
10687
|
+
if (!success) {
|
|
10688
|
+
const errorMessage = `[${code}] ${message}` || "Unknown error";
|
|
10689
|
+
logError("PauseSessionAsync", errorMessage);
|
|
10690
|
+
return {
|
|
10691
|
+
requestId: requestId || "",
|
|
10692
|
+
success: false,
|
|
10693
|
+
errorMessage,
|
|
10694
|
+
code,
|
|
10695
|
+
message,
|
|
10696
|
+
httpStatusCode
|
|
10697
|
+
};
|
|
10698
|
+
}
|
|
10699
|
+
logInfo(`PauseSessionAsync`, `Session ${this.sessionId} pause initiated successfully`);
|
|
10700
|
+
const startTime = Date.now();
|
|
10701
|
+
const maxAttempts = Math.floor(timeout / pollInterval);
|
|
10702
|
+
let attempt = 0;
|
|
10703
|
+
while (attempt < maxAttempts) {
|
|
10704
|
+
const getResult = await this.agentBay.getSession(this.sessionId);
|
|
10705
|
+
if (!getResult.success) {
|
|
10706
|
+
logError(`Failed to get session status: ${getResult.errorMessage}`);
|
|
10707
|
+
return {
|
|
10708
|
+
requestId: getResult.requestId || "",
|
|
10709
|
+
success: false,
|
|
10710
|
+
errorMessage: `Failed to get session status: ${getResult.errorMessage}`
|
|
10711
|
+
};
|
|
10712
|
+
}
|
|
10713
|
+
if (getResult.data) {
|
|
10714
|
+
const status = getResult.data.status || "UNKNOWN";
|
|
10715
|
+
logDebug(`Session status: ${status} (attempt ${attempt + 1}/${maxAttempts})`);
|
|
10716
|
+
if (status === "PAUSED") {
|
|
10717
|
+
const elapsed2 = Date.now() - startTime;
|
|
10718
|
+
logInfo(`Session paused successfully in ${elapsed2}ms`);
|
|
10719
|
+
return {
|
|
10720
|
+
requestId: getResult.requestId || "",
|
|
10721
|
+
success: true,
|
|
10722
|
+
status
|
|
10723
|
+
};
|
|
10724
|
+
} else if (status === "PAUSING") {
|
|
10725
|
+
} else {
|
|
10726
|
+
const elapsed2 = Date.now() - startTime;
|
|
10727
|
+
const errorMessage = `Session pause failed: unexpected state '${status}' after ${elapsed2}ms`;
|
|
10728
|
+
logError(errorMessage);
|
|
10729
|
+
return {
|
|
10730
|
+
requestId: getResult.requestId || "",
|
|
10731
|
+
success: false,
|
|
10732
|
+
errorMessage,
|
|
10733
|
+
status
|
|
10734
|
+
};
|
|
10471
10735
|
}
|
|
10472
10736
|
}
|
|
10473
|
-
|
|
10474
|
-
|
|
10475
|
-
|
|
10476
|
-
}
|
|
10477
|
-
}
|
|
10478
|
-
const envFile = findDotEnvFile();
|
|
10479
|
-
if (envFile) {
|
|
10480
|
-
try {
|
|
10481
|
-
const envConfig = dotenv.parse(fs4.readFileSync(envFile));
|
|
10482
|
-
for (const k in envConfig) {
|
|
10483
|
-
if (!process.env.hasOwnProperty(k)) {
|
|
10484
|
-
process.env[k] = envConfig[k];
|
|
10737
|
+
attempt++;
|
|
10738
|
+
if (attempt < maxAttempts) {
|
|
10739
|
+
await new Promise((resolve3) => setTimeout(resolve3, pollInterval * 1e3));
|
|
10485
10740
|
}
|
|
10486
10741
|
}
|
|
10742
|
+
const elapsed = Date.now() - startTime;
|
|
10743
|
+
const errorMsg = `Session pause timed out after ${elapsed}ms`;
|
|
10744
|
+
logError(errorMsg);
|
|
10745
|
+
return {
|
|
10746
|
+
requestId: "",
|
|
10747
|
+
success: false,
|
|
10748
|
+
errorMessage: errorMsg
|
|
10749
|
+
};
|
|
10487
10750
|
} catch (error) {
|
|
10751
|
+
logError("PauseSessionAsync", error);
|
|
10752
|
+
return {
|
|
10753
|
+
requestId: "",
|
|
10754
|
+
success: false,
|
|
10755
|
+
errorMessage: `Unexpected error pausing session: ${error}`
|
|
10756
|
+
};
|
|
10488
10757
|
}
|
|
10489
10758
|
}
|
|
10490
|
-
|
|
10491
|
-
|
|
10492
|
-
|
|
10493
|
-
|
|
10494
|
-
|
|
10495
|
-
|
|
10496
|
-
|
|
10497
|
-
|
|
10498
|
-
|
|
10499
|
-
|
|
10500
|
-
|
|
10501
|
-
|
|
10502
|
-
|
|
10503
|
-
|
|
10759
|
+
/**
|
|
10760
|
+
* Asynchronously resume this session from a paused state.
|
|
10761
|
+
*
|
|
10762
|
+
* This method calls the ResumeSessionAsync API to initiate the resume operation and then polls
|
|
10763
|
+
* the GetSession API to check the session status until it becomes RUNNING or until timeout is reached.
|
|
10764
|
+
* After resuming, the session restores full functionality and can perform all operations normally.
|
|
10765
|
+
*
|
|
10766
|
+
* @param timeout - Timeout in seconds to wait for the session to resume. Defaults to 600 seconds.
|
|
10767
|
+
* @param pollInterval - Interval in seconds between status polls. Defaults to 2.0 seconds.
|
|
10768
|
+
*
|
|
10769
|
+
* @returns Promise resolving to SessionResumeResult containing:
|
|
10770
|
+
* - success: Whether the resume operation succeeded
|
|
10771
|
+
* - requestId: Unique identifier for this API request
|
|
10772
|
+
* - status: Final session status (should be "RUNNING" if successful)
|
|
10773
|
+
* - errorMessage: Error description if resume failed
|
|
10774
|
+
*
|
|
10775
|
+
* @throws Error if the API call fails or network issues occur.
|
|
10776
|
+
*
|
|
10777
|
+
* @example
|
|
10778
|
+
* ```typescript
|
|
10779
|
+
* const agentBay = new AgentBay({ apiKey: 'your_api_key' });
|
|
10780
|
+
* const result = await agentBay.get('paused_session_id');
|
|
10781
|
+
* if (result.success) {
|
|
10782
|
+
* const resumeResult = await result.session.resumeAsync();
|
|
10783
|
+
* if (resumeResult.success) {
|
|
10784
|
+
* console.log('Session resumed successfully');
|
|
10785
|
+
* }
|
|
10786
|
+
* }
|
|
10787
|
+
* ```
|
|
10788
|
+
*
|
|
10789
|
+
* @remarks
|
|
10790
|
+
* **Behavior:**
|
|
10791
|
+
* - Initiates resume operation through ResumeSessionAsync API
|
|
10792
|
+
* - Polls session status until RUNNING state or timeout
|
|
10793
|
+
* - Session state transitions: PAUSED -> RESUMING -> RUNNING
|
|
10794
|
+
* - All previous session state is restored during resume
|
|
10795
|
+
*
|
|
10796
|
+
* **Important Notes:**
|
|
10797
|
+
* - Only sessions in PAUSED state can be resumed
|
|
10798
|
+
* - After resume, the session can perform all operations normally
|
|
10799
|
+
* - Use {@link pauseAsync} to put a session into PAUSED state
|
|
10800
|
+
* - If timeout is exceeded, returns with success=false
|
|
10801
|
+
*
|
|
10802
|
+
* @see {@link pauseAsync}
|
|
10803
|
+
*/
|
|
10804
|
+
async resumeAsync(timeout = 600, pollInterval = 2) {
|
|
10805
|
+
try {
|
|
10806
|
+
const request = new ResumeSessionAsyncRequest({
|
|
10807
|
+
authorization: `Bearer ${this.getAPIKey()}`,
|
|
10808
|
+
sessionId: this.sessionId
|
|
10809
|
+
});
|
|
10810
|
+
logAPICall("ResumeSessionAsync", `SessionId=${this.sessionId}`);
|
|
10811
|
+
const response = await this.getClient().resumeSessionAsync(request);
|
|
10812
|
+
const requestId = extractRequestId(response) || "";
|
|
10813
|
+
setRequestId(requestId);
|
|
10814
|
+
const responseMap = response.to_map ? response.to_map() : response;
|
|
10815
|
+
if (!responseMap) {
|
|
10816
|
+
return {
|
|
10817
|
+
requestId: requestId || "",
|
|
10818
|
+
success: false,
|
|
10819
|
+
errorMessage: "Invalid response format"
|
|
10820
|
+
};
|
|
10821
|
+
}
|
|
10822
|
+
const body = responseMap.body;
|
|
10823
|
+
if (!body) {
|
|
10824
|
+
return {
|
|
10825
|
+
requestId: requestId || "",
|
|
10826
|
+
success: false,
|
|
10827
|
+
errorMessage: "Invalid response body"
|
|
10828
|
+
};
|
|
10829
|
+
}
|
|
10830
|
+
const success = body.success !== false;
|
|
10831
|
+
const code = body.code || "";
|
|
10832
|
+
const message = body.message || "";
|
|
10833
|
+
const httpStatusCode = body.httpStatusCode || 0;
|
|
10834
|
+
if (!success) {
|
|
10835
|
+
const errorMessage = `[${code}] ${message}` || "Unknown error";
|
|
10836
|
+
logError("ResumeSessionAsync", errorMessage);
|
|
10837
|
+
return {
|
|
10838
|
+
requestId: requestId || "",
|
|
10839
|
+
success: false,
|
|
10840
|
+
errorMessage,
|
|
10841
|
+
code,
|
|
10842
|
+
message,
|
|
10843
|
+
httpStatusCode
|
|
10844
|
+
};
|
|
10845
|
+
}
|
|
10846
|
+
logInfo(`ResumeSessionAsync`, `Session ${this.sessionId} resume initiated successfully`);
|
|
10847
|
+
const startTime = Date.now();
|
|
10848
|
+
const maxAttempts = Math.floor(timeout / pollInterval);
|
|
10849
|
+
let attempt = 0;
|
|
10850
|
+
while (attempt < maxAttempts) {
|
|
10851
|
+
const getResult = await this.agentBay.getSession(this.sessionId);
|
|
10852
|
+
if (!getResult.success) {
|
|
10853
|
+
logError(`Failed to get session status: ${getResult.errorMessage}`);
|
|
10854
|
+
return {
|
|
10855
|
+
requestId: getResult.requestId || "",
|
|
10856
|
+
success: false,
|
|
10857
|
+
errorMessage: `Failed to get session status: ${getResult.errorMessage}`
|
|
10858
|
+
};
|
|
10859
|
+
}
|
|
10860
|
+
if (getResult.data) {
|
|
10861
|
+
const status = getResult.data.status || "UNKNOWN";
|
|
10862
|
+
logDebug(`Session status: ${status} (attempt ${attempt + 1}/${maxAttempts})`);
|
|
10863
|
+
if (status === "RUNNING") {
|
|
10864
|
+
const elapsed2 = Date.now() - startTime;
|
|
10865
|
+
logInfo(`Session resumed successfully in ${elapsed2}ms`);
|
|
10866
|
+
return {
|
|
10867
|
+
requestId: getResult.requestId || "",
|
|
10868
|
+
success: true,
|
|
10869
|
+
status
|
|
10870
|
+
};
|
|
10871
|
+
} else if (status === "RESUMING") {
|
|
10872
|
+
} else {
|
|
10873
|
+
const elapsed2 = Date.now() - startTime;
|
|
10874
|
+
const errorMessage = `Session resume failed: unexpected state '${status}' after ${elapsed2}ms`;
|
|
10875
|
+
logError(errorMessage);
|
|
10876
|
+
return {
|
|
10877
|
+
requestId: getResult.requestId || "",
|
|
10878
|
+
success: false,
|
|
10879
|
+
errorMessage,
|
|
10880
|
+
status
|
|
10881
|
+
};
|
|
10882
|
+
}
|
|
10883
|
+
}
|
|
10884
|
+
attempt++;
|
|
10885
|
+
if (attempt < maxAttempts) {
|
|
10886
|
+
await new Promise((resolve3) => setTimeout(resolve3, pollInterval * 1e3));
|
|
10887
|
+
}
|
|
10888
|
+
}
|
|
10889
|
+
const elapsed = Date.now() - startTime;
|
|
10890
|
+
const errorMsg = `Session resume timed out after ${elapsed}ms`;
|
|
10891
|
+
logError(errorMsg);
|
|
10892
|
+
return {
|
|
10893
|
+
requestId: "",
|
|
10894
|
+
success: false,
|
|
10895
|
+
errorMessage: errorMsg
|
|
10896
|
+
};
|
|
10897
|
+
} catch (error) {
|
|
10898
|
+
logError("ResumeSessionAsync", error);
|
|
10899
|
+
return {
|
|
10900
|
+
requestId: "",
|
|
10901
|
+
success: false,
|
|
10902
|
+
errorMessage: `Unexpected error resuming session: ${error}`
|
|
10903
|
+
};
|
|
10904
|
+
}
|
|
10905
|
+
}
|
|
10906
|
+
};
|
|
10907
|
+
__name(_Session, "Session");
|
|
10908
|
+
var Session = _Session;
|
|
10909
|
+
|
|
10910
|
+
// src/agent-bay.ts
|
|
10911
|
+
var BROWSER_DATA_PATH2 = "/tmp/agentbay_browser";
|
|
10912
|
+
function defaultConfig() {
|
|
10913
|
+
return {
|
|
10914
|
+
endpoint: "wuyingai.cn-shanghai.aliyuncs.com",
|
|
10915
|
+
timeout_ms: 6e4
|
|
10916
|
+
};
|
|
10917
|
+
}
|
|
10918
|
+
__name(defaultConfig, "defaultConfig");
|
|
10919
|
+
function findDotEnvFile2(startPath) {
|
|
10920
|
+
const currentPath = startPath ? path5.resolve(startPath) : process.cwd();
|
|
10921
|
+
let searchPath = currentPath;
|
|
10922
|
+
while (searchPath !== path5.dirname(searchPath)) {
|
|
10923
|
+
const envFile = path5.join(searchPath, ".env");
|
|
10924
|
+
if (fs5.existsSync(envFile)) {
|
|
10925
|
+
return envFile;
|
|
10926
|
+
}
|
|
10927
|
+
const gitDir = path5.join(searchPath, ".git");
|
|
10928
|
+
if (fs5.existsSync(gitDir)) {
|
|
10929
|
+
}
|
|
10930
|
+
searchPath = path5.dirname(searchPath);
|
|
10931
|
+
}
|
|
10932
|
+
const rootEnv = path5.join(searchPath, ".env");
|
|
10933
|
+
if (fs5.existsSync(rootEnv)) {
|
|
10934
|
+
return rootEnv;
|
|
10935
|
+
}
|
|
10936
|
+
return null;
|
|
10937
|
+
}
|
|
10938
|
+
__name(findDotEnvFile2, "findDotEnvFile");
|
|
10939
|
+
function loadDotEnvWithFallback2(customEnvPath) {
|
|
10940
|
+
if (customEnvPath) {
|
|
10941
|
+
if (fs5.existsSync(customEnvPath)) {
|
|
10942
|
+
try {
|
|
10943
|
+
const envConfig = dotenv2.parse(fs5.readFileSync(customEnvPath));
|
|
10944
|
+
for (const k in envConfig) {
|
|
10945
|
+
if (!process.env.hasOwnProperty(k)) {
|
|
10946
|
+
process.env[k] = envConfig[k];
|
|
10947
|
+
}
|
|
10948
|
+
}
|
|
10949
|
+
return;
|
|
10950
|
+
} catch (error) {
|
|
10951
|
+
}
|
|
10952
|
+
}
|
|
10953
|
+
}
|
|
10954
|
+
const envFile = findDotEnvFile2();
|
|
10955
|
+
if (envFile) {
|
|
10956
|
+
try {
|
|
10957
|
+
const envConfig = dotenv2.parse(fs5.readFileSync(envFile));
|
|
10958
|
+
for (const k in envConfig) {
|
|
10959
|
+
if (!process.env.hasOwnProperty(k)) {
|
|
10960
|
+
process.env[k] = envConfig[k];
|
|
10961
|
+
}
|
|
10962
|
+
}
|
|
10963
|
+
} catch (error) {
|
|
10964
|
+
}
|
|
10965
|
+
}
|
|
10966
|
+
}
|
|
10967
|
+
__name(loadDotEnvWithFallback2, "loadDotEnvWithFallback");
|
|
10968
|
+
function loadConfig(customConfig, customEnvPath) {
|
|
10969
|
+
if (customConfig) {
|
|
10970
|
+
return customConfig;
|
|
10971
|
+
}
|
|
10972
|
+
const config = defaultConfig();
|
|
10973
|
+
try {
|
|
10974
|
+
loadDotEnvWithFallback2(customEnvPath);
|
|
10975
|
+
} catch (error) {
|
|
10976
|
+
}
|
|
10977
|
+
if (process.env.AGENTBAY_ENDPOINT) {
|
|
10978
|
+
config.endpoint = process.env.AGENTBAY_ENDPOINT;
|
|
10979
|
+
}
|
|
10504
10980
|
if (process.env.AGENTBAY_TIMEOUT_MS) {
|
|
10505
10981
|
const timeout = parseInt(process.env.AGENTBAY_TIMEOUT_MS, 10);
|
|
10506
10982
|
if (!isNaN(timeout) && timeout > 0) {
|
|
@@ -10530,9 +11006,8 @@ var _AgentBay = class _AgentBay {
|
|
|
10530
11006
|
* @param options.envFile - Custom path to .env file. If not provided, will search upward from current directory.
|
|
10531
11007
|
*/
|
|
10532
11008
|
constructor(options = {}) {
|
|
10533
|
-
this.sessions = /* @__PURE__ */ new Map();
|
|
10534
11009
|
this.fileTransferContext = null;
|
|
10535
|
-
|
|
11010
|
+
loadDotEnvWithFallback2(options.envFile);
|
|
10536
11011
|
this.apiKey = options.apiKey || process.env.AGENTBAY_API_KEY || "";
|
|
10537
11012
|
if (!this.apiKey) {
|
|
10538
11013
|
throw new AuthenticationError(
|
|
@@ -10555,6 +11030,59 @@ var _AgentBay = class _AgentBay {
|
|
|
10555
11030
|
throw new AuthenticationError(`Failed to constructor: ${error}`);
|
|
10556
11031
|
}
|
|
10557
11032
|
}
|
|
11033
|
+
/**
|
|
11034
|
+
* Wait for mobile simulate command to complete.
|
|
11035
|
+
*
|
|
11036
|
+
* @param session - The session to wait for mobile simulate
|
|
11037
|
+
* @param mobileSimPath - The dev info path to the mobile simulate
|
|
11038
|
+
* @param mobileSimMode - The mode of the mobile simulate. If not provided, will use the default mode.
|
|
11039
|
+
*/
|
|
11040
|
+
async _waitForMobileSimulate(session, mobileSimPath, mobileSimMode) {
|
|
11041
|
+
log("\u23F3 Mobile simulate: Waiting for completion");
|
|
11042
|
+
if (!session.mobile) {
|
|
11043
|
+
logInfo("Mobile module not found in session, skipping mobile simulate");
|
|
11044
|
+
return;
|
|
11045
|
+
}
|
|
11046
|
+
if (!session.command) {
|
|
11047
|
+
logInfo("Command module not found in session, skipping mobile simulate");
|
|
11048
|
+
return;
|
|
11049
|
+
}
|
|
11050
|
+
if (!mobileSimPath) {
|
|
11051
|
+
logInfo("Mobile simulate path is empty, skipping mobile simulate");
|
|
11052
|
+
return;
|
|
11053
|
+
}
|
|
11054
|
+
try {
|
|
11055
|
+
const startTime = Date.now();
|
|
11056
|
+
const devInfoFilePath = `${mobileSimPath}/dev_info.json`;
|
|
11057
|
+
let wyaApplyOption = "";
|
|
11058
|
+
if (!mobileSimMode || mobileSimMode === "PropertiesOnly") {
|
|
11059
|
+
wyaApplyOption = "";
|
|
11060
|
+
} else if (mobileSimMode === "SensorsOnly") {
|
|
11061
|
+
wyaApplyOption = "-sensors";
|
|
11062
|
+
} else if (mobileSimMode === "PackagesOnly") {
|
|
11063
|
+
wyaApplyOption = "-packages";
|
|
11064
|
+
} else if (mobileSimMode === "ServicesOnly") {
|
|
11065
|
+
wyaApplyOption = "-services";
|
|
11066
|
+
} else if (mobileSimMode === "All") {
|
|
11067
|
+
wyaApplyOption = "-all";
|
|
11068
|
+
}
|
|
11069
|
+
const command = `chmod -R a+rwx ${mobileSimPath}; wya apply ${wyaApplyOption} ${devInfoFilePath}`.trim();
|
|
11070
|
+
logInfo(`\u2139\uFE0F \u23F3 Waiting for mobile simulate completion, command: ${command}`);
|
|
11071
|
+
const cmdResult = await session.command.executeCommand(command);
|
|
11072
|
+
if (cmdResult.success) {
|
|
11073
|
+
const endTime = Date.now();
|
|
11074
|
+
const consumeTime = (endTime - startTime) / 1e3;
|
|
11075
|
+
log(`\u2705 Mobile simulate completed with mode: ${mobileSimMode || "PropertiesOnly"}, duration: ${consumeTime.toFixed(2)} seconds`);
|
|
11076
|
+
if (cmdResult.output) {
|
|
11077
|
+
log(` Output: ${cmdResult.output.trim()}`);
|
|
11078
|
+
}
|
|
11079
|
+
} else {
|
|
11080
|
+
logInfo(`Failed to execute mobile simulate command: ${cmdResult.errorMessage}`);
|
|
11081
|
+
}
|
|
11082
|
+
} catch (error) {
|
|
11083
|
+
logInfo(`Error executing mobile simulate command: ${error}`);
|
|
11084
|
+
}
|
|
11085
|
+
}
|
|
10558
11086
|
/**
|
|
10559
11087
|
* Update browser replay context with AppInstanceId from response data.
|
|
10560
11088
|
*
|
|
@@ -10635,13 +11163,28 @@ var _AgentBay = class _AgentBay {
|
|
|
10635
11163
|
async create(params = {}) {
|
|
10636
11164
|
try {
|
|
10637
11165
|
logDebug(`default context syncs length: ${params.contextSync?.length}`);
|
|
11166
|
+
if (params.extraConfigs?.mobile?.simulateConfig) {
|
|
11167
|
+
const mobileSimContextId = params.extraConfigs.mobile.simulateConfig.simulatedContextId;
|
|
11168
|
+
if (mobileSimContextId) {
|
|
11169
|
+
const mobileSimContextSync = new ContextSync(
|
|
11170
|
+
mobileSimContextId,
|
|
11171
|
+
"/data/agentbay_mobile_info"
|
|
11172
|
+
);
|
|
11173
|
+
if (!params.contextSync) {
|
|
11174
|
+
params.contextSync = [];
|
|
11175
|
+
}
|
|
11176
|
+
logInfo(`Adding context sync for mobile simulate: ${JSON.stringify(mobileSimContextSync)}`);
|
|
11177
|
+
params.contextSync.push(mobileSimContextSync);
|
|
11178
|
+
}
|
|
11179
|
+
}
|
|
11180
|
+
logDebug(`Origin context syncs length: ${params.contextSync?.length}`);
|
|
10638
11181
|
const contextName = `file-transfer-context-${Date.now()}`;
|
|
10639
11182
|
const contextResult = await this.context.get(contextName, true);
|
|
10640
11183
|
if (contextResult.success && contextResult.context) {
|
|
10641
11184
|
this.fileTransferContext = contextResult.context;
|
|
10642
11185
|
const fileTransferContextSync = new ContextSync(
|
|
10643
11186
|
contextResult.context.id,
|
|
10644
|
-
"/
|
|
11187
|
+
"/tmp/file-transfer"
|
|
10645
11188
|
);
|
|
10646
11189
|
if (!params.contextSync) {
|
|
10647
11190
|
params.contextSync = [];
|
|
@@ -10666,6 +11209,9 @@ var _AgentBay = class _AgentBay {
|
|
|
10666
11209
|
}
|
|
10667
11210
|
request.vpcResource = params.isVpc || false;
|
|
10668
11211
|
let needsContextSync = false;
|
|
11212
|
+
let needsMobileSim = false;
|
|
11213
|
+
let mobileSimMode = void 0;
|
|
11214
|
+
let mobileSimPath = void 0;
|
|
10669
11215
|
if (params.contextSync && params.contextSync.length > 0) {
|
|
10670
11216
|
const persistenceDataList = [];
|
|
10671
11217
|
for (const contextSync of params.contextSync) {
|
|
@@ -10703,7 +11249,7 @@ var _AgentBay = class _AgentBay {
|
|
|
10703
11249
|
}
|
|
10704
11250
|
let recordContextId = "";
|
|
10705
11251
|
if (params.enableBrowserReplay) {
|
|
10706
|
-
const recordPath =
|
|
11252
|
+
const recordPath = BROWSER_RECORD_PATH;
|
|
10707
11253
|
const recordContextName = generateRandomContextName();
|
|
10708
11254
|
const result = await this.context.get(recordContextName, true);
|
|
10709
11255
|
recordContextId = result.success ? result.contextId : "";
|
|
@@ -10718,6 +11264,15 @@ var _AgentBay = class _AgentBay {
|
|
|
10718
11264
|
}
|
|
10719
11265
|
if (params.extraConfigs) {
|
|
10720
11266
|
request.extraConfigs = JSON.stringify(params.extraConfigs);
|
|
11267
|
+
if (params.extraConfigs.mobile?.simulateConfig?.simulate) {
|
|
11268
|
+
mobileSimPath = params.extraConfigs.mobile.simulateConfig.simulatePath;
|
|
11269
|
+
if (!mobileSimPath) {
|
|
11270
|
+
logInfo("mobile_sim_path is not set now, skip mobile simulate operation");
|
|
11271
|
+
} else {
|
|
11272
|
+
needsMobileSim = true;
|
|
11273
|
+
mobileSimMode = params.extraConfigs.mobile.simulateConfig.simulateMode;
|
|
11274
|
+
}
|
|
11275
|
+
}
|
|
10721
11276
|
}
|
|
10722
11277
|
logAPICall("CreateMcpSession", {
|
|
10723
11278
|
labels: params.labels,
|
|
@@ -10835,7 +11390,6 @@ var _AgentBay = class _AgentBay {
|
|
|
10835
11390
|
session.fileTransferContextId = this.fileTransferContext ? this.fileTransferContext.id : null;
|
|
10836
11391
|
session.recordContextId = recordContextId || null;
|
|
10837
11392
|
session.imageId = params.imageId;
|
|
10838
|
-
this.sessions.set(session.sessionId, session);
|
|
10839
11393
|
if (params.extraConfigs && params.extraConfigs.mobile) {
|
|
10840
11394
|
log("Applying mobile configuration...");
|
|
10841
11395
|
try {
|
|
@@ -10890,13 +11444,16 @@ var _AgentBay = class _AgentBay {
|
|
|
10890
11444
|
break;
|
|
10891
11445
|
}
|
|
10892
11446
|
logDebug(`Waiting for context synchronization, attempt ${retry + 1}/${maxRetries}`);
|
|
10893
|
-
await new Promise((
|
|
11447
|
+
await new Promise((resolve3) => setTimeout(resolve3, retryInterval));
|
|
10894
11448
|
} catch (error) {
|
|
10895
11449
|
logError(`Error checking context status on attempt ${retry + 1}: ${error}`);
|
|
10896
|
-
await new Promise((
|
|
11450
|
+
await new Promise((resolve3) => setTimeout(resolve3, retryInterval));
|
|
10897
11451
|
}
|
|
10898
11452
|
}
|
|
10899
11453
|
}
|
|
11454
|
+
if (needsMobileSim && mobileSimPath) {
|
|
11455
|
+
await this._waitForMobileSimulate(session, mobileSimPath, mobileSimMode);
|
|
11456
|
+
}
|
|
10900
11457
|
return {
|
|
10901
11458
|
requestId,
|
|
10902
11459
|
success: true,
|
|
@@ -11082,7 +11639,6 @@ var _AgentBay = class _AgentBay {
|
|
|
11082
11639
|
deleteResult.success,
|
|
11083
11640
|
{ sessionId: session.sessionId }
|
|
11084
11641
|
);
|
|
11085
|
-
this.sessions.delete(session.sessionId);
|
|
11086
11642
|
return deleteResult;
|
|
11087
11643
|
} catch (error) {
|
|
11088
11644
|
logError("Error deleting session:", error);
|
|
@@ -11093,27 +11649,6 @@ var _AgentBay = class _AgentBay {
|
|
|
11093
11649
|
};
|
|
11094
11650
|
}
|
|
11095
11651
|
}
|
|
11096
|
-
/**
|
|
11097
|
-
* Remove a session from the internal session cache.
|
|
11098
|
-
*
|
|
11099
|
-
* This is an internal utility method that removes a session reference from the AgentBay client's
|
|
11100
|
-
* session cache without actually deleting the session from the cloud. Use this when you need to
|
|
11101
|
-
* clean up local references to a session that was deleted externally or no longer needed.
|
|
11102
|
-
*
|
|
11103
|
-
* @param sessionId - The ID of the session to remove from the cache.
|
|
11104
|
-
*
|
|
11105
|
-
* @internal
|
|
11106
|
-
*
|
|
11107
|
-
* @remarks
|
|
11108
|
-
* **Note:** This method only removes the session from the local cache. It does not delete the
|
|
11109
|
-
* session from the cloud. To delete a session from the cloud, use {@link delete} or
|
|
11110
|
-
* {@link Session.delete}.
|
|
11111
|
-
*
|
|
11112
|
-
* @see {@link delete}, {@link Session.delete}
|
|
11113
|
-
*/
|
|
11114
|
-
removeSession(sessionId) {
|
|
11115
|
-
this.sessions.delete(sessionId);
|
|
11116
|
-
}
|
|
11117
11652
|
/**
|
|
11118
11653
|
* Get session information by session ID.
|
|
11119
11654
|
*
|
|
@@ -11156,6 +11691,18 @@ var _AgentBay = class _AgentBay {
|
|
|
11156
11691
|
errorMessage: ""
|
|
11157
11692
|
};
|
|
11158
11693
|
if (body?.data) {
|
|
11694
|
+
const contextsList = body.data.contexts || [];
|
|
11695
|
+
const contexts = [];
|
|
11696
|
+
if (Array.isArray(contextsList)) {
|
|
11697
|
+
for (const ctx of contextsList) {
|
|
11698
|
+
if (ctx && typeof ctx === "object" && ctx.name && ctx.id) {
|
|
11699
|
+
contexts.push({
|
|
11700
|
+
name: ctx.name,
|
|
11701
|
+
id: ctx.id
|
|
11702
|
+
});
|
|
11703
|
+
}
|
|
11704
|
+
}
|
|
11705
|
+
}
|
|
11159
11706
|
result.data = {
|
|
11160
11707
|
appInstanceId: body.data.appInstanceId || "",
|
|
11161
11708
|
resourceId: body.data.resourceId || "",
|
|
@@ -11165,7 +11712,9 @@ var _AgentBay = class _AgentBay {
|
|
|
11165
11712
|
networkInterfaceIp: body.data.networkInterfaceIp || "",
|
|
11166
11713
|
token: body.data.token || "",
|
|
11167
11714
|
vpcResource: body.data.vpcResource || false,
|
|
11168
|
-
resourceUrl: body.data.resourceUrl || ""
|
|
11715
|
+
resourceUrl: body.data.resourceUrl || "",
|
|
11716
|
+
status: body.data.status || "",
|
|
11717
|
+
contexts: contexts.length > 0 ? contexts : void 0
|
|
11169
11718
|
};
|
|
11170
11719
|
logAPIResponseWithDetails(
|
|
11171
11720
|
"GetSession",
|
|
@@ -11249,13 +11798,40 @@ var _AgentBay = class _AgentBay {
|
|
|
11249
11798
|
session.token = getResult.data.token;
|
|
11250
11799
|
session.resourceUrl = getResult.data.resourceUrl;
|
|
11251
11800
|
}
|
|
11252
|
-
|
|
11253
|
-
|
|
11254
|
-
|
|
11255
|
-
|
|
11256
|
-
|
|
11801
|
+
if (getResult.data && getResult.data.contexts && getResult.data.contexts.length > 0) {
|
|
11802
|
+
const contexts = getResult.data.contexts;
|
|
11803
|
+
const fileTransferContexts = contexts.filter(
|
|
11804
|
+
(ctx) => ctx.name && ctx.name.startsWith("file-transfer-context-")
|
|
11805
|
+
);
|
|
11806
|
+
if (fileTransferContexts.length === 0) {
|
|
11807
|
+
const availableContexts = contexts.map((ctx) => ctx.name || "unknown");
|
|
11808
|
+
logWarn(
|
|
11809
|
+
`\u26A0\uFE0F No file-transfer-context- found in contexts list for session ${sessionId}. Available contexts: ${availableContexts.join(", ")}`
|
|
11810
|
+
);
|
|
11811
|
+
session.fileTransferContextId = null;
|
|
11812
|
+
} else if (fileTransferContexts.length === 1) {
|
|
11813
|
+
const contextId = fileTransferContexts[0].id;
|
|
11814
|
+
if (contextId) {
|
|
11815
|
+
session.fileTransferContextId = contextId;
|
|
11816
|
+
logInfo(`\u{1F4C1} Found file transfer context for recovered session: ${contextId}`);
|
|
11817
|
+
} else {
|
|
11818
|
+
logWarn(
|
|
11819
|
+
`\u26A0\uFE0F File transfer context found but missing 'id' field: ${JSON.stringify(fileTransferContexts[0])}`
|
|
11820
|
+
);
|
|
11821
|
+
session.fileTransferContextId = null;
|
|
11822
|
+
}
|
|
11823
|
+
} else {
|
|
11824
|
+
const contextNames = fileTransferContexts.map((ctx) => ctx.name || "unknown");
|
|
11825
|
+
logWarn(
|
|
11826
|
+
`\u26A0\uFE0F Multiple file-transfer-context- found in contexts list for session ${sessionId}. Found ${fileTransferContexts.length} contexts: ${contextNames.join(", ")}. Not setting fileTransferContextId.`
|
|
11827
|
+
);
|
|
11828
|
+
session.fileTransferContextId = null;
|
|
11829
|
+
}
|
|
11257
11830
|
} else {
|
|
11258
|
-
|
|
11831
|
+
logWarn(
|
|
11832
|
+
`\u26A0\uFE0F No contexts list found in GetSession response for session ${sessionId}. fileTransferContextId will remain null.`
|
|
11833
|
+
);
|
|
11834
|
+
session.fileTransferContextId = null;
|
|
11259
11835
|
}
|
|
11260
11836
|
return {
|
|
11261
11837
|
requestId: getResult.requestId,
|
|
@@ -11294,6 +11870,88 @@ var _AgentBay = class _AgentBay {
|
|
|
11294
11870
|
getAPIKey() {
|
|
11295
11871
|
return this.apiKey;
|
|
11296
11872
|
}
|
|
11873
|
+
/**
|
|
11874
|
+
* Asynchronously pause a session, putting it into a dormant state.
|
|
11875
|
+
*
|
|
11876
|
+
* This method directly calls the PauseSessionAsync API without waiting for the session
|
|
11877
|
+
* to reach the PAUSED state.
|
|
11878
|
+
*
|
|
11879
|
+
* @param session - The session to pause.
|
|
11880
|
+
* @param timeout - Timeout in seconds to wait for the session to pause. Defaults to 600 seconds.
|
|
11881
|
+
* @param pollInterval - Interval in seconds between status polls. Defaults to 2.0 seconds.
|
|
11882
|
+
* @returns SessionPauseResult indicating success or failure and request ID
|
|
11883
|
+
*
|
|
11884
|
+
* @example
|
|
11885
|
+
* ```typescript
|
|
11886
|
+
* const agentBay = new AgentBay({ apiKey: 'your_api_key' });
|
|
11887
|
+
* const session = (await agentBay.create()).session;
|
|
11888
|
+
* const pauseResult = await agentBay.pauseAsync(session);
|
|
11889
|
+
* await agentBay.resumeAsync(session);
|
|
11890
|
+
* await session.delete();
|
|
11891
|
+
* ```
|
|
11892
|
+
*
|
|
11893
|
+
* @remarks
|
|
11894
|
+
* **Behavior:**
|
|
11895
|
+
* - This method does not wait for the session to reach the PAUSED state
|
|
11896
|
+
* - It only submits the pause request to the API
|
|
11897
|
+
* - The session state transitions from RUNNING -> PAUSING -> PAUSED
|
|
11898
|
+
* - Paused sessions consume fewer resources but maintain their state
|
|
11899
|
+
*
|
|
11900
|
+
* @see {@link resumeAsync}, {@link Session.pauseAsync}
|
|
11901
|
+
*/
|
|
11902
|
+
async pauseAsync(session, timeout = 600, pollInterval = 2) {
|
|
11903
|
+
try {
|
|
11904
|
+
return await session.pauseAsync(timeout, pollInterval);
|
|
11905
|
+
} catch (error) {
|
|
11906
|
+
logError("Error calling pause session async:", error);
|
|
11907
|
+
return {
|
|
11908
|
+
requestId: "",
|
|
11909
|
+
success: false,
|
|
11910
|
+
errorMessage: `Failed to pause session ${session.sessionId}: ${error}`
|
|
11911
|
+
};
|
|
11912
|
+
}
|
|
11913
|
+
}
|
|
11914
|
+
/**
|
|
11915
|
+
* Asynchronously resume a session from a paused state.
|
|
11916
|
+
*
|
|
11917
|
+
* This method directly calls the ResumeSessionAsync API without waiting for the session
|
|
11918
|
+
* to reach the RUNNING state.
|
|
11919
|
+
*
|
|
11920
|
+
* @param session - The session to resume.
|
|
11921
|
+
* @param timeout - Timeout in seconds to wait for the session to resume. Defaults to 600 seconds.
|
|
11922
|
+
* @param pollInterval - Interval in seconds between status polls. Defaults to 2.0 seconds.
|
|
11923
|
+
* @returns SessionResumeResult indicating success or failure and request ID
|
|
11924
|
+
*
|
|
11925
|
+
* @example
|
|
11926
|
+
* ```typescript
|
|
11927
|
+
* const agentBay = new AgentBay({ apiKey: 'your_api_key' });
|
|
11928
|
+
* const session = (await agentBay.create()).session;
|
|
11929
|
+
* await agentBay.pauseAsync(session);
|
|
11930
|
+
* const resumeResult = await agentBay.resumeAsync(session);
|
|
11931
|
+
* await session.delete();
|
|
11932
|
+
* ```
|
|
11933
|
+
*
|
|
11934
|
+
* @remarks
|
|
11935
|
+
* **Behavior:**
|
|
11936
|
+
* - This method does not wait for the session to reach the RUNNING state
|
|
11937
|
+
* - It only submits the resume request to the API
|
|
11938
|
+
* - The session state transitions from PAUSED -> RESUMING -> RUNNING
|
|
11939
|
+
* - Only sessions in PAUSED state can be resumed
|
|
11940
|
+
*
|
|
11941
|
+
* @see {@link pauseAsync}, {@link Session.resumeAsync}
|
|
11942
|
+
*/
|
|
11943
|
+
async resumeAsync(session, timeout = 600, pollInterval = 2) {
|
|
11944
|
+
try {
|
|
11945
|
+
return await session.resumeAsync(timeout, pollInterval);
|
|
11946
|
+
} catch (error) {
|
|
11947
|
+
logError("Error calling resume session async:", error);
|
|
11948
|
+
return {
|
|
11949
|
+
requestId: "",
|
|
11950
|
+
success: false,
|
|
11951
|
+
errorMessage: `Failed to resume session ${session.sessionId}: ${error}`
|
|
11952
|
+
};
|
|
11953
|
+
}
|
|
11954
|
+
}
|
|
11297
11955
|
};
|
|
11298
11956
|
__name(_AgentBay, "AgentBay");
|
|
11299
11957
|
var AgentBay = _AgentBay;
|
|
@@ -11303,8 +11961,8 @@ init_esm_shims();
|
|
|
11303
11961
|
|
|
11304
11962
|
// src/extension.ts
|
|
11305
11963
|
init_esm_shims();
|
|
11306
|
-
import * as
|
|
11307
|
-
import * as
|
|
11964
|
+
import * as fs6 from "fs";
|
|
11965
|
+
import * as path6 from "path";
|
|
11308
11966
|
import * as crypto from "crypto";
|
|
11309
11967
|
import fetch3 from "node-fetch";
|
|
11310
11968
|
var EXTENSIONS_BASE_PATH = "/tmp/extensions";
|
|
@@ -11456,7 +12114,7 @@ var _ExtensionsService = class _ExtensionsService {
|
|
|
11456
12114
|
throw new AgentBayError(`Failed to get upload URL: ${urlResult.url || "No URL returned"}`);
|
|
11457
12115
|
}
|
|
11458
12116
|
const preSignedUrl = urlResult.url;
|
|
11459
|
-
const fileBuffer =
|
|
12117
|
+
const fileBuffer = fs6.readFileSync(localPath);
|
|
11460
12118
|
const response = await fetch3(preSignedUrl, {
|
|
11461
12119
|
method: "PUT",
|
|
11462
12120
|
body: fileBuffer
|
|
@@ -11539,15 +12197,15 @@ var _ExtensionsService = class _ExtensionsService {
|
|
|
11539
12197
|
*/
|
|
11540
12198
|
async create(localPath) {
|
|
11541
12199
|
await this._ensureInitialized();
|
|
11542
|
-
if (!
|
|
12200
|
+
if (!fs6.existsSync(localPath)) {
|
|
11543
12201
|
throw new Error(`The specified local file was not found: ${localPath}`);
|
|
11544
12202
|
}
|
|
11545
|
-
const fileExtension =
|
|
12203
|
+
const fileExtension = path6.extname(localPath).toLowerCase();
|
|
11546
12204
|
if (fileExtension !== ".zip") {
|
|
11547
12205
|
throw new Error(`Unsupported plugin format '${fileExtension}'. Only ZIP format (.zip) is supported.`);
|
|
11548
12206
|
}
|
|
11549
12207
|
const extensionId = `ext_${crypto.randomBytes(16).toString("hex")}${fileExtension}`;
|
|
11550
|
-
const extensionName =
|
|
12208
|
+
const extensionName = path6.basename(localPath);
|
|
11551
12209
|
const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;
|
|
11552
12210
|
await this._uploadToCloud(localPath, remotePath);
|
|
11553
12211
|
return new Extension(extensionId, extensionName);
|
|
@@ -11574,7 +12232,7 @@ var _ExtensionsService = class _ExtensionsService {
|
|
|
11574
12232
|
*/
|
|
11575
12233
|
async update(extensionId, newLocalPath) {
|
|
11576
12234
|
await this._ensureInitialized();
|
|
11577
|
-
if (!
|
|
12235
|
+
if (!fs6.existsSync(newLocalPath)) {
|
|
11578
12236
|
throw new Error(`The specified new local file was not found: ${newLocalPath}`);
|
|
11579
12237
|
}
|
|
11580
12238
|
const existingExtensions = await this.list();
|
|
@@ -11584,7 +12242,7 @@ var _ExtensionsService = class _ExtensionsService {
|
|
|
11584
12242
|
}
|
|
11585
12243
|
const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;
|
|
11586
12244
|
await this._uploadToCloud(newLocalPath, remotePath);
|
|
11587
|
-
return new Extension(extensionId,
|
|
12245
|
+
return new Extension(extensionId, path6.basename(newLocalPath));
|
|
11588
12246
|
}
|
|
11589
12247
|
/**
|
|
11590
12248
|
* Gets detailed information about a specific browser extension.
|
|
@@ -11709,21 +12367,20 @@ var _ExtensionsService = class _ExtensionsService {
|
|
|
11709
12367
|
__name(_ExtensionsService, "ExtensionsService");
|
|
11710
12368
|
var ExtensionsService = _ExtensionsService;
|
|
11711
12369
|
|
|
11712
|
-
// src/
|
|
11713
|
-
init_esm_shims();
|
|
11714
|
-
|
|
11715
|
-
// src/types/list-session-params.ts
|
|
12370
|
+
// src/mobile-simulate.ts
|
|
11716
12371
|
init_esm_shims();
|
|
11717
|
-
|
|
11718
|
-
return {
|
|
11719
|
-
maxResults: 10,
|
|
11720
|
-
labels
|
|
11721
|
-
};
|
|
11722
|
-
}
|
|
11723
|
-
__name(createListSessionParams, "createListSessionParams");
|
|
12372
|
+
import fetch4 from "node-fetch";
|
|
11724
12373
|
|
|
11725
12374
|
// src/types/extra-configs.ts
|
|
11726
12375
|
init_esm_shims();
|
|
12376
|
+
var MobileSimulateMode = /* @__PURE__ */ ((MobileSimulateMode2) => {
|
|
12377
|
+
MobileSimulateMode2["PropertiesOnly"] = "PropertiesOnly";
|
|
12378
|
+
MobileSimulateMode2["SensorsOnly"] = "SensorsOnly";
|
|
12379
|
+
MobileSimulateMode2["PackagesOnly"] = "PackagesOnly";
|
|
12380
|
+
MobileSimulateMode2["ServicesOnly"] = "ServicesOnly";
|
|
12381
|
+
MobileSimulateMode2["All"] = "All";
|
|
12382
|
+
return MobileSimulateMode2;
|
|
12383
|
+
})(MobileSimulateMode || {});
|
|
11727
12384
|
function extraConfigsToJSON(extraConfigs) {
|
|
11728
12385
|
if (!extraConfigs) {
|
|
11729
12386
|
return "";
|
|
@@ -11759,6 +12416,21 @@ function validateAppManagerRule(rule) {
|
|
|
11759
12416
|
}
|
|
11760
12417
|
}
|
|
11761
12418
|
__name(validateAppManagerRule, "validateAppManagerRule");
|
|
12419
|
+
function validateMobileSimulateConfig(config) {
|
|
12420
|
+
if (typeof config.simulate !== "boolean") {
|
|
12421
|
+
throw new Error("MobileSimulateConfig simulate must be a boolean");
|
|
12422
|
+
}
|
|
12423
|
+
if (config.simulateMode !== void 0) {
|
|
12424
|
+
const validModes = Object.values(MobileSimulateMode);
|
|
12425
|
+
if (!validModes.includes(config.simulateMode)) {
|
|
12426
|
+
throw new Error(`Invalid simulateMode: ${config.simulateMode}. Must be one of: ${validModes.join(", ")}`);
|
|
12427
|
+
}
|
|
12428
|
+
}
|
|
12429
|
+
if (config.simulatedContextId !== void 0 && typeof config.simulatedContextId !== "string") {
|
|
12430
|
+
throw new Error("MobileSimulateConfig simulatedContextId must be a string");
|
|
12431
|
+
}
|
|
12432
|
+
}
|
|
12433
|
+
__name(validateMobileSimulateConfig, "validateMobileSimulateConfig");
|
|
11762
12434
|
function validateMobileExtraConfig(config) {
|
|
11763
12435
|
if (typeof config.lockResolution !== "boolean") {
|
|
11764
12436
|
throw new Error("MobileExtraConfig lockResolution must be a boolean");
|
|
@@ -11779,6 +12451,9 @@ function validateMobileExtraConfig(config) {
|
|
|
11779
12451
|
}
|
|
11780
12452
|
}
|
|
11781
12453
|
}
|
|
12454
|
+
if (config.simulateConfig) {
|
|
12455
|
+
validateMobileSimulateConfig(config.simulateConfig);
|
|
12456
|
+
}
|
|
11782
12457
|
}
|
|
11783
12458
|
__name(validateMobileExtraConfig, "validateMobileExtraConfig");
|
|
11784
12459
|
function validateExtraConfigs(extraConfigs) {
|
|
@@ -11788,6 +12463,300 @@ function validateExtraConfigs(extraConfigs) {
|
|
|
11788
12463
|
}
|
|
11789
12464
|
__name(validateExtraConfigs, "validateExtraConfigs");
|
|
11790
12465
|
|
|
12466
|
+
// src/mobile-simulate.ts
|
|
12467
|
+
var MOBILE_INFO_DEFAULT_PATH = "/data/agentbay_mobile_info";
|
|
12468
|
+
var MOBILE_INFO_SUB_PATH = "/agentbay_mobile_info";
|
|
12469
|
+
var MOBILE_INFO_FILE_NAME = "dev_info.json";
|
|
12470
|
+
var _MobileSimulateService = class _MobileSimulateService {
|
|
12471
|
+
/**
|
|
12472
|
+
* Initialize the MobileSimulateService.
|
|
12473
|
+
*
|
|
12474
|
+
* @param agentBay - The AgentBay instance.
|
|
12475
|
+
*/
|
|
12476
|
+
constructor(agentBay) {
|
|
12477
|
+
this.simulateEnable = false;
|
|
12478
|
+
this.simulateMode = "PropertiesOnly" /* PropertiesOnly */;
|
|
12479
|
+
this.useInternalContext = true;
|
|
12480
|
+
if (!agentBay) {
|
|
12481
|
+
throw new Error("agentBay is required");
|
|
12482
|
+
}
|
|
12483
|
+
if (!agentBay.context) {
|
|
12484
|
+
throw new Error("agentBay.context is required");
|
|
12485
|
+
}
|
|
12486
|
+
this.agentBay = agentBay;
|
|
12487
|
+
this.contextService = agentBay.context;
|
|
12488
|
+
}
|
|
12489
|
+
/**
|
|
12490
|
+
* Set the simulate enable flag.
|
|
12491
|
+
*
|
|
12492
|
+
* @param enable - The simulate feature enable flag.
|
|
12493
|
+
*/
|
|
12494
|
+
setSimulateEnable(enable) {
|
|
12495
|
+
this.simulateEnable = enable;
|
|
12496
|
+
}
|
|
12497
|
+
/**
|
|
12498
|
+
* Get the simulate enable flag.
|
|
12499
|
+
*
|
|
12500
|
+
* @returns The simulate feature enable flag.
|
|
12501
|
+
*/
|
|
12502
|
+
getSimulateEnable() {
|
|
12503
|
+
return this.simulateEnable;
|
|
12504
|
+
}
|
|
12505
|
+
/**
|
|
12506
|
+
* Set the simulate mode.
|
|
12507
|
+
*
|
|
12508
|
+
* @param mode - The simulate mode.
|
|
12509
|
+
* - PropertiesOnly: Simulate only device properties.
|
|
12510
|
+
* - SensorsOnly: Simulate only device sensors.
|
|
12511
|
+
* - PackagesOnly: Simulate only installed packages.
|
|
12512
|
+
* - ServicesOnly: Simulate only system services.
|
|
12513
|
+
* - All: Simulate all aspects of the device.
|
|
12514
|
+
*/
|
|
12515
|
+
setSimulateMode(mode) {
|
|
12516
|
+
this.simulateMode = mode;
|
|
12517
|
+
}
|
|
12518
|
+
/**
|
|
12519
|
+
* Get the simulate mode.
|
|
12520
|
+
*
|
|
12521
|
+
* @returns The simulate mode.
|
|
12522
|
+
*/
|
|
12523
|
+
getSimulateMode() {
|
|
12524
|
+
return this.simulateMode;
|
|
12525
|
+
}
|
|
12526
|
+
/**
|
|
12527
|
+
* Set a previously saved simulate context id. Please make sure the context id is provided by MobileSimulateService
|
|
12528
|
+
* but not user side created context.
|
|
12529
|
+
*
|
|
12530
|
+
* @param contextId - The context ID of the previously saved mobile simulate context.
|
|
12531
|
+
*/
|
|
12532
|
+
setSimulateContextId(contextId) {
|
|
12533
|
+
this.contextId = contextId;
|
|
12534
|
+
logInfo(`set simulate context id = ${contextId}`);
|
|
12535
|
+
this.updateContext(true, contextId, void 0);
|
|
12536
|
+
}
|
|
12537
|
+
/**
|
|
12538
|
+
* Get the simulate context id.
|
|
12539
|
+
*
|
|
12540
|
+
* @returns The context ID of the mobile simulate context.
|
|
12541
|
+
*/
|
|
12542
|
+
getSimulateContextId() {
|
|
12543
|
+
return this.contextId;
|
|
12544
|
+
}
|
|
12545
|
+
/**
|
|
12546
|
+
* Get the simulate config.
|
|
12547
|
+
*
|
|
12548
|
+
* @returns The simulate config.
|
|
12549
|
+
* - simulate: The simulate feature enable flag.
|
|
12550
|
+
* - simulatePath: The path of the mobile dev info file.
|
|
12551
|
+
* - simulateMode: The simulate mode.
|
|
12552
|
+
* - simulatedContextId: The context ID of the mobile info.
|
|
12553
|
+
*/
|
|
12554
|
+
getSimulateConfig() {
|
|
12555
|
+
const simulatedContextId = this.useInternalContext ? this.contextId : void 0;
|
|
12556
|
+
return {
|
|
12557
|
+
simulate: this.simulateEnable,
|
|
12558
|
+
simulatePath: this.mobileDevInfoPath,
|
|
12559
|
+
simulateMode: this.simulateMode,
|
|
12560
|
+
simulatedContextId
|
|
12561
|
+
};
|
|
12562
|
+
}
|
|
12563
|
+
/**
|
|
12564
|
+
* Check if the mobile dev info file exists in one context sync. (Only for user provided context sync)
|
|
12565
|
+
*
|
|
12566
|
+
* @param contextSync - The context sync to check.
|
|
12567
|
+
* @returns True if the mobile dev info file exists, False otherwise.
|
|
12568
|
+
* @throws Error if context_sync is not provided or context_sync.context_id or context_sync.path is not provided.
|
|
12569
|
+
*
|
|
12570
|
+
* @remarks
|
|
12571
|
+
* This method can only be used when mobile simulate context sync is managed by user side. For internal mobile simulate
|
|
12572
|
+
* context sync, this method will not work.
|
|
12573
|
+
*/
|
|
12574
|
+
async hasMobileInfo(contextSync) {
|
|
12575
|
+
if (!contextSync) {
|
|
12576
|
+
throw new Error("contextSync is required");
|
|
12577
|
+
}
|
|
12578
|
+
if (!contextSync.contextId) {
|
|
12579
|
+
throw new Error("contextSync.contextId is required");
|
|
12580
|
+
}
|
|
12581
|
+
if (!contextSync.path) {
|
|
12582
|
+
throw new Error("contextSync.path is required");
|
|
12583
|
+
}
|
|
12584
|
+
const mobileDevInfoPath = contextSync.path + MOBILE_INFO_SUB_PATH + "/";
|
|
12585
|
+
logDebug(`hasMobileInfo: context_id = ${contextSync.contextId}, mobile_dev_info_path = ${mobileDevInfoPath}`);
|
|
12586
|
+
const res = await this.contextService.listFiles(contextSync.contextId, mobileDevInfoPath, 1, 50);
|
|
12587
|
+
let foundDevInfo = false;
|
|
12588
|
+
if (res.success) {
|
|
12589
|
+
for (const entry of res.entries) {
|
|
12590
|
+
if (entry.fileName === MOBILE_INFO_FILE_NAME) {
|
|
12591
|
+
foundDevInfo = true;
|
|
12592
|
+
break;
|
|
12593
|
+
}
|
|
12594
|
+
}
|
|
12595
|
+
} else {
|
|
12596
|
+
logError(`failed to list files: ${res.errorMessage}`);
|
|
12597
|
+
return false;
|
|
12598
|
+
}
|
|
12599
|
+
if (foundDevInfo) {
|
|
12600
|
+
logInfo("mobile dev info already exists");
|
|
12601
|
+
this.updateContext(false, contextSync.contextId, contextSync);
|
|
12602
|
+
return true;
|
|
12603
|
+
} else {
|
|
12604
|
+
logInfo("mobile dev info does not exist");
|
|
12605
|
+
return false;
|
|
12606
|
+
}
|
|
12607
|
+
}
|
|
12608
|
+
/**
|
|
12609
|
+
* Upload the mobile simulate dev info.
|
|
12610
|
+
*
|
|
12611
|
+
* @param mobileDevInfoContent - The mobile simulate dev info content to upload.
|
|
12612
|
+
* @param contextSync - Optional
|
|
12613
|
+
* - If not provided, a new context sync will be created for the mobile simulate service and this context id will
|
|
12614
|
+
* be returned by the MobileSimulateUploadResult. User can use this context id to do persistent mobile simulate across sessions.
|
|
12615
|
+
* - If provided, the mobile simulate dev info will be uploaded to the context sync in a specific path.
|
|
12616
|
+
*
|
|
12617
|
+
* @returns The result of the upload operation.
|
|
12618
|
+
*
|
|
12619
|
+
* @throws Error if mobile_dev_info_content is not provided or not a valid JSON string.
|
|
12620
|
+
* @throws Error if context_sync is provided but context_sync.context_id is not provided.
|
|
12621
|
+
*
|
|
12622
|
+
* @remarks
|
|
12623
|
+
* If context_sync is not provided, a new context sync will be created for the mobile simulate.
|
|
12624
|
+
* If context_sync is provided, the mobile simulate dev info will be uploaded to the context sync.
|
|
12625
|
+
* If the mobile simulate dev info already exists in the context sync, the context sync will be updated.
|
|
12626
|
+
* If the mobile simulate dev info does not exist in the context sync, the context sync will be created.
|
|
12627
|
+
* If the upload operation fails, the error message will be returned.
|
|
12628
|
+
*/
|
|
12629
|
+
async uploadMobileInfo(mobileDevInfoContent, contextSync) {
|
|
12630
|
+
if (!mobileDevInfoContent) {
|
|
12631
|
+
throw new Error("mobileDevInfoContent is required");
|
|
12632
|
+
}
|
|
12633
|
+
try {
|
|
12634
|
+
JSON.parse(mobileDevInfoContent);
|
|
12635
|
+
} catch (error) {
|
|
12636
|
+
throw new Error("mobileDevInfoContent is not a valid JSON string");
|
|
12637
|
+
}
|
|
12638
|
+
if (!contextSync) {
|
|
12639
|
+
const createdContext = await this.createContextForSimulate();
|
|
12640
|
+
if (!createdContext) {
|
|
12641
|
+
logError("Failed to create context for simulate");
|
|
12642
|
+
return {
|
|
12643
|
+
success: false,
|
|
12644
|
+
errorMessage: "Failed to create context for simulate"
|
|
12645
|
+
};
|
|
12646
|
+
}
|
|
12647
|
+
this.updateContext(true, createdContext.id, void 0);
|
|
12648
|
+
} else {
|
|
12649
|
+
if (!contextSync.contextId) {
|
|
12650
|
+
throw new Error("contextSync.contextId is required");
|
|
12651
|
+
}
|
|
12652
|
+
this.updateContext(false, contextSync.contextId, contextSync);
|
|
12653
|
+
}
|
|
12654
|
+
const uploadPath = `${this.mobileDevInfoPath}/${MOBILE_INFO_FILE_NAME}`;
|
|
12655
|
+
const uploadUrlResult = await this.contextService.getFileUploadUrl(this.contextId, uploadPath);
|
|
12656
|
+
if (!uploadUrlResult.success) {
|
|
12657
|
+
logError(`Failed to get file upload URL: ${uploadUrlResult.errorMessage}`);
|
|
12658
|
+
return {
|
|
12659
|
+
success: false,
|
|
12660
|
+
errorMessage: uploadUrlResult.errorMessage
|
|
12661
|
+
};
|
|
12662
|
+
}
|
|
12663
|
+
logDebug(`upload_url = ${uploadUrlResult.url}`);
|
|
12664
|
+
try {
|
|
12665
|
+
const encoder = new TextEncoder();
|
|
12666
|
+
const uint8Array = encoder.encode(mobileDevInfoContent);
|
|
12667
|
+
const response = await fetch4(uploadUrlResult.url, {
|
|
12668
|
+
method: "PUT",
|
|
12669
|
+
body: uint8Array
|
|
12670
|
+
});
|
|
12671
|
+
if (!response.ok) {
|
|
12672
|
+
throw new Error(`Upload failed with status ${response.status}: ${response.statusText}`);
|
|
12673
|
+
}
|
|
12674
|
+
} catch (error) {
|
|
12675
|
+
const errorMsg = `An error occurred while uploading the file: ${error instanceof Error ? error.message : String(error)}`;
|
|
12676
|
+
logError(errorMsg);
|
|
12677
|
+
return {
|
|
12678
|
+
success: false,
|
|
12679
|
+
errorMessage: errorMsg
|
|
12680
|
+
};
|
|
12681
|
+
}
|
|
12682
|
+
logInfo("mobile dev info uploaded successfully");
|
|
12683
|
+
return {
|
|
12684
|
+
success: true,
|
|
12685
|
+
mobileSimulateContextId: this.contextId
|
|
12686
|
+
};
|
|
12687
|
+
}
|
|
12688
|
+
/**
|
|
12689
|
+
* Update the context information.
|
|
12690
|
+
*
|
|
12691
|
+
* @param isInternal - Whether this is an internal context.
|
|
12692
|
+
* @param contextId - The context ID.
|
|
12693
|
+
* @param contextSync - The context sync (required for external context).
|
|
12694
|
+
*/
|
|
12695
|
+
updateContext(isInternal, contextId, contextSync) {
|
|
12696
|
+
if (!isInternal) {
|
|
12697
|
+
if (!contextSync) {
|
|
12698
|
+
throw new Error("contextSync is required for external context");
|
|
12699
|
+
}
|
|
12700
|
+
if (contextSync.policy?.bwList?.whiteLists) {
|
|
12701
|
+
const exists = contextSync.policy.bwList.whiteLists.some(
|
|
12702
|
+
(whiteList) => whiteList.path === MOBILE_INFO_SUB_PATH
|
|
12703
|
+
);
|
|
12704
|
+
if (!exists) {
|
|
12705
|
+
contextSync.policy.bwList.whiteLists.push({
|
|
12706
|
+
path: MOBILE_INFO_SUB_PATH,
|
|
12707
|
+
excludePaths: []
|
|
12708
|
+
});
|
|
12709
|
+
logInfo(`added mobile_dev_info_path to context_sync.policy.bw_list.white_lists: ${MOBILE_INFO_SUB_PATH}`);
|
|
12710
|
+
}
|
|
12711
|
+
}
|
|
12712
|
+
}
|
|
12713
|
+
this.useInternalContext = isInternal;
|
|
12714
|
+
this.contextId = contextId;
|
|
12715
|
+
this.contextSync = contextSync;
|
|
12716
|
+
if (isInternal) {
|
|
12717
|
+
this.mobileDevInfoPath = MOBILE_INFO_DEFAULT_PATH;
|
|
12718
|
+
} else {
|
|
12719
|
+
this.mobileDevInfoPath = contextSync.path + MOBILE_INFO_SUB_PATH;
|
|
12720
|
+
}
|
|
12721
|
+
logInfo(`updated context, is_internal = ${isInternal}, context_id = ${this.contextId}, mobile_dev_info_path = ${this.mobileDevInfoPath}`);
|
|
12722
|
+
}
|
|
12723
|
+
/**
|
|
12724
|
+
* Create a context for simulate.
|
|
12725
|
+
*
|
|
12726
|
+
* @returns The created context or null if failed.
|
|
12727
|
+
*/
|
|
12728
|
+
async createContextForSimulate() {
|
|
12729
|
+
const randomHex = Array.from(
|
|
12730
|
+
{ length: 16 },
|
|
12731
|
+
() => Math.floor(Math.random() * 256).toString(16).padStart(2, "0")
|
|
12732
|
+
).join("");
|
|
12733
|
+
const contextName = `mobile_sim_${randomHex}_${Math.floor(Date.now() / 1e3)}`;
|
|
12734
|
+
const contextResult = await this.contextService.get(contextName, true);
|
|
12735
|
+
if (!contextResult.success || !contextResult.context) {
|
|
12736
|
+
logError(`Failed to create mobile simulate context: ${contextResult.errorMessage}`);
|
|
12737
|
+
return null;
|
|
12738
|
+
}
|
|
12739
|
+
const context = contextResult.context;
|
|
12740
|
+
logInfo(`created mobile simulate context, context_id = ${context.id}, context_name = ${context.name}`);
|
|
12741
|
+
return context;
|
|
12742
|
+
}
|
|
12743
|
+
};
|
|
12744
|
+
__name(_MobileSimulateService, "MobileSimulateService");
|
|
12745
|
+
var MobileSimulateService = _MobileSimulateService;
|
|
12746
|
+
|
|
12747
|
+
// src/types/index.ts
|
|
12748
|
+
init_esm_shims();
|
|
12749
|
+
|
|
12750
|
+
// src/types/list-session-params.ts
|
|
12751
|
+
init_esm_shims();
|
|
12752
|
+
function createListSessionParams(labels = {}) {
|
|
12753
|
+
return {
|
|
12754
|
+
maxResults: 10,
|
|
12755
|
+
labels
|
|
12756
|
+
};
|
|
12757
|
+
}
|
|
12758
|
+
__name(createListSessionParams, "createListSessionParams");
|
|
12759
|
+
|
|
11791
12760
|
// src/session-params.ts
|
|
11792
12761
|
init_esm_shims();
|
|
11793
12762
|
var BROWSER_FINGERPRINT_PERSIST_PATH2 = "/tmp/browser_fingerprint";
|
|
@@ -12061,8 +13030,8 @@ var _CreateSessionParams = class _CreateSessionParams {
|
|
|
12061
13030
|
/**
|
|
12062
13031
|
* AddContextSync adds a context sync configuration to the session parameters.
|
|
12063
13032
|
*/
|
|
12064
|
-
addContextSync(contextId,
|
|
12065
|
-
const contextSync = new ContextSync(contextId,
|
|
13033
|
+
addContextSync(contextId, path7, policy) {
|
|
13034
|
+
const contextSync = new ContextSync(contextId, path7, policy);
|
|
12066
13035
|
this.contextSync.push(contextSync);
|
|
12067
13036
|
return this;
|
|
12068
13037
|
}
|
|
@@ -12273,15 +13242,23 @@ export {
|
|
|
12273
13242
|
ListSessionResponseBodyData,
|
|
12274
13243
|
MOBILE_COMMAND_TEMPLATES,
|
|
12275
13244
|
Mobile,
|
|
13245
|
+
MobileSimulateMode,
|
|
13246
|
+
MobileSimulateService,
|
|
12276
13247
|
ModifyContextRequest,
|
|
12277
13248
|
ModifyContextResponse,
|
|
12278
13249
|
ModifyContextResponseBody,
|
|
12279
13250
|
Oss,
|
|
12280
13251
|
OssError,
|
|
13252
|
+
PauseSessionAsyncRequest,
|
|
13253
|
+
PauseSessionAsyncResponse,
|
|
13254
|
+
PauseSessionAsyncResponseBody,
|
|
12281
13255
|
RESOLUTION_LOCK_TEMPLATE,
|
|
12282
13256
|
ReleaseMcpSessionRequest,
|
|
12283
13257
|
ReleaseMcpSessionResponse,
|
|
12284
13258
|
ReleaseMcpSessionResponseBody,
|
|
13259
|
+
ResumeSessionAsyncRequest,
|
|
13260
|
+
ResumeSessionAsyncResponse,
|
|
13261
|
+
ResumeSessionAsyncResponseBody,
|
|
12285
13262
|
SHOW_NAVIGATION_BAR_TEMPLATE,
|
|
12286
13263
|
Session,
|
|
12287
13264
|
SessionError,
|
|
@@ -12325,7 +13302,8 @@ export {
|
|
|
12325
13302
|
setupLogger,
|
|
12326
13303
|
validateAppManagerRule,
|
|
12327
13304
|
validateExtraConfigs,
|
|
12328
|
-
validateMobileExtraConfig
|
|
13305
|
+
validateMobileExtraConfig,
|
|
13306
|
+
validateMobileSimulateConfig
|
|
12329
13307
|
};
|
|
12330
13308
|
//# sourceMappingURL=index.mjs.map
|
|
12331
13309
|
|