Commit b6d30835 by heheer Committed by GitHub

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

parent 29e9e3fe
...@@ -84,13 +84,19 @@ const getNodeInputRenderTypeFromSchemaInputType = ({ ...@@ -84,13 +84,19 @@ const getNodeInputRenderTypeFromSchemaInputType = ({
} }
return { renderTypeList: [FlowNodeInputTypeEnum.JSONEditor, FlowNodeInputTypeEnum.reference] }; 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]) => ({ return Object.entries(jsonSchema?.properties || {}).map(([key, value]) => ({
key, key,
label: key, label: key,
valueType: getNodeInputTypeFromSchemaInputType({ type: value.type, arrayItems: value.items }), valueType: getNodeInputTypeFromSchemaInputType({ type: value.type, arrayItems: value.items }),
description: value.description, 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), required: jsonSchema?.required?.includes(key),
...getNodeInputRenderTypeFromSchemaInputType(value) ...getNodeInputRenderTypeFromSchemaInputType(value)
})); }));
......
...@@ -69,7 +69,7 @@ export const getHTTPToolRuntimeNode = ({ ...@@ -69,7 +69,7 @@ export const getHTTPToolRuntimeNode = ({
toolId: `${AppToolSourceEnum.http}-${parentId}/${tool.name}` toolId: `${AppToolSourceEnum.http}-${parentId}/${tool.name}`
} }
}, },
inputs: jsonSchema2NodeInput(tool.inputSchema), inputs: jsonSchema2NodeInput({ jsonSchema: tool.inputSchema, schemaType: 'http' }),
outputs: [ outputs: [
...jsonSchema2NodeOutput(tool.outputSchema), ...jsonSchema2NodeOutput(tool.outputSchema),
{ {
......
...@@ -62,7 +62,7 @@ export const getMCPToolRuntimeNode = ({ ...@@ -62,7 +62,7 @@ export const getMCPToolRuntimeNode = ({
toolId: `${AppToolSourceEnum.mcp}-${parentId}/${tool.name}` toolId: `${AppToolSourceEnum.mcp}-${parentId}/${tool.name}`
} }
}, },
inputs: jsonSchema2NodeInput(tool.inputSchema), inputs: jsonSchema2NodeInput({ jsonSchema: tool.inputSchema, schemaType: 'mcp' }),
outputs: [ outputs: [
{ {
id: NodeOutputKeyEnum.rawResponse, id: NodeOutputKeyEnum.rawResponse,
......
...@@ -154,13 +154,17 @@ const EditForm = ({ ...@@ -154,13 +154,17 @@ const EditForm = ({
> >
<Flex alignItems={'center'} py={3} px={3}> <Flex alignItems={'center'} py={3} px={3}>
<Box maxW={'full'} pl={2} position="relative" width="calc(100% - 30px)"> <Box maxW={'full'} pl={2} position="relative" width="calc(100% - 30px)">
<Flex alignItems="center" gap={2} mb={1}> <Flex alignItems="center" gap={2} mb={1} w={'full'}>
<Box>{renderHttpMethod(tool.method)}</Box> <Box flex={'0 0 40px'}>{renderHttpMethod(tool.method)}</Box>
<Box <Box
color={'myGray.900'} color={'myGray.900'}
fontSize={'14px'} fontSize={'14px'}
lineHeight={'20px'} lineHeight={'20px'}
letterSpacing={'0.25px'} letterSpacing={'0.25px'}
whiteSpace={'nowrap'}
overflow={'hidden'}
textOverflow={'ellipsis'}
maxW={'200px'}
> >
{tool.name} {tool.name}
</Box> </Box>
...@@ -170,6 +174,10 @@ const EditForm = ({ ...@@ -170,6 +174,10 @@ const EditForm = ({
fontSize={'14px'} fontSize={'14px'}
lineHeight={'20px'} lineHeight={'20px'}
letterSpacing={'0.25px'} letterSpacing={'0.25px'}
whiteSpace={'nowrap'}
overflow={'hidden'}
textOverflow={'ellipsis'}
maxW={'200px'}
> >
{tool.path} {tool.path}
</Box> </Box>
......
...@@ -371,7 +371,7 @@ const RenderList = React.memo(function RenderList({ ...@@ -371,7 +371,7 @@ const RenderList = React.memo(function RenderList({
objectFit={'contain'} objectFit={'contain'}
borderRadius={'sm'} 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))} {t(parseI18nString(template.name, i18n.language))}
</Box> </Box>
{isSystemTool && ( {isSystemTool && (
...@@ -408,16 +408,19 @@ const RenderList = React.memo(function RenderList({ ...@@ -408,16 +408,19 @@ const RenderList = React.memo(function RenderList({
borderRadius={'sm'} borderRadius={'sm'}
flexShrink={0} flexShrink={0}
/> />
<Box flex={'1 0 0'} ml={3}>
<Box <Box
px={3}
color={'myGray.900'} color={'myGray.900'}
fontWeight={'500'} fontWeight={'500'}
fontSize={'sm'} fontSize={'sm'}
className="textEllipsis" maxW={'200px'}
whiteSpace={'nowrap'}
overflow={'hidden'}
textOverflow={'ellipsis'}
> >
{t(parseI18nString(template.name, i18n.language))} {t(parseI18nString(template.name, i18n.language))}
</Box> </Box>
</Box> <Box flex={1} />
{selected ? ( {selected ? (
<Button <Button
......
...@@ -3,7 +3,7 @@ import type { JSONSchemaInputType } from '@fastgpt/global/core/app/jsonschema'; ...@@ -3,7 +3,7 @@ import type { JSONSchemaInputType } from '@fastgpt/global/core/app/jsonschema';
import { jsonSchema2NodeInput } from '@fastgpt/global/core/app/jsonschema'; import { jsonSchema2NodeInput } from '@fastgpt/global/core/app/jsonschema';
describe('jsonSchema2NodeInput', () => { describe('jsonSchema2NodeInput', () => {
it('should return correct node input', () => { it('should return correct node input for http schema', () => {
const jsonSchema: JSONSchemaInputType = { const jsonSchema: JSONSchemaInputType = {
type: 'object', type: 'object',
properties: { properties: {
...@@ -25,7 +25,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -25,7 +25,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'name', key: 'name',
label: 'name', label: 'name',
valueType: 'string', valueType: 'string',
toolDescription: 'name', toolDescription: undefined,
required: true, required: true,
renderTypeList: ['input', 'reference'] renderTypeList: ['input', 'reference']
}, },
...@@ -33,7 +33,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -33,7 +33,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'select', key: 'select',
label: 'select', label: 'select',
valueType: 'string', valueType: 'string',
toolDescription: 'select', toolDescription: undefined,
required: false, required: false,
value: '11', value: '11',
renderTypeList: ['select'], renderTypeList: ['select'],
...@@ -52,7 +52,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -52,7 +52,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'age', key: 'age',
label: 'age', label: 'age',
valueType: 'number', valueType: 'number',
toolDescription: 'age', toolDescription: undefined,
required: true, required: true,
renderTypeList: ['numberInput', 'reference'], renderTypeList: ['numberInput', 'reference'],
max: 100, max: 100,
...@@ -62,7 +62,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -62,7 +62,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'boolean', key: 'boolean',
label: 'boolean', label: 'boolean',
valueType: 'boolean', valueType: 'boolean',
toolDescription: 'boolean', toolDescription: undefined,
required: false, required: false,
renderTypeList: ['switch'] renderTypeList: ['switch']
}, },
...@@ -70,7 +70,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -70,7 +70,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'object', key: 'object',
label: 'object', label: 'object',
valueType: 'object', valueType: 'object',
toolDescription: 'object', toolDescription: undefined,
required: false, required: false,
renderTypeList: ['JSONEditor', 'reference'] renderTypeList: ['JSONEditor', 'reference']
}, },
...@@ -78,7 +78,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -78,7 +78,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'strArr', key: 'strArr',
label: 'strArr', label: 'strArr',
valueType: 'arrayString', valueType: 'arrayString',
toolDescription: 'strArr', toolDescription: undefined,
required: false, required: false,
renderTypeList: ['JSONEditor', 'reference'] renderTypeList: ['JSONEditor', 'reference']
}, },
...@@ -86,7 +86,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -86,7 +86,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'numArr', key: 'numArr',
label: 'numArr', label: 'numArr',
valueType: 'arrayNumber', valueType: 'arrayNumber',
toolDescription: 'numArr', toolDescription: undefined,
required: false, required: false,
renderTypeList: ['JSONEditor', 'reference'] renderTypeList: ['JSONEditor', 'reference']
}, },
...@@ -94,7 +94,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -94,7 +94,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'boolArr', key: 'boolArr',
label: 'boolArr', label: 'boolArr',
valueType: 'arrayBoolean', valueType: 'arrayBoolean',
toolDescription: 'boolArr', toolDescription: undefined,
required: false, required: false,
renderTypeList: ['JSONEditor', 'reference'] renderTypeList: ['JSONEditor', 'reference']
}, },
...@@ -102,7 +102,7 @@ describe('jsonSchema2NodeInput', () => { ...@@ -102,7 +102,7 @@ describe('jsonSchema2NodeInput', () => {
key: 'objArr', key: 'objArr',
label: 'objArr', label: 'objArr',
valueType: 'arrayObject', valueType: 'arrayObject',
toolDescription: 'objArr', toolDescription: undefined,
required: false, required: false,
renderTypeList: ['JSONEditor', 'reference'] renderTypeList: ['JSONEditor', 'reference']
}, },
...@@ -110,12 +110,56 @@ describe('jsonSchema2NodeInput', () => { ...@@ -110,12 +110,56 @@ describe('jsonSchema2NodeInput', () => {
key: 'anyArr', key: 'anyArr',
label: 'anyArr', label: 'anyArr',
valueType: 'arrayAny', valueType: 'arrayAny',
toolDescription: 'anyArr', toolDescription: undefined,
required: false, required: false,
renderTypeList: ['JSONEditor', 'reference'] 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); expect(result).toEqual(expectResponse);
}); });
......
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 sign in to comment