Skip to content
Toggle navigation
P
Projects
G
Groups
S
Snippets
Help
赵月辉
/
fastgpt-migrated
This project
Loading...
Sign in
Toggle navigation
Go to a project
Project
Repository
Issues
0
Merge Requests
0
Pipelines
Wiki
Snippets
Members
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Unverified
Commit
81dfc589
authored
Apr 24, 2026
by
Archer
Committed by
GitHub
Apr 24, 2026
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
fix: messages adapt test (#6813)
* doc * doc * doc
parent
5316c3ca
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
162 additions
and
7 deletions
+162
-7
document/content/docs/self-host/upgrading/4-14/41414.mdx
+4
-2
document/data/doc-last-modified.json
+5
-4
packages/global/core/chat/adapt.ts
+1
-1
test/cases/global/core/chat/adapt.test.ts
+152
-0
No files found.
document/content/docs/self-host/upgrading/4-14/41414.mdx
View file @
81dfc589
...
@@ -8,6 +8,7 @@ description: 'FastGPT V4.14.14 更新说明'
...
@@ -8,6 +8,7 @@ description: 'FastGPT V4.14.14 更新说明'
### 1. 更新镜像 tag
### 1. 更新镜像 tag
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.14
- 更新 fastgpt-app(fastgpt 主服务) 镜像 tag: v4.14.14
- 更新 fastgpt-pro(fastgpt 商业版) 镜像 tag: v4.14.14
## 🐛 修复
## 🐛 修复
...
@@ -16,4 +17,5 @@ description: 'FastGPT V4.14.14 更新说明'
...
@@ -16,4 +17,5 @@ description: 'FastGPT V4.14.14 更新说明'
1. 个人微信发布渠道,优化轮询策略(拉取与回复解耦),避免数据量超大时出现阻塞。
1. 个人微信发布渠道,优化轮询策略(拉取与回复解耦),避免数据量超大时出现阻塞。
2. 新增环境变量 `WECHAT_CHANNEL_CONCURRENCY`(默认 1000)用于控制微信渠道 poll worker 并发数,建议 ≥ online channel 峰值。
2. 新增环境变量 `WECHAT_CHANNEL_CONCURRENCY`(默认 1000)用于控制微信渠道 poll worker 并发数,建议 ≥ online channel 峰值。
3. 完善内网地址检测。
3. 完善内网地址检测。
\ No newline at end of file
4. 兼容 deepseek 工具调用+思考模式,避免接口出现 400 错误。
\ No newline at end of file
document/data/doc-last-modified.json
View file @
81dfc589
...
@@ -225,12 +225,12 @@
...
@@ -225,12 +225,12 @@
"document/content/docs/self-host/upgrading/4-14/41410.en.mdx"
:
"2026-03-31T23:15:29+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41410.en.mdx"
:
"2026-03-31T23:15:29+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41410.mdx"
:
"2026-04-18T20:47:39+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41410.mdx"
:
"2026-04-18T20:47:39+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41411.en.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41411.en.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41411.mdx"
:
"2026-04-2
0T20:18:35
+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41411.mdx"
:
"2026-04-2
4T17:13:58
+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41412.en.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41412.en.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41412.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41412.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41413.en.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41413.en.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41413.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41413.mdx"
:
"2026-04-21T23:04:26+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41414.mdx"
:
"2026-04-2
2T23:35:11
+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41414.mdx"
:
"2026-04-2
4T18:21:37
+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4142.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4142.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4142.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4142.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4143.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4143.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
...
@@ -251,7 +251,7 @@
...
@@ -251,7 +251,7 @@
"document/content/docs/self-host/upgrading/4-14/41481.mdx"
:
"2026-03-09T17:39:53+08:00"
,
"document/content/docs/self-host/upgrading/4-14/41481.mdx"
:
"2026-03-09T17:39:53+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4149.en.mdx"
:
"2026-03-23T12:17:04+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4149.en.mdx"
:
"2026-03-23T12:17:04+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4149.mdx"
:
"2026-04-07T21:01:52+08:00"
,
"document/content/docs/self-host/upgrading/4-14/4149.mdx"
:
"2026-04-07T21:01:52+08:00"
,
"document/content/docs/self-host/upgrading/4-15/4150.mdx"
:
"2026-04-2
2T14:36:14
+08:00"
,
"document/content/docs/self-host/upgrading/4-15/4150.mdx"
:
"2026-04-2
3T18:02:28
+08:00"
,
"document/content/docs/self-host/upgrading/outdated/40.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/outdated/40.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/outdated/40.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/outdated/40.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/outdated/41.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
"document/content/docs/self-host/upgrading/outdated/41.en.mdx"
:
"2026-03-03T17:39:47+08:00"
,
...
@@ -426,4 +426,4 @@
...
@@ -426,4 +426,4 @@
"document/content/docs/use-cases/external-integration/wecom.mdx"
:
"2025-12-10T20:07:05+08:00"
,
"document/content/docs/use-cases/external-integration/wecom.mdx"
:
"2025-12-10T20:07:05+08:00"
,
"document/content/docs/use-cases/index.en.mdx"
:
"2026-02-26T22:14:30+08:00"
,
"document/content/docs/use-cases/index.en.mdx"
:
"2026-02-26T22:14:30+08:00"
,
"document/content/docs/use-cases/index.mdx"
:
"2025-07-24T14:23:04+08:00"
"document/content/docs/use-cases/index.mdx"
:
"2025-07-24T14:23:04+08:00"
}
}
\ No newline at end of file
packages/global/core/chat/adapt.ts
View file @
81dfc589
...
@@ -171,7 +171,7 @@ export const chats2GPTMessages = ({
...
@@ -171,7 +171,7 @@ export const chats2GPTMessages = ({
typeof
lastResult
?.
content
===
'string'
typeof
lastResult
?.
content
===
'string'
)
{
)
{
lastResult
.
content
+=
value
.
text
.
content
;
lastResult
.
content
+=
value
.
text
.
content
;
}
else
if
(
lastResult
.
reasoning_content
)
{
}
else
if
(
lastResult
?
.
reasoning_content
)
{
lastResult
.
content
=
value
.
text
.
content
;
lastResult
.
content
=
value
.
text
.
content
;
}
else
{
}
else
{
aiResults
.
push
({
aiResults
.
push
({
...
...
test/cases/global/core/chat/adapt.test.ts
View file @
81dfc589
...
@@ -444,6 +444,124 @@ describe('chats2GPTMessages', () => {
...
@@ -444,6 +444,124 @@ describe('chats2GPTMessages', () => {
// Plan should be skipped when reserveTool is false
// Plan should be skipped when reserveTool is false
expect
(
result
).
toHaveLength
(
2
);
expect
(
result
).
toHaveLength
(
2
);
});
});
it
(
'should convert AI message with reasoning only'
,
()
=>
{
const
messages
:
ChatItemMiniType
[]
=
[
{
obj
:
ChatRoleEnum
.
AI
,
value
:
[{
reasoning
:
{
content
:
'Let me think...'
}
}]
}
];
const
result
=
chats2GPTMessages
({
messages
,
reserveId
:
false
});
expect
(
result
).
toHaveLength
(
1
);
expect
(
result
[
0
].
role
).
toBe
(
ChatCompletionRequestMessageRoleEnum
.
Assistant
);
expect
((
result
[
0
]
as
any
).
reasoning_content
).
toBe
(
'Let me think...'
);
expect
((
result
[
0
]
as
any
).
content
).
toBeUndefined
();
});
it
(
'should merge reasoning + text into a single assistant message'
,
()
=>
{
const
messages
:
ChatItemMiniType
[]
=
[
{
obj
:
ChatRoleEnum
.
AI
,
value
:
[
{
reasoning
:
{
content
:
'Let me think...'
}
},
{
text
:
{
content
:
'Final answer'
}
}
]
}
];
const
result
=
chats2GPTMessages
({
messages
,
reserveId
:
false
});
expect
(
result
).
toHaveLength
(
1
);
expect
(
result
[
0
].
role
).
toBe
(
ChatCompletionRequestMessageRoleEnum
.
Assistant
);
expect
((
result
[
0
]
as
any
).
reasoning_content
).
toBe
(
'Let me think...'
);
expect
((
result
[
0
]
as
any
).
content
).
toBe
(
'Final answer'
);
});
it
(
'should merge reasoning + tool_calls into a single assistant message'
,
()
=>
{
const
messages
:
ChatItemMiniType
[]
=
[
{
obj
:
ChatRoleEnum
.
AI
,
value
:
[
{
reasoning
:
{
content
:
'Need to call a tool'
}
},
{
tool
:
{
id
:
'tool-1'
,
toolName
:
'Search'
,
toolAvatar
:
''
,
functionName
:
'search_web'
,
params
:
'{"q":"x"}'
,
response
:
'{}'
}
}
]
}
];
const
result
=
chats2GPTMessages
({
messages
,
reserveId
:
false
,
reserveTool
:
true
});
// 1 merged assistant (reasoning + tool_calls) + 1 tool response
expect
(
result
).
toHaveLength
(
2
);
expect
(
result
[
0
].
role
).
toBe
(
ChatCompletionRequestMessageRoleEnum
.
Assistant
);
expect
((
result
[
0
]
as
any
).
reasoning_content
).
toBe
(
'Need to call a tool'
);
expect
((
result
[
0
]
as
any
).
tool_calls
).
toHaveLength
(
1
);
expect
((
result
[
0
]
as
any
).
tool_calls
[
0
].
function
.
name
).
toBe
(
'search_web'
);
expect
(
result
[
1
].
role
).
toBe
(
ChatCompletionRequestMessageRoleEnum
.
Tool
);
});
it
(
'should keep tool_calls separate when no reasoning precedes them'
,
()
=>
{
const
messages
:
ChatItemMiniType
[]
=
[
{
obj
:
ChatRoleEnum
.
AI
,
value
:
[
{
text
:
{
content
:
'Calling tool'
}
},
{
tool
:
{
id
:
'tool-1'
,
toolName
:
'Search'
,
toolAvatar
:
''
,
functionName
:
'search_web'
,
params
:
'{}'
,
response
:
'{}'
}
}
]
}
];
const
result
=
chats2GPTMessages
({
messages
,
reserveId
:
false
,
reserveTool
:
true
});
// text assistant + tool_calls assistant + tool response
expect
(
result
).
toHaveLength
(
3
);
expect
((
result
[
0
]
as
any
).
content
).
toBe
(
'Calling tool'
);
expect
((
result
[
0
]
as
any
).
tool_calls
).
toBeUndefined
();
expect
((
result
[
1
]
as
any
).
tool_calls
).
toHaveLength
(
1
);
expect
(
result
[
2
].
role
).
toBe
(
ChatCompletionRequestMessageRoleEnum
.
Tool
);
});
it
(
'should handle multiple reasoning values producing separate assistant entries'
,
()
=>
{
const
messages
:
ChatItemMiniType
[]
=
[
{
obj
:
ChatRoleEnum
.
AI
,
value
:
[
{
reasoning
:
{
content
:
'Step 1 thinking'
}
},
{
text
:
{
content
:
'Intermediate answer'
}
},
{
reasoning
:
{
content
:
'Step 2 thinking'
}
},
{
text
:
{
content
:
'Final answer'
}
}
]
}
];
const
result
=
chats2GPTMessages
({
messages
,
reserveId
:
false
});
expect
(
result
).
toHaveLength
(
2
);
expect
((
result
[
0
]
as
any
).
reasoning_content
).
toBe
(
'Step 1 thinking'
);
expect
((
result
[
0
]
as
any
).
content
).
toBe
(
'Intermediate answer'
);
expect
((
result
[
1
]
as
any
).
reasoning_content
).
toBe
(
'Step 2 thinking'
);
expect
((
result
[
1
]
as
any
).
content
).
toBe
(
'Final answer'
);
});
});
});
describe
(
'GPTMessages2Chats'
,
()
=>
{
describe
(
'GPTMessages2Chats'
,
()
=>
{
...
@@ -530,6 +648,40 @@ describe('GPTMessages2Chats', () => {
...
@@ -530,6 +648,40 @@ describe('GPTMessages2Chats', () => {
expect
(
result
[
0
].
value
[
1
].
text
?.
content
).
toBe
(
'Final answer'
);
expect
(
result
[
0
].
value
[
1
].
text
?.
content
).
toBe
(
'Final answer'
);
});
});
it
(
'should drop reasoning when reserveReason is false'
,
()
=>
{
const
messages
:
ChatCompletionMessageParam
[]
=
[
{
role
:
ChatCompletionRequestMessageRoleEnum
.
Assistant
,
content
:
'Final answer'
,
reasoning_content
:
'Let me think about this...'
}
];
const
result
=
GPTMessages2Chats
({
messages
,
reserveReason
:
false
});
expect
(
result
).
toHaveLength
(
1
);
expect
(
result
[
0
].
value
).
toHaveLength
(
1
);
expect
(
result
[
0
].
value
[
0
].
text
?.
content
).
toBe
(
'Final answer'
);
expect
((
result
[
0
].
value
[
0
]
as
any
).
reasoning
).
toBeUndefined
();
});
it
(
'should keep only reasoning when assistant message has no content'
,
()
=>
{
const
messages
:
ChatCompletionMessageParam
[]
=
[
{
role
:
ChatCompletionRequestMessageRoleEnum
.
Assistant
,
content
:
''
,
reasoning_content
:
'Thinking only'
}
];
const
result
=
GPTMessages2Chats
({
messages
});
expect
(
result
).
toHaveLength
(
1
);
expect
(
result
[
0
].
value
).
toHaveLength
(
1
);
const
value
=
result
[
0
].
value
[
0
]
as
{
reasoning
?:
{
content
:
string
}
};
expect
(
value
.
reasoning
?.
content
).
toBe
(
'Thinking only'
);
});
it
(
'should merge messages with same dataId'
,
()
=>
{
it
(
'should merge messages with same dataId'
,
()
=>
{
const
messages
:
ChatCompletionMessageParam
[]
=
[
const
messages
:
ChatCompletionMessageParam
[]
=
[
{
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment