agent功能开发增加MCP后端

This commit is contained in:
2025-11-07 20:23:54 +08:00
parent f01eff6eb7
commit 322b1dd845
3 changed files with 332 additions and 58 deletions

View File

@@ -95,7 +95,7 @@ export const ChatInterfaceV2 = () => {
});
};
// 发送消息Agent模式
// 发送消息Agent模式 - 流式
const handleSendMessage = async () => {
if (!inputValue.trim() || isProcessing) return;
@@ -106,10 +106,16 @@ export const ChatInterfaceV2 = () => {
};
addMessage(userMessage);
const userInput = inputValue; // 保存输入值
setInputValue('');
setIsProcessing(true);
setCurrentProgress(0);
// 用于存储步骤结果
let currentPlan = null;
let stepResults = [];
let executingMessageId = null;
try {
// 1. 显示思考状态
addMessage({
@@ -120,18 +126,40 @@ export const ChatInterfaceV2 = () => {
setCurrentProgress(10);
// Agent API
const response = await fetch(`${mcpService.baseURL.replace('/mcp', '')}/mcp/agent/chat`, {
// 使EventSource 接收流式数据
const eventSource = new EventSource(
`${mcpService.baseURL.replace('/mcp', '')}/mcp/agent/chat/stream`,
{
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: userInput,
conversation_history: messages
.filter(m => m.type === MessageTypes.USER || m.type === MessageTypes.AGENT_RESPONSE)
.map(m => ({
isUser: m.type === MessageTypes.USER,
content: m.content,
})),
}),
}
);
// 由于 EventSource 不支持 POST我们使用 fetch + ReadableStream
const response = await fetch(`${mcpService.baseURL.replace('/mcp', '')}/mcp/agent/chat/stream`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
message: inputValue,
conversation_history: messages.filter(m => m.type === MessageTypes.USER || m.type === MessageTypes.AGENT_RESPONSE).map(m => ({
isUser: m.type === MessageTypes.USER,
content: m.content,
})),
message: userInput,
conversation_history: messages
.filter(m => m.type === MessageTypes.USER || m.type === MessageTypes.AGENT_RESPONSE)
.map(m => ({
isUser: m.type === MessageTypes.USER,
content: m.content,
})),
}),
});
@@ -139,62 +167,139 @@ export const ChatInterfaceV2 = () => {
throw new Error('Agent请求失败');
}
const agentResponse = await response.json();
logger.info('Agent response', agentResponse);
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';
// 移除思考消息
setMessages(prev => prev.filter(m => m.type !== MessageTypes.AGENT_THINKING));
// 读取流式数据
while (true) {
const { done, value } = await reader.read();
if (done) break;
if (!agentResponse.success) {
throw new Error(agentResponse.message || '处理失败');
}
buffer += decoder.decode(value, { stream: true });
const lines = buffer.split('\n\n');
buffer = lines.pop(); // 保留不完整的行
setCurrentProgress(30);
for (const line of lines) {
if (!line.trim()) continue;
// 2. 显示执行计划
if (agentResponse.plan) {
addMessage({
type: MessageTypes.AGENT_PLAN,
content: '已制定执行计划',
plan: agentResponse.plan,
timestamp: new Date().toISOString(),
});
}
// 解析 SSE 消息
const eventMatch = line.match(/^event: (.+)$/m);
const dataMatch = line.match(/^data: (.+)$/m);
setCurrentProgress(40);
if (!eventMatch || !dataMatch) continue;
// 3. 显示执行过程
if (agentResponse.step_results && agentResponse.step_results.length > 0) {
addMessage({
type: MessageTypes.AGENT_EXECUTING,
content: '正在执行步骤...',
plan: agentResponse.plan,
stepResults: agentResponse.step_results,
timestamp: new Date().toISOString(),
});
const event = eventMatch[1];
const data = JSON.parse(dataMatch[1]);
// 模拟进度更新
for (let i = 0; i < agentResponse.step_results.length; i++) {
setCurrentProgress(40 + (i + 1) / agentResponse.step_results.length * 50);
await new Promise(resolve => setTimeout(resolve, 100));
logger.info(`SSE Event: ${event}`, data);
// 处理不同类型的事件
switch (event) {
case 'status':
if (data.stage === 'planning') {
// 移除思考消息,显示规划中
setMessages(prev => prev.filter(m => m.type !== MessageTypes.AGENT_THINKING));
addMessage({
type: MessageTypes.AGENT_THINKING,
content: data.message,
timestamp: new Date().toISOString(),
});
setCurrentProgress(20);
} else if (data.stage === 'executing') {
setCurrentProgress(30);
} else if (data.stage === 'summarizing') {
setCurrentProgress(90);
}
break;
case 'plan':
// 移除思考消息
setMessages(prev => prev.filter(m => m.type !== MessageTypes.AGENT_THINKING));
// 显示执行计划
currentPlan = data;
addMessage({
type: MessageTypes.AGENT_PLAN,
content: '已制定执行计划',
plan: data,
timestamp: new Date().toISOString(),
});
setCurrentProgress(30);
break;
case 'step_start':
// 如果还没有执行中消息,创建一个
if (!executingMessageId) {
const executingMsg = {
type: MessageTypes.AGENT_EXECUTING,
content: '正在执行步骤...',
plan: currentPlan,
stepResults: [],
timestamp: new Date().toISOString(),
};
addMessage(executingMsg);
executingMessageId = Date.now();
}
break;
case 'step_complete':
// 添加步骤结果
stepResults.push({
step_index: data.step_index,
tool: data.tool,
status: data.status,
result: data.result,
error: data.error,
execution_time: data.execution_time,
arguments: data.arguments,
});
// 更新执行中消息
setMessages(prev =>
prev.map(msg =>
msg.type === MessageTypes.AGENT_EXECUTING
? { ...msg, stepResults: [...stepResults] }
: msg
)
);
// 更新进度
if (currentPlan) {
const progress = 30 + ((data.step_index + 1) / currentPlan.steps.length) * 60;
setCurrentProgress(progress);
}
break;
case 'summary':
// 移除执行中消息
setMessages(prev => prev.filter(m => 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);
break;
case 'error':
throw new Error(data.message);
case 'done':
logger.info('Stream完成');
break;
default:
logger.warn('未知事件类型:', event);
}
}
}
setCurrentProgress(100);
// 移除执行中消息
setMessages(prev => prev.filter(m => m.type !== MessageTypes.AGENT_EXECUTING));
// 4. 显示最终结果
addMessage({
type: MessageTypes.AGENT_RESPONSE,
content: agentResponse.message || agentResponse.final_summary,
plan: agentResponse.plan,
stepResults: agentResponse.step_results,
metadata: agentResponse.metadata,
timestamp: new Date().toISOString(),
});
} catch (error) {
logger.error('Agent chat error', error);