refactor(trigger): refactor app mode type to enum

This commit is contained in:
yessenia 2025-10-21 15:42:04 +08:00
parent d5e2649608
commit dc4801c014
59 changed files with 260 additions and 223 deletions

View File

@ -24,7 +24,7 @@ import { fetchAppDetailDirect } from '@/service/apps'
import { useAppContext } from '@/context/app-context'
import Loading from '@/app/components/base/loading'
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
import type { App } from '@/types/app'
import { type App, AppModeEnum } from '@/types/app'
import useDocumentTitle from '@/hooks/use-document-title'
import { useStore as useTagStore } from '@/app/components/base/tag-management/store'
import dynamic from 'next/dynamic'
@ -64,12 +64,12 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
selectedIcon: NavIcon
}>>([])
const getNavigationConfig = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: string) => {
const getNavigationConfig = useCallback((appId: string, isCurrentWorkspaceEditor: boolean, mode: AppModeEnum) => {
const navConfig = [
...(isCurrentWorkspaceEditor
? [{
name: t('common.appMenus.promptEng'),
href: `/app/${appId}/${(mode === 'workflow' || mode === 'advanced-chat') ? 'workflow' : 'configuration'}`,
href: `/app/${appId}/${(mode === AppModeEnum.WORKFLOW || mode === AppModeEnum.ADVANCED_CHAT) ? 'workflow' : 'configuration'}`,
icon: RiTerminalWindowLine,
selectedIcon: RiTerminalWindowFill,
}]
@ -83,7 +83,7 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
},
...(isCurrentWorkspaceEditor
? [{
name: mode !== 'workflow'
name: mode !== AppModeEnum.WORKFLOW
? t('common.appMenus.logAndAnn')
: t('common.appMenus.logs'),
href: `/app/${appId}/logs`,
@ -110,7 +110,7 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
const mode = isMobile ? 'collapse' : 'expand'
setAppSidebarExpand(isMobile ? mode : localeMode)
// TODO: consider screen size and mode
// if ((appDetail.mode === 'advanced-chat' || appDetail.mode === 'workflow') && (pathname).endsWith('workflow'))
// if ((appDetail.mode === AppModeEnum.ADVANCED_CHAT || appDetail.mode === 'workflow') && (pathname).endsWith('workflow'))
// setAppSidebarExpand('collapse')
}
}, [appDetail, isMobile])
@ -138,10 +138,10 @@ const AppDetailLayout: FC<IAppDetailLayoutProps> = (props) => {
router.replace(`/app/${appId}/overview`)
return
}
if ((res.mode === 'workflow' || res.mode === 'advanced-chat') && (pathname).endsWith('configuration')) {
if ((res.mode === AppModeEnum.WORKFLOW || res.mode === AppModeEnum.ADVANCED_CHAT) && (pathname).endsWith('configuration')) {
router.replace(`/app/${appId}/workflow`)
}
else if ((res.mode !== 'workflow' && res.mode !== 'advanced-chat') && (pathname).endsWith('workflow')) {
else if ((res.mode !== AppModeEnum.WORKFLOW && res.mode !== AppModeEnum.ADVANCED_CHAT) && (pathname).endsWith('workflow')) {
router.replace(`/app/${appId}/configuration`)
}
else {

View File

@ -1,14 +1,15 @@
'use client'
import React, { useState } from 'react'
import dayjs from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
import { useTranslation } from 'react-i18next'
import { TIME_PERIOD_MAPPING } from '@/app/components/app/log/filter'
import type { PeriodParams } from '@/app/components/app/overview/app-chart'
import { AvgResponseTime, AvgSessionInteractions, AvgUserInteractions, ConversationsChart, CostChart, EndUsersChart, MessagesChart, TokenPerSecond, UserSatisfactionRate, WorkflowCostChart, WorkflowDailyTerminalsChart, WorkflowMessagesChart } from '@/app/components/app/overview/app-chart'
import { useStore as useAppStore } from '@/app/components/app/store'
import type { Item } from '@/app/components/base/select'
import { SimpleSelect } from '@/app/components/base/select'
import { TIME_PERIOD_MAPPING } from '@/app/components/app/log/filter'
import { useStore as useAppStore } from '@/app/components/app/store'
import { AppModeEnum } from '@/types/app'
import dayjs from 'dayjs'
import quarterOfYear from 'dayjs/plugin/quarterOfYear'
import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
dayjs.extend(quarterOfYear)
@ -24,8 +25,8 @@ export type IChartViewProps = {
export default function ChartView({ appId, headerRight }: IChartViewProps) {
const { t } = useTranslation()
const appDetail = useAppStore(state => state.appDetail)
const isChatApp = appDetail?.mode !== 'completion' && appDetail?.mode !== 'workflow'
const isWorkflow = appDetail?.mode === 'workflow'
const isChatApp = appDetail?.mode !== AppModeEnum.COMPLETION && appDetail?.mode !== AppModeEnum.WORKFLOW
const isWorkflow = appDetail?.mode === AppModeEnum.WORKFLOW
const [period, setPeriod] = useState<PeriodParams>({ name: t('appLog.filter.period.last7days'), query: { start: today.subtract(7, 'day').startOf('day').format(queryDateFormat), end: today.endOf('day').format(queryDateFormat) } })
const onSelect = (item: Item) => {

View File

@ -30,6 +30,7 @@ import type { Operation } from './app-operations'
import AppOperations from './app-operations'
import dynamic from 'next/dynamic'
import cn from '@/utils/classnames'
import { AppModeEnum } from '@/types/app'
const SwitchAppModal = dynamic(() => import('@/app/components/app/switch-app-modal'), {
ssr: false,
@ -157,7 +158,7 @@ const AppInfo = ({ expand, onlyShowDetail = false, openState = false, onDetailEx
const exportCheck = async () => {
if (!appDetail)
return
if (appDetail.mode !== 'workflow' && appDetail.mode !== 'advanced-chat') {
if (appDetail.mode !== AppModeEnum.WORKFLOW && appDetail.mode !== AppModeEnum.ADVANCED_CHAT) {
onExport()
return
}
@ -238,7 +239,7 @@ const AppInfo = ({ expand, onlyShowDetail = false, openState = false, onDetailEx
const secondaryOperations: Operation[] = [
// Import DSL (conditional)
...(appDetail.mode !== 'agent-chat' && (appDetail.mode === 'advanced-chat' || appDetail.mode === 'workflow')) ? [{
...(appDetail.mode !== AppModeEnum.AGENT_CHAT && (appDetail.mode === AppModeEnum.ADVANCED_CHAT || appDetail.mode === AppModeEnum.WORKFLOW)) ? [{
id: 'import',
title: t('workflow.common.importDSL'),
icon: <RiFileUploadLine />,
@ -270,7 +271,7 @@ const AppInfo = ({ expand, onlyShowDetail = false, openState = false, onDetailEx
]
// Keep the switch operation separate as it's not part of the main operations
const switchOperation = (appDetail.mode !== 'agent-chat' && (appDetail.mode === 'completion' || appDetail.mode === 'chat')) ? {
const switchOperation = (appDetail.mode !== AppModeEnum.AGENT_CHAT && (appDetail.mode === AppModeEnum.COMPLETION || appDetail.mode === AppModeEnum.CHAT)) ? {
id: 'switch',
title: t('app.switch'),
icon: <RiExchange2Line />,
@ -322,7 +323,12 @@ const AppInfo = ({ expand, onlyShowDetail = false, openState = false, onDetailEx
<div className='flex w-full'>
<div className='system-md-semibold truncate whitespace-nowrap text-text-secondary'>{appDetail.name}</div>
</div>
<div className='system-2xs-medium-uppercase whitespace-nowrap text-text-tertiary'>{appDetail.mode === 'advanced-chat' ? t('app.types.advanced') : appDetail.mode === 'agent-chat' ? t('app.types.agent') : appDetail.mode === 'chat' ? t('app.types.chatbot') : appDetail.mode === 'completion' ? t('app.types.completion') : t('app.types.workflow')}</div>
<div className='system-2xs-medium-uppercase whitespace-nowrap text-text-tertiary'>
{appDetail.mode === AppModeEnum.ADVANCED_CHAT ? t('app.types.advanced')
: appDetail.mode === AppModeEnum.AGENT_CHAT ? t('app.types.agent')
: appDetail.mode === AppModeEnum.CHAT ? t('app.types.chatbot')
: appDetail.mode === AppModeEnum.COMPLETION ? t('app.types.completion')
: t('app.types.workflow')}</div>
</div>
)}
</div>
@ -347,7 +353,7 @@ const AppInfo = ({ expand, onlyShowDetail = false, openState = false, onDetailEx
/>
<div className='flex flex-1 flex-col items-start justify-center overflow-hidden'>
<div className='system-md-semibold w-full truncate text-text-secondary'>{appDetail.name}</div>
<div className='system-2xs-medium-uppercase text-text-tertiary'>{appDetail.mode === 'advanced-chat' ? t('app.types.advanced') : appDetail.mode === 'agent-chat' ? t('app.types.agent') : appDetail.mode === 'chat' ? t('app.types.chatbot') : appDetail.mode === 'completion' ? t('app.types.completion') : t('app.types.workflow')}</div>
<div className='system-2xs-medium-uppercase text-text-tertiary'>{appDetail.mode === AppModeEnum.ADVANCED_CHAT ? t('app.types.advanced') : appDetail.mode === AppModeEnum.AGENT_CHAT ? t('app.types.agent') : appDetail.mode === AppModeEnum.CHAT ? t('app.types.chatbot') : appDetail.mode === AppModeEnum.COMPLETION ? t('app.types.completion') : t('app.types.workflow')}</div>
</div>
</div>
{/* description */}

View File

@ -17,6 +17,7 @@ import NavLink from './navLink'
import { useStore as useAppStore } from '@/app/components/app/store'
import type { NavIcon } from './navLink'
import cn from '@/utils/classnames'
import { AppModeEnum } from '@/types/app'
type Props = {
navigation: Array<{
@ -97,7 +98,7 @@ const AppSidebarDropdown = ({ navigation }: Props) => {
<div className='flex w-full'>
<div className='system-md-semibold truncate text-text-secondary'>{appDetail.name}</div>
</div>
<div className='system-2xs-medium-uppercase text-text-tertiary'>{appDetail.mode === 'advanced-chat' ? t('app.types.advanced') : appDetail.mode === 'agent-chat' ? t('app.types.agent') : appDetail.mode === 'chat' ? t('app.types.chatbot') : appDetail.mode === 'completion' ? t('app.types.completion') : t('app.types.workflow')}</div>
<div className='system-2xs-medium-uppercase text-text-tertiary'>{appDetail.mode === AppModeEnum.ADVANCED_CHAT ? t('app.types.advanced') : appDetail.mode === AppModeEnum.AGENT_CHAT ? t('app.types.agent') : appDetail.mode === AppModeEnum.CHAT ? t('app.types.chatbot') : appDetail.mode === AppModeEnum.COMPLETION ? t('app.types.completion') : t('app.types.workflow')}</div>
</div>
</div>
</div>

View File

@ -24,7 +24,7 @@ import type { AnnotationReplyConfig } from '@/models/debug'
import { sleep } from '@/utils'
import { useProviderContext } from '@/context/provider-context'
import AnnotationFullModal from '@/app/components/billing/annotation-full/modal'
import type { App } from '@/types/app'
import { type App, AppModeEnum } from '@/types/app'
import cn from '@/utils/classnames'
import { delAnnotations } from '@/service/annotation'
@ -37,7 +37,7 @@ const Annotation: FC<Props> = (props) => {
const { t } = useTranslation()
const [isShowEdit, setIsShowEdit] = useState(false)
const [annotationConfig, setAnnotationConfig] = useState<AnnotationReplyConfig | null>(null)
const [isChatApp] = useState(appDetail.mode !== 'completion')
const [isChatApp] = useState(appDetail.mode !== AppModeEnum.COMPLETION)
const [controlRefreshSwitch, setControlRefreshSwitch] = useState(() => Date.now())
const { plan, enableBilling } = useProviderContext()
const isAnnotationFull = enableBilling && plan.usage.annotatedResponse >= plan.total.annotatedResponse

View File

@ -407,7 +407,7 @@ const AppPublisher = ({
{t('workflow.common.accessAPIReference')}
</SuggestedAction>
</Tooltip>
{appDetail?.mode === 'workflow' && (
{appDetail?.mode === AppModeEnum.WORKFLOW && (
<WorkflowToolConfigureButton
disabled={workflowToolDisabled}
published={!!toolPublished}

View File

@ -28,7 +28,7 @@ import { jsonConfigPlaceHolder, jsonObjectWrap } from './config'
import { useStore as useAppStore } from '@/app/components/app/store'
import Textarea from '@/app/components/base/textarea'
import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uploader'
import { TransferMethod } from '@/types/app'
import { AppModeEnum, TransferMethod } from '@/types/app'
import type { FileEntity } from '@/app/components/base/file-uploader/types'
const TEXT_MAX_LENGTH = 256
@ -70,7 +70,7 @@ const ConfigModal: FC<IConfigModalProps> = ({
const { type, label, variable, options, max_length } = tempPayload
const modalRef = useRef<HTMLDivElement>(null)
const appDetail = useAppStore(state => state.appDetail)
const isBasicApp = appDetail?.mode !== 'advanced-chat' && appDetail?.mode !== 'workflow'
const isBasicApp = appDetail?.mode !== AppModeEnum.ADVANCED_CHAT && appDetail?.mode !== AppModeEnum.WORKFLOW
const isSupportJSON = false
const jsonSchemaStr = useMemo(() => {
const isJsonObject = type === InputVarType.jsonObject

View File

@ -13,7 +13,7 @@ import CardItem from './card-item/item'
import ParamsConfig from './params-config'
import ContextVar from './context-var'
import ConfigContext from '@/context/debug-configuration'
import { AppType } from '@/types/app'
import { AppModeEnum } from '@/types/app'
import type { DataSet } from '@/models/datasets'
import {
getMultipleRetrievalConfig,
@ -232,7 +232,7 @@ const DatasetConfig: FC = () => {
draft.metadata_model_config = {
provider: model.provider,
name: model.modelId,
mode: model.mode || 'chat',
mode: model.mode || AppModeEnum.CHAT,
completion_params: draft.metadata_model_config?.completion_params || { temperature: 0.7 },
}
})
@ -302,7 +302,7 @@ const DatasetConfig: FC = () => {
/>
</div>
{mode === AppType.completion && dataSet.length > 0 && (
{mode === AppModeEnum.COMPLETION && dataSet.length > 0 && (
<ContextVar
value={selectedContextVar?.key}
options={promptVariablesToSelect}

View File

@ -11,6 +11,7 @@ import Dropdown from '@/app/components/base/dropdown'
import type { Item } from '@/app/components/base/dropdown'
import { useProviderContext } from '@/context/provider-context'
import { ModelStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { AppModeEnum } from '@/types/app'
type DebugItemProps = {
modelAndParameter: ModelAndParameter
@ -112,13 +113,13 @@ const DebugItem: FC<DebugItemProps> = ({
</div>
<div style={{ height: 'calc(100% - 40px)' }}>
{
(mode === 'chat' || mode === 'agent-chat') && currentProvider && currentModel && currentModel.status === ModelStatusEnum.active && (
(mode === AppModeEnum.CHAT || mode === AppModeEnum.AGENT_CHAT) && currentProvider && currentModel && currentModel.status === ModelStatusEnum.active && (
<ChatItem modelAndParameter={modelAndParameter} />
)
}
{
mode === 'completion' && currentProvider && currentModel && currentModel.status === ModelStatusEnum.active && (
<TextGenerationItem modelAndParameter={modelAndParameter}/>
mode === AppModeEnum.COMPLETION && currentProvider && currentModel && currentModel.status === ModelStatusEnum.active && (
<TextGenerationItem modelAndParameter={modelAndParameter} />
)
}
</div>

View File

@ -18,6 +18,7 @@ import { useFeatures } from '@/app/components/base/features/hooks'
import { useStore as useAppStore } from '@/app/components/app/store'
import type { FileEntity } from '@/app/components/base/file-uploader/types'
import type { InputForm } from '@/app/components/base/chat/chat/type'
import { AppModeEnum } from '@/types/app'
const DebugWithMultipleModel = () => {
const {
@ -33,7 +34,7 @@ const DebugWithMultipleModel = () => {
} = useDebugWithMultipleModelContext()
const { eventEmitter } = useEventEmitterContextContext()
const isChatMode = mode === 'chat' || mode === 'agent-chat'
const isChatMode = mode === AppModeEnum.CHAT || mode === AppModeEnum.AGENT_CHAT
const handleSend = useCallback((message: string, files?: FileEntity[]) => {
if (checkCanSend && !checkCanSend())

View File

@ -3,14 +3,14 @@ import { clone } from 'lodash-es'
import { produce } from 'immer'
import type { ChatPromptConfig, CompletionPromptConfig, ConversationHistoriesRole, PromptItem } from '@/models/debug'
import { PromptMode } from '@/models/debug'
import { ModelModeType } from '@/types/app'
import { AppModeEnum, ModelModeType } from '@/types/app'
import { DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
import { PRE_PROMPT_PLACEHOLDER_TEXT, checkHasContextBlock, checkHasHistoryBlock, checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
import { fetchPromptTemplate } from '@/service/debug'
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
type Param = {
appMode: string
appMode: AppModeEnum
modelModeType: ModelModeType
modelName: string
promptMode: PromptMode
@ -152,7 +152,7 @@ const useAdvancedPromptConfig = ({
else
draft.prompt.text = completionPromptConfig.prompt?.text.replace(PRE_PROMPT_PLACEHOLDER_TEXT, toReplacePrePrompt)
if (['advanced-chat', 'agent-chat', 'chat'].includes(appMode) && completionPromptConfig.conversation_histories_role.assistant_prefix && completionPromptConfig.conversation_histories_role.user_prefix)
if ([AppModeEnum.ADVANCED_CHAT, AppModeEnum.AGENT_CHAT, AppModeEnum.CHAT].includes(appMode) && completionPromptConfig.conversation_histories_role.assistant_prefix && completionPromptConfig.conversation_histories_role.user_prefix)
draft.conversation_histories_role = completionPromptConfig.conversation_histories_role
})
setCompletionPromptConfig(newPromptConfig)

View File

@ -47,7 +47,7 @@ import { fetchAppDetail, updateAppModelConfig } from '@/service/apps'
import { promptVariablesToUserInputsForm, userInputsFormToPromptVariables } from '@/utils/model-config'
import { fetchDatasets } from '@/service/datasets'
import { useProviderContext } from '@/context/provider-context'
import { AgentStrategy, AppType, ModelModeType, RETRIEVE_TYPE, Resolution, TransferMethod } from '@/types/app'
import { AgentStrategy, AppModeEnum, ModelModeType, RETRIEVE_TYPE, Resolution, TransferMethod } from '@/types/app'
import { PromptMode } from '@/models/debug'
import { ANNOTATION_DEFAULT, DATASET_DEFAULT, DEFAULT_AGENT_SETTING, DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
import SelectDataSet from '@/app/components/app/configuration/dataset-config/select-dataset'
@ -110,7 +110,7 @@ const Configuration: FC = () => {
const pathname = usePathname()
const matched = pathname.match(/\/app\/([^/]+)/)
const appId = (matched?.length && matched[1]) ? matched[1] : ''
const [mode, setMode] = useState('')
const [mode, setMode] = useState<AppModeEnum>()
const [publishedConfig, setPublishedConfig] = useState<PublishConfig | null>(null)
const [conversationId, setConversationId] = useState<string | null>('')
@ -199,7 +199,7 @@ const Configuration: FC = () => {
dataSets: [],
agentConfig: DEFAULT_AGENT_SETTING,
})
const isAgent = mode === 'agent-chat'
const isAgent = mode === AppModeEnum.AGENT_CHAT
const isOpenAI = modelConfig.provider === 'langgenius/openai/openai'
@ -441,7 +441,7 @@ const Configuration: FC = () => {
const appMode = mode
if (modeMode === ModelModeType.completion) {
if (appMode !== AppType.completion) {
if (appMode !== AppModeEnum.COMPLETION) {
if (!completionPromptConfig.prompt?.text || !completionPromptConfig.conversation_histories_role.assistant_prefix || !completionPromptConfig.conversation_histories_role.user_prefix)
await migrateToDefaultPrompt(true, ModelModeType.completion)
}
@ -544,7 +544,7 @@ const Configuration: FC = () => {
}
setCollectionList(collectionList)
fetchAppDetail({ url: '/apps', id: appId }).then(async (res: any) => {
setMode(res.mode)
setMode(res.mode as AppModeEnum)
const modelConfig = res.model_config
const promptMode = modelConfig.prompt_type === PromptMode.advanced ? PromptMode.advanced : PromptMode.simple
doSetPromptMode(promptMode)
@ -654,7 +654,7 @@ const Configuration: FC = () => {
annotation_reply: modelConfig.annotation_reply,
external_data_tools: modelConfig.external_data_tools,
dataSets: datasets || [],
agentConfig: res.mode === 'agent-chat' ? {
agentConfig: res.mode === AppModeEnum.AGENT_CHAT ? {
max_iteration: DEFAULT_AGENT_SETTING.max_iteration,
...modelConfig.agent_mode,
// remove dataset
@ -710,7 +710,7 @@ const Configuration: FC = () => {
}, [appId])
const promptEmpty = (() => {
if (mode !== AppType.completion)
if (mode !== AppModeEnum.COMPLETION)
return false
if (isAdvancedMode) {
@ -724,7 +724,7 @@ const Configuration: FC = () => {
else { return !modelConfig.configs.prompt_template }
})()
const cannotPublish = (() => {
if (mode !== AppType.completion) {
if (mode !== AppModeEnum.COMPLETION) {
if (!isAdvancedMode)
return false
@ -739,7 +739,7 @@ const Configuration: FC = () => {
}
else { return promptEmpty }
})()
const contextVarEmpty = mode === AppType.completion && dataSets.length > 0 && !hasSetContextVar
const contextVarEmpty = mode === AppModeEnum.COMPLETION && dataSets.length > 0 && !hasSetContextVar
const onPublish = async (modelAndParameter?: ModelAndParameter, features?: FeaturesData) => {
const modelId = modelAndParameter?.model || modelConfig.model_id
const promptTemplate = modelConfig.configs.prompt_template
@ -749,7 +749,7 @@ const Configuration: FC = () => {
notify({ type: 'error', message: t('appDebug.otherError.promptNoBeEmpty') })
return
}
if (isAdvancedMode && mode !== AppType.completion) {
if (isAdvancedMode && mode !== AppModeEnum.COMPLETION) {
if (modelModeType === ModelModeType.completion) {
if (!hasSetBlockStatus.history) {
notify({ type: 'error', message: t('appDebug.otherError.historyNoBeEmpty') })
@ -1082,7 +1082,7 @@ const Configuration: FC = () => {
show
inWorkflow={false}
showFileUpload={false}
isChatMode={mode !== 'completion'}
isChatMode={mode !== AppModeEnum.COMPLETION}
disabled={false}
onChange={handleFeaturesChange}
onClose={() => setShowAppConfigureFeaturesModal(false)}

View File

@ -25,7 +25,7 @@ import { NEED_REFRESH_APP_LIST_KEY } from '@/config'
import { useAppContext } from '@/context/app-context'
import { getRedirection } from '@/utils/app-redirection'
import Input from '@/app/components/base/input'
import type { AppMode } from '@/types/app'
import { AppModeEnum } from '@/types/app'
import { DSLImportMode } from '@/models/app'
import { usePluginDependencies } from '@/app/components/workflow/plugin-dependency/hooks'
@ -61,7 +61,7 @@ const Apps = ({
handleSearch()
}
const [currentType, setCurrentType] = useState<AppMode[]>([])
const [currentType, setCurrentType] = useState<AppModeEnum[]>([])
const [currCategory, setCurrCategory] = useTabSearchParams({
defaultTab: allCategoriesEn,
disableSearchParams: true,
@ -93,15 +93,15 @@ const Apps = ({
if (currentType.length === 0)
return filteredByCategory
return filteredByCategory.filter((item) => {
if (currentType.includes('chat') && item.app.mode === 'chat')
if (currentType.includes(AppModeEnum.CHAT) && item.app.mode === AppModeEnum.CHAT)
return true
if (currentType.includes('advanced-chat') && item.app.mode === 'advanced-chat')
if (currentType.includes(AppModeEnum.ADVANCED_CHAT) && item.app.mode === AppModeEnum.ADVANCED_CHAT)
return true
if (currentType.includes('agent-chat') && item.app.mode === 'agent-chat')
if (currentType.includes(AppModeEnum.AGENT_CHAT) && item.app.mode === AppModeEnum.AGENT_CHAT)
return true
if (currentType.includes('completion') && item.app.mode === 'completion')
if (currentType.includes(AppModeEnum.COMPLETION) && item.app.mode === AppModeEnum.COMPLETION)
return true
if (currentType.includes('workflow') && item.app.mode === 'workflow')
if (currentType.includes(AppModeEnum.WORKFLOW) && item.app.mode === AppModeEnum.WORKFLOW)
return true
return false
})

View File

@ -18,7 +18,7 @@ import { basePath } from '@/utils/var'
import { useAppContext } from '@/context/app-context'
import { useProviderContext } from '@/context/provider-context'
import { ToastContext } from '@/app/components/base/toast'
import type { AppMode } from '@/types/app'
import { AppModeEnum } from '@/types/app'
import { createApp } from '@/service/apps'
import Input from '@/app/components/base/input'
import Textarea from '@/app/components/base/textarea'
@ -35,7 +35,7 @@ type CreateAppProps = {
onSuccess: () => void
onClose: () => void
onCreateFromTemplate?: () => void
defaultAppMode?: AppMode
defaultAppMode?: AppModeEnum
}
function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }: CreateAppProps) {
@ -43,7 +43,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
const { push } = useRouter()
const { notify } = useContext(ToastContext)
const [appMode, setAppMode] = useState<AppMode>(defaultAppMode || 'advanced-chat')
const [appMode, setAppMode] = useState<AppModeEnum>(defaultAppMode || AppModeEnum.ADVANCED_CHAT)
const [appIcon, setAppIcon] = useState<AppIconSelection>({ type: 'emoji', icon: '🤖', background: '#FFEAD5' })
const [showAppIconPicker, setShowAppIconPicker] = useState(false)
const [name, setName] = useState('')
@ -57,7 +57,7 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
const isCreatingRef = useRef(false)
useEffect(() => {
if (appMode === 'chat' || appMode === 'agent-chat' || appMode === 'completion')
if (appMode === AppModeEnum.CHAT || appMode === AppModeEnum.AGENT_CHAT || appMode === AppModeEnum.COMPLETION)
setIsAppTypeExpanded(true)
}, [appMode])
@ -118,24 +118,24 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
<div>
<div className='flex flex-row gap-2'>
<AppTypeCard
active={appMode === 'workflow'}
active={appMode === AppModeEnum.WORKFLOW}
title={t('app.types.workflow')}
description={t('app.newApp.workflowShortDescription')}
icon={<div className='flex h-6 w-6 items-center justify-center rounded-md bg-components-icon-bg-indigo-solid'>
<RiExchange2Fill className='h-4 w-4 text-components-avatar-shape-fill-stop-100' />
</div>}
onClick={() => {
setAppMode('workflow')
setAppMode(AppModeEnum.WORKFLOW)
}} />
<AppTypeCard
active={appMode === 'advanced-chat'}
active={appMode === AppModeEnum.ADVANCED_CHAT}
title={t('app.types.advanced')}
description={t('app.newApp.advancedShortDescription')}
icon={<div className='flex h-6 w-6 items-center justify-center rounded-md bg-components-icon-bg-blue-light-solid'>
<BubbleTextMod className='h-4 w-4 text-components-avatar-shape-fill-stop-100' />
</div>}
onClick={() => {
setAppMode('advanced-chat')
setAppMode(AppModeEnum.ADVANCED_CHAT)
}} />
</div>
</div>
@ -152,34 +152,34 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
{isAppTypeExpanded && (
<div className='flex flex-row gap-2'>
<AppTypeCard
active={appMode === 'chat'}
active={appMode === AppModeEnum.CHAT}
title={t('app.types.chatbot')}
description={t('app.newApp.chatbotShortDescription')}
icon={<div className='flex h-6 w-6 items-center justify-center rounded-md bg-components-icon-bg-blue-solid'>
<ChatBot className='h-4 w-4 text-components-avatar-shape-fill-stop-100' />
</div>}
onClick={() => {
setAppMode('chat')
setAppMode(AppModeEnum.CHAT)
}} />
<AppTypeCard
active={appMode === 'agent-chat'}
active={appMode === AppModeEnum.AGENT_CHAT}
title={t('app.types.agent')}
description={t('app.newApp.agentShortDescription')}
icon={<div className='flex h-6 w-6 items-center justify-center rounded-md bg-components-icon-bg-violet-solid'>
<Logic className='h-4 w-4 text-components-avatar-shape-fill-stop-100' />
</div>}
onClick={() => {
setAppMode('agent-chat')
setAppMode(AppModeEnum.AGENT_CHAT)
}} />
<AppTypeCard
active={appMode === 'completion'}
active={appMode === AppModeEnum.COMPLETION}
title={t('app.newApp.completeApp')}
description={t('app.newApp.completionShortDescription')}
icon={<div className='flex h-6 w-6 items-center justify-center rounded-md bg-components-icon-bg-teal-solid'>
<ListSparkle className='h-4 w-4 text-components-avatar-shape-fill-stop-100' />
</div>}
onClick={() => {
setAppMode('completion')
setAppMode(AppModeEnum.COMPLETION)
}} />
</div>
)}
@ -255,11 +255,11 @@ function CreateApp({ onClose, onSuccess, onCreateFromTemplate, defaultAppMode }:
<AppPreview mode={appMode} />
<div className='absolute left-0 right-0 border-b border-b-divider-subtle'></div>
<div className='flex h-[448px] w-[664px] items-center justify-center' style={{ background: 'repeating-linear-gradient(135deg, transparent, transparent 2px, rgba(16,24,40,0.04) 4px,transparent 3px, transparent 6px)' }}>
<AppScreenShot show={appMode === 'chat'} mode='chat' />
<AppScreenShot show={appMode === 'advanced-chat'} mode='advanced-chat' />
<AppScreenShot show={appMode === 'agent-chat'} mode='agent-chat' />
<AppScreenShot show={appMode === 'completion'} mode='completion' />
<AppScreenShot show={appMode === 'workflow'} mode='workflow' />
<AppScreenShot show={appMode === AppModeEnum.CHAT} mode={AppModeEnum.CHAT} />
<AppScreenShot show={appMode === AppModeEnum.ADVANCED_CHAT} mode={AppModeEnum.ADVANCED_CHAT} />
<AppScreenShot show={appMode === AppModeEnum.AGENT_CHAT} mode={AppModeEnum.AGENT_CHAT} />
<AppScreenShot show={appMode === AppModeEnum.COMPLETION} mode={AppModeEnum.COMPLETION} />
<AppScreenShot show={appMode === AppModeEnum.WORKFLOW} mode={AppModeEnum.WORKFLOW} />
</div>
<div className='absolute left-0 right-0 border-b border-b-divider-subtle'></div>
</div>
@ -309,16 +309,16 @@ function AppTypeCard({ icon, title, description, active, onClick }: AppTypeCardP
</div>
}
function AppPreview({ mode }: { mode: AppMode }) {
function AppPreview({ mode }: { mode: AppModeEnum }) {
const { t } = useTranslation()
const docLink = useDocLink()
const modeToPreviewInfoMap = {
'chat': {
[AppModeEnum.CHAT]: {
title: t('app.types.chatbot'),
description: t('app.newApp.chatbotUserDescription'),
link: docLink('/guides/application-orchestrate/chatbot-application'),
},
'advanced-chat': {
[AppModeEnum.ADVANCED_CHAT]: {
title: t('app.types.advanced'),
description: t('app.newApp.advancedUserDescription'),
link: docLink('/guides/workflow/README', {
@ -326,12 +326,12 @@ function AppPreview({ mode }: { mode: AppMode }) {
'ja-JP': '/guides/workflow/concepts',
}),
},
'agent-chat': {
[AppModeEnum.AGENT_CHAT]: {
title: t('app.types.agent'),
description: t('app.newApp.agentUserDescription'),
link: docLink('/guides/application-orchestrate/agent'),
},
'completion': {
[AppModeEnum.COMPLETION]: {
title: t('app.newApp.completeApp'),
description: t('app.newApp.completionUserDescription'),
link: docLink('/guides/application-orchestrate/text-generator', {
@ -339,7 +339,7 @@ function AppPreview({ mode }: { mode: AppMode }) {
'ja-JP': '/guides/application-orchestrate/README',
}),
},
'workflow': {
[AppModeEnum.WORKFLOW]: {
title: t('app.types.workflow'),
description: t('app.newApp.workflowUserDescription'),
link: docLink('/guides/workflow/README', {
@ -358,14 +358,14 @@ function AppPreview({ mode }: { mode: AppMode }) {
</div>
}
function AppScreenShot({ mode, show }: { mode: AppMode; show: boolean }) {
function AppScreenShot({ mode, show }: { mode: AppModeEnum; show: boolean }) {
const { theme } = useTheme()
const modeToImageMap = {
'chat': 'Chatbot',
'advanced-chat': 'Chatflow',
'agent-chat': 'Agent',
'completion': 'TextGenerator',
'workflow': 'Workflow',
[AppModeEnum.CHAT]: 'Chatbot',
[AppModeEnum.ADVANCED_CHAT]: 'Chatflow',
[AppModeEnum.AGENT_CHAT]: 'Agent',
[AppModeEnum.COMPLETION]: 'TextGenerator',
[AppModeEnum.WORKFLOW]: 'Workflow',
}
return <picture>
<source media="(resolution: 1x)" srcSet={`${basePath}/screenshots/${theme}/${modeToImageMap[mode]}.png`} />

View File

@ -11,6 +11,7 @@ import Loading from '@/app/components/base/loading'
import { PageType } from '@/app/components/base/features/new-feature-panel/annotation-reply/type'
import TabSlider from '@/app/components/base/tab-slider-plain'
import { useStore as useAppStore } from '@/app/components/app/store'
import { AppModeEnum } from '@/types/app'
type Props = {
pageType: PageType
@ -24,7 +25,7 @@ const LogAnnotation: FC<Props> = ({
const appDetail = useAppStore(state => state.appDetail)
const options = useMemo(() => {
if (appDetail?.mode === 'completion')
if (appDetail?.mode === AppModeEnum.COMPLETION)
return [{ value: PageType.log, text: t('appLog.title') }]
return [
{ value: PageType.log, text: t('appLog.title') },
@ -42,7 +43,7 @@ const LogAnnotation: FC<Props> = ({
return (
<div className='flex h-full flex-col px-6 pt-3'>
{appDetail.mode !== 'workflow' && (
{appDetail.mode !== AppModeEnum.WORKFLOW && (
<TabSlider
className='shrink-0'
value={pageType}
@ -52,10 +53,10 @@ const LogAnnotation: FC<Props> = ({
options={options}
/>
)}
<div className={cn('h-0 grow', appDetail.mode !== 'workflow' && 'mt-3')}>
{pageType === PageType.log && appDetail.mode !== 'workflow' && (<Log appDetail={appDetail} />)}
<div className={cn('h-0 grow', appDetail.mode !== AppModeEnum.WORKFLOW && 'mt-3')}>
{pageType === PageType.log && appDetail.mode !== AppModeEnum.WORKFLOW && (<Log appDetail={appDetail} />)}
{pageType === PageType.annotation && (<Annotation appDetail={appDetail} />)}
{pageType === PageType.log && appDetail.mode === 'workflow' && (<WorkflowLog appDetail={appDetail} />)}
{pageType === PageType.log && appDetail.mode === AppModeEnum.WORKFLOW && (<WorkflowLog appDetail={appDetail} />)}
</div>
</div>
)

View File

@ -15,7 +15,8 @@ import Pagination from '@/app/components/base/pagination'
import Loading from '@/app/components/base/loading'
import { fetchChatConversations, fetchCompletionConversations } from '@/service/log'
import { APP_PAGE_LIMIT } from '@/config'
import type { App, AppMode } from '@/types/app'
import type { App } from '@/types/app'
import { AppModeEnum } from '@/types/app'
export type ILogsProps = {
appDetail: App
}
@ -63,7 +64,7 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
const debouncedQueryParams = useDebounce(queryParams, { wait: 500 })
// Get the app type first
const isChatMode = appDetail.mode !== 'completion'
const isChatMode = appDetail.mode !== AppModeEnum.COMPLETION
const query = {
page: currPage + 1,
@ -78,9 +79,9 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
...omit(debouncedQueryParams, ['period']),
}
const getWebAppType = (appType: AppMode) => {
if (appType !== 'completion' && appType !== 'workflow')
return 'chat'
const getWebAppType = (appType: AppModeEnum) => {
if (appType !== AppModeEnum.COMPLETION && appType !== AppModeEnum.WORKFLOW)
return AppModeEnum.CHAT
return appType
}

View File

@ -19,7 +19,7 @@ import Indicator from '../../header/indicator'
import VarPanel from './var-panel'
import type { FeedbackFunc, FeedbackType, IChatItem, SubmitAnnotationFunc } from '@/app/components/base/chat/chat/type'
import type { Annotation, ChatConversationGeneralDetail, ChatConversationsResponse, ChatMessage, ChatMessagesRequest, CompletionConversationGeneralDetail, CompletionConversationsResponse, LogAnnotation } from '@/models/log'
import type { App } from '@/types/app'
import { type App, AppModeEnum } from '@/types/app'
import ActionButton from '@/app/components/base/action-button'
import Loading from '@/app/components/base/loading'
import Drawer from '@/app/components/base/drawer'
@ -369,7 +369,7 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
// Only load initial messages, don't auto-load more
useEffect(() => {
if (appDetail?.id && detail.id && appDetail?.mode !== 'completion' && !fetchInitiated.current) {
if (appDetail?.id && detail.id && appDetail?.mode !== AppModeEnum.COMPLETION && !fetchInitiated.current) {
// Mark as initialized, but don't auto-load more messages
fetchInitiated.current = true
// Still call fetchData to get initial messages
@ -578,8 +578,8 @@ function DetailPanel({ detail, onFeedback }: IDetailPanel) {
}
}, [hasMore, isLoading, loadMoreMessages])
const isChatMode = appDetail?.mode !== 'completion'
const isAdvanced = appDetail?.mode === 'advanced-chat'
const isChatMode = appDetail?.mode !== AppModeEnum.COMPLETION
const isAdvanced = appDetail?.mode === AppModeEnum.ADVANCED_CHAT
const varList = (detail.model_config as any).user_input_form?.map((item: any) => {
const itemContent = item[Object.keys(item)[0]]
@ -899,8 +899,8 @@ const ConversationList: FC<IConversationList> = ({ logs, appDetail, onRefresh })
const [showDrawer, setShowDrawer] = useState<boolean>(false) // Whether to display the chat details drawer
const [currentConversation, setCurrentConversation] = useState<ChatConversationGeneralDetail | CompletionConversationGeneralDetail | undefined>() // Currently selected conversation
const isChatMode = appDetail.mode !== 'completion' // Whether the app is a chat app
const isChatflow = appDetail.mode === 'advanced-chat' // Whether the app is a chatflow app
const isChatMode = appDetail.mode !== AppModeEnum.COMPLETION // Whether the app is a chat app
const isChatflow = appDetail.mode === AppModeEnum.ADVANCED_CHAT // Whether the app is a chatflow app
const { setShowPromptLogModal, setShowAgentLogModal, setShowMessageLogModal } = useAppStore(useShallow(state => ({
setShowPromptLogModal: state.setShowPromptLogModal,
setShowAgentLogModal: state.setShowAgentLogModal,

View File

@ -43,6 +43,7 @@ import { useAppWorkflow } from '@/service/use-workflow'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { BlockEnum } from '@/app/components/workflow/types'
import { useDocLink } from '@/context/i18n'
import { AppModeEnum } from '@/types/app'
export type IAppCardProps = {
className?: string
@ -68,7 +69,7 @@ function AppCard({
const router = useRouter()
const pathname = usePathname()
const { isCurrentWorkspaceManager, isCurrentWorkspaceEditor } = useAppContext()
const { data: currentWorkflow } = useAppWorkflow(appInfo.mode === 'workflow' ? appInfo.id : '')
const { data: currentWorkflow } = useAppWorkflow(appInfo.mode === AppModeEnum.WORKFLOW ? appInfo.id : '')
const docLink = useDocLink()
const appDetail = useAppStore(state => state.appDetail)
const setAppDetail = useAppStore(state => state.setAppDetail)
@ -90,7 +91,7 @@ function AppCard({
api: [{ opName: t('appOverview.overview.apiInfo.doc'), opIcon: RiBookOpenLine }],
app: [],
}
if (appInfo.mode !== 'completion' && appInfo.mode !== 'workflow')
if (appInfo.mode !== AppModeEnum.COMPLETION && appInfo.mode !== AppModeEnum.WORKFLOW)
operationsMap.webapp.push({ opName: t('appOverview.overview.appInfo.embedded.entry'), opIcon: RiWindowLine })
operationsMap.webapp.push({ opName: t('appOverview.overview.appInfo.customize.entry'), opIcon: RiPaintBrushLine })
@ -105,7 +106,7 @@ function AppCard({
const basicName = isApp
? t('appOverview.overview.appInfo.title')
: t('appOverview.overview.apiInfo.title')
const isWorkflowApp = appInfo.mode === 'workflow'
const isWorkflowApp = appInfo.mode === AppModeEnum.WORKFLOW
const appUnpublished = isWorkflowApp && !currentWorkflow?.graph
const hasStartNode = currentWorkflow?.graph?.nodes?.some(node => node.data.type === BlockEnum.Start)
const missingStartNode = isWorkflowApp && !hasStartNode
@ -114,7 +115,7 @@ function AppCard({
const runningStatus = (appUnpublished || missingStartNode) ? false : (isApp ? appInfo.enable_site : appInfo.enable_api)
const isMinimalState = appUnpublished || missingStartNode
const { app_base_url, access_token } = appInfo.site ?? {}
const appMode = (appInfo.mode !== 'completion' && appInfo.mode !== 'workflow') ? 'chat' : appInfo.mode
const appMode = (appInfo.mode !== AppModeEnum.COMPLETION && appInfo.mode !== AppModeEnum.WORKFLOW) ? AppModeEnum.CHAT : appInfo.mode
const appUrl = `${app_base_url}${basePath}/${appMode}/${access_token}`
const apiUrl = appInfo?.api_base_url
@ -328,9 +329,9 @@ function AppCard({
{!isApp && <SecretKeyButton appId={appInfo.id} />}
{OPERATIONS_MAP[cardType].map((op) => {
const disabled
= op.opName === t('appOverview.overview.appInfo.settings.entry')
? false
: !runningStatus
= op.opName === t('appOverview.overview.appInfo.settings.entry')
? false
: !runningStatus
return (
<Button
className="mr-1 min-w-[88px]"
@ -361,7 +362,7 @@ function AppCard({
? (
<>
<SettingsModal
isChat={appMode === 'chat'}
isChat={appMode === AppModeEnum.CHAT}
appInfo={appInfo}
isShow={showSettingsModal}
onClose={() => setShowSettingsModal(false)}

View File

@ -4,7 +4,7 @@ import React from 'react'
import { ArrowTopRightOnSquareIcon } from '@heroicons/react/24/outline'
import { useTranslation } from 'react-i18next'
import { useDocLink } from '@/context/i18n'
import type { AppMode } from '@/types/app'
import { AppModeEnum } from '@/types/app'
import Button from '@/app/components/base/button'
import Modal from '@/app/components/base/modal'
import Tag from '@/app/components/base/tag'
@ -15,7 +15,7 @@ type IShareLinkProps = {
linkUrl: string
api_base_url: string
appId: string
mode: AppMode
mode: AppModeEnum
}
const StepNum: FC<{ children: React.ReactNode }> = ({ children }) =>
@ -42,7 +42,7 @@ const CustomizeModal: FC<IShareLinkProps> = ({
}) => {
const { t } = useTranslation()
const docLink = useDocLink()
const isChatApp = mode === 'chat' || mode === 'advanced-chat'
const isChatApp = mode === AppModeEnum.CHAT || mode === AppModeEnum.ADVANCED_CHAT
return <Modal
title={t(`${prefixCustomize}.title`)}

View File

@ -16,7 +16,7 @@ import Switch from '@/app/components/base/switch'
import PremiumBadge from '@/app/components/base/premium-badge'
import { SimpleSelect } from '@/app/components/base/select'
import type { AppDetailResponse } from '@/models/app'
import type { AppIconType, AppSSO, Language } from '@/types/app'
import { type AppIconType, AppModeEnum, type AppSSO, type Language } from '@/types/app'
import { useToastContext } from '@/app/components/base/toast'
import { languages } from '@/i18n-config/language'
import Tooltip from '@/app/components/base/tooltip'
@ -328,7 +328,7 @@ const SettingsModal: FC<ISettingsModalProps> = ({
<div className='flex items-center justify-between'>
<div className={cn('system-sm-semibold py-1 text-text-secondary')}>{t(`${prefixSettings}.workflow.subTitle`)}</div>
<Switch
disabled={!(appInfo.mode === 'workflow' || appInfo.mode === 'advanced-chat')}
disabled={!(appInfo.mode === AppModeEnum.WORKFLOW || appInfo.mode === AppModeEnum.ADVANCED_CHAT)}
defaultValue={inputInfo.show_workflow_steps}
onChange={v => setInputInfo({ ...inputInfo, show_workflow_steps: v })}
/>

View File

@ -24,6 +24,7 @@ import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/aler
import AppIcon from '@/app/components/base/app-icon'
import { useStore as useAppStore } from '@/app/components/app/store'
import { noop } from 'lodash-es'
import { AppModeEnum } from '@/types/app'
type SwitchAppModalProps = {
show: boolean
@ -77,7 +78,7 @@ const SwitchAppModal = ({ show, appDetail, inAppDetail = false, onSuccess, onClo
isCurrentWorkspaceEditor,
{
id: newAppID,
mode: appDetail.mode === 'completion' ? 'workflow' : 'advanced-chat',
mode: appDetail.mode === AppModeEnum.COMPLETION ? AppModeEnum.WORKFLOW : AppModeEnum.ADVANCED_CHAT,
},
removeOriginal ? replace : push,
)

View File

@ -9,13 +9,14 @@ import {
PortalToFollowElemTrigger,
} from '@/app/components/base/portal-to-follow-elem'
import { BubbleTextMod, ChatBot, ListSparkle, Logic } from '@/app/components/base/icons/src/vender/solid/communication'
import type { AppMode } from '@/types/app'
import { AppModeEnum } from '@/types/app'
export type AppSelectorProps = {
value: Array<AppMode>
value: Array<AppModeEnum>
onChange: (value: AppSelectorProps['value']) => void
}
const allTypes: AppMode[] = ['workflow', 'advanced-chat', 'chat', 'agent-chat', 'completion']
const allTypes: AppModeEnum[] = [AppModeEnum.WORKFLOW, AppModeEnum.ADVANCED_CHAT, AppModeEnum.CHAT, AppModeEnum.AGENT_CHAT, AppModeEnum.COMPLETION]
const AppTypeSelector = ({ value, onChange }: AppSelectorProps) => {
const [open, setOpen] = useState(false)
@ -66,7 +67,7 @@ const AppTypeSelector = ({ value, onChange }: AppSelectorProps) => {
export default AppTypeSelector
type AppTypeIconProps = {
type: AppMode
type: AppModeEnum
style?: React.CSSProperties
className?: string
wrapperClassName?: string
@ -75,27 +76,27 @@ type AppTypeIconProps = {
export const AppTypeIcon = React.memo(({ type, className, wrapperClassName, style }: AppTypeIconProps) => {
const wrapperClassNames = cn('inline-flex h-5 w-5 items-center justify-center rounded-md border border-divider-regular', wrapperClassName)
const iconClassNames = cn('h-3.5 w-3.5 text-components-avatar-shape-fill-stop-100', className)
if (type === 'chat') {
if (type === AppModeEnum.CHAT) {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-blue-solid')}>
<ChatBot className={iconClassNames} />
</div>
}
if (type === 'agent-chat') {
if (type === AppModeEnum.AGENT_CHAT) {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-violet-solid')}>
<Logic className={iconClassNames} />
</div>
}
if (type === 'advanced-chat') {
if (type === AppModeEnum.ADVANCED_CHAT) {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-blue-light-solid')}>
<BubbleTextMod className={iconClassNames} />
</div>
}
if (type === 'workflow') {
if (type === AppModeEnum.WORKFLOW) {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-indigo-solid')}>
<RiExchange2Fill className={iconClassNames} />
</div>
}
if (type === 'completion') {
if (type === AppModeEnum.COMPLETION) {
return <div style={style} className={cn(wrapperClassNames, 'bg-components-icon-bg-teal-solid')}>
<ListSparkle className={iconClassNames} />
</div>
@ -133,7 +134,7 @@ function AppTypeSelectTrigger({ values }: { readonly values: AppSelectorProps['v
type AppTypeSelectorItemProps = {
checked: boolean
type: AppMode
type: AppModeEnum
onClick: () => void
}
function AppTypeSelectorItem({ checked, type, onClick }: AppTypeSelectorItemProps) {
@ -147,21 +148,21 @@ function AppTypeSelectorItem({ checked, type, onClick }: AppTypeSelectorItemProp
}
type AppTypeLabelProps = {
type: AppMode
type: AppModeEnum
className?: string
}
export function AppTypeLabel({ type, className }: AppTypeLabelProps) {
const { t } = useTranslation()
let label = ''
if (type === 'chat')
if (type === AppModeEnum.CHAT)
label = t('app.typeSelector.chatbot')
if (type === 'agent-chat')
if (type === AppModeEnum.AGENT_CHAT)
label = t('app.typeSelector.agent')
if (type === 'completion')
if (type === AppModeEnum.COMPLETION)
label = t('app.typeSelector.completion')
if (type === 'advanced-chat')
if (type === AppModeEnum.ADVANCED_CHAT)
label = t('app.typeSelector.advanced')
if (type === 'workflow')
if (type === AppModeEnum.WORKFLOW)
label = t('app.typeSelector.workflow')
return <span className={className}>{label}</span>

View File

@ -17,7 +17,7 @@ import Pagination from '@/app/components/base/pagination'
import Loading from '@/app/components/base/loading'
import { fetchWorkflowLogs } from '@/service/log'
import { APP_PAGE_LIMIT } from '@/config'
import type { App, AppMode } from '@/types/app'
import { type App, AppModeEnum } from '@/types/app'
import { useAppContext } from '@/context/app-context'
dayjs.extend(utc)
@ -78,9 +78,9 @@ const Logs: FC<ILogsProps> = ({ appDetail }) => {
...omit(debouncedQueryParams, ['period', 'status']),
}
const getWebAppType = (appType: AppMode) => {
if (appType !== 'completion' && appType !== 'workflow')
return 'chat'
const getWebAppType = (appType: AppModeEnum) => {
if (appType !== AppModeEnum.COMPLETION && appType !== AppModeEnum.WORKFLOW)
return AppModeEnum.CHAT
return appType
}

View File

@ -6,7 +6,7 @@ import { ArrowDownIcon } from '@heroicons/react/24/outline'
import DetailPanel from './detail'
import TriggerByDisplay from './trigger-by-display'
import type { WorkflowAppLogDetail, WorkflowLogsResponse } from '@/models/log'
import type { App } from '@/types/app'
import { type App, AppModeEnum } from '@/types/app'
import Loading from '@/app/components/base/loading'
import Drawer from '@/app/components/base/drawer'
import Indicator from '@/app/components/header/indicator'
@ -52,7 +52,7 @@ const WorkflowAppLogList: FC<ILogs> = ({ logs, appDetail, onRefresh }) => {
setSortOrder(sortOrder === 'asc' ? 'desc' : 'asc')
}
const isWorkflow = appDetail?.mode === 'workflow'
const isWorkflow = appDetail?.mode === AppModeEnum.WORKFLOW
const statusTdRender = (status: string) => {
if (status === 'succeeded') {

View File

@ -6,7 +6,7 @@ import { useRouter } from 'next/navigation'
import { useTranslation } from 'react-i18next'
import { RiBuildingLine, RiGlobalLine, RiLockLine, RiMoreFill, RiVerifiedBadgeLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import type { App } from '@/types/app'
import { type App, AppModeEnum } from '@/types/app'
import Toast, { ToastContext } from '@/app/components/base/toast'
import { copyApp, deleteApp, exportAppConfig, updateAppInfo } from '@/service/apps'
import type { DuplicateAppModalProps } from '@/app/components/app/duplicate-modal'
@ -171,7 +171,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
}
const exportCheck = async () => {
if (app.mode !== 'workflow' && app.mode !== 'advanced-chat') {
if (app.mode !== AppModeEnum.WORKFLOW && app.mode !== AppModeEnum.ADVANCED_CHAT) {
onExport()
return
}
@ -269,7 +269,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
<button type="button" className='mx-1 flex h-8 cursor-pointer items-center gap-2 rounded-lg px-3 hover:bg-state-base-hover' onClick={onClickExport}>
<span className='system-sm-regular text-text-secondary'>{t('app.export')}</span>
</button>
{(app.mode === 'completion' || app.mode === 'chat') && (
{(app.mode === AppModeEnum.COMPLETION || app.mode === AppModeEnum.CHAT) && (
<>
<Divider className="my-1" />
<button
@ -425,7 +425,7 @@ const AppCard = ({ app, onRefresh }: AppCardProps) => {
)
}
popupClassName={
(app.mode === 'completion' || app.mode === 'chat')
(app.mode === AppModeEnum.COMPLETION || app.mode === AppModeEnum.CHAT)
? '!w-[256px] translate-x-[-224px]'
: '!w-[216px] translate-x-[-128px]'
}

View File

@ -34,6 +34,7 @@ import dynamic from 'next/dynamic'
import Empty from './empty'
import Footer from './footer'
import { useGlobalPublicStore } from '@/context/global-public-context'
import { AppModeEnum } from '@/types/app'
const TagManagementModal = dynamic(() => import('@/app/components/base/tag-management'), {
ssr: false,
@ -115,11 +116,11 @@ const List = () => {
const anchorRef = useRef<HTMLDivElement>(null)
const options = [
{ value: 'all', text: t('app.types.all'), icon: <RiApps2Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: 'workflow', text: t('app.types.workflow'), icon: <RiExchange2Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: 'advanced-chat', text: t('app.types.advanced'), icon: <RiMessage3Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: 'chat', text: t('app.types.chatbot'), icon: <RiMessage3Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: 'agent-chat', text: t('app.types.agent'), icon: <RiRobot3Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: 'completion', text: t('app.types.completion'), icon: <RiFile4Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: AppModeEnum.WORKFLOW, text: t('app.types.workflow'), icon: <RiExchange2Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: AppModeEnum.ADVANCED_CHAT, text: t('app.types.advanced'), icon: <RiMessage3Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: AppModeEnum.CHAT, text: t('app.types.chatbot'), icon: <RiMessage3Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: AppModeEnum.AGENT_CHAT, text: t('app.types.agent'), icon: <RiRobot3Line className='mr-1 h-[14px] w-[14px]' /> },
{ value: AppModeEnum.COMPLETION, text: t('app.types.completion'), icon: <RiFile4Line className='mr-1 h-[14px] w-[14px]' /> },
]
useEffect(() => {

View File

@ -6,6 +6,7 @@ import { RiArrowRightUpLine } from '@remixicon/react'
import cn from '@/utils/classnames'
import AppIcon from '@/app/components/base/app-icon'
import type { RelatedApp } from '@/models/datasets'
import { AppModeEnum } from '@/types/app'
type ILikedItemProps = {
appStatus?: boolean
@ -14,11 +15,11 @@ type ILikedItemProps = {
}
const appTypeMap = {
'chat': 'Chatbot',
'completion': 'Completion',
'agent-chat': 'Agent',
'advanced-chat': 'Chatflow',
'workflow': 'Workflow',
[AppModeEnum.CHAT]: 'Chatbot',
[AppModeEnum.COMPLETION]: 'Completion',
[AppModeEnum.AGENT_CHAT]: 'Agent',
[AppModeEnum.ADVANCED_CHAT]: 'Chatflow',
[AppModeEnum.WORKFLOW]: 'Workflow',
}
const LikedItem = ({

View File

@ -18,7 +18,7 @@ import TemplateChatJa from './template/template_chat.ja.mdx'
import I18n from '@/context/i18n'
import { LanguagesSupported } from '@/i18n-config/language'
import useTheme from '@/hooks/use-theme'
import { Theme } from '@/types/app'
import { AppModeEnum, Theme } from '@/types/app'
import cn from '@/utils/classnames'
type IDocProps = {
@ -115,7 +115,7 @@ const Doc = ({ appDetail }: IDocProps) => {
}
const Template = useMemo(() => {
if (appDetail?.mode === 'chat' || appDetail?.mode === 'agent-chat') {
if (appDetail?.mode === AppModeEnum.CHAT || appDetail?.mode === AppModeEnum.AGENT_CHAT) {
switch (locale) {
case LanguagesSupported[1]:
return <TemplateChatZh appDetail={appDetail} variables={variables} inputs={inputs} />
@ -125,7 +125,7 @@ const Doc = ({ appDetail }: IDocProps) => {
return <TemplateChatEn appDetail={appDetail} variables={variables} inputs={inputs} />
}
}
if (appDetail?.mode === 'advanced-chat') {
if (appDetail?.mode === AppModeEnum.ADVANCED_CHAT) {
switch (locale) {
case LanguagesSupported[1]:
return <TemplateAdvancedChatZh appDetail={appDetail} variables={variables} inputs={inputs} />
@ -135,7 +135,7 @@ const Doc = ({ appDetail }: IDocProps) => {
return <TemplateAdvancedChatEn appDetail={appDetail} variables={variables} inputs={inputs} />
}
}
if (appDetail?.mode === 'workflow') {
if (appDetail?.mode === AppModeEnum.WORKFLOW) {
switch (locale) {
case LanguagesSupported[1]:
return <TemplateWorkflowZh appDetail={appDetail} variables={variables} inputs={inputs} />
@ -145,7 +145,7 @@ const Doc = ({ appDetail }: IDocProps) => {
return <TemplateWorkflowEn appDetail={appDetail} variables={variables} inputs={inputs} />
}
}
if (appDetail?.mode === 'completion') {
if (appDetail?.mode === AppModeEnum.COMPLETION) {
switch (locale) {
case LanguagesSupported[1]:
return <TemplateZh appDetail={appDetail} variables={variables} inputs={inputs} />

View File

@ -6,6 +6,7 @@ import cn from '@/utils/classnames'
import type { App } from '@/models/explore'
import AppIcon from '@/app/components/base/app-icon'
import { AppTypeIcon } from '../../app/type-selector'
import { AppModeEnum } from '@/types/app'
export type AppCardProps = {
app: App
canCreate: boolean
@ -40,11 +41,11 @@ const AppCard = ({
<div className='truncate' title={appBasicInfo.name}>{appBasicInfo.name}</div>
</div>
<div className='flex items-center text-[10px] font-medium leading-[18px] text-text-tertiary'>
{appBasicInfo.mode === 'advanced-chat' && <div className='truncate'>{t('app.types.advanced').toUpperCase()}</div>}
{appBasicInfo.mode === 'chat' && <div className='truncate'>{t('app.types.chatbot').toUpperCase()}</div>}
{appBasicInfo.mode === 'agent-chat' && <div className='truncate'>{t('app.types.agent').toUpperCase()}</div>}
{appBasicInfo.mode === 'workflow' && <div className='truncate'>{t('app.types.workflow').toUpperCase()}</div>}
{appBasicInfo.mode === 'completion' && <div className='truncate'>{t('app.types.completion').toUpperCase()}</div>}
{appBasicInfo.mode === AppModeEnum.ADVANCED_CHAT && <div className='truncate'>{t('app.types.advanced').toUpperCase()}</div>}
{appBasicInfo.mode === AppModeEnum.CHAT && <div className='truncate'>{t('app.types.chatbot').toUpperCase()}</div>}
{appBasicInfo.mode === AppModeEnum.AGENT_CHAT && <div className='truncate'>{t('app.types.agent').toUpperCase()}</div>}
{appBasicInfo.mode === AppModeEnum.WORKFLOW && <div className='truncate'>{t('app.types.workflow').toUpperCase()}</div>}
{appBasicInfo.mode === AppModeEnum.COMPLETION && <div className='truncate'>{t('app.types.completion').toUpperCase()}</div>}
</div>
</div>
</div>

View File

@ -13,7 +13,7 @@ import Toast from '@/app/components/base/toast'
import AppIcon from '@/app/components/base/app-icon'
import { useProviderContext } from '@/context/provider-context'
import AppsFull from '@/app/components/billing/apps-full-in-dialog'
import type { AppIconType } from '@/types/app'
import { type AppIconType, AppModeEnum } from '@/types/app'
import { noop } from 'lodash-es'
export type CreateAppModalProps = {
@ -158,7 +158,7 @@ const CreateAppModal = ({
/>
</div>
{/* answer icon */}
{isEditModal && (appMode === 'chat' || appMode === 'advanced-chat' || appMode === 'agent-chat') && (
{isEditModal && (appMode === AppModeEnum.CHAT || appMode === AppModeEnum.ADVANCED_CHAT || appMode === AppModeEnum.AGENT_CHAT) && (
<div className='pt-2'>
<div className='flex items-center justify-between'>
<div className='py-2 text-sm font-medium leading-[20px] text-text-primary'>{t('app.answerIcon.title')}</div>

View File

@ -12,6 +12,7 @@ import AppUnavailable from '../../base/app-unavailable'
import { useGetUserCanAccessApp } from '@/service/access-control'
import { useGetInstalledAppAccessModeByAppId, useGetInstalledAppMeta, useGetInstalledAppParams } from '@/service/use-explore'
import type { AppData } from '@/models/share'
import { AppModeEnum } from '@/types/app'
export type IInstalledAppProps = {
id: string
@ -102,13 +103,13 @@ const InstalledApp: FC<IInstalledAppProps> = ({
}
return (
<div className='h-full bg-background-default py-2 pl-0 pr-2 sm:p-2'>
{installedApp?.app.mode !== 'completion' && installedApp?.app.mode !== 'workflow' && (
{installedApp?.app.mode !== AppModeEnum.COMPLETION && installedApp?.app.mode !== AppModeEnum.WORKFLOW && (
<ChatWithHistory installedAppInfo={installedApp} className='overflow-hidden rounded-2xl shadow-md' />
)}
{installedApp?.app.mode === 'completion' && (
{installedApp?.app.mode === AppModeEnum.COMPLETION && (
<TextGenerationApp isInstalledApp installedAppInfo={installedApp} />
)}
{installedApp?.app.mode === 'workflow' && (
{installedApp?.app.mode === AppModeEnum.WORKFLOW && (
<TextGenerationApp isWorkflow isInstalledApp installedAppInfo={installedApp} />
)}
</div>

View File

@ -31,12 +31,13 @@ import Loading from '@/app/components/base/loading'
import { useProviderContext } from '@/context/provider-context'
import { PROVIDER_WITH_PRESET_TONE, STOP_PARAMETER_RULE, TONE_LIST } from '@/config'
import { ArrowNarrowLeft } from '@/app/components/base/icons/src/vender/line/arrows'
import type { AppModeEnum } from '@/types/app'
export type ModelParameterModalProps = {
popupClassName?: string
portalToFollowElemContentClassName?: string
isAdvancedMode: boolean
mode: string
mode: AppModeEnum
modelId: string
provider: string
setModel: (model: { modelId: string; provider: string; mode?: string; features?: string[] }) => void

View File

@ -19,6 +19,7 @@ import CreateFromDSLModal from '@/app/components/app/create-from-dsl-modal'
import type { AppListResponse } from '@/models/app'
import { useAppContext } from '@/context/app-context'
import { useStore as useAppStore } from '@/app/components/app/store'
import { AppModeEnum } from '@/types/app'
const getKey = (
pageIndex: number,
@ -79,7 +80,7 @@ const AppNav = () => {
return `/app/${app.id}/overview`
}
else {
if (app.mode === 'workflow' || app.mode === 'advanced-chat')
if (app.mode === AppModeEnum.WORKFLOW || app.mode === AppModeEnum.ADVANCED_CHAT)
return `/app/${app.id}/workflow`
else
return `/app/${app.id}/configuration`

View File

@ -15,7 +15,7 @@ import { AppTypeIcon } from '@/app/components/app/type-selector'
import { useAppContext } from '@/context/app-context'
import { useStore as useAppStore } from '@/app/components/app/store'
import { FileArrow01, FilePlus01, FilePlus02 } from '@/app/components/base/icons/src/vender/line/files'
import type { AppIconType, AppMode } from '@/types/app'
import type { AppIconType, AppModeEnum } from '@/types/app'
export type NavItem = {
id: string
@ -25,7 +25,7 @@ export type NavItem = {
icon: string
icon_background: string | null
icon_url: string | null
mode?: AppMode
mode?: AppModeEnum
}
export type INavSelectorProps = {
navigationItems: NavItem[]

View File

@ -6,7 +6,7 @@ import AppInputsForm from '@/app/components/plugins/plugin-detail-panel/app-sele
import { useAppDetail } from '@/service/use-apps'
import { useAppWorkflow } from '@/service/use-workflow'
import { useFileUploadConfig } from '@/service/use-common'
import { Resolution } from '@/types/app'
import { AppModeEnum, Resolution } from '@/types/app'
import { FILE_EXTS } from '@/app/components/base/prompt-editor/constants'
import type { App } from '@/types/app'
import type { FileUpload } from '@/app/components/base/features/types'
@ -30,7 +30,7 @@ const AppInputsPanel = ({
}: Props) => {
const { t } = useTranslation()
const inputsRef = useRef<any>(value?.inputs || {})
const isBasicApp = appDetail.mode !== 'advanced-chat' && appDetail.mode !== 'workflow'
const isBasicApp = appDetail.mode !== AppModeEnum.ADVANCED_CHAT && appDetail.mode !== AppModeEnum.WORKFLOW
const { data: fileUploadConfig } = useFileUploadConfig()
const { data: currentApp, isFetching: isAppLoading } = useAppDetail(appDetail.id)
const { data: currentWorkflow, isFetching: isWorkflowLoading } = useAppWorkflow(isBasicApp ? '' : appDetail.id)
@ -77,7 +77,7 @@ const AppInputsPanel = ({
required: false,
}
}
if(item.checkbox) {
if (item.checkbox) {
return {
...item.checkbox,
type: 'checkbox',
@ -148,7 +148,7 @@ const AppInputsPanel = ({
}
}) || []
}
if ((currentApp.mode === 'completion' || currentApp.mode === 'workflow') && basicAppFileConfig.enabled) {
if ((currentApp.mode === AppModeEnum.COMPLETION || currentApp.mode === AppModeEnum.WORKFLOW) && basicAppFileConfig.enabled) {
inputFormSchema.push({
label: 'Image Upload',
variable: '#image#',

View File

@ -12,7 +12,7 @@ import type {
} from '@floating-ui/react'
import Input from '@/app/components/base/input'
import AppIcon from '@/app/components/base/app-icon'
import type { App } from '@/types/app'
import { type App, AppModeEnum } from '@/types/app'
import { useTranslation } from 'react-i18next'
type Props = {
@ -118,15 +118,15 @@ const AppPicker: FC<Props> = ({
const getAppType = (app: App) => {
switch (app.mode) {
case 'advanced-chat':
case AppModeEnum.ADVANCED_CHAT:
return 'chatflow'
case 'agent-chat':
case AppModeEnum.AGENT_CHAT:
return 'agent'
case 'chat':
case AppModeEnum.CHAT:
return 'chat'
case 'completion':
case AppModeEnum.COMPLETION:
return 'completion'
case 'workflow':
case AppModeEnum.WORKFLOW:
return 'workflow'
}
}

View File

@ -13,7 +13,7 @@ import CopyFeedback from '@/app/components/base/copy-feedback'
import Confirm from '@/app/components/base/confirm'
import type { AppDetailResponse } from '@/models/app'
import { useAppContext } from '@/context/app-context'
import type { AppSSO } from '@/types/app'
import { AppModeEnum, type AppSSO } from '@/types/app'
import Indicator from '@/app/components/header/indicator'
import MCPServerModal from '@/app/components/tools/mcp/mcp-server-modal'
import { useAppWorkflow } from '@/service/use-workflow'
@ -45,7 +45,7 @@ function MCPServiceCard({
const [showConfirmDelete, setShowConfirmDelete] = useState(false)
const [showMCPServerModal, setShowMCPServerModal] = useState(false)
const isAdvancedApp = appInfo?.mode === 'advanced-chat' || appInfo?.mode === 'workflow'
const isAdvancedApp = appInfo?.mode === AppModeEnum.ADVANCED_CHAT || appInfo?.mode === AppModeEnum.WORKFLOW
const isBasicApp = !isAdvancedApp
const { data: currentWorkflow } = useAppWorkflow(isAdvancedApp ? appId : '')
const [basicAppConfig, setBasicAppConfig] = useState<any>({})
@ -71,7 +71,7 @@ function MCPServiceCard({
const { data: detail } = useMCPServerDetail(appId)
const { id, status, server_code } = detail ?? {}
const isWorkflowApp = appInfo.mode === 'workflow'
const isWorkflowApp = appInfo.mode === AppModeEnum.WORKFLOW
const appUnpublished = isAdvancedApp ? !currentWorkflow?.graph : !basicAppConfig.updated_at
const serverPublished = !!id
const serverActivated = status === 'active'

View File

@ -1,7 +1,8 @@
import { useStore as useAppStore } from '@/app/components/app/store'
import { AppModeEnum } from '@/types/app'
export const useIsChatMode = () => {
const appDetail = useAppStore(s => s.appDetail)
return appDetail?.mode === 'advanced-chat'
return appDetail?.mode === AppModeEnum.ADVANCED_CHAT
}

View File

@ -19,6 +19,7 @@ import type { FetchWorkflowDraftResponse } from '@/types/workflow'
import { useWorkflowConfig } from '@/service/use-workflow'
import type { FileUploadConfigResponse } from '@/models/common'
import { BlockEnum } from '@/app/components/workflow/types'
import { AppModeEnum } from '@/types/app'
const hasConnectedUserInput = (nodes: any[] = [], edges: any[] = []) => {
const startNodeIds = nodes
@ -73,7 +74,7 @@ export const useWorkflowInit = () => {
if (error && error.json && !error.bodyUsed && appDetail) {
error.json().then((err: any) => {
if (err.code === 'draft_workflow_not_exist') {
const isAdvancedChat = appDetail.mode === 'advanced-chat'
const isAdvancedChat = appDetail.mode === AppModeEnum.ADVANCED_CHAT
workflowStore.setState({
notInitialWorkflow: true,
showOnboarding: !isAdvancedChat,

View File

@ -26,6 +26,7 @@ import { useConfigsMap } from './use-configs-map'
import { API_PREFIX } from '@/config'
import { base } from '@/service/fetch'
import { TriggerType } from '@/app/components/workflow/header/test-run-menu'
import { AppModeEnum } from '@/types/app'
type HandleRunMode = TriggerType
type HandleRunOptions = {
@ -169,7 +170,7 @@ export const useWorkflowRun = () => {
clientHeight,
} = workflowContainer!
const isInWorkflowDebug = appDetail?.mode === 'workflow'
const isInWorkflowDebug = appDetail?.mode === AppModeEnum.WORKFLOW
let url = ''
if (runMode === TriggerType.Plugin || runMode === TriggerType.Webhook || runMode === TriggerType.Schedule) {
@ -186,7 +187,7 @@ export const useWorkflowRun = () => {
}
url = `/apps/${appDetail.id}/workflows/draft/trigger/run-all`
}
else if (appDetail?.mode === 'advanced-chat') {
else if (appDetail?.mode === AppModeEnum.ADVANCED_CHAT) {
url = `/apps/${appDetail.id}/advanced-chat/workflows/draft/run`
}
else if (isInWorkflowDebug && appDetail?.id) {

View File

@ -34,6 +34,7 @@ import { useSearchParams } from 'next/navigation'
import { fetchRunDetail } from '@/service/log'
import { useGetRunAndTraceUrl } from './hooks/use-get-run-and-trace-url'
import { AppModeEnum } from '@/types/app'
const WorkflowAppWithAdditionalContext = () => {
const {
@ -48,7 +49,7 @@ const WorkflowAppWithAdditionalContext = () => {
const { setTriggerStatuses } = useTriggerStatusStore()
const appDetail = useAppStore(s => s.appDetail)
const appId = appDetail?.id
const isWorkflowMode = appDetail?.mode === 'workflow'
const isWorkflowMode = appDetail?.mode === AppModeEnum.WORKFLOW
const { data: triggersResponse } = useAppTriggers(isWorkflowMode ? appId : undefined, {
staleTime: 5 * 60 * 1000, // 5 minutes cache
refetchOnWindowFocus: false,

View File

@ -46,11 +46,12 @@ import { CUSTOM_ITERATION_START_NODE } from '@/app/components/workflow/nodes/ite
import { CUSTOM_LOOP_START_NODE } from '@/app/components/workflow/nodes/loop-start/constants'
import { basePath } from '@/utils/var'
import { useNodesMetaData } from '.'
import { AppModeEnum } from '@/types/app'
export const useIsChatMode = () => {
const appDetail = useAppStore(s => s.appDetail)
return appDetail?.mode === 'advanced-chat'
return appDetail?.mode === AppModeEnum.ADVANCED_CHAT
}
export const useWorkflow = () => {

View File

@ -22,6 +22,7 @@ import type { Node } from 'reactflow'
import type { PluginMeta } from '@/app/components/plugins/types'
import { noop } from 'lodash-es'
import { useDocLink } from '@/context/i18n'
import { AppModeEnum } from '@/types/app'
export type Strategy = {
agent_strategy_provider_name: string
@ -99,7 +100,7 @@ export const AgentStrategy = memo((props: AgentStrategyProps) => {
modelConfig={
defaultModel.data
? {
mode: 'chat',
mode: AppModeEnum.CHAT,
name: defaultModel.data.model,
provider: defaultModel.data.provider.provider,
completion_params: {},

View File

@ -63,6 +63,7 @@ import type { PromptItem } from '@/models/debug'
import { VAR_REGEX } from '@/config'
import type { AgentNodeType } from '../../../agent/types'
import type { SchemaTypeDefinition } from '@/service/use-common'
import { AppModeEnum } from '@/types/app'
export const isSystemVar = (valueSelector: ValueSelector) => {
return valueSelector[0] === 'sys' || valueSelector[1] === 'sys'
@ -1278,7 +1279,7 @@ export const getNodeUsedVars = (node: Node): ValueSelector[] => {
}
case BlockEnum.LLM: {
const payload = data as LLMNodeType
const isChatModel = payload.model?.mode === 'chat'
const isChatModel = payload.model?.mode === AppModeEnum.CHAT
let prompts: string[] = []
if (isChatModel) {
prompts
@ -1581,7 +1582,7 @@ export const updateNodeVars = (
}
case BlockEnum.LLM: {
const payload = data as LLMNodeType
const isChatModel = payload.model?.mode === 'chat'
const isChatModel = payload.model?.mode === AppModeEnum.CHAT
if (isChatModel) {
payload.prompt_template = (
payload.prompt_template as PromptItem[]

View File

@ -11,6 +11,7 @@ import type { MetadataShape } from '@/app/components/workflow/nodes/knowledge-re
import { MetadataFilteringModeEnum } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
import ModelParameterModal from '@/app/components/header/account-setting/model-provider-page/model-parameter-modal'
import { noop } from 'lodash-es'
import { AppModeEnum } from '@/types/app'
type MetadataFilterProps = {
metadataFilterMode?: MetadataFilteringModeEnum
@ -84,7 +85,7 @@ const MetadataFilter = ({
popupClassName='!w-[387px]'
isInWorkflow
isAdvancedMode={true}
mode={metadataModelConfig?.mode || 'chat'}
mode={metadataModelConfig?.mode || AppModeEnum.CHAT}
provider={metadataModelConfig?.provider || ''}
completionParams={metadataModelConfig?.completion_params || { temperature: 0.7 }}
modelId={metadataModelConfig?.name || ''}

View File

@ -32,7 +32,7 @@ import {
getMultipleRetrievalConfig,
getSelectedDatasetsMode,
} from './utils'
import { RETRIEVE_TYPE } from '@/types/app'
import { AppModeEnum, RETRIEVE_TYPE } from '@/types/app'
import { DATASET_DEFAULT } from '@/config'
import type { DataSet } from '@/models/datasets'
import { fetchDatasets } from '@/service/datasets'
@ -344,7 +344,7 @@ const useConfig = (id: string, payload: KnowledgeRetrievalNodeType) => {
draft.metadata_model_config = {
provider: model.provider,
name: model.modelId,
mode: model.mode || 'chat',
mode: model.mode || AppModeEnum.CHAT,
completion_params: draft.metadata_model_config?.completion_params || { temperature: 0.7 },
}
})

View File

@ -1,4 +1,5 @@
// import { RETRIEVAL_OUTPUT_STRUCT } from '../../constants'
import { AppModeEnum } from '@/types/app'
import { BlockEnum, EditionType } from '../../types'
import { type NodeDefault, type PromptItem, PromptRole } from '../../types'
import type { LLMNodeType } from './types'
@ -36,7 +37,7 @@ const nodeDefault: NodeDefault<LLMNodeType> = {
model: {
provider: '',
name: '',
mode: 'chat',
mode: AppModeEnum.CHAT,
completion_params: {
temperature: 0.7,
},
@ -63,7 +64,7 @@ const nodeDefault: NodeDefault<LLMNodeType> = {
errorMessages = t(`${i18nPrefix}.fieldRequired`, { field: t(`${i18nPrefix}.fields.model`) })
if (!errorMessages && !payload.memory) {
const isChatModel = payload.model.mode === 'chat'
const isChatModel = payload.model.mode === AppModeEnum.CHAT
const isPromptEmpty = isChatModel
? !(payload.prompt_template as PromptItem[]).some((t) => {
if (t.edition_type === EditionType.jinja2)
@ -77,14 +78,14 @@ const nodeDefault: NodeDefault<LLMNodeType> = {
}
if (!errorMessages && !!payload.memory) {
const isChatModel = payload.model.mode === 'chat'
const isChatModel = payload.model.mode === AppModeEnum.CHAT
// payload.memory.query_prompt_template not pass is default: {{#sys.query#}}
if (isChatModel && !!payload.memory.query_prompt_template && !payload.memory.query_prompt_template.includes('{{#sys.query#}}'))
errorMessages = t('workflow.nodes.llm.sysQueryInUser')
}
if (!errorMessages) {
const isChatModel = payload.model.mode === 'chat'
const isChatModel = payload.model.mode === AppModeEnum.CHAT
const isShowVars = (() => {
if (isChatModel)
return (payload.prompt_template as PromptItem[]).some(item => item.edition_type === EditionType.jinja2)

View File

@ -18,6 +18,7 @@ import {
import useNodeCrud from '@/app/components/workflow/nodes/_base/hooks/use-node-crud'
import { checkHasContextBlock, checkHasHistoryBlock, checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
import useInspectVarsCrud from '@/app/components/workflow/hooks/use-inspect-vars-crud'
import { AppModeEnum } from '@/types/app'
const useConfig = (id: string, payload: LLMNodeType) => {
const { nodesReadOnly: readOnly } = useNodesReadOnly()
@ -46,7 +47,7 @@ const useConfig = (id: string, payload: LLMNodeType) => {
// model
const model = inputs.model
const modelMode = inputs.model?.mode
const isChatModel = modelMode === 'chat'
const isChatModel = modelMode === AppModeEnum.CHAT
const isCompletionModel = !isChatModel
@ -131,7 +132,7 @@ const useConfig = (id: string, payload: LLMNodeType) => {
draft.model.mode = model.mode!
const isModeChange = model.mode !== inputRef.current.model.mode
if (isModeChange && defaultConfig && Object.keys(defaultConfig).length > 0)
appendDefaultPromptConfig(draft, defaultConfig, model.mode === 'chat')
appendDefaultPromptConfig(draft, defaultConfig, model.mode === AppModeEnum.CHAT)
})
setInputs(newInputs)
setModelChanged(true)

View File

@ -12,6 +12,7 @@ import useConfigVision from '../../hooks/use-config-vision'
import { noop } from 'lodash-es'
import { findVariableWhenOnLLMVision } from '../utils'
import useAvailableVarList from '../_base/hooks/use-available-var-list'
import { AppModeEnum } from '@/types/app'
const i18nPrefix = 'workflow.nodes.llm'
type Params = {
@ -56,7 +57,7 @@ const useSingleRunFormParams = ({
// model
const model = inputs.model
const modelMode = inputs.model?.mode
const isChatModel = modelMode === 'chat'
const isChatModel = modelMode === AppModeEnum.CHAT
const {
isVisionModel,
} = useConfigVision(model, {

View File

@ -3,6 +3,7 @@ import { type ParameterExtractorNodeType, ReasoningModeType } from './types'
import { genNodeMetaData } from '@/app/components/workflow/utils'
import { BlockEnum } from '@/app/components/workflow/types'
import { BlockClassificationEnum } from '@/app/components/workflow/block-selector/types'
import { AppModeEnum } from '@/types/app'
const i18nPrefix = 'workflow'
const metaData = genNodeMetaData({
@ -17,7 +18,7 @@ const nodeDefault: NodeDefault<ParameterExtractorNodeType> = {
model: {
provider: '',
name: '',
mode: 'chat',
mode: AppModeEnum.CHAT,
completion_params: {
temperature: 0.7,
},

View File

@ -17,6 +17,7 @@ import { checkHasQueryBlock } from '@/app/components/base/prompt-editor/constant
import useAvailableVarList from '@/app/components/workflow/nodes/_base/hooks/use-available-var-list'
import { supportFunctionCall } from '@/utils/tool-call'
import useInspectVarsCrud from '../../hooks/use-inspect-vars-crud'
import { AppModeEnum } from '@/types/app'
const useConfig = (id: string, payload: ParameterExtractorNodeType) => {
const {
@ -86,13 +87,13 @@ const useConfig = (id: string, payload: ParameterExtractorNodeType) => {
const model = inputs.model || {
provider: '',
name: '',
mode: 'chat',
mode: AppModeEnum.CHAT,
completion_params: {
temperature: 0.7,
},
}
const modelMode = inputs.model?.mode
const isChatModel = modelMode === 'chat'
const isChatModel = modelMode === AppModeEnum.CHAT
const isCompletionModel = !isChatModel
const {
@ -133,7 +134,7 @@ const useConfig = (id: string, payload: ParameterExtractorNodeType) => {
draft.model.mode = model.mode!
const isModeChange = model.mode !== inputRef.current.model?.mode
if (isModeChange && defaultConfig && Object.keys(defaultConfig).length > 0)
appendDefaultPromptConfig(draft, defaultConfig, model.mode === 'chat')
appendDefaultPromptConfig(draft, defaultConfig, model.mode === AppModeEnum.CHAT)
})
setInputs(newInputs)
setModelChanged(true)

View File

@ -3,6 +3,7 @@ import type { QuestionClassifierNodeType } from './types'
import { genNodeMetaData } from '@/app/components/workflow/utils'
import { BlockEnum } from '@/app/components/workflow/types'
import { BlockClassificationEnum } from '@/app/components/workflow/block-selector/types'
import { AppModeEnum } from '@/types/app'
const i18nPrefix = 'workflow'
@ -18,7 +19,7 @@ const nodeDefault: NodeDefault<QuestionClassifierNodeType> = {
model: {
provider: '',
name: '',
mode: 'chat',
mode: AppModeEnum.CHAT,
completion_params: {
temperature: 0.7,
},

View File

@ -15,6 +15,7 @@ import { useModelListAndDefaultModelAndCurrentProviderAndModel } from '@/app/com
import { ModelTypeEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import { checkHasQueryBlock } from '@/app/components/base/prompt-editor/constants'
import { useUpdateNodeInternals } from 'reactflow'
import { AppModeEnum } from '@/types/app'
const useConfig = (id: string, payload: QuestionClassifierNodeType) => {
const updateNodeInternals = useUpdateNodeInternals()
@ -38,7 +39,7 @@ const useConfig = (id: string, payload: QuestionClassifierNodeType) => {
const model = inputs.model
const modelMode = inputs.model?.mode
const isChatModel = modelMode === 'chat'
const isChatModel = modelMode === AppModeEnum.CHAT
const {
isVisionModel,

View File

@ -22,6 +22,7 @@ import type {
import type { ExternalDataTool } from '@/models/common'
import type { DataSet } from '@/models/datasets'
import type { VisionSettings } from '@/types/app'
import { AppModeEnum } from '@/types/app'
import { ModelModeType, RETRIEVE_TYPE, Resolution, TransferMethod } from '@/types/app'
import { ANNOTATION_DEFAULT, DEFAULT_AGENT_SETTING, DEFAULT_CHAT_PROMPT_CONFIG, DEFAULT_COMPLETION_PROMPT_CONFIG } from '@/config'
import type { FormValue } from '@/app/components/header/account-setting/model-provider-page/declarations'
@ -32,7 +33,7 @@ type IDebugConfiguration = {
appId: string
isAPIKeySet: boolean
isTrailFinished: boolean
mode: string
mode: AppModeEnum
modelModeType: ModelModeType
promptMode: PromptMode
setPromptMode: (promptMode: PromptMode) => void
@ -111,7 +112,7 @@ const DebugConfigurationContext = createContext<IDebugConfiguration>({
appId: '',
isAPIKeySet: false,
isTrailFinished: false,
mode: '',
mode: AppModeEnum.CHAT,
modelModeType: ModelModeType.chat,
promptMode: PromptMode.simple,
setPromptMode: noop,

View File

@ -1,5 +1,5 @@
import type { AliyunConfig, ArizeConfig, LangFuseConfig, LangSmithConfig, OpikConfig, PhoenixConfig, TracingProvider, WeaveConfig } from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type'
import type { App, AppMode, AppTemplate, SiteConfig } from '@/types/app'
import type { App, AppModeEnum, AppTemplate, SiteConfig } from '@/types/app'
import type { Dependency } from '@/app/components/plugins/types'
export enum DSLImportMode {
@ -27,7 +27,7 @@ export type AppDetailResponse = App
export type DSLImportResponse = {
id: string
status: DSLImportStatus
app_mode: AppMode
app_mode: AppModeEnum
app_id?: string
current_dsl_version?: string
imported_dsl_version?: string

View File

@ -1,5 +1,5 @@
import type { DataSourceNotionPage, DataSourceProvider } from './common'
import type { AppIconType, AppMode, RetrievalConfig, TransferMethod } from '@/types/app'
import type { AppIconType, AppModeEnum, RetrievalConfig, TransferMethod } from '@/types/app'
import type { Tag } from '@/app/components/base/tag-management/constant'
import type { IndexingType } from '@/app/components/datasets/create/step-two'
import type { MetadataFilteringVariableType } from '@/app/components/workflow/nodes/knowledge-retrieval/types'
@ -660,7 +660,7 @@ export type ExternalKnowledgeBaseHitTestingResponse = {
export type RelatedApp = {
id: string
name: string
mode: AppMode
mode: AppModeEnum
icon_type: AppIconType | null
icon: string
icon_background: string

View File

@ -1,7 +1,7 @@
import type { AppIconType, AppMode } from '@/types/app'
import type { AppIconType, AppModeEnum } from '@/types/app'
export type AppBasicInfo = {
id: string
mode: AppMode
mode: AppModeEnum
icon_type: AppIconType | null
icon: string
icon_background: string

View File

@ -2,7 +2,7 @@ import type { Fetcher } from 'swr'
import { del, get, patch, post, put } from './base'
import type { ApiKeysListResponse, AppDailyConversationsResponse, AppDailyEndUsersResponse, AppDailyMessagesResponse, AppDetailResponse, AppListResponse, AppStatisticsResponse, AppTemplatesResponse, AppTokenCostsResponse, AppVoicesListResponse, CreateApiKeyResponse, DSLImportMode, DSLImportResponse, GenerationIntroductionResponse, TracingConfig, TracingStatus, UpdateAppModelConfigResponse, UpdateAppSiteCodeResponse, UpdateOpenAIKeyResponse, ValidateOpenAIKeyResponse, WebhookTriggerResponse, WorkflowDailyConversationsResponse } from '@/models/app'
import type { CommonResponse } from '@/models/common'
import type { AppIconType, AppMode, ModelConfig } from '@/types/app'
import type { AppIconType, AppModeEnum, ModelConfig } from '@/types/app'
import type { TracingProvider } from '@/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/type'
export const fetchAppList: Fetcher<AppListResponse, { url: string; params?: Record<string, any> }> = ({ url, params }) => {
@ -22,7 +22,7 @@ export const fetchAppTemplates: Fetcher<AppTemplatesResponse, { url: string }> =
return get<AppTemplatesResponse>(url)
}
export const createApp: Fetcher<AppDetailResponse, { name: string; icon_type?: AppIconType; icon?: string; icon_background?: string; mode: AppMode; description?: string; config?: ModelConfig }> = ({ name, icon_type, icon, icon_background, mode, description, config }) => {
export const createApp: Fetcher<AppDetailResponse, { name: string; icon_type?: AppIconType; icon?: string; icon_background?: string; mode: AppModeEnum; description?: string; config?: ModelConfig }> = ({ name, icon_type, icon, icon_background, mode, description, config }) => {
return post<AppDetailResponse>('apps', { body: { name, icon_type, icon, icon_background, mode, description, model_config: config } })
}
@ -31,7 +31,7 @@ export const updateAppInfo: Fetcher<AppDetailResponse, { appID: string; name: st
return put<AppDetailResponse>(`apps/${appID}`, { body })
}
export const copyApp: Fetcher<AppDetailResponse, { appID: string; name: string; icon_type: AppIconType; icon: string; icon_background?: string | null; mode: AppMode; description?: string }> = ({ appID, name, icon_type, icon, icon_background, mode, description }) => {
export const copyApp: Fetcher<AppDetailResponse, { appID: string; name: string; icon_type: AppIconType; icon: string; icon_background?: string | null; mode: AppModeEnum; description?: string }> = ({ appID, name, icon_type, icon, icon_background, mode, description }) => {
return post<AppDetailResponse>(`apps/${appID}/copy`, { body: { name, icon_type, icon, icon_background, mode, description } })
}

View File

@ -1,14 +1,14 @@
import type { AppMode } from '@/types/app'
import { AppModeEnum } from '@/types/app'
export const getRedirectionPath = (
isCurrentWorkspaceEditor: boolean,
app: { id: string, mode: AppMode },
app: { id: string, mode: AppModeEnum },
) => {
if (!isCurrentWorkspaceEditor) {
return `/app/${app.id}/overview`
}
else {
if (app.mode === 'workflow' || app.mode === 'advanced-chat')
if (app.mode === AppModeEnum.WORKFLOW || app.mode === AppModeEnum.ADVANCED_CHAT)
return `/app/${app.id}/workflow`
else
return `/app/${app.id}/configuration`
@ -17,7 +17,7 @@ export const getRedirectionPath = (
export const getRedirection = (
isCurrentWorkspaceEditor: boolean,
app: { id: string, mode: AppMode },
app: { id: string, mode: AppModeEnum },
redirectionFunc: (href: string) => void,
) => {
const redirectionPath = getRedirectionPath(isCurrentWorkspaceEditor, app)