@lobehub/chat 1.79.10 → 1.80.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 (52) hide show
  1. package/CHANGELOG.md +52 -0
  2. package/changelog/v1.json +15 -0
  3. package/docs/development/basic/feature-development-new.mdx +465 -0
  4. package/docs/development/basic/feature-development-new.zh-CN.mdx +465 -0
  5. package/docs/development/database-schema.dbml +2 -0
  6. package/locales/ar/setting.json +16 -0
  7. package/locales/bg-BG/setting.json +16 -0
  8. package/locales/de-DE/setting.json +16 -0
  9. package/locales/en-US/setting.json +16 -0
  10. package/locales/es-ES/setting.json +16 -0
  11. package/locales/fa-IR/setting.json +16 -0
  12. package/locales/fr-FR/setting.json +16 -0
  13. package/locales/it-IT/setting.json +16 -0
  14. package/locales/ja-JP/setting.json +16 -0
  15. package/locales/ko-KR/setting.json +16 -0
  16. package/locales/nl-NL/setting.json +16 -0
  17. package/locales/pl-PL/setting.json +16 -0
  18. package/locales/pt-BR/setting.json +16 -0
  19. package/locales/ru-RU/setting.json +16 -0
  20. package/locales/tr-TR/setting.json +16 -0
  21. package/locales/vi-VN/setting.json +16 -0
  22. package/locales/zh-CN/setting.json +16 -0
  23. package/locales/zh-TW/setting.json +16 -0
  24. package/package.json +1 -1
  25. package/scripts/generate-oidc-jwk.mjs +2 -1
  26. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/OpeningQuestions.tsx +78 -0
  27. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/WelcomeMessage.tsx +24 -4
  28. package/src/app/[variants]/(main)/chat/(workspace)/features/AgentSettings/CategoryContent/useCategory.tsx +6 -1
  29. package/src/app/[variants]/(main)/chat/(workspace)/features/AgentSettings/index.tsx +2 -0
  30. package/src/const/settings/agent.ts +1 -0
  31. package/src/database/_deprecated/schemas/session.ts +2 -0
  32. package/src/database/client/migrations.json +9 -0
  33. package/src/database/migrations/0021_add_agent_opening_settings.sql +2 -0
  34. package/src/database/migrations/meta/0021_snapshot.json +4988 -0
  35. package/src/database/migrations/meta/_journal.json +7 -0
  36. package/src/database/repositories/dataImporter/deprecated/__tests__/fixtures/messages.json +2 -0
  37. package/src/database/repositories/dataImporter/deprecated/__tests__/index.test.ts +19 -0
  38. package/src/database/schemas/agent.ts +3 -0
  39. package/src/features/AgentSetting/AgentOpening/OpeningMessage.tsx +80 -0
  40. package/src/features/AgentSetting/AgentOpening/OpeningQuestions.tsx +144 -0
  41. package/src/features/AgentSetting/AgentOpening/index.tsx +52 -0
  42. package/src/features/AgentSetting/store/selectors.ts +3 -0
  43. package/src/locales/default/setting.ts +16 -0
  44. package/src/migrations/FromV5ToV6/types/v6.ts +2 -0
  45. package/src/server/routers/lambda/session.ts +8 -1
  46. package/src/services/import/client.test.ts +18 -0
  47. package/src/services/session/server.test.ts +2 -0
  48. package/src/store/agent/slices/chat/selectors/__snapshots__/agent.test.ts.snap +1 -0
  49. package/src/store/agent/slices/chat/selectors/agent.ts +7 -0
  50. package/src/store/global/initialState.ts +1 -0
  51. package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +2 -0
  52. package/src/types/agent/index.ts +12 -0
@@ -6,6 +6,7 @@
6
6
  "chat": "Preferenze di chat",
7
7
  "meta": "Informazioni assistente",
8
8
  "modal": "Impostazioni modello",
