mirror of
https://github.com/langgenius/dify.git
synced 2026-05-04 01:18:05 +08:00
Merge remote-tracking branch 'origin/main' into feat/trigger
This commit is contained in:
@ -5,7 +5,7 @@ import { useTranslation } from 'react-i18next'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import TracingIcon from './tracing-icon'
|
||||
import ProviderPanel from './provider-panel'
|
||||
import type { AliyunConfig, ArizeConfig, LangFuseConfig, LangSmithConfig, OpikConfig, PhoenixConfig, WeaveConfig } from './type'
|
||||
import type { AliyunConfig, ArizeConfig, LangFuseConfig, LangSmithConfig, OpikConfig, PhoenixConfig, TencentConfig, WeaveConfig } from './type'
|
||||
import { TracingProvider } from './type'
|
||||
import ProviderConfigModal from './provider-config-modal'
|
||||
import Indicator from '@/app/components/header/indicator'
|
||||
@ -30,7 +30,8 @@ export type PopupProps = {
|
||||
opikConfig: OpikConfig | null
|
||||
weaveConfig: WeaveConfig | null
|
||||
aliyunConfig: AliyunConfig | null
|
||||
onConfigUpdated: (provider: TracingProvider, payload: ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig) => void
|
||||
tencentConfig: TencentConfig | null
|
||||
onConfigUpdated: (provider: TracingProvider, payload: ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig | TencentConfig) => void
|
||||
onConfigRemoved: (provider: TracingProvider) => void
|
||||
}
|
||||
|
||||
@ -48,6 +49,7 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
opikConfig,
|
||||
weaveConfig,
|
||||
aliyunConfig,
|
||||
tencentConfig,
|
||||
onConfigUpdated,
|
||||
onConfigRemoved,
|
||||
}) => {
|
||||
@ -81,8 +83,8 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
hideConfigModal()
|
||||
}, [currentProvider, hideConfigModal, onConfigRemoved])
|
||||
|
||||
const providerAllConfigured = arizeConfig && phoenixConfig && langSmithConfig && langFuseConfig && opikConfig && weaveConfig && aliyunConfig
|
||||
const providerAllNotConfigured = !arizeConfig && !phoenixConfig && !langSmithConfig && !langFuseConfig && !opikConfig && !weaveConfig && !aliyunConfig
|
||||
const providerAllConfigured = arizeConfig && phoenixConfig && langSmithConfig && langFuseConfig && opikConfig && weaveConfig && aliyunConfig && tencentConfig
|
||||
const providerAllNotConfigured = !arizeConfig && !phoenixConfig && !langSmithConfig && !langFuseConfig && !opikConfig && !weaveConfig && !aliyunConfig && !tencentConfig
|
||||
|
||||
const switchContent = (
|
||||
<Switch
|
||||
@ -182,6 +184,19 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
key="aliyun-provider-panel"
|
||||
/>
|
||||
)
|
||||
|
||||
const tencentPanel = (
|
||||
<ProviderPanel
|
||||
type={TracingProvider.tencent}
|
||||
readOnly={readOnly}
|
||||
config={tencentConfig}
|
||||
hasConfigured={!!tencentConfig}
|
||||
onConfig={handleOnConfig(TracingProvider.tencent)}
|
||||
isChosen={chosenProvider === TracingProvider.tencent}
|
||||
onChoose={handleOnChoose(TracingProvider.tencent)}
|
||||
key="tencent-provider-panel"
|
||||
/>
|
||||
)
|
||||
const configuredProviderPanel = () => {
|
||||
const configuredPanels: JSX.Element[] = []
|
||||
|
||||
@ -206,6 +221,9 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
if (aliyunConfig)
|
||||
configuredPanels.push(aliyunPanel)
|
||||
|
||||
if (tencentConfig)
|
||||
configuredPanels.push(tencentPanel)
|
||||
|
||||
return configuredPanels
|
||||
}
|
||||
|
||||
@ -233,6 +251,9 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
if (!aliyunConfig)
|
||||
notConfiguredPanels.push(aliyunPanel)
|
||||
|
||||
if (!tencentConfig)
|
||||
notConfiguredPanels.push(tencentPanel)
|
||||
|
||||
return notConfiguredPanels
|
||||
}
|
||||
|
||||
@ -249,6 +270,8 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
return opikConfig
|
||||
if (currentProvider === TracingProvider.aliyun)
|
||||
return aliyunConfig
|
||||
if (currentProvider === TracingProvider.tencent)
|
||||
return tencentConfig
|
||||
return weaveConfig
|
||||
}
|
||||
|
||||
@ -297,6 +320,7 @@ const ConfigPopup: FC<PopupProps> = ({
|
||||
{arizePanel}
|
||||
{phoenixPanel}
|
||||
{aliyunPanel}
|
||||
{tencentPanel}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
@ -8,4 +8,5 @@ export const docURL = {
|
||||
[TracingProvider.opik]: 'https://www.comet.com/docs/opik/tracing/integrations/dify#setup-instructions',
|
||||
[TracingProvider.weave]: 'https://weave-docs.wandb.ai/',
|
||||
[TracingProvider.aliyun]: 'https://help.aliyun.com/zh/arms/tracing-analysis/untitled-document-1750672984680',
|
||||
[TracingProvider.tencent]: 'https://cloud.tencent.com/document/product/248/116531',
|
||||
}
|
||||
|
||||
@ -8,12 +8,12 @@ import {
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { usePathname } from 'next/navigation'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import type { AliyunConfig, ArizeConfig, LangFuseConfig, LangSmithConfig, OpikConfig, PhoenixConfig, WeaveConfig } from './type'
|
||||
import type { AliyunConfig, ArizeConfig, LangFuseConfig, LangSmithConfig, OpikConfig, PhoenixConfig, TencentConfig, WeaveConfig } from './type'
|
||||
import { TracingProvider } from './type'
|
||||
import TracingIcon from './tracing-icon'
|
||||
import ConfigButton from './config-button'
|
||||
import cn from '@/utils/classnames'
|
||||
import { AliyunIcon, ArizeIcon, LangfuseIcon, LangsmithIcon, OpikIcon, PhoenixIcon, WeaveIcon } from '@/app/components/base/icons/src/public/tracing'
|
||||
import { AliyunIcon, ArizeIcon, LangfuseIcon, LangsmithIcon, OpikIcon, PhoenixIcon, TencentIcon, WeaveIcon } from '@/app/components/base/icons/src/public/tracing'
|
||||
import Indicator from '@/app/components/header/indicator'
|
||||
import { fetchTracingConfig as doFetchTracingConfig, fetchTracingStatus, updateTracingStatus } from '@/service/apps'
|
||||
import type { TracingStatus } from '@/models/app'
|
||||
@ -71,6 +71,7 @@ const Panel: FC = () => {
|
||||
[TracingProvider.opik]: OpikIcon,
|
||||
[TracingProvider.weave]: WeaveIcon,
|
||||
[TracingProvider.aliyun]: AliyunIcon,
|
||||
[TracingProvider.tencent]: TencentIcon,
|
||||
}
|
||||
const InUseProviderIcon = inUseTracingProvider ? providerIconMap[inUseTracingProvider] : undefined
|
||||
|
||||
@ -81,7 +82,8 @@ const Panel: FC = () => {
|
||||
const [opikConfig, setOpikConfig] = useState<OpikConfig | null>(null)
|
||||
const [weaveConfig, setWeaveConfig] = useState<WeaveConfig | null>(null)
|
||||
const [aliyunConfig, setAliyunConfig] = useState<AliyunConfig | null>(null)
|
||||
const hasConfiguredTracing = !!(langSmithConfig || langFuseConfig || opikConfig || weaveConfig || arizeConfig || phoenixConfig || aliyunConfig)
|
||||
const [tencentConfig, setTencentConfig] = useState<TencentConfig | null>(null)
|
||||
const hasConfiguredTracing = !!(langSmithConfig || langFuseConfig || opikConfig || weaveConfig || arizeConfig || phoenixConfig || aliyunConfig || tencentConfig)
|
||||
|
||||
const fetchTracingConfig = async () => {
|
||||
const getArizeConfig = async () => {
|
||||
@ -119,6 +121,11 @@ const Panel: FC = () => {
|
||||
if (!aliyunHasNotConfig)
|
||||
setAliyunConfig(aliyunConfig as AliyunConfig)
|
||||
}
|
||||
const getTencentConfig = async () => {
|
||||
const { tracing_config: tencentConfig, has_not_configured: tencentHasNotConfig } = await doFetchTracingConfig({ appId, provider: TracingProvider.tencent })
|
||||
if (!tencentHasNotConfig)
|
||||
setTencentConfig(tencentConfig as TencentConfig)
|
||||
}
|
||||
Promise.all([
|
||||
getArizeConfig(),
|
||||
getPhoenixConfig(),
|
||||
@ -127,6 +134,7 @@ const Panel: FC = () => {
|
||||
getOpikConfig(),
|
||||
getWeaveConfig(),
|
||||
getAliyunConfig(),
|
||||
getTencentConfig(),
|
||||
])
|
||||
}
|
||||
|
||||
@ -147,6 +155,8 @@ const Panel: FC = () => {
|
||||
setWeaveConfig(tracing_config as WeaveConfig)
|
||||
else if (provider === TracingProvider.aliyun)
|
||||
setAliyunConfig(tracing_config as AliyunConfig)
|
||||
else if (provider === TracingProvider.tencent)
|
||||
setTencentConfig(tracing_config as TencentConfig)
|
||||
}
|
||||
|
||||
const handleTracingConfigRemoved = (provider: TracingProvider) => {
|
||||
@ -164,6 +174,8 @@ const Panel: FC = () => {
|
||||
setWeaveConfig(null)
|
||||
else if (provider === TracingProvider.aliyun)
|
||||
setAliyunConfig(null)
|
||||
else if (provider === TracingProvider.tencent)
|
||||
setTencentConfig(null)
|
||||
if (provider === inUseTracingProvider) {
|
||||
handleTracingStatusChange({
|
||||
enabled: false,
|
||||
@ -209,6 +221,7 @@ const Panel: FC = () => {
|
||||
opikConfig={opikConfig}
|
||||
weaveConfig={weaveConfig}
|
||||
aliyunConfig={aliyunConfig}
|
||||
tencentConfig={tencentConfig}
|
||||
onConfigUpdated={handleTracingConfigUpdated}
|
||||
onConfigRemoved={handleTracingConfigRemoved}
|
||||
>
|
||||
@ -245,6 +258,7 @@ const Panel: FC = () => {
|
||||
opikConfig={opikConfig}
|
||||
weaveConfig={weaveConfig}
|
||||
aliyunConfig={aliyunConfig}
|
||||
tencentConfig={tencentConfig}
|
||||
onConfigUpdated={handleTracingConfigUpdated}
|
||||
onConfigRemoved={handleTracingConfigRemoved}
|
||||
>
|
||||
|
||||
@ -4,7 +4,7 @@ import React, { useCallback, useState } from 'react'
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { useBoolean } from 'ahooks'
|
||||
import Field from './field'
|
||||
import type { AliyunConfig, ArizeConfig, LangFuseConfig, LangSmithConfig, OpikConfig, PhoenixConfig, WeaveConfig } from './type'
|
||||
import type { AliyunConfig, ArizeConfig, LangFuseConfig, LangSmithConfig, OpikConfig, PhoenixConfig, TencentConfig, WeaveConfig } from './type'
|
||||
import { TracingProvider } from './type'
|
||||
import { docURL } from './config'
|
||||
import {
|
||||
@ -22,10 +22,10 @@ import Divider from '@/app/components/base/divider'
|
||||
type Props = {
|
||||
appId: string
|
||||
type: TracingProvider
|
||||
payload?: ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig | null
|
||||
payload?: ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig | TencentConfig | null
|
||||
onRemoved: () => void
|
||||
onCancel: () => void
|
||||
onSaved: (payload: ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig) => void
|
||||
onSaved: (payload: ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig | TencentConfig) => void
|
||||
onChosen: (provider: TracingProvider) => void
|
||||
}
|
||||
|
||||
@ -77,6 +77,12 @@ const aliyunConfigTemplate = {
|
||||
endpoint: '',
|
||||
}
|
||||
|
||||
const tencentConfigTemplate = {
|
||||
token: '',
|
||||
endpoint: '',
|
||||
service_name: '',
|
||||
}
|
||||
|
||||
const ProviderConfigModal: FC<Props> = ({
|
||||
appId,
|
||||
type,
|
||||
@ -90,7 +96,7 @@ const ProviderConfigModal: FC<Props> = ({
|
||||
const isEdit = !!payload
|
||||
const isAdd = !isEdit
|
||||
const [isSaving, setIsSaving] = useState(false)
|
||||
const [config, setConfig] = useState<ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig>((() => {
|
||||
const [config, setConfig] = useState<ArizeConfig | PhoenixConfig | LangSmithConfig | LangFuseConfig | OpikConfig | WeaveConfig | AliyunConfig | TencentConfig>((() => {
|
||||
if (isEdit)
|
||||
return payload
|
||||
|
||||
@ -112,6 +118,9 @@ const ProviderConfigModal: FC<Props> = ({
|
||||
else if (type === TracingProvider.aliyun)
|
||||
return aliyunConfigTemplate
|
||||
|
||||
else if (type === TracingProvider.tencent)
|
||||
return tencentConfigTemplate
|
||||
|
||||
return weaveConfigTemplate
|
||||
})())
|
||||
const [isShowRemoveConfirm, {
|
||||
@ -202,6 +211,16 @@ const ProviderConfigModal: FC<Props> = ({
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: 'Endpoint' })
|
||||
}
|
||||
|
||||
if (type === TracingProvider.tencent) {
|
||||
const postData = config as TencentConfig
|
||||
if (!errorMessage && !postData.token)
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: 'Token' })
|
||||
if (!errorMessage && !postData.endpoint)
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: 'Endpoint' })
|
||||
if (!errorMessage && !postData.service_name)
|
||||
errorMessage = t('common.errorMsg.fieldRequired', { field: 'Service Name' })
|
||||
}
|
||||
|
||||
return errorMessage
|
||||
}, [config, t, type])
|
||||
const handleSave = useCallback(async () => {
|
||||
@ -338,6 +357,34 @@ const ProviderConfigModal: FC<Props> = ({
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{type === TracingProvider.tencent && (
|
||||
<>
|
||||
<Field
|
||||
label='Token'
|
||||
labelClassName='!text-sm'
|
||||
isRequired
|
||||
value={(config as TencentConfig).token}
|
||||
onChange={handleConfigChange('token')}
|
||||
placeholder={t(`${I18N_PREFIX}.placeholder`, { key: 'Token' })!}
|
||||
/>
|
||||
<Field
|
||||
label='Endpoint'
|
||||
labelClassName='!text-sm'
|
||||
isRequired
|
||||
value={(config as TencentConfig).endpoint}
|
||||
onChange={handleConfigChange('endpoint')}
|
||||
placeholder='https://your-region.cls.tencentcs.com'
|
||||
/>
|
||||
<Field
|
||||
label='Service Name'
|
||||
labelClassName='!text-sm'
|
||||
isRequired
|
||||
value={(config as TencentConfig).service_name}
|
||||
onChange={handleConfigChange('service_name')}
|
||||
placeholder='dify_app'
|
||||
/>
|
||||
</>
|
||||
)}
|
||||
{type === TracingProvider.weave && (
|
||||
<>
|
||||
<Field
|
||||
|
||||
@ -7,7 +7,7 @@ import {
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { TracingProvider } from './type'
|
||||
import cn from '@/utils/classnames'
|
||||
import { AliyunIconBig, ArizeIconBig, LangfuseIconBig, LangsmithIconBig, OpikIconBig, PhoenixIconBig, WeaveIconBig } from '@/app/components/base/icons/src/public/tracing'
|
||||
import { AliyunIconBig, ArizeIconBig, LangfuseIconBig, LangsmithIconBig, OpikIconBig, PhoenixIconBig, TencentIconBig, WeaveIconBig } from '@/app/components/base/icons/src/public/tracing'
|
||||
import { Eye as View } from '@/app/components/base/icons/src/vender/solid/general'
|
||||
|
||||
const I18N_PREFIX = 'app.tracing'
|
||||
@ -31,6 +31,7 @@ const getIcon = (type: TracingProvider) => {
|
||||
[TracingProvider.opik]: OpikIconBig,
|
||||
[TracingProvider.weave]: WeaveIconBig,
|
||||
[TracingProvider.aliyun]: AliyunIconBig,
|
||||
[TracingProvider.tencent]: TencentIconBig,
|
||||
})[type]
|
||||
}
|
||||
|
||||
|
||||
@ -6,6 +6,7 @@ export enum TracingProvider {
|
||||
opik = 'opik',
|
||||
weave = 'weave',
|
||||
aliyun = 'aliyun',
|
||||
tencent = 'tencent',
|
||||
}
|
||||
|
||||
export type ArizeConfig = {
|
||||
@ -53,3 +54,9 @@ export type AliyunConfig = {
|
||||
license_key: string
|
||||
endpoint: string
|
||||
}
|
||||
|
||||
export type TencentConfig = {
|
||||
token: string
|
||||
endpoint: string
|
||||
service_name: string
|
||||
}
|
||||
|
||||
@ -53,9 +53,6 @@ const ChatWrapper = () => {
|
||||
initUserVariables,
|
||||
} = useChatWithHistoryContext()
|
||||
|
||||
// Semantic variable for better code readability
|
||||
const isHistoryConversation = !!currentConversationId
|
||||
|
||||
const appConfig = useMemo(() => {
|
||||
const config = appParams || {}
|
||||
|
||||
@ -66,9 +63,9 @@ const ChatWrapper = () => {
|
||||
fileUploadConfig: (config as any).system_parameters,
|
||||
},
|
||||
supportFeedback: true,
|
||||
opening_statement: isHistoryConversation ? currentConversationItem?.introduction : (config as any).opening_statement,
|
||||
opening_statement: currentConversationItem?.introduction || (config as any).opening_statement,
|
||||
} as ChatConfig
|
||||
}, [appParams, currentConversationItem?.introduction, isHistoryConversation])
|
||||
}, [appParams, currentConversationItem?.introduction])
|
||||
const {
|
||||
chatList,
|
||||
setTargetMessageId,
|
||||
@ -79,7 +76,7 @@ const ChatWrapper = () => {
|
||||
} = useChat(
|
||||
appConfig,
|
||||
{
|
||||
inputs: (isHistoryConversation ? currentConversationInputs : newConversationInputs) as any,
|
||||
inputs: (currentConversationId ? currentConversationInputs : newConversationInputs) as any,
|
||||
inputsForm: inputsForms,
|
||||
},
|
||||
appPrevChatTree,
|
||||
@ -87,7 +84,7 @@ const ChatWrapper = () => {
|
||||
clearChatList,
|
||||
setClearChatList,
|
||||
)
|
||||
const inputsFormValue = isHistoryConversation ? currentConversationInputs : newConversationInputsRef?.current
|
||||
const inputsFormValue = currentConversationId ? currentConversationInputs : newConversationInputsRef?.current
|
||||
const inputDisabled = useMemo(() => {
|
||||
if (allInputsHidden)
|
||||
return false
|
||||
@ -136,7 +133,7 @@ const ChatWrapper = () => {
|
||||
const data: any = {
|
||||
query: message,
|
||||
files,
|
||||
inputs: formatBooleanInputs(inputsForms, isHistoryConversation ? currentConversationInputs : newConversationInputs),
|
||||
inputs: formatBooleanInputs(inputsForms, currentConversationId ? currentConversationInputs : newConversationInputs),
|
||||
conversation_id: currentConversationId,
|
||||
parent_message_id: (isRegenerate ? parentAnswer?.id : getLastAnswer(chatList)?.id) || null,
|
||||
}
|
||||
@ -146,11 +143,11 @@ const ChatWrapper = () => {
|
||||
data,
|
||||
{
|
||||
onGetSuggestedQuestions: responseItemId => fetchSuggestedQuestions(responseItemId, isInstalledApp, appId),
|
||||
onConversationComplete: isHistoryConversation ? undefined : handleNewConversationCompleted,
|
||||
onConversationComplete: currentConversationId ? undefined : handleNewConversationCompleted,
|
||||
isPublicAPI: !isInstalledApp,
|
||||
},
|
||||
)
|
||||
}, [chatList, handleNewConversationCompleted, handleSend, isHistoryConversation, currentConversationInputs, newConversationInputs, isInstalledApp, appId])
|
||||
}, [chatList, handleNewConversationCompleted, handleSend, currentConversationId, currentConversationInputs, newConversationInputs, isInstalledApp, appId])
|
||||
|
||||
const doRegenerate = useCallback((chatItem: ChatItemInTree, editedQuestion?: { message: string, files?: FileEntity[] }) => {
|
||||
const question = editedQuestion ? chatItem : chatList.find(item => item.id === chatItem.parentMessageId)!
|
||||
@ -163,30 +160,38 @@ const ChatWrapper = () => {
|
||||
}, [chatList, doSend])
|
||||
|
||||
const messageList = useMemo(() => {
|
||||
// Always filter out opening statement from message list as it's handled separately in welcome component
|
||||
if (currentConversationId || chatList.length > 1)
|
||||
return chatList
|
||||
// Without messages we are in the welcome screen, so hide the opening statement from chatlist
|
||||
return chatList.filter(item => !item.isOpeningStatement)
|
||||
}, [chatList])
|
||||
|
||||
const [collapsed, setCollapsed] = useState(isHistoryConversation)
|
||||
const [collapsed, setCollapsed] = useState(!!currentConversationId)
|
||||
|
||||
const chatNode = useMemo(() => {
|
||||
if (allInputsHidden || !inputsForms.length)
|
||||
return null
|
||||
if (isMobile) {
|
||||
if (!isHistoryConversation)
|
||||
if (!currentConversationId)
|
||||
return <InputsForm collapsed={collapsed} setCollapsed={setCollapsed} />
|
||||
return null
|
||||
}
|
||||
else {
|
||||
return <InputsForm collapsed={collapsed} setCollapsed={setCollapsed} />
|
||||
}
|
||||
}, [inputsForms.length, isMobile, isHistoryConversation, collapsed, allInputsHidden])
|
||||
},
|
||||
[
|
||||
inputsForms.length,
|
||||
isMobile,
|
||||
currentConversationId,
|
||||
collapsed, allInputsHidden,
|
||||
])
|
||||
|
||||
const welcome = useMemo(() => {
|
||||
const welcomeMessage = chatList.find(item => item.isOpeningStatement)
|
||||
if (respondingState)
|
||||
return null
|
||||
if (isHistoryConversation)
|
||||
if (currentConversationId)
|
||||
return null
|
||||
if (!welcomeMessage)
|
||||
return null
|
||||
@ -227,7 +232,18 @@ const ChatWrapper = () => {
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
}, [appData?.site.icon, appData?.site.icon_background, appData?.site.icon_type, appData?.site.icon_url, chatList, collapsed, isHistoryConversation, inputsForms.length, respondingState, allInputsHidden])
|
||||
},
|
||||
[
|
||||
appData?.site.icon,
|
||||
appData?.site.icon_background,
|
||||
appData?.site.icon_type,
|
||||
appData?.site.icon_url,
|
||||
chatList, collapsed,
|
||||
currentConversationId,
|
||||
inputsForms.length,
|
||||
respondingState,
|
||||
allInputsHidden,
|
||||
])
|
||||
|
||||
const answerIcon = (appData?.site && appData.site.use_icon_as_answer_icon)
|
||||
? <AnswerIcon
|
||||
@ -251,7 +267,7 @@ const ChatWrapper = () => {
|
||||
chatFooterClassName='pb-4'
|
||||
chatFooterInnerClassName={`mx-auto w-full max-w-[768px] ${isMobile ? 'px-2' : 'px-4'}`}
|
||||
onSend={doSend}
|
||||
inputs={isHistoryConversation ? currentConversationInputs as any : newConversationInputs}
|
||||
inputs={currentConversationId ? currentConversationInputs as any : newConversationInputs}
|
||||
inputsForm={inputsForms}
|
||||
onRegenerate={doRegenerate}
|
||||
onStopResponding={handleStop}
|
||||
|
||||
@ -111,6 +111,8 @@ const Answer: FC<AnswerProps> = ({
|
||||
}
|
||||
}, [switchSibling, item.prevSibling, item.nextSibling])
|
||||
|
||||
const contentIsEmpty = content.trim() === ''
|
||||
|
||||
return (
|
||||
<div className='mb-2 flex last:mb-0'>
|
||||
<div className='relative h-10 w-10 shrink-0'>
|
||||
@ -153,14 +155,14 @@ const Answer: FC<AnswerProps> = ({
|
||||
)
|
||||
}
|
||||
{
|
||||
responding && !content && !hasAgentThoughts && (
|
||||
responding && contentIsEmpty && !hasAgentThoughts && (
|
||||
<div className='flex h-5 w-6 items-center justify-center'>
|
||||
<LoadingAnim type='text' />
|
||||
</div>
|
||||
)
|
||||
}
|
||||
{
|
||||
content && !hasAgentThoughts && (
|
||||
!contentIsEmpty && !hasAgentThoughts && (
|
||||
<BasicContent item={item} />
|
||||
)
|
||||
}
|
||||
|
||||
@ -83,6 +83,15 @@ const ChatInputArea = ({
|
||||
const historyRef = useRef([''])
|
||||
const [currentIndex, setCurrentIndex] = useState(-1)
|
||||
const isComposingRef = useRef(false)
|
||||
|
||||
const handleQueryChange = useCallback(
|
||||
(value: string) => {
|
||||
setQuery(value)
|
||||
setTimeout(handleTextareaResize, 0)
|
||||
},
|
||||
[handleTextareaResize],
|
||||
)
|
||||
|
||||
const handleSend = () => {
|
||||
if (isResponding) {
|
||||
notify({ type: 'info', message: t('appDebug.errorMessage.waitForResponse') })
|
||||
@ -101,7 +110,7 @@ const ChatInputArea = ({
|
||||
}
|
||||
if (checkInputsForm(inputs, inputsForm)) {
|
||||
onSend(query, files)
|
||||
setQuery('')
|
||||
handleQueryChange('')
|
||||
setFiles([])
|
||||
}
|
||||
}
|
||||
@ -131,19 +140,19 @@ const ChatInputArea = ({
|
||||
// When the cmd + up key is pressed, output the previous element
|
||||
if (currentIndex > 0) {
|
||||
setCurrentIndex(currentIndex - 1)
|
||||
setQuery(historyRef.current[currentIndex - 1])
|
||||
handleQueryChange(historyRef.current[currentIndex - 1])
|
||||
}
|
||||
}
|
||||
else if (e.key === 'ArrowDown' && !e.shiftKey && !e.nativeEvent.isComposing && e.metaKey) {
|
||||
// When the cmd + down key is pressed, output the next element
|
||||
if (currentIndex < historyRef.current.length - 1) {
|
||||
setCurrentIndex(currentIndex + 1)
|
||||
setQuery(historyRef.current[currentIndex + 1])
|
||||
handleQueryChange(historyRef.current[currentIndex + 1])
|
||||
}
|
||||
else if (currentIndex === historyRef.current.length - 1) {
|
||||
// If it is the last element, clear the input box
|
||||
setCurrentIndex(historyRef.current.length)
|
||||
setQuery('')
|
||||
handleQueryChange('')
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -171,7 +180,7 @@ const ChatInputArea = ({
|
||||
<>
|
||||
<div
|
||||
className={cn(
|
||||
'relative z-10 rounded-xl border border-components-chat-input-border bg-components-panel-bg-blur pb-[9px] shadow-md',
|
||||
'relative z-10 overflow-hidden rounded-xl border border-components-chat-input-border bg-components-panel-bg-blur pb-[9px] shadow-md',
|
||||
isDragActive && 'border border-dashed border-components-option-card-option-selected-border',
|
||||
disabled && 'pointer-events-none border-components-panel-border opacity-50 shadow-none',
|
||||
)}
|
||||
@ -197,12 +206,8 @@ const ChatInputArea = ({
|
||||
placeholder={t('common.chat.inputPlaceholder', { botName }) || ''}
|
||||
autoFocus
|
||||
minRows={1}
|
||||
onResize={handleTextareaResize}
|
||||
value={query}
|
||||
onChange={(e) => {
|
||||
setQuery(e.target.value)
|
||||
setTimeout(handleTextareaResize, 0)
|
||||
}}
|
||||
onChange={e => handleQueryChange(e.target.value)}
|
||||
onKeyDown={handleKeyDown}
|
||||
onCompositionStart={handleCompositionStart}
|
||||
onCompositionEnd={handleCompositionEnd}
|
||||
@ -221,7 +226,7 @@ const ChatInputArea = ({
|
||||
showVoiceInput && (
|
||||
<VoiceInput
|
||||
onCancel={() => setShowVoiceInput(false)}
|
||||
onConverted={text => setQuery(text)}
|
||||
onConverted={text => handleQueryChange(text)}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
||||
@ -1,3 +1,4 @@
|
||||
import type { FC, Ref } from 'react'
|
||||
import { memo } from 'react'
|
||||
import {
|
||||
RiMicLine,
|
||||
@ -18,20 +19,17 @@ type OperationProps = {
|
||||
speechToTextConfig?: EnableType
|
||||
onShowVoiceInput?: () => void
|
||||
onSend: () => void
|
||||
theme?: Theme | null
|
||||
theme?: Theme | null,
|
||||
ref?: Ref<HTMLDivElement>;
|
||||
}
|
||||
const Operation = (
|
||||
{
|
||||
ref,
|
||||
fileConfig,
|
||||
speechToTextConfig,
|
||||
onShowVoiceInput,
|
||||
onSend,
|
||||
theme,
|
||||
}: OperationProps & {
|
||||
ref: React.RefObject<HTMLDivElement>;
|
||||
},
|
||||
) => {
|
||||
const Operation: FC<OperationProps> = ({
|
||||
ref,
|
||||
fileConfig,
|
||||
speechToTextConfig,
|
||||
onShowVoiceInput,
|
||||
onSend,
|
||||
theme,
|
||||
}) => {
|
||||
return (
|
||||
<div
|
||||
className={cn(
|
||||
|
||||
@ -62,9 +62,9 @@ const ChatWrapper = () => {
|
||||
fileUploadConfig: (config as any).system_parameters,
|
||||
},
|
||||
supportFeedback: true,
|
||||
opening_statement: currentConversationId ? currentConversationItem?.introduction : (config as any).opening_statement,
|
||||
opening_statement: currentConversationItem?.introduction || (config as any).opening_statement,
|
||||
} as ChatConfig
|
||||
}, [appParams, currentConversationItem?.introduction, currentConversationId])
|
||||
}, [appParams, currentConversationItem?.introduction])
|
||||
const {
|
||||
chatList,
|
||||
setTargetMessageId,
|
||||
@ -158,8 +158,9 @@ const ChatWrapper = () => {
|
||||
}, [chatList, doSend])
|
||||
|
||||
const messageList = useMemo(() => {
|
||||
if (currentConversationId)
|
||||
if (currentConversationId || chatList.length > 1)
|
||||
return chatList
|
||||
// Without messages we are in the welcome screen, so hide the opening statement from chatlist
|
||||
return chatList.filter(item => !item.isOpeningStatement)
|
||||
}, [chatList, currentConversationId])
|
||||
|
||||
@ -240,7 +241,7 @@ const ChatWrapper = () => {
|
||||
config={appConfig}
|
||||
chatList={messageList}
|
||||
isResponding={respondingState}
|
||||
chatContainerInnerClassName={cn('mx-auto w-full max-w-full pt-4 tablet:px-4', isMobile && 'px-4')}
|
||||
chatContainerInnerClassName={cn('mx-auto w-full max-w-full px-4', messageList.length && 'pt-4')}
|
||||
chatFooterClassName={cn('pb-4', !isMobile && 'rounded-b-2xl')}
|
||||
chatFooterInnerClassName={cn('mx-auto w-full max-w-full px-4', isMobile && 'px-2')}
|
||||
onSend={doSend}
|
||||
|
||||
@ -36,6 +36,7 @@ const Header: FC<IHeaderProps> = ({
|
||||
appData,
|
||||
currentConversationId,
|
||||
inputsForms,
|
||||
allInputsHidden,
|
||||
} = useEmbeddedChatbotContext()
|
||||
|
||||
const isClient = typeof window !== 'undefined'
|
||||
@ -124,7 +125,7 @@ const Header: FC<IHeaderProps> = ({
|
||||
</ActionButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
{currentConversationId && inputsForms.length > 0 && (
|
||||
{currentConversationId && inputsForms.length > 0 && !allInputsHidden && (
|
||||
<ViewFormDropdown />
|
||||
)}
|
||||
</div>
|
||||
@ -135,7 +136,7 @@ const Header: FC<IHeaderProps> = ({
|
||||
return (
|
||||
<div
|
||||
className={cn('flex h-14 shrink-0 items-center justify-between rounded-t-2xl px-3')}
|
||||
style={Object.assign({}, CssTransform(theme?.backgroundHeaderColorStyle ?? ''), CssTransform(theme?.headerBorderBottomStyle ?? ''))}
|
||||
style={CssTransform(theme?.headerBorderBottomStyle ?? '')}
|
||||
>
|
||||
<div className="flex grow items-center space-x-3">
|
||||
{customerIcon}
|
||||
@ -171,7 +172,7 @@ const Header: FC<IHeaderProps> = ({
|
||||
</ActionButton>
|
||||
</Tooltip>
|
||||
)}
|
||||
{currentConversationId && inputsForms.length > 0 && (
|
||||
{currentConversationId && inputsForms.length > 0 && !allInputsHidden && (
|
||||
<ViewFormDropdown iconColor={theme?.colorPathOnHeader} />
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -49,8 +49,8 @@ const Chatbot = () => {
|
||||
<div className='relative'>
|
||||
<div
|
||||
className={cn(
|
||||
'flex flex-col rounded-2xl border border-components-panel-border-subtle',
|
||||
isMobile ? 'h-[calc(100vh_-_60px)] border-[0.5px] border-components-panel-border shadow-xs' : 'h-[100vh] bg-chatbot-bg',
|
||||
'flex flex-col rounded-2xl',
|
||||
isMobile ? 'h-[calc(100vh_-_60px)] shadow-xs' : 'h-[100vh] bg-chatbot-bg',
|
||||
)}
|
||||
style={isMobile ? Object.assign({}, CssTransform(themeBuilder?.theme?.backgroundHeaderColorStyle ?? '')) : {}}
|
||||
>
|
||||
@ -62,7 +62,7 @@ const Chatbot = () => {
|
||||
theme={themeBuilder?.theme}
|
||||
onCreateNewChat={handleNewConversation}
|
||||
/>
|
||||
<div className={cn('flex grow flex-col overflow-y-auto', isMobile && '!h-[calc(100vh_-_3rem)] rounded-2xl bg-chatbot-bg')}>
|
||||
<div className={cn('flex grow flex-col overflow-y-auto', isMobile && 'm-[0.5px] !h-[calc(100vh_-_3rem)] rounded-2xl bg-chatbot-bg')}>
|
||||
{appChatListDataLoading && (
|
||||
<Loading type='app' />
|
||||
)}
|
||||
|
||||
@ -1,13 +0,0 @@
|
||||
export { default as Chunk } from './Chunk'
|
||||
export { default as Collapse } from './Collapse'
|
||||
export { default as Divider } from './Divider'
|
||||
export { default as File } from './File'
|
||||
export { default as GeneralType } from './GeneralType'
|
||||
export { default as LayoutRight2LineMod } from './LayoutRight2LineMod'
|
||||
export { default as OptionCardEffectBlueLight } from './OptionCardEffectBlueLight'
|
||||
export { default as OptionCardEffectBlue } from './OptionCardEffectBlue'
|
||||
export { default as OptionCardEffectOrange } from './OptionCardEffectOrange'
|
||||
export { default as OptionCardEffectPurple } from './OptionCardEffectPurple'
|
||||
export { default as ParentChildType } from './ParentChildType'
|
||||
export { default as SelectionMod } from './SelectionMod'
|
||||
export { default as Watercrawl } from './Watercrawl'
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/baichuan-text-cn.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './BaichuanTextCn.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'BaichuanTextCn'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/minimax.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './Minimax.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'Minimax'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/minimax-text.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './MinimaxText.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'MinimaxText'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/tongyi.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './Tongyi.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'Tongyi'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/tongyi-text.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './TongyiText.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'TongyiText'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/tongyi-text-cn.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './TongyiTextCn.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'TongyiTextCn'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/wxyy.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './Wxyy.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'Wxyy'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/wxyy-text.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './WxyyText.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'WxyyText'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +0,0 @@
|
||||
.wrapper {
|
||||
display: inline-flex;
|
||||
background: url(~@/app/components/base/icons/assets/image/llm/wxyy-text-cn.png) center center no-repeat;
|
||||
background-size: contain;
|
||||
}
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import cn from '@/utils/classnames'
|
||||
import s from './WxyyTextCn.module.css'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
className,
|
||||
...restProps
|
||||
}: React.DetailedHTMLProps<React.HTMLAttributes<HTMLSpanElement>, HTMLSpanElement> & {
|
||||
ref?: React.RefObject<HTMLSpanElement>;
|
||||
},
|
||||
) => <span className={cn(s.wrapper, className)} {...restProps} ref={ref} />
|
||||
|
||||
Icon.displayName = 'WxyyTextCn'
|
||||
|
||||
export default Icon
|
||||
@ -1,9 +0,0 @@
|
||||
export { default as BaichuanTextCn } from './BaichuanTextCn'
|
||||
export { default as MinimaxText } from './MinimaxText'
|
||||
export { default as Minimax } from './Minimax'
|
||||
export { default as TongyiTextCn } from './TongyiTextCn'
|
||||
export { default as TongyiText } from './TongyiText'
|
||||
export { default as Tongyi } from './Tongyi'
|
||||
export { default as WxyyTextCn } from './WxyyTextCn'
|
||||
export { default as WxyyText } from './WxyyText'
|
||||
export { default as Wxyy } from './Wxyy'
|
||||
@ -1 +0,0 @@
|
||||
export { default as Checked } from './Checked'
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './WebReader.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'WebReader'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Wikipedia.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Wikipedia'
|
||||
|
||||
export default Icon
|
||||
@ -1,7 +0,0 @@
|
||||
export { default as Google } from './Google'
|
||||
export { default as PartnerDark } from './PartnerDark'
|
||||
export { default as PartnerLight } from './PartnerLight'
|
||||
export { default as VerifiedDark } from './VerifiedDark'
|
||||
export { default as VerifiedLight } from './VerifiedLight'
|
||||
export { default as WebReader } from './WebReader'
|
||||
export { default as Wikipedia } from './Wikipedia'
|
||||
@ -18,3 +18,4 @@ const Icon = (
|
||||
Icon.displayName = 'DataSet'
|
||||
|
||||
export default Icon
|
||||
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Loading.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Loading'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Search.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Search'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './ThoughtList.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'ThoughtList'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './WebReader.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'WebReader'
|
||||
|
||||
export default Icon
|
||||
@ -1,5 +1,2 @@
|
||||
export { default as DataSet } from './DataSet'
|
||||
export { default as Loading } from './Loading'
|
||||
export { default as Search } from './Search'
|
||||
export { default as ThoughtList } from './ThoughtList'
|
||||
export { default as WebReader } from './WebReader'
|
||||
|
||||
|
||||
@ -0,0 +1,170 @@
|
||||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"width": "80px",
|
||||
"height": "18px",
|
||||
"viewBox": "0 0 80 18",
|
||||
"version": "1.1"
|
||||
},
|
||||
"isRootNode": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "title",
|
||||
"attributes": {},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "页面-1",
|
||||
"stroke": "none",
|
||||
"stroke-width": "1",
|
||||
"fill": "none",
|
||||
"fill-rule": "evenodd"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "logo",
|
||||
"fill-rule": "nonzero"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "XMLID_25_",
|
||||
"transform": "translate(30.592488, 1.100000)",
|
||||
"fill": "#253554"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M30.8788968,0.6 L21.8088578,0.6 L21.8088578,1.9 L24.5604427,1.9 L24.5604427,6.7 L21.2993051,6.7 L21.2993051,8 L24.5604427,8 L24.5604427,15.9 L26.089101,15.9 L26.089101,8 L29.5540597,8 L29.5540597,15.6 L32.3056445,15.6 L32.3056445,14.3 L31.0827179,14.3 L31.0827179,0.6 L30.8788968,0.6 Z M25.9871904,6.5 L25.9871904,1.9 L29.5540597,1.9 L29.5540597,6.7 L26.089101,6.7 L26.089101,6.5 L25.9871904,6.5 Z",
|
||||
"id": "XMLID_38_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "polygon",
|
||||
"attributes": {
|
||||
"id": "XMLID_14_",
|
||||
"points": "5.60508028 12.2 12.8407294 12.2 12.8407294 13.5 5.60508028 13.5"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M0.611463304,9.8 C0.611463304,12.1 0.509552753,14 0,15.5 C0,15.6 0,15.6 0.101910551,15.6 C0.101910551,15.6 1.22292661,15.6 1.42674771,15.6 C1.93630046,13.4 1.93630046,11.6 1.93630046,10.3 L3.77069037,10.3 L3.77069037,14.3 L2.54776377,14.3 C2.44585321,14.3 2.44585321,14.3 2.44585321,14.4 L2.85349542,15.6 L5.19743808,15.6 L5.19743808,0.6 L0.713373854,0.6 L0.611463304,9.8 L0.611463304,9.8 Z M2.03821101,9.2 L2.03821101,6.2 L3.87260092,6.2 L3.87260092,9.4 L2.03821101,9.4 L2.03821101,9.2 Z M3.87260092,1.9 L3.87260092,5 L2.03821101,5 L2.03821101,1.9 L3.87260092,1.9 Z",
|
||||
"id": "XMLID_33_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M13.3502821,5.9 L15.0827615,5.9 L15.0827615,4.7 L9.88532341,4.7 C9.98723396,4.3 10.0891445,3.8 10.3948762,3.5 L14.8789404,3.5 L14.8789404,2.3 L13.6560138,2.3 C13.7579243,1.6 14.1655665,0.7 14.1655665,0.7 C14.1655665,0.6 14.1655665,0.6 14.063656,0.6 L12.9426399,0.6 L12.4330872,2.3 L10.8025184,2.3 C10.9044289,1.6 11.0063395,0.8 11.2101606,0.1 C11.2101606,0 11.2101606,0 11.10825,0 C11.0063395,0 10.1910551,0 9.88532341,0 C9.78341286,0.9 9.68150231,1.7 9.37577066,2.4 L8.4585757,2.4 L7.94902295,0.7 L6.82800689,0.7 C6.72609634,0.7 6.72609634,0.7 6.72609634,0.8 C6.72609634,0.9 6.92991744,1.7 7.23564909,2.4 L6.01272249,2.4 L6.01272249,3.6 L8.8662179,3.6 C8.76430735,4 8.6623968,4.5 8.35666515,4.8 L5.60508028,4.8 L5.60508028,6 L7.74520185,6 C6.82800689,7.2 6.01272249,7.7 5.60508028,8 C5.60508028,8.1 5.60508028,9.3 5.60508028,9.3 C5.60508028,9.4 5.70699083,9.4 5.80890138,9.3 C6.21654359,9.2 6.72609634,8.8 7.03182799,8.4 L12.025445,8.4 L12.025445,10.2 L8.15284405,10.2 L8.2547546,9.1 C8.2547546,9 8.2547546,9 8.15284405,9 C8.0509335,9 6.92991744,9 6.92991744,9 L6.82800689,11.2 C6.82800689,11.3 6.82800689,11.3 6.92991744,11.3 C7.03182799,11.3 13.6560138,11.3 13.6560138,11.3 L13.6560138,14.5 L10.7006078,14.5 C10.5986973,14.5 10.5986973,14.5 10.5986973,14.6 L11.0063395,15.8 L15.2865826,15.8 L15.2865826,10.2 L13.6560138,10.2 L13.6560138,7.8 C14.2674771,8.3 14.8789404,8.8 15.4904037,9 C15.5923142,9.1 15.6942248,9.1 15.6942248,9 C15.6942248,9 15.6942248,7.8 15.6942248,7.7 C15.0827615,7.5 14.1655665,7 13.3502821,5.9 Z M11.7197133,5.9 C11.9235344,6.4 12.3311766,6.9 12.7388188,7.2 L8.35666515,7.2 C8.76430735,6.8 8.96812845,6.3 9.37577066,5.9 L11.7197133,5.9 L11.7197133,5.9 Z",
|
||||
"id": "XMLID_30_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M22.6241422,11.3 C22.6241422,11.3 21.4012156,12.2 20.178289,13.1 L20.178289,4.7 L16.9171514,4.7 L16.9171514,6.2 L18.7515413,6.2 L18.7515413,14.3 C18.2419886,14.7 17.8343464,14.8 17.8343464,14.8 L18.7515413,15.9 L22.7260528,13 L22.6241422,11.3 C22.9298739,11.3 22.8279633,11.2 22.6241422,11.3 Z",
|
||||
"id": "XMLID_8_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M18.9553624,3.4 L20.3821101,3.4 C20.5859312,3.4 20.5859312,3.3 20.5859312,3.3 L18.5477202,0.2 L17.019062,0.2 L16.9171514,0.3 C17.019062,0.4 18.9553624,3.4 18.9553624,3.4 Z",
|
||||
"id": "XMLID_7_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "rect",
|
||||
"attributes": {
|
||||
"id": "XMLID_6_",
|
||||
"x": "35.2610505",
|
||||
"y": "0.9",
|
||||
"width": "11.4139817",
|
||||
"height": "1.5"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M39.4393831,7.8 L48.4075115,7.8 L48.4075115,6.3 L33.6304817,6.3 L33.6304817,7.8 L37.7069037,7.8 C36.7897088,10 34.8534083,15.4 34.7514978,15.5 C34.7514978,15.6 34.7514978,15.6 34.8534083,15.6 L47.5922271,15.6 C47.6941377,15.6 47.6941377,15.5 47.6941377,15.5 L45.8597478,10.6 L44.3310895,10.6 C44.229179,10.6 44.229179,10.7 44.229179,10.7 C44.229179,10.8 45.5540161,14.2 45.5540161,14.2 L37.197351,14.2 L39.4393831,7.8 Z",
|
||||
"id": "XMLID_5_"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "XMLID_19_"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M22.5,14.7 C22.1,15.1 21.3,15.7 19.9,15.7 C19.3,15.7 18.6,15.7 18.3,15.7 C17.9,15.7 14.9,15.7 11.3,15.7 C13.9,13.2 16.1,11.1 16.3,10.9 C16.5,10.7 17,10.2 17.5,9.8 C18.5,8.9 19.3,8.8 20,8.8 C21,8.8 21.8,9.2 22.5,9.8 C23.9,11.1 23.9,13.4 22.5,14.7 M24.2,8.2 C23.2,7.1 21.7,6.4 20.1,6.4 C18.7,6.4 17.5,6.9 16.4,7.7 C16,8.1 15.4,8.5 14.9,9.1 C14.5,9.5 5.9,17.9 5.9,17.9 C6.4,18 7,18 7.5,18 C8,18 18,18 18.4,18 C19.2,18 19.8,18 20.4,17.9 C21.7,17.8 23,17.3 24.1,16.3 C26.4,14.1 26.4,10.4 24.2,8.2 Z",
|
||||
"id": "XMLID_22_",
|
||||
"fill": "#00A3FF"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M10.2,7.6 C9.1,6.8 8,6.4 6.7,6.4 C5.1,6.4 3.6,7.1 2.6,8.2 C0.4,10.5 0.4,14.1 2.7,16.4 C3.7,17.3 4.7,17.8 5.9,17.9 L8.2,15.7 C7.8,15.7 7.3,15.7 6.9,15.7 C5.6,15.6 4.8,15.2 4.3,14.7 C2.9,13.3 2.9,11.1 4.2,9.7 C4.9,9 5.7,8.7 6.7,8.7 C7.3,8.7 8.2,8.8 9.1,9.7 C9.5,10.1 10.6,10.9 11,11.3 L11.1,11.3 L12.6,9.8 L12.6,9.7 C11.9,9 10.8,8.1 10.2,7.6",
|
||||
"id": "XMLID_2_",
|
||||
"fill": "#00C8DC"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M20.7,5.1 C19.6,2.1 16.7,0 13.4,0 C9.5,0 6.4,2.9 5.8,6.5 C6.1,6.5 6.4,6.4 6.8,6.4 C7.2,6.4 7.7,6.5 8.1,6.5 L8.1,6.5 C8.6,4 10.8,2.2 13.4,2.2 C15.6,2.2 17.5,3.5 18.4,5.4 C18.4,5.4 18.5,5.5 18.5,5.4 C19.2,5.3 20,5.1 20.7,5.1 C20.7,5.2 20.7,5.2 20.7,5.1",
|
||||
"id": "XMLID_1_",
|
||||
"fill": "#006EFF"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "TencentIcon"
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Checked.json'
|
||||
import data from './TencentIcon.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
@ -15,6 +15,6 @@ const Icon = (
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Checked'
|
||||
Icon.displayName = 'TencentIcon'
|
||||
|
||||
export default Icon
|
||||
@ -0,0 +1,170 @@
|
||||
{
|
||||
"icon": {
|
||||
"type": "element",
|
||||
"name": "svg",
|
||||
"attributes": {
|
||||
"width": "80px",
|
||||
"height": "18px",
|
||||
"viewBox": "0 0 80 18",
|
||||
"version": "1.1"
|
||||
},
|
||||
"isRootNode": true,
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "title",
|
||||
"attributes": {},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "页面-1",
|
||||
"stroke": "none",
|
||||
"stroke-width": "1",
|
||||
"fill": "none",
|
||||
"fill-rule": "evenodd"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "logo",
|
||||
"fill-rule": "nonzero"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "XMLID_25_",
|
||||
"transform": "translate(30.592488, 1.100000)",
|
||||
"fill": "#253554"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M30.8788968,0.6 L21.8088578,0.6 L21.8088578,1.9 L24.5604427,1.9 L24.5604427,6.7 L21.2993051,6.7 L21.2993051,8 L24.5604427,8 L24.5604427,15.9 L26.089101,15.9 L26.089101,8 L29.5540597,8 L29.5540597,15.6 L32.3056445,15.6 L32.3056445,14.3 L31.0827179,14.3 L31.0827179,0.6 L30.8788968,0.6 Z M25.9871904,6.5 L25.9871904,1.9 L29.5540597,1.9 L29.5540597,6.7 L26.089101,6.7 L26.089101,6.5 L25.9871904,6.5 Z",
|
||||
"id": "XMLID_38_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "polygon",
|
||||
"attributes": {
|
||||
"id": "XMLID_14_",
|
||||
"points": "5.60508028 12.2 12.8407294 12.2 12.8407294 13.5 5.60508028 13.5"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M0.611463304,9.8 C0.611463304,12.1 0.509552753,14 0,15.5 C0,15.6 0,15.6 0.101910551,15.6 C0.101910551,15.6 1.22292661,15.6 1.42674771,15.6 C1.93630046,13.4 1.93630046,11.6 1.93630046,10.3 L3.77069037,10.3 L3.77069037,14.3 L2.54776377,14.3 C2.44585321,14.3 2.44585321,14.3 2.44585321,14.4 L2.85349542,15.6 L5.19743808,15.6 L5.19743808,0.6 L0.713373854,0.6 L0.611463304,9.8 L0.611463304,9.8 Z M2.03821101,9.2 L2.03821101,6.2 L3.87260092,6.2 L3.87260092,9.4 L2.03821101,9.4 L2.03821101,9.2 Z M3.87260092,1.9 L3.87260092,5 L2.03821101,5 L2.03821101,1.9 L3.87260092,1.9 Z",
|
||||
"id": "XMLID_33_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M13.3502821,5.9 L15.0827615,5.9 L15.0827615,4.7 L9.88532341,4.7 C9.98723396,4.3 10.0891445,3.8 10.3948762,3.5 L14.8789404,3.5 L14.8789404,2.3 L13.6560138,2.3 C13.7579243,1.6 14.1655665,0.7 14.1655665,0.7 C14.1655665,0.6 14.1655665,0.6 14.063656,0.6 L12.9426399,0.6 L12.4330872,2.3 L10.8025184,2.3 C10.9044289,1.6 11.0063395,0.8 11.2101606,0.1 C11.2101606,0 11.2101606,0 11.10825,0 C11.0063395,0 10.1910551,0 9.88532341,0 C9.78341286,0.9 9.68150231,1.7 9.37577066,2.4 L8.4585757,2.4 L7.94902295,0.7 L6.82800689,0.7 C6.72609634,0.7 6.72609634,0.7 6.72609634,0.8 C6.72609634,0.9 6.92991744,1.7 7.23564909,2.4 L6.01272249,2.4 L6.01272249,3.6 L8.8662179,3.6 C8.76430735,4 8.6623968,4.5 8.35666515,4.8 L5.60508028,4.8 L5.60508028,6 L7.74520185,6 C6.82800689,7.2 6.01272249,7.7 5.60508028,8 C5.60508028,8.1 5.60508028,9.3 5.60508028,9.3 C5.60508028,9.4 5.70699083,9.4 5.80890138,9.3 C6.21654359,9.2 6.72609634,8.8 7.03182799,8.4 L12.025445,8.4 L12.025445,10.2 L8.15284405,10.2 L8.2547546,9.1 C8.2547546,9 8.2547546,9 8.15284405,9 C8.0509335,9 6.92991744,9 6.92991744,9 L6.82800689,11.2 C6.82800689,11.3 6.82800689,11.3 6.92991744,11.3 C7.03182799,11.3 13.6560138,11.3 13.6560138,11.3 L13.6560138,14.5 L10.7006078,14.5 C10.5986973,14.5 10.5986973,14.5 10.5986973,14.6 L11.0063395,15.8 L15.2865826,15.8 L15.2865826,10.2 L13.6560138,10.2 L13.6560138,7.8 C14.2674771,8.3 14.8789404,8.8 15.4904037,9 C15.5923142,9.1 15.6942248,9.1 15.6942248,9 C15.6942248,9 15.6942248,7.8 15.6942248,7.7 C15.0827615,7.5 14.1655665,7 13.3502821,5.9 Z M11.7197133,5.9 C11.9235344,6.4 12.3311766,6.9 12.7388188,7.2 L8.35666515,7.2 C8.76430735,6.8 8.96812845,6.3 9.37577066,5.9 L11.7197133,5.9 L11.7197133,5.9 Z",
|
||||
"id": "XMLID_30_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M22.6241422,11.3 C22.6241422,11.3 21.4012156,12.2 20.178289,13.1 L20.178289,4.7 L16.9171514,4.7 L16.9171514,6.2 L18.7515413,6.2 L18.7515413,14.3 C18.2419886,14.7 17.8343464,14.8 17.8343464,14.8 L18.7515413,15.9 L22.7260528,13 L22.6241422,11.3 C22.9298739,11.3 22.8279633,11.2 22.6241422,11.3 Z",
|
||||
"id": "XMLID_8_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M18.9553624,3.4 L20.3821101,3.4 C20.5859312,3.4 20.5859312,3.3 20.5859312,3.3 L18.5477202,0.2 L17.019062,0.2 L16.9171514,0.3 C17.019062,0.4 18.9553624,3.4 18.9553624,3.4 Z",
|
||||
"id": "XMLID_7_"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "rect",
|
||||
"attributes": {
|
||||
"id": "XMLID_6_",
|
||||
"x": "35.2610505",
|
||||
"y": "0.9",
|
||||
"width": "11.4139817",
|
||||
"height": "1.5"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M39.4393831,7.8 L48.4075115,7.8 L48.4075115,6.3 L33.6304817,6.3 L33.6304817,7.8 L37.7069037,7.8 C36.7897088,10 34.8534083,15.4 34.7514978,15.5 C34.7514978,15.6 34.7514978,15.6 34.8534083,15.6 L47.5922271,15.6 C47.6941377,15.6 47.6941377,15.5 47.6941377,15.5 L45.8597478,10.6 L44.3310895,10.6 C44.229179,10.6 44.229179,10.7 44.229179,10.7 C44.229179,10.8 45.5540161,14.2 45.5540161,14.2 L37.197351,14.2 L39.4393831,7.8 Z",
|
||||
"id": "XMLID_5_"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "g",
|
||||
"attributes": {
|
||||
"id": "XMLID_19_"
|
||||
},
|
||||
"children": [
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M22.5,14.7 C22.1,15.1 21.3,15.7 19.9,15.7 C19.3,15.7 18.6,15.7 18.3,15.7 C17.9,15.7 14.9,15.7 11.3,15.7 C13.9,13.2 16.1,11.1 16.3,10.9 C16.5,10.7 17,10.2 17.5,9.8 C18.5,8.9 19.3,8.8 20,8.8 C21,8.8 21.8,9.2 22.5,9.8 C23.9,11.1 23.9,13.4 22.5,14.7 M24.2,8.2 C23.2,7.1 21.7,6.4 20.1,6.4 C18.7,6.4 17.5,6.9 16.4,7.7 C16,8.1 15.4,8.5 14.9,9.1 C14.5,9.5 5.9,17.9 5.9,17.9 C6.4,18 7,18 7.5,18 C8,18 18,18 18.4,18 C19.2,18 19.8,18 20.4,17.9 C21.7,17.8 23,17.3 24.1,16.3 C26.4,14.1 26.4,10.4 24.2,8.2 Z",
|
||||
"id": "XMLID_22_",
|
||||
"fill": "#00A3FF"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M10.2,7.6 C9.1,6.8 8,6.4 6.7,6.4 C5.1,6.4 3.6,7.1 2.6,8.2 C0.4,10.5 0.4,14.1 2.7,16.4 C3.7,17.3 4.7,17.8 5.9,17.9 L8.2,15.7 C7.8,15.7 7.3,15.7 6.9,15.7 C5.6,15.6 4.8,15.2 4.3,14.7 C2.9,13.3 2.9,11.1 4.2,9.7 C4.9,9 5.7,8.7 6.7,8.7 C7.3,8.7 8.2,8.8 9.1,9.7 C9.5,10.1 10.6,10.9 11,11.3 L11.1,11.3 L12.6,9.8 L12.6,9.7 C11.9,9 10.8,8.1 10.2,7.6",
|
||||
"id": "XMLID_2_",
|
||||
"fill": "#00C8DC"
|
||||
},
|
||||
"children": []
|
||||
},
|
||||
{
|
||||
"type": "element",
|
||||
"name": "path",
|
||||
"attributes": {
|
||||
"d": "M20.7,5.1 C19.6,2.1 16.7,0 13.4,0 C9.5,0 6.4,2.9 5.8,6.5 C6.1,6.5 6.4,6.4 6.8,6.4 C7.2,6.4 7.7,6.5 8.1,6.5 L8.1,6.5 C8.6,4 10.8,2.2 13.4,2.2 C15.6,2.2 17.5,3.5 18.4,5.4 C18.4,5.4 18.5,5.5 18.5,5.4 C19.2,5.3 20,5.1 20.7,5.1 C20.7,5.2 20.7,5.2 20.7,5.1",
|
||||
"id": "XMLID_1_",
|
||||
"fill": "#006EFF"
|
||||
},
|
||||
"children": []
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
},
|
||||
"name": "TencentIconBig"
|
||||
}
|
||||
@ -2,7 +2,7 @@
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Google.json'
|
||||
import data from './TencentIconBig.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
@ -15,6 +15,6 @@ const Icon = (
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Google'
|
||||
Icon.displayName = 'TencentIconBig'
|
||||
|
||||
export default Icon
|
||||
@ -10,6 +10,8 @@ export { default as OpikIconBig } from './OpikIconBig'
|
||||
export { default as OpikIcon } from './OpikIcon'
|
||||
export { default as PhoenixIconBig } from './PhoenixIconBig'
|
||||
export { default as PhoenixIcon } from './PhoenixIcon'
|
||||
export { default as TencentIconBig } from './TencentIconBig'
|
||||
export { default as TencentIcon } from './TencentIcon'
|
||||
export { default as TracingIcon } from './TracingIcon'
|
||||
export { default as WeaveIconBig } from './WeaveIconBig'
|
||||
export { default as WeaveIcon } from './WeaveIcon'
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './AlignLeft01.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'AlignLeft01'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './AlignRight01.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'AlignRight01'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Grid01.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Grid01'
|
||||
|
||||
export default Icon
|
||||
@ -1,4 +1 @@
|
||||
export { default as AlignLeft01 } from './AlignLeft01'
|
||||
export { default as AlignRight01 } from './AlignRight01'
|
||||
export { default as Grid01 } from './Grid01'
|
||||
export { default as LayoutGrid02 } from './LayoutGrid02'
|
||||
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Route.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Route'
|
||||
|
||||
export default Icon
|
||||
@ -1 +0,0 @@
|
||||
export { default as Route } from './Route'
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './User01.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'User01'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Users01.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Users01'
|
||||
|
||||
export default Icon
|
||||
@ -1,2 +0,0 @@
|
||||
export { default as User01 } from './User01'
|
||||
export { default as Users01 } from './Users01'
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Stars02.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Stars02'
|
||||
|
||||
export default Icon
|
||||
@ -1 +0,0 @@
|
||||
export { default as Stars02 } from './Stars02'
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './ChevronDown.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'ChevronDown'
|
||||
|
||||
export default Icon
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './HighPriority.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'HighPriority'
|
||||
|
||||
export default Icon
|
||||
@ -1,2 +0,0 @@
|
||||
export { default as ChevronDown } from './ChevronDown'
|
||||
export { default as HighPriority } from './HighPriority'
|
||||
@ -1,20 +0,0 @@
|
||||
// GENERATE BY script
|
||||
// DON NOT EDIT IT MANUALLY
|
||||
|
||||
import * as React from 'react'
|
||||
import data from './Grid01.json'
|
||||
import IconBase from '@/app/components/base/icons/IconBase'
|
||||
import type { IconData } from '@/app/components/base/icons/IconBase'
|
||||
|
||||
const Icon = (
|
||||
{
|
||||
ref,
|
||||
...props
|
||||
}: React.SVGProps<SVGSVGElement> & {
|
||||
ref?: React.RefObject<React.RefObject<HTMLOrSVGElement>>;
|
||||
},
|
||||
) => <IconBase {...props} ref={ref} data={data as IconData} />
|
||||
|
||||
Icon.displayName = 'Grid01'
|
||||
|
||||
export default Icon
|
||||
@ -1 +0,0 @@
|
||||
export { default as Grid01 } from './Grid01'
|
||||
@ -767,8 +767,8 @@ The text generation application offers non-session support and is ideal for tran
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -764,8 +764,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -728,8 +728,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -199,7 +199,7 @@ Chat applications support session persistence, allowing previous chat history to
|
||||
--header 'Authorization: Bearer {api_key}' \\
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data-raw '{
|
||||
"inputs": ${JSON.stringify(props.inputs)},
|
||||
"inputs": ${JSON.stringify(props.inputs)},
|
||||
"query": "What are the specs of the iPhone 13 Pro Max?",
|
||||
"response_mode": "streaming",
|
||||
"conversation_id": "",
|
||||
@ -1182,7 +1182,7 @@ Chat applications support session persistence, allowing previous chat history to
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data-raw '{
|
||||
"value": "Updated Value",
|
||||
"user": "abc-123"
|
||||
"user": "abc-123"
|
||||
}'`}
|
||||
/>
|
||||
|
||||
@ -1599,8 +1599,8 @@ Chat applications support session persistence, allowing previous chat history to
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -1586,8 +1586,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="リクエスト"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -1188,7 +1188,7 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data-raw '{
|
||||
"value": "Updated Value",
|
||||
"user": "abc-123"
|
||||
"user": "abc-123"
|
||||
}'`}
|
||||
/>
|
||||
|
||||
@ -1579,8 +1579,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty } from '../md.tsx'
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -1025,8 +1025,8 @@ Workflow applications offers non-session support and is ideal for translation, a
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -1021,8 +1021,8 @@ import { Row, Col, Properties, Property, Heading, SubProperty, Paragraph } from
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -182,7 +182,7 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
|
||||
--header 'Authorization: Bearer {api_key}' \\
|
||||
--header 'Content-Type: application/json' \\
|
||||
--data-raw '{
|
||||
"inputs": ${JSON.stringify(props.inputs)},
|
||||
"inputs": ${JSON.stringify(props.inputs)},
|
||||
"response_mode": "streaming",
|
||||
"user": "abc-123"
|
||||
}'`}
|
||||
@ -1012,8 +1012,8 @@ Workflow 应用无会话支持,适合用于翻译/文章写作/总结 AI 等
|
||||
<Col>
|
||||
<CodeGroup
|
||||
title="Request"
|
||||
tag="POST"
|
||||
label="/meta"
|
||||
tag="GET"
|
||||
label="/site"
|
||||
targetCode={`curl -X GET '${props.appDetail.api_base_url}/site' \\
|
||||
-H 'Authorization: Bearer {api_key}'`}
|
||||
/>
|
||||
|
||||
@ -20,7 +20,9 @@ import type { SiteInfo } from '@/models/share'
|
||||
import { TEXT_GENERATION_TIMEOUT_MS } from '@/config'
|
||||
import {
|
||||
getFilesInLogs,
|
||||
getProcessedFiles,
|
||||
} from '@/app/components/base/file-uploader/utils'
|
||||
import type { FileEntity } from '@/app/components/base/file-uploader/types'
|
||||
import { formatBooleanInputs } from '@/utils/model-config'
|
||||
|
||||
export type IResultProps = {
|
||||
@ -160,8 +162,22 @@ const Result: FC<IResultProps> = ({
|
||||
if (!checkCanSend())
|
||||
return
|
||||
|
||||
// Process inputs: convert file entities to API format
|
||||
const processedInputs = { ...formatBooleanInputs(promptConfig?.prompt_variables, inputs) }
|
||||
promptConfig?.prompt_variables.forEach((variable) => {
|
||||
const value = processedInputs[variable.key]
|
||||
if (variable.type === 'file' && value && typeof value === 'object' && !Array.isArray(value)) {
|
||||
// Convert single file entity to API format
|
||||
processedInputs[variable.key] = getProcessedFiles([value as FileEntity])[0]
|
||||
}
|
||||
else if (variable.type === 'file-list' && Array.isArray(value) && value.length > 0) {
|
||||
// Convert file entity array to API format
|
||||
processedInputs[variable.key] = getProcessedFiles(value as FileEntity[])
|
||||
}
|
||||
})
|
||||
|
||||
const data: Record<string, any> = {
|
||||
inputs: formatBooleanInputs(promptConfig?.prompt_variables, inputs),
|
||||
inputs: processedInputs,
|
||||
}
|
||||
if (visionConfig.enabled && completionFiles && completionFiles?.length > 0) {
|
||||
data.files = completionFiles.map((item) => {
|
||||
|
||||
@ -15,7 +15,6 @@ import { DEFAULT_VALUE_MAX_LEN } from '@/config'
|
||||
import TextGenerationImageUploader from '@/app/components/base/image-uploader/text-generation-image-uploader'
|
||||
import type { VisionFile, VisionSettings } from '@/types/app'
|
||||
import { FileUploaderInAttachmentWrapper } from '@/app/components/base/file-uploader'
|
||||
import { getProcessedFiles } from '@/app/components/base/file-uploader/utils'
|
||||
import useBreakpoints, { MediaType } from '@/hooks/use-breakpoints'
|
||||
import cn from '@/utils/classnames'
|
||||
import BoolInput from '@/app/components/workflow/nodes/_base/components/before-run-form/bool-input'
|
||||
@ -82,9 +81,9 @@ const RunOnce: FC<IRunOnceProps> = ({
|
||||
else if (item.type === 'checkbox')
|
||||
newInputs[item.key] = item.default || false
|
||||
else if (item.type === 'file')
|
||||
newInputs[item.key] = item.default
|
||||
newInputs[item.key] = undefined
|
||||
else if (item.type === 'file-list')
|
||||
newInputs[item.key] = item.default || []
|
||||
newInputs[item.key] = []
|
||||
else
|
||||
newInputs[item.key] = undefined
|
||||
})
|
||||
@ -148,8 +147,8 @@ const RunOnce: FC<IRunOnceProps> = ({
|
||||
)}
|
||||
{item.type === 'file' && (
|
||||
<FileUploaderInAttachmentWrapper
|
||||
value={inputs[item.key] ? [inputs[item.key]] : []}
|
||||
onChange={(files) => { handleInputsChange({ ...inputsRef.current, [item.key]: getProcessedFiles(files)[0] }) }}
|
||||
value={(inputs[item.key] && typeof inputs[item.key] === 'object') ? [inputs[item.key]] : []}
|
||||
onChange={(files) => { handleInputsChange({ ...inputsRef.current, [item.key]: files[0] }) }}
|
||||
fileConfig={{
|
||||
...item.config,
|
||||
fileUploadConfig: (visionConfig as any).fileUploadConfig,
|
||||
@ -158,8 +157,8 @@ const RunOnce: FC<IRunOnceProps> = ({
|
||||
)}
|
||||
{item.type === 'file-list' && (
|
||||
<FileUploaderInAttachmentWrapper
|
||||
value={inputs[item.key]}
|
||||
onChange={(files) => { handleInputsChange({ ...inputsRef.current, [item.key]: getProcessedFiles(files) }) }}
|
||||
value={Array.isArray(inputs[item.key]) ? inputs[item.key] : []}
|
||||
onChange={(files) => { handleInputsChange({ ...inputsRef.current, [item.key]: files }) }}
|
||||
fileConfig={{
|
||||
...item.config,
|
||||
fileUploadConfig: (visionConfig as any).fileUploadConfig,
|
||||
|
||||
@ -160,6 +160,10 @@ const translation = {
|
||||
title: 'Cloud-Monitor',
|
||||
description: 'Die vollständig verwaltete und wartungsfreie Observability-Plattform von Alibaba Cloud ermöglicht eine sofortige Überwachung, Verfolgung und Bewertung von Dify-Anwendungen.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Application Performance Monitoring bietet umfassendes Tracing und multidimensionale Analyse für LLM-Anwendungen.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
descriptionInExplore: 'Gibt an, ob das web app Symbol zum Ersetzen 🤖 in Explore verwendet werden soll',
|
||||
|
||||
@ -183,6 +183,10 @@ const translation = {
|
||||
title: 'Cloud Monitor',
|
||||
description: 'The fully-managed and maintenance-free observability platform provided by Alibaba Cloud, enables out-of-the-box monitoring, tracing, and evaluation of Dify applications.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Application Performance Monitoring provides comprehensive tracing and multi-dimensional analysis for LLM applications.',
|
||||
},
|
||||
inUse: 'In use',
|
||||
configProvider: {
|
||||
title: 'Config ',
|
||||
|
||||
@ -163,6 +163,10 @@ const translation = {
|
||||
title: 'Monitor de Nubes',
|
||||
description: 'La plataforma de observabilidad totalmente gestionada y sin mantenimiento proporcionada por Alibaba Cloud, permite la monitorización, trazado y evaluación de aplicaciones Dify de manera inmediata.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Application Performance Monitoring proporciona rastreo integral y análisis multidimensional para aplicaciones LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
title: 'Usar el icono de la aplicación web para reemplazar 🤖',
|
||||
|
||||
@ -171,6 +171,10 @@ const translation = {
|
||||
title: 'نظارت بر ابر',
|
||||
description: 'پلتفرم مشاهدهپذیری کاملاً مدیریتشده و بدون نیاز به نگهداری که توسط Alibaba Cloud ارائه شده، امکان نظارت، ردیابی و ارزیابی برنامههای Dify را بهصورت آماده و با تنظیمات اولیه فراهم میکند.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'تنست ایپیام',
|
||||
description: 'نظارت بر عملکرد برنامههای Tencent تحلیلهای جامع و ردیابی چندبعدی برای برنامههای LLM ارائه میدهد.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
descriptionInExplore: 'آیا از نماد web app برای جایگزینی 🤖 در Explore استفاده کنیم یا خیر',
|
||||
|
||||
@ -163,6 +163,10 @@ const translation = {
|
||||
title: 'Surveillance Cloud',
|
||||
description: 'La plateforme d\'observabilité entièrement gérée et sans maintenance fournie par Alibaba Cloud permet une surveillance, un traçage et une évaluation prêts à l\'emploi des applications Dify.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Application Performance Monitoring fournit une traçabilité complète et une analyse multidimensionnelle pour les applications LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
description: 'S’il faut utiliser l’icône web app pour remplacer 🤖 dans l’application partagée',
|
||||
|
||||
@ -163,6 +163,10 @@ const translation = {
|
||||
title: 'क्लाउड मॉनिटर',
|
||||
description: 'अलीबाबा क्लाउड द्वारा प्रदान की गई पूरी तरह से प्रबंधित और रखरखाव-मुक्त अवलोकन प्लेटफ़ॉर्म, Dify अनुप्रयोगों की स्वचालित निगरानी, ट्रेसिंग और मूल्यांकन का सक्षम बनाता है।',
|
||||
},
|
||||
tencent: {
|
||||
title: 'टेनसेंट एपीएम',
|
||||
description: 'Tencent एप्लिकेशन परफॉर्मेंस मॉनिटरिंग LLM एप्लिकेशन के लिए व्यापक ट्रेसिंग और बहु-आयामी विश्लेषण प्रदान करता है।',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
title: 'बदलने 🤖 के लिए web app चिह्न का उपयोग करें',
|
||||
|
||||
@ -155,6 +155,10 @@ const translation = {
|
||||
description: 'Mengonfigurasi penyedia LLMOps Pihak Ketiga dan melacak performa aplikasi.',
|
||||
inUse: 'Sedang digunakan',
|
||||
tracingDescription: 'Tangkap konteks lengkap eksekusi aplikasi, termasuk panggilan LLM, konteks, perintah, permintaan HTTP, dan lainnya, ke platform pelacakan pihak ketiga.',
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Application Performance Monitoring menyediakan pelacakan komprehensif dan analisis multi-dimensi untuk aplikasi LLM.',
|
||||
},
|
||||
},
|
||||
appSelector: {
|
||||
placeholder: 'Pilih aplikasi...',
|
||||
|
||||
@ -169,6 +169,10 @@ const translation = {
|
||||
title: 'Monitoraggio Cloud',
|
||||
description: 'La piattaforma di osservabilità completamente gestita e senza manutenzione fornita da Alibaba Cloud consente il monitoraggio, il tracciamento e la valutazione delle applicazioni Dify fin da subito.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Application Performance Monitoring fornisce tracciamento completo e analisi multidimensionale per le applicazioni LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
description: 'Se utilizzare l\'icona web app per la sostituzione 🤖 nell\'applicazione condivisa',
|
||||
|
||||
@ -175,6 +175,10 @@ const translation = {
|
||||
title: 'クラウドモニター',
|
||||
description: 'Alibaba Cloud が提供する完全管理型でメンテナンスフリーの可観測性プラットフォームは、Dify アプリケーションの即時監視、トレース、評価を可能にします。',
|
||||
},
|
||||
tencent: {
|
||||
title: 'テンセントAPM',
|
||||
description: 'Tencent アプリケーションパフォーマンスモニタリングは、LLM アプリケーションに対して包括的なトレーシングと多次元分析を提供します。',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
title: 'Web アプリアイコンを使用して🤖を置き換える',
|
||||
|
||||
@ -178,6 +178,10 @@ const translation = {
|
||||
title: '클라우드 모니터',
|
||||
description: '알리바바 클라우드에서 제공하는 완전 관리형 및 유지보수가 필요 없는 가시성 플랫폼은 Dify 애플리케이션의 모니터링, 추적 및 평가를 즉시 사용할 수 있도록 지원합니다.',
|
||||
},
|
||||
tencent: {
|
||||
title: '텐센트 APM',
|
||||
description: '텐센트 애플리케이션 성능 모니터링은 LLM 애플리케이션에 대한 포괄적인 추적 및 다차원 분석을 제공합니다.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
description:
|
||||
|
||||
@ -164,6 +164,10 @@ const translation = {
|
||||
title: 'Monitor Chmury',
|
||||
description: 'W pełni zarządzana i wolna od konserwacji platforma obserwowalności oferowana przez Alibaba Cloud umożliwia gotowe monitorowanie, śledzenie i oceny aplikacji Dify.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Application Performance Monitoring zapewnia kompleksowe śledzenie i wielowymiarową analizę dla aplikacji LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
description: 'Czy w aplikacji udostępnionej ma być używana ikona aplikacji internetowej do zamiany 🤖.',
|
||||
|
||||
@ -163,6 +163,10 @@ const translation = {
|
||||
title: 'Monitoramento em Nuvem',
|
||||
description: 'A plataforma de observabilidade totalmente gerenciada e sem manutenção fornecida pela Alibaba Cloud, permite monitoramento, rastreamento e avaliação prontos para uso de aplicações Dify.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'O Monitoramento de Desempenho de Aplicações da Tencent fornece rastreamento abrangente e análise multidimensional para aplicações LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
descriptionInExplore: 'Se o ícone do web app deve ser usado para substituir 🤖 no Explore',
|
||||
|
||||
@ -163,6 +163,10 @@ const translation = {
|
||||
description: 'Platforma de observabilitate SaaS oferită de Alibaba Cloud permite monitorizarea, urmărirea și evaluarea aplicațiilor Dify din cutie.',
|
||||
title: 'Monitorizarea Cloud',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Monitorizarea Performanței Aplicațiilor Tencent oferă trasabilitate cuprinzătoare și analiză multidimensională pentru aplicațiile LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
descriptionInExplore: 'Dacă să utilizați pictograma web app pentru a înlocui 🤖 în Explore',
|
||||
|
||||
@ -171,6 +171,10 @@ const translation = {
|
||||
title: 'Облачный монитор',
|
||||
description: 'Полностью управляемая и не требующая обслуживания платформа наблюдения, предоставляемая Alibaba Cloud, обеспечивает мониторинг, трассировку и оценку приложений Dify из коробки.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Мониторинг производительности приложений Tencent предоставляет всестороннее отслеживание и многомерный анализ для приложений LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
title: 'Использование значка web app для замены 🤖',
|
||||
|
||||
@ -176,6 +176,10 @@ const translation = {
|
||||
title: 'Oblačni nadzor',
|
||||
description: 'Popolnoma upravljana in brez vzdrževanja platforma za opazovanje, ki jo zagotavlja Alibaba Cloud, omogoča takojšnje spremljanje, sledenje in ocenjevanje aplikacij Dify.',
|
||||
},
|
||||
tencent: {
|
||||
description: 'Tencent Application Performance Monitoring zagotavlja celovito sledenje in večdimenzionalno analizo za aplikacije LLM.',
|
||||
title: 'Tencent APM',
|
||||
},
|
||||
},
|
||||
mermaid: {
|
||||
handDrawn: 'Ročno narisano',
|
||||
|
||||
@ -172,6 +172,10 @@ const translation = {
|
||||
title: 'การตรวจสอบคลาวด์',
|
||||
description: 'แพลตฟอร์มการสังเกตการณ์ที่จัดการโดย Alibaba Cloud ซึ่งไม่ต้องดูแลและบำรุงรักษา ช่วยให้สามารถติดตาม ตรวจสอบ และประเมินแอปพลิเคชัน Dify ได้ทันที',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'การติดตามประสิทธิภาพแอปพลิเคชันของ Tencent มอบการตรวจสอบแบบครบวงจรและการวิเคราะห์หลายมิติสำหรับแอป LLM',
|
||||
},
|
||||
},
|
||||
mermaid: {
|
||||
handDrawn: 'วาดด้วยมือ',
|
||||
|
||||
@ -167,6 +167,10 @@ const translation = {
|
||||
title: 'Bulut İzleyici',
|
||||
description: 'Alibaba Cloud tarafından sağlanan tamamen yönetilen ve bakım gerektirmeyen gözlemleme platformu, Dify uygulamalarının kutudan çıkar çıkmaz izlenmesi, takip edilmesi ve değerlendirilmesine olanak tanır.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Tencent Uygulama Performans İzleme, LLM uygulamaları için kapsamlı izleme ve çok boyutlu analiz sağlar.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
descriptionInExplore: 'Keşfet\'te değiştirilecek 🤖 web app simgesinin kullanılıp kullanılmayacağı',
|
||||
|
||||
@ -163,6 +163,10 @@ const translation = {
|
||||
title: 'Моніторинг Хмари',
|
||||
description: 'Повністю керовані та без обслуговування платформи спостереження, надані Alibaba Cloud, дозволяють миттєвий моніторинг, трасування та оцінку застосувань Dify.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Сервіс моніторингу продуктивності додатків Tencent забезпечує комплексне трасування та багатовимірний аналіз додатків LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
title: 'Використовуйте піктограму web app для заміни 🤖',
|
||||
|
||||
@ -163,6 +163,10 @@ const translation = {
|
||||
title: 'Giám sát Đám mây',
|
||||
description: 'Nền tảng quan sát được quản lý hoàn toàn và không cần bảo trì do Alibaba Cloud cung cấp, cho phép giám sát, theo dõi và đánh giá các ứng dụng Dify ngay lập tức.',
|
||||
},
|
||||
tencent: {
|
||||
title: 'Tencent APM',
|
||||
description: 'Giám sát hiệu suất ứng dụng của Tencent cung cấp khả năng theo dõi toàn diện và phân tích đa chiều cho các ứng dụng LLM.',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
description: 'Có nên sử dụng biểu tượng web app để thay thế 🤖 trong ứng dụng được chia sẻ hay không',
|
||||
|
||||
@ -192,6 +192,10 @@ const translation = {
|
||||
title: '云监控',
|
||||
description: '阿里云提供的全托管免运维可观测平台,一键开启Dify应用的监控追踪和评估',
|
||||
},
|
||||
tencent: {
|
||||
title: '腾讯云 APM',
|
||||
description: '腾讯云应用性能监控,提供 LLM 应用全链路追踪和多维分析',
|
||||
},
|
||||
},
|
||||
appSelector: {
|
||||
label: '应用',
|
||||
|
||||
@ -20,7 +20,7 @@ const translation = {
|
||||
save: '保存',
|
||||
yes: '是',
|
||||
no: '否',
|
||||
deleteConfirmTitle: '删除?',
|
||||
deleteConfirmTitle: '删除?',
|
||||
confirmAction: '请确认您的操作。',
|
||||
saveAndEnable: '保存并启用',
|
||||
edit: '编辑',
|
||||
|
||||
@ -162,6 +162,10 @@ const translation = {
|
||||
title: '雲端監控',
|
||||
description: '阿里雲提供的完全管理且無需維護的可觀察性平台,支持即時監控、追蹤和評估 Dify 應用程序。',
|
||||
},
|
||||
tencent: {
|
||||
title: '騰訊 APM',
|
||||
description: '騰訊應用性能監控為大型語言模型應用提供全面的追蹤和多維分析。',
|
||||
},
|
||||
},
|
||||
answerIcon: {
|
||||
descriptionInExplore: '是否使用 web app 圖示在 Explore 中取代 🤖',
|
||||
|
||||
288
web/knip.config.ts
Normal file
288
web/knip.config.ts
Normal file
@ -0,0 +1,288 @@
|
||||
import type { KnipConfig } from 'knip'
|
||||
|
||||
/**
|
||||
* Knip Configuration for Dead Code Detection
|
||||
*
|
||||
* This configuration helps identify unused files, exports, and dependencies
|
||||
* in the Dify web application (Next.js 15 + TypeScript + React 19).
|
||||
*
|
||||
* ⚠️ SAFETY FIRST: This configuration is designed to be conservative and
|
||||
* avoid false positives that could lead to deleting actively used code.
|
||||
*
|
||||
* @see https://knip.dev/reference/configuration
|
||||
*/
|
||||
const config: KnipConfig = {
|
||||
// ============================================================================
|
||||
// Next.js Framework Configuration
|
||||
// ============================================================================
|
||||
// Configure entry points specific to Next.js application structure.
|
||||
// These files are automatically treated as entry points by the framework.
|
||||
next: {
|
||||
entry: [
|
||||
// Next.js App Router pages (must exist for routing)
|
||||
'app/**/page.tsx',
|
||||
'app/**/layout.tsx',
|
||||
'app/**/loading.tsx',
|
||||
'app/**/error.tsx',
|
||||
'app/**/not-found.tsx',
|
||||
'app/**/template.tsx',
|
||||
'app/**/default.tsx',
|
||||
|
||||
// Middleware (runs before every route)
|
||||
'middleware.ts',
|
||||
|
||||
// Configuration files
|
||||
'next.config.js',
|
||||
'tailwind.config.js',
|
||||
'tailwind-common-config.ts',
|
||||
'postcss.config.js',
|
||||
|
||||
// Testing configuration
|
||||
'jest.config.ts',
|
||||
'jest.setup.ts',
|
||||
|
||||
// Linting configuration
|
||||
'eslint.config.mjs',
|
||||
],
|
||||
},
|
||||
|
||||
// ============================================================================
|
||||
// Global Entry Points
|
||||
// ============================================================================
|
||||
// Files that serve as entry points for the application.
|
||||
// The '!' suffix means these patterns take precedence and are always included.
|
||||
entry: [
|
||||
// Next.js App Router patterns (high priority)
|
||||
'app/**/page.tsx!',
|
||||
'app/**/layout.tsx!',
|
||||
'app/**/loading.tsx!',
|
||||
'app/**/error.tsx!',
|
||||
'app/**/not-found.tsx!',
|
||||
'app/**/template.tsx!',
|
||||
'app/**/default.tsx!',
|
||||
|
||||
// Core configuration files
|
||||
'middleware.ts!',
|
||||
'next.config.js!',
|
||||
'tailwind.config.js!',
|
||||
'tailwind-common-config.ts!',
|
||||
'postcss.config.js!',
|
||||
|
||||
// Testing setup
|
||||
'jest.config.ts!',
|
||||
'jest.setup.ts!',
|
||||
|
||||
// Linting setup
|
||||
'eslint.config.mjs!',
|
||||
|
||||
// ========================================================================
|
||||
// 🔒 CRITICAL: Global Initializers and Providers
|
||||
// ========================================================================
|
||||
// These files are imported by root layout.tsx and provide global functionality.
|
||||
// Even if not directly imported elsewhere, they are essential for app initialization.
|
||||
|
||||
// Browser initialization (runs on client startup)
|
||||
'app/components/browser-initializer.tsx!',
|
||||
'app/components/sentry-initializer.tsx!',
|
||||
'app/components/swr-initializer.tsx!',
|
||||
|
||||
// i18n initialization (server and client)
|
||||
'app/components/i18n.tsx!',
|
||||
'app/components/i18n-server.tsx!',
|
||||
|
||||
// Route prefix handling (used in root layout)
|
||||
'app/routePrefixHandle.tsx!',
|
||||
|
||||
// ========================================================================
|
||||
// 🔒 CRITICAL: Context Providers
|
||||
// ========================================================================
|
||||
// Context providers might be used via React Context API and imported dynamically.
|
||||
// Protecting all context files to prevent breaking the provider chain.
|
||||
'context/**/*.ts?(x)!',
|
||||
|
||||
// Component-level contexts (also used via React.useContext)
|
||||
'app/components/**/*.context.ts?(x)!',
|
||||
|
||||
// ========================================================================
|
||||
// 🔒 CRITICAL: State Management Stores
|
||||
// ========================================================================
|
||||
// Zustand stores might be imported dynamically or via hooks.
|
||||
// These are often imported at module level, so they should be protected.
|
||||
'app/components/**/*.store.ts?(x)!',
|
||||
'context/**/*.store.ts?(x)!',
|
||||
|
||||
// ========================================================================
|
||||
// 🔒 CRITICAL: Provider Components
|
||||
// ========================================================================
|
||||
// Provider components wrap the app and provide global state/functionality
|
||||
'app/components/**/*.provider.ts?(x)!',
|
||||
'context/**/*.provider.ts?(x)!',
|
||||
|
||||
// ========================================================================
|
||||
// Development tools
|
||||
// ========================================================================
|
||||
// Storybook configuration
|
||||
'.storybook/**/*',
|
||||
],
|
||||
|
||||
// ============================================================================
|
||||
// Project Files to Analyze
|
||||
// ============================================================================
|
||||
// Glob patterns for files that should be analyzed for unused code.
|
||||
// Excludes test files to avoid false positives.
|
||||
project: [
|
||||
'**/*.{js,jsx,ts,tsx,mjs,cjs}',
|
||||
],
|
||||
|
||||
// ============================================================================
|
||||
// Ignored Files and Directories
|
||||
// ============================================================================
|
||||
// Files and directories that should be completely excluded from analysis.
|
||||
// These typically contain:
|
||||
// - Test files
|
||||
// - Internationalization files (loaded dynamically)
|
||||
// - Static assets
|
||||
// - Build outputs
|
||||
// - External libraries
|
||||
ignore: [
|
||||
// Test files and directories
|
||||
'**/__tests__/**',
|
||||
'**/*.spec.{ts,tsx}',
|
||||
'**/*.test.{ts,tsx}',
|
||||
|
||||
// ========================================================================
|
||||
// 🔒 CRITICAL: i18n Files (Dynamically Loaded)
|
||||
// ========================================================================
|
||||
// Internationalization files are loaded dynamically at runtime via i18next.
|
||||
// Pattern: import(`@/i18n/${locale}/messages`)
|
||||
// These will NEVER show up in static analysis but are essential!
|
||||
'i18n/**',
|
||||
|
||||
// ========================================================================
|
||||
// 🔒 CRITICAL: Static Assets
|
||||
// ========================================================================
|
||||
// Static assets are referenced by URL in the browser, not via imports.
|
||||
// Examples: /logo.png, /icons/*, /embed.js
|
||||
'public/**',
|
||||
|
||||
// Build outputs and caches
|
||||
'node_modules/**',
|
||||
'.next/**',
|
||||
'coverage/**',
|
||||
|
||||
// Development tools
|
||||
'**/*.stories.{ts,tsx}',
|
||||
|
||||
// ========================================================================
|
||||
// 🔒 Utility scripts (not part of application runtime)
|
||||
// ========================================================================
|
||||
// These scripts are run manually (e.g., pnpm gen-icons, pnpm check-i18n)
|
||||
// and are not imported by the application code.
|
||||
'scripts/**',
|
||||
'bin/**',
|
||||
'i18n-config/**',
|
||||
|
||||
// Icon generation script (generates components, not used in runtime)
|
||||
'app/components/base/icons/script.mjs',
|
||||
],
|
||||
|
||||
// ============================================================================
|
||||
// Ignored Dependencies
|
||||
// ============================================================================
|
||||
// Dependencies that are used but not directly imported in code.
|
||||
// These are typically:
|
||||
// - Build tools
|
||||
// - Plugins loaded by configuration files
|
||||
// - CLI tools
|
||||
ignoreDependencies: [
|
||||
// ========================================================================
|
||||
// Next.js plugins (loaded by next.config.js)
|
||||
// ========================================================================
|
||||
'next-pwa',
|
||||
'@next/bundle-analyzer',
|
||||
'@next/mdx',
|
||||
|
||||
// ========================================================================
|
||||
// Build tools (used by webpack/next.js build process)
|
||||
// ========================================================================
|
||||
'code-inspector-plugin',
|
||||
|
||||
// ========================================================================
|
||||
// Development and translation tools (used by scripts)
|
||||
// ========================================================================
|
||||
'bing-translate-api',
|
||||
'uglify-js',
|
||||
'magicast',
|
||||
],
|
||||
|
||||
// ============================================================================
|
||||
// Export Analysis Configuration
|
||||
// ============================================================================
|
||||
// Configure how exports are analyzed
|
||||
|
||||
// Ignore exports that are only used within the same file
|
||||
// (e.g., helper functions used internally in the same module)
|
||||
ignoreExportsUsedInFile: true,
|
||||
|
||||
// ⚠️ SAFETY: Include exports from entry files in the analysis
|
||||
// This helps find unused public APIs, but be careful with:
|
||||
// - Context exports (useContext hooks)
|
||||
// - Store exports (useStore hooks)
|
||||
// - Type exports (might be used in other files)
|
||||
includeEntryExports: true,
|
||||
|
||||
// ============================================================================
|
||||
// Ignored Binaries
|
||||
// ============================================================================
|
||||
// Binary executables that are used but not listed in package.json
|
||||
ignoreBinaries: [
|
||||
'only-allow', // Used in preinstall script to enforce pnpm usage
|
||||
],
|
||||
|
||||
// ============================================================================
|
||||
// Reporting Rules
|
||||
// ============================================================================
|
||||
// Configure what types of issues to report and at what severity level
|
||||
rules: {
|
||||
// ========================================================================
|
||||
// Unused files are ERRORS
|
||||
// ========================================================================
|
||||
// These should definitely be removed or used.
|
||||
// However, always manually verify before deleting!
|
||||
files: 'error',
|
||||
|
||||
// ========================================================================
|
||||
// Unused dependencies are WARNINGS
|
||||
// ========================================================================
|
||||
// Dependencies might be:
|
||||
// - Used in production builds but not in dev
|
||||
// - Peer dependencies
|
||||
// - Used by other tools
|
||||
dependencies: 'warn',
|
||||
devDependencies: 'warn',
|
||||
|
||||
// ========================================================================
|
||||
// Unlisted imports are ERRORS
|
||||
// ========================================================================
|
||||
// Missing from package.json - will break in production!
|
||||
unlisted: 'error',
|
||||
|
||||
// ========================================================================
|
||||
// Unused exports are WARNINGS (not errors!)
|
||||
// ========================================================================
|
||||
// Exports might be:
|
||||
// - Part of public API for future use
|
||||
// - Used by external tools
|
||||
// - Exported for type inference
|
||||
// ⚠️ ALWAYS manually verify before removing exports!
|
||||
exports: 'warn',
|
||||
|
||||
// Unused types are warnings (might be part of type definitions)
|
||||
types: 'warn',
|
||||
|
||||
// Duplicate exports are warnings (could cause confusion but not breaking)
|
||||
duplicates: 'warn',
|
||||
},
|
||||
}
|
||||
|
||||
export default config
|
||||
@ -23,10 +23,10 @@
|
||||
"build": "next build",
|
||||
"build:docker": "next build && node scripts/optimize-standalone.js",
|
||||
"start": "cp -r .next/static .next/standalone/.next/static && cp -r public .next/standalone/public && cross-env PORT=$npm_config_port HOSTNAME=$npm_config_host node .next/standalone/server.js",
|
||||
"lint": "eslint --concurrency=auto --cache --cache-location node_modules/.cache/eslint/.eslint-cache",
|
||||
"lint:fix": "eslint --concurrency=auto --cache --cache-location node_modules/.cache/eslint/.eslint-cache --fix",
|
||||
"lint:quiet": "eslint --concurrency=auto --cache --cache-location node_modules/.cache/eslint/.eslint-cache --quiet",
|
||||
"lint:complexity": "eslint --concurrency=auto --cache --cache-location node_modules/.cache/eslint/.eslint-cache --rule 'complexity: [error, {max: 15}]' --quiet",
|
||||
"lint": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache",
|
||||
"lint:fix": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache --fix",
|
||||
"lint:quiet": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache --quiet",
|
||||
"lint:complexity": "eslint --cache --cache-location node_modules/.cache/eslint/.eslint-cache --rule 'complexity: [error, {max: 15}]' --quiet",
|
||||
"prepare": "cd ../ && node -e \"if (process.env.NODE_ENV !== 'production'){process.exit(1)} \" || husky ./web/.husky",
|
||||
"gen-icons": "node ./app/components/base/icons/script.mjs",
|
||||
"uglify-embed": "node ./bin/uglify-embed",
|
||||
@ -209,10 +209,10 @@
|
||||
},
|
||||
"lint-staged": {
|
||||
"**/*.js?(x)": [
|
||||
"eslint --concurrency=auto --fix"
|
||||
"eslint --fix"
|
||||
],
|
||||
"**/*.ts?(x)": [
|
||||
"eslint --concurrency=auto --fix"
|
||||
"eslint --fix"
|
||||
]
|
||||
},
|
||||
"pnpm": {
|
||||
|
||||
Reference in New Issue
Block a user