@lobehub/chat 1.134.3 → 1.134.5
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/.github/workflows/docker-database.yml +2 -0
- package/.github/workflows/docker-pglite.yml +2 -0
- package/.github/workflows/docker.yml +2 -0
- package/.github/workflows/release.yml +6 -0
- package/.github/workflows/sync-database-schema.yml +2 -0
- package/CHANGELOG.md +50 -0
- package/changelog/v1.json +14 -0
- package/docs/development/database-schema.dbml +27 -0
- package/package.json +3 -2
- package/packages/database/migrations/0036_add_group_messages.sql +21 -0
- package/packages/database/migrations/meta/0036_snapshot.json +6772 -0
- package/packages/database/migrations/meta/_journal.json +7 -0
- package/packages/database/package.json +1 -1
- package/packages/database/src/core/migrations.json +15 -0
- package/packages/database/src/models/__tests__/aiModel.test.ts +43 -0
- package/packages/database/src/models/aiModel.ts +25 -1
- package/packages/database/src/repositories/tableViewer/index.test.ts +1 -1
- package/packages/database/src/schemas/_helpers.ts +3 -1
- package/packages/database/src/schemas/message.ts +55 -4
- package/packages/database/src/schemas/relations.ts +24 -1
- package/packages/database/src/utils/idGenerator.ts +1 -0
- package/packages/prompts/CLAUDE.md +329 -0
- package/packages/prompts/README.md +224 -0
- package/packages/prompts/package.json +14 -1
- package/packages/prompts/promptfoo/emoji-picker/eval.yaml +170 -0
- package/packages/prompts/promptfoo/emoji-picker/prompt.ts +16 -0
- package/packages/prompts/promptfoo/knowledge-qa/eval.yaml +89 -0
- package/packages/prompts/promptfoo/knowledge-qa/prompt.ts +26 -0
- package/packages/prompts/promptfoo/language-detection/eval.yaml +65 -0
- package/packages/prompts/promptfoo/language-detection/prompt.ts +16 -0
- package/packages/prompts/promptfoo/summary-title/eval.yaml +85 -0
- package/packages/prompts/promptfoo/summary-title/prompt.ts +18 -0
- package/packages/prompts/promptfoo/translate/eval.yaml +79 -0
- package/packages/prompts/promptfoo/translate/prompt.ts +18 -0
- package/packages/prompts/promptfooconfig.yaml +35 -0
- package/packages/prompts/src/chains/__tests__/__snapshots__/answerWithContext.test.ts.snap +164 -0
- package/packages/prompts/src/chains/__tests__/__snapshots__/pickEmoji.test.ts.snap +58 -0
- package/packages/prompts/src/chains/__tests__/__snapshots__/summaryTitle.test.ts.snap +26 -0
- package/packages/prompts/src/chains/__tests__/__snapshots__/translate.test.ts.snap +22 -0
- package/packages/prompts/src/chains/__tests__/answerWithContext.test.ts +18 -63
- package/packages/prompts/src/chains/__tests__/pickEmoji.test.ts +2 -37
- package/packages/prompts/src/chains/__tests__/summaryTitle.test.ts +2 -16
- package/packages/prompts/src/chains/__tests__/translate.test.ts +1 -12
- package/packages/prompts/src/chains/answerWithContext.ts +45 -21
- package/packages/prompts/src/chains/pickEmoji.ts +20 -6
- package/packages/prompts/src/chains/summaryTitle.ts +20 -15
- package/packages/prompts/src/chains/translate.ts +8 -2
|
@@ -11,25 +11,11 @@ describe('chainSummaryTitle', () => {
|
|
|
11
11
|
{ content: 'I need help with my account.', role: 'user' },
|
|
12
12
|
];
|
|
13
13
|
const currentLanguage = 'en-US';
|
|
14
|
-
const tokenCount = 10000; // Arbitrary token count below the GPT-3.5 limit
|
|
15
14
|
|
|
16
15
|
// Act
|
|
17
|
-
const result =
|
|
16
|
+
const result = chainSummaryTitle(messages, currentLanguage);
|
|
18
17
|
|
|
19
18
|
// Assert
|
|
20
|
-
expect(result).
|
|
21
|
-
messages: [
|
|
22
|
-
{
|
|
23
|
-
content: '你是一名擅长会话的助理,你需要将用户的会话总结为 10 个字以内的标题',
|
|
24
|
-
role: 'system',
|
|
25
|
-
},
|
|
26
|
-
{
|
|
27
|
-
content: `assistant: Hello, how can I assist you?\nuser: I need help with my account.
|
|
28
|
-
|
|
29
|
-
请总结上述对话为10个字以内的标题,不需要包含标点符号,输出语言语种为:${currentLanguage}`,
|
|
30
|
-
role: 'user',
|
|
31
|
-
},
|
|
32
|
-
],
|
|
33
|
-
});
|
|
19
|
+
expect(result).toMatchSnapshot();
|
|
34
20
|
});
|
|
35
21
|
});
|
|
@@ -12,17 +12,6 @@ describe('chainTranslate', () => {
|
|
|
12
12
|
const result = chainTranslate(content, targetLang);
|
|
13
13
|
|
|
14
14
|
// Assert
|
|
15
|
-
expect(result).
|
|
16
|
-
messages: [
|
|
17
|
-
{
|
|
18
|
-
content: '你是一名擅长翻译的助理,你需要将输入的语言翻译为目标语言',
|
|
19
|
-
role: 'system',
|
|
20
|
-
},
|
|
21
|
-
{
|
|
22
|
-
content: `请将以下内容 ${content},翻译为 ${targetLang} `,
|
|
23
|
-
role: 'user',
|
|
24
|
-
},
|
|
25
|
-
],
|
|
26
|
-
});
|
|
15
|
+
expect(result).toMatchSnapshot();
|
|
27
16
|
});
|
|
28
17
|
});
|
|
@@ -1,33 +1,57 @@
|
|
|
1
1
|
import { ChatStreamPayload } from '@lobechat/types';
|
|
2
2
|
|
|
3
|
+
interface AnswerWithContext {
|
|
4
|
+
context: string[];
|
|
5
|
+
knowledge: string[];
|
|
6
|
+
question: string;
|
|
7
|
+
}
|
|
3
8
|
export const chainAnswerWithContext = ({
|
|
4
9
|
context,
|
|
5
10
|
knowledge,
|
|
6
11
|
question,
|
|
7
|
-
}: {
|
|
8
|
-
context
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
12
|
+
}: AnswerWithContext): Partial<ChatStreamPayload> => {
|
|
13
|
+
const filteredContext = context.filter((c) => c.trim());
|
|
14
|
+
const hasContext = filteredContext.length > 0;
|
|
15
|
+
|
|
16
|
+
return {
|
|
17
|
+
messages: [
|
|
18
|
+
{
|
|
19
|
+
content: hasContext
|
|
20
|
+
? `You are a helpful assistant specialized in ${knowledge.join('/')}. Your task is to answer questions based on the provided context passages.
|
|
21
|
+
|
|
22
|
+
IMPORTANT RULES:
|
|
23
|
+
- First, check if the context is relevant to the question topic
|
|
24
|
+
- If the context is about a COMPLETELY DIFFERENT topic than the question:
|
|
25
|
+
* State what topic the context is about
|
|
26
|
+
* Clearly state "The provided context does not contain information about [question topic]"
|
|
27
|
+
* Do NOT answer using your general knowledge
|
|
28
|
+
- If the context is related to the question topic (even if information is limited):
|
|
29
|
+
* ALWAYS use the context information as a foundation
|
|
30
|
+
* You SHOULD supplement with your general knowledge to provide a complete, helpful answer
|
|
31
|
+
* For "how to" questions, MUST provide practical, actionable steps combining context + your expertise
|
|
32
|
+
* The context provides the topic relevance - you provide the comprehensive answer
|
|
33
|
+
* Example: If context mentions "Docker is for containerization", and question is "How to deploy with Docker?", you should explain deployment steps using your knowledge
|
|
34
|
+
- Answer in the same language as the question
|
|
35
|
+
- Use markdown formatting for better readability
|
|
36
|
+
|
|
37
|
+
The provided context passages:
|
|
15
38
|
|
|
16
|
-
|
|
39
|
+
<context>
|
|
40
|
+
${filteredContext.join('\n')}
|
|
41
|
+
</context>
|
|
17
42
|
|
|
18
|
-
|
|
43
|
+
Question to answer:
|
|
19
44
|
|
|
20
|
-
|
|
45
|
+
${question}`
|
|
46
|
+
: `You are a helpful assistant specialized in ${knowledge.join('/')}. Please answer the following question using your knowledge.
|
|
21
47
|
|
|
22
|
-
|
|
23
|
-
${context.join('\n')}
|
|
24
|
-
</Context>
|
|
48
|
+
Answer in the same language as the question and use markdown formatting for better readability.
|
|
25
49
|
|
|
26
|
-
|
|
50
|
+
Question to answer:
|
|
27
51
|
|
|
28
|
-
${question}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
52
|
+
${question}`,
|
|
53
|
+
role: 'user',
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
};
|
|
57
|
+
};
|
|
@@ -7,25 +7,39 @@ import { ChatStreamPayload } from '@lobechat/types';
|
|
|
7
7
|
export const chainPickEmoji = (content: string): Partial<ChatStreamPayload> => ({
|
|
8
8
|
messages: [
|
|
9
9
|
{
|
|
10
|
-
content:
|
|
11
|
-
|
|
10
|
+
content: `You are an emoji expert who selects the most appropriate emoji to represent concepts, emotions, or topics.
|
|
11
|
+
|
|
12
|
+
Rules:
|
|
13
|
+
- Output ONLY a single emoji (1-2 characters maximum)
|
|
14
|
+
- Focus on the CONTENT meaning, not the language it's written in
|
|
15
|
+
- Choose an emoji that best represents the core topic, activity, or subject matter
|
|
16
|
+
- Prioritize topic-specific emojis over generic emotion emojis (e.g., for sports, use 🏃 instead of 😅)
|
|
17
|
+
- For work/projects, use work-related emojis (💼, 🚀, 💪) not cultural symbols
|
|
18
|
+
- For pure emotions without specific topics, use face emojis (happy: 🎉, sad: 😢, thinking: 🤔)
|
|
19
|
+
- For activities or subjects, use object or symbol emojis that represent the main topic
|
|
20
|
+
- No explanations or additional text`,
|
|
12
21
|
role: 'system',
|
|
13
22
|
},
|
|
14
23
|
{
|
|
15
|
-
content:
|
|
24
|
+
content: 'I am a copywriting master who helps name design and art works with literary depth',
|
|
16
25
|
role: 'user',
|
|
17
26
|
},
|
|
18
27
|
{ content: '✒️', role: 'assistant' },
|
|
19
28
|
{
|
|
20
|
-
content:
|
|
29
|
+
content: 'I am a code wizard who converts JavaScript code to TypeScript',
|
|
21
30
|
role: 'user',
|
|
22
31
|
},
|
|
23
32
|
{ content: '🧙♂️', role: 'assistant' },
|
|
24
33
|
{
|
|
25
|
-
content:
|
|
34
|
+
content: 'I just got a promotion at work',
|
|
35
|
+
role: 'user',
|
|
36
|
+
},
|
|
37
|
+
{ content: '🎉', role: 'assistant' },
|
|
38
|
+
{
|
|
39
|
+
content: 'I am a business plan expert who helps with startup strategies and marketing',
|
|
26
40
|
role: 'user',
|
|
27
41
|
},
|
|
28
42
|
{ content: '🚀', role: 'assistant' },
|
|
29
|
-
{ content
|
|
43
|
+
{ content, role: 'user' },
|
|
30
44
|
],
|
|
31
45
|
});
|
|
@@ -3,19 +3,24 @@ import { ChatStreamPayload, OpenAIChatMessage } from '@/types/openai/chat';
|
|
|
3
3
|
export const chainSummaryTitle = (
|
|
4
4
|
messages: OpenAIChatMessage[],
|
|
5
5
|
locale: string,
|
|
6
|
-
): Partial<ChatStreamPayload> => {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
content: '你是一名擅长会话的助理,你需要将用户的会话总结为 10 个字以内的标题',
|
|
11
|
-
role: 'system',
|
|
12
|
-
},
|
|
13
|
-
{
|
|
14
|
-
content: `${messages.map((message) => `${message.role}: ${message.content}`).join('\n')}
|
|
6
|
+
): Partial<ChatStreamPayload> => ({
|
|
7
|
+
messages: [
|
|
8
|
+
{
|
|
9
|
+
content: `You are a professional conversation summarizer. Generate a concise title that captures the essence of the conversation.
|
|
15
10
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
}
|
|
11
|
+
Rules:
|
|
12
|
+
- Output ONLY the title text, no explanations or additional context
|
|
13
|
+
- Maximum 10 words
|
|
14
|
+
- Maximum 50 characters
|
|
15
|
+
- No punctuation marks
|
|
16
|
+
- Use the language specified by the locale code: ${locale}
|
|
17
|
+
- The title should accurately reflect the main topic of the conversation
|
|
18
|
+
- Keep it short and to the point`,
|
|
19
|
+
role: 'system',
|
|
20
|
+
},
|
|
21
|
+
{
|
|
22
|
+
content: messages.map((message) => `${message.role}: ${message.content}`).join('\n'),
|
|
23
|
+
role: 'user',
|
|
24
|
+
},
|
|
25
|
+
],
|
|
26
|
+
});
|
|
@@ -6,11 +6,17 @@ export const chainTranslate = (
|
|
|
6
6
|
): Partial<ChatStreamPayload> => ({
|
|
7
7
|
messages: [
|
|
8
8
|
{
|
|
9
|
-
content:
|
|
9
|
+
content: `You are a professional translator. Translate the input text to ${targetLang}.
|
|
10
|
+
|
|
11
|
+
Rules:
|
|
12
|
+
- Output ONLY the translated text, no explanations or additional context
|
|
13
|
+
- Preserve technical terms, code identifiers, API keys, and proper nouns exactly as they appear
|
|
14
|
+
- Maintain the original formatting and structure
|
|
15
|
+
- Use natural, idiomatic expressions in the target language`,
|
|
10
16
|
role: 'system',
|
|
11
17
|
},
|
|
12
18
|
{
|
|
13
|
-
content
|
|
19
|
+
content,
|
|
14
20
|
role: 'user',
|
|
15
21
|
},
|
|
16
22
|
],
|