@opentiny/next-sdk 0.4.2 → 0.4.3

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 (88) hide show
  1. package/dist/{SimulatorMask-BHVXyogh-CARX3Rff.js → SimulatorMask-BHVXyogh-CKmEDsYG.js} +1 -1
  2. package/dist/{index-R_HIbfUX.js → index-CHMa2zG4.js} +1065 -1042
  3. package/dist/index.js +1 -1
  4. package/dist/page-tools/a11y/config.d.ts +6 -3
  5. package/dist/page-tools/a11y/constants.d.ts +20 -0
  6. package/dist/page-tools/a11y/utils.d.ts +14 -0
  7. package/dist/page-tools/constants.d.ts +4 -2
  8. package/dist/page-tools/context.d.ts +2 -0
  9. package/dist/page-tools/handlers/hover.d.ts +9 -0
  10. package/dist/page-tools/schema.d.ts +3 -3
  11. package/dist/page-tools/utils/dom.d.ts +8 -2
  12. package/dist/runtime.js +19 -172
  13. package/package.json +6 -1
  14. package/WebMcpClient.ts +0 -505
  15. package/WebMcpServer.ts +0 -447
  16. package/agent/AgentModelProvider.ts +0 -932
  17. package/agent/type.ts +0 -91
  18. package/agent/utils/generateReActPrompt.ts +0 -71
  19. package/agent/utils/getAISDKTools.ts +0 -34
  20. package/agent/utils/getBuiltinMcpTools.ts +0 -86
  21. package/agent/utils/parseReActAction.ts +0 -34
  22. package/core.ts +0 -26
  23. package/index.ts +0 -91
  24. package/page-tools/a11y/build.ts +0 -74
  25. package/page-tools/a11y/config.ts +0 -465
  26. package/page-tools/a11y/constants.ts +0 -131
  27. package/page-tools/a11y/search.ts +0 -127
  28. package/page-tools/a11y/types.ts +0 -105
  29. package/page-tools/a11y/utils.ts +0 -239
  30. package/page-tools/a11y/vnode.ts +0 -439
  31. package/page-tools/a11y-tree.ts +0 -14
  32. package/page-tools/bridge.ts +0 -722
  33. package/page-tools/configs/console-cloud.ts +0 -172
  34. package/page-tools/constants.ts +0 -12
  35. package/page-tools/context.ts +0 -50
  36. package/page-tools/effects.ts +0 -345
  37. package/page-tools/handlers/browserState.ts +0 -12
  38. package/page-tools/handlers/click.ts +0 -30
  39. package/page-tools/handlers/executeJavascript.ts +0 -22
  40. package/page-tools/handlers/fill.ts +0 -65
  41. package/page-tools/handlers/scroll.ts +0 -66
  42. package/page-tools/handlers/searchTree.ts +0 -27
  43. package/page-tools/handlers/select.ts +0 -39
  44. package/page-tools/initialize-builtin-WebMCP.ts +0 -20
  45. package/page-tools/page-agent-highlight/index.ts +0 -245
  46. package/page-tools/page-agent-mask/SimulatorMask.module.css +0 -14
  47. package/page-tools/page-agent-mask/SimulatorMask.ts +0 -299
  48. package/page-tools/page-agent-mask/checkDarkMode.ts +0 -181
  49. package/page-tools/page-agent-mask/cursor-border.svg +0 -3
  50. package/page-tools/page-agent-mask/cursor-fill.svg +0 -5
  51. package/page-tools/page-agent-mask/cursor.module.css +0 -70
  52. package/page-tools/page-agent-mask/hauwei.svg +0 -25
  53. package/page-tools/page-agent-prompt.md +0 -139
  54. package/page-tools/page-agent-tool-event.ts +0 -113
  55. package/page-tools/page-agent-tool.ts +0 -207
  56. package/page-tools/page-state-cache.ts +0 -78
  57. package/page-tools/schema.ts +0 -52
  58. package/page-tools/tool-config.ts +0 -100
  59. package/page-tools/utils/dom.ts +0 -158
  60. package/page-tools/utils/scroll.ts +0 -58
  61. package/remoter/QrCode.ts +0 -54
  62. package/remoter/createRemoter.ts +0 -957
  63. package/remoter/svgs/chat.svg +0 -43
  64. package/remoter/svgs/icon-copy.svg +0 -25
  65. package/remoter/svgs/link.svg +0 -28
  66. package/remoter/svgs/logo.svg +0 -45
  67. package/remoter/svgs/qrcode.svg +0 -35
  68. package/remoter/svgs/scan.svg +0 -21
  69. package/remoter/tooltips.ts +0 -260
  70. package/runtime.html +0 -39
  71. package/runtime.ts +0 -44
  72. package/script/utils.ts +0 -26
  73. package/skills/index.ts +0 -287
  74. package/test/page-tools/a11y/build.test.ts +0 -638
  75. package/test/page-tools/a11y/config.test.ts +0 -370
  76. package/test/page-tools/configs/console-cloud.test.ts +0 -168
  77. package/test/page-tools/page-agent-highlight.test.ts +0 -110
  78. package/test/page-tools/page-agent-tool-dispatch.test.ts +0 -208
  79. package/test/page-tools/page-agent-tool.test.ts +0 -102
  80. package/test/page-tools/tool-config.test.ts +0 -112
  81. package/test/page-tools/utils/dom.test.ts +0 -122
  82. package/tsconfig.json +0 -16
  83. package/utils/builtinProxy.ts +0 -144
  84. package/utils/env.ts +0 -13
  85. package/utils/uuid.ts +0 -10
  86. package/vite.config.runtime.ts +0 -22
  87. package/vite.config.ts +0 -63
  88. package/vitest.config.ts +0 -10
