@opentiny/next-sdk 0.1.7 → 0.1.9

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.
@@ -31,14 +31,12 @@ export class AgentModelProvider {
31
31
  /** 需要实时过滤掉的tools name*/
32
32
  ignoreToolnames: string[] = []
33
33
 
34
- /** 在 chat 之前,自动更新 所有的tools */
35
- autoUpdateTools = true
36
-
37
34
  /** chat 时,自动更新 所有的tools 后的事件 */
38
35
  onUpdatedTools: (() => void) | undefined
39
36
  /** 内部报错时,抛出错误事件 */
40
37
  onError: ((msg: string, err?: any) => void) | undefined
41
38
 
39
+ /** 缓存 ai-sdk response 中的 多轮会话 */
42
40
  messages: any[] = []
43
41
 
44
42
  constructor({ llmConfig, mcpServers, llm }: IAgentModelProviderOption) {
@@ -76,7 +74,10 @@ export class AgentModelProvider {
76
74
  transport = serverConfig as MCPClientConfig['transport']
77
75
  }
78
76
 
79
- return await createMCPClient({ transport: transport as MCPClientConfig['transport'] })
77
+ const client = await createMCPClient({ transport: transport as MCPClientConfig['transport'] })
78
+ //@ts-ignore
79
+ client['__transport__'] = transport
80
+ return client
80
81
  } catch (error: unknown) {
81
82
  if (this.onError) {
82
83
  this.onError((error as Error)?.message || `Failed to create MCP client`, error)
@@ -85,6 +86,12 @@ export class AgentModelProvider {
85
86
  return null
86
87
  }
87
88
  }
89
+ /** 关闭一个client */
90
+ private async _closeOneClient(client: any) {
91
+ await client['__transport__']?.terminateSession?.()
92
+ await client['__transport__']?.close?.()
93
+ await client?.close?.()
94
+ }
88
95
  /** 创建 ai-sdk的 mcpClient, 失败则保存为null */
89
96
  private async _createMpcClients() {
90
97
  // 使用 Promise.all 并行处理所有 mcpServer 项
@@ -115,7 +122,7 @@ export class AgentModelProvider {
115
122
  await Promise.all(
116
123
  this.mcpClients.map(async (client) => {
117
124
  try {
118
- await client.close()
125
+ await this._closeOneClient(client)
119
126
  } catch (error: unknown) {
120
127
  if (this.onError) {
121
128
  this.onError((error as Error)?.message || `Failed to close client`, error)
@@ -150,7 +157,7 @@ export class AgentModelProvider {
150
157
  return false
151
158
  }
152
159
  /** 通过引用,删除一个 mcpServers mcpClients mcpTools ignoreToolnames */
153
- removeMcpServer(mcpServer: McpServerConfig) {
160
+ async removeMcpServer(mcpServer: McpServerConfig) {
154
161
  const index = this.mcpServers.findIndex((server) => server === mcpServer)
155
162
 
156
163
  // 移除
@@ -160,7 +167,7 @@ export class AgentModelProvider {
160
167
  const delClient = this.mcpClients[index]
161
168
  this.mcpClients.splice(index, 1)
162
169
  try {
163
- delClient?.close()
170
+ await this._closeOneClient(delClient)
164
171
  } catch (error) {}
165
172
 
166
173
  // 移除 tools
@@ -176,7 +183,7 @@ export class AgentModelProvider {
176
183
  }
177
184
 
178
185
  /** 创建临时允许调用的tools集合 */
179
- tempMergeTools(extraTool = {}) {
186
+ private _tempMergeTools(extraTool = {}) {
180
187
  const toolsResult = this.mcpTools.reduce((acc, curr) => ({ ...acc, ...curr }), {})
181
188
  Object.assign(toolsResult, extraTool)
182
189
 
@@ -186,7 +193,7 @@ export class AgentModelProvider {
186
193
  return toolsResult
187
194
  }
188
195
 
189
- async _chat(
196
+ private async _chat(
190
197
  chatMethod: ChatMethodFn,
191
198
  { model, maxSteps = 5, ...options }: Parameters<typeof generateText>[0] & { maxSteps?: number; message?: string }
192
199
  ): Promise<any> {
@@ -194,17 +201,16 @@ export class AgentModelProvider {
194
201
  throw new Error('LLM is not initialized')
195
202
  }
196
203
 
197
- if (this.autoUpdateTools) {
198
- await this._createMpcTools()
199
- this.onUpdatedTools?.()
200
- }
204
+ await this.initClientsAndTools()
205
+
206
+ this.onUpdatedTools?.()
201
207
 
202
208
  const chatOptions = {
203
209
  // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
204
210
  model: this.llm(model),
205
211
  stopWhen: stepCountIs(maxSteps),
206
212
  ...options,
207
- tools: this.tempMergeTools(options.tools) as ToolSet
213
+ tools: this._tempMergeTools(options.tools) as ToolSet
208
214
  }
209
215
 
210
216
  if (options.message && !options.messages) {
@@ -214,6 +220,7 @@ export class AgentModelProvider {
214
220
 
215
221
  const result = chatMethod(chatOptions)
216
222
 
223
+ // 缓存 ai-sdk的多轮对话的消息
217
224
  ;(result as StreamTextResult<ToolSet, unknown>)?.response?.then((res: any) => {
218
225
  this.messages.push(...res.messages)
219
226
  })
@@ -8,7 +8,6 @@ export declare const AIProviderFactories: {
8
8
  openai: typeof createOpenAI;
9
9
  deepseek: typeof createDeepSeek;
10
10
  };
11
- type ChatMethodFn = typeof streamText | typeof generateText;
12
11
  /** 一个通用的ai-sdk的agent封装
13
12
  * @summary 内部自动管理了 llm, mcpServer, ai-sdk的clients 和 tools
14
13
  * @returns 暴露了 chat, chatStream方法
@@ -24,16 +23,17 @@ export declare class AgentModelProvider {
24
23
  mcpTools: Array<Record<string, any>>;
25
24
  /** 需要实时过滤掉的tools name*/
26
25
  ignoreToolnames: string[];
27
- /** 在 chat 之前,自动更新 所有的tools */
28
- autoUpdateTools: boolean;
29
26
  /** chat 时,自动更新 所有的tools 后的事件 */
30
27
  onUpdatedTools: (() => void) | undefined;
31
28
  /** 内部报错时,抛出错误事件 */
32
29
  onError: ((msg: string, err?: any) => void) | undefined;
30
+ /** 缓存 ai-sdk response 中的 多轮会话 */
33
31
  messages: any[];
34
32
  constructor({ llmConfig, mcpServers, llm }: IAgentModelProviderOption);
35
33
  /** 创建一个 ai-sdk的 mcpClient, 创建失败则返回 Null */
36
34
  private _createOneClient;
35
+ /** 关闭一个client */
36
+ private _closeOneClient;
37
37
  /** 创建 ai-sdk的 mcpClient, 失败则保存为null */
38
38
  private _createMpcClients;
39
39
  /** 创建所有 mcpClients 的 tools, 失败则保存为null */
@@ -44,13 +44,10 @@ export declare class AgentModelProvider {
44
44
  updateMcpServers(mcpServers: McpServerConfig[]): Promise<void>;
45
45
  insertMcpServer(mcpServer: McpServerConfig): Promise<boolean>;
46
46
  /** 通过引用,删除一个 mcpServers mcpClients mcpTools ignoreToolnames */
47
- removeMcpServer(mcpServer: McpServerConfig): void;
47
+ removeMcpServer(mcpServer: McpServerConfig): Promise<void>;
48
48
  /** 创建临时允许调用的tools集合 */
49
- tempMergeTools(extraTool?: {}): Record<string, any>;
50
- _chat(chatMethod: ChatMethodFn, { model, maxSteps, ...options }: Parameters<typeof generateText>[0] & {
51
- maxSteps?: number;
52
- message?: string;
53
- }): Promise<any>;
49
+ private _tempMergeTools;
50
+ private _chat;
54
51
  chat(options: Parameters<typeof generateText>[0] & {
55
52
  maxSteps?: number;
56
53
  message?: string;
@@ -60,4 +57,3 @@ export declare class AgentModelProvider {
60
57
  message?: string;
61
58
  }): Promise<any>;
62
59
  }
63
- export {};
@@ -42,8 +42,7 @@ export class AgentModelProvider {
42
42
  this.mcpTools = [];
43
43
  /** 需要实时过滤掉的tools name*/
44
44
  this.ignoreToolnames = [];
45
- /** chat 之前,自动更新 所有的tools */
46
- this.autoUpdateTools = true;
45
+ /** 缓存 ai-sdk response 中的 多轮会话 */
47
46
  this.messages = [];
48
47
  // 1、保存 mcpServer
49
48
  this.mcpServers = mcpServers || [];
@@ -80,7 +79,10 @@ export class AgentModelProvider {
80
79
  else {
81
80
  transport = serverConfig;
82
81
  }
83
- return yield createMCPClient({ transport: transport });
82
+ const client = yield createMCPClient({ transport: transport });
83
+ //@ts-ignore
84
+ client['__transport__'] = transport;
85
+ return client;
84
86
  }
85
87
  catch (error) {
86
88
  if (this.onError) {
@@ -91,6 +93,15 @@ export class AgentModelProvider {
91
93
  }
92
94
  });
93
95
  }
96
+ /** 关闭一个client */
97
+ _closeOneClient(client) {
98
+ return __awaiter(this, void 0, void 0, function* () {
99
+ var _a, _b, _c, _d, _e;
100
+ yield ((_b = (_a = client['__transport__']) === null || _a === void 0 ? void 0 : _a.terminateSession) === null || _b === void 0 ? void 0 : _b.call(_a));
101
+ yield ((_d = (_c = client['__transport__']) === null || _c === void 0 ? void 0 : _c.close) === null || _d === void 0 ? void 0 : _d.call(_c));
102
+ yield ((_e = client === null || client === void 0 ? void 0 : client.close) === null || _e === void 0 ? void 0 : _e.call(client));
103
+ });
104
+ }
94
105
  /** 创建 ai-sdk的 mcpClient, 失败则保存为null */
95
106
  _createMpcClients() {
96
107
  return __awaiter(this, void 0, void 0, function* () {
@@ -123,7 +134,7 @@ export class AgentModelProvider {
123
134
  return __awaiter(this, void 0, void 0, function* () {
124
135
  yield Promise.all(this.mcpClients.map((client) => __awaiter(this, void 0, void 0, function* () {
125
136
  try {
126
- yield client.close();
137
+ yield this._closeOneClient(client);
127
138
  }
128
139
  catch (error) {
129
140
  if (this.onError) {
@@ -163,28 +174,30 @@ export class AgentModelProvider {
163
174
  }
164
175
  /** 通过引用,删除一个 mcpServers mcpClients mcpTools ignoreToolnames */
165
176
  removeMcpServer(mcpServer) {
166
- const index = this.mcpServers.findIndex((server) => server === mcpServer);
167
- // 移除
168
- this.mcpServers.splice(index, 1);
169
- // 移除
170
- const delClient = this.mcpClients[index];
171
- this.mcpClients.splice(index, 1);
172
- try {
173
- delClient === null || delClient === void 0 ? void 0 : delClient.close();
174
- }
175
- catch (error) { }
176
- // 移除 tools
177
- const delTool = this.mcpTools[index];
178
- this.mcpTools.splice(index, 1);
179
- // 移除 ignoreToolnames
180
- if (delTool) {
181
- Object.keys(delTool).forEach((toolName) => {
182
- this.ignoreToolnames = this.ignoreToolnames.filter((name) => name !== toolName);
183
- });
184
- }
177
+ return __awaiter(this, void 0, void 0, function* () {
178
+ const index = this.mcpServers.findIndex((server) => server === mcpServer);
179
+ // 移除
180
+ this.mcpServers.splice(index, 1);
181
+ // 移除
182
+ const delClient = this.mcpClients[index];
183
+ this.mcpClients.splice(index, 1);
184
+ try {
185
+ yield this._closeOneClient(delClient);
186
+ }
187
+ catch (error) { }
188
+ // 移除 tools
189
+ const delTool = this.mcpTools[index];
190
+ this.mcpTools.splice(index, 1);
191
+ // 移除 ignoreToolnames
192
+ if (delTool) {
193
+ Object.keys(delTool).forEach((toolName) => {
194
+ this.ignoreToolnames = this.ignoreToolnames.filter((name) => name !== toolName);
195
+ });
196
+ }
197
+ });
185
198
  }
186
199
  /** 创建临时允许调用的tools集合 */
187
- tempMergeTools(extraTool = {}) {
200
+ _tempMergeTools(extraTool = {}) {
188
201
  const toolsResult = this.mcpTools.reduce((acc, curr) => (Object.assign(Object.assign({}, acc), curr)), {});
189
202
  Object.assign(toolsResult, extraTool);
190
203
  this.ignoreToolnames.forEach((name) => {
@@ -199,13 +212,11 @@ export class AgentModelProvider {
199
212
  if (!this.llm) {
200
213
  throw new Error('LLM is not initialized');
201
214
  }
202
- if (this.autoUpdateTools) {
203
- yield this._createMpcTools();
204
- (_b = this.onUpdatedTools) === null || _b === void 0 ? void 0 : _b.call(this);
205
- }
215
+ yield this.initClientsAndTools();
216
+ (_b = this.onUpdatedTools) === null || _b === void 0 ? void 0 : _b.call(this);
206
217
  const chatOptions = Object.assign(Object.assign({
207
218
  // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
208
- model: this.llm(model), stopWhen: stepCountIs(maxSteps) }, options), { tools: this.tempMergeTools(options.tools) });
219
+ model: this.llm(model), stopWhen: stepCountIs(maxSteps) }, options), { tools: this._tempMergeTools(options.tools) });
209
220
  if (options.message && !options.messages) {
210
221
  this.messages.push({ role: 'user', content: options.message });
211
222
  chatOptions.messages = [...this.messages];
@@ -24885,6 +24885,8 @@ class QrCode {
24885
24885
  img.src = await this.toDataURL();
24886
24886
  }
24887
24887
  }
24888
+ const DEFAULT_REMOTE_URL = "https://agent.opentiny.design/tiny-robot";
24889
+ const DEFAULT_QR_CODE_URL = "https://ai.opentiny.design/next-remoter";
24888
24890
  const getDefaultMenuItems = (options) => {
24889
24891
  return [
24890
24892
  {
@@ -24933,8 +24935,8 @@ const getDefaultMenuItems = (options) => {
24933
24935
  {
24934
24936
  action: "remote-url",
24935
24937
  show: true,
24936
- text: `${options.qrCodeUrl}`,
24937
- tip: options.qrCodeUrl,
24938
+ text: `${options.remoteUrl}`,
24939
+ tip: options.remoteUrl,
24938
24940
  showCopyIcon: true,
24939
24941
  icon: `<svg width="20" height="20" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">
24940
24942
  <path d="M10 13a5 5 0 0 0 7.54.54l3-3a5 5 0 0 0-7.07-7.07l-1.72 1.71" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" fill="none"/>
@@ -24950,8 +24952,9 @@ class FloatingBlock {
24950
24952
  throw new Error("sessionId is required");
24951
24953
  }
24952
24954
  this.options = {
24953
- qrCodeUrl: options.qrCodeUrl || "https://ai.opentiny.design/next-remoter",
24954
- ...options
24955
+ ...options,
24956
+ qrCodeUrl: options.qrCodeUrl || DEFAULT_QR_CODE_URL,
24957
+ remoteUrl: options.remoteUrl || DEFAULT_REMOTE_URL
24955
24958
  };
24956
24959
  this.menuItems = this.mergeMenuItems(options.menuItems);
24957
24960
  this.init();
@@ -24995,7 +24998,7 @@ class FloatingBlock {
24995
24998
  this.floatingBlock.className = "tiny-remoter-floating-block";
24996
24999
  this.floatingBlock.innerHTML = `
24997
25000
  <div class="tiny-remoter-floating-block__icon">
24998
- <img style="display: block; width: 56px;" src="https://ai.opentiny.design/next-remoter/svgs/logo-next-no-bg-left.svg" alt="icon" />
25001
+ <img style="display: block; width: 56px;" src="${DEFAULT_QR_CODE_URL}/svgs/logo-next-no-bg-left.svg" alt="icon" />
24999
25002
  </div>
25000
25003
  `;
25001
25004
  document.body.appendChild(this.floatingBlock);
@@ -25095,7 +25098,7 @@ class FloatingBlock {
25095
25098
  this.copyToClipboard(this.options.sessionId.slice(-6));
25096
25099
  }
25097
25100
  copyRemoteURL() {
25098
- this.copyToClipboard((this.options.qrCodeUrl || "") + this.sessionPrefix + this.options.sessionId);
25101
+ this.copyToClipboard(this.options.remoteUrl + this.sessionPrefix + this.options.sessionId);
25099
25102
  }
25100
25103
  // 实现复制到剪贴板功能
25101
25104
  async copyToClipboard(text2) {
@@ -42810,7 +42813,6 @@ class AgentModelProvider {
42810
42813
  this.mcpClients = [];
42811
42814
  this.mcpTools = [];
42812
42815
  this.ignoreToolnames = [];
42813
- this.autoUpdateTools = true;
42814
42816
  this.messages = [];
42815
42817
  this.mcpServers = mcpServers || [];
42816
42818
  if (llm) {
@@ -42839,7 +42841,9 @@ class AgentModelProvider {
42839
42841
  } else {
42840
42842
  transport = serverConfig;
42841
42843
  }
42842
- return await createMCPClient({ transport });
42844
+ const client = await createMCPClient({ transport });
42845
+ client["__transport__"] = transport;
42846
+ return client;
42843
42847
  } catch (error2) {
42844
42848
  if (this.onError) {
42845
42849
  this.onError((error2 == null ? void 0 : error2.message) || `Failed to create MCP client`, error2);
@@ -42848,6 +42852,13 @@ class AgentModelProvider {
42848
42852
  return null;
42849
42853
  }
42850
42854
  }
42855
+ /** 关闭一个client */
42856
+ async _closeOneClient(client) {
42857
+ var _a16, _b8, _c, _d, _e;
42858
+ await ((_b8 = (_a16 = client["__transport__"]) == null ? void 0 : _a16.terminateSession) == null ? void 0 : _b8.call(_a16));
42859
+ await ((_d = (_c = client["__transport__"]) == null ? void 0 : _c.close) == null ? void 0 : _d.call(_c));
42860
+ await ((_e = client == null ? void 0 : client.close) == null ? void 0 : _e.call(client));
42861
+ }
42851
42862
  /** 创建 ai-sdk的 mcpClient, 失败则保存为null */
42852
42863
  async _createMpcClients() {
42853
42864
  this.mcpClients = await Promise.all(
@@ -42878,7 +42889,7 @@ class AgentModelProvider {
42878
42889
  await Promise.all(
42879
42890
  this.mcpClients.map(async (client) => {
42880
42891
  try {
42881
- await client.close();
42892
+ await this._closeOneClient(client);
42882
42893
  } catch (error2) {
42883
42894
  if (this.onError) {
42884
42895
  this.onError((error2 == null ? void 0 : error2.message) || `Failed to close client`, error2);
@@ -42910,13 +42921,13 @@ class AgentModelProvider {
42910
42921
  return false;
42911
42922
  }
42912
42923
  /** 通过引用,删除一个 mcpServers mcpClients mcpTools ignoreToolnames */
42913
- removeMcpServer(mcpServer) {
42924
+ async removeMcpServer(mcpServer) {
42914
42925
  const index = this.mcpServers.findIndex((server) => server === mcpServer);
42915
42926
  this.mcpServers.splice(index, 1);
42916
42927
  const delClient = this.mcpClients[index];
42917
42928
  this.mcpClients.splice(index, 1);
42918
42929
  try {
42919
- delClient == null ? void 0 : delClient.close();
42930
+ await this._closeOneClient(delClient);
42920
42931
  } catch (error2) {
42921
42932
  }
42922
42933
  const delTool = this.mcpTools[index];
@@ -42928,7 +42939,7 @@ class AgentModelProvider {
42928
42939
  }
42929
42940
  }
42930
42941
  /** 创建临时允许调用的tools集合 */
42931
- tempMergeTools(extraTool = {}) {
42942
+ _tempMergeTools(extraTool = {}) {
42932
42943
  const toolsResult = this.mcpTools.reduce((acc, curr) => ({ ...acc, ...curr }), {});
42933
42944
  Object.assign(toolsResult, extraTool);
42934
42945
  this.ignoreToolnames.forEach((name16) => {
@@ -42941,16 +42952,14 @@ class AgentModelProvider {
42941
42952
  if (!this.llm) {
42942
42953
  throw new Error("LLM is not initialized");
42943
42954
  }
42944
- if (this.autoUpdateTools) {
42945
- await this._createMpcTools();
42946
- (_a16 = this.onUpdatedTools) == null ? void 0 : _a16.call(this);
42947
- }
42955
+ await this.initClientsAndTools();
42956
+ (_a16 = this.onUpdatedTools) == null ? void 0 : _a16.call(this);
42948
42957
  const chatOptions = {
42949
42958
  // @ts-ignore ProviderV2 是所有llm的父类, 在每一个具体的llm 类都有一个选择model的函数用法
42950
42959
  model: this.llm(model),
42951
42960
  stopWhen: stepCountIs(maxSteps),
42952
42961
  ...options,
42953
- tools: this.tempMergeTools(options.tools)
42962
+ tools: this._tempMergeTools(options.tools)
42954
42963
  };
42955
42964
  if (options.message && !options.messages) {
42956
42965
  this.messages.push({ role: "user", content: options.message });