balibabu
commited on
Commit
·
99d136b
1
Parent(s):
6d4f792
feat: Add GoogleScholar #918 (#1818)
Browse files### What problem does this PR solve?
feat: Add GoogleScholar #918
### Type of change
- [x] New Feature (non-breaking change which adds functionality)
- web/src/assets/svg/google-scholar.svg +9 -0
- web/src/components/file-upload-modal/index.less +5 -0
- web/src/components/file-upload-modal/index.tsx +1 -0
- web/src/locales/en.ts +9 -0
- web/src/locales/zh-traditional.ts +7 -0
- web/src/locales/zh.ts +7 -0
- web/src/pages/flow/constant.tsx +15 -0
- web/src/pages/flow/flow-drawer/index.tsx +2 -0
- web/src/pages/flow/google-scholar-form/index.tsx +78 -0
- web/src/pages/flow/hooks.ts +2 -0
web/src/assets/svg/google-scholar.svg
ADDED
|
|
web/src/components/file-upload-modal/index.less
CHANGED
|
@@ -6,3 +6,8 @@
|
|
| 6 |
}
|
| 7 |
}
|
| 8 |
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
}
|
| 7 |
}
|
| 8 |
}
|
| 9 |
+
|
| 10 |
+
.uploadLimit {
|
| 11 |
+
color: red;
|
| 12 |
+
font-size: 12px;
|
| 13 |
+
}
|
web/src/components/file-upload-modal/index.tsx
CHANGED
|
@@ -53,6 +53,7 @@ const FileUpload = ({
|
|
| 53 |
</p>
|
| 54 |
<p className="ant-upload-text">{t('uploadTitle')}</p>
|
| 55 |
<p className="ant-upload-hint">{t('uploadDescription')}</p>
|
|
|
|
| 56 |
</Dragger>
|
| 57 |
);
|
| 58 |
};
|
|
|
|
| 53 |
</p>
|
| 54 |
<p className="ant-upload-text">{t('uploadTitle')}</p>
|
| 55 |
<p className="ant-upload-hint">{t('uploadDescription')}</p>
|
| 56 |
+
{false && <p className={styles.uploadLimit}>{t('uploadLimit')}</p>}
|
| 57 |
</Dragger>
|
| 58 |
);
|
| 59 |
};
|
web/src/locales/en.ts
CHANGED
|
@@ -562,6 +562,8 @@ The above is the content you need to summarize.`,
|
|
| 562 |
s3: 'S3 uploads',
|
| 563 |
preview: 'Preview',
|
| 564 |
fileError: 'File error',
|
|
|
|
|
|
|
| 565 |
},
|
| 566 |
flow: {
|
| 567 |
cite: 'Cite',
|
|
@@ -650,6 +652,13 @@ The above is the content you need to summarize.`,
|
|
| 650 |
apiKey: 'Api Key',
|
| 651 |
country: 'Country',
|
| 652 |
language: 'Language',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 653 |
},
|
| 654 |
footer: {
|
| 655 |
profile: 'All rights reserved @ React',
|
|
|
|
| 562 |
s3: 'S3 uploads',
|
| 563 |
preview: 'Preview',
|
| 564 |
fileError: 'File error',
|
| 565 |
+
uploadLimit:
|
| 566 |
+
'The file size cannot exceed 10M, and the total number of files cannot exceed 128',
|
| 567 |
},
|
| 568 |
flow: {
|
| 569 |
cite: 'Cite',
|
|
|
|
| 652 |
apiKey: 'Api Key',
|
| 653 |
country: 'Country',
|
| 654 |
language: 'Language',
|
| 655 |
+
googleScholar: 'Google Scholar',
|
| 656 |
+
googleScholarDescription:
|
| 657 |
+
'This component is used to get search result from https://scholar.google.com/. Typically, it performs as a supplement to knowledgebases. Top N specifies the number of search results you need to adapt.',
|
| 658 |
+
yearLow: 'Year low',
|
| 659 |
+
yearHigh: 'Year high',
|
| 660 |
+
patents: 'Patents',
|
| 661 |
+
data: 'Data',
|
| 662 |
},
|
| 663 |
footer: {
|
| 664 |
profile: 'All rights reserved @ React',
|
web/src/locales/zh-traditional.ts
CHANGED
|
@@ -523,6 +523,7 @@ export default {
|
|
| 523 |
s3: 'S3 上傳',
|
| 524 |
preview: '預覽',
|
| 525 |
fileError: '文件錯誤',
|
|
|
|
| 526 |
},
|
| 527 |
flow: {
|
| 528 |
cite: '引用',
|
|
@@ -610,6 +611,12 @@ export default {
|
|
| 610 |
apiKey: 'Api Key',
|
| 611 |
country: '國家',
|
| 612 |
language: '語言',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 613 |
},
|
| 614 |
footer: {
|
| 615 |
profile: '“保留所有權利 @ react”',
|
|
|
|
| 523 |
s3: 'S3 上傳',
|
| 524 |
preview: '預覽',
|
| 525 |
fileError: '文件錯誤',
|
| 526 |
+
uploadLimit: '文件大小不能超過10M,文件總數不超過128個',
|
| 527 |
},
|
| 528 |
flow: {
|
| 529 |
cite: '引用',
|
|
|
|
| 611 |
apiKey: 'Api Key',
|
| 612 |
country: '國家',
|
| 613 |
language: '語言',
|
| 614 |
+
googleScholar: '谷歌學術',
|
| 615 |
+
googleScholarDescription: `該元件用於從 https://scholar.google.com/ 取得搜尋結果。通常,它充當知識庫的補充。 Top N 指定您需要調整的搜尋結果的數量。`,
|
| 616 |
+
yearLow: '開始年份',
|
| 617 |
+
yearHigh: '結束年份',
|
| 618 |
+
patents: '專利',
|
| 619 |
+
data: '數據',
|
| 620 |
},
|
| 621 |
footer: {
|
| 622 |
profile: '“保留所有權利 @ react”',
|
web/src/locales/zh.ts
CHANGED
|
@@ -541,6 +541,7 @@ export default {
|
|
| 541 |
s3: 'S3 上传',
|
| 542 |
preview: '预览',
|
| 543 |
fileError: '文件错误',
|
|
|
|
| 544 |
},
|
| 545 |
flow: {
|
| 546 |
flow: '工作流',
|
|
@@ -628,6 +629,12 @@ export default {
|
|
| 628 |
apiKey: 'Api Key',
|
| 629 |
country: '国家',
|
| 630 |
language: '语言',
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 631 |
},
|
| 632 |
footer: {
|
| 633 |
profile: 'All rights reserved @ React',
|
|
|
|
| 541 |
s3: 'S3 上传',
|
| 542 |
preview: '预览',
|
| 543 |
fileError: '文件错误',
|
| 544 |
+
uploadLimit: '文件大小不能超过10M,文件总数不超过128个',
|
| 545 |
},
|
| 546 |
flow: {
|
| 547 |
flow: '工作流',
|
|
|
|
| 629 |
apiKey: 'Api Key',
|
| 630 |
country: '国家',
|
| 631 |
language: '语言',
|
| 632 |
+
googleScholar: '谷歌学术',
|
| 633 |
+
googleScholarDescription: `此组件用于从 https://scholar.google.com/ 获取搜索结果。通常,它作为知识库的补充。Top N 指定您需要调整的搜索结果数量。`,
|
| 634 |
+
yearLow: '开始年份',
|
| 635 |
+
yearHigh: '结束年份',
|
| 636 |
+
patents: '专利',
|
| 637 |
+
data: '数据',
|
| 638 |
},
|
| 639 |
footer: {
|
| 640 |
profile: 'All rights reserved @ React',
|
web/src/pages/flow/constant.tsx
CHANGED
|
@@ -2,6 +2,7 @@ import { ReactComponent as ArXivIcon } from '@/assets/svg/arxiv.svg';
|
|
| 2 |
import { ReactComponent as BaiduIcon } from '@/assets/svg/baidu.svg';
|
| 3 |
import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg';
|
| 4 |
import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg';
|
|
|
|
| 5 |
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
| 6 |
import { ReactComponent as KeywordIcon } from '@/assets/svg/keyword.svg';
|
| 7 |
import { ReactComponent as PubMedIcon } from '@/assets/svg/pubmed.svg';
|
|
@@ -44,6 +45,7 @@ export enum Operator {
|
|
| 44 |
ArXiv = 'ArXiv',
|
| 45 |
Google = 'Google',
|
| 46 |
Bing = 'Bing',
|
|
|
|
| 47 |
}
|
| 48 |
|
| 49 |
export const operatorIconMap = {
|
|
@@ -63,6 +65,7 @@ export const operatorIconMap = {
|
|
| 63 |
[Operator.ArXiv]: ArXivIcon,
|
| 64 |
[Operator.Google]: GoogleIcon,
|
| 65 |
[Operator.Bing]: BingIcon,
|
|
|
|
| 66 |
};
|
| 67 |
|
| 68 |
export const operatorMap = {
|
|
@@ -145,6 +148,7 @@ export const operatorMap = {
|
|
| 145 |
backgroundColor: 'pink',
|
| 146 |
},
|
| 147 |
[Operator.Bing]: {},
|
|
|
|
| 148 |
};
|
| 149 |
|
| 150 |
export const componentMenuList = [
|
|
@@ -193,6 +197,9 @@ export const componentMenuList = [
|
|
| 193 |
{
|
| 194 |
name: Operator.Bing,
|
| 195 |
},
|
|
|
|
|
|
|
|
|
|
| 196 |
];
|
| 197 |
|
| 198 |
export const initialRetrievalValues = {
|
|
@@ -291,6 +298,12 @@ export const initialBingValues = {
|
|
| 291 |
language: 'en',
|
| 292 |
};
|
| 293 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 294 |
export const CategorizeAnchorPointPositions = [
|
| 295 |
{ top: 1, right: 34 },
|
| 296 |
{ top: 8, right: 18 },
|
|
@@ -354,6 +367,7 @@ export const RestrictedUpstreamMap = {
|
|
| 354 |
[Operator.ArXiv]: [Operator.Begin, Operator.Retrieval],
|
| 355 |
[Operator.Google]: [Operator.Begin, Operator.Retrieval],
|
| 356 |
[Operator.Bing]: [Operator.Begin, Operator.Retrieval],
|
|
|
|
| 357 |
};
|
| 358 |
|
| 359 |
export const NodeMap = {
|
|
@@ -373,6 +387,7 @@ export const NodeMap = {
|
|
| 373 |
[Operator.ArXiv]: 'ragNode',
|
| 374 |
[Operator.Google]: 'ragNode',
|
| 375 |
[Operator.Bing]: 'ragNode',
|
|
|
|
| 376 |
};
|
| 377 |
|
| 378 |
export const LanguageOptions = [
|
|
|
|
| 2 |
import { ReactComponent as BaiduIcon } from '@/assets/svg/baidu.svg';
|
| 3 |
import { ReactComponent as BingIcon } from '@/assets/svg/bing.svg';
|
| 4 |
import { ReactComponent as DuckIcon } from '@/assets/svg/duck.svg';
|
| 5 |
+
import { ReactComponent as GoogleScholarIcon } from '@/assets/svg/google-scholar.svg';
|
| 6 |
import { ReactComponent as GoogleIcon } from '@/assets/svg/google.svg';
|
| 7 |
import { ReactComponent as KeywordIcon } from '@/assets/svg/keyword.svg';
|
| 8 |
import { ReactComponent as PubMedIcon } from '@/assets/svg/pubmed.svg';
|
|
|
|
| 45 |
ArXiv = 'ArXiv',
|
| 46 |
Google = 'Google',
|
| 47 |
Bing = 'Bing',
|
| 48 |
+
GoogleScholar = 'GoogleScholar',
|
| 49 |
}
|
| 50 |
|
| 51 |
export const operatorIconMap = {
|
|
|
|
| 65 |
[Operator.ArXiv]: ArXivIcon,
|
| 66 |
[Operator.Google]: GoogleIcon,
|
| 67 |
[Operator.Bing]: BingIcon,
|
| 68 |
+
[Operator.GoogleScholar]: GoogleScholarIcon,
|
| 69 |
};
|
| 70 |
|
| 71 |
export const operatorMap = {
|
|
|
|
| 148 |
backgroundColor: 'pink',
|
| 149 |
},
|
| 150 |
[Operator.Bing]: {},
|
| 151 |
+
[Operator.GoogleScholar]: {},
|
| 152 |
};
|
| 153 |
|
| 154 |
export const componentMenuList = [
|
|
|
|
| 197 |
{
|
| 198 |
name: Operator.Bing,
|
| 199 |
},
|
| 200 |
+
{
|
| 201 |
+
name: Operator.GoogleScholar,
|
| 202 |
+
},
|
| 203 |
];
|
| 204 |
|
| 205 |
export const initialRetrievalValues = {
|
|
|
|
| 298 |
language: 'en',
|
| 299 |
};
|
| 300 |
|
| 301 |
+
export const initialGoogleScholarValues = {
|
| 302 |
+
top_n: 5,
|
| 303 |
+
sort_by: 'relevance',
|
| 304 |
+
patents: true,
|
| 305 |
+
};
|
| 306 |
+
|
| 307 |
export const CategorizeAnchorPointPositions = [
|
| 308 |
{ top: 1, right: 34 },
|
| 309 |
{ top: 8, right: 18 },
|
|
|
|
| 367 |
[Operator.ArXiv]: [Operator.Begin, Operator.Retrieval],
|
| 368 |
[Operator.Google]: [Operator.Begin, Operator.Retrieval],
|
| 369 |
[Operator.Bing]: [Operator.Begin, Operator.Retrieval],
|
| 370 |
+
[Operator.GoogleScholar]: [Operator.Begin, Operator.Retrieval],
|
| 371 |
};
|
| 372 |
|
| 373 |
export const NodeMap = {
|
|
|
|
| 387 |
[Operator.ArXiv]: 'ragNode',
|
| 388 |
[Operator.Google]: 'ragNode',
|
| 389 |
[Operator.Bing]: 'ragNode',
|
| 390 |
+
[Operator.GoogleScholar]: 'ragNode',
|
| 391 |
};
|
| 392 |
|
| 393 |
export const LanguageOptions = [
|
web/src/pages/flow/flow-drawer/index.tsx
CHANGED
|
@@ -13,6 +13,7 @@ import { Operator } from '../constant';
|
|
| 13 |
import DuckDuckGoForm from '../duckduckgo-form';
|
| 14 |
import GenerateForm from '../generate-form';
|
| 15 |
import GoogleForm from '../google-form';
|
|
|
|
| 16 |
import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks';
|
| 17 |
import KeywordExtractForm from '../keyword-extract-form';
|
| 18 |
import MessageForm from '../message-form';
|
|
@@ -46,6 +47,7 @@ const FormMap = {
|
|
| 46 |
[Operator.ArXiv]: ArXivForm,
|
| 47 |
[Operator.Google]: GoogleForm,
|
| 48 |
[Operator.Bing]: BingForm,
|
|
|
|
| 49 |
};
|
| 50 |
|
| 51 |
const EmptyContent = () => <div>empty</div>;
|
|
|
|
| 13 |
import DuckDuckGoForm from '../duckduckgo-form';
|
| 14 |
import GenerateForm from '../generate-form';
|
| 15 |
import GoogleForm from '../google-form';
|
| 16 |
+
import GoogleScholarForm from '../google-scholar-form';
|
| 17 |
import { useHandleFormValuesChange, useHandleNodeNameChange } from '../hooks';
|
| 18 |
import KeywordExtractForm from '../keyword-extract-form';
|
| 19 |
import MessageForm from '../message-form';
|
|
|
|
| 47 |
[Operator.ArXiv]: ArXivForm,
|
| 48 |
[Operator.Google]: GoogleForm,
|
| 49 |
[Operator.Bing]: BingForm,
|
| 50 |
+
[Operator.GoogleScholar]: GoogleScholarForm,
|
| 51 |
};
|
| 52 |
|
| 53 |
const EmptyContent = () => <div>empty</div>;
|
web/src/pages/flow/google-scholar-form/index.tsx
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import TopNItem from '@/components/top-n-item';
|
| 2 |
+
import { useTranslate } from '@/hooks/common-hooks';
|
| 3 |
+
import { DatePicker, DatePickerProps, Form, Select, Switch } from 'antd';
|
| 4 |
+
import dayjs from 'dayjs';
|
| 5 |
+
import { useCallback, useMemo } from 'react';
|
| 6 |
+
import { IOperatorForm } from '../interface';
|
| 7 |
+
|
| 8 |
+
const YearPicker = ({
|
| 9 |
+
onChange,
|
| 10 |
+
value,
|
| 11 |
+
}: {
|
| 12 |
+
onChange?: (val: number | undefined) => void;
|
| 13 |
+
value?: number | undefined;
|
| 14 |
+
}) => {
|
| 15 |
+
const handleChange: DatePickerProps['onChange'] = useCallback(
|
| 16 |
+
(val: any) => {
|
| 17 |
+
const nextVal = val?.format('YYYY');
|
| 18 |
+
onChange?.(nextVal ? Number(nextVal) : undefined);
|
| 19 |
+
},
|
| 20 |
+
[onChange],
|
| 21 |
+
);
|
| 22 |
+
// The year needs to be converted into a number and saved to the backend
|
| 23 |
+
const nextValue = useMemo(() => {
|
| 24 |
+
if (value) {
|
| 25 |
+
return dayjs(value.toString());
|
| 26 |
+
}
|
| 27 |
+
return undefined;
|
| 28 |
+
}, [value]);
|
| 29 |
+
|
| 30 |
+
return <DatePicker picker="year" onChange={handleChange} value={nextValue} />;
|
| 31 |
+
};
|
| 32 |
+
|
| 33 |
+
const GoogleScholarForm = ({ onValuesChange, form }: IOperatorForm) => {
|
| 34 |
+
const { t } = useTranslate('flow');
|
| 35 |
+
|
| 36 |
+
const options = useMemo(() => {
|
| 37 |
+
return ['data', 'relevance'].map((x) => ({
|
| 38 |
+
value: x,
|
| 39 |
+
label: t(x),
|
| 40 |
+
}));
|
| 41 |
+
}, [t]);
|
| 42 |
+
|
| 43 |
+
return (
|
| 44 |
+
<Form
|
| 45 |
+
name="basic"
|
| 46 |
+
labelCol={{ span: 6 }}
|
| 47 |
+
wrapperCol={{ span: 18 }}
|
| 48 |
+
autoComplete="off"
|
| 49 |
+
form={form}
|
| 50 |
+
onValuesChange={onValuesChange}
|
| 51 |
+
>
|
| 52 |
+
<TopNItem initialValue={5}></TopNItem>
|
| 53 |
+
<Form.Item
|
| 54 |
+
label={t('sortBy')}
|
| 55 |
+
name={'sort_by'}
|
| 56 |
+
initialValue={'relevance'}
|
| 57 |
+
>
|
| 58 |
+
<Select options={options}></Select>
|
| 59 |
+
</Form.Item>
|
| 60 |
+
<Form.Item label={t('yearLow')} name={'year_low'}>
|
| 61 |
+
<YearPicker />
|
| 62 |
+
</Form.Item>
|
| 63 |
+
<Form.Item label={t('yearHigh')} name={'year_high'}>
|
| 64 |
+
<YearPicker />
|
| 65 |
+
</Form.Item>
|
| 66 |
+
<Form.Item
|
| 67 |
+
label={t('patents')}
|
| 68 |
+
name={'patents'}
|
| 69 |
+
valuePropName="checked"
|
| 70 |
+
initialValue={true}
|
| 71 |
+
>
|
| 72 |
+
<Switch></Switch>
|
| 73 |
+
</Form.Item>
|
| 74 |
+
</Form>
|
| 75 |
+
);
|
| 76 |
+
};
|
| 77 |
+
|
| 78 |
+
export default GoogleScholarForm;
|
web/src/pages/flow/hooks.ts
CHANGED
|
@@ -37,6 +37,7 @@ import {
|
|
| 37 |
initialCategorizeValues,
|
| 38 |
initialDuckValues,
|
| 39 |
initialGenerateValues,
|
|
|
|
| 40 |
initialGoogleValues,
|
| 41 |
initialKeywordExtractValues,
|
| 42 |
initialMessageValues,
|
|
@@ -97,6 +98,7 @@ export const useInitializeOperatorParams = () => {
|
|
| 97 |
[Operator.ArXiv]: initialArXivValues,
|
| 98 |
[Operator.Google]: initialGoogleValues,
|
| 99 |
[Operator.Bing]: initialBingValues,
|
|
|
|
| 100 |
};
|
| 101 |
}, [llmId]);
|
| 102 |
|
|
|
|
| 37 |
initialCategorizeValues,
|
| 38 |
initialDuckValues,
|
| 39 |
initialGenerateValues,
|
| 40 |
+
initialGoogleScholarValues,
|
| 41 |
initialGoogleValues,
|
| 42 |
initialKeywordExtractValues,
|
| 43 |
initialMessageValues,
|
|
|
|
| 98 |
[Operator.ArXiv]: initialArXivValues,
|
| 99 |
[Operator.Google]: initialGoogleValues,
|
| 100 |
[Operator.Bing]: initialBingValues,
|
| 101 |
+
[Operator.GoogleScholar]: initialGoogleScholarValues,
|
| 102 |
};
|
| 103 |
}, [llmId]);
|
| 104 |
|