mirror of
https://github.com/lobehub/lobe-chat.git
synced 2025-12-20 01:12:52 +08:00
💄 style: improve styles and fix tools calling condition (#9591)
* clean and refactor * improve * update * update * fix tools engine
This commit is contained in:
@@ -3,8 +3,8 @@
|
||||
"title": "النموذج"
|
||||
},
|
||||
"agentDefaultMessage": "مرحبًا، أنا **{{name}}**، يمكنك بدء المحادثة معي على الفور، أو يمكنك الذهاب إلى [إعدادات المساعد]({{url}}) لإكمال معلوماتي.",
|
||||
"agentDefaultMessageWithSystemRole": "مرحبًا، أنا **{{name}}**، {{systemRole}}، دعنا نبدأ الدردشة!",
|
||||
"agentDefaultMessageWithoutEdit": "مرحبًا، أنا **{{name}}**، دعنا نبدأ المحادثة!",
|
||||
"agentDefaultMessageWithSystemRole": "مرحبًا، أنا **{{name}}**، كيف يمكنني مساعدتك؟",
|
||||
"agentDefaultMessageWithoutEdit": "مرحبًا، أنا **{{name}}**، كيف يمكنني مساعدتك؟",
|
||||
"agents": "مساعد",
|
||||
"artifact": {
|
||||
"generating": "جاري الإنشاء",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Модел"
|
||||
},
|
||||
"agentDefaultMessage": "Здравейте, аз съм **{{name}}**, можете да започнете разговор с мен веднага или да отидете на [Настройки на асистента]({{url}}), за да попълните информацията ми.",
|
||||
"agentDefaultMessageWithSystemRole": "Здравей, аз съм **{{name}}**, {{systemRole}}. Нека започнем да чатим!",
|
||||
"agentDefaultMessageWithoutEdit": "Здравей, аз съм **{{name}}** и нека започнем разговора!",
|
||||
"agentDefaultMessageWithSystemRole": "Здравейте, аз съм **{{name}}**. Как мога да ви помогна?",
|
||||
"agentDefaultMessageWithoutEdit": "Здравейте, аз съм **{{name}}**. Как мога да ви помогна?",
|
||||
"agents": "Асистент",
|
||||
"artifact": {
|
||||
"generating": "Генериране",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Modell"
|
||||
},
|
||||
"agentDefaultMessage": "Hallo, ich bin **{{name}}**. Du kannst sofort mit mir sprechen oder zu den [Assistenteneinstellungen]({{url}}) gehen, um meine Informationen zu vervollständigen.",
|
||||
"agentDefaultMessageWithSystemRole": "Hallo, ich bin **{{name}}**, {{systemRole}}. Lass uns chatten!",
|
||||
"agentDefaultMessageWithoutEdit": "Hallo, ich bin **{{name}}**. Lassen Sie uns ins Gespräch kommen!",
|
||||
"agentDefaultMessageWithSystemRole": "Hallo, ich bin **{{name}}**. Wie kann ich Ihnen behilflich sein?",
|
||||
"agentDefaultMessageWithoutEdit": "Hallo, ich bin **{{name}}**. Wie kann ich Ihnen behilflich sein?",
|
||||
"agents": "Assistent",
|
||||
"artifact": {
|
||||
"generating": "Wird generiert",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Model"
|
||||
},
|
||||
"agentDefaultMessage": "Hello, I am **{{name}}**. You can start a conversation with me right away, or you can go to [Assistant Settings]({{url}}) to complete my information.",
|
||||
"agentDefaultMessageWithSystemRole": "Hello, I'm **{{name}}**, {{systemRole}}. Let's start chatting!",
|
||||
"agentDefaultMessageWithoutEdit": "Hello, I'm **{{name}}**, let's start chatting!",
|
||||
"agentDefaultMessageWithSystemRole": "Hello, I am **{{name}}**. How can I assist you today?",
|
||||
"agentDefaultMessageWithoutEdit": "Hello, I am **{{name}}**. How can I assist you today?",
|
||||
"agents": "Assistants",
|
||||
"artifact": {
|
||||
"generating": "Generating",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Cambiar modelo"
|
||||
},
|
||||
"agentDefaultMessage": "Hola, soy **{{name}}**. Puedes comenzar a hablar conmigo de inmediato o ir a [Configuración del asistente]({{url}}) para completar mi información.",
|
||||
"agentDefaultMessageWithSystemRole": "Hola, soy **{{name}}**, {{systemRole}}, ¡comencemos a chatear!",
|
||||
"agentDefaultMessageWithoutEdit": "¡Hola, soy **{{name}}**! Comencemos nuestra conversación.",
|
||||
"agentDefaultMessageWithSystemRole": "Hola, soy **{{name}}**, ¿en qué puedo ayudarte?",
|
||||
"agentDefaultMessageWithoutEdit": "Hola, soy **{{name}}**, ¿en qué puedo ayudarte?",
|
||||
"agents": "Asistente",
|
||||
"artifact": {
|
||||
"generating": "Generando",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "مدل"
|
||||
},
|
||||
"agentDefaultMessage": "سلام، من **{{name}}** هستم. میتوانید همین حالا با من گفتگو را شروع کنید یا به [تنظیمات دستیار]({{url}}) بروید و اطلاعات من را تکمیل کنید.",
|
||||
"agentDefaultMessageWithSystemRole": "سلام، من **{{name}}** هستم، {{systemRole}}، بیایید گفتگو را شروع کنیم!",
|
||||
"agentDefaultMessageWithoutEdit": "سلام، من **{{name}}** هستم، بیایید گفتگو را شروع کنیم!",
|
||||
"agentDefaultMessageWithSystemRole": "سلام، من **{{name}}** هستم، چگونه میتوانم به شما کمک کنم؟",
|
||||
"agentDefaultMessageWithoutEdit": "سلام، من **{{name}}** هستم، چگونه میتوانم به شما کمک کنم؟",
|
||||
"agents": "دستیار",
|
||||
"artifact": {
|
||||
"generating": "در حال تولید",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Modèle"
|
||||
},
|
||||
"agentDefaultMessage": "Bonjour, je suis **{{name}}**, vous pouvez commencer à discuter avec moi immédiatement ou vous rendre dans [Paramètres de l'assistant]({{url}}) pour compléter mes informations.",
|
||||
"agentDefaultMessageWithSystemRole": "Bonjour, je suis **{{name}}**, {{systemRole}}. Commençons la conversation !",
|
||||
"agentDefaultMessageWithoutEdit": "Bonjour, je suis **{{name}}**. Commençons notre conversation !",
|
||||
"agentDefaultMessageWithSystemRole": "Bonjour, je suis **{{name}}**, comment puis-je vous aider ?",
|
||||
"agentDefaultMessageWithoutEdit": "Bonjour, je suis **{{name}}**, comment puis-je vous aider ?",
|
||||
"agents": "Assistant",
|
||||
"artifact": {
|
||||
"generating": "Génération en cours",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Modelli"
|
||||
},
|
||||
"agentDefaultMessage": "Ciao, sono **{{name}}**, puoi iniziare subito a parlare con me oppure andare su [Impostazioni assistente]({{url}}) per completare le mie informazioni.",
|
||||
"agentDefaultMessageWithSystemRole": "Ciao, sono **{{name}}**, {{systemRole}}, iniziamo a chattare!",
|
||||
"agentDefaultMessageWithoutEdit": "Ciao, sono **{{name}}**. Cominciamo a chiacchierare!",
|
||||
"agentDefaultMessageWithSystemRole": "Ciao, sono **{{name}}**, come posso aiutarti?",
|
||||
"agentDefaultMessageWithoutEdit": "Ciao, sono **{{name}}**, come posso aiutarti?",
|
||||
"agents": "Assistente",
|
||||
"artifact": {
|
||||
"generating": "Generazione in corso",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "モデル"
|
||||
},
|
||||
"agentDefaultMessage": "こんにちは、私は **{{name}}** です。すぐに私と会話を始めることもできますし、[アシスタント設定]({{url}}) に行って私の情報を充実させることもできます。",
|
||||
"agentDefaultMessageWithSystemRole": "こんにちは、私は **{{name}}** です、{{systemRole}}、さあ、チャットを始めましょう!",
|
||||
"agentDefaultMessageWithoutEdit": "こんにちは、私は**{{name}}**です。会話しましょう!",
|
||||
"agentDefaultMessageWithSystemRole": "こんにちは、私は **{{name}}** です。何かお手伝いできることはありますか?",
|
||||
"agentDefaultMessageWithoutEdit": "こんにちは、私は **{{name}}** です。何かお手伝いできることはありますか?",
|
||||
"agents": "エージェント",
|
||||
"artifact": {
|
||||
"generating": "生成中",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "모델"
|
||||
},
|
||||
"agentDefaultMessage": "안녕하세요, 저는 **{{name}}**입니다. 지금 바로 저와 대화를 시작하시거나 [도우미 설정]({{url}})으로 가셔서 제 정보를 완성하실 수 있습니다.",
|
||||
"agentDefaultMessageWithSystemRole": "안녕하세요, 저는 **{{name}}**입니다. {{systemRole}}입니다. 대화를 시작해 봅시다!",
|
||||
"agentDefaultMessageWithoutEdit": "안녕하세요, 저는 **{{name}}**입니다. 대화를 시작해보세요!",
|
||||
"agentDefaultMessageWithSystemRole": "안녕하세요, 저는 **{{name}}**입니다. 무엇을 도와드릴까요?",
|
||||
"agentDefaultMessageWithoutEdit": "안녕하세요, 저는 **{{name}}**입니다. 무엇을 도와드릴까요?",
|
||||
"agents": "도우미",
|
||||
"artifact": {
|
||||
"generating": "생성 중",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Modelen"
|
||||
},
|
||||
"agentDefaultMessage": "Hallo, ik ben **{{name}}**. Je kunt meteen met me beginnen praten, of je kunt naar [Assistentinstellingen]({{url}}) gaan om mijn informatie aan te vullen.",
|
||||
"agentDefaultMessageWithSystemRole": "Hallo, ik ben **{{name}}**, {{systemRole}}, laten we beginnen met praten!",
|
||||
"agentDefaultMessageWithoutEdit": "Hallo, ik ben **{{name}}**. Laten we beginnen met een gesprek!",
|
||||
"agentDefaultMessageWithSystemRole": "Hallo, ik ben **{{name}}**. Waarmee kan ik u van dienst zijn?",
|
||||
"agentDefaultMessageWithoutEdit": "Hallo, ik ben **{{name}}**. Waarmee kan ik u van dienst zijn?",
|
||||
"agents": "Assistent",
|
||||
"artifact": {
|
||||
"generating": "Genereren",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Przełącz model"
|
||||
},
|
||||
"agentDefaultMessage": "Cześć, jestem **{{name}}**, możesz od razu rozpocząć ze mną rozmowę lub przejść do [ustawień asystenta]({{url}}), aby uzupełnić moje informacje.",
|
||||
"agentDefaultMessageWithSystemRole": "Cześć, jestem **{{name}}**, {{systemRole}}, zacznijmy rozmowę!",
|
||||
"agentDefaultMessageWithoutEdit": "Cześć, jestem **{{name}}**. Zacznijmy rozmowę!",
|
||||
"agentDefaultMessageWithSystemRole": "Cześć, jestem **{{name}}**. W czym mogę pomóc?",
|
||||
"agentDefaultMessageWithoutEdit": "Cześć, jestem **{{name}}**. W czym mogę pomóc?",
|
||||
"agents": "Asystent",
|
||||
"artifact": {
|
||||
"generating": "Generowanie",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Modelo"
|
||||
},
|
||||
"agentDefaultMessage": "Olá, eu sou **{{name}}**, você pode começar a conversar comigo agora ou ir para [Configurações do Assistente]({{url}}) para completar minhas informações.",
|
||||
"agentDefaultMessageWithSystemRole": "Olá, eu sou **{{name}}**, {{systemRole}}, vamos conversar!",
|
||||
"agentDefaultMessageWithoutEdit": "Olá, sou o **{{name}}**, vamos começar a conversa!",
|
||||
"agentDefaultMessageWithSystemRole": "Olá, eu sou **{{name}}**. Como posso ajudar você?",
|
||||
"agentDefaultMessageWithoutEdit": "Olá, eu sou **{{name}}**. Como posso ajudar você?",
|
||||
"agents": "Assistente",
|
||||
"artifact": {
|
||||
"generating": "Gerando",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Модель"
|
||||
},
|
||||
"agentDefaultMessage": "Здравствуйте, я **{{name}}**. Вы можете сразу начать со мной разговор или перейти в [настройки помощника]({{url}}), чтобы дополнить мою информацию.",
|
||||
"agentDefaultMessageWithSystemRole": "Привет, я **{{name}}**, {{systemRole}}. Давай начнем разговор!",
|
||||
"agentDefaultMessageWithoutEdit": "Привет, я **{{name}}**, давай начнём разговор!",
|
||||
"agentDefaultMessageWithSystemRole": "Здравствуйте, я **{{name}}**, чем могу помочь?",
|
||||
"agentDefaultMessageWithoutEdit": "Здравствуйте, я **{{name}}**, чем могу помочь?",
|
||||
"agents": "Ассистент",
|
||||
"artifact": {
|
||||
"generating": "Генерация",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Model Değiştir"
|
||||
},
|
||||
"agentDefaultMessage": "Merhaba, ben **{{name}}**. Hemen benimle konuşmaya başlayabilir veya [Asistan Ayarları]({{url}}) sayfasına giderek bilgilerimi güncelleyebilirsin.",
|
||||
"agentDefaultMessageWithSystemRole": "Merhaba, Ben **{{name}}**, {{systemRole}}. Hemen sohbet etmeye başlayalım!",
|
||||
"agentDefaultMessageWithoutEdit": "Merhaba, ben **{{name}}**. Konuşmaya başlayalım!",
|
||||
"agentDefaultMessageWithSystemRole": "Merhaba, ben **{{name}}**. Size nasıl yardımcı olabilirim?",
|
||||
"agentDefaultMessageWithoutEdit": "Merhaba, ben **{{name}}**. Size nasıl yardımcı olabilirim?",
|
||||
"agents": "Asistan",
|
||||
"artifact": {
|
||||
"generating": "Üretiliyor",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "Mô hình"
|
||||
},
|
||||
"agentDefaultMessage": "Xin chào, tôi là **{{name}}**, bạn có thể bắt đầu trò chuyện với tôi ngay bây giờ, hoặc bạn có thể đến [Cài đặt trợ lý]({{url}}) để hoàn thiện thông tin của tôi.",
|
||||
"agentDefaultMessageWithSystemRole": "Xin chào, tôi là **{{name}}**, {{systemRole}}. Hãy bắt đầu trò chuyện ngay!",
|
||||
"agentDefaultMessageWithoutEdit": "Xin chào, tôi là **{{name}}**, chúng ta hãy bắt đầu trò chuyện nào!",
|
||||
"agentDefaultMessageWithSystemRole": "Xin chào, tôi là **{{name}}**, tôi có thể giúp gì cho bạn?",
|
||||
"agentDefaultMessageWithoutEdit": "Xin chào, tôi là **{{name}}**, tôi có thể giúp gì cho bạn?",
|
||||
"agents": "Trợ lý",
|
||||
"artifact": {
|
||||
"generating": "Đang tạo",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "模型"
|
||||
},
|
||||
"agentDefaultMessage": "你好,我是 **{{name}}**,你可以立即与我开始对话,也可以前往 [助手设置]({{url}}) 完善我的信息。",
|
||||
"agentDefaultMessageWithSystemRole": "你好,我是 **{{name}}**,{{systemRole}},让我们开始对话吧!",
|
||||
"agentDefaultMessageWithoutEdit": "你好,我是 **{{name}}**,让我们开始对话吧!",
|
||||
"agentDefaultMessageWithSystemRole": "你好,我是 **{{name}}**,有什么我可以帮忙的吗?",
|
||||
"agentDefaultMessageWithoutEdit": "你好,我是 **{{name}}**,有什么我可以帮忙的吗?",
|
||||
"agents": "助手",
|
||||
"artifact": {
|
||||
"generating": "生成中",
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
"title": "模型"
|
||||
},
|
||||
"agentDefaultMessage": "你好,我是 **{{name}}**,你可以立即與我開始對話,也可以前往 [助手設定]({{url}}) 完善我的資訊。",
|
||||
"agentDefaultMessageWithSystemRole": "你好,我是 **{{name}}**,{{systemRole}},讓我們開始對話吧!",
|
||||
"agentDefaultMessageWithoutEdit": "你好,我是 **{{name}}**,讓我們開始對話吧!",
|
||||
"agentDefaultMessageWithSystemRole": "你好,我是 **{{name}}**,有什麼我可以幫忙的嗎?",
|
||||
"agentDefaultMessageWithoutEdit": "你好,我是 **{{name}}**,有什麼我可以幫忙的嗎?",
|
||||
"agents": "助手",
|
||||
"artifact": {
|
||||
"generating": "生成中",
|
||||
|
||||
@@ -250,17 +250,16 @@ const nextConfig: NextConfig = {
|
||||
// permanent: true,
|
||||
// source: '/settings',
|
||||
// },
|
||||
{
|
||||
destination: '/chat',
|
||||
permanent: false,
|
||||
source: '/',
|
||||
},
|
||||
{
|
||||
destination: '/chat',
|
||||
permanent: true,
|
||||
source: '/welcome',
|
||||
},
|
||||
// TODO: 等 V2 做强制跳转吧
|
||||
// {
|
||||
// destination: '/settings/provider/volcengine',
|
||||
// permanent: true,
|
||||
// source: '/settings/provider/doubao',
|
||||
// },
|
||||
// we need back /repos url in the further
|
||||
{
|
||||
destination: '/files',
|
||||
|
||||
@@ -107,28 +107,33 @@ export class ToolsEngine {
|
||||
this.defaultToolIds.length,
|
||||
);
|
||||
|
||||
// Filter and validate plugins
|
||||
// Check if model supports Function Calling
|
||||
const supportsFunctionCall = this.checkFunctionCallSupport(model, provider);
|
||||
|
||||
// Filter and validate plugins with FC support information
|
||||
const { enabledManifests, filteredPlugins } = this.filterEnabledPlugins(
|
||||
allToolIds,
|
||||
model,
|
||||
provider,
|
||||
context,
|
||||
supportsFunctionCall,
|
||||
);
|
||||
|
||||
// Convert to UniformTool format
|
||||
const tools = this.convertManifestsToTools(enabledManifests);
|
||||
// Convert to UniformTool format only if there are enabled manifests
|
||||
const tools =
|
||||
enabledManifests.length > 0 ? this.convertManifestsToTools(enabledManifests) : undefined;
|
||||
|
||||
log(
|
||||
'Generated detailed result: enabled=%d, filtered=%d, tools=%d',
|
||||
enabledManifests.length,
|
||||
filteredPlugins.length,
|
||||
tools.length,
|
||||
tools?.length ?? 0,
|
||||
);
|
||||
|
||||
return {
|
||||
enabledToolIds: enabledManifests.map((m) => m.identifier),
|
||||
filteredTools: filteredPlugins,
|
||||
tools: tools.length > 0 ? tools : undefined,
|
||||
tools,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -155,6 +160,7 @@ export class ToolsEngine {
|
||||
model: string,
|
||||
provider: string,
|
||||
context?: ToolsGenerationContext,
|
||||
supportsFunctionCall?: boolean,
|
||||
): {
|
||||
enabledManifests: LobeChatPluginManifest[];
|
||||
filteredPlugins: Array<{
|
||||
@@ -170,6 +176,22 @@ export class ToolsEngine {
|
||||
|
||||
log('Filtering plugins: %o', pluginIds);
|
||||
|
||||
// If function calling is not supported, filter all plugins as incompatible
|
||||
if (supportsFunctionCall === false) {
|
||||
for (const pluginId of pluginIds) {
|
||||
const manifest = this.manifestSchemas.get(pluginId);
|
||||
if (!manifest) {
|
||||
log('Plugin not found: %s', pluginId);
|
||||
filteredPlugins.push({ id: pluginId, reason: 'not_found' });
|
||||
} else {
|
||||
log('Plugin incompatible (no FC support): %s', pluginId);
|
||||
filteredPlugins.push({ id: pluginId, reason: 'incompatible' });
|
||||
}
|
||||
}
|
||||
log('Filtering complete: enabled=%d, filtered=%d', 0, filteredPlugins.length);
|
||||
return { enabledManifests, filteredPlugins };
|
||||
}
|
||||
|
||||
for (const pluginId of pluginIds) {
|
||||
const manifest = this.manifestSchemas.get(pluginId);
|
||||
|
||||
|
||||
@@ -206,6 +206,95 @@ describe('ToolsEngine', () => {
|
||||
{ id: 'non-existent', reason: 'not_found' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should filter all plugins as incompatible when function calling is not supported', () => {
|
||||
const mockFunctionCallChecker = vi.fn().mockReturnValue(false);
|
||||
const engine = new ToolsEngine({
|
||||
manifestSchemas: [mockWebBrowsingManifest, mockDalleManifest],
|
||||
functionCallChecker: mockFunctionCallChecker,
|
||||
});
|
||||
|
||||
const result = engine.generateToolsDetailed({
|
||||
toolIds: ['lobe-web-browsing', 'dalle'],
|
||||
model: 'gpt-5-chat-latest',
|
||||
provider: 'openai',
|
||||
});
|
||||
|
||||
expect(mockFunctionCallChecker).toHaveBeenCalledWith('gpt-5-chat-latest', 'openai');
|
||||
expect(result.tools).toBeUndefined();
|
||||
expect(result.enabledToolIds).toEqual([]);
|
||||
expect(result.filteredTools).toEqual([
|
||||
{ id: 'lobe-web-browsing', reason: 'incompatible' },
|
||||
{ id: 'dalle', reason: 'incompatible' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should combine incompatible and not_found reasons when FC is not supported', () => {
|
||||
const engine = new ToolsEngine({
|
||||
manifestSchemas: [mockWebBrowsingManifest],
|
||||
functionCallChecker: () => false,
|
||||
});
|
||||
|
||||
const result = engine.generateToolsDetailed({
|
||||
toolIds: ['lobe-web-browsing', 'non-existent', 'dalle'],
|
||||
model: 'gpt-5-chat-latest',
|
||||
provider: 'openai',
|
||||
});
|
||||
|
||||
expect(result.tools).toBeUndefined();
|
||||
expect(result.enabledToolIds).toEqual([]);
|
||||
expect(result.filteredTools).toEqual([
|
||||
{ id: 'lobe-web-browsing', reason: 'incompatible' },
|
||||
{ id: 'non-existent', reason: 'not_found' },
|
||||
{ id: 'dalle', reason: 'not_found' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should still call enableChecker when FC is supported', () => {
|
||||
const mockEnableChecker = vi.fn().mockReturnValue(false);
|
||||
const engine = new ToolsEngine({
|
||||
manifestSchemas: [mockWebBrowsingManifest, mockDalleManifest],
|
||||
enableChecker: mockEnableChecker,
|
||||
functionCallChecker: () => true,
|
||||
});
|
||||
|
||||
const result = engine.generateToolsDetailed({
|
||||
toolIds: ['lobe-web-browsing', 'dalle'],
|
||||
model: 'gpt-4',
|
||||
provider: 'openai',
|
||||
});
|
||||
|
||||
expect(mockEnableChecker).toHaveBeenCalledTimes(2);
|
||||
expect(result.tools).toBeUndefined();
|
||||
expect(result.enabledToolIds).toEqual([]);
|
||||
expect(result.filteredTools).toEqual([
|
||||
{ id: 'lobe-web-browsing', reason: 'disabled' },
|
||||
{ id: 'dalle', reason: 'disabled' },
|
||||
]);
|
||||
});
|
||||
|
||||
it('should not call enableChecker when FC is not supported', () => {
|
||||
const mockEnableChecker = vi.fn().mockReturnValue(true);
|
||||
const engine = new ToolsEngine({
|
||||
manifestSchemas: [mockWebBrowsingManifest, mockDalleManifest],
|
||||
enableChecker: mockEnableChecker,
|
||||
functionCallChecker: () => false,
|
||||
});
|
||||
|
||||
const result = engine.generateToolsDetailed({
|
||||
toolIds: ['lobe-web-browsing', 'dalle'],
|
||||
model: 'gpt-5-chat-latest',
|
||||
provider: 'openai',
|
||||
});
|
||||
|
||||
expect(mockEnableChecker).not.toHaveBeenCalled();
|
||||
expect(result.tools).toBeUndefined();
|
||||
expect(result.enabledToolIds).toEqual([]);
|
||||
expect(result.filteredTools).toEqual([
|
||||
{ id: 'lobe-web-browsing', reason: 'incompatible' },
|
||||
{ id: 'dalle', reason: 'incompatible' },
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('plugin management', () => {
|
||||
|
||||
@@ -1,17 +1 @@
|
||||
import React, { memo } from 'react';
|
||||
|
||||
import { useChatStore } from '@/store/chat';
|
||||
import { chatSelectors } from '@/store/chat/selectors';
|
||||
|
||||
import InboxWelcome from './InboxWelcome';
|
||||
import WelcomeMessage from './WelcomeMessage';
|
||||
|
||||
const WelcomeChatItem = memo(() => {
|
||||
const showInboxWelcome = useChatStore(chatSelectors.showInboxWelcome);
|
||||
|
||||
if (showInboxWelcome) return <InboxWelcome />;
|
||||
|
||||
return <WelcomeMessage />;
|
||||
});
|
||||
|
||||
export default WelcomeChatItem;
|
||||
export { default } from './WelcomeMessage';
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { Tooltip } from 'antd';
|
||||
import { createStyles, useTheme } from 'antd-style';
|
||||
import debug from 'debug';
|
||||
import { ChevronDown, ChevronUp } from 'lucide-react';
|
||||
import { memo, useCallback, useMemo, useState, useSyncExternalStore } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
@@ -17,10 +18,12 @@ import {
|
||||
import { useChatStore } from '@/store/chat';
|
||||
import { chatSelectors } from '@/store/chat/selectors';
|
||||
|
||||
const log = debug('lobe-react:chat-minimap');
|
||||
|
||||
const MIN_WIDTH = 16;
|
||||
const MAX_WIDTH = 30;
|
||||
const MAX_CONTENT_LENGTH = 320;
|
||||
const MIN_MESSAGES = 6;
|
||||
const MIN_MESSAGES = 4;
|
||||
|
||||
const useStyles = createStyles(({ css, token }) => ({
|
||||
arrow: css`
|
||||
@@ -219,8 +222,8 @@ const ChatMinimap = () => {
|
||||
const activeIndicatorPosition = useMemo(() => {
|
||||
if (activeIndex === null) return null;
|
||||
|
||||
console.log('> activeIndex', activeIndex);
|
||||
console.log('> indicatorIndexMap', indicatorIndexMap);
|
||||
log('> activeIndex', activeIndex);
|
||||
log('> indicatorIndexMap', indicatorIndexMap);
|
||||
|
||||
return indicatorIndexMap.get(activeIndex) ?? null;
|
||||
}, [activeIndex, indicatorIndexMap]);
|
||||
@@ -246,7 +249,7 @@ const ChatMinimap = () => {
|
||||
let targetPosition: number;
|
||||
|
||||
if (activeIndicatorPosition !== null) {
|
||||
console.log('activeIndicatorPosition', activeIndicatorPosition);
|
||||
log('activeIndicatorPosition', activeIndicatorPosition);
|
||||
// We're on an indicator, move to prev/next
|
||||
const delta = direction === 'prev' ? -1 : 1;
|
||||
targetPosition = Math.min(
|
||||
|
||||
@@ -31,22 +31,21 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
|
||||
const [active] = useSessionStore((s) => [s.activeId === id]);
|
||||
const [loading] = useChatStore((s) => [chatSelectors.isAIGenerating(s) && id === s.activeId]);
|
||||
|
||||
const [pin, title, description, avatar, avatarBackground, updateAt, model, group] =
|
||||
useSessionStore((s) => {
|
||||
const session = sessionSelectors.getSessionById(id)(s);
|
||||
const meta = session.meta;
|
||||
const [pin, title, avatar, avatarBackground, updateAt, model, group] = useSessionStore((s) => {
|
||||
const session = sessionSelectors.getSessionById(id)(s);
|
||||
const meta = session.meta;
|
||||
|
||||
return [
|
||||
sessionHelpers.getSessionPinned(session),
|
||||
sessionMetaSelectors.getTitle(meta),
|
||||
sessionMetaSelectors.getDescription(meta),
|
||||
sessionMetaSelectors.getAvatar(meta),
|
||||
meta.backgroundColor,
|
||||
session?.updatedAt,
|
||||
session.model,
|
||||
session?.group,
|
||||
];
|
||||
});
|
||||
return [
|
||||
sessionHelpers.getSessionPinned(session),
|
||||
sessionMetaSelectors.getTitle(meta),
|
||||
sessionMetaSelectors.getAvatar(meta),
|
||||
meta.backgroundColor,
|
||||
session?.updatedAt,
|
||||
session.model,
|
||||
session?.group,
|
||||
// sessionMetaSelectors.getDescription(meta),
|
||||
];
|
||||
});
|
||||
|
||||
const showModel = model !== defaultModel;
|
||||
|
||||
@@ -99,7 +98,7 @@ const SessionItem = memo<SessionItemProps>(({ id }) => {
|
||||
avatar={avatar}
|
||||
avatarBackground={avatarBackground}
|
||||
date={updateAt?.valueOf()}
|
||||
description={description}
|
||||
// description={description}
|
||||
draggable={isDesktop}
|
||||
key={id}
|
||||
loading={loading}
|
||||
|
||||
@@ -12,7 +12,7 @@ const useStyles = createStyles(({ css, token }) => {
|
||||
container: css`
|
||||
position: relative;
|
||||
margin-block: 2px;
|
||||
padding-inline: 8px 16px;
|
||||
padding-inline: 12px 16px;
|
||||
border-radius: ${token.borderRadius}px;
|
||||
`,
|
||||
mobile: css`
|
||||
@@ -40,7 +40,7 @@ const ListItem = memo<ListItemProps & { avatar: string; avatarBackground?: strin
|
||||
avatar={avatar}
|
||||
background={avatarBackground}
|
||||
shape="circle"
|
||||
size={40}
|
||||
size={32}
|
||||
/>
|
||||
),
|
||||
[isHovering, avatar, avatarBackground],
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { ReactNode, memo } from 'react';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
|
||||
import Loader from '@/components/CircleLoader';
|
||||
import { useChatStore } from '@/store/chat';
|
||||
import { chatSelectors } from '@/store/chat/selectors';
|
||||
import { shinyTextStylish } from '@/styles/loading';
|
||||
@@ -32,21 +33,18 @@ interface BuiltinPluginTitleProps {
|
||||
toolCallId: string;
|
||||
}
|
||||
|
||||
const BuiltinPluginTitle = memo<BuiltinPluginTitleProps>(
|
||||
({ messageId, index, apiName, icon, title }) => {
|
||||
const { styles } = useStyles();
|
||||
const BuiltinPluginTitle = memo<BuiltinPluginTitleProps>(({ messageId, index, apiName, title }) => {
|
||||
const { styles } = useStyles();
|
||||
|
||||
const isLoading = useChatStore(chatSelectors.isInToolsCalling(messageId, index));
|
||||
const isLoading = useChatStore(chatSelectors.isInToolsCalling(messageId, index));
|
||||
|
||||
return (
|
||||
<Flexbox align={'center'} className={isLoading ? styles.shinyText : ''} gap={4} horizontal>
|
||||
{isLoading ? <Loader /> : icon}
|
||||
<Flexbox align={'baseline'} gap={4} horizontal>
|
||||
<div>{title}</div>/<span className={styles.apiName}>{apiName}</span>
|
||||
</Flexbox>
|
||||
</Flexbox>
|
||||
);
|
||||
},
|
||||
);
|
||||
return (
|
||||
<Flexbox align={'center'} className={isLoading ? styles.shinyText : ''} gap={4} horizontal>
|
||||
<div>{title}</div>
|
||||
<Icon icon={ChevronRight} />
|
||||
<span className={styles.apiName}>{apiName}</span>
|
||||
</Flexbox>
|
||||
);
|
||||
});
|
||||
|
||||
export default BuiltinPluginTitle;
|
||||
|
||||
@@ -1,13 +1,11 @@
|
||||
import { Icon } from '@lobehub/ui';
|
||||
import { createStyles } from 'antd-style';
|
||||
import isEqual from 'fast-deep-equal';
|
||||
import { Globe, Laptop } from 'lucide-react';
|
||||
import { ChevronRight } from 'lucide-react';
|
||||
import { memo, useMemo } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { Flexbox } from 'react-layout-kit';
|
||||
|
||||
import Loader from '@/components/CircleLoader';
|
||||
import PluginAvatar from '@/features/PluginAvatar';
|
||||
import { useChatStore } from '@/store/chat';
|
||||
import { chatSelectors } from '@/store/chat/selectors';
|
||||
import { pluginHelpers, useToolStore } from '@/store/tool';
|
||||
@@ -60,13 +58,13 @@ const ToolTitle = memo<ToolTitleProps>(({ identifier, messageId, index, apiName,
|
||||
() => [
|
||||
{
|
||||
apiName: t(`search.apiName.${apiName}`, apiName),
|
||||
icon: <Icon icon={Globe} size={13} />,
|
||||
// icon: <Icon icon={Globe} size={13} />,
|
||||
id: WebBrowsingManifest.identifier,
|
||||
title: t('search.title'),
|
||||
},
|
||||
{
|
||||
apiName: t(`localSystem.apiName.${apiName}`, apiName),
|
||||
icon: <Icon icon={Laptop} size={13} />,
|
||||
// icon: <Icon icon={Laptop} size={13} />,
|
||||
id: LocalSystemManifest.identifier,
|
||||
title: t('localSystem.title'),
|
||||
},
|
||||
@@ -92,8 +90,8 @@ const ToolTitle = memo<ToolTitleProps>(({ identifier, messageId, index, apiName,
|
||||
|
||||
return (
|
||||
<Flexbox align={'center'} className={isLoading ? styles.shinyText : ''} gap={6} horizontal>
|
||||
{isLoading ? <Loader /> : <PluginAvatar identifier={identifier} size={18} />}
|
||||
<div>{pluginTitle}</div>/<span className={styles.apiName}>{apiName}</span>
|
||||
<div>{pluginTitle}</div> <Icon icon={ChevronRight} />
|
||||
<span className={styles.apiName}>{apiName}</span>
|
||||
</Flexbox>
|
||||
);
|
||||
});
|
||||
|
||||
@@ -116,14 +116,7 @@ const Arguments = memo<ArgumentsProps>(({ arguments: args = '', shine, actions }
|
||||
</Flexbox>
|
||||
)}
|
||||
{args.length > 100 ? (
|
||||
<Highlighter
|
||||
language={'json'}
|
||||
showLanguage={false}
|
||||
style={{ padding: 8 }}
|
||||
variant={'borderless'}
|
||||
>
|
||||
{JSON.stringify(displayArgs, null, 2)}
|
||||
</Highlighter>
|
||||
<pre style={{ padding: 8 }}>{JSON.stringify(displayArgs, null, 2)}</pre>
|
||||
) : (
|
||||
Object.entries(displayArgs).map(([key, value]) => {
|
||||
return (
|
||||
|
||||
@@ -4,8 +4,8 @@ export default {
|
||||
},
|
||||
agentDefaultMessage:
|
||||
'你好,我是 **{{name}}**,你可以立即与我开始对话,也可以前往 [助手设置]({{url}}) 完善我的信息。',
|
||||
agentDefaultMessageWithSystemRole: '你好,我是 **{{name}}**,{{systemRole}},让我们开始对话吧!',
|
||||
agentDefaultMessageWithoutEdit: '你好,我是 **{{name}}**,让我们开始对话吧!',
|
||||
agentDefaultMessageWithSystemRole: '你好,我是 **{{name}}**,有什么我可以帮忙的吗?',
|
||||
agentDefaultMessageWithoutEdit: '你好,我是 **{{name}}**,有什么我可以帮忙的吗?',
|
||||
agents: '助手',
|
||||
artifact: {
|
||||
generating: '生成中',
|
||||
|
||||
Reference in New Issue
Block a user