@lobehub/chat 1.131.4 → 1.132.1
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 +50 -0
- package/changelog/v1.json +18 -0
- package/package.json +1 -1
- package/packages/context-engine/src/processors/MessageContent.ts +45 -10
- package/packages/context-engine/src/processors/__tests__/MessageContent.test.ts +179 -1
- package/packages/database/src/models/message.ts +9 -1
- package/packages/model-bank/src/aiModels/google.ts +7 -0
- package/packages/model-runtime/src/providers/google/index.ts +31 -8
- package/packages/model-runtime/src/types/chat.ts +6 -0
- package/packages/prompts/src/prompts/files/index.test.ts +148 -3
- package/packages/prompts/src/prompts/files/index.ts +17 -5
- package/packages/prompts/src/prompts/files/video.ts +17 -0
- package/packages/types/src/agent/index.ts +1 -1
- package/packages/types/src/message/chat.ts +2 -4
- package/packages/types/src/message/index.ts +1 -0
- package/packages/types/src/message/video.ts +5 -0
- package/packages/utils/src/client/index.ts +1 -0
- package/packages/utils/src/client/videoValidation.test.ts +53 -0
- package/packages/utils/src/client/videoValidation.ts +21 -0
- package/packages/utils/src/parseModels.ts +4 -0
- package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatInput/useSend.ts +9 -4
- package/src/components/ModelSelect/index.tsx +14 -2
- package/src/features/ChatInput/ActionBar/Upload/ClientMode.tsx +7 -0
- package/src/features/ChatInput/ActionBar/Upload/ServerMode.tsx +29 -3
- package/src/features/ChatInput/components/UploadDetail/UploadStatus.tsx +1 -1
- package/src/features/Conversation/Messages/Assistant/index.tsx +4 -1
- package/src/features/Conversation/Messages/User/VideoFileListViewer.tsx +31 -0
- package/src/features/Conversation/Messages/User/index.tsx +3 -1
- package/src/hooks/useModelSupportVideo.ts +10 -0
- package/src/locales/default/chat.ts +4 -0
- package/src/locales/default/components.ts +1 -0
- package/src/server/routers/lambda/aiChat.ts +1 -0
- package/src/services/chat/contextEngineering.test.ts +0 -1
- package/src/services/chat/contextEngineering.ts +3 -1
- package/src/services/chat/helper.ts +4 -0
- package/src/services/upload.ts +1 -1
- package/src/store/aiInfra/slices/aiModel/selectors.ts +7 -0
- package/src/store/chat/slices/aiChat/actions/generateAIChatV2.ts +22 -0
- package/src/store/chat/slices/message/action.ts +15 -14
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { useAiInfraStore } from '@/store/aiInfra';
|
|
2
|
+
import { aiModelSelectors } from '@/store/aiInfra/selectors';
|
|
3
|
+
|
|
4
|
+
export const useModelSupportVideo = (id?: string, provider?: string) => {
|
|
5
|
+
return useAiInfraStore((s) => {
|
|
6
|
+
if (!id || !provider) return false;
|
|
7
|
+
|
|
8
|
+
return aiModelSelectors.isModelSupportVideo(id, provider)(s);
|
|
9
|
+
});
|
|
10
|
+
};
|
|
@@ -285,6 +285,7 @@ export default {
|
|
|
285
285
|
actionFiletip: '上传文件',
|
|
286
286
|
actionTooltip: '上传',
|
|
287
287
|
disabled: '当前模型不支持视觉识别和文件分析,请切换模型后使用',
|
|
288
|
+
fileNotSupported: '浏览器模式下暂不支持上传文件,仅支持图片',
|
|
288
289
|
visionNotSupported: '当前模型不支持视觉识别,请切换模型后使用',
|
|
289
290
|
},
|
|
290
291
|
preview: {
|
|
@@ -294,6 +295,9 @@ export default {
|
|
|
294
295
|
processing: '文件处理中...',
|
|
295
296
|
},
|
|
296
297
|
},
|
|
298
|
+
validation: {
|
|
299
|
+
videoSizeExceeded: '视频文件大小不能超过 20MB,当前文件大小为 {{actualSize}}',
|
|
300
|
+
},
|
|
297
301
|
},
|
|
298
302
|
zenMode: '专注模式',
|
|
299
303
|
};
|
|
@@ -55,6 +55,7 @@ export const aiChatRouter = router({
|
|
|
55
55
|
const assistantMessageItem = await ctx.messageModel.create({
|
|
56
56
|
content: LOADING_FLAT,
|
|
57
57
|
fromModel: input.newAssistantMessage.model,
|
|
58
|
+
fromProvider: input.newAssistantMessage.provider,
|
|
58
59
|
parentId: messageId,
|
|
59
60
|
role: 'assistant',
|
|
60
61
|
sessionId: input.sessionId!,
|
|
@@ -162,7 +162,6 @@ describe('contextEngineering', () => {
|
|
|
162
162
|
<images_docstring>here are user upload images you can refer to</images_docstring>
|
|
163
163
|
<image name="abc.png" url="http://example.com/image.jpg"></image>
|
|
164
164
|
</images>
|
|
165
|
-
|
|
166
165
|
</files_info>
|
|
167
166
|
<!-- END SYSTEM CONTEXT -->`,
|
|
168
167
|
type: 'text',
|
|
@@ -23,7 +23,8 @@ import { toolSelectors } from '@/store/tool/selectors';
|
|
|
23
23
|
import { VARIABLE_GENERATORS } from '@/utils/client/parserPlaceholder';
|
|
24
24
|
import { genToolCallingName } from '@/utils/toolCall';
|
|
25
25
|
|
|
26
|
-
import { isCanUseFC, isCanUseVision } from './helper';
|
|
26
|
+
import { isCanUseFC, isCanUseVideo, isCanUseVision } from './helper';
|
|
27
|
+
|
|
27
28
|
|
|
28
29
|
interface ContextEngineeringContext {
|
|
29
30
|
enableHistoryCount?: boolean;
|
|
@@ -98,6 +99,7 @@ export const contextEngineering = async ({
|
|
|
98
99
|
// 8. Message content processing
|
|
99
100
|
new MessageContentProcessor({
|
|
100
101
|
fileContext: { enabled: isServerMode, includeFileUrl: !isDesktop },
|
|
102
|
+
isCanUseVideo,
|
|
101
103
|
isCanUseVision,
|
|
102
104
|
model,
|
|
103
105
|
provider,
|
|
@@ -23,6 +23,10 @@ export const isCanUseVision = (model: string, provider: string): boolean => {
|
|
|
23
23
|
return aiModelSelectors.isModelSupportVision(model, provider)(getAiInfraStoreState());
|
|
24
24
|
};
|
|
25
25
|
|
|
26
|
+
export const isCanUseVideo = (model: string, provider: string): boolean => {
|
|
27
|
+
return aiModelSelectors.isModelSupportVideo(model, provider)(getAiInfraStoreState()) || false;
|
|
28
|
+
};
|
|
29
|
+
|
|
26
30
|
/**
|
|
27
31
|
* TODO: we need to update this function to auto find deploymentName with provider setting config
|
|
28
32
|
*/
|
package/src/services/upload.ts
CHANGED
|
@@ -84,7 +84,7 @@ class UploadService {
|
|
|
84
84
|
|
|
85
85
|
// upload to client s3
|
|
86
86
|
// 客户端上传逻辑
|
|
87
|
-
if (!skipCheckFileType && !file.type.startsWith('image')) {
|
|
87
|
+
if (!skipCheckFileType && !file.type.startsWith('image') && !file.type.startsWith('video')) {
|
|
88
88
|
onNotSupported?.();
|
|
89
89
|
return { data: undefined as unknown as FileMetadata, success: false };
|
|
90
90
|
}
|
|
@@ -62,6 +62,12 @@ const isModelSupportVision = (id: string, provider: string) => (s: AIProviderSto
|
|
|
62
62
|
return model?.abilities?.vision || false;
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
+
const isModelSupportVideo = (id: string, provider: string) => (s: AIProviderStoreState) => {
|
|
66
|
+
const model = getEnabledModelById(id, provider)(s);
|
|
67
|
+
|
|
68
|
+
return model?.abilities?.video;
|
|
69
|
+
};
|
|
70
|
+
|
|
65
71
|
const isModelSupportReasoning = (id: string, provider: string) => (s: AIProviderStoreState) => {
|
|
66
72
|
const model = getEnabledModelById(id, provider)(s);
|
|
67
73
|
|
|
@@ -136,6 +142,7 @@ export const aiModelSelectors = {
|
|
|
136
142
|
isModelSupportFiles,
|
|
137
143
|
isModelSupportReasoning,
|
|
138
144
|
isModelSupportToolUse,
|
|
145
|
+
isModelSupportVideo,
|
|
139
146
|
isModelSupportVision,
|
|
140
147
|
modelBuiltinSearchImpl,
|
|
141
148
|
modelContextWindowTokens,
|
|
@@ -23,8 +23,11 @@ import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/slices/c
|
|
|
23
23
|
import { aiModelSelectors, aiProviderSelectors, getAiInfraStoreState } from '@/store/aiInfra';
|
|
24
24
|
import { MainSendMessageOperation } from '@/store/chat/slices/aiChat/initialState';
|
|
25
25
|
import type { ChatStore } from '@/store/chat/store';
|
|
26
|
+
import { getFileStoreState } from '@/store/file/store';
|
|
26
27
|
import { getSessionStoreState } from '@/store/session';
|
|
27
28
|
import { WebBrowsingManifest } from '@/tools/web-browsing';
|
|
29
|
+
import { ChatImageItem } from '@/types/message/image';
|
|
30
|
+
import { ChatVideoItem } from '@/types/message/video';
|
|
28
31
|
import { setNamespace } from '@/utils/storeDebug';
|
|
29
32
|
|
|
30
33
|
import { chatSelectors, topicSelectors } from '../../../selectors';
|
|
@@ -107,6 +110,23 @@ export const generateAIChatV2: StateCreator<
|
|
|
107
110
|
|
|
108
111
|
const messages = chatSelectors.activeBaseChats(get());
|
|
109
112
|
|
|
113
|
+
// 构造服务端模式临时消息的本地媒体预览(优先使用 S3 URL)
|
|
114
|
+
const filesInStore = getFileStoreState().chatUploadFileList;
|
|
115
|
+
const tempImages: ChatImageItem[] = filesInStore
|
|
116
|
+
.filter((f) => f.file?.type?.startsWith('image'))
|
|
117
|
+
.map((f) => ({
|
|
118
|
+
id: f.id,
|
|
119
|
+
url: f.fileUrl || f.base64Url || f.previewUrl || '',
|
|
120
|
+
alt: f.file?.name || f.id,
|
|
121
|
+
}));
|
|
122
|
+
const tempVideos: ChatVideoItem[] = filesInStore
|
|
123
|
+
.filter((f) => f.file?.type?.startsWith('video'))
|
|
124
|
+
.map((f) => ({
|
|
125
|
+
id: f.id,
|
|
126
|
+
url: f.fileUrl || f.base64Url || f.previewUrl || '',
|
|
127
|
+
alt: f.file?.name || f.id,
|
|
128
|
+
}));
|
|
129
|
+
|
|
110
130
|
// use optimistic update to avoid the slow waiting
|
|
111
131
|
const tempId = get().internal_createTmpMessage({
|
|
112
132
|
content: message,
|
|
@@ -117,6 +137,8 @@ export const generateAIChatV2: StateCreator<
|
|
|
117
137
|
// if there is activeTopicId,then add topicId to message
|
|
118
138
|
topicId: activeTopicId,
|
|
119
139
|
threadId: activeThreadId,
|
|
140
|
+
imageList: tempImages.length > 0 ? tempImages : undefined,
|
|
141
|
+
videoList: tempVideos.length > 0 ? tempVideos : undefined,
|
|
120
142
|
});
|
|
121
143
|
get().internal_toggleMessageLoading(true, tempId);
|
|
122
144
|
|
|
@@ -1,6 +1,20 @@
|
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
|
|
2
2
|
// Disable the auto sort key eslint rule to make the code more logic and readable
|
|
3
|
-
import {
|
|
3
|
+
import {
|
|
4
|
+
ChatErrorType,
|
|
5
|
+
ChatImageItem,
|
|
6
|
+
ChatMessage,
|
|
7
|
+
ChatMessageError,
|
|
8
|
+
ChatMessagePluginError,
|
|
9
|
+
CreateMessageParams,
|
|
10
|
+
GroundingSearch,
|
|
11
|
+
MessageMetadata,
|
|
12
|
+
MessageToolCall,
|
|
13
|
+
ModelReasoning,
|
|
14
|
+
TraceEventPayloads,
|
|
15
|
+
TraceEventType,
|
|
16
|
+
UpdateMessageRAGParams,
|
|
17
|
+
} from '@lobechat/types';
|
|
4
18
|
import { copyToClipboard } from '@lobehub/ui';
|
|
5
19
|
import isEqual from 'fast-deep-equal';
|
|
6
20
|
import { SWRResponse, mutate } from 'swr';
|
|
@@ -12,19 +26,6 @@ import { topicService } from '@/services/topic';
|
|
|
12
26
|
import { traceService } from '@/services/trace';
|
|
13
27
|
import { ChatStore } from '@/store/chat/store';
|
|
14
28
|
import { messageMapKey } from '@/store/chat/utils/messageMapKey';
|
|
15
|
-
import {
|
|
16
|
-
ChatMessage,
|
|
17
|
-
ChatMessageError,
|
|
18
|
-
ChatMessagePluginError,
|
|
19
|
-
CreateMessageParams,
|
|
20
|
-
MessageMetadata,
|
|
21
|
-
MessageToolCall,
|
|
22
|
-
ModelReasoning,
|
|
23
|
-
} from '@/types/message';
|
|
24
|
-
import { ChatImageItem } from '@/types/message/image';
|
|
25
|
-
import { UpdateMessageRAGParams } from '@/types/message/rag';
|
|
26
|
-
import { GroundingSearch } from '@/types/search';
|
|
27
|
-
import { TraceEventPayloads } from '@/types/trace';
|
|
28
29
|
import { Action, setNamespace } from '@/utils/storeDebug';
|
|
29
30
|
import { nanoid } from '@/utils/uuid';
|
|
30
31
|
|