9
+ "opening": "Impostazioni di apertura",
9
10
  "plugin": "Impostazioni plugin",
10
11
  "prompt": "Impostazioni ruolo",
11
12
  "tts": "Servizio vocale"
@@ -253,6 +254,21 @@
253
254
  "title": "Apertura Mentale"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "Messaggio di apertura quando si avvia la conversazione, utilizzato per presentare le funzionalità dell'assistente",
260
+ "placeholder": "Ciao, sono l'assistente personalizzato, puoi iniziare subito a conversare con me oppure andare su Impostazioni assistente per completare le mie informazioni.",
261
+ "title": "Messaggio di apertura"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "Domande guida visualizzate all'inizio della conversazione",
265
+ "empty": "Nessuna domanda disponibile",
266
+ "placeholder": "Inserisci una domanda",
267
+ "repeat": "La domanda esiste già",
268
+ "title": "Domande di apertura"
269
+ },
270
+ "title": "Impostazioni di apertura"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "Elenco dei plugin"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "チャット設定",
7
7
  "meta": "メタ情報",
8
8
  "modal": "モーダル設定",
9
+ "opening": "オープニング設定",
9
10
  "plugin": "プラグイン設定",
10
11
  "prompt": "プロンプト設定",
11
12
  "tts": "音声サービス"
@@ -253,6 +254,21 @@
253
254
  "title": "思考の開放度"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "会話を開始する際のオープニングメッセージで、アシスタントの機能を紹介します",
260
+ "placeholder": "こんにちは、私はカスタムアシスタントです。すぐに私と会話を始めることも、アシスタント設定に進んで私の情報を充実させることもできます。",
261
+ "title": "オープニングメッセージ"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "会話開始時に表示されるガイド質問",
265
+ "empty": "質問はありません",
266
+ "placeholder": "質問を入力してください",
267
+ "repeat": "質問は既に存在します",
268
+ "title": "オープニング質問"
269
+ },
270
+ "title": "オープニング設定"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "プラグインリスト"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "채팅 환경",
7
7
  "meta": "도우미 정보",
8
8
  "modal": "모델 설정",
9
+ "opening": "오프닝 설정",
9
10
  "plugin": "플러그인 설정",
10
11
  "prompt": "역할 설정",
11
12
  "tts": "음성 서비스"
@@ -253,6 +254,21 @@
253
254
  "title": "사고 개방성"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "대화 시작 시 표시되는 오프닝 메시지로, 어시스턴트의 기능을 소개합니다.",
260
+ "placeholder": "안녕하세요, 저는 맞춤형 어시스턴트입니다. 지금 바로 저와 대화를 시작하시거나, 어시스턴트 설정으로 가서 제 정보를 완성할 수 있습니다.",
261
+ "title": "오프닝 메시지"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "대화 시작 시 표시되는 안내 질문",
265
+ "empty": "질문이 없습니다",
266
+ "placeholder": "질문을 입력하세요",
267
+ "repeat": "질문이 이미 존재합니다",
268
+ "title": "오프닝 질문"
269
+ },
270
+ "title": "오프닝 설정"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "플러그인 목록"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "Chatvoorkeur",
7
7
  "meta": "Assistentinformatie",
8
8
  "modal": "Modelinstellingen",
9
+ "opening": "Openingsinstellingen",
9
10
  "plugin": "Plugin-instellingen",
10
11
  "prompt": "Rolinstelling",
11
12
  "tts": "Tekst-naar-spraakdienst"
@@ -253,6 +254,21 @@
253
254
  "title": "Openheid van Denken"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "De openingsboodschap bij het starten van een gesprek, bedoeld om de functies van de assistent voor te stellen",
