neoagent 2.3.1-beta.98 → 2.4.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.
Files changed (52) hide show
  1. package/.env.example +6 -3
  2. package/flutter_app/lib/main.dart +1 -0
  3. package/flutter_app/lib/main_integrations.dart +21 -2
  4. package/flutter_app/lib/main_models.dart +60 -0
  5. package/flutter_app/lib/main_theme.dart +31 -2
  6. package/flutter_app/macos/Runner/AppDelegate.swift +11 -1
  7. package/flutter_app/macos/Runner/DebugProfile.entitlements +4 -0
  8. package/flutter_app/macos/Runner/Release.entitlements +4 -0
  9. package/flutter_app/pubspec.lock +5 -5
  10. package/lib/manager.js +164 -2
  11. package/package.json +1 -1
  12. package/server/db/database.js +85 -0
  13. package/server/public/.last_build_id +1 -1
  14. package/server/public/assets/NOTICES +971 -1066
  15. package/server/public/assets/fonts/MaterialIcons-Regular.otf +0 -0
  16. package/server/public/assets/shaders/ink_sparkle.frag +1 -1
  17. package/server/public/assets/shaders/stretch_effect.frag +1 -1
  18. package/server/public/canvaskit/canvaskit.js +2 -2
  19. package/server/public/canvaskit/canvaskit.js.symbols +11796 -11733
  20. package/server/public/canvaskit/canvaskit.wasm +0 -0
  21. package/server/public/canvaskit/chromium/canvaskit.js +2 -2
  22. package/server/public/canvaskit/chromium/canvaskit.js.symbols +10706 -10643
  23. package/server/public/canvaskit/chromium/canvaskit.wasm +0 -0
  24. package/server/public/canvaskit/experimental_webparagraph/canvaskit.js +171 -0
  25. package/server/public/canvaskit/experimental_webparagraph/canvaskit.js.symbols +9134 -0
  26. package/server/public/canvaskit/experimental_webparagraph/canvaskit.wasm +0 -0
  27. package/server/public/canvaskit/skwasm.js +14 -14
  28. package/server/public/canvaskit/skwasm.js.symbols +12787 -12676
  29. package/server/public/canvaskit/skwasm.wasm +0 -0
  30. package/server/public/canvaskit/skwasm_heavy.js +14 -14
  31. package/server/public/canvaskit/skwasm_heavy.js.symbols +14400 -14286
  32. package/server/public/canvaskit/skwasm_heavy.wasm +0 -0
  33. package/server/public/canvaskit/wimp.js +94 -95
  34. package/server/public/canvaskit/wimp.js.symbols +11325 -11177
  35. package/server/public/canvaskit/wimp.wasm +0 -0
  36. package/server/public/flutter_bootstrap.js +2 -2
  37. package/server/public/main.dart.js +83866 -82074
  38. package/server/routes/integrations.js +2 -2
  39. package/server/routes/memory.js +73 -0
  40. package/server/services/ai/engine.js +65 -26
  41. package/server/services/ai/models.js +21 -0
  42. package/server/services/ai/preModelCompaction.js +191 -0
  43. package/server/services/ai/providers/claudeCode.js +273 -0
  44. package/server/services/ai/providers/openaiCodex.js +226 -41
  45. package/server/services/ai/settings.js +11 -1
  46. package/server/services/integrations/google/provider.js +78 -0
  47. package/server/services/integrations/manager.js +29 -13
  48. package/server/services/manager.js +25 -0
  49. package/server/services/memory/ingestion.js +486 -0
  50. package/server/services/memory/manager.js +422 -0
  51. package/server/services/memory/openhuman_uplift.test.js +98 -0
  52. package/server/services/widgets/focus_widget.js +45 -4
@@ -248,6 +248,81 @@ async function executeGoogleWorkspaceTool(toolName, args, connection) {
248
248
  return { result, credentials: auth.credentials };
249
249
  }
250
250
 
