@lobehub/chat 0.90.3 → 0.92.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 (92) hide show
  1. package/CHANGELOG.md +50 -0
  2. package/locales/en_US/chat.json +55 -0
  3. package/locales/en_US/common.json +17 -51
  4. package/locales/ja_JP/chat.json +55 -0
  5. package/locales/ja_JP/common.json +14 -48
  6. package/locales/ko_KR/chat.json +55 -0
  7. package/locales/ko_KR/common.json +25 -59
  8. package/locales/ru_RU/chat.json +55 -0
  9. package/locales/ru_RU/common.json +11 -45
  10. package/locales/zh_CN/chat.json +55 -0
  11. package/locales/zh_CN/common.json +11 -45
  12. package/locales/zh_TW/chat.json +55 -0
  13. package/locales/zh_TW/common.json +30 -64
  14. package/package.json +2 -1
  15. package/src/app/chat/(desktop)/features/ChatHeader.tsx +1 -1
  16. package/src/app/chat/(desktop)/features/SessionHeader.tsx +1 -1
  17. package/src/app/chat/(mobile)/features/ChatHeader.tsx +1 -1
  18. package/src/app/chat/(mobile)/features/TopicList.tsx +1 -1
  19. package/src/app/chat/features/ChatHeader/ShareButton/Inner.tsx +1 -1
  20. package/src/app/chat/features/ChatHeader/ShareButton/Preview.tsx +1 -1
  21. package/src/app/chat/features/ChatInputContent/ActionBar/ActionRight.tsx +13 -2
  22. package/src/app/chat/features/ChatInputContent/ActionBar/Token.tsx +1 -1
  23. package/src/app/chat/features/ChatInputContent/Footer/SaveTopic.tsx +11 -2
  24. package/src/app/chat/features/ChatInputContent/Footer/index.tsx +1 -1
  25. package/src/app/chat/features/ChatInputContent/index.tsx +1 -1
  26. package/src/app/chat/features/Conversation/ChatList/Actions/Assistant.tsx +22 -0
  27. package/src/app/chat/features/Conversation/ChatList/Actions/Error.tsx +15 -0
  28. package/src/app/chat/features/Conversation/ChatList/{Messages/System.tsx → Actions/Fallback.tsx} +1 -1
  29. package/src/app/chat/features/Conversation/ChatList/Actions/Function.tsx +14 -0
  30. package/src/app/chat/features/Conversation/ChatList/{Messages → Actions}/User.tsx +6 -1
  31. package/src/app/chat/features/Conversation/ChatList/Actions/customAction.ts +21 -0
  32. package/src/app/chat/features/Conversation/ChatList/Actions/index.ts +13 -0
  33. package/src/app/chat/features/Conversation/ChatList/Extras/Assistant.tsx +39 -0
  34. package/src/app/chat/features/Conversation/ChatList/Extras/Translate.tsx +75 -0
  35. package/src/app/chat/features/Conversation/ChatList/Extras/User.tsx +24 -0
  36. package/src/app/chat/features/Conversation/ChatList/Extras/index.ts +9 -0
  37. package/src/app/chat/features/Conversation/ChatList/Loading.tsx +53 -0
  38. package/src/app/chat/features/Conversation/ChatList/Messages/Assistant.tsx +5 -58
  39. package/src/app/chat/features/Conversation/ChatList/Messages/Default.tsx +7 -1
  40. package/src/app/chat/features/Conversation/ChatList/Messages/Function.tsx +4 -23
  41. package/src/app/chat/features/Conversation/ChatList/Messages/index.ts +4 -17
  42. package/src/app/chat/features/Conversation/ChatList/Plugins/FunctionCall.tsx +0 -2
  43. package/src/app/chat/features/Conversation/ChatList/Plugins/PluginMessage.tsx +3 -4
  44. package/src/app/chat/features/Conversation/ChatList/index.tsx +34 -2
  45. package/src/app/chat/features/Conversation/index.tsx +1 -1
  46. package/src/app/chat/features/PageTitle/index.tsx +1 -3
  47. package/src/app/chat/features/SessionListContent/Inbox/index.tsx +1 -1
  48. package/src/app/chat/features/SessionListContent/List/AddButton.tsx +1 -1
  49. package/src/app/chat/features/SessionSearchBar/index.tsx +1 -1
  50. package/src/app/chat/features/TopicListContent/SystemRole/index.tsx +13 -2
  51. package/src/app/chat/features/TopicListContent/Topic/DefaultContent.tsx +1 -1
  52. package/src/app/chat/features/TopicListContent/Topic/TopicContent.tsx +11 -2
  53. package/src/app/chat/features/TopicListContent/Topic/index.tsx +1 -1
  54. package/src/app/chat/features/TopicListContent/TopicSearchBar/index.tsx +1 -1
  55. package/src/app/chat/settings/features/EditPage.tsx +1 -4
  56. package/src/app/home/index.tsx +2 -2
  57. package/src/app/market/index.tsx +1 -3
  58. package/src/app/metadata.ts +1 -3
  59. package/src/app/settings/agent/index.tsx +1 -3
  60. package/src/app/settings/common/index.tsx +1 -3
  61. package/src/app/settings/llm/index.tsx +1 -3
  62. package/src/chains/chat.ts +77 -0
  63. package/src/components/HotKeys/index.tsx +57 -0
  64. package/src/components/{PageTitle.tsx → PageTitle/index.tsx} +1 -1
  65. package/src/const/hotkeys.ts +4 -0
  66. package/src/features/AgentSetting/AgentPrompt/index.tsx +3 -3
  67. package/src/features/AgentSetting/store/action.ts +1 -1
  68. package/src/layout/ResponsiveLayout.client.tsx +4 -2
  69. package/src/locales/create.ts +2 -1
  70. package/src/locales/default/chat.ts +60 -0
  71. package/src/locales/default/common.ts +10 -45
  72. package/src/locales/options.ts +10 -0
  73. package/src/locales/resources/en_US.ts +2 -0
  74. package/src/locales/resources/index.ts +1 -1
  75. package/src/locales/resources/ja_JP.ts +2 -0
  76. package/src/locales/resources/ko_KR.ts +2 -0
  77. package/src/locales/resources/ru_RU.ts +2 -0
  78. package/src/locales/resources/zh_CN.ts +2 -0
  79. package/src/locales/resources/zh_TW.ts +2 -0
  80. package/src/store/global/selectors/settings.ts +4 -0
  81. package/src/store/session/slices/chat/actions/index.ts +7 -1
  82. package/src/store/session/slices/chat/actions/message.ts +2 -2
  83. package/src/store/session/slices/chat/actions/topic.ts +2 -2
  84. package/src/store/session/slices/chat/actions/translate.ts +87 -0
  85. package/src/store/session/slices/chat/selectors/chat.ts +23 -17
  86. package/src/store/session/slices/chat/selectors/index.ts +2 -2
  87. package/src/types/chatMessage.ts +5 -4
  88. package/src/types/translate.ts +4 -0
  89. package/src/prompts/chat.ts +0 -32
  90. package/src/utils/genSiteHeadTitle.ts +0 -1
  91. /package/src/{prompts → chains}/agent.ts +0 -0
  92. /package/src/components/{ResponsiveIndex.tsx → ResponsiveIndex/index.tsx} +0 -0
