@mongrov/analytics 0.9.1 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/core/metric_metadata.d.ts +41 -0
- package/dist/core/metric_metadata.d.ts.map +1 -1
- package/dist/core/metric_metadata.js +29 -5
- package/dist/core/metric_metadata.js.map +1 -1
- package/dist/tools/factory.d.ts +2 -0
- package/dist/tools/factory.d.ts.map +1 -1
- package/dist/tools/factory.js +9 -0
- package/dist/tools/factory.js.map +1 -1
- package/dist/tools/formatters/copy-guidelines.d.ts +1 -1
- package/dist/tools/formatters/copy-guidelines.d.ts.map +1 -1
- package/dist/tools/formatters/copy-guidelines.js +14 -0
- package/dist/tools/formatters/copy-guidelines.js.map +1 -1
- package/dist/tools/impls/temperature.d.ts +30 -0
- package/dist/tools/impls/temperature.d.ts.map +1 -0
- package/dist/tools/impls/temperature.js +84 -0
- package/dist/tools/impls/temperature.js.map +1 -0
- package/dist/tools/index.d.ts +1 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +1 -0
- package/dist/tools/index.js.map +1 -1
- package/package.json +3 -3
|
@@ -44,6 +44,24 @@ export interface MetricMetadataEntry {
|
|
|
44
44
|
* distance and sleep_score have no baseline consumer in v0.2.0).
|
|
45
45
|
*/
|
|
46
46
|
baselineDailyAggregate?: BaselineDailyAggregate;
|
|
47
|
+
/**
|
|
48
|
+
* Smallest increment the CURRENT ring actually reports, in the metric's
|
|
49
|
+
* own units (sprint6 §7).
|
|
50
|
+
*
|
|
51
|
+
* Drives the display precision clamp and the Day-view mark rule: a
|
|
52
|
+
* whole-degree temperature reading cannot support a continuous intra-day
|
|
53
|
+
* curve, so the screen shows discrete marks instead of segments. Storage
|
|
54
|
+
* precision is a separate thing — `temperature.temp_c` is DECIMAL(4,1) so
|
|
55
|
+
* a finer device needs no migration, but today's hardware still emits 1.0.
|
|
56
|
+
*
|
|
57
|
+
* NOT per device generation, which is what sprint6 §7 asks for. There is
|
|
58
|
+
* no generation, model or hardware-revision field anywhere in the schema:
|
|
59
|
+
* `device_id` is `hash(brand + hardware_id)` by principle 26 and is opaque
|
|
60
|
+
* by construction, so nothing can key a per-generation lookup today. This
|
|
61
|
+
* field is the current-hardware value; when a generation key exists, this
|
|
62
|
+
* becomes its default row rather than being replaced.
|
|
63
|
+
*/
|
|
64
|
+
precision?: number;
|
|
47
65
|
}
|
|
48
66
|
/**
|
|
49
67
|
* Frozen metric registry, verbatim from spec §Metric metadata.
|
|
@@ -58,6 +76,7 @@ export declare const METRIC_METADATA: Readonly<{
|
|
|
58
76
|
readonly sampling_minutes: 60;
|
|
59
77
|
readonly exposure: "full";
|
|
60
78
|
readonly baselineDailyAggregate: "avg";
|
|
79
|
+
readonly precision: 1;
|
|
61
80
|
};
|
|
62
81
|
readonly stress: {
|
|
63
82
|
readonly table: "hrv";
|
|
@@ -65,6 +84,7 @@ export declare const METRIC_METADATA: Readonly<{
|
|
|
65
84
|
readonly sampling_minutes: 60;
|
|
66
85
|
readonly exposure: "full";
|
|
67
86
|
readonly baselineDailyAggregate: "avg";
|
|
87
|
+
readonly precision: 1;
|
|
68
88
|
};
|
|
69
89
|
readonly systolic_bp: {
|
|
70
90
|
readonly table: "hrv";
|
|
@@ -90,6 +110,7 @@ export declare const METRIC_METADATA: Readonly<{
|
|
|
90
110
|
readonly sampling_minutes: 10;
|
|
91
111
|
readonly exposure: "full";
|
|
92
112
|
readonly baselineDailyAggregate: "avg";
|
|
113
|
+
readonly precision: 1;
|
|
93
114
|
};
|
|
94
115
|
readonly spo2: {
|
|
95
116
|
readonly table: "spo2";
|
|
@@ -97,6 +118,7 @@ export declare const METRIC_METADATA: Readonly<{
|
|
|
97
118
|
readonly sampling_minutes: 30;
|
|
98
119
|
readonly exposure: "full";
|
|
99
120
|
readonly baselineDailyAggregate: "avg";
|
|
121
|
+
readonly precision: 1;
|
|
100
122
|
};
|
|
101
123
|
readonly temp_c: {
|
|
102
124
|
readonly table: "temperature";
|
|
@@ -104,6 +126,7 @@ export declare const METRIC_METADATA: Readonly<{
|
|
|
104
126
|
readonly sampling_minutes: 30;
|
|
105
127
|
readonly exposure: "full";
|
|
106
128
|
readonly baselineDailyAggregate: "avg";
|
|
129
|
+
readonly precision: 1;
|
|
107
130
|
};
|
|
108
131
|
readonly activity_steps: {
|
|
109
132
|
readonly table: "activity";
|
|
@@ -170,6 +193,24 @@ export declare function getBaselineMetricIds(): MetricId[];
|
|
|
170
193
|
* field is genuinely absent — not `undefined` — on entries without one.
|
|
171
194
|
*/
|
|
172
195
|
export declare function baselineAggregateFor(id: MetricId): BaselineDailyAggregate | undefined;
|
|
196
|
+
/**
|
|
197
|
+
* Reporting precision for a metric, or `undefined` when unstated.
|
|
198
|
+
*
|
|
199
|
+
* Accessor rather than a property read for the same reason as
|
|
200
|
+
* `baselineAggregateFor`: the `as const` registry narrows each entry to its
|
|
201
|
+
* own literal type, and the field is genuinely absent — not `undefined` — on
|
|
202
|
+
* entries without one.
|
|
203
|
+
*/
|
|
204
|
+
export declare function precisionFor(id: MetricId): number | undefined;
|
|
205
|
+
/**
|
|
206
|
+
* Does this metric's data support a continuous intra-day curve?
|
|
207
|
+
*
|
|
208
|
+
* `false` when the device reports in steps coarse enough that a line between
|
|
209
|
+
* readings would be drawn detail the hardware never measured — the temp
|
|
210
|
+
* screen's mark rule (sprint6 §7): whole-degree ⇒ discrete marks, no
|
|
211
|
+
* segments.
|
|
212
|
+
*/
|
|
213
|
+
export declare function supportsContinuousCurve(id: MetricId): boolean;
|
|
173
214
|
/** Baseline windows computed per metric (Sprint 5 §7). */
|
|
174
215
|
export declare const BASELINE_WINDOW_DAYS: readonly [7, 30, 90];
|
|
175
216
|
export type BaselineWindowDays = (typeof BASELINE_WINDOW_DAYS)[number];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metric_metadata.d.ts","sourceRoot":"","sources":["../../src/core/metric_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,gBAAgB,CAAA;AAEtD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,aAAa,CAAA;AAE1D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;AAE9D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,gBAAgB,EAAE,qBAAqB,CAAA;IACvC,QAAQ,EAAE,cAAc,CAAA;IACxB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;
|
|
1
|
+
{"version":3,"file":"metric_metadata.d.ts","sourceRoot":"","sources":["../../src/core/metric_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAE1C,MAAM,MAAM,cAAc,GAAG,MAAM,GAAG,gBAAgB,CAAA;AAEtD;;;;GAIG;AACH,MAAM,MAAM,qBAAqB,GAAG,MAAM,GAAG,aAAa,CAAA;AAE1D;;;;;;;;;;;GAWG;AACH,MAAM,MAAM,sBAAsB,GAAG,KAAK,GAAG,KAAK,GAAG,SAAS,CAAA;AAE9D,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,SAAS,CAAA;IAChB,MAAM,EAAE,MAAM,CAAA;IACd;;;;OAIG;IACH,gBAAgB,EAAE,qBAAqB,CAAA;IACvC,QAAQ,EAAE,cAAc,CAAA;IACxB;;;;OAIG;IACH,sBAAsB,CAAC,EAAE,sBAAsB,CAAA;IAC/C;;;;;;;;;;;;;;;;OAgBG;IACH,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;;;GAKG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;EAeuC,CAAA;AAEnE,MAAM,MAAM,QAAQ,GAAG,MAAM,OAAO,eAAe,CAAA;AAEnD;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAErD;AAED;;;GAGG;AACH,wBAAgB,mBAAmB,IAAI,QAAQ,EAAE,CAEhD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,QAAQ,EAAE,CAIjD;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,GACX,sBAAsB,GAAG,SAAS,CAGpC;AAED;;;;;;;GAOG;AACH,wBAAgB,YAAY,CAAC,EAAE,EAAE,QAAQ,GAAG,MAAM,GAAG,SAAS,CAG7D;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,QAAQ,GAAG,OAAO,CAG7D;AAED,0DAA0D;AAC1D,eAAO,MAAM,oBAAoB,sBAAuB,CAAA;AACxD,MAAM,MAAM,kBAAkB,GAAG,CAAC,OAAO,oBAAoB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEtE;;;;;GAKG;AACH,eAAO,MAAM,iBAAiB,KAAK,CAAA"}
|
|
@@ -14,14 +14,14 @@
|
|
|
14
14
|
* change (bump metadata; add DDL column if new).
|
|
15
15
|
*/
|
|
16
16
|
export const METRIC_METADATA = Object.freeze({
|
|
17
|
-
hrv_ms: { table: 'hrv', column: 'hrv_ms', sampling_minutes: 60, exposure: 'full', baselineDailyAggregate: 'avg' },
|
|
18
|
-
stress: { table: 'hrv', column: 'stress', sampling_minutes: 60, exposure: 'full', baselineDailyAggregate: 'avg' },
|
|
17
|
+
hrv_ms: { table: 'hrv', column: 'hrv_ms', sampling_minutes: 60, exposure: 'full', baselineDailyAggregate: 'avg', precision: 1 },
|
|
18
|
+
stress: { table: 'hrv', column: 'stress', sampling_minutes: 60, exposure: 'full', baselineDailyAggregate: 'avg', precision: 1 },
|
|
19
19
|
systolic_bp: { table: 'hrv', column: 'systolic_bp', sampling_minutes: 60, exposure: 'collected_only' },
|
|
20
20
|
diastolic_bp: { table: 'hrv', column: 'diastolic_bp', sampling_minutes: 60, exposure: 'collected_only' },
|
|
21
21
|
vascular_aging: { table: 'hrv', column: 'vascular_aging', sampling_minutes: 60, exposure: 'collected_only' },
|
|
22
|
-
hr_bpm: { table: 'heart_rate', column: 'bpm', sampling_minutes: 10, exposure: 'full', baselineDailyAggregate: 'avg' },
|
|
23
|
-
spo2: { table: 'spo2', column: 'spo2', sampling_minutes: 30, exposure: 'full', baselineDailyAggregate: 'avg' },
|
|
24
|
-
temp_c: { table: 'temperature', column: 'temp_c', sampling_minutes: 30, exposure: 'full', baselineDailyAggregate: 'avg' },
|
|
22
|
+
hr_bpm: { table: 'heart_rate', column: 'bpm', sampling_minutes: 10, exposure: 'full', baselineDailyAggregate: 'avg', precision: 1 },
|
|
23
|
+
spo2: { table: 'spo2', column: 'spo2', sampling_minutes: 30, exposure: 'full', baselineDailyAggregate: 'avg', precision: 1 },
|
|
24
|
+
temp_c: { table: 'temperature', column: 'temp_c', sampling_minutes: 30, exposure: 'full', baselineDailyAggregate: 'avg', precision: 1 },
|
|
25
25
|
activity_steps: { table: 'activity', column: 'steps', sampling_minutes: 1, exposure: 'full', baselineDailyAggregate: 'sum' },
|
|
26
26
|
calories: { table: 'activity_bucket', column: 'calories', sampling_minutes: 10, exposure: 'full' },
|
|
27
27
|
distance_km: { table: 'activity_bucket', column: 'distance_km', sampling_minutes: 10, exposure: 'full' },
|
|
@@ -63,6 +63,30 @@ export function baselineAggregateFor(id) {
|
|
|
63
63
|
const entry = METRIC_METADATA[id];
|
|
64
64
|
return entry.baselineDailyAggregate;
|
|
65
65
|
}
|
|
66
|
+
/**
|
|
67
|
+
* Reporting precision for a metric, or `undefined` when unstated.
|
|
68
|
+
*
|
|
69
|
+
* Accessor rather than a property read for the same reason as
|
|
70
|
+
* `baselineAggregateFor`: the `as const` registry narrows each entry to its
|
|
71
|
+
* own literal type, and the field is genuinely absent — not `undefined` — on
|
|
72
|
+
* entries without one.
|
|
73
|
+
*/
|
|
74
|
+
export function precisionFor(id) {
|
|
75
|
+
const entry = METRIC_METADATA[id];
|
|
76
|
+
return entry.precision;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Does this metric's data support a continuous intra-day curve?
|
|
80
|
+
*
|
|
81
|
+
* `false` when the device reports in steps coarse enough that a line between
|
|
82
|
+
* readings would be drawn detail the hardware never measured — the temp
|
|
83
|
+
* screen's mark rule (sprint6 §7): whole-degree ⇒ discrete marks, no
|
|
84
|
+
* segments.
|
|
85
|
+
*/
|
|
86
|
+
export function supportsContinuousCurve(id) {
|
|
87
|
+
const p = precisionFor(id);
|
|
88
|
+
return p !== undefined && p < 1;
|
|
89
|
+
}
|
|
66
90
|
/** Baseline windows computed per metric (Sprint 5 §7). */
|
|
67
91
|
export const BASELINE_WINDOW_DAYS = [7, 30, 90];
|
|
68
92
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"metric_metadata.js","sourceRoot":"","sources":["../../src/core/metric_metadata.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;
|
|
1
|
+
{"version":3,"file":"metric_metadata.js","sourceRoot":"","sources":["../../src/core/metric_metadata.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/factory.d.ts
CHANGED
|
@@ -24,6 +24,7 @@ import type { GetHRVInput } from './impls/hrv';
|
|
|
24
24
|
import type { GetInsightsInput } from './impls/insights';
|
|
25
25
|
import type { GetSleepSummaryInput } from './impls/sleep';
|
|
26
26
|
import type { GetSpO2Input } from './impls/spo2';
|
|
27
|
+
import type { GetTemperatureInput } from './impls/temperature';
|
|
27
28
|
import type { AnalyticsToolsConfig, AuditWriter, ToolContext } from './types';
|
|
28
29
|
import { makeTool } from './wrap';
|
|
29
30
|
export interface AnalyticsToolMap {
|
|
@@ -33,6 +34,7 @@ export interface AnalyticsToolMap {
|
|
|
33
34
|
compareTrend: ReturnType<typeof makeTool<CompareTrendInput>>;
|
|
34
35
|
detectAnomaly: ReturnType<typeof makeTool<DetectAnomalyInput>>;
|
|
35
36
|
getSpO2: ReturnType<typeof makeTool<GetSpO2Input>>;
|
|
37
|
+
getTemperature: ReturnType<typeof makeTool<GetTemperatureInput>>;
|
|
36
38
|
getInsights: ReturnType<typeof makeTool<GetInsightsInput>>;
|
|
37
39
|
}
|
|
38
40
|
export interface AnalyticsToolsHandle {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/tools/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;
|
|
1
|
+
{"version":3,"file":"factory.d.ts","sourceRoot":"","sources":["../../src/tools/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kBAAkB,CAAA;AAC7D,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,iBAAiB,CAAA;AACzD,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAA;AACxD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AACxD,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA;AACzD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,qBAAqB,CAAA;AAG9D,OAAO,KAAK,EACV,oBAAoB,EACpB,WAAW,EAEX,WAAW,EACZ,MAAM,SAAS,CAAA;AAoChB,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAwBjC,MAAM,WAAW,gBAAgB;IAC/B,MAAM,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,WAAW,CAAC,CAAC,CAAA;IAChD,eAAe,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,oBAAoB,CAAC,CAAC,CAAA;IAClE,gBAAgB,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,qBAAqB,CAAC,CAAC,CAAA;IACpE,YAAY,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAC5D,aAAa,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,kBAAkB,CAAC,CAAC,CAAA;IAC9D,OAAO,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAA;IAClD,cAAc,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,mBAAmB,CAAC,CAAC,CAAA;IAChE,WAAW,EAAE,UAAU,CAAC,OAAO,QAAQ,CAAC,gBAAgB,CAAC,CAAC,CAAA;CAC3D;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,gBAAgB,CAAA;IACvB,UAAU,EAAE,CAAC,GAAG,EAAE,WAAW,GAAG,IAAI,KAAK,IAAI,CAAA;IAC7C,WAAW,EAAE,WAAW,CAAA;IACxB,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAC3B;AAED,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,oBAAoB,GAC3B,oBAAoB,CA+GtB"}
|
package/dist/tools/factory.js
CHANGED
|
@@ -26,6 +26,7 @@ import { getHRV, getHRVInputSchema } from './impls/hrv';
|
|
|
26
26
|
import { getInsights, getInsightsInputSchema, } from './impls/insights';
|
|
27
27
|
import { getSleepSummary, getSleepSummaryInputSchema, } from './impls/sleep';
|
|
28
28
|
import { getSpO2, getSpO2InputSchema } from './impls/spo2';
|
|
29
|
+
import { getTemperature, getTemperatureInputSchema } from './impls/temperature';
|
|
29
30
|
import { createRateLimiter } from './rate-limit';
|
|
30
31
|
import { DEFAULT_OUTPUT_BUDGET, DEFAULT_RATE_LIMIT, } from './types';
|
|
31
32
|
import { makeTool } from './wrap';
|
|
@@ -46,6 +47,7 @@ const DESCRIPTIONS = {
|
|
|
46
47
|
getSpO2: 'Return nightly blood-oxygen averages during sleep for a user, '
|
|
47
48
|
+ 'with how many brief low moments occurred each night and how it '
|
|
48
49
|
+ 'compares to their usual range. Args: userId, days (1..90).',
|
|
50
|
+
getTemperature: 'Return a user\'s daily temperature in Celsius — average, high and low per day — alongside their own usual range. Says how it compares to their usual, never whether it is high. Args: userId, days (1..90).',
|
|
49
51
|
getInsights: 'Return recent AI-generated insights for a user. Args: userId, '
|
|
50
52
|
+ 'days (1..30, default 7), optional severity (info|warn|urgent).',
|
|
51
53
|
};
|
|
@@ -91,6 +93,13 @@ export function createAnalyticsTools(config) {
|
|
|
91
93
|
inputSchema: getSpO2InputSchema,
|
|
92
94
|
impl: getSpO2,
|
|
93
95
|
}),
|
|
96
|
+
getTemperature: makeTool({
|
|
97
|
+
...shared,
|
|
98
|
+
name: 'getTemperature',
|
|
99
|
+
description: DESCRIPTIONS.getTemperature,
|
|
100
|
+
inputSchema: getTemperatureInputSchema,
|
|
101
|
+
impl: getTemperature,
|
|
102
|
+
}),
|
|
94
103
|
getHRV: makeTool({
|
|
95
104
|
...shared,
|
|
96
105
|
name: 'getHRV',
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/tools/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;
|
|
1
|
+
{"version":3,"file":"factory.js","sourceRoot":"","sources":["../../src/tools/factory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAkBH,OAAO,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAC3C,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAClD,OAAO,EACL,gBAAgB,EAEhB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EAEb,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,YAAY,EAEZ,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,MAAM,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAA;AACvD,OAAO,EACL,WAAW,EAEX,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,eAAe,EAEf,0BAA0B,GAC3B,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAA;AAC1D,OAAO,EAAE,cAAc,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAC/E,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAA;AAChD,OAAO,EACL,qBAAqB,EACrB,kBAAkB,GACnB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAA;AAEjC,MAAM,YAAY,GAAG;IACnB,MAAM,EAAE,oEAAoE;UACxE,mDAAmD;IACvD,eAAe,EAAE,0DAA0D;UACvE,mDAAmD;IACvD,gBAAgB,EAAE,2DAA2D;UACzE,mDAAmD;IACvD,YAAY,EAAE,6DAA6D;UACvE,8DAA8D;UAC9D,kDAAkD;IACtD,aAAa,EAAE,+DAA+D;UAC1E,uEAAuE;UACvE,qEAAqE;UACrE,oCAAoC;IACxC,OAAO,EAAE,gEAAgE;UACrE,iEAAiE;UACjE,4DAA4D;IAChE,cAAc,EAAE,6MAA6M;IAC7N,WAAW,EAAE,gEAAgE;UACzE,gEAAgE;CAC5D,CAAA;AAoBV,MAAM,UAAU,oBAAoB,CAClC,MAA4B;IAE5B,MAAM,MAAM,GAAiB;QAC3B,GAAG,qBAAqB;QACxB,GAAG,CAAC,MAAM,CAAC,YAAY,IAAI,EAAE,CAAC;KAC/B,CAAA;IAED,MAAM,WAAW,GACb,MAAM,CAAC,SAAS,KAAK,KAAK;QAC1B,CAAC,CAAC,IAAI;QACN,CAAC,CAAC,iBAAiB,CAAC;YAChB,MAAM,EAAE,MAAM,CAAC,SAAS,IAAI,kBAAkB;YAC9C,KAAK,EAAE,MAAM,CAAC,KAAK;SACpB,CAAC,CAAA;IAER,MAAM,SAAS,GACX,MAAM,CAAC,SAAS;WACb,oBAAoB,CAAC,MAAM,CAAC,SAAS,EAAE;YACxC,qBAAqB,EAAE,MAAM,CAAC,qBAAqB;SACpD,CAAC,CAAA;IAEN,MAAM,KAAK,GAAG,iBAAiB,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,OAAO,EAAE,MAAM,CAAC,KAAK,EAAE,OAAO,IAAI,IAAI;QACtC,SAAS,EAAE,MAAM,CAAC,KAAK,EAAE,SAAS;QAClC,eAAe,EAAE,MAAM,CAAC,KAAK,EAAE,eAAe;QAC9C,MAAM,EAAE,MAAM,CAAC,MAAM;KACtB,CAAC,CAAA;IAEF,IAAI,UAAU,GAAuB,IAAI,CAAA;IACzC,MAAM,WAAW,GAAG,GAAuB,EAAE,CAAC,UAAU,CAAA;IAExD,MAAM,MAAM,GAAG;QACb,SAAS,EAAE,MAAM,CAAC,SAAS;QAC3B,SAAS;QACT,WAAW;QACX,KAAK;QACL,MAAM;QACN,MAAM,EAAE,MAAM,CAAC,MAAM;QACrB,WAAW;QACX,KAAK,EAAE,MAAM,CAAC,KAAK;KACpB,CAAA;IAED,MAAM,KAAK,GAAqB;QAC9B,OAAO,EAAE,QAAQ,CAAC;YAChB,GAAG,MAAM;YACT,IAAI,EAAE,SAAS;YACf,WAAW,EAAE,YAAY,CAAC,OAAO;YACjC,WAAW,EAAE,kBAAkB;YAC/B,IAAI,EAAE,OAAO;SACd,CAAC;QACF,cAAc,EAAE,QAAQ,CAAC;YACvB,GAAG,MAAM;YACT,IAAI,EAAE,gBAAgB;YACtB,WAAW,EAAE,YAAY,CAAC,cAAc;YACxC,WAAW,EAAE,yBAAyB;YACtC,IAAI,EAAE,cAAc;SACrB,CAAC;QACF,MAAM,EAAE,QAAQ,CAAC;YACf,GAAG,MAAM;YACT,IAAI,EAAE,QAAQ;YACd,WAAW,EAAE,YAAY,CAAC,MAAM;YAChC,WAAW,EAAE,iBAAiB;YAC9B,IAAI,EAAE,MAAM;SACb,CAAC;QACF,eAAe,EAAE,QAAQ,CAAC;YACxB,GAAG,MAAM;YACT,IAAI,EAAE,iBAAiB;YACvB,WAAW,EAAE,YAAY,CAAC,eAAe;YACzC,WAAW,EAAE,0BAA0B;YACvC,IAAI,EAAE,eAAe;SACtB,CAAC;QACF,gBAAgB,EAAE,QAAQ,CAAC;YACzB,GAAG,MAAM;YACT,IAAI,EAAE,kBAAkB;YACxB,WAAW,EAAE,YAAY,CAAC,gBAAgB;YAC1C,WAAW,EAAE,2BAA2B;YACxC,IAAI,EAAE,gBAAgB;SACvB,CAAC;QACF,YAAY,EAAE,QAAQ,CAAC;YACrB,GAAG,MAAM;YACT,IAAI,EAAE,cAAc;YACpB,WAAW,EAAE,YAAY,CAAC,YAAY;YACtC,WAAW,EAAE,uBAAuB;YACpC,IAAI,EAAE,YAAY;SACnB,CAAC;QACF,aAAa,EAAE,QAAQ,CAAC;YACtB,GAAG,MAAM;YACT,IAAI,EAAE,eAAe;YACrB,WAAW,EAAE,YAAY,CAAC,aAAa;YACvC,WAAW,EAAE,wBAAwB;YACrC,IAAI,EAAE,aAAa;SACpB,CAAC;QACF,WAAW,EAAE,QAAQ,CAAC;YACpB,GAAG,MAAM;YACT,IAAI,EAAE,aAAa;YACnB,WAAW,EAAE,YAAY,CAAC,WAAW;YACrC,WAAW,EAAE,sBAAsB;YACnC,IAAI,EAAE,WAAW;SAClB,CAAC;KACH,CAAA;IAED,OAAO;QACL,KAAK;QACL,UAAU,CAAC,GAAG;YACZ,UAAU,GAAG,GAAG,CAAA;QAClB,CAAC;QACD,WAAW,EAAE,KAAK;QAClB,KAAK,CAAC,KAAK;YACT,MAAM,KAAK,CAAC,KAAK,EAAE,CAAA;QACrB,CAAC;KACF,CAAA;AACH,CAAC"}
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
* also catches `desaturations` and `desaturating`. Inflections are still
|
|
22
22
|
* listed explicitly where they read differently, for documentation value.
|
|
23
23
|
*/
|
|
24
|
-
export declare const BANNED_MEDICAL_VOCABULARY: readonly ["desaturation", "desaturated", "desaturating", "hypoxia", "hypoxic", "hypoxemia", "apnea", "apneic", "arrhythmia", "arrhythmic", "bradycardia", "tachycardia", "ischemia", "ischemic"];
|
|
24
|
+
export declare const BANNED_MEDICAL_VOCABULARY: readonly ["desaturation", "desaturated", "desaturating", "hypoxia", "hypoxic", "hypoxemia", "apnea", "apneic", "arrhythmia", "arrhythmic", "bradycardia", "tachycardia", "ischemia", "ischemic", "febrile", "pyrexia", "rmssd", "sdnn", "autonomic", "sympathetic", "parasympathetic", "vagal", "afib"];
|
|
25
25
|
export type BannedTerm = (typeof BANNED_MEDICAL_VOCABULARY)[number];
|
|
26
26
|
/**
|
|
27
27
|
* What to write instead. Keys are the clinical phrasing a formatter author
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-guidelines.d.ts","sourceRoot":"","sources":["../../../src/tools/formatters/copy-guidelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,
|
|
1
|
+
{"version":3,"file":"copy-guidelines.d.ts","sourceRoot":"","sources":["../../../src/tools/formatters/copy-guidelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;GAMG;AACH,eAAO,MAAM,yBAAyB,ySA6B5B,CAAA;AAEV,MAAM,MAAM,UAAU,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAA;AAEnE;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAYrD,CAAA;AAED,uDAAuD;AACvD,qBAAa,kBAAmB,SAAQ,KAAK;IAC3C,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAA;IAC9B,QAAQ,CAAC,KAAK,EAAE,MAAM,EAAE,CAAA;gBAEZ,aAAa,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE;CAUnD;AAWD,4EAA4E;AAC5E,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEnD;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CAK1E;AAED;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAY3D"}
|
|
@@ -36,6 +36,20 @@ export const BANNED_MEDICAL_VOCABULARY = [
|
|
|
36
36
|
'tachycardia',
|
|
37
37
|
'ischemia',
|
|
38
38
|
'ischemic',
|
|
39
|
+
// sprint6 §6 — temperature. Ziva says "running warm", never a diagnosis.
|
|
40
|
+
'febrile',
|
|
41
|
+
'pyrexia',
|
|
42
|
+
// sprint6 §6 — HRV. The metric names are as clinical as the conditions:
|
|
43
|
+
// an LLM handed "RMSSD" in context will hand it back to the user, and a
|
|
44
|
+
// grandmother reading "reduced vagal tone" hears a diagnosis nobody made.
|
|
45
|
+
// `arrhythmia`/`arrhythmic` were already banned above.
|
|
46
|
+
'rmssd',
|
|
47
|
+
'sdnn',
|
|
48
|
+
'autonomic',
|
|
49
|
+
'sympathetic',
|
|
50
|
+
'parasympathetic',
|
|
51
|
+
'vagal',
|
|
52
|
+
'afib',
|
|
39
53
|
];
|
|
40
54
|
/**
|
|
41
55
|
* What to write instead. Keys are the clinical phrasing a formatter author
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"copy-guidelines.js","sourceRoot":"","sources":["../../../src/tools/formatters/copy-guidelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,cAAc;IACd,aAAa;IACb,cAAc;IACd,SAAS;IACT,SAAS;IACT,WAAW;IACX,OAAO;IACP,QAAQ;IACR,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,aAAa;IACb,UAAU;IACV,UAAU;
|
|
1
|
+
{"version":3,"file":"copy-guidelines.js","sourceRoot":"","sources":["../../../src/tools/formatters/copy-guidelines.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG;IACvC,cAAc;IACd,aAAa;IACb,cAAc;IACd,SAAS;IACT,SAAS;IACT,WAAW;IACX,OAAO;IACP,QAAQ;IACR,YAAY;IACZ,YAAY;IACZ,aAAa;IACb,aAAa;IACb,UAAU;IACV,UAAU;IACV,yEAAyE;IACzE,SAAS;IACT,SAAS;IACT,wEAAwE;IACxE,wEAAwE;IACxE,0EAA0E;IAC1E,uDAAuD;IACvD,OAAO;IACP,MAAM;IACN,WAAW;IACX,aAAa;IACb,iBAAiB;IACjB,OAAO;IACP,MAAM;CACE,CAAA;AAIV;;;;;;GAMG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAA2B;IACxD,qBAAqB,EAAE,YAAY;IACnC,oBAAoB,EAAE,kBAAkB;IACxC,qBAAqB,EAAE,mBAAmB;IAC1C,eAAe,EAAE,mBAAmB;IACpC,cAAc,EAAE,kBAAkB;IAClC,WAAW,EAAE,YAAY;IACzB,SAAS,EAAE,YAAY;IACvB,OAAO,EAAE,qBAAqB;IAC9B,aAAa,EAAE,iBAAiB;IAChC,aAAa,EAAE,iBAAiB;IAChC,YAAY,EAAE,qBAAqB;CACpC,CAAA;AAED,uDAAuD;AACvD,MAAM,OAAO,kBAAmB,SAAQ,KAAK;IAI3C,YAAY,aAAqB,EAAE,KAAe;QAChD,KAAK,CACH,cAAc,aAAa,uCAAuC;cAChE,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,kDAAkD;cACrE,0DAA0D,CAC7D,CAAA;QACD,IAAI,CAAC,IAAI,GAAG,oBAAoB,CAAA;QAChC,IAAI,CAAC,aAAa,GAAG,aAAa,CAAA;QAClC,IAAI,CAAC,KAAK,GAAG,KAAK,CAAA;IACpB,CAAC;CACF;AAED;;;;GAIG;AACH,MAAM,QAAQ,GAAmC,yBAAyB,CAAC,GAAG,CAC5E,IAAI,CAAC,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,MAAM,CAAC,MAAM,IAAI,EAAE,EAAE,IAAI,CAAC,EAAE,CAAC,CACvD,CAAA;AAED,4EAA4E;AAC5E,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAA;AAC/D,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,gBAAgB,CAAC,IAAY,EAAE,aAAqB;IAClE,MAAM,KAAK,GAAG,YAAY,CAAC,IAAI,CAAC,CAAA;IAChC,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrB,MAAM,IAAI,kBAAkB,CAAC,aAAa,EAAE,KAAK,CAAC,CAAA;IACpD,CAAC;AACH,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,sBAAsB,CAAC,IAAY;IACjD,6DAA6D;IAC7D,yCAAyC;IACzC,MAAM,OAAO,GAAG,MAAM,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,MAAM,CAAC,CAAA;IACnF,IAAI,GAAG,GAAG,IAAI,CAAA;IACd,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,GAAG,GAAG,GAAG,CAAC,OAAO,CACf,IAAI,MAAM,CAAC,MAAM,MAAM,KAAK,EAAE,KAAK,CAAC,EACpC,kBAAkB,CAAC,MAAM,CAAC,CAC3B,CAAA;IACH,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ToolImpl } from '../types';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
export declare const getTemperatureInputSchema: z.ZodObject<{
|
|
4
|
+
userId: z.ZodString;
|
|
5
|
+
days: z.ZodNumber;
|
|
6
|
+
}, "strip", z.ZodTypeAny, {
|
|
7
|
+
userId: string;
|
|
8
|
+
days: number;
|
|
9
|
+
}, {
|
|
10
|
+
userId: string;
|
|
11
|
+
days: number;
|
|
12
|
+
}>;
|
|
13
|
+
export type GetTemperatureInput = z.infer<typeof getTemperatureInputSchema>;
|
|
14
|
+
/**
|
|
15
|
+
* Daily temperature against the user's own usual range (sprint6 §6).
|
|
16
|
+
*
|
|
17
|
+
* Two things this deliberately does not do:
|
|
18
|
+
*
|
|
19
|
+
* - It never says whether a temperature is high. "Running warm" is a
|
|
20
|
+
* comparison to the user's own band; a threshold judgement belongs to
|
|
21
|
+
* the rules engine, which the user configures. A tool that editorialises
|
|
22
|
+
* teaches the model to do the same.
|
|
23
|
+
* - It never prints more decimals than the ring measured. Today's hardware
|
|
24
|
+
* reports whole degrees (`precisionFor('temp_c') === 1`), so rendering
|
|
25
|
+
* "36.8" off a whole-degree reading would be inventing detail. The
|
|
26
|
+
* column is DECIMAL(4,1) so a finer device needs no migration — the
|
|
27
|
+
* formatter follows the device, not the column.
|
|
28
|
+
*/
|
|
29
|
+
export declare const getTemperature: ToolImpl<GetTemperatureInput>;
|
|
30
|
+
//# sourceMappingURL=temperature.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temperature.d.ts","sourceRoot":"","sources":["../../../src/tools/impls/temperature.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,QAAQ,EAAc,MAAM,UAAU,CAAA;AACpD,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAKvB,eAAO,MAAM,yBAAyB;;;;;;;;;EAGpC,CAAA;AAEF,MAAM,MAAM,mBAAmB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,yBAAyB,CAAC,CAAA;AAe3E;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,cAAc,EAAE,QAAQ,CAAC,mBAAmB,CAyCxD,CAAA"}
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import { z } from 'zod';
|
|
2
|
+
import { precisionFor } from '../../core/metric_metadata';
|
|
3
|
+
import { assertNoBanTerms, formatBytes } from '../formatters';
|
|
4
|
+
export const getTemperatureInputSchema = z.object({
|
|
5
|
+
userId: z.string(),
|
|
6
|
+
days: z.number().int().min(1).max(90),
|
|
7
|
+
});
|
|
8
|
+
/**
|
|
9
|
+
* Daily temperature against the user's own usual range (sprint6 §6).
|
|
10
|
+
*
|
|
11
|
+
* Two things this deliberately does not do:
|
|
12
|
+
*
|
|
13
|
+
* - It never says whether a temperature is high. "Running warm" is a
|
|
14
|
+
* comparison to the user's own band; a threshold judgement belongs to
|
|
15
|
+
* the rules engine, which the user configures. A tool that editorialises
|
|
16
|
+
* teaches the model to do the same.
|
|
17
|
+
* - It never prints more decimals than the ring measured. Today's hardware
|
|
18
|
+
* reports whole degrees (`precisionFor('temp_c') === 1`), so rendering
|
|
19
|
+
* "36.8" off a whole-degree reading would be inventing detail. The
|
|
20
|
+
* column is DECIMAL(4,1) so a finer device needs no migration — the
|
|
21
|
+
* formatter follows the device, not the column.
|
|
22
|
+
*/
|
|
23
|
+
export const getTemperature = async (input, ctx) => {
|
|
24
|
+
const rows = await ctx.analytics.execute(`SELECT date_trunc('day', ts)::VARCHAR AS day,
|
|
25
|
+
AVG(temp_c)::DOUBLE AS avg_temp,
|
|
26
|
+
MAX(temp_c)::DOUBLE AS hi_temp,
|
|
27
|
+
MIN(temp_c)::DOUBLE AS lo_temp
|
|
28
|
+
FROM v_temperature
|
|
29
|
+
WHERE user_id = $userId AND brand = $brand AND family_id = $familyId
|
|
30
|
+
AND ts >= now() - INTERVAL (CAST($days AS BIGINT)) DAY
|
|
31
|
+
AND temp_c IS NOT NULL
|
|
32
|
+
GROUP BY 1 ORDER BY 1`, {
|
|
33
|
+
userId: input.userId,
|
|
34
|
+
brand: ctx.brand,
|
|
35
|
+
familyId: ctx.familyId,
|
|
36
|
+
days: input.days,
|
|
37
|
+
});
|
|
38
|
+
if (rows.length === 0)
|
|
39
|
+
return finalize('No temperature data for the requested window.', 0);
|
|
40
|
+
const baseline = await readBaseline(ctx, input.userId);
|
|
41
|
+
const decimals = decimalsFor(precisionFor('temp_c'));
|
|
42
|
+
const daily = rows
|
|
43
|
+
.map(r => ` ${r.day}: ${r.avg_temp.toFixed(decimals)}°C `
|
|
44
|
+
+ `(low ${r.lo_temp.toFixed(decimals)}, high ${r.hi_temp.toFixed(decimals)})`)
|
|
45
|
+
.join('\n');
|
|
46
|
+
const usual = baseline === null
|
|
47
|
+
? ' usual range: not established yet'
|
|
48
|
+
: ` usual range: ${baseline.p10.toFixed(decimals)}–${baseline.p90.toFixed(decimals)}°C `
|
|
49
|
+
+ `(typical ${baseline.p50.toFixed(decimals)})`;
|
|
50
|
+
return finalize(`Temperature in °C, last ${input.days} days:\n${daily}\n${usual}`, rows.length);
|
|
51
|
+
};
|
|
52
|
+
/**
|
|
53
|
+
* The user's own band, or null before the 20-day gate passes.
|
|
54
|
+
*
|
|
55
|
+
* A failure here degrades to "not established yet" rather than failing the
|
|
56
|
+
* whole call: the daily numbers are useful without the comparison, and a
|
|
57
|
+
* tool that throws because a secondary read failed gives the model nothing.
|
|
58
|
+
*/
|
|
59
|
+
async function readBaseline(ctx, userId) {
|
|
60
|
+
try {
|
|
61
|
+
const rows = await ctx.analytics.execute(`SELECT p10::DOUBLE AS p10, p50::DOUBLE AS p50, p90::DOUBLE AS p90
|
|
62
|
+
FROM user_baseline
|
|
63
|
+
WHERE user_id = $userId AND brand = $brand AND family_id = $familyId
|
|
64
|
+
AND metric = 'temp_c' AND window_days = 30`, { userId, brand: ctx.brand, familyId: ctx.familyId });
|
|
65
|
+
return rows[0] ?? null;
|
|
66
|
+
}
|
|
67
|
+
catch {
|
|
68
|
+
return null;
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
/** Decimal places justified by what the device reports. */
|
|
72
|
+
function decimalsFor(precision) {
|
|
73
|
+
if (precision === undefined || precision >= 1)
|
|
74
|
+
return 0;
|
|
75
|
+
return Math.min(2, Math.ceil(-Math.log10(precision)));
|
|
76
|
+
}
|
|
77
|
+
function finalize(text, rowCount) {
|
|
78
|
+
// principle 37 — guarded on the return path, like every other formatter.
|
|
79
|
+
// The temperature vocabulary is the point: sprint6 §6 added `febrile` and
|
|
80
|
+
// `pyrexia` because "running warm" is the register Ziva speaks.
|
|
81
|
+
assertNoBanTerms(text, 'getTemperature');
|
|
82
|
+
return { text, rowCount, bytes: formatBytes(text) };
|
|
83
|
+
}
|
|
84
|
+
//# sourceMappingURL=temperature.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"temperature.js","sourceRoot":"","sources":["../../../src/tools/impls/temperature.ts"],"names":[],"mappings":"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"}
|
package/dist/tools/index.d.ts
CHANGED
|
@@ -9,6 +9,7 @@ export { compareTrend, type CompareTrendInput, compareTrendInputSchema, } from '
|
|
|
9
9
|
export { getHRV, type GetHRVInput, getHRVInputSchema, } from './impls/hrv';
|
|
10
10
|
export { getInsights, type GetInsightsInput, getInsightsInputSchema, } from './impls/insights';
|
|
11
11
|
export { getSleepSummary, type GetSleepSummaryInput, getSleepSummaryInputSchema, } from './impls/sleep';
|
|
12
|
+
export { getTemperature, type GetTemperatureInput, getTemperatureInputSchema, } from './impls/temperature';
|
|
12
13
|
export * from './rate-limit';
|
|
13
14
|
export * from './types';
|
|
14
15
|
export * from './wrap';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AASA,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AAIzB,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,UAAU,EACf,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,MAAM,EACN,KAAK,WAAW,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,eAAe,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AAEvB,cAAc,QAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AASA,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AAIzB,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,yBAAyB,EACzB,KAAK,UAAU,EACf,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAChB,KAAK,qBAAqB,EAC1B,2BAA2B,GAC5B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EACb,KAAK,kBAAkB,EACvB,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,YAAY,EACZ,KAAK,iBAAiB,EACtB,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,MAAM,EACN,KAAK,WAAW,EAChB,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,WAAW,EACX,KAAK,gBAAgB,EACrB,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,eAAe,EACf,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,cAAc,EACd,KAAK,mBAAmB,EACxB,yBAAyB,GAC1B,MAAM,qBAAqB,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AAEvB,cAAc,QAAQ,CAAA"}
|
package/dist/tools/index.js
CHANGED
|
@@ -20,6 +20,7 @@ export { compareTrend, compareTrendInputSchema, } from './impls/compare';
|
|
|
20
20
|
export { getHRV, getHRVInputSchema, } from './impls/hrv';
|
|
21
21
|
export { getInsights, getInsightsInputSchema, } from './impls/insights';
|
|
22
22
|
export { getSleepSummary, getSleepSummaryInputSchema, } from './impls/sleep';
|
|
23
|
+
export { getTemperature, getTemperatureInputSchema, } from './impls/temperature';
|
|
23
24
|
export * from './rate-limit';
|
|
24
25
|
export * from './types';
|
|
25
26
|
export * from './wrap';
|
package/dist/tools/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,iEAAiE;AACjE,kEAAkE;AAClE,qEAAqE;AACrE,oEAAoE;AACpE,+DAA+D;AAC/D,yCAAyC;AAEzC,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,sEAAsE;AACtE,mEAAmE;AACnE,kCAAkC;AAClC,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,yBAAyB,EAEzB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAEhB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EAEb,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,YAAY,EAEZ,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,MAAM,EAEN,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,WAAW,EAEX,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,eAAe,EAEf,0BAA0B,GAC3B,MAAM,eAAe,CAAA;AACtB,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AAEvB,cAAc,QAAQ,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/tools/index.ts"],"names":[],"mappings":"AAAA,uDAAuD;AACvD,EAAE;AACF,iEAAiE;AACjE,kEAAkE;AAClE,qEAAqE;AACrE,oEAAoE;AACpE,+DAA+D;AAC/D,yCAAyC;AAEzC,cAAc,SAAS,CAAA;AACvB,cAAc,aAAa,CAAA;AAC3B,cAAc,UAAU,CAAA;AACxB,cAAc,WAAW,CAAA;AACzB,sEAAsE;AACtE,mEAAmE;AACnE,kCAAkC;AAClC,OAAO,EACL,sBAAsB,EACtB,gBAAgB,EAChB,yBAAyB,EAEzB,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,GACnB,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,gBAAgB,EAEhB,2BAA2B,GAC5B,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,aAAa,EAEb,wBAAwB,GACzB,MAAM,iBAAiB,CAAA;AAExB,OAAO,EACL,YAAY,EAEZ,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,MAAM,EAEN,iBAAiB,GAClB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,WAAW,EAEX,sBAAsB,GACvB,MAAM,kBAAkB,CAAA;AACzB,OAAO,EACL,eAAe,EAEf,0BAA0B,GAC3B,MAAM,eAAe,CAAA;AACtB,OAAO,EACL,cAAc,EAEd,yBAAyB,GAC1B,MAAM,qBAAqB,CAAA;AAC5B,cAAc,cAAc,CAAA;AAC5B,cAAc,SAAS,CAAA;AAEvB,cAAc,QAAQ,CAAA"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mongrov/analytics",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0",
|
|
4
4
|
"sideEffects": false,
|
|
5
5
|
"description": "DuckDB + R2 Iceberg local analytics for @mongrov apps",
|
|
6
6
|
"license": "MIT",
|
|
@@ -107,8 +107,8 @@
|
|
|
107
107
|
"typescript": "^5.9.3",
|
|
108
108
|
"vitest": "^2.1.9",
|
|
109
109
|
"zod": "^3.23.8",
|
|
110
|
-
"@mongrov/
|
|
111
|
-
"@mongrov/
|
|
110
|
+
"@mongrov/db": "0.3.0",
|
|
111
|
+
"@mongrov/types": "0.5.3"
|
|
112
112
|
},
|
|
113
113
|
"scripts": {
|
|
114
114
|
"build": "tsc -p tsconfig.build.json",
|