@opentiny/next-sdk 0.3.3 → 0.4.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.
Files changed (134) hide show
  1. package/agent/AgentModelProvider.ts +78 -81
  2. package/agent/type.ts +6 -9
  3. package/agent/utils/getAISDKTools.ts +0 -1
  4. package/agent/utils/getBuiltinMcpTools.ts +7 -7
  5. package/core.ts +1 -3
  6. package/dist/SimulatorMask-BHVXyogh-iNUb4dyF.js +361 -0
  7. package/dist/agent/type.d.ts +4 -12
  8. package/dist/agent/utils/getBuiltinMcpTools.d.ts +3 -3
  9. package/dist/core.d.ts +1 -1
  10. package/dist/core.js +18 -18
  11. package/dist/index-CXK8CcKq.js +6076 -0
  12. package/dist/index.d.ts +2 -4
  13. package/dist/index.js +57 -2783
  14. package/dist/initialize-builtin-WebMCP-rALfqS-o.js +6389 -0
  15. package/dist/page-tools/a11y/build.d.ts +11 -0
  16. package/dist/page-tools/a11y/constants.d.ts +9 -0
  17. package/dist/page-tools/a11y/search.d.ts +17 -0
  18. package/dist/page-tools/a11y/types.d.ts +104 -0
  19. package/dist/page-tools/a11y/utils.d.ts +34 -0
  20. package/dist/page-tools/a11y/vnode.d.ts +37 -0
  21. package/dist/page-tools/a11y-tree.d.ts +12 -0
  22. package/dist/page-tools/bridge.d.ts +0 -6
  23. package/dist/page-tools/constants.d.ts +22 -0
  24. package/dist/page-tools/context.d.ts +28 -0
  25. package/dist/page-tools/handlers/browserState.d.ts +8 -0
  26. package/dist/page-tools/handlers/click.d.ts +8 -0
  27. package/dist/page-tools/handlers/executeJavascript.d.ts +8 -0
  28. package/dist/page-tools/handlers/fill.d.ts +8 -0
  29. package/dist/page-tools/handlers/scroll.d.ts +8 -0
  30. package/dist/page-tools/handlers/searchTree.d.ts +8 -0
  31. package/dist/page-tools/handlers/select.d.ts +8 -0
  32. package/dist/page-tools/initialize-builtin-WebMCP.d.ts +1 -0
  33. package/dist/page-tools/page-agent-highlight/index.d.ts +9 -0
  34. package/dist/page-tools/page-agent-mask/SimulatorMask.d.ts +14 -0
  35. package/dist/page-tools/page-agent-mask/checkDarkMode.d.ts +5 -0
  36. package/dist/page-tools/page-agent-tool.d.ts +4 -0
  37. package/dist/page-tools/page-state-cache.d.ts +36 -0
  38. package/dist/page-tools/schema.d.ts +43 -0
  39. package/dist/page-tools/utils/dom.d.ts +6 -0
  40. package/dist/page-tools/utils/scroll.d.ts +15 -0
  41. package/dist/runtime.d.ts +4 -0
  42. package/dist/runtime.js +744 -0
  43. package/dist/utils/builtinProxy.d.ts +1 -1
  44. package/index.ts +2 -19
  45. package/package.json +14 -18
  46. package/page-tools/a11y/build.ts +70 -0
  47. package/page-tools/a11y/constants.ts +110 -0
  48. package/page-tools/a11y/search.ts +129 -0
  49. package/page-tools/a11y/types.ts +108 -0
  50. package/page-tools/a11y/utils.ts +266 -0
  51. package/page-tools/a11y/vnode.ts +229 -0
  52. package/page-tools/a11y-tree.ts +13 -0
  53. package/page-tools/bridge.ts +49 -15
  54. package/page-tools/constants.ts +72 -0
  55. package/page-tools/context.ts +13 -0
  56. package/page-tools/handlers/browserState.ts +12 -0
  57. package/page-tools/handlers/click.ts +26 -0
  58. package/page-tools/handlers/executeJavascript.ts +22 -0
  59. package/page-tools/handlers/fill.ts +60 -0
  60. package/page-tools/handlers/scroll.ts +66 -0
  61. package/page-tools/handlers/searchTree.ts +30 -0
  62. package/page-tools/handlers/select.ts +34 -0
  63. package/page-tools/initialize-builtin-WebMCP.ts +20 -0
  64. package/page-tools/page-agent-highlight/index.ts +198 -0
  65. package/page-tools/page-agent-mask/SimulatorMask.module.css +14 -0
  66. package/page-tools/page-agent-mask/SimulatorMask.ts +279 -0
  67. package/page-tools/page-agent-mask/checkDarkMode.ts +181 -0
  68. package/page-tools/page-agent-mask/cursor-border.svg +3 -0
  69. package/page-tools/page-agent-mask/cursor-fill.svg +5 -0
  70. package/page-tools/page-agent-mask/cursor.module.css +70 -0
  71. package/page-tools/page-agent-prompt.md +139 -0
  72. package/page-tools/page-agent-tool.ts +175 -0
  73. package/page-tools/page-state-cache.ts +78 -0
  74. package/page-tools/schema.ts +51 -0
  75. package/page-tools/utils/dom.ts +155 -0
  76. package/page-tools/utils/scroll.ts +58 -0
  77. package/runtime.ts +13 -0
  78. package/utils/builtinProxy.ts +45 -13
  79. package/vite.config.runtime.ts +22 -0
  80. package/vite.config.ts +52 -8
  81. package/McpSdk.ts +0 -14
  82. package/WebAgent.ts +0 -5
  83. package/WebMcp.ts +0 -20
  84. package/Zod.ts +0 -1
  85. package/dist/AgentModelProvider-CwqOT28f.js +0 -4198
  86. package/dist/McpSdk.d.ts +0 -14
  87. package/dist/WebAgent.d.ts +0 -5
  88. package/dist/WebMcp.d.ts +0 -20
  89. package/dist/Zod.d.ts +0 -1
  90. package/dist/index.es.dev.js +0 -53427
  91. package/dist/index.es.js +0 -42147
  92. package/dist/index.umd.dev.js +0 -53820
  93. package/dist/index.umd.js +0 -814
  94. package/dist/mcpsdk@1.25.3.dev.js +0 -22621
  95. package/dist/mcpsdk@1.25.3.es.dev.js +0 -22619
  96. package/dist/mcpsdk@1.25.3.es.js +0 -16802
  97. package/dist/mcpsdk@1.25.3.js +0 -43
  98. package/dist/transport/ExtensionClientTransport.d.ts +0 -24
  99. package/dist/transport/ExtensionContentServerTransport.d.ts +0 -39
  100. package/dist/transport/ExtensionPageServerTransport.d.ts +0 -36
  101. package/dist/transport/messages.d.ts +0 -9
  102. package/dist/vite.config.mcpSdk.d.ts +0 -2
  103. package/dist/vite.config.webAgent.d.ts +0 -2
  104. package/dist/vite.config.webMcp.d.ts +0 -2
  105. package/dist/vite.config.webMcpFull.d.ts +0 -2
  106. package/dist/vite.config.zod.d.ts +0 -2
  107. package/dist/webagent.dev.js +0 -47597
  108. package/dist/webagent.es.dev.js +0 -47204
  109. package/dist/webagent.es.js +0 -37494
  110. package/dist/webagent.js +0 -634
  111. package/dist/webmcp-full.dev.js +0 -24430
  112. package/dist/webmcp-full.es.dev.js +0 -24426
  113. package/dist/webmcp-full.es.js +0 -18333
  114. package/dist/webmcp-full.js +0 -43
  115. package/dist/webmcp.dev.js +0 -1595
  116. package/dist/webmcp.es.dev.js +0 -1589
  117. package/dist/webmcp.es.js +0 -1406
  118. package/dist/webmcp.js +0 -1
  119. package/dist/zod@3.25.76.dev.js +0 -4037
  120. package/dist/zod@3.25.76.es.dev.js +0 -4033
  121. package/dist/zod@3.25.76.es.js +0 -2945
  122. package/dist/zod@3.25.76.js +0 -1
  123. package/transport/ExtensionClientTransport.ts +0 -100
  124. package/transport/ExtensionContentServerTransport.ts +0 -162
  125. package/transport/ExtensionPageServerTransport.ts +0 -149
  126. package/transport/messages.ts +0 -63
  127. package/vite-build-tsc.ts +0 -63
  128. package/vite-env.d.ts +0 -5
  129. package/vite.config.mcpSdk.ts +0 -28
  130. package/vite.config.webAgent.ts +0 -19
  131. package/vite.config.webMcp.ts +0 -40
  132. package/vite.config.webMcpFull.ts +0 -19
  133. package/vite.config.zod.ts +0 -23
  134. /package/dist/{vite-build-tsc.d.ts → vite.config.runtime.d.ts} +0 -0
