@midscene/playground 1.0.1-beta-20251208112226.0 → 1.0.1-beta-20251209112631.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.
@@ -49,6 +49,14 @@ class LocalExecutionAdapter extends BasePlaygroundAdapter {
49
49
  async overrideConfig(aiConfig) {
50
50
  overrideAIConfig(aiConfig);
51
51
  }
52
+ async detachDebuggerSafely() {
53
+ try {
54
+ const page = this.agent?.interface;
55
+ await page?.detachDebugger?.();
56
+ } catch (error) {
57
+ console.warn('Failed to detach debugger:', error);
58
+ }
59
+ }
52
60
  async executeAction(actionType, value, options) {
53
61
  const actionSpace = await this.getActionSpace();
54
62
  let originalOnTaskStartTip;
@@ -80,9 +88,13 @@ class LocalExecutionAdapter extends BasePlaygroundAdapter {
80
88
  } catch (error) {
81
89
  console.error('Failed to get dump/reportHTML from agent:', error);
82
90
  }
83
- this.agent.resetDump();
84
91
  return response;
85
92
  } finally{
93
+ try {
94
+ this.agent.resetDump();
95
+ } catch (error) {
96
+ console.error('Failed to reset dump:', error);
97
+ }
86
98
  if (options.requestId) {
87
99
  this.cleanup(options.requestId);
88
100
  if (this.agent) this.agent.onTaskStartTip = originalOnTaskStartTip;
@@ -1 +1 @@
1
- {"version":3,"file":"adapters/local-execution.mjs","sources":["../../../src/adapters/local-execution.ts"],"sourcesContent":["import type { DeviceAction } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private taskProgressTips: Record<string, string> = {};\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n setProgressCallback(callback: (tip: string) => void): void {\n // Clear any existing callback before setting new one\n this.progressCallback = undefined;\n // Set the new callback\n this.progressCallback = callback;\n }\n\n private cleanup(requestId: string): void {\n delete this.taskProgressTips[requestId];\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => DeviceAction<unknown>[];\n };\n if (page?.actionSpace) {\n return page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => DeviceAction<unknown>[];\n };\n return contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let originalOnTaskStartTip: ((tip: string) => void) | undefined;\n\n // Setup progress tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n originalOnTaskStartTip = this.agent.onTaskStartTip;\n\n // Set up a fresh callback\n this.agent.onTaskStartTip = (tip: string) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Store tip for our progress tracking\n this.taskProgressTips[options.requestId!] = tip;\n\n // Call the direct progress callback set via setProgressCallback\n if (this.progressCallback) {\n this.progressCallback(tip);\n }\n\n if (typeof originalOnTaskStartTip === 'function') {\n originalOnTaskStartTip(tip);\n }\n };\n }\n\n try {\n // Call the base implementation with the original signature\n const result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n\n // For local execution, we need to package the result with dump and reportHTML\n // similar to how the server does it\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: null as string | null,\n };\n\n try {\n // Get dump and reportHTML from agent like the server does\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n response.dump = JSON.parse(dumpString);\n }\n }\n\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n this.agent.resetDump();\n\n return response;\n } finally {\n // Always clean up progress tracking to prevent memory leaks\n if (options.requestId) {\n this.cleanup(options.requestId);\n // Clear the agent callback to prevent accumulation\n if (this.agent) {\n this.agent.onTaskStartTip = originalOnTaskStartTip;\n }\n }\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\n // Return the stored tip for this requestId\n return { tip: this.taskProgressTips[requestId] || undefined };\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","requestId","action","params","options","parseStructuredParams","error","errorMessage","context","page","contextPage","aiConfig","overrideAIConfig","actionType","value","actionSpace","originalOnTaskStartTip","tip","result","executeAction","response","dumpString","JSON","console","_requestId","Error","type","description","agent","uuid"],"mappings":"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"}
1
+ {"version":3,"file":"adapters/local-execution.mjs","sources":["../../../src/adapters/local-execution.ts"],"sourcesContent":["import type { DeviceAction } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private taskProgressTips: Record<string, string> = {};\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n setProgressCallback(callback: (tip: string) => void): void {\n // Clear any existing callback before setting new one\n this.progressCallback = undefined;\n // Set the new callback\n this.progressCallback = callback;\n }\n\n private cleanup(requestId: string): void {\n delete this.taskProgressTips[requestId];\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => DeviceAction<unknown>[];\n };\n if (page?.actionSpace) {\n return page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => DeviceAction<unknown>[];\n };\n return contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n /**\n * Safely detaches the Chrome debugger without destroying the agent.\n * This removes the \"Debugger attached\" banner from the browser window\n * while keeping the agent instance intact for potential reuse.\n * Called on errors to improve user experience by cleaning up the UI.\n */\n private async detachDebuggerSafely() {\n try {\n const page = this.agent?.interface as\n | { detachDebugger?: () => Promise<void> }\n | undefined;\n await page?.detachDebugger?.();\n } catch (error) {\n console.warn('Failed to detach debugger:', error);\n }\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let originalOnTaskStartTip: ((tip: string) => void) | undefined;\n\n // Setup progress tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n originalOnTaskStartTip = this.agent.onTaskStartTip;\n\n // Set up a fresh callback\n this.agent.onTaskStartTip = (tip: string) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Store tip for our progress tracking\n this.taskProgressTips[options.requestId!] = tip;\n\n // Call the direct progress callback set via setProgressCallback\n if (this.progressCallback) {\n this.progressCallback(tip);\n }\n\n if (typeof originalOnTaskStartTip === 'function') {\n originalOnTaskStartTip(tip);\n }\n };\n }\n\n try {\n // Call the base implementation with the original signature\n const result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n\n // For local execution, we need to package the result with dump and reportHTML\n // similar to how the server does it\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: null as string | null,\n };\n\n try {\n // Get dump and reportHTML from agent like the server does\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n response.dump = JSON.parse(dumpString);\n }\n }\n\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n return response;\n } finally {\n // Always reset dump to clear execution history\n try {\n this.agent.resetDump();\n } catch (error: unknown) {\n console.error('Failed to reset dump:', error);\n }\n\n // Always clean up progress tracking to prevent memory leaks\n if (options.requestId) {\n this.cleanup(options.requestId);\n // Clear the agent callback to prevent accumulation\n if (this.agent) {\n this.agent.onTaskStartTip = originalOnTaskStartTip;\n }\n }\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\n // Return the stored tip for this requestId\n return { tip: this.taskProgressTips[requestId] || undefined };\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","requestId","action","params","options","parseStructuredParams","error","errorMessage","context","page","contextPage","aiConfig","overrideAIConfig","console","actionType","value","actionSpace","originalOnTaskStartTip","tip","result","executeAction","response","dumpString","JSON","_requestId","Error","type","description","agent","uuid"],"mappings":"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"}
@@ -155,9 +155,9 @@ class BasePlaygroundAdapter {
155
155
  }
156
156
  }
157
157
  exports.BasePlaygroundAdapter = __webpack_exports__.BasePlaygroundAdapter;
158
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
158
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
159
159
  "BasePlaygroundAdapter"
160
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
160
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
161
161
  Object.defineProperty(exports, '__esModule', {
162
162
  value: true
163
163
  });
@@ -77,6 +77,14 @@ class LocalExecutionAdapter extends external_base_js_namespaceObject.BasePlaygro
77
77
  async overrideConfig(aiConfig) {
78
78
  (0, env_namespaceObject.overrideAIConfig)(aiConfig);
79
79
  }
80
+ async detachDebuggerSafely() {
81
+ try {
82
+ const page = this.agent?.interface;
83
+ await page?.detachDebugger?.();
84
+ } catch (error) {
85
+ console.warn('Failed to detach debugger:', error);
86
+ }
87
+ }
80
88
  async executeAction(actionType, value, options) {
81
89
  const actionSpace = await this.getActionSpace();
82
90
  let originalOnTaskStartTip;
@@ -108,9 +116,13 @@ class LocalExecutionAdapter extends external_base_js_namespaceObject.BasePlaygro
108
116
  } catch (error) {
109
117
  console.error('Failed to get dump/reportHTML from agent:', error);
110
118
  }
111
- this.agent.resetDump();
112
119
  return response;
113
120
  } finally{
121
+ try {
122
+ this.agent.resetDump();
123
+ } catch (error) {
124
+ console.error('Failed to reset dump:', error);
125
+ }
114
126
  if (options.requestId) {
115
127
  this.cleanup(options.requestId);
116
128
  if (this.agent) this.agent.onTaskStartTip = originalOnTaskStartTip;
@@ -160,9 +172,9 @@ class LocalExecutionAdapter extends external_base_js_namespaceObject.BasePlaygro
160
172
  }
161
173
  }
162
174
  exports.LocalExecutionAdapter = __webpack_exports__.LocalExecutionAdapter;
163
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
175
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
164
176
  "LocalExecutionAdapter"
165
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
177
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
166
178
  Object.defineProperty(exports, '__esModule', {
167
179
  value: true
168
180
  });
@@ -1 +1 @@
1
- {"version":3,"file":"adapters/local-execution.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/adapters/local-execution.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private taskProgressTips: Record<string, string> = {};\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n setProgressCallback(callback: (tip: string) => void): void {\n // Clear any existing callback before setting new one\n this.progressCallback = undefined;\n // Set the new callback\n this.progressCallback = callback;\n }\n\n private cleanup(requestId: string): void {\n delete this.taskProgressTips[requestId];\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => DeviceAction<unknown>[];\n };\n if (page?.actionSpace) {\n return page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => DeviceAction<unknown>[];\n };\n return contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let originalOnTaskStartTip: ((tip: string) => void) | undefined;\n\n // Setup progress tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n originalOnTaskStartTip = this.agent.onTaskStartTip;\n\n // Set up a fresh callback\n this.agent.onTaskStartTip = (tip: string) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Store tip for our progress tracking\n this.taskProgressTips[options.requestId!] = tip;\n\n // Call the direct progress callback set via setProgressCallback\n if (this.progressCallback) {\n this.progressCallback(tip);\n }\n\n if (typeof originalOnTaskStartTip === 'function') {\n originalOnTaskStartTip(tip);\n }\n };\n }\n\n try {\n // Call the base implementation with the original signature\n const result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n\n // For local execution, we need to package the result with dump and reportHTML\n // similar to how the server does it\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: null as string | null,\n };\n\n try {\n // Get dump and reportHTML from agent like the server does\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n response.dump = JSON.parse(dumpString);\n }\n }\n\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n this.agent.resetDump();\n\n return response;\n } finally {\n // Always clean up progress tracking to prevent memory leaks\n if (options.requestId) {\n this.cleanup(options.requestId);\n // Clear the agent callback to prevent accumulation\n if (this.agent) {\n this.agent.onTaskStartTip = originalOnTaskStartTip;\n }\n }\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\n // Return the stored tip for this requestId\n return { tip: this.taskProgressTips[requestId] || undefined };\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","requestId","action","params","options","parseStructuredParams","error","errorMessage","context","page","contextPage","aiConfig","overrideAIConfig","actionType","value","actionSpace","originalOnTaskStartTip","tip","result","executeAction","response","dumpString","JSON","console","_requestId","Error","type","description","agent","uuid"],"mappings":"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"}
1
+ {"version":3,"file":"adapters/local-execution.js","sources":["webpack/runtime/define_property_getters","webpack/runtime/has_own_property","webpack/runtime/make_namespace_object","../../../src/adapters/local-execution.ts"],"sourcesContent":["__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n if(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n }\n }\n};","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","// define __esModule on exports\n__webpack_require__.r = (exports) => {\n\tif(typeof Symbol !== 'undefined' && Symbol.toStringTag) {\n\t\tObject.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });\n\t}\n\tObject.defineProperty(exports, '__esModule', { value: true });\n};","import type { DeviceAction } from '@midscene/core';\nimport { overrideAIConfig } from '@midscene/shared/env';\nimport { uuid } from '@midscene/shared/utils';\nimport { executeAction, parseStructuredParams } from '../common';\nimport type { ExecutionOptions, FormValue, PlaygroundAgent } from '../types';\nimport { BasePlaygroundAdapter } from './base';\n\nexport class LocalExecutionAdapter extends BasePlaygroundAdapter {\n private agent: PlaygroundAgent;\n private taskProgressTips: Record<string, string> = {};\n private progressCallback?: (tip: string) => void;\n private readonly _id: string; // Unique identifier for this local adapter instance\n private currentRequestId?: string; // Track current request to prevent stale callbacks\n\n constructor(agent: PlaygroundAgent) {\n super();\n this.agent = agent;\n this._id = uuid(); // Generate unique ID for local adapter\n }\n\n // Get adapter ID\n get id(): string {\n return this._id;\n }\n\n setProgressCallback(callback: (tip: string) => void): void {\n // Clear any existing callback before setting new one\n this.progressCallback = undefined;\n // Set the new callback\n this.progressCallback = callback;\n }\n\n private cleanup(requestId: string): void {\n delete this.taskProgressTips[requestId];\n }\n\n async parseStructuredParams(\n action: DeviceAction<unknown>,\n params: Record<string, unknown>,\n options: ExecutionOptions,\n ): Promise<unknown[]> {\n // Use shared implementation from common.ts\n return await parseStructuredParams(action, params, options);\n }\n\n formatErrorMessage(error: any): string {\n const errorMessage = error?.message || '';\n if (errorMessage.includes('of different extension')) {\n return 'Conflicting extension detected. Please disable the suspicious plugins and refresh the page. Guide: https://midscenejs.com/quick-experience.html#faq';\n }\n return this.formatBasicErrorMessage(error);\n }\n\n // Local execution - use base implementation\n // (inherits default executeAction from BasePlaygroundAdapter)\n\n // Local execution gets actionSpace from internal agent (parameter is for backward compatibility)\n async getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]> {\n // Priority 1: Use agent's getActionSpace method\n if (this.agent?.getActionSpace) {\n return await this.agent.getActionSpace();\n }\n\n // Priority 2: Use agent's interface.actionSpace method\n if (\n this.agent &&\n 'interface' in this.agent &&\n typeof this.agent.interface === 'object'\n ) {\n const page = this.agent.interface as {\n actionSpace?: () => DeviceAction<unknown>[];\n };\n if (page?.actionSpace) {\n return page.actionSpace();\n }\n }\n\n // Priority 3: Fallback to context parameter (for backward compatibility with tests)\n if (context && typeof context === 'object' && 'actionSpace' in context) {\n const contextPage = context as {\n actionSpace: () => DeviceAction<unknown>[];\n };\n return contextPage.actionSpace();\n }\n\n return [];\n }\n\n // Local execution doesn't use a server, so always return true\n async checkStatus(): Promise<boolean> {\n return true;\n }\n\n async overrideConfig(aiConfig: Record<string, unknown>): Promise<void> {\n // For local execution, use the shared env override function\n overrideAIConfig(aiConfig);\n }\n\n /**\n * Safely detaches the Chrome debugger without destroying the agent.\n * This removes the \"Debugger attached\" banner from the browser window\n * while keeping the agent instance intact for potential reuse.\n * Called on errors to improve user experience by cleaning up the UI.\n */\n private async detachDebuggerSafely() {\n try {\n const page = this.agent?.interface as\n | { detachDebugger?: () => Promise<void> }\n | undefined;\n await page?.detachDebugger?.();\n } catch (error) {\n console.warn('Failed to detach debugger:', error);\n }\n }\n\n async executeAction(\n actionType: string,\n value: FormValue,\n options: ExecutionOptions,\n ): Promise<unknown> {\n // Get actionSpace using our simplified getActionSpace method\n const actionSpace = await this.getActionSpace();\n let originalOnTaskStartTip: ((tip: string) => void) | undefined;\n\n // Setup progress tracking if requestId is provided\n if (options.requestId && this.agent) {\n // Track current request ID to prevent stale callbacks\n this.currentRequestId = options.requestId;\n originalOnTaskStartTip = this.agent.onTaskStartTip;\n\n // Set up a fresh callback\n this.agent.onTaskStartTip = (tip: string) => {\n // Only process if this is still the current request\n if (this.currentRequestId !== options.requestId) {\n return;\n }\n\n // Store tip for our progress tracking\n this.taskProgressTips[options.requestId!] = tip;\n\n // Call the direct progress callback set via setProgressCallback\n if (this.progressCallback) {\n this.progressCallback(tip);\n }\n\n if (typeof originalOnTaskStartTip === 'function') {\n originalOnTaskStartTip(tip);\n }\n };\n }\n\n try {\n // Call the base implementation with the original signature\n const result = await executeAction(\n this.agent,\n actionType,\n actionSpace,\n value,\n options,\n );\n\n // For local execution, we need to package the result with dump and reportHTML\n // similar to how the server does it\n const response = {\n result,\n dump: null as unknown,\n reportHTML: null as string | null,\n error: null as string | null,\n };\n\n try {\n // Get dump and reportHTML from agent like the server does\n if (this.agent.dumpDataString) {\n const dumpString = this.agent.dumpDataString();\n if (dumpString) {\n response.dump = JSON.parse(dumpString);\n }\n }\n\n if (this.agent.reportHTMLString) {\n response.reportHTML = this.agent.reportHTMLString() || null;\n }\n\n // Write out action dumps\n if (this.agent.writeOutActionDumps) {\n this.agent.writeOutActionDumps();\n }\n } catch (error: unknown) {\n console.error('Failed to get dump/reportHTML from agent:', error);\n }\n\n return response;\n } finally {\n // Always reset dump to clear execution history\n try {\n this.agent.resetDump();\n } catch (error: unknown) {\n console.error('Failed to reset dump:', error);\n }\n\n // Always clean up progress tracking to prevent memory leaks\n if (options.requestId) {\n this.cleanup(options.requestId);\n // Clear the agent callback to prevent accumulation\n if (this.agent) {\n this.agent.onTaskStartTip = originalOnTaskStartTip;\n }\n }\n }\n }\n\n async getTaskProgress(requestId: string): Promise<{ tip?: string }> {\n // Return the stored tip for this requestId\n return { tip: this.taskProgressTips[requestId] || undefined };\n }\n\n // Local execution task cancellation - minimal implementation\n async cancelTask(\n _requestId: string,\n ): Promise<{ error?: string; success?: boolean }> {\n if (!this.agent) {\n return { error: 'No active agent found for this requestId' };\n }\n\n try {\n await this.agent.destroy?.();\n return { success: true };\n } catch (error: unknown) {\n const errorMessage =\n error instanceof Error ? error.message : 'Unknown error';\n console.error(`Failed to cancel agent: ${errorMessage}`);\n return { error: `Failed to cancel: ${errorMessage}` };\n }\n }\n\n // Get interface information from the agent\n async getInterfaceInfo(): Promise<{\n type: string;\n description?: string;\n } | null> {\n if (!this.agent?.interface) {\n return null;\n }\n\n try {\n const type = this.agent.interface.interfaceType || 'Unknown';\n const description = this.agent.interface.describe?.() || undefined;\n\n return {\n type,\n description,\n };\n } catch (error: unknown) {\n console.error('Failed to get interface info:', error);\n return null;\n }\n }\n}\n"],"names":["__webpack_require__","definition","key","Object","obj","prop","Symbol","LocalExecutionAdapter","BasePlaygroundAdapter","callback","undefined","requestId","action","params","options","parseStructuredParams","error","errorMessage","context","page","contextPage","aiConfig","overrideAIConfig","console","actionType","value","actionSpace","originalOnTaskStartTip","tip","result","executeAction","response","dumpString","JSON","_requestId","Error","type","description","agent","uuid"],"mappings":"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"}
@@ -334,9 +334,9 @@ class RemoteExecutionAdapter extends external_base_js_namespaceObject.BasePlaygr
334
334
  }
