@lobehub/chat 0.62.0 → 0.63.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,56 @@
2
2
 
3
3
  # Changelog
4
4
 
5
+ ## [Version 0.63.0](https://github.com/lobehub/lobe-chat/compare/v0.62.1...v0.63.0)
6
+
7
+ <sup>Released on **2023-08-27**</sup>
8
+
9
+ #### ✨ Features
10
+
11
+ - **misc**: support sharing to shareGPT.
12
+
13
+ <br/>
14
+
15
+ <details>
16
+ <summary><kbd>Improvements and Fixes</kbd></summary>
17
+
18
+ #### What's improved
19
+
20
+ - **misc**: support sharing to shareGPT, closes [#119](https://github.com/lobehub/lobe-chat/issues/119) ([026e9ec](https://github.com/lobehub/lobe-chat/commit/026e9ec))
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.62.1](https://github.com/lobehub/lobe-chat/compare/v0.62.0...v0.62.1)
31
+
32
+ <sup>Released on **2023-08-26**</sup>
33
+
34
+ #### 🐛 Bug Fixes
35
+
36
+ - **misc**: Fix plugin settings error.
37
+
38
+ <br/>
39
+
40
+ <details>
41
+ <summary><kbd>Improvements and Fixes</kbd></summary>
42
+
43
+ #### What's fixed
44
+
45
+ - **misc**: Fix plugin settings error, closes [#117](https://github.com/lobehub/lobe-chat/issues/117) ([064d90e](https://github.com/lobehub/lobe-chat/commit/064d90e))
46
+
47
+ </details>
48
+
49
+ <div align="right">
50
+
51
+ [![](https://img.shields.io/badge/-BACK_TO_TOP-151515?style=flat-square)](#readme-top)
52
+
53
+ </div>
54
+
5
55
  ## [Version 0.62.0](https://github.com/lobehub/lobe-chat/compare/v0.61.0...v0.62.0)
6
56
 
7
57
  <sup>Released on **2023-08-26**</sup>
package/README.md CHANGED
@@ -129,7 +129,7 @@ This project is [MIT](./LICENSE) licensed.
129
129
 
130
130
  <!-- release -->
131
131
 
132
- [release-shield]: https://img.shields.io/npm/v/@lobehub/chat?label=%F0%9F%A4%AF%20NPM
132
+ [release-shield]: https://img.shields.io/npm/v/@lobehub/chat?label=%F0%9F%A4%AF%20Chat
133
133
  [release-url]: https://www.npmjs.com/package/@lobehub/chat
134
134
 
135
135
  <!-- releaseDate -->
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "0.62.0",
3
+ "version": "0.63.0",
4
4
  "description": "Lobe Chat is an open-source chatbot client using LangChain, Typescript and Next.js",
5
5
  "keywords": [
6
6
  "chatbot",
@@ -65,7 +65,7 @@
65
65
  "@ant-design/icons": "^5",
66
66
  "@emoji-mart/data": "^1",
67
67
  "@emoji-mart/react": "^1",
68
- "@icons-pack/react-simple-icons": "^8",
68
+ "@icons-pack/react-simple-icons": "^9",
69
69
  "@lobehub/chat-plugin-sdk": "latest",
70
70
  "@lobehub/chat-plugins-gateway": "latest",
71
71
  "@lobehub/ui": "latest",
@@ -113,7 +113,7 @@ const AgentPlugin = memo<AgentPluginProps>(({ config, updateConfig }) => {
113
113
  if (!item) return null;
114
114
  const manifest = pluginManifestMap[identifier];
115
115
 
116
- if (!manifest.settings) return null;
116
+ if (!manifest?.settings) return null;
117
117
 
118
118
  return {
119
119
  children: transformPluginSettings(manifest.settings).map((item) => ({
@@ -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
@@ -49,21 +49,24 @@ const List = () => {
49
49
 
50
50
  if (message.role === 'function')
51
51
  return (
52
- <Flexbox gap={12}>
52
+ <Flexbox gap={12} id={message.id}>
53
53
  <FunctionCall {...fcProps} />
54
54
  <PluginMessage loading={message.id === chatLoadingId} {...message} />
55
55
  </Flexbox>
56
56
  );
57
57
 
58
- if (message.role === 'assistant') {
59
- return isFunctionMessage(message.content) || !!message.function_call ? (
60
- <FunctionCall {...fcProps} />
61
- ) : (
62
- content
58
+ if (
59
+ message.role === 'assistant' &&
60
+ // 包含了 function 信息
61
+ isFunctionMessage(message.content)
62
+ )
63
+ return (
64
+ <div id={message.id}>
65
+ <FunctionCall {...fcProps} />
66
+ </div>
63
67
  );
64
- }
65
68
 
66
- return content;
69
+ return <div id={message.id}>{content}</div>;
67
70
  },
68
71
  [chatLoadingId],
69
72
  );
@@ -12,6 +12,7 @@ import { useGlobalStore } from '@/store/global';
12
12
  import { agentSelectors, useSessionChatInit, useSessionStore } from '@/store/session';
13
13
 
14
14
  import PluginTag from './PluginTag';
15
+ import ShareButton from './ShareButton';
15
16
 
16
17
  const Header = memo<{ settings?: boolean }>(({ settings = true }) => {
17
18
  const init = useSessionChatInit();
@@ -68,14 +69,7 @@ const Header = memo<{ settings?: boolean }>(({ settings = true }) => {
68
69
  }
69
70
  right={
70
71
  <>
71
- {/*<ActionIcon*/}
72
- {/* icon={Share2}*/}
73
- {/* onClick={() => {*/}
74
- {/* // genShareUrl();*/}
75
- {/* }}*/}
76
- {/* size={{ fontSize: 24 }}*/}
77
- {/* title={t('share')}*/}
78
- {/*/>*/}
72
+ <ShareButton />
79
73
  <ActionIcon
80
74
  icon={showAgentSettings ? PanelRightClose : PanelRightOpen}
81
75
  onClick={() => toggleConfig()}
@@ -0,0 +1,29 @@
1
+ import { ActionIcon, Icon } from '@lobehub/ui';
2
+ import { Loader2, Share2 } from 'lucide-react';
3
+ import { memo } from 'react';
4
+ import { useTranslation } from 'react-i18next';
5
+
6
+ import { useSessionStore } from '@/store/session';
7
+
8
+ const ShareButton = memo(() => {
9
+ const { t } = useTranslation('common');
10
+
11
+ const [shareLoading, shareToShareGPT] = useSessionStore((s) => [
12
+ s.shareLoading,
13
+
14
+ s.shareToShareGPT,
15
+ ]);
16
+
17
+ return shareLoading ? (
18
+ <Icon icon={Loader2} size={{ fontSize: 24 }} spin />
19
+ ) : (
20
+ <ActionIcon
21
+ icon={Share2}
22
+ onClick={shareToShareGPT}
23
+ size={{ fontSize: 24 }}
24
+ title={t('share')}
25
+ />
26
+ );
27
+ });
28
+
29
+ export default ShareButton;
@@ -0,0 +1,18 @@
1
+ import { ShareGPTConversation } from '@/types/share';
2
+
3
+ const SHAREGPT_URL = 'https://sharegpt.com/api/conversations';
4
+
5
+ export const genShareGPTUrl = async (conversation: ShareGPTConversation) => {
6
+ const res = await fetch(SHAREGPT_URL, {
7
+ body: JSON.stringify(conversation),
8
+ headers: {
9
+ 'Content-Type': 'application/json',
10
+ },
11
+ method: 'POST',
12
+ });
13
+
14
+ const { id } = await res.json();
15
+
16
+ // short link to the ShareGPT post
17
+ return `https://shareg.pt/${id}`;
18
+ };
@@ -3,12 +3,13 @@ import { StateCreator } from 'zustand/vanilla';
3
3
  import { SessionStore } from '@/store/session';
4
4
 
5
5
  import { ChatMessageAction, chatMessage } from './message';
6
+ import { ShareAction, chatShare } from './share';
6
7
  import { ChatTopicAction, chatTopic } from './topic';
7
8
 
8
9
  /**
9
10
  * 聊天操作
10
11
  */
11
- export interface ChatAction extends ChatTopicAction, ChatMessageAction {}
12
+ export interface ChatAction extends ChatTopicAction, ChatMessageAction, ShareAction {}
12
13
 
13
14
  export const createChatSlice: StateCreator<
14
15
  SessionStore,
@@ -18,4 +19,5 @@ export const createChatSlice: StateCreator<
18
19
  > = (...params) => ({
19
20
  ...chatTopic(...params),
20
21
  ...chatMessage(...params),
22
+ ...chatShare(...params),
21
23
  });
@@ -359,11 +359,4 @@ export const chatMessage: StateCreator<
359
359
 
360
360
  await realFetchAIResponse(chats, message.id);
361
361
  },
362
- // genShareUrl: () => {
363
- // const session = sessionSelectors.currentSession(get());
364
- // if (!session) return '';
365
- //
366
- // const agent = session.config;
367
- // return genShareMessagesUrl(session.chats, agent.systemRole);
368
- // },
369
362
  });
@@ -0,0 +1,91 @@
1
+ import { produce } from 'immer';
2
+ import { StateCreator } from 'zustand/vanilla';
3
+
4
+ import { genShareGPTUrl } from '@/services/shareGPT';
5
+ import { SessionStore } from '@/store/session';
6
+ import { ShareGPTConversation } from '@/types/share';
7
+
8
+ import { agentSelectors } from '../../agentConfig';
9
+ import { sessionSelectors } from '../../session/selectors';
10
+ import { chatSelectors } from '../selectors';
11
+
12
+ // const t = setNamespace('chat/share');
13
+ export interface ShareAction {
14
+ shareToShareGPT: () => void;
15
+ }
16
+
17
+ export const chatShare: StateCreator<
18
+ SessionStore,
19
+ [['zustand/devtools', never]],
20
+ [],
21
+ ShareAction
22
+ > = (set, get) => ({
23
+ // genShareUrl: () => {
24
+ // const session = sessionSelectors.currentSession(get());
25
+ // if (!session) return '';
26
+ //
27
+ // const agent = session.config;
28
+ // return genShareMessagesUrl(session.chats, agent.systemRole);
29
+ // },
30
+ shareToShareGPT: async () => {
31
+ const session = sessionSelectors.currentSession(get());
32
+ if (!session) return;
33
+ const messages = chatSelectors.currentChats(get());
34
+ const config = agentSelectors.currentAgentConfig(get());
35
+
36
+ const defaultMsg: ShareGPTConversation['items'] = [];
37
+
38
+ const shareMsgs = produce(defaultMsg, (draft) => {
39
+ if (!!config.systemRole) {
40
+ draft.push({
41
+ from: 'human',
42
+ value: `-------------- ### This is a system settings | 这是一条系统设定
43
+
44
+ ${config.systemRole}`,
45
+ });
46
+ }
47
+
48
+ for (const i of messages) {
49
+ switch (i.role) {
50
+ case 'user':
51
+ default: {
52
+ draft.push({ from: 'human', value: i.content });
53
+ break;
54
+ }
55
+
56
+ case 'assistant': {
57
+ draft.push({ from: 'gpt', value: i.content });
58
+ break;
59
+ }
60
+ case 'function': {
61
+ draft.push({
62
+ from: 'gpt',
63
+ value: `-------------- ### This is a function call | 这是一次插件调用
64
+ plugin name: ${i.plugin?.identifier}
65
+ function call name: ${i.plugin?.apiName}
66
+ result:
67
+ \`\`\`json
68
+ ${i.content}
69
+ \`\`\``,
70
+ });
71
+ break;
72
+ }
73
+ }
74
+ }
75
+
76
+ draft.push({
77
+ from: 'human',
78
+ value: 'Share from [LobeChat](https://github.com/lobehub/lobe-chat)',
79
+ });
80
+ });
81
+
82
+ set({ shareLoading: true });
83
+ const res = await genShareGPTUrl({
84
+ avatarUrl: 'https://npm.elemecdn.com/@lobehub/assets-logo/assets/logo-3d.webp',
85
+ items: shareMsgs,
86
+ });
87
+ set({ shareLoading: false });
88
+
89
+ window.open(res, '_blank');
90
+ },
91
+ });
@@ -3,6 +3,7 @@ export interface ChatState {
3
3
  activeTopicId?: string;
4
4
  chatLoadingId?: string;
5
5
  renameTopicId?: string;
6
+ shareLoading?: boolean;
6
7
  topicLoadingId?: string;
7
8
  }
8
9
 
@@ -0,0 +1,7 @@
1
+ export interface ShareGPTConversation {
2
+ avatarUrl?: string | null;
3
+ items: Array<{
4
+ from: 'human' | 'gpt';
5
+ value: any;
6
+ }>;
7
+ }