@lobehub/lobehub 2.0.0-next.123 → 2.0.0-next.124
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 +26 -0
- package/README.md +8 -8
- package/README.zh-CN.md +8 -8
- package/changelog/v1.json +9 -0
- package/docs/development/database-schema.dbml +1 -0
- package/package.json +1 -1
- package/packages/database/migrations/0048_add_editor_data.sql +1 -0
- package/packages/database/migrations/meta/0048_snapshot.json +8533 -0
- package/packages/database/migrations/meta/_journal.json +8 -1
- package/packages/database/src/core/migrations.json +6 -0
- package/packages/database/src/schemas/agent.ts +1 -0
- package/src/app/[variants]/(main)/chat/components/topic/features/Topic/TopicListContent/TopicItem/TopicContent.tsx +15 -8
- package/src/app/[variants]/(main)/chat/components/topic/features/Topic/TopicListContent/TopicItem/index.tsx +27 -30
- package/src/features/AgentSetting/AgentPlugin/index.tsx +6 -2
- package/src/layout/GlobalProvider/StoreInitialization.tsx +3 -3
- package/src/store/aiInfra/slices/aiProvider/action.ts +4 -4
|
@@ -336,7 +336,14 @@
|
|
|
336
336
|
"when": 1763987922211,
|
|
337
337
|
"tag": "0047_add_slug_document",
|
|
338
338
|
"breakpoints": true
|
|
339
|
+
},
|
|
340
|
+
{
|
|
341
|
+
"idx": 48,
|
|
342
|
+
"version": "7",
|
|
343
|
+
"when": 1764215503726,
|
|
344
|
+
"tag": "0048_add_editor_data",
|
|
345
|
+
"breakpoints": true
|
|
339
346
|
}
|
|
340
347
|
],
|
|
341
348
|
"version": "6"
|
|
342
|
-
}
|
|
349
|
+
}
|
|
@@ -797,5 +797,11 @@
|
|
|
797
797
|
"bps": true,
|
|
798
798
|
"folderMillis": 1763987922211,
|
|
799
799
|
"hash": "f823b521f4d25e5dc5ab238b372727d2d2d7f0aed27b5eabc8a9608ce4e50568"
|
|
800
|
+
},
|
|
801
|
+
{
|
|
802
|
+
"sql": ["ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"editor_data\" jsonb;"],
|
|
803
|
+
"bps": true,
|
|
804
|
+
"folderMillis": 1764215503726,
|
|
805
|
+
"hash": "4188893a9083b3c7baebdbad0dd3f9d9400ede7584ca2394f5c64305dc9ec7b0"
|
|
800
806
|
}
|
|
801
807
|
]
|
|
@@ -34,6 +34,7 @@ export const agents = pgTable(
|
|
|
34
34
|
title: varchar('title', { length: 255 }),
|
|
35
35
|
description: varchar('description', { length: 1000 }),
|
|
36
36
|
tags: jsonb('tags').$type<string[]>().default([]),
|
|
37
|
+
editorData: jsonb('editor_data'),
|
|
37
38
|
avatar: text('avatar'),
|
|
38
39
|
backgroundColor: text('background_color'),
|
|
39
40
|
marketIdentifier: text('market_identifier'),
|
|
@@ -97,15 +97,15 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
|
|
|
97
97
|
},
|
|
98
98
|
...(isDesktop
|
|
99
99
|
? [
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
100
|
+
{
|
|
101
|
+
icon: <Icon icon={ExternalLink} />,
|
|
102
|
+
key: 'openInNewWindow',
|
|
103
|
+
label: t('actions.openInNewWindow'),
|
|
104
|
+
onClick: () => {
|
|
105
|
+
openTopicInNewWindow(activeId, id);
|
|
106
|
+
},
|
|
106
107
|
},
|
|
107
|
-
|
|
108
|
-
]
|
|
108
|
+
]
|
|
109
109
|
: []),
|
|
110
110
|
{
|
|
111
111
|
type: 'divider',
|
|
@@ -210,6 +210,13 @@ const TopicContent = memo<TopicContentProps>(({ id, title, fav, showMore }) => {
|
|
|
210
210
|
) : (
|
|
211
211
|
<EditableText
|
|
212
212
|
editing={editing}
|
|
213
|
+
onBlur={(e) => {
|
|
214
|
+
const v = (e.target as HTMLInputElement).value;
|
|
215
|
+
if (title !== v) {
|
|
216
|
+
updateTopicTitle(id, v);
|
|
217
|
+
}
|
|
218
|
+
toggleEditing(false);
|
|
219
|
+
}}
|
|
213
220
|
onChangeEnd={(v) => {
|
|
214
221
|
if (title !== v) {
|
|
215
222
|
updateTopicTitle(id, v);
|
|
@@ -3,7 +3,6 @@ import { createStyles } from 'antd-style';
|
|
|
3
3
|
import qs from 'query-string';
|
|
4
4
|
import { Suspense, memo, useState } from 'react';
|
|
5
5
|
import { Flexbox } from 'react-layout-kit';
|
|
6
|
-
import { Link } from 'react-router-dom';
|
|
7
6
|
|
|
8
7
|
import { useChatStore } from '@/store/chat';
|
|
9
8
|
import { useGlobalStore } from '@/store/global';
|
|
@@ -54,47 +53,45 @@ export interface ConfigCellProps {
|
|
|
54
53
|
const TopicItem = memo<ConfigCellProps>(({ title, active, id, fav, threadId }) => {
|
|
55
54
|
const { styles, cx } = useStyles();
|
|
56
55
|
const toggleConfig = useGlobalStore((s) => s.toggleMobileTopic);
|
|
57
|
-
const [toggleTopic] = useChatStore((s) => [s.switchTopic]);
|
|
56
|
+
const [toggleTopic, editing] = useChatStore((s) => [s.switchTopic, s.topicRenamingId === id]);
|
|
58
57
|
const activeId = useSessionStore((s) => s.activeId);
|
|
59
58
|
const [isHover, setHovering] = useState(false);
|
|
60
59
|
|
|
61
|
-
const topicUrl = qs.stringifyUrl({
|
|
62
|
-
query: id ? { session: activeId, topic: id } : { session: activeId },
|
|
63
|
-
url: '/chat',
|
|
64
|
-
});
|
|
65
|
-
|
|
66
60
|
return (
|
|
67
61
|
<Flexbox style={{ position: 'relative' }}>
|
|
68
|
-
<
|
|
62
|
+
<Flexbox
|
|
63
|
+
align={'center'}
|
|
64
|
+
className={cx(styles.container, 'topic-item', active && !threadId && styles.active)}
|
|
65
|
+
distribution={'space-between'}
|
|
66
|
+
horizontal
|
|
69
67
|
onClick={(e) => {
|
|
70
|
-
|
|
68
|
+
// 重命名时不切换话题
|
|
69
|
+
if (editing) return;
|
|
70
|
+
// Ctrl/Cmd+点击在新窗口打开
|
|
71
|
+
if (e.button === 0 && (e.metaKey || e.ctrlKey) && id) {
|
|
72
|
+
const topicUrl = qs.stringifyUrl({
|
|
73
|
+
query: { session: activeId, topic: id },
|
|
74
|
+
url: '/chat',
|
|
75
|
+
});
|
|
76
|
+
window.open(topicUrl, '_blank');
|
|
71
77
|
return;
|
|
72
78
|
}
|
|
73
|
-
e.preventDefault();
|
|
74
79
|
toggleTopic(id);
|
|
75
80
|
toggleConfig(false);
|
|
76
81
|
}}
|
|
77
|
-
|
|
82
|
+
onMouseEnter={() => {
|
|
83
|
+
setHovering(true);
|
|
84
|
+
}}
|
|
85
|
+
onMouseLeave={() => {
|
|
86
|
+
setHovering(false);
|
|
87
|
+
}}
|
|
78
88
|
>
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
setHovering(true);
|
|
86
|
-
}}
|
|
87
|
-
onMouseLeave={() => {
|
|
88
|
-
setHovering(false);
|
|
89
|
-
}}
|
|
90
|
-
>
|
|
91
|
-
{!id ? (
|
|
92
|
-
<DefaultContent />
|
|
93
|
-
) : (
|
|
94
|
-
<TopicContent fav={fav} id={id} showMore={isHover} title={title} />
|
|
95
|
-
)}
|
|
96
|
-
</Flexbox>
|
|
97
|
-
</Link>
|
|
89
|
+
{!id ? (
|
|
90
|
+
<DefaultContent />
|
|
91
|
+
) : (
|
|
92
|
+
<TopicContent fav={fav} id={id} showMore={isHover} title={title} />
|
|
93
|
+
)}
|
|
94
|
+
</Flexbox>
|
|
98
95
|
{active && (
|
|
99
96
|
<Suspense
|
|
100
97
|
fallback={
|
|
@@ -4,7 +4,7 @@ import { Avatar, Button, Form, type FormGroupItemType, Tag, Tooltip } from '@lob
|
|
|
4
4
|
import { Empty, Space, Switch } from 'antd';
|
|
5
5
|
import isEqual from 'fast-deep-equal';
|
|
6
6
|
import { LucideTrash2, Store } from 'lucide-react';
|
|
7
|
-
import Link from '
|
|
7
|
+
import { Link, useNavigate } from 'react-router-dom';
|
|
8
8
|
import { memo, useState } from 'react';
|
|
9
9
|
import { Trans, useTranslation } from 'react-i18next';
|
|
10
10
|
import { Center, Flexbox } from 'react-layout-kit';
|
|
@@ -29,6 +29,8 @@ const AgentPlugin = memo(() => {
|
|
|
29
29
|
|
|
30
30
|
const [showStore, setShowStore] = useState(false);
|
|
31
31
|
|
|
32
|
+
const navigate = useNavigate();
|
|
33
|
+
|
|
32
34
|
const [userEnabledPlugins, toggleAgentPlugin] = useStore((s) => [
|
|
33
35
|
s.config.plugins || [],
|
|
34
36
|
s.toggleAgentPlugin,
|
|
@@ -134,11 +136,13 @@ const AgentPlugin = memo(() => {
|
|
|
134
136
|
<Trans i18nKey={'plugin.empty'} ns={'setting'}>
|
|
135
137
|
暂无安装插件,
|
|
136
138
|
<Link
|
|
137
|
-
href={'/'}
|
|
138
139
|
onClick={(e) => {
|
|
140
|
+
e.stopPropagation();
|
|
139
141
|
e.preventDefault();
|
|
140
142
|
setShowStore(true);
|
|
143
|
+
navigate('/discover/mcp');
|
|
141
144
|
}}
|
|
145
|
+
to={'/discover/mcp'}
|
|
142
146
|
>
|
|
143
147
|
前往插件市场
|
|
144
148
|
</Link>
|
|
@@ -9,14 +9,14 @@ import { createStoreUpdater } from 'zustand-utils';
|
|
|
9
9
|
import { useIsMobile } from '@/hooks/useIsMobile';
|
|
10
10
|
import { useAgentStore } from '@/store/agent';
|
|
11
11
|
import { useAiInfraStore } from '@/store/aiInfra';
|
|
12
|
+
import { useElectronStore } from '@/store/electron';
|
|
13
|
+
import { electronSyncSelectors } from '@/store/electron/selectors';
|
|
12
14
|
import { useGlobalStore } from '@/store/global';
|
|
13
15
|
import { useServerConfigStore } from '@/store/serverConfig';
|
|
14
16
|
import { serverConfigSelectors } from '@/store/serverConfig/selectors';
|
|
15
17
|
import { useUrlHydrationStore } from '@/store/urlHydration';
|
|
16
18
|
import { useUserStore } from '@/store/user';
|
|
17
19
|
import { authSelectors } from '@/store/user/selectors';
|
|
18
|
-
import { electronSyncSelectors } from '@/store/electron/selectors';
|
|
19
|
-
import { useElectronStore } from '@/store/electron';
|
|
20
20
|
|
|
21
21
|
const StoreInitialization = memo(() => {
|
|
22
22
|
// prefetch error ns to avoid don't show error content correctly
|
|
@@ -68,7 +68,7 @@ const StoreInitialization = memo(() => {
|
|
|
68
68
|
const isSyncActive = useElectronStore((s) => electronSyncSelectors.isSyncActive(s));
|
|
69
69
|
|
|
70
70
|
// init user provider key vaults
|
|
71
|
-
useInitAiProviderKeyVaults(isLoginOnInit,isSyncActive);
|
|
71
|
+
useInitAiProviderKeyVaults(isLoginOnInit, isSyncActive);
|
|
72
72
|
|
|
73
73
|
// init user state
|
|
74
74
|
useInitUserState(isLoginOnInit, serverConfig, {
|
|
@@ -77,10 +77,10 @@ export const normalizeImageModel = async (
|
|
|
77
77
|
const fallbackParametersPromise = model.parameters
|
|
78
78
|
? Promise.resolve<ModelParamsSchema | undefined>(model.parameters)
|
|
79
79
|
: getModelPropertyWithFallback<ModelParamsSchema | undefined>(
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
80
|
+
model.id,
|
|
81
|
+
'parameters',
|
|
82
|
+
model.providerId,
|
|
83
|
+
);
|
|
84
84
|
|
|
85
85
|
const modelWithPricing = model as AIImageModelCard;
|
|
86
86
|
const fallbackPricingPromise = modelWithPricing.pricing
|