335
335
  }
336
336
  exports.RemoteExecutionAdapter = __webpack_exports__.RemoteExecutionAdapter;
337
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
337
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
338
338
  "RemoteExecutionAdapter"
339
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
339
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
340
340
  Object.defineProperty(exports, '__esModule', {
341
341
  value: true
342
342
  });
@@ -187,7 +187,7 @@ exports.noReplayAPIs = __webpack_exports__.noReplayAPIs;
187
187
  exports.parseStructuredParams = __webpack_exports__.parseStructuredParams;
188
188
  exports.validateStructuredParams = __webpack_exports__.validateStructuredParams;
189
189
  exports.validationAPIs = __webpack_exports__.validationAPIs;
190
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
190
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
191
191
  "dataExtractionAPIs",
192
192
  "executeAction",
193
193
  "formatErrorMessage",
@@ -195,7 +195,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
195
195
  "parseStructuredParams",
196
196
  "validateStructuredParams",
197
197
  "validationAPIs"
198
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
198
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
199
199
  Object.defineProperty(exports, '__esModule', {
200
200
  value: true
201
201
  });
@@ -53,7 +53,7 @@ exports.formatErrorMessage = __webpack_exports__.formatErrorMessage;
53
53
  exports.noReplayAPIs = __webpack_exports__.noReplayAPIs;
