feat(rvw,asl): RVW V3.0 smart review + ASL deep research history + stability
RVW module (V3.0 Smart Review Enhancement): - Add LLM data validation via PromptService (RVW_DATA_VALIDATION) - Add ClinicalAssessmentSkill with FINER-based evaluation (RVW_CLINICAL) - Remove all numeric scores from UI (editorial, methodology, overall) - Implement partial_completed status with Promise.allSettled - Add error_details JSON field to ReviewTask for granular failure info - Fix overallStatus logic: warning status now counts as success - Restructure ForensicsReport: per-table LLM results, remove top-level block - Refactor ClinicalReport: structured collapsible sections - Increase all skill timeouts to 300s for long manuscripts (20+ pages) - Increase DataForensics LLM timeout to 180s, pg-boss to 15min - Executor default fallback timeout 30s -> 60s ASL module: - Add deep research history with sidebar accordion UI - Implement waterfall flow for historical task display - Upgrade Unifuncs DeepSearch API from S2 to S3 with fallback - Add ASL_SR module seed for admin configurability - Fix new search button inconsistency Docs: - Update RVW module status to V3.0 - Update deployment changelist - Add 0305 deployment summary DB Migration: - Add error_details JSONB column to rvw_schema.review_tasks Tested: All 4 review modules verified, partial completion working Made-with: Cursor
This commit is contained in:
75
backend/src/modules/rvw/services/clinicalService.ts
Normal file
75
backend/src/modules/rvw/services/clinicalService.ts
Normal file
@@ -0,0 +1,75 @@
|
||||
/**
|
||||
* RVW稿件审查模块 - 临床专业评估服务
|
||||
* @module rvw/services/clinicalService
|
||||
*
|
||||
* 使用 PromptService 获取 RVW_CLINICAL prompt
|
||||
* 返回纯 Markdown 报告(无分数)
|
||||
*/
|
||||
|
||||
import { LLMFactory } from '../../../common/llm/adapters/LLMFactory.js';
|
||||
import { ModelType } from '../../../common/llm/adapters/types.js';
|
||||
import { logger } from '../../../common/logging/index.js';
|
||||
import { prisma } from '../../../config/database.js';
|
||||
import { getPromptService } from '../../../common/prompt/index.js';
|
||||
|
||||
export interface ClinicalReviewResult {
|
||||
report: string;
|
||||
summary: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* 临床专业评估
|
||||
* @param text 稿件文本
|
||||
* @param modelType 模型类型
|
||||
* @param userId 用户ID(用于灰度预览判断)
|
||||
* @returns 评估结果(Markdown 报告 + 摘要)
|
||||
*/
|
||||
export async function reviewClinical(
|
||||
text: string,
|
||||
modelType: ModelType = 'deepseek-v3',
|
||||
userId?: string
|
||||
): Promise<ClinicalReviewResult> {
|
||||
try {
|
||||
const promptService = getPromptService(prisma);
|
||||
const { content: systemPrompt, isDraft } = await promptService.get(
|
||||
'RVW_CLINICAL',
|
||||
{},
|
||||
{ userId }
|
||||
);
|
||||
|
||||
if (isDraft) {
|
||||
logger.info('[RVW:Clinical] 使用 DRAFT 版本 Prompt(调试模式)', { userId });
|
||||
}
|
||||
|
||||
const messages = [
|
||||
{ role: 'system' as const, content: systemPrompt },
|
||||
{ role: 'user' as const, content: `请对以下医学稿件进行临床专业评估:\n\n${text}` },
|
||||
];
|
||||
|
||||
logger.info('[RVW:Clinical] 开始临床专业评估', { modelType });
|
||||
const llmAdapter = LLMFactory.getAdapter(modelType);
|
||||
const response = await llmAdapter.chat(messages, {
|
||||
temperature: 0.3,
|
||||
maxTokens: 8000,
|
||||
});
|
||||
const content = response.content ?? '';
|
||||
logger.info('[RVW:Clinical] 评估完成', {
|
||||
modelType,
|
||||
responseLength: content.length,
|
||||
});
|
||||
|
||||
// 提取摘要:取第一段非标题文本(最多200字)
|
||||
const lines = content.split('\n').filter(l => l.trim() && !l.startsWith('#'));
|
||||
const summary = lines.length > 0
|
||||
? lines[0].trim().substring(0, 200)
|
||||
: '临床专业评估已完成';
|
||||
|
||||
return { report: content, summary };
|
||||
} catch (error) {
|
||||
logger.error('[RVW:Clinical] 临床专业评估失败', {
|
||||
error: error instanceof Error ? error.message : 'Unknown error',
|
||||
stack: error instanceof Error ? error.stack : undefined,
|
||||
});
|
||||
throw new Error(`临床专业评估失败: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user