feat: manually mirror opencoze's code from bytedance
Change-Id: I09a73aadda978ad9511264a756b2ce51f5761adf
This commit is contained in:
@@ -0,0 +1,239 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import copy from 'copy-to-clipboard';
|
||||
import { BotE2e } from '@coze-data/e2e';
|
||||
import { I18n, getUnReactiveLanguage } from '@coze-arch/i18n';
|
||||
import { UITag, Toast, Tooltip, Image, Typography } from '@coze-arch/bot-semi';
|
||||
import { IconCopy } from '@coze-arch/bot-icons';
|
||||
import {
|
||||
KnowledgeShowSourceMode,
|
||||
KnowledgeNoRecallReplyMode,
|
||||
} from '@coze-arch/bot-api/playground_api';
|
||||
|
||||
import ZhCustomizePromptPNG from '../assets/customize-prompt-zh.png';
|
||||
import EnCustomizePromptPNG from '../assets/customize-prompt-en.png';
|
||||
import { type RadioItem } from './radio-group-setting';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export const MAX_TOP_K_VALUE = 5;
|
||||
export const FULL_TEXT_SEARCH_KEY = 20;
|
||||
|
||||
export const getSearchStrategyOptions = () => [
|
||||
{
|
||||
label: I18n.t('knowledge_hybird_search_title'),
|
||||
value: 1,
|
||||
tip: I18n.t('knowledge_hybird_search_tooltip'),
|
||||
},
|
||||
{
|
||||
label: I18n.t('knowledge_semantic_search_title'),
|
||||
value: 0,
|
||||
tip: I18n.t('knowledge_semantic_search_tooltip'),
|
||||
},
|
||||
{
|
||||
label: I18n.t('knowledge_full_text_search_title'),
|
||||
value: 20,
|
||||
tip: I18n.t('knowledge_full_text_search_tooltip'),
|
||||
},
|
||||
];
|
||||
|
||||
export const getAutomaticCallOptions = () => {
|
||||
const onCopy = (text: string) => {
|
||||
const res = copy(text);
|
||||
if (!res) {
|
||||
return;
|
||||
}
|
||||
Toast.success({
|
||||
content: I18n.t('copy_success'),
|
||||
showClose: false,
|
||||
});
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
e2e: BotE2e.BotKnowledgeSettingModalAutoRadio,
|
||||
label: I18n.t('dataset_automatic_call'),
|
||||
value: 1,
|
||||
},
|
||||
{
|
||||
e2e: BotE2e.BotKnowledgeSettingModalManualRadio,
|
||||
label: I18n.t('dataset_on_demand_call'),
|
||||
value: 0,
|
||||
desc: (
|
||||
<>
|
||||
{I18n.t('bot_edit_dataset_on_demand_prompt1')}
|
||||
<Tooltip content={I18n.t('bot_edit_datasets_copyName')}>
|
||||
<UITag
|
||||
onClick={() => onCopy(I18n.t('dataset_recall_copy_value'))}
|
||||
type="light"
|
||||
className={styles['setting-item-copy']}
|
||||
>
|
||||
{I18n.t('dataset_recall_copy_label')}
|
||||
<IconCopy className={styles['icon-copy']} />
|
||||
</UITag>
|
||||
</Tooltip>
|
||||
{I18n.t('bot_edit_dataset_on_demand_prompt2')}
|
||||
</>
|
||||
),
|
||||
},
|
||||
];
|
||||
};
|
||||
|
||||
export const getNoRecallReplyOptions = (): RadioItem[] => [
|
||||
{
|
||||
e2e: BotE2e.BotKnowledgeSettingNoRecallReplyModeDefaultRadio,
|
||||
label: I18n.t('No_recall_003'),
|
||||
value: KnowledgeNoRecallReplyMode.Default,
|
||||
},
|
||||
{
|
||||
e2e: BotE2e.BotKnowledgeSettingNoRecallReplyModeCustomizePromptRadio,
|
||||
label: I18n.t('No_recall_004'),
|
||||
value: KnowledgeNoRecallReplyMode.CustomizePrompt,
|
||||
tip: (
|
||||
<>
|
||||
<div
|
||||
style={{
|
||||
lineHeight: '20px',
|
||||
color: 'rgba(29, 28, 35, 1)',
|
||||
marginBottom: '8px',
|
||||
}}
|
||||
>
|
||||
{I18n.t('No_recall_007')}
|
||||
</div>
|
||||
<Image
|
||||
width={344}
|
||||
preview={false}
|
||||
src={
|
||||
I18n.language === 'zh-CN'
|
||||
? ZhCustomizePromptPNG
|
||||
: EnCustomizePromptPNG
|
||||
}
|
||||
/>
|
||||
</>
|
||||
),
|
||||
tipStyle: {
|
||||
backgroundColor: '#fff',
|
||||
padding: '16px',
|
||||
minWidth: '376px',
|
||||
maxWidth: '376px',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
export const localeMapLink: Record<string, string> = {
|
||||
'zh-CN': '/docs/guides/knowledge',
|
||||
en: '/docs/guides/knowledge_overview?_lang=en',
|
||||
};
|
||||
|
||||
export const getShowSourceModeOptions = (): RadioItem[] => {
|
||||
const language = getUnReactiveLanguage();
|
||||
|
||||
const goToGuides = (module = 'knowledge') => {
|
||||
window.open(
|
||||
`${window.location.origin}${
|
||||
localeMapLink[language] || `/docs/guides/${module}`
|
||||
}`,
|
||||
);
|
||||
};
|
||||
|
||||
return [
|
||||
{
|
||||
e2e: BotE2e.BotKnowledgeSettingShowSourceModeCardRadio,
|
||||
label: I18n.t('knowledge_source_card_0002'),
|
||||
value: KnowledgeShowSourceMode.CardList,
|
||||
tip: (
|
||||
<div className={styles['show-source-mode-tip']}>
|
||||
<div className={styles.title}>
|
||||
{I18n.t('knowledge_source_card_0004')}
|
||||
</div>
|
||||
<div className={styles.space}>
|
||||
{[
|
||||
{
|
||||
title: I18n.t('what_is_coze'),
|
||||
content: I18n.t('landingpage_description'),
|
||||
guideModule: 'welcome',
|
||||
},
|
||||
{
|
||||
title: I18n.t('knowledge_source_display_tooltip_link'),
|
||||
content: I18n.t('knowledge_source_display_tooltip_content'),
|
||||
guideModule: 'knowledge',
|
||||
},
|
||||
].map(i => (
|
||||
<div
|
||||
className={styles.card}
|
||||
onClick={e => {
|
||||
goToGuides(i.guideModule);
|
||||
}}
|
||||
>
|
||||
<div className={styles.title}>
|
||||
<div>{i.title}</div>
|
||||
</div>
|
||||
<Typography.Text
|
||||
className={styles.content}
|
||||
ellipsis={{
|
||||
rows: 3,
|
||||
showTooltip: false,
|
||||
}}
|
||||
>
|
||||
{i.content}
|
||||
</Typography.Text>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
tipStyle: {
|
||||
backgroundColor: '#fff',
|
||||
maxWidth: '436px',
|
||||
minWidth: '436px',
|
||||
padding: '16px',
|
||||
},
|
||||
},
|
||||
{
|
||||
e2e: BotE2e.BotKnowledgeSettingShowSourceModeTextRadio,
|
||||
label: I18n.t('knowledge_source_card_0001'),
|
||||
value: KnowledgeShowSourceMode.ReplyBottom,
|
||||
tip: (
|
||||
<div className={styles['show-source-mode-tip']}>
|
||||
<div className={styles.title}>
|
||||
{I18n.t('knowledge_source_card_0003')}
|
||||
</div>
|
||||
<div className={styles.main}>
|
||||
<Typography.Text className={styles.content}>
|
||||
{I18n.t('knowledge_source_display_tooltip_content')}
|
||||
</Typography.Text>
|
||||
<div className={styles.link}>
|
||||
<div
|
||||
onClick={e => {
|
||||
goToGuides();
|
||||
}}
|
||||
>
|
||||
1. {I18n.t('knowledge_source_display_tooltip_link')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
),
|
||||
tipStyle: {
|
||||
backgroundColor: '#fff',
|
||||
maxWidth: '436px',
|
||||
minWidth: '436px',
|
||||
padding: '16px',
|
||||
},
|
||||
},
|
||||
];
|
||||
};
|
||||
@@ -0,0 +1,411 @@
|
||||
/* stylelint-disable declaration-no-important */
|
||||
/* stylelint-disable no-descending-specificity */
|
||||
/* stylelint-disable selector-class-pattern */
|
||||
@common-box-shadow: 0px 2px 8px 0px rgba(31, 35, 41, 0.02),
|
||||
0px 2px 4px 0px rgba(31, 35, 41, 0.02), 0px 2px 2px 0px rgba(31, 35, 41, 0.02);
|
||||
|
||||
.common-svg-icon(@size: 14px, @color: #4d53e8) {
|
||||
>svg {
|
||||
width: @size;
|
||||
height: @size;
|
||||
|
||||
>path {
|
||||
fill: @color;
|
||||
fill-opacity: 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.text {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
font-style: normal;
|
||||
line-height: 16px;
|
||||
}
|
||||
|
||||
.icon-copy {
|
||||
cursor: pointer;
|
||||
padding: 2px;
|
||||
border-radius: 4px;
|
||||
.common-svg-icon(14px, rgba(107, 109, 117, 1));
|
||||
|
||||
&:hover {
|
||||
background-color: var(--semi-color-fill-0);
|
||||
}
|
||||
}
|
||||
|
||||
.data-set-info {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.default-text {
|
||||
.text;
|
||||
|
||||
padding: 4px 0;
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
color: var(--light-usage-text-color-text-2, rgb(28 29 35 / 60%));
|
||||
}
|
||||
|
||||
.setting-trigger {
|
||||
cursor: pointer;
|
||||
|
||||
display: flex;
|
||||
column-gap: 4px;
|
||||
align-items: center;
|
||||
|
||||
margin-left: 8px;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
font-style: normal;
|
||||
line-height: 16px;
|
||||
color: var(--light-color-brand-brand-5, #4d53e8);
|
||||
|
||||
&-icon {
|
||||
svg {
|
||||
width: 10px;
|
||||
height: 10px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting-content-popover {
|
||||
background: #f7f7fa;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.setting {
|
||||
overflow-y: auto;
|
||||
|
||||
max-width: 611px;
|
||||
height: 454px;
|
||||
padding: 24px;
|
||||
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: var(--light-usage-text-color-text-0, #1f2329);
|
||||
|
||||
background-color: #f7f7fa;
|
||||
border-radius: 12px;
|
||||
|
||||
.setting-title {
|
||||
padding-bottom: 24px;
|
||||
font-size: 18px;
|
||||
font-weight: 600;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.recall_title {
|
||||
margin-top: 16px;
|
||||
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
color: var(--Light-usage-text---color-text-0, #1d1c24);
|
||||
}
|
||||
|
||||
.setting-item-container {
|
||||
display: flex;
|
||||
align-items: self-start;
|
||||
justify-content: space-between;
|
||||
|
||||
min-height: 32px;
|
||||
margin-top: 16px;
|
||||
|
||||
.setting-item {
|
||||
width: 346px;
|
||||
}
|
||||
|
||||
.setting-item-copy {
|
||||
cursor: pointer;
|
||||
|
||||
margin: 0 4px;
|
||||
padding: 2px 4px 2px 8px;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
color: var(--light-color-brand-brand-5, #4d53e8);
|
||||
|
||||
border-radius: 6px;
|
||||
|
||||
.icon-copy {
|
||||
.common-svg-icon(14px, var(--light-color-brand-brand-5, #4d53e8));
|
||||
|
||||
margin: 0 0 0 4px;
|
||||
}
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-tag-grey-light {
|
||||
background: var(--light-color-brand-brand-1, #d9dcfa) !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.setting-source-display {
|
||||
margin-top: 16px;
|
||||
padding-top: 16px;
|
||||
border-top: 1px solid var(--Light-usage-border---color-border, rgba(29, 28, 35, 8%));
|
||||
|
||||
:global {
|
||||
.semi-switch-checked {
|
||||
background-color: var(--light-color-brand-brand-5, #4d53e8);
|
||||
}
|
||||
|
||||
.semi-switch-disabled.semi-switch-checked {
|
||||
background-color: var(--semi-color-primary-disabled);
|
||||
}
|
||||
}
|
||||
|
||||
&-title {
|
||||
font-size: 16px;
|
||||
font-weight: 600;
|
||||
line-height: 22px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.title-area {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
width: 220px;
|
||||
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: var(--light-usage-text-color-text-0, #1c1d23);
|
||||
|
||||
&-icon {
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
margin-left: 8px;
|
||||
color: #a7a9b0;
|
||||
}
|
||||
}
|
||||
|
||||
.slider-area {
|
||||
&:hover {
|
||||
.slider-boundary {
|
||||
opacity: 1;
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-slider-mark {
|
||||
display: block !important;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.slider-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.slider {
|
||||
width: 210px;
|
||||
margin-right: 24px;
|
||||
|
||||
:global {
|
||||
.semi-slider-mark {
|
||||
display: none;
|
||||
margin-top: 9px;
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.input-number {
|
||||
width: 108px;
|
||||
}
|
||||
}
|
||||
|
||||
.slider-boundary {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
||||
box-sizing: border-box;
|
||||
width: 200px;
|
||||
margin-top: 0;
|
||||
padding: 0 12px;
|
||||
|
||||
font-size: 12px;
|
||||
line-height: 16px;
|
||||
color: var(--light-color-black-black, #000);
|
||||
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
.tip-area {
|
||||
width: 540px;
|
||||
margin-top: 16px;
|
||||
border-radius: 8px;
|
||||
|
||||
.icon {
|
||||
width: 20px;
|
||||
height: 20px;
|
||||
}
|
||||
|
||||
.desc {
|
||||
font-size: 14px;
|
||||
line-height: 20px;
|
||||
color: var(--Light-usage-text---color-text-0, #1c1f23);
|
||||
}
|
||||
}
|
||||
|
||||
.radio-area {
|
||||
width: 346px;
|
||||
|
||||
:global {
|
||||
.semi-radioGroup-horizontal {
|
||||
gap: 24px;
|
||||
}
|
||||
}
|
||||
|
||||
.radio-item {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
|
||||
.radio-item-desc {
|
||||
margin: 4px 0 0 24px;
|
||||
font-size: 14px;
|
||||
line-height: 22px;
|
||||
color: var(--light-usage-text-color-text-2, rgb(28 29 35 / 60%));
|
||||
}
|
||||
|
||||
:global {
|
||||
.semi-radio-addon {
|
||||
font-weight: 600;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.radio-item-icon {
|
||||
cursor: pointer;
|
||||
flex-shrink: 0;
|
||||
margin-left: 4px;
|
||||
color: #a7a9b0;
|
||||
}
|
||||
|
||||
.radio-desc {
|
||||
box-sizing: border-box;
|
||||
width: 346px;
|
||||
margin: 8px 0;
|
||||
padding: 12px;
|
||||
|
||||
font-size: 12px;
|
||||
|
||||
background: var(--Light-color-brand---brand-0, #f1f2fd);
|
||||
border: 1px solid var(--Light-color-brand---brand-1, #d9dcfa);
|
||||
border-radius: 8px;
|
||||
}
|
||||
}
|
||||
|
||||
.display_tooltip {
|
||||
.display_tooltip_content {
|
||||
margin-top: 16px;
|
||||
padding: 12px;
|
||||
background: var(--Light-usage-fill---color-fill-0, rgba(46, 46, 57, 4%));
|
||||
border-radius: var(--default, 8px);
|
||||
|
||||
.display_tooltip_content_link {
|
||||
// text-decoration: underline;
|
||||
cursor: pointer;
|
||||
display: flex;
|
||||
margin-top: 8px;
|
||||
color: var(--Light-usage-primary---color-primary, #4c54f0);
|
||||
|
||||
.link_num {
|
||||
margin-right: 10px;
|
||||
color: var(--Light-usage-text---color-text-0, #1d1c24);
|
||||
text-decoration: none !important;
|
||||
}
|
||||
|
||||
.display_tooltip_link {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.show-source-mode-tip {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
align-items: center;
|
||||
|
||||
.title {
|
||||
font-size: 14px;
|
||||
font-weight: 600;
|
||||
line-height: 20px;
|
||||
color: rgba(29, 28, 35, 100%);
|
||||
}
|
||||
|
||||
// Footer展示
|
||||
.main {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 12px;
|
||||
|
||||
padding: 12px;
|
||||
|
||||
background: #f9f9f9;
|
||||
border: 1px solid rgba(6, 7, 9, 10%);
|
||||
border-radius: 16px;
|
||||
|
||||
.content {
|
||||
font-size: 14px;
|
||||
font-weight: 400;
|
||||
line-height: 20px;
|
||||
color: rgba(6, 7, 9, 80%);
|
||||
}
|
||||
|
||||
.link {
|
||||
cursor: pointer;
|
||||
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 16px;
|
||||
color: #543ef7;
|
||||
}
|
||||
}
|
||||
|
||||
// Card展示
|
||||
.space {
|
||||
display: flex;
|
||||
gap: 8px;
|
||||
justify-content: center;
|
||||
|
||||
.card {
|
||||
cursor: pointer;
|
||||
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
gap: 8px;
|
||||
|
||||
width: 177px;
|
||||
padding: 16px;
|
||||
|
||||
background-color: rgba(244, 244, 246, 100%);
|
||||
border-radius: 8px;
|
||||
|
||||
.content {
|
||||
font-size: 12px;
|
||||
font-weight: 400;
|
||||
line-height: 16px;
|
||||
color: rgba(6, 7, 9, 50%);
|
||||
}
|
||||
|
||||
.title {
|
||||
font-size: 12px;
|
||||
font-weight: 500;
|
||||
line-height: 16px;
|
||||
color: rgba(6, 7, 9, 80%);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,392 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { useRef } from 'react';
|
||||
|
||||
import { debounce, isEmpty } from 'lodash-es';
|
||||
import { produce } from 'immer';
|
||||
import classNames from 'classnames';
|
||||
import { BotE2e } from '@coze-data/e2e';
|
||||
import { RerankTips, RewriteTips } from '@coze-common/biz-tooltip-ui';
|
||||
import { I18n, getUnReactiveLanguage } from '@coze-arch/i18n';
|
||||
import { Banner, Form, Switch } from '@coze-arch/bot-semi';
|
||||
import { IconWarningInfo } from '@coze-arch/bot-icons';
|
||||
import { getFlags } from '@coze-arch/bot-flags';
|
||||
import {
|
||||
KnowledgeShowSourceMode,
|
||||
KnowledgeNoRecallReplyMode,
|
||||
} from '@coze-arch/bot-api/playground_api';
|
||||
|
||||
import { recallStrategyUpdater } from './utils';
|
||||
import { type RagModeConfigurationProps } from './type';
|
||||
import { SliderSetting } from './slider-setting';
|
||||
import { SettingItem } from './setting-item';
|
||||
import { RadioGroupSetting } from './radio-group-setting';
|
||||
import {
|
||||
MAX_TOP_K_VALUE,
|
||||
getAutomaticCallOptions,
|
||||
getShowSourceModeOptions,
|
||||
getNoRecallReplyOptions,
|
||||
getSearchStrategyOptions,
|
||||
localeMapLink,
|
||||
} from './constant';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
const DATASET_INFO_MIN_SCORE = 0.01;
|
||||
|
||||
/* eslint-disable @coze-arch/max-line-per-function*/
|
||||
|
||||
// eslint-disable-next-line complexity, max-lines-per-function
|
||||
export function RagModeConfiguration({
|
||||
dataSetInfo,
|
||||
onDataSetInfoChange,
|
||||
showTitle = true,
|
||||
isReadonly = false,
|
||||
showNL2SQLConfig,
|
||||
showAuto = true,
|
||||
showSourceDisplay = true,
|
||||
}: RagModeConfigurationProps): JSX.Element {
|
||||
const {
|
||||
auto,
|
||||
min_score: minScore,
|
||||
top_k: topK,
|
||||
search_strategy: searchStrategy,
|
||||
show_source,
|
||||
no_recall_reply_mode,
|
||||
no_recall_reply_customize_prompt,
|
||||
show_source_mode,
|
||||
recall_strategy = {},
|
||||
} = dataSetInfo;
|
||||
|
||||
// undefined 默认为 true
|
||||
const {
|
||||
use_nl2sql = true,
|
||||
use_rerank = true,
|
||||
use_rewrite = true,
|
||||
} = recall_strategy;
|
||||
|
||||
const language = getUnReactiveLanguage();
|
||||
const FLAGS = getFlags();
|
||||
|
||||
const textAreaRef = useRef<HTMLTextAreaElement>(null);
|
||||
|
||||
const debounceOnNoRecallReplyCustomizePromptChange = debounce(v => {
|
||||
onDataSetInfoChange({
|
||||
...dataSetInfo,
|
||||
no_recall_reply_customize_prompt: v,
|
||||
});
|
||||
}, 300);
|
||||
|
||||
return (
|
||||
<div className={styles.setting}>
|
||||
{showTitle ? (
|
||||
<div
|
||||
data-testid={BotE2e.BotKnowledgeSettingModalTitle}
|
||||
className={classNames(
|
||||
styles['setting-title'],
|
||||
'dataset-setting-content-title',
|
||||
)}
|
||||
>
|
||||
{I18n.t('dataset_settings_title')}
|
||||
</div>
|
||||
) : null}
|
||||
<div className={styles.recall_title}>
|
||||
{I18n.t('dataset-setting_recall_title')}
|
||||
</div>
|
||||
{showAuto ? (
|
||||
<SettingItem
|
||||
title={I18n.t('dataset_call_method')}
|
||||
tip={I18n.t('knowledge_call_method_tooltip')}
|
||||
>
|
||||
<RadioGroupSetting
|
||||
options={getAutomaticCallOptions()}
|
||||
value={auto ? 1 : 0}
|
||||
onChange={v => onDataSetInfoChange({ ...dataSetInfo, auto: !!v })}
|
||||
disabled={isReadonly}
|
||||
/>
|
||||
</SettingItem>
|
||||
) : null}
|
||||
<SettingItem
|
||||
title={I18n.t('knowledge_search_strategy_title')}
|
||||
tip={I18n.t('knowledge_search_strategy_tooltip')}
|
||||
>
|
||||
<RadioGroupSetting
|
||||
options={getSearchStrategyOptions()}
|
||||
value={searchStrategy ?? 0}
|
||||
onChange={v =>
|
||||
onDataSetInfoChange({ ...dataSetInfo, search_strategy: v })
|
||||
}
|
||||
disabled={isReadonly}
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem
|
||||
title={I18n.t('dataset_max_recall')}
|
||||
tip={I18n.t('bot_edit_datasetsSettings_MaxTip')}
|
||||
>
|
||||
<SliderSetting
|
||||
min={1}
|
||||
max={10}
|
||||
step={1}
|
||||
precision={0}
|
||||
value={topK}
|
||||
marks={{ 3: I18n.t('dataset_max_recall_default') }}
|
||||
onChange={v => {
|
||||
onDataSetInfoChange({
|
||||
...dataSetInfo,
|
||||
top_k: v,
|
||||
});
|
||||
}}
|
||||
disabled={isReadonly}
|
||||
/>
|
||||
</SettingItem>
|
||||
{topK > MAX_TOP_K_VALUE && (
|
||||
<Banner
|
||||
bordered
|
||||
type="warning"
|
||||
fullMode={false}
|
||||
closeIcon={null}
|
||||
className={classNames(
|
||||
styles['tip-area'],
|
||||
'dataset-setting-content-tip-area',
|
||||
)}
|
||||
icon={<IconWarningInfo className={styles.icon} />}
|
||||
description={
|
||||
<span className={styles.desc}>
|
||||
{I18n.t('dataset_max_recall_desc')}
|
||||
</span>
|
||||
}
|
||||
/>
|
||||
)}
|
||||
{recall_strategy.use_rerank ? (
|
||||
<SettingItem
|
||||
title={I18n.t('dataset_min_degree')}
|
||||
tip={I18n.t('bot_edit_datasetsSettings_MinTip')}
|
||||
>
|
||||
<SliderSetting
|
||||
min={DATASET_INFO_MIN_SCORE}
|
||||
max={0.99}
|
||||
step={0.01}
|
||||
precision={2}
|
||||
value={minScore}
|
||||
marks={{ 0.5: I18n.t('dataset_min_degree_default') }}
|
||||
disabled={isReadonly}
|
||||
onChange={v => {
|
||||
onDataSetInfoChange({
|
||||
...dataSetInfo,
|
||||
min_score: v,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
) : null}
|
||||
{showNL2SQLConfig ? (
|
||||
<SettingItem
|
||||
title={I18n.t('kl_write_022')}
|
||||
tip={I18n.t('kl_write_023')}
|
||||
>
|
||||
<Switch
|
||||
checked={use_nl2sql}
|
||||
onChange={value => {
|
||||
onDataSetInfoChange(
|
||||
produce(dataSetInfo, draft =>
|
||||
recallStrategyUpdater({
|
||||
datasetInfo: draft,
|
||||
field: 'use_nl2sql',
|
||||
value,
|
||||
}),
|
||||
),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
) : null}
|
||||
<SettingItem title={I18n.t('kl_write_024')} tip={<RewriteTips />}>
|
||||
<Switch
|
||||
checked={use_rewrite}
|
||||
onChange={value => {
|
||||
onDataSetInfoChange(
|
||||
produce(dataSetInfo, draft =>
|
||||
recallStrategyUpdater({
|
||||
datasetInfo: draft,
|
||||
field: 'use_rewrite',
|
||||
value,
|
||||
}),
|
||||
),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
<SettingItem title={I18n.t('kl_write_026')} tip={<RerankTips />}>
|
||||
<Switch
|
||||
checked={use_rerank}
|
||||
onChange={value => {
|
||||
onDataSetInfoChange(
|
||||
produce(dataSetInfo, draft => {
|
||||
const nextState = {
|
||||
datasetInfo: draft,
|
||||
field: 'use_rerank',
|
||||
value,
|
||||
} as const;
|
||||
|
||||
if (!value) {
|
||||
nextState.datasetInfo.min_score = 0;
|
||||
} else if (!nextState.datasetInfo.min_score) {
|
||||
nextState.datasetInfo.min_score = DATASET_INFO_MIN_SCORE;
|
||||
}
|
||||
|
||||
return recallStrategyUpdater(nextState);
|
||||
}),
|
||||
);
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
{FLAGS['bot.data.no_recall_reply'] ? (
|
||||
<div className={styles['setting-source-display']}>
|
||||
<div className={styles['setting-source-display-title']}>
|
||||
{I18n.t('No_recall_001')}
|
||||
</div>
|
||||
<SettingItem
|
||||
title={I18n.t('No_recall_002')}
|
||||
tip={
|
||||
<div className={styles.display_tooltip}>
|
||||
{I18n.t('No_recall_005')}
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<RadioGroupSetting
|
||||
options={getNoRecallReplyOptions()}
|
||||
value={no_recall_reply_mode ?? KnowledgeNoRecallReplyMode.Default}
|
||||
onChange={v =>
|
||||
onDataSetInfoChange({
|
||||
...dataSetInfo,
|
||||
no_recall_reply_mode: v,
|
||||
no_recall_reply_customize_prompt:
|
||||
v === KnowledgeNoRecallReplyMode.CustomizePrompt &&
|
||||
isEmpty(no_recall_reply_customize_prompt)
|
||||
? I18n.t('No_recall_006')
|
||||
: no_recall_reply_customize_prompt,
|
||||
})
|
||||
}
|
||||
disabled={isReadonly}
|
||||
/>
|
||||
</SettingItem>
|
||||
{no_recall_reply_mode ===
|
||||
KnowledgeNoRecallReplyMode.CustomizePrompt ? (
|
||||
<Form<Record<string, unknown>>
|
||||
initValues={{
|
||||
no_recall_reply_customize_prompt:
|
||||
no_recall_reply_customize_prompt ?? I18n.t('No_recall_006'),
|
||||
}}
|
||||
>
|
||||
<Form.TextArea
|
||||
maxLength={500}
|
||||
maxCount={500}
|
||||
ref={textAreaRef}
|
||||
onChange={debounceOnNoRecallReplyCustomizePromptChange}
|
||||
rows={2}
|
||||
disabled={isReadonly}
|
||||
placeholder={I18n.t(
|
||||
'card_builder_dataEditor_get_errormsg_please_enter',
|
||||
)}
|
||||
pure
|
||||
field="no_recall_reply_customize_prompt"
|
||||
/>
|
||||
</Form>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
{FLAGS['bot.data.source_display'] && showSourceDisplay ? (
|
||||
<div className={styles['setting-source-display']}>
|
||||
<div
|
||||
className={styles['setting-source-display-title']}
|
||||
data-testid={BotE2e.BotKnowledgeSettingShowSourceDisplayTitle}
|
||||
>
|
||||
{I18n.t('knowledge_source_display_title')}
|
||||
</div>
|
||||
<SettingItem
|
||||
title={I18n.t('knowledge_source_display_status')}
|
||||
tipStyle={{
|
||||
backgroundColor: '#fff',
|
||||
color: 'var(--Light-usage-text---color-text-0, #1D1C24)',
|
||||
maxWidth: '453px',
|
||||
minWidth: '453px',
|
||||
}}
|
||||
tip={
|
||||
<div className={styles.display_tooltip}>
|
||||
<div className={styles.display_tooltip_title}>
|
||||
{I18n.t('knowledge_source_display_tooltip_title')}
|
||||
</div>
|
||||
<div className={styles.display_tooltip_content}>
|
||||
<div>
|
||||
{I18n.t('knowledge_source_display_tooltip_content')}
|
||||
</div>
|
||||
<div className={styles.display_tooltip_content_link}>
|
||||
<div className={styles.link_num}>1.</div>
|
||||
<div
|
||||
className={styles.display_tooltip_link}
|
||||
onClick={() =>
|
||||
window.open(
|
||||
`${window.location.origin}${
|
||||
localeMapLink[language] || '/docs/guides/knowledge'
|
||||
}`,
|
||||
)
|
||||
}
|
||||
>
|
||||
{I18n.t('knowledge_source_display_tooltip_link')}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
>
|
||||
<Switch
|
||||
data-testid={BotE2e.BotKnowledgeSettingShowSourceDisplaySwitch}
|
||||
className={styles.display_status}
|
||||
checked={show_source}
|
||||
disabled={isReadonly}
|
||||
onChange={v => {
|
||||
onDataSetInfoChange({
|
||||
...dataSetInfo,
|
||||
show_source: v,
|
||||
// 展示方式没有值且打开展示来源,默认选中卡片
|
||||
...(!show_source_mode && v
|
||||
? {
|
||||
show_source_mode: KnowledgeShowSourceMode.CardList,
|
||||
}
|
||||
: {}),
|
||||
});
|
||||
}}
|
||||
/>
|
||||
</SettingItem>
|
||||
|
||||
{show_source ? (
|
||||
<SettingItem title={I18n.t('Display format')}>
|
||||
<RadioGroupSetting
|
||||
options={getShowSourceModeOptions()}
|
||||
value={show_source_mode ?? KnowledgeShowSourceMode.ReplyBottom}
|
||||
onChange={v =>
|
||||
onDataSetInfoChange({ ...dataSetInfo, show_source_mode: v })
|
||||
}
|
||||
disabled={isReadonly}
|
||||
/>
|
||||
</SettingItem>
|
||||
) : null}
|
||||
</div>
|
||||
) : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React, { type CSSProperties, type ReactNode } from 'react';
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { Radio, RadioGroup, Popover } from '@coze-arch/bot-semi';
|
||||
import { IconInfo } from '@coze-arch/bot-icons';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface RadioItem {
|
||||
label: string;
|
||||
value: number;
|
||||
e2e?: string;
|
||||
tip?: ReactNode;
|
||||
tipStyle?: CSSProperties;
|
||||
desc?: string | ReactNode;
|
||||
}
|
||||
|
||||
export interface RadioGroupSettingProps {
|
||||
options: RadioItem[];
|
||||
value: number;
|
||||
disabled?: boolean;
|
||||
onChange: (value: number) => void;
|
||||
}
|
||||
export function RadioGroupSetting({
|
||||
options,
|
||||
value,
|
||||
disabled,
|
||||
onChange,
|
||||
}: RadioGroupSettingProps) {
|
||||
const desc = options.find(v => v.value === value)?.desc;
|
||||
return (
|
||||
<div className={styles['radio-area']}>
|
||||
<RadioGroup
|
||||
onChange={e => onChange(e.target.value as number)}
|
||||
value={value}
|
||||
disabled={disabled}
|
||||
>
|
||||
{options.map(item => (
|
||||
<div
|
||||
data-testid={item.e2e}
|
||||
key={item.value}
|
||||
className={classNames(
|
||||
styles['radio-item'],
|
||||
value === item.value ? styles.active : styles.normal,
|
||||
)}
|
||||
>
|
||||
<Radio value={item.value}>{item.label}</Radio>
|
||||
{!!item.tip && (
|
||||
<Popover
|
||||
showArrow
|
||||
position="top"
|
||||
zIndex={1031}
|
||||
style={{
|
||||
backgroundColor: '#41464c',
|
||||
color: '#fff',
|
||||
maxWidth: '276px',
|
||||
...(item.tipStyle || {}),
|
||||
}}
|
||||
content={item.tip}
|
||||
>
|
||||
<IconInfo className={styles['radio-item-icon']} />
|
||||
</Popover>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</RadioGroup>
|
||||
{desc ? <div className={styles['radio-desc']}>{desc}</div> : null}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import classNames from 'classnames';
|
||||
import { type I18nKeysNoOptionsType } from '@coze-arch/i18n';
|
||||
import { I18n } from '@coze-arch/i18n';
|
||||
|
||||
import { TitleArea } from './title-area';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
export interface SettingItemProps {
|
||||
title: string;
|
||||
tip?: string | React.ReactNode;
|
||||
children: React.ReactNode;
|
||||
className?: string;
|
||||
tipStyle?: Record<string, string | number>;
|
||||
}
|
||||
|
||||
export const SettingItem = ({
|
||||
title,
|
||||
tip,
|
||||
children,
|
||||
className,
|
||||
tipStyle,
|
||||
}: SettingItemProps) => (
|
||||
<div className={classNames(styles['setting-item-container'], className)}>
|
||||
<TitleArea
|
||||
title={I18n.t(title as unknown as I18nKeysNoOptionsType)}
|
||||
tip={tip || ''}
|
||||
tipStyle={tipStyle}
|
||||
/>
|
||||
<div
|
||||
className={classNames(
|
||||
styles['setting-item'],
|
||||
'dataset-setting-content-item',
|
||||
)}
|
||||
>
|
||||
{children}
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,85 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { InputNumber, Slider } from '@coze-arch/bot-semi';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
interface SliderSettingProps {
|
||||
min: number;
|
||||
max: number;
|
||||
step: number;
|
||||
precision: number;
|
||||
value: number;
|
||||
marks: Record<number, string>;
|
||||
onChange: (value: number) => void;
|
||||
disabled: boolean;
|
||||
}
|
||||
|
||||
export const SliderSetting = ({
|
||||
min = 0,
|
||||
max = 100,
|
||||
step = 1,
|
||||
precision = 0,
|
||||
value,
|
||||
marks,
|
||||
onChange,
|
||||
disabled,
|
||||
}: SliderSettingProps) => (
|
||||
<div className={styles['slider-area']}>
|
||||
<div className={styles['slider-wrapper']}>
|
||||
<div className={styles.slider}>
|
||||
<Slider
|
||||
step={step}
|
||||
min={min}
|
||||
max={max}
|
||||
value={value}
|
||||
marks={marks}
|
||||
disabled={disabled}
|
||||
onChange={v => onChange(v as number)}
|
||||
></Slider>
|
||||
</div>
|
||||
<InputNumber
|
||||
className={styles['input-number']}
|
||||
step={step}
|
||||
precision={precision}
|
||||
onChange={v => {
|
||||
let inputValue = Number(v);
|
||||
if (isNaN(inputValue)) {
|
||||
inputValue = value;
|
||||
} else {
|
||||
inputValue = inputValue || value;
|
||||
inputValue = Math.max(inputValue, 0);
|
||||
}
|
||||
if (inputValue > max) {
|
||||
inputValue = max;
|
||||
}
|
||||
onChange(inputValue);
|
||||
}}
|
||||
value={value}
|
||||
min={min}
|
||||
max={max}
|
||||
disabled={disabled}
|
||||
/>
|
||||
</div>
|
||||
<div className={styles['slider-boundary']}>
|
||||
<div className={styles.min}>{min}</div>
|
||||
<div className={styles.max}>{max}</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
|
||||
import { IconInfo } from '@coze-arch/bot-icons';
|
||||
import { Popover } from '@coze-arch/coze-design';
|
||||
|
||||
import styles from './index.module.less';
|
||||
|
||||
interface TitleAreaProps {
|
||||
title: string;
|
||||
tipStyle?: Record<string, string | number>;
|
||||
tip?: string | React.ReactNode;
|
||||
}
|
||||
|
||||
export function TitleArea({ title, tip, tipStyle = {} }: TitleAreaProps) {
|
||||
return (
|
||||
<div className={styles['title-area']}>
|
||||
{title}
|
||||
{!!tip && (
|
||||
<Popover
|
||||
showArrow
|
||||
position="top"
|
||||
zIndex={1031}
|
||||
style={{
|
||||
maxWidth: '276px',
|
||||
...tipStyle,
|
||||
}}
|
||||
content={tip}
|
||||
>
|
||||
<IconInfo className={styles['title-area-icon']} />
|
||||
</Popover>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {
|
||||
type KnowledgeShowSourceMode,
|
||||
type KnowledgeNoRecallReplyMode,
|
||||
type RecallStrategy,
|
||||
} from '@coze-arch/bot-api/playground_api';
|
||||
export interface IDataSetInfo {
|
||||
min_score: number;
|
||||
top_k: number;
|
||||
auto: boolean;
|
||||
search_strategy?: number;
|
||||
show_source?: boolean;
|
||||
no_recall_reply_mode?: KnowledgeNoRecallReplyMode;
|
||||
no_recall_reply_customize_prompt?: string;
|
||||
show_source_mode?: KnowledgeShowSourceMode;
|
||||
recall_strategy?: RecallStrategy;
|
||||
}
|
||||
export interface RagModeConfigurationProps {
|
||||
dataSetInfo: IDataSetInfo;
|
||||
onDataSetInfoChange: (v: IDataSetInfo) => void;
|
||||
showTitle?: boolean;
|
||||
isReadonly?: boolean;
|
||||
showNL2SQLConfig?: boolean;
|
||||
showAuto?: boolean;
|
||||
showSourceDisplay?: boolean;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2025 coze-dev Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import { type RecallStrategy } from '@coze-arch/bot-api/playground_api';
|
||||
|
||||
import { type IDataSetInfo } from './type';
|
||||
|
||||
export const recallStrategyUpdater: (params: {
|
||||
datasetInfo: IDataSetInfo;
|
||||
field: keyof RecallStrategy;
|
||||
value: boolean;
|
||||
}) => IDataSetInfo = ({ datasetInfo, field, value }) => {
|
||||
if (!datasetInfo.recall_strategy) {
|
||||
datasetInfo.recall_strategy = {
|
||||
[field]: value,
|
||||
};
|
||||
} else {
|
||||
datasetInfo.recall_strategy[field] = value;
|
||||
}
|
||||
return datasetInfo;
|
||||
};
|
||||
Reference in New Issue
Block a user