diff --git a/web/app/components/app/configuration/config/index.tsx b/web/app/components/app/configuration/config/index.tsx index 542b645880..488d305bea 100644 --- a/web/app/components/app/configuration/config/index.tsx +++ b/web/app/components/app/configuration/config/index.tsx @@ -29,8 +29,8 @@ const Config: FC = () => { setModelConfig, setPrevPromptConfig, setFormattingChanged, - moreLikeThisConifg, - setMoreLikeThisConifg, + moreLikeThisConfig, + setMoreLikeThisConfig, suggestedQuestionsAfterAnswerConfig, setSuggestedQuestionsAfterAnswerConfig, } = useContext(ConfigContext) @@ -66,9 +66,9 @@ const Config: FC = () => { const { featureConfig, handleFeatureChange } = useFeature({ introduction, setIntroduction, - moreLikeThis: moreLikeThisConifg.enabled, + moreLikeThis: moreLikeThisConfig.enabled, setMoreLikeThis: (value) => { - setMoreLikeThisConifg(produce(moreLikeThisConifg, (draft) => { + setMoreLikeThisConfig(produce(moreLikeThisConfig, (draft) => { draft.enabled = value })) }, @@ -154,7 +154,7 @@ const Config: FC = () => { } {/* TextnGeneration config */} - {moreLikeThisConifg.enabled && ( + {moreLikeThisConfig.enabled && ( )} diff --git a/web/app/components/app/configuration/debug/index.tsx b/web/app/components/app/configuration/debug/index.tsx index 363cb4c3e3..14156896e3 100644 --- a/web/app/components/app/configuration/debug/index.tsx +++ b/web/app/components/app/configuration/debug/index.tsx @@ -38,7 +38,7 @@ const Debug: FC = ({ mode, introduction, suggestedQuestionsAfterAnswerConfig, - moreLikeThisConifg, + moreLikeThisConfig, inputs, // setInputs, formattingChanged, @@ -304,7 +304,7 @@ const Debug: FC = ({ user_input_form: promptVariablesToUserInputsForm(modelConfig.configs.prompt_variables), opening_statement: introduction, suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig, - more_like_this: moreLikeThisConifg, + more_like_this: moreLikeThisConfig, agent_mode: { enabled: true, tools: [...postDatasets], diff --git a/web/app/components/app/configuration/index.tsx b/web/app/components/app/configuration/index.tsx index 03bea3f316..34af8d8443 100644 --- a/web/app/components/app/configuration/index.tsx +++ b/web/app/components/app/configuration/index.tsx @@ -5,7 +5,10 @@ import { useTranslation } from 'react-i18next' import { useContext } from 'use-context-selector' import { usePathname } from 'next/navigation' import produce from 'immer' -import type { CompletionParams, Inputs, ModelConfig, PromptConfig, PromptVariable, MoreLikeThisConfig } from '@/models/debug' +import { useBoolean } from 'ahooks' +import Button from '../../base/button' +import Loading from '../../base/loading' +import type { CompletionParams, Inputs, ModelConfig, MoreLikeThisConfig, PromptConfig, PromptVariable } from '@/models/debug' import type { DataSet } from '@/models/datasets' import type { ModelConfig as BackendModelConfig } from '@/types/app' import ConfigContext from '@/context/debug-configuration' @@ -17,12 +20,9 @@ import type { AppDetailResponse } from '@/models/app' import { ToastContext } from '@/app/components/base/toast' import { fetchTenantInfo } from '@/service/common' import { fetchAppDetail, updateAppModelConfig } from '@/service/apps' -import { userInputsFormToPromptVariables, promptVariablesToUserInputsForm } from '@/utils/model-config' +import { promptVariablesToUserInputsForm, userInputsFormToPromptVariables } from '@/utils/model-config' import { fetchDatasets } from '@/service/datasets' import AccountSetting from '@/app/components/header/account-setting' -import { useBoolean } from 'ahooks' -import Button from '../../base/button' -import Loading from '../../base/loading' const Configuration: FC = () => { const { t } = useTranslation() @@ -35,8 +35,8 @@ const Configuration: FC = () => { const matched = pathname.match(/\/app\/([^/]+)/) const appId = (matched?.length && matched[1]) ? matched[1] : '' const [mode, setMode] = useState('') - const [pusblisedConfig, setPusblisedConfig] = useState<{ - modelConfig: ModelConfig, + const [publishedConfig, setPublishedConfig] = useState<{ + modelConfig: ModelConfig completionParams: CompletionParams } | null>(null) @@ -47,7 +47,7 @@ const Configuration: FC = () => { prompt_template: '', prompt_variables: [], }) - const [moreLikeThisConifg, setMoreLikeThisConifg] = useState({ + const [moreLikeThisConfig, setMoreLikeThisConfig] = useState({ enabled: false, }) const [suggestedQuestionsAfterAnswerConfig, setSuggestedQuestionsAfterAnswerConfig] = useState({ @@ -70,6 +70,10 @@ const Configuration: FC = () => { prompt_template: '', prompt_variables: [] as PromptVariable[], }, + opening_statement: '', + more_like_this: null, + suggested_questions_after_answer: null, + dataSets: [], }) const setModelConfig = (newModelConfig: ModelConfig) => { @@ -77,19 +81,29 @@ const Configuration: FC = () => { } const setModelId = (modelId: string) => { - const newModelConfig = produce(modelConfig, (draft) => { + const newModelConfig = produce(modelConfig, (draft: any) => { draft.model_id = modelId }) setModelConfig(newModelConfig) } - const syncToPublishedConfig = (_pusblisedConfig: any) => { - setModelConfig(_pusblisedConfig.modelConfig) - setCompletionParams(_pusblisedConfig.completionParams) - } - const [dataSets, setDataSets] = useState([]) + const syncToPublishedConfig = (_publishedConfig: any) => { + const modelConfig = _publishedConfig.modelConfig + setModelConfig(_publishedConfig.modelConfig) + setCompletionParams(_publishedConfig.completionParams) + setDataSets(modelConfig.dataSets || []) + // feature + setIntroduction(modelConfig.opening_statement) + setMoreLikeThisConfig(modelConfig.more_like_this || { + enabled: false, + }) + setSuggestedQuestionsAfterAnswerConfig(modelConfig.suggested_questions_after_answer || { + enabled: false, + }) + } + const [hasSetCustomAPIKEY, setHasSetCustomerAPIKEY] = useState(true) const [isTrailFinished, setIsTrailFinished] = useState(false) const hasSetAPIKEY = hasSetCustomAPIKEY || !isTrailFinished @@ -116,35 +130,40 @@ const Configuration: FC = () => { const model = res.model_config.model let datasets: any = null - if (modelConfig.agent_mode?.enabled) { + if (modelConfig.agent_mode?.enabled) datasets = modelConfig.agent_mode?.tools.filter(({ dataset }: any) => dataset?.enabled) - } if (dataSets && datasets?.length && datasets?.length > 0) { const { data: dataSetsWithDetail } = await fetchDatasets({ url: '/datasets', params: { page: 1, ids: datasets.map(({ dataset }: any) => dataset.id) } }) datasets = dataSetsWithDetail setDataSets(datasets) } + + setIntroduction(modelConfig.opening_statement) + if (modelConfig.more_like_this) + setMoreLikeThisConfig(modelConfig.more_like_this) + + if (modelConfig.suggested_questions_after_answer) + setSuggestedQuestionsAfterAnswerConfig(modelConfig.suggested_questions_after_answer) + const config = { modelConfig: { provider: model.provider, model_id: model.name, configs: { prompt_template: modelConfig.pre_prompt, - prompt_variables: userInputsFormToPromptVariables(modelConfig.user_input_form) + prompt_variables: userInputsFormToPromptVariables(modelConfig.user_input_form), }, + opening_statement: modelConfig.opening_statement, + more_like_this: modelConfig.more_like_this, + suggested_questions_after_answer: modelConfig.suggested_questions_after_answer, + dataSets: datasets || [], }, completionParams: model.completion_params, } syncToPublishedConfig(config) - setPusblisedConfig(config) - setIntroduction(modelConfig.opening_statement) - if (modelConfig.more_like_this) { - setMoreLikeThisConifg(modelConfig.more_like_this) - } - if (modelConfig.suggested_questions_after_answer) { - setSuggestedQuestionsAfterAnswerConfig(modelConfig.suggested_questions_after_answer) - } + setPublishedConfig(config) + setHasFetchedDetail(true) }) }, [appId]) @@ -154,18 +173,11 @@ const Configuration: FC = () => { const promptTemplate = modelConfig.configs.prompt_template const promptVariables = modelConfig.configs.prompt_variables - // not save empty key adn name - // const missingNameItem = promptVariables.find(item => item.name.trim() === '') - // if (missingNameItem) { - // notify({ type: 'error', message: t('appDebug.errorMessage.nameOfKeyRequired', { key: missingNameItem.key }) }) - // return - // } - const postDatasets = dataSets.map(({ id }) => ({ dataset: { enabled: true, id, - } + }, })) // new model config data struct @@ -173,11 +185,11 @@ const Configuration: FC = () => { pre_prompt: promptTemplate, user_input_form: promptVariablesToUserInputsForm(promptVariables), opening_statement: introduction || '', - more_like_this: moreLikeThisConifg, + more_like_this: moreLikeThisConfig, suggested_questions_after_answer: suggestedQuestionsAfterAnswerConfig, agent_mode: { enabled: true, - tools: [...postDatasets] + tools: [...postDatasets], }, model: { provider: modelConfig.provider, @@ -187,8 +199,14 @@ const Configuration: FC = () => { } await updateAppModelConfig({ url: `/apps/${appId}/model-config`, body: data }) - setPusblisedConfig({ - modelConfig, + const newModelConfig = produce(modelConfig, (draft: any) => { + draft.opening_statement = introduction + draft.more_like_this = moreLikeThisConfig + draft.suggested_questions_after_answer = suggestedQuestionsAfterAnswerConfig + draft.dataSets = dataSets + }) + setPublishedConfig({ + modelConfig: newModelConfig, completionParams, }) notify({ type: 'success', message: t('common.api.success'), duration: 3000 }) @@ -196,8 +214,7 @@ const Configuration: FC = () => { const [showConfirm, setShowConfirm] = useState(false) const resetAppConfig = () => { - // debugger - syncToPublishedConfig(pusblisedConfig) + syncToPublishedConfig(publishedConfig) setShowConfirm(false) } @@ -224,8 +241,8 @@ const Configuration: FC = () => { setControlClearChatMessage, prevPromptConfig, setPrevPromptConfig, - moreLikeThisConifg, - setMoreLikeThisConifg, + moreLikeThisConfig, + setMoreLikeThisConfig, suggestedQuestionsAfterAnswerConfig, setSuggestedQuestionsAfterAnswerConfig, formattingChanged, @@ -239,7 +256,7 @@ const Configuration: FC = () => { modelConfig, setModelConfig, dataSets, - setDataSets + setDataSets, }} > <> diff --git a/web/app/components/base/switch/index.tsx b/web/app/components/base/switch/index.tsx index 45bf7e4428..848f1d4491 100644 --- a/web/app/components/base/switch/index.tsx +++ b/web/app/components/base/switch/index.tsx @@ -1,5 +1,5 @@ 'use client' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import classNames from 'classnames' import { Switch as OriginalSwitch } from '@headlessui/react' @@ -12,25 +12,29 @@ type SwitchProps = { const Switch = ({ onChange, size = 'lg', defaultValue = false, disabled = false }: SwitchProps) => { const [enabled, setEnabled] = useState(defaultValue) + useEffect(() => { + setEnabled(defaultValue) + }, [defaultValue]) const wrapStyle = { lg: 'h-6 w-11', - md: 'h-4 w-7' + md: 'h-4 w-7', } const circleStyle = { lg: 'h-5 w-5', - md: 'h-3 w-3' + md: 'h-3 w-3', } const translateLeft = { lg: 'translate-x-5', - md: 'translate-x-3' + md: 'translate-x-3', } return ( { - if (disabled) return; + if (disabled) + return setEnabled(checked) onChange(checked) }} diff --git a/web/app/components/share/text-generation/index.tsx b/web/app/components/share/text-generation/index.tsx index aa651b697b..3e5dd3ef46 100644 --- a/web/app/components/share/text-generation/index.tsx +++ b/web/app/components/share/text-generation/index.tsx @@ -47,7 +47,7 @@ const TextGeneration: FC = ({ const [appId, setAppId] = useState('') const [siteInfo, setSiteInfo] = useState(null) const [promptConfig, setPromptConfig] = useState(null) - const [moreLikeThisConifg, setMoreLikeThisConifg] = useState(null) + const [moreLikeThisConfig, setMoreLikeThisConfig] = useState(null) const [isResponsing, { setTrue: setResponsingTrue, setFalse: setResponsingFalse }] = useBoolean(false) const [query, setQuery] = useState('') const [completionRes, setCompletionRes] = useState('') @@ -193,7 +193,7 @@ const TextGeneration: FC = ({ prompt_template: '', // placeholder for feture prompt_variables, } as PromptConfig) - setMoreLikeThisConifg(more_like_this) + setMoreLikeThisConfig(more_like_this) })() }, []) @@ -251,7 +251,7 @@ const TextGeneration: FC = ({ content={completionRes} messageId={messageId} isInWebApp - moreLikeThis={moreLikeThisConifg?.enabled} + moreLikeThis={moreLikeThisConfig?.enabled} onFeedback={handleFeedback} feedback={feedback} onSave={handleSaveMessage} diff --git a/web/context/debug-configuration.ts b/web/context/debug-configuration.ts index bcf7ccd02f..6c238fe4ce 100644 --- a/web/context/debug-configuration.ts +++ b/web/context/debug-configuration.ts @@ -1,5 +1,5 @@ import { createContext } from 'use-context-selector' -import type { CompletionParams, Inputs, ModelConfig, PromptConfig, MoreLikeThisConfig, SuggestedQuestionsAfterAnswerConfig } from '@/models/debug' +import type { CompletionParams, Inputs, ModelConfig, MoreLikeThisConfig, PromptConfig, SuggestedQuestionsAfterAnswerConfig } from '@/models/debug' import type { DataSet } from '@/models/datasets' type IDebugConfiguration = { @@ -15,9 +15,9 @@ type IDebugConfiguration = { setControlClearChatMessage: (controlClearChatMessage: number) => void prevPromptConfig: PromptConfig setPrevPromptConfig: (prevPromptConfig: PromptConfig) => void - moreLikeThisConifg: MoreLikeThisConfig, - setMoreLikeThisConifg: (moreLikeThisConfig: MoreLikeThisConfig) => void - suggestedQuestionsAfterAnswerConfig: SuggestedQuestionsAfterAnswerConfig, + moreLikeThisConfig: MoreLikeThisConfig + setMoreLikeThisConfig: (moreLikeThisConfig: MoreLikeThisConfig) => void + suggestedQuestionsAfterAnswerConfig: SuggestedQuestionsAfterAnswerConfig setSuggestedQuestionsAfterAnswerConfig: (suggestedQuestionsAfterAnswerConfig: SuggestedQuestionsAfterAnswerConfig) => void formattingChanged: boolean setFormattingChanged: (formattingChanged: boolean) => void @@ -51,10 +51,10 @@ const DebugConfigurationContext = createContext({ prompt_variables: [], }, setPrevPromptConfig: () => { }, - moreLikeThisConifg: { + moreLikeThisConfig: { enabled: false, }, - setMoreLikeThisConifg: () => { }, + setMoreLikeThisConfig: () => { }, suggestedQuestionsAfterAnswerConfig: { enabled: false, }, diff --git a/web/models/debug.ts b/web/models/debug.ts index cde30cdd71..cfc7f9f803 100644 --- a/web/models/debug.ts +++ b/web/models/debug.ts @@ -1,28 +1,28 @@ export type Inputs = Record export type PromptVariable = { - key: string, - name: string, - type: string, // "string" | "number" | "select", - default?: string | number, - required: boolean, + key: string + name: string + type: string // "string" | "number" | "select", + default?: string | number + required: boolean options?: string[] max_length?: number } export type CompletionParams = { - max_tokens: number, - temperature: number, - top_p: number, - presence_penalty: number, - frequency_penalty: number, + max_tokens: number + temperature: number + top_p: number + presence_penalty: number + frequency_penalty: number } -export type ModelId = "gpt-3.5-turbo" | "text-davinci-003" +export type ModelId = 'gpt-3.5-turbo' | 'text-davinci-003' export type PromptConfig = { - prompt_template: string, - prompt_variables: PromptVariable[], + prompt_template: string + prompt_variables: PromptVariable[] } export type MoreLikeThisConfig = { @@ -33,83 +33,88 @@ export type SuggestedQuestionsAfterAnswerConfig = MoreLikeThisConfig // frontend use. Not the same as backend export type ModelConfig = { - provider: string, // LLM Provider: for example "OPENAI" - model_id: string, + provider: string // LLM Provider: for example "OPENAI" + model_id: string configs: PromptConfig + opening_statement: string | null + more_like_this: { + enabled: boolean + } | null + suggested_questions_after_answer: { + enabled: boolean + } | null + dataSets: any[] } export type DebugRequestBody = { - inputs: Inputs, - query: string, - completion_params: CompletionParams, + inputs: Inputs + query: string + completion_params: CompletionParams model_config: ModelConfig } export type DebugResponse = { - id: string, - answer: string, - created_at: string, + id: string + answer: string + created_at: string } - export type DebugResponseStream = { - id: string, - data: string, - created_at: string, + id: string + data: string + created_at: string } - export type FeedBackRequestBody = { - message_id: string, - rating: 'like' | 'dislike', - content?: string, + message_id: string + rating: 'like' | 'dislike' + content?: string from_source: 'api' | 'log' } - export type FeedBackResponse = { - message_id: string, + message_id: string rating: 'like' | 'dislike' } // Log session list export type LogSessionListQuery = { - keyword?: string, - start?: string, // format datetime(YYYY-mm-dd HH:ii) - end?: string, // format datetime(YYYY-mm-dd HH:ii) - page: number, - limit: number, // default 20. 1-100 + keyword?: string + start?: string // format datetime(YYYY-mm-dd HH:ii) + end?: string // format datetime(YYYY-mm-dd HH:ii) + page: number + limit: number // default 20. 1-100 } export type LogSessionListResponse = { data: { - id: string, - conversation_id: string, - query: string, // user's query question - message: string, // prompt send to LLM - answer: string, - creat_at: string, - }[], - total: number, - page: number, + id: string + conversation_id: string + query: string // user's query question + message: string // prompt send to LLM + answer: string + creat_at: string + }[] + total: number + page: number } // log session detail and debug export type LogSessionDetailResponse = { - id: string, - cnversation_id: string, - model_provider: string, - query: string, - inputs: Record[], - message: string, - message_tokens: number, // number of tokens in message - answer: string, - answer_tokens: number, // number of tokens in answer - provider_response_latency: number, // used time in ms - from_source: 'api' | 'log', + id: string + cnversation_id: string + model_provider: string + query: string + inputs: Record[] + message: string + message_tokens: number // number of tokens in message + answer: string + answer_tokens: number // number of tokens in answer + provider_response_latency: number // used time in ms + from_source: 'api' | 'log' } export type SavedMessage = { - id: string, + id: string answer: string -} \ No newline at end of file +}