update pay function
This commit is contained in:
@@ -2361,6 +2361,36 @@ MEETING_MODEL_CONFIGS = {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def clean_deepseek_tool_markers(content: str) -> str:
|
||||||
|
"""
|
||||||
|
清理 DeepSeek 模型输出中的工具调用标记
|
||||||
|
DeepSeek 有时会以文本形式输出工具调用,格式如:
|
||||||
|
<|tool▁calls▁begin|><|tool▁call▁begin|>tool_name<|tool▁sep|>{"args": "value"}<|tool▁call▁end|><|tool▁calls▁end|>
|
||||||
|
"""
|
||||||
|
import re
|
||||||
|
if not content:
|
||||||
|
return content
|
||||||
|
|
||||||
|
# 清理 DeepSeek 工具调用标记
|
||||||
|
# 匹配 <|tool▁calls▁begin|> ... <|tool▁calls▁end|> 整个块
|
||||||
|
pattern = r'<|tool▁calls▁begin|>.*?<|tool▁calls▁end|>'
|
||||||
|
cleaned = re.sub(pattern, '', content, flags=re.DOTALL)
|
||||||
|
|
||||||
|
# 也清理可能残留的单个标记
|
||||||
|
markers = [
|
||||||
|
'<|tool▁calls▁begin|>',
|
||||||
|
'<|tool▁calls▁end|>',
|
||||||
|
'<|tool▁call▁begin|>',
|
||||||
|
'<|tool▁call▁end|>',
|
||||||
|
'<|tool▁sep|>',
|
||||||
|
]
|
||||||
|
for marker in markers:
|
||||||
|
cleaned = cleaned.replace(marker, '')
|
||||||
|
|
||||||
|
return cleaned.strip()
|
||||||
|
|
||||||
|
|
||||||
# 每个角色可用的工具列表
|
# 每个角色可用的工具列表
|
||||||
ROLE_TOOLS = {
|
ROLE_TOOLS = {
|
||||||
"buffett": ["search_china_news", "search_research_reports", "get_stock_basic_info", "get_stock_financial_index"],
|
"buffett": ["search_china_news", "search_research_reports", "get_stock_basic_info", "get_stock_financial_index"],
|
||||||
@@ -2663,6 +2693,9 @@ async def stream_role_response(
|
|||||||
"content": content
|
"content": content
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# 清理 DeepSeek 工具调用标记
|
||||||
|
full_content = clean_deepseek_tool_markers(full_content)
|
||||||
|
|
||||||
# 发送完成事件
|
# 发送完成事件
|
||||||
yield {
|
yield {
|
||||||
"type": "content_done",
|
"type": "content_done",
|
||||||
|
|||||||
@@ -38,6 +38,32 @@ import {
|
|||||||
import { getRoleConfig, MEETING_ROLES } from '../../constants/meetingRoles';
|
import { getRoleConfig, MEETING_ROLES } from '../../constants/meetingRoles';
|
||||||
import { MarkdownWithCharts } from '@components/ChatBot/MarkdownWithCharts';
|
import { MarkdownWithCharts } from '@components/ChatBot/MarkdownWithCharts';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 清理 DeepSeek 模型输出中的工具调用标记
|
||||||
|
* DeepSeek 有时会以文本形式输出工具调用,格式如:
|
||||||
|
* <|tool▁calls▁begin|><|tool▁call▁begin|>tool_name<|tool▁sep|>{"args": "value"}<|tool▁call▁end|><|tool▁calls▁end|>
|
||||||
|
*/
|
||||||
|
const cleanDeepseekToolMarkers = (content) => {
|
||||||
|
if (!content) return content;
|
||||||
|
|
||||||
|
// 清理 DeepSeek 工具调用标记(匹配整个块)
|
||||||
|
let cleaned = content.replace(/<|tool▁calls▁begin|>[\s\S]*?<|tool▁calls▁end|>/g, '');
|
||||||
|
|
||||||
|
// 清理可能残留的单个标记
|
||||||
|
const markers = [
|
||||||
|
'<|tool▁calls▁begin|>',
|
||||||
|
'<|tool▁calls▁end|>',
|
||||||
|
'<|tool▁call▁begin|>',
|
||||||
|
'<|tool▁call▁end|>',
|
||||||
|
'<|tool▁sep|>',
|
||||||
|
];
|
||||||
|
markers.forEach((marker) => {
|
||||||
|
cleaned = cleaned.split(marker).join('');
|
||||||
|
});
|
||||||
|
|
||||||
|
return cleaned.trim();
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 解析 deepmoney 格式的内容
|
* 解析 deepmoney 格式的内容
|
||||||
* 格式: <think>思考过程</think><answer>回答内容</answer>
|
* 格式: <think>思考过程</think><answer>回答内容</answer>
|
||||||
@@ -48,10 +74,13 @@ import { MarkdownWithCharts } from '@components/ChatBot/MarkdownWithCharts';
|
|||||||
const parseDeepmoneyContent = (content) => {
|
const parseDeepmoneyContent = (content) => {
|
||||||
if (!content) return { thinking: null, answer: '' };
|
if (!content) return { thinking: null, answer: '' };
|
||||||
|
|
||||||
|
// 先清理 DeepSeek 工具调用标记
|
||||||
|
const cleanedContent = cleanDeepseekToolMarkers(content);
|
||||||
|
|
||||||
// 匹配 <think>...</think> 标签
|
// 匹配 <think>...</think> 标签
|
||||||
const thinkMatch = content.match(/<think>([\s\S]*?)<\/think>/i);
|
const thinkMatch = cleanedContent.match(/<think>([\s\S]*?)<\/think>/i);
|
||||||
// 匹配 <answer>...</answer> 标签
|
// 匹配 <answer>...</answer> 标签
|
||||||
const answerMatch = content.match(/<answer>([\s\S]*?)<\/answer>/i);
|
const answerMatch = cleanedContent.match(/<answer>([\s\S]*?)<\/answer>/i);
|
||||||
|
|
||||||
// 如果有 answer 标签,提取内容
|
// 如果有 answer 标签,提取内容
|
||||||
if (answerMatch) {
|
if (answerMatch) {
|
||||||
@@ -64,7 +93,7 @@ const parseDeepmoneyContent = (content) => {
|
|||||||
// 如果只有 think 标签但没有 answer 标签,可能正在流式输出中
|
// 如果只有 think 标签但没有 answer 标签,可能正在流式输出中
|
||||||
if (thinkMatch && !answerMatch) {
|
if (thinkMatch && !answerMatch) {
|
||||||
// 检查 think 后面是否有其他内容
|
// 检查 think 后面是否有其他内容
|
||||||
const afterThink = content.replace(/<think>[\s\S]*?<\/think>/i, '').trim();
|
const afterThink = cleanedContent.replace(/<think>[\s\S]*?<\/think>/i, '').trim();
|
||||||
// 如果 think 后面有内容但不是 answer 标签包裹的,可能是部分输出
|
// 如果 think 后面有内容但不是 answer 标签包裹的,可能是部分输出
|
||||||
if (afterThink && !afterThink.startsWith('<answer>')) {
|
if (afterThink && !afterThink.startsWith('<answer>')) {
|
||||||
return {
|
return {
|
||||||
@@ -78,10 +107,10 @@ const parseDeepmoneyContent = (content) => {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果没有特殊标签,返回原内容
|
// 如果没有特殊标签,返回清理后的内容
|
||||||
return {
|
return {
|
||||||
thinking: null,
|
thinking: null,
|
||||||
answer: content,
|
answer: cleanedContent,
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user