54
54
  exports.validateStructuredParams = __webpack_exports__.validateStructuredParams;
55
55
  exports.validationAPIs = __webpack_exports__.validationAPIs;
56
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
56
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
57
57
  "BasePlaygroundAdapter",
58
58
  "LocalExecutionAdapter",
59
59
  "PlaygroundSDK",
@@ -65,7 +65,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
65
65
  "noReplayAPIs",
66
66
  "validateStructuredParams",
67
67
  "validationAPIs"
68
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
68
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
69
69
  Object.defineProperty(exports, '__esModule', {
70
70
  value: true
71
71
  });
package/dist/lib/index.js CHANGED
@@ -56,7 +56,7 @@ exports.noReplayAPIs = __webpack_exports__.noReplayAPIs;
56
56
  exports.playgroundForAgent = __webpack_exports__.playgroundForAgent;
57
57
  exports.validateStructuredParams = __webpack_exports__.validateStructuredParams;
58
58
  exports.validationAPIs = __webpack_exports__.validationAPIs;
59
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
59
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
60
60
  "BasePlaygroundAdapter",
61
61
  "LocalExecutionAdapter",
62
62
  "PlaygroundSDK",
@@ -69,7 +69,7 @@ for(var __webpack_i__ in __webpack_exports__)if (-1 === [
69
69
  "playgroundForAgent",
70
70
  "validateStructuredParams",
71
71
  "validationAPIs"
72
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
72
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
73
73
  Object.defineProperty(exports, '__esModule', {
74
74
  value: true
75
75
  });
@@ -130,9 +130,9 @@ async function openInBrowser(url, customCommand, verbose = true) {
130
130
  });
131
131
  }
132
132
  exports.playgroundForAgent = __webpack_exports__.playgroundForAgent;
133
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
133
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
134
134
  "playgroundForAgent"
135
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
135
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
136
136
  Object.defineProperty(exports, '__esModule', {
137
137
  value: true
138
138
  });
@@ -126,9 +126,9 @@ class PlaygroundSDK {
126
126
  }
127
127
  }
128
128
  exports.PlaygroundSDK = __webpack_exports__.PlaygroundSDK;
129
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
129
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
130
130
  "PlaygroundSDK"
131
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
131
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
132
132
  Object.defineProperty(exports, '__esModule', {
133
133
  value: true
134
134
  });
@@ -428,10 +428,10 @@ class PlaygroundServer {
428
428
  const server = PlaygroundServer;
429
429
  exports.PlaygroundServer = __webpack_exports__.PlaygroundServer;
430
430
  exports["default"] = __webpack_exports__["default"];
431
- for(var __webpack_i__ in __webpack_exports__)if (-1 === [
431
+ for(var __rspack_i in __webpack_exports__)if (-1 === [
432
432
  "PlaygroundServer",
433
433
  "default"
434
- ].indexOf(__webpack_i__)) exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
434
+ ].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
435
435
  Object.defineProperty(exports, '__esModule', {
436
436
  value: true
437
437
  });
package/dist/lib/types.js CHANGED
@@ -12,7 +12,7 @@ var __webpack_require__ = {};
12
12
  })();
13
13
  var __webpack_exports__ = {};
14
14
  __webpack_require__.r(__webpack_exports__);
15
- for(var __webpack_i__ in __webpack_exports__)exports[__webpack_i__] = __webpack_exports__[__webpack_i__];
15
+ for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
16
16
  Object.defineProperty(exports, '__esModule', {
17
17
  value: true
18
18
  });
