@lobehub/chat 0.91.0 → 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 (79) hide show
  1. package/CHANGELOG.md +25 -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 +3 -3
  22. package/src/app/chat/features/ChatInputContent/ActionBar/Token.tsx +1 -1
  23. package/src/app/chat/features/ChatInputContent/Footer/SaveTopic.tsx +1 -1
  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 +17 -2
  45. package/src/app/chat/features/Conversation/index.tsx +1 -1
  46. package/src/app/chat/features/SessionListContent/Inbox/index.tsx +1 -1
  47. package/src/app/chat/features/SessionListContent/List/AddButton.tsx +1 -1
  48. package/src/app/chat/features/SessionSearchBar/index.tsx +1 -1
  49. package/src/app/chat/features/TopicListContent/Topic/DefaultContent.tsx +1 -1
  50. package/src/app/chat/features/TopicListContent/Topic/TopicContent.tsx +1 -1
  51. package/src/app/chat/features/TopicListContent/Topic/index.tsx +1 -1
  52. package/src/app/chat/features/TopicListContent/TopicSearchBar/index.tsx +1 -1
  53. package/src/app/home/index.tsx +2 -2
  54. package/src/chains/chat.ts +77 -0
  55. package/src/features/AgentSetting/AgentPrompt/index.tsx +3 -3
  56. package/src/features/AgentSetting/store/action.ts +1 -1
  57. package/src/layout/ResponsiveLayout.client.tsx +4 -2
  58. package/src/locales/create.ts +2 -1
  59. package/src/locales/default/chat.ts +60 -0
  60. package/src/locales/default/common.ts +10 -45
  61. package/src/locales/options.ts +10 -0
  62. package/src/locales/resources/en_US.ts +2 -0
  63. package/src/locales/resources/index.ts +1 -1
  64. package/src/locales/resources/ja_JP.ts +2 -0
  65. package/src/locales/resources/ko_KR.ts +2 -0
  66. package/src/locales/resources/ru_RU.ts +2 -0
  67. package/src/locales/resources/zh_CN.ts +2 -0
  68. package/src/locales/resources/zh_TW.ts +2 -0
  69. package/src/store/global/selectors/settings.ts +4 -0
  70. package/src/store/session/slices/chat/actions/index.ts +7 -1
  71. package/src/store/session/slices/chat/actions/message.ts +2 -2
  72. package/src/store/session/slices/chat/actions/topic.ts +2 -2
  73. package/src/store/session/slices/chat/actions/translate.ts +87 -0
  74. package/src/store/session/slices/chat/selectors/chat.ts +23 -17
  75. package/src/store/session/slices/chat/selectors/index.ts +2 -2
  76. package/src/types/chatMessage.ts +5 -4
  77. package/src/types/translate.ts +4 -0
  78. package/src/prompts/chat.ts +0 -32
  79. /package/src/{prompts → chains}/agent.ts +0 -0
