@aiscene/shared 1.6.0 → 3.0.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.
Files changed (99) hide show
  1. package/dist/es/cli/cli-runner.mjs +13 -1
  2. package/dist/es/constants/example-code.mjs +25 -21
  3. package/dist/es/env/parse-model-config.mjs +11 -1
  4. package/dist/es/env/types.mjs +1 -0
  5. package/dist/es/extractor/dom-util.mjs +9 -5
  6. package/dist/es/extractor/locator.mjs +6 -6
  7. package/dist/es/extractor/util.mjs +6 -6
  8. package/dist/es/img/canvas-fallback.mjs +1 -1
  9. package/dist/es/index.mjs +1 -3
  10. package/dist/es/logger.mjs +1 -7
  11. package/dist/es/mcp/base-server.mjs +1 -1
  12. package/dist/es/mcp/base-tools.mjs +2 -2
  13. package/dist/es/mcp/tool-generator.mjs +131 -57
  14. package/dist/es/node/fs.mjs +1 -1
  15. package/dist/es/us-keyboard-layout.mjs +1 -1
  16. package/dist/es/utils.mjs +4 -9
  17. package/dist/lib/baseDB.js +1 -1
  18. package/dist/lib/cli/cli-runner.js +14 -2
  19. package/dist/lib/cli/index.js +1 -1
  20. package/dist/lib/common.js +1 -1
  21. package/dist/lib/constants/example-code.js +26 -22
  22. package/dist/lib/constants/index.js +1 -1
  23. package/dist/lib/env/basic.js +1 -1
  24. package/dist/lib/env/constants.js +1 -1
  25. package/dist/lib/env/global-config-manager.js +1 -1
  26. package/dist/lib/env/helper.js +1 -1
  27. package/dist/lib/env/index.js +1 -1
  28. package/dist/lib/env/init-debug.js +1 -1
  29. package/dist/lib/env/model-config-manager.js +1 -1
  30. package/dist/lib/env/parse-model-config.js +12 -2
  31. package/dist/lib/env/types.js +2 -1
  32. package/dist/lib/env/utils.js +1 -1
  33. package/dist/lib/extractor/constants.js +1 -1
  34. package/dist/lib/extractor/dom-util.js +10 -6
  35. package/dist/lib/extractor/index.js +1 -1
  36. package/dist/lib/extractor/locator.js +7 -7
  37. package/dist/lib/extractor/tree.js +1 -1
  38. package/dist/lib/extractor/util.js +7 -7
  39. package/dist/lib/extractor/web-extractor.js +1 -1
  40. package/dist/lib/img/box-select.js +1 -1
  41. package/dist/lib/img/canvas-fallback.js +2 -2
  42. package/dist/lib/img/get-photon.js +1 -1
  43. package/dist/lib/img/get-sharp.js +1 -1
  44. package/dist/lib/img/index.js +1 -1
  45. package/dist/lib/img/info.js +1 -1
  46. package/dist/lib/img/transform.js +1 -1
  47. package/dist/lib/index.js +3 -14
  48. package/dist/lib/logger.js +1 -10
  49. package/dist/lib/mcp/base-server.js +3 -3
  50. package/dist/lib/mcp/base-tools.js +5 -5
  51. package/dist/lib/mcp/chrome-path.js +1 -1
  52. package/dist/lib/mcp/index.js +1 -1
  53. package/dist/lib/mcp/inject-report-html-plugin.js +1 -1
  54. package/dist/lib/mcp/launcher-helper.js +1 -1
  55. package/dist/lib/mcp/tool-generator.js +134 -60
  56. package/dist/lib/mcp/types.js +1 -1
  57. package/dist/lib/node/fs.js +2 -2
  58. package/dist/lib/node/index.js +1 -1
  59. package/dist/lib/node/port.js +1 -1
  60. package/dist/lib/polyfills/async-hooks.js +1 -1
  61. package/dist/lib/polyfills/index.js +1 -1
  62. package/dist/lib/types/index.js +1 -1
  63. package/dist/lib/us-keyboard-layout.js +2 -2
  64. package/dist/lib/utils.js +4 -12
  65. package/dist/lib/zod-schema-utils.js +1 -1
  66. package/dist/types/cli/cli-runner.d.ts +8 -0
  67. package/dist/types/cli/index.d.ts +1 -1
  68. package/dist/types/constants/example-code.d.ts +1 -1
  69. package/dist/types/env/types.d.ts +1 -1
  70. package/dist/types/extractor/dom-util.d.ts +5 -4
  71. package/dist/types/index.d.ts +0 -2
  72. package/dist/types/logger.d.ts +0 -1
  73. package/dist/types/mcp/launcher-helper.d.ts +1 -1
  74. package/dist/types/mcp/types.d.ts +1 -0
  75. package/dist/types/utils.d.ts +0 -3
  76. package/package.json +2 -2
  77. package/src/cli/cli-runner.ts +26 -1
  78. package/src/cli/index.ts +1 -1
  79. package/src/constants/example-code.ts +25 -21
  80. package/src/env/parse-model-config.ts +21 -1
  81. package/src/env/types.ts +2 -0
  82. package/src/extractor/dom-util.ts +10 -5
  83. package/src/img/canvas-fallback.ts +1 -1
  84. package/src/index.ts +0 -7
  85. package/src/logger.ts +0 -11
  86. package/src/mcp/base-server.ts +1 -1
  87. package/src/mcp/base-tools.ts +2 -2
  88. package/src/mcp/launcher-helper.ts +1 -1
  89. package/src/mcp/tool-generator.ts +218 -67
  90. package/src/mcp/types.ts +4 -0
  91. package/src/utils.ts +0 -17
  92. package/dist/es/build/copy-static.mjs +0 -31
  93. package/dist/es/build/rspack-config.mjs +0 -4
  94. package/dist/lib/build/copy-static.js +0 -79
  95. package/dist/lib/build/rspack-config.js +0 -38
  96. package/dist/types/build/copy-static.d.ts +0 -31
  97. package/dist/types/build/rspack-config.d.ts +0 -8
  98. package/src/build/copy-static.ts +0 -68
  99. package/src/build/rspack-config.ts +0 -12
