@lobehub/chat 1.79.9 → 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 (75) hide show
  1. package/CHANGELOG.md +77 -0
  2. package/changelog/v1.json +24 -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/models.json +9 -0
  7. package/locales/ar/setting.json +16 -0
  8. package/locales/bg-BG/models.json +9 -0
  9. package/locales/bg-BG/setting.json +16 -0
  10. package/locales/de-DE/models.json +9 -0
  11. package/locales/de-DE/setting.json +16 -0
  12. package/locales/en-US/models.json +9 -0
  13. package/locales/en-US/setting.json +16 -0
  14. package/locales/es-ES/models.json +9 -0
  15. package/locales/es-ES/setting.json +16 -0
  16. package/locales/fa-IR/models.json +9 -0
  17. package/locales/fa-IR/setting.json +16 -0
  18. package/locales/fr-FR/models.json +9 -0
  19. package/locales/fr-FR/setting.json +16 -0
  20. package/locales/it-IT/models.json +9 -0
  21. package/locales/it-IT/setting.json +16 -0
  22. package/locales/ja-JP/models.json +9 -0
  23. package/locales/ja-JP/setting.json +16 -0
  24. package/locales/ko-KR/models.json +9 -0
  25. package/locales/ko-KR/setting.json +16 -0
  26. package/locales/nl-NL/models.json +9 -0
  27. package/locales/nl-NL/setting.json +16 -0
  28. package/locales/pl-PL/models.json +9 -0
  29. package/locales/pl-PL/setting.json +16 -0
  30. package/locales/pt-BR/models.json +9 -0
  31. package/locales/pt-BR/setting.json +16 -0
  32. package/locales/ru-RU/models.json +9 -0
  33. package/locales/ru-RU/setting.json +16 -0
  34. package/locales/tr-TR/models.json +9 -0
  35. package/locales/tr-TR/setting.json +16 -0
  36. package/locales/vi-VN/models.json +9 -0
  37. package/locales/vi-VN/setting.json +16 -0
  38. package/locales/zh-CN/models.json +9 -0
  39. package/locales/zh-CN/setting.json +16 -0
  40. package/locales/zh-TW/models.json +9 -0
  41. package/locales/zh-TW/setting.json +16 -0
  42. package/package.json +1 -1
  43. package/scripts/generate-oidc-jwk.mjs +2 -1
  44. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/OpeningQuestions.tsx +78 -0
  45. package/src/app/[variants]/(main)/chat/(workspace)/@conversation/features/ChatList/WelcomeChatItem/WelcomeMessage.tsx +24 -4
  46. package/src/app/[variants]/(main)/chat/(workspace)/features/AgentSettings/CategoryContent/useCategory.tsx +6 -1
  47. package/src/app/[variants]/(main)/chat/(workspace)/features/AgentSettings/index.tsx +2 -0
  48. package/src/config/modelProviders/openai.ts +17 -0
  49. package/src/const/settings/agent.ts +1 -0
  50. package/src/const/settings/llm.ts +1 -1
  51. package/src/database/_deprecated/schemas/session.ts +2 -0
  52. package/src/database/client/migrations.json +9 -0
  53. package/src/database/migrations/0021_add_agent_opening_settings.sql +2 -0
  54. package/src/database/migrations/meta/0021_snapshot.json +4988 -0
  55. package/src/database/migrations/meta/_journal.json +7 -0
  56. package/src/database/repositories/dataImporter/deprecated/__tests__/fixtures/messages.json +2 -0
  57. package/src/database/repositories/dataImporter/deprecated/__tests__/index.test.ts +19 -0
  58. package/src/database/schemas/agent.ts +3 -0
  59. package/src/features/AgentSetting/AgentOpening/OpeningMessage.tsx +80 -0
  60. package/src/features/AgentSetting/AgentOpening/OpeningQuestions.tsx +144 -0
  61. package/src/features/AgentSetting/AgentOpening/index.tsx +52 -0
  62. package/src/features/AgentSetting/store/selectors.ts +3 -0
  63. package/src/locales/default/setting.ts +16 -0
  64. package/src/migrations/FromV5ToV6/types/v6.ts +2 -0
  65. package/src/server/routers/lambda/session.ts +8 -1
  66. package/src/server/routers/tools/search.ts +1 -0
  67. package/src/services/chat.ts +1 -0
  68. package/src/services/import/client.test.ts +18 -0
  69. package/src/services/session/server.test.ts +2 -0
  70. package/src/store/agent/slices/chat/selectors/__snapshots__/agent.test.ts.snap +2 -1
  71. package/src/store/agent/slices/chat/selectors/agent.ts +7 -0
  72. package/src/store/global/initialState.ts +1 -0
  73. package/src/store/user/slices/modelList/selectors/modelProvider.test.ts +1 -0
  74. package/src/store/user/slices/settings/selectors/__snapshots__/settings.test.ts.snap +10 -8
  75. package/src/types/agent/index.ts +12 -0
