@lobehub/chat 1.19.31 → 1.19.32
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 +25 -0
- package/next.config.mjs +5 -7
- package/package.json +3 -2
- package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/TextArea.test.tsx +1 -0
- package/src/app/sw.ts +26 -0
- package/src/config/modelProviders/taichu.ts +5 -2
- package/src/features/FileViewer/Renderer/Image/index.tsx +1 -0
- package/src/features/PWAInstall/Install.tsx +80 -0
- package/src/features/PWAInstall/index.tsx +6 -61
- package/src/server/services/discover/index.ts +1 -1
- package/src/services/message/server.ts +1 -1
- package/src/services/session/server.ts +2 -2
- package/src/store/chat/slices/plugin/action.ts +3 -1
- package/tsconfig.json +3 -3
package/CHANGELOG.md
CHANGED
@@ -2,6 +2,31 @@
|
|
2
2
|
|
3
3
|
# Changelog
|
4
4
|
|
5
|
+
### [Version 1.19.32](https://github.com/lobehub/lobe-chat/compare/v1.19.31...v1.19.32)
|
6
|
+
|
7
|
+
<sup>Released on **2024-09-25**</sup>
|
8
|
+
|
9
|
+
#### 💄 Styles
|
10
|
+
|
11
|
+
- **misc**: Add function call for `taichu_llm`.
|
12
|
+
|
13
|
+
<br/>
|
14
|
+
|
15
|
+
<details>
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
17
|
+
|
18
|
+
#### Styles
|
19
|
+
|
20
|
+
- **misc**: Add function call for `taichu_llm`, closes [#4119](https://github.com/lobehub/lobe-chat/issues/4119) ([8f629d8](https://github.com/lobehub/lobe-chat/commit/8f629d8))
|
21
|
+
|
22
|
+
</details>
|
23
|
+
|
24
|
+
<div align="right">
|
25
|
+
|
26
|
+
[](#readme-top)
|
27
|
+
|
28
|
+
</div>
|
29
|
+
|
5
30
|
### [Version 1.19.31](https://github.com/lobehub/lobe-chat/compare/v1.19.30...v1.19.31)
|
6
31
|
|
7
32
|
<sup>Released on **2024-09-24**</sup>
|
package/next.config.mjs
CHANGED
@@ -1,6 +1,6 @@
|
|
1
|
-
import nextPWA from '@ducanh2912/next-pwa';
|
2
1
|
import analyzer from '@next/bundle-analyzer';
|
3
2
|
import { withSentryConfig } from '@sentry/nextjs';
|
3
|
+
import withSerwistInit from '@serwist/next';
|
4
4
|
|
5
5
|
const isProd = process.env.NODE_ENV === 'production';
|
6
6
|
const buildWithDocker = process.env.DOCKER === 'true';
|
@@ -192,12 +192,10 @@ const noWrapper = (config) => config;
|
|
192
192
|
const withBundleAnalyzer = process.env.ANALYZE === 'true' ? analyzer() : noWrapper;
|
193
193
|
|
194
194
|
const withPWA = isProd
|
195
|
-
?
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
skipWaiting: true,
|
200
|
-
},
|
195
|
+
? withSerwistInit({
|
196
|
+
register: false,
|
197
|
+
swDest: 'public/sw.js',
|
198
|
+
swSrc: 'src/app/sw.ts',
|
201
199
|
})
|
202
200
|
: noWrapper;
|
203
201
|
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@lobehub/chat",
|
3
|
-
"version": "1.19.
|
3
|
+
"version": "1.19.32",
|
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",
|
@@ -127,6 +127,7 @@
|
|
127
127
|
"@next/third-parties": "^14.2.6",
|
128
128
|
"@react-spring/web": "^9.7.3",
|
129
129
|
"@sentry/nextjs": "^7.119.0",
|
130
|
+
"@serwist/next": "^9.0.8",
|
130
131
|
"@t3-oss/env-nextjs": "^0.11.0",
|
131
132
|
"@tanstack/react-query": "^5.52.1",
|
132
133
|
"@trpc/client": "next",
|
@@ -232,7 +233,6 @@
|
|
232
233
|
},
|
233
234
|
"devDependencies": {
|
234
235
|
"@commitlint/cli": "^19.4.0",
|
235
|
-
"@ducanh2912/next-pwa": "^10.2.8",
|
236
236
|
"@edge-runtime/vm": "^4.0.2",
|
237
237
|
"@lobehub/i18n-cli": "^1.19.1",
|
238
238
|
"@lobehub/lint": "^1.24.4",
|
@@ -288,6 +288,7 @@
|
|
288
288
|
"remark-cli": "^11.0.0",
|
289
289
|
"remark-parse": "^10.0.2",
|
290
290
|
"semantic-release": "^21.1.2",
|
291
|
+
"serwist": "^9.0.8",
|
291
292
|
"stylelint": "^15.11.0",
|
292
293
|
"supports-color": "8",
|
293
294
|
"tsx": "^4.17.0",
|
package/src/app/(main)/chat/(workspace)/@conversation/features/ChatInput/Desktop/TextArea.test.tsx
CHANGED
@@ -150,6 +150,7 @@ describe('<InputArea />', () => {
|
|
150
150
|
const beforeUnloadHandler = vi.fn();
|
151
151
|
|
152
152
|
addEventListenerSpy.mockImplementation((event, handler) => {
|
153
|
+
// @ts-ignore
|
153
154
|
if (event === 'beforeunload') {
|
154
155
|
beforeUnloadHandler.mockImplementation(handler as any);
|
155
156
|
}
|
package/src/app/sw.ts
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
import { defaultCache } from '@serwist/next/worker';
|
2
|
+
import type { PrecacheEntry, SerwistGlobalConfig } from 'serwist';
|
3
|
+
import { Serwist } from 'serwist';
|
4
|
+
|
5
|
+
// This declares the value of `injectionPoint` to TypeScript.
|
6
|
+
// `injectionPoint` is the string that will be replaced by the
|
7
|
+
// actual precache manifest. By default, this string is set to
|
8
|
+
// `"self.__SW_MANIFEST"`.
|
9
|
+
declare global {
|
10
|
+
interface WorkerGlobalScope extends SerwistGlobalConfig {
|
11
|
+
__SW_MANIFEST: (PrecacheEntry | string)[] | undefined;
|
12
|
+
}
|
13
|
+
}
|
14
|
+
|
15
|
+
// eslint-disable-next-line no-undef
|
16
|
+
declare const self: ServiceWorkerGlobalScope;
|
17
|
+
|
18
|
+
const serwist = new Serwist({
|
19
|
+
clientsClaim: true,
|
20
|
+
navigationPreload: true,
|
21
|
+
precacheEntries: self.__SW_MANIFEST,
|
22
|
+
runtimeCaching: defaultCache,
|
23
|
+
skipWaiting: true,
|
24
|
+
});
|
25
|
+
|
26
|
+
serwist.addEventListeners();
|
@@ -8,11 +8,13 @@ const Taichu: ModelProviderCard = {
|
|
8
8
|
'Taichu 2.0 基于海量高质数据训练,具有更强的文本理解、内容创作、对话问答等能力',
|
9
9
|
displayName: 'Taichu 2.0',
|
10
10
|
enabled: true,
|
11
|
-
functionCall:
|
11
|
+
functionCall: true,
|
12
12
|
id: 'taichu_llm',
|
13
13
|
tokens: 32_768,
|
14
14
|
},
|
15
|
-
|
15
|
+
/*
|
16
|
+
// TODO: Not support for now
|
17
|
+
{
|
16
18
|
description:
|
17
19
|
'Taichu 2.0V 融合了图像理解、知识迁移、逻辑归因等能力,在图文问答领域表现突出',
|
18
20
|
displayName: 'Taichu 2.0V',
|
@@ -20,6 +22,7 @@ const Taichu: ModelProviderCard = {
|
|
20
22
|
tokens: 4096,
|
21
23
|
vision: true,
|
22
24
|
},
|
25
|
+
*/
|
23
26
|
],
|
24
27
|
checkModel: 'taichu_llm',
|
25
28
|
description:
|
@@ -0,0 +1,80 @@
|
|
1
|
+
'use client';
|
2
|
+
|
3
|
+
import dynamic from 'next/dynamic';
|
4
|
+
import { memo, useEffect, useLayoutEffect } from 'react';
|
5
|
+
import { useTranslation } from 'react-i18next';
|
6
|
+
|
7
|
+
import { BRANDING_NAME } from '@/const/branding';
|
8
|
+
import { PWA_INSTALL_ID } from '@/const/layoutTokens';
|
9
|
+
import { usePWAInstall } from '@/hooks/usePWAInstall';
|
10
|
+
import { useGlobalStore } from '@/store/global';
|
11
|
+
import { systemStatusSelectors } from '@/store/global/selectors';
|
12
|
+
import { useUserStore } from '@/store/user';
|
13
|
+
|
14
|
+
// @ts-ignore
|
15
|
+
const PWA: any = dynamic(() => import('@khmyznikov/pwa-install/dist/pwa-install.react.js'), {
|
16
|
+
ssr: false,
|
17
|
+
});
|
18
|
+
|
19
|
+
const PWAInstall = memo(() => {
|
20
|
+
const { t } = useTranslation('metadata');
|
21
|
+
|
22
|
+
const { install, canInstall } = usePWAInstall();
|
23
|
+
|
24
|
+
const isShowPWAGuide = useUserStore((s) => s.isShowPWAGuide);
|
25
|
+
const [hidePWAInstaller, updateSystemStatus] = useGlobalStore((s) => [
|
26
|
+
systemStatusSelectors.hidePWAInstaller(s),
|
27
|
+
s.updateSystemStatus,
|
28
|
+
]);
|
29
|
+
|
30
|
+
// we need to make the pwa installer hidden by default
|
31
|
+
useLayoutEffect(() => {
|
32
|
+
sessionStorage.setItem('pwa-hide-install', 'true');
|
33
|
+
}, []);
|
34
|
+
|
35
|
+
const pwaInstall =
|
36
|
+
// eslint-disable-next-line unicorn/prefer-query-selector
|
37
|
+
typeof window === 'undefined' ? undefined : document.getElementById(PWA_INSTALL_ID);
|
38
|
+
|
39
|
+
// add an event listener to control the user close installer action
|
40
|
+
useEffect(() => {
|
41
|
+
if (!pwaInstall) return;
|
42
|
+
|
43
|
+
const handler = (e: Event) => {
|
44
|
+
const event = e as CustomEvent;
|
45
|
+
|
46
|
+
// it means user hide installer
|
47
|
+
if (event.detail.message === 'dismissed') {
|
48
|
+
updateSystemStatus({ hidePWAInstaller: true });
|
49
|
+
}
|
50
|
+
};
|
51
|
+
|
52
|
+
pwaInstall.addEventListener('pwa-user-choice-result-event', handler);
|
53
|
+
return () => {
|
54
|
+
pwaInstall.removeEventListener('pwa-user-choice-result-event', handler);
|
55
|
+
};
|
56
|
+
}, [pwaInstall]);
|
57
|
+
|
58
|
+
// trigger the PWA guide on demand
|
59
|
+
useEffect(() => {
|
60
|
+
if (!canInstall || hidePWAInstaller) return;
|
61
|
+
|
62
|
+
// trigger the pwa installer and register the service worker
|
63
|
+
if (isShowPWAGuide) {
|
64
|
+
install();
|
65
|
+
if ('serviceWorker' in navigator && window.serwist !== undefined) {
|
66
|
+
window.serwist.register();
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}, [canInstall, hidePWAInstaller, isShowPWAGuide]);
|
70
|
+
|
71
|
+
return (
|
72
|
+
<PWA
|
73
|
+
description={t('chat.description', { appName: BRANDING_NAME })}
|
74
|
+
id={PWA_INSTALL_ID}
|
75
|
+
manifest-url={'/manifest.webmanifest'}
|
76
|
+
/>
|
77
|
+
);
|
78
|
+
});
|
79
|
+
|
80
|
+
export default PWAInstall;
|
@@ -1,79 +1,24 @@
|
|
1
1
|
'use client';
|
2
2
|
|
3
3
|
import dynamic from 'next/dynamic';
|
4
|
-
import { memo
|
5
|
-
import { useTranslation } from 'react-i18next';
|
4
|
+
import { memo } from 'react';
|
6
5
|
|
7
|
-
import { BRANDING_NAME } from '@/const/branding';
|
8
|
-
import { PWA_INSTALL_ID } from '@/const/layoutTokens';
|
9
|
-
import { usePWAInstall } from '@/hooks/usePWAInstall';
|
10
6
|
import { usePlatform } from '@/hooks/usePlatform';
|
11
|
-
import { useGlobalStore } from '@/store/global';
|
12
|
-
import { systemStatusSelectors } from '@/store/global/selectors';
|
13
7
|
import { useUserStore } from '@/store/user';
|
14
8
|
|
15
|
-
|
16
|
-
const PWA: any = dynamic(() => import('@khmyznikov/pwa-install/dist/pwa-install.react.js'), {
|
9
|
+
const Install: any = dynamic(() => import('./Install'), {
|
17
10
|
ssr: false,
|
18
11
|
});
|
19
12
|
|
20
13
|
const PWAInstall = memo(() => {
|
21
|
-
const { t } = useTranslation('metadata');
|
22
14
|
const { isPWA } = usePlatform();
|
23
|
-
|
24
|
-
const { install, canInstall } = usePWAInstall();
|
25
|
-
|
26
15
|
const isShowPWAGuide = useUserStore((s) => s.isShowPWAGuide);
|
27
|
-
const [hidePWAInstaller, updateSystemStatus] = useGlobalStore((s) => [
|
28
|
-
systemStatusSelectors.hidePWAInstaller(s),
|
29
|
-
s.updateSystemStatus,
|
30
|
-
]);
|
31
|
-
|
32
|
-
// we need to make the pwa installer hidden by default
|
33
|
-
useLayoutEffect(() => {
|
34
|
-
sessionStorage.setItem('pwa-hide-install', 'true');
|
35
|
-
}, []);
|
36
|
-
|
37
|
-
const pwaInstall =
|
38
|
-
// eslint-disable-next-line unicorn/prefer-query-selector
|
39
|
-
typeof window === 'undefined' ? undefined : document.getElementById(PWA_INSTALL_ID);
|
40
|
-
|
41
|
-
// add an event listener to control the user close installer action
|
42
|
-
useEffect(() => {
|
43
|
-
if (!pwaInstall) return;
|
44
|
-
|
45
|
-
const handler = (e: Event) => {
|
46
|
-
const event = e as CustomEvent;
|
47
|
-
|
48
|
-
// it means user hide installer
|
49
|
-
if (event.detail.message === 'dismissed') {
|
50
|
-
updateSystemStatus({ hidePWAInstaller: true });
|
51
|
-
}
|
52
|
-
};
|
53
|
-
|
54
|
-
pwaInstall.addEventListener('pwa-user-choice-result-event', handler);
|
55
|
-
return () => {
|
56
|
-
pwaInstall.removeEventListener('pwa-user-choice-result-event', handler);
|
57
|
-
};
|
58
|
-
}, [pwaInstall]);
|
59
|
-
|
60
|
-
// trigger the PWA guide on demand
|
61
|
-
useEffect(() => {
|
62
|
-
if (!canInstall || hidePWAInstaller) return;
|
63
16
|
|
64
|
-
|
65
|
-
install();
|
66
|
-
}
|
67
|
-
}, [canInstall, hidePWAInstaller, isShowPWAGuide]);
|
17
|
+
if (isPWA || !isShowPWAGuide) return null;
|
68
18
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
description={t('chat.description', { appName: BRANDING_NAME })}
|
73
|
-
id={PWA_INSTALL_ID}
|
74
|
-
manifest-url={'/manifest.webmanifest'}
|
75
|
-
/>
|
76
|
-
);
|
19
|
+
// only when the user is suitable for the pwa install and not install the pwa
|
20
|
+
// then show the installation guide
|
21
|
+
return <Install />;
|
77
22
|
});
|
78
23
|
|
79
24
|
export default PWAInstall;
|
@@ -212,7 +212,7 @@ export class DiscoverService {
|
|
212
212
|
// Providers
|
213
213
|
|
214
214
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
215
|
-
getProviderList = async (
|
215
|
+
getProviderList = async (_locale: Locales): Promise<DiscoverProviderItem[]> => {
|
216
216
|
const list = DEFAULT_MODEL_PROVIDER_LIST.filter((item) => item.chatModels.length > 0);
|
217
217
|
return list.map((item) => {
|
218
218
|
const provider = {
|
@@ -79,7 +79,7 @@ export class ServerService implements IMessageService {
|
|
79
79
|
return lambdaClient.message.updatePluginState.mutate({ id, value });
|
80
80
|
}
|
81
81
|
|
82
|
-
bindMessagesToTopic(
|
82
|
+
bindMessagesToTopic(_topicId: string, _messageIds: string[]): Promise<any> {
|
83
83
|
throw new Error('Method not implemented.');
|
84
84
|
}
|
85
85
|
|
@@ -91,7 +91,7 @@ export class ServerService implements ISessionService {
|
|
91
91
|
return lambdaClient.session.updateSessionChatConfig.mutate({ id, value }, { signal });
|
92
92
|
}
|
93
93
|
|
94
|
-
getSessionsByType(
|
94
|
+
getSessionsByType(_type: 'agent' | 'group' | 'all' = 'all'): Promise<LobeSessions> {
|
95
95
|
// TODO: need be fixed
|
96
96
|
// @ts-ignore
|
97
97
|
return lambdaClient.session.getSessions.query({});
|
@@ -121,7 +121,7 @@ export class ServerService implements ISessionService {
|
|
121
121
|
return lambdaClient.sessionGroup.getSessionGroup.query();
|
122
122
|
}
|
123
123
|
|
124
|
-
batchCreateSessionGroups(
|
124
|
+
batchCreateSessionGroups(_groups: SessionGroups): Promise<BatchTaskResult> {
|
125
125
|
return Promise.resolve({ added: 0, ids: [], skips: [], success: true });
|
126
126
|
}
|
127
127
|
|
package/tsconfig.json
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
"$schema": "https://json.schemastore.org/tsconfig",
|
3
3
|
"compilerOptions": {
|
4
4
|
"target": "ESNext",
|
5
|
-
"lib": ["dom", "dom.iterable", "esnext"],
|
5
|
+
"lib": ["dom", "dom.iterable", "esnext", "webworker"],
|
6
6
|
"allowJs": true,
|
7
7
|
"skipLibCheck": true,
|
8
8
|
"strict": true,
|
@@ -16,7 +16,7 @@
|
|
16
16
|
"jsx": "preserve",
|
17
17
|
"incremental": true,
|
18
18
|
"baseUrl": ".",
|
19
|
-
"types": ["vitest/globals"],
|
19
|
+
"types": ["vitest/globals", "@serwist/next/typings"],
|
20
20
|
"paths": {
|
21
21
|
"@/*": ["./src/*"],
|
22
22
|
"~test-utils": ["./tests/utils.tsx"]
|
@@ -27,7 +27,7 @@
|
|
27
27
|
}
|
28
28
|
]
|
29
29
|
},
|
30
|
-
"exclude": ["node_modules"],
|
30
|
+
"exclude": ["node_modules", "public/sw.js"],
|
31
31
|
"include": [
|
32
32
|
"next-env.d.ts",
|
33
33
|
"vitest.config.ts",
|