HawkinsDB

repository·main·Indexed 43 days ago

https://github.com/harishsg993010/hawkinsdb

A neuroscience-inspired memory layer for LLM applications based on the Thousand Brains Theory. It utilizes structured, multi-dimensional memory—Semantic, Episodic, and Procedural—via Reference Frames and Cortical Columns. Features include an LLMInterface for natural language querying and text-to-structured-data conversion, SQLite and JSON storage backends, and ConceptNetEnricher for automatic knowledge expansion.

Tokens
7.2K
Snippets
23
Records
29
Agent score
55%

What's inside HawkinsDB

  1. HawkinsDB Storage and Integrations

    main

    HawkinsDB supports different storage backends and integrations depending on your use case:

    Storage Options:

    • SQLite: Recommended for production systems.
    • JSON: Best for quick prototyping.

    Integrations:

    • ConceptNet: Provides automatic knowledge enrichment and relationship discovery.
  2. How HawkinsDB manages information

    main

    HawkinsDB uses a neuroscience-inspired architecture to manage information through three core abstractions:

    • Reference Frames: Smart containers that capture an entity's identity, properties, relationships, and context. This allows for complex, context-aware queries.
    • Cortical Columns: A mechanism to store knowledge from multiple perspectives (e.g., visual, tactile, conceptual). Instead of a single definition, objects are understood through different "columns."
    • Memory Types: The system unifies three types of memory:
      • Semantic Memory: Facts, concepts, and general knowledge.
      • Episodic Memory: Events and experiences over time.
      • Procedural Memory: Step-by-step processes and workflows.
  3. Initialize the LLMInterface

    main

    To interact with HawkinsDB using natural language, you must initialize an LLMInterface instance and pass it your HawkinsDB instance. You can enable or disable automatic enrichment (using ConceptNet) and configure validation thresholds.

    Key configuration options:

    • auto_enrich (bool): Enables/disables ConceptNet integration for knowledge expansion.
    • confidence_threshold (float): Minimum confidence score required for accepting properties.
    • max_enrichment_depth (int): Maximum depth for ConceptNet enrichment.
    • validate_properties (bool): Enables strict property type validation.
    from hawkinsdb import HawkinsDB, LLMInterface
    
    # Initialize database and LLM interface with auto-enrichment
    db = HawkinsDB()
    llm = LLMInterface(db, auto_enrich=True)
    
    # Or initialize with custom settings
    llm = LLMInterface(
        db,
        auto_enrich=True,
        confidence_threshold=0.7,
        max_enrichment_depth=2,
        validate_properties=True
    )
  4. Initialize HawkinsDB with SQLite storage

    main

    To use HawkinsDB with persistent storage, initialize the HawkinsDB class with storage_type="sqlite" and provide a db_path. You can then wrap the database instance in an LLMInterface to enable natural language capabilities.

    from hawkinsdb import HawkinsDB , LLMInterface
    
    # Initialize with SQLite storage
    db = HawkinsDB(storage_type="sqlite", db_path="memory.db")
    llm = LLMInterface(db)
  5. Install HawkinsDB

    main

    You can install HawkinsDB using pip. Choose the installation method that best fits your needs:

    • Basic installation: Standard installation.
    • Recommended installation: Includes all features.
    • Specific features: Install only specific components, such as conceptnet for ConceptNet tools.
    # Basic installation
    pip install hawkinsdb
    
    # Recommended installation with all features
    pip install hawkinsdb[all]
    
    # Install specific features
    pip install hawkinsdb[conceptnet]
  6. Add Semantic and Episodic memories

    main

    HawkinsDB supports different memory types via the add_entity method.

    • Semantic Memory: Stores conceptual knowledge and facts. Use "column": "Semantic" in your entity dictionary.
    • Episodic Memory: Stores event-based memories with temporal information. Use "column": "Episodic" and include a timestamp in the properties field.

    Entities are defined using a dictionary containing name, column, properties, and relationships.

    # Add semantic memory
    semantic_memory = {
        "name": "cat",
        "column": "Semantic",
        "properties": {
            "type": "animal",
            "size": "medium",
            "characteristics": ["furry", "agile", "carnivorous"]
        },
        "relationships": {
            "habitat": ["homes", "outdoors"],
            "behavior": ["hunting", "sleeping", "grooming"]
        }
    }
    result = db.add_entity(semantic_memory)
    
    # Add episodic memory
    import time
    
    episodic_memory = {
        "name": "cat_observation",
        "column": "Episodic",
        "properties": {
            "timestamp": time.time(),
            "action": "Observed cat behavior",
            "location": "Garden",
            "details": "Cat was chasing a butterfly"
        },
        "relationships": {
            "relates_to": ["cat"],
            "observed_by": ["human"]
        }
    }
    result = db.add_entity(episodic_memory)
  7. Configure the SQLite storage backend

    main

    To enable persistent storage using SQLite, you must initialize HawkinsDB and then use the config object to set the storage backend to 'sqlite'. You can optionally specify a custom file path for the database; if omitted, it defaults to ./hawkins_memory.db.

    from hawkinsdb import HawkinsDB
    
    # Initialize database
    db = HawkinsDB()
    
    # Enable SQLite storage
    db.config.set_storage_backend('sqlite')
    
    # Optionally configure SQLite path (default: ./hawkins_memory.db)
    db.config.set_storage_path('path/to/your/database.db')
  8. Handle errors and clean up SQLite connections

    main

    When performing database operations, wrap calls in try-except blocks to catch ValueError (for invalid data) or general Exception (for storage errors). To prevent 'Database Locked' issues and free up system resources, always call db.cleanup() when your application is finished with the database.

    try:
        result = db.add_entity(entity_data)
    except ValueError as e:
        print(f"Invalid data: {str(e)}")
    except Exception as e:
        print(f"Storage error: {str(e)}")
    
    # Always cleanup when finished
    db.cleanup()
  9. Directly enrich entities using ConceptNetEnricher

    main

    You can manually enhance existing entities in HawkinsDB by using the ConceptNetEnricher class. This allows you to fetch common-sense knowledge from the ConceptNet graph and attach it to your entities.

    To use this, initialize HawkinsDB and ConceptNetEnricher, add your base entity using db.add_entity(), and then call enricher.enrich_entity(db, entity_name, entity_type) to trigger the enrichment process.

    from hawkinsdb import HawkinsDB, ConceptNetEnricher
    
    # Initialize
    db = HawkinsDB()
    enricher = ConceptNetEnricher()
    
    # Add basic entity
    entity_data = {
        "name": "Dog",
        "column": "Semantic",
        "properties": {
            "type": "Animal",
            "category": "Pet"
        }
    }
    db.add_entity(entity_data)
    
    # Enrich the entity
    enriched_result = enricher.enrich_entity(db, "Dog", "Animal")
    print(f"Enrichment status: {enriched_result}")
    
    # Query enriched entity
    enriched_dog = db.query_frames("Dog")
    print("Enriched properties:", enriched_dog["Semantic"].properties)
    print("Enriched relationships:", enriched_dog["Semantic"].relationships)
  10. Quick Start with HawkinsDB

    main

    To get started, initialize HawkinsDB and an LLMInterface. You can then use add_entity to store knowledge with multiple perspectives (defining columns, names, properties, and relationships) and use the LLMInterface to query that knowledge using natural language.

    Requirements:

    • Python 3.10 or higher
    • OpenAI API key
    • SQLite or JSON storage backend
    from hawkinsdb import HawkinsDB, LLMInterface
    
    # Initialize
    db = HawkinsDB()
    llm = LLMInterface(db)
    
    # Store knowledge with multiple perspectives
    db.add_entity({
        "column": "Semantic",
        "name": "Coffee Cup",
        "properties": {
            "type": "Container",
            "material": "Ceramic",
            "capacity": "350ml"
        },
        "relationships": {
            "used_for": ["Drinking Coffee", "Hot Beverages"],
            "found_in": ["Kitchen", "Coffee Shop"]
        }
    })
    
    # Query using natural language
    response = llm.query("What can you tell me about the coffee cup?")
    print(response)
  11. Use HawkinsRAG or Hawkins-Agent for specialized tasks

    main

    If your goal is not general memory management but a specific application, consider these specialized packages built on top of HawkinsDB:

    • HawkinsRAG: A dedicated package for implementing Retrieval-Augmented Generation (RAG) with support for 22+ data sources.
    • Hawkins-Agent: A specialized framework for building intelligent AI agents.