Unverified Commit 80504660 authored by Yeuoly's avatar Yeuoly

feat: frontend support add model tool

parent 61fec52f
......@@ -89,6 +89,25 @@ class ToolModelProviderIconApi(Resource):
def get(self, provider):
icon_bytes, minetype = ToolManageService.get_model_tool_provider_icon(provider)
return send_file(io.BytesIO(icon_bytes), mimetype=minetype)
class ToolModelProviderListToolsApi(Resource):
@setup_required
@login_required
@account_initialization_required
def get(self):
user_id = current_user.id
tenant_id = current_user.current_tenant_id
parser = reqparse.RequestParser()
parser.add_argument('provider', type=str, required=True, nullable=False, location='args')
args = parser.parse_args()
return ToolManageService.list_model_tool_provider_tools(
user_id,
tenant_id,
args['provider'],
)
class ToolApiProviderAddApi(Resource):
@setup_required
......@@ -289,6 +308,7 @@ api.add_resource(ToolBuiltinProviderUpdateApi, '/workspaces/current/tool-provide
api.add_resource(ToolBuiltinProviderCredentialsSchemaApi, '/workspaces/current/tool-provider/builtin/<provider>/credentials_schema')
api.add_resource(ToolBuiltinProviderIconApi, '/workspaces/current/tool-provider/builtin/<provider>/icon')
api.add_resource(ToolModelProviderIconApi, '/workspaces/current/tool-provider/model/<provider>/icon')
api.add_resource(ToolModelProviderListToolsApi, '/workspaces/current/tool-provider/model/tools')
api.add_resource(ToolApiProviderAddApi, '/workspaces/current/tool-provider/api/add')
api.add_resource(ToolApiProviderGetRemoteSchemaApi, '/workspaces/current/tool-provider/api/remote')
api.add_resource(ToolApiProviderListToolsApi, '/workspaces/current/tool-provider/api/tools')
......
......@@ -129,13 +129,13 @@ class ModelToolProviderController(ToolProviderController):
"""
return {}
def get_tools(self, user_id: str, tanent_id: str) -> List[ModelTool]:
def get_tools(self, user_id: str, tenant_id: str) -> List[ModelTool]:
"""
returns a list of tools that the provider can provide
:return: list of tools
"""
return self._get_model_tools(tenant_id=tanent_id)
return self._get_model_tools(tenant_id=tenant_id)
def get_tool(self, tool_name: str) -> ModelTool:
"""
......
......@@ -292,6 +292,24 @@ class ToolManager:
return model_providers
@staticmethod
def get_model_provider(tenant_id: str, provider_name: str) -> ModelToolProviderController:
"""
get the model provider
:param provider_name: the name of the provider
:return: the provider
"""
# get configurations
provider_manager = ProviderManager()
configurations = provider_manager.get_configurations(tenant_id)
configuration = configurations.get(provider_name)
if configuration is None:
raise ToolProviderNotFoundError(f'model provider {provider_name} not found')
return ModelToolProviderController.from_db(configuration)
@staticmethod
def get_tool_label(tool_name: str) -> Union[I18nObject, None]:
"""
......@@ -512,4 +530,5 @@ class ToolManager:
'description': provider.description,
'credentials': masked_credentials,
'privacy_policy': provider.privacy_policy
}))
\ No newline at end of file
}))
\ No newline at end of file
......@@ -309,6 +309,30 @@ class ToolManageService:
) for tool_bundle in provider.tools
])
)
@staticmethod
def list_model_tool_provider_tools(
user_id: str, tenant_id: str, provider: str
):
"""
list model tool provider tools
"""
provider_controller = ToolManager.get_model_provider(tenant_id=tenant_id, provider_name=provider)
tools = provider_controller.get_tools(user_id=user_id, tenant_id=tenant_id)
result = [
UserTool(
author=tool.identity.author,
name=tool.identity.name,
label=tool.identity.label,
description=tool.description.human,
parameters=tool.parameters or []
) for tool in tools
]
return json.loads(
serialize_base_model_array(result)
)
@staticmethod
def update_builtin_tool_provider(
......
......@@ -32,7 +32,7 @@ const AgentTools: FC = () => {
const [selectedProviderId, setSelectedProviderId] = useState<string | undefined>(undefined)
const [isShowSettingTool, setIsShowSettingTool] = useState(false)
const tools = (modelConfig?.agentConfig?.tools as AgentTool[] || []).map((item) => {
const collection = collectionList.find(collection => collection.id === item.provider_id)
const collection = collectionList.find(collection => collection.id === item.provider_id && collection.type === item.provider_type)
const icon = collection?.icon
return {
...item,
......
......@@ -16,7 +16,7 @@ import EditCustomToolModal from './edit-custom-collection-modal'
import NoCustomTool from './info/no-custom-tool'
import NoSearchRes from './info/no-search-res'
import TabSlider from '@/app/components/base/tab-slider'
import { createCustomCollection, fetchCollectionList as doFetchCollectionList, fetchBuiltInToolList, fetchCustomToolList } from '@/service/tools'
import { createCustomCollection, fetchCollectionList as doFetchCollectionList, fetchBuiltInToolList, fetchCustomToolList, fetchModelToolList } from '@/service/tools'
import type { AgentTool } from '@/types/app'
type Props = {
......@@ -105,10 +105,14 @@ const Tools: FC<Props> = ({
const list = await fetchBuiltInToolList(currCollection.name) as Tool[]
setCurrentTools(list)
}
else {
else if (currCollection.type === CollectionType.custom) {
const list = await fetchCustomToolList(currCollection.name) as Tool[]
setCurrentTools(list)
}
else if (currCollection.type === CollectionType.model) {
const list = await fetchModelToolList(currCollection.name) as Tool[]
setCurrentTools(list)
}
}
catch (e) { }
setIsDetailLoading(false)
......@@ -180,7 +184,7 @@ const Tools: FC<Props> = ({
(showCollectionList.length > 0 || !query)
? <ToolNavList
className='mt-2 grow height-0 overflow-y-auto'
currentName={currCollection?.name || ''}
currentIndex={currCollectionIndex || 0}
list={showCollectionList}
onChosen={setCurrCollectionIndex}
/>
......
......@@ -30,7 +30,7 @@ const Header: FC<Props> = ({
const { t } = useTranslation()
const isInToolsPage = loc === LOC.tools
const isInDebugPage = !isInToolsPage
const needAuth = collection?.allow_delete
const needAuth = collection?.allow_delete || collection?.type === CollectionType.model
// const isBuiltIn = collection.type === CollectionType.builtIn
const isAuthed = collection.is_team_authorization
......@@ -51,10 +51,13 @@ const Header: FC<Props> = ({
)}
</div>
</div>
{collection.type === CollectionType.builtIn && needAuth && (
{(collection.type === CollectionType.builtIn || collection.type === CollectionType.model) && needAuth && (
<div
className={cn('cursor-pointer', 'ml-1 shrink-0 flex items-center h-8 border border-gray-200 rounded-lg px-3 space-x-2 shadow-xs')}
onClick={() => onShowAuth()}
onClick={() => {
if (collection.type === CollectionType.builtIn)
onShowAuth()
}}
>
<div className={cn(isAuthed ? 'border-[#12B76A] bg-[#32D583]' : 'border-gray-400 bg-gray-300', 'rounded h-2 w-2 border')}></div>
<div className='leading-5 text-sm font-medium text-gray-700'>{t(`tools.auth.${isAuthed ? 'authorized' : 'unauthorized'}`)}</div>
......
......@@ -42,7 +42,8 @@ const ToolList: FC<Props> = ({
const { t } = useTranslation()
const isInToolsPage = loc === LOC.tools
const isBuiltIn = collection?.type === CollectionType.builtIn
const needAuth = collection?.allow_delete
const isModel = collection?.type === CollectionType.model
const needAuth = collection?.allow_delete || collection?.type === CollectionType.model
const [showSettingAuth, setShowSettingAuth] = useState(false)
......@@ -52,6 +53,7 @@ const ToolList: FC<Props> = ({
return
(async () => {
if (collection.type === CollectionType.custom) {
console.log(collection)
const res = await fetchCustomCollection(collection.name) as any
setCustomCollection({
...res,
......@@ -120,7 +122,7 @@ const ToolList: FC<Props> = ({
<div className=''>{t('tools.includeToolNum', {
num: list.length,
})}</div>
{needAuth && isBuiltIn && !collection.is_team_authorization && (
{needAuth && (isBuiltIn || isModel) && !collection.is_team_authorization && (
<>
<div>·</div>
<div
......@@ -145,7 +147,7 @@ const ToolList: FC<Props> = ({
collection={collection}
isInToolsPage={isInToolsPage}
isToolNumMax={(addedTools?.length || 0) >= MAX_TOOLS_NUM}
added={!!addedTools?.find(v => v.provider_id === collection.id && v.tool_name === item.name)}
added={!!addedTools?.find(v => v.provider_id === collection.id && v.provider_type === collection.type && v.tool_name === item.name)}
onAdd={!isInToolsPage ? tool => onAddTool?.(collection as Collection, tool) : undefined}
/>
))}
......
......@@ -6,21 +6,21 @@ import Item from './item'
import type { Collection } from '@/app/components/tools/types'
type Props = {
className?: string
currentName: string
currentIndex: number
list: Collection[]
onChosen: (index: number) => void
}
const ToolNavList: FC<Props> = ({
className,
currentName,
currentIndex,
list,
onChosen,
}) => {
return (
<div className={cn(className)}>
{list.map((item, index) => (
<Item isCurrent={item.name === currentName} key={item.name} payload={item} onClick={() => onChosen(index)}></Item>
<Item isCurrent={index === currentIndex} key={item.name} payload={item} onClick={() => onChosen(index)}></Item>
))}
</div>
)
......
......@@ -19,6 +19,7 @@ export enum CollectionType {
all = 'all',
builtIn = 'builtin',
custom = 'api',
model = 'model',
}
export type Emoji = {
......
......@@ -12,6 +12,11 @@ export const fetchBuiltInToolList = (collectionName: string) => {
export const fetchCustomToolList = (collectionName: string) => {
return get(`/workspaces/current/tool-provider/api/tools?provider=${collectionName}`)
}
export const fetchModelToolList = (collectionName: string) => {
return get(`/workspaces/current/tool-provider/model/tools?provider=${collectionName}`)
}
export const fetchBuiltInToolCredentialSchema = (collectionName: string) => {
return get(`/workspaces/current/tool-provider/builtin/${collectionName}/credentials_schema`)
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment