wuying-agentbay-sdk 0.9.4 → 0.10.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.
@@ -1 +1 @@
1
- {"version":3,"sources":["/home/runner/work/wuying-agentbay-sdk/wuying-agentbay-sdk/typescript/dist/index.cjs","../node_modules/dotenv/package.json","../node_modules/dotenv/lib/main.js","../node_modules/dotenv/lib/env-options.js","../node_modules/dotenv/lib/cli-options.js","../src/index.ts","../src/agent-bay.ts","../node_modules/dotenv/config.js","../src/api/index.ts","../src/api/client.ts","../src/api/models/model.ts","../src/api/models/ApplyMqttTokenResponseBodyData.ts","../src/api/models/CreateMcpSessionRequestPersistenceDataList.ts","../src/api/models/CreateMcpSessionResponseBodyData.ts","../src/api/models/GetContextResponseBodyData.ts","../src/api/models/GetContextInfoResponseBodyData.ts","../src/api/models/GetLabelResponseBodyData.ts","../src/api/models/GetSessionResponseBodyData.ts","../src/api/models/GetLinkResponseBodyData.ts","../src/api/models/GetMcpResourceResponseBodyDataDesktopInfo.ts","../src/api/models/GetMcpResourceResponseBodyData.ts","../src/api/models/ListContextsResponseBodyData.ts","../src/api/models/ListSessionResponseBodyData.ts","../src/api/models/ApplyMqttTokenRequest.ts","../src/api/models/ApplyMqttTokenResponseBody.ts","../src/api/models/ApplyMqttTokenResponse.ts","../src/api/models/CallMcpToolRequest.ts","../src/api/models/CallMcpToolResponseBody.ts","../src/api/models/CallMcpToolResponse.ts","../src/api/models/CreateMcpSessionRequest.ts","../src/api/models/CreateMcpSessionShrinkRequest.ts","../src/api/models/CreateMcpSessionResponseBody.ts","../src/api/models/CreateMcpSessionResponse.ts","../src/api/models/DeleteContextRequest.ts","../src/api/models/DeleteContextResponseBody.ts","../src/api/models/DeleteContextResponse.ts","../src/api/models/GetContextRequest.ts","../src/api/models/GetContextResponseBody.ts","../src/api/models/GetContextResponse.ts","../src/api/models/GetContextInfoRequest.ts","../src/api/models/GetContextInfoResponseBody.ts","../src/api/models/GetContextInfoResponse.ts","../src/api/models/GetLabelRequest.ts","../src/api/models/GetLabelResponseBody.ts","../src/api/models/GetLabelResponse.ts","../src/api/models/GetSessionRequest.ts","../src/api/models/GetSessionResponseBody.ts","../src/api/models/GetSessionResponse.ts","../src/api/models/GetLinkRequest.ts","../src/api/models/GetLinkResponseBody.ts","../src/api/models/GetLinkResponse.ts","../src/api/models/GetMcpResourceRequest.ts","../src/api/models/GetMcpResourceResponseBody.ts","../src/api/models/GetMcpResourceResponse.ts","../src/api/models/InitBrowserRequest.ts","../src/api/models/InitBrowserResponseBody.ts","../src/api/models/InitBrowserResponseBodyData.ts","../src/api/models/InitBrowserResponse.ts","../src/api/models/ListContextsRequest.ts","../src/api/models/ListContextsResponseBody.ts","../src/api/models/ListContextsResponse.ts","../src/api/models/ListMcpToolsRequest.ts","../src/api/models/ListMcpToolsResponseBody.ts","../src/api/models/ListMcpToolsResponse.ts","../src/api/models/ListSessionRequest.ts","../src/api/models/ListSessionResponseBody.ts","../src/api/models/ListSessionResponse.ts","../src/api/models/ModifyContextRequest.ts","../src/api/models/ModifyContextResponseBody.ts","../src/api/models/ModifyContextResponse.ts","../src/api/models/ReleaseMcpSessionRequest.ts","../src/api/models/ReleaseMcpSessionResponseBody.ts","../src/api/models/ReleaseMcpSessionResponse.ts","../src/api/models/SetLabelRequest.ts","../src/api/models/SetLabelResponseBody.ts","../src/api/models/SetLabelResponse.ts","../src/api/models/SyncContextRequest.ts","../src/api/models/SyncContextResponseBody.ts","../src/api/models/SyncContextResponse.ts","../src/api/models/DeleteContextFileRequest.ts","../src/api/models/DeleteContextFileResponseBody.ts","../src/api/models/DeleteContextFileResponse.ts","../src/api/models/DescribeContextFilesRequest.ts","../src/api/models/DescribeContextFilesResponseBody.ts","../src/api/models/DescribeContextFilesResponse.ts","../src/api/models/GetContextFileDownloadUrlRequest.ts","../src/api/models/GetContextFileDownloadUrlResponseBody.ts","../src/api/models/GetContextFileDownloadUrlResponse.ts","../src/api/models/GetContextFileUploadUrlRequest.ts","../src/api/models/GetContextFileUploadUrlResponseBody.ts","../src/api/models/GetContextFileUploadUrlResponse.ts","../src/config.ts","../src/utils/logger.ts","../src/context.ts","../src/types/api-response.ts","../src/context-sync.ts","../src/exceptions.ts","../src/session.ts","../src/agent/agent.ts","../src/application/application.ts","../src/browser/index.ts","../src/browser/browser.ts","../src/browser/browser_agent.ts","../src/code/index.ts","../src/code/code.ts","../src/command/command.ts","../src/computer/index.ts","../src/computer/computer.ts","../src/context-manager.ts","../src/filesystem/filesystem.ts","../src/filesystem/file-transfer.ts","../src/mobile/index.ts","../src/mobile/mobile.ts","../src/oss/index.ts","../src/oss/oss.ts","../src/ui/ui.ts","../src/agent/index.ts","../src/extension.ts","../src/session-params.ts"],"names":["fs","path","crypto","parse","context","UploadStrategy","DownloadStrategy","Lifecycle","resolve","MouseButton","ScrollDirection","KeyCode","requestId"],"mappings":"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CC,MAAA;AACD,MAAA;AACQ,MAAA;AACT,MAAA;AACG,MAAA;AACW,MAAA;AAC5B,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAKwE,EAAA;AAC/B,IAAA;AACL,IAAA;AACV,IAAA;AACoB,IAAA;AAGjB,IAAA;AACU,MAAA;AAEF,QAAA;AAC1B,MAAA;AAEa,QAAA;AACU,QAAA;AACvB,UAAA;AACA,UAAA;AACA,UAAA;AACL,QAAA;AACF,MAAA;AACF,IAAA;AAE+B,IAAA;AACN,IAAA;AACW,IAAA;AAC7B,IAAA;AACT,EAAA;AACF;AA/LsE;AAA/D;AAoMuD;AAC7B,EAAA;AACjC;AAFgB;AtH8gVuC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/wuying-agentbay-sdk/wuying-agentbay-sdk/typescript/dist/index.cjs","sourcesContent":[null,"{\n \"name\": \"dotenv\",\n \"version\": \"16.6.1\",\n \"description\": \"Loads environment variables from .env file\",\n \"main\": \"lib/main.js\",\n \"types\": \"lib/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/main.d.ts\",\n \"require\": \"./lib/main.js\",\n \"default\": \"./lib/main.js\"\n },\n \"./config\": \"./config.js\",\n \"./config.js\": \"./config.js\",\n \"./lib/env-options\": \"./lib/env-options.js\",\n \"./lib/env-options.js\": \"./lib/env-options.js\",\n \"./lib/cli-options\": \"./lib/cli-options.js\",\n \"./lib/cli-options.js\": \"./lib/cli-options.js\",\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"dts-check\": \"tsc --project tests/types/tsconfig.json\",\n \"lint\": \"standard\",\n \"pretest\": \"npm run lint && npm run dts-check\",\n \"test\": \"tap run --allow-empty-coverage --disable-coverage --timeout=60000\",\n \"test:coverage\": \"tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov\",\n \"prerelease\": \"npm test\",\n \"release\": \"standard-version\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/motdotla/dotenv.git\"\n },\n \"homepage\": \"https://github.com/motdotla/dotenv#readme\",\n \"funding\": \"https://dotenvx.com\",\n \"keywords\": [\n \"dotenv\",\n \"env\",\n \".env\",\n \"environment\",\n \"variables\",\n \"config\",\n \"settings\"\n ],\n \"readmeFilename\": \"README.md\",\n \"license\": \"BSD-2-Clause\",\n \"devDependencies\": {\n \"@types/node\": \"^18.11.3\",\n \"decache\": \"^4.6.2\",\n \"sinon\": \"^14.0.1\",\n \"standard\": \"^17.0.0\",\n \"standard-version\": \"^9.5.0\",\n \"tap\": \"^19.2.0\",\n \"typescript\": \"^4.8.4\"\n },\n \"engines\": {\n \"node\": \">=12\"\n },\n \"browser\": {\n \"fs\": false\n }\n}\n","const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","// ../config.js accepts options via environment variables\nconst options = {}\n\nif (process.env.DOTENV_CONFIG_ENCODING != null) {\n options.encoding = process.env.DOTENV_CONFIG_ENCODING\n}\n\nif (process.env.DOTENV_CONFIG_PATH != null) {\n options.path = process.env.DOTENV_CONFIG_PATH\n}\n\nif (process.env.DOTENV_CONFIG_QUIET != null) {\n options.quiet = process.env.DOTENV_CONFIG_QUIET\n}\n\nif (process.env.DOTENV_CONFIG_DEBUG != null) {\n options.debug = process.env.DOTENV_CONFIG_DEBUG\n}\n\nif (process.env.DOTENV_CONFIG_OVERRIDE != null) {\n options.override = process.env.DOTENV_CONFIG_OVERRIDE\n}\n\nif (process.env.DOTENV_CONFIG_DOTENV_KEY != null) {\n options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY\n}\n\nmodule.exports = options\n","const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/\n\nmodule.exports = function optionMatcher (args) {\n const options = args.reduce(function (acc, cur) {\n const matches = cur.match(re)\n if (matches) {\n acc[matches[1]] = matches[2]\n }\n return acc\n }, {})\n\n if (!('quiet' in options)) {\n options.quiet = 'true'\n }\n\n return options\n}\n","// Export all public classes and interfaces\nexport { AgentBay, type CreateSessionParams} from \"./agent-bay\";\nexport * from \"./agent\";\nexport * from \"./api\";\nexport * from \"./application\";\nexport * from \"./browser\";\nexport * from \"./command\";\nexport { Context, ContextService } from \"./context\";\nexport * from \"./exceptions\";\nexport * from \"./extension\";\nexport * from \"./filesystem\";\nexport * from \"./oss\";\nexport { Session } from \"./session\";\nexport { type ListSessionParams } from \"./types\";\nexport * from \"./ui\";\nexport * from './context-sync'\nexport * from './context-manager'\nexport * from './session-params'\n// Export utility functions\nexport { log, logError } from \"./utils/logger\";\nexport { loadConfig, loadDotEnv, type Config } from \"./config\";\n","import { $OpenApiUtil } from \"@alicloud/openapi-core\";\nimport \"dotenv/config\";\nimport * as $_client from \"./api\";\nimport { ListSessionRequest, CreateMcpSessionRequestPersistenceDataList, GetSessionRequest as $GetSessionRequest } from \"./api/models/model\";\nimport { Client } from \"./api/client\";\n\nimport { loadConfig, loadDotEnvWithFallback, Config, BROWSER_DATA_PATH } from \"./config\";\nimport { ContextService } from \"./context\";\nimport { ContextSync } from \"./context-sync\";\nimport { APIError, AuthenticationError } from \"./exceptions\";\nimport { Session } from \"./session\";\nimport { BrowserContext } from \"./session-params\";\nimport { Context } from \"./context\";\n\nimport {\n DeleteResult,\n extractRequestId,\n GetSessionResult as $GetSessionResult,\n SessionResult,\n} from \"./types/api-response\";\nimport {\n ListSessionParams,\n SessionListResult,\n} from \"./types/list-session-params\";\nimport { log, logError } from \"./utils/logger\";\n\n/**\n * Generate a random context name using alphanumeric characters with timestamp.\n * This function is similar to the Python version's generate_random_context_name.\n */\nfunction generateRandomContextName(length = 8, includeTimestamp = true): string {\n const timestamp = new Date().toISOString().replace(/[-T:.Z]/g, '').slice(0, 14);\n\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let randomPart = '';\n for (let i = 0; i < length; i++) {\n randomPart += characters.charAt(Math.floor(Math.random() * characters.length));\n }\n\n return includeTimestamp ? `${timestamp}_${randomPart}` : randomPart;\n}\n\n/**\n * Parameters for creating a session.\n */\nexport interface CreateSessionParams {\n labels?: Record<string, string>;\n imageId?: string;\n contextSync?: ContextSync[];\n browserContext?: BrowserContext;\n isVpc?: boolean;\n policyId?: string;\n enableBrowserReplay?: boolean;\n}\n\n/**\n * Main class for interacting with the AgentBay cloud runtime environment.\n */\nexport class AgentBay {\n private apiKey: string;\n private client: Client;\n private endpoint: string;\n private sessions: Map<string, Session> = new Map();\n private fileTransferContext: Context | null = null;\n\n /**\n * Context service for managing persistent contexts.\n */\n context: ContextService;\n\n /**\n * Initialize the AgentBay client.\n *\n * @param options - Configuration options\n * @param options.apiKey - API key for authentication. If not provided, will look for AGENTBAY_API_KEY environment variable.\n * @param options.config - Custom configuration object. If not provided, will use environment-based configuration.\n * @param options.envFile - Custom path to .env file. If not provided, will search upward from current directory.\n */\n constructor(\n options: {\n apiKey?: string;\n config?: Config;\n envFile?: string;\n } = {}\n ) {\n // Load .env file first to ensure AGENTBAY_API_KEY is available\n loadDotEnvWithFallback(options.envFile);\n\n this.apiKey = options.apiKey || process.env.AGENTBAY_API_KEY || \"\";\n\n if (!this.apiKey) {\n throw new AuthenticationError(\n \"API key is required. Provide it as a parameter or set the AGENTBAY_API_KEY environment variable.\"\n );\n }\n\n // Load configuration using the enhanced loadConfig function\n const configData = loadConfig(options.config, options.envFile);\n this.endpoint = configData.endpoint;\n\n const config = new $OpenApiUtil.Config({\n regionId: \"\",\n endpoint: this.endpoint,\n });\n\n config.readTimeout = configData.timeout_ms;\n config.connectTimeout = configData.timeout_ms;\n\n try {\n this.client = new Client(config);\n\n // Initialize context service\n this.context = new ContextService(this);\n } catch (error) {\n logError(`Failed to constructor:`, error);\n throw new AuthenticationError(`Failed to constructor: ${error}`);\n }\n }\n\n /**\n * Update browser replay context with AppInstanceId from response data.\n *\n * @param responseData - Response data containing AppInstanceId\n * @param recordContextId - The record context ID to update\n */\n private async _updateBrowserReplayContext(responseData: any, recordContextId: string): Promise<void> {\n // Check if record_context_id is provided\n if (!recordContextId) {\n return;\n }\n\n try {\n // Extract AppInstanceId from response data\n const appInstanceId = responseData?.appInstanceId;\n if (!appInstanceId) {\n logError(\"AppInstanceId not found in response data, skipping browser replay context update\");\n return;\n }\n\n // Create context name with prefix\n const contextName = `browserreplay-${appInstanceId}`;\n\n // Create Context object for update\n const contextObj = new Context(recordContextId, contextName);\n\n // Call context.update interface\n log(`Updating browser replay context: ${contextName} -> ${recordContextId}`);\n const updateResult = await this.context.update(contextObj);\n\n if (updateResult.success) {\n log(`✅ Successfully updated browser replay context: ${contextName}`);\n } else {\n logError(`⚠️ Failed to update browser replay context: ${updateResult.errorMessage}`);\n }\n } catch (error) {\n logError(`❌ Error updating browser replay context: ${error}`);\n // Continue execution even if context update fails\n }\n }\n\n /**\n * Create a new session in the AgentBay cloud environment.\n *\n * @param params - Optional parameters for creating the session\n * @returns SessionResult containing the created session and request ID\n */\n async create(params: CreateSessionParams = {}): Promise<SessionResult> {\n try {\n // Create a default context for file transfer operations if none provided\n // and no context_syncs are specified\n const contextName = `file-transfer-context-${Date.now()}`;\n const contextResult = await this.context.get(contextName, true);\n if (contextResult.success && contextResult.context) {\n this.fileTransferContext = contextResult.context;\n // Add the context to the session params for file transfer operations\n const fileTransferContextSync = new ContextSync(\n contextResult.context.id,\n \"/temp/file-transfer\"\n );\n if (!params.contextSync) {\n params.contextSync = [];\n }\n log(`Adding context sync for file transfer operations: ${fileTransferContextSync}`);\n params.contextSync.push(fileTransferContextSync);\n }\n\n const request = new $_client.CreateMcpSessionRequest({\n authorization: \"Bearer \" + this.apiKey,\n });\n\n // Add labels if provided\n if (params.labels) {\n request.labels = JSON.stringify(params.labels);\n }\n\n // Add image_id if provided\n if (params.imageId) {\n request.imageId = params.imageId;\n }\n\n // Add PolicyId if provided\n if (params.policyId) {\n request.mcpPolicyId = params.policyId;\n }\n\n // Add VPC resource if specified\n request.vpcResource = params.isVpc || false;\n\n // Flag to indicate if we need to wait for context synchronization\n let needsContextSync = false;\n\n // Add context sync configurations if provided\n if (params.contextSync && params.contextSync.length > 0) {\n const persistenceDataList: CreateMcpSessionRequestPersistenceDataList[] = [];\n for (const contextSync of params.contextSync) {\n const persistenceItem = new CreateMcpSessionRequestPersistenceDataList({\n contextId: contextSync.contextId,\n path: contextSync.path,\n });\n\n // Convert policy to JSON string if provided\n if (contextSync.policy) {\n persistenceItem.policy = JSON.stringify(contextSync.policy);\n }\n\n persistenceDataList.push(persistenceItem);\n }\n request.persistenceDataList = persistenceDataList;\n needsContextSync = persistenceDataList.length > 0;\n }\n\n // Add BrowserContext as a ContextSync if provided\n if (params.browserContext) {\n // Create a simple sync policy for browser context\n const syncPolicy = {\n uploadPolicy: { autoUpload: params.browserContext.autoUpload },\n downloadPolicy: null,\n deletePolicy: null,\n bwList: null,\n recyclePolicy: null,\n };\n\n // Create browser context sync item\n const browserContextSync = new CreateMcpSessionRequestPersistenceDataList({\n contextId: params.browserContext.contextId,\n path: BROWSER_DATA_PATH, // Using a constant path for browser data\n policy: JSON.stringify(syncPolicy)\n });\n\n // Add to persistence data list or create new one if not exists\n if (!request.persistenceDataList) {\n request.persistenceDataList = [];\n }\n request.persistenceDataList.push(browserContextSync);\n needsContextSync = true;\n }\n\n // Add browser recording persistence if enabled\n let recordContextId = \"\"; // Initialize record_context_id\n if (params.enableBrowserReplay) {\n // Create browser recording persistence configuration\n const recordPath = \"/home/guest/record\";\n const recordContextName = generateRandomContextName();\n const result = await this.context.get(recordContextName, true);\n recordContextId = result.success ? result.contextId : \"\";\n const recordPersistence = new CreateMcpSessionRequestPersistenceDataList({\n contextId: recordContextId,\n path: recordPath,\n });\n\n // Add to persistence data list or create new one if not exists\n if (!request.persistenceDataList) {\n request.persistenceDataList = [];\n }\n request.persistenceDataList.push(recordPersistence);\n }\n\n // Log API request\n log(\"API Call: CreateMcpSession\");\n let requestLog = \"Request: \";\n if (request.imageId) {\n requestLog += `ImageId=${request.imageId}, `;\n }\n if (request.labels) {\n requestLog += `Labels=${request.labels}, `;\n }\n if (\n request.persistenceDataList &&\n request.persistenceDataList.length > 0\n ) {\n requestLog += `PersistenceDataList=${request.persistenceDataList.length} items, `;\n request.persistenceDataList.forEach((pd: CreateMcpSessionRequestPersistenceDataList, i: number) => {\n requestLog += `Item${i}[ContextId=${pd.contextId}, Path=${pd.path}`;\n if (pd.policy) {\n requestLog += `, Policy=${pd.policy}`;\n }\n requestLog += `], `;\n });\n }\n log(requestLog);\n\n const response = await this.client.createMcpSession(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Log response data with requestId\n log(\"response data =\", response.body?.data);\n if (requestId) {\n log(`requestId = ${requestId}`);\n }\n\n const sessionData = response.body;\n\n if (!sessionData || typeof sessionData !== \"object\") {\n return {\n requestId,\n success: false,\n errorMessage: \"Invalid response format: expected a dictionary\",\n };\n }\n\n // Check for API-level errors\n if (sessionData.success === false && sessionData.code) {\n const errorMessage = `[${sessionData.code}] ${sessionData.message || 'Unknown error'}`;\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n const data = sessionData.data;\n if (!data || typeof data !== \"object\") {\n return {\n requestId,\n success: false,\n errorMessage:\n \"Invalid response format: 'data' field is not a dictionary\",\n };\n }\n\n const sessionId = data.sessionId;\n if (!sessionId) {\n return {\n requestId,\n success: false,\n errorMessage: \"SessionId not found in response\",\n };\n }\n\n // ResourceUrl is optional in CreateMcpSession response\n const resourceUrl = data.resourceUrl || \"\";\n\n log(\"session_id =\", sessionId);\n log(\"resource_url =\", resourceUrl);\n\n const session = new Session(this, sessionId);\n\n // Set VPC-related information from response\n session.isVpc = params.isVpc || false;\n if (data.networkInterfaceIp) {\n session.networkInterfaceIp = data.networkInterfaceIp;\n }\n if (data.httpPort) {\n session.httpPort = data.httpPort;\n }\n if (data.token) {\n session.token = data.token;\n }\n\n // Set ResourceUrl\n session.resourceUrl = resourceUrl;\n\n // Set browser recording state\n session.enableBrowserReplay = params.enableBrowserReplay || false;\n\n // Store the file transfer context ID if we created one\n session.fileTransferContextId = this.fileTransferContext ? this.fileTransferContext.id : null;\n // Store imageId used for this session\n (session as any).imageId = params.imageId;\n\n this.sessions.set(session.sessionId, session);\n\n // Update browser replay context if enabled\n if (params.enableBrowserReplay) {\n await this._updateBrowserReplayContext(data, recordContextId);\n }\n\n // For VPC sessions, automatically fetch MCP tools information\n if (params.isVpc) {\n log(\"VPC session detected, automatically fetching MCP tools...\");\n try {\n const toolsResult = await session.listMcpTools();\n log(`Successfully fetched ${toolsResult.tools.length} MCP tools for VPC session (RequestID: ${toolsResult.requestId})`);\n } catch (error) {\n logError(`Warning: Failed to fetch MCP tools for VPC session: ${error}`);\n // Continue with session creation even if tools fetch fails\n }\n }\n\n // If we have persistence data, wait for context synchronization\n if (needsContextSync) {\n log(\"Waiting for context synchronization to complete...\");\n\n // Wait for context synchronization to complete\n const maxRetries = 150; // Maximum number of retries\n const retryInterval = 1500; // Milliseconds to wait between retries\n\n for (let retry = 0; retry < maxRetries; retry++) {\n try {\n // Get context status data\n const infoResult = await session.context.info();\n\n // Check if all context items have status \"Success\" or \"Failed\"\n let allCompleted = true;\n let hasFailure = false;\n\n for (const item of infoResult.contextStatusData) {\n log(`Context ${item.contextId} status: ${item.status}, path: ${item.path}`);\n\n if (item.status !== \"Success\" && item.status !== \"Failed\") {\n allCompleted = false;\n break;\n }\n\n if (item.status === \"Failed\") {\n hasFailure = true;\n logError(`Context synchronization failed for ${item.contextId}: ${item.errorMessage}`);\n }\n }\n\n if (allCompleted || infoResult.contextStatusData.length === 0) {\n if (hasFailure) {\n log(\"Context synchronization completed with failures\");\n } else {\n log(\"Context synchronization completed successfully\");\n }\n break;\n }\n\n log(`Waiting for context synchronization, attempt ${retry+1}/${maxRetries}`);\n await new Promise(resolve => setTimeout(resolve, retryInterval));\n } catch (error) {\n logError(`Error checking context status on attempt ${retry+1}: ${error}`);\n await new Promise(resolve => setTimeout(resolve, retryInterval));\n }\n }\n }\n\n // Return SessionResult with request ID\n return {\n requestId,\n success: true,\n session,\n };\n } catch (error) {\n logError(\"Error calling create_mcp_session:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to create session: ${error}`,\n };\n }\n }\n\n\n /**\n * List sessions filtered by the provided labels with pagination support.\n * It returns sessions that match all the specified labels.\n *\n * @deprecated This method is deprecated and will be removed in a future version. Use list() instead.\n *\n * **Breaking Change**: This method currently only accepts ListSessionParams parameters,\n *\n * @param params - Parameters including labels and pagination options (required)\n * @returns API response with sessions list and pagination info\n */\n async listByLabels(params?: ListSessionParams): Promise<SessionListResult> {\n if (!params) {\n params = {\n maxResults: 10,\n labels: {},\n };\n }\n\n try {\n // Convert labels to JSON\n const labelsJSON = JSON.stringify(params.labels);\n\n //Build request object with support for pagination parameters\n const listSessionRequest = new ListSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n labels: labelsJSON,\n maxResults: params.maxResults || 10,\n ...(params.nextToken && { nextToken: params.nextToken }),\n });\n\n log(\"API Call: ListSession\");\n log(\n `Request: Labels=${labelsJSON}, MaxResults=${params.maxResults || 10}${\n params.nextToken ? `, NextToken=${params.nextToken}` : \"\"\n }`\n );\n\n const response = await this.client.listSession(listSessionRequest);\n const body = response.body;\n const requestId = extractRequestId(body?.requestId) || \"\";\n\n // Check for errors in the response\n if (\n body?.data &&\n typeof body.data === \"object\" &&\n body.success &&\n body.success !== true\n ) {\n return {\n requestId,\n success: false,\n errorMessage: \"Failed to list sessions by labels\",\n sessionIds: [],\n nextToken: \"\",\n maxResults: params.maxResults || 10,\n totalCount: 0,\n };\n }\n\n const sessionIds: string[] = [];\n let nextToken = \"\";\n let maxResults = params.maxResults || 10;\n let totalCount = 0;\n\n log(\"body =\", body);\n\n // Extract pagination information\n if (body && typeof body === \"object\") {\n nextToken = body.nextToken || \"\";\n maxResults = parseInt(String(body.maxResults || 0)) || maxResults;\n totalCount = parseInt(String(body.totalCount || 0));\n }\n\n // Extract session data\n const responseData = body?.data;\n\n // Handle both list and dict responses\n if (Array.isArray(responseData)) {\n // Data is a list of session objects\n for (const sessionData of responseData) {\n if (sessionData && typeof sessionData === \"object\") {\n const sessionId = (sessionData as any).sessionId; // Capital S and I to match Python\n if (sessionId) {\n sessionIds.push(sessionId);\n }\n }\n }\n }\n\n // Return SessionListResult with request ID and pagination info\n return {\n requestId,\n success: true,\n sessionIds,\n nextToken,\n maxResults,\n totalCount,\n };\n } catch (error) {\n logError(\"Error calling list_session:\", error);\n return {\n requestId: \"\",\n success: false,\n sessionIds: [],\n errorMessage: `Failed to list sessions by labels: ${error}`,\n };\n }\n }\n\n /**\n * Returns paginated list of session IDs filtered by labels.\n *\n * @param labels - Optional labels to filter sessions (defaults to empty object)\n * @param page - Optional page number for pagination (starting from 1, defaults to 1)\n * @param limit - Optional maximum number of items per page (defaults to 10)\n * @returns SessionListResult - Paginated list of session IDs that match the labels\n *\n * @example\n * ```typescript\n * const agentBay = new AgentBay({ apiKey: \"your_api_key\" });\n *\n * // List all sessions\n * const result = await agentBay.list();\n *\n * // List sessions with specific labels\n * const result = await agentBay.list({ project: \"demo\" });\n *\n * // List sessions with pagination\n * const result = await agentBay.list({ \"my-label\": \"my-value\" }, 2, 10);\n *\n * if (result.success) {\n * for (const sessionId of result.sessionIds) {\n * console.log(`Session ID: ${sessionId}`);\n * }\n * console.log(`Total count: ${result.totalCount}`);\n * console.log(`Request ID: ${result.requestId}`);\n * }\n * ```\n */\n async list(\n labels: Record<string, string> = {},\n page?: number,\n limit: number = 10\n ): Promise<SessionListResult> {\n try {\n // Validate page number\n if (page !== undefined && page < 1) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Cannot reach page ${page}: Page number must be >= 1`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: 0,\n };\n }\n\n // Calculate next_token based on page number\n // Page 1 or undefined means no next_token (first page)\n // For page > 1, we need to make multiple requests to get to that page\n let nextToken = \"\";\n if (page !== undefined && page > 1) {\n // We need to fetch pages 1 through page-1 to get the next_token\n let currentPage = 1;\n while (currentPage < page) {\n // Make API call to get next_token\n const request = new ListSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n labels: JSON.stringify(labels),\n maxResults: limit,\n });\n if (nextToken) {\n request.nextToken = nextToken;\n }\n\n const response = await this.client.listSession(request);\n const requestId = extractRequestId(response) || \"\";\n\n if (!response.body?.success) {\n const code = response.body?.code || \"Unknown\";\n const message = response.body?.message || \"Unknown error\";\n return {\n requestId,\n success: false,\n errorMessage: `[${code}] ${message}`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: 0,\n };\n }\n\n nextToken = response.body.nextToken || \"\";\n if (!nextToken) {\n // No more pages available\n return {\n requestId,\n success: false,\n errorMessage: `Cannot reach page ${page}: No more pages available`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: response.body.totalCount || 0,\n };\n }\n currentPage += 1;\n }\n }\n\n // Make the actual request for the desired page\n const request = new ListSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n labels: JSON.stringify(labels),\n maxResults: limit,\n });\n if (nextToken) {\n request.nextToken = nextToken;\n }\n\n // Log API request\n log(\"API Call: ListSession\");\n log(`Request: Labels=${JSON.stringify(labels)}, MaxResults=${limit}${nextToken ? `, NextToken=${nextToken}` : \"\"}`);\n\n const response = await this.client.listSession(request);\n\n // Log API response\n log(\"body =\", response.body);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for errors in the response\n if (!response.body?.success) {\n const code = response.body?.code || \"Unknown\";\n const message = response.body?.message || \"Unknown error\";\n return {\n requestId,\n success: false,\n errorMessage: `[${code}] ${message}`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: 0,\n };\n }\n\n const sessionIds: string[] = [];\n\n // Extract session data\n if (response.body.data) {\n for (const sessionData of response.body.data) {\n if (sessionData.sessionId) {\n sessionIds.push(sessionData.sessionId);\n }\n }\n }\n\n // Return SessionListResult with request ID and pagination info\n return {\n requestId,\n success: true,\n sessionIds,\n nextToken: response.body.nextToken || \"\",\n maxResults: response.body.maxResults || limit,\n totalCount: response.body.totalCount || 0,\n };\n } catch (error) {\n logError(\"Error calling list_session:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to list sessions: ${error}`,\n sessionIds: [],\n };\n }\n }\n\n /**\n * Delete a session by session object.\n *\n * @param session - The session to delete.\n * @param syncContext - Whether to sync context data (trigger file uploads) before deleting the session. Defaults to false.\n * @returns DeleteResult indicating success or failure and request ID\n */\n async delete(session: Session, syncContext = false): Promise<DeleteResult> {\n try {\n // Delete the session and get the result\n if (session.enableBrowserReplay) {\n syncContext = true;\n }\n const deleteResult = await session.delete(syncContext);\n\n this.sessions.delete(session.sessionId);\n\n // Return the DeleteResult obtained from session.delete()\n return deleteResult;\n } catch (error) {\n logError(\"Error deleting session:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to delete session ${session.sessionId}: ${error}`,\n };\n }\n }\n\n /**\n *\n * @param sessionId - The ID of the session to remove.\n */\n public removeSession(sessionId: string): void {\n this.sessions.delete(sessionId);\n }\n\n /**\n * Get session information by session ID.\n *\n * @param sessionId - The ID of the session to retrieve.\n * @returns GetSessionResult containing session information\n */\n async getSession(sessionId: string): Promise<$GetSessionResult> {\n try {\n log(\"API Call: GetSession\");\n log(`Request: SessionId=${sessionId}`);\n\n const request = new $GetSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n sessionId: sessionId,\n });\n\n const response = await this.client.getSession(request);\n\n log(\"Response from GetSession:\", response.body);\n\n const requestId = extractRequestId(response) || \"\";\n const body = response.body;\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n return {\n requestId,\n httpStatusCode: body.httpStatusCode || 0,\n code: body.code,\n success: false,\n errorMessage: `[${body.code}] ${body.message || 'Unknown error'}`,\n };\n }\n\n const result: $GetSessionResult = {\n requestId,\n httpStatusCode: body?.httpStatusCode || 0,\n code: body?.code || \"\",\n success: body?.success || false,\n errorMessage: \"\",\n };\n\n if (body?.data) {\n result.data = {\n appInstanceId: body.data.appInstanceId || \"\",\n resourceId: body.data.resourceId || \"\",\n sessionId: body.data.sessionId || \"\",\n success: body.data.success || false,\n httpPort: body.data.httpPort || \"\",\n networkInterfaceIp: body.data.networkInterfaceIp || \"\",\n token: body.data.token || \"\",\n vpcResource: body.data.vpcResource || false,\n resourceUrl: body.data.resourceUrl || \"\",\n };\n }\n\n return result;\n } catch (error) {\n logError(\"Error calling GetSession:\", error);\n return {\n requestId: \"\",\n httpStatusCode: 0,\n code: \"\",\n success: false,\n errorMessage: `Failed to get session ${sessionId}: ${error}`,\n };\n }\n }\n\n /**\n * Get a session by its ID.\n *\n * This method retrieves a session by calling the GetSession API\n * and returns a SessionResult containing the Session object and request ID.\n *\n * @param sessionId - The ID of the session to retrieve\n * @returns Promise resolving to SessionResult with the Session instance, request ID, and success status\n *\n * @example\n * ```typescript\n * const result = await agentBay.get(\"my-session-id\");\n * if (result.success) {\n * console.log(result.session.sessionId);\n * console.log(result.requestId);\n * }\n * ```\n */\n async get(sessionId: string): Promise<SessionResult> {\n // Validate input\n if (\n !sessionId ||\n (typeof sessionId === \"string\" && !sessionId.trim())\n ) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"session_id is required\",\n };\n }\n\n // Call GetSession API\n const getResult = await this.getSession(sessionId);\n\n // Check if the API call was successful\n if (!getResult.success) {\n const errorMsg = getResult.errorMessage || \"Unknown error\";\n return {\n requestId: getResult.requestId,\n success: false,\n errorMessage: `Failed to get session ${sessionId}: ${errorMsg}`,\n };\n }\n\n // Create the Session object\n const session = new Session(this, sessionId);\n\n // Set VPC-related information and ResourceUrl from GetSession response\n if (getResult.data) {\n session.isVpc = getResult.data.vpcResource;\n session.networkInterfaceIp = getResult.data.networkInterfaceIp;\n session.httpPort = getResult.data.httpPort;\n session.token = getResult.data.token;\n session.resourceUrl = getResult.data.resourceUrl;\n }\n\n return {\n requestId: getResult.requestId,\n success: true,\n session,\n };\n }\n\n // For internal use by the Session class\n getClient(): Client {\n return this.client;\n }\n\n getAPIKey(): string {\n return this.apiKey;\n }\n}\n\n/**\n * Creates a new AgentBay client using default configuration.\n * This is a convenience function that allows creating an AgentBay instance without a config parameter.\n *\n * @param apiKey - API key for authentication\n * @returns A new AgentBay instance with default configuration\n */\nexport function newAgentBayWithDefaults(apiKey: string): AgentBay {\n return new AgentBay({ apiKey });\n}\n","(function () {\n require('./lib/main').config(\n Object.assign(\n {},\n require('./lib/env-options'),\n require('./lib/cli-options')(process.argv)\n )\n )\n})()\n","// Export the client and models\nimport { Client } from \"./client\";\nexport { Client } from \"./client\";\nexport * from \"./models/model\";\n\nexport default Client;\n","// This file is auto-generated, don't edit it\nimport * as $dara from \"@darabonba/typescript\";\nimport OpenApi from \"@alicloud/openapi-core\";\nimport { OpenApiUtil, $OpenApiUtil } from \"@alicloud/openapi-core\";\n\nimport * as $_model from \"./models/model\";\nexport * from \"./models/model\";\n\nexport class Client extends OpenApi {\n constructor(config: $OpenApiUtil.Config) {\n super(config);\n this._signatureAlgorithm = \"v2\";\n this._endpointRule = \"\";\n this.checkConfig(config);\n this._endpoint = this.getEndpoint(\n \"wuyingai\",\n this._regionId,\n this._endpointRule,\n this._network,\n this._suffix,\n this._endpointMap,\n this._endpoint\n );\n }\n\n getEndpoint(\n productId: string,\n regionId: string,\n endpointRule: string,\n network: string,\n suffix: string,\n endpointMap: { [key: string]: string },\n endpoint: string\n ): string {\n if (!$dara.isNull(endpoint)) {\n return endpoint;\n }\n\n if (!$dara.isNull(endpointMap) && !$dara.isNull(endpointMap[regionId])) {\n return endpointMap[regionId];\n }\n\n return OpenApiUtil.getEndpointRules(\n productId,\n regionId,\n endpointRule,\n network,\n suffix\n );\n }\n\n /**\n * Call MCP tool\n *\n * @param request - CallMcpToolRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns CallMcpToolResponse\n */\n async callMcpToolWithOptions(\n request: $_model.CallMcpToolRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.CallMcpToolResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.args)) {\n body[\"Args\"] = request.args;\n }\n\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.externalUserId)) {\n body[\"ExternalUserId\"] = request.externalUserId;\n }\n\n if (!$dara.isNull(request.imageId)) {\n body[\"ImageId\"] = request.imageId;\n }\n\n if (!$dara.isNull(request.name)) {\n body[\"Name\"] = request.name;\n }\n\n if (!$dara.isNull(request.server)) {\n body[\"Server\"] = request.server;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n if (!$dara.isNull(request.tool)) {\n body[\"Tool\"] = request.tool;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"CallMcpTool\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.CallMcpToolResponse>(\n await this.callApi(params, req, runtime),\n new $_model.CallMcpToolResponse({})\n );\n }\n\n /**\n * Call MCP tool\n *\n * @param request - CallMcpToolRequest\n * @returns CallMcpToolResponse\n */\n async callMcpTool(\n request: $_model.CallMcpToolRequest\n ): Promise<$_model.CallMcpToolResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.callMcpToolWithOptions(request, runtime);\n }\n\n /**\n * Create MCP session\n *\n * @param tmpReq - CreateMcpSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns CreateMcpSessionResponse\n */\n async createMcpSessionWithOptions(\n tmpReq: $_model.CreateMcpSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.CreateMcpSessionResponse> {\n tmpReq.validate();\n const request = new $_model.CreateMcpSessionShrinkRequest({});\n OpenApiUtil.convert(tmpReq, request);\n if (!$dara.isNull(tmpReq.persistenceDataList)) {\n request.persistenceDataListShrink =\n OpenApiUtil.arrayToStringWithSpecifiedStyle(\n tmpReq.persistenceDataList,\n \"PersistenceDataList\",\n \"json\"\n );\n }\n\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.externalUserId)) {\n body[\"ExternalUserId\"] = request.externalUserId;\n }\n\n if (!$dara.isNull(request.imageId)) {\n body[\"ImageId\"] = request.imageId;\n }\n\n if (!$dara.isNull(request.labels)) {\n body[\"Labels\"] = request.labels;\n }\n\n if (!$dara.isNull(request.mcpPolicyId)) {\n body[\"McpPolicyId\"] = request.mcpPolicyId;\n }\n\n if (!$dara.isNull(request.persistenceDataListShrink)) {\n body[\"PersistenceDataList\"] = request.persistenceDataListShrink;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n if (!$dara.isNull(request.vpcResource)) {\n body[\"VpcResource\"] = request.vpcResource;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"CreateMcpSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.CreateMcpSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.CreateMcpSessionResponse({})\n );\n }\n\n /**\n * Create MCP session\n *\n * @param request - CreateMcpSessionRequest\n * @returns CreateMcpSessionResponse\n */\n async createMcpSession(\n request: $_model.CreateMcpSessionRequest\n ): Promise<$_model.CreateMcpSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.createMcpSessionWithOptions(request, runtime);\n }\n\n /**\n * Delete persistent context\n *\n * @param request - DeleteContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns DeleteContextResponse\n */\n async deleteContextWithOptions(\n request: $_model.DeleteContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.DeleteContextResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.id)) {\n body[\"Id\"] = request.id;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"DeleteContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.DeleteContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.DeleteContextResponse({})\n );\n }\n\n /**\n * Delete persistent context\n *\n * @param request - DeleteContextRequest\n * @returns DeleteContextResponse\n */\n async deleteContext(\n request: $_model.DeleteContextRequest\n ): Promise<$_model.DeleteContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.deleteContextWithOptions(request, runtime);\n }\n\n /**\n * Get context\n *\n * @param request - GetContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextResponse\n */\n async getContextWithOptions(\n request: $_model.GetContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.allowCreate)) {\n body[\"AllowCreate\"] = request.allowCreate;\n }\n\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.name)) {\n body[\"Name\"] = request.name;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextResponse({})\n );\n }\n\n /**\n * Get context\n *\n * @param request - GetContextRequest\n * @returns GetContextResponse\n */\n async getContext(\n request: $_model.GetContextRequest\n ): Promise<$_model.GetContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextWithOptions(request, runtime);\n }\n\n /**\n * Get context information\n *\n * @param request - GetContextInfoRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextInfoResponse\n */\n async getContextInfoWithOptions(\n request: $_model.GetContextInfoRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextInfoResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.path)) {\n body[\"Path\"] = request.path;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n if (!$dara.isNull(request.taskType)) {\n body[\"TaskType\"] = request.taskType;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContextInfo\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextInfoResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextInfoResponse({})\n );\n }\n\n /**\n * Get context information\n *\n * @param request - GetContextInfoRequest\n * @returns GetContextInfoResponse\n */\n async getContextInfo(\n request: $_model.GetContextInfoRequest\n ): Promise<$_model.GetContextInfoResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextInfoWithOptions(request, runtime);\n }\n\n /**\n * Get labels\n *\n * @param request - GetLabelRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetLabelResponse\n */\n async getLabelWithOptions(\n request: $_model.GetLabelRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetLabelResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.maxResults)) {\n body[\"MaxResults\"] = request.maxResults;\n }\n\n if (!$dara.isNull(request.nextToken)) {\n body[\"NextToken\"] = request.nextToken;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetLabel\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetLabelResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetLabelResponse({})\n );\n }\n\n /**\n * Get labels\n *\n * @param request - GetLabelRequest\n * @returns GetLabelResponse\n */\n async getLabel(\n request: $_model.GetLabelRequest\n ): Promise<$_model.GetLabelResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getLabelWithOptions(request, runtime);\n }\n\n /**\n * Get session information\n *\n * @param request - GetSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetSessionResponse\n */\n async getSessionWithOptions(\n request: $_model.GetSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetSessionResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetSessionResponse({})\n );\n }\n\n /**\n * Get session information\n *\n * @param request - GetSessionRequest\n * @returns GetSessionResponse\n */\n async getSession(\n request: $_model.GetSessionRequest\n ): Promise<$_model.GetSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getSessionWithOptions(request, runtime);\n }\n\n /**\n * Get forwarding link for specific port\n *\n * @param request - GetLinkRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetLinkResponse\n */\n async getLinkWithOptions(\n request: $_model.GetLinkRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetLinkResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.port)) {\n body[\"Port\"] = request.port;\n }\n\n if (!$dara.isNull(request.protocolType)) {\n body[\"ProtocolType\"] = request.protocolType;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetLink\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetLinkResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetLinkResponse({})\n );\n }\n\n /**\n * Get forwarding link for specific port\n *\n * @param request - GetLinkRequest\n * @returns GetLinkResponse\n */\n async getLink(\n request: $_model.GetLinkRequest\n ): Promise<$_model.GetLinkResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getLinkWithOptions(request, runtime);\n }\n\n /**\n * Get MCP resource information\n *\n * @param request - GetMcpResourceRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetMcpResourceResponse\n */\n async getMcpResourceWithOptions(\n request: $_model.GetMcpResourceRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetMcpResourceResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetMcpResource\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetMcpResourceResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetMcpResourceResponse({})\n );\n }\n\n /**\n * Get MCP resource information\n *\n * @param request - GetMcpResourceRequest\n * @returns GetMcpResourceResponse\n */\n async getMcpResource(\n request: $_model.GetMcpResourceRequest\n ): Promise<$_model.GetMcpResourceResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getMcpResourceWithOptions(request, runtime);\n }\n\n /**\n * Get context list\n *\n * @param request - ListContextsRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ListContextsResponse\n */\n async listContextsWithOptions(\n request: $_model.ListContextsRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ListContextsResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.maxResults)) {\n body[\"MaxResults\"] = request.maxResults;\n }\n\n if (!$dara.isNull(request.nextToken)) {\n body[\"NextToken\"] = request.nextToken;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ListContexts\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ListContextsResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ListContextsResponse({})\n );\n }\n\n /**\n * Get context list\n *\n * @param request - ListContextsRequest\n * @returns ListContextsResponse\n */\n async listContexts(\n request: $_model.ListContextsRequest\n ): Promise<$_model.ListContextsResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.listContextsWithOptions(request, runtime);\n }\n\n /**\n * ListMcpTools\n *\n * @param request - ListMcpToolsRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ListMcpToolsResponse\n */\n async listMcpToolsWithOptions(\n request: $_model.ListMcpToolsRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ListMcpToolsResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.imageId)) {\n body[\"ImageId\"] = request.imageId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ListMcpTools\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ListMcpToolsResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ListMcpToolsResponse({})\n );\n }\n\n /**\n * ListMcpTools\n *\n * @param request - ListMcpToolsRequest\n * @returns ListMcpToolsResponse\n */\n async listMcpTools(\n request: $_model.ListMcpToolsRequest\n ): Promise<$_model.ListMcpToolsResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.listMcpToolsWithOptions(request, runtime);\n }\n\n /**\n * Query session list by label\n *\n * @param request - ListSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ListSessionResponse\n */\n async listSessionWithOptions(\n request: $_model.ListSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ListSessionResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.labels)) {\n body[\"Labels\"] = request.labels;\n }\n\n if (!$dara.isNull(request.maxResults)) {\n body[\"MaxResults\"] = request.maxResults;\n }\n\n if (!$dara.isNull(request.nextToken)) {\n body[\"NextToken\"] = request.nextToken;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ListSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ListSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ListSessionResponse({})\n );\n }\n\n /**\n * Query session list by label\n *\n * @param request - ListSessionRequest\n * @returns ListSessionResponse\n */\n async listSession(\n request: $_model.ListSessionRequest\n ): Promise<$_model.ListSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.listSessionWithOptions(request, runtime);\n }\n\n /**\n * Modify context\n *\n * @param request - ModifyContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ModifyContextResponse\n */\n async modifyContextWithOptions(\n request: $_model.ModifyContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ModifyContextResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.id)) {\n body[\"Id\"] = request.id;\n }\n\n if (!$dara.isNull(request.name)) {\n body[\"Name\"] = request.name;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ModifyContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ModifyContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ModifyContextResponse({})\n );\n }\n\n /**\n * Modify context\n *\n * @param request - ModifyContextRequest\n * @returns ModifyContextResponse\n */\n async modifyContext(\n request: $_model.ModifyContextRequest\n ): Promise<$_model.ModifyContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.modifyContextWithOptions(request, runtime);\n }\n\n /**\n * Release MCP session\n *\n * @param request - ReleaseMcpSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ReleaseMcpSessionResponse\n */\n async releaseMcpSessionWithOptions(\n request: $_model.ReleaseMcpSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ReleaseMcpSessionResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ReleaseMcpSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ReleaseMcpSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ReleaseMcpSessionResponse({})\n );\n }\n\n /**\n * Release MCP session\n *\n * @param request - ReleaseMcpSessionRequest\n * @returns ReleaseMcpSessionResponse\n */\n async releaseMcpSession(\n request: $_model.ReleaseMcpSessionRequest\n ): Promise<$_model.ReleaseMcpSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.releaseMcpSessionWithOptions(request, runtime);\n }\n\n /**\n * Set labels\n *\n * @param request - SetLabelRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns SetLabelResponse\n */\n async setLabelWithOptions(\n request: $_model.SetLabelRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.SetLabelResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.labels)) {\n body[\"Labels\"] = request.labels;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"SetLabel\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.SetLabelResponse>(\n await this.callApi(params, req, runtime),\n new $_model.SetLabelResponse({})\n );\n }\n\n /**\n * Set labels\n *\n * @param request - SetLabelRequest\n * @returns SetLabelResponse\n */\n async setLabel(\n request: $_model.SetLabelRequest\n ): Promise<$_model.SetLabelResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.setLabelWithOptions(request, runtime);\n }\n\n /**\n * Sync context\n *\n * @param request - SyncContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns SyncContextResponse\n */\n async syncContextWithOptions(\n request: $_model.SyncContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.SyncContextResponse> {\n request.validate();\n const query: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n query[\"Authorization\"] = request.authorization;\n }\n\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.mode)) {\n body[\"Mode\"] = request.mode;\n }\n\n if (!$dara.isNull(request.path)) {\n body[\"Path\"] = request.path;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n query: OpenApiUtil.query(query),\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"SyncContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.SyncContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.SyncContextResponse({})\n );\n }\n\n /**\n * Sync context\n *\n * @param request - SyncContextRequest\n * @returns SyncContextResponse\n */\n async syncContext(\n request: $_model.SyncContextRequest\n ): Promise<$_model.SyncContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.syncContextWithOptions(request, runtime);\n }\n\n /**\n * Initialize browser\n *\n * @param tmpReq - InitBrowserRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns InitBrowserResponse\n */\n async initBrowserWithOptions(\n request: $_model.InitBrowserRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.InitBrowserResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n if (!$dara.isNull(request.persistentPath)) {\n body[\"PersistentPath\"] = request.persistentPath;\n }\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n if (!$dara.isNull(request.browserOption)) {\n body[\"BrowserOption\"] = JSON.stringify(request.browserOption);\n }\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"InitBrowser\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.InitBrowserResponse>(\n await this.callApi(params, req, runtime),\n new $_model.InitBrowserResponse({})\n );\n }\n\n /**\n * Initialize browser\n *\n * @param request - InitBrowserRequest\n * @returns InitBrowserResponse\n */\n async initBrowser(\n request: $_model.InitBrowserRequest\n ): Promise<$_model.InitBrowserResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.initBrowserWithOptions(request, runtime);\n }\n\n /**\n * Initialize browser (sync version)\n *\n * @param request - InitBrowserRequest\n * @returns InitBrowserResponse\n */\n initBrowserSync(\n request: $_model.InitBrowserRequest\n ): $_model.InitBrowserResponse {\n const runtime = new $dara.RuntimeOptions({});\n \n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n if (!$dara.isNull(request.persistentPath)) {\n body[\"PersistentPath\"] = request.persistentPath;\n }\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n if (!$dara.isNull(request.browserOption)) {\n body[\"BrowserOption\"] = JSON.stringify(request.browserOption);\n }\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"InitBrowser\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.InitBrowserResponse>(\n this.callApi(params, req, runtime),\n new $_model.InitBrowserResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - DeleteContextFileRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns DeleteContextFileResponse\n */\n async deleteContextFileWithOptions(\n request: $_model.DeleteContextFileRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.DeleteContextFileResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.filePath)) {\n body[\"FilePath\"] = request.filePath;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"DeleteContextFile\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.DeleteContextFileResponse>(\n await this.callApi(params, req, runtime),\n new $_model.DeleteContextFileResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - DeleteContextFileRequest\n * @returns DeleteContextFileResponse\n */\n async deleteContextFile(\n request: $_model.DeleteContextFileRequest\n ): Promise<$_model.DeleteContextFileResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.deleteContextFileWithOptions(request, runtime);\n }\n\n /**\n * Query context specific directory files\n *\n * @param request - DescribeContextFilesRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns DescribeContextFilesResponse\n */\n async describeContextFilesWithOptions(\n request: $_model.DescribeContextFilesRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.DescribeContextFilesResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.pageNumber)) {\n body[\"PageNumber\"] = request.pageNumber;\n }\n\n if (!$dara.isNull(request.pageSize)) {\n body[\"PageSize\"] = request.pageSize;\n }\n\n if (!$dara.isNull(request.parentFolderPath)) {\n body[\"ParentFolderPath\"] = request.parentFolderPath;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"DescribeContextFiles\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.DescribeContextFilesResponse>(\n await this.callApi(params, req, runtime),\n new $_model.DescribeContextFilesResponse({})\n );\n }\n\n /**\n * Query context specific directory files\n *\n * @param request - DescribeContextFilesRequest\n * @returns DescribeContextFilesResponse\n */\n async describeContextFiles(\n request: $_model.DescribeContextFilesRequest\n ): Promise<$_model.DescribeContextFilesResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.describeContextFilesWithOptions(request, runtime);\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileDownloadUrlRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextFileDownloadUrlResponse\n */\n async getContextFileDownloadUrlWithOptions(\n request: $_model.GetContextFileDownloadUrlRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextFileDownloadUrlResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.filePath)) {\n body[\"FilePath\"] = request.filePath;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContextFileDownloadUrl\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextFileDownloadUrlResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextFileDownloadUrlResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileDownloadUrlRequest\n * @returns GetContextFileDownloadUrlResponse\n */\n async getContextFileDownloadUrl(\n request: $_model.GetContextFileDownloadUrlRequest\n ): Promise<$_model.GetContextFileDownloadUrlResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextFileDownloadUrlWithOptions(request, runtime);\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileUploadUrlRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextFileUploadUrlResponse\n */\n async getContextFileUploadUrlWithOptions(\n request: $_model.GetContextFileUploadUrlRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextFileUploadUrlResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.filePath)) {\n body[\"FilePath\"] = request.filePath;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContextFileUploadUrl\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextFileUploadUrlResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextFileUploadUrlResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileUploadUrlRequest\n * @returns GetContextFileUploadUrlResponse\n */\n async getContextFileUploadUrl(\n request: $_model.GetContextFileUploadUrlRequest\n ): Promise<$_model.GetContextFileUploadUrlResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextFileUploadUrlWithOptions(request, runtime);\n }\n}\n","export { ApplyMqttTokenResponseBodyData } from './ApplyMqttTokenResponseBodyData';\nexport { CreateMcpSessionRequestPersistenceDataList } from './CreateMcpSessionRequestPersistenceDataList';\nexport { CreateMcpSessionResponseBodyData } from './CreateMcpSessionResponseBodyData';\nexport { GetContextResponseBodyData } from './GetContextResponseBodyData';\nexport { GetContextInfoResponseBodyData } from './GetContextInfoResponseBodyData';\nexport { GetLabelResponseBodyData } from './GetLabelResponseBodyData';\nexport { GetSessionResponseBodyData } from './GetSessionResponseBodyData';\nexport { GetLinkResponseBodyData } from './GetLinkResponseBodyData';\nexport { GetMcpResourceResponseBodyDataDesktopInfo } from './GetMcpResourceResponseBodyDataDesktopInfo';\nexport { GetMcpResourceResponseBodyData } from './GetMcpResourceResponseBodyData';\nexport { ListContextsResponseBodyData } from './ListContextsResponseBodyData';\nexport { ListSessionResponseBodyData } from './ListSessionResponseBodyData';\nexport { ApplyMqttTokenRequest } from './ApplyMqttTokenRequest';\nexport { ApplyMqttTokenResponseBody } from './ApplyMqttTokenResponseBody';\nexport { ApplyMqttTokenResponse } from './ApplyMqttTokenResponse';\nexport { CallMcpToolRequest } from './CallMcpToolRequest';\nexport { CallMcpToolResponseBody } from './CallMcpToolResponseBody';\nexport { CallMcpToolResponse } from './CallMcpToolResponse';\nexport { CreateMcpSessionRequest } from './CreateMcpSessionRequest';\nexport { CreateMcpSessionShrinkRequest } from './CreateMcpSessionShrinkRequest';\nexport { CreateMcpSessionResponseBody } from './CreateMcpSessionResponseBody';\nexport { CreateMcpSessionResponse } from './CreateMcpSessionResponse';\nexport { DeleteContextRequest } from './DeleteContextRequest';\nexport { DeleteContextResponseBody } from './DeleteContextResponseBody';\nexport { DeleteContextResponse } from './DeleteContextResponse';\nexport { GetContextRequest } from './GetContextRequest';\nexport { GetContextResponseBody } from './GetContextResponseBody';\nexport { GetContextResponse } from './GetContextResponse';\nexport { GetContextInfoRequest } from './GetContextInfoRequest';\nexport { GetContextInfoResponseBody } from './GetContextInfoResponseBody';\nexport { GetContextInfoResponse } from './GetContextInfoResponse';\nexport { GetLabelRequest } from './GetLabelRequest';\nexport { GetLabelResponseBody } from './GetLabelResponseBody';\nexport { GetLabelResponse } from './GetLabelResponse';\nexport { GetSessionRequest } from './GetSessionRequest';\nexport { GetSessionResponseBody } from './GetSessionResponseBody';\nexport { GetSessionResponse } from './GetSessionResponse';\nexport { GetLinkRequest } from './GetLinkRequest';\nexport { GetLinkResponseBody } from './GetLinkResponseBody';\nexport { GetLinkResponse } from './GetLinkResponse';\nexport { GetMcpResourceRequest } from './GetMcpResourceRequest';\nexport { GetMcpResourceResponseBody } from './GetMcpResourceResponseBody';\nexport { GetMcpResourceResponse } from './GetMcpResourceResponse';\nexport { InitBrowserRequest } from './InitBrowserRequest';\nexport { InitBrowserResponseBody } from './InitBrowserResponseBody';\nexport { InitBrowserResponseBodyData } from './InitBrowserResponseBodyData';\nexport { InitBrowserResponse } from './InitBrowserResponse';\nexport { ListContextsRequest } from './ListContextsRequest';\nexport { ListContextsResponseBody } from './ListContextsResponseBody';\nexport { ListContextsResponse } from './ListContextsResponse';\nexport { ListMcpToolsRequest } from './ListMcpToolsRequest';\nexport { ListMcpToolsResponseBody } from './ListMcpToolsResponseBody';\nexport { ListMcpToolsResponse } from './ListMcpToolsResponse';\nexport { ListSessionRequest } from './ListSessionRequest';\nexport { ListSessionResponseBody } from './ListSessionResponseBody';\nexport { ListSessionResponse } from './ListSessionResponse';\nexport { ModifyContextRequest } from './ModifyContextRequest';\nexport { ModifyContextResponseBody } from './ModifyContextResponseBody';\nexport { ModifyContextResponse } from './ModifyContextResponse';\nexport { ReleaseMcpSessionRequest } from './ReleaseMcpSessionRequest';\nexport { ReleaseMcpSessionResponseBody } from './ReleaseMcpSessionResponseBody';\nexport { ReleaseMcpSessionResponse } from './ReleaseMcpSessionResponse';\nexport { SetLabelRequest } from './SetLabelRequest';\nexport { SetLabelResponseBody } from './SetLabelResponseBody';\nexport { SetLabelResponse } from './SetLabelResponse';\nexport { SyncContextRequest } from './SyncContextRequest';\nexport { SyncContextResponseBody } from './SyncContextResponseBody';\nexport { SyncContextResponse } from './SyncContextResponse';\n// New context file operations\nexport { DeleteContextFileRequest } from './DeleteContextFileRequest';\nexport { DeleteContextFileResponseBody } from './DeleteContextFileResponseBody';\nexport { DeleteContextFileResponse } from './DeleteContextFileResponse';\nexport { DescribeContextFilesRequest } from './DescribeContextFilesRequest';\nexport { DescribeContextFilesResponseBody } from './DescribeContextFilesResponseBody';\nexport { DescribeContextFilesResponse } from './DescribeContextFilesResponse';\nexport { GetContextFileDownloadUrlRequest } from './GetContextFileDownloadUrlRequest';\nexport { GetContextFileDownloadUrlResponseBody } from './GetContextFileDownloadUrlResponseBody';\nexport { GetContextFileDownloadUrlResponse } from './GetContextFileDownloadUrlResponse';\nexport { GetContextFileUploadUrlRequest } from './GetContextFileUploadUrlRequest';\nexport { GetContextFileUploadUrlResponseBody } from './GetContextFileUploadUrlResponseBody';\nexport { GetContextFileUploadUrlResponse } from './GetContextFileUploadUrlResponse';\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\n/**\n */\nexport class ApplyMqttTokenResponseBodyData extends $dara.Model {\n accessKeyId?: string;\n clientId?: string;\n expiration?: string;\n instanceId?: string;\n regionId?: string;\n securityToken?: string;\n static names(): { [key: string]: string } {\n return {\n accessKeyId: 'AccessKeyId',\n clientId: 'ClientId',\n expiration: 'Expiration',\n instanceId: 'InstanceId',\n regionId: 'RegionId',\n securityToken: 'SecurityToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n accessKeyId: 'string',\n clientId: 'string',\n expiration: 'string',\n instanceId: 'string',\n regionId: 'string',\n securityToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CreateMcpSessionRequestPersistenceDataList extends $dara.Model {\n contextId?: string;\n path?: string;\n policy?: string;\n static names(): { [key: string]: string } {\n return {\n contextId: 'ContextId',\n path: 'Path',\n policy: 'Policy',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n contextId: 'string',\n path: 'string',\n policy: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CreateMcpSessionResponseBodyData extends $dara.Model {\n appInstanceId?: string;\n errMsg?: string;\n httpPort?: string;\n networkInterfaceIp?: string;\n resourceId?: string;\n resourceUrl?: string;\n sessionId?: string;\n success?: boolean;\n token?: string;\n vpcResource?: boolean;\n static names(): { [key: string]: string } {\n return {\n appInstanceId: 'AppInstanceId',\n errMsg: 'ErrMsg',\n httpPort: 'HttpPort',\n networkInterfaceIp: 'NetworkInterfaceIp',\n resourceId: 'ResourceId',\n resourceUrl: 'ResourceUrl',\n sessionId: 'SessionId',\n success: 'Success',\n token: 'Token',\n vpcResource: 'VpcResource',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n appInstanceId: 'string',\n errMsg: 'string',\n httpPort: 'string',\n networkInterfaceIp: 'string',\n resourceId: 'string',\n resourceUrl: 'string',\n sessionId: 'string',\n success: 'boolean',\n token: 'string',\n vpcResource: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextResponseBodyData extends $dara.Model {\n createTime?: string;\n id?: string;\n lastUsedTime?: string;\n name?: string;\n osType?: string;\n state?: string;\n static names(): { [key: string]: string } {\n return {\n createTime: 'CreateTime',\n id: 'Id',\n lastUsedTime: 'LastUsedTime',\n name: 'Name',\n osType: 'OsType',\n state: 'State',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n createTime: 'string',\n id: 'string',\n lastUsedTime: 'string',\n name: 'string',\n osType: 'string',\n state: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextInfoResponseBodyData extends $dara.Model {\n contextStatus?: string;\n static names(): { [key: string]: string } {\n return {\n contextStatus: 'ContextStatus',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n contextStatus: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLabelResponseBodyData extends $dara.Model {\n labels?: string;\n static names(): { [key: string]: string } {\n return {\n labels: 'Labels',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n labels: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetSessionResponseBodyData extends $dara.Model {\n appInstanceId?: string;\n resourceId?: string;\n sessionId?: string;\n success?: boolean;\n httpPort?: string;\n networkInterfaceIp?: string;\n token?: string;\n vpcResource?: boolean;\n resourceUrl?: string;\n static names(): { [key: string]: string } {\n return {\n appInstanceId: 'AppInstanceId',\n resourceId: 'ResourceId',\n sessionId: 'SessionId',\n success: 'Success',\n httpPort: 'HttpPort',\n networkInterfaceIp: 'NetworkInterfaceIp',\n token: 'Token',\n vpcResource: 'VpcResource',\n resourceUrl: 'ResourceUrl',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n appInstanceId: 'string',\n resourceId: 'string',\n sessionId: 'string',\n success: 'boolean',\n httpPort: 'string',\n networkInterfaceIp: 'string',\n token: 'string',\n vpcResource: 'boolean',\n resourceUrl: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLinkResponseBodyData extends $dara.Model {\n url?: string;\n static names(): { [key: string]: string } {\n return {\n url: 'Url',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n url: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetMcpResourceResponseBodyDataDesktopInfo extends $dara.Model {\n appId?: string;\n authCode?: string;\n connectionProperties?: string;\n resourceId?: string;\n resourceType?: string;\n ticket?: string;\n static names(): { [key: string]: string } {\n return {\n appId: 'AppId',\n authCode: 'AuthCode',\n connectionProperties: 'ConnectionProperties',\n resourceId: 'ResourceId',\n resourceType: 'ResourceType',\n ticket: 'Ticket',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n appId: 'string',\n authCode: 'string',\n connectionProperties: 'string',\n resourceId: 'string',\n resourceType: 'string',\n ticket: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetMcpResourceResponseBodyDataDesktopInfo } from \"./GetMcpResourceResponseBodyDataDesktopInfo\";\n\n\nexport class GetMcpResourceResponseBodyData extends $dara.Model {\n desktopInfo?: GetMcpResourceResponseBodyDataDesktopInfo;\n resourceUrl?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n desktopInfo: 'DesktopInfo',\n resourceUrl: 'ResourceUrl',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n desktopInfo: GetMcpResourceResponseBodyDataDesktopInfo,\n resourceUrl: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n if(this.desktopInfo && typeof (this.desktopInfo as any).validate === 'function') {\n (this.desktopInfo as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListContextsResponseBodyData extends $dara.Model {\n createTime?: string;\n id?: string;\n lastUsedTime?: string;\n name?: string;\n osType?: string;\n state?: string;\n static names(): { [key: string]: string } {\n return {\n createTime: 'CreateTime',\n id: 'Id',\n lastUsedTime: 'LastUsedTime',\n name: 'Name',\n osType: 'OsType',\n state: 'State',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n createTime: 'string',\n id: 'string',\n lastUsedTime: 'string',\n name: 'string',\n osType: 'string',\n state: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListSessionResponseBodyData extends $dara.Model {\n sessionId?: string;\n sessionStatus?: string;\n static names(): { [key: string]: string } {\n return {\n sessionId: 'SessionId',\n sessionStatus: 'SessionStatus',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n sessionId: 'string',\n sessionStatus: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ApplyMqttTokenRequest extends $dara.Model {\n desktopId?: string;\n sessionToken?: string;\n static names(): { [key: string]: string } {\n return {\n desktopId: 'DesktopId',\n sessionToken: 'SessionToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n desktopId: 'string',\n sessionToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ApplyMqttTokenResponseBodyData } from \"./ApplyMqttTokenResponseBodyData\";\n\n\nexport class ApplyMqttTokenResponseBody extends $dara.Model {\n code?: string;\n data?: ApplyMqttTokenResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: ApplyMqttTokenResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ApplyMqttTokenResponseBody } from \"./ApplyMqttTokenResponseBody\";\n\n\nexport class ApplyMqttTokenResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ApplyMqttTokenResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ApplyMqttTokenResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CallMcpToolRequest extends $dara.Model {\n args?: string;\n authorization?: string;\n externalUserId?: string;\n imageId?: string;\n name?: string;\n server?: string;\n sessionId?: string;\n tool?: string;\n static names(): { [key: string]: string } {\n return {\n args: 'Args',\n authorization: 'Authorization',\n externalUserId: 'ExternalUserId',\n imageId: 'ImageId',\n name: 'Name',\n server: 'Server',\n sessionId: 'SessionId',\n tool: 'Tool',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n args: 'string',\n authorization: 'string',\n externalUserId: 'string',\n imageId: 'string',\n name: 'string',\n server: 'string',\n sessionId: 'string',\n tool: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CallMcpToolResponseBody extends $dara.Model {\n code?: string;\n data?: any;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: 'any',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CallMcpToolResponseBody } from \"./CallMcpToolResponseBody\";\n\n\nexport class CallMcpToolResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: CallMcpToolResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: CallMcpToolResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CreateMcpSessionRequestPersistenceDataList } from \"./CreateMcpSessionRequestPersistenceDataList\";\n\n\nexport class CreateMcpSessionRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n externalUserId?: string;\n imageId?: string;\n labels?: string;\n mcpPolicyId?: string;\n persistenceDataList?: CreateMcpSessionRequestPersistenceDataList[];\n sessionId?: string;\n vpcResource?: boolean;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n externalUserId: 'ExternalUserId',\n imageId: 'ImageId',\n labels: 'Labels',\n mcpPolicyId: 'McpPolicyId',\n persistenceDataList: 'PersistenceDataList',\n sessionId: 'SessionId',\n vpcResource: 'VpcResource',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n externalUserId: 'string',\n imageId: 'string',\n labels: 'string',\n mcpPolicyId: 'string',\n persistenceDataList: { 'type': 'array', 'itemType': CreateMcpSessionRequestPersistenceDataList },\n sessionId: 'string',\n vpcResource: 'boolean',\n };\n }\n\n validate() {\n if(Array.isArray(this.persistenceDataList)) {\n $dara.Model.validateArray(this.persistenceDataList);\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CreateMcpSessionShrinkRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n externalUserId?: string;\n imageId?: string;\n labels?: string;\n mcpPolicyId?: string;\n persistenceDataListShrink?: string;\n sessionId?: string;\n vpcResource?: boolean;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n externalUserId: 'ExternalUserId',\n imageId: 'ImageId',\n labels: 'Labels',\n mcpPolicyId: 'McpPolicyId',\n persistenceDataListShrink: 'PersistenceDataList',\n sessionId: 'SessionId',\n vpcResource: 'VpcResource',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n externalUserId: 'string',\n imageId: 'string',\n labels: 'string',\n mcpPolicyId: 'string',\n persistenceDataListShrink: 'string',\n sessionId: 'string',\n vpcResource: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CreateMcpSessionResponseBodyData } from \"./CreateMcpSessionResponseBodyData\";\n\n\nexport class CreateMcpSessionResponseBody extends $dara.Model {\n code?: string;\n data?: CreateMcpSessionResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: CreateMcpSessionResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CreateMcpSessionResponseBody } from \"./CreateMcpSessionResponseBody\";\n\n\nexport class CreateMcpSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: CreateMcpSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: CreateMcpSessionResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class DeleteContextRequest extends $dara.Model {\n authorization?: string;\n id?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n id: 'Id',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n id: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class DeleteContextResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { DeleteContextResponseBody } from \"./DeleteContextResponseBody\";\n\n\nexport class DeleteContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: DeleteContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: DeleteContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextRequest extends $dara.Model {\n allowCreate?: boolean;\n authorization?: string;\n name?: string;\n static names(): { [key: string]: string } {\n return {\n allowCreate: 'AllowCreate',\n authorization: 'Authorization',\n name: 'Name',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n allowCreate: 'boolean',\n authorization: 'string',\n name: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextResponseBodyData } from \"./GetContextResponseBodyData\";\n\n\nexport class GetContextResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextResponseBody } from \"./GetContextResponseBody\";\n\n\nexport class GetContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextInfoRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n path?: string;\n sessionId?: string;\n taskType?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n path: 'Path',\n sessionId: 'SessionId',\n taskType: 'TaskType',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n path: 'string',\n sessionId: 'string',\n taskType: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextInfoResponseBodyData } from \"./GetContextInfoResponseBodyData\";\n\n\nexport class GetContextInfoResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextInfoResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextInfoResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextInfoResponseBody } from \"./GetContextInfoResponseBody\";\n\n\nexport class GetContextInfoResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextInfoResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetContextInfoResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLabelRequest extends $dara.Model {\n authorization?: string;\n maxResults?: number;\n nextToken?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n maxResults: 'MaxResults',\n nextToken: 'NextToken',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n maxResults: 'number',\n nextToken: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLabelResponseBodyData } from \"./GetLabelResponseBodyData\";\n\n\nexport class GetLabelResponseBody extends $dara.Model {\n code?: string;\n data?: GetLabelResponseBodyData;\n httpStatusCode?: number;\n maxResults?: number;\n message?: string;\n nextToken?: string;\n requestId?: string;\n success?: boolean;\n totalCount?: number;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n maxResults: 'MaxResults',\n message: 'Message',\n nextToken: 'NextToken',\n requestId: 'RequestId',\n success: 'Success',\n totalCount: 'TotalCount',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetLabelResponseBodyData,\n httpStatusCode: 'number',\n maxResults: 'number',\n message: 'string',\n nextToken: 'string',\n requestId: 'string',\n success: 'boolean',\n totalCount: 'number',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLabelResponseBody } from \"./GetLabelResponseBody\";\n\n\nexport class GetLabelResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetLabelResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetLabelResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetSessionRequest extends $dara.Model {\n authorization?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetSessionResponseBodyData } from \"./GetSessionResponseBodyData\";\n\n\nexport class GetSessionResponseBody extends $dara.Model {\n code?: string;\n data?: GetSessionResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetSessionResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetSessionResponseBody } from \"./GetSessionResponseBody\";\n\n\nexport class GetSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetSessionResponseBody,\n };\n }\n\n validate() {\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLinkRequest extends $dara.Model {\n authorization?: string;\n port?: number;\n protocolType?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n port: 'Port',\n protocolType: 'ProtocolType',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n port: 'number',\n protocolType: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLinkResponseBodyData } from \"./GetLinkResponseBodyData\";\n\n\nexport class GetLinkResponseBody extends $dara.Model {\n code?: string;\n data?: GetLinkResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetLinkResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLinkResponseBody } from \"./GetLinkResponseBody\";\n\n\nexport class GetLinkResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetLinkResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetLinkResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetMcpResourceRequest extends $dara.Model {\n authorization?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetMcpResourceResponseBodyData } from \"./GetMcpResourceResponseBodyData\";\n\n\nexport class GetMcpResourceResponseBody extends $dara.Model {\n code?: string;\n data?: GetMcpResourceResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetMcpResourceResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetMcpResourceResponseBody } from \"./GetMcpResourceResponseBody\";\n\n\nexport class GetMcpResourceResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetMcpResourceResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetMcpResourceResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class InitBrowserRequest extends $dara.Model {\n authorization?: string;\n persistentPath?: string;\n sessionId?: string;\n browserOption?: { [key: string]: any };\n \n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n persistentPath: 'PersistentPath',\n sessionId: 'SessionId',\n browserOption: 'BrowserOption',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n persistentPath: 'string',\n sessionId: 'string',\n browserOption: { 'type': 'map', 'keyType': 'string', 'valueType': 'any' },\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserRequest {\n return $dara.cast<InitBrowserRequest>(m, new InitBrowserRequest());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { InitBrowserResponseBodyData } from './InitBrowserResponseBodyData';\n\nexport class InitBrowserResponseBody extends $dara.Model {\n code?: string;\n data?: InitBrowserResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n \n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: InitBrowserResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserResponseBody {\n return $dara.cast<InitBrowserResponseBody>(m, new InitBrowserResponseBody());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class InitBrowserResponseBodyData extends $dara.Model {\n port?: number;\n \n static names(): { [key: string]: string } {\n return {\n port: 'Port',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n port: 'number',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserResponseBodyData {\n return $dara.cast<InitBrowserResponseBodyData>(m, new InitBrowserResponseBodyData());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { InitBrowserResponseBody } from './InitBrowserResponseBody';\n\nexport class InitBrowserResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: InitBrowserResponseBody;\n \n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: InitBrowserResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserResponse {\n return $dara.cast<InitBrowserResponse>(m, new InitBrowserResponse());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListContextsRequest extends $dara.Model {\n authorization?: string;\n maxResults?: number;\n nextToken?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n maxResults: 'MaxResults',\n nextToken: 'NextToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n maxResults: 'number',\n nextToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListContextsResponseBodyData } from \"./ListContextsResponseBodyData\";\n\n\nexport class ListContextsResponseBody extends $dara.Model {\n code?: string;\n data?: ListContextsResponseBodyData[];\n httpStatusCode?: number;\n maxResults?: number;\n message?: string;\n nextToken?: string;\n requestId?: string;\n success?: boolean;\n totalCount?: number;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n maxResults: 'MaxResults',\n message: 'Message',\n nextToken: 'NextToken',\n requestId: 'RequestId',\n success: 'Success',\n totalCount: 'TotalCount',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: { 'type': 'array', 'itemType': ListContextsResponseBodyData },\n httpStatusCode: 'number',\n maxResults: 'number',\n message: 'string',\n nextToken: 'string',\n requestId: 'string',\n success: 'boolean',\n totalCount: 'number',\n };\n }\n\n validate() {\n if(Array.isArray(this.data)) {\n $dara.Model.validateArray(this.data);\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListContextsResponseBody } from \"./ListContextsResponseBody\";\n\n\nexport class ListContextsResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ListContextsResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ListContextsResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListMcpToolsRequest extends $dara.Model {\n authorization?: string;\n imageId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n imageId: 'ImageId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n imageId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListMcpToolsResponseBody extends $dara.Model {\n code?: string;\n data?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListMcpToolsResponseBody } from \"./ListMcpToolsResponseBody\";\n\n\nexport class ListMcpToolsResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ListMcpToolsResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ListMcpToolsResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListSessionRequest extends $dara.Model {\n authorization?: string;\n labels?: string;\n maxResults?: number;\n nextToken?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n labels: 'Labels',\n maxResults: 'MaxResults',\n nextToken: 'NextToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n labels: 'string',\n maxResults: 'number',\n nextToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListSessionResponseBodyData } from \"./ListSessionResponseBodyData\";\n\n\nexport class ListSessionResponseBody extends $dara.Model {\n code?: string;\n data?: ListSessionResponseBodyData[];\n httpStatusCode?: number;\n maxResults?: number;\n message?: string;\n nextToken?: string;\n requestId?: string;\n success?: boolean;\n totalCount?: number;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n maxResults: 'MaxResults',\n message: 'Message',\n nextToken: 'NextToken',\n requestId: 'RequestId',\n success: 'Success',\n totalCount: 'TotalCount',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: { 'type': 'array', 'itemType': ListSessionResponseBodyData },\n httpStatusCode: 'number',\n maxResults: 'number',\n message: 'string',\n nextToken: 'string',\n requestId: 'string',\n success: 'boolean',\n totalCount: 'number',\n };\n }\n\n validate() {\n if(Array.isArray(this.data)) {\n $dara.Model.validateArray(this.data);\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListSessionResponseBody } from \"./ListSessionResponseBody\";\n\n\nexport class ListSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ListSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ListSessionResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ModifyContextRequest extends $dara.Model {\n authorization?: string;\n id?: string;\n name?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n id: 'Id',\n name: 'Name',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n id: 'string',\n name: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ModifyContextResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ModifyContextResponseBody } from \"./ModifyContextResponseBody\";\n\n\nexport class ModifyContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ModifyContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ModifyContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ReleaseMcpSessionRequest extends $dara.Model {\n authorization?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ReleaseMcpSessionResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ReleaseMcpSessionResponseBody } from \"./ReleaseMcpSessionResponseBody\";\n\n\nexport class ReleaseMcpSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ReleaseMcpSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ReleaseMcpSessionResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SetLabelRequest extends $dara.Model {\n authorization?: string;\n labels?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n labels: 'Labels',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n labels: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SetLabelResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { SetLabelResponseBody } from \"./SetLabelResponseBody\";\n\n\nexport class SetLabelResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: SetLabelResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: SetLabelResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SyncContextRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n mode?: string;\n path?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n mode: 'Mode',\n path: 'Path',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n mode: 'string',\n path: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SyncContextResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { SyncContextResponseBody } from \"./SyncContextResponseBody\";\n\n\nexport class SyncContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: SyncContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: SyncContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DeleteContextFileRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n filePath?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n filePath: 'FilePath',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n filePath: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DeleteContextFileResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { DeleteContextFileResponseBody } from './DeleteContextFileResponseBody';\n\nexport class DeleteContextFileResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: DeleteContextFileResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: DeleteContextFileResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DescribeContextFilesRequest extends $dara.Model {\n authorization?: string;\n pageNumber?: number;\n pageSize?: number;\n parentFolderPath?: string;\n contextId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n pageNumber: 'PageNumber',\n pageSize: 'PageSize',\n parentFolderPath: 'ParentFolderPath',\n contextId: 'ContextId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n pageNumber: 'number',\n pageSize: 'number',\n parentFolderPath: 'string',\n contextId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DescribeContextFilesResponseBodyData extends $dara.Model {\n fileId?: string;\n fileName?: string;\n filePath?: string;\n fileType?: string;\n gmtCreate?: string;\n gmtModified?: string;\n size?: number;\n status?: string;\n static names(): { [key: string]: string } {\n return {\n fileId: 'FileId',\n fileName: 'FileName',\n filePath: 'FilePath',\n fileType: 'FileType',\n gmtCreate: 'GmtCreate',\n gmtModified: 'GmtModified',\n size: 'Size',\n status: 'Status',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n fileId: 'string',\n fileName: 'string',\n filePath: 'string',\n fileType: 'string',\n gmtCreate: 'string',\n gmtModified: 'string',\n size: 'number',\n status: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\nexport class DescribeContextFilesResponseBody extends $dara.Model {\n code?: string;\n count?: number;\n data?: DescribeContextFilesResponseBodyData[];\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n count: 'Count',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n count: 'number',\n data: { type: 'array', itemType: DescribeContextFilesResponseBodyData },\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { DescribeContextFilesResponseBody } from './DescribeContextFilesResponseBody';\n\nexport class DescribeContextFilesResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: DescribeContextFilesResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: DescribeContextFilesResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileDownloadUrlRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n filePath?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n filePath: 'FilePath',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n filePath: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileDownloadUrlResponseBodyData extends $dara.Model {\n expireTime?: number;\n url?: string;\n static names(): { [key: string]: string } {\n return {\n expireTime: 'ExpireTime',\n url: 'Url',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n expireTime: 'number',\n url: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\nexport class GetContextFileDownloadUrlResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextFileDownloadUrlResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextFileDownloadUrlResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextFileDownloadUrlResponseBody } from './GetContextFileDownloadUrlResponseBody';\n\nexport class GetContextFileDownloadUrlResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextFileDownloadUrlResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: GetContextFileDownloadUrlResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileUploadUrlRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n filePath?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n filePath: 'FilePath',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n filePath: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileUploadUrlResponseBodyData extends $dara.Model {\n expireTime?: number;\n url?: string;\n static names(): { [key: string]: string } {\n return {\n expireTime: 'ExpireTime',\n url: 'Url',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n expireTime: 'number',\n url: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\nexport class GetContextFileUploadUrlResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextFileUploadUrlResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextFileUploadUrlResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextFileUploadUrlResponseBody } from './GetContextFileUploadUrlResponseBody';\n\nexport class GetContextFileUploadUrlResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextFileUploadUrlResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: GetContextFileUploadUrlResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as dotenv from \"dotenv\";\nimport { log } from \"./utils/logger\";\ninterface Config {\n endpoint: string;\n timeout_ms: number;\n}\n\n/**\n * Browser data path constant\n */\nexport const BROWSER_DATA_PATH = \"/tmp/agentbay_browser\";\n\n/**\n * Returns the default configuration\n */\nexport function defaultConfig(): Config {\n return {\n endpoint: \"wuyingai.cn-shanghai.aliyuncs.com\",\n timeout_ms: 60000,\n };\n}\n\n/**\n * Find .env file by searching upward from start_path.\n * \n * Search order:\n * 1. Current working directory\n * 2. Parent directories (up to root)\n * 3. Git repository root (if found)\n * \n * @param startPath Starting directory for search (defaults to current working directory)\n * @returns Path to .env file if found, null otherwise\n */\nexport function findDotEnvFile(startPath?: string): string | null {\n const currentPath = startPath ? path.resolve(startPath) : process.cwd();\n let searchPath = currentPath;\n\n // Search upward until we reach root directory\n while (searchPath !== path.dirname(searchPath)) {\n const envFile = path.join(searchPath, \".env\");\n if (fs.existsSync(envFile)) {\n log(`Found .env file at: ${envFile}`);\n return envFile;\n }\n\n // Check if this is a git repository root\n const gitDir = path.join(searchPath, \".git\");\n if (fs.existsSync(gitDir)) {\n log(`Found git repository root at: ${searchPath}`);\n }\n\n searchPath = path.dirname(searchPath);\n }\n\n // Check root directory as well\n const rootEnv = path.join(searchPath, \".env\");\n if (fs.existsSync(rootEnv)) {\n log(`Found .env file at root: ${rootEnv}`);\n return rootEnv;\n }\n\n return null;\n}\n\n/**\n * Load .env file with improved search strategy.\n * \n * @param customEnvPath Custom path to .env file (optional)\n */\nexport function loadDotEnvWithFallback(customEnvPath?: string): void {\n if (customEnvPath) {\n // Use custom path if provided\n if (fs.existsSync(customEnvPath)) {\n try {\n const envConfig = dotenv.parse(fs.readFileSync(customEnvPath));\n for (const k in envConfig) {\n // only load env variables that are not already set in process.env\n if (!process.env.hasOwnProperty(k)) {\n process.env[k] = envConfig[k];\n }\n }\n log(`Loaded custom .env file from: ${customEnvPath}`);\n return;\n } catch (error) {\n log(`Warning: Failed to load custom .env file ${customEnvPath}: ${error}`);\n }\n } else {\n log(`Warning: Custom .env file not found: ${customEnvPath}`);\n }\n }\n\n // Find .env file using upward search\n const envFile = findDotEnvFile();\n if (envFile) {\n try {\n const envConfig = dotenv.parse(fs.readFileSync(envFile));\n for (const k in envConfig) {\n // only load env variables that are not already set in process.env\n if (!process.env.hasOwnProperty(k)) {\n process.env[k] = envConfig[k];\n }\n }\n log(`Loaded .env file from: ${envFile}`);\n } catch (error) {\n log(`Warning: Failed to load .env file ${envFile}: ${error}`);\n }\n } else {\n log(\"No .env file found in current directory or parent directories\");\n }\n}\n\n// Track if .env file has been loaded to avoid duplicate loading\nlet dotEnvLoaded = false;\n\n/**\n * Load .env file into process.env if it exists\n * This function should be called early to ensure .env variables are available\n * @deprecated Use loadDotEnvWithFallback instead\n */\nexport function loadDotEnv(): void {\n if (dotEnvLoaded) {\n return; // Already loaded, skip\n }\n\n loadDotEnvWithFallback();\n dotEnvLoaded = true;\n}\n\n/**\n * The SDK uses the following precedence order for configuration (highest to lowest):\n * 1. Explicitly passed configuration in code.\n * 2. Environment variables.\n * 3. .env file.\n * 4. Default configuration.\n */\n/**\n * Load configuration with improved .env file search.\n * \n * @param customConfig Configuration object (if provided, skips env loading)\n * @param customEnvPath Custom path to .env file (optional)\n * @returns Configuration object\n */\nexport function loadConfig(customConfig?: Config, customEnvPath?: string): Config {\n // If custom config is provided, use it directly\n if (customConfig) {\n return customConfig;\n }\n\n // Create base config from default values\n const config = defaultConfig();\n\n // Load .env file with improved search first\n try {\n loadDotEnvWithFallback(customEnvPath);\n } catch (error) {\n log(`Warning: Failed to load .env file: ${error}`);\n }\n\n // Override with environment variables if they exist (highest priority)\n if (process.env.AGENTBAY_ENDPOINT) {\n config.endpoint = process.env.AGENTBAY_ENDPOINT;\n }\n\n if (process.env.AGENTBAY_TIMEOUT_MS) {\n const timeout = parseInt(process.env.AGENTBAY_TIMEOUT_MS, 10);\n if (!isNaN(timeout) && timeout > 0) {\n config.timeout_ms = timeout;\n } else {\n log(`Warning: Invalid AGENTBAY_TIMEOUT_MS value: ${process.env.AGENTBAY_TIMEOUT_MS}, using default`);\n }\n }\n\n return config;\n}\n\nexport { Config };\n","/**\n * Utility functions for logging in a clean format\n */\n\n/**\n * Log a message without the log prefix and file location\n * @param message The message to log\n * @param args Optional arguments to log\n */\nexport function log(message: string, ...args: any[]): void {\n // Use process.stdout.write instead of log to avoid the prefix and newline\n process.stdout.write(message + \"\\n\");\n\n // If there are additional arguments, print them on new lines with proper formatting\n if (args.length > 0) {\n for (const arg of args) {\n if (typeof arg === \"object\") {\n // For objects, format them as JSON with indentation\n process.stdout.write(JSON.stringify(arg, null, 2) + \"\\n\");\n } else {\n // For other types, just convert to string\n process.stdout.write(String(arg) + \"\\n\");\n }\n }\n }\n}\n\n/**\n * Log an error message\n * @param message The error message to log\n * @param error Optional error object\n */\nexport function logError(message: string, error?: any): void {\n process.stderr.write(`ERROR: ${message}\\n`);\n if (error) {\n if (error instanceof Error) {\n process.stderr.write(`${error.message}\\n`);\n } else if (typeof error === \"object\") {\n process.stderr.write(JSON.stringify(error, null, 2) + \"\\n\");\n } else {\n process.stderr.write(String(error) + \"\\n\");\n }\n }\n}\n","import { AgentBay } from \"./agent-bay\";\nimport { APIError } from \"./exceptions\";\nimport * as $_client from \"./api\";\nimport { log, logError } from \"./utils/logger\";\nimport {\n extractRequestId,\n ContextResult,\n ContextListResult,\n OperationResult,\n FileUrlResult,\n ContextFileListResult,\n ContextFileEntry,\n} from \"./types/api-response\";\n\n/**\n * Represents a persistent storage context in the AgentBay cloud environment.\n */\nexport class Context {\n /**\n * The unique identifier of the context.\n */\n id: string;\n\n /**\n * The name of the context.\n */\n name: string;\n\n /**\n * @deprecated This field is no longer used and will be removed in a future version.\n */\n state: string;\n\n /**\n * Date and time when the Context was created.\n */\n createdAt?: string;\n\n /**\n * Date and time when the Context was last used.\n */\n lastUsedAt?: string;\n\n /**\n * @deprecated This field is no longer used and will be removed in a future version.\n */\n osType?: string;\n\n /**\n * Initialize a Context object.\n *\n * @param id - The unique identifier of the context.\n * @param name - The name of the context.\n * @param state - **Deprecated.** This parameter is no longer used.\n * @param createdAt - Date and time when the Context was created.\n * @param lastUsedAt - Date and time when the Context was last used.\n * @param osType - **Deprecated.** This parameter is no longer used.\n */\n constructor(\n id: string,\n name: string,\n state = \"available\",\n createdAt?: string,\n lastUsedAt?: string,\n osType?: string\n ) {\n this.id = id;\n this.name = name;\n this.state = state;\n this.createdAt = createdAt;\n this.lastUsedAt = lastUsedAt;\n this.osType = osType;\n }\n}\n\n/**\n * Parameters for listing contexts with pagination support.\n */\nexport interface ContextListParams {\n /**\n * Maximum number of results per page.\n * Defaults to 10 if not specified.\n */\n maxResults?: number;\n\n /**\n * Token for the next page of results.\n */\n nextToken?: string;\n}\n\n/**\n * Provides methods to manage persistent contexts in the AgentBay cloud environment.\n */\nexport class ContextService {\n private agentBay: AgentBay;\n\n /**\n * Initialize the ContextService.\n *\n * @param agentBay - The AgentBay instance.\n */\n constructor(agentBay: AgentBay) {\n this.agentBay = agentBay;\n }\n\n /**\n * Lists all available contexts with pagination support.\n * Corresponds to Python's list() method\n *\n * @param params - Optional parameters for listing contexts.\n * @returns ContextListResult with contexts list and pagination information\n */\n async list(params?: ContextListParams): Promise<ContextListResult> {\n try {\n // Set default maxResults if not specified\n const maxResults = params?.maxResults !== undefined ? params.maxResults : 10;\n\n const request = new $_client.ListContextsRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n maxResults: maxResults,\n nextToken: params?.nextToken,\n });\n\n // Log API request\n log(\"API Call: ListContexts\");\n log(`Request: MaxResults=${maxResults}`, params?.nextToken ? `, NextToken=${params.nextToken}` : \"\");\n\n const response = await this.agentBay.getClient().listContexts(request);\n\n // Log API response\n log(`Response from ListContexts:`, response.body);\n\n // Check for API-level errors\n if (response.body?.success === false && response.body?.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n return {\n requestId: extractRequestId(response) || \"\",\n success: false,\n contexts: [],\n errorMessage,\n };\n }\n\n const contexts: Context[] = [];\n if (response.body?.data) {\n for (const contextData of response.body.data) {\n contexts.push(\n new Context(\n contextData.id || \"\",\n contextData.name || \"\",\n contextData.state || \"available\",\n contextData.createTime,\n contextData.lastUsedTime,\n contextData.osType\n )\n );\n }\n }\n\n return {\n requestId: extractRequestId(response) || \"\",\n success: true,\n contexts,\n nextToken: response.body?.nextToken,\n maxResults: response.body?.maxResults || maxResults,\n totalCount: response.body?.totalCount,\n };\n } catch (error) {\n logError(\"Error calling ListContexts:\", error);\n return {\n requestId: \"\",\n success: false,\n contexts: [],\n errorMessage: `Failed to list contexts: ${error}`,\n };\n }\n }\n\n /**\n * Gets a context by name. Optionally creates it if it doesn't exist.\n * Corresponds to Python's get() method\n *\n * @param name - The name of the context to get.\n * @param create - Whether to create the context if it doesn't exist.\n * @returns ContextResult with context data and requestId\n */\n async get(name: string, create = false): Promise<ContextResult> {\n try {\n const request = new $_client.GetContextRequest({\n name: name,\n allowCreate: create ? \"true\" : \"false\",\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n });\n\n // Log API request\n log(\"API Call: GetContext\");\n log(`Request: Name=${name}, AllowCreate=${create}`);\n\n const response = await this.agentBay.getClient().getContext(request);\n\n // Log API response\n log(`Response from GetContext:`, response.body);\n\n // Check for API-level errors\n if (response.body?.success === false && response.body?.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n return {\n requestId: extractRequestId(response) || \"\",\n success: false,\n contextId: \"\",\n context: undefined,\n errorMessage,\n };\n }\n\n const contextId = response.body?.data?.id || \"\";\n if (!contextId) {\n return {\n requestId: extractRequestId(response) || \"\",\n success: false,\n contextId: \"\",\n context: undefined,\n errorMessage: \"Context ID not found in response\",\n };\n }\n\n // Get the full context details\n const contextsResponse = await this.list();\n for (const context of contextsResponse.contexts) {\n if (context.id === contextId) {\n return {\n requestId: extractRequestId(response) || \"\",\n success: true,\n contextId,\n context,\n };\n }\n }\n\n // If we couldn't find the context in the list, create a basic one\n const context = new Context(contextId, name);\n return {\n requestId: extractRequestId(response) || \"\",\n success: true,\n contextId,\n context,\n };\n } catch (error) {\n logError(\"Error calling GetContext:\", error);\n return {\n requestId: \"\",\n success: false,\n contextId: \"\",\n context: undefined,\n errorMessage: `Failed to get context ${name}: ${error}`,\n };\n }\n }\n\n /**\n * Creates a new context with the given name.\n * Corresponds to Python's create() method\n *\n * @param name - The name for the new context.\n * @returns ContextResult with created context data and requestId\n */\n async create(name: string): Promise<ContextResult> {\n return await this.get(name, true);\n }\n\n /**\n * Updates the specified context.\n * Corresponds to Python's update() method\n *\n * @param context - The Context object to update.\n * @returns OperationResult with updated context data and requestId\n */\n async update(context: Context): Promise<OperationResult> {\n try {\n const request = new $_client.ModifyContextRequest({\n id: context.id,\n name: context.name,\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n });\n\n // Log API request\n log(\"API Call: ModifyContext\");\n log(`Request: Id=${context.id}, Name=${context.name}`);\n\n const response = await this.agentBay.getClient().modifyContext(request);\n\n // Log API response\n log(`Response from ModifyContext:`, response.body);\n\n // Check for success (matching Python logic)\n const success = response.body?.success !== false;\n const errorMessage = success\n ? \"\"\n : `[${response.body?.code || 'Unknown'}] ${response.body?.message || 'Unknown error'}`;\n\n return {\n requestId: extractRequestId(response) || \"\",\n success,\n data: success,\n errorMessage,\n };\n } catch (error) {\n logError(\"Error calling ModifyContext:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to update context ${context.id}: ${error}`,\n };\n }\n }\n\n /**\n * Deletes the specified context.\n * Corresponds to Python's delete() method\n *\n * @param context - The Context object to delete.\n * @returns OperationResult with requestId\n */\n async delete(context: Context): Promise<OperationResult> {\n try {\n const request = new $_client.DeleteContextRequest({\n id: context.id,\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n });\n\n // Log API request\n log(\"API Call: DeleteContext\");\n log(`Request: Id=${context.id}`);\n\n const response = await this.agentBay.getClient().deleteContext(request);\n\n // Log API response\n log(`Response from DeleteContext:`, response.body);\n\n // Check for success (matching Python logic)\n const success = response.body?.success !== false;\n const errorMessage = success\n ? \"\"\n : `[${response.body?.code || 'Unknown'}] ${response.body?.message || 'Unknown error'}`;\n\n return {\n requestId: extractRequestId(response) || \"\",\n success,\n data: success,\n errorMessage,\n };\n } catch (error) {\n logError(\"Error calling DeleteContext:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to delete context ${context.id}: ${error}`,\n };\n }\n }\n\n /**\n * Get a presigned upload URL for a file in a context.\n */\n async getFileUploadUrl(contextId: string, filePath: string): Promise<FileUrlResult> {\n log(\"API Call: GetContextFileUploadUrl\");\n log(`Request: ContextId=${contextId}, FilePath=${filePath}`);\n const req = new $_client.GetContextFileUploadUrlRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n contextId,\n filePath,\n });\n const resp = await this.agentBay.getClient().getContextFileUploadUrl(req);\n log(\"Response from GetContextFileUploadUrl:\", resp.body);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n return {\n requestId,\n success: false,\n url: \"\",\n expireTime: undefined,\n errorMessage: `[${body.code}] ${body.message || 'Unknown error'}`,\n };\n }\n\n const data = body?.data;\n return {\n requestId,\n success: !!(body && body.success),\n url: data?.url || \"\",\n expireTime: data?.expireTime,\n errorMessage: undefined,\n };\n }\n\n /**\n * Get a presigned download URL for a file in a context.\n */\n async getFileDownloadUrl(contextId: string, filePath: string): Promise<FileUrlResult> {\n log(\"API Call: GetContextFileDownloadUrl\");\n log(`Request: ContextId=${contextId}, FilePath=${filePath}`);\n const req = new $_client.GetContextFileDownloadUrlRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n contextId,\n filePath,\n });\n const resp = await this.agentBay.getClient().getContextFileDownloadUrl(req);\n log(\"Response from GetContextFileDownloadUrl:\", resp.body);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n return {\n requestId,\n success: false,\n url: \"\",\n expireTime: undefined,\n errorMessage: `[${body.code}] ${body.message || 'Unknown error'}`,\n };\n }\n\n const data = body?.data;\n return {\n requestId,\n success: !!(body && body.success),\n url: data?.url || \"\",\n expireTime: data?.expireTime,\n errorMessage: undefined,\n };\n }\n\n /**\n * Delete a file in a context.\n */\n async deleteFile(contextId: string, filePath: string): Promise<OperationResult> {\n log(\"API Call: DeleteContextFile\");\n log(`Request: ContextId=${contextId}, FilePath=${filePath}`);\n const req = new $_client.DeleteContextFileRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n contextId,\n filePath,\n });\n const resp = await this.agentBay.getClient().deleteContextFile(req);\n log(\"Response from DeleteContextFile:\", resp.body);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n const success = !!(body && body.success);\n\n // Check for API-level errors\n const errorMessage = success\n ? \"\"\n : `[${body?.code || 'Unknown'}] ${body?.message || 'Failed to delete file'}`;\n\n return {\n requestId,\n success,\n data: success,\n errorMessage,\n };\n }\n\n /**\n * List files under a specific folder path in a context.\n */\n async listFiles(\n contextId: string,\n parentFolderPath: string,\n pageNumber = 1,\n pageSize = 50\n ): Promise<ContextFileListResult> {\n log(\"API Call: DescribeContextFiles\");\n log(\n `Request: ContextId=${contextId}, ParentFolderPath=${parentFolderPath}, PageNumber=${pageNumber}, PageSize=${pageSize}`\n );\n const req = new $_client.DescribeContextFilesRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n pageNumber,\n pageSize,\n parentFolderPath,\n contextId,\n });\n const resp = await this.agentBay.getClient().describeContextFiles(req);\n log(\"Response from DescribeContextFiles:\", resp.body);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n return {\n requestId,\n success: false,\n entries: [],\n count: undefined,\n errorMessage: `[${body.code}] ${body.message || 'Unknown error'}`,\n };\n }\n\n const rawList = body?.data || [];\n const entries: ContextFileEntry[] = rawList.map((it: any) => ({\n fileId: it.fileId,\n fileName: it.fileName,\n filePath: it.filePath || \"\",\n fileType: it.fileType,\n gmtCreate: it.gmtCreate,\n gmtModified: it.gmtModified,\n size: it.size,\n status: it.status,\n }));\n return {\n requestId,\n success: !!(body && body.success),\n entries,\n count: body?.count,\n errorMessage: undefined,\n };\n }\n}\n","/**\n * Base interface for API responses\n */\nexport interface ApiResponse {\n /** Optional request identifier for tracking API calls */\n requestId?: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n /** Optional status code if the operation failed */\n success?: boolean;\n}\n\n/**\n * Generic interface for API responses that include data payload\n * @template T The type of the data being returned\n */\nexport interface ApiResponseWithData<T> extends ApiResponse {\n /** The actual data payload returned by the API */\n session?: T;\n data?: T;\n}\n\n/**\n * Interface for delete operation responses\n */\nexport interface DeleteResult extends ApiResponse {\n /** Whether the delete operation was successful */\n success: boolean;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for GetSession data\n */\nexport interface GetSessionData {\n /** Application instance ID */\n appInstanceId: string;\n /** Resource ID */\n resourceId: string;\n /** Session ID */\n sessionId: string;\n /** Success status */\n success: boolean;\n /** HTTP port for VPC sessions */\n httpPort: string;\n /** Network interface IP for VPC sessions */\n networkInterfaceIp: string;\n /** Token for VPC sessions */\n token: string;\n /** Whether this session uses VPC resources */\n vpcResource: boolean;\n /** Resource URL for accessing the session */\n resourceUrl: string;\n}\n\n/**\n * Interface for GetSession operation responses\n */\nexport interface GetSessionResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** HTTP status code */\n httpStatusCode: number;\n /** Response code */\n code: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Session data */\n data?: GetSessionData;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for session creation operation responses\n * Corresponds to Python's SessionResult type\n */\nexport interface SessionResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the session creation was successful */\n success: boolean;\n /** The created session object (only present if successful) */\n session?: any; // Will be Session type, avoiding circular import\n /** Error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for operation results\n * Corresponds to Python's OperationResult type\n */\nexport interface OperationResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Optional data payload */\n data?: any;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for session info operation responses\n * Corresponds to Go's InfoResult type\n */\nexport interface InfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Session information object */\n info?: any; // Will be SessionInfo type, avoiding circular import\n}\n\n/**\n * Interface for label operation responses\n * Corresponds to Go's LabelResult type\n */\nexport interface LabelResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Labels string (JSON format) */\n labels: string;\n}\n\n/**\n * Interface for link operation responses\n * Corresponds to Go's LinkResult type\n */\nexport interface LinkResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Link string */\n link: string;\n}\n\n/**\n * Interface for process list operation responses\n * Corresponds to Python's ProcessListResult type\n */\nexport interface ProcessListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The list of process objects */\n data: any[]; // Will be Process[] type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for installed app list operation responses\n * Corresponds to Python's InstalledAppListResult type\n */\nexport interface InstalledAppListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The list of installed app objects */\n data: any[]; // Will be InstalledApp[] type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application operation responses\n * Corresponds to Python's AppOperationResult type\n */\nexport interface AppOperationResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application info operation responses\n * Corresponds to Python's AppInfoResult type\n */\nexport interface AppInfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Application information */\n appInfo: Record<string, any>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application list operation responses\n * Corresponds to Python's AppListResult type\n */\nexport interface AppListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** List of applications */\n apps: Record<string, any>[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application installation responses\n * Corresponds to Python's AppInstallResult type\n */\nexport interface AppInstallResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the installation was successful */\n success: boolean;\n /** Result description or error message */\n message: string;\n}\n\n/**\n * Interface for command execution operation responses\n * Corresponds to Python's CommandResult type\n */\nexport interface CommandResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the command execution was successful */\n success: boolean;\n /** The command output */\n output: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for code execution operation responses\n * Corresponds to Python's CodeExecutionResult type\n */\nexport interface CodeExecutionResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the code execution was successful */\n success: boolean;\n /** The execution result */\n result: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for boolean operation responses\n * Corresponds to Python's BoolResult type\n */\nexport interface BoolResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Boolean data result */\n data?: boolean;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for file info operation responses\n * Corresponds to Python's FileInfoResult type\n */\nexport interface FileInfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** File information object */\n fileInfo?: Record<string, any>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for directory list operation responses\n * Corresponds to Python's DirectoryListResult type\n */\nexport interface DirectoryListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Directory entries */\n entries: Record<string, any>[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for file content operation responses\n * Corresponds to Python's FileContentResult type\n */\nexport interface FileContentResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** File content */\n content: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for multiple file content operation responses\n * Corresponds to Python's MultipleFileContentResult type\n */\nexport interface MultipleFileContentResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Multiple file contents */\n contents: Record<string, string>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for file search operation responses\n * Corresponds to Python's FileSearchResult type\n */\nexport interface FileSearchResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Matching file paths */\n matches: string[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for OSS client creation operation responses\n * Corresponds to Python's OSSClientResult type\n */\nexport interface OSSClientResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** OSS client configuration */\n clientConfig: Record<string, any>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for OSS upload operation responses\n * Corresponds to Python's OSSUploadResult type\n */\nexport interface OSSUploadResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Result of the upload operation */\n content: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for OSS download operation responses\n * Corresponds to Python's OSSDownloadResult type\n */\nexport interface OSSDownloadResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Result of the download operation */\n content: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for UI element list operation responses\n * Corresponds to Python's UIElementListResult type\n */\nexport interface UIElementListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** UI elements */\n elements: Record<string, any>[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for window list operation responses\n * Corresponds to Python's WindowListResult type\n */\nexport interface WindowListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** List of windows */\n windows: any[]; // Will be Window[] type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for window info operation responses\n * Corresponds to Python's WindowInfoResult type\n */\nexport interface WindowInfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Window object */\n window?: any; // Will be Window type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for context operation responses\n * Corresponds to Python's ContextResult type\n */\nexport interface ContextResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The context ID */\n contextId: string;\n /** The context object (only present if successful) */\n context?: any; // Will be Context type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for context list operation responses\n * Corresponds to Python's ContextListResult type\n */\nexport interface ContextListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** List of contexts */\n contexts: any[]; // Will be Context[] type, avoiding circular import\n /** Token for the next page of results */\n nextToken?: string;\n /** Maximum number of results per page */\n maxResults?: number;\n /** Total number of contexts available */\n totalCount?: number;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Result of a presigned URL request\n */\nexport interface FileUrlResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The presigned URL */\n url: string;\n /** Optional expire time (epoch seconds) */\n expireTime?: number;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Represents a file item in a context\n */\nexport interface ContextFileEntry {\n fileId?: string;\n fileName?: string;\n filePath: string;\n fileType?: string;\n gmtCreate?: string;\n gmtModified?: string;\n size?: number;\n status?: string;\n}\n\n/**\n * Result of context file listing\n */\nexport interface ContextFileListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** File entries under a folder */\n entries: ContextFileEntry[];\n /** Optional total count returned by backend */\n count?: number;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Helper function to extract request ID from API responses\n */\nexport function extractRequestId(response: any): string | undefined {\n if (!response) return undefined;\n\n // If response is a string (like body?.requestId), return it directly\n if (typeof response === \"string\" && response.length > 0) {\n return response;\n }\n\n // Check for requestId in response.body first\n if (response.body && response.body.requestId) {\n return response.body.requestId;\n }\n // Check for requestId directly on response\n if (response.requestId) {\n return response.requestId;\n }\n\n return undefined;\n}\n","// UploadStrategy defines the upload strategy for context synchronization\nexport enum UploadStrategy {\n UploadBeforeResourceRelease = \"UploadBeforeResourceRelease\",\n}\n\n// DownloadStrategy defines the download strategy for context synchronization\nexport enum DownloadStrategy {\n DownloadAsync = \"DownloadAsync\",\n}\n\n// Lifecycle defines the lifecycle options for recycle policy\nexport enum Lifecycle {\n Lifecycle_1Day = \"Lifecycle_1Day\",\n Lifecycle_3Days = \"Lifecycle_3Days\", \n Lifecycle_5Days = \"Lifecycle_5Days\",\n Lifecycle_10Days = \"Lifecycle_10Days\",\n Lifecycle_15Days = \"Lifecycle_15Days\",\n Lifecycle_30Days = \"Lifecycle_30Days\",\n Lifecycle_90Days = \"Lifecycle_90Days\",\n Lifecycle_180Days = \"Lifecycle_180Days\",\n Lifecycle_360Days = \"Lifecycle_360Days\",\n Lifecycle_Forever = \"Lifecycle_Forever\",\n}\n\n// UploadPolicy defines the upload policy for context synchronization\nexport interface UploadPolicy {\n autoUpload: boolean;\n uploadStrategy: UploadStrategy;\n}\n\n// DownloadPolicy defines the download policy for context synchronization\nexport interface DownloadPolicy {\n autoDownload: boolean;\n downloadStrategy: DownloadStrategy;\n}\n\n// DeletePolicy defines the delete policy for context synchronization\nexport interface DeletePolicy {\n syncLocalFile: boolean;\n}\n\n// ExtractPolicy defines the extract policy for context synchronization\nexport interface ExtractPolicy {\n extract: boolean;\n deleteSrcFile: boolean;\n extractToCurrentFolder: boolean;\n}\n\n// RecyclePolicy defines the recycle policy for context synchronization\nexport interface RecyclePolicy {\n lifecycle: Lifecycle;\n paths: string[];\n}\n\n// ExtractPolicyClass provides a class-based implementation with default values\nexport class ExtractPolicyClass implements ExtractPolicy {\n extract: boolean = true;\n deleteSrcFile: boolean = true;\n extractToCurrentFolder: boolean = false;\n\n constructor(extract: boolean = true, deleteSrcFile: boolean = true, extractToCurrentFolder: boolean = false) {\n this.extract = extract;\n this.deleteSrcFile = deleteSrcFile;\n this.extractToCurrentFolder = extractToCurrentFolder;\n }\n\n /**\n * Creates a new extract policy with default values\n */\n static default(): ExtractPolicyClass {\n return new ExtractPolicyClass();\n }\n\n /**\n * Converts to plain object for JSON serialization\n */\n toDict(): Record<string, any> {\n return {\n extract: this.extract,\n deleteSrcFile: this.deleteSrcFile,\n extractToCurrentFolder: this.extractToCurrentFolder\n };\n }\n}\n\n// WhiteList defines the white list configuration\nexport interface WhiteList {\n path: string;\n excludePaths?: string[];\n}\n\nexport class WhiteListValidator {\n private static containsWildcard(path: string): boolean {\n return /[*?\\[\\]]/.test(path);\n }\n\n static validate(whitelist: WhiteList): void {\n if (this.containsWildcard(whitelist.path)) {\n throw new Error(\n `Wildcard patterns are not supported in path. Got: ${whitelist.path}. ` +\n \"Please use exact directory paths instead.\"\n );\n }\n\n if (whitelist.excludePaths) {\n for (const excludePath of whitelist.excludePaths) {\n if (this.containsWildcard(excludePath)) {\n throw new Error(\n `Wildcard patterns are not supported in exclude_paths. Got: ${excludePath}. ` +\n \"Please use exact directory paths instead.\"\n );\n }\n }\n }\n }\n}\n\n// BWList defines the black and white list configuration\nexport interface BWList {\n whiteLists?: WhiteList[];\n}\n\n// SyncPolicy defines the synchronization policy\nexport interface SyncPolicy {\n uploadPolicy?: UploadPolicy;\n downloadPolicy?: DownloadPolicy;\n deletePolicy?: DeletePolicy;\n extractPolicy?: ExtractPolicy;\n recyclePolicy?: RecyclePolicy;\n bwList?: BWList;\n}\n\n// SyncPolicyImpl provides a class-based implementation with default value handling\nexport class SyncPolicyImpl implements SyncPolicy {\n uploadPolicy?: UploadPolicy;\n downloadPolicy?: DownloadPolicy;\n deletePolicy?: DeletePolicy;\n extractPolicy?: ExtractPolicy;\n recyclePolicy?: RecyclePolicy;\n bwList?: BWList;\n\n constructor(policy?: Partial<SyncPolicy>) {\n if (policy) {\n this.uploadPolicy = policy.uploadPolicy;\n this.downloadPolicy = policy.downloadPolicy;\n this.deletePolicy = policy.deletePolicy;\n this.extractPolicy = policy.extractPolicy;\n this.recyclePolicy = policy.recyclePolicy;\n this.bwList = policy.bwList;\n }\n this.ensureDefaults();\n }\n\n private ensureDefaults(): void {\n if (!this.uploadPolicy) {\n this.uploadPolicy = newUploadPolicy();\n }\n if (!this.downloadPolicy) {\n this.downloadPolicy = newDownloadPolicy();\n }\n if (!this.deletePolicy) {\n this.deletePolicy = newDeletePolicy();\n }\n if (!this.extractPolicy) {\n this.extractPolicy = newExtractPolicy();\n }\n if (!this.recyclePolicy) {\n this.recyclePolicy = newRecyclePolicy();\n }\n if (!this.bwList) {\n this.bwList = {\n whiteLists: [\n {\n path: \"\",\n excludePaths: [],\n },\n ],\n };\n }\n }\n\n toJSON(): SyncPolicy {\n this.ensureDefaults();\n return {\n uploadPolicy: this.uploadPolicy,\n downloadPolicy: this.downloadPolicy,\n deletePolicy: this.deletePolicy,\n extractPolicy: this.extractPolicy,\n recyclePolicy: this.recyclePolicy,\n bwList: this.bwList,\n };\n }\n}\n\n// ContextSync defines the context synchronization configuration\nexport class ContextSync {\n contextId: string;\n path: string;\n policy?: SyncPolicy;\n\n constructor(contextId: string, path: string, policy?: SyncPolicy) {\n if (policy) {\n validateSyncPolicy(policy);\n }\n this.contextId = contextId;\n this.path = path;\n this.policy = policy;\n }\n\n // WithPolicy sets the policy and returns the context sync for chaining\n withPolicy(policy: SyncPolicy): ContextSync {\n validateSyncPolicy(policy);\n this.policy = policy;\n return this;\n }\n}\n\n// NewUploadPolicy creates a new upload policy with default values\nexport function newUploadPolicy(): UploadPolicy {\n return {\n autoUpload: true,\n uploadStrategy: UploadStrategy.UploadBeforeResourceRelease,\n };\n}\n\n// NewDownloadPolicy creates a new download policy with default values\nexport function newDownloadPolicy(): DownloadPolicy {\n return {\n autoDownload: true,\n downloadStrategy: DownloadStrategy.DownloadAsync,\n };\n}\n\n// NewDeletePolicy creates a new delete policy with default values\nexport function newDeletePolicy(): DeletePolicy {\n return {\n syncLocalFile: true,\n };\n}\n\n// NewExtractPolicy creates a new extract policy with default values\nexport function newExtractPolicy(): ExtractPolicy {\n return {\n extract: true,\n deleteSrcFile: true,\n extractToCurrentFolder: false,\n };\n}\n\n// NewRecyclePolicy creates a new recycle policy with default values\nexport function newRecyclePolicy(): RecyclePolicy {\n return {\n lifecycle: Lifecycle.Lifecycle_Forever,\n paths: [\"\"],\n };\n}\n\n// NewSyncPolicy creates a new sync policy with default values\nexport function newSyncPolicy(): SyncPolicy {\n return {\n uploadPolicy: newUploadPolicy(),\n downloadPolicy: newDownloadPolicy(),\n deletePolicy: newDeletePolicy(),\n extractPolicy: newExtractPolicy(),\n recyclePolicy: newRecyclePolicy(),\n bwList: {\n whiteLists: [\n {\n path: \"\",\n excludePaths: [],\n },\n ],\n },\n };\n}\n\n// isValidLifecycle checks if the given lifecycle value is valid\nfunction isValidLifecycle(lifecycle: Lifecycle): boolean {\n return Object.values(Lifecycle).includes(lifecycle);\n}\n\nexport function validateSyncPolicy(policy?: SyncPolicy): void {\n if (policy?.bwList?.whiteLists) {\n for (const whitelist of policy.bwList.whiteLists) {\n WhiteListValidator.validate(whitelist);\n }\n }\n\n if (policy?.recyclePolicy) {\n // Validate lifecycle value\n if (!isValidLifecycle(policy.recyclePolicy.lifecycle)) {\n const validValues = Object.values(Lifecycle).join(', ');\n throw new Error(\n `Invalid lifecycle value: ${policy.recyclePolicy.lifecycle}. ` +\n `Valid values are: ${validValues}`\n );\n }\n\n // Validate paths don't contain wildcard patterns\n if (policy.recyclePolicy.paths) {\n for (const path of policy.recyclePolicy.paths) {\n if (path && path.trim() !== \"\") {\n // Create a temporary WhiteList object for validation\n const tempWhiteList: WhiteList = { path: path };\n WhiteListValidator.validate(tempWhiteList);\n }\n }\n }\n }\n}\n\n// NewSyncPolicyWithDefaults creates a new sync policy with partial parameters and fills defaults\nexport function newSyncPolicyWithDefaults(policy?: Partial<SyncPolicy>): SyncPolicy {\n return new SyncPolicyImpl(policy).toJSON();\n}\n\n// NewContextSync creates a new context sync configuration\nexport function newContextSync(contextId: string, path: string, policy?: SyncPolicy): ContextSync {\n if (policy) {\n validateSyncPolicy(policy);\n }\n return new ContextSync(contextId, path, policy);\n}","/**\n * Base exception for all AgentBay SDK errors.\n */\nexport class AgentBayError extends Error {\n extra: Record<string, any>;\n\n constructor(message?: string, extra: Record<string, any> = {}) {\n const errorMessage = message || \"AgentBayError\";\n super(errorMessage);\n this.name = \"AgentBayError\";\n this.extra = extra;\n Object.setPrototypeOf(this, AgentBayError.prototype);\n }\n}\n\n/**\n * Raised when there is an authentication error.\n */\nexport class AuthenticationError extends AgentBayError {\n constructor(\n message = \"Authentication failed\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"AuthenticationError\";\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Raised when there is an error with the API.\n */\nexport class APIError extends AgentBayError {\n statusCode?: number;\n\n constructor(\n message = \"API error\",\n statusCode?: number,\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"APIError\";\n this.statusCode = statusCode;\n Object.setPrototypeOf(this, APIError.prototype);\n }\n}\n\n/**\n * Raised for errors related to file operations.\n */\nexport class FileError extends AgentBayError {\n constructor(\n message = \"File operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"FileError\";\n Object.setPrototypeOf(this, FileError.prototype);\n }\n}\n\n/**\n * Raised for errors related to command execution.\n */\nexport class CommandError extends AgentBayError {\n constructor(\n message = \"Command execution error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"CommandError\";\n Object.setPrototypeOf(this, CommandError.prototype);\n }\n}\n\n/**\n * Raised for errors related to session operations.\n */\nexport class SessionError extends AgentBayError {\n constructor(message = \"Session error\", extra: Record<string, any> = {}) {\n super(message, extra);\n this.name = \"SessionError\";\n Object.setPrototypeOf(this, SessionError.prototype);\n }\n}\n\n/**\n * Raised for errors related to OSS operations.\n */\nexport class OssError extends AgentBayError {\n constructor(\n message = \"OSS operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"OssError\";\n Object.setPrototypeOf(this, OssError.prototype);\n }\n}\n\n/**\n * Raised for errors related to application operations.\n */\nexport class ApplicationError extends AgentBayError {\n constructor(\n message = \"Application operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"ApplicationError\";\n Object.setPrototypeOf(this, ApplicationError.prototype);\n }\n}\n\n/**\n * Raised for errors related to UI operations.\n */\nexport class UIError extends AgentBayError {\n constructor(message = \"UI operation error\", extra: Record<string, any> = {}) {\n super(message, extra);\n this.name = \"UIError\";\n Object.setPrototypeOf(this, UIError.prototype);\n }\n}\n\n/**\n * Raised for errors related to browser operations.\n */\nexport class BrowserError extends AgentBayError {\n constructor(\n message = \"Browser operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"BrowserError\";\n Object.setPrototypeOf(this, BrowserError.prototype);\n }\n}\n","import { AgentBay } from \"./agent-bay\";\nimport { Agent } from \"./agent/agent\";\nimport { Client } from \"./api/client\";\nimport {\n CallMcpToolRequest,\n GetLabelRequest,\n GetLinkRequest,\n GetMcpResourceRequest,\n ListMcpToolsRequest,\n ReleaseMcpSessionRequest,\n SetLabelRequest,\n} from \"./api/models/model\";\nimport { Application } from \"./application\";\nimport { Browser } from \"./browser\";\nimport { Code } from \"./code\";\nimport { Command } from \"./command\";\nimport { Computer } from \"./computer\";\nimport { ContextManager, newContextManager } from \"./context-manager\";\nimport { FileSystem } from \"./filesystem\";\nimport { Mobile } from \"./mobile\";\nimport { Oss } from \"./oss\";\nimport {\n DeleteResult,\n extractRequestId,\n OperationResult,\n} from \"./types/api-response\";\nimport { UI } from \"./ui\";\nimport { log, logError } from \"./utils/logger\";\nimport { WindowManager } from \"./window\";\n\n/**\n * Represents an MCP tool with complete information.\n */\nexport interface McpTool {\n name: string;\n description: string;\n inputSchema: Record<string, any>;\n server: string;\n tool: string;\n}\n\n/**\n * Result containing MCP tools list and request ID.\n */\nexport interface McpToolsResult extends OperationResult {\n tools: McpTool[];\n}\n\n/**\n * Result containing MCP resource information and request ID.\n */\nexport interface McpResourceResult extends OperationResult {\n uri: string;\n name: string;\n description: string;\n mimeType: string;\n}\n\n/**\n * Result containing MCP resource content and request ID.\n */\nexport interface McpResourceContentResult extends OperationResult {\n contents: Array<{\n uri: string;\n mimeType: string;\n text?: string;\n blob?: string;\n }>;\n}\n\n/**\n * Contains information about a session.\n */\nexport interface SessionInfo {\n sessionId: string;\n resourceUrl: string;\n appId?: string;\n authCode?: string;\n connectionProperties?: string;\n resourceId?: string;\n resourceType?: string;\n ticket?: string;\n}\n\n/**\n * SessionInfo class to match Python version structure\n */\nexport class SessionInfoClass {\n sessionId: string;\n resourceUrl: string;\n appId: string;\n authCode: string;\n connectionProperties: string;\n resourceId: string;\n resourceType: string;\n ticket: string;\n\n constructor(\n sessionId = \"\",\n resourceUrl = \"\",\n appId = \"\",\n authCode = \"\",\n connectionProperties = \"\",\n resourceId = \"\",\n resourceType = \"\",\n ticket = \"\"\n ) {\n this.sessionId = sessionId;\n this.resourceUrl = resourceUrl;\n this.appId = appId;\n this.authCode = authCode;\n this.connectionProperties = connectionProperties;\n this.resourceId = resourceId;\n this.resourceType = resourceType;\n this.ticket = ticket;\n }\n}\n\n/**\n * Represents a session in the AgentBay cloud environment.\n */\nexport class Session {\n private agentBay: AgentBay;\n public sessionId: string;\n\n // File transfer context ID\n public fileTransferContextId: string | null = null;\n\n // VPC-related information\n public isVpc = false; // Whether this session uses VPC resources\n public networkInterfaceIp = \"\"; // Network interface IP for VPC sessions\n public httpPort = \"\"; // HTTP port for VPC sessions\n public token = \"\"; // Token for VPC sessions\n\n // Resource URL for accessing the session\n public resourceUrl = \"\";\n\n // Recording functionality\n public enableBrowserReplay = false; // Whether browser recording is enabled for this session\n\n // File, command, code, and oss handlers (matching Python naming)\n public fileSystem: FileSystem; // file_system in Python\n public command: Command;\n public code: Code;\n public oss: Oss;\n\n // Application, window, and UI management (matching Python naming)\n public application: Application; // application in Python (ApplicationManager)\n public window: WindowManager;\n public ui: UI;\n\n // Computer and Mobile automation (new modules)\n public computer: Computer;\n public mobile: Mobile;\n\n // Agent for task execution\n public agent: Agent;\n\n // Browser for web automation\n public browser: Browser;\n\n // Context management (matching Go version)\n public context: ContextManager;\n\n // MCP tools available for this session\n public mcpTools: McpTool[] = [];\n\n /**\n * Initialize a Session object.\n *\n * @param agentBay - The AgentBay instance that created this session.\n * @param sessionId - The ID of this session.\n */\n constructor(agentBay: AgentBay, sessionId: string) {\n this.agentBay = agentBay;\n this.sessionId = sessionId;\n\n // Initialize file system, command and code handlers (matching Python naming)\n this.fileSystem = new FileSystem(this);\n this.command = new Command(this);\n this.code = new Code(this);\n this.oss = new Oss(this);\n\n // Initialize application and window managers (matching Python naming)\n this.application = new Application(this);\n this.window = new WindowManager(this);\n this.ui = new UI(this);\n\n // Initialize Computer and Mobile modules\n this.computer = new Computer(this);\n this.mobile = new Mobile(this);\n\n // Initialize Agent\n this.agent = new Agent(this);\n\n // Initialize Browser\n this.browser = new Browser(this);\n\n // Initialize context manager (matching Go version)\n this.context = newContextManager(this);\n }\n\n /**\n * Return the AgentBay instance that created this session.\n */\n getAgentBay(): AgentBay {\n return this.agentBay;\n }\n\n /**\n * Return the API key for this session.\n */\n getAPIKey(): string {\n return this.agentBay.getAPIKey();\n }\n\n /**\n * Return the HTTP client for this session.\n */\n getClient(): Client {\n return this.agentBay.getClient();\n }\n\n /**\n * Return the session_id for this session.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Return whether this session uses VPC resources.\n */\n isVpcEnabled(): boolean {\n return this.isVpc;\n }\n\n /**\n * Return the network interface IP for VPC sessions.\n */\n getNetworkInterfaceIp(): string {\n return this.networkInterfaceIp;\n }\n\n /**\n * Return the HTTP port for VPC sessions.\n */\n getHttpPort(): string {\n return this.httpPort;\n }\n\n /**\n * Return the token for VPC sessions.\n */\n getToken(): string {\n return this.token;\n }\n\n /**\n * Find the server that provides the given tool.\n */\n findServerForTool(toolName: string): string {\n for (const tool of this.mcpTools) {\n if (tool.name === toolName) {\n return tool.server;\n }\n }\n return \"\";\n }\n\n /**\n * Delete this session.\n *\n * @param syncContext - Whether to sync context data (trigger file uploads) before deleting the session. Defaults to false.\n * @returns DeleteResult indicating success or failure and request ID\n */\n async delete(syncContext = false): Promise<DeleteResult> {\n try {\n // If syncContext is true, trigger file uploads first\n if (syncContext) {\n log(\"Triggering context synchronization before session deletion...\");\n\n // Use the new sync method without callback (sync mode)\n const syncStartTime = Date.now();\n\n try {\n const syncResult = await this.context.sync();\n\n const syncDuration = Date.now() - syncStartTime;\n\n if (syncResult.success) {\n log(`Context sync completed in ${syncDuration}ms`);\n } else {\n log(`Context sync completed with failures after ${syncDuration}ms`);\n }\n } catch (error) {\n const syncDuration = Date.now() - syncStartTime;\n logError(`Failed to trigger context sync after ${syncDuration}ms:`, error);\n // Continue with deletion even if sync fails\n }\n }\n\n // Proceed with session deletion\n const request = new ReleaseMcpSessionRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n });\n\n const response = await this.getClient().releaseMcpSession(request);\n log(`Response from release_mcp_session: ${JSON.stringify(response)}`);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check if the response is success (matching Python logic)\n const responseBody = response.body;\n const success = responseBody?.success !== false; // Note: capital S to match Python\n\n if (!success) {\n const errorMessage = `[${responseBody?.code || 'Unknown'}] ${responseBody?.message || 'Failed to delete session'}`;\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n // Return success result with request ID\n return {\n requestId,\n success: true,\n };\n } catch (error) {\n logError(\"Error calling release_mcp_session:\", error);\n // In case of error, return failure result with error message (matching Python)\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to delete session ${this.sessionId}: ${error}`,\n };\n }\n }\n\n /**\n * Validates labels parameter for label operations.\n *\n * @param labels - The labels to validate\n * @returns null if validation passes, or OperationResult with error if validation fails\n */\n private validateLabels(labels: Record<string, string>): OperationResult | null {\n // Check if labels is null, undefined, or invalid type\n if (!labels || typeof labels !== 'object') {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels cannot be null, undefined, or invalid type. Please provide a valid labels object.\",\n };\n }\n\n // Check if labels is an array or other non-plain object\n if (Array.isArray(labels)) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels cannot be an array. Please provide a valid labels object.\",\n };\n }\n\n // Check if labels is a Date, RegExp, or other built-in object types\n if (labels instanceof Date || labels instanceof RegExp || labels instanceof Error ||\n labels instanceof Map || labels instanceof Set || labels instanceof WeakMap ||\n labels instanceof WeakSet || labels instanceof Promise) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels must be a plain object. Built-in object types are not allowed.\",\n };\n }\n\n // Check if labels object is empty\n if (Object.keys(labels).length === 0) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels cannot be empty. Please provide at least one label.\",\n };\n }\n\n for (const [key, value] of Object.entries(labels)) {\n // Check key validity\n if (!key || key.trim() === \"\") {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Label keys cannot be empty Please provide valid keys.\",\n };\n }\n\n // Check value is not null or undefined\n if (!value || value.trim() === \"\") {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Label values cannot be empty Please provide valid values.\",\n };\n }\n }\n\n // Validation passed\n return null;\n }\n\n /**\n * Sets the labels for this session.\n *\n * @param labels - The labels to set for the session.\n * @returns OperationResult indicating success or failure with request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async setLabels(labels: Record<string, string>): Promise<OperationResult> {\n try {\n // Validate labels using the extracted validation function\n const validationResult = this.validateLabels(labels);\n if (validationResult !== null) {\n return validationResult;\n }\n\n // Convert labels to JSON string\n const labelsJSON = JSON.stringify(labels);\n\n const request = new SetLabelRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n labels: labelsJSON,\n });\n\n const response = await this.getClient().setLabel(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n return {\n requestId,\n success: true,\n };\n } catch (error) {\n logError(\"Error calling set_label:\", error);\n throw new Error(\n `Failed to set labels for session ${this.sessionId}: ${error}`\n );\n }\n }\n\n /**\n * Gets the labels for this session.\n *\n * @returns OperationResult containing the labels as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async getLabels(): Promise<OperationResult> {\n try {\n const request = new GetLabelRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n });\n\n const response = await this.getClient().getLabel(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Extract labels from response (matching Python structure)\n const responseBody = response?.body;\n const data = responseBody?.data; // Capital D to match Python\n const labelsJSON = data?.labels; // Capital L to match Python\n\n let labels = {};\n if (labelsJSON) {\n labels = JSON.parse(labelsJSON);\n }\n\n return {\n requestId,\n success: true,\n data: labels,\n };\n } catch (error) {\n logError(\"Error calling get_label:\", error);\n throw new Error(\n `Failed to get labels for session ${this.sessionId}: ${error}`\n );\n }\n }\n\n /**\n * Gets information about this session.\n *\n * @returns OperationResult containing the session information as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async info(): Promise<OperationResult> {\n try {\n const request = new GetMcpResourceRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n });\n\n log(\"API Call: GetMcpResource\");\n log(`Request: SessionId=${this.sessionId}`);\n\n const response = await this.getClient().getMcpResource(request);\n log(`Response from GetMcpResource: ${JSON.stringify(response)}`);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Extract session info from response (matching Python structure)\n const responseBody = response.body;\n const data = responseBody?.data; // Capital D to match Python\n\n const sessionInfo = new SessionInfoClass();\n\n if (data?.sessionId) {\n // Capital S and I to match Python\n sessionInfo.sessionId = data.sessionId;\n }\n\n if (data?.resourceUrl) {\n // Capital R and U to match Python\n sessionInfo.resourceUrl = data.resourceUrl;\n }\n\n // Transfer DesktopInfo fields to SessionInfo (matching Python structure)\n if (data?.desktopInfo) {\n // Capital D and I to match Python\n const desktopInfo = data.desktopInfo;\n if (desktopInfo.appId) {\n sessionInfo.appId = desktopInfo.appId;\n }\n if (desktopInfo.authCode) {\n sessionInfo.authCode = desktopInfo.authCode;\n }\n if (desktopInfo.connectionProperties) {\n sessionInfo.connectionProperties = desktopInfo.connectionProperties;\n }\n if (desktopInfo.resourceId) {\n sessionInfo.resourceId = desktopInfo.resourceId;\n }\n if (desktopInfo.resourceType) {\n sessionInfo.resourceType = desktopInfo.resourceType;\n }\n if (desktopInfo.ticket) {\n sessionInfo.ticket = desktopInfo.ticket;\n }\n }\n\n return {\n requestId,\n success: true,\n data: sessionInfo,\n };\n } catch (error) {\n logError(\"Error calling GetMcpResource:\", error);\n throw new Error(\n `Failed to get session info for session ${this.sessionId}: ${error}`\n );\n }\n }\n\n /**\n * Get a link associated with the current session.\n *\n * @param protocolType - Optional protocol type to use for the link\n * @param port - Optional port to use for the link (must be in range [30100, 30199])\n * @returns OperationResult containing the link as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async getLink(\n protocolType?: string,\n port?: number\n ): Promise<OperationResult> {\n try {\n // Validate port range if port is provided\n if (port) {\n if (!Number.isInteger(port) || port < 30100 || port > 30199) {\n throw new Error(\n `Invalid port value: ${port}. Port must be an integer in the range [30100, 30199].`\n );\n }\n }\n\n const request = new GetLinkRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.getSessionId(),\n protocolType,\n port,\n });\n\n const response = await this.agentBay.getClient().getLink(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n const responseBody = response.body;\n\n if (typeof responseBody !== \"object\") {\n throw new Error(\n \"Invalid response format: expected a dictionary from response body\"\n );\n }\n\n let data = responseBody.data || {}; // Capital D to match Python\n log(`Data: ${JSON.stringify(data)}`);\n\n if (typeof data !== \"object\") {\n try {\n data = typeof data === \"string\" ? JSON.parse(data) : {};\n } catch (jsonError) {\n data = {};\n }\n }\n\n const url = (data as any).Url || (data as any).url;\n\n return {\n requestId,\n success: true,\n data: url,\n };\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"Invalid response format\")\n ) {\n throw error;\n }\n throw new Error(`Failed to get link: ${error}`);\n }\n }\n\n /**\n * Asynchronously get a link associated with the current session.\n *\n * @param protocolType - Optional protocol type to use for the link\n * @param port - Optional port to use for the link (must be in range [30100, 30199])\n * @returns OperationResult containing the link as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async getLinkAsync(\n protocolType?: string,\n port?: number\n ): Promise<OperationResult> {\n try {\n // Validate port range if port is provided\n if (port !== undefined) {\n if (!Number.isInteger(port) || port < 30100 || port > 30199) {\n throw new Error(\n `Invalid port value: ${port}. Port must be an integer in the range [30100, 30199].`\n );\n }\n }\n\n const request = new GetLinkRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.getSessionId(),\n protocolType,\n port,\n });\n\n // Note: In TypeScript, async is the default, but keeping this method for API compatibility\n const response = await this.agentBay.getClient().getLink(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n const responseBody = response?.body;\n\n if (typeof responseBody !== \"object\") {\n throw new Error(\n \"Invalid response format: expected a dictionary from response body\"\n );\n }\n\n let data = responseBody?.data || {}; // Capital D to match Python\n log(`Data: ${JSON.stringify(data)}`);\n\n if (typeof data !== \"object\") {\n try {\n data = typeof data === \"string\" ? JSON.parse(data) : {};\n } catch (jsonError) {\n data = {};\n }\n }\n\n const url = (data as any).Url || (data as any).url;\n\n return {\n requestId,\n success: true,\n data: url,\n };\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"Invalid response format\")\n ) {\n throw error;\n }\n throw new Error(`Failed to get link asynchronously: ${error}`);\n }\n }\n\n /**\n * List MCP tools available for this session.\n *\n * @param imageId Optional image ID, defaults to session's imageId or \"linux_latest\"\n * @returns McpToolsResult containing tools list and request ID\n */\n async listMcpTools(imageId?: string): Promise<McpToolsResult> {\n // Use provided imageId, session's imageId, or default\n if (!imageId) {\n imageId = (this as any).imageId || \"linux_latest\";\n }\n\n const request = new ListMcpToolsRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n imageId: imageId,\n });\n\n log(\"API Call: ListMcpTools\");\n log(`Request: ImageId=${imageId}`);\n\n const response = await this.getClient().listMcpTools(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n if (response && response.body) {\n log(\"Response from ListMcpTools:\", response.body);\n }\n\n // Parse the response data\n const tools: McpTool[] = [];\n if (response && response.body && response.body.data) {\n try {\n const toolsData = JSON.parse(response.body.data as string);\n for (const toolData of toolsData) {\n const tool: McpTool = {\n name: toolData.name || \"\",\n description: toolData.description || \"\",\n inputSchema: toolData.inputSchema || {},\n server: toolData.server || \"\",\n tool: toolData.tool || \"\",\n };\n tools.push(tool);\n }\n } catch (error) {\n logError(`Error unmarshaling tools data: ${error}`);\n }\n }\n\n this.mcpTools = tools; // Update the session's mcpTools field\n\n return {\n requestId,\n success: true,\n tools,\n };\n }\n\n /**\n * Call an MCP tool and return the result in a format compatible with Agent.\n *\n * @param toolName - Name of the MCP tool to call\n * @param args - Arguments to pass to the tool\n * @returns McpToolResult containing the response data\n */\n async callMcpTool(toolName: string, args: any): Promise<import(\"./agent/agent\").McpToolResult> {\n try {\n const argsJSON = JSON.stringify(args);\n\n // Check if this is a VPC session\n if (this.isVpcEnabled()) {\n // VPC mode: Use HTTP request to the VPC endpoint\n const server = this.findServerForTool(toolName);\n if (!server) {\n return {\n success: false,\n data: \"\",\n errorMessage: `Server not found for tool: ${toolName}`,\n requestId: \"\",\n };\n }\n\n if (!this.networkInterfaceIp || !this.httpPort) {\n return {\n success: false,\n data: \"\",\n errorMessage: `VPC network configuration incomplete: networkInterfaceIp=${this.networkInterfaceIp}, httpPort=${this.httpPort}. This may indicate the VPC session was not properly configured with network parameters.`,\n requestId: \"\",\n };\n }\n\n const baseURL = `http://${this.networkInterfaceIp}:${this.httpPort}/callTool`;\n const url = new URL(baseURL);\n url.searchParams.append(\"server\", server);\n url.searchParams.append(\"tool\", toolName);\n url.searchParams.append(\"args\", argsJSON);\n url.searchParams.append(\"token\", this.getToken());\n // Add requestId for debugging purposes\n const requestId = `vpc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n url.searchParams.append(\"requestId\", requestId);\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n });\n\n if (!response.ok) {\n return {\n success: false,\n data: \"\",\n errorMessage: `VPC request failed: ${response.statusText}`,\n requestId: \"\",\n };\n }\n\n const responseData = await response.json() as any;\n\n // Extract the actual result from the nested VPC response structure\n let actualResult: any = responseData;\n if (typeof responseData.data === \"string\") {\n try {\n const dataMap = JSON.parse(responseData.data);\n if (dataMap.result) {\n actualResult = dataMap.result;\n }\n } catch (err) {\n // Keep original response if parsing fails\n }\n } else if (responseData.data && responseData.data.result) {\n actualResult = responseData.data.result;\n }\n\n // Extract text content from the result\n let textContent = \"\";\n if (actualResult.content && Array.isArray(actualResult.content) && actualResult.content.length > 0) {\n const contentItem = actualResult.content[0];\n if (contentItem && contentItem.text) {\n textContent = contentItem.text;\n }\n }\n\n return {\n success: true,\n data: textContent || JSON.stringify(actualResult),\n errorMessage: \"\",\n requestId: \"\",\n };\n } else {\n // Non-VPC mode: use traditional API call\n const callToolRequest = new CallMcpToolRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.getSessionId(),\n name: toolName,\n args: argsJSON,\n });\n\n const response = await this.getClient().callMcpTool(callToolRequest);\n\n if (!response.body?.data) {\n return {\n success: false,\n data: \"\",\n errorMessage: \"Invalid response data format\",\n requestId: extractRequestId(response) || \"\",\n };\n }\n\n // Check for API-level errors before parsing Data\n if (response.body.success === false && response.body.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n return {\n success: false,\n data: \"\",\n errorMessage,\n requestId: extractRequestId(response) || \"\",\n };\n }\n\n const data = response.body.data as Record<string, any>;\n\n // Check if there's an error in the response\n if (data.isError) {\n const errorContent = data.content || [];\n const errorMessage = errorContent\n .map((item: any) => item.text || \"Unknown error\")\n .join(\"; \");\n\n return {\n success: false,\n data: \"\",\n errorMessage,\n requestId: extractRequestId(response) || \"\",\n };\n }\n\n // Extract text content from content array\n const content = data.content || [];\n let textContent = \"\";\n if (content.length > 0 && content[0].text !== undefined) {\n textContent = content[0].text;\n }\n\n return {\n success: true,\n data: textContent,\n errorMessage: \"\",\n requestId: extractRequestId(response) || \"\",\n };\n }\n } catch (error) {\n return {\n success: false,\n data: \"\",\n errorMessage: error instanceof Error ? error.message : String(error),\n requestId: \"\",\n };\n }\n }\n}\n","import { ApiResponse } from \"../types/api-response\";\nimport { log } from \"../utils/logger\";\n\n/**\n * Result of task execution.\n */\nexport interface ExecutionResult extends ApiResponse {\n success: boolean;\n errorMessage: string;\n taskId: string;\n taskStatus: string;\n}\n\n/**\n * Result of query operations.\n */\nexport interface QueryResult extends ApiResponse {\n success: boolean;\n output: string;\n errorMessage: string;\n}\n\n/**\n * Result of an MCP tool call.\n */\nexport interface McpToolResult {\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n}\n\n/**\n * Interface defining the methods needed by Agent from Session.\n */\nexport interface McpSession {\n getAPIKey(): string;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<McpToolResult>;\n}\n\n/**\n * An Agent to manipulate applications to complete specific tasks.\n */\nexport class Agent {\n private session: McpSession;\n\n /**\n * Initialize an Agent object.\n *\n * @param session - The Session instance that this Agent belongs to.\n */\n constructor(session: McpSession) {\n this.session = session;\n }\n\n /**\n * Execute a specific task described in human language.\n *\n * @param task - Task description in human language.\n * @param maxTryTimes - Maximum number of retry attempts.\n * @returns ExecutionResult containing success status, task output, and error message if any.\n */\n async executeTask(task: string, maxTryTimes: number): Promise<ExecutionResult> {\n try {\n const args = { task, max_try_times: maxTryTimes };\n const result = await this.session.callMcpTool(\"flux_execute_task\", args);\n \n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n\n // Parse task ID from response\n let content: any;\n try {\n content = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: `Failed to parse response: ${err}`,\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n\n const taskId = content.task_id;\n if (!taskId) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Task ID not found in response\",\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n\n // Poll for task completion\n let triedTime = 0;\n while (triedTime < maxTryTimes) {\n const query = await this.getTaskStatus(taskId);\n if (!query.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: query.errorMessage,\n taskStatus: \"failed\",\n taskId,\n };\n }\n\n let statusContent: any;\n try {\n statusContent = JSON.parse(query.output);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: `Failed to parse status response: ${err}`,\n taskStatus: \"failed\",\n taskId,\n };\n }\n\n const taskStatus = statusContent.status;\n if (!taskStatus) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Task status not found in response\",\n taskStatus: \"failed\",\n taskId,\n };\n }\n\n switch (taskStatus) {\n case \"finished\":\n return {\n requestId: result.requestId,\n success: true,\n errorMessage: \"\",\n taskId,\n taskStatus,\n };\n case \"failed\":\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Failed to execute task.\",\n taskId,\n taskStatus,\n };\n case \"unsupported\":\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Unsupported task.\",\n taskId,\n taskStatus,\n };\n }\n\n log(`Task ${taskId} is still running, please wait for a while.`);\n await new Promise(resolve => setTimeout(resolve, 3000));\n triedTime++;\n }\n\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Task execution timed out\",\n taskStatus: \"timeout\",\n taskId,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to execute: ${error}`,\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n }\n\n /**\n * Get the status of the task with the given task ID.\n *\n * @param taskId - Task ID\n * @returns QueryResult containing the task status\n */\n async getTaskStatus(taskId: string): Promise<QueryResult> {\n try {\n const args = { task_id: taskId };\n const result = await this.session.callMcpTool(\"flux_get_task_status\", args);\n \n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n output: \"\",\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n output: result.data,\n errorMessage: \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to get task status: ${error}`,\n output: \"\",\n };\n }\n }\n\n /**\n * Terminate a task with a specified task ID.\n *\n * @param taskId - The ID of the running task.\n * @returns ExecutionResult containing success status, task output, and error message if any.\n */\n async terminateTask(taskId: string): Promise<ExecutionResult> {\n log(\"Terminating task\");\n \n try {\n const args = { task_id: taskId };\n const result = await this.session.callMcpTool(\"flux_terminate_task\", args);\n\n let content: any;\n try {\n content = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: `Failed to parse response: ${err}`,\n taskId,\n taskStatus: \"failed\",\n };\n }\n\n const terminatedTaskId = content.task_id || taskId;\n const status = content.status || \"unknown\";\n\n if (result.success) {\n return {\n requestId: result.requestId,\n success: true,\n errorMessage: \"\",\n taskId: terminatedTaskId,\n taskStatus: status,\n };\n }\n\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n taskId: terminatedTaskId,\n taskStatus: status,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to terminate: ${error}`,\n taskId,\n taskStatus: \"failed\",\n };\n }\n }\n} ","import { Client } from \"../api/client\";\nimport {\n InstalledAppListResult,\n ProcessListResult,\n AppOperationResult,\n} from \"../types/api-response\";\n\n\n/**\n * Represents an installed application\n */\nexport interface InstalledApp {\n name: string;\n start_cmd: string;\n stop_cmd?: string;\n work_directory?: string;\n}\n\n/**\n * Represents a running process\n */\nexport interface Process {\n pname: string;\n pid: number;\n cmdline?: string;\n path?: string;\n}\n\n/**\n * Handles application operations in the AgentBay cloud environment.\n * \n * @deprecated This module is deprecated. Use Computer or Mobile modules instead.\n * - For desktop applications, use session.computer\n * - For mobile applications, use session.mobile\n */\nexport class Application {\n private session: {\n getAPIKey(): string;\n getClient(): Client;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n };\n\n /**\n * Initialize an Application object.\n *\n * @param session - The Session instance that this Application belongs to.\n */\n constructor(session: {\n getAPIKey(): string;\n getClient(): Client;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n }) {\n this.session = session;\n }\n\n /**\n * Sanitizes error messages to remove sensitive information like API keys.\n *\n * @param error - The error to sanitize\n * @returns The sanitized error\n */\n private sanitizeError(error: any): any {\n if (!error) {\n return error;\n }\n\n const errorString = String(error);\n return errorString.replace(/Bearer\\s+[^\\s]+/g, \"Bearer [REDACTED]\");\n }\n\n /**\n * Helper method to parse JSON string into objects\n */\n private parseJSON<T>(jsonString: string): T {\n try {\n return JSON.parse(jsonString);\n } catch (error) {\n throw new Error(`Failed to parse JSON: ${error}`);\n }\n }\n\n /**\n * Get a list of installed applications.\n *\n * @param startMenu - Whether to include start menu applications.\n * @param desktop - Whether to include desktop applications.\n * @param ignoreSystemApps - Whether to ignore system applications.\n * @returns A promise that resolves to the list of installed applications.\n * \n * @deprecated Use session.computer.getInstalledApps() for desktop or session.mobile.getInstalledApps() for mobile instead.\n */\n async getInstalledApps(\n startMenu = false,\n desktop = true,\n ignoreSystemApps = true\n ): Promise<InstalledAppListResult> {\n console.warn('⚠️ Application.getInstalledApps() is deprecated. Use session.computer.getInstalledApps() for desktop or session.mobile.getInstalledApps() for mobile instead.');\n \n try {\n const args = {\n start_menu: startMenu,\n desktop,\n ignore_system_apps: ignoreSystemApps,\n };\n\n const result = await this.session.callMcpTool(\"get_installed_apps\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let apps: InstalledApp[] = [];\n try {\n apps = this.parseJSON<InstalledApp[]>(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: `Failed to parse installed apps: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: apps,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: [],\n errorMessage: `Failed to get installed apps: ${error}`,\n };\n }\n }\n\n /**\n * Start an application.\n *\n * @param startCmd - The command to start the application.\n * @param workDirectory - The working directory for the application.\n * @param activity - The activity to start (for mobile applications).\n * @returns A promise that resolves to the result of starting the application.\n * \n * @deprecated Use session.computer.startApp() for desktop or session.mobile.startApp() for mobile instead.\n */\n async startApp(\n startCmd: string,\n workDirectory = \"\",\n activity = \"\"\n ): Promise<ProcessListResult> {\n console.warn('⚠️ Application.startApp() is deprecated. Use session.computer.startApp() for desktop or session.mobile.startApp() for mobile instead.');\n \n try {\n const args = {\n start_cmd: startCmd,\n work_directory: workDirectory,\n activity,\n };\n\n const result = await this.session.callMcpTool(\"start_app\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let processes: Process[] = [];\n try {\n processes = this.parseJSON<Process[]>(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: `Failed to parse processes: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: processes,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: [],\n errorMessage: `Failed to start app: ${error}`,\n };\n }\n }\n\n /**\n * Stop an application by process name.\n *\n * @param pname - The process name of the application to stop.\n * @returns A promise that resolves to the result of stopping the application.\n * \n * @deprecated Use session.computer.stopAppByPName() for desktop or session.mobile.stopAppByPName() for mobile instead.\n */\n async stopAppByPName(pname: string): Promise<AppOperationResult> {\n console.warn('⚠️ Application.stopAppByPName() is deprecated. Use session.computer.stopAppByPName() for desktop or session.mobile.stopAppByPName() for mobile instead.');\n \n try {\n const args = { pname };\n const result = await this.session.callMcpTool(\"stop_app_by_pname\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to stop app by process name: ${error}`,\n };\n }\n }\n\n /**\n * Stops an application by process ID.\n * Corresponds to Python's stop_app_by_pid() method\n *\n * @param pid - The process ID to stop.\n * @returns AppOperationResult with operation result and requestId\n * @throws Error if the operation fails.\n */\n async stopAppByPID(pid: number): Promise<AppOperationResult> {\n try {\n const args = { pid };\n const result = await this.session.callMcpTool(\"stop_app_by_pid\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to stop app by process ID: ${error}`,\n };\n }\n }\n\n /**\n * Stop an application by command.\n *\n * @param cmd - The command to stop the application.\n * @returns A promise that resolves to the result of stopping the application.\n * \n * @deprecated Use session.computer.stopAppByCmd() for desktop or session.mobile.stopAppByCmd() for mobile instead.\n */\n async stopAppByCmd(cmd: string): Promise<AppOperationResult> {\n console.warn('⚠️ Application.stopAppByCmd() is deprecated. Use session.computer.stopAppByCmd() for desktop or session.mobile.stopAppByCmd() for mobile instead.');\n \n try {\n const args = { stop_cmd: cmd };\n const result = await this.session.callMcpTool(\"stop_app_by_cmd\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to stop app by command: ${error}`,\n };\n }\n }\n\n /**\n * Returns a list of currently visible applications.\n * Corresponds to Python's list_visible_apps() method\n *\n * @returns ProcessListResult with visible apps and requestId\n * @throws Error if the operation fails.\n */\n async listVisibleApps(): Promise<ProcessListResult> {\n try {\n const result = await this.session.callMcpTool(\"list_visible_apps\", {});\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let processes: Process[] = [];\n try {\n processes = this.parseJSON<Process[]>(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: `Failed to parse visible apps: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: processes,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: [],\n errorMessage: `Failed to list visible apps: ${error}`,\n };\n }\n }\n\n /**\n * Get a list of running processes.\n *\n * @returns A promise that resolves to the list of running processes.\n * \n * @deprecated Use session.computer.getRunningProcesses() for desktop or session.mobile.getRunningProcesses() for mobile instead.\n */\n async getRunningProcesses(): Promise<ProcessListResult> {\n console.warn('⚠️ Application.getRunningProcesses() is deprecated. Use session.computer.getRunningProcesses() for desktop or session.mobile.getRunningProcesses() for mobile instead.');\n \n try {\n const result = await this.session.callMcpTool(\"list_running_processes\", {});\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let processes: Process[] = [];\n try {\n processes = this.parseJSON<Process[]>(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: `Failed to parse running processes: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: processes,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: [],\n errorMessage: `Failed to get running processes: ${error}`,\n };\n }\n }\n\n /**\n * Get a list of visible applications.\n *\n * @returns A promise that resolves to the list of visible applications.\n * \n * @deprecated Use session.computer.getVisibleApps() for desktop instead. This API is not available for mobile.\n */\n async getVisibleApps(): Promise<InstalledAppListResult> {\n console.warn('⚠️ Application.getVisibleApps() is deprecated. Use session.computer.getVisibleApps() for desktop instead. This API is not available for mobile.');\n \n try {\n const result = await this.session.callMcpTool(\"list_visible_apps\", {});\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let apps: InstalledApp[] = [];\n try {\n apps = this.parseJSON<InstalledApp[]>(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n data: [],\n errorMessage: `Failed to parse visible apps: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: apps,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: [],\n errorMessage: `Failed to get visible apps: ${error}`,\n };\n }\n }\n}\n","export { Browser, BrowserViewport, BrowserScreen, BrowserFingerprint, BrowserProxy, BrowserProxyClass, BrowserOption, BrowserOptionClass } from './browser';\nexport { BrowserAgent } from './browser_agent';\nexport type { ActOptions, ActResult, ObserveOptions, ObserveResult, ExtractOptions } from './browser_agent'; ","import { Session } from '../session';\nimport { BrowserAgent } from './browser_agent';\nimport { BrowserError } from '../exceptions';\nimport { BROWSER_DATA_PATH } from '../config';\nimport { InitBrowserRequest } from '../api/models/InitBrowserRequest';\nimport { log } from '../utils/logger';\n\nexport interface BrowserViewport {\n width: number;\n height: number;\n}\n\nexport interface BrowserScreen {\n width: number;\n height: number;\n}\n\nexport interface BrowserFingerprint {\n devices?: Array<'desktop' | 'mobile'>;\n operatingSystems?: Array<'windows' | 'macos' | 'linux' | 'android' | 'ios'>;\n locales?: string[];\n}\n\nexport interface BrowserProxy {\n type: 'custom' | 'wuying';\n server?: string;\n username?: string;\n password?: string;\n strategy?: 'restricted' | 'polling';\n pollsize?: number;\n toMap(): Record<string, any>;\n}\n\nexport class BrowserProxyClass implements BrowserProxy {\n type: 'custom' | 'wuying';\n server?: string;\n username?: string;\n password?: string;\n strategy?: 'restricted' | 'polling';\n pollsize?: number;\n\n constructor(\n proxyType: 'custom' | 'wuying',\n server?: string,\n username?: string,\n password?: string,\n strategy?: 'restricted' | 'polling',\n pollsize?: number\n ) {\n this.type = proxyType;\n this.server = server;\n this.username = username;\n this.password = password;\n this.strategy = strategy;\n this.pollsize = pollsize;\n\n // Validation\n if (proxyType !== 'custom' && proxyType !== 'wuying') {\n throw new Error('proxy_type must be custom or wuying');\n }\n\n if (proxyType === 'custom' && !server) {\n throw new Error('server is required for custom proxy type');\n }\n\n if (proxyType === 'wuying' && !strategy) {\n throw new Error('strategy is required for wuying proxy type');\n }\n\n if (proxyType === 'wuying' && strategy !== 'restricted' && strategy !== 'polling') {\n throw new Error('strategy must be restricted or polling for wuying proxy type');\n }\n\n if (proxyType === 'wuying' && strategy === 'polling' && pollsize !== undefined && pollsize <= 0) {\n throw new Error('pollsize must be greater than 0 for polling strategy');\n }\n }\n\n toMap(): Record<string, any> {\n const proxyMap: Record<string, any> = {\n type: this.type\n };\n\n if (this.type === 'custom') {\n proxyMap.server = this.server;\n if (this.username) {\n proxyMap.username = this.username;\n }\n if (this.password) {\n proxyMap.password = this.password;\n }\n } else if (this.type === 'wuying') {\n proxyMap.strategy = this.strategy;\n if (this.strategy === 'polling') {\n proxyMap.pollsize = this.pollsize;\n }\n }\n\n return proxyMap;\n }\n\n static fromMap(m: Record<string, any> | null | undefined): BrowserProxyClass | null {\n if (!m || typeof m !== 'object') {\n return null;\n }\n\n const proxyType = m.type;\n if (!proxyType) {\n return null;\n }\n\n if (proxyType === 'custom') {\n return new BrowserProxyClass(\n proxyType,\n m.server,\n m.username,\n m.password\n );\n } else if (proxyType === 'wuying') {\n return new BrowserProxyClass(\n proxyType,\n undefined,\n undefined,\n undefined,\n m.strategy,\n m.pollsize || 10\n );\n } else {\n throw new Error(`Unsupported proxy type: ${proxyType}`);\n }\n }\n}\n\nexport interface BrowserOption {\n persistentPath?: string;\n useStealth?: boolean;\n userAgent?: string;\n viewport?: BrowserViewport;\n screen?: BrowserScreen;\n fingerprint?: BrowserFingerprint;\n solveCaptchas?: boolean;\n proxies?: BrowserProxy[];\n /** Path to the extensions directory. Defaults to \"/tmp/extensions/\" */\n extensionPath?: string;\n}\n\nexport class BrowserOptionClass implements BrowserOption {\n persistentPath?: string;\n useStealth?: boolean;\n userAgent?: string;\n viewport?: BrowserViewport;\n screen?: BrowserScreen;\n fingerprint?: BrowserFingerprint;\n solveCaptchas?: boolean;\n proxies?: BrowserProxy[];\n extensionPath?: string;\n\n constructor(\n useStealth = false,\n userAgent?: string,\n viewport?: BrowserViewport,\n screen?: BrowserScreen,\n fingerprint?: BrowserFingerprint,\n solveCaptchas = false,\n proxies?: BrowserProxy[],\n ) {\n this.useStealth = useStealth;\n this.userAgent = userAgent;\n this.viewport = viewport;\n this.screen = screen;\n this.fingerprint = fingerprint;\n this.solveCaptchas = solveCaptchas;\n this.extensionPath = \"/tmp/extensions/\";\n\n // Validate proxies list items\n if (proxies !== undefined) {\n if (!Array.isArray(proxies)) {\n throw new Error('proxies must be a list');\n }\n if (proxies.length > 1) {\n throw new Error('proxies list length must be limited to 1');\n }\n }\n\n // Set proxies after validation\n this.proxies = proxies;\n }\n\n toMap(): Record<string, any> {\n const optionMap: Record<string, any> = {};\n if (process.env.AGENTBAY_BROWSER_BEHAVIOR_SIMULATE) {\n optionMap['behaviorSimulate'] = (process.env.AGENTBAY_BROWSER_BEHAVIOR_SIMULATE !== \"0\") as boolean;\n }\n if (this.useStealth !== undefined) {\n optionMap['useStealth'] = this.useStealth;\n }\n if (this.userAgent !== undefined) {\n optionMap['userAgent'] = this.userAgent;\n }\n if (this.viewport !== undefined) {\n optionMap['viewport'] = { width: this.viewport.width, height: this.viewport.height };\n }\n if (this.screen !== undefined) {\n optionMap['screen'] = { width: this.screen.width, height: this.screen.height };\n }\n if (this.fingerprint !== undefined) {\n const fp: Record<string, any> = {};\n if (this.fingerprint.devices) fp['devices'] = this.fingerprint.devices;\n if (this.fingerprint.operatingSystems) fp['operatingSystems'] = this.fingerprint.operatingSystems;\n if (this.fingerprint.locales) fp['locales'] = this.fingerprint.locales;\n optionMap['fingerprint'] = fp;\n }\n if (this.solveCaptchas !== undefined) {\n optionMap['solveCaptchas'] = this.solveCaptchas;\n }\n if (this.proxies !== undefined) {\n optionMap['proxies'] = this.proxies.map(proxy => proxy.toMap());\n }\n if (this.extensionPath !== undefined) {\n optionMap['extensionPath'] = this.extensionPath;\n }\n return optionMap;\n }\n\n fromMap(m: Record<string, any> | null | undefined): BrowserOptionClass {\n const map = m || {};\n if (map.useStealth !== undefined) {\n this.useStealth = map.useStealth;\n } else {\n this.useStealth = false;\n }\n if (map.userAgent !== undefined) {\n this.userAgent = map.userAgent;\n }\n if (map.viewport !== undefined) {\n this.viewport = { width: map.viewport.width, height: map.viewport.height };\n }\n if (map.screen !== undefined) {\n this.screen = { width: map.screen.width, height: map.screen.height };\n }\n if (map.fingerprint !== undefined) {\n const fp: BrowserFingerprint = {};\n if (map.fingerprint.devices) fp.devices = map.fingerprint.devices;\n if (map.fingerprint.operatingSystems) fp.operatingSystems = map.fingerprint.operatingSystems;\n if (map.fingerprint.locales) fp.locales = map.fingerprint.locales;\n this.fingerprint = fp;\n }\n if (map.solveCaptchas !== undefined) {\n this.solveCaptchas = map.solveCaptchas;\n }\n if (map.proxies !== undefined) {\n const proxyList = map.proxies;\n if (proxyList.length > 1) {\n throw new Error('proxies list length must be limited to 1');\n }\n this.proxies = proxyList.map((proxyData: any) => {\n // If it's already a BrowserProxyClass instance, return it\n if (proxyData instanceof BrowserProxyClass) {\n return proxyData;\n }\n // Otherwise, convert from map\n return BrowserProxyClass.fromMap(proxyData);\n }).filter(Boolean) as BrowserProxy[];\n }\n if (map.extensionPath !== undefined) {\n this.extensionPath = map.extensionPath;\n }\n return this;\n }\n}\n\nexport class Browser {\n private session: Session;\n private _endpointUrl: string | null = null;\n private _initialized = false;\n private _option: BrowserOptionClass | null = null;\n public agent: BrowserAgent;\n\n constructor(session: Session) {\n this.session = session;\n this.agent = new BrowserAgent(this.session, this);\n }\n\n /**\n * Initialize the browser instance with the given options.\n * Returns true if successful, false otherwise.\n */\n initialize(option: BrowserOptionClass | BrowserOption): boolean {\n if (this.isInitialized()) {\n return true;\n }\n\n try {\n // Use direct API call to initialize browser\n const request = new InitBrowserRequest();\n request.authorization = `Bearer ${this.session.getAPIKey()}`;\n request.persistentPath = BROWSER_DATA_PATH;\n request.sessionId = this.session.getSessionId();\n\n // Ensure option is a BrowserOptionClass instance\n let browserOption: BrowserOptionClass;\n if (option instanceof BrowserOptionClass) {\n browserOption = option;\n } else {\n // Convert plain object to BrowserOptionClass instance\n browserOption = new BrowserOptionClass();\n browserOption.fromMap(option as Record<string, any>);\n }\n\n // Map BrowserOption to API BrowserOption payload\n const browserOptionMap = browserOption.toMap();\n\n // Enable record if session.enableBrowserReplay is true\n if (this.session.enableBrowserReplay) {\n browserOptionMap['enableRecord'] = true;\n }\n\n if (Object.keys(browserOptionMap).length > 0) {\n request.browserOption = browserOptionMap;\n }\n\n const response = this.session.getClient().initBrowserSync(request);\n log(`Response from init_browser data:`, response.body?.data);\n\n const success = response.body?.data?.port !== null && response.body?.data?.port !== undefined;\n if (success) {\n this._initialized = true;\n this._option = browserOption;\n log(\"Browser instance was successfully initialized.\");\n }\n\n return success;\n } catch (error) {\n console.error(\"Failed to initialize browser instance:\", error);\n this._initialized = false;\n this._endpointUrl = null;\n this._option = null;\n return false;\n }\n }\n\n /**\n * Initialize the browser instance with the given options asynchronously.\n * Returns true if successful, false otherwise.\n */\n async initializeAsync(option: BrowserOptionClass | BrowserOption): Promise<boolean> {\n if (this.isInitialized()) {\n return true;\n }\n\n try {\n // Use direct API call to initialize browser\n const request = new InitBrowserRequest();\n request.authorization = `Bearer ${this.session.getAPIKey()}`;\n request.persistentPath = BROWSER_DATA_PATH;\n request.sessionId = this.session.getSessionId();\n\n // Ensure option is a BrowserOptionClass instance\n let browserOption: BrowserOptionClass;\n if (option instanceof BrowserOptionClass) {\n browserOption = option;\n } else {\n // Convert plain object to BrowserOptionClass instance\n browserOption = new BrowserOptionClass();\n browserOption.fromMap(option as Record<string, any>);\n }\n\n // Map BrowserOption to API BrowserOption payload\n const browserOptionMap = browserOption.toMap();\n\n // Enable record if session.enableBrowserReplay is true\n if (this.session.enableBrowserReplay) {\n browserOptionMap['enableRecord'] = true;\n }\n\n if (Object.keys(browserOptionMap).length > 0) {\n request.browserOption = browserOptionMap;\n }\n\n const response = await this.session.getClient().initBrowser(request);\n log(`Response from init_browser data:`, response.body?.data);\n\n const success = response.body?.data?.port !== null && response.body?.data?.port !== undefined;\n if (success) {\n this._initialized = true;\n this._option = browserOption;\n log(\"Browser instance successfully initialized\");\n }\n\n return success;\n } catch (error) {\n console.error(\"Failed to initialize browser instance:\", error);\n this._initialized = false;\n this._endpointUrl = null;\n this._option = null;\n return false;\n }\n }\n\n /**\n * Returns the endpoint URL if the browser is initialized, otherwise throws an exception.\n * When initialized, always fetches the latest CDP url from session.getLink().\n */\n async getEndpointUrl(): Promise<string> {\n if (!this.isInitialized()) {\n throw new BrowserError(\"Browser is not initialized. Cannot access endpoint URL.\");\n }\n\n try {\n const linkResult = await this.session.getLink();\n this._endpointUrl = linkResult.data;\n return this._endpointUrl!;\n } catch (error) {\n throw new BrowserError(`Failed to get endpoint URL from session: ${error}`);\n }\n }\n\n /**\n * Returns the current BrowserOption used to initialize the browser, or null if not set.\n */\n getOption(): BrowserOptionClass | null {\n return this._option;\n }\n\n /**\n * Returns true if the browser was initialized, false otherwise.\n */\n isInitialized(): boolean {\n return this._initialized;\n }\n\n /**\n * Stop the browser instance, internal use only.\n */\n private _stopBrowser(): void {\n if (this.isInitialized()) {\n this.session.callMcpTool(\"stopChrome\", {});\n } else {\n throw new BrowserError(\"Browser is not initialized. Cannot stop browser.\");\n }\n }\n}\n","import { Session } from '../session';\nimport { Browser } from './browser';\nimport { BrowserError } from '../exceptions';\nimport { log } from '../utils/logger';\n\n// Options interfaces\nexport interface ActOptions {\n action: string;\n timeoutMS?: number;\n iframes?: boolean;\n domSettleTimeoutMS?: number;\n variables?: Record<string, string>;\n use_vision?: boolean;\n}\n\nexport interface ObserveOptions {\n instruction: string;\n iframes?: boolean;\n domSettleTimeoutMS?: number;\n use_vision?: boolean;\n}\n\nexport interface ExtractOptions<T = any> {\n instruction: string;\n schema: new (...args: any[]) => T;\n use_text_extract?: boolean;\n selector?: string;\n iframe?: boolean;\n domSettleTimeoutMS?: number;\n use_vision?: boolean;\n}\n\nexport class ActResult {\n success: boolean;\n message: string;\n action?: string;\n constructor(success: boolean, message: string, action?: string) {\n this.success = success;\n this.message = message;\n this.action = action;\n }\n}\n\nexport class ObserveResult {\n selector: string;\n description: string;\n method: string;\n args: Record<string, any>;\n constructor(selector: string, description: string, method: string, args: Record<string, any>) {\n this.selector = selector;\n this.description = description;\n this.method = method;\n this.args = args;\n }\n}\n\nexport class BrowserAgent {\n private session: Session;\n private browser: Browser;\n\n constructor(session: Session, browser: Browser) {\n this.session = session;\n this.browser = browser;\n }\n\n /** ------------------ ACT ------------------ **/\n async act(options: ActOptions, page: any): Promise<ActResult> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling act.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n action: options.action,\n variables: options.variables,\n timeout_ms: options.timeoutMS,\n iframes: options.iframes,\n dom_settle_timeout_ms: options.domSettleTimeoutMS,\n use_vision: options.use_vision\n };\n const task_name = options.action;\n log(`${task_name}`);\n \n const response = await this._callMcpTool(\"page_use_act\", args);\n\n if (response.success && response.data) {\n const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;\n return new ActResult(true, JSON.stringify(data), options.action);\n }\n return new ActResult(false, response.errorMessage || \"\");\n }\n\n async actAsync(options: ActOptions, page: any): Promise<ActResult> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling actAsync.\");\n\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n action: options.action,\n variables: options.variables,\n timeout_ms: options.timeoutMS,\n iframes: options.iframes,\n dom_settle_timeout_ms: options.domSettleTimeoutMS,\n use_vision: options.use_vision\n };\n const task_name = options.action;\n log(`${task_name}`);\n\n const startResp = await this._callMcpTool(\"page_use_act_async\", args);\n if (!startResp.success) throw new BrowserError(\"Failed to start act task\");\n\n const { task_id } = JSON.parse(startResp.data);\n let retries = 30;\n\n while (retries-- > 0) {\n await this._delay(5000);\n const pollResp = await this._callMcpTool(\"page_use_get_act_result\", { task_id });\n\n if (pollResp.success && pollResp.data) {\n const data = typeof pollResp.data === 'string' ? JSON.parse(pollResp.data) : pollResp.data;\n const steps = data.steps || [];\n const is_done = data.is_done || false;\n const success = !!data.success;\n if (is_done) {\n const msg = steps.length ? JSON.stringify(steps) : \"No actions have been executed.\";\n log(`Task ${task_id}:${task_name} is done. Success=${success}. ${msg}`);\n return new ActResult(success, msg, options.action);\n } else {\n if (steps.length) {\n log(`Task ${task_id}:${task_name} progress: ${steps.length} steps done. Details: ${JSON.stringify(steps)}`);\n } else {\n log(`Task ${task_id}:${task_name} No actions have been executed yet.`);\n }\n }\n }\n }\n throw new BrowserError(`Task ${task_id}: Act timed out`);\n }\n\n /** ------------------ OBSERVE ------------------ **/\n async observe(options: ObserveOptions, page: any): Promise<[boolean, ObserveResult[]]> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling observe.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n instruction: options.instruction,\n iframes: options.iframes,\n dom_settle_timeout_ms: options.domSettleTimeoutMS,\n use_vision: options.use_vision\n };\n\n const response = await this._callMcpTool(\"page_use_observe\", args);\n if (response.success && response.data) {\n const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;\n const results: ObserveResult[] = [];\n\n for (const item of data) {\n let argsParsed: any;\n try {\n argsParsed = typeof item.arguments === 'string' ? JSON.parse(item.arguments) : item.arguments;\n } catch {\n log(`Warning: Could not parse arguments JSON: ${item.arguments}`);\n argsParsed = item.arguments;\n }\n results.push(new ObserveResult(item.selector || \"\", item.description || \"\", item.method || \"\", argsParsed));\n }\n return [true, results];\n }\n return [false, []];\n }\n\n async observeAsync(options: ObserveOptions, page: any): Promise<[boolean, ObserveResult[]]> {\n return this.observe(options, page);\n }\n\n /** ------------------ EXTRACT ------------------ **/\n async extract<T>(options: ExtractOptions<T>, page: any): Promise<[boolean, T | null]> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling extract.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n instruction: options.instruction,\n field_schema: `schema: ${JSON.stringify({ name: options.schema.name })}`,\n use_text_extract: options.use_text_extract,\n use_vision: options.use_vision,\n selector: options.selector,\n iframe: options.iframe,\n dom_settle_timeout_ms: options.domSettleTimeoutMS\n };\n\n const response = await this._callMcpTool(\"page_use_extract\", args);\n if (response.success && response.data) {\n const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;\n return [true, data as T];\n }\n return [false, null];\n }\n\n async extractAsync<T>(options: ExtractOptions<T>, page: any): Promise<[boolean, T | null]> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling extractAsync.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n instruction: options.instruction,\n field_schema: `schema: ${JSON.stringify({ name: options.schema.name })}`,\n use_text_extract: options.use_text_extract,\n use_vision: options.use_vision,\n selector: options.selector,\n iframe: options.iframe,\n dom_settle_timeout_ms: options.domSettleTimeoutMS\n };\n\n const startResp = await this._callMcpTool(\"page_use_extract_async\", args);\n if (!startResp.success) throw new BrowserError(\"Failed to start extract task\");\n\n const { task_id } = JSON.parse(startResp.data);\n let retries = 20;\n\n while (retries-- > 0) {\n await this._delay(8000);\n const pollResp = await this._callMcpTool(\"page_use_get_extract_result\", { task_id });\n\n if (pollResp.success && pollResp.data) {\n const data = typeof pollResp.data === 'string' ? JSON.parse(pollResp.data) : pollResp.data;\n return [true, data as T];\n }\n log(`Task ${task_id}: No extract result yet (attempt ${20 - retries}/20)`);\n }\n throw new BrowserError(`Task ${task_id}: Extract timed out`);\n }\n\n private async _getPageAndContextIndexAsync(page: any): Promise<[string, number]> {\n if (!page) {\n throw new BrowserError(\"Page is null\");\n }\n\n // Try to use Playwright CDP if available\n try {\n if (page.context && typeof page.context === 'function') {\n const context = page.context();\n if (context && typeof context.newCDPSession === 'function') {\n const cdpSession = await context.newCDPSession(page);\n const targetInfo = await cdpSession.send('Target.getTargetInfo');\n const pageIndex = (targetInfo && targetInfo.targetInfo && targetInfo.targetInfo.targetId) ? targetInfo.targetInfo.targetId : 'default-page-id';\n if (typeof cdpSession.detach === 'function') {\n await cdpSession.detach();\n }\n\n let contextIndex = 0;\n if (typeof context.browser === 'function') {\n const browserObj = context.browser();\n if (browserObj && typeof browserObj.contexts === 'function') {\n const contexts = browserObj.contexts();\n const idx = contexts.indexOf(context);\n if (idx >= 0) {\n contextIndex = idx;\n }\n }\n }\n return [pageIndex, contextIndex];\n }\n }\n } catch (error) {\n log(`CDP targetId retrieval failed, fallback to defaults: ${error}`);\n }\n\n // Fallback to defaults if CDP is not available\n const pageIndex = \"default-page-id\";\n const contextIndex = 0;\n return [pageIndex, contextIndex];\n }\n\n private async _callMcpTool(toolName: string, args: Record<string, any>) {\n return this.session.callMcpTool(toolName, args);\n }\n\n private _delay(ms: number) {\n return new Promise(res => setTimeout(res, ms));\n }\n}\n","export { Code } from \"./code\";\nexport type { CodeExecutionResult } from \"../types/api-response\"; ","import {\n CodeExecutionResult,\n} from \"../types/api-response\";\n\n/**\n * Handles code execution operations in the AgentBay cloud environment.\n */\nexport class Code {\n private session: {\n getAPIKey(): string;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n };\n\n /**\n * Initialize a Code object.\n *\n * @param session - The Session instance that this Code belongs to.\n */\n constructor(session: {\n getAPIKey(): string;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n }) {\n this.session = session;\n }\n\n /**\n * Execute code in the specified language with a timeout.\n * Corresponds to Python's run_code() method\n *\n * @param code - The code to execute.\n * @param language - The programming language of the code. Must be either 'python' or 'javascript'.\n * @param timeoutS - The timeout for the code execution in seconds. Default is 60s.\n * Note: Due to gateway limitations, each request cannot exceed 60 seconds.\n * @returns CodeExecutionResult with code execution output and requestId\n * @throws Error if an unsupported language is specified.\n */\n async runCode(\n code: string,\n language: string,\n timeoutS = 60\n ): Promise<CodeExecutionResult> {\n try {\n // Validate language\n if (language !== \"python\" && language !== \"javascript\") {\n return {\n requestId: \"\",\n success: false,\n result: \"\",\n errorMessage: `Unsupported language: ${language}. Supported languages are 'python' and 'javascript'`,\n };\n }\n\n const args = {\n code,\n language,\n timeout_s: timeoutS,\n };\n\n const response = await this.session.callMcpTool(\n \"run_code\",\n args\n );\n\n if (!response.success) {\n return {\n requestId: response.requestId,\n success: false,\n result: \"\",\n errorMessage: response.errorMessage,\n };\n }\n\n return {\n requestId: response.requestId,\n success: true,\n result: response.data || \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n result: \"\",\n errorMessage: `Failed to run code: ${error}`,\n };\n }\n }\n} ","import { Session } from \"../session\";\nimport {\n CommandResult,\n} from \"../types/api-response\";\n\n\n/**\n * Handles command execution operations in the AgentBay cloud environment.\n */\nexport class Command {\n private session: Session;\n\n /**\n * Initialize a Command object.\n *\n * @param session - The Session instance that this Command belongs to.\n */\n constructor(session: Session) {\n this.session = session;\n }\n\n /**\n * Sanitizes error messages to remove sensitive information like API keys.\n *\n * @param error - The error to sanitize\n * @returns The sanitized error\n */\n private sanitizeError(error: any): any {\n if (!error) {\n return error;\n }\n\n const errorString = String(error);\n return errorString.replace(/Bearer\\s+[^\\s]+/g, \"Bearer [REDACTED]\");\n }\n\n /**\n * Execute a command in the session environment.\n * Corresponds to Python's execute_command() method\n *\n * @param command - The command to execute\n * @param timeoutMs - The timeout in milliseconds. Default is 1000ms.\n * @returns CommandResult with command output and requestId\n * @throws APIError if the operation fails.\n */\n async executeCommand(\n command: string,\n timeoutMs = 1000\n ): Promise<CommandResult> {\n try {\n const args = {\n command,\n timeout_ms: timeoutMs,\n };\n const result = await this.session.callMcpTool(\"shell\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n output: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n output: \"\",\n errorMessage: `Failed to execute command: ${error}`,\n };\n }\n }\n}\n","export { Computer, BoolResult, CursorPosition, ScreenSize, ScreenshotResult } from './computer'; ","/**\n * Computer module for desktop UI automation.\n * Provides mouse, keyboard, and screen operations for desktop environments.\n */\n\nimport { OperationResult, WindowListResult, WindowInfoResult, BoolResult as WindowBoolResult } from \"../types/api-response\";\n\nexport enum MouseButton {\n LEFT = 'left',\n RIGHT = 'right',\n MIDDLE = 'middle',\n DOUBLE_LEFT = 'double_left'\n}\n\nexport enum ScrollDirection {\n UP = 'up',\n DOWN = 'down',\n LEFT = 'left',\n RIGHT = 'right'\n}\n\nexport interface BoolResult extends OperationResult {\n data?: boolean;\n}\n\nexport interface CursorPosition extends OperationResult {\n x: number;\n y: number;\n}\n\nexport interface ScreenSize extends OperationResult {\n width: number;\n height: number;\n dpiScalingFactor: number;\n}\n\nexport interface ScreenshotResult extends OperationResult {\n data: string; // Screenshot URL\n}\n\n// Session interface for Computer module\ninterface ComputerSession {\n callMcpTool(toolName: string, args: Record<string, any>): Promise<any>;\n sessionId: string;\n getAPIKey(): string;\n getSessionId(): string;\n}\n\nexport class Computer {\n private session: ComputerSession;\n\n constructor(session: ComputerSession) {\n this.session = session;\n }\n\n /**\n * Click mouse at specified coordinates.\n */\n async clickMouse(x: number, y: number, button: MouseButton | string = MouseButton.LEFT): Promise<BoolResult> {\n const buttonStr = typeof button === 'string' ? button : button;\n const validButtons = Object.values(MouseButton);\n if (!validButtons.includes(buttonStr as MouseButton)) {\n throw new Error(`Invalid button '${buttonStr}'. Must be one of ${validButtons.join(', ')}`);\n }\n\n const args = { x, y, button: buttonStr };\n try {\n const result = await this.session.callMcpTool('click_mouse', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to click mouse: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Move mouse to specified coordinates.\n */\n async moveMouse(x: number, y: number): Promise<BoolResult> {\n const args = { x, y };\n try {\n const result = await this.session.callMcpTool('move_mouse', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to move mouse: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Drag mouse from one position to another.\n */\n async dragMouse(fromX: number, fromY: number, toX: number, toY: number, button: MouseButton | string = MouseButton.LEFT): Promise<BoolResult> {\n const buttonStr = typeof button === 'string' ? button : button;\n const validButtons = [MouseButton.LEFT, MouseButton.RIGHT, MouseButton.MIDDLE];\n if (!validButtons.includes(buttonStr as MouseButton)) {\n throw new Error(`Invalid button '${buttonStr}'. Must be one of ${validButtons.join(', ')}`);\n }\n\n const args = { from_x: fromX, from_y: fromY, to_x: toX, to_y: toY, button: buttonStr };\n try {\n const result = await this.session.callMcpTool('drag_mouse', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to drag mouse: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Scroll at specified coordinates.\n */\n async scroll(x: number, y: number, direction: ScrollDirection | string = ScrollDirection.UP, amount = 1): Promise<BoolResult> {\n const directionStr = typeof direction === 'string' ? direction : direction;\n const validDirections = Object.values(ScrollDirection);\n if (!validDirections.includes(directionStr as ScrollDirection)) {\n throw new Error(`Invalid direction '${directionStr}'. Must be one of ${validDirections.join(', ')}`);\n }\n\n const args = { x, y, direction: directionStr, amount };\n try {\n const result = await this.session.callMcpTool('scroll', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to scroll: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Input text.\n */\n async inputText(text: string): Promise<BoolResult> {\n const args = { text };\n try {\n const result = await this.session.callMcpTool('input_text', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to input text: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Press keys.\n */\n async pressKeys(keys: string[], hold = false): Promise<BoolResult> {\n const args = { keys, hold };\n try {\n const result = await this.session.callMcpTool('press_keys', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to press keys: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Release keys.\n */\n async releaseKeys(keys: string[]): Promise<BoolResult> {\n const args = { keys };\n try {\n const result = await this.session.callMcpTool('release_keys', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to release keys: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Get cursor position.\n */\n async getCursorPosition(): Promise<CursorPosition> {\n try {\n const result = await this.session.callMcpTool('get_cursor_position', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get cursor position',\n x: 0,\n y: 0\n };\n }\n\n // Parse JSON response from data field (callMcpTool already extracts content[0].text to data)\n const content = result.data;\n if (!content) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: 'No content in response',\n x: 0,\n y: 0\n };\n }\n\n try {\n const position = JSON.parse(content);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n x: position.x || 0,\n y: position.y || 0\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse cursor position: ${parseError}`,\n x: 0,\n y: 0\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get cursor position: ${error instanceof Error ? error.message : String(error)}`,\n x: 0,\n y: 0\n };\n }\n }\n\n /**\n * Get screen size.\n */\n async getScreenSize(): Promise<ScreenSize> {\n try {\n const result = await this.session.callMcpTool('get_screen_size', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get screen size',\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n\n // Parse JSON response from data field (callMcpTool already extracts content[0].text to data)\n const content = result.data;\n if (!content) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: 'No content in response',\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n\n try {\n const screenInfo = JSON.parse(content);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n width: screenInfo.width || 0,\n height: screenInfo.height || 0,\n dpiScalingFactor: screenInfo.dpiScalingFactor || 1.0\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse screen size: ${parseError}`,\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get screen size: ${error instanceof Error ? error.message : String(error)}`,\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n }\n\n /**\n * Take a screenshot.\n */\n async screenshot(): Promise<ScreenshotResult> {\n try {\n const result = await this.session.callMcpTool('system_screenshot', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to take screenshot',\n data: ''\n };\n }\n\n const screenshotUrl = result.content?.[0]?.text || '';\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n data: screenshotUrl\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to take screenshot: ${error instanceof Error ? error.message : String(error)}`,\n data: ''\n };\n }\n }\n\n /**\n * Lists all root windows.\n */\n async listRootWindows(timeoutMs = 3000): Promise<WindowListResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.listRootWindows(timeoutMs);\n }\n\n /**\n * Gets the currently active window.\n */\n async getActiveWindow(timeoutMs = 3000): Promise<WindowInfoResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.getActiveWindow(timeoutMs);\n }\n\n /**\n * Activates the specified window.\n */\n async activateWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.activateWindow(windowId);\n }\n\n /**\n * Closes the specified window.\n */\n async closeWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.closeWindow(windowId);\n }\n\n /**\n * Maximizes the specified window.\n */\n async maximizeWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.maximizeWindow(windowId);\n }\n\n /**\n * Minimizes the specified window.\n */\n async minimizeWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.minimizeWindow(windowId);\n }\n\n /**\n * Restores the specified window.\n */\n async restoreWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.restoreWindow(windowId);\n }\n\n /**\n * Resizes the specified window.\n */\n async resizeWindow(windowId: number, width: number, height: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.resizeWindow(windowId, width, height);\n }\n\n /**\n * Makes the specified window fullscreen.\n */\n async fullscreenWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.fullscreenWindow(windowId);\n }\n\n /**\n * Toggles focus mode on or off.\n */\n async focusMode(on: boolean): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.focusMode(on);\n }\n} ","import { Client } from \"./api/client\";\nimport { GetContextInfoRequest, SyncContextRequest } from \"./api/models/model\";\nimport { ApiResponse, extractRequestId } from \"./types/api-response\";\nimport { log, logError } from \"./utils/logger\";\n\nexport interface ContextStatusData {\n contextId: string;\n path: string;\n errorMessage: string;\n status: string;\n startTime: number;\n finishTime: number;\n taskType: string;\n}\n\nexport interface ContextStatusItem {\n type: string;\n data: string;\n}\n\nexport interface ContextInfoResult extends ApiResponse {\n success?: boolean;\n contextStatusData: ContextStatusData[];\n errorMessage?: string;\n}\n\nexport interface ContextSyncResult extends ApiResponse {\n success: boolean;\n errorMessage?: string;\n}\n\nexport type SyncCallback = (success: boolean) => void;\n\nexport interface SessionInterface {\n getAPIKey(): string;\n getClient(): Client;\n getSessionId(): string;\n}\n\nexport class ContextManager {\n private session: SessionInterface;\n\n constructor(session: SessionInterface) {\n this.session = session;\n }\n\n async info(): Promise<ContextInfoResult> {\n return this.infoWithParams();\n }\n\n async infoWithParams(\n contextId?: string,\n path?: string,\n taskType?: string\n ): Promise<ContextInfoResult> {\n const request = new GetContextInfoRequest({\n authorization: `Bearer ${this.session.getAPIKey()}`,\n sessionId: this.session.getSessionId(),\n });\n\n // Set optional parameters if provided\n if (contextId) {\n request.contextId = contextId;\n }\n if (path) {\n request.path = path;\n }\n if (taskType) {\n request.taskType = taskType;\n }\n\n // Log API request (matching Go version format)\n log(\"API Call: GetContextInfo\");\n let requestLog = `Request: SessionId=${request.sessionId}`;\n if (request.contextId) {\n requestLog += `, ContextId=${request.contextId}`;\n }\n if (request.path) {\n requestLog += `, Path=${request.path}`;\n }\n if (request.taskType) {\n requestLog += `, TaskType=${request.taskType}`;\n }\n log(requestLog);\n\n try {\n const response = await this.session.getClient().getContextInfo(request);\n\n // Extract RequestID\n const requestId = extractRequestId(response) || \"\";\n\n if (response?.body) {\n log(\"Response from GetContextInfo:\", response.body);\n }\n\n // Check for API-level errors\n if (response?.body?.success === false && response.body.code) {\n return {\n requestId,\n success: false,\n contextStatusData: [],\n errorMessage: `[${response.body.code}] ${response.body.message || 'Unknown error'}`,\n };\n }\n\n // Parse the context status data\n const contextStatusData: ContextStatusData[] = [];\n if (response?.body?.data?.contextStatus) {\n try {\n // First, parse the outer array\n const contextStatusStr = response.body.data.contextStatus;\n const statusItems: ContextStatusItem[] = JSON.parse(contextStatusStr);\n \n // Process each item in the array\n for (const item of statusItems) {\n if (item.type === \"data\") {\n // Parse the inner data string\n const dataItems: ContextStatusData[] = JSON.parse(item.data);\n contextStatusData.push(...dataItems);\n }\n }\n } catch (error) {\n logError(\"Error parsing context status:\", error);\n }\n }\n\n return {\n requestId,\n success: true,\n contextStatusData,\n errorMessage: undefined,\n };\n } catch (error) {\n logError(\"Error calling GetContextInfo:\", error);\n throw new Error(`Failed to get context info: ${error}`);\n }\n }\n\n async sync(\n contextId?: string,\n path?: string,\n mode?: string,\n callback?: SyncCallback,\n maxRetries: number = 150,\n retryInterval: number = 1500\n ): Promise<ContextSyncResult> {\n const request = new SyncContextRequest({\n authorization: `Bearer ${this.session.getAPIKey()}`,\n sessionId: this.session.getSessionId(),\n });\n\n // Set optional parameters if provided\n if (contextId) {\n request.contextId = contextId;\n }\n if (path) {\n request.path = path;\n }\n if (mode) {\n request.mode = mode;\n }\n\n // Log API request (matching Go version format)\n log(\"API Call: SyncContext\");\n let requestLog = `Request: SessionId=${request.sessionId}`;\n if (request.contextId) {\n requestLog += `, ContextId=${request.contextId}`;\n }\n if (request.path) {\n requestLog += `, Path=${request.path}`;\n }\n if (request.mode) {\n requestLog += `, Mode=${request.mode}`;\n }\n log(requestLog);\n\n try {\n const response = await this.session.getClient().syncContext(request);\n\n // Extract RequestID\n const requestId = extractRequestId(response) || \"\";\n\n if (response?.body) {\n log(\"Response from SyncContext:\", response.body);\n }\n\n // Check for API-level errors\n if (response?.body?.success === false && response.body.code) {\n return {\n requestId,\n success: false,\n errorMessage: `[${response.body.code}] ${response.body.message || 'Unknown error'}`,\n };\n }\n\n let success = false;\n if (response?.body?.success !== undefined) {\n success = response.body.success;\n }\n\n // If callback is provided, start polling in background (async mode)\n if (callback && success) {\n // Start polling in background without blocking\n this.pollForCompletion(callback, contextId, path, maxRetries, retryInterval)\n .catch((error) => {\n logError(\"Error in background polling:\", error);\n callback(false);\n });\n return {\n requestId,\n success,\n };\n }\n\n // If no callback, wait for completion (sync mode)\n if (success) {\n const finalSuccess = await this.pollForCompletionAsync(\n contextId,\n path,\n maxRetries,\n retryInterval\n );\n return {\n requestId,\n success: finalSuccess,\n };\n }\n\n return {\n requestId,\n success,\n };\n } catch (error) {\n logError(\"Error calling SyncContext:\", error);\n throw new Error(`Failed to sync context: ${error}`);\n }\n }\n\n /**\n * Polls the info interface to check if sync is completed and calls callback.\n */\n private async pollForCompletion(\n callback: SyncCallback,\n contextId?: string,\n path?: string,\n maxRetries: number = 150,\n retryInterval: number = 1500\n ): Promise<void> {\n for (let retry = 0; retry < maxRetries; retry++) {\n try {\n // Get context status data\n const infoResult = await this.infoWithParams(contextId, path);\n\n // Check if all sync tasks are completed\n let allCompleted = true;\n let hasFailure = false;\n let hasSyncTasks = false;\n\n for (const item of infoResult.contextStatusData) {\n // We only care about sync tasks (upload/download)\n if (item.taskType !== \"upload\" && item.taskType !== \"download\") {\n continue;\n }\n\n hasSyncTasks = true;\n log(`Sync task ${item.contextId} status: ${item.status}, path: ${item.path}`);\n\n if (item.status !== \"Success\" && item.status !== \"Failed\") {\n allCompleted = false;\n break;\n }\n\n if (item.status === \"Failed\") {\n hasFailure = true;\n logError(`Sync failed for context ${item.contextId}: ${item.errorMessage}`);\n }\n }\n\n if (allCompleted || !hasSyncTasks) {\n // All tasks completed or no sync tasks found\n if (hasFailure) {\n log(\"Context sync completed with failures\");\n callback(false);\n } else if (hasSyncTasks) {\n log(\"Context sync completed successfully\");\n callback(true);\n } else {\n log(\"No sync tasks found\");\n callback(true);\n }\n return; // Exit the function immediately after calling callback\n }\n\n log(`Waiting for context sync to complete, attempt ${retry + 1}/${maxRetries}`);\n await this.sleep(retryInterval);\n } catch (error) {\n logError(`Error checking context status on attempt ${retry + 1}:`, error);\n await this.sleep(retryInterval);\n }\n }\n\n // If we've exhausted all retries, call callback with failure\n logError(`Context sync polling timed out after ${maxRetries} attempts`);\n callback(false);\n }\n\n /**\n * Async version of polling for sync completion.\n */\n private async pollForCompletionAsync(\n contextId?: string,\n path?: string,\n maxRetries: number = 150,\n retryInterval: number = 1500\n ): Promise<boolean> {\n for (let retry = 0; retry < maxRetries; retry++) {\n try {\n // Get context status data\n const infoResult = await this.infoWithParams(contextId, path);\n\n // Check if all sync tasks are completed\n let allCompleted = true;\n let hasFailure = false;\n let hasSyncTasks = false;\n\n for (const item of infoResult.contextStatusData) {\n // We only care about sync tasks (upload/download)\n if (item.taskType !== \"upload\" && item.taskType !== \"download\") {\n continue;\n }\n\n hasSyncTasks = true;\n log(`Sync task ${item.contextId} status: ${item.status}, path: ${item.path}`);\n\n if (item.status !== \"Success\" && item.status !== \"Failed\") {\n allCompleted = false;\n break;\n }\n\n if (item.status === \"Failed\") {\n hasFailure = true;\n logError(`Sync failed for context ${item.contextId}: ${item.errorMessage}`);\n }\n }\n\n if (allCompleted || !hasSyncTasks) {\n // All tasks completed or no sync tasks found\n if (hasFailure) {\n log(\"Context sync completed with failures\");\n return false;\n } else if (hasSyncTasks) {\n log(\"Context sync completed successfully\");\n return true;\n } else {\n log(\"No sync tasks found\");\n return true;\n }\n }\n\n log(`Waiting for context sync to complete, attempt ${retry + 1}/${maxRetries}`);\n await this.sleep(retryInterval);\n } catch (error) {\n logError(`Error checking context status on attempt ${retry + 1}:`, error);\n await this.sleep(retryInterval);\n }\n }\n\n // If we've exhausted all retries, return failure\n logError(`Context sync polling timed out after ${maxRetries} attempts`);\n return false;\n }\n\n /**\n * Sleep utility function for TypeScript\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\nexport function newContextManager(session: SessionInterface): ContextManager {\n return new ContextManager(session);\n}\n","import {\n BoolResult,\n FileInfoResult,\n DirectoryListResult,\n FileContentResult,\n MultipleFileContentResult,\n FileSearchResult,\n ApiResponse,\n} from \"../types/api-response\";\nimport { UploadResult, DownloadResult } from \"./file-transfer\";\nimport { FileTransfer } from \"./file-transfer\";\nimport { Session } from \"../session\";\nimport { log } from \"../utils/logger\";\n\n// Default chunk size for large file operations (60KB)\nconst DEFAULT_CHUNK_SIZE = 60 * 1024;\n\n/**\n * Represents a single file change event\n */\nexport interface FileChangeEvent {\n eventType: string; // \"create\", \"modify\", \"delete\"\n path: string;\n pathType: string; // \"file\", \"directory\"\n}\n\n/**\n * Result of file change detection operations\n */\nexport interface FileChangeResult extends ApiResponse {\n events: FileChangeEvent[];\n rawData: string;\n}\n\n/**\n * Helper functions for FileChangeEvent\n */\nexport class FileChangeEventHelper {\n static toString(event: FileChangeEvent): string {\n return `FileChangeEvent(eventType='${event.eventType}', path='${event.path}', pathType='${event.pathType}')`;\n }\n\n static toDict(event: FileChangeEvent): Record<string, string> {\n return {\n eventType: event.eventType,\n path: event.path,\n pathType: event.pathType,\n };\n }\n\n static fromDict(data: Record<string, any>): FileChangeEvent {\n return {\n eventType: data.eventType || \"\",\n path: data.path || \"\",\n pathType: data.pathType || \"\",\n };\n }\n}\n\n/**\n * Helper functions for FileChangeResult\n */\nexport class FileChangeResultHelper {\n static hasChanges(result: FileChangeResult): boolean {\n return result.events.length > 0;\n }\n\n static getModifiedFiles(result: FileChangeResult): string[] {\n return result.events\n .filter(event => event.eventType === \"modify\" && event.pathType === \"file\")\n .map(event => event.path);\n }\n\n static getCreatedFiles(result: FileChangeResult): string[] {\n return result.events\n .filter(event => event.eventType === \"create\" && event.pathType === \"file\")\n .map(event => event.path);\n }\n\n static getDeletedFiles(result: FileChangeResult): string[] {\n return result.events\n .filter(event => event.eventType === \"delete\" && event.pathType === \"file\")\n .map(event => event.path);\n }\n}\n\n/**\n * FileInfo represents information about a file or directory\n */\nexport interface FileInfo {\n name: string;\n path: string;\n size: number;\n isDirectory: boolean;\n modTime: string;\n mode: string;\n owner?: string;\n group?: string;\n}\n\n/**\n * DirectoryEntry represents an entry in a directory listing\n */\nexport interface DirectoryEntry {\n name: string;\n isDirectory: boolean;\n}\n\n/**\n * Parse a file info string into a FileInfo object\n *\n * @param fileInfoStr - The file info string to parse\n * @returns A FileInfo object\n */\nfunction parseFileInfo(fileInfoStr: string): FileInfo {\n const result: FileInfo = {\n name: \"\",\n path: \"\",\n size: 0,\n isDirectory: false,\n modTime: \"\",\n mode: \"\",\n };\n\n const lines = fileInfoStr.split(\"\\n\");\n for (const line of lines) {\n if (line.includes(\":\")) {\n const [key, value] = line.split(\":\", 2).map((part) => part.trim());\n\n switch (key) {\n case \"name\":\n result.name = value;\n break;\n case \"path\":\n result.path = value;\n break;\n case \"size\":\n result.size = parseInt(value, 10);\n break;\n case \"isDirectory\":\n result.isDirectory = value === \"true\";\n break;\n case \"modTime\":\n result.modTime = value;\n break;\n case \"mode\":\n result.mode = value;\n break;\n case \"owner\":\n result.owner = value;\n break;\n case \"group\":\n result.group = value;\n break;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Parse a directory listing string into an array of DirectoryEntry objects\n *\n * @param text - The directory listing text to parse\n * @returns An array of DirectoryEntry objects\n */\nfunction parseDirectoryListing(text: string): DirectoryEntry[] {\n const result: DirectoryEntry[] = [];\n const lines = text.split(\"\\n\");\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (trimmedLine === \"\") {\n continue;\n }\n\n if (trimmedLine.startsWith(\"[DIR]\")) {\n result.push({\n isDirectory: true,\n name: trimmedLine.replace(\"[DIR]\", \"\").trim(),\n });\n } else if (trimmedLine.startsWith(\"[FILE]\")) {\n result.push({\n isDirectory: false,\n name: trimmedLine.replace(\"[FILE]\", \"\").trim(),\n });\n }\n }\n\n return result;\n}\n\n/**\n * Handles file operations in the AgentBay cloud environment.\n */\nexport class FileSystem {\n private session: Session;\n \n private _fileTransfer: FileTransfer | null = null;\n\n /**\n * Initialize a FileSystem object.\n *\n * @param session - The Session instance that this FileSystem belongs to.\n */\n constructor(session: Session) {\n this.session = session;\n }\n\n /**\n * Ensure FileTransfer is initialized with the current session.\n * \n * @returns The FileTransfer instance\n */\n private _ensureFileTransfer(): FileTransfer {\n if (this._fileTransfer === null) {\n // Get the agent_bay instance from the session\n const agentBay = this.session.getAgentBay();\n if (agentBay === undefined) {\n throw new Error(\"FileTransfer requires an AgentBay instance\");\n }\n \n this._fileTransfer = new FileTransfer(agentBay, this.session);\n }\n \n return this._fileTransfer;\n }\n\n /**\n * Creates a new directory at the specified path.\n * Corresponds to Python's create_directory() method\n *\n * @param path - Path to the directory to create.\n * @returns BoolResult with creation result and requestId\n */\n async createDirectory(path: string): Promise<BoolResult> {\n try {\n const args = {\n path,\n };\n\n const result = await this.session.callMcpTool(\n \"create_directory\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to create directory: ${error}`,\n };\n }\n }\n\n /**\n * Edits a file by replacing occurrences of oldText with newText.\n * Corresponds to Python's edit_file() method\n *\n * @param path - Path to the file to edit.\n * @param edits - Array of edit operations, each containing oldText and newText.\n * @param dryRun - Optional: If true, preview changes without applying them.\n * @returns BoolResult with edit result and requestId\n */\n async editFile(\n path: string,\n edits: Array<{ oldText: string; newText: string }>,\n dryRun = false\n ): Promise<BoolResult> {\n try {\n const args = {\n path,\n edits,\n dryRun,\n };\n\n const result = await this.session.callMcpTool(\n \"edit_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to edit file: ${error}`,\n };\n }\n }\n\n /**\n * Gets information about a file or directory.\n * Corresponds to Python's get_file_info() method\n *\n * @param path - Path to the file or directory to inspect.\n * @returns FileInfoResult with file info and requestId\n */\n async getFileInfo(path: string): Promise<FileInfoResult> {\n try {\n const args = {\n path,\n };\n\n const result = await this.session.callMcpTool(\n \"get_file_info\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n fileInfo: {},\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse and return the file info\n if (!result.data) {\n return {\n requestId: result.requestId,\n success: false,\n fileInfo: {},\n errorMessage: \"Empty response from get_file_info\",\n };\n }\n\n const fileInfo = parseFileInfo(result.data);\n\n return {\n requestId: result.requestId,\n success: true,\n fileInfo,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to get file info: ${error}`,\n };\n }\n }\n\n /**\n * Lists the contents of a directory.\n * Corresponds to Python's list_directory() method\n *\n * @param path - Path to the directory to list.\n * @returns DirectoryListResult with directory entries and requestId\n */\n async listDirectory(path: string): Promise<DirectoryListResult> {\n try {\n const args = {\n path,\n };\n\n const result = await this.session.callMcpTool(\n \"list_directory\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n entries: [],\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse the text content into directory entries\n const entries = result.data\n ? parseDirectoryListing(result.data)\n : [];\n\n return {\n requestId: result.requestId,\n success: true,\n entries,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n entries: [],\n errorMessage: `Failed to list directory: ${error}`,\n };\n }\n }\n\n /**\n * Moves a file or directory from source to destination.\n * Corresponds to Python's move_file() method\n *\n * @param source - Path to the source file or directory.\n * @param destination - Path to the destination file or directory.\n * @returns BoolResult with move result and requestId\n */\n async moveFile(source: string, destination: string): Promise<BoolResult> {\n try {\n const args = {\n source,\n destination,\n };\n\n const result = await this.session.callMcpTool(\n \"move_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to move file: ${error}`,\n };\n }\n }\n\n /**\n * Internal method to read a file chunk. Used for chunked file operations.\n *\n * @param path - Path to the file to read.\n * @param offset - Optional: Byte offset to start reading from (0-based).\n * @param length - Optional: Number of bytes to read. If 0, reads the entire file from offset.\n * @returns FileContentResult with file content and requestId\n */\n private async readFileChunk(\n path: string,\n offset = 0,\n length = 0\n ): Promise<FileContentResult> {\n try {\n const args: any = {\n path,\n };\n\n if (offset > 0) {\n args.offset = offset;\n }\n\n if (length > 0) {\n args.length = length;\n }\n\n const result = await this.session.callMcpTool(\n \"read_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n content: \"\",\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n content: result.data || \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to read file: ${error}`,\n };\n }\n }\n\n /**\n * Reads the content of multiple files.\n * Corresponds to Python's read_multiple_files() method\n *\n * @param paths - Array of file paths to read.\n * @returns MultipleFileContentResult with file contents and requestId\n */\n async readMultipleFiles(paths: string[]): Promise<MultipleFileContentResult> {\n try {\n const args = {\n paths,\n };\n\n const result = await this.session.callMcpTool(\n \"read_multiple_files\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n contents: {},\n errorMessage: result.errorMessage,\n };\n }\n\n const fileContents: Record<string, string> = {};\n\n if (result.data) {\n // Parse the response into a map of file paths to contents\n const lines = result.data.split(\"\\n\");\n let currentPath = \"\";\n let currentContent: string[] = [];\n\n for (const line of lines) {\n // Check if this line contains a file path (ends with a colon)\n const colonIndex = line.indexOf(\":\");\n if (\n colonIndex > 0 &&\n currentPath === \"\" &&\n !line.substring(0, colonIndex).includes(\" \")\n ) {\n // Extract path (everything before the first colon)\n const path = line.substring(0, colonIndex).trim();\n\n // Start collecting content (everything after the colon)\n currentPath = path;\n\n // If there's content on the same line after the colon, add it\n if (line.length > colonIndex + 1) {\n const contentStart = line.substring(colonIndex + 1).trim();\n if (contentStart) {\n currentContent.push(contentStart);\n }\n }\n } else if (line === \"---\") {\n // Save the current file content\n if (currentPath) {\n fileContents[currentPath] = currentContent.join(\"\\n\");\n currentPath = \"\";\n currentContent = [];\n }\n } else if (currentPath) {\n // If we're collecting content for a path, add this line\n currentContent.push(line);\n }\n }\n\n // Save the last file content if exists\n if (currentPath) {\n fileContents[currentPath] = currentContent.join(\"\\n\");\n }\n\n // Trim trailing newlines from file contents to match expected test values\n for (const path in fileContents) {\n fileContents[path] = fileContents[path].replace(/\\n+$/, \"\");\n }\n }\n\n return {\n requestId: result.requestId,\n success: true,\n contents: fileContents,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n contents: {},\n errorMessage: `Failed to read multiple files: ${error}`,\n };\n }\n }\n\n /**\n * Searches for files in a directory that match a pattern.\n * Corresponds to Python's search_files() method\n *\n * @param path - Path to the directory to search in.\n * @param pattern - Pattern to search for. Supports glob patterns.\n * @param excludePatterns - Optional: Array of patterns to exclude.\n * @returns FileSearchResult with search results and requestId\n */\n async searchFiles(\n path: string,\n pattern: string,\n excludePatterns: string[] = []\n ): Promise<FileSearchResult> {\n try {\n const args: any = {\n path,\n pattern,\n };\n\n if (excludePatterns.length > 0) {\n args.excludePatterns = excludePatterns;\n }\n\n const result = await this.session.callMcpTool(\n \"search_files\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n matches: [],\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse the text content into search results\n let searchResults: string[] = [];\n if (result.data) {\n // Split by newlines and filter out empty lines\n searchResults = result.data\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\");\n }\n\n return {\n requestId: result.requestId,\n success: true,\n matches: searchResults,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n matches: [],\n errorMessage: `Failed to search files: ${error}`,\n };\n }\n }\n\n /**\n * Internal method to write a file chunk. Used for chunked file operations.\n *\n * @param path - Path to the file to write.\n * @param content - Content to write to the file.\n * @param mode - Optional: Write mode. One of \"overwrite\", \"append\", or \"create_new\". Default is \"overwrite\".\n * @returns BoolResult with write result and requestId\n */\n private async writeFileChunk(\n path: string,\n content: string,\n mode = \"overwrite\"\n ): Promise<BoolResult> {\n try {\n // Validate mode\n const validModes = [\"overwrite\", \"append\", \"create_new\"];\n if (!validModes.includes(mode)) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Invalid mode: ${mode}. Must be one of ${validModes.join(\n \", \"\n )}`,\n };\n }\n\n const args = {\n path,\n content,\n mode,\n };\n\n const result = await this.session.callMcpTool(\n \"write_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to write file: ${error}`,\n };\n }\n }\n\n /**\n * Reads the contents of a file. Automatically handles large files by chunking.\n *\n * @param path - Path to the file to read.\n * @returns FileContentResult with complete file content and requestId\n */\n async readFile(\n path: string\n ): Promise<FileContentResult> {\n const chunkSize = DEFAULT_CHUNK_SIZE;\n try {\n // First get the file info\n const fileInfoResult = await this.getFileInfo(path);\n\n if (!fileInfoResult.success) {\n return {\n requestId: fileInfoResult.requestId,\n success: false,\n content: \"\",\n errorMessage: fileInfoResult.errorMessage,\n };\n }\n\n // Check if file exists and is a file (not a directory)\n if (!fileInfoResult.fileInfo || fileInfoResult.fileInfo.isDirectory) {\n return {\n requestId: fileInfoResult.requestId,\n success: false,\n content: \"\",\n errorMessage: `Path does not exist or is a directory: ${path}`,\n };\n }\n\n // Get size from the fileInfo object\n const fileSize = fileInfoResult.fileInfo.size || 0;\n\n if (fileSize === 0) {\n return {\n requestId: fileInfoResult.requestId,\n success: true,\n content: \"\",\n };\n }\n\n // Read the file in chunks\n let result = \"\";\n let offset = 0;\n let chunkCount = 0;\n\n while (offset < fileSize) {\n // Calculate how much to read in this chunk\n let length = chunkSize;\n if (offset + length > fileSize) {\n length = fileSize - offset;\n }\n\n try {\n // Read the chunk\n const chunkResult = await this.readFileChunk(path, offset, length);\n\n if (!chunkResult.success) {\n return chunkResult; // Return the error\n }\n\n // Extract the actual content from the response\n result += chunkResult.content;\n\n // Move to the next chunk\n offset += length;\n chunkCount++;\n } catch (error) {\n return {\n requestId: fileInfoResult.requestId,\n success: false,\n content: \"\",\n errorMessage: `Error reading chunk at offset ${offset}: ${error}`,\n };\n }\n }\n\n return {\n requestId: fileInfoResult.requestId,\n success: true,\n content: result,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to read large file: ${error}`,\n };\n }\n }\n\n /**\n * Writes content to a file. Automatically handles large files by chunking.\n *\n * @param path - Path to the file to write.\n * @param content - Content to write to the file.\n * @param mode - Optional: Write mode. One of \"overwrite\", \"append\", or \"create_new\". Default is \"overwrite\".\n * @returns BoolResult indicating success or failure with requestId\n */\n async writeFile(\n path: string,\n content: string,\n mode = \"overwrite\"\n ): Promise<BoolResult> {\n const chunkSize = DEFAULT_CHUNK_SIZE;\n try {\n const contentLen = content.length;\n\n // If content is small enough, use the regular writeFileChunk method\n if (contentLen <= chunkSize) {\n return await this.writeFileChunk(path, content, mode);\n }\n\n // Write the first chunk with the specified mode\n const firstChunkEnd = Math.min(chunkSize, contentLen);\n\n const firstResult = await this.writeFileChunk(\n path,\n content.substring(0, firstChunkEnd),\n mode\n );\n\n if (!firstResult.success) {\n return firstResult;\n }\n\n // Write the remaining chunks with \"append\" mode\n let chunkCount = 1; // Already wrote first chunk\n for (let offset = firstChunkEnd; offset < contentLen; ) {\n const end = Math.min(offset + chunkSize, contentLen);\n\n const chunkResult = await this.writeFileChunk(\n path,\n content.substring(offset, end),\n \"append\"\n );\n\n if (!chunkResult.success) {\n return chunkResult;\n }\n\n offset = end;\n chunkCount++;\n }\n\n return {\n requestId: firstResult.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to write large file: ${error}`,\n };\n }\n }\n\n /**\n * Get file change information for the specified directory path\n */\n async getFileChange(path: string): Promise<FileChangeResult> {\n try {\n const args = { path };\n const result = await this.session.callMcpTool(\"get_file_change\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n events: [],\n rawData: result.data || \"\",\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse the file change events\n const events = this.parseFileChangeData(result.data);\n\n return {\n requestId: result.requestId,\n success: true,\n events,\n rawData: result.data,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n events: [],\n rawData: \"\",\n errorMessage: `Failed to get file change: ${error}`,\n };\n }\n }\n\n /**\n * Parse raw JSON data into FileChangeEvent array\n */\n private parseFileChangeData(rawData: string): FileChangeEvent[] {\n const events: FileChangeEvent[] = [];\n \n try {\n const changeData = JSON.parse(rawData);\n if (Array.isArray(changeData)) {\n for (const eventDict of changeData) {\n if (typeof eventDict === \"object\" && eventDict !== null) {\n const event = FileChangeEventHelper.fromDict(eventDict);\n events.push(event);\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to parse JSON data: ${error}`);\n }\n \n return events;\n }\n\n /**\n * Watch a directory for file changes and call the callback function when changes occur\n */\n async watchDirectory(\n path: string,\n callback: (events: FileChangeEvent[]) => void,\n interval = 500,\n signal?: AbortSignal\n ): Promise<void> {\n console.log(`Starting directory monitoring for: ${path}`);\n console.log(`Polling interval: ${interval} ms`);\n\n const monitor = async () => {\n while (!signal?.aborted) {\n try {\n const result = await this.getFileChange(path);\n\n if (result.success && result.events.length > 0) {\n console.log(`Detected ${result.events.length} file changes:`);\n for (const event of result.events) {\n console.log(` - ${FileChangeEventHelper.toString(event)}`);\n }\n\n try {\n callback(result.events);\n } catch (error) {\n console.error(`Error in callback function: ${error}`);\n }\n } else if (!result.success) {\n console.error(`Error monitoring directory: ${result.errorMessage}`);\n }\n\n // Wait for next poll\n await new Promise((resolve) => {\n const timeoutId = setTimeout(resolve, interval);\n signal?.addEventListener(\"abort\", () => {\n clearTimeout(timeoutId);\n resolve(void 0);\n });\n });\n } catch (error) {\n console.error(`Unexpected error in directory monitoring: ${error}`);\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n }\n\n console.log(`Stopped monitoring directory: ${path}`);\n };\n\n return monitor();\n }\n\n /**\n * Upload a file from local to remote path using pre-signed URLs.\n * This is a synchronous wrapper around the FileTransfer.upload method.\n *\n * @param localPath - Local file path to upload\n * @param remotePath - Remote file path to upload to\n * @param options - Optional parameters\n * @returns UploadResult with upload result and requestId\n */\n async uploadFile(\n localPath: string,\n remotePath: string,\n options?: {\n contentType?: string;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesTransferred: number) => void;\n }\n ): Promise<any> {\n try {\n // Ensure FileTransfer is initialized\n const fileTransfer = this._ensureFileTransfer();\n \n // Perform upload\n const result = await fileTransfer.upload(localPath, remotePath, options);\n \n // If upload was successful, delete the file from OSS\n if (result.success && (this.session as any).fileTransferContextId) {\n const contextId = (this.session as any).fileTransferContextId;\n if (contextId) {\n try {\n // Delete the uploaded file from OSS\n const deleteResult = await (this.session as any).agentBay.context.deleteFile(contextId, remotePath);\n if (!deleteResult.success) {\n log(`Warning: Failed to delete uploaded file from OSS: ${deleteResult}`);\n }\n } catch (deleteError: any) {\n log(`Warning: Error deleting uploaded file from OSS: ${deleteError}`);\n }\n }\n }\n \n return result;\n } catch (error) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: `Upload failed: ${error}`,\n };\n }\n }\n\n /**\n * Download a file from remote path to local path using pre-signed URLs.\n * This is a synchronous wrapper around the FileTransfer.download method.\n *\n * @param remotePath - Remote file path to download from\n * @param localPath - Local file path to download to\n * @param options - Optional parameters\n * @returns DownloadResult with download result and requestId\n */\n async downloadFile(\n remotePath: string,\n localPath: string,\n options?: {\n overwrite?: boolean;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesReceived: number) => void;\n }\n ): Promise<any> {\n try {\n // Ensure FileTransfer is initialized\n const fileTransfer = this._ensureFileTransfer();\n \n // Perform download\n const result = await fileTransfer.download(remotePath, localPath, options);\n \n // If download was successful, delete the file from OSS\n if (result.success && (this.session as any).fileTransferContextId) {\n const contextId = (this.session as any).fileTransferContextId;\n if (contextId) {\n try {\n // Delete the downloaded file from OSS\n const deleteResult = await (this.session as any).agentBay.context.deleteFile(contextId, remotePath);\n if (!deleteResult.success) {\n log(`Warning: Failed to delete downloaded file from OSS: ${deleteResult}`);\n }\n } catch (deleteError: any) {\n log(`Warning: Error deleting downloaded file from OSS: ${deleteError}`);\n }\n }\n }\n \n return result;\n } catch (error) {\n return {\n success: false,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download failed: ${error}`,\n };\n }\n }\n}\n","import { AgentBay } from \"../agent-bay\";\nimport { Session } from \"../session\";\nimport { ContextService } from \"../context\";\nimport { FileUrlResult, OperationResult } from \"../types/api-response\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport fetch from \"node-fetch\";\nimport { log } from \"../utils/logger\";\n\n/**\n * Result structure for file upload operations.\n */\nexport interface UploadResult {\n /** Whether the upload was successful */\n success: boolean;\n /** Request ID for getting the upload URL */\n requestIdUploadUrl?: string;\n /** Request ID for sync operation */\n requestIdSync?: string;\n /** HTTP status code */\n httpStatus?: number;\n /** ETag of the uploaded file */\n etag?: string;\n /** Number of bytes sent */\n bytesSent: number;\n /** Remote file path */\n path: string;\n /** Error message if upload failed */\n error?: string;\n}\n\n/**\n * Result structure for file download operations.\n */\nexport interface DownloadResult {\n /** Whether the download was successful */\n success: boolean;\n /** Request ID for getting the download URL */\n requestIdDownloadUrl?: string;\n /** Request ID for sync operation */\n requestIdSync?: string;\n /** HTTP status code */\n httpStatus?: number;\n /** Number of bytes received */\n bytesReceived: number;\n /** Remote file path */\n path: string;\n /** Local file path where file was saved */\n localPath: string;\n /** Error message if download failed */\n error?: string;\n}\n\n/**\n * FileTransfer provides pre-signed URL upload/download functionality between local and OSS,\n * with integration to Session Context synchronization.\n * \n * Prerequisites and Constraints:\n * - Session must be associated with the corresponding context_id and path through \n * CreateSessionParams.contextSyncs, and remotePath should fall within that \n * synchronization path (or conform to backend path rules).\n * - Requires available AgentBay context service (agentBay.context) and session context.\n */\nexport class FileTransfer {\n private agentBay: AgentBay;\n private contextSvc: ContextService;\n private session: Session;\n private httpTimeout: number;\n private followRedirects: boolean;\n private contextId: string;\n\n // Task completion states (for compatibility)\n private finishedStates = new Set([\"success\", \"successful\", \"ok\", \"finished\", \"done\", \"completed\", \"complete\"]);\n\n /**\n * Initialize FileTransfer with AgentBay client and session.\n * \n * @param agentBay - AgentBay instance for context service access\n * @param session - Created session object for context operations\n * @param httpTimeout - HTTP request timeout in seconds (default: 60.0)\n * @param followRedirects - Whether to follow HTTP redirects (default: true)\n */\n constructor(\n agentBay: AgentBay,\n session: Session,\n httpTimeout = 60.0,\n followRedirects = true\n ) {\n this.agentBay = agentBay;\n this.contextSvc = agentBay.context;\n this.session = session;\n this.httpTimeout = httpTimeout;\n this.followRedirects = followRedirects;\n this.contextId = session.fileTransferContextId || \"\";\n }\n\n /**\n * Upload workflow:\n * 1) Get OSS pre-signed URL via context.getFileUploadUrl\n * 2) Upload local file to OSS using the URL (HTTP PUT)\n * 3) Trigger session.context.sync(mode=\"download\") to sync OSS objects to cloud disk\n * 4) If wait=true, poll session.context.info until upload task reaches completion or timeout\n *\n * Returns UploadResult containing request_ids, HTTP status, ETag and other information.\n */\n async upload(\n localPath: string,\n remotePath: string,\n options?: {\n contentType?: string;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesTransferred: number) => void;\n }\n ): Promise<UploadResult> {\n const {\n contentType = null,\n wait = true,\n waitTimeout = 30.0,\n pollInterval = 1.5,\n progressCb = undefined\n } = options || {};\n\n try {\n // 0. Parameter validation\n if (!fs.existsSync(localPath)) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: `Local file not found: ${localPath}`\n };\n }\n\n if (!this.contextId) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: \"No context ID\"\n };\n }\n\n // 1. Get pre-signed upload URL\n const urlRes = await this.contextSvc.getFileUploadUrl(this.contextId, remotePath);\n if (!urlRes.success || !urlRes.url) {\n return {\n success: false,\n requestIdUploadUrl: urlRes.requestId,\n bytesSent: 0,\n path: remotePath,\n error: `getFileUploadUrl failed: ${urlRes.url || \"unknown error\"}`\n };\n }\n\n const uploadUrl = urlRes.url;\n const reqIdUpload = urlRes.requestId;\n\n log(`Uploading ${localPath} to ${uploadUrl}`);\n\n // 2. PUT upload to pre-signed URL\n try {\n const { httpStatus, etag, bytesSent } = await this.putFile(\n uploadUrl,\n localPath,\n contentType,\n progressCb\n );\n \n log(`Upload completed with HTTP ${httpStatus}`);\n if (httpStatus && ![200, 201, 204].includes(httpStatus)) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n httpStatus,\n etag,\n bytesSent,\n path: remotePath,\n error: `Upload failed with HTTP ${httpStatus}`\n };\n }\n } catch (e: any) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n bytesSent: 0,\n path: remotePath,\n error: `Upload exception: ${e.message || e}`\n };\n }\n\n // 3. Trigger sync to cloud disk (download mode), download from oss to cloud disk\n let reqIdSync: string | undefined;\n try {\n log(\"Triggering sync to cloud disk\");\n reqIdSync = await this.awaitSync(\"download\", remotePath, this.contextId);\n } catch (e: any) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n requestIdSync: reqIdSync,\n httpStatus: 200, // Assuming previous step succeeded\n etag: \"\", // Assuming previous step succeeded\n bytesSent: fs.statSync(localPath).size, // Assuming previous step succeeded\n path: remotePath,\n error: `session.context.sync(upload) failed: ${e.message || e}`\n };\n }\n\n log(`Sync request ID: ${reqIdSync}`);\n \n // 4. Optionally wait for task completion\n if (wait) {\n const { success, error } = await this.waitForTask({\n contextId: this.contextId,\n remotePath,\n taskType: \"download\",\n timeout: waitTimeout,\n interval: pollInterval\n });\n \n if (!success) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n requestIdSync: reqIdSync,\n httpStatus: 200, // Assuming previous step succeeded\n etag: \"\", // Assuming previous step succeeded\n bytesSent: fs.statSync(localPath).size, // Assuming previous step succeeded\n path: remotePath,\n error: `Upload sync not finished: ${error || \"timeout or unknown\"}`\n };\n }\n }\n\n return {\n success: true,\n requestIdUploadUrl: reqIdUpload,\n requestIdSync: reqIdSync,\n httpStatus: 200,\n etag: \"\",\n bytesSent: fs.statSync(localPath).size,\n path: remotePath\n };\n } catch (e: any) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: `Upload failed: ${e.message || e}`\n };\n }\n }\n\n /**\n * Download workflow:\n * 1) Trigger session.context.sync(mode=\"upload\") to sync cloud disk data to OSS\n * 2) Get pre-signed download URL via context.getFileDownloadUrl\n * 3) Download the file and save to local localPath\n * 4) If wait=true, wait for download task to reach completion after step 1 \n * (ensuring backend has prepared the download object)\n *\n * Returns DownloadResult containing sync and download request_ids, HTTP status, byte count, etc.\n */\n async download(\n remotePath: string,\n localPath: string,\n options?: {\n overwrite?: boolean;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesReceived: number) => void;\n }\n ): Promise<DownloadResult> {\n const {\n overwrite = true,\n wait = true,\n waitTimeout = 30.0,\n pollInterval = 1.5,\n progressCb = undefined\n } = options || {};\n\n try {\n // Use default context if none provided\n if (!this.contextId) {\n return {\n success: false,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: \"No context ID\"\n };\n }\n\n // 1. Trigger cloud disk to OSS download sync\n let reqIdSync: string | undefined;\n try {\n reqIdSync = await this.awaitSync(\"upload\", remotePath, this.contextId);\n } catch (e: any) {\n return {\n success: false,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `session.context.sync(download) failed: ${e.message || e}`\n };\n }\n\n // Optionally wait for task completion (ensure object is ready in OSS)\n if (wait) {\n const { success, error } = await this.waitForTask({\n contextId: this.contextId,\n remotePath,\n taskType: \"upload\",\n timeout: waitTimeout,\n interval: pollInterval\n });\n \n if (!success) {\n return {\n success: false,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download sync not finished: ${error || \"timeout or unknown\"}`\n };\n }\n }\n\n // 2. Get pre-signed download URL\n const urlRes = await this.contextSvc.getFileDownloadUrl(this.contextId, remotePath);\n if (!urlRes.success || !urlRes.url) {\n return {\n success: false,\n requestIdDownloadUrl: urlRes.requestId,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `getFileDownloadUrl failed: ${urlRes.url || \"unknown error\"}`\n };\n }\n\n const downloadUrl = urlRes.url;\n const reqIdDownload = urlRes.requestId;\n\n // 3. Download and save to local\n try {\n // Ensure directory exists\n const dir = path.dirname(localPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n if (fs.existsSync(localPath) && !overwrite) {\n return {\n success: false,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Destination exists and overwrite=false: ${localPath}`\n };\n }\n\n const bytesReceived = await this.getFile(\n downloadUrl,\n localPath,\n progressCb\n );\n\n if (fs.existsSync(localPath)) {\n return {\n success: true,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n httpStatus: 200,\n bytesReceived: fs.statSync(localPath).size,\n path: remotePath,\n localPath\n };\n } else {\n return {\n success: false,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n bytesReceived,\n path: remotePath,\n localPath,\n error: \"Download completed but file not found\"\n };\n }\n } catch (e: any) {\n return {\n success: false,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download exception: ${e.message || e}`\n };\n }\n } catch (e: any) {\n return {\n success: false,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download failed: ${e.message || e}`\n };\n }\n }\n\n // ========== Internal Utilities ==========\n\n /**\n * Compatibility wrapper for session.context.sync which may be sync or async:\n * - Try async call first\n * - Fall back to sync call\n * Returns request_id if available\n */\n private async awaitSync(mode: string, remotePath = \"\", contextId = \"\"): Promise<string | undefined> {\n mode = mode.toLowerCase().trim();\n\n // Check if session has context property\n if (!this.session.context) {\n throw new Error(\"Session does not have context property\");\n }\n\n const syncFn = this.session.context.sync.bind(this.session.context);\n log(`session.context.sync(mode=${mode}, path=${remotePath}, contextId=${contextId})`);\n \n // Try calling with all parameters\n try {\n const result = await syncFn(contextId || undefined, remotePath || undefined, mode);\n log(` Result: ${result.success}`);\n return result.requestId;\n } catch (e1) {\n // Backend may not support all parameters, try with mode and path only\n try {\n const result = await syncFn(undefined, remotePath || undefined, mode);\n log(` Result: ${result.success}`);\n return result.requestId;\n } catch (e2) {\n // Backend may not support mode or path parameter\n try {\n const result = await syncFn(undefined, undefined, mode);\n log(` Result: ${result.success}`);\n return result.requestId;\n } catch (e3) {\n // Backend may not support mode parameter\n const result = await syncFn();\n log(` Result: ${result.success}`);\n return result.requestId;\n }\n }\n }\n }\n\n /**\n * Poll session.context.info within timeout to check if specified task is completed.\n * Returns { success, error } object.\n */\n private async waitForTask(options: {\n contextId: string;\n remotePath: string;\n taskType?: string;\n timeout: number;\n interval: number;\n }): Promise<{ success: boolean; error?: string }> {\n const { contextId, remotePath, taskType, timeout, interval } = options;\n const deadline = Date.now() + timeout * 1000;\n let lastErr: string | null = null;\n\n while (Date.now() < deadline) {\n try {\n // Check if session has context property\n if (!this.session.context) {\n throw new Error(\"Session does not have context property\");\n }\n\n const infoFn = this.session.context.infoWithParams.bind(this.session.context);\n // Try calling with filter parameters\n let res;\n try {\n res = await infoFn(contextId, remotePath, taskType);\n } catch (e1) {\n try {\n res = await infoFn();\n } catch (e2) {\n // If all attempts fail, re-throw the last error\n throw e2;\n }\n }\n\n // Parse response\n const statusList = res.contextStatusData || [];\n for (const item of statusList) {\n const cid = item.contextId;\n const path = item.path;\n const ttype = item.taskType;\n const status = item.status;\n const err = item.errorMessage;\n\n if (cid === contextId && path === remotePath && (taskType === undefined || ttype === taskType)) {\n if (err) {\n return { success: false, error: `Task error: ${err}` };\n }\n if (status && this.finishedStates.has(status.toLowerCase())) {\n return { success: true };\n }\n // Otherwise continue waiting\n }\n }\n lastErr = \"task not finished\";\n } catch (e: any) {\n lastErr = `info error: ${e.message || e}`;\n }\n\n // Wait before next poll\n await new Promise(resolve => setTimeout(resolve, interval * 1000));\n }\n\n return { success: false, error: lastErr || \"timeout\" };\n }\n\n /**\n * Synchronously PUT file using node-fetch.\n * Returns { status, etag, bytesSent }\n */\n private async putFile(\n url: string,\n filePath: string,\n contentType: string | null,\n progressCb?: (bytesTransferred: number) => void\n ): Promise<{ httpStatus: number; etag?: string; bytesSent: number }> {\n const headers: Record<string, string> = {};\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n\n const fileBuffer = fs.readFileSync(filePath);\n const response = await fetch(url, {\n method: \"PUT\",\n body: fileBuffer,\n headers\n });\n\n const status = response.status;\n const etag = response.headers.get(\"ETag\") || undefined;\n const bytesSent = fileBuffer.length;\n\n if (progressCb) {\n progressCb(bytesSent);\n }\n\n return { httpStatus: status, etag, bytesSent };\n }\n\n /**\n * Synchronously GET download to local file using node-fetch.\n * Returns bytesReceived\n */\n private async getFile(\n url: string,\n destPath: string,\n progressCb?: (bytesReceived: number) => void\n ): Promise<number> {\n let bytesReceived = 0;\n \n const response = await fetch(url);\n const status = response.status;\n \n if (status !== 200) {\n throw new Error(`HTTP ${status}`);\n }\n\n const buffer = await response.buffer();\n bytesReceived = buffer.length;\n \n // Save to file\n fs.writeFileSync(destPath, buffer);\n \n if (progressCb) {\n progressCb(bytesReceived);\n }\n\n return bytesReceived;\n }\n}","export { \n Mobile, \n BoolResult, \n UIElement, \n UIElementsResult, \n InstalledApp, \n InstalledAppsResult, \n Process, \n ProcessResult, \n ScreenshotResult \n} from './mobile'; ","/**\n * Mobile module for mobile UI automation.\n * Provides touch, input, and app management operations for mobile environments.\n */\n\nimport { OperationResult } from \"../types/api-response\";\n\nexport interface BoolResult extends OperationResult {\n data?: boolean;\n}\n\nexport interface UIElement {\n text: string;\n className: string;\n bounds: {\n left: number;\n top: number;\n right: number;\n bottom: number;\n };\n}\n\nexport interface UIElementsResult extends OperationResult {\n elements: UIElement[];\n}\n\nexport interface InstalledApp {\n name: string;\n startCmd: string;\n workDirectory: string;\n}\n\nexport interface InstalledAppsResult extends OperationResult {\n apps: InstalledApp[];\n}\n\nexport interface Process {\n pid: number;\n pname: string;\n}\n\nexport interface ProcessResult extends OperationResult {\n processes: Process[];\n}\n\nexport interface ScreenshotResult extends OperationResult {\n data: string; // Screenshot URL\n}\n\n// Session interface for Mobile module\ninterface MobileSession {\n callMcpTool(toolName: string, args: Record<string, any>): Promise<any>;\n sessionId: string;\n getAPIKey(): string;\n}\n\nexport class Mobile {\n private session: MobileSession;\n\n constructor(session: MobileSession) {\n this.session = session;\n }\n\n /**\n * Tap at specified coordinates.\n */\n async tap(x: number, y: number): Promise<BoolResult> {\n const args = { x, y };\n try {\n const result = await this.session.callMcpTool('tap', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to tap: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Swipe from one position to another.\n */\n async swipe(startX: number, startY: number, endX: number, endY: number, durationMs = 300): Promise<BoolResult> {\n const args = { start_x: startX, start_y: startY, end_x: endX, end_y: endY, duration_ms: durationMs };\n try {\n const result = await this.session.callMcpTool('swipe', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to swipe: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Input text.\n */\n async inputText(text: string): Promise<BoolResult> {\n const args = { text };\n try {\n const result = await this.session.callMcpTool('input_text', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to input text: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Send Android key code.\n */\n async sendKey(key: number): Promise<BoolResult> {\n const args = { key };\n try {\n const result = await this.session.callMcpTool('send_key', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to send key: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Get clickable UI elements.\n */\n async getClickableUIElements(timeoutMs = 5000): Promise<UIElementsResult> {\n const args = { timeout_ms: timeoutMs };\n try {\n const result = await this.session.callMcpTool('get_clickable_ui_elements', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get clickable UI elements',\n elements: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: []\n };\n }\n\n try {\n const elements = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: elements || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse UI elements: ${parseError}`,\n elements: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get clickable UI elements: ${error instanceof Error ? error.message : String(error)}`,\n elements: []\n };\n }\n }\n\n /**\n * Get all UI elements.\n */\n async getAllUIElements(timeoutMs = 3000): Promise<UIElementsResult> {\n const args = { timeout_ms: timeoutMs };\n try {\n const result = await this.session.callMcpTool('get_all_ui_elements', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get all UI elements',\n elements: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: []\n };\n }\n\n try {\n const elements = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: elements || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse UI elements: ${parseError}`,\n elements: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get all UI elements: ${error instanceof Error ? error.message : String(error)}`,\n elements: []\n };\n }\n }\n\n /**\n * Get installed apps.\n */\n async getInstalledApps(startMenu = false, desktop = true, ignoreSystemApps = true): Promise<InstalledAppsResult> {\n const args = { start_menu: startMenu, desktop, ignore_system_apps: ignoreSystemApps };\n try {\n const result = await this.session.callMcpTool('get_installed_apps', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get installed apps',\n apps: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n apps: []\n };\n }\n\n try {\n const apps = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n apps: apps || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse installed apps: ${parseError}`,\n apps: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get installed apps: ${error instanceof Error ? error.message : String(error)}`,\n apps: []\n };\n }\n }\n\n /**\n * Start an app.\n */\n async startApp(startCmd: string, workDirectory = '', activity = ''): Promise<ProcessResult> {\n const args = { start_cmd: startCmd, work_directory: workDirectory, activity };\n try {\n const result = await this.session.callMcpTool('start_app', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to start app',\n processes: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n processes: []\n };\n }\n\n try {\n const processes = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n processes: processes || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse process result: ${parseError}`,\n processes: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to start app: ${error instanceof Error ? error.message : String(error)}`,\n processes: []\n };\n }\n }\n\n /**\n * Stop app by package name.\n */\n async stopAppByPName(pname: string): Promise<BoolResult> {\n const args = { pname };\n try {\n const result = await this.session.callMcpTool('stop_app_by_pname', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to stop app: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Take a screenshot.\n */\n async screenshot(): Promise<ScreenshotResult> {\n try {\n const result = await this.session.callMcpTool('system_screenshot', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to take screenshot',\n data: ''\n };\n }\n\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n data: result.data || ''\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to take screenshot: ${error instanceof Error ? error.message : String(error)}`,\n data: ''\n };\n }\n }\n} ","export { Oss } from \"./oss\";\n","import { Session } from \"../session\";\nimport {\n OSSClientResult,\n OSSUploadResult,\n OSSDownloadResult,\n} from \"../types/api-response\";\n\n\n/**\n * Handles OSS operations in the AgentBay cloud environment.\n */\nexport class Oss {\n private session: Session;\n\n /**\n * Initialize an Oss object.\n *\n * @param session - The Session instance that this Oss belongs to.\n */\n constructor(session: Session) {\n this.session = session;\n }\n\n /**\n * Sanitizes error messages to remove sensitive information like API keys.\n *\n * @param error - The error to sanitize\n * @returns The sanitized error\n */\n private sanitizeError(error: any): any {\n if (!error) {\n return error;\n }\n\n const errorString = String(error);\n return errorString.replace(/Bearer\\s+[^\\s]+/g, \"Bearer [REDACTED]\");\n }\n\n /**\n * Initialize OSS environment variables with the specified credentials.\n * Corresponds to Python's env_init() method\n *\n * @param accessKeyId - The access key ID\n * @param accessKeySecret - The access key secret\n * @param securityToken - The security token (optional)\n * @param endpoint - The OSS endpoint (optional)\n * @param region - The OSS region (optional)\n * @returns OSSClientResult with client configuration and requestId\n * @throws APIError if the operation fails.\n */\n async envInit(\n accessKeyId: string,\n accessKeySecret: string,\n securityToken?: string,\n endpoint?: string,\n region?: string\n ): Promise<OSSClientResult> {\n try {\n const args = {\n access_key_id: accessKeyId,\n access_key_secret: accessKeySecret,\n security_token: securityToken || \"\",\n endpoint: endpoint || \"\",\n region: region || \"\",\n };\n const result = await this.session.callMcpTool(\"oss_env_init\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n clientConfig: {},\n errorMessage: result.errorMessage,\n };\n }\n\n let clientConfig: Record<string, any> = {};\n try {\n clientConfig = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n clientConfig: {},\n errorMessage: `Failed to parse client config: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n clientConfig,\n errorMessage: \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n clientConfig: {},\n errorMessage: `Failed to initialize OSS environment: ${error}`,\n };\n }\n }\n\n /**\n * Upload a file to OSS.\n * Corresponds to Python's upload() method\n *\n * @param bucket - The OSS bucket name\n * @param object - The OSS object key\n * @param path - The local file path to upload\n * @returns OSSUploadResult with upload result and requestId\n * @throws APIError if the operation fails.\n */\n async upload(\n bucket: string,\n object: string,\n path: string\n ): Promise<OSSUploadResult> {\n try {\n const args = {\n bucket,\n object,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_upload\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to upload file: ${error}`,\n };\n }\n }\n\n /**\n * Upload a file to OSS using an anonymous URL.\n * Corresponds to Python's upload_anonymous() method\n *\n * @param url - The anonymous upload URL\n * @param path - The local file path to upload\n * @returns OSSUploadResult with upload result and requestId\n * @throws APIError if the operation fails.\n */\n async uploadAnonymous(url: string, path: string): Promise<OSSUploadResult> {\n try {\n const args = {\n url,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_upload_annon\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to upload file anonymously: ${error}`,\n };\n }\n }\n\n /**\n * Download a file from OSS.\n * Corresponds to Python's download() method\n *\n * @param bucket - The OSS bucket name\n * @param object - The OSS object key\n * @param path - The local file path to save the downloaded file\n * @returns OSSDownloadResult with download result and requestId\n * @throws APIError if the operation fails.\n */\n async download(\n bucket: string,\n object: string,\n path: string\n ): Promise<OSSDownloadResult> {\n try {\n const args = {\n bucket,\n object,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_download\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to download file: ${error}`,\n };\n }\n }\n\n /**\n * Download a file from OSS using an anonymous URL.\n * Corresponds to Python's download_anonymous() method\n *\n * @param url - The anonymous download URL\n * @param path - The local file path to save the downloaded file\n * @returns OSSDownloadResult with download result and requestId\n * @throws APIError if the operation fails.\n */\n async downloadAnonymous(\n url: string,\n path: string\n ): Promise<OSSDownloadResult> {\n try {\n const args = {\n url,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_download_annon\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to download file anonymously: ${error}`,\n };\n }\n }\n}\n","import { Session } from \"../session\";\nimport {\n UIElementListResult,\n BoolResult,\n OperationResult,\n} from \"../types/api-response\";\n\n/**\n * Key codes for UI operations\n */\nexport enum KeyCode {\n HOME = 3,\n BACK = 4,\n VOLUME_UP = 24,\n VOLUME_DOWN = 25,\n POWER = 26,\n MENU = 82\n}\n\n/**\n * Interface representing a UI element in the UI hierarchy\n */\nexport interface UIElement {\n bounds: string;\n className: string;\n text: string;\n type: string;\n resourceId: string;\n index: number;\n isParent: boolean;\n children?: UIElement[];\n}\n\n\n\n/**\n * Handles UI operations in the AgentBay cloud environment.\n * \n * @deprecated This module is deprecated. Use Computer or Mobile modules instead.\n * - For desktop UI operations, use session.computer\n * - For mobile UI operations, use session.mobile\n */\nexport class UI {\n private session: Session;\n\n /**\n * Initialize a UI object.\n *\n * @param session - The Session instance that this UI belongs to.\n */\n constructor(session: {\n getAPIKey(): string;\n getClient(): any;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n }) {\n this.session = session as Session;\n }\n\n /**\n * Sanitizes error messages to remove sensitive information like API keys.\n *\n * @param error - The error to sanitize\n * @returns The sanitized error\n */\n private sanitizeError(error: any): any {\n if (!error) {\n return error;\n }\n\n const errorString = String(error);\n return errorString.replace(/Bearer\\s+[^\\s]+/g, \"Bearer [REDACTED]\");\n }\n\n /**\n * Retrieves all clickable UI elements within the specified timeout.\n * Corresponds to Python's get_clickable_ui_elements() method\n *\n * @param timeoutMs - The timeout in milliseconds. Default is 2000ms.\n * @returns UIElementListResult with clickable elements and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.getClickableUIElements() for desktop or session.mobile.getClickableUIElements() for mobile instead.\n */\n async getClickableUIElements(timeoutMs = 2000): Promise<UIElementListResult> {\n console.warn('⚠️ UI.getClickableUIElements() is deprecated. Use session.computer.getClickableUIElements() for desktop or session.mobile.getClickableUIElements() for mobile instead.');\n \n try {\n const args = { timeout_ms: timeoutMs };\n const result = await this.session.callMcpTool(\"get_clickable_ui_elements\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let elements: UIElement[] = [];\n try {\n elements = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: `Failed to parse UI elements: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n elements: elements,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n elements: [],\n errorMessage: `Failed to get clickable UI elements: ${error}`,\n };\n }\n }\n\n /**\n * Retrieves all UI elements regardless of their clickable status.\n * Corresponds to Python's get_all_ui_elements() method\n *\n * @param timeoutMs - The timeout in milliseconds. Default is 2000ms.\n * @returns UIElementListResult with all elements and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.getAllUIElements() for desktop or session.mobile.getAllUIElements() for mobile instead.\n */\n async getAllUIElements(timeoutMs = 2000): Promise<UIElementListResult> {\n console.warn('⚠️ UI.getAllUIElements() is deprecated. Use session.computer.getAllUIElements() for desktop or session.mobile.getAllUIElements() for mobile instead.');\n \n try {\n const args = { timeout_ms: timeoutMs };\n const result = await this.session.callMcpTool(\"get_all_ui_elements\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let elements: UIElement[] = [];\n try {\n elements = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: `Failed to parse UI elements: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n elements: elements,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n elements: [],\n errorMessage: `Failed to get all UI elements: ${error}`,\n };\n }\n }\n\n /**\n * Sends a key press event.\n * Corresponds to Python's send_key() method\n *\n * @param key - The key code to send. Supported key codes are:\n * - 3 : HOME\n * - 4 : BACK\n * - 24 : VOLUME UP\n * - 25 : VOLUME DOWN\n * - 26 : POWER\n * - 82 : MENU\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.pressKeys() for desktop or session.mobile.sendKey() for mobile instead.\n */\n async sendKey(key: number): Promise<BoolResult> {\n console.warn('⚠️ UI.sendKey() is deprecated. Use session.computer.pressKeys() for desktop or session.mobile.sendKey() for mobile instead.');\n \n try {\n const args = { key };\n const result = await this.session.callMcpTool(\"send_key\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to send key: ${error}`,\n };\n }\n }\n\n /**\n * Inputs text into the currently focused UI element.\n * Corresponds to Python's input_text() method\n *\n * @param text - The text to input\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.inputText() for desktop or session.mobile.inputText() for mobile instead.\n */\n async inputText(text: string): Promise<BoolResult> {\n console.warn('⚠️ UI.inputText() is deprecated. Use session.computer.inputText() for desktop or session.mobile.inputText() for mobile instead.');\n \n try {\n const args = { text };\n const result = await this.session.callMcpTool(\"input_text\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to input text: ${error}`,\n };\n }\n }\n\n /**\n * Performs a swipe gesture on the screen.\n * Corresponds to Python's swipe() method\n *\n * @param startX - The starting X coordinate\n * @param startY - The starting Y coordinate\n * @param endX - The ending X coordinate\n * @param endY - The ending Y coordinate\n * @param durationMs - The duration of the swipe in milliseconds. Default is 300ms.\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.dragMouse() for desktop or session.mobile.swipe() for mobile instead.\n */\n async swipe(\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n durationMs = 300\n ): Promise<BoolResult> {\n console.warn('⚠️ UI.swipe() is deprecated. Use session.computer.dragMouse() for desktop or session.mobile.swipe() for mobile instead.');\n \n try {\n const args = {\n start_x: startX,\n start_y: startY,\n end_x: endX,\n end_y: endY,\n duration_ms: durationMs,\n };\n const result = await this.session.callMcpTool(\"swipe\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to perform swipe: ${error}`,\n };\n }\n }\n\n /**\n * Clicks on the screen at the specified coordinates.\n * Corresponds to Python's click() method\n *\n * @param x - The X coordinate\n * @param y - The Y coordinate\n * @param button - The mouse button to use. Default is 'left'\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.clickMouse() for desktop or session.mobile.tap() for mobile instead.\n */\n async click(x: number, y: number, button = \"left\"): Promise<BoolResult> {\n console.warn('⚠️ UI.click() is deprecated. Use session.computer.clickMouse() for desktop or session.mobile.tap() for mobile instead.');\n \n try {\n const args = { x, y, button };\n const result = await this.session.callMcpTool(\"click\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to click: ${error}`,\n };\n }\n }\n\n /**\n * Takes a screenshot of the current screen.\n * Corresponds to Python's screenshot() method\n *\n * @returns OperationResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.screenshot() for desktop or session.mobile.screenshot() for mobile instead.\n */\n async screenshot(): Promise<OperationResult> {\n console.warn('⚠️ UI.screenshot() is deprecated. Use session.computer.screenshot() for desktop or session.mobile.screenshot() for mobile instead.');\n \n try {\n const result = await this.session.callMcpTool(\"system_screenshot\", {});\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n data: \"\",\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: result.data,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: \"\",\n errorMessage: `Failed to take screenshot: ${error}`,\n };\n }\n }\n}\n","export { Agent, ExecutionResult, QueryResult, McpToolResult, McpSession } from \"./agent\"; ","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\nimport fetch from \"node-fetch\";\nimport { AgentBay } from \"./agent-bay\";\nimport { ContextService, Context } from \"./context\";\nimport { AgentBayError } from \"./exceptions\";\nimport { OperationResult, ContextFileListResult, FileUrlResult } from \"./types/api-response\";\nimport { log, logError } from \"./utils/logger\";\n\n// ==============================================================================\n// Constants\n// ==============================================================================\nconst EXTENSIONS_BASE_PATH = \"/tmp/extensions\";\n\n// ==============================================================================\n// 1. Data Models\n// ==============================================================================\n\n/**\n * Represents a browser extension as a cloud resource.\n */\nexport class Extension {\n /**\n * The unique identifier of the extension.\n */\n id: string;\n\n /**\n * The name of the extension.\n */\n name: string;\n\n /**\n * Date and time when the extension was created.\n */\n createdAt?: string;\n\n /**\n * Initialize an Extension object.\n *\n * @param id - The unique identifier of the extension.\n * @param name - The name of the extension.\n * @param createdAt - Date and time when the extension was created.\n */\n constructor(id: string, name: string, createdAt?: string) {\n this.id = id;\n this.name = name;\n this.createdAt = createdAt;\n }\n}\n\n/**\n * Configuration options for browser extension integration.\n * \n * This class encapsulates the necessary parameters for setting up\n * browser extension synchronization and context management.\n */\nexport class ExtensionOption {\n /**\n * ID of the extension context for browser extensions.\n */\n contextId: string;\n\n /**\n * List of extension IDs to be loaded/synchronized.\n */\n extensionIds: string[];\n\n /**\n * Initialize ExtensionOption with context and extension configuration.\n * \n * @param contextId - ID of the extension context for browser extensions.\n * This should match the context where extensions are stored.\n * @param extensionIds - List of extension IDs to be loaded in the browser session.\n * Each ID should correspond to a valid extension in the context.\n * \n * @throws {Error} If contextId is empty or extensionIds is empty.\n */\n constructor(contextId: string, extensionIds: string[]) {\n if (!contextId || !contextId.trim()) {\n throw new Error(\"contextId cannot be empty\");\n }\n\n if (!extensionIds || extensionIds.length === 0) {\n throw new Error(\"extensionIds cannot be empty\");\n }\n\n this.contextId = contextId;\n this.extensionIds = extensionIds;\n }\n\n /**\n * String representation of ExtensionOption.\n */\n toString(): string {\n return `ExtensionOption(contextId='${this.contextId}', extensionIds=${JSON.stringify(this.extensionIds)})`;\n }\n\n /**\n * Human-readable string representation.\n */\n toDisplayString(): string {\n return `Extension Config: ${this.extensionIds.length} extension(s) in context '${this.contextId}'`;\n }\n\n /**\n * Validate the extension option configuration.\n * \n * @returns True if configuration is valid, false otherwise.\n */\n validate(): boolean {\n try {\n // Check contextId\n if (!this.contextId || !this.contextId.trim()) {\n return false;\n }\n\n // Check extensionIds\n if (!this.extensionIds || this.extensionIds.length === 0) {\n return false;\n }\n\n // Check that all extension IDs are non-empty strings\n for (const extId of this.extensionIds) {\n if (typeof extId !== 'string' || !extId.trim()) {\n return false;\n }\n }\n\n return true;\n } catch (error) {\n return false;\n }\n }\n}\n\n// ==============================================================================\n// 2. Core Service Class (Scoped Stateless Model)\n// ==============================================================================\n\n/**\n * Provides methods to manage user browser extensions.\n * This service integrates with the existing context functionality for file operations.\n * \n * **Usage** (Simplified - Auto-detection):\n * ```typescript\n * // Service automatically detects if context exists and creates if needed\n * const extensionsService = new ExtensionsService(agentBay, \"browser_extensions\");\n * \n * // Or use with empty contextId to auto-generate context name\n * const extensionsService = new ExtensionsService(agentBay); // Uses default generated name\n * \n * // Use the service immediately - initialization happens automatically\n * const extension = await extensionsService.create(\"/path/to/plugin.zip\");\n * ```\n * \n * **Integration with ExtensionOption (Simplified)**:\n * ```typescript\n * // Create extensions and configure for browser sessions\n * const extensionsService = new ExtensionsService(agentBay, \"my_extensions\");\n * const ext1 = await extensionsService.create(\"/path/to/ext1.zip\");\n * const ext2 = await extensionsService.create(\"/path/to/ext2.zip\");\n * \n * // Create extension option for browser integration (no contextId needed!)\n * const extOption = extensionsService.createExtensionOption([ext1.id, ext2.id]);\n * \n * // Use with BrowserContext for session creation\n * const browserContext = new BrowserContext({\n * contextId: \"browser_session\",\n * autoUpload: true,\n * extensionOption: extOption // All extension config encapsulated\n * });\n * ```\n * \n * **Context Management**:\n * - If contextId provided and exists: Uses the existing context\n * - If contextId provided but doesn't exist: Creates context with provided name\n * - If contextId empty or not provided: Generates default name and creates context\n * - No need to manually manage context creation or call initialize()\n * - Context initialization happens automatically on first method call\n */\nexport class ExtensionsService {\n private agentBay: AgentBay;\n private contextService: ContextService;\n private extensionContext!: Context;\n private contextId!: string;\n private contextName: string;\n private autoCreated: boolean;\n private _initializationPromise: Promise<void> | null = null;\n\n /**\n * Initializes the ExtensionsService with a context.\n *\n * @param agentBay - The AgentBay client instance.\n * @param contextId - The context ID or name. If empty or not provided,\n * a default context name will be generated automatically.\n * If the context doesn't exist, it will be automatically created.\n * \n * Note:\n * The service automatically detects if the context exists. If not,\n * it creates a new context with the provided name or a generated default name.\n * Context initialization is handled lazily on first use.\n */\n constructor(agentBay: AgentBay, contextId: string = \"\") {\n if (!agentBay) {\n throw new AgentBayError(\"AgentBay instance is required\");\n }\n if (!agentBay.context) {\n throw new AgentBayError(\"AgentBay instance must have a context service\");\n }\n \n this.agentBay = agentBay;\n this.contextService = agentBay.context;\n this.autoCreated = true;\n\n // Generate default context name if contextId is empty\n if (!contextId || contextId.trim() === \"\") {\n contextId = `extensions-${Math.floor(Date.now() / 1000)}`;\n log(`Generated default context name: ${contextId}`);\n }\n\n this.contextName = contextId;\n \n // Initialize context lazily - will be set on first method call\n this._initializationPromise = this._initializeContext();\n }\n\n /**\n * Internal method to initialize the context.\n * This ensures the context is ready before any operations.\n */\n private async _initializeContext(): Promise<void> {\n try {\n // Context doesn't exist, create it\n const contextResult = await this.contextService.get(this.contextName, true);\n if (!contextResult.success || !contextResult.context) {\n throw new AgentBayError(`Failed to create extension repository context: ${this.contextName}`);\n }\n\n this.extensionContext = contextResult.context;\n this.contextId = this.extensionContext.id;\n } catch (error) {\n throw new AgentBayError(`Failed to initialize ExtensionsService: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Ensures the service is initialized before performing operations.\n */\n private async _ensureInitialized(): Promise<void> {\n if (this._initializationPromise) {\n await this._initializationPromise;\n this._initializationPromise = null;\n }\n }\n\n /**\n * An internal helper method that encapsulates the flow of \"get upload URL for a specific path and upload\".\n * Uses the existing context service for file operations.\n *\n * @param localPath - The path to the local file.\n * @param remotePath - The path of the file in context storage.\n * \n * @throws {AgentBayError} If getting the credential or uploading fails.\n */\n private async _uploadToCloud(localPath: string, remotePath: string): Promise<void> {\n try {\n // 1. Get upload URL using context service\n const urlResult = await this.contextService.getFileUploadUrl(this.contextId, remotePath);\n if (!urlResult.success || !urlResult.url) {\n throw new AgentBayError(`Failed to get upload URL: ${urlResult.url || 'No URL returned'}`);\n }\n\n const preSignedUrl = urlResult.url;\n\n // 2. Use the presigned URL to upload the file directly\n const fileBuffer = fs.readFileSync(localPath);\n \n const response = await fetch(preSignedUrl, {\n method: 'PUT',\n body: fileBuffer,\n });\n\n if (!response.ok) {\n throw new AgentBayError(`HTTP error uploading file: ${response.status} ${response.statusText}`);\n }\n } catch (error) {\n if (error instanceof AgentBayError) {\n throw error;\n }\n throw new AgentBayError(`An error occurred while uploading the file: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Lists all available browser extensions within this context from the cloud.\n * Uses the context service to list files under the extensions directory.\n * \n * @returns Promise that resolves to an array of Extension objects.\n * @throws {AgentBayError} If listing extensions fails.\n */\n async list(): Promise<Extension[]> {\n await this._ensureInitialized();\n \n try {\n // Use context service to list files in the extensions directory\n const fileListResult = await this.contextService.listFiles(\n this.contextId,\n EXTENSIONS_BASE_PATH,\n 1, // pageNumber\n 100 // pageSize - reasonable limit for extensions\n );\n\n if (!fileListResult.success) {\n throw new AgentBayError(\"Failed to list extensions: Context file listing failed.\");\n }\n\n const extensions: Extension[] = [];\n for (const fileEntry of fileListResult.entries) {\n // Extract the extension ID from the file name\n const extensionId = fileEntry.fileName || fileEntry.filePath;\n extensions.push(new Extension(\n extensionId,\n fileEntry.fileName || extensionId,\n fileEntry.gmtCreate\n ));\n }\n return extensions;\n } catch (error) {\n if (error instanceof AgentBayError) {\n throw error;\n }\n throw new AgentBayError(`An error occurred while listing browser extensions: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Uploads a new browser extension from a local path into the current context.\n * \n * @param localPath - Path to the local extension file (must be a .zip file).\n * @returns Promise that resolves to an Extension object.\n * @throws {Error} If the local file doesn't exist.\n * @throws {Error} If the file format is not supported (only .zip is supported).\n * @throws {AgentBayError} If upload fails.\n */\n async create(localPath: string): Promise<Extension> {\n await this._ensureInitialized();\n \n if (!fs.existsSync(localPath)) {\n throw new Error(`The specified local file was not found: ${localPath}`);\n }\n\n // Determine the ID and cloud path before uploading\n // Validate file type - only ZIP format is supported\n const fileExtension = path.extname(localPath).toLowerCase();\n if (fileExtension !== '.zip') {\n throw new Error(`Unsupported plugin format '${fileExtension}'. Only ZIP format (.zip) is supported.`);\n }\n\n const extensionId = `ext_${crypto.randomBytes(16).toString('hex')}${fileExtension}`;\n const extensionName = path.basename(localPath);\n const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;\n\n // Use the helper method to perform the cloud upload\n await this._uploadToCloud(localPath, remotePath);\n\n // Upload implies creation. Return a locally constructed object with basic info.\n return new Extension(extensionId, extensionName);\n }\n\n /**\n * Updates an existing browser extension in the current context with a new file.\n * \n * @param extensionId - ID of the extension to update.\n * @param newLocalPath - Path to the new local extension file.\n * @returns Promise that resolves to an Extension object.\n * @throws {Error} If the new local file doesn't exist.\n * @throws {Error} If the extension doesn't exist in the context.\n * @throws {AgentBayError} If update fails.\n */\n async update(extensionId: string, newLocalPath: string): Promise<Extension> {\n await this._ensureInitialized();\n \n if (!fs.existsSync(newLocalPath)) {\n throw new Error(`The specified new local file was not found: ${newLocalPath}`);\n }\n\n // Validate that the extension exists by checking the file list\n const existingExtensions = await this.list();\n const extensionExists = existingExtensions.some(ext => ext.id === extensionId);\n \n if (!extensionExists) {\n throw new Error(`Browser extension with ID '${extensionId}' not found in the context. Cannot update.`);\n }\n\n const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;\n\n // Use the helper method to perform the cloud upload (overwrite)\n await this._uploadToCloud(newLocalPath, remotePath);\n\n return new Extension(extensionId, path.basename(newLocalPath));\n }\n\n /**\n * Gets detailed information about a specific browser extension.\n * \n * @param extensionId - The ID of the extension to get info for.\n * @returns Promise that resolves to an Extension object if found, undefined otherwise.\n */\n private async _getExtensionInfo(extensionId: string): Promise<Extension | undefined> {\n await this._ensureInitialized();\n \n try {\n const extensions = await this.list();\n return extensions.find(ext => ext.id === extensionId);\n } catch (error) {\n logError(`An error occurred while getting extension info for '${extensionId}':`, error);\n return undefined;\n }\n }\n\n /**\n * Cleans up the auto-created context if it was created by this service.\n * \n * @returns Promise that resolves to true if cleanup was successful or not needed, false if cleanup failed.\n * \n * Note:\n * This method only works if the context was auto-created by this service.\n * For existing contexts, no cleanup is performed.\n */\n async cleanup(): Promise<boolean> {\n await this._ensureInitialized();\n \n if (!this.autoCreated) {\n // Context was not auto-created by this service, no cleanup needed\n return true;\n }\n\n try {\n const deleteResult = await this.contextService.delete(this.extensionContext);\n if (deleteResult) {\n log(`Extension context deleted: ${this.contextName} (ID: ${this.contextId})`);\n return true;\n } else {\n logError(`Warning: Failed to delete extension context: ${this.contextName}`, new Error('Delete operation returned false'));\n return false;\n }\n } catch (error) {\n logError(`Warning: Failed to delete extension context:`, error);\n return false;\n }\n }\n\n /**\n * Deletes a browser extension from the current context.\n * \n * @param extensionId - ID of the extension to delete.\n * @returns Promise that resolves to true if deletion was successful, false otherwise.\n */\n async delete(extensionId: string): Promise<boolean> {\n await this._ensureInitialized();\n \n const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;\n try {\n // Use context service to delete the file\n const deleteResult = await this.contextService.deleteFile(this.contextId, remotePath);\n\n return deleteResult.success;\n } catch (error) {\n logError(`An error occurred while deleting browser extension '${extensionId}':`, error);\n return false;\n }\n }\n\n /**\n * Create an ExtensionOption for the current context with specified extension IDs.\n * \n * This is a convenience method that creates an ExtensionOption using the current\n * service's contextId and the provided extension IDs. This option can then be\n * used with BrowserContext for browser session creation.\n * \n * @param extensionIds - List of extension IDs to include in the option.\n * These should be extensions that exist in the current context.\n * @returns ExtensionOption configuration object for browser extension integration.\n * @throws {Error} If extensionIds is empty or invalid.\n * \n * @example\n * ```typescript\n * // Create extensions\n * const ext1 = await extensionsService.create(\"/path/to/ext1.zip\");\n * const ext2 = await extensionsService.create(\"/path/to/ext2.zip\");\n * \n * // Create extension option for browser integration\n * const extOption = extensionsService.createExtensionOption([ext1.id, ext2.id]);\n * \n * // Use with BrowserContext\n * const browserContext = new BrowserContext({\n * contextId: \"browser_session\",\n * autoUpload: true,\n * extensionContextId: extOption.contextId,\n * extensionIds: extOption.extensionIds\n * });\n * ```\n */\n createExtensionOption(extensionIds: string[]): ExtensionOption {\n // Note: This method is synchronous like in Python, but contextId might not be available yet\n // In practice, this should be called after the service has been used at least once\n if (!this.contextId) {\n throw new Error(\"Service not initialized. Please call an async method first or ensure context is created.\");\n }\n \n return new ExtensionOption(\n this.contextId,\n extensionIds\n );\n }\n}","import { ContextSync, SyncPolicy, newUploadPolicy, newExtractPolicy, newRecyclePolicy, WhiteList, BWList } from \"./context-sync\";\nimport { ExtensionOption } from \"./extension\";\n\n/**\n * Browser context configuration for session with optional extension support.\n *\n * This class provides browser context configuration for cloud sessions and supports\n * automatic extension synchronization when ExtensionOption is provided.\n *\n * Key Features:\n * - Browser context binding for sessions\n * - Automatic browser data upload on session end\n * - Optional extension integration with automatic context sync generation\n * - Clean API with ExtensionOption encapsulation\n *\n * Extension Configuration:\n * - **ExtensionOption**: Pass an ExtensionOption object with contextId and extensionIds\n * - **No Extensions**: Don't provide extensionOption parameter (extensionContextSyncs will be undefined)\n *\n * Usage Examples:\n * ```typescript\n * // With extensions using ExtensionOption\n * import { ExtensionOption } from \"./extension\";\n *\n * const extOption = new ExtensionOption(\n * \"my_extensions\",\n * [\"ext1\", \"ext2\"]\n * );\n *\n * const browserContext = new BrowserContext(\n * \"browser_session\",\n * true,\n * extOption\n * );\n *\n * // Without extensions (minimal configuration)\n * const browserContext = new BrowserContext(\n * \"browser_session\",\n * true\n * );\n * // extensionContextSyncs will be undefined\n * ```\n */\nexport class BrowserContext {\n /** ID of the browser context to bind to the session */\n contextId: string;\n /** Whether to automatically upload browser data when the session ends */\n autoUpload: boolean;\n /** Optional extension configuration object containing context_id and extension_ids */\n extensionOption?: ExtensionOption;\n /** ID of the extension context for browser extensions. Set automatically from extension_option. */\n extensionContextId?: string;\n /** List of extension IDs to synchronize. Set automatically from extension_option. */\n extensionIds?: string[];\n /** Auto-generated context syncs for extensions. None if no extension configuration provided. */\n extensionContextSyncs?: ContextSync[];\n\n /**\n * Initialize BrowserContextImpl with optional extension support.\n *\n * @param contextId - ID of the browser context to bind to the session.\n * This identifies the browser instance for the session.\n * @param autoUpload - Whether to automatically upload browser data\n * when the session ends. Defaults to true.\n * @param extensionOption - Extension configuration object containing\n * contextId and extensionIds. This encapsulates\n * all extension-related configuration.\n * Defaults to undefined.\n *\n * Extension Configuration:\n * - **ExtensionOption**: Use extensionOption parameter with an ExtensionOption object\n * - **No Extensions**: Don't provide extensionOption parameter\n *\n * Auto-generation:\n * - extensionContextSyncs is automatically generated when extensionOption is provided\n * - extensionContextSyncs will be undefined if no extensionOption is provided\n * - extensionContextSyncs will be a ContextSync[] if extensionOption is valid\n */\n constructor(\n contextId: string,\n autoUpload: boolean = true,\n extensionOption?: ExtensionOption\n ) {\n this.contextId = contextId;\n this.autoUpload = autoUpload;\n this.extensionOption = extensionOption;\n\n // Handle extension configuration from ExtensionOption\n if (extensionOption) {\n // Extract extension information from ExtensionOption\n this.extensionContextId = extensionOption.contextId;\n this.extensionIds = extensionOption.extensionIds;\n // Auto-generate extension context syncs\n this.extensionContextSyncs = this._createExtensionContextSyncs();\n } else {\n // No extension configuration provided\n this.extensionContextId = undefined;\n this.extensionIds = [];\n this.extensionContextSyncs = undefined;\n }\n }\n\n /**\n * Create ContextSync configurations for browser extensions.\n *\n * This method is called only when extensionOption is provided and contains\n * valid extension configuration (contextId and extensionIds).\n *\n * @returns ContextSync[] - List of context sync configurations for extensions.\n * Returns empty list if extension configuration is invalid.\n */\n private _createExtensionContextSyncs(): ContextSync[] {\n if (!this.extensionIds || this.extensionIds.length === 0 || !this.extensionContextId) {\n return [];\n }\n\n // Create whitelist for each extension ID\n const whiteLists: WhiteList[] = this.extensionIds.map(extId => ({\n path: extId,\n excludePaths: []\n }));\n\n // Create sync policy for extensions\n const syncPolicy: SyncPolicy = {\n uploadPolicy: {\n ...newUploadPolicy(),\n autoUpload: false\n },\n extractPolicy: {\n ...newExtractPolicy(),\n extract: true,\n deleteSrcFile: true\n },\n recyclePolicy: newRecyclePolicy(),\n bwList: {\n whiteLists: whiteLists\n }\n };\n\n // Create context sync for extensions\n const extensionSync = new ContextSync(\n this.extensionContextId,\n \"/tmp/extensions/\",\n syncPolicy\n );\n\n return [extensionSync];\n }\n\n /**\n * Get all context syncs including extension syncs.\n *\n * @returns ContextSync[] - All context sync configurations. Returns empty list if no extensions configured.\n */\n getAllContextSyncs(): ContextSync[] {\n return this.extensionContextSyncs || [];\n }\n}\n\n/**\n * Configuration interface for CreateSessionParams\n */\nexport interface CreateSessionParamsConfig {\n labels: Record<string, string>;\n imageId?: string;\n contextSync: ContextSync[];\n /** Optional configuration for browser data synchronization */\n browserContext?: BrowserContext;\n /** Whether to create a VPC-based session. Defaults to false. */\n isVpc?: boolean;\n /** Policy id to apply when creating the session. */\n policyId?: string;\n /** Whether to enable browser recording for the session. Defaults to false. */\n enableBrowserReplay?: boolean;\n}\n\n/**\n * CreateSessionParams provides a way to configure the parameters for creating a new session\n * in the AgentBay cloud environment.\n */\nexport class CreateSessionParams implements CreateSessionParamsConfig {\n /** Custom labels for the Session. These can be used for organizing and filtering sessions. */\n public labels: Record<string, string>;\n\n /** Image ID to use for the session. */\n public imageId?: string;\n\n /**\n * List of context synchronization configurations.\n * These configurations define how contexts should be synchronized and mounted.\n */\n public contextSync: ContextSync[];\n\n /** Optional configuration for browser data synchronization. */\n public browserContext?: BrowserContext;\n\n /** Whether to create a VPC-based session. Defaults to false. */\n public isVpc: boolean;\n\n /** Policy id to apply when creating the session. */\n public policyId?: string;\n\n /** Whether to enable browser recording for the session. Defaults to false. */\n public enableBrowserReplay: boolean;\n\n constructor() {\n this.labels = {};\n this.contextSync = [];\n this.isVpc = false;\n this.enableBrowserReplay = false;\n }\n\n /**\n * WithLabels sets the labels for the session parameters and returns the updated parameters.\n */\n withLabels(labels: Record<string, string>): CreateSessionParams {\n this.labels = labels;\n return this;\n }\n\n\n /**\n * WithImageId sets the image ID for the session parameters and returns the updated parameters.\n */\n withImageId(imageId: string): CreateSessionParams {\n this.imageId = imageId;\n return this;\n }\n\n /**\n * WithBrowserContext sets the browser context for the session parameters and returns the updated parameters.\n */\n withBrowserContext(browserContext: BrowserContext): CreateSessionParams {\n this.browserContext = browserContext;\n return this;\n }\n\n /**\n * WithIsVpc sets the VPC flag for the session parameters and returns the updated parameters.\n */\n withIsVpc(isVpc: boolean): CreateSessionParams {\n this.isVpc = isVpc;\n return this;\n }\n\n /**\n * WithPolicyId sets the policy id for the session parameters and returns the updated parameters.\n */\n withPolicyId(policyId: string): CreateSessionParams {\n this.policyId = policyId;\n return this;\n }\n\n /**\n * WithenableBrowserReplay sets the browser recording flag for the session parameters and returns the updated parameters.\n */\n withEnableBrowserReplay(enableBrowserReplay: boolean): CreateSessionParams {\n this.enableBrowserReplay = enableBrowserReplay;\n return this;\n }\n\n /**\n * Alias for withEnableBrowserReplay for backward compatibility.\n */\n withEnableRecord(enableRecord: boolean): CreateSessionParams {\n return this.withEnableBrowserReplay(enableRecord);\n }\n\n /**\n * GetLabelsJSON returns the labels as a JSON string.\n * Returns an object with success status and result/error message to match Go version behavior.\n */\n getLabelsJSON(): { result: string; error?: string } {\n if (Object.keys(this.labels).length === 0) {\n return { result: \"\" };\n }\n\n try {\n const labelsJSON = JSON.stringify(this.labels);\n return { result: labelsJSON };\n } catch (error) {\n return {\n result: \"\",\n error: `Failed to marshal labels to JSON: ${error}`,\n };\n }\n }\n\n /**\n * AddContextSync adds a context sync configuration to the session parameters.\n */\n addContextSync(\n contextId: string,\n path: string,\n policy?: SyncPolicy\n ): CreateSessionParams {\n const contextSync = new ContextSync(contextId, path, policy);\n this.contextSync.push(contextSync);\n return this;\n }\n\n /**\n * AddContextSyncConfig adds a pre-configured context sync to the session parameters.\n */\n addContextSyncConfig(contextSync: ContextSync): CreateSessionParams {\n this.contextSync.push(contextSync);\n return this;\n }\n\n /**\n * WithContextSync sets the context sync configurations for the session parameters.\n */\n withContextSync(contextSyncs: ContextSync[]): CreateSessionParams {\n this.contextSync = contextSyncs;\n return this;\n }\n\n /**\n * Convert to plain object for JSON serialization\n */\n toJSON(): CreateSessionParamsConfig {\n // Get base context syncs\n let allContextSyncs = [...this.contextSync];\n\n // Add extension context syncs if browser context has them\n if (this.browserContext && 'getAllContextSyncs' in this.browserContext) {\n const extensionSyncs = this.browserContext.getAllContextSyncs();\n allContextSyncs = allContextSyncs.concat(extensionSyncs);\n }\n\n return {\n labels: this.labels,\n imageId: this.imageId,\n contextSync: allContextSyncs,\n browserContext: this.browserContext,\n isVpc: this.isVpc,\n policyId: this.policyId,\n enableBrowserReplay: this.enableBrowserReplay,\n };\n }\n\n /**\n * Create from plain object\n */\n static fromJSON(config: CreateSessionParamsConfig): CreateSessionParams {\n const params = new CreateSessionParams();\n params.labels = config.labels || {};\n params.imageId = config.imageId;\n params.contextSync = config.contextSync || [];\n\n // Handle browser context - convert to BrowserContext class if needed\n if (config.browserContext) {\n if ('getAllContextSyncs' in config.browserContext) {\n // It's already a BrowserContext instance\n params.browserContext = config.browserContext;\n } else {\n // It's a plain object, convert to BrowserContext class\n const bc = config.browserContext as any; // Type assertion for plain object\n params.browserContext = new BrowserContext(\n bc.contextId,\n bc.autoUpload,\n bc.extensionOption\n );\n }\n }\n\n params.isVpc = config.isVpc || false;\n params.policyId = config.policyId;\n params.enableBrowserReplay = config.enableBrowserReplay || false;\n return params;\n }\n}\n\n/**\n * NewCreateSessionParams creates a new CreateSessionParams with default values.\n */\nexport function newCreateSessionParams(): CreateSessionParams {\n return new CreateSessionParams();\n}"]}
1
+ {"version":3,"sources":["/home/runner/work/wuying-agentbay-sdk/wuying-agentbay-sdk/typescript/dist/index.cjs","../node_modules/dotenv/package.json","../node_modules/dotenv/lib/main.js","../node_modules/dotenv/lib/env-options.js","../node_modules/dotenv/lib/cli-options.js","../src/index.ts","../src/config.ts","../src/version.ts","../src/agent-bay.ts","../node_modules/dotenv/config.js","../src/api/index.ts","../src/api/client.ts","../src/api/models/model.ts","../src/api/models/ApplyMqttTokenResponseBodyData.ts","../src/api/models/CreateMcpSessionRequestPersistenceDataList.ts","../src/api/models/CreateMcpSessionResponseBodyData.ts","../src/api/models/GetContextResponseBodyData.ts","../src/api/models/GetContextInfoResponseBodyData.ts","../src/api/models/GetLabelResponseBodyData.ts","../src/api/models/GetSessionResponseBodyData.ts","../src/api/models/GetLinkResponseBodyData.ts","../src/api/models/GetMcpResourceResponseBodyDataDesktopInfo.ts","../src/api/models/GetMcpResourceResponseBodyData.ts","../src/api/models/ListContextsResponseBodyData.ts","../src/api/models/ListSessionResponseBodyData.ts","../src/api/models/ApplyMqttTokenRequest.ts","../src/api/models/ApplyMqttTokenResponseBody.ts","../src/api/models/ApplyMqttTokenResponse.ts","../src/api/models/CallMcpToolRequest.ts","../src/api/models/CallMcpToolResponseBody.ts","../src/api/models/CallMcpToolResponse.ts","../src/api/models/ClearContextRequest.ts","../src/api/models/ClearContextResponseBody.ts","../src/api/models/ClearContextResponse.ts","../src/api/models/CreateMcpSessionRequest.ts","../src/api/models/CreateMcpSessionShrinkRequest.ts","../src/api/models/CreateMcpSessionResponseBody.ts","../src/api/models/CreateMcpSessionResponse.ts","../src/api/models/DeleteContextRequest.ts","../src/api/models/DeleteContextResponseBody.ts","../src/api/models/DeleteContextResponse.ts","../src/api/models/GetContextRequest.ts","../src/api/models/GetContextResponseBody.ts","../src/api/models/GetContextResponse.ts","../src/api/models/GetContextInfoRequest.ts","../src/api/models/GetContextInfoResponseBody.ts","../src/api/models/GetContextInfoResponse.ts","../src/api/models/GetLabelRequest.ts","../src/api/models/GetLabelResponseBody.ts","../src/api/models/GetLabelResponse.ts","../src/api/models/GetSessionRequest.ts","../src/api/models/GetSessionResponseBody.ts","../src/api/models/GetSessionResponse.ts","../src/api/models/GetLinkRequest.ts","../src/api/models/GetLinkResponseBody.ts","../src/api/models/GetLinkResponse.ts","../src/api/models/GetMcpResourceRequest.ts","../src/api/models/GetMcpResourceResponseBody.ts","../src/api/models/GetMcpResourceResponse.ts","../src/api/models/InitBrowserRequest.ts","../src/api/models/InitBrowserResponseBody.ts","../src/api/models/InitBrowserResponseBodyData.ts","../src/api/models/InitBrowserResponse.ts","../src/api/models/ListContextsRequest.ts","../src/api/models/ListContextsResponseBody.ts","../src/api/models/ListContextsResponse.ts","../src/api/models/ListMcpToolsRequest.ts","../src/api/models/ListMcpToolsResponseBody.ts","../src/api/models/ListMcpToolsResponse.ts","../src/api/models/ListSessionRequest.ts","../src/api/models/ListSessionResponseBody.ts","../src/api/models/ListSessionResponse.ts","../src/api/models/ModifyContextRequest.ts","../src/api/models/ModifyContextResponseBody.ts","../src/api/models/ModifyContextResponse.ts","../src/api/models/ReleaseMcpSessionRequest.ts","../src/api/models/ReleaseMcpSessionResponseBody.ts","../src/api/models/ReleaseMcpSessionResponse.ts","../src/api/models/SetLabelRequest.ts","../src/api/models/SetLabelResponseBody.ts","../src/api/models/SetLabelResponse.ts","../src/api/models/SyncContextRequest.ts","../src/api/models/SyncContextResponseBody.ts","../src/api/models/SyncContextResponse.ts","../src/api/models/DeleteContextFileRequest.ts","../src/api/models/DeleteContextFileResponseBody.ts","../src/api/models/DeleteContextFileResponse.ts","../src/api/models/DescribeContextFilesRequest.ts","../src/api/models/DescribeContextFilesResponseBody.ts","../src/api/models/DescribeContextFilesResponse.ts","../src/api/models/GetContextFileDownloadUrlRequest.ts","../src/api/models/GetContextFileDownloadUrlResponseBody.ts","../src/api/models/GetContextFileDownloadUrlResponse.ts","../src/api/models/GetContextFileUploadUrlRequest.ts","../src/api/models/GetContextFileUploadUrlResponseBody.ts","../src/api/models/GetContextFileUploadUrlResponse.ts","../src/context.ts","../src/exceptions.ts","../src/utils/logger.ts","../src/types/api-response.ts","../src/context-sync.ts","../src/session.ts","../src/agent/agent.ts","../src/browser/index.ts","../src/browser/browser.ts","../src/browser/browser_agent.ts","../src/code/index.ts","../src/code/code.ts","../src/command/command.ts","../src/command/command-templates.ts","../src/computer/index.ts","../src/computer/computer.ts","../src/context-manager.ts","../src/filesystem/filesystem.ts","../src/filesystem/file-transfer.ts","../src/mobile/index.ts","../src/mobile/mobile.ts","../src/oss/index.ts","../src/oss/oss.ts","../src/ui/ui.ts","../src/agent/index.ts","../src/extension.ts","../src/types/index.ts","../src/types/list-session-params.ts","../src/types/extra-configs.ts","../src/session-params.ts"],"names":["fs","path","crypto","parse","context","errorMessage","resolve","elapsed","UploadStrategy","DownloadStrategy","UploadMode","Lifecycle","MouseButton","ScrollDirection","KeyCode","requestId"],"mappings":"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AC2C,MAAA;AACjB,MAAA;AACd,IAAA;AACP,MAAA;AACG,QAAA;AACoC,QAAA;AAC9C,MAAA;AACF,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAAA;AAM0D,EAAA;AAChC,IAAA;AACF,MAAA;AACtB,IAAA;AAEI,IAAA;AAC+C,MAAA;AACf,MAAA;AACpB,IAAA;AACP,MAAA;AACG,QAAA;AACD,QAAA;AACT,MAAA;AACF,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AASuB,EAAA;AAC0Bd,IAAAA;AACd,IAAA;AAC1B,IAAA;AACT,EAAA;AAAA;AAAA;AAAA;AAKoE,EAAA;AACjC,IAAA;AAC1B,IAAA;AACT,EAAA;AAAA;AAAA;AAAA;AAKkE,EAAA;AAC7C,IAAA;AACZ,IAAA;AACT,EAAA;AAAA;AAAA;AAAA;AAKoC,EAAA;AAEQ,IAAA;AAGS,IAAA;AACN,MAAA;AACF,MAAA;AAC3C,IAAA;AAEO,IAAA;AACQ,MAAA;AACC,MAAA;AACD,MAAA;AACQ,MAAA;AACT,MAAA;AACG,MAAA;AACW,MAAA;AACP,MAAA;AACrB,IAAA;AACF,EAAA;AAAA;AAAA;AAAA;AAKwE,EAAA;AAC/B,IAAA;AACL,IAAA;AACV,IAAA;AACoB,IAAA;AAGjB,IAAA;AACU,MAAA;AAEF,QAAA;AAC1B,MAAA;AAEa,QAAA;AACU,QAAA;AACvB,UAAA;AACA,UAAA;AACA,UAAA;AACL,QAAA;AACF,MAAA;AACF,IAAA;AAE+B,IAAA;AACN,IAAA;AACW,IAAA;AACP,IAAA;AACtB,IAAA;AACT,EAAA;AACF;AAhOsE;AAA/D;AAqOuD;AAC7B,EAAA;AACjC;AAFgB;A7H+vXuC;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA","file":"/home/runner/work/wuying-agentbay-sdk/wuying-agentbay-sdk/typescript/dist/index.cjs","sourcesContent":[null,"{\n \"name\": \"dotenv\",\n \"version\": \"16.6.1\",\n \"description\": \"Loads environment variables from .env file\",\n \"main\": \"lib/main.js\",\n \"types\": \"lib/main.d.ts\",\n \"exports\": {\n \".\": {\n \"types\": \"./lib/main.d.ts\",\n \"require\": \"./lib/main.js\",\n \"default\": \"./lib/main.js\"\n },\n \"./config\": \"./config.js\",\n \"./config.js\": \"./config.js\",\n \"./lib/env-options\": \"./lib/env-options.js\",\n \"./lib/env-options.js\": \"./lib/env-options.js\",\n \"./lib/cli-options\": \"./lib/cli-options.js\",\n \"./lib/cli-options.js\": \"./lib/cli-options.js\",\n \"./package.json\": \"./package.json\"\n },\n \"scripts\": {\n \"dts-check\": \"tsc --project tests/types/tsconfig.json\",\n \"lint\": \"standard\",\n \"pretest\": \"npm run lint && npm run dts-check\",\n \"test\": \"tap run --allow-empty-coverage --disable-coverage --timeout=60000\",\n \"test:coverage\": \"tap run --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov\",\n \"prerelease\": \"npm test\",\n \"release\": \"standard-version\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"git://github.com/motdotla/dotenv.git\"\n },\n \"homepage\": \"https://github.com/motdotla/dotenv#readme\",\n \"funding\": \"https://dotenvx.com\",\n \"keywords\": [\n \"dotenv\",\n \"env\",\n \".env\",\n \"environment\",\n \"variables\",\n \"config\",\n \"settings\"\n ],\n \"readmeFilename\": \"README.md\",\n \"license\": \"BSD-2-Clause\",\n \"devDependencies\": {\n \"@types/node\": \"^18.11.3\",\n \"decache\": \"^4.6.2\",\n \"sinon\": \"^14.0.1\",\n \"standard\": \"^17.0.0\",\n \"standard-version\": \"^9.5.0\",\n \"tap\": \"^19.2.0\",\n \"typescript\": \"^4.8.4\"\n },\n \"engines\": {\n \"node\": \">=12\"\n },\n \"browser\": {\n \"fs\": false\n }\n}\n","const fs = require('fs')\nconst path = require('path')\nconst os = require('os')\nconst crypto = require('crypto')\nconst packageJson = require('../package.json')\n\nconst version = packageJson.version\n\nconst LINE = /(?:^|^)\\s*(?:export\\s+)?([\\w.-]+)(?:\\s*=\\s*?|:\\s+?)(\\s*'(?:\\\\'|[^'])*'|\\s*\"(?:\\\\\"|[^\"])*\"|\\s*`(?:\\\\`|[^`])*`|[^#\\r\\n]+)?\\s*(?:#.*)?(?:$|$)/mg\n\n// Parse src into an Object\nfunction parse (src) {\n const obj = {}\n\n // Convert buffer to string\n let lines = src.toString()\n\n // Convert line breaks to same format\n lines = lines.replace(/\\r\\n?/mg, '\\n')\n\n let match\n while ((match = LINE.exec(lines)) != null) {\n const key = match[1]\n\n // Default undefined or null to empty string\n let value = (match[2] || '')\n\n // Remove whitespace\n value = value.trim()\n\n // Check if double quoted\n const maybeQuote = value[0]\n\n // Remove surrounding quotes\n value = value.replace(/^(['\"`])([\\s\\S]*)\\1$/mg, '$2')\n\n // Expand newlines if double quoted\n if (maybeQuote === '\"') {\n value = value.replace(/\\\\n/g, '\\n')\n value = value.replace(/\\\\r/g, '\\r')\n }\n\n // Add to object\n obj[key] = value\n }\n\n return obj\n}\n\nfunction _parseVault (options) {\n options = options || {}\n\n const vaultPath = _vaultPath(options)\n options.path = vaultPath // parse .env.vault\n const result = DotenvModule.configDotenv(options)\n if (!result.parsed) {\n const err = new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`)\n err.code = 'MISSING_DATA'\n throw err\n }\n\n // handle scenario for comma separated keys - for use with key rotation\n // example: DOTENV_KEY=\"dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=prod,dotenv://:key_7890@dotenvx.com/vault/.env.vault?environment=prod\"\n const keys = _dotenvKey(options).split(',')\n const length = keys.length\n\n let decrypted\n for (let i = 0; i < length; i++) {\n try {\n // Get full key\n const key = keys[i].trim()\n\n // Get instructions for decrypt\n const attrs = _instructions(result, key)\n\n // Decrypt\n decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key)\n\n break\n } catch (error) {\n // last key\n if (i + 1 >= length) {\n throw error\n }\n // try next key\n }\n }\n\n // Parse decrypted .env string\n return DotenvModule.parse(decrypted)\n}\n\nfunction _warn (message) {\n console.log(`[dotenv@${version}][WARN] ${message}`)\n}\n\nfunction _debug (message) {\n console.log(`[dotenv@${version}][DEBUG] ${message}`)\n}\n\nfunction _log (message) {\n console.log(`[dotenv@${version}] ${message}`)\n}\n\nfunction _dotenvKey (options) {\n // prioritize developer directly setting options.DOTENV_KEY\n if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) {\n return options.DOTENV_KEY\n }\n\n // secondary infra already contains a DOTENV_KEY environment variable\n if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) {\n return process.env.DOTENV_KEY\n }\n\n // fallback to empty string\n return ''\n}\n\nfunction _instructions (result, dotenvKey) {\n // Parse DOTENV_KEY. Format is a URI\n let uri\n try {\n uri = new URL(dotenvKey)\n } catch (error) {\n if (error.code === 'ERR_INVALID_URL') {\n const err = new Error('INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n throw error\n }\n\n // Get decrypt key\n const key = uri.password\n if (!key) {\n const err = new Error('INVALID_DOTENV_KEY: Missing key part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get environment\n const environment = uri.searchParams.get('environment')\n if (!environment) {\n const err = new Error('INVALID_DOTENV_KEY: Missing environment part')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n }\n\n // Get ciphertext payload\n const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`\n const ciphertext = result.parsed[environmentKey] // DOTENV_VAULT_PRODUCTION\n if (!ciphertext) {\n const err = new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`)\n err.code = 'NOT_FOUND_DOTENV_ENVIRONMENT'\n throw err\n }\n\n return { ciphertext, key }\n}\n\nfunction _vaultPath (options) {\n let possibleVaultPath = null\n\n if (options && options.path && options.path.length > 0) {\n if (Array.isArray(options.path)) {\n for (const filepath of options.path) {\n if (fs.existsSync(filepath)) {\n possibleVaultPath = filepath.endsWith('.vault') ? filepath : `${filepath}.vault`\n }\n }\n } else {\n possibleVaultPath = options.path.endsWith('.vault') ? options.path : `${options.path}.vault`\n }\n } else {\n possibleVaultPath = path.resolve(process.cwd(), '.env.vault')\n }\n\n if (fs.existsSync(possibleVaultPath)) {\n return possibleVaultPath\n }\n\n return null\n}\n\nfunction _resolveHome (envPath) {\n return envPath[0] === '~' ? path.join(os.homedir(), envPath.slice(1)) : envPath\n}\n\nfunction _configVault (options) {\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (debug || !quiet) {\n _log('Loading env from encrypted .env.vault')\n }\n\n const parsed = DotenvModule._parseVault(options)\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsed, options)\n\n return { parsed }\n}\n\nfunction configDotenv (options) {\n const dotenvPath = path.resolve(process.cwd(), '.env')\n let encoding = 'utf8'\n const debug = Boolean(options && options.debug)\n const quiet = options && 'quiet' in options ? options.quiet : true\n\n if (options && options.encoding) {\n encoding = options.encoding\n } else {\n if (debug) {\n _debug('No encoding is specified. UTF-8 is used by default')\n }\n }\n\n let optionPaths = [dotenvPath] // default, look for .env\n if (options && options.path) {\n if (!Array.isArray(options.path)) {\n optionPaths = [_resolveHome(options.path)]\n } else {\n optionPaths = [] // reset default\n for (const filepath of options.path) {\n optionPaths.push(_resolveHome(filepath))\n }\n }\n }\n\n // Build the parsed data in a temporary object (because we need to return it). Once we have the final\n // parsed data, we will combine it with process.env (or options.processEnv if provided).\n let lastError\n const parsedAll = {}\n for (const path of optionPaths) {\n try {\n // Specifying an encoding returns a string instead of a buffer\n const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }))\n\n DotenvModule.populate(parsedAll, parsed, options)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${path} ${e.message}`)\n }\n lastError = e\n }\n }\n\n let processEnv = process.env\n if (options && options.processEnv != null) {\n processEnv = options.processEnv\n }\n\n DotenvModule.populate(processEnv, parsedAll, options)\n\n if (debug || !quiet) {\n const keysCount = Object.keys(parsedAll).length\n const shortPaths = []\n for (const filePath of optionPaths) {\n try {\n const relative = path.relative(process.cwd(), filePath)\n shortPaths.push(relative)\n } catch (e) {\n if (debug) {\n _debug(`Failed to load ${filePath} ${e.message}`)\n }\n lastError = e\n }\n }\n\n _log(`injecting env (${keysCount}) from ${shortPaths.join(',')}`)\n }\n\n if (lastError) {\n return { parsed: parsedAll, error: lastError }\n } else {\n return { parsed: parsedAll }\n }\n}\n\n// Populates process.env from .env file\nfunction config (options) {\n // fallback to original dotenv if DOTENV_KEY is not set\n if (_dotenvKey(options).length === 0) {\n return DotenvModule.configDotenv(options)\n }\n\n const vaultPath = _vaultPath(options)\n\n // dotenvKey exists but .env.vault file does not exist\n if (!vaultPath) {\n _warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`)\n\n return DotenvModule.configDotenv(options)\n }\n\n return DotenvModule._configVault(options)\n}\n\nfunction decrypt (encrypted, keyStr) {\n const key = Buffer.from(keyStr.slice(-64), 'hex')\n let ciphertext = Buffer.from(encrypted, 'base64')\n\n const nonce = ciphertext.subarray(0, 12)\n const authTag = ciphertext.subarray(-16)\n ciphertext = ciphertext.subarray(12, -16)\n\n try {\n const aesgcm = crypto.createDecipheriv('aes-256-gcm', key, nonce)\n aesgcm.setAuthTag(authTag)\n return `${aesgcm.update(ciphertext)}${aesgcm.final()}`\n } catch (error) {\n const isRange = error instanceof RangeError\n const invalidKeyLength = error.message === 'Invalid key length'\n const decryptionFailed = error.message === 'Unsupported state or unable to authenticate data'\n\n if (isRange || invalidKeyLength) {\n const err = new Error('INVALID_DOTENV_KEY: It must be 64 characters long (or more)')\n err.code = 'INVALID_DOTENV_KEY'\n throw err\n } else if (decryptionFailed) {\n const err = new Error('DECRYPTION_FAILED: Please check your DOTENV_KEY')\n err.code = 'DECRYPTION_FAILED'\n throw err\n } else {\n throw error\n }\n }\n}\n\n// Populate process.env with parsed values\nfunction populate (processEnv, parsed, options = {}) {\n const debug = Boolean(options && options.debug)\n const override = Boolean(options && options.override)\n\n if (typeof parsed !== 'object') {\n const err = new Error('OBJECT_REQUIRED: Please check the processEnv argument being passed to populate')\n err.code = 'OBJECT_REQUIRED'\n throw err\n }\n\n // Set process.env\n for (const key of Object.keys(parsed)) {\n if (Object.prototype.hasOwnProperty.call(processEnv, key)) {\n if (override === true) {\n processEnv[key] = parsed[key]\n }\n\n if (debug) {\n if (override === true) {\n _debug(`\"${key}\" is already defined and WAS overwritten`)\n } else {\n _debug(`\"${key}\" is already defined and was NOT overwritten`)\n }\n }\n } else {\n processEnv[key] = parsed[key]\n }\n }\n}\n\nconst DotenvModule = {\n configDotenv,\n _configVault,\n _parseVault,\n config,\n decrypt,\n parse,\n populate\n}\n\nmodule.exports.configDotenv = DotenvModule.configDotenv\nmodule.exports._configVault = DotenvModule._configVault\nmodule.exports._parseVault = DotenvModule._parseVault\nmodule.exports.config = DotenvModule.config\nmodule.exports.decrypt = DotenvModule.decrypt\nmodule.exports.parse = DotenvModule.parse\nmodule.exports.populate = DotenvModule.populate\n\nmodule.exports = DotenvModule\n","// ../config.js accepts options via environment variables\nconst options = {}\n\nif (process.env.DOTENV_CONFIG_ENCODING != null) {\n options.encoding = process.env.DOTENV_CONFIG_ENCODING\n}\n\nif (process.env.DOTENV_CONFIG_PATH != null) {\n options.path = process.env.DOTENV_CONFIG_PATH\n}\n\nif (process.env.DOTENV_CONFIG_QUIET != null) {\n options.quiet = process.env.DOTENV_CONFIG_QUIET\n}\n\nif (process.env.DOTENV_CONFIG_DEBUG != null) {\n options.debug = process.env.DOTENV_CONFIG_DEBUG\n}\n\nif (process.env.DOTENV_CONFIG_OVERRIDE != null) {\n options.override = process.env.DOTENV_CONFIG_OVERRIDE\n}\n\nif (process.env.DOTENV_CONFIG_DOTENV_KEY != null) {\n options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY\n}\n\nmodule.exports = options\n","const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/\n\nmodule.exports = function optionMatcher (args) {\n const options = args.reduce(function (acc, cur) {\n const matches = cur.match(re)\n if (matches) {\n acc[matches[1]] = matches[2]\n }\n return acc\n }, {})\n\n if (!('quiet' in options)) {\n options.quiet = 'true'\n }\n\n return options\n}\n","// IMPORTANT: Load config first to ensure .env file is loaded before logger initialization\nexport { loadConfig, loadDotEnv, type Config } from \"./config\";\n\n// Export version information\nexport { VERSION, IS_RELEASE } from \"./version\";\n\n// Export all public classes and interfaces\nexport { AgentBay, type CreateSessionParams} from \"./agent-bay\";\nexport * from \"./agent\";\nexport * from \"./api\";\nexport * from \"./application\";\nexport * from \"./browser\";\nexport * from \"./command\";\nexport { Context, ContextService } from \"./context\";\nexport * from \"./exceptions\";\nexport * from \"./extension\";\nexport * from \"./filesystem\";\nexport * from \"./oss\";\nexport { Session } from \"./session\";\nexport { type ListSessionParams } from \"./types\";\nexport * from \"./types\";\nexport * from \"./ui\";\nexport * from './context-sync'\nexport * from './context-manager'\nexport * from './session-params'\n// Export utility functions\nexport {\n log,\n logDebug,\n logInfo,\n logWarn,\n logError,\n setLogLevel,\n getLogLevel,\n maskSensitiveData,\n setupLogger,\n type LogLevel,\n type LoggerConfig\n} from \"./utils/logger\";\n","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as dotenv from \"dotenv\";\n\ninterface Config {\n endpoint: string;\n timeout_ms: number;\n}\n\n/**\n * Browser data path constant\n */\nexport const BROWSER_DATA_PATH = \"/tmp/agentbay_browser\";\n\n/**\n * Returns the default configuration\n */\nexport function defaultConfig(): Config {\n return {\n endpoint: \"wuyingai.cn-shanghai.aliyuncs.com\",\n timeout_ms: 60000,\n };\n}\n\n/**\n * Find .env file by searching upward from start_path.\n * \n * Search order:\n * 1. Current working directory\n * 2. Parent directories (up to root)\n * 3. Git repository root (if found)\n * \n * @param startPath Starting directory for search (defaults to current working directory)\n * @returns Path to .env file if found, null otherwise\n */\nexport function findDotEnvFile(startPath?: string): string | null {\n const currentPath = startPath ? path.resolve(startPath) : process.cwd();\n let searchPath = currentPath;\n\n // Search upward until we reach root directory\n while (searchPath !== path.dirname(searchPath)) {\n const envFile = path.join(searchPath, \".env\");\n if (fs.existsSync(envFile)) {\n return envFile;\n }\n\n // Check if this is a git repository root\n const gitDir = path.join(searchPath, \".git\");\n if (fs.existsSync(gitDir)) {\n // Found git root, continue searching\n }\n\n searchPath = path.dirname(searchPath);\n }\n\n // Check root directory as well\n const rootEnv = path.join(searchPath, \".env\");\n if (fs.existsSync(rootEnv)) {\n return rootEnv;\n }\n\n return null;\n}\n\n/**\n * Load .env file with improved search strategy.\n * \n * @param customEnvPath Custom path to .env file (optional)\n */\nexport function loadDotEnvWithFallback(customEnvPath?: string): void {\n if (customEnvPath) {\n // Use custom path if provided\n if (fs.existsSync(customEnvPath)) {\n try {\n const envConfig = dotenv.parse(fs.readFileSync(customEnvPath));\n for (const k in envConfig) {\n // only load env variables that are not already set in process.env\n if (!process.env.hasOwnProperty(k)) {\n process.env[k] = envConfig[k];\n }\n }\n return;\n } catch (error) {\n // Silently fail - .env loading is optional\n }\n }\n }\n\n // Find .env file using upward search\n const envFile = findDotEnvFile();\n if (envFile) {\n try {\n const envConfig = dotenv.parse(fs.readFileSync(envFile));\n for (const k in envConfig) {\n // only load env variables that are not already set in process.env\n if (!process.env.hasOwnProperty(k)) {\n process.env[k] = envConfig[k];\n }\n }\n } catch (error) {\n // Silently fail - .env loading is optional\n }\n }\n}\n\n// Track if .env file has been loaded to avoid duplicate loading\nlet dotEnvLoaded = false;\n\n/**\n * Load .env file into process.env if it exists\n * This function should be called early to ensure .env variables are available\n * @deprecated Use loadDotEnvWithFallback instead\n */\nexport function loadDotEnv(): void {\n if (dotEnvLoaded) {\n return; // Already loaded, skip\n }\n\n loadDotEnvWithFallback();\n dotEnvLoaded = true;\n}\n\n// Auto-load .env file on module initialization\n// This ensures environment variables are available before logger module is loaded\nif (!dotEnvLoaded) {\n try {\n loadDotEnvWithFallback();\n dotEnvLoaded = true;\n } catch (error) {\n // Silently fail - .env loading is optional\n }\n}\n\n/**\n * The SDK uses the following precedence order for configuration (highest to lowest):\n * 1. Explicitly passed configuration in code.\n * 2. Environment variables.\n * 3. .env file.\n * 4. Default configuration.\n */\n/**\n * Load configuration with improved .env file search.\n * \n * @param customConfig Configuration object (if provided, skips env loading)\n * @param customEnvPath Custom path to .env file (optional)\n * @returns Configuration object\n */\nexport function loadConfig(customConfig?: Config, customEnvPath?: string): Config {\n // If custom config is provided, use it directly\n if (customConfig) {\n return customConfig;\n }\n\n // Create base config from default values\n const config = defaultConfig();\n\n // Load .env file with improved search first\n try {\n loadDotEnvWithFallback(customEnvPath);\n } catch (error) {\n // Silently fail - .env loading is optional\n }\n\n // Override with environment variables if they exist (highest priority)\n if (process.env.AGENTBAY_ENDPOINT) {\n config.endpoint = process.env.AGENTBAY_ENDPOINT;\n }\n\n if (process.env.AGENTBAY_TIMEOUT_MS) {\n const timeout = parseInt(process.env.AGENTBAY_TIMEOUT_MS, 10);\n if (!isNaN(timeout) && timeout > 0) {\n config.timeout_ms = timeout;\n }\n }\n\n return config;\n}\n\nexport { Config };\n","/**\n * Version information for the AgentBay SDK\n * Automatically read from package.json\n */\n\nimport * as fs from \"fs\";\nimport * as path from \"path\";\n\nfunction getVersionFromPackageJson(): string {\n try {\n // Get the path to package.json (relative to this file)\n // When compiled, this will be in dist/, so we need to go up to find package.json\n const packageJsonPath = path.join(__dirname, \"..\", \"package.json\");\n \n if (fs.existsSync(packageJsonPath)) {\n const packageJson = JSON.parse(fs.readFileSync(packageJsonPath, \"utf-8\"));\n return packageJson.version || \"0.0.0\";\n }\n } catch (error) {\n // Fallback to default version if reading fails\n }\n \n // Fallback version if package.json cannot be read\n return \"0.9.4\";\n}\n\n/**\n * Check if this is a release build.\n * Returns true only if built by official release workflows:\n * - npm_publish.yml\n */\nfunction isReleaseBuild(): boolean {\n // Check if running in GitHub Actions\n if (process.env.GITHUB_ACTIONS !== \"true\") {\n return false;\n }\n \n // Check if triggered by npm_publish workflow\n const workflow = process.env.GITHUB_WORKFLOW || \"\";\n if (workflow.includes(\"Build and Publish to npm\")) {\n return true;\n }\n \n // Check for AGENTBAY_RELEASE_BUILD environment variable\n // This can be set in CI/CD for release builds\n if (process.env.AGENTBAY_RELEASE_BUILD === \"true\") {\n return true;\n }\n \n return false;\n}\n\nexport const VERSION = getVersionFromPackageJson();\nexport const IS_RELEASE = isReleaseBuild();\n\n","import { $OpenApiUtil } from \"@alicloud/openapi-core\";\nimport \"dotenv/config\";\nimport * as $_client from \"./api\";\nimport { ListSessionRequest, CreateMcpSessionRequestPersistenceDataList, GetSessionRequest as $GetSessionRequest } from \"./api/models/model\";\nimport { Client } from \"./api/client\";\n\nimport { loadConfig, loadDotEnvWithFallback, Config, BROWSER_DATA_PATH } from \"./config\";\nimport { ContextService } from \"./context\";\nimport { ContextSync } from \"./context-sync\";\nimport { APIError, AuthenticationError } from \"./exceptions\";\nimport { Session } from \"./session\";\nimport { BrowserContext } from \"./session-params\";\nimport { Context } from \"./context\";\nimport { ExtraConfigs } from \"./types/extra-configs\";\n\nimport {\n DeleteResult,\n extractRequestId,\n GetSessionResult as $GetSessionResult,\n SessionResult,\n} from \"./types/api-response\";\nimport {\n ListSessionParams,\n SessionListResult,\n} from \"./types/list-session-params\";\nimport {\n log,\n logError,\n logInfo,\n logDebug,\n logAPICall,\n logAPIResponseWithDetails,\n maskSensitiveData,\n setRequestId,\n getRequestId,\n} from \"./utils/logger\";\nimport { VERSION, IS_RELEASE } from \"./version\";\n\n/**\n * Generate a random context name using alphanumeric characters with timestamp.\n * This function is similar to the Python version's generate_random_context_name.\n */\nfunction generateRandomContextName(length = 8, includeTimestamp = true): string {\n const timestamp = new Date().toISOString().replace(/[-T:.Z]/g, '').slice(0, 14);\n\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n let randomPart = '';\n for (let i = 0; i < length; i++) {\n randomPart += characters.charAt(Math.floor(Math.random() * characters.length));\n }\n\n return includeTimestamp ? `${timestamp}_${randomPart}` : randomPart;\n}\n\n/**\n * Parameters for creating a session.\n */\nexport interface CreateSessionParams {\n labels?: Record<string, string>;\n imageId?: string;\n contextSync?: ContextSync[];\n browserContext?: BrowserContext;\n isVpc?: boolean;\n policyId?: string;\n enableBrowserReplay?: boolean;\n extraConfigs?: ExtraConfigs;\n framework?: string;\n}\n\n/**\n * Main class for interacting with the AgentBay cloud runtime environment.\n */\nexport class AgentBay {\n private apiKey: string;\n private client: Client;\n private endpoint: string;\n private sessions: Map<string, Session> = new Map();\n private fileTransferContext: Context | null = null;\n\n /**\n * Context service for managing persistent contexts.\n */\n context: ContextService;\n\n /**\n * Initialize the AgentBay client.\n *\n * @param options - Configuration options\n * @param options.apiKey - API key for authentication. If not provided, will look for AGENTBAY_API_KEY environment variable.\n * @param options.config - Custom configuration object. If not provided, will use environment-based configuration.\n * @param options.envFile - Custom path to .env file. If not provided, will search upward from current directory.\n */\n constructor(\n options: {\n apiKey?: string;\n config?: Config;\n envFile?: string;\n } = {}\n ) {\n // Load .env file first to ensure AGENTBAY_API_KEY is available\n loadDotEnvWithFallback(options.envFile);\n\n this.apiKey = options.apiKey || process.env.AGENTBAY_API_KEY || \"\";\n\n if (!this.apiKey) {\n throw new AuthenticationError(\n \"API key is required. Provide it as a parameter or set the AGENTBAY_API_KEY environment variable.\"\n );\n }\n\n // Load configuration using the enhanced loadConfig function\n const configData = loadConfig(options.config, options.envFile);\n this.endpoint = configData.endpoint;\n\n const config = new $OpenApiUtil.Config({\n regionId: \"\",\n endpoint: this.endpoint,\n });\n\n config.readTimeout = configData.timeout_ms;\n config.connectTimeout = configData.timeout_ms;\n\n try {\n this.client = new Client(config);\n\n // Initialize context service\n this.context = new ContextService(this);\n } catch (error) {\n logError(`Failed to constructor:`, error);\n throw new AuthenticationError(`Failed to constructor: ${error}`);\n }\n }\n\n /**\n * Update browser replay context with AppInstanceId from response data.\n *\n * @param responseData - Response data containing AppInstanceId\n * @param recordContextId - The record context ID to update\n */\n private async _updateBrowserReplayContext(responseData: any, recordContextId: string): Promise<void> {\n // Check if record_context_id is provided\n if (!recordContextId) {\n return;\n }\n\n try {\n // Extract AppInstanceId from response data\n const appInstanceId = responseData?.appInstanceId;\n if (!appInstanceId) {\n logError(\"AppInstanceId not found in response data, skipping browser replay context update\");\n return;\n }\n\n // Create context name with prefix\n const contextName = `browserreplay-${appInstanceId}`;\n\n // Create Context object for update\n const contextObj = new Context(recordContextId, contextName);\n\n // Call context.update interface\n logDebug(`Updating browser replay context: ${contextName} -> ${recordContextId}`);\n const updateResult = await this.context.update(contextObj);\n\n if (updateResult.success) {\n logInfo(`✅ Successfully updated browser replay context: ${contextName}`);\n } else {\n logError(`⚠️ Failed to update browser replay context: ${updateResult.errorMessage}`);\n }\n } catch (error) {\n logError(`❌ Error updating browser replay context: ${error}`);\n // Continue execution even if context update fails\n }\n }\n\n /**\n * Create a new session in the AgentBay cloud environment.\n *\n * @param params - Optional parameters for creating the session\n * @returns SessionResult containing the created session and request ID\n */\n async create(params: CreateSessionParams = {}): Promise<SessionResult> {\n try {\n // Create a default context for file transfer operations if none provided\n // and no context_syncs are specified\n const contextName = `file-transfer-context-${Date.now()}`;\n const contextResult = await this.context.get(contextName, true);\n if (contextResult.success && contextResult.context) {\n this.fileTransferContext = contextResult.context;\n // Add the context to the session params for file transfer operations\n const fileTransferContextSync = new ContextSync(\n contextResult.context.id,\n \"/temp/file-transfer\"\n );\n if (!params.contextSync) {\n params.contextSync = [];\n }\n logDebug(`Adding context sync for file transfer operations: ${fileTransferContextSync}`);\n params.contextSync.push(fileTransferContextSync);\n }\n\n const request = new $_client.CreateMcpSessionRequest({\n authorization: \"Bearer \" + this.apiKey,\n });\n\n // Add SDK stats for tracking\n const framework = params?.framework || \"\";\n const sdkStatsJson = `{\"source\":\"sdk\",\"sdk_language\":\"typescript\",\"sdk_version\":\"${VERSION}\",\"is_release\":${IS_RELEASE},\"framework\":\"${framework}\"}`;\n request.sdkStats = sdkStatsJson;\n\n // Add labels if provided\n if (params.labels) {\n request.labels = JSON.stringify(params.labels);\n }\n\n // Add image_id if provided\n if (params.imageId) {\n request.imageId = params.imageId;\n }\n\n // Add PolicyId if provided\n if (params.policyId) {\n request.mcpPolicyId = params.policyId;\n }\n\n // Add VPC resource if specified\n request.vpcResource = params.isVpc || false;\n\n // Flag to indicate if we need to wait for context synchronization\n let needsContextSync = false;\n\n // Add context sync configurations if provided\n if (params.contextSync && params.contextSync.length > 0) {\n const persistenceDataList: CreateMcpSessionRequestPersistenceDataList[] = [];\n for (const contextSync of params.contextSync) {\n const persistenceItem = new CreateMcpSessionRequestPersistenceDataList({\n contextId: contextSync.contextId,\n path: contextSync.path,\n });\n\n // Convert policy to JSON string if provided\n if (contextSync.policy) {\n persistenceItem.policy = JSON.stringify(contextSync.policy);\n }\n\n persistenceDataList.push(persistenceItem);\n }\n request.persistenceDataList = persistenceDataList;\n needsContextSync = persistenceDataList.length > 0;\n }\n\n // Add BrowserContext as a ContextSync if provided\n if (params.browserContext) {\n // Create a simple sync policy for browser context\n const syncPolicy = {\n uploadPolicy: { autoUpload: params.browserContext.autoUpload },\n downloadPolicy: null,\n deletePolicy: null,\n bwList: null,\n recyclePolicy: null,\n };\n\n // Create browser context sync item\n const browserContextSync = new CreateMcpSessionRequestPersistenceDataList({\n contextId: params.browserContext.contextId,\n path: BROWSER_DATA_PATH, // Using a constant path for browser data\n policy: JSON.stringify(syncPolicy)\n });\n\n // Add to persistence data list or create new one if not exists\n if (!request.persistenceDataList) {\n request.persistenceDataList = [];\n }\n request.persistenceDataList.push(browserContextSync);\n needsContextSync = true;\n }\n\n // Add browser recording persistence if enabled\n let recordContextId = \"\"; // Initialize record_context_id\n if (params.enableBrowserReplay) {\n // Create browser recording persistence configuration\n const recordPath = \"/home/guest/record\";\n const recordContextName = generateRandomContextName();\n const result = await this.context.get(recordContextName, true);\n recordContextId = result.success ? result.contextId : \"\";\n const recordPersistence = new CreateMcpSessionRequestPersistenceDataList({\n contextId: recordContextId,\n path: recordPath,\n });\n\n // Add to persistence data list or create new one if not exists\n if (!request.persistenceDataList) {\n request.persistenceDataList = [];\n }\n request.persistenceDataList.push(recordPersistence);\n }\n\n // Add extra configs if provided\n if (params.extraConfigs) {\n request.extraConfigs = JSON.stringify(params.extraConfigs);\n }\n\n // Log API request\n logAPICall(\"CreateMcpSession\", {\n labels: params.labels,\n imageId: params.imageId,\n policyId: params.policyId,\n isVpc: params.isVpc,\n persistenceDataCount: params.contextSync ? params.contextSync.length : 0,\n });\n\n const response = await this.client.createMcpSession(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n setRequestId(requestId);\n\n const sessionData = response.body;\n\n if (!sessionData || typeof sessionData !== \"object\") {\n logAPIResponseWithDetails(\n \"CreateMcpSession\",\n requestId,\n false,\n {},\n \"Invalid response format: expected a dictionary\"\n );\n logDebug(\"Full response:\", JSON.stringify(sessionData, null, 2));\n return {\n requestId,\n success: false,\n errorMessage: \"Invalid response format: expected a dictionary\",\n };\n }\n\n // Check for API-level errors\n if (sessionData.success === false && sessionData.code) {\n const errorMessage = `[${sessionData.code}] ${sessionData.message || 'Unknown error'}`;\n logAPIResponseWithDetails(\n \"CreateMcpSession\",\n requestId,\n false,\n {},\n errorMessage\n );\n logDebug(\"Full response:\", JSON.stringify(sessionData, null, 2));\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n const data = sessionData.data;\n if (!data || typeof data !== \"object\") {\n logAPIResponseWithDetails(\n \"CreateMcpSession\",\n requestId,\n false,\n {},\n \"Invalid response format: 'data' field is not a dictionary\"\n );\n logDebug(\"Full response:\", JSON.stringify(sessionData, null, 2));\n return {\n requestId,\n success: false,\n errorMessage:\n \"Invalid response format: 'data' field is not a dictionary\",\n };\n }\n\n // Check data-level success field (business logic success)\n if (data.success === false) {\n const errorMessage = data.errMsg || \"Session creation failed\";\n logAPIResponseWithDetails(\n \"CreateMcpSession\",\n requestId,\n false,\n {},\n errorMessage\n );\n logDebug(\"Full response:\", JSON.stringify(sessionData, null, 2));\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n const sessionId = data.sessionId;\n if (!sessionId) {\n logAPIResponseWithDetails(\n \"CreateMcpSession\",\n requestId,\n false,\n {},\n \"SessionId not found in response\"\n );\n logDebug(\"Full response:\", JSON.stringify(sessionData, null, 2));\n return {\n requestId,\n success: false,\n errorMessage: \"SessionId not found in response\",\n };\n }\n\n // ResourceUrl is optional in CreateMcpSession response\n const resourceUrl = data.resourceUrl || \"\";\n\n logAPIResponseWithDetails(\n \"CreateMcpSession\",\n requestId,\n true,\n {\n sessionId,\n resourceUrl,\n }\n );\n\n const session = new Session(this, sessionId);\n\n // Set VPC-related information from response\n session.isVpc = params.isVpc || false;\n if (data.networkInterfaceIp) {\n session.networkInterfaceIp = data.networkInterfaceIp;\n }\n if (data.httpPort) {\n session.httpPort = data.httpPort;\n }\n if (data.token) {\n session.token = data.token;\n }\n\n // Set ResourceUrl\n session.resourceUrl = resourceUrl;\n\n // Set browser recording state\n session.enableBrowserReplay = params.enableBrowserReplay || false;\n\n // Store the file transfer context ID if we created one\n session.fileTransferContextId = this.fileTransferContext ? this.fileTransferContext.id : null;\n\n // Store the browser recording context ID if we created one\n session.recordContextId = recordContextId || null;\n\n // Store imageId used for this session\n (session as any).imageId = params.imageId;\n\n\n this.sessions.set(session.sessionId, session);\n\n // Apply mobile configuration if provided\n if (params.extraConfigs && params.extraConfigs.mobile) {\n log(\"Applying mobile configuration...\");\n try {\n const configResult = await session.mobile.configure(params.extraConfigs.mobile);\n if (configResult.success) {\n log(\"Mobile configuration applied successfully\");\n } else {\n logError(`Warning: Failed to apply mobile configuration: ${configResult.errorMessage}`);\n // Continue with session creation even if mobile config fails\n }\n } catch (error) {\n logError(`Warning: Failed to apply mobile configuration: ${error}`);\n // Continue with session creation even if mobile config fails\n }\n }\n\n // Update browser replay context if enabled\n if (params.enableBrowserReplay) {\n await this._updateBrowserReplayContext(data, recordContextId);\n }\n\n // For VPC sessions, automatically fetch MCP tools information\n if (params.isVpc) {\n logDebug(\"VPC session detected, automatically fetching MCP tools...\");\n try {\n const toolsResult = await session.listMcpTools();\n logDebug(`Successfully fetched ${toolsResult.tools.length} MCP tools for VPC session (RequestID: ${toolsResult.requestId})`);\n } catch (error) {\n logError(`Warning: Failed to fetch MCP tools for VPC session: ${error}`);\n // Continue with session creation even if tools fetch fails\n }\n }\n\n // If we have persistence data, wait for context synchronization\n if (needsContextSync) {\n logDebug(\"Waiting for context synchronization to complete...\");\n\n // Wait for context synchronization to complete\n const maxRetries = 150; // Maximum number of retries\n const retryInterval = 1500; // Milliseconds to wait between retries\n\n for (let retry = 0; retry < maxRetries; retry++) {\n try {\n // Get context status data\n const infoResult = await session.context.info();\n\n // Check if all context items have status \"Success\" or \"Failed\"\n let allCompleted = true;\n let hasFailure = false;\n\n for (const item of infoResult.contextStatusData) {\n logDebug(`Context ${item.contextId} status: ${item.status}, path: ${item.path}`);\n\n if (item.status !== \"Success\" && item.status !== \"Failed\") {\n allCompleted = false;\n break;\n }\n\n if (item.status === \"Failed\") {\n hasFailure = true;\n logError(`Context synchronization failed for ${item.contextId}: ${item.errorMessage}`);\n }\n }\n\n if (allCompleted || infoResult.contextStatusData.length === 0) {\n if (hasFailure) {\n logDebug(\"Context synchronization completed with failures\");\n } else {\n logDebug(\"Context synchronization completed successfully\");\n }\n break;\n }\n\n logDebug(`Waiting for context synchronization, attempt ${retry+1}/${maxRetries}`);\n await new Promise(resolve => setTimeout(resolve, retryInterval));\n } catch (error) {\n logError(`Error checking context status on attempt ${retry+1}: ${error}`);\n await new Promise(resolve => setTimeout(resolve, retryInterval));\n }\n }\n }\n\n // Return SessionResult with request ID\n return {\n requestId,\n success: true,\n session,\n };\n } catch (error) {\n logError(\"Error calling create_mcp_session:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to create session: ${error}`,\n };\n }\n }\n\n\n /**\n * List sessions filtered by the provided labels with pagination support.\n * It returns sessions that match all the specified labels.\n *\n * @deprecated This method is deprecated and will be removed in a future version. Use list() instead.\n *\n * **Breaking Change**: This method currently only accepts ListSessionParams parameters,\n *\n * @param params - Parameters including labels and pagination options (required)\n * @returns API response with sessions list and pagination info\n */\n async listByLabels(params?: ListSessionParams): Promise<SessionListResult> {\n if (!params) {\n params = {\n maxResults: 10,\n labels: {},\n };\n }\n\n try {\n // Convert labels to JSON\n const labelsJSON = JSON.stringify(params.labels);\n\n //Build request object with support for pagination parameters\n const listSessionRequest = new ListSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n labels: labelsJSON,\n maxResults: params.maxResults || 10,\n ...(params.nextToken && { nextToken: params.nextToken }),\n });\n\n logAPICall(\"ListSession\");\n logDebug(\n `Request: Labels=${labelsJSON}, MaxResults=${params.maxResults || 10}${\n params.nextToken ? `, NextToken=${params.nextToken}` : \"\"\n }`\n );\n\n const response = await this.client.listSession(listSessionRequest);\n const body = response.body;\n const requestId = extractRequestId(body?.requestId) || \"\";\n\n // Check for errors in the response\n if (\n body?.data &&\n typeof body.data === \"object\" &&\n body.success &&\n body.success !== true\n ) {\n return {\n requestId,\n success: false,\n errorMessage: \"Failed to list sessions by labels\",\n sessionIds: [],\n nextToken: \"\",\n maxResults: params.maxResults || 10,\n totalCount: 0,\n };\n }\n\n const sessionIds: string[] = [];\n let nextToken = \"\";\n let maxResults = params.maxResults || 10;\n let totalCount = 0;\n\n logDebug(\"body =\", body);\n\n // Extract pagination information\n if (body && typeof body === \"object\") {\n nextToken = body.nextToken || \"\";\n maxResults = parseInt(String(body.maxResults || 0)) || maxResults;\n totalCount = parseInt(String(body.totalCount || 0));\n }\n\n // Extract session data\n const responseData = body?.data;\n\n // Handle both list and dict responses\n if (Array.isArray(responseData)) {\n // Data is a list of session objects\n for (const sessionData of responseData) {\n if (sessionData && typeof sessionData === \"object\") {\n const sessionId = (sessionData as any).sessionId; // Capital S and I to match Python\n if (sessionId) {\n sessionIds.push(sessionId);\n }\n }\n }\n }\n\n // Return SessionListResult with request ID and pagination info\n return {\n requestId,\n success: true,\n sessionIds,\n nextToken,\n maxResults,\n totalCount,\n };\n } catch (error) {\n logError(\"Error calling list_session:\", error);\n return {\n requestId: \"\",\n success: false,\n sessionIds: [],\n errorMessage: `Failed to list sessions by labels: ${error}`,\n };\n }\n }\n\n /**\n * Returns paginated list of session IDs filtered by labels.\n *\n * @param labels - Optional labels to filter sessions (defaults to empty object)\n * @param page - Optional page number for pagination (starting from 1, defaults to 1)\n * @param limit - Optional maximum number of items per page (defaults to 10)\n * @returns SessionListResult - Paginated list of session IDs that match the labels\n *\n * @example\n * ```typescript\n * const agentBay = new AgentBay({ apiKey: \"your_api_key\" });\n *\n * // List all sessions\n * const result = await agentBay.list();\n *\n * // List sessions with specific labels\n * const result = await agentBay.list({ project: \"demo\" });\n *\n * // List sessions with pagination\n * const result = await agentBay.list({ \"my-label\": \"my-value\" }, 2, 10);\n *\n * if (result.success) {\n * for (const sessionId of result.sessionIds) {\n * console.log(`Session ID: ${sessionId}`);\n * }\n * console.log(`Total count: ${result.totalCount}`);\n * console.log(`Request ID: ${result.requestId}`);\n * }\n * ```\n */\n async list(\n labels: Record<string, string> = {},\n page?: number,\n limit: number = 10\n ): Promise<SessionListResult> {\n try {\n // Validate page number\n if (page !== undefined && page < 1) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Cannot reach page ${page}: Page number must be >= 1`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: 0,\n };\n }\n\n // Calculate next_token based on page number\n // Page 1 or undefined means no next_token (first page)\n // For page > 1, we need to make multiple requests to get to that page\n let nextToken = \"\";\n if (page !== undefined && page > 1) {\n // We need to fetch pages 1 through page-1 to get the next_token\n let currentPage = 1;\n while (currentPage < page) {\n // Make API call to get next_token\n const request = new ListSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n labels: JSON.stringify(labels),\n maxResults: limit,\n });\n if (nextToken) {\n request.nextToken = nextToken;\n }\n\n const response = await this.client.listSession(request);\n const requestId = extractRequestId(response) || \"\";\n\n if (!response.body?.success) {\n const code = response.body?.code || \"Unknown\";\n const message = response.body?.message || \"Unknown error\";\n return {\n requestId,\n success: false,\n errorMessage: `[${code}] ${message}`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: 0,\n };\n }\n\n nextToken = response.body.nextToken || \"\";\n if (!nextToken) {\n // No more pages available\n return {\n requestId,\n success: false,\n errorMessage: `Cannot reach page ${page}: No more pages available`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: response.body.totalCount || 0,\n };\n }\n currentPage += 1;\n }\n }\n\n // Make the actual request for the desired page\n const request = new ListSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n labels: JSON.stringify(labels),\n maxResults: limit,\n });\n if (nextToken) {\n request.nextToken = nextToken;\n }\n\n // Log API request\n logAPICall(\"ListSession\", {\n labels,\n maxResults: limit,\n nextToken: nextToken || undefined,\n });\n\n const response = await this.client.listSession(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n setRequestId(requestId);\n\n // Check for errors in the response\n if (!response.body?.success) {\n const code = response.body?.code || \"Unknown\";\n const message = response.body?.message || \"Unknown error\";\n logAPIResponseWithDetails(\n \"ListSession\",\n requestId,\n false,\n {},\n `[${code}] ${message}`\n );\n logDebug(\"Full ListSession response:\", JSON.stringify(response.body, null, 2));\n return {\n requestId,\n success: false,\n errorMessage: `[${code}] ${message}`,\n sessionIds: [],\n nextToken: \"\",\n maxResults: limit,\n totalCount: 0,\n };\n }\n\n const sessionIds: string[] = [];\n\n // Extract session data\n if (response.body.data) {\n for (const sessionData of response.body.data) {\n if (sessionData.sessionId) {\n sessionIds.push(sessionData.sessionId);\n }\n }\n }\n\n logAPIResponseWithDetails(\n \"ListSession\",\n requestId,\n true,\n {\n sessionCount: sessionIds.length,\n totalCount: response.body.totalCount || 0,\n maxResults: response.body.maxResults || limit,\n }\n );\n\n // Return SessionListResult with request ID and pagination info\n return {\n requestId,\n success: true,\n sessionIds,\n nextToken: response.body.nextToken || \"\",\n maxResults: response.body.maxResults || limit,\n totalCount: response.body.totalCount || 0,\n };\n } catch (error) {\n logError(\"Error calling list_session:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to list sessions: ${error}`,\n sessionIds: [],\n };\n }\n }\n\n /**\n * Delete a session by session object.\n *\n * @param session - The session to delete.\n * @param syncContext - Whether to sync context data (trigger file uploads) before deleting the session. Defaults to false.\n * @returns DeleteResult indicating success or failure and request ID\n */\n async delete(session: Session, syncContext = false): Promise<DeleteResult> {\n try {\n // Delete the session and get the result\n logAPICall(\"DeleteSession\", { sessionId: session.sessionId });\n const deleteResult = await session.delete(syncContext);\n\n logAPIResponseWithDetails(\n \"DeleteSession\",\n deleteResult.requestId,\n deleteResult.success,\n { sessionId: session.sessionId }\n );\n\n this.sessions.delete(session.sessionId);\n\n // Return the DeleteResult obtained from session.delete()\n return deleteResult;\n } catch (error) {\n logError(\"Error deleting session:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to delete session ${session.sessionId}: ${error}`,\n };\n }\n }\n\n /**\n *\n * @param sessionId - The ID of the session to remove.\n */\n public removeSession(sessionId: string): void {\n this.sessions.delete(sessionId);\n }\n\n /**\n * Get session information by session ID.\n *\n * @param sessionId - The ID of the session to retrieve.\n * @returns GetSessionResult containing session information\n */\n async getSession(sessionId: string): Promise<$GetSessionResult> {\n try {\n logAPICall(\"GetSession\", { sessionId });\n\n const request = new $GetSessionRequest({\n authorization: `Bearer ${this.apiKey}`,\n sessionId: sessionId,\n });\n\n const response = await this.client.getSession(request);\n const requestId = extractRequestId(response) || \"\";\n const body = response.body;\n\n setRequestId(requestId);\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n logAPIResponseWithDetails(\n \"GetSession\",\n requestId,\n false,\n {},\n `[${body.code}] ${body.message || 'Unknown error'}`\n );\n logDebug(\"Full GetSession response:\", JSON.stringify(body, null, 2));\n return {\n requestId,\n httpStatusCode: body.httpStatusCode || 0,\n code: body.code,\n success: false,\n errorMessage: `[${body.code}] ${body.message || 'Unknown error'}`,\n };\n }\n\n const result: $GetSessionResult = {\n requestId,\n httpStatusCode: body?.httpStatusCode || 0,\n code: body?.code || \"\",\n success: body?.success || false,\n errorMessage: \"\",\n };\n\n if (body?.data) {\n result.data = {\n appInstanceId: body.data.appInstanceId || \"\",\n resourceId: body.data.resourceId || \"\",\n sessionId: body.data.sessionId || \"\",\n success: body.data.success || false,\n httpPort: body.data.httpPort || \"\",\n networkInterfaceIp: body.data.networkInterfaceIp || \"\",\n token: body.data.token || \"\",\n vpcResource: body.data.vpcResource || false,\n resourceUrl: body.data.resourceUrl || \"\",\n };\n\n logAPIResponseWithDetails(\n \"GetSession\",\n requestId,\n true,\n {\n sessionId: result.data.sessionId,\n resourceId: result.data.resourceId,\n httpPort: result.data.httpPort,\n }\n );\n }\n\n return result;\n } catch (error) {\n logError(\"Error calling GetSession:\", error);\n return {\n requestId: \"\",\n httpStatusCode: 0,\n code: \"\",\n success: false,\n errorMessage: `Failed to get session ${sessionId}: ${error}`,\n };\n }\n }\n\n /**\n * Get a session by its ID.\n *\n * This method retrieves a session by calling the GetSession API\n * and returns a SessionResult containing the Session object and request ID.\n *\n * @param sessionId - The ID of the session to retrieve\n * @returns Promise resolving to SessionResult with the Session instance, request ID, and success status\n *\n * @example\n * ```typescript\n * const result = await agentBay.get(\"my-session-id\");\n * if (result.success) {\n * console.log(result.session.sessionId);\n * console.log(result.requestId);\n * }\n * ```\n */\n async get(sessionId: string): Promise<SessionResult> {\n // Validate input\n if (\n !sessionId ||\n (typeof sessionId === \"string\" && !sessionId.trim())\n ) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"session_id is required\",\n };\n }\n\n // Call GetSession API\n const getResult = await this.getSession(sessionId);\n\n // Check if the API call was successful\n if (!getResult.success) {\n const errorMsg = getResult.errorMessage || \"Unknown error\";\n return {\n requestId: getResult.requestId,\n success: false,\n errorMessage: `Failed to get session ${sessionId}: ${errorMsg}`,\n };\n }\n\n // Create the Session object\n const session = new Session(this, sessionId);\n\n // Set VPC-related information and ResourceUrl from GetSession response\n if (getResult.data) {\n session.isVpc = getResult.data.vpcResource;\n session.networkInterfaceIp = getResult.data.networkInterfaceIp;\n session.httpPort = getResult.data.httpPort;\n session.token = getResult.data.token;\n session.resourceUrl = getResult.data.resourceUrl;\n }\n\n return {\n requestId: getResult.requestId,\n success: true,\n session,\n };\n }\n\n // For internal use by the Session class\n getClient(): Client {\n return this.client;\n }\n\n getAPIKey(): string {\n return this.apiKey;\n }\n}\n\n/**\n * Creates a new AgentBay client using default configuration.\n * This is a convenience function that allows creating an AgentBay instance without a config parameter.\n *\n * @param apiKey - API key for authentication\n * @returns A new AgentBay instance with default configuration\n */\nexport function newAgentBayWithDefaults(apiKey: string): AgentBay {\n return new AgentBay({ apiKey });\n}\n","(function () {\n require('./lib/main').config(\n Object.assign(\n {},\n require('./lib/env-options'),\n require('./lib/cli-options')(process.argv)\n )\n )\n})()\n","// Export the client and models\nimport { Client } from \"./client\";\nexport { Client } from \"./client\";\nexport * from \"./models/model\";\n\nexport default Client;\n","// This file is auto-generated, don't edit it\nimport * as $dara from \"@darabonba/typescript\";\nimport OpenApi from \"@alicloud/openapi-core\";\nimport { OpenApiUtil, $OpenApiUtil } from \"@alicloud/openapi-core\";\n\nimport * as $_model from \"./models/model\";\nexport * from \"./models/model\";\n\nexport class Client extends OpenApi {\n constructor(config: $OpenApiUtil.Config) {\n super(config);\n this._signatureAlgorithm = \"v2\";\n this._endpointRule = \"\";\n this.checkConfig(config);\n this._endpoint = this.getEndpoint(\n \"wuyingai\",\n this._regionId,\n this._endpointRule,\n this._network,\n this._suffix,\n this._endpointMap,\n this._endpoint\n );\n }\n\n getEndpoint(\n productId: string,\n regionId: string,\n endpointRule: string,\n network: string,\n suffix: string,\n endpointMap: { [key: string]: string },\n endpoint: string\n ): string {\n if (!$dara.isNull(endpoint)) {\n return endpoint;\n }\n\n if (!$dara.isNull(endpointMap) && !$dara.isNull(endpointMap[regionId])) {\n return endpointMap[regionId];\n }\n\n return OpenApiUtil.getEndpointRules(\n productId,\n regionId,\n endpointRule,\n network,\n suffix\n );\n }\n\n /**\n * Call MCP tool\n *\n * @param request - CallMcpToolRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns CallMcpToolResponse\n */\n async callMcpToolWithOptions(\n request: $_model.CallMcpToolRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.CallMcpToolResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.args)) {\n body[\"Args\"] = request.args;\n }\n\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.externalUserId)) {\n body[\"ExternalUserId\"] = request.externalUserId;\n }\n\n if (!$dara.isNull(request.imageId)) {\n body[\"ImageId\"] = request.imageId;\n }\n\n if (!$dara.isNull(request.name)) {\n body[\"Name\"] = request.name;\n }\n\n if (!$dara.isNull(request.server)) {\n body[\"Server\"] = request.server;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n if (!$dara.isNull(request.tool)) {\n body[\"Tool\"] = request.tool;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"CallMcpTool\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.CallMcpToolResponse>(\n await this.callApi(params, req, runtime),\n new $_model.CallMcpToolResponse({})\n );\n }\n\n /**\n * Call MCP tool\n *\n * @param request - CallMcpToolRequest\n * @returns CallMcpToolResponse\n */\n async callMcpTool(\n request: $_model.CallMcpToolRequest\n ): Promise<$_model.CallMcpToolResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.callMcpToolWithOptions(request, runtime);\n }\n\n /**\n * Delete Persistent Context\n * \n * @param request - ClearContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ClearContextResponse\n */\n async clearContextWithOptions(request: $_model.ClearContextRequest, runtime: $dara.RuntimeOptions): Promise<$_model.ClearContextResponse> {\n request.validate();\n const body : {[key: string ]: any} = { };\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.id)) {\n body[\"Id\"] = request.id;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ClearContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ClearContextResponse>(await this.doRPCRequest(params.action, params.version, params.protocol, params.method, params.authType, params.bodyType, req, runtime), new $_model.ClearContextResponse({}));\n }\n\n /**\n * Delete Persistent Context\n * \n * @param request - ClearContextRequest\n * @returns ClearContextResponse\n */\n async clearContext(request: $_model.ClearContextRequest): Promise<$_model.ClearContextResponse> {\n const runtime = new $dara.RuntimeOptions({ });\n return await this.clearContextWithOptions(request, runtime);\n }\n /**\n * Create MCP session\n *\n * @param tmpReq - CreateMcpSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns CreateMcpSessionResponse\n */\n async createMcpSessionWithOptions(\n tmpReq: $_model.CreateMcpSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.CreateMcpSessionResponse> {\n tmpReq.validate();\n const request = new $_model.CreateMcpSessionShrinkRequest({});\n OpenApiUtil.convert(tmpReq, request);\n if (!$dara.isNull(tmpReq.persistenceDataList)) {\n request.persistenceDataListShrink =\n OpenApiUtil.arrayToStringWithSpecifiedStyle(\n tmpReq.persistenceDataList,\n \"PersistenceDataList\",\n \"json\"\n );\n }\n\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.externalUserId)) {\n body[\"ExternalUserId\"] = request.externalUserId;\n }\n\n if (!$dara.isNull(request.imageId)) {\n body[\"ImageId\"] = request.imageId;\n }\n\n if (!$dara.isNull(request.labels)) {\n body[\"Labels\"] = request.labels;\n }\n\n if (!$dara.isNull(request.mcpPolicyId)) {\n body[\"McpPolicyId\"] = request.mcpPolicyId;\n }\n\n if (!$dara.isNull(request.persistenceDataListShrink)) {\n body[\"PersistenceDataList\"] = request.persistenceDataListShrink;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n if (!$dara.isNull(request.vpcResource)) {\n body[\"VpcResource\"] = request.vpcResource;\n }\n\n if (!$dara.isNull(request.extraConfigs)) {\n body[\"ExtraConfigs\"] = request.extraConfigs;\n }\n\n if (!$dara.isNull(request.sdkStats)) {\n body[\"SdkStats\"] = request.sdkStats;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"CreateMcpSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.CreateMcpSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.CreateMcpSessionResponse({})\n );\n }\n\n /**\n * Create MCP session\n *\n * @param request - CreateMcpSessionRequest\n * @returns CreateMcpSessionResponse\n */\n async createMcpSession(\n request: $_model.CreateMcpSessionRequest\n ): Promise<$_model.CreateMcpSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.createMcpSessionWithOptions(request, runtime);\n }\n\n /**\n * Delete persistent context\n *\n * @param request - DeleteContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns DeleteContextResponse\n */\n async deleteContextWithOptions(\n request: $_model.DeleteContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.DeleteContextResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.id)) {\n body[\"Id\"] = request.id;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"DeleteContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.DeleteContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.DeleteContextResponse({})\n );\n }\n\n /**\n * Delete persistent context\n *\n * @param request - DeleteContextRequest\n * @returns DeleteContextResponse\n */\n async deleteContext(\n request: $_model.DeleteContextRequest\n ): Promise<$_model.DeleteContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.deleteContextWithOptions(request, runtime);\n }\n\n /**\n * Get context\n *\n * @param request - GetContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextResponse\n */\n async getContextWithOptions(\n request: $_model.GetContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.allowCreate)) {\n body[\"AllowCreate\"] = request.allowCreate;\n }\n\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.name)) {\n body[\"Name\"] = request.name;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextResponse({})\n );\n }\n\n /**\n * Get context\n *\n * @param request - GetContextRequest\n * @returns GetContextResponse\n */\n async getContext(\n request: $_model.GetContextRequest\n ): Promise<$_model.GetContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextWithOptions(request, runtime);\n }\n\n /**\n * Get context information\n *\n * @param request - GetContextInfoRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextInfoResponse\n */\n async getContextInfoWithOptions(\n request: $_model.GetContextInfoRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextInfoResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.path)) {\n body[\"Path\"] = request.path;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n if (!$dara.isNull(request.taskType)) {\n body[\"TaskType\"] = request.taskType;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContextInfo\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextInfoResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextInfoResponse({})\n );\n }\n\n /**\n * Get context information\n *\n * @param request - GetContextInfoRequest\n * @returns GetContextInfoResponse\n */\n async getContextInfo(\n request: $_model.GetContextInfoRequest\n ): Promise<$_model.GetContextInfoResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextInfoWithOptions(request, runtime);\n }\n\n /**\n * Get labels\n *\n * @param request - GetLabelRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetLabelResponse\n */\n async getLabelWithOptions(\n request: $_model.GetLabelRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetLabelResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.maxResults)) {\n body[\"MaxResults\"] = request.maxResults;\n }\n\n if (!$dara.isNull(request.nextToken)) {\n body[\"NextToken\"] = request.nextToken;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetLabel\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetLabelResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetLabelResponse({})\n );\n }\n\n /**\n * Get labels\n *\n * @param request - GetLabelRequest\n * @returns GetLabelResponse\n */\n async getLabel(\n request: $_model.GetLabelRequest\n ): Promise<$_model.GetLabelResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getLabelWithOptions(request, runtime);\n }\n\n /**\n * Get session information\n *\n * @param request - GetSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetSessionResponse\n */\n async getSessionWithOptions(\n request: $_model.GetSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetSessionResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetSessionResponse({})\n );\n }\n\n /**\n * Get session information\n *\n * @param request - GetSessionRequest\n * @returns GetSessionResponse\n */\n async getSession(\n request: $_model.GetSessionRequest\n ): Promise<$_model.GetSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getSessionWithOptions(request, runtime);\n }\n\n /**\n * Get forwarding link for specific port\n *\n * @param request - GetLinkRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetLinkResponse\n */\n async getLinkWithOptions(\n request: $_model.GetLinkRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetLinkResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.port)) {\n body[\"Port\"] = request.port;\n }\n\n if (!$dara.isNull(request.protocolType)) {\n body[\"ProtocolType\"] = request.protocolType;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n if (!$dara.isNull(request.option)) {\n body[\"Option\"] = request.option;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetLink\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetLinkResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetLinkResponse({})\n );\n }\n\n /**\n * Get forwarding link for specific port\n *\n * @param request - GetLinkRequest\n * @returns GetLinkResponse\n */\n async getLink(\n request: $_model.GetLinkRequest\n ): Promise<$_model.GetLinkResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getLinkWithOptions(request, runtime);\n }\n\n /**\n * Get MCP resource information\n *\n * @param request - GetMcpResourceRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetMcpResourceResponse\n */\n async getMcpResourceWithOptions(\n request: $_model.GetMcpResourceRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetMcpResourceResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetMcpResource\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetMcpResourceResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetMcpResourceResponse({})\n );\n }\n\n /**\n * Get MCP resource information\n *\n * @param request - GetMcpResourceRequest\n * @returns GetMcpResourceResponse\n */\n async getMcpResource(\n request: $_model.GetMcpResourceRequest\n ): Promise<$_model.GetMcpResourceResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getMcpResourceWithOptions(request, runtime);\n }\n\n /**\n * Get context list\n *\n * @param request - ListContextsRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ListContextsResponse\n */\n async listContextsWithOptions(\n request: $_model.ListContextsRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ListContextsResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.maxResults)) {\n body[\"MaxResults\"] = request.maxResults;\n }\n\n if (!$dara.isNull(request.nextToken)) {\n body[\"NextToken\"] = request.nextToken;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ListContexts\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ListContextsResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ListContextsResponse({})\n );\n }\n\n /**\n * Get context list\n *\n * @param request - ListContextsRequest\n * @returns ListContextsResponse\n */\n async listContexts(\n request: $_model.ListContextsRequest\n ): Promise<$_model.ListContextsResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.listContextsWithOptions(request, runtime);\n }\n\n /**\n * ListMcpTools\n *\n * @param request - ListMcpToolsRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ListMcpToolsResponse\n */\n async listMcpToolsWithOptions(\n request: $_model.ListMcpToolsRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ListMcpToolsResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.imageId)) {\n body[\"ImageId\"] = request.imageId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ListMcpTools\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ListMcpToolsResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ListMcpToolsResponse({})\n );\n }\n\n /**\n * ListMcpTools\n *\n * @param request - ListMcpToolsRequest\n * @returns ListMcpToolsResponse\n */\n async listMcpTools(\n request: $_model.ListMcpToolsRequest\n ): Promise<$_model.ListMcpToolsResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.listMcpToolsWithOptions(request, runtime);\n }\n\n /**\n * Query session list by label\n *\n * @param request - ListSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ListSessionResponse\n */\n async listSessionWithOptions(\n request: $_model.ListSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ListSessionResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.labels)) {\n body[\"Labels\"] = request.labels;\n }\n\n if (!$dara.isNull(request.maxResults)) {\n body[\"MaxResults\"] = request.maxResults;\n }\n\n if (!$dara.isNull(request.nextToken)) {\n body[\"NextToken\"] = request.nextToken;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ListSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ListSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ListSessionResponse({})\n );\n }\n\n /**\n * Query session list by label\n *\n * @param request - ListSessionRequest\n * @returns ListSessionResponse\n */\n async listSession(\n request: $_model.ListSessionRequest\n ): Promise<$_model.ListSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.listSessionWithOptions(request, runtime);\n }\n\n /**\n * Modify context\n *\n * @param request - ModifyContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ModifyContextResponse\n */\n async modifyContextWithOptions(\n request: $_model.ModifyContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ModifyContextResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.id)) {\n body[\"Id\"] = request.id;\n }\n\n if (!$dara.isNull(request.name)) {\n body[\"Name\"] = request.name;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ModifyContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ModifyContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ModifyContextResponse({})\n );\n }\n\n /**\n * Modify context\n *\n * @param request - ModifyContextRequest\n * @returns ModifyContextResponse\n */\n async modifyContext(\n request: $_model.ModifyContextRequest\n ): Promise<$_model.ModifyContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.modifyContextWithOptions(request, runtime);\n }\n\n /**\n * Release MCP session\n *\n * @param request - ReleaseMcpSessionRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns ReleaseMcpSessionResponse\n */\n async releaseMcpSessionWithOptions(\n request: $_model.ReleaseMcpSessionRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.ReleaseMcpSessionResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"ReleaseMcpSession\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.ReleaseMcpSessionResponse>(\n await this.callApi(params, req, runtime),\n new $_model.ReleaseMcpSessionResponse({})\n );\n }\n\n /**\n * Release MCP session\n *\n * @param request - ReleaseMcpSessionRequest\n * @returns ReleaseMcpSessionResponse\n */\n async releaseMcpSession(\n request: $_model.ReleaseMcpSessionRequest\n ): Promise<$_model.ReleaseMcpSessionResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.releaseMcpSessionWithOptions(request, runtime);\n }\n\n /**\n * Set labels\n *\n * @param request - SetLabelRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns SetLabelResponse\n */\n async setLabelWithOptions(\n request: $_model.SetLabelRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.SetLabelResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.labels)) {\n body[\"Labels\"] = request.labels;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"SetLabel\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.SetLabelResponse>(\n await this.callApi(params, req, runtime),\n new $_model.SetLabelResponse({})\n );\n }\n\n /**\n * Set labels\n *\n * @param request - SetLabelRequest\n * @returns SetLabelResponse\n */\n async setLabel(\n request: $_model.SetLabelRequest\n ): Promise<$_model.SetLabelResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.setLabelWithOptions(request, runtime);\n }\n\n /**\n * Sync context\n *\n * @param request - SyncContextRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns SyncContextResponse\n */\n async syncContextWithOptions(\n request: $_model.SyncContextRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.SyncContextResponse> {\n request.validate();\n const query: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n query[\"Authorization\"] = request.authorization;\n }\n\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.mode)) {\n body[\"Mode\"] = request.mode;\n }\n\n if (!$dara.isNull(request.path)) {\n body[\"Path\"] = request.path;\n }\n\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n query: OpenApiUtil.query(query),\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"SyncContext\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.SyncContextResponse>(\n await this.callApi(params, req, runtime),\n new $_model.SyncContextResponse({})\n );\n }\n\n /**\n * Sync context\n *\n * @param request - SyncContextRequest\n * @returns SyncContextResponse\n */\n async syncContext(\n request: $_model.SyncContextRequest\n ): Promise<$_model.SyncContextResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.syncContextWithOptions(request, runtime);\n }\n\n /**\n * Initialize browser\n *\n * @param tmpReq - InitBrowserRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns InitBrowserResponse\n */\n async initBrowserWithOptions(\n request: $_model.InitBrowserRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.InitBrowserResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n if (!$dara.isNull(request.persistentPath)) {\n body[\"PersistentPath\"] = request.persistentPath;\n }\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n if (!$dara.isNull(request.browserOption)) {\n body[\"BrowserOption\"] = JSON.stringify(request.browserOption);\n }\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"InitBrowser\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.InitBrowserResponse>(\n await this.callApi(params, req, runtime),\n new $_model.InitBrowserResponse({})\n );\n }\n\n /**\n * Initialize browser\n *\n * @param request - InitBrowserRequest\n * @returns InitBrowserResponse\n */\n async initBrowser(\n request: $_model.InitBrowserRequest\n ): Promise<$_model.InitBrowserResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.initBrowserWithOptions(request, runtime);\n }\n\n /**\n * Initialize browser (sync version)\n *\n * @param request - InitBrowserRequest\n * @returns InitBrowserResponse\n */\n initBrowserSync(\n request: $_model.InitBrowserRequest\n ): $_model.InitBrowserResponse {\n const runtime = new $dara.RuntimeOptions({});\n \n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n if (!$dara.isNull(request.persistentPath)) {\n body[\"PersistentPath\"] = request.persistentPath;\n }\n if (!$dara.isNull(request.sessionId)) {\n body[\"SessionId\"] = request.sessionId;\n }\n if (!$dara.isNull(request.browserOption)) {\n body[\"BrowserOption\"] = JSON.stringify(request.browserOption);\n }\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"InitBrowser\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.InitBrowserResponse>(\n this.callApi(params, req, runtime),\n new $_model.InitBrowserResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - DeleteContextFileRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns DeleteContextFileResponse\n */\n async deleteContextFileWithOptions(\n request: $_model.DeleteContextFileRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.DeleteContextFileResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.filePath)) {\n body[\"FilePath\"] = request.filePath;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"DeleteContextFile\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.DeleteContextFileResponse>(\n await this.callApi(params, req, runtime),\n new $_model.DeleteContextFileResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - DeleteContextFileRequest\n * @returns DeleteContextFileResponse\n */\n async deleteContextFile(\n request: $_model.DeleteContextFileRequest\n ): Promise<$_model.DeleteContextFileResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.deleteContextFileWithOptions(request, runtime);\n }\n\n /**\n * Query context specific directory files\n *\n * @param request - DescribeContextFilesRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns DescribeContextFilesResponse\n */\n async describeContextFilesWithOptions(\n request: $_model.DescribeContextFilesRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.DescribeContextFilesResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.pageNumber)) {\n body[\"PageNumber\"] = request.pageNumber;\n }\n\n if (!$dara.isNull(request.pageSize)) {\n body[\"PageSize\"] = request.pageSize;\n }\n\n if (!$dara.isNull(request.parentFolderPath)) {\n body[\"ParentFolderPath\"] = request.parentFolderPath;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"DescribeContextFiles\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.DescribeContextFilesResponse>(\n await this.callApi(params, req, runtime),\n new $_model.DescribeContextFilesResponse({})\n );\n }\n\n /**\n * Query context specific directory files\n *\n * @param request - DescribeContextFilesRequest\n * @returns DescribeContextFilesResponse\n */\n async describeContextFiles(\n request: $_model.DescribeContextFilesRequest\n ): Promise<$_model.DescribeContextFilesResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.describeContextFilesWithOptions(request, runtime);\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileDownloadUrlRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextFileDownloadUrlResponse\n */\n async getContextFileDownloadUrlWithOptions(\n request: $_model.GetContextFileDownloadUrlRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextFileDownloadUrlResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.filePath)) {\n body[\"FilePath\"] = request.filePath;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContextFileDownloadUrl\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextFileDownloadUrlResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextFileDownloadUrlResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileDownloadUrlRequest\n * @returns GetContextFileDownloadUrlResponse\n */\n async getContextFileDownloadUrl(\n request: $_model.GetContextFileDownloadUrlRequest\n ): Promise<$_model.GetContextFileDownloadUrlResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextFileDownloadUrlWithOptions(request, runtime);\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileUploadUrlRequest\n * @param runtime - runtime options for this request RuntimeOptions\n * @returns GetContextFileUploadUrlResponse\n */\n async getContextFileUploadUrlWithOptions(\n request: $_model.GetContextFileUploadUrlRequest,\n runtime: $dara.RuntimeOptions\n ): Promise<$_model.GetContextFileUploadUrlResponse> {\n request.validate();\n const body: { [key: string]: any } = {};\n if (!$dara.isNull(request.authorization)) {\n body[\"Authorization\"] = request.authorization;\n }\n\n if (!$dara.isNull(request.contextId)) {\n body[\"ContextId\"] = request.contextId;\n }\n\n if (!$dara.isNull(request.filePath)) {\n body[\"FilePath\"] = request.filePath;\n }\n\n const req = new $OpenApiUtil.OpenApiRequest({\n body: OpenApiUtil.parseToMap(body),\n });\n const params = new $OpenApiUtil.Params({\n action: \"GetContextFileUploadUrl\",\n version: \"2025-05-06\",\n protocol: \"HTTPS\",\n pathname: \"/\",\n method: \"POST\",\n authType: \"Anonymous\",\n style: \"RPC\",\n reqBodyType: \"formData\",\n bodyType: \"json\",\n });\n return $dara.cast<$_model.GetContextFileUploadUrlResponse>(\n await this.callApi(params, req, runtime),\n new $_model.GetContextFileUploadUrlResponse({})\n );\n }\n\n /**\n * Get context file upload URL\n *\n * @param request - GetContextFileUploadUrlRequest\n * @returns GetContextFileUploadUrlResponse\n */\n async getContextFileUploadUrl(\n request: $_model.GetContextFileUploadUrlRequest\n ): Promise<$_model.GetContextFileUploadUrlResponse> {\n const runtime = new $dara.RuntimeOptions({});\n return await this.getContextFileUploadUrlWithOptions(request, runtime);\n }\n}\n","export { ApplyMqttTokenResponseBodyData } from './ApplyMqttTokenResponseBodyData';\nexport { CreateMcpSessionRequestPersistenceDataList } from './CreateMcpSessionRequestPersistenceDataList';\nexport { CreateMcpSessionResponseBodyData } from './CreateMcpSessionResponseBodyData';\nexport { GetContextResponseBodyData } from './GetContextResponseBodyData';\nexport { GetContextInfoResponseBodyData } from './GetContextInfoResponseBodyData';\nexport { GetLabelResponseBodyData } from './GetLabelResponseBodyData';\nexport { GetSessionResponseBodyData } from './GetSessionResponseBodyData';\nexport { GetLinkResponseBodyData } from './GetLinkResponseBodyData';\nexport { GetMcpResourceResponseBodyDataDesktopInfo } from './GetMcpResourceResponseBodyDataDesktopInfo';\nexport { GetMcpResourceResponseBodyData } from './GetMcpResourceResponseBodyData';\nexport { ListContextsResponseBodyData } from './ListContextsResponseBodyData';\nexport { ListSessionResponseBodyData } from './ListSessionResponseBodyData';\nexport { ApplyMqttTokenRequest } from './ApplyMqttTokenRequest';\nexport { ApplyMqttTokenResponseBody } from './ApplyMqttTokenResponseBody';\nexport { ApplyMqttTokenResponse } from './ApplyMqttTokenResponse';\nexport { CallMcpToolRequest } from './CallMcpToolRequest';\nexport { CallMcpToolResponseBody } from './CallMcpToolResponseBody';\nexport { CallMcpToolResponse } from './CallMcpToolResponse';\nexport { ClearContextRequest } from './ClearContextRequest';\nexport { ClearContextResponseBody } from './ClearContextResponseBody';\nexport { ClearContextResponse } from './ClearContextResponse';\nexport { CreateMcpSessionRequest } from './CreateMcpSessionRequest';\nexport { CreateMcpSessionShrinkRequest } from './CreateMcpSessionShrinkRequest';\nexport { CreateMcpSessionResponseBody } from './CreateMcpSessionResponseBody';\nexport { CreateMcpSessionResponse } from './CreateMcpSessionResponse';\nexport { DeleteContextRequest } from './DeleteContextRequest';\nexport { DeleteContextResponseBody } from './DeleteContextResponseBody';\nexport { DeleteContextResponse } from './DeleteContextResponse';\nexport { GetContextRequest } from './GetContextRequest';\nexport { GetContextResponseBody } from './GetContextResponseBody';\nexport { GetContextResponse } from './GetContextResponse';\nexport { GetContextInfoRequest } from './GetContextInfoRequest';\nexport { GetContextInfoResponseBody } from './GetContextInfoResponseBody';\nexport { GetContextInfoResponse } from './GetContextInfoResponse';\nexport { GetLabelRequest } from './GetLabelRequest';\nexport { GetLabelResponseBody } from './GetLabelResponseBody';\nexport { GetLabelResponse } from './GetLabelResponse';\nexport { GetSessionRequest } from './GetSessionRequest';\nexport { GetSessionResponseBody } from './GetSessionResponseBody';\nexport { GetSessionResponse } from './GetSessionResponse';\nexport { GetLinkRequest } from './GetLinkRequest';\nexport { GetLinkResponseBody } from './GetLinkResponseBody';\nexport { GetLinkResponse } from './GetLinkResponse';\nexport { GetMcpResourceRequest } from './GetMcpResourceRequest';\nexport { GetMcpResourceResponseBody } from './GetMcpResourceResponseBody';\nexport { GetMcpResourceResponse } from './GetMcpResourceResponse';\nexport { InitBrowserRequest } from './InitBrowserRequest';\nexport { InitBrowserResponseBody } from './InitBrowserResponseBody';\nexport { InitBrowserResponseBodyData } from './InitBrowserResponseBodyData';\nexport { InitBrowserResponse } from './InitBrowserResponse';\nexport { ListContextsRequest } from './ListContextsRequest';\nexport { ListContextsResponseBody } from './ListContextsResponseBody';\nexport { ListContextsResponse } from './ListContextsResponse';\nexport { ListMcpToolsRequest } from './ListMcpToolsRequest';\nexport { ListMcpToolsResponseBody } from './ListMcpToolsResponseBody';\nexport { ListMcpToolsResponse } from './ListMcpToolsResponse';\nexport { ListSessionRequest } from './ListSessionRequest';\nexport { ListSessionResponseBody } from './ListSessionResponseBody';\nexport { ListSessionResponse } from './ListSessionResponse';\nexport { ModifyContextRequest } from './ModifyContextRequest';\nexport { ModifyContextResponseBody } from './ModifyContextResponseBody';\nexport { ModifyContextResponse } from './ModifyContextResponse';\nexport { ReleaseMcpSessionRequest } from './ReleaseMcpSessionRequest';\nexport { ReleaseMcpSessionResponseBody } from './ReleaseMcpSessionResponseBody';\nexport { ReleaseMcpSessionResponse } from './ReleaseMcpSessionResponse';\nexport { SetLabelRequest } from './SetLabelRequest';\nexport { SetLabelResponseBody } from './SetLabelResponseBody';\nexport { SetLabelResponse } from './SetLabelResponse';\nexport { SyncContextRequest } from './SyncContextRequest';\nexport { SyncContextResponseBody } from './SyncContextResponseBody';\nexport { SyncContextResponse } from './SyncContextResponse';\n// New context file operations\nexport { DeleteContextFileRequest } from './DeleteContextFileRequest';\nexport { DeleteContextFileResponseBody } from './DeleteContextFileResponseBody';\nexport { DeleteContextFileResponse } from './DeleteContextFileResponse';\nexport { DescribeContextFilesRequest } from './DescribeContextFilesRequest';\nexport { DescribeContextFilesResponseBody } from './DescribeContextFilesResponseBody';\nexport { DescribeContextFilesResponse } from './DescribeContextFilesResponse';\nexport { GetContextFileDownloadUrlRequest } from './GetContextFileDownloadUrlRequest';\nexport { GetContextFileDownloadUrlResponseBody } from './GetContextFileDownloadUrlResponseBody';\nexport { GetContextFileDownloadUrlResponse } from './GetContextFileDownloadUrlResponse';\nexport { GetContextFileUploadUrlRequest } from './GetContextFileUploadUrlRequest';\nexport { GetContextFileUploadUrlResponseBody } from './GetContextFileUploadUrlResponseBody';\nexport { GetContextFileUploadUrlResponse } from './GetContextFileUploadUrlResponse';\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\n/**\n */\nexport class ApplyMqttTokenResponseBodyData extends $dara.Model {\n accessKeyId?: string;\n clientId?: string;\n expiration?: string;\n instanceId?: string;\n regionId?: string;\n securityToken?: string;\n static names(): { [key: string]: string } {\n return {\n accessKeyId: 'AccessKeyId',\n clientId: 'ClientId',\n expiration: 'Expiration',\n instanceId: 'InstanceId',\n regionId: 'RegionId',\n securityToken: 'SecurityToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n accessKeyId: 'string',\n clientId: 'string',\n expiration: 'string',\n instanceId: 'string',\n regionId: 'string',\n securityToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CreateMcpSessionRequestPersistenceDataList extends $dara.Model {\n contextId?: string;\n path?: string;\n policy?: string;\n static names(): { [key: string]: string } {\n return {\n contextId: 'ContextId',\n path: 'Path',\n policy: 'Policy',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n contextId: 'string',\n path: 'string',\n policy: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CreateMcpSessionResponseBodyData extends $dara.Model {\n appInstanceId?: string;\n errMsg?: string;\n httpPort?: string;\n networkInterfaceIp?: string;\n resourceId?: string;\n resourceUrl?: string;\n sessionId?: string;\n success?: boolean;\n token?: string;\n vpcResource?: boolean;\n static names(): { [key: string]: string } {\n return {\n appInstanceId: 'AppInstanceId',\n errMsg: 'ErrMsg',\n httpPort: 'HttpPort',\n networkInterfaceIp: 'NetworkInterfaceIp',\n resourceId: 'ResourceId',\n resourceUrl: 'ResourceUrl',\n sessionId: 'SessionId',\n success: 'Success',\n token: 'Token',\n vpcResource: 'VpcResource',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n appInstanceId: 'string',\n errMsg: 'string',\n httpPort: 'string',\n networkInterfaceIp: 'string',\n resourceId: 'string',\n resourceUrl: 'string',\n sessionId: 'string',\n success: 'boolean',\n token: 'string',\n vpcResource: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextResponseBodyData extends $dara.Model {\n createTime?: string;\n id?: string;\n lastUsedTime?: string;\n name?: string;\n osType?: string;\n state?: string;\n static names(): { [key: string]: string } {\n return {\n createTime: 'CreateTime',\n id: 'Id',\n lastUsedTime: 'LastUsedTime',\n name: 'Name',\n osType: 'OsType',\n state: 'State',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n createTime: 'string',\n id: 'string',\n lastUsedTime: 'string',\n name: 'string',\n osType: 'string',\n state: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextInfoResponseBodyData extends $dara.Model {\n contextStatus?: string;\n static names(): { [key: string]: string } {\n return {\n contextStatus: 'ContextStatus',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n contextStatus: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLabelResponseBodyData extends $dara.Model {\n labels?: string;\n static names(): { [key: string]: string } {\n return {\n labels: 'Labels',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n labels: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetSessionResponseBodyData extends $dara.Model {\n appInstanceId?: string;\n resourceId?: string;\n sessionId?: string;\n success?: boolean;\n httpPort?: string;\n networkInterfaceIp?: string;\n token?: string;\n vpcResource?: boolean;\n resourceUrl?: string;\n static names(): { [key: string]: string } {\n return {\n appInstanceId: 'AppInstanceId',\n resourceId: 'ResourceId',\n sessionId: 'SessionId',\n success: 'Success',\n httpPort: 'HttpPort',\n networkInterfaceIp: 'NetworkInterfaceIp',\n token: 'Token',\n vpcResource: 'VpcResource',\n resourceUrl: 'ResourceUrl',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n appInstanceId: 'string',\n resourceId: 'string',\n sessionId: 'string',\n success: 'boolean',\n httpPort: 'string',\n networkInterfaceIp: 'string',\n token: 'string',\n vpcResource: 'boolean',\n resourceUrl: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLinkResponseBodyData extends $dara.Model {\n url?: string;\n static names(): { [key: string]: string } {\n return {\n url: 'Url',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n url: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetMcpResourceResponseBodyDataDesktopInfo extends $dara.Model {\n appId?: string;\n authCode?: string;\n connectionProperties?: string;\n resourceId?: string;\n resourceType?: string;\n ticket?: string;\n static names(): { [key: string]: string } {\n return {\n appId: 'AppId',\n authCode: 'AuthCode',\n connectionProperties: 'ConnectionProperties',\n resourceId: 'ResourceId',\n resourceType: 'ResourceType',\n ticket: 'Ticket',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n appId: 'string',\n authCode: 'string',\n connectionProperties: 'string',\n resourceId: 'string',\n resourceType: 'string',\n ticket: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetMcpResourceResponseBodyDataDesktopInfo } from \"./GetMcpResourceResponseBodyDataDesktopInfo\";\n\n\nexport class GetMcpResourceResponseBodyData extends $dara.Model {\n desktopInfo?: GetMcpResourceResponseBodyDataDesktopInfo;\n resourceUrl?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n desktopInfo: 'DesktopInfo',\n resourceUrl: 'ResourceUrl',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n desktopInfo: GetMcpResourceResponseBodyDataDesktopInfo,\n resourceUrl: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n if(this.desktopInfo && typeof (this.desktopInfo as any).validate === 'function') {\n (this.desktopInfo as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListContextsResponseBodyData extends $dara.Model {\n createTime?: string;\n id?: string;\n lastUsedTime?: string;\n name?: string;\n osType?: string;\n state?: string;\n static names(): { [key: string]: string } {\n return {\n createTime: 'CreateTime',\n id: 'Id',\n lastUsedTime: 'LastUsedTime',\n name: 'Name',\n osType: 'OsType',\n state: 'State',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n createTime: 'string',\n id: 'string',\n lastUsedTime: 'string',\n name: 'string',\n osType: 'string',\n state: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListSessionResponseBodyData extends $dara.Model {\n sessionId?: string;\n sessionStatus?: string;\n static names(): { [key: string]: string } {\n return {\n sessionId: 'SessionId',\n sessionStatus: 'SessionStatus',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n sessionId: 'string',\n sessionStatus: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ApplyMqttTokenRequest extends $dara.Model {\n desktopId?: string;\n sessionToken?: string;\n static names(): { [key: string]: string } {\n return {\n desktopId: 'DesktopId',\n sessionToken: 'SessionToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n desktopId: 'string',\n sessionToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ApplyMqttTokenResponseBodyData } from \"./ApplyMqttTokenResponseBodyData\";\n\n\nexport class ApplyMqttTokenResponseBody extends $dara.Model {\n code?: string;\n data?: ApplyMqttTokenResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: ApplyMqttTokenResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ApplyMqttTokenResponseBody } from \"./ApplyMqttTokenResponseBody\";\n\n\nexport class ApplyMqttTokenResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ApplyMqttTokenResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ApplyMqttTokenResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CallMcpToolRequest extends $dara.Model {\n args?: string;\n authorization?: string;\n externalUserId?: string;\n imageId?: string;\n name?: string;\n server?: string;\n sessionId?: string;\n tool?: string;\n static names(): { [key: string]: string } {\n return {\n args: 'Args',\n authorization: 'Authorization',\n externalUserId: 'ExternalUserId',\n imageId: 'ImageId',\n name: 'Name',\n server: 'Server',\n sessionId: 'SessionId',\n tool: 'Tool',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n args: 'string',\n authorization: 'string',\n externalUserId: 'string',\n imageId: 'string',\n name: 'string',\n server: 'string',\n sessionId: 'string',\n tool: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CallMcpToolResponseBody extends $dara.Model {\n code?: string;\n data?: any;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: 'any',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CallMcpToolResponseBody } from \"./CallMcpToolResponseBody\";\n\n\nexport class CallMcpToolResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: CallMcpToolResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: CallMcpToolResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ClearContextRequest extends $dara.Model {\n authorization?: string;\n id?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n id: 'Id',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n id: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ClearContextResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ClearContextResponseBody } from \"./ClearContextResponseBody\";\n\n\nexport class ClearContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ClearContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ClearContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CreateMcpSessionRequestPersistenceDataList } from \"./CreateMcpSessionRequestPersistenceDataList\";\n\n\nexport class CreateMcpSessionRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n externalUserId?: string;\n imageId?: string;\n labels?: string;\n mcpPolicyId?: string;\n persistenceDataList?: CreateMcpSessionRequestPersistenceDataList[];\n sessionId?: string;\n vpcResource?: boolean;\n extraConfigs?: string;\n sdkStats?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n externalUserId: 'ExternalUserId',\n imageId: 'ImageId',\n labels: 'Labels',\n mcpPolicyId: 'McpPolicyId',\n persistenceDataList: 'PersistenceDataList',\n sessionId: 'SessionId',\n vpcResource: 'VpcResource',\n extraConfigs: 'ExtraConfigs',\n sdkStats: 'SdkStats',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n externalUserId: 'string',\n imageId: 'string',\n labels: 'string',\n mcpPolicyId: 'string',\n persistenceDataList: { 'type': 'array', 'itemType': CreateMcpSessionRequestPersistenceDataList },\n sessionId: 'string',\n vpcResource: 'boolean',\n extraConfigs: 'string',\n sdkStats: 'string',\n };\n }\n\n validate() {\n if(Array.isArray(this.persistenceDataList)) {\n $dara.Model.validateArray(this.persistenceDataList);\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class CreateMcpSessionShrinkRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n externalUserId?: string;\n imageId?: string;\n labels?: string;\n mcpPolicyId?: string;\n persistenceDataListShrink?: string;\n sessionId?: string;\n vpcResource?: boolean;\n extraConfigs?: string;\n sdkStats?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n externalUserId: 'ExternalUserId',\n imageId: 'ImageId',\n labels: 'Labels',\n mcpPolicyId: 'McpPolicyId',\n persistenceDataListShrink: 'PersistenceDataList',\n sessionId: 'SessionId',\n vpcResource: 'VpcResource',\n extraConfigs: 'ExtraConfigs',\n sdkStats: 'SdkStats',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n externalUserId: 'string',\n imageId: 'string',\n labels: 'string',\n mcpPolicyId: 'string',\n persistenceDataListShrink: 'string',\n sessionId: 'string',\n vpcResource: 'boolean',\n extraConfigs: 'string',\n sdkStats: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CreateMcpSessionResponseBodyData } from \"./CreateMcpSessionResponseBodyData\";\n\n\nexport class CreateMcpSessionResponseBody extends $dara.Model {\n code?: string;\n data?: CreateMcpSessionResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: CreateMcpSessionResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { CreateMcpSessionResponseBody } from \"./CreateMcpSessionResponseBody\";\n\n\nexport class CreateMcpSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: CreateMcpSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: CreateMcpSessionResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class DeleteContextRequest extends $dara.Model {\n authorization?: string;\n id?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n id: 'Id',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n id: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class DeleteContextResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { DeleteContextResponseBody } from \"./DeleteContextResponseBody\";\n\n\nexport class DeleteContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: DeleteContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: DeleteContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextRequest extends $dara.Model {\n allowCreate?: boolean;\n authorization?: string;\n contextId?: string;\n name?: string;\n static names(): { [key: string]: string } {\n return {\n allowCreate: 'AllowCreate',\n authorization: 'Authorization',\n contextId: 'ContextId',\n name: 'Name',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n allowCreate: 'boolean',\n authorization: 'string',\n contextId: 'string',\n name: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextResponseBodyData } from \"./GetContextResponseBodyData\";\n\n\nexport class GetContextResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextResponseBody } from \"./GetContextResponseBody\";\n\n\nexport class GetContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetContextInfoRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n path?: string;\n sessionId?: string;\n taskType?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n path: 'Path',\n sessionId: 'SessionId',\n taskType: 'TaskType',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n path: 'string',\n sessionId: 'string',\n taskType: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextInfoResponseBodyData } from \"./GetContextInfoResponseBodyData\";\n\n\nexport class GetContextInfoResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextInfoResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextInfoResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextInfoResponseBody } from \"./GetContextInfoResponseBody\";\n\n\nexport class GetContextInfoResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextInfoResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetContextInfoResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLabelRequest extends $dara.Model {\n authorization?: string;\n maxResults?: number;\n nextToken?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n maxResults: 'MaxResults',\n nextToken: 'NextToken',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n maxResults: 'number',\n nextToken: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLabelResponseBodyData } from \"./GetLabelResponseBodyData\";\n\n\nexport class GetLabelResponseBody extends $dara.Model {\n code?: string;\n data?: GetLabelResponseBodyData;\n httpStatusCode?: number;\n maxResults?: number;\n message?: string;\n nextToken?: string;\n requestId?: string;\n success?: boolean;\n totalCount?: number;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n maxResults: 'MaxResults',\n message: 'Message',\n nextToken: 'NextToken',\n requestId: 'RequestId',\n success: 'Success',\n totalCount: 'TotalCount',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetLabelResponseBodyData,\n httpStatusCode: 'number',\n maxResults: 'number',\n message: 'string',\n nextToken: 'string',\n requestId: 'string',\n success: 'boolean',\n totalCount: 'number',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLabelResponseBody } from \"./GetLabelResponseBody\";\n\n\nexport class GetLabelResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetLabelResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetLabelResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetSessionRequest extends $dara.Model {\n authorization?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetSessionResponseBodyData } from \"./GetSessionResponseBodyData\";\n\n\nexport class GetSessionResponseBody extends $dara.Model {\n code?: string;\n data?: GetSessionResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetSessionResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetSessionResponseBody } from \"./GetSessionResponseBody\";\n\n\nexport class GetSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetSessionResponseBody,\n };\n }\n\n validate() {\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetLinkRequest extends $dara.Model {\n authorization?: string;\n port?: number;\n protocolType?: string;\n sessionId?: string;\n option?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n port: 'Port',\n protocolType: 'ProtocolType',\n sessionId: 'SessionId',\n option: 'Option',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n port: 'number',\n protocolType: 'string',\n sessionId: 'string',\n option: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLinkResponseBodyData } from \"./GetLinkResponseBodyData\";\n\n\nexport class GetLinkResponseBody extends $dara.Model {\n code?: string;\n data?: GetLinkResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetLinkResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetLinkResponseBody } from \"./GetLinkResponseBody\";\n\n\nexport class GetLinkResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetLinkResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetLinkResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class GetMcpResourceRequest extends $dara.Model {\n authorization?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetMcpResourceResponseBodyData } from \"./GetMcpResourceResponseBodyData\";\n\n\nexport class GetMcpResourceResponseBody extends $dara.Model {\n code?: string;\n data?: GetMcpResourceResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetMcpResourceResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetMcpResourceResponseBody } from \"./GetMcpResourceResponseBody\";\n\n\nexport class GetMcpResourceResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetMcpResourceResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: GetMcpResourceResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class InitBrowserRequest extends $dara.Model {\n authorization?: string;\n persistentPath?: string;\n sessionId?: string;\n browserOption?: { [key: string]: any };\n \n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n persistentPath: 'PersistentPath',\n sessionId: 'SessionId',\n browserOption: 'BrowserOption',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n persistentPath: 'string',\n sessionId: 'string',\n browserOption: { 'type': 'map', 'keyType': 'string', 'valueType': 'any' },\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserRequest {\n return $dara.cast<InitBrowserRequest>(m, new InitBrowserRequest());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { InitBrowserResponseBodyData } from './InitBrowserResponseBodyData';\n\nexport class InitBrowserResponseBody extends $dara.Model {\n code?: string;\n data?: InitBrowserResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n \n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: InitBrowserResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n if(this.data && typeof (this.data as any).validate === 'function') {\n (this.data as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserResponseBody {\n return $dara.cast<InitBrowserResponseBody>(m, new InitBrowserResponseBody());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class InitBrowserResponseBodyData extends $dara.Model {\n port?: number;\n \n static names(): { [key: string]: string } {\n return {\n port: 'Port',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n port: 'number',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserResponseBodyData {\n return $dara.cast<InitBrowserResponseBodyData>(m, new InitBrowserResponseBodyData());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { InitBrowserResponseBody } from './InitBrowserResponseBody';\n\nexport class InitBrowserResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: InitBrowserResponseBody;\n \n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: InitBrowserResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n\n static fromMap(m: { [key: string]: any }): InitBrowserResponse {\n return $dara.cast<InitBrowserResponse>(m, new InitBrowserResponse());\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListContextsRequest extends $dara.Model {\n authorization?: string;\n maxResults?: number;\n nextToken?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n maxResults: 'MaxResults',\n nextToken: 'NextToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n maxResults: 'number',\n nextToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListContextsResponseBodyData } from \"./ListContextsResponseBodyData\";\n\n\nexport class ListContextsResponseBody extends $dara.Model {\n code?: string;\n data?: ListContextsResponseBodyData[];\n httpStatusCode?: number;\n maxResults?: number;\n message?: string;\n nextToken?: string;\n requestId?: string;\n success?: boolean;\n totalCount?: number;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n maxResults: 'MaxResults',\n message: 'Message',\n nextToken: 'NextToken',\n requestId: 'RequestId',\n success: 'Success',\n totalCount: 'TotalCount',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: { 'type': 'array', 'itemType': ListContextsResponseBodyData },\n httpStatusCode: 'number',\n maxResults: 'number',\n message: 'string',\n nextToken: 'string',\n requestId: 'string',\n success: 'boolean',\n totalCount: 'number',\n };\n }\n\n validate() {\n if(Array.isArray(this.data)) {\n $dara.Model.validateArray(this.data);\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListContextsResponseBody } from \"./ListContextsResponseBody\";\n\n\nexport class ListContextsResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ListContextsResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ListContextsResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListMcpToolsRequest extends $dara.Model {\n authorization?: string;\n imageId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n imageId: 'ImageId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n imageId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListMcpToolsResponseBody extends $dara.Model {\n code?: string;\n data?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListMcpToolsResponseBody } from \"./ListMcpToolsResponseBody\";\n\n\nexport class ListMcpToolsResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ListMcpToolsResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ListMcpToolsResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ListSessionRequest extends $dara.Model {\n authorization?: string;\n labels?: string;\n maxResults?: number;\n nextToken?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n labels: 'Labels',\n maxResults: 'MaxResults',\n nextToken: 'NextToken',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n labels: 'string',\n maxResults: 'number',\n nextToken: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListSessionResponseBodyData } from \"./ListSessionResponseBodyData\";\n\n\nexport class ListSessionResponseBody extends $dara.Model {\n code?: string;\n data?: ListSessionResponseBodyData[];\n httpStatusCode?: number;\n maxResults?: number;\n message?: string;\n nextToken?: string;\n requestId?: string;\n success?: boolean;\n totalCount?: number;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n maxResults: 'MaxResults',\n message: 'Message',\n nextToken: 'NextToken',\n requestId: 'RequestId',\n success: 'Success',\n totalCount: 'TotalCount',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: { 'type': 'array', 'itemType': ListSessionResponseBodyData },\n httpStatusCode: 'number',\n maxResults: 'number',\n message: 'string',\n nextToken: 'string',\n requestId: 'string',\n success: 'boolean',\n totalCount: 'number',\n };\n }\n\n validate() {\n if(Array.isArray(this.data)) {\n $dara.Model.validateArray(this.data);\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ListSessionResponseBody } from \"./ListSessionResponseBody\";\n\n\nexport class ListSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ListSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ListSessionResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ModifyContextRequest extends $dara.Model {\n authorization?: string;\n id?: string;\n name?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n id: 'Id',\n name: 'Name',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n id: 'string',\n name: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ModifyContextResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ModifyContextResponseBody } from \"./ModifyContextResponseBody\";\n\n\nexport class ModifyContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ModifyContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ModifyContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ReleaseMcpSessionRequest extends $dara.Model {\n authorization?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class ReleaseMcpSessionResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { ReleaseMcpSessionResponseBody } from \"./ReleaseMcpSessionResponseBody\";\n\n\nexport class ReleaseMcpSessionResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: ReleaseMcpSessionResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: ReleaseMcpSessionResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SetLabelRequest extends $dara.Model {\n authorization?: string;\n labels?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n labels: 'Labels',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n labels: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SetLabelResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { SetLabelResponseBody } from \"./SetLabelResponseBody\";\n\n\nexport class SetLabelResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: SetLabelResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: SetLabelResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SyncContextRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n mode?: string;\n path?: string;\n sessionId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n mode: 'Mode',\n path: 'Path',\n sessionId: 'SessionId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n mode: 'string',\n path: 'string',\n sessionId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\n\nexport class SyncContextResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { SyncContextResponseBody } from \"./SyncContextResponseBody\";\n\n\nexport class SyncContextResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: SyncContextResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { 'type': 'map', 'keyType': 'string', 'valueType': 'string' },\n statusCode: 'number',\n body: SyncContextResponseBody,\n };\n }\n\n validate() {\n if(this.headers) {\n $dara.Model.validateMap(this.headers);\n }\n if(this.body && typeof (this.body as any).validate === 'function') {\n (this.body as any).validate();\n }\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\n","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DeleteContextFileRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n filePath?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n filePath: 'FilePath',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n filePath: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DeleteContextFileResponseBody extends $dara.Model {\n code?: string;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { DeleteContextFileResponseBody } from './DeleteContextFileResponseBody';\n\nexport class DeleteContextFileResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: DeleteContextFileResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: DeleteContextFileResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DescribeContextFilesRequest extends $dara.Model {\n authorization?: string;\n pageNumber?: number;\n pageSize?: number;\n parentFolderPath?: string;\n contextId?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n pageNumber: 'PageNumber',\n pageSize: 'PageSize',\n parentFolderPath: 'ParentFolderPath',\n contextId: 'ContextId',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n pageNumber: 'number',\n pageSize: 'number',\n parentFolderPath: 'string',\n contextId: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class DescribeContextFilesResponseBodyData extends $dara.Model {\n fileId?: string;\n fileName?: string;\n filePath?: string;\n fileType?: string;\n gmtCreate?: string;\n gmtModified?: string;\n size?: number;\n status?: string;\n static names(): { [key: string]: string } {\n return {\n fileId: 'FileId',\n fileName: 'FileName',\n filePath: 'FilePath',\n fileType: 'FileType',\n gmtCreate: 'GmtCreate',\n gmtModified: 'GmtModified',\n size: 'Size',\n status: 'Status',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n fileId: 'string',\n fileName: 'string',\n filePath: 'string',\n fileType: 'string',\n gmtCreate: 'string',\n gmtModified: 'string',\n size: 'number',\n status: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\nexport class DescribeContextFilesResponseBody extends $dara.Model {\n code?: string;\n count?: number;\n data?: DescribeContextFilesResponseBodyData[];\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n count: 'Count',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n count: 'number',\n data: { type: 'array', itemType: DescribeContextFilesResponseBodyData },\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { DescribeContextFilesResponseBody } from './DescribeContextFilesResponseBody';\n\nexport class DescribeContextFilesResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: DescribeContextFilesResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: DescribeContextFilesResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileDownloadUrlRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n filePath?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n filePath: 'FilePath',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n filePath: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileDownloadUrlResponseBodyData extends $dara.Model {\n expireTime?: number;\n url?: string;\n static names(): { [key: string]: string } {\n return {\n expireTime: 'ExpireTime',\n url: 'Url',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n expireTime: 'number',\n url: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\nexport class GetContextFileDownloadUrlResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextFileDownloadUrlResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextFileDownloadUrlResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextFileDownloadUrlResponseBody } from './GetContextFileDownloadUrlResponseBody';\n\nexport class GetContextFileDownloadUrlResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextFileDownloadUrlResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: GetContextFileDownloadUrlResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileUploadUrlRequest extends $dara.Model {\n authorization?: string;\n contextId?: string;\n filePath?: string;\n static names(): { [key: string]: string } {\n return {\n authorization: 'Authorization',\n contextId: 'ContextId',\n filePath: 'FilePath',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n authorization: 'string',\n contextId: 'string',\n filePath: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\n\nexport class GetContextFileUploadUrlResponseBodyData extends $dara.Model {\n expireTime?: number;\n url?: string;\n static names(): { [key: string]: string } {\n return {\n expireTime: 'ExpireTime',\n url: 'Url',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n expireTime: 'number',\n url: 'string',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n}\n\nexport class GetContextFileUploadUrlResponseBody extends $dara.Model {\n code?: string;\n data?: GetContextFileUploadUrlResponseBodyData;\n httpStatusCode?: number;\n message?: string;\n requestId?: string;\n success?: boolean;\n static names(): { [key: string]: string } {\n return {\n code: 'Code',\n data: 'Data',\n httpStatusCode: 'HttpStatusCode',\n message: 'Message',\n requestId: 'RequestId',\n success: 'Success',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n code: 'string',\n data: GetContextFileUploadUrlResponseBodyData,\n httpStatusCode: 'number',\n message: 'string',\n requestId: 'string',\n success: 'boolean',\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","// This file is auto-generated, don't edit it\nimport * as $dara from '@darabonba/typescript';\nimport { GetContextFileUploadUrlResponseBody } from './GetContextFileUploadUrlResponseBody';\n\nexport class GetContextFileUploadUrlResponse extends $dara.Model {\n headers?: { [key: string]: string };\n statusCode?: number;\n body?: GetContextFileUploadUrlResponseBody;\n static names(): { [key: string]: string } {\n return {\n headers: 'headers',\n statusCode: 'statusCode',\n body: 'body',\n };\n }\n\n static types(): { [key: string]: any } {\n return {\n headers: { type: 'map', keyType: 'string', valueType: 'string' },\n statusCode: 'number',\n body: GetContextFileUploadUrlResponseBody,\n };\n }\n\n validate() {\n super.validate();\n }\n\n constructor(map?: { [key: string]: any }) {\n super(map);\n }\n} ","import { AgentBay } from \"./agent-bay\";\nimport { APIError } from \"./exceptions\";\nimport * as $_client from \"./api\";\nimport {\n log,\n logError,\n logInfo,\n logDebug,\n logAPICall,\n logAPIResponseWithDetails,\n setRequestId,\n getRequestId,\n} from \"./utils/logger\";\nimport {\n extractRequestId,\n ContextResult,\n ContextListResult,\n OperationResult,\n FileUrlResult,\n ContextFileListResult,\n ContextFileEntry,\n ClearContextResult,\n} from \"./types/api-response\";\n\n/**\n * Represents a persistent storage context in the AgentBay cloud environment.\n */\nexport class Context {\n /**\n * The unique identifier of the context.\n */\n id: string;\n\n /**\n * The name of the context.\n */\n name: string;\n\n /**\n * @deprecated This field is no longer used and will be removed in a future version.\n */\n state: string;\n\n /**\n * Date and time when the Context was created.\n */\n createdAt?: string;\n\n /**\n * Date and time when the Context was last used.\n */\n lastUsedAt?: string;\n\n /**\n * @deprecated This field is no longer used and will be removed in a future version.\n */\n osType?: string;\n\n /**\n * Initialize a Context object.\n *\n * @param id - The unique identifier of the context.\n * @param name - The name of the context.\n * @param state - **Deprecated.** This parameter is no longer used.\n * @param createdAt - Date and time when the Context was created.\n * @param lastUsedAt - Date and time when the Context was last used.\n * @param osType - **Deprecated.** This parameter is no longer used.\n */\n constructor(\n id: string,\n name: string,\n state = \"available\",\n createdAt?: string,\n lastUsedAt?: string,\n osType?: string\n ) {\n this.id = id;\n this.name = name;\n this.state = state;\n this.createdAt = createdAt;\n this.lastUsedAt = lastUsedAt;\n this.osType = osType;\n }\n}\n\n/**\n * Parameters for listing contexts with pagination support.\n */\nexport interface ContextListParams {\n /**\n * Maximum number of results per page.\n * Defaults to 10 if not specified.\n */\n maxResults?: number;\n\n /**\n * Token for the next page of results.\n */\n nextToken?: string;\n}\n\n/**\n * Provides methods to manage persistent contexts in the AgentBay cloud environment.\n */\nexport class ContextService {\n private agentBay: AgentBay;\n\n /**\n * Initialize the ContextService.\n *\n * @param agentBay - The AgentBay instance.\n */\n constructor(agentBay: AgentBay) {\n this.agentBay = agentBay;\n }\n\n /**\n * Lists all available contexts with pagination support.\n * Corresponds to Python's list() method\n *\n * @param params - Optional parameters for listing contexts.\n * @returns ContextListResult with contexts list and pagination information\n */\n async list(params?: ContextListParams): Promise<ContextListResult> {\n try {\n // Set default maxResults if not specified\n const maxResults = params?.maxResults !== undefined ? params.maxResults : 10;\n\n const request = new $_client.ListContextsRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n maxResults: maxResults,\n nextToken: params?.nextToken,\n });\n\n // Log API request\n logAPICall(\"ListContexts\");\n logDebug(`Request: MaxResults=${maxResults}`, params?.nextToken ? `, NextToken=${params.nextToken}` : \"\");\n\n const response = await this.agentBay.getClient().listContexts(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for API-level errors\n if (response.body?.success === false && response.body?.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"ListContexts\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n contexts: [],\n errorMessage,\n };\n }\n\n const contexts: Context[] = [];\n if (response.body?.data) {\n for (const contextData of response.body.data) {\n contexts.push(\n new Context(\n contextData.id || \"\",\n contextData.name || \"\",\n contextData.state || \"available\",\n contextData.createTime,\n contextData.lastUsedTime,\n contextData.osType\n )\n );\n }\n }\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_count: contexts.length,\n max_results: maxResults,\n };\n if (response.body?.totalCount !== undefined) {\n keyFields.total_count = response.body.totalCount;\n }\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"ListContexts\", requestId, true, keyFields, fullResponse);\n\n return {\n requestId,\n success: true,\n contexts,\n nextToken: response.body?.nextToken,\n maxResults: response.body?.maxResults || maxResults,\n totalCount: response.body?.totalCount,\n };\n } catch (error) {\n logError(\"Error calling ListContexts:\", error);\n return {\n requestId: \"\",\n success: false,\n contexts: [],\n errorMessage: `Failed to list contexts: ${error}`,\n };\n }\n }\n\n /**\n * Gets a context by name. Optionally creates it if it doesn't exist.\n * Corresponds to Python's get() method\n *\n * @param name - The name of the context to get.\n * @param create - Whether to create the context if it doesn't exist.\n * @returns ContextResult with context data and requestId\n */\n async get(name: string, create = false): Promise<ContextResult> {\n try {\n const request = new $_client.GetContextRequest({\n name: name,\n allowCreate: create ? \"true\" : \"false\",\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n });\n\n // Log API request\n logAPICall(\"GetContext\");\n logDebug(`Request: Name=${name}, AllowCreate=${create}`);\n\n const response = await this.agentBay.getClient().getContext(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for API-level errors\n if (response.body?.success === false && response.body?.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContext\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n contextId: \"\",\n context: undefined,\n errorMessage,\n };\n }\n\n const contextId = response.body?.data?.id || \"\";\n if (!contextId) {\n logAPIResponseWithDetails(\"GetContext\", requestId, false, undefined, \"Context ID not found in response\");\n return {\n requestId,\n success: false,\n contextId: \"\",\n context: undefined,\n errorMessage: \"Context ID not found in response\",\n };\n }\n\n // Get the full context details\n try {\n const contextsResponse = await this.list();\n for (const context of contextsResponse.contexts) {\n if (context.id === contextId) {\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_id: contextId,\n context_name: context.name,\n };\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContext\", requestId, true, keyFields, fullResponse);\n return {\n requestId,\n success: true,\n contextId,\n context,\n };\n }\n }\n } catch (listError) {\n logDebug(`Warning: Failed to get full context details from list: ${listError}`);\n }\n\n // If we couldn't find the context in the list, create a basic one\n const context = new Context(contextId, name);\n const keyFields: Record<string, any> = {\n context_id: contextId,\n context_name: name,\n };\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContext\", requestId, true, keyFields, fullResponse);\n return {\n requestId,\n success: true,\n contextId,\n context,\n };\n } catch (error) {\n logError(\"Error calling GetContext:\", error);\n return {\n requestId: \"\",\n success: false,\n contextId: \"\",\n context: undefined,\n errorMessage: `Failed to get context ${name}: ${error}`,\n };\n }\n }\n\n /**\n * Creates a new context with the given name.\n * Corresponds to Python's create() method\n *\n * @param name - The name for the new context.\n * @returns ContextResult with created context data and requestId\n */\n async create(name: string): Promise<ContextResult> {\n return await this.get(name, true);\n }\n\n /**\n * Updates the specified context.\n * Corresponds to Python's update() method\n *\n * @param context - The Context object to update.\n * @returns OperationResult with updated context data and requestId\n */\n async update(context: Context): Promise<OperationResult> {\n try {\n const request = new $_client.ModifyContextRequest({\n id: context.id,\n name: context.name,\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n });\n\n // Log API request\n logAPICall(\"ModifyContext\");\n logDebug(`Request: Id=${context.id}, Name=${context.name}`);\n\n const response = await this.agentBay.getClient().modifyContext(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for success (matching Python logic)\n const success = response.body?.success !== false;\n const errorMessage = success\n ? \"\"\n : `[${response.body?.code || 'Unknown'}] ${response.body?.message || 'Unknown error'}`;\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_id: context.id,\n context_name: context.name,\n };\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"ModifyContext\", requestId, success, keyFields, fullResponse);\n\n return {\n requestId,\n success,\n data: success,\n errorMessage,\n };\n } catch (error) {\n logError(\"Error calling ModifyContext:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to update context ${context.id}: ${error}`,\n };\n }\n }\n\n /**\n * Deletes the specified context.\n * Corresponds to Python's delete() method\n *\n * @param context - The Context object to delete.\n * @returns OperationResult with requestId\n */\n async delete(context: Context): Promise<OperationResult> {\n try {\n const request = new $_client.DeleteContextRequest({\n id: context.id,\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n });\n\n // Log API request\n logAPICall(\"DeleteContext\");\n logDebug(`Request: Id=${context.id}`);\n\n const response = await this.agentBay.getClient().deleteContext(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for success (matching Python logic)\n const success = response.body?.success !== false;\n const errorMessage = success\n ? \"\"\n : `[${response.body?.code || 'Unknown'}] ${response.body?.message || 'Unknown error'}`;\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_id: context.id,\n };\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"DeleteContext\", requestId, success, keyFields, fullResponse);\n\n return {\n requestId,\n success,\n data: success,\n errorMessage,\n };\n } catch (error) {\n logError(\"Error calling DeleteContext:\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to delete context ${context.id}: ${error}`,\n };\n }\n }\n\n /**\n * Get a presigned upload URL for a file in a context.\n */\n async getFileUploadUrl(contextId: string, filePath: string): Promise<FileUrlResult> {\n logAPICall(\"GetContextFileUploadUrl\");\n logDebug(`Request: ContextId=${contextId}, FilePath=${filePath}`);\n const req = new $_client.GetContextFileUploadUrlRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n contextId,\n filePath,\n });\n const resp = await this.agentBay.getClient().getContextFileUploadUrl(req);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n const errorMessage = `[${body.code}] ${body.message || 'Unknown error'}`;\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContextFileUploadUrl\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n url: \"\",\n expireTime: undefined,\n errorMessage,\n };\n }\n\n const data = body?.data;\n const success = !!(body && body.success);\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_id: contextId,\n file_path: filePath,\n };\n if (data?.expireTime) {\n keyFields.expire_time = data.expireTime;\n }\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContextFileUploadUrl\", requestId, success, keyFields, fullResponse);\n\n return {\n requestId,\n success,\n url: data?.url || \"\",\n expireTime: data?.expireTime,\n errorMessage: undefined,\n };\n }\n\n /**\n * Get a presigned download URL for a file in a context.\n */\n async getFileDownloadUrl(contextId: string, filePath: string): Promise<FileUrlResult> {\n logAPICall(\"GetContextFileDownloadUrl\");\n logDebug(`Request: ContextId=${contextId}, FilePath=${filePath}`);\n const req = new $_client.GetContextFileDownloadUrlRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n contextId,\n filePath,\n });\n const resp = await this.agentBay.getClient().getContextFileDownloadUrl(req);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n const errorMessage = `[${body.code}] ${body.message || 'Unknown error'}`;\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContextFileDownloadUrl\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n url: \"\",\n expireTime: undefined,\n errorMessage,\n };\n }\n\n const data = body?.data;\n const success = !!(body && body.success);\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_id: contextId,\n file_path: filePath,\n };\n if (data?.expireTime) {\n keyFields.expire_time = data.expireTime;\n }\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContextFileDownloadUrl\", requestId, success, keyFields, fullResponse);\n\n return {\n requestId,\n success,\n url: data?.url || \"\",\n expireTime: data?.expireTime,\n errorMessage: undefined,\n };\n }\n\n /**\n * Delete a file in a context.\n */\n async deleteFile(contextId: string, filePath: string): Promise<OperationResult> {\n logAPICall(\"DeleteContextFile\");\n logDebug(`Request: ContextId=${contextId}, FilePath=${filePath}`);\n const req = new $_client.DeleteContextFileRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n contextId,\n filePath,\n });\n const resp = await this.agentBay.getClient().deleteContextFile(req);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n const success = !!(body && body.success);\n\n // Check for API-level errors\n const errorMessage = success\n ? \"\"\n : `[${body?.code || 'Unknown'}] ${body?.message || 'Failed to delete file'}`;\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_id: contextId,\n file_path: filePath,\n };\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"DeleteContextFile\", requestId, success, keyFields, fullResponse);\n\n return {\n requestId,\n success,\n data: success,\n errorMessage,\n };\n }\n\n /**\n * List files under a specific folder path in a context.\n */\n async listFiles(\n contextId: string,\n parentFolderPath: string,\n pageNumber = 1,\n pageSize = 50\n ): Promise<ContextFileListResult> {\n logAPICall(\"DescribeContextFiles\");\n logDebug(\n `Request: ContextId=${contextId}, ParentFolderPath=${parentFolderPath}, PageNumber=${pageNumber}, PageSize=${pageSize}`\n );\n const req = new $_client.DescribeContextFilesRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n pageNumber,\n pageSize,\n parentFolderPath,\n contextId,\n });\n const resp = await this.agentBay.getClient().describeContextFiles(req);\n const requestId = extractRequestId(resp) || \"\";\n const body = resp.body;\n\n // Check for API-level errors\n if (body?.success === false && body.code) {\n const errorMessage = `[${body.code}] ${body.message || 'Unknown error'}`;\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"DescribeContextFiles\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n entries: [],\n count: undefined,\n errorMessage,\n };\n }\n\n const rawList = body?.data || [];\n const entries: ContextFileEntry[] = rawList.map((it: any) => ({\n fileId: it.fileId,\n fileName: it.fileName,\n filePath: it.filePath || \"\",\n fileType: it.fileType,\n gmtCreate: it.gmtCreate,\n gmtModified: it.gmtModified,\n size: it.size,\n status: it.status,\n }));\n\n const success = !!(body && body.success);\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n context_id: contextId,\n parent_folder_path: parentFolderPath,\n file_count: entries.length,\n page_number: pageNumber,\n page_size: pageSize,\n };\n if (body?.count !== undefined) {\n keyFields.count = body.count;\n }\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"DescribeContextFiles\", requestId, success, keyFields, fullResponse);\n\n return {\n requestId,\n success,\n entries,\n count: body?.count,\n errorMessage: undefined,\n };\n }\n\n /**\n * Asynchronously initiate a task to clear the context's persistent data.\n *\n * This is a non-blocking method that returns immediately after initiating the clearing task\n * on the backend. The context's state will transition to \"clearing\" while the operation\n * is in progress.\n *\n * @param contextId - Unique ID of the context to clear.\n * @returns A ClearContextResult object indicating the task has been successfully started,\n * with status field set to \"clearing\".\n * @throws APIError - If the backend API rejects the clearing request (e.g., invalid ID).\n */\n async clearAsync(contextId: string): Promise<ClearContextResult> {\n try {\n logAPICall(\"ClearContext\");\n logDebug(`Request: ContextId=${contextId}`);\n\n const request = new $_client.ClearContextRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n id: contextId,\n });\n\n const response = await this.agentBay.getClient().clearContext(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Directly access response body object\n if (!response.body) {\n const fullResponse = \"Empty response body\";\n logAPIResponseWithDetails(\"ClearContext\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n errorMessage: \"Empty response body\",\n };\n }\n\n const body = response.body;\n\n // Check for API-level errors\n if (!body.success && body.code) {\n const errorMessage = `[${body.code}] ${body.message || 'Unknown error'}`;\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"ClearContext\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n // ClearContext API returns success info without Data field\n // Initial status is \"clearing\" when the task starts\n const keyFields: Record<string, any> = {\n context_id: contextId,\n status: \"clearing\",\n };\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"ClearContext\", requestId, true, keyFields, fullResponse);\n\n return {\n requestId,\n success: true,\n contextId,\n status: \"clearing\",\n errorMessage: \"\",\n };\n } catch (error) {\n logError(\"Error calling ClearContext:\", error);\n throw new APIError(`Failed to start context clearing for ${contextId}: ${error}`);\n }\n }\n\n /**\n * Queries the status of the clearing task.\n *\n * This method calls GetContext API directly and parses the raw response to extract\n * the state field, which indicates the current clearing status.\n *\n * @param contextId - ID of the context.\n * @returns ClearContextResult object containing the current task status.\n */\n async getClearStatus(contextId: string): Promise<ClearContextResult> {\n try {\n logAPICall(\"GetContext\");\n logDebug(`Request: ContextId=${contextId} (for clear status)`);\n\n const request = new $_client.GetContextRequest({\n authorization: `Bearer ${this.agentBay.getAPIKey()}`,\n contextId: contextId,\n allowCreate: \"false\",\n });\n\n const response = await this.agentBay.getClient().getContext(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Directly access response body object\n if (!response.body) {\n const fullResponse = \"Empty response body\";\n logAPIResponseWithDetails(\"GetContext (for clear status)\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n errorMessage: \"Empty response body\",\n };\n }\n\n const body = response.body;\n\n // Check for API-level errors\n if (!body.success && body.code) {\n const errorMessage = `[${body.code}] ${body.message || 'Unknown error'}`;\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContext (for clear status)\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n // Check if data exists\n if (!body.data) {\n const fullResponse = \"No data in response\";\n logAPIResponseWithDetails(\"GetContext (for clear status)\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n errorMessage: \"No data in response\",\n };\n }\n\n const data = body.data;\n\n // Extract clearing status from the response data object\n // The server's state field indicates the clearing status:\n // - \"clearing\": Clearing is in progress\n // - \"available\": Clearing completed successfully\n // - \"in-use\": Context is being used\n // - \"pre-available\": Context is being prepared\n const contextIdFromResponse = data.id || \"\";\n const state = data.state || \"clearing\"; // Extract state from response object\n const errorMessage = \"\"; // ErrorMessage is not in GetContextResponseBodyData\n\n const keyFields: Record<string, any> = {\n context_id: contextIdFromResponse,\n state: state,\n };\n const fullResponse = body ? JSON.stringify(body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContext (for clear status)\", requestId, true, keyFields, fullResponse);\n\n return {\n requestId,\n success: true,\n contextId: contextIdFromResponse,\n status: state,\n errorMessage,\n };\n } catch (error) {\n logError(\"Error calling GetContext (for clear status):\", error);\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to get clear status: ${error}`,\n };\n }\n }\n\n /**\n * Synchronously clear the context's persistent data and wait for the final result.\n *\n * This method wraps the `clearAsync` and `getClearStatus` polling logic,\n * providing the simplest and most direct way to handle clearing tasks.\n *\n * The clearing process transitions through the following states:\n * - \"clearing\": Data clearing is in progress\n * - \"available\": Clearing completed successfully (final success state)\n *\n * @param contextId - Unique ID of the context to clear.\n * @param timeout - (Optional) Timeout in seconds to wait for task completion, default is 60 seconds.\n * @param pollInterval - (Optional) Interval in seconds between status polls, default is 2 seconds.\n * @returns A ClearContextResult object containing the final task result.\n * The status field will be \"available\" on success, or other states if interrupted.\n * @throws APIError - If the task fails to complete within the specified timeout.\n */\n async clear(contextId: string, timeout = 60, pollInterval = 2.0): Promise<ClearContextResult> {\n // 1. Asynchronously start the clearing task\n const startResult = await this.clearAsync(contextId);\n if (!startResult.success) {\n return startResult;\n }\n\n logInfo(`Started context clearing task for: ${contextId}`);\n\n // 2. Poll task status until completion or timeout\n const startTime = Date.now();\n const maxAttempts = Math.floor(timeout / pollInterval);\n let attempt = 0;\n\n while (attempt < maxAttempts) {\n // Wait before querying\n await new Promise(resolve => setTimeout(resolve, pollInterval * 1000));\n attempt++;\n\n // Query task status (using GetContext API with context ID)\n const statusResult = await this.getClearStatus(contextId);\n\n if (!statusResult.success) {\n logError(`Failed to get clear status: ${statusResult.errorMessage}`);\n return statusResult;\n }\n\n const status = statusResult.status;\n logInfo(`Clear task status: ${status} (attempt ${attempt}/${maxAttempts})`);\n\n // Check if completed\n // When clearing is complete, the state changes from \"clearing\" to \"available\"\n if (status === \"available\") {\n const elapsed = (Date.now() - startTime) / 1000;\n logInfo(`Context cleared successfully in ${elapsed.toFixed(2)} seconds`);\n return {\n requestId: statusResult.requestId,\n success: true,\n contextId: statusResult.contextId,\n status,\n errorMessage: \"\",\n };\n } else if (status && ![\"clearing\", \"pre-available\"].includes(status)) {\n // If status is not \"clearing\" or \"pre-available\", and not \"available\",\n // treat it as a potential error or unexpected state\n const elapsed = (Date.now() - startTime) / 1000;\n logError(`Context in unexpected state after ${elapsed.toFixed(2)} seconds: ${status}`);\n // Continue polling as the state might transition to \"available\"\n }\n }\n\n // Timeout\n const elapsed = (Date.now() - startTime) / 1000;\n const errorMsg = `Context clearing timed out after ${elapsed.toFixed(2)} seconds`;\n logError(errorMsg);\n throw new APIError(errorMsg);\n }\n}\n","/**\n * Base exception for all AgentBay SDK errors.\n */\nexport class AgentBayError extends Error {\n extra: Record<string, any>;\n\n constructor(message?: string, extra: Record<string, any> = {}) {\n const errorMessage = message || \"AgentBayError\";\n super(errorMessage);\n this.name = \"AgentBayError\";\n this.extra = extra;\n Object.setPrototypeOf(this, AgentBayError.prototype);\n }\n}\n\n/**\n * Raised when there is an authentication error.\n */\nexport class AuthenticationError extends AgentBayError {\n constructor(\n message = \"Authentication failed\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"AuthenticationError\";\n Object.setPrototypeOf(this, AuthenticationError.prototype);\n }\n}\n\n/**\n * Raised when there is an error with the API.\n */\nexport class APIError extends AgentBayError {\n statusCode?: number;\n\n constructor(\n message = \"API error\",\n statusCode?: number,\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"APIError\";\n this.statusCode = statusCode;\n Object.setPrototypeOf(this, APIError.prototype);\n }\n}\n\n/**\n * Raised for errors related to file operations.\n */\nexport class FileError extends AgentBayError {\n constructor(\n message = \"File operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"FileError\";\n Object.setPrototypeOf(this, FileError.prototype);\n }\n}\n\n/**\n * Raised for errors related to command execution.\n */\nexport class CommandError extends AgentBayError {\n constructor(\n message = \"Command execution error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"CommandError\";\n Object.setPrototypeOf(this, CommandError.prototype);\n }\n}\n\n/**\n * Raised for errors related to session operations.\n */\nexport class SessionError extends AgentBayError {\n constructor(message = \"Session error\", extra: Record<string, any> = {}) {\n super(message, extra);\n this.name = \"SessionError\";\n Object.setPrototypeOf(this, SessionError.prototype);\n }\n}\n\n/**\n * Raised for errors related to OSS operations.\n */\nexport class OssError extends AgentBayError {\n constructor(\n message = \"OSS operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"OssError\";\n Object.setPrototypeOf(this, OssError.prototype);\n }\n}\n\n/**\n * Raised for errors related to application operations.\n */\nexport class ApplicationError extends AgentBayError {\n constructor(\n message = \"Application operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"ApplicationError\";\n Object.setPrototypeOf(this, ApplicationError.prototype);\n }\n}\n\n/**\n * Raised for errors related to UI operations.\n */\nexport class UIError extends AgentBayError {\n constructor(message = \"UI operation error\", extra: Record<string, any> = {}) {\n super(message, extra);\n this.name = \"UIError\";\n Object.setPrototypeOf(this, UIError.prototype);\n }\n}\n\n/**\n * Raised for errors related to browser operations.\n */\nexport class BrowserError extends AgentBayError {\n constructor(\n message = \"Browser operation error\",\n extra: Record<string, any> = {}\n ) {\n super(message, extra);\n this.name = \"BrowserError\";\n Object.setPrototypeOf(this, BrowserError.prototype);\n }\n}\n","/**\n * Utility functions for structured logging with multiple levels, API tracking,\n * sensitive data masking, and RequestID management.\n */\n\nimport * as fs from 'fs';\nimport * as path from 'path';\n\n/**\n * Log level type\n */\nexport type LogLevel = 'DEBUG' | 'INFO' | 'WARN' | 'ERROR';\n\n/**\n * Logger configuration options\n */\nexport interface LoggerConfig {\n level?: LogLevel;\n logFile?: string;\n maxFileSize?: string;\n enableConsole?: boolean;\n}\n\n/**\n * Log level numeric values for comparison\n */\nconst LOG_LEVEL_VALUES: Record<LogLevel, number> = {\n DEBUG: 0,\n INFO: 1,\n WARN: 2,\n ERROR: 3,\n};\n\n/**\n * RequestID storage for tracking across API calls\n */\nlet currentRequestId = '';\n\n/**\n * Current log level configuration\n * Supports both LOG_LEVEL and AGENTBAY_LOG_LEVEL environment variables\n */\nlet currentLogLevel: LogLevel = (\n (process.env.LOG_LEVEL as LogLevel) ||\n (process.env.AGENTBAY_LOG_LEVEL as LogLevel) ||\n 'INFO'\n);\n\n/**\n * File logging configuration\n */\nlet fileLoggingEnabled = false;\nlet logFilePath: string | null = null;\nlet logFileMaxSize = 10 * 1024 * 1024; // 10MB default\nlet consoleLoggingEnabled = true;\n\n/**\n * Determine whether to use colors in output\n * Priority: DISABLE_COLORS > FORCE_COLOR > TTY > IDE > default\n */\nfunction shouldUseColors(): boolean {\n // Priority 1: Explicit disable via DISABLE_COLORS\n if (process.env.DISABLE_COLORS === 'true') {\n return false;\n }\n\n // Priority 2: Explicit enable via FORCE_COLOR\n if (process.env.FORCE_COLOR !== undefined && process.env.FORCE_COLOR !== '0') {\n return true;\n }\n\n // Priority 3: TTY detection (terminal output)\n const isTTY = process.stdout?.isTTY || process.stderr?.isTTY;\n if (isTTY) {\n return true;\n }\n\n // Priority 4: IDE environment detection\n const isVSCode = process.env.TERM_PROGRAM === 'vscode';\n const isGoLand = process.env.GOLAND !== undefined;\n const isIntelliJ = process.env.IDEA_INITIAL_DIRECTORY !== undefined;\n if (isVSCode || isGoLand || isIntelliJ) {\n return true;\n }\n\n // Default: no colors (safe for file output, CI/CD, pipes)\n return false;\n}\n\n/**\n * ANSI color codes\n */\nconst ANSI_RESET = '\\x1b[0m';\nconst ANSI_BLUE = '\\x1b[34m';\nconst ANSI_CYAN = '\\x1b[36m';\nconst ANSI_YELLOW = '\\x1b[33m';\nconst ANSI_RED = '\\x1b[31m';\nconst ANSI_GREEN = '\\x1b[32m';\n\n/**\n * Determine if colors should be used (evaluated once at startup)\n */\nconst useColors = shouldUseColors();\n\n/**\n * Sensitive field names for data masking\n */\nconst SENSITIVE_FIELDS = [\n 'api_key', 'apikey', 'api-key',\n 'password', 'passwd', 'pwd',\n 'token', 'access_token', 'auth_token',\n 'secret', 'private_key', 'authorization',\n];\n\n/**\n * Get emoji for log level\n */\nfunction getLogLevelEmoji(level: LogLevel): string {\n switch (level) {\n case 'DEBUG':\n return '🐛 DEBUG';\n case 'INFO':\n return 'ℹ️ INFO';\n case 'WARN':\n return '⚠️ WARN';\n case 'ERROR':\n return '❌ ERROR';\n default:\n return level;\n }\n}\n\n/**\n * Check if a message should be logged based on current log level\n */\nfunction shouldLog(level: LogLevel): boolean {\n return LOG_LEVEL_VALUES[level] >= LOG_LEVEL_VALUES[currentLogLevel];\n}\n\n/**\n * Format log message with level and RequestID\n */\nfunction formatLogMessage(level: LogLevel, message: string, forFile = false): string {\n let formattedMessage = `${getLogLevelEmoji(level)}: ${message}`;\n if (currentRequestId) {\n formattedMessage += ` [RequestId=${currentRequestId}]`;\n }\n\n if (forFile || !useColors) {\n return formattedMessage;\n }\n\n // Apply colors based on log level\n const color = getColorForLevel(level);\n return `${color}${formattedMessage}${ANSI_RESET}`;\n}\n\n/**\n * Get color code for log level\n */\nfunction getColorForLevel(level: LogLevel): string {\n switch (level) {\n case 'DEBUG':\n return ANSI_CYAN;\n case 'INFO':\n return ANSI_BLUE;\n case 'WARN':\n return ANSI_YELLOW;\n case 'ERROR':\n return ANSI_RED;\n default:\n return '';\n }\n}\n\n/**\n * Mask sensitive information in data structures\n * @param data Data to mask (dict, str, list, etc.)\n * @param fields Additional sensitive field names\n * @returns Masked data (deep copy)\n */\nexport function maskSensitiveData(data: any, fields?: string[]): any {\n const sensitiveFields = fields || SENSITIVE_FIELDS;\n const visitedObjects = new WeakSet();\n\n function mask(obj: any): any {\n if (obj === null || obj === undefined) {\n return obj;\n }\n\n if (typeof obj === 'object') {\n if (visitedObjects.has(obj)) {\n return '[Circular]';\n }\n visitedObjects.add(obj);\n\n if (Array.isArray(obj)) {\n return obj.map(item => mask(item));\n }\n\n const masked: any = {};\n for (const key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n const value = obj[key];\n if (sensitiveFields.some(field => key.toLowerCase().includes(field.toLowerCase()))) {\n if (typeof value === 'string' && value.length > 4) {\n masked[key] = value.substring(0, 2) + '****' + value.substring(value.length - 2);\n } else {\n masked[key] = '****';\n }\n } else {\n masked[key] = mask(value);\n }\n }\n }\n return masked;\n }\n\n if (typeof obj === 'string') {\n return obj;\n }\n\n return obj;\n }\n\n return mask(data);\n}\n\n/**\n * Set the log level\n * @param level The log level to set\n */\nexport function setLogLevel(level: LogLevel): void {\n if (LOG_LEVEL_VALUES[level] !== undefined) {\n currentLogLevel = level;\n }\n}\n\n/**\n * Get the current log level\n * @returns The current log level\n */\nexport function getLogLevel(): LogLevel {\n return currentLogLevel;\n}\n\n/**\n * Set the RequestID for tracking\n * @param requestId The RequestID to set\n */\nexport function setRequestId(requestId: string): void {\n currentRequestId = requestId;\n}\n\n/**\n * Get the current RequestID\n * @returns The current RequestID or empty string\n */\nexport function getRequestId(): string {\n return currentRequestId;\n}\n\n/**\n * Clear the current RequestID\n */\nexport function clearRequestId(): void {\n currentRequestId = '';\n}\n\n/**\n * Parse file size string to bytes (e.g., \"10 MB\" -> 10485760)\n * @param sizeStr Size string like \"10 MB\", \"100 MB\", \"1 GB\"\n * @returns Size in bytes\n */\nfunction parseFileSize(sizeStr: string): number {\n const match = sizeStr.match(/^(\\d+)\\s*(MB|GB|KB)?$/i);\n if (!match) {\n return 10 * 1024 * 1024; // Default 10MB\n }\n\n const value = parseInt(match[1], 10);\n const unit = (match[2] || 'MB').toUpperCase();\n\n switch (unit) {\n case 'KB':\n return value * 1024;\n case 'MB':\n return value * 1024 * 1024;\n case 'GB':\n return value * 1024 * 1024 * 1024;\n default:\n return value * 1024 * 1024;\n }\n}\n\n/**\n * Write log message to file\n * @param message The formatted log message\n */\nfunction writeToFile(message: string): void {\n if (!fileLoggingEnabled || !logFilePath) {\n return;\n }\n\n try {\n // Check file size and rotate if necessary\n if (fs.existsSync(logFilePath)) {\n const stats = fs.statSync(logFilePath);\n if (stats.size >= logFileMaxSize) {\n // Rotate: rename current file to .log.1\n const rotatedPath = `${logFilePath}.1`;\n if (fs.existsSync(rotatedPath)) {\n fs.unlinkSync(rotatedPath);\n }\n fs.renameSync(logFilePath, rotatedPath);\n }\n }\n\n // Append to file (create if doesn't exist)\n fs.appendFileSync(logFilePath, message + '\\n', 'utf8');\n } catch (error) {\n // Silently fail to avoid infinite loop\n if (consoleLoggingEnabled) {\n process.stderr.write(`Failed to write to log file: ${error}\\n`);\n }\n }\n}\n\n/**\n * Setup logger configuration\n * @param config Logger configuration options\n */\nexport function setupLogger(config: LoggerConfig): void {\n if (config.level) {\n setLogLevel(config.level);\n }\n\n if (config.logFile !== undefined) {\n if (config.logFile) {\n logFilePath = config.logFile;\n fileLoggingEnabled = true;\n\n // Ensure directory exists\n const dir = path.dirname(logFilePath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n // Parse max file size\n if (config.maxFileSize) {\n logFileMaxSize = parseFileSize(config.maxFileSize);\n }\n } else {\n fileLoggingEnabled = false;\n logFilePath = null;\n }\n }\n\n if (config.enableConsole !== undefined) {\n consoleLoggingEnabled = config.enableConsole;\n }\n}\n\n/**\n * Log a message without the log prefix and file location\n * Treated as INFO level - will be filtered if log level is WARN or higher\n * @param message The message to log\n * @param args Optional arguments to log\n */\nexport function log(message: string, ...args: any[]): void {\n if (!shouldLog('INFO')) return;\n\n if (consoleLoggingEnabled) {\n process.stdout.write(message + \"\\n\");\n }\n\n // Write to file without colors\n writeToFile(message);\n\n if (args.length > 0) {\n for (const arg of args) {\n const argStr = typeof arg === \"object\" && arg !== null\n ? JSON.stringify(arg, null, 2)\n : String(arg);\n\n if (consoleLoggingEnabled) {\n process.stdout.write(argStr + \"\\n\");\n }\n writeToFile(argStr);\n }\n }\n}\n\n/**\n * Log a debug level message\n * @param message The message to log\n * @param args Optional arguments to log\n */\nexport function logDebug(message: string, ...args: any[]): void {\n if (!shouldLog('DEBUG')) return;\n\n const formattedMessage = formatLogMessage('DEBUG', message);\n const fileMessage = formatLogMessage('DEBUG', message, true);\n\n if (consoleLoggingEnabled) {\n process.stdout.write(formattedMessage + \"\\n\");\n }\n writeToFile(fileMessage);\n\n if (args.length > 0) {\n for (const arg of args) {\n const argStr = typeof arg === \"object\" && arg !== null\n ? JSON.stringify(arg, null, 2)\n : String(arg);\n\n if (consoleLoggingEnabled) {\n process.stdout.write(argStr + \"\\n\");\n }\n writeToFile(argStr);\n }\n }\n}\n\n/**\n * Log an info level message\n * @param message The message to log\n * @param args Optional arguments to log\n */\nexport function logInfo(message: string, ...args: any[]): void {\n if (!shouldLog('INFO')) return;\n\n const formattedMessage = formatLogMessage('INFO', message);\n const fileMessage = formatLogMessage('INFO', message, true);\n\n if (consoleLoggingEnabled) {\n process.stdout.write(formattedMessage + \"\\n\");\n }\n writeToFile(fileMessage);\n\n if (args.length > 0) {\n for (const arg of args) {\n const argStr = typeof arg === \"object\" && arg !== null\n ? JSON.stringify(arg, null, 2)\n : String(arg);\n\n if (consoleLoggingEnabled) {\n process.stdout.write(argStr + \"\\n\");\n }\n writeToFile(argStr);\n }\n }\n}\n\n/**\n * Log a warning level message (outputs to stderr)\n * @param message The message to log\n * @param args Optional arguments to log\n */\nexport function logWarn(message: string, ...args: any[]): void {\n if (!shouldLog('WARN')) return;\n\n const formattedMessage = formatLogMessage('WARN', message);\n const fileMessage = formatLogMessage('WARN', message, true);\n\n if (consoleLoggingEnabled) {\n process.stderr.write(formattedMessage + \"\\n\");\n }\n writeToFile(fileMessage);\n\n if (args.length > 0) {\n for (const arg of args) {\n const argStr = typeof arg === \"object\" && arg !== null\n ? JSON.stringify(arg, null, 2)\n : String(arg);\n\n if (consoleLoggingEnabled) {\n process.stderr.write(argStr + \"\\n\");\n }\n writeToFile(argStr);\n }\n }\n}\n\n/**\n * Log an error message with optional error object (outputs to stderr)\n * @param message The error message to log\n * @param error Optional error object\n */\nexport function logError(message: string, error?: any): void {\n if (!shouldLog('ERROR')) return;\n\n const formattedMessage = formatLogMessage('ERROR', message);\n const fileMessage = formatLogMessage('ERROR', message, true);\n\n if (consoleLoggingEnabled) {\n process.stderr.write(formattedMessage + \"\\n\");\n }\n writeToFile(fileMessage);\n\n if (error) {\n let errorStr = '';\n if (error instanceof Error) {\n errorStr = error.message;\n if (error.stack) {\n errorStr += `\\nStack Trace:\\n${error.stack}`;\n }\n } else if (typeof error === \"object\") {\n errorStr = JSON.stringify(error, null, 2);\n } else {\n errorStr = String(error);\n }\n\n if (consoleLoggingEnabled) {\n process.stderr.write(errorStr + \"\\n\");\n }\n writeToFile(errorStr);\n }\n}\n\n/**\n * Log an API call\n * @param apiName Name of the API being called\n * @param requestData Optional request data to log at DEBUG level\n */\nexport function logAPICall(apiName: string, requestData?: any): void {\n if (!shouldLog('INFO')) return;\n const message = `🔗 API Call: ${apiName}`;\n\n // Temporarily clear RequestId since it's not available until API response\n const savedRequestId = currentRequestId;\n currentRequestId = '';\n\n if (useColors) {\n // Use cyan/bright blue for API calls\n process.stdout.write(`${ANSI_CYAN}ℹ️ INFO: ${message}${ANSI_RESET}\\n`);\n } else {\n logInfo(message);\n }\n\n currentRequestId = savedRequestId;\n\n if (requestData && shouldLog('DEBUG')) {\n const maskedData = maskSensitiveData(requestData);\n logDebug(`📤 Request: ${JSON.stringify(maskedData)}`);\n }\n}\n\n/**\n * Log an API response with key details at INFO level\n * @param apiName Name of the API being called\n * @param requestId Request ID from the response\n * @param success Whether the API call was successful\n * @param keyFields Dictionary of key business fields to log\n * @param fullResponse Full response body (logged at DEBUG level)\n */\nexport function logAPIResponseWithDetails(\n apiName: string,\n requestId?: string,\n success = true,\n keyFields?: Record<string, any>,\n fullResponse?: string\n): void {\n\n if (success) {\n if (shouldLog('INFO')) {\n let mainMessage = `✅ API Response: ${apiName}`;\n if (requestId) {\n mainMessage += `, RequestId=${requestId}`;\n }\n\n if (useColors) {\n // Use green for successful API responses\n process.stdout.write(`${ANSI_GREEN}ℹ️ INFO: ${mainMessage}${ANSI_RESET}\\n`);\n } else {\n logInfo(mainMessage);\n }\n\n if (keyFields) {\n for (const [key, value] of Object.entries(keyFields)) {\n const maskedValue = maskSensitiveData({ [key]: value });\n const keyMessage = ` └─ ${key}=${maskedValue[key]}`;\n if (useColors) {\n process.stdout.write(`${ANSI_GREEN}ℹ️ INFO: ${keyMessage}${ANSI_RESET}\\n`);\n } else {\n logInfo(keyMessage);\n }\n }\n }\n }\n\n if (fullResponse && shouldLog('DEBUG')) {\n logDebug(`📥 Full Response: ${fullResponse}`);\n }\n } else {\n if (shouldLog('ERROR')) {\n let errorMessage = `❌ API Response Failed: ${apiName}`;\n if (requestId) {\n errorMessage += `, RequestId=${requestId}`;\n }\n\n if (useColors) {\n // Use red for failed API responses\n process.stderr.write(`${ANSI_RED}❌ ERROR: ${errorMessage}${ANSI_RESET}\\n`);\n } else {\n logError(errorMessage);\n }\n\n if (fullResponse) {\n if (useColors) {\n process.stderr.write(`${ANSI_RED}ℹ️ INFO: 📥 Response: ${fullResponse}${ANSI_RESET}\\n`);\n } else {\n logError(`📥 Response: ${fullResponse}`);\n }\n }\n }\n }\n}\n\n/**\n * Extract and log the actual code execution output from run_code response\n * @param requestId Request ID from the API response\n * @param rawOutput Raw JSON output from the MCP tool\n */\nexport function logCodeExecutionOutput(requestId: string, rawOutput: string): void {\n if (!shouldLog('INFO')) return;\n\n try {\n // Parse the JSON response to extract the actual code output\n const response = JSON.parse(rawOutput);\n\n // Extract text from all content items\n const texts: string[] = [];\n if (response && typeof response === 'object' && 'content' in response) {\n const content = response.content;\n if (Array.isArray(content)) {\n for (const item of content) {\n if (item && typeof item === 'object' && item.type === 'text' && item.text) {\n texts.push(item.text);\n }\n }\n }\n }\n\n if (texts.length === 0) {\n return;\n }\n\n const actualOutput = texts.join('');\n\n // Format the output with a clear separator\n const header = `📋 Code Execution Output (RequestID: ${requestId}):`;\n\n if (useColors) {\n process.stdout.write(`${ANSI_GREEN}ℹ️ INFO: ${header}${ANSI_RESET}\\n`);\n } else {\n logInfo(header);\n }\n\n // Print each line with indentation\n const lines = actualOutput.trimEnd().split('\\n');\n for (const line of lines) {\n if (useColors) {\n process.stdout.write(`${ANSI_GREEN}ℹ️ INFO: ${line}${ANSI_RESET}\\n`);\n } else {\n logInfo(` ${line}`);\n }\n }\n\n // Also write to file if enabled\n if (fileLoggingEnabled && logFilePath) {\n writeToFile(header);\n for (const line of lines) {\n writeToFile(` ${line}`);\n }\n }\n } catch (error) {\n // If parsing fails, just return without logging\n return;\n }\n}\n\n/**\n * Log operation start\n * @param operation Name of the operation\n * @param details Optional operation details\n */\nexport function logOperationStart(operation: string, details?: string): void {\n if (!shouldLog('INFO')) return;\n const message = `🚀 Starting: ${operation}`;\n logInfo(message);\n\n if (details && shouldLog('DEBUG')) {\n logDebug(`📋 Details: ${details}`);\n }\n}\n\n/**\n * Log operation success\n * @param operation Name of the operation\n * @param result Optional operation result\n */\nexport function logOperationSuccess(operation: string, result?: string): void {\n if (!shouldLog('INFO')) return;\n const message = `✅ Completed: ${operation}`;\n logInfo(message);\n\n if (result && shouldLog('DEBUG')) {\n logDebug(`📊 Result: ${result}`);\n }\n}\n\n/**\n * Log operation error\n * @param operation Name of the operation that failed\n * @param error Error message or error object\n * @param includeStackTrace Whether to include stack trace\n */\nexport function logOperationError(\n operation: string,\n error: string | Error,\n includeStackTrace = false\n): void {\n if (!shouldLog('ERROR')) return;\n const message = `❌ Failed: ${operation}`;\n\n if (typeof error === 'string') {\n logError(message, new Error(error));\n } else if (error instanceof Error) {\n if (includeStackTrace) {\n logError(message, error);\n } else {\n logError(message, error.message);\n }\n } else {\n logError(message, String(error));\n }\n}\n","/**\n * Base interface for API responses\n */\nexport interface ApiResponse {\n /** Optional request identifier for tracking API calls */\n requestId?: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n /** Optional status code if the operation failed */\n success?: boolean;\n}\n\n/**\n * Generic interface for API responses that include data payload\n * @template T The type of the data being returned\n */\nexport interface ApiResponseWithData<T> extends ApiResponse {\n /** The actual data payload returned by the API */\n session?: T;\n data?: T;\n}\n\n/**\n * Interface for delete operation responses\n */\nexport interface DeleteResult extends ApiResponse {\n /** Whether the delete operation was successful */\n success: boolean;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for GetSession data\n */\nexport interface GetSessionData {\n /** Application instance ID */\n appInstanceId: string;\n /** Resource ID */\n resourceId: string;\n /** Session ID */\n sessionId: string;\n /** Success status */\n success: boolean;\n /** HTTP port for VPC sessions */\n httpPort: string;\n /** Network interface IP for VPC sessions */\n networkInterfaceIp: string;\n /** Token for VPC sessions */\n token: string;\n /** Whether this session uses VPC resources */\n vpcResource: boolean;\n /** Resource URL for accessing the session */\n resourceUrl: string;\n}\n\n/**\n * Interface for GetSession operation responses\n */\nexport interface GetSessionResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** HTTP status code */\n httpStatusCode: number;\n /** Response code */\n code: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Session data */\n data?: GetSessionData;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for session creation operation responses\n * Corresponds to Python's SessionResult type\n */\nexport interface SessionResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the session creation was successful */\n success: boolean;\n /** The created session object (only present if successful) */\n session?: any; // Will be Session type, avoiding circular import\n /** Error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for operation results\n * Corresponds to Python's OperationResult type\n */\nexport interface OperationResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Optional data payload */\n data?: any;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for session info operation responses\n * Corresponds to Go's InfoResult type\n */\nexport interface InfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Session information object */\n info?: any; // Will be SessionInfo type, avoiding circular import\n}\n\n/**\n * Interface for label operation responses\n * Corresponds to Go's LabelResult type\n */\nexport interface LabelResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Labels string (JSON format) */\n labels: string;\n}\n\n/**\n * Interface for link operation responses\n * Corresponds to Go's LinkResult type\n */\nexport interface LinkResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Link string */\n link: string;\n}\n\n/**\n * Interface for process list operation responses\n * Corresponds to Python's ProcessListResult type\n */\nexport interface ProcessListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The list of process objects */\n data: any[]; // Will be Process[] type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for installed app list operation responses\n * Corresponds to Python's InstalledAppListResult type\n */\nexport interface InstalledAppListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The list of installed app objects */\n data: any[]; // Will be InstalledApp[] type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application operation responses\n * Corresponds to Python's AppOperationResult type\n */\nexport interface AppOperationResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application info operation responses\n * Corresponds to Python's AppInfoResult type\n */\nexport interface AppInfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Application information */\n appInfo: Record<string, any>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application list operation responses\n * Corresponds to Python's AppListResult type\n */\nexport interface AppListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** List of applications */\n apps: Record<string, any>[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for application installation responses\n * Corresponds to Python's AppInstallResult type\n */\nexport interface AppInstallResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the installation was successful */\n success: boolean;\n /** Result description or error message */\n message: string;\n}\n\n/**\n * Interface for command execution operation responses\n * Corresponds to Python's CommandResult type\n */\nexport interface CommandResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the command execution was successful */\n success: boolean;\n /** The command output */\n output: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for code execution operation responses\n * Corresponds to Python's CodeExecutionResult type\n */\nexport interface CodeExecutionResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the code execution was successful */\n success: boolean;\n /** The execution result */\n result: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for boolean operation responses\n * Corresponds to Python's BoolResult type\n */\nexport interface BoolResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Boolean data result */\n data?: boolean;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for file info operation responses\n * Corresponds to Python's FileInfoResult type\n */\nexport interface FileInfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** File information object */\n fileInfo?: Record<string, any>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for directory list operation responses\n * Corresponds to Python's DirectoryListResult type\n */\nexport interface DirectoryListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Directory entries */\n entries: Record<string, any>[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for file content operation responses\n * Corresponds to Python's FileContentResult type\n */\nexport interface FileContentResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** File content */\n content: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for multiple file content operation responses\n * Corresponds to Python's MultipleFileContentResult type\n */\nexport interface MultipleFileContentResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Multiple file contents */\n contents: Record<string, string>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for file search operation responses\n * Corresponds to Python's FileSearchResult type\n */\nexport interface FileSearchResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Matching file paths */\n matches: string[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for OSS client creation operation responses\n * Corresponds to Python's OSSClientResult type\n */\nexport interface OSSClientResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** OSS client configuration */\n clientConfig: Record<string, any>;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for OSS upload operation responses\n * Corresponds to Python's OSSUploadResult type\n */\nexport interface OSSUploadResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Result of the upload operation */\n content: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for OSS download operation responses\n * Corresponds to Python's OSSDownloadResult type\n */\nexport interface OSSDownloadResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Result of the download operation */\n content: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for UI element list operation responses\n * Corresponds to Python's UIElementListResult type\n */\nexport interface UIElementListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** UI elements */\n elements: Record<string, any>[];\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for window list operation responses\n * Corresponds to Python's WindowListResult type\n */\nexport interface WindowListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** List of windows */\n windows: any[]; // Will be Window[] type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for window info operation responses\n * Corresponds to Python's WindowInfoResult type\n */\nexport interface WindowInfoResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Window object */\n window?: any; // Will be Window type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for context operation responses\n * Corresponds to Python's ContextResult type\n */\nexport interface ContextResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The context ID */\n contextId: string;\n /** The context object (only present if successful) */\n context?: any; // Will be Context type, avoiding circular import\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Interface for context list operation responses\n * Corresponds to Python's ContextListResult type\n */\nexport interface ContextListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** List of contexts */\n contexts: any[]; // Will be Context[] type, avoiding circular import\n /** Token for the next page of results */\n nextToken?: string;\n /** Maximum number of results per page */\n maxResults?: number;\n /** Total number of contexts available */\n totalCount?: number;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Result of a presigned URL request\n */\nexport interface FileUrlResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** The presigned URL */\n url: string;\n /** Optional expire time (epoch seconds) */\n expireTime?: number;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Represents a file item in a context\n */\nexport interface ContextFileEntry {\n fileId?: string;\n fileName?: string;\n filePath: string;\n fileType?: string;\n gmtCreate?: string;\n gmtModified?: string;\n size?: number;\n status?: string;\n}\n\n/**\n * Result of context file listing\n */\nexport interface ContextFileListResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** File entries under a folder */\n entries: ContextFileEntry[];\n /** Optional total count returned by backend */\n count?: number;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n\n/**\n * Helper function to extract request ID from API responses\n */\nexport function extractRequestId(response: any): string | undefined {\n if (!response) return undefined;\n\n // If response is a string (like body?.requestId), return it directly\n if (typeof response === \"string\" && response.length > 0) {\n return response;\n }\n\n // Check for requestId in response.body first\n if (response.body && response.body.requestId) {\n return response.body.requestId;\n }\n // Check for requestId directly on response\n if (response.requestId) {\n return response.requestId;\n }\n\n return undefined;\n}\n\n/**\n * Result of context clear operations, including the real-time status.\n * Corresponds to Python's ClearContextResult type\n */\nexport interface ClearContextResult extends ApiResponse {\n /** Request identifier for tracking API calls */\n requestId: string;\n /** Whether the operation was successful */\n success: boolean;\n /** Current status of the clearing task. This corresponds to the\n context's state field. Possible values:\n - \"clearing\": Context data is being cleared (in progress)\n - \"available\": Clearing completed successfully\n - Other values may indicate the context state after clearing */\n status?: string;\n /** The unique identifier of the context being cleared */\n contextId?: string;\n /** Optional error message if the operation failed */\n errorMessage?: string;\n}\n","// UploadStrategy defines the upload strategy for context synchronization\nexport enum UploadStrategy {\n UploadBeforeResourceRelease = \"UploadBeforeResourceRelease\",\n}\n\n// DownloadStrategy defines the download strategy for context synchronization\nexport enum DownloadStrategy {\n DownloadAsync = \"DownloadAsync\",\n}\n\n// UploadMode defines the upload mode for context synchronization\nexport enum UploadMode {\n File = \"File\",\n Archive = \"Archive\",\n}\n\n// Lifecycle defines the lifecycle options for recycle policy\nexport enum Lifecycle {\n Lifecycle_1Day = \"Lifecycle_1Day\",\n Lifecycle_3Days = \"Lifecycle_3Days\", \n Lifecycle_5Days = \"Lifecycle_5Days\",\n Lifecycle_10Days = \"Lifecycle_10Days\",\n Lifecycle_15Days = \"Lifecycle_15Days\",\n Lifecycle_30Days = \"Lifecycle_30Days\",\n Lifecycle_90Days = \"Lifecycle_90Days\",\n Lifecycle_180Days = \"Lifecycle_180Days\",\n Lifecycle_360Days = \"Lifecycle_360Days\",\n Lifecycle_Forever = \"Lifecycle_Forever\",\n}\n\n// UploadPolicy defines the upload policy for context synchronization\nexport interface UploadPolicy {\n autoUpload: boolean;\n uploadStrategy: UploadStrategy;\n uploadMode: UploadMode;\n}\n\n// DownloadPolicy defines the download policy for context synchronization\nexport interface DownloadPolicy {\n autoDownload: boolean;\n downloadStrategy: DownloadStrategy;\n}\n\n// DeletePolicy defines the delete policy for context synchronization\nexport interface DeletePolicy {\n syncLocalFile: boolean;\n}\n\n// ExtractPolicy defines the extract policy for context synchronization\nexport interface ExtractPolicy {\n extract: boolean;\n deleteSrcFile: boolean;\n extractToCurrentFolder: boolean;\n}\n\n// RecyclePolicy defines the recycle policy for context synchronization\nexport interface RecyclePolicy {\n lifecycle: Lifecycle;\n paths: string[];\n}\n\n// ExtractPolicyClass provides a class-based implementation with default values\nexport class ExtractPolicyClass implements ExtractPolicy {\n extract: boolean = true;\n deleteSrcFile: boolean = true;\n extractToCurrentFolder: boolean = false;\n\n constructor(extract: boolean = true, deleteSrcFile: boolean = true, extractToCurrentFolder: boolean = false) {\n this.extract = extract;\n this.deleteSrcFile = deleteSrcFile;\n this.extractToCurrentFolder = extractToCurrentFolder;\n }\n\n /**\n * Creates a new extract policy with default values\n */\n static default(): ExtractPolicyClass {\n return new ExtractPolicyClass();\n }\n\n /**\n * Converts to plain object for JSON serialization\n */\n toDict(): Record<string, any> {\n return {\n extract: this.extract,\n deleteSrcFile: this.deleteSrcFile,\n extractToCurrentFolder: this.extractToCurrentFolder\n };\n }\n}\n\n// WhiteList defines the white list configuration\nexport interface WhiteList {\n path: string;\n excludePaths?: string[];\n}\n\nexport class WhiteListValidator {\n private static containsWildcard(path: string): boolean {\n return /[*?\\[\\]]/.test(path);\n }\n\n static validate(whitelist: WhiteList): void {\n if (this.containsWildcard(whitelist.path)) {\n throw new Error(\n `Wildcard patterns are not supported in path. Got: ${whitelist.path}. ` +\n \"Please use exact directory paths instead.\"\n );\n }\n\n if (whitelist.excludePaths) {\n for (const excludePath of whitelist.excludePaths) {\n if (this.containsWildcard(excludePath)) {\n throw new Error(\n `Wildcard patterns are not supported in exclude_paths. Got: ${excludePath}. ` +\n \"Please use exact directory paths instead.\"\n );\n }\n }\n }\n }\n}\n\n// BWList defines the black and white list configuration\nexport interface BWList {\n whiteLists?: WhiteList[];\n}\n\n// SyncPolicy defines the synchronization policy\nexport interface SyncPolicy {\n uploadPolicy?: UploadPolicy;\n downloadPolicy?: DownloadPolicy;\n deletePolicy?: DeletePolicy;\n extractPolicy?: ExtractPolicy;\n recyclePolicy?: RecyclePolicy;\n bwList?: BWList;\n}\n\n// SyncPolicyImpl provides a class-based implementation with default value handling\nexport class SyncPolicyImpl implements SyncPolicy {\n uploadPolicy?: UploadPolicy;\n downloadPolicy?: DownloadPolicy;\n deletePolicy?: DeletePolicy;\n extractPolicy?: ExtractPolicy;\n recyclePolicy?: RecyclePolicy;\n bwList?: BWList;\n\n constructor(policy?: Partial<SyncPolicy>) {\n if (policy) {\n this.uploadPolicy = policy.uploadPolicy;\n this.downloadPolicy = policy.downloadPolicy;\n this.deletePolicy = policy.deletePolicy;\n this.extractPolicy = policy.extractPolicy;\n this.recyclePolicy = policy.recyclePolicy;\n this.bwList = policy.bwList;\n }\n this.ensureDefaults();\n }\n\n private ensureDefaults(): void {\n if (!this.uploadPolicy) {\n this.uploadPolicy = newUploadPolicy();\n }\n if (!this.downloadPolicy) {\n this.downloadPolicy = newDownloadPolicy();\n }\n if (!this.deletePolicy) {\n this.deletePolicy = newDeletePolicy();\n }\n if (!this.extractPolicy) {\n this.extractPolicy = newExtractPolicy();\n }\n if (!this.recyclePolicy) {\n this.recyclePolicy = newRecyclePolicy();\n }\n if (!this.bwList) {\n this.bwList = {\n whiteLists: [\n {\n path: \"\",\n excludePaths: [],\n },\n ],\n };\n }\n }\n\n toJSON(): SyncPolicy {\n this.ensureDefaults();\n return {\n uploadPolicy: this.uploadPolicy,\n downloadPolicy: this.downloadPolicy,\n deletePolicy: this.deletePolicy,\n extractPolicy: this.extractPolicy,\n recyclePolicy: this.recyclePolicy,\n bwList: this.bwList,\n };\n }\n}\n\n// ContextSync defines the context synchronization configuration\nexport class ContextSync {\n contextId: string;\n path: string;\n policy?: SyncPolicy;\n\n constructor(contextId: string, path: string, policy?: SyncPolicy) {\n if (policy) {\n validateSyncPolicy(policy);\n }\n this.contextId = contextId;\n this.path = path;\n this.policy = policy;\n }\n\n // WithPolicy sets the policy and returns the context sync for chaining\n withPolicy(policy: SyncPolicy): ContextSync {\n validateSyncPolicy(policy);\n this.policy = policy;\n return this;\n }\n}\n\n// NewUploadPolicy creates a new upload policy with default values\nexport function newUploadPolicy(): UploadPolicy {\n return {\n autoUpload: true,\n uploadStrategy: UploadStrategy.UploadBeforeResourceRelease,\n uploadMode: UploadMode.File,\n };\n}\n\n// NewDownloadPolicy creates a new download policy with default values\nexport function newDownloadPolicy(): DownloadPolicy {\n return {\n autoDownload: true,\n downloadStrategy: DownloadStrategy.DownloadAsync,\n };\n}\n\n// NewDeletePolicy creates a new delete policy with default values\nexport function newDeletePolicy(): DeletePolicy {\n return {\n syncLocalFile: true,\n };\n}\n\n// NewExtractPolicy creates a new extract policy with default values\nexport function newExtractPolicy(): ExtractPolicy {\n return {\n extract: true,\n deleteSrcFile: true,\n extractToCurrentFolder: false,\n };\n}\n\n// NewRecyclePolicy creates a new recycle policy with default values\nexport function newRecyclePolicy(): RecyclePolicy {\n return {\n lifecycle: Lifecycle.Lifecycle_Forever,\n paths: [\"\"],\n };\n}\n\n// NewSyncPolicy creates a new sync policy with default values\nexport function newSyncPolicy(): SyncPolicy {\n return {\n uploadPolicy: newUploadPolicy(),\n downloadPolicy: newDownloadPolicy(),\n deletePolicy: newDeletePolicy(),\n extractPolicy: newExtractPolicy(),\n recyclePolicy: newRecyclePolicy(),\n bwList: {\n whiteLists: [\n {\n path: \"\",\n excludePaths: [],\n },\n ],\n },\n };\n}\n\n// isValidLifecycle checks if the given lifecycle value is valid\nfunction isValidLifecycle(lifecycle: Lifecycle): boolean {\n return Object.values(Lifecycle).includes(lifecycle);\n}\n\n// isValidUploadMode checks if the given uploadMode value is valid\nfunction isValidUploadMode(uploadMode: UploadMode): boolean {\n return uploadMode === UploadMode.File || uploadMode === UploadMode.Archive;\n}\n\nexport function validateSyncPolicy(policy?: SyncPolicy): void {\n if (policy?.bwList?.whiteLists) {\n for (const whitelist of policy.bwList.whiteLists) {\n WhiteListValidator.validate(whitelist);\n }\n }\n\n if (policy?.uploadPolicy?.uploadMode) {\n // Validate uploadMode value\n if (!isValidUploadMode(policy.uploadPolicy.uploadMode)) {\n throw new Error(\n `Invalid uploadMode value: ${policy.uploadPolicy.uploadMode}. ` +\n `Valid values are: ${UploadMode.File}, ${UploadMode.Archive}`\n );\n }\n }\n\n if (policy?.recyclePolicy) {\n // Validate lifecycle value\n if (!isValidLifecycle(policy.recyclePolicy.lifecycle)) {\n const validValues = Object.values(Lifecycle).join(', ');\n throw new Error(\n `Invalid lifecycle value: ${policy.recyclePolicy.lifecycle}. ` +\n `Valid values are: ${validValues}`\n );\n }\n\n // Validate paths don't contain wildcard patterns\n if (policy.recyclePolicy.paths) {\n for (const path of policy.recyclePolicy.paths) {\n if (path && path.trim() !== \"\") {\n // Create a temporary WhiteList object for validation\n const tempWhiteList: WhiteList = { path: path };\n WhiteListValidator.validate(tempWhiteList);\n }\n }\n }\n }\n}\n\n// NewSyncPolicyWithDefaults creates a new sync policy with partial parameters and fills defaults\nexport function newSyncPolicyWithDefaults(policy?: Partial<SyncPolicy>): SyncPolicy {\n return new SyncPolicyImpl(policy).toJSON();\n}\n\n// NewContextSync creates a new context sync configuration\nexport function newContextSync(contextId: string, path: string, policy?: SyncPolicy): ContextSync {\n if (policy) {\n validateSyncPolicy(policy);\n }\n return new ContextSync(contextId, path, policy);\n}","import { AgentBay } from \"./agent-bay\";\nimport { Agent } from \"./agent/agent\";\nimport { Client } from \"./api/client\";\nimport {\n CallMcpToolRequest,\n GetLabelRequest,\n GetLinkRequest,\n GetMcpResourceRequest,\n ListMcpToolsRequest,\n ReleaseMcpSessionRequest,\n SetLabelRequest,\n} from \"./api/models/model\";\nimport { Application } from \"./application\";\nimport { Browser } from \"./browser\";\nimport { Code } from \"./code\";\nimport { Command } from \"./command\";\nimport { Computer } from \"./computer\";\nimport { ContextManager, ContextSyncResult, newContextManager } from \"./context-manager\";\nimport { FileSystem } from \"./filesystem\";\nimport { Mobile } from \"./mobile\";\nimport { Oss } from \"./oss\";\nimport {\n DeleteResult,\n extractRequestId,\n OperationResult,\n} from \"./types/api-response\";\nimport { UI } from \"./ui\";\nimport {\n log,\n logError,\n logInfo,\n logDebug,\n logAPICall,\n logAPIResponseWithDetails,\n logCodeExecutionOutput,\n setRequestId,\n getRequestId,\n} from \"./utils/logger\";\nimport { WindowManager } from \"./window\";\n\n/**\n * Represents an MCP tool with complete information.\n */\nexport interface McpTool {\n name: string;\n description: string;\n inputSchema: Record<string, any>;\n server: string;\n tool: string;\n}\n\n/**\n * Result containing MCP tools list and request ID.\n */\nexport interface McpToolsResult extends OperationResult {\n tools: McpTool[];\n}\n\n/**\n * Result containing MCP resource information and request ID.\n */\nexport interface McpResourceResult extends OperationResult {\n uri: string;\n name: string;\n description: string;\n mimeType: string;\n}\n\n/**\n * Result containing MCP resource content and request ID.\n */\nexport interface McpResourceContentResult extends OperationResult {\n contents: Array<{\n uri: string;\n mimeType: string;\n text?: string;\n blob?: string;\n }>;\n}\n\n/**\n * Contains information about a session.\n */\nexport interface SessionInfo {\n sessionId: string;\n resourceUrl: string;\n appId?: string;\n authCode?: string;\n connectionProperties?: string;\n resourceId?: string;\n resourceType?: string;\n ticket?: string;\n}\n\n/**\n * SessionInfo class to match Python version structure\n */\nexport class SessionInfoClass {\n sessionId: string;\n resourceUrl: string;\n appId: string;\n authCode: string;\n connectionProperties: string;\n resourceId: string;\n resourceType: string;\n ticket: string;\n\n constructor(\n sessionId = \"\",\n resourceUrl = \"\",\n appId = \"\",\n authCode = \"\",\n connectionProperties = \"\",\n resourceId = \"\",\n resourceType = \"\",\n ticket = \"\"\n ) {\n this.sessionId = sessionId;\n this.resourceUrl = resourceUrl;\n this.appId = appId;\n this.authCode = authCode;\n this.connectionProperties = connectionProperties;\n this.resourceId = resourceId;\n this.resourceType = resourceType;\n this.ticket = ticket;\n }\n}\n\n/**\n * Represents a session in the AgentBay cloud environment.\n */\nexport class Session {\n private agentBay: AgentBay;\n public sessionId: string;\n\n // File transfer context ID\n public fileTransferContextId: string | null = null;\n\n // Browser recording context ID\n public recordContextId: string | null = null;\n\n // VPC-related information\n public isVpc = false; // Whether this session uses VPC resources\n public networkInterfaceIp = \"\"; // Network interface IP for VPC sessions\n public httpPort = \"\"; // HTTP port for VPC sessions\n public token = \"\"; // Token for VPC sessions\n\n // Resource URL for accessing the session\n public resourceUrl = \"\";\n\n // Recording functionality\n public enableBrowserReplay = false; // Whether browser recording is enabled for this session\n\n // File, command, code, and oss handlers (matching Python naming)\n public fileSystem: FileSystem; // file_system in Python\n public command: Command;\n public code: Code;\n public oss: Oss;\n\n // Application, window, and UI management (matching Python naming)\n public application: Application; // application in Python (ApplicationManager)\n public window: WindowManager;\n public ui: UI;\n\n // Computer and Mobile automation (new modules)\n public computer: Computer;\n public mobile: Mobile;\n\n // Agent for task execution\n public agent: Agent;\n\n // Browser for web automation\n public browser: Browser;\n\n // Context management (matching Go version)\n public context: ContextManager;\n\n // MCP tools available for this session\n public mcpTools: McpTool[] = [];\n\n /**\n * Initialize a Session object.\n *\n * @param agentBay - The AgentBay instance that created this session.\n * @param sessionId - The ID of this session.\n */\n constructor(agentBay: AgentBay, sessionId: string) {\n this.agentBay = agentBay;\n this.sessionId = sessionId;\n\n // Initialize file system, command and code handlers (matching Python naming)\n this.fileSystem = new FileSystem(this);\n this.command = new Command(this);\n this.code = new Code(this);\n this.oss = new Oss(this);\n\n // Initialize application and window managers (matching Python naming)\n this.application = new Application(this);\n this.window = new WindowManager(this);\n this.ui = new UI(this);\n\n // Initialize Computer and Mobile modules\n this.computer = new Computer(this);\n this.mobile = new Mobile(this);\n\n // Initialize Agent\n this.agent = new Agent(this);\n\n // Initialize Browser\n this.browser = new Browser(this);\n\n // Initialize context manager (matching Go version)\n this.context = newContextManager(this);\n }\n\n /**\n * Return the AgentBay instance that created this session.\n */\n getAgentBay(): AgentBay {\n return this.agentBay;\n }\n\n /**\n * Return the API key for this session.\n */\n getAPIKey(): string {\n return this.agentBay.getAPIKey();\n }\n\n /**\n * Return the HTTP client for this session.\n */\n getClient(): Client {\n return this.agentBay.getClient();\n }\n\n /**\n * Return the session_id for this session.\n */\n getSessionId(): string {\n return this.sessionId;\n }\n\n /**\n * Return whether this session uses VPC resources.\n */\n isVpcEnabled(): boolean {\n return this.isVpc;\n }\n\n /**\n * Return the network interface IP for VPC sessions.\n */\n getNetworkInterfaceIp(): string {\n return this.networkInterfaceIp;\n }\n\n /**\n * Return the HTTP port for VPC sessions.\n */\n getHttpPort(): string {\n return this.httpPort;\n }\n\n /**\n * Return the token for VPC sessions.\n */\n getToken(): string {\n return this.token;\n }\n\n /**\n * Find the server that provides the given tool.\n */\n findServerForTool(toolName: string): string {\n for (const tool of this.mcpTools) {\n if (tool.name === toolName) {\n return tool.server;\n }\n }\n return \"\";\n }\n\n /**\n * Delete this session.\n *\n * @param syncContext - Whether to sync context data (trigger file uploads) before deleting the session. Defaults to false.\n * @returns DeleteResult indicating success or failure and request ID\n */\n async delete(syncContext = false): Promise<DeleteResult> {\n try {\n // Determine sync behavior based on enableBrowserReplay and syncContext\n let shouldSync = false;\n let syncContextId: string | null = null;\n\n if (syncContext) {\n // User explicitly requested sync - sync all contexts\n shouldSync = true;\n logInfo(\"🔄 User requested context synchronization\");\n } else if (this.enableBrowserReplay && this.recordContextId) {\n // Browser replay enabled but no explicit sync - sync only browser recording context\n shouldSync = true;\n syncContextId = this.recordContextId;\n logInfo(`🎥 Browser replay enabled - syncing recording context: ${syncContextId}`);\n }\n\n // If syncContext is true, trigger file uploads first\n if (shouldSync) {\n logDebug(\"Triggering context synchronization before session deletion...\");\n\n // Use the new sync method without callback (sync mode)\n const syncStartTime = Date.now();\n\n try {\n let syncResult: ContextSyncResult;\n if (syncContextId) {\n // Sync specific context (browser recording)\n syncResult = await this.context.sync(syncContextId);\n logInfo(`🎥 Synced browser recording context: ${syncContextId}`);\n } else {\n // Sync all contexts\n syncResult = await this.context.sync();\n logInfo(\"🔄 Synced all contexts\");\n }\n\n const syncDuration = Date.now() - syncStartTime;\n\n if (syncResult.success) {\n logInfo(`Context sync completed in ${syncDuration}ms`);\n } else {\n logInfo(`Context sync completed with failures after ${syncDuration}ms`);\n }\n } catch (error) {\n const syncDuration = Date.now() - syncStartTime;\n logError(`Failed to trigger context sync after ${syncDuration}ms:`, error);\n // Continue with deletion even if sync fails\n }\n }\n\n // Proceed with session deletion\n const request = new ReleaseMcpSessionRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n });\n\n const response = await this.getClient().releaseMcpSession(request);\n logDebug(`Response from release_mcp_session: ${JSON.stringify(response)}`);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check if the response is success (matching Python logic)\n const responseBody = response.body;\n const success = responseBody?.success !== false; // Note: capital S to match Python\n\n if (!success) {\n const errorMessage = `[${responseBody?.code || 'Unknown'}] ${responseBody?.message || 'Failed to delete session'}`;\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n // Return success result with request ID\n return {\n requestId,\n success: true,\n };\n } catch (error) {\n logError(\"Error calling release_mcp_session:\", error);\n // In case of error, return failure result with error message (matching Python)\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to delete session ${this.sessionId}: ${error}`,\n };\n }\n }\n\n /**\n * Validates labels parameter for label operations.\n *\n * @param labels - The labels to validate\n * @returns null if validation passes, or OperationResult with error if validation fails\n */\n private validateLabels(labels: Record<string, string>): OperationResult | null {\n // Check if labels is null, undefined, or invalid type\n if (!labels || typeof labels !== 'object') {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels cannot be null, undefined, or invalid type. Please provide a valid labels object.\",\n };\n }\n\n // Check if labels is an array or other non-plain object\n if (Array.isArray(labels)) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels cannot be an array. Please provide a valid labels object.\",\n };\n }\n\n // Check if labels is a Date, RegExp, or other built-in object types\n if (labels instanceof Date || labels instanceof RegExp || labels instanceof Error ||\n labels instanceof Map || labels instanceof Set || labels instanceof WeakMap ||\n labels instanceof WeakSet || labels instanceof Promise) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels must be a plain object. Built-in object types are not allowed.\",\n };\n }\n\n // Check if labels object is empty\n if (Object.keys(labels).length === 0) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Labels cannot be empty. Please provide at least one label.\",\n };\n }\n\n for (const [key, value] of Object.entries(labels)) {\n // Check key validity\n if (!key || key.trim() === \"\") {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Label keys cannot be empty Please provide valid keys.\",\n };\n }\n\n // Check value is not null or undefined\n if (!value || value.trim() === \"\") {\n return {\n requestId: \"\",\n success: false,\n errorMessage: \"Label values cannot be empty Please provide valid values.\",\n };\n }\n }\n\n // Validation passed\n return null;\n }\n\n /**\n * Sets the labels for this session.\n *\n * @param labels - The labels to set for the session.\n * @returns OperationResult indicating success or failure with request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async setLabels(labels: Record<string, string>): Promise<OperationResult> {\n try {\n // Validate labels using the extracted validation function\n const validationResult = this.validateLabels(labels);\n if (validationResult !== null) {\n return validationResult;\n }\n\n // Convert labels to JSON string\n const labelsJSON = JSON.stringify(labels);\n\n const request = new SetLabelRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n labels: labelsJSON,\n });\n\n const response = await this.getClient().setLabel(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n return {\n requestId,\n success: true,\n };\n } catch (error) {\n logError(\"Error calling set_label:\", error);\n throw new Error(\n `Failed to set labels for session ${this.sessionId}: ${error}`\n );\n }\n }\n\n /**\n * Gets the labels for this session.\n *\n * @returns OperationResult containing the labels as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async getLabels(): Promise<OperationResult> {\n try {\n const request = new GetLabelRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n });\n\n const response = await this.getClient().getLabel(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Extract labels from response (matching Python structure)\n const responseBody = response?.body;\n const data = responseBody?.data; // Capital D to match Python\n const labelsJSON = data?.labels; // Capital L to match Python\n\n let labels = {};\n if (labelsJSON) {\n labels = JSON.parse(labelsJSON);\n }\n\n return {\n requestId,\n success: true,\n data: labels,\n };\n } catch (error) {\n logError(\"Error calling get_label:\", error);\n throw new Error(\n `Failed to get labels for session ${this.sessionId}: ${error}`\n );\n }\n }\n\n /**\n * Gets information about this session.\n *\n * @returns OperationResult containing the session information as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async info(): Promise<OperationResult> {\n try {\n const request = new GetMcpResourceRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.sessionId,\n });\n\n logAPICall(\"GetMcpResource\");\n logDebug(`Request: SessionId=${this.sessionId}`);\n\n const response = await this.getClient().getMcpResource(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for API-level errors\n if (response?.body?.success === false && response.body?.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetMcpResource\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n errorMessage,\n };\n }\n\n // Extract session info from response (matching Python structure)\n const responseBody = response.body;\n const data = responseBody?.data; // Capital D to match Python\n\n const sessionInfo = new SessionInfoClass();\n\n if (data?.sessionId) {\n // Capital S and I to match Python\n sessionInfo.sessionId = data.sessionId;\n }\n\n if (data?.resourceUrl) {\n // Capital R and U to match Python\n sessionInfo.resourceUrl = data.resourceUrl;\n }\n\n // Transfer DesktopInfo fields to SessionInfo (matching Python structure)\n if (data?.desktopInfo) {\n // Capital D and I to match Python\n const desktopInfo = data.desktopInfo;\n if (desktopInfo.appId) {\n sessionInfo.appId = desktopInfo.appId;\n }\n if (desktopInfo.authCode) {\n sessionInfo.authCode = desktopInfo.authCode;\n }\n if (desktopInfo.connectionProperties) {\n sessionInfo.connectionProperties = desktopInfo.connectionProperties;\n }\n if (desktopInfo.resourceId) {\n sessionInfo.resourceId = desktopInfo.resourceId;\n }\n if (desktopInfo.resourceType) {\n sessionInfo.resourceType = desktopInfo.resourceType;\n }\n if (desktopInfo.ticket) {\n sessionInfo.ticket = desktopInfo.ticket;\n }\n }\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n session_id: this.sessionId,\n };\n if (sessionInfo.resourceUrl) {\n keyFields.resource_url = sessionInfo.resourceUrl;\n }\n if (sessionInfo.appId) {\n keyFields.app_id = sessionInfo.appId;\n }\n const fullResponse = responseBody ? JSON.stringify(responseBody, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetMcpResource\", requestId, true, keyFields, fullResponse);\n\n return {\n requestId,\n success: true,\n data: sessionInfo,\n };\n } catch (error) {\n logError(\"Error calling GetMcpResource:\", error);\n throw new Error(\n `Failed to get session info for session ${this.sessionId}: ${error}`\n );\n }\n }\n\n /**\n * Get a link associated with the current session.\n *\n * @param protocolType - Optional protocol type to use for the link\n * @param port - Optional port to use for the link (must be in range [30100, 30199])\n * @returns OperationResult containing the link as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async getLink(\n protocolType?: string,\n port?: number,\n options?: string\n ): Promise<OperationResult> {\n try {\n // Validate port range if port is provided\n if (port) {\n if (!Number.isInteger(port) || port < 30100 || port > 30199) {\n throw new Error(\n `Invalid port value: ${port}. Port must be an integer in the range [30100, 30199].`\n );\n }\n }\n\n // Log API call\n let requestParams = `SessionId=${this.getSessionId()}, ProtocolType=${protocolType || 'default'}, Port=${port || 'default'}`;\n if (options) {\n requestParams += ', Options=provided';\n }\n logAPICall('GetLink', requestParams);\n\n const request = new GetLinkRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.getSessionId(),\n protocolType,\n port,\n option: options,\n });\n\n const response = await this.agentBay.getClient().getLink(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n const responseBody = response.body;\n\n if (typeof responseBody !== \"object\") {\n throw new Error(\n \"Invalid response format: expected a dictionary from response body\"\n );\n }\n\n let data = responseBody.data || {}; // Capital D to match Python\n logDebug(`Data: ${JSON.stringify(data)}`);;\n\n if (typeof data !== \"object\") {\n try {\n data = typeof data === \"string\" ? JSON.parse(data) : {};\n } catch (jsonError) {\n data = {};\n }\n }\n\n const url = (data as any).Url || (data as any).url;\n\n // Log API response\n const keyFields: Record<string, any> = {};\n if (url) {\n keyFields.url = url;\n }\n logAPIResponseWithDetails('GetLink', requestId, true, keyFields);\n\n return {\n requestId,\n success: true,\n data: url,\n };\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"Invalid response format\")\n ) {\n throw error;\n }\n throw new Error(`Failed to get link: ${error}`);\n }\n }\n\n /**\n * Asynchronously get a link associated with the current session.\n *\n * @param protocolType - Optional protocol type to use for the link\n * @param port - Optional port to use for the link (must be in range [30100, 30199])\n * @returns OperationResult containing the link as data and request ID\n * @throws Error if the operation fails (matching Python SessionError)\n */\n async getLinkAsync(\n protocolType?: string,\n port?: number,\n options?: string\n ): Promise<OperationResult> {\n try {\n // Validate port range if port is provided\n if (port !== undefined) {\n if (!Number.isInteger(port) || port < 30100 || port > 30199) {\n throw new Error(\n `Invalid port value: ${port}. Port must be an integer in the range [30100, 30199].`\n );\n }\n }\n\n // Log API call\n let requestParams = `SessionId=${this.getSessionId()}, ProtocolType=${protocolType || 'default'}, Port=${port || 'default'}`;\n if (options) {\n requestParams += ', Options=provided';\n }\n logAPICall('GetLink', requestParams);\n\n const request = new GetLinkRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.getSessionId(),\n protocolType,\n port,\n option: options,\n });\n\n // Note: In TypeScript, async is the default, but keeping this method for API compatibility\n const response = await this.agentBay.getClient().getLink(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n const responseBody = response?.body;\n\n if (typeof responseBody !== \"object\") {\n throw new Error(\n \"Invalid response format: expected a dictionary from response body\"\n );\n }\n\n let data = responseBody?.data || {}; // Capital D to match Python\n logDebug(`Data: ${JSON.stringify(data)}`);;\n\n if (typeof data !== \"object\") {\n try {\n data = typeof data === \"string\" ? JSON.parse(data) : {};\n } catch (jsonError) {\n data = {};\n }\n }\n\n const url = (data as any).Url || (data as any).url;\n\n // Log API response\n const keyFields: Record<string, any> = {};\n if (url) {\n keyFields.url = url;\n }\n logAPIResponseWithDetails('GetLink', requestId, true, keyFields);\n\n return {\n requestId,\n success: true,\n data: url,\n };\n } catch (error) {\n if (\n error instanceof Error &&\n error.message.includes(\"Invalid response format\")\n ) {\n throw error;\n }\n throw new Error(`Failed to get link asynchronously: ${error}`);\n }\n }\n\n /**\n * List MCP tools available for this session.\n *\n * @param imageId Optional image ID, defaults to session's imageId or \"linux_latest\"\n * @returns McpToolsResult containing tools list and request ID\n */\n async listMcpTools(imageId?: string): Promise<McpToolsResult> {\n // Use provided imageId, session's imageId, or default\n if (!imageId) {\n imageId = (this as any).imageId || \"linux_latest\";\n }\n\n const request = new ListMcpToolsRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n imageId: imageId,\n });\n\n logAPICall(\"ListMcpTools\");\n logDebug(`Request: ImageId=${imageId}`);\n\n const response = await this.getClient().listMcpTools(request);\n\n // Extract request ID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for API-level errors\n if (response?.body?.success === false && response.body?.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"ListMcpTools\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n tools: [],\n errorMessage,\n };\n }\n\n // Parse the response data\n const tools: McpTool[] = [];\n if (response && response.body && response.body.data) {\n try {\n const toolsData = JSON.parse(response.body.data as string);\n for (const toolData of toolsData) {\n const tool: McpTool = {\n name: toolData.name || \"\",\n description: toolData.description || \"\",\n inputSchema: toolData.inputSchema || {},\n server: toolData.server || \"\",\n tool: toolData.tool || \"\",\n };\n tools.push(tool);\n }\n } catch (error) {\n logError(`Error unmarshaling tools data: ${error}`);\n }\n }\n\n this.mcpTools = tools; // Update the session's mcpTools field\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n image_id: imageId,\n tool_count: tools.length,\n };\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"ListMcpTools\", requestId, true, keyFields, fullResponse);\n\n return {\n requestId,\n success: true,\n tools,\n };\n }\n\n /**\n * Call an MCP tool and return the result in a format compatible with Agent.\n *\n * @param toolName - Name of the MCP tool to call\n * @param args - Arguments to pass to the tool\n * @returns McpToolResult containing the response data\n */\n async callMcpTool(toolName: string, args: any): Promise<import(\"./agent/agent\").McpToolResult> {\n try {\n const argsJSON = JSON.stringify(args);\n\n // Check if this is a VPC session\n if (this.isVpcEnabled()) {\n // VPC mode: Use HTTP request to the VPC endpoint\n const server = this.findServerForTool(toolName);\n if (!server) {\n return {\n success: false,\n data: \"\",\n errorMessage: `Server not found for tool: ${toolName}`,\n requestId: \"\",\n };\n }\n\n if (!this.networkInterfaceIp || !this.httpPort) {\n return {\n success: false,\n data: \"\",\n errorMessage: `VPC network configuration incomplete: networkInterfaceIp=${this.networkInterfaceIp}, httpPort=${this.httpPort}. This may indicate the VPC session was not properly configured with network parameters.`,\n requestId: \"\",\n };\n }\n\n const baseURL = `http://${this.networkInterfaceIp}:${this.httpPort}/callTool`;\n const url = new URL(baseURL);\n url.searchParams.append(\"server\", server);\n url.searchParams.append(\"tool\", toolName);\n url.searchParams.append(\"args\", argsJSON);\n url.searchParams.append(\"token\", this.getToken());\n // Add requestId for debugging purposes\n const requestId = `vpc-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;\n url.searchParams.append(\"requestId\", requestId);\n\n const response = await fetch(url.toString(), {\n method: \"GET\",\n headers: {\n \"Content-Type\": \"application/x-www-form-urlencoded\",\n },\n });\n\n if (!response.ok) {\n return {\n success: false,\n data: \"\",\n errorMessage: `VPC request failed: ${response.statusText}`,\n requestId: \"\",\n };\n }\n\n const responseData = await response.json() as any;\n\n // Extract the actual result from the nested VPC response structure\n let actualResult: any = responseData;\n if (typeof responseData.data === \"string\") {\n try {\n const dataMap = JSON.parse(responseData.data);\n if (dataMap.result) {\n actualResult = dataMap.result;\n }\n } catch (err) {\n // Keep original response if parsing fails\n }\n } else if (responseData.data && responseData.data.result) {\n actualResult = responseData.data.result;\n }\n\n // Extract text content from the result\n let textContent = \"\";\n if (actualResult.content && Array.isArray(actualResult.content) && actualResult.content.length > 0) {\n const contentItem = actualResult.content[0];\n if (contentItem && contentItem.text) {\n textContent = contentItem.text;\n }\n }\n\n // For run_code tool, extract and log the actual code execution output\n if (toolName === \"run_code\" && actualResult) {\n const dataStr = typeof actualResult === 'string' ? actualResult : JSON.stringify(actualResult);\n logCodeExecutionOutput(requestId, dataStr);\n }\n\n return {\n success: true,\n data: textContent || JSON.stringify(actualResult),\n errorMessage: \"\",\n requestId: \"\",\n };\n } else {\n // Non-VPC mode: use traditional API call\n const callToolRequest = new CallMcpToolRequest({\n authorization: `Bearer ${this.getAPIKey()}`,\n sessionId: this.getSessionId(),\n name: toolName,\n args: argsJSON,\n });\n\n const response = await this.getClient().callMcpTool(callToolRequest);\n\n if (!response.body?.data) {\n return {\n success: false,\n data: \"\",\n errorMessage: \"Invalid response data format\",\n requestId: extractRequestId(response) || \"\",\n };\n }\n\n // Check for API-level errors before parsing Data\n if (response.body.success === false && response.body.code) {\n const errorMessage = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n return {\n success: false,\n data: \"\",\n errorMessage,\n requestId: extractRequestId(response) || \"\",\n };\n }\n\n const data = response.body.data as Record<string, any>;\n\n // Check if there's an error in the response\n if (data.isError) {\n const errorContent = data.content || [];\n const errorMessage = errorContent\n .map((item: any) => item.text || \"Unknown error\")\n .join(\"; \");\n\n return {\n success: false,\n data: \"\",\n errorMessage,\n requestId: extractRequestId(response) || \"\",\n };\n }\n\n // Extract text content from content array\n const content = data.content || [];\n let textContent = \"\";\n if (content.length > 0 && content[0].text !== undefined) {\n textContent = content[0].text;\n }\n\n // For run_code tool, extract and log the actual code execution output\n const reqId = extractRequestId(response) || \"\";\n if (toolName === \"run_code\" && data) {\n const dataStr = typeof response.body.data === 'string'\n ? response.body.data\n : JSON.stringify(response.body.data);\n logCodeExecutionOutput(reqId, dataStr);\n }\n\n return {\n success: true,\n data: textContent,\n errorMessage: \"\",\n requestId: reqId,\n };\n }\n } catch (error) {\n return {\n success: false,\n data: \"\",\n errorMessage: error instanceof Error ? error.message : String(error),\n requestId: \"\",\n };\n }\n }\n}\n","import { ApiResponse } from \"../types/api-response\";\nimport {\n log,\n logError,\n logInfo,\n logDebug,\n logAPICall,\n logAPIResponseWithDetails,\n setRequestId,\n} from \"../utils/logger\";\n\n/**\n * Result of task execution.\n */\nexport interface ExecutionResult extends ApiResponse {\n success: boolean;\n errorMessage: string;\n taskId: string;\n taskStatus: string;\n}\n\n/**\n * Result of query operations.\n */\nexport interface QueryResult extends ApiResponse {\n success: boolean;\n output: string;\n errorMessage: string;\n}\n\n/**\n * Result of an MCP tool call.\n */\nexport interface McpToolResult {\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n}\n\n/**\n * Interface defining the methods needed by Agent from Session.\n */\nexport interface McpSession {\n getAPIKey(): string;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<McpToolResult>;\n}\n\n/**\n * An Agent to manipulate applications to complete specific tasks.\n */\nexport class Agent {\n private session: McpSession;\n\n /**\n * Initialize an Agent object.\n *\n * @param session - The Session instance that this Agent belongs to.\n */\n constructor(session: McpSession) {\n this.session = session;\n }\n\n /**\n * Execute a specific task described in human language.\n *\n * @param task - Task description in human language.\n * @param maxTryTimes - Maximum number of retry attempts.\n * @returns ExecutionResult containing success status, task output, and error message if any.\n */\n async executeTask(task: string, maxTryTimes: number): Promise<ExecutionResult> {\n try {\n const args = { task, max_try_times: maxTryTimes };\n const result = await this.session.callMcpTool(\"flux_execute_task\", args);\n \n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n\n // Parse task ID from response\n let content: any;\n try {\n content = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: `Failed to parse response: ${err}`,\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n\n const taskId = content.task_id;\n if (!taskId) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Task ID not found in response\",\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n\n // Poll for task completion\n let triedTime = 0;\n while (triedTime < maxTryTimes) {\n const query = await this.getTaskStatus(taskId);\n if (!query.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: query.errorMessage,\n taskStatus: \"failed\",\n taskId,\n };\n }\n\n let statusContent: any;\n try {\n statusContent = JSON.parse(query.output);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: `Failed to parse status response: ${err}`,\n taskStatus: \"failed\",\n taskId,\n };\n }\n\n const taskStatus = statusContent.status;\n if (!taskStatus) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Task status not found in response\",\n taskStatus: \"failed\",\n taskId,\n };\n }\n\n switch (taskStatus) {\n case \"finished\":\n return {\n requestId: result.requestId,\n success: true,\n errorMessage: \"\",\n taskId,\n taskStatus,\n };\n case \"failed\":\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Failed to execute task.\",\n taskId,\n taskStatus,\n };\n case \"unsupported\":\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Unsupported task.\",\n taskId,\n taskStatus,\n };\n }\n\n logDebug(`Task ${taskId} is still running, please wait for a while.`);\n await new Promise(resolve => setTimeout(resolve, 3000));\n triedTime++;\n }\n\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: \"Task execution timed out\",\n taskStatus: \"timeout\",\n taskId,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to execute: ${error}`,\n taskStatus: \"failed\",\n taskId: \"\",\n };\n }\n }\n\n /**\n * Get the status of the task with the given task ID.\n *\n * @param taskId - Task ID\n * @returns QueryResult containing the task status\n */\n async getTaskStatus(taskId: string): Promise<QueryResult> {\n try {\n const args = { task_id: taskId };\n const result = await this.session.callMcpTool(\"flux_get_task_status\", args);\n \n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n output: \"\",\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n output: result.data,\n errorMessage: \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to get task status: ${error}`,\n output: \"\",\n };\n }\n }\n\n /**\n * Terminate a task with a specified task ID.\n *\n * @param taskId - The ID of the running task.\n * @returns ExecutionResult containing success status, task output, and error message if any.\n */\n async terminateTask(taskId: string): Promise<ExecutionResult> {\n logDebug(\"Terminating task\");\n \n try {\n const args = { task_id: taskId };\n const result = await this.session.callMcpTool(\"flux_terminate_task\", args);\n\n let content: any;\n try {\n content = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: `Failed to parse response: ${err}`,\n taskId,\n taskStatus: \"failed\",\n };\n }\n\n const terminatedTaskId = content.task_id || taskId;\n const status = content.status || \"unknown\";\n\n if (result.success) {\n return {\n requestId: result.requestId,\n success: true,\n errorMessage: \"\",\n taskId: terminatedTaskId,\n taskStatus: status,\n };\n }\n\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n taskId: terminatedTaskId,\n taskStatus: status,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to terminate: ${error}`,\n taskId,\n taskStatus: \"failed\",\n };\n }\n }\n} ","export { Browser, BrowserViewport, BrowserScreen, BrowserFingerprint, BrowserProxy, BrowserProxyClass, BrowserOption, BrowserOptionClass } from './browser';\nexport { BrowserAgent } from './browser_agent';\nexport type { ActOptions, ActResult, ObserveOptions, ObserveResult, ExtractOptions } from './browser_agent'; ","import { Session } from '../session';\nimport { BrowserAgent } from './browser_agent';\nimport { BrowserError } from '../exceptions';\nimport { BROWSER_DATA_PATH } from '../config';\nimport { InitBrowserRequest } from '../api/models/InitBrowserRequest';\nimport {\n log,\n logError,\n logInfo,\n logDebug,\n logAPICall,\n logAPIResponseWithDetails,\n setRequestId,\n} from '../utils/logger';\n\nexport interface BrowserViewport {\n width: number;\n height: number;\n}\n\nexport interface BrowserScreen {\n width: number;\n height: number;\n}\n\nexport interface BrowserFingerprint {\n devices?: Array<'desktop' | 'mobile'>;\n operatingSystems?: Array<'windows' | 'macos' | 'linux' | 'android' | 'ios'>;\n locales?: string[];\n}\n\nexport interface BrowserProxy {\n type: 'custom' | 'wuying';\n server?: string;\n username?: string;\n password?: string;\n strategy?: 'restricted' | 'polling';\n pollsize?: number;\n toMap(): Record<string, any>;\n}\n\nexport class BrowserProxyClass implements BrowserProxy {\n type: 'custom' | 'wuying';\n server?: string;\n username?: string;\n password?: string;\n strategy?: 'restricted' | 'polling';\n pollsize?: number;\n\n constructor(\n proxyType: 'custom' | 'wuying',\n server?: string,\n username?: string,\n password?: string,\n strategy?: 'restricted' | 'polling',\n pollsize?: number\n ) {\n this.type = proxyType;\n this.server = server;\n this.username = username;\n this.password = password;\n this.strategy = strategy;\n this.pollsize = pollsize;\n\n // Validation\n if (proxyType !== 'custom' && proxyType !== 'wuying') {\n throw new Error('proxy_type must be custom or wuying');\n }\n\n if (proxyType === 'custom' && !server) {\n throw new Error('server is required for custom proxy type');\n }\n\n if (proxyType === 'wuying' && !strategy) {\n throw new Error('strategy is required for wuying proxy type');\n }\n\n if (proxyType === 'wuying' && strategy !== 'restricted' && strategy !== 'polling') {\n throw new Error('strategy must be restricted or polling for wuying proxy type');\n }\n\n if (proxyType === 'wuying' && strategy === 'polling' && pollsize !== undefined && pollsize <= 0) {\n throw new Error('pollsize must be greater than 0 for polling strategy');\n }\n }\n\n toMap(): Record<string, any> {\n const proxyMap: Record<string, any> = {\n type: this.type\n };\n\n if (this.type === 'custom') {\n proxyMap.server = this.server;\n if (this.username) {\n proxyMap.username = this.username;\n }\n if (this.password) {\n proxyMap.password = this.password;\n }\n } else if (this.type === 'wuying') {\n proxyMap.strategy = this.strategy;\n if (this.strategy === 'polling') {\n proxyMap.pollsize = this.pollsize;\n }\n }\n\n return proxyMap;\n }\n\n static fromMap(m: Record<string, any> | null | undefined): BrowserProxyClass | null {\n if (!m || typeof m !== 'object') {\n return null;\n }\n\n const proxyType = m.type;\n if (!proxyType) {\n return null;\n }\n\n if (proxyType === 'custom') {\n return new BrowserProxyClass(\n proxyType,\n m.server,\n m.username,\n m.password\n );\n } else if (proxyType === 'wuying') {\n return new BrowserProxyClass(\n proxyType,\n undefined,\n undefined,\n undefined,\n m.strategy,\n m.pollsize || 10\n );\n } else {\n throw new Error(`Unsupported proxy type: ${proxyType}`);\n }\n }\n}\n\nexport interface BrowserOption {\n persistentPath?: string;\n useStealth?: boolean;\n userAgent?: string;\n viewport?: BrowserViewport;\n screen?: BrowserScreen;\n fingerprint?: BrowserFingerprint;\n solveCaptchas?: boolean;\n proxies?: BrowserProxy[];\n /** Path to the extensions directory. Defaults to \"/tmp/extensions/\" */\n extensionPath?: string;\n /** Additional command line arguments for the browser */\n cmdArgs?: string[];\n /** Default URL to navigate to when browser starts */\n defaultNavigateUrl?: string;\n /** Browser type: 'chrome' or 'chromium'. Defaults to undefined */\n browserType?: 'chrome' | 'chromium' | undefined;\n}\n\nexport class BrowserOptionClass implements BrowserOption {\n persistentPath?: string;\n useStealth?: boolean;\n userAgent?: string;\n viewport?: BrowserViewport;\n screen?: BrowserScreen;\n fingerprint?: BrowserFingerprint;\n solveCaptchas?: boolean;\n proxies?: BrowserProxy[];\n extensionPath?: string;\n cmdArgs?: string[];\n defaultNavigateUrl?: string;\n browserType?: 'chrome' | 'chromium' | undefined;\n\n constructor(\n useStealth = false,\n userAgent?: string,\n viewport?: BrowserViewport,\n screen?: BrowserScreen,\n fingerprint?: BrowserFingerprint,\n solveCaptchas = false,\n proxies?: BrowserProxy[],\n cmdArgs?: string[],\n defaultNavigateUrl?: string,\n browserType?: 'chrome' | 'chromium',\n ) {\n this.useStealth = useStealth;\n this.userAgent = userAgent;\n this.viewport = viewport;\n this.screen = screen;\n this.fingerprint = fingerprint;\n this.solveCaptchas = solveCaptchas;\n this.extensionPath = \"/tmp/extensions/\";\n this.cmdArgs = cmdArgs;\n this.defaultNavigateUrl = defaultNavigateUrl;\n this.browserType = browserType;\n\n // Validate proxies list items\n if (proxies !== undefined) {\n if (!Array.isArray(proxies)) {\n throw new Error('proxies must be a list');\n }\n if (proxies.length > 1) {\n throw new Error('proxies list length must be limited to 1');\n }\n }\n\n // Set proxies after validation\n this.proxies = proxies;\n\n // Validate cmdArgs\n if (cmdArgs !== undefined && !Array.isArray(cmdArgs)) {\n throw new Error('cmdArgs must be a list');\n }\n\n // Validate browser_type\n if (browserType !== undefined && browserType !== 'chrome' && browserType !== 'chromium') {\n throw new Error(\"browserType must be 'chrome' or 'chromium'\");\n }\n }\n\n toMap(): Record<string, any> {\n const optionMap: Record<string, any> = {};\n if (process.env.AGENTBAY_BROWSER_BEHAVIOR_SIMULATE) {\n optionMap['behaviorSimulate'] = (process.env.AGENTBAY_BROWSER_BEHAVIOR_SIMULATE !== \"0\") as boolean;\n }\n if (this.useStealth !== undefined) {\n optionMap['useStealth'] = this.useStealth;\n }\n if (this.userAgent !== undefined) {\n optionMap['userAgent'] = this.userAgent;\n }\n if (this.viewport !== undefined) {\n optionMap['viewport'] = { width: this.viewport.width, height: this.viewport.height };\n }\n if (this.screen !== undefined) {\n optionMap['screen'] = { width: this.screen.width, height: this.screen.height };\n }\n if (this.fingerprint !== undefined) {\n const fp: Record<string, any> = {};\n if (this.fingerprint.devices) fp['devices'] = this.fingerprint.devices;\n if (this.fingerprint.operatingSystems) fp['operatingSystems'] = this.fingerprint.operatingSystems;\n if (this.fingerprint.locales) fp['locales'] = this.fingerprint.locales;\n optionMap['fingerprint'] = fp;\n }\n if (this.solveCaptchas !== undefined) {\n optionMap['solveCaptchas'] = this.solveCaptchas;\n }\n if (this.proxies !== undefined) {\n optionMap['proxies'] = this.proxies.map(proxy => proxy.toMap());\n }\n if (this.extensionPath !== undefined) {\n optionMap['extensionPath'] = this.extensionPath;\n }\n if (this.cmdArgs !== undefined) {\n optionMap['cmdArgs'] = this.cmdArgs;\n }\n if (this.defaultNavigateUrl !== undefined) {\n optionMap['defaultNavigateUrl'] = this.defaultNavigateUrl;\n }\n if (this.browserType !== undefined) {\n optionMap['browserType'] = this.browserType;\n }\n return optionMap;\n }\n\n fromMap(m: Record<string, any> | null | undefined): BrowserOptionClass {\n const map = m || {};\n if (map.useStealth !== undefined) {\n this.useStealth = map.useStealth;\n } else {\n this.useStealth = false;\n }\n if (map.userAgent !== undefined) {\n this.userAgent = map.userAgent;\n }\n if (map.viewport !== undefined) {\n this.viewport = { width: map.viewport.width, height: map.viewport.height };\n }\n if (map.screen !== undefined) {\n this.screen = { width: map.screen.width, height: map.screen.height };\n }\n if (map.fingerprint !== undefined) {\n const fp: BrowserFingerprint = {};\n if (map.fingerprint.devices) fp.devices = map.fingerprint.devices;\n if (map.fingerprint.operatingSystems) fp.operatingSystems = map.fingerprint.operatingSystems;\n if (map.fingerprint.locales) fp.locales = map.fingerprint.locales;\n this.fingerprint = fp;\n }\n if (map.solveCaptchas !== undefined) {\n this.solveCaptchas = map.solveCaptchas;\n }\n if (map.proxies !== undefined) {\n const proxyList = map.proxies;\n if (proxyList.length > 1) {\n throw new Error('proxies list length must be limited to 1');\n }\n this.proxies = proxyList.map((proxyData: any) => {\n // If it's already a BrowserProxyClass instance, return it\n if (proxyData instanceof BrowserProxyClass) {\n return proxyData;\n }\n // Otherwise, convert from map\n return BrowserProxyClass.fromMap(proxyData);\n }).filter(Boolean) as BrowserProxy[];\n }\n if (map.extensionPath !== undefined) {\n this.extensionPath = map.extensionPath;\n }\n if (map.cmdArgs !== undefined) {\n this.cmdArgs = map.cmdArgs;\n }\n if (map.defaultNavigateUrl !== undefined) {\n this.defaultNavigateUrl = map.defaultNavigateUrl;\n }\n if (map.browserType !== undefined) {\n this.browserType = map.browserType;\n }\n return this;\n }\n}\n\nexport class Browser {\n private session: Session;\n private _endpointUrl: string | null = null;\n private _initialized = false;\n private _option: BrowserOptionClass | null = null;\n public agent: BrowserAgent;\n\n constructor(session: Session) {\n this.session = session;\n this.agent = new BrowserAgent(this.session, this);\n }\n\n /**\n * Initialize the browser instance with the given options.\n * Returns true if successful, false otherwise.\n */\n initialize(option: BrowserOptionClass | BrowserOption): boolean {\n if (this.isInitialized()) {\n return true;\n }\n\n try {\n // Use direct API call to initialize browser\n const request = new InitBrowserRequest();\n request.authorization = `Bearer ${this.session.getAPIKey()}`;\n request.persistentPath = BROWSER_DATA_PATH;\n request.sessionId = this.session.getSessionId();\n\n // Ensure option is a BrowserOptionClass instance\n let browserOption: BrowserOptionClass;\n if (option instanceof BrowserOptionClass) {\n browserOption = option;\n } else {\n // Convert plain object to BrowserOptionClass instance\n browserOption = new BrowserOptionClass();\n browserOption.fromMap(option as Record<string, any>);\n }\n\n // Map BrowserOption to API BrowserOption payload\n const browserOptionMap = browserOption.toMap();\n\n // Enable record if session.enableBrowserReplay is true\n if (this.session.enableBrowserReplay) {\n browserOptionMap['enableRecord'] = true;\n }\n\n if (Object.keys(browserOptionMap).length > 0) {\n request.browserOption = browserOptionMap;\n }\n\n const response = this.session.getClient().initBrowserSync(request);\n logDebug(`Response from init_browser data:`, response.body?.data);\n\n const success = response.body?.data?.port !== null && response.body?.data?.port !== undefined;\n if (success) {\n this._initialized = true;\n this._option = browserOption;\n logInfo(\"Browser instance was successfully initialized.\");\n }\n\n return success;\n } catch (error) {\n console.error(\"Failed to initialize browser instance:\", error);\n this._initialized = false;\n this._endpointUrl = null;\n this._option = null;\n return false;\n }\n }\n\n /**\n * Initialize the browser instance with the given options asynchronously.\n * Returns true if successful, false otherwise.\n */\n async initializeAsync(option: BrowserOptionClass | BrowserOption): Promise<boolean> {\n if (this.isInitialized()) {\n return true;\n }\n\n try {\n // Use direct API call to initialize browser\n const request = new InitBrowserRequest();\n request.authorization = `Bearer ${this.session.getAPIKey()}`;\n request.persistentPath = BROWSER_DATA_PATH;\n request.sessionId = this.session.getSessionId();\n\n // Ensure option is a BrowserOptionClass instance\n let browserOption: BrowserOptionClass;\n if (option instanceof BrowserOptionClass) {\n browserOption = option;\n } else {\n // Convert plain object to BrowserOptionClass instance\n browserOption = new BrowserOptionClass();\n browserOption.fromMap(option as Record<string, any>);\n }\n\n // Map BrowserOption to API BrowserOption payload\n const browserOptionMap = browserOption.toMap();\n\n // Enable record if session.enableBrowserReplay is true\n if (this.session.enableBrowserReplay) {\n browserOptionMap['enableRecord'] = true;\n }\n\n if (Object.keys(browserOptionMap).length > 0) {\n request.browserOption = browserOptionMap;\n }\n\n const response = await this.session.getClient().initBrowser(request);\n const requestId = response.body?.requestId || \"\";\n setRequestId(requestId);\n\n const success = response.body?.data?.port !== null && response.body?.data?.port !== undefined;\n if (success) {\n logAPIResponseWithDetails(\n \"InitBrowser\",\n requestId,\n true,\n {\n port: response.body?.data?.port,\n endpoint: response.body?.data?.endpoint,\n }\n );\n this._initialized = true;\n this._option = browserOption;\n } else {\n logAPIResponseWithDetails(\n \"InitBrowser\",\n requestId,\n false,\n {},\n \"Port not found in response\"\n );\n }\n\n return success;\n } catch (error) {\n logError(\"Failed to initialize browser instance:\", error);\n this._initialized = false;\n this._endpointUrl = null;\n this._option = null;\n return false;\n }\n }\n\n /**\n * Destroy the browser instance.\n */\n async destroy(): Promise<void> {\n if (this.isInitialized()) {\n await this.session.callMcpTool(\"stopChrome\", {});\n } else {\n throw new BrowserError(\"Browser is not initialized. Cannot destroy browser.\");\n }\n }\n\n /**\n * Returns the endpoint URL if the browser is initialized, otherwise throws an exception.\n * When initialized, always fetches the latest CDP url from session.getLink().\n */\n async getEndpointUrl(): Promise<string> {\n if (!this.isInitialized()) {\n throw new BrowserError(\"Browser is not initialized. Cannot access endpoint URL.\");\n }\n\n try {\n const linkResult = await this.session.getLink();\n this._endpointUrl = linkResult.data;\n return this._endpointUrl!;\n } catch (error) {\n throw new BrowserError(`Failed to get endpoint URL from session: ${error}`);\n }\n }\n\n /**\n * Returns the current BrowserOption used to initialize the browser, or null if not set.\n */\n getOption(): BrowserOptionClass | null {\n return this._option;\n }\n\n /**\n * Returns true if the browser was initialized, false otherwise.\n */\n isInitialized(): boolean {\n return this._initialized;\n }\n\n /**\n * Stop the browser instance, internal use only.\n */\n private _stopBrowser(): void {\n if (this.isInitialized()) {\n this.session.callMcpTool(\"stopChrome\", {});\n } else {\n throw new BrowserError(\"Browser is not initialized. Cannot stop browser.\");\n }\n }\n}\n","import { Session } from '../session';\nimport { Browser } from './browser';\nimport { BrowserError } from '../exceptions';\nimport {\n log,\n logError,\n logInfo,\n logDebug,\n logWarn,\n logAPICall,\n logAPIResponseWithDetails,\n setRequestId,\n} from '../utils/logger';\n\n// Options interfaces\nexport interface ActOptions {\n action: string;\n timeoutMS?: number;\n iframes?: boolean;\n domSettleTimeoutMS?: number;\n variables?: Record<string, string>;\n use_vision?: boolean;\n}\n\nexport interface ObserveOptions {\n instruction: string;\n iframes?: boolean;\n domSettleTimeoutMS?: number;\n use_vision?: boolean;\n}\n\nexport interface ExtractOptions<T = any> {\n instruction: string;\n schema: new (...args: any[]) => T;\n use_text_extract?: boolean;\n selector?: string;\n iframe?: boolean;\n domSettleTimeoutMS?: number;\n use_vision?: boolean;\n}\n\nexport class ActResult {\n success: boolean;\n message: string;\n action?: string;\n constructor(success: boolean, message: string, action?: string) {\n this.success = success;\n this.message = message;\n this.action = action;\n }\n}\n\nexport class ObserveResult {\n selector: string;\n description: string;\n method: string;\n args: Record<string, any>;\n constructor(selector: string, description: string, method: string, args: Record<string, any>) {\n this.selector = selector;\n this.description = description;\n this.method = method;\n this.args = args;\n }\n}\n\nexport class BrowserAgent {\n private session: Session;\n private browser: Browser;\n\n constructor(session: Session, browser: Browser) {\n this.session = session;\n this.browser = browser;\n }\n\n /** ------------------ ACT ------------------ **/\n async act(options: ActOptions, page: any): Promise<ActResult> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling act.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n action: options.action,\n variables: options.variables,\n timeout_ms: options.timeoutMS,\n iframes: options.iframes,\n dom_settle_timeout_ms: options.domSettleTimeoutMS,\n use_vision: options.use_vision\n };\n const task_name = options.action;\n logDebug(`${task_name}`);\n \n const response = await this._callMcpTool(\"page_use_act\", args);\n\n if (response.success && response.data) {\n const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;\n return new ActResult(true, JSON.stringify(data), options.action);\n }\n return new ActResult(false, response.errorMessage || \"\");\n }\n\n async actAsync(options: ActOptions, page: any): Promise<ActResult> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling actAsync.\");\n\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n action: options.action,\n variables: options.variables,\n timeout_ms: options.timeoutMS,\n iframes: options.iframes,\n dom_settle_timeout_ms: options.domSettleTimeoutMS,\n use_vision: options.use_vision\n };\n const task_name = options.action;\n logDebug(`${task_name}`);\n\n const startResp = await this._callMcpTool(\"page_use_act_async\", args);\n if (!startResp.success) throw new BrowserError(\"Failed to start act task\");\n\n const { task_id } = JSON.parse(startResp.data);\n let retries = 30;\n\n while (retries-- > 0) {\n await this._delay(5000);\n const pollResp = await this._callMcpTool(\"page_use_get_act_result\", { task_id });\n\n if (pollResp.success && pollResp.data) {\n const data = typeof pollResp.data === 'string' ? JSON.parse(pollResp.data) : pollResp.data;\n const steps = data.steps || [];\n const is_done = data.is_done || false;\n const success = !!data.success;\n if (is_done) {\n const msg = steps.length ? JSON.stringify(steps) : \"No actions have been executed.\";\n logInfo(`Task ${task_id}:${task_name} is done. Success=${success}. ${msg}`);\n return new ActResult(success, msg, options.action);\n } else {\n if (steps.length) {\n logDebug(`Task ${task_id}:${task_name} progress: ${steps.length} steps done. Details: ${JSON.stringify(steps)}`);\n } else {\n logDebug(`Task ${task_id}:${task_name} No actions have been executed yet.`);\n }\n }\n }\n }\n throw new BrowserError(`Task ${task_id}: Act timed out`);\n }\n\n /** ------------------ OBSERVE ------------------ **/\n async observe(options: ObserveOptions, page: any): Promise<[boolean, ObserveResult[]]> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling observe.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n instruction: options.instruction,\n iframes: options.iframes,\n dom_settle_timeout_ms: options.domSettleTimeoutMS,\n use_vision: options.use_vision\n };\n\n const response = await this._callMcpTool(\"page_use_observe\", args);\n if (response.success && response.data) {\n const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;\n const results: ObserveResult[] = [];\n\n for (const item of data) {\n let argsParsed: any;\n try {\n argsParsed = typeof item.arguments === 'string' ? JSON.parse(item.arguments) : item.arguments;\n } catch {\n logWarn(`Warning: Could not parse arguments JSON: ${item.arguments}`);\n argsParsed = item.arguments;\n }\n results.push(new ObserveResult(item.selector || \"\", item.description || \"\", item.method || \"\", argsParsed));\n }\n return [true, results];\n }\n return [false, []];\n }\n\n async observeAsync(options: ObserveOptions, page: any): Promise<[boolean, ObserveResult[]]> {\n return this.observe(options, page);\n }\n\n /** ------------------ EXTRACT ------------------ **/\n async extract<T>(options: ExtractOptions<T>, page: any): Promise<[boolean, T | null]> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling extract.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n instruction: options.instruction,\n field_schema: `schema: ${JSON.stringify({ name: options.schema.name })}`,\n use_text_extract: options.use_text_extract,\n use_vision: options.use_vision,\n selector: options.selector,\n iframe: options.iframe,\n dom_settle_timeout_ms: options.domSettleTimeoutMS\n };\n\n const response = await this._callMcpTool(\"page_use_extract\", args);\n if (response.success && response.data) {\n const data = typeof response.data === 'string' ? JSON.parse(response.data) : response.data;\n return [true, data as T];\n }\n return [false, null];\n }\n\n async extractAsync<T>(options: ExtractOptions<T>, page: any): Promise<[boolean, T | null]> {\n if (!this.browser.isInitialized()) throw new BrowserError(\"Browser must be initialized before calling extractAsync.\");\n const [pageId, contextId] = await this._getPageAndContextIndexAsync(page);\n\n const args: Record<string, any> = {\n context_id: contextId,\n page_id: pageId,\n instruction: options.instruction,\n field_schema: `schema: ${JSON.stringify({ name: options.schema.name })}`,\n use_text_extract: options.use_text_extract,\n use_vision: options.use_vision,\n selector: options.selector,\n iframe: options.iframe,\n dom_settle_timeout_ms: options.domSettleTimeoutMS\n };\n\n const startResp = await this._callMcpTool(\"page_use_extract_async\", args);\n if (!startResp.success) throw new BrowserError(\"Failed to start extract task\");\n\n const { task_id } = JSON.parse(startResp.data);\n let retries = 20;\n\n while (retries-- > 0) {\n await this._delay(8000);\n const pollResp = await this._callMcpTool(\"page_use_get_extract_result\", { task_id });\n\n if (pollResp.success && pollResp.data) {\n const data = typeof pollResp.data === 'string' ? JSON.parse(pollResp.data) : pollResp.data;\n return [true, data as T];\n }\n logDebug(`Task ${task_id}: No extract result yet (attempt ${20 - retries}/20)`);\n }\n throw new BrowserError(`Task ${task_id}: Extract timed out`);\n }\n\n private async _getPageAndContextIndexAsync(page: any): Promise<[string, number]> {\n if (!page) {\n throw new BrowserError(\"Page is null\");\n }\n\n // Try to use Playwright CDP if available\n try {\n if (page.context && typeof page.context === 'function') {\n const context = page.context();\n if (context && typeof context.newCDPSession === 'function') {\n const cdpSession = await context.newCDPSession(page);\n const targetInfo = await cdpSession.send('Target.getTargetInfo');\n const pageIndex = (targetInfo && targetInfo.targetInfo && targetInfo.targetInfo.targetId) ? targetInfo.targetInfo.targetId : 'default-page-id';\n if (typeof cdpSession.detach === 'function') {\n await cdpSession.detach();\n }\n\n let contextIndex = 0;\n if (typeof context.browser === 'function') {\n const browserObj = context.browser();\n if (browserObj && typeof browserObj.contexts === 'function') {\n const contexts = browserObj.contexts();\n const idx = contexts.indexOf(context);\n if (idx >= 0) {\n contextIndex = idx;\n }\n }\n }\n return [pageIndex, contextIndex];\n }\n }\n } catch (error) {\n logWarn(`CDP targetId retrieval failed, fallback to defaults: ${error}`);\n }\n\n // Fallback to defaults if CDP is not available\n const pageIndex = \"default-page-id\";\n const contextIndex = 0;\n return [pageIndex, contextIndex];\n }\n\n private async _callMcpTool(toolName: string, args: Record<string, any>) {\n return this.session.callMcpTool(toolName, args);\n }\n\n private _delay(ms: number) {\n return new Promise(res => setTimeout(res, ms));\n }\n}\n","export { Code } from \"./code\";\nexport type { CodeExecutionResult } from \"../types/api-response\"; ","import {\n CodeExecutionResult,\n} from \"../types/api-response\";\n\n/**\n * Handles code execution operations in the AgentBay cloud environment.\n */\nexport class Code {\n private session: {\n getAPIKey(): string;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n };\n\n /**\n * Initialize a Code object.\n *\n * @param session - The Session instance that this Code belongs to.\n */\n constructor(session: {\n getAPIKey(): string;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n }) {\n this.session = session;\n }\n\n /**\n * Execute code in the specified language with a timeout.\n * Corresponds to Python's run_code() method\n *\n * @param code - The code to execute.\n * @param language - The programming language of the code. Must be either 'python' or 'javascript'.\n * @param timeoutS - The timeout for the code execution in seconds. Default is 60s.\n * Note: Due to gateway limitations, each request cannot exceed 60 seconds.\n * @returns CodeExecutionResult with code execution output and requestId\n * @throws Error if an unsupported language is specified.\n */\n async runCode(\n code: string,\n language: string,\n timeoutS = 60\n ): Promise<CodeExecutionResult> {\n try {\n // Validate language\n if (language !== \"python\" && language !== \"javascript\") {\n return {\n requestId: \"\",\n success: false,\n result: \"\",\n errorMessage: `Unsupported language: ${language}. Supported languages are 'python' and 'javascript'`,\n };\n }\n\n const args = {\n code,\n language,\n timeout_s: timeoutS,\n };\n\n const response = await this.session.callMcpTool(\n \"run_code\",\n args\n );\n\n if (!response.success) {\n return {\n requestId: response.requestId,\n success: false,\n result: \"\",\n errorMessage: response.errorMessage,\n };\n }\n\n return {\n requestId: response.requestId,\n success: true,\n result: response.data || \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n result: \"\",\n errorMessage: `Failed to run code: ${error}`,\n };\n }\n }\n} ","import { Session } from \"../session\";\nimport {\n CommandResult,\n} from \"../types/api-response\";\n\n\n/**\n * Handles command execution operations in the AgentBay cloud environment.\n */\nexport class Command {\n private session: Session;\n\n /**\n * Initialize a Command object.\n *\n * @param session - The Session instance that this Command belongs to.\n */\n constructor(session: Session) {\n this.session = session;\n }\n\n /**\n * Sanitizes error messages to remove sensitive information like API keys.\n *\n * @param error - The error to sanitize\n * @returns The sanitized error\n */\n private sanitizeError(error: any): any {\n if (!error) {\n return error;\n }\n\n const errorString = String(error);\n return errorString.replace(/Bearer\\s+[^\\s]+/g, \"Bearer [REDACTED]\");\n }\n\n /**\n * Execute a command in the session environment.\n * Corresponds to Python's execute_command() method\n *\n * @param command - The command to execute\n * @param timeoutMs - The timeout in milliseconds. Default is 1000ms.\n * @returns CommandResult with command output and requestId\n * @throws APIError if the operation fails.\n */\n async executeCommand(\n command: string,\n timeoutMs = 1000\n ): Promise<CommandResult> {\n try {\n const args = {\n command,\n timeout_ms: timeoutMs,\n };\n const result = await this.session.callMcpTool(\"shell\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n output: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n output: \"\",\n errorMessage: `Failed to execute command: ${error}`,\n };\n }\n }\n}\n","/**\n * Command templates for various AgentBay operations.\n *\n * This module contains shell command templates used by different modules\n * to execute operations in remote environments.\n *\n * Template naming convention:\n * - Use descriptive names that clearly indicate the operation\n * - Group templates by functionality (mobile, desktop, network, etc.)\n * - Use consistent parameter naming across similar templates\n *\n * Parameter conventions:\n * - Use snake_case for parameter names\n * - Include descriptive parameter names (e.g., lock_switch, package_list)\n * - Document expected parameter types and values\n */\n\n// ================================\n// Mobile Device Command Templates\n// ================================\n\n/**\n * Resolution lock template\n * Parameters:\n * lock_switch (string): \"1\" to enable lock, \"0\" to disable lock\n */\nexport const RESOLUTION_LOCK_TEMPLATE = \"setprop sys.wuying.lockres {lock_switch}\";\n\n/**\n * Application whitelist template\n * Parameters:\n * package_list (string): Newline-separated list of package names\n */\nexport const APP_WHITELIST_TEMPLATE = `cat > /data/system/pm_whitelist.txt << 'EOF'\n{package_list}\nEOF\nchmod 644 /data/system/pm_whitelist.txt\nsetprop rw.wy.pm_whitelist.refresh 1\nsetprop persist.wy.pm_blacklist.switch 2`;\n\n/**\n * Application blacklist template\n * Parameters:\n * package_list (string): Newline-separated list of package names\n */\nexport const APP_BLACKLIST_TEMPLATE = `cat > /data/system/pm_blacklist.txt << 'EOF'\n{package_list}\nEOF\nchmod 644 /data/system/pm_blacklist.txt\nsetprop rw.wy.pm_blacklist.refresh 1\nsetprop persist.wy.pm_blacklist.switch 1`;\n\n/**\n * Hide navigation bar template\n * Hides the system navigation bar by setting system property and restarting SystemUI\n */\nexport const HIDE_NAVIGATION_BAR_TEMPLATE = \"setprop persist.wy.hasnavibar false; killall com.android.systemui\";\n\n/**\n * Show navigation bar template\n * Shows the system navigation bar by setting system property and restarting SystemUI\n */\nexport const SHOW_NAVIGATION_BAR_TEMPLATE = \"setprop persist.wy.hasnavibar true; killall com.android.systemui\";\n\n/**\n * Uninstall blacklist template\n * Parameters:\n * package_list (string): Semicolon-separated list of package names\n */\nexport const UNINSTALL_BLACKLIST_TEMPLATE = \"setprop persist.wy.pm_lock \\\"{package_list}\\\"\";\n\n/**\n * Mobile command templates mapping for easy access\n */\nexport const MOBILE_COMMAND_TEMPLATES: Record<string, string> = {\n \"resolution_lock_enable\": \"setprop sys.wuying.lockres 1\",\n \"resolution_lock_disable\": \"setprop sys.wuying.lockres 0\",\n \"app_whitelist\": APP_WHITELIST_TEMPLATE,\n \"app_blacklist\": APP_BLACKLIST_TEMPLATE,\n \"hide_navigation_bar\": HIDE_NAVIGATION_BAR_TEMPLATE,\n \"show_navigation_bar\": SHOW_NAVIGATION_BAR_TEMPLATE,\n \"uninstall_blacklist\": UNINSTALL_BLACKLIST_TEMPLATE,\n};\n\n/**\n * Get a mobile command template by name\n * \n * @param templateName - The name of the template to retrieve\n * @returns The template string if found, undefined otherwise\n */\nexport function getMobileCommandTemplate(templateName: string): string | undefined {\n return MOBILE_COMMAND_TEMPLATES[templateName];\n}\n\n/**\n * Check if a mobile command template exists\n * \n * @param templateName - The name of the template to check\n * @returns True if the template exists, false otherwise\n */\nexport function hasMobileCommandTemplate(templateName: string): boolean {\n return templateName in MOBILE_COMMAND_TEMPLATES;\n}\n\n/**\n * Replace placeholders in a template with actual values\n * \n * @param template - The template string with placeholders\n * @param replacements - Object containing placeholder-value pairs\n * @returns The template with placeholders replaced\n */\nexport function replaceTemplatePlaceholders(\n template: string, \n replacements: Record<string, string>\n): string {\n let result = template;\n for (const [placeholder, value] of Object.entries(replacements)) {\n const placeholderPattern = new RegExp(`\\\\{${placeholder}\\\\}`, 'g');\n result = result.replace(placeholderPattern, value);\n }\n return result;\n}\n","export { Computer, BoolResult, CursorPosition, ScreenSize, ScreenshotResult } from './computer'; ","/**\n * Computer module for desktop UI automation.\n * Provides mouse, keyboard, and screen operations for desktop environments.\n */\n\nimport { OperationResult, WindowListResult, WindowInfoResult, BoolResult as WindowBoolResult } from \"../types/api-response\";\n\nexport enum MouseButton {\n LEFT = 'left',\n RIGHT = 'right',\n MIDDLE = 'middle',\n DOUBLE_LEFT = 'double_left'\n}\n\nexport enum ScrollDirection {\n UP = 'up',\n DOWN = 'down',\n LEFT = 'left',\n RIGHT = 'right'\n}\n\nexport interface BoolResult extends OperationResult {\n data?: boolean;\n}\n\nexport interface CursorPosition extends OperationResult {\n x: number;\n y: number;\n}\n\nexport interface ScreenSize extends OperationResult {\n width: number;\n height: number;\n dpiScalingFactor: number;\n}\n\nexport interface ScreenshotResult extends OperationResult {\n data: string; // Screenshot URL\n}\n\n// Session interface for Computer module\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ninterface ComputerSession {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n callMcpTool(toolName: string, args: Record<string, any>): Promise<any>;\n sessionId: string;\n getAPIKey(): string;\n getSessionId(): string;\n}\n\nexport class Computer {\n private session: ComputerSession;\n\n constructor(session: ComputerSession) {\n this.session = session;\n }\n\n /**\n * Click mouse at specified coordinates.\n */\n async clickMouse(x: number, y: number, button: MouseButton | string = MouseButton.LEFT): Promise<BoolResult> {\n const buttonStr = typeof button === 'string' ? button : button;\n const validButtons = Object.values(MouseButton);\n if (!validButtons.includes(buttonStr as MouseButton)) {\n throw new Error(`Invalid button '${buttonStr}'. Must be one of ${validButtons.join(', ')}`);\n }\n\n const args = { x, y, button: buttonStr };\n try {\n const result = await this.session.callMcpTool('click_mouse', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to click mouse: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Move mouse to specified coordinates.\n */\n async moveMouse(x: number, y: number): Promise<BoolResult> {\n const args = { x, y };\n try {\n const result = await this.session.callMcpTool('move_mouse', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to move mouse: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Drag mouse from one position to another.\n */\n async dragMouse(fromX: number, fromY: number, toX: number, toY: number, button: MouseButton | string = MouseButton.LEFT): Promise<BoolResult> {\n const buttonStr = typeof button === 'string' ? button : button;\n const validButtons = [MouseButton.LEFT, MouseButton.RIGHT, MouseButton.MIDDLE];\n if (!validButtons.includes(buttonStr as MouseButton)) {\n throw new Error(`Invalid button '${buttonStr}'. Must be one of ${validButtons.join(', ')}`);\n }\n\n const args = { from_x: fromX, from_y: fromY, to_x: toX, to_y: toY, button: buttonStr };\n try {\n const result = await this.session.callMcpTool('drag_mouse', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to drag mouse: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Scroll at specified coordinates.\n */\n async scroll(x: number, y: number, direction: ScrollDirection | string = ScrollDirection.UP, amount = 1): Promise<BoolResult> {\n const directionStr = typeof direction === 'string' ? direction : direction;\n const validDirections = Object.values(ScrollDirection);\n if (!validDirections.includes(directionStr as ScrollDirection)) {\n throw new Error(`Invalid direction '${directionStr}'. Must be one of ${validDirections.join(', ')}`);\n }\n\n const args = { x, y, direction: directionStr, amount };\n try {\n const result = await this.session.callMcpTool('scroll', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to scroll: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Input text.\n */\n async inputText(text: string): Promise<BoolResult> {\n const args = { text };\n try {\n const result = await this.session.callMcpTool('input_text', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to input text: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Press keys.\n */\n async pressKeys(keys: string[], hold = false): Promise<BoolResult> {\n const args = { keys, hold };\n try {\n const result = await this.session.callMcpTool('press_keys', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to press keys: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Release keys.\n */\n async releaseKeys(keys: string[]): Promise<BoolResult> {\n const args = { keys };\n try {\n const result = await this.session.callMcpTool('release_keys', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to release keys: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Get cursor position.\n */\n async getCursorPosition(): Promise<CursorPosition> {\n try {\n const result = await this.session.callMcpTool('get_cursor_position', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get cursor position',\n x: 0,\n y: 0\n };\n }\n\n // Parse JSON response from data field (callMcpTool already extracts content[0].text to data)\n const content = result.data;\n if (!content) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: 'No content in response',\n x: 0,\n y: 0\n };\n }\n\n try {\n const position = JSON.parse(content);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n x: position.x || 0,\n y: position.y || 0\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse cursor position: ${parseError}`,\n x: 0,\n y: 0\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get cursor position: ${error instanceof Error ? error.message : String(error)}`,\n x: 0,\n y: 0\n };\n }\n }\n\n /**\n * Get screen size.\n */\n async getScreenSize(): Promise<ScreenSize> {\n try {\n const result = await this.session.callMcpTool('get_screen_size', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get screen size',\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n\n // Parse JSON response from data field (callMcpTool already extracts content[0].text to data)\n const content = result.data;\n if (!content) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: 'No content in response',\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n\n try {\n const screenInfo = JSON.parse(content);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n width: screenInfo.width || 0,\n height: screenInfo.height || 0,\n dpiScalingFactor: screenInfo.dpiScalingFactor || 1.0\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse screen size: ${parseError}`,\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get screen size: ${error instanceof Error ? error.message : String(error)}`,\n width: 0,\n height: 0,\n dpiScalingFactor: 1.0\n };\n }\n }\n\n /**\n * Take a screenshot.\n */\n async screenshot(): Promise<ScreenshotResult> {\n try {\n const result = await this.session.callMcpTool('system_screenshot', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to take screenshot',\n data: ''\n };\n }\n\n const screenshotUrl = result.content?.[0]?.text || '';\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n data: screenshotUrl\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to take screenshot: ${error instanceof Error ? error.message : String(error)}`,\n data: ''\n };\n }\n }\n\n /**\n * Lists all root windows.\n */\n async listRootWindows(timeoutMs = 3000): Promise<WindowListResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.listRootWindows(timeoutMs);\n }\n\n /**\n * Gets the currently active window.\n */\n async getActiveWindow(timeoutMs = 3000): Promise<WindowInfoResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.getActiveWindow(timeoutMs);\n }\n\n /**\n * Activates the specified window.\n */\n async activateWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.activateWindow(windowId);\n }\n\n /**\n * Closes the specified window.\n */\n async closeWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.closeWindow(windowId);\n }\n\n /**\n * Maximizes the specified window.\n */\n async maximizeWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.maximizeWindow(windowId);\n }\n\n /**\n * Minimizes the specified window.\n */\n async minimizeWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.minimizeWindow(windowId);\n }\n\n /**\n * Restores the specified window.\n */\n async restoreWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.restoreWindow(windowId);\n }\n\n /**\n * Resizes the specified window.\n */\n async resizeWindow(windowId: number, width: number, height: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.resizeWindow(windowId, width, height);\n }\n\n /**\n * Makes the specified window fullscreen.\n */\n async fullscreenWindow(windowId: number): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.fullscreenWindow(windowId);\n }\n\n /**\n * Toggles focus mode on or off.\n */\n async focusMode(on: boolean): Promise<WindowBoolResult> {\n const { WindowManager } = await import('../window/window');\n const windowManager = new WindowManager(this.session);\n return windowManager.focusMode(on);\n }\n\n // Application Management Operations (delegated to existing application module)\n\n /**\n * Gets the list of installed applications.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async getInstalledApps(): Promise<any> {\n const { Application } = await import('../application/application');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const app = new Application(this.session as any);\n return app.getInstalledApps();\n }\n\n /**\n * Starts the specified application.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async startApp(startCmd: string, workDirectory = \"\"): Promise<any> {\n const { Application } = await import('../application/application');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const app = new Application(this.session as any);\n return app.startApp(startCmd, workDirectory);\n }\n\n /**\n * Stops an application by process name.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async stopAppByPName(pname: string): Promise<any> {\n const { Application } = await import('../application/application');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const app = new Application(this.session as any);\n return app.stopAppByPName(pname);\n }\n\n /**\n * Stops an application by process ID.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async stopAppByPID(pid: number): Promise<any> {\n const { Application } = await import('../application/application');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const app = new Application(this.session as any);\n return app.stopAppByPID(pid);\n }\n\n /**\n * Stops an application by stop command.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async stopAppByCmd(cmd: string): Promise<any> {\n const { Application } = await import('../application/application');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const app = new Application(this.session as any);\n return app.stopAppByCmd(cmd);\n }\n\n /**\n * Lists all visible applications.\n */\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n async listVisibleApps(): Promise<any> {\n const { Application } = await import('../application/application');\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const app = new Application(this.session as any);\n return app.listVisibleApps();\n }\n} ","import { Client } from \"./api/client\";\nimport { GetContextInfoRequest, SyncContextRequest } from \"./api/models/model\";\nimport { ApiResponse, extractRequestId } from \"./types/api-response\";\nimport {\n log,\n logError,\n logInfo,\n logDebug,\n logAPICall,\n logAPIResponseWithDetails,\n setRequestId,\n getRequestId,\n} from \"./utils/logger\";\n\nexport interface ContextStatusData {\n contextId: string;\n path: string;\n errorMessage: string;\n status: string;\n startTime: number;\n finishTime: number;\n taskType: string;\n}\n\nexport interface ContextStatusItem {\n type: string;\n data: string;\n}\n\nexport interface ContextInfoResult extends ApiResponse {\n success?: boolean;\n contextStatusData: ContextStatusData[];\n errorMessage?: string;\n}\n\nexport interface ContextSyncResult extends ApiResponse {\n success: boolean;\n errorMessage?: string;\n}\n\nexport type SyncCallback = (success: boolean) => void;\n\nexport interface SessionInterface {\n getAPIKey(): string;\n getClient(): Client;\n getSessionId(): string;\n}\n\nexport class ContextManager {\n private session: SessionInterface;\n\n constructor(session: SessionInterface) {\n this.session = session;\n }\n\n async info(): Promise<ContextInfoResult> {\n return this.infoWithParams();\n }\n\n async infoWithParams(\n contextId?: string,\n path?: string,\n taskType?: string\n ): Promise<ContextInfoResult> {\n const request = new GetContextInfoRequest({\n authorization: `Bearer ${this.session.getAPIKey()}`,\n sessionId: this.session.getSessionId(),\n });\n\n // Set optional parameters if provided\n if (contextId) {\n request.contextId = contextId;\n }\n if (path) {\n request.path = path;\n }\n if (taskType) {\n request.taskType = taskType;\n }\n\n // Log API request (matching Go version format)\n logAPICall(\"GetContextInfo\");\n let requestLog = `Request: SessionId=${request.sessionId}`;\n if (request.contextId) {\n requestLog += `, ContextId=${request.contextId}`;\n }\n if (request.path) {\n requestLog += `, Path=${request.path}`;\n }\n if (request.taskType) {\n requestLog += `, TaskType=${request.taskType}`;\n }\n logDebug(requestLog);\n\n try {\n const response = await this.session.getClient().getContextInfo(request);\n\n // Extract RequestID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for API-level errors\n if (response?.body?.success === false && response.body.code) {\n const errorMsg = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContextInfo\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n contextStatusData: [],\n errorMessage: errorMsg,\n };\n }\n\n // Parse the context status data\n const contextStatusData: ContextStatusData[] = [];\n if (response?.body?.data?.contextStatus) {\n try {\n // First, parse the outer array\n const contextStatusStr = response.body.data.contextStatus;\n const statusItems: ContextStatusItem[] = JSON.parse(contextStatusStr);\n\n // Process each item in the array\n for (const item of statusItems) {\n if (item.type === \"data\") {\n // Parse the inner data string\n const dataItems: ContextStatusData[] = JSON.parse(item.data);\n contextStatusData.push(...dataItems);\n }\n }\n } catch (error) {\n logError(\"Error parsing context status:\", error);\n }\n }\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n session_id: request.sessionId,\n context_count: contextStatusData.length,\n };\n if (request.contextId) {\n keyFields.context_id = request.contextId;\n }\n if (request.path) {\n keyFields.path = request.path;\n }\n if (request.taskType) {\n keyFields.task_type = request.taskType;\n }\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"GetContextInfo\", requestId, true, keyFields, fullResponse);\n\n return {\n requestId,\n success: true,\n contextStatusData,\n errorMessage: undefined,\n };\n } catch (error) {\n logError(\"Error calling GetContextInfo:\", error);\n throw new Error(`Failed to get context info: ${error}`);\n }\n }\n\n async sync(\n contextId?: string,\n path?: string,\n mode?: string,\n callback?: SyncCallback,\n maxRetries: number = 150,\n retryInterval: number = 1500\n ): Promise<ContextSyncResult> {\n const request = new SyncContextRequest({\n authorization: `Bearer ${this.session.getAPIKey()}`,\n sessionId: this.session.getSessionId(),\n });\n\n // Set optional parameters if provided\n if (contextId) {\n request.contextId = contextId;\n }\n if (path) {\n request.path = path;\n }\n if (mode) {\n request.mode = mode;\n }\n\n // Log API request (matching Go version format)\n logAPICall(\"SyncContext\");\n let requestLog = `Request: SessionId=${request.sessionId}`;\n if (request.contextId) {\n requestLog += `, ContextId=${request.contextId}`;\n }\n if (request.path) {\n requestLog += `, Path=${request.path}`;\n }\n if (request.mode) {\n requestLog += `, Mode=${request.mode}`;\n }\n logDebug(requestLog);\n\n try {\n const response = await this.session.getClient().syncContext(request);\n\n // Extract RequestID\n const requestId = extractRequestId(response) || \"\";\n\n // Check for API-level errors\n if (response?.body?.success === false && response.body.code) {\n const errorMsg = `[${response.body.code}] ${response.body.message || 'Unknown error'}`;\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"SyncContext\", requestId, false, undefined, fullResponse);\n return {\n requestId,\n success: false,\n errorMessage: errorMsg,\n };\n }\n\n let success = false;\n if (response?.body?.success !== undefined) {\n success = response.body.success;\n }\n\n // Log API response with key fields\n const keyFields: Record<string, any> = {\n session_id: request.sessionId,\n success: success,\n };\n if (request.contextId) {\n keyFields.context_id = request.contextId;\n }\n if (request.path) {\n keyFields.path = request.path;\n }\n if (request.mode) {\n keyFields.mode = request.mode;\n }\n const fullResponse = response.body ? JSON.stringify(response.body, null, 2) : \"\";\n logAPIResponseWithDetails(\"SyncContext\", requestId, success, keyFields, fullResponse);\n\n // If callback is provided, start polling in background (async mode)\n if (callback && success) {\n // Start polling in background without blocking\n this.pollForCompletion(callback, contextId, path, maxRetries, retryInterval)\n .catch((error) => {\n logError(\"Error in background polling:\", error);\n callback(false);\n });\n return {\n requestId,\n success,\n };\n }\n\n // If no callback, wait for completion (sync mode)\n if (success) {\n const finalSuccess = await this.pollForCompletionAsync(\n contextId,\n path,\n maxRetries,\n retryInterval\n );\n return {\n requestId,\n success: finalSuccess,\n };\n }\n\n return {\n requestId,\n success,\n };\n } catch (error) {\n logError(\"Error calling SyncContext:\", error);\n throw new Error(`Failed to sync context: ${error}`);\n }\n }\n\n /**\n * Polls the info interface to check if sync is completed and calls callback.\n */\n private async pollForCompletion(\n callback: SyncCallback,\n contextId?: string,\n path?: string,\n maxRetries: number = 150,\n retryInterval: number = 1500\n ): Promise<void> {\n for (let retry = 0; retry < maxRetries; retry++) {\n try {\n // Get context status data\n const infoResult = await this.infoWithParams(contextId, path);\n\n // Check if all sync tasks are completed\n let allCompleted = true;\n let hasFailure = false;\n let hasSyncTasks = false;\n\n for (const item of infoResult.contextStatusData) {\n // We only care about sync tasks (upload/download)\n if (item.taskType !== \"upload\" && item.taskType !== \"download\") {\n continue;\n }\n\n hasSyncTasks = true;\n logDebug(`Sync task ${item.contextId} status: ${item.status}, path: ${item.path}`);\n\n if (item.status !== \"Success\" && item.status !== \"Failed\") {\n allCompleted = false;\n break;\n }\n\n if (item.status === \"Failed\") {\n hasFailure = true;\n logError(`Sync failed for context ${item.contextId}: ${item.errorMessage}`);\n }\n }\n\n if (allCompleted || !hasSyncTasks) {\n // All tasks completed or no sync tasks found\n if (hasFailure) {\n logInfo(\"Context sync completed with failures\");\n callback(false);\n } else if (hasSyncTasks) {\n logInfo(\"Context sync completed successfully\");\n callback(true);\n } else {\n logDebug(\"No sync tasks found\");\n callback(true);\n }\n return; // Exit the function immediately after calling callback\n }\n\n logDebug(`Waiting for context sync to complete, attempt ${retry + 1}/${maxRetries}`);\n await this.sleep(retryInterval);\n } catch (error) {\n logError(`Error checking context status on attempt ${retry + 1}:`, error);\n await this.sleep(retryInterval);\n }\n }\n\n // If we've exhausted all retries, call callback with failure\n logError(`Context sync polling timed out after ${maxRetries} attempts`);\n callback(false);\n }\n\n /**\n * Async version of polling for sync completion.\n */\n private async pollForCompletionAsync(\n contextId?: string,\n path?: string,\n maxRetries: number = 150,\n retryInterval: number = 1500\n ): Promise<boolean> {\n for (let retry = 0; retry < maxRetries; retry++) {\n try {\n // Get context status data\n const infoResult = await this.infoWithParams(contextId, path);\n\n // Check if all sync tasks are completed\n let allCompleted = true;\n let hasFailure = false;\n let hasSyncTasks = false;\n\n for (const item of infoResult.contextStatusData) {\n // We only care about sync tasks (upload/download)\n if (item.taskType !== \"upload\" && item.taskType !== \"download\") {\n continue;\n }\n\n hasSyncTasks = true;\n logDebug(`Sync task ${item.contextId} status: ${item.status}, path: ${item.path}`);\n\n if (item.status !== \"Success\" && item.status !== \"Failed\") {\n allCompleted = false;\n break;\n }\n\n if (item.status === \"Failed\") {\n hasFailure = true;\n logError(`Sync failed for context ${item.contextId}: ${item.errorMessage}`);\n }\n }\n\n if (allCompleted || !hasSyncTasks) {\n // All tasks completed or no sync tasks found\n if (hasFailure) {\n logInfo(\"Context sync completed with failures\");\n return false;\n } else if (hasSyncTasks) {\n logInfo(\"Context sync completed successfully\");\n return true;\n } else {\n logDebug(\"No sync tasks found\");\n return true;\n }\n }\n\n logDebug(`Waiting for context sync to complete, attempt ${retry + 1}/${maxRetries}`);\n await this.sleep(retryInterval);\n } catch (error) {\n logError(`Error checking context status on attempt ${retry + 1}:`, error);\n await this.sleep(retryInterval);\n }\n }\n\n // If we've exhausted all retries, return failure\n logError(`Context sync polling timed out after ${maxRetries} attempts`);\n return false;\n }\n\n /**\n * Sleep utility function for TypeScript\n */\n private sleep(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms));\n }\n}\n\nexport function newContextManager(session: SessionInterface): ContextManager {\n return new ContextManager(session);\n}\n","import {\n BoolResult,\n FileInfoResult,\n DirectoryListResult,\n FileContentResult,\n MultipleFileContentResult,\n FileSearchResult,\n ApiResponse,\n} from \"../types/api-response\";\nimport { UploadResult, DownloadResult } from \"./file-transfer\";\nimport { FileTransfer } from \"./file-transfer\";\nimport { Session } from \"../session\";\nimport { log, logWarn } from \"../utils/logger\";\n\n// Default chunk size for large file operations (60KB)\nconst DEFAULT_CHUNK_SIZE = 60 * 1024;\n\n/**\n * Represents a single file change event\n */\nexport interface FileChangeEvent {\n eventType: string; // \"create\", \"modify\", \"delete\"\n path: string;\n pathType: string; // \"file\", \"directory\"\n}\n\n/**\n * Result of file change detection operations\n */\nexport interface FileChangeResult extends ApiResponse {\n events: FileChangeEvent[];\n rawData: string;\n}\n\n/**\n * Helper functions for FileChangeEvent\n */\nexport class FileChangeEventHelper {\n static toString(event: FileChangeEvent): string {\n return `FileChangeEvent(eventType='${event.eventType}', path='${event.path}', pathType='${event.pathType}')`;\n }\n\n static toDict(event: FileChangeEvent): Record<string, string> {\n return {\n eventType: event.eventType,\n path: event.path,\n pathType: event.pathType,\n };\n }\n\n static fromDict(data: Record<string, any>): FileChangeEvent {\n return {\n eventType: data.eventType || \"\",\n path: data.path || \"\",\n pathType: data.pathType || \"\",\n };\n }\n}\n\n/**\n * Helper functions for FileChangeResult\n */\nexport class FileChangeResultHelper {\n static hasChanges(result: FileChangeResult): boolean {\n return result.events.length > 0;\n }\n\n static getModifiedFiles(result: FileChangeResult): string[] {\n return result.events\n .filter(event => event.eventType === \"modify\" && event.pathType === \"file\")\n .map(event => event.path);\n }\n\n static getCreatedFiles(result: FileChangeResult): string[] {\n return result.events\n .filter(event => event.eventType === \"create\" && event.pathType === \"file\")\n .map(event => event.path);\n }\n\n static getDeletedFiles(result: FileChangeResult): string[] {\n return result.events\n .filter(event => event.eventType === \"delete\" && event.pathType === \"file\")\n .map(event => event.path);\n }\n}\n\n/**\n * FileInfo represents information about a file or directory\n */\nexport interface FileInfo {\n name: string;\n path: string;\n size: number;\n isDirectory: boolean;\n modTime: string;\n mode: string;\n owner?: string;\n group?: string;\n}\n\n/**\n * DirectoryEntry represents an entry in a directory listing\n */\nexport interface DirectoryEntry {\n name: string;\n isDirectory: boolean;\n}\n\n/**\n * Parse a file info string into a FileInfo object\n *\n * @param fileInfoStr - The file info string to parse\n * @returns A FileInfo object\n */\nfunction parseFileInfo(fileInfoStr: string): FileInfo {\n const result: FileInfo = {\n name: \"\",\n path: \"\",\n size: 0,\n isDirectory: false,\n modTime: \"\",\n mode: \"\",\n };\n\n const lines = fileInfoStr.split(\"\\n\");\n for (const line of lines) {\n if (line.includes(\":\")) {\n const [key, value] = line.split(\":\", 2).map((part) => part.trim());\n\n switch (key) {\n case \"name\":\n result.name = value;\n break;\n case \"path\":\n result.path = value;\n break;\n case \"size\":\n result.size = parseInt(value, 10);\n break;\n case \"isDirectory\":\n result.isDirectory = value === \"true\";\n break;\n case \"modTime\":\n result.modTime = value;\n break;\n case \"mode\":\n result.mode = value;\n break;\n case \"owner\":\n result.owner = value;\n break;\n case \"group\":\n result.group = value;\n break;\n }\n }\n }\n\n return result;\n}\n\n/**\n * Parse a directory listing string into an array of DirectoryEntry objects\n *\n * @param text - The directory listing text to parse\n * @returns An array of DirectoryEntry objects\n */\nfunction parseDirectoryListing(text: string): DirectoryEntry[] {\n const result: DirectoryEntry[] = [];\n const lines = text.split(\"\\n\");\n\n for (const line of lines) {\n const trimmedLine = line.trim();\n if (trimmedLine === \"\") {\n continue;\n }\n\n if (trimmedLine.startsWith(\"[DIR]\")) {\n result.push({\n isDirectory: true,\n name: trimmedLine.replace(\"[DIR]\", \"\").trim(),\n });\n } else if (trimmedLine.startsWith(\"[FILE]\")) {\n result.push({\n isDirectory: false,\n name: trimmedLine.replace(\"[FILE]\", \"\").trim(),\n });\n }\n }\n\n return result;\n}\n\n/**\n * Handles file operations in the AgentBay cloud environment.\n */\nexport class FileSystem {\n private session: Session;\n \n private _fileTransfer: FileTransfer | null = null;\n\n /**\n * Initialize a FileSystem object.\n *\n * @param session - The Session instance that this FileSystem belongs to.\n */\n constructor(session: Session) {\n this.session = session;\n }\n\n /**\n * Ensure FileTransfer is initialized with the current session.\n * \n * @returns The FileTransfer instance\n */\n private _ensureFileTransfer(): FileTransfer {\n if (this._fileTransfer === null) {\n // Get the agent_bay instance from the session\n const agentBay = this.session.getAgentBay();\n if (agentBay === undefined) {\n throw new Error(\"FileTransfer requires an AgentBay instance\");\n }\n \n this._fileTransfer = new FileTransfer(agentBay, this.session);\n }\n \n return this._fileTransfer;\n }\n\n /**\n * Creates a new directory at the specified path.\n * Corresponds to Python's create_directory() method\n *\n * @param path - Path to the directory to create.\n * @returns BoolResult with creation result and requestId\n */\n async createDirectory(path: string): Promise<BoolResult> {\n try {\n const args = {\n path,\n };\n\n const result = await this.session.callMcpTool(\n \"create_directory\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to create directory: ${error}`,\n };\n }\n }\n\n /**\n * Edits a file by replacing occurrences of oldText with newText.\n * Corresponds to Python's edit_file() method\n *\n * @param path - Path to the file to edit.\n * @param edits - Array of edit operations, each containing oldText and newText.\n * @param dryRun - Optional: If true, preview changes without applying them.\n * @returns BoolResult with edit result and requestId\n */\n async editFile(\n path: string,\n edits: Array<{ oldText: string; newText: string }>,\n dryRun = false\n ): Promise<BoolResult> {\n try {\n const args = {\n path,\n edits,\n dryRun,\n };\n\n const result = await this.session.callMcpTool(\n \"edit_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to edit file: ${error}`,\n };\n }\n }\n\n /**\n * Gets information about a file or directory.\n * Corresponds to Python's get_file_info() method\n *\n * @param path - Path to the file or directory to inspect.\n * @returns FileInfoResult with file info and requestId\n */\n async getFileInfo(path: string): Promise<FileInfoResult> {\n try {\n const args = {\n path,\n };\n\n const result = await this.session.callMcpTool(\n \"get_file_info\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n fileInfo: {},\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse and return the file info\n if (!result.data) {\n return {\n requestId: result.requestId,\n success: false,\n fileInfo: {},\n errorMessage: \"Empty response from get_file_info\",\n };\n }\n\n const fileInfo = parseFileInfo(result.data);\n\n return {\n requestId: result.requestId,\n success: true,\n fileInfo,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to get file info: ${error}`,\n };\n }\n }\n\n /**\n * Lists the contents of a directory.\n * Corresponds to Python's list_directory() method\n *\n * @param path - Path to the directory to list.\n * @returns DirectoryListResult with directory entries and requestId\n */\n async listDirectory(path: string): Promise<DirectoryListResult> {\n try {\n const args = {\n path,\n };\n\n const result = await this.session.callMcpTool(\n \"list_directory\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n entries: [],\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse the text content into directory entries\n const entries = result.data\n ? parseDirectoryListing(result.data)\n : [];\n\n return {\n requestId: result.requestId,\n success: true,\n entries,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n entries: [],\n errorMessage: `Failed to list directory: ${error}`,\n };\n }\n }\n\n /**\n * Moves a file or directory from source to destination.\n * Corresponds to Python's move_file() method\n *\n * @param source - Path to the source file or directory.\n * @param destination - Path to the destination file or directory.\n * @returns BoolResult with move result and requestId\n */\n async moveFile(source: string, destination: string): Promise<BoolResult> {\n try {\n const args = {\n source,\n destination,\n };\n\n const result = await this.session.callMcpTool(\n \"move_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to move file: ${error}`,\n };\n }\n }\n\n /**\n * Internal method to read a file chunk. Used for chunked file operations.\n *\n * @param path - Path to the file to read.\n * @param offset - Optional: Byte offset to start reading from (0-based).\n * @param length - Optional: Number of bytes to read. If 0, reads the entire file from offset.\n * @returns FileContentResult with file content and requestId\n */\n private async readFileChunk(\n path: string,\n offset = 0,\n length = 0\n ): Promise<FileContentResult> {\n try {\n const args: any = {\n path,\n };\n\n if (offset > 0) {\n args.offset = offset;\n }\n\n if (length > 0) {\n args.length = length;\n }\n\n const result = await this.session.callMcpTool(\n \"read_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n content: \"\",\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n content: result.data || \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to read file: ${error}`,\n };\n }\n }\n\n /**\n * Reads the content of multiple files.\n * Corresponds to Python's read_multiple_files() method\n *\n * @param paths - Array of file paths to read.\n * @returns MultipleFileContentResult with file contents and requestId\n */\n async readMultipleFiles(paths: string[]): Promise<MultipleFileContentResult> {\n try {\n const args = {\n paths,\n };\n\n const result = await this.session.callMcpTool(\n \"read_multiple_files\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n contents: {},\n errorMessage: result.errorMessage,\n };\n }\n\n const fileContents: Record<string, string> = {};\n\n if (result.data) {\n // Parse the response into a map of file paths to contents\n const lines = result.data.split(\"\\n\");\n let currentPath = \"\";\n let currentContent: string[] = [];\n\n for (const line of lines) {\n // Check if this line contains a file path (ends with a colon)\n const colonIndex = line.indexOf(\":\");\n if (\n colonIndex > 0 &&\n currentPath === \"\" &&\n !line.substring(0, colonIndex).includes(\" \")\n ) {\n // Extract path (everything before the first colon)\n const path = line.substring(0, colonIndex).trim();\n\n // Start collecting content (everything after the colon)\n currentPath = path;\n\n // If there's content on the same line after the colon, add it\n if (line.length > colonIndex + 1) {\n const contentStart = line.substring(colonIndex + 1).trim();\n if (contentStart) {\n currentContent.push(contentStart);\n }\n }\n } else if (line === \"---\") {\n // Save the current file content\n if (currentPath) {\n fileContents[currentPath] = currentContent.join(\"\\n\");\n currentPath = \"\";\n currentContent = [];\n }\n } else if (currentPath) {\n // If we're collecting content for a path, add this line\n currentContent.push(line);\n }\n }\n\n // Save the last file content if exists\n if (currentPath) {\n fileContents[currentPath] = currentContent.join(\"\\n\");\n }\n\n // Trim trailing newlines from file contents to match expected test values\n for (const path in fileContents) {\n fileContents[path] = fileContents[path].replace(/\\n+$/, \"\");\n }\n }\n\n return {\n requestId: result.requestId,\n success: true,\n contents: fileContents,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n contents: {},\n errorMessage: `Failed to read multiple files: ${error}`,\n };\n }\n }\n\n /**\n * Searches for files in a directory that match a pattern.\n * Corresponds to Python's search_files() method\n *\n * @param path - Path to the directory to search in.\n * @param pattern - Pattern to search for. Supports glob patterns.\n * @param excludePatterns - Optional: Array of patterns to exclude.\n * @returns FileSearchResult with search results and requestId\n */\n async searchFiles(\n path: string,\n pattern: string,\n excludePatterns: string[] = []\n ): Promise<FileSearchResult> {\n try {\n const args: any = {\n path,\n pattern,\n };\n\n if (excludePatterns.length > 0) {\n args.excludePatterns = excludePatterns;\n }\n\n const result = await this.session.callMcpTool(\n \"search_files\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n matches: [],\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse the text content into search results\n let searchResults: string[] = [];\n if (result.data) {\n // Split by newlines and filter out empty lines\n searchResults = result.data\n .split(\"\\n\")\n .map((line) => line.trim())\n .filter((line) => line !== \"\");\n }\n\n return {\n requestId: result.requestId,\n success: true,\n matches: searchResults,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n matches: [],\n errorMessage: `Failed to search files: ${error}`,\n };\n }\n }\n\n /**\n * Internal method to write a file chunk. Used for chunked file operations.\n *\n * @param path - Path to the file to write.\n * @param content - Content to write to the file.\n * @param mode - Optional: Write mode. One of \"overwrite\", \"append\", or \"create_new\". Default is \"overwrite\".\n * @returns BoolResult with write result and requestId\n */\n private async writeFileChunk(\n path: string,\n content: string,\n mode = \"overwrite\"\n ): Promise<BoolResult> {\n try {\n // Validate mode\n const validModes = [\"overwrite\", \"append\", \"create_new\"];\n if (!validModes.includes(mode)) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Invalid mode: ${mode}. Must be one of ${validModes.join(\n \", \"\n )}`,\n };\n }\n\n const args = {\n path,\n content,\n mode,\n };\n\n const result = await this.session.callMcpTool(\n \"write_file\",\n args\n );\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to write file: ${error}`,\n };\n }\n }\n\n /**\n * Reads the contents of a file. Automatically handles large files by chunking.\n *\n * @param path - Path to the file to read.\n * @returns FileContentResult with complete file content and requestId\n */\n async readFile(\n path: string\n ): Promise<FileContentResult> {\n const chunkSize = DEFAULT_CHUNK_SIZE;\n try {\n // First get the file info\n const fileInfoResult = await this.getFileInfo(path);\n\n if (!fileInfoResult.success) {\n return {\n requestId: fileInfoResult.requestId,\n success: false,\n content: \"\",\n errorMessage: fileInfoResult.errorMessage,\n };\n }\n\n // Check if file exists and is a file (not a directory)\n if (!fileInfoResult.fileInfo || fileInfoResult.fileInfo.isDirectory) {\n return {\n requestId: fileInfoResult.requestId,\n success: false,\n content: \"\",\n errorMessage: `Path does not exist or is a directory: ${path}`,\n };\n }\n\n // Get size from the fileInfo object\n const fileSize = fileInfoResult.fileInfo.size || 0;\n\n if (fileSize === 0) {\n return {\n requestId: fileInfoResult.requestId,\n success: true,\n content: \"\",\n };\n }\n\n // Read the file in chunks\n let result = \"\";\n let offset = 0;\n let chunkCount = 0;\n\n while (offset < fileSize) {\n // Calculate how much to read in this chunk\n let length = chunkSize;\n if (offset + length > fileSize) {\n length = fileSize - offset;\n }\n\n try {\n // Read the chunk\n const chunkResult = await this.readFileChunk(path, offset, length);\n\n if (!chunkResult.success) {\n return chunkResult; // Return the error\n }\n\n // Extract the actual content from the response\n result += chunkResult.content;\n\n // Move to the next chunk\n offset += length;\n chunkCount++;\n } catch (error) {\n return {\n requestId: fileInfoResult.requestId,\n success: false,\n content: \"\",\n errorMessage: `Error reading chunk at offset ${offset}: ${error}`,\n };\n }\n }\n\n return {\n requestId: fileInfoResult.requestId,\n success: true,\n content: result,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to read large file: ${error}`,\n };\n }\n }\n\n /**\n * Writes content to a file. Automatically handles large files by chunking.\n *\n * @param path - Path to the file to write.\n * @param content - Content to write to the file.\n * @param mode - Optional: Write mode. One of \"overwrite\", \"append\", or \"create_new\". Default is \"overwrite\".\n * @returns BoolResult indicating success or failure with requestId\n */\n async writeFile(\n path: string,\n content: string,\n mode = \"overwrite\"\n ): Promise<BoolResult> {\n const chunkSize = DEFAULT_CHUNK_SIZE;\n try {\n const contentLen = content.length;\n\n // If content is small enough, use the regular writeFileChunk method\n if (contentLen <= chunkSize) {\n return await this.writeFileChunk(path, content, mode);\n }\n\n // Write the first chunk with the specified mode\n const firstChunkEnd = Math.min(chunkSize, contentLen);\n\n const firstResult = await this.writeFileChunk(\n path,\n content.substring(0, firstChunkEnd),\n mode\n );\n\n if (!firstResult.success) {\n return firstResult;\n }\n\n // Write the remaining chunks with \"append\" mode\n let chunkCount = 1; // Already wrote first chunk\n for (let offset = firstChunkEnd; offset < contentLen; ) {\n const end = Math.min(offset + chunkSize, contentLen);\n\n const chunkResult = await this.writeFileChunk(\n path,\n content.substring(offset, end),\n \"append\"\n );\n\n if (!chunkResult.success) {\n return chunkResult;\n }\n\n offset = end;\n chunkCount++;\n }\n\n return {\n requestId: firstResult.requestId,\n success: true,\n data: true,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n errorMessage: `Failed to write large file: ${error}`,\n };\n }\n }\n\n /**\n * Get file change information for the specified directory path\n */\n async getFileChange(path: string): Promise<FileChangeResult> {\n try {\n const args = { path };\n const result = await this.session.callMcpTool(\"get_file_change\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n events: [],\n rawData: result.data || \"\",\n errorMessage: result.errorMessage,\n };\n }\n\n // Parse the file change events\n const events = this.parseFileChangeData(result.data);\n\n return {\n requestId: result.requestId,\n success: true,\n events,\n rawData: result.data,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n events: [],\n rawData: \"\",\n errorMessage: `Failed to get file change: ${error}`,\n };\n }\n }\n\n /**\n * Parse raw JSON data into FileChangeEvent array\n */\n private parseFileChangeData(rawData: string): FileChangeEvent[] {\n const events: FileChangeEvent[] = [];\n \n try {\n const changeData = JSON.parse(rawData);\n if (Array.isArray(changeData)) {\n for (const eventDict of changeData) {\n if (typeof eventDict === \"object\" && eventDict !== null) {\n const event = FileChangeEventHelper.fromDict(eventDict);\n events.push(event);\n }\n }\n }\n } catch (error) {\n console.warn(`Failed to parse JSON data: ${error}`);\n }\n \n return events;\n }\n\n /**\n * Watch a directory for file changes and call the callback function when changes occur\n */\n async watchDirectory(\n path: string,\n callback: (events: FileChangeEvent[]) => void,\n interval = 500,\n signal?: AbortSignal\n ): Promise<void> {\n console.log(`Starting directory monitoring for: ${path}`);\n console.log(`Polling interval: ${interval} ms`);\n\n const monitor = async () => {\n while (!signal?.aborted) {\n try {\n const result = await this.getFileChange(path);\n\n if (result.success && result.events.length > 0) {\n console.log(`Detected ${result.events.length} file changes:`);\n for (const event of result.events) {\n console.log(` - ${FileChangeEventHelper.toString(event)}`);\n }\n\n try {\n callback(result.events);\n } catch (error) {\n console.error(`Error in callback function: ${error}`);\n }\n } else if (!result.success) {\n console.error(`Error monitoring directory: ${result.errorMessage}`);\n }\n\n // Wait for next poll\n await new Promise((resolve) => {\n const timeoutId = setTimeout(resolve, interval);\n signal?.addEventListener(\"abort\", () => {\n clearTimeout(timeoutId);\n resolve(void 0);\n });\n });\n } catch (error) {\n console.error(`Unexpected error in directory monitoring: ${error}`);\n await new Promise((resolve) => setTimeout(resolve, interval));\n }\n }\n\n console.log(`Stopped monitoring directory: ${path}`);\n };\n\n return monitor();\n }\n\n /**\n * Upload a file from local to remote path using pre-signed URLs.\n * This is a synchronous wrapper around the FileTransfer.upload method.\n *\n * @param localPath - Local file path to upload\n * @param remotePath - Remote file path to upload to\n * @param options - Optional parameters\n * @returns UploadResult with upload result and requestId\n */\n async uploadFile(\n localPath: string,\n remotePath: string,\n options?: {\n contentType?: string;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesTransferred: number) => void;\n }\n ): Promise<any> {\n try {\n // Ensure FileTransfer is initialized\n const fileTransfer = this._ensureFileTransfer();\n \n // Perform upload\n const result = await fileTransfer.upload(localPath, remotePath, options);\n \n // If upload was successful, delete the file from OSS\n if (result.success && (this.session as any).fileTransferContextId) {\n const contextId = (this.session as any).fileTransferContextId;\n if (contextId) {\n try {\n // Delete the uploaded file from OSS\n const deleteResult = await (this.session as any).agentBay.context.deleteFile(contextId, remotePath);\n if (!deleteResult.success) {\n logWarn(`Warning: Failed to delete uploaded file from OSS: ${deleteResult}`);\n }\n } catch (deleteError: any) {\n logWarn(`Warning: Error deleting uploaded file from OSS: ${deleteError}`);\n }\n }\n }\n \n return result;\n } catch (error) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: `Upload failed: ${error}`,\n };\n }\n }\n\n /**\n * Download a file from remote path to local path using pre-signed URLs.\n * This is a synchronous wrapper around the FileTransfer.download method.\n *\n * @param remotePath - Remote file path to download from\n * @param localPath - Local file path to download to\n * @param options - Optional parameters\n * @returns DownloadResult with download result and requestId\n */\n async downloadFile(\n remotePath: string,\n localPath: string,\n options?: {\n overwrite?: boolean;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesReceived: number) => void;\n }\n ): Promise<any> {\n try {\n // Ensure FileTransfer is initialized\n const fileTransfer = this._ensureFileTransfer();\n \n // Perform download\n const result = await fileTransfer.download(remotePath, localPath, options);\n \n // If download was successful, delete the file from OSS\n if (result.success && (this.session as any).fileTransferContextId) {\n const contextId = (this.session as any).fileTransferContextId;\n if (contextId) {\n try {\n // Delete the downloaded file from OSS\n const deleteResult = await (this.session as any).agentBay.context.deleteFile(contextId, remotePath);\n if (!deleteResult.success) {\n logWarn(`Warning: Failed to delete downloaded file from OSS: ${deleteResult}`);\n }\n } catch (deleteError: any) {\n logWarn(`Warning: Error deleting downloaded file from OSS: ${deleteError}`);\n }\n }\n }\n \n return result;\n } catch (error) {\n return {\n success: false,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download failed: ${error}`,\n };\n }\n }\n}\n","import { AgentBay } from \"../agent-bay\";\nimport { Session } from \"../session\";\nimport { ContextService } from \"../context\";\nimport { FileUrlResult, OperationResult } from \"../types/api-response\";\nimport * as fs from \"fs\";\nimport * as path from \"path\";\nimport fetch from \"node-fetch\";\nimport { log, logDebug, logInfo } from \"../utils/logger\";\n\n/**\n * Result structure for file upload operations.\n */\nexport interface UploadResult {\n /** Whether the upload was successful */\n success: boolean;\n /** Request ID for getting the upload URL */\n requestIdUploadUrl?: string;\n /** Request ID for sync operation */\n requestIdSync?: string;\n /** HTTP status code */\n httpStatus?: number;\n /** ETag of the uploaded file */\n etag?: string;\n /** Number of bytes sent */\n bytesSent: number;\n /** Remote file path */\n path: string;\n /** Error message if upload failed */\n error?: string;\n}\n\n/**\n * Result structure for file download operations.\n */\nexport interface DownloadResult {\n /** Whether the download was successful */\n success: boolean;\n /** Request ID for getting the download URL */\n requestIdDownloadUrl?: string;\n /** Request ID for sync operation */\n requestIdSync?: string;\n /** HTTP status code */\n httpStatus?: number;\n /** Number of bytes received */\n bytesReceived: number;\n /** Remote file path */\n path: string;\n /** Local file path where file was saved */\n localPath: string;\n /** Error message if download failed */\n error?: string;\n}\n\n/**\n * FileTransfer provides pre-signed URL upload/download functionality between local and OSS,\n * with integration to Session Context synchronization.\n * \n * Prerequisites and Constraints:\n * - Session must be associated with the corresponding context_id and path through \n * CreateSessionParams.contextSyncs, and remotePath should fall within that \n * synchronization path (or conform to backend path rules).\n * - Requires available AgentBay context service (agentBay.context) and session context.\n */\nexport class FileTransfer {\n private agentBay: AgentBay;\n private contextSvc: ContextService;\n private session: Session;\n private httpTimeout: number;\n private followRedirects: boolean;\n private contextId: string;\n\n // Task completion states (for compatibility)\n private finishedStates = new Set([\"success\", \"successful\", \"ok\", \"finished\", \"done\", \"completed\", \"complete\"]);\n\n /**\n * Initialize FileTransfer with AgentBay client and session.\n * \n * @param agentBay - AgentBay instance for context service access\n * @param session - Created session object for context operations\n * @param httpTimeout - HTTP request timeout in seconds (default: 60.0)\n * @param followRedirects - Whether to follow HTTP redirects (default: true)\n */\n constructor(\n agentBay: AgentBay,\n session: Session,\n httpTimeout = 60.0,\n followRedirects = true\n ) {\n this.agentBay = agentBay;\n this.contextSvc = agentBay.context;\n this.session = session;\n this.httpTimeout = httpTimeout;\n this.followRedirects = followRedirects;\n this.contextId = session.fileTransferContextId || \"\";\n }\n\n /**\n * Upload workflow:\n * 1) Get OSS pre-signed URL via context.getFileUploadUrl\n * 2) Upload local file to OSS using the URL (HTTP PUT)\n * 3) Trigger session.context.sync(mode=\"download\") to sync OSS objects to cloud disk\n * 4) If wait=true, poll session.context.info until upload task reaches completion or timeout\n *\n * Returns UploadResult containing request_ids, HTTP status, ETag and other information.\n */\n async upload(\n localPath: string,\n remotePath: string,\n options?: {\n contentType?: string;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesTransferred: number) => void;\n }\n ): Promise<UploadResult> {\n const {\n contentType = null,\n wait = true,\n waitTimeout = 30.0,\n pollInterval = 1.5,\n progressCb = undefined\n } = options || {};\n\n try {\n // 0. Parameter validation\n if (!fs.existsSync(localPath)) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: `Local file not found: ${localPath}`\n };\n }\n\n if (!this.contextId) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: \"No context ID\"\n };\n }\n\n // 1. Get pre-signed upload URL\n const urlRes = await this.contextSvc.getFileUploadUrl(this.contextId, remotePath);\n if (!urlRes.success || !urlRes.url) {\n return {\n success: false,\n requestIdUploadUrl: urlRes.requestId,\n bytesSent: 0,\n path: remotePath,\n error: `getFileUploadUrl failed: ${urlRes.url || \"unknown error\"}`\n };\n }\n\n const uploadUrl = urlRes.url;\n const reqIdUpload = urlRes.requestId;\n\n logDebug(`Uploading ${localPath} to ${uploadUrl}`);\n\n // 2. PUT upload to pre-signed URL\n try {\n const { httpStatus, etag, bytesSent } = await this.putFile(\n uploadUrl,\n localPath,\n contentType,\n progressCb\n );\n \n logInfo(`Upload completed with HTTP ${httpStatus}`);\n if (httpStatus && ![200, 201, 204].includes(httpStatus)) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n httpStatus,\n etag,\n bytesSent,\n path: remotePath,\n error: `Upload failed with HTTP ${httpStatus}`\n };\n }\n } catch (e: any) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n bytesSent: 0,\n path: remotePath,\n error: `Upload exception: ${e.message || e}`\n };\n }\n\n // 3. Trigger sync to cloud disk (download mode), download from oss to cloud disk\n let reqIdSync: string | undefined;\n try {\n logDebug(\"Triggering sync to cloud disk\");\n reqIdSync = await this.awaitSync(\"download\", remotePath, this.contextId);\n } catch (e: any) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n requestIdSync: reqIdSync,\n httpStatus: 200, // Assuming previous step succeeded\n etag: \"\", // Assuming previous step succeeded\n bytesSent: fs.statSync(localPath).size, // Assuming previous step succeeded\n path: remotePath,\n error: `session.context.sync(upload) failed: ${e.message || e}`\n };\n }\n\n logInfo(`Sync request ID: ${reqIdSync}`);\n \n // 4. Optionally wait for task completion\n if (wait) {\n const { success, error } = await this.waitForTask({\n contextId: this.contextId,\n remotePath,\n taskType: \"download\",\n timeout: waitTimeout,\n interval: pollInterval\n });\n \n if (!success) {\n return {\n success: false,\n requestIdUploadUrl: reqIdUpload,\n requestIdSync: reqIdSync,\n httpStatus: 200, // Assuming previous step succeeded\n etag: \"\", // Assuming previous step succeeded\n bytesSent: fs.statSync(localPath).size, // Assuming previous step succeeded\n path: remotePath,\n error: `Upload sync not finished: ${error || \"timeout or unknown\"}`\n };\n }\n }\n\n return {\n success: true,\n requestIdUploadUrl: reqIdUpload,\n requestIdSync: reqIdSync,\n httpStatus: 200,\n etag: \"\",\n bytesSent: fs.statSync(localPath).size,\n path: remotePath\n };\n } catch (e: any) {\n return {\n success: false,\n bytesSent: 0,\n path: remotePath,\n error: `Upload failed: ${e.message || e}`\n };\n }\n }\n\n /**\n * Download workflow:\n * 1) Trigger session.context.sync(mode=\"upload\") to sync cloud disk data to OSS\n * 2) Get pre-signed download URL via context.getFileDownloadUrl\n * 3) Download the file and save to local localPath\n * 4) If wait=true, wait for download task to reach completion after step 1 \n * (ensuring backend has prepared the download object)\n *\n * Returns DownloadResult containing sync and download request_ids, HTTP status, byte count, etc.\n */\n async download(\n remotePath: string,\n localPath: string,\n options?: {\n overwrite?: boolean;\n wait?: boolean;\n waitTimeout?: number;\n pollInterval?: number;\n progressCb?: (bytesReceived: number) => void;\n }\n ): Promise<DownloadResult> {\n const {\n overwrite = true,\n wait = true,\n waitTimeout = 30.0,\n pollInterval = 1.5,\n progressCb = undefined\n } = options || {};\n\n try {\n // Use default context if none provided\n if (!this.contextId) {\n return {\n success: false,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: \"No context ID\"\n };\n }\n\n // 1. Trigger cloud disk to OSS download sync\n let reqIdSync: string | undefined;\n try {\n reqIdSync = await this.awaitSync(\"upload\", remotePath, this.contextId);\n } catch (e: any) {\n return {\n success: false,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `session.context.sync(download) failed: ${e.message || e}`\n };\n }\n\n // Optionally wait for task completion (ensure object is ready in OSS)\n if (wait) {\n const { success, error } = await this.waitForTask({\n contextId: this.contextId,\n remotePath,\n taskType: \"upload\",\n timeout: waitTimeout,\n interval: pollInterval\n });\n \n if (!success) {\n return {\n success: false,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download sync not finished: ${error || \"timeout or unknown\"}`\n };\n }\n }\n\n // 2. Get pre-signed download URL\n const urlRes = await this.contextSvc.getFileDownloadUrl(this.contextId, remotePath);\n if (!urlRes.success || !urlRes.url) {\n return {\n success: false,\n requestIdDownloadUrl: urlRes.requestId,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `getFileDownloadUrl failed: ${urlRes.url || \"unknown error\"}`\n };\n }\n\n const downloadUrl = urlRes.url;\n const reqIdDownload = urlRes.requestId;\n\n // 3. Download and save to local\n try {\n // Ensure directory exists\n const dir = path.dirname(localPath);\n if (!fs.existsSync(dir)) {\n fs.mkdirSync(dir, { recursive: true });\n }\n\n if (fs.existsSync(localPath) && !overwrite) {\n return {\n success: false,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Destination exists and overwrite=false: ${localPath}`\n };\n }\n\n const bytesReceived = await this.getFile(\n downloadUrl,\n localPath,\n progressCb\n );\n\n if (fs.existsSync(localPath)) {\n return {\n success: true,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n httpStatus: 200,\n bytesReceived: fs.statSync(localPath).size,\n path: remotePath,\n localPath\n };\n } else {\n return {\n success: false,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n bytesReceived,\n path: remotePath,\n localPath,\n error: \"Download completed but file not found\"\n };\n }\n } catch (e: any) {\n return {\n success: false,\n requestIdDownloadUrl: reqIdDownload,\n requestIdSync: reqIdSync,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download exception: ${e.message || e}`\n };\n }\n } catch (e: any) {\n return {\n success: false,\n bytesReceived: 0,\n path: remotePath,\n localPath,\n error: `Download failed: ${e.message || e}`\n };\n }\n }\n\n // ========== Internal Utilities ==========\n\n /**\n * Compatibility wrapper for session.context.sync which may be sync or async:\n * - Try async call first\n * - Fall back to sync call\n * Returns request_id if available\n */\n private async awaitSync(mode: string, remotePath = \"\", contextId = \"\"): Promise<string | undefined> {\n mode = mode.toLowerCase().trim();\n\n // Check if session has context property\n if (!this.session.context) {\n throw new Error(\"Session does not have context property\");\n }\n\n const syncFn = this.session.context.sync.bind(this.session.context);\n logDebug(`session.context.sync(mode=${mode}, path=${remotePath}, contextId=${contextId})`);\n \n // Try calling with all parameters\n try {\n const result = await syncFn(contextId || undefined, remotePath || undefined, mode);\n logDebug(` Result: ${result.success}`);\n return result.requestId;\n } catch (e1) {\n // Backend may not support all parameters, try with mode and path only\n try {\n const result = await syncFn(undefined, remotePath || undefined, mode);\n logDebug(` Result: ${result.success}`);\n return result.requestId;\n } catch (e2) {\n // Backend may not support mode or path parameter\n try {\n const result = await syncFn(undefined, undefined, mode);\n logDebug(` Result: ${result.success}`);\n return result.requestId;\n } catch (e3) {\n // Backend may not support mode parameter\n const result = await syncFn();\n logDebug(` Result: ${result.success}`);\n return result.requestId;\n }\n }\n }\n }\n\n /**\n * Poll session.context.info within timeout to check if specified task is completed.\n * Returns { success, error } object.\n */\n private async waitForTask(options: {\n contextId: string;\n remotePath: string;\n taskType?: string;\n timeout: number;\n interval: number;\n }): Promise<{ success: boolean; error?: string }> {\n const { contextId, remotePath, taskType, timeout, interval } = options;\n const deadline = Date.now() + timeout * 1000;\n let lastErr: string | null = null;\n\n while (Date.now() < deadline) {\n try {\n // Check if session has context property\n if (!this.session.context) {\n throw new Error(\"Session does not have context property\");\n }\n\n const infoFn = this.session.context.infoWithParams.bind(this.session.context);\n // Try calling with filter parameters\n let res;\n try {\n res = await infoFn(contextId, remotePath, taskType);\n } catch (e1) {\n try {\n res = await infoFn();\n } catch (e2) {\n // If all attempts fail, re-throw the last error\n throw e2;\n }\n }\n\n // Parse response\n const statusList = res.contextStatusData || [];\n for (const item of statusList) {\n const cid = item.contextId;\n const path = item.path;\n const ttype = item.taskType;\n const status = item.status;\n const err = item.errorMessage;\n\n if (cid === contextId && path === remotePath && (taskType === undefined || ttype === taskType)) {\n if (err) {\n return { success: false, error: `Task error: ${err}` };\n }\n if (status && this.finishedStates.has(status.toLowerCase())) {\n return { success: true };\n }\n // Otherwise continue waiting\n }\n }\n lastErr = \"task not finished\";\n } catch (e: any) {\n lastErr = `info error: ${e.message || e}`;\n }\n\n // Wait before next poll\n await new Promise(resolve => setTimeout(resolve, interval * 1000));\n }\n\n return { success: false, error: lastErr || \"timeout\" };\n }\n\n /**\n * Synchronously PUT file using node-fetch.\n * Returns { status, etag, bytesSent }\n */\n private async putFile(\n url: string,\n filePath: string,\n contentType: string | null,\n progressCb?: (bytesTransferred: number) => void\n ): Promise<{ httpStatus: number; etag?: string; bytesSent: number }> {\n const headers: Record<string, string> = {};\n if (contentType) {\n headers[\"Content-Type\"] = contentType;\n }\n\n const fileBuffer = fs.readFileSync(filePath);\n const response = await fetch(url, {\n method: \"PUT\",\n body: fileBuffer,\n headers\n });\n\n const status = response.status;\n const etag = response.headers.get(\"ETag\") || undefined;\n const bytesSent = fileBuffer.length;\n\n if (progressCb) {\n progressCb(bytesSent);\n }\n\n return { httpStatus: status, etag, bytesSent };\n }\n\n /**\n * Synchronously GET download to local file using node-fetch.\n * Returns bytesReceived\n */\n private async getFile(\n url: string,\n destPath: string,\n progressCb?: (bytesReceived: number) => void\n ): Promise<number> {\n let bytesReceived = 0;\n \n const response = await fetch(url);\n const status = response.status;\n \n if (status !== 200) {\n throw new Error(`HTTP ${status}`);\n }\n\n const buffer = await response.buffer();\n bytesReceived = buffer.length;\n \n // Save to file\n fs.writeFileSync(destPath, buffer);\n \n if (progressCb) {\n progressCb(bytesReceived);\n }\n\n return bytesReceived;\n }\n}","export { \n Mobile, \n BoolResult, \n UIElement, \n UIElementsResult, \n InstalledApp, \n InstalledAppsResult, \n Process, \n ProcessResult, \n ScreenshotResult \n} from './mobile'; ","/**\n * Mobile module for mobile UI automation.\n * Provides touch, input, and app management operations for mobile environments.\n */\n\nimport { OperationResult } from \"../types/api-response\";\nimport { MobileExtraConfig } from \"../types/extra-configs\";\nimport { log, logError } from \"../utils/logger\";\nimport { getMobileCommandTemplate, replaceTemplatePlaceholders } from \"../command/command-templates\";\n\nexport interface BoolResult extends OperationResult {\n data?: boolean;\n}\n\nexport interface UIElement {\n text: string;\n className: string;\n bounds: {\n left: number;\n top: number;\n right: number;\n bottom: number;\n };\n}\n\nexport interface UIElementsResult extends OperationResult {\n elements: UIElement[];\n}\n\nexport interface InstalledApp {\n name: string;\n startCmd: string;\n workDirectory: string;\n}\n\nexport interface InstalledAppsResult extends OperationResult {\n apps: InstalledApp[];\n}\n\nexport interface Process {\n pid: number;\n pname: string;\n}\n\nexport interface ProcessResult extends OperationResult {\n processes: Process[];\n}\n\nexport interface ScreenshotResult extends OperationResult {\n data: string; // Screenshot URL\n}\n\nexport interface AdbUrlResult extends OperationResult {\n data?: string; // ADB connection URL (e.g., \"adb connect xx.xx.xx.xx:xxxxx\")\n url?: string; // Alternative field name for compatibility\n}\n\n// Session interface for Mobile module\ninterface MobileSession {\n callMcpTool(toolName: string, args: Record<string, any>): Promise<any>;\n sessionId: string;\n getAPIKey(): string;\n imageId?: string;\n getLink(protocolType?: string, port?: number, options?: string): Promise<any>;\n}\n\nexport class Mobile {\n private session: MobileSession;\n\n constructor(session: MobileSession) {\n this.session = session;\n }\n\n\n /**\n * Tap at specified coordinates.\n */\n async tap(x: number, y: number): Promise<BoolResult> {\n const args = { x, y };\n try {\n const result = await this.session.callMcpTool('tap', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to tap: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Swipe from one position to another.\n */\n async swipe(startX: number, startY: number, endX: number, endY: number, durationMs = 300): Promise<BoolResult> {\n const args = { start_x: startX, start_y: startY, end_x: endX, end_y: endY, duration_ms: durationMs };\n try {\n const result = await this.session.callMcpTool('swipe', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to swipe: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Input text.\n */\n async inputText(text: string): Promise<BoolResult> {\n const args = { text };\n try {\n const result = await this.session.callMcpTool('input_text', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to input text: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Send Android key code.\n */\n async sendKey(key: number): Promise<BoolResult> {\n const args = { key };\n try {\n const result = await this.session.callMcpTool('send_key', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to send key: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Get clickable UI elements.\n */\n async getClickableUIElements(timeoutMs = 5000): Promise<UIElementsResult> {\n const args = { timeout_ms: timeoutMs };\n try {\n const result = await this.session.callMcpTool('get_clickable_ui_elements', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get clickable UI elements',\n elements: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: []\n };\n }\n\n try {\n const elements = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: elements || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse UI elements: ${parseError}`,\n elements: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get clickable UI elements: ${error instanceof Error ? error.message : String(error)}`,\n elements: []\n };\n }\n }\n\n /**\n * Get all UI elements.\n */\n async getAllUIElements(timeoutMs = 3000): Promise<UIElementsResult> {\n const args = { timeout_ms: timeoutMs };\n try {\n const result = await this.session.callMcpTool('get_all_ui_elements', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get all UI elements',\n elements: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: []\n };\n }\n\n try {\n const elements = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n elements: elements || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse UI elements: ${parseError}`,\n elements: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get all UI elements: ${error instanceof Error ? error.message : String(error)}`,\n elements: []\n };\n }\n }\n\n /**\n * Get installed apps.\n */\n async getInstalledApps(startMenu = false, desktop = true, ignoreSystemApps = true): Promise<InstalledAppsResult> {\n const args = { start_menu: startMenu, desktop, ignore_system_apps: ignoreSystemApps };\n try {\n const result = await this.session.callMcpTool('get_installed_apps', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to get installed apps',\n apps: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n apps: []\n };\n }\n\n try {\n const apps = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n apps: apps || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse installed apps: ${parseError}`,\n apps: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to get installed apps: ${error instanceof Error ? error.message : String(error)}`,\n apps: []\n };\n }\n }\n\n /**\n * Start an app.\n */\n async startApp(startCmd: string, workDirectory = '', activity = ''): Promise<ProcessResult> {\n const args = { start_cmd: startCmd, work_directory: workDirectory, activity };\n try {\n const result = await this.session.callMcpTool('start_app', args);\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to start app',\n processes: []\n };\n }\n\n if (!result.data) {\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n processes: []\n };\n }\n\n try {\n const processes = JSON.parse(result.data);\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n processes: processes || []\n };\n } catch (parseError) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: `Failed to parse process result: ${parseError}`,\n processes: []\n };\n }\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to start app: ${error instanceof Error ? error.message : String(error)}`,\n processes: []\n };\n }\n }\n\n /**\n * Stop app by package name.\n */\n async stopAppByPName(pname: string): Promise<BoolResult> {\n const args = { pname };\n try {\n const result = await this.session.callMcpTool('stop_app_by_pname', args);\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.success || false\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to stop app: ${error instanceof Error ? error.message : String(error)}`,\n data: false\n };\n }\n }\n\n /**\n * Take a screenshot.\n */\n async screenshot(): Promise<ScreenshotResult> {\n try {\n const result = await this.session.callMcpTool('system_screenshot', {});\n \n if (!result.success) {\n return {\n success: false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || 'Failed to take screenshot',\n data: ''\n };\n }\n\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: '',\n data: result.data || ''\n };\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to take screenshot: ${error instanceof Error ? error.message : String(error)}`,\n data: ''\n };\n }\n }\n\n /**\n * Retrieves the ADB connection URL for the mobile environment.\n * This method is only supported in mobile environments (mobile_latest image).\n * It uses the provided ADB public key to establish the connection and returns\n * the ADB connect URL.\n * \n * @param adbkeyPub - ADB public key for authentication\n * @returns AdbUrlResult containing the ADB connection URL\n */\n async getAdbUrl(adbkeyPub: string): Promise<AdbUrlResult> {\n try {\n // Build options JSON with adbkey_pub\n const optionsJson = JSON.stringify({ adbkey_pub: adbkeyPub });\n\n // Call getLink with protocol_type=\"adb\" and options\n const result = await this.session.getLink('adb', undefined, optionsJson);\n\n return {\n success: result.success || false,\n requestId: result.requestId || '',\n errorMessage: result.errorMessage || '',\n data: result.data,\n url: result.data\n };\n } catch (error) {\n const errorMsg = `Failed to get ADB URL: ${error instanceof Error ? error.message : String(error)}`;\n return {\n success: false,\n requestId: '',\n errorMessage: errorMsg,\n data: undefined,\n url: undefined\n };\n }\n }\n\n /**\n * Configure mobile device settings based on MobileExtraConfig.\n * This method applies various mobile configuration settings including\n * resolution lock and app access management.\n * \n * @param config - The mobile configuration to apply\n * @returns OperationResult indicating success or failure\n */\n async configure(config: MobileExtraConfig): Promise<OperationResult> {\n try {\n if (!config) {\n return {\n success: false,\n requestId: '',\n errorMessage: 'No mobile configuration provided'\n };\n }\n\n // Configure resolution lock\n const resolutionResult = await this.setResolutionLock(config.lockResolution);\n if (!resolutionResult.success) {\n return {\n success: false,\n requestId: resolutionResult.requestId,\n errorMessage: `Failed to set resolution lock: ${resolutionResult.errorMessage}`\n };\n }\n\n // Configure app management rules\n if (config.appManagerRule && config.appManagerRule.ruleType) {\n const appRule = config.appManagerRule;\n const packageNames = appRule.appPackageNameList;\n\n if (packageNames && packageNames.length > 0 && \n (appRule.ruleType === \"White\" || appRule.ruleType === \"Black\")) {\n \n let appResult: OperationResult;\n if (appRule.ruleType === \"White\") {\n appResult = await this.setAppWhitelist(packageNames);\n } else {\n appResult = await this.setAppBlacklist(packageNames);\n }\n\n if (!appResult.success) {\n return {\n success: false,\n requestId: appResult.requestId,\n errorMessage: `Failed to set app ${appRule.ruleType.toLowerCase()}list: ${appResult.errorMessage}`\n };\n }\n } else if (packageNames && packageNames.length === 0) {\n return {\n success: false,\n requestId: '',\n errorMessage: `No package names provided for ${appRule.ruleType} list`\n };\n }\n }\n\n // Configure navigation bar visibility\n if (config.hideNavigationBar !== undefined) {\n const navResult = await this.setNavigationBarVisibility(config.hideNavigationBar);\n if (!navResult.success) {\n return {\n success: false,\n requestId: navResult.requestId,\n errorMessage: `Failed to set navigation bar visibility: ${navResult.errorMessage}`\n };\n }\n }\n\n // Configure uninstall blacklist\n if (config.uninstallBlacklist && config.uninstallBlacklist.length > 0) {\n const uninstallResult = await this.setUninstallBlacklist(config.uninstallBlacklist);\n if (!uninstallResult.success) {\n return {\n success: false,\n requestId: uninstallResult.requestId,\n errorMessage: `Failed to set uninstall blacklist: ${uninstallResult.errorMessage}`\n };\n }\n }\n\n log(\"Mobile configuration applied successfully\");\n return {\n success: true,\n requestId: '',\n errorMessage: ''\n };\n } catch (error) {\n const errorMsg = `Failed to configure mobile: ${error instanceof Error ? error.message : String(error)}`;\n logError(errorMsg);\n return {\n success: false,\n requestId: '',\n errorMessage: errorMsg\n };\n }\n }\n\n /**\n * Set display resolution lock for mobile devices.\n * \n * @param enable - Whether to enable resolution lock\n * @returns OperationResult indicating success or failure\n */\n async setResolutionLock(enable: boolean): Promise<OperationResult> {\n try {\n const templateName = enable ? \"resolution_lock_enable\" : \"resolution_lock_disable\";\n const template = getMobileCommandTemplate(templateName);\n \n if (!template) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Resolution lock template not found: ${templateName}`\n };\n }\n\n const description = `Resolution lock ${enable ? 'enable' : 'disable'}`;\n return await this.executeCommand(template, description);\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to set resolution lock: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n }\n\n /**\n * Set app whitelist configuration.\n * \n * @param packageNames - List of package names to whitelist\n * @returns OperationResult indicating success or failure\n */\n async setAppWhitelist(packageNames: string[]): Promise<OperationResult> {\n try {\n const template = getMobileCommandTemplate(\"app_whitelist\");\n if (!template) {\n return {\n success: false,\n requestId: '',\n errorMessage: \"App whitelist template not found\"\n };\n }\n\n // Replace placeholder with actual package names (newline-separated for file content)\n const packageList = packageNames.join('\\n');\n const command = replaceTemplatePlaceholders(template, { package_list: packageList });\n \n const description = `App whitelist configuration (${packageNames.length} packages)`;\n return await this.executeCommand(command, description);\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to set app whitelist: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n }\n\n /**\n * Set app blacklist configuration.\n * \n * @param packageNames - List of package names to blacklist\n * @returns OperationResult indicating success or failure\n */\n async setAppBlacklist(packageNames: string[]): Promise<OperationResult> {\n try {\n const template = getMobileCommandTemplate(\"app_blacklist\");\n if (!template) {\n return {\n success: false,\n requestId: '',\n errorMessage: \"App blacklist template not found\"\n };\n }\n\n // Replace placeholder with actual package names (newline-separated for file content)\n const packageList = packageNames.join('\\n');\n const command = replaceTemplatePlaceholders(template, { package_list: packageList });\n \n const description = `App blacklist configuration (${packageNames.length} packages)`;\n return await this.executeCommand(command, description);\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to set app blacklist: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n }\n\n /**\n * Set navigation bar visibility for mobile devices.\n * \n * @param hide - True to hide navigation bar, false to show navigation bar\n * @returns OperationResult indicating success or failure\n */\n async setNavigationBarVisibility(hide: boolean): Promise<OperationResult> {\n try {\n const templateName = hide ? \"hide_navigation_bar\" : \"show_navigation_bar\";\n const template = getMobileCommandTemplate(templateName);\n \n if (!template) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Navigation bar template not found: ${templateName}`\n };\n }\n\n const description = `Navigation bar visibility (hide: ${hide})`;\n return await this.executeCommand(template, description);\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to set navigation bar visibility: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n }\n\n /**\n * Set uninstall protection blacklist for mobile devices.\n * \n * @param packageNames - List of Android package names to protect from uninstallation\n * @returns OperationResult indicating success or failure\n */\n async setUninstallBlacklist(packageNames: string[]): Promise<OperationResult> {\n try {\n const template = getMobileCommandTemplate(\"uninstall_blacklist\");\n if (!template) {\n return {\n success: false,\n requestId: '',\n errorMessage: \"Uninstall blacklist template not found\"\n };\n }\n\n // Use semicolon-separated format for uninstall blacklist property\n const packageList = packageNames.join(';');\n const command = replaceTemplatePlaceholders(template, { package_list: packageList });\n \n const description = `Uninstall blacklist configuration (${packageNames.length} packages)`;\n return await this.executeCommand(command, description);\n } catch (error) {\n return {\n success: false,\n requestId: '',\n errorMessage: `Failed to set uninstall blacklist: ${error instanceof Error ? error.message : String(error)}`\n };\n }\n }\n\n /**\n * Execute a command template for mobile configuration.\n * \n * @param command - The command to execute\n * @param description - Description of the operation\n * @returns OperationResult indicating success or failure\n */\n private async executeCommand(command: string, description: string): Promise<OperationResult> {\n try {\n log(`Executing ${description}`);\n \n // Use the session's command module to execute the command with longer timeout for mobile operations\n const result = await (this.session as any).command.executeCommand(command, 10000);\n \n if (result && result.success) {\n log(`✅ ${description} completed successfully`);\n if (result.output) {\n log(`Command output: ${result.output}`);\n }\n return {\n success: true,\n requestId: result.requestId || '',\n errorMessage: ''\n };\n } else {\n const errorMessage = result?.errorMessage || `Failed to execute ${description}`;\n logError(`Failed to execute ${description}: ${errorMessage}`);\n return {\n success: false,\n requestId: result?.requestId || '',\n errorMessage: errorMessage\n };\n }\n } catch (error) {\n const errorMsg = `Failed to execute ${description}: ${error instanceof Error ? error.message : String(error)}`;\n logError(errorMsg);\n return {\n success: false,\n requestId: '',\n errorMessage: errorMsg\n };\n }\n }\n} ","export { Oss } from \"./oss\";\n","import { Session } from \"../session\";\nimport {\n OSSClientResult,\n OSSUploadResult,\n OSSDownloadResult,\n} from \"../types/api-response\";\n\n\n/**\n * Handles OSS operations in the AgentBay cloud environment.\n */\nexport class Oss {\n private session: Session;\n\n /**\n * Initialize an Oss object.\n *\n * @param session - The Session instance that this Oss belongs to.\n */\n constructor(session: Session) {\n this.session = session;\n }\n\n /**\n * Sanitizes error messages to remove sensitive information like API keys.\n *\n * @param error - The error to sanitize\n * @returns The sanitized error\n */\n private sanitizeError(error: any): any {\n if (!error) {\n return error;\n }\n\n const errorString = String(error);\n return errorString.replace(/Bearer\\s+[^\\s]+/g, \"Bearer [REDACTED]\");\n }\n\n /**\n * Initialize OSS environment variables with the specified credentials.\n * Corresponds to Python's env_init() method\n *\n * @param accessKeyId - The access key ID\n * @param accessKeySecret - The access key secret\n * @param securityToken - The security token (optional)\n * @param endpoint - The OSS endpoint (optional)\n * @param region - The OSS region (optional)\n * @returns OSSClientResult with client configuration and requestId\n * @throws APIError if the operation fails.\n */\n async envInit(\n accessKeyId: string,\n accessKeySecret: string,\n securityToken?: string,\n endpoint?: string,\n region?: string\n ): Promise<OSSClientResult> {\n try {\n const args = {\n access_key_id: accessKeyId,\n access_key_secret: accessKeySecret,\n security_token: securityToken || \"\",\n endpoint: endpoint || \"\",\n region: region || \"\",\n };\n const result = await this.session.callMcpTool(\"oss_env_init\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n clientConfig: {},\n errorMessage: result.errorMessage,\n };\n }\n\n let clientConfig: Record<string, any> = {};\n try {\n clientConfig = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n clientConfig: {},\n errorMessage: `Failed to parse client config: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n clientConfig,\n errorMessage: \"\",\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n clientConfig: {},\n errorMessage: `Failed to initialize OSS environment: ${error}`,\n };\n }\n }\n\n /**\n * Upload a file to OSS.\n * Corresponds to Python's upload() method\n *\n * @param bucket - The OSS bucket name\n * @param object - The OSS object key\n * @param path - The local file path to upload\n * @returns OSSUploadResult with upload result and requestId\n * @throws APIError if the operation fails.\n */\n async upload(\n bucket: string,\n object: string,\n path: string\n ): Promise<OSSUploadResult> {\n try {\n const args = {\n bucket,\n object,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_upload\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to upload file: ${error}`,\n };\n }\n }\n\n /**\n * Upload a file to OSS using an anonymous URL.\n * Corresponds to Python's upload_anonymous() method\n *\n * @param url - The anonymous upload URL\n * @param path - The local file path to upload\n * @returns OSSUploadResult with upload result and requestId\n * @throws APIError if the operation fails.\n */\n async uploadAnonymous(url: string, path: string): Promise<OSSUploadResult> {\n try {\n const args = {\n url,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_upload_annon\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to upload file anonymously: ${error}`,\n };\n }\n }\n\n /**\n * Download a file from OSS.\n * Corresponds to Python's download() method\n *\n * @param bucket - The OSS bucket name\n * @param object - The OSS object key\n * @param path - The local file path to save the downloaded file\n * @returns OSSDownloadResult with download result and requestId\n * @throws APIError if the operation fails.\n */\n async download(\n bucket: string,\n object: string,\n path: string\n ): Promise<OSSDownloadResult> {\n try {\n const args = {\n bucket,\n object,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_download\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to download file: ${error}`,\n };\n }\n }\n\n /**\n * Download a file from OSS using an anonymous URL.\n * Corresponds to Python's download_anonymous() method\n *\n * @param url - The anonymous download URL\n * @param path - The local file path to save the downloaded file\n * @returns OSSDownloadResult with download result and requestId\n * @throws APIError if the operation fails.\n */\n async downloadAnonymous(\n url: string,\n path: string\n ): Promise<OSSDownloadResult> {\n try {\n const args = {\n url,\n path,\n };\n const result = await this.session.callMcpTool(\"oss_download_annon\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n content: result.data,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n content: \"\",\n errorMessage: `Failed to download file anonymously: ${error}`,\n };\n }\n }\n}\n","import { Session } from \"../session\";\nimport {\n UIElementListResult,\n BoolResult,\n OperationResult,\n} from \"../types/api-response\";\n\n/**\n * Key codes for UI operations\n */\nexport enum KeyCode {\n HOME = 3,\n BACK = 4,\n VOLUME_UP = 24,\n VOLUME_DOWN = 25,\n POWER = 26,\n MENU = 82\n}\n\n/**\n * Interface representing a UI element in the UI hierarchy\n */\nexport interface UIElement {\n bounds: string;\n className: string;\n text: string;\n type: string;\n resourceId: string;\n index: number;\n isParent: boolean;\n children?: UIElement[];\n}\n\n\n\n/**\n * Handles UI operations in the AgentBay cloud environment.\n * \n * @deprecated This module is deprecated. Use Computer or Mobile modules instead.\n * - For desktop UI operations, use session.computer\n * - For mobile UI operations, use session.mobile\n */\nexport class UI {\n private session: Session;\n\n /**\n * Initialize a UI object.\n *\n * @param session - The Session instance that this UI belongs to.\n */\n constructor(session: {\n getAPIKey(): string;\n getClient(): any;\n getSessionId(): string;\n callMcpTool(toolName: string, args: any): Promise<{\n success: boolean;\n data: string;\n errorMessage: string;\n requestId: string;\n }>;\n }) {\n this.session = session as Session;\n }\n\n /**\n * Sanitizes error messages to remove sensitive information like API keys.\n *\n * @param error - The error to sanitize\n * @returns The sanitized error\n */\n private sanitizeError(error: any): any {\n if (!error) {\n return error;\n }\n\n const errorString = String(error);\n return errorString.replace(/Bearer\\s+[^\\s]+/g, \"Bearer [REDACTED]\");\n }\n\n /**\n * Retrieves all clickable UI elements within the specified timeout.\n * Corresponds to Python's get_clickable_ui_elements() method\n *\n * @param timeoutMs - The timeout in milliseconds. Default is 2000ms.\n * @returns UIElementListResult with clickable elements and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.getClickableUIElements() for desktop or session.mobile.getClickableUIElements() for mobile instead.\n */\n async getClickableUIElements(timeoutMs = 2000): Promise<UIElementListResult> {\n console.warn('⚠️ UI.getClickableUIElements() is deprecated. Use session.computer.getClickableUIElements() for desktop or session.mobile.getClickableUIElements() for mobile instead.');\n \n try {\n const args = { timeout_ms: timeoutMs };\n const result = await this.session.callMcpTool(\"get_clickable_ui_elements\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let elements: UIElement[] = [];\n try {\n elements = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: `Failed to parse UI elements: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n elements: elements,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n elements: [],\n errorMessage: `Failed to get clickable UI elements: ${error}`,\n };\n }\n }\n\n /**\n * Retrieves all UI elements regardless of their clickable status.\n * Corresponds to Python's get_all_ui_elements() method\n *\n * @param timeoutMs - The timeout in milliseconds. Default is 2000ms.\n * @returns UIElementListResult with all elements and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.getAllUIElements() for desktop or session.mobile.getAllUIElements() for mobile instead.\n */\n async getAllUIElements(timeoutMs = 2000): Promise<UIElementListResult> {\n console.warn('⚠️ UI.getAllUIElements() is deprecated. Use session.computer.getAllUIElements() for desktop or session.mobile.getAllUIElements() for mobile instead.');\n \n try {\n const args = { timeout_ms: timeoutMs };\n const result = await this.session.callMcpTool(\"get_all_ui_elements\", args);\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: result.errorMessage,\n };\n }\n\n let elements: UIElement[] = [];\n try {\n elements = JSON.parse(result.data);\n } catch (err) {\n return {\n requestId: result.requestId,\n success: false,\n elements: [],\n errorMessage: `Failed to parse UI elements: ${err}`,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n elements: elements,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n elements: [],\n errorMessage: `Failed to get all UI elements: ${error}`,\n };\n }\n }\n\n /**\n * Sends a key press event.\n * Corresponds to Python's send_key() method\n *\n * @param key - The key code to send. Supported key codes are:\n * - 3 : HOME\n * - 4 : BACK\n * - 24 : VOLUME UP\n * - 25 : VOLUME DOWN\n * - 26 : POWER\n * - 82 : MENU\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.pressKeys() for desktop or session.mobile.sendKey() for mobile instead.\n */\n async sendKey(key: number): Promise<BoolResult> {\n console.warn('⚠️ UI.sendKey() is deprecated. Use session.computer.pressKeys() for desktop or session.mobile.sendKey() for mobile instead.');\n \n try {\n const args = { key };\n const result = await this.session.callMcpTool(\"send_key\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to send key: ${error}`,\n };\n }\n }\n\n /**\n * Inputs text into the currently focused UI element.\n * Corresponds to Python's input_text() method\n *\n * @param text - The text to input\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.inputText() for desktop or session.mobile.inputText() for mobile instead.\n */\n async inputText(text: string): Promise<BoolResult> {\n console.warn('⚠️ UI.inputText() is deprecated. Use session.computer.inputText() for desktop or session.mobile.inputText() for mobile instead.');\n \n try {\n const args = { text };\n const result = await this.session.callMcpTool(\"input_text\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to input text: ${error}`,\n };\n }\n }\n\n /**\n * Performs a swipe gesture on the screen.\n * Corresponds to Python's swipe() method\n *\n * @param startX - The starting X coordinate\n * @param startY - The starting Y coordinate\n * @param endX - The ending X coordinate\n * @param endY - The ending Y coordinate\n * @param durationMs - The duration of the swipe in milliseconds. Default is 300ms.\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.dragMouse() for desktop or session.mobile.swipe() for mobile instead.\n */\n async swipe(\n startX: number,\n startY: number,\n endX: number,\n endY: number,\n durationMs = 300\n ): Promise<BoolResult> {\n console.warn('⚠️ UI.swipe() is deprecated. Use session.computer.dragMouse() for desktop or session.mobile.swipe() for mobile instead.');\n \n try {\n const args = {\n start_x: startX,\n start_y: startY,\n end_x: endX,\n end_y: endY,\n duration_ms: durationMs,\n };\n const result = await this.session.callMcpTool(\"swipe\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to perform swipe: ${error}`,\n };\n }\n }\n\n /**\n * Clicks on the screen at the specified coordinates.\n * Corresponds to Python's click() method\n *\n * @param x - The X coordinate\n * @param y - The Y coordinate\n * @param button - The mouse button to use. Default is 'left'\n * @returns BoolResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.clickMouse() for desktop or session.mobile.tap() for mobile instead.\n */\n async click(x: number, y: number, button = \"left\"): Promise<BoolResult> {\n console.warn('⚠️ UI.click() is deprecated. Use session.computer.clickMouse() for desktop or session.mobile.tap() for mobile instead.');\n \n try {\n const args = { x, y, button };\n const result = await this.session.callMcpTool(\"click\", args);\n\n return {\n requestId: result.requestId,\n success: result.success,\n data: result.success,\n errorMessage: result.errorMessage,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: false,\n errorMessage: `Failed to click: ${error}`,\n };\n }\n }\n\n /**\n * Takes a screenshot of the current screen.\n * Corresponds to Python's screenshot() method\n *\n * @returns OperationResult with success status and requestId\n * @throws Error if the operation fails.\n * \n * @deprecated Use session.computer.screenshot() for desktop or session.mobile.screenshot() for mobile instead.\n */\n async screenshot(): Promise<OperationResult> {\n console.warn('⚠️ UI.screenshot() is deprecated. Use session.computer.screenshot() for desktop or session.mobile.screenshot() for mobile instead.');\n \n try {\n const result = await this.session.callMcpTool(\"system_screenshot\", {});\n\n if (!result.success) {\n return {\n requestId: result.requestId,\n success: false,\n data: \"\",\n errorMessage: result.errorMessage,\n };\n }\n\n return {\n requestId: result.requestId,\n success: true,\n data: result.data,\n };\n } catch (error) {\n return {\n requestId: \"\",\n success: false,\n data: \"\",\n errorMessage: `Failed to take screenshot: ${error}`,\n };\n }\n }\n}\n","export { Agent, ExecutionResult, QueryResult, McpToolResult, McpSession } from \"./agent\"; ","import * as fs from \"fs\";\nimport * as path from \"path\";\nimport * as crypto from \"crypto\";\nimport fetch from \"node-fetch\";\nimport { AgentBay } from \"./agent-bay\";\nimport { ContextService, Context } from \"./context\";\nimport { AgentBayError } from \"./exceptions\";\nimport { OperationResult, ContextFileListResult, FileUrlResult } from \"./types/api-response\";\nimport { log, logError, logInfo, logDebug } from \"./utils/logger\";\n\n// ==============================================================================\n// Constants\n// ==============================================================================\nconst EXTENSIONS_BASE_PATH = \"/tmp/extensions\";\n\n// ==============================================================================\n// 1. Data Models\n// ==============================================================================\n\n/**\n * Represents a browser extension as a cloud resource.\n */\nexport class Extension {\n /**\n * The unique identifier of the extension.\n */\n id: string;\n\n /**\n * The name of the extension.\n */\n name: string;\n\n /**\n * Date and time when the extension was created.\n */\n createdAt?: string;\n\n /**\n * Initialize an Extension object.\n *\n * @param id - The unique identifier of the extension.\n * @param name - The name of the extension.\n * @param createdAt - Date and time when the extension was created.\n */\n constructor(id: string, name: string, createdAt?: string) {\n this.id = id;\n this.name = name;\n this.createdAt = createdAt;\n }\n}\n\n/**\n * Configuration options for browser extension integration.\n * \n * This class encapsulates the necessary parameters for setting up\n * browser extension synchronization and context management.\n */\nexport class ExtensionOption {\n /**\n * ID of the extension context for browser extensions.\n */\n contextId: string;\n\n /**\n * List of extension IDs to be loaded/synchronized.\n */\n extensionIds: string[];\n\n /**\n * Initialize ExtensionOption with context and extension configuration.\n * \n * @param contextId - ID of the extension context for browser extensions.\n * This should match the context where extensions are stored.\n * @param extensionIds - List of extension IDs to be loaded in the browser session.\n * Each ID should correspond to a valid extension in the context.\n * \n * @throws {Error} If contextId is empty or extensionIds is empty.\n */\n constructor(contextId: string, extensionIds: string[]) {\n if (!contextId || !contextId.trim()) {\n throw new Error(\"contextId cannot be empty\");\n }\n\n if (!extensionIds || extensionIds.length === 0) {\n throw new Error(\"extensionIds cannot be empty\");\n }\n\n this.contextId = contextId;\n this.extensionIds = extensionIds;\n }\n\n /**\n * String representation of ExtensionOption.\n */\n toString(): string {\n return `ExtensionOption(contextId='${this.contextId}', extensionIds=${JSON.stringify(this.extensionIds)})`;\n }\n\n /**\n * Human-readable string representation.\n */\n toDisplayString(): string {\n return `Extension Config: ${this.extensionIds.length} extension(s) in context '${this.contextId}'`;\n }\n\n /**\n * Validate the extension option configuration.\n * \n * @returns True if configuration is valid, false otherwise.\n */\n validate(): boolean {\n try {\n // Check contextId\n if (!this.contextId || !this.contextId.trim()) {\n return false;\n }\n\n // Check extensionIds\n if (!this.extensionIds || this.extensionIds.length === 0) {\n return false;\n }\n\n // Check that all extension IDs are non-empty strings\n for (const extId of this.extensionIds) {\n if (typeof extId !== 'string' || !extId.trim()) {\n return false;\n }\n }\n\n return true;\n } catch (error) {\n return false;\n }\n }\n}\n\n// ==============================================================================\n// 2. Core Service Class (Scoped Stateless Model)\n// ==============================================================================\n\n/**\n * Provides methods to manage user browser extensions.\n * This service integrates with the existing context functionality for file operations.\n * \n * **Usage** (Simplified - Auto-detection):\n * ```typescript\n * // Service automatically detects if context exists and creates if needed\n * const extensionsService = new ExtensionsService(agentBay, \"browser_extensions\");\n * \n * // Or use with empty contextId to auto-generate context name\n * const extensionsService = new ExtensionsService(agentBay); // Uses default generated name\n * \n * // Use the service immediately - initialization happens automatically\n * const extension = await extensionsService.create(\"/path/to/plugin.zip\");\n * ```\n * \n * **Integration with ExtensionOption (Simplified)**:\n * ```typescript\n * // Create extensions and configure for browser sessions\n * const extensionsService = new ExtensionsService(agentBay, \"my_extensions\");\n * const ext1 = await extensionsService.create(\"/path/to/ext1.zip\");\n * const ext2 = await extensionsService.create(\"/path/to/ext2.zip\");\n * \n * // Create extension option for browser integration (no contextId needed!)\n * const extOption = extensionsService.createExtensionOption([ext1.id, ext2.id]);\n * \n * // Use with BrowserContext for session creation\n * const browserContext = new BrowserContext({\n * contextId: \"browser_session\",\n * autoUpload: true,\n * extensionOption: extOption // All extension config encapsulated\n * });\n * ```\n * \n * **Context Management**:\n * - If contextId provided and exists: Uses the existing context\n * - If contextId provided but doesn't exist: Creates context with provided name\n * - If contextId empty or not provided: Generates default name and creates context\n * - No need to manually manage context creation or call initialize()\n * - Context initialization happens automatically on first method call\n */\nexport class ExtensionsService {\n private agentBay: AgentBay;\n private contextService: ContextService;\n private extensionContext!: Context;\n private contextId!: string;\n private contextName: string;\n private autoCreated: boolean;\n private _initializationPromise: Promise<void> | null = null;\n\n /**\n * Initializes the ExtensionsService with a context.\n *\n * @param agentBay - The AgentBay client instance.\n * @param contextId - The context ID or name. If empty or not provided,\n * a default context name will be generated automatically.\n * If the context doesn't exist, it will be automatically created.\n * \n * Note:\n * The service automatically detects if the context exists. If not,\n * it creates a new context with the provided name or a generated default name.\n * Context initialization is handled lazily on first use.\n */\n constructor(agentBay: AgentBay, contextId: string = \"\") {\n if (!agentBay) {\n throw new AgentBayError(\"AgentBay instance is required\");\n }\n if (!agentBay.context) {\n throw new AgentBayError(\"AgentBay instance must have a context service\");\n }\n \n this.agentBay = agentBay;\n this.contextService = agentBay.context;\n this.autoCreated = true;\n\n // Generate default context name if contextId is empty\n if (!contextId || contextId.trim() === \"\") {\n contextId = `extensions-${Math.floor(Date.now() / 1000)}`;\n logDebug(`Generated default context name: ${contextId}`);\n }\n\n this.contextName = contextId;\n \n // Initialize context lazily - will be set on first method call\n this._initializationPromise = this._initializeContext();\n }\n\n /**\n * Internal method to initialize the context.\n * This ensures the context is ready before any operations.\n */\n private async _initializeContext(): Promise<void> {\n try {\n // Context doesn't exist, create it\n const contextResult = await this.contextService.get(this.contextName, true);\n if (!contextResult.success || !contextResult.context) {\n throw new AgentBayError(`Failed to create extension repository context: ${this.contextName}`);\n }\n\n this.extensionContext = contextResult.context;\n this.contextId = this.extensionContext.id;\n } catch (error) {\n throw new AgentBayError(`Failed to initialize ExtensionsService: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Ensures the service is initialized before performing operations.\n */\n private async _ensureInitialized(): Promise<void> {\n if (this._initializationPromise) {\n await this._initializationPromise;\n this._initializationPromise = null;\n }\n }\n\n /**\n * An internal helper method that encapsulates the flow of \"get upload URL for a specific path and upload\".\n * Uses the existing context service for file operations.\n *\n * @param localPath - The path to the local file.\n * @param remotePath - The path of the file in context storage.\n * \n * @throws {AgentBayError} If getting the credential or uploading fails.\n */\n private async _uploadToCloud(localPath: string, remotePath: string): Promise<void> {\n try {\n // 1. Get upload URL using context service\n const urlResult = await this.contextService.getFileUploadUrl(this.contextId, remotePath);\n if (!urlResult.success || !urlResult.url) {\n throw new AgentBayError(`Failed to get upload URL: ${urlResult.url || 'No URL returned'}`);\n }\n\n const preSignedUrl = urlResult.url;\n\n // 2. Use the presigned URL to upload the file directly\n const fileBuffer = fs.readFileSync(localPath);\n \n const response = await fetch(preSignedUrl, {\n method: 'PUT',\n body: fileBuffer,\n });\n\n if (!response.ok) {\n throw new AgentBayError(`HTTP error uploading file: ${response.status} ${response.statusText}`);\n }\n } catch (error) {\n if (error instanceof AgentBayError) {\n throw error;\n }\n throw new AgentBayError(`An error occurred while uploading the file: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Lists all available browser extensions within this context from the cloud.\n * Uses the context service to list files under the extensions directory.\n * \n * @returns Promise that resolves to an array of Extension objects.\n * @throws {AgentBayError} If listing extensions fails.\n */\n async list(): Promise<Extension[]> {\n await this._ensureInitialized();\n \n try {\n // Use context service to list files in the extensions directory\n const fileListResult = await this.contextService.listFiles(\n this.contextId,\n EXTENSIONS_BASE_PATH,\n 1, // pageNumber\n 100 // pageSize - reasonable limit for extensions\n );\n\n if (!fileListResult.success) {\n throw new AgentBayError(\"Failed to list extensions: Context file listing failed.\");\n }\n\n const extensions: Extension[] = [];\n for (const fileEntry of fileListResult.entries) {\n // Extract the extension ID from the file name\n const extensionId = fileEntry.fileName || fileEntry.filePath;\n extensions.push(new Extension(\n extensionId,\n fileEntry.fileName || extensionId,\n fileEntry.gmtCreate\n ));\n }\n return extensions;\n } catch (error) {\n if (error instanceof AgentBayError) {\n throw error;\n }\n throw new AgentBayError(`An error occurred while listing browser extensions: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n\n /**\n * Uploads a new browser extension from a local path into the current context.\n * \n * @param localPath - Path to the local extension file (must be a .zip file).\n * @returns Promise that resolves to an Extension object.\n * @throws {Error} If the local file doesn't exist.\n * @throws {Error} If the file format is not supported (only .zip is supported).\n * @throws {AgentBayError} If upload fails.\n */\n async create(localPath: string): Promise<Extension> {\n await this._ensureInitialized();\n \n if (!fs.existsSync(localPath)) {\n throw new Error(`The specified local file was not found: ${localPath}`);\n }\n\n // Determine the ID and cloud path before uploading\n // Validate file type - only ZIP format is supported\n const fileExtension = path.extname(localPath).toLowerCase();\n if (fileExtension !== '.zip') {\n throw new Error(`Unsupported plugin format '${fileExtension}'. Only ZIP format (.zip) is supported.`);\n }\n\n const extensionId = `ext_${crypto.randomBytes(16).toString('hex')}${fileExtension}`;\n const extensionName = path.basename(localPath);\n const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;\n\n // Use the helper method to perform the cloud upload\n await this._uploadToCloud(localPath, remotePath);\n\n // Upload implies creation. Return a locally constructed object with basic info.\n return new Extension(extensionId, extensionName);\n }\n\n /**\n * Updates an existing browser extension in the current context with a new file.\n * \n * @param extensionId - ID of the extension to update.\n * @param newLocalPath - Path to the new local extension file.\n * @returns Promise that resolves to an Extension object.\n * @throws {Error} If the new local file doesn't exist.\n * @throws {Error} If the extension doesn't exist in the context.\n * @throws {AgentBayError} If update fails.\n */\n async update(extensionId: string, newLocalPath: string): Promise<Extension> {\n await this._ensureInitialized();\n \n if (!fs.existsSync(newLocalPath)) {\n throw new Error(`The specified new local file was not found: ${newLocalPath}`);\n }\n\n // Validate that the extension exists by checking the file list\n const existingExtensions = await this.list();\n const extensionExists = existingExtensions.some(ext => ext.id === extensionId);\n \n if (!extensionExists) {\n throw new Error(`Browser extension with ID '${extensionId}' not found in the context. Cannot update.`);\n }\n\n const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;\n\n // Use the helper method to perform the cloud upload (overwrite)\n await this._uploadToCloud(newLocalPath, remotePath);\n\n return new Extension(extensionId, path.basename(newLocalPath));\n }\n\n /**\n * Gets detailed information about a specific browser extension.\n * \n * @param extensionId - The ID of the extension to get info for.\n * @returns Promise that resolves to an Extension object if found, undefined otherwise.\n */\n private async _getExtensionInfo(extensionId: string): Promise<Extension | undefined> {\n await this._ensureInitialized();\n \n try {\n const extensions = await this.list();\n return extensions.find(ext => ext.id === extensionId);\n } catch (error) {\n logError(`An error occurred while getting extension info for '${extensionId}':`, error);\n return undefined;\n }\n }\n\n /**\n * Cleans up the auto-created context if it was created by this service.\n * \n * @returns Promise that resolves to true if cleanup was successful or not needed, false if cleanup failed.\n * \n * Note:\n * This method only works if the context was auto-created by this service.\n * For existing contexts, no cleanup is performed.\n */\n async cleanup(): Promise<boolean> {\n await this._ensureInitialized();\n \n if (!this.autoCreated) {\n // Context was not auto-created by this service, no cleanup needed\n return true;\n }\n\n try {\n const deleteResult = await this.contextService.delete(this.extensionContext);\n if (deleteResult) {\n logInfo(`Extension context deleted: ${this.contextName} (ID: ${this.contextId})`);\n return true;\n } else {\n logError(`Warning: Failed to delete extension context: ${this.contextName}`, new Error('Delete operation returned false'));\n return false;\n }\n } catch (error) {\n logError(`Warning: Failed to delete extension context:`, error);\n return false;\n }\n }\n\n /**\n * Deletes a browser extension from the current context.\n * \n * @param extensionId - ID of the extension to delete.\n * @returns Promise that resolves to true if deletion was successful, false otherwise.\n */\n async delete(extensionId: string): Promise<boolean> {\n await this._ensureInitialized();\n \n const remotePath = `${EXTENSIONS_BASE_PATH}/${extensionId}`;\n try {\n // Use context service to delete the file\n const deleteResult = await this.contextService.deleteFile(this.contextId, remotePath);\n\n return deleteResult.success;\n } catch (error) {\n logError(`An error occurred while deleting browser extension '${extensionId}':`, error);\n return false;\n }\n }\n\n /**\n * Create an ExtensionOption for the current context with specified extension IDs.\n * \n * This is a convenience method that creates an ExtensionOption using the current\n * service's contextId and the provided extension IDs. This option can then be\n * used with BrowserContext for browser session creation.\n * \n * @param extensionIds - List of extension IDs to include in the option.\n * These should be extensions that exist in the current context.\n * @returns ExtensionOption configuration object for browser extension integration.\n * @throws {Error} If extensionIds is empty or invalid.\n * \n * @example\n * ```typescript\n * // Create extensions\n * const ext1 = await extensionsService.create(\"/path/to/ext1.zip\");\n * const ext2 = await extensionsService.create(\"/path/to/ext2.zip\");\n * \n * // Create extension option for browser integration\n * const extOption = extensionsService.createExtensionOption([ext1.id, ext2.id]);\n * \n * // Use with BrowserContext\n * const browserContext = new BrowserContext({\n * contextId: \"browser_session\",\n * autoUpload: true,\n * extensionContextId: extOption.contextId,\n * extensionIds: extOption.extensionIds\n * });\n * ```\n */\n createExtensionOption(extensionIds: string[]): ExtensionOption {\n // Note: This method is synchronous like in Python, but contextId might not be available yet\n // In practice, this should be called after the service has been used at least once\n if (!this.contextId) {\n throw new Error(\"Service not initialized. Please call an async method first or ensure context is created.\");\n }\n \n return new ExtensionOption(\n this.contextId,\n extensionIds\n );\n }\n}","export {\n createListSessionParams,\n type ListSessionParams,\n type SessionListResult,\n} from \"./list-session-params\";\n\nexport {\n extractRequestId,\n type ApiResponse,\n type ApiResponseWithData,\n type DeleteResult,\n} from \"./api-response\";\n\nexport {\n type AppManagerRule,\n type MobileExtraConfig,\n type ExtraConfigs,\n validateAppManagerRule,\n validateMobileExtraConfig,\n validateExtraConfigs,\n extraConfigsToJSON,\n extraConfigsFromJSON,\n} from \"./extra-configs\";\n","import { Session } from \"../session\";\nimport { ApiResponse } from \"./api-response\";\n\n/**\n * Parameters for listing sessions with pagination support\n */\nexport interface ListSessionParams {\n /** Number of results per page (default: 10) */\n maxResults?: number;\n\n /** Token for the next page */\n nextToken?: string;\n\n /** Labels to filter by */\n labels: Record<string, string>;\n}\n\n/**\n * Result type for session listing with pagination information\n */\nexport interface SessionListResult extends ApiResponse {\n /** Array of session IDs */\n sessionIds: string[];\n\n /** Token for the next page (if available) */\n nextToken?: string;\n\n /** Number of results per page */\n maxResults?: number;\n\n /** Total number of results */\n totalCount?: number;\n}\n\n/**\n * Helper function to create ListSessionParams with default values\n */\nexport function createListSessionParams(\n labels: Record<string, string> = {}\n): ListSessionParams {\n return {\n maxResults: 10,\n labels,\n };\n}\n","/**\n * App manager rule for mobile device configuration.\n * \n * Defines rules for managing app access on mobile devices through whitelist or blacklist modes.\n */\nexport interface AppManagerRule {\n /**\n * Type of rule to apply.\n * - \"White\": Whitelist mode - only allow specified apps\n * - \"Black\": Blacklist mode - block specified apps\n */\n ruleType: \"White\" | \"Black\";\n \n /**\n * List of Android package names to apply the rule to.\n * Example: [\"com.android.settings\", \"com.example.app\"]\n */\n appPackageNameList: string[];\n}\n\n/**\n * Mobile-specific configuration settings for session creation.\n * \n * These settings allow control over mobile device behavior including\n * resolution locking, app access management, navigation bar visibility, and uninstall protection.\n */\nexport interface MobileExtraConfig {\n /**\n * Whether to lock the screen resolution.\n * - true: Locks resolution for consistent mobile testing environments\n * - false: Allows adaptive resolution for different device types\n */\n lockResolution: boolean;\n \n /**\n * Optional app manager rule for controlling app access.\n * Defines which apps are allowed (whitelist) or blocked (blacklist).\n */\n appManagerRule?: AppManagerRule;\n \n /**\n * Whether to hide the system navigation bar for immersive full-screen experience.\n * - true: Hide navigation bar\n * - false: Show navigation bar (default)\n */\n hideNavigationBar?: boolean;\n \n /**\n * List of package names to protect from uninstallation.\n * Prevents accidental or malicious removal of critical apps.\n * Example: [\"com.android.systemui\", \"com.android.settings\"]\n */\n uninstallBlacklist?: string[];\n}\n\n/**\n * Extra configuration settings for different session types.\n * \n * This container holds specialized configurations for various\n * session environments (mobile, desktop, etc.).\n */\nexport interface ExtraConfigs {\n /**\n * Mobile-specific configuration settings.\n * Only applicable when creating mobile sessions.\n */\n mobile?: MobileExtraConfig;\n}\n\n/**\n * Serializes ExtraConfigs to JSON string format.\n * Returns empty string if extraConfigs is null or undefined.\n * \n * @param extraConfigs - The extra configs to serialize\n * @returns JSON string representation\n */\nexport function extraConfigsToJSON(extraConfigs?: ExtraConfigs | null): string {\n if (!extraConfigs) {\n return \"\";\n }\n \n return JSON.stringify(extraConfigs);\n}\n\n/**\n * Deserializes ExtraConfigs from JSON string format.\n * Returns null if jsonStr is empty or invalid.\n * \n * @param jsonStr - JSON string to deserialize\n * @returns Parsed ExtraConfigs object or null\n */\nexport function extraConfigsFromJSON(jsonStr: string): ExtraConfigs | null {\n if (!jsonStr || jsonStr.trim() === \"\") {\n return null;\n }\n \n try {\n return JSON.parse(jsonStr) as ExtraConfigs;\n } catch (error) {\n throw new Error(`Failed to parse ExtraConfigs JSON: ${error}`);\n }\n}\n\n/**\n * Validates an AppManagerRule object.\n * Throws an error if validation fails.\n * \n * @param rule - The rule to validate\n */\nexport function validateAppManagerRule(rule: AppManagerRule): void {\n if (!rule.ruleType) {\n throw new Error(\"AppManagerRule ruleType is required\");\n }\n \n if (rule.ruleType !== \"White\" && rule.ruleType !== \"Black\") {\n throw new Error(`Invalid ruleType: ${rule.ruleType}. Must be \"White\" or \"Black\"`);\n }\n \n if (!Array.isArray(rule.appPackageNameList)) {\n throw new Error(\"AppManagerRule appPackageNameList must be an array\");\n }\n \n for (const packageName of rule.appPackageNameList) {\n if (typeof packageName !== \"string\") {\n throw new Error(\"AppManagerRule appPackageNameList items must be strings\");\n }\n }\n}\n\n/**\n * Validates a MobileExtraConfig object.\n * Throws an error if validation fails.\n * \n * @param config - The config to validate\n */\nexport function validateMobileExtraConfig(config: MobileExtraConfig): void {\n if (typeof config.lockResolution !== \"boolean\") {\n throw new Error(\"MobileExtraConfig lockResolution must be a boolean\");\n }\n \n if (config.appManagerRule) {\n validateAppManagerRule(config.appManagerRule);\n }\n \n if (config.hideNavigationBar !== undefined && typeof config.hideNavigationBar !== \"boolean\") {\n throw new Error(\"MobileExtraConfig hideNavigationBar must be a boolean\");\n }\n \n if (config.uninstallBlacklist) {\n if (!Array.isArray(config.uninstallBlacklist)) {\n throw new Error(\"MobileExtraConfig uninstallBlacklist must be an array\");\n }\n \n for (const packageName of config.uninstallBlacklist) {\n if (typeof packageName !== \"string\" || packageName.trim() === \"\") {\n throw new Error(\"MobileExtraConfig uninstallBlacklist items must be non-empty strings\");\n }\n }\n }\n}\n\n/**\n * Validates an ExtraConfigs object.\n * Throws an error if validation fails.\n * \n * @param extraConfigs - The extra configs to validate\n */\nexport function validateExtraConfigs(extraConfigs: ExtraConfigs): void {\n if (extraConfigs.mobile) {\n validateMobileExtraConfig(extraConfigs.mobile);\n }\n}\n","import { ContextSync, SyncPolicy, newUploadPolicy, newExtractPolicy, newRecyclePolicy, WhiteList, BWList, newDeletePolicy } from \"./context-sync\";\nimport { ExtensionOption } from \"./extension\";\nimport { ExtraConfigs, extraConfigsToJSON } from \"./types/extra-configs\";\n\n/**\n * Browser context configuration for session with optional extension support.\n *\n * This class provides browser context configuration for cloud sessions and supports\n * automatic extension synchronization when ExtensionOption is provided.\n *\n * Key Features:\n * - Browser context binding for sessions\n * - Automatic browser data upload on session end\n * - Optional extension integration with automatic context sync generation\n * - Clean API with ExtensionOption encapsulation\n *\n * Extension Configuration:\n * - **ExtensionOption**: Pass an ExtensionOption object with contextId and extensionIds\n * - **No Extensions**: Don't provide extensionOption parameter (extensionContextSyncs will be undefined)\n *\n * Usage Examples:\n * ```typescript\n * // With extensions using ExtensionOption\n * import { ExtensionOption } from \"./extension\";\n *\n * const extOption = new ExtensionOption(\n * \"my_extensions\",\n * [\"ext1\", \"ext2\"]\n * );\n *\n * const browserContext = new BrowserContext(\n * \"browser_session\",\n * true,\n * extOption\n * );\n *\n * // Without extensions (minimal configuration)\n * const browserContext = new BrowserContext(\n * \"browser_session\",\n * true\n * );\n * // extensionContextSyncs will be undefined\n * ```\n */\nexport class BrowserContext {\n /** ID of the browser context to bind to the session */\n contextId: string;\n /** Whether to automatically upload browser data when the session ends */\n autoUpload: boolean;\n /** Optional extension configuration object containing context_id and extension_ids */\n extensionOption?: ExtensionOption;\n /** ID of the extension context for browser extensions. Set automatically from extension_option. */\n extensionContextId?: string;\n /** List of extension IDs to synchronize. Set automatically from extension_option. */\n extensionIds?: string[];\n /** Auto-generated context syncs for extensions. None if no extension configuration provided. */\n extensionContextSyncs?: ContextSync[];\n\n /**\n * Initialize BrowserContextImpl with optional extension support.\n *\n * @param contextId - ID of the browser context to bind to the session.\n * This identifies the browser instance for the session.\n * @param autoUpload - Whether to automatically upload browser data\n * when the session ends. Defaults to true.\n * @param extensionOption - Extension configuration object containing\n * contextId and extensionIds. This encapsulates\n * all extension-related configuration.\n * Defaults to undefined.\n *\n * Extension Configuration:\n * - **ExtensionOption**: Use extensionOption parameter with an ExtensionOption object\n * - **No Extensions**: Don't provide extensionOption parameter\n *\n * Auto-generation:\n * - extensionContextSyncs is automatically generated when extensionOption is provided\n * - extensionContextSyncs will be undefined if no extensionOption is provided\n * - extensionContextSyncs will be a ContextSync[] if extensionOption is valid\n */\n constructor(\n contextId: string,\n autoUpload: boolean = true,\n extensionOption?: ExtensionOption\n ) {\n this.contextId = contextId;\n this.autoUpload = autoUpload;\n this.extensionOption = extensionOption;\n\n // Handle extension configuration from ExtensionOption\n if (extensionOption) {\n // Extract extension information from ExtensionOption\n this.extensionContextId = extensionOption.contextId;\n this.extensionIds = extensionOption.extensionIds;\n // Auto-generate extension context syncs\n this.extensionContextSyncs = this._createExtensionContextSyncs();\n } else {\n // No extension configuration provided\n this.extensionContextId = undefined;\n this.extensionIds = [];\n this.extensionContextSyncs = undefined;\n }\n }\n\n /**\n * Create ContextSync configurations for browser extensions.\n *\n * This method is called only when extensionOption is provided and contains\n * valid extension configuration (contextId and extensionIds).\n *\n * @returns ContextSync[] - List of context sync configurations for extensions.\n * Returns empty list if extension configuration is invalid.\n */\n private _createExtensionContextSyncs(): ContextSync[] {\n if (!this.extensionIds || this.extensionIds.length === 0 || !this.extensionContextId) {\n return [];\n }\n\n // Create whitelist for each extension ID\n const whiteLists: WhiteList[] = this.extensionIds.map(extId => ({\n path: extId,\n excludePaths: []\n }));\n\n // Create sync policy for extensions\n const syncPolicy: SyncPolicy = {\n uploadPolicy: {\n ...newUploadPolicy(),\n autoUpload: false\n },\n extractPolicy: {\n ...newExtractPolicy(),\n extract: true,\n deleteSrcFile: true\n },\n deletePolicy: {\n ...newDeletePolicy(),\n syncLocalFile: false\n },\n recyclePolicy: newRecyclePolicy(),\n bwList: {\n whiteLists: whiteLists\n }\n };\n\n // Create context sync for extensions\n const extensionSync = new ContextSync(\n this.extensionContextId,\n \"/tmp/extensions/\",\n syncPolicy\n );\n\n return [extensionSync];\n }\n\n /**\n * Get all context syncs including extension syncs.\n *\n * @returns ContextSync[] - All context sync configurations. Returns empty list if no extensions configured.\n */\n getAllContextSyncs(): ContextSync[] {\n return this.extensionContextSyncs || [];\n }\n}\n\n/**\n * Configuration interface for CreateSessionParams\n */\nexport interface CreateSessionParamsConfig {\n labels: Record<string, string>;\n imageId?: string;\n contextSync: ContextSync[];\n /** Optional configuration for browser data synchronization */\n browserContext?: BrowserContext;\n /** Whether to create a VPC-based session. Defaults to false. */\n isVpc?: boolean;\n /** Policy id to apply when creating the session. */\n policyId?: string;\n /** Whether to enable browser recording for the session. Defaults to false. */\n enableBrowserReplay?: boolean;\n /** Extra configuration settings for different session types (e.g., mobile) */\n extraConfigs?: ExtraConfigs;\n}\n\n/**\n * CreateSessionParams provides a way to configure the parameters for creating a new session\n * in the AgentBay cloud environment.\n */\nexport class CreateSessionParams implements CreateSessionParamsConfig {\n /** Custom labels for the Session. These can be used for organizing and filtering sessions. */\n public labels: Record<string, string>;\n\n /** Image ID to use for the session. */\n public imageId?: string;\n\n /**\n * List of context synchronization configurations.\n * These configurations define how contexts should be synchronized and mounted.\n */\n public contextSync: ContextSync[];\n\n /** Optional configuration for browser data synchronization. */\n public browserContext?: BrowserContext;\n\n /** Whether to create a VPC-based session. Defaults to false. */\n public isVpc: boolean;\n\n /** Policy id to apply when creating the session. */\n public policyId?: string;\n\n /** Whether to enable browser recording for the session. Defaults to false. */\n public enableBrowserReplay: boolean;\n\n /** Extra configuration settings for different session types (e.g., mobile) */\n public extraConfigs?: ExtraConfigs;\n\n constructor() {\n this.labels = {};\n this.contextSync = [];\n this.isVpc = false;\n this.enableBrowserReplay = false;\n }\n\n /**\n * WithLabels sets the labels for the session parameters and returns the updated parameters.\n */\n withLabels(labels: Record<string, string>): CreateSessionParams {\n this.labels = labels;\n return this;\n }\n\n\n /**\n * WithImageId sets the image ID for the session parameters and returns the updated parameters.\n */\n withImageId(imageId: string): CreateSessionParams {\n this.imageId = imageId;\n return this;\n }\n\n /**\n * WithBrowserContext sets the browser context for the session parameters and returns the updated parameters.\n */\n withBrowserContext(browserContext: BrowserContext): CreateSessionParams {\n this.browserContext = browserContext;\n return this;\n }\n\n /**\n * WithIsVpc sets the VPC flag for the session parameters and returns the updated parameters.\n */\n withIsVpc(isVpc: boolean): CreateSessionParams {\n this.isVpc = isVpc;\n return this;\n }\n\n /**\n * WithPolicyId sets the policy id for the session parameters and returns the updated parameters.\n */\n withPolicyId(policyId: string): CreateSessionParams {\n this.policyId = policyId;\n return this;\n }\n\n /**\n * WithenableBrowserReplay sets the browser recording flag for the session parameters and returns the updated parameters.\n */\n withEnableBrowserReplay(enableBrowserReplay: boolean): CreateSessionParams {\n this.enableBrowserReplay = enableBrowserReplay;\n return this;\n }\n\n /**\n * Alias for withEnableBrowserReplay for backward compatibility.\n */\n withEnableRecord(enableRecord: boolean): CreateSessionParams {\n return this.withEnableBrowserReplay(enableRecord);\n }\n\n /**\n * WithExtraConfigs sets the extra configurations for the session parameters and returns the updated parameters.\n */\n withExtraConfigs(extraConfigs: ExtraConfigs): CreateSessionParams {\n this.extraConfigs = extraConfigs;\n return this;\n }\n\n /**\n * GetLabelsJSON returns the labels as a JSON string.\n * Returns an object with success status and result/error message to match Go version behavior.\n */\n getLabelsJSON(): { result: string; error?: string } {\n if (Object.keys(this.labels).length === 0) {\n return { result: \"\" };\n }\n\n try {\n const labelsJSON = JSON.stringify(this.labels);\n return { result: labelsJSON };\n } catch (error) {\n return {\n result: \"\",\n error: `Failed to marshal labels to JSON: ${error}`,\n };\n }\n }\n\n /**\n * GetExtraConfigsJSON returns the extra configs as a JSON string.\n * Returns an object with result and optional error message to match Go version behavior.\n */\n getExtraConfigsJSON(): { result: string; error?: string } {\n if (!this.extraConfigs) {\n return { result: \"\" };\n }\n\n try {\n const extraConfigsJSON = extraConfigsToJSON(this.extraConfigs);\n return { result: extraConfigsJSON };\n } catch (error) {\n return {\n result: \"\",\n error: `Failed to marshal extra configs to JSON: ${error}`,\n };\n }\n }\n\n /**\n * AddContextSync adds a context sync configuration to the session parameters.\n */\n addContextSync(\n contextId: string,\n path: string,\n policy?: SyncPolicy\n ): CreateSessionParams {\n const contextSync = new ContextSync(contextId, path, policy);\n this.contextSync.push(contextSync);\n return this;\n }\n\n /**\n * AddContextSyncConfig adds a pre-configured context sync to the session parameters.\n */\n addContextSyncConfig(contextSync: ContextSync): CreateSessionParams {\n this.contextSync.push(contextSync);\n return this;\n }\n\n /**\n * WithContextSync sets the context sync configurations for the session parameters.\n */\n withContextSync(contextSyncs: ContextSync[]): CreateSessionParams {\n this.contextSync = contextSyncs;\n return this;\n }\n\n /**\n * Convert to plain object for JSON serialization\n */\n toJSON(): CreateSessionParamsConfig {\n // Get base context syncs\n let allContextSyncs = [...this.contextSync];\n\n // Add extension context syncs if browser context has them\n if (this.browserContext && 'getAllContextSyncs' in this.browserContext) {\n const extensionSyncs = this.browserContext.getAllContextSyncs();\n allContextSyncs = allContextSyncs.concat(extensionSyncs);\n }\n\n return {\n labels: this.labels,\n imageId: this.imageId,\n contextSync: allContextSyncs,\n browserContext: this.browserContext,\n isVpc: this.isVpc,\n policyId: this.policyId,\n enableBrowserReplay: this.enableBrowserReplay,\n extraConfigs: this.extraConfigs,\n };\n }\n\n /**\n * Create from plain object\n */\n static fromJSON(config: CreateSessionParamsConfig): CreateSessionParams {\n const params = new CreateSessionParams();\n params.labels = config.labels || {};\n params.imageId = config.imageId;\n params.contextSync = config.contextSync || [];\n\n // Handle browser context - convert to BrowserContext class if needed\n if (config.browserContext) {\n if ('getAllContextSyncs' in config.browserContext) {\n // It's already a BrowserContext instance\n params.browserContext = config.browserContext;\n } else {\n // It's a plain object, convert to BrowserContext class\n const bc = config.browserContext as any; // Type assertion for plain object\n params.browserContext = new BrowserContext(\n bc.contextId,\n bc.autoUpload,\n bc.extensionOption\n );\n }\n }\n\n params.isVpc = config.isVpc || false;\n params.policyId = config.policyId;\n params.enableBrowserReplay = config.enableBrowserReplay || false;\n params.extraConfigs = config.extraConfigs;\n return params;\n }\n}\n\n/**\n * NewCreateSessionParams creates a new CreateSessionParams with default values.\n */\nexport function newCreateSessionParams(): CreateSessionParams {\n return new CreateSessionParams();\n}"]}