@aiscene/android 1.8.0 → 1.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/es/cli.mjs +17 -17
- package/dist/es/index.mjs +15 -15
- package/dist/es/mcp-server.mjs +17 -17
- package/dist/lib/cli.js +16 -16
- package/dist/lib/index.js +14 -14
- package/dist/lib/mcp-server.js +16 -16
- package/dist/types/index.d.ts +1448 -16
- package/dist/types/mcp-server.d.ts +1520 -18
- package/package.json +3 -3
package/dist/types/index.d.ts
CHANGED
|
@@ -1,26 +1,407 @@
|
|
|
1
|
-
import { AbstractInterface } from '@midscene/core/device';
|
|
2
|
-
import type { ActionParam } from '@midscene/core';
|
|
3
|
-
import type { ActionReturn } from '@midscene/core';
|
|
4
1
|
import { ADB } from 'appium-adb';
|
|
5
2
|
import type { Adb } from '@yume-chan/adb';
|
|
6
|
-
import {
|
|
7
|
-
import { AgentOpt } from '@midscene/core/agent';
|
|
8
|
-
import { AndroidDeviceInputOpt } from '@midscene/core/device';
|
|
9
|
-
import { AndroidDeviceOpt } from '@midscene/core/device';
|
|
10
|
-
import { BaseMidsceneTools } from '@midscene/shared/mcp';
|
|
3
|
+
import type { CreateOpenAIClientFn } from '@midscene/shared/env';
|
|
11
4
|
import { Device } from 'appium-adb';
|
|
12
|
-
import {
|
|
13
|
-
import
|
|
14
|
-
import {
|
|
15
|
-
import {
|
|
16
|
-
import {
|
|
17
|
-
import {
|
|
18
|
-
import {
|
|
5
|
+
import type { ElementNode } from '@midscene/shared/extractor';
|
|
6
|
+
import { IModelConfig } from '@midscene/shared/env';
|
|
7
|
+
import type { LocateResultElement } from '@midscene/shared/types';
|
|
8
|
+
import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
|
|
9
|
+
import { ModelConfigManager } from '@midscene/shared/env';
|
|
10
|
+
import { Point } from '@midscene/shared/types';
|
|
11
|
+
import { Rect } from '@midscene/shared/types';
|
|
12
|
+
import { Size } from '@midscene/shared/types';
|
|
13
|
+
import type { TModelConfig } from '@midscene/shared/env';
|
|
14
|
+
import { z } from './lib';
|
|
15
|
+
|
|
16
|
+
declare abstract class AbstractInterface {
|
|
17
|
+
abstract interfaceType: string;
|
|
18
|
+
abstract screenshotBase64(): Promise<string>;
|
|
19
|
+
abstract size(): Promise<Size>;
|
|
20
|
+
abstract actionSpace(): DeviceAction[];
|
|
21
|
+
abstract cacheFeatureForPoint?(center: [number, number], options?: {
|
|
22
|
+
targetDescription?: string;
|
|
23
|
+
modelConfig?: IModelConfig;
|
|
24
|
+
}): Promise<ElementCacheFeature>;
|
|
25
|
+
abstract rectMatchesCacheFeature?(feature: ElementCacheFeature): Promise<Rect>;
|
|
26
|
+
abstract destroy?(): Promise<void>;
|
|
27
|
+
abstract describe?(): string;
|
|
28
|
+
abstract beforeInvokeAction?(actionName: string, param: any): Promise<void>;
|
|
29
|
+
abstract afterInvokeAction?(actionName: string, param: any): Promise<void>;
|
|
30
|
+
registerFileChooserListener?(handler: (chooser: FileChooserHandler) => Promise<void>): Promise<{
|
|
31
|
+
dispose: () => void;
|
|
32
|
+
getError: () => Error | undefined;
|
|
33
|
+
}>;
|
|
34
|
+
abstract getElementsNodeTree?: () => Promise<ElementNode>;
|
|
35
|
+
abstract url?: () => string | Promise<string>;
|
|
36
|
+
abstract evaluateJavaScript?<T = any>(script: string): Promise<T>;
|
|
37
|
+
/**
|
|
38
|
+
* Get the current time from the device.
|
|
39
|
+
* Returns the device's current timestamp in milliseconds.
|
|
40
|
+
* This is useful when the system time and device time are not synchronized.
|
|
41
|
+
*/
|
|
42
|
+
getTimestamp?(): Promise<number>;
|
|
43
|
+
/** URL of native MJPEG stream for real-time screen preview (e.g. WDA MJPEG server) */
|
|
44
|
+
mjpegStreamUrl?: string;
|
|
45
|
+
}
|
|
19
46
|
|
|
20
47
|
declare type ActionArgs<T extends DeviceAction> = [ActionParam<T>] extends [undefined] ? [] : [ActionParam<T>];
|
|
21
48
|
|
|
49
|
+
/**
|
|
50
|
+
* Type utilities for extracting types from DeviceAction definitions
|
|
51
|
+
*/
|
|
52
|
+
/**
|
|
53
|
+
* Extract parameter type from a DeviceAction
|
|
54
|
+
*/
|
|
55
|
+
declare type ActionParam<Action extends DeviceAction<any, any>> = Action extends DeviceAction<infer P, any> ? P : never;
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* Extract return type from a DeviceAction
|
|
59
|
+
*/
|
|
60
|
+
declare type ActionReturn<Action extends DeviceAction<any, any>> = Action extends DeviceAction<any, infer R> ? R : never;
|
|
61
|
+
|
|
62
|
+
declare type ActionScrollParam = {
|
|
63
|
+
direction?: 'down' | 'up' | 'right' | 'left';
|
|
64
|
+
scrollType?: ScrollType;
|
|
65
|
+
distance?: number | null;
|
|
66
|
+
locate?: LocateResultElement;
|
|
67
|
+
};
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Action space item definition
|
|
71
|
+
* Note: Intentionally no index signature to maintain compatibility with DeviceAction
|
|
72
|
+
*/
|
|
73
|
+
declare interface ActionSpaceItem {
|
|
74
|
+
name: string;
|
|
75
|
+
description?: string;
|
|
76
|
+
args?: Record<string, unknown>;
|
|
77
|
+
paramSchema?: z.ZodTypeAny;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
declare class Agent<InterfaceType extends AbstractInterface = AbstractInterface> {
|
|
81
|
+
interface: InterfaceType;
|
|
82
|
+
service: Service;
|
|
83
|
+
dump: GroupedActionDump;
|
|
84
|
+
reportFile?: string | null;
|
|
85
|
+
reportFileName?: string;
|
|
86
|
+
taskExecutor: TaskExecutor;
|
|
87
|
+
opts: AgentOpt;
|
|
88
|
+
/**
|
|
89
|
+
* If true, the agent will not perform any actions
|
|
90
|
+
*/
|
|
91
|
+
dryMode: boolean;
|
|
92
|
+
onTaskStartTip?: OnTaskStartTip;
|
|
93
|
+
taskCache?: TaskCache;
|
|
94
|
+
private dumpUpdateListeners;
|
|
95
|
+
get onDumpUpdate(): ((dump: string, executionDump?: ExecutionDump) => void) | undefined;
|
|
96
|
+
set onDumpUpdate(callback: ((dump: string, executionDump?: ExecutionDump) => void) | undefined);
|
|
97
|
+
destroyed: boolean;
|
|
98
|
+
modelConfigManager: ModelConfigManager;
|
|
99
|
+
/**
|
|
100
|
+
* Frozen page context for consistent AI operations
|
|
101
|
+
*/
|
|
102
|
+
private frozenUIContext?;
|
|
103
|
+
private get aiActContext();
|
|
104
|
+
/**
|
|
105
|
+
* Flag to track if VL model warning has been shown
|
|
106
|
+
*/
|
|
107
|
+
private hasWarnedNonVLModel;
|
|
108
|
+
private executionDumpIndexByRunner;
|
|
109
|
+
private fullActionSpace;
|
|
110
|
+
private reportGenerator;
|
|
111
|
+
get page(): InterfaceType;
|
|
112
|
+
/**
|
|
113
|
+
* Ensures VL model warning is shown once when needed
|
|
114
|
+
*/
|
|
115
|
+
private ensureVLModelWarning;
|
|
116
|
+
private resolveReplanningCycleLimit;
|
|
117
|
+
constructor(interfaceInstance: InterfaceType, opts?: AgentOpt);
|
|
118
|
+
getActionSpace(): Promise<DeviceAction[]>;
|
|
119
|
+
private static readonly CONTEXT_RETRY_MAX;
|
|
120
|
+
private static readonly CONTEXT_RETRY_DELAY_MS;
|
|
121
|
+
/**
|
|
122
|
+
* Override in subclasses to indicate which errors are transient and should
|
|
123
|
+
* trigger an automatic retry when building the UI context.
|
|
124
|
+
* Returns `false` by default (no retry).
|
|
125
|
+
*/
|
|
126
|
+
protected isRetryableContextError(_error: unknown): boolean;
|
|
127
|
+
getUIContext(action?: ServiceAction): Promise<UIContext>;
|
|
128
|
+
_snapshotContext(): Promise<UIContext>;
|
|
129
|
+
/**
|
|
130
|
+
* @deprecated Use {@link setAIActContext} instead.
|
|
131
|
+
*/
|
|
132
|
+
setAIActionContext(prompt: string): Promise<void>;
|
|
133
|
+
setAIActContext(prompt: string): Promise<void>;
|
|
134
|
+
resetDump(): GroupedActionDump;
|
|
135
|
+
appendExecutionDump(execution: ExecutionDump, runner?: TaskRunner): void;
|
|
136
|
+
dumpDataString(opt?: {
|
|
137
|
+
inlineScreenshots?: boolean;
|
|
138
|
+
}): string;
|
|
139
|
+
reportHTMLString(opt?: {
|
|
140
|
+
inlineScreenshots?: boolean;
|
|
141
|
+
}): string;
|
|
142
|
+
private lastExecutionDump?;
|
|
143
|
+
writeOutActionDumps(executionDump?: ExecutionDump): void;
|
|
144
|
+
private getGroupMeta;
|
|
145
|
+
private callbackOnTaskStartTip;
|
|
146
|
+
wrapActionInActionSpace<T extends DeviceAction>(name: string): (param: ActionParam<T>) => Promise<ActionReturn<T>>;
|
|
147
|
+
callActionInActionSpace<T = any>(type: string, opt?: T): Promise<any>;
|
|
148
|
+
aiTap(locatePrompt: TUserPrompt, opt?: LocateOption & {
|
|
149
|
+
fileChooserAccept?: string | string[];
|
|
150
|
+
}): Promise<any>;
|
|
151
|
+
aiRightClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
152
|
+
aiDoubleClick(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
153
|
+
aiHover(locatePrompt: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
154
|
+
aiInput(locatePrompt: TUserPrompt, opt: LocateOption & {
|
|
155
|
+
value: string | number;
|
|
156
|
+
} & {
|
|
157
|
+
autoDismissKeyboard?: boolean;
|
|
158
|
+
} & {
|
|
159
|
+
mode?: 'replace' | 'clear' | 'typeOnly' | 'append';
|
|
160
|
+
}): Promise<any>;
|
|
161
|
+
/**
|
|
162
|
+
* @deprecated Use aiInput(locatePrompt, opt) instead where opt contains the value
|
|
163
|
+
*/
|
|
164
|
+
aiInput(value: string | number, locatePrompt: TUserPrompt, opt?: LocateOption & {
|
|
165
|
+
autoDismissKeyboard?: boolean;
|
|
166
|
+
} & {
|
|
167
|
+
mode?: 'replace' | 'clear' | 'typeOnly' | 'append';
|
|
168
|
+
}): Promise<any>;
|
|
169
|
+
aiKeyboardPress(locatePrompt: TUserPrompt, opt: LocateOption & {
|
|
170
|
+
keyName: string;
|
|
171
|
+
}): Promise<any>;
|
|
172
|
+
/**
|
|
173
|
+
* @deprecated Use aiKeyboardPress(locatePrompt, opt) instead where opt contains the keyName
|
|
174
|
+
*/
|
|
175
|
+
aiKeyboardPress(keyName: string, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
176
|
+
aiScroll(locatePrompt: TUserPrompt | undefined, opt: LocateOption & ScrollParam): Promise<any>;
|
|
177
|
+
/**
|
|
178
|
+
* @deprecated Use aiScroll(locatePrompt, opt) instead where opt contains the scroll parameters
|
|
179
|
+
*/
|
|
180
|
+
aiScroll(scrollParam: ScrollParam, locatePrompt?: TUserPrompt, opt?: LocateOption): Promise<any>;
|
|
181
|
+
aiPinch(locatePrompt: TUserPrompt | undefined, opt: LocateOption & {
|
|
182
|
+
direction: 'in' | 'out';
|
|
183
|
+
distance?: number;
|
|
184
|
+
duration?: number;
|
|
185
|
+
}): Promise<any>;
|
|
186
|
+
aiAct(taskPrompt: string, opt?: AiActOptions): Promise<string | undefined>;
|
|
187
|
+
/**
|
|
188
|
+
* @deprecated Use {@link Agent.aiAct} instead.
|
|
189
|
+
*/
|
|
190
|
+
aiAction(taskPrompt: string, opt?: AiActOptions): Promise<string | undefined>;
|
|
191
|
+
aiQuery<ReturnType = any>(demand: ServiceExtractParam, opt?: ServiceExtractOption): Promise<ReturnType>;
|
|
192
|
+
aiBoolean(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<boolean>;
|
|
193
|
+
aiNumber(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<number>;
|
|
194
|
+
aiString(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<string>;
|
|
195
|
+
aiAsk(prompt: TUserPrompt, opt?: ServiceExtractOption): Promise<string>;
|
|
196
|
+
describeElementAtPoint(center: [number, number], opt?: {
|
|
197
|
+
verifyPrompt?: boolean;
|
|
198
|
+
retryLimit?: number;
|
|
199
|
+
deepLocate?: boolean;
|
|
200
|
+
} & LocatorValidatorOption): Promise<AgentDescribeElementAtPointResult>;
|
|
201
|
+
verifyLocator(prompt: string, locateOpt: LocateOption | undefined, expectCenter: [number, number], verifyLocateOption?: LocatorValidatorOption): Promise<LocateValidatorResult>;
|
|
202
|
+
aiLocate(prompt: TUserPrompt, opt?: LocateOption): Promise<Pick<LocateResultElement, "rect" | "center">>;
|
|
203
|
+
aiAssert(assertion: TUserPrompt, msg?: string, opt?: AgentAssertOpt & ServiceExtractOption): Promise<{
|
|
204
|
+
pass: boolean;
|
|
205
|
+
thought: string | undefined;
|
|
206
|
+
message: string | undefined;
|
|
207
|
+
} | undefined>;
|
|
208
|
+
aiWaitFor(assertion: TUserPrompt, opt?: AgentWaitForOpt): Promise<void>;
|
|
209
|
+
ai(...args: Parameters<typeof Agent.aiAct>): Promise<string | undefined>;
|
|
210
|
+
runYaml(yamlScriptContent: string): Promise<{
|
|
211
|
+
result: Record<string, any>;
|
|
212
|
+
}>;
|
|
213
|
+
evaluateJavaScript(script: string): Promise<any>;
|
|
214
|
+
/**
|
|
215
|
+
* Add a dump update listener
|
|
216
|
+
* @param listener Listener function
|
|
217
|
+
* @returns A remove function that can be called to remove this listener
|
|
218
|
+
*/
|
|
219
|
+
addDumpUpdateListener(listener: (dump: string, executionDump?: ExecutionDump) => void): () => void;
|
|
220
|
+
/**
|
|
221
|
+
* Remove a dump update listener
|
|
222
|
+
* @param listener The listener function to remove
|
|
223
|
+
*/
|
|
224
|
+
removeDumpUpdateListener(listener: (dump: string, executionDump?: ExecutionDump) => void): void;
|
|
225
|
+
/**
|
|
226
|
+
* Clear all dump update listeners
|
|
227
|
+
*/
|
|
228
|
+
clearDumpUpdateListeners(): void;
|
|
229
|
+
destroy(): Promise<void>;
|
|
230
|
+
recordToReport(title?: string, opt?: {
|
|
231
|
+
content: string;
|
|
232
|
+
}): Promise<void>;
|
|
233
|
+
/**
|
|
234
|
+
* @deprecated Use {@link Agent.recordToReport} instead.
|
|
235
|
+
*/
|
|
236
|
+
logScreenshot(title?: string, opt?: {
|
|
237
|
+
content: string;
|
|
238
|
+
}): Promise<void>;
|
|
239
|
+
_unstableLogContent(): {
|
|
240
|
+
groupName: string;
|
|
241
|
+
groupDescription: string | undefined;
|
|
242
|
+
executions: ExecutionDump[];
|
|
243
|
+
};
|
|
244
|
+
/**
|
|
245
|
+
* Freezes the current page context to be reused in subsequent AI operations
|
|
246
|
+
* This avoids recalculating page context for each operation
|
|
247
|
+
*/
|
|
248
|
+
freezePageContext(): Promise<void>;
|
|
249
|
+
/**
|
|
250
|
+
* Unfreezes the page context, allowing AI operations to calculate context dynamically
|
|
251
|
+
*/
|
|
252
|
+
unfreezePageContext(): Promise<void>;
|
|
253
|
+
/**
|
|
254
|
+
* Process cache configuration and return normalized cache settings
|
|
255
|
+
*/
|
|
256
|
+
private processCacheConfig;
|
|
257
|
+
private normalizeFilePaths;
|
|
258
|
+
private normalizeFileInput;
|
|
259
|
+
/**
|
|
260
|
+
* Manually flush cache to file
|
|
261
|
+
* @param options - Optional configuration
|
|
262
|
+
* @param options.cleanUnused - If true, removes unused cache records before flushing
|
|
263
|
+
*/
|
|
264
|
+
flushCache(options?: {
|
|
265
|
+
cleanUnused?: boolean;
|
|
266
|
+
}): Promise<void>;
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
declare interface AgentAssertOpt {
|
|
270
|
+
keepRawResponse?: boolean;
|
|
271
|
+
}
|
|
272
|
+
|
|
273
|
+
declare interface AgentDescribeElementAtPointResult {
|
|
274
|
+
prompt: string;
|
|
275
|
+
deepLocate: boolean;
|
|
276
|
+
verifyResult?: LocateValidatorResult;
|
|
277
|
+
}
|
|
278
|
+
|
|
22
279
|
export declare function agentFromAdbDevice(deviceId?: string, opts?: AndroidAgentOpt & AndroidDeviceOpt): Promise<AndroidAgent>;
|
|
23
280
|
|
|
281
|
+
declare interface AgentOpt {
|
|
282
|
+
testId?: string;
|
|
283
|
+
cacheId?: string;
|
|
284
|
+
groupName?: string;
|
|
285
|
+
groupDescription?: string;
|
|
286
|
+
generateReport?: boolean;
|
|
287
|
+
autoPrintReportMsg?: boolean;
|
|
288
|
+
/**
|
|
289
|
+
* Use directory-based report format with separate image files.
|
|
290
|
+
*
|
|
291
|
+
* When enabled:
|
|
292
|
+
* - Screenshots are saved as PNG files in a `screenshots/` subdirectory
|
|
293
|
+
* - Report is generated as `index.html` with relative image paths
|
|
294
|
+
* - Reduces memory usage and report file size
|
|
295
|
+
*
|
|
296
|
+
* IMPORTANT: 'html-and-external-assets' reports must be served via HTTP server
|
|
297
|
+
* (e.g., `npx serve ./report-dir`). The file:// protocol will not
|
|
298
|
+
* work due to browser CORS restrictions.
|
|
299
|
+
*
|
|
300
|
+
* @default 'single-html'
|
|
301
|
+
*/
|
|
302
|
+
outputFormat?: 'single-html' | 'html-and-external-assets';
|
|
303
|
+
onTaskStartTip?: OnTaskStartTip;
|
|
304
|
+
aiActContext?: string;
|
|
305
|
+
aiActionContext?: string;
|
|
306
|
+
reportFileName?: string;
|
|
307
|
+
modelConfig?: TModelConfig;
|
|
308
|
+
cache?: Cache_2;
|
|
309
|
+
/**
|
|
310
|
+
* Maximum number of replanning cycles for aiAct.
|
|
311
|
+
* Defaults to 20 (40 for `vlm-ui-tars`) when not provided.
|
|
312
|
+
* If omitted, the agent will also read `MIDSCENE_REPLANNING_CYCLE_LIMIT` for backward compatibility.
|
|
313
|
+
*/
|
|
314
|
+
replanningCycleLimit?: number;
|
|
315
|
+
/**
|
|
316
|
+
* Wait time in milliseconds after each action execution.
|
|
317
|
+
* This allows the UI to settle and stabilize before the next action.
|
|
318
|
+
* Defaults to 300ms when not provided.
|
|
319
|
+
*/
|
|
320
|
+
waitAfterAction?: number;
|
|
321
|
+
/**
|
|
322
|
+
* When set to true, Midscene will use the target device's time (Android/iOS)
|
|
323
|
+
* instead of the system time. Useful when the device time differs from the
|
|
324
|
+
* host machine. Default: false
|
|
325
|
+
*/
|
|
326
|
+
useDeviceTimestamp?: boolean;
|
|
327
|
+
/**
|
|
328
|
+
* Custom screenshot shrink factor to reduce AI token usage.
|
|
329
|
+
* When set, the screenshot will be scaled down by this factor from the physical resolution.
|
|
330
|
+
*
|
|
331
|
+
* Example:
|
|
332
|
+
* - Physical screen width: 3000px, dpr=6
|
|
333
|
+
* - Logical width: 500px
|
|
334
|
+
* - screenshotShrinkFactor: 2
|
|
335
|
+
* - Actual shrunk screenshot width: 3000 / 2 = 1500px
|
|
336
|
+
* - AI analyzes the 1500px screenshot
|
|
337
|
+
* - Coordinates are transformed back to logical (500px) before actions execute
|
|
338
|
+
*
|
|
339
|
+
* Benefits:
|
|
340
|
+
* - Reduces token usage for high-resolution screenshots
|
|
341
|
+
* - Maintains accuracy by scaling coordinates appropriately
|
|
342
|
+
*
|
|
343
|
+
* Must be >= 1 (shrinking only, enlarging is not supported).
|
|
344
|
+
*
|
|
345
|
+
* @default 1 (no shrinking, uses original physical screenshot)
|
|
346
|
+
*/
|
|
347
|
+
screenshotShrinkFactor?: number;
|
|
348
|
+
/**
|
|
349
|
+
* Custom OpenAI client factory function
|
|
350
|
+
*
|
|
351
|
+
* If provided, this function will be called to create OpenAI client instances
|
|
352
|
+
* for each AI call, allowing you to:
|
|
353
|
+
* - Wrap clients with observability tools (langsmith, langfuse)
|
|
354
|
+
* - Use custom OpenAI-compatible clients
|
|
355
|
+
* - Apply different configurations based on intent
|
|
356
|
+
*
|
|
357
|
+
* @param config - Resolved model configuration
|
|
358
|
+
* @returns OpenAI client instance (original or wrapped)
|
|
359
|
+
*
|
|
360
|
+
* @example
|
|
361
|
+
* ```typescript
|
|
362
|
+
* createOpenAIClient: async (openai, opts) => {
|
|
363
|
+
* // Wrap with langsmith for planning tasks
|
|
364
|
+
* if (opts.baseURL?.includes('planning')) {
|
|
365
|
+
* return wrapOpenAI(openai, { metadata: { task: 'planning' } });
|
|
366
|
+
* }
|
|
367
|
+
*
|
|
368
|
+
* return openai;
|
|
369
|
+
* }
|
|
370
|
+
* ```
|
|
371
|
+
*/
|
|
372
|
+
createOpenAIClient?: CreateOpenAIClientFn;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
declare interface AgentWaitForOpt extends ServiceExtractOption {
|
|
376
|
+
checkIntervalMs?: number;
|
|
377
|
+
timeoutMs?: number;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
declare type AiActOptions = {
|
|
381
|
+
cacheable?: boolean;
|
|
382
|
+
fileChooserAccept?: string | string[];
|
|
383
|
+
deepThink?: DeepThinkOption;
|
|
384
|
+
deepLocate?: boolean;
|
|
385
|
+
abortSignal?: AbortSignal;
|
|
386
|
+
};
|
|
387
|
+
|
|
388
|
+
declare interface AIDescribeElementResponse {
|
|
389
|
+
description: string;
|
|
390
|
+
error?: string;
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
declare type AIUsageInfo = Record<string, any> & {
|
|
394
|
+
prompt_tokens: number | undefined;
|
|
395
|
+
completion_tokens: number | undefined;
|
|
396
|
+
total_tokens: number | undefined;
|
|
397
|
+
cached_input: number | undefined;
|
|
398
|
+
time_cost: number | undefined;
|
|
399
|
+
model_name: string | undefined;
|
|
400
|
+
model_description: string | undefined;
|
|
401
|
+
intent: string | undefined;
|
|
402
|
+
request_id: string | undefined;
|
|
403
|
+
};
|
|
404
|
+
|
|
24
405
|
export declare class AndroidAgent extends Agent<AndroidDevice> {
|
|
25
406
|
/**
|
|
26
407
|
* Trigger the system back operation on Android devices
|
|
@@ -229,6 +610,107 @@ export declare class AndroidDevice implements AbstractInterface {
|
|
|
229
610
|
hideKeyboard(options?: AndroidDeviceInputOpt, timeoutMs?: number): Promise<boolean>;
|
|
230
611
|
}
|
|
231
612
|
|
|
613
|
+
/**
|
|
614
|
+
* Android device input options
|
|
615
|
+
*/
|
|
616
|
+
declare type AndroidDeviceInputOpt = {
|
|
617
|
+
/** Automatically dismiss the keyboard after input is completed */
|
|
618
|
+
autoDismissKeyboard?: boolean;
|
|
619
|
+
/** Strategy for dismissing the keyboard: 'esc-first' tries ESC before BACK, 'back-first' tries BACK before ESC */
|
|
620
|
+
keyboardDismissStrategy?: 'esc-first' | 'back-first';
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
/**
|
|
624
|
+
* Android device options
|
|
625
|
+
*/
|
|
626
|
+
declare type AndroidDeviceOpt = {
|
|
627
|
+
/** Path to the ADB executable */
|
|
628
|
+
androidAdbPath?: string;
|
|
629
|
+
/** Remote ADB host address */
|
|
630
|
+
remoteAdbHost?: string;
|
|
631
|
+
/** Remote ADB port */
|
|
632
|
+
remoteAdbPort?: number;
|
|
633
|
+
/** Input method editor strategy: 'always-yadb' always uses yadb, 'yadb-for-non-ascii' uses yadb only for non-ASCII characters */
|
|
634
|
+
imeStrategy?: 'always-yadb' | 'yadb-for-non-ascii';
|
|
635
|
+
/** Display ID to use for this device */
|
|
636
|
+
displayId?: number;
|
|
637
|
+
/** Use physical display ID for screenshot operations */
|
|
638
|
+
usePhysicalDisplayIdForScreenshot?: boolean;
|
|
639
|
+
/** Use physical display ID when looking up display information */
|
|
640
|
+
usePhysicalDisplayIdForDisplayLookup?: boolean;
|
|
641
|
+
/** Custom device actions to register */
|
|
642
|
+
customActions?: DeviceAction<any>[];
|
|
643
|
+
/**
|
|
644
|
+
* @deprecated Use `screenshotShrinkFactor` in AgentOpt instead.
|
|
645
|
+
* This option no longer affects screenshot size sent to AI model.
|
|
646
|
+
*/
|
|
647
|
+
screenshotResizeScale?: number;
|
|
648
|
+
/** Always fetch screen info on each call; if false, cache the first result */
|
|
649
|
+
alwaysRefreshScreenInfo?: boolean;
|
|
650
|
+
/** Minimum screenshot buffer size in bytes (default: 10240 = 10KB). Set to 0 to disable validation. */
|
|
651
|
+
minScreenshotBufferSize?: number;
|
|
652
|
+
/**
|
|
653
|
+
* Scrcpy screenshot configuration for high-performance screen capture.
|
|
654
|
+
*
|
|
655
|
+
* Scrcpy provides 6-8x faster screenshots by streaming H.264 video from the device.
|
|
656
|
+
* When enabled, scrcpy will:
|
|
657
|
+
* 1. Start a video stream from the device on first screenshot request
|
|
658
|
+
* 2. Keep the connection alive for subsequent screenshots (16-50ms each)
|
|
659
|
+
* 3. Automatically disconnect after idle timeout to save resources
|
|
660
|
+
* 4. Fallback to standard ADB mode if unavailable
|
|
661
|
+
*
|
|
662
|
+
* @example
|
|
663
|
+
* ```typescript
|
|
664
|
+
* // Enable scrcpy for high-performance screenshots
|
|
665
|
+
* const device = new AndroidDevice(deviceId, {
|
|
666
|
+
* scrcpyConfig: {
|
|
667
|
+
* enabled: true,
|
|
668
|
+
* },
|
|
669
|
+
* });
|
|
670
|
+
*
|
|
671
|
+
* // Custom configuration
|
|
672
|
+
* const device = new AndroidDevice(deviceId, {
|
|
673
|
+
* scrcpyConfig: {
|
|
674
|
+
* enabled: true,
|
|
675
|
+
* maxSize: 0, // 0 = no scaling
|
|
676
|
+
* idleTimeoutMs: 30000,
|
|
677
|
+
* videoBitRate: 8_000_000,
|
|
678
|
+
* },
|
|
679
|
+
* });
|
|
680
|
+
* ```
|
|
681
|
+
*/
|
|
682
|
+
scrcpyConfig?: {
|
|
683
|
+
/**
|
|
684
|
+
* Enable scrcpy for high-performance screenshots.
|
|
685
|
+
* @default false
|
|
686
|
+
*/
|
|
687
|
+
enabled?: boolean;
|
|
688
|
+
/**
|
|
689
|
+
* Maximum video dimension (width or height).
|
|
690
|
+
* Video stream will be scaled down if device resolution exceeds this value.
|
|
691
|
+
* Lower values reduce bandwidth but may affect image quality.
|
|
692
|
+
*
|
|
693
|
+
* @default 0 (no scaling, use original resolution)
|
|
694
|
+
* @example
|
|
695
|
+
* { maxSize: 1024 } // Always scale to 1024
|
|
696
|
+
*/
|
|
697
|
+
maxSize?: number;
|
|
698
|
+
/**
|
|
699
|
+
* Idle timeout in milliseconds before disconnecting scrcpy.
|
|
700
|
+
* Connection auto-closes after this period of inactivity to save resources.
|
|
701
|
+
* Set to 0 to disable auto-disconnect.
|
|
702
|
+
* @default 30000 (30 seconds)
|
|
703
|
+
*/
|
|
704
|
+
idleTimeoutMs?: number;
|
|
705
|
+
/**
|
|
706
|
+
* Video bit rate for H.264 encoding in bits per second.
|
|
707
|
+
* Higher values improve quality but increase bandwidth usage.
|
|
708
|
+
* @default 2000000 (2 Mbps)
|
|
709
|
+
*/
|
|
710
|
+
videoBitRate?: number;
|
|
711
|
+
};
|
|
712
|
+
} & AndroidDeviceInputOpt;
|
|
713
|
+
|
|
232
714
|
/**
|
|
233
715
|
* Android-specific tools manager
|
|
234
716
|
* Extends BaseMidsceneTools to provide Android ADB device connection tools
|
|
@@ -242,6 +724,145 @@ export declare class AndroidMidsceneTools extends BaseMidsceneTools<AndroidAgent
|
|
|
242
724
|
protected preparePlatformTools(): ToolDefinition[];
|
|
243
725
|
}
|
|
244
726
|
|
|
727
|
+
/**
|
|
728
|
+
* Base agent interface
|
|
729
|
+
* Represents a platform-specific agent (Android, iOS, Web)
|
|
730
|
+
* Note: Return types use `unknown` for compatibility with platform-specific implementations
|
|
731
|
+
*/
|
|
732
|
+
declare interface BaseAgent {
|
|
733
|
+
getActionSpace(): Promise<ActionSpaceItem[]>;
|
|
734
|
+
destroy?(): Promise<void>;
|
|
735
|
+
page?: {
|
|
736
|
+
screenshotBase64(): Promise<string>;
|
|
737
|
+
};
|
|
738
|
+
aiAction?: (description: string, params?: Record<string, unknown>) => Promise<unknown>;
|
|
739
|
+
aiWaitFor?: (assertion: string, options: Record<string, unknown>) => Promise<unknown>;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* Base device interface for temporary device instances
|
|
744
|
+
*/
|
|
745
|
+
declare interface BaseDevice {
|
|
746
|
+
actionSpace(): ActionSpaceItem[];
|
|
747
|
+
destroy?(): Promise<void>;
|
|
748
|
+
}
|
|
749
|
+
|
|
750
|
+
/**
|
|
751
|
+
* Base class for platform-specific MCP tools
|
|
752
|
+
* Generic type TAgent allows subclasses to use their specific agent types
|
|
753
|
+
*/
|
|
754
|
+
declare abstract class BaseMidsceneTools<TAgent extends BaseAgent = BaseAgent> implements IMidsceneTools {
|
|
755
|
+
protected mcpServer?: McpServer;
|
|
756
|
+
protected agent?: TAgent;
|
|
757
|
+
protected toolDefinitions: ToolDefinition[];
|
|
758
|
+
/**
|
|
759
|
+
* Ensure agent is initialized and ready for use.
|
|
760
|
+
* Must be implemented by subclasses to create platform-specific agent.
|
|
761
|
+
* @param initParam Optional initialization parameter (platform-specific, e.g., URL, device ID)
|
|
762
|
+
* @returns Promise resolving to initialized agent instance
|
|
763
|
+
* @throws Error if agent initialization fails
|
|
764
|
+
*/
|
|
765
|
+
protected abstract ensureAgent(initParam?: string): Promise<TAgent>;
|
|
766
|
+
/**
|
|
767
|
+
* Optional: prepare platform-specific tools (e.g., device connection)
|
|
768
|
+
*/
|
|
769
|
+
protected preparePlatformTools(): ToolDefinition[];
|
|
770
|
+
/**
|
|
771
|
+
* Must be implemented by subclasses to create a temporary device instance
|
|
772
|
+
* This allows getting real actionSpace without connecting to device
|
|
773
|
+
*/
|
|
774
|
+
protected abstract createTemporaryDevice(): BaseDevice;
|
|
775
|
+
/**
|
|
776
|
+
* Initialize all tools by querying actionSpace
|
|
777
|
+
* Uses two-layer fallback strategy:
|
|
778
|
+
* 1. Try to get actionSpace from connected agent (if available)
|
|
779
|
+
* 2. Create temporary device instance to read actionSpace (always succeeds)
|
|
780
|
+
*/
|
|
781
|
+
initTools(): Promise<void>;
|
|
782
|
+
/**
|
|
783
|
+
* Attach to MCP server and register all tools
|
|
784
|
+
*/
|
|
785
|
+
attachToServer(server: McpServer): void;
|
|
786
|
+
/**
|
|
787
|
+
* Cleanup method - destroy agent and release resources
|
|
788
|
+
*/
|
|
789
|
+
destroy(): Promise<void>;
|
|
790
|
+
/**
|
|
791
|
+
* Get tool definitions
|
|
792
|
+
*/
|
|
793
|
+
getToolDefinitions(): ToolDefinition[];
|
|
794
|
+
/**
|
|
795
|
+
* Set agent for the tools manager
|
|
796
|
+
*/
|
|
797
|
+
setAgent(agent: TAgent): void;
|
|
798
|
+
/**
|
|
799
|
+
* Helper: Convert base64 screenshot to image content array
|
|
800
|
+
*/
|
|
801
|
+
protected buildScreenshotContent(screenshot: string): {
|
|
802
|
+
type: "image";
|
|
803
|
+
data: string;
|
|
804
|
+
mimeType: string;
|
|
805
|
+
}[];
|
|
806
|
+
/**
|
|
807
|
+
* Helper: Build a simple text result for tool responses
|
|
808
|
+
*/
|
|
809
|
+
protected buildTextResult(text: string): {
|
|
810
|
+
content: {
|
|
811
|
+
type: "text";
|
|
812
|
+
text: string;
|
|
813
|
+
}[];
|
|
814
|
+
};
|
|
815
|
+
/**
|
|
816
|
+
* Create a disconnect handler for releasing platform resources
|
|
817
|
+
* @param platformName Human-readable platform name for the response message
|
|
818
|
+
* @returns Handler function that destroys the agent and returns appropriate response
|
|
819
|
+
*/
|
|
820
|
+
protected createDisconnectHandler(platformName: string): () => Promise<{
|
|
821
|
+
content: {
|
|
822
|
+
type: "text";
|
|
823
|
+
text: string;
|
|
824
|
+
}[];
|
|
825
|
+
}>;
|
|
826
|
+
}
|
|
827
|
+
|
|
828
|
+
declare type Cache_2 = false | true | CacheConfig;
|
|
829
|
+
|
|
830
|
+
/**
|
|
831
|
+
* Agent
|
|
832
|
+
*/
|
|
833
|
+
declare type CacheConfig = {
|
|
834
|
+
strategy?: 'read-only' | 'read-write' | 'write-only';
|
|
835
|
+
id: string;
|
|
836
|
+
};
|
|
837
|
+
|
|
838
|
+
declare type CacheFileContent = {
|
|
839
|
+
midsceneVersion: string;
|
|
840
|
+
cacheId: string;
|
|
841
|
+
caches: Array<PlanningCache | LocateCache>;
|
|
842
|
+
};
|
|
843
|
+
|
|
844
|
+
declare type DeepThinkOption = 'unset' | true | false;
|
|
845
|
+
|
|
846
|
+
declare interface DetailedLocateParam extends Omit<LocateOption, 'deepThink' | keyof TMultimodalPrompt> {
|
|
847
|
+
prompt: TUserPrompt;
|
|
848
|
+
}
|
|
849
|
+
|
|
850
|
+
declare interface DeviceAction<TParam = any, TReturn = any> {
|
|
851
|
+
name: string;
|
|
852
|
+
description?: string;
|
|
853
|
+
interfaceAlias?: string;
|
|
854
|
+
paramSchema?: z.ZodType<TParam>;
|
|
855
|
+
call: (param: TParam, context: ExecutorContext) => Promise<TReturn> | TReturn;
|
|
856
|
+
delayAfterRunner?: number;
|
|
857
|
+
/**
|
|
858
|
+
* An example param object for this action.
|
|
859
|
+
* Locate fields with { prompt } will automatically get bbox injected when needed.
|
|
860
|
+
*/
|
|
861
|
+
sample?: {
|
|
862
|
+
[K in keyof TParam]?: any;
|
|
863
|
+
};
|
|
864
|
+
}
|
|
865
|
+
|
|
245
866
|
declare type DeviceActionAndroidBackButton = DeviceAction<undefined, void>;
|
|
246
867
|
|
|
247
868
|
declare type DeviceActionAndroidHomeButton = DeviceAction<undefined, void>;
|
|
@@ -256,9 +877,403 @@ declare interface DevicePhysicalInfo {
|
|
|
256
877
|
isCurrentOrientation?: boolean;
|
|
257
878
|
}
|
|
258
879
|
|
|
880
|
+
declare interface DumpMeta {
|
|
881
|
+
logTime: number;
|
|
882
|
+
}
|
|
883
|
+
|
|
884
|
+
declare type ElementCacheFeature = Record<string, unknown>;
|
|
885
|
+
|
|
886
|
+
declare interface ElementInfo {
|
|
887
|
+
id: string;
|
|
888
|
+
indexId: number;
|
|
889
|
+
nodeHashId: string;
|
|
890
|
+
xpaths?: string[];
|
|
891
|
+
attributes: {
|
|
892
|
+
nodeType: NodeType;
|
|
893
|
+
[key: string]: string;
|
|
894
|
+
};
|
|
895
|
+
nodeType: NodeType;
|
|
896
|
+
content: string;
|
|
897
|
+
rect: {
|
|
898
|
+
left: number;
|
|
899
|
+
top: number;
|
|
900
|
+
width: number;
|
|
901
|
+
height: number;
|
|
902
|
+
};
|
|
903
|
+
center: [number, number];
|
|
904
|
+
isVisible: boolean;
|
|
905
|
+
}
|
|
906
|
+
|
|
907
|
+
/**
|
|
908
|
+
* ExecutionDump class for serializing and deserializing execution dumps
|
|
909
|
+
*/
|
|
910
|
+
declare class ExecutionDump implements IExecutionDump {
|
|
911
|
+
id?: string;
|
|
912
|
+
logTime: number;
|
|
913
|
+
name: string;
|
|
914
|
+
description?: string;
|
|
915
|
+
tasks: ExecutionTask[];
|
|
916
|
+
aiActContext?: string;
|
|
917
|
+
constructor(data: IExecutionDump);
|
|
918
|
+
/**
|
|
919
|
+
* Serialize the ExecutionDump to a JSON string
|
|
920
|
+
*/
|
|
921
|
+
serialize(indents?: number): string;
|
|
922
|
+
/**
|
|
923
|
+
* Convert to a plain object for JSON serialization
|
|
924
|
+
*/
|
|
925
|
+
toJSON(): IExecutionDump;
|
|
926
|
+
/**
|
|
927
|
+
* Create an ExecutionDump instance from a serialized JSON string
|
|
928
|
+
*/
|
|
929
|
+
static fromSerializedString(serialized: string): ExecutionDump;
|
|
930
|
+
/**
|
|
931
|
+
* Create an ExecutionDump instance from a plain object
|
|
932
|
+
*/
|
|
933
|
+
static fromJSON(data: IExecutionDump): ExecutionDump;
|
|
934
|
+
/**
|
|
935
|
+
* Collect all ScreenshotItem instances from tasks.
|
|
936
|
+
* Scans through uiContext and recorder items to find screenshots.
|
|
937
|
+
*
|
|
938
|
+
* @returns Array of ScreenshotItem instances
|
|
939
|
+
*/
|
|
940
|
+
collectScreenshots(): ScreenshotItem[];
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
declare interface ExecutionRecorderItem {
|
|
944
|
+
type: 'screenshot';
|
|
945
|
+
ts: number;
|
|
946
|
+
screenshot?: ScreenshotItem;
|
|
947
|
+
timing?: string;
|
|
948
|
+
}
|
|
949
|
+
|
|
950
|
+
declare interface ExecutionResult<OutputType = any> {
|
|
951
|
+
output: OutputType;
|
|
952
|
+
thought?: string;
|
|
953
|
+
runner: TaskRunner;
|
|
954
|
+
}
|
|
955
|
+
|
|
956
|
+
declare type ExecutionTask<E extends ExecutionTaskApply<any, any, any> = ExecutionTaskApply<any, any, any>> = E & ExecutionTaskReturn<E extends ExecutionTaskApply<any, any, infer TaskOutput, any> ? TaskOutput : unknown, E extends ExecutionTaskApply<any, any, any, infer TaskLog> ? TaskLog : unknown> & {
|
|
957
|
+
taskId: string;
|
|
958
|
+
status: 'pending' | 'running' | 'finished' | 'failed' | 'cancelled';
|
|
959
|
+
error?: Error;
|
|
960
|
+
errorMessage?: string;
|
|
961
|
+
errorStack?: string;
|
|
962
|
+
timing?: {
|
|
963
|
+
start: number;
|
|
964
|
+
getUiContextStart?: number;
|
|
965
|
+
getUiContextEnd?: number;
|
|
966
|
+
callAiStart?: number;
|
|
967
|
+
callAiEnd?: number;
|
|
968
|
+
beforeInvokeActionHookStart?: number;
|
|
969
|
+
beforeInvokeActionHookEnd?: number;
|
|
970
|
+
callActionStart?: number;
|
|
971
|
+
callActionEnd?: number;
|
|
972
|
+
afterInvokeActionHookStart?: number;
|
|
973
|
+
afterInvokeActionHookEnd?: number;
|
|
974
|
+
captureAfterCallingSnapshotStart?: number;
|
|
975
|
+
captureAfterCallingSnapshotEnd?: number;
|
|
976
|
+
end?: number;
|
|
977
|
+
cost?: number;
|
|
978
|
+
};
|
|
979
|
+
usage?: AIUsageInfo;
|
|
980
|
+
searchAreaUsage?: AIUsageInfo;
|
|
981
|
+
reasoning_content?: string;
|
|
982
|
+
};
|
|
983
|
+
|
|
984
|
+
declare interface ExecutionTaskApply<Type extends ExecutionTaskType = any, TaskParam = any, TaskOutput = any, TaskLog = any> {
|
|
985
|
+
type: Type;
|
|
986
|
+
subType?: string;
|
|
987
|
+
param?: TaskParam;
|
|
988
|
+
thought?: string;
|
|
989
|
+
uiContext?: UIContext;
|
|
990
|
+
executor: (param: TaskParam, context: ExecutorContext) => Promise<ExecutionTaskReturn<TaskOutput, TaskLog> | undefined | void> | undefined | void;
|
|
991
|
+
}
|
|
992
|
+
|
|
993
|
+
declare interface ExecutionTaskHitBy {
|
|
994
|
+
from: string;
|
|
995
|
+
context: Record<string, any>;
|
|
996
|
+
}
|
|
997
|
+
|
|
998
|
+
declare interface ExecutionTaskProgressOptions {
|
|
999
|
+
onTaskStart?: (task: ExecutionTask) => Promise<void> | void;
|
|
1000
|
+
}
|
|
1001
|
+
|
|
1002
|
+
declare interface ExecutionTaskReturn<TaskOutput = unknown, TaskLog = unknown> {
|
|
1003
|
+
output?: TaskOutput;
|
|
1004
|
+
log?: TaskLog;
|
|
1005
|
+
recorder?: ExecutionRecorderItem[];
|
|
1006
|
+
hitBy?: ExecutionTaskHitBy;
|
|
1007
|
+
}
|
|
1008
|
+
|
|
1009
|
+
declare type ExecutionTaskType = 'Planning' | 'Insight' | 'Action Space' | 'Log';
|
|
1010
|
+
|
|
1011
|
+
declare interface ExecutorContext {
|
|
1012
|
+
task: ExecutionTask;
|
|
1013
|
+
element?: LocateResultElement | null;
|
|
1014
|
+
uiContext?: UIContext;
|
|
1015
|
+
}
|
|
1016
|
+
|
|
1017
|
+
declare interface FileChooserHandler {
|
|
1018
|
+
accept(files: string[]): Promise<void>;
|
|
1019
|
+
}
|
|
1020
|
+
|
|
259
1021
|
export declare function getConnectedDevices(): Promise<Device[]>;
|
|
260
1022
|
|
|
261
|
-
|
|
1023
|
+
/**
|
|
1024
|
+
* Non model related env keys, used for globally controlling the behavior of midscene
|
|
1025
|
+
* Can not be override by agent.modelConfig but can be override by overrideAIConfig
|
|
1026
|
+
* Can be access at any time
|
|
1027
|
+
*/
|
|
1028
|
+
declare const GLOBAL_ENV_KEYS: readonly ["MIDSCENE_CACHE", "MIDSCENE_MCP_USE_PUPPETEER_MODE", "MIDSCENE_MCP_ANDROID_MODE", "MIDSCENE_LANGSMITH_DEBUG", "MIDSCENE_LANGFUSE_DEBUG", "MIDSCENE_REPORT_QUIET", "MIDSCENE_MODEL_MAX_TOKENS", "MIDSCENE_CACHE_MAX_FILENAME_LENGTH", "MIDSCENE_REPLANNING_CYCLE_LIMIT", "MIDSCENE_MODEL_MAX_TOKENS", "OPENAI_MAX_TOKENS", "MIDSCENE_ADB_PATH", "MIDSCENE_ADB_REMOTE_HOST", "MIDSCENE_ADB_REMOTE_PORT", "MIDSCENE_ANDROID_IME_STRATEGY", "MIDSCENE_IOS_DEVICE_UDID", "MIDSCENE_IOS_SIMULATOR_UDID", "MIDSCENE_REPORT_TAG_NAME", "MIDSCENE_PREFERRED_LANGUAGE", "MATCH_BY_POSITION", "MIDSCENE_MCP_CHROME_PATH", "DOCKER_CONTAINER"];
|
|
1029
|
+
|
|
1030
|
+
/**
|
|
1031
|
+
* GroupedActionDump class for serializing and deserializing grouped action dumps
|
|
1032
|
+
*/
|
|
1033
|
+
declare class GroupedActionDump implements IGroupedActionDump {
|
|
1034
|
+
sdkVersion: string;
|
|
1035
|
+
groupName: string;
|
|
1036
|
+
groupDescription?: string;
|
|
1037
|
+
modelBriefs: ModelBrief[];
|
|
1038
|
+
executions: ExecutionDump[];
|
|
1039
|
+
deviceType?: string;
|
|
1040
|
+
constructor(data: IGroupedActionDump);
|
|
1041
|
+
/**
|
|
1042
|
+
* Serialize the GroupedActionDump to a JSON string
|
|
1043
|
+
* Uses compact { $screenshot: id } format
|
|
1044
|
+
*/
|
|
1045
|
+
serialize(indents?: number): string;
|
|
1046
|
+
/**
|
|
1047
|
+
* Serialize the GroupedActionDump with inline screenshots to a JSON string.
|
|
1048
|
+
* Each ScreenshotItem is replaced with { base64: "...", capturedAt }.
|
|
1049
|
+
*/
|
|
1050
|
+
serializeWithInlineScreenshots(indents?: number): string;
|
|
1051
|
+
/**
|
|
1052
|
+
* Convert to a plain object for JSON serialization
|
|
1053
|
+
*/
|
|
1054
|
+
toJSON(): IGroupedActionDump;
|
|
1055
|
+
/**
|
|
1056
|
+
* Create a GroupedActionDump instance from a serialized JSON string
|
|
1057
|
+
*/
|
|
1058
|
+
static fromSerializedString(serialized: string): GroupedActionDump;
|
|
1059
|
+
/**
|
|
1060
|
+
* Create a GroupedActionDump instance from a plain object
|
|
1061
|
+
*/
|
|
1062
|
+
static fromJSON(data: IGroupedActionDump): GroupedActionDump;
|
|
1063
|
+
/**
|
|
1064
|
+
* Collect all ScreenshotItem instances from all executions.
|
|
1065
|
+
*
|
|
1066
|
+
* @returns Array of all ScreenshotItem instances across all executions
|
|
1067
|
+
*/
|
|
1068
|
+
collectAllScreenshots(): ScreenshotItem[];
|
|
1069
|
+
/**
|
|
1070
|
+
* Serialize the dump to files with screenshots as separate PNG files.
|
|
1071
|
+
* Creates:
|
|
1072
|
+
* - {basePath} - dump JSON with { $screenshot: id } references
|
|
1073
|
+
* - {basePath}.screenshots/ - PNG files
|
|
1074
|
+
* - {basePath}.screenshots.json - ID to path mapping
|
|
1075
|
+
*
|
|
1076
|
+
* @param basePath - Base path for the dump file
|
|
1077
|
+
*/
|
|
1078
|
+
serializeToFiles(basePath: string): void;
|
|
1079
|
+
/**
|
|
1080
|
+
* Read dump from files and return JSON string with inline screenshots.
|
|
1081
|
+
* Reads the dump JSON and screenshot files, then inlines the base64 data.
|
|
1082
|
+
*
|
|
1083
|
+
* @param basePath - Base path for the dump file
|
|
1084
|
+
* @returns JSON string with inline screenshots ({ base64: "..." } format)
|
|
1085
|
+
*/
|
|
1086
|
+
static fromFilesAsInlineJson(basePath: string): string;
|
|
1087
|
+
/**
|
|
1088
|
+
* Clean up all files associated with a serialized dump.
|
|
1089
|
+
*
|
|
1090
|
+
* @param basePath - Base path for the dump file
|
|
1091
|
+
*/
|
|
1092
|
+
static cleanupFiles(basePath: string): void;
|
|
1093
|
+
/**
|
|
1094
|
+
* Get all file paths associated with a serialized dump.
|
|
1095
|
+
*
|
|
1096
|
+
* @param basePath - Base path for the dump file
|
|
1097
|
+
* @returns Array of all associated file paths
|
|
1098
|
+
*/
|
|
1099
|
+
static getFilePaths(basePath: string): string[];
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
declare interface IExecutionDump extends DumpMeta {
|
|
1103
|
+
/** Stable unique identifier for this execution run */
|
|
1104
|
+
id?: string;
|
|
1105
|
+
name: string;
|
|
1106
|
+
description?: string;
|
|
1107
|
+
tasks: ExecutionTask[];
|
|
1108
|
+
aiActContext?: string;
|
|
1109
|
+
}
|
|
1110
|
+
|
|
1111
|
+
declare interface IGroupedActionDump {
|
|
1112
|
+
sdkVersion: string;
|
|
1113
|
+
groupName: string;
|
|
1114
|
+
groupDescription?: string;
|
|
1115
|
+
modelBriefs: ModelBrief[];
|
|
1116
|
+
executions: IExecutionDump[];
|
|
1117
|
+
deviceType?: string;
|
|
1118
|
+
}
|
|
1119
|
+
|
|
1120
|
+
/**
|
|
1121
|
+
* Interface for platform-specific MCP tools manager
|
|
1122
|
+
*/
|
|
1123
|
+
declare interface IMidsceneTools {
|
|
1124
|
+
attachToServer(server: McpServer): void;
|
|
1125
|
+
initTools(): Promise<void>;
|
|
1126
|
+
destroy?(): Promise<void>;
|
|
1127
|
+
}
|
|
1128
|
+
|
|
1129
|
+
declare type InterfaceType = 'puppeteer' | 'playwright' | 'static' | 'chrome-extension-proxy' | 'android' | string;
|
|
1130
|
+
|
|
1131
|
+
declare interface LocateCache {
|
|
1132
|
+
type: 'locate';
|
|
1133
|
+
prompt: TUserPrompt;
|
|
1134
|
+
cache?: ElementCacheFeature;
|
|
1135
|
+
/** @deprecated kept for backward compatibility */
|
|
1136
|
+
xpaths?: string[];
|
|
1137
|
+
}
|
|
1138
|
+
|
|
1139
|
+
declare interface LocateOption extends Partial<TMultimodalPrompt> {
|
|
1140
|
+
prompt?: TUserPrompt;
|
|
1141
|
+
deepLocate?: boolean;
|
|
1142
|
+
/** @deprecated Use `deepLocate` instead. Kept for backward compatibility. */
|
|
1143
|
+
deepThink?: boolean;
|
|
1144
|
+
cacheable?: boolean;
|
|
1145
|
+
xpath?: string;
|
|
1146
|
+
uiContext?: UIContext;
|
|
1147
|
+
fileChooserAccept?: string | string[];
|
|
1148
|
+
}
|
|
1149
|
+
|
|
1150
|
+
declare interface LocateOpts {
|
|
1151
|
+
context?: UIContext;
|
|
1152
|
+
planLocatedElement?: LocateResultElement;
|
|
1153
|
+
}
|
|
1154
|
+
|
|
1155
|
+
declare interface LocateResult {
|
|
1156
|
+
element: LocateResultElement | null;
|
|
1157
|
+
rect?: Rect;
|
|
1158
|
+
}
|
|
1159
|
+
|
|
1160
|
+
declare type LocateResultWithDump = LocateResult & ServiceResultBase;
|
|
1161
|
+
|
|
1162
|
+
declare interface LocateValidatorResult {
|
|
1163
|
+
pass: boolean;
|
|
1164
|
+
rect: Rect;
|
|
1165
|
+
center: [number, number];
|
|
1166
|
+
centerDistance?: number;
|
|
1167
|
+
}
|
|
1168
|
+
|
|
1169
|
+
declare interface LocatorValidatorOption {
|
|
1170
|
+
centerDistanceThreshold?: number;
|
|
1171
|
+
}
|
|
1172
|
+
|
|
1173
|
+
declare interface MatchCacheResult<T extends PlanningCache | LocateCache> {
|
|
1174
|
+
cacheContent: T;
|
|
1175
|
+
cacheUsable: boolean;
|
|
1176
|
+
updateFn: (cb: (cache: T) => void) => void;
|
|
1177
|
+
}
|
|
1178
|
+
|
|
1179
|
+
declare type MidsceneYamlFlowItem = MidsceneYamlFlowItemAIAction | MidsceneYamlFlowItemAIAssert | MidsceneYamlFlowItemAIWaitFor | MidsceneYamlFlowItemEvaluateJavaScript | MidsceneYamlFlowItemSleep | MidsceneYamlFlowItemLogScreenshot;
|
|
1180
|
+
|
|
1181
|
+
declare interface MidsceneYamlFlowItemAIAction {
|
|
1182
|
+
aiAction?: string;
|
|
1183
|
+
ai?: string;
|
|
1184
|
+
aiAct?: string;
|
|
1185
|
+
aiActionProgressTips?: string[];
|
|
1186
|
+
cacheable?: boolean;
|
|
1187
|
+
[key: string]: unknown;
|
|
1188
|
+
}
|
|
1189
|
+
|
|
1190
|
+
declare interface MidsceneYamlFlowItemAIAssert extends ServiceExtractOption {
|
|
1191
|
+
aiAssert: string;
|
|
1192
|
+
errorMessage?: string;
|
|
1193
|
+
name?: string;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
declare interface MidsceneYamlFlowItemAIWaitFor extends ServiceExtractOption {
|
|
1197
|
+
aiWaitFor: string;
|
|
1198
|
+
timeout?: number;
|
|
1199
|
+
}
|
|
1200
|
+
|
|
1201
|
+
declare interface MidsceneYamlFlowItemEvaluateJavaScript {
|
|
1202
|
+
javascript: string;
|
|
1203
|
+
name?: string;
|
|
1204
|
+
}
|
|
1205
|
+
|
|
1206
|
+
declare interface MidsceneYamlFlowItemLogScreenshot {
|
|
1207
|
+
logScreenshot?: string;
|
|
1208
|
+
recordToReport?: string;
|
|
1209
|
+
content?: string;
|
|
1210
|
+
}
|
|
1211
|
+
|
|
1212
|
+
declare interface MidsceneYamlFlowItemSleep {
|
|
1213
|
+
sleep: number;
|
|
1214
|
+
}
|
|
1215
|
+
|
|
1216
|
+
/**
|
|
1217
|
+
* Model related eve keys, used for declare which model to use.
|
|
1218
|
+
* Can be override by both agent.modelConfig and overrideAIConfig
|
|
1219
|
+
* Can only be access after agent.constructor
|
|
1220
|
+
*/
|
|
1221
|
+
declare const MODEL_ENV_KEYS: readonly ["MIDSCENE_MODEL_NAME", "MIDSCENE_MODEL_INIT_CONFIG_JSON", "MIDSCENE_MODEL_EXTRA_BODY_JSON", "MIDSCENE_MODEL_API_KEY", "MIDSCENE_MODEL_BASE_URL", "MIDSCENE_MODEL_SOCKS_PROXY", "MIDSCENE_MODEL_HTTP_PROXY", "MIDSCENE_MODEL_TIMEOUT", "MIDSCENE_MODEL_TEMPERATURE", "MIDSCENE_MODEL_RETRY_COUNT", "MIDSCENE_MODEL_RETRY_INTERVAL", "MIDSCENE_MODEL_REASONING_EFFORT", "MIDSCENE_MODEL_REASONING_ENABLED", "MIDSCENE_MODEL_REASONING_BUDGET", "MIDSCENE_USE_VLM_UI_TARS", "MIDSCENE_USE_QWEN_VL", "MIDSCENE_USE_QWEN3_VL", "MIDSCENE_USE_DOUBAO_VISION", "MIDSCENE_USE_GEMINI", "MIDSCENE_USE_VL_MODEL", "OPENAI_API_KEY", "OPENAI_BASE_URL", "MIDSCENE_OPENAI_INIT_CONFIG_JSON", "MIDSCENE_OPENAI_HTTP_PROXY", "MIDSCENE_OPENAI_SOCKS_PROXY", "MIDSCENE_INSIGHT_MODEL_NAME", "MIDSCENE_INSIGHT_MODEL_SOCKS_PROXY", "MIDSCENE_INSIGHT_MODEL_HTTP_PROXY", "MIDSCENE_INSIGHT_MODEL_BASE_URL", "MIDSCENE_INSIGHT_MODEL_API_KEY", "MIDSCENE_INSIGHT_MODEL_INIT_CONFIG_JSON", "MIDSCENE_INSIGHT_MODEL_EXTRA_BODY_JSON", "MIDSCENE_INSIGHT_MODEL_TIMEOUT", "MIDSCENE_INSIGHT_MODEL_TEMPERATURE", "MIDSCENE_INSIGHT_MODEL_RETRY_COUNT", "MIDSCENE_INSIGHT_MODEL_RETRY_INTERVAL", "MIDSCENE_INSIGHT_MODEL_FAMILY", "MIDSCENE_INSIGHT_MODEL_REASONING_EFFORT", "MIDSCENE_INSIGHT_MODEL_REASONING_ENABLED", "MIDSCENE_INSIGHT_MODEL_REASONING_BUDGET", "MIDSCENE_PLANNING_MODEL_NAME", "MIDSCENE_PLANNING_MODEL_SOCKS_PROXY", "MIDSCENE_PLANNING_MODEL_HTTP_PROXY", "MIDSCENE_PLANNING_MODEL_BASE_URL", "MIDSCENE_PLANNING_MODEL_API_KEY", "MIDSCENE_PLANNING_MODEL_INIT_CONFIG_JSON", "MIDSCENE_PLANNING_MODEL_EXTRA_BODY_JSON", "MIDSCENE_PLANNING_MODEL_TIMEOUT", "MIDSCENE_PLANNING_MODEL_TEMPERATURE", "MIDSCENE_PLANNING_MODEL_RETRY_COUNT", "MIDSCENE_PLANNING_MODEL_RETRY_INTERVAL", "MIDSCENE_PLANNING_MODEL_FAMILY", "MIDSCENE_PLANNING_MODEL_REASONING_EFFORT", "MIDSCENE_PLANNING_MODEL_REASONING_ENABLED", "MIDSCENE_PLANNING_MODEL_REASONING_BUDGET", "MIDSCENE_MODEL_FAMILY"];
|
|
1222
|
+
|
|
1223
|
+
declare interface ModelBrief {
|
|
1224
|
+
/**
|
|
1225
|
+
* The intent/category of the model call, for example "planning" or "insight".
|
|
1226
|
+
*/
|
|
1227
|
+
intent?: string;
|
|
1228
|
+
/**
|
|
1229
|
+
* The model name returned by usage metadata, for example "gpt-4o".
|
|
1230
|
+
*/
|
|
1231
|
+
name?: string;
|
|
1232
|
+
/**
|
|
1233
|
+
* Optional human-readable model description, for example "qwen2.5-vl mode".
|
|
1234
|
+
*/
|
|
1235
|
+
modelDescription?: string;
|
|
1236
|
+
}
|
|
1237
|
+
|
|
1238
|
+
declare enum NodeType {
|
|
1239
|
+
CONTAINER = "CONTAINER Node",
|
|
1240
|
+
FORM_ITEM = "FORM_ITEM Node",
|
|
1241
|
+
BUTTON = "BUTTON Node",
|
|
1242
|
+
A = "Anchor Node",
|
|
1243
|
+
IMG = "IMG Node",
|
|
1244
|
+
TEXT = "TEXT Node",
|
|
1245
|
+
POSITION = "POSITION Node"
|
|
1246
|
+
}
|
|
1247
|
+
|
|
1248
|
+
/**
|
|
1249
|
+
* agent
|
|
1250
|
+
*/
|
|
1251
|
+
declare type OnTaskStartTip = (tip: string) => Promise<void> | void;
|
|
1252
|
+
|
|
1253
|
+
export declare const overrideAIConfig: (newConfig: Partial<Record<(typeof GLOBAL_ENV_KEYS)[number] | (typeof MODEL_ENV_KEYS)[number], string>>, extendMode?: boolean) => void;
|
|
1254
|
+
|
|
1255
|
+
declare interface PlanningAction<ParamType = any> {
|
|
1256
|
+
thought?: string;
|
|
1257
|
+
log?: string;
|
|
1258
|
+
type: string;
|
|
1259
|
+
param: ParamType;
|
|
1260
|
+
}
|
|
1261
|
+
|
|
1262
|
+
declare type PlanningActionParamWaitFor = AgentWaitForOpt & {};
|
|
1263
|
+
|
|
1264
|
+
declare interface PlanningCache {
|
|
1265
|
+
type: 'plan';
|
|
1266
|
+
prompt: string;
|
|
1267
|
+
yamlWorkflow: string;
|
|
1268
|
+
}
|
|
1269
|
+
|
|
1270
|
+
/**
|
|
1271
|
+
* planning
|
|
1272
|
+
*
|
|
1273
|
+
*/
|
|
1274
|
+
declare interface PlanningLocateParam extends DetailedLocateParam {
|
|
1275
|
+
bbox?: [number, number, number, number];
|
|
1276
|
+
}
|
|
262
1277
|
|
|
263
1278
|
declare interface ResolvedScrcpyConfig {
|
|
264
1279
|
enabled: boolean;
|
|
@@ -440,6 +1455,423 @@ declare interface ScrcpyScreenshotOptions {
|
|
|
440
1455
|
idleTimeoutMs?: number;
|
|
441
1456
|
}
|
|
442
1457
|
|
|
1458
|
+
/**
|
|
1459
|
+
* ScreenshotItem encapsulates screenshot data.
|
|
1460
|
+
*
|
|
1461
|
+
* Supports lazy loading after memory release:
|
|
1462
|
+
* - inline mode: reads from HTML file using streaming (extractImageByIdSync)
|
|
1463
|
+
* - directory mode: reads from file on disk
|
|
1464
|
+
*
|
|
1465
|
+
* After persistence, memory is released but the screenshot can be recovered
|
|
1466
|
+
* on-demand from disk, making it safe to release memory at any time.
|
|
1467
|
+
*/
|
|
1468
|
+
declare class ScreenshotItem {
|
|
1469
|
+
private _id;
|
|
1470
|
+
private _base64;
|
|
1471
|
+
private _format;
|
|
1472
|
+
private _capturedAt;
|
|
1473
|
+
private _persistedAs;
|
|
1474
|
+
private _persistedPath;
|
|
1475
|
+
private _persistedHtmlPath;
|
|
1476
|
+
private constructor();
|
|
1477
|
+
/** Create a new ScreenshotItem from base64 data */
|
|
1478
|
+
static create(base64: string, capturedAt: number): ScreenshotItem;
|
|
1479
|
+
get id(): string;
|
|
1480
|
+
/** Get the image format (png or jpeg) */
|
|
1481
|
+
get format(): 'png' | 'jpeg';
|
|
1482
|
+
/** Get the file extension for this screenshot */
|
|
1483
|
+
get extension(): string;
|
|
1484
|
+
/** Get screenshot capture timestamp in milliseconds */
|
|
1485
|
+
get capturedAt(): number;
|
|
1486
|
+
get base64(): string;
|
|
1487
|
+
/** Check if base64 data is still available in memory (not yet released) */
|
|
1488
|
+
hasBase64(): boolean;
|
|
1489
|
+
/**
|
|
1490
|
+
* Mark as persisted to HTML (inline mode).
|
|
1491
|
+
* Releases base64 memory, but keeps HTML path for lazy loading recovery.
|
|
1492
|
+
* @param htmlPath - absolute path to the HTML file containing the image
|
|
1493
|
+
*/
|
|
1494
|
+
markPersistedInline(htmlPath: string): void;
|
|
1495
|
+
/**
|
|
1496
|
+
* Mark as persisted to file (directory mode).
|
|
1497
|
+
* Releases base64 memory, but keeps file path for lazy loading recovery.
|
|
1498
|
+
* @param relativePath - relative path for serialization (e.g., "./screenshots/id.jpeg")
|
|
1499
|
+
* @param absolutePath - absolute path for lazy loading recovery
|
|
1500
|
+
*/
|
|
1501
|
+
markPersistedToPath(relativePath: string, absolutePath: string): void;
|
|
1502
|
+
/** Serialize for JSON - format depends on persistence state */
|
|
1503
|
+
toSerializable(): ScreenshotSerializeFormat;
|
|
1504
|
+
/** Check if a value is a serialized ScreenshotItem reference (inline or directory mode) */
|
|
1505
|
+
static isSerialized(value: unknown): value is ScreenshotSerializeFormat;
|
|
1506
|
+
/**
|
|
1507
|
+
* Get base64 data without the data URI prefix.
|
|
1508
|
+
* Useful for writing raw binary data to files.
|
|
1509
|
+
*/
|
|
1510
|
+
get rawBase64(): string;
|
|
1511
|
+
}
|
|
1512
|
+
|
|
1513
|
+
/**
|
|
1514
|
+
* Serialization format for ScreenshotItem
|
|
1515
|
+
* - { $screenshot: "id" } - inline mode, references imageMap in HTML
|
|
1516
|
+
* - { base64: "path" } - directory mode, references external file path
|
|
1517
|
+
*/
|
|
1518
|
+
declare type ScreenshotSerializeFormat = {
|
|
1519
|
+
$screenshot: string;
|
|
1520
|
+
capturedAt: number;
|
|
1521
|
+
} | {
|
|
1522
|
+
base64: string;
|
|
1523
|
+
capturedAt: number;
|
|
1524
|
+
};
|
|
1525
|
+
|
|
1526
|
+
declare type ScrollParam = Omit<ActionScrollParam, 'locate'>;
|
|
1527
|
+
|
|
1528
|
+
declare type ScrollType = 'singleAction' | 'scrollToBottom' | 'scrollToTop' | 'scrollToRight' | 'scrollToLeft' | 'once' | 'untilBottom' | 'untilTop' | 'untilRight' | 'untilLeft';
|
|
1529
|
+
|
|
1530
|
+
declare class Service {
|
|
1531
|
+
contextRetrieverFn: () => Promise<UIContext> | UIContext;
|
|
1532
|
+
taskInfo?: Omit<ServiceTaskInfo, 'durationMs'>;
|
|
1533
|
+
constructor(context: UIContext | (() => Promise<UIContext> | UIContext), opt?: ServiceOptions);
|
|
1534
|
+
locate(query: PlanningLocateParam, opt: LocateOpts, modelConfig: IModelConfig, abortSignal?: AbortSignal): Promise<LocateResultWithDump>;
|
|
1535
|
+
extract<T>(dataDemand: ServiceExtractParam, modelConfig: IModelConfig, opt?: ServiceExtractOption, pageDescription?: string, multimodalPrompt?: TMultimodalPrompt, context?: UIContext): Promise<ServiceExtractResult<T>>;
|
|
1536
|
+
describe(target: Rect | [number, number], modelConfig: IModelConfig, opt?: {
|
|
1537
|
+
deepLocate?: boolean;
|
|
1538
|
+
}): Promise<Pick<AIDescribeElementResponse, 'description'>>;
|
|
1539
|
+
}
|
|
1540
|
+
|
|
1541
|
+
declare type ServiceAction = 'locate' | 'extract' | 'assert' | 'describe';
|
|
1542
|
+
|
|
1543
|
+
declare interface ServiceDump extends DumpMeta {
|
|
1544
|
+
type: 'locate' | 'extract' | 'assert';
|
|
1545
|
+
logId: string;
|
|
1546
|
+
userQuery: {
|
|
1547
|
+
element?: TUserPrompt;
|
|
1548
|
+
dataDemand?: ServiceExtractParam;
|
|
1549
|
+
assertion?: TUserPrompt;
|
|
1550
|
+
};
|
|
1551
|
+
matchedElement: LocateResultElement[];
|
|
1552
|
+
matchedRect?: Rect;
|
|
1553
|
+
deepLocate?: boolean;
|
|
1554
|
+
data: any;
|
|
1555
|
+
assertionPass?: boolean;
|
|
1556
|
+
assertionThought?: string;
|
|
1557
|
+
taskInfo: ServiceTaskInfo;
|
|
1558
|
+
error?: string;
|
|
1559
|
+
output?: any;
|
|
1560
|
+
}
|
|
1561
|
+
|
|
1562
|
+
declare interface ServiceExtractOption {
|
|
1563
|
+
domIncluded?: boolean | 'visible-only';
|
|
1564
|
+
screenshotIncluded?: boolean;
|
|
1565
|
+
[key: string]: unknown;
|
|
1566
|
+
}
|
|
1567
|
+
|
|
1568
|
+
declare type ServiceExtractParam = string | Record<string, string>;
|
|
1569
|
+
|
|
1570
|
+
declare interface ServiceExtractResult<T> extends ServiceResultBase {
|
|
1571
|
+
data: T;
|
|
1572
|
+
thought?: string;
|
|
1573
|
+
usage?: AIUsageInfo;
|
|
1574
|
+
reasoning_content?: string;
|
|
1575
|
+
}
|
|
1576
|
+
|
|
1577
|
+
declare interface ServiceOptions {
|
|
1578
|
+
taskInfo?: Omit<ServiceTaskInfo, 'durationMs'>;
|
|
1579
|
+
}
|
|
1580
|
+
|
|
1581
|
+
declare interface ServiceResultBase {
|
|
1582
|
+
dump: ServiceDump;
|
|
1583
|
+
}
|
|
1584
|
+
|
|
1585
|
+
declare interface ServiceTaskInfo {
|
|
1586
|
+
durationMs: number;
|
|
1587
|
+
formatResponse?: string;
|
|
1588
|
+
rawResponse?: string;
|
|
1589
|
+
usage?: AIUsageInfo;
|
|
1590
|
+
searchArea?: Rect;
|
|
1591
|
+
searchAreaRawResponse?: string;
|
|
1592
|
+
searchAreaUsage?: AIUsageInfo;
|
|
1593
|
+
reasoning_content?: string;
|
|
1594
|
+
}
|
|
1595
|
+
|
|
1596
|
+
declare class TaskCache {
|
|
1597
|
+
cacheId: string;
|
|
1598
|
+
cacheFilePath?: string;
|
|
1599
|
+
cache: CacheFileContent;
|
|
1600
|
+
isCacheResultUsed: boolean;
|
|
1601
|
+
cacheOriginalLength: number;
|
|
1602
|
+
readOnlyMode: boolean;
|
|
1603
|
+
writeOnlyMode: boolean;
|
|
1604
|
+
private matchedCacheIndices;
|
|
1605
|
+
constructor(cacheId: string, isCacheResultUsed: boolean, cacheFilePath?: string, options?: {
|
|
1606
|
+
readOnly?: boolean;
|
|
1607
|
+
writeOnly?: boolean;
|
|
1608
|
+
});
|
|
1609
|
+
matchCache(prompt: TUserPrompt, type: 'plan' | 'locate'): MatchCacheResult<PlanningCache | LocateCache> | undefined;
|
|
1610
|
+
matchPlanCache(prompt: string): MatchCacheResult<PlanningCache> | undefined;
|
|
1611
|
+
matchLocateCache(prompt: TUserPrompt): MatchCacheResult<LocateCache> | undefined;
|
|
1612
|
+
appendCache(cache: PlanningCache | LocateCache): void;
|
|
1613
|
+
loadCacheFromFile(): CacheFileContent | undefined;
|
|
1614
|
+
flushCacheToFile(options?: {
|
|
1615
|
+
cleanUnused?: boolean;
|
|
1616
|
+
}): void;
|
|
1617
|
+
updateOrAppendCacheRecord(newRecord: PlanningCache | LocateCache, cachedRecord?: MatchCacheResult<PlanningCache | LocateCache>): void;
|
|
1618
|
+
}
|
|
1619
|
+
|
|
1620
|
+
declare class TaskExecutionError extends Error {
|
|
1621
|
+
runner: TaskRunner;
|
|
1622
|
+
errorTask: ExecutionTask | null;
|
|
1623
|
+
constructor(message: string, runner: TaskRunner, errorTask: ExecutionTask | null, options?: {
|
|
1624
|
+
cause?: unknown;
|
|
1625
|
+
});
|
|
1626
|
+
}
|
|
1627
|
+
|
|
1628
|
+
declare class TaskExecutor {
|
|
1629
|
+
interface: AbstractInterface;
|
|
1630
|
+
service: Service;
|
|
1631
|
+
taskCache?: TaskCache;
|
|
1632
|
+
private readonly providedActionSpace;
|
|
1633
|
+
private readonly taskBuilder;
|
|
1634
|
+
onTaskStartCallback?: ExecutionTaskProgressOptions['onTaskStart'];
|
|
1635
|
+
private readonly hooks?;
|
|
1636
|
+
replanningCycleLimit?: number;
|
|
1637
|
+
waitAfterAction?: number;
|
|
1638
|
+
useDeviceTimestamp?: boolean;
|
|
1639
|
+
get page(): AbstractInterface;
|
|
1640
|
+
constructor(interfaceInstance: AbstractInterface, service: Service, opts: {
|
|
1641
|
+
taskCache?: TaskCache;
|
|
1642
|
+
onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];
|
|
1643
|
+
replanningCycleLimit?: number;
|
|
1644
|
+
waitAfterAction?: number;
|
|
1645
|
+
useDeviceTimestamp?: boolean;
|
|
1646
|
+
hooks?: TaskExecutorHooks;
|
|
1647
|
+
actionSpace: DeviceAction[];
|
|
1648
|
+
});
|
|
1649
|
+
private createExecutionSession;
|
|
1650
|
+
private getActionSpace;
|
|
1651
|
+
/**
|
|
1652
|
+
* Get a readable time string using device time when configured.
|
|
1653
|
+
* This method respects the useDeviceTimestamp configuration.
|
|
1654
|
+
* @param format - Optional format string
|
|
1655
|
+
* @returns A formatted time string
|
|
1656
|
+
*/
|
|
1657
|
+
private getTimeString;
|
|
1658
|
+
convertPlanToExecutable(plans: PlanningAction[], modelConfigForPlanning: IModelConfig, modelConfigForDefaultIntent: IModelConfig, options?: {
|
|
1659
|
+
cacheable?: boolean;
|
|
1660
|
+
deepLocate?: boolean;
|
|
1661
|
+
abortSignal?: AbortSignal;
|
|
1662
|
+
}): Promise<{
|
|
1663
|
+
tasks: ExecutionTaskApply[];
|
|
1664
|
+
}>;
|
|
1665
|
+
loadYamlFlowAsPlanning(userInstruction: string, yamlString: string): Promise<{
|
|
1666
|
+
runner: TaskRunner;
|
|
1667
|
+
}>;
|
|
1668
|
+
runPlans(title: string, plans: PlanningAction[], modelConfigForPlanning: IModelConfig, modelConfigForDefaultIntent: IModelConfig): Promise<ExecutionResult>;
|
|
1669
|
+
action(userPrompt: string, modelConfigForPlanning: IModelConfig, modelConfigForDefaultIntent: IModelConfig, includeBboxInPlanning: boolean, aiActContext?: string, cacheable?: boolean, replanningCycleLimitOverride?: number, imagesIncludeCount?: number, deepThink?: DeepThinkOption, fileChooserAccept?: string[], deepLocate?: boolean, abortSignal?: AbortSignal): Promise<ExecutionResult<{
|
|
1670
|
+
yamlFlow?: MidsceneYamlFlowItem[];
|
|
1671
|
+
output?: string;
|
|
1672
|
+
} | undefined>>;
|
|
1673
|
+
private runAction;
|
|
1674
|
+
private createTypeQueryTask;
|
|
1675
|
+
createTypeQueryExecution<T>(type: 'Query' | 'Boolean' | 'Number' | 'String' | 'Assert', demand: ServiceExtractParam, modelConfig: IModelConfig, opt?: ServiceExtractOption, multimodalPrompt?: TMultimodalPrompt): Promise<ExecutionResult<T>>;
|
|
1676
|
+
waitFor(assertion: TUserPrompt, opt: PlanningActionParamWaitFor, modelConfig: IModelConfig): Promise<ExecutionResult<void>>;
|
|
1677
|
+
}
|
|
1678
|
+
|
|
1679
|
+
declare interface TaskExecutorHooks {
|
|
1680
|
+
onTaskUpdate?: (runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void;
|
|
1681
|
+
}
|
|
1682
|
+
|
|
1683
|
+
declare class TaskRunner {
|
|
1684
|
+
readonly id: string;
|
|
1685
|
+
name: string;
|
|
1686
|
+
tasks: ExecutionTask[];
|
|
1687
|
+
status: 'init' | 'pending' | 'running' | 'completed' | 'error';
|
|
1688
|
+
onTaskStart?: ExecutionTaskProgressOptions['onTaskStart'];
|
|
1689
|
+
private readonly uiContextBuilder;
|
|
1690
|
+
private readonly onTaskUpdate?;
|
|
1691
|
+
private readonly executionLogTime;
|
|
1692
|
+
constructor(name: string, uiContextBuilder: () => Promise<UIContext>, options?: TaskRunnerInitOptions);
|
|
1693
|
+
private emitOnTaskUpdate;
|
|
1694
|
+
private lastUiContext?;
|
|
1695
|
+
private getUiContext;
|
|
1696
|
+
private captureScreenshot;
|
|
1697
|
+
private attachRecorderItem;
|
|
1698
|
+
private markTaskAsPending;
|
|
1699
|
+
private normalizeStatusFromError;
|
|
1700
|
+
append(task: ExecutionTaskApply[] | ExecutionTaskApply, options?: TaskRunnerOperationOptions): Promise<void>;
|
|
1701
|
+
appendAndFlush(task: ExecutionTaskApply[] | ExecutionTaskApply, options?: TaskRunnerOperationOptions): Promise<{
|
|
1702
|
+
output: any;
|
|
1703
|
+
thought?: string;
|
|
1704
|
+
} | undefined>;
|
|
1705
|
+
flush(options?: TaskRunnerOperationOptions): Promise<{
|
|
1706
|
+
output: any;
|
|
1707
|
+
thought?: string;
|
|
1708
|
+
} | undefined>;
|
|
1709
|
+
isInErrorState(): boolean;
|
|
1710
|
+
latestErrorTask(): ExecutionTask | null;
|
|
1711
|
+
dump(): ExecutionDump;
|
|
1712
|
+
appendErrorPlan(errorMsg: string): Promise<{
|
|
1713
|
+
output: undefined;
|
|
1714
|
+
runner: TaskRunner;
|
|
1715
|
+
}>;
|
|
1716
|
+
}
|
|
1717
|
+
|
|
1718
|
+
declare type TaskRunnerInitOptions = ExecutionTaskProgressOptions & {
|
|
1719
|
+
tasks?: ExecutionTaskApply[];
|
|
1720
|
+
onTaskUpdate?: (runner: TaskRunner, error?: TaskExecutionError) => Promise<void> | void;
|
|
1721
|
+
};
|
|
1722
|
+
|
|
1723
|
+
declare type TaskRunnerOperationOptions = {
|
|
1724
|
+
allowWhenError?: boolean;
|
|
1725
|
+
};
|
|
1726
|
+
|
|
1727
|
+
declare type TMultimodalPrompt = z.infer<typeof TMultimodalPromptSchema>;
|
|
1728
|
+
|
|
1729
|
+
declare const TMultimodalPromptSchema: z.ZodObject<{
|
|
1730
|
+
images: z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1731
|
+
name: z.ZodString;
|
|
1732
|
+
url: z.ZodString;
|
|
1733
|
+
}, "strip", z.ZodTypeAny, {
|
|
1734
|
+
name: string;
|
|
1735
|
+
url: string;
|
|
1736
|
+
}, {
|
|
1737
|
+
name: string;
|
|
1738
|
+
url: string;
|
|
1739
|
+
}>, "many">>;
|
|
1740
|
+
convertHttpImage2Base64: z.ZodOptional<z.ZodBoolean>;
|
|
1741
|
+
}, "strip", z.ZodTypeAny, {
|
|
1742
|
+
images?: {
|
|
1743
|
+
name: string;
|
|
1744
|
+
url: string;
|
|
1745
|
+
}[] | undefined;
|
|
1746
|
+
convertHttpImage2Base64?: boolean | undefined;
|
|
1747
|
+
}, {
|
|
1748
|
+
images?: {
|
|
1749
|
+
name: string;
|
|
1750
|
+
url: string;
|
|
1751
|
+
}[] | undefined;
|
|
1752
|
+
convertHttpImage2Base64?: boolean | undefined;
|
|
1753
|
+
}>;
|
|
1754
|
+
|
|
1755
|
+
/**
|
|
1756
|
+
* Tool definition for MCP server
|
|
1757
|
+
*/
|
|
1758
|
+
declare interface ToolDefinition<T = Record<string, unknown>> {
|
|
1759
|
+
name: string;
|
|
1760
|
+
description: string;
|
|
1761
|
+
schema: ToolSchema;
|
|
1762
|
+
handler: ToolHandler<T>;
|
|
1763
|
+
}
|
|
1764
|
+
|
|
1765
|
+
/**
|
|
1766
|
+
* Tool handler function type
|
|
1767
|
+
* Takes parsed arguments and returns a tool result
|
|
1768
|
+
*/
|
|
1769
|
+
declare type ToolHandler<T = Record<string, unknown>> = (args: T) => Promise<ToolResult>;
|
|
1770
|
+
|
|
1771
|
+
/**
|
|
1772
|
+
* Result type for tool execution (MCP compatible)
|
|
1773
|
+
*/
|
|
1774
|
+
declare interface ToolResult {
|
|
1775
|
+
[x: string]: unknown;
|
|
1776
|
+
content: ToolResultContent[];
|
|
1777
|
+
isError?: boolean;
|
|
1778
|
+
_meta?: Record<string, unknown>;
|
|
1779
|
+
}
|
|
1780
|
+
|
|
1781
|
+
/**
|
|
1782
|
+
* Content item types for tool results (MCP compatible)
|
|
1783
|
+
*/
|
|
1784
|
+
declare type ToolResultContent = {
|
|
1785
|
+
type: 'text';
|
|
1786
|
+
text: string;
|
|
1787
|
+
} | {
|
|
1788
|
+
type: 'image';
|
|
1789
|
+
data: string;
|
|
1790
|
+
mimeType: string;
|
|
1791
|
+
} | {
|
|
1792
|
+
type: 'audio';
|
|
1793
|
+
data: string;
|
|
1794
|
+
mimeType: string;
|
|
1795
|
+
} | {
|
|
1796
|
+
type: 'resource';
|
|
1797
|
+
resource: {
|
|
1798
|
+
text: string;
|
|
1799
|
+
uri: string;
|
|
1800
|
+
mimeType?: string;
|
|
1801
|
+
} | {
|
|
1802
|
+
uri: string;
|
|
1803
|
+
blob: string;
|
|
1804
|
+
mimeType?: string;
|
|
1805
|
+
};
|
|
1806
|
+
};
|
|
1807
|
+
|
|
1808
|
+
/**
|
|
1809
|
+
* Tool schema type using Zod
|
|
1810
|
+
*/
|
|
1811
|
+
declare type ToolSchema = Record<string, z.ZodTypeAny>;
|
|
1812
|
+
|
|
1813
|
+
declare type TUserPrompt = z.infer<typeof TUserPromptSchema>;
|
|
1814
|
+
|
|
1815
|
+
declare const TUserPromptSchema: z.ZodUnion<[z.ZodString, z.ZodIntersection<z.ZodObject<{
|
|
1816
|
+
prompt: z.ZodString;
|
|
1817
|
+
}, "strip", z.ZodTypeAny, {
|
|
1818
|
+
prompt: string;
|
|
1819
|
+
}, {
|
|
1820
|
+
prompt: string;
|
|
1821
|
+
}>, z.ZodObject<{
|
|
1822
|
+
images: z.ZodOptional<z.ZodOptional<z.ZodArray<z.ZodObject<{
|
|
1823
|
+
name: z.ZodString;
|
|
1824
|
+
url: z.ZodString;
|
|
1825
|
+
}, "strip", z.ZodTypeAny, {
|
|
1826
|
+
name: string;
|
|
1827
|
+
url: string;
|
|
1828
|
+
}, {
|
|
1829
|
+
name: string;
|
|
1830
|
+
url: string;
|
|
1831
|
+
}>, "many">>>;
|
|
1832
|
+
convertHttpImage2Base64: z.ZodOptional<z.ZodOptional<z.ZodBoolean>>;
|
|
1833
|
+
}, "strip", z.ZodTypeAny, {
|
|
1834
|
+
images?: {
|
|
1835
|
+
name: string;
|
|
1836
|
+
url: string;
|
|
1837
|
+
}[] | undefined;
|
|
1838
|
+
convertHttpImage2Base64?: boolean | undefined;
|
|
1839
|
+
}, {
|
|
1840
|
+
images?: {
|
|
1841
|
+
name: string;
|
|
1842
|
+
url: string;
|
|
1843
|
+
}[] | undefined;
|
|
1844
|
+
convertHttpImage2Base64?: boolean | undefined;
|
|
1845
|
+
}>>]>;
|
|
1846
|
+
|
|
1847
|
+
/**
|
|
1848
|
+
* context
|
|
1849
|
+
*/
|
|
1850
|
+
declare abstract class UIContext {
|
|
1851
|
+
/**
|
|
1852
|
+
* screenshot of the current UI state. which size is shotSize(be shrunk by screenshotShrinkFactor),
|
|
1853
|
+
*/
|
|
1854
|
+
abstract screenshot: ScreenshotItem;
|
|
1855
|
+
/**
|
|
1856
|
+
* screenshot size after shrinking
|
|
1857
|
+
*/
|
|
1858
|
+
abstract shotSize: Size;
|
|
1859
|
+
/**
|
|
1860
|
+
* The ratio for converting shrunk screenshot coordinates to logical coordinates.
|
|
1861
|
+
*
|
|
1862
|
+
* Example:
|
|
1863
|
+
* - Physical screen width: 3000px, dpr=6
|
|
1864
|
+
* - Logical width: 500px
|
|
1865
|
+
* - User-defined screenshotShrinkFactor: 2
|
|
1866
|
+
* - Actual shrunk screenshot width: 3000 / 2 = 1500px
|
|
1867
|
+
* - shrunkShotToLogicalRatio: dpr / screenshotShrinkFactor = 6 / 2 = 3
|
|
1868
|
+
* - To map back to logical coordinates: 1500 / shrunkShotToLogicalRatio = 500px
|
|
1869
|
+
*/
|
|
1870
|
+
abstract shrunkShotToLogicalRatio: number;
|
|
1871
|
+
abstract _isFrozen?: boolean;
|
|
1872
|
+
abstract deprecatedDpr?: number;
|
|
1873
|
+
}
|
|
1874
|
+
|
|
443
1875
|
/**
|
|
444
1876
|
* Helper type to convert DeviceAction to wrapped method signature
|
|
445
1877
|
*/
|