mirror of
https://github.com/labring/FastGPT.git
synced 2025-07-27 08:25:07 +00:00
perf: mcp save raw schema (#5030)
* perf: mcp save raw schema * fix: test * code * perf: json schema test * perf: mcp
This commit is contained in:
86
packages/global/core/app/jsonschema.ts
Normal file
86
packages/global/core/app/jsonschema.ts
Normal file
@@ -0,0 +1,86 @@
|
||||
import { WorkflowIOValueTypeEnum } from '../workflow/constants';
|
||||
import { FlowNodeInputTypeEnum } from '../workflow/node/constant';
|
||||
import type { FlowNodeInputItemType } from '../workflow/type/io';
|
||||
|
||||
type SchemaInputValueType = 'string' | 'number' | 'integer' | 'boolean' | 'array' | 'object';
|
||||
export type JsonSchemaPropertiesItemType = {
|
||||
description?: string;
|
||||
type: SchemaInputValueType;
|
||||
enum?: string[];
|
||||
minimum?: number;
|
||||
maximum?: number;
|
||||
items?: { type: SchemaInputValueType };
|
||||
};
|
||||
export type JSONSchemaInputType = {
|
||||
type: SchemaInputValueType;
|
||||
properties?: Record<string, JsonSchemaPropertiesItemType>;
|
||||
required?: string[];
|
||||
};
|
||||
|
||||
const getNodeInputTypeFromSchemaInputType = ({
|
||||
type,
|
||||
arrayItems
|
||||
}: {
|
||||
type: SchemaInputValueType;
|
||||
arrayItems?: { type: SchemaInputValueType };
|
||||
}) => {
|
||||
if (type === 'string') return WorkflowIOValueTypeEnum.string;
|
||||
if (type === 'number') return WorkflowIOValueTypeEnum.number;
|
||||
if (type === 'integer') return WorkflowIOValueTypeEnum.number;
|
||||
if (type === 'boolean') return WorkflowIOValueTypeEnum.boolean;
|
||||
if (type === 'object') return WorkflowIOValueTypeEnum.object;
|
||||
|
||||
if (!arrayItems) return WorkflowIOValueTypeEnum.arrayAny;
|
||||
|
||||
const itemType = arrayItems.type;
|
||||
if (itemType === 'string') return WorkflowIOValueTypeEnum.arrayString;
|
||||
if (itemType === 'number') return WorkflowIOValueTypeEnum.arrayNumber;
|
||||
if (itemType === 'integer') return WorkflowIOValueTypeEnum.arrayNumber;
|
||||
if (itemType === 'boolean') return WorkflowIOValueTypeEnum.arrayBoolean;
|
||||
if (itemType === 'object') return WorkflowIOValueTypeEnum.arrayObject;
|
||||
|
||||
return WorkflowIOValueTypeEnum.arrayAny;
|
||||
};
|
||||
const getNodeInputRenderTypeFromSchemaInputType = ({
|
||||
type,
|
||||
enum: enumList,
|
||||
minimum,
|
||||
maximum
|
||||
}: JsonSchemaPropertiesItemType) => {
|
||||
if (enumList && enumList.length > 0) {
|
||||
return {
|
||||
value: enumList[0],
|
||||
renderTypeList: [FlowNodeInputTypeEnum.select],
|
||||
list: enumList.map((item) => ({ label: item, value: item }))
|
||||
};
|
||||
}
|
||||
if (type === 'string') {
|
||||
return {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.input]
|
||||
};
|
||||
}
|
||||
if (type === 'number') {
|
||||
return {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.numberInput],
|
||||
max: maximum,
|
||||
min: minimum
|
||||
};
|
||||
}
|
||||
if (type === 'boolean') {
|
||||
return {
|
||||
renderTypeList: [FlowNodeInputTypeEnum.switch]
|
||||
};
|
||||
}
|
||||
return { renderTypeList: [FlowNodeInputTypeEnum.JSONEditor] };
|
||||
};
|
||||
export const jsonSchema2NodeInput = (jsonSchema: JSONSchemaInputType): 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.description || key,
|
||||
required: jsonSchema?.required?.includes(key),
|
||||
...getNodeInputRenderTypeFromSchemaInputType(value)
|
||||
}));
|
||||
};
|
12
packages/global/core/app/mcpTools/type.d.ts
vendored
Normal file
12
packages/global/core/app/mcpTools/type.d.ts
vendored
Normal file
@@ -0,0 +1,12 @@
|
||||
import type { McpToolConfigType } from '../type';
|
||||
|
||||
export type McpToolSetDataType = {
|
||||
url: string;
|
||||
headerSecret?: StoreSecretValueType;
|
||||
toolList: McpToolConfigType[];
|
||||
};
|
||||
|
||||
export type McpToolDataType = McpToolConfigType & {
|
||||
url: string;
|
||||
headerSecret?: StoreSecretValueType;
|
||||
};
|
@@ -1,4 +1,8 @@
|
||||
import { NodeOutputKeyEnum, WorkflowIOValueTypeEnum } from '../../workflow/constants';
|
||||
import {
|
||||
NodeInputKeyEnum,
|
||||
NodeOutputKeyEnum,
|
||||
WorkflowIOValueTypeEnum
|
||||
} from '../../workflow/constants';
|
||||
import {
|
||||
FlowNodeInputTypeEnum,
|
||||
FlowNodeOutputTypeEnum,
|
||||
@@ -9,6 +13,7 @@ import { type McpToolConfigType } from '../type';
|
||||
import { i18nT } from '../../../../web/i18n/utils';
|
||||
import { type RuntimeNodeItemType } from '../../workflow/runtime/type';
|
||||
import { type StoreSecretValueType } from '../../../common/secret/type';
|
||||
import { jsonSchema2NodeInput } from '../jsonschema';
|
||||
|
||||
export const getMCPToolSetRuntimeNode = ({
|
||||
url,
|
||||
@@ -30,14 +35,14 @@ export const getMCPToolSetRuntimeNode = ({
|
||||
intro: 'MCP Tools',
|
||||
inputs: [
|
||||
{
|
||||
key: 'toolSetData',
|
||||
key: NodeInputKeyEnum.toolSetData,
|
||||
label: 'Tool Set Data',
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
value: {
|
||||
url,
|
||||
toolList,
|
||||
headerSecret
|
||||
headerSecret,
|
||||
toolList
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -65,7 +70,7 @@ export const getMCPToolRuntimeNode = ({
|
||||
intro: tool.description,
|
||||
inputs: [
|
||||
{
|
||||
key: 'toolData',
|
||||
key: NodeInputKeyEnum.toolData,
|
||||
label: 'Tool Data',
|
||||
valueType: WorkflowIOValueTypeEnum.object,
|
||||
renderTypeList: [FlowNodeInputTypeEnum.hidden],
|
||||
@@ -75,23 +80,7 @@ export const getMCPToolRuntimeNode = ({
|
||||
headerSecret
|
||||
}
|
||||
},
|
||||
...Object.entries(tool.inputSchema?.properties || {}).map(([key, value]) => ({
|
||||
key,
|
||||
label: key,
|
||||
valueType: value.type as WorkflowIOValueTypeEnum, // TODO: 这里需要做一个映射
|
||||
description: value.description,
|
||||
toolDescription: value.description || key,
|
||||
required: tool.inputSchema?.required?.includes(key) || false,
|
||||
renderTypeList: [
|
||||
value.type === 'string'
|
||||
? FlowNodeInputTypeEnum.input
|
||||
: value.type === 'number'
|
||||
? FlowNodeInputTypeEnum.numberInput
|
||||
: value.type === 'boolean'
|
||||
? FlowNodeInputTypeEnum.switch
|
||||
: FlowNodeInputTypeEnum.JSONEditor
|
||||
]
|
||||
}))
|
||||
...jsonSchema2NodeInput(tool.inputSchema)
|
||||
],
|
||||
outputs: [
|
||||
{
|
||||
|
7
packages/global/core/app/type.d.ts
vendored
7
packages/global/core/app/type.d.ts
vendored
@@ -15,6 +15,7 @@ import type { ParentIdType } from '../../common/parentFolder/type';
|
||||
import { FlowNodeInputTypeEnum } from '../../core/workflow/node/constant';
|
||||
import type { WorkflowTemplateBasicType } from '@fastgpt/global/core/workflow/type';
|
||||
import type { SourceMemberType } from '../../support/user/type';
|
||||
import type { JSONSchemaInputType } from './jsonschema';
|
||||
|
||||
export type AppSchema = {
|
||||
_id: string;
|
||||
@@ -110,11 +111,7 @@ export type AppSimpleEditFormType = {
|
||||
export type McpToolConfigType = {
|
||||
name: string;
|
||||
description: string;
|
||||
inputSchema: {
|
||||
type: string;
|
||||
properties?: Record<string, { type: string; description?: string }>;
|
||||
required?: string[];
|
||||
};
|
||||
inputSchema: JSONSchemaInputType;
|
||||
};
|
||||
|
||||
/* app chat config type */
|
||||
|
Reference in New Issue
Block a user