neoagent 1.4.4 → 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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "neoagent",
3
- "version": "1.4.4",
3
+ "version": "1.4.6",
4
4
  "description": "Proactive personal AI agent with no limits",
5
5
  "license": "MIT",
6
6
  "main": "server/index.js",
@@ -81,7 +81,33 @@ class GoogleProvider extends BaseProvider {
81
81
  });
82
82
  }
83
83
 
84
- return { systemInstruction, history };
84
+ const normalizedHistory = [];
85
+ let currentRole = null;
86
+ let currentParts = [];
87
+
88
+ for (const msg of history) {
89
+ if (msg.role === currentRole) {
90
+ currentParts.push(...msg.parts);
91
+ } else {
92
+ if (currentRole) {
93
+ normalizedHistory.push({ role: currentRole, parts: currentParts });
94
+ }
95
+ currentRole = msg.role;
96
+ currentParts = [...msg.parts];
97
+ }
98
+ }
99
+ if (currentRole) {
100
+ normalizedHistory.push({ role: currentRole, parts: currentParts });
101
+ }
102
+
103
+ if (normalizedHistory.length > 0 && normalizedHistory[0].role !== 'user') {
104
+ normalizedHistory.unshift({
105
+ role: 'user',
106
+ parts: [{ text: '[Conversation Resumed]' }]
107
+ });
108
+ }
109
+
110
+ return { systemInstruction, history: normalizedHistory };
85
111
  }
86
112
 
87
113
  async chat(messages, tools = [], options = {}) {
@@ -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
  };