@lobehub/chat 0.118.5 → 0.118.7
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/next.config.mjs +0 -1
- package/package.json +1 -1
- package/src/app/api/openai/chat/createChatCompletion.test.ts +37 -0
- package/src/app/api/openai/chat/createChatCompletion.ts +10 -2
- package/src/app/api/openai/chat/desensitizeUrl.test.ts +47 -0
- package/src/app/api/openai/chat/desensitizeUrl.ts +34 -0
- package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +1 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Assistant.tsx +3 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Error.tsx +3 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Fallback.tsx +4 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/Function.tsx +4 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/User.tsx +3 -1
- package/src/features/Conversation/{ChatList/Actions → Actions}/index.ts +1 -2
- package/src/features/Conversation/{ChatList/Error → Error}/InvalidAccess.tsx +2 -1
- package/src/features/Conversation/{ChatList/Error → Error}/OpenAPIKey.tsx +1 -1
- package/src/features/Conversation/{ChatList/Error → Error}/OpenAiBizError.tsx +2 -1
- package/src/features/Conversation/{ChatList/Error → Error}/Plugin/PluginError.tsx +3 -1
- package/src/features/Conversation/{ChatList/Error → Error}/Plugin/PluginSettings.tsx +2 -1
- package/src/features/Conversation/{ChatList/Error → Error}/index.tsx +1 -1
- package/src/features/Conversation/{ChatList/Extras → Extras}/Translate.tsx +1 -1
- package/src/features/Conversation/{ChatList/Extras → Extras}/index.ts +1 -2
- package/src/features/Conversation/{ChatList/Messages → Messages}/Default.tsx +1 -1
- package/src/features/Conversation/{ChatList/Messages → Messages}/User.tsx +1 -1
- package/src/features/Conversation/{ChatList/Messages → Messages}/index.ts +5 -5
- package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/Loading.tsx +10 -11
- package/src/features/Conversation/components/ChatList/ActionsBar.tsx +27 -0
- package/src/features/Conversation/components/ChatList/HistoryDivider.tsx +23 -0
- package/src/features/Conversation/components/ChatList/Item.tsx +236 -0
- package/src/features/Conversation/components/ChatList/index.tsx +88 -0
- package/src/features/Conversation/components/ChatList/style.ts +10 -0
- package/src/features/Conversation/{ChatList → container}/index.tsx +6 -7
- package/src/features/Conversation/hooks/useChatListActionsBar.tsx +43 -0
- package/src/features/Conversation/index.tsx +3 -3
- package/src/store/middleware/createHyperStorage/index.test.ts +341 -0
- package/src/store/middleware/createHyperStorage/indexedDB.test.ts +64 -0
- package/src/store/middleware/createHyperStorage/urlStorage.test.ts +84 -0
- package/src/store/middleware/createHyperStorage/urlStorage.ts +25 -8
- /package/src/features/Conversation/{ChatList/Actions → Actions}/customAction.ts +0 -0
- /package/src/features/Conversation/{ChatList/Error → Error}/ApiKeyForm.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Error → Error}/ErrorActionContainer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Error → Error}/style.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/Assistant.test.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/Assistant.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/ExtraContainer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/FilePlayer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/InitPlayer.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/Player.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/TTS/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/User.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Extras → Extras}/type.ts +0 -0
- /package/src/features/Conversation/{ChatList/Messages → Messages}/Assistant.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Messages → Messages}/Function.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/PluginResultJSON.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/Settings.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Inspector/style.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/BuiltinType/index.test.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/BuiltinType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/IFrameRender/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/SystemJsRender/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/SystemJsRender/utils.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/DefaultType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/MarkdownType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/StandaloneType/Iframe.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/StandaloneType/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/index.tsx +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/useParseContent.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/iframeOnReady.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/iframeOnReady.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/listenToPlugin.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/listenToPlugin.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginSettings.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginSettings.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginState.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/pluginState.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/postMessage.test.ts +0 -0
- /package/src/features/Conversation/{ChatList/Plugins → Plugins}/Render/utils/postMessage.ts +0 -0
- /package/src/features/Conversation/{ChatList/Loading.tsx → components/BubblesLoading.tsx} +0 -0
- /package/src/features/Conversation/{ChatList → components}/OTPInput.tsx +0 -0
- /package/src/features/Conversation/{ScrollAnchor → components/ScrollAnchor}/index.tsx +0 -0
- /package/src/features/Conversation/{ScrollAnchor → components/ScrollAnchor}/useAtBottom.ts +0 -0
- /package/src/features/Conversation/{ChatList → components}/SkeletonList.tsx +0 -0
- /package/src/features/Conversation/{useInitConversation.ts → hooks/useInitConversation.ts} +0 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,56 @@
|
|
|
2
2
|
|
|
3
3
|
# Changelog
|
|
4
4
|
|
|
5
|
+
### [Version 0.118.7](https://github.com/lobehub/lobe-chat/compare/v0.118.6...v0.118.7)
|
|
6
|
+
|
|
7
|
+
<sup>Released on **2024-01-03**</sup>
|
|
8
|
+
|
|
9
|
+
#### 🐛 Bug Fixes
|
|
10
|
+
|
|
11
|
+
- **misc**: Desensitize openai base url in the error response.
|
|
12
|
+
|
|
13
|
+
<br/>
|
|
14
|
+
|
|
15
|
+
<details>
|
|
16
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
17
|
+
|
|
18
|
+
#### What's fixed
|
|
19
|
+
|
|
20
|
+
- **misc**: Desensitize openai base url in the error response, closes [#918](https://github.com/lobehub/lobe-chat/issues/918) ([ab0aeb7](https://github.com/lobehub/lobe-chat/commit/ab0aeb7))
|
|
21
|
+
|
|
22
|
+
</details>
|
|
23
|
+
|
|
24
|
+
<div align="right">
|
|
25
|
+
|
|
26
|
+
[](#readme-top)
|
|
27
|
+
|
|
28
|
+
</div>
|
|
29
|
+
|
|
30
|
+
### [Version 0.118.6](https://github.com/lobehub/lobe-chat/compare/v0.118.5...v0.118.6)
|
|
31
|
+
|
|
32
|
+
<sup>Released on **2024-01-03**</sup>
|
|
33
|
+
|
|
34
|
+
#### ♻ Code Refactoring
|
|
35
|
+
|
|
36
|
+
- **misc**: Migration the ChatList into Conversation.
|
|
37
|
+
|
|
38
|
+
<br/>
|
|
39
|
+
|
|
40
|
+
<details>
|
|
41
|
+
<summary><kbd>Improvements and Fixes</kbd></summary>
|
|
42
|
+
|
|
43
|
+
#### Code refactoring
|
|
44
|
+
|
|
45
|
+
- **misc**: Migration the ChatList into Conversation, closes [#916](https://github.com/lobehub/lobe-chat/issues/916) ([6ee3795](https://github.com/lobehub/lobe-chat/commit/6ee3795))
|
|
46
|
+
|
|
47
|
+
</details>
|
|
48
|
+
|
|
49
|
+
<div align="right">
|
|
50
|
+
|
|
51
|
+
[](#readme-top)
|
|
52
|
+
|
|
53
|
+
</div>
|
|
54
|
+
|
|
5
55
|
### [Version 0.118.5](https://github.com/lobehub/lobe-chat/compare/v0.118.4...v0.118.5)
|
|
6
56
|
|
|
7
57
|
<sup>Released on **2024-01-02**</sup>
|
package/next.config.mjs
CHANGED
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "0.118.
|
|
3
|
+
"version": "0.118.7",
|
|
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",
|
|
@@ -73,6 +73,7 @@ describe('createChatCompletion', () => {
|
|
|
73
73
|
expect(result).toBeInstanceOf(Response);
|
|
74
74
|
expect(result.status).toBe(577); // Your custom error status code
|
|
75
75
|
});
|
|
76
|
+
|
|
76
77
|
it('should return an cause response when OpenAI.APIError is thrown with cause', async () => {
|
|
77
78
|
// Arrange
|
|
78
79
|
const errorInfo = {
|
|
@@ -101,6 +102,42 @@ describe('createChatCompletion', () => {
|
|
|
101
102
|
|
|
102
103
|
const content = await result.json();
|
|
103
104
|
expect(content.body).toHaveProperty('endpoint');
|
|
105
|
+
expect(content.body.endpoint).toEqual('https://api.openai.com/v1');
|
|
106
|
+
expect(content.body.error).toEqual(errorInfo);
|
|
107
|
+
});
|
|
108
|
+
|
|
109
|
+
it('should return an cause response with desensitize Url', async () => {
|
|
110
|
+
// Arrange
|
|
111
|
+
const errorInfo = {
|
|
112
|
+
stack: 'abc',
|
|
113
|
+
cause: { message: 'api is undefined' },
|
|
114
|
+
};
|
|
115
|
+
const apiError = new OpenAI.APIError(400, errorInfo, 'module error', {});
|
|
116
|
+
|
|
117
|
+
openaiInstance = new OpenAI({
|
|
118
|
+
apiKey: 'test',
|
|
119
|
+
dangerouslyAllowBrowser: true,
|
|
120
|
+
baseURL: 'https://api.abc.com/v1',
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
vi.spyOn(openaiInstance.chat.completions, 'create').mockRejectedValue(apiError);
|
|
124
|
+
|
|
125
|
+
// Act
|
|
126
|
+
const result = await createChatCompletion({
|
|
127
|
+
openai: openaiInstance,
|
|
128
|
+
payload: {
|
|
129
|
+
messages: [{ content: 'Hello', role: 'user' }],
|
|
130
|
+
model: 'gpt-3.5-turbo',
|
|
131
|
+
temperature: 0,
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
|
|
135
|
+
// Assert
|
|
136
|
+
expect(result).toBeInstanceOf(Response);
|
|
137
|
+
expect(result.status).toBe(577); // Your custom error status code
|
|
138
|
+
|
|
139
|
+
const content = await result.json();
|
|
140
|
+
expect(content.body.endpoint).toEqual('https://api.***.com/v1');
|
|
104
141
|
expect(content.body.error).toEqual(errorInfo);
|
|
105
142
|
});
|
|
106
143
|
|
|
@@ -5,6 +5,7 @@ import { ChatErrorType } from '@/types/fetch';
|
|
|
5
5
|
import { OpenAIChatStreamPayload } from '@/types/openai/chat';
|
|
6
6
|
|
|
7
7
|
import { createErrorResponse } from '../errorResponse';
|
|
8
|
+
import { desensitizeUrl } from './desensitizeUrl';
|
|
8
9
|
|
|
9
10
|
interface CreateChatCompletionOptions {
|
|
10
11
|
openai: OpenAI;
|
|
@@ -29,6 +30,13 @@ export const createChatCompletion = async ({ payload, openai }: CreateChatComple
|
|
|
29
30
|
const stream = OpenAIStream(response);
|
|
30
31
|
return new StreamingTextResponse(stream);
|
|
31
32
|
} catch (error) {
|
|
33
|
+
let desensitizedEndpoint = openai.baseURL;
|
|
34
|
+
|
|
35
|
+
// refs: https://github.com/lobehub/lobe-chat/issues/842
|
|
36
|
+
if (openai.baseURL !== 'https://api.openai.com/v1') {
|
|
37
|
+
desensitizedEndpoint = desensitizeUrl(openai.baseURL);
|
|
38
|
+
}
|
|
39
|
+
|
|
32
40
|
// Check if the error is an OpenAI APIError
|
|
33
41
|
if (error instanceof OpenAI.APIError) {
|
|
34
42
|
let errorResult: any;
|
|
@@ -51,7 +59,7 @@ export const createChatCompletion = async ({ payload, openai }: CreateChatComple
|
|
|
51
59
|
console.error(errorResult);
|
|
52
60
|
|
|
53
61
|
return createErrorResponse(ChatErrorType.OpenAIBizError, {
|
|
54
|
-
endpoint:
|
|
62
|
+
endpoint: desensitizedEndpoint,
|
|
55
63
|
error: errorResult,
|
|
56
64
|
});
|
|
57
65
|
}
|
|
@@ -61,7 +69,7 @@ export const createChatCompletion = async ({ payload, openai }: CreateChatComple
|
|
|
61
69
|
|
|
62
70
|
// return as a GatewayTimeout error
|
|
63
71
|
return createErrorResponse(ChatErrorType.InternalServerError, {
|
|
64
|
-
endpoint:
|
|
72
|
+
endpoint: desensitizedEndpoint,
|
|
65
73
|
error: JSON.stringify(error),
|
|
66
74
|
});
|
|
67
75
|
}
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { desensitizeUrl } from './desensitizeUrl';
|
|
4
|
+
|
|
5
|
+
describe('desensitizeUrl', () => {
|
|
6
|
+
it('should desensitize a URL with a subdomain', () => {
|
|
7
|
+
const originalUrl = 'https://api.example.com/v1';
|
|
8
|
+
const result = desensitizeUrl(originalUrl);
|
|
9
|
+
expect(result).toBe('https://api.ex****le.com/v1');
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
it('should desensitize a URL without a subdomain', () => {
|
|
13
|
+
const originalUrl = 'https://example.com/v1';
|
|
14
|
+
const result = desensitizeUrl(originalUrl);
|
|
15
|
+
expect(result).toBe('https://ex****le.com/v1');
|
|
16
|
+
});
|
|
17
|
+
|
|
18
|
+
it('should desensitize a URL without a subdomain less then 5 chartarters', () => {
|
|
19
|
+
const originalUrl = 'https://abc.com/v1';
|
|
20
|
+
const result = desensitizeUrl(originalUrl);
|
|
21
|
+
expect(result).toBe('https://***.com/v1');
|
|
22
|
+
});
|
|
23
|
+
|
|
24
|
+
it('should desensitize a URL with multiple subdomains', () => {
|
|
25
|
+
const originalUrl = 'https://sub.api.example.com/v1';
|
|
26
|
+
const result = desensitizeUrl(originalUrl);
|
|
27
|
+
expect(result).toBe('https://sub.api.ex****le.com/v1');
|
|
28
|
+
});
|
|
29
|
+
|
|
30
|
+
it('should desensitize a URL with path and query parameters', () => {
|
|
31
|
+
const originalUrl = 'https://api.example.com/v1?query=123';
|
|
32
|
+
const result = desensitizeUrl(originalUrl);
|
|
33
|
+
expect(result).toBe('https://api.ex****le.com/v1?query=123');
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
it('should return the original URL if it is invalid', () => {
|
|
37
|
+
const originalUrl = 'invalidurl';
|
|
38
|
+
const result = desensitizeUrl(originalUrl);
|
|
39
|
+
expect(result).toBe(originalUrl);
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
it('should desensitize a URL with a port number', () => {
|
|
43
|
+
const originalUrl = 'https://api.example.com:8080/v1';
|
|
44
|
+
const result = desensitizeUrl(originalUrl);
|
|
45
|
+
expect(result).toBe('https://api.ex****le.com:****/v1');
|
|
46
|
+
});
|
|
47
|
+
});
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
export const desensitizeUrl = (url: string) => {
|
|
2
|
+
try {
|
|
3
|
+
const urlObj = new URL(url);
|
|
4
|
+
const hostnameParts = urlObj.hostname.split('.');
|
|
5
|
+
const port = urlObj.port;
|
|
6
|
+
|
|
7
|
+
// Desensitize domain only if there are at least two parts (example.com)
|
|
8
|
+
if (hostnameParts.length > 1) {
|
|
9
|
+
// Desensitize the second level domain (second part from the right)
|
|
10
|
+
// Special case for short domain names
|
|
11
|
+
const secondLevelDomainIndex = hostnameParts.length - 2;
|
|
12
|
+
if (hostnameParts[secondLevelDomainIndex].length < 5) {
|
|
13
|
+
hostnameParts[secondLevelDomainIndex] = '***';
|
|
14
|
+
} else {
|
|
15
|
+
hostnameParts[secondLevelDomainIndex] = hostnameParts[secondLevelDomainIndex].replace(
|
|
16
|
+
/^(.*?)(\w{2})(\w+)(\w{2})$/,
|
|
17
|
+
(_, prefix, start, middle, end) => `${prefix}${start}****${end}`,
|
|
18
|
+
);
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
// Join the hostname parts back together
|
|
23
|
+
const desensitizedHostname = hostnameParts.join('.');
|
|
24
|
+
|
|
25
|
+
// Desensitize port if present
|
|
26
|
+
const desensitizedPort = port ? ':****' : '';
|
|
27
|
+
|
|
28
|
+
// Reconstruct the URL with the desensitized parts
|
|
29
|
+
return `${urlObj.protocol}//${desensitizedHostname}${desensitizedPort}${urlObj.pathname}${urlObj.search}`;
|
|
30
|
+
} catch {
|
|
31
|
+
// If the URL is invalid, return the original URL
|
|
32
|
+
return url;
|
|
33
|
+
}
|
|
34
|
+
};
|
|
@@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next';
|
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
6
|
|
|
7
7
|
import pkg from '@/../package.json';
|
|
8
|
-
import ChatList from '@/features/Conversation/
|
|
8
|
+
import ChatList from '@/features/Conversation/container';
|
|
9
9
|
import { useSessionStore } from '@/store/session';
|
|
10
10
|
import { agentSelectors, sessionSelectors } from '@/store/session/selectors';
|
|
11
11
|
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
4
6
|
import { ErrorActionsBar } from './Error';
|
|
5
7
|
import { useCustomActions } from './customAction';
|
|
6
8
|
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { ActionsBarProps } from '@lobehub/ui/es/ChatList/ActionsBar';
|
|
3
3
|
import { memo } from 'react';
|
|
4
4
|
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
6
|
+
|
|
5
7
|
export const ErrorActionsBar = memo<ActionsBarProps>(({ text, onActionClick }) => {
|
|
6
8
|
const { regenerate, del } = useChatListActionsBar(text);
|
|
7
9
|
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
6
|
+
|
|
4
7
|
export const DefaultActionsBar: RenderAction = memo(({ text, onActionClick }) => {
|
|
5
8
|
const { del } = useChatListActionsBar(text);
|
|
6
9
|
return (
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
6
|
+
|
|
4
7
|
export const FunctionActionsBar: RenderAction = memo(({ text, onActionClick }) => {
|
|
5
8
|
const { regenerate, divider, del } = useChatListActionsBar(text);
|
|
6
9
|
return (
|
|
@@ -1,6 +1,8 @@
|
|
|
1
|
-
import { ActionIconGroup
|
|
1
|
+
import { ActionIconGroup } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
|
|
4
|
+
import { RenderAction } from '../components/ChatList';
|
|
5
|
+
import { useChatListActionsBar } from '../hooks/useChatListActionsBar';
|
|
4
6
|
import { useCustomActions } from './customAction';
|
|
5
7
|
|
|
6
8
|
export const UserActionsBar: RenderAction = memo(({ text, onActionClick }) => {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
|
-
import { ChatListProps } from '@lobehub/ui';
|
|
2
|
-
|
|
3
1
|
import { useChatStore } from '@/store/chat';
|
|
4
2
|
|
|
3
|
+
import { ChatListProps } from '../components/ChatList';
|
|
5
4
|
import { AssistantActionsBar } from './Assistant';
|
|
6
5
|
import { DefaultActionsBar } from './Fallback';
|
|
7
6
|
import { FunctionActionsBar } from './Function';
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Icon
|
|
1
|
+
import { Icon } from '@lobehub/ui';
|
|
2
2
|
import { Button, Input, Segmented } from 'antd';
|
|
3
3
|
import { KeySquare, SquareAsterisk } from 'lucide-react';
|
|
4
4
|
import { memo, useState } from 'react';
|
|
@@ -8,6 +8,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
8
8
|
import { useChatStore } from '@/store/chat';
|
|
9
9
|
import { useGlobalStore } from '@/store/global';
|
|
10
10
|
|
|
11
|
+
import { RenderErrorMessage } from '../components/ChatList';
|
|
11
12
|
import APIKeyForm from './ApiKeyForm';
|
|
12
13
|
import { ErrorActionContainer, FormAction } from './style';
|
|
13
14
|
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { Highlighter
|
|
1
|
+
import { Highlighter } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
4
|
|
|
5
|
+
import { RenderErrorMessage } from '../components/ChatList';
|
|
5
6
|
import OpenAPIKey from './OpenAPIKey';
|
|
6
7
|
|
|
7
8
|
interface OpenAIError {
|
|
@@ -1,7 +1,9 @@
|
|
|
1
|
-
import { Highlighter
|
|
1
|
+
import { Highlighter } from '@lobehub/ui';
|
|
2
2
|
import { memo } from 'react';
|
|
3
3
|
import { Flexbox } from 'react-layout-kit';
|
|
4
4
|
|
|
5
|
+
import { RenderErrorMessage } from '../../components/ChatList';
|
|
6
|
+
|
|
5
7
|
interface OpenAIError {
|
|
6
8
|
code: 'invalid_api_key' | string;
|
|
7
9
|
message: string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Avatar
|
|
1
|
+
import { Avatar } from '@lobehub/ui';
|
|
2
2
|
import { Button, Divider } from 'antd';
|
|
3
3
|
import { useTheme } from 'antd-style';
|
|
4
4
|
import isEqual from 'fast-deep-equal';
|
|
@@ -11,6 +11,7 @@ import { useChatStore } from '@/store/chat';
|
|
|
11
11
|
import { pluginHelpers, useToolStore } from '@/store/tool';
|
|
12
12
|
import { pluginSelectors } from '@/store/tool/selectors';
|
|
13
13
|
|
|
14
|
+
import { RenderErrorMessage } from '../../components/ChatList';
|
|
14
15
|
import { ErrorActionContainer, useStyles } from '../style';
|
|
15
16
|
|
|
16
17
|
const PluginSettings: RenderErrorMessage['Render'] = memo(({ id, plugin }) => {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { PluginErrorType } from '@lobehub/chat-plugin-sdk';
|
|
2
|
-
import { ChatListProps } from '@lobehub/ui';
|
|
3
2
|
|
|
4
3
|
import { ChatErrorType } from '@/types/fetch';
|
|
5
4
|
|
|
5
|
+
import { ChatListProps } from '../components/ChatList';
|
|
6
6
|
import InvalidAccess from './InvalidAccess';
|
|
7
7
|
import OpenAPIKey from './OpenAPIKey';
|
|
8
8
|
import OpenAiBizError from './OpenAiBizError';
|
|
@@ -10,7 +10,7 @@ import { Flexbox } from 'react-layout-kit';
|
|
|
10
10
|
import { useChatStore } from '@/store/chat';
|
|
11
11
|
import { ChatTranslate } from '@/types/message';
|
|
12
12
|
|
|
13
|
-
import BubblesLoading from '../
|
|
13
|
+
import BubblesLoading from '../components/BubblesLoading';
|
|
14
14
|
|
|
15
15
|
const useStyles = createStyles(({ stylish }) => ({
|
|
16
16
|
markdown: stylish.markdownInChat,
|
|
@@ -3,7 +3,7 @@ import { ReactNode, memo } from 'react';
|
|
|
3
3
|
import { LOADING_FLAT } from '@/const/message';
|
|
4
4
|
import { ChatMessage } from '@/types/message';
|
|
5
5
|
|
|
6
|
-
import BubblesLoading from '../
|
|
6
|
+
import BubblesLoading from '../components/BubblesLoading';
|
|
7
7
|
|
|
8
8
|
export const DefaultMessage = memo<
|
|
9
9
|
ChatMessage & {
|
|
@@ -5,7 +5,7 @@ import FileList from '@/components/FileList';
|
|
|
5
5
|
import { LOADING_FLAT } from '@/const/message';
|
|
6
6
|
import { ChatMessage } from '@/types/message';
|
|
7
7
|
|
|
8
|
-
import BubblesLoading from '../
|
|
8
|
+
import BubblesLoading from '../components/BubblesLoading';
|
|
9
9
|
|
|
10
10
|
export const UserMessage = memo<
|
|
11
11
|
ChatMessage & {
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ChatListProps } from '@lobehub/ui';
|
|
2
1
|
import { useResponsive } from 'antd-style';
|
|
3
2
|
import { useRouter } from 'next/navigation';
|
|
4
3
|
|
|
@@ -7,16 +6,17 @@ import { useSessionStore } from '@/store/session';
|
|
|
7
6
|
import { sessionSelectors } from '@/store/session/selectors';
|
|
8
7
|
import { pathString } from '@/utils/url';
|
|
9
8
|
|
|
9
|
+
import { ChatListProps } from '../components/ChatList';
|
|
10
10
|
import { AssistantMessage } from './Assistant';
|
|
11
11
|
import { DefaultMessage } from './Default';
|
|
12
12
|
import { FunctionMessage } from './Function';
|
|
13
13
|
import { UserMessage } from './User';
|
|
14
14
|
|
|
15
15
|
export const renderMessages: ChatListProps['renderMessages'] = {
|
|
16
|
-
assistant: AssistantMessage
|
|
17
|
-
default: DefaultMessage
|
|
18
|
-
function: FunctionMessage
|
|
19
|
-
user: UserMessage
|
|
16
|
+
assistant: AssistantMessage,
|
|
17
|
+
default: DefaultMessage,
|
|
18
|
+
function: FunctionMessage,
|
|
19
|
+
user: UserMessage,
|
|
20
20
|
};
|
|
21
21
|
|
|
22
22
|
export const useAvatarsClick = (): ChatListProps['onAvatarsClick'] => {
|
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import {createStyles} from 'antd-style';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
|
|
1
|
+
import { createStyles } from 'antd-style';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
import { useTranslation } from 'react-i18next';
|
|
4
|
+
import { Flexbox } from 'react-layout-kit';
|
|
6
5
|
|
|
7
6
|
const useStyles = createStyles(
|
|
8
|
-
({css, token}) => css`
|
|
7
|
+
({ css, token }) => css`
|
|
9
8
|
position: relative;
|
|
10
9
|
|
|
11
10
|
overflow: hidden;
|
|
@@ -46,16 +45,16 @@ const useStyles = createStyles(
|
|
|
46
45
|
}
|
|
47
46
|
`,
|
|
48
47
|
);
|
|
49
|
-
|
|
50
|
-
const {t} = useTranslation('plugin');
|
|
51
|
-
const {styles} = useStyles();
|
|
48
|
+
const Loading = memo(() => {
|
|
49
|
+
const { t } = useTranslation('plugin');
|
|
50
|
+
const { styles } = useStyles();
|
|
52
51
|
|
|
53
52
|
return (
|
|
54
53
|
<Flexbox align={'center'} gap={8} padding={16}>
|
|
55
|
-
<span className={styles}/>
|
|
54
|
+
<span className={styles} />
|
|
56
55
|
{t('loading.content')}
|
|
57
56
|
</Flexbox>
|
|
58
57
|
);
|
|
59
58
|
});
|
|
60
59
|
|
|
61
|
-
export default Loading
|
|
60
|
+
export default Loading;
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
import { ActionIconGroup, type ActionIconGroupProps } from '@lobehub/ui';
|
|
2
|
+
import { memo } from 'react';
|
|
3
|
+
|
|
4
|
+
import { useChatListActionsBar } from '../../hooks/useChatListActionsBar';
|
|
5
|
+
|
|
6
|
+
export interface ActionsBarProps extends ActionIconGroupProps {
|
|
7
|
+
text?: {
|
|
8
|
+
copy?: string;
|
|
9
|
+
delete?: string;
|
|
10
|
+
edit?: string;
|
|
11
|
+
regenerate?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const ActionsBar = memo<ActionsBarProps>(({ text, ...rest }) => {
|
|
16
|
+
const { regenerate, edit, copy, divider, del } = useChatListActionsBar(text);
|
|
17
|
+
return (
|
|
18
|
+
<ActionIconGroup
|
|
19
|
+
dropdownMenu={[edit, copy, regenerate, divider, del]}
|
|
20
|
+
items={[regenerate, edit]}
|
|
21
|
+
type="ghost"
|
|
22
|
+
{...rest}
|
|
23
|
+
/>
|
|
24
|
+
);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
export default ActionsBar;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { Icon, Tag } from '@lobehub/ui';
|
|
2
|
+
import { Divider } from 'antd';
|
|
3
|
+
import { Timer } from 'lucide-react';
|
|
4
|
+
import { memo } from 'react';
|
|
5
|
+
|
|
6
|
+
interface HistoryDividerProps {
|
|
7
|
+
enable?: boolean;
|
|
8
|
+
text?: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const HistoryDivider = memo<HistoryDividerProps>(({ enable, text }) => {
|
|
12
|
+
if (!enable) return null;
|
|
13
|
+
|
|
14
|
+
return (
|
|
15
|
+
<div style={{ padding: '0 20px' }}>
|
|
16
|
+
<Divider>
|
|
17
|
+
<Tag icon={<Icon icon={Timer} />}>{text || 'History Message'}</Tag>
|
|
18
|
+
</Divider>
|
|
19
|
+
</div>
|
|
20
|
+
);
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
export default HistoryDivider;
|