diff --git a/frontend/src/api/chat.ts b/frontend/src/api/chat.ts index 6ed71ff4..83c05266 100644 --- a/frontend/src/api/chat.ts +++ b/frontend/src/api/chat.ts @@ -20,6 +20,8 @@ export interface ChatMessage { export interface SendMessageRequest { session_id: string content: string + team_id?: string | null + team_name?: string | null } export interface ChatHistoryResponse { @@ -85,15 +87,21 @@ export interface ErrorEvent { export interface DebugEvent { type: 'debug' - debug_type: 'classification' | 'routing' | 'agent_start' | 'agent_end' | 'tool_result' | 'handoff' | 'data_sharing' | 'discussion_argument' | 'decision_summary' | 'preview_signal' | 'arena_error' + debug_type: 'classification' | 'routing' | 'agent_start' | 'agent_end' | 'tool_result' | 'handoff' | 'data_sharing' | 'discussion_argument' | 'decision_summary' | 'preview_signal' | 'arena_error' | 'decision_trace' agent: string timestamp: number data: { - // classification + // classification / decision_trace intent?: string selected_agent?: string + selected_team?: string rationale?: string available_agents?: string[] + stage?: 'orchestrator' | 'team_agent' | 'team_summary' | 'agent' + title?: string + role?: string + key_points?: string[] + direction?: 'bullish' | 'bearish' | 'neutral' // routing from_agent?: string to_agent?: string @@ -189,6 +197,7 @@ export const chatApi = { async streamMessagePost( sessionId: string, content: string, + team: { team_id?: string | null; team_name?: string | null } | null, onEvent: (event: StreamEvent) => void, onError?: (error: Error) => void, abortController?: AbortController @@ -211,7 +220,9 @@ export const chatApi = { headers, body: JSON.stringify({ session_id: sessionId, - content: content + content: content, + ...(team?.team_id ? { team_id: team.team_id } : {}), + ...(team?.team_name ? { team_name: team.team_name } : {}) }), signal: controller.signal }) diff --git a/frontend/src/stores/chat.ts b/frontend/src/stores/chat.ts index 93967024..0d730f79 100644 --- a/frontend/src/stores/chat.ts +++ b/frontend/src/stores/chat.ts @@ -140,6 +140,10 @@ export const useChatStore = defineStore('chat', () => { } | null>(null) const decisionSidebarOpen = ref(false) + // Selected Agent team for Chat requests + const activeTeamId = ref(null) + const activeTeamName = ref(null) + // Preview signal state (instant rule-based, before full LLM synthesis) const previewSignal = ref<{ signal: 'BUY' | 'SELL' | 'HOLD' @@ -492,7 +496,7 @@ export const useChatStore = defineStore('chat', () => { role = 'handoff' } else if (debugType === 'data_sharing') { role = 'system' - } else if (debugType === 'discussion_argument' || debugType === 'decision_summary' || debugType === 'preview_signal' || debugType === 'arena_error') { + } else if (debugType === 'discussion_argument' || debugType === 'decision_summary' || debugType === 'preview_signal' || debugType === 'arena_error' || debugType === 'decision_trace') { role = 'discussion' } @@ -541,6 +545,20 @@ export const useChatStore = defineStore('chat', () => { console.log('[Chat] Preview signal received:', previewSignal.value) } + // Special handling for decision_trace team_summary: update decision state + if (debugType === 'decision_trace' && data.stage === 'team_summary' && data.signal) { + previewSignal.value = null + decisionSummary.value = { + signal: data.signal as 'BUY' | 'SELL' | 'HOLD' | 'NONE', + confidence: data.confidence || 0, + bull_count: data.bull_count || 0, + bear_count: data.bear_count || 0, + neutral_count: data.neutral_count || 0, + suggested_action: data.suggested_action || '', + } + decisionSidebarOpen.value = true + } + // Special handling for decision_summary: update decision state (upgrades preview) if (debugType === 'decision_summary' && data.signal) { // Clear preview signal — the full summary replaces it @@ -586,6 +604,16 @@ export const useChatStore = defineStore('chat', () => { } } + const setActiveTeam = (team: { id?: string; name?: string } | null) => { + activeTeamId.value = team?.id || null + activeTeamName.value = team?.name || null + } + + const clearActiveTeam = () => { + activeTeamId.value = null + activeTeamName.value = null + } + const sendMessage = async (content: string) => { if (!sessionId.value) { await initSession() @@ -629,6 +657,9 @@ export const useChatStore = defineStore('chat', () => { await chatApi.streamMessagePost( sendingSessionId, content, + activeTeamId.value || activeTeamName.value + ? { team_id: activeTeamId.value, team_name: activeTeamName.value } + : null, (event: StreamEvent) => { // SESSION GUARD: If user switched sessions, discard stale events if (sessionId.value !== sendingSessionId) { @@ -899,6 +930,8 @@ export const useChatStore = defineStore('chat', () => { decisionSummary, decisionSidebarOpen, previewSignal, + activeTeamId, + activeTeamName, lastSessionRef, // Actions initSession, @@ -909,6 +942,8 @@ export const useChatStore = defineStore('chat', () => { updateSessionTitle, newConversation, clearCurrentConversation, + setActiveTeam, + clearActiveTeam, sendMessage, loadHistory, clearMessages, diff --git a/frontend/src/views/chat/ChatView.vue b/frontend/src/views/chat/ChatView.vue index 057a11f0..a7328f64 100644 --- a/frontend/src/views/chat/ChatView.vue +++ b/frontend/src/views/chat/ChatView.vue @@ -28,10 +28,10 @@ const loadTeams = async () => { } const handleTeamChat = (team: any) => { - // Send team name as message to trigger multi-agent collaboration - const msg = `请使用"${team.name}"团队模式来协作处理我的下一个问题` + chatStore.setActiveTeam(team) + chatStore.decisionSidebarOpen = true showTeamPanel.value = false - handleSend(msg) + MessagePlugin.success(`已启用 ${team.name} 团队模式`) } const showSessionsSidebar = ref(false) const editingSessionId = ref('') @@ -267,7 +267,7 @@ onMounted(async () => { MessagePlugin.error('加载历史对话失败,请重新登录后重试') } - // 加载Agent Teams + // 加载投研团队 loadTeams() }) @@ -569,14 +569,21 @@ const syncUrlToSession = () => { @click="showTeamPanel = !showTeamPanel" > - Agent Teams + 投研团队 - +
+ + 当前团队:{{ chatStore.activeTeamName }} + + 退出团队模式 +
+ +
- Agent 团队 + 投研团队 管理团队
@@ -589,11 +596,11 @@ const syncUrlToSession = () => {
{{ team.name }} - {{ team.description || '多Agent协作' }} + {{ team.description || '投研角色协作' }}
- 暂无团队,去Agent中心创建 + 暂无团队,去 AI Agent 投研创建
@@ -832,6 +839,13 @@ const syncUrlToSession = () => { opacity: 0.8; } +.active-team-bar { + display: flex; + align-items: center; + gap: 8px; + margin-bottom: 10px; +} + /* Workflow Panel */ .workflow-panel { background: var(--td-bg-color-secondarycontainer, #f5f5f5); diff --git a/frontend/src/views/chat/components/AgentDiscussionSidebar.vue b/frontend/src/views/chat/components/AgentDiscussionSidebar.vue index 5b8f892a..630aa973 100644 --- a/frontend/src/views/chat/components/AgentDiscussionSidebar.vue +++ b/frontend/src/views/chat/components/AgentDiscussionSidebar.vue @@ -63,38 +63,95 @@ - +
-