2baf29b3ae
Deliver encrypted health zone, observation API, baseline maturity pipeline, page-data bindings, and H5/WeChat channel integration for health P0. Co-authored-by: Cursor <cursoragent@cursor.com>
70 lines
2.7 KiB
JavaScript
70 lines
2.7 KiB
JavaScript
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}`;
|
||
}
|