package/skills/index.ts DELETED
@@ -1,287 +0,0 @@
1
- /**
2
- * Web 端 Skill 公共能力模块(next-sdk)
3
- * - 提供解析、概况、systemPrompt 拼接、按路径/名称查文档
4
- * - 提供 createSkillTools:供 remoter 注入 get_skill_content 工具,大模型可按需加载技能文档
5
- */
6
-
7
- import { tool } from 'ai'
8
- import { z } from 'zod'
9
-
10
- /** 主 SKILL.md 路径格式:仅匹配一级子目录下的 SKILL.md,如 ./calculator/SKILL.md */
11
- const MAIN_SKILL_PATH_REG = /^\.\/[^/]+\/SKILL\.md$/
12
-
13
- /** 从 front matter 中提取 name 和 description 的正则(--- 与 --- 之间) */
14
- const FRONT_MATTER_BLOCK_REG = /^---\s*\n([\s\S]+?)\s*\n---/
15
-
16
- /** 单个技能的概况信息(从主 SKILL.md 的 front matter 提取) */
17
- export interface SkillMeta {
18
- /** 技能名称,与 skill 目录名一致 */
19
- name: string
20
- /** 技能描述,用于 systemPrompt */
21
- description: string
22
- /** 主 SKILL.md 相对路径,如 ./calculator/SKILL.md */
23
- path: string
24
- }
25
-
26
- /**
27
- * 从主 SKILL.md 的 YAML front matter 中用正则提取 name、description
28
- */
29
- export async function parseSkillFrontMatter(
30
- content: string | (() => Promise<string>)
31
- ): Promise<{ name: string; description: string } | null> {
32
- if (typeof content !== 'string' && typeof content !== 'function') return null
33
-
34
- // 先提取 --- 之间的文本块
35
- const realContent = typeof content === 'string' ? content : await content()
36
- const blockMatch = realContent.match(FRONT_MATTER_BLOCK_REG)
37
-
38
- if (!blockMatch?.[1]) return null
39
- const block = blockMatch[1]
40
-
41
- // 分别匹配 name 和 description 字段(支持任意顺序)
42
- const nameMatch = block.match(/^name:\s*(.+)$/m)
43
- const descMatch = block.match(/^description:\s*(.+)$/m)
44
-
45
- const name = nameMatch?.[1]?.trim()
46
- const description = descMatch?.[1]?.trim()
47
-
48
- return name && description ? { name, description } : null
49
- }
50
-
51
- /**
52
- * 将 Vite import.meta.glob 得到的多种 key 格式统一为「相对 skills 根目录」的路径(如 ./calculator/SKILL.md),
53
- * 以便 getSkillMdContent / getMainSkillPathByName 等能正确按 path 查找。
54
- * 兼容任意引入位置:./skills/xxx、../skills/xxx、src/skills/xxx 等,取最后一个 skills/ 后的部分并加上 ./
55
- */
56
- async function normalizeSkillModuleKeys(
57
- modules: Record<string, string | (() => Promise<string>)>
58
- ): Promise<Record<string, string>> {
59
- const result: Record<string, string> = {}
60
- for (const [key, content] of Object.entries(modules)) {
61
- const normalizedKey = key.replace(/\\/g, '/')
62
- const skillsIndex = normalizedKey.lastIndexOf('skills/')
63
- const relativePath = skillsIndex >= 0 ? normalizedKey.slice(skillsIndex + 7) : normalizedKey
64
- const standardPath = relativePath.startsWith('./') ? relativePath : `./${relativePath}`
65
- const realContent = typeof content === 'string' ? content : await content()
66
- result[standardPath] = realContent
67
- }
68
- return result
69
- }
70
-
71
- /**
72
- * 获取所有「主 SKILL.md」的路径(一级子目录下的 SKILL.md)
73
- * - 对传入的 modules 先做 normalize,兼容任意 import.meta.glob 写法
74
- */
75
- export async function getMainSkillPaths(modules: Record<string, string | (() => Promise<string>)>): Promise<string[]> {
76
- const normalized = await normalizeSkillModuleKeys(modules)
77
- return Object.keys(normalized).filter((path) => MAIN_SKILL_PATH_REG.test(path))
78
- }
79
-
80
- /**
81
- * 获取所有技能的概况列表(name、description、path),用于 systemPrompt 或列表展示
82
- * - 内部统一对 modules 做 normalize,避免调用方关心路径细节
83
- */
84
- export async function getSkillOverviews(
85
- modules: Record<string, string | (() => Promise<string>)>
86
- ): Promise<SkillMeta[]> {
87
- const normalized = await normalizeSkillModuleKeys(modules)
88
- const mainPaths = Object.keys(normalized).filter((path) => MAIN_SKILL_PATH_REG.test(path))
89
- const list: SkillMeta[] = []
90
- for (const path of mainPaths) {
91
- const content = normalized[path]
92
- if (!content) continue
93
- const parsed = await parseSkillFrontMatter(content)
94
- if (!parsed) continue
95
- list.push({
96
- name: parsed.name,
97
- description: parsed.description,
98
- path
99
- })
100
- }
101
- return list
102
- }
103
-
104
- /**
105
- * 格式化为大模型 systemPrompt 可用的技能说明文本
106
- * @param skills 不传则需由调用方传入从 getSkillOverviews 得到的结果
107
- */
108
- export function formatSkillsForSystemPrompt(skills: SkillMeta[]): string {
109
- if (skills.length === 0) return ''
110
- const lines = skills.map((s) => `- **${s.name}**: ${s.description}`)
111
- return `## 可用技能\n\n${lines.join('\n')}\n\n当需要用到某技能时,请使用 get_skill_content 工具获取该技能的完整文档内容。`
112
- }
113
-
114
- /**
115
- * 根据相对路径获取某个技能文档的原始内容(支持 .md、.json、.xml 等文本格式)
116
- * - 自动对 modules 做 normalize,再按 path 查找
117
- */
118
- export async function getSkillMdContent(
119
- modules: Record<string, string | (() => Promise<string>)>,
120
- path: string
121
- ): Promise<string | undefined> {
122
- const normalized = await normalizeSkillModuleKeys(modules)
123
-
124
- // 1. 尝试原有的严格匹配
125
- const exactMatch = normalized[path]
126
- if (exactMatch) return exactMatch
127
-
128
- // 2. 降级匹配:如果严格匹配完整路径未找到
129
- // 则尝试寻找后缀能够匹配上的真实文件路径。
130
- // 去除开头的 '.' 或 './' 以精确匹配结尾部分的路径。
131
- const suffix = path.replace(/^\.?\//, '/')
132
- const matchingKey = Object.keys(normalized).find((key) => key.endsWith(suffix))
133
- return matchingKey ? normalized[matchingKey] : undefined
134
- }
135
-
136
- /**
137
- * 根据技能 name 查找其主 SKILL.md 的路径
138
- * 支持匹配目录名(如 ecommerce)或 SKILL.md 内 frontmatter 定义的 name
139
- * - 依赖 getMainSkillPaths,内部已做 normalize
140
- */
141
- export async function getMainSkillPathByName(
142
- modules: Record<string, string | (() => Promise<string>)>,
143
- name: string
144
- ): Promise<string | undefined> {
145
- const normalizedModules = await normalizeSkillModuleKeys(modules)
146
- const paths = await getMainSkillPaths(normalizedModules)
147
-
148
- // 1. 先尝试按目录名精确匹配 (兼容老逻辑)
149
- const dirMatch = paths.find((p) => p.startsWith(`./${name}/SKILL.md`))
150
- if (dirMatch) return dirMatch
151
-
152
- // 2. 如果按目录名找不到,则解析内容按 frontmatter 的 name 匹配
153
- for (const p of paths) {
154
- const content = normalizedModules[p]
155
- if (content) {
156
- const parsed = await parseSkillFrontMatter(content)
157
- if (parsed && parsed.name === name) {
158
- return p
159
- }
160
- }
161
- }
162
-
163
- return undefined
164
- }
165
-
166
- // ============ 内置工具:供 remoter 注入,替代业界 skill 中「读取文档」的操作 ============
167
-
168
- /** AI SDK Tool 类型,用于 extraTools 合并,不写死泛型避免与 ai 包版本强绑定 */
169
- // eslint-disable-next-line @typescript-eslint/no-explicit-any
170
- export type SkillToolsSet = Record<string, any>
171
-
172
- // 提升为模块级常量:避免 tool() 推断 PARAMETERS 泛型时递归展开 Zod 链导致"类型实例化过深"
173
- const SKILL_INPUT_SCHEMA = z.object({
174
- skillName: z
175
- .string()
176
- .optional()
177
- .describe(
178
- '进入某个技能的主入口名称。优先匹配技能的目录名(如 ecommerce),或者技能的中文名称(如"客户价保单创建及审核")。'
179
- ),
180
- path: z
181
- .string()
182
- .optional()
183
- .describe('你想查阅的文档的路径。如 ./calculator/SKILL.md 或从其他文档里看到的相对路径 ./reference/inventory.md。'),
184
- currentPath: z
185
- .string()
186
- .optional()
187
- .describe(
188
- '你当前正在阅读的文档路径(如果有)。比如你刚刚读取了 ./ecommerce/SKILL.md,请把这个路径原样传回来,这样系统才能根据你的相对路径准确找到下一份文件。'
189
- )
190
- })
191
-
192
- /**
193
- * 根据 skillMdModules 创建供 AI 调用的工具集
194
- * - get_skill_content: 按技能名或路径获取完整文档内容,便于大模型自动识别并加载技能
195
- * remoter 可将返回的 tools 合并进 extraTools 注入 agent
196
- */
197
- export function createSkillTools(modules: Record<string, string | (() => Promise<string>)>): SkillToolsSet {
198
- let isNormalizeSkillModuleKeys = false
199
- let normalizeSkillModuleKeysResult: Record<string, string>
200
-
201
- // @ts-ignore ai package 的 tool() 函数类型推断存在"类型实例化过深"的已知限制,无法正确推断包含复杂 Zod 链的 schema
202
- const getSkillContent = tool({
203
- description:
204
- '根据技能名称或文档路径获取该技能的完整文档内容。如果你想根据相对路径查阅文件,请务必同时提供你当前所在的文件路径 currentPath。',
205
- inputSchema: SKILL_INPUT_SCHEMA,
206
- execute: async (args: {
207
- skillName?: string
208
- path?: string
209
- currentPath?: string
210
- }): Promise<Record<string, unknown>> => {
211
- if (!isNormalizeSkillModuleKeys) {
212
- normalizeSkillModuleKeysResult = await normalizeSkillModuleKeys(modules)
213
- isNormalizeSkillModuleKeys = true
214
- }
215
-
216
- const normalizedModules = normalizeSkillModuleKeysResult
217
- const { skillName, path: pathArg, currentPath: currentPathArg } = args
218
- let content: string | undefined
219
- let resolvedPath = ''
220
-
221
- if (pathArg) {
222
- // 使用明确提供的当前阅读上下文作为基准路径(默认在根目录)
223
- let basePathContext = '.'
224
- if (currentPathArg) {
225
- // 提取出当前文档所在的目录
226
- // 比如 ./ecommerce/SKILL.md -> ./ecommerce
227
- const lastSlashIndex = currentPathArg.lastIndexOf('/')
228
- if (lastSlashIndex >= 0) {
229
- basePathContext = currentPathArg.slice(0, lastSlashIndex)
230
- }
231
- }
232
-
233
- // 尝试 1:按照大模型当前提供的上下文进行标准相对路径解析
234
- const dummyBase = `http://localhost/${basePathContext}/`
235
- const url = new URL(pathArg, dummyBase)
236
- resolvedPath = '.' + url.pathname
237
- content = await getSkillMdContent(normalizedModules, resolvedPath)
238
-
239
- // 尝试 2:如果大模型忘了传正确的 currentPath,或者是强行传错,做个智能根目录回退
240
- if (content === undefined && (pathArg.startsWith('./') || pathArg.startsWith('../')) && currentPathArg) {
241
- const baseParts = currentPathArg.split('/')
242
- if (baseParts.length >= 2) {
243
- const skillRoot = baseParts[1]
244
- const fallbackDummyBase = `http://localhost/${skillRoot}/`
245
- const fallbackUrl = new URL(pathArg, fallbackDummyBase)
246
- const fallbackPath = '.' + fallbackUrl.pathname
247
- content = await getSkillMdContent(normalizedModules, fallbackPath)
248
- if (content) {
249
- resolvedPath = fallbackPath
250
- }
251
- }
252
- }
253
-
254
- // 尝试 3:后缀自动降级匹配修正
255
- if (content && !normalizedModules[resolvedPath]) {
256
- const suffix = resolvedPath.replace(/^\.?\//, '/')
257
- const matchingKey = Object.keys(normalizedModules).find((key) => key.endsWith(suffix))
258
- if (matchingKey) {
259
- resolvedPath = matchingKey
260
- }
261
- }
262
- } else if (skillName) {
263
- const mainPath = await getMainSkillPathByName(normalizedModules, skillName)
264
- if (mainPath) {
265
- resolvedPath = mainPath
266
- content = await getSkillMdContent(normalizedModules, mainPath)
267
- }
268
- }
269
-
270
- if (content === undefined) {
271
- return {
272
- error: '未找到对应技能文档',
273
- skillName,
274
- path: pathArg,
275
- providedCurrentPath: currentPathArg,
276
- attemptedPath: resolvedPath
277
- }
278
- }
279
-
280
- return { content, path: resolvedPath }
281
- }
282
- })
283
-
284
- return {
285
- get_skill_content: getSkillContent
286
- }
287
- }