Skip to content

Commit 1a37846

Browse files
arvinxxlikaiqiang
authored andcommitted
✨ feat: support pplx search grounding (lobehub#6331)
1 parent 5ae0450 commit 1a37846

File tree

33 files changed

+4125
-85
lines changed

33 files changed

+4125
-85
lines changed

locales/en-US/components.json

+3-3
Original file line numberDiff line numberDiff line change
@@ -111,8 +111,8 @@
111111
}
112112
},
113113
"Thinking": {
114-
"thinking": "Deep in thought...",
115-
"thought": "Deeply thought (took {{duration}} seconds)",
116-
"thoughtWithDuration": "Deeply thought"
114+
"thinking": "Deep Thinking...",
115+
"thought": "Deeply Thought (in {{duration}} seconds)",
116+
"thoughtWithDuration": "Deeply Thought"
117117
}
118118
}

package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,7 @@
129129
"@lobehub/chat-plugins-gateway": "^1.9.0",
130130
"@lobehub/icons": "^1.73.1",
131131
"@lobehub/tts": "^1.28.0",
132-
"@lobehub/ui": "^1.164.15",
132+
"@lobehub/ui": "^1.165.0",
133133
"@neondatabase/serverless": "^0.10.4",
134134
"@next/third-parties": "^15.1.4",
135135
"@react-spring/web": "^9.7.5",

src/components/ModelSelect/index.tsx

+24-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,14 @@ import { IconAvatarProps, ModelIcon, ProviderIcon } from '@lobehub/icons';
22
import { Avatar, Icon, Tooltip } from '@lobehub/ui';
33
import { Typography } from 'antd';
44
import { createStyles } from 'antd-style';
5-
import { Infinity, AtomIcon, LucideEye, LucidePaperclip, ToyBrick } from 'lucide-react';
5+
import {
6+
Infinity,
7+
AtomIcon,
8+
LucideEye,
9+
LucideGlobe,
10+
LucidePaperclip,
11+
ToyBrick,
12+
} from 'lucide-react';
613
import numeral from 'numeral';
714
import { rgba } from 'polished';
815
import { FC, memo } from 'react';
@@ -14,7 +21,7 @@ import { AiProviderSourceType } from '@/types/aiProvider';
1421
import { ChatModelCard } from '@/types/llm';
1522
import { formatTokenNumber } from '@/utils/format';
1623

