@opentiny/next-sdk 0.2.10 → 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 +67 -22
- package/core.ts +28 -0
- package/dist/AgentModelProvider-BIOOEdcN.js +4068 -0
- package/dist/agent/AgentModelProvider.d.ts +2 -0
- package/dist/core.d.ts +24 -0
- package/dist/core.js +35 -0
- package/dist/index.es.dev.js +1439 -218
- package/dist/index.es.js +16997 -16001
- package/dist/index.js +891 -4484
- package/dist/index.umd.dev.js +1439 -218
- package/dist/index.umd.js +56 -57
- package/dist/page-tools/bridge.d.ts +94 -7
- package/dist/transport/ExtensionPageServerTransport.d.ts +0 -1
- package/dist/webagent.dev.js +776 -112
- package/dist/webagent.es.dev.js +776 -112
- package/dist/webagent.es.js +11703 -11117
- package/dist/webagent.js +57 -58
- 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/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/README.md
CHANGED
|
@@ -11,6 +11,9 @@
|
|
|
11
11
|
<a href="#️-参与开发">🛠️ 参与开发</a>
|
|
12
12
|
</p>
|
|
13
13
|
|
|
14
|
+
> [!IMPORTANT]
|
|
15
|
+
> **WebMCP 兼容性说明**:OpenTiny WebMCP 方案**全面兼容 Google Chrome 浏览器由 Google 官方定义的内置 WebMCP 协议**。这意味着您通过此 SDK 开发的 WebSkills 可以无缝接入浏览器原生的 AI 能力。
|
|
16
|
+
|
|
14
17
|
---
|
|
15
18
|
|
|
16
19
|
**OpenTiny NEXT-SDKs** 是一套前端智能应用开发工具包,旨在简化 WebAgent 的集成与使用,支持多种编程语言和前端框架,帮助开发者快速实现智能化功能。
|
|
@@ -31,7 +34,7 @@
|
|
|
31
34
|
## ✨ 主要特性
|
|
32
35
|
|
|
33
36
|
- 🎯 **简化集成**:提供简洁的 API 封装,简化与 WebAgent 服务的连接、认证等逻辑
|
|
34
|
-
- 🔌 **MCP 协议**:完整实现 Model Context Protocol(MCP)的 Web
|
|
37
|
+
- 🔌 **MCP 协议**:完整实现 Model Context Protocol(MCP)的 Web 版本,**全面兼容 Google Chrome 内置的 WebMCP 协议**,支持浏览器端工具调用
|
|
35
38
|
- 🤖 **AI 对话组件**:提供开箱即用的 AI 对话框组件(`@opentiny/next-remoter`)
|
|
36
39
|
- 🔄 **适配器层**:可将任意前端 AI 对话框组件快速接入 WebAgent 服务
|
|
37
40
|
- 🌐 **多模态支持**:支持文字、语音等多模态输入,抹平不同 LLM 之间的差异
|
|
@@ -88,21 +91,27 @@ const server = new WebMcpServer({
|
|
|
88
91
|
})
|
|
89
92
|
|
|
90
93
|
// 注册工具
|
|
91
|
-
server.registerTool(
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
94
|
+
server.registerTool(
|
|
95
|
+
'demo-tool',
|
|
96
|
+
{
|
|
97
|
+
title: '演示工具',
|
|
98
|
+
description: '这是一个演示工具',
|
|
99
|
+
inputSchema: {
|
|
100
|
+
foo: z.string().describe('输入参数')
|
|
101
|
+
}
|
|
96
102
|
},
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
103
|
+
async (params) => {
|
|
104
|
+
console.log('接收到参数:', params)
|
|
105
|
+
return {
|
|
106
|
+
content: [
|
|
107
|
+
{
|
|
108
|
+
type: 'text',
|
|
109
|
+
text: `已处理: ${params.foo}`
|
|
110
|
+
}
|
|
111
|
+
]
|
|
112
|
+
}
|
|
104
113
|
}
|
|
105
|
-
|
|
114
|
+
)
|
|
106
115
|
|
|
107
116
|
// 连接 Server Transport
|
|
108
117
|
await server.connect(serverTransport)
|
|
@@ -157,10 +166,7 @@ const sessionId = 'your-session-id'
|
|
|
157
166
|
</script>
|
|
158
167
|
|
|
159
168
|
<template>
|
|
160
|
-
<tiny-remoter
|
|
161
|
-
:session-id="sessionId"
|
|
162
|
-
title="我的智能助手"
|
|
163
|
-
/>
|
|
169
|
+
<tiny-remoter :session-id="sessionId" title="我的智能助手" />
|
|
164
170
|
</template>
|
|
165
171
|
```
|
|
166
172
|
|
|
@@ -185,33 +191,33 @@ const sessionId = 'your-session-id'
|
|
|
185
191
|
</head>
|
|
186
192
|
<body>
|
|
187
193
|
<script>
|
|
188
|
-
(async () => {
|
|
189
|
-
const { WebMcpServer, createMessageChannelPairTransport, z, WebMcpClient } = WebMCP
|
|
190
|
-
const [serverTransport, clientTransport] = createMessageChannelPairTransport()
|
|
194
|
+
;(async () => {
|
|
195
|
+
const { WebMcpServer, createMessageChannelPairTransport, z, WebMcpClient } = WebMCP
|
|
196
|
+
const [serverTransport, clientTransport] = createMessageChannelPairTransport()
|
|
191
197
|
|
|
192
|
-
const client = new WebMcpClient()
|
|
193
|
-
await client.connect(clientTransport)
|
|
198
|
+
const client = new WebMcpClient()
|
|
199
|
+
await client.connect(clientTransport)
|
|
194
200
|
const { sessionId } = await client.connect({
|
|
195
201
|
agent: true,
|
|
196
|
-
url:
|
|
197
|
-
})
|
|
202
|
+
url: 'https://agent.opentiny.design/api/v1/webmcp-trial/mcp'
|
|
203
|
+
})
|
|
198
204
|
|
|
199
|
-
const server = new WebMcpServer()
|
|
205
|
+
const server = new WebMcpServer()
|
|
200
206
|
server.registerTool(
|
|
201
|
-
|
|
207
|
+
'demo-tool',
|
|
202
208
|
{
|
|
203
|
-
title:
|
|
204
|
-
description:
|
|
205
|
-
inputSchema: { foo: z.string() }
|
|
209
|
+
title: '演示工具',
|
|
210
|
+
description: '一个简单工具',
|
|
211
|
+
inputSchema: { foo: z.string() }
|
|
206
212
|
},
|
|
207
213
|
async (params) => {
|
|
208
|
-
console.log(
|
|
209
|
-
return { content: [{ type:
|
|
214
|
+
console.log('params:', params)
|
|
215
|
+
return { content: [{ type: 'text', text: `收到: ${params.foo}` }] }
|
|
210
216
|
}
|
|
211
|
-
)
|
|
217
|
+
)
|
|
212
218
|
|
|
213
|
-
await server.connect(serverTransport)
|
|
214
|
-
})()
|
|
219
|
+
await server.connect(serverTransport)
|
|
220
|
+
})()
|
|
215
221
|
</script>
|
|
216
222
|
</body>
|
|
217
223
|
</html>
|
|
@@ -265,14 +271,20 @@ const server = new WebMcpServer({
|
|
|
265
271
|
})
|
|
266
272
|
|
|
267
273
|
// 注册工具
|
|
268
|
-
server.registerTool(
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
}
|
|
274
|
+
server.registerTool(
|
|
275
|
+
'tool-name',
|
|
276
|
+
{
|
|
277
|
+
title: '工具标题',
|
|
278
|
+
description: '工具描述',
|
|
279
|
+
inputSchema: {
|
|
280
|
+
/* Zod schema */
|
|
281
|
+
}
|
|
282
|
+
},
|
|
283
|
+
async (params) => {
|
|
284
|
+
// 工具处理逻辑
|
|
285
|
+
return { content: [{ type: 'text', text: '结果' }] }
|
|
286
|
+
}
|
|
287
|
+
)
|
|
276
288
|
```
|
|
277
289
|
|
|
278
290
|
### WebMcpClient
|
|
@@ -590,17 +602,21 @@ const { sessionId } = await client.connect({
|
|
|
590
602
|
使用 `server.registerTool()` 注册自定义工具:
|
|
591
603
|
|
|
592
604
|
```typescript
|
|
593
|
-
server.registerTool(
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
605
|
+
server.registerTool(
|
|
606
|
+
'my-tool',
|
|
607
|
+
{
|
|
608
|
+
title: '我的工具',
|
|
609
|
+
description: '工具描述',
|
|
610
|
+
inputSchema: {
|
|
611
|
+
param1: z.string(),
|
|
612
|
+
param2: z.number()
|
|
613
|
+
}
|
|
614
|
+
},
|
|
615
|
+
async (params) => {
|
|
616
|
+
// 实现工具逻辑
|
|
617
|
+
return { content: [{ type: 'text', text: '执行结果' }] }
|
|
599
618
|
}
|
|
600
|
-
|
|
601
|
-
// 实现工具逻辑
|
|
602
|
-
return { content: [{ type: 'text', text: '执行结果' }] }
|
|
603
|
-
})
|
|
619
|
+
)
|
|
604
620
|
```
|
|
605
621
|
|
|
606
622
|
### 3. 支持哪些大语言模型?
|
|
@@ -222,12 +222,18 @@ export class AgentModelProvider {
|
|
|
222
222
|
)
|
|
223
223
|
}
|
|
224
224
|
|
|
225
|
-
/** 创建所有的 mcpClients,并更新它们的tools */
|
|
226
|
-
async initClientsAndTools() {
|
|
227
|
-
await this._createMpcClients()
|
|
228
|
-
await this._createMpcTools()
|
|
229
|
-
this.onUpdatedTools?.()
|
|
230
|
-
}
|
|
225
|
+
/** 创建所有的 mcpClients,并更新它们的tools */
|
|
226
|
+
async initClientsAndTools() {
|
|
227
|
+
await this._createMpcClients()
|
|
228
|
+
await this._createMpcTools()
|
|
229
|
+
this.onUpdatedTools?.()
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
/** 仅刷新已连接 clients 的 tools(不重建 client,适合工具目录动态变化场景) */
|
|
233
|
+
async refreshTools() {
|
|
234
|
+
await this._createMpcTools()
|
|
235
|
+
this.onUpdatedTools?.()
|
|
236
|
+
}
|
|
231
237
|
|
|
232
238
|
/** 全量更新所有的 mcpServers */
|
|
233
239
|
async updateMcpServers(mcpServers?: Record<string, McpServerConfig>) {
|
|
@@ -820,22 +826,61 @@ export class AgentModelProvider {
|
|
|
820
826
|
}
|
|
821
827
|
|
|
822
828
|
// 否则使用原有的 function calling 模式
|
|
823
|
-
if (!this.llm) {
|
|
824
|
-
throw new Error('LLM is not initialized')
|
|
825
|
-
}
|
|
826
|
-
|
|
827
|
-
await this.initClientsAndTools()
|
|
828
|
-
|
|
829
|
-
const
|
|
830
|
-
|
|
831
|
-
|
|
832
|
-
|
|
833
|
-
|
|
834
|
-
|
|
835
|
-
|
|
836
|
-
|
|
837
|
-
|
|
838
|
-
|
|
829
|
+
if (!this.llm) {
|
|
830
|
+
throw new Error('LLM is not initialized')
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
await this.initClientsAndTools()
|
|
834
|
+
|
|
835
|
+
const extraTools = (options.tools || {}) as ToolSet
|
|
836
|
+
const allTools = this._tempMergeTools(extraTools, false)
|
|
837
|
+
|
|
838
|
+
// 让 tools 保持“同一个对象引用”并在每个 step 前同步:
|
|
839
|
+
// - prepareStep 只能控制 activeTools,不能直接返回 tools
|
|
840
|
+
// - 因此需要在进入每个 step 前,把最新 mcpTools 合并回当前 tools 对象
|
|
841
|
+
// - 这样 activeTools 新增的工具名在当步就能命中真实工具定义
|
|
842
|
+
const syncToolsForStep = () => {
|
|
843
|
+
const latestTools = this._tempMergeTools(extraTools, false)
|
|
844
|
+
|
|
845
|
+
// upsert
|
|
846
|
+
Object.entries(latestTools).forEach(([name, tool]) => {
|
|
847
|
+
;(allTools as any)[name] = tool
|
|
848
|
+
})
|
|
849
|
+
|
|
850
|
+
// remove stale
|
|
851
|
+
Object.keys(allTools).forEach((name) => {
|
|
852
|
+
if (!(name in latestTools)) {
|
|
853
|
+
delete (allTools as any)[name]
|
|
854
|
+
}
|
|
855
|
+
})
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
const userPrepareStep = (options as any).prepareStep
|
|
859
|
+
const wrappedPrepareStep = async (stepOptions: any) => {
|
|
860
|
+
syncToolsForStep()
|
|
861
|
+
|
|
862
|
+
const latestActiveTools = this._getActiveToolNames(allTools)
|
|
863
|
+
const userStepPatch = typeof userPrepareStep === 'function' ? await userPrepareStep(stepOptions) : undefined
|
|
864
|
+
const safeUserStepPatch =
|
|
865
|
+
userStepPatch && typeof userStepPatch === 'object' ? userStepPatch : ({} as Record<string, any>)
|
|
866
|
+
|
|
867
|
+
return {
|
|
868
|
+
...safeUserStepPatch,
|
|
869
|
+
activeTools: Array.isArray(safeUserStepPatch.activeTools)
|
|
870
|
+
? safeUserStepPatch.activeTools.filter((name: string) => latestActiveTools.includes(name))
|
|
871
|
+
: latestActiveTools
|
|
872
|
+
}
|
|
873
|
+
}
|
|
874
|
+
|
|
875
|
+
const chatOptions = {
|
|
876
|
+
// @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
|
|
877
|
+
model: this.llm(model),
|
|
878
|
+
stopWhen: stepCountIs(maxSteps),
|
|
879
|
+
...options,
|
|
880
|
+
tools: allTools,
|
|
881
|
+
prepareStep: wrappedPrepareStep,
|
|
882
|
+
activeTools: this._getActiveToolNames(allTools)
|
|
883
|
+
}
|
|
839
884
|
|
|
840
885
|
// 保存最后一条 user 消息,用于后续缓存
|
|
841
886
|
let lastUserMessage: any = null
|
package/core.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
// 核心导出,仅包含无 DOM 依赖(Node.js / Service Worker 安全)的内容
|
|
2
|
+
import Ajv from 'ajv'
|
|
3
|
+
export { Ajv }
|
|
4
|
+
export { z } from 'zod'
|
|
5
|
+
export { AuthClientProvider } from '@opentiny/next'
|
|
6
|
+
export { ResourceTemplate } from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
7
|
+
export { UriTemplate } from '@modelcontextprotocol/sdk/shared/uriTemplate.js'
|
|
8
|
+
export { completable } from '@modelcontextprotocol/sdk/server/completable.js'
|
|
9
|
+
export { getDisplayName } from '@modelcontextprotocol/sdk/shared/metadataUtils.js'
|
|
10
|
+
export { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'
|
|
11
|
+
export type * from 'zod'
|
|
12
|
+
export type * from '@opentiny/next'
|
|
13
|
+
export type * from '@modelcontextprotocol/sdk/types.js'
|
|
14
|
+
export type * from '@modelcontextprotocol/sdk/shared/protocol.js'
|
|
15
|
+
export type * from '@modelcontextprotocol/sdk/shared/transport.js'
|
|
16
|
+
export type * from '@modelcontextprotocol/sdk/client/sse.js'
|
|
17
|
+
export type * from '@modelcontextprotocol/sdk/client/streamableHttp.js'
|
|
18
|
+
export type * from '@modelcontextprotocol/sdk/server/mcp.js'
|
|
19
|
+
|
|
20
|
+
export * from './WebMcpServer'
|
|
21
|
+
export * from './WebMcpClient'
|
|
22
|
+
|
|
23
|
+
// 浏览器扩展自定义传输层(不包含对 window 依赖的模块)
|
|
24
|
+
export * from './transport/ExtensionClientTransport'
|
|
25
|
+
|
|
26
|
+
export { AgentModelProvider } from './agent/AgentModelProvider'
|
|
27
|
+
export { getAISDKTools } from './agent/utils/getAISDKTools'
|
|
28
|
+
export type * from './agent/type'
|