AbstractCore can store memory blocs: content-addressed snapshots of extracted text or file text, plus optional provider/model prompt-cache artifacts derived from that exact text.
This is useful for apps that want:
- durable, incremental “cached file text” across runs,
- per-model prompt-cache/KV artifacts compiled from that text (so you do not re-prefill the same file or text bloc repeatedly),
- stable selectors (
bloc_id) for REPL/CLI workflows.
A bloc is an atomic extracted-text snapshot stored on disk. It is identified by a SHA256 of the source file bytes (or another stable content hash chosen by the app).
The store persists:
content.txt— extracted textmeta.json— record metadata (path, size, timestamps, token estimate, etc.)meta.jsonld(optional) — compact JSON-LD metadata for catalogs/searchkv/…(optional) — per-(provider, model) prompt-cache artifacts (derived;.safetensorsfor MLX/HF transformers,.npzfor supported HF GGUF)kv/…manifest.json(optional) — sidecar integrity/freshness metadata for those artifacts
Default root:
~/.abstractcore/blocs/
Per-bloc directory:
~/.abstractcore/blocs/files/<sha256>/content.txtmeta.jsonmeta.jsonld(optional)kv/<provider+model-slug>.<provider-extension>(optional)kv/<provider+model-slug>.manifest.json(optional)
FileBlocStore.kv_cache_path(...) and FileBlocStore.kv_cache_manifest_path(...) define the
on-disk naming convention for KV artifacts and their manifest sidecars.
FileBlocStore does not extract files by itself; it expects extracted content + file metadata from the caller.
Typical flow:
- extract a file to text (e.g. via
extract_file_box()or your own pipeline) - write/update the bloc record +
content.txtviaFileBlocStore.upsert(...) - (optional) compile a per-model KV artifact with
ensure_bloc_kv_artifact(...) - (optional) load or fork it later with
load_bloc_kv_artifact(...) - (optional) generate JSON-LD metadata with
generate_bloc_metadata_jsonld(...) - (optional) list, delete, or prune bloc KV artifacts with
list_bloc_kv_artifacts(...),delete_bloc_kv_artifact(...), andprune_bloc_kv_artifacts(...)
from abstractcore import create_llm, ensure_bloc_kv_artifact, load_bloc_kv_artifact
from abstractcore.core.file_blocs import FileBlocStore
store = FileBlocStore()
llm = create_llm("mlx", model="mlx-community/Qwen3-4B")
record = store.upsert(
file_meta={
"path": "notes/orbit.txt",
"sha256": "...",
"content_sha256": "...",
"media_type": "text",
"size_bytes": 1234,
},
content="Document title: Orbit Notes\n\nThe launch window is Tuesday.",
)
ensure = ensure_bloc_kv_artifact(provider=llm, store=store, record=record, debug=True)
loaded = load_bloc_kv_artifact(provider=llm, store=store, record=record, key="work:orbit")
response = llm.generate(
"Summarize the loaded bloc.",
prompt_cache_binding=loaded.prompt_cache_binding,
)See:
abstractcore/core/file_blocs.pyfor the store and record schemaabstractcore/core/bloc_kv.pyfor the unified bloc artifact compiler/loader and deletion helpersabstractcore/core/bloc_metadata.pyfor JSON-LD schema + metadata generator/parser
The public API shape is shared. Provider internals and artifact formats remain backend-specific:
- MLX:
.safetensors, exact prompt fragment rendered byMLXProvider. - HuggingFace transformers:
.safetensors, gated on local prompt-cache save/load support for standard text-generation models and provider-native cache state AbstractCore can serialize and reconstruct. Current coverage includes standardDynamicCachelayer state, Qwen3.5/Qwen3Next tensor-list hybrid state, and Mamba-style tensor state when the Transformers cache class can be constructed from model config. - HuggingFace GGUF:
.npz, gated on exact cached prompt renderers. Current exact renderer paths arechatml-function-calling,llama-3, and Gemma4gemma_turnvia llama.cpp chat templates; other GGUF chat formats remain keyed-only.
Remote providers and generic OpenAI-compatible servers keep best-effort prompt_cache_key
semantics. They do not expose local durable bloc artifacts.
Artifact payloads are provider-native and model-bound. The portable contract is the manifest, binding object, Python helper, and server route shape, not a universal KV tensor layout. For general HuggingFace model-load compatibility, including quantized Transformers checkpoints, see HuggingFace Model Compatibility.
load_bloc_kv_artifact(...) returns:
key: the runtime prompt-cache key to usebinding_id: an opaque digest over the exact manifest identityprompt_cache_binding: the compact object callers can pass to generation for strict checking
prompt_cache_key by itself remains best-effort. If you need to prove that a request is using the
exact loaded bloc artifact, pass prompt_cache_binding (or the direct Python alias
expected_prompt_cache_binding). If the key is missing or rebound to another artifact, generation
fails before producing output.
Verbose verification is available with debug=True on ensure_bloc_kv_artifact(...) and
load_bloc_kv_artifact(...), or by setting ABSTRACTCORE_BLOC_KV_DEBUG=1. Debug payloads include
provider/backend ids, artifact paths, manifest path, artifact hash, binding id, rendered recipe
hash, bloc/content hashes, and token count when available.
For a long-lived single-model local runtime, AbstractEndpoint exposes:
POST /acore/blocs/upsert_textGET /acore/blocsGET /acore/blocs/recordPOST /acore/blocs/deleteGET /acore/blocs/kv/manifestGET /acore/blocs/kv/listPOST /acore/blocs/kv/ensurePOST /acore/blocs/kv/loadPOST /acore/blocs/kv/deletePOST /acore/blocs/kv/prune
The multi-provider gateway abstractcore.server.app now exposes two modes:
- direct gateway mode:
POST /acore/models/loadGET /acore/models/loadedPOST /acore/models/unload- local
POST /acore/blocs/upsert_text - local
GET /acore/blocs - local
GET /acore/blocs/record - local
POST /acore/blocs/delete - local
GET /acore/blocs/kv/manifest - local
GET /acore/blocs/kv/list - local
POST /acore/blocs/kv/ensure - local
POST /acore/blocs/kv/load - local
POST /acore/blocs/kv/delete - local
POST /acore/blocs/kv/prune
- proxy mode:
- the same
/acore/blocs/*routes withbase_urlpointing at an upstreamAbstractEndpoint
- the same
Important boundary:
- the durable artifact is bloc-only
- in direct gateway mode, text loaded cache keys live on the loaded gateway runtime selected by
provider+model /acore/models/loadis task-aware; omittedtaskkeeps the text runtime behavior used by bloc-KV, whileimage_generation,tts, andsttroute to capability residency where supportedruntime_idfrom/acore/models/loadis the most precise selector when multiple warm runtimes share the sametask+provider+model- in proxy mode, loaded cache keys live on the upstream endpoint worker/provider instance
/acore/blocs/kv/loadreturnsartifact.key,artifact.binding_id, andartifact.prompt_cache_binding- use
artifact.prompt_cache_bindingon the next chat call when exact request-time binding is required - deletion is safe by default: deleting a loaded bloc KV artifact returns
409until the caller usesclear_loaded=trueor explicitly opts into forced deletion - use
dry_run=trueon delete/prune calls to inspect matched files and live bindings before removing artifacts