@@ -16,6 +16,13 @@ export declare class LocalExecutionAdapter extends BasePlaygroundAdapter {
16
16
  getActionSpace(context?: unknown): Promise<DeviceAction<unknown>[]>;
17
17
  checkStatus(): Promise<boolean>;
18
18
  overrideConfig(aiConfig: Record<string, unknown>): Promise<void>;
19
+ /**
20
+ * Safely detaches the Chrome debugger without destroying the agent.
21
+ * This removes the "Debugger attached" banner from the browser window
22
+ * while keeping the agent instance intact for potential reuse.
23
+ * Called on errors to improve user experience by cleaning up the UI.
24
+ */
25
+ private detachDebuggerSafely;
19
26
  executeAction(actionType: string, value: FormValue, options: ExecutionOptions): Promise<unknown>;
20
27
  getTaskProgress(requestId: string): Promise<{
21
28
  tip?: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@midscene/playground",
3
- "version": "1.0.1-beta-20251208112226.0",
3
+ "version": "1.0.1-beta-20251209112631.0",
4
4
  "description": "Midscene playground utilities for web integration",
5
5
  "author": "midscene team",
6
6
  "license": "MIT",
@@ -25,11 +25,11 @@
25
25
  "express": "^4.21.2",
26
26
  "open": "10.1.0",
27
27
  "uuid": "11.1.0",
28
- "@midscene/core": "1.0.1-beta-20251208112226.0",
29
- "@midscene/shared": "1.0.1-beta-20251208112226.0"
28
+ "@midscene/core": "1.0.1-beta-20251209112631.0",
29
+ "@midscene/shared": "1.0.1-beta-20251209112631.0"
30
30
  },
31
31
  "devDependencies": {
32
- "@rslib/core": "^0.18.2",
32
+ "@rslib/core": "^0.18.3",
33
33
  "@types/cors": "^2.8.17",
34
34
  "@types/express": "^4.17.21",
35
35
  "@types/node": "^18.0.0",
package/static/index.html CHANGED
@@ -1 +1 @@
1
- <!doctype html><html><head><link rel="icon" href="/favicon.ico"><title>Midscene Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.bc3a3965.js"></script><script defer src="/static/js/430.adc9a336.js"></script><script defer src="/static/js/index.e0568653.js"></script><link href="/static/css/index.987d3a64.css" rel="stylesheet"></head><body><div id="root"></div></body></html>
1
+ <!doctype html><html><head><link rel="icon" href="/favicon.ico"><title>Midscene Playground</title><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><script defer src="/static/js/lib-react.bc3a3965.js"></script><script defer src="/static/js/430.adc9a336.js"></script><script defer src="/static/js/index.7cdfccfc.js"></script><link href="/static/css/index.7fc783ce.css" rel="stylesheet"></head><body><div id="root"></div></body></html>
@@ -0,0 +1,2 @@
1
+ body{margin:0;padding:0;font-family:-apple-system,BlinkMacSystemFont,Segoe UI,Noto Sans,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;font-size:14px}h3{text-transform:capitalize}.app-container{background-color:#f5f5f5;flex-direction:column;width:100%;height:100vh;display:flex}.app-content{height:100vh;overflow:hidden}.app-grid-layout{height:100%;display:flex}.app-grid-layout .ant-row{flex-wrap:nowrap;flex:1;width:100%;height:100%;display:flex}.app-panel{background-color:#fff;border-radius:0;height:100%;transition:box-shadow .3s;overflow:hidden;box-shadow:0 1px 2px #0000000d}.app-panel:hover{box-shadow:0 2px 8px #00000017}.app-panel.left-panel{flex-direction:column;height:100%;display:flex;overflow:hidden}.app-panel.right-panel{border-radius:0;flex:1;overflow:hidden;box-shadow:-4px 0 20px #0000000a}.panel-content{flex-direction:column;height:100%;display:flex;overflow:auto}.panel-content.left-panel-content{flex-direction:column;height:100%;display:flex;overflow:hidden}.panel-content.left-panel-content .playground-panel-header{border-bottom:1px solid #0000000f;flex-shrink:0;align-items:center;height:60px;padding:0 24px;display:flex}.panel-content.left-panel-content .playground-panel-header .header-row{justify-content:space-between;align-items:center;gap:10px;width:100%;display:flex}.panel-content.left-panel-content .playground-panel-header h2{color:#1890ff;margin:0 0 16px;font-size:18px;font-weight:600}.panel-content.left-panel-content .playground-panel-playground{flex-direction:column;flex:1;min-height:0;padding:0 24px;display:flex}.panel-content.left-panel-content .playground-panel-playground .playground-container{background:#fff;border:none;border-radius:8px;flex:1;overflow:hidden}.panel-content.right-panel-content{border-radius:0;padding:0 24px 24px}.server-offline-container{background:#f5f5f5;justify-content:center;align-items:center;height:100vh;display:flex}.server-offline-container .server-offline-message{background:#f2f4f7;border-radius:8px;flex-direction:column;width:100%;height:100%;padding:14px 24px 0;display:flex;box-shadow:0 2px 8px #0000000f}.server-offline-container .server-offline-message .server-offline-content{text-align:center;flex-direction:column;flex:1;justify-content:flex-start;align-items:center;padding-top:20vh;display:flex}.server-offline-container .server-offline-message .server-offline-icon{display:inline-block;position:relative}.server-offline-container .server-offline-message .server-offline-icon .icon-background,.server-offline-container .server-offline-message .server-offline-icon .icon-foreground{display:block;position:absolute;top:50%;left:50%;transform:translate(-50%,-50%)}.server-offline-container .server-offline-message .server-offline-icon .icon-background{z-index:1;width:300px;height:212px}.server-offline-container .server-offline-message .server-offline-icon .icon-foreground{z-index:2;width:134px;height:101px}.server-offline-container .server-offline-message .server-offline-icon:after{content:"";width:300px;height:212px;display:block;position:relative}.server-offline-container .server-offline-message h1{letter-spacing:0%;color:#000;margin:0;font-size:18px;font-weight:600}.server-offline-container .server-offline-message .connection-status{letter-spacing:0%;text-align:center;margin-top:8px;font-size:12px}.panel-resize-handle{background-color:#f0f0f0;transition:background-color .2s;position:relative}.panel-resize-handle.horizontal{cursor:col-resize;width:1px}.panel-resize-handle.vertical{cursor:row-resize;height:1px}.panel-resize-handle:hover,.panel-resize-handle:active,.panel-resize-handle[data-resize-handle-active]{background-color:#1677ff}.clear-button-container{top:20px!important;right:-4px!important}.logo img{vertical-align:baseline;height:30px;vertical-align:-webkit-baseline-middle;line-height:30px}.logo-with-star-wrapper{flex-direction:row;justify-content:space-between;display:flex}.nav-actions{align-items:center;gap:8px;display:flex}.nav-actions .nav-icon{color:#000000a6;cursor:pointer;font-size:16px;transition:color .3s}.nav-actions .nav-icon:hover{color:#2b83ff}.nav-actions a{align-items:center;text-decoration:none;display:flex}.nav-actions a:hover .nav-icon{color:#2b83ff}[data-theme=dark] .nav-actions .nav-icon{color:#f8fafd}[data-theme=dark] .nav-actions .nav-icon:hover{color:#2b83ff}.blackboard .footer{color:#aaa}.blackboard ul{padding-left:0}.blackboard li{list-style:none}.blackboard .bottom-tip{height:30px}.blackboard .bottom-tip-item{color:#aaa;text-overflow:ellipsis;word-wrap:break-word;max-width:500px}.blackboard-filter{margin:10px 0}.blackboard-main-content canvas{box-sizing:border-box;border:1px solid #888;width:100%}[data-theme=dark] .blackboard .footer,[data-theme=dark] .blackboard .bottom-tip-item{color:#ffffff73}[data-theme=dark] .blackboard-main-content canvas{border-color:#ffffff1f}.shiny-text{color:#0000;letter-spacing:.5px;text-shadow:0 1px 2px #0000000d;background-image:linear-gradient(45deg,#2b83ff,#6a11cb,#2575fc,#4481eb);background-size:300%;-webkit-background-clip:text;background-clip:text;font-weight:600;animation:8s infinite textGradient;display:inline-block;position:relative;overflow:hidden}.shiny-text:after{content:"";width:120%;height:120%;animation:shine var(--animation-duration,5s)cubic-bezier(.25,.1,.25,1)infinite;z-index:1;pointer-events:none;background:linear-gradient(90deg,#fff0 0%,#ffffff1a 10%,#fff9 50%,#ffffff1a 90%,#fff0 100%);position:absolute;top:-10%;left:-150%;transform:skew(-20deg)translateY(0)}.shiny-text.disabled{background:#2b83ff;-webkit-background-clip:text;background-clip:text;animation:none}.shiny-text.disabled:after{animation:none;display:none}@keyframes shine{0%{opacity:.7;left:-150%}20%{opacity:1}80%{opacity:1}to{opacity:.7;left:250%}}@keyframes textGradient{0%{background-position:0%}50%{background-position:100%}to{background-position:0%}}.env-config-reminder{background:#fff2e8;border-radius:12px;align-items:center;gap:12px;margin-bottom:12px;padding:12px 16px;display:flex}.env-config-reminder .reminder-icon{color:#fa541c;width:16px;height:16px}.env-config-reminder .reminder-text{color:#000;flex:1;font-size:14px}[data-theme=dark] .env-config-reminder{background:#5226074d}[data-theme=dark] .env-config-reminder .reminder-text{color:#f8fafd}.player-container{box-sizing:border-box;background:#f2f4f7;border:1px solid #f2f4f7;border-radius:8px;flex-direction:column;width:100%;max-width:100%;height:100%;min-height:300px;max-height:100%;margin:0 auto;padding:12px;line-height:100%;display:flex;position:relative;overflow:visible}.player-container[data-fit-mode=height]{background:#fff}.player-container[data-fit-mode=height] .canvas-container{background-color:#f2f4f7}.player-container .canvas-container{width:100%;min-height:200px;aspect-ratio:var(--canvas-aspect-ratio,16/9);background-color:#fff;border-top-left-radius:4px;border-top-right-radius:4px;flex:none;justify-content:center;align-items:center;display:flex;position:relative;overflow:hidden}.player-container .canvas-container canvas{box-sizing:border-box;object-fit:contain;border:none;width:100%;max-width:100%;height:auto;max-height:100%;margin:0 auto;display:block}.player-container .canvas-container[data-fit-mode=height]{aspect-ratio:unset;flex:auto;height:auto;min-height:0}.player-container .canvas-container[data-fit-mode=height] canvas{width:auto;max-width:100%;height:100%;max-height:100%}.player-container .canvas-container[data-fit-mode=width]{aspect-ratio:var(--canvas-aspect-ratio,16/9)}.player-container .canvas-container[data-fit-mode=width] canvas{width:100%;height:auto}.player-container .player-timeline-wrapper{flex:none;width:100%;height:4px;margin-bottom:2px;position:relative}.player-container .player-timeline{background:#666;flex-shrink:0;width:100%;height:4px;position:relative}.player-container .player-timeline .player-timeline-progress{background:#2b83ff;height:4px;transition-timing-function:linear;position:absolute;top:0;left:0}.player-container .player-tools-wrapper{box-sizing:border-box;flex:none;width:100%;height:72px;padding:15px 16px;position:relative}.player-container .player-tools{color:#000;box-sizing:border-box;flex-direction:row;flex-shrink:0;justify-content:space-between;width:100%;max-width:100%;height:42px;font-size:14px;display:flex;overflow:hidden}.player-container .player-tools .ant-spin{color:#333}.player-container .player-tools .player-control{flex-direction:row;flex-grow:1;align-items:center;display:flex;overflow:hidden}.player-container .player-tools .status-icon{border-radius:8px;flex-shrink:0;justify-content:center;align-items:center;width:32px;height:32px;margin-left:10px;transition:all .2s;display:flex}.player-container .player-tools .status-icon:hover{cursor:pointer;background:#f0f0f0}.player-container .player-tools .status-text{flex-direction:column;flex-grow:1;flex-shrink:1;justify-content:space-between;width:0;min-width:0;height:100%;display:flex;position:relative;overflow:hidden}.player-container .player-tools .title{font-weight:600}.player-container .player-tools .title,.player-container .player-tools .subtitle{text-overflow:ellipsis;white-space:nowrap;width:100%;overflow:hidden}.player-container .player-tools .player-tools-item{flex-direction:column;justify-content:center;height:100%;display:flex}[data-theme=dark] .player-container{background:#141414;border-color:#292929}[data-theme=dark] .player-container[data-fit-mode=height]{background:#292929;border-color:#292929}[data-theme=dark] .player-container[data-fit-mode=height] .canvas-container{background-color:#141414}[data-theme=dark] .player-container .canvas-container{background-color:#1f1f1f}[data-theme=dark] .player-container .player-tools,[data-theme=dark] .player-container .player-tools .ant-spin,[data-theme=dark] .player-container .player-tools .status-icon svg{color:#f8fafd}[data-theme=dark] .player-container .player-tools .status-icon:hover{background:#ffffff14}.result-wrapper{justify-content:center;height:100%;margin:4px 0;display:flex}.result-wrapper .loading-container{flex-direction:column;justify-content:center;align-items:center;width:100%;height:100%;display:flex}.result-wrapper .loading-container .loading-progress-text{color:#888;margin-top:8px;font-size:12px}.result-wrapper pre{white-space:pre-wrap;text-wrap:unset;word-wrap:break-word;overflow-wrap:break-word;background:#f2f4f7;border-radius:8px;margin:0;padding:14px;overflow:scroll}.playground-container{background:#fff;flex-direction:column;width:100%;height:100vh;display:flex;position:relative}.playground-container .command-form{flex-direction:column;width:100%;height:100%;display:flex}.playground-container .context-preview-section{border-bottom:1px solid #f0f0f0;flex-shrink:0;padding:16px}.playground-container .middle-dialog-area{flex-direction:column;flex:1;min-height:0;display:flex;position:relative;overflow:hidden}.playground-container .middle-dialog-area .clear-button-container{z-index:10;position:absolute;top:16px;right:0}.playground-container .middle-dialog-area .clear-button-container .clear-button{opacity:.7;transition:opacity .2s}.playground-container .middle-dialog-area .clear-button-container .clear-button:hover{opacity:1}.playground-container .middle-dialog-area .info-list-container{scrollbar-width:none;flex:1;padding-top:16px;padding-bottom:16px;overflow:hidden auto}.playground-container .middle-dialog-area .info-list-container .ant-list .ant-list-item{border-bottom:none;padding:0}.playground-container .middle-dialog-area .info-list-container .ant-list .ant-list-item .ant-card{border:1px solid #f0f0f0;border-radius:8px;box-shadow:0 1px 3px #0000001a}.playground-container .middle-dialog-area .info-list-container .ant-list .ant-list-item .ant-card:hover{box-shadow:0 2px 6px #00000026}.playground-container .middle-dialog-area .info-list-container .ant-list .ant-list-item .ant-card .ant-card-body{padding:12px}.playground-container .middle-dialog-area .info-list-container .ant-list .ant-list-empty-text{color:#999;font-style:italic}.playground-container .middle-dialog-area .info-list-container::-webkit-scrollbar{display:none}.playground-container .middle-dialog-area .info-list-container .list-item{background:0 0;border:none;padding:0}.playground-container .middle-dialog-area .scroll-to-bottom-button{z-index:10;background:#fff;border:1px solid #00000014;position:absolute;bottom:10px;right:0}.playground-container .middle-dialog-area .scroll-to-bottom-button:hover{background:#1890ff}.playground-container .middle-dialog-area .scroll-to-bottom-button:hover .anticon{color:#fff}.playground-container .middle-dialog-area .scroll-to-bottom-button .anticon{color:#333;font-size:16px}.playground-container .user-message-container{justify-content:flex-end;width:100%;margin:20px 0 30px;display:flex}.playground-container .user-message-container .user-message-bubble{color:#000000d9;text-align:left;background:#f2f4f7;border-radius:12px;max-width:80%;padding:12px 16px;font-size:14px;font-weight:400;display:inline-block}.playground-container .progress-action-item{color:#000;background:#f2f4f7;border-radius:8px;justify-content:space-between;height:36px;margin:4px 0;padding:0 12px;font-size:14px;line-height:36px;display:flex}.playground-container .progress-action-item .progress-status-icon{margin-left:4px}.playground-container .progress-action-item .progress-status-icon.loading{color:#1890ff}.playground-container .progress-action-item .progress-status-icon.completed{color:#52c41a}.playground-container .progress-action-item .progress-status-icon.error{color:#ff4d4f;font-weight:700}.playground-container .progress-description{color:#000;padding:8px 0;font-size:14px;line-height:22px;display:inline-block}.playground-container .system-message-container{flex-direction:column;display:flex}.playground-container .system-message-container .system-message-header{align-items:center;gap:8px;margin:12px 0;display:flex}.playground-container .system-message-container .system-message-header .system-message-title{font-size:12px;font-weight:400;line-height:100%}.playground-container .system-message-container .system-message-content{color:#000000d9;font-size:14px}.playground-container .system-message-container .system-message-content .system-message-text{color:#000000d9;font-size:14px;line-height:25px}.playground-container .system-message-container .system-message-content .error-message{color:#e51723;word-break:break-word;background-color:#fff;border:none;border-radius:0;align-items:flex-start;margin-bottom:16px;padding:0;font-size:14px;display:flex}.playground-container .system-message-container .system-message-content .error-message .divider{background-color:#e6e8eb;flex-shrink:0;align-self:stretch;width:1px;min-height:20px;margin:0 8px 0 0}.playground-container .system-message-container .system-message-content .loading-progress-text{color:#666;background:#f6f8fa;border-left:3px solid #1890ff;border-radius:4px;margin-top:8px;padding:8px 12px;font-size:13px}.playground-container .new-conversation-separator{flex-shrink:0;justify-content:center;align-items:center;padding:20px 0;display:flex;position:relative}.playground-container .new-conversation-separator .separator-line{background-color:#e8e8e8;height:1px;position:absolute;top:50%;left:0;right:0}.playground-container .new-conversation-separator .separator-text-container{z-index:1;background-color:#fff;padding:0 16px;position:relative}.playground-container .new-conversation-separator .separator-text-container .separator-text{color:#999;background-color:#fff;font-size:12px}.playground-container .bottom-input-section{background-color:#fff;flex-shrink:0;padding:16px 0 0}.playground-container .version-info-section{flex-shrink:0;justify-content:center;align-items:center;height:38px;display:flex}.playground-container .version-text{color:#999;text-align:center;font-size:12px}.playground-container .hidden-result-ref{display:none}.playground-container .playground-description{margin-bottom:32px}.playground-container .playground-description .description-zh{color:#333;margin:0 0 8px;font-size:16px;line-height:1.5}.playground-container .playground-description .description-en{color:#666;margin:0;font-size:14px;line-height:1.5}.playground-container .config-section{margin-bottom:24px}.playground-container .config-section .config-title{color:#333;margin:0 0 16px;font-size:18px;font-weight:600}.playground-container .config-section .config-item{align-items:center;gap:8px;margin-bottom:12px;display:flex}.playground-container .config-section .config-item .config-check{color:#52c41a;font-size:16px}.playground-container .config-section .config-item .config-label{color:#333;font-size:14px}.playground-container .config-section .config-link{color:#1890ff;font-size:14px;text-decoration:none}.playground-container .config-section .config-link:hover{text-decoration:underline}[data-theme=dark] .universal-playground .error-hint{color:#ffffff73}[data-theme=dark] .universal-playground .status-indicator{color:#f8fafd}[data-theme=dark] .universal-playground .status-indicator.error{color:#ff4d4f}[data-theme=dark] .universal-playground .status-indicator.success{color:#52c41a}[data-theme=dark] .universal-playground .operation-label{color:#f8fafd}[data-theme=dark] .universal-playground .alert-message{color:#f8fafd;background-color:#5226074d}[data-theme=dark] .universal-playground .operation-item .operation-icon-wrapper{background-color:#ffffff14}[data-theme=dark] .universal-playground .operation-item .operation-content{background-color:#0000}[data-theme=dark] .universal-playground .operation-item .operation-content .operation-title{color:#ffffff73}[data-theme=dark] .universal-playground .playground-footer{background-color:#ffffff0a}[data-theme=dark] .universal-playground .playground-footer .status-text{color:#f8fafd}[data-theme=dark] .universal-playground .results-info{color:#ffffff73}[data-theme=dark] .universal-playground .result-section .result-title,[data-theme=dark] .universal-playground .result-section .result-details,[data-theme=dark] .universal-playground .result-section .result-value{color:#f8fafd}[data-theme=dark] .universal-playground .result-section .result-value.success{color:#52c41a}[data-theme=dark] .universal-playground .result-section .result-value.error{color:#ff4d4f}.prompt-input-wrapper{width:100%}.prompt-input-wrapper .mode-radio-group-wrapper{align-items:center;gap:8px;display:flex;position:relative}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group{scrollbar-width:thin;flex:1;align-items:center;gap:8px;min-width:0;height:100%;margin-right:60px;display:flex;overflow:auto hidden}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group::-webkit-scrollbar{height:6px}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group::-webkit-scrollbar-thumb:hover{background:#a8a8a8}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-form-item{flex-shrink:0;margin:0!important}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-form-item .ant-radio-group{flex-wrap:nowrap;gap:8px;display:flex}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper{height:24px;box-shadow:none;white-space:nowrap;background-color:#f7f7f7;border:none;border-radius:11px;flex-shrink:0;margin-right:0;padding:0 8px;font-size:12px;line-height:24px}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper:before{display:none}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper:focus-within{outline:none}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked{color:#fff;background-color:#2b83ff;border-color:#2b83ff}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked:hover{color:#fff}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-dropdown-trigger{flex-shrink:0}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button{height:24px;box-shadow:none;white-space:nowrap;background-color:#f7f7f7;border:none;border-radius:11px;flex-shrink:0;align-items:center;gap:2px;max-width:160px;padding:0 8px;font-size:12px;display:inline-flex}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button .ant-btn-content{text-overflow:ellipsis;white-space:nowrap;overflow:hidden}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button:hover{background-color:#e6e6e6}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button.selected-from-dropdown{color:#fff;background-color:#2b83ff;font-weight:500}.prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button.selected-from-dropdown:hover{background-color:#2b83ff}.prompt-input-wrapper .mode-radio-group-wrapper .action-icons{z-index:10;pointer-events:none;background:linear-gradient(90deg,#0000 0%,#ffffff80 20%,#fffc 40%,#fffffff2 60%,#fff 70%);flex-shrink:0;justify-content:flex-end;align-items:center;gap:8px;width:80px;padding-left:20px;display:flex;position:absolute;top:50%;right:0;transform:translateY(-50%)}.prompt-input-wrapper .mode-radio-group-wrapper .action-icons>*{pointer-events:auto}.prompt-input-wrapper .main-side-console-input{margin-top:10px;position:relative}.prompt-input-wrapper .main-side-console-input .main-side-console-input-textarea{white-space:pre-wrap;scrollbar-width:thin;background:#fff;border:1px solid #f2f4f7;border-radius:12px;padding:12px 16px;line-height:21px;transition:background-color .2s;overflow-y:auto}@keyframes hue-shift{0%{filter:hue-rotate()}to{filter:hue-rotate(360deg)}}.prompt-input-wrapper .main-side-console-input .main-side-console-input-textarea:focus-within{background:linear-gradient(#fff,#fff) padding-box padding-box,linear-gradient(135deg,#4285f4 0%,#06f 25%,#7b02c5 50%,#ea4335 75%,#ff7043 100%) border-box;border:1px solid #0000}.prompt-input-wrapper .main-side-console-input .main-side-console-input-textarea::-webkit-scrollbar{width:6px}.prompt-input-wrapper .main-side-console-input .main-side-console-input-textarea::-webkit-scrollbar-thumb{background-color:#0003;border-radius:3px}.prompt-input-wrapper .main-side-console-input.loading .main-side-console-input-textarea{background:linear-gradient(#fff,#fff) padding-box padding-box,linear-gradient(135deg,#4285f4 0%,#06f 25%,#7b02c5 50%,#ea4335 75%,#ff7043 100%) border-box;border:1px solid #0000;animation:5s linear infinite hue-shift}.prompt-input-wrapper .main-side-console-input .ant-form-item-control-input-content{z-index:999;border:3px solid #0000;border-radius:14px}.prompt-input-wrapper .main-side-console-input:focus-within .ant-form-item-control-input-content{border-color:#2b83ff29}.prompt-input-wrapper .main-side-console-input.disabled .form-controller-wrapper{background-color:#0000}.prompt-input-wrapper .ant-form-item-with-help+.form-controller-wrapper{bottom:22px}.prompt-input-wrapper .ant-input{padding-bottom:40px}.prompt-input-wrapper .form-controller-wrapper{box-sizing:border-box;background-color:#fff;flex-direction:row;justify-content:flex-end;align-items:flex-end;gap:8px;width:calc(100% - 32px);padding:12px 0;line-height:32px;transition:background-color .2s;display:flex;position:absolute;bottom:1px;left:16px}.prompt-input-wrapper .settings-wrapper{color:#777;flex-flow:wrap;gap:2px;display:flex}.prompt-input-wrapper .settings-wrapper.settings-wrapper-hover{color:#3b3b3b}.prompt-input-wrapper .structured-params-container{background:linear-gradient(#fff,#fff) padding-box padding-box,linear-gradient(135deg,#4285f4 0%,#06f 25%,#7b02c5 50%,#ea4335 75%,#ff7043 100%) border-box;border:1px solid #0000;border-radius:12px;padding:16px 16px 56px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item{flex-direction:column;display:flex}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label{text-align:left;flex-basis:auto;padding-bottom:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label{color:#000000d9;height:auto;font-size:12px;font-weight:500;line-height:1.5}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:after{color:#ff4d4f;font-family:SimSun,sans-serif;font-size:12px;line-height:1;display:inline-block}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:not(:-webkit-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))):after{margin-left:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:not(:-moz-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))):after{margin-left:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:not(:-webkit-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))):after{margin-left:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:not(:-moz-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))):after{margin-left:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:not(:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi))):after{margin-left:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:-webkit-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)):after{margin-right:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:-moz-any(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)):after{margin-right:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-label>label:is(:lang(ae),:lang(ar),:lang(arc),:lang(bcc),:lang(bqi),:lang(ckb),:lang(dv),:lang(fa),:lang(glk),:lang(he),:lang(ku),:lang(mzn),:lang(nqo),:lang(pnb),:lang(ps),:lang(sd),:lang(ug),:lang(ur),:lang(yi)):after{margin-right:4px}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-control{flex:1;margin-top:0}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-row{flex-direction:column}.prompt-input-wrapper .structured-params-container .structured-params .ant-form-item .ant-form-item-control-input{min-height:auto}.prompt-input-wrapper .structured-params-container .structured-params .ant-input,.prompt-input-wrapper .structured-params-container .structured-params .ant-input-number,.prompt-input-wrapper .structured-params-container .structured-params .ant-select{border:1px solid #e1e5e9;border-radius:6px;width:100%}.prompt-input-wrapper .structured-params-container .structured-params .ant-input:hover,.prompt-input-wrapper .structured-params-container .structured-params .ant-input-number:hover,.prompt-input-wrapper .structured-params-container .structured-params .ant-select:hover{border-color:#40a9ff}.prompt-input-wrapper .structured-params-container .structured-params .ant-input:focus,.prompt-input-wrapper .structured-params-container .structured-params .ant-input-number:focus,.prompt-input-wrapper .structured-params-container .structured-params .ant-select:focus,.prompt-input-wrapper .structured-params-container .structured-params .ant-input:focus-within,.prompt-input-wrapper .structured-params-container .structured-params .ant-input-number:focus-within,.prompt-input-wrapper .structured-params-container .structured-params .ant-select:focus-within{border-color:#40a9ff;box-shadow:0 0 0 2px #1890ff33}.prompt-input-wrapper .structured-params-container .structured-params textarea.ant-input{padding-bottom:5px}.prompt-input-wrapper .structured-params-container .structured-params .ant-input-number .ant-input-number-input{box-shadow:none;border:none}.prompt-input-wrapper .structured-params-container .structured-params .ant-input-number:hover .ant-input-number-input{box-shadow:none}.prompt-input-wrapper .structured-params-container .structured-params .ant-select{min-width:120px}.prompt-input-wrapper .structured-params-container .structured-params .ant-select .ant-select-selector{box-shadow:none;border:none}.prompt-input-wrapper .structured-params-container .structured-params .ant-select:hover .ant-select-selector,.prompt-input-wrapper .structured-params-container .structured-params .ant-select.ant-select-focused .ant-select-selector{box-shadow:none}.prompt-input-wrapper .structured-params-container .structured-params .ant-radio-group{width:100%}.prompt-input-wrapper .structured-params-container .structured-params .ant-radio-group .ant-radio-button-wrapper{border:1px solid #e1e5e9;border-radius:6px;height:32px;margin-right:4px;font-size:12px;line-height:30px}.prompt-input-wrapper .structured-params-container .structured-params .ant-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked{color:#fff;background-color:#2b83ff;border-color:#2b83ff}.selector-trigger{cursor:pointer;width:24px;height:24px;transition:all .2s}.selector-trigger .action-icon{color:#000000d9;font-size:14px;transition:all .2s}.selector-trigger .action-icon:hover{color:#2b83ff}.more-apis-dropdown .ant-dropdown-menu{scrollbar-width:thin;max-height:400px;overflow-y:auto}.more-apis-dropdown .ant-dropdown-menu::-webkit-scrollbar{width:6px}.more-apis-dropdown .ant-dropdown-menu::-webkit-scrollbar-track{background:#f1f1f1;border-radius:3px}.more-apis-dropdown .ant-dropdown-menu::-webkit-scrollbar-thumb{background:#c1c1c1;border-radius:3px}.more-apis-dropdown .ant-dropdown-menu::-webkit-scrollbar-thumb:hover{background:#a8a8a8}[data-theme=dark] .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper{color:#f8fafd!important;background-color:#ffffff14!important}[data-theme=dark] .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked{color:#fff!important;background-color:#2b83ff!important;border-color:#2b83ff!important}[data-theme=dark] .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button{color:#f8fafd!important;background-color:#ffffff14!important}[data-theme=dark] .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button:hover{background-color:#ffffff1f!important}[data-theme=dark] .prompt-input-wrapper .mode-radio-group-wrapper .mode-radio-group .more-apis-button.selected-from-dropdown{color:#fff!important;background-color:#2b83ff!important}[data-theme=dark] .prompt-input-wrapper .mode-radio-group-wrapper .action-icons{background:linear-gradient(90deg,#0000 0%,#1f1f1f80 20%,#1f1f1fcc 40%,#1f1f1ff2 60%,#1f1f1f 70%)!important}[data-theme=dark] .prompt-input-wrapper .main-side-console-input .main-side-console-input-textarea{color:#f8fafd!important;background:#ffffff0a!important;border-color:#ffffff1f!important}[data-theme=dark] .prompt-input-wrapper .main-side-console-input .main-side-console-input-textarea:focus-within,[data-theme=dark] .prompt-input-wrapper .main-side-console-input.loading .main-side-console-input-textarea{background:linear-gradient(#1f1f1f,#1f1f1f) padding-box padding-box,linear-gradient(135deg,#4285f4 0%,#06f 25%,#7b02c5 50%,#ea4335 75%,#ff7043 100%) border-box!important;border:1px solid #0000!important}[data-theme=dark] .prompt-input-wrapper .ant-form-item-control-input-content .ant-input,[data-theme=dark] .prompt-input-wrapper .ant-form-item-control-input-content textarea.ant-input{color:#f8fafd!important;background:#ffffff0a!important;border-color:#ffffff1f!important}[data-theme=dark] .prompt-input-wrapper .ant-form-item-control-input-content .ant-btn{color:#f8fafd!important;background-color:#ffffff14!important;border-color:#ffffff1f!important}[data-theme=dark] .prompt-input-wrapper .ant-form-item-control-input-content .ant-btn.ant-btn-primary{color:#fff!important;background-color:#2b83ff!important;border-color:#2b83ff!important}[data-theme=dark] .prompt-input-wrapper .form-controller-wrapper{background-color:#1f1f1f!important}[data-theme=dark] .prompt-input-wrapper .structured-params-container{background:linear-gradient(#1f1f1f,#1f1f1f) padding-box padding-box,linear-gradient(135deg,#4285f4 0%,#06f 25%,#7b02c5 50%,#ea4335 75%,#ff7043 100%) border-box!important}[data-theme=dark] .prompt-input-wrapper .structured-params-container .structured-params .ant-form-item-label>label{color:#f8fafd!important}[data-theme=dark] .prompt-input-wrapper .structured-params-container .structured-params .ant-input,[data-theme=dark] .prompt-input-wrapper .structured-params-container .structured-params .ant-input-number,[data-theme=dark] .prompt-input-wrapper .structured-params-container .structured-params .ant-select,[data-theme=dark] .prompt-input-wrapper .structured-params-container .structured-params .ant-radio-group .ant-radio-button-wrapper{color:#f8fafd!important;background-color:#ffffff0a!important;border-color:#ffffff1f!important}[data-theme=dark] .prompt-input-wrapper .structured-params-container .structured-params .ant-radio-group .ant-radio-button-wrapper.ant-radio-button-wrapper-checked{color:#fff!important;background-color:#2b83ff!important;border-color:#2b83ff!important}[data-theme=dark] .prompt-input .tip-button{background-color:#ffffff14}[data-theme=dark] .prompt-input .tip-button.active{color:#fff;background-color:#2b83ff}[data-theme=dark] .prompt-input .prompt-textarea-wrapper{background-color:#ffffff0a}[data-theme=dark] .prompt-input .prompt-textarea-wrapper:hover,[data-theme=dark] .prompt-input .prompt-textarea-wrapper.focused{background-color:#ffffff14}[data-theme=dark] .prompt-input .btn-wrapper .btn-item{color:#fff;background-color:#2b83ff}[data-theme=dark] .prompt-input .btn-wrapper .btn-item:hover{background-color:#2b83ff}[data-theme=dark] .prompt-input .dropdown-content{background-color:#1f1f1f;border-color:#ffffff1f}[data-theme=dark] .prompt-input .param-label{color:#f8fafd}[data-theme=dark] .prompt-input .error-message{color:#ff4d4f}[data-theme=dark] .prompt-input .send-button-text{color:#2b83ff}[data-theme=dark] .more-apis-dropdown .ant-dropdown-menu::-webkit-scrollbar-track{background:#ffffff14}[data-theme=dark] .more-apis-dropdown .ant-dropdown-menu::-webkit-scrollbar-thumb{background:#fff3}[data-theme=dark] .more-apis-dropdown .ant-dropdown-menu::-webkit-scrollbar-thumb:hover{background:#ffffff4d}.history-selector-wrapper{position:relative}.history-modal-overlay{z-index:9999;background:#fff;border:1px solid #00000014;border-radius:12px;width:320px;height:400px;position:fixed;top:auto;bottom:20px;right:20px;box-shadow:0 8px 24px #0000001f}.history-modal-container{border-radius:12px;flex-direction:column;width:100%;height:100%;display:flex;overflow:hidden}.history-modal-container .history-modal-header{justify-content:space-between;align-items:center;height:48px;padding:0 25px;line-height:48px;display:flex}.history-modal-container .history-modal-header .close-button{justify-content:center;align-items:center;margin-right:-4px;padding:4px;display:flex}.history-modal-container .history-modal-header .close-button .anticon{color:#999;font-size:18px}.history-modal-container .history-modal-header .close-button:hover .anticon{color:#666}.history-modal-container .history-search-section{background:#fff;padding:16px 20px}.history-modal-container .history-search-section .search-input-wrapper{color:#00000040;align-items:center;gap:12px;display:flex}.history-modal-container .history-search-section .search-input-wrapper .search-input{background:#f1f2f3;border:none;border-radius:16px;flex:1;height:36px}.history-modal-container .history-search-section .search-input-wrapper .search-input .ant-input{box-shadow:none;background:0 0;border:none}.history-modal-container .history-search-section .search-input-wrapper .search-input:hover,.history-modal-container .history-search-section .search-input-wrapper .search-input:focus-within{background:#fff;border-color:#d9d9d9}.history-modal-container .history-search-section .search-input-wrapper .clear-button{color:#1890ff;height:auto;padding:0}.history-modal-container .history-search-section .search-input-wrapper .clear-button:hover{color:#40a9ff}.history-modal-container .history-content{flex:1;padding:0 25px 25px;overflow-y:auto}.history-modal-container .history-content .history-group{margin-bottom:10px}.history-modal-container .history-content .history-group .history-group-title{color:#00000073;height:40px;font-size:12px;font-weight:400;line-height:40px}.history-modal-container .history-content .history-group .history-item{cursor:pointer;color:#000000d9;white-space:nowrap;text-overflow:ellipsis;height:40px;font-size:14px;line-height:40px;overflow:hidden}.history-modal-container .history-content .history-group .history-item:hover{background:#f2f4f7;margin:0 -8px;padding:0 8px}.history-modal-container .history-content .no-results{text-align:center;color:#999;padding:40px 20px}[data-theme=dark] .history-selector .history-timestamp,[data-theme=dark] .history-selector .history-path{color:#ffffff73}[data-theme=dark] .history-selector .history-description{color:#f8fafd}[data-theme=dark] .history-selector .history-no-items{color:#ffffff73}[data-theme=dark] .history-selector .history-item:hover{background:#ffffff14}[data-theme=dark] .history-selector .history-item .history-clear-icon{border-color:#ffffff1f}[data-theme=dark] .history-selector .history-item .history-clear-icon:hover{border-color:#40a9ff}[data-theme=dark] .history-selector .history-load-more{color:#1890ff}[data-theme=dark] .history-selector .history-load-more:hover{color:#40a9ff}.screenshot-viewer{flex-direction:column;height:100%;display:flex}.screenshot-viewer.offline,.screenshot-viewer.loading,.screenshot-viewer.error{text-align:center;color:#666;justify-content:center;align-items:center}.screenshot-viewer.offline .screenshot-placeholder h3,.screenshot-viewer.loading .screenshot-placeholder h3,.screenshot-viewer.error .screenshot-placeholder h3{color:#1890ff;text-transform:capitalize;margin-bottom:12px;font-size:18px}.screenshot-viewer.offline .screenshot-placeholder p,.screenshot-viewer.loading .screenshot-placeholder p,.screenshot-viewer.error .screenshot-placeholder p{color:#666;margin:0}.screenshot-viewer.offline .screenshot-placeholder p.error-message,.screenshot-viewer.loading .screenshot-placeholder p.error-message,.screenshot-viewer.error .screenshot-placeholder p.error-message{color:#ff4d4f}.screenshot-viewer .screenshot-header{justify-content:space-between;align-items:center;height:56px;display:flex}.screenshot-viewer .screenshot-header .screenshot-title{flex-direction:column;gap:4px;display:flex}.screenshot-viewer .screenshot-header .screenshot-title h3{color:#000;text-transform:capitalize;align-items:center;gap:8px;margin:0;font-size:14px;font-weight:600;display:flex}.screenshot-viewer .screenshot-header .screenshot-title .screenshot-subtitle{color:#999;margin:0;font-size:12px}.screenshot-viewer .screenshot-container{background:#f2f4f7;border-radius:16px;flex-direction:column;flex:1;padding:0 15px;display:flex;overflow:hidden}.screenshot-viewer .screenshot-container .screenshot-overlay{z-index:10;justify-content:space-between;align-items:flex-start;padding:12px 5px 8px;display:flex}.screenshot-viewer .screenshot-container .screenshot-overlay .device-name-overlay{color:#000000d9;text-transform:capitalize;align-items:center;gap:8px;font-size:12px;font-weight:500;display:flex}.screenshot-viewer .screenshot-container .screenshot-overlay .device-name-overlay .info-icon{opacity:.8;cursor:pointer;font-size:12px}.screenshot-viewer .screenshot-container .screenshot-overlay .device-name-overlay .info-icon:hover{opacity:1}.screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls{opacity:1;box-sizing:border-box;border-radius:4px;align-items:center;gap:10px;height:18px;padding:4px 8px;display:flex}.screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .last-update-time{color:#666;white-space:nowrap;text-overflow:ellipsis;font-size:12px;overflow:hidden}.screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .operation-indicator{align-items:center;gap:4px;font-size:12px;display:flex}.screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .ant-btn{box-shadow:none;background:0 0;border:none;justify-content:center;align-items:center;width:16px;min-width:16px;height:16px;padding:0;display:flex}.screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .ant-btn:hover{background-color:#0000000f;border-radius:2px;transition:all .2s;transform:scale(1.1)}.screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .ant-btn .anticon{color:#666;font-size:12px;transition:color .2s}.screenshot-viewer .screenshot-container .screenshot-content{flex:1;justify-content:center;align-items:center;min-height:0;display:flex}.screenshot-viewer .screenshot-container .screenshot-content .screenshot-image{object-fit:contain;border-radius:12px;max-width:100%;height:auto;max-height:100%}.screenshot-viewer .screenshot-container .screenshot-content .screenshot-placeholder{text-align:center;color:#999}[data-theme=dark] .screenshot-viewer.offline,[data-theme=dark] .screenshot-viewer.loading,[data-theme=dark] .screenshot-viewer.error{color:#f8fafd}[data-theme=dark] .screenshot-viewer.offline .screenshot-placeholder h3,[data-theme=dark] .screenshot-viewer.loading .screenshot-placeholder h3,[data-theme=dark] .screenshot-viewer.error .screenshot-placeholder h3{color:#1890ff}[data-theme=dark] .screenshot-viewer.offline .screenshot-placeholder p,[data-theme=dark] .screenshot-viewer.loading .screenshot-placeholder p,[data-theme=dark] .screenshot-viewer.error .screenshot-placeholder p{color:#f8fafd}[data-theme=dark] .screenshot-viewer.offline .screenshot-placeholder p.error-message,[data-theme=dark] .screenshot-viewer.loading .screenshot-placeholder p.error-message,[data-theme=dark] .screenshot-viewer.error .screenshot-placeholder p.error-message{color:#ff4d4f}[data-theme=dark] .screenshot-viewer .screenshot-header .screenshot-title h3{color:#f8fafd}[data-theme=dark] .screenshot-viewer .screenshot-header .screenshot-title .screenshot-subtitle{color:#ffffff73}[data-theme=dark] .screenshot-viewer .screenshot-container{background:#141414}[data-theme=dark] .screenshot-viewer .screenshot-container .screenshot-overlay .device-name-overlay,[data-theme=dark] .screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .last-update-time{color:#f8fafd}[data-theme=dark] .screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .ant-btn:hover{background-color:#ffffff14}[data-theme=dark] .screenshot-viewer .screenshot-container .screenshot-overlay .screenshot-controls .ant-btn .anticon{color:#f8fafd}[data-theme=dark] .screenshot-viewer .screenshot-container .screenshot-content .screenshot-placeholder{color:#ffffff73}
2
+ /*# sourceMappingURL=index.7fc783ce.css.map*/