Skip to content

Commit deebcc4

Browse files
committed
fix(workflow): preserve tool descriptions on add
1 parent 986b2f1 commit deebcc4

9 files changed

Lines changed: 76 additions & 7 deletions

File tree

packages/global/core/app/tool/httpTool/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@ export const getHTTPToolRuntimeNode = ({
6666
flowNodeType: FlowNodeTypeEnum.tool,
6767
avatar,
6868
intro: tool.description,
69+
toolDescription: tool.description,
6970
toolConfig: {
7071
httpTool: {
7172
toolId: `${AppToolSourceEnum.http}-${toolSetId}/${tool.name}`

packages/global/core/app/tool/mcpTool/utils.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ export const getMCPToolRuntimeNode = ({
5959
flowNodeType: FlowNodeTypeEnum.tool,
6060
avatar,
6161
intro: tool.description,
62+
toolDescription: tool.description,
6263
toolConfig: {
6364
mcpTool: {
6465
toolId: `${AppToolSourceEnum.mcp}-${toolSetId}/${tool.name}` // When runtool is used, parentId and toolname will be employed

packages/global/core/workflow/type/node.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ export const NodeTemplateListItemTypeSchema = z.object({
235235
avatar: z.string().optional(),
236236
name: z.string(),
237237
intro: z.string().optional(), // template list intro
238+
toolDescription: z.string().optional(), // tool description
238239
isTool: BoolSchema.optional(),
239240

240241
authorAvatar: z.string().optional(),

packages/global/core/workflow/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,9 @@ export const toolData2FlowNodeIO = ({ nodes }: { nodes: StoreNodeItemType[] }) =
355355
return {
356356
inputs: toolNode?.inputs || [],
357357
outputs: toolNode?.outputs || [],
358-
toolConfig: toolNode?.toolConfig
358+
toolConfig: toolNode?.toolConfig,
359+
...(toolNode?.intro ? { intro: toolNode.intro } : {}),
360+
...(toolNode?.toolDescription ? { toolDescription: toolNode.toolDescription } : {})
359361
};
360362
};
361363

packages/service/core/app/tool/utils/client.ts

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,7 @@ export async function getClientSystemToolPreviewNode({
163163
];
164164
const isWorkflowTool = !!toolDetail.associatedPluginId;
165165
const toolConfigSource = isDebugToolSource(toolSource) ? toolSource : undefined;
166+
const toolDescription = toolDetail.toolDescription || toolDetail.intro;
166167

167168
return {
168169
id: getNanoid(),
@@ -176,7 +177,7 @@ export async function getClientSystemToolPreviewNode({
176177
avatar: toolDetail.avatar,
177178
name: toolDetail.name,
178179
intro: toolDetail.intro,
179-
toolDescription: toolDetail.toolDescription,
180+
toolDescription,
180181
courseUrl: toolDetail.courseUrl,
181182
readmeUrl: toolDetail.readmeUrl,
182183
userGuide: toolDetail.userGuide ?? undefined,
@@ -215,7 +216,7 @@ export async function getClientSystemToolPreviewNode({
215216
...(toolConfigSource ? { source: toolConfigSource } : {}),
216217
toolList:
217218
toolDetail.children?.map((child) => ({
218-
description: child.description ?? '',
219+
description: child.toolDescription || child.description || '',
219220
name: child.name,
220221
toolId: child.id
221222
})) ?? []
@@ -355,6 +356,8 @@ export async function getClientToolPreviewNode({
355356
avatar: item.avatar,
356357
id: appId,
357358
name: tool.name,
359+
intro: tool.description,
360+
toolDescription: tool.description,
358361
templateType: FlowNodeTemplateTypeEnum.tools,
359362
workflow: {
360363
nodes: [
@@ -401,6 +404,8 @@ export async function getClientToolPreviewNode({
401404
avatar: item.avatar,
402405
id: appId,
403406
name: tool.name,
407+
intro: tool.description,
408+
toolDescription: tool.description,
404409
templateType: FlowNodeTemplateTypeEnum.tools,
405410
workflow: {
406411
nodes: [
@@ -435,6 +440,8 @@ export async function getClientToolPreviewNode({
435440
inputs: FlowNodeInputItemType[];
436441
outputs: FlowNodeOutputItemType[];
437442
toolConfig?: NodeToolConfigType;
443+
intro?: string;
444+
toolDescription?: string;
438445
showSourceHandle?: boolean;
439446
showTargetHandle?: boolean;
440447
};

packages/service/test/core/app/tool/utils/client.test.ts

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,54 @@ describe('getClientToolPreviewNode', () => {
116116
expect(result.toolConfig?.httpTool).toEqual({
117117
toolId: 'http-507f1f77bcf86cd799439011/search'
118118
});
119+
expect(result.intro).toBe('Search tool');
120+
expect(result.toolDescription).toBe('Search tool');
119121
expect(result.inputs[0]?.key).toBe('q');
120122
expect((result as any).jsonSchema).toBeUndefined();
121123
});
124+
125+
it('writes mcp tool description onto the preview node', async () => {
126+
mocks.findById.mockReturnValueOnce({
127+
lean: vi.fn().mockResolvedValue({
128+
_id: '507f1f77bcf86cd799439011',
129+
teamId: '507f1f77bcf86cd799439012',
130+
type: AppTypeEnum.mcpToolSet,
131+
name: 'MCP Tools',
132+
avatar: 'mcp.svg',
133+
intro: 'MCP toolset'
134+
})
135+
});
136+
mocks.getAppVersionById.mockResolvedValueOnce({
137+
nodes: [
138+
{
139+
toolConfig: {
140+
mcpToolSet: {
141+
toolList: [
142+
{
143+
name: 'search',
144+
description: 'Search MCP resources',
145+
inputSchema: { type: 'object', properties: { q: { type: 'string' } } }
146+
}
147+
]
148+
}
149+
}
150+
}
151+
],
152+
edges: [],
153+
chatConfig: {},
154+
versionId: 'version-id',
155+
versionName: 'Version 1'
156+
});
157+
158+
const result = await getClientToolPreviewNode({
159+
appId: 'mcp-507f1f77bcf86cd799439011/search',
160+
lang: 'en'
161+
});
162+
163+
expect(result.intro).toBe('Search MCP resources');
164+
expect(result.toolDescription).toBe('Search MCP resources');
165+
expect(result.toolConfig?.mcpTool).toEqual({
166+
toolId: 'mcp-507f1f77bcf86cd799439011/search'
167+
});
168+
});
122169
});

packages/service/test/core/app/tool/utils/clientSystemTool.test.ts

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,8 @@ describe('getClientSystemToolPreviewNode', () => {
254254
{
255255
id: 'web',
256256
name: 'Web Search',
257-
description: 'Search web'
257+
description: 'Search web',
258+
toolDescription: 'Search web for model'
258259
}
259260
]
260261
});
@@ -269,7 +270,14 @@ describe('getClientSystemToolPreviewNode', () => {
269270
expect(result.source).toBe('debug:tmbId:tmb-1');
270271
expect(result.toolConfig?.systemToolSet).toMatchObject({
271272
toolId: 'systemTool-search',
272-
source: 'debug:tmbId:tmb-1'
273+
source: 'debug:tmbId:tmb-1',
274+
toolList: [
275+
{
276+
toolId: 'web',
277+
name: 'Web Search',
278+
description: 'Search web for model'
279+
}
280+
]
273281
});
274282
});
275283

projects/app/src/pages/api/core/app/tool/getSystemToolTemplates.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ export async function handler(
6767
flowNodeType: FlowNodeTypeEnum.tool,
6868
name: child.name,
6969
intro: child.description,
70-
toolDescription: child.toolDescription,
70+
toolDescription: child.toolDescription || child.description,
7171
id: `${parentId}/${child.id}`,
7272
source: parent.source,
7373
avatar: child.icon ?? parent.avatar,
@@ -107,7 +107,7 @@ export async function handler(
107107
name: tool.name,
108108
intro: tool.intro,
109109
instructions: tool.userGuide ?? '',
110-
toolDescription: tool.toolDescription,
110+
toolDescription: tool.toolDescription || tool.intro,
111111
tags: tool.tags
112112
}))
113113
.filter((item) => filterTemplateBySearchKey(item, searchRegex));

projects/app/test/api/core/app/tool/getSystemToolTemplates.test.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ describe('get system tool templates handler', () => {
107107
} as ApiRequestProps<GetSystemPluginTemplatesBody>);
108108

109109
expect(result.map((item) => item.id)).toEqual(['weather']);
110+
expect(result[0]?.toolDescription).toBe('Get weather');
110111
expect(mocks.getSystemToolList).toHaveBeenCalledWith({
111112
lang: 'zh',
112113
op: 'or',
@@ -244,6 +245,7 @@ describe('get system tool templates handler', () => {
244245
expect(result.map((item) => item.id)).toEqual(['toolset/plus']);
245246
expect(result[0]).toMatchObject({
246247
avatar: 'plus-icon',
248+
toolDescription: 'Use literal plus',
247249
currentCost: 2,
248250
systemKeyCost: 0.5,
249251
hasTokenFee: true

0 commit comments

Comments
 (0)