@lobehub/chat 1.136.8 → 1.136.10
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 +50 -0
- package/changelog/v1.json +18 -0
- package/locales/ar/common.json +1 -0
- package/locales/ar/hotkey.json +8 -0
- package/locales/ar/labs.json +14 -0
- package/locales/bg-BG/common.json +1 -0
- package/locales/bg-BG/hotkey.json +8 -0
- package/locales/bg-BG/labs.json +14 -0
- package/locales/de-DE/common.json +1 -0
- package/locales/de-DE/hotkey.json +8 -0
- package/locales/de-DE/labs.json +14 -0
- package/locales/en-US/common.json +1 -0
- package/locales/en-US/hotkey.json +8 -0
- package/locales/en-US/labs.json +14 -0
- package/locales/es-ES/common.json +1 -0
- package/locales/es-ES/hotkey.json +8 -0
- package/locales/es-ES/labs.json +14 -0
- package/locales/fa-IR/common.json +1 -0
- package/locales/fa-IR/hotkey.json +8 -0
- package/locales/fa-IR/labs.json +14 -0
- package/locales/fr-FR/common.json +1 -0
- package/locales/fr-FR/hotkey.json +8 -0
- package/locales/fr-FR/labs.json +14 -0
- package/locales/it-IT/common.json +1 -0
- package/locales/it-IT/hotkey.json +8 -0
- package/locales/it-IT/labs.json +14 -0
- package/locales/ja-JP/common.json +1 -0
- package/locales/ja-JP/hotkey.json +8 -0
- package/locales/ja-JP/labs.json +14 -0
- package/locales/ko-KR/common.json +1 -0
- package/locales/ko-KR/hotkey.json +8 -0
- package/locales/ko-KR/labs.json +14 -0
- package/locales/nl-NL/common.json +1 -0
- package/locales/nl-NL/hotkey.json +8 -0
- package/locales/nl-NL/labs.json +14 -0
- package/locales/pl-PL/common.json +1 -0
- package/locales/pl-PL/hotkey.json +8 -0
- package/locales/pl-PL/labs.json +14 -0
- package/locales/pt-BR/common.json +1 -0
- package/locales/pt-BR/hotkey.json +8 -0
- package/locales/pt-BR/labs.json +14 -0
- package/locales/ru-RU/common.json +1 -0
- package/locales/ru-RU/hotkey.json +8 -0
- package/locales/ru-RU/labs.json +14 -0
- package/locales/tr-TR/common.json +1 -0
- package/locales/tr-TR/hotkey.json +8 -0
- package/locales/tr-TR/labs.json +14 -0
- package/locales/vi-VN/common.json +1 -0
- package/locales/vi-VN/hotkey.json +8 -0
- package/locales/vi-VN/labs.json +14 -0
- package/locales/zh-CN/common.json +1 -0
- package/locales/zh-CN/hotkey.json +8 -0
- package/locales/zh-CN/labs.json +14 -0
- package/locales/zh-TW/common.json +1 -0
- package/locales/zh-TW/hotkey.json +8 -0
- package/locales/zh-TW/labs.json +14 -0
- package/package.json +1 -1
- package/packages/prompts/package.json +1 -0
- package/packages/prompts/promptfoo/abstract-chunk/eval.yaml +111 -0
- package/packages/prompts/promptfoo/abstract-chunk/prompt.ts +16 -0
- package/packages/prompts/promptfooconfig.yaml +1 -0
- package/packages/prompts/src/chains/__tests__/__snapshots__/abstractChunk.test.ts.snap +38 -0
- package/packages/prompts/src/chains/__tests__/abstractChunk.test.ts +2 -21
- package/packages/prompts/src/chains/abstractChunk.ts +24 -3
- package/packages/prompts/src/prompts/index.ts +1 -0
- package/packages/prompts/src/prompts/search/crawlResults.test.ts +172 -0
- package/packages/prompts/src/prompts/search/crawlResults.ts +82 -0
- package/packages/prompts/src/prompts/search/index.ts +2 -0
- package/packages/prompts/src/prompts/search/searchResults.test.ts +138 -0
- package/packages/prompts/src/prompts/search/searchResults.ts +58 -0
- package/packages/prompts/src/prompts/search/xmlEscape.ts +21 -0
- package/packages/types/src/tool/builtin.ts +8 -0
- package/packages/types/src/tool/index.ts +2 -0
- package/src/app/[variants]/(main)/_layout/Desktop/SideBar/BottomActions.tsx +12 -10
- package/src/app/[variants]/(main)/labs/components/LabCard.tsx +15 -4
- package/src/app/[variants]/(main)/labs/page.tsx +54 -27
- package/src/features/Conversation/Messages/Assistant/Tool/Inspector/BuiltinPluginTitle.tsx +17 -13
- package/src/features/Conversation/Messages/Assistant/Tool/Inspector/ToolTitle.tsx +1 -8
- package/src/features/Conversation/Messages/Assistant/Tool/Render/Arguments/index.tsx +12 -16
- package/src/features/Conversation/Messages/Assistant/Tool/Render/LoadingPlaceholder/index.tsx +29 -0
- package/src/features/Conversation/Messages/Assistant/Tool/Render/index.tsx +26 -7
- package/src/features/Conversation/Messages/Assistant/Tool/index.tsx +2 -0
- package/src/features/PluginsUI/Render/BuiltinType/index.test.tsx +5 -5
- package/src/features/PluginsUI/Render/BuiltinType/index.tsx +1 -7
- package/src/store/chat/slices/builtinTool/actions/search.test.ts +4 -3
- package/src/store/chat/slices/builtinTool/actions/search.ts +23 -15
- package/src/store/chat/slices/message/selectors.ts +10 -0
- package/src/store/user/slices/preference/selectors.ts +1 -2
- package/src/styles/text.ts +10 -7
- package/src/tools/placeholders.ts +8 -0
- package/src/tools/web-browsing/Placeholder/PageContent.tsx +27 -0
- package/src/tools/web-browsing/Placeholder/Search.tsx +65 -0
- package/src/tools/web-browsing/Placeholder/index.tsx +40 -0
- package/src/tools/web-browsing/Render/PageContent/Loading.tsx +14 -5
- package/src/tools/web-browsing/Render/PageContent/Result.tsx +14 -13
- package/src/tools/web-browsing/Render/PageContent/index.tsx +15 -6
- package/src/tools/web-browsing/Render/Search/SearchQuery/SearchView.tsx +13 -19
- package/src/tools/web-browsing/Render/Search/SearchResult/index.tsx +21 -26
- package/src/tools/web-browsing/components/EngineAvatar.tsx +8 -2
- package/src/tools/web-browsing/const.ts +8 -1
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"desc": "Здесь мы будем периодически обновлять информацию о новых функциях, которые мы исследуем. Добро пожаловать на пробное использование!",
|
|
3
|
+
"features": {
|
|
4
|
+
"groupChat": {
|
|
5
|
+
"desc": "Включить возможность организации группового чата с несколькими интеллектуальными агентами.",
|
|
6
|
+
"title": "Групповой чат (мультиагенты)"
|
|
7
|
+
},
|
|
8
|
+
"inputMarkdown": {
|
|
9
|
+
"desc": "Мгновенная визуализация Markdown (жирный шрифт, блоки кода, таблицы и т.д.) в поле ввода.",
|
|
10
|
+
"title": "Рендеринг Markdown в поле ввода"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"title": "Лаборатория"
|
|
14
|
+
}
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
"desc": "Geçerli oturumun mesajlarını ve yüklenen dosyaları temizle",
|
|
8
8
|
"title": "Oturum mesajlarını temizle"
|
|
9
9
|
},
|
|
10
|
+
"deleteAndRegenerateMessage": {
|
|
11
|
+
"desc": "Son mesajı sil ve yeniden oluştur",
|
|
12
|
+
"title": "Sil ve Yeniden Oluştur"
|
|
13
|
+
},
|
|
14
|
+
"deleteLastMessage": {
|
|
15
|
+
"desc": "Son mesajı sil",
|
|
16
|
+
"title": "Son Mesajı Sil"
|
|
17
|
+
},
|
|
10
18
|
"desktop": {
|
|
11
19
|
"openSettings": {
|
|
12
20
|
"desc": "Uygulama ayarları sayfasını aç",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"desc": "Burada keşfetmekte olduğumuz yeni özellikleri düzenli olarak güncelliyoruz, denemekten çekinmeyin!",
|
|
3
|
+
"features": {
|
|
4
|
+
"groupChat": {
|
|
5
|
+
"desc": "Çoklu yapay zeka ajanlarıyla grup sohbeti düzenleme yeteneğini etkinleştirir.",
|
|
6
|
+
"title": "Grup Sohbeti (Çoklu Ajan)"
|
|
7
|
+
},
|
|
8
|
+
"inputMarkdown": {
|
|
9
|
+
"desc": "Giriş alanında Markdown biçimlendirmesini (kalın yazı, kod blokları, tablolar vb.) anında görüntüleyin.",
|
|
10
|
+
"title": "Giriş Kutusu Markdown Görüntüleme"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"title": "Deneysel Özellikler"
|
|
14
|
+
}
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
"desc": "Xóa tất cả tin nhắn và tệp đã tải lên trong cuộc trò chuyện hiện tại",
|
|
8
8
|
"title": "Xóa tin nhắn cuộc trò chuyện"
|
|
9
9
|
},
|
|
10
|
+
"deleteAndRegenerateMessage": {
|
|
11
|
+
"desc": "Xoá tin nhắn cuối cùng và tạo lại",
|
|
12
|
+
"title": "Xoá và tạo lại"
|
|
13
|
+
},
|
|
14
|
+
"deleteLastMessage": {
|
|
15
|
+
"desc": "Xoá tin nhắn cuối cùng",
|
|
16
|
+
"title": "Xoá tin nhắn cuối cùng"
|
|
17
|
+
},
|
|
10
18
|
"desktop": {
|
|
11
19
|
"openSettings": {
|
|
12
20
|
"desc": "Mở trang cài đặt ứng dụng",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"desc": "Tại đây, chúng tôi sẽ cập nhật định kỳ các tính năng mới đang được khám phá. Rất hoan nghênh bạn dùng thử!",
|
|
3
|
+
"features": {
|
|
4
|
+
"groupChat": {
|
|
5
|
+
"desc": "Kích hoạt khả năng điều phối trò chuyện nhóm với nhiều tác nhân thông minh.",
|
|
6
|
+
"title": "Trò chuyện nhóm (đa tác nhân)"
|
|
7
|
+
},
|
|
8
|
+
"inputMarkdown": {
|
|
9
|
+
"desc": "Hiển thị trực tiếp Markdown trong vùng nhập (in đậm, khối mã, bảng, v.v.).",
|
|
10
|
+
"title": "Hiển thị Markdown trong ô nhập"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"title": "Phòng thí nghiệm"
|
|
14
|
+
}
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
"desc": "清空当前会话的消息和上传的文件",
|
|
8
8
|
"title": "清空会话消息"
|
|
9
9
|
},
|
|
10
|
+
"deleteAndRegenerateMessage": {
|
|
11
|
+
"desc": "删除最后一条消息并重新生成",
|
|
12
|
+
"title": "删除并重新生成"
|
|
13
|
+
},
|
|
14
|
+
"deleteLastMessage": {
|
|
15
|
+
"desc": "删除最后一条消息",
|
|
16
|
+
"title": "删除最后一条消息"
|
|
17
|
+
},
|
|
10
18
|
"desktop": {
|
|
11
19
|
"openSettings": {
|
|
12
20
|
"desc": "打开应用设置页面",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"desc": "这里会不定期更新我们正在探索的新功能,欢迎试用!",
|
|
3
|
+
"features": {
|
|
4
|
+
"groupChat": {
|
|
5
|
+
"desc": "启用多智能体群聊编排能力。",
|
|
6
|
+
"title": "群聊(多智能体)"
|
|
7
|
+
},
|
|
8
|
+
"inputMarkdown": {
|
|
9
|
+
"desc": "在输入区域实时渲染 Markdown(粗体、代码块、表格等)。",
|
|
10
|
+
"title": "输入框 Markdown 渲染"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"title": "实验室"
|
|
14
|
+
}
|
|
@@ -7,6 +7,14 @@
|
|
|
7
7
|
"desc": "清空當前會話的消息和上傳的檔案",
|
|
8
8
|
"title": "清空會話消息"
|
|
9
9
|
},
|
|
10
|
+
"deleteAndRegenerateMessage": {
|
|
11
|
+
"desc": "刪除最後一則訊息並重新產生",
|
|
12
|
+
"title": "刪除並重新產生"
|
|
13
|
+
},
|
|
14
|
+
"deleteLastMessage": {
|
|
15
|
+
"desc": "刪除最後一則訊息",
|
|
16
|
+
"title": "刪除最後一則訊息"
|
|
17
|
+
},
|
|
10
18
|
"desktop": {
|
|
11
19
|
"openSettings": {
|
|
12
20
|
"desc": "打開應用設定頁面",
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
{
|
|
2
|
+
"desc": "這裡會不定期更新我們正在探索的新功能,歡迎試用!",
|
|
3
|
+
"features": {
|
|
4
|
+
"groupChat": {
|
|
5
|
+
"desc": "啟用多智能體群組聊天編排功能。",
|
|
6
|
+
"title": "群組聊天(多智能體)"
|
|
7
|
+
},
|
|
8
|
+
"inputMarkdown": {
|
|
9
|
+
"desc": "在輸入區即時渲染 Markdown(粗體、程式碼區塊、表格等)。",
|
|
10
|
+
"title": "輸入框 Markdown 渲染"
|
|
11
|
+
}
|
|
12
|
+
},
|
|
13
|
+
"title": "實驗室"
|
|
14
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lobehub/chat",
|
|
3
|
-
"version": "1.136.
|
|
3
|
+
"version": "1.136.10",
|
|
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",
|
|
@@ -9,6 +9,7 @@
|
|
|
9
9
|
"test": "vitest",
|
|
10
10
|
"test:coverage": "vitest --coverage --silent='passed-only'",
|
|
11
11
|
"test:prompts": "pnpm test:prompts:translate && pnpm test:prompts:summary && pnpm test:prompts:lang && pnpm test:prompts:emoji && pnpm test:prompts:qa",
|
|
12
|
+
"test:prompts:abstract-chunk": "promptfoo eval -c promptfoo/abstract-chunk/eval.yaml",
|
|
12
13
|
"test:prompts:emoji": "promptfoo eval -c promptfoo/emoji-picker/eval.yaml",
|
|
13
14
|
"test:prompts:lang": "promptfoo eval -c promptfoo/language-detection/eval.yaml",
|
|
14
15
|
"test:prompts:qa": "promptfoo eval -c promptfoo/knowledge-qa/eval.yaml",
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
description: Test chunk text summarization in different languages
|
|
2
|
+
|
|
3
|
+
providers:
|
|
4
|
+
- openai:chat:gpt-5-mini
|
|
5
|
+
- openai:chat:claude-3-5-haiku-latest
|
|
6
|
+
- openai:chat:gemini-flash-latest
|
|
7
|
+
- openai:chat:deepseek-chat
|
|
8
|
+
|
|
9
|
+
prompts:
|
|
10
|
+
- file://promptfoo/abstract-chunk/prompt.ts
|
|
11
|
+
|
|
12
|
+
tests:
|
|
13
|
+
# English technical content
|
|
14
|
+
- vars:
|
|
15
|
+
text: "React is a JavaScript library for building user interfaces. It was developed by Facebook and is now maintained by Facebook and the community. React makes it painless to create interactive UIs. Design simple views for each state in your application, and React will efficiently update and render just the right components when your data changes. Declarative views make your code more predictable and easier to debug."
|
|
16
|
+
assert:
|
|
17
|
+
- type: llm-rubric
|
|
18
|
+
provider: openai:gpt-5-mini
|
|
19
|
+
value: "The summary should be 1-2 sentences in English, capturing the main topic about React being a JavaScript library for UIs"
|
|
20
|
+
- type: contains-any
|
|
21
|
+
value: ["React", "JavaScript", "library", "UI", "user interface"]
|
|
22
|
+
- type: javascript
|
|
23
|
+
value: "output.split(/[.!?]/).filter(s => s.trim()).length <= 2" # At most 2 sentences
|
|
24
|
+
|
|
25
|
+
# Chinese content
|
|
26
|
+
- vars:
|
|
27
|
+
text: "深度学习是机器学习的一个分支,它使用多层神经网络来学习数据的表示。近年来,深度学习在图像识别、自然语言处理、语音识别等领域取得了突破性进展。卷积神经网络(CNN)在计算机视觉任务中表现优异,而循环神经网络(RNN)和Transformer架构在序列建模任务中非常有效。"
|
|
28
|
+
assert:
|
|
29
|
+
- type: llm-rubric
|
|
30
|
+
provider: openai:gpt-5-mini
|
|
31
|
+
value: "The summary should be 1-2 sentences in Chinese, summarizing deep learning and its applications"
|
|
32
|
+
- type: contains-any
|
|
33
|
+
value: ["深度学习", "神经网络", "机器学习"]
|
|
34
|
+
- type: not-contains
|
|
35
|
+
value: "摘要" # Should not contain meta labels
|
|
36
|
+
- type: javascript
|
|
37
|
+
value: "output.split(/[。!?]/).filter(s => s.trim()).length <= 2" # At most 2 sentences
|
|
38
|
+
|
|
39
|
+
# Japanese content
|
|
40
|
+
- vars:
|
|
41
|
+
text: "人工知能(AI)は、コンピュータシステムが人間の知能を模倣する技術です。AIは、学習、推論、問題解決などの認知機能を実行できます。現代のAIシステムは、大量のデータから学習し、パターンを認識して予測を行います。"
|
|
42
|
+
assert:
|
|
43
|
+
- type: llm-rubric
|
|
44
|
+
provider: openai:gpt-5-mini
|
|
45
|
+
value: "The summary should be 1-2 sentences in Japanese about artificial intelligence"
|
|
46
|
+
- type: contains-any
|
|
47
|
+
value: ["人工知能", "AI", "コンピュータ"]
|
|
48
|
+
- type: javascript
|
|
49
|
+
value: "output.split(/[。!?]/).filter(s => s.trim()).length <= 2"
|
|
50
|
+
|
|
51
|
+
# Spanish content
|
|
52
|
+
- vars:
|
|
53
|
+
text: "El cambio climático es uno de los mayores desafíos que enfrenta la humanidad en el siglo XXI. Las temperaturas globales están aumentando debido a las emisiones de gases de efecto invernadero producidas por actividades humanas como la quema de combustibles fósiles, la deforestación y la agricultura industrial. Los efectos incluyen el derretimiento de los glaciares, el aumento del nivel del mar y eventos climáticos extremos más frecuentes."
|
|
54
|
+
assert:
|
|
55
|
+
- type: llm-rubric
|
|
56
|
+
provider: openai:gpt-5-mini
|
|
57
|
+
value: "The summary should be 1-2 sentences in Spanish about climate change"
|
|
58
|
+
- type: contains-any
|
|
59
|
+
value: ["cambio climático", "temperatura", "clima"]
|
|
60
|
+
- type: javascript
|
|
61
|
+
value: "output.split(/[.!?]/).filter(s => s.trim()).length <= 2"
|
|
62
|
+
|
|
63
|
+
# Short technical content (English)
|
|
64
|
+
- vars:
|
|
65
|
+
text: "TypeScript is a strongly typed programming language that builds on JavaScript. It adds static type definitions to JavaScript, making code more robust and maintainable."
|
|
66
|
+
assert:
|
|
67
|
+
- type: llm-rubric
|
|
68
|
+
provider: openai:gpt-5-mini
|
|
69
|
+
value: "The summary should be 1-2 sentences in English about TypeScript"
|
|
70
|
+
- type: contains-any
|
|
71
|
+
value: ["TypeScript", "JavaScript", "type"]
|
|
72
|
+
- type: javascript
|
|
73
|
+
value: "output.split(/[.!?]/).filter(s => s.trim()).length <= 2"
|
|
74
|
+
|
|
75
|
+
# Mixed technical terms in Chinese
|
|
76
|
+
- vars:
|
|
77
|
+
text: "Docker 是一个开源的容器化平台,它允许开发者将应用程序及其依赖项打包到一个可移植的容器中。通过使用 Docker,可以确保应用在任何环境中都能一致地运行。Docker 容器比传统虚拟机更轻量级,启动速度更快,资源占用更少。"
|
|
78
|
+
assert:
|
|
79
|
+
- type: llm-rubric
|
|
80
|
+
provider: openai:gpt-5-mini
|
|
81
|
+
value: "The summary should be 1-2 sentences in Chinese, keeping 'Docker' in English"
|
|
82
|
+
- type: contains
|
|
83
|
+
value: "Docker" # Technical term should be preserved
|
|
84
|
+
- type: contains-any
|
|
85
|
+
value: ["容器", "平台", "应用"]
|
|
86
|
+
- type: javascript
|
|
87
|
+
value: "output.split(/[。!?]/).filter(s => s.trim()).length <= 2"
|
|
88
|
+
|
|
89
|
+
# German content
|
|
90
|
+
- vars:
|
|
91
|
+
text: "Die Quantenphysik ist ein fundamentaler Zweig der Physik, der sich mit dem Verhalten von Materie und Energie auf atomarer und subatomarer Ebene befasst. Im Gegensatz zur klassischen Physik beschreibt die Quantenphysik Phänomene, bei denen Teilchen sowohl Wellen- als auch Teilcheneigenschaften aufweisen können."
|
|
92
|
+
assert:
|
|
93
|
+
- type: llm-rubric
|
|
94
|
+
provider: openai:gpt-5-mini
|
|
95
|
+
value: "The summary should be 1-2 sentences in German about quantum physics"
|
|
96
|
+
- type: contains-any
|
|
97
|
+
value: ["Quantenphysik", "Physik", "Materie"]
|
|
98
|
+
- type: javascript
|
|
99
|
+
value: "output.split(/[.!?]/).filter(s => s.trim()).length <= 2"
|
|
100
|
+
|
|
101
|
+
# Code snippet in content (English)
|
|
102
|
+
- vars:
|
|
103
|
+
text: "The useState hook in React allows you to add state to functional components. For example: const [count, setCount] = useState(0). This creates a state variable 'count' with initial value 0 and a setter function 'setCount' to update it."
|
|
104
|
+
assert:
|
|
105
|
+
- type: llm-rubric
|
|
106
|
+
provider: openai:gpt-5-mini
|
|
107
|
+
value: "The summary should be 1-2 sentences in English about useState hook, may preserve code syntax"
|
|
108
|
+
- type: contains-any
|
|
109
|
+
value: ["useState", "React", "state", "hook"]
|
|
110
|
+
- type: javascript
|
|
111
|
+
value: "output.split(/[.!?]/).filter(s => s.trim()).length <= 2"
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
// TypeScript prompt wrapper that uses actual chain implementation
|
|
2
|
+
import { chainAbstractChunkText } from '@lobechat/prompts';
|
|
3
|
+
|
|
4
|
+
interface PromptVars {
|
|
5
|
+
text: string;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
export default function generatePrompt({ vars }: { vars: PromptVars }) {
|
|
9
|
+
const { text } = vars;
|
|
10
|
+
|
|
11
|
+
// Use the actual chain function from src
|
|
12
|
+
const result = chainAbstractChunkText(text);
|
|
13
|
+
|
|
14
|
+
// Return messages array as expected by promptfoo
|
|
15
|
+
return result.messages || [];
|
|
16
|
+
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
|
|
2
|
+
|
|
3
|
+
exports[`chainAbstractChunkText > should generate correct chat payload for chunk text 1`] = `
|
|
4
|
+
{
|
|
5
|
+
"messages": [
|
|
6
|
+
{
|
|
7
|
+
"content": "You are a summarization expert. Generate a concise summary from the provided text chunk.
|
|
8
|
+
|
|
9
|
+
Rules:
|
|
10
|
+
- Output ONLY the summary text itself, nothing else
|
|
11
|
+
- NO labels, prefixes, or meta-text (like "Summary:", "摘要:", etc.)
|
|
12
|
+
- NO explanations, commentary, or additional context
|
|
13
|
+
- MUST be 1-2 complete sentences maximum (count carefully!)
|
|
14
|
+
- MUST use the SAME language as the input text
|
|
15
|
+
- Preserve technical terms, proper nouns, and code identifiers exactly as they appear
|
|
16
|
+
- Focus on capturing the main topic or key information
|
|
17
|
+
- Keep it concise and direct
|
|
18
|
+
|
|
19
|
+
<examples>
|
|
20
|
+
<input>React is a JavaScript library for building user interfaces...</input>
|
|
21
|
+
<output>React is a JavaScript library developed by Facebook for building interactive user interfaces with declarative views.</output>
|
|
22
|
+
|
|
23
|
+
<input>The useState hook in React allows you to add state...</input>
|
|
24
|
+
<output>The useState hook in React enables functional components to manage state using a state variable and setter function.</output>
|
|
25
|
+
|
|
26
|
+
<input>深度学习是机器学习的一个分支...</input>
|
|
27
|
+
<output>深度学习是机器学习的一个分支,使用多层神经网络学习数据表示,在图像识别、自然语言处理等领域取得突破。</output>
|
|
28
|
+
</examples>
|
|
29
|
+
",
|
|
30
|
+
"role": "system",
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"content": "This is a sample chunk of text that needs to be summarized.",
|
|
34
|
+
"role": "user",
|
|
35
|
+
},
|
|
36
|
+
],
|
|
37
|
+
}
|
|
38
|
+
`;
|
|
@@ -8,26 +8,7 @@ describe('chainAbstractChunkText', () => {
|
|
|
8
8
|
|
|
9
9
|
const result = chainAbstractChunkText(testText);
|
|
10
10
|
|
|
11
|
-
expect(result).
|
|
12
|
-
messages: [
|
|
13
|
-
{
|
|
14
|
-
content:
|
|
15
|
-
'你是一名擅长从 chunk 中提取摘要的助理,你需要将用户的会话总结为 1~2 句话的摘要,输出成 chunk 所使用的语种',
|
|
16
|
-
role: 'system',
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
content: `chunk: ${testText}`,
|
|
20
|
-
role: 'user',
|
|
21
|
-
},
|
|
22
|
-
],
|
|
23
|
-
});
|
|
24
|
-
});
|
|
25
|
-
|
|
26
|
-
it('should handle empty text', () => {
|
|
27
|
-
const result = chainAbstractChunkText('');
|
|
28
|
-
|
|
29
|
-
expect(result.messages).toHaveLength(2);
|
|
30
|
-
expect(result.messages![1].content).toBe('chunk: ');
|
|
11
|
+
expect(result).toMatchSnapshot();
|
|
31
12
|
});
|
|
32
13
|
|
|
33
14
|
it('should handle text with special characters', () => {
|
|
@@ -35,7 +16,7 @@ describe('chainAbstractChunkText', () => {
|
|
|
35
16
|
|
|
36
17
|
const result = chainAbstractChunkText(testText);
|
|
37
18
|
|
|
38
|
-
expect(result.messages![1].content).toBe(
|
|
19
|
+
expect(result.messages![1].content).toBe(testText);
|
|
39
20
|
});
|
|
40
21
|
|
|
41
22
|
it('should always use system role for first message', () => {
|
|
@@ -4,12 +4,33 @@ export const chainAbstractChunkText = (text: string): Partial<ChatStreamPayload>
|
|
|
4
4
|
return {
|
|
5
5
|
messages: [
|
|
6
6
|
{
|
|
7
|
-
content:
|
|
8
|
-
|
|
7
|
+
content: `You are a summarization expert. Generate a concise summary from the provided text chunk.
|
|
8
|
+
|
|
9
|
+
Rules:
|
|
10
|
+
- Output ONLY the summary text itself, nothing else
|
|
11
|
+
- NO labels, prefixes, or meta-text (like "Summary:", "摘要:", etc.)
|
|
12
|
+
- NO explanations, commentary, or additional context
|
|
13
|
+
- MUST be 1-2 complete sentences maximum (count carefully!)
|
|
14
|
+
- MUST use the SAME language as the input text
|
|
15
|
+
- Preserve technical terms, proper nouns, and code identifiers exactly as they appear
|
|
16
|
+
- Focus on capturing the main topic or key information
|
|
17
|
+
- Keep it concise and direct
|
|
18
|
+
|
|
19
|
+
<examples>
|
|
20
|
+
<input>React is a JavaScript library for building user interfaces...</input>
|
|
21
|
+
<output>React is a JavaScript library developed by Facebook for building interactive user interfaces with declarative views.</output>
|
|
22
|
+
|
|
23
|
+
<input>The useState hook in React allows you to add state...</input>
|
|
24
|
+
<output>The useState hook in React enables functional components to manage state using a state variable and setter function.</output>
|
|
25
|
+
|
|
26
|
+
<input>深度学习是机器学习的一个分支...</input>
|
|
27
|
+
<output>深度学习是机器学习的一个分支,使用多层神经网络学习数据表示,在图像识别、自然语言处理等领域取得突破。</output>
|
|
28
|
+
</examples>
|
|
29
|
+
`,
|
|
9
30
|
role: 'system',
|
|
10
31
|
},
|
|
11
32
|
{
|
|
12
|
-
content:
|
|
33
|
+
content: text,
|
|
13
34
|
role: 'user',
|
|
14
35
|
},
|
|
15
36
|
],
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { describe, expect, it } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { crawlResultsPrompt } from './crawlResults';
|
|
4
|
+
|
|
5
|
+
describe('crawlResultsPrompt', () => {
|
|
6
|
+
it('should return empty XML for empty results', () => {
|
|
7
|
+
const result = crawlResultsPrompt([]);
|
|
8
|
+
expect(result).toBe('<no_crawl_results />');
|
|
9
|
+
});
|
|
10
|
+
|
|
11
|
+
it('should convert basic crawl result to compact XML format', () => {
|
|
12
|
+
const results = [
|
|
13
|
+
{
|
|
14
|
+
url: 'https://example.com',
|
|
15
|
+
title: 'Example Page',
|
|
16
|
+
content: 'Page content here',
|
|
17
|
+
},
|
|
18
|
+
];
|
|
19
|
+
|
|
20
|
+
const xml = crawlResultsPrompt(results);
|
|
21
|
+
|
|
22
|
+
expect(xml).toEqual(`<crawlResults>
|
|
23
|
+
<page url="https://example.com" title="Example Page">Page content here</page>
|
|
24
|
+
</crawlResults>`);
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
it('should include all optional metadata fields', () => {
|
|
28
|
+
const results = [
|
|
29
|
+
{
|
|
30
|
+
url: 'http://arxiv.org/abs/2509.09734v1',
|
|
31
|
+
title: 'MCP-AgentBench: Evaluating Real-World Language Agent Performance',
|
|
32
|
+
contentType: 'text' as const,
|
|
33
|
+
description: 'Abstract page for arXiv paper 2509.09734v1',
|
|
34
|
+
length: 10187,
|
|
35
|
+
content: 'Full paper content...',
|
|
36
|
+
},
|
|
37
|
+
];
|
|
38
|
+
|
|
39
|
+
const xml = crawlResultsPrompt(results);
|
|
40
|
+
|
|
41
|
+
expect(xml).toEqual(`<crawlResults>
|
|
42
|
+
<page url="http://arxiv.org/abs/2509.09734v1" title="MCP-AgentBench: Evaluating Real-World Language Agent Performance" contentType="text" description="Abstract page for arXiv paper 2509.09734v1" length="10187">Full paper content...</page>
|
|
43
|
+
</crawlResults>`);
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
it('should handle page without content', () => {
|
|
47
|
+
const results = [
|
|
48
|
+
{
|
|
49
|
+
url: 'https://example.com',
|
|
50
|
+
title: 'Empty Page',
|
|
51
|
+
contentType: 'text' as const,
|
|
52
|
+
},
|
|
53
|
+
];
|
|
54
|
+
|
|
55
|
+
const xml = crawlResultsPrompt(results);
|
|
56
|
+
|
|
57
|
+
expect(xml).toEqual(`<crawlResults>
|
|
58
|
+
<page url="https://example.com" title="Empty Page" contentType="text" />
|
|
59
|
+
</crawlResults>`);
|
|
60
|
+
});
|
|
61
|
+
|
|
62
|
+
it('should handle error items', () => {
|
|
63
|
+
const results = [
|
|
64
|
+
{
|
|
65
|
+
errorType: 'NetworkError',
|
|
66
|
+
errorMessage: 'Failed to fetch the page',
|
|
67
|
+
url: 'https://failed.com',
|
|
68
|
+
},
|
|
69
|
+
];
|
|
70
|
+
|
|
71
|
+
const xml = crawlResultsPrompt(results);
|
|
72
|
+
|
|
73
|
+
expect(xml).toEqual(`<crawlResults>
|
|
74
|
+
<error errorType="NetworkError" errorMessage="Failed to fetch the page" url="https://failed.com" />
|
|
75
|
+
</crawlResults>`);
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
it('should escape XML special characters in attributes', () => {
|
|
79
|
+
const results = [
|
|
80
|
+
{
|
|
81
|
+
url: 'https://example.com?foo=bar&baz=qux',
|
|
82
|
+
title: 'Title with <tags> & "quotes"',
|
|
83
|
+
description: 'Description with special chars & <html>',
|
|
84
|
+
},
|
|
85
|
+
];
|
|
86
|
+
|
|
87
|
+
const xml = crawlResultsPrompt(results);
|
|
88
|
+
|
|
89
|
+
expect(xml).toEqual(`<crawlResults>
|
|
90
|
+
<page url="https://example.com?foo=bar&baz=qux" title="Title with <tags> & "quotes"" description="Description with special chars & <html>" />
|
|
91
|
+
</crawlResults>`);
|
|
92
|
+
});
|
|
93
|
+
|
|
94
|
+
it('should escape XML special characters in content', () => {
|
|
95
|
+
const results = [
|
|
96
|
+
{
|
|
97
|
+
url: 'https://example.com',
|
|
98
|
+
title: 'Test',
|
|
99
|
+
content: 'Content with <html> tags & special chars',
|
|
100
|
+
},
|
|
101
|
+
];
|
|
102
|
+
|
|
103
|
+
const xml = crawlResultsPrompt(results);
|
|
104
|
+
|
|
105
|
+
expect(xml).toEqual(`<crawlResults>
|
|
106
|
+
<page url="https://example.com" title="Test">Content with <html> tags & special chars</page>
|
|
107
|
+
</crawlResults>`);
|
|
108
|
+
});
|
|
109
|
+
|
|
110
|
+
it('should handle multiple pages with mixed success and errors', () => {
|
|
111
|
+
const results = [
|
|
112
|
+
{
|
|
113
|
+
url: 'https://success1.com',
|
|
114
|
+
title: 'First Page',
|
|
115
|
+
content: 'First content',
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
errorType: 'TimeoutError',
|
|
119
|
+
errorMessage: 'Request timeout',
|
|
120
|
+
url: 'https://failed.com',
|
|
121
|
+
},
|
|
122
|
+
{
|
|
123
|
+
url: 'https://success2.com',
|
|
124
|
+
title: 'Second Page',
|
|
125
|
+
content: 'Second content',
|
|
126
|
+
},
|
|
127
|
+
];
|
|
128
|
+
|
|
129
|
+
const xml = crawlResultsPrompt(results);
|
|
130
|
+
|
|
131
|
+
expect(xml).toEqual(`<crawlResults>
|
|
132
|
+
<page url="https://success1.com" title="First Page">First content</page>
|
|
133
|
+
<error errorType="TimeoutError" errorMessage="Request timeout" url="https://failed.com" />
|
|
134
|
+
<page url="https://success2.com" title="Second Page">Second content</page>
|
|
135
|
+
</crawlResults>`);
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('should handle error without url', () => {
|
|
139
|
+
const results = [
|
|
140
|
+
{
|
|
141
|
+
errorType: 'UnknownError',
|
|
142
|
+
errorMessage: 'Unknown error occurred',
|
|
143
|
+
},
|
|
144
|
+
];
|
|
145
|
+
|
|
146
|
+
const xml = crawlResultsPrompt(results);
|
|
147
|
+
|
|
148
|
+
expect(xml).toEqual(`<crawlResults>
|
|
149
|
+
<error errorType="UnknownError" errorMessage="Unknown error occurred" />
|
|
150
|
+
</crawlResults>`);
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
it('should handle real arXiv example', () => {
|
|
154
|
+
const results = [
|
|
155
|
+
{
|
|
156
|
+
url: 'http://arxiv.org/abs/2508.01780v1',
|
|
157
|
+
title: 'LiveMCPBench: Can Agents Navigate an Ocean of MCP Tools?',
|
|
158
|
+
contentType: 'text' as const,
|
|
159
|
+
description: 'Abstract page for arXiv paper 2508.01780v1',
|
|
160
|
+
length: 10512,
|
|
161
|
+
content:
|
|
162
|
+
'With the rapid development of Model Context Protocol (MCP), the number of MCP servers has surpassed 10,000...',
|
|
163
|
+
},
|
|
164
|
+
];
|
|
165
|
+
|
|
166
|
+
const xml = crawlResultsPrompt(results);
|
|
167
|
+
|
|
168
|
+
expect(xml).toEqual(`<crawlResults>
|
|
169
|
+
<page url="http://arxiv.org/abs/2508.01780v1" title="LiveMCPBench: Can Agents Navigate an Ocean of MCP Tools?" contentType="text" description="Abstract page for arXiv paper 2508.01780v1" length="10512">With the rapid development of Model Context Protocol (MCP), the number of MCP servers has surpassed 10,000...</page>
|
|
170
|
+
</crawlResults>`);
|
|
171
|
+
});
|
|
172
|
+
});
|