feat(ssa): Complete Phase I-IV intelligent dialogue and tool system development

Phase I - Session Blackboard + READ Layer:
- SessionBlackboardService with Postgres-Only cache
- DataProfileService for data overview generation
- PicoInferenceService for LLM-driven PICO extraction
- Frontend DataContextCard and VariableDictionaryPanel
- E2E tests: 31/31 passed

Phase II - Conversation Layer LLM + Intent Router:
- ConversationService with SSE streaming
- IntentRouterService (rule-first + LLM fallback, 6 intents)
- SystemPromptService with 6-segment dynamic assembly
- TokenTruncationService for context management
- ChatHandlerService as unified chat entry
- Frontend SSAChatPane and useSSAChat hook
- E2E tests: 38/38 passed

Phase III - Method Consultation + AskUser Standardization:
- ToolRegistryService with Repository Pattern
- MethodConsultService with DecisionTable + LLM enhancement
- AskUserService with global interrupt handling
- Frontend AskUserCard component
- E2E tests: 13/13 passed

Phase IV - Dialogue-Driven Analysis + QPER Integration:
- ToolOrchestratorService (plan/execute/report)
- analysis_plan SSE event for WorkflowPlan transmission
- Dual-channel confirmation (ask_user card + workspace button)
- PICO as optional hint for LLM parsing
- E2E tests: 25/25 passed

R Statistics Service:
- 5 new R tools: anova_one, baseline_table, fisher, linear_reg, wilcoxon
- Enhanced guardrails and block helpers
- Comprehensive test suite (run_all_tools_test.js)

Documentation:
- Updated system status document (v5.9)
- Updated SSA module status and development plan (v1.8)

Total E2E: 107/107 passed (Phase I: 31, Phase II: 38, Phase III: 13, Phase IV: 25)

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
2026-02-22 18:53:39 +08:00
parent bf10dec4c8
commit 3446909ff7
68 changed files with 11583 additions and 412 deletions

View File

@@ -0,0 +1,135 @@
/**
* Phase III — method_consult Prompt 种子脚本
*
* 写入 Prompt 模板:
* 1. SSA_METHOD_CONSULT — 方法推荐指令P1: 结论先行 + 结构化列表)
*
* 运行方式: npx tsx scripts/seed-ssa-phase3-prompts.ts
* 前置: 数据库已启动
*/
import { PrismaClient } from '@prisma/client';
const prisma = new PrismaClient();
interface PromptDef {
code: string;
name: string;
description: string;
variables: string[];
content: string;
modelConfig: Record<string, any>;
}
const PROMPTS: PromptDef[] = [
{
code: 'SSA_METHOD_CONSULT',
name: 'SSA 方法推荐指令',
description: 'Phase III — method_consult 工具调用后,指导 LLM 生成结构化方法推荐P1 格式约束)',
variables: [],
content: `## 当前任务:统计方法推荐
你正在为用户推荐统计分析方法。系统已通过决策表匹配到候选方法,匹配结果在"工具执行结果"中给出。
### 输出要求(严格遵守)
1. **首先用一句话给出明确的推荐**(如:"建议采用独立样本 T 检验"
2. 然后使用 Markdown 列表分别列出:
- **选择理由** (Rationale):为什么这个方法适合当前数据和研究目的
- **必须满足的前提条件** (Prerequisites):该方法对数据的要求(如正态性、样本量等)
- **备选降级方案** (Alternatives):如果前提条件不满足,应该切换到什么方法
3. 如果匹配结果包含降级方案,必须说明切换条件
4. 如果匹配不完整或信息不足,诚实告知用户需要补充什么信息
### 禁止事项
- 严禁生成大段的不分段的长篇大论
- 严禁直接执行分析,只推荐方法
- 严禁编造数据特征或假设用户未提供的信息`,
modelConfig: { model: 'deepseek-v3', temperature: 0.5, maxTokens: 1500 },
},
];
async function upsertPrompt(def: PromptDef): Promise<void> {
const existing = await prisma.prompt_templates.findUnique({
where: { code: def.code },
});
if (existing) {
const latestVersion = await prisma.prompt_versions.findFirst({
where: { template_id: existing.id },
orderBy: { version: 'desc' },
});
const activeVersion = await prisma.prompt_versions.findFirst({
where: { template_id: existing.id, status: 'ACTIVE' },
});
if (activeVersion && activeVersion.content === def.content) {
console.log(` ⏭️ ${def.code} 内容未变化,跳过`);
return;
}
const newVersion = (latestVersion?.version ?? 0) + 1;
await prisma.prompt_versions.updateMany({
where: { template_id: existing.id, status: 'ACTIVE' },
data: { status: 'ARCHIVED' },
});
await prisma.prompt_versions.create({
data: {
template_id: existing.id,
version: newVersion,
content: def.content,
model_config: def.modelConfig,
status: 'ACTIVE',
changelog: `Phase III v${newVersion}: ${def.description}`,
created_by: 'system-seed',
},
});
console.log(`${def.code} 更新到 v${newVersion}`);
} else {
const template = await prisma.prompt_templates.create({
data: {
code: def.code,
name: def.name,
module: 'SSA',
description: def.description,
variables: def.variables,
},
});
await prisma.prompt_versions.create({
data: {
template_id: template.id,
version: 1,
content: def.content,
model_config: def.modelConfig,
status: 'ACTIVE',
changelog: `Phase III v1.0: ${def.description}`,
created_by: 'system-seed',
},
});
console.log(`${def.code} 创建成功 (id=${template.id})`);
}
}
async function main() {
console.log('🚀 开始写入 SSA Phase III Prompt 模板...\n');
for (const def of PROMPTS) {
console.log(`📝 处理 ${def.code} (${def.name})...`);
await upsertPrompt(def);
}
console.log(`\n✅ 全部 ${PROMPTS.length} 个 Prompt 模板写入完成!`);
}
main()
.catch(e => {
console.error('❌ Seed 失败:', e);
process.exit(1);
})
.finally(() => prisma.$disconnect());