@@ -128,7 +128,7 @@ export type TGlobalConfig = Record<TEnvKeys, string | undefined>;
128
128
  /**
129
129
  * valid Model family types
130
130
  */
131
- export type TModelFamily = 'qwen2.5-vl' | 'qwen3-vl' | 'qwen3.5' | 'doubao-vision' | 'doubao-seed' | 'gemini' | 'vlm-ui-tars' | 'vlm-ui-tars-doubao' | 'vlm-ui-tars-doubao-1.5' | 'glm-v' | 'auto-glm' | 'auto-glm-multilingual' | 'gpt-5';
131
+ export type TModelFamily = 'qwen2.5-vl' | 'qwen3-vl' | 'qwen3.5' | 'qwen3.6' | 'doubao-vision' | 'doubao-seed' | 'gemini' | 'vlm-ui-tars' | 'vlm-ui-tars-doubao' | 'vlm-ui-tars-doubao-1.5' | 'glm-v' | 'auto-glm' | 'auto-glm-multilingual' | 'gpt-5';
132
132
  export declare const MODEL_FAMILY_VALUES: TModelFamily[];
133
133
  export interface IModelConfigForInsight {
134
134
  [MIDSCENE_INSIGHT_MODEL_NAME]: string;
@@ -37,7 +37,8 @@ export declare function isContainerElement(node: globalThis.Node): node is globa
37
37
  export declare function generateElementByPoint(center: [number, number], description: string, edgeSize?: number): LocateResultElement;
38
38
  /**
39
39
  * Generate a LocateResultElement from a rect.
40
- * This function calculates the center point from the rect and expands the rect by edgeSize.
40
+ * This function calculates the center point from the rect and preserves the
41
+ * original rect as the returned element boundary.
41
42
  *
42
43
  * Note: The rect uses inclusive coordinates where:
43
44
  * - A rect from [left=10, top=10] with [width=1, height=1] covers exactly 1 pixel
@@ -45,12 +46,12 @@ export declare function generateElementByPoint(center: [number, number], descrip
45
46
  *
46
47
  * @param sourceRect - The source rect to generate element from (typically contains integer values)
47
48
  * @param description - Description of the element
48
- * @param edgeSize - Size to expand around the center point (default: 8)
49
- * @returns A LocateResultElement with rect, center (always integers), and description
49
+ * @param edgeSize - Deprecated, retained for backward compatibility
50
+ * @returns A LocateResultElement with the original rect, center (always integers), and description
50
51
  */
51
52
  export declare function generateElementByRect(sourceRect: {
52
53
  left: number;
53
54
  top: number;
54
55
  width: number;
55
56
  height: number;
56
- }, description: string, edgeSize?: number): LocateResultElement;
57
+ }, description: string, _edgeSize?: number): LocateResultElement;
@@ -1,4 +1,2 @@
1
- export { createCopyStaticPlugin, createPlaygroundCopyPlugin, } from './build/copy-static';
2
- export { commonIgnoreWarnings } from './build/rspack-config';
3
1
  declare const _default: {};