260
+ "placeholder": "Hallo, ik ben de aangepaste assistent. Je kunt direct met me beginnen praten of naar de assistentinstellingen gaan om mijn informatie aan te vullen.",
261
+ "title": "Openingsboodschap"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "Leidende vragen die worden weergegeven aan het begin van het gesprek",
265
+ "empty": "Geen vragen beschikbaar",
266
+ "placeholder": "Voer een vraag in",
267
+ "repeat": "Vraag bestaat al",
268
+ "title": "Openingsvragen"
269
+ },
270
+ "title": "Openingsinstellingen"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "Plugin-lijst"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "Preferencje czatu",
7
7
  "meta": "Informacje o asystencie",
8
8
  "modal": "Ustawienia modalne",
9
+ "opening": "Ustawienia otwarcia",
9
10
  "plugin": "Ustawienia wtyczki",
10
11
  "prompt": "Ustawienia roli",
11
12
  "tts": "Usługi głosowe"
@@ -253,6 +254,21 @@
253
254
  "title": "Otwartość myślenia"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "Wiadomość powitalna wyświetlana przy otwarciu rozmowy, służąca do przedstawienia funkcji asystenta",
260
+ "placeholder": "Cześć, jestem dostosowanym asystentem, możesz od razu rozpocząć rozmowę lub przejść do ustawień asystenta, aby uzupełnić moje informacje.",
261
+ "title": "Wiadomość powitalna"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "Pytania wprowadzające wyświetlane na początku rozmowy",
265
+ "empty": "Brak pytań",
266
+ "placeholder": "Wprowadź pytanie",
267
+ "repeat": "Pytanie już istnieje",
268
+ "title": "Pytania powitalne"
269
+ },
270
+ "title": "Ustawienia otwarcia"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "Lista wtyczek"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "Preferências de bate-papo",
7
7
  "meta": "Informações do assistente",
8
8
  "modal": "Configurações do modelo",
9
+ "opening": "Configuração de Abertura",
9
10
  "plugin": "Configurações do plug-in",
10
11
  "prompt": "Configuração de personagem",
11
12
  "tts": "Serviço de voz"
@@ -253,6 +254,21 @@
253
254
  "title": "Abertura Mental"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "Mensagem de abertura exibida ao iniciar a conversa, usada para apresentar as funcionalidades do assistente",
260
+ "placeholder": "Olá, eu sou o Assistente Personalizado, você pode começar a conversar comigo imediatamente ou ir para Configurações do Assistente para completar minhas informações.",
261
+ "title": "Mensagem de Abertura"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "Perguntas orientadoras exibidas no início da conversa",
265
+ "empty": "Nenhuma pergunta disponível",
266
+ "placeholder": "Digite uma pergunta",
267
+ "repeat": "A pergunta já existe",
268
+ "title": "Perguntas de Abertura"
269
+ },
270
+ "title": "Configuração de Abertura"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "Lista de plugins"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "Предпочтения чата",
7
7
  "meta": "Информация об ассистенте",
8
8
  "modal": "Настройки модели",
9
+ "opening": "Настройки начала",
9
10
  "plugin": "Настройки плагина",
10
11
  "prompt": "Настройки роли",
11
12
  "tts": "Сервис озвучивания текста"
@@ -253,6 +254,21 @@
253
254
  "title": "Открытость мышления"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "Сообщение, отображаемое при открытии сессии, для представления функций помощника",
260
+ "placeholder": "Привет, я ваш настраиваемый помощник, вы можете сразу начать со мной разговор или перейти в настройки помощника, чтобы дополнить мою информацию.",
261
+ "title": "Сообщение начала"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "Вводные вопросы, отображаемые в начале сессии",
265
+ "empty": "Нет вопросов",
266
+ "placeholder": "Введите вопрос",
267
+ "repeat": "Вопрос уже существует",
268
+ "title": "Вопросы начала"
269
+ },
270
+ "title": "Настройки начала"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "Список плагинов"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "Sohbet Tercihi",
7
7
  "meta": "Asistan Bilgisi",
8
8
  "modal": "Model Ayarları",
