Feat: feature and log dark mode (#13208)

This commit is contained in:
KVOJJJin 2025-02-05 13:58:19 +08:00 committed by GitHub
parent 1de84fdda0
commit 2710242982
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
25 changed files with 208 additions and 143 deletions

View File

@ -151,7 +151,6 @@ const SettingBuiltInTool: FC<Props> = ({
isEditMode={false}
showOnVariableMap={{}}
validating={false}
inputClassName='!bg-gray-50'
readonly={readonly}
/>
)
@ -224,7 +223,7 @@ const SettingBuiltInTool: FC<Props> = ({
</div>
{!readonly && !isInfoActive && (
<div className='mt-2 shrink-0 flex justify-end py-4 px-6 space-x-2 rounded-b-[10px] bg-components-panel-bg border-t border-divider-regular'>
<Button className='flex items-center h-8 !px-3 !text-[13px] font-medium !text-gray-700' onClick={onHide}>{t('common.operation.cancel')}</Button>
<Button className='flex items-center h-8 !px-3 !text-[13px] font-medium ' onClick={onHide}>{t('common.operation.cancel')}</Button>
<Button className='flex items-center h-8 !px-3 !text-[13px] font-medium' variant='primary' disabled={!isValid} onClick={() => onSave?.(addDefaultValue(tempSetting, formSchemas))}>{t('common.operation.save')}</Button>
</div>
)}

View File

@ -48,7 +48,7 @@ import PromptLogModal from '@/app/components/base/prompt-log-modal'
import { useStore as useAppStore } from '@/app/components/app/store'
import { useFeatures, useFeaturesStore } from '@/app/components/base/features/hooks'
interface IDebug {
type IDebug = {
isAPIKeySet: boolean
onSetting: () => void
inputs: Inputs

View File

@ -81,26 +81,26 @@ const AgentLogDetail: FC<AgentLogDetailProps> = ({
return (
<div className='grow relative flex flex-col'>
{/* tab */}
<div className='shrink-0 flex items-center px-4 border-b-[0.5px] border-[rgba(0,0,0,0.05)]'>
<div className='shrink-0 flex items-center px-4 border-b-[0.5px] border-divider-regular'>
<div
className={cn(
'mr-6 py-3 border-b-2 border-transparent text-[13px] font-semibold leading-[18px] text-gray-400 cursor-pointer',
currentTab === 'DETAIL' && '!border-[rgb(21,94,239)] text-gray-700',
'mr-6 py-3 border-b-2 border-transparent text-[13px] font-semibold leading-[18px] text-text-tertiary cursor-pointer',
currentTab === 'DETAIL' && '!border-[rgb(21,94,239)] text-text-secondary',
)}
onClick={() => switchTab('DETAIL')}
>{t('runLog.detail')}</div>
<div
className={cn(
'mr-6 py-3 border-b-2 border-transparent text-[13px] font-semibold leading-[18px] text-gray-400 cursor-pointer',
currentTab === 'TRACING' && '!border-[rgb(21,94,239)] text-gray-700',
'mr-6 py-3 border-b-2 border-transparent text-[13px] font-semibold leading-[18px] text-text-tertiary cursor-pointer',
currentTab === 'TRACING' && '!border-[rgb(21,94,239)] text-text-secondary',
)}
onClick={() => switchTab('TRACING')}
>{t('runLog.tracing')}</div>
</div>
{/* panel detail */}
<div className={cn('grow bg-white h-0 overflow-y-auto rounded-b-2xl', currentTab !== 'DETAIL' && '!bg-gray-50')}>
<div className={cn('grow bg-components-panel-bg h-0 overflow-y-auto rounded-b-2xl', currentTab !== 'DETAIL' && '!bg-background-section')}>
{loading && (
<div className='flex h-full items-center justify-center bg-white'>
<div className='flex h-full items-center justify-center bg-components-panel-bg'>
<Loading />
</div>
)}

View File

@ -35,7 +35,7 @@ const AgentLogModal: FC<AgentLogModalProps> = ({
return (
<div
className={cn('relative flex flex-col py-3 bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl z-10')}
className={cn('relative flex flex-col py-3 bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-xl shadow-xl z-10')}
style={{
width: 480,
position: 'fixed',
@ -45,9 +45,9 @@ const AgentLogModal: FC<AgentLogModalProps> = ({
}}
ref={ref}
>
<h1 className='shrink-0 px-4 py-1 text-md font-semibold text-gray-900'>{t('appLog.runDetail.workflowTitle')}</h1>
<h1 className='shrink-0 px-4 py-1 text-md font-semibold text-text-primary'>{t('appLog.runDetail.workflowTitle')}</h1>
<span className='absolute right-3 top-4 p-1 cursor-pointer z-20' onClick={onCancel}>
<RiCloseLine className='w-4 h-4 text-gray-500' />
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
</span>
<AgentLogDetail
conversationID={currentLogItem.conversationId}

View File

@ -2,8 +2,9 @@
import { useTranslation } from 'react-i18next'
import type { FC } from 'react'
import ToolCall from './tool-call'
import cn from '@/utils/classnames'
import Divider from '@/app/components/base/divider'
import type { AgentIteration } from '@/models/log'
import cn from '@/utils/classnames'
type Props = {
isFinal: boolean
@ -18,12 +19,12 @@ const Iteration: FC<Props> = ({ iterationInfo, isFinal, index }) => {
<div className={cn('px-4 py-2')}>
<div className='flex items-center'>
{isFinal && (
<div className='shrink-0 mr-3 text-gray-500 text-xs leading-[18px] font-semibold'>{t('appLog.agentLogDetail.finalProcessing')}</div>
<div className='shrink-0 mr-3 text-text-tertiary text-xs leading-[18px] font-semibold'>{t('appLog.agentLogDetail.finalProcessing')}</div>
)}
{!isFinal && (
<div className='shrink-0 mr-3 text-gray-500 text-xs leading-[18px] font-semibold'>{`${t('appLog.agentLogDetail.iteration').toUpperCase()} ${index}`}</div>
<div className='shrink-0 mr-3 text-text-tertiary text-xs leading-[18px] font-semibold'>{`${t('appLog.agentLogDetail.iteration').toUpperCase()} ${index}`}</div>
)}
<div className='grow h-[1px] bg-gradient-to-r from-[#f3f4f6] to-gray-50'></div>
<Divider bgStyle='gradient' className='grow h-[1px] mx-0'/>
</div>
<ToolCall
isLLM

View File

@ -36,7 +36,7 @@ const ResultPanel: FC<ResultPanelProps> = ({
const { formatTime } = useTimestamp()
return (
<div className='bg-white py-2'>
<div className='bg-components-panel-bg py-2'>
<div className='px-4 py-2'>
<StatusPanel
status='succeeded'
@ -62,57 +62,57 @@ const ResultPanel: FC<ResultPanelProps> = ({
/>
</div>
<div className='px-4 py-2'>
<div className='h-[0.5px] bg-black opacity-5' />
<div className='h-[0.5px] bg-divider-regular opacity-5' />
</div>
<div className='px-4 py-2'>
<div className='relative'>
<div className='h-6 leading-6 text-gray-500 text-xs font-medium'>{t('runLog.meta.title')}</div>
<div className='h-6 leading-6 text-text-tertiary text-xs font-medium'>{t('runLog.meta.title')}</div>
<div className='py-1'>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.status')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('runLog.meta.status')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>SUCCESS</span>
</div>
</div>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.executor')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('runLog.meta.executor')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>{created_by || 'N/A'}</span>
</div>
</div>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.startTime')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('runLog.meta.startTime')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>{formatTime(Date.parse(created_at) / 1000, t('appLog.dateTimeFormat') as string)}</span>
</div>
</div>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.time')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('runLog.meta.time')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>{`${elapsed_time?.toFixed(3)}s`}</span>
</div>
</div>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('runLog.meta.tokens')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('runLog.meta.tokens')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>{`${total_tokens || 0} Tokens`}</span>
</div>
</div>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('appLog.agentLogDetail.agentMode')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('appLog.agentLogDetail.agentMode')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>{agentMode === 'function_call' ? t('appDebug.agent.agentModeType.functionCall') : t('appDebug.agent.agentModeType.ReACT')}</span>
</div>
</div>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('appLog.agentLogDetail.toolUsed')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('appLog.agentLogDetail.toolUsed')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>{tools?.length ? tools?.join(', ') : 'Null'}</span>
</div>
</div>
<div className='flex'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-gray-500 text-xs leading-[18px] truncate'>{t('appLog.agentLogDetail.iterations')}</div>
<div className='grow px-2 py-[5px] text-gray-900 text-xs leading-[18px]'>
<div className='shrink-0 w-[104px] px-2 py-[5px] text-text-tertiary text-xs leading-[18px] truncate'>{t('appLog.agentLogDetail.iterations')}</div>
<div className='grow px-2 py-[5px] text-text-primary text-xs leading-[18px]'>
<span>{iterations}</span>
</div>
</div>

View File

@ -33,7 +33,7 @@ const ToolCallItem: FC<Props> = ({ toolCall, isLLM = false, isFinal, tokens, obs
if (time < 1)
return `${(time * 1000).toFixed(3)} ms`
if (time > 60)
return `${parseInt(Math.round(time / 60).toString())} m ${(time % 60).toFixed(3)} s`
return `${Number.parseInt(Math.round(time / 60).toString())} m ${(time % 60).toFixed(3)} s`
return `${time.toFixed(3)} s`
}
@ -41,14 +41,14 @@ const ToolCallItem: FC<Props> = ({ toolCall, isLLM = false, isFinal, tokens, obs
if (tokens < 1000)
return tokens
if (tokens >= 1000 && tokens < 1000000)
return `${parseFloat((tokens / 1000).toFixed(3))}K`
return `${Number.parseFloat((tokens / 1000).toFixed(3))}K`
if (tokens >= 1000000)
return `${parseFloat((tokens / 1000000).toFixed(3))}M`
return `${Number.parseFloat((tokens / 1000000).toFixed(3))}M`
}
return (
<div className={cn('py-1')}>
<div className={cn('group transition-all bg-white border border-gray-100 rounded-2xl shadow-xs hover:shadow-md')}>
<div className={cn('group transition-all bg-background-default border border-components-panel-border rounded-2xl shadow-xs hover:shadow-md')}>
<div
className={cn(
'flex items-center py-3 pl-[6px] pr-3 cursor-pointer',
@ -58,15 +58,15 @@ const ToolCallItem: FC<Props> = ({ toolCall, isLLM = false, isFinal, tokens, obs
>
<ChevronRight
className={cn(
'shrink-0 w-3 h-3 mr-1 text-gray-400 transition-all group-hover:text-gray-500',
'shrink-0 w-3 h-3 mr-1 text-text-quaternary transition-all group-hover:text-text-tertiary',
!collapseState && 'rotate-90',
)}
/>
<BlockIcon className={cn('shrink-0 mr-2')} type={isLLM ? BlockEnum.LLM : BlockEnum.Tool} toolIcon={toolCall.tool_icon} />
<div className={cn(
'grow text-gray-700 text-[13px] leading-[16px] font-semibold truncate',
'grow text-text-secondary text-[13px] leading-[16px] font-semibold truncate',
)} title={toolName}>{toolName}</div>
<div className='shrink-0 text-gray-500 text-xs leading-[18px]'>
<div className='shrink-0 text-text-tertiary text-xs leading-[18px]'>
{toolCall.time_cost && (
<span>{getTime(toolCall.time_cost || 0)}</span>
)}

View File

@ -9,7 +9,7 @@ type TracingPanelProps = {
const TracingPanel: FC<TracingPanelProps> = ({ list }) => {
return (
<div className='bg-gray-50'>
<div className='bg-background-section'>
{list.map((iteration, index) => (
<Iteration
key={index}

View File

@ -76,7 +76,7 @@ export const CopyFeedbackNew = ({ content, className }: Pick<Props, 'className'
}
>
<div
className={`w-8 h-8 cursor-pointer hover:bg-gray-100 rounded-lg ${
className={`w-8 h-8 cursor-pointer hover:bg-components-button-ghost-bg-hover rounded-lg ${
className ?? ''
}`}
>

View File

@ -6,12 +6,14 @@ import { ReactSortable } from 'react-sortablejs'
import { RiAddLine, RiAsterisk, RiCloseLine, RiDeleteBinLine, RiDraggable } from '@remixicon/react'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import ConfirmAddVar from '@/app/components/app/configuration/config-prompt/confirm-add-var'
import type { OpeningStatement } from '@/app/components/base/features/types'
import { getInputKeys } from '@/app/components/base/block-input'
import type { PromptVariable } from '@/models/debug'
import type { InputVar } from '@/app/components/workflow/types'
import { getNewVar } from '@/utils/var'
import cn from '@/utils/classnames'
type OpeningSettingModalProps = {
data: OpeningStatement
@ -86,16 +88,19 @@ const OpeningSettingModal = ({
handleSave(true)
}, [handleSave, hideConfirmAddVar, notIncludeKeys, onAutoAddPromptVariable])
const [focusID, setFocusID] = useState<number | null>(null)
const [deletingID, setDeletingID] = useState<number | null>(null)
const renderQuestions = () => {
return (
<div>
<div className='flex items-center py-2'>
<div className='shrink-0 flex space-x-0.5 leading-[18px] text-xs font-medium text-gray-500'>
<div className='shrink-0 flex space-x-0.5 leading-[18px] text-xs font-medium text-text-tertiary'>
<div className='uppercase'>{t('appDebug.openingStatement.openingQuestion')}</div>
<div>·</div>
<div>{tempSuggestedQuestions.length}/{MAX_QUESTION_NUM}</div>
</div>
<div className='ml-3 grow w-0 h-px bg-[#243, 244, 246]'></div>
<Divider bgStyle='gradient' className='ml-3 grow w-0 h-px'/>
</div>
<ReactSortable
className="space-y-1"
@ -112,8 +117,15 @@ const OpeningSettingModal = ({
>
{tempSuggestedQuestions.map((question, index) => {
return (
<div className='group relative rounded-lg border border-gray-200 flex items-center pl-2.5 hover:border-gray-300 hover:bg-white' key={index}>
<RiDraggable className='handle w-4 h-4 cursor-grab' />
<div
className={cn(
'group relative rounded-lg border border-components-panel-border-subtle bg-components-panel-on-panel-item-bg flex items-center pl-2.5 hover:bg-components-panel-on-panel-item-bg-hover',
focusID === index && 'border-components-input-border-active hover:border-components-input-border-active bg-components-input-bg-active hover:bg-components-input-bg-active',
deletingID === index && 'border-components-input-border-destructive hover:border-components-input-border-destructive bg-state-destructive-hover hover:bg-state-destructive-hover',
)}
key={index}
>
<RiDraggable className='handle w-4 h-4 text-text-quaternary cursor-grab' />
<input
type="input"
value={question || ''}
@ -126,14 +138,18 @@ const OpeningSettingModal = ({
return item
}))
}}
className={'w-full overflow-x-auto pl-1.5 pr-8 text-sm leading-9 text-gray-900 border-0 grow h-9 bg-transparent focus:outline-none cursor-pointer rounded-lg'}
className={'w-full overflow-x-auto pl-1.5 pr-8 text-sm leading-9 text-text-secondary border-0 grow h-9 bg-transparent focus:outline-none cursor-pointer rounded-lg'}
onFocus={() => setFocusID(index)}
onBlur={() => setFocusID(null)}
/>
<div
className='block absolute top-1/2 translate-y-[-50%] right-1.5 p-1 rounded-md cursor-pointer hover:bg-[#FEE4E2] hover:text-[#D92D20]'
className='block absolute top-1/2 translate-y-[-50%] right-1.5 p-1 rounded-md cursor-pointer text-text-tertiary hover:bg-state-destructive-hover hover:text-text-destructive'
onClick={() => {
setTempSuggestedQuestions(tempSuggestedQuestions.filter((_, i) => index !== i))
}}
onMouseEnter={() => setDeletingID(index)}
onMouseLeave={() => setDeletingID(null)}
>
<RiDeleteBinLine className='w-3.5 h-3.5' />
</div>
@ -143,9 +159,9 @@ const OpeningSettingModal = ({
{tempSuggestedQuestions.length < MAX_QUESTION_NUM && (
<div
onClick={() => { setTempSuggestedQuestions([...tempSuggestedQuestions, '']) }}
className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-gray-400 bg-gray-100 hover:bg-gray-200'>
className='mt-1 flex items-center h-9 px-3 gap-2 rounded-lg cursor-pointer text-components-button-tertiary-text bg-components-button-tertiary-bg hover:bg-components-button-tertiary-bg-hover'>
<RiAddLine className='w-4 h-4' />
<div className='text-gray-500 text-[13px]'>{t('appDebug.variableConfig.addOption')}</div>
<div className='system-sm-medium text-[13px]'>{t('appDebug.variableConfig.addOption')}</div>
</div>
)}
</div>

View File

@ -30,14 +30,14 @@ const FormGeneration: FC<FormGenerationProps> = ({
key={index}
className='py-2'
>
<div className='flex items-center h-9 text-sm font-medium text-gray-900'>
<div className='flex items-center h-9 text-sm font-medium text-text-primary'>
{locale === 'zh-Hans' ? form.label['zh-Hans'] : form.label['en-US']}
</div>
{
form.type === 'text-input' && (
<input
value={value?.[form.variable] || ''}
className='block px-3 w-full h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none'
className='block px-3 w-full h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-primary outline-none appearance-none'
placeholder={form.placeholder}
onChange={e => handleFormChange(form.variable, e.target.value)}
/>

View File

@ -27,13 +27,13 @@ const ModerationContent: FC<ModerationContentProps> = ({
return (
<div className='py-2'>
<div className='rounded-lg bg-gray-50 border border-gray-200'>
<div className='rounded-lg bg-components-panel-bg border border-components-panel-border'>
<div className='flex items-center justify-between px-3 h-10 rounded-lg'>
<div className='shrink-0 text-sm font-medium text-gray-900'>{title}</div>
<div className='shrink-0 text-sm font-medium text-text-primary'>{title}</div>
<div className='grow flex items-center justify-end'>
{
info && (
<div className='mr-2 text-xs text-gray-500 truncate' title={info}>{info}</div>
<div className='mr-2 text-xs text-text-tertiary truncate' title={info}>{info}</div>
)
}
<Switch
@ -45,20 +45,20 @@ const ModerationContent: FC<ModerationContentProps> = ({
</div>
{
config.enabled && showPreset && (
<div className='px-3 pt-1 pb-3 bg-white rounded-lg'>
<div className='flex items-center justify-between h-8 text-[13px] font-medium text-gray-700'>
<div className='px-3 pt-1 pb-3 bg-components-panel-bg rounded-lg'>
<div className='flex items-center justify-between h-8 text-[13px] font-medium text-text-secondary'>
{t('appDebug.feature.moderation.modal.content.preset')}
<span className='text-xs font-normal text-gray-500'>{t('appDebug.feature.moderation.modal.content.supportMarkdown')}</span>
<span className='text-xs font-normal text-text-tertiary'>{t('appDebug.feature.moderation.modal.content.supportMarkdown')}</span>
</div>
<div className='relative px-3 py-2 h-20 rounded-lg bg-gray-100'>
<div className='relative px-3 py-2 h-20 rounded-lg bg-components-input-bg-normal'>
<textarea
value={config.preset_response || ''}
className='block w-full h-full bg-transparent text-sm outline-none appearance-none resize-none'
className='block w-full h-full bg-transparent text-sm text-text-secondary outline-none appearance-none resize-none'
placeholder={t('appDebug.feature.moderation.modal.content.placeholder') || ''}
onChange={e => handleConfigChange('preset_response', e.target.value)}
/>
<div className='absolute bottom-2 right-2 flex items-center px-1 h-5 rounded-md bg-gray-50 text-xs font-medium text-gray-300'>
<span>{(config.preset_response || '').length}</span>/<span className='text-gray-500'>100</span>
<div className='absolute bottom-2 right-2 flex items-center px-1 h-5 rounded-md bg-background-section text-xs font-medium text-text-quaternary'>
<span>{(config.preset_response || '').length}</span>/<span className='text-text-tertiary'>100</span>
</div>
</div>
</div>

View File

@ -9,6 +9,7 @@ import FormGeneration from './form-generation'
import ApiBasedExtensionSelector from '@/app/components/header/account-setting/api-based-extension-page/selector'
import Modal from '@/app/components/base/modal'
import Button from '@/app/components/base/button'
import Divider from '@/app/components/base/divider'
import { BookOpen01 } from '@/app/components/base/icons/src/vender/line/education'
import type { ModerationConfig, ModerationContentConfig } from '@/models/debug'
import { useToastContext } from '@/app/components/base/toast'
@ -22,6 +23,7 @@ import { LanguagesSupported } from '@/i18n/language'
import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general'
import { useModalContext } from '@/context/modal-context'
import { CustomConfigurationStatusEnum } from '@/app/components/header/account-setting/model-provider-page/declarations'
import cn from '@/utils/classnames'
const systemTypes = ['openai_moderation', 'keywords', 'api']
@ -245,7 +247,7 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
<div className='p-1 cursor-pointer' onClick={onCancel}><RiCloseLine className='w-4 h-4 text-text-tertiary'/></div>
</div>
<div className='py-2'>
<div className='leading-9 text-sm font-medium text-gray-900'>
<div className='leading-9 text-sm font-medium text-text-primary'>
{t('appDebug.feature.moderation.modal.provider.title')}
</div>
<div className='grid gap-2.5 grid-cols-3'>
@ -253,16 +255,18 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
providers.map(provider => (
<div
key={provider.key}
className={`
flex items-center px-3 py-2 rounded-lg text-sm text-gray-900 cursor-pointer
${localeData.type === provider.key ? 'bg-white border-[1.5px] border-primary-400 shadow-sm' : 'border border-gray-100 bg-gray-25'}
${localeData.type === 'openai_moderation' && provider.key === 'openai_moderation' && !isOpenAIProviderConfigured && 'opacity-50'}
`}
className={cn(
'flex items-center px-2 h-8 rounded-md system-sm-regular bg-components-option-card-option-bg border border-components-option-card-option-border text-text-secondary cursor-default',
localeData.type !== provider.key && 'hover:bg-components-option-card-option-bg-hover hover:border-components-option-card-option-border-hover hover:shadow-xs cursor-pointer',
localeData.type === provider.key && 'bg-components-option-card-option-selected-bg border-[1.5px] border-components-option-card-option-selected-border system-sm-medium shadow-xs',
localeData.type === 'openai_moderation' && provider.key === 'openai_moderation' && !isOpenAIProviderConfigured && 'text-text-disabled',
)}
onClick={() => handleDataTypeChange(provider.key)}
>
<div className={`
mr-2 w-4 h-4 rounded-full border
${localeData.type === provider.key ? 'border-[5px] border-primary-600' : 'border border-gray-300'}`} />
<div className={cn(
'mr-2 w-4 h-4 border border-components-radio-border bg-components-radio-bg shadow-xs rounded-full',
localeData.type === provider.key && 'border-[5px] border-components-radio-border-checked',
)}></div>
{provider.name}
</div>
))
@ -289,17 +293,17 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
{
localeData.type === 'keywords' && (
<div className='py-2'>
<div className='mb-1 text-sm font-medium text-gray-900'>{t('appDebug.feature.moderation.modal.provider.keywords')}</div>
<div className='mb-2 text-xs text-gray-500'>{t('appDebug.feature.moderation.modal.keywords.tip')}</div>
<div className='relative px-3 py-2 h-[88px] bg-gray-100 rounded-lg'>
<div className='mb-1 text-sm font-medium text-text-primary'>{t('appDebug.feature.moderation.modal.provider.keywords')}</div>
<div className='mb-2 text-xs text-text-tertiary'>{t('appDebug.feature.moderation.modal.keywords.tip')}</div>
<div className='relative px-3 py-2 h-[88px] bg-components-input-bg-normal rounded-lg'>
<textarea
value={localeData.config?.keywords || ''}
onChange={handleDataKeywordsChange}
className='block w-full h-full bg-transparent text-sm outline-none appearance-none resize-none'
className='block w-full h-full bg-transparent text-sm text-text-secondary outline-none appearance-none resize-none'
placeholder={t('appDebug.feature.moderation.modal.keywords.placeholder') || ''}
/>
<div className='absolute bottom-2 right-2 flex items-center px-1 h-5 rounded-md bg-gray-50 text-xs font-medium text-gray-300'>
<span>{(localeData.config?.keywords || '').split('\n').filter(Boolean).length}</span>/<span className='text-gray-500'>100 {t('appDebug.feature.moderation.modal.keywords.line')}</span>
<div className='absolute bottom-2 right-2 flex items-center px-1 h-5 rounded-md bg-background-section text-xs font-medium text-text-quaternary'>
<span>{(localeData.config?.keywords || '').split('\n').filter(Boolean).length}</span>/<span className='text-text-tertiary'>100 {t('appDebug.feature.moderation.modal.keywords.line')}</span>
</div>
</div>
</div>
@ -309,13 +313,13 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
localeData.type === 'api' && (
<div className='py-2'>
<div className='flex items-center justify-between h-9'>
<div className='text-sm font-medium text-gray-900'>{t('common.apiBasedExtension.selector.title')}</div>
<div className='text-sm font-medium text-text-primary'>{t('common.apiBasedExtension.selector.title')}</div>
<a
href={t('common.apiBasedExtension.linkUrl') || '/'}
target='_blank' rel='noopener noreferrer'
className='group flex items-center text-xs text-gray-500 hover:text-primary-600'
className='group flex items-center text-xs text-text-tertiary hover:text-primary-600'
>
<BookOpen01 className='mr-1 w-3 h-3 text-gray-500 group-hover:text-primary-600' />
<BookOpen01 className='mr-1 w-3 h-3 text-text-tertiary group-hover:text-primary-600' />
{t('common.apiBasedExtension.link')}
</a>
</div>
@ -337,7 +341,7 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
/>
)
}
<div className='my-3 h-[1px] bg-gradient-to-r from-[#F3F4F6]'></div>
<Divider bgStyle='gradient' className='my-3 h-px' />
<ModerationContent
title={t('appDebug.feature.moderation.modal.content.input') || ''}
config={localeData.config?.inputs_config || { enabled: false, preset_response: '' }}
@ -352,7 +356,7 @@ const ModerationSettingModal: FC<ModerationSettingModalProps> = ({
info={(localeData.type === 'api' && t('appDebug.feature.moderation.modal.content.fromApi')) || ''}
showPreset={!(localeData.type === 'api')}
/>
<div className='mt-1 mb-8 text-xs font-medium text-gray-500'>{t('appDebug.feature.moderation.modal.content.condition')}</div>
<div className='mt-1 mb-8 text-xs font-medium text-text-tertiary'>{t('appDebug.feature.moderation.modal.content.condition')}</div>
<div className='flex items-center justify-end'>
<Button
onClick={onCancel}

View File

@ -93,13 +93,13 @@ const VoiceParamConfig = ({
>
<div className='relative h-8'>
<Listbox.Button
className={'w-full h-full rounded-lg border-0 bg-gray-100 py-1.5 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 cursor-pointer'}>
<span className={classNames('block truncate text-left', !languageItem?.name && 'text-gray-400')}>
className={'w-full h-full rounded-lg border-0 bg-components-input-bg-normal py-1.5 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover group-hover:bg-state-base-hover cursor-pointer'}>
<span className={classNames('block truncate text-left text-text-secondary', !languageItem?.name && 'text-text-tertiary')}>
{languageItem?.name ? t(`common.voice.language.${languageItem?.value.replace('-', '')}`) : localLanguagePlaceholder}
</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronDownIcon
className="h-5 w-5 text-gray-400"
className="h-4 w-4 text-text-tertiary"
aria-hidden="true"
/>
</span>
@ -112,12 +112,12 @@ const VoiceParamConfig = ({
>
<Listbox.Options
className="absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm">
className="absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm">
{languages.map((item: Item) => (
<Listbox.Option
key={item.value}
className={({ active }) =>
`relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : ''
`relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-state-base-hover text-text-secondary ${active ? 'bg-state-base-active' : ''
}`
}
value={item}
@ -130,10 +130,10 @@ const VoiceParamConfig = ({
{(selected || item.value === text2speech?.language) && (
<span
className={classNames(
'absolute inset-y-0 right-0 flex items-center pr-4 text-gray-700',
'absolute inset-y-0 right-0 flex items-center pr-4 text-text-secondary',
)}
>
<CheckIcon className="h-5 w-5" aria-hidden="true"/>
<CheckIcon className="h-4 w-4" aria-hidden="true"/>
</span>
)}
</>
@ -161,12 +161,12 @@ const VoiceParamConfig = ({
>
<div className={'grow relative h-8'}>
<Listbox.Button
className={'w-full h-full rounded-lg border-0 bg-gray-100 py-1.5 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-gray-200 group-hover:bg-gray-200 cursor-pointer'}>
className={'w-full h-full rounded-lg border-0 bg-components-input-bg-normal py-1.5 pl-3 pr-10 sm:text-sm sm:leading-6 focus-visible:outline-none focus-visible:bg-state-base-hover group-hover:bg-state-base-hover cursor-pointer'}>
<span
className={classNames('block truncate text-left', !voiceItem?.name && 'text-gray-400')}>{voiceItem?.name ?? localVoicePlaceholder}</span>
className={classNames('block truncate text-left text-text-secondary', !voiceItem?.name && 'text-text-tertiary')}>{voiceItem?.name ?? localVoicePlaceholder}</span>
<span className="pointer-events-none absolute inset-y-0 right-0 flex items-center pr-2">
<ChevronDownIcon
className="h-5 w-5 text-gray-400"
className="h-4 w-4 text-text-tertiary"
aria-hidden="true"
/>
</span>
@ -179,12 +179,12 @@ const VoiceParamConfig = ({
>
<Listbox.Options
className="absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-white py-1 text-base shadow-lg border-gray-200 border-[0.5px] focus:outline-none sm:text-sm">
className="absolute z-10 mt-1 px-1 max-h-60 w-full overflow-auto rounded-md bg-components-panel-bg py-1 text-base shadow-lg border-components-panel-border border-[0.5px] focus:outline-none sm:text-sm">
{voiceItems?.map((item: Item) => (
<Listbox.Option
key={item.value}
className={({ active }) =>
`relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-gray-100 text-gray-700 ${active ? 'bg-gray-100' : ''
`relative cursor-pointer select-none py-2 pl-3 pr-9 rounded-lg hover:bg-state-base-hover text-text-secondary ${active ? 'bg-state-base-active' : ''
}`
}
value={item}
@ -196,10 +196,10 @@ const VoiceParamConfig = ({
{(selected || item.value === text2speech?.voice) && (
<span
className={classNames(
'absolute inset-y-0 right-0 flex items-center pr-4 text-gray-700',
'absolute inset-y-0 right-0 flex items-center pr-4 text-text-secondary',
)}
>
<CheckIcon className="h-5 w-5" aria-hidden="true"/>
<CheckIcon className="h-4 w-4" aria-hidden="true"/>
</span>
)}
</>

View File

@ -12,7 +12,7 @@ const Card: FC<CardProps> = ({
{
log.length === 1 && (
<div className='px-4 py-2'>
<div className='whitespace-pre-line text-gray-700'>
<div className='whitespace-pre-line text-text-secondary'>
{log[0].text}
</div>
</div>
@ -23,12 +23,12 @@ const Card: FC<CardProps> = ({
<div>
{
log.map((item, index) => (
<div key={index} className='group/card mb-2 px-4 pt-2 pb-4 rounded-xl hover:bg-gray-50 last-of-type:mb-0'>
<div key={index} className='group/card mb-2 px-4 pt-2 pb-4 rounded-xl hover:bg-state-base-hover last-of-type:mb-0'>
<div className='flex justify-between items-center h-8'>
<div className='font-semibold text-[#2D31A6]'>{item.role.toUpperCase()}</div>
<CopyFeedbackNew className='hidden w-6 h-6 group-hover/card:block' content={item.text} />
</div>
<div className='whitespace-pre-line text-gray-700'>{item.text}</div>
<div className='whitespace-pre-line text-text-secondary'>{item.text}</div>
</div>
))
}

View File

@ -33,7 +33,7 @@ const PromptLogModal: FC<PromptLogModalProps> = ({
return (
<div
className='relative flex flex-col bg-white border-[0.5px] border-gray-200 rounded-xl shadow-xl z-10'
className='relative flex flex-col bg-components-panel-bg border-[0.5px] border-components-panel-border rounded-xl shadow-xl z-10'
style={{
width: 480,
position: 'fixed',
@ -43,14 +43,14 @@ const PromptLogModal: FC<PromptLogModalProps> = ({
}}
ref={ref}
>
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-b-gray-100'>
<div className='text-base font-semibold text-gray-900'>PROMPT LOG</div>
<div className='shrink-0 flex justify-between items-center pl-6 pr-5 h-14 border-b border-divider-regular'>
<div className='text-base font-semibold text-text-primary'>PROMPT LOG</div>
<div className='flex items-center'>
{
currentLogItem.log?.length === 1 && (
<>
<CopyFeedbackNew className='w-6 h-6' content={currentLogItem.log[0].text} />
<div className='mx-2.5 w-[1px] h-[14px] bg-gray-200' />
<div className='mx-2.5 w-[1px] h-[14px] bg-divider-regular' />
</>
)
}
@ -58,7 +58,7 @@ const PromptLogModal: FC<PromptLogModalProps> = ({
onClick={onCancel}
className='flex justify-center items-center w-6 h-6 cursor-pointer'
>
<RiCloseLine className='w-4 h-4 text-gray-500' />
<RiCloseLine className='w-4 h-4 text-text-tertiary' />
</div>
</div>
</div>

View File

@ -77,7 +77,7 @@ const ApiBasedExtensionModal: FC<ApiBasedExtensionModalProps> = ({
onClose={() => { }}
className='!p-8 !pb-6 !max-w-none !w-[640px]'
>
<div className='mb-2 text-xl font-semibold text-gray-900'>
<div className='mb-2 text-xl font-semibold text-text-primary'>
{
data.name
? t('common.apiBasedExtension.modal.editTitle')
@ -85,44 +85,44 @@ const ApiBasedExtensionModal: FC<ApiBasedExtensionModalProps> = ({
}
</div>
<div className='py-2'>
<div className='leading-9 text-sm font-medium text-gray-900'>
<div className='leading-9 text-sm font-medium text-text-primary'>
{t('common.apiBasedExtension.modal.name.title')}
</div>
<input
value={localeData.name || ''}
onChange={e => handleDataChange('name', e.target.value)}
className='block px-3 w-full h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none'
className='block px-3 w-full h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-primary outline-none appearance-none'
placeholder={t('common.apiBasedExtension.modal.name.placeholder') || ''}
/>
</div>
<div className='py-2'>
<div className='flex justify-between items-center h-9 text-sm font-medium text-gray-900'>
<div className='flex justify-between items-center h-9 text-sm font-medium text-text-primary'>
{t('common.apiBasedExtension.modal.apiEndpoint.title')}
<a
href={t('common.apiBasedExtension.linkUrl') || '/'}
target='_blank' rel='noopener noreferrer'
className='group flex items-center text-xs text-gray-500 font-normal hover:text-primary-600'
className='group flex items-center text-xs text-text-tertiary font-normal hover:text-text-accent'
>
<BookOpen01 className='mr-1 w-3 h-3 text-gray-500 group-hover:text-primary-600' />
<BookOpen01 className='mr-1 w-3 h-3 text-text-tertiary group-hover:text-text-accent' />
{t('common.apiBasedExtension.link')}
</a>
</div>
<input
value={localeData.api_endpoint || ''}
onChange={e => handleDataChange('api_endpoint', e.target.value)}
className='block px-3 w-full h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none'
className='block px-3 w-full h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-primary outline-none appearance-none'
placeholder={t('common.apiBasedExtension.modal.apiEndpoint.placeholder') || ''}
/>
</div>
<div className='py-2'>
<div className='leading-9 text-sm font-medium text-gray-900'>
<div className='leading-9 text-sm font-medium text-text-primary'>
{t('common.apiBasedExtension.modal.apiKey.title')}
</div>
<div className='flex items-center'>
<input
value={localeData.api_key || ''}
onChange={e => handleDataChange('api_key', e.target.value)}
className='block grow mr-2 px-3 h-9 bg-gray-100 rounded-lg text-sm text-gray-900 outline-none appearance-none'
className='block grow mr-2 px-3 h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-primary outline-none appearance-none'
placeholder={t('common.apiBasedExtension.modal.apiKey.placeholder') || ''}
/>
</div>

View File

@ -54,33 +54,33 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
{
currentItem
? (
<div className='flex items-center justify-between pl-3 pr-2.5 h-9 bg-gray-100 rounded-lg cursor-pointer'>
<div className='text-sm text-gray-900'>{currentItem.name}</div>
<div className='flex items-center justify-between pl-3 pr-2.5 h-9 bg-components-input-bg-normal rounded-lg cursor-pointer'>
<div className='text-sm text-text-primary'>{currentItem.name}</div>
<div className='flex items-center'>
<div className='mr-1.5 w-[270px] text-xs text-gray-400 truncate text-right'>
<div className='mr-1.5 w-[270px] text-xs text-text-quaternary truncate text-right'>
{currentItem.api_endpoint}
</div>
<RiArrowDownSLine className={`w-4 h-4 text-gray-700 ${!open && 'opacity-60'}`} />
<RiArrowDownSLine className={`w-4 h-4 text-text-secondary ${!open && 'opacity-60'}`} />
</div>
</div>
)
: (
<div className='flex items-center justify-between pl-3 pr-2.5 h-9 bg-gray-100 rounded-lg text-sm text-gray-400 cursor-pointer'>
<div className='flex items-center justify-between pl-3 pr-2.5 h-9 bg-components-input-bg-normal rounded-lg text-sm text-text-quaternary cursor-pointer'>
{t('common.apiBasedExtension.selector.placeholder')}
<RiArrowDownSLine className={`w-4 h-4 text-gray-700 ${!open && 'opacity-60'}`} />
<RiArrowDownSLine className={`w-4 h-4 text-text-secondary ${!open && 'opacity-60'}`} />
</div>
)
}
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='w-[calc(100%-32px)] max-w-[576px] z-[102]'>
<div className='w-full rounded-lg border-[0.5px] border-gray-200 bg-white shadow-lg z-10'>
<div className='w-full rounded-lg border-[0.5px] border-components-panel-border bg-components-panel-bg shadow-lg z-10'>
<div className='p-1'>
<div className='flex items-center justify-between px-3 pt-2 pb-1'>
<div className='text-xs font-medium text-gray-500'>
<div className='text-xs font-medium text-text-tertiary'>
{t('common.apiBasedExtension.selector.title')}
</div>
<div
className='flex items-center text-xs text-primary-600 cursor-pointer'
className='flex items-center text-xs text-text-accent cursor-pointer'
onClick={() => {
setOpen(false)
setShowAccountSettingModal({ payload: 'api-based-extension' })
@ -95,20 +95,20 @@ const ApiBasedExtensionSelector: FC<ApiBasedExtensionSelectorProps> = ({
data?.map(item => (
<div
key={item.id}
className='px-3 py-1.5 w-full cursor-pointer hover:bg-gray-50 rounded-md text-left'
className='px-3 py-1.5 w-full cursor-pointer hover:stroke-state-base-hover rounded-md text-left'
onClick={() => handleSelect(item.id!)}
>
<div className='text-sm text-gray-900'>{item.name}</div>
<div className='text-xs text-gray-500'>{item.api_endpoint}</div>
<div className='text-sm text-text-primary'>{item.name}</div>
<div className='text-xs text-text-tertiary'>{item.api_endpoint}</div>
</div>
))
}
</div>
</div>
<div className='h-[1px] bg-gray-100' />
<div className='h-[1px] bg-divider-regular' />
<div className='p-1'>
<div
className='flex items-center px-3 h-8 text-sm text-primary-600 cursor-pointer'
className='flex items-center px-3 h-8 text-sm text-text-accent cursor-pointer'
onClick={() => {
setOpen(false)
setShowApiBasedExtensionModal({ payload: {}, onSaveCallback: () => mutate() })

View File

@ -44,6 +44,7 @@ const MultipleToolSelector = ({
// add tool
const [open, setOpen] = React.useState(false)
const [panelShowState, setPanelShowState] = React.useState(true)
const handleAdd = (val: ToolValue) => {
const newValue = [...value, val]
// deduplication
@ -109,7 +110,10 @@ const MultipleToolSelector = ({
</>
)}
{!disabled && (
<ActionButton className='mx-1' onClick={() => setOpen(!open)}>
<ActionButton className='mx-1' onClick={() => {
setOpen(!open)
setPanelShowState(true)
}}>
<RiAddLine className='w-4 h-4' />
</ActionButton>
)}
@ -126,6 +130,9 @@ const MultipleToolSelector = ({
trigger={
<div className=''></div>
}
panelShowState={panelShowState}
onPanelShowStateChange={setPanelShowState}
/>
{value.length === 0 && (
<div className='p-3 flex justify-center rounded-[10px] bg-background-section text-text-tertiary system-xs-regular'>{t('plugin.detailPanel.toolSelector.empty')}</div>

View File

@ -53,6 +53,7 @@ type Props = {
onSelect: (tool: {
provider_name: string
tool_name: string
tool_label: string
parameters?: Record<string, any>
extra?: Record<string, any>
}) => void
@ -62,6 +63,8 @@ type Props = {
trigger?: React.ReactNode
controlledState?: boolean
onControlledStateChange?: (state: boolean) => void
panelShowState?: boolean
onPanelShowStateChange?: (state: boolean) => void
}
const ToolSelector: FC<Props> = ({
value,
@ -76,6 +79,8 @@ const ToolSelector: FC<Props> = ({
trigger,
controlledState,
onControlledStateChange,
panelShowState,
onPanelShowStateChange,
}) => {
const { t } = useTranslation()
const [isShow, onShowChange] = useState(false)
@ -244,17 +249,18 @@ const ToolSelector: FC<Props> = ({
<div className='flex flex-col gap-1'>
<div className='h-6 flex items-center system-sm-semibold text-text-secondary'>{t('plugin.detailPanel.toolSelector.toolLabel')}</div>
<ToolPicker
panelClassName='w-[328px]'
placement='bottom'
offset={offset}
trigger={
<ToolTrigger
open={isShowChooseTool}
open={panelShowState || isShowChooseTool}
value={value}
provider={currentProvider}
/>
}
isShow={isShowChooseTool}
onShowChange={setIsShowChooseTool}
isShow={panelShowState || isShowChooseTool}
onShowChange={trigger ? onPanelShowStateChange as any : setIsShowChooseTool}
disabled={false}
supportAddCustomTool
onSelect={handleSelectTool}

View File

@ -24,8 +24,10 @@ import {
import type { CustomCollectionBackend } from '@/app/components/tools/types'
import Toast from '@/app/components/base/toast'
import { useAllBuiltInTools, useAllCustomTools, useAllWorkflowTools, useInvalidateAllCustomTools } from '@/service/use-tools'
import cn from '@/utils/classnames'
type Props = {
panelClassName?: string
disabled: boolean
trigger: React.ReactNode
placement?: Placement
@ -49,6 +51,7 @@ const ToolPicker: FC<Props> = ({
supportAddCustomTool,
scope = 'all',
selectedTools,
panelClassName,
}) => {
const { t } = useTranslation()
const [searchText, setSearchText] = useState('')
@ -139,7 +142,7 @@ const ToolPicker: FC<Props> = ({
</PortalToFollowElemTrigger>
<PortalToFollowElemContent className='z-[1000]'>
<div className="relative w-[356px] min-h-20 rounded-xl backdrop-blur-sm bg-components-panel-bg-blur border-[0.5px] border-components-panel-border shadow-lg">
<div className={cn('relative w-[356px] min-h-20 rounded-xl backdrop-blur-sm bg-components-panel-bg-blur border-[0.5px] border-components-panel-border shadow-lg', panelClassName)}>
<div className='p-2 pb-1'>
<SearchBox
search={searchText}

View File

@ -0,0 +1,9 @@
<svg width="237" height="50" viewBox="0 0 237 50" fill="none" xmlns="http://www.w3.org/2000/svg">
<path opacity="0.5" d="M0 8C0 3.58172 3.58172 0 8 0H237L215.033 50H8C3.58172 50 0 46.4183 0 42V8Z" fill="url(#paint0_linear_3552_29170)"/>
<defs>
<linearGradient id="paint0_linear_3552_29170" x1="-4.89158e-08" y1="4.62963" x2="168.013" y2="23.1752" gradientUnits="userSpaceOnUse">
<stop stop-color="white" stop-opacity="0.03"/>
<stop offset="1" stop-color="white" stop-opacity="0.05"/>
</linearGradient>
</defs>
</svg>

After

Width:  |  Height:  |  Size: 517 B

View File

@ -1,5 +1,7 @@
'use client'
import type { FC } from 'react'
import { useAppContext } from '@/context/app-context'
import { Theme } from '@/types/app'
import cn from '@/utils/classnames'
type Props = {
@ -11,19 +13,36 @@ const StatusContainer: FC<Props> = ({
status,
children,
}) => {
const { theme } = useAppContext()
return (
<div
className={cn(
'relative px-3 py-2.5 rounded-lg border system-xs-regular break-all',
status === 'succeeded' && 'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(23,178,106,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-success',
status === 'partial-succeeded' && 'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(23,178,106,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-success',
status === 'failed' && 'border-[rgba(240,68,56,0.8)] bg-workflow-display-error-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-error.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(240,68,56,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-warning',
status === 'stopped' && 'border-[rgba(247,144,9,0.8)] bg-workflow-display-warning-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-warning.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(247,144,9,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-destructive',
status === 'exception' && 'border-[rgba(247,144,9,0.8)] bg-workflow-display-warning-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-warning.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(247,144,9,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-text-destructive',
status === 'running' && 'border-[rgba(11,165,236,0.8)] bg-workflow-display-normal-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-running.svg)] shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(11,165,236,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)] text-util-colors-blue-light-blue-light-600',
status === 'succeeded' && 'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] text-text-success',
status === 'succeeded' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(23,178,106,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
status === 'succeeded' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(23,178,106,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
status === 'partial-succeeded' && 'border-[rgba(23,178,106,0.8)] bg-workflow-display-success-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-success.svg)] text-text-success',
status === 'partial-succeeded' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(23,178,106,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
status === 'partial-succeeded' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(23,178,106,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
status === 'failed' && 'border-[rgba(240,68,56,0.8)] bg-workflow-display-error-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-error.svg)] text-text-warning',
status === 'failed' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(240,68,56,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
status === 'failed' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(240,68,56,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
status === 'stopped' && 'border-[rgba(247,144,9,0.8)] bg-workflow-display-warning-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-warning.svg)] text-text-destructive',
status === 'stopped' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(247,144,9,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
status === 'stopped' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(247,144,9,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
status === 'exception' && 'border-[rgba(247,144,9,0.8)] bg-workflow-display-warning-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-warning.svg)] text-text-destructive',
status === 'exception' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(247,144,9,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
status === 'exception' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(247,144,9,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
status === 'running' && 'border-[rgba(11,165,236,0.8)] bg-workflow-display-normal-bg bg-[url(~@/app/components/workflow/run/assets/bg-line-running.svg)] text-util-colors-blue-light-blue-light-600',
status === 'running' && theme === Theme.light && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.5),inset_0_1px_3px_0_rgba(0,0,0,0.12),inset_0_2px_24px_0_rgba(11,165,236,0.2),0_1px_2px_0_rgba(9,9,11,0.05),0_0_0_1px_rgba(0,0,0,0.05)]',
status === 'running' && theme === Theme.dark && 'shadow-[inset_2px_2px_0_0_rgba(255,255,255,0.12),inset_0_1px_3px_0_rgba(0,0,0,0.4),inset_0_2px_24px_0_rgba(11,165,236,0.25),0_1px_2px_0_rgba(0,0,0,0.1),0_0_0_1px_rgba(24, 24, 27, 0.95)]',
)}
>
<div className='absolute top-0 left-0 w-[65%] h-[50px] bg-[url(~@/app/components/workflow/run/assets/highlight.svg)]'></div>
<div className={cn(
'absolute top-0 left-0 w-[65%] h-[50px] bg-no-repeat',
theme === Theme.light && 'bg-[url(~@/app/components/workflow/run/assets/highlight.svg)]',
theme === Theme.dark && 'bg-[url(~@/app/components/workflow/run/assets/highlight-dark.svg)]',
)}></div>
{children}
</div>
)

View File

@ -5,7 +5,7 @@ import cn from '@/utils/classnames'
import Indicator from '@/app/components/header/indicator'
import StatusContainer from '@/app/components/workflow/run/status-container'
interface ResultProps {
type ResultProps = {
status: string
time?: number
tokens?: number

View File

@ -66,6 +66,7 @@ const AppContext = createContext<AppContextValue>({
name: '',
email: '',
avatar: '',
avatar_url: '',
is_password_set: false,
},
currentWorkspace: initialWorkspaceInfo,