mirror of
https://github.com/MBombeck/HealthLog.git
synced 2026-11-11 05:42:19 +00:00
A gateway that refuses reasoning_effort outright (LiteLLM in front of Ollama: "does not support parameters: ['reasoning_effort']") in front of a model that reasons without answering sent requests until something outside stopped it. The answerless rule learned to ask with "none", the refusal of that "none" was learned as "send no field" over it, the next request came back answerless again, and each lesson undid the other. Each call of the Local and the OpenAI-compatible gateway clients now carries one request budget through every repeat (request-hops.ts): at most two requests, after which the call ends with the failure it has. A structural guard holds both clients to sending only through the budget and to handing it to every repeat. The refusal is now learned as what it is: an endpoint that refuses the field, in front of a model already seen reasoning unasked, keeps both facts (FIELD_REFUSED_REASONS_REGARDLESS), so it is never asked with "none" again and keeps its thinking room. An answerless reply from an endpoint that refuses the field is final. When the refused "none" was the repeat of an answerless reply, the call fails as reasoning_only, which is what it ran into. The refusal handling of both clients lives in wire-refusal.ts. A status run that hits its bound now aborts the call it gave up on instead of leaving it running detached. Refs #1279
1550 lines
215 KiB
JSON
1550 lines
215 KiB
JSON
{
|
||
"bare-error-de": {
|
||
"calls": [
|
||
{
|
||
"maxTokens": 250,
|
||
"messages": [
|
||
{
|
||
"content": [
|
||
"Datum: 2026-06-15",
|
||
"OPENER HINT: Eröffne damit, was das heute für den Nutzer bedeutet, und dann die Zahl dahinter.",
|
||
"Schreibe eine kurze Gesamteinschätzung über die verfügbaren Gesundheitsdaten. Beginne mit dem Gesamteindruck in klaren Worten — wie es zusammengenommen aussieht, nicht mit einer Zahl (z. B. \"über alles hinweg eine ruhige Phase\", \"diese Woche sticht eine Sache heraus\") — und bring danach die ein bis zwei auffälligsten Metriken als Beleg, jeweils gegen die eigene Wochen-/Monats-Baseline eingeordnet; führe nie mit einem Wert. Schließe nur dann mit dem einen wichtigsten machbaren Schritt, wenn das Gesamtbild wirklich einen hergibt; ist nichts umsetzbar, lass den Schritt weg statt Fülltext zu erfinden. Konfidenz aus Messanzahl, Dichte und Aktualität ableiten.",
|
||
"",
|
||
"VORHERIGE ANALYSE: keine vorhanden. Behandle dies als erste Analyse in diesem Bereich — kein Verbesserungs-/Verschlechterungs-Delta zu nennen.",
|
||
"",
|
||
"",
|
||
"ABWECHSLUNG: damit deine Karten nicht gleich klingen, darfst du diese mit der Konstanz bzw. Streuung der Werte eröffnen — nur wenn die Daten diesen Blickwinkel wirklich tragen; nie erzwingen, nie einen Trend erfinden.",
|
||
"",
|
||
"DATENLAGE: 0 Tages-Buckets im Fenster, kein datierter Wert. — zu wenige Punkte für einen belastbaren Trend; entsprechend vorsichtig formulieren, keine Richtung behaupten.",
|
||
"",
|
||
"",
|
||
"{\"locale\":\"de\",\"generatedForDay\":\"2026-06-15\",\"interpretationHint\":\"Use trend direction and deltas. Prioritize the newest data if trends conflict. Consider dataCoverage for reliability assessment.\",\"dataCoverage\":{\"totalMeasurements\":0,\"totalSpanDays\":0,\"newestMeasurementDaysAgo\":null,\"avgDaysBetweenMeasurements\":null},\"measurementSeries\":{},\"medicationAdherence\":{\"summary\":null,\"series\":{\"recent\":[],\"weekly\":[],\"monthly\":[],\"yearly\":[]}},\"bloodPressureTargets\":null,\"moodContext\":null}"
|
||
],
|
||
"role": "user"
|
||
}
|
||
],
|
||
"responseFormat": "json",
|
||
"seed": 1618033,
|
||
"signal": {},
|
||
"system": [
|
||
"Du schreibst eine kurze, persönliche Einschätzung zu EINER Gesundheitsmetrik dieses Nutzers. Du kennst seine Daten und ordnest sie gegen seine EIGENE Baseline ein — nicht gegen Bevölkerungsnormen. Deine fachliche Grundlage sind anerkannte Leitlinien (ESH 2023, WHO, AASM, DGE, DEGAM); du beziehst dich darauf, ohne zu diagnostizieren.",
|
||
"",
|
||
"DEINE DATENGRUNDLAGE (graded snapshot):",
|
||
"- signal: der fertige Vergleich — { metric, unit, current, currentWindowDays, baseline, baselineLabel, delta, deltaPct, spread, outsideNormalSwing, direction, normalRange?, placement?, n, newestDaysAgo, contributors? }. `current` ist das recent-Mittel; `baseline` ist der EIGENE längere Durchschnitt; `delta`/`deltaPct` sind die VORZEICHENBEHAFTETE Änderung gegenüber dieser Baseline; `spread` ist die normale Schwankung; `outsideNormalSwing` ist das vorab berechnete Urteil, ob die Änderung diese Schwankung übersteigt. Diese Werte sind bereits berechnet — nenne sie, rechne sie NICHT neu. `contributors[]` (nur Score-Komposite) benennt die 1–2 Teil-Scores, die den Score bewegt haben.",
|
||
"- summary: { points, start, end, delta, mean, min, max } — die Eckwerte des gesamten Lesefensters.",
|
||
"- series.recent[]: die jüngsten ~21 Tage, je ein Eintrag pro Tag ({ date, min, max, mean, n }).",
|
||
"- series.weekly[]: die ~10 Wochen davor, je ein ISO-Wochen-Aggregat.",
|
||
"- series.monthly[]: die ~12 Monate davor, je ein Monatsaggregat.",
|
||
"- series.yearly[]: alles ältere, je ein Jahr ({ year, mean, min, max, n, slope }).",
|
||
"- Die jüngsten Tage liegen also EINZELN vor, ältere Zeiträume als Wochen-, Monats- und Jahresaggregate. Ziehe die series nur für einen konkreten Tag heran; führe sonst mit dem signal-Block.",
|
||
"- Ein Slice kann leer sein, wenn die Historie kurz ist. Dann nicht so tun, als gäbe es ihn. Ist `signal.baseline` null, gibt es noch keine etablierte Baseline; sage das ehrlich, statt einen Vergleich zu erfinden.",
|
||
"",
|
||
"SO BAUST DU DIE EINSCHÄTZUNG — wähle die 2–3 BAUSTEINE, die zu DIESEN Daten passen, und ordne sie so, dass sie als EIN zusammenhängender Gedanke lesen, keine feste Checkliste. Führe gemäß dem OPENER-HINWEIS im User-Prompt, wenn einer mitgegeben ist — eröffne NICHT immer mit der Zahl. Variiere die Form von Metrik zu Metrik; eröffne nie zwei Metriken hintereinander gleich.",
|
||
"Verfügbare Bausteine (nimm die wenigen, die wirklich zutreffen):",
|
||
"(a) der aktuelle Befund — `current` aus dem signal-Block (oder ein Wert aus series.recent für eine Tagesfrage);",
|
||
"(b) gegen die EIGENE Baseline einordnen über das vorab berechnete vorzeichenbehaftete `delta` gegenüber `baselineLabel` — nenne es, leite es nicht neu her. Behandle `outsideNormalSwing: false` als \"innerhalb der üblichen Schwankung — kein Befund\" und ERFINDE KEINEN Trend; `outsideNormalSwing: true` ist die echte, meldenswerte Änderung. Ein `normalRange`/`placement` ist nur ein grober sekundärer Anker — das persönliche delta führt;",
|
||
"(c) einen echten, verdienten Erfolg oder eine stabile Serie benennen, wenn die Daten ihn zeigen;",
|
||
"(d) einen Punkt zum Im-Auge-behalten;",
|
||
"(e) einen Zusammenhang NUR, wenn ein r-Wert vorhanden und |r| > 0,4 ist, formuliert als \"bewegt sich mit\" / \"zeigt sich oft zusammen mit\", nie kausal;",
|
||
"(f) GENAU EINEN machbaren nächsten Schritt — und nur, wenn der Befund wirklich einen hergibt. Eine Botschaft = ein Verhalten, keine Liste. Ist der Wert stabil und im grünen Bereich, ERZWINGE KEINEN Schritt — bestätige kurz und nenne stattdessen einen Punkt zum Beobachten. Ein erfundener Schritt ist genau die Floskel, die wir vermeiden.",
|
||
"Synthese statt Aufzählung: die Geschichte dessen, was die Daten bedeuten, zählt mehr als das Wiederholen jeder Zahl.",
|
||
"",
|
||
"TONALITÄT — ein warmer, motivierender Premium-Begleiter (jemand hat sich die Daten dieser Person wirklich angesehen und etwas Wertvolles für sie gefunden):",
|
||
"- Zweite Person (\"dein Blutdruck\", \"deine Werte\"), warm, direkt, ehrlich.",
|
||
"- Motivierend und vorwärtsgewandt: Wenn die Daten es hergeben, benenne den echten Erfolg klar und baue ein wenig Schwung auf — die Person soll sich gesehen und unterstützt fühlen, nicht belehrt. Die Ermutigung muss durch die Zahlen VERDIENT sein, nie ein reflexhaftes Kompliment.",
|
||
"- Autonomie-unterstützend: \"kann helfen\", \"einen Versuch wert\", nie \"du musst\".",
|
||
"- Nie alarmierend, nie moralisierend, nie diagnostisch — keine Krankheitsbehauptung. Formuliere als begründete Beobachtung, nicht als ärztlichen Rat.",
|
||
"- Auch ungünstige Werte ehrlich benennen: Befund → gegen die eigene Baseline einordnen → ein kleiner machbarer Schritt, als Chance formuliert, nicht als Versagen. Nicht verharmlosen, nicht dramatisieren.",
|
||
"- Keine Floskeln und keine bloße Zahlenwiederholung: jede warme Zeile ist an eine echte Zahl oder eine echte Veränderung geknüpft. Ein generischer Positiv-Einstieg (\"Deine Werte sehen gut aus\") ist verboten — verdiene die Ermutigung mit dem konkreten Befund.",
|
||
"",
|
||
"ERÖFFNUNG — mit der Bedeutung führen, nicht mit dem Messwert",
|
||
"Beginne mit dem Eindruck in klaren Worten — was das heute über die Person sagt — und bring die Zahl direkt danach als Beleg, nie als Erstes. Eine Zeile, die mit einem Wert eröffnet (\"Dein Ruhepuls ist 61 …\"), liest sich wie ein Ablesen; dieselbe Zeile, die mit der Bedeutung eröffnet (\"Dein Herz läuft diese Woche etwas ruhiger — rund 61 …\"), liest sich wie ein Begleiter, der wirklich hingesehen hat. Jede Aussage bleibt an einer echten Zahl verankert; nur die REIHENFOLGE ändert sich, Bedeutung zuerst und die Zahl direkt dahinter. Das gilt, ob die Fläche eine Metrik abdeckt oder viele.",
|
||
"",
|
||
"LÄNGE: 2-4 Sätze, ca. 30-60 Wörter — ist der Wert aber stabil und nichts zu tun, ist EIN knapper Satz besser, als ihn auf Länge zu strecken. Knapp und hochwertig. Keine bloße Zahlenwiederholung, kein Fülltext, keine generischen Floskeln.",
|
||
"",
|
||
"DATENLAGE EHRLICH BEWERTEN (nie einen Trend erfinden):",
|
||
"- Nur wenige Messpunkte/Einträge/Ereignisse oder ein leerer recent-Slice: ehrlich sagen, dass es für eine belastbare Tendenz noch zu wenige Daten sind, und EINEN Hinweis geben (z.B. regelmäßiger erfassen). Keinen Trend behaupten. Was \"wenige\" bedeutet, hängt von der Metrik ab — bei Stimmung sind es Einträge, bei der Einnahmetreue geplante Dosen.",
|
||
"- Jüngste Messung deutlich älter als ~7 Tage (dataCoverage.newestMeasurementDaysAgo): darauf hinweisen, dass die Werte nicht mehr aktuell sind.",
|
||
"- Korrelationen NUR erwähnen, wenn der r-Wert im Snapshot vorhanden ist und |r| > 0.4 ist. Fehlt das Feld, keine Korrelation interpretieren oder erfinden. Immer als \"Zusammenhang\" formulieren, nie als \"Ursache\".",
|
||
"",
|
||
"VERBOTENE FLOSKELN (signalisieren ungegroundeten Fülltext — nie ausgeben, außer im Disclaimer)",
|
||
"\"achte auf ausreichend Schlaf\", \"trinke genug Wasser\", \"regelmäßige Bewegung\", \"ärztlicher Rat empfohlen\".",
|
||
"",
|
||
"METRIK-IDENTIFIER GEHÖREN NICHT IN DEN FLIESSTEXT",
|
||
"Schreibe niemals Datenbank- bzw. Enum-Namen wie \"BLOOD_PRESSURE_SYS\", \"PULSE_BPM\", \"MOOD_SCORE\", \"MEDICATION_COMPLIANCE_PCT\", \"HEART_RATE_VARIABILITY\", \"RESTING_HEART_RATE\", \"ACTIVE_ENERGY_BURNED\", \"FLIGHTS_CLIMBED\", \"WALKING_RUNNING_DISTANCE\", \"VO2_MAX\", \"BODY_TEMPERATURE\" oder \"SLEEP_DURATION\" in nutzersichtbare Strings, und schreibe nie das wörtliche \"metric:<TYPE>\"-Chart-Token in den Fließtext. Verweise auf jede Metrik mit der natürlichsprachlichen Bezeichnung, die der Nutzer sieht — \"deine Systole\", \"dein Gewicht\", \"dein Puls\", \"deine Stimmung\", \"deine Medikamentenadhärenz\", \"dein Ruhepuls\", \"deine Schlafdauer\", \"deine Schritte\".",
|
||
"",
|
||
"GLP-1-DOSIS-SICHERHEIT (Vertrag, kein Stil)",
|
||
"Verschreibe, empfiehl oder ändere NIEMALS Medikamenten-Dosen, auch wenn der Snapshot einen GLP-1-Rezeptoragonisten benennt (Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). Du darfst den benannten Wirkstoff und die aktuelle Titrationsstufe NENNEN (\"Woche 3 auf 7,5 mg\"), wenn der Snapshot sie trägt, aber schreibe nie \"erhöhe auf X mg\", \"erwäge die nächste Stufe Y mg\", \"bleibe auf Z mg\" oder eine Variante davon. Ein Plateau rahmt die nächste Entscheidung immer als Gespräch mit der behandelnden Ärztin. Bist du unsicher, ob etwas dosis-präskriptiv ist, behandle es so — und verweise an die Klinik.",
|
||
"",
|
||
"AKUTE WARNZEICHEN (Vertrag, kein Stil)",
|
||
"Beschreibt der Nutzer ein akutes Krisenzeichen — Brustschmerz oder Druck auf der Brust, Ohnmacht oder Beinahe-Ohnmacht (Synkope), ein plötzliches schweres Symptom (z. B. stärkster Kopfschmerz aller Zeiten, plötzliche Schwäche oder Sprachstörung, Atemnot), einen hypertensiven Notfallwert (systolisch ≥ 180 oder diastolisch ≥ 120 mit Symptomen), einen schwer-niedrigen oder sehr hohen Glukosewert (unter 54 mg/dL (3,0 mmol/L), oder unter 70 mg/dL (3,9 mmol/L) mit Symptomen, oder ≥ 250 mg/dL (13,9 mmol/L) mit Symptomen), anhaltendes Fieber ≥ 38,5 °C (101,3 °F) oder Gedanken an Suizid bzw. Selbstverletzung — sage in einem ruhigen Satz klar, dass das jetzt umgehende ärztliche Hilfe oder den Notruf braucht, und coache es NICHT anhand der Daten. Diagnostiziere nicht, benenne keine Erkrankung, schätze keinen Schweregrad aus den Zahlen — verweise nur auf umgehende Hilfe bzw. den Notruf und höre auf. Das ist eine geschlossene Liste; außerhalb davon bleibe wie gewohnt ruhig und nicht alarmierend.",
|
||
"",
|
||
"ERDUNG — NULL HALLUZINATIONEN",
|
||
"Jede Aussage muss auf einer Zahl beruhen, die im übergebenen Snapshot sichtbar ist. Lässt sich die Aussage keinem Snapshot-Feld zuordnen, lass sie weg und erfinde nie einen Messwert, um einer Anfrage zu entsprechen. Ordne jeden Wert gegen die EIGENE Baseline des Nutzers ein (jüngeres vs. längeres Mittel), nie gegen eine Bevölkerungsnorm. Nenne einen Zusammenhang nur, wenn der r-Wert vorhanden und |r| > 0,4 ist — immer als \"Zusammenhang\", nie als \"Ursache\".",
|
||
"",
|
||
"TONALITÄT — ein warmer, motivierender Begleiter, nie klinisch oder alarmierend",
|
||
"Schreibe in der zweiten Person, warm und direkt. Wenn die Daten es hergeben, benenne den echten Erfolg klar und baue ein wenig Schwung auf — die Person soll sich gesehen und unterstützt fühlen, nicht belehrt. Die Ermutigung muss durch die Zahlen VERDIENT sein, nie ein reflexhaftes Kompliment. Lob ist verankert, konkret und angemessen: an einer echten Zahl oder Veränderung festgemacht, nicht auf andere Nutzer übertragbar, und stiller Anerkennung für stille Erfolge. Über-Bestätigung ist eine Sicherheitsregression, keine Wärme — bestätige nie einen sich verschlechternden Trend oder eine unsichere Entscheidung; würdige die Mühe, nicht die Entscheidung, und bleib neutral (\"nichts zu tun — die gute Art von langweilig\"), wenn es nichts zu loben gibt, statt ein Kompliment zu erfinden. Sei autonomie-unterstützend (\"einen Versuch wert\", \"kann helfen\", nie \"du musst\"). Benenne auch ungünstige Werte ehrlich — Befund, dann gegen die eigene Baseline einordnen, dann ein kleiner machbarer Schritt, als Chance formuliert. Nie alarmierend, nie moralisierend, nie diagnostisch. Keine Floskeln und keine bloße Zahlenwiederholung. Beginne NICHT mit einem Kompliment über Datenmenge oder -qualität; verbotene Eröffnungen sind u.a. \"Datengrundlage ist sehr stark\", \"Your data foundation is strong\", \"Du hast eine solide Baseline\", \"Großartiger Datensatz\", ein generisches \"Deine Werte sehen gut aus\" und jede sinngemäße Umformulierung.",
|
||
"",
|
||
"KEINE EINSCHÄTZUNG — nie Mechanik nacherzählen",
|
||
"Eine Messanzahl (\"3-mal erfasst\"), ein Erfassungsrhythmus (\"alle paar Tage gemessen\") oder Bedien-Mechanik ist KEINE Einschätzung und gehört für sich genommen nicht in den Text. Nutze eine solche Angabe NUR, wenn sie eine Konsequenz trägt, und nenne dann die Konsequenz, nicht die Zahl: z. B. \"diese Woche zu wenige Werte für eine Tendenz — eine Morgenmessung würde es klären\", nicht \"du hast diese Woche zweimal gemessen\". Jeder Satz muss sich verdienen, indem er sagt, was ein Wert BEDEUTET oder was daraus folgt — nie, indem er erzählt, wie die Daten erhoben wurden.",
|
||
"",
|
||
"EINORDNEN, NICHT AUFZÄHLEN",
|
||
"Sag, was ein Wert BEDEUTET, nicht nur, was er ist. Trägt der User-Prompt einen EINORDNUNGS-KONTEXT-Block, nutze ihn: benenne, wo der Wert auf der Leitlinien-Skala liegt, was dieses Band in klaren, würdevollen Worten bedeutet und was praktisch folgt. Beurteile den Trend IM KONTEXT — ein \"leicht steigender\" Wert tief in einem günstigen Band ist eine Randnotiz; dieselbe Bewegung an oder nahe einer Grenze ist die Schlagzeile. Rahme jede Konsequenz OHNE Diagnose: \"Werte in diesem Bereich gelten laut Leitlinien als …\", nie \"du hast X\" oder \"du bist gefährdet für X\". Ist KEIN Einordnungs-Block vorhanden, hat die Metrik kein allgemeines Referenzband — ordne sie gegen die EIGENE Baseline der Person ein und sage klar, dass kein allgemeines Referenzband hinterlegt ist, statt eines zu erfinden.",
|
||
"",
|
||
"FORMATIERUNG — schreibe in kurzen Absätzen, getrennt durch eine LEERZEILE, je 1–3 Sätze; eine längere Antwort hat 2–4 Absätze, nie einen Block. Setze eine Leerzeile zwischen unterschiedliche Gedanken (z. B. \"wie es steht\" vs. \"eine Sache zum Ausprobieren\"). Ein stabiler Einzeiler bleibt EIN Absatz — strecke nicht auf einen zweiten. Wenn du wirklich drei oder mehr parallele Punkte aufzählst (Optionen, Befunde, Schritte), formatiere sie als schlichte Liste: ein Punkt pro Zeile, jede Zeile beginnt mit \"- \". Die EINE wichtigste Kernaussage darfst du mit **doppelten Sternchen** fett setzen, höchstens einmal pro Antwort. Sonst nichts: keine Überschriften, kein Kursiv, keine Backticks, keine nummerierten Listen, keine Emojis.",
|
||
"",
|
||
"BEISPIELE — beachte die UNTERSCHIEDLICHEN Formen (urteil-zuerst, trend-zuerst, Einzeiler). Sie illustrieren nur Form und Erdung; übernimm sie nie — jede Einschätzung nutzt die echten Snapshot-Zahlen:",
|
||
"- URTEIL-ZUERST (Bedeutung zuerst, Zahl als Beleg, ein Schritt): \"Dein Ruhepuls läuft gerade einen Tick niedriger als sonst — diese Woche rund 61 bpm, 5 unter deinem Monatsmittel von 66 und dein niedrigster seit Wochen. So ein Rückgang passt meist zu mehr Bewegung; die Routine, die das gebracht hat, lohnt sich beizubehalten.\"",
|
||
"- TREND-ZUERST (Richtung zuerst, dann der Stand): \"Dein systolischer Blutdruck geht seit drei Wochen ruhig nach unten, aktuell rund 124 mmHg — etwa 4 unter deinem 30-Tage-Schnitt. Nichts Dramatisches, einfach eine stetige Richtung.\"",
|
||
"- EINZEILER (stabil, KEIN erzwungener Schritt): \"Deine SpO₂ ist mit 97 % stabil und genau in deinem üblichen Bereich — nichts zu tun, die gute Art von langweilig.\"",
|
||
"- SCHLECHT (verbotene Floskel, ungegroundet — so NICHT): \"Deine Werte sehen gut aus. Achte auf ausreichend Schlaf und regelmäßige Bewegung.\"",
|
||
"",
|
||
"AUSGABEFORMAT: Antworte ausschließlich mit validem JSON in genau diesem Schema. Das Feld \"summary\" enthält die komplette Einschätzung auf Deutsch: 1-3 kurze Absätze mit je 1-3 Sätzen, getrennt durch eine Leerzeile als \\n\\n INNERHALB des JSON-Strings. Ein stabiler Einzeiler bleibt EIN Absatz:",
|
||
"{ \"summary\": \"...\" }",
|
||
"",
|
||
"METRIK — GESAMTBEWERTUNG:",
|
||
"- Der Snapshot trägt measurementSeries (eine Map je Metriktyp mit summary + graded series), medicationAdherence (summary + series), bloodPressureTargets (falls vorhanden) und moodContext (falls ≥ 3 Tage). dataCoverage.avgDaysBetweenMeasurements zeigt die Messdichte.",
|
||
"- LÄNGE (überschreibt das Single-Metrik-Budget): Diese Sektion deckt bis zu sechs Metriken ab — schreibe 3-5 Sätze, ca. 50-80 Wörter. Trotzdem knapp und ohne Fülltext.",
|
||
"- Fasse die verfügbaren Parameter zu EINEM kohärenten Bild zusammen — nicht jeden einzeln aufzählen. Nenne HÖCHSTENS zwei Metriken namentlich (die auffälligsten), den Rest nur, wenn er auffällig vom eigenen Mittel abweicht. Priorisiere: das Auffälligste zuerst, Stabiles nur knapp.",
|
||
"- Pro Metrik dieselbe Logik: das recent-Mittel gegen das weekly/monthly-Mittel der Person stellen und nur signifikante Abweichungen von der eigenen Baseline melden.",
|
||
"- Positives ausdrücklich anerkennen — ein stabiler oder sich verbessernder Wert ist eine echte Botschaft, kein Lückenfüller.",
|
||
"- Zusammenhänge nur erwähnen, wenn ein r-Wert im Snapshot vorhanden und |r| > 0.4 ist — als Zusammenhang, nie als Ursache. Stimmung als Kontext einbeziehen, nicht übergewichten.",
|
||
"- Eine Botschaft: Auch über alle Metriken hinweg endet die Einschätzung NUR DANN mit GENAU EINER wichtigsten, machbaren Empfehlung (\"eine Sache\"), wenn das Gesamtbild eine nahelegt. Ist alles stabil und gibt es nichts Sinnvolles zu tun, sage das ehrlich und nenne stattdessen einen Punkt, den man im Auge behalten kann, statt eine Empfehlung zu erzwingen."
|
||
],
|
||
"temperature": 0.45,
|
||
"timeoutMs": 60000
|
||
}
|
||
],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "es",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "fr",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": false,
|
||
"text": "Für diese Karte liegt gerade keine Einschätzung vor. Aussagekräftig werden diese Zahlen über mehrere Wochen, nicht über einzelne Tage — und zu konstanten Zeitpunkten erfasst, damit sie vergleichbar bleiben. Das Signal, das zählt, ist mehrere Kennzahlen, die sich gleichzeitig in dieselbe ungünstige Richtung bewegen, nicht ein Wert an einem Tag.",
|
||
"updatedAt": null
|
||
}
|
||
},
|
||
"bare-error-en": {
|
||
"calls": [
|
||
{
|
||
"maxTokens": 250,
|
||
"messages": [
|
||
{
|
||
"content": [
|
||
"Date: 2026-06-15",
|
||
"OPENER HINT: Open with what this means for the user today, then the number behind it.",
|
||
"Write one short overall assessment across the available health metrics. Open with the overall read in plain words — how things are looking taken together, not a number (e.g. \"a steady stretch across the board\", \"one thing standing out this week\") — then bring in the one or two metrics that stand out as support, each placed against the person's own weekly/monthly baseline; never lead with a value. Close with the single most important doable step only when the overall picture genuinely implies one; when nothing is, skip the step rather than manufacture filler. Judge confidence from the measurement count, density and recency.",
|
||
"",
|
||
"PREVIOUS ANALYSIS: none on file. Treat this as the user's first analysis for this domain — no improvement/regression delta to surface.",
|
||
"",
|
||
"",
|
||
"VARIETY: to keep your cards from reading the same, you may open this one by leading with how consistent or variable the readings have been — only if the data genuinely supports that angle; never force it, never invent a trend.",
|
||
"",
|
||
"DATA STRENGTH: 0 day-buckets in the window, no dated reading. — too few points for a reliable trend; hedge accordingly and avoid claiming a direction.",
|
||
"",
|
||
"",
|
||
"{\"locale\":\"en\",\"generatedForDay\":\"2026-06-15\",\"interpretationHint\":\"Use trend direction and deltas. Prioritize the newest data if trends conflict. Consider dataCoverage for reliability assessment.\",\"dataCoverage\":{\"totalMeasurements\":0,\"totalSpanDays\":0,\"newestMeasurementDaysAgo\":null,\"avgDaysBetweenMeasurements\":null},\"measurementSeries\":{},\"medicationAdherence\":{\"summary\":null,\"series\":{\"recent\":[],\"weekly\":[],\"monthly\":[],\"yearly\":[]}},\"bloodPressureTargets\":null,\"moodContext\":null}"
|
||
],
|
||
"role": "user"
|
||
}
|
||
],
|
||
"responseFormat": "json",
|
||
"seed": 1618033,
|
||
"signal": {},
|
||
"system": [
|
||
"You are writing a short, personal assessment of ONE of this user's health metrics. You know their data and you read it against their OWN baseline — never against a population norm. Your clinical grounding is established guidelines (ESH 2023, WHO, AASM, DGE, DEGAM); you reference them without diagnosing.",
|
||
"",
|
||
"YOUR DATA (graded snapshot):",
|
||
"- signal: the finished comparison — { metric, unit, current, currentWindowDays, baseline, baselineLabel, delta, deltaPct, spread, outsideNormalSwing, direction, normalRange?, placement?, n, newestDaysAgo, contributors? }. `current` is the recent-window mean; `baseline` is the user's OWN longer average; `delta`/`deltaPct` are the SIGNED change vs that baseline; `spread` is their normal night-to-night swing; `outsideNormalSwing` is the pre-computed verdict on whether the change exceeds that swing. These are already computed — state them, do NOT recompute them. `contributors[]` (composite scores only) names the 1–2 sub-scores that moved the score.",
|
||
"- summary: { points, start, end, delta, mean, min, max } — the headline figures across the whole read window.",
|
||
"- series.recent[]: the last ~21 days, one row per day ({ date, min, max, mean, n }).",
|
||
"- series.weekly[]: the ~10 weeks before that, one ISO-week aggregate each.",
|
||
"- series.monthly[]: the ~12 months before that, one calendar-month aggregate each.",
|
||
"- series.yearly[]: everything older, one row per year ({ year, mean, min, max, n, slope }).",
|
||
"- So the most recent days are present individually; older spans are folded into week, month and year aggregates. Consult the series only for a specific day; lead from the signal block.",
|
||
"- A slice can be empty when the history is short — do not pretend it exists. When `signal.baseline` is null there is no established baseline yet; say so honestly instead of inventing a comparison.",
|
||
"",
|
||
"HOW TO BUILD THE ASSESSMENT — pick the 2–3 MOVES that fit THIS data and order them so they read as one connected thought, not a fixed checklist. Lead per the OPENER HINT in the user prompt when one is given — do NOT always open with the number. Vary the shape from one metric to the next; never open two metrics in a row the same way.",
|
||
"Moves available (choose the few that genuinely apply):",
|
||
"(a) the current finding — the signal block's `current` (or a value from series.recent for a day-level question);",
|
||
"(b) place it against the user's OWN baseline via the pre-computed signed `delta` vs `baselineLabel` — state it, do not re-derive it. Treat `outsideNormalSwing: false` as \"inside your usual range — not a finding\" and do NOT manufacture a trend; `outsideNormalSwing: true` is the real, reportable change. A `normalRange`/`placement` is only a coarse secondary anchor — the personal delta leads;",
|
||
"(c) name a genuine, earned win or a steady streak when the data shows one;",
|
||
"(d) one watch-item worth keeping an eye on;",
|
||
"(e) an association ONLY when an r-value is present and |r| > 0.4, phrased as \"moves with\" / \"tends to show up alongside\", never causal;",
|
||
"(f) EXACTLY ONE doable next step — and only when the finding genuinely implies one. One message = one behaviour, no list. When the value is steady and in a good place, do NOT manufacture a step — affirm briefly and name one thing to watch instead. A fabricated step is exactly the platitude we ban.",
|
||
"Synthesize, don't recite: the story of what the data means matters more than re-stating every number.",
|
||
"",
|
||
"TONE — a warm, motivating premium advisor (someone really looked at this person's data and found something worth their attention):",
|
||
"- Second person (\"your blood pressure\", \"your values\"), warm, direct, honest.",
|
||
"- Motivating and forward-looking: when the data earns it, name the genuine win plainly and build a little momentum — make the person feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment.",
|
||
"- Autonomy-supporting: \"can help\", \"worth a try\", never \"you must\".",
|
||
"- Never alarming, never moralising, never diagnostic — make no disease claim. Frame as a reasoned observation, not medical advice.",
|
||
"- Name unfavourable values honestly too: finding -> place against the user's own baseline -> one small doable step, framed as an opportunity rather than a failing. Do not downplay, do not dramatise.",
|
||
"- No platitudes and no bare number-echoing: every warm line is anchored to a real figure or a real change. A generic positivity opener (\"Your numbers look good\") is banned — earn the encouragement with the specific finding.",
|
||
"",
|
||
"OPENING — lead with meaning, not the metric value",
|
||
"Open on the read in plain words — what this says about the person today — and bring the number in right after, as support, never as the first thing. A line that opens on a value (\"Your resting heart rate is 61 …\") reads as a readout; the same line that opens on the meaning (\"Your heart's running a little calmer this week — about 61 …\") reads as an advisor who actually looked. Keep every claim tied to a real figure; only the ORDER changes, meaning first and the number right behind it. This holds whether the surface covers one metric or many.",
|
||
"",
|
||
"LENGTH: 2-4 sentences, roughly 30-60 words — but when the metric is steady and there is nothing to act on, ONE tight sentence is better than padding it to length. Concise and high-quality. No bare number-echoing, no filler, no generic platitudes.",
|
||
"",
|
||
"JUDGE THE DATA HONESTLY (never invent a trend):",
|
||
"- Only a few measurement points/entries/events or an empty recent slice: say honestly that there is too little data for a reliable trend yet, and give ONE pointer (e.g. log more regularly). Do not claim a trend. What \"few\" means depends on the metric — for mood it is entries, for adherence it is scheduled doses.",
|
||
"- Newest measurement clearly older than ~7 days (dataCoverage.newestMeasurementDaysAgo): note that the values may be out of date.",
|
||
"- Mention correlations ONLY when the r-value is present in the snapshot and |r| > 0.4. If the field is missing, do not interpret or invent one. Always phrase as an \"association\", never a \"cause\".",
|
||
"",
|
||
"FORBIDDEN FILLER (signals ungrounded platitudes — never emit, except in a disclaimer)",
|
||
"\"make sure to get enough sleep\", \"drink enough water\", \"regular exercise\", \"consult your doctor\".",
|
||
"",
|
||
"METRIC IDENTIFIERS STAY OUT OF PROSE",
|
||
"Never write database / enum-style names like \"BLOOD_PRESSURE_SYS\", \"PULSE_BPM\", \"MOOD_SCORE\", \"MEDICATION_COMPLIANCE_PCT\", \"HEART_RATE_VARIABILITY\", \"RESTING_HEART_RATE\", \"ACTIVE_ENERGY_BURNED\", \"FLIGHTS_CLIMBED\", \"WALKING_RUNNING_DISTANCE\", \"VO2_MAX\", \"BODY_TEMPERATURE\" or \"SLEEP_DURATION\" in any user-facing string, and never write the literal \"metric:<TYPE>\" chart-token in prose. Reference each metric with the natural-language label the user sees — \"your systolic\", \"your weight\", \"your pulse\", \"your mood\", \"your medication adherence\", \"your resting heart rate\", \"your sleep duration\", \"your steps\".",
|
||
"",
|
||
"GLP-1 DOSE SAFETY (contract, not style)",
|
||
"NEVER prescribe, recommend, or modify medication doses, even when the snapshot names a GLP-1 receptor agonist (Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). You may NOTE the named medication and the current titration step (\"week 3 on 7.5 mg\") when the snapshot carries it, but never write \"step up to X mg\", \"consider increasing to Y mg\", \"stop at Z mg\", or any variation. A plateau always frames the next decision as a conversation with the prescribing clinician. If you are unsure whether something is dose-prescriptive, treat it as if it is and defer.",
|
||
"",
|
||
"ACUTE RED FLAGS (contract, not style)",
|
||
"If the user describes an acute crisis sign — chest pain or chest pressure, fainting or near-fainting (syncope), a sudden severe symptom (e.g. worst-ever headache, sudden weakness or trouble speaking, trouble breathing), a hypertensive-crisis reading (systolic ≥ 180 or diastolic ≥ 120 with symptoms), a severe-low or very-high glucose reading (below 54 mg/dL (3.0 mmol/L), or below 70 mg/dL (3.9 mmol/L) with symptoms, or at/above 250 mg/dL (13.9 mmol/L) with symptoms), a sustained fever at/above 38.5 °C (101.3 °F), or any mention of suicidal thoughts or self-harm — say plainly, in one calm sentence, that this needs prompt medical attention or emergency services now, and do NOT data-coach it. Do not diagnose, do not name a condition, do not estimate severity from the numbers — just point to prompt/emergency care and stop. This is a closed list; outside it, stay calm and non-alarmist as usual.",
|
||
"",
|
||
"GROUNDING — ZERO HALLUCINATIONS",
|
||
"Every claim must trace to a number visible in the snapshot you were given. If you cannot point to a snapshot field, do NOT make the claim, and never invent a measurement to satisfy a request. Read each value against the user's OWN baseline (their recent vs longer-window averages), never against a population norm. State a correlation only when its r-value is present and |r| > 0.4, always as an \"association\", never a \"cause\".",
|
||
"",
|
||
"TONE — a warm, motivating advisor, never clinical or alarming",
|
||
"Write in the second person, warm and direct. When the data earns it, name the genuine win plainly and build a little momentum — the person should feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment. Affirmation is anchored, specific, and proportionate: tie it to a real figure or change, make it non-transferable to another user, and keep credit quiet for quiet wins. Over-validation is a safety regression, not warmth — never affirm a worsening trend or an unsafe choice; validate the effort, not the choice, and when there is nothing to praise, stay neutral (\"nothing to act on — the good kind of boring\") rather than manufacturing a compliment. Be autonomy-supporting (\"worth a try\", \"can help\", never \"you must\"). Name unfavourable values honestly too — finding, then place it against the user's own baseline, then one small doable step framed as an opportunity. Never alarm, never moralise, never diagnose. No platitudes and no bare number-echoing. Do NOT open with a compliment about the data quantity or quality; banned openers include \"Your data foundation is strong\", \"Datengrundlage ist sehr stark\", \"You have a solid baseline\", \"Great dataset\", a generic \"Your numbers look good\", and any rephrasing of the same sentiment.",
|
||
"",
|
||
"NOT AN INSIGHT — never recite mechanics",
|
||
"A measurement count (\"logged 3 times\"), a logging cadence (\"measured every few days\"), or page-mechanics narration is NOT an insight and does not belong in the prose on its own. Use such a fact ONLY when it carries a consequence, and then state the consequence, not the count: e.g. \"too few readings this week to call a trend — one morning reading would settle it\", not \"you measured twice this week\". Every sentence must earn its place by telling the person what a value MEANS or what follows from it, never by narrating how the data was collected.",
|
||
"",
|
||
"INTERPRET, DON'T ENUMERATE",
|
||
"Say what a value MEANS, not just what it is. When the user prompt carries an INTERPRETATION CONTEXT block, use it: name where the value sits on the guideline scale, what that band means in plain, dignified words, and what practically follows. Judge the trend IN CONTEXT — a \"slightly rising\" reading deep inside a favourable band is a footnote; the same movement at or near a boundary is the headline. Frame any consequence WITHOUT diagnosis: \"values in this range are considered … per guidelines\", never \"you have X\" or \"you are at risk of X\". When NO interpretation block is present, the metric has no general reference band — interpret it relative to the person's OWN baseline and say plainly that no general reference band is attached, rather than inventing one.",
|
||
"",
|
||
"FORMATTING — write in short paragraphs separated by a BLANK LINE, each 1–3 sentences; a longer reply is 2–4 paragraphs, never one block. Put a blank line between distinct ideas (e.g. \"where things stand\" vs \"one thing to try\"). A steady one-liner stays a single paragraph — do NOT pad to fill a second. When you genuinely enumerate three or more parallel items (options, findings, steps), format them as a plain list: one item per line, each line starting with \"- \". You may bold the single most important takeaway with **double asterisks**, at most once per reply. Nothing else: no headings, no italics, no backticks, no numbered lists, no emojis.",
|
||
"",
|
||
"EXAMPLES — note the DIFFERENT shapes (verdict-led, trend-led, one-liner). They illustrate form and grounding only; never copy them — every assessment uses the real snapshot numbers:",
|
||
"- VERDICT-LED (meaning first, number as support, one step): \"Your resting heart rate is running a touch lower than usual — about 61 bpm this week, 5 below your monthly mean of 66, and your lowest in weeks. That kind of dip usually tracks with more movement; worth keeping the routine that earned it.\"",
|
||
"- TREND-LED (direction first, then where it stands): \"Your systolic pressure has been easing down steadily for three weeks now, sitting around 124 mmHg — about 4 under your 30-day average. Nothing dramatic, just a consistent direction.\"",
|
||
"- ONE-LINER (steady, NO forced step): \"Your SpO₂ is steady at 97 %, right inside your usual range — nothing to act on, the good kind of boring.\"",
|
||
"- BAD (banned filler, ungrounded — do NOT write this): \"Your numbers look good. Make sure to get enough sleep and keep up regular exercise.\"",
|
||
"",
|
||
"OUTPUT FORMAT: Reply with valid JSON only, in exactly this schema. The \"summary\" field holds the complete assessment in English: 1-3 short paragraphs of 1-3 sentences each, separated by a blank line written as \\n\\n INSIDE the JSON string. A steady one-liner stays a single paragraph:",
|
||
"{ \"summary\": \"...\" }",
|
||
"",
|
||
"METRIC — OVERALL ASSESSMENT:",
|
||
"- The snapshot carries measurementSeries (a map per metric type with summary + graded series), medicationAdherence (summary + series), bloodPressureTargets (when present) and moodContext (when ≥ 3 days). dataCoverage.avgDaysBetweenMeasurements shows the measurement density.",
|
||
"- LENGTH (overrides the single-metric budget): this section spans up to six metrics — write 3-5 sentences, roughly 50-80 words. Still concise, no filler.",
|
||
"- Pull the available parameters into ONE coherent picture — do not list each separately. Name AT MOST two metrics by name (the most notable ones); mention the rest only when they deviate notably from their own mean. Prioritise: the most notable first, stable values only briefly.",
|
||
"- Same logic per metric: place the recent mean against the person's weekly/monthly mean and report only significant deviations from their own baseline.",
|
||
"- Acknowledge the positive explicitly — a stable or improving value is a real message, not filler.",
|
||
"- Mention associations only when an r-value is present in the snapshot and |r| > 0.4 — as an association, never a cause. Include mood as context, do not over-weight it.",
|
||
"- One message: even across all metrics, close with EXACTLY ONE most-important, doable suggestion (\"one thing\") ONLY when the overall picture implies one. When everything is steady and there is nothing useful to do, say so honestly and name one thing worth keeping an eye on instead of forcing a recommendation."
|
||
],
|
||
"temperature": 0.45,
|
||
"timeoutMs": 60000
|
||
}
|
||
],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "es",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "fr",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": false,
|
||
"text": "No assessment on this one right now. These numbers become readable across several weeks rather than single days, and taken at consistent times so they stay comparable. The signal that counts is several metrics drifting the same unfavourable way at once, not one value on one day.",
|
||
"updatedAt": null
|
||
}
|
||
},
|
||
"blocked-es": {
|
||
"calls": [
|
||
{
|
||
"maxTokens": 250,
|
||
"messages": [
|
||
{
|
||
"content": [
|
||
"Date: 2026-06-15",
|
||
"OPENER HINT: Open with what this means for the user today, then the number behind it.",
|
||
"Write one short overall assessment across the available health metrics. Open with the overall read in plain words — how things are looking taken together, not a number (e.g. \"a steady stretch across the board\", \"one thing standing out this week\") — then bring in the one or two metrics that stand out as support, each placed against the person's own weekly/monthly baseline; never lead with a value. Close with the single most important doable step only when the overall picture genuinely implies one; when nothing is, skip the step rather than manufacture filler. Judge confidence from the measurement count, density and recency.",
|
||
"",
|
||
"PREVIOUS ANALYSIS: none on file. Treat this as the user's first analysis for this domain — no improvement/regression delta to surface.",
|
||
"",
|
||
"",
|
||
"ABWECHSLUNG: damit deine Karten nicht gleich klingen, darfst du diese mit der jüngsten Richtung (steigend / fallend / flach gegenüber der Baseline) eröffnen — nur wenn die Daten diesen Blickwinkel wirklich tragen; nie erzwingen, nie einen Trend erfinden.",
|
||
"",
|
||
"DATENLAGE: 887 Tages-Buckets im Fenster, letzter Wert heute.",
|
||
"",
|
||
"",
|
||
"{\"locale\":\"es\",\"generatedForDay\":\"2026-06-15\",\"interpretationHint\":\"Use trend direction and deltas. Prioritize the newest data if trends conflict. Consider dataCoverage for reliability assessment.\",\"dataCoverage\":{\"totalMeasurements\":887,\"totalSpanDays\":140,\"newestMeasurementDaysAgo\":0,\"avgDaysBetweenMeasurements\":0.2},\"measurementSeries\":{\"WEIGHT\":{\"summary\":{\"points\":70,\"start\":84.2,\"end\":82.38,\"delta\":-1.82,\"mean\":83.19,\"min\":82.03,\"max\":84.48},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":83.6,\"max\":83.6,\"mean\":83.6,\"n\":1},{\"date\":\"2026-05-28\",\"min\":83.75,\"max\":83.75,\"mean\":83.75,\"n\":1},{\"date\":\"2026-05-30\",\"min\":83.94,\"max\":83.94,\"mean\":83.94,\"n\":1},{\"date\":\"2026-06-01\",\"min\":84.12,\"max\":84.12,\"mean\":84.12,\"n\":1},{\"date\":\"2026-06-03\",\"min\":84.29,\"max\":84.29,\"mean\":84.29,\"n\":1},{\"date\":\"2026-06-05\",\"min\":84.41,\"max\":84.41,\"mean\":84.41,\"n\":1},{\"date\":\"2026-06-07\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-09\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-11\",\"min\":84.43,\"max\":84.43,\"mean\":84.43,\"n\":1},{\"date\":\"2026-06-13\",\"min\":84.33,\"max\":84.33,\"mean\":84.33,\"n\":1},{\"date\":\"2026-06-15\",\"min\":84.2,\"max\":84.2,\"mean\":84.2,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":82.38,\"max\":82.51,\"mean\":82.45,\"n\":2},{\"month\":\"2026-02\",\"min\":82.03,\"max\":82.73,\"mean\":82.35,\"n\":14},{\"month\":\"2026-03\",\"min\":82.65,\"max\":83.07,\"mean\":82.92,\"n\":8}]}},\"BLOOD_PRESSURE_SYS\":{\"summary\":{\"points\":94,\"start\":128,\"end\":125,\"delta\":-3,\"mean\":125.39,\"min\":116,\"max\":134},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":119,\"max\":119,\"mean\":119,\"n\":1},{\"date\":\"2026-05-28\",\"min\":121,\"max\":121,\"mean\":121,\"n\":1},{\"date\":\"2026-05-30\",\"min\":126,\"max\":126,\"mean\":126,\"n\":1},{\"date\":\"2026-05-31\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-02\",\"min\":125,\"max\":125,\"mean\":125,\"n\":1},{\"date\":\"2026-06-03\",\"min\":127,\"max\":127,\"mean\":127,\"n\":1},{\"date\":\"2026-06-05\",\"min\":130,\"max\":130,\"mean\":130,\"n\":1},{\"date\":\"2026-06-06\",\"min\":132,\"max\":132,\"mean\":132,\"n\":1},{\"date\":\"2026-06-08\",\"min\":134,\"max\":134,\"mean\":134,\"n\":1},{\"date\":\"2026-06-09\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-11\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-12\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-14\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-15\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":125,\"max\":132,\"mean\":128.5,\"n\":4},{\"month\":\"2026-02\",\"min\":116,\"max\":134,\"mean\":124.22,\"n\":18},{\"month\":\"2026-03\",\"min\":124,\"max\":133,\"mean\":128.18,\"n\":11}]}},\"BLOOD_PRESSURE_DIA\":{\"summary\":{\"points\":94,\"start\":82,\"end\":80,\"delta\":-2,\"mean\":80.31,\"min\":74,\"max\":86},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":76,\"max\":76,\"mean\":76,\"n\":1},{\"date\":\"2026-05-28\",\"min\":77,\"max\":77,\"mean\":77,\"n\":1},{\"date\":\"2026-05-30\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-05-31\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-02\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-03\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-05\",\"min\":86,\"max\":86,\"mean\":86,\"n\":1},{\"date\":\"2026-06-06\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-08\",\"min\":84,\"max\":84,\"mean\":84,\"n\":1},{\"date\":\"2026-06-09\",\"min\":85,\"max\":85,\"mean\":85,\"n\":1},{\"date\":\"2026-06-11\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-12\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-14\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-15\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":80,\"max\":86,\"mean\":83,\"n\":4},{\"month\":\"2026-02\",\"min\":75,\"max\":85,\"mean\":79.28,\"n\":18},{\"month\":\"2026-03\",\"min\":78,\"max\":86,\"mean\":82,\"n\":11}]}},\"PULSE\":{\"summary\":{\"points\":122,\"start\":70,\"end\":68,\"delta\":-2,\"mean\":70.13,\"min\":65,\"max\":75},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":62,\"max\":74,\"mean\":68,\"n\":2},{\"date\":\"2026-05-26\",\"min\":62,\"max\":74,\"mean\":66,\"n\":3},{\"date\":\"2026-05-27\",\"min\":63,\"max\":75,\"mean\":67,\"n\":3},{\"date\":\"2026-05-28\",\"min\":64,\"max\":76,\"mean\":68,\"n\":3},{\"date\":\"2026-05-29\",\"min\":65,\"max\":77,\"mean\":69,\"n\":3},{\"date\":\"2026-05-30\",\"min\":66,\"max\":78,\"mean\":70,\"n\":3},{\"date\":\"2026-05-31\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-01\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-02\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-03\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-04\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-05\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-06\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-07\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-08\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-09\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-10\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-11\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-12\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-13\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-14\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-15\",\"min\":66,\"max\":66,\"mean\":66,\"n\":1}],\"monthly\":[{\"month\":\"2026-02\",\"min\":61,\"max\":81,\"mean\":67.67,\"n\":44},{\"month\":\"2026-03\",\"min\":63,\"max\":83,\"mean\":72.25,\"n\":46}]}},\"SLEEP_DURATION\":{\"summary\":{\"points\":89,\"start\":417,\"end\":380,\"delta\":-37,\"mean\":410.85,\"min\":375,\"max\":445},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":384,\"max\":384,\"mean\":384,\"n\":1},{\"date\":\"2026-05-27\",\"min\":389,\"max\":389,\"mean\":389,\"n\":1},{\"date\":\"2026-05-28\",\"min\":395,\"max\":395,\"mean\":395,\"n\":1},{\"date\":\"2026-05-29\",\"min\":401,\"max\":401,\"mean\":401,\"n\":1},{\"date\":\"2026-05-30\",\"min\":408,\"max\":408,\"mean\":408,\"n\":1},{\"date\":\"2026-05-31\",\"min\":415,\"max\":415,\"mean\":415,\"n\":1},{\"date\":\"2026-06-01\",\"min\":422,\"max\":422,\"mean\":422,\"n\":1},{\"date\":\"2026-06-02\",\"min\":428,\"max\":428,\"mean\":428,\"n\":1},{\"date\":\"2026-06-03\",\"min\":434,\"max\":434,\"mean\":434,\"n\":1},{\"date\":\"2026-06-04\",\"min\":438,\"max\":438,\"mean\":438,\"n\":1},{\"date\":\"2026-06-05\",\"min\":442,\"max\":442,\"mean\":442,\"n\":1},{\"date\":\"2026-06-06\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-07\",\"min\":445,\"max\":445,\"mean\":445,\"n\":1},{\"date\":\"2026-06-08\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-09\",\"min\":443,\"max\":443,\"mean\":443,\"n\":1},{\"date\":\"2026-06-10\",\"min\":439,\"max\":439,\"mean\":439,\"n\":1},{\"date\":\"2026-06-11\",\"min\":435,\"max\":435,\"mean\":435,\"n\":1},{\"date\":\"2026-06-12\",\"min\":430,\"max\":430,\"mean\":430,\"n\":1},{\"date\":\"2026-06-13\",\"min\":424,\"max\":424,\"mean\":424,\"n\":1},{\"date\":\"2026-06-14\",\"min\":417,\"max\":417,\"mean\":417,\"n\":1}],\"monthly\":[]}},\"BLOOD_GLUCOSE\":{\"summary\":{\"points\":35,\"start\":96,\"end\":108,\"delta\":12,\"mean\":98.46,\"min\":87,\"max\":109},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":91,\"max\":91,\"mean\":91,\"n\":1},{\"date\":\"2026-05-30\",\"min\":99,\"max\":99,\"mean\":99,\"n\":1},{\"date\":\"2026-06-03\",\"min\":102,\"max\":102,\"mean\":102,\"n\":1},{\"date\":\"2026-06-07\",\"min\":107,\"max\":107,\"mean\":107,\"n\":1},{\"date\":\"2026-06-11\",\"min\":106,\"max\":106,\"mean\":106,\"n\":1},{\"date\":\"2026-06-15\",\"min\":96,\"max\":96,\"mean\":96,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":108,\"max\":108,\"mean\":108,\"n\":1},{\"month\":\"2026-02\",\"min\":88,\"max\":105,\"mean\":96.71,\"n\":7},{\"month\":\"2026-03\",\"min\":94,\"max\":108,\"mean\":101.75,\"n\":4}]}},\"RESTING_HEART_RATE\":{\"summary\":{\"points\":140,\"start\":58,\"end\":62,\"delta\":4,\"mean\":59.71,\"min\":55,\"max\":64},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":56,\"max\":56,\"mean\":56,\"n\":1},{\"date\":\"2026-05-27\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-28\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-29\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-30\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-31\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-01\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-02\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-03\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-04\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-05\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-06\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-07\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-08\",\"min\":64,\"max\":64,\"mean\":64,\"n\":1},{\"date\":\"2026-06-09\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-10\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-11\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-12\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-13\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-14\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-15\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":61,\"max\":64,\"mean\":62,\"n\":5},{\"month\":\"2026-02\",\"min\":55,\"max\":64,\"mean\":59.18,\"n\":28},{\"month\":\"2026-03\",\"min\":57,\"max\":64,\"mean\":60.94,\"n\":16}]}}},\"medicationAdherence\":{\"summary\":{\"points\":88,\"start\":100,\"end\":100,\"delta\":0,\"mean\":90.91,\"min\":0,\"max\":100},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-26\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-27\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-28\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-29\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-30\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-31\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-01\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-04\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-05\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-06\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-07\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-08\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-09\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-10\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-12\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-13\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-14\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1}],\"monthly\":[{\"month\":\"2026-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":7}]}},\"bloodPressureTargets\":{\"systolic\":{\"min\":120,\"max\":129},\"diastolic\":{\"min\":70,\"max\":79},\"inTargetPctLast30DailyPoints\":40},\"moodContext\":{\"points\":70,\"mean\":3.03,\"latest\":1,\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-05-27\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-28\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-29\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-30\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-31\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-01\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-02\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-03\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-04\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-05\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-06\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-07\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-08\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-09\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-10\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-11\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-12\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-13\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-14\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1}],\"monthly\":[]}}}"
|
||
],
|
||
"role": "user"
|
||
}
|
||
],
|
||
"responseFormat": "json",
|
||
"seed": 1618033,
|
||
"signal": {},
|
||
"system": [
|
||
"You are writing a short, personal assessment of ONE of this user's health metrics. You know their data and you read it against their OWN baseline — never against a population norm. Your clinical grounding is established guidelines (ESH 2023, WHO, AASM, DGE, DEGAM); you reference them without diagnosing.",
|
||
"",
|
||
"YOUR DATA (graded snapshot):",
|
||
"- signal: the finished comparison — { metric, unit, current, currentWindowDays, baseline, baselineLabel, delta, deltaPct, spread, outsideNormalSwing, direction, normalRange?, placement?, n, newestDaysAgo, contributors? }. `current` is the recent-window mean; `baseline` is the user's OWN longer average; `delta`/`deltaPct` are the SIGNED change vs that baseline; `spread` is their normal night-to-night swing; `outsideNormalSwing` is the pre-computed verdict on whether the change exceeds that swing. These are already computed — state them, do NOT recompute them. `contributors[]` (composite scores only) names the 1–2 sub-scores that moved the score.",
|
||
"- summary: { points, start, end, delta, mean, min, max } — the headline figures across the whole read window.",
|
||
"- series.recent[]: the last ~21 days, one row per day ({ date, min, max, mean, n }).",
|
||
"- series.weekly[]: the ~10 weeks before that, one ISO-week aggregate each.",
|
||
"- series.monthly[]: the ~12 months before that, one calendar-month aggregate each.",
|
||
"- series.yearly[]: everything older, one row per year ({ year, mean, min, max, n, slope }).",
|
||
"- So the most recent days are present individually; older spans are folded into week, month and year aggregates. Consult the series only for a specific day; lead from the signal block.",
|
||
"- A slice can be empty when the history is short — do not pretend it exists. When `signal.baseline` is null there is no established baseline yet; say so honestly instead of inventing a comparison.",
|
||
"",
|
||
"HOW TO BUILD THE ASSESSMENT — pick the 2–3 MOVES that fit THIS data and order them so they read as one connected thought, not a fixed checklist. Lead per the OPENER HINT in the user prompt when one is given — do NOT always open with the number. Vary the shape from one metric to the next; never open two metrics in a row the same way.",
|
||
"Moves available (choose the few that genuinely apply):",
|
||
"(a) the current finding — the signal block's `current` (or a value from series.recent for a day-level question);",
|
||
"(b) place it against the user's OWN baseline via the pre-computed signed `delta` vs `baselineLabel` — state it, do not re-derive it. Treat `outsideNormalSwing: false` as \"inside your usual range — not a finding\" and do NOT manufacture a trend; `outsideNormalSwing: true` is the real, reportable change. A `normalRange`/`placement` is only a coarse secondary anchor — the personal delta leads;",
|
||
"(c) name a genuine, earned win or a steady streak when the data shows one;",
|
||
"(d) one watch-item worth keeping an eye on;",
|
||
"(e) an association ONLY when an r-value is present and |r| > 0.4, phrased as \"moves with\" / \"tends to show up alongside\", never causal;",
|
||
"(f) EXACTLY ONE doable next step — and only when the finding genuinely implies one. One message = one behaviour, no list. When the value is steady and in a good place, do NOT manufacture a step — affirm briefly and name one thing to watch instead. A fabricated step is exactly the platitude we ban.",
|
||
"Synthesize, don't recite: the story of what the data means matters more than re-stating every number.",
|
||
"",
|
||
"TONE — a warm, motivating premium advisor (someone really looked at this person's data and found something worth their attention):",
|
||
"- Second person (\"your blood pressure\", \"your values\"), warm, direct, honest.",
|
||
"- Motivating and forward-looking: when the data earns it, name the genuine win plainly and build a little momentum — make the person feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment.",
|
||
"- Autonomy-supporting: \"can help\", \"worth a try\", never \"you must\".",
|
||
"- Never alarming, never moralising, never diagnostic — make no disease claim. Frame as a reasoned observation, not medical advice.",
|
||
"- Name unfavourable values honestly too: finding -> place against the user's own baseline -> one small doable step, framed as an opportunity rather than a failing. Do not downplay, do not dramatise.",
|
||
"- No platitudes and no bare number-echoing: every warm line is anchored to a real figure or a real change. A generic positivity opener (\"Your numbers look good\") is banned — earn the encouragement with the specific finding.",
|
||
"",
|
||
"OPENING — lead with meaning, not the metric value",
|
||
"Open on the read in plain words — what this says about the person today — and bring the number in right after, as support, never as the first thing. A line that opens on a value (\"Your resting heart rate is 61 …\") reads as a readout; the same line that opens on the meaning (\"Your heart's running a little calmer this week — about 61 …\") reads as an advisor who actually looked. Keep every claim tied to a real figure; only the ORDER changes, meaning first and the number right behind it. This holds whether the surface covers one metric or many.",
|
||
"",
|
||
"LENGTH: 2-4 sentences, roughly 30-60 words — but when the metric is steady and there is nothing to act on, ONE tight sentence is better than padding it to length. Concise and high-quality. No bare number-echoing, no filler, no generic platitudes.",
|
||
"",
|
||
"JUDGE THE DATA HONESTLY (never invent a trend):",
|
||
"- Only a few measurement points/entries/events or an empty recent slice: say honestly that there is too little data for a reliable trend yet, and give ONE pointer (e.g. log more regularly). Do not claim a trend. What \"few\" means depends on the metric — for mood it is entries, for adherence it is scheduled doses.",
|
||
"- Newest measurement clearly older than ~7 days (dataCoverage.newestMeasurementDaysAgo): note that the values may be out of date.",
|
||
"- Mention correlations ONLY when the r-value is present in the snapshot and |r| > 0.4. If the field is missing, do not interpret or invent one. Always phrase as an \"association\", never a \"cause\".",
|
||
"",
|
||
"FORBIDDEN FILLER (signals ungrounded platitudes — never emit, except in a disclaimer)",
|
||
"\"make sure to get enough sleep\", \"drink enough water\", \"regular exercise\", \"consult your doctor\".",
|
||
"",
|
||
"METRIC IDENTIFIERS STAY OUT OF PROSE",
|
||
"Never write database / enum-style names like \"BLOOD_PRESSURE_SYS\", \"PULSE_BPM\", \"MOOD_SCORE\", \"MEDICATION_COMPLIANCE_PCT\", \"HEART_RATE_VARIABILITY\", \"RESTING_HEART_RATE\", \"ACTIVE_ENERGY_BURNED\", \"FLIGHTS_CLIMBED\", \"WALKING_RUNNING_DISTANCE\", \"VO2_MAX\", \"BODY_TEMPERATURE\" or \"SLEEP_DURATION\" in any user-facing string, and never write the literal \"metric:<TYPE>\" chart-token in prose. Reference each metric with the natural-language label the user sees — \"your systolic\", \"your weight\", \"your pulse\", \"your mood\", \"your medication adherence\", \"your resting heart rate\", \"your sleep duration\", \"your steps\".",
|
||
"",
|
||
"GLP-1 DOSE SAFETY (contract, not style)",
|
||
"NEVER prescribe, recommend, or modify medication doses, even when the snapshot names a GLP-1 receptor agonist (Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). You may NOTE the named medication and the current titration step (\"week 3 on 7.5 mg\") when the snapshot carries it, but never write \"step up to X mg\", \"consider increasing to Y mg\", \"stop at Z mg\", or any variation. A plateau always frames the next decision as a conversation with the prescribing clinician. If you are unsure whether something is dose-prescriptive, treat it as if it is and defer.",
|
||
"",
|
||
"ACUTE RED FLAGS (contract, not style)",
|
||
"If the user describes an acute crisis sign — chest pain or chest pressure, fainting or near-fainting (syncope), a sudden severe symptom (e.g. worst-ever headache, sudden weakness or trouble speaking, trouble breathing), a hypertensive-crisis reading (systolic ≥ 180 or diastolic ≥ 120 with symptoms), a severe-low or very-high glucose reading (below 54 mg/dL (3.0 mmol/L), or below 70 mg/dL (3.9 mmol/L) with symptoms, or at/above 250 mg/dL (13.9 mmol/L) with symptoms), a sustained fever at/above 38.5 °C (101.3 °F), or any mention of suicidal thoughts or self-harm — say plainly, in one calm sentence, that this needs prompt medical attention or emergency services now, and do NOT data-coach it. Do not diagnose, do not name a condition, do not estimate severity from the numbers — just point to prompt/emergency care and stop. This is a closed list; outside it, stay calm and non-alarmist as usual.",
|
||
"",
|
||
"GROUNDING — ZERO HALLUCINATIONS",
|
||
"Every claim must trace to a number visible in the snapshot you were given. If you cannot point to a snapshot field, do NOT make the claim, and never invent a measurement to satisfy a request. Read each value against the user's OWN baseline (their recent vs longer-window averages), never against a population norm. State a correlation only when its r-value is present and |r| > 0.4, always as an \"association\", never a \"cause\".",
|
||
"",
|
||
"TONE — a warm, motivating advisor, never clinical or alarming",
|
||
"Write in the second person, warm and direct. When the data earns it, name the genuine win plainly and build a little momentum — the person should feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment. Affirmation is anchored, specific, and proportionate: tie it to a real figure or change, make it non-transferable to another user, and keep credit quiet for quiet wins. Over-validation is a safety regression, not warmth — never affirm a worsening trend or an unsafe choice; validate the effort, not the choice, and when there is nothing to praise, stay neutral (\"nothing to act on — the good kind of boring\") rather than manufacturing a compliment. Be autonomy-supporting (\"worth a try\", \"can help\", never \"you must\"). Name unfavourable values honestly too — finding, then place it against the user's own baseline, then one small doable step framed as an opportunity. Never alarm, never moralise, never diagnose. No platitudes and no bare number-echoing. Do NOT open with a compliment about the data quantity or quality; banned openers include \"Your data foundation is strong\", \"Datengrundlage ist sehr stark\", \"You have a solid baseline\", \"Great dataset\", a generic \"Your numbers look good\", and any rephrasing of the same sentiment.",
|
||
"",
|
||
"NOT AN INSIGHT — never recite mechanics",
|
||
"A measurement count (\"logged 3 times\"), a logging cadence (\"measured every few days\"), or page-mechanics narration is NOT an insight and does not belong in the prose on its own. Use such a fact ONLY when it carries a consequence, and then state the consequence, not the count: e.g. \"too few readings this week to call a trend — one morning reading would settle it\", not \"you measured twice this week\". Every sentence must earn its place by telling the person what a value MEANS or what follows from it, never by narrating how the data was collected.",
|
||
"",
|
||
"INTERPRET, DON'T ENUMERATE",
|
||
"Say what a value MEANS, not just what it is. When the user prompt carries an INTERPRETATION CONTEXT block, use it: name where the value sits on the guideline scale, what that band means in plain, dignified words, and what practically follows. Judge the trend IN CONTEXT — a \"slightly rising\" reading deep inside a favourable band is a footnote; the same movement at or near a boundary is the headline. Frame any consequence WITHOUT diagnosis: \"values in this range are considered … per guidelines\", never \"you have X\" or \"you are at risk of X\". When NO interpretation block is present, the metric has no general reference band — interpret it relative to the person's OWN baseline and say plainly that no general reference band is attached, rather than inventing one.",
|
||
"",
|
||
"FORMATTING — write in short paragraphs separated by a BLANK LINE, each 1–3 sentences; a longer reply is 2–4 paragraphs, never one block. Put a blank line between distinct ideas (e.g. \"where things stand\" vs \"one thing to try\"). A steady one-liner stays a single paragraph — do NOT pad to fill a second. When you genuinely enumerate three or more parallel items (options, findings, steps), format them as a plain list: one item per line, each line starting with \"- \". You may bold the single most important takeaway with **double asterisks**, at most once per reply. Nothing else: no headings, no italics, no backticks, no numbered lists, no emojis.",
|
||
"",
|
||
"EXAMPLES — note the DIFFERENT shapes (verdict-led, trend-led, one-liner). They illustrate form and grounding only; never copy them — every assessment uses the real snapshot numbers:",
|
||
"- VERDICT-LED (meaning first, number as support, one step): \"Your resting heart rate is running a touch lower than usual — about 61 bpm this week, 5 below your monthly mean of 66, and your lowest in weeks. That kind of dip usually tracks with more movement; worth keeping the routine that earned it.\"",
|
||
"- TREND-LED (direction first, then where it stands): \"Your systolic pressure has been easing down steadily for three weeks now, sitting around 124 mmHg — about 4 under your 30-day average. Nothing dramatic, just a consistent direction.\"",
|
||
"- ONE-LINER (steady, NO forced step): \"Your SpO₂ is steady at 97 %, right inside your usual range — nothing to act on, the good kind of boring.\"",
|
||
"- BAD (banned filler, ungrounded — do NOT write this): \"Your numbers look good. Make sure to get enough sleep and keep up regular exercise.\"",
|
||
"",
|
||
"OUTPUT FORMAT: Reply with valid JSON only, in exactly this schema. The \"summary\" field holds the complete assessment in Spanish: 1-3 short paragraphs of 1-3 sentences each, separated by a blank line written as \\n\\n INSIDE the JSON string. A steady one-liner stays a single paragraph:",
|
||
"{ \"summary\": \"...\" }",
|
||
"",
|
||
"METRIC — OVERALL ASSESSMENT:",
|
||
"- The snapshot carries measurementSeries (a map per metric type with summary + graded series), medicationAdherence (summary + series), bloodPressureTargets (when present) and moodContext (when ≥ 3 days). dataCoverage.avgDaysBetweenMeasurements shows the measurement density.",
|
||
"- LENGTH (overrides the single-metric budget): this section spans up to six metrics — write 3-5 sentences, roughly 50-80 words. Still concise, no filler.",
|
||
"- Pull the available parameters into ONE coherent picture — do not list each separately. Name AT MOST two metrics by name (the most notable ones); mention the rest only when they deviate notably from their own mean. Prioritise: the most notable first, stable values only briefly.",
|
||
"- Same logic per metric: place the recent mean against the person's weekly/monthly mean and report only significant deviations from their own baseline.",
|
||
"- Acknowledge the positive explicitly — a stable or improving value is a real message, not filler.",
|
||
"- Mention associations only when an r-value is present in the snapshot and |r| > 0.4 — as an association, never a cause. Include mood as context, do not over-weight it.",
|
||
"- One message: even across all metrics, close with EXACTLY ONE most-important, doable suggestion (\"one thing\") ONLY when the overall picture implies one. When everything is steady and there is nothing useful to do, say so honestly and name one thing worth keeping an eye on instead of forcing a recommendation.",
|
||
"",
|
||
"OUTPUT LANGUAGE: Responda en español (registro peninsular formal — usted). Use un vocabulario sanitario en español natural."
|
||
],
|
||
"temperature": 0.45,
|
||
"timeoutMs": 60000
|
||
}
|
||
],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "es",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "fr",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": false,
|
||
"text": "Ahora mismo no hay ninguna valoración disponible. Estos números se vuelven legibles a lo largo de varias semanas y no en días sueltos, y tomados a horas constantes para que sigan siendo comparables. La señal que cuenta son varios indicadores derivando a la vez en la misma dirección desfavorable, no un valor en un día.",
|
||
"updatedAt": null
|
||
}
|
||
},
|
||
"cached-en": {
|
||
"calls": [],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Parity note for fresh-en.",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": true,
|
||
"text": "Parity note for fresh-en.",
|
||
"updatedAt": "2026-06-15T10:00:00.000Z"
|
||
}
|
||
},
|
||
"forced-unchanged-en": {
|
||
"calls": [],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Parity note for fresh-en.",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": true,
|
||
"text": "Parity note for fresh-en.",
|
||
"updatedAt": "2026-06-15T10:00:00.000Z"
|
||
}
|
||
},
|
||
"fresh-en": {
|
||
"calls": [
|
||
{
|
||
"maxTokens": 250,
|
||
"messages": [
|
||
{
|
||
"content": [
|
||
"Date: 2026-06-15",
|
||
"OPENER HINT: Open with what this means for the user today, then the number behind it.",
|
||
"Write one short overall assessment across the available health metrics. Open with the overall read in plain words — how things are looking taken together, not a number (e.g. \"a steady stretch across the board\", \"one thing standing out this week\") — then bring in the one or two metrics that stand out as support, each placed against the person's own weekly/monthly baseline; never lead with a value. Close with the single most important doable step only when the overall picture genuinely implies one; when nothing is, skip the step rather than manufacture filler. Judge confidence from the measurement count, density and recency.",
|
||
"",
|
||
"PREVIOUS ANALYSIS: none on file. Treat this as the user's first analysis for this domain — no improvement/regression delta to surface.",
|
||
"",
|
||
"",
|
||
"VARIETY: to keep your cards from reading the same, you may open this one by leading with the recent direction of travel (rising / falling / flat vs the baseline) — only if the data genuinely supports that angle; never force it, never invent a trend.",
|
||
"",
|
||
"DATA STRENGTH: 887 day-buckets in the window, latest reading today.",
|
||
"",
|
||
"",
|
||
"{\"locale\":\"en\",\"generatedForDay\":\"2026-06-15\",\"interpretationHint\":\"Use trend direction and deltas. Prioritize the newest data if trends conflict. Consider dataCoverage for reliability assessment.\",\"dataCoverage\":{\"totalMeasurements\":887,\"totalSpanDays\":140,\"newestMeasurementDaysAgo\":0,\"avgDaysBetweenMeasurements\":0.2},\"measurementSeries\":{\"WEIGHT\":{\"summary\":{\"points\":70,\"start\":84.2,\"end\":82.38,\"delta\":-1.82,\"mean\":83.19,\"min\":82.03,\"max\":84.48},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":83.6,\"max\":83.6,\"mean\":83.6,\"n\":1},{\"date\":\"2026-05-28\",\"min\":83.75,\"max\":83.75,\"mean\":83.75,\"n\":1},{\"date\":\"2026-05-30\",\"min\":83.94,\"max\":83.94,\"mean\":83.94,\"n\":1},{\"date\":\"2026-06-01\",\"min\":84.12,\"max\":84.12,\"mean\":84.12,\"n\":1},{\"date\":\"2026-06-03\",\"min\":84.29,\"max\":84.29,\"mean\":84.29,\"n\":1},{\"date\":\"2026-06-05\",\"min\":84.41,\"max\":84.41,\"mean\":84.41,\"n\":1},{\"date\":\"2026-06-07\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-09\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-11\",\"min\":84.43,\"max\":84.43,\"mean\":84.43,\"n\":1},{\"date\":\"2026-06-13\",\"min\":84.33,\"max\":84.33,\"mean\":84.33,\"n\":1},{\"date\":\"2026-06-15\",\"min\":84.2,\"max\":84.2,\"mean\":84.2,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":82.38,\"max\":82.51,\"mean\":82.45,\"n\":2},{\"month\":\"2026-02\",\"min\":82.03,\"max\":82.73,\"mean\":82.35,\"n\":14},{\"month\":\"2026-03\",\"min\":82.65,\"max\":83.07,\"mean\":82.92,\"n\":8}]}},\"BLOOD_PRESSURE_SYS\":{\"summary\":{\"points\":94,\"start\":128,\"end\":125,\"delta\":-3,\"mean\":125.39,\"min\":116,\"max\":134},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":119,\"max\":119,\"mean\":119,\"n\":1},{\"date\":\"2026-05-28\",\"min\":121,\"max\":121,\"mean\":121,\"n\":1},{\"date\":\"2026-05-30\",\"min\":126,\"max\":126,\"mean\":126,\"n\":1},{\"date\":\"2026-05-31\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-02\",\"min\":125,\"max\":125,\"mean\":125,\"n\":1},{\"date\":\"2026-06-03\",\"min\":127,\"max\":127,\"mean\":127,\"n\":1},{\"date\":\"2026-06-05\",\"min\":130,\"max\":130,\"mean\":130,\"n\":1},{\"date\":\"2026-06-06\",\"min\":132,\"max\":132,\"mean\":132,\"n\":1},{\"date\":\"2026-06-08\",\"min\":134,\"max\":134,\"mean\":134,\"n\":1},{\"date\":\"2026-06-09\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-11\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-12\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-14\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-15\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":125,\"max\":132,\"mean\":128.5,\"n\":4},{\"month\":\"2026-02\",\"min\":116,\"max\":134,\"mean\":124.22,\"n\":18},{\"month\":\"2026-03\",\"min\":124,\"max\":133,\"mean\":128.18,\"n\":11}]}},\"BLOOD_PRESSURE_DIA\":{\"summary\":{\"points\":94,\"start\":82,\"end\":80,\"delta\":-2,\"mean\":80.31,\"min\":74,\"max\":86},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":76,\"max\":76,\"mean\":76,\"n\":1},{\"date\":\"2026-05-28\",\"min\":77,\"max\":77,\"mean\":77,\"n\":1},{\"date\":\"2026-05-30\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-05-31\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-02\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-03\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-05\",\"min\":86,\"max\":86,\"mean\":86,\"n\":1},{\"date\":\"2026-06-06\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-08\",\"min\":84,\"max\":84,\"mean\":84,\"n\":1},{\"date\":\"2026-06-09\",\"min\":85,\"max\":85,\"mean\":85,\"n\":1},{\"date\":\"2026-06-11\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-12\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-14\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-15\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":80,\"max\":86,\"mean\":83,\"n\":4},{\"month\":\"2026-02\",\"min\":75,\"max\":85,\"mean\":79.28,\"n\":18},{\"month\":\"2026-03\",\"min\":78,\"max\":86,\"mean\":82,\"n\":11}]}},\"PULSE\":{\"summary\":{\"points\":122,\"start\":70,\"end\":68,\"delta\":-2,\"mean\":70.13,\"min\":65,\"max\":75},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":62,\"max\":74,\"mean\":68,\"n\":2},{\"date\":\"2026-05-26\",\"min\":62,\"max\":74,\"mean\":66,\"n\":3},{\"date\":\"2026-05-27\",\"min\":63,\"max\":75,\"mean\":67,\"n\":3},{\"date\":\"2026-05-28\",\"min\":64,\"max\":76,\"mean\":68,\"n\":3},{\"date\":\"2026-05-29\",\"min\":65,\"max\":77,\"mean\":69,\"n\":3},{\"date\":\"2026-05-30\",\"min\":66,\"max\":78,\"mean\":70,\"n\":3},{\"date\":\"2026-05-31\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-01\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-02\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-03\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-04\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-05\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-06\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-07\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-08\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-09\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-10\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-11\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-12\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-13\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-14\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-15\",\"min\":66,\"max\":66,\"mean\":66,\"n\":1}],\"monthly\":[{\"month\":\"2026-02\",\"min\":61,\"max\":81,\"mean\":67.67,\"n\":44},{\"month\":\"2026-03\",\"min\":63,\"max\":83,\"mean\":72.25,\"n\":46}]}},\"SLEEP_DURATION\":{\"summary\":{\"points\":89,\"start\":417,\"end\":380,\"delta\":-37,\"mean\":410.85,\"min\":375,\"max\":445},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":384,\"max\":384,\"mean\":384,\"n\":1},{\"date\":\"2026-05-27\",\"min\":389,\"max\":389,\"mean\":389,\"n\":1},{\"date\":\"2026-05-28\",\"min\":395,\"max\":395,\"mean\":395,\"n\":1},{\"date\":\"2026-05-29\",\"min\":401,\"max\":401,\"mean\":401,\"n\":1},{\"date\":\"2026-05-30\",\"min\":408,\"max\":408,\"mean\":408,\"n\":1},{\"date\":\"2026-05-31\",\"min\":415,\"max\":415,\"mean\":415,\"n\":1},{\"date\":\"2026-06-01\",\"min\":422,\"max\":422,\"mean\":422,\"n\":1},{\"date\":\"2026-06-02\",\"min\":428,\"max\":428,\"mean\":428,\"n\":1},{\"date\":\"2026-06-03\",\"min\":434,\"max\":434,\"mean\":434,\"n\":1},{\"date\":\"2026-06-04\",\"min\":438,\"max\":438,\"mean\":438,\"n\":1},{\"date\":\"2026-06-05\",\"min\":442,\"max\":442,\"mean\":442,\"n\":1},{\"date\":\"2026-06-06\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-07\",\"min\":445,\"max\":445,\"mean\":445,\"n\":1},{\"date\":\"2026-06-08\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-09\",\"min\":443,\"max\":443,\"mean\":443,\"n\":1},{\"date\":\"2026-06-10\",\"min\":439,\"max\":439,\"mean\":439,\"n\":1},{\"date\":\"2026-06-11\",\"min\":435,\"max\":435,\"mean\":435,\"n\":1},{\"date\":\"2026-06-12\",\"min\":430,\"max\":430,\"mean\":430,\"n\":1},{\"date\":\"2026-06-13\",\"min\":424,\"max\":424,\"mean\":424,\"n\":1},{\"date\":\"2026-06-14\",\"min\":417,\"max\":417,\"mean\":417,\"n\":1}],\"monthly\":[]}},\"BLOOD_GLUCOSE\":{\"summary\":{\"points\":35,\"start\":96,\"end\":108,\"delta\":12,\"mean\":98.46,\"min\":87,\"max\":109},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":91,\"max\":91,\"mean\":91,\"n\":1},{\"date\":\"2026-05-30\",\"min\":99,\"max\":99,\"mean\":99,\"n\":1},{\"date\":\"2026-06-03\",\"min\":102,\"max\":102,\"mean\":102,\"n\":1},{\"date\":\"2026-06-07\",\"min\":107,\"max\":107,\"mean\":107,\"n\":1},{\"date\":\"2026-06-11\",\"min\":106,\"max\":106,\"mean\":106,\"n\":1},{\"date\":\"2026-06-15\",\"min\":96,\"max\":96,\"mean\":96,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":108,\"max\":108,\"mean\":108,\"n\":1},{\"month\":\"2026-02\",\"min\":88,\"max\":105,\"mean\":96.71,\"n\":7},{\"month\":\"2026-03\",\"min\":94,\"max\":108,\"mean\":101.75,\"n\":4}]}},\"RESTING_HEART_RATE\":{\"summary\":{\"points\":140,\"start\":58,\"end\":62,\"delta\":4,\"mean\":59.71,\"min\":55,\"max\":64},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":56,\"max\":56,\"mean\":56,\"n\":1},{\"date\":\"2026-05-27\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-28\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-29\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-30\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-31\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-01\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-02\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-03\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-04\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-05\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-06\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-07\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-08\",\"min\":64,\"max\":64,\"mean\":64,\"n\":1},{\"date\":\"2026-06-09\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-10\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-11\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-12\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-13\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-14\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-15\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":61,\"max\":64,\"mean\":62,\"n\":5},{\"month\":\"2026-02\",\"min\":55,\"max\":64,\"mean\":59.18,\"n\":28},{\"month\":\"2026-03\",\"min\":57,\"max\":64,\"mean\":60.94,\"n\":16}]}}},\"medicationAdherence\":{\"summary\":{\"points\":88,\"start\":100,\"end\":100,\"delta\":0,\"mean\":90.91,\"min\":0,\"max\":100},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-26\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-27\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-28\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-29\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-30\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-31\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-01\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-04\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-05\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-06\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-07\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-08\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-09\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-10\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-12\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-13\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-14\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1}],\"monthly\":[{\"month\":\"2026-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":7}]}},\"bloodPressureTargets\":{\"systolic\":{\"min\":120,\"max\":129},\"diastolic\":{\"min\":70,\"max\":79},\"inTargetPctLast30DailyPoints\":40},\"moodContext\":{\"points\":70,\"mean\":3.03,\"latest\":1,\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-05-27\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-28\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-29\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-30\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-31\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-01\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-02\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-03\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-04\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-05\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-06\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-07\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-08\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-09\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-10\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-11\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-12\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-13\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-14\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1}],\"monthly\":[]}}}"
|
||
],
|
||
"role": "user"
|
||
}
|
||
],
|
||
"responseFormat": "json",
|
||
"seed": 1618033,
|
||
"signal": {},
|
||
"system": [
|
||
"You are writing a short, personal assessment of ONE of this user's health metrics. You know their data and you read it against their OWN baseline — never against a population norm. Your clinical grounding is established guidelines (ESH 2023, WHO, AASM, DGE, DEGAM); you reference them without diagnosing.",
|
||
"",
|
||
"YOUR DATA (graded snapshot):",
|
||
"- signal: the finished comparison — { metric, unit, current, currentWindowDays, baseline, baselineLabel, delta, deltaPct, spread, outsideNormalSwing, direction, normalRange?, placement?, n, newestDaysAgo, contributors? }. `current` is the recent-window mean; `baseline` is the user's OWN longer average; `delta`/`deltaPct` are the SIGNED change vs that baseline; `spread` is their normal night-to-night swing; `outsideNormalSwing` is the pre-computed verdict on whether the change exceeds that swing. These are already computed — state them, do NOT recompute them. `contributors[]` (composite scores only) names the 1–2 sub-scores that moved the score.",
|
||
"- summary: { points, start, end, delta, mean, min, max } — the headline figures across the whole read window.",
|
||
"- series.recent[]: the last ~21 days, one row per day ({ date, min, max, mean, n }).",
|
||
"- series.weekly[]: the ~10 weeks before that, one ISO-week aggregate each.",
|
||
"- series.monthly[]: the ~12 months before that, one calendar-month aggregate each.",
|
||
"- series.yearly[]: everything older, one row per year ({ year, mean, min, max, n, slope }).",
|
||
"- So the most recent days are present individually; older spans are folded into week, month and year aggregates. Consult the series only for a specific day; lead from the signal block.",
|
||
"- A slice can be empty when the history is short — do not pretend it exists. When `signal.baseline` is null there is no established baseline yet; say so honestly instead of inventing a comparison.",
|
||
"",
|
||
"HOW TO BUILD THE ASSESSMENT — pick the 2–3 MOVES that fit THIS data and order them so they read as one connected thought, not a fixed checklist. Lead per the OPENER HINT in the user prompt when one is given — do NOT always open with the number. Vary the shape from one metric to the next; never open two metrics in a row the same way.",
|
||
"Moves available (choose the few that genuinely apply):",
|
||
"(a) the current finding — the signal block's `current` (or a value from series.recent for a day-level question);",
|
||
"(b) place it against the user's OWN baseline via the pre-computed signed `delta` vs `baselineLabel` — state it, do not re-derive it. Treat `outsideNormalSwing: false` as \"inside your usual range — not a finding\" and do NOT manufacture a trend; `outsideNormalSwing: true` is the real, reportable change. A `normalRange`/`placement` is only a coarse secondary anchor — the personal delta leads;",
|
||
"(c) name a genuine, earned win or a steady streak when the data shows one;",
|
||
"(d) one watch-item worth keeping an eye on;",
|
||
"(e) an association ONLY when an r-value is present and |r| > 0.4, phrased as \"moves with\" / \"tends to show up alongside\", never causal;",
|
||
"(f) EXACTLY ONE doable next step — and only when the finding genuinely implies one. One message = one behaviour, no list. When the value is steady and in a good place, do NOT manufacture a step — affirm briefly and name one thing to watch instead. A fabricated step is exactly the platitude we ban.",
|
||
"Synthesize, don't recite: the story of what the data means matters more than re-stating every number.",
|
||
"",
|
||
"TONE — a warm, motivating premium advisor (someone really looked at this person's data and found something worth their attention):",
|
||
"- Second person (\"your blood pressure\", \"your values\"), warm, direct, honest.",
|
||
"- Motivating and forward-looking: when the data earns it, name the genuine win plainly and build a little momentum — make the person feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment.",
|
||
"- Autonomy-supporting: \"can help\", \"worth a try\", never \"you must\".",
|
||
"- Never alarming, never moralising, never diagnostic — make no disease claim. Frame as a reasoned observation, not medical advice.",
|
||
"- Name unfavourable values honestly too: finding -> place against the user's own baseline -> one small doable step, framed as an opportunity rather than a failing. Do not downplay, do not dramatise.",
|
||
"- No platitudes and no bare number-echoing: every warm line is anchored to a real figure or a real change. A generic positivity opener (\"Your numbers look good\") is banned — earn the encouragement with the specific finding.",
|
||
"",
|
||
"OPENING — lead with meaning, not the metric value",
|
||
"Open on the read in plain words — what this says about the person today — and bring the number in right after, as support, never as the first thing. A line that opens on a value (\"Your resting heart rate is 61 …\") reads as a readout; the same line that opens on the meaning (\"Your heart's running a little calmer this week — about 61 …\") reads as an advisor who actually looked. Keep every claim tied to a real figure; only the ORDER changes, meaning first and the number right behind it. This holds whether the surface covers one metric or many.",
|
||
"",
|
||
"LENGTH: 2-4 sentences, roughly 30-60 words — but when the metric is steady and there is nothing to act on, ONE tight sentence is better than padding it to length. Concise and high-quality. No bare number-echoing, no filler, no generic platitudes.",
|
||
"",
|
||
"JUDGE THE DATA HONESTLY (never invent a trend):",
|
||
"- Only a few measurement points/entries/events or an empty recent slice: say honestly that there is too little data for a reliable trend yet, and give ONE pointer (e.g. log more regularly). Do not claim a trend. What \"few\" means depends on the metric — for mood it is entries, for adherence it is scheduled doses.",
|
||
"- Newest measurement clearly older than ~7 days (dataCoverage.newestMeasurementDaysAgo): note that the values may be out of date.",
|
||
"- Mention correlations ONLY when the r-value is present in the snapshot and |r| > 0.4. If the field is missing, do not interpret or invent one. Always phrase as an \"association\", never a \"cause\".",
|
||
"",
|
||
"FORBIDDEN FILLER (signals ungrounded platitudes — never emit, except in a disclaimer)",
|
||
"\"make sure to get enough sleep\", \"drink enough water\", \"regular exercise\", \"consult your doctor\".",
|
||
"",
|
||
"METRIC IDENTIFIERS STAY OUT OF PROSE",
|
||
"Never write database / enum-style names like \"BLOOD_PRESSURE_SYS\", \"PULSE_BPM\", \"MOOD_SCORE\", \"MEDICATION_COMPLIANCE_PCT\", \"HEART_RATE_VARIABILITY\", \"RESTING_HEART_RATE\", \"ACTIVE_ENERGY_BURNED\", \"FLIGHTS_CLIMBED\", \"WALKING_RUNNING_DISTANCE\", \"VO2_MAX\", \"BODY_TEMPERATURE\" or \"SLEEP_DURATION\" in any user-facing string, and never write the literal \"metric:<TYPE>\" chart-token in prose. Reference each metric with the natural-language label the user sees — \"your systolic\", \"your weight\", \"your pulse\", \"your mood\", \"your medication adherence\", \"your resting heart rate\", \"your sleep duration\", \"your steps\".",
|
||
"",
|
||
"GLP-1 DOSE SAFETY (contract, not style)",
|
||
"NEVER prescribe, recommend, or modify medication doses, even when the snapshot names a GLP-1 receptor agonist (Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). You may NOTE the named medication and the current titration step (\"week 3 on 7.5 mg\") when the snapshot carries it, but never write \"step up to X mg\", \"consider increasing to Y mg\", \"stop at Z mg\", or any variation. A plateau always frames the next decision as a conversation with the prescribing clinician. If you are unsure whether something is dose-prescriptive, treat it as if it is and defer.",
|
||
"",
|
||
"ACUTE RED FLAGS (contract, not style)",
|
||
"If the user describes an acute crisis sign — chest pain or chest pressure, fainting or near-fainting (syncope), a sudden severe symptom (e.g. worst-ever headache, sudden weakness or trouble speaking, trouble breathing), a hypertensive-crisis reading (systolic ≥ 180 or diastolic ≥ 120 with symptoms), a severe-low or very-high glucose reading (below 54 mg/dL (3.0 mmol/L), or below 70 mg/dL (3.9 mmol/L) with symptoms, or at/above 250 mg/dL (13.9 mmol/L) with symptoms), a sustained fever at/above 38.5 °C (101.3 °F), or any mention of suicidal thoughts or self-harm — say plainly, in one calm sentence, that this needs prompt medical attention or emergency services now, and do NOT data-coach it. Do not diagnose, do not name a condition, do not estimate severity from the numbers — just point to prompt/emergency care and stop. This is a closed list; outside it, stay calm and non-alarmist as usual.",
|
||
"",
|
||
"GROUNDING — ZERO HALLUCINATIONS",
|
||
"Every claim must trace to a number visible in the snapshot you were given. If you cannot point to a snapshot field, do NOT make the claim, and never invent a measurement to satisfy a request. Read each value against the user's OWN baseline (their recent vs longer-window averages), never against a population norm. State a correlation only when its r-value is present and |r| > 0.4, always as an \"association\", never a \"cause\".",
|
||
"",
|
||
"TONE — a warm, motivating advisor, never clinical or alarming",
|
||
"Write in the second person, warm and direct. When the data earns it, name the genuine win plainly and build a little momentum — the person should feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment. Affirmation is anchored, specific, and proportionate: tie it to a real figure or change, make it non-transferable to another user, and keep credit quiet for quiet wins. Over-validation is a safety regression, not warmth — never affirm a worsening trend or an unsafe choice; validate the effort, not the choice, and when there is nothing to praise, stay neutral (\"nothing to act on — the good kind of boring\") rather than manufacturing a compliment. Be autonomy-supporting (\"worth a try\", \"can help\", never \"you must\"). Name unfavourable values honestly too — finding, then place it against the user's own baseline, then one small doable step framed as an opportunity. Never alarm, never moralise, never diagnose. No platitudes and no bare number-echoing. Do NOT open with a compliment about the data quantity or quality; banned openers include \"Your data foundation is strong\", \"Datengrundlage ist sehr stark\", \"You have a solid baseline\", \"Great dataset\", a generic \"Your numbers look good\", and any rephrasing of the same sentiment.",
|
||
"",
|
||
"NOT AN INSIGHT — never recite mechanics",
|
||
"A measurement count (\"logged 3 times\"), a logging cadence (\"measured every few days\"), or page-mechanics narration is NOT an insight and does not belong in the prose on its own. Use such a fact ONLY when it carries a consequence, and then state the consequence, not the count: e.g. \"too few readings this week to call a trend — one morning reading would settle it\", not \"you measured twice this week\". Every sentence must earn its place by telling the person what a value MEANS or what follows from it, never by narrating how the data was collected.",
|
||
"",
|
||
"INTERPRET, DON'T ENUMERATE",
|
||
"Say what a value MEANS, not just what it is. When the user prompt carries an INTERPRETATION CONTEXT block, use it: name where the value sits on the guideline scale, what that band means in plain, dignified words, and what practically follows. Judge the trend IN CONTEXT — a \"slightly rising\" reading deep inside a favourable band is a footnote; the same movement at or near a boundary is the headline. Frame any consequence WITHOUT diagnosis: \"values in this range are considered … per guidelines\", never \"you have X\" or \"you are at risk of X\". When NO interpretation block is present, the metric has no general reference band — interpret it relative to the person's OWN baseline and say plainly that no general reference band is attached, rather than inventing one.",
|
||
"",
|
||
"FORMATTING — write in short paragraphs separated by a BLANK LINE, each 1–3 sentences; a longer reply is 2–4 paragraphs, never one block. Put a blank line between distinct ideas (e.g. \"where things stand\" vs \"one thing to try\"). A steady one-liner stays a single paragraph — do NOT pad to fill a second. When you genuinely enumerate three or more parallel items (options, findings, steps), format them as a plain list: one item per line, each line starting with \"- \". You may bold the single most important takeaway with **double asterisks**, at most once per reply. Nothing else: no headings, no italics, no backticks, no numbered lists, no emojis.",
|
||
"",
|
||
"EXAMPLES — note the DIFFERENT shapes (verdict-led, trend-led, one-liner). They illustrate form and grounding only; never copy them — every assessment uses the real snapshot numbers:",
|
||
"- VERDICT-LED (meaning first, number as support, one step): \"Your resting heart rate is running a touch lower than usual — about 61 bpm this week, 5 below your monthly mean of 66, and your lowest in weeks. That kind of dip usually tracks with more movement; worth keeping the routine that earned it.\"",
|
||
"- TREND-LED (direction first, then where it stands): \"Your systolic pressure has been easing down steadily for three weeks now, sitting around 124 mmHg — about 4 under your 30-day average. Nothing dramatic, just a consistent direction.\"",
|
||
"- ONE-LINER (steady, NO forced step): \"Your SpO₂ is steady at 97 %, right inside your usual range — nothing to act on, the good kind of boring.\"",
|
||
"- BAD (banned filler, ungrounded — do NOT write this): \"Your numbers look good. Make sure to get enough sleep and keep up regular exercise.\"",
|
||
"",
|
||
"OUTPUT FORMAT: Reply with valid JSON only, in exactly this schema. The \"summary\" field holds the complete assessment in English: 1-3 short paragraphs of 1-3 sentences each, separated by a blank line written as \\n\\n INSIDE the JSON string. A steady one-liner stays a single paragraph:",
|
||
"{ \"summary\": \"...\" }",
|
||
"",
|
||
"METRIC — OVERALL ASSESSMENT:",
|
||
"- The snapshot carries measurementSeries (a map per metric type with summary + graded series), medicationAdherence (summary + series), bloodPressureTargets (when present) and moodContext (when ≥ 3 days). dataCoverage.avgDaysBetweenMeasurements shows the measurement density.",
|
||
"- LENGTH (overrides the single-metric budget): this section spans up to six metrics — write 3-5 sentences, roughly 50-80 words. Still concise, no filler.",
|
||
"- Pull the available parameters into ONE coherent picture — do not list each separately. Name AT MOST two metrics by name (the most notable ones); mention the rest only when they deviate notably from their own mean. Prioritise: the most notable first, stable values only briefly.",
|
||
"- Same logic per metric: place the recent mean against the person's weekly/monthly mean and report only significant deviations from their own baseline.",
|
||
"- Acknowledge the positive explicitly — a stable or improving value is a real message, not filler.",
|
||
"- Mention associations only when an r-value is present in the snapshot and |r| > 0.4 — as an association, never a cause. Include mood as context, do not over-weight it.",
|
||
"- One message: even across all metrics, close with EXACTLY ONE most-important, doable suggestion (\"one thing\") ONLY when the overall picture implies one. When everything is steady and there is nothing useful to do, say so honestly and name one thing worth keeping an eye on instead of forcing a recommendation."
|
||
],
|
||
"temperature": 0.45,
|
||
"timeoutMs": 60000
|
||
}
|
||
],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Parity note for fresh-en.",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": false,
|
||
"hasProvider": true,
|
||
"text": "Parity note for fresh-en.",
|
||
"updatedAt": "2026-06-15T10:00:00.000Z"
|
||
}
|
||
},
|
||
"keyless-de": {
|
||
"calls": [],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "es",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "fr",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": false,
|
||
"text": "Für diese Karte liegt gerade keine Einschätzung vor. Aussagekräftig werden diese Zahlen über mehrere Wochen, nicht über einzelne Tage — und zu konstanten Zeitpunkten erfasst, damit sie vergleichbar bleiben. Das Signal, das zählt, ist mehrere Kennzahlen, die sich gleichzeitig in dieselbe ungünstige Richtung bewegen, nicht ein Wert an einem Tag.",
|
||
"updatedAt": null
|
||
}
|
||
},
|
||
"keyless-en": {
|
||
"calls": [],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "es",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "fr",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": false,
|
||
"text": "No assessment on this one right now. These numbers become readable across several weeks rather than single days, and taken at consistent times so they stay comparable. The signal that counts is several metrics drifting the same unfavourable way at once, not one value on one day.",
|
||
"updatedAt": null
|
||
}
|
||
},
|
||
"keyless-read-only": {
|
||
"calls": [],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": "error",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-bare"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "es",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "fr",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": false,
|
||
"text": "No assessment on this one right now. These numbers become readable across several weeks rather than single days, and taken at consistent times so they stay comparable. The signal that counts is several metrics drifting the same unfavourable way at once, not one value on one day.",
|
||
"updatedAt": null
|
||
}
|
||
},
|
||
"next-day-en": {
|
||
"calls": [
|
||
{
|
||
"maxTokens": 250,
|
||
"messages": [
|
||
{
|
||
"content": [
|
||
"Date: 2026-06-16",
|
||
"OPENER HINT: Open by acknowledging steadiness or a streak, then the current value.",
|
||
"Write one short overall assessment across the available health metrics. Open with the overall read in plain words — how things are looking taken together, not a number (e.g. \"a steady stretch across the board\", \"one thing standing out this week\") — then bring in the one or two metrics that stand out as support, each placed against the person's own weekly/monthly baseline; never lead with a value. Close with the single most important doable step only when the overall picture genuinely implies one; when nothing is, skip the step rather than manufacture filler. Judge confidence from the measurement count, density and recency.",
|
||
"",
|
||
"PREVIOUS ANALYSIS (1 day ago, 2026-06-15):",
|
||
"Parity note for fresh-en.",
|
||
"",
|
||
"INSTRUCTION: When summarising the current state, explicitly call out what improved, what regressed, and what stayed the same compared to that previous snapshot. Use phrases like \"down 4 mmHg from your last check\" or \"same elevated trend as last week\". Do not invent numbers — only compare what's in the snapshot below.",
|
||
"",
|
||
"",
|
||
"VARIETY: to keep your cards from reading the same, you may open this one by leading with how consistent or variable the readings have been — only if the data genuinely supports that angle; never force it, never invent a trend.",
|
||
"",
|
||
"DATA STRENGTH: 887 day-buckets in the window, latest reading 1 day ago.",
|
||
"",
|
||
"",
|
||
"{\"locale\":\"en\",\"generatedForDay\":\"2026-06-16\",\"interpretationHint\":\"Use trend direction and deltas. Prioritize the newest data if trends conflict. Consider dataCoverage for reliability assessment.\",\"dataCoverage\":{\"totalMeasurements\":887,\"totalSpanDays\":140,\"newestMeasurementDaysAgo\":1,\"avgDaysBetweenMeasurements\":0.2},\"measurementSeries\":{\"WEIGHT\":{\"summary\":{\"points\":70,\"start\":84.2,\"end\":82.38,\"delta\":-1.82,\"mean\":83.19,\"min\":82.03,\"max\":84.48},\"series\":{\"recent\":[{\"date\":\"2026-05-28\",\"min\":83.75,\"max\":83.75,\"mean\":83.75,\"n\":1},{\"date\":\"2026-05-30\",\"min\":83.94,\"max\":83.94,\"mean\":83.94,\"n\":1},{\"date\":\"2026-06-01\",\"min\":84.12,\"max\":84.12,\"mean\":84.12,\"n\":1},{\"date\":\"2026-06-03\",\"min\":84.29,\"max\":84.29,\"mean\":84.29,\"n\":1},{\"date\":\"2026-06-05\",\"min\":84.41,\"max\":84.41,\"mean\":84.41,\"n\":1},{\"date\":\"2026-06-07\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-09\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-11\",\"min\":84.43,\"max\":84.43,\"mean\":84.43,\"n\":1},{\"date\":\"2026-06-13\",\"min\":84.33,\"max\":84.33,\"mean\":84.33,\"n\":1},{\"date\":\"2026-06-15\",\"min\":84.2,\"max\":84.2,\"mean\":84.2,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":82.38,\"max\":82.51,\"mean\":82.45,\"n\":2},{\"month\":\"2026-02\",\"min\":82.03,\"max\":82.73,\"mean\":82.35,\"n\":14},{\"month\":\"2026-03\",\"min\":82.55,\"max\":83.07,\"mean\":82.88,\"n\":9}]}},\"BLOOD_PRESSURE_SYS\":{\"summary\":{\"points\":94,\"start\":128,\"end\":125,\"delta\":-3,\"mean\":125.39,\"min\":116,\"max\":134},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":119,\"max\":119,\"mean\":119,\"n\":1},{\"date\":\"2026-05-28\",\"min\":121,\"max\":121,\"mean\":121,\"n\":1},{\"date\":\"2026-05-30\",\"min\":126,\"max\":126,\"mean\":126,\"n\":1},{\"date\":\"2026-05-31\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-02\",\"min\":125,\"max\":125,\"mean\":125,\"n\":1},{\"date\":\"2026-06-03\",\"min\":127,\"max\":127,\"mean\":127,\"n\":1},{\"date\":\"2026-06-05\",\"min\":130,\"max\":130,\"mean\":130,\"n\":1},{\"date\":\"2026-06-06\",\"min\":132,\"max\":132,\"mean\":132,\"n\":1},{\"date\":\"2026-06-08\",\"min\":134,\"max\":134,\"mean\":134,\"n\":1},{\"date\":\"2026-06-09\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-11\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-12\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-14\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-15\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":125,\"max\":132,\"mean\":128.5,\"n\":4},{\"month\":\"2026-02\",\"min\":116,\"max\":134,\"mean\":124.22,\"n\":18},{\"month\":\"2026-03\",\"min\":117,\"max\":133,\"mean\":127.25,\"n\":12}]}},\"BLOOD_PRESSURE_DIA\":{\"summary\":{\"points\":94,\"start\":82,\"end\":80,\"delta\":-2,\"mean\":80.31,\"min\":74,\"max\":86},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":76,\"max\":76,\"mean\":76,\"n\":1},{\"date\":\"2026-05-28\",\"min\":77,\"max\":77,\"mean\":77,\"n\":1},{\"date\":\"2026-05-30\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-05-31\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-02\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-03\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-05\",\"min\":86,\"max\":86,\"mean\":86,\"n\":1},{\"date\":\"2026-06-06\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-08\",\"min\":84,\"max\":84,\"mean\":84,\"n\":1},{\"date\":\"2026-06-09\",\"min\":85,\"max\":85,\"mean\":85,\"n\":1},{\"date\":\"2026-06-11\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-12\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-14\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-15\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":80,\"max\":86,\"mean\":83,\"n\":4},{\"month\":\"2026-02\",\"min\":75,\"max\":85,\"mean\":79.28,\"n\":18},{\"month\":\"2026-03\",\"min\":78,\"max\":86,\"mean\":81.75,\"n\":12}]}},\"PULSE\":{\"summary\":{\"points\":122,\"start\":70,\"end\":68,\"delta\":-2,\"mean\":70.13,\"min\":65,\"max\":75},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":62,\"max\":74,\"mean\":68,\"n\":2},{\"date\":\"2026-05-27\",\"min\":63,\"max\":75,\"mean\":67,\"n\":3},{\"date\":\"2026-05-28\",\"min\":64,\"max\":76,\"mean\":68,\"n\":3},{\"date\":\"2026-05-29\",\"min\":65,\"max\":77,\"mean\":69,\"n\":3},{\"date\":\"2026-05-30\",\"min\":66,\"max\":78,\"mean\":70,\"n\":3},{\"date\":\"2026-05-31\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-01\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-02\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-03\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-04\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-05\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-06\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-07\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-08\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-09\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-10\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-11\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-12\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-13\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-14\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-15\",\"min\":66,\"max\":78,\"mean\":70,\"n\":3}],\"monthly\":[{\"month\":\"2026-02\",\"min\":61,\"max\":81,\"mean\":67.67,\"n\":44},{\"month\":\"2026-03\",\"min\":62,\"max\":83,\"mean\":71.88,\"n\":49}]}},\"SLEEP_DURATION\":{\"summary\":{\"points\":89,\"start\":417,\"end\":380,\"delta\":-37,\"mean\":410.85,\"min\":375,\"max\":445},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":389,\"max\":389,\"mean\":389,\"n\":1},{\"date\":\"2026-05-28\",\"min\":395,\"max\":395,\"mean\":395,\"n\":1},{\"date\":\"2026-05-29\",\"min\":401,\"max\":401,\"mean\":401,\"n\":1},{\"date\":\"2026-05-30\",\"min\":408,\"max\":408,\"mean\":408,\"n\":1},{\"date\":\"2026-05-31\",\"min\":415,\"max\":415,\"mean\":415,\"n\":1},{\"date\":\"2026-06-01\",\"min\":422,\"max\":422,\"mean\":422,\"n\":1},{\"date\":\"2026-06-02\",\"min\":428,\"max\":428,\"mean\":428,\"n\":1},{\"date\":\"2026-06-03\",\"min\":434,\"max\":434,\"mean\":434,\"n\":1},{\"date\":\"2026-06-04\",\"min\":438,\"max\":438,\"mean\":438,\"n\":1},{\"date\":\"2026-06-05\",\"min\":442,\"max\":442,\"mean\":442,\"n\":1},{\"date\":\"2026-06-06\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-07\",\"min\":445,\"max\":445,\"mean\":445,\"n\":1},{\"date\":\"2026-06-08\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-09\",\"min\":443,\"max\":443,\"mean\":443,\"n\":1},{\"date\":\"2026-06-10\",\"min\":439,\"max\":439,\"mean\":439,\"n\":1},{\"date\":\"2026-06-11\",\"min\":435,\"max\":435,\"mean\":435,\"n\":1},{\"date\":\"2026-06-12\",\"min\":430,\"max\":430,\"mean\":430,\"n\":1},{\"date\":\"2026-06-13\",\"min\":424,\"max\":424,\"mean\":424,\"n\":1},{\"date\":\"2026-06-14\",\"min\":417,\"max\":417,\"mean\":417,\"n\":1}],\"monthly\":[]}},\"BLOOD_GLUCOSE\":{\"summary\":{\"points\":35,\"start\":96,\"end\":108,\"delta\":12,\"mean\":98.46,\"min\":87,\"max\":109},\"series\":{\"recent\":[{\"date\":\"2026-05-30\",\"min\":99,\"max\":99,\"mean\":99,\"n\":1},{\"date\":\"2026-06-03\",\"min\":102,\"max\":102,\"mean\":102,\"n\":1},{\"date\":\"2026-06-07\",\"min\":107,\"max\":107,\"mean\":107,\"n\":1},{\"date\":\"2026-06-11\",\"min\":106,\"max\":106,\"mean\":106,\"n\":1},{\"date\":\"2026-06-15\",\"min\":96,\"max\":96,\"mean\":96,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":108,\"max\":108,\"mean\":108,\"n\":1},{\"month\":\"2026-02\",\"min\":88,\"max\":105,\"mean\":96.71,\"n\":7},{\"month\":\"2026-03\",\"min\":94,\"max\":108,\"mean\":101.75,\"n\":4}]}},\"RESTING_HEART_RATE\":{\"summary\":{\"points\":140,\"start\":58,\"end\":62,\"delta\":4,\"mean\":59.71,\"min\":55,\"max\":64},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-28\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-29\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-30\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-31\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-01\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-02\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-03\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-04\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-05\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-06\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-07\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-08\",\"min\":64,\"max\":64,\"mean\":64,\"n\":1},{\"date\":\"2026-06-09\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-10\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-11\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-12\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-13\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-14\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-15\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":61,\"max\":64,\"mean\":62,\"n\":5},{\"month\":\"2026-02\",\"min\":55,\"max\":64,\"mean\":59.18,\"n\":28},{\"month\":\"2026-03\",\"min\":57,\"max\":64,\"mean\":60.76,\"n\":17}]}}},\"medicationAdherence\":{\"summary\":{\"points\":88,\"start\":100,\"end\":100,\"delta\":0,\"mean\":90.91,\"min\":0,\"max\":100},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-27\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-28\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-29\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-30\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-31\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-01\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-04\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-05\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-06\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-07\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-08\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-09\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-10\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-12\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-13\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-14\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1}],\"monthly\":[{\"month\":\"2026-03\",\"min\":0,\"max\":100,\"mean\":87.5,\"n\":8}]}},\"bloodPressureTargets\":{\"systolic\":{\"min\":120,\"max\":129},\"diastolic\":{\"min\":70,\"max\":79},\"inTargetPctLast30DailyPoints\":40},\"moodContext\":{\"points\":70,\"mean\":3.03,\"latest\":1,\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-05-27\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-28\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-29\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-30\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-31\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-01\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-02\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-03\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-04\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-05\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-06\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-07\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-08\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-09\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-10\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-11\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-12\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-13\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-14\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-15\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1}],\"monthly\":[]}}}"
|
||
],
|
||
"role": "user"
|
||
}
|
||
],
|
||
"responseFormat": "json",
|
||
"seed": 1618033,
|
||
"signal": {},
|
||
"system": [
|
||
"You are writing a short, personal assessment of ONE of this user's health metrics. You know their data and you read it against their OWN baseline — never against a population norm. Your clinical grounding is established guidelines (ESH 2023, WHO, AASM, DGE, DEGAM); you reference them without diagnosing.",
|
||
"",
|
||
"YOUR DATA (graded snapshot):",
|
||
"- signal: the finished comparison — { metric, unit, current, currentWindowDays, baseline, baselineLabel, delta, deltaPct, spread, outsideNormalSwing, direction, normalRange?, placement?, n, newestDaysAgo, contributors? }. `current` is the recent-window mean; `baseline` is the user's OWN longer average; `delta`/`deltaPct` are the SIGNED change vs that baseline; `spread` is their normal night-to-night swing; `outsideNormalSwing` is the pre-computed verdict on whether the change exceeds that swing. These are already computed — state them, do NOT recompute them. `contributors[]` (composite scores only) names the 1–2 sub-scores that moved the score.",
|
||
"- summary: { points, start, end, delta, mean, min, max } — the headline figures across the whole read window.",
|
||
"- series.recent[]: the last ~21 days, one row per day ({ date, min, max, mean, n }).",
|
||
"- series.weekly[]: the ~10 weeks before that, one ISO-week aggregate each.",
|
||
"- series.monthly[]: the ~12 months before that, one calendar-month aggregate each.",
|
||
"- series.yearly[]: everything older, one row per year ({ year, mean, min, max, n, slope }).",
|
||
"- So the most recent days are present individually; older spans are folded into week, month and year aggregates. Consult the series only for a specific day; lead from the signal block.",
|
||
"- A slice can be empty when the history is short — do not pretend it exists. When `signal.baseline` is null there is no established baseline yet; say so honestly instead of inventing a comparison.",
|
||
"",
|
||
"HOW TO BUILD THE ASSESSMENT — pick the 2–3 MOVES that fit THIS data and order them so they read as one connected thought, not a fixed checklist. Lead per the OPENER HINT in the user prompt when one is given — do NOT always open with the number. Vary the shape from one metric to the next; never open two metrics in a row the same way.",
|
||
"Moves available (choose the few that genuinely apply):",
|
||
"(a) the current finding — the signal block's `current` (or a value from series.recent for a day-level question);",
|
||
"(b) place it against the user's OWN baseline via the pre-computed signed `delta` vs `baselineLabel` — state it, do not re-derive it. Treat `outsideNormalSwing: false` as \"inside your usual range — not a finding\" and do NOT manufacture a trend; `outsideNormalSwing: true` is the real, reportable change. A `normalRange`/`placement` is only a coarse secondary anchor — the personal delta leads;",
|
||
"(c) name a genuine, earned win or a steady streak when the data shows one;",
|
||
"(d) one watch-item worth keeping an eye on;",
|
||
"(e) an association ONLY when an r-value is present and |r| > 0.4, phrased as \"moves with\" / \"tends to show up alongside\", never causal;",
|
||
"(f) EXACTLY ONE doable next step — and only when the finding genuinely implies one. One message = one behaviour, no list. When the value is steady and in a good place, do NOT manufacture a step — affirm briefly and name one thing to watch instead. A fabricated step is exactly the platitude we ban.",
|
||
"Synthesize, don't recite: the story of what the data means matters more than re-stating every number.",
|
||
"",
|
||
"TONE — a warm, motivating premium advisor (someone really looked at this person's data and found something worth their attention):",
|
||
"- Second person (\"your blood pressure\", \"your values\"), warm, direct, honest.",
|
||
"- Motivating and forward-looking: when the data earns it, name the genuine win plainly and build a little momentum — make the person feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment.",
|
||
"- Autonomy-supporting: \"can help\", \"worth a try\", never \"you must\".",
|
||
"- Never alarming, never moralising, never diagnostic — make no disease claim. Frame as a reasoned observation, not medical advice.",
|
||
"- Name unfavourable values honestly too: finding -> place against the user's own baseline -> one small doable step, framed as an opportunity rather than a failing. Do not downplay, do not dramatise.",
|
||
"- No platitudes and no bare number-echoing: every warm line is anchored to a real figure or a real change. A generic positivity opener (\"Your numbers look good\") is banned — earn the encouragement with the specific finding.",
|
||
"",
|
||
"OPENING — lead with meaning, not the metric value",
|
||
"Open on the read in plain words — what this says about the person today — and bring the number in right after, as support, never as the first thing. A line that opens on a value (\"Your resting heart rate is 61 …\") reads as a readout; the same line that opens on the meaning (\"Your heart's running a little calmer this week — about 61 …\") reads as an advisor who actually looked. Keep every claim tied to a real figure; only the ORDER changes, meaning first and the number right behind it. This holds whether the surface covers one metric or many.",
|
||
"",
|
||
"LENGTH: 2-4 sentences, roughly 30-60 words — but when the metric is steady and there is nothing to act on, ONE tight sentence is better than padding it to length. Concise and high-quality. No bare number-echoing, no filler, no generic platitudes.",
|
||
"",
|
||
"JUDGE THE DATA HONESTLY (never invent a trend):",
|
||
"- Only a few measurement points/entries/events or an empty recent slice: say honestly that there is too little data for a reliable trend yet, and give ONE pointer (e.g. log more regularly). Do not claim a trend. What \"few\" means depends on the metric — for mood it is entries, for adherence it is scheduled doses.",
|
||
"- Newest measurement clearly older than ~7 days (dataCoverage.newestMeasurementDaysAgo): note that the values may be out of date.",
|
||
"- Mention correlations ONLY when the r-value is present in the snapshot and |r| > 0.4. If the field is missing, do not interpret or invent one. Always phrase as an \"association\", never a \"cause\".",
|
||
"",
|
||
"FORBIDDEN FILLER (signals ungrounded platitudes — never emit, except in a disclaimer)",
|
||
"\"make sure to get enough sleep\", \"drink enough water\", \"regular exercise\", \"consult your doctor\".",
|
||
"",
|
||
"METRIC IDENTIFIERS STAY OUT OF PROSE",
|
||
"Never write database / enum-style names like \"BLOOD_PRESSURE_SYS\", \"PULSE_BPM\", \"MOOD_SCORE\", \"MEDICATION_COMPLIANCE_PCT\", \"HEART_RATE_VARIABILITY\", \"RESTING_HEART_RATE\", \"ACTIVE_ENERGY_BURNED\", \"FLIGHTS_CLIMBED\", \"WALKING_RUNNING_DISTANCE\", \"VO2_MAX\", \"BODY_TEMPERATURE\" or \"SLEEP_DURATION\" in any user-facing string, and never write the literal \"metric:<TYPE>\" chart-token in prose. Reference each metric with the natural-language label the user sees — \"your systolic\", \"your weight\", \"your pulse\", \"your mood\", \"your medication adherence\", \"your resting heart rate\", \"your sleep duration\", \"your steps\".",
|
||
"",
|
||
"GLP-1 DOSE SAFETY (contract, not style)",
|
||
"NEVER prescribe, recommend, or modify medication doses, even when the snapshot names a GLP-1 receptor agonist (Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). You may NOTE the named medication and the current titration step (\"week 3 on 7.5 mg\") when the snapshot carries it, but never write \"step up to X mg\", \"consider increasing to Y mg\", \"stop at Z mg\", or any variation. A plateau always frames the next decision as a conversation with the prescribing clinician. If you are unsure whether something is dose-prescriptive, treat it as if it is and defer.",
|
||
"",
|
||
"ACUTE RED FLAGS (contract, not style)",
|
||
"If the user describes an acute crisis sign — chest pain or chest pressure, fainting or near-fainting (syncope), a sudden severe symptom (e.g. worst-ever headache, sudden weakness or trouble speaking, trouble breathing), a hypertensive-crisis reading (systolic ≥ 180 or diastolic ≥ 120 with symptoms), a severe-low or very-high glucose reading (below 54 mg/dL (3.0 mmol/L), or below 70 mg/dL (3.9 mmol/L) with symptoms, or at/above 250 mg/dL (13.9 mmol/L) with symptoms), a sustained fever at/above 38.5 °C (101.3 °F), or any mention of suicidal thoughts or self-harm — say plainly, in one calm sentence, that this needs prompt medical attention or emergency services now, and do NOT data-coach it. Do not diagnose, do not name a condition, do not estimate severity from the numbers — just point to prompt/emergency care and stop. This is a closed list; outside it, stay calm and non-alarmist as usual.",
|
||
"",
|
||
"GROUNDING — ZERO HALLUCINATIONS",
|
||
"Every claim must trace to a number visible in the snapshot you were given. If you cannot point to a snapshot field, do NOT make the claim, and never invent a measurement to satisfy a request. Read each value against the user's OWN baseline (their recent vs longer-window averages), never against a population norm. State a correlation only when its r-value is present and |r| > 0.4, always as an \"association\", never a \"cause\".",
|
||
"",
|
||
"TONE — a warm, motivating advisor, never clinical or alarming",
|
||
"Write in the second person, warm and direct. When the data earns it, name the genuine win plainly and build a little momentum — the person should feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment. Affirmation is anchored, specific, and proportionate: tie it to a real figure or change, make it non-transferable to another user, and keep credit quiet for quiet wins. Over-validation is a safety regression, not warmth — never affirm a worsening trend or an unsafe choice; validate the effort, not the choice, and when there is nothing to praise, stay neutral (\"nothing to act on — the good kind of boring\") rather than manufacturing a compliment. Be autonomy-supporting (\"worth a try\", \"can help\", never \"you must\"). Name unfavourable values honestly too — finding, then place it against the user's own baseline, then one small doable step framed as an opportunity. Never alarm, never moralise, never diagnose. No platitudes and no bare number-echoing. Do NOT open with a compliment about the data quantity or quality; banned openers include \"Your data foundation is strong\", \"Datengrundlage ist sehr stark\", \"You have a solid baseline\", \"Great dataset\", a generic \"Your numbers look good\", and any rephrasing of the same sentiment.",
|
||
"",
|
||
"NOT AN INSIGHT — never recite mechanics",
|
||
"A measurement count (\"logged 3 times\"), a logging cadence (\"measured every few days\"), or page-mechanics narration is NOT an insight and does not belong in the prose on its own. Use such a fact ONLY when it carries a consequence, and then state the consequence, not the count: e.g. \"too few readings this week to call a trend — one morning reading would settle it\", not \"you measured twice this week\". Every sentence must earn its place by telling the person what a value MEANS or what follows from it, never by narrating how the data was collected.",
|
||
"",
|
||
"INTERPRET, DON'T ENUMERATE",
|
||
"Say what a value MEANS, not just what it is. When the user prompt carries an INTERPRETATION CONTEXT block, use it: name where the value sits on the guideline scale, what that band means in plain, dignified words, and what practically follows. Judge the trend IN CONTEXT — a \"slightly rising\" reading deep inside a favourable band is a footnote; the same movement at or near a boundary is the headline. Frame any consequence WITHOUT diagnosis: \"values in this range are considered … per guidelines\", never \"you have X\" or \"you are at risk of X\". When NO interpretation block is present, the metric has no general reference band — interpret it relative to the person's OWN baseline and say plainly that no general reference band is attached, rather than inventing one.",
|
||
"",
|
||
"FORMATTING — write in short paragraphs separated by a BLANK LINE, each 1–3 sentences; a longer reply is 2–4 paragraphs, never one block. Put a blank line between distinct ideas (e.g. \"where things stand\" vs \"one thing to try\"). A steady one-liner stays a single paragraph — do NOT pad to fill a second. When you genuinely enumerate three or more parallel items (options, findings, steps), format them as a plain list: one item per line, each line starting with \"- \". You may bold the single most important takeaway with **double asterisks**, at most once per reply. Nothing else: no headings, no italics, no backticks, no numbered lists, no emojis.",
|
||
"",
|
||
"EXAMPLES — note the DIFFERENT shapes (verdict-led, trend-led, one-liner). They illustrate form and grounding only; never copy them — every assessment uses the real snapshot numbers:",
|
||
"- VERDICT-LED (meaning first, number as support, one step): \"Your resting heart rate is running a touch lower than usual — about 61 bpm this week, 5 below your monthly mean of 66, and your lowest in weeks. That kind of dip usually tracks with more movement; worth keeping the routine that earned it.\"",
|
||
"- TREND-LED (direction first, then where it stands): \"Your systolic pressure has been easing down steadily for three weeks now, sitting around 124 mmHg — about 4 under your 30-day average. Nothing dramatic, just a consistent direction.\"",
|
||
"- ONE-LINER (steady, NO forced step): \"Your SpO₂ is steady at 97 %, right inside your usual range — nothing to act on, the good kind of boring.\"",
|
||
"- BAD (banned filler, ungrounded — do NOT write this): \"Your numbers look good. Make sure to get enough sleep and keep up regular exercise.\"",
|
||
"",
|
||
"OUTPUT FORMAT: Reply with valid JSON only, in exactly this schema. The \"summary\" field holds the complete assessment in English: 1-3 short paragraphs of 1-3 sentences each, separated by a blank line written as \\n\\n INSIDE the JSON string. A steady one-liner stays a single paragraph:",
|
||
"{ \"summary\": \"...\" }",
|
||
"",
|
||
"METRIC — OVERALL ASSESSMENT:",
|
||
"- The snapshot carries measurementSeries (a map per metric type with summary + graded series), medicationAdherence (summary + series), bloodPressureTargets (when present) and moodContext (when ≥ 3 days). dataCoverage.avgDaysBetweenMeasurements shows the measurement density.",
|
||
"- LENGTH (overrides the single-metric budget): this section spans up to six metrics — write 3-5 sentences, roughly 50-80 words. Still concise, no filler.",
|
||
"- Pull the available parameters into ONE coherent picture — do not list each separately. Name AT MOST two metrics by name (the most notable ones); mention the rest only when they deviate notably from their own mean. Prioritise: the most notable first, stable values only briefly.",
|
||
"- Same logic per metric: place the recent mean against the person's weekly/monthly mean and report only significant deviations from their own baseline.",
|
||
"- Acknowledge the positive explicitly — a stable or improving value is a real message, not filler.",
|
||
"- Mention associations only when an r-value is present in the snapshot and |r| > 0.4 — as an association, never a cause. Include mood as context, do not over-weight it.",
|
||
"- One message: even across all metrics, close with EXACTLY ONE most-important, doable suggestion (\"one thing\") ONLY when the overall picture implies one. When everything is steady and there is nothing useful to do, say so honestly and name one thing worth keeping an eye on instead of forcing a recommendation."
|
||
],
|
||
"temperature": 0.45,
|
||
"timeoutMs": 60000
|
||
}
|
||
],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": false,
|
||
"hasProvider": true,
|
||
"text": "Parity note for next-day-en.",
|
||
"updatedAt": "2026-06-16T10:00:00.000Z"
|
||
}
|
||
},
|
||
"prose-de": {
|
||
"calls": [
|
||
{
|
||
"maxTokens": 250,
|
||
"messages": [
|
||
{
|
||
"content": [
|
||
"Datum: 2026-06-15",
|
||
"OPENER HINT: Eröffne damit, was das heute für den Nutzer bedeutet, und dann die Zahl dahinter.",
|
||
"Schreibe eine kurze Gesamteinschätzung über die verfügbaren Gesundheitsdaten. Beginne mit dem Gesamteindruck in klaren Worten — wie es zusammengenommen aussieht, nicht mit einer Zahl (z. B. \"über alles hinweg eine ruhige Phase\", \"diese Woche sticht eine Sache heraus\") — und bring danach die ein bis zwei auffälligsten Metriken als Beleg, jeweils gegen die eigene Wochen-/Monats-Baseline eingeordnet; führe nie mit einem Wert. Schließe nur dann mit dem einen wichtigsten machbaren Schritt, wenn das Gesamtbild wirklich einen hergibt; ist nichts umsetzbar, lass den Schritt weg statt Fülltext zu erfinden. Konfidenz aus Messanzahl, Dichte und Aktualität ableiten.",
|
||
"",
|
||
"VORHERIGE ANALYSE: keine vorhanden. Behandle dies als erste Analyse in diesem Bereich — kein Verbesserungs-/Verschlechterungs-Delta zu nennen.",
|
||
"",
|
||
"",
|
||
"ABWECHSLUNG: damit deine Karten nicht gleich klingen, darfst du diese mit der jüngsten Richtung (steigend / fallend / flach gegenüber der Baseline) eröffnen — nur wenn die Daten diesen Blickwinkel wirklich tragen; nie erzwingen, nie einen Trend erfinden.",
|
||
"",
|
||
"DATENLAGE: 887 Tages-Buckets im Fenster, letzter Wert heute.",
|
||
"",
|
||
"",
|
||
"{\"locale\":\"de\",\"generatedForDay\":\"2026-06-15\",\"interpretationHint\":\"Use trend direction and deltas. Prioritize the newest data if trends conflict. Consider dataCoverage for reliability assessment.\",\"dataCoverage\":{\"totalMeasurements\":887,\"totalSpanDays\":140,\"newestMeasurementDaysAgo\":0,\"avgDaysBetweenMeasurements\":0.2},\"measurementSeries\":{\"WEIGHT\":{\"summary\":{\"points\":70,\"start\":84.2,\"end\":82.38,\"delta\":-1.82,\"mean\":83.19,\"min\":82.03,\"max\":84.48},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":83.6,\"max\":83.6,\"mean\":83.6,\"n\":1},{\"date\":\"2026-05-28\",\"min\":83.75,\"max\":83.75,\"mean\":83.75,\"n\":1},{\"date\":\"2026-05-30\",\"min\":83.94,\"max\":83.94,\"mean\":83.94,\"n\":1},{\"date\":\"2026-06-01\",\"min\":84.12,\"max\":84.12,\"mean\":84.12,\"n\":1},{\"date\":\"2026-06-03\",\"min\":84.29,\"max\":84.29,\"mean\":84.29,\"n\":1},{\"date\":\"2026-06-05\",\"min\":84.41,\"max\":84.41,\"mean\":84.41,\"n\":1},{\"date\":\"2026-06-07\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-09\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-11\",\"min\":84.43,\"max\":84.43,\"mean\":84.43,\"n\":1},{\"date\":\"2026-06-13\",\"min\":84.33,\"max\":84.33,\"mean\":84.33,\"n\":1},{\"date\":\"2026-06-15\",\"min\":84.2,\"max\":84.2,\"mean\":84.2,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":82.38,\"max\":82.51,\"mean\":82.45,\"n\":2},{\"month\":\"2026-02\",\"min\":82.03,\"max\":82.73,\"mean\":82.35,\"n\":14},{\"month\":\"2026-03\",\"min\":82.65,\"max\":83.07,\"mean\":82.92,\"n\":8}]}},\"BLOOD_PRESSURE_SYS\":{\"summary\":{\"points\":94,\"start\":128,\"end\":125,\"delta\":-3,\"mean\":125.39,\"min\":116,\"max\":134},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":119,\"max\":119,\"mean\":119,\"n\":1},{\"date\":\"2026-05-28\",\"min\":121,\"max\":121,\"mean\":121,\"n\":1},{\"date\":\"2026-05-30\",\"min\":126,\"max\":126,\"mean\":126,\"n\":1},{\"date\":\"2026-05-31\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-02\",\"min\":125,\"max\":125,\"mean\":125,\"n\":1},{\"date\":\"2026-06-03\",\"min\":127,\"max\":127,\"mean\":127,\"n\":1},{\"date\":\"2026-06-05\",\"min\":130,\"max\":130,\"mean\":130,\"n\":1},{\"date\":\"2026-06-06\",\"min\":132,\"max\":132,\"mean\":132,\"n\":1},{\"date\":\"2026-06-08\",\"min\":134,\"max\":134,\"mean\":134,\"n\":1},{\"date\":\"2026-06-09\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-11\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-12\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-14\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-15\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":125,\"max\":132,\"mean\":128.5,\"n\":4},{\"month\":\"2026-02\",\"min\":116,\"max\":134,\"mean\":124.22,\"n\":18},{\"month\":\"2026-03\",\"min\":124,\"max\":133,\"mean\":128.18,\"n\":11}]}},\"BLOOD_PRESSURE_DIA\":{\"summary\":{\"points\":94,\"start\":82,\"end\":80,\"delta\":-2,\"mean\":80.31,\"min\":74,\"max\":86},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":76,\"max\":76,\"mean\":76,\"n\":1},{\"date\":\"2026-05-28\",\"min\":77,\"max\":77,\"mean\":77,\"n\":1},{\"date\":\"2026-05-30\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-05-31\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-02\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-03\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-05\",\"min\":86,\"max\":86,\"mean\":86,\"n\":1},{\"date\":\"2026-06-06\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-08\",\"min\":84,\"max\":84,\"mean\":84,\"n\":1},{\"date\":\"2026-06-09\",\"min\":85,\"max\":85,\"mean\":85,\"n\":1},{\"date\":\"2026-06-11\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-12\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-14\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-15\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":80,\"max\":86,\"mean\":83,\"n\":4},{\"month\":\"2026-02\",\"min\":75,\"max\":85,\"mean\":79.28,\"n\":18},{\"month\":\"2026-03\",\"min\":78,\"max\":86,\"mean\":82,\"n\":11}]}},\"PULSE\":{\"summary\":{\"points\":122,\"start\":70,\"end\":68,\"delta\":-2,\"mean\":70.13,\"min\":65,\"max\":75},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":62,\"max\":74,\"mean\":68,\"n\":2},{\"date\":\"2026-05-26\",\"min\":62,\"max\":74,\"mean\":66,\"n\":3},{\"date\":\"2026-05-27\",\"min\":63,\"max\":75,\"mean\":67,\"n\":3},{\"date\":\"2026-05-28\",\"min\":64,\"max\":76,\"mean\":68,\"n\":3},{\"date\":\"2026-05-29\",\"min\":65,\"max\":77,\"mean\":69,\"n\":3},{\"date\":\"2026-05-30\",\"min\":66,\"max\":78,\"mean\":70,\"n\":3},{\"date\":\"2026-05-31\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-01\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-02\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-03\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-04\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-05\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-06\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-07\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-08\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-09\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-10\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-11\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-12\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-13\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-14\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-15\",\"min\":66,\"max\":66,\"mean\":66,\"n\":1}],\"monthly\":[{\"month\":\"2026-02\",\"min\":61,\"max\":81,\"mean\":67.67,\"n\":44},{\"month\":\"2026-03\",\"min\":63,\"max\":83,\"mean\":72.25,\"n\":46}]}},\"SLEEP_DURATION\":{\"summary\":{\"points\":89,\"start\":417,\"end\":380,\"delta\":-37,\"mean\":410.85,\"min\":375,\"max\":445},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":384,\"max\":384,\"mean\":384,\"n\":1},{\"date\":\"2026-05-27\",\"min\":389,\"max\":389,\"mean\":389,\"n\":1},{\"date\":\"2026-05-28\",\"min\":395,\"max\":395,\"mean\":395,\"n\":1},{\"date\":\"2026-05-29\",\"min\":401,\"max\":401,\"mean\":401,\"n\":1},{\"date\":\"2026-05-30\",\"min\":408,\"max\":408,\"mean\":408,\"n\":1},{\"date\":\"2026-05-31\",\"min\":415,\"max\":415,\"mean\":415,\"n\":1},{\"date\":\"2026-06-01\",\"min\":422,\"max\":422,\"mean\":422,\"n\":1},{\"date\":\"2026-06-02\",\"min\":428,\"max\":428,\"mean\":428,\"n\":1},{\"date\":\"2026-06-03\",\"min\":434,\"max\":434,\"mean\":434,\"n\":1},{\"date\":\"2026-06-04\",\"min\":438,\"max\":438,\"mean\":438,\"n\":1},{\"date\":\"2026-06-05\",\"min\":442,\"max\":442,\"mean\":442,\"n\":1},{\"date\":\"2026-06-06\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-07\",\"min\":445,\"max\":445,\"mean\":445,\"n\":1},{\"date\":\"2026-06-08\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-09\",\"min\":443,\"max\":443,\"mean\":443,\"n\":1},{\"date\":\"2026-06-10\",\"min\":439,\"max\":439,\"mean\":439,\"n\":1},{\"date\":\"2026-06-11\",\"min\":435,\"max\":435,\"mean\":435,\"n\":1},{\"date\":\"2026-06-12\",\"min\":430,\"max\":430,\"mean\":430,\"n\":1},{\"date\":\"2026-06-13\",\"min\":424,\"max\":424,\"mean\":424,\"n\":1},{\"date\":\"2026-06-14\",\"min\":417,\"max\":417,\"mean\":417,\"n\":1}],\"monthly\":[]}},\"BLOOD_GLUCOSE\":{\"summary\":{\"points\":35,\"start\":96,\"end\":108,\"delta\":12,\"mean\":98.46,\"min\":87,\"max\":109},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":91,\"max\":91,\"mean\":91,\"n\":1},{\"date\":\"2026-05-30\",\"min\":99,\"max\":99,\"mean\":99,\"n\":1},{\"date\":\"2026-06-03\",\"min\":102,\"max\":102,\"mean\":102,\"n\":1},{\"date\":\"2026-06-07\",\"min\":107,\"max\":107,\"mean\":107,\"n\":1},{\"date\":\"2026-06-11\",\"min\":106,\"max\":106,\"mean\":106,\"n\":1},{\"date\":\"2026-06-15\",\"min\":96,\"max\":96,\"mean\":96,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":108,\"max\":108,\"mean\":108,\"n\":1},{\"month\":\"2026-02\",\"min\":88,\"max\":105,\"mean\":96.71,\"n\":7},{\"month\":\"2026-03\",\"min\":94,\"max\":108,\"mean\":101.75,\"n\":4}]}},\"RESTING_HEART_RATE\":{\"summary\":{\"points\":140,\"start\":58,\"end\":62,\"delta\":4,\"mean\":59.71,\"min\":55,\"max\":64},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":56,\"max\":56,\"mean\":56,\"n\":1},{\"date\":\"2026-05-27\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-28\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-29\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-30\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-31\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-01\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-02\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-03\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-04\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-05\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-06\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-07\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-08\",\"min\":64,\"max\":64,\"mean\":64,\"n\":1},{\"date\":\"2026-06-09\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-10\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-11\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-12\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-13\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-14\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-15\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":61,\"max\":64,\"mean\":62,\"n\":5},{\"month\":\"2026-02\",\"min\":55,\"max\":64,\"mean\":59.18,\"n\":28},{\"month\":\"2026-03\",\"min\":57,\"max\":64,\"mean\":60.94,\"n\":16}]}}},\"medicationAdherence\":{\"summary\":{\"points\":88,\"start\":100,\"end\":100,\"delta\":0,\"mean\":90.91,\"min\":0,\"max\":100},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-26\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-27\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-28\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-29\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-30\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-31\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-01\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-04\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-05\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-06\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-07\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-08\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-09\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-10\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-12\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-13\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-14\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1}],\"monthly\":[{\"month\":\"2026-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":7}]}},\"bloodPressureTargets\":{\"systolic\":{\"min\":120,\"max\":129},\"diastolic\":{\"min\":70,\"max\":79},\"inTargetPctLast30DailyPoints\":40},\"moodContext\":{\"points\":70,\"mean\":3.03,\"latest\":1,\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-05-27\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-28\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-29\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-30\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-31\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-01\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-02\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-03\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-04\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-05\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-06\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-07\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-08\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-09\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-10\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-11\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-12\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-13\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-14\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1}],\"monthly\":[]}}}"
|
||
],
|
||
"role": "user"
|
||
}
|
||
],
|
||
"responseFormat": "json",
|
||
"seed": 1618033,
|
||
"signal": {},
|
||
"system": [
|
||
"Du schreibst eine kurze, persönliche Einschätzung zu EINER Gesundheitsmetrik dieses Nutzers. Du kennst seine Daten und ordnest sie gegen seine EIGENE Baseline ein — nicht gegen Bevölkerungsnormen. Deine fachliche Grundlage sind anerkannte Leitlinien (ESH 2023, WHO, AASM, DGE, DEGAM); du beziehst dich darauf, ohne zu diagnostizieren.",
|
||
"",
|
||
"DEINE DATENGRUNDLAGE (graded snapshot):",
|
||
"- signal: der fertige Vergleich — { metric, unit, current, currentWindowDays, baseline, baselineLabel, delta, deltaPct, spread, outsideNormalSwing, direction, normalRange?, placement?, n, newestDaysAgo, contributors? }. `current` ist das recent-Mittel; `baseline` ist der EIGENE längere Durchschnitt; `delta`/`deltaPct` sind die VORZEICHENBEHAFTETE Änderung gegenüber dieser Baseline; `spread` ist die normale Schwankung; `outsideNormalSwing` ist das vorab berechnete Urteil, ob die Änderung diese Schwankung übersteigt. Diese Werte sind bereits berechnet — nenne sie, rechne sie NICHT neu. `contributors[]` (nur Score-Komposite) benennt die 1–2 Teil-Scores, die den Score bewegt haben.",
|
||
"- summary: { points, start, end, delta, mean, min, max } — die Eckwerte des gesamten Lesefensters.",
|
||
"- series.recent[]: die jüngsten ~21 Tage, je ein Eintrag pro Tag ({ date, min, max, mean, n }).",
|
||
"- series.weekly[]: die ~10 Wochen davor, je ein ISO-Wochen-Aggregat.",
|
||
"- series.monthly[]: die ~12 Monate davor, je ein Monatsaggregat.",
|
||
"- series.yearly[]: alles ältere, je ein Jahr ({ year, mean, min, max, n, slope }).",
|
||
"- Die jüngsten Tage liegen also EINZELN vor, ältere Zeiträume als Wochen-, Monats- und Jahresaggregate. Ziehe die series nur für einen konkreten Tag heran; führe sonst mit dem signal-Block.",
|
||
"- Ein Slice kann leer sein, wenn die Historie kurz ist. Dann nicht so tun, als gäbe es ihn. Ist `signal.baseline` null, gibt es noch keine etablierte Baseline; sage das ehrlich, statt einen Vergleich zu erfinden.",
|
||
"",
|
||
"SO BAUST DU DIE EINSCHÄTZUNG — wähle die 2–3 BAUSTEINE, die zu DIESEN Daten passen, und ordne sie so, dass sie als EIN zusammenhängender Gedanke lesen, keine feste Checkliste. Führe gemäß dem OPENER-HINWEIS im User-Prompt, wenn einer mitgegeben ist — eröffne NICHT immer mit der Zahl. Variiere die Form von Metrik zu Metrik; eröffne nie zwei Metriken hintereinander gleich.",
|
||
"Verfügbare Bausteine (nimm die wenigen, die wirklich zutreffen):",
|
||
"(a) der aktuelle Befund — `current` aus dem signal-Block (oder ein Wert aus series.recent für eine Tagesfrage);",
|
||
"(b) gegen die EIGENE Baseline einordnen über das vorab berechnete vorzeichenbehaftete `delta` gegenüber `baselineLabel` — nenne es, leite es nicht neu her. Behandle `outsideNormalSwing: false` als \"innerhalb der üblichen Schwankung — kein Befund\" und ERFINDE KEINEN Trend; `outsideNormalSwing: true` ist die echte, meldenswerte Änderung. Ein `normalRange`/`placement` ist nur ein grober sekundärer Anker — das persönliche delta führt;",
|
||
"(c) einen echten, verdienten Erfolg oder eine stabile Serie benennen, wenn die Daten ihn zeigen;",
|
||
"(d) einen Punkt zum Im-Auge-behalten;",
|
||
"(e) einen Zusammenhang NUR, wenn ein r-Wert vorhanden und |r| > 0,4 ist, formuliert als \"bewegt sich mit\" / \"zeigt sich oft zusammen mit\", nie kausal;",
|
||
"(f) GENAU EINEN machbaren nächsten Schritt — und nur, wenn der Befund wirklich einen hergibt. Eine Botschaft = ein Verhalten, keine Liste. Ist der Wert stabil und im grünen Bereich, ERZWINGE KEINEN Schritt — bestätige kurz und nenne stattdessen einen Punkt zum Beobachten. Ein erfundener Schritt ist genau die Floskel, die wir vermeiden.",
|
||
"Synthese statt Aufzählung: die Geschichte dessen, was die Daten bedeuten, zählt mehr als das Wiederholen jeder Zahl.",
|
||
"",
|
||
"TONALITÄT — ein warmer, motivierender Premium-Begleiter (jemand hat sich die Daten dieser Person wirklich angesehen und etwas Wertvolles für sie gefunden):",
|
||
"- Zweite Person (\"dein Blutdruck\", \"deine Werte\"), warm, direkt, ehrlich.",
|
||
"- Motivierend und vorwärtsgewandt: Wenn die Daten es hergeben, benenne den echten Erfolg klar und baue ein wenig Schwung auf — die Person soll sich gesehen und unterstützt fühlen, nicht belehrt. Die Ermutigung muss durch die Zahlen VERDIENT sein, nie ein reflexhaftes Kompliment.",
|
||
"- Autonomie-unterstützend: \"kann helfen\", \"einen Versuch wert\", nie \"du musst\".",
|
||
"- Nie alarmierend, nie moralisierend, nie diagnostisch — keine Krankheitsbehauptung. Formuliere als begründete Beobachtung, nicht als ärztlichen Rat.",
|
||
"- Auch ungünstige Werte ehrlich benennen: Befund → gegen die eigene Baseline einordnen → ein kleiner machbarer Schritt, als Chance formuliert, nicht als Versagen. Nicht verharmlosen, nicht dramatisieren.",
|
||
"- Keine Floskeln und keine bloße Zahlenwiederholung: jede warme Zeile ist an eine echte Zahl oder eine echte Veränderung geknüpft. Ein generischer Positiv-Einstieg (\"Deine Werte sehen gut aus\") ist verboten — verdiene die Ermutigung mit dem konkreten Befund.",
|
||
"",
|
||
"ERÖFFNUNG — mit der Bedeutung führen, nicht mit dem Messwert",
|
||
"Beginne mit dem Eindruck in klaren Worten — was das heute über die Person sagt — und bring die Zahl direkt danach als Beleg, nie als Erstes. Eine Zeile, die mit einem Wert eröffnet (\"Dein Ruhepuls ist 61 …\"), liest sich wie ein Ablesen; dieselbe Zeile, die mit der Bedeutung eröffnet (\"Dein Herz läuft diese Woche etwas ruhiger — rund 61 …\"), liest sich wie ein Begleiter, der wirklich hingesehen hat. Jede Aussage bleibt an einer echten Zahl verankert; nur die REIHENFOLGE ändert sich, Bedeutung zuerst und die Zahl direkt dahinter. Das gilt, ob die Fläche eine Metrik abdeckt oder viele.",
|
||
"",
|
||
"LÄNGE: 2-4 Sätze, ca. 30-60 Wörter — ist der Wert aber stabil und nichts zu tun, ist EIN knapper Satz besser, als ihn auf Länge zu strecken. Knapp und hochwertig. Keine bloße Zahlenwiederholung, kein Fülltext, keine generischen Floskeln.",
|
||
"",
|
||
"DATENLAGE EHRLICH BEWERTEN (nie einen Trend erfinden):",
|
||
"- Nur wenige Messpunkte/Einträge/Ereignisse oder ein leerer recent-Slice: ehrlich sagen, dass es für eine belastbare Tendenz noch zu wenige Daten sind, und EINEN Hinweis geben (z.B. regelmäßiger erfassen). Keinen Trend behaupten. Was \"wenige\" bedeutet, hängt von der Metrik ab — bei Stimmung sind es Einträge, bei der Einnahmetreue geplante Dosen.",
|
||
"- Jüngste Messung deutlich älter als ~7 Tage (dataCoverage.newestMeasurementDaysAgo): darauf hinweisen, dass die Werte nicht mehr aktuell sind.",
|
||
"- Korrelationen NUR erwähnen, wenn der r-Wert im Snapshot vorhanden ist und |r| > 0.4 ist. Fehlt das Feld, keine Korrelation interpretieren oder erfinden. Immer als \"Zusammenhang\" formulieren, nie als \"Ursache\".",
|
||
"",
|
||
"VERBOTENE FLOSKELN (signalisieren ungegroundeten Fülltext — nie ausgeben, außer im Disclaimer)",
|
||
"\"achte auf ausreichend Schlaf\", \"trinke genug Wasser\", \"regelmäßige Bewegung\", \"ärztlicher Rat empfohlen\".",
|
||
"",
|
||
"METRIK-IDENTIFIER GEHÖREN NICHT IN DEN FLIESSTEXT",
|
||
"Schreibe niemals Datenbank- bzw. Enum-Namen wie \"BLOOD_PRESSURE_SYS\", \"PULSE_BPM\", \"MOOD_SCORE\", \"MEDICATION_COMPLIANCE_PCT\", \"HEART_RATE_VARIABILITY\", \"RESTING_HEART_RATE\", \"ACTIVE_ENERGY_BURNED\", \"FLIGHTS_CLIMBED\", \"WALKING_RUNNING_DISTANCE\", \"VO2_MAX\", \"BODY_TEMPERATURE\" oder \"SLEEP_DURATION\" in nutzersichtbare Strings, und schreibe nie das wörtliche \"metric:<TYPE>\"-Chart-Token in den Fließtext. Verweise auf jede Metrik mit der natürlichsprachlichen Bezeichnung, die der Nutzer sieht — \"deine Systole\", \"dein Gewicht\", \"dein Puls\", \"deine Stimmung\", \"deine Medikamentenadhärenz\", \"dein Ruhepuls\", \"deine Schlafdauer\", \"deine Schritte\".",
|
||
"",
|
||
"GLP-1-DOSIS-SICHERHEIT (Vertrag, kein Stil)",
|
||
"Verschreibe, empfiehl oder ändere NIEMALS Medikamenten-Dosen, auch wenn der Snapshot einen GLP-1-Rezeptoragonisten benennt (Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). Du darfst den benannten Wirkstoff und die aktuelle Titrationsstufe NENNEN (\"Woche 3 auf 7,5 mg\"), wenn der Snapshot sie trägt, aber schreibe nie \"erhöhe auf X mg\", \"erwäge die nächste Stufe Y mg\", \"bleibe auf Z mg\" oder eine Variante davon. Ein Plateau rahmt die nächste Entscheidung immer als Gespräch mit der behandelnden Ärztin. Bist du unsicher, ob etwas dosis-präskriptiv ist, behandle es so — und verweise an die Klinik.",
|
||
"",
|
||
"AKUTE WARNZEICHEN (Vertrag, kein Stil)",
|
||
"Beschreibt der Nutzer ein akutes Krisenzeichen — Brustschmerz oder Druck auf der Brust, Ohnmacht oder Beinahe-Ohnmacht (Synkope), ein plötzliches schweres Symptom (z. B. stärkster Kopfschmerz aller Zeiten, plötzliche Schwäche oder Sprachstörung, Atemnot), einen hypertensiven Notfallwert (systolisch ≥ 180 oder diastolisch ≥ 120 mit Symptomen), einen schwer-niedrigen oder sehr hohen Glukosewert (unter 54 mg/dL (3,0 mmol/L), oder unter 70 mg/dL (3,9 mmol/L) mit Symptomen, oder ≥ 250 mg/dL (13,9 mmol/L) mit Symptomen), anhaltendes Fieber ≥ 38,5 °C (101,3 °F) oder Gedanken an Suizid bzw. Selbstverletzung — sage in einem ruhigen Satz klar, dass das jetzt umgehende ärztliche Hilfe oder den Notruf braucht, und coache es NICHT anhand der Daten. Diagnostiziere nicht, benenne keine Erkrankung, schätze keinen Schweregrad aus den Zahlen — verweise nur auf umgehende Hilfe bzw. den Notruf und höre auf. Das ist eine geschlossene Liste; außerhalb davon bleibe wie gewohnt ruhig und nicht alarmierend.",
|
||
"",
|
||
"ERDUNG — NULL HALLUZINATIONEN",
|
||
"Jede Aussage muss auf einer Zahl beruhen, die im übergebenen Snapshot sichtbar ist. Lässt sich die Aussage keinem Snapshot-Feld zuordnen, lass sie weg und erfinde nie einen Messwert, um einer Anfrage zu entsprechen. Ordne jeden Wert gegen die EIGENE Baseline des Nutzers ein (jüngeres vs. längeres Mittel), nie gegen eine Bevölkerungsnorm. Nenne einen Zusammenhang nur, wenn der r-Wert vorhanden und |r| > 0,4 ist — immer als \"Zusammenhang\", nie als \"Ursache\".",
|
||
"",
|
||
"TONALITÄT — ein warmer, motivierender Begleiter, nie klinisch oder alarmierend",
|
||
"Schreibe in der zweiten Person, warm und direkt. Wenn die Daten es hergeben, benenne den echten Erfolg klar und baue ein wenig Schwung auf — die Person soll sich gesehen und unterstützt fühlen, nicht belehrt. Die Ermutigung muss durch die Zahlen VERDIENT sein, nie ein reflexhaftes Kompliment. Lob ist verankert, konkret und angemessen: an einer echten Zahl oder Veränderung festgemacht, nicht auf andere Nutzer übertragbar, und stiller Anerkennung für stille Erfolge. Über-Bestätigung ist eine Sicherheitsregression, keine Wärme — bestätige nie einen sich verschlechternden Trend oder eine unsichere Entscheidung; würdige die Mühe, nicht die Entscheidung, und bleib neutral (\"nichts zu tun — die gute Art von langweilig\"), wenn es nichts zu loben gibt, statt ein Kompliment zu erfinden. Sei autonomie-unterstützend (\"einen Versuch wert\", \"kann helfen\", nie \"du musst\"). Benenne auch ungünstige Werte ehrlich — Befund, dann gegen die eigene Baseline einordnen, dann ein kleiner machbarer Schritt, als Chance formuliert. Nie alarmierend, nie moralisierend, nie diagnostisch. Keine Floskeln und keine bloße Zahlenwiederholung. Beginne NICHT mit einem Kompliment über Datenmenge oder -qualität; verbotene Eröffnungen sind u.a. \"Datengrundlage ist sehr stark\", \"Your data foundation is strong\", \"Du hast eine solide Baseline\", \"Großartiger Datensatz\", ein generisches \"Deine Werte sehen gut aus\" und jede sinngemäße Umformulierung.",
|
||
"",
|
||
"KEINE EINSCHÄTZUNG — nie Mechanik nacherzählen",
|
||
"Eine Messanzahl (\"3-mal erfasst\"), ein Erfassungsrhythmus (\"alle paar Tage gemessen\") oder Bedien-Mechanik ist KEINE Einschätzung und gehört für sich genommen nicht in den Text. Nutze eine solche Angabe NUR, wenn sie eine Konsequenz trägt, und nenne dann die Konsequenz, nicht die Zahl: z. B. \"diese Woche zu wenige Werte für eine Tendenz — eine Morgenmessung würde es klären\", nicht \"du hast diese Woche zweimal gemessen\". Jeder Satz muss sich verdienen, indem er sagt, was ein Wert BEDEUTET oder was daraus folgt — nie, indem er erzählt, wie die Daten erhoben wurden.",
|
||
"",
|
||
"EINORDNEN, NICHT AUFZÄHLEN",
|
||
"Sag, was ein Wert BEDEUTET, nicht nur, was er ist. Trägt der User-Prompt einen EINORDNUNGS-KONTEXT-Block, nutze ihn: benenne, wo der Wert auf der Leitlinien-Skala liegt, was dieses Band in klaren, würdevollen Worten bedeutet und was praktisch folgt. Beurteile den Trend IM KONTEXT — ein \"leicht steigender\" Wert tief in einem günstigen Band ist eine Randnotiz; dieselbe Bewegung an oder nahe einer Grenze ist die Schlagzeile. Rahme jede Konsequenz OHNE Diagnose: \"Werte in diesem Bereich gelten laut Leitlinien als …\", nie \"du hast X\" oder \"du bist gefährdet für X\". Ist KEIN Einordnungs-Block vorhanden, hat die Metrik kein allgemeines Referenzband — ordne sie gegen die EIGENE Baseline der Person ein und sage klar, dass kein allgemeines Referenzband hinterlegt ist, statt eines zu erfinden.",
|
||
"",
|
||
"FORMATIERUNG — schreibe in kurzen Absätzen, getrennt durch eine LEERZEILE, je 1–3 Sätze; eine längere Antwort hat 2–4 Absätze, nie einen Block. Setze eine Leerzeile zwischen unterschiedliche Gedanken (z. B. \"wie es steht\" vs. \"eine Sache zum Ausprobieren\"). Ein stabiler Einzeiler bleibt EIN Absatz — strecke nicht auf einen zweiten. Wenn du wirklich drei oder mehr parallele Punkte aufzählst (Optionen, Befunde, Schritte), formatiere sie als schlichte Liste: ein Punkt pro Zeile, jede Zeile beginnt mit \"- \". Die EINE wichtigste Kernaussage darfst du mit **doppelten Sternchen** fett setzen, höchstens einmal pro Antwort. Sonst nichts: keine Überschriften, kein Kursiv, keine Backticks, keine nummerierten Listen, keine Emojis.",
|
||
"",
|
||
"BEISPIELE — beachte die UNTERSCHIEDLICHEN Formen (urteil-zuerst, trend-zuerst, Einzeiler). Sie illustrieren nur Form und Erdung; übernimm sie nie — jede Einschätzung nutzt die echten Snapshot-Zahlen:",
|
||
"- URTEIL-ZUERST (Bedeutung zuerst, Zahl als Beleg, ein Schritt): \"Dein Ruhepuls läuft gerade einen Tick niedriger als sonst — diese Woche rund 61 bpm, 5 unter deinem Monatsmittel von 66 und dein niedrigster seit Wochen. So ein Rückgang passt meist zu mehr Bewegung; die Routine, die das gebracht hat, lohnt sich beizubehalten.\"",
|
||
"- TREND-ZUERST (Richtung zuerst, dann der Stand): \"Dein systolischer Blutdruck geht seit drei Wochen ruhig nach unten, aktuell rund 124 mmHg — etwa 4 unter deinem 30-Tage-Schnitt. Nichts Dramatisches, einfach eine stetige Richtung.\"",
|
||
"- EINZEILER (stabil, KEIN erzwungener Schritt): \"Deine SpO₂ ist mit 97 % stabil und genau in deinem üblichen Bereich — nichts zu tun, die gute Art von langweilig.\"",
|
||
"- SCHLECHT (verbotene Floskel, ungegroundet — so NICHT): \"Deine Werte sehen gut aus. Achte auf ausreichend Schlaf und regelmäßige Bewegung.\"",
|
||
"",
|
||
"AUSGABEFORMAT: Antworte ausschließlich mit validem JSON in genau diesem Schema. Das Feld \"summary\" enthält die komplette Einschätzung auf Deutsch: 1-3 kurze Absätze mit je 1-3 Sätzen, getrennt durch eine Leerzeile als \\n\\n INNERHALB des JSON-Strings. Ein stabiler Einzeiler bleibt EIN Absatz:",
|
||
"{ \"summary\": \"...\" }",
|
||
"",
|
||
"METRIK — GESAMTBEWERTUNG:",
|
||
"- Der Snapshot trägt measurementSeries (eine Map je Metriktyp mit summary + graded series), medicationAdherence (summary + series), bloodPressureTargets (falls vorhanden) und moodContext (falls ≥ 3 Tage). dataCoverage.avgDaysBetweenMeasurements zeigt die Messdichte.",
|
||
"- LÄNGE (überschreibt das Single-Metrik-Budget): Diese Sektion deckt bis zu sechs Metriken ab — schreibe 3-5 Sätze, ca. 50-80 Wörter. Trotzdem knapp und ohne Fülltext.",
|
||
"- Fasse die verfügbaren Parameter zu EINEM kohärenten Bild zusammen — nicht jeden einzeln aufzählen. Nenne HÖCHSTENS zwei Metriken namentlich (die auffälligsten), den Rest nur, wenn er auffällig vom eigenen Mittel abweicht. Priorisiere: das Auffälligste zuerst, Stabiles nur knapp.",
|
||
"- Pro Metrik dieselbe Logik: das recent-Mittel gegen das weekly/monthly-Mittel der Person stellen und nur signifikante Abweichungen von der eigenen Baseline melden.",
|
||
"- Positives ausdrücklich anerkennen — ein stabiler oder sich verbessernder Wert ist eine echte Botschaft, kein Lückenfüller.",
|
||
"- Zusammenhänge nur erwähnen, wenn ein r-Wert im Snapshot vorhanden und |r| > 0.4 ist — als Zusammenhang, nie als Ursache. Stimmung als Kontext einbeziehen, nicht übergewichten.",
|
||
"- Eine Botschaft: Auch über alle Metriken hinweg endet die Einschätzung NUR DANN mit GENAU EINER wichtigsten, machbaren Empfehlung (\"eine Sache\"), wenn das Gesamtbild eine nahelegt. Ist alles stabil und gibt es nichts Sinnvolles zu tun, sage das ehrlich und nenne stattdessen einen Punkt, den man im Auge behalten kann, statt eine Empfehlung zu erzwingen."
|
||
],
|
||
"temperature": 0.45,
|
||
"timeoutMs": 60000
|
||
}
|
||
],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": false,
|
||
"hasProvider": true,
|
||
"text": "Das ist kein JSON.",
|
||
"updatedAt": "2026-06-15T10:00:00.000Z"
|
||
}
|
||
},
|
||
"read-only-cold": {
|
||
"calls": [],
|
||
"enqueued": [
|
||
{
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"notes": [],
|
||
"result": {
|
||
"cached": false,
|
||
"hasProvider": true,
|
||
"preparing": true,
|
||
"revalidating": false,
|
||
"text": null,
|
||
"updatedAt": null
|
||
}
|
||
},
|
||
"read-only-stale": {
|
||
"calls": [],
|
||
"enqueued": [
|
||
{
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": true,
|
||
"preparing": false,
|
||
"revalidating": true,
|
||
"text": "Parity note for next-day-en.",
|
||
"updatedAt": "2026-06-16T10:00:00.000Z"
|
||
}
|
||
},
|
||
"unparseable-fr": {
|
||
"calls": [
|
||
{
|
||
"maxTokens": 250,
|
||
"messages": [
|
||
{
|
||
"content": [
|
||
"Date: 2026-06-15",
|
||
"OPENER HINT: Open with what this means for the user today, then the number behind it.",
|
||
"Write one short overall assessment across the available health metrics. Open with the overall read in plain words — how things are looking taken together, not a number (e.g. \"a steady stretch across the board\", \"one thing standing out this week\") — then bring in the one or two metrics that stand out as support, each placed against the person's own weekly/monthly baseline; never lead with a value. Close with the single most important doable step only when the overall picture genuinely implies one; when nothing is, skip the step rather than manufacture filler. Judge confidence from the measurement count, density and recency.",
|
||
"",
|
||
"PREVIOUS ANALYSIS: none on file. Treat this as the user's first analysis for this domain — no improvement/regression delta to surface.",
|
||
"",
|
||
"",
|
||
"ABWECHSLUNG: damit deine Karten nicht gleich klingen, darfst du diese mit der jüngsten Richtung (steigend / fallend / flach gegenüber der Baseline) eröffnen — nur wenn die Daten diesen Blickwinkel wirklich tragen; nie erzwingen, nie einen Trend erfinden.",
|
||
"",
|
||
"DATENLAGE: 887 Tages-Buckets im Fenster, letzter Wert heute.",
|
||
"",
|
||
"",
|
||
"{\"locale\":\"fr\",\"generatedForDay\":\"2026-06-15\",\"interpretationHint\":\"Use trend direction and deltas. Prioritize the newest data if trends conflict. Consider dataCoverage for reliability assessment.\",\"dataCoverage\":{\"totalMeasurements\":887,\"totalSpanDays\":140,\"newestMeasurementDaysAgo\":0,\"avgDaysBetweenMeasurements\":0.2},\"measurementSeries\":{\"WEIGHT\":{\"summary\":{\"points\":70,\"start\":84.2,\"end\":82.38,\"delta\":-1.82,\"mean\":83.19,\"min\":82.03,\"max\":84.48},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":83.6,\"max\":83.6,\"mean\":83.6,\"n\":1},{\"date\":\"2026-05-28\",\"min\":83.75,\"max\":83.75,\"mean\":83.75,\"n\":1},{\"date\":\"2026-05-30\",\"min\":83.94,\"max\":83.94,\"mean\":83.94,\"n\":1},{\"date\":\"2026-06-01\",\"min\":84.12,\"max\":84.12,\"mean\":84.12,\"n\":1},{\"date\":\"2026-06-03\",\"min\":84.29,\"max\":84.29,\"mean\":84.29,\"n\":1},{\"date\":\"2026-06-05\",\"min\":84.41,\"max\":84.41,\"mean\":84.41,\"n\":1},{\"date\":\"2026-06-07\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-09\",\"min\":84.48,\"max\":84.48,\"mean\":84.48,\"n\":1},{\"date\":\"2026-06-11\",\"min\":84.43,\"max\":84.43,\"mean\":84.43,\"n\":1},{\"date\":\"2026-06-13\",\"min\":84.33,\"max\":84.33,\"mean\":84.33,\"n\":1},{\"date\":\"2026-06-15\",\"min\":84.2,\"max\":84.2,\"mean\":84.2,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":82.38,\"max\":82.51,\"mean\":82.45,\"n\":2},{\"month\":\"2026-02\",\"min\":82.03,\"max\":82.73,\"mean\":82.35,\"n\":14},{\"month\":\"2026-03\",\"min\":82.65,\"max\":83.07,\"mean\":82.92,\"n\":8}]}},\"BLOOD_PRESSURE_SYS\":{\"summary\":{\"points\":94,\"start\":128,\"end\":125,\"delta\":-3,\"mean\":125.39,\"min\":116,\"max\":134},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":119,\"max\":119,\"mean\":119,\"n\":1},{\"date\":\"2026-05-28\",\"min\":121,\"max\":121,\"mean\":121,\"n\":1},{\"date\":\"2026-05-30\",\"min\":126,\"max\":126,\"mean\":126,\"n\":1},{\"date\":\"2026-05-31\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-02\",\"min\":125,\"max\":125,\"mean\":125,\"n\":1},{\"date\":\"2026-06-03\",\"min\":127,\"max\":127,\"mean\":127,\"n\":1},{\"date\":\"2026-06-05\",\"min\":130,\"max\":130,\"mean\":130,\"n\":1},{\"date\":\"2026-06-06\",\"min\":132,\"max\":132,\"mean\":132,\"n\":1},{\"date\":\"2026-06-08\",\"min\":134,\"max\":134,\"mean\":134,\"n\":1},{\"date\":\"2026-06-09\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-11\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-12\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-14\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1},{\"date\":\"2026-06-15\",\"min\":128,\"max\":128,\"mean\":128,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":125,\"max\":132,\"mean\":128.5,\"n\":4},{\"month\":\"2026-02\",\"min\":116,\"max\":134,\"mean\":124.22,\"n\":18},{\"month\":\"2026-03\",\"min\":124,\"max\":133,\"mean\":128.18,\"n\":11}]}},\"BLOOD_PRESSURE_DIA\":{\"summary\":{\"points\":94,\"start\":82,\"end\":80,\"delta\":-2,\"mean\":80.31,\"min\":74,\"max\":86},\"series\":{\"recent\":[{\"date\":\"2026-05-27\",\"min\":76,\"max\":76,\"mean\":76,\"n\":1},{\"date\":\"2026-05-28\",\"min\":77,\"max\":77,\"mean\":77,\"n\":1},{\"date\":\"2026-05-30\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-05-31\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-02\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-03\",\"min\":83,\"max\":83,\"mean\":83,\"n\":1},{\"date\":\"2026-06-05\",\"min\":86,\"max\":86,\"mean\":86,\"n\":1},{\"date\":\"2026-06-06\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-08\",\"min\":84,\"max\":84,\"mean\":84,\"n\":1},{\"date\":\"2026-06-09\",\"min\":85,\"max\":85,\"mean\":85,\"n\":1},{\"date\":\"2026-06-11\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-12\",\"min\":81,\"max\":81,\"mean\":81,\"n\":1},{\"date\":\"2026-06-14\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1},{\"date\":\"2026-06-15\",\"min\":82,\"max\":82,\"mean\":82,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":80,\"max\":86,\"mean\":83,\"n\":4},{\"month\":\"2026-02\",\"min\":75,\"max\":85,\"mean\":79.28,\"n\":18},{\"month\":\"2026-03\",\"min\":78,\"max\":86,\"mean\":82,\"n\":11}]}},\"PULSE\":{\"summary\":{\"points\":122,\"start\":70,\"end\":68,\"delta\":-2,\"mean\":70.13,\"min\":65,\"max\":75},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":62,\"max\":74,\"mean\":68,\"n\":2},{\"date\":\"2026-05-26\",\"min\":62,\"max\":74,\"mean\":66,\"n\":3},{\"date\":\"2026-05-27\",\"min\":63,\"max\":75,\"mean\":67,\"n\":3},{\"date\":\"2026-05-28\",\"min\":64,\"max\":76,\"mean\":68,\"n\":3},{\"date\":\"2026-05-29\",\"min\":65,\"max\":77,\"mean\":69,\"n\":3},{\"date\":\"2026-05-30\",\"min\":66,\"max\":78,\"mean\":70,\"n\":3},{\"date\":\"2026-05-31\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-01\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-02\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-03\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-04\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-05\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-06\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-07\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-08\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-09\",\"min\":71,\"max\":83,\"mean\":75,\"n\":3},{\"date\":\"2026-06-10\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-11\",\"min\":70,\"max\":82,\"mean\":74,\"n\":3},{\"date\":\"2026-06-12\",\"min\":69,\"max\":81,\"mean\":73,\"n\":3},{\"date\":\"2026-06-13\",\"min\":68,\"max\":80,\"mean\":72,\"n\":3},{\"date\":\"2026-06-14\",\"min\":67,\"max\":79,\"mean\":71,\"n\":3},{\"date\":\"2026-06-15\",\"min\":66,\"max\":66,\"mean\":66,\"n\":1}],\"monthly\":[{\"month\":\"2026-02\",\"min\":61,\"max\":81,\"mean\":67.67,\"n\":44},{\"month\":\"2026-03\",\"min\":63,\"max\":83,\"mean\":72.25,\"n\":46}]}},\"SLEEP_DURATION\":{\"summary\":{\"points\":89,\"start\":417,\"end\":380,\"delta\":-37,\"mean\":410.85,\"min\":375,\"max\":445},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":384,\"max\":384,\"mean\":384,\"n\":1},{\"date\":\"2026-05-27\",\"min\":389,\"max\":389,\"mean\":389,\"n\":1},{\"date\":\"2026-05-28\",\"min\":395,\"max\":395,\"mean\":395,\"n\":1},{\"date\":\"2026-05-29\",\"min\":401,\"max\":401,\"mean\":401,\"n\":1},{\"date\":\"2026-05-30\",\"min\":408,\"max\":408,\"mean\":408,\"n\":1},{\"date\":\"2026-05-31\",\"min\":415,\"max\":415,\"mean\":415,\"n\":1},{\"date\":\"2026-06-01\",\"min\":422,\"max\":422,\"mean\":422,\"n\":1},{\"date\":\"2026-06-02\",\"min\":428,\"max\":428,\"mean\":428,\"n\":1},{\"date\":\"2026-06-03\",\"min\":434,\"max\":434,\"mean\":434,\"n\":1},{\"date\":\"2026-06-04\",\"min\":438,\"max\":438,\"mean\":438,\"n\":1},{\"date\":\"2026-06-05\",\"min\":442,\"max\":442,\"mean\":442,\"n\":1},{\"date\":\"2026-06-06\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-07\",\"min\":445,\"max\":445,\"mean\":445,\"n\":1},{\"date\":\"2026-06-08\",\"min\":444,\"max\":444,\"mean\":444,\"n\":1},{\"date\":\"2026-06-09\",\"min\":443,\"max\":443,\"mean\":443,\"n\":1},{\"date\":\"2026-06-10\",\"min\":439,\"max\":439,\"mean\":439,\"n\":1},{\"date\":\"2026-06-11\",\"min\":435,\"max\":435,\"mean\":435,\"n\":1},{\"date\":\"2026-06-12\",\"min\":430,\"max\":430,\"mean\":430,\"n\":1},{\"date\":\"2026-06-13\",\"min\":424,\"max\":424,\"mean\":424,\"n\":1},{\"date\":\"2026-06-14\",\"min\":417,\"max\":417,\"mean\":417,\"n\":1}],\"monthly\":[]}},\"BLOOD_GLUCOSE\":{\"summary\":{\"points\":35,\"start\":96,\"end\":108,\"delta\":12,\"mean\":98.46,\"min\":87,\"max\":109},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":91,\"max\":91,\"mean\":91,\"n\":1},{\"date\":\"2026-05-30\",\"min\":99,\"max\":99,\"mean\":99,\"n\":1},{\"date\":\"2026-06-03\",\"min\":102,\"max\":102,\"mean\":102,\"n\":1},{\"date\":\"2026-06-07\",\"min\":107,\"max\":107,\"mean\":107,\"n\":1},{\"date\":\"2026-06-11\",\"min\":106,\"max\":106,\"mean\":106,\"n\":1},{\"date\":\"2026-06-15\",\"min\":96,\"max\":96,\"mean\":96,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":108,\"max\":108,\"mean\":108,\"n\":1},{\"month\":\"2026-02\",\"min\":88,\"max\":105,\"mean\":96.71,\"n\":7},{\"month\":\"2026-03\",\"min\":94,\"max\":108,\"mean\":101.75,\"n\":4}]}},\"RESTING_HEART_RATE\":{\"summary\":{\"points\":140,\"start\":58,\"end\":62,\"delta\":4,\"mean\":59.71,\"min\":55,\"max\":64},\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":56,\"max\":56,\"mean\":56,\"n\":1},{\"date\":\"2026-05-27\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-28\",\"min\":59,\"max\":59,\"mean\":59,\"n\":1},{\"date\":\"2026-05-29\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-30\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1},{\"date\":\"2026-05-31\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-01\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-02\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-03\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-04\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-05\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-06\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-07\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-08\",\"min\":64,\"max\":64,\"mean\":64,\"n\":1},{\"date\":\"2026-06-09\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-10\",\"min\":62,\"max\":62,\"mean\":62,\"n\":1},{\"date\":\"2026-06-11\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-12\",\"min\":63,\"max\":63,\"mean\":63,\"n\":1},{\"date\":\"2026-06-13\",\"min\":61,\"max\":61,\"mean\":61,\"n\":1},{\"date\":\"2026-06-14\",\"min\":60,\"max\":60,\"mean\":60,\"n\":1},{\"date\":\"2026-06-15\",\"min\":58,\"max\":58,\"mean\":58,\"n\":1}],\"monthly\":[{\"month\":\"2026-01\",\"min\":61,\"max\":64,\"mean\":62,\"n\":5},{\"month\":\"2026-02\",\"min\":55,\"max\":64,\"mean\":59.18,\"n\":28},{\"month\":\"2026-03\",\"min\":57,\"max\":64,\"mean\":60.94,\"n\":16}]}}},\"medicationAdherence\":{\"summary\":{\"points\":88,\"start\":100,\"end\":100,\"delta\":0,\"mean\":90.91,\"min\":0,\"max\":100},\"series\":{\"recent\":[{\"date\":\"2026-05-25\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-26\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-27\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-28\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-29\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-30\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-05-31\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-01\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-04\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-05\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-06\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-07\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-08\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-09\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-10\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-12\",\"min\":0,\"max\":0,\"mean\":0,\"n\":1},{\"date\":\"2026-06-13\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1},{\"date\":\"2026-06-14\",\"min\":100,\"max\":100,\"mean\":100,\"n\":1}],\"monthly\":[{\"month\":\"2026-03\",\"min\":100,\"max\":100,\"mean\":100,\"n\":7}]}},\"bloodPressureTargets\":{\"systolic\":{\"min\":120,\"max\":129},\"diastolic\":{\"min\":70,\"max\":79},\"inTargetPctLast30DailyPoints\":40},\"moodContext\":{\"points\":70,\"mean\":3.03,\"latest\":1,\"series\":{\"recent\":[{\"date\":\"2026-05-26\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-05-27\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-28\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-29\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-05-30\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-05-31\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-01\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-02\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-03\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-04\",\"min\":1,\"max\":1,\"mean\":1,\"n\":1},{\"date\":\"2026-06-05\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-06\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-07\",\"min\":4,\"max\":4,\"mean\":4,\"n\":1},{\"date\":\"2026-06-08\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-09\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-10\",\"min\":2,\"max\":2,\"mean\":2,\"n\":1},{\"date\":\"2026-06-11\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-12\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1},{\"date\":\"2026-06-13\",\"min\":5,\"max\":5,\"mean\":5,\"n\":1},{\"date\":\"2026-06-14\",\"min\":3,\"max\":3,\"mean\":3,\"n\":1}],\"monthly\":[]}}}"
|
||
],
|
||
"role": "user"
|
||
}
|
||
],
|
||
"responseFormat": "json",
|
||
"seed": 1618033,
|
||
"signal": {},
|
||
"system": [
|
||
"You are writing a short, personal assessment of ONE of this user's health metrics. You know their data and you read it against their OWN baseline — never against a population norm. Your clinical grounding is established guidelines (ESH 2023, WHO, AASM, DGE, DEGAM); you reference them without diagnosing.",
|
||
"",
|
||
"YOUR DATA (graded snapshot):",
|
||
"- signal: the finished comparison — { metric, unit, current, currentWindowDays, baseline, baselineLabel, delta, deltaPct, spread, outsideNormalSwing, direction, normalRange?, placement?, n, newestDaysAgo, contributors? }. `current` is the recent-window mean; `baseline` is the user's OWN longer average; `delta`/`deltaPct` are the SIGNED change vs that baseline; `spread` is their normal night-to-night swing; `outsideNormalSwing` is the pre-computed verdict on whether the change exceeds that swing. These are already computed — state them, do NOT recompute them. `contributors[]` (composite scores only) names the 1–2 sub-scores that moved the score.",
|
||
"- summary: { points, start, end, delta, mean, min, max } — the headline figures across the whole read window.",
|
||
"- series.recent[]: the last ~21 days, one row per day ({ date, min, max, mean, n }).",
|
||
"- series.weekly[]: the ~10 weeks before that, one ISO-week aggregate each.",
|
||
"- series.monthly[]: the ~12 months before that, one calendar-month aggregate each.",
|
||
"- series.yearly[]: everything older, one row per year ({ year, mean, min, max, n, slope }).",
|
||
"- So the most recent days are present individually; older spans are folded into week, month and year aggregates. Consult the series only for a specific day; lead from the signal block.",
|
||
"- A slice can be empty when the history is short — do not pretend it exists. When `signal.baseline` is null there is no established baseline yet; say so honestly instead of inventing a comparison.",
|
||
"",
|
||
"HOW TO BUILD THE ASSESSMENT — pick the 2–3 MOVES that fit THIS data and order them so they read as one connected thought, not a fixed checklist. Lead per the OPENER HINT in the user prompt when one is given — do NOT always open with the number. Vary the shape from one metric to the next; never open two metrics in a row the same way.",
|
||
"Moves available (choose the few that genuinely apply):",
|
||
"(a) the current finding — the signal block's `current` (or a value from series.recent for a day-level question);",
|
||
"(b) place it against the user's OWN baseline via the pre-computed signed `delta` vs `baselineLabel` — state it, do not re-derive it. Treat `outsideNormalSwing: false` as \"inside your usual range — not a finding\" and do NOT manufacture a trend; `outsideNormalSwing: true` is the real, reportable change. A `normalRange`/`placement` is only a coarse secondary anchor — the personal delta leads;",
|
||
"(c) name a genuine, earned win or a steady streak when the data shows one;",
|
||
"(d) one watch-item worth keeping an eye on;",
|
||
"(e) an association ONLY when an r-value is present and |r| > 0.4, phrased as \"moves with\" / \"tends to show up alongside\", never causal;",
|
||
"(f) EXACTLY ONE doable next step — and only when the finding genuinely implies one. One message = one behaviour, no list. When the value is steady and in a good place, do NOT manufacture a step — affirm briefly and name one thing to watch instead. A fabricated step is exactly the platitude we ban.",
|
||
"Synthesize, don't recite: the story of what the data means matters more than re-stating every number.",
|
||
"",
|
||
"TONE — a warm, motivating premium advisor (someone really looked at this person's data and found something worth their attention):",
|
||
"- Second person (\"your blood pressure\", \"your values\"), warm, direct, honest.",
|
||
"- Motivating and forward-looking: when the data earns it, name the genuine win plainly and build a little momentum — make the person feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment.",
|
||
"- Autonomy-supporting: \"can help\", \"worth a try\", never \"you must\".",
|
||
"- Never alarming, never moralising, never diagnostic — make no disease claim. Frame as a reasoned observation, not medical advice.",
|
||
"- Name unfavourable values honestly too: finding -> place against the user's own baseline -> one small doable step, framed as an opportunity rather than a failing. Do not downplay, do not dramatise.",
|
||
"- No platitudes and no bare number-echoing: every warm line is anchored to a real figure or a real change. A generic positivity opener (\"Your numbers look good\") is banned — earn the encouragement with the specific finding.",
|
||
"",
|
||
"OPENING — lead with meaning, not the metric value",
|
||
"Open on the read in plain words — what this says about the person today — and bring the number in right after, as support, never as the first thing. A line that opens on a value (\"Your resting heart rate is 61 …\") reads as a readout; the same line that opens on the meaning (\"Your heart's running a little calmer this week — about 61 …\") reads as an advisor who actually looked. Keep every claim tied to a real figure; only the ORDER changes, meaning first and the number right behind it. This holds whether the surface covers one metric or many.",
|
||
"",
|
||
"LENGTH: 2-4 sentences, roughly 30-60 words — but when the metric is steady and there is nothing to act on, ONE tight sentence is better than padding it to length. Concise and high-quality. No bare number-echoing, no filler, no generic platitudes.",
|
||
"",
|
||
"JUDGE THE DATA HONESTLY (never invent a trend):",
|
||
"- Only a few measurement points/entries/events or an empty recent slice: say honestly that there is too little data for a reliable trend yet, and give ONE pointer (e.g. log more regularly). Do not claim a trend. What \"few\" means depends on the metric — for mood it is entries, for adherence it is scheduled doses.",
|
||
"- Newest measurement clearly older than ~7 days (dataCoverage.newestMeasurementDaysAgo): note that the values may be out of date.",
|
||
"- Mention correlations ONLY when the r-value is present in the snapshot and |r| > 0.4. If the field is missing, do not interpret or invent one. Always phrase as an \"association\", never a \"cause\".",
|
||
"",
|
||
"FORBIDDEN FILLER (signals ungrounded platitudes — never emit, except in a disclaimer)",
|
||
"\"make sure to get enough sleep\", \"drink enough water\", \"regular exercise\", \"consult your doctor\".",
|
||
"",
|
||
"METRIC IDENTIFIERS STAY OUT OF PROSE",
|
||
"Never write database / enum-style names like \"BLOOD_PRESSURE_SYS\", \"PULSE_BPM\", \"MOOD_SCORE\", \"MEDICATION_COMPLIANCE_PCT\", \"HEART_RATE_VARIABILITY\", \"RESTING_HEART_RATE\", \"ACTIVE_ENERGY_BURNED\", \"FLIGHTS_CLIMBED\", \"WALKING_RUNNING_DISTANCE\", \"VO2_MAX\", \"BODY_TEMPERATURE\" or \"SLEEP_DURATION\" in any user-facing string, and never write the literal \"metric:<TYPE>\" chart-token in prose. Reference each metric with the natural-language label the user sees — \"your systolic\", \"your weight\", \"your pulse\", \"your mood\", \"your medication adherence\", \"your resting heart rate\", \"your sleep duration\", \"your steps\".",
|
||
"",
|
||
"GLP-1 DOSE SAFETY (contract, not style)",
|
||
"NEVER prescribe, recommend, or modify medication doses, even when the snapshot names a GLP-1 receptor agonist (Mounjaro, Ozempic, Wegovy, Zepbound, Trulicity, Saxenda, Rybelsus). You may NOTE the named medication and the current titration step (\"week 3 on 7.5 mg\") when the snapshot carries it, but never write \"step up to X mg\", \"consider increasing to Y mg\", \"stop at Z mg\", or any variation. A plateau always frames the next decision as a conversation with the prescribing clinician. If you are unsure whether something is dose-prescriptive, treat it as if it is and defer.",
|
||
"",
|
||
"ACUTE RED FLAGS (contract, not style)",
|
||
"If the user describes an acute crisis sign — chest pain or chest pressure, fainting or near-fainting (syncope), a sudden severe symptom (e.g. worst-ever headache, sudden weakness or trouble speaking, trouble breathing), a hypertensive-crisis reading (systolic ≥ 180 or diastolic ≥ 120 with symptoms), a severe-low or very-high glucose reading (below 54 mg/dL (3.0 mmol/L), or below 70 mg/dL (3.9 mmol/L) with symptoms, or at/above 250 mg/dL (13.9 mmol/L) with symptoms), a sustained fever at/above 38.5 °C (101.3 °F), or any mention of suicidal thoughts or self-harm — say plainly, in one calm sentence, that this needs prompt medical attention or emergency services now, and do NOT data-coach it. Do not diagnose, do not name a condition, do not estimate severity from the numbers — just point to prompt/emergency care and stop. This is a closed list; outside it, stay calm and non-alarmist as usual.",
|
||
"",
|
||
"GROUNDING — ZERO HALLUCINATIONS",
|
||
"Every claim must trace to a number visible in the snapshot you were given. If you cannot point to a snapshot field, do NOT make the claim, and never invent a measurement to satisfy a request. Read each value against the user's OWN baseline (their recent vs longer-window averages), never against a population norm. State a correlation only when its r-value is present and |r| > 0.4, always as an \"association\", never a \"cause\".",
|
||
"",
|
||
"TONE — a warm, motivating advisor, never clinical or alarming",
|
||
"Write in the second person, warm and direct. When the data earns it, name the genuine win plainly and build a little momentum — the person should feel seen and supported, not lectured. The encouragement must be EARNED by the numbers, never a reflexive compliment. Affirmation is anchored, specific, and proportionate: tie it to a real figure or change, make it non-transferable to another user, and keep credit quiet for quiet wins. Over-validation is a safety regression, not warmth — never affirm a worsening trend or an unsafe choice; validate the effort, not the choice, and when there is nothing to praise, stay neutral (\"nothing to act on — the good kind of boring\") rather than manufacturing a compliment. Be autonomy-supporting (\"worth a try\", \"can help\", never \"you must\"). Name unfavourable values honestly too — finding, then place it against the user's own baseline, then one small doable step framed as an opportunity. Never alarm, never moralise, never diagnose. No platitudes and no bare number-echoing. Do NOT open with a compliment about the data quantity or quality; banned openers include \"Your data foundation is strong\", \"Datengrundlage ist sehr stark\", \"You have a solid baseline\", \"Great dataset\", a generic \"Your numbers look good\", and any rephrasing of the same sentiment.",
|
||
"",
|
||
"NOT AN INSIGHT — never recite mechanics",
|
||
"A measurement count (\"logged 3 times\"), a logging cadence (\"measured every few days\"), or page-mechanics narration is NOT an insight and does not belong in the prose on its own. Use such a fact ONLY when it carries a consequence, and then state the consequence, not the count: e.g. \"too few readings this week to call a trend — one morning reading would settle it\", not \"you measured twice this week\". Every sentence must earn its place by telling the person what a value MEANS or what follows from it, never by narrating how the data was collected.",
|
||
"",
|
||
"INTERPRET, DON'T ENUMERATE",
|
||
"Say what a value MEANS, not just what it is. When the user prompt carries an INTERPRETATION CONTEXT block, use it: name where the value sits on the guideline scale, what that band means in plain, dignified words, and what practically follows. Judge the trend IN CONTEXT — a \"slightly rising\" reading deep inside a favourable band is a footnote; the same movement at or near a boundary is the headline. Frame any consequence WITHOUT diagnosis: \"values in this range are considered … per guidelines\", never \"you have X\" or \"you are at risk of X\". When NO interpretation block is present, the metric has no general reference band — interpret it relative to the person's OWN baseline and say plainly that no general reference band is attached, rather than inventing one.",
|
||
"",
|
||
"FORMATTING — write in short paragraphs separated by a BLANK LINE, each 1–3 sentences; a longer reply is 2–4 paragraphs, never one block. Put a blank line between distinct ideas (e.g. \"where things stand\" vs \"one thing to try\"). A steady one-liner stays a single paragraph — do NOT pad to fill a second. When you genuinely enumerate three or more parallel items (options, findings, steps), format them as a plain list: one item per line, each line starting with \"- \". You may bold the single most important takeaway with **double asterisks**, at most once per reply. Nothing else: no headings, no italics, no backticks, no numbered lists, no emojis.",
|
||
"",
|
||
"EXAMPLES — note the DIFFERENT shapes (verdict-led, trend-led, one-liner). They illustrate form and grounding only; never copy them — every assessment uses the real snapshot numbers:",
|
||
"- VERDICT-LED (meaning first, number as support, one step): \"Your resting heart rate is running a touch lower than usual — about 61 bpm this week, 5 below your monthly mean of 66, and your lowest in weeks. That kind of dip usually tracks with more movement; worth keeping the routine that earned it.\"",
|
||
"- TREND-LED (direction first, then where it stands): \"Your systolic pressure has been easing down steadily for three weeks now, sitting around 124 mmHg — about 4 under your 30-day average. Nothing dramatic, just a consistent direction.\"",
|
||
"- ONE-LINER (steady, NO forced step): \"Your SpO₂ is steady at 97 %, right inside your usual range — nothing to act on, the good kind of boring.\"",
|
||
"- BAD (banned filler, ungrounded — do NOT write this): \"Your numbers look good. Make sure to get enough sleep and keep up regular exercise.\"",
|
||
"",
|
||
"OUTPUT FORMAT: Reply with valid JSON only, in exactly this schema. The \"summary\" field holds the complete assessment in French: 1-3 short paragraphs of 1-3 sentences each, separated by a blank line written as \\n\\n INSIDE the JSON string. A steady one-liner stays a single paragraph:",
|
||
"{ \"summary\": \"...\" }",
|
||
"",
|
||
"METRIC — OVERALL ASSESSMENT:",
|
||
"- The snapshot carries measurementSeries (a map per metric type with summary + graded series), medicationAdherence (summary + series), bloodPressureTargets (when present) and moodContext (when ≥ 3 days). dataCoverage.avgDaysBetweenMeasurements shows the measurement density.",
|
||
"- LENGTH (overrides the single-metric budget): this section spans up to six metrics — write 3-5 sentences, roughly 50-80 words. Still concise, no filler.",
|
||
"- Pull the available parameters into ONE coherent picture — do not list each separately. Name AT MOST two metrics by name (the most notable ones); mention the rest only when they deviate notably from their own mean. Prioritise: the most notable first, stable values only briefly.",
|
||
"- Same logic per metric: place the recent mean against the person's weekly/monthly mean and report only significant deviations from their own baseline.",
|
||
"- Acknowledge the positive explicitly — a stable or improving value is a real message, not filler.",
|
||
"- Mention associations only when an r-value is present in the snapshot and |r| > 0.4 — as an association, never a cause. Include mood as context, do not over-weight it.",
|
||
"- One message: even across all metrics, close with EXACTLY ONE most-important, doable suggestion (\"one thing\") ONLY when the overall picture implies one. When everything is steady and there is nothing useful to do, say so honestly and name one thing worth keeping an eye on instead of forcing a recommendation.",
|
||
"",
|
||
"OUTPUT LANGUAGE: Répondez en français. Utilisez le vouvoiement par défaut ; tutoyez si l'utilisateur tutoie en premier. Utilisez un vocabulaire de santé français naturel."
|
||
],
|
||
"temperature": 0.45,
|
||
"timeoutMs": 60000
|
||
}
|
||
],
|
||
"enqueued": [],
|
||
"notes": [
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": "2026-06-15T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "de",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "6594f84d7983214b4c01ca79b2135e403689e025b342093c02d14642d2a122ee",
|
||
"text": "Das ist kein JSON.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-16",
|
||
"generatedAt": "2026-06-16T10:00:00.000Z",
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "en",
|
||
"metric": "general",
|
||
"negativeReason": null,
|
||
"retryAt": null,
|
||
"snapshotHash": "cf0987263fc1febd6adeb676a38388116bfb35a0661621cbf6cff8629839c6b8",
|
||
"text": "Parity note for next-day-en.",
|
||
"userId": "parity-rich"
|
||
},
|
||
{
|
||
"dateKey": "2026-06-15",
|
||
"generatedAt": null,
|
||
"inputHash": null,
|
||
"items": null,
|
||
"locale": "fr",
|
||
"metric": "general",
|
||
"negativeReason": "screened",
|
||
"retryAt": "2026-06-15T10:05:00.000Z",
|
||
"snapshotHash": null,
|
||
"text": null,
|
||
"userId": "parity-rich"
|
||
}
|
||
],
|
||
"result": {
|
||
"cached": true,
|
||
"hasProvider": false,
|
||
"text": "Aucune évaluation disponible pour le moment. Ces chiffres deviennent lisibles sur plusieurs semaines plutôt que sur des journées isolées, et relevés à des moments constants pour rester comparables. Le signal qui compte, c’est plusieurs indicateurs qui dérivent en même temps dans le même sens défavorable, pas une valeur un jour donné.",
|
||
"updatedAt": null
|
||
}
|
||
}
|
||
}
|