4
2
  export default _default;
@@ -3,4 +3,3 @@ export declare function getDebug(topic: string, options?: {
3
3
  console?: boolean;
4
4
  }): DebugFunction;
5
5
  export declare function enableDebug(topic: string): void;
6
- export declare function cleanupLogStreams(): void;
@@ -58,7 +58,7 @@ export interface MCPServerLauncherConfig<AgentType extends GenericAgent = Generi
58
58
  *
59
59
  * @example
60
60
  * ```typescript
61
- * import { createMCPServerLauncher } from '@midscene/shared/mcp';
61
+ * import { createMCPServerLauncher } from '@aiscene/shared/mcp';
62
62
  * import { Agent } from '@midscene/core/agent';
63
63
  * import { WebMidsceneTools } from './web-tools';
64
64
  * import { WebMCPServer } from './server';
@@ -83,6 +83,7 @@ export interface BaseAgent {
83
83
  page?: {
84
84
  screenshotBase64(): Promise<string>;
85
85
  };
86
+ callActionInActionSpace?: (actionName: string, params?: unknown) => Promise<unknown>;
86
87
  aiAction?: (description: string, params?: Record<string, unknown>) => Promise<unknown>;
87
88
  aiWaitFor?: (assertion: string, options: Record<string, unknown>) => Promise<unknown>;
88
89
  }
@@ -11,8 +11,6 @@ export declare function generateHashId(rect: any, content?: string): string;
11
11
  * @throws Error with the provided message if the condition is false
12
12
  */
13
13
  export declare function assert(condition: any, message?: string): asserts condition;
14
- type GlobalScope = typeof window | typeof globalThis | typeof self | undefined;
15
- export declare function getGlobalScope(): GlobalScope;
16
14
  export declare function setIsMcp(value: boolean): void;
17
15
  export declare function logMsg(...message: Parameters<typeof console.log>): void;
18
16
  export declare function repeat(times: number, fn: (index: number) => Promise<void>): Promise<void>;
@@ -34,4 +32,3 @@ export declare function normalizeForComparison(str: string): string;
34
32
  * User-provided mapping takes precedence over default mapping.
35
33
  */
36
34
  export declare function mergeAndNormalizeAppNameMapping(defaultMapping: Record<string, string>, userMapping?: Record<string, string>): Record<string, string>;
37
- export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiscene/shared",
3
- "version": "1.6.0",
3
+ "version": "3.0.0",
4
4
  "repository": "https://github.com/web-infra-dev/midscene",
5
5
  "homepage": "https://midscenejs.com/",
6
6
  "types": "./dist/types/index.d.ts",
@@ -99,7 +99,7 @@
99
99
  "sharp": "^0.34.3",
100
100
  "dotenv": "^16.4.5",
101
101
  "uuid": "11.1.0",
102
- "zod": "3.24.3"
102
+ "zod": "^3.25.1"
103
103
  },
104
104
  "devDependencies": {
105
105
  "@rslib/core": "^0.18.3",
@@ -15,12 +15,21 @@ const debug = getDebug('cli-runner');
15
15
  interface CLICommand {
16
16
  name: string;
17
17
  def: ToolDefinition;
18
+ hidden?: boolean;
19
+ }
20
+
21
+ export interface CLIExtraCommand {
22
+ name: string;
23
+ def: ToolDefinition;
24
+ aliases?: string[];
25
+ hidden?: boolean;
18
26
  }
19
27
 
20
28
  export interface CLIRunnerOptions {
21
29
  stripPrefix?: string;
22
30
  argv?: string[];
23
31
  version?: string;
32
+ extraCommands?: CLIExtraCommand[];
24
33
  }
25
34
 
26
35
  export class CLIError extends Error {
@@ -142,7 +151,7 @@ function printHelp(
142
151
  }
143
152
  console.log(`\nUsage: ${scriptName} <command> [options]\n`);
144
153
  console.log('Commands:');
145
- for (const { name, def } of commands) {
154
+ for (const { name, def } of commands.filter((command) => !command.hidden)) {
146
155
  console.log(` ${name.padEnd(30)} ${def.description}`);
147
156
  }
148
157
  console.log(` ${'version'.padEnd(30)} Show CLI version`);
@@ -169,6 +178,22 @@ export async function runToolsCLI(
169
178
  name: removePrefix(def.name, options?.stripPrefix).toLowerCase(),
170
179
  def,
171
180
  }));
181
+ if (options?.extraCommands?.length) {
182
+ commands.push(
183
+ ...options.extraCommands.flatMap((cmd) => [
184
+ {
185
+ name: cmd.name.toLowerCase(),
186
+ def: cmd.def,
187
+ hidden: cmd.hidden,
188
+ },
189
+ ...(cmd.aliases ?? []).map((alias) => ({
190
+ name: alias.toLowerCase(),
191
+ def: cmd.def,
192
+ hidden: true,
193
+ })),
194
+ ]),
195
+ );
196
+ }
172
197
  const cliVersion = options?.version;
173
198
 
174
199
  const [commandName, ...restArgs] = rawArgs;
package/src/cli/index.ts CHANGED
@@ -5,4 +5,4 @@ export {
5
5
  parseCliArgs,
6
6
  removePrefix,
7
7
  } from './cli-runner';
8
- export type { CLIRunnerOptions } from './cli-runner';
8
+ export type { CLIRunnerOptions, CLIExtraCommand } from './cli-runner';
@@ -81,6 +81,23 @@ test('ai shop', async ({
81
81
  `;
