diff --git a/mcp_server.py b/mcp_server.py index d1a30147..917a8f0c 100644 --- a/mcp_server.py +++ b/mcp_server.py @@ -12,6 +12,7 @@ from typing import List, Dict, Any, Optional, Literal, AsyncGenerator from datetime import datetime, date import logging import httpx +import time from enum import Enum import mcp_database as db from openai import OpenAI @@ -2474,7 +2475,7 @@ MEETING_ROLES = { "nickname": "决策者", "role_type": "manager", "avatar": "/avatars/fund_manager.png", - "model": "kimi-k2-thinking", + "model": "deepseek", "color": "#8B5CF6", "description": "综合分析做出最终决策", "tools": ROLE_TOOLS["fund_manager"], @@ -2600,6 +2601,7 @@ async def stream_role_response( for tool_call in assistant_message.tool_calls: tool_name = tool_call.function.name + tool_call_id = tool_call.id try: arguments = json.loads(tool_call.function.arguments) except: @@ -2608,19 +2610,31 @@ async def stream_role_response( # 发送工具调用开始事件 yield { "type": "tool_call_start", - "tool": tool_name, + "tool_call_id": tool_call_id, + "tool_name": tool_name, "arguments": arguments } # 执行工具调用 + start_time = time.time() result = await call_role_tool(role_id, tool_name, arguments) - tool_calls_made.append(result) + execution_time = time.time() - start_time + tool_calls_made.append({ + "tool_call_id": tool_call_id, + "tool_name": tool_name, + "arguments": arguments, + "result": result, + "execution_time": execution_time + }) # 发送工具调用结果事件 yield { "type": "tool_call_result", - "tool": tool_name, - "result": result + "tool_call_id": tool_call_id, + "tool_name": tool_name, + "result": result, + "status": "success" if result.get("success") else "error", + "execution_time": execution_time } # 添加工具结果到消息 @@ -2715,11 +2729,11 @@ async def stream_investment_meeting(request: MeetingRequest): async for event in stream_role_response(role_id, request.topic, accumulated_context, role_tools): if event["type"] == "tool_call_start": - yield f"data: {json.dumps({'type': 'tool_call_start', 'role_id': role_id, 'tool': event['tool'], 'arguments': event['arguments']}, ensure_ascii=False)}\n\n" + yield f"data: {json.dumps({'type': 'tool_call_start', 'role_id': role_id, 'tool_call_id': event['tool_call_id'], 'tool_name': event['tool_name'], 'arguments': event['arguments']}, ensure_ascii=False)}\n\n" elif event["type"] == "tool_call_result": - yield f"data: {json.dumps({'type': 'tool_call_result', 'role_id': role_id, 'tool': event['tool'], 'result': event['result']}, ensure_ascii=False)}\n\n" - tool_calls.append(event["result"]) + yield f"data: {json.dumps({'type': 'tool_call_result', 'role_id': role_id, 'tool_call_id': event['tool_call_id'], 'tool_name': event['tool_name'], 'result': event['result'], 'status': event['status'], 'execution_time': event['execution_time']}, ensure_ascii=False)}\n\n" + tool_calls.append(event) elif event["type"] == "content_delta": yield f"data: {json.dumps({'type': 'content_delta', 'role_id': role_id, 'content': event['content']}, ensure_ascii=False)}\n\n" @@ -2765,10 +2779,10 @@ async def stream_investment_meeting(request: MeetingRequest): async for event in stream_role_response("fund_manager", request.topic, accumulated_context, fm_tools): if event["type"] == "tool_call_start": - yield f"data: {json.dumps({'type': 'tool_call_start', 'role_id': 'fund_manager', 'tool': event['tool'], 'arguments': event['arguments']}, ensure_ascii=False)}\n\n" + yield f"data: {json.dumps({'type': 'tool_call_start', 'role_id': 'fund_manager', 'tool_call_id': event['tool_call_id'], 'tool_name': event['tool_name'], 'arguments': event['arguments']}, ensure_ascii=False)}\n\n" elif event["type"] == "tool_call_result": - yield f"data: {json.dumps({'type': 'tool_call_result', 'role_id': 'fund_manager', 'tool': event['tool'], 'result': event['result']}, ensure_ascii=False)}\n\n" - fm_tool_calls.append(event["result"]) + yield f"data: {json.dumps({'type': 'tool_call_result', 'role_id': 'fund_manager', 'tool_call_id': event['tool_call_id'], 'tool_name': event['tool_name'], 'result': event['result'], 'status': event['status'], 'execution_time': event['execution_time']}, ensure_ascii=False)}\n\n" + fm_tool_calls.append(event) elif event["type"] == "content_delta": yield f"data: {json.dumps({'type': 'content_delta', 'role_id': 'fund_manager', 'content': event['content']}, ensure_ascii=False)}\n\n" fm_full_content += event["content"] diff --git a/public/images/agent/simons.png b/public/images/agent/simons.png new file mode 100644 index 00000000..0cba3549 Binary files /dev/null and b/public/images/agent/simons.png differ diff --git a/public/images/agent/基金经理.png b/public/images/agent/基金经理.png new file mode 100644 index 00000000..a5c69801 Binary files /dev/null and b/public/images/agent/基金经理.png differ diff --git a/public/images/agent/大空头.png b/public/images/agent/大空头.png new file mode 100644 index 00000000..c4a54af1 Binary files /dev/null and b/public/images/agent/大空头.png differ diff --git a/public/images/agent/巴菲特.png b/public/images/agent/巴菲特.png new file mode 100644 index 00000000..594209f4 Binary files /dev/null and b/public/images/agent/巴菲特.png differ diff --git a/public/images/agent/牢大.png b/public/images/agent/牢大.png new file mode 100644 index 00000000..f45870ea Binary files /dev/null and b/public/images/agent/牢大.png differ diff --git a/public/images/hero/background.jpg b/public/images/hero/background.jpg deleted file mode 100644 index 29ff748c..00000000 Binary files a/public/images/hero/background.jpg and /dev/null differ diff --git a/public/images/hero/robot.jpg b/public/images/hero/robot.jpg deleted file mode 100644 index ce38995f..00000000 Binary files a/public/images/hero/robot.jpg and /dev/null differ diff --git a/public/images/how-it-works/gradient.png b/public/images/how-it-works/gradient.png deleted file mode 100644 index d5544896..00000000 Binary files a/public/images/how-it-works/gradient.png and /dev/null differ diff --git a/public/images/how-it-works/image-1.png b/public/images/how-it-works/image-1.png deleted file mode 100644 index de9aa998..00000000 Binary files a/public/images/how-it-works/image-1.png and /dev/null differ diff --git a/public/images/how-it-works/image-2.png b/public/images/how-it-works/image-2.png deleted file mode 100644 index cbeec783..00000000 Binary files a/public/images/how-it-works/image-2.png and /dev/null differ diff --git a/public/images/how-it-works/image-3.png b/public/images/how-it-works/image-3.png deleted file mode 100644 index 6ee2ea1c..00000000 Binary files a/public/images/how-it-works/image-3.png and /dev/null differ diff --git a/public/images/how-it-works/image-4.png b/public/images/how-it-works/image-4.png deleted file mode 100644 index d5a06ec1..00000000 Binary files a/public/images/how-it-works/image-4.png and /dev/null differ diff --git a/public/images/how-to-use/image-1.jpg b/public/images/how-to-use/image-1.jpg deleted file mode 100644 index 4e223ecf..00000000 Binary files a/public/images/how-to-use/image-1.jpg and /dev/null differ diff --git a/public/images/how-to-use/image-2.jpg b/public/images/how-to-use/image-2.jpg deleted file mode 100644 index 382fa478..00000000 Binary files a/public/images/how-to-use/image-2.jpg and /dev/null differ diff --git a/public/images/how-to-use/image-3.jpg b/public/images/how-to-use/image-3.jpg deleted file mode 100644 index 55cd2c93..00000000 Binary files a/public/images/how-to-use/image-3.jpg and /dev/null differ diff --git a/public/images/how-to-use/image-4.jpg b/public/images/how-to-use/image-4.jpg deleted file mode 100644 index ff97d2f3..00000000 Binary files a/public/images/how-to-use/image-4.jpg and /dev/null differ diff --git a/src/mocks/handlers/agent.js b/src/mocks/handlers/agent.js index 2fce2a8c..0ce9f5d3 100644 --- a/src/mocks/handlers/agent.js +++ b/src/mocks/handlers/agent.js @@ -519,8 +519,10 @@ export const agentHandlers = [ await delay(200); // 发送工具调用 + const toolCallResults = []; for (const tool of role.tools) { const toolCallId = `tc-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`; + const execTime = 0.5 + Math.random() * 0.5; // tool_call_start controller.enqueue(encoder.encode(`data: ${JSON.stringify({ @@ -538,11 +540,20 @@ export const agentHandlers = [ type: 'tool_call_result', role_id: role.role_id, tool_call_id: toolCallId, - result: tool.result, + tool_name: tool.name, + result: { success: true, data: tool.result }, status: 'success', - execution_time: 0.5 + Math.random() * 0.5, + execution_time: execTime, })}\n\n`)); + toolCallResults.push({ + tool_call_id: toolCallId, + tool_name: tool.name, + result: { success: true, data: tool.result }, + status: 'success', + execution_time: execTime, + }); + await delay(200); } @@ -561,8 +572,13 @@ export const agentHandlers = [ controller.enqueue(encoder.encode(`data: ${JSON.stringify({ type: 'message_complete', role_id: role.role_id, - content: role.content, - is_conclusion: role.is_conclusion || false, + message: { + role_id: role.role_id, + role_name: role.role_name, + content: role.content, + tool_calls: toolCallResults, + is_conclusion: role.is_conclusion || false, + }, })}\n\n`)); await delay(500); diff --git a/src/views/AgentChat/hooks/useInvestmentMeeting.ts b/src/views/AgentChat/hooks/useInvestmentMeeting.ts index bf082a95..f6959a24 100644 --- a/src/views/AgentChat/hooks/useInvestmentMeeting.ts +++ b/src/views/AgentChat/hooks/useInvestmentMeeting.ts @@ -358,7 +358,9 @@ export const useInvestmentMeeting = ({ case 'message_complete': if (data.role_id) { - finishStreamingMessage(data.role_id, data.content); + // 后端可能发送 message 对象或直接 content + const finalContent = data.message?.content || data.content; + finishStreamingMessage(data.role_id, finalContent); setSpeakingRoleId(null); } break; @@ -561,7 +563,9 @@ export const useInvestmentMeeting = ({ case 'message_complete': if (data.role_id) { - finishStreamingMessage(data.role_id, data.content); + // 后端可能发送 message 对象或直接 content + const finalContent = data.message?.content || data.content; + finishStreamingMessage(data.role_id, finalContent); setSpeakingRoleId(null); } break;