feat: strategy form init
This commit is contained in:
parent
07d7965e3b
commit
03520a5a81
@ -2,6 +2,7 @@ import { pinyin } from 'pinyin-pro'
|
|||||||
import type { FC, RefObject } from 'react'
|
import type { FC, RefObject } from 'react'
|
||||||
import type { ToolWithProvider } from '../types'
|
import type { ToolWithProvider } from '../types'
|
||||||
import { CollectionType } from '../../tools/types'
|
import { CollectionType } from '../../tools/types'
|
||||||
|
import classNames from '@/utils/classnames'
|
||||||
|
|
||||||
export const CUSTOM_GROUP_NAME = '@@@custom@@@'
|
export const CUSTOM_GROUP_NAME = '@@@custom@@@'
|
||||||
export const WORKFLOW_GROUP_NAME = '@@@workflow@@@'
|
export const WORKFLOW_GROUP_NAME = '@@@workflow@@@'
|
||||||
@ -69,16 +70,17 @@ export const groupItems = (items: ToolWithProvider[], getFirstChar: (item: ToolW
|
|||||||
type IndexBarProps = {
|
type IndexBarProps = {
|
||||||
letters: string[]
|
letters: string[]
|
||||||
itemRefs: RefObject<{ [key: string]: HTMLElement | null }>
|
itemRefs: RefObject<{ [key: string]: HTMLElement | null }>
|
||||||
|
className?: string
|
||||||
}
|
}
|
||||||
|
|
||||||
const IndexBar: FC<IndexBarProps> = ({ letters, itemRefs }) => {
|
const IndexBar: FC<IndexBarProps> = ({ letters, itemRefs, className }) => {
|
||||||
const handleIndexClick = (letter: string) => {
|
const handleIndexClick = (letter: string) => {
|
||||||
const element = itemRefs.current?.[letter]
|
const element = itemRefs.current?.[letter]
|
||||||
if (element)
|
if (element)
|
||||||
element.scrollIntoView({ behavior: 'smooth' })
|
element.scrollIntoView({ behavior: 'smooth' })
|
||||||
}
|
}
|
||||||
return (
|
return (
|
||||||
<div className="index-bar absolute right-0 top-36 flex flex-col items-center w-6 justify-center text-xs font-medium text-text-quaternary ">
|
<div className={classNames('index-bar absolute right-0 top-36 flex flex-col items-center w-6 justify-center text-xs font-medium text-text-quaternary', className)}>
|
||||||
<div className='absolute left-0 top-0 h-full w-px bg-[linear-gradient(270deg,rgba(255,255,255,0)_0%,rgba(16,24,40,0.08)_30%,rgba(16,24,40,0.08)_50%,rgba(16,24,40,0.08)_70.5%,rgba(255,255,255,0)_100%)]'></div>
|
<div className='absolute left-0 top-0 h-full w-px bg-[linear-gradient(270deg,rgba(255,255,255,0)_0%,rgba(16,24,40,0.08)_30%,rgba(16,24,40,0.08)_50%,rgba(16,24,40,0.08)_70.5%,rgba(255,255,255,0)_100%)]'></div>
|
||||||
{letters.map(letter => (
|
{letters.map(letter => (
|
||||||
<div className="hover:text-text-secondary cursor-pointer" key={letter} onClick={() => handleIndexClick(letter)}>
|
<div className="hover:text-text-secondary cursor-pointer" key={letter} onClick={() => handleIndexClick(letter)}>
|
||||||
|
@ -12,6 +12,7 @@ import Empty from '@/app/components/tools/add-tool-modal/empty'
|
|||||||
import { useGetLanguage } from '@/context/i18n'
|
import { useGetLanguage } from '@/context/i18n'
|
||||||
import ToolListTreeView from './tool/tool-list-tree-view/list'
|
import ToolListTreeView from './tool/tool-list-tree-view/list'
|
||||||
import ToolListFlatView from './tool/tool-list-flat-view/list'
|
import ToolListFlatView from './tool/tool-list-flat-view/list'
|
||||||
|
import classNames from '@/utils/classnames'
|
||||||
|
|
||||||
type ToolsProps = {
|
type ToolsProps = {
|
||||||
showWorkflowEmpty: boolean
|
showWorkflowEmpty: boolean
|
||||||
@ -19,6 +20,8 @@ type ToolsProps = {
|
|||||||
tools: ToolWithProvider[]
|
tools: ToolWithProvider[]
|
||||||
viewType: ViewType
|
viewType: ViewType
|
||||||
hasSearchText: boolean
|
hasSearchText: boolean
|
||||||
|
className?: string
|
||||||
|
indexBarClassName?: string
|
||||||
}
|
}
|
||||||
const Blocks = ({
|
const Blocks = ({
|
||||||
showWorkflowEmpty,
|
showWorkflowEmpty,
|
||||||
@ -26,6 +29,8 @@ const Blocks = ({
|
|||||||
tools,
|
tools,
|
||||||
viewType,
|
viewType,
|
||||||
hasSearchText,
|
hasSearchText,
|
||||||
|
className,
|
||||||
|
indexBarClassName,
|
||||||
}: ToolsProps) => {
|
}: ToolsProps) => {
|
||||||
const { t } = useTranslation()
|
const { t } = useTranslation()
|
||||||
const language = useGetLanguage()
|
const language = useGetLanguage()
|
||||||
@ -75,7 +80,7 @@ const Blocks = ({
|
|||||||
const toolRefs = useRef({})
|
const toolRefs = useRef({})
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='p-1 max-w-[320px]'>
|
<div className={classNames('p-1 max-w-[320px]', className)}>
|
||||||
{
|
{
|
||||||
!tools.length && !showWorkflowEmpty && (
|
!tools.length && !showWorkflowEmpty && (
|
||||||
<div className='flex items-center px-3 h-[22px] text-xs font-medium text-text-tertiary'>{t('workflow.tabs.noResult')}</div>
|
<div className='flex items-center px-3 h-[22px] text-xs font-medium text-text-tertiary'>{t('workflow.tabs.noResult')}</div>
|
||||||
@ -103,7 +108,7 @@ const Blocks = ({
|
|||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{isShowLetterIndex && <IndexBar letters={letters} itemRefs={toolRefs} />}
|
{isShowLetterIndex && <IndexBar letters={letters} itemRefs={toolRefs} className={indexBarClassName} />}
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
|
import { PortalToFollowElem, PortalToFollowElemContent, PortalToFollowElemTrigger } from '@/app/components/base/portal-to-follow-elem'
|
||||||
import { useState } from 'react'
|
import { useMemo, useState } from 'react'
|
||||||
import type { Strategy } from './agent-strategy'
|
import type { Strategy } from './agent-strategy'
|
||||||
import classNames from '@/utils/classnames'
|
import classNames from '@/utils/classnames'
|
||||||
import { RiArrowDownSLine, RiArrowRightUpLine, RiErrorWarningFill } from '@remixicon/react'
|
import { RiArrowDownSLine, RiArrowRightUpLine, RiErrorWarningFill } from '@remixicon/react'
|
||||||
@ -7,10 +7,10 @@ import { useAllBuiltInTools } from '@/service/use-tools'
|
|||||||
import Tooltip from '@/app/components/base/tooltip'
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
import { InstallPluginButton } from './install-plugin-button'
|
import { InstallPluginButton } from './install-plugin-button'
|
||||||
import SearchInput from '@/app/components/base/search-input'
|
|
||||||
import ViewTypeSelect, { ViewType } from '../../../block-selector/view-type-select'
|
import ViewTypeSelect, { ViewType } from '../../../block-selector/view-type-select'
|
||||||
import Tools from '../../../block-selector/tools'
|
import SearchInput from '@/app/components/base/search-input'
|
||||||
import { MARKETPLACE_URL_PREFIX } from '@/config'
|
import { MARKETPLACE_URL_PREFIX } from '@/config'
|
||||||
|
import Tools from '../../../block-selector/tools'
|
||||||
|
|
||||||
const ExternalNotInstallWarn = () => {
|
const ExternalNotInstallWarn = () => {
|
||||||
// TODO: add i18n label
|
// TODO: add i18n label
|
||||||
@ -40,18 +40,23 @@ export const AgentStrategySelector = (props: AgentStrategySelectorProps) => {
|
|||||||
const [open, setOpen] = useState(false)
|
const [open, setOpen] = useState(false)
|
||||||
const list = useAllBuiltInTools()
|
const list = useAllBuiltInTools()
|
||||||
const [viewType, setViewType] = useState<ViewType>(ViewType.flat)
|
const [viewType, setViewType] = useState<ViewType>(ViewType.flat)
|
||||||
|
const [query, setQuery] = useState('')
|
||||||
|
const filteredTools = useMemo(() => {
|
||||||
|
if (!list.data) return []
|
||||||
|
return list.data.filter(tool => tool.name.toLowerCase().includes(query.toLowerCase()))
|
||||||
|
}, [query, list.data])
|
||||||
// TODO: should be replaced by real data
|
// TODO: should be replaced by real data
|
||||||
const isExternalInstalled = true
|
const isExternalInstalled = true
|
||||||
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
|
return <PortalToFollowElem open={open} onOpenChange={setOpen} placement='bottom'>
|
||||||
<PortalToFollowElemTrigger className='w-full'>
|
<PortalToFollowElemTrigger className='w-full'>
|
||||||
<div className='py-2 pl-3 pr-2 flex items-center rounded-lg bg-components-input-bg-normal w-full hover:bg-state-base-hover-alt' onClick={() => setOpen(true)}>
|
<div className='py-2 pl-3 pr-2 flex items-center rounded-lg bg-components-input-bg-normal w-full hover:bg-state-base-hover-alt select-none' onClick={() => setOpen(o => !o)}>
|
||||||
{/* eslint-disable-next-line @next/next/no-img-element */}
|
{/* eslint-disable-next-line @next/next/no-img-element */}
|
||||||
{list.data && <img
|
{list.data && value && <img
|
||||||
src={list.data.find(
|
src={list.data.find(
|
||||||
coll => coll,
|
coll => coll,
|
||||||
)?.icon as string}
|
)?.icon as string}
|
||||||
width={24}
|
width={20}
|
||||||
height={24}
|
height={20}
|
||||||
className='rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default-dodge'
|
className='rounded-md border-[0.5px] border-components-panel-border-subtle bg-background-default-dodge'
|
||||||
alt='icon'
|
alt='icon'
|
||||||
/>}
|
/>}
|
||||||
@ -60,21 +65,21 @@ export const AgentStrategySelector = (props: AgentStrategySelectorProps) => {
|
|||||||
>
|
>
|
||||||
{value?.agent_strategy_name || 'Select agentic strategy'}
|
{value?.agent_strategy_name || 'Select agentic strategy'}
|
||||||
</p>
|
</p>
|
||||||
<div className='ml-auto flex items-center gap-1'>
|
{value && <div className='ml-auto flex items-center gap-1'>
|
||||||
<InstallPluginButton onClick={e => e.stopPropagation()} size={'small'} />
|
<InstallPluginButton onClick={e => e.stopPropagation()} size={'small'} />
|
||||||
{isExternalInstalled ? <ExternalNotInstallWarn /> : <RiArrowDownSLine className='size-4 text-text-tertiary' />}
|
{isExternalInstalled ? <ExternalNotInstallWarn /> : <RiArrowDownSLine className='size-4 text-text-tertiary' />}
|
||||||
</div>
|
</div>}
|
||||||
</div>
|
</div>
|
||||||
</PortalToFollowElemTrigger>
|
</PortalToFollowElemTrigger>
|
||||||
<PortalToFollowElemContent>
|
<PortalToFollowElemContent className='z-10'>
|
||||||
<div className='bg-components-panel-bg-blur border-components-panel-border border-[0.5px] rounded-md shadow overflow-hidden'>
|
<div className='bg-components-panel-bg-blur border-components-panel-border border-[0.5px] rounded-md shadow overflow-hidden w-[388px]'>
|
||||||
<header className='p-2 gap-1 flex'>
|
<header className='p-2 gap-1 flex'>
|
||||||
<SearchInput placeholder='Search agentic strategy' value='' onChange={console.error} />
|
<SearchInput placeholder='Search agentic strategy' value={query} onChange={setQuery} className={'w-full'} />
|
||||||
<ViewTypeSelect viewType={viewType} onChange={setViewType} />
|
<ViewTypeSelect viewType={viewType} onChange={setViewType} />
|
||||||
</header>
|
</header>
|
||||||
<main className="h-96 relative overflow-hidden">
|
<main className="md:h-[300px] xl:h-[400px] 2xl:h-[564px] relative overflow-hidden">
|
||||||
<Tools
|
<Tools
|
||||||
tools={list.data || []}
|
tools={filteredTools}
|
||||||
viewType={viewType}
|
viewType={viewType}
|
||||||
onSelect={(_, tool) => {
|
onSelect={(_, tool) => {
|
||||||
onChange({
|
onChange({
|
||||||
@ -86,16 +91,20 @@ export const AgentStrategySelector = (props: AgentStrategySelectorProps) => {
|
|||||||
}}
|
}}
|
||||||
hasSearchText={false}
|
hasSearchText={false}
|
||||||
showWorkflowEmpty
|
showWorkflowEmpty
|
||||||
|
className='max-w-none'
|
||||||
|
indexBarClassName='top-0 xl:top-36'
|
||||||
/>
|
/>
|
||||||
<div className='sticky bottom-0 px-4 py-2 flex items-center justify-center border-t border-divider-subtle text-text-accent-light-mode-only bg-components-panel-bg text-xs'>
|
<div className='absolute bottom-0 px-4 py-2 flex items-center justify-center border-t border-divider-subtle text-text-accent-light-mode-only bg-components-panel-bg text-xs'>
|
||||||
Find more in
|
Find more in
|
||||||
{/** //TODO: replace URL */}
|
|
||||||
<Link href={MARKETPLACE_URL_PREFIX} className='flex ml-1'>
|
<Link href={MARKETPLACE_URL_PREFIX} className='flex ml-1'>
|
||||||
Marketplace <RiArrowRightUpLine className='size-3' />
|
Marketplace <RiArrowRightUpLine className='size-3' />
|
||||||
</Link>
|
</Link>
|
||||||
</div>
|
</div>
|
||||||
</main>
|
</main>
|
||||||
</div>
|
</div>
|
||||||
|
{/* <div>
|
||||||
|
aaa
|
||||||
|
</div> */}
|
||||||
</PortalToFollowElemContent>
|
</PortalToFollowElemContent>
|
||||||
</PortalToFollowElem>
|
</PortalToFollowElem>
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@ import type { ToolVarInputs } from '../../tool/types'
|
|||||||
import ListEmpty from '@/app/components/base/list-empty'
|
import ListEmpty from '@/app/components/base/list-empty'
|
||||||
import { AgentStrategySelector } from './agent-strategy-selector'
|
import { AgentStrategySelector } from './agent-strategy-selector'
|
||||||
import Link from 'next/link'
|
import Link from 'next/link'
|
||||||
|
import { useTranslation } from 'react-i18next'
|
||||||
|
import InputVarList from '../../tool/components/input-var-list'
|
||||||
|
|
||||||
export type Strategy = {
|
export type Strategy = {
|
||||||
agent_strategy_provider_name: string
|
agent_strategy_provider_name: string
|
||||||
@ -17,21 +19,36 @@ export type AgentStrategyProps = {
|
|||||||
formSchema: CredentialFormSchema[]
|
formSchema: CredentialFormSchema[]
|
||||||
formValue: ToolVarInputs
|
formValue: ToolVarInputs
|
||||||
onFormValueChange: (value: ToolVarInputs) => void
|
onFormValueChange: (value: ToolVarInputs) => void
|
||||||
|
/**
|
||||||
|
* @description use for get available vars
|
||||||
|
*/
|
||||||
|
nodeId: string
|
||||||
}
|
}
|
||||||
|
|
||||||
export const AgentStrategy = (props: AgentStrategyProps) => {
|
export const AgentStrategy = (props: AgentStrategyProps) => {
|
||||||
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange } = props
|
const { strategy, onStrategyChange, formSchema, formValue, onFormValueChange, nodeId } = props
|
||||||
|
const { t } = useTranslation()
|
||||||
return <div className='space-y-2'>
|
return <div className='space-y-2'>
|
||||||
<AgentStrategySelector value={strategy} onChange={onStrategyChange} />
|
<AgentStrategySelector value={strategy} onChange={onStrategyChange} />
|
||||||
{
|
{
|
||||||
strategy
|
strategy
|
||||||
? <div></div>
|
? <div>
|
||||||
|
<InputVarList
|
||||||
|
readOnly={false}
|
||||||
|
nodeId={nodeId}
|
||||||
|
schema={formSchema}
|
||||||
|
value={formValue}
|
||||||
|
onChange={onFormValueChange}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
// TODO: list empty need a icon
|
// TODO: list empty need a icon
|
||||||
: <ListEmpty
|
: <ListEmpty
|
||||||
title='Please configure agentic strategy.'
|
title={t('workflow.nodes.agent.strategy.configureTip')}
|
||||||
description={<div className='text-text-tertiary text-xs'>
|
description={<div className='text-text-tertiary text-xs'>
|
||||||
After configuring the agentic strategy, this node will automatically load the remaining configurations. The strategy will affect the mechanism of multi-step tool reasoning. <br />
|
{t('workflow.nodes.agent.strategy.configureTipDesc')} <br />
|
||||||
<Link href={'/'} className='text-text-accent-secondary'>Learn more</Link>
|
<Link href={'/'} className='text-text-accent-secondary'>
|
||||||
|
{t('workflow.nodes.agent.learnMore')}
|
||||||
|
</Link>
|
||||||
</div>}
|
</div>}
|
||||||
/>
|
/>
|
||||||
}
|
}
|
||||||
|
@ -1,19 +1,26 @@
|
|||||||
|
import Tooltip from '@/app/components/base/tooltip'
|
||||||
import Indicator from '@/app/components/header/indicator'
|
import Indicator from '@/app/components/header/indicator'
|
||||||
import type { ComponentProps, PropsWithChildren } from 'react'
|
import classNames from '@/utils/classnames'
|
||||||
|
import type { ComponentProps, PropsWithChildren, ReactNode } from 'react'
|
||||||
|
|
||||||
export type SettingItemProps = PropsWithChildren<{
|
export type SettingItemProps = PropsWithChildren<{
|
||||||
label: string
|
label: string
|
||||||
indicator?: ComponentProps<typeof Indicator>['color']
|
status?: 'error' | 'warning'
|
||||||
|
tooltip?: ReactNode
|
||||||
}>
|
}>
|
||||||
|
|
||||||
export const SettingItem = ({ label, children, indicator }: SettingItemProps) => {
|
export const SettingItem = ({ label, children, status, tooltip }: SettingItemProps) => {
|
||||||
return <div className='flex items-center h-6 justify-between bg-gray-100 rounded-md px-1 space-x-1 text-xs font-normal relative'>
|
const indicator: ComponentProps<typeof Indicator>['color'] = status === 'error' ? 'red' : status === 'warning' ? 'yellow' : undefined
|
||||||
<div className='max-w-[100px] shrink-0 truncate text-xs font-medium text-text-tertiary uppercase'>
|
const needTooltip = ['error', 'warning'].includes(status as any)
|
||||||
|
return <div className='flex items-center h-6 justify-between bg-workflow-block-parma-bg rounded-md px-1 space-x-1 text-xs font-normal relative'>
|
||||||
|
<div className={classNames('shrink-0 truncate text-xs font-medium text-text-tertiary uppercase', !!children && 'max-w-[100px]')}>
|
||||||
{label}
|
{label}
|
||||||
</div>
|
</div>
|
||||||
<div className='grow w-0 shrink-0 truncate text-right text-xs font-normal text-text-secondary'>
|
<Tooltip popupContent={tooltip} disabled={!needTooltip}>
|
||||||
{children}
|
<div className='truncate text-right text-xs font-normal text-text-secondary'>
|
||||||
</div>
|
{children}
|
||||||
|
</div>
|
||||||
|
</Tooltip>
|
||||||
{indicator && <Indicator color={indicator} className='absolute -right-0.5 -top-0.5' />}
|
{indicator && <Indicator color={indicator} className='absolute -right-0.5 -top-0.5' />}
|
||||||
</div>
|
</div>
|
||||||
}
|
}
|
||||||
|
@ -5,20 +5,21 @@ import { SettingItem } from '../_base/components/setting-item'
|
|||||||
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
import ModelSelector from '@/app/components/header/account-setting/model-provider-page/model-selector'
|
||||||
import { Group, GroupLabel } from '../_base/components/group'
|
import { Group, GroupLabel } from '../_base/components/group'
|
||||||
import { ToolIcon } from './components/tool-icon'
|
import { ToolIcon } from './components/tool-icon'
|
||||||
|
import useConfig from './use-config'
|
||||||
|
|
||||||
const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
const AgentNode: FC<NodeProps<AgentNodeType>> = (props) => {
|
||||||
const strategySelected = true
|
const { inputs } = useConfig(props.id, props.data)
|
||||||
return <div className='mb-1 px-3 py-1 space-y-1'>
|
return <div className='mb-1 px-3 py-1 space-y-1'>
|
||||||
{strategySelected
|
{inputs.agent_strategy_name
|
||||||
// TODO: add tooltip for this
|
? <SettingItem label='Strategy' status='error' tooltip='ReAct is not installed'>
|
||||||
? <SettingItem label='Strategy' indicator='red'>
|
{inputs.agent_strategy_name}
|
||||||
ReAct
|
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
: <SettingItem label='Agentic strategy Not Set' />}
|
: <SettingItem label='Agentic strategy Not Set' />}
|
||||||
<Group label={
|
<Group
|
||||||
<GroupLabel className='mt-1'>
|
label={<GroupLabel className='mt-1'>
|
||||||
Model
|
Model
|
||||||
</GroupLabel>}>
|
</GroupLabel>}
|
||||||
|
>
|
||||||
<ModelSelector
|
<ModelSelector
|
||||||
modelList={[]}
|
modelList={[]}
|
||||||
readonly
|
readonly
|
||||||
|
@ -7,6 +7,258 @@ import Slider from '@/app/components/base/slider'
|
|||||||
import useNodeCrud from '../_base/hooks/use-node-crud'
|
import useNodeCrud from '../_base/hooks/use-node-crud'
|
||||||
import { AgentStrategy } from '../_base/components/agent-strategy'
|
import { AgentStrategy } from '../_base/components/agent-strategy'
|
||||||
|
|
||||||
|
const mockSchema = [
|
||||||
|
{
|
||||||
|
name: 'format',
|
||||||
|
label: {
|
||||||
|
en_US: 'Format',
|
||||||
|
zh_Hans: '格式',
|
||||||
|
pt_BR: 'Format',
|
||||||
|
ja_JP: 'Format',
|
||||||
|
},
|
||||||
|
placeholder: null,
|
||||||
|
scope: null,
|
||||||
|
required: false,
|
||||||
|
default: '%Y-%m-%d %H:%M:%S',
|
||||||
|
min: null,
|
||||||
|
max: null,
|
||||||
|
options: [],
|
||||||
|
type: 'text-input',
|
||||||
|
human_description: {
|
||||||
|
en_US: 'Time format in strftime standard.',
|
||||||
|
zh_Hans: 'strftime 标准的时间格式。',
|
||||||
|
pt_BR: 'Time format in strftime standard.',
|
||||||
|
ja_JP: 'Time format in strftime standard.',
|
||||||
|
},
|
||||||
|
form: 'form',
|
||||||
|
llm_description: null,
|
||||||
|
variable: 'format',
|
||||||
|
_type: 'string',
|
||||||
|
show_on: [],
|
||||||
|
tooltip: {
|
||||||
|
en_US: 'Time format in strftime standard.',
|
||||||
|
zh_Hans: 'strftime 标准的时间格式。',
|
||||||
|
pt_BR: 'Time format in strftime standard.',
|
||||||
|
ja_JP: 'Time format in strftime standard.',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: 'timezone',
|
||||||
|
label: {
|
||||||
|
en_US: 'Timezone',
|
||||||
|
zh_Hans: '时区',
|
||||||
|
pt_BR: 'Timezone',
|
||||||
|
ja_JP: 'Timezone',
|
||||||
|
},
|
||||||
|
placeholder: null,
|
||||||
|
scope: null,
|
||||||
|
required: false,
|
||||||
|
default: 'UTC',
|
||||||
|
min: null,
|
||||||
|
max: null,
|
||||||
|
options: [
|
||||||
|
{
|
||||||
|
value: 'UTC',
|
||||||
|
label: {
|
||||||
|
en_US: 'UTC',
|
||||||
|
zh_Hans: 'UTC',
|
||||||
|
pt_BR: 'UTC',
|
||||||
|
ja_JP: 'UTC',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'America/New_York',
|
||||||
|
label: {
|
||||||
|
en_US: 'America/New_York',
|
||||||
|
zh_Hans: '美洲/纽约',
|
||||||
|
pt_BR: 'America/New_York',
|
||||||
|
ja_JP: 'America/New_York',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'America/Los_Angeles',
|
||||||
|
label: {
|
||||||
|
en_US: 'America/Los_Angeles',
|
||||||
|
zh_Hans: '美洲/洛杉矶',
|
||||||
|
pt_BR: 'America/Los_Angeles',
|
||||||
|
ja_JP: 'America/Los_Angeles',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'America/Chicago',
|
||||||
|
label: {
|
||||||
|
en_US: 'America/Chicago',
|
||||||
|
zh_Hans: '美洲/芝加哥',
|
||||||
|
pt_BR: 'America/Chicago',
|
||||||
|
ja_JP: 'America/Chicago',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'America/Sao_Paulo',
|
||||||
|
label: {
|
||||||
|
en_US: 'America/Sao_Paulo',
|
||||||
|
zh_Hans: '美洲/圣保罗',
|
||||||
|
pt_BR: 'América/São Paulo',
|
||||||
|
ja_JP: 'America/Sao_Paulo',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Asia/Shanghai',
|
||||||
|
label: {
|
||||||
|
en_US: 'Asia/Shanghai',
|
||||||
|
zh_Hans: '亚洲/上海',
|
||||||
|
pt_BR: 'Asia/Shanghai',
|
||||||
|
ja_JP: 'Asia/Shanghai',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Asia/Ho_Chi_Minh',
|
||||||
|
label: {
|
||||||
|
en_US: 'Asia/Ho_Chi_Minh',
|
||||||
|
zh_Hans: '亚洲/胡志明市',
|
||||||
|
pt_BR: 'Ásia/Ho Chi Minh',
|
||||||
|
ja_JP: 'Asia/Ho_Chi_Minh',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Asia/Tokyo',
|
||||||
|
label: {
|
||||||
|
en_US: 'Asia/Tokyo',
|
||||||
|
zh_Hans: '亚洲/东京',
|
||||||
|
pt_BR: 'Asia/Tokyo',
|
||||||
|
ja_JP: 'Asia/Tokyo',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Asia/Dubai',
|
||||||
|
label: {
|
||||||
|
en_US: 'Asia/Dubai',
|
||||||
|
zh_Hans: '亚洲/迪拜',
|
||||||
|
pt_BR: 'Asia/Dubai',
|
||||||
|
ja_JP: 'Asia/Dubai',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Asia/Kolkata',
|
||||||
|
label: {
|
||||||
|
en_US: 'Asia/Kolkata',
|
||||||
|
zh_Hans: '亚洲/加尔各答',
|
||||||
|
pt_BR: 'Asia/Kolkata',
|
||||||
|
ja_JP: 'Asia/Kolkata',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Asia/Seoul',
|
||||||
|
label: {
|
||||||
|
en_US: 'Asia/Seoul',
|
||||||
|
zh_Hans: '亚洲/首尔',
|
||||||
|
pt_BR: 'Asia/Seoul',
|
||||||
|
ja_JP: 'Asia/Seoul',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Asia/Singapore',
|
||||||
|
label: {
|
||||||
|
en_US: 'Asia/Singapore',
|
||||||
|
zh_Hans: '亚洲/新加坡',
|
||||||
|
pt_BR: 'Asia/Singapore',
|
||||||
|
ja_JP: 'Asia/Singapore',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Europe/London',
|
||||||
|
label: {
|
||||||
|
en_US: 'Europe/London',
|
||||||
|
zh_Hans: '欧洲/伦敦',
|
||||||
|
pt_BR: 'Europe/London',
|
||||||
|
ja_JP: 'Europe/London',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Europe/Berlin',
|
||||||
|
label: {
|
||||||
|
en_US: 'Europe/Berlin',
|
||||||
|
zh_Hans: '欧洲/柏林',
|
||||||
|
pt_BR: 'Europe/Berlin',
|
||||||
|
ja_JP: 'Europe/Berlin',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Europe/Moscow',
|
||||||
|
label: {
|
||||||
|
en_US: 'Europe/Moscow',
|
||||||
|
zh_Hans: '欧洲/莫斯科',
|
||||||
|
pt_BR: 'Europe/Moscow',
|
||||||
|
ja_JP: 'Europe/Moscow',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Australia/Sydney',
|
||||||
|
label: {
|
||||||
|
en_US: 'Australia/Sydney',
|
||||||
|
zh_Hans: '澳大利亚/悉尼',
|
||||||
|
pt_BR: 'Australia/Sydney',
|
||||||
|
ja_JP: 'Australia/Sydney',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Pacific/Auckland',
|
||||||
|
label: {
|
||||||
|
en_US: 'Pacific/Auckland',
|
||||||
|
zh_Hans: '太平洋/奥克兰',
|
||||||
|
pt_BR: 'Pacific/Auckland',
|
||||||
|
ja_JP: 'Pacific/Auckland',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
value: 'Africa/Cairo',
|
||||||
|
label: {
|
||||||
|
en_US: 'Africa/Cairo',
|
||||||
|
zh_Hans: '非洲/开罗',
|
||||||
|
pt_BR: 'Africa/Cairo',
|
||||||
|
ja_JP: 'Africa/Cairo',
|
||||||
|
},
|
||||||
|
show_on: [],
|
||||||
|
},
|
||||||
|
],
|
||||||
|
type: 'select',
|
||||||
|
human_description: {
|
||||||
|
en_US: 'Timezone',
|
||||||
|
zh_Hans: '时区',
|
||||||
|
pt_BR: 'Timezone',
|
||||||
|
ja_JP: 'Timezone',
|
||||||
|
},
|
||||||
|
form: 'form',
|
||||||
|
llm_description: null,
|
||||||
|
variable: 'timezone',
|
||||||
|
_type: 'select',
|
||||||
|
show_on: [],
|
||||||
|
tooltip: {
|
||||||
|
en_US: 'Timezone',
|
||||||
|
zh_Hans: '时区',
|
||||||
|
pt_BR: 'Timezone',
|
||||||
|
ja_JP: 'Timezone',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
] as const
|
||||||
|
|
||||||
const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
||||||
const { inputs, setInputs } = useNodeCrud(props.id, props.data)
|
const { inputs, setInputs } = useNodeCrud(props.id, props.data)
|
||||||
const [iter, setIter] = [inputs.max_iterations, (value: number) => {
|
const [iter, setIter] = [inputs.max_iterations, (value: number) => {
|
||||||
@ -15,7 +267,7 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
|||||||
max_iterations: value,
|
max_iterations: value,
|
||||||
})
|
})
|
||||||
}]
|
}]
|
||||||
return <>
|
return <div className='space-y-2 my-2'>
|
||||||
<Field title={'Strategy'} className='px-4' >
|
<Field title={'Strategy'} className='px-4' >
|
||||||
<AgentStrategy
|
<AgentStrategy
|
||||||
strategy={inputs.agent_strategy_name ? {
|
strategy={inputs.agent_strategy_name ? {
|
||||||
@ -31,9 +283,13 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
|||||||
agent_parameters: strategy?.agent_parameters,
|
agent_parameters: strategy?.agent_parameters,
|
||||||
})
|
})
|
||||||
}}
|
}}
|
||||||
formSchema={[]}
|
formSchema={mockSchema as any}
|
||||||
formValue={{}}
|
formValue={inputs.agent_parameters || {}}
|
||||||
onFormValueChange={console.error}
|
onFormValueChange={value => setInputs({
|
||||||
|
...inputs,
|
||||||
|
agent_parameters: value,
|
||||||
|
})}
|
||||||
|
nodeId={props.id}
|
||||||
/>
|
/>
|
||||||
</Field>
|
</Field>
|
||||||
<Field title={'tools'} className='px-4'>
|
<Field title={'tools'} className='px-4'>
|
||||||
@ -55,7 +311,7 @@ const AgentPanel: FC<NodePanelProps<AgentNodeType>> = (props) => {
|
|||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
</Field>
|
</Field>
|
||||||
</>
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AgentPanel
|
export default AgentPanel
|
||||||
|
@ -256,7 +256,7 @@ const translation = {
|
|||||||
'parameter-extractor': 'Use LLM to extract structured parameters from natural language for tool invocations or HTTP requests.',
|
'parameter-extractor': 'Use LLM to extract structured parameters from natural language for tool invocations or HTTP requests.',
|
||||||
'document-extractor': 'Used to parse uploaded documents into text content that is easily understandable by LLM.',
|
'document-extractor': 'Used to parse uploaded documents into text content that is easily understandable by LLM.',
|
||||||
'list-operator': 'Used to filter or sort array content.',
|
'list-operator': 'Used to filter or sort array content.',
|
||||||
'agent': 'TODO: add text here',
|
'agent': 'Invoking large language models to answer questions or process natural language',
|
||||||
},
|
},
|
||||||
operator: {
|
operator: {
|
||||||
zoomIn: 'Zoom In',
|
zoomIn: 'Zoom In',
|
||||||
@ -697,6 +697,13 @@ const translation = {
|
|||||||
last_record: 'Last record',
|
last_record: 'Last record',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
agent: {
|
||||||
|
strategy: {
|
||||||
|
configureTip: 'Please configure agentic strategy.',
|
||||||
|
configureTipDesc: 'After configuring the agentic strategy, this node will automatically load the remaining configurations. The strategy will affect the mechanism of multi-step tool reasoning. ',
|
||||||
|
},
|
||||||
|
learnMore: 'Learn more',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
tracing: {
|
tracing: {
|
||||||
stopBy: 'Stop by {{user}}',
|
stopBy: 'Stop by {{user}}',
|
||||||
|
@ -256,7 +256,7 @@ const translation = {
|
|||||||
'parameter-extractor': '利用 LLM 从自然语言内推理提取出结构化参数,用于后置的工具调用或 HTTP 请求。',
|
'parameter-extractor': '利用 LLM 从自然语言内推理提取出结构化参数,用于后置的工具调用或 HTTP 请求。',
|
||||||
'document-extractor': '用于将用户上传的文档解析为 LLM 便于理解的文本内容。',
|
'document-extractor': '用于将用户上传的文档解析为 LLM 便于理解的文本内容。',
|
||||||
'list-operator': '用于过滤或排序数组内容。',
|
'list-operator': '用于过滤或排序数组内容。',
|
||||||
'agent': 'TODO: Agent',
|
'agent': '调用大型语言模型回答问题或处理自然语言',
|
||||||
},
|
},
|
||||||
operator: {
|
operator: {
|
||||||
zoomIn: '放大',
|
zoomIn: '放大',
|
||||||
@ -697,6 +697,13 @@ const translation = {
|
|||||||
last_record: '最后一条记录',
|
last_record: '最后一条记录',
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
agent: {
|
||||||
|
strategy: {
|
||||||
|
configureTip: '请配置 Agent 策略。',
|
||||||
|
configureTipDesc: '配置完成后,此节点将自动加载剩余配置。策略将影响多步工具推理的机制。',
|
||||||
|
},
|
||||||
|
learnMore: '了解更多',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
tracing: {
|
tracing: {
|
||||||
stopBy: '由{{user}}终止',
|
stopBy: '由{{user}}终止',
|
||||||
|
Loading…
Reference in New Issue
Block a user