neoagent 1.4.5 → 1.4.6
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/package.json
CHANGED
|
@@ -581,6 +581,17 @@ function getAvailableTools(app, options = {}) {
|
|
|
581
581
|
},
|
|
582
582
|
required: ['image_path']
|
|
583
583
|
}
|
|
584
|
+
},
|
|
585
|
+
{
|
|
586
|
+
name: 'read_health_data',
|
|
587
|
+
description: 'Read the user\'s synced mobile health data (like steps, heart rate, sleep). If you omit metric_type, it returns a summary of all available metrics. If you provide a metric_type, it returns the most recent historical records for that metric.',
|
|
588
|
+
parameters: {
|
|
589
|
+
type: 'object',
|
|
590
|
+
properties: {
|
|
591
|
+
metric_type: { type: 'string', description: 'The specific metric to query, e.g. "Steps", "HeartRate", "SleepSession". Optional.' },
|
|
592
|
+
limit: { type: 'number', description: 'Maximum number of recent records to return if metric_type is specified (default 50, max 200).' }
|
|
593
|
+
}
|
|
594
|
+
}
|
|
584
595
|
}
|
|
585
596
|
];
|
|
586
597
|
|
|
@@ -801,6 +812,12 @@ async function executeTool(toolName, args, context, engine) {
|
|
|
801
812
|
return { success: true, key: args.key, message: 'Core memory updated' };
|
|
802
813
|
}
|
|
803
814
|
|
|
815
|
+
case 'read_health_data': {
|
|
816
|
+
const { readHealthData } = require('../health/ingestion');
|
|
817
|
+
const result = readHealthData(userId, args.metric_type, args.limit);
|
|
818
|
+
return result;
|
|
819
|
+
}
|
|
820
|
+
|
|
804
821
|
case 'memory_write': {
|
|
805
822
|
const { MemoryManager } = require('../memory/manager');
|
|
806
823
|
const mm = new MemoryManager();
|
|
@@ -169,7 +169,42 @@ function getHealthSyncStatus(userId) {
|
|
|
169
169
|
};
|
|
170
170
|
}
|
|
171
171
|
|
|
172
|
+
function readHealthData(userId, metricType, limit = 50) {
|
|
173
|
+
if (!metricType) {
|
|
174
|
+
const metrics = db.prepare(`
|
|
175
|
+
SELECT metric_type, COUNT(*) AS sample_count, MAX(COALESCE(end_time, recorded_at, start_time)) AS last_seen_at
|
|
176
|
+
FROM health_metric_samples
|
|
177
|
+
WHERE user_id = ?
|
|
178
|
+
GROUP BY metric_type
|
|
179
|
+
ORDER BY metric_type ASC
|
|
180
|
+
`).all(userId);
|
|
181
|
+
return { metrics };
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
const samples = db.prepare(`
|
|
185
|
+
SELECT
|
|
186
|
+
start_time, end_time, recorded_at,
|
|
187
|
+
numeric_value, text_value, unit,
|
|
188
|
+
source_app_id, source_device,
|
|
189
|
+
payload_json
|
|
190
|
+
FROM health_metric_samples
|
|
191
|
+
WHERE user_id = ? AND metric_type = ?
|
|
192
|
+
ORDER BY COALESCE(end_time, recorded_at, start_time) DESC
|
|
193
|
+
LIMIT ?
|
|
194
|
+
`).all(userId, metricType, limit);
|
|
195
|
+
|
|
196
|
+
return {
|
|
197
|
+
metricType,
|
|
198
|
+
samples: samples.map(s => ({
|
|
199
|
+
...s,
|
|
200
|
+
payload: s.payload_json ? JSON.parse(s.payload_json) : null,
|
|
201
|
+
payload_json: undefined
|
|
202
|
+
}))
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
172
206
|
module.exports = {
|
|
173
207
|
getHealthSyncStatus,
|
|
174
208
|
ingestHealthSync,
|
|
209
|
+
readHealthData,
|
|
175
210
|
};
|