@lobehub/chat 0.60.4 → 0.62.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.
@@ -2,7 +2,7 @@ name: Release CI
2
2
  on:
3
3
  push:
4
4
  branches:
5
- - master
5
+ - main
6
6
 
7
7
  jobs:
8
8
  release:
package/CHANGELOG.md CHANGED
@@ -2,6 +2,73 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 0.62.0](https://github.com/lobehub/lobe-chat/compare/v0.61.0...v0.62.0)
6
+
7
+ <sup>Released on **2023-08-26**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: 支持超过 4k 的会话使用 16k 总结标题.
12
+
13
+ #### 🐛 Bug Fixes
14
+
15
+ - **misc**: Fix plugin settings error.
16
+
17
+ #### 💄 Styles
18
+
19
+ - **misc**: 优化清理会话的操作路径, 优化默认角色的配置.
20
+
21
+ <br/>
22
+
23
+ <details>
24
+ <summary><kbd>Improvements and Fixes</kbd></summary>
25
+
26
+ #### What's improved
27
+
28
+ - **misc**: 支持超过 4k 的会话使用 16k 总结标题 ([5764cfb](https://github.com/lobehub/lobe-chat/commit/5764cfb))
29
+
30
+ #### What's fixed
31
+
32
+ - **misc**: Fix plugin settings error ([008c2e3](https://github.com/lobehub/lobe-chat/commit/008c2e3))
33
+
34
+ #### Styles
35
+
36
+ - **misc**: 优化清理会话的操作路径 ([6b7218e](https://github.com/lobehub/lobe-chat/commit/6b7218e))
37
+ - **misc**: 优化默认角色的配置 ([a07d7a8](https://github.com/lobehub/lobe-chat/commit/a07d7a8))
38
+
39
+ </details>
40
+
41
+ <div align="right">
42
+
43
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
44
+
45
+ </div>
46
+
47
+ ## [Version 0.61.0](https://github.com/lobehub/lobe-chat/compare/v0.60.4...v0.61.0)
48
+
49
+ <sup>Released on **2023-08-26**</sup>
50
+
51
+ #### ✨ Features
52
+
53
+ - **misc**: 新增自动滚动.
54
+
55
+ <br/>
56
+
57
+ <details>
58
+ <summary><kbd>Improvements and Fixes</kbd></summary>
59
+
60
+ #### What's improved
61
+
62
+ - **misc**: 新增自动滚动, closes [#113](https://github.com/lobehub/lobe-chat/issues/113) ([03fd161](https://github.com/lobehub/lobe-chat/commit/03fd161))
63
+
64
+ </details>
65
+
66
+ <div align="right">
67
+
68
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
69
+
70
+ </div>
71
+
5
72
  ### [Version 0.60.4](https://github.com/lobehub/lobe-chat/compare/v0.60.3...v0.60.4)
6
73
 
7
74
  <sup>Released on **2023-08-26**</sup>
package/README.md CHANGED
@@ -23,6 +23,7 @@ Lobe Chat is an open-source chatbot client using OpenAI and Next.js
23
23
  [![stargazers][stargazers-shield]][stargazers-url]
24
24
  [![issues][issues-shield]][issues-url]
25
25
 
26
+ [![Deploy with Vercel][deploy-button-image]][deploy-url]
26
27
  ![](https://raw.githubusercontent.com/andreasbm/readme/master/assets/lines/rainbow.png)
27
28
 
28
29
  </div>
@@ -32,13 +33,35 @@ Lobe Chat is an open-source chatbot client using OpenAI and Next.js
32
33
 
33
34
  #### TOC
34
35
 
36
+ - [🛳 Self Hosting](#-self-hosting)
37
+
38
+ - [Deploy to Vercel](#deploy-to-vercel)
39
+
35
40
  - [⌨️ Local Development](#️-local-development)
41
+
36
42
  - [🤝 Contributing](#-contributing)
37
43
 
38
44
  ####
39
45
 
40
46
  </details>
41
47
 
48
+ ## 🛳 Self Hosting
49
+
50
+ If you want to deploy this service by yourself, you can follow the steps below.
51
+
52
+ ### Deploy to Vercel
53
+
54
+ Click button below to deploy your private plugins' gateway.
55
+
56
+ [![Deploy with Vercel][deploy-button-image]][deploy-url]
57
+
58
+ If you want to make some customization, you can add environment variable:
59
+
60
+ | Environment variable | Description | Example |
61
+ | -------------------- | --------------------------------------------------------------------------------- | ----------------------------- |
62
+ | `OPENAI_PROXY_URL` | OpenAI API 代理 URL,例如:`https://api.chatanywhere.cn` | `https://api.chatanywhere.cn` |
63
+ | `ACCESS_CODE` | Add Password to access this service, the password should be 6 digits or alphabets | `awCT74` \| `e3@09!` |
64
+
42
65
  ## ⌨️ Local Development
43
66
 
44
67
  You can use Gitpod for online development:
@@ -51,7 +74,7 @@ Or clone it for local development:
51
74
  $ git clone https://github.com/lobehub/lobe-chat.git
52
75
  $ cd lobe-chat
53
76
  $ pnpm install
54
- $ pnpm start
77
+ $ pnpm dev
55
78
  ```
56
79
 
57
80
  <div align="right">
@@ -143,3 +166,8 @@ This project is [MIT](./LICENSE) licensed.
143
166
 
144
167
  [issues-shield]: https://img.shields.io/github/issues/lobehub/lobe-chat.svg?style=flat
145
168
  [issues-url]: https://img.shields.io/github/issues/lobehub/lobe-chat.svg?style=flat
169
+
170
+ <!-- deploy -->
171
+
172
+ [deploy-button-image]: https://vercel.com/button
173
+ [deploy-url]: https://vercel.com/new/clone?repository-url=https%3A%2F%2Fgithub.com%2Flobehub%2Flobe-chat&env=OPENAI_API_KEY&envDescription=Find%20your%20OpenAI%20API%20Key%20by%20click%20the%20right%20Learn%20More%20button.%20%20&envLink=https%3A%2F%2Fplatform.openai.com%2Faccount%2Fapi-keys&project-name=lobe-chat&repository-name=lobe-chat
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.60.4",
3
+ "version": "0.62.0",
4
4
  "description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -63,7 +63,6 @@
63
63
  "dependencies": {
64
64
  "@ant-design/colors": "^7",
65
65
  "@ant-design/icons": "^5",
66
- "@cfworker/json-schema": "^1.12.7",
67
66
  "@emoji-mart/data": "^1",
68
67
  "@emoji-mart/react": "^1",
69
68
  "@icons-pack/react-simple-icons": "^8",
@@ -92,6 +91,7 @@
92
91
  "react-dom": "^18",
93
92
  "react-hotkeys-hook": "^4",
94
93
  "react-i18next": "^13",
94
+ "react-intersection-observer": "^9",
95
95
  "react-layout-kit": "^1.7.1",
96
96
  "serpapi": "^2",
97
97
  "swr": "^2",
@@ -114,7 +114,7 @@
114
114
  "@types/node": "^20",
115
115
  "@types/react": "^18",
116
116
  "@types/react-dom": "^18",
117
- "@types/systemjs": "^6.13.1",
117
+ "@types/systemjs": "^6.13.2",
118
118
  "@types/testing-library__jest-dom": "^6",
119
119
  "@types/uuid": "^9",
120
120
  "@umijs/lint": "^4",
@@ -22,6 +22,7 @@ export const DEFAULT_BASE_SETTINGS: GlobalBaseSettings = {
22
22
 
23
23
  export const DEFAULT_AGENT_CONFIG: LobeAgentConfig = {
24
24
  displayMode: 'chat',
25
+ historyCount: 1,
25
26
  model: LanguageModel.GPT3_5,
26
27
  params: {
27
28
  frequency_penalty: 0,
@@ -41,7 +41,7 @@ const PluginSettings = memo<PluginSettingsProps>(({ id, pluginIdentifier }) => {
41
41
  </Flexbox>
42
42
  <Flexbox className={styles.desc}>{t('pluginSettings.desc')}</Flexbox>
43
43
  <Divider style={{ margin: '0 16px' }} />
44
- {manifest.settings && (
44
+ {manifest?.settings && (
45
45
  <PluginSettingsConfig id={manifest.identifier} settings={manifest.settings} />
46
46
  )}
47
47
  <Button
@@ -16,6 +16,7 @@ const ActionsRight = memo(() => {
16
16
  okButtonProps={{ danger: true }}
17
17
  okText={t('ok', { ns: 'common' })}
18
18
  onConfirm={() => clearMessage()}
19
+ placement={'topRight'}
19
20
  title={t('confirmClearCurrentMessages', { ns: 'common' })}
20
21
  >
21
22
  <ActionIcon
@@ -0,0 +1,29 @@
1
+ import { memo, useEffect } from 'react';
2
+ import { useInView } from 'react-intersection-observer';
3
+
4
+ import { useSessionStore } from '@/store/session';
5
+
6
+ import { useAtBottom } from './useAtBottom';
7
+
8
+ const ChatScrollAnchor = memo(() => {
9
+ const trackVisibility = useSessionStore((s) => !!s.chatLoadingId);
10
+
11
+ const isAtBottom = useAtBottom();
12
+ const { ref, entry, inView } = useInView({
13
+ delay: 100,
14
+ rootMargin: '0px 0px -150px 0px',
15
+ trackVisibility,
16
+ });
17
+
18
+ useEffect(() => {
19
+ if (isAtBottom && trackVisibility && !inView) {
20
+ entry?.target.scrollIntoView({
21
+ block: 'start',
22
+ });
23
+ }
24
+ }, [inView, entry, isAtBottom, trackVisibility]);
25
+
26
+ return <div ref={ref} style={{ height: 1, width: '100%' }} />;
27
+ });
28
+
29
+ export default ChatScrollAnchor;
@@ -0,0 +1,20 @@
1
+ import { useEffect, useState } from 'react';
2
+
3
+ export const useAtBottom = (offset = 0) => {
4
+ const [isAtBottom, setIsAtBottom] = useState(false);
5
+
6
+ useEffect(() => {
7
+ const handleScroll = () => {
8
+ setIsAtBottom(window.innerHeight + window.scrollY >= document.body.offsetHeight - offset);
9
+ };
10
+
11
+ window.addEventListener('scroll', handleScroll, { passive: true });
12
+ handleScroll();
13
+
14
+ return () => {
15
+ window.removeEventListener('scroll', handleScroll);
16
+ };
17
+ }, [offset]);
18
+
19
+ return isAtBottom;
20
+ };
@@ -7,6 +7,7 @@ import SafeSpacing from '@/components/SafeSpacing';
7
7
 
8
8
  import ChatList from './ChatList';
9
9
  import ChatInput from './Input';
10
+ import ChatScrollAnchor from './ScrollAnchor';
10
11
 
11
12
  const Conversation = memo<{ mobile?: boolean }>(({ mobile }) => {
12
13
  const ref = useRef(null);
@@ -17,6 +18,7 @@ const Conversation = memo<{ mobile?: boolean }>(({ mobile }) => {
17
18
  <div ref={ref} style={{ height: '100%', overflowY: 'scroll' }}>
18
19
  {!mobile && <SafeSpacing />}
19
20
  <ChatList />
21
+ <ChatScrollAnchor />
20
22
  </div>
21
23
  <BackBottom target={ref} text={t('backToBottom')} />
22
24
  </div>
@@ -1,9 +1,9 @@
1
+ import { chatHelpers } from '@/store/session/helpers';
2
+ import { LanguageModel } from '@/types/llm';
1
3
  import { OpenAIChatMessage, OpenAIStreamPayload } from '@/types/openai';
2
4
 
3
- export const promptSummaryTitle = (
4
- messages: OpenAIChatMessage[],
5
- ): Partial<OpenAIStreamPayload> => ({
6
- messages: [
5
+ export const promptSummaryTitle = (messages: OpenAIChatMessage[]): Partial<OpenAIStreamPayload> => {
6
+ const finalMessages: OpenAIChatMessage[] = [
7
7
  {
8
8
  content:
9
9
  '你是一名擅长会话的助理,你需要将用户的会话总结为 10 个字以内的标题,不需要包含标点符号',
@@ -15,5 +15,16 @@ export const promptSummaryTitle = (
15
15
  请总结上述对话为10个字以内的标题,不需要包含标点符号`,
16
16
  role: 'user',
17
17
  },
18
- ],
19
- });
18
+ ];
19
+ // 如果超过 4k,则使用 GPT3.5 16K 模型
20
+ const tokens = chatHelpers.getMessagesTokenCount(finalMessages);
21
+ let model: LanguageModel | undefined = undefined;
22
+ if (tokens > 4000) {
23
+ model = LanguageModel.GPT3_5_16K;
24
+ }
25
+
26
+ return {
27
+ messages: finalMessages,
28
+ model,
29
+ };
30
+ };
@@ -0,0 +1 @@
1
+ export * from './slices/chat/helpers';
@@ -178,12 +178,6 @@ export const chatMessage: StateCreator<
178
178
  if (isFunctionMessage(output)) {
179
179
  isFunctionCall = true;
180
180
  }
181
-
182
- // 滚动到最后一条消息
183
- const item = document.querySelector('#for-loading');
184
- if (!item) return;
185
-
186
- item.scrollIntoView({ behavior: 'smooth' });
187
181
  },
188
182
  });
189
183
 
@@ -0,0 +1,10 @@
1
+ import { encode } from 'gpt-tokenizer';
2
+
3
+ import { OpenAIChatMessage } from '@/types/openai';
4
+
5
+ export const getMessagesTokenCount = (messages: OpenAIChatMessage[]) =>
6
+ encode(messages.map((m) => m.content).join('')).length;
7
+
8
+ export const chatHelpers = {
9
+ getMessagesTokenCount,
10
+ };
@@ -83,11 +83,7 @@ export class StrCompressor {
83
83
  after += '=';
84
84
  }
85
85
 
86
- return new Uint8Array(
87
- atob(after)
88
- .split('')
89
- .map((c) => c.charCodeAt(0)),
90
- );
86
+ return new Uint8Array([...atob(after)].map((c) => c.charCodeAt(0)));
91
87
  };
92
88
  }
93
89
 
package/vercel.json ADDED
@@ -0,0 +1,3 @@
1
+ {
2
+ "installCommand": "pnpm i"
3
+ }