| @@ -38,9 +38,9 @@ const CardView: FC<ICardViewProps> = ({ appId }) => { | |||
| message ||= (type === 'success' ? 'modifiedSuccessfully' : 'modifiedUnsuccessfully') | |||
| if (type === 'success') { | |||
| if (type === 'success') | |||
| mutate(detailParams) | |||
| } | |||
| notify({ | |||
| type, | |||
| message: t(`common.actionMsg.${message}`), | |||
| @@ -79,7 +79,7 @@ const CardView: FC<ICardViewProps> = ({ appId }) => { | |||
| if (!err) | |||
| localStorage.setItem(NEED_REFRESH_APP_LIST_KEY, '1') | |||
| handleCallbackResult(err) | |||
| handleCallbackResult(err) | |||
| } | |||
| const onGenerateCode = async () => { | |||
| @@ -64,8 +64,8 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { | |||
| const getAppDetail = async () => { | |||
| setDetailState({ loading: true }) | |||
| const [err, res] = await asyncRunSafe<App>( | |||
| fetchAppDetail({ url: '/apps', id: app.id }) as Promise<App>, | |||
| const [err, res] = await asyncRunSafe( | |||
| fetchAppDetail({ url: '/apps', id: app.id }), | |||
| ) | |||
| if (!err) { | |||
| setDetailState({ loading: false, detail: res }) | |||
| @@ -76,11 +76,11 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => { | |||
| const onSaveSiteConfig = useCallback( | |||
| async (params: ConfigParams) => { | |||
| const [err] = await asyncRunSafe<App>( | |||
| const [err] = await asyncRunSafe( | |||
| updateAppSiteConfig({ | |||
| url: `/apps/${app.id}/site`, | |||
| body: params, | |||
| }) as Promise<App>, | |||
| }), | |||
| ) | |||
| if (!err) { | |||
| notify({ | |||
| @@ -18,7 +18,6 @@ import Config from '@/app/components/app/configuration/config' | |||
| import Debug from '@/app/components/app/configuration/debug' | |||
| import Confirm from '@/app/components/base/confirm' | |||
| import { ProviderEnum } from '@/app/components/header/account-setting/model-page/declarations' | |||
| import type { AppDetailResponse } from '@/models/app' | |||
| import { ToastContext } from '@/app/components/base/toast' | |||
| import { fetchAppDetail, updateAppModelConfig } from '@/service/apps' | |||
| import { promptVariablesToUserInputsForm, userInputsFormToPromptVariables } from '@/utils/model-config' | |||
| @@ -27,6 +26,11 @@ import AccountSetting from '@/app/components/header/account-setting' | |||
| import { useProviderContext } from '@/context/provider-context' | |||
| import { AppType } from '@/types/app' | |||
| type PublichConfig = { | |||
| modelConfig: ModelConfig | |||
| completionParams: CompletionParams | |||
| } | |||
| const Configuration: FC = () => { | |||
| const { t } = useTranslation() | |||
| const { notify } = useContext(ToastContext) | |||
| @@ -37,10 +41,7 @@ const Configuration: FC = () => { | |||
| const matched = pathname.match(/\/app\/([^/]+)/) | |||
| const appId = (matched?.length && matched[1]) ? matched[1] : '' | |||
| const [mode, setMode] = useState('') | |||
| const [publishedConfig, setPublishedConfig] = useState<{ | |||
| modelConfig: ModelConfig | |||
| completionParams: CompletionParams | |||
| } | null>(null) | |||
| const [publishedConfig, setPublishedConfig] = useState<PublichConfig | null>(null) | |||
| const [conversationId, setConversationId] = useState<string | null>('') | |||
| const [introduction, setIntroduction] = useState<string>('') | |||
| @@ -100,13 +101,13 @@ const Configuration: FC = () => { | |||
| const [dataSets, setDataSets] = useState<DataSet[]>([]) | |||
| const syncToPublishedConfig = (_publishedConfig: any) => { | |||
| const syncToPublishedConfig = (_publishedConfig: PublichConfig) => { | |||
| const modelConfig = _publishedConfig.modelConfig | |||
| setModelConfig(_publishedConfig.modelConfig) | |||
| setCompletionParams(_publishedConfig.completionParams) | |||
| setDataSets(modelConfig.dataSets || []) | |||
| // feature | |||
| setIntroduction(modelConfig.opening_statement) | |||
| setIntroduction(modelConfig.opening_statement!) | |||
| setMoreLikeThisConfig(modelConfig.more_like_this || { | |||
| enabled: false, | |||
| }) | |||
| @@ -143,7 +144,7 @@ const Configuration: FC = () => { | |||
| const [isShowSetAPIKey, { setTrue: showSetAPIKey, setFalse: hideSetAPIkey }] = useBoolean() | |||
| useEffect(() => { | |||
| (fetchAppDetail({ url: '/apps', id: appId }) as any).then(async (res: AppDetailResponse) => { | |||
| fetchAppDetail({ url: '/apps', id: appId }).then(async (res) => { | |||
| setMode(res.mode) | |||
| const modelConfig = res.model_config | |||
| const model = res.model_config.model | |||
| @@ -250,7 +251,7 @@ const Configuration: FC = () => { | |||
| const [showConfirm, setShowConfirm] = useState(false) | |||
| const resetAppConfig = () => { | |||
| syncToPublishedConfig(publishedConfig) | |||
| syncToPublishedConfig(publishedConfig!) | |||
| setShowConfirm(false) | |||
| } | |||
| @@ -48,7 +48,7 @@ const translation = { | |||
| copyright: 'Copyright', | |||
| copyRightPlaceholder: 'Enter the name of the author or organization', | |||
| privacyPolicy: 'Privacy Policy', | |||
| privacyPolicyPlaceholder: 'Enter the privacy policy', | |||
| privacyPolicyPlaceholder: 'Enter the privacy policy link', | |||
| privacyPolicyTip: 'Helps visitors understand the data the application collects, see Dify\'s <privacyPolicyLink>Privacy Policy</privacyPolicyLink>.', | |||
| }, | |||
| }, | |||
| @@ -48,7 +48,7 @@ const translation = { | |||
| copyright: '版权', | |||
| copyRightPlaceholder: '请输入作者或组织名称', | |||
| privacyPolicy: '隐私政策', | |||
| privacyPolicyPlaceholder: '请输入隐私政策', | |||
| privacyPolicyPlaceholder: '请输入隐私政策链接', | |||
| privacyPolicyTip: '帮助访问者了解该应用收集的数据,可参考 Dify 的<privacyPolicyLink>隐私政策</privacyPolicyLink>。', | |||
| }, | |||
| }, | |||
| @@ -29,6 +29,12 @@ export type CompletionParamsType = { | |||
| frequency_penalty: number | |||
| } | |||
| export type LogModelConfig = { | |||
| name: string | |||
| provider: string | |||
| completion_params: CompletionParamsType | |||
| } | |||
| export type ModelConfigDetail = { | |||
| introduction: string | |||
| prompt_template: string | |||
| @@ -155,6 +161,7 @@ export type ChatConversationFullDetailResponse = Omit<CompletionConversationGene | |||
| provider: string | |||
| model_id: string | |||
| configs: ModelConfigDetail | |||
| model: LogModelConfig | |||
| } | |||
| } | |||
| @@ -8,7 +8,7 @@ export const fetchAppList: Fetcher<AppListResponse, { url: string; params?: Reco | |||
| return get<AppListResponse>(url, { params }) | |||
| } | |||
| export const fetchAppDetail: Fetcher<AppDetailResponse, { url: string; id: string }> = ({ url, id }) => { | |||
| export const fetchAppDetail = ({ url, id }: { url: string; id: string }) => { | |||
| return get<AppDetailResponse>(`${url}/${id}`) | |||
| } | |||
| @@ -41,7 +41,7 @@ export const updateAppSiteAccessToken: Fetcher<UpdateAppSiteCodeResponse, { url: | |||
| return post<UpdateAppSiteCodeResponse>(url) | |||
| } | |||
| export const updateAppSiteConfig: Fetcher<AppDetailResponse, { url: string; body: Record<string, any> }> = ({ url, body }) => { | |||
| export const updateAppSiteConfig = ({ url, body }: { url: string; body: Record<string, any> }) => { | |||
| return post<AppDetailResponse>(url, { body }) | |||
| } | |||
| @@ -1,5 +1,5 @@ | |||
| import { VAR_ITEM_TEMPLATE, getMaxVarNameLength, zhRegex, emojiRegex, MAX_VAR_KEY_LENGHT } from "@/config" | |||
| const otherAllowedRegex = new RegExp(`^[a-zA-Z0-9_]+$`) | |||
| import { MAX_VAR_KEY_LENGHT, VAR_ITEM_TEMPLATE, getMaxVarNameLength } from '@/config' | |||
| const otherAllowedRegex = /^[a-zA-Z0-9_]+$/ | |||
| export const getNewVar = (key: string) => { | |||
| return { | |||
| @@ -10,19 +10,19 @@ export const getNewVar = (key: string) => { | |||
| } | |||
| const checkKey = (key: string, canBeEmpty?: boolean) => { | |||
| if (key.length === 0 && !canBeEmpty) { | |||
| if (key.length === 0 && !canBeEmpty) | |||
| return 'canNoBeEmpty' | |||
| } | |||
| if (canBeEmpty && key === '') { | |||
| if (canBeEmpty && key === '') | |||
| return true | |||
| } | |||
| if (key.length > MAX_VAR_KEY_LENGHT) { | |||
| if (key.length > MAX_VAR_KEY_LENGHT) | |||
| return 'tooLong' | |||
| } | |||
| if (otherAllowedRegex.test(key)) { | |||
| if (/[0-9]/.test(key[0])) { | |||
| if (/[0-9]/.test(key[0])) | |||
| return 'notStartWithNumber' | |||
| } | |||
| return true | |||
| } | |||
| return 'notValid' | |||
| @@ -33,9 +33,9 @@ export const checkKeys = (keys: string[], canBeEmpty?: boolean) => { | |||
| let errorKey = '' | |||
| let errorMessageKey = '' | |||
| keys.forEach((key) => { | |||
| if (!isValid) { | |||
| if (!isValid) | |||
| return | |||
| } | |||
| const res = checkKey(key, canBeEmpty) | |||
| if (res !== true) { | |||
| isValid = false | |||
| @@ -44,4 +44,4 @@ export const checkKeys = (keys: string[], canBeEmpty?: boolean) => { | |||
| } | |||
| }) | |||
| return { isValid, errorKey, errorMessageKey } | |||
| } | |||
| } | |||