Skip to content

Commit 025b3da

Browse files
authored
fix: http tool schema (#6768)
* fix: http tool schema * perf: del dataset * perf: review * add test
1 parent 7506a14 commit 025b3da

14 files changed

Lines changed: 771 additions & 49 deletions

File tree

document/content/docs/self-host/upgrading/4-14/41410.mdx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,12 +9,13 @@ description: 'FastGPT V4.14.10 更新说明'
99

1010
以下针对的是 `docker compose` 部署方案的配置调整,使用`sealos`的商业版用户,可私信支持人员,提供在线的沙盒服务方案。
1111

12-
打开[最新 yml 部署文件](https://github.com/labring/FastGPT/blob/main/deploy/docker/cn/docker-compose.pg.yml)调整以下内容
12+
参考[最新 yml 部署文件](https://github.com/labring/FastGPT/blob/main/deploy/docker/cn/docker-compose.pg.yml)调整本地 yml 文件,加入以下内容
1313

1414
1. 在文件顶部增加 `x-volume-manager-auth-token: &x-volume-manager-auth-token 'vmtoken'` 变量配置。
15-
2. 增加 3 组 services: `opensandbox-server`,`volume-manager`,`agent-sandbox-image`
16-
3. 增加 `configs`, 文件底部可找到该内容,直接复制添加。
17-
4. 修改 `fastgpt-app`/`fastgpt-pro` 环境变量, 增加以下变量:
15+
2. 增加 5 组 services: `opensandbox-server`,`opensandbox-agent-sandbox-image`,`opensandbox-execd-image`,`opensandbox-egress-image`,`fastgpt-volume-manager`
16+
3. 调整 `networks`,可参考最新的 yml 完全修改。
17+
4. 增加 `configs`配置, 文件底部可找到该内容,直接复制添加。
18+
5. 修改 `fastgpt-app`/`fastgpt-pro` 环境变量, 增加以下变量:
1819

1920
```bash
2021
# ==================== Agent sandbox 配置 ====================
@@ -25,6 +26,7 @@ AGENT_SANDBOX_OPENSANDBOX_API_KEY:
2526
AGENT_SANDBOX_OPENSANDBOX_RUNTIME: docker
2627
AGENT_SANDBOX_OPENSANDBOX_IMAGE_REPO: registry.cn-hangzhou.aliyuncs.com/fastgpt/fastgpt-agent-sandbox
2728
AGENT_SANDBOX_OPENSANDBOX_IMAGE_TAG: v0.1
29+
AGENT_SANDBOX_OPENSANDBOX_USE_SERVER_PROXY: true
2830
# Volume 持久化配置(opensandbox provider 下可选)
2931
AGENT_SANDBOX_ENABLE_VOLUME: true
3032
AGENT_SANDBOX_VOLUME_MANAGER_URL: http://volume-manager:3000
@@ -39,7 +41,7 @@ AGENT_SANDBOX_VOLUME_MANAGER_TOKEN: *x-volume-manager-auth-token
3941

4042
### 3. 更新镜像 tag
4143

42-
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.10.2
44+
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.10.4
4345
- 更新 fastpgt-pro(商业版) 镜像 tag: v4.14.10
4446
- 更新 code-sandbox 镜像 tag: v4.14.10
4547
- 更新 fastgpt-plugin 镜像 tag: v0.5.6

document/content/docs/self-host/upgrading/4-14/41411.mdx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,4 +39,4 @@ description: 'FastGPT V4.14.11 更新说明'
3939
8. 工作流代码运行节点,AI 生成代码后,会讲输出值的 id 全部替换,优化成相同 key 的 id 不替换。
4040
9. 工作流中,父级节点受到辅助线自动对齐时候,其子节点位置会偏移。
4141
10. 评估列表权限过滤未覆盖继承权限。
42-
11. MCP 工具 raw schema 未成功保存,导致工具调用时候,schema 不准确。
42+
11. MCP 工具和 Http 工具 raw schema 未成功保存,导致工具调用时候,schema 不准确。

document/data/doc-last-modified.json

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,8 @@
7373
"document/content/docs/introduction/guide/dashboard/workflow/laf.mdx": "2025-07-23T21:35:03+08:00",
7474
"document/content/docs/introduction/guide/dashboard/workflow/loop.en.mdx": "2026-02-26T22:14:30+08:00",
7575
"document/content/docs/introduction/guide/dashboard/workflow/loop.mdx": "2025-09-17T22:29:56+08:00",
76-
"document/content/docs/introduction/guide/dashboard/workflow/parallel_run.en.mdx": "2026-04-17T15:12:11+08:00",
77-
"document/content/docs/introduction/guide/dashboard/workflow/parallel_run.mdx": "2026-04-17T15:12:11+08:00",
76+
"document/content/docs/introduction/guide/dashboard/workflow/parallel_run.en.mdx": "2026-04-17T23:28:43+08:00",
77+
"document/content/docs/introduction/guide/dashboard/workflow/parallel_run.mdx": "2026-04-17T23:28:43+08:00",
7878
"document/content/docs/introduction/guide/dashboard/workflow/question_classify.en.mdx": "2026-02-26T22:14:30+08:00",
7979
"document/content/docs/introduction/guide/dashboard/workflow/question_classify.mdx": "2025-07-23T21:35:03+08:00",
8080
"document/content/docs/introduction/guide/dashboard/workflow/reply.en.mdx": "2026-02-26T22:14:30+08:00",
@@ -155,8 +155,8 @@
155155
"document/content/docs/self-host/config/model/minimax.mdx": "2026-03-19T09:32:57-05:00",
156156
"document/content/docs/self-host/config/model/siliconCloud.en.mdx": "2026-03-19T14:09:03+08:00",
157157
"document/content/docs/self-host/config/model/siliconCloud.mdx": "2026-03-19T14:09:03+08:00",
158-
"document/content/docs/self-host/config/object-storage.en.mdx": "2026-04-13T17:52:30+08:00",
159-
"document/content/docs/self-host/config/object-storage.mdx": "2026-04-13T17:52:30+08:00",
158+
"document/content/docs/self-host/config/object-storage.en.mdx": "2026-04-17T23:28:43+08:00",
159+
"document/content/docs/self-host/config/object-storage.mdx": "2026-04-17T23:28:43+08:00",
160160
"document/content/docs/self-host/config/signoz.en.mdx": "2026-03-03T17:39:47+08:00",
161161
"document/content/docs/self-host/config/signoz.mdx": "2026-03-03T17:39:47+08:00",
162162
"document/content/docs/self-host/custom-models/bge-rerank.en.mdx": "2026-03-03T17:39:47+08:00",
@@ -175,8 +175,8 @@
175175
"document/content/docs/self-host/custom-models/ollama.mdx": "2026-03-03T17:39:47+08:00",
176176
"document/content/docs/self-host/custom-models/xinference.en.mdx": "2026-03-30T10:05:42+08:00",
177177
"document/content/docs/self-host/custom-models/xinference.mdx": "2026-03-30T10:05:42+08:00",
178-
"document/content/docs/self-host/deploy/docker.en.mdx": "2026-04-16T15:22:51+08:00",
179-
"document/content/docs/self-host/deploy/docker.mdx": "2026-04-16T15:22:51+08:00",
178+
"document/content/docs/self-host/deploy/docker.en.mdx": "2026-04-17T23:28:43+08:00",
179+
"document/content/docs/self-host/deploy/docker.mdx": "2026-04-17T23:28:43+08:00",
180180
"document/content/docs/self-host/deploy/sealos.en.mdx": "2026-03-03T17:39:47+08:00",
181181
"document/content/docs/self-host/deploy/sealos.mdx": "2026-03-03T17:39:47+08:00",
182182
"document/content/docs/self-host/design/dataset.en.mdx": "2026-03-03T17:39:47+08:00",
@@ -223,8 +223,8 @@
223223
"document/content/docs/self-host/upgrading/4-14/4141.en.mdx": "2026-03-03T17:39:47+08:00",
224224
"document/content/docs/self-host/upgrading/4-14/4141.mdx": "2026-03-03T17:39:47+08:00",
225225
"document/content/docs/self-host/upgrading/4-14/41410.en.mdx": "2026-03-31T23:15:29+08:00",
226-
"document/content/docs/self-host/upgrading/4-14/41410.mdx": "2026-04-08T16:15:25+08:00",
227-
"document/content/docs/self-host/upgrading/4-14/41411.mdx": "2026-04-17T17:46:20+08:00",
226+
"document/content/docs/self-host/upgrading/4-14/41410.mdx": "2026-04-18T19:42:07+08:00",
227+
"document/content/docs/self-host/upgrading/4-14/41411.mdx": "2026-04-18T19:42:07+08:00",
228228
"document/content/docs/self-host/upgrading/4-14/4142.en.mdx": "2026-03-03T17:39:47+08:00",
229229
"document/content/docs/self-host/upgrading/4-14/4142.mdx": "2026-03-03T17:39:47+08:00",
230230
"document/content/docs/self-host/upgrading/4-14/4143.en.mdx": "2026-03-03T17:39:47+08:00",
@@ -385,8 +385,8 @@
385385
"document/content/docs/self-host/upgrading/outdated/499.mdx": "2026-03-03T17:39:47+08:00",
386386
"document/content/docs/self-host/upgrading/upgrade-intruction.en.mdx": "2026-03-03T17:39:47+08:00",
387387
"document/content/docs/self-host/upgrading/upgrade-intruction.mdx": "2026-03-03T17:39:47+08:00",
388-
"document/content/docs/toc.en.mdx": "2026-04-17T15:12:11+08:00",
389-
"document/content/docs/toc.mdx": "2026-04-17T15:12:11+08:00",
388+
"document/content/docs/toc.en.mdx": "2026-04-17T23:28:43+08:00",
389+
"document/content/docs/toc.mdx": "2026-04-17T23:28:43+08:00",
390390
"document/content/docs/use-cases/app-cases/dalle3.en.mdx": "2026-02-26T22:14:30+08:00",
391391
"document/content/docs/use-cases/app-cases/dalle3.mdx": "2025-07-23T21:35:03+08:00",
392392
"document/content/docs/use-cases/app-cases/english_essay_correction_bot.en.mdx": "2026-02-26T22:14:30+08:00",

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

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import { type StoreSecretValueType } from '../../../../common/secret/type';
88
import { type JsonSchemaPropertiesItemType } from '../../jsonschema';
99
import { NodeOutputKeyEnum, WorkflowIOValueTypeEnum } from '../../../workflow/constants';
1010
import { i18nT } from '../../../../../web/i18n/utils';
11+
import type { NodeToolConfigType } from '../../../workflow/type/node';
1112

1213
export const getHTTPToolSetRuntimeNode = ({
1314
name,
@@ -89,6 +90,25 @@ export const getHTTPToolRuntimeNode = ({
8990
};
9091
};
9192

93+
export const parseHttpToolConfig = (
94+
config: NonNullable<NodeToolConfigType['httpTool']>
95+
):
96+
| {
97+
toolsetId: string;
98+
toolName: string;
99+
}
100+
| undefined => {
101+
const prefix = `${AppToolSourceEnum.http}-`;
102+
if (!config.toolId.startsWith(prefix)) return undefined;
103+
const [toolsetId, ...rest] = config.toolId.slice(prefix.length).split('/');
104+
const toolName = rest.join('/');
105+
if (!toolsetId || !toolName) return undefined;
106+
return {
107+
toolsetId,
108+
toolName
109+
};
110+
};
111+
92112
export const pathData2ToolList = async (
93113
pathData: PathDataType[]
94114
): Promise<HttpToolConfigType[]> => {

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,8 @@ export const parsetMcpToolConfig = (
9292
| undefined => {
9393
const prefix = `${AppToolSourceEnum.mcp}-`;
9494
if (!config.toolId.startsWith(prefix)) return undefined;
95-
const [toolsetId, toolName] = config.toolId.slice(prefix.length).split('/');
95+
const [toolsetId, ...rest] = config.toolId.slice(prefix.length).split('/');
96+
const toolName = rest.join('/');
9697
if (!toolsetId || !toolName) return undefined;
9798
return {
9899
toolsetId,
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import type { AppSchemaType } from '@fastgpt/global/core/app/type';
2+
import { MongoApp } from '../../schema';
3+
4+
export const getHttpToolsets = ({
5+
teamId,
6+
ids,
7+
field
8+
}: {
9+
teamId: string;
10+
ids: string[];
11+
field?: Record<string, boolean>;
12+
}): Promise<AppSchemaType[]> => {
13+
return MongoApp.find({ teamId, _id: { $in: ids } }, field).lean();
14+
};

packages/service/core/app/tool/mcpTool/entity.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { AppSchemaType } from '@fastgpt/global/core/app/type';
12
import { MongoApp } from '../../schema';
23

34
export const getMcpToolsets = ({
@@ -8,6 +9,6 @@ export const getMcpToolsets = ({
89
teamId: string;
910
ids: string[];
1011
field?: Record<string, boolean>;
11-
}) => {
12+
}): Promise<AppSchemaType[]> => {
1213
return MongoApp.find({ teamId, _id: { $in: ids } }, field).lean();
1314
};

packages/service/core/dataset/delete/processor.ts

Lines changed: 25 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -43,25 +43,32 @@ export const deleteTeamAllDatasets = async (teamId: string) => {
4343
teamId,
4444
datasetIds: datasets.map((d) => d._id)
4545
});
46-
await MongoDataset.updateMany(
47-
{
48-
teamId
49-
},
50-
{
51-
$set: {
52-
deleteTime: new Date()
46+
47+
await mongoSessionRun(async (session) => {
48+
await MongoDataset.updateMany(
49+
{
50+
teamId
51+
},
52+
{
53+
$set: {
54+
deleteTime: new Date()
55+
}
56+
},
57+
{
58+
session
5359
}
54-
}
55-
);
56-
await Promise.all(
57-
datasets.map((dataset) => {
58-
if (dataset.parentId) return;
59-
return addDatasetDeleteJob({
60-
teamId,
61-
datasetId: dataset._id
62-
});
63-
})
64-
);
60+
);
61+
await Promise.all(
62+
datasets.map((dataset) => {
63+
// 有 parentId 的忽略,只需要删 root 下的即可。
64+
if (dataset.parentId) return;
65+
return addDatasetDeleteJob({
66+
teamId,
67+
datasetId: dataset._id
68+
});
69+
})
70+
);
71+
});
6572
};
6673

6774
// 批量删除函数

packages/service/core/workflow/dispatch/utils.ts

Lines changed: 47 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,10 @@ import {
2525
import { getNanoid } from '@fastgpt/global/common/string/tools';
2626
import { type SearchDataResponseItemType } from '@fastgpt/global/core/dataset/type';
2727
import { getMCPToolRuntimeNode } from '@fastgpt/global/core/app/tool/mcpTool/utils';
28-
import { getHTTPToolRuntimeNode } from '@fastgpt/global/core/app/tool/httpTool/utils';
28+
import {
29+
getHTTPToolRuntimeNode,
30+
parseHttpToolConfig
31+
} from '@fastgpt/global/core/app/tool/httpTool/utils';
2932
import { FlowNodeTypeEnum } from '@fastgpt/global/core/workflow/node/constant';
3033
import { MongoApp } from '../../../core/app/schema';
3134
import { getMCPChildren } from '../../../core/app/mcp';
@@ -40,6 +43,7 @@ import { presignVariablesFileUrls } from '../../chat/utils';
4043
import { getSystemTime } from '@fastgpt/global/common/time/timezone';
4144
import { parsetMcpToolConfig } from '@fastgpt/global/core/app/tool/mcpTool/utils';
4245
import { getMcpToolsets } from '../../app/tool/mcpTool/entity';
46+
import { getHttpToolsets } from '../../app/tool/httpTool/entity';
4347
import { getHTTPToolList } from '../../app/http';
4448

4549
/* get system variable */
@@ -396,7 +400,7 @@ export const rewriteRuntimeWorkFlow = async ({
396400
}) => {
397401
/* Toolset 展开 */
398402
// TODO: 待性能优化
399-
{
403+
const parseToolset = async () => {
400404
const toolSetNodes = nodes.filter((node) => node.flowNodeType === FlowNodeTypeEnum.toolSet);
401405
if (toolSetNodes.length > 0) {
402406
const nodeIdsToRemove = new Set<string>();
@@ -481,10 +485,10 @@ export const rewriteRuntimeWorkFlow = async ({
481485
}
482486
}
483487
}
484-
}
488+
};
485489

486490
/* MCP tool 获取原始 schema 加入到 jsonschema 字段里 */
487-
{
491+
const parseMcpTool = async () => {
488492
const mcpToolNodes = nodes.filter(
489493
(node) => node.flowNodeType === FlowNodeTypeEnum.tool && node.toolConfig?.mcpTool
490494
);
@@ -517,7 +521,45 @@ export const rewriteRuntimeWorkFlow = async ({
517521
node.jsonSchema = toolRaw.inputSchema;
518522
node.intro = toolRaw.description;
519523
});
520-
}
524+
};
525+
526+
/* Http tool 获取原始 schema 加入到 jsonschema 字段里 */
527+
const parseHttpTool = async () => {
528+
const httpToolNodes = nodes.filter(
529+
(node) => node.flowNodeType === FlowNodeTypeEnum.tool && node.toolConfig?.httpTool
530+
);
531+
const parseHttpToolConfigs = httpToolNodes
532+
.map((node) => parseHttpToolConfig(node.toolConfig?.httpTool!))
533+
.filter(Boolean) as { toolsetId: string; toolName: string }[];
534+
// 批量获取 toolset
535+
const toolsets = await getHttpToolsets({
536+
teamId,
537+
ids: parseHttpToolConfigs.map((config) => config.toolsetId),
538+
field: {
539+
_id: true,
540+
modules: true
541+
}
542+
});
543+
const toolsetMap = new Map<string, (typeof toolsets)[number]>();
544+
toolsets.forEach((toolset) => {
545+
toolsetMap.set(String(toolset._id), toolset);
546+
});
547+
httpToolNodes.forEach((node) => {
548+
const httpTool = node.toolConfig?.httpTool;
549+
if (!httpTool) return;
550+
const parseResult = parseHttpToolConfig(httpTool);
551+
if (!parseResult) return;
552+
const toolset = toolsetMap.get(parseResult.toolsetId);
553+
const toolList = toolset?.modules?.[0].toolConfig?.httpToolSet?.toolList;
554+
if (!toolList) return;
555+
const toolRaw = toolList.find((tool) => tool.name === parseResult.toolName);
556+
if (!toolRaw) return;
557+
node.jsonSchema = toolRaw.requestSchema;
558+
node.intro = toolRaw.description;
559+
});
560+
};
561+
562+
await Promise.all([parseToolset(), parseMcpTool(), parseHttpTool()]);
521563
};
522564

523565
export const getNodeErrResponse = ({

projects/app/src/pages/api/core/dataset/delete.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,10 @@ async function handler(req: ApiRequestProps) {
3030
fields: '_id'
3131
});
3232
const datasetIds = deleteDatasets.map((d) => d._id);
33+
await deleteDatasetsImmediate({
34+
teamId,
35+
datasetIds
36+
});
3337

3438
await mongoSessionRun(async (session) => {
3539
// 1. Mark as deleted
@@ -46,11 +50,6 @@ async function handler(req: ApiRequestProps) {
4650
}
4751
);
4852

49-
await deleteDatasetsImmediate({
50-
teamId,
51-
datasetIds
52-
});
53-
5453
// 2. Add to delete queue
5554
await addDatasetDeleteJob({
5655
teamId,

0 commit comments

Comments
 (0)