9
+ "opening": "Açılış Ayarları",
9
10
  "plugin": "Eklenti Ayarları",
10
11
  "prompt": "Karakter Ayarları",
11
12
  "tts": "Metin Okuma Hizmeti"
@@ -253,6 +254,21 @@
253
254
  "title": "Düşünce Açıklığı"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "Sohbet açıldığında gösterilecek açılış mesajı, asistanın işlevlerini tanıtmak için kullanılır",
260
+ "placeholder": "Merhaba, ben Özelleştirilmiş Asistan, hemen benimle sohbet edebilirsiniz veya Asistan Ayarları'na giderek bilgimi tamamlayabilirsiniz.",
261
+ "title": "Açılış Mesajı"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "Sohbetin başlangıcında gösterilecek yönlendirici sorular",
265
+ "empty": "Henüz soru yok",
266
+ "placeholder": "Soruyu girin",
267
+ "repeat": "Soru zaten mevcut",
268
+ "title": "Açılış Soruları"
269
+ },
270
+ "title": "Açılış Ayarları"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "Eklenti Listesi"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "Tùy chọn Trò chuyện",
7
7
  "meta": "Thông tin Trợ lý",
8
8
  "modal": "Cài đặt Mô hình",
9
+ "opening": "Cài đặt mở đầu",
9
10
  "plugin": "Cài đặt Plugin",
10
11
  "prompt": "Thiết lập Nhân vật",
11
12
  "tts": "Dịch vụ Giọng nói"
@@ -253,6 +254,21 @@
253
254
  "title": "Mức độ mở trong tư duy"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "Tin nhắn mở đầu khi bắt đầu cuộc trò chuyện, dùng để giới thiệu chức năng của trợ lý",
260
+ "placeholder": "Xin chào, tôi là Trợ lý tùy chỉnh, bạn có thể bắt đầu trò chuyện với tôi ngay lập tức, hoặc đến Cài đặt trợ lý để hoàn thiện thông tin của tôi.",
261
+ "title": "Tin nhắn mở đầu"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "Câu hỏi hướng dẫn hiển thị khi bắt đầu cuộc trò chuyện",
265
+ "empty": "Chưa có câu hỏi nào",
266
+ "placeholder": "Nhập câu hỏi",
267
+ "repeat": "Câu hỏi đã tồn tại",
268
+ "title": "Câu hỏi mở đầu"
269
+ },
270
+ "title": "Cài đặt mở đầu"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "Danh sách plugin"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "聊天偏好",
7
7
  "meta": "助手信息",
8
8
  "modal": "模型设置",
9
+ "opening": "开场设置",
9
10
  "plugin": "插件设置",
10
11
  "prompt": "角色设定",
11
12
  "tts": "语音服务"
@@ -253,6 +254,21 @@
253
254
  "title": "思维开放度"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "打开会话时的开场消息,用来介绍助手的功能",
260
+ "placeholder": "你好,我是自定义助手。你可以立即与我开始对话,也可以前往助手设置完善我的信息。",
261
+ "title": "开场消息"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "会话开始时展示的引导性问题",
265
+ "empty": "暂无问题",
266
+ "placeholder": "请输入问题",
267
+ "repeat": "问题已存在",
268
+ "title": "开场问题"
269
+ },
270
+ "title": "开场设置"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "插件列表"
258
274
  },
@@ -6,6 +6,7 @@
6
6
  "chat": "聊天偏好",
7
7
  "meta": "助手資訊",
8
8
  "modal": "模型設定",
9
+ "opening": "開場設定",
9
10
  "plugin": "外掛程式設定",
10
11
  "prompt": "角色設定",
11
12
  "tts": "語音服務"
@@ -253,6 +254,21 @@
253
254
  "title": "思維開放度"
254
255
  }
255
256
  },