251
+ async function collectGoogleMemoryDocuments({ connection, sourceTypes = [] }) {
252
+ const appKey = String(connection?.app_key || '').trim();
253
+ const documents = [];
254
+ const collectedAt = new Date().toISOString();
255
+
256
+ if (appKey === 'gmail' && sourceTypes.includes('email')) {
257
+ const { result } = await executeGoogleWorkspaceTool(
258
+ 'google_workspace_gmail_search_threads',
259
+ { query: 'newer_than:7d', max_results: 8 },
260
+ connection,
261
+ );
262
+ for (const thread of Array.isArray(result?.threads) ? result.threads : []) {
263
+ const subject = String(thread.subject || 'Gmail thread').trim();
264
+ documents.push({
265
+ externalObjectId: thread.id,
266
+ sourceType: 'email',
267
+ normalizedType: 'email',
268
+ title: subject,
269
+ content: [
270
+ subject,
271
+ thread.from ? `From: ${thread.from}` : '',
272
+ thread.date ? `Date: ${thread.date}` : '',
273
+ thread.snippet || '',
274
+ ].filter(Boolean).join('\n'),
275
+ summary: thread.snippet || subject,
276
+ sourceTimestamp: thread.date || collectedAt,
277
+ salience: Array.isArray(thread.labelIds) && thread.labelIds.includes('IMPORTANT') ? 8 : 5,
278
+ payload: thread,
279
+ });
280
+ }
281
+ }
282
+
283
+ if (appKey === 'calendar' && sourceTypes.includes('calendar')) {
284
+ const timeMin = new Date(Date.now() - 24 * 60 * 60 * 1000).toISOString();
285
+ const timeMax = new Date(Date.now() + 14 * 24 * 60 * 60 * 1000).toISOString();
286
+ const { result } = await executeGoogleWorkspaceTool(
287
+ 'google_workspace_calendar_list_events',
288
+ { time_min: timeMin, time_max: timeMax, max_results: 12 },
289
+ connection,
290
+ );
291
+ for (const event of Array.isArray(result?.events) ? result.events : []) {
292
+ const title = String(event.summary || 'Calendar event').trim();
293
+ documents.push({
294
+ externalObjectId: event.id,
295
+ sourceType: 'calendar',
296
+ normalizedType: 'calendar',
297
+ title,
298
+ content: [
299
+ title,
300
+ event.start ? `Start: ${event.start}` : '',
301
+ event.end ? `End: ${event.end}` : '',
302
+ event.location ? `Location: ${event.location}` : '',
303
+ event.description || '',
304
+ Array.isArray(event.attendees) && event.attendees.length
305
+ ? `Attendees: ${event.attendees.join(', ')}`
306
+ : '',
307
+ ].filter(Boolean).join('\n'),
308
+ summary: [event.start, event.location, event.description].filter(Boolean).join(' | ') || title,
309
+ sourceTimestamp: event.start || collectedAt,
310
+ salience: 6,
311
+ payload: event,
312
+ });
313
+ }
314
+ }
315
+
316
+ return {
317
+ documents,
318
+ cursor: {
319
+ collectedAt,
320
+ appKey,
321
+ sourceTypes,
322
+ },
323
+ };
324
+ }
325
+
251
326
  function buildConnectedAppSummary(appSnapshots) {
252
327
  return appSnapshots
253
328
  .filter((app) => app.connection.connected)
@@ -456,6 +531,9 @@ function createGoogleWorkspaceProvider() {
456
531
  async executeTool(toolName, args, connectionRow) {
457
532
  return executeGoogleWorkspaceTool(toolName, args, connectionRow);
458
533
  },
534
+ async collectMemoryDocuments(options) {
535
+ return collectGoogleMemoryDocuments(options);
536
+ },
459
537
  summarizeConnection(connectionRows) {
460
538
  const snapshot = this.buildSnapshot(connectionRows);
461
539
  if (!snapshot.connection.connected) {
@@ -182,7 +182,7 @@ class IntegrationManager {
182
182
  rowsByProvider.get(providerKey).push(row);
183
183
  }
184
184
 
185
- return this.registry
185
+ const snapshots = this.registry
186
186
  .list()
187
187
  .map((provider) =>
188
188
  provider.buildSnapshot(rowsByProvider.get(provider.key) || [], {
@@ -190,6 +190,13 @@ class IntegrationManager {
190
190
  agentId: scopedAgentId,
191
191
  }),
192
192
  );
193
+ const ingestionService = this.app?.locals?.memoryIngestionService || null;
194
+ if (!ingestionService || typeof ingestionService.decorateProviderSnapshot !== 'function') {
195
+ return snapshots;
196
+ }
197
+ return snapshots.map((snapshot) =>
198
+ ingestionService.decorateProviderSnapshot(snapshot, userId, scopedAgentId),
199
+ );
193
200
  }
194
201
 
195
202
  async beginOAuth(userId, providerKey, options = {}) {
@@ -705,15 +712,20 @@ class IntegrationManager {
705
712
  }
706
713
 
707
714
  summarizeConnectedProviders(userId, agentId = null) {
715
+ const scopedAgentId = resolveAgentId(userId, agentId);
716
+ const ingestionService = this.app?.locals?.memoryIngestionService || null;
708
717
  const providers = this.registry.list().map((provider) => ({
709
718
  provider,
710
- snapshot: provider.buildSnapshot(
711
- this.listConnections(userId, provider.key, agentId),
712
- {
713
- userId,
714
- agentId,
715
- },
716
- ),
719
+ snapshot: (() => {
720
+ const snapshot = provider.buildSnapshot(
721
+ this.listConnections(userId, provider.key, scopedAgentId),
722
+ {
723
+ userId,
724
+ agentId: scopedAgentId,
725
+ },
726
+ );
727
+ return ingestionService?.decorateProviderSnapshot?.(snapshot, userId, scopedAgentId) || snapshot;
728
+ })(),
717
729
  }));
718
730
 
719
731
  if (providers.length === 0) {
@@ -722,22 +734,26 @@ class IntegrationManager {
722
734
 
723
735
  return providers
724
736
  .map(({ provider, snapshot }) => {
737
+ const memoryCoverage = snapshot.memoryCoverage?.supported
738
+ ? ` Memory ingestion: ${snapshot.memoryCoverage.status}; domains: ${(snapshot.memoryCoverage.dataDomains || []).join(', ') || 'none'}; documents: ${snapshot.memoryCoverage.documentCount || 0}.`
739
+ : '';
740
+
725
741
  if (typeof provider.summarizeForModel === 'function') {
726
- return provider.summarizeForModel(snapshot);
742
+ return `${provider.summarizeForModel(snapshot)}${memoryCoverage}`;
727
743
  }
728
744
 
729
745
  if (!snapshot?.env?.configured) {
730
746
  if (snapshot?.env?.setupMode === 'user') {
731
- return `${provider.label}: setup is not complete for this user yet. If the user wants to use it, tell them to finish setup in Official Integrations first.`;
747
+ return `${provider.label}: setup is not complete for this user yet. If the user wants to use it, tell them to finish setup in Official Integrations first.${memoryCoverage}`;
732
748
  }
733
- return `${provider.label}: available but not configured on the server yet. If the user wants to use it, tell them to finish setup in Official Integrations first.`;
749
+ return `${provider.label}: available but not configured on the server yet. If the user wants to use it, tell them to finish setup in Official Integrations first.${memoryCoverage}`;
734
750
  }
735
751
 
736
752
  if (!snapshot.connection?.connected) {
737
- return `${provider.label}: server setup is ready, but no accounts are connected. If the user wants to use it, tell them to connect an account in Official Integrations first.`;
753
+ return `${provider.label}: server setup is ready, but no accounts are connected. If the user wants to use it, tell them to connect an account in Official Integrations first.${memoryCoverage}`;
738
754
  }
739
755
 
740
- return `${provider.label}: native built-in access is connected in this run.`;
756
+ return `${provider.label}: native built-in access is connected in this run.${memoryCoverage}`;
741
757
  })
742
758
  .join('\n');
743
759
  }
@@ -17,6 +17,7 @@ const { SocialVideoService } = require('./social_video');
17
17
  const { VoiceRuntimeManager } = require('./voice/runtimeManager');
18
18
  const { AuthProviderManager } = require('./account/auth_provider_manager');
19
19
  const { IntegrationManager } = require('./integrations/manager');
20
+ const { MemoryIngestionService } = require('./memory/ingestion');
20
21
  const { ArtifactStore } = require('./artifacts/store');
21
22
  const { RuntimeManager } = require('./runtime/manager');
22
23
  const { WorkspaceManager } = require('./workspace/manager');
@@ -104,6 +105,20 @@ function createIntegrationManager(app) {
104
105
  return integrationManager;
105
106
  }
106
107
 
108
+ function createMemoryIngestionService(app, { memoryManager, integrationManager }) {
109
+ const memoryIngestionService = registerLocal(
110
+ app,
111
+ 'memoryIngestionService',
112
+ new MemoryIngestionService({
113
+ memoryManager,
114
+ integrationManager,
115
+ }),
116
+ );
117
+ memoryIngestionService.start();
118
+ logServiceReady('Memory ingestion service started');
119
+ return memoryIngestionService;
120
+ }
121
+
107
122
  function createAuthProviderManager(app) {
108
123
  const authProviderManager = registerLocal(
109
124
  app,
@@ -447,6 +462,7 @@ async function startServices(app, io) {
447
462
  const mcpClient = createMcpClient(app);
448
463
  createAuthProviderManager(app);
449
464
  const integrationManager = createIntegrationManager(app);
465
+ createMemoryIngestionService(app, { memoryManager, integrationManager });
450
466
  const browserController = createBrowserController(app, artifactStore);
451
467
  const runtimeManager = createRuntimeManager(app);
452
468
  const runtimeValidation = getRuntimeValidation(runtimeManager);
@@ -525,6 +541,15 @@ async function stopServices(app) {
525
541
  }
526
542
  }
527
543
 
544
+ if (app.locals.memoryIngestionService) {
545
+ try {
546
+ app.locals.memoryIngestionService.stop();
547
+ logServiceReady('Memory ingestion service stopped');
548
+ } catch (err) {
549
+ console.error('[MemoryIngestion] Stop error:', getErrorMessage(err));
550
+ }
551
+ }
552
+
528
553
  if (app.locals.mcpClient) {
529
554
  tasks.push(
530
555
  app.locals.mcpClient.shutdown().catch((err) => {