@opentiny/next-sdk 0.2.9 → 0.2.10

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.
@@ -2,6 +2,7 @@ import { streamText, stepCountIs, generateText } from 'ai'
2
2
  import { MCPClientConfig, createMCPClient } from '@ai-sdk/mcp'
3
3
  import type { ToolSet } from 'ai'
4
4
  import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js'
5
+ import { SSEClientTransport } from '@modelcontextprotocol/sdk/client/sse.js'
5
6
  import { InMemoryTransport } from '@modelcontextprotocol/sdk/inMemory.js'
6
7
  import type { IAgentModelProviderOption, McpServerConfig } from './type'
7
8
  import { ProviderV2 } from '@ai-sdk/provider'
@@ -81,15 +82,21 @@ export class AgentModelProvider {
81
82
  private async _createOneClient(serverConfig: McpServerConfig) {
82
83
  try {
83
84
  let transport: MCPClientConfig['transport']
84
- // transport 一定是 streamableHttp 或者就是: ai-sdk允许的 transport
85
+ // transport 一定是 streamableHttp/sse 或者就是: ai-sdk允许的 transport
85
86
  if ('type' in serverConfig && serverConfig.type.toLocaleLowerCase() === 'streamablehttp') {
86
- transport = new StreamableHTTPClientTransport(new URL((serverConfig as { url: string }).url))
87
+ const configWithHeaders = serverConfig as { url: string; headers?: Record<string, string> }
88
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : undefined
89
+ transport = new StreamableHTTPClientTransport(new URL(configWithHeaders.url), { requestInit })
90
+ } else if ('type' in serverConfig && serverConfig.type === 'sse') {
91
+ const configWithHeaders = serverConfig as { url: string; headers?: Record<string, string> }
92
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : undefined
93
+ transport = new SSEClientTransport(new URL(configWithHeaders.url), { requestInit })
87
94
  } else if ('type' in serverConfig && serverConfig.type === 'extension') {
88
95
  transport = new ExtensionClientTransport(serverConfig.sessionId)
89
96
  } else if ('transport' in serverConfig) {
90
97
  transport = serverConfig.transport
91
98
  } else {
92
- transport = serverConfig as MCPClientConfig['transport']
99
+ transport = serverConfig as unknown as MCPClientConfig['transport']
93
100
  }
94
101
 
95
102
  // 根据 useAISdkClient 配置决定使用哪种 client 创建方式
package/agent/type.ts CHANGED
@@ -35,9 +35,9 @@ export type IAgentModelProviderLlmConfig = LlmFactoryConfig | LlmInstanceConfig
35
35
 
36
36
  /** Mcp Server的配置对象 */
37
37
  export type McpServerConfig =
38
- | { type: 'streamableHttp'; url: string; useAISdkClient?: boolean }
39
- | { type: 'sse'; url: string; useAISdkClient?: boolean }
40
- | { type: 'extension'; url: string; sessionId: string; useAISdkClient?: boolean }
38
+ | { type: 'streamableHttp'; url: string; useAISdkClient?: boolean; headers?: Record<string, string> }
39
+ | { type: 'sse'; url: string; useAISdkClient?: boolean; headers?: Record<string, string> }
40
+ | { type: 'extension'; url: string; sessionId: string; useAISdkClient?: boolean; headers?: Record<string, string> }
41
41
  | { type: 'local'; transport: MCPTransport; useAISdkClient?: boolean }
42
42
 
43
43
  /** */
@@ -32,15 +32,18 @@ export type McpServerConfig = {
32
32
  type: 'streamableHttp';
33
33
  url: string;
34
34
  useAISdkClient?: boolean;
35
+ headers?: Record<string, string>;
35
36
  } | {
36
37
  type: 'sse';
37
38
  url: string;
38
39
  useAISdkClient?: boolean;
40
+ headers?: Record<string, string>;
39
41
  } | {
40
42
  type: 'extension';
41
43
  url: string;
42
44
  sessionId: string;
43
45
  useAISdkClient?: boolean;
46
+ headers?: Record<string, string>;
44
47
  } | {
45
48
  type: 'local';
46
49
  transport: MCPTransport;
@@ -27069,27 +27069,27 @@ class FloatingBlock {
27069
27069
  }
27070
27070
  /**
27071
27071
  * 合并菜单项配置。
27072
- * - sessionId:使用默认菜单 + 用户配置(可定制每一项的 show/text/icon 等)
27073
- * - sessionId:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
27072
+ * - 用户明确传入 menuItems:直接使用用户配置,不受 sessionId 限制;未传 icon 时自动补充默认图标
27073
+ * - sessionId 且未传 menuItems:使用默认菜单
27074
+ * - 无 sessionId 且未传 menuItems:不渲染任何下拉菜单,仅保留点击浮标打开对话框的能力
27074
27075
  */
27075
27076
  mergeMenuItems(userMenuItems) {
27077
+ const defaultIcons = {
27078
+ "qr-code": qrCode,
27079
+ "ai-chat": chat,
27080
+ "remote-url": link,
27081
+ "remote-control": scan
27082
+ };
27083
+ if (userMenuItems) {
27084
+ return userMenuItems.map((item) => ({
27085
+ ...item,
27086
+ icon: item.icon ?? defaultIcons[item.action]
27087
+ }));
27088
+ }
27076
27089
  if (!this.options.sessionId) {
27077
27090
  return [];
27078
27091
  }
27079
- if (!userMenuItems) {
27080
- return getDefaultMenuItems(this.options);
27081
- }
27082
- return getDefaultMenuItems(this.options).map((defaultItem) => {
27083
- const userItem = userMenuItems.find((item) => item.action === defaultItem.action);
27084
- if (userItem) {
27085
- return {
27086
- ...defaultItem,
27087
- ...userItem,
27088
- show: userItem.show !== void 0 ? userItem.show : defaultItem.show
27089
- };
27090
- }
27091
- return defaultItem;
27092
- });
27092
+ return getDefaultMenuItems(this.options);
27093
27093
  }
27094
27094
  init() {
27095
27095
  this.createFloatingBlock();
@@ -27120,7 +27120,7 @@ class FloatingBlock {
27120
27120
  <div class="tiny-remoter-dropdown-item__content">
27121
27121
  <div title="${item.tip}">${item.text}</div>
27122
27122
  <div class="tiny-remoter-dropdown-item__desc-wrapper">
27123
- <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>
27123
+ <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>
27124
27124
  <div>
27125
27125
  ${item.showCopyIcon ? `
27126
27126
  <div class="tiny-remoter-copy-icon" id="${item.action}" data-action="${item.action}">
@@ -27228,12 +27228,20 @@ class FloatingBlock {
27228
27228
  this.closeDropdown();
27229
27229
  }
27230
27230
  copyRemoteControl() {
27231
- if (!this.options.sessionId) return;
27232
- this.copyToClipboard(this.options.sessionId.slice(-6));
27231
+ const menuItem = this.menuItems.find((item) => item.action === "remote-control");
27232
+ const codeToCopy = menuItem?.desc || menuItem?.text || (this.options.sessionId ? this.options.sessionId.slice(-6) : "");
27233
+ if (codeToCopy) {
27234
+ this.copyToClipboard(codeToCopy);
27235
+ }
27233
27236
  }
27234
27237
  copyRemoteURL() {
27235
- if (!this.options.sessionId) return;
27236
- this.copyToClipboard(this.options.remoteUrl + this.sessionPrefix + this.options.sessionId);
27238
+ const menuItem = this.menuItems.find((item) => item.action === "remote-url");
27239
+ const sessionUrl = this.options.sessionId ? this.options.remoteUrl + this.sessionPrefix + this.options.sessionId : "";
27240
+ const customDesc = menuItem?.desc && menuItem.desc !== this.options.remoteUrl ? menuItem.desc : void 0;
27241
+ const urlToCopy = customDesc || sessionUrl || menuItem?.text || "";
27242
+ if (urlToCopy) {
27243
+ this.copyToClipboard(urlToCopy);
27244
+ }
27237
27245
  }
27238
27246
  // 实现复制到剪贴板功能
27239
27247
  async copyToClipboard(text2) {
@@ -49629,7 +49637,13 @@ class AgentModelProvider {
49629
49637
  try {
49630
49638
  let transport;
49631
49639
  if ("type" in serverConfig && serverConfig.type.toLocaleLowerCase() === "streamablehttp") {
49632
- transport = new StreamableHTTPClientTransport(new URL(serverConfig.url));
49640
+ const configWithHeaders = serverConfig;
49641
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : void 0;
49642
+ transport = new StreamableHTTPClientTransport(new URL(configWithHeaders.url), { requestInit });
49643
+ } else if ("type" in serverConfig && serverConfig.type === "sse") {
49644
+ const configWithHeaders = serverConfig;
49645
+ const requestInit = configWithHeaders.headers ? { headers: configWithHeaders.headers } : void 0;
49646
+ transport = new SSEClientTransport(new URL(configWithHeaders.url), { requestInit });
49633
49647
  } else if ("type" in serverConfig && serverConfig.type === "extension") {
49634
49648
  transport = new ExtensionClientTransport(serverConfig.sessionId);
49635
49649
  } else if ("transport" in serverConfig) {