@@ -9,10 +9,9 @@ import { ProviderV2 } from '@ai-sdk/provider'
9
9
  import { OpenAIProvider } from '@ai-sdk/openai'
10
10
  import { createOpenAI } from '@ai-sdk/openai'
11
11
  import { createDeepSeek, DeepSeekProvider } from '@ai-sdk/deepseek'
12
- import { ExtensionClientTransport } from '../transport/ExtensionClientTransport'
13
12
  import { MessageChannelTransport } from '@opentiny/next'
14
13
  import { WebMcpClient } from '../WebMcpClient'
15
- import { getAISDKTools } from './utils/getAISDKTools'
14
+ import { getAISDKTools } from './utils/getAISDKTools'
16
15
  import { getBuiltinMcpTools } from './utils/getBuiltinMcpTools'
17
16
  import { generateReActToolsPrompt } from './utils/generateReActPrompt'
18
17
  import { parseReActAction } from './utils/parseReActAction'
@@ -83,15 +82,15 @@ export class AgentModelProvider {
83
82
  private async _createOneClient(serverConfig: McpServerConfig) {
84
83
  try {
85
84
  let transport: MCPClientConfig['transport']
86
- // builtin 类型:使用 navigator.modelContextTesting 作为工具数据源
87
- if ('type' in serverConfig && serverConfig.type === 'builtin') {
88
- const builtinClient = serverConfig.client
89
- // 包装成与 ai-sdk MCPClient 相同接口:提供 tools() 方法
90
- return {
91
- tools: () => getBuiltinMcpTools(builtinClient),
92
- close: async () => {}
93
- }
94
- }
85
+ // builtin 类型:使用 document.modelContext 作为工具数据源
86
+ if ('type' in serverConfig && serverConfig.type === 'builtin') {
87
+ const builtinClient = serverConfig.client
88
+ // 包装成与 ai-sdk MCPClient 相同接口:提供 tools() 方法
89
+ return {
90
+ tools: () => getBuiltinMcpTools(builtinClient),
91
+ close: async () => {}
92
+ }
93
+ }
95
94
  // transport 一定是 streamableHttp/sse 或者就是: ai-sdk允许的 transport
96
95
  if ('type' in serverConfig && serverConfig.type.toLocaleLowerCase() === 'streamablehttp') {
97
96
  const configWithHeaders = serverConfig as { url: string; headers?: Record<string, string> }
@@ -101,8 +100,6 @@ export class AgentModelProvider {
101
100
  const configWithHeaders = serverConfig as { url: string; headers?: Record<string, string> }
102
101
  const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : undefined
103
102
  transport = new SSEClientTransport(new URL(configWithHeaders.url), { requestInit })
104
- } else if ('type' in serverConfig && serverConfig.type === 'extension') {
105
- transport = new ExtensionClientTransport(serverConfig.sessionId)
106
103
  } else if ('transport' in serverConfig) {
107
104
  transport = serverConfig.transport
108
105
  } else {
@@ -232,18 +229,18 @@ export class AgentModelProvider {
232
229
  )
233
230
  }
234
231
 
235
- /** 创建所有的 mcpClients,并更新它们的tools */
236
- async initClientsAndTools() {
237
- await this._createMpcClients()
238
- await this._createMpcTools()
239
- this.onUpdatedTools?.()
240
- }
241
-
242
- /** 仅刷新已连接 clients 的 tools(不重建 client,适合工具目录动态变化场景) */
243
- async refreshTools() {
244
- await this._createMpcTools()
245
- this.onUpdatedTools?.()
246
- }
232
+ /** 创建所有的 mcpClients,并更新它们的tools */
233
+ async initClientsAndTools() {
234
+ await this._createMpcClients()
235
+ await this._createMpcTools()
236
+ this.onUpdatedTools?.()
237
+ }
238
+
239
+ /** 仅刷新已连接 clients 的 tools(不重建 client,适合工具目录动态变化场景) */
240
+ async refreshTools() {
241
+ await this._createMpcTools()
242
+ this.onUpdatedTools?.()
243
+ }
247
244
 
248
245
  /** 全量更新所有的 mcpServers */
249
246
  async updateMcpServers(mcpServers?: Record<string, McpServerConfig>) {
@@ -307,7 +304,7 @@ export class AgentModelProvider {
307
304
  /** 创建临时允许调用的 tools 集合,合并 mcpTools 与 extraTool */
308
305
  private _tempMergeTools(extraTool: ToolSet = {} as ToolSet, deleteIgnored = true): ToolSet {
309
306
  const toolsResult: ToolSet = Object.values(this.mcpTools).reduce(
310
- (acc, curr) => ({ ...acc, ...curr } as ToolSet),
307
+ (acc, curr) => ({ ...acc, ...curr }) as ToolSet,
311
308
  {} as ToolSet
312
309
  )
313
310
  Object.assign(toolsResult, extraTool)
@@ -836,61 +833,61 @@ export class AgentModelProvider {
836
833
  }
837
834
 
838
835
  // 否则使用原有的 function calling 模式
839
- if (!this.llm) {
840
- throw new Error('LLM is not initialized')
841
- }
842
-
843
- await this.initClientsAndTools()
844
-
845
- const extraTools = (options.tools || {}) as ToolSet
846
- const allTools = this._tempMergeTools(extraTools, false)
847
-
848
- // 让 tools 保持“同一个对象引用”并在每个 step 前同步:
849
- // - prepareStep 只能控制 activeTools,不能直接返回 tools
850
- // - 因此需要在进入每个 step 前,把最新 mcpTools 合并回当前 tools 对象
851
- // - 这样 activeTools 新增的工具名在当步就能命中真实工具定义
852
- const syncToolsForStep = () => {
853
- const latestTools = this._tempMergeTools(extraTools, false)
854
-
855
- // upsert
856
- Object.entries(latestTools).forEach(([name, tool]) => {
857
- ;(allTools as any)[name] = tool
858
- })
859
-
860
- // remove stale
861
- Object.keys(allTools).forEach((name) => {
862
- if (!(name in latestTools)) {
863
- delete (allTools as any)[name]
864
- }
865
- })
866
- }
867
-
868
- const userPrepareStep = (options as any).prepareStep
869
- const wrappedPrepareStep = async (stepOptions: any) => {
870
- syncToolsForStep()
871
-
872
- const latestActiveTools = this._getActiveToolNames(allTools)
873
- const userStepPatch = typeof userPrepareStep === 'function' ? await userPrepareStep(stepOptions) : undefined
874
- const safeUserStepPatch =
875
- userStepPatch && typeof userStepPatch === 'object' ? userStepPatch : ({} as Record<string, any>)
876
-
877
- return {
878
- ...safeUserStepPatch,
879
- activeTools: Array.isArray(safeUserStepPatch.activeTools)
880
- ? safeUserStepPatch.activeTools.filter((name: string) => latestActiveTools.includes(name))
881
- : latestActiveTools
882
- }
883
- }
884
-
885
- const chatOptions = {
886
- // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
887
- model: this.llm(model),
888
- stopWhen: stepCountIs(maxSteps),
889
- ...options,
890
- tools: allTools,
891
- prepareStep: wrappedPrepareStep,
892
- activeTools: this._getActiveToolNames(allTools)
893
- }
836
+ if (!this.llm) {
837
+ throw new Error('LLM is not initialized')
838
+ }
839
+
840
+ await this.initClientsAndTools()
841
+
842
+ const extraTools = (options.tools || {}) as ToolSet
843
+ const allTools = this._tempMergeTools(extraTools, false)
844
+
845
+ // 让 tools 保持“同一个对象引用”并在每个 step 前同步:
846
+ // - prepareStep 只能控制 activeTools,不能直接返回 tools
847
+ // - 因此需要在进入每个 step 前,把最新 mcpTools 合并回当前 tools 对象
848
+ // - 这样 activeTools 新增的工具名在当步就能命中真实工具定义
849
+ const syncToolsForStep = () => {
850
+ const latestTools = this._tempMergeTools(extraTools, false)
851
+
852
+ // upsert
853
+ Object.entries(latestTools).forEach(([name, tool]) => {
854
+ ;(allTools as any)[name] = tool
855
+ })
856
+
857
+ // remove stale
858
+ Object.keys(allTools).forEach((name) => {
859
+ if (!(name in latestTools)) {
860
+ delete (allTools as any)[name]
861
+ }
862
+ })
863
+ }
864
+
865
+ const userPrepareStep = (options as any).prepareStep
866
+ const wrappedPrepareStep = async (stepOptions: any) => {
867
+ syncToolsForStep()
868
+
869
+ const latestActiveTools = this._getActiveToolNames(allTools)
870
+ const userStepPatch = typeof userPrepareStep === 'function' ? await userPrepareStep(stepOptions) : undefined
871
+ const safeUserStepPatch =
872
+ userStepPatch && typeof userStepPatch === 'object' ? userStepPatch : ({} as Record<string, any>)
873
+
874
+ return {
875
+ ...safeUserStepPatch,
876
+ activeTools: Array.isArray(safeUserStepPatch.activeTools)
877
+ ? safeUserStepPatch.activeTools.filter((name: string) => latestActiveTools.includes(name))
878
+ : latestActiveTools
879
+ }
880
+ }
881
+
882
+ const chatOptions = {
883
+ // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
884
+ model: this.llm(model),
885
+ stopWhen: stepCountIs(maxSteps),
886
+ ...options,
887
+ tools: allTools,
888
+ prepareStep: wrappedPrepareStep,
889
+ activeTools: this._getActiveToolNames(allTools)
890
+ }
894
891
 
895
892
  // 保存最后一条 user 消息,用于后续缓存
896
893
  let lastUserMessage: any = null
package/agent/type.ts CHANGED
@@ -5,12 +5,12 @@ import type { MCPClientConfig } from '@ai-sdk/mcp'
5
5
  export type MCPTransport = MCPClientConfig['transport']
6
6
 
7
7
  /**
8
- * 浏览器内置 WebMCP 测试 API 接口 (如 navigator.modelContextTesting)
8
+ * 浏览器内置 WebMCP 测试 API 接口 (如 document.modelContext)
9
9
  */
10
10
  export interface BuiltinMcpClient {
11
11
  listTools?: () => Promise<any[]>
12
12
  getTools?: () => Promise<any[]>
13
- executeTool: (name: string, input: string) => Promise<any>
13
+ executeTool: (tool: any, input: string) => Promise<any>
14
14
  registerTool?: (config: { name: string; execute: (input: any) => Promise<any> | any; [key: string]: any }) => void
15
15
  unregisterTool?: (name: string) => void
16
16
  }
@@ -63,23 +63,20 @@ export type McpServerConfig =
63
63
  description?: string
64
64
  }
65
65
  | {
66
- type: 'extension'
67
- url: string
68
- sessionId: string
66
+ type: 'local'
67
+ transport: MCPTransport
69
68
  useAISdkClient?: boolean
70
- headers?: Record<string, string>
71
69
  name?: string
72
70
  description?: string
73
71
  }
74
- | { type: 'local'; transport: MCPTransport; useAISdkClient?: boolean; name?: string; description?: string }
75
72
  | {
76
73
  /**
77
74
  * 浏览器内置 WebMCP 类型。
78
- * 将 `navigator.modelContextTesting` 作为 MCP 工具数据源,
75
+ * 将 `document.modelContext` 作为 MCP 工具数据源,
79
76
  * 通过 `getBuiltinMcpTools` 适配为 ai-sdk 可调用的 ToolSet。
80
77
  */
81
78
  type: 'builtin'
82
- /** 传入 `navigator.modelContextTesting` 对象 */
79
+ /** 传入 `document.modelContext` 对象 */
83
80
  client: BuiltinMcpClient
84
81
  name?: string
85
82
  description?: string
@@ -11,7 +11,6 @@ export const getAISDKTools = async (client: WebMcpClient): Promise<ToolSet> => {
11
11
 
12
12
  try {
13
13
  const listToolsResult = await client.listTools()
14
-
15
14
  for (const { name, description, inputSchema } of listToolsResult.tools) {
16
15
  const execute = async (args: any, options: ToolExecutionOptions): Promise<any> => {
17
16
  return client.callTool({ name, arguments: args }, { signal: options?.abortSignal })
@@ -1,7 +1,7 @@
1
1
  import { dynamicTool, jsonSchema, Tool, ToolSet } from 'ai'
2
2
 
3
3
  /**
4
- * 浏览器内置 WebMCP 测试 API 的工具描述格式(Chrome navigator.modelContextTesting
4
+ * 浏览器内置 WebMCP 测试 API 的工具描述格式(Chrome document.modelContext
5
5
  */
6
6
  type BuiltinToolDescriptor = {
7
7
  name: string
@@ -17,16 +17,16 @@ type BuiltinToolDescriptor = {
17
17
  type BuiltinModelContextTesting = {
18
18
  listTools?: () => Promise<BuiltinToolDescriptor[]>
19
19
  getTools?: () => Promise<BuiltinToolDescriptor[]>
20
- executeTool?: (name: string, input: string) => Promise<unknown>
20
+ executeTool?: (tool: { name: string }, input: string) => Promise<unknown>
21
21
  }
22
22
 
23
23
  /**
24
- * 将浏览器内置 WebMCP 的 `navigator.modelContext` 适配为 ai-sdk 的 ToolSet。
24
+ * 将浏览器内置 WebMCP 的 `document.modelContext` 适配为 ai-sdk 的 ToolSet。
25
25
  *
26
26
  * 类似 getAISDKTools,但数据源是浏览器原生 API 而非 MCP client。
27
- * 工具执行时通过 `executeTool(name, JSON.stringify(args))` 代理给浏览器。
27
+ * 工具执行时通过 `executeTool(toolObj, JSON.stringify(args))` 代理给浏览器。
28
28
  *
29
- * @param client - `navigator.modelContext` 对象
29
+ * @param client - `document.modelContext` 对象
30
30
  * @returns ai-sdk 格式的 ToolSet,可直接传入 streamText/generateText 的 tools 参数
31
31
  */
32
32
  export const getBuiltinMcpTools = async (client: object | undefined | null): Promise<ToolSet> => {
@@ -75,9 +75,9 @@ export const getBuiltinMcpTools = async (client: object | undefined | null): Pro
75
75
  inputSchema: jsonSchema(normalizedSchema as Parameters<typeof jsonSchema>[0]),
76
76
  async execute(args) {
77
77
  if (!testing.executeTool) {
78
- throw new Error(`navigator.modelContextTesting.executeTool is not available`)
78
+ throw new Error(`document.modelContext.executeTool is not available`)
79
79
  }
80
- return testing.executeTool(name, JSON.stringify(args ?? {}))
80
+ return testing.executeTool(descriptor, JSON.stringify(args ?? {}))
81
81
  }
82
82
  })
83
83
  }
package/core.ts CHANGED
@@ -20,9 +20,7 @@ export type * from '@modelcontextprotocol/sdk/server/mcp.js'
20
20
  export * from './WebMcpServer'
21
21
  export * from './WebMcpClient'
22
22
 
23
- // 浏览器扩展自定义传输层(不包含对 window 依赖的模块)
24
- export * from './transport/ExtensionClientTransport'
25
-
26
23
  export { AgentModelProvider } from './agent/AgentModelProvider'
27
24
  export { getAISDKTools } from './agent/utils/getAISDKTools'
28
25
  export type * from './agent/type'
26
+ export { initializeBuiltinWebMCP } from './page-tools/initialize-builtin-WebMCP'
@@ -0,0 +1,361 @@
1
+ import { M as u } from "./index-CXK8CcKq.js";
2
+ (function() {
3
+ try {
4
+ if (typeof document < "u") {
5
+ var t = document.createElement("style");
6
+ t.appendChild(document.createTextNode(`._wrapper_1ooyb_1 {
7
+ position: fixed;
8
+ inset: 0;
9
+ z-index: 2147483641; /* 确保在所有元素之上,除了 panel */
10
+ cursor: wait;
11
+ overflow: hidden;
12
+
13
+ display: none;
14
+ }
15
+
16
+ ._wrapper_1ooyb_1._visible_1ooyb_11 {
17
+ display: block;
18
+ }
19
+ /* AI 光标样式 */
20
+ ._cursor_1dgwb_2 {
21
+ position: absolute;
22
+ width: var(--cursor-size, 75px);
23
+ height: var(--cursor-size, 75px);
24
+ pointer-events: none;
25
+ z-index: 10000;
26
+ }
27
+
28
+ ._cursorBorder_1dgwb_10 {
29
+ position: absolute;
30
+ width: 100%;
31
+ height: 100%;
32
+ background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));
33
+ mask-image: url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%20fill='none'%3e%3cg%3e%3cpath%20d='M%2015%2042%20L%2015%2036.99%20Q%2015%2031.99%2023.7%2031.99%20L%2028.05%2031.99%20Q%2032.41%2031.99%2032.41%2021.99%20L%2032.41%2017%20Q%2032.41%2012%2041.09%2016.95%20L%2076.31%2037.05%20Q%2085%2042%2076.31%2046.95%20L%2041.09%2067.05%20Q%2032.41%2072%2032.41%2062.01%20L%2032.41%2057.01%20Q%2032.41%2052.01%2023.7%2052.01%20L%2019.35%2052.01%20Q%2015%2052.01%2015%2047.01%20Z'%20fill='none'%20stroke='%23000000'%20stroke-width='6'%20stroke-miterlimit='10'%20style='stroke:%20light-dark(rgb(0,%200,%200),%20rgb(255,%20255,%20255));'/%3e%3c/g%3e%3c/svg%3e");
34
+ mask-size: 100% 100%;
35
+ mask-repeat: no-repeat;
36
+
37
+ transform-origin: center;
38
+ transform: rotate(-135deg) scale(1.2);
39
+ margin-left: -10px;
40
+ margin-top: -18px;
41
+ }
42
+
43
+ ._cursorFilling_1dgwb_25 {
44
+ position: absolute;
45
+ width: 100%;
46
+ height: 100%;
47
+ background: url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3e%3cdefs%3e%3c/defs%3e%3cg%20xmlns='http://www.w3.org/2000/svg'%20style='filter:%20drop-shadow(light-dark(rgba(0,%200,%200,%200.4),%20rgba(237,%20237,%20237,%200.4))%203px%204px%204px);'%3e%3cpath%20d='M%2015%2042%20L%2015%2036.99%20Q%2015%2031.99%2023.7%2031.99%20L%2028.05%2031.99%20Q%2032.41%2031.99%2032.41%2021.99%20L%2032.41%2017%20Q%2032.41%2012%2041.09%2016.95%20L%2076.31%2037.05%20Q%2085%2042%2076.31%2046.95%20L%2041.09%2067.05%20Q%2032.41%2072%2032.41%2062.01%20L%2032.41%2057.01%20Q%2032.41%2052.01%2023.7%2052.01%20L%2019.35%2052.01%20Q%2015%2052.01%2015%2047.01%20Z'%20fill='%23ffffff'%20stroke='none'%20style='fill:%20%23ffffff;'/%3e%3c/g%3e%3c/svg%3e");
48
+ background-size: 100% 100%;
49
+ background-repeat: no-repeat;
50
+
51
+ transform-origin: center;
52
+ transform: rotate(-135deg) scale(1.2);
53
+ margin-left: -10px;
54
+ margin-top: -18px;
55
+ }
56
+
57
+ ._cursorRipple_1dgwb_39 {
58
+ position: absolute;
59
+ width: 100%;
60
+ height: 100%;
61
+ pointer-events: none;
62
+ margin-left: -50%;
63
+ margin-top: -50%;
64
+
65
+ &::after {
66
+ content: '';
67
+ opacity: 0;
68
+ position: absolute;
69
+ inset: 0;
70
+ border: 4px solid rgba(57, 182, 255, 1);
71
+ border-radius: 50%;
72
+ }
73
+ }
74
+
75
+ ._cursor_1dgwb_2._clicking_1dgwb_57 ._cursorRipple_1dgwb_39::after {
76
+ animation: _cursor-ripple_1dgwb_1 300ms ease-out forwards;
77
+ }
78
+
79
+ @keyframes _cursor-ripple_1dgwb_1 {
80
+ 0% {
81
+ transform: scale(0);
82
+ opacity: 1;
83
+ }
84
+ 100% {
85
+ transform: scale(2);
86
+ opacity: 0;
87
+ }
88
+ }`)), document.head.appendChild(t);
89
+ }
90
+ } catch (e) {
91
+ console.error("vite-plugin-css-injected-by-js", e);
92
+ }
93
+ })();
94
+ (function() {
95
+ try {
96
+ if (typeof document < "u") {
97
+ var t = document.createElement("style");
98
+ t.appendChild(document.createTextNode(`._wrapper_1ooyb_1 {
99
+ position: fixed;
100
+ inset: 0;
101
+ z-index: 2147483641; /* 确保在所有元素之上,除了 panel */
102
+ cursor: wait;
103
+ overflow: hidden;
104
+
105
+ display: none;
106
+ }
107
+
108
+ ._wrapper_1ooyb_1._visible_1ooyb_11 {
109
+ display: block;
110
+ }
111
+ /* AI 光标样式 */
112
+ ._cursor_1dgwb_2 {
113
+ position: absolute;
114
+ width: var(--cursor-size, 75px);
115
+ height: var(--cursor-size, 75px);
116
+ pointer-events: none;
117
+ z-index: 10000;
118
+ }
119
+
120
+ ._cursorBorder_1dgwb_10 {
121
+ position: absolute;
122
+ width: 100%;
123
+ height: 100%;
124
+ background: linear-gradient(45deg, rgb(57, 182, 255), rgb(189, 69, 251));
125
+ mask-image: url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%20fill='none'%3e%3cg%3e%3cpath%20d='M%2015%2042%20L%2015%2036.99%20Q%2015%2031.99%2023.7%2031.99%20L%2028.05%2031.99%20Q%2032.41%2031.99%2032.41%2021.99%20L%2032.41%2017%20Q%2032.41%2012%2041.09%2016.95%20L%2076.31%2037.05%20Q%2085%2042%2076.31%2046.95%20L%2041.09%2067.05%20Q%2032.41%2072%2032.41%2062.01%20L%2032.41%2057.01%20Q%2032.41%2052.01%2023.7%2052.01%20L%2019.35%2052.01%20Q%2015%2052.01%2015%2047.01%20Z'%20fill='none'%20stroke='%23000000'%20stroke-width='6'%20stroke-miterlimit='10'%20style='stroke:%20light-dark(rgb(0,%200,%200),%20rgb(255,%20255,%20255));'/%3e%3c/g%3e%3c/svg%3e");
126
+ mask-size: 100% 100%;
127
+ mask-repeat: no-repeat;
128
+
129
+ transform-origin: center;
130
+ transform: rotate(-135deg) scale(1.2);
131
+ margin-left: -10px;
132
+ margin-top: -18px;
133
+ }
134
+
135
+ ._cursorFilling_1dgwb_25 {
136
+ position: absolute;
137
+ width: 100%;
138
+ height: 100%;
139
+ background: url("data:image/svg+xml,%3csvg%20xmlns='http://www.w3.org/2000/svg'%20viewBox='0%200%20100%20100'%3e%3cdefs%3e%3c/defs%3e%3cg%20xmlns='http://www.w3.org/2000/svg'%20style='filter:%20drop-shadow(light-dark(rgba(0,%200,%200,%200.4),%20rgba(237,%20237,%20237,%200.4))%203px%204px%204px);'%3e%3cpath%20d='M%2015%2042%20L%2015%2036.99%20Q%2015%2031.99%2023.7%2031.99%20L%2028.05%2031.99%20Q%2032.41%2031.99%2032.41%2021.99%20L%2032.41%2017%20Q%2032.41%2012%2041.09%2016.95%20L%2076.31%2037.05%20Q%2085%2042%2076.31%2046.95%20L%2041.09%2067.05%20Q%2032.41%2072%2032.41%2062.01%20L%2032.41%2057.01%20Q%2032.41%2052.01%2023.7%2052.01%20L%2019.35%2052.01%20Q%2015%2052.01%2015%2047.01%20Z'%20fill='%23ffffff'%20stroke='none'%20style='fill:%20%23ffffff;'/%3e%3c/g%3e%3c/svg%3e");
140
+ background-size: 100% 100%;
141
+ background-repeat: no-repeat;
142
+
143
+ transform-origin: center;
144
+ transform: rotate(-135deg) scale(1.2);
145
+ margin-left: -10px;
146
+ margin-top: -18px;
147
+ }
148
+
149
+ ._cursorRipple_1dgwb_39 {
150
+ position: absolute;
151
+ width: 100%;
152
+ height: 100%;
153
+ pointer-events: none;
154
+ margin-left: -50%;
155
+ margin-top: -50%;
156
+
157
+ &::after {
158
+ content: '';
159
+ opacity: 0;
160
+ position: absolute;
161
+ inset: 0;
162
+ border: 4px solid rgba(57, 182, 255, 1);
163
+ border-radius: 50%;
164
+ }
165
+ }
166
+
167
+ ._cursor_1dgwb_2._clicking_1dgwb_57 ._cursorRipple_1dgwb_39::after {
168
+ animation: _cursor-ripple_1dgwb_1 300ms ease-out forwards;
169
+ }
170
+
171
+ @keyframes _cursor-ripple_1dgwb_1 {
172
+ 0% {
173
+ transform: scale(0);
174
+ opacity: 1;
175
+ }
176
+ 100% {
177
+ transform: scale(2);
178
+ opacity: 0;
179
+ }
180
+ }`)), document.head.appendChild(t);
181
+ }
182
+ } catch (e) {
183
+ console.error("vite-plugin-css-injected-by-js", e);
184
+ }
185
+ })();
186
+ function p() {
187
+ try {
188
+ return !!(g() || h() || m() || w() || b() || f());
189
+ } catch (t) {
190
+ return console.warn("Error determining if page is dark:", t), !1;
191
+ }
192
+ }
193
+ function g() {
194
+ const t = [
195
+ "dark",
196
+ "dark-mode",
197
+ "theme-dark",
198
+ "night",
199
+ "night-mode"
200
+ ], e = document.documentElement, r = document.body || document.documentElement;
201
+ for (const o of t) if (e.classList.contains(o) || r?.classList.contains(o)) return !0;
202
+ return !1;
203
+ }
204
+ function h() {
205
+ const t = document.documentElement, e = document.body || document.documentElement;
206
+ for (const r of [
207
+ "data-theme",
208
+ "data-color-mode",
209
+ "data-bs-theme",
210
+ "data-mui-color-scheme"
211
+ ]) {
212
+ const o = e?.getAttribute(r), n = t.getAttribute(r);
213
+ if (o?.toLowerCase() === "dark" || n?.toLowerCase() === "dark") return !0;
214
+ }
215
+ return !1;
216
+ }
217
+ function m() {
218
+ const t = document.querySelector('meta[name="color-scheme"]')?.content.toLowerCase();
219
+ if (t === "dark" || t === "only dark") return !0;
220
+ const e = window.getComputedStyle(document.documentElement).getPropertyValue("color-scheme").trim().toLowerCase();
221
+ return e === "dark" || e === "only dark";
222
+ }
223
+ function w() {
224
+ const t = window.getComputedStyle(document.documentElement), e = window.getComputedStyle(document.body || document.documentElement), r = t.backgroundColor, o = e.backgroundColor;
225
+ return d(o) ? !0 : o === "transparent" || o.startsWith("rgba(0, 0, 0, 0)") ? d(r) : !1;
226
+ }
227
+ function f() {
228
+ const e = c(window.getComputedStyle(document.body || document.documentElement).color);
229
+ return e !== null && e > 200;
230
+ }
231
+ function b() {
232
+ const { innerWidth: t, innerHeight: e } = window, r = t * e * 0.5;
233
+ for (const o of [
234
+ "#app",
235
+ "#root",
236
+ "#__next"
237
+ ]) {
238
+ const n = document.querySelector(o);
239
+ if (!n) continue;
240
+ const s = n.getBoundingClientRect();
241
+ if (!(s.width * s.height < r) && d(window.getComputedStyle(n).backgroundColor))
242
+ return !0;
243
+ }
244
+ return !1;
245
+ }
246
+ function _(t) {
247
+ const e = /rgba?\((\d+),\s*(\d+),\s*(\d+)/.exec(t);
248
+ return e ? {
249
+ r: parseInt(e[1]),
250
+ g: parseInt(e[2]),
251
+ b: parseInt(e[3])
252
+ } : null;
253
+ }
254
+ function c(t) {
255
+ if (!t || t === "transparent" || t.startsWith("rgba(0, 0, 0, 0)")) return null;
256
+ const e = _(t);
257
+ return e ? 0.299 * e.r + 0.587 * e.g + 0.114 * e.b : null;
258
+ }
259
+ function d(t, e = 128) {
260
+ const r = c(t);
261
+ return r !== null && r < e;
262
+ }
263
+ var a = {
264
+ wrapper: "_wrapper_1ooyb_1",
265
+ visible: "_visible_1ooyb_11"
266
+ }, i = {
267
+ cursor: "_cursor_1dgwb_2",
268
+ cursorBorder: "_cursorBorder_1dgwb_10",
269
+ cursorFilling: "_cursorFilling_1dgwb_25",
270
+ cursorRipple: "_cursorRipple_1dgwb_39",
271
+ clicking: "_clicking_1dgwb_57"
272
+ }, k = class extends EventTarget {
273
+ shown = !1;
274
+ wrapper = document.createElement("div");
275
+ motion = null;
276
+ #r = !1;
277
+ #e = document.createElement("div");
278
+ #t = 0;
279
+ #n = 0;
280
+ #o = 0;
281
+ #i = 0;
282
+ constructor() {
283
+ super(), this.wrapper.id = "page-agent-runtime_simulator-mask", this.wrapper.className = a.wrapper, this.wrapper.setAttribute("data-browser-use-ignore", "true"), this.wrapper.setAttribute("data-page-agent-ignore", "true");
284
+ try {
285
+ const n = new u({
286
+ mode: p() ? "dark" : "light",
287
+ styles: {
288
+ position: "absolute",
289
+ inset: "0"
290
+ }
291
+ });
292
+ this.motion = n, this.wrapper.appendChild(n.element), n.autoResize(this.wrapper);
293
+ } catch (n) {
294
+ console.warn("[SimulatorMask] Motion overlay unavailable:", n);
295
+ }
296
+ this.wrapper.addEventListener("click", (n) => {
297
+ n.stopPropagation(), n.preventDefault();
298
+ }), this.wrapper.addEventListener("mousedown", (n) => {
299
+ n.stopPropagation(), n.preventDefault();
300
+ }), this.wrapper.addEventListener("mouseup", (n) => {
301
+ n.stopPropagation(), n.preventDefault();
302
+ }), this.wrapper.addEventListener("mousemove", (n) => {
303
+ n.stopPropagation(), n.preventDefault();
304
+ }), this.wrapper.addEventListener("wheel", (n) => {
305
+ n.stopPropagation(), n.preventDefault();
306
+ }), this.wrapper.addEventListener("keydown", (n) => {
307
+ n.stopPropagation(), n.preventDefault();
308
+ }), this.wrapper.addEventListener("keyup", (n) => {
309
+ n.stopPropagation(), n.preventDefault();
310
+ }), this.#a(), document.body.appendChild(this.wrapper), this.#s();
311
+ const t = (n) => {
312
+ const { x: s, y: l } = n.detail;
313
+ this.setCursorPosition(s, l);
314
+ }, e = () => {
315
+ this.triggerClickAnimation();
316
+ }, r = () => {
317
+ this.wrapper.style.pointerEvents = "none";
318
+ }, o = () => {
319
+ this.wrapper.style.pointerEvents = "auto";
320
+ };
321
+ window.addEventListener("PageAgent::MovePointerTo", t), window.addEventListener("PageAgent::ClickPointer", e), window.addEventListener("PageAgent::EnablePassThrough", r), window.addEventListener("PageAgent::DisablePassThrough", o), this.addEventListener("dispose", () => {
322
+ window.removeEventListener("PageAgent::MovePointerTo", t), window.removeEventListener("PageAgent::ClickPointer", e), window.removeEventListener("PageAgent::EnablePassThrough", r), window.removeEventListener("PageAgent::DisablePassThrough", o);
323
+ });
324
+ }
325
+ #a() {
326
+ this.#e.className = i.cursor;
327
+ const t = document.createElement("div");
328
+ t.className = i.cursorRipple, this.#e.appendChild(t);
329
+ const e = document.createElement("div");
330
+ e.className = i.cursorFilling, this.#e.appendChild(e);
331
+ const r = document.createElement("div");
332
+ r.className = i.cursorBorder, this.#e.appendChild(r), this.wrapper.appendChild(this.#e);
333
+ }
334
+ #s() {
335
+ if (this.#r) return;
336
+ const t = this.#t + (this.#o - this.#t) * 0.2, e = this.#n + (this.#i - this.#n) * 0.2, r = Math.abs(t - this.#o);
337
+ r > 0 && (r < 2 ? this.#t = this.#o : this.#t = t, this.#e.style.left = `${this.#t}px`);
338
+ const o = Math.abs(e - this.#i);
339
+ o > 0 && (o < 2 ? this.#n = this.#i : this.#n = e, this.#e.style.top = `${this.#n}px`), requestAnimationFrame(() => this.#s());
340
+ }
341
+ setCursorPosition(t, e) {
342
+ this.#r || (this.#o = t, this.#i = e);
343
+ }
344
+ triggerClickAnimation() {
345
+ this.#r || (this.#e.classList.remove(i.clicking), this.#e.offsetHeight, this.#e.classList.add(i.clicking));
346
+ }
347
+ show() {
348
+ this.shown || this.#r || (this.shown = !0, this.motion?.start(), this.motion?.fadeIn(), this.wrapper.classList.add(a.visible), this.#t = window.innerWidth / 2, this.#n = window.innerHeight / 2, this.#o = this.#t, this.#i = this.#n, this.#e.style.left = `${this.#t}px`, this.#e.style.top = `${this.#n}px`);
349
+ }
350
+ hide() {
351
+ !this.shown || this.#r || (this.shown = !1, this.motion?.fadeOut(), this.motion?.pause(), this.#e.classList.remove(i.clicking), setTimeout(() => {
352
+ this.wrapper.classList.remove(a.visible);
353
+ }, 800));
354
+ }
355
+ dispose() {
356
+ this.#r = !0, this.motion?.dispose(), this.wrapper.remove(), this.dispatchEvent(new Event("dispose"));
357
+ }
358
+ };
359
+ export {
360
+ k as SimulatorMask
361
+ };