update pay function
This commit is contained in:
@@ -434,4 +434,157 @@ export const agentHandlers = [
|
||||
conclusion: messages[messages.length - 1],
|
||||
});
|
||||
}),
|
||||
|
||||
// POST /mcp/agent/meeting/stream - 流式会议接口(V2)
|
||||
http.post('/mcp/agent/meeting/stream', async ({ request }) => {
|
||||
const body = await request.json();
|
||||
const { topic, user_id } = body;
|
||||
|
||||
const sessionId = `meeting-${Date.now()}`;
|
||||
|
||||
// 定义会议角色和他们的消息
|
||||
const roleMessages = [
|
||||
{
|
||||
role_id: 'buffett',
|
||||
role_name: '巴菲特',
|
||||
content: `关于「${topic}」,我认为这里存在显著的投资机会。从价值投资的角度看,我们应该关注以下几点:\n\n1. **长期价值**:该标的具有较强的护城河\n2. **盈利能力**:ROE持续保持在较高水平\n3. **管理层质量**:管理团队稳定且执行力强\n\n我的观点是**看多**,建议逢低布局。`,
|
||||
tools: [
|
||||
{ name: 'search_china_news', result: { articles: [{ title: '相关新闻1' }, { title: '相关新闻2' }] } },
|
||||
{ name: 'get_stock_basic_info', result: { pe: 25.6, pb: 3.2, roe: 18.5 } },
|
||||
],
|
||||
},
|
||||
{
|
||||
role_id: 'big_short',
|
||||
role_name: '大空头',
|
||||
content: `等等,让我泼点冷水。关于「${topic}」,市场似乎过于乐观了:\n\n⚠️ **风险提示**:\n1. 当前估值处于历史高位,安全边际不足\n2. 行业竞争加剧,利润率面临压力\n3. 宏观环境不确定性增加\n\n建议投资者**保持谨慎**,不要追高。`,
|
||||
tools: [
|
||||
{ name: 'get_stock_financial_index', result: { debt_ratio: 45.2, current_ratio: 1.8 } },
|
||||
],
|
||||
},
|
||||
{
|
||||
role_id: 'simons',
|
||||
role_name: '量化分析员',
|
||||
content: `从量化角度分析「${topic}」:\n\n📊 **技术指标**:\n- MACD:金叉形态,动能向上\n- RSI:58,处于中性区域\n- 均线:5日>10日>20日,多头排列\n\n📈 **资金面**:\n- 主力资金:近5日净流入2.3亿\n- 北向资金:持续加仓\n\n**结论**:短期技术面偏多,但需关注60日均线支撑。`,
|
||||
tools: [
|
||||
{ name: 'get_stock_trade_data', result: { volume: 1234567, turnover: 5.2 } },
|
||||
{ name: 'get_concept_statistics', result: { concepts: ['AI概念', '半导体'], avg_change: 2.3 } },
|
||||
],
|
||||
},
|
||||
{
|
||||
role_id: 'leek',
|
||||
role_name: '韭菜',
|
||||
content: `哇!「${topic}」看起来要涨啊!\n\n🚀 我觉得必须满仓干!隔壁老王都赚翻了!\n\n不过话说回来...万一跌了怎么办?会不会套住?\n\n算了不管了,先冲一把再说!错过这村就没这店了!\n\n(内心OS:希望别当接盘侠...)`,
|
||||
tools: [], // 韭菜不用工具
|
||||
},
|
||||
{
|
||||
role_id: 'fund_manager',
|
||||
role_name: '基金经理',
|
||||
content: `## 投资建议总结\n\n综合各方观点,对于「${topic}」,我的判断如下:\n\n### 综合评估\n多空双方都提出了有价值的观点。技术面短期偏多,但估值确实需要关注。\n\n### 关键观点\n- ✅ 基本面优质,长期价值明确\n- ⚠️ 短期估值偏高,需要耐心等待\n- 📊 技术面处于上升趋势\n\n### 风险提示\n注意仓位控制,避免追高\n\n### 操作建议\n**观望为主**,等待回调至支撑位再考虑建仓\n\n### 信心指数:7/10`,
|
||||
tools: [
|
||||
{ name: 'search_research_reports', result: { reports: [{ title: '深度研报1' }] } },
|
||||
],
|
||||
is_conclusion: true,
|
||||
},
|
||||
];
|
||||
|
||||
// 创建 SSE 流
|
||||
const encoder = new TextEncoder();
|
||||
const stream = new ReadableStream({
|
||||
async start(controller) {
|
||||
// 发送 session_start
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'session_start',
|
||||
session_id: sessionId,
|
||||
})}\n\n`));
|
||||
|
||||
await delay(300);
|
||||
|
||||
// 发送 order_decided
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'order_decided',
|
||||
order: roleMessages.map(r => r.role_id),
|
||||
})}\n\n`));
|
||||
|
||||
await delay(300);
|
||||
|
||||
// 依次发送每个角色的消息
|
||||
for (const role of roleMessages) {
|
||||
// speaking_start
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'speaking_start',
|
||||
role_id: role.role_id,
|
||||
role_name: role.role_name,
|
||||
})}\n\n`));
|
||||
|
||||
await delay(200);
|
||||
|
||||
// 发送工具调用
|
||||
for (const tool of role.tools) {
|
||||
const toolCallId = `tc-${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
||||
|
||||
// tool_call_start
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'tool_call_start',
|
||||
role_id: role.role_id,
|
||||
tool_call_id: toolCallId,
|
||||
tool_name: tool.name,
|
||||
arguments: {},
|
||||
})}\n\n`));
|
||||
|
||||
await delay(500);
|
||||
|
||||
// tool_call_result
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'tool_call_result',
|
||||
role_id: role.role_id,
|
||||
tool_call_id: toolCallId,
|
||||
result: tool.result,
|
||||
status: 'success',
|
||||
execution_time: 0.5 + Math.random() * 0.5,
|
||||
})}\n\n`));
|
||||
|
||||
await delay(200);
|
||||
}
|
||||
|
||||
// 流式发送内容
|
||||
const chunks = role.content.match(/.{1,20}/g) || [];
|
||||
for (const chunk of chunks) {
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'content_delta',
|
||||
role_id: role.role_id,
|
||||
content: chunk,
|
||||
})}\n\n`));
|
||||
await delay(30);
|
||||
}
|
||||
|
||||
// message_complete
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'message_complete',
|
||||
role_id: role.role_id,
|
||||
content: role.content,
|
||||
is_conclusion: role.is_conclusion || false,
|
||||
})}\n\n`));
|
||||
|
||||
await delay(500);
|
||||
}
|
||||
|
||||
// round_end
|
||||
controller.enqueue(encoder.encode(`data: ${JSON.stringify({
|
||||
type: 'round_end',
|
||||
round_number: 1,
|
||||
is_concluded: false,
|
||||
})}\n\n`));
|
||||
|
||||
controller.close();
|
||||
},
|
||||
});
|
||||
|
||||
return new Response(stream, {
|
||||
headers: {
|
||||
'Content-Type': 'text/event-stream',
|
||||
'Cache-Control': 'no-cache',
|
||||
'Connection': 'keep-alive',
|
||||
},
|
||||
});
|
||||
}),
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user