mirror of
https://github.com/labring/FastGPT.git
synced 2025-12-25 20:02:47 +00:00
fix: mcp tool description & tool select ui (#5948)
This commit is contained in:
parent
29e9e3fecd
commit
b6d3083585
|
|
@ -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)
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
});
|
||||
|
|
|
|||
Loading…
Reference in New Issue