@lobehub/chat 1.26.8 → 1.26.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.
- package/CHANGELOG.md +42 -0
- package/package.json +1 -1
- package/src/features/ChatInput/useSend.ts +1 -1
- package/src/libs/langchain/file.ts +1 -0
- package/src/prompts/files/file.ts +15 -0
- package/src/prompts/files/image.ts +14 -0
- package/src/prompts/files/index.test.ts +117 -0
- package/src/prompts/files/index.ts +21 -0
- package/src/services/__tests__/chat.test.ts +98 -1
- package/src/services/chat.ts +7 -13
- package/src/store/chat/slices/aiChat/{action.test.ts → actions/__tests__/action.test.ts} +1 -1
- package/src/store/chat/slices/aiChat/{action.ts → actions/generateAIChat.ts} +6 -21
- package/src/store/chat/slices/aiChat/actions/index.ts +20 -0
- package/src/store/chat/store.ts +1 -1
- package/src/types/message/index.ts +12 -0
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,48 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.26.10](https://github.com/lobehub/lobe-chat/compare/v1.26.9...v1.26.10)
|
6
|
+
|
7
|
+
<sup>Released on **2024-10-29**</sup>
|
8
|
+
|
9
|
+
#### ♻ Code Refactoring
|
10
|
+
|
11
|
+
- **misc**: Refactor the aiChat slice actions.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Code refactoring
|
19
|
+
|
20
|
+
- **misc**: Refactor the aiChat slice actions, closes [#4542](https://github.com/lobehub/lobe-chat/issues/4542) ([8b33ba4](https://github.com/lobehub/lobe-chat/commit/8b33ba4))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
30
|
+
### [Version 1.26.9](https://github.com/lobehub/lobe-chat/compare/v1.26.8...v1.26.9)
|
31
|
+
|
32
|
+
<sup>Released on **2024-10-29**</sup>
|
33
|
+
|
34
|
+
<br/>
|
35
|
+
|
36
|
+
<details>
|
37
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
38
|
+
|
39
|
+
</details>
|
40
|
+
|
41
|
+
<div align="right">
|
42
|
+
|
43
|
+
[](#readme-top)
|
44
|
+
|
45
|
+
</div>
|
46
|
+
|
5
47
|
### [Version 1.26.8](https://github.com/lobehub/lobe-chat/compare/v1.26.7...v1.26.8)
|
6
48
|
|
7
49
|
<sup>Released on **2024-10-29**</sup>
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.26.
|
3
|
+
"version": "1.26.10",
|
4
4
|
"description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
|
5
5
|
"keywords": [
|
6
6
|
"framework",
|
@@ -2,8 +2,8 @@ import { useCallback, useMemo } from 'react';
|
|
2
2
|
|
3
3
|
import { useChatStore } from '@/store/chat';
|
4
4
|
import { chatSelectors } from '@/store/chat/selectors';
|
5
|
-
import { SendMessageParams } from '@/store/chat/slices/aiChat/action';
|
6
5
|
import { fileChatSelectors, useFileStore } from '@/store/file';
|
6
|
+
import { SendMessageParams } from '@/types/message';
|
7
7
|
|
8
8
|
export type UseSendMessageParams = Pick<
|
9
9
|
SendMessageParams,
|
@@ -0,0 +1,15 @@
|
|
1
|
+
import { ChatFileItem } from '@/types/message';
|
2
|
+
|
3
|
+
const filePrompt = (item: ChatFileItem) =>
|
4
|
+
`<file id="${item.id}" name="${item.name}" type="${item.fileType}" size="${item.size}" url="${item.url}"></file>`;
|
5
|
+
|
6
|
+
export const filePrompts = (fileList: ChatFileItem[]) => {
|
7
|
+
if (fileList.length === 0) return '';
|
8
|
+
|
9
|
+
const prompt = `<files>
|
10
|
+
<files_docstring>here are user upload files you can refer to</files_docstring>
|
11
|
+
${fileList.map((item) => filePrompt(item)).join('\n')}
|
12
|
+
</files>`;
|
13
|
+
|
14
|
+
return prompt.trim();
|
15
|
+
};
|
@@ -0,0 +1,14 @@
|
|
1
|
+
import { ChatImageItem } from '@/types/message';
|
2
|
+
|
3
|
+
const imagePrompt = (item: ChatImageItem) => `<image name="${item.alt}" url="${item.url}"></image>`;
|
4
|
+
|
5
|
+
export const imagesPrompts = (imageList: ChatImageItem[]) => {
|
6
|
+
if (imageList.length === 0) return '';
|
7
|
+
|
8
|
+
const prompt = `<images>
|
9
|
+
<images_docstring>here are user upload images you can refer to</images_docstring>
|
10
|
+
${imageList.map((item) => imagePrompt(item)).join('\n')}
|
11
|
+
</images>`;
|
12
|
+
|
13
|
+
return prompt.trim();
|
14
|
+
};
|
@@ -0,0 +1,117 @@
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
2
|
+
|
3
|
+
import { ChatFileItem, ChatImageItem } from '@/types/message';
|
4
|
+
|
5
|
+
import { filesPrompts } from './index';
|
6
|
+
|
7
|
+
describe('filesPrompts', () => {
|
8
|
+
// 创建测试用的示例数据
|
9
|
+
const mockImage: ChatImageItem = {
|
10
|
+
id: 'img-1',
|
11
|
+
alt: 'test image',
|
12
|
+
url: 'https://example.com/image.jpg',
|
13
|
+
};
|
14
|
+
|
15
|
+
const mockFile: ChatFileItem = {
|
16
|
+
id: 'file-1',
|
17
|
+
name: 'test.pdf',
|
18
|
+
fileType: 'application/pdf',
|
19
|
+
size: 1024,
|
20
|
+
url: 'https://example.com/test.pdf',
|
21
|
+
};
|
22
|
+
|
23
|
+
it('should generate prompt with only images', () => {
|
24
|
+
const result = filesPrompts({
|
25
|
+
imageList: [mockImage],
|
26
|
+
fileList: undefined,
|
27
|
+
});
|
28
|
+
|
29
|
+
expect(result).toEqual(
|
30
|
+
`<files_info>
|
31
|
+
<images>
|
32
|
+
<images_docstring>here are user upload images you can refer to</images_docstring>
|
33
|
+
<image name="test image" url="https://example.com/image.jpg"></image>
|
34
|
+
</images>
|
35
|
+
|
36
|
+
</files_info>`,
|
37
|
+
);
|
38
|
+
});
|
39
|
+
|
40
|
+
it('should generate prompt with only files', () => {
|
41
|
+
const result = filesPrompts({
|
42
|
+
imageList: [],
|
43
|
+
fileList: [mockFile],
|
44
|
+
});
|
45
|
+
|
46
|
+
expect(result).toEqual(
|
47
|
+
`<files_info>
|
48
|
+
|
49
|
+
<files>
|
50
|
+
<files_docstring>here are user upload files you can refer to</files_docstring>
|
51
|
+
<file id="file-1" name="test.pdf" type="application/pdf" size="1024" url="https://example.com/test.pdf"></file>
|
52
|
+
</files>
|
53
|
+
</files_info>`,
|
54
|
+
);
|
55
|
+
});
|
56
|
+
|
57
|
+
it('should generate prompt with both images and files', () => {
|
58
|
+
const result = filesPrompts({
|
59
|
+
imageList: [mockImage],
|
60
|
+
fileList: [mockFile],
|
61
|
+
});
|
62
|
+
|
63
|
+
expect(result).toEqual(
|
64
|
+
`<files_info>
|
65
|
+
<images>
|
66
|
+
<images_docstring>here are user upload images you can refer to</images_docstring>
|
67
|
+
<image name="test image" url="https://example.com/image.jpg"></image>
|
68
|
+
</images>
|
69
|
+
<files>
|
70
|
+
<files_docstring>here are user upload files you can refer to</files_docstring>
|
71
|
+
<file id="file-1" name="test.pdf" type="application/pdf" size="1024" url="https://example.com/test.pdf"></file>
|
72
|
+
</files>
|
73
|
+
</files_info>`,
|
74
|
+
);
|
75
|
+
});
|
76
|
+
|
77
|
+
it('should generate prompt with empty lists', () => {
|
78
|
+
const result = filesPrompts({
|
79
|
+
imageList: [],
|
80
|
+
fileList: [],
|
81
|
+
});
|
82
|
+
|
83
|
+
expect(result).toEqual('');
|
84
|
+
});
|
85
|
+
|
86
|
+
it('should handle multiple images and files', () => {
|
87
|
+
const images: ChatImageItem[] = [
|
88
|
+
mockImage,
|
89
|
+
{
|
90
|
+
id: 'img-2',
|
91
|
+
alt: 'second image',
|
92
|
+
url: 'https://example.com/image2.jpg',
|
93
|
+
},
|
94
|
+
];
|
95
|
+
|
96
|
+
const files: ChatFileItem[] = [
|
97
|
+
mockFile,
|
98
|
+
{
|
99
|
+
id: 'file-2',
|
100
|
+
name: 'document.docx',
|
101
|
+
fileType: 'application/docx',
|
102
|
+
size: 2048,
|
103
|
+
url: 'https://example.com/document.docx',
|
104
|
+
},
|
105
|
+
];
|
106
|
+
|
107
|
+
const result = filesPrompts({
|
108
|
+
imageList: images,
|
109
|
+
fileList: files,
|
110
|
+
});
|
111
|
+
|
112
|
+
expect(result).toContain('second image');
|
113
|
+
expect(result).toContain('document.docx');
|
114
|
+
expect(result).toMatch(/<image.*?>.*<image.*?>/s); // Check for multiple image tags
|
115
|
+
expect(result).toMatch(/<file.*?>.*<file.*?>/s); // Check for multiple file tags
|
116
|
+
});
|
117
|
+
});
|
@@ -0,0 +1,21 @@
|
|
1
|
+
import { ChatFileItem, ChatImageItem } from '@/types/message';
|
2
|
+
|
3
|
+
import { filePrompts } from './file';
|
4
|
+
import { imagesPrompts } from './image';
|
5
|
+
|
6
|
+
export const filesPrompts = ({
|
7
|
+
imageList,
|
8
|
+
fileList,
|
9
|
+
}: {
|
10
|
+
fileList?: ChatFileItem[];
|
11
|
+
imageList: ChatImageItem[];
|
12
|
+
}) => {
|
13
|
+
if (imageList.length === 0 && (fileList || []).length === 0) return '';
|
14
|
+
|
15
|
+
const prompt = `<files_info>
|
16
|
+
${imagesPrompts(imageList)}
|
17
|
+
${fileList ? filePrompts(fileList) : ''}
|
18
|
+
</files_info>`;
|
19
|
+
|
20
|
+
return prompt.trim();
|
21
|
+
};
|
@@ -126,6 +126,92 @@ describe('ChatService', () => {
|
|
126
126
|
);
|
127
127
|
});
|
128
128
|
|
129
|
+
describe('handle with files content', () => {
|
130
|
+
it('should includes files', async () => {
|
131
|
+
const messages = [
|
132
|
+
{
|
133
|
+
content: 'Hello',
|
134
|
+
role: 'user',
|
135
|
+
imageList: [
|
136
|
+
{
|
137
|
+
id: 'imagecx1',
|
138
|
+
url: 'http://example.com/xxx0asd-dsd.png',
|
139
|
+
alt: 'ttt.png',
|
140
|
+
},
|
141
|
+
],
|
142
|
+
fileList: [
|
143
|
+
{
|
144
|
+
fileType: 'plain/txt',
|
145
|
+
size: 100000,
|
146
|
+
id: 'file1',
|
147
|
+
url: 'http://abc.com/abc.txt',
|
148
|
+
name: 'abc.png',
|
149
|
+
},
|
150
|
+
{
|
151
|
+
id: 'file_oKMve9qySLMI',
|
152
|
+
name: '2402.16667v1.pdf',
|
153
|
+
type: 'application/pdf',
|
154
|
+
size: 11256078,
|
155
|
+
url: 'https://xxx.com/ppp/480497/5826c2b8-fde0-4de1-a54b-a224d5e3d898.pdf',
|
156
|
+
},
|
157
|
+
],
|
158
|
+
}, // Message with files
|
159
|
+
{ content: 'Hi', role: 'tool', plugin: { identifier: 'plugin1', apiName: 'api1' } }, // Message with tool role
|
160
|
+
{ content: 'Hey', role: 'assistant' }, // Regular user message
|
161
|
+
] as ChatMessage[];
|
162
|
+
|
163
|
+
const getChatCompletionSpy = vi.spyOn(chatService, 'getChatCompletion');
|
164
|
+
await chatService.createAssistantMessage({
|
165
|
+
messages,
|
166
|
+
plugins: [],
|
167
|
+
model: 'gpt-4o',
|
168
|
+
});
|
169
|
+
|
170
|
+
expect(getChatCompletionSpy).toHaveBeenCalledWith(
|
171
|
+
{
|
172
|
+
messages: [
|
173
|
+
{
|
174
|
+
content: [
|
175
|
+
{
|
176
|
+
text: `Hello
|
177
|
+
|
178
|
+
<files_info>
|
179
|
+
<images>
|
180
|
+
<images_docstring>here are user upload images you can refer to</images_docstring>
|
181
|
+
<image name="ttt.png" url="http://example.com/xxx0asd-dsd.png"></image>
|
182
|
+
</images>
|
183
|
+
<files>
|
184
|
+
<files_docstring>here are user upload files you can refer to</files_docstring>
|
185
|
+
<file id="file1" name="abc.png" type="plain/txt" size="100000" url="http://abc.com/abc.txt"></file>
|
186
|
+
<file id="file_oKMve9qySLMI" name="2402.16667v1.pdf" type="undefined" size="11256078" url="https://xxx.com/ppp/480497/5826c2b8-fde0-4de1-a54b-a224d5e3d898.pdf"></file>
|
187
|
+
</files>
|
188
|
+
</files_info>`,
|
189
|
+
type: 'text',
|
190
|
+
},
|
191
|
+
{
|
192
|
+
image_url: { detail: 'auto', url: 'http://example.com/xxx0asd-dsd.png' },
|
193
|
+
type: 'image_url',
|
194
|
+
},
|
195
|
+
],
|
196
|
+
role: 'user',
|
197
|
+
},
|
198
|
+
{
|
199
|
+
content: 'Hi',
|
200
|
+
name: 'plugin1____api1',
|
201
|
+
role: 'tool',
|
202
|
+
},
|
203
|
+
{
|
204
|
+
content: 'Hey',
|
205
|
+
role: 'assistant',
|
206
|
+
},
|
207
|
+
],
|
208
|
+
model: 'gpt-4o',
|
209
|
+
},
|
210
|
+
undefined,
|
211
|
+
);
|
212
|
+
});
|
213
|
+
});
|
214
|
+
|
129
215
|
describe('should handle content correctly for vision models', () => {
|
130
216
|
it('should include image content when with vision model', async () => {
|
131
217
|
const messages = [
|
@@ -156,7 +242,18 @@ describe('ChatService', () => {
|
|
156
242
|
messages: [
|
157
243
|
{
|
158
244
|
content: [
|
159
|
-
{
|
245
|
+
{
|
246
|
+
text: `Hello
|
247
|
+
|
248
|
+
<files_info>
|
249
|
+
<images>
|
250
|
+
<images_docstring>here are user upload images you can refer to</images_docstring>
|
251
|
+
<image name="abc.png" url="http://example.com/image.jpg"></image>
|
252
|
+
</images>
|
253
|
+
|
254
|
+
</files_info>`,
|
255
|
+
type: 'text',
|
256
|
+
},
|
160
257
|
{
|
161
258
|
image_url: { detail: 'auto', url: 'http://example.com/image.jpg' },
|
162
259
|
type: 'image_url',
|
package/src/services/chat.ts
CHANGED
@@ -8,6 +8,7 @@ import { INBOX_SESSION_ID } from '@/const/session';
|
|
8
8
|
import { DEFAULT_AGENT_CONFIG } from '@/const/settings';
|
9
9
|
import { TracePayload, TraceTagMap } from '@/const/trace';
|
10
10
|
import { AgentRuntime, ChatCompletionErrorPayload, ModelProvider } from '@/libs/agent-runtime';
|
11
|
+
import { filesPrompts } from '@/prompts/files';
|
11
12
|
import { useSessionStore } from '@/store/session';
|
12
13
|
import { sessionMetaSelectors } from '@/store/session/selectors';
|
13
14
|
import { useToolStore } from '@/store/tool';
|
@@ -413,22 +414,15 @@ class ChatService {
|
|
413
414
|
// for the models with visual ability, add image url to content
|
414
415
|
// refs: https://platform.openai.com/docs/guides/vision/quick-start
|
415
416
|
const getContent = (m: ChatMessage) => {
|
416
|
-
if
|
417
|
-
|
418
|
-
const imageList = m.imageList;
|
419
|
-
|
420
|
-
if (imageList.length === 0) return m.content;
|
421
|
-
|
422
|
-
const canUploadFile = modelProviderSelectors.isModelEnabledUpload(model)(
|
423
|
-
useUserStore.getState(),
|
424
|
-
);
|
425
|
-
|
426
|
-
if (!canUploadFile) {
|
417
|
+
// only if message doesn't have images and files, then return the plain content
|
418
|
+
if ((!m.imageList || m.imageList.length === 0) && (!m.fileList || m.fileList.length === 0))
|
427
419
|
return m.content;
|
428
|
-
}
|
429
420
|
|
421
|
+
const imageList = m.imageList || [];
|
422
|
+
|
423
|
+
const filesContext = filesPrompts({ fileList: m.fileList, imageList });
|
430
424
|
return [
|
431
|
-
{ text: m.content, type: 'text' },
|
425
|
+
{ text: (m.content + '\n\n' + filesContext).trim(), type: 'text' },
|
432
426
|
...imageList.map(
|
433
427
|
(i) => ({ image_url: { detail: 'auto', url: i.url }, type: 'image_url' }) as const,
|
434
428
|
),
|
@@ -14,7 +14,7 @@ import { sessionMetaSelectors } from '@/store/session/selectors';
|
|
14
14
|
import { UploadFileItem } from '@/types/files/upload';
|
15
15
|
import { ChatMessage } from '@/types/message';
|
16
16
|
|
17
|
-
import { useChatStore } from '
|
17
|
+
import { useChatStore } from '../../../../store';
|
18
18
|
|
19
19
|
vi.stubGlobal(
|
20
20
|
'fetch',
|
@@ -16,27 +16,14 @@ import { chatHelpers } from '@/store/chat/helpers';
|
|
16
16
|
import { ChatStore } from '@/store/chat/store';
|
17
17
|
import { messageMapKey } from '@/store/chat/utils/messageMapKey';
|
18
18
|
import { useSessionStore } from '@/store/session';
|
19
|
-
import {
|
20
|
-
import { ChatMessage, CreateMessageParams } from '@/types/message';
|
19
|
+
import { ChatMessage, CreateMessageParams, SendMessageParams } from '@/types/message';
|
21
20
|
import { MessageSemanticSearchChunk } from '@/types/rag';
|
22
21
|
import { setNamespace } from '@/utils/storeDebug';
|
23
22
|
|
24
|
-
import { chatSelectors, topicSelectors } from '
|
25
|
-
import { ChatRAGAction, chatRag } from './actions/rag';
|
23
|
+
import { chatSelectors, topicSelectors } from '../../../selectors';
|
26
24
|
|
27
25
|
const n = setNamespace('ai');
|
28
26
|
|
29
|
-
export interface SendMessageParams {
|
30
|
-
message: string;
|
31
|
-
files?: UploadFileItem[];
|
32
|
-
onlyAddUserMessage?: boolean;
|
33
|
-
/**
|
34
|
-
*
|
35
|
-
* https://github.com/lobehub/lobe-chat/pull/2086
|
36
|
-
*/
|
37
|
-
isWelcomeQuestion?: boolean;
|
38
|
-
}
|
39
|
-
|
40
27
|
interface ProcessMessageParams {
|
41
28
|
traceId?: string;
|
42
29
|
isWelcomeQuestion?: boolean;
|
@@ -46,7 +33,7 @@ interface ProcessMessageParams {
|
|
46
33
|
ragQuery?: string;
|
47
34
|
}
|
48
35
|
|
49
|
-
export interface
|
36
|
+
export interface AIGenerateAction {
|
50
37
|
/**
|
51
38
|
* Sends a new message to the AI chat system
|
52
39
|
*/
|
@@ -110,14 +97,12 @@ const getAgentConfig = () => agentSelectors.currentAgentConfig(useAgentStore.get
|
|
110
97
|
const getAgentChatConfig = () => agentSelectors.currentAgentChatConfig(useAgentStore.getState());
|
111
98
|
const getAgentKnowledge = () => agentSelectors.currentEnabledKnowledge(useAgentStore.getState());
|
112
99
|
|
113
|
-
export const
|
100
|
+
export const generateAIChat: StateCreator<
|
114
101
|
ChatStore,
|
115
102
|
[['zustand/devtools', never]],
|
116
103
|
[],
|
117
|
-
|
118
|
-
> = (set, get
|
119
|
-
...chatRag(set, get, ...rest),
|
120
|
-
|
104
|
+
AIGenerateAction
|
105
|
+
> = (set, get) => ({
|
121
106
|
delAndRegenerateMessage: async (id) => {
|
122
107
|
const traceId = chatSelectors.getTraceIdByMessageId(id)(get());
|
123
108
|
get().internal_resendMessage(id, traceId);
|
@@ -0,0 +1,20 @@
|
|
1
|
+
import { StateCreator } from 'zustand/vanilla';
|
2
|
+
|
3
|
+
import { ChatStore } from '@/store/chat/store';
|
4
|
+
|
5
|
+
import { AIGenerateAction, generateAIChat } from './generateAIChat';
|
6
|
+
import { ChatRAGAction, chatRag } from './rag';
|
7
|
+
|
8
|
+
export interface ChatAIChatAction extends ChatRAGAction, AIGenerateAction {
|
9
|
+
/**/
|
10
|
+
}
|
11
|
+
|
12
|
+
export const chatAiChat: StateCreator<
|
13
|
+
ChatStore,
|
14
|
+
[['zustand/devtools', never]],
|
15
|
+
[],
|
16
|
+
ChatAIChatAction
|
17
|
+
> = (...params) => ({
|
18
|
+
...chatRag(...params),
|
19
|
+
...generateAIChat(...params),
|
20
|
+
});
|
package/src/store/chat/store.ts
CHANGED
@@ -13,7 +13,7 @@ import { ChatMessageAction, chatMessage } from './slices/message/action';
|
|
13
13
|
import { ChatPluginAction, chatPlugin } from './slices/plugin/action';
|
14
14
|
import { ShareAction, chatShare } from './slices/share/action';
|
15
15
|
import { ChatTopicAction, chatTopic } from './slices/topic/action';
|
16
|
-
import { chatAiChat, ChatAIChatAction } from './slices/aiChat/
|
16
|
+
import { chatAiChat, ChatAIChatAction } from './slices/aiChat/actions';
|
17
17
|
|
18
18
|
export interface ChatStoreAction
|
19
19
|
extends ChatMessageAction,
|
@@ -2,6 +2,7 @@ import { IPluginErrorType } from '@lobehub/chat-plugin-sdk';
|
|
2
2
|
|
3
3
|
import { ILobeAgentRuntimeErrorType } from '@/libs/agent-runtime';
|
4
4
|
import { ErrorType } from '@/types/fetch';
|
5
|
+
import { UploadFileItem } from '@/types/files';
|
5
6
|
import { MessageSemanticSearchChunk } from '@/types/rag';
|
6
7
|
|
7
8
|
import { BaseDataModel } from '../meta';
|
@@ -131,3 +132,14 @@ export interface CreateMessageParams
|
|
131
132
|
topicId?: string;
|
132
133
|
traceId?: string;
|
133
134
|
}
|
135
|
+
|
136
|
+
export interface SendMessageParams {
|
137
|
+
files?: UploadFileItem[];
|
138
|
+
/**
|
139
|
+
*
|
140
|
+
* https://github.com/lobehub/lobe-chat/pull/2086
|
141
|
+
*/
|
142
|
+
isWelcomeQuestion?: boolean;
|
143
|
+
message: string;
|
144
|
+
onlyAddUserMessage?: boolean;
|
145
|
+
}
|