fix: mcp tool description & tool select ui (#5948)

This commit is contained in:
heheer 2025-11-18 16:43:45 +08:00 committed by GitHub
parent 29e9e3fecd
commit b6d3083585
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 89 additions and 28 deletions

View File

@ -84,13 +84,19 @@ const getNodeInputRenderTypeFromSchemaInputType = ({
}
return { renderTypeList: [FlowNodeInputTypeEnum.JSONEditor, FlowNodeInputTypeEnum.reference] };
};
export const jsonSchema2NodeInput = (jsonSchema: JSONSchemaInputType): FlowNodeInputItemType[] => {
export const jsonSchema2NodeInput = ({
jsonSchema,
schemaType
}: {
jsonSchema: JSONSchemaInputType;
schemaType: 'mcp' | 'http';
}): FlowNodeInputItemType[] => {
return Object.entries(jsonSchema?.properties || {}).map(([key, value]) => ({
key,
label: key,
valueType: getNodeInputTypeFromSchemaInputType({ type: value.type, arrayItems: value.items }),
description: value.description,
toolDescription: value['x-tool-description'] ?? value.description ?? key,
toolDescription: schemaType === 'http' ? value['x-tool-description'] : value.description || key,
required: jsonSchema?.required?.includes(key),
...getNodeInputRenderTypeFromSchemaInputType(value)
}));

View File

@ -69,7 +69,7 @@ export const getHTTPToolRuntimeNode = ({
toolId: `${AppToolSourceEnum.http}-${parentId}/${tool.name}`
}
},
inputs: jsonSchema2NodeInput(tool.inputSchema),
inputs: jsonSchema2NodeInput({ jsonSchema: tool.inputSchema, schemaType: 'http' }),
outputs: [
...jsonSchema2NodeOutput(tool.outputSchema),
{

View File

@ -62,7 +62,7 @@ export const getMCPToolRuntimeNode = ({
toolId: `${AppToolSourceEnum.mcp}-${parentId}/${tool.name}`
}
},
inputs: jsonSchema2NodeInput(tool.inputSchema),
inputs: jsonSchema2NodeInput({ jsonSchema: tool.inputSchema, schemaType: 'mcp' }),
outputs: [
{
id: NodeOutputKeyEnum.rawResponse,

View File

@ -154,13 +154,17 @@ const EditForm = ({
>
<Flex alignItems={'center'} py={3} px={3}>
<Box maxW={'full'} pl={2} position="relative" width="calc(100% - 30px)">
<Flex alignItems="center" gap={2} mb={1}>
<Box>{renderHttpMethod(tool.method)}</Box>
<Flex alignItems="center" gap={2} mb={1} w={'full'}>
<Box flex={'0 0 40px'}>{renderHttpMethod(tool.method)}</Box>
<Box
color={'myGray.900'}
fontSize={'14px'}
lineHeight={'20px'}
letterSpacing={'0.25px'}
whiteSpace={'nowrap'}
overflow={'hidden'}
textOverflow={'ellipsis'}
maxW={'200px'}
>
{tool.name}
</Box>
@ -170,6 +174,10 @@ const EditForm = ({
fontSize={'14px'}
lineHeight={'20px'}
letterSpacing={'0.25px'}
whiteSpace={'nowrap'}
overflow={'hidden'}
textOverflow={'ellipsis'}
maxW={'200px'}
>
{tool.path}
</Box>

View File

@ -371,7 +371,7 @@ const RenderList = React.memo(function RenderList({
objectFit={'contain'}
borderRadius={'sm'}
/>
<Box fontWeight={'bold'} ml={3} color={'myGray.900'} flex={'1'}>
<Box fontWeight={'bold'} ml={3} color={'myGray.900'} overflow={'hidden'}>
{t(parseI18nString(template.name, i18n.language))}
</Box>
{isSystemTool && (
@ -408,16 +408,19 @@ const RenderList = React.memo(function RenderList({
borderRadius={'sm'}
flexShrink={0}
/>
<Box flex={'1 0 0'} ml={3}>
<Box
color={'myGray.900'}
fontWeight={'500'}
fontSize={'sm'}
className="textEllipsis"
>
{t(parseI18nString(template.name, i18n.language))}
</Box>
<Box
px={3}
color={'myGray.900'}
fontWeight={'500'}
fontSize={'sm'}
maxW={'200px'}
whiteSpace={'nowrap'}
overflow={'hidden'}
textOverflow={'ellipsis'}
>
{t(parseI18nString(template.name, i18n.language))}
</Box>
<Box flex={1} />
{selected ? (
<Button

View File

@ -3,7 +3,7 @@ import type { JSONSchemaInputType } from '@fastgpt/global/core/app/jsonschema';
import { jsonSchema2NodeInput } from '@fastgpt/global/core/app/jsonschema';
describe('jsonSchema2NodeInput', () => {
it('should return correct node input', () => {
it('should return correct node input for http schema', () => {
const jsonSchema: JSONSchemaInputType = {
type: 'object',
properties: {
@ -25,7 +25,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'name',
label: 'name',
valueType: 'string',
toolDescription: 'name',
toolDescription: undefined,
required: true,
renderTypeList: ['input', 'reference']
},
@ -33,7 +33,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'select',
label: 'select',
valueType: 'string',
toolDescription: 'select',
toolDescription: undefined,
required: false,
value: '11',
renderTypeList: ['select'],
@ -52,7 +52,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'age',
label: 'age',
valueType: 'number',
toolDescription: 'age',
toolDescription: undefined,
required: true,
renderTypeList: ['numberInput', 'reference'],
max: 100,
@ -62,7 +62,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'boolean',
label: 'boolean',
valueType: 'boolean',
toolDescription: 'boolean',
toolDescription: undefined,
required: false,
renderTypeList: ['switch']
},
@ -70,7 +70,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'object',
label: 'object',
valueType: 'object',
toolDescription: 'object',
toolDescription: undefined,
required: false,
renderTypeList: ['JSONEditor', 'reference']
},
@ -78,7 +78,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'strArr',
label: 'strArr',
valueType: 'arrayString',
toolDescription: 'strArr',
toolDescription: undefined,
required: false,
renderTypeList: ['JSONEditor', 'reference']
},
@ -86,7 +86,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'numArr',
label: 'numArr',
valueType: 'arrayNumber',
toolDescription: 'numArr',
toolDescription: undefined,
required: false,
renderTypeList: ['JSONEditor', 'reference']
},
@ -94,7 +94,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'boolArr',
label: 'boolArr',
valueType: 'arrayBoolean',
toolDescription: 'boolArr',
toolDescription: undefined,
required: false,
renderTypeList: ['JSONEditor', 'reference']
},
@ -102,7 +102,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'objArr',
label: 'objArr',
valueType: 'arrayObject',
toolDescription: 'objArr',
toolDescription: undefined,
required: false,
renderTypeList: ['JSONEditor', 'reference']
},
@ -110,12 +110,56 @@ describe('jsonSchema2NodeInput', () => {
key: 'anyArr',
label: 'anyArr',
valueType: 'arrayAny',
toolDescription: 'anyArr',
toolDescription: undefined,
required: false,
renderTypeList: ['JSONEditor', 'reference']
}
];
const result = jsonSchema2NodeInput(jsonSchema);
const result = jsonSchema2NodeInput({ jsonSchema, schemaType: 'http' });
expect(result).toEqual(expectResponse);
});
it('should return correct node input for mcp schema', () => {
const jsonSchema: JSONSchemaInputType = {
type: 'object',
properties: {
name: { type: 'string', description: 'User name' },
age: { type: 'number', minimum: 0, maximum: 100 },
withoutDesc: { type: 'string' }
},
required: ['name']
};
const expectResponse = [
{
key: 'name',
label: 'name',
valueType: 'string',
description: 'User name',
toolDescription: 'User name',
required: true,
renderTypeList: ['input', 'reference']
},
{
key: 'age',
label: 'age',
valueType: 'number',
toolDescription: 'age',
required: false,
renderTypeList: ['numberInput', 'reference'],
max: 100,
min: 0
},
{
key: 'withoutDesc',
label: 'withoutDesc',
valueType: 'string',
toolDescription: 'withoutDesc',
required: false,
renderTypeList: ['input', 'reference']
}
];
const result = jsonSchema2NodeInput({ jsonSchema, schemaType: 'mcp' });
expect(result).toEqual(expectResponse);
});