@lobehub/chat 0.41.1 → 0.42.0

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 (60) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/locales/en_US/error.json +1 -0
  3. package/locales/en_US/plugin.json +5 -0
  4. package/locales/en_US/welcome.json +14 -0
  5. package/locales/zh_CN/error.json +1 -0
  6. package/locales/zh_CN/plugin.json +5 -0
  7. package/locales/zh_CN/welcome.json +14 -0
  8. package/package.json +1 -1
  9. package/src/components/DiscordIcon/index.tsx +15 -0
  10. package/src/const/url.ts +7 -0
  11. package/src/features/AvatarWithUpload/index.tsx +1 -2
  12. package/src/features/FolderPanel/index.tsx +4 -5
  13. package/src/features/SideBar/BottomActions.tsx +7 -6
  14. package/src/features/SideBar/TopActions.tsx +1 -1
  15. package/src/features/SideBar/index.tsx +1 -2
  16. package/src/layout/AppLayout.tsx +15 -0
  17. package/src/layout/index.tsx +6 -6
  18. package/src/locales/default/common.ts +1 -0
  19. package/src/locales/default/welcome.ts +14 -0
  20. package/src/locales/resources/zh_CN.ts +2 -0
  21. package/src/pages/chat/SessionList/Header.tsx +2 -6
  22. package/src/pages/chat/SessionList/List/SessionItem.tsx +2 -2
  23. package/src/pages/chat/SessionList/List/index.tsx +2 -6
  24. package/src/pages/chat/[id]/Conversation/ChatList/Error/ApiKeyForm.tsx +1 -5
  25. package/src/pages/chat/[id]/Conversation/ChatList/Error/InvalidAccess.tsx +2 -6
  26. package/src/pages/chat/[id]/Conversation/ChatList/Error/OpenAiBizError.tsx +1 -5
  27. package/src/pages/chat/[id]/Conversation/ChatList/MessageExtra.tsx +1 -2
  28. package/src/pages/chat/[id]/Conversation/ChatList/index.tsx +7 -11
  29. package/src/pages/chat/[id]/Conversation/Input/Action.tsx +1 -2
  30. package/src/pages/chat/[id]/Conversation/Input/ActionRight.tsx +1 -2
  31. package/src/pages/chat/[id]/Conversation/Input/Token.tsx +6 -10
  32. package/src/pages/chat/[id]/Conversation/Input/index.tsx +6 -6
  33. package/src/pages/chat/[id]/Header/index.tsx +13 -17
  34. package/src/pages/chat/[id]/Sidebar/Inner.tsx +45 -28
  35. package/src/pages/chat/[id]/Sidebar/Topic/TopicContent.tsx +5 -5
  36. package/src/pages/chat/[id]/Sidebar/Topic/TopicItem.tsx +1 -2
  37. package/src/pages/chat/[id]/Sidebar/Topic/index.tsx +2 -6
  38. package/src/pages/chat/[id]/Sidebar/index.tsx +4 -5
  39. package/src/pages/chat/[id]/index.page.tsx +5 -6
  40. package/src/pages/chat/{layout.tsx → [id]/layout.tsx} +4 -12
  41. package/src/pages/chat/[id]/setting/index.page.tsx +10 -14
  42. package/src/pages/chat/index.page.tsx +1 -24
  43. package/src/pages/index.page.tsx +33 -1
  44. package/src/pages/settings/Settings/Agent.tsx +5 -5
  45. package/src/pages/settings/Settings/Common.tsx +5 -9
  46. package/src/pages/settings/ThemeSwatches/ThemeSwatchesNeutral.tsx +1 -5
  47. package/src/pages/settings/ThemeSwatches/ThemeSwatchesPrimary.tsx +1 -5
  48. package/src/pages/welcome/Banner/AgentCard.tsx +71 -0
  49. package/src/pages/welcome/Banner/AgentTemplate.tsx +43 -0
  50. package/src/pages/welcome/Banner/Hero.tsx +39 -0
  51. package/src/pages/welcome/Banner/index.tsx +56 -0
  52. package/src/pages/welcome/Footer/index.tsx +24 -0
  53. package/src/pages/welcome/index.page.tsx +28 -0
  54. package/src/pages/welcome/layout.tsx +31 -0
  55. package/src/pages/welcome/style.ts +63 -0
  56. package/src/store/session/slices/session/selectors/index.ts +2 -0
  57. package/src/store/session/slices/session/selectors/list.ts +5 -0
  58. package/src/store/session/store.ts +2 -2
  59. package/src/store/settings/hooks/useHydrated.ts +20 -0
  60. package/src/store/settings/store.ts +2 -2
package/CHANGELOG.md CHANGED
@@ -2,6 +2,57 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 0.42.0](https://github.com/lobehub/lobe-chat/compare/v0.41.2...v0.42.0)
6
+
7
+ <sup>Released on **2023-08-11**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: Add `Welcome` page.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: Add `Welcome` page, closes [#60](https://github.com/lobehub/lobe-chat/issues/60) ([810ab0f](https://github.com/lobehub/lobe-chat/commit/810ab0f))
21
+
22
+ </details>
23
+
24
+ <div align="right">
25
+
26
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
27
+
28
+ </div>
29
+
30
+ ### [Version 0.41.2](https://github.com/lobehub/lobe-chat/compare/v0.41.1...v0.41.2)
31
+
32
+ <sup>Released on **2023-08-10**</sup>
33
+
34
+ #### ♻ Code Refactoring
35
+
36
+ - **misc**: 将 sessionStore 默认 equalFn 改为 shallow, 将 settingStore 默认 equalFn 改为 shallow.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### Code refactoring
44
+
45
+ - **misc**: 将 sessionStore 默认 equalFn 改为 shallow ([5c1b8d7](https://github.com/lobehub/lobe-chat/commit/5c1b8d7))
46
+ - **misc**: 将 settingStore 默认 equalFn 改为 shallow ([1e72308](https://github.com/lobehub/lobe-chat/commit/1e72308))
47
+
48
+ </details>
49
+
50
+ <div align="right">
51
+
52
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
53
+
54
+ </div>
55
+
5
56
  ### [Version 0.41.1](https://github.com/lobehub/lobe-chat/compare/v0.41.0...v0.41.1)
6
57
 
7
58
  <sup>Released on **2023-08-10**</sup>
@@ -4,6 +4,7 @@
4
4
  "401": "Sorry, the server has rejected your request. This may be due to insufficient permissions or invalid authentication.",
5
5
  "403": "Sorry, the server has rejected your request. You do not have permission to access this content.",
6
6
  "404": "Sorry, the server cannot find the page or resource you requested. Please make sure your URL is correct.",
7
+ "405": "Sorry, the server does not support the request method you are using. Please make sure your request method is correct.",
7
8
  "429": "Sorry, your request is too frequent and the server is a bit tired. Please try again later.",
8
9
  "500": "Sorry, the server seems to be experiencing some difficulties and is temporarily unable to complete your request. Please try again later.",
9
10
  "502": "Sorry, the server seems to be lost and is temporarily unable to provide service. Please try again later.",
@@ -1,4 +1,9 @@
1
1
  {
2
+ "debug": {
3
+ "arguments": "Arguments",
4
+ "function_call": "Function Call",
5
+ "response": "Response"
6
+ },
2
7
  "loading": {
3
8
  "content": "Loading data...",
4
9
  "plugin": "Plugin is running..."
@@ -0,0 +1,14 @@
1
+ {
2
+ "button": {
3
+ "import": "Import Configuration",
4
+ "start": "Start Now"
5
+ },
6
+ "header": "Welcome",
7
+ "pickAgent": "Or choose from the following assistant templates",
8
+ "skip": "Skip Creation",
9
+ "slogan": {
10
+ "desc1": "Unlock the power of your brain and ignite your creativity. Your intelligent assistant is always here.",
11
+ "desc2": "Create your first assistant and let's get started~",
12
+ "title": "Give yourself a smarter brain"
13
+ }
14
+ }
@@ -4,6 +4,7 @@
4
4
  "401": "很抱歉,服务器拒绝了您的请求,可能是因为您的权限不足或未提供有效的身份验证",
5
5
  "403": "很抱歉,服务器拒绝了您的请求,您没有访问此内容的权限 ",
6
6
  "404": "很抱歉,服务器找不到您请求的页面或资源,请确认您的 URL 是否正确",
7
+ "405": "很抱歉,服务器不支持您使用的请求方法,请确认您的请求方法是否正确",
7
8
  "429": "很抱歉,您的请求太多,服务器有点累了,请稍后再试",
8
9
  "500": "很抱歉,服务器似乎遇到了一些困难,暂时无法完成您的请求,请稍后再试",
9
10
  "502": "很抱歉,服务器似乎迷失了方向,暂时无法提供服务,请稍后再试",
@@ -1,4 +1,9 @@
1
1
  {
2
+ "debug": {
3
+ "arguments": "调用参数",
4
+ "function_call": "函数调用",
5
+ "response": "返回结果"
6
+ },
2
7
  "loading": {
3
8
  "content": "数据获取中...",
4
9
  "plugin": "插件运行中..."
@@ -0,0 +1,14 @@
1
+ {
2
+ "button": {
3
+ "import": "导入配置",
4
+ "start": "立即开始"
5
+ },
6
+ "header": "欢迎使用",
7
+ "pickAgent": "或从下列助手模板选择",
8
+ "skip": "跳过创建",
9
+ "slogan": {
10
+ "desc1": "开启大脑集群,激发思维火花。你的智能助理,一直都在。",
11
+ "desc2": "创建你的第一个助手,让我们开始吧~",
12
+ "title": "给自己一个更聪明的大脑"
13
+ }
14
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.41.1",
3
+ "version": "0.42.0",
4
4
  "description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -0,0 +1,15 @@
1
+ import { type LucideIcon, createLucideIcon } from 'lucide-react';
2
+
3
+ const Discord: LucideIcon = createLucideIcon('Discord', [
4
+ [
5
+ 'path',
6
+ {
7
+ d: 'M20.317 4.3698a19.7913 19.7913 0 00-4.8851-1.5152.0741.0741 0 00-.0785.0371c-.211.3753-.4447.8648-.6083 1.2495-1.8447-.2762-3.68-.2762-5.4868 0-.1636-.3933-.4058-.8742-.6177-1.2495a.077.077 0 00-.0785-.037 19.7363 19.7363 0 00-4.8852 1.515.0699.0699 0 00-.0321.0277C.5334 9.0458-.319 13.5799.0992 18.0578a.0824.0824 0 00.0312.0561c2.0528 1.5076 4.0413 2.4228 5.9929 3.0294a.0777.0777 0 00.0842-.0276c.4616-.6304.8731-1.2952 1.226-1.9942a.076.076 0 00-.0416-.1057c-.6528-.2476-1.2743-.5495-1.8722-.8923a.077.077 0 01-.0076-.1277c.1258-.0943.2517-.1923.3718-.2914a.0743.0743 0 01.0776-.0105c3.9278 1.7933 8.18 1.7933 12.0614 0a.0739.0739 0 01.0785.0095c.1202.099.246.1981.3728.2924a.077.077 0 01-.0066.1276 12.2986 12.2986 0 01-1.873.8914.0766.0766 0 00-.0407.1067c.3604.698.7719 1.3628 1.225 1.9932a.076.076 0 00.0842.0286c1.961-.6067 3.9495-1.5219 6.0023-3.0294a.077.077 0 00.0313-.0552c.5004-5.177-.8382-9.6739-3.5485-13.6604a.061.061 0 00-.0312-.0286zM8.02 15.3312c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9555-2.4189 2.157-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.9555 2.4189-2.1569 2.4189zm7.9748 0c-1.1825 0-2.1569-1.0857-2.1569-2.419 0-1.3332.9554-2.4189 2.1569-2.4189 1.2108 0 2.1757 1.0952 2.1568 2.419 0 1.3332-.946 2.4189-2.1568 2.4189Z',
8
+ key: '18tl5t',
9
+ },
10
+ ],
11
+ ]);
12
+
13
+ const DiscordIcon = (props: LucideIcon) => <Discord style={{ overflow: 'visible' }} {...props} />;
14
+
15
+ export default DiscordIcon as LucideIcon;
@@ -0,0 +1,7 @@
1
+ import pkg from '../../package.json';
2
+
3
+ export const GITHUB = pkg.homepage;
4
+ export const CHANGELOG = `${pkg.homepage}/blob/master/CHANGELOG.md`;
5
+ export const ABOUT = pkg.homepage;
6
+ export const FEEDBACK = pkg.bugs.url;
7
+ export const DISCORD = 'https://discord.gg/AYFPHvv2jT';
@@ -2,7 +2,6 @@ import { Avatar, Logo } from '@lobehub/ui';
2
2
  import { Upload } from 'antd';
3
3
  import { createStyles } from 'antd-style';
4
4
  import { memo } from 'react';
5
- import { shallow } from 'zustand/shallow';
6
5
 
7
6
  import { useSettings } from '@/store/settings';
8
7
  import { createUploadImageHandler } from '@/utils/uploadFIle';
@@ -28,7 +27,7 @@ interface AvatarWithUploadProps {
28
27
  }
29
28
 
30
29
  const AvatarWithUpload = memo<AvatarWithUploadProps>(({ size = 40 }) => {
31
- const [avatar, setSettings] = useSettings((st) => [st.settings.avatar, st.setSettings], shallow);
30
+ const [avatar, setSettings] = useSettings((st) => [st.settings.avatar, st.setSettings]);
32
31
  const { styles } = useStyle();
33
32
 
34
33
  const handleUploadAvatar = createUploadImageHandler((avatar) => {
@@ -2,7 +2,6 @@ import { DraggablePanel, DraggablePanelContainer } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
3
  import isEqual from 'fast-deep-equal';
4
4
  import { PropsWithChildren, memo, useState } from 'react';
5
- import { shallow } from 'zustand/shallow';
6
5
 
7
6
  import { FOLDER_WIDTH } from '@/const/layoutTokens';
8
7
  import { useSettings } from '@/store/settings';
@@ -17,10 +16,10 @@ export const useStyles = createStyles(({ css, token }) => ({
17
16
 
18
17
  const FolderPanel = memo<PropsWithChildren>(({ children }) => {
19
18
  const { styles } = useStyles();
20
- const [sessionsWidth, sessionExpandable] = useSettings(
21
- (s) => [s.sessionsWidth, s.sessionExpandable],
22
- shallow,
23
- );
19
+ const [sessionsWidth, sessionExpandable] = useSettings((s) => [
20
+ s.sessionsWidth,
21
+ s.sessionExpandable,
22
+ ]);
24
23
  const [tmpWidth, setWidth] = useState(sessionsWidth);
25
24
  if (tmpWidth !== sessionsWidth) setWidth(sessionsWidth);
26
25
 
@@ -14,12 +14,12 @@ import Router from 'next/router';
14
14
  import { memo, useMemo } from 'react';
15
15
  import { useTranslation } from 'react-i18next';
16
16
 
17
+ import DiscordIcon from '@/components/DiscordIcon';
18
+ import { ABOUT, CHANGELOG, DISCORD, FEEDBACK, GITHUB } from '@/const/url';
17
19
  import { useExportConfig } from '@/hooks/useExportConfig';
18
20
  import { useImportConfig } from '@/hooks/useImportConfig';
19
21
  import { SettingsStore } from '@/store/settings';
20
22
 
21
- import pkg from '../../../package.json';
22
-
23
23
  export interface BottomActionProps {
24
24
  setTab: SettingsStore['switchSideBar'];
25
25
  tab: SettingsStore['sidebarKey'];
@@ -79,19 +79,19 @@ const BottomActions = memo<BottomActionProps>(({ tab, setTab }) => {
79
79
  icon: <Icon icon={Feather} />,
80
80
  key: 'feedback',
81
81
  label: t('feedback'),
82
- onClick: () => window.open(pkg.bugs.url, '__blank'),
82
+ onClick: () => window.open(FEEDBACK, '__blank'),
83
83
  },
84
84
  {
85
85
  icon: <Icon icon={FileClock} />,
86
86
  key: 'changelog',
87
87
  label: t('changelog'),
88
- onClick: () => window.open(`${pkg.homepage}/blob/master/CHANGELOG.md`, '__blank'),
88
+ onClick: () => window.open(CHANGELOG, '__blank'),
89
89
  },
90
90
  {
91
91
  icon: <Icon icon={Heart} />,
92
92
  key: 'about',
93
93
  label: t('about'),
94
- onClick: () => window.open(pkg.homepage, '__blank'),
94
+ onClick: () => window.open(ABOUT, '__blank'),
95
95
  },
96
96
  {
97
97
  type: 'divider',
@@ -111,7 +111,8 @@ const BottomActions = memo<BottomActionProps>(({ tab, setTab }) => {
111
111
 
112
112
  return (
113
113
  <>
114
- <ActionIcon icon={Github} onClick={() => window.open(pkg.homepage, '__blank')} />
114
+ <ActionIcon icon={DiscordIcon} onClick={() => window.open(DISCORD, '__blank')} />
115
+ <ActionIcon icon={Github} onClick={() => window.open(GITHUB, '__blank')} />
115
116
  <Dropdown arrow={false} menu={{ items }} trigger={['click']}>
116
117
  <ActionIcon active={tab === 'settings'} icon={Settings2} />
117
118
  </Dropdown>
@@ -23,7 +23,7 @@ const TopActions = memo<TopActionProps>(({ tab, setTab }) => {
23
23
  // 如果已经在 chat 路径下了,那么就不用再跳转了
24
24
  if (Router.asPath.startsWith('/chat')) return;
25
25
 
26
- Router.push('/');
26
+ Router.push('/chat');
27
27
  }}
28
28
  size="large"
29
29
  title={t('tab.chat')}
@@ -1,6 +1,5 @@
1
1
  import { SideNav } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
- import { shallow } from 'zustand/shallow';
4
3
 
5
4
  import AvatarWithUpload from '@/features/AvatarWithUpload';
6
5
  import { useSettings } from '@/store/settings';
@@ -9,7 +8,7 @@ import BottomActions from './BottomActions';
9
8
  import TopActions from './TopActions';
10
9
 
11
10
  export default memo(() => {
12
- const [tab, setTab] = useSettings((s) => [s.sidebarKey, s.switchSideBar], shallow);
11
+ const [tab, setTab] = useSettings((s) => [s.sidebarKey, s.switchSideBar]);
13
12
 
14
13
  return (
15
14
  <SideNav
@@ -0,0 +1,15 @@
1
+ import { PropsWithChildren, memo } from 'react';
2
+ import { Flexbox } from 'react-layout-kit';
3
+
4
+ import SideBar from '@/features/SideBar';
5
+
6
+ const AppLayout = memo<PropsWithChildren>(({ children }) => {
7
+ return (
8
+ <Flexbox horizontal width={'100%'}>
9
+ <SideBar />
10
+ {children}
11
+ </Flexbox>
12
+ );
13
+ });
14
+
15
+ export default AppLayout;
@@ -4,7 +4,6 @@ import { useThemeMode } from 'antd-style';
4
4
  import 'antd/dist/reset.css';
5
5
  import Zh_CN from 'antd/locale/zh_CN';
6
6
  import { PropsWithChildren, useCallback, useEffect } from 'react';
7
- import { shallow } from 'zustand/shallow';
8
7
 
9
8
  import { useSessionStore } from '@/store/session';
10
9
  import { useSettings } from '@/store/settings';
@@ -29,11 +28,12 @@ const Layout = ({ children }: PropsWithChildren) => {
29
28
  };
30
29
 
31
30
  export default ({ children }: PropsWithChildren) => {
32
- const themeMode = useSettings((s) => s.settings.themeMode, shallow);
33
- const { primaryColor, neutralColor } = useSettings(
34
- (s) => ({ neutralColor: s.settings.neutralColor, primaryColor: s.settings.primaryColor }),
35
- shallow,
36
- );
31
+ const themeMode = useSettings((s) => s.settings.themeMode);
32
+ const [primaryColor, neutralColor] = useSettings((s) => [
33
+ s.settings.primaryColor,
34
+ s.settings.neutralColor,
35
+ ]);
36
+
37
37
  const { browserPrefers } = useThemeMode();
38
38
  const isDarkMode = themeMode === 'auto' ? browserPrefers === 'dark' : themeMode === 'dark';
39
39
 
@@ -4,6 +4,7 @@ export default {
4
4
  agentMaxToken: '会话最大长度',
5
5
  agentModel: '模型',
6
6
  agentProfile: '助手信息',
7
+ appInitializing: '应用加载中...',
7
8
  archive: '归档',
8
9
  autoGenerate: '自动补全',
9
10
  autoGenerateTooltip: '基于提示词自动补全助手描述',
@@ -0,0 +1,14 @@
1
+ export default {
2
+ button: {
3
+ import: '导入配置',
4
+ start: '立即开始',
5
+ },
6
+ header: '欢迎使用',
7
+ pickAgent: '或从下列助手模板选择',
8
+ skip: '跳过创建',
9
+ slogan: {
10
+ desc1: '开启大脑集群,激发思维火花。你的智能助理,一直都在。',
11
+ desc2: '创建你的第一个助手,让我们开始吧~',
12
+ title: '给自己一个更聪明的大脑',
13
+ },
14
+ };
@@ -3,6 +3,7 @@ import empty from '../default/empty';
3
3
  import error from '../default/error';
4
4
  import plugin from '../default/plugin';
5
5
  import setting from '../default/setting';
6
+ import welcome from '../default/welcome';
6
7
 
7
8
  const resources = {
8
9
  common,
@@ -10,6 +11,7 @@ const resources = {
10
11
  error,
11
12
  plugin,
12
13
  setting,
14
+ welcome,
13
15
  } as const;
14
16
 
15
17
  export default resources;
@@ -1,11 +1,10 @@
1
1
  import { ActionIcon, Logo, SearchBar } from '@lobehub/ui';
2
2
  import { createStyles } from 'antd-style';
3
3
  import { MessageSquarePlus } from 'lucide-react';
4
- import { useTranslation } from 'react-i18next';
5
4
  import Link from 'next/link';
6
5
  import { memo } from 'react';
6
+ import { useTranslation } from 'react-i18next';
7
7
  import { Flexbox } from 'react-layout-kit';
8
- import { shallow } from 'zustand/shallow';
9
8
 
10
9
  import { useSessionStore } from '@/store/session';
11
10
 
@@ -22,10 +21,7 @@ export const useStyles = createStyles(({ css, token }) => ({
22
21
  const Header = memo(() => {
23
22
  const { styles } = useStyles();
24
23
  const { t } = useTranslation('common');
25
- const [keywords, createSession] = useSessionStore(
26
- (s) => [s.searchKeywords, s.createSession],
27
- shallow,
28
- );
24
+ const [keywords, createSession] = useSessionStore((s) => [s.searchKeywords, s.createSession]);
29
25
 
30
26
  return (
31
27
  <Flexbox className={styles.top} gap={16} padding={16}>
@@ -29,7 +29,7 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading })
29
29
  const { t } = useTranslation('common');
30
30
 
31
31
  const { styles } = useStyles();
32
- const [defaultModel] = useSettings((s) => [s.settings.defaultAgent.config?.model], shallow);
32
+ const [defaultModel] = useSettings((s) => [s.settings.defaultAgent.config?.model]);
33
33
 
34
34
  const [
35
35
  pin,
@@ -60,7 +60,7 @@ const SessionItem: FC<SessionItemProps> = memo(({ id, active = true, loading })
60
60
  s.removeSession,
61
61
  s.pinSession,
62
62
  ];
63
- }, shallow);
63
+ });
64
64
 
65
65
  const { modal } = App.useApp();
66
66
  const items: MenuProps['items'] = useMemo(
@@ -1,7 +1,6 @@
1
1
  import isEqual from 'fast-deep-equal';
2
2
  import Link from 'next/link';
3
3
  import { memo } from 'react';
4
- import { shallow } from 'zustand/shallow';
5
4
 
6
5
  import { sessionSelectors, useSessionHydrated, useSessionStore } from '@/store/session';
7
6
 
@@ -9,11 +8,8 @@ import SessionItem from './SessionItem';
9
8
  import SkeletonItem from './SkeletonItem';
10
9
 
11
10
  const SessionList = memo(() => {
12
- const list = useSessionStore((s) => sessionSelectors.sessionList(s), isEqual);
13
- const [activeId, loading] = useSessionStore(
14
- (s) => [s.activeId, s.autocompleteLoading.title],
15
- shallow,
16
- );
11
+ const list = useSessionStore(sessionSelectors.sessionList, isEqual);
12
+ const [activeId, loading] = useSessionStore((s) => [s.activeId, s.autocompleteLoading.title]);
17
13
 
18
14
  const isInit = useSessionHydrated();
19
15
 
@@ -3,7 +3,6 @@ import { Button, Input } from 'antd';
3
3
  import { memo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { Center, Flexbox } from 'react-layout-kit';
6
- import { shallow } from 'zustand/shallow';
7
6
 
8
7
  import { useSettings } from '@/store/settings';
9
8
 
@@ -12,10 +11,7 @@ import { useStyles } from './style';
12
11
  const APIKeyForm = memo<{ onConfirm?: () => void }>(({ onConfirm }) => {
13
12
  const { t } = useTranslation('error');
14
13
  const { styles, theme } = useStyles();
15
- const [apiKey, setSettings] = useSettings(
16
- (s) => [s.settings.OPENAI_API_KEY, s.setSettings],
17
- shallow,
18
- );
14
+ const [apiKey, setSettings] = useSettings((s) => [s.settings.OPENAI_API_KEY, s.setSettings]);
19
15
 
20
16
  return (
21
17
  <Center gap={16} style={{ maxWidth: 300 }}>
@@ -4,7 +4,6 @@ import { KeySquare, SquareAsterisk } from 'lucide-react';
4
4
  import { memo, useState } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { Flexbox } from 'react-layout-kit';
7
- import { shallow } from 'zustand/shallow';
8
7
 
9
8
  import { useSessionStore } from '@/store/session';
10
9
  import { useSettings } from '@/store/settings';
@@ -16,11 +15,8 @@ import { ErrorActionContainer, FormAction } from './style';
16
15
  const InvalidAccess = memo<{ id: string }>(({ id }) => {
17
16
  const { t } = useTranslation('error');
18
17
  const [mode, setMode] = useState('password');
19
- const [password, setSettings] = useSettings((s) => [s.settings.password, s.setSettings], shallow);
20
- const [resend, deleteMessage] = useSessionStore(
21
- (s) => [s.resendMessage, s.deleteMessage],
22
- shallow,
23
- );
18
+ const [password, setSettings] = useSettings((s) => [s.settings.password, s.setSettings]);
19
+ const [resend, deleteMessage] = useSessionStore((s) => [s.resendMessage, s.deleteMessage]);
24
20
 
25
21
  return (
26
22
  <ErrorActionContainer>
@@ -1,7 +1,6 @@
1
1
  import { Highlighter } from '@lobehub/ui';
2
2
  import { memo } from 'react';
3
3
  import { Flexbox } from 'react-layout-kit';
4
- import { shallow } from 'zustand/shallow';
5
4
 
6
5
  import { useSessionStore } from '@/store/session';
7
6
 
@@ -22,10 +21,7 @@ interface OpenAIErrorResponse {
22
21
  const OpenAiBizError = memo<{ content: OpenAIErrorResponse; id: string }>(({ content, id }) => {
23
22
  const { styles } = useStyles();
24
23
 
25
- const [resend, deleteMessage] = useSessionStore(
26
- (s) => [s.resendMessage, s.deleteMessage],
27
- shallow,
28
- );
24
+ const [resend, deleteMessage] = useSessionStore((s) => [s.resendMessage, s.deleteMessage]);
29
25
 
30
26
  const errorCode = content.error?.code;
31
27
 
@@ -1,7 +1,6 @@
1
1
  import { createStyles } from 'antd-style';
2
2
  import { ReactNode } from 'react';
3
3
  import { Flexbox } from 'react-layout-kit';
4
- import { shallow } from 'zustand/shallow';
5
4
 
6
5
  import Tag from '@/components/Tag';
7
6
  import { agentSelectors, useSessionStore } from '@/store/session';
@@ -28,7 +27,7 @@ const MessageExtra = ({
28
27
  const { styles } = useStyles();
29
28
 
30
29
  // const { t } = useTranslation();
31
- const [model] = useSessionStore((s) => [agentSelectors.currentAgentModel(s)], shallow);
30
+ const [model] = useSessionStore((s) => [agentSelectors.currentAgentModel(s)]);
32
31
 
33
32
  // const plugin = PluginsMap[name || ''];
34
33
 
@@ -3,7 +3,6 @@ import isEqual from 'fast-deep-equal';
3
3
  import { memo, useCallback } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
5
  import { Flexbox } from 'react-layout-kit';
6
- import { shallow } from 'zustand/shallow';
7
6
 
8
7
  import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session';
9
8
  import { ChatMessage } from '@/types/chatMessage';
@@ -32,16 +31,13 @@ const List = () => {
32
31
 
33
32
  const data = useSessionStore(chatSelectors.currentChats, isEqual);
34
33
  const [displayMode, chatLoadingId, deleteMessage, resendMessage, dispatchMessage] =
35
- useSessionStore(
36
- (s) => [
37
- agentSelectors.currentAgentConfig(s).displayMode,
38
- s.chatLoadingId,
39
- s.deleteMessage,
40
- s.resendMessage,
41
- s.dispatchMessage,
42
- ],
43
- shallow,
44
- );
34
+ useSessionStore((s) => [
35
+ agentSelectors.currentAgentConfig(s).displayMode,
36
+ s.chatLoadingId,
37
+ s.deleteMessage,
38
+ s.resendMessage,
39
+ s.dispatchMessage,
40
+ ]);
45
41
 
46
42
  const renderMessage: RenderMessage = useCallback(
47
43
  (content, message: ChatMessage) => {
@@ -4,7 +4,6 @@ import { BrainCog, Thermometer, Timer, TimerOff } from 'lucide-react';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
  import { Flexbox } from 'react-layout-kit';
7
- import { shallow } from 'zustand/shallow';
8
7
 
9
8
  import SliderWithInput from '@/components/SliderWithInput';
10
9
  import { agentSelectors, useSessionStore } from '@/store/session';
@@ -22,7 +21,7 @@ const InputActions = memo(() => {
22
21
  !config.enableHistoryCount,
23
22
  s.updateAgentConfig,
24
23
  ];
25
- }, shallow);
24
+ });
26
25
 
27
26
  return (
28
27
  <>
@@ -3,13 +3,12 @@ import { Popconfirm } from 'antd';
3
3
  import { Eraser } from 'lucide-react';
4
4
  import { memo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
- import { shallow } from 'zustand/shallow';
7
6
 
8
7
  import { useSessionStore } from '@/store/session';
9
8
 
10
9
  const ActionsRight = memo(() => {
11
10
  const { t } = useTranslation('setting');
12
- const [clearMessage] = useSessionStore((s) => [s.clearMessage, s.updateAgentConfig], shallow);
11
+ const [clearMessage] = useSessionStore((s) => [s.clearMessage, s.updateAgentConfig]);
13
12
 
14
13
  return (
15
14
  <Popconfirm
@@ -2,7 +2,6 @@ import { TokenTag, Tooltip } from '@lobehub/ui';
2
2
  import { encode } from 'gpt-tokenizer';
3
3
  import { memo, useMemo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
- import { shallow } from 'zustand/shallow';
6
5
 
7
6
  import { ModelTokens } from '@/const/modelTokens';
8
7
  import { agentSelectors, chatSelectors, useSessionStore } from '@/store/session';
@@ -12,15 +11,12 @@ const Token = memo<{ input: string }>(({ input }) => {
12
11
 
13
12
  const inputTokenCount = useMemo(() => encode(input).length, [input]);
14
13
 
15
- const [totalToken, systemRoleToken, chatsToken, model] = useSessionStore(
16
- (s) => [
17
- chatSelectors.totalTokenCount(s),
18
- chatSelectors.systemRoleTokenCount(s),
19
- chatSelectors.chatsTokenCount(s),
20
- agentSelectors.currentAgentModel(s),
21
- ],
22
- shallow,
23
- );
14
+ const [totalToken, systemRoleToken, chatsToken, model] = useSessionStore((s) => [
15
+ chatSelectors.totalTokenCount(s),
16
+ chatSelectors.systemRoleTokenCount(s),
17
+ chatSelectors.chatsTokenCount(s),
18
+ agentSelectors.currentAgentModel(s),
19
+ ]);
24
20
 
25
21
  return (
26
22
  <Tooltip placement={'bottom'} title={t('tokenDetail', { chatsToken, systemRoleToken })}>
@@ -3,7 +3,6 @@ import { Button } from 'antd';
3
3
  import { LucideGalleryVerticalEnd } from 'lucide-react';
4
4
  import { memo, useState } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
- import { shallow } from 'zustand/shallow';
7
6
 
8
7
  import { CHAT_TEXTAREA_HEIGHT, HEADER_HEIGHT } from '@/const/layoutTokens';
9
8
  import { useSessionStore } from '@/store/session';
@@ -18,11 +17,12 @@ const ChatInput = () => {
18
17
  const [expand, setExpand] = useState<boolean>(false);
19
18
  const [text, setText] = useState('');
20
19
 
21
- const [inputHeight] = useSettings((s) => [s.inputHeight], shallow);
22
- const [sendMessage, hasTopic, saveToTopic] = useSessionStore(
23
- (s) => [s.createOrSendMsg, !!s.activeTopicId, s.saveToTopic],
24
- shallow,
25
- );
20
+ const [inputHeight] = useSettings((s) => [s.inputHeight]);
21
+ const [sendMessage, hasTopic, saveToTopic] = useSessionStore((s) => [
22
+ s.createOrSendMsg,
23
+ !!s.activeTopicId,
24
+ s.saveToTopic,
25
+ ]);
26
26
 
27
27
  const footer = hasTopic ? null : (
28
28
  <Tooltip title={t('topic.saveCurrentMessages')}>