@@ -147,6 +147,13 @@
147
147
  "when": 1744458287757,
148
148
  "tag": "0020_add_oidc",
149
149
  "breakpoints": true
150
+ },
151
+ {
152
+ "idx": 21,
153
+ "version": "7",
154
+ "when": 1744602998656,
155
+ "tag": "0021_add_agent_opening_settings",
156
+ "breakpoints": true
150
157
  }
151
158
  ],
152
159
  "version": "6"
@@ -926,6 +926,8 @@
926
926
  "ttsService": "openai",
927
927
  "voice": { "openai": "alloy" }
928
928
  },
929
+ "openingMessage": "I'm an AI assistant, how can I help you today?",
930
+ "openingQuestions": ["Question 1", "Question 2"],
929
931
  "chatConfig": {
930
932
  "autoCreateTopicThreshold": 2,
931
933
  "displayMode": "chat",
@@ -94,6 +94,7 @@ describe('DataImporter', () => {
94
94
  params: {},
95
95
  systemRole: 'abc',
96
96
  tts: {} as any,
97
+ openingQuestions: [],
97
98
  },
98
99
  meta: {
99
100
  title: 'Session 1',
@@ -110,6 +111,7 @@ describe('DataImporter', () => {
110
111
  params: {},
111
112
  systemRole: 'abc',
112
113
  tts: {} as any,
114
+ openingQuestions: [],
113
115
  },
114
116
  meta: {
115
117
  title: 'Session 2',
@@ -156,6 +158,7 @@ describe('DataImporter', () => {
156
158
  params: {},
157
159
  systemRole: 'abc',
158
160
  tts: {} as any,
161
+ openingQuestions: [],
159
162
  },
160
163
  meta: {
161
164
  title: 'Session 1',
@@ -172,6 +175,7 @@ describe('DataImporter', () => {
172
175
  params: {},
173
176
  systemRole: 'abc',
174
177
  tts: {} as any,
178
+ openingQuestions: [],
175
179
  },
176
180
  meta: {
177
181
  title: 'Session 2',
@@ -207,6 +211,7 @@ describe('DataImporter', () => {
207
211
  params: {},
208
212
  systemRole: 'abc',
209
213
  tts: {} as any,
214
+ openingQuestions: [],
210
215
  },
211
216
  meta: {
212
217
  title: 'Session 1',
@@ -224,6 +229,7 @@ describe('DataImporter', () => {
224
229
  params: {},
225
230
  systemRole: 'abc',
226
231
  tts: {} as any,
232
+ openingQuestions: [],
227
233
  },
228
234
  meta: {
229
235
  title: 'Session 2',
@@ -241,6 +247,7 @@ describe('DataImporter', () => {
241
247
  params: {},
242
248
  systemRole: 'abc',
243
249
  tts: {} as any,
250
+ openingQuestions: [],
244
251
  },
245
252
  meta: {
246
253
  title: 'Session 3',
@@ -287,6 +294,7 @@ describe('DataImporter', () => {
287
294
  params: {},
288
295
  systemRole: 'Test Agent 1',
289
296
  tts: {} as any,
297
+ openingQuestions: [],
290
298
  },
291
299
  meta: {
292
300
  title: 'Session 1',
@@ -303,6 +311,7 @@ describe('DataImporter', () => {
303
311
  params: {},
304
312
  systemRole: 'Test Agent 2',
305
313
  tts: {} as any,
314
+ openingQuestions: [],
306
315
  },
307
316
  meta: {
308
317
  title: 'Session 2',
@@ -367,6 +376,7 @@ describe('DataImporter', () => {
367
376
  params: {},
368
377
  systemRole: 'Test Agent 1',
369
378
  tts: {} as any,
379
+ openingQuestions: [],
370
380
  },
371
381
  meta: {
372
382
  title: 'Session 1',
@@ -390,6 +400,7 @@ describe('DataImporter', () => {
390
400
  params: {},
391
401
  systemRole: 'Test Agent 1',
392
402
  tts: {} as any,
403
+ openingQuestions: [],
393
404
  },
394
405
  meta: {
395
406
  title: 'Session 1',
@@ -439,6 +450,7 @@ describe('DataImporter', () => {
439
450
  params: {},
440
451
  systemRole: 'abc',
441
452
  tts: {} as any,
453
+ openingQuestions: [],
442
454
  },
443
455
  meta: {
444
456
  title: 'Session 1',
@@ -455,6 +467,8 @@ describe('DataImporter', () => {
455
467
  params: {},
456
468
  systemRole: 'abc',
457
469
  tts: {} as any,
470
+ openingQuestions: [],
471
+ openingMessage: `Hello, I'm Agent 2, learn more from [xxx](https://xxx.com)`,
458
472
  },
459
473
  meta: {
460
474
  title: 'Session 2',
@@ -507,6 +521,7 @@ describe('DataImporter', () => {
507
521
  params: {},
508
522
  systemRole: 'abc',
509
523
  tts: {} as any,
524
+ openingQuestions: [],
510
525
  },
511
526
  meta: {
512
527
  title: 'Session 1',
@@ -582,6 +597,7 @@ describe('DataImporter', () => {
582
597
  params: {},
583
598
  systemRole: 'abc',
584
599
  tts: {} as any,
600
+ openingQuestions: [],
585
601
  },
586
602
  meta: {
587
603
  title: 'Session 1',
@@ -661,6 +677,7 @@ describe('DataImporter', () => {
661
677
  params: {},
662
678
  systemRole: 'abc',
663
679
  tts: {} as any,
680
+ openingQuestions: [],
664
681
  },
665
682
  meta: {
666
683
  title: 'Session 1',
@@ -872,6 +889,8 @@ describe('DataImporter', () => {
872
889
  enableAutoCreateTopic: true,
873
890
  historyCount: 1,
874
891
  },
892
+ openingQuestions: ['Question 1', 'Question 2'],
893
+ openingMessage: `Hello, I'm Agent 1, learn more from [xxx](https://xxx.com)`,
875
894
  },
876
895
  group: 'XlUbvOvL',
877
896
  meta: {
@@ -54,6 +54,9 @@ export const agents = pgTable(
54
54
  systemRole: text('system_role'),
55
55
  tts: jsonb('tts').$type<LobeAgentTTSConfig>(),
56
56
 
57
+ openingMessage: text('opening_message'),
58
+ openingQuestions: text('opening_questions').array().default([]),
59
+
57
60
  ...timestamps,
58
61
  },
59
62
  (t) => ({
@@ -0,0 +1,80 @@
1
+ 'use client';
2
+
3
+ import { EditableMessage } from '@lobehub/ui';
4
+ import { Button } from 'antd';
5
+ import { createStyles } from 'antd-style';
6
+ import { PencilLine } from 'lucide-react';
7
+ import { memo, useCallback, useState } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { Flexbox } from 'react-layout-kit';
10
+
11
+ import { useStore } from '../store';
12
+ import { selectors } from '../store/selectors';
13
+
14
+ export const useStyles = createStyles(({ css, token }) => ({
15
+ markdown: css`
16
+ border: unset;
17
+ `,
18
+ wrapper: css`
19
+ width: 100%;
20
+ padding: 8px;
21
+ border: 1px solid ${token.colorBorder};
22
+ border-radius: ${token.borderRadiusLG - 1}px;
23
+
24
+ background: ${token.colorBgContainer};
25
+ `,
26
+ }));
27
+
28
+ const OpeningMessage = memo(() => {
29
+ const { t } = useTranslation('setting');
30
+ const { styles } = useStyles();
31
+
32
+ const openingMessage = useStore(selectors.openingMessage);
33
+ const updateConfig = useStore((s) => s.setAgentConfig);
34
+ const setOpeningMessage = useCallback(
35
+ (message: string) => {
36
+ updateConfig({ openingMessage: message });
37
+ },
38
+ [updateConfig],
39
+ );
40
+
41
+ const [editing, setEditing] = useState(false);
42
+
43
+ const handleEdit = useCallback(() => {
44
+ setEditing(true);
45
+ }, []);
46
+
47
+ const editIconButton = !editing && openingMessage && (
48
+ <Button onClick={handleEdit} size={'small'}>
49
+ <PencilLine size={16} />
50
+ </Button>
51
+ );
52
+
53
+ return (
54
+ <div className={styles.wrapper}>
55
+ <Flexbox direction={'horizontal'}>
56
+ <EditableMessage
57
+ classNames={{
58
+ markdown: styles.markdown,
59
+ }}
60
+ editButtonSize={'small'}
61
+ editing={editing}
62
+ height={'auto'}
63
+ inputType={'pure'}
64
+ onChange={setOpeningMessage}
65
+ onEditingChange={setEditing}
66
+ placeholder={t('settingOpening.openingMessage.placeholder')}
67
+ showEditWhenEmpty
68
+ text={{
69
+ cancel: t('cancel', { ns: 'common' }),
70
+ confirm: t('ok', { ns: 'common' }),
71
+ }}
72
+ value={openingMessage ?? ''}
73
+ />
74
+ {editIconButton}
75
+ </Flexbox>
76
+ </div>
77
+ );
78
+ });
79
+
80
+ export default OpeningMessage;
@@ -0,0 +1,144 @@
1
+ 'use client';
2
+
3
+ import { DeleteOutlined, PlusOutlined } from '@ant-design/icons';
4
+ import { SortableList } from '@lobehub/ui';
5
+ import { Button, Empty, Input } from 'antd';
6
+ import { createStyles } from 'antd-style';
7
+ import { memo, useCallback, useMemo, useState } from 'react';
8
+ import { useTranslation } from 'react-i18next';
9
+ import { Flexbox } from 'react-layout-kit';
10
+
11
+ import { useStore } from '../store';
12
+ import { selectors } from '../store/selectors';
13
+
14
+ const useStyles = createStyles(({ css, token }) => ({
15
+ empty: css`
16
+ margin-block: 24px;
17
+ margin-inline: 0;
18
+ `,
19
+ questionItemContainer: css`
20
+ margin-block-end: 8px;
21
+ padding-block: 2px;
22
+ padding-inline: 10px 0;
23
+ background: ${token.colorBgContainer};
24
+ `,
25
+ questionItemContent: css`
26
+ flex: 1;
27
+ `,
28
+ questionsList: css`
29
+ width: 100%;
30
+ margin-block-start: 16px;
31
+ `,
32
+ repeatError: css`
33
+ margin: 0;
34
+ color: ${token.colorErrorText};
35
+ `,
36
+ }));
37
+
38
+ interface QuestionItem {
39
+ content: string;
40
+ id: number;
41
+ }
42
+
43
+ const OpeningQuestions = memo(() => {
44
+ const { t } = useTranslation('setting');
45
+ const { styles } = useStyles();
46
+ const [questionInput, setQuestionInput] = useState('');
47
+
48
+ const openingQuestions = useStore(selectors.openingQuestions);
49
+ const updateConfig = useStore((s) => s.setAgentConfig);
50
+ const setQuestions = useCallback(
51
+ (questions: string[]) => {
52
+ updateConfig({ openingQuestions: questions });
53
+ },
54
+ [updateConfig],
55
+ );
56
+
57
+ const addQuestion = useCallback(() => {
58
+ if (!questionInput.trim()) return;
59
+
60
+ setQuestions([...openingQuestions, questionInput.trim()]);
61
+ setQuestionInput('');
62
+ }, [openingQuestions, questionInput, setQuestions]);
63
+
64
+ const removeQuestion = useCallback(
65
+ (content: string) => {
66
+ const newQuestions = [...openingQuestions];
67
+ const index = newQuestions.indexOf(content);
68
+ newQuestions.splice(index, 1);
69
+ setQuestions(newQuestions);
70
+ },
71
+ [openingQuestions, setQuestions],
72
+ );
73
+
74
+ // 处理拖拽排序后的逻辑
75
+ const handleSortEnd = useCallback(
76
+ (items: QuestionItem[]) => {
77
+ setQuestions(items.map((item) => item.content));
78
+ },
79
+ [setQuestions],
80
+ );
81
+
82
+ const items: QuestionItem[] = useMemo(() => {
83
+ return openingQuestions.map((item, index) => ({
84
+ content: item,
85
+ id: index,
86
+ }));
87
+ }, [openingQuestions]);
88
+
89
+ const isRepeat = openingQuestions.includes(questionInput.trim());
90
+
91
+ return (
92
+ <Flexbox gap={8}>
93
+ <Flexbox gap={4}>
94
+ <Input
95
+ addonAfter={
96
+ <Button
97
+ // don't allow repeat
98
+ disabled={openingQuestions.includes(questionInput.trim())}
99
+ icon={<PlusOutlined />}
100
+ onClick={addQuestion}
101
+ size="small"
102
+ type="text"
103
+ />
104
+ }
105
+ onChange={(e) => setQuestionInput(e.target.value)}
106
+ onPressEnter={addQuestion}
107
+ placeholder={t('settingOpening.openingQuestions.placeholder')}
108
+ value={questionInput}
109
+ />
110
+
111
+ {isRepeat && (
112
+ <p className={styles.repeatError}>{t('settingOpening.openingQuestions.repeat')}</p>
113
+ )}
114
+ </Flexbox>
115
+
116
+ <div className={styles.questionsList}>
117
+ {openingQuestions.length > 0 ? (
118
+ <SortableList
119
+ items={items}
120
+ onChange={handleSortEnd}
121
+ renderItem={(item) => (
122
+ <SortableList.Item className={styles.questionItemContainer} id={item.id}>
123
+ <SortableList.DragHandle />
124
+ <div className={styles.questionItemContent}>{item.content}</div>
125
+ <Button
126
+ icon={<DeleteOutlined />}
127
+ onClick={() => removeQuestion(item.content)}
128
+ type="text"
129
+ />
130
+ </SortableList.Item>
131
+ )}
132
+ />
133
+ ) : (
134
+ <Empty
135
+ className={styles.empty}
136
+ description={t('settingOpening.openingQuestions.empty')}
137
+ />
138
+ )}
139
+ </div>
140
+ </Flexbox>
141
+ );
142
+ });
143
+
144
+ export default OpeningQuestions;
@@ -0,0 +1,52 @@
1
+ 'use client';
2
+
3
+ import { Form } from '@lobehub/ui';
4
+ import { memo } from 'react';
5
+ import { useTranslation } from 'react-i18next';
6
+
7
+ import { FORM_STYLE } from '@/const/layoutTokens';
8
+
9
+ import OpeningMessage from './OpeningMessage';
10
+ import OpeningQuestions from './OpeningQuestions';
11
+
12
+ const wrapperCol = {
13
+ style: {
14
+ maxWidth: '100%',
15
+ width: '100%',
16
+ },
17
+ };
18
+
19
+ const AgentOpening = memo(() => {
20
+ const { t } = useTranslation('setting');
21
+
22
+ return (
23
+ <Form
24
+ items={[
25
+ {
26
+ children: [
27
+ {
28
+ children: <OpeningMessage />,
29
+ desc: t('settingOpening.openingMessage.desc'),
30
+ label: t('settingOpening.openingMessage.title'),
31
+ layout: 'vertical',
32
+ wrapperCol,
33
+ },
34
+ {
35
+ children: <OpeningQuestions />,
36
+ desc: t('settingOpening.openingQuestions.desc'),
37
+ label: t('settingOpening.openingQuestions.title'),
38
+ layout: 'vertical',
39
+ wrapperCol,
40
+ },
41
+ ],
42
+ title: t('settingOpening.title'),
43
+ },
44
+ ]}
45
+ itemsType={'group'}
46
+ variant={'pure'}
47
+ {...FORM_STYLE}
48
+ />
49
+ );
50
+ });
51
+
52
+ export default AgentOpening;
@@ -6,6 +6,9 @@ import { Store } from './action';
6
6
  const chatConfig = (s: Store): LobeAgentChatConfig =>
7
7
  s.config.chatConfig || DEFAULT_AGENT_CHAT_CONFIG;
8
8
 
9
+ export const DEFAULT_OPENING_QUESTIONS: string[] = [];
9
10
  export const selectors = {
10
11
  chatConfig,
12
+ openingMessage: (s: Store) => s.config.openingMessage,
13
+ openingQuestions: (s: Store) => s.config.openingQuestions || DEFAULT_OPENING_QUESTIONS,
11
14
  };
@@ -6,6 +6,7 @@ export default {
6
6
  chat: '聊天偏好',
7
7
  meta: '助手信息',
8
8
  modal: '模型设置',
9
+ opening: '开场设置',
9
10
  plugin: '插件设置',
10
11
  prompt: '角色设定',
11
12
  tts: '语音服务',
@@ -255,6 +256,21 @@ export default {
255
256
  title: '思维开放度',
256
257
  },
257
258
  },
259
+ settingOpening: {
260
+ openingMessage: {
261
+ desc: '打开会话时的开场消息,用来介绍助手的功能',
262
+ placeholder: '你好,我是自定义助手。你可以立即与我开始对话,也可以前往助手设置完善我的信息。',
263
+ title: '开场消息',
264
+ },
265
+ openingQuestions: {
266
+ desc: '会话开始时展示的引导性问题',
267
+ empty: '暂无问题',
268
+ placeholder: '请输入问题',
269
+ repeat: '问题已存在',
270
+ title: '开场问题',
271
+ },
272
+ title: '开场设置',
273
+ },
258
274
  settingPlugin: {
259
275
  title: '插件列表',
260
276
  },
@@ -29,6 +29,8 @@ export interface V6AgentConfig {
29
29
  chatConfig: ChatConfig;
30
30
  fewShots?: FewShots;
31
31
  model: string;
32
+ openingMessage?: string;
33
+ openingQuestions?: string[];
32
34
  params: LLMParams;
33
35
  plugins?: string[];
34
36
  provider?: string;
@@ -76,7 +76,14 @@ export const sessionRouter = router({
76
76
  .input(
77
77
  z.object({
78
78
  config: insertAgentSchema
79
- .omit({ chatConfig: true, plugins: true, tags: true, tts: true })
79
+ .omit({
80
+ chatConfig: true,
81
+ openingMessage: true,
82
+ openingQuestions: true,
83
+ plugins: true,
84
+ tags: true,
85
+ tts: true,
86
+ })
80
87
  .passthrough()
81
88
  .partial(),
82
89
  session: insertSessionSchema.omit({ createdAt: true, updatedAt: true }).partial(),
@@ -10,6 +10,7 @@ import { authedProcedure, router } from '@/libs/trpc/lambda';
10
10
  import { SearXNGClient } from '@/server/modules/SearXNG';
11
11
  import { SEARCH_SEARXNG_NOT_CONFIG } from '@/types/tool/search';
12
12
 
13
+ // TODO: password procedure 未来的处理方式可能要思考下
13
14
  const searchProcedure = isServerMode ? authedProcedure : passwordProcedure;
14
15
 
15
16
  export const searchRouter = router({
@@ -180,6 +180,7 @@ class ChatService {
180
180
  )(getAiInfraStoreState());
181
181
 
182
182
  const useModelSearch = isModelHasBuiltinSearch && chatConfig.useModelBuiltinSearch;
183
+
183
184
  const useApplicationBuiltinSearchTool = enabledSearch && !useModelSearch;
184
185
 
185
186
  const pluginIds = [...(enabledPlugins || [])];
@@ -102,6 +102,7 @@ describe('ImporterService', () => {
102
102
  params: {},
103
103
  systemRole: 'abc',
104
104
  tts: {} as any,
105
+ openingQuestions: [],
105
106
  },
106
107
  meta: {
107
108
  title: 'Session 1',
@@ -118,6 +119,7 @@ describe('ImporterService', () => {
118
119
  params: {},
119
120
  systemRole: 'abc',
120
121
  tts: {} as any,
122
+ openingQuestions: [],
121
123
  },
122
124
  meta: {
123
125
  title: 'Session 2',
@@ -169,6 +171,7 @@ describe('ImporterService', () => {
169
171
  params: {},
170
172
  systemRole: 'abc',
171
173
  tts: {} as any,
174
+ openingQuestions: [],
172
175
  },
173
176
  meta: {
174
177
  title: 'Session 1',
@@ -185,6 +188,7 @@ describe('ImporterService', () => {
185
188
  params: {},
186
189
  systemRole: 'abc',
187
190
  tts: {} as any,
191
+ openingQuestions: [],
188
192
  },
189
193
  meta: {
190
194
  title: 'Session 2',
@@ -225,6 +229,7 @@ describe('ImporterService', () => {
225
229
  params: {},
226
230
  systemRole: 'abc',
227
231
  tts: {} as any,
232
+ openingQuestions: [],
228
233
  },
229
234
  meta: {
230
235
  title: 'Session 1',
@@ -242,6 +247,7 @@ describe('ImporterService', () => {
242
247
  params: {},
243
248
  systemRole: 'abc',
244
249
  tts: {} as any,
250
+ openingQuestions: [],
245
251
  },
246
252
  meta: {
247
253
  title: 'Session 2',
@@ -259,6 +265,7 @@ describe('ImporterService', () => {
259
265
  params: {},
260
266
  systemRole: 'abc',
261
267
  tts: {} as any,
268
+ openingQuestions: [],
262
269
  },
263
270
  meta: {
264
271
  title: 'Session 3',
@@ -310,6 +317,7 @@ describe('ImporterService', () => {
310
317
  params: {},
311
318
  systemRole: 'Test Agent 1',
312
319
  tts: {} as any,
320
+ openingQuestions: [],
313
321
  },
314
322
  meta: {
315
323
  title: 'Session 1',
@@ -326,6 +334,7 @@ describe('ImporterService', () => {
326
334
  params: {},
327
335
  systemRole: 'Test Agent 2',
328
336
  tts: {} as any,
337
+ openingQuestions: [],
329
338
  },
330
339
  meta: {
331
340
  title: 'Session 2',
@@ -390,6 +399,7 @@ describe('ImporterService', () => {
390
399
  params: {},
391
400
  systemRole: 'Test Agent 1',
392
401
  tts: {} as any,
402
+ openingQuestions: [],
393
403
  },
394
404
  meta: {
395
405
  title: 'Session 1',
@@ -413,6 +423,7 @@ describe('ImporterService', () => {
413
423
  params: {},
414
424
  systemRole: 'Test Agent 1',
415
425
  tts: {} as any,
426
+ openingQuestions: [],
416
427
  },
417
428
  meta: {
418
429
  title: 'Session 1',
@@ -462,6 +473,7 @@ describe('ImporterService', () => {
462
473
  params: {},
463
474
  systemRole: 'abc',
464
475
  tts: {} as any,
476
+ openingQuestions: [],
465
477
  },
466
478
  meta: {
467
479
  title: 'Session 1',
@@ -478,6 +490,7 @@ describe('ImporterService', () => {
478
490
  params: {},
479
491
  systemRole: 'abc',
480
492
  tts: {} as any,
493
+ openingQuestions: [],
481
494
  },
482
495
  meta: {
483
496
  title: 'Session 2',
@@ -544,6 +557,7 @@ describe('ImporterService', () => {
544
557
  params: {},
545
558
  systemRole: 'abc',
546
559
  tts: {} as any,
560
+ openingQuestions: [],
547
561
  },
548
562
  meta: {
549
563
  title: 'Session 1',
@@ -619,6 +633,7 @@ describe('ImporterService', () => {
619
633
  params: {},
620
634
  systemRole: 'abc',
621
635
  tts: {} as any,
636
+ openingQuestions: [],
622
637
  },
623
638
  meta: {
624
639
  title: 'Session 1',
@@ -711,6 +726,7 @@ describe('ImporterService', () => {
711
726
  params: {},
712
727
  systemRole: 'abc',
713
728
  tts: {} as any,
729
+ openingQuestions: [],
714
730
  },
715
731
  meta: {
716
732
  title: 'Session 1',
@@ -923,6 +939,8 @@ describe('ImporterService', () => {
923
939
  enableAutoCreateTopic: true,
924
940
  historyCount: 1,
925
941
  },
942
+ openingQuestions: ['Question 1', 'Question 2'],
943
+ openingMessage: 'Hello, I am [LobeChat](https://github.com/lobehub/lobe-chat).',
926
944
  },
927
945
  group: 'XlUbvOvL',
928
946
  meta: {
@@ -78,6 +78,8 @@ describe('ServerService', () => {
78
78
  openai: 'voice-id',
79
79
  },
80
80
  },
81
+ openingQuestions: ['Question 1', 'Question 2'],
82
+ openingMessage: 'Hello, I am [LobeChat](https://github.com/lobehub/lobe-chat).',
81
83
  },
82
84
  group: 'testGroup',
83
85
  meta: { description: 'test' },
@@ -12,12 +12,13 @@ exports[`agentSelectors > defaultAgentConfig > should merge DEFAULT_AGENT_CONFIG
12
12
  "historyCount": 8,
13
13
  "reasoningBudgetToken": 1024,
14
14
  "searchFCModel": {
15
- "model": "gpt-4o-mini",
15
+ "model": "gpt-4.1-mini",
16
16
  "provider": "openai",
17
17
  },
18
18
  "searchMode": "off",
19
19
  },
20
20
  "model": "gpt-3.5-turbo",
21
+ "openingQuestions": [],
21
22
  "params": {
22
23
  "frequency_penalty": 0,
23
24
  "presence_penalty": 0,