Database Sync
HLM includes a built-in extension for syncing SQL databases with energy landscapes. Each database row becomes a named concept — an attractor basin that can be edited, strengthened, or removed without touching the source database.
SQL DB (source of truth) → qriton_hlm.db → BasinSurgeon (editable semantic layer)Architecture
Your SQL database stays the source of truth with full ACID guarantees. HLM becomes the editable semantic memory layer on top. The sync module bridges the two:
- With a loaded model:
capture()runs text through the network to create real attractor states. The row content is semantically encoded. - Without a model: Falls back to deterministic seed injection. Basins are addressable but don't encode text semantically.
Installation
# Core + DB sync (SQLite included in stdlib)
pip install qriton-hlm
# For MSSQL support
pip install qriton-hlm[db]Quick Start
1. Configure
Create hlm_sync_config.json:
{
"db_type": "sqlite",
"db_connection_string": "app.db",
"hlm_checkpoint_path": "models/hlm_main.pt",
"allowed_tables": ["Products", "Customers", "KnowledgeItems"],
"batch_size": 50,
"default_strength": 0.85,
"default_layer": 0
}2. Sync
from qriton_hlm.db import HLMSync
# From config file
with HLMSync.from_config("hlm_sync_config.json") as syncer:
# Sync a single row
syncer.sync_row("Products", {
"id": 123,
"name": "Cardiac Monitor X1",
"price": 4500.00,
"category": "Medical Devices",
})
# Sync an entire table
syncer.full_sync_table("Products")
# Delete a row's concept
syncer.delete_row("Products", 123)
# Check stats
print(syncer.stats)
# {'synced': 5, 'deleted': 1, 'errors': 0, 'retries': 0}3. Hook into your write path
# After every DB write, sync to HLM
def save_product(product):
db.insert("Products", product) # source of truth
syncer.sync_row("Products", product) # semantic memory
def remove_product(product_id):
db.delete("Products", product_id)
syncer.delete_row("Products", product_id)API Reference
SyncConfig
| Field | Type | Default | Description |
|---|---|---|---|
db_type | "sqlite" | "mssql" | required | Database type |
db_connection_string | str | required | Connection string or file path |
hlm_checkpoint_path | str | required | Path to HLM model checkpoint |
allowed_tables | list[str] | required | Tables permitted for sync |
batch_size | int | 50 | Rows per batch in full_sync_table |
max_retries | int | 3 | Retry attempts per operation |
retry_delay_seconds | float | 0.5 | Base delay between retries (linear backoff) |
checkpoint_interval_seconds | float | 300 | Background checkpoint interval |
default_strength | float | 0.85 | Basin injection strength |
default_layer | int | 0 | Target Hopfield layer |
HLMSync
from qriton_hlm.db import HLMSync, SyncConfig, CheckpointWorker
syncer = HLMSync(config) # from SyncConfig object
syncer = HLMSync.from_config("cfg.json") # from JSON file| Method | Returns | Description |
|---|---|---|
sync_row(table, row, id_column="id") | concept name | Sync one row as a named concept |
sync_batch(table, rows) | list of concept names | Sync multiple rows |
full_sync_table(table) | row count | Sync all rows from a table |
delete_row(table, row_id) | — | Remove a row's concept |
checkpoint(path=None) | — | Save state to disk |
close() | — | Checkpoint + close DB connection |
stats | dict | {synced, deleted, errors, retries} |
synced_concepts | set | All synced concept names |
CheckpointWorker
Background thread that periodically saves HLM state:
worker = CheckpointWorker(syncer, interval=300)
worker.start()
# ... your application runs ...
worker.stop()Concept Naming
Each synced row becomes a concept named table:row_id:
Products:123
Customers:456
KnowledgeItems:789These concepts are accessible via the standard BasinSurgeon API:
# After syncing, inspect what was captured
surgeon.list_concepts()
# {'Products:123': 1, 'Products:456': 1, 'Customers:789': 1}
# Remove a specific concept from the energy landscape
surgeon.remove_concept(layer=0, concept_name="Products:123")Concept Accumulation Guard
When re-syncing the same row (e.g., after an update), the sync module automatically clears the existing concept before re-capturing. This prevents stale samples from accumulating in the basin.
If remove_concept fails (concept not in registry), the module logs a warning and continues. The overwrite_warnings counter in stats tracks how often this happens.
Sync Strategies
| Strategy | When to use | How |
|---|---|---|
| App-level hooks | Simplest; call after every DB write | sync_row() in your save/delete functions |
| CDC / Triggers | MSSQL with Service Broker or Debezium | Push change events to a worker that calls sync_row() |
| Periodic batch | Low-frequency updates | Cron job runs full_sync_table() |
Persistence
Sync state is saved to .session files alongside the original checkpoint:
syncer.checkpoint()
# Saves to: models/hlm_main.pt.sessionSession files contain modified W matrices, captured concepts, and operation history. The original .pt checkpoint is never modified.
To restore a previous session:
from qriton_hlm import BasinSurgeon
surgeon = BasinSurgeon.from_checkpoint("models/hlm_main.pt")
surgeon.load_session("models/hlm_main.pt.session")
print(surgeon.list_concepts())