@opentiny/next-sdk 0.2.9 → 0.3.0-alpha.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.
- package/README.md +69 -53
- package/agent/AgentModelProvider.ts +77 -25
- package/agent/type.ts +3 -3
- package/core.ts +28 -0
- package/dist/AgentModelProvider-BIOOEdcN.js +4068 -0
- package/dist/agent/AgentModelProvider.d.ts +2 -0
- package/dist/agent/type.d.ts +3 -0
- package/dist/core.d.ts +24 -0
- package/dist/core.js +35 -0
- package/dist/index.es.dev.js +1475 -240
- package/dist/index.es.js +17007 -15999
- package/dist/index.js +894 -4475
- package/dist/index.umd.dev.js +1475 -240
- package/dist/index.umd.js +57 -58
- package/dist/page-tools/bridge.d.ts +94 -7
- package/dist/remoter/createRemoter.d.ts +3 -2
- package/dist/transport/ExtensionPageServerTransport.d.ts +0 -1
- package/dist/webagent.dev.js +1467 -789
- package/dist/webagent.es.dev.js +1467 -789
- package/dist/webagent.es.js +13644 -13046
- package/dist/webagent.js +58 -59
- package/dist/webmcp-full.dev.js +0 -12
- package/dist/webmcp-full.es.dev.js +0 -12
- package/dist/webmcp-full.es.js +1050 -1058
- package/dist/webmcp-full.js +9 -9
- package/dist/webmcp.dev.js +0 -12
- package/dist/webmcp.es.dev.js +0 -12
- package/dist/webmcp.es.js +78 -86
- package/dist/webmcp.js +1 -1
- package/package.json +11 -1
- package/page-tools/bridge.ts +907 -102
- package/remoter/createRemoter.ts +44 -23
- package/transport/ExtensionClientTransport.ts +15 -5
- package/transport/ExtensionContentServerTransport.ts +4 -15
- package/transport/ExtensionPageServerTransport.ts +3 -13
- package/vite-build-tsc.ts +5 -2
package/remoter/createRemoter.ts
CHANGED
|
@@ -146,30 +146,33 @@ class FloatingBlock {
|
|
|
146
146
|
|
|
147
147
|
/**
|
|
148
148
|
* 合并菜单项配置。
|
|
149
|
-
* -
|
|
150
|
-
* -
|
|
149
|
+
* - 用户明确传入 menuItems:直接使用用户配置,不受 sessionId 限制;未传 icon 时自动补充默认图标
|
|
150
|
+
* - 有 sessionId 且未传 menuItems:使用默认菜单
|
|
151
|
+
* - 无 sessionId 且未传 menuItems:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
|
|
151
152
|
*/
|
|
152
153
|
private mergeMenuItems(userMenuItems?: MenuItemConfig[]): MenuItemConfig[] {
|
|
153
|
-
//
|
|
154
|
-
|
|
155
|
-
|
|
154
|
+
// 各 action 对应的默认图标映射
|
|
155
|
+
const defaultIcons: Partial<Record<ActionType, string>> = {
|
|
156
|
+
'qr-code': qrCode,
|
|
157
|
+
'ai-chat': chat,
|
|
158
|
+
'remote-url': link,
|
|
159
|
+
'remote-control': scan
|
|
156
160
|
}
|
|
157
161
|
|
|
158
|
-
|
|
159
|
-
|
|
162
|
+
// 用户明确传入了 menuItems,直接使用,并补充缺失的图标
|
|
163
|
+
if (userMenuItems) {
|
|
164
|
+
return userMenuItems.map((item) => ({
|
|
165
|
+
...item,
|
|
166
|
+
icon: item.icon ?? defaultIcons[item.action]
|
|
167
|
+
}))
|
|
160
168
|
}
|
|
161
169
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
show: userItem.show !== undefined ? userItem.show : defaultItem.show
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
return defaultItem
|
|
172
|
-
})
|
|
170
|
+
// 无 sessionId 且无用户菜单:完全关闭下拉菜单,只保留点击浮标触发 onShowAIChat
|
|
171
|
+
if (!this.options.sessionId) {
|
|
172
|
+
return []
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
return getDefaultMenuItems(this.options)
|
|
173
176
|
}
|
|
174
177
|
|
|
175
178
|
private init(): void {
|
|
@@ -220,7 +223,7 @@ class FloatingBlock {
|
|
|
220
223
|
<div class="tiny-remoter-dropdown-item__content">
|
|
221
224
|
<div title="${item.tip}">${item.text}</div>
|
|
222
225
|
<div class="tiny-remoter-dropdown-item__desc-wrapper">
|
|
223
|
-
<div class="tiny-remoter-dropdown-item__desc ${item.active ? 'tiny-remoter-dropdown-item__desc--active' : ''} ${item.know ? 'tiny-remoter-dropdown-item__desc--know' : ''}">${item.desc}</div>
|
|
226
|
+
<div class="tiny-remoter-dropdown-item__desc ${item.active ? 'tiny-remoter-dropdown-item__desc--active' : ''} ${item.know ? 'tiny-remoter-dropdown-item__desc--know' : ''}">${item.desc ?? ''}</div>
|
|
224
227
|
<div>
|
|
225
228
|
${
|
|
226
229
|
item.showCopyIcon
|
|
@@ -357,13 +360,31 @@ class FloatingBlock {
|
|
|
357
360
|
}
|
|
358
361
|
|
|
359
362
|
private copyRemoteControl(): void {
|
|
360
|
-
|
|
361
|
-
this.
|
|
363
|
+
// 优先使用用户菜单项中的 desc/text(支持自定义识别码),回退到 sessionId 末 6 位
|
|
364
|
+
const menuItem = this.menuItems.find((item) => item.action === 'remote-control')
|
|
365
|
+
const codeToCopy =
|
|
366
|
+
menuItem?.desc || menuItem?.text || (this.options.sessionId ? this.options.sessionId.slice(-6) : '')
|
|
367
|
+
if (codeToCopy) {
|
|
368
|
+
this.copyToClipboard(codeToCopy)
|
|
369
|
+
}
|
|
362
370
|
}
|
|
363
371
|
|
|
364
372
|
private copyRemoteURL(): void {
|
|
365
|
-
|
|
366
|
-
|
|
373
|
+
const menuItem = this.menuItems.find((item) => item.action === 'remote-url')
|
|
374
|
+
|
|
375
|
+
// 构造带 sessionId 的完整遥控链接(默认行为)
|
|
376
|
+
const sessionUrl = this.options.sessionId
|
|
377
|
+
? this.options.remoteUrl + this.sessionPrefix + this.options.sessionId
|
|
378
|
+
: ''
|
|
379
|
+
|
|
380
|
+
// 仅当 desc 是用户真正自定义的值(不同于裸 remoteUrl)时才优先使用,
|
|
381
|
+
// 否则回退到带 sessionId 的完整链接,避免默认菜单场景复制裸域名
|
|
382
|
+
const customDesc = menuItem?.desc && menuItem.desc !== this.options.remoteUrl ? menuItem.desc : undefined
|
|
383
|
+
const urlToCopy = customDesc || sessionUrl || menuItem?.text || ''
|
|
384
|
+
|
|
385
|
+
if (urlToCopy) {
|
|
386
|
+
this.copyToClipboard(urlToCopy)
|
|
387
|
+
}
|
|
367
388
|
}
|
|
368
389
|
|
|
369
390
|
// 实现复制到剪贴板功能
|
|
@@ -47,7 +47,7 @@ export class ExtensionClientTransport implements Transport {
|
|
|
47
47
|
console.log('【Client Transport】处理server消息错误:', error)
|
|
48
48
|
}
|
|
49
49
|
},
|
|
50
|
-
'content->
|
|
50
|
+
'content->bg'
|
|
51
51
|
)
|
|
52
52
|
}
|
|
53
53
|
|
|
@@ -63,14 +63,24 @@ export class ExtensionClientTransport implements Transport {
|
|
|
63
63
|
this._throwError(() => this._isClosed, '【Client Transport】 已关闭,无法发送消息')
|
|
64
64
|
|
|
65
65
|
// 查询 当前sessionId的最后一个tabid
|
|
66
|
-
|
|
67
|
-
|
|
66
|
+
let tabId: number | undefined
|
|
67
|
+
if (chrome.sessionRegistry) {
|
|
68
|
+
const sessionInfo = chrome.sessionRegistry.get(this.targetSessionId)
|
|
69
|
+
if (sessionInfo && sessionInfo.tabIds.length > 0) {
|
|
70
|
+
tabId = sessionInfo.tabIds[sessionInfo.tabIds.length - 1]
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
if (tabId == null) {
|
|
75
|
+
tabId = await chrome.runtime.sendMessage({ type: 'get-session-tab-id', sessionId: this.targetSessionId })
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
this._throwError(() => tabId == null, `【Client Transport】后台未找到活动的tabId用于${this.targetSessionId}`)
|
|
68
79
|
|
|
69
|
-
const tabId = sessionInfo.tabIds[sessionInfo.tabIds.length - 1]
|
|
70
80
|
sendRuntimeMessage(
|
|
71
81
|
'mcp-client-to-server',
|
|
72
82
|
{ sessionId: this.targetSessionId, tabId, mcpMessage: message },
|
|
73
|
-
'
|
|
83
|
+
'bg->content'
|
|
74
84
|
)
|
|
75
85
|
}
|
|
76
86
|
|
|
@@ -54,18 +54,7 @@ export class ContentScriptServerTransport implements Transport {
|
|
|
54
54
|
this.sessionId = sessionId || randomUUID()
|
|
55
55
|
this.tabId = tabId
|
|
56
56
|
|
|
57
|
-
|
|
58
|
-
'sidepanel-ready',
|
|
59
|
-
() => {
|
|
60
|
-
if (this._lastRegistration && this._isStarted) {
|
|
61
|
-
this.notifyRegistration(this._lastRegistration).catch((error) => {
|
|
62
|
-
console.log('【Content Svr Transport】 notifyRegistration 失败', error)
|
|
63
|
-
})
|
|
64
|
-
}
|
|
65
|
-
},
|
|
66
|
-
'side->content',
|
|
67
|
-
this.tabId
|
|
68
|
-
)
|
|
57
|
+
// 移除对 sidepanel-ready 的监听,因为现在的注册信息将直接发送给长期驻留的 background,不丢失状态
|
|
69
58
|
}
|
|
70
59
|
|
|
71
60
|
/** 启动 transport,开始监听MCP client 消息 */
|
|
@@ -99,7 +88,7 @@ export class ContentScriptServerTransport implements Transport {
|
|
|
99
88
|
console.log('【Content Svr Transport】 处理消息时发生错误:', error)
|
|
100
89
|
}
|
|
101
90
|
},
|
|
102
|
-
'
|
|
91
|
+
'bg->content',
|
|
103
92
|
this.tabId
|
|
104
93
|
)
|
|
105
94
|
|
|
@@ -120,7 +109,7 @@ export class ContentScriptServerTransport implements Transport {
|
|
|
120
109
|
sessionId: this.sessionId,
|
|
121
110
|
mcpMessage: message
|
|
122
111
|
},
|
|
123
|
-
'content->
|
|
112
|
+
'content->bg'
|
|
124
113
|
)
|
|
125
114
|
|
|
126
115
|
// 判断是否为工具调用成功了!
|
|
@@ -153,7 +142,7 @@ export class ContentScriptServerTransport implements Transport {
|
|
|
153
142
|
title: document.title
|
|
154
143
|
}
|
|
155
144
|
},
|
|
156
|
-
'content->
|
|
145
|
+
'content->bg'
|
|
157
146
|
)
|
|
158
147
|
}
|
|
159
148
|
|
|
@@ -30,7 +30,7 @@ export class ExtensionPageServerTransport implements Transport {
|
|
|
30
30
|
readonly sessionId: string
|
|
31
31
|
|
|
32
32
|
// 内部状态
|
|
33
|
-
|
|
33
|
+
|
|
34
34
|
private _messageListener2: () => void
|
|
35
35
|
private _isStarted: boolean = false
|
|
36
36
|
private _isClosed: boolean = false
|
|
@@ -50,17 +50,7 @@ export class ExtensionPageServerTransport implements Transport {
|
|
|
50
50
|
// 如果提供了 sessionId,使用提供的;否则随机生成
|
|
51
51
|
this.sessionId = sessionId || randomUUID()
|
|
52
52
|
|
|
53
|
-
|
|
54
|
-
'sidepanel-ready-to-page',
|
|
55
|
-
() => {
|
|
56
|
-
if (this._lastRegistration && this._isStarted) {
|
|
57
|
-
this.notifyRegistration(this._lastRegistration).catch((error) => {
|
|
58
|
-
console.error('【Page Svr Transport】 notifyRegistration失败:', error)
|
|
59
|
-
})
|
|
60
|
-
}
|
|
61
|
-
},
|
|
62
|
-
'content->page'
|
|
63
|
-
)
|
|
53
|
+
// 移除了对 sidepanel-ready-to-page 的监听,因为信息直接发往常驻的 background
|
|
64
54
|
|
|
65
55
|
this._messageListener2 = onWindowMessage(
|
|
66
56
|
'mcp-client-to-server-to-page',
|
|
@@ -146,7 +136,7 @@ export class ExtensionPageServerTransport implements Transport {
|
|
|
146
136
|
if (this._isClosed) return
|
|
147
137
|
|
|
148
138
|
try {
|
|
149
|
-
|
|
139
|
+
|
|
150
140
|
this._messageListener2 && this._messageListener2()
|
|
151
141
|
|
|
152
142
|
this._isClosed = true
|
package/vite-build-tsc.ts
CHANGED
|
@@ -35,10 +35,13 @@ export default defineConfig(() => {
|
|
|
35
35
|
build: {
|
|
36
36
|
emptyOutDir: false,
|
|
37
37
|
lib: {
|
|
38
|
-
entry:
|
|
38
|
+
entry: {
|
|
39
|
+
index: 'index.ts',
|
|
40
|
+
core: 'core.ts'
|
|
41
|
+
},
|
|
39
42
|
name: 'NEXT-SDK',
|
|
40
43
|
formats: ['es'],
|
|
41
|
-
fileName: () =>
|
|
44
|
+
fileName: (format, entryName) => `${entryName}.js`
|
|
42
45
|
},
|
|
43
46
|
rollupOptions: {
|
|
44
47
|
// 排除第三方依赖,保留本地文件
|