257
+ "settingOpening": {
258
+ "openingMessage": {
259
+ "desc": "打開會話時的開場消息,用來介紹助手的功能",
260
+ "placeholder": "你好,我是 自訂助手,你可以立即與我開始對話,也可以前往 助手設定 完善我的資訊。",
261
+ "title": "開場消息"
262
+ },
263
+ "openingQuestions": {
264
+ "desc": "會話開始時展示的引導性問題",
265
+ "empty": "暫無問題",
266
+ "placeholder": "請輸入問題",
267
+ "repeat": "問題已存在",
268
+ "title": "開場問題"
269
+ },
270
+ "title": "開場設定"
271
+ },
256
272
  "settingPlugin": {
257
273
  "title": "插件列表"
258
274
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lobehub/chat",
3
- "version": "1.79.10",
3
+ "version": "1.80.0",
4
4
  "description": "Lobe Chat - an open-source, high-performance chatbot framework that supports speech synthesis, multimodal, and extensible Function Call plugin system. Supports one-click free deployment of your private ChatGPT/LLM web application.",
5
5
  "keywords": [
6
6
  "framework",
@@ -8,8 +8,8 @@
8
8
  *
9
9
  * 将输出的单行 JSON 字符串设置为环境变量 OIDC_JWKS_KEY
10
10
  */
11
- import crypto from 'node:crypto';
12
11
  import { exportJWK, generateKeyPair } from 'jose';
12
+ import crypto from 'node:crypto';
13
13
 
14
14
  // 生成密钥 ID
15
15
  function generateKeyId() {
@@ -56,4 +56,5 @@ async function generateJwks() {
56
56
  }
57
57
 
58
58
  // 执行主函数
59
+ // eslint-disable-next-line unicorn/prefer-top-level-await
59
60
  generateJwks();
@@ -0,0 +1,78 @@
1
+ 'use client';
2
+
3
+ import { createStyles } from 'antd-style';
4
+ import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+ import { Flexbox } from 'react-layout-kit';
7
+
8
+ import { useSendMessage } from '@/features/ChatInput/useSend';
9
+ import { useChatStore } from '@/store/chat';
10
+
11
+ const useStyles = createStyles(({ css, token, responsive }) => ({
12
+ card: css`
13
+ cursor: pointer;
14
+
15
+ padding-block: 12px;
16
+ padding-inline: 24px;
17
+ border-radius: 48px;
18
+
19
+ color: ${token.colorText};
20
+
21
+ background: ${token.colorBgContainer};
22
+
23
+ &:hover {
24
+ background: ${token.colorBgElevated};
25
+ }
26
+
27
+ ${responsive.mobile} {
28
+ padding-block: 8px;
29
+ padding-inline: 16px;
30
+ }
31
+ `,
32
+
33
+ container: css`
34
+ padding-block: 0;
35
+ padding-inline: 20px;
36
+ `,
37
+
38
+ title: css`
39
+ color: ${token.colorTextDescription};
40
+ `,
41
+ }));
42
+
43
+ interface OpeningQuestionsProps {
44
+ mobile?: boolean;
45
+ questions: string[];
46
+ }
47
+
48
+ const OpeningQuestions = memo<OpeningQuestionsProps>(({ mobile, questions }) => {
49
+ const { t } = useTranslation('welcome');
50
+ const [updateInputMessage] = useChatStore((s) => [s.updateInputMessage]);
51
+
52
+ const { styles } = useStyles();
53
+ const { send: sendMessage } = useSendMessage();
54
+
55
+ return (
56
+ <div className={styles.container}>
57
+ <p className={styles.title}>{t('guide.questions.title')}</p>
58
+ <Flexbox gap={8} horizontal wrap={'wrap'}>
59
+ {questions.slice(0, mobile ? 2 : 5).map((question) => {
60
+ return (
61
+ <div
62
+ className={styles.card}
63
+ key={question}
64
+ onClick={() => {
65
+ updateInputMessage(question);
66
+ sendMessage({ isWelcomeQuestion: true });
67
+ }}
68
+ >
69
+ {question}
70
+ </div>
71
+ );
72
+ })}
73
+ </Flexbox>
74
+ </div>
75
+ );
76
+ });
77
+
78
+ export default OpeningQuestions;
@@ -1,18 +1,24 @@
1
1
  import { ChatItem } from '@lobehub/ui';
2
2
  import isEqual from 'fast-deep-equal';
3
- import React from 'react';
3
+ import React, { useMemo } from 'react';
4
4
  import { useTranslation } from 'react-i18next';
5
+ import { Flexbox } from 'react-layout-kit';
5
6
 
6
7
  import { useAgentStore } from '@/store/agent';
7
- import { agentChatConfigSelectors } from '@/store/agent/selectors';
8
+ import { agentChatConfigSelectors, agentSelectors } from '@/store/agent/selectors';
8
9
  import { useChatStore } from '@/store/chat';
9
10
  import { featureFlagsSelectors, useServerConfigStore } from '@/store/serverConfig';
10
11
  import { useSessionStore } from '@/store/session';
11
12
  import { sessionMetaSelectors } from '@/store/session/selectors';
12
13
 
14
+ import OpeningQuestions from './OpeningQuestions';
15
+
13
16
  const WelcomeMessage = () => {
17
+ const mobile = useServerConfigStore((s) => s.isMobile);
14
18
  const { t } = useTranslation('chat');
15
19
  const type = useAgentStore(agentChatConfigSelectors.displayMode);
20
+ const openingMessage = useAgentStore(agentSelectors.openingMessage);
21
+ const openingQuestions = useAgentStore(agentSelectors.openingQuestions);
16
22
 
17
23
  const meta = useSessionStore(sessionMetaSelectors.currentAgentMeta, isEqual);
18
24
  const { isAgentEditable } = useServerConfigStore(featureFlagsSelectors);
@@ -28,14 +34,28 @@ const WelcomeMessage = () => {
28
34
  url: `/chat/settings?session=${activeId}`,
29
35
  });
30
36
 
31
- return (
37
+ const message = useMemo(() => {
38
+ if (openingMessage) return openingMessage;
39
+ return !!meta.description ? agentSystemRoleMsg : agentMsg;
40
+ }, [openingMessage, agentSystemRoleMsg, agentMsg, meta.description]);
41
+
42
+ const chatItem = (
32
43
  <ChatItem
33
44
  avatar={meta}
34
45
  editing={false}
35
- message={!!meta.description ? agentSystemRoleMsg : agentMsg}
46
+ message={message}
36
47
  placement={'left'}
37
48
  type={type === 'chat' ? 'block' : 'pure'}
38
49
  />
39
50
  );
51
+
52
+ return openingQuestions.length > 0 ? (
53
+ <Flexbox>
54
+ {chatItem}
55
+ <OpeningQuestions mobile={mobile} questions={openingQuestions} />
56
+ </Flexbox>
57
+ ) : (
58
+ chatItem
59
+ );
40
60
  };
41
61
  export default WelcomeMessage;
@@ -1,6 +1,6 @@
1
1
  import { Icon } from '@lobehub/ui';
2
2
  import { MenuItemType } from 'antd/es/menu/interface';
3
- import { Blocks, Bot, BrainCog, MessagesSquare, Mic2, UserCircle } from 'lucide-react';
3
+ import { Blocks, Bot, BrainCog, Handshake, MessagesSquare, Mic2, UserCircle } from 'lucide-react';
4
4
  import { useMemo } from 'react';
5
5
  import { useTranslation } from 'react-i18next';
6
6
 
@@ -32,6 +32,11 @@ export const useCategory = ({ mobile }: UseCategoryOptions = {}) => {
32
32
  key: ChatSettingsTabs.Prompt,
33
33
  label: t('agentTab.prompt'),
34
34
  },
35
+ (!isInbox && {
36
+ icon: <Icon icon={Handshake} size={iconSize} />,
37
+ key: ChatSettingsTabs.Opening,
38
+ label: t('agentTab.opening'),
39
+ }) as MenuItemType,
35
40
  {
36
41
  icon: <Icon icon={MessagesSquare} size={iconSize} />,
37
42
  key: ChatSettingsTabs.Chat,
@@ -12,6 +12,7 @@ import { INBOX_SESSION_ID } from '@/const/session';
12
12
  import AgentChat from '@/features/AgentSetting/AgentChat';
13
13
  import AgentMeta from '@/features/AgentSetting/AgentMeta';
14
14
  import AgentModal from '@/features/AgentSetting/AgentModal';
15
+ import AgentOpening from '@/features/AgentSetting/AgentOpening';
15
16
  import AgentPlugin from '@/features/AgentSetting/AgentPlugin';
16
17
  import AgentPrompt from '@/features/AgentSetting/AgentPrompt';
17
18
  import { AgentSettingsProvider } from '@/features/AgentSetting/AgentSettingsProvider';
@@ -104,6 +105,7 @@ const AgentSettings = memo(() => {
104
105
  >
105
106
  {tab === ChatSettingsTabs.Meta && <AgentMeta />}
106
107
  {tab === ChatSettingsTabs.Prompt && <AgentPrompt />}
108
+ {tab === ChatSettingsTabs.Opening && <AgentOpening />}
107
109
  {tab === ChatSettingsTabs.Chat && <AgentChat />}
108
110
  {tab === ChatSettingsTabs.Modal && <AgentModal />}
109
111
  {tab === ChatSettingsTabs.TTS && <AgentTTS />}
@@ -33,6 +33,7 @@ export const DEFAULT_AGENT_CHAT_CONFIG: LobeAgentChatConfig = {
33
33
  export const DEFAULT_AGENT_CONFIG: LobeAgentConfig = {
34
34
  chatConfig: DEFAULT_AGENT_CHAT_CONFIG,
35
35
  model: DEFAULT_MODEL,
36
+ openingQuestions: [],
36
37
  params: {
37
38
  frequency_penalty: 0,
38
39
  presence_penalty: 0,
@@ -28,6 +28,8 @@ export const AgentSchema = z.object({
28
28
  chatConfig: AgentChatConfigSchema,
29
29
  fewShots: fewShotsSchema.optional(),
30
30
  model: z.string().default(DEFAULT_MODEL),
31
+ openingMessage: z.string().optional(),
32
+ openingQuestions: z.array(z.string()).default([]).optional(),
31
33
  params: z.object({
32
34
  frequency_penalty: z.number().default(0).optional(),
33
35
  max_tokens: z.number().optional(),
@@ -448,5 +448,14 @@
448
448
  "bps": true,
449
449
  "folderMillis": 1744458287757,
450
450
  "hash": "f3a80b900906b54ba658208cd448610647fc03f1f4d51963509c07f4e53ef4de"
451
+ },
452
+ {
453
+ "sql": [
454
+ "ALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"opening_message\" text;",
455
+ "\nALTER TABLE \"agents\" ADD COLUMN IF NOT EXISTS \"opening_questions\" text[] DEFAULT '{}';"
456
+ ],
457
+ "bps": true,
458
+ "folderMillis": 1744602998656,
459
+ "hash": "9a32c373461472a4afdb45e690c3009a0db0eaae81dcf6c8d05277a48f3a5e85"
451
460
  }
452
461
  ]
@@ -0,0 +1,2 @@
1
+ ALTER TABLE "agents" ADD COLUMN IF NOT EXISTS "opening_message" text;--> statement-breakpoint
2
+ ALTER TABLE "agents" ADD COLUMN IF NOT EXISTS "opening_questions" text[] DEFAULT '{}';