@@ -42,7 +42,6 @@ def example_multi_db(db_name: str = "paper"):
4242 metadata = TreeNodeTextualMemoryMetadata (
4343 memory_type = "LongTermMemory" ,
4444 key = "Multi-UAV Long-Term Coverage" ,
45- value = "Research topic on distributed multi-agent UAV navigation and coverage" ,
4645 hierarchy_level = "topic" ,
4746 type = "fact" ,
4847 memory_time = "2024-01-01" ,
@@ -74,7 +73,6 @@ def example_multi_db(db_name: str = "paper"):
7473 metadata = TreeNodeTextualMemoryMetadata (
7574 memory_type = "LongTermMemory" ,
7675 key = "Reward Function Design" ,
77- value = "Combines coverage, energy efficiency, and overlap penalty" ,
7876 hierarchy_level = "concept" ,
7977 type = "fact" ,
8078 memory_time = "2024-01-01" ,
@@ -99,7 +97,6 @@ def example_multi_db(db_name: str = "paper"):
9997 metadata = TreeNodeTextualMemoryMetadata (
10098 memory_type = "LongTermMemory" ,
10199 key = "Energy Model" ,
102- value = "Includes communication and motion energy consumption" ,
103100 hierarchy_level = "concept" ,
104101 type = "fact" ,
105102 memory_time = "2024-01-01" ,
@@ -122,7 +119,6 @@ def example_multi_db(db_name: str = "paper"):
122119 metadata = TreeNodeTextualMemoryMetadata (
123120 memory_type = "LongTermMemory" ,
124121 key = "Coverage Metrics" ,
125- value = "CT and FT used for long-term area and fairness evaluation" ,
126122 hierarchy_level = "concept" ,
127123 type = "fact" ,
128124 memory_time = "2024-01-01" ,
@@ -161,7 +157,6 @@ def example_multi_db(db_name: str = "paper"):
161157 metadata = TreeNodeTextualMemoryMetadata (
162158 memory_type = "WorkingMemory" ,
163159 key = "Reward Components" ,
164- value = "Coverage gain, energy usage penalty, overlap penalty" ,
165160 hierarchy_level = "fact" ,
166161 type = "fact" ,
167162 memory_time = "2024-01-01" ,
@@ -186,7 +181,6 @@ def example_multi_db(db_name: str = "paper"):
186181 metadata = TreeNodeTextualMemoryMetadata (
187182 memory_type = "LongTermMemory" ,
188183 key = "Energy Cost Components" ,
189- value = "Includes movement and communication energy" ,
190184 hierarchy_level = "fact" ,
191185 type = "fact" ,
192186 memory_time = "2024-01-01" ,
@@ -211,7 +205,6 @@ def example_multi_db(db_name: str = "paper"):
211205 metadata = TreeNodeTextualMemoryMetadata (
212206 memory_type = "LongTermMemory" ,
213207 key = "CT and FT Definition" ,
214- value = "CT: total coverage duration; FT: fairness index" ,
215208 hierarchy_level = "fact" ,
216209 type = "fact" ,
217210 memory_time = "2024-01-01" ,
@@ -347,9 +340,202 @@ def example_shared_db(db_name: str = "shared-traval-group"):
347340 print (graph_alice .get_node (node ["id" ]))
348341
349342
343+ def run_user_session (
344+ user_name : str ,
345+ db_name : str ,
346+ topic_text : str ,
347+ concept_texts : list [str ],
348+ fact_texts : list [str ],
349+ community : bool = False ,
350+ ):
351+ print (f"\n === { user_name } starts building their memory graph ===" )
352+
353+ # Manually initialize correct GraphDB class
354+ if community :
355+ config = GraphDBConfigFactory (
356+ backend = "neo4j-community" ,
357+ config = {
358+ "uri" : "bolt://localhost:7687" ,
359+ "user" : "neo4j" ,
360+ "password" : "12345678" ,
361+ "db_name" : db_name ,
362+ "user_name" : user_name ,
363+ "use_multi_db" : False ,
364+ "auto_create" : False , # Neo4j Community does not allow auto DB creation
365+ "embedding_dimension" : 768 ,
366+ "vec_config" : {
367+ # Pass nested config to initialize external vector DB
368+ # If you use qdrant, please use Server instead of local mode.
369+ "backend" : "qdrant" ,
370+ "config" : {
371+ "collection_name" : "neo4j_vec_db" ,
372+ "vector_dimension" : 768 ,
373+ "distance_metric" : "cosine" ,
374+ "host" : "localhost" ,
375+ "port" : 6333 ,
376+ },
377+ },
378+ },
379+ )
380+ else :
381+ config = GraphDBConfigFactory (
382+ backend = "neo4j" ,
383+ config = {
384+ "uri" : "bolt://localhost:7687" ,
385+ "user" : "neo4j" ,
386+ "password" : "12345678" ,
387+ "db_name" : db_name ,
388+ "user_name" : user_name ,
389+ "use_multi_db" : False ,
390+ "auto_create" : True ,
391+ "embedding_dimension" : 768 ,
392+ },
393+ )
394+ graph = GraphStoreFactory .from_config (config )
395+
396+ # Start with a clean slate for this user
397+ graph .clear ()
398+
399+ now = datetime .utcnow ().isoformat ()
400+
401+ # === Step 1: Create a root topic node (e.g., user's research focus) ===
402+ topic = TextualMemoryItem (
403+ memory = topic_text ,
404+ metadata = TreeNodeTextualMemoryMetadata (
405+ memory_type = "LongTermMemory" ,
406+ key = "Research Topic" ,
407+ hierarchy_level = "topic" ,
408+ type = "fact" ,
409+ memory_time = "2024-01-01" ,
410+ status = "activated" ,
411+ visibility = "public" ,
412+ updated_at = now ,
413+ embedding = embed_memory_item (topic_text ),
414+ ),
415+ )
416+ graph .add_node (topic .id , topic .memory , topic .metadata .model_dump (exclude_none = True ))
417+
418+ # === Step 2: Create two concept nodes linked to the topic ===
419+ concept_items = []
420+ for i , text in enumerate (concept_texts ):
421+ concept = TextualMemoryItem (
422+ memory = text ,
423+ metadata = TreeNodeTextualMemoryMetadata (
424+ memory_type = "LongTermMemory" ,
425+ key = f"Concept { i + 1 } " ,
426+ hierarchy_level = "concept" ,
427+ type = "fact" ,
428+ memory_time = "2024-01-01" ,
429+ status = "activated" ,
430+ visibility = "public" ,
431+ updated_at = now ,
432+ embedding = embed_memory_item (text ),
433+ tags = ["concept" ],
434+ confidence = 90 + i ,
435+ ),
436+ )
437+ graph .add_node (concept .id , concept .memory , concept .metadata .model_dump (exclude_none = True ))
438+ graph .add_edge (topic .id , concept .id , type = "PARENT" )
439+ concept_items .append (concept )
440+
441+ # === Step 3: Create supporting facts under each concept ===
442+ for i , text in enumerate (fact_texts ):
443+ fact = TextualMemoryItem (
444+ memory = text ,
445+ metadata = TreeNodeTextualMemoryMetadata (
446+ memory_type = "WorkingMemory" ,
447+ key = f"Fact { i + 1 } " ,
448+ hierarchy_level = "fact" ,
449+ type = "fact" ,
450+ memory_time = "2024-01-01" ,
451+ status = "activated" ,
452+ visibility = "public" ,
453+ updated_at = now ,
454+ embedding = embed_memory_item (text ),
455+ confidence = 85.0 ,
456+ tags = ["fact" ],
457+ ),
458+ )
459+ graph .add_node (fact .id , fact .memory , fact .metadata .model_dump (exclude_none = True ))
460+ graph .add_edge (concept_items [i % len (concept_items )].id , fact .id , type = "PARENT" )
461+
462+ # === Step 4: Retrieve memory using semantic search ===
463+ vector = embed_memory_item ("How is memory retrieved?" )
464+ search_result = graph .search_by_embedding (vector , top_k = 2 )
465+ for r in search_result :
466+ node = graph .get_node (r ["id" ])
467+ print ("🔍 Search result:" , node ["memory" ])
468+
469+ # === Step 5: Tag-based neighborhood discovery ===
470+ neighbors = graph .get_neighbors_by_tag (["concept" ], exclude_ids = [], top_k = 2 )
471+ print ("📎 Tag-related nodes:" , [neighbor ["memory" ] for neighbor in neighbors ])
472+
473+ # === Step 6: Retrieve children (facts) of first concept ===
474+ children = graph .get_children_with_embeddings (concept_items [0 ].id )
475+ print ("📍 Children of concept:" , [child ["memory" ] for child in children ])
476+
477+ # === Step 7: Export a local subgraph and grouped statistics ===
478+ subgraph = graph .get_subgraph (topic .id , depth = 2 )
479+ print ("📌 Subgraph node count:" , len (subgraph ["neighbors" ]))
480+
481+ stats = graph .get_grouped_counts (["memory_type" , "status" ])
482+ print ("📊 Grouped counts:" , stats )
483+
484+ # === Step 8: Demonstrate updates and cleanup ===
485+ graph .update_node (concept_items [0 ].id , {"confidence" : 99.0 })
486+ graph .remove_oldest_memory ("WorkingMemory" , keep_latest = 1 )
487+ graph .delete_edge (topic .id , concept_items [0 ].id , type = "PARENT" )
488+ graph .delete_node (concept_items [1 ].id )
489+
490+ # === Step 9: Export and re-import the entire graph structure ===
491+ exported = graph .export_graph ()
492+ graph .import_graph (exported )
493+ print ("📦 Graph exported and re-imported, total nodes:" , len (exported ["nodes" ]))
494+
495+
496+ def example_complex_shared_db (db_name : str = "shared-traval-group-complex" , community = False ):
497+ # User 1: Alice explores structured memory for LLMs
498+ run_user_session (
499+ user_name = "alice" ,
500+ db_name = db_name ,
501+ topic_text = "Alice studies structured memory and long-term memory optimization in LLMs." ,
502+ concept_texts = [
503+ "Short-term memory can be simulated using WorkingMemory blocks." ,
504+ "A structured memory graph improves retrieval precision for agents." ,
505+ ],
506+ fact_texts = [
507+ "Embedding search is used to find semantically similar memory items." ,
508+ "User memories are stored as node-edge structures that support hierarchical reasoning." ,
509+ ],
510+ community = community ,
511+ )
512+
513+ # User 2: Bob focuses on GNN-based reasoning
514+ run_user_session (
515+ user_name = "bob" ,
516+ db_name = db_name ,
517+ topic_text = "Bob investigates how graph neural networks can support knowledge reasoning." ,
518+ concept_texts = [
519+ "GNNs can learn high-order relations among entities." ,
520+ "Attention mechanisms in graphs improve inference precision." ,
521+ ],
522+ fact_texts = [
523+ "GAT outperforms GCN in graph classification tasks." ,
524+ "Multi-hop reasoning helps answer complex queries." ,
525+ ],
526+ community = community ,
527+ )
528+
529+
350530if __name__ == "__main__" :
351531 print ("\n === Example: Multi-DB ===" )
352532 example_multi_db (db_name = "paper" )
353533
354534 print ("\n === Example: Single-DB ===" )
355- example_shared_db (db_name = "shared-traval-group11" )
535+ example_shared_db (db_name = "shared-traval-group" )
536+
537+ print ("\n === Example: Single-DB-Complex ===" )
538+ example_complex_shared_db (db_name = "shared-traval-group-complex-new" )
539+
540+ print ("\n === Example: Single-Community-DB-Complex ===" )
541+ example_complex_shared_db (db_name = "paper" , community = True )
0 commit comments