82
82
 
83
83
  export const YAML_EXAMPLE_CODE = `
84
+ CRITICAL - YAML Indentation Rules:
85
+ For actions with additional parameters (aiScroll, aiInput, aiKeyboardPress), the parameters must be SIBLING keys at the SAME indentation level as the action key, NOT nested children indented further.
86
+ CORRECT (parameters align with the action key):
87
+ - aiScroll:
88
+ direction: 'down'
89
+ scrollType: 'singleAction'
90
+ distance: 500
91
+ locate: "main content area"
92
+ - aiInput: 'text value'
93
+ locate: 'input field description'
94
+ WRONG (parameters are indented further than the action key, DO NOT do this):
95
+ - aiScroll:
96
+ direction: 'down'
97
+ scrollType: 'singleAction'
98
+ - aiInput: 'text value'
99
+ locate: 'input field description'
100
+
84
101
  1. Format:
85
102
 
86
103
  web:
@@ -92,13 +109,18 @@ tasks:
92
109
  - name: "descriptive task name"
93
110
  flow:
94
111
  - aiTap: "element description"
112
+ xpath: '/html/body/div[1]/button[1]'
95
113
  - aiInput: 'text value'
96
114
  locate: 'input field description'
115
+ xpath: '/html/body/div[1]/input[1]'
97
116
  - aiScroll:
98
- direction: down/up
99
- scrollType: scrollToBottom/scrollToTop/singleAction
117
+ direction: 'down'
118
+ scrollType: 'singleAction'
119
+ distance: 500
120
+ locate: "scrollable area description"
121
+ xpath: '/html/body/div[1]/main[1]'
100
122
  - aiAssert: "expected state"
101
- - sleep: milliseconds
123
+ - sleep: 1000
102
124
 
103
125
  2. Action Types:
104
126
  - aiTap: for clicks (natural language targeting)
@@ -107,24 +129,6 @@ tasks:
107
129
  - aiAssert: for validations
108
130
  - sleep: for delays (milliseconds)
109
131
 
110
- 3. Best Practices:
111
- - Group related actions into logical tasks
112
- - Use natural language descriptions
113
- - Add deepLocate: true for complex interactions
114
- - Keep task names concise but descriptive
115
-
116
- 4. CRITICAL - YAML Indentation Rules:
117
- - For actions with additional parameters (aiScroll, aiInput, aiKeyboardPress), the parameters must be SIBLING keys, NOT nested children
118
- - Parameters like direction, scrollType, locate must align with the action key, not indented further
119
- - CORRECT indentation example:
120
- - aiScroll:
121
- direction: down
122
- scrollType: singleAction
123
- - WRONG indentation (DO NOT do this):
124
- - aiScroll:
125
- direction: down
126
- scrollType: singleAction
127
-
128
132
 
129
133
 
130
134
  YAML type
@@ -136,6 +136,26 @@ const getModelDescription = (
136
136
  return '';
137
137
  };
138
138
 
139
+ const normalizeOpenaiExtraConfig = (
140
+ config: unknown,
141
+ ): Record<string, unknown> | undefined => {
142
+ if (!config || typeof config !== 'object' || Array.isArray(config)) {
143
+ return undefined;
144
+ }
145
+
146
+ const { defaultHeaders, extra_headers, extraHeaders, ...rest } =
147
+ config as Record<string, unknown>;
148
+
149
+ // Priority: defaultHeaders > extra_headers > extraHeaders
150
+ const headers = defaultHeaders ?? extra_headers ?? extraHeaders;
151
+
152
+ if (headers !== undefined) {
153
+ return { ...rest, defaultHeaders: headers };
154
+ }
155
+
156
+ return rest;
157
+ };
158
+
139
159
  /**
140
160
  * Parse OpenAI SDK config
141
161
  */
@@ -201,7 +221,7 @@ export const parseOpenaiSdkConfig = ({
201
221
  httpProxy,
202
222
  openaiBaseURL,
203
223
  openaiApiKey,
204
- openaiExtraConfig,
224
+ openaiExtraConfig: normalizeOpenaiExtraConfig(openaiExtraConfig),
205
225
  extraBody,
206
226
  modelFamily,
207
227
  uiTarsModelVersion,
package/src/env/types.ts CHANGED
@@ -293,6 +293,7 @@ export type TModelFamily =
293
293
  | 'qwen2.5-vl'
294
294
  | 'qwen3-vl'
295
295
  | 'qwen3.5'
296
+ | 'qwen3.6'
296
297
  | 'doubao-vision'
297
298
  | 'doubao-seed'
298
299
  | 'gemini'
@@ -311,6 +312,7 @@ export const MODEL_FAMILY_VALUES: TModelFamily[] = [
311
312
  'qwen2.5-vl',
312
313
  'qwen3-vl',
313
314
  'qwen3.5',
315
+ 'qwen3.6',
314
316
  'vlm-ui-tars',
315
317
  'vlm-ui-tars-doubao',
316
318
  'vlm-ui-tars-doubao-1.5',
@@ -181,7 +181,8 @@ export function generateElementByPoint(
181
181
 
182
182
  /**
183
183
  * Generate a LocateResultElement from a rect.
184
- * This function calculates the center point from the rect and expands the rect by edgeSize.
184
+ * This function calculates the center point from the rect and preserves the
185
+ * original rect as the returned element boundary.
185
186
  *
186
187
  * Note: The rect uses inclusive coordinates where:
187
188
  * - A rect from [left=10, top=10] with [width=1, height=1] covers exactly 1 pixel
@@ -189,13 +190,13 @@ export function generateElementByPoint(
189
190
  *
190
191
  * @param sourceRect - The source rect to generate element from (typically contains integer values)
191
192
  * @param description - Description of the element
192
- * @param edgeSize - Size to expand around the center point (default: 8)
193
- * @returns A LocateResultElement with rect, center (always integers), and description
193
+ * @param edgeSize - Deprecated, retained for backward compatibility
194
+ * @returns A LocateResultElement with the original rect, center (always integers), and description
194
195
  */
195
196
  export function generateElementByRect(
196
197
  sourceRect: { left: number; top: number; width: number; height: number },
197
198
  description: string,
198
- edgeSize = 8,
199
+ _edgeSize = 8,
199
200
  ): LocateResultElement {
200
201
  /**
201
202
  * Calculate center point from rect
@@ -222,5 +223,9 @@ export function generateElementByRect(
222
223
  const centerX = sourceRect.left + Math.floor((sourceRect.width - 1) / 2);
223
224
  const centerY = sourceRect.top + Math.floor((sourceRect.height - 1) / 2);
224
225
 
225
- return generateElementByPoint([centerX, centerY], description, edgeSize);
226
+ return {
227
+ rect: sourceRect,
228
+ center: [centerX, centerY],
229
+ description: description || '',
230
+ };
226
231
  }
@@ -99,7 +99,7 @@ export class CanvasImage {
99
99
  */
100
100
  static async new_from_byteslice(bytes: Uint8Array): Promise<CanvasImage> {
101
101
  return new Promise((resolve, reject) => {
102
- const blob = new Blob([bytes], { type: 'image/png' });
102
+ const blob = new Blob([bytes.buffer as ArrayBuffer], { type: 'image/png' });
103
103
  const url = URL.createObjectURL(blob);
104
104
  const img = new Image();
105
105
 
package/src/index.ts CHANGED
@@ -1,8 +1 @@
1
- export {
2
- createCopyStaticPlugin,
3
- createPlaygroundCopyPlugin,
4
- } from './build/copy-static';
5
-
6
- export { commonIgnoreWarnings } from './build/rspack-config';
7
-
8
1
  export default {};
package/src/logger.ts CHANGED
@@ -94,14 +94,3 @@ export function enableDebug(topic: string): void {
94
94
  }
95
95
  debug.enable(`${topicPrefix}:${topic}`);
96
96
  }
97
-
98
- // Cleanup function to close all log streams
99
- export function cleanupLogStreams(): void {
100
- if (!ifInNode) return;
101
-
102
- for (const stream of logStreams.values()) {
103
- stream.end();
104
- }
105
- logStreams.clear();
106
- debugInstances.clear();
107
- }
@@ -1,6 +1,6 @@
1
1
  import { randomUUID } from 'node:crypto';
2
2
  import type { ParseArgsConfig } from 'node:util';
3
- import { setIsMcp } from '../utils';
3
+ import { setIsMcp } from '@aiscene/shared/utils';
4
4
  import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
5
5
  import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
6
6
  import { StreamableHTTPServerTransport } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
@@ -1,5 +1,5 @@
1
- import { parseBase64 } from '../img';
2
- import { getDebug } from '../logger';
1
+ import { parseBase64 } from '@aiscene/shared/img';
2
+ import { getDebug } from '@aiscene/shared/logger';
3
3
  import type { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
4
  import {
5
5
  generateCommonTools,
@@ -64,7 +64,7 @@ export interface MCPServerLauncherConfig<
64
64
  *
65
65
  * @example
66
66
  * ```typescript
67
- * import { createMCPServerLauncher } from '@midscene/shared/mcp';
67
+ * import { createMCPServerLauncher } from '@aiscene/shared/mcp';
68
68
  * import { Agent } from '@midscene/core/agent';
69
69
  * import { WebMidsceneTools } from './web-tools';
70
70
  * import { WebMCPServer } from './server';