Documentation Index
Fetch the complete documentation index at: https://ahvn.top/llms.txt
Use this file to discover all available pages before exploring further.
A workspace is not a database. It is a map from meaning to storage.
1. The Shortest Mental Model
HeavenBase gives you one logical workspace over many physical backends. You define entities to describe what your data means. Each entity has typed fields, and every row has one stableobject_id. HeavenBase then decides, or follows your explicit instructions, where each field should live: scalar values may go to SQL, vectors to a vector store, long text to search, and JSON or files to a row store.
The important part is that users and agents do not have to think in those physical pieces. They write to a workspace, query a workspace, and receive one logical row or one ResultFrame. HeavenBase keeps the physical placement, query compilation, backend execution, and result merge behind that surface.
For a user, the model is:
2. The Core Path
The diagram is intentionally small. HeavenBase has more modules than this, but most of them sit on one of these lines: they define structure, choose placement, compile operations, talk to providers, or adapt the workspace to another interface.3. Workspace Is the Boundary
AHeavenBase workspace owns the things that must agree with each other:
- registered entities
- configured backend instances
- field-level storage plans
- operation handlers
- system rows for discovery and introspection
hb.get_workspace("shop") makes a named workspace easy to reuse, while the workspace lock keeps registration, CRUD, query, refresh, and drop operations from racing inside one workspace object.
4. Entities Describe Meaning
An entity is a logical schema. It says, “this object has these fields, and these fields have these meanings.” It does not say, by itself, which database must store them. When you define anhb.Entity, the metaclass compiles the class into an EntitySchema. Fields become FieldSchema records. Logical types such as ShortText, LongText, Float, Date, Json, Array, HyperG, and Vector own the value contract:
validate()turns user input into canonical Python values.encode()turns canonical values into backend-ready storage values.decode()turns backend values back into canonical values.
object_id: Identifier primary key. If you do not provide one, HeavenBase derives a deterministic ID from the configured source field, usually name. That object_id is the thread that lets split field fragments come back together later.
5. Routing Places Fields
Routing is field-level. A field can have an explicit placement with.store(to=..., strategy=...), or it can use the default storage profile for its logical type.
The default intuition is:
- vectors prefer vector backends with
VectorIndex - long text prefers search backends with
InvertedIndex, then row storage - JSON prefers JSON-capable row storage with
JsonField - arrays and
HyperGprefer SQL side tables when available - ordinary scalars use inline row columns
StoragePlan. The plan contains effective StorageBinding rows: entity, field, backend, strategy, and source. Backends then receive ensure(schema, bindings) so they can prepare tables, indexes, files, or provider collections for the fields they own.
The object_id field is special. HeavenBase controls its placement and replicates it to the backends that store pieces of the same entity so those pieces can be merged safely.
6. CRUD Fans Out, Then Rejoins
Writes start from the workspace surface:upsert, set, delete, and their batch variants.
For an upsert, HeavenBase materializes the row first. It normalizes object_id, applies defaults, runs compute hooks, validates each present field through its logical type, and then encodes only the fields owned by each backend. The writer groups those pieces into RowOp batches and calls Backend.upsert(...) on each routed backend.
After a non-system entity write succeeds, HeavenBase publishes a Catalog row. This keeps object discovery separate from the object payload: the catalog tells agents what exists, while the entity row still carries the typed data.
Reads reverse the route. get and get_many ask each routed backend for the requested object_id, decode the fields that backend owns, and merge the fragments into one logical row. If two routed backends disagree about the same field, HeavenBase raises under the normal unique read path instead of hiding the conflict.
Deletes remove Catalog rows before entity rows, so discovery does not keep pointing at objects that are being removed.
7. Queries Compile to Fragments
HeavenBase accepts more than one query surface, but they meet at the sameQuerySpec.
Python expressions such as Product.price < 100, Mongo-style JSON filters, vector .near(...), projections, ordering, offset, and limit all normalize into that spec. The query engine then looks at the StoragePlan and asks a narrow question for each leaf:
(logical type, operation, backend type, strategy). A handler does not execute the query. It compiles a leaf into a QueryFragment: SQLAlchemy where clauses for SQL, provider query payloads for search/vector systems, or Python row predicates for scan fallback.
Backends execute only fragments. They do not parse user queries.
When a query spans multiple backends, HeavenBase executes the relevant fragments and merges frames by object_id: AND becomes intersection, OR becomes union, and NOT becomes difference from the entity universe. Vector queries follow the same principle, with extra planning for near + filter: same-backend combined execution first, duplicated metadata prefilter when available, bounded candidate-ID prefilter when supported, and post-filter merge otherwise.
The final public value is a ResultFrame. It keeps object_id, preserves columns from backend merges, hydrates missing logical fields when needed, then applies ordering, offset, limit, and projection.
8. Catalog Makes the Workspace Observable
HeavenBase has two built-in system entities:Catalogdescribes concrete objects: target entity, targetobject_id, name, description, tags, active flag, and workspace.MetaSchemadescribes structure: workspaces, backends, capabilities, entities, fields, storage bindings, and enabled extensions.
Catalog to find the right object, inspect MetaSchema to understand the entity and field structure, then run a typed query or CRUD operation through the same workspace.
This is the small loop behind the larger HeavenBase idea: structure is data too, and agents should be able to observe it.
9. Where Developers Should Look
If you are reading the source, start from the public path and move downward:| Area | Source path | What to look for |
|---|---|---|
| Workspace facade | src/heavenbase/workspace/ | Public CRUD/query methods, workspace registry, writer, query engine, system-row publisher |
| Logical model | src/heavenbase/entity/, src/heavenbase/schema/, src/heavenbase/types/ | Entity metaclass, field DSL, schema IR, logical type validation and encoding |
| Placement | src/heavenbase/storage/, src/heavenbase/strategies/ | Storage rules, default profiles, effective bindings, strategy identifiers |
| Execution | src/heavenbase/handlers/, src/heavenbase/backends/ | Handler lookup, native compilers, scan fallbacks, provider adapters |
| Results | src/heavenbase/query/, src/heavenbase/frame/ | Query AST, JSON query parser, QueryBuilder, ResultFrame merge/export behavior |
| Discovery and adapters | src/heavenbase/discovery/, src/heavenbase/toolkit/, src/heavenbase/mcp/, src/heavenbase/cli/, src/heavenbase/interop/ | Capability browsing, MCP tools, CLI commands, import/export bridges |
QuerySpec, and do not hide new routing rules inside provider code.

