@lobehub/chat 1.140.0 → 1.141.1
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 +68 -0
- package/changelog/v1.json +24 -0
- package/locales/ar/chat.json +13 -0
- package/locales/ar/common.json +1 -0
- package/locales/ar/components.json +4 -0
- package/locales/ar/file.json +2 -2
- package/locales/bg-BG/chat.json +13 -0
- package/locales/bg-BG/common.json +1 -0
- package/locales/bg-BG/components.json +4 -0
- package/locales/bg-BG/file.json +2 -2
- package/locales/de-DE/chat.json +13 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/components.json +4 -0
- package/locales/de-DE/file.json +2 -2
- package/locales/en-US/chat.json +13 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/components.json +4 -0
- package/locales/en-US/file.json +2 -2
- package/locales/es-ES/chat.json +13 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/es-ES/components.json +4 -0
- package/locales/es-ES/file.json +2 -2
- package/locales/fa-IR/chat.json +13 -0
- package/locales/fa-IR/common.json +1 -0
- package/locales/fa-IR/components.json +4 -0
- package/locales/fa-IR/file.json +2 -2
- package/locales/fr-FR/chat.json +13 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/components.json +4 -0
- package/locales/fr-FR/file.json +2 -2
- package/locales/it-IT/chat.json +13 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/components.json +4 -0
- package/locales/it-IT/file.json +2 -2
- package/locales/ja-JP/chat.json +13 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ja-JP/components.json +4 -0
- package/locales/ja-JP/file.json +2 -2
- package/locales/ko-KR/chat.json +13 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/components.json +4 -0
- package/locales/ko-KR/file.json +2 -2
- package/locales/nl-NL/chat.json +13 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/nl-NL/components.json +4 -0
- package/locales/nl-NL/file.json +2 -2
- package/locales/pl-PL/chat.json +13 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/components.json +4 -0
- package/locales/pl-PL/file.json +2 -2
- package/locales/pt-BR/chat.json +13 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/pt-BR/components.json +4 -0
- package/locales/pt-BR/file.json +2 -2
- package/locales/ru-RU/chat.json +13 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/components.json +4 -0
- package/locales/ru-RU/file.json +2 -2
- package/locales/tr-TR/chat.json +13 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/tr-TR/components.json +4 -0
- package/locales/tr-TR/file.json +2 -2
- package/locales/vi-VN/chat.json +13 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/components.json +4 -0
- package/locales/vi-VN/file.json +2 -2
- package/locales/zh-CN/chat.json +13 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-CN/components.json +4 -0
- package/locales/zh-CN/file.json +2 -2
- package/locales/zh-TW/chat.json +13 -0
- package/locales/zh-TW/common.json +1 -0
- package/locales/zh-TW/components.json +4 -0
- package/locales/zh-TW/file.json +2 -2
- package/next.config.ts +5 -6
- package/package.json +8 -2
- package/packages/context-engine/src/__tests__/pipeline.test.ts +7 -27
- package/packages/context-engine/src/pipeline.ts +5 -21
- package/packages/context-engine/src/types.ts +2 -2
- package/packages/database/src/models/__tests__/message.test.ts +200 -2
- package/packages/database/src/models/message.ts +13 -0
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.test.ts +313 -0
- package/packages/model-runtime/src/core/openaiCompatibleFactory/index.ts +21 -5
- package/packages/model-runtime/src/providers/azureai/index.test.ts +12 -2
- package/packages/model-runtime/src/providers/groq/index.test.ts +449 -0
- package/packages/model-runtime/src/providers/groq/index.ts +46 -0
- package/src/app/[variants]/(main)/_layout/Desktop/SideBar/TopActions.tsx +3 -2
- package/src/app/[variants]/(main)/chat/(workspace)/_layout/Desktop/ChatHeader/Tags/index.tsx +1 -1
- package/src/app/[variants]/(main)/files/(content)/@menu/features/KnowledgeBase/Item/index.tsx +10 -2
- package/src/features/ChatInput/InputEditor/index.tsx +2 -0
- package/src/features/Conversation/Messages/User/index.tsx +7 -17
- package/src/features/Conversation/components/ChatItem/ShareMessageModal/SharePdf/PdfPreview.tsx +361 -0
- package/src/features/Conversation/components/ChatItem/ShareMessageModal/SharePdf/index.tsx +119 -0
- package/src/features/Conversation/components/ChatItem/ShareMessageModal/SharePdf/style.ts +63 -0
- package/src/features/Conversation/components/ChatItem/ShareMessageModal/SharePdf/template.ts +24 -0
- package/src/features/Conversation/components/ChatItem/ShareMessageModal/SharePdf/usePdfGeneration.ts +93 -0
- package/src/features/Conversation/components/ShareMessageModal/ShareImage/Preview.tsx +1 -1
- package/src/features/Conversation/components/ShareMessageModal/index.tsx +39 -14
- package/src/features/FileManager/FileList/MasonryFileItem/MasonryItemWrapper.tsx +44 -0
- package/src/features/FileManager/FileList/MasonryFileItem/index.tsx +553 -0
- package/src/features/FileManager/FileList/MasonrySkeleton.tsx +57 -0
- package/src/features/FileManager/FileList/ToolBar/ViewSwitcher.tsx +45 -0
- package/src/features/FileManager/FileList/ToolBar/index.tsx +9 -1
- package/src/features/FileManager/FileList/index.tsx +83 -13
- package/src/features/FileManager/Header/FilesSearchBar.tsx +7 -2
- package/src/features/ShareModal/ShareImage/Preview.tsx +1 -1
- package/src/features/ShareModal/SharePdf/PdfPreview.tsx +361 -0
- package/src/features/ShareModal/SharePdf/index.tsx +194 -0
- package/src/features/ShareModal/SharePdf/usePdfGeneration.ts +90 -0
- package/src/features/ShareModal/index.tsx +40 -14
- package/src/features/ShareModal/style.ts +8 -5
- package/src/helpers/toolEngineering/index.ts +7 -1
- package/src/helpers/toolFilters.ts +35 -0
- package/src/libs/trpc/client/lambda.ts +7 -1
- package/src/locales/default/chat.ts +13 -0
- package/src/locales/default/common.ts +1 -0
- package/src/locales/default/components.ts +4 -0
- package/src/locales/default/file.ts +2 -2
- package/src/server/globalConfig/parseSystemAgent.ts +4 -2
- package/src/server/routers/lambda/exporter.ts +173 -3
- package/src/server/routers/lambda/message.ts +11 -0
- package/src/services/chat/contextEngineering.ts +1 -9
- package/src/store/agent/slices/chat/selectors/agent.ts +16 -6
- package/src/store/global/initialState.ts +2 -0
- package/src/store/tool/slices/builtin/selectors.ts +15 -5
|
@@ -1,4 +1,10 @@
|
|
|
1
|
+
import { marked } from 'marked';
|
|
2
|
+
import PDFDocument from 'pdfkit';
|
|
3
|
+
import { z } from 'zod';
|
|
4
|
+
|
|
1
5
|
import { DrizzleMigrationModel } from '@/database/models/drizzleMigration';
|
|
6
|
+
import { MessageModel } from '@/database/models/message';
|
|
7
|
+
import { SessionModel } from '@/database/models/session';
|
|
2
8
|
import { DataExporterRepos } from '@/database/repositories/dataExporter';
|
|
3
9
|
import { authedProcedure, router } from '@/libs/trpc/lambda';
|
|
4
10
|
import { serverDatabase } from '@/libs/trpc/lambda/middleware';
|
|
@@ -8,18 +14,182 @@ const exportProcedure = authedProcedure.use(serverDatabase).use(async (opts) =>
|
|
|
8
14
|
const { ctx } = opts;
|
|
9
15
|
const dataExporterRepos = new DataExporterRepos(ctx.serverDB, ctx.userId);
|
|
10
16
|
const drizzleMigration = new DrizzleMigrationModel(ctx.serverDB);
|
|
17
|
+
const messageModel = new MessageModel(ctx.serverDB, ctx.userId);
|
|
18
|
+
const sessionModel = new SessionModel(ctx.serverDB, ctx.userId);
|
|
11
19
|
|
|
12
20
|
return opts.next({
|
|
13
|
-
ctx: { dataExporterRepos, drizzleMigration },
|
|
21
|
+
ctx: { dataExporterRepos, drizzleMigration, messageModel, sessionModel },
|
|
14
22
|
});
|
|
15
23
|
});
|
|
16
24
|
|
|
25
|
+
|
|
26
|
+
const REGULAR_FONT_URL =
|
|
27
|
+
'https://cdn.jsdelivr.net/gh/adobe-fonts/source-han-sans@2.004R/OTF/SimplifiedChinese/SourceHanSansSC-Regular.otf';
|
|
28
|
+
|
|
29
|
+
let regularFontCache: Buffer | null = null;
|
|
30
|
+
|
|
31
|
+
const loadRegularFont = async (): Promise<Buffer> => {
|
|
32
|
+
if (regularFontCache) return regularFontCache;
|
|
33
|
+
|
|
34
|
+
const response = await fetch(REGULAR_FONT_URL);
|
|
35
|
+
if (!response.ok) {
|
|
36
|
+
throw new Error(`Failed to fetch font from CDN: ${response.status} ${response.statusText}`);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const fontBuffer = Buffer.from(await response.arrayBuffer());
|
|
40
|
+
regularFontCache = fontBuffer;
|
|
41
|
+
|
|
42
|
+
return fontBuffer;
|
|
43
|
+
};
|
|
44
|
+
|
|
45
|
+
const generatePdfFromMarkdown = async (
|
|
46
|
+
markdownContent: string,
|
|
47
|
+
title?: string,
|
|
48
|
+
): Promise<Buffer> => {
|
|
49
|
+
const regularFont = await loadRegularFont();
|
|
50
|
+
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
try {
|
|
53
|
+
const tokens = marked.lexer(markdownContent);
|
|
54
|
+
|
|
55
|
+
const doc = new PDFDocument({
|
|
56
|
+
bufferPages: true,
|
|
57
|
+
margins: {
|
|
58
|
+
bottom: 50,
|
|
59
|
+
left: 50,
|
|
60
|
+
right: 50,
|
|
61
|
+
top: 50,
|
|
62
|
+
},
|
|
63
|
+
size: 'A4',
|
|
64
|
+
});
|
|
65
|
+
|
|
66
|
+
const chunks: Buffer[] = [];
|
|
67
|
+
|
|
68
|
+
doc.registerFont('Regular', regularFont);
|
|
69
|
+
doc.font('Regular');
|
|
70
|
+
|
|
71
|
+
doc.on('data', (chunk: Buffer) => chunks.push(chunk));
|
|
72
|
+
doc.on('end', () => {
|
|
73
|
+
const pdfBuffer = Buffer.concat(chunks);
|
|
74
|
+
resolve(pdfBuffer);
|
|
75
|
+
});
|
|
76
|
+
doc.on('error', reject);
|
|
77
|
+
|
|
78
|
+
if (title) {
|
|
79
|
+
doc.fontSize(20).text(title, { align: 'center' });
|
|
80
|
+
}
|
|
81
|
+
doc.moveDown(2);
|
|
82
|
+
|
|
83
|
+
let currentY = doc.y;
|
|
84
|
+
|
|
85
|
+
for (const token of tokens) {
|
|
86
|
+
if (currentY > 700) {
|
|
87
|
+
doc.addPage();
|
|
88
|
+
currentY = 50;
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
switch (token.type) {
|
|
92
|
+
case 'heading': {
|
|
93
|
+
const headingSize = Math.max(16 - (token.depth - 1) * 2, 12);
|
|
94
|
+
doc.fontSize(headingSize).fillColor('#222').text(token.text, { continued: false });
|
|
95
|
+
doc.moveDown(0.5);
|
|
96
|
+
break;
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
case 'paragraph': {
|
|
100
|
+
doc.fontSize(12).fillColor('#333').text(token.text, { align: 'left', lineGap: 2 });
|
|
101
|
+
doc.moveDown(1);
|
|
102
|
+
break;
|
|
103
|
+
}
|
|
104
|
+
|
|
105
|
+
case 'list': {
|
|
106
|
+
for (const item of token.items) {
|
|
107
|
+
doc.fontSize(12).fillColor('#333').text(`• ${item.text}`, { indent: 20, lineGap: 2 });
|
|
108
|
+
}
|
|
109
|
+
doc.moveDown(1);
|
|
110
|
+
break;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
case 'blockquote': {
|
|
114
|
+
doc.fontSize(12).fillColor('#666').text(token.text, { indent: 20, lineGap: 2 });
|
|
115
|
+
doc.moveDown(1);
|
|
116
|
+
break;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
case 'code': {
|
|
120
|
+
doc.fontSize(10).fillColor('#333').text(token.text, {
|
|
121
|
+
continued: false,
|
|
122
|
+
indent: 20,
|
|
123
|
+
lineGap: 1,
|
|
124
|
+
});
|
|
125
|
+
doc.moveDown(1);
|
|
126
|
+
break;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
case 'hr': {
|
|
130
|
+
doc.moveTo(50, doc.y).lineTo(545, doc.y).stroke();
|
|
131
|
+
doc.moveDown(1);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
default: {
|
|
136
|
+
if ('text' in token && token.text) {
|
|
137
|
+
doc.fontSize(12).fillColor('#333').text(token.text, { align: 'left', lineGap: 2 });
|
|
138
|
+
doc.moveDown(1);
|
|
139
|
+
}
|
|
140
|
+
break;
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
currentY = doc.y;
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
const pages = doc.bufferedPageRange();
|
|
148
|
+
for (let i = 0; i < pages.count; i++) {
|
|
149
|
+
doc.switchToPage(i);
|
|
150
|
+
doc
|
|
151
|
+
.fontSize(8)
|
|
152
|
+
.fillColor('#666')
|
|
153
|
+
.text(`Page ${i + 1} of ${pages.count}`, 50, 750, {
|
|
154
|
+
align: 'center',
|
|
155
|
+
width: 495,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// 完成文档
|
|
160
|
+
doc.end();
|
|
161
|
+
} catch (error) {
|
|
162
|
+
reject(
|
|
163
|
+
new Error(
|
|
164
|
+
`PDFKit PDF generation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,
|
|
165
|
+
),
|
|
166
|
+
);
|
|
167
|
+
}
|
|
168
|
+
});
|
|
169
|
+
};
|
|
170
|
+
|
|
17
171
|
export const exporterRouter = router({
|
|
18
172
|
exportData: exportProcedure.mutation(async ({ ctx }): Promise<ExportDatabaseData> => {
|
|
19
173
|
const data = await ctx.dataExporterRepos.export(5);
|
|
20
|
-
|
|
21
174
|
const schemaHash = await ctx.drizzleMigration.getLatestMigrationHash();
|
|
22
|
-
|
|
23
175
|
return { data, schemaHash };
|
|
24
176
|
}),
|
|
177
|
+
|
|
178
|
+
exportPdf: exportProcedure
|
|
179
|
+
.input(
|
|
180
|
+
z.object({
|
|
181
|
+
content: z.string(),
|
|
182
|
+
sessionId: z.string(),
|
|
183
|
+
title: z.string().optional(),
|
|
184
|
+
topicId: z.string().optional(),
|
|
185
|
+
}),
|
|
186
|
+
)
|
|
187
|
+
.mutation(async ({ input }) => {
|
|
188
|
+
const { content, title } = input;
|
|
189
|
+
const pdfBuffer = await generatePdfFromMarkdown(content, title);
|
|
190
|
+
return {
|
|
191
|
+
filename: `${title}.pdf`,
|
|
192
|
+
pdf: pdfBuffer.toString('base64'),
|
|
193
|
+
};
|
|
194
|
+
}),
|
|
25
195
|
});
|
|
@@ -198,6 +198,17 @@ export const messageRouter = router({
|
|
|
198
198
|
await ctx.messageModel.updateMessageRAG(input.id, input.value);
|
|
199
199
|
}),
|
|
200
200
|
|
|
201
|
+
updateMetadata: messageProcedure
|
|
202
|
+
.input(
|
|
203
|
+
z.object({
|
|
204
|
+
id: z.string(),
|
|
205
|
+
value: z.object({}).passthrough(),
|
|
206
|
+
}),
|
|
207
|
+
)
|
|
208
|
+
.mutation(async ({ input, ctx }) => {
|
|
209
|
+
return ctx.messageModel.updateMetadata(input.id, input.value);
|
|
210
|
+
}),
|
|
211
|
+
|
|
201
212
|
updatePluginError: messageProcedure
|
|
202
213
|
.input(
|
|
203
214
|
z.object({
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { INBOX_GUIDE_SYSTEMROLE, INBOX_SESSION_ID, isDesktop, isServerMode } from '@lobechat/const';
|
|
2
2
|
import {
|
|
3
|
-
type AgentState,
|
|
4
3
|
ContextEngine,
|
|
5
4
|
HistorySummaryProvider,
|
|
6
5
|
HistoryTruncateProcessor,
|
|
@@ -122,14 +121,7 @@ export const contextEngineering = async ({
|
|
|
122
121
|
],
|
|
123
122
|
});
|
|
124
123
|
|
|
125
|
-
const
|
|
126
|
-
|
|
127
|
-
const result = await pipeline.process({
|
|
128
|
-
initialState,
|
|
129
|
-
maxTokens: 10_000_000,
|
|
130
|
-
messages,
|
|
131
|
-
model,
|
|
132
|
-
});
|
|
124
|
+
const result = await pipeline.process({ messages });
|
|
133
125
|
|
|
134
126
|
return result.messages;
|
|
135
127
|
};
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import { VoiceList } from '@lobehub/tts';
|
|
2
|
-
|
|
3
|
-
import { INBOX_SESSION_ID } from '@/const/session';
|
|
4
1
|
import {
|
|
5
2
|
DEFAULT_AGENT_CONFIG,
|
|
6
3
|
DEFAULT_MODEL,
|
|
7
4
|
DEFAULT_PROVIDER,
|
|
8
5
|
DEFAUTT_AGENT_TTS_CONFIG,
|
|
9
|
-
|
|
6
|
+
INBOX_SESSION_ID,
|
|
7
|
+
} from '@lobechat/const';
|
|
8
|
+
import { KnowledgeItem, KnowledgeType, LobeAgentConfig, LobeAgentTTSConfig } from '@lobechat/types';
|
|
9
|
+
import { VoiceList } from '@lobehub/tts';
|
|
10
|
+
|
|
10
11
|
import { DEFAULT_OPENING_QUESTIONS } from '@/features/AgentSetting/store/selectors';
|
|
12
|
+
import { filterToolIds } from '@/helpers/toolFilters';
|
|
11
13
|
import { AgentStoreState } from '@/store/agent/initialState';
|
|
12
|
-
import { LobeAgentConfig, LobeAgentTTSConfig } from '@/types/agent';
|
|
13
|
-
import { KnowledgeItem, KnowledgeType } from '@/types/knowledgeBase';
|
|
14
14
|
import { merge } from '@/utils/merge';
|
|
15
15
|
|
|
16
16
|
const isInboxSession = (s: AgentStoreState) => s.activeId === INBOX_SESSION_ID;
|
|
@@ -68,6 +68,15 @@ const currentAgentPlugins = (s: AgentStoreState) => {
|
|
|
68
68
|
return config?.plugins || [];
|
|
69
69
|
};
|
|
70
70
|
|
|
71
|
+
/**
|
|
72
|
+
* Get displayable agent plugins by filtering out platform-specific tools
|
|
73
|
+
* that shouldn't be shown in the current environment
|
|
74
|
+
*/
|
|
75
|
+
const displayableAgentPlugins = (s: AgentStoreState) => {
|
|
76
|
+
const plugins = currentAgentPlugins(s);
|
|
77
|
+
return filterToolIds(plugins);
|
|
78
|
+
};
|
|
79
|
+
|
|
71
80
|
const currentAgentKnowledgeBases = (s: AgentStoreState) => {
|
|
72
81
|
const config = currentAgentConfig(s);
|
|
73
82
|
|
|
@@ -172,6 +181,7 @@ export const agentSelectors = {
|
|
|
172
181
|
currentAgentTTSVoice,
|
|
173
182
|
currentEnabledKnowledge,
|
|
174
183
|
currentKnowledgeIds,
|
|
184
|
+
displayableAgentPlugins,
|
|
175
185
|
getAgentConfigByAgentId,
|
|
176
186
|
getAgentConfigById,
|
|
177
187
|
hasEnabledKnowledge,
|
|
@@ -57,6 +57,7 @@ export interface SystemStatus {
|
|
|
57
57
|
expandInputActionbar?: boolean;
|
|
58
58
|
// which sessionGroup should expand
|
|
59
59
|
expandSessionGroupKeys: string[];
|
|
60
|
+
fileManagerViewMode?: 'list' | 'masonry';
|
|
60
61
|
filePanelWidth: number;
|
|
61
62
|
hideGemini2_5FlashImagePreviewChineseWarning?: boolean;
|
|
62
63
|
hidePWAInstaller?: boolean;
|
|
@@ -125,6 +126,7 @@ export const INITIAL_STATUS = {
|
|
|
125
126
|
chatInputHeight: 64,
|
|
126
127
|
expandInputActionbar: true,
|
|
127
128
|
expandSessionGroupKeys: [SessionDefaultGroup.Pinned, SessionDefaultGroup.Default],
|
|
129
|
+
fileManagerViewMode: 'list' as const,
|
|
128
130
|
filePanelWidth: 320,
|
|
129
131
|
hideGemini2_5FlashImagePreviewChineseWarning: false,
|
|
130
132
|
hidePWAInstaller: false,
|
|
@@ -1,5 +1,7 @@
|
|
|
1
|
+
import { LobeToolMeta } from '@lobechat/types';
|
|
2
|
+
|
|
3
|
+
import { shouldEnableTool } from '@/helpers/toolFilters';
|
|
1
4
|
import { DalleManifest } from '@/tools/dalle';
|
|
2
|
-
import { LobeToolMeta } from '@/types/tool/tool';
|
|
3
5
|
|
|
4
6
|
import type { ToolStoreState } from '../../initialState';
|
|
5
7
|
|
|
@@ -7,10 +9,18 @@ const metaList =
|
|
|
7
9
|
(showDalle?: boolean) =>
|
|
8
10
|
(s: ToolStoreState): LobeToolMeta[] =>
|
|
9
11
|
s.builtinTools
|
|
10
|
-
.filter(
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
12
|
+
.filter((item) => {
|
|
13
|
+
// Filter hidden tools
|
|
14
|
+
if (item.hidden) return false;
|
|
15
|
+
|
|
16
|
+
// Filter Dalle if not enabled
|
|
17
|
+
if (!showDalle && item.identifier === DalleManifest.identifier) return false;
|
|
18
|
+
|
|
19
|
+
// Filter platform-specific tools (e.g., LocalSystem desktop-only)
|
|
20
|
+
if (!shouldEnableTool(item.identifier)) return false;
|
|
21
|
+
|
|
22
|
+
return true;
|
|
23
|
+
})
|
|
14
24
|
.map((t) => ({
|
|
15
25
|
author: 'LobeHub',
|
|
16
26
|
identifier: t.identifier,
|