Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .flutter-plugins-dependencies
Original file line number Diff line number Diff line change
@@ -1 +1 @@
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"isar_flutter_libs","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\isar_flutter_libs-3.1.0+1\\\\","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"isar_flutter_libs","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\isar_flutter_libs-3.1.0+1\\\\","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"path_provider_android","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_android-2.2.17\\\\","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"isar_flutter_libs","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\isar_flutter_libs-3.1.0+1\\\\","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"path_provider_foundation","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_foundation-2.4.2\\\\","shared_darwin_source":true,"native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"isar_flutter_libs","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\isar_flutter_libs-3.1.0+1\\\\","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"path_provider_linux","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_linux-2.2.1\\\\","native_build":false,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"isar_flutter_libs","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\isar_flutter_libs-3.1.0+1\\\\","native_build":true,"dependencies":[],"dev_dependency":true},{"name":"path_provider_windows","path":"C:\\\\Users\\\\belal\\\\AppData\\\\Local\\\\Pub\\\\Cache\\\\hosted\\\\pub.dev\\\\path_provider_windows-2.3.0\\\\","native_build":false,"dependencies":[],"dev_dependency":false}],"web":[]},"dependencyGraph":[{"name":"isar_flutter_libs","dependencies":[]},{"name":"path_provider","dependencies":["path_provider_android","path_provider_foundation","path_provider_linux","path_provider_windows"]},{"name":"path_provider_android","dependencies":[]},{"name":"path_provider_foundation","dependencies":[]},{"name":"path_provider_linux","dependencies":[]},{"name":"path_provider_windows","dependencies":[]}],"date_created":"2025-08-16 18:52:05.168876","version":"3.32.6","swift_package_manager_enabled":{"ios":false,"macos":false}}
{"info":"This is a generated file; do not edit or check into version control.","plugins":{"ios":[{"name":"onnxruntime","path":"/home/jules/.pub-cache/hosted/pub.dev/onnxruntime-1.4.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"android":[{"name":"onnxruntime","path":"/home/jules/.pub-cache/hosted/pub.dev/onnxruntime-1.4.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"macos":[{"name":"onnxruntime","path":"/home/jules/.pub-cache/hosted/pub.dev/onnxruntime-1.4.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"linux":[{"name":"onnxruntime","path":"/home/jules/.pub-cache/hosted/pub.dev/onnxruntime-1.4.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"windows":[{"name":"onnxruntime","path":"/home/jules/.pub-cache/hosted/pub.dev/onnxruntime-1.4.1/","native_build":true,"dependencies":[],"dev_dependency":false}],"web":[]},"dependencyGraph":[{"name":"onnxruntime","dependencies":[]}],"date_created":"2025-11-24 21:02:48.717549","version":"3.38.3","swift_package_manager_enabled":{"ios":false,"macos":false}}
57 changes: 56 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ isar_agent_memory: ^0.2.3
isar: ^3.1.0+1
# ObjectBox is the default vector backend.
# onnxruntime is used for on-device embeddings.
# cryptography is used for sync encryption.
```

### 2. Basic Usage
Expand Down Expand Up @@ -60,6 +61,58 @@ if (results.isNotEmpty) {

---

## 🔄 Sync & Privacy (Beta)

This package supports an encrypted, offline-first synchronization protocol (LWW - Last Write Wins).

### Export Encrypted Data

```dart
import 'package:isar_agent_memory/isar_agent_memory.dart';
import 'package:isar_agent_memory/src/sync/sync_manager.dart';

final syncManager = SyncManager(graph);
// Initialize with a 32-byte key (or generate one)
final key = List<int>.generate(32, (i) => i);
await syncManager.initialize(encryptionKey: key);

// Export encrypted snapshot
final encryptedData = await syncManager.exportEncryptedSnapshot();
// Upload 'encryptedData' to your cloud storage or peer.
```

### Import Encrypted Data

```dart
// Download 'encryptedData' from cloud...
await syncManager.importEncryptedSnapshot(encryptedData);
// Local DB is now merged with remote data.
```

**Note:** Data is encrypted using AES-256-GCM (via `cryptography` package). The server only sees encrypted blobs.

---

## 🧠 HiRAG (Hierarchical RAG) Support

We are laying the foundation for HiRAG. You can currently create summary nodes and organize memory into layers.

```dart
import 'package:isar_agent_memory/isar_agent_memory.dart';

// Create a summary node for a set of child nodes (Layer 1)
await graph.createSummaryNode(
summaryContent: 'Summary of recent events...',
childNodeIds: [nodeId1, nodeId2],
layer: 1,
);

// Retrieve nodes by layer
final summaries = await graph.getNodesByLayer(1);
```

---

## 🔒 On-Device Embeddings (Local Privacy)

You can run embeddings entirely on-device using ONNX Runtime (e.g., with `all-MiniLM-L6-v2`).
Expand Down Expand Up @@ -125,6 +178,7 @@ To run tests that require the ONNX model files, you must first download the test
- **Hybrid Search**: Combine vector similarity with full-text search (BM25-like) for better recall.
- **Robust Testing**: comprehensive test suite and real-world examples.
- **Extensible**: Add metadata, new adapters, or future sync/export capabilities.
- **Sync & Privacy**: Client-side AES-GCM encryption, LWW conflict resolution.

---

Expand Down Expand Up @@ -351,7 +405,8 @@ print(explanation);
- [x] `OnDeviceEmbeddingsAdapter` (ONNX) for Android/iOS/Desktop.
- [x] Benchmarks via GitHub Actions.
- [x] Hybrid Retrieval (Dense + Isar Filter).
- [ ] Sync & Privacy (Encryption).
- [x] Sync & Privacy (Encryption).
- [ ] HiRAG (Hierarchical RAG) - In Progress.

---

Expand Down
1 change: 1 addition & 0 deletions flutter
Submodule flutter added at 19074d
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@

#include "generated_plugin_registrant.h"

#include <isar_flutter_libs/isar_flutter_libs_plugin.h>

void fl_register_plugins(FlPluginRegistry* registry) {
g_autoptr(FlPluginRegistrar) isar_flutter_libs_registrar =
fl_plugin_registry_get_registrar_for_plugin(registry, "IsarFlutterLibsPlugin");
isar_flutter_libs_plugin_register_with_registrar(isar_flutter_libs_registrar);
}
2 changes: 2 additions & 0 deletions isar_agent_memory_tests/linux/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
isar_flutter_libs
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
onnxruntime
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@
import FlutterMacOS
import Foundation

import isar_flutter_libs

func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
IsarFlutterLibsPlugin.register(with: registry.registrar(forPlugin: "IsarFlutterLibsPlugin"))
}
2 changes: 2 additions & 0 deletions isar_agent_memory_tests/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ dependencies:
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.8
isar_flutter_libs: ^3.1.0+1
cryptography: ^2.9.0

dev_dependencies:
flutter_test:
Expand Down
88 changes: 88 additions & 0 deletions isar_agent_memory_tests/test/sync_integration_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:isar_agent_memory/isar_agent_memory.dart';
import 'package:isar_agent_memory/src/sync/sync_manager.dart';
import 'package:isar/isar.dart';
import 'dart:io';
import 'support/in_memory_index.dart'; // Import InMemoryVectorIndex

void main() {
late MemoryGraph memoryGraph;
late SyncManager syncManager;

setUpAll(() async {
await Isar.initializeIsarCore(download: true);
});

setUp(() async {
final dir = Directory.systemTemp.createTempSync();
final isar = await Isar.open(
[MemoryNodeSchema, MemoryEdgeSchema],
directory: dir.path,
);

// Mock adapter
final adapter = FallbackEmbeddingsAdapter(
primary: _MockEmbeddingsAdapter(),
fallback: _MockEmbeddingsAdapter(),
);

memoryGraph = MemoryGraph(isar, embeddingsAdapter: adapter, index: InMemoryVectorIndex());
syncManager = SyncManager(memoryGraph);
await syncManager.initialize(); // Random key
});

tearDown(() async {
await memoryGraph.isar.close(deleteFromDisk: true);
});

test('SyncManager export and import loop', () async {
// 1. Create some data
final nodeId = await memoryGraph.storeNodeWithEmbedding(content: 'Secret Memory');
final edgeId = await memoryGraph.storeEdge(MemoryEdge(fromNodeId: nodeId, toNodeId: nodeId, relation: 'self'));

// 2. Export
final encrypted = await syncManager.exportEncryptedSnapshot();
expect(encrypted, isNotEmpty);

// 3. Clear DB
await memoryGraph.isar.writeTxn(() async {
await memoryGraph.isar.clear();
});
expect(await memoryGraph.getNode(nodeId), isNull);

// 4. Import
await syncManager.importEncryptedSnapshot(encrypted);

// 5. Verify
final node = await memoryGraph.getNode(nodeId);
expect(node, isNotNull);
expect(node!.content, 'Secret Memory');

final edges = await memoryGraph.getEdgesForNode(nodeId);
expect(edges, isNotEmpty);
expect(edges.first.relation, 'self');
});
}

class _MockEmbeddingsAdapter implements EmbeddingsAdapter {
@override
int get dimension => 768;

@override
Future<List<double>> embed(String text) async {
return List.filled(768, 0.1);
}

@override
Future<List<List<double>>> embedDocuments(List<String> documents) async {
return documents.map((_) => List.filled(768, 0.1)).toList();
}

@override
Future<List<double>> embedQuery(String query) async {
return List.filled(768, 0.1);
}

@override
String get providerName => 'mock';
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

#include "generated_plugin_registrant.h"

#include <isar_flutter_libs/isar_flutter_libs_plugin.h>

void RegisterPlugins(flutter::PluginRegistry* registry) {
IsarFlutterLibsPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("IsarFlutterLibsPlugin"));
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
isar_flutter_libs
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
onnxruntime
)

set(PLUGIN_BUNDLED_LIBRARIES)
Expand Down
1 change: 1 addition & 0 deletions lib/isar_agent_memory.dart
Original file line number Diff line number Diff line change
Expand Up @@ -14,3 +14,4 @@ export 'src/fallback_embeddings_adapter.dart';
export 'src/on_device_embeddings_adapter.dart';
export 'src/vector_index.dart';
export 'src/vector_index_objectbox.dart';
export 'src/hierarchical_graph.dart';
8 changes: 4 additions & 4 deletions lib/objectbox-model.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
{
"id": "2:1442387009774653075",
"name": "docKey",
"indexId": "1:8701917581695520620",
"type": 9,
"flags": 2080,
"indexId": "1:8701917581695520620"
"flags": 2080
},
{
"id": "3:1210557137860714142",
Expand All @@ -29,9 +29,9 @@
{
"id": "4:9089606705394925499",
"name": "vector",
"indexId": "2:7396986783401268781",
"type": 28,
"flags": 8,
"indexId": "2:7396986783401268781"
"flags": 8
}
],
"relations": []
Expand Down
Loading
Loading