@@ -0,0 +1,77 @@
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 chainSummaryTitle = 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
+ };
33
+
34
+ export const chainTranslate = (
35
+ content: string,
36
+ targetLang: string,
37
+ ): Partial<OpenAIChatStreamPayload> => ({
38
+ messages: [
39
+ {
40
+ content: '你是一名擅长翻译的助理,你需要将输入的语言翻译为目标语言',
41
+ role: 'system',
42
+ },
43
+ {
44
+ content: `请将以下内容 ${content},翻译为 ${targetLang} `,
45
+ role: 'user',
46
+ },
47
+ ],
48
+ });
49
+ export const chainLangDetect = (content: string): Partial<OpenAIChatStreamPayload> => ({
50
+ messages: [
51
+ {
52
+ content:
53
+ '你是一名精通全世界语言的语言专家,你需要识别用户输入的内容,以国际标准 locale 进行输出',
54
+ role: 'system',
55
+ },
56
+ {
57
+ content: '{你好}',
58
+ role: 'user',
59
+ },
60
+ {
61
+ content: 'zh-CN',
62
+ role: 'assistant',
63
+ },
64
+ {
65
+ content: '{hello}',
66
+ role: 'user',
67
+ },
68
+ {
69
+ content: 'en-US',
70
+ role: 'assistant',
71
+ },
72
+ {
73
+ content: `{${content}}`,
74
+ role: 'user',
75
+ },
76
+ ],
77
+ });
@@ -42,9 +42,9 @@ const AgentPrompt = memo(() => {
42
42
  maxValue={ModelTokens[model as LanguageModel]}
43
43
  shape={'square'}
44
44
  text={{
45
- overload: t('tokenTag.overload', { ns: 'common' }),
46
- remained: t('tokenTag.remained', { ns: 'common' }),
47
- used: t('tokenTag.used', { ns: 'common' }),
45
+ overload: t('tokenTag.overload', { ns: 'chat' }),
46
+ remained: t('tokenTag.remained', { ns: 'chat' }),
47
+ used: t('tokenTag.used', { ns: 'chat' }),
48
48
  }}
49
49
  value={systemTokenCount}
50
50
  />
@@ -1,6 +1,6 @@
1
1
  import { StateCreator } from 'zustand/vanilla';
2
2
 
3
- import { promptPickEmoji, promptSummaryAgentName, promptSummaryDescription } from '@/prompts/agent';
3
+ import { promptPickEmoji, promptSummaryAgentName, promptSummaryDescription } from '@/chains/agent';
4
4
  import { MetaData } from '@/types/meta';
5
5
  import { LobeAgentConfig } from '@/types/session';
6
6
  import { fetchPresetTaskResult } from '@/utils/fetch';
@@ -15,10 +15,12 @@ const ResponsiveLayout = ({ children, Desktop, Mobile }: ServerResponsiveLayoutP
15
15
  const { t } = useTranslation();
16
16
  const mobile = useIsMobile();
17
17
 
18
- return (
18
+ return mobile ? (
19
19
  <Suspense fallback={<FullscreenLoading title={t('layoutInitializing', { ns: 'common' })} />}>
20
- {mobile ? <Mobile>{children}</Mobile> : <Desktop>{children}</Desktop>}
20
+ <Mobile>{children}</Mobile>
21
21
  </Suspense>
22
+ ) : (
23
+ <Desktop>{children}</Desktop>
22
24
  );
23
25
  };
24
26
 
@@ -4,10 +4,11 @@ import { initReactI18next } from 'react-i18next';
4
4
 
5
5
  import { getClientConfig } from '@/config/client';
6
6
  import { DEFAULT_LANG, LOBE_LOCALE_COOKIE } from '@/const/locale';
7
- import resources from '@/locales/resources';
8
7
  import type { Namespaces } from '@/types/locale';
9
8
  import { isOnServerSide } from '@/utils/env';
10
9
 
10
+ import { resources } from './options';
11
+
11
12
  const { I18N_DEBUG, I18N_DEBUG_BROWSER, I18N_DEBUG_SERVER } = getClientConfig();
12
13
  const debugMode = I18N_DEBUG ?? isOnServerSide ? I18N_DEBUG_SERVER : I18N_DEBUG_BROWSER;
13
14
 
@@ -0,0 +1,60 @@
1
+ export default {
2
+ agentDefaultMessage:
3
+ '你好,我是 **{{name}}**,你可以立即与我开始对话,也可以前往 [助手设置](/chat/settings#session={{id}}) 完善我的信息。',
4
+ agentDefaultMessageWithSystemRole: '你好,我是 **{{name}}**,{{systemRole}},让我们开始对话吧!',
5
+ backToBottom: '查看最新消息',
6
+ clearCurrentMessages: '清空当前会话消息',
7
+ confirmClearCurrentMessages: '即将清空当前会话消息,清空后将无法找回,请确认你的操作',
8
+ confirmRemoveSessionItemAlert: '即将删除该助手,删除后该将无法找回,请确认你的操作',
9
+ defaultAgent: '自定义助手',
10
+ defaultSession: '自定义助手',
11
+ historyRange: '历史范围',
12
+ inbox: {
13
+ defaultMessage:
14
+ '你好,我是你的智能助手,你可以问我任何问题,我会尽力回答你。如果需要获得更加专业或定制的助手,可以点击`+`创建自定义助手',
15
+ desc: '开启大脑集群,激发思维火花。你的智能助理,在这里与你交流一切',
16
+ title: '随便聊聊',
17
+ },
18
+ newAgent: '新建助手',
19
+ noDescription: '暂无描述',
20
+
21
+ regenerate: '重新生成',
22
+
23
+ roleAndArchive: '角色与记录',
24
+ searchAgentPlaceholder: '搜索助手和对话...',
25
+ send: '发送',
26
+ sendPlaceholder: '输入聊天内容...',
27
+ shareModal: {
28
+ download: '下载截图',
29
+ imageType: '图片格式',
30
+ screenshot: '截图',
31
+ settings: '导出设置',
32
+ shareToShareGPT: '生成 ShareGPT 分享链接',
33
+ withBackground: '包含背景图片',
34
+ withFooter: '包含页脚',
35
+ withPluginInfo: '包含插件信息',
36
+ withSystemRole: '包含助手角色设定',
37
+ },
38
+ stop: '停止',
39
+
40
+ temp: '临时',
41
+ tokenDetail: '角色设定: {{systemRoleToken}} · 历史消息: {{chatsToken}}',
42
+ tokenTag: {
43
+ overload: '超过限制',
44
+ remained: '剩余',
45
+ used: '使用',
46
+ },
47
+ topic: {
48
+ confirmRemoveTopic: '即将删除该话题,删除后将不可恢复,请谨慎操作。',
49
+ defaultTitle: '默认话题',
50
+ saveCurrentMessages: '将当前会话保存为话题',
51
+ searchPlaceholder: '搜索话题...',
52
+ title: '话题',
53
+ },
54
+ translate: {
55
+ clear: '删除翻译',
56
+ },
57
+ translateTo: '翻译',
58
+ updateAgent: '更新助理信息',
59
+ warp: '换行',
60
+ };
@@ -1,9 +1,6 @@
1
1
  export default {
2
2
  about: '关于',
3
3
  advanceSettings: '高级设置',
4
- agentDefaultMessage:
5
- '你好,我是 **{{name}}**,你可以立即与我开始对话,也可以前往 [助手设置](/chat/settings#session={{id}}) 完善我的信息。',
6
- agentDefaultMessageWithSystemRole: '你好,我是 **{{name}}**,{{systemRole}},让我们开始对话吧!',
7
4
  agentMaxToken: '会话最大长度',
8
5
  agentModel: '模型',
9
6
  agentProfile: '助手信息',
@@ -11,12 +8,9 @@ export default {
11
8
  archive: '归档',
12
9
  autoGenerate: '自动补全',
13
10
  autoGenerateTooltip: '基于提示词自动补全助手描述',
14
- backToBottom: '查看最新消息',
15
11
  cancel: '取消',
16
12
  changelog: '更新日志',
17
- clearCurrentMessages: '清空当前会话消息',
18
13
  close: '关闭',
19
- confirmClearCurrentMessages: '即将清空当前会话消息,清空后将无法找回,请确认你的操作',
20
14
  confirmRemoveSessionItemAlert: '即将删除该助手,删除后该将无法找回,请确认你的操作',
21
15
  copy: '复制',
22
16
  copySuccess: '复制成功',
@@ -37,18 +31,17 @@ export default {
37
31
  historyRange: '历史范围',
38
32
  import: '导入配置',
39
33
 
40
- inbox: {
41
- defaultMessage:
42
- '你好,我是你的智能助手,你可以问我任何问题,我会尽力回答你。如果需要获得更加专业或定制的助手,可以点击`+`创建自定义助手',
43
- desc: '开启大脑集群,激发思维火花。你的智能助理,在这里与你交流一切',
44
- title: '随便聊聊',
34
+ lang: {
35
+ 'en': '英语',
36
+ 'en-US': '英语',
37
+ 'ja-JP': '日语',
38
+ 'ko-KR': '韩语',
39
+ 'ru-RU': '俄语',
40
+ 'zh': '简体中文',
41
+ 'zh-CN': '简体中文',
42
+ 'zh-TW': '繁体中文',
45
43
  },
46
44
  layoutInitializing: '正在加载布局...',
47
- message: {
48
- function_loading: '插件请求中...',
49
- },
50
- moreSetting: '更多设置...',
51
- newAgent: '新建助手',
52
45
  noDescription: '暂无描述',
53
46
  ok: '确定',
54
47
  password: '密码',
@@ -58,24 +51,10 @@ export default {
58
51
  rename: '重命名',
59
52
  reset: '重置',
60
53
  retry: '重试',
61
- roleAndArchive: '角色与记录',
62
- searchAgentPlaceholder: '搜索助手和对话...',
63
54
  send: '发送',
64
- sendPlaceholder: '输入聊天内容...',
65
55
  sessionList: '助手列表',
66
56
  setting: '设置',
67
57
  share: '分享',
68
- shareModal: {
69
- download: '下载截图',
70
- imageType: '图片格式',
71
- screenshot: '截图',
72
- settings: '导出设置',
73
- shareToShareGPT: '生成 ShareGPT 分享链接',
74
- withBackground: '包含背景图片',
75
- withFooter: '包含页脚',
76
- withPluginInfo: '包含插件信息',
77
- withSystemRole: '包含助手角色设定',
78
- },
79
58
  stop: '停止',
80
59
  tab: {
81
60
  chat: '会话',
@@ -83,25 +62,11 @@ export default {
83
62
  setting: '设置',
84
63
  },
85
64
  temp: '临时',
86
- tokenDetail: '角色设定: {{systemRoleToken}} · 历史消息: {{chatsToken}}',
87
- tokenTag: {
88
- overload: '超过限制',
89
- remained: '剩余',
90
- used: '使用',
91
- },
92
- topic: {
93
- confirmRemoveTopic: '即将删除该话题,删除后将不可恢复,请谨慎操作。',
94
- defaultTitle: '默认话题',
95
- saveCurrentMessages: '将当前会话保存为话题',
96
- searchPlaceholder: '搜索话题...',
97
- title: '话题',
98
- },
65
+
99
66
  updateAgent: '更新助理信息',
100
- updatePrompt: '更新提示词',
101
67
  upgradeVersion: {
102
68
  action: '立即升级',
103
69
  hasNew: '有可用更新',
104
70
  newVersion: '有新版本可用:{{version}}',
105
71
  },
106
- warp: '换行',
107
72
  };
@@ -1,5 +1,7 @@
1
1
  import type { Locales } from '@/types/locale';
2
2
 
3
+ import _resources from './resources';
4
+
3
5
  type LocaleOptions = {
4
6
  label: string;
5
7
  value: Locales;
@@ -33,3 +35,11 @@ export const localeOptions: LocaleOptions = [
33
35
  ] as LocaleOptions;
34
36
 
35
37
  export const supportLangs: string[] = localeOptions.map((i) => i.value);
38
+
39
+ export const resources = {
40
+ ..._resources,
41
+ en: _resources['en-US'],
42
+ zh: _resources['zh-CN'],
43
+ };
44
+
45
+ export const supportLocales = Object.keys(resources);
@@ -1,3 +1,4 @@
1
+ import chat from '../../../locales/en_US/chat.json';
1
2
  import common from '../../../locales/en_US/common.json';
2
3
  import empty from '../../../locales/en_US/empty.json';
3
4
  import error from '../../../locales/en_US/error.json';
@@ -7,6 +8,7 @@ import setting from '../../../locales/en_US/setting.json';
7
8
  import welcome from '../../../locales/en_US/welcome.json';
8
9
 
9
10
  const resources = {
11
+ chat,
10
12
  common,
11
13
  empty,
12
14
  error,
@@ -10,10 +10,10 @@ const resources = {
10
10
  'ja-JP': ja_JP,
11
11
  'ko-KR': ko_KR,
12
12
  'ru-RU': ru_RU,
13
- 'zh': zh_CN,
14
13
  'zh-CN': zh_CN,
15
14
  'zh-TW': zh_TW,
16
15
  } as const;
16
+
17
17
  export default resources;
18
18
  export const defaultResources = zh_CN;
19
19
  export type Resources = typeof resources;
@@ -1,3 +1,4 @@
1
+ import chat from '../../../locales/ja_JP/chat.json';
1
2
  import common from '../../../locales/ja_JP/common.json';
2
3
  import empty from '../../../locales/ja_JP/empty.json';
3
4
  import error from '../../../locales/ja_JP/error.json';
@@ -7,6 +8,7 @@ import setting from '../../../locales/ja_JP/setting.json';
7
8
  import welcome from '../../../locales/ja_JP/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/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 = {