import { buildHealthAssessSummary } from './health-assess-summary.mjs'; import { buildHealthTimeline } from './health-timeline.mjs'; import { computeHealthBaselines } from './health-baseline-engine.mjs'; import { evaluateHealthEvents } from './health-event-engine.mjs'; export function buildHealthAgentContext( observations = [], { now = Date.now(), limitDays = 30, documents = [] } = {}, ) { const timeline = buildHealthTimeline(observations, { limitDays }); const baselines = computeHealthBaselines(observations, { now }); const events = evaluateHealthEvents(observations, baselines, { now, mode: 'active' }); const summary = buildHealthAssessSummary(observations, { now }); const lines = [ '【本人健康档案摘要 — 仅供 health-assistant 解释,勿当作诊断】', summary, ]; if (timeline.length >= 2) { lines.push('', '【近几日记录摘要】'); for (const day of timeline.slice(0, 7)) { const metricText = Object.values(day.metrics) .map((item) => `${item.label} ${item.value}`) .join(';'); lines.push(`- ${day.date}: ${metricText || '无结构化读数'}`); } } const openEvents = events.filter((e) => e.severity === 'watch' || e.severity === 'alert'); if (openEvents.length > 0) { lines.push('', '【开放事件】'); for (const event of openEvents.slice(0, 5)) { lines.push(`- ${event.message}`); } } const docRows = Array.isArray(documents) ? documents : []; if (docRows.length > 0) { lines.push('', '【已归档报告】'); for (const doc of docRows.slice(0, 10)) { const date = doc.reportDate ?? (doc.createdAt ? new Date(doc.createdAt).toISOString().slice(0, 10) : '未知日期'); const title = doc.notes ?? doc.docType ?? '报告'; const metricHint = doc.extractedMetrics?.length ? `(OCR 提取 ${doc.extractedMetrics.length} 项)` : ''; lines.push(`- ${date} ${title}${metricHint}`); if (doc.ocrText) { const excerpt = String(doc.ocrText).replace(/\s+/g, ' ').trim().slice(0, 240); if (excerpt) lines.push(` 摘要: ${excerpt}${doc.ocrText.length > 240 ? '…' : ''}`); } } } lines.push( '', '请基于以上档案回答用户问题;若用户要求健康报告,输出结构化章节(概况、近期趋势、需留意项、建议下一步)。', '禁止诊断口吻;只解释变化并建议复测或就医。', ); return lines.join('\n'); } export function wrapHealthAgentUserMessage(context, userText) { const trimmed = String(userText ?? '').trim(); const block = String(context ?? '').trim(); if (!block) return trimmed; return `[系统提供的本人健康档案摘要,勿当作用户原话]\n${block}\n\n[用户问题]\n${trimmed}`; }