@lobehub/chat 1.90.4 → 1.91.1
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 +58 -0
- package/changelog/v1.json +21 -0
- package/docs/changelog/2023-09-09-plugin-system.mdx +2 -3
- package/docs/changelog/2023-11-14-gpt4-vision.mdx +4 -6
- package/docs/changelog/2023-11-19-tts-stt.mdx +2 -3
- package/docs/changelog/2023-12-22-dalle-3.mdx +2 -5
- package/docs/changelog/2023-12-22-dalle-3.zh-CN.mdx +2 -2
- package/docs/changelog/2024-02-08-sso-oauth.mdx +2 -2
- package/docs/changelog/2024-06-19-lobe-chat-v1.mdx +2 -3
- package/docs/changelog/2024-06-19-lobe-chat-v1.zh-CN.mdx +2 -2
- package/docs/changelog/2024-07-19-gpt-4o-mini.mdx +2 -3
- package/docs/changelog/2024-07-19-gpt-4o-mini.zh-CN.mdx +2 -2
- package/docs/changelog/2024-08-02-lobe-chat-database-docker.mdx +2 -3
- package/docs/changelog/2024-08-21-file-upload-and-knowledge-base.mdx +4 -5
- package/docs/changelog/2024-09-13-openai-o1-models.mdx +2 -2
- package/docs/changelog/2024-09-20-artifacts.mdx +2 -3
- package/docs/changelog/2024-09-20-artifacts.zh-CN.mdx +2 -2
- package/docs/changelog/2024-10-27-pin-assistant.mdx +2 -3
- package/docs/changelog/2024-11-06-share-text-json.mdx +2 -4
- package/docs/changelog/2024-11-06-share-text-json.zh-CN.mdx +2 -2
- package/docs/changelog/2024-11-25-november-providers.mdx +2 -2
- package/docs/changelog/2024-11-27-forkable-chat.mdx +2 -2
- package/docs/changelog/2025-01-03-user-profile.mdx +2 -2
- package/docs/changelog/2025-01-22-new-ai-provider.mdx +2 -2
- package/docs/changelog/2025-02-02-deepseek-r1.mdx +4 -4
- package/docs/development/basic/add-new-authentication-providers.zh-CN.mdx +1 -2
- package/docs/development/basic/chat-api.mdx +2 -4
- package/docs/development/basic/chat-api.zh-CN.mdx +2 -4
- package/docs/development/internationalization/internationalization-implementation.mdx +10 -10
- package/docs/development/internationalization/internationalization-implementation.zh-CN.mdx +10 -10
- package/docs/self-hosting/advanced/analytics.mdx +2 -2
- package/docs/self-hosting/advanced/auth/clerk.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/auth0.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/authelia.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/authentik.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.mdx +4 -7
- package/docs/self-hosting/advanced/auth/next-auth/casdoor.zh-CN.mdx +0 -3
- package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/cloudflare-zero-trust.zh-CN.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/github.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/keycloak.mdx +12 -6
- package/docs/self-hosting/advanced/auth/next-auth/keycloak.zh-CN.mdx +5 -1
- package/docs/self-hosting/advanced/auth/next-auth/logto.mdx +8 -14
- package/docs/self-hosting/advanced/auth/next-auth/logto.zh-CN.mdx +6 -12
- package/docs/self-hosting/advanced/auth/next-auth/microsoft-entra-id.mdx +2 -3
- package/docs/self-hosting/advanced/auth/next-auth/wechat.mdx +2 -2
- package/docs/self-hosting/advanced/auth/next-auth/zitadel.mdx +2 -3
- package/docs/self-hosting/advanced/auth.mdx +2 -3
- package/docs/self-hosting/advanced/desktop.mdx +2 -1
- package/docs/self-hosting/advanced/desktop.zh-CN.mdx +1 -3
- package/docs/self-hosting/advanced/feature-flags.mdx +2 -3
- package/docs/self-hosting/advanced/knowledge-base.mdx +4 -3
- package/docs/self-hosting/advanced/model-list.mdx +11 -10
- package/docs/self-hosting/advanced/model-list.zh-CN.mdx +10 -9
- package/docs/self-hosting/advanced/observability/langfuse.mdx +2 -3
- package/docs/self-hosting/advanced/online-search.mdx +11 -10
- package/docs/self-hosting/advanced/online-search.zh-CN.mdx +7 -7
- package/docs/self-hosting/advanced/s3/tencent-cloud.mdx +2 -2
- package/docs/self-hosting/advanced/settings-url-share.mdx +2 -3
- package/docs/self-hosting/advanced/upstream-sync.mdx +2 -3
- package/docs/self-hosting/advanced/webrtc.mdx +2 -2
- package/docs/self-hosting/environment-variables/analytics.mdx +2 -3
- package/docs/self-hosting/environment-variables/auth.mdx +2 -3
- package/docs/self-hosting/environment-variables/basic.mdx +4 -5
- package/docs/self-hosting/environment-variables/basic.zh-CN.mdx +2 -2
- package/docs/self-hosting/environment-variables/model-provider.mdx +2 -3
- package/docs/self-hosting/environment-variables/s3.mdx +3 -5
- package/docs/self-hosting/environment-variables.mdx +2 -2
- package/docs/self-hosting/examples/azure-openai.mdx +2 -2
- package/docs/self-hosting/examples/ollama.mdx +2 -3
- package/docs/self-hosting/faq/no-v1-suffix.mdx +4 -4
- package/docs/self-hosting/faq/proxy-with-unable-to-verify-leaf-signature.mdx +2 -3
- package/docs/self-hosting/platform/alibaba-cloud.mdx +2 -3
- package/docs/self-hosting/platform/btpanel.mdx +5 -5
- package/docs/self-hosting/platform/btpanel.zh-CN.mdx +4 -3
- package/docs/self-hosting/platform/docker-compose.mdx +2 -3
- package/docs/self-hosting/platform/docker-compose.zh-CN.mdx +0 -2
- package/docs/self-hosting/platform/docker.mdx +2 -2
- package/docs/self-hosting/platform/netlify.mdx +2 -4
- package/docs/self-hosting/platform/netlify.zh-CN.mdx +2 -2
- package/docs/self-hosting/platform/railway.mdx +2 -3
- package/docs/self-hosting/platform/repocloud.mdx +2 -3
- package/docs/self-hosting/platform/sealos.mdx +2 -2
- package/docs/self-hosting/platform/tencentcloud-lighthouse.mdx +2 -3
- package/docs/self-hosting/platform/vercel.mdx +2 -3
- package/docs/self-hosting/platform/zeabur.mdx +2 -2
- package/docs/self-hosting/server-database/docker-compose.mdx +65 -44
- package/docs/self-hosting/server-database/docker-compose.zh-CN.mdx +48 -55
- package/docs/self-hosting/server-database/docker.mdx +2 -2
- package/docs/self-hosting/server-database/docker.zh-CN.mdx +2 -2
- package/docs/self-hosting/server-database/dokploy.mdx +4 -5
- package/docs/self-hosting/server-database/dokploy.zh-CN.mdx +137 -138
- package/docs/self-hosting/server-database/netlify.mdx +2 -2
- package/docs/self-hosting/server-database/netlify.zh-CN.mdx +2 -2
- package/docs/self-hosting/server-database/railway.mdx +2 -2
- package/docs/self-hosting/server-database/repocloud.mdx +2 -2
- package/docs/self-hosting/server-database/sealos.mdx +4 -5
- package/docs/self-hosting/server-database/sealos.zh-CN.mdx +18 -20
- package/docs/self-hosting/server-database/vercel.mdx +5 -3
- package/docs/self-hosting/server-database/vercel.zh-CN.mdx +2 -2
- package/docs/self-hosting/server-database/zeabur.mdx +2 -2
- package/docs/self-hosting/server-database.mdx +1 -1
- package/docs/self-hosting/server-database.zh-CN.mdx +2 -1
- package/docs/self-hosting/start.mdx +2 -2
- package/docs/self-hosting/start.zh-CN.mdx +2 -2
- package/docs/usage/agents/agent-organization.mdx +2 -2
- package/docs/usage/agents/concepts.mdx +4 -5
- package/docs/usage/agents/concepts.zh-CN.mdx +2 -2
- package/docs/usage/agents/custom-agent.mdx +3 -4
- package/docs/usage/agents/custom-agent.zh-CN.mdx +1 -1
- package/docs/usage/agents/model.mdx +5 -5
- package/docs/usage/agents/model.zh-CN.mdx +3 -5
- package/docs/usage/agents/prompt.mdx +4 -5
- package/docs/usage/agents/topics.mdx +3 -4
- package/docs/usage/agents/topics.zh-CN.mdx +1 -1
- package/docs/usage/features/agent-market.mdx +3 -11
- package/docs/usage/features/agent-market.zh-CN.mdx +2 -7
- package/docs/usage/features/artifacts.mdx +2 -2
- package/docs/usage/features/auth.mdx +2 -3
- package/docs/usage/features/cot.mdx +2 -2
- package/docs/usage/features/database.mdx +2 -2
- package/docs/usage/features/knowledge-base.mdx +4 -3
- package/docs/usage/features/knowledge-base.zh-CN.mdx +2 -1
- package/docs/usage/features/local-llm.mdx +2 -3
- package/docs/usage/features/mobile.mdx +2 -2
- package/docs/usage/features/more.mdx +2 -3
- package/docs/usage/features/multi-ai-providers.mdx +2 -3
- package/docs/usage/features/plugin-system.mdx +3 -11
- package/docs/usage/features/plugin-system.zh-CN.mdx +1 -8
- package/docs/usage/features/pwa.mdx +4 -4
- package/docs/usage/features/pwa.zh-CN.mdx +2 -1
- package/docs/usage/features/text-to-image.mdx +3 -11
- package/docs/usage/features/text-to-image.zh-CN.mdx +3 -10
- package/docs/usage/features/theme.mdx +2 -3
- package/docs/usage/features/tts.mdx +3 -11
- package/docs/usage/features/tts.zh-CN.mdx +1 -8
- package/docs/usage/features/vision.mdx +3 -11
- package/docs/usage/features/vision.zh-CN.mdx +1 -8
- package/docs/usage/foundation/basic.mdx +2 -3
- package/docs/usage/foundation/share.mdx +2 -3
- package/docs/usage/foundation/text2image.mdx +2 -2
- package/docs/usage/foundation/translate.mdx +2 -2
- package/docs/usage/foundation/tts-stt.mdx +2 -2
- package/docs/usage/foundation/vision.mdx +2 -3
- package/docs/usage/plugins/basic-usage.mdx +2 -3
- package/docs/usage/plugins/custom-plugin.mdx +2 -2
- package/docs/usage/plugins/development.mdx +2 -4
- package/docs/usage/plugins/store.mdx +2 -2
- package/docs/usage/providers/ai21.mdx +2 -2
- package/docs/usage/providers/anthropic.mdx +2 -3
- package/docs/usage/providers/anthropic.zh-CN.mdx +2 -2
- package/docs/usage/providers/azure.mdx +2 -3
- package/docs/usage/providers/azureai.mdx +4 -2
- package/docs/usage/providers/azureai.zh-CN.mdx +2 -1
- package/docs/usage/providers/baichuan.mdx +2 -3
- package/docs/usage/providers/bedrock.mdx +2 -3
- package/docs/usage/providers/cloudflare.mdx +3 -2
- package/docs/usage/providers/deepseek.mdx +2 -2
- package/docs/usage/providers/fireworksai.mdx +2 -2
- package/docs/usage/providers/giteeai.mdx +2 -2
- package/docs/usage/providers/github.mdx +1 -1
- package/docs/usage/providers/github.zh-CN.mdx +1 -1
- package/docs/usage/providers/google.mdx +2 -3
- package/docs/usage/providers/groq.mdx +2 -2
- package/docs/usage/providers/hunyuan.mdx +2 -2
- package/docs/usage/providers/infiniai.zh-CN.mdx +3 -1
- package/docs/usage/providers/internlm.mdx +2 -2
- package/docs/usage/providers/jina.mdx +4 -3
- package/docs/usage/providers/jina.zh-CN.mdx +2 -2
- package/docs/usage/providers/lmstudio.mdx +2 -2
- package/docs/usage/providers/lmstudio.zh-CN.mdx +2 -4
- package/docs/usage/providers/minimax.mdx +2 -3
- package/docs/usage/providers/minimax.zh-CN.mdx +2 -2
- package/docs/usage/providers/mistral.mdx +2 -3
- package/docs/usage/providers/modelscope.mdx +4 -0
- package/docs/usage/providers/modelscope.zh-CN.mdx +4 -0
- package/docs/usage/providers/moonshot.mdx +2 -3
- package/docs/usage/providers/novita.mdx +2 -3
- package/docs/usage/providers/novita.zh-CN.mdx +2 -2
- package/docs/usage/providers/nvidia.mdx +3 -2
- package/docs/usage/providers/ollama/gemma.mdx +2 -3
- package/docs/usage/providers/ollama/gemma.zh-CN.mdx +2 -2
- package/docs/usage/providers/ollama.mdx +2 -2
- package/docs/usage/providers/openai.mdx +5 -5
- package/docs/usage/providers/openai.zh-CN.mdx +3 -3
- package/docs/usage/providers/openrouter.mdx +2 -3
- package/docs/usage/providers/perplexity.mdx +2 -2
- package/docs/usage/providers/ppio.mdx +5 -6
- package/docs/usage/providers/ppio.zh-CN.mdx +6 -6
- package/docs/usage/providers/qiniu.mdx +6 -6
- package/docs/usage/providers/qiniu.zh-CN.mdx +2 -1
- package/docs/usage/providers/qwen.mdx +2 -4
- package/docs/usage/providers/sambanova.mdx +2 -1
- package/docs/usage/providers/sensenova.mdx +2 -2
- package/docs/usage/providers/siliconcloud.mdx +2 -2
- package/docs/usage/providers/stepfun.mdx +2 -3
- package/docs/usage/providers/taichu.mdx +2 -3
- package/docs/usage/providers/togetherai.mdx +2 -2
- package/docs/usage/providers/vllm.mdx +15 -12
- package/docs/usage/providers/vllm.zh-CN.mdx +9 -7
- package/docs/usage/providers/volcengine.mdx +16 -14
- package/docs/usage/providers/wenxin.mdx +2 -2
- package/docs/usage/providers/xai.mdx +2 -2
- package/docs/usage/providers/zeroone.mdx +2 -3
- package/docs/usage/providers/zeroone.zh-CN.mdx +2 -2
- package/docs/usage/providers/zhipu.mdx +2 -3
- package/docs/usage/providers/zhipu.zh-CN.mdx +1 -1
- package/docs/usage/providers.mdx +2 -3
- package/docs/usage/start.mdx +2 -3
- package/docs/usage/tools-calling/anthropic.mdx +2 -2
- package/docs/usage/tools-calling/anthropic.zh-CN.mdx +2 -2
- package/docs/usage/tools-calling/google.mdx +2 -2
- package/docs/usage/tools-calling/google.zh-CN.mdx +4 -4
- package/docs/usage/tools-calling/groq.zh-CN.mdx +2 -2
- package/docs/usage/tools-calling/openai.mdx +2 -2
- package/docs/usage/tools-calling/openai.zh-CN.mdx +2 -2
- package/package.json +1 -1
- package/packages/web-crawler/src/crawImpl/exa.ts +93 -0
- package/packages/web-crawler/src/crawImpl/firecrawl.ts +97 -0
- package/packages/web-crawler/src/crawImpl/index.ts +6 -0
- package/packages/web-crawler/src/crawImpl/tavily.ts +94 -0
- package/src/app/(backend)/webapi/user/avatar/[id]/[image]/route.ts +1 -1
- package/src/app/[variants]/(main)/repos/[id]/_layout/Mobile.tsx +7 -7
- package/src/config/aiModels/deepseek.ts +1 -0
- package/src/config/aiModels/hunyuan.ts +1 -0
- package/src/config/aiModels/mistral.ts +1 -2
- package/src/config/aiModels/modelscope.ts +3 -3
- package/src/config/aiModels/novita.ts +23 -22
- package/src/config/aiModels/openrouter.ts +1 -0
- package/src/config/aiModels/qwen.ts +11 -11
- package/src/config/aiModels/siliconcloud.ts +7 -6
- package/src/config/aiModels/vertexai.ts +2 -2
- package/src/config/aiModels/wenxin.ts +1 -2
- package/src/config/modelProviders/baichuan.ts +3 -0
- package/src/config/modelProviders/fireworksai.ts +3 -0
- package/src/config/modelProviders/giteeai.ts +3 -0
- package/src/config/modelProviders/github.ts +1 -2
- package/src/config/modelProviders/groq.ts +0 -3
- package/src/config/modelProviders/hunyuan.ts +3 -0
- package/src/config/modelProviders/infiniai.ts +0 -3
- package/src/config/modelProviders/internlm.ts +3 -0
- package/src/config/modelProviders/minimax.ts +3 -4
- package/src/config/modelProviders/modelscope.ts +3 -3
- package/src/config/modelProviders/moonshot.ts +0 -7
- package/src/config/modelProviders/novita.ts +3 -0
- package/src/config/modelProviders/openrouter.ts +0 -4
- package/src/config/modelProviders/perplexity.ts +0 -3
- package/src/config/modelProviders/qiniu.ts +0 -3
- package/src/config/modelProviders/qwen.ts +0 -3
- package/src/config/modelProviders/sensenova.ts +3 -0
- package/src/config/modelProviders/siliconcloud.ts +0 -3
- package/src/config/modelProviders/spark.ts +0 -5
- package/src/config/modelProviders/stepfun.ts +3 -6
- package/src/config/modelProviders/taichu.ts +3 -0
- package/src/config/modelProviders/tencentcloud.ts +3 -0
- package/src/config/modelProviders/togetherai.ts +3 -0
- package/src/config/modelProviders/upstage.ts +3 -0
- package/src/config/modelProviders/wenxin.ts +3 -4
- package/src/config/modelProviders/xai.ts +0 -3
- package/src/config/modelProviders/zhipu.ts +3 -0
- package/src/database/client/migrations.json +10 -0
- package/src/database/migrations/0023_remove_param_and_doubao.sql +6 -0
- package/src/database/migrations/meta/0014_snapshot.json +182 -539
- package/src/database/migrations/meta/0016_snapshot.json +182 -539
- package/src/database/migrations/meta/0023_snapshot.json +5340 -0
- package/src/database/migrations/meta/_journal.json +7 -0
- package/src/database/repositories/dataImporter/__tests__/fixtures/with-client-id.json +13 -58
- package/src/features/ChatInput/ActionBar/Model/ControlsForm.tsx +1 -8
- package/src/features/ChatInput/ActionBar/Model/index.tsx +8 -16
- package/src/features/ChatInput/ActionBar/Search/Controls.tsx +4 -12
- package/src/features/ChatInput/ActionBar/Search/FCSearchModel.tsx +1 -7
- package/src/features/ChatInput/ActionBar/Search/index.tsx +2 -4
- package/src/features/ModelSwitchPanel/index.tsx +1 -4
- package/src/libs/model-runtime/anthropic/index.test.ts +4 -2
- package/src/libs/model-runtime/utils/streams/anthropic.ts +12 -11
- package/src/libs/model-runtime/utils/streams/openai.ts +6 -4
- package/src/libs/model-runtime/utils/streams/protocol.ts +1 -1
- package/src/libs/model-runtime/utils/streams/spark.test.ts +1 -1
- package/src/libs/model-runtime/utils/streams/spark.ts +1 -2
- package/src/middleware.ts +1 -1
- package/src/server/services/search/impls/bocha/index.ts +124 -0
- package/src/server/services/search/impls/bocha/type.ts +47 -0
- package/src/server/services/search/impls/exa/index.ts +129 -0
- package/src/server/services/search/impls/exa/type.ts +39 -0
- package/src/server/services/search/impls/firecrawl/index.ts +128 -0
- package/src/server/services/search/impls/firecrawl/type.ts +35 -0
- package/src/server/services/search/impls/index.ts +31 -0
- package/src/server/services/search/impls/jina/index.ts +109 -0
- package/src/server/services/search/impls/jina/type.ts +26 -0
- package/src/server/services/search/impls/tavily/index.ts +124 -0
- package/src/server/services/search/impls/tavily/type.ts +36 -0
- package/src/server/services/user/index.ts +3 -4
- package/src/services/__tests__/assistant.test.ts +4 -6
- package/src/services/__tests__/tool.test.ts +3 -1
- package/src/store/user/slices/auth/selectors.ts +1 -1
- package/src/store/user/slices/common/action.test.ts +1 -1
- package/src/tools/web-browsing/index.ts +1 -7
@@ -161,6 +161,13 @@
|
|
161
161
|
"when": 1746724476380,
|
162
162
|
"tag": "0022_add_documents",
|
163
163
|
"breakpoints": true
|
164
|
+
},
|
165
|
+
{
|
166
|
+
"idx": 23,
|
167
|
+
"version": "7",
|
168
|
+
"when": 1748925630721,
|
169
|
+
"tag": "0023_remove_param_and_doubao",
|
170
|
+
"breakpoints": true
|
164
171
|
}
|
165
172
|
],
|
166
173
|
"version": "6"
|
@@ -15,9 +15,7 @@
|
|
15
15
|
"name": "showMJ",
|
16
16
|
"parameters": {
|
17
17
|
"type": "object",
|
18
|
-
"required": [
|
19
|
-
"prompts"
|
20
|
-
],
|
18
|
+
"required": ["prompts"],
|
21
19
|
"properties": {
|
22
20
|
"prompts": {
|
23
21
|
"type": "string",
|
@@ -29,11 +27,7 @@
|
|
29
27
|
}
|
30
28
|
],
|
31
29
|
"meta": {
|
32
|
-
"tags": [
|
33
|
-
"AI Image Generation",
|
34
|
-
"Midjourney",
|
35
|
-
"Visualization"
|
36
|
-
],
|
30
|
+
"tags": ["AI Image Generation", "Midjourney", "Visualization"],
|
37
31
|
"title": "Midjourney",
|
38
32
|
"avatar": "https://cdn.discordapp.com/icons/662267976984297473/39128f6c9fc33f4c95a27d4c601ad7db.webp",
|
39
33
|
"description": "Unleash creativity with Midjourney, effortlessly generating unique AI-driven images through simple prompts. Add visual flair to your conversations with Midjourney's artistic touch."
|
@@ -44,9 +38,7 @@
|
|
44
38
|
"version": "1",
|
45
39
|
"settings": {
|
46
40
|
"type": "object",
|
47
|
-
"required": [
|
48
|
-
"MIDJOURNEY_PROXY_URL"
|
49
|
-
],
|
41
|
+
"required": ["MIDJOURNEY_PROXY_URL"],
|
50
42
|
"properties": {
|
51
43
|
"MIDJOURNEY_PROXY_URL": {
|
52
44
|
"type": "string",
|
@@ -128,13 +120,7 @@
|
|
128
120
|
"slug": "rapidly-radio-harbor-mountain",
|
129
121
|
"title": "CAN",
|
130
122
|
"description": "有经验的程序员,精通多种编程语言。提供代码解决方案、指导和实际示例,帮助用户实现他们的编程目标。\"我热爱编程。\"",
|
131
|
-
"tags": [
|
132
|
-
"programming",
|
133
|
-
"coding",
|
134
|
-
"programming-assistance",
|
135
|
-
"code-examples",
|
136
|
-
"guidance"
|
137
|
-
],
|
123
|
+
"tags": ["programming", "coding", "programming-assistance", "code-examples", "guidance"],
|
138
124
|
"avatar": "👨💻",
|
139
125
|
"backgroundColor": null,
|
140
126
|
"plugins": [],
|
@@ -174,9 +160,7 @@
|
|
174
160
|
"slug": "crowd-society-south-shallow",
|
175
161
|
"title": "",
|
176
162
|
"description": "",
|
177
|
-
"tags": [
|
178
|
-
""
|
179
|
-
],
|
163
|
+
"tags": [""],
|
180
164
|
"avatar": "",
|
181
165
|
"backgroundColor": "rgba(0,0,0,0)",
|
182
166
|
"plugins": [],
|
@@ -216,18 +200,10 @@
|
|
216
200
|
"slug": "team-energy-settlers-west",
|
217
201
|
"title": "量化交易顾问",
|
218
202
|
"description": "擅长数字货币市场量化交易与策略优化",
|
219
|
-
"tags": [
|
220
|
-
"数字货币",
|
221
|
-
"量化交易",
|
222
|
-
"市场分析",
|
223
|
-
"风险管理",
|
224
|
-
"策略开发"
|
225
|
-
],
|
203
|
+
"tags": ["数字货币", "量化交易", "市场分析", "风险管理", "策略开发"],
|
226
204
|
"avatar": "📈",
|
227
205
|
"backgroundColor": "rgba(0,0,0,0)",
|
228
|
-
"plugins": [
|
229
|
-
"web_search"
|
230
|
-
],
|
206
|
+
"plugins": ["web_search"],
|
231
207
|
"clientId": null,
|
232
208
|
"chatConfig": {
|
233
209
|
"displayMode": "chat",
|
@@ -264,11 +240,7 @@
|
|
264
240
|
"slug": "load-essential-likely-travel",
|
265
241
|
"title": "中英文互译助手",
|
266
242
|
"description": "中英文翻译专家,追求翻译信达雅",
|
267
|
-
"tags": [
|
268
|
-
"翻译",
|
269
|
-
"中文",
|
270
|
-
"英文"
|
271
|
-
],
|
243
|
+
"tags": ["翻译", "中文", "英文"],
|
272
244
|
"avatar": "🌐",
|
273
245
|
"backgroundColor": null,
|
274
246
|
"plugins": [],
|
@@ -308,13 +280,7 @@
|
|
308
280
|
"slug": "look-quickly-break-yard",
|
309
281
|
"title": "全栈开发助手",
|
310
282
|
"description": "此角色擅长全栈开发的深度思考与技术分析。",
|
311
|
-
"tags": [
|
312
|
-
"人工智能",
|
313
|
-
"全栈开发",
|
314
|
-
"思维模式",
|
315
|
-
"技术能力",
|
316
|
-
"解决方案"
|
317
|
-
],
|
283
|
+
"tags": ["人工智能", "全栈开发", "思维模式", "技术能力", "解决方案"],
|
318
284
|
"avatar": "🧩",
|
319
285
|
"backgroundColor": "rgba(0,0,0,0)",
|
320
286
|
"plugins": [],
|
@@ -354,9 +320,7 @@
|
|
354
320
|
"slug": "everybody-those-unhappy-age",
|
355
321
|
"title": "自适应全能产业顾问",
|
356
322
|
"description": "你是一个能够适应各个行业和领域的全能人工智能助手。您的任务是根据用户指定的兴趣领域及其后续问题提供专家建议和信息。",
|
357
|
-
"tags": [
|
358
|
-
"产业专家、技术答疑"
|
359
|
-
],
|
323
|
+
"tags": ["产业专家、技术答疑"],
|
360
324
|
"avatar": "https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhJ5XrlGZKwN3Q_hEk139JOvb3Ieg5bC08jOqftLpESRRQ6_v4appLaa55PGR4g_1eK3A73UBrF_PaA8XsfswRgPPShCgZRkG8yHMvEIJNllUq3g14Pok0UGjtNZRVl3PNrLcbLxSfLX7TZ/s550/ai_shigoto_makaseru.png",
|
361
325
|
"backgroundColor": null,
|
362
326
|
"plugins": [],
|
@@ -396,10 +360,7 @@
|
|
396
360
|
"slug": "swept-name-church-rays",
|
397
361
|
"title": "AI代理生成器",
|
398
362
|
"description": "擅长创建满足需求的AI代理角色描述。",
|
399
|
-
"tags": [
|
400
|
-
"ai-agent",
|
401
|
-
"角色创建"
|
402
|
-
],
|
363
|
+
"tags": ["ai-agent", "角色创建"],
|
403
364
|
"avatar": "🤖",
|
404
365
|
"backgroundColor": null,
|
405
366
|
"plugins": [],
|
@@ -439,11 +400,7 @@
|
|
439
400
|
"slug": "continued-method-equator-attached",
|
440
401
|
"title": "Stack Overflow 编程专家",
|
441
402
|
"description": "",
|
442
|
-
"tags": [
|
443
|
-
"编程",
|
444
|
-
"专家",
|
445
|
-
"编程语言"
|
446
|
-
],
|
403
|
+
"tags": ["编程", "专家", "编程语言"],
|
447
404
|
"avatar": "🚀",
|
448
405
|
"backgroundColor": null,
|
449
406
|
"plugins": [],
|
@@ -486,9 +443,7 @@
|
|
486
443
|
"tags": [],
|
487
444
|
"avatar": null,
|
488
445
|
"backgroundColor": null,
|
489
|
-
"plugins": [
|
490
|
-
"midjourney"
|
491
|
-
],
|
446
|
+
"plugins": ["midjourney"],
|
492
447
|
"clientId": null,
|
493
448
|
"chatConfig": {
|
494
449
|
"searchMode": "off",
|
@@ -14,12 +14,7 @@ import ContextCachingSwitch from './ContextCachingSwitch';
|
|
14
14
|
import ReasoningEffortSlider from './ReasoningEffortSlider';
|
15
15
|
import ReasoningTokenSlider from './ReasoningTokenSlider';
|
16
16
|
|
17
|
-
|
18
|
-
setUpdating: (updating: boolean) => void;
|
19
|
-
updating: boolean;
|
20
|
-
}
|
21
|
-
|
22
|
-
const ControlsForm = memo<ControlsProps>(({ setUpdating }) => {
|
17
|
+
const ControlsForm = memo(() => {
|
23
18
|
const { t } = useTranslation('chat');
|
24
19
|
const [model, provider, updateAgentChatConfig] = useAgentStore((s) => [
|
25
20
|
agentSelectors.currentAgentModel(s),
|
@@ -111,9 +106,7 @@ const ControlsForm = memo<ControlsProps>(({ setUpdating }) => {
|
|
111
106
|
}
|
112
107
|
itemsType={'flat'}
|
113
108
|
onValuesChange={async (_, values) => {
|
114
|
-
setUpdating(true);
|
115
109
|
await updateAgentChatConfig(values);
|
116
|
-
setUpdating(false);
|
117
110
|
}}
|
118
111
|
size={'small'}
|
119
112
|
style={{ fontSize: 12 }}
|
@@ -1,8 +1,7 @@
|
|
1
1
|
import { ModelIcon } from '@lobehub/icons';
|
2
|
-
import { Icon } from '@lobehub/ui';
|
3
2
|
import { createStyles } from 'antd-style';
|
4
|
-
import {
|
5
|
-
import { memo
|
3
|
+
import { Settings2Icon } from 'lucide-react';
|
4
|
+
import { memo } from 'react';
|
6
5
|
import { useTranslation } from 'react-i18next';
|
7
6
|
import { Center, Flexbox } from 'react-layout-kit';
|
8
7
|
|
@@ -55,9 +54,7 @@ const useStyles = createStyles(({ css, token, cx }) => ({
|
|
55
54
|
|
56
55
|
const ModelSwitch = memo(() => {
|
57
56
|
const { t } = useTranslation('chat');
|
58
|
-
const { styles, cx
|
59
|
-
const [updating, setUpdating] = useState(false);
|
60
|
-
const [controlsUpdating, setControlsUpdating] = useState(false);
|
57
|
+
const { styles, cx } = useStyles();
|
61
58
|
|
62
59
|
const [model, provider] = useAgentStore((s) => [
|
63
60
|
agentSelectors.currentAgentModel(s),
|
@@ -70,28 +67,23 @@ const ModelSwitch = memo(() => {
|
|
70
67
|
|
71
68
|
return (
|
72
69
|
<Flexbox align={'center'} className={isModelHasExtendParams ? styles.container : ''} horizontal>
|
73
|
-
<ModelSwitchPanel
|
70
|
+
<ModelSwitchPanel>
|
74
71
|
<Center
|
75
72
|
className={cx(styles.model, isModelHasExtendParams && styles.modelWithControl)}
|
76
73
|
height={36}
|
77
74
|
width={36}
|
78
75
|
>
|
79
|
-
{
|
80
|
-
<
|
81
|
-
|
82
|
-
<div className={styles.icon}>
|
83
|
-
<ModelIcon model={model} size={22} />
|
84
|
-
</div>
|
85
|
-
)}
|
76
|
+
<div className={styles.icon}>
|
77
|
+
<ModelIcon model={model} size={22} />
|
78
|
+
</div>
|
86
79
|
</Center>
|
87
80
|
</ModelSwitchPanel>
|
88
81
|
|
89
82
|
{isModelHasExtendParams && (
|
90
83
|
<Action
|
91
84
|
icon={Settings2Icon}
|
92
|
-
loading={controlsUpdating}
|
93
85
|
popover={{
|
94
|
-
content: <ControlsForm
|
86
|
+
content: <ControlsForm />,
|
95
87
|
minWidth: 350,
|
96
88
|
placement: 'topLeft',
|
97
89
|
}}
|
@@ -59,11 +59,10 @@ interface NetworkOption {
|
|
59
59
|
disable?: boolean;
|
60
60
|
icon: LucideIcon;
|
61
61
|
label: string;
|
62
|
-
setUpdating?: (loading: boolean) => void;
|
63
62
|
value: SearchMode;
|
64
63
|
}
|
65
64
|
|
66
|
-
const Item = memo<NetworkOption>(({ value, description, icon, label
|
65
|
+
const Item = memo<NetworkOption>(({ value, description, icon, label }) => {
|
67
66
|
const { cx, styles } = useStyles();
|
68
67
|
const [mode, updateAgentChatConfig] = useAgentStore((s) => [
|
69
68
|
agentChatConfigSelectors.agentSearchMode(s),
|
@@ -78,9 +77,7 @@ const Item = memo<NetworkOption>(({ value, description, icon, label, setUpdating
|
|
78
77
|
horizontal
|
79
78
|
key={value}
|
80
79
|
onClick={async () => {
|
81
|
-
setUpdating?.(true);
|
82
80
|
await updateAgentChatConfig({ searchMode: value });
|
83
|
-
setUpdating?.(false);
|
84
81
|
}}
|
85
82
|
>
|
86
83
|
<Center className={styles.icon} flex={'none'} height={32} width={32}>
|
@@ -94,12 +91,7 @@ const Item = memo<NetworkOption>(({ value, description, icon, label, setUpdating
|
|
94
91
|
);
|
95
92
|
});
|
96
93
|
|
97
|
-
|
98
|
-
setUpdating: (updating: boolean) => void;
|
99
|
-
updating: boolean;
|
100
|
-
}
|
101
|
-
|
102
|
-
const Controls = memo<ControlsProps>(({ setUpdating }) => {
|
94
|
+
const Controls = memo(() => {
|
103
95
|
const { t } = useTranslation('chat');
|
104
96
|
const [model, provider] = useAgentStore((s) => [
|
105
97
|
agentSelectors.currentAgentModel(s),
|
@@ -131,11 +123,11 @@ const Controls = memo<ControlsProps>(({ setUpdating }) => {
|
|
131
123
|
return (
|
132
124
|
<Flexbox gap={4}>
|
133
125
|
{options.map((option) => (
|
134
|
-
<Item
|
126
|
+
<Item {...option} key={option.value} />
|
135
127
|
))}
|
136
128
|
{showDivider && <Divider style={{ margin: 0 }} />}
|
137
129
|
{isModelHasBuiltinSearchConfig && <ModelBuiltinSearch />}
|
138
|
-
{!supportFC && <FCSearchModel
|
130
|
+
{!supportFC && <FCSearchModel />}
|
139
131
|
</Flexbox>
|
140
132
|
);
|
141
133
|
});
|
@@ -31,11 +31,7 @@ const useStyles = createStyles(({ css, token }) => ({
|
|
31
31
|
`,
|
32
32
|
}));
|
33
33
|
|
34
|
-
|
35
|
-
setLoading?: (loading: boolean) => void;
|
36
|
-
}
|
37
|
-
|
38
|
-
const FCSearchModel = memo<FCSearchModelProps>(({ setLoading }) => {
|
34
|
+
const FCSearchModel = memo(() => {
|
39
35
|
const { t } = useTranslation('chat');
|
40
36
|
const { styles } = useStyles();
|
41
37
|
const [searchFCModel, updateAgentChatConfig] = useAgentStore((s) => [
|
@@ -50,9 +46,7 @@ const FCSearchModel = memo<FCSearchModelProps>(({ setLoading }) => {
|
|
50
46
|
</Flexbox>
|
51
47
|
<FunctionCallingModelSelect
|
52
48
|
onChange={async (value) => {
|
53
|
-
setLoading?.(true);
|
54
49
|
await updateAgentChatConfig({ searchFCModel: value });
|
55
|
-
setLoading?.(false);
|
56
50
|
}}
|
57
51
|
style={{
|
58
52
|
maxWidth: 160,
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { GlobeOffIcon } from '@lobehub/ui/icons';
|
2
2
|
import { useTheme } from 'antd-style';
|
3
3
|
import { Globe } from 'lucide-react';
|
4
|
-
import { memo
|
4
|
+
import { memo } from 'react';
|
5
5
|
import { useTranslation } from 'react-i18next';
|
6
6
|
|
7
7
|
import { isDeprecatedEdition } from '@/const/version';
|
@@ -15,7 +15,6 @@ import Controls from './Controls';
|
|
15
15
|
const Search = memo(() => {
|
16
16
|
const { t } = useTranslation('chat');
|
17
17
|
const [isLoading] = useAgentStore((s) => [agentSelectors.isAgentConfigLoading(s)]);
|
18
|
-
const [updating, setUpdating] = useState(false);
|
19
18
|
const isAgentEnableSearch = useAgentEnableSearch();
|
20
19
|
const theme = useTheme();
|
21
20
|
|
@@ -26,9 +25,8 @@ const Search = memo(() => {
|
|
26
25
|
<Action
|
27
26
|
color={isAgentEnableSearch ? theme.colorInfo : undefined}
|
28
27
|
icon={isAgentEnableSearch ? Globe : GlobeOffIcon}
|
29
|
-
loading={updating}
|
30
28
|
popover={{
|
31
|
-
content: <Controls
|
29
|
+
content: <Controls />,
|
32
30
|
maxWidth: 320,
|
33
31
|
minWidth: 320,
|
34
32
|
placement: 'topLeft',
|
@@ -44,11 +44,10 @@ interface IProps {
|
|
44
44
|
children?: ReactNode;
|
45
45
|
onOpenChange?: (open: boolean) => void;
|
46
46
|
open?: boolean;
|
47
|
-
setUpdating?: (updating: boolean) => void;
|
48
47
|
updating?: boolean;
|
49
48
|
}
|
50
49
|
|
51
|
-
const ModelSwitchPanel = memo<IProps>(({ children,
|
50
|
+
const ModelSwitchPanel = memo<IProps>(({ children, onOpenChange, open }) => {
|
52
51
|
const { t } = useTranslation('components');
|
53
52
|
const { styles, theme } = useStyles();
|
54
53
|
const [model, provider, updateAgentConfig] = useAgentStore((s) => [
|
@@ -66,9 +65,7 @@ const ModelSwitchPanel = memo<IProps>(({ children, setUpdating, onOpenChange, op
|
|
66
65
|
key: menuKey(provider.id, model.id),
|
67
66
|
label: <ModelItemRender {...model} {...model.abilities} />,
|
68
67
|
onClick: async () => {
|
69
|
-
setUpdating?.(true);
|
70
68
|
await updateAgentConfig({ model: model.id, provider: provider.id });
|
71
|
-
setUpdating?.(false);
|
72
69
|
},
|
73
70
|
}));
|
74
71
|
|
@@ -305,12 +305,14 @@ describe('LobeAnthropicAI', () => {
|
|
305
305
|
|
306
306
|
it('should build payload with tools and web search enabled', async () => {
|
307
307
|
const tools: ChatCompletionTool[] = [
|
308
|
-
{ function: { name: 'tool1', description: 'desc1' }, type: 'function' }
|
308
|
+
{ function: { name: 'tool1', description: 'desc1' }, type: 'function' },
|
309
309
|
];
|
310
310
|
|
311
311
|
const mockAnthropicTools = [{ name: 'tool1', description: 'desc1' }];
|
312
312
|
|
313
|
-
vi.spyOn(anthropicHelpers, 'buildAnthropicTools').mockReturnValue(
|
313
|
+
vi.spyOn(anthropicHelpers, 'buildAnthropicTools').mockReturnValue(
|
314
|
+
mockAnthropicTools as any,
|
315
|
+
);
|
314
316
|
|
315
317
|
const payload: ChatStreamPayload = {
|
316
318
|
messages: [{ content: 'Search and get info', role: 'user' }],
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import Anthropic from '@anthropic-ai/sdk';
|
2
2
|
import type { Stream } from '@anthropic-ai/sdk/streaming';
|
3
3
|
|
4
|
-
import {
|
4
|
+
import { CitationItem, ModelTokensUsage } from '@/types/message';
|
5
5
|
|
6
6
|
import { ChatStreamCallbacks } from '../../types';
|
7
7
|
import {
|
@@ -180,7 +180,7 @@ export const transformAnthropicStream = (
|
|
180
180
|
context.returnedCitationArray.push({
|
181
181
|
title: citations.title,
|
182
182
|
url: citations.url,
|
183
|
-
} as CitationItem)
|
183
|
+
} as CitationItem);
|
184
184
|
}
|
185
185
|
|
186
186
|
return { data: null, id: context.id, type: 'text' };
|
@@ -219,15 +219,16 @@ export const transformAnthropicStream = (
|
|
219
219
|
|
220
220
|
case 'message_stop': {
|
221
221
|
return [
|
222
|
-
...(context.returnedCitationArray?.length
|
223
|
-
? [
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
222
|
+
...(context.returnedCitationArray?.length
|
223
|
+
? [
|
224
|
+
{
|
225
|
+
data: { citations: context.returnedCitationArray },
|
226
|
+
id: context.id,
|
227
|
+
type: 'grounding',
|
228
|
+
},
|
229
|
+
]
|
230
|
+
: []),
|
231
|
+
{ data: 'message_stop', id: context.id, type: 'stop' },
|
231
232
|
] as any;
|
232
233
|
}
|
233
234
|
|
@@ -227,10 +227,12 @@ export const transformOpenAIStream = (
|
|
227
227
|
return [
|
228
228
|
{
|
229
229
|
data: {
|
230
|
-
citations: (citations as any[])
|
231
|
-
|
232
|
-
|
233
|
-
|
230
|
+
citations: (citations as any[])
|
231
|
+
.map((item) => ({
|
232
|
+
title: typeof item === 'string' ? item : item.title,
|
233
|
+
url: typeof item === 'string' ? item : item.url || item.link,
|
234
|
+
}))
|
235
|
+
.filter((c) => c.title && c.url), // Zhipu 内建搜索工具有时会返回空 link 引发程序崩溃
|
234
236
|
},
|
235
237
|
id: chunk.id,
|
236
238
|
type: 'grounding',
|
@@ -18,7 +18,7 @@ export interface StreamContext {
|
|
18
18
|
returnedCitation?: boolean;
|
19
19
|
/**
|
20
20
|
* Claude's citations are inline and interleaved with text output.
|
21
|
-
* Each text segment may carry references to sources (e.g., web search results)
|
21
|
+
* Each text segment may carry references to sources (e.g., web search results)
|
22
22
|
* relevant to that specific portion of the generated content.
|
23
23
|
* This array accumulates all citation items received during the streaming response.
|
24
24
|
*/
|
@@ -2,6 +2,7 @@ import OpenAI from 'openai';
|
|
2
2
|
import type { Stream } from 'openai/streaming';
|
3
3
|
|
4
4
|
import { ChatStreamCallbacks } from '../../types';
|
5
|
+
import { convertUsage } from '../usageConverter';
|
5
6
|
import {
|
6
7
|
StreamProtocolChunk,
|
7
8
|
StreamProtocolToolCallChunk,
|
@@ -11,8 +12,6 @@ import {
|
|
11
12
|
generateToolCallId,
|
12
13
|
} from './protocol';
|
13
14
|
|
14
|
-
import { convertUsage } from '../usageConverter';
|
15
|
-
|
16
15
|
export function transformSparkResponseToStream(data: OpenAI.ChatCompletion) {
|
17
16
|
return new ReadableStream({
|
18
17
|
start(controller) {
|
package/src/middleware.ts
CHANGED
@@ -0,0 +1,124 @@
|
|
1
|
+
import { TRPCError } from '@trpc/server';
|
2
|
+
import debug from 'debug';
|
3
|
+
import urlJoin from 'url-join';
|
4
|
+
|
5
|
+
import { SearchParams, UniformSearchResponse, UniformSearchResult } from '@/types/tool/search';
|
6
|
+
|
7
|
+
import { SearchServiceImpl } from '../type';
|
8
|
+
import { BochaSearchParameters, BochaResponse } from './type';
|
9
|
+
|
10
|
+
const log = debug('lobe-search:Bocha');
|
11
|
+
|
12
|
+
const timeRangeMapping = {
|
13
|
+
day: 'oneDay',
|
14
|
+
month: 'oneMonth',
|
15
|
+
week: 'oneWeek',
|
16
|
+
year: 'oneYear',
|
17
|
+
};
|
18
|
+
|
19
|
+
/**
|
20
|
+
* Bocha implementation of the search service
|
21
|
+
* Primarily used for web crawling
|
22
|
+
*/
|
23
|
+
export class BochaImpl implements SearchServiceImpl {
|
24
|
+
private get apiKey(): string | undefined {
|
25
|
+
return process.env.BOCHA_API_KEY;
|
26
|
+
}
|
27
|
+
|
28
|
+
private get baseUrl(): string {
|
29
|
+
// Assuming the base URL is consistent with the crawl endpoint
|
30
|
+
return 'https://api.bochaai.com/v1';
|
31
|
+
}
|
32
|
+
|
33
|
+
async query(query: string, params: SearchParams = {}): Promise<UniformSearchResponse> {
|
34
|
+
log('Starting Bocha query with query: "%s", params: %o', query, params);
|
35
|
+
const endpoint = urlJoin(this.baseUrl, '/web-search');
|
36
|
+
|
37
|
+
const defaultQueryParams: BochaSearchParameters = {
|
38
|
+
count: 15,
|
39
|
+
query,
|
40
|
+
summary: true,
|
41
|
+
};
|
42
|
+
|
43
|
+
let body: BochaSearchParameters = {
|
44
|
+
...defaultQueryParams,
|
45
|
+
freshness:
|
46
|
+
params?.searchTimeRange && params.searchTimeRange !== 'anytime'
|
47
|
+
? timeRangeMapping[params.searchTimeRange as keyof typeof timeRangeMapping] ?? undefined
|
48
|
+
: undefined,
|
49
|
+
};
|
50
|
+
|
51
|
+
log('Constructed request body: %o', body);
|
52
|
+
|
53
|
+
let response: Response;
|
54
|
+
const startAt = Date.now();
|
55
|
+
let costTime = 0;
|
56
|
+
try {
|
57
|
+
log('Sending request to endpoint: %s', endpoint);
|
58
|
+
response = await fetch(endpoint, {
|
59
|
+
body: JSON.stringify(body),
|
60
|
+
headers: {
|
61
|
+
'Authorization': this.apiKey ? `Bearer ${this.apiKey}` : '',
|
62
|
+
'Content-Type': 'application/json',
|
63
|
+
},
|
64
|
+
method: 'POST',
|
65
|
+
});
|
66
|
+
log('Received response with status: %d', response.status);
|
67
|
+
costTime = Date.now() - startAt;
|
68
|
+
} catch (error) {
|
69
|
+
log.extend('error')('Bocha fetch error: %o', error);
|
70
|
+
throw new TRPCError({
|
71
|
+
cause: error,
|
72
|
+
code: 'SERVICE_UNAVAILABLE',
|
73
|
+
message: 'Failed to connect to Bocha.',
|
74
|
+
});
|
75
|
+
}
|
76
|
+
|
77
|
+
if (!response.ok) {
|
78
|
+
const errorBody = await response.text();
|
79
|
+
log.extend('error')(
|
80
|
+
`Bocha request failed with status ${response.status}: %s`,
|
81
|
+
errorBody.length > 200 ? `${errorBody.slice(0, 200)}...` : errorBody,
|
82
|
+
);
|
83
|
+
throw new TRPCError({
|
84
|
+
cause: errorBody,
|
85
|
+
code: 'SERVICE_UNAVAILABLE',
|
86
|
+
message: `Bocha request failed: ${response.statusText}`,
|
87
|
+
});
|
88
|
+
}
|
89
|
+
|
90
|
+
try {
|
91
|
+
const bochaResponse = (await response.json()) as BochaResponse;
|
92
|
+
|
93
|
+
log('Parsed Bocha response: %o', bochaResponse);
|
94
|
+
|
95
|
+
const mappedResults = (bochaResponse.data.webPages.value || []).map(
|
96
|
+
(result): UniformSearchResult => ({
|
97
|
+
category: 'general', // Default category
|
98
|
+
content: result.summary || result.snippet || '', // Prioritize content, fallback to snippet
|
99
|
+
engines: ['bocha'], // Use 'bocha' as the engine name
|
100
|
+
parsedUrl: result.url ? new URL(result.url).hostname : '', // Basic URL parsing
|
101
|
+
score: 1, // Default score to 1
|
102
|
+
title: result.name || '',
|
103
|
+
url: result.url,
|
104
|
+
}),
|
105
|
+
);
|
106
|
+
|
107
|
+
log('Mapped %d results to SearchResult format', mappedResults.length);
|
108
|
+
|
109
|
+
return {
|
110
|
+
costTime,
|
111
|
+
query: query,
|
112
|
+
resultNumbers: mappedResults.length,
|
113
|
+
results: mappedResults,
|
114
|
+
};
|
115
|
+
} catch (error) {
|
116
|
+
log.extend('error')('Error parsing Bocha response: %o', error);
|
117
|
+
throw new TRPCError({
|
118
|
+
cause: error,
|
119
|
+
code: 'INTERNAL_SERVER_ERROR',
|
120
|
+
message: 'Failed to parse Bocha response.',
|
121
|
+
});
|
122
|
+
}
|
123
|
+
}
|
124
|
+
}
|
@@ -0,0 +1,47 @@
|
|
1
|
+
export interface BochaSearchParameters {
|
2
|
+
count?: number;
|
3
|
+
exclude?: string;
|
4
|
+
freshness?: string;
|
5
|
+
include?: string;
|
6
|
+
query: string;
|
7
|
+
summary?: boolean;
|
8
|
+
}
|
9
|
+
|
10
|
+
interface BochaQueryContext {
|
11
|
+
originalQuery: string;
|
12
|
+
}
|
13
|
+
|
14
|
+
interface BochaValue {
|
15
|
+
cachedPageUrl?: string;
|
16
|
+
dateLastCrawled?: string;
|
17
|
+
displayUrl?: string;
|
18
|
+
id?: string | null;
|
19
|
+
isFamilyFriendly?: boolean;
|
20
|
+
isNavigational?: boolean;
|
21
|
+
language?: string;
|
22
|
+
name: string;
|
23
|
+
siteName?: string;
|
24
|
+
snippet?: string;
|
25
|
+
summary?: string;
|
26
|
+
url: string;
|
27
|
+
}
|
28
|
+
|
29
|
+
interface BochaWebPages {
|
30
|
+
totalEstimatedMatches?: number;
|
31
|
+
value?: BochaValue[];
|
32
|
+
webSearchUrl?: string;
|
33
|
+
}
|
34
|
+
|
35
|
+
interface BochaData {
|
36
|
+
images?: any;
|
37
|
+
queryContext?: BochaQueryContext;
|
38
|
+
videos?: any;
|
39
|
+
webPages: BochaWebPages;
|
40
|
+
}
|
41
|
+
|
42
|
+
export interface BochaResponse {
|
43
|
+
code?: number;
|
44
|
+
data: BochaData;
|
45
|
+
log_id?: string;
|
46
|
+
msg?: string | null;
|
47
|
+
}
|