feat(aia): Implement Protocol Agent MVP with reusable Agent framework

Sprint 1-3 Completed (Backend + Frontend):

Backend (Sprint 1-2):
- Implement 5-layer Agent framework (Query->Planner->Executor->Tools->Reflection)
- Create agent_schema with 6 tables (agent_definitions, stages, prompts, sessions, traces, reflexion_rules)
- Create protocol_schema with 2 tables (protocol_contexts, protocol_generations)
- Implement Protocol Agent core services (Orchestrator, ContextService, PromptBuilder)
- Integrate LLM service adapter (DeepSeek/Qwen/GPT-5/Claude)
- 6 API endpoints with full authentication
- 10/10 API tests passed

Frontend (Sprint 3):
- Add Protocol Agent entry in AgentHub (indigo theme card)
- Implement ProtocolAgentPage with 3-column layout
- Collapsible sidebar (Gemini style, 48px <-> 280px)
- StatePanel with 5 stage cards (scientific_question, pico, study_design, sample_size, endpoints)
- ChatArea with sync button and action cards integration
- 100% prototype design restoration (608 lines CSS)
- Detailed endpoints structure: baseline, exposure, outcomes, confounders

Features:
- 5-stage dialogue flow for research protocol design
- Conversation-driven interaction with sync-to-protocol button
- Real-time context state management
- One-click protocol generation button (UI ready, backend pending)

Database:
- agent_schema: 6 tables for reusable Agent framework
- protocol_schema: 2 tables for Protocol Agent
- Seed data: 1 agent + 5 stages + 9 prompts + 4 reflexion rules

Code Stats:
- Backend: 13 files, 4338 lines
- Frontend: 14 files, 2071 lines
- Total: 27 files, 6409 lines

Status: MVP core functionality completed, pending frontend-backend integration testing

Next: Sprint 4 - One-click protocol generation + Word export
This commit is contained in:
2026-01-24 17:29:24 +08:00
parent 61cdc97eeb
commit 96290d2f76
345 changed files with 13945 additions and 47 deletions

View File

@@ -1,49 +1,80 @@
/**
* AIA - AI Intelligent Assistant 模块入口
*
* 视图管理:
* - Hub: 智能体大厅12个模块展示
* - Chat: 沉浸式对话工作台
* 路由管理:
* - /aia -> Hub: 智能体大厅12个模块展示
* - /aia/chat -> Chat: 沉浸式对话工作台原12个智能体
* - /aia/protocol-agent/:conversationId? -> Protocol Agent全流程方案制定
*/
import React, { useState } from 'react';
import { Routes, Route, useNavigate, useLocation } from 'react-router-dom';
import { AgentHub } from './components/AgentHub';
import { ChatWorkspace } from './components/ChatWorkspace';
import { ProtocolAgentPage } from './protocol-agent';
import type { AgentConfig } from './types';
const AIAModule: React.FC = () => {
const [currentView, setCurrentView] = useState<'hub' | 'chat'>('hub');
const [selectedAgent, setSelectedAgent] = useState<AgentConfig | null>(null);
const [initialQuery, setInitialQuery] = useState<string | undefined>();
return (
<Routes>
{/* 智能体大厅 */}
<Route index element={<AIAHub />} />
{/* Protocol Agent全流程研究方案制定 */}
<Route path="protocol-agent/:conversationId?" element={<ProtocolAgentPage />} />
{/* 传统智能体对话(向后兼容) */}
<Route path="chat" element={<AIAChat />} />
</Routes>
);
};
/**
* Hub 页面
*/
const AIAHub: React.FC = () => {
const navigate = useNavigate();
// 选择智能体,进入对话
const handleAgentSelect = (agent: AgentConfig & { initialQuery?: string }) => {
setSelectedAgent(agent);
setInitialQuery(agent.initialQuery);
setCurrentView('chat');
console.log('[AIAHub] Agent selected:', agent.id, 'isProtocolAgent:', agent.isProtocolAgent);
if (agent.isProtocolAgent) {
// Protocol Agent跳转专属页面
console.log('[AIAHub] Navigating to /aia/protocol-agent');
navigate('/aia/protocol-agent');
} else {
// 传统智能体:跳转对话页面
console.log('[AIAHub] Navigating to /aia/chat');
navigate('/aia/chat', { state: { agent, initialQuery: agent.initialQuery } });
}
};
// 返回大厅
return <AgentHub onAgentSelect={handleAgentSelect} />;
};
/**
* 传统智能体对话页面
*/
const AIAChat: React.FC = () => {
const navigate = useNavigate();
const location = useLocation();
const state = location.state as { agent: AgentConfig; initialQuery?: string } | null;
const handleBack = () => {
setCurrentView('hub');
setSelectedAgent(null);
setInitialQuery(undefined);
navigate('/aia');
};
if (!state?.agent) {
navigate('/aia');
return null;
}
return (
<>
{currentView === 'hub' && (
<AgentHub onAgentSelect={handleAgentSelect} />
)}
{currentView === 'chat' && selectedAgent && (
<ChatWorkspace
agent={selectedAgent}
initialQuery={initialQuery}
onBack={handleBack}
/>
)}
</>
<ChatWorkspace
agent={state.agent}
initialQuery={state.initialQuery}
onBack={handleBack}
/>
);
};