| @@ -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 && ( | |||
| <ExperienceEnchanceGroup /> | |||
| )} | |||
| @@ -38,7 +38,7 @@ const Debug: FC<IDebug> = ({ | |||
| mode, | |||
| introduction, | |||
| suggestedQuestionsAfterAnswerConfig, | |||
| moreLikeThisConifg, | |||
| moreLikeThisConfig, | |||
| inputs, | |||
| // setInputs, | |||
| formattingChanged, | |||
| @@ -304,7 +304,7 @@ const Debug: FC<IDebug> = ({ | |||
| 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], | |||
| @@ -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<MoreLikeThisConfig>({ | |||
| const [moreLikeThisConfig, setMoreLikeThisConfig] = useState<MoreLikeThisConfig>({ | |||
| enabled: false, | |||
| }) | |||
| const [suggestedQuestionsAfterAnswerConfig, setSuggestedQuestionsAfterAnswerConfig] = useState<MoreLikeThisConfig>({ | |||
| @@ -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<DataSet[]>([]) | |||
| 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, | |||
| }} | |||
| > | |||
| <> | |||
| @@ -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 ( | |||
| <OriginalSwitch | |||
| checked={enabled} | |||
| onChange={(checked: boolean) => { | |||
| if (disabled) return; | |||
| if (disabled) | |||
| return | |||
| setEnabled(checked) | |||
| onChange(checked) | |||
| }} | |||
| @@ -47,7 +47,7 @@ const TextGeneration: FC<IMainProps> = ({ | |||
| const [appId, setAppId] = useState<string>('') | |||
| const [siteInfo, setSiteInfo] = useState<SiteInfo | null>(null) | |||
| const [promptConfig, setPromptConfig] = useState<PromptConfig | null>(null) | |||
| const [moreLikeThisConifg, setMoreLikeThisConifg] = useState<MoreLikeThisConfig | null>(null) | |||
| const [moreLikeThisConfig, setMoreLikeThisConfig] = useState<MoreLikeThisConfig | null>(null) | |||
| const [isResponsing, { setTrue: setResponsingTrue, setFalse: setResponsingFalse }] = useBoolean(false) | |||
| const [query, setQuery] = useState('') | |||
| const [completionRes, setCompletionRes] = useState('') | |||
| @@ -193,7 +193,7 @@ const TextGeneration: FC<IMainProps> = ({ | |||
| prompt_template: '', // placeholder for feture | |||
| prompt_variables, | |||
| } as PromptConfig) | |||
| setMoreLikeThisConifg(more_like_this) | |||
| setMoreLikeThisConfig(more_like_this) | |||
| })() | |||
| }, []) | |||
| @@ -251,7 +251,7 @@ const TextGeneration: FC<IMainProps> = ({ | |||
| content={completionRes} | |||
| messageId={messageId} | |||
| isInWebApp | |||
| moreLikeThis={moreLikeThisConifg?.enabled} | |||
| moreLikeThis={moreLikeThisConfig?.enabled} | |||
| onFeedback={handleFeedback} | |||
| feedback={feedback} | |||
| onSave={handleSaveMessage} | |||
| @@ -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<IDebugConfiguration>({ | |||
| prompt_variables: [], | |||
| }, | |||
| setPrevPromptConfig: () => { }, | |||
| moreLikeThisConifg: { | |||
| moreLikeThisConfig: { | |||
| enabled: false, | |||
| }, | |||
| setMoreLikeThisConifg: () => { }, | |||
| setMoreLikeThisConfig: () => { }, | |||
| suggestedQuestionsAfterAnswerConfig: { | |||
| enabled: false, | |||
| }, | |||
| @@ -1,28 +1,28 @@ | |||
| export type Inputs = Record<string, string | number | object> | |||
| 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<string, string | number | object>[], | |||
| 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<string, string | number | object>[] | |||
| 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 | |||
| } | |||
| } | |||