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:
@@ -6,7 +6,7 @@ generator client {
|
||||
datasource db {
|
||||
provider = "postgresql"
|
||||
url = env("DATABASE_URL")
|
||||
schemas = ["admin_schema", "aia_schema", "asl_schema", "capability_schema", "common_schema", "dc_schema", "ekb_schema", "iit_schema", "pkb_schema", "platform_schema", "public", "rvw_schema", "ssa_schema", "st_schema"]
|
||||
schemas = ["admin_schema", "agent_schema", "aia_schema", "asl_schema", "capability_schema", "common_schema", "dc_schema", "ekb_schema", "iit_schema", "pkb_schema", "platform_schema", "protocol_schema", "public", "rvw_schema", "ssa_schema", "st_schema"]
|
||||
}
|
||||
|
||||
/// 应用缓存表 - Postgres-Only架构
|
||||
@@ -1393,3 +1393,303 @@ model EkbChunk {
|
||||
@@map("ekb_chunk")
|
||||
@@schema("ekb_schema")
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Agent Framework Schema (agent_schema)
|
||||
// 通用Agent框架 - 可复用于多种Agent类型
|
||||
// ============================================================
|
||||
|
||||
/// Agent定义表 - 存储Agent的基本配置
|
||||
model AgentDefinition {
|
||||
id String @id @default(uuid())
|
||||
code String @unique /// 唯一标识: protocol_agent, stat_agent
|
||||
name String /// 显示名称
|
||||
description String? /// 描述
|
||||
version String @default("1.0.0") /// 版本号
|
||||
|
||||
/// Agent配置
|
||||
config Json? @db.JsonB /// 全局配置 { defaultModel, maxTurns, timeout }
|
||||
|
||||
/// 状态
|
||||
isActive Boolean @default(true) @map("is_active")
|
||||
|
||||
/// 关联
|
||||
stages AgentStage[]
|
||||
prompts AgentPrompt[]
|
||||
sessions AgentSession[]
|
||||
reflexionRules ReflexionRule[]
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@index([code], map: "idx_agent_def_code")
|
||||
@@index([isActive], map: "idx_agent_def_active")
|
||||
@@map("agent_definitions")
|
||||
@@schema("agent_schema")
|
||||
}
|
||||
|
||||
/// Agent阶段配置表 - 定义Agent的工作流阶段
|
||||
model AgentStage {
|
||||
id String @id @default(uuid())
|
||||
agentId String @map("agent_id") /// 关联的Agent
|
||||
|
||||
/// 阶段标识
|
||||
stageCode String @map("stage_code") /// 阶段代码: scientific_question, pico
|
||||
stageName String @map("stage_name") /// 阶段名称: 科学问题梳理
|
||||
sortOrder Int @map("sort_order") /// 排序顺序
|
||||
|
||||
/// 阶段配置
|
||||
config Json? @db.JsonB /// 阶段特定配置
|
||||
|
||||
/// 状态机配置
|
||||
nextStages String[] @map("next_stages") /// 可转换的下一阶段列表
|
||||
isInitial Boolean @default(false) @map("is_initial") /// 是否为起始阶段
|
||||
isFinal Boolean @default(false) @map("is_final") /// 是否为结束阶段
|
||||
|
||||
/// 关联
|
||||
agent AgentDefinition @relation(fields: [agentId], references: [id], onDelete: Cascade)
|
||||
prompts AgentPrompt[]
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@unique([agentId, stageCode], map: "unique_agent_stage")
|
||||
@@index([agentId], map: "idx_agent_stage_agent")
|
||||
@@index([sortOrder], map: "idx_agent_stage_order")
|
||||
@@map("agent_stages")
|
||||
@@schema("agent_schema")
|
||||
}
|
||||
|
||||
/// Agent Prompt模板表 - 存储各阶段的Prompt
|
||||
model AgentPrompt {
|
||||
id String @id @default(uuid())
|
||||
agentId String @map("agent_id") /// 关联的Agent
|
||||
stageId String? @map("stage_id") /// 关联的阶段(可选,null表示通用Prompt)
|
||||
|
||||
/// Prompt标识
|
||||
promptType String @map("prompt_type") /// system, stage, extraction, reflexion
|
||||
promptCode String @map("prompt_code") /// 唯一代码
|
||||
|
||||
/// Prompt内容
|
||||
content String @db.Text /// Prompt模板内容(支持变量)
|
||||
variables String[] /// 预期变量列表
|
||||
|
||||
/// 版本控制
|
||||
version Int @default(1) /// 版本号
|
||||
isActive Boolean @default(true) @map("is_active")
|
||||
|
||||
/// 关联
|
||||
agent AgentDefinition @relation(fields: [agentId], references: [id], onDelete: Cascade)
|
||||
stage AgentStage? @relation(fields: [stageId], references: [id], onDelete: SetNull)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@unique([agentId, promptCode, version], map: "unique_agent_prompt_version")
|
||||
@@index([agentId, promptType], map: "idx_agent_prompt_type")
|
||||
@@index([stageId], map: "idx_agent_prompt_stage")
|
||||
@@map("agent_prompts")
|
||||
@@schema("agent_schema")
|
||||
}
|
||||
|
||||
/// Agent会话表 - 存储Agent的运行时会话状态
|
||||
model AgentSession {
|
||||
id String @id @default(uuid())
|
||||
agentId String @map("agent_id") /// 关联的Agent定义
|
||||
conversationId String @map("conversation_id") /// 关联的对话ID(aia_schema.conversations)
|
||||
userId String @map("user_id") /// 用户ID
|
||||
|
||||
/// 当前状态
|
||||
currentStage String @map("current_stage") /// 当前阶段代码
|
||||
status String @default("active") /// active, completed, paused, error
|
||||
|
||||
/// 上下文数据(具体Agent的上下文存储在对应schema)
|
||||
contextRef String? @map("context_ref") /// 上下文引用ID(如protocol_schema.protocol_contexts.id)
|
||||
|
||||
/// 统计信息
|
||||
turnCount Int @default(0) @map("turn_count") /// 对话轮数
|
||||
totalTokens Int @default(0) @map("total_tokens") /// 总Token数
|
||||
|
||||
/// 关联
|
||||
agent AgentDefinition @relation(fields: [agentId], references: [id])
|
||||
traces AgentTrace[]
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@unique([conversationId], map: "unique_agent_session_conv")
|
||||
@@index([agentId], map: "idx_agent_session_agent")
|
||||
@@index([userId], map: "idx_agent_session_user")
|
||||
@@index([status], map: "idx_agent_session_status")
|
||||
@@map("agent_sessions")
|
||||
@@schema("agent_schema")
|
||||
}
|
||||
|
||||
/// Agent执行追踪表 - 记录每一步的执行详情
|
||||
model AgentTrace {
|
||||
id String @id @default(uuid())
|
||||
sessionId String @map("session_id") /// 关联的会话
|
||||
|
||||
/// 追踪信息
|
||||
traceId String @map("trace_id") /// 请求追踪ID(用于关联日志)
|
||||
stepIndex Int @map("step_index") /// 步骤序号
|
||||
stepType String @map("step_type") /// query, plan, execute, reflect, tool_call
|
||||
|
||||
/// 输入输出
|
||||
input Json? @db.JsonB /// 步骤输入
|
||||
output Json? @db.JsonB /// 步骤输出
|
||||
|
||||
/// 执行信息
|
||||
stageCode String? @map("stage_code") /// 执行时的阶段
|
||||
modelUsed String? @map("model_used") /// 使用的模型
|
||||
tokensUsed Int? @map("tokens_used") /// 消耗的Token
|
||||
durationMs Int? @map("duration_ms") /// 执行时长(毫秒)
|
||||
|
||||
/// 错误信息
|
||||
errorType String? @map("error_type") /// 错误类型
|
||||
errorMsg String? @map("error_msg") /// 错误信息
|
||||
|
||||
/// 关联
|
||||
session AgentSession @relation(fields: [sessionId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
|
||||
@@index([sessionId, stepIndex], map: "idx_agent_trace_session_step")
|
||||
@@index([traceId], map: "idx_agent_trace_trace_id")
|
||||
@@index([stepType], map: "idx_agent_trace_step_type")
|
||||
@@map("agent_traces")
|
||||
@@schema("agent_schema")
|
||||
}
|
||||
|
||||
/// Reflexion规则表 - 定义质量检查规则
|
||||
model ReflexionRule {
|
||||
id String @id @default(uuid())
|
||||
agentId String @map("agent_id") /// 关联的Agent
|
||||
|
||||
/// 规则标识
|
||||
ruleCode String @map("rule_code") /// 规则代码
|
||||
ruleName String @map("rule_name") /// 规则名称
|
||||
|
||||
/// 触发条件
|
||||
triggerStage String? @map("trigger_stage") /// 触发阶段(null表示全局)
|
||||
triggerTiming String @map("trigger_timing") /// on_sync, on_stage_complete, on_generate
|
||||
|
||||
/// 规则类型
|
||||
ruleType String @map("rule_type") /// rule_based, prompt_based
|
||||
|
||||
/// 规则内容
|
||||
conditions Json? @db.JsonB /// 规则条件(rule_based时使用)
|
||||
promptTemplate String? @map("prompt_template") @db.Text /// Prompt模板(prompt_based时使用)
|
||||
|
||||
/// 行为配置
|
||||
severity String @default("warning") /// error, warning, info
|
||||
failureAction String @default("warn") @map("failure_action") /// block, warn, log
|
||||
|
||||
/// 状态
|
||||
isActive Boolean @default(true) @map("is_active")
|
||||
sortOrder Int @default(0) @map("sort_order")
|
||||
|
||||
/// 关联
|
||||
agent AgentDefinition @relation(fields: [agentId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@unique([agentId, ruleCode], map: "unique_agent_rule")
|
||||
@@index([agentId, triggerStage], map: "idx_reflexion_rule_agent_stage")
|
||||
@@index([isActive], map: "idx_reflexion_rule_active")
|
||||
@@map("reflexion_rules")
|
||||
@@schema("agent_schema")
|
||||
}
|
||||
|
||||
// ============================================================
|
||||
// Protocol Agent Schema (protocol_schema)
|
||||
// Protocol Agent专用 - 研究方案制定
|
||||
// ============================================================
|
||||
|
||||
/// Protocol Context表 - 存储研究方案的核心上下文数据
|
||||
model ProtocolContext {
|
||||
id String @id @default(uuid())
|
||||
conversationId String @unique @map("conversation_id") /// 关联的对话ID
|
||||
userId String @map("user_id")
|
||||
|
||||
/// 当前状态
|
||||
currentStage String @default("scientific_question") @map("current_stage")
|
||||
status String @default("in_progress") /// in_progress, completed, abandoned
|
||||
|
||||
/// ===== 5个核心阶段数据 =====
|
||||
|
||||
/// 阶段1: 科学问题
|
||||
scientificQuestion Json? @map("scientific_question") @db.JsonB
|
||||
/// { content, background, significance, confirmed, confirmedAt }
|
||||
|
||||
/// 阶段2: PICO
|
||||
pico Json? @db.JsonB
|
||||
/// { P: {value, details}, I: {}, C: {}, O: {}, confirmed, confirmedAt }
|
||||
|
||||
/// 阶段3: 研究设计
|
||||
studyDesign Json? @map("study_design") @db.JsonB
|
||||
/// { type, blinding, randomization, duration, multiCenter, confirmed }
|
||||
|
||||
/// 阶段4: 样本量
|
||||
sampleSize Json? @map("sample_size") @db.JsonB
|
||||
/// { total, perGroup, alpha, power, effectSize, dropoutRate, justification, confirmed }
|
||||
|
||||
/// 阶段5: 观察指标(终点指标)
|
||||
endpoints Json? @db.JsonB
|
||||
/// { primary: [{name, definition, method, timePoint}], secondary: [], safety: [], confirmed }
|
||||
|
||||
/// ===== 元数据 =====
|
||||
completedStages String[] @default([]) @map("completed_stages") /// 已完成的阶段列表
|
||||
lastActiveAt DateTime @default(now()) @map("last_active_at")
|
||||
|
||||
/// 关联
|
||||
generations ProtocolGeneration[]
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@index([userId], map: "idx_protocol_context_user")
|
||||
@@index([status], map: "idx_protocol_context_status")
|
||||
@@index([currentStage], map: "idx_protocol_context_stage")
|
||||
@@map("protocol_contexts")
|
||||
@@schema("protocol_schema")
|
||||
}
|
||||
|
||||
/// Protocol生成记录表 - 存储一键生成的研究方案
|
||||
model ProtocolGeneration {
|
||||
id String @id @default(uuid())
|
||||
contextId String @map("context_id") /// 关联的Context
|
||||
userId String @map("user_id")
|
||||
|
||||
/// 生成内容
|
||||
generatedContent String @map("generated_content") @db.Text /// 生成的研究方案全文(Markdown)
|
||||
contentVersion Int @default(1) @map("content_version") /// 版本号
|
||||
|
||||
/// 使用的Prompt
|
||||
promptUsed String @map("prompt_used") @db.Text /// 实际使用的Prompt
|
||||
|
||||
/// 生成参数
|
||||
modelUsed String @map("model_used") /// 使用的模型
|
||||
tokensUsed Int? @map("tokens_used") /// 消耗的Token
|
||||
durationMs Int? @map("duration_ms") /// 生成耗时(毫秒)
|
||||
|
||||
/// 导出记录
|
||||
wordFileKey String? @map("word_file_key") /// Word文件OSS Key
|
||||
lastExportedAt DateTime? @map("last_exported_at")
|
||||
|
||||
/// 状态
|
||||
status String @default("completed") /// generating, completed, failed
|
||||
errorMessage String? @map("error_message")
|
||||
|
||||
/// 关联
|
||||
context ProtocolContext @relation(fields: [contextId], references: [id], onDelete: Cascade)
|
||||
|
||||
createdAt DateTime @default(now()) @map("created_at")
|
||||
updatedAt DateTime @updatedAt @map("updated_at")
|
||||
|
||||
@@index([contextId], map: "idx_protocol_gen_context")
|
||||
@@index([userId, createdAt], map: "idx_protocol_gen_user_time")
|
||||
@@map("protocol_generations")
|
||||
@@schema("protocol_schema")
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user