@@ -1,3 +1,4 @@
1
+ import chat from '../../../locales/ko_KR/chat.json';
1
2
  import common from '../../../locales/ko_KR/common.json';
2
3
  import empty from '../../../locales/ko_KR/empty.json';
3
4
  import error from '../../../locales/ko_KR/error.json';
@@ -7,6 +8,7 @@ import setting from '../../../locales/ko_KR/setting.json';
7
8
  import welcome from '../../../locales/ko_KR/welcome.json';
8
9
 
9
10
  const resources = {
11
+ chat,
10
12
  common,
11
13
  empty,
12
14
  error,
@@ -1,3 +1,4 @@
1
+ import chat from '../../../locales/ru_RU/chat.json';
1
2
  import common from '../../../locales/ru_RU/common.json';
2
3
  import empty from '../../../locales/ru_RU/empty.json';
3
4
  import error from '../../../locales/ru_RU/error.json';
@@ -7,6 +8,7 @@ import setting from '../../../locales/ru_RU/setting.json';
7
8
  import welcome from '../../../locales/ru_RU/welcome.json';
8
9
 
9
10
  const resources = {
11
+ chat,
10
12
  common,
11
13
  empty,
12
14
  error,
@@ -1,3 +1,4 @@
1
+ import chat from '../default/chat';
1
2
  import common from '../default/common';
2
3
  import empty from '../default/empty';
3
4
  import error from '../default/error';
@@ -7,6 +8,7 @@ import setting from '../default/setting';
7
8
  import welcome from '../default/welcome';
8
9
 
9
10
  const resources = {
11
+ chat,
10
12
  common,
11
13
  empty,
12
14
  error,
@@ -1,3 +1,4 @@
1
+ import chat from '../../../locales/zh_TW/chat.json';
1
2
  import common from '../../../locales/zh_TW/common.json';
2
3
  import empty from '../../../locales/zh_TW/empty.json';
3
4
  import error from '../../../locales/zh_TW/error.json';
@@ -7,6 +8,7 @@ import setting from '../../../locales/zh_TW/setting.json';
7
8
  import welcome from '../../../locales/zh_TW/welcome.json';
8
9
 
9
10
  const resources = {
11
+ chat,
10
12
  common,
11
13
  empty,
12
14
  error,
@@ -1,8 +1,10 @@
1
1
  import { DEFAULT_OPENAI_MODEL_LIST } from '@/const/llm';
2
+ import { DEFAULT_LANG } from '@/const/locale';
2
3
  import { DEFAULT_AGENT_META } from '@/const/meta';
3
4
  import { DEFAULT_AGENT, DEFAULT_AGENT_CONFIG, DEFAULT_SETTINGS } from '@/const/settings';
4
5
  import { Locales } from '@/locales/resources';
5
6
  import { GlobalSettings } from '@/types/settings';
7
+ import { isOnServerSide } from '@/utils/env';
6
8
  import { merge } from '@/utils/merge';
7
9
 
8
10
  import { GlobalStore } from '../store';
@@ -35,6 +37,8 @@ export const exportSettings = (s: GlobalStore) => {
35
37
  const currentLanguage = (s: GlobalStore) => {
36
38
  const locale = s.settings.language;
37
39
  if (locale === 'auto') {
40
+ if (isOnServerSide) return DEFAULT_LANG;
41
+
38
42
  return navigator.language as Locales;
39
43
  }
40
44
 
@@ -5,11 +5,16 @@ import { SessionStore } from '@/store/session';
5
5
  import { ChatMessageAction, chatMessage } from './message';
6
6
  import { ShareAction, chatShare } from './share';
7
7
  import { ChatTopicAction, chatTopic } from './topic';
8
+ import { ChatTranslateAction, chatTranslate } from './translate';
8
9
 
9
10
  /**
10
11
  * 聊天操作
11
12
  */
12
- export interface ChatAction extends ChatTopicAction, ChatMessageAction, ShareAction {}
13
+ export interface ChatAction
14
+ extends ChatTopicAction,
15
+ ChatMessageAction,
16
+ ShareAction,
17
+ ChatTranslateAction {}
13
18
 
14
19
  export const createChatSlice: StateCreator<
15
20
  SessionStore,
@@ -20,4 +25,5 @@ export const createChatSlice: StateCreator<
20
25
  ...chatTopic(...params),
21
26
  ...chatMessage(...params),
22
27
  ...chatShare(...params),
28
+ ...chatTranslate(...params),
23
29
  });
@@ -66,13 +66,14 @@ export interface ChatMessageAction {
66
66
  * @param text - 消息文本
67
67
  */
68
68
  sendMessage: (text: string) => Promise<void>;
69
-
70
69
  stopGenerateMessage: () => void;
70
+
71
71
  toggleChatLoading: (
72
72
  loading: boolean,
73
73
  id?: string,
74
74
  action?: string,
75
75
  ) => AbortController | undefined;
76
+
76
77
  triggerFunctionCall: (id: string) => Promise<void>;
77
78
  }
78
79
 
@@ -298,7 +299,6 @@ export const chatMessage: StateCreator<
298
299
 
299
300
  toggleChatLoading(false);
300
301
  },
301
-
302
302
  toggleChatLoading: (loading, id, action) => {
303
303
  if (loading) {
304
304
  const abortController = new AbortController();
@@ -1,7 +1,7 @@
1
1
  import { StateCreator } from 'zustand/vanilla';
2
2
 
3
+ import { chainSummaryTitle } from '@/chains/chat';
3
4
  import { LOADING_FLAT } from '@/const/message';
4
- import { promptSummaryTitle } from '@/prompts/chat';
5
5
  import { SessionStore } from '@/store/session';
6
6
  import { fetchPresetTaskResult } from '@/utils/fetch';
7
7
  import { setNamespace } from '@/utils/storeDebug';
@@ -116,7 +116,7 @@ export const chatTopic: StateCreator<
116
116
  output += x;
117
117
  dispatchTopic({ id: topicId, key: 'title', type: 'updateChatTopic', value: output });
118
118
  },
119
- params: await promptSummaryTitle(messages),
119
+ params: await chainSummaryTitle(messages),
120
120
  });
121
121
 
122
122
  return topicId;
@@ -0,0 +1,87 @@
1
+ import { produce } from 'immer';
2
+ import { StateCreator } from 'zustand/vanilla';
3
+
4
+ import { chainLangDetect, chainTranslate } from '@/chains/chat';
5
+ import { supportLocales } from '@/locales/options';
6
+ import { SessionStore } from '@/store/session';
7
+ import { fetchPresetTaskResult } from '@/utils/fetch';
8
+ import { setNamespace } from '@/utils/storeDebug';
9
+
10
+ import { sessionSelectors } from '../../session/selectors';
11
+
12
+ const t = setNamespace('chat/translate');
13
+
14
+ /**
15
+ * 翻译事件
16
+ */
17
+ export interface ChatTranslateAction {
18
+ clearTranslate: (id: string) => void;
19
+
20
+ /**
21
+ * 翻译消息
22
+ * @param id
23
+ */
24
+ translateMessage: (id: string, targetLang: string) => Promise<void>;
25
+ }
26
+
27
+ export const chatTranslate: StateCreator<
28
+ SessionStore,
29
+ [['zustand/devtools', never]],
30
+ [],
31
+ ChatTranslateAction
32
+ > = (set, get) => ({
33
+ clearTranslate: (id) => {
34
+ get().dispatchMessage({
35
+ id,
36
+ key: 'translate',
37
+ type: 'updateMessageExtra',
38
+ value: null,
39
+ });
40
+ },
41
+
42
+ translateMessage: async (id, targetLang) => {
43
+ const { toggleChatLoading, dispatchMessage } = get();
44
+ const session = sessionSelectors.currentSession(get());
45
+ if (!session || !id) return;
46
+
47
+ const message = session.chats[id];
48
+ if (!message) return;
49
+
50
+ let content = '';
51
+ let from = '';
52
+
53
+ dispatchMessage({
54
+ id,
55
+ key: 'translate',
56
+ type: 'updateMessageExtra',
57
+ value: { content: '', to: targetLang },
58
+ });
59
+
60
+ toggleChatLoading(true, id, t('translateMessage(start)', { id }) as string);
61
+
62
+ // detect from language
63
+ fetchPresetTaskResult({
64
+ params: chainLangDetect(message.content),
65
+ }).then((data) => {
66
+ if (data && supportLocales.includes(data)) from = data;
67
+ });
68
+
69
+ // translate to target language
70
+ await fetchPresetTaskResult({
71
+ onMessageHandle: (text) => {
72
+ dispatchMessage({
73
+ id,
74
+ key: 'translate',
75
+ type: 'updateMessageExtra',
76
+ value: produce({ content: '', from, to: targetLang }, (draft) => {
77
+ content += text;
78
+ draft.content += content;
79
+ }),
80
+ });
81
+ },
82
+ params: chainTranslate(message.content, targetLang),
83
+ });
84
+
85
+ toggleChatLoading(false);
86
+ },
87
+ });
@@ -52,15 +52,21 @@ export const currentChatsWithGuideMessage = (s: SessionStore): ChatMessage[] =>
52
52
 
53
53
  const [activeId, isInbox] = [s.activeId, s.activeId === INBOX_SESSION_ID];
54
54
  const meta = agentSelectors.currentAgentMeta(s);
55
+
56
+ const inboxMsg = t('inbox.defaultMessage', { ns: 'chat' });
57
+ const agentSystemRoleMsg = t('agentDefaultMessageWithSystemRole', {
58
+ name: meta.title || t('defaultAgent'),
59
+ ns: 'chat',
60
+ systemRole: meta.description,
61
+ });
62
+ const agentMsg = t('agentDefaultMessage', {
63
+ id: activeId,
64
+ name: meta.title || t('defaultAgent'),
65
+ ns: 'chat',
66
+ });
67
+
55
68
  const emptyInboxGuideMessage = {
56
- content: isInbox
57
- ? t('inbox.defaultMessage')
58
- : !!meta.description
59
- ? t('agentDefaultMessageWithSystemRole', {
60
- name: meta.title || t('defaultAgent'),
61
- systemRole: meta.description,
62
- })
63
- : t('agentDefaultMessage', { id: activeId, name: meta.title || t('defaultAgent') }),
69
+ content: isInbox ? inboxMsg : !!meta.description ? agentSystemRoleMsg : agentMsg,
64
70
  createAt: Date.now(),
65
71
  extra: {},
66
72
  id: 'default',
@@ -86,22 +92,22 @@ export const chatsMessageString = (s: SessionStore): string => {
86
92
  return chats.map((m) => m.content).join('');
87
93
  };
88
94
 
89
- export const currentFunctionCallProps = (
90
- s: SessionStore,
91
- ): ((
92
- props: Pick<ChatMessage, 'plugin' | 'function_call' | 'content' | 'id'>,
93
- ) => FunctionCallProps) => {
94
- const chatLoadingId = s.chatLoadingId;
95
- return ({ plugin, function_call, content, id }) => {
95
+ export const getFunctionMessageParams =
96
+ (
97
+ s: SessionStore,
98
+ ): ((
99
+ props: Pick<ChatMessage, 'plugin' | 'function_call' | 'content' | 'id'>,
100
+ ) => FunctionCallProps) =>
101
+ ({ plugin, function_call, content, id }) => {
96
102
  const itemId = plugin?.identifier || function_call?.name;
97
103
  const command = plugin ?? function_call;
98
104
  const args = command?.arguments;
105
+
99
106
  return {
100
107
  arguments: args,
101
108
  command,
102
109
  content,
103
110
  id: itemId,
104
- loading: id === chatLoadingId,
111
+ loading: id === s.chatLoadingId,
105
112
  };
106
113
  };
107
- };
@@ -3,8 +3,8 @@ import {
3
3
  currentChats,
4
4
  currentChatsWithGuideMessage,
5
5
  currentChatsWithHistoryConfig,
6
- currentFunctionCallProps,
7
6
  getChatsById,
7
+ getFunctionMessageParams,
8
8
  } from './chat';
9
9
  import { currentTopics, getTopicMessages } from './topic';
10
10
 
@@ -13,8 +13,8 @@ export const chatSelectors = {
13
13
  currentChats,
14
14
  currentChatsWithGuideMessage,
15
15
  currentChatsWithHistoryConfig,
16
- currentFunctionCallProps,
17
16
  getChatsById,
17
+ getFunctionMessageParams,
18
18
  };
19
19
 
20
20
  export const topicSelectors = {
@@ -1,6 +1,7 @@
1
1
  import { PluginRequestPayload } from '@lobehub/chat-plugin-sdk';
2
2
 
3
3
  import { ErrorType } from '@/types/fetch';
4
+ import { Translate } from '@/types/translate';
4
5
 
5
6
  import { LLMRoleType } from './llm';
6
7
  import { BaseDataModel } from './meta';
@@ -18,6 +19,9 @@ export interface OpenAIFunctionCall {
18
19
  name: string;
19
20
  }
20
21
 
22
+ export interface ChatTranslate extends Translate {
23
+ content?: string;
24
+ }
21
25
  export interface ChatMessage extends BaseDataModel {
22
26
  /**
23
27
  * @title 内容
@@ -29,10 +33,7 @@ export interface ChatMessage extends BaseDataModel {
29
33
  extra?: {
30
34
  fromModel?: string;
31
35
  // 翻译
32
- translate?: {
33
- target: string;
34
- to: string;
35
- };
36
+ translate?: ChatTranslate;
36
37
  } & Record<string, any>;
37
38
 
38
39
  /**
@@ -0,0 +1,4 @@
1
+ export interface Translate {
2
+ from: string;
3
+ to: string;
4
+ }
@@ -1,32 +0,0 @@
1
- import { chatHelpers } from '@/store/session/helpers';
2
- import { LanguageModel } from '@/types/llm';
3
- import { OpenAIChatMessage, OpenAIChatStreamPayload } from '@/types/openai/chat';
4
-
5
- export const promptSummaryTitle = async (
6
- messages: OpenAIChatMessage[],
7
- ): Promise<Partial<OpenAIChatStreamPayload>> => {
8
- const finalMessages: OpenAIChatMessage[] = [
9
- {
10
- content:
11
- '你是一名擅长会话的助理,你需要将用户的会话总结为 10 个字以内的标题,不需要包含标点符号',
12
- role: 'system',
13
- },
14
- {
15
- content: `${messages.map((message) => `${message.role}: ${message.content}`).join('\n')}
16
-
17
- 请总结上述对话为10个字以内的标题,不需要包含标点符号`,
18
- role: 'user',
19
- },
20
- ];
21
- // 如果超过 4k,则使用 GPT3.5 16K 模型
22
- const tokens = await chatHelpers.getMessagesTokenCount(finalMessages);
23
- let model: LanguageModel | undefined = undefined;
24
- if (tokens > 4000) {
25
- model = LanguageModel.GPT3_5_16K;
26
- }
27
-
28
- return {
29
- messages: finalMessages,
30
- model,
31
- };
32
- };
@@ -1 +0,0 @@
1
- export const genSiteHeadTitle = (title?: string) => (title ? `${title} · LobeChat` : 'LobeChat');
File without changes