@lobehub/chat 1.81.4 → 1.81.6

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 (120) hide show
  1. package/.eslintrc.js +1 -0
  2. package/.github/workflows/release.yml +5 -0
  3. package/.github/workflows/test.yml +5 -0
  4. package/CHANGELOG.md +50 -0
  5. package/changelog/v1.json +18 -0
  6. package/locales/ar/auth.json +1 -1
  7. package/locales/ar/hotkey.json +4 -0
  8. package/locales/ar/models.json +3 -0
  9. package/locales/bg-BG/auth.json +1 -1
  10. package/locales/bg-BG/hotkey.json +4 -0
  11. package/locales/bg-BG/models.json +3 -0
  12. package/locales/de-DE/auth.json +1 -1
  13. package/locales/de-DE/hotkey.json +4 -0
  14. package/locales/de-DE/models.json +3 -0
  15. package/locales/en-US/auth.json +1 -1
  16. package/locales/en-US/hotkey.json +4 -0
  17. package/locales/en-US/models.json +3 -0
  18. package/locales/es-ES/auth.json +1 -1
  19. package/locales/es-ES/hotkey.json +4 -0
  20. package/locales/es-ES/models.json +3 -0
  21. package/locales/fa-IR/auth.json +1 -1
  22. package/locales/fa-IR/hotkey.json +4 -0
  23. package/locales/fa-IR/models.json +3 -0
  24. package/locales/fr-FR/auth.json +1 -1
  25. package/locales/fr-FR/hotkey.json +4 -0
  26. package/locales/fr-FR/models.json +3 -0
  27. package/locales/it-IT/auth.json +1 -1
  28. package/locales/it-IT/hotkey.json +4 -0
  29. package/locales/it-IT/models.json +3 -0
  30. package/locales/ja-JP/auth.json +1 -1
  31. package/locales/ja-JP/hotkey.json +4 -0
  32. package/locales/ja-JP/models.json +3 -0
  33. package/locales/ko-KR/auth.json +1 -1
  34. package/locales/ko-KR/hotkey.json +4 -0
  35. package/locales/ko-KR/models.json +3 -0
  36. package/locales/nl-NL/auth.json +1 -1
  37. package/locales/nl-NL/hotkey.json +4 -0
  38. package/locales/nl-NL/models.json +3 -0
  39. package/locales/pl-PL/auth.json +1 -1
  40. package/locales/pl-PL/hotkey.json +4 -0
  41. package/locales/pl-PL/models.json +3 -0
  42. package/locales/pt-BR/auth.json +1 -1
  43. package/locales/pt-BR/hotkey.json +4 -0
  44. package/locales/pt-BR/models.json +3 -0
  45. package/locales/ru-RU/auth.json +1 -1
  46. package/locales/ru-RU/hotkey.json +4 -0
  47. package/locales/ru-RU/models.json +3 -0
  48. package/locales/tr-TR/auth.json +1 -1
  49. package/locales/tr-TR/hotkey.json +4 -0
  50. package/locales/tr-TR/models.json +3 -0
  51. package/locales/vi-VN/auth.json +1 -1
  52. package/locales/vi-VN/hotkey.json +4 -0
  53. package/locales/vi-VN/models.json +3 -0
  54. package/locales/zh-CN/auth.json +1 -1
  55. package/locales/zh-CN/changelog.json +1 -1
  56. package/locales/zh-CN/clerk.json +1 -1
  57. package/locales/zh-CN/discover.json +1 -1
  58. package/locales/zh-CN/file.json +1 -1
  59. package/locales/zh-CN/hotkey.json +4 -0
  60. package/locales/zh-CN/knowledgeBase.json +1 -1
  61. package/locales/zh-CN/metadata.json +1 -1
  62. package/locales/zh-CN/migration.json +1 -1
  63. package/locales/zh-CN/models.json +3 -0
  64. package/locales/zh-CN/ragEval.json +1 -1
  65. package/locales/zh-CN/thread.json +1 -1
  66. package/locales/zh-CN/welcome.json +1 -1
  67. package/locales/zh-TW/auth.json +1 -1
  68. package/locales/zh-TW/hotkey.json +4 -0
  69. package/locales/zh-TW/models.json +3 -0
  70. package/package.json +6 -4
  71. package/packages/file-loaders/README.md +63 -0
  72. package/packages/file-loaders/package.json +42 -0
  73. package/packages/file-loaders/src/index.ts +2 -0
  74. package/packages/file-loaders/src/loadFile.ts +206 -0
  75. package/packages/file-loaders/src/loaders/docx/__snapshots__/index.test.ts.snap +74 -0
  76. package/packages/file-loaders/src/loaders/docx/fixtures/test.docx +0 -0
  77. package/packages/file-loaders/src/loaders/docx/index.test.ts +41 -0
  78. package/packages/file-loaders/src/loaders/docx/index.ts +73 -0
  79. package/packages/file-loaders/src/loaders/excel/__snapshots__/index.test.ts.snap +58 -0
  80. package/packages/file-loaders/src/loaders/excel/fixtures/test.xlsx +0 -0
  81. package/packages/file-loaders/src/loaders/excel/index.test.ts +47 -0
  82. package/packages/file-loaders/src/loaders/excel/index.ts +121 -0
  83. package/packages/file-loaders/src/loaders/index.ts +19 -0
  84. package/packages/file-loaders/src/loaders/pdf/__snapshots__/index.test.ts.snap +98 -0
  85. package/packages/file-loaders/src/loaders/pdf/index.test.ts +49 -0
  86. package/packages/file-loaders/src/loaders/pdf/index.ts +133 -0
  87. package/packages/file-loaders/src/loaders/pptx/__snapshots__/index.test.ts.snap +40 -0
  88. package/packages/file-loaders/src/loaders/pptx/fixtures/test.pptx +0 -0
  89. package/packages/file-loaders/src/loaders/pptx/index.test.ts +47 -0
  90. package/packages/file-loaders/src/loaders/pptx/index.ts +186 -0
  91. package/packages/file-loaders/src/loaders/text/__snapshots__/index.test.ts.snap +15 -0
  92. package/packages/file-loaders/src/loaders/text/fixtures/test.txt +2 -0
  93. package/packages/file-loaders/src/loaders/text/index.test.ts +38 -0
  94. package/packages/file-loaders/src/loaders/text/index.ts +53 -0
  95. package/packages/file-loaders/src/types.ts +200 -0
  96. package/packages/file-loaders/src/utils/isTextReadableFile.ts +68 -0
  97. package/packages/file-loaders/src/utils/parser-utils.ts +112 -0
  98. package/packages/file-loaders/test/__snapshots__/loaders.test.ts.snap +93 -0
  99. package/packages/file-loaders/test/fixtures/test.csv +4 -0
  100. package/packages/file-loaders/test/fixtures/test.docx +0 -0
  101. package/packages/file-loaders/test/fixtures/test.epub +0 -0
  102. package/packages/file-loaders/test/fixtures/test.md +3 -0
  103. package/packages/file-loaders/test/fixtures/test.pptx +0 -0
  104. package/packages/file-loaders/test/fixtures/test.txt +3 -0
  105. package/packages/file-loaders/test/loaders.test.ts +39 -0
  106. package/src/config/aiModels/github.ts +2 -4
  107. package/src/config/aiModels/google.ts +3 -4
  108. package/src/config/aiModels/sensenova.ts +4 -5
  109. package/src/const/hotkeys.ts +6 -0
  110. package/src/features/ChatInput/ActionBar/Clear.tsx +18 -8
  111. package/src/hooks/useHotkeys/chatScope.ts +7 -0
  112. package/src/libs/agent-runtime/google/index.ts +1 -1
  113. package/src/libs/agent-runtime/sensenova/index.ts +20 -27
  114. package/src/libs/agent-runtime/utils/sensenovaHelpers.test.ts +24 -33
  115. package/src/libs/agent-runtime/utils/sensenovaHelpers.ts +2 -3
  116. package/src/locales/default/hotkey.ts +4 -0
  117. package/src/server/modules/MCPClient/__tests__/__snapshots__/index.test.ts.snap +113 -0
  118. package/src/server/modules/MCPClient/__tests__/index.test.ts +81 -0
  119. package/src/server/modules/MCPClient/index.ts +80 -0
  120. package/src/types/hotkey.ts +1 -0
