agent功能开发增加MCP后端

This commit is contained in:
2025-11-07 23:18:20 +08:00
parent a8edb8bde3
commit 6899b9d0d2
2 changed files with 143 additions and 53 deletions

View File

@@ -217,7 +217,7 @@ const AgentChatV3 = () => {
setMessages((prev) => [...prev, { ...message, id: Date.now() }]);
};
// 发送消息
// 发送消息(流式 SSE 版本)
const handleSendMessage = async () => {
if (!inputValue.trim() || isProcessing) return;
@@ -242,10 +242,10 @@ const AgentChatV3 = () => {
return;
}
logger.info('AgentChat', '权限检查通过', {
userId: user?.id,
username: user?.username,
subscription_type: user?.subscription_type
logger.info('AgentChat', '权限检查通过', {
userId: user?.id,
username: user?.username,
subscription_type: user?.subscription_type
});
const userMessage = {
@@ -262,6 +262,7 @@ const AgentChatV3 = () => {
let currentPlan = null;
let stepResults = [];
let executingMessageId = null;
try {
// 1. 显示思考状态
@@ -273,8 +274,8 @@ const AgentChatV3 = () => {
setCurrentProgress(10);
// 2. 调用后端API非流式
const response = await axios.post('/mcp/agent/chat', {
// 2. 使用 EventSource 接收 SSE 流式数据
const requestBody = {
message: userInput,
conversation_history: messages
.filter((m) => m.type === MessageTypes.USER || m.type === MessageTypes.AGENT_RESPONSE)
@@ -285,54 +286,140 @@ const AgentChatV3 = () => {
user_id: user?.id ? String(user.id) : 'anonymous',
user_nickname: user?.nickname || user?.username || '匿名用户',
user_avatar: user?.avatar || '',
subscription_type: user?.subscription_type || 'free', // 传递订阅类型
subscription_type: user?.subscription_type || 'free',
session_id: currentSessionId,
};
// 使用 fetch API 进行 SSE 请求
const response = await fetch('/mcp/agent/chat/stream', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
});
// 移除思考消息
setMessages((prev) => prev.filter((m) => m.type !== MessageTypes.AGENT_THINKING));
if (response.data.success) {
const data = response.data;
// 更新 session_id如果是新会话
if (data.session_id && !currentSessionId) {
setCurrentSessionId(data.session_id);
}
// 显示执行计划
if (data.plan) {
currentPlan = data.plan;
addMessage({
type: MessageTypes.AGENT_PLAN,
content: '已制定执行计划',
plan: data.plan,
timestamp: new Date().toISOString(),
});
setCurrentProgress(30);
}
// 显示执行步骤
if (data.step_results && data.step_results.length > 0) {
stepResults = data.step_results;
setCurrentProgress(70);
}
// 显示最终结果(包含执行步骤)
addMessage({
type: MessageTypes.AGENT_RESPONSE,
content: data.final_summary || data.message || '处理完成',
plan: currentPlan,
stepResults: stepResults,
metadata: data.metadata,
timestamp: new Date().toISOString(),
});
setCurrentProgress(100);
// 重新加载会话列表
loadSessions();
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
// 读取流式数据
while (true) {
const { done, value } = await reader.read();
if (done) break;
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n');
buffer = lines.pop(); // 保留不完整的行
for (const line of lines) {
if (!line.trim() || line.startsWith(':')) continue;
if (line.startsWith('event:')) {
// 忽略事件类型行
continue;
}
if (line.startsWith('data:')) {
try {
const data = JSON.parse(line.substring(5).trim());
// 处理不同类型的事件
if (data.stage === 'planning') {
// 正在制定计划
setMessages((prev) => prev.filter((m) => m.type !== MessageTypes.AGENT_THINKING));
addMessage({
type: MessageTypes.AGENT_THINKING,
content: '正在制定执行计划...',
timestamp: new Date().toISOString(),
});
setCurrentProgress(20);
} else if (data.goal) {
// 收到执行计划
currentPlan = data;
setMessages((prev) => prev.filter((m) => m.type !== MessageTypes.AGENT_THINKING));
addMessage({
type: MessageTypes.AGENT_PLAN,
content: '已制定执行计划',
plan: data,
timestamp: new Date().toISOString(),
});
setCurrentProgress(30);
} else if (data.stage === 'executing') {
// 开始执行步骤
const msgId = Date.now();
executingMessageId = msgId;
addMessage({
id: msgId,
type: MessageTypes.AGENT_EXECUTING,
content: `正在执行 ${data.message}`,
plan: currentPlan,
stepResults: [],
timestamp: new Date().toISOString(),
});
setCurrentProgress(40);
} else if (data.step_index !== undefined && data.tool) {
// 收到步骤完成事件
const stepResult = {
step_index: data.step_index,
tool: data.tool,
status: data.status,
result: data.result,
error: data.error,
execution_time: data.execution_time,
};
stepResults.push(stepResult);
// 更新执行中的消息
setMessages((prev) =>
prev.map((m) =>
m.id === executingMessageId
? { ...m, stepResults: [...stepResults] }
: m
)
);
// 更新进度
const progress = 40 + (stepResults.length / (currentPlan?.steps?.length || 5)) * 40;
setCurrentProgress(Math.min(progress, 80));
} else if (data.stage === 'summarizing') {
// 正在生成总结
setMessages((prev) => prev.filter((m) => m.type !== MessageTypes.AGENT_EXECUTING));
addMessage({
type: MessageTypes.AGENT_THINKING,
content: '正在生成分析报告...',
timestamp: new Date().toISOString(),
});
setCurrentProgress(85);
} else if (data.content) {
// 收到最终总结
setMessages((prev) =>
prev.filter((m) => m.type !== MessageTypes.AGENT_THINKING && m.type !== MessageTypes.AGENT_EXECUTING)
);
addMessage({
type: MessageTypes.AGENT_RESPONSE,
content: data.content,
plan: currentPlan,
stepResults: stepResults,
metadata: data.metadata,
timestamp: new Date().toISOString(),
});
setCurrentProgress(100);
}
} catch (e) {
logger.error('解析 SSE 数据失败', e);
}
}
}
}
// 重新加载会话列表
loadSessions();
} catch (error) {
logger.error('Agent chat error', error);
@@ -343,7 +430,7 @@ const AgentChatV3 = () => {
)
);
const errorMessage = error.response?.data?.error || error.message || '处理失败';
const errorMessage = error.response?.data?.detail || error.message || '处理失败';
addMessage({
type: MessageTypes.ERROR,