@lobehub/chat 1.110.1 → 1.110.3
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 +59 -0
- package/Dockerfile +1 -1
- package/apps/desktop/.i18nrc.js +2 -1
- package/apps/desktop/package.json +1 -2
- package/apps/desktop/resources/locales/ar/menu.json +1 -0
- package/apps/desktop/resources/locales/bg-BG/menu.json +1 -0
- package/apps/desktop/resources/locales/de-DE/menu.json +1 -0
- package/apps/desktop/resources/locales/en-US/menu.json +1 -0
- package/apps/desktop/resources/locales/es-ES/menu.json +1 -0
- package/apps/desktop/resources/locales/fa-IR/menu.json +1 -0
- package/apps/desktop/resources/locales/fr-FR/menu.json +1 -0
- package/apps/desktop/resources/locales/it-IT/menu.json +1 -0
- package/apps/desktop/resources/locales/ja-JP/menu.json +1 -0
- package/apps/desktop/resources/locales/ko-KR/menu.json +1 -0
- package/apps/desktop/resources/locales/nl-NL/menu.json +1 -0
- package/apps/desktop/resources/locales/pl-PL/menu.json +1 -0
- package/apps/desktop/resources/locales/pt-BR/menu.json +1 -0
- package/apps/desktop/resources/locales/ru-RU/menu.json +1 -0
- package/apps/desktop/resources/locales/tr-TR/menu.json +1 -0
- package/apps/desktop/resources/locales/vi-VN/menu.json +1 -0
- package/apps/desktop/resources/locales/zh-CN/menu.json +1 -0
- package/apps/desktop/resources/locales/zh-TW/menu.json +1 -0
- package/apps/desktop/src/main/controllers/MenuCtr.ts +2 -2
- package/apps/desktop/src/main/controllers/__tests__/MenuCtr.test.ts +13 -13
- package/apps/desktop/src/main/locales/default/menu.ts +1 -0
- package/apps/desktop/src/main/menus/impls/linux.ts +9 -24
- package/apps/desktop/src/main/menus/impls/macOS.ts +9 -28
- package/apps/desktop/src/main/menus/impls/windows.ts +9 -27
- package/changelog/v1.json +21 -0
- package/locales/ar/modelProvider.json +10 -1
- package/locales/ar/models.json +19 -1
- package/locales/bg-BG/modelProvider.json +10 -1
- package/locales/bg-BG/models.json +19 -1
- package/locales/de-DE/modelProvider.json +10 -1
- package/locales/de-DE/models.json +19 -1
- package/locales/en-US/modelProvider.json +10 -1
- package/locales/en-US/models.json +19 -1
- package/locales/es-ES/modelProvider.json +10 -1
- package/locales/es-ES/models.json +19 -1
- package/locales/fa-IR/modelProvider.json +10 -1
- package/locales/fa-IR/models.json +19 -1
- package/locales/fr-FR/modelProvider.json +10 -1
- package/locales/fr-FR/models.json +19 -1
- package/locales/it-IT/modelProvider.json +10 -1
- package/locales/it-IT/models.json +19 -1
- package/locales/ja-JP/modelProvider.json +10 -1
- package/locales/ja-JP/models.json +19 -1
- package/locales/ko-KR/modelProvider.json +10 -1
- package/locales/ko-KR/models.json +19 -1
- package/locales/nl-NL/modelProvider.json +10 -1
- package/locales/nl-NL/models.json +19 -1
- package/locales/pl-PL/modelProvider.json +10 -1
- package/locales/pl-PL/models.json +19 -1
- package/locales/pt-BR/modelProvider.json +10 -1
- package/locales/pt-BR/models.json +19 -1
- package/locales/ru-RU/modelProvider.json +10 -1
- package/locales/ru-RU/models.json +19 -1
- package/locales/tr-TR/modelProvider.json +10 -1
- package/locales/tr-TR/models.json +19 -1
- package/locales/vi-VN/modelProvider.json +10 -1
- package/locales/vi-VN/models.json +19 -1
- package/locales/zh-CN/modelProvider.json +10 -1
- package/locales/zh-CN/models.json +19 -1
- package/locales/zh-TW/modelProvider.json +10 -1
- package/locales/zh-TW/models.json +19 -1
- package/next.config.ts +1 -0
- package/package.json +4 -4
- package/packages/electron-client-ipc/src/events/menu.ts +1 -1
- package/packages/types/package.json +3 -0
- package/packages/types/src/agent/chatConfig.ts +1 -1
- package/packages/types/src/agent/index.ts +3 -4
- package/packages/types/src/discover/assistants.ts +3 -3
- package/packages/types/src/message/chat.ts +4 -4
- package/src/app/(backend)/_deprecated/createBizOpenAI/auth.ts +2 -1
- package/src/app/(backend)/_deprecated/createBizOpenAI/createAzureOpenai.ts +1 -1
- package/src/app/(backend)/_deprecated/createBizOpenAI/createOpenai.ts +1 -1
- package/src/app/(backend)/_deprecated/createBizOpenAI/index.ts +1 -1
- package/src/app/(backend)/middleware/auth/index.test.ts +1 -1
- package/src/app/(backend)/middleware/auth/index.ts +1 -1
- package/src/app/(backend)/middleware/auth/utils.ts +1 -1
- package/src/app/(backend)/webapi/chat/[provider]/route.test.ts +1 -1
- package/src/app/(backend)/webapi/chat/[provider]/route.ts +2 -1
- package/src/app/(backend)/webapi/models/[provider]/pull/route.ts +2 -1
- package/src/app/(backend)/webapi/models/[provider]/route.ts +1 -1
- package/src/app/(backend)/webapi/plugin/gateway/route.ts +1 -1
- package/src/app/(backend)/webapi/text-to-image/[provider]/route.ts +1 -1
- package/src/app/[variants]/(main)/settings/_layout/Desktop/index.tsx +2 -1
- package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/Container.tsx +1 -0
- package/src/app/[variants]/(main)/settings/provider/_layout/Desktop/index.tsx +4 -9
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/DisabledModels.tsx +15 -5
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/EnabledModelList/index.tsx +22 -4
- package/src/app/[variants]/(main)/settings/provider/features/ModelList/index.tsx +99 -3
- package/src/app/[variants]/layout.tsx +2 -1
- package/src/components/InnerLink.tsx +20 -0
- package/src/config/modelProviders/ai302.ts +1 -0
- package/src/config/modelProviders/openai.ts +1 -0
- package/src/features/ChatInput/Desktop/InputArea/index.tsx +14 -0
- package/src/features/Conversation/Error/index.tsx +1 -1
- package/src/features/Conversation/components/ChatItem/index.tsx +18 -1
- package/src/features/ElectronTitlebar/UpdateModal.tsx +15 -3
- package/src/features/Portal/Artifacts/Header.tsx +1 -1
- package/src/hooks/usePlatform.ts +1 -1
- package/src/layout/GlobalProvider/index.tsx +3 -0
- package/src/libs/model-runtime/RouterRuntime/createRuntime.ts +2 -2
- package/src/locales/default/modelProvider.ts +9 -0
- package/src/server/ld.ts +1 -1
- package/src/services/__tests__/chat.test.ts +1 -1
- package/src/services/chat.ts +1 -1
- package/src/services/electron/system.ts +3 -1
- package/src/store/chat/slices/message/action.ts +1 -1
- package/src/store/chat/slices/plugin/action.ts +1 -1
- package/src/store/serverConfig/Provider.tsx +7 -2
- package/src/store/serverConfig/store.ts +2 -0
- package/src/utils/errorResponse.test.ts +1 -1
- package/src/utils/errorResponse.ts +2 -1
- package/src/utils/fetch/__tests__/parseError.test.ts +1 -2
- package/src/utils/fetch/fetchSSE.ts +2 -1
- package/src/utils/fetch/parseError.ts +1 -1
- package/tsconfig.json +1 -1
- package/.dockerignore +0 -9
- package/packages/file-loaders/src/loaders/docx/fixtures/test.docx +0 -0
- package/packages/file-loaders/src/loaders/excel/fixtures/test.xlsx +0 -0
- package/packages/file-loaders/src/loaders/pptx/fixtures/test.pptx +0 -0
- package/packages/file-loaders/test/fixtures/test.docx +0 -0
- package/packages/file-loaders/test/fixtures/test.pptx +0 -0
- /package/{packages/types/src → src/types}/next.ts +0 -0
package/src/app/[variants]/(main)/settings/provider/features/ModelList/EnabledModelList/index.tsx
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { ActionIcon, Text } from '@lobehub/ui';
|
2
2
|
import isEqual from 'fast-deep-equal';
|
3
3
|
import { ArrowDownUpIcon, ToggleLeft } from 'lucide-react';
|
4
|
-
import { useState } from 'react';
|
4
|
+
import { useMemo, useState } from 'react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
6
|
import { Center, Flexbox } from 'react-layout-kit';
|
7
7
|
|
@@ -11,7 +11,11 @@ import { aiModelSelectors } from '@/store/aiInfra/selectors';
|
|
11
11
|
import ModelItem from '../ModelItem';
|
12
12
|
import SortModelModal from '../SortModelModal';
|
13
13
|
|
14
|
-
|
14
|
+
interface EnabledModelListProps {
|
15
|
+
activeTab: string;
|
16
|
+
}
|
17
|
+
|
18
|
+
const EnabledModelList = ({ activeTab }: EnabledModelListProps) => {
|
15
19
|
const { t } = useTranslation('modelProvider');
|
16
20
|
|
17
21
|
const enabledModels = useAiInfraStore(aiModelSelectors.enabledAiProviderModelList, isEqual);
|
@@ -20,6 +24,14 @@ const EnabledModelList = () => {
|
|
20
24
|
const [batchLoading, setBatchLoading] = useState(false);
|
21
25
|
|
22
26
|
const isEmpty = enabledModels.length === 0;
|
27
|
+
|
28
|
+
// Filter models based on active tab
|
29
|
+
const filteredModels = useMemo(() => {
|
30
|
+
if (activeTab === 'all') return enabledModels;
|
31
|
+
return enabledModels.filter((model) => model.type === activeTab);
|
32
|
+
}, [enabledModels, activeTab]);
|
33
|
+
|
34
|
+
const isCurrentTabEmpty = filteredModels.length === 0;
|
23
35
|
return (
|
24
36
|
<>
|
25
37
|
<Flexbox horizontal justify={'space-between'}>
|
@@ -63,17 +75,23 @@ const EnabledModelList = () => {
|
|
63
75
|
/>
|
64
76
|
)}
|
65
77
|
</Flexbox>
|
78
|
+
|
66
79
|
{isEmpty ? (
|
67
80
|
<Center padding={12}>
|
68
81
|
<Text style={{ fontSize: 12 }} type={'secondary'}>
|
69
82
|
{t('providerModels.list.enabledEmpty')}
|
70
83
|
</Text>
|
71
84
|
</Center>
|
85
|
+
) : isCurrentTabEmpty ? (
|
86
|
+
<Center padding={12}>
|
87
|
+
<Text style={{ fontSize: 12 }} type={'secondary'}>
|
88
|
+
{t('providerModels.list.noModelsInCategory')}
|
89
|
+
</Text>
|
90
|
+
</Center>
|
72
91
|
) : (
|
73
92
|
<Flexbox gap={2}>
|
74
|
-
{
|
93
|
+
{filteredModels.map(({ displayName, id, ...res }) => {
|
75
94
|
const label = displayName || id;
|
76
|
-
|
77
95
|
return <ModelItem displayName={label as string} id={id as string} key={id} {...res} />;
|
78
96
|
})}
|
79
97
|
</Flexbox>
|
@@ -1,7 +1,18 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
|
+
import { Icon, Tabs } from '@lobehub/ui';
|
3
4
|
import { useTheme } from 'antd-style';
|
4
|
-
import
|
5
|
+
import isEqual from 'fast-deep-equal';
|
6
|
+
import {
|
7
|
+
AudioLines,
|
8
|
+
BoltIcon,
|
9
|
+
Grid3x3Icon,
|
10
|
+
ImageIcon,
|
11
|
+
MessageSquareTextIcon,
|
12
|
+
MicIcon,
|
13
|
+
} from 'lucide-react';
|
14
|
+
import { Suspense, memo, useMemo, useState } from 'react';
|
15
|
+
import { useTranslation } from 'react-i18next';
|
5
16
|
import { Flexbox } from 'react-layout-kit';
|
6
17
|
|
7
18
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
@@ -20,14 +31,92 @@ interface ContentProps {
|
|
20
31
|
}
|
21
32
|
|
22
33
|
const Content = memo<ContentProps>(({ id }) => {
|
34
|
+
const { t } = useTranslation('modelProvider');
|
35
|
+
const [activeTab, setActiveTab] = useState('all');
|
36
|
+
|
23
37
|
const [isSearching, isEmpty, useFetchAiProviderModels] = useAiInfraStore((s) => [
|
24
38
|
!!s.modelSearchKeyword,
|
25
39
|
aiModelSelectors.isEmptyAiProviderModelList(s),
|
26
40
|
s.useFetchAiProviderModels,
|
27
41
|
]);
|
28
42
|
|
43
|
+
const allModels = useAiInfraStore(aiModelSelectors.filteredAiProviderModelList, isEqual);
|
44
|
+
|
29
45
|
const { isLoading } = useFetchAiProviderModels(id);
|
30
46
|
|
47
|
+
// Count models by type (for all models, not just enabled)
|
48
|
+
const modelCounts = useMemo(() => {
|
49
|
+
const counts = {
|
50
|
+
all: allModels.length,
|
51
|
+
chat: 0,
|
52
|
+
embedding: 0,
|
53
|
+
image: 0,
|
54
|
+
stt: 0,
|
55
|
+
tts: 0,
|
56
|
+
};
|
57
|
+
|
58
|
+
allModels.forEach((model) => {
|
59
|
+
const type = model.type;
|
60
|
+
if (type && Object.prototype.hasOwnProperty.call(counts, type)) {
|
61
|
+
counts[type as keyof typeof counts]++;
|
62
|
+
}
|
63
|
+
});
|
64
|
+
|
65
|
+
return counts;
|
66
|
+
}, [allModels]);
|
67
|
+
|
68
|
+
// Tab definitions with counts (only show tabs with models > 0, except 'all' tab)
|
69
|
+
const tabs = useMemo(() => {
|
70
|
+
const formatTabLabel = (baseLabel: string, count: number) =>
|
71
|
+
count > 0 ? `${baseLabel} (${count})` : baseLabel;
|
72
|
+
|
73
|
+
const allTabs = [
|
74
|
+
{
|
75
|
+
count: modelCounts.all,
|
76
|
+
icon: <Icon icon={Grid3x3Icon} size={16} />,
|
77
|
+
key: 'all',
|
78
|
+
label: formatTabLabel(t('providerModels.tabs.all'), modelCounts.all),
|
79
|
+
},
|
80
|
+
{
|
81
|
+
count: modelCounts.chat,
|
82
|
+
icon: <Icon icon={MessageSquareTextIcon} size={16} />,
|
83
|
+
key: 'chat',
|
84
|
+
label: formatTabLabel(t('providerModels.tabs.chat'), modelCounts.chat),
|
85
|
+
},
|
86
|
+
{
|
87
|
+
count: modelCounts.image,
|
88
|
+
icon: <Icon icon={ImageIcon} size={16} />,
|
89
|
+
key: 'image',
|
90
|
+
label: formatTabLabel(t('providerModels.tabs.image'), modelCounts.image),
|
91
|
+
},
|
92
|
+
{
|
93
|
+
count: modelCounts.embedding,
|
94
|
+
icon: <Icon icon={BoltIcon} size={16} />,
|
95
|
+
key: 'embedding',
|
96
|
+
label: formatTabLabel(t('providerModels.tabs.embedding'), modelCounts.embedding),
|
97
|
+
},
|
98
|
+
{
|
99
|
+
count: modelCounts.stt,
|
100
|
+
icon: <Icon icon={MicIcon} size={16} />,
|
101
|
+
key: 'stt',
|
102
|
+
label: formatTabLabel(t('providerModels.tabs.stt'), modelCounts.stt),
|
103
|
+
},
|
104
|
+
{
|
105
|
+
count: modelCounts.tts,
|
106
|
+
icon: <Icon icon={AudioLines} size={16} />,
|
107
|
+
key: 'tts',
|
108
|
+
label: formatTabLabel(t('providerModels.tabs.tts'), modelCounts.tts),
|
109
|
+
},
|
110
|
+
];
|
111
|
+
|
112
|
+
// Only show tabs that have models (count > 0), but always show 'all' tab
|
113
|
+
return allTabs.filter((tab) => tab.key === 'all' || tab.count > 0);
|
114
|
+
}, [modelCounts]);
|
115
|
+
|
116
|
+
// Ensure active tab is available, fallback to 'all' if current tab is hidden
|
117
|
+
const availableTabKeys = tabs.map((tab) => tab.key);
|
118
|
+
const currentActiveTab = availableTabKeys.includes(activeTab) ? activeTab : 'all';
|
119
|
+
|
31
120
|
if (isLoading) return <SkeletonList />;
|
32
121
|
|
33
122
|
if (isSearching) return <SearchResult />;
|
@@ -36,8 +125,15 @@ const Content = memo<ContentProps>(({ id }) => {
|
|
36
125
|
<EmptyModels provider={id} />
|
37
126
|
) : (
|
38
127
|
<Flexbox>
|
39
|
-
<
|
40
|
-
|
128
|
+
<Tabs
|
129
|
+
activeKey={currentActiveTab}
|
130
|
+
items={tabs}
|
131
|
+
onChange={setActiveTab}
|
132
|
+
size="small"
|
133
|
+
style={{ marginBottom: 12 }}
|
134
|
+
/>
|
135
|
+
<EnabledModelList activeTab={currentActiveTab} />
|
136
|
+
<DisabledModels activeTab={currentActiveTab} />
|
41
137
|
</Flexbox>
|
42
138
|
);
|
43
139
|
});
|
@@ -31,7 +31,7 @@ const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
|
|
31
31
|
const direction = isRtlLang(locale) ? 'rtl' : 'ltr';
|
32
32
|
|
33
33
|
return (
|
34
|
-
<html dir={direction} lang={locale}
|
34
|
+
<html dir={direction} lang={locale}>
|
35
35
|
<head>
|
36
36
|
{process.env.DEBUG_REACT_SCAN === '1' && (
|
37
37
|
// eslint-disable-next-line @next/next/no-sync-scripts
|
@@ -46,6 +46,7 @@ const RootLayout = async ({ children, params, modal }: RootLayoutProps) => {
|
|
46
46
|
locale={locale}
|
47
47
|
neutralColor={neutralColor}
|
48
48
|
primaryColor={primaryColor}
|
49
|
+
variants={variants}
|
49
50
|
>
|
50
51
|
<AuthProvider>
|
51
52
|
{children}
|
@@ -0,0 +1,20 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import Link, { LinkProps } from 'next/link';
|
4
|
+
import { AnchorHTMLAttributes, ReactNode } from 'react';
|
5
|
+
|
6
|
+
import { useServerConfigStore } from '@/store/serverConfig';
|
7
|
+
|
8
|
+
interface InnerLinkProps
|
9
|
+
extends Omit<AnchorHTMLAttributes<HTMLAnchorElement>, keyof LinkProps>,
|
10
|
+
LinkProps {
|
11
|
+
children?: ReactNode | undefined;
|
12
|
+
}
|
13
|
+
|
14
|
+
const InnerLink = ({ href, ...props }: InnerLinkProps) => {
|
15
|
+
const variants = useServerConfigStore((s) => s.segmentVariants);
|
16
|
+
|
17
|
+
return <Link {...props} as={href} href={`/${variants}${href}`} />;
|
18
|
+
};
|
19
|
+
|
20
|
+
export default InnerLink;
|
@@ -2,6 +2,7 @@ import { ModelProviderCard } from '@/types/llm';
|
|
2
2
|
|
3
3
|
// ref: https://platform.openai.com/docs/deprecations
|
4
4
|
const OpenAI: ModelProviderCard = {
|
5
|
+
apiKeyUrl: 'https://platform.openai.com/api-keys?utm_source=lobehub',
|
5
6
|
chatModels: [
|
6
7
|
{
|
7
8
|
contextWindowTokens: 1_047_576,
|
@@ -5,6 +5,7 @@ import { RefObject, memo, useEffect, useRef } from 'react';
|
|
5
5
|
import { useHotkeysContext } from 'react-hotkeys-hook';
|
6
6
|
import { useTranslation } from 'react-i18next';
|
7
7
|
|
8
|
+
import { isDesktop } from '@/const/version';
|
8
9
|
import { useUserStore } from '@/store/user';
|
9
10
|
import { preferenceSelectors } from '@/store/user/selectors';
|
10
11
|
import { HotkeyEnum } from '@/types/hotkey';
|
@@ -86,6 +87,19 @@ const InputArea = memo<InputAreaProps>(({ onSend, value, loading, onChange }) =>
|
|
86
87
|
onCompositionStart={() => {
|
87
88
|
isChineseInput.current = true;
|
88
89
|
}}
|
90
|
+
onContextMenu={async (e) => {
|
91
|
+
if (isDesktop) {
|
92
|
+
e.preventDefault();
|
93
|
+
const textArea = ref.current?.resizableTextArea?.textArea;
|
94
|
+
const hasSelection = textArea && textArea.selectionStart !== textArea.selectionEnd;
|
95
|
+
const { electronSystemService } = await import('@/services/electron/system');
|
96
|
+
|
97
|
+
electronSystemService.showContextMenu('editor', {
|
98
|
+
hasSelection: !!hasSelection,
|
99
|
+
value: value,
|
100
|
+
});
|
101
|
+
}
|
102
|
+
}}
|
89
103
|
onFocus={() => {
|
90
104
|
enableScope(HotkeyEnum.AddUserMessage);
|
91
105
|
}}
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { ChatErrorType, ErrorType } from '@lobechat/types/fetch';
|
1
2
|
import { IPluginErrorType } from '@lobehub/chat-plugin-sdk';
|
2
3
|
import type { AlertProps } from '@lobehub/ui';
|
3
4
|
import { Skeleton } from 'antd';
|
@@ -7,7 +8,6 @@ import { useTranslation } from 'react-i18next';
|
|
7
8
|
|
8
9
|
import { useProviderName } from '@/hooks/useProviderName';
|
9
10
|
import { AgentRuntimeErrorType, ILobeAgentRuntimeErrorType } from '@/libs/model-runtime';
|
10
|
-
import { ChatErrorType, ErrorType } from '@/types/fetch';
|
11
11
|
import { ChatMessage, ChatMessageError } from '@/types/message';
|
12
12
|
|
13
13
|
import ChatInvalidAPIKey from './ChatInvalidApiKey';
|
@@ -6,6 +6,7 @@ import { MouseEventHandler, ReactNode, memo, use, useCallback, useMemo } from 'r
|
|
6
6
|
import { useTranslation } from 'react-i18next';
|
7
7
|
import { Flexbox } from 'react-layout-kit';
|
8
8
|
|
9
|
+
import { isDesktop } from '@/const/version';
|
9
10
|
import ChatItem from '@/features/ChatItem';
|
10
11
|
import { VirtuosoContext } from '@/features/Conversation/components/VirtualizedList/VirtuosoContext';
|
11
12
|
import { useAgentStore } from '@/store/agent';
|
@@ -220,6 +221,19 @@ const Item = memo<ChatListItemProps>(
|
|
220
221
|
toggleMessageEditing(id, edit);
|
221
222
|
}, []);
|
222
223
|
|
224
|
+
const onContextMenu = useCallback(async () => {
|
225
|
+
if (isDesktop && item) {
|
226
|
+
const { electronSystemService } = await import('@/services/electron/system');
|
227
|
+
|
228
|
+
electronSystemService.showContextMenu('chat', {
|
229
|
+
content: item.content,
|
230
|
+
hasError: !!item.error,
|
231
|
+
messageId: id,
|
232
|
+
role: item.role,
|
233
|
+
});
|
234
|
+
}
|
235
|
+
}, [id, item]);
|
236
|
+
|
223
237
|
const belowMessage = useMemo(() => item && <BelowMessage data={item} />, [item]);
|
224
238
|
const errorMessage = useMemo(() => item && <ErrorMessageExtra data={item} />, [item]);
|
225
239
|
const messageExtra = useMemo(() => item && <MessageExtra data={item} />, [item]);
|
@@ -228,7 +242,10 @@ const Item = memo<ChatListItemProps>(
|
|
228
242
|
item && (
|
229
243
|
<InPortalThreadContext.Provider value={inPortalThread}>
|
230
244
|
{enableHistoryDivider && <History />}
|
231
|
-
<Flexbox
|
245
|
+
<Flexbox
|
246
|
+
className={cx(styles.message, className, isMessageLoading && styles.loading)}
|
247
|
+
onContextMenu={onContextMenu}
|
248
|
+
>
|
232
249
|
<ChatItem
|
233
250
|
actions={actionBar}
|
234
251
|
avatar={item.meta}
|
@@ -115,11 +115,23 @@ export const UpdateModal = memo(() => {
|
|
115
115
|
const closeDownloadedModal = () => setDownloadedInfo(null);
|
116
116
|
const closeLatestVersionModal = () => setLatestVersionInfo(null);
|
117
117
|
|
118
|
+
const handleCancelCheck = () => {
|
119
|
+
setIsChecking(false);
|
120
|
+
setUpdateAvailableInfo(null);
|
121
|
+
setDownloadedInfo(null);
|
122
|
+
setProgress(null);
|
123
|
+
setLatestVersionInfo(null);
|
124
|
+
};
|
125
|
+
|
118
126
|
const renderCheckingModal = () => (
|
119
127
|
<Modal
|
120
|
-
closable
|
121
|
-
footer={
|
122
|
-
|
128
|
+
closable
|
129
|
+
footer={[
|
130
|
+
<Button key="cancel" onClick={handleCancelCheck}>
|
131
|
+
{t('cancel', { ns: 'common' })}
|
132
|
+
</Button>,
|
133
|
+
]}
|
134
|
+
onCancel={handleCancelCheck}
|
123
135
|
open={isChecking}
|
124
136
|
title={t('updater.checkingUpdate')}
|
125
137
|
>
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { ArtifactType } from '@lobechat/types/artifact';
|
1
2
|
import { ActionIcon, Icon, Segmented, Text } from '@lobehub/ui';
|
2
3
|
import { ConfigProvider } from 'antd';
|
3
4
|
import { cx } from 'antd-style';
|
@@ -9,7 +10,6 @@ import { useChatStore } from '@/store/chat';
|
|
9
10
|
import { chatPortalSelectors } from '@/store/chat/selectors';
|
10
11
|
import { ArtifactDisplayMode } from '@/store/chat/slices/portal/initialState';
|
11
12
|
import { oneLineEllipsis } from '@/styles';
|
12
|
-
import { ArtifactType } from '@/types/artifact';
|
13
13
|
|
14
14
|
const Header = () => {
|
15
15
|
const { t } = useTranslation('portal');
|
package/src/hooks/usePlatform.ts
CHANGED
@@ -23,6 +23,7 @@ interface GlobalLayoutProps {
|
|
23
23
|
locale: string;
|
24
24
|
neutralColor?: string;
|
25
25
|
primaryColor?: string;
|
26
|
+
variants?: string;
|
26
27
|
}
|
27
28
|
|
28
29
|
const GlobalLayout = async ({
|
@@ -32,6 +33,7 @@ const GlobalLayout = async ({
|
|
32
33
|
locale: userLocale,
|
33
34
|
appearance,
|
34
35
|
isMobile,
|
36
|
+
variants,
|
35
37
|
}: GlobalLayoutProps) => {
|
36
38
|
const antdLocale = await getAntdLocale(userLocale);
|
37
39
|
|
@@ -52,6 +54,7 @@ const GlobalLayout = async ({
|
|
52
54
|
<ServerConfigStoreProvider
|
53
55
|
featureFlags={serverFeatureFlags}
|
54
56
|
isMobile={isMobile}
|
57
|
+
segmentVariants={variants}
|
55
58
|
serverConfig={serverConfig}
|
56
59
|
>
|
57
60
|
<QueryProvider>
|
@@ -135,9 +135,9 @@ export const createRouterRuntime = ({
|
|
135
135
|
this._runtimes = routers.map((router) => {
|
136
136
|
const providerAI = router.runtime ?? baseRuntimeMap[router.apiType] ?? LobeOpenAI;
|
137
137
|
|
138
|
-
const finalOptions = { ...
|
138
|
+
const finalOptions = { ...params, ...options, ...router.options };
|
139
139
|
// @ts-ignore
|
140
|
-
const runtime: LobeRuntimeAI = new providerAI({ ...
|
140
|
+
const runtime: LobeRuntimeAI = new providerAI({ ...finalOptions, id });
|
141
141
|
|
142
142
|
return { id: router.apiType, models: router.models, runtime };
|
143
143
|
});
|
@@ -310,6 +310,7 @@ export default {
|
|
310
310
|
latestTime: '上次更新时间:{{time}}',
|
311
311
|
noLatestTime: '暂未获取列表',
|
312
312
|
},
|
313
|
+
noModelsInCategory: '该分类下暂无启用的模型',
|
313
314
|
resetAll: {
|
314
315
|
conform: '确认重置当前模型的所有修改?重置后当前模型列表将会回到默认状态',
|
315
316
|
success: '重置成功',
|
@@ -321,6 +322,14 @@ export default {
|
|
321
322
|
total: '共 {{count}} 个模型可用',
|
322
323
|
},
|
323
324
|
searchNotFound: '未找到搜索结果',
|
325
|
+
tabs: {
|
326
|
+
all: '全部',
|
327
|
+
chat: '对话',
|
328
|
+
embedding: '向量化',
|
329
|
+
image: '图片',
|
330
|
+
stt: 'ASR',
|
331
|
+
tts: 'TTS',
|
332
|
+
},
|
324
333
|
},
|
325
334
|
sortModal: {
|
326
335
|
success: '排序更新成功',
|
package/src/server/ld.ts
CHANGED
@@ -22,7 +22,7 @@ export const AUTHOR_LIST = {
|
|
22
22
|
avatar: 'https://avatars.githubusercontent.com/u/17870709?v=4',
|
23
23
|
desc: 'Founder, Design Engineer',
|
24
24
|
name: 'CanisMinor',
|
25
|
-
url: 'https://github.com/
|
25
|
+
url: 'https://github.com/canisminor1990',
|
26
26
|
},
|
27
27
|
lobehub: {
|
28
28
|
avatar: 'https://avatars.githubusercontent.com/u/131470832?v=4',
|
@@ -1,3 +1,4 @@
|
|
1
|
+
import { ChatErrorType } from '@lobechat/types/fetch';
|
1
2
|
import { LobeChatPluginManifest } from '@lobehub/chat-plugin-sdk';
|
2
3
|
import { act } from '@testing-library/react';
|
3
4
|
import { merge } from 'lodash-es';
|
@@ -35,7 +36,6 @@ import { UserStore } from '@/store/user';
|
|
35
36
|
import { UserSettingsState, initialSettingsState } from '@/store/user/slices/settings/initialState';
|
36
37
|
import { DalleManifest } from '@/tools/dalle';
|
37
38
|
import { WebBrowsingManifest } from '@/tools/web-browsing';
|
38
|
-
import { ChatErrorType } from '@/types/fetch';
|
39
39
|
import { ChatImageItem, ChatMessage } from '@/types/message';
|
40
40
|
import { ChatStreamPayload, type OpenAIChatMessage } from '@/types/openai/chat';
|
41
41
|
import { LobeTool } from '@/types/tool';
|
package/src/services/chat.ts
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
import { ChatErrorType } from '@lobechat/types/fetch';
|
1
2
|
import { PluginRequestPayload, createHeadersWithPluginSettings } from '@lobehub/chat-plugin-sdk';
|
2
3
|
import { produce } from 'immer';
|
3
4
|
import { merge } from 'lodash-es';
|
@@ -34,7 +35,6 @@ import {
|
|
34
35
|
} from '@/store/user/selectors';
|
35
36
|
import { WebBrowsingManifest } from '@/tools/web-browsing';
|
36
37
|
import { WorkingModel } from '@/types/agent';
|
37
|
-
import { ChatErrorType } from '@/types/fetch';
|
38
38
|
import { ChatImageItem, ChatMessage, MessageToolCall } from '@/types/message';
|
39
39
|
import type { ChatStreamPayload, OpenAIChatMessage } from '@/types/openai/chat';
|
40
40
|
import { UserMessageContentPart } from '@/types/openai/chat';
|
@@ -26,7 +26,9 @@ class ElectronSystemService {
|
|
26
26
|
return dispatch('minimizeWindow');
|
27
27
|
}
|
28
28
|
|
29
|
-
|
29
|
+
showContextMenu = async (type: string, data?: any) => {
|
30
|
+
return dispatch('showContextMenu', { data, type });
|
31
|
+
};
|
30
32
|
}
|
31
33
|
|
32
34
|
// Export a singleton instance of the service
|
@@ -1,5 +1,6 @@
|
|
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 { ChatErrorType } from '@lobechat/types/fetch';
|
3
4
|
import { copyToClipboard } from '@lobehub/ui';
|
4
5
|
import isEqual from 'fast-deep-equal';
|
5
6
|
import { SWRResponse, mutate } from 'swr';
|
@@ -12,7 +13,6 @@ import { topicService } from '@/services/topic';
|
|
12
13
|
import { traceService } from '@/services/trace';
|
13
14
|
import { ChatStore } from '@/store/chat/store';
|
14
15
|
import { messageMapKey } from '@/store/chat/utils/messageMapKey';
|
15
|
-
import { ChatErrorType } from '@/types/fetch';
|
16
16
|
import {
|
17
17
|
ChatMessage,
|
18
18
|
ChatMessageError,
|
@@ -1,4 +1,5 @@
|
|
1
1
|
/* eslint-disable sort-keys-fix/sort-keys-fix, typescript-sort-keys/interface */
|
2
|
+
import { ChatErrorType } from '@lobechat/types/fetch';
|
2
3
|
import { PluginErrorType } from '@lobehub/chat-plugin-sdk';
|
3
4
|
import isEqual from 'fast-deep-equal';
|
4
5
|
import { t } from 'i18next';
|
@@ -13,7 +14,6 @@ import { ChatStore } from '@/store/chat/store';
|
|
13
14
|
import { useToolStore } from '@/store/tool';
|
14
15
|
import { pluginSelectors } from '@/store/tool/selectors';
|
15
16
|
import { builtinTools } from '@/tools';
|
16
|
-
import { ChatErrorType } from '@/types/fetch';
|
17
17
|
import {
|
18
18
|
ChatMessage,
|
19
19
|
ChatMessageError,
|
@@ -11,12 +11,17 @@ interface GlobalStoreProviderProps {
|
|
11
11
|
children: ReactNode;
|
12
12
|
featureFlags?: Partial<IFeatureFlags>;
|
13
13
|
isMobile?: boolean;
|
14
|
+
segmentVariants?: string;
|
14
15
|
serverConfig?: GlobalServerConfig;
|
15
16
|
}
|
16
17
|
|
17
18
|
export const ServerConfigStoreProvider = memo<GlobalStoreProviderProps>(
|
18
|
-
({ children, featureFlags, serverConfig, isMobile }) => (
|
19
|
-
<Provider
|
19
|
+
({ children, featureFlags, serverConfig, isMobile, segmentVariants }) => (
|
20
|
+
<Provider
|
21
|
+
createStore={() =>
|
22
|
+
createServerConfigStore({ featureFlags, isMobile, segmentVariants, serverConfig })
|
23
|
+
}
|
24
|
+
>
|
20
25
|
{children}
|
21
26
|
</Provider>
|
22
27
|
),
|
@@ -15,11 +15,13 @@ import { ServerConfigAction, createServerConfigSlice } from './action';
|
|
15
15
|
interface ServerConfigState {
|
16
16
|
featureFlags: IFeatureFlags;
|
17
17
|
isMobile?: boolean;
|
18
|
+
segmentVariants?: string;
|
18
19
|
serverConfig: GlobalServerConfig;
|
19
20
|
}
|
20
21
|
|
21
22
|
const initialState: ServerConfigState = {
|
22
23
|
featureFlags: DEFAULT_FEATURE_FLAGS,
|
24
|
+
segmentVariants: '',
|
23
25
|
serverConfig: { aiProvider: {}, telemetry: {} },
|
24
26
|
};
|
25
27
|
|
@@ -1,7 +1,7 @@
|
|
1
|
+
import { ChatErrorType } from '@lobechat/types/fetch';
|
1
2
|
import { describe, expect, it, vi } from 'vitest';
|
2
3
|
|
3
4
|
import { AgentRuntimeErrorType } from '@/libs/model-runtime';
|
4
|
-
import { ChatErrorType } from '@/types/fetch';
|
5
5
|
|
6
6
|
import { createErrorResponse } from './errorResponse';
|
7
7
|
|
@@ -1,5 +1,6 @@
|
|
1
|
+
import { ChatErrorType, ErrorResponse, ErrorType } from '@lobechat/types/fetch';
|
2
|
+
|
1
3
|
import { AgentRuntimeErrorType, ILobeAgentRuntimeErrorType } from '@/libs/model-runtime';
|
2
|
-
import { ChatErrorType, ErrorResponse, ErrorType } from '@/types/fetch';
|
3
4
|
|
4
5
|
const getStatus = (errorType: ILobeAgentRuntimeErrorType | ErrorType) => {
|
5
6
|
// InvalidAccessCode / InvalidAzureAPIKey / InvalidOpenAIAPIKey / InvalidZhipuAPIKey ....
|
@@ -1,7 +1,8 @@
|
|
1
|
+
import { ChatErrorType } from '@lobechat/types/fetch';
|
2
|
+
|
1
3
|
import { MESSAGE_CANCEL_FLAT } from '@/const/message';
|
2
4
|
import { LOBE_CHAT_OBSERVATION_ID, LOBE_CHAT_TRACE_ID } from '@/const/trace';
|
3
5
|
import { parseToolCalls } from '@/libs/model-runtime';
|
4
|
-
import { ChatErrorType } from '@/types/fetch';
|
5
6
|
import { ResponseAnimation, ResponseAnimationStyle } from '@/types/llm';
|
6
7
|
import {
|
7
8
|
ChatMessageError,
|
@@ -1,6 +1,6 @@
|
|
1
|
+
import { ErrorResponse, ErrorType } from '@lobechat/types/fetch';
|
1
2
|
import { t } from 'i18next';
|
2
3
|
|
3
|
-
import { ErrorResponse, ErrorType } from '@/types/fetch';
|
4
4
|
import { ChatMessageError } from '@/types/message';
|
5
5
|
|
6
6
|
export const getMessageError = async (response: Response) => {
|
package/tsconfig.json
CHANGED
@@ -18,7 +18,7 @@
|
|
18
18
|
"baseUrl": ".",
|
19
19
|
"types": ["vitest/globals", "@serwist/next/typings"],
|
20
20
|
"paths": {
|
21
|
-
"@/types/*": ["./packages/types/src/*"],
|
21
|
+
"@/types/*": ["./packages/types/src/*", "./src/types/*"],
|
22
22
|
"@/*": ["./src/*"],
|
23
23
|
"~test-utils": ["./tests/utils.tsx"]
|
24
24
|
},
|
package/.dockerignore
DELETED
Binary file
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
File without changes
|