From 77950e48c76f4a3b29d01831d43039caba29888a Mon Sep 17 00:00:00 2001
From: wwf <1971391498@qq.com>
Date: 星期二, 18 十一月 2025 14:12:42 +0800
Subject: [PATCH] 修改
---
app/components/app/configuration/config/agent/agent-tools/index.tsx | 289 ++++++++++++++++++++-------------------------------------
1 files changed, 103 insertions(+), 186 deletions(-)
diff --git a/app/components/app/configuration/config/agent/agent-tools/index.tsx b/app/components/app/configuration/config/agent/agent-tools/index.tsx
index 4b773c0..52e5d5d 100644
--- a/app/components/app/configuration/config/agent/agent-tools/index.tsx
+++ b/app/components/app/configuration/config/agent/agent-tools/index.tsx
@@ -1,24 +1,21 @@
'use client'
import type { FC } from 'react'
-import React, { useMemo, useState } from 'react'
+import React, { useState } from 'react'
import { useTranslation } from 'react-i18next'
import { useContext } from 'use-context-selector'
-import copy from 'copy-to-clipboard'
import produce from 'immer'
import {
RiDeleteBinLine,
- RiEqualizer2Line,
- RiInformation2Line,
+ RiHammerFill,
} from '@remixicon/react'
import { useFormattingChangedDispatcher } from '../../../debug/hooks'
import SettingBuiltInTool from './setting-built-in-tool'
+import cn from '@/utils/classnames'
import Panel from '@/app/components/app/configuration/base/feature-panel'
+import { InfoCircle } from '@/app/components/base/icons/src/vender/line/general'
import OperationBtn from '@/app/components/app/configuration/base/operation-btn'
import AppIcon from '@/app/components/base/app-icon'
-import Button from '@/app/components/base/button'
-import Indicator from '@/app/components/header/indicator'
import Switch from '@/app/components/base/switch'
-import Toast from '@/app/components/base/toast'
import ConfigContext from '@/context/debug-configuration'
import type { AgentTool } from '@/types/app'
import { type Collection, CollectionType } from '@/app/components/tools/types'
@@ -26,12 +23,7 @@
import { AlertTriangle } from '@/app/components/base/icons/src/vender/solid/alertsAndFeedback'
import Tooltip from '@/app/components/base/tooltip'
import { DefaultToolIcon } from '@/app/components/base/icons/src/public/other'
-import ConfigCredential from '@/app/components/tools/setting/build-in/config-credentials'
-import { updateBuiltInToolCredential } from '@/service/tools'
-import cn from '@/utils/classnames'
-import ToolPicker from '@/app/components/workflow/block-selector/tool-picker'
-import type { ToolDefaultValue } from '@/app/components/workflow/block-selector/types'
-import { canFindTool } from '@/utils'
+import AddToolModal from '@/app/components/tools/add-tool-modal'
type AgentToolWithMoreInfo = AgentTool & { icon: any; collection?: Collection } | null
const AgentTools: FC = () => {
@@ -41,19 +33,9 @@
const formattingChangedDispatcher = useFormattingChangedDispatcher()
const [currentTool, setCurrentTool] = useState<AgentToolWithMoreInfo>(null)
- const currentCollection = useMemo(() => {
- if (!currentTool) return null
- const collection = collectionList.find(collection => canFindTool(collection.id, currentTool?.provider_id) && collection.type === currentTool?.provider_type)
- return collection
- }, [currentTool, collectionList])
const [isShowSettingTool, setIsShowSettingTool] = useState(false)
- const [isShowSettingAuth, setShowSettingAuth] = useState(false)
const tools = (modelConfig?.agentConfig?.tools as AgentTool[] || []).map((item) => {
- const collection = collectionList.find(
- collection =>
- canFindTool(collection.id, item.provider_id)
- && collection.type === item.provider_type,
- )
+ const collection = collectionList.find(collection => collection.id === item.provider_id && collection.type === item.provider_type)
const icon = collection?.icon
return {
...item,
@@ -73,40 +55,14 @@
formattingChangedDispatcher()
}
- const handleToolAuthSetting = (value: AgentToolWithMoreInfo) => {
- const newModelConfig = produce(modelConfig, (draft) => {
- const tool = (draft.agentConfig.tools).find((item: any) => item.provider_id === value?.collection?.id && item.tool_name === value?.tool_name)
- if (tool)
- (tool as AgentTool).notAuthor = false
- })
- setModelConfig(newModelConfig)
- setIsShowSettingTool(false)
- formattingChangedDispatcher()
- }
-
- const [isDeleting, setIsDeleting] = useState<number>(-1)
-
- const handleSelectTool = (tool: ToolDefaultValue) => {
- const newModelConfig = produce(modelConfig, (draft) => {
- draft.agentConfig.tools.push({
- provider_id: tool.provider_id,
- provider_type: tool.provider_type as CollectionType,
- provider_name: tool.provider_name,
- tool_name: tool.tool_name,
- tool_label: tool.tool_label,
- tool_parameters: tool.params,
- notAuthor: !tool.is_team_authorization,
- enabled: true,
- })
- })
- setModelConfig(newModelConfig)
- }
-
return (
<>
<Panel
- className={cn('mt-2', tools.length === 0 && 'pb-2')}
+ className="mt-2"
noBodySpacing={tools.length === 0}
+ headerIcon={
+ <RiHammerFill className='w-4 h-4 text-primary-500' />
+ }
title={
<div className='flex items-center'>
<div className='mr-1'>{t('appDebug.agent.tools.name')}</div>
@@ -121,181 +77,142 @@
}
headerRight={
<div className='flex items-center'>
- <div className='text-xs font-normal leading-[18px] text-text-tertiary'>{tools.filter(item => !!item.enabled).length}/{tools.length} {t('appDebug.agent.tools.enabled')}</div>
+ <div className='leading-[18px] text-xs font-normal text-gray-500'>{tools.filter((item: any) => !!item.enabled).length}/{tools.length} {t('appDebug.agent.tools.enabled')}</div>
{tools.length < MAX_TOOLS_NUM && (
<>
- <div className='ml-3 mr-1 h-3.5 w-px bg-divider-regular'></div>
- <ToolPicker
- trigger={<OperationBtn type="add" />}
- isShow={isShowChooseTool}
- onShowChange={setIsShowChooseTool}
- disabled={false}
- supportAddCustomTool
- onSelect={handleSelectTool}
- selectedTools={tools}
- />
+ <div className='ml-3 mr-1 h-3.5 w-px bg-gray-200'></div>
+ <OperationBtn type="add" onClick={() => setIsShowChooseTool(true)} />
</>
)}
</div>
}
>
- <div className='grid grid-cols-1 flex-wrap items-center justify-between gap-1 2xl:grid-cols-2'>
+ <div className='grid gap-1 grid-cols-1 2xl:grid-cols-2 items-center flex-wrap justify-between'>
{tools.map((item: AgentTool & { icon: any; collection?: Collection }, index) => (
<div key={index}
- className={cn(
- 'cursor group relative flex w-full items-center justify-between rounded-lg border-[0.5px] border-components-panel-border-subtle bg-components-panel-on-panel-item-bg p-1.5 pr-2 shadow-xs last-of-type:mb-0 hover:bg-components-panel-on-panel-item-bg-hover hover:shadow-sm',
- isDeleting === index && 'border-state-destructive-border hover:bg-state-destructive-hover',
- )}
+ className={cn((item.isDeleted || item.notAuthor) ? 'bg-white/50' : 'bg-white', (item.enabled && !item.isDeleted && !item.notAuthor) && 'shadow-xs', index > 1 && 'mt-1', 'group relative flex justify-between items-center last-of-type:mb-0 pl-2.5 py-2 pr-3 w-full rounded-lg border-[0.5px] border-gray-200 ')}
>
- <div className='flex w-0 grow items-center'>
- {item.isDeleted && <DefaultToolIcon className='h-5 w-5' />}
- {!item.isDeleted && (
- <div className={cn((item.notAuthor || !item.enabled) && 'opacity-50')}>
- {typeof item.icon === 'string' && <div className='h-5 w-5 rounded-md bg-cover bg-center' style={{ backgroundImage: `url(${item.icon})` }} />}
- {typeof item.icon !== 'string' && <AppIcon className='rounded-md' size='xs' icon={item.icon?.content} background={item.icon?.background} />}
- </div>
- )}
+ <div className='grow w-0 flex items-center'>
+ {(item.isDeleted || item.notAuthor)
+ ? (
+ <DefaultToolIcon className='w-6 h-6' />
+ )
+ : (
+ typeof item.icon === 'string'
+ ? (
+ <div
+ className='w-6 h-6 bg-cover bg-center rounded-md'
+ style={{
+ backgroundImage: `url(${item.icon})`,
+ }}
+ ></div>
+ )
+ : (
+ <AppIcon
+ className='rounded-md'
+ size='tiny'
+ icon={item.icon?.content}
+ background={item.icon?.background}
+ />
+ ))}
<div
- className={cn(
- 'system-xs-regular ml-1.5 flex w-0 grow items-center truncate',
- (item.isDeleted || item.notAuthor || !item.enabled) ? 'opacity-50' : '',
- )}
+ className={cn((item.isDeleted || item.notAuthor) ? 'line-through opacity-50' : '', 'grow w-0 ml-2 leading-[18px] text-[13px] font-medium text-gray-800 truncate')}
>
- <span className='system-xs-medium pr-1.5 text-text-secondary'>{item.provider_type === CollectionType.builtIn ? item.provider_name.split('/').pop() : item.tool_label}</span>
- <span className='text-text-tertiary'>{item.tool_label}</span>
- {!item.isDeleted && (
- <Tooltip
- needsDelay
- popupContent={
- <div className='w-[180px]'>
- <div className='mb-1.5 text-text-secondary'>{item.tool_name}</div>
- <div className='mb-1.5 text-text-tertiary'>{t('tools.toolNameUsageTip')}</div>
- <div className='cursor-pointer text-text-accent' onClick={() => copy(item.tool_name)}>{t('tools.copyToolName')}</div>
- </div>
- }
- >
- <div className='h-4 w-4'>
- <div className='ml-0.5 hidden group-hover:inline-block'>
- <RiInformation2Line className='h-4 w-4 text-text-tertiary' />
- </div>
- </div>
- </Tooltip>
- )}
+ <span className='text-gray-800 pr-2'>{item.provider_type === CollectionType.builtIn ? item.provider_name : item.tool_label}</span>
+ <Tooltip
+ popupContent={t('tools.toolNameUsageTip')}
+ >
+ <span className='text-gray-500'>{item.tool_name}</span>
+ </Tooltip>
</div>
</div>
- <div className='ml-1 flex shrink-0 items-center'>
- {item.isDeleted && (
- <div className='mr-2 flex items-center'>
- <Tooltip
- popupContent={t('tools.toolRemoved')}
- needsDelay
- >
- <div className='mr-1 cursor-pointer rounded-md p-1 hover:bg-black/5'>
- <AlertTriangle className='h-4 w-4 text-[#F79009]' />
- </div>
- </Tooltip>
- <div
- className='cursor-pointer rounded-md p-1 text-text-tertiary hover:text-text-destructive'
- onClick={() => {
+ <div className='shrink-0 ml-1 flex items-center'>
+ {(item.isDeleted || item.notAuthor)
+ ? (
+ <div className='flex items-center'>
+ <Tooltip
+ popupContent={t(`tools.${item.isDeleted ? 'toolRemoved' : 'notAuthorized'}`)}
+ needsDelay
+ >
+ <div className='mr-1 p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
+ if (item.notAuthor)
+ setIsShowChooseTool(true)
+ }}>
+ <AlertTriangle className='w-4 h-4 text-[#F79009]' />
+ </div>
+ </Tooltip>
+
+ <div className='p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
const newModelConfig = produce(modelConfig, (draft) => {
draft.agentConfig.tools.splice(index, 1)
})
setModelConfig(newModelConfig)
formattingChangedDispatcher()
- }}
- onMouseOver={() => setIsDeleting(index)}
- onMouseLeave={() => setIsDeleting(-1)}
- >
- <RiDeleteBinLine className='h-4 w-4' />
+ }}>
+ <RiDeleteBinLine className='w-4 h-4 text-gray-500' />
+ </div>
+ <div className='ml-2 mr-3 w-px h-3.5 bg-gray-200'></div>
</div>
- </div>
- )}
- {!item.isDeleted && (
- <div className='mr-2 hidden items-center gap-1 group-hover:flex'>
- {!item.notAuthor && (
+ )
+ : (
+ <div className='hidden group-hover:flex items-center'>
<Tooltip
popupContent={t('tools.setBuiltInTools.infoAndSetting')}
needsDelay
>
- <div className='cursor-pointer rounded-md p-1 hover:bg-black/5' onClick={() => {
+ <div className='p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
setCurrentTool(item)
setIsShowSettingTool(true)
}}>
- <RiEqualizer2Line className='h-4 w-4 text-text-tertiary' />
+ <InfoCircle className='w-4 h-4 text-gray-500' />
</div>
</Tooltip>
- )}
- <div
- className='cursor-pointer rounded-md p-1 text-text-tertiary hover:text-text-destructive'
- onClick={() => {
+
+ <div className='p-1 rounded-md hover:bg-black/5 cursor-pointer' onClick={() => {
const newModelConfig = produce(modelConfig, (draft) => {
draft.agentConfig.tools.splice(index, 1)
})
setModelConfig(newModelConfig)
formattingChangedDispatcher()
- }}
- onMouseOver={() => setIsDeleting(index)}
- onMouseLeave={() => setIsDeleting(-1)}
- >
- <RiDeleteBinLine className='h-4 w-4' />
+ }}>
+ <RiDeleteBinLine className='w-4 h-4 text-gray-500' />
+ </div>
+ <div className='ml-2 mr-3 w-px h-3.5 bg-gray-200'></div>
</div>
- </div>
- )}
- <div className={cn(item.isDeleted && 'opacity-50')}>
- {!item.notAuthor && (
- <Switch
- defaultValue={item.isDeleted ? false : item.enabled}
- disabled={item.isDeleted}
- size='md'
- onChange={(enabled) => {
- const newModelConfig = produce(modelConfig, (draft) => {
- (draft.agentConfig.tools[index] as any).enabled = enabled
- })
- setModelConfig(newModelConfig)
- formattingChangedDispatcher()
- }} />
)}
- {item.notAuthor && (
- <Button variant='secondary' size='small' onClick={() => {
- setCurrentTool(item)
- setShowSettingAuth(true)
- }}>
- {t('tools.notAuthorized')}
- <Indicator className='ml-2' color='orange' />
- </Button>
- )}
+ <div className={cn((item.isDeleted || item.notAuthor) && 'opacity-50')}>
+ <Switch
+ defaultValue={(item.isDeleted || item.notAuthor) ? false : item.enabled}
+ disabled={(item.isDeleted || item.notAuthor)}
+ size='md'
+ onChange={(enabled) => {
+ const newModelConfig = produce(modelConfig, (draft) => {
+ (draft.agentConfig.tools[index] as any).enabled = enabled
+ })
+ setModelConfig(newModelConfig)
+ formattingChangedDispatcher()
+ }} />
</div>
</div>
</div>
))}
</div >
</Panel >
- {isShowSettingTool && (
- <SettingBuiltInTool
- toolName={currentTool?.tool_name as string}
- setting={currentTool?.tool_parameters}
- collection={currentTool?.collection as Collection}
- isBuiltIn={currentTool?.collection?.type === CollectionType.builtIn}
- isModel={currentTool?.collection?.type === CollectionType.model}
- onSave={handleToolSettingChange}
- onHide={() => setIsShowSettingTool(false)}
- />
+ {isShowChooseTool && (
+ <AddToolModal onHide={() => setIsShowChooseTool(false)} />
)}
- {isShowSettingAuth && (
- <ConfigCredential
- collection={currentCollection as any}
- onCancel={() => setShowSettingAuth(false)}
- onSaved={async (value) => {
- await updateBuiltInToolCredential((currentCollection as any).name, value)
- Toast.notify({
- type: 'success',
- message: t('common.api.actionSuccess'),
- })
- handleToolAuthSetting(currentTool)
- setShowSettingAuth(false)
- }}
- />
- )}
+ {
+ isShowSettingTool && (
+ <SettingBuiltInTool
+ toolName={currentTool?.tool_name as string}
+ setting={currentTool?.tool_parameters as any}
+ collection={currentTool?.collection as Collection}
+ isBuiltIn={currentTool?.collection?.type === CollectionType.builtIn}
+ isModel={currentTool?.collection?.type === CollectionType.model}
+ onSave={handleToolSettingChange}
+ onHide={() => setIsShowSettingTool(false)}
+ />)
+ }
</>
)
}
--
Gitblit v1.8.0