@@ -1,5 +1,4 @@
1
1
  export const convertSenseNovaMessage = (content: any) => {
2
-
3
2
  // 如果为单条 string 类 content,则格式转换为 text 类
4
3
  if (typeof content === 'string') {
5
4
  return [{ text: content, type: 'text' }];
@@ -16,8 +15,8 @@ export const convertSenseNovaMessage = (content: any) => {
16
15
  const url = item.image_url.url;
17
16
 
18
17
  // 如果 image_url 为 base64 格式,则返回 image_base64 类,否则返回 image_url 类
19
- return url.startsWith('data:image/jpeg;base64')
20
- ? {
18
+ return url.startsWith('data:image/jpeg;base64')
19
+ ? {
21
20
  image_base64: url.split(',')[1],
22
21
  type: 'image_base64',
23
22
  }
@@ -5,6 +5,10 @@ const hotkey: HotkeyI18nTranslations = {
5
5
  desc: '将当前输入内容添加为用户消息,但不触发生成',
6
6
  title: '添加一条用户消息',
7
7
  },
8
+ clearCurrentMessages: {
9
+ desc: '清空当前会话的消息和上传的文件',
10
+ title: '清空会话消息',
11
+ },
8
12
  editMessage: {
9
13
  desc: '通过按住 Alt 并双击消息进入编辑模式',
10
14
  title: '编辑消息',
@@ -0,0 +1,113 @@
1
+ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
2
+
3
+ exports[`MCPClient > Stdio Transport (using SDK Mock Server) > should list tools via stdio 1`] = `
4
+ [
5
+ {
6
+ "description": "Echoes back a message with 'Hello' prefix",
7
+ "inputSchema": {
8
+ "$schema": "http://json-schema.org/draft-07/schema#",
9
+ "additionalProperties": false,
10
+ "properties": {
11
+ "message": {
12
+ "description": "The message to echo",
13
+ "type": "string",
14
+ },
15
+ },
16
+ "required": [
17
+ "message",
18
+ ],
19
+ "type": "object",
20
+ },
21
+ "name": "echo",
22
+ },
23
+ {
24
+ "description": "Lists all available tools and methods",
25
+ "inputSchema": {
26
+ "$schema": "http://json-schema.org/draft-07/schema#",
27
+ "additionalProperties": false,
28
+ "properties": {},
29
+ "type": "object",
30
+ },
31
+ "name": "debug",
32
+ },
33
+ {
34
+ "description": "Adds two numbers",
35
+ "inputSchema": {
36
+ "$schema": "http://json-schema.org/draft-07/schema#",
37
+ "additionalProperties": false,
38
+ "properties": {
39
+ "a": {
40
+ "description": "The first number",
41
+ "type": "number",
42
+ },
43
+ "b": {
44
+ "description": "The second number",
45
+ "type": "number",
46
+ },
47
+ },
48
+ "required": [
49
+ "a",
50
+ "b",
51
+ ],
52
+ "type": "object",
53
+ },
54
+ "name": "add",
55
+ },
56
+ ]
57
+ `;
58
+
59
+ exports[`MCPClient > Stdio Transport > should list tools via stdio 1`] = `
60
+ [
61
+ {
62
+ "description": "Echoes back a message with 'Hello' prefix",
63
+ "inputSchema": {
64
+ "$schema": "http://json-schema.org/draft-07/schema#",
65
+ "additionalProperties": false,
66
+ "properties": {
67
+ "message": {
68
+ "description": "The message to echo",
69
+ "type": "string",
70
+ },
71
+ },
72
+ "required": [
73
+ "message",
74
+ ],
75
+ "type": "object",
76
+ },
77
+ "name": "echo",
78
+ },
79
+ {
80
+ "description": "Lists all available tools and methods",
81
+ "inputSchema": {
82
+ "$schema": "http://json-schema.org/draft-07/schema#",
83
+ "additionalProperties": false,
84
+ "properties": {},
85
+ "type": "object",
86
+ },
87
+ "name": "debug",
88
+ },
89
+ {
90
+ "description": "Adds two numbers",
91
+ "inputSchema": {
92
+ "$schema": "http://json-schema.org/draft-07/schema#",
93
+ "additionalProperties": false,
94
+ "properties": {
95
+ "a": {
96
+ "description": "The first number",
97
+ "type": "number",
98
+ },
99
+ "b": {
100
+ "description": "The second number",
101
+ "type": "number",
102
+ },
103
+ },
104
+ "required": [
105
+ "a",
106
+ "b",
107
+ ],
108
+ "type": "object",
109
+ },
110
+ "name": "add",
111
+ },
112
+ ]
113
+ `;
@@ -0,0 +1,81 @@
1
+ import { afterEach, beforeEach, describe, expect, it } from 'vitest';
2
+
3
+ import { MCPClient } from '../index';
4
+
5
+ describe('MCPClient', () => {
6
+ // --- Updated Stdio Transport tests ---
7
+ describe('Stdio Transport', () => {
8
+ let mcpClient: MCPClient;
9
+ const stdioConnection = {
10
+ id: 'mcp-hello-world',
11
+ name: 'Stdio SDK Test Connection',
12
+ type: 'stdio' as const,
13
+ command: 'npx', // Use node to run the compiled mock server
14
+ args: ['mcp-hello-world@1.1.2'], // Use the path to the compiled JS file
15
+ };
16
+
17
+ beforeEach(async () => {
18
+ // args are now set directly in the connection object
19
+ mcpClient = new MCPClient(stdioConnection);
20
+ // Initialize the client - this starts the stdio process
21
+ await mcpClient.initialize();
22
+ // Add a small delay to allow the server process to fully start (optional, but can help)
23
+ await new Promise((resolve) => setTimeout(resolve, 100));
24
+ });
25
+
26
+ afterEach(async () => {
27
+ // Assume SDK client/transport handles process termination gracefully
28
+ // If processes leak, more explicit cleanup might be needed here
29
+ });
30
+
31
+ it('should create and initialize an instance with stdio transport', () => {
32
+ expect(mcpClient).toBeInstanceOf(MCPClient);
33
+ });
34
+
35
+ it('should list tools via stdio', async () => {
36
+ const result = await mcpClient.listTools();
37
+
38
+ // Check exact length if no other tools are expected
39
+ expect(result.tools).toHaveLength(3);
40
+
41
+ // Expect the tools defined in mock-sdk-server.ts
42
+ expect(result.tools).toMatchSnapshot();
43
+ });
44
+
45
+ it('should call the "echo" tool via stdio', async () => {
46
+ const toolName = 'echo';
47
+ const toolArgs = { message: 'hello stdio' };
48
+ // Expect the result format defined in mock-sdk-server.ts
49
+ const expectedResult = {
50
+ content: [{ type: 'text', text: 'You said: hello stdio' }],
51
+ };
52
+
53
+ const result = await mcpClient.callTool(toolName, toolArgs);
54
+ expect(result).toEqual(expectedResult);
55
+ });
56
+
57
+ it('should call the "add" tool via stdio', async () => {
58
+ const toolName = 'add';
59
+ const toolArgs = { a: 5, b: 7 };
60
+
61
+ const result = await mcpClient.callTool(toolName, toolArgs);
62
+ expect(result).toEqual({
63
+ content: [{ type: 'text', text: 'The sum is: 12' }],
64
+ });
65
+ });
66
+ });
67
+
68
+ // Error Handling tests remain the same...
69
+ describe('Error Handling', () => {
70
+ it('should throw error for unsupported connection type', () => {
71
+ const connection = {
72
+ id: 'invalid-test',
73
+ name: 'Invalid Test Connection',
74
+ type: 'invalid' as any,
75
+ };
76
+ expect(() => new MCPClient(connection as any)).toThrow(
77
+ 'Unsupported MCP connection type: invalid',
78
+ );
79
+ });
80
+ });
81
+ });
@@ -0,0 +1,80 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js';
4
+ import type { Transport } from '@modelcontextprotocol/sdk/shared/transport.d.ts';
5
+ import debug from 'debug';
6
+
7
+ const log = debug('lobe-mcp:client');
8
+
9
+ interface MCPConnectionBase {
10
+ id: string;
11
+ name: string;
12
+ type: 'http' | 'stdio';
13
+ }
14
+
15
+ interface HttpMCPConnection extends MCPConnectionBase {
16
+ type: 'http';
17
+ url: string;
18
+ }
19
+
20
+ interface StdioMCPConnection extends MCPConnectionBase {
21
+ args: string[];
22
+ command: string;
23
+ type: 'stdio';
24
+ }
25
+ type MCPConnection = HttpMCPConnection | StdioMCPConnection;
26
+
27
+ export class MCPClient {
28
+ private mcp: Client;
29
+ private transport: Transport;
30
+
31
+ constructor(connection: MCPConnection) {
32
+ log('Creating MCPClient with connection: %O', connection);
33
+ this.mcp = new Client({ name: 'lobehub-mcp-client', version: '1.0.0' });
34
+
35
+ switch (connection.type) {
36
+ case 'http': {
37
+ log('Using HTTP transport with url: %s', connection.url);
38
+ this.transport = new StreamableHTTPClientTransport(new URL(connection.url));
39
+ break;
40
+ }
41
+ case 'stdio': {
42
+ log(
43
+ 'Using Stdio transport with command: %s and args: %O',
44
+ connection.command,
45
+ connection.args,
46
+ );
47
+ this.transport = new StdioClientTransport({
48
+ args: connection.args,
49
+ command: connection.command,
50
+ });
51
+ break;
52
+ }
53
+ default: {
54
+ const err = new Error(`Unsupported MCP connection type: ${(connection as any).type}`);
55
+ log('Error creating client: %O', err);
56
+ throw err;
57
+ }
58
+ }
59
+ }
60
+
61
+ async initialize() {
62
+ log('Initializing MCP connection...');
63
+ await this.mcp.connect(this.transport);
64
+ log('MCP connection initialized.');
65
+ }
66
+
67
+ async listTools() {
68
+ log('Listing tools...');
69
+ const tools = await this.mcp.listTools();
70
+ log('Listed tools: %O', tools);
71
+ return tools;
72
+ }
73
+
74
+ async callTool(toolName: string, args: any) {
75
+ log('Calling tool: %s with args: %O', toolName, args);
76
+ const result = await this.mcp.callTool({ arguments: args, name: toolName });
77
+ log('Tool call result: %O', result);
78
+ return result;
79
+ }
80
+ }
@@ -58,6 +58,7 @@ export const KeyEnum = {
58
58
 
59
59
  export const HotkeyEnum = {
60
60
  AddUserMessage: 'addUserMessage',
61
+ ClearCurrentMessages: 'clearCurrentMessages',
61
62
  EditMessage: 'editMessage',
62
63
  OpenChatSettings: 'openChatSettings',
63
64
  OpenHotkeyHelper: 'openHotkeyHelper',