17-
const useStyles = createStyles(({ css, token }) => ({
24+
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
1825
custom: css`
1926
width: 36px;
2027
height: 20px;
@@ -41,6 +48,10 @@ const useStyles = createStyles(({ css, token }) => ({
4148
color: ${token.geekblue};
4249
background: ${token.geekblue1};
4350
`,
51+
tagCyan: css`
52+
color: ${isDarkMode ? token.cyan7 : token.cyan10};
53+
background: ${isDarkMode ? token.cyan1 : token.cyan2};
54+
`,
4455
tagGreen: css`
4556
color: ${token.green};
4657
background: ${token.green1};
@@ -122,6 +133,17 @@ export const ModelInfoTags = memo<ModelInfoTagsProps>(
122133
</div>
123134
</Tooltip>
124135
)}
136+
{model.search && (
137+
<Tooltip
138+
placement={placement}
139+
styles={{ root: { pointerEvents: 'none' } }}
140+
title={t('ModelSelect.featureTag.search')}
141+
>
142+
<div className={cx(styles.tag, styles.tagCyan)} style={{ cursor: 'pointer' }} title="">
143+
<Icon icon={LucideGlobe} />
144+
</div>
145+
</Tooltip>
146+
)}
125147
{typeof model.contextWindowTokens === 'number' && (
126148
<Tooltip
127149
placement={placement}

src/components/Thinking/index.tsx

+7-2
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ import { CSSProperties, memo, useEffect, useState } from 'react';
77
import { useTranslation } from 'react-i18next';
88
import { Flexbox } from 'react-layout-kit';
99

10+
import { CitationItem } from '@/types/message';
11+
1012
const useStyles = createStyles(({ css, token, isDarkMode }) => ({
1113
container: css`
1214
width: fit-content;
@@ -59,13 +61,14 @@ const useStyles = createStyles(({ css, token, isDarkMode }) => ({
5961
}));
6062

6163
interface ThinkingProps {
64+
citations?: CitationItem[];
6265
content?: string;
6366
duration?: number;
6467
style?: CSSProperties;
6568
thinking?: boolean;
6669
}
6770

68-
const Thinking = memo<ThinkingProps>(({ content, duration, thinking, style }) => {
71+
const Thinking = memo<ThinkingProps>(({ content, duration, thinking, style, citations }) => {
6972
const { t } = useTranslation(['components', 'common']);
7073
const { styles, cx } = useStyles();
7174

@@ -135,7 +138,9 @@ const Thinking = memo<ThinkingProps>(({ content, duration, thinking, style }) =>
135138
}}
136139
>
137140
{typeof content === 'string' ? (
138-
<Markdown variant={'chat'}>{content}</Markdown>
141+
<Markdown citations={citations} variant={'chat'}>
142+
{content}
143+
</Markdown>
139144
) : (
140145
content
141146
)}

src/config/aiModels/jina.ts

+7-5
Original file line numberDiff line numberDiff line change
@@ -4,19 +4,21 @@ const jinaChatModels: AIChatModelCard[] = [
44
{
55
abilities: {
66
reasoning: true,
7+
search: true,
78
},
89
contextWindowTokens: 1_000_000,
9-
description: '深度搜索结合了网络搜索、阅读和推理,可进行全面调查。您可以将其视为一个代理,接受您的研究任务 - 它会进行广泛搜索并经过多次迭代,然后才能给出答案。这个过程涉及持续的研究、推理和从各个角度解决问题。这与直接从预训练数据生成答案的标准大模型以及依赖一次性表面搜索的传统 RAG 系统有着根本的不同。',
10+
description:
11+
'深度搜索结合了网络搜索、阅读和推理,可进行全面调查。您可以将其视为一个代理,接受您的研究任务 - 它会进行广泛搜索并经过多次迭代,然后才能给出答案。这个过程涉及持续的研究、推理和从各个角度解决问题。这与直接从预训练数据生成答案的标准大模型以及依赖一次性表面搜索的传统 RAG 系统有着根本的不同。',
1012
displayName: 'Jina DeepSearch v1',
1113
enabled: true,
1214
id: 'jina-deepsearch-v1',
1315
pricing: {
1416
input: 0.02,
15-
output: 0.02
17+
output: 0.02,
1618
},
17-
type: 'chat'
18-
}
19-
]
19+
type: 'chat',
20+
},
21+
];
2022

2123
export const allModels = [...jinaChatModels];
2224

src/config/aiModels/perplexity.ts

+8
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ const perplexityChatModels: AIChatModelCard[] = [
44
{
55
abilities: {
66
reasoning: true,
7+
search: true,
78
},
89
contextWindowTokens: 127_072,
910
description: '由 DeepSeek 推理模型提供支持的新 API 产品。',
@@ -16,6 +17,7 @@ const perplexityChatModels: AIChatModelCard[] = [
1617
{
1718
abilities: {
1819
reasoning: true,
20+
search: true,
1921
},
2022
contextWindowTokens: 127_072,
2123
description: '由 DeepSeek 推理模型提供支持的新 API 产品。',
@@ -26,6 +28,9 @@ const perplexityChatModels: AIChatModelCard[] = [
2628
type: 'chat',
2729
},
2830
{
31+
abilities: {
32+
search: true,
33+
},
2934
contextWindowTokens: 200_000,
3035
description: '支持搜索上下文的高级搜索产品,支持高级查询和跟进。',
3136
displayName: 'Sonar Pro',
@@ -34,6 +39,9 @@ const perplexityChatModels: AIChatModelCard[] = [
3439
type: 'chat',
3540
},
3641
{
42+
abilities: {
43+
search: true,
44+
},
3745
contextWindowTokens: 127_072,
3846
description: '基于搜索上下文的轻量级搜索产品,比 Sonar Pro 更快、更便宜。',
3947
displayName: 'Sonar',

src/database/client/migrations.json

+12-8
Original file line numberDiff line numberDiff line change
@@ -223,10 +223,7 @@
223223
"hash": "9646161fa041354714f823d726af27247bcd6e60fa3be5698c0d69f337a5700b"
224224
},
225225
{
226-
"sql": [
227-
"DROP TABLE \"user_budgets\";",
228-
"\nDROP TABLE \"user_subscriptions\";"
229-
],
226+
"sql": ["DROP TABLE \"user_budgets\";", "\nDROP TABLE \"user_subscriptions\";"],
230227
"bps": true,
231228
"folderMillis": 1729699958471,
232229
"hash": "7dad43a2a25d1aec82124a4e53f8d82f8505c3073f23606c1dc5d2a4598eacf9"
@@ -298,11 +295,18 @@
298295
"hash": "845a692ceabbfc3caf252a97d3e19a213bc0c433df2689900135f9cfded2cf49"
299296
},
300297
{
301-
"sql": [
302-
"ALTER TABLE \"messages\" ADD COLUMN \"reasoning\" jsonb;"
303-
],
298+
"sql": ["ALTER TABLE \"messages\" ADD COLUMN \"reasoning\" jsonb;"],
304299
"bps": true,
305300
"folderMillis": 1737609172353,
306301
"hash": "2cb36ae4fcdd7b7064767e04bfbb36ae34518ff4bb1b39006f2dd394d1893868"
302+
},
303+
{
304+
"sql": [
305+
"ALTER TABLE \"messages\" ADD COLUMN \"search\" jsonb;",
306+
"\nALTER TABLE \"messages\" ADD COLUMN \"metadata\" jsonb;"
307+
],
308+
"bps": true,
309+
"folderMillis": 1739901891891,
310+
"hash": "78d8fefd8c58938d7bc3da2295a73b35ce2e8d7cb2820f8e817acdb8dd5bebb2"
307311
}
308-
]
312+
]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
ALTER TABLE "messages" ADD COLUMN "search" jsonb;--> statement-breakpoint
2+
ALTER TABLE "messages" ADD COLUMN "metadata" jsonb;